From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53223) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1evR9E-0008TU-42 for qemu-devel@nongnu.org; Mon, 12 Mar 2018 13:22:09 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1evR9C-0007r3-SV for qemu-devel@nongnu.org; Mon, 12 Mar 2018 13:22:08 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:57632 helo=mx1.redhat.com) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1evR9C-0007qf-NO for qemu-devel@nongnu.org; Mon, 12 Mar 2018 13:22:06 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 6054D401DE71 for ; Mon, 12 Mar 2018 17:22:06 +0000 (UTC) From: "Dr. David Alan Gilbert (git)" Date: Mon, 12 Mar 2018 17:21:18 +0000 Message-Id: <20180312172124.56461-24-dgilbert@redhat.com> In-Reply-To: <20180312172124.56461-1-dgilbert@redhat.com> References: <20180312172124.56461-1-dgilbert@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: [Qemu-devel] [PATCH v5 23/29] libvhost-user: mprotect & madvises for postcopy List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org, mst@redhat.com, maxime.coquelin@redhat.com, marcandre.lureau@redhat.com, peterx@redhat.com, quintela@redhat.com Cc: aarcange@redhat.com From: "Dr. David Alan Gilbert" Clear the area and turn off THP. PROT_NONE the area until after we've userfault advised it to catch any unexpected changes. Signed-off-by: Dr. David Alan Gilbert Reviewed-by: Marc-Andr=C3=A9 Lureau --- contrib/libvhost-user/libvhost-user.c | 47 +++++++++++++++++++++++++++++= ++---- 1 file changed, 42 insertions(+), 5 deletions(-) diff --git a/contrib/libvhost-user/libvhost-user.c b/contrib/libvhost-use= r/libvhost-user.c index 6314549b65..5feed52098 100644 --- a/contrib/libvhost-user/libvhost-user.c +++ b/contrib/libvhost-user/libvhost-user.c @@ -454,7 +454,7 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUserM= sg *vmsg) int i; VhostUserMemory *memory =3D &vmsg->payload.memory; dev->nregions =3D memory->nregions; - /* TODO: Postcopy specific code */ + DPRINT("Nregions: %d\n", memory->nregions); for (i =3D 0; i < dev->nregions; i++) { void *mmap_addr; @@ -478,9 +478,12 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUser= Msg *vmsg) =20 /* We don't use offset argument of mmap() since the * mapped address has to be page aligned, and we use huge - * pages. */ + * pages. + * In postcopy we're using PROT_NONE here to catch anyone + * accessing it before we userfault + */ mmap_addr =3D mmap(0, dev_region->size + dev_region->mmap_offset= , - PROT_READ | PROT_WRITE, MAP_SHARED, + PROT_NONE, MAP_SHARED, vmsg->fds[i], 0); =20 if (mmap_addr =3D=3D MAP_FAILED) { @@ -519,12 +522,38 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUse= rMsg *vmsg) /* OK, now we can go and register the memory and generate faults */ for (i =3D 0; i < dev->nregions; i++) { VuDevRegion *dev_region =3D &dev->regions[i]; + int ret; #ifdef UFFDIO_REGISTER /* We should already have an open ufd. Mark each memory * range as ufd. - * Note: Do we need any madvises? Well it's not been accessed - * yet, still probably need no THP to be safe, discard to be saf= e? + * Discard any mapping we have here; note I can't use MADV_REMOV= E + * or fallocate to make the hole since I don't want to lose + * data that's already arrived in the shared process. + * TODO: How to do hugepage */ + ret =3D madvise((void *)dev_region->mmap_addr, + dev_region->size + dev_region->mmap_offset, + MADV_DONTNEED); + if (ret) { + fprintf(stderr, + "%s: Failed to madvise(DONTNEED) region %d: %s\n", + __func__, i, strerror(errno)); + } + /* Turn off transparent hugepages so we dont get lose wakeups + * in neighbouring pages. + * TODO: Turn this backon later. + */ + ret =3D madvise((void *)dev_region->mmap_addr, + dev_region->size + dev_region->mmap_offset, + MADV_NOHUGEPAGE); + if (ret) { + /* Note: This can happen legally on kernels that are configu= red + * without madvise'able hugepages + */ + fprintf(stderr, + "%s: Failed to madvise(NOHUGEPAGE) region %d: %s\n", + __func__, i, strerror(errno)); + } struct uffdio_register reg_struct; reg_struct.range.start =3D (uintptr_t)dev_region->mmap_addr; reg_struct.range.len =3D dev_region->size + dev_region->mmap_off= set; @@ -546,6 +575,14 @@ vu_set_mem_table_exec_postcopy(VuDev *dev, VhostUser= Msg *vmsg) } DPRINT("%s: region %d: Registered userfault for %llx + %llx\n", __func__, i, reg_struct.range.start, reg_struct.range.le= n); + /* Now it's registered we can let the client at it */ + if (mprotect((void *)dev_region->mmap_addr, + dev_region->size + dev_region->mmap_offset, + PROT_READ | PROT_WRITE)) { + vu_panic(dev, "failed to mprotect region %d for postcopy (%s= )", + i, strerror(errno)); + return false; + } /* TODO: Stash 'zero' support flags somewhere */ #endif } --=20 2.14.3