Page MenuHomeFreeBSD

D38978.id118521.diff
No OneTemporary

D38978.id118521.diff

diff --git a/sys/compat/linux/linux_misc.c b/sys/compat/linux/linux_misc.c
--- a/sys/compat/linux/linux_misc.c
+++ b/sys/compat/linux/linux_misc.c
@@ -62,6 +62,7 @@
#include <security/mac/mac_framework.h>
#include <vm/pmap.h>
+#include <vm/vm_param.h>
#include <vm/vm_map.h>
#include <vm/swap_pager.h>
@@ -324,6 +325,14 @@
args->old_len = round_page(args->old_len);
if (args->new_len > args->old_len) {
+ vm_offset_t new_addr = args->addr;
+
+ if (vm_mremap(td, &new_addr, args->new_len, args->addr,
+ args->old_len, args->flags) == KERN_SUCCESS) {
+ td->td_retval[0] = (uintptr_t)new_addr;
+ return 0;
+ }
+
td->td_retval[0] = 0;
return (ENOMEM);
}
diff --git a/sys/vm/vm_map.h b/sys/vm/vm_map.h
--- a/sys/vm/vm_map.h
+++ b/sys/vm/vm_map.h
@@ -534,5 +534,7 @@
int flags);
long vmspace_swap_count(struct vmspace *vmspace);
void vm_map_entry_set_vnode_text(vm_map_entry_t entry, bool add);
+int vm_mremap(struct thread *td, vm_offset_t *naddr,
+ size_t nsize, uintptr_t oaddr, size_t osize, int flags);
#endif /* _KERNEL */
#endif /* _VM_MAP_ */
diff --git a/sys/vm/vm_mmap.c b/sys/vm/vm_mmap.c
--- a/sys/vm/vm_mmap.c
+++ b/sys/vm/vm_mmap.c
@@ -94,6 +94,8 @@
#include <vm/vm_page.h>
#include <vm/vnode_pager.h>
+#include <fs/tmpfs/tmpfs.h>
+
#ifdef HWPMC_HOOKS
#include <sys/pmckern.h>
#endif
@@ -1678,3 +1680,74 @@
return (EINVAL);
}
}
+
+int
+vm_mremap(struct thread *td, vm_offset_t *naddr,
+ size_t nsize, uintptr_t oaddr, size_t osize, int flags)
+{
+ struct vmspace *vms;
+ vm_map_entry_t entry;
+ vm_offset_t kva, ofs;
+ vm_object_t obj;
+ vm_pindex_t pindex;
+ vm_prot_t prot;
+ boolean_t wired;
+ vm_map_t map;
+ size_t size;
+ int rv, vnode;
+
+ vms = td->td_proc->p_vmspace;
+
+ kva = (vm_offset_t)oaddr;
+ ofs = kva & PAGE_MASK;
+ kva = trunc_page(kva);
+ size = round_page(osize + ofs);
+ map = &vms->vm_map;
+
+ rv = vm_map_lookup(&map, kva, VM_PROT_READ | VM_PROT_WRITE, &entry,
+ &obj, &pindex, &prot, &wired);
+
+ if (rv != KERN_SUCCESS)
+ goto out;
+
+ vm_map_lookup_done(map, entry);
+
+ vnode = (obj->backing_object || obj->handle
+ || (obj->flags & OBJ_TMPFS));
+
+ if (vnode) {
+ vm_object_reference(obj);
+ rv = vm_mmap_object(map, naddr, nsize, prot, prot, MAP_SHARED,
+ obj, kva - entry->start, FALSE, td);
+ } else {
+ rv = vm_mmap_object(map, naddr, nsize, prot, prot,
+ MAP_PRIVATE | MAP_ANON, NULL, 0, FALSE, td);
+ if (rv == KERN_SUCCESS) {
+ size_t n = 0;
+ int save;
+
+ save = vm_fault_disable_pagefaults();
+ for (n = 0; n < osize; n += PAGE_SIZE) {
+ rv = vm_fault(map, (*naddr) + n, prot,
+ VM_FAULT_NORMAL, NULL);
+ if (rv != KERN_SUCCESS) {
+ vm_fault_enable_pagefaults(save);
+ goto out;
+ }
+
+ rv = copyin((void *)(kva + n),
+ (void *)((*naddr) + n), PAGE_SIZE);
+ if (rv) {
+ vm_fault_enable_pagefaults(save);
+ return KERN_NO_ACCESS;
+ }
+ }
+ vm_fault_enable_pagefaults(save);
+ }
+ }
+
+ vm_map_remove(map, kva, kva + size);
+
+out:
+ return rv;
+}

File Metadata

Mime Type
text/plain
Expires
Wed, Nov 6, 2:55 PM (8 h, 58 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
14471877
Default Alt Text
D38978.id118521.diff (2 KB)

Event Timeline