Quantcast
Channel: Active questions tagged linux-kernel - Stack Overflow
Viewing all 12160 articles
Browse latest View live

Linux keyboard event capturing /dev/inputX

$
0
0

I was trying to capture keyboard events. e.g. I want to drill down a keylogger from the scratch. After 2 hours of fighting I found the following

neel@pc1$ ls -l /dev/input/by-id
lrwxrwxrwx 1 root root 9 2010-05-05 21:33 usb-Plus_More_Enterprise_LTD._USB-compliant_keyboard-event-kbd -> ../event1
lrwxrwxrwx 1 root root 9 2010-05-05 21:33 usb-Plus_More_Enterprise_LTD._USB-compliant_keyboard-event-mouse -> ../event2
lrwxrwxrwx 1 root root 9 2010-05-05 21:33 usb-Plus_More_Enterprise_LTD._USB-compliant_keyboard-mouse -> ../mouse1

But when I tried to

neel@pc1$ sudo cat /dev/input/usb-Plus_More_Enterprise_LTD._USB-compliant_keyboard-event-kbd

It yields nothing THERE WAS NO OUTPUT

after a bit more searching Now I am thinking probabbly something in Xorg blocks it.

So Any more Information ?? and atthe end of the say how can I read the input from that file ?? or is there any other way of capturing keyboard events ??


How to load network block device on CentOS7

$
0
0

I am trying to load the nbd network block device on my CentOS7 server. However, I got:

modprobe nbd
modprobe: FATAL: Module nbd not found.

It would be really appreciated if anyone could tell me the best way to have nbd module loaded. And eventually, I hope I can automate this tasks via ansible.

Here is my kernel version:

$ uname -r
3.10.0-327.28.3.el7.x86_64

Thanks!

How to setup vega (AMD) for Fedora 31 (Linux)

$
0
0

How do I download driver AMD for Fedora 31 (Linux) and install it by terminal? I can't find the URL from supporter of AMD site.

What is the (wget URL) for the driver?

What does TIF_NEED_RESCHED do?

$
0
0

What is the purpose of TIF_NEED_RESCHED in a Linux scheduler (say CFS)? In case of writing a new scheduling class, can this flag be used? If yes, where and how can this flag be used for a new scheduling class?

problem while booting when the uImage is replaced

$
0
0

I made a small change in the driver code in the kernel, built the kernel (uImage).

make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- uImage

Replaced the uImage in the ISO (extracted it and rebuilt). But I get the following error while booting. I even reverted the code changes, only built and replaced the uImage. Still the error is present. I am not understanding the problem. Even searched the internet, but could not succeed with all the solutions.

Can anyone please guide me. The pre-built kernel uImage works fine.

U-Boot 2009.08 (Jan 11 2019 - 08:37:07)

CPU: Freescale i.MX6 family TO0.0 at 996 MHz
Thermal sensor with ratio = 189
Temperature:   20 C, calibration data 0x5a94f97d
mx6q pll1: 996MHz
mx6q pll2: 528MHz
mx6q pll3: 480MHz
mx6q pll8: 50MHz
ipg clock     : 66000000Hz
ipg per clock : 66000000Hz
uart clock    : 80000000Hz
cspi clock    : 60000000Hz
ahb clock     : 132000000Hz
axi clock   : 264000000Hz
emi_slow clock: 132000000Hz
ddr clock     : 528000000Hz
usdhc1 clock  : 198000000Hz
usdhc2 clock  : 198000000Hz
usdhc3 clock  : 198000000Hz
usdhc4 clock  : 198000000Hz
nfc clock     : 24000000Hz
Board: MX6-IAVS:[POR] - Built under Wind River Linux
Boot Device: UNKNOWN
I2C:   ready
DRAM:   2 GB
MMC:   status 0
FSL_ESDHC: 0
In:    serial
Out:   serial
Err:   serial
Net:   got MAC address from IIM: 9c:28:bf:d2:c1:c7
FEC0 [PRIME]
autoboot in 5 seconds
(Re)start USB...
USB:   Register 10011 NbrPorts 1
USB EHCI 1.00
scanning bus for devices... 2 USB Device(s) found
       scanning bus for storage devices... 1 Storage Device(s) found

Loading from USB device 0, partition 0: Name: usbda0  Type: U-Boot
   Image Name:   EoLTesting
   Image Type:   ARM Linux Multi-File Image (uncompressed)
   Data Size:    4708687 Bytes =  4.5 MB
   Load Address: 10008000
   Entry Point:  10008000
   Contents:
      Image 0: 4283224 Bytes =  4.1 MB
      Image 1: 425451 Bytes = 415.5 kB
...........................................................................................................................................................................................................................................................................................................................................................................................................................................................................
stopping USB..
## Copying part 1 from legacy image at 10800000 ...
   Verifying Checksum ... OK
## Booting kernel from Legacy Image at 10800000 ...
   Image Name:   EoLTesting
   Image Type:   ARM Linux Multi-File Image (uncompressed)
   Data Size:    4708687 Bytes =  4.5 MB
   Load Address: 10008000
   Entry Point:  10008000
   Contents:
      Image 0: 4283224 Bytes =  4.1 MB
      Image 1: 425451 Bytes = 415.5 kB
   Verifying Checksum ... OK
## Loading init Ramdisk from Legacy Image at 12000000 ...
   Image Name:   
   Image Type:   ARM Linux RAMDisk Image (gzip compressed)
   Data Size:    425387 Bytes = 415.4 kB
   Load Address: 00000000
   Entry Point:  00000000
   Verifying Checksum ... OK
   Loading Multi-File Image ... OK
OK

Starting kernel ...

Booting Linux on physical CPU 0
Initializing cgroup subsys cpuset
Initializing cgroup subsys cpu
Linux version 3.4.91-rt56-WR5.0.1.26_preempt-rt (chukkaa@nul6136u) (gcc version 4.6.3 (Wind River Linux Sourcery CodeBench 4.6a-148) ) #4 SMP PREEMPT RT Tue Jul 12 13:18:56 CEST 2016
CPU: ARMv7 Processor [412fc09a] revision 10 (ARMv7), cr=10c5387d
CPU: PIPT / VIPT nonaliasing data cache, VIPT aliasing instruction cache

Truncating RAM at 10000000-8fffffff to -7b7fffff (vmalloc region overlap).
Memory policy: ECC disabled, Data cache writealloc
CPU identified as i.MX6Q, silicon rev 1.5
PERCPU: Embedded 9 pages/cpu @81a75000 s16256 r8192 d12416 u36864
Built 1 zonelists in Zone order, mobility grouping on.  Total pages: 432784
Kernel command line: root=/dev/ram0 rw nosmp video=mxcfb0:dev=lcd,800x600-32@60,if=RGB24
PID hash table entries: 4096 (order: 2, 16384 bytes)
Dentry cache hash table entries: 262144 (order: 8, 1048576 bytes)
Inode-cache hash table entries: 131072 (order: 7, 524288 bytes)
allocated 15851520 bytes of page_cgroup
please try 'cgroup_disable=memory' option if you don't want memory cgroups
Memory: 752MB 952MB = 1704MB total
Memory: 1700200k/1700200k available, 61080k reserved, 0K highmem
Virtual kernel memory layout:
    vector  : 0xffff0000 - 0xffff1000   (   4 kB)
    fixmap  : 0xffc00000 - 0xfff00000   (3072 kB)
    vmalloc : 0xec000000 - 0xfb000000   ( 240 MB)
    lowmem  : 0x80000000 - 0xeb800000   (1720 MB)
    modules : 0x7f000000 - 0x80000000   (  16 MB)
      .text : 0x80008000 - 0x80b789b8   (11715 kB)
      .init : 0x80b79000 - 0x80bc2f80   ( 296 kB)
      .data : 0x80bc4000 - 0x80c33a58   ( 447 kB)
       .bss : 0x80c33a7c - 0x80cdf06c   ( 686 kB)
