PCI driver 'Oops: Kernel access of bad area' error

1

I wanted to write a simple PCI express driver for Xilinx FPGA. But I am not able to request memory region for PCI.

Question is: How to claim that I/O memory area for custom driver. I want to write 3. byte of that area using driver.

Below are the details. What am I missing ? Thanks

1-) I am getting this error:

[    4.345350] Unable to handle kernel paging request for data at address 0x00000005
[    4.353978] Faulting instruction address: 0x80000000002c9370
[    4.358337] Oops: Kernel access of bad area, sig: 11 [#1]
[    4.362426] BE SMP NR_CPUS=24 CoreNet Generic
[    4.365477] Modules linked in: fpgapcie(O+) ucc_uart
[    4.369139] CPU: 0 PID: 1999 Comm: udevd Tainted: G           O      4.19.26+gc0c2141 #1
[    4.375924] NIP:  80000000002c9370 LR: 80000000002c9350 CTR: c00000000053acfc
[    4.381753] REGS: c0000001ee2bb1c0 TRAP: 0300   Tainted: G           O       (4.19.26+gc0c2141)
[    4.389146] MSR:  000000008002b000 <CE,EE,FP,ME>  CR: 22228242  XER: 20000000
[    4.394982] DEAR: 0000000000000005 ESR: 0000000000800000 IRQMASK: 0 
               GPR00: 80000000002c9350 c0000001ee2bb440 80000000002d1f00 000000000000001a 
               GPR04: 0000000000000001 000000000000022d c000000000f30548 c000000001013000 
               GPR08: 00000001fec37000 0000000000000003 0000000000000000 0000000000000020 
               GPR12: 0000000028228444 c000000001013000 0000000000020000 000000013c323ac8 
               GPR16: 000000013c323ae0 80000000002cc000 c000000000a194b0 c0000001f0eaa1c0 
               GPR20: 00000000006000c0 c000000000ed9da0 0000000000000000 0000000000000100 
               GPR24: 000000000000001c 000000000f700000 c0000001f3034880 0000000000000000 
               GPR28: c0000001f337b800 00000000000000f7 c0000001f337b8a0 0000000000000000 

2-) Code piece in PCI probe function:

    static int pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
    {
    int ret, minor;
    struct cdev *cdev;
    dev_t devno;
    unsigned long pci_io_addr = 0;
    /* add this pci device in pci_cdev */
    if ((minor = pci_cdev_add(pci_cdev, MAX_DEVICE, dev)) < 0)
        goto error;

    /* compute major/minor number */
    devno = MKDEV(major, minor);

    /* allocate struct cdev */
    cdev = cdev_alloc();

    /* initialise struct cde
    cdev_init(cdev, &pci_ops);
    cdev->owner = THIS_MODULE;

    /* register cdev */
    ret = cdev_add(cdev, devno, 1);
    if (ret < 0) {
        dev_err(&(dev->dev), "Can't register character device\n");
        goto error;
    }
    pci_cdev[minor].cdev = cdev;

    dev_info(&(dev->dev), "%s The major device number is %d (%d).\n",
           "Registeration is a success", MAJOR(devno), MINOR(devno));
    dev_info(&(dev->dev), "If you want to talk to the device driver,\n");
    dev_info(&(dev->dev), "you'll have to create a device file. \n");
    dev_info(&(dev->dev), "We suggest you use:\n");
    dev_info(&(dev->dev), "mknod %s c %d %d\n", DEVICE_NAME, MAJOR(devno), MINOR(devno));
    dev_info(&(dev->dev), "The device file name is important, because\n");
    dev_info(&(dev->dev), "the ioctl program assumes that's the\n");
    dev_info(&(dev->dev), "file you'll use.\n");

    /* enable the device */
    pci_enable_device(dev);

    /* 'alloc' IO to talk with the card */
    if (pci_request_region(dev, BAR_IO, "IO-pci") == 0) {
        printk(KERN_ALERT "The memory you requested from fpgapcie is already reserved by CORE pci driver.");
    }

     check that BAR_IO is *really* IO region 
    if ((pci_resource_flags(dev, BAR_IO) & IORESOURCE_IO) != IORESOURCE_IO) {
        dev_err(&(dev->dev), "BAR2 isn't an IO region\n");
        cdev_del(cdev);
        goto error;
    }


    pci_io_addr = pci_resource_start(dev,BAR_IO);
        printk(KERN_INFO "PCI start adress: %02X", &pci_io_addr);
    outb(pci_io_addr+3, 5);
        printk(KERN_INFO "Message from PCI device to user: 5");
    return 1;

error:
        printk(KERN_INFO "An error occuder while probing pci");
    return 0;
}

3-) lspci -v output:

0001:01:00.0 Memory controller: Xilinx Corporation Device 7021
        Subsystem: Xilinx Corporation Device 0007
        Flags: bus master, fast devsel, latency 0, IRQ 41
        Memory at c10000000 (32-bit, non-prefetchable) [size=2K]
        Capabilities: [40] Power Management version 3
        Capabilities: [48] MSI: Enable- Count=1/1 Maskable- 64bit+
        Capabilities: [60] Express Endpoint, MSI 00
        Capabilities: [100] Device Serial Number 00-00-00-01-01-00-0a-35
        Kernel driver in use: yusufpci
        Kernel modules: fpgapcie

4-) full dmesg:

[    4.285663] Module pci init
[    4.294787] yusufpci 0001:01:00.0: Registeration is a success The major device number is 247 (0).
[    4.302367] yusufpci 0001:01:00.0: If you want to talk to the device driver,
[    4.308116] yusufpci 0001:01:00.0: you'll have to create a device file. 
[    4.313516] yusufpci 0001:01:00.0: We suggest you use:
[    4.317354] yusufpci 0001:01:00.0: mknod virtual_pci c 247 0
[    4.321713] yusufpci 0001:01:00.0: The device file name is important, because
[    4.327553] yusufpci 0001:01:00.0: the ioctl program assumes that's the
[    4.332866] yusufpci 0001:01:00.0: file you'll use.
[    4.336459] The memory you requested from fpgapcie is already reserved by CORE pci driver. This is not an error.
[    4.336463] PCI start adress: EE2BB4B0
[    4.345350] Unable to handle kernel paging request for data at address 0x00000005
[    4.353978] Faulting instruction address: 0x80000000002c9370
[    4.358337] Oops: Kernel access of bad area, sig: 11 [#1]
[    4.362426] BE SMP NR_CPUS=24 CoreNet Generic
[    4.365477] Modules linked in: fpgapcie(O+) ucc_uart
[    4.369139] CPU: 0 PID: 1999 Comm: udevd Tainted: G           O      4.19.26+gc0c2141 #1
[    4.375924] NIP:  80000000002c9370 LR: 80000000002c9350 CTR: c00000000053acfc
[    4.381753] REGS: c0000001ee2bb1c0 TRAP: 0300   Tainted: G           O       (4.19.26+gc0c2141)
[    4.389146] MSR:  000000008002b000 <CE,EE,FP,ME>  CR: 22228242  XER: 20000000
[    4.394982] DEAR: 0000000000000005 ESR: 0000000000800000 IRQMASK: 0 
               GPR00: 80000000002c9350 c0000001ee2bb440 80000000002d1f00 000000000000001a 
               GPR04: 0000000000000001 000000000000022d c000000000f30548 c000000001013000 
               GPR08: 00000001fec37000 0000000000000003 0000000000000000 0000000000000020 
               GPR12: 0000000028228444 c000000001013000 0000000000020000 000000013c323ac8 
               GPR16: 000000013c323ae0 80000000002cc000 c000000000a194b0 c0000001f0eaa1c0 
               GPR20: 00000000006000c0 c000000000ed9da0 0000000000000000 0000000000000100 
               GPR24: 000000000000001c 000000000f700000 c0000001f3034880 0000000000000000 
               GPR28: c0000001f337b800 00000000000000f7 c0000001f337b8a0 0000000000000000 
[    4.453632] NIP [80000000002c9370] .pci_probe+0x220/0x2b4 [fpgapcie]
[    4.458680] LR [80000000002c9350] .pci_probe+0x200/0x2b4 [fpgapcie]
[    4.463639] Call Trace:
[    4.464775] [c0000001ee2bb440] [80000000002c9350] .pci_probe+0x200/0x2b4 [fpgapcie] (unreliable)
[    4.472262] [c0000001ee2bb500] [c0000000004b77c8] .pci_device_probe+0x11c/0x1f4
[    4.478270] [c0000001ee2bb5a0] [c000000000561ebc] .really_probe+0x26c/0x38c
[    4.483927] [c0000001ee2bb640] [c0000000005621ac] .driver_probe_device+0x78/0x154
[    4.490106] [c0000001ee2bb6d0] [c0000000005623d8] .__driver_attach+0x150/0x154
[    4.496025] [c0000001ee2bb760] [c00000000055f424] .bus_for_each_dev+0x94/0xdc
[    4.501856] [c0000001ee2bb800] [c0000000005615fc] .driver_attach+0x24/0x38
[    4.507426] [c0000001ee2bb870] [c000000000560ec8] .bus_add_driver+0x264/0x2a4
[    4.513258] [c0000001ee2bb910] [c000000000563384] .driver_register+0x88/0x178
[    4.519089] [c0000001ee2bb990] [c0000000004b5a68] .__pci_register_driver+0x50/0x64
[    4.525355] [c0000001ee2bba00] [80000000002c9564] .pci_init_module+0xc0/0x444 [fpgapcie]
[    4.532144] [c0000001ee2bba80] [c0000000000020b4] .do_one_initcall+0x64/0x224
[    4.537978] [c0000001ee2bbb50] [c0000000000f443c] .do_init_module+0x70/0x260
[    4.543722] [c0000001ee2bbbf0] [c0000000000f6564] .load_module+0x1e6c/0x2400
[    4.549467] [c0000001ee2bbd10] [c0000000000f6d28] .__se_sys_finit_module+0xcc/0x100
[    4.555819] [c0000001ee2bbe30] [c0000000000006b0] system_call+0x60/0x6c
[    4.561127] Instruction dump:
[    4.562785] e86a8080 38810070 f9210070 4800041d e8410028 e9210070 3d420000 e94a8088 
[    4.569231] 39290003 5529063e e94a0000 7c0004ac <992a0005> 39200001 3d420000 992d0684 
[    4.575854] ---[ end trace 2d15cff7ba1b3255 ]---
linux
linux-kernel
linux-device-driver
embedded-linux
device-driver
asked on Stack Overflow Jan 10, 2020 by Yusuf Altıparmak • edited Jan 11, 2020 by Yusuf Altıparmak

1 Answer

0

Problem solved. But when I write the third byte of Memory Mapped area, FPGA programmed to answer with lighting its GPIO leds. I tried to write first 15 byte of MMIO but it did not work. The leds did not lighted. But the code stopped giving errors.

I also cannot read the bytes on MMIO space using readb() function. It's giving

unrecoverable machine check error

Problem solved using this code.

pci_request_regions(dev, "fpgapcie");

    pci_io_startaddr = pci_resource_start(dev,BAR_IO);
    pci_io_endaddr = pci_resource_end(dev,BAR_IO);
    pci_io_size = pci_resource_len(dev,BAR_IO);
    printk(KERN_INFO "Region start: %lX, Region end: %lX, Size: % lX",pci_io_startaddr,pci_io_endaddr,pci_io_size);  
    pci_io_addr = ioremap(pci_io_startaddr, pci_io_endaddr);
    printk(KERN_INFO "PCI start adress: %lX", pci_io_addr);
    for(i = 0;i<15;i++) /* Write first 15 byte */
    {
        writeb(2, pci_io_addr+i);
        printk(KERN_INFO "%lX, Message from PCI device to user: 2", pci_io_addr+i);
    }

and the dmesg output:

fpgapcie: loading out-of-tree module taints kernel.
fpgapcie 0001:01:00.0: Registeration is a success The major device number is 247 (0).
fpgapcie 0001:01:00.0: If you want to talk to the device driver,
fsl-fman-port ffe488000.port fm1-gb0: renamed from eth0
fpgapcie 0001:01:00.0: you'll have to create a device file.
fpgapcie 0001:01:00.0: We suggest you use:
fpgapcie 0001:01:00.0: mknod virtual_pci c 247 0
fpgapcie 0001:01:00.0: The device file name is important, because
fpgapcie 0001:01:00.0: the ioctl program assumes that's the
fpgapcie 0001:01:00.0: file you'll use.
Region start: 210000000, Region end: 2100007FF, Size: 800
PCI start adress: 8000080088900000
8000080088900000, Message from PCI device to user: 2
8000080088900001, Message from PCI device to user: 2
8000080088900002, Message from PCI device to user: 2
8000080088900003, Message from PCI device to user: 2
8000080088900004, Message from PCI device to user: 2
8000080088900005, Message from PCI device to user: 2
8000080088900006, Message from PCI device to user: 2
8000080088900007, Message from PCI device to user: 2
8000080088900008, Message from PCI device to user: 2
8000080088900009, Message from PCI device to user: 2
800008008890000A, Message from PCI device to user: 2
800008008890000B, Message from PCI device to user: 2
800008008890000C, Message from PCI device to user: 2
800008008890000D, Message from PCI device to user: 2
800008008890000E, Message from PCI device to user: 2
answered on Stack Overflow Jan 13, 2020 by Yusuf Altıparmak

User contributions licensed under CC BY-SA 3.0