All of lore.kernel.org
 help / color / mirror / Atom feed
From: Michael Roth <michael.roth@amd.com>
To: <linux-kselftest@vger.kernel.org>
Cc: Brijesh Singh <brijesh.singh@amd.com>,
	kvm@vger.kernel.org, David Hildenbrand <david@redhat.com>,
	Marc Orr <marcorr@google.com>, "H . Peter Anvin" <hpa@zytor.com>,
	Claudio Imbrenda <imbrenda@linux.ibm.com>,
	Shuah Khan <shuah@kernel.org>,
	kvmarm@lists.cs.columbia.edu, Nathan Tempelman <natet@google.com>,
	Janosch Frank <frankja@linux.ibm.com>,
	Marc Zyngier <maz@kernel.org>, Joerg Roedel <joro@8bytes.org>,
	x86@kernel.org, Ingo Molnar <mingo@redhat.com>,
	Mingwei Zhang <mizhang@google.com>,
	Christian Borntraeger <borntraeger@linux.ibm.com>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	Borislav Petkov <bp@alien8.de>,
	Thomas Gleixner <tglx@linutronix.de>,
	Varad Gautam <varad.gautam@suse.com>,
	Jim Mattson <jmattson@google.com>,
	Steve Rutherford <srutherford@google.com>,
	linux-kernel@vger.kernel.org,
	Vitaly Kuznetsov <vkuznets@redhat.com>,
	David Woodhouse <dwmw@amazon.co.uk>
Subject: [PATCH RFC 06/10] kvm: selftests: add ucall interfaces based around shared memory
Date: Fri, 10 Dec 2021 10:46:16 -0600	[thread overview]
Message-ID: <20211210164620.11636-7-michael.roth@amd.com> (raw)
In-Reply-To: <20211210164620.11636-1-michael.roth@amd.com>

One complication with SEV and likely other Confidential Computing
implementations is the fact that guest stacks might be encrypted, so
existing interfaces like ucall()/get_ucall() will not work as-is since
they allocate ucall structs on the guest stack dynamically.
Additionally, the basic task of communicating the location in guest
memory of these structs is complicated by the fact that guest register
state may also be also encrypted, so existing approaches like reading
vCPU register values to get these addresses would need to take this
into consideration.

One way to address both of these in a (hopefully) robust way is to
introduce a new set of ucall interfaces that rely on tests setting up
shared guest memory in advance so that these ucall struct addresses are
communicated between host/guest in advance, along with any work needed
to ensure the memory is shared/public. With that in place, a ucall
implementation only needs to trigger an exit back to host userspace to
allow for host/guest communication via this shared memory / ucall
struct.

Implement this approach by extending ucall_ops to allow for ucall
implementations based on shared memory, and introducing
ucall_shared()/get_ucall_shared() analogs to the existing
ucall()/get_ucall() interfaces.

Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 .../selftests/kvm/include/ucall_common.h      |  5 +++
 .../testing/selftests/kvm/lib/ucall_common.c  | 38 +++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/ucall_common.h b/tools/testing/selftests/kvm/include/ucall_common.h
index fcd32607dcff..ae0e8eec9734 100644
--- a/tools/testing/selftests/kvm/include/ucall_common.h
+++ b/tools/testing/selftests/kvm/include/ucall_common.h
@@ -34,6 +34,8 @@ struct ucall_ops {
 	void (*uninit)(struct kvm_vm *vm);
 	void (*send_cmd)(struct ucall *uc);
 	uint64_t (*recv_cmd)(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);
+	void (*send_cmd_shared)(struct ucall *uc);
+	uint64_t (*recv_cmd_shared)(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);
 };
 
 void ucall_init(struct kvm_vm *vm, void *arg);
@@ -42,6 +44,9 @@ void ucall_init_ops(struct kvm_vm *vm, void *arg, const struct ucall_ops *ops);
 void ucall_uninit_ops(struct kvm_vm *vm);
 void ucall(uint64_t cmd, int nargs, ...);
 uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);
+vm_vaddr_t ucall_shared_alloc(struct kvm_vm *vm, int count);
+void ucall_shared(struct ucall *uc, uint64_t cmd, int nargs, ...);
+uint64_t get_ucall_shared(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);
 
 #define GUEST_SYNC_ARGS(stage, arg1, arg2, arg3, arg4)	\
 				ucall(UCALL_SYNC, 6, "hello", stage, arg1, arg2, arg3, arg4)
diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
index db0129edcbc1..8e5738241a7c 100644
--- a/tools/testing/selftests/kvm/lib/ucall_common.c
+++ b/tools/testing/selftests/kvm/lib/ucall_common.c
@@ -93,3 +93,41 @@ uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc)
 
 	return ucall_ops->recv_cmd(vm, vcpu_id, uc);
 }
+
+/* Allocate shared memory within a guest to for a shared ucall buffer. */
+vm_vaddr_t ucall_shared_alloc(struct kvm_vm *vm, int count)
+{
+	return vm_vaddr_alloc(vm, count * sizeof(struct ucall),
+			      vm_get_page_size(vm));
+}
+
+/*
+ * Populate a shared ucall buffer previously allocated by ucall_shared_alloc()
+ * and then generate an exit to host userspace.
+ */
+void ucall_shared(struct ucall *uc, uint64_t cmd, int nargs, ...)
+{
+	va_list va;
+
+	if (!ucall_ops->send_cmd_shared)
+		return;
+
+	va_start(va, nargs);
+	ucall_process_args(uc, cmd, nargs, va);
+	va_end(va);
+
+	ucall_ops->send_cmd_shared(uc);
+}
+
+/*
+ * Parse a ucall buffer that has been allocated by ucall_shared_alloc() and
+ * shared with the guest in advance to determine the ucall message/command that
+ * was sent by the guest.
+ */
+uint64_t get_ucall_shared(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc)
+{
+	if (!ucall_ops->recv_cmd_shared)
+		return UCALL_NOT_IMPLEMENTED;
+
+	return ucall_ops->recv_cmd_shared(vm, vcpu_id, uc);
+}
-- 
2.25.1

_______________________________________________
kvmarm mailing list
kvmarm@lists.cs.columbia.edu
https://lists.cs.columbia.edu/mailman/listinfo/kvmarm

WARNING: multiple messages have this Message-ID (diff)
From: Michael Roth <michael.roth@amd.com>
To: <linux-kselftest@vger.kernel.org>
Cc: <kvm@vger.kernel.org>, <linux-kernel@vger.kernel.org>,
	<x86@kernel.org>, Nathan Tempelman <natet@google.com>,
	Marc Orr <marcorr@google.com>,
	"Steve Rutherford" <srutherford@google.com>,
	Sean Christopherson <seanjc@google.com>,
	Mingwei Zhang <mizhang@google.com>,
	Brijesh Singh <brijesh.singh@amd.com>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	Varad Gautam <varad.gautam@suse.com>,
	Shuah Khan <shuah@kernel.org>,
	Vitaly Kuznetsov <vkuznets@redhat.com>,
	"David Woodhouse" <dwmw@amazon.co.uk>,
	Ricardo Koller <ricarkol@google.com>,
	"Jim Mattson" <jmattson@google.com>,
	Joerg Roedel <joro@8bytes.org>,
	"Thomas Gleixner" <tglx@linutronix.de>,
	Ingo Molnar <mingo@redhat.com>, "Borislav Petkov" <bp@alien8.de>,
	"H . Peter Anvin" <hpa@zytor.com>,
	"Christian Borntraeger" <borntraeger@linux.ibm.com>,
	Janosch Frank <frankja@linux.ibm.com>,
	David Hildenbrand <david@redhat.com>,
	"Claudio Imbrenda" <imbrenda@linux.ibm.com>,
	Marc Zyngier <maz@kernel.org>, James Morse <james.morse@arm.com>,
	Alexandru Elisei <alexandru.elisei@arm.com>,
	"Suzuki K Poulose" <suzuki.poulose@arm.com>,
	<kvmarm@lists.cs.columbia.edu>
Subject: [PATCH RFC 06/10] kvm: selftests: add ucall interfaces based around shared memory
Date: Fri, 10 Dec 2021 10:46:16 -0600	[thread overview]
Message-ID: <20211210164620.11636-7-michael.roth@amd.com> (raw)
In-Reply-To: <20211210164620.11636-1-michael.roth@amd.com>

One complication with SEV and likely other Confidential Computing
implementations is the fact that guest stacks might be encrypted, so
existing interfaces like ucall()/get_ucall() will not work as-is since
they allocate ucall structs on the guest stack dynamically.
Additionally, the basic task of communicating the location in guest
memory of these structs is complicated by the fact that guest register
state may also be also encrypted, so existing approaches like reading
vCPU register values to get these addresses would need to take this
into consideration.

