Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Feb 2011 17:18:50 +0800
From:      "beezarliu" <beezarliu@yahoo.com.cn>
To:        "freebsd-hackers@freebsd.org" <freebsd-hackers@freebsd.org>
Subject:   map share memory to kernel space
Message-ID:  <201102141718415933573@yahoo.com.cn>

next in thread | raw e-mail | index | archive | help
Hackers,

I want to access a userland share memory in a kernel thread. 
So I tried to map the share memory to the kernel space. 
The basic idea is to map the shm_object into kernel_map
when the share memory is created.

Using the following patch, I found the vm_object in kernel_map,
and the vm_object in the address space of userland process are the same.
But their content in the kernel and userland address mapped are different.

It's very strang since they are exactly the same vm_object.
Do I miss something, please help.

Thanks!


Index: sys/kern/sysv_shm.c
===================================================================
--- sys/kern/sysv_shm.c (revision xxxxxx)
+++ sys/kern/sysv_shm.c (working copy)
@@ -90,11 +90,14 @@
 #include <vm/vm.h>
 #include <vm/vm_param.h>
 #include <vm/pmap.h>
+#include <vm/vm_kern.h>
 #include <vm/vm_object.h>
 #include <vm/vm_map.h>
 #include <vm/vm_page.h>
 #include <vm/vm_pager.h>
 
 static MALLOC_DEFINE(M_SHM, "shm", "SVID compatible shared memory segments");
 
 static int shmget_allocate_segment(struct thread *td,
@@ -421,6 +424,7 @@
        shmseg->u.shm_atime = time_second;
        shmseg->u.shm_nattch++;
        td->td_retval[0] = attach_va;
 done2:
        mtx_unlock(&Giant);
        return (error);
@@ -678,10 +682,61 @@
         * We make sure that we have allocated a pager before we need
         * to.
         */
-       shm_object = vm_pager_allocate(shm_use_phys ? OBJT_PHYS : OBJT_SWAP,
-           0, size, VM_PROT_DEFAULT, 0, cred);
+       if (uap->key == aaaaaa) {
+               shm_object = vm_pager_allocate(shm_use_phys ? OBJT_PHYS : OBJT_SWAP,
+                   0, size, VM_PROT_DEFAULT, 0, cred);
+       } else {
+               shm_object = vm_pager_allocate(OBJT_PHYS, 0, size,
+                   VM_PROT_DEFAULT, 0, cred);
+       }
        if (shm_object == NULL)
                return (ENOMEM);
+
+       if (uap->key == aaaaaa) {
+               vm_offset_t addr;
+               vm_offset_t offset;
+               vm_offset_t i;
+
+               printf("attach to kernel map.\n");
+
+               vm_map_lock(kernel_map);
+               if (vm_map_findspace(kernel_map, vm_map_min(kernel_map),
+                   size, &addr)) {
+                       vm_map_unlock(kernel_map);
+                       return (0);
+               }
+               offset = addr - VM_MIN_KERNEL_ADDRESS;
+               vm_object_reference(shm_object);
+               vm_map_insert(kernel_map, shm_object, offset, addr, addr + size,
+                       VM_PROT_ALL, VM_PROT_ALL, 0);
+               vm_map_unlock(kernel_map);
+
+               VM_OBJECT_LOCK(shm_object);
+               for (i = 0; i < size; i += PAGE_SIZE) {
+                       vm_page_t mem;
+
+                       mem = vm_page_grab(shm_object, OFF_TO_IDX(offset + i),
+                           VM_ALLOC_NOBUSY | VM_ALLOC_ZERO | VM_ALLOC_RETRY);
+                       mem->valid = VM_PAGE_BITS_ALL;
+                       KASSERT((mem->flags & PG_UNMANAGED) != 0,
+                           ("shm_alloc: page %p is managed", mem));
+               }
+               VM_OBJECT_UNLOCK(shm_object);
+
+               /*
+                * And finally, mark the data as non-pageable.
+                */
+               (void) vm_map_wire(kernel_map, addr, addr + size,
+                   VM_MAP_WIRE_USER|VM_MAP_WIRE_NOHOLES);
+
+               vm_map_inherit(kernel_map, addr, addr + size, VM_INHERIT_SHARE);
+       }
+
        VM_OBJECT_LOCK(shm_object);
        vm_object_clear_flag(shm_object, OBJ_ONEMAPPING);
        vm_object_set_flag(shm_object, OBJ_NOSPLIT);


2011-02-14 



beezarliu 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201102141718415933573>