I am trying to develop a function which would enable the Kernel (Android kernel: 4.9.59) to send a message to an/many userspace application and I have followed this example: Kernel to userspace application communication

However, when I am trying to call the message conveying function from the scheduler I am receiving the following error:

Fatal exception

PC is at netlink_broadcast_filtered+0x24/0x3d4

LR is at netlink_broadcast+0x14/0x20

Inside the kernel scheduler (kernel/sched) I have created a header (custom_code.h) which holds the function to send message from the kernel. I am not using Kernel module to inject this because Android does not support modules. The code inside custom_code.h is as follows:

#include <linux/sched.h>
#include <net/sock.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#include <linux/string.h>

#define MY_GROUP    1 //For netlink socket
struct sock* socket; //For netlink socket
struct sk_buff* socket_buff; //For netlink socket

static inline void nl_receive_callback (struct sk_buff *skb)
{
    nlmsg_free(skb);
}

struct netlink_kernel_cfg cfg = {
    .input  = nl_receive_callback,
    .groups = 1,
};

static inline int kernel_send_nl_msg(void)
{
    struct nlmsghdr *nlsk_mh;
    char* msg = "hello from kernel";

    socket = netlink_kernel_create(&init_net, NETLINK_USERSOCK, &cfg);

    socket_buff = nlmsg_new(256, GFP_KERNEL);
    nlsk_mh = nlmsg_put(socket_buff, 0, 0, NLMSG_DONE, strlen(msg), 0);
    //NETLINK_CB(socket_buff).pid = 0;    // kernel pid pid is deprecated
    NETLINK_CB(socket_buff).portid = 0;
    NETLINK_CB(socket_buff).dst_group = MY_GROUP;
    strcpy(nlmsg_data(nlsk_mh), msg);

    nlmsg_multicast(socket, socket_buff, 0, MY_GROUP, GFP_KERNEL);
    pr_info("%s", msg);//Print out the message to kernel

    return 0;
}

I am calling the kernel_send_nl_msg from the sugov_start(struct cpufreq_policy *policy) function inside the cpufreq_schedutil.c (kernel/sched/cpufreq_schedutil.c), and I have built the whole kernel and flashed it on an Android device.

My modified code inside the kernel/sched/cpufreq_schedutil.c as follows:

static int sugov_start(struct cpufreq_policy *policy)
{
    struct sugov_policy *sg_policy = policy->governor_data;
    unsigned int cpu;

    sg_policy->up_rate_delay_ns =
        sg_policy->tunables->up_rate_limit_us * NSEC_PER_USEC;
    sg_policy->down_rate_delay_ns =
        sg_policy->tunables->down_rate_limit_us * NSEC_PER_USEC;
    update_min_rate_limit_us(sg_policy);
    sg_policy->last_freq_update_time = 0;
    sg_policy->next_freq = UINT_MAX;
    sg_policy->work_in_progress = false;
    sg_policy->need_freq_update = false;
    sg_policy->cached_raw_freq = 0;

    for_each_cpu(cpu, policy->cpus) {
        struct sugov_cpu *sg_cpu = &per_cpu(sugov_cpu, cpu);

        memset(sg_cpu, 0, sizeof(*sg_cpu));
        sg_cpu->sg_policy = sg_policy;
        sg_cpu->flags = 0;
        sugov_start_slack(cpu);
        sg_cpu->iowait_boost_max = policy->cpuinfo.max_freq;
        cpufreq_add_update_util_hook(cpu, &sg_cpu->update_util,
                         policy_is_shared(policy) ?
                            sugov_update_shared :
                            sugov_update_single);
    }
        if(kernel_send_nl_msg() != 0)
            pr_info("Error sending message from Kernel using socket");

    return 0;
}

After flashing the kernel image to the device and trying to boot the aformentioned error is conveyed by the device (even without booting).

My question on the error is as follows:

1) What might be the issue that is causing the error?

2) How can I send messages successfully from Android kernel to an/many userspace application? Any suggestion would be really helpful.

0 Answers