Subject: Re: uvm_map ?
To: George Peter Staplin <georgeps@xmission.com>
From: Nalin Gupta <nalingupta2000@gmail.com>
List: tech-kern
Date: 05/15/2007 16:59:46
All / George,

As I had reported last time, based on George suggestion my module was
able to attach kernel memory to user process. Now if I make user
process "daemon", i observe for following both "error" and "vaddr"
returned are ZERO.

I even tried putting sleep(15) in my user space program, before
calling open/ioctl to my module.

Any Comments ?

    /* Attach phy pages to user virtual addr */
    error = uvm_map( &p->p_vmspace->vm_map,
                     &vaddr,
                     size,
                     uvmObject,
                     0,
                     0,
                     UVM_MAPFLAG(UVM_PROT_ALL, UVM_PROT_ALL,
                                UVM_INH_SHARE, UVM_ADV_NORMAL, 0)) ;

I am using NetBSD-2.0.3.

Thanks in Advance.

regards,
- nalin
=============================================================

On 4/13/07, George Peter Staplin <georgeps@xmission.com> wrote:
> Quote "Nalin":
> > hello
> >
> > Is uvm_map enough to attach kernel memory to user process ?
> >
> > regards,
> > - nalin
>
> This is one possible solution in the kernel using uvm_map I think.  I
> used this solution in NetBSD 3.0 for shared memory in a project I
> called blockmgr.  I was able to write to/read from all of the pages
> from userland and the kernel, after loading the LKM.  I'm not sure how
> well it works with wired memory, but I'm sure someone will post about
> that, if needed.
>
> In the kernel init/setup routine for your code:
> blockmgr->size = round_page (blocksize * n);
> blockmgr->uaoobj = uao_create (blockmgr->size, 0);
> blockmgr->kerneladdress = 0;
>
> error = uvm_map (kernel_map, &blockmgr->kerneladdress, blockmgr->size,
>    blockmgr->uaoobj, 0, /*align*/ 2,   UVM_MAPFLAG (UVM_PROT_ALL,
> UVM_PROT_ALL, UVM_INH_SHARE, UVM_ADV_NORMAL, 0));
>
> if (error) {
>   uao_detach (blockmgr->uaoobj);
>   return error;
> }
>
> uao_reference (blockmgr->uaoobj)
>
>
>
>
> Now in a syscall I did this:
>
> int
> sys_inherit_blocks ( struct lwp *l, void *ua, register_t *retval ) {
> int error;
> vaddr_t r = 0;
>
> *retval = 0;
>   if (NULL == blockmgr->uaoobj) {
>    printf ("sys_inherit_blocks: blockmgr not initialized!\n");
>    return ENOBUFS;
> }
>
> uao_reference (blockmgr->uaoobj);
>   error = uvm_map (&l->l_proc->p_vmspace->vm_map, &r, blockmgr->size,
>    blockmgr->uaoobj, 0, /*align*/ 2,
>    UVM_MAPFLAG (UVM_PROT_ALL, UVM_PROT_ALL, UVM_INH_SHARE, UVM_ADV_NORMAL, 0));
>
> if (error)
>   return error;
>
> *retval = (register_t) r;
>   return 0;
> }
>
> I think in hindsight I'd create a new /dev/blockmgr or something along
> those lines.
>
> --
> http://www.xmission.com/~georgeps/
>