One way to address both of these in a (hopefully) robust way is to
introduce a new set of ucall interfaces that rely on tests setting up
shared guest memory in advance so that these ucall struct addresses are
communicated between host/guest in advance, along with any work needed
to ensure the memory is shared/public. With that in place, a ucall
implementation only needs to trigger an exit back to host userspace to
allow for host/guest communication via this shared memory / ucall
struct.

Implement this approach by extending ucall_ops to allow for ucall
implementations based on shared memory, and introducing
ucall_shared()/get_ucall_shared() analogs to the existing
ucall()/get_ucall() interfaces.

Signed-off-by: Michael Roth <michael.roth@amd.com>
---
 .../selftests/kvm/include/ucall_common.h      |  5 +++
 .../testing/selftests/kvm/lib/ucall_common.c  | 38 +++++++++++++++++++
 2 files changed, 43 insertions(+)

diff --git a/tools/testing/selftests/kvm/include/ucall_common.h b/tools/testing/selftests/kvm/include/ucall_common.h
index fcd32607dcff..ae0e8eec9734 100644
--- a/tools/testing/selftests/kvm/include/ucall_common.h
+++ b/tools/testing/selftests/kvm/include/ucall_common.h
@@ -34,6 +34,8 @@ struct ucall_ops {
 	void (*uninit)(struct kvm_vm *vm);
 	void (*send_cmd)(struct ucall *uc);
 	uint64_t (*recv_cmd)(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);
+	void (*send_cmd_shared)(struct ucall *uc);
+	uint64_t (*recv_cmd_shared)(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);
 };
 
 void ucall_init(struct kvm_vm *vm, void *arg);
@@ -42,6 +44,9 @@ void ucall_init_ops(struct kvm_vm *vm, void *arg, const struct ucall_ops *ops);
 void ucall_uninit_ops(struct kvm_vm *vm);
 void ucall(uint64_t cmd, int nargs, ...);
 uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);
+vm_vaddr_t ucall_shared_alloc(struct kvm_vm *vm, int count);
+void ucall_shared(struct ucall *uc, uint64_t cmd, int nargs, ...);
+uint64_t get_ucall_shared(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc);
 
 #define GUEST_SYNC_ARGS(stage, arg1, arg2, arg3, arg4)	\
 				ucall(UCALL_SYNC, 6, "hello", stage, arg1, arg2, arg3, arg4)
diff --git a/tools/testing/selftests/kvm/lib/ucall_common.c b/tools/testing/selftests/kvm/lib/ucall_common.c
index db0129edcbc1..8e5738241a7c 100644
--- a/tools/testing/selftests/kvm/lib/ucall_common.c
+++ b/tools/testing/selftests/kvm/lib/ucall_common.c
@@ -93,3 +93,41 @@ uint64_t get_ucall(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc)
 
 	return ucall_ops->recv_cmd(vm, vcpu_id, uc);
 }
+
+/* Allocate shared memory within a guest to for a shared ucall buffer. */
+vm_vaddr_t ucall_shared_alloc(struct kvm_vm *vm, int count)
+{
+	return vm_vaddr_alloc(vm, count * sizeof(struct ucall),
+			      vm_get_page_size(vm));
+}
+
+/*
+ * Populate a shared ucall buffer previously allocated by ucall_shared_alloc()
+ * and then generate an exit to host userspace.
+ */
+void ucall_shared(struct ucall *uc, uint64_t cmd, int nargs, ...)
+{
+	va_list va;
+
+	if (!ucall_ops->send_cmd_shared)
+		return;
+
+	va_start(va, nargs);
+	ucall_process_args(uc, cmd, nargs, va);
+	va_end(va);
+
+	ucall_ops->send_cmd_shared(uc);
+}
+
+/*
+ * Parse a ucall buffer that has been allocated by ucall_shared_alloc() and
+ * shared with the guest in advance to determine the ucall message/command that
+ * was sent by the guest.
+ */
+uint64_t get_ucall_shared(struct kvm_vm *vm, uint32_t vcpu_id, struct ucall *uc)
+{
+	if (!ucall_ops->recv_cmd_shared)
+		return UCALL_NOT_IMPLEMENTED;
+
+	return ucall_ops->recv_cmd_shared(vm, vcpu_id, uc);
+}
-- 
2.25.1


  parent reply	other threads:[~2021-12-10 17:36 UTC|newest]

Thread overview: 46+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-12-10 16:46 [RFC PATCH 00/10] KVM: selftests: Add support for test-selectable ucall implementations Michael Roth
2021-12-10 16:46 ` Michael Roth
2021-12-10 16:46 ` [PATCH RFC 01/10] kvm: selftests: move base kvm_util.h declarations to kvm_util_base.h Michael Roth
2021-12-10 16:46   ` Michael Roth
2021-12-10 16:46 ` [PATCH RFC 02/10] kvm: selftests: move ucall declarations into ucall_common.h Michael Roth
2021-12-10 16:46   ` Michael Roth
2021-12-25  9:11   ` Andrew Jones
2021-12-25  9:11     ` Andrew Jones
2021-12-10 16:46 ` [PATCH RFC 03/10] kvm: selftests: introduce ucall_ops for test/arch-specific ucall implementations Michael Roth
2021-12-10 16:46   ` Michael Roth
2021-12-10 16:46 ` [PATCH RFC 04/10] kvm: arm64: selftests: use ucall_ops to define default ucall implementation Michael Roth
2021-12-10 16:46   ` Michael Roth
2021-12-10 16:46 ` [PATCH RFC 05/10] kvm: s390: " Michael Roth
2021-12-10 16:46   ` Michael Roth
2021-12-10 16:46 ` Michael Roth [this message]
2021-12-10 16:46   ` [PATCH RFC 06/10] kvm: selftests: add ucall interfaces based around shared memory Michael Roth
2021-12-10 16:46 ` [PATCH RFC 07/10] kvm: selftests: add ucall_shared ops for PIO Michael Roth
2021-12-10 16:46   ` Michael Roth
2021-12-10 16:46 ` [PATCH RFC 08/10] kvm: selftests: introduce ucall implementation based on halt instructions Michael Roth
2021-12-10 16:46   ` Michael Roth
2021-12-10 16:46 ` [PATCH RFC 09/10] kvm: selftests: add GUEST_SHARED_* macros for shared ucall implementations Michael Roth
2021-12-10 16:46   ` Michael Roth
2021-12-10 16:46 ` [PATCH RFC 10/10] kvm: selftests: add ucall_test to test various ucall functionality Michael Roth
2021-12-10 16:46   ` Michael Roth
2021-12-22 14:46 ` [RFC PATCH 00/10] KVM: selftests: Add support for test-selectable ucall implementations Paolo Bonzini
2021-12-22 14:46   ` Paolo Bonzini
2021-12-30 21:11 ` Sean Christopherson
2021-12-30 21:11   ` Sean Christopherson
2022-01-04 23:35   ` Michael Roth
2022-01-04 23:35     ` Michael Roth
2022-01-05  0:17     ` Sean Christopherson
2022-01-05  0:17       ` Sean Christopherson
2022-01-05 17:02       ` Michael Roth
2022-01-05 17:02         ` Michael Roth
2022-01-05 17:43         ` Sean Christopherson
2022-01-05 17:43           ` Sean Christopherson
2022-01-05 19:11           ` Michael Roth
2022-01-05 19:11             ` Michael Roth
2022-01-05 19:40             ` Sean Christopherson
2022-01-05 19:40               ` Sean Christopherson
2022-01-05 21:35               ` Michael Roth
2022-01-05 21:35                 ` Michael Roth
2022-01-05 22:02                 ` Sean Christopherson
2022-01-05 22:02                   ` Sean Christopherson
2022-01-05 22:32                   ` Michael Roth
2022-01-05 22:32                     ` Michael Roth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20211210164620.11636-7-michael.roth@amd.com \
    --to=michael.roth@amd.com \
    --cc=borntraeger@linux.ibm.com \
    --cc=bp@alien8.de \
    --cc=brijesh.singh@amd.com \
    --cc=david@redhat.com \
    --cc=dwmw@amazon.co.uk \
    --cc=frankja@linux.ibm.com \
    --cc=hpa@zytor.com \
    --cc=imbrenda@linux.ibm.com \
    --cc=jmattson@google.com \
    --cc=joro@8bytes.org \
    --cc=kvm@vger.kernel.org \
    --cc=kvmarm@lists.cs.columbia.edu \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=marcorr@google.com \
    --cc=maz@kernel.org \
    --cc=mingo@redhat.com \
    --cc=mizhang@google.com \
    --cc=natet@google.com \
    --cc=shuah@kernel.org \
    --cc=srutherford@google.com \
    --cc=tglx@linutronix.de \
    --cc=thomas.lendacky@amd.com \
    --cc=varad.gautam@suse.com \
    --cc=vkuznets@redhat.com \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.