Issue
I am trying to implement a PCI device driver for a virtual PCI device on QEMU. The device defines a BAR region as RAM, and the driver can do ioremap() this region and access it without any issues. The next step is to assign this region (or a fraction of it) to a user application. To do this, I have also implemented an .mmap function as part of my driver file operations. This mmap is simply using remap_pfn_range, but it also passes the pfn of the memory pointer returned by the ioremap() earlier.
However, upon running the user space application, the mmap is successful, but when the app tries to access the memory, it gets killed and I get the following dmesg errors.
" a.out: Corrupted page table at address 7f66248b8000
..Some page table info..
Bad pagetable: 000f [#2] SMP NOPTI
..and the core dump.. " Does anyone know what have I done wrong? Did I missed a step? Or it could be an error specific to QEMU? I am running x86_softmmu as my QEMU configuration and my kernel is the 4.14
Solution
I've solved this issue and managed to map PCI memory to user space via the driver. As @IanAbbott implied, I've changed the pfn
input of the remap_pfn_range()
function I was using in my custom ->mmap()
.
The original was:
io_remap_pfn_range(vma, vma->vm_start, pfn, vma->vm_end - vma->vm_start, vma->vm_page_prot));
where the pfn
was the result of the buffer pointer return from the ioremap()
. I changed the pfn
to:
pfn = pci_resource_start(pdev, BAR) >> PAGE_SHIFT;
That basically points to the actual starting address pointed by the BAR. My working remap_pfn_range()
function is now:
io_remap_pfn_range(vma, vma->vm_start, pci_resource_start(pdev, BAR) >> PAGE_SHIFT, vma->vm_end - vma->vm_start,vma->vm_page_prot);
I confirmed that it works by doing some dummy writes to the buffer pointer in my driver, then picking up the reads and doing some writes in my user space application.
Answered By - Κυριάκος Παρασκευάς
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.