Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 14 Feb 2011 09:39:17 -0500
From:      John Baldwin <jhb@freebsd.org>
To:        freebsd-hackers@freebsd.org
Cc:        beezarliu <beezarliu@yahoo.com.cn>
Subject:   Re: map share memory to kernel space
Message-ID:  <201102140939.17486.jhb@freebsd.org>
In-Reply-To: <201102141718415933573@yahoo.com.cn>
References:  <201102141718415933573@yahoo.com.cn>

next in thread | previous in thread | raw e-mail | index | archive | help
On Monday, February 14, 2011 4:18:50 am beezarliu wrote:
> 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.

Hmm, this is a bit of code I use for something similar to map a VM object into 
the kernel.  It does not use vm_page_grab() directly though:

        VM_OBJECT_LOCK(obj);
        vm_object_reference_locked(obj);
        VM_OBJECT_UNLOCK(obj);

        /* Map the object into the kernel_map and wire it. */
        kva = vm_map_min(kernel_map);
        ofs = foff & PAGE_MASK;
        foff = trunc_page(foff);
        size = round_page(size + ofs);
        rv = vm_map_find(kernel_map, obj, foff, &kva, size, TRUE,
            VM_PROT_READ | VM_PROT_WRITE, VM_PROT_READ | VM_PROT_WRITE, 0);
        if (rv == KERN_SUCCESS) {
                rv = vm_map_wire(kernel_map, kva, kva + size,
                    VM_MAP_WIRE_SYSTEM | VM_MAP_WIRE_NOHOLES);
                if (rv == KERN_SUCCESS) {
                        *memp = (void *)(kva + ofs);
                        return (0);
                }
                vm_map_remove(kernel_map, kva, kva + size);
        } else
                vm_object_deallocate(obj);

Unmapping the object is easy of course:

        kva = (vm_offset_t)mem;
        ofs = kva & PAGE_MASK;
        kva = trunc_page(kva);
        size = round_page(size + ofs);
        vm_map_remove(kernel_map, kva, kva + size);


-- 
John Baldwin



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