Changeset View
Changeset View
Standalone View
Standalone View
sys/compat/linuxkpi/common/src/linux_page.c
Show First 20 Lines • Show All 190 Lines • ▼ Show 20 Lines | |||||
static int | static int | ||||
linux_get_user_pages_internal(vm_map_t map, unsigned long start, int nr_pages, | linux_get_user_pages_internal(vm_map_t map, unsigned long start, int nr_pages, | ||||
int write, struct page **pages) | int write, struct page **pages) | ||||
{ | { | ||||
vm_prot_t prot; | vm_prot_t prot; | ||||
size_t len; | size_t len; | ||||
int count; | int count; | ||||
int i; | |||||
prot = write ? (VM_PROT_READ | VM_PROT_WRITE) : VM_PROT_READ; | prot = write ? (VM_PROT_READ | VM_PROT_WRITE) : VM_PROT_READ; | ||||
len = ((size_t)nr_pages) << PAGE_SHIFT; | len = ((size_t)nr_pages) << PAGE_SHIFT; | ||||
count = vm_fault_quick_hold_pages(map, start, len, prot, pages, nr_pages); | count = vm_fault_quick_hold_pages(map, start, len, prot, pages, nr_pages); | ||||
if (count == -1) | return (count == -1 ? -EFAULT : nr_pages); | ||||
return (-EFAULT); | |||||
for (i = 0; i != nr_pages; i++) { | |||||
struct page *pg = pages[i]; | |||||
vm_page_lock(pg); | |||||
vm_page_wire(pg); | |||||
vm_page_unhold(pg); | |||||
vm_page_unlock(pg); | |||||
} | } | ||||
return (nr_pages); | |||||
} | |||||
int | int | ||||
__get_user_pages_fast(unsigned long start, int nr_pages, int write, | __get_user_pages_fast(unsigned long start, int nr_pages, int write, | ||||
struct page **pages) | struct page **pages) | ||||
{ | { | ||||
vm_map_t map; | vm_map_t map; | ||||
vm_page_t *mp; | vm_page_t *mp; | ||||
vm_offset_t va; | vm_offset_t va; | ||||
Show All 11 Lines | __get_user_pages_fast(unsigned long start, int nr_pages, int write, | ||||
if (start < vm_map_min(map) || end > vm_map_max(map)) | if (start < vm_map_min(map) || end > vm_map_max(map)) | ||||
return (-EINVAL); | return (-EINVAL); | ||||
prot = write ? (VM_PROT_READ | VM_PROT_WRITE) : VM_PROT_READ; | prot = write ? (VM_PROT_READ | VM_PROT_WRITE) : VM_PROT_READ; | ||||
for (count = 0, mp = pages, va = start; va < end; | for (count = 0, mp = pages, va = start; va < end; | ||||
mp++, va += PAGE_SIZE, count++) { | mp++, va += PAGE_SIZE, count++) { | ||||
*mp = pmap_extract_and_hold(map->pmap, va, prot); | *mp = pmap_extract_and_hold(map->pmap, va, prot); | ||||
if (*mp == NULL) | if (*mp == NULL) | ||||
break; | break; | ||||
vm_page_lock(*mp); | |||||
vm_page_wire(*mp); | |||||
vm_page_unhold(*mp); | |||||
vm_page_unlock(*mp); | |||||
if ((prot & VM_PROT_WRITE) != 0 && | if ((prot & VM_PROT_WRITE) != 0 && | ||||
(*mp)->dirty != VM_PAGE_BITS_ALL) { | (*mp)->dirty != VM_PAGE_BITS_ALL) { | ||||
/* | /* | ||||
* Explicitly dirty the physical page. Otherwise, the | * Explicitly dirty the physical page. Otherwise, the | ||||
* caller's changes may go unnoticed because they are | * caller's changes may go unnoticed because they are | ||||
* performed through an unmanaged mapping or by a DMA | * performed through an unmanaged mapping or by a DMA | ||||
* operation. | * operation. | ||||
▲ Show 20 Lines • Show All 139 Lines • Show Last 20 Lines |