Re: mapping user space buffer to kernel address space

From: Linus Torvalds (torvalds@transmeta.com)
Date: Thu Oct 19 2000 - 15:23:39 EST


On Thu, 19 Oct 2000, Jeff Garzik wrote:
>
> > > Since this code works in my local tests, my two concerns at this point
> > > are correct vma->vm_pgoff treatment, and correct vm_flags/vm_file usage.
>
> Can I completely ignore vm_pgoff in nopage()? Currently I just do the
> following, to get the page number relative to the start of the vma:
>
> pgoff = (address - vma->vm_start) >> PAGE_SHIFT;
>
> where 'address' is the value passed to nopage().

Oh, no, you can't do that. It should be something like

        pgoff = vma->vm_pgoff + (address - vma->vm_start) >> PAGE_SHIFT;

and quite frankly we should just change the damn "nopage()" arguments to
be

        struct page * (*nopage)(struct vm_area_struct * area, unsigned long pgoff, int write_access);

because the nopage() routine really shouldn't care about "address" at all
(the VM layer cares, but "nopage()" should just return the proper page at
the proper offset into the mapping).

I didn't notice..

>
> The first draft of code had only
>
> vma->vm_ops = &via_mm_ops;
> vma->vm_private_data = card;
>
> and userspace apps segfaulted. I then added the two objectionable
> lines, and things started working:
>
> vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
> vma->vm_file = file;
>
> Have not yet checked any combinations in between...

Ahh, I think I see why. You should do a "get_page()" on the page before
you return it from your nopage() - otherwise your page counts will be
completely wrong.

Actually, as far as I can tell your page counts ended up being wrong
anyway, but probably only at the end of the munmap() rather than at
runtime.

                Linus

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.kernel.org
Please read the FAQ at http://www.tux.org/lkml/



This archive was generated by hypermail 2b29 : Mon Oct 23 2000 - 21:00:15 EST