0

I reserved a block of memory for my driver in dts:

<pre>

    reserved-memory {
        #size-cells = <2>;
        #address-cells = <2>;
        ranges;

        adc_reserved: ADC {
            compatible = "shared-dma-pool";
            reg = <0x5 0x0 0x0 0x100000>;
            /* memory at pysical adress 0x500000000 actually exists and */
            /* I need exactly this region */
        };
    };
    ...
    my_device {
        ...
        memory-region = &lt&adc_reserved>;
    };

</pre>

Then in my driver I did the following:

/* Allocate memory */
dma_set_coherent_mask(dev, DMA_BIT_MASK(64));
dma_vaddr = dma_alloc_coherent(dev, dma_size, &dma_paddr, GFP_KERNEL);
dev_info(dev, "Allocated coherent memory, vaddr: 0x%0llX, paddr: 0x%0llX\n",        (uint64_t)dma_vaddr, (uint64_t)dma_paddr);

In log I see this:

Allocated coherent memory, vaddr: 0xFFFFFF800CB00000, paddr: 0x500000000

Everething seems ok. Then I get page struct:

struct page* p = vmalloc_to_page(dma_vaddr);

and then segfault when I access any member of p:

Unable to handle kernel paging request at virtual address ffffffbf11800000

  • Why I get segfault?
  • How can I get valid pointer to page in my case?
סטנלי גרונן
  • 2,917
  • 23
  • 46
  • 68
  • Did you check if the value of p is NULL? – stark Apr 24 '20 at 21:43
  • p is ffffffbf11800000 – snip777 Apr 24 '20 at 21:51
  • Means that would be the address in the page table for that page, but no page table entry has been created. – stark Apr 24 '20 at 21:56
  • My guess is you need to populate using something like https://elixir.bootlin.com/linux/v4.5/source/mm/sparse-vmemmap.c#L211 but I don't know the memory mgmt stuff very well. Normally the kernel gets the memory map handed off from the boot firmware. – stark Apr 24 '20 at 22:06

0 Answers0