Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F101919284
D38978.id118521.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
2 KB
Referenced Files
None
Subscribers
None
D38978.id118521.diff
View Options
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
Details
Attached
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)
Attached To
Mode
D38978: Linux Compatible: enhance the linux_mremap
Attached
Detach File
Event Timeline
Log In to Comment