Preemptible hierarchical RCU implementation.
NR_IRQS:436
sched_clock: 32 bits at 3000kHz, resolution 333ns, wraps every 1431655ms
arm_max_freq=1GHz
twd_local_timer_register failed -6
MXC_Early serial console at MMIO 0x21f0000 (options '115200')
bootconsole [ttymxc0] enabled
Console: colour dummy device 80x30
VFS: Unable to mount root fs on unknown-block(1,0)
User configuration error - no valid root filesystem found
Kernel panic - not syncing: Invalid configuration from end user prevents continuing
[<80017c70>] (unwind_backtrace+0x0/0xf8) from [<80542f64>] (dump_stack+0x20/0x24)
[<80542f64>] (dump_stack+0x20/0x24) from [<8054328c>] (panic+0x138/0x298)
[<8054328c>] (panic+0x138/0x298) from [<80afff60>] (change_floppy+0x0/0xec)
[<80afff60>] (change_floppy+0x0/0xec) from [<80b000b4>] (mount_root+0x68/0x6c)
[<80b000b4>] (mount_root+0x68/0x6c) from [<80b00250>] (prepare_namespace+0x198/0x1dc)
[<80b00250>] (prepare_namespace+0x198/0x1dc) from [<80affb50>] (kernel_init+0x294/0x29c)
[<80affb50>] (kernel_init+0x294/0x29c) from [<8000f4e4>] (kernel_thread_exit+0x0/0x8)
CPU3: stopping
[<80017c70>] (unwind_backtrace+0x0/0xf8) from [<80542f64>] (dump_stack+0x20/0x24)
[<80542f64>] (dump_stack+0x20/0x24) from [<80014e18>] (handle_IPI+0x170/0x1a8)
[<80014e18>] (handle_IPI+0x170/0x1a8) from [<80008544>] (gic_handle_irq+0x64/0x68)
[<80008544>] (gic_handle_irq+0x64/0x68) from [<805483c0>] (__irq_svc+0x40/0x70)
Exception stack(0xea0f5f58 to 0xea0f5fa0)
5f40:                                                       00000001 80000093
5f60: f2a02000 8001f200 80bb77c8 80b67408 805505d0 ea0f4000 ea0f4030 80b6c650
5f80: ea0f4000 ea0f5fac ea0f5fb0 ea0f5fa0 8000f5b8 8000f5bc 60000013 ffffffff
[<805483c0>] (__irq_svc+0x40/0x70) from [<8000f5bc>] (default_idle+0x48/0x4c)
[<8000f5bc>] (default_idle+0x48/0x4c) from [<8000f8f4>] (cpu_idle+0xdc/0x110)
[<8000f8f4>] (cpu_idle+0xdc/0x110) from [<8053f730>] (secondary_start_kernel+0x124/0x12c)
[<8053f730>] (secondary_start_kernel+0x124/0x12c) from [<1053ed14>] (0x1053ed14)
CPU1: stopping
[<80017c70>] (unwind_backtrace+0x0/0xf8) from [<80542f64>] (dump_stack+0x20/0x24)
[<80542f64>] (dump_stack+0x20/0x24) from [<80014e18>] (handle_IPI+0x170/0x1a8)
[<80014e18>] (handle_IPI+0x170/0x1a8) from [<80008544>] (gic_handle_irq+0x64/0x68)
[<80008544>] (gic_handle_irq+0x64/0x68) from [<805483c0>] (__irq_svc+0x40/0x70)
Exception stack(0xea0b1f58 to 0xea0b1fa0)
1f40:                                                       00000001 80000093
1f60: f2a02000 8001f200 80bb77c8 80b67408 805505d0 ea0b0000 ea0b0030 80b6c650
1f80: ea0b0000 ea0b1fac ea0b1fb0 ea0b1fa0 8000f5b8 8000f5bc 60000013 ffffffff
[<805483c0>] (__irq_svc+0x40/0x70) from [<8000f5bc>] (default_idle+0x48/0x4c)
[<8000f5bc>] (default_idle+0x48/0x4c) from [<8000f8f4>] (cpu_idle+0xdc/0x110)
[<8000f8f4>] (cpu_idle+0xdc/0x110) from [<8053f730>] (secondary_start_kernel+0x124/0x12c)
[<8053f730>] (secondary_start_kernel+0x124/0x12c) from [<1053ed14>] (0x1053ed14)
CPU2: stopping
[<80017c70>] (unwind_backtrace+0x0/0xf8) from [<80542f64>] (dump_stack+0x20/0x24)
[<80542f64>] (dump_stack+0x20/0x24) from [<80014e18>] (handle_IPI+0x170/0x1a8)
[<80014e18>] (handle_IPI+0x170/0x1a8) from [<80008544>] (gic_handle_irq+0x64/0x68)
[<80008544>] (gic_handle_irq+0x64/0x68) from [<805483c0>] (__irq_svc+0x40/0x70)
Exception stack(0xea0e3f58 to 0xea0e3fa0)
3f40:                                                       00000001 80000093
3f60: f2a02000 8001f200 80bb77c8 80b67408 805505d0 ea0e2000 ea0e2030 80b6c650
3f80: ea0e2000 ea0e3fac ea0e3fb0 ea0e3fa0 8000f5b8 8000f5bc 60000013 ffffffff
[<805483c0>] (__irq_svc+0x40/0x70) from [<8000f5bc>] (default_idle+0x48/0x4c)
[<8000f5bc>] (default_idle+0x48/0x4c) from [<8000f8f4>] (cpu_idle+0xdc/0x110)
[<8000f8f4>] (cpu_idle+0xdc/0x110) from [<8053f730>] (secondary_start_kernel+0x124/0x12c)
[<8053f730>] (secondary_start_kernel+0x124/0x12c) from [<1053ed14>] (0x1053ed14)

EDIT: It is an imx ARM controller. I used the mkisofs tool to extract and rebuild the ISO file for ARM. If I just extract and rebuild the old ISO, it works fine.

I used the same configuration file from the old kernel.

Why `pstore` is not working with Samsung S10 5G?

$
0
0

I have Samsung S10 5G with root via instructions given by Magisk. I am trying to modify system.img to patch my SELinux policies in the AP file of ROM. When I flashed the AP file with other files using Odin then it fails with a boot loop. To debug the cause I am using pstore which is configured on the device as follows:

  1. In init.rc the pstore is mounted at /sys/fs/pstore as follows:
314:    # pstore/ramoops previous console log
315:    mount pstore pstore /sys/fs/pstore nodev noexec nosuid
316:    chown system log /sys/fs/pstore/console-ramoops
317:    chmod 0440 /sys/fs/pstore/console-ramoops
318:    chown system log /sys/fs/pstore/console-ramoops-0
319:    chmod 0440 /sys/fs/pstore/console-ramoops-0
320:    chown system log /sys/fs/pstore/pmsg-ramoops-0
321:    chmod 0440 /sys/fs/pstore/pmsg-ramoops-0
  1. The Kernel config options is as follows:
$ cat config | grep PSTORE
CONFIG_PSTORE=y
CONFIG_PSTORE_ZLIB_COMPRESS=y
# CONFIG_PSTORE_LZO_COMPRESS is not set
# CONFIG_PSTORE_LZ4_COMPRESS is not set
CONFIG_PSTORE_CONSOLE=y
CONFIG_PSTORE_PMSG=y
CONFIG_PSTORE_PMSG_SSPLOG=y
CONFIG_PSTORE_RAM=y
  1. Ramoops configurations is as follows:
./sys/module/ramoops/parameters/console_size            262144
./sys/module/ramoops/parameters/dump_oops               1
./sys/module/ramoops/parameters/ecc                     0
./sys/module/ramoops/parameters/ftrace_size             262144
./sys/module/ramoops/parameters/mem_address             3241148416
./sys/module/ramoops/parameters/mem_size                1048576
./sys/module/ramoops/parameters/mem_type                0
./sys/module/ramoops/parameters/pmsg_size               262144
./sys/module/ramoops/parameters/record_size             262144

Now, I am following the tutorial: Reading kernel logs

but there are no logs in /sys/fs/pstore directory. When I have tried the same step on another device(OnePlus 6T) then I can see the logs.

Also, I have tried to check logs for the real cause of flashing ROM with the following instructions:

  1. Flash ROM that causes a boot loop.
  2. Flash ROM that has root access.
  3. Check the logs within /sys/fs/pstore directory.

This is also not working.

Along with check /sys/fs/pstore directory, I have also tried to mount the pstore at some other location with mount -t pstore - /dev/pstore but there are no logs.

I need a favor in

  • Any way to debug the pstore problem?
  • Any other way to find the kernel logs?

linux disable_irq() and local_irq_save()

$
0
0

I have a piece of code where there is:

disable_irq(irq_clk);
local_irq_save(flags);

I found that the the disable_irq() disables a specific interrupt, on the other hand local_irq_save() disables all the interrupt.

So I wonder the meaning of the above code.

arm-linux-gnueabihf-ld: no machine record defined

$
0
0

I am trying to build my own custom linux kernel for my beagle bone black with ARM am355x processor. It would compile and work just fine if i just use the default kernel configuration. But after performing the necessary steps to add my device driver to arch/arm/mach-omap1 and try to compile to it gives me this error:

arm-linux-gnueabihf-ld: no machine record defined

I wonder if it is because of toolchain version, I am using the arm-linux-gnueabihf- version 7.2 Thank you


How to fix: fatal error: openssl/opensslv.h: No such file or directory in RedHat 7

$
0
0

I have RedHat Enterprise Linux Server 7, and I downloaded the linux kernel version 4.12.10 which I am trying to compile but when I execute the following command:

make modules

I get the following error:

scripts/sign-file.c:25:30: fatal error: openssl/opensslv.h: No such file or directory

Does anyone have an idea to fix this please ?

What is the benefit of calling ioread functions when using memory mapped IO

$
0
0

To use memory mapped I/O, we need to first call request_mem_region.

struct resource *request_mem_region(
                unsigned long start,
                unsigned long len,
                char *name);

Then, as kernel is running in virtual address space, we need to map physical addresses to virtual address space by running ioremap function.

void *ioremap(unsigned long phys_addr, unsigned long size);

Then why can't we access the return value directly.

From Linux Device Drivers Book

Once equipped with ioremap (and iounmap), a device driver can access any I/O memory address, whether or not it is directly mapped to virtual address space. Remember, though, that the addresses returned from ioremap should not be dereferenced directly; instead, accessor functions provided by the kernel should be used.

Can anyone explain the reason behind this or the advantage with accessor functions?

ip_rcv (in ip_input.c for ipv4) behaviour in loopback mode

$
0
0

So I wanted to put a few printk messages in ip_rcv function to see whether after receiving a packet from a particular IP there is a message printed. I am attaching the entire ip_rcv function which has the printk modifications:

int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
{
    const struct iphdr *iph;
    struct net *net;
    u32 len;

    /* When the interface is in promisc. mode, drop all the crap
     * that it receives, do not try to analyse it.
     */
    if (skb->pkt_type == PACKET_OTHERHOST)
        goto drop;


    net = dev_net(dev);
    __IP_UPD_PO_STATS(net, IPSTATS_MIB_IN, skb->len);

    skb = skb_share_check(skb, GFP_ATOMIC);
    if (!skb) {
        __IP_INC_STATS(net, IPSTATS_MIB_INDISCARDS);
        goto out;
    }

    if (!pskb_may_pull(skb, sizeof(struct iphdr)))
        goto inhdr_error;

    iph = ip_hdr(skb);

    //**PSK's Modification**
    if (iph->saddr == 0x08080808)
        printk("\n***PSK: %x IP's message recieved: Google***\n", iph->saddr);
    if (iph->saddr == 0x0202000A)
        printk("\n***PSK: %x IP's message recieved: Gateway***\n", iph->saddr);
    if (iph->saddr == 0x010000FF)
        printk("\n***PSK: %x IP's message recieved : Home***\n", iph->saddr);

     /* RFC1122: 3.2.1.2 MUST silently discard any IP frame that fails the checksum.
     *
     *  Is the datagram acceptable?
     *
     *  1.  Length at least the size of an ip header
     *  2.  Version of 4
     *  3.  Checksums correctly. [Speed optimisation for later, skip loopback checksums]
     *  4.  Doesn't have a bogus length
     */

    if (iph->ihl < 5 || iph->version != 4)
        goto inhdr_error;

    BUILD_BUG_ON(IPSTATS_MIB_ECT1PKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_ECT_1);
    BUILD_BUG_ON(IPSTATS_MIB_ECT0PKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_ECT_0);
    BUILD_BUG_ON(IPSTATS_MIB_CEPKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_CE);
    __IP_ADD_STATS(net,
               IPSTATS_MIB_NOECTPKTS + (iph->tos & INET_ECN_MASK),
               max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));

    if (!pskb_may_pull(skb, iph->ihl*4))
        goto inhdr_error;

    iph = ip_hdr(skb);

    if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
        goto csum_error;

    len = ntohs(iph->tot_len);
    if (skb->len < len) {
        __IP_INC_STATS(net, IPSTATS_MIB_INTRUNCATEDPKTS);
        goto drop;
    } else if (len < (iph->ihl*4))
        goto inhdr_error;

    /* Our transport medium may have padded the buffer out. Now we know it
     * is IP we can trim to the true length of the frame.
     * Note this now means skb->len holds ntohs(iph->tot_len).
     */
    if (pskb_trim_rcsum(skb, len)) {
        __IP_INC_STATS(net, IPSTATS_MIB_INDISCARDS);
        goto drop;
    }

    iph = ip_hdr(skb);
    skb->transport_header = skb->network_header + iph->ihl*4;

    /* Remove any debris in the socket control block */
    memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
    IPCB(skb)->iif = skb->skb_iif;

    /* Must drop socket now because of tproxy. */
    skb_orphan(skb);

    return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
               net, NULL, skb, dev, NULL,
               ip_rcv_finish);

csum_error:
    __IP_INC_STATS(net, IPSTATS_MIB_CSUMERRORS);
inhdr_error:
    __IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
drop:
    kfree_skb(skb);
out:
    return NET_RX_DROP;
}

I should get a message printed into the kernel buffer after getting a packet from either Google DNS, my local gateway (10.0.2.2) or loop-back address (127.0.0.1). This is working fine for the DNS and the gateway, but not when I ping localhost or try to run a program which involves back and forth from a localhost. Are there some other kernel function calls that specifically handle packets to localhost, or am I missing something very basic? I thought the loopback packets should trace the same path through the stack as any other packet at least until L3. I would also appreciate if someone briefly explains the handling of loopback traffic along with the answer.

System Specs: System- Ubuntu on Virtual Machine Kernel- 4.15.0-70 generic

Kubernetes installation error in flannel step

$
0
0

I am installing kubernetes using kubeadm on GCP Centos VM and I am getting the following error while running flannel step.

Error:

[root@master ~]# kubectl apply -f https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml
clusterrole.rbac.authorization.k8s.io/flannel created
clusterrolebinding.rbac.authorization.k8s.io/flannel created
serviceaccount/flannel created
configmap/kube-flannel-cfg created
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"
unable to recognize "https://raw.githubusercontent.com/coreos/flannel/a70459be0084506e4ec919aa1c114638878db11b/Documentation/kube-flannel.yml": no matches for kind "DaemonSet" in version "extensions/v1beta1"

What changes shall I made in order to fix this?

understanding WARN_ON_ONCE macro definition

$
0
0

I was going through the WARN_ON_ONCE macro definition. I have doubt regarding the following line, what is the use of !! before condition. If we remove !! then also same will be stored in __ret_warn_once.

int __ret_warn_once = !!(condition);

What will happen when compiler executing the following source line.

static bool __section(.data.unlikely) __warned;

Simple SPI device driver

$
0
0

I have written a simple driver for a character device in Non Blocking mode using epoll. Now I would like to use that driver for SPI interface.

What should be the device name or how will I map the actual device with the kernel ? How will I use the interrupt?

Also who is the Master and Slave?Suppose I am connecting a SPI compatible device to the panda board.Will that device becomes a slave and the development board becomes Master?

I am a newbie.I am using a panda board. In what way should I go through the Technical Reference manual?

I would really appreciate if anybody would explain and clarify my doubts.

Does UIO generic PCI support interrupts?

$
0
0

I use uio generic driver with HW composed of PCIe device (FPGA) connected to Intel ATOM cpu.

But, on testing, although interrupt is seen in the driver, it is not delivered to userspace.

These are the steps I'm doing:

echo "10ee 0007"> /sys/bus/pci/drivers/uio_pci_generic/new_id

I use userspace application which wait for interrupt, just as described in code example here.

I than trigger an interrupt from FPGA, but no print from the userspace application is given and there is an exception:

irq 23: nobody cared (try booting with the "irqpoll" option)
[ 91.030760] CPU: 2 PID: 0 Comm: swapper/2 Not tainted 4.18.16 #6
[ 91.037037] Hardware name: /conga-MA5, BIOS MA50R000 10/30/2019
[ 91.043302] Call Trace:
[ 91.045881] <IRQ>
[ 91.048002] dump_stack+0x5c/0x80
[ 91.051464] __report_bad_irq+0x35/0xaf
[ 91.055465] note_interrupt.cold.9+0xa/0x63
[ 91.059823] handle_irq_event_percpu+0x68/0x70
[ 91.064470] handle_irq_event+0x37/0x57
[ 91.068481] handle_fasteoi_irq+0x97/0x150
...
[ 91.176043] handlers:
[ 91.178419] [<00000000ec05b056>] uio_interrupt
[ 91.183054] Disabling IRQ #23

I started debugging the uio driver, and I see that interrupt handler is called, but not handled:

static irqreturn_t irqhandler(int irq, struct uio_info *info)
{
        struct uio_pci_generic_dev *gdev = to_uio_pci_generic_dev(info);
printk("here 1\n");    <<--- we get here interrupt is catched here
        if (!pci_check_and_mask_intx(gdev->pdev))
                return IRQ_NONE;
printk("here 2\n");    <<--- But we never get here
        /* UIO core will signal the user process. */
        return IRQ_HANDLED;
}

It seems that pci_check_and_mask_intx() does not detect it as an interrupt from our device!

The device appear as following:

02:00.0 RAM memory: Xilinx Corporation Default PCIe endpoint ID
        Subsystem: Xilinx Corporation Default PCIe endpoint ID
        Control: I/O- Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
        Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
        Interrupt: pin A routed to IRQ 23
        Region 0: Memory at 91200000 (32-bit, non-prefetchable) [size=1M]
        Capabilities: [40] Power Management version 3
                Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
                Status: D0 NoSoftRst+ PME-Enable- DSel=0 DScale=0 PME-
        Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
                Address: 0000000000000000  Data: 0000
        Capabilities: [58] Express (v1) Endpoint, MSI 00
                DevCap: MaxPayload 256 bytes, PhantFunc 1, Latency L0s <64ns, L1 <1us
                        ExtTag+ AttnBtn- AttnInd- PwrInd- RBE+ FLReset- SlotPowerLimit 10.000W
                DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
                        RlxdOrd+ ExtTag+ PhantFunc- AuxPwr- NoSnoop+
                        MaxPayload 256 bytes, MaxReadReq 512 bytes
                DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
                LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s, Exit Latency L0s unlimited
                        ClockPM- Surprise- LLActRep- BwNot- ASPMOptComp-
                LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- CommClk+
                        ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
                LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
        Capabilities: [100 v1] Device Serial Number 00-00-00-00-00-00-00-00
        Kernel driver in use: uio_pci_generic

Is it an issue of FPGA device ? or does UIO generic PCI does not support interrupts ?


hrtimer state gets changed, and getting crash while accessing it via user defined soft-uart driver

$
0
0

