lkml.org 
[lkml]   [2021]   [Sep]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
/
Date
From
SubjectRe: [PATCH v7 03/19] gup: Turn fault_in_pages_{readable,writeable} into fault_in_{readable,writeable}
On Tue, Sep 28, 2021 at 05:02:43PM +0200, Andreas Gruenbacher wrote:
> On Fri, Sep 3, 2021 at 4:57 PM Filipe Manana <fdmanana@gmail.com> wrote:
> > On Fri, Aug 27, 2021 at 5:52 PM Andreas Gruenbacher <agruenba@redhat.com> wrote:
> > > +size_t fault_in_writeable(char __user *uaddr, size_t size)
> > > +{
> > > + char __user *start = uaddr, *end;
> > > +
> > > + if (unlikely(size == 0))
> > > + return 0;
> > > + if (!PAGE_ALIGNED(uaddr)) {
> > > + if (unlikely(__put_user(0, uaddr) != 0))
> > > + return size;
> > > + uaddr = (char __user *)PAGE_ALIGN((unsigned long)uaddr);
> > > + }
> > > + end = (char __user *)PAGE_ALIGN((unsigned long)start + size);
> > > + if (unlikely(end < start))
> > > + end = NULL;
> > > + while (uaddr != end) {
> > > + if (unlikely(__put_user(0, uaddr) != 0))
> > > + goto out;
> > > + uaddr += PAGE_SIZE;
> >
> > Won't we loop endlessly or corrupt some unwanted page when 'end' was
> > set to NULL?
>
> What do you mean? We set 'end' to NULL when start + size < start
> exactly so that the loop will stop when uaddr wraps around.

But think about x86-64. The virtual address space (unless you have 5
level PTs) looks like:

[0, 2^47) userspace
[2^47, 2^64 - 2^47) hole
[2^64 - 2^47, 2^64) kernel space

If we try to copy from the hole we'll get some kind of fault (I forget
the details). We have to stop at the top of userspace.

\
 
 \ /
  Last update: 2021-09-28 18:42    [W:0.122 / U:0.032 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site