support large pages
This commit is contained in:
126
kernel/process.c
126
kernel/process.c
@@ -522,7 +522,9 @@ static int copy_user_pte(void *arg0, page_table_t src_pt, pte_t *src_ptep, void
|
||||
attr = arch_vrflag_to_ptattr(args->new_vrflag, PF_POPULATE, NULL);
|
||||
}
|
||||
|
||||
error = ihk_mc_pt_set_range(args->new_vm->address_space->page_table, args->new_vm, pgaddr, pgaddr+pgsize, phys, attr);
|
||||
error = ihk_mc_pt_set_range(args->new_vm->address_space->page_table,
|
||||
args->new_vm, pgaddr, pgaddr+pgsize, phys, attr,
|
||||
pgshift);
|
||||
if (error) {
|
||||
args->fault_addr = (intptr_t)pgaddr;
|
||||
goto out;
|
||||
@@ -572,6 +574,7 @@ static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm)
|
||||
range->flag = src_range->flag;
|
||||
range->memobj = src_range->memobj;
|
||||
range->objoff = src_range->objoff;
|
||||
range->pgshift = src_range->pgshift;
|
||||
if (range->memobj) {
|
||||
memobj_ref(range->memobj);
|
||||
}
|
||||
@@ -583,7 +586,8 @@ static int copy_user_ranges(struct process_vm *vm, struct process_vm *orgvm)
|
||||
|
||||
error = visit_pte_range(orgvm->address_space->page_table,
|
||||
(void *)range->start, (void *)range->end,
|
||||
VPTEF_SKIP_NULL, ©_user_pte, &args);
|
||||
range->pgshift, VPTEF_SKIP_NULL,
|
||||
©_user_pte, &args);
|
||||
if (error) {
|
||||
if (args.fault_addr != -1) {
|
||||
kprintf("ERROR: copy_user_ranges() "
|
||||
@@ -626,7 +630,8 @@ int update_process_page_table(struct process_vm *vm,
|
||||
attr = arch_vrflag_to_ptattr(range->flag, PF_POPULATE, NULL);
|
||||
flags = ihk_mc_spinlock_lock(&vm->page_table_lock);
|
||||
error = ihk_mc_pt_set_range(vm->address_space->page_table, vm,
|
||||
(void *)range->start, (void *)range->end, phys, attr);
|
||||
(void *)range->start, (void *)range->end, phys, attr,
|
||||
range->pgshift);
|
||||
if (error) {
|
||||
kprintf("update_process_page_table:ihk_mc_pt_set_range failed. %d\n", error);
|
||||
goto out;
|
||||
@@ -647,6 +652,13 @@ int split_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
dkprintf("split_process_memory_range(%p,%lx-%lx,%lx,%p)\n",
|
||||
vm, range->start, range->end, addr, splitp);
|
||||
|
||||
error = ihk_mc_pt_split(vm->address_space->page_table, vm, (void *)addr);
|
||||
if (error) {
|
||||
ekprintf("split_process_memory_range:"
|
||||
"ihk_mc_pt_split failed. %d\n", error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
newrange = kmalloc(sizeof(struct vm_range), IHK_MC_AP_NOWAIT);
|
||||
if (!newrange) {
|
||||
ekprintf("split_process_memory_range(%p,%lx-%lx,%lx,%p):"
|
||||
@@ -659,6 +671,7 @@ int split_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
newrange->start = addr;
|
||||
newrange->end = range->end;
|
||||
newrange->flag = range->flag;
|
||||
newrange->pgshift = range->pgshift;
|
||||
|
||||
if (range->memobj) {
|
||||
memobj_ref(range->memobj);
|
||||
@@ -735,11 +748,10 @@ int free_process_memory_range(struct process_vm *vm, struct vm_range *range)
|
||||
int error;
|
||||
intptr_t start;
|
||||
intptr_t end;
|
||||
#ifdef USE_LARGE_PAGES
|
||||
struct vm_range *neighbor;
|
||||
intptr_t lpstart;
|
||||
intptr_t lpend;
|
||||
#endif /* USE_LARGE_PAGES */
|
||||
size_t pgsize;
|
||||
|
||||
dkprintf("free_process_memory_range(%p, 0x%lx - 0x%lx)\n",
|
||||
vm, range->start, range->end);
|
||||
@@ -747,25 +759,40 @@ int free_process_memory_range(struct process_vm *vm, struct vm_range *range)
|
||||
start = range->start;
|
||||
end = range->end;
|
||||
if (!(range->flag & (VR_REMOTE | VR_IO_NOCACHE | VR_RESERVED))) {
|
||||
#ifdef USE_LARGE_PAGES
|
||||
lpstart = start & LARGE_PAGE_MASK;
|
||||
lpend = (end + LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK;
|
||||
|
||||
|
||||
if (lpstart < start) {
|
||||
neighbor = previous_process_memory_range(vm, range);
|
||||
if ((neighbor == NULL) || (neighbor->end <= lpstart)) {
|
||||
neighbor = previous_process_memory_range(vm, range);
|
||||
pgsize = -1;
|
||||
for (;;) {
|
||||
error = arch_get_smaller_page_size(
|
||||
NULL, pgsize, &pgsize, NULL);
|
||||
if (error) {
|
||||
kprintf("free_process_memory_range:"
|
||||
"arch_get_smaller_page_size failed."
|
||||
" %d\n", error);
|
||||
break;
|
||||
}
|
||||
lpstart = start & ~(pgsize - 1);
|
||||
if (!neighbor || (neighbor->end <= lpstart)) {
|
||||
start = lpstart;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (end < lpend) {
|
||||
neighbor = next_process_memory_range(vm, range);
|
||||
if ((neighbor == NULL) || (lpend <= neighbor->start)) {
|
||||
neighbor = next_process_memory_range(vm, range);
|
||||
pgsize = -1;
|
||||
for (;;) {
|
||||
error = arch_get_smaller_page_size(
|
||||
NULL, pgsize, &pgsize, NULL);
|
||||
if (error) {
|
||||
kprintf("free_process_memory_range:"
|
||||
"arch_get_smaller_page_size failed."
|
||||
" %d\n", error);
|
||||
break;
|
||||
}
|
||||
lpend = (end + pgsize - 1) & ~(pgsize - 1);
|
||||
if (!neighbor || (lpend <= neighbor->start)) {
|
||||
end = lpend;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* USE_LARGE_PAGES */
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
if (range->memobj) {
|
||||
@@ -928,6 +955,7 @@ enum ihk_mc_pt_attribute common_vrflag_to_ptattr(unsigned long flag, uint64_t fa
|
||||
return attr;
|
||||
}
|
||||
|
||||
/* XXX: インデントを揃える必要がある */
|
||||
int add_process_memory_range(struct process_vm *vm,
|
||||
unsigned long start, unsigned long end,
|
||||
unsigned long phys, unsigned long flag,
|
||||
@@ -1236,7 +1264,8 @@ int remap_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
args.memobj = range->memobj;
|
||||
|
||||
error = visit_pte_range(vm->address_space->page_table, (void *)start,
|
||||
(void *)end, VPTEF_DEFAULT, &remap_one_page, &args);
|
||||
(void *)end, range->pgshift, VPTEF_DEFAULT,
|
||||
&remap_one_page, &args);
|
||||
if (error) {
|
||||
ekprintf("remap_process_memory_range(%p,%p,%#lx,%#lx,%#lx):"
|
||||
"visit pte failed %d\n",
|
||||
@@ -1306,8 +1335,8 @@ int sync_process_memory_range(struct process_vm *vm, struct vm_range *range,
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
memobj_lock(range->memobj);
|
||||
error = visit_pte_range(vm->address_space->page_table, (void *)start,
|
||||
(void *)end, VPTEF_SKIP_NULL, &sync_one_page,
|
||||
&args);
|
||||
(void *)end, range->pgshift, VPTEF_SKIP_NULL,
|
||||
&sync_one_page, &args);
|
||||
memobj_unlock(range->memobj);
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||
if (error) {
|
||||
@@ -1389,7 +1418,7 @@ int invalidate_process_memory_range(struct process_vm *vm,
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
memobj_lock(range->memobj);
|
||||
error = visit_pte_range(vm->address_space->page_table, (void *)start,
|
||||
(void *)end, VPTEF_SKIP_NULL,
|
||||
(void *)end, range->pgshift, VPTEF_SKIP_NULL,
|
||||
&invalidate_one_page, &args);
|
||||
memobj_unlock(range->memobj);
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||
@@ -1421,8 +1450,8 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
/*****/
|
||||
ptep = ihk_mc_pt_lookup_pte(vm->address_space->page_table,
|
||||
(void *)fault_addr, &pgaddr, &pgsize,
|
||||
&p2align);
|
||||
(void *)fault_addr, range->pgshift, &pgaddr, &pgsize,
|
||||
&p2align);
|
||||
if (!(reason & (PF_PROT | PF_PATCH)) && ptep && !pte_is_null(ptep)
|
||||
&& !pte_is_fileoff(ptep, pgsize)) {
|
||||
if (!pte_is_present(ptep)) {
|
||||
@@ -1439,13 +1468,19 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
||||
goto out;
|
||||
}
|
||||
/*****/
|
||||
if (!ptep || (pgsize != PAGE_SIZE)) {
|
||||
while (((uintptr_t)pgaddr < range->start)
|
||||
|| (range->end < ((uintptr_t)pgaddr + pgsize))) {
|
||||
ptep = NULL;
|
||||
pgsize = PAGE_SIZE;
|
||||
p2align = PAGE_P2ALIGN;
|
||||
error = arch_get_smaller_page_size(NULL, pgsize, &pgsize, &p2align);
|
||||
if (error) {
|
||||
kprintf("page_fault_process_memory_range(%p,%lx-%lx %lx,%lx,%lx):arch_get_smaller_page_size(pte) failed. %d\n", vm, range->start, range->end, range->flag, fault_addr, reason, error);
|
||||
goto out;
|
||||
}
|
||||
pgaddr = (void *)(fault_addr & ~(pgsize - 1));
|
||||
}
|
||||
pgaddr = (void *)(fault_addr & ~(pgsize - 1));
|
||||
/*****/
|
||||
if (!ptep || pte_is_null(ptep) || pte_is_fileoff(ptep, pgsize)) {
|
||||
phys = NOPHYS;
|
||||
if (range->memobj) {
|
||||
off_t off;
|
||||
|
||||
@@ -1458,17 +1493,34 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
||||
error = memobj_get_page(range->memobj, off, p2align,
|
||||
&phys, &memobj_flag);
|
||||
if (error) {
|
||||
if (error != -ERESTART) {
|
||||
struct memobj *obj;
|
||||
|
||||
if (zeroobj_create(&obj)) {
|
||||
panic("PFPMR: zeroobj_crate");
|
||||
}
|
||||
|
||||
if (range->memobj != obj) {
|
||||
goto out;
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (phys == NOPHYS) {
|
||||
void *virt;
|
||||
size_t npages;
|
||||
|
||||
retry:
|
||||
npages = pgsize / PAGE_SIZE;
|
||||
virt = ihk_mc_alloc_aligned_pages(npages, p2align, IHK_MC_AP_NOWAIT);
|
||||
if (!virt && !range->pgshift && (pgsize != PAGE_SIZE)) {
|
||||
error = arch_get_smaller_page_size(NULL, pgsize, &pgsize, &p2align);
|
||||
if (error) {
|
||||
kprintf("page_fault_process_memory_range(%p,%lx-%lx %lx,%lx,%lx):arch_get_smaller_page_size(anon) failed. %d\n", vm, range->start, range->end, range->flag, fault_addr, reason, error);
|
||||
goto out;
|
||||
}
|
||||
ptep = NULL;
|
||||
pgaddr = (void *)(fault_addr & ~(pgsize - 1));
|
||||
goto retry;
|
||||
}
|
||||
if (!virt) {
|
||||
error = -ENOMEM;
|
||||
kprintf("page_fault_process_memory_range(%p,%lx-%lx %lx,%lx,%lx):cannot allocate new page. %d\n", vm, range->start, range->end, range->flag, fault_addr, reason, error);
|
||||
@@ -1527,18 +1579,20 @@ static int page_fault_process_memory_range(struct process_vm *vm, struct vm_rang
|
||||
else {
|
||||
error = ihk_mc_pt_set_range(vm->address_space->page_table, vm,
|
||||
pgaddr, pgaddr + pgsize, phys,
|
||||
attr);
|
||||
attr, range->pgshift);
|
||||
if (error) {
|
||||
kprintf("page_fault_process_memory_range(%p,%lx-%lx %lx,%lx,%lx):set_range failed. %d\n", vm, range->start, range->end, range->flag, fault_addr, reason, error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
flush_tlb_single(fault_addr);
|
||||
error = 0;
|
||||
page = NULL;
|
||||
vm->currss += PAGE_SIZE;
|
||||
vm->currss += pgsize;
|
||||
if(vm->currss > vm->proc->maxrss)
|
||||
vm->proc->maxrss = vm->currss;
|
||||
|
||||
error = 0;
|
||||
page = NULL;
|
||||
|
||||
out:
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->page_table_lock);
|
||||
if (page) {
|
||||
@@ -1712,7 +1766,7 @@ int init_process_stack(struct thread *thread, struct program_load_desc *pn,
|
||||
thread->vm, (void *)(end-minsz),
|
||||
(void *)end, virt_to_phys(stack),
|
||||
arch_vrflag_to_ptattr(vrflag, PF_POPULATE,
|
||||
NULL));
|
||||
NULL), 0);
|
||||
if (error) {
|
||||
kprintf("init_process_stack:"
|
||||
"set range %lx-%lx %lx failed. %d\n",
|
||||
|
||||
@@ -159,8 +159,16 @@ int shmobj_create(struct shmid_ds *ds, struct memobj **objp)
|
||||
{
|
||||
struct shmobj *obj = NULL;
|
||||
int error;
|
||||
int pgshift;
|
||||
size_t pgsize;
|
||||
|
||||
dkprintf("shmobj_create(%p %#lx,%p)\n", ds, ds->shm_segsz, objp);
|
||||
pgshift = ds->init_pgshift;
|
||||
if (!pgshift) {
|
||||
pgshift = PAGE_SHIFT;
|
||||
}
|
||||
pgsize = (size_t)1 << pgshift;
|
||||
|
||||
obj = kmalloc(sizeof(*obj), IHK_MC_AP_NOWAIT);
|
||||
if (!obj) {
|
||||
error = -ENOMEM;
|
||||
@@ -174,9 +182,10 @@ int shmobj_create(struct shmid_ds *ds, struct memobj **objp)
|
||||
obj->ds = *ds;
|
||||
obj->ds.shm_perm.seq = the_seq++;
|
||||
obj->ds.shm_nattch = 1;
|
||||
obj->ds.init_pgshift = 0;
|
||||
obj->index = -1;
|
||||
obj->pgshift = PAGE_SHIFT;
|
||||
obj->real_segsz = (obj->ds.shm_segsz + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
obj->pgshift = pgshift;
|
||||
obj->real_segsz = (obj->ds.shm_segsz + pgsize - 1) & ~(pgsize - 1);
|
||||
page_list_init(obj);
|
||||
ihk_mc_spinlock_init(&obj->memobj.lock);
|
||||
|
||||
@@ -213,13 +222,14 @@ void shmobj_destroy(struct shmobj *obj)
|
||||
extern int the_maxi;
|
||||
struct shmlock_user *user;
|
||||
size_t size;
|
||||
int npages;
|
||||
|
||||
dkprintf("shmobj_destroy(%p [%d %o])\n", obj, obj->index, obj->ds.shm_perm.mode);
|
||||
if (obj->user) {
|
||||
user = obj->user;
|
||||
obj->user = NULL;
|
||||
shmlock_users_lock();
|
||||
size = (obj->ds.shm_segsz + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
size = obj->real_segsz;
|
||||
user->locked -= size;
|
||||
if (!user->locked) {
|
||||
shmlock_user_free(user);
|
||||
@@ -227,6 +237,7 @@ void shmobj_destroy(struct shmobj *obj)
|
||||
shmlock_users_unlock();
|
||||
}
|
||||
/* zap page_list */
|
||||
npages = (size_t)1 << (obj->pgshift - PAGE_SHIFT);
|
||||
for (;;) {
|
||||
struct page *page;
|
||||
int count;
|
||||
@@ -253,9 +264,8 @@ void shmobj_destroy(struct shmobj *obj)
|
||||
panic("shmobj_release");
|
||||
}
|
||||
|
||||
/* XXX:NYI: large pages */
|
||||
page->mode = PM_NONE;
|
||||
free_pages(phys_to_virt(page_to_phys(page)), 1);
|
||||
free_pages(phys_to_virt(page_to_phys(page)), npages);
|
||||
}
|
||||
if (obj->index < 0) {
|
||||
kfree(obj);
|
||||
@@ -362,9 +372,9 @@ static int shmobj_get_page(struct memobj *memobj, off_t off, int p2align,
|
||||
memobj, off, p2align, physp, error);
|
||||
goto out;
|
||||
}
|
||||
if (p2align != PAGE_P2ALIGN) { /* XXX:NYI:large pages */
|
||||
if (p2align != (obj->pgshift - PAGE_SHIFT)) {
|
||||
error = -ENOMEM;
|
||||
ekprintf("shmobj_get_page(%p,%#lx,%d,%p):large page. %d\n",
|
||||
ekprintf("shmobj_get_page(%p,%#lx,%d,%p):pgsize mismatch. %d\n",
|
||||
memobj, off, p2align, physp, error);
|
||||
goto out;
|
||||
}
|
||||
@@ -384,7 +394,8 @@ static int shmobj_get_page(struct memobj *memobj, off_t off, int p2align,
|
||||
page = page_list_lookup(obj, off);
|
||||
if (!page) {
|
||||
npages = 1 << p2align;
|
||||
virt = ihk_mc_alloc_pages(npages, IHK_MC_AP_NOWAIT);
|
||||
virt = ihk_mc_alloc_aligned_pages(npages, p2align,
|
||||
IHK_MC_AP_NOWAIT);
|
||||
if (!virt) {
|
||||
error = -ENOMEM;
|
||||
ekprintf("shmobj_get_page(%p,%#lx,%d,%p):"
|
||||
@@ -460,7 +471,7 @@ static int shmobj_lookup_page(struct memobj *memobj, off_t off, int p2align,
|
||||
struct shmobj *obj = to_shmobj(memobj);
|
||||
int error;
|
||||
struct page *page;
|
||||
uintptr_t phys;
|
||||
uintptr_t phys = NOPHYS;
|
||||
|
||||
dkprintf("shmobj_lookup_page(%p,%#lx,%d,%p)\n",
|
||||
memobj, off, p2align, physp);
|
||||
@@ -471,9 +482,9 @@ static int shmobj_lookup_page(struct memobj *memobj, off_t off, int p2align,
|
||||
memobj, off, p2align, physp, error);
|
||||
goto out;
|
||||
}
|
||||
if (p2align != PAGE_P2ALIGN) { /* XXX:NYI:large pages */
|
||||
if (p2align != (obj->pgshift - PAGE_SHIFT)) {
|
||||
error = -ENOMEM;
|
||||
ekprintf("shmobj_lookup_page(%p,%#lx,%d,%p):large page. %d\n",
|
||||
ekprintf("shmobj_lookup_page(%p,%#lx,%d,%p):pgsize mismatch. %d\n",
|
||||
memobj, off, p2align, physp, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -895,24 +895,20 @@ static int do_munmap(void *addr, size_t len)
|
||||
return error;
|
||||
}
|
||||
|
||||
static int search_free_space(size_t len, intptr_t hint, intptr_t *addrp)
|
||||
static int search_free_space(size_t len, intptr_t hint, int pgshift, intptr_t *addrp)
|
||||
{
|
||||
struct thread *thread = cpu_local_var(current);
|
||||
struct vm_regions *region = &thread->vm->region;
|
||||
intptr_t addr;
|
||||
int error;
|
||||
struct vm_range *range;
|
||||
size_t pgsize = (size_t)1 << pgshift;
|
||||
|
||||
dkprintf("search_free_space(%lx,%lx,%p)\n", len, hint, addrp);
|
||||
dkprintf("search_free_space(%lx,%lx,%d,%p)\n", len, hint, pgshift, addrp);
|
||||
|
||||
addr = hint;
|
||||
for (;;) {
|
||||
#ifdef USE_LARGE_PAGES
|
||||
if (len >= LARGE_PAGE_SIZE) {
|
||||
addr = (addr + LARGE_PAGE_SIZE - 1) & LARGE_PAGE_MASK;
|
||||
}
|
||||
#endif /* USE_LARGE_PAGES */
|
||||
|
||||
addr = (addr + pgsize - 1) & ~(pgsize - 1);
|
||||
if ((region->user_end <= addr)
|
||||
|| ((region->user_end - len) < addr)) {
|
||||
ekprintf("search_free_space(%lx,%lx,%p):"
|
||||
@@ -934,8 +930,8 @@ static int search_free_space(size_t len, intptr_t hint, intptr_t *addrp)
|
||||
*addrp = addr;
|
||||
|
||||
out:
|
||||
dkprintf("search_free_space(%lx,%lx,%p): %d %lx\n",
|
||||
len, hint, addrp, error, addr);
|
||||
dkprintf("search_free_space(%lx,%lx,%d,%p): %d %lx\n",
|
||||
len, hint, pgshift, addrp, error, addr);
|
||||
return error;
|
||||
}
|
||||
|
||||
@@ -994,6 +990,27 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
|
||||
|
||||
flush_nfo_tlb();
|
||||
|
||||
if (flags & MAP_HUGETLB) {
|
||||
pgshift = (flags >> MAP_HUGE_SHIFT) & 0x3F;
|
||||
p2align = pgshift - PAGE_SHIFT;
|
||||
}
|
||||
else if ((flags & MAP_PRIVATE) && (flags & MAP_ANONYMOUS)) {
|
||||
pgshift = 0; /* transparent huge page */
|
||||
p2align = PAGE_P2ALIGN;
|
||||
|
||||
if (len > PAGE_SIZE) {
|
||||
error = arch_get_smaller_page_size(NULL, len+1, NULL, &p2align);
|
||||
if (error) {
|
||||
ekprintf("do_mmap:arch_get_smaller_page_size failed. %d\n", error);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
pgshift = PAGE_SHIFT; /* basic page size */
|
||||
p2align = PAGE_P2ALIGN;
|
||||
}
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&thread->vm->memory_range_lock);
|
||||
|
||||
if (flags & MAP_FIXED) {
|
||||
@@ -1007,10 +1024,11 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
|
||||
}
|
||||
else {
|
||||
/* choose mapping address */
|
||||
error = search_free_space(len, region->map_end, &addr);
|
||||
error = search_free_space(len, region->map_end,
|
||||
PAGE_SHIFT+p2align, &addr);
|
||||
if (error) {
|
||||
ekprintf("do_mmap:search_free_space(%lx,%lx) failed. %d\n",
|
||||
len, region->map_end, error);
|
||||
ekprintf("do_mmap:search_free_space(%lx,%lx,%d) failed. %d\n",
|
||||
len, region->map_end, p2align, error);
|
||||
goto out;
|
||||
}
|
||||
region->map_end = addr + len;
|
||||
@@ -1096,13 +1114,6 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
|
||||
else if (!(vrflags & VR_DEMAND_PAGING)
|
||||
&& ((vrflags & VR_PROT_MASK) != VR_PROT_NONE)) {
|
||||
npages = len >> PAGE_SHIFT;
|
||||
p2align = PAGE_P2ALIGN;
|
||||
#ifdef USE_LARGE_PAGES
|
||||
if ((len >= LARGE_PAGE_SIZE)
|
||||
&& ((addr & (LARGE_PAGE_SIZE - 1)) == 0)) {
|
||||
p2align = LARGE_PAGE_P2ALIGN;
|
||||
}
|
||||
#endif /* USE_LARGE_PAGES */
|
||||
p = ihk_mc_alloc_aligned_pages(npages, p2align, IHK_MC_AP_NOWAIT);
|
||||
if (p == NULL) {
|
||||
ekprintf("do_mmap:allocate_pages(%d,%d) failed.\n",
|
||||
@@ -1116,6 +1127,7 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
|
||||
memset(&ads, 0, sizeof(ads));
|
||||
ads.shm_segsz = len;
|
||||
ads.shm_perm.mode = SHM_DEST;
|
||||
ads.init_pgshift = PAGE_SHIFT;
|
||||
error = shmobj_create(&ads, &memobj);
|
||||
if (error) {
|
||||
ekprintf("do_mmap:shmobj_create failed. %d\n", error);
|
||||
@@ -1141,13 +1153,6 @@ do_mmap(const intptr_t addr0, const size_t len0, const int prot,
|
||||
}
|
||||
vrflags |= VRFLAG_PROT_TO_MAXPROT(PROT_TO_VR_FLAG(maxprot));
|
||||
|
||||
if (flags & MAP_HUGETLB) {
|
||||
pgshift = (flags >> MAP_HUGE_SHIFT) & 0x3F;
|
||||
}
|
||||
else {
|
||||
pgshift = PAGE_SHIFT; /* basic page size */
|
||||
}
|
||||
|
||||
error = add_process_memory_range(thread->vm, addr, addr+len, phys,
|
||||
vrflags, memobj, off, pgshift);
|
||||
if (error) {
|
||||
@@ -3238,7 +3243,7 @@ SYSCALL_DECLARE(mincore)
|
||||
|
||||
ihk_mc_spinlock_lock_noirq(&vm->page_table_lock);
|
||||
ptep = ihk_mc_pt_lookup_pte(vm->address_space->page_table,
|
||||
(void *)addr, NULL, NULL, NULL);
|
||||
(void *)addr, 0, NULL, NULL, NULL);
|
||||
if (ptep && pte_is_present(ptep)) {
|
||||
value = 1;
|
||||
}
|
||||
@@ -3630,6 +3635,7 @@ int do_shmget(const key_t key, const size_t size, const int shmflg)
|
||||
ads.shm_segsz = size;
|
||||
ads.shm_ctime = now;
|
||||
ads.shm_cpid = proc->pid;
|
||||
ads.init_pgshift = pgshift;
|
||||
|
||||
error = shmobj_create_indexed(&ads, &obj);
|
||||
if (error) {
|
||||
@@ -3639,7 +3645,6 @@ int do_shmget(const key_t key, const size_t size, const int shmflg)
|
||||
}
|
||||
|
||||
obj->index = ++the_maxi;
|
||||
obj->pgshift = pgshift;
|
||||
|
||||
list_add(&obj->chain, &kds_list);
|
||||
++the_shm_info.used_ids;
|
||||
@@ -3668,6 +3673,7 @@ SYSCALL_DECLARE(shmat)
|
||||
int vrflags;
|
||||
int req;
|
||||
struct shmobj *obj;
|
||||
size_t pgsize;
|
||||
|
||||
dkprintf("shmat(%#x,%p,%#x)\n", shmid, shmaddr, shmflg);
|
||||
|
||||
@@ -3679,13 +3685,14 @@ SYSCALL_DECLARE(shmat)
|
||||
return error;
|
||||
}
|
||||
|
||||
if (shmaddr && ((uintptr_t)shmaddr & (PAGE_SIZE - 1)) && !(shmflg & SHM_RND)) {
|
||||
pgsize = (size_t)1 << obj->pgshift;
|
||||
if (shmaddr && ((uintptr_t)shmaddr & (pgsize - 1)) && !(shmflg & SHM_RND)) {
|
||||
shmobj_list_unlock();
|
||||
dkprintf("shmat(%#x,%p,%#x): -EINVAL\n", shmid, shmaddr, shmflg);
|
||||
return -EINVAL;
|
||||
}
|
||||
addr = (uintptr_t)shmaddr & PAGE_MASK;
|
||||
len = (obj->ds.shm_segsz + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
addr = (uintptr_t)shmaddr & ~(pgsize - 1);
|
||||
len = obj->real_segsz;
|
||||
|
||||
prot = PROT_READ;
|
||||
req = 4;
|
||||
@@ -3725,7 +3732,7 @@ SYSCALL_DECLARE(shmat)
|
||||
}
|
||||
}
|
||||
else {
|
||||
error = search_free_space(len, region->map_end, &addr);
|
||||
error = search_free_space(len, region->map_end, obj->pgshift, &addr);
|
||||
if (error) {
|
||||
ihk_mc_spinlock_unlock_noirq(&vm->memory_range_lock);
|
||||
shmobj_list_unlock();
|
||||
@@ -3753,7 +3760,7 @@ SYSCALL_DECLARE(shmat)
|
||||
memobj_ref(&obj->memobj);
|
||||
|
||||
error = add_process_memory_range(vm, addr, addr+len, -1,
|
||||
vrflags, &obj->memobj, 0, PAGE_SHIFT);
|
||||
vrflags, &obj->memobj, 0, obj->pgshift);
|
||||
if (error) {
|
||||
if (!(prot & PROT_WRITE)) {
|
||||
(void)set_host_vma(addr, len, PROT_READ|PROT_WRITE);
|
||||
@@ -3940,7 +3947,7 @@ SYSCALL_DECLARE(shmctl)
|
||||
ekprintf("shmctl(%#x,%d,%p): user lookup: %d\n", shmid, cmd, buf, error);
|
||||
return -ENOMEM;
|
||||
}
|
||||
size = (obj->ds.shm_segsz + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
size = obj->real_segsz;
|
||||
if (!has_cap_ipc_lock(thread)
|
||||
&& (rlim->rlim_cur != (rlim_t)-1)
|
||||
&& ((rlim->rlim_cur < user->locked)
|
||||
@@ -3978,7 +3985,7 @@ SYSCALL_DECLARE(shmctl)
|
||||
if ((obj->ds.shm_perm.mode & SHM_LOCKED)
|
||||
&& ((obj->pgshift == 0)
|
||||
|| (obj->pgshift == PAGE_SHIFT))) {
|
||||
size = (obj->ds.shm_segsz + PAGE_SIZE - 1) & PAGE_MASK;
|
||||
size = obj->real_segsz;
|
||||
shmlock_users_lock();
|
||||
user = obj->user;
|
||||
obj->user = NULL;
|
||||
@@ -6433,7 +6440,7 @@ SYSCALL_DECLARE(mremap)
|
||||
}
|
||||
need_relocate = 1;
|
||||
error = search_free_space(newsize, vm->region.map_end,
|
||||
(intptr_t *)&newstart);
|
||||
range->pgshift, (intptr_t *)&newstart);
|
||||
if (error) {
|
||||
ekprintf("sys_mremap(%#lx,%#lx,%#lx,%#x,%#lx):"
|
||||
"search failed. %d\n",
|
||||
|
||||
@@ -182,7 +182,7 @@ static int zeroobj_get_page(struct memobj *memobj, off_t off, int p2align,
|
||||
}
|
||||
if (p2align != PAGE_P2ALIGN) { /* XXX:NYI:large pages */
|
||||
error = -ENOMEM;
|
||||
ekprintf("zeroobj_get_page(%p,%#lx,%d,%p):large page. %d\n",
|
||||
dkprintf("zeroobj_get_page(%p,%#lx,%d,%p):large page. %d\n",
|
||||
memobj, off, p2align, physp, error);
|
||||
goto out;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user