I have taken the Software-based serial port module code from [here] (https://github.com/adrianomarto/soft_uart/) and implemented it for my application for the iMX-6 processor.

Although my driver is working fine to send/receive data between MCU (STM32L476) and MPU (iMX-6) via this driver module. I am getting crash for "hrtimer state" after running this module for hours. crash dump is attached below.

Below is the details for the setup:

  • This module is used to receive incoming usart data from STM32 MCU usart set @ 4800 baud, 8N1.
  • MPU two gpio pins are configured to mimic usart through bit-bang method.
  • MPU software usart module has baud set to 4800, 8N1 with no flow control.

I am suspecting that somewhere in the soft-uart module "hrtimer_start" is called so much frequently or it is being handled incorrectly such that hrtimer is getting enqueued from "__run_hrtimer" as soon as the software is expecting it to be in callback state and that is the cause of the crash. Can anyone have a similar issue? or have information about this behavior please guide me. what could cause this kind of behavior?

Below is the code for software-based UART module

#include <linux/gpio.h> 
#include <linux/hrtimer.h>
#include <linux/interrupt.h>
#include <linux/ktime.h>
#include <linux/tty.h>
#include <linux/tty_flip.h>
#include <linux/version.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/tty_driver.h>

#define SOFT_UART_MAJOR            0
#define N_PORTS                    1
#define NONE                       0
#define TX_BUFFER_FLUSH_TIMEOUT 4000  // milliseconds
#define DEV_BAUDRATE            4800

MODULE_LICENSE("GPL");
MODULE_AUTHOR("General");
MODULE_DESCRIPTION("Software-UART");
MODULE_VERSION("0.2");

//***********************************************************************************************//
int imx_soft_uart_init(const int gpio_tx, const int gpio_rx);
int imx_soft_uart_finalize(void);
int imx_soft_uart_open(struct tty_struct* tty);
int imx_soft_uart_close(void);
int imx_soft_uart_set_rx_callback(void (*callback)(unsigned char));
int imx_soft_uart_set_baudrate(const int baudrate);
int imx_soft_uart_send_string(const unsigned char* string, int string_size);
int imx_soft_uart_get_tx_queue_room(void);
int imx_soft_uart_get_tx_queue_size(void);
//***********************************************************************************************//

static irq_handler_t handle_rx_start(unsigned int irq, void* device, struct pt_regs* registers);
static irq_handler_t handle_rx_bytes(unsigned int irq, void* device, struct pt_regs* registers);

static enum hrtimer_restart handle_tx(struct hrtimer* timer);
static enum hrtimer_restart handle_rx(struct hrtimer* timer);
static void receive_character(unsigned char character);

static struct queue queue_tx;
static struct tty_struct* current_tty = NULL;
static DEFINE_MUTEX(current_tty_mutex);
static struct hrtimer timer_tx;
static struct hrtimer timer_rx;
static ktime_t period;
static ktime_t half_period;
unsigned long long t_half_period;
static int rx_bit_index = -1;
static void (*rx_callback)(unsigned char) = NULL;

//***********************************************************************************************//
#define QUEUE_MAX_SIZE  256

struct queue
{
  int front;
  int rear;
  int size;
  unsigned char data[QUEUE_MAX_SIZE];
};


void initialize_queue(struct queue* queue);
int  enqueue_character(struct queue* queue, const unsigned char character);
int  dequeue_character(struct queue* queue, unsigned char* character);
int  enqueue_string(struct queue* queue, const unsigned char* string, int string_size);
int  get_queue_room(struct queue* queue);
int  get_queue_size(struct queue* queue);
//***********************************************************************************************//

/**
 * Initializes a given queue.
 * @param queue given queue
 */
void initialize_queue(struct queue* queue)
{
  queue->size  = 0;
  queue->front = 0;
  queue->rear  = 0;
}

/**
 * Adds a given character into a given queue.
 * @param queue given queue
 * @param character given character
 * @return 1 if the character is added to the queue. 0 if the queue is full.
 */
int enqueue_character(struct queue* queue, const unsigned char character)
{
  int success = 0;
  if (queue->size < QUEUE_MAX_SIZE)
  {
    if (queue->size != 0)
    {
      queue->rear++;
      if (queue->rear >= QUEUE_MAX_SIZE)
      {
        queue->rear = 0;
      }
    }
    else
    {
      queue->rear = 0;
      queue->front = 0;
    }
    queue->data[queue->rear] = character;
    queue->size++;
    success = 1;
  }
  return success;
}

/**
 * Gets a character from a fiven queue.
 * @param queue given queue
 * @param character a character
 * @return 1 if a character is fetched from the queue. 0 if the queue is empy.
 */
int dequeue_character(struct queue* queue, unsigned char* character)
{
  int success = 0;
  if (queue->size > 0)
  {
    *character = queue->data[queue->front];
    queue->front++;
    if (queue->front >= QUEUE_MAX_SIZE)
    {
      queue->front = 0;
    }
    queue->size--;
    success = 1;
  }
  return success;
}

/**
 * Adds a given string to a given queue.
 * @param queue given queue
 * @param string given string
 * @param string_size size of the given string
 * @return The amount of characters successfully added to the queue.
 */
int enqueue_string(struct queue* queue, const unsigned char* string, int string_size)
{
  int n = 0;
  while (n < string_size && enqueue_character(queue, string[n]))
  {
    n++;
  }
  return n;
}

/**
 * Gets the number of characters that can be added to a given queue.
 * @return number of characters.
 */
int get_queue_room(struct queue* queue)
{
  return QUEUE_MAX_SIZE - queue->size;
}

/**
 * Gets the number of characters contained in a given queue.
 * @return number of characters.
 */
int get_queue_size(struct queue* queue)
{
  return queue->size;
}

//****************************************************************************//

static int gpio_tx = 147;
module_param(gpio_tx, int, 0);

static int gpio_rx = 146;
module_param(gpio_rx, int, 0);

// Module prototypes.
static int  soft_uart_open(struct tty_struct*, struct file*);
static void soft_uart_close(struct tty_struct*, struct file*);
static int  soft_uart_write(struct tty_struct*, const unsigned char*, int);
static int  soft_uart_write_room(struct tty_struct*);
static void soft_uart_flush_buffer(struct tty_struct*);
static int  soft_uart_chars_in_buffer(struct tty_struct*);
static void soft_uart_set_termios(struct tty_struct*, struct ktermios*);
static void soft_uart_stop(struct tty_struct*);
static void soft_uart_start(struct tty_struct*);
static void soft_uart_hangup(struct tty_struct*);
static int  soft_uart_tiocmget(struct tty_struct*);
static int  soft_uart_tiocmset(struct tty_struct*, unsigned int, unsigned int);
static int  soft_uart_ioctl(struct tty_struct*, unsigned int, unsigned int long);
static void soft_uart_throttle(struct tty_struct*);
static void soft_uart_unthrottle(struct tty_struct*);

// Module operations.
static const struct tty_operations soft_uart_operations = {
  .open            = soft_uart_open,
  .close           = soft_uart_close,
  .write           = soft_uart_write,
  .write_room      = soft_uart_write_room,
  .flush_buffer    = soft_uart_flush_buffer,
  .chars_in_buffer = soft_uart_chars_in_buffer,
  .ioctl           = soft_uart_ioctl,
  .set_termios     = soft_uart_set_termios,
  .stop            = soft_uart_stop,
  .start           = soft_uart_start,
  .hangup          = soft_uart_hangup,
  .tiocmget        = soft_uart_tiocmget,
  .tiocmset        = soft_uart_tiocmset,
  .throttle        = soft_uart_throttle,
  .unthrottle      = soft_uart_unthrottle
};

// Driver instance.
static struct tty_driver* soft_uart_driver = NULL;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
static struct tty_port port;
#endif

/**
 * Module initialization.
 */
static int __init soft_uart_init(void)
{
  imx_soft_uart_set_baudrate(DEV_BAUDRATE);
  printk(KERN_INFO "soft_uart: Initializing module...#2\n");
  if (!imx_soft_uart_init(gpio_tx, gpio_rx))
  {
    printk(KERN_ALERT "soft_uart: Failed initialize GPIO.\n");
    return -ENOMEM;
  }

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  printk(KERN_INFO "soft_uart: LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0).\n");

  // Initializes the port.
  tty_port_init(&port);
  port.low_latency = 0;

  // Allocates the driver.
  soft_uart_driver = tty_alloc_driver(N_PORTS, TTY_DRIVER_REAL_RAW);

  // Returns if the allocation fails.
  if (IS_ERR(soft_uart_driver))
  {
    printk(KERN_ALERT "soft_uart: Failed to allocate the driver.\n");
    return -ENOMEM;
  }
#else
  printk(KERN_INFO "soft_uart: LINUX_VERSION_CODE < KERNEL_VERSION(3,10,0).\n");

  // Allocates the driver.
  soft_uart_driver = alloc_tty_driver(N_PORTS);

  // Returns if the allocation fails.
  if (!soft_uart_driver)
  {
    printk(KERN_ALERT "soft_uart: Failed to allocate the driver.\n");
    return -ENOMEM;
  }
#endif

  // Initializes the driver.
  soft_uart_driver->owner                 = THIS_MODULE;
  soft_uart_driver->driver_name           = "soft_uart";
  soft_uart_driver->name                  = "ttySOFT";
  soft_uart_driver->major                 = SOFT_UART_MAJOR;
  soft_uart_driver->minor_start           = 0;
  soft_uart_driver->flags                 = TTY_DRIVER_REAL_RAW;
  soft_uart_driver->type                  = TTY_DRIVER_TYPE_SERIAL;
  soft_uart_driver->subtype               = SERIAL_TYPE_NORMAL;
  soft_uart_driver->init_termios          = tty_std_termios;
  soft_uart_driver->init_termios.c_ispeed = 4800;
  soft_uart_driver->init_termios.c_ospeed = 4800;
  soft_uart_driver->init_termios.c_cflag  = B4800 | CREAD | CS8 | CLOCAL;

  // Sets the callbacks for the driver.
  tty_set_operations(soft_uart_driver, &soft_uart_operations);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  // Link the port with the driver.
  tty_port_link_device(&port, soft_uart_driver, 0);
#endif

  // Registers the TTY driver.
  if (tty_register_driver(soft_uart_driver))
  {
    printk(KERN_ALERT "soft_uart: Failed to register the driver.\n");
    put_tty_driver(soft_uart_driver);
    return -1; // return if registration fails
  }
  printk(KERN_INFO "soft_uart: baudrate : %d\n", DEV_BAUDRATE);
  printk(KERN_INFO "soft_uart: Module initialized.\n");
  return 0;
}

/**
 * Cleanup function that gets called when the module is unloaded.
 */
static void __exit soft_uart_exit(void)
{
  printk(KERN_INFO "soft_uart: Finalizing the module...\n");

  // Finalizes the soft UART.
  if (!imx_soft_uart_finalize())
  {
    printk(KERN_ALERT "soft_uart: Something went wrong whilst finalizing the soft UART.\n");
  }

  // Unregisters the driver.
  if (tty_unregister_driver(soft_uart_driver))
  {
    printk(KERN_ALERT "soft_uart: Failed to unregister the driver.\n");
  }

  put_tty_driver(soft_uart_driver);
  printk(KERN_INFO "soft_uart: Module finalized.\n");
}

/**
 * Opens a given TTY device.
 * @param tty given TTY device
 * @param file
 * @return error code.
 */
static int soft_uart_open(struct tty_struct* tty, struct file* file)
{
  int error = NONE;

  if (imx_soft_uart_open(tty))
  {
    printk(KERN_INFO "soft_uart: Device opened.\n");
  }
  else
  {
    printk(KERN_ALERT "soft_uart: Device busy.\n");
    error = -ENODEV;
  }

  return error;
}

/**
 * Closes a given TTY device.
 * @param tty
 * @param file
 */
static void soft_uart_close(struct tty_struct* tty, struct file* file)
{
  // Waits for the TX buffer to be empty before closing the UART.
  int wait_time = 0;
  while ((imx_soft_uart_get_tx_queue_size() > 0)
    && (wait_time < TX_BUFFER_FLUSH_TIMEOUT))
  {
    msleep(100);
    wait_time += 100;
  }

  if (imx_soft_uart_close())
  {
    printk(KERN_INFO "soft_uart: Device closed.\n");
  }
  else
  {
    printk(KERN_ALERT "soft_uart: Could not close the device.\n");
  }
}

/**
 * Writes the contents of a given buffer into a given TTY device.
 * @param tty given TTY device
 * @param buffer given buffer
 * @param buffer_size number of bytes contained in the given buffer
 * @return number of bytes successfuly written into the TTY device
 */
static int soft_uart_write(struct tty_struct* tty, const unsigned char* buffer, int buffer_size)
{
  return imx_soft_uart_send_string(buffer, buffer_size);
}

/**
 * Tells the kernel the number of bytes that can be written to a given TTY.
 * @param tty given TTY
 * @return number of bytes
 */
static int soft_uart_write_room(struct tty_struct* tty)
{
  return imx_soft_uart_get_tx_queue_room();
}

/**
 * Does nothing.
 * @param tty
 */
static void soft_uart_flush_buffer(struct tty_struct* tty)
{
}

/**
 * Tells the kernel the number of bytes contained in the buffer of a given TTY.
 * @param tty given TTY
 * @return number of bytes
 */
static int soft_uart_chars_in_buffer(struct tty_struct* tty)
{
  return imx_soft_uart_get_tx_queue_size();
}

/**
 * Sets the UART parameters for a given TTY (only the baudrate is taken into account).
 * @param tty given TTY
 * @param termios parameters
 */
static void soft_uart_set_termios(struct tty_struct* tty, struct ktermios* termios)
{
  int cflag = 0;
  speed_t baudrate = tty_get_baud_rate(tty);
  printk(KERN_INFO "soft_uart: soft_uart_set_termios: baudrate = %d.\n", baudrate);

  // Gets the cflag.
#if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
  cflag = tty->termios.c_cflag;
#else
  cflag = tty->termios->c_cflag;
#endif

  // Verifies the number of data bits (it must be 8).
  if ((cflag & CSIZE) != CS8)
  {
    printk(KERN_ALERT "soft_uart: Invalid number of data bits.\n");
  }

  // Verifies the number of stop bits (it must be 1).
  if (cflag & CSTOPB)
  {
    printk(KERN_ALERT "soft_uart: Invalid number of stop bits.\n");
  }

  // Verifies the parity (it must be none).
  if (cflag & PARENB)
  {
    printk(KERN_ALERT "soft_uart: Invalid parity.\n");
  }

  // Configure the baudrate.
  if (!imx_soft_uart_set_baudrate(baudrate))
  {
    printk(KERN_ALERT "soft_uart: Invalid baudrate.\n");
  }
}

/**
 * Does nothing.
 * @param tty
 */
static void soft_uart_stop(struct tty_struct* tty)
{
  printk(KERN_DEBUG "soft_uart: soft_uart_stop.\n");
}

/**
 * Does nothing.
 * @param tty
 */
static void soft_uart_start(struct tty_struct* tty)
{
  printk(KERN_DEBUG "soft_uart: soft_uart_start.\n");
}

/**
 * Does nothing.
 * @param tty
 */
static void soft_uart_hangup(struct tty_struct* tty)
{
  printk(KERN_DEBUG "soft_uart: soft_uart_hangup.\n");
}

/**
 * Does nothing.
 * @param tty
 */
static int soft_uart_tiocmget(struct tty_struct* tty)
{
  return 0;
}

/**
 * Does nothing.
 * @param tty
 * @param set
 * @param clear
 */
static int soft_uart_tiocmset(struct tty_struct* tty, unsigned int set, unsigned int clear)
{
  return 0;
}

/**
 * Does nothing.
 * @param tty
 * @param command
 * @param parameter
 */
static int soft_uart_ioctl(struct tty_struct* tty, unsigned int command, unsigned int long parameter)
{
  int error = NONE;

  switch (command)
  {
    case TIOCMSET:
      error = NONE;
      break;

    case TIOCMGET:
      error = NONE;
      break;

      default:
        error = -ENOIOCTLCMD;
        break;
  }

  return error;
}

/**
 * Does nothing.
 * @param tty
 */
static void soft_uart_throttle(struct tty_struct* tty)
{
  printk(KERN_DEBUG "soft_uart: soft_uart_throttle.\n");
}

/**
 * Does nothing.
 * @param tty
 */
static void soft_uart_unthrottle(struct tty_struct* tty)
{
  printk(KERN_DEBUG "soft_uart: soft_uart_unthrottle.\n");
}

// Module entry points.
module_init(soft_uart_init);
module_exit(soft_uart_exit);

//**************************************************************************************************//

/**
 * Initializes the Soft UART infrastructure.
 * This must be called during the module initialization.
 * The GPIO pin used as TX is configured as output.
 * The GPIO pin used as RX is configured as input.
 * @param gpio_tx GPIO pin used as TX
 * @param gpio_rx GPIO pin used as RX
 * @return 1 if the initialization is successful. 0 otherwise.
 */
int imx_soft_uart_init(const int _gpio_tx, const int _gpio_rx)
{
  bool success = true;

  mutex_init(&current_tty_mutex);

  // Initializes the TX timer.
  hrtimer_init(&timer_tx, CLOCK_MONOTONIC_RAW, HRTIMER_MODE_REL);
  timer_tx.function = &handle_tx;

  // Initializes the RX timer.
  hrtimer_init(&timer_rx, CLOCK_MONOTONIC_RAW, HRTIMER_MODE_REL);
  timer_rx.function = &handle_rx;

  // Initializes the GPIO pins.
  gpio_tx = _gpio_tx;
  gpio_rx = _gpio_rx;

  success &= gpio_request(gpio_tx, "soft_uart_tx") == 0;
  success &= gpio_direction_output(gpio_tx, 1) == 0;

  success &= gpio_request(gpio_rx, "soft_uart_rx") == 0;
  success &= gpio_direction_input(gpio_rx) == 0;

     // Initializes the interruption.
  // success &= request_threaded_irq(
  //   gpio_to_irq(gpio_rx), (irq_handler_t) handle_rx_bytes,
  //   (irq_handler_t) handle_rx_start,
  //   IRQF_TRIGGER_FALLING,
  //   "soft_uart_irq_handler",
  //   NULL) == 0;

  // Initializes the interruption.
  success &= request_irq(
    gpio_to_irq(gpio_rx),
    (irq_handler_t) handle_rx_start,
    IRQF_TRIGGER_FALLING,
    "soft_uart_irq_handler",
    NULL) == 0;
  disable_irq(gpio_to_irq(gpio_rx));

  return success;
}

/**
 * Finalizes the Soft UART infrastructure.
 */
int imx_soft_uart_finalize(void)
{
  free_irq(gpio_to_irq(gpio_rx), NULL);
  gpio_set_value(gpio_tx, 0);
  gpio_free(gpio_tx);
  gpio_free(gpio_rx);
  return 1;
}

/**
 * Opens the Soft UART.
 * @param tty
 * @return 1 if the operation is successful. 0 otherwise.
 */
int imx_soft_uart_open(struct tty_struct* tty)
{
  int success = 0;
  mutex_lock(&current_tty_mutex);
  rx_bit_index = -1;
  if (current_tty == NULL)
  {
    current_tty = tty;
    initialize_queue(&queue_tx);
    success = 1;
    enable_irq(gpio_to_irq(gpio_rx));
  }
  mutex_unlock(&current_tty_mutex);
  return success;
}

/**
 * Closes the Soft UART.
 */
int imx_soft_uart_close(void)
{
  mutex_lock(&current_tty_mutex);
  disable_irq(gpio_to_irq(gpio_rx));
  hrtimer_cancel(&timer_tx);
  hrtimer_cancel(&timer_rx);
  current_tty = NULL;
  mutex_unlock(&current_tty_mutex);
  return 1;
}

/**
 * Sets the Soft UART baudrate.
 * @param baudrate desired baudrate
 * @return 1 if the operation is successful. 0 otherwise.
 */
int imx_soft_uart_set_baudrate(const int baudrate) 
{
  period = ktime_set(0, 1000000000/baudrate);
  half_period = ktime_set(0, 1000000000/baudrate/2);
  t_half_period = half_period.tv64;
  gpio_set_debounce(gpio_rx, 1000/baudrate/2);
  return 1;
}

/**
 * Adds a given string to the TX queue.
 * @param string given string
 * @param string_size size of the given string
 * @return The amount of characters successfully added to the queue.
 */
int imx_soft_uart_send_string(const unsigned char* string, int string_size)
{
  int result = enqueue_string(&queue_tx, string, string_size);

  // Starts the TX timer if it is not already running.
  if (!hrtimer_active(&timer_tx))
  {
    hrtimer_start(&timer_tx, period, HRTIMER_MODE_REL);
  }

  return result;
}

/*
 * Gets the number of characters that can be added to the TX queue.
 * @return number of characters.
 */
int imx_soft_uart_get_tx_queue_room(void)
{
  return get_queue_room(&queue_tx);
}

/*
 * Gets the number of characters in the TX queue.
 * @return number of characters.
 */
int imx_soft_uart_get_tx_queue_size(void)
{
  return get_queue_size(&queue_tx);
}

/**
 * Sets the callback function to be called on received character.
 * @param callback the callback function
 */
int imx_soft_uart_set_rx_callback(void (*callback)(unsigned char))
{
    rx_callback = callback;
    return 1;
}

//-----------------------------------------------------------------------------
// Internals
//-----------------------------------------------------------------------------

/**
 * If we are waiting for the RX start bit, then starts the RX timer. Otherwise,
 * does nothing.
 */
static irq_handler_t handle_rx_start(unsigned int irq, void* device, struct pt_regs* registers)
{
  if (rx_bit_index == -1)
  {
    hrtimer_start(&timer_rx, ktime_set( 0, t_half_period), HRTIMER_MODE_REL);
  }
  return (irq_handler_t) IRQ_HANDLED;
}

/**
 * If we are waiting for the RX start bit, then starts the RX timer. Otherwise,
 * does nothing.
 */
static irq_handler_t handle_rx_bytes(unsigned int irq, void* device, struct pt_regs* registers)
{
  return (irq_handler_t) IRQ_WAKE_THREAD;
}

/**
 * Dequeues a character from the TX queue and sends it.
 */
static enum hrtimer_restart handle_tx(struct hrtimer* timer)
{
  ktime_t current_time = ktime_get();
  static unsigned char character = 0;
  static int bit_index = -1;
  enum hrtimer_restart result = HRTIMER_NORESTART;
  bool must_restart_timer = false;

  // Start bit.
  if (bit_index == -1)
  {
    if (dequeue_character(&queue_tx, &character))
    {
      gpio_set_value(gpio_tx, 0);
      bit_index++;
      must_restart_timer = true;
    }
  }

  // Data bits.
  else if (0 <= bit_index && bit_index < 8)
  {
    gpio_set_value(gpio_tx, 1 & (character >> bit_index));
    bit_index++;
    must_restart_timer = true;
  }

  // Stop bit.
  else if (bit_index == 8)
  {
    gpio_set_value(gpio_tx, 1);
    character = 0;
    bit_index = -1;
    must_restart_timer = get_queue_size(&queue_tx) > 0;
  }

  // Restarts the TX timer.
  if (must_restart_timer)
  {
    hrtimer_forward(&timer_tx, current_time, period);
    result = HRTIMER_RESTART;
  }

  return result;
}

/*
 * Receives a character and sends it to the kernel.
 */
static enum hrtimer_restart handle_rx(struct hrtimer* timer)
{
  ktime_t current_time = ktime_get();
  static unsigned int character = 0;
  int bit_value = gpio_get_value(gpio_rx);
  enum hrtimer_restart result = HRTIMER_NORESTART;
  bool must_restart_timer = false;

  // Start bit.
  if (rx_bit_index == -1)
  {
    rx_bit_index++;
    character = 0;
    must_restart_timer = true;
  }

  // Data bits.
  else if (0 <= rx_bit_index && rx_bit_index < 8)
  {
    if (bit_value == 0)
    {
      character &= 0xfeff;
    }
    else
    {
      character |= 0x0100;
    }

    rx_bit_index++;
    character >>= 1;
    must_restart_timer = true;
  }

  // Stop bit.
  else if (rx_bit_index == 8)
  {
    receive_character(character);
    rx_bit_index = -1;
  }

  // Restarts the RX timer.
  if (must_restart_timer)
  {
    hrtimer_forward(&timer_rx, current_time, period);
    result = HRTIMER_RESTART;
  }

  return result;
}

/**
 * Adds a given (received) character to the RX buffer, which is managed by the kernel,
 * and then flushes (flip) it.
 * @param character given character
 */
void receive_character(unsigned char character)
{
  mutex_lock(&current_tty_mutex);
  if (rx_callback != NULL) {
      (*rx_callback)(character);
  } else {
    #if LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0)
      if (current_tty != NULL && current_tty->port != NULL)
      {
        tty_insert_flip_char(current_tty->port, character, TTY_NORMAL);
        tty_flip_buffer_push(current_tty->port);
      }
    #else
      if (tty != NULL)
      {
        tty_insert_flip_char(current_tty, character, TTY_NORMAL);
        tty_flip_buffer_push(tty);
      }
    #endif
  }
  mutex_unlock(&current_tty_mutex);
}

Crash details:

[2019-11-23 21:58:12] ------------[ cut here ]------------
[2019-11-23 21:58:12] WARNING: CPU: 1 PID: 707 at /home/shalin/Documents/mainboard_src/yocto/core-image-base/linux_src/kernel/time/h)
[2019-11-23 21:58:12] Modules linked in: brcmfmac brcmutil usb_f_ecm g_ether usb_f_rndis u_ether libcomposite soft_uart bt8xxx(O) sd8xxx(O) mlan(PO) cfg80211
[2019-11-23 21:58:12] CPU: 1 PID: 707 Comm: hw_watchdog Tainted: P           O    4.1.15-2.0.0-ga+yocto+g83728b9 #4
[2019-11-23 21:58:12] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[2019-11-23 21:58:12] Backtrace: 
[2019-11-23 21:58:12] [<8010c358>] (dump_backtrace) from [<8010c5d4>] (show_stack+0x20/0x24)
[2019-11-23 21:58:12]  r7:80190514 r6:80e45ca0 r5:00000000 r4:80e45ca0
[2019-11-23 21:58:12] [<8010c5b4>] (show_stack) from [<80923a58>] (dump_stack+0x7c/0xbc)
[2019-11-23 21:58:12] [<809239dc>] (dump_stack) from [<80133844>] (warn_slowpath_common+0x94/0xc4)
[2019-11-23 21:58:12]  r7:80190514 r6:000004ce r5:00000009 r4:00000000
[2019-11-23 21:58:12] [<801337b0>] (warn_slowpath_common) from [<80133978>] (warn_slowpath_null+0x2c/0x34)
[2019-11-23 21:58:12]  r8:00000001 r7:ab72e3c0 r6:ab72e3f8 r5:00005e38 r4:7f19e2a8
[2019-11-23 21:58:12] [<8013394c>] (warn_slowpath_null) from [<80190514>] (__run_hrtimer+0x248/0x294)
[2019-11-23 21:58:12] [<801902cc>] (__run_hrtimer) from [<8019096c>] (hrtimer_interrupt+0x138/0x344)
[2019-11-23 21:58:12]  r9:00000001 r8:ab72e3c0 r7:00000000 r6:ab72e3f8 r5:00005e38 r4:be670b5f
[2019-11-23 21:58:12] [<80190834>] (hrtimer_interrupt) from [<80110d24>] (twd_handler+0x40/0x50)
[2019-11-23 21:58:12]  r10:80e46000 r9:a8006d80 r8:00000001 r7:00000010 r6:a8035340 r5:ab7344c0
[2019-11-23 21:58:12]  r4:00000001
[2019-11-23 21:58:12] [<80110ce4>] (twd_handler) from [<80180574>] (handle_percpu_devid_irq+0xac/0x1d0)
[2019-11-23 21:58:12]  r5:ab7344c0 r4:00000010
[2019-11-23 21:58:12] [<801804c8>] (handle_percpu_devid_irq) from [<8017bbdc>] (generic_handle_irq+0x3c/0x4c)
[2019-11-23 21:58:12]  r10:a872bcc0 r9:a8020000 r8:00000001 r7:00000000 r6:00000010 r5:00000000
[2019-11-23 21:58:12]  r4:00000010 r3:801804c8
[2019-11-23 21:58:12] [<8017bba0>] (generic_handle_irq) from [<8017bf08>] (__handle_domain_irq+0x8c/0xfc)
[2019-11-23 21:58:12]  r5:00000000 r4:80d9ac34
[2019-11-23 21:58:12] [<8017be7c>] (__handle_domain_irq) from [<80101560>] (gic_handle_irq+0x34/0x6c)
[2019-11-23 21:58:12]  r10:000033d4 r9:00000000 r8:00000006 r7:f4a00100 r6:a872bcc0 r5:80e02f7c
[2019-11-23 21:58:12]  r4:f4a0010c r3:a872bcc0
[2019-11-23 21:58:12] [<8010152c>] (gic_handle_irq) from [<8010d240>] (__irq_svc+0x40/0x74)
[2019-11-23 21:58:12] Exception stack(0xa872bcc0 to 0xa872bd08)
[2019-11-23 21:58:12] bcc0: 00000001 80000093 00000001 20000013 80ea5eb0 00000002 0000002b 80ed14a8
[2019-11-23 21:58:12] bce0: 00000006 00000000 000033d4 a872bd5c a872bc58 a872bd08 809296d8 8017a7a0
[2019-11-23 21:58:12] bd00: 60000013 ffffffff
[2019-11-23 21:58:12]  r7:a872bcf4 r6:ffffffff r5:60000013 r4:8017a7a0
[2019-11-23 21:58:12] [<8017a468>] (console_unlock) from [<8017abdc>] (vprintk_emit+0x2ac/0x50c)
[2019-11-23 21:58:12]  r10:00000000 r9:00000000 r8:00000000 r7:80e915a8 r6:80ed1efc r5:0000002a
[2019-11-23 21:58:12]  r4:00000001
[2019-11-23 21:58:12] [<8017a930>] (vprintk_emit) from [<8056a758>] (dev_vprintk_emit+0xc0/0x1f8)
[2019-11-23 21:58:12]  r10:a872bebc r9:80c0543c r8:80c36ab0 r7:a872bde4 r6:a8512200 r5:80e02508
[2019-11-23 21:58:12]  r4:00000013
[2019-11-23 21:58:12] [<8056a698>] (dev_vprintk_emit) from [<8056a8d0>] (dev_printk_emit+0x40/0x5c)
[2019-11-23 21:58:12]  r10:a86dc788 r9:00000008 r8:00000000 r7:a602bc38 r6:a849649c r5:a84964b4
[2019-11-23 21:58:12]  r4:80e02508
[2019-11-23 21:58:12] [<8056a894>] (dev_printk_emit) from [<8056ac40>] (__dev_printk+0x58/0x98)
[2019-11-23 21:58:12]  r3:80c36ab0 r2:80c0543c
[2019-11-23 21:58:12]  r4:80e02508
[2019-11-23 21:58:12] [<8056abe8>] (__dev_printk) from [<8056ae28>] (dev_crit+0x58/0x74)
[2019-11-23 21:58:12] [<8056add4>] (dev_crit) from [<806b9f0c>] (watchdog_release+0xd4/0xd8)
[2019-11-23 21:58:12]  r3:00000003 r2:00000000 r1:80c36b18
[2019-11-23 21:58:12]  r4:a8496434
[2019-11-23 21:58:12] [<806b9e38>] (watchdog_release) from [<8024ce80>] (__fput+0x90/0x1e0)
[2019-11-23 21:58:12]  r7:a602bc38 r6:a8534850 r5:a84e8da8 r4:a86dc780
[2019-11-23 21:58:12] [<8024cdf0>] (__fput) from [<8024d040>] (____fput+0x18/0x1c)
[2019-11-23 21:58:12]  r10:00000000 r9:a872a000 r8:80108124 r7:a8b27700 r6:80e90f20 r5:00000000
[2019-11-23 21:58:12]  r4:a8b27b18
[2019-11-23 21:58:12] [<8024d028>] (____fput) from [<8014f834>] (task_work_run+0xc0/0xf8)
[2019-11-23 21:58:12] [<8014f774>] (task_work_run) from [<8010bbd8>] (do_work_pending+0x8c/0xb4)
[2019-11-23 21:58:12]  r7:00000006 r6:a872bfb0 r5:80108124 r4:a872a000
[2019-11-23 21:58:12] [<8010bb4c>] (do_work_pending) from [<80107fcc>] (work_pending+0xc/0x20)
[2019-11-23 21:58:12]  r7:00000006 r6:00010a78 r5:00000004 r4:00000001
[2019-11-23 21:58:12] ---[ end trace 4de5a0751e851227 ]---

