Skip to content

Instantly share code, notes, and snippets.

@juniorprincewang
Last active April 24, 2020 12:42
Show Gist options
  • Select an option

  • Save juniorprincewang/eabbb879e9b8acde8afb8717de5ac67f to your computer and use it in GitHub Desktop.

Select an option

Save juniorprincewang/eabbb879e9b8acde8afb8717de5ac67f to your computer and use it in GitHub Desktop.
vm_insert_page
int _mmap(struct file *f, struct vm_area_struct *vma) {
unsigned long pages = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT;
unsigned long addr;
struct page *page;
int i,rc=-ENODEV;
// TODO need any semaphore for vma manipulation?
printk(KERN_DEBUG "vma->vm_end %lu vm_start %lu len %lu pages %lu vm_pgoff %lu\n",
vma->vm_end, vma->vm_start, vma->vm_end - vma->vm_start, pages, vma->vm_pgoff);
/* allocate and insert pages to fill the vma. */
for(i=0; i < pages; i++) {
page = alloc_page(GFP_KERNEL); // TODO IO RESERVE?
if (!page) {
// TODO free previous pages
printk(KERN_DEBUG "alloc_page failed\n");
goto done;
}
addr = vma->vm_start+i*PAGE_SIZE;
if (vm_insert_page(vma,addr,page) < 0) {
// TODO free previous pages
printk(KERN_DEBUG "vm_insert_page failed\n");
goto done;
}
printk(KERN_DEBUG "inserted page %d at %p\n",i,(void*)addr);
// TODO __free_page now, should be ok, since vm_insert_page incremented its
// refcount. that way, upon munmap, refcount hits zer0, pages get freed
__free_page(page);
}
printk(KERN_DEBUG "completed inserting %lu pages\n", pages);
rc = 0;
done:
return rc;
}
pos = usbvision->frame[i].data;
while (size > 0) {
if (vm_insert_page(vma, start, vmalloc_to_page(pos))) {
PDEBUG(DBG_MMAP, "mmap: vm_insert_page failed");
return -EAGAIN;
}
start += PAGE_SIZE;
pos += PAGE_SIZE;
size -= PAGE_SIZE;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment