Cyclone V: Cortex A9 dma_alloc_coherent() Internal Error


I am trying to allocate some memory on CycloneV ARM9 in the Linux kernel.

This is the code in the driver

typedef struct tx_dma_buf {
    volatile phys_addr_t phys_addr;
    volatile unsigned int *virt_addr;
    volatile unsigned int *dma_regs;
    dma_addr_t *dma_handle;
    struct device *dev;
} buf_t;

typedef struct bufs
    buf_t *tx_buf;
    buf_t *rx_buf;
    struct cdev cdev;
    struct class *class;
    dev_t dev_node;
} buffers_t;

buf_t *tx_buf;
buf_t *rx_buf;
buffers_t *buf;
static int __init my_init(void)
    int err;

    printk(KERN_INFO, "my_init\n");
    buf = (buffers_t*)kmalloc(sizeof(buffers_t*), GFP_KERNEL);
    tx_buf = (buf_t *) kmalloc(sizeof(buf_t), GFP_KERNEL);
    tx_buf->dev = (struct device*)kmalloc(sizeof(struct device), GFP_KERNEL);
    tx_buf->virt_addr = dma_alloc_coherent(tx_buf->dev, BUFFER_SIZE, tx_buf->dma_handle, GFP_KERNEL);

    rx_buf = (buf_t *) kmalloc(sizeof(buf_t), GFP_KERNEL);
    rx_buf->dev = (struct device*)kmalloc(sizeof(struct device), GFP_KERNEL);
    rx_buf->phys_addr = dma_alloc_coherent(rx_buf->dev, BUFFER_SIZE, rx_buf->dma_handle, GFP_KERNEL);

    buf->tx_buf = tx_buf;
    buf->rx_buf = rx_buf;

Then in the dmesg upon loading the module

[  138.309547] buff_alloc: loading out-of-tree module taints kernel.
[  138.316499] ------------[ cut here ]------------
[  138.321165] WARNING: CPU: 0 PID: 344 at kernel/dma/mapping.c:303 dma_alloc_attrs+0x114/0x124
[  138.329624] Modules linked in: buff_alloc(O+)
[  138.333979] CPU: 0 PID: 344 Comm: insmod Tainted: G           O      5.4.44-05622-gcda983e75c17 #3
[  138.342896] Hardware name: Altera SOCFPGA
[  138.346889] Backtrace:
[  138.349340] [<c010d5a0>] (dump_backtrace) from [<c010d8b8>] (show_stack+0x20/0x24)

[  138.539173] 8<--- cut here ---
[  138.542223] Unable to handle kernel paging request at virtual address 6e69622f
[  138.549442] pgd = 954810e3
[  138.552142] [6e69622f] *pgd=00000000
[  138.555731] Internal error: Oops: 5 [#1] SMP ARM
[  138.560335] Modules linked in: buff_alloc(O+)
[  138.564683] CPU: 0 PID: 344 Comm: insmod Tainted: G        W  O      5.4.44-05622-gcda983e75c17 #3
[  138.573598] Hardware name: Altera SOCFPGA
[  138.577598] PC is at string_nocheck+0x28/0x90
[  138.581938] LR is at 0xffffffff
[  138.585065] pc : [<c08ad3d4>]    lr : [<ffffffff>]    psr: a00f0013

I think everything in the driver is allocated such that dma_alloc_coherent isn't receiving NULLs that it should not be. I was able to get kmalloc to work, but when using kmalloc, I think I am having cache consistency issues between the OS and firmware that is interacting with the SDRAM. If there is an obvious problem with the code, I don't see it, but if it is a deeper issue with the call to the OS (something in the kernel), I will need help diagnosing the problem.


I tried putting the same call in a probe function and using the platform_device dev. I looked at a Xilinx driver example, and it seemed that was how it was done.

It seems to fail the same way. Here is my new snippet

static int dmabuffer_probe(struct platform_device *pdev)

    printk(KERN_INFO "dmabuffer module initialized\n");

        buf = (buf_t*)kmalloc(sizeof(buf_t*), GFP_KERNEL);
        buf->dev = &pdev->dev;
        buf->virt_addr = dma_alloc_coherent(buf->dev, BUFFER_SIZE, buf->dma_handle, GFP_KERNEL);

    return 0;
asked on Stack Overflow Feb 11, 2021 by Jack Frye • edited Feb 13, 2021 by Jack Frye

0 Answers

Nobody has answered this question yet.

User contributions licensed under CC BY-SA 3.0