Linux latest stable compilation: cannot represent change to vmlinux-gdb.py:

$
0
0

The issue:

  • It's been 20 years since:
    • I last wrote >1K of C code
    • compiled anything >10K source lines
  • My current Distro's support (Ubuntu 16.04) for an 0cf3:e300 Atheros Communications, Inc. WiFi driver is abysmal: 8-12Mbps is the best I get.

What I know about kernel version priorities:

  1. Use your own distro's kernel (out of the question: just too slow)
  2. Use the latest stable kernel
  3. Use the latest LTS kernel

What I've tried:

git clone git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
git checkout -b stable v5.1.2
cp /boot/config-`uname -r` .config
yes '' | make oldconfig
make -j `getconf _NPROCESSORS_ONLN\' deb-pkg LOCALVERSION=-fab

Which gives me the following error:

dpkg-source: error: cannot represent change to vmlinux-gdb.py:
dpkg-source: error:   new version is symlink to /home/fab-user/Documents/Source/linux/scripts/gdb/vmlinux-gdb.py
dpkg-source: error:   old version is nonexistent

in the following full output:

make -j `getconf _NPROCESSORS_ONLN` deb-pkg LOCALVERSION=-fab
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/confdata.o
  HOSTCC  scripts/kconfig/expr.o
  LEX     scripts/kconfig/lexer.lex.c
  YACC    scripts/kconfig/parser.tab.h
  YACC    scripts/kconfig/parser.tab.c
  HOSTCC  scripts/kconfig/preprocess.o
  HOSTCC  scripts/kconfig/symbol.o
  HOSTCC  scripts/kconfig/lexer.lex.o
  HOSTCC  scripts/kconfig/parser.tab.o
  HOSTLD  scripts/kconfig/conf
scripts/kconfig/conf  --syncconfig Kconfig
  UPD     include/config/kernel.release
make clean
/bin/bash ./scripts/package/mkdebian
  TAR     linux-5.1.2-fab.tar.gz
origversion=$(dpkg-parsechangelog -SVersion |sed 's/-[^-]*$//');\
    mv linux-5.1.2-fab.tar.gz ../linux-5.1.2-fab_${origversion}.orig.tar.gz
dpkg-buildpackage -r"fakeroot -u" -a$(cat debian/arch)  -i.git -us -uc
dpkg-buildpackage: source package linux-5.1.2-fab
dpkg-buildpackage: source version 5.1.2-fab-1
dpkg-buildpackage: source distribution xenial
dpkg-buildpackage: source changed by fab-user <fab-user@fab-ux-predator>
dpkg-buildpackage: host architecture amd64
 dpkg-source -i.git --before-build linux
 fakeroot -u debian/rules clean
rm -rf debian/*tmp debian/files
make clean
 dpkg-source -i.git -b linux
dpkg-source: info: using source format '1.0'
dpkg-source: warning: source directory 'linux' is not <sourcepackage>-<upstreamversion> 'linux-5.1.2-fab-5.1.2-fab'
dpkg-source: warning: .orig directory name linux.orig is not <package>-<upstreamversion> (wanted linux-5.1.2-fab-5.1.2-fab.orig)
dpkg-source: info: building linux-5.1.2-fab using existing linux-5.1.2-fab_5.1.2-fab.orig.tar.gz
dpkg-source: info: building linux-5.1.2-fab in linux-5.1.2-fab_5.1.2-fab-1.diff.gz
dpkg-source: error: cannot represent change to vmlinux-gdb.py:
dpkg-source: error:   new version is symlink to /home/fab-user/Documents/Source/linux/scripts/gdb/vmlinux-gdb.py
dpkg-source: error:   old version is nonexistent
dpkg-source: warning: ignoring deletion of file .scmversion, use --include-removal to override
dpkg-source: error: cannot represent change to linux-5.1.1-fab.tar.gz: binary file contents changed
dpkg-source: warning: the diff modifies the following upstream files: 
 .clang-format
 .cocciconfig
 .config.old
 .get_maintainer.ignore
 .mailmap
 .version
 CREDITS
 LICENSES/exceptions/GCC-exception-2.0
 LICENSES/exceptions/Linux-syscall-note
 LICENSES/other/Apache-2.0
 LICENSES/other/CDDL-1.0
 LICENSES/other/GPL-1.0
 LICENSES/other/ISC
 LICENSES/other/Linux-OpenIB
 LICENSES/other/MPL-1.1
 LICENSES/other/X11
 LICENSES/preferred/BSD-2-Clause
 LICENSES/preferred/BSD-3-Clause
 LICENSES/preferred/BSD-3-Clause-Clear
 LICENSES/preferred/GPL-2.0
 LICENSES/preferred/LGPL-2.0
 LICENSES/preferred/LGPL-2.1
 LICENSES/preferred/MIT
 MAINTAINERS
 Module.symvers
 README
dpkg-source: info: use the '3.0 (quilt)' format to have separate and documented changes to upstream files, see dpkg-source(1)
dpkg-source: error: unrepresentable changes to source
dpkg-buildpackage: error: dpkg-source -i.git -b linux gave error exit status 1
scripts/package/Makefile:70: recipe for target 'deb-pkg' failed
make[1]: *** [deb-pkg] Error 1
Makefile:1396: recipe for target 'deb-pkg' failed
make: *** [deb-pkg] Error 2

so I ended up doing:

git checkout -b v4.19.38 v4.19.38

which gives me up to 10MB/S instead of my distro's standard kernel's 12Mbps, and works great, but I need to reboot my machine every 24 hours if I want to keep the full speed of the WiFi Driver.

The question:

Am I doomed to stay on 4.19.38?
Is there a way to get the 4.19.39-5.12 versions working permanently?

Unable to receive customized message sent from kernel module to user application using NETLINK_ROUTE channel

$
0
0

I am working with Netlink sockets to send customized notifications regarding the state of an ethernet interface from a kernel module to a user space application over the NETLINK_ROUTE channel. I have gone through several articles and papers but all of them demonstrate an approach where you need to define your own family e.g. NETLINK_TEST in the netlink.h header or by using NETLINK_GENERIC. I am aware that the socket using NETLINK_ROUTE is already owned by the kernel so one cannot create it in the kernel module. I am unable to receive the message in the user space. Any guidance will be highly appreciated. So here are the two codes:

Kernel Module:

#include <linux/notifier.h>
#include <asm/kdebug.h> 
#include <linux/netdevice.h>
#include <linux/inetdevice.h>
#include <linux/module.h>
#include <net/sock.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <asm/types.h>
#include <linux/skbuff.h>

MODULE_LICENSE("GPL");

int my_dev_event_handler(struct notifier_block *this, unsigned long event, void *ptr)
{
struct sk_buff *skb = NULL;
struct nlmsghdr *nlh;
int size = 0;
char buf[512];

switch (event) {
    case NETDEV_REGISTER:
            sprintf (buf, "Interface:: %s is Registered with the Notifier...", ((struct net_device *) ptr)->name);
            break;

    case NETDEV_UP:
            sprintf (buf, "Interface:: %s is Up and Running...", ((struct net_device *) ptr)->name);
            break;

    case NETDEV_GOING_DOWN:
            sprintf (buf, "Interface:: %s is going Down...", ((struct net_device *) ptr)->name);
            break;

    case NETDEV_DOWN:
            sprintf (buf, "Interface:: %s is Down...", ((struct net_device *) ptr)->name);
            break;
    }

printk (KERN_INFO "Content of Buf :: %s" , buf);    

size = sizeof(buf);

skb = nlmsg_new(size, GFP_ATOMIC);

if (skb == NULL)
    {
        printk(KERN_ERR "\nError Allocating skb for sending Netlink Message...\n");
        return -1;
    }

nlh = nlmsg_put(skb, 0, 0, NLMSG_DONE, size, 0);
if (nlh == NULL)
    {
        printk(KERN_ERR "\nError putting Netlink Message data into skb...\n");
        goto nlmsg_failure;
        }   

    NETLINK_CB(skb).dst_group = RTNLGRP_LINK;
    strncpy(nlmsg_data(nlh), buf, size);
    nlmsg_end(skb, nlh);

    rtnl_notify(skb, &init_net, 0, RTNLGRP_LINK, nlh, 0);

return 0;

nlmsg_failure:
kfree_skb(skb);
return -EMSGSIZE;

}

static struct notifier_block my_dev_notifier = 
{
.notifier_call = my_dev_event_handler,
};

static int __init my_init (void)
{
printk(KERN_ALERT "***IFM Module Loaded***\n");
register_netdevice_notifier (&my_dev_notifier); 
return 0;
}

static void __exit my_end(void)
{
printk(KERN_ALERT "***IFM Module Unloaded***\n");
unregister_netdevice_notifier (&my_dev_notifier);
}

module_init(my_init);
module_exit(my_end);

User space application:

#include <asm/types.h>
#include <sys/socket.h>
#include <unistd.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <net/if.h>
#include <netinet/in.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <stdlib.h>
#include <sys/time.h>
#include <sys/types.h>

#define MAX_PAYLOAD 1024

struct sockaddr_nl src_addr, dest_addr;

int read_event (int sockint)
{
int status;
int ret = 0;
char buf[4096];
struct iovec iov = { buf, sizeof(buf) };
struct msghdr msg = { (void *) &dest_addr, sizeof dest_addr, &iov, 1, NULL, 0, 0 };
struct nlmsghdr *h;

h = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
    memset(h, 0, NLMSG_SPACE(MAX_PAYLOAD));
    h->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
    h->nlmsg_pid = getpid();
    h->nlmsg_flags = 0;

strcpy(NLMSG_DATA(h), "Hello");
printf("Sending message to kernel\n");
    sendmsg(sockint, &msg, 0);

printf("Waiting for message from kernel\n");
memset(h, 0, NLMSG_SPACE(MAX_PAYLOAD));

status = recvmsg (sockint, &msg, 0);

if (status < 0)
    {
            if (errno == EWOULDBLOCK || errno == EAGAIN)
                    return ret;

            printf ("read_netlink: Error recvmsg: %d\n", status);
            perror ("read_netlink: Error: ");
            return status;
    }

    if (status == 0)
    {
            printf ("read_netlink: EOF\n");
    }
printf("\nNo. of Bytes read : %d\n", status);
printf("Received Payload data : %s", NLMSG_DATA (h));
return ret;
}

int main (void)
{
fd_set rfds;
struct timeval tv;
int retval;

int nl_socket = socket (AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);

 if (nl_socket < 0)
 {
 printf ("Socket Open Error!");
 exit (1);
 }

 memset ((void *) &src_addr, 0, sizeof (src_addr));
 src_addr.nl_family = AF_NETLINK;
src_addr.nl_pid = getpid ();
//src_addr.nl_pid = 0;
src_addr.nl_groups = RTMGRP_LINK;
//src_addr.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR | RTMGRP_IPV6_IFADDR;

if (bind (nl_socket, (struct sockaddr *) &src_addr, sizeof (src_addr)) < 0)
{
    printf ("Socket bind failed!");
    exit (1);
}

memset(&dest_addr, 0, sizeof(dest_addr));
    dest_addr.nl_family = AF_NETLINK;
    dest_addr.nl_pid = 0; /* For Linux Kernel */
    dest_addr.nl_groups = 0; /* unicast */

while (1)
{
    FD_ZERO (&rfds);
    //FD_CLR (nl_socket, &rfds);
    FD_SET (nl_socket, &rfds);

    tv.tv_sec = 5;
    tv.tv_usec = 0;

    retval = select (FD_SETSIZE, &rfds, NULL, NULL, &tv);

    if (retval == -1)
        printf ("Error in select() \n");

    else if (retval)
    {
        printf ("Event received >> ");
        read_event (nl_socket);
    }

    else
        printf ("## Select Timed Out ## \n");
}

return 0;
}

Why is my module unable to handle kernel paging request?

$
0
0

This is my module to allocate one huge page by using dequeue_huge_page_vma() and alloc_buddy_huge_page(). To make them vma independent, I get available vm area from __get_vm_area_node(), and then get its virtual address. I want to allocate one 2MB page, however, kernel says :

[   84.944634] BUG: unable to handle kernel paging request at ffffc90013d02000
[   84.944641] IP: [<ffffffffa0ac9063>] vma_null_test+0x63/0xa3 [vma_null_test]
[   84.944650] PGD bd019067 PUD bd01a067 PMD b35c0067 PTE 0
[   84.944657] Oops: 0000 [#1] SMP 

My code:

/*
 * vma_null_test.c - Cindy: to test if vma can be set to NULL in alloc_huge_page() 
 */

 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
 #include <linux/hugetlb.h>
 #include <linux/mm.h>
 #include <linux/list.h>
 #include <asm/page.h>
 #include <linux/nodemask.h>
 #include <linux/gfp.h>
 #include <linux/mm_types.h>
 #include <asm-generic/pgtable.h>
 #include <linux/err.h>
 #include <linux/vmalloc.h>
 #define TWO_MB 0x200000

struct hstate *h;

struct vm_struct *__get_vm_area_node(unsigned long size,
            unsigned long align, unsigned long flags, unsigned long start,
            unsigned long end, int node, gfp_t gfp_mask, void *caller);

struct page *dequeue_huge_page_vma(struct hstate *,struct vm_area_struct *,
            unsigned long, int);

struct page *alloc_buddy_huge_page(struct hstate *,struct vm_area_struct *,
                            unsigned long);

struct page *alloc_huge_page_node_mod(unsigned long vaddr)
{
struct page *page;

page = dequeue_huge_page_vma(h, NULL, vaddr, 0);

if (!page)
    page = alloc_buddy_huge_page(h, NULL, vaddr);

return page;
}

static int __init vma_null_test(void)
{
  struct vm_struct *area;
  h=&default_hstate;
  unsigned long *address;
  struct page *page;
  int ret;

  area=__get_vm_area_node(TWO_MB, 1, VM_ALLOC, VMALLOC_START, VMALLOC_END, -1,   GFP_KERNEL|__GFP_HIGHMEM, __builtin_return_address(0));
  address=(unsigned long *)area->addr;
  page=alloc_huge_page_node_mod(*address);
  if(IS_ERR(page)){
  ret=-PTR_ERR(page);
  printk(KERN_ERR "Cannot allocate page\n");

  }
  else{
  ret=0;
  printk(KERN_ERR "Allocate one huge page at virtual address:%x\n",*address);
  }

  return ret;
}

static void __exit vma_null_exit(void)
{
  printk(KERN_ERR ".............Exit..........\n");
}

module_init(vma_null_test);
module_exit(vma_null_exit);
MODULE_LICENSE("GPL");

Add vendor service to ServiceManager with android treble architecture[SELinux policy]

$
0
0

Note: I am beginner in SELinux policy and followed vndservicemanager by Android

I have a java service(MyService) that starts on the BootComplete receiver. Now i am adding myservice to ServiceManager in onCreate of MyService.java.

ServiceManager.addService(mysystemservice, mybinder);

As per treble architecture, I moved my application to vendor image partition by adding below in Android.mk of application.

LOCAL_VENDOR_MODULE := true

I made below changes in OEM SELinux policy, earlier it was written for system service now as i moved application to vendor so made changes for vendor service, providing both old and current SE policy.

Created Context "my_service"

OLD

In private/service_contexts

mysystemservice u:object_r:my_service:s0

NOW

In vendor/common/vndservice_contexts

mysystemservice u:object_r:my_service:s0

Defined Service Type

OLD

In public/service.te

type my_service, service_manager_type;

NOW

In vendor/common/vndservice.te

type my_service, vndservice_manager_type;

Now giving add permission

OLD

In public/servicemanager.te

allow system_app my_service:service_manager add;

NOW

In abc.te

type abc_exec, exec_type, vendor_file_type, file_type;

init_daemon_domain(abc)

vndbinder_use(abc)

binder_call(abc, system_app)

add_service(abc, my_service)

allow abc  my_service:service_manager  find;
allow abc  my_service:service_manager  add; 

After above changes and giving full build I can see my service context is part of out/product/target/vendor/etc/selinux/vndservice_contexts..inplace of out/product/target/system.

But once Myservice.java try to add "mysystemservice" in ServiceManager by

ServiceManager.addService(mysystemservice, mybinder);

I get below **avc denied ** error

E/SELinux: avc: denied { add } for service=mysystemservice pid=7588 uid=1000 scontext=u:r:system_app:s0 tcontext=u:object_r:default_android_service:s0 tclass=service_manager permissive=0 2019-11-14 12:44:39.613 592-592/? E/ServiceManager: add_service('mysystemservice',b0) uid=1000 - PERMISSION DENIED

As we can see in log above Target context is taking default "tcontext=u:object_r:default_android_service:s0" inplace of "my_service"

Note: If i keep changes for system image everything works fine only issue is when i move SE policy changes to vendor.

Please let me know if i missed something or any other way is to add Service.

Viewing all 12160 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>