From mboxrd@z Thu Jan 1 00:00:00 1970 From: Matthew Wilcox Date: Tue, 28 Sep 2021 17:37:52 +0100 Subject: [Cluster-devel] [PATCH v7 03/19] gup: Turn fault_in_pages_{readable, writeable} into fault_in_{readable, writeable} In-Reply-To: References: <20210827164926.1726765-1-agruenba@redhat.com> <20210827164926.1726765-4-agruenba@redhat.com> Message-ID: List-Id: To: cluster-devel.redhat.com MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit On Tue, Sep 28, 2021 at 05:02:43PM +0200, Andreas Gruenbacher wrote: > On Fri, Sep 3, 2021 at 4:57 PM Filipe Manana wrote: > > On Fri, Aug 27, 2021 at 5:52 PM Andreas Gruenbacher 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.