lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date:   Wed, 20 Feb 2019 20:15:56 +0000
From:   Joao Martins <joao.m.martins@...cle.com>
To:     kvm@...r.kernel.org, linux-kernel@...r.kernel.org
Cc:     Ankur Arora <ankur.a.arora@...cle.com>,
        Boris Ostrovsky <boris.ostrovsky@...cle.com>,
        Joao Martins <joao.m.martins@...cle.com>,
        Paolo Bonzini <pbonzini@...hat.com>,
        Radim Krčmář <rkrcmar@...hat.com>,
        Thomas Gleixner <tglx@...utronix.de>,
        Ingo Molnar <mingo@...hat.com>, Borislav Petkov <bp@...en8.de>,
        "H. Peter Anvin" <hpa@...or.com>, x86@...nel.org
Subject: [PATCH RFC 26/39] KVM: x86/xen: grant unmap support

From: Ankur Arora <ankur.a.arora@...cle.com>

Grant unmap removes the grant from maptrack and marks it as not in use.
We maintain a one-to-one correspondence between grant table and maptrack
entries so there's no contention in allocation/free.

Co-developed-by: Joao Martins <joao.m.martins@...cle.com>
Signed-off-by: Ankur Arora <ankur.a.arora@...cle.com>
Signed-off-by: Joao Martins <joao.m.martins@...cle.com>
---
 arch/x86/kvm/xen.c | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 73 insertions(+)

diff --git a/arch/x86/kvm/xen.c b/arch/x86/kvm/xen.c
index 3603645086a7..8f06924e0dfa 100644
--- a/arch/x86/kvm/xen.c
+++ b/arch/x86/kvm/xen.c
@@ -1684,6 +1684,69 @@ static int shim_hcall_gntmap(struct kvm_xen *ld,
 	return 0;
 }
 
+static int shim_hcall_gntunmap(struct kvm_xen *xen,
+			       struct gnttab_unmap_grant_ref *op)
+{
+	struct kvm_grant_map *map, unmap;
+	struct grant_entry_v1 **rgt;
+	struct grant_entry_v1 *shah;
+	struct kvm *rd = NULL;
+	domid_t domid;
+	u32 ref;
+
+	domid = handle_get_domid(op->handle);
+	ref = handle_get_grant(op->handle);
+
+
+	rd = kvm_xen_find_vm(domid);
+	if (unlikely(!rd)) {
+		/* We already teardown all ongoing grant maps */
+		op->status = GNTST_okay;
+		return 0;
+	}
+
+	if (unlikely(ref >= gnttab_entries(rd))) {
+		pr_err("gnttab: bad ref %u\n", ref);
+		op->status = GNTST_bad_handle;
+		return 0;
+	}
+
+	rgt = rd->arch.xen.gnttab.frames_v1;
+	map = maptrack_entry(rd->arch.xen.gnttab.handle, ref);
+
+	/*
+	 * The test_and_clear_bit (below) serializes ownership of this
+	 * grant-entry.  After we clear it, there can be a grant-map on this
+	 * entry. So we cache the unmap entry before relinquishing ownership.
+	 */
+	unmap = *map;
+
+	if (!test_and_clear_bit(_KVM_GNTMAP_ACTIVE,
+				(unsigned long *) &map->flags)) {
+		pr_err("gnttab: bad flags for %u (dom %u ref %u) flags %x\n",
+			op->handle, domid, ref, unmap.flags);
+		op->status = GNTST_bad_handle;
+		return 0;
+	}
+
+	/* Give up the reference taken in get_user_pages_remote(). */
+	put_page(virt_to_page(unmap.gpa));
+
+	shah = shared_entry(rgt, unmap.ref);
+
+	/*
+	 * We have cleared _KVM_GNTMAP_ACTIVE, so a simultaneous grant-map
+	 * could update the shah and we would stomp all over it but the
+	 * guest deserves it.
+	 */
+	if (!(unmap.flags & GNTMAP_readonly))
+		clear_bit(_GTF_writing, (unsigned long *) &shah->flags);
+	clear_bit(_GTF_reading, (unsigned long *) &shah->flags);
+
+	op->status = GNTST_okay;
+	return 0;
+}
+
 static int shim_hcall_gnttab(int op, void *p, int count)
 {
 	int ret = -ENOSYS;
@@ -1698,6 +1761,16 @@ static int shim_hcall_gnttab(int op, void *p, int count)
 		ret = 0;
 		break;
 	}
+	case GNTTABOP_unmap_grant_ref: {
+		struct gnttab_unmap_grant_ref *ref = p;
+
+		for (i = 0; i < count; i++) {
+			shim_hcall_gntunmap(xen_shim, ref + i);
+			ref[i].host_addr = 0;
+		}
+		ret = 0;
+		break;
+	}
 	default:
 		pr_info("lcall-gnttab:op default=%d\n", op);
 		break;
-- 
2.11.0

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