Implementing fault handler

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



I'm trying to implement a fault handler to map memory allocated with __get_free_pages() to userspace. In module init, I'm allocating 64k by calling __get_free_pages(GFP_KERNEL, get_order(size)), where size = 64 << 10.

I've also added an ioctl so that userspace can obtain the size and virtual address of allocated block, to for example mmap() a smaller portion of the allocated memory, like so:

void *p = mmap(0, size / 2, PROT_READ | PROT_WRITE, MAP_SHARED, fd, addr + size / 2);

Mmap is implemented as follows:

int my_mmap(struct file *filp, struct vm_area_struct *vma)
{
vma->vm_ops = &my_vm_ops;
return 0;
}

and the fault handler like this:

int my_vma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
{
vmf->page = virt_to_page(vmf->pgoff << PAGE_SHIFT);
get_page(vmf->page);
return 0;
}

This seems to work, mmap returns virtual address and memory can be read & written without problems.

However, when I unload the module, there's an error due to bad page state when calling free_pages() to free the memory:

BUG: Bad page state in process rmmod  pfn:01648
page:c102c900 flags:40040000 count:0 mapcount:0 mapping:(null) index:0 (Not tainted)
Pid: 2412, comm: rmmod Not tainted 2.6.29.3-140.fc11.i586 #1
Call Trace:
 [<c047c727>] bad_page+0xdf/0xf4
 [<c047cdef>] free_pages_check+0xac/0xc9
 [<c047ce3e>] __free_pages_ok+0x32/0x13b
 [<c047d352>] __free_pages+0x23/0x25
 [<c047d376>] free_pages+0x22/0x24
 [<d081a124>] my_exit+0x78/0x7a [my_mod]
 [<c044fc90>] sys_delete_module+0x17b/0x1cd
 [<c046587f>] ? audit_syscall_entry+0x163/0x185
 [<c0403f72>] syscall_call+0x7/0xb

So what's special about doing allocation by __get_free_pages()? If I use vmalloc() & vfree() and call vmalloc_to_page() in fault handler instead of virt_to_page(), it works just fine.

[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux