Mapping IO memory read-write
I'm writing a device driver for a memory-mapped device on x86-64. I'm mapping the device in the kernel using ioremap_cache(). My file_operations.mmap function is as follows: static int dev_mmap(struct file *filep, struct vm_area_struct *vma) { vma->vm_page_prot.pgprot|=_PAGE_BIT_RW; return vm_iomap_memory(vma,START,LEN); } The user process calls mmap(..,PROT_READ|PROT_WRITE|PROT_EXEC,..). The mapping in /proc/[pid]/maps shows the write bit. However, when looking at the actual page table entry does not have the RW bit set. For example: virtual address = 0000_0001_8000_0000 cr3 = 0000_0000_700a_e000 phys:0000_0000_700a_e000 = 0000_0000_7e05_5067 (P|RW|US|A|D) phys:0000_0000_7e05_5030 = 0000_0001_66e2_9067 (P|RW|US|A|D) phys:0000_0001_66e2_9000 = 0000_0001_69db_3067 (P|RW|US|A|D) phys:0000_0001_69db_3000 = 0000_0000_8020_0225 (P|US|A|SOFTW1) Am I doing something wrong? Jethro
In this case, have you tried reading and writing to the memory segment being mmap'd from userland? Here's an example mmap'ing device driver if you need to see that: https://github.com/claudioscordino/mmap_alloc On Tue, Jan 12, 2016 at 6:10 PM, Jethro Beekman <kernel@jbeekman.nl> wrote:
I'm writing a device driver for a memory-mapped device on x86-64. I'm mapping the device in the kernel using ioremap_cache(). My file_operations.mmap function is as follows:
static int dev_mmap(struct file *filep, struct vm_area_struct *vma) { vma->vm_page_prot.pgprot|=_PAGE_BIT_RW; return vm_iomap_memory(vma,START,LEN); }
The user process calls mmap(..,PROT_READ|PROT_WRITE|PROT_EXEC,..). The mapping in /proc/[pid]/maps shows the write bit. However, when looking at the actual page table entry does not have the RW bit set. For example:
virtual address = 0000_0001_8000_0000 cr3 = 0000_0000_700a_e000 phys:0000_0000_700a_e000 = 0000_0000_7e05_5067 (P|RW|US|A|D) phys:0000_0000_7e05_5030 = 0000_0001_66e2_9067 (P|RW|US|A|D) phys:0000_0001_66e2_9000 = 0000_0001_69db_3067 (P|RW|US|A|D) phys:0000_0001_69db_3000 = 0000_0000_8020_0225 (P|US|A|SOFTW1)
Am I doing something wrong?
Jethro
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
In this case, have you tried reading and writing to the memory segment being mmap'd from userland?
Here's an example mmap'ing device driver if you need to see that: https://github.com/claudioscordino/mmap_alloc
That would not have worked, but your example code did give me an idea. I was using MAP_PRIVATE while I should've been using MAP_SHARED. It works now. Thanks! Jethro On 13-01-16 06:34, Kenneth Adam Miller wrote:
In this case, have you tried reading and writing to the memory segment being mmap'd from userland?
Here's an example mmap'ing device driver if you need to see that: https://github.com/claudioscordino/mmap_alloc
On Tue, Jan 12, 2016 at 6:10 PM, Jethro Beekman <kernel@jbeekman.nl <mailto:kernel@jbeekman.nl>> wrote:
I'm writing a device driver for a memory-mapped device on x86-64. I'm mapping the device in the kernel using ioremap_cache(). My file_operations.mmap function is as follows:
static int dev_mmap(struct file *filep, struct vm_area_struct *vma) { vma->vm_page_prot.pgprot|=_PAGE_BIT_RW; return vm_iomap_memory(vma,START,LEN); }
The user process calls mmap(..,PROT_READ|PROT_WRITE|PROT_EXEC,..). The mapping in /proc/[pid]/maps shows the write bit. However, when looking at the actual page table entry does not have the RW bit set. For example:
virtual address = 0000_0001_8000_0000 cr3 = 0000_0000_700a_e000 phys:0000_0000_700a_e000 = 0000_0000_7e05_5067 (P|RW|US|A|D) phys:0000_0000_7e05_5030 = 0000_0001_66e2_9067 (P|RW|US|A|D) phys:0000_0001_66e2_9000 = 0000_0001_69db_3067 (P|RW|US|A|D) phys:0000_0001_69db_3000 = 0000_0000_8020_0225 (P|US|A|SOFTW1)
Am I doing something wrong?
Jethro
_______________________________________________ Kernelnewbies mailing list Kernelnewbies@kernelnewbies.org <mailto:Kernelnewbies@kernelnewbies.org> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
participants (2)
-
Jethro Beekman -
Kenneth Adam Miller