All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ackerley Tng <ackerleytng@google.com>
To: linux-kselftest@vger.kernel.org
Cc: pbonzini@redhat.com, seanjc@google.com, isaku.yamahata@intel.com,
	sagis@google.com, erdemaktas@google.com, afranji@google.com,
	runanwang@google.com, shuah@kernel.org, drjones@redhat.com,
	maz@kernel.org, bgardon@google.com, jmattson@google.com,
	dmatlack@google.com, peterx@redhat.com, oupton@google.com,
	ricarkol@google.com, yang.zhong@intel.com, wei.w.wang@intel.com,
	xiaoyao.li@intel.com, pgonda@google.com, marcorr@google.com,
	eesposit@redhat.com, borntraeger@de.ibm.com,
	eric.auger@redhat.com, wangyanan55@huawei.com,
	aaronlewis@google.com, vkuznets@redhat.com, pshier@google.com,
	axelrasmussen@google.com, zhenzhong.duan@intel.com,
	maciej.szmigiero@oracle.com, like.xu@linux.intel.com,
	linux-kernel@vger.kernel.org, kvm@vger.kernel.org,
	Ackerley Tng <ackerleytng@google.com>
Subject: [RFC PATCH v3 24/31] KVM: selftests: TDX: Add shared memory test
Date: Sat, 21 Jan 2023 00:15:35 +0000	[thread overview]
Message-ID: <20230121001542.2472357-25-ackerleytng@google.com> (raw)
In-Reply-To: <20230121001542.2472357-1-ackerleytng@google.com>

From: Ryan Afranji <afranji@google.com>

Adds a test that sets up shared memory between the host and guest.

Signed-off-by: Ryan Afranji <afranji@google.com>
Signed-off-by: Sagi Shahar <sagis@google.com>
Signed-off-by: Ackerley Tng <ackerleytng@google.com>
---
 tools/testing/selftests/kvm/.gitignore        |   1 +
 tools/testing/selftests/kvm/Makefile          |   1 +
 .../selftests/kvm/include/x86_64/tdx/tdx.h    |   2 +
 .../kvm/include/x86_64/tdx/tdx_util.h         |   3 +
 .../selftests/kvm/lib/x86_64/tdx/tdx.c        |  16 ++
 .../selftests/kvm/lib/x86_64/tdx/tdx_util.c   |  30 ++++
 .../kvm/x86_64/tdx_shared_mem_test.c          | 137 ++++++++++++++++++
 7 files changed, 190 insertions(+)
 create mode 100644 tools/testing/selftests/kvm/x86_64/tdx_shared_mem_test.c

diff --git a/tools/testing/selftests/kvm/.gitignore b/tools/testing/selftests/kvm/.gitignore
index 370d6430b32b4..e1663b0f809b4 100644
--- a/tools/testing/selftests/kvm/.gitignore
+++ b/tools/testing/selftests/kvm/.gitignore
@@ -66,6 +66,7 @@
 /x86_64/vmx_pmu_caps_test
 /x86_64/triple_fault_event_test
 /x86_64/tdx_vm_tests
+/x86_64/tdx_shared_mem_test
 /access_tracking_perf_test
 /demand_paging_test
 /dirty_log_test
diff --git a/tools/testing/selftests/kvm/Makefile b/tools/testing/selftests/kvm/Makefile
index 9f289322a4933..27e9148212fa5 100644
--- a/tools/testing/selftests/kvm/Makefile
+++ b/tools/testing/selftests/kvm/Makefile
@@ -152,6 +152,7 @@ TEST_GEN_PROGS_x86_64 += steal_time
 TEST_GEN_PROGS_x86_64 += kvm_binary_stats_test
 TEST_GEN_PROGS_x86_64 += system_counter_offset_test
 TEST_GEN_PROGS_x86_64 += x86_64/tdx_vm_tests
+TEST_GEN_PROGS_x86_64 += x86_64/tdx_shared_mem_test
 
 # Compiled outputs used by test targets
 TEST_GEN_PROGS_EXTENDED_x86_64 += x86_64/nx_huge_pages_test
diff --git a/tools/testing/selftests/kvm/include/x86_64/tdx/tdx.h b/tools/testing/selftests/kvm/include/x86_64/tdx/tdx.h
index ffab2c3ca312b..857a297e51ac6 100644
--- a/tools/testing/selftests/kvm/include/x86_64/tdx/tdx.h
+++ b/tools/testing/selftests/kvm/include/x86_64/tdx/tdx.h
@@ -7,6 +7,7 @@
 #define TDG_VP_INFO 1
 
 #define TDG_VP_VMCALL_GET_TD_VM_CALL_INFO 0x10000
+#define TDG_VP_VMCALL_MAP_GPA 0x10001
 #define TDG_VP_VMCALL_REPORT_FATAL_ERROR 0x10003
 
 #define TDG_VP_VMCALL_INSTRUCTION_CPUID 10
@@ -36,5 +37,6 @@ uint64_t tdg_vp_vmcall_instruction_cpuid(uint32_t eax, uint32_t ecx,
 uint64_t tdg_vp_info(uint64_t *rcx, uint64_t *rdx,
 		uint64_t *r8, uint64_t *r9,
 		uint64_t *r10, uint64_t *r11);
+uint64_t tdg_vp_vmcall_map_gpa(uint64_t address, uint64_t size, uint64_t *data_out);
 
 #endif // SELFTEST_TDX_TDX_H
diff --git a/tools/testing/selftests/kvm/include/x86_64/tdx/tdx_util.h b/tools/testing/selftests/kvm/include/x86_64/tdx/tdx_util.h
index 274b245f200bf..58374453b4b7e 100644
--- a/tools/testing/selftests/kvm/include/x86_64/tdx/tdx_util.h
+++ b/tools/testing/selftests/kvm/include/x86_64/tdx/tdx_util.h
@@ -13,4 +13,7 @@ void td_initialize(struct kvm_vm *vm, enum vm_mem_backing_src_type src_type,
 		   uint64_t attributes);
 void td_finalize(struct kvm_vm *vm);
 
+void handle_memory_conversion(struct kvm_vm *vm, uint64_t gpa, uint64_t size,
+			bool shared_to_private);
+
 #endif // SELFTESTS_TDX_KVM_UTIL_H
diff --git a/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx.c b/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx.c
index a280136634d3b..e0a39f29a0662 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx.c
@@ -189,3 +189,19 @@ uint64_t tdg_vp_info(uint64_t *rcx, uint64_t *rdx,
 
 	return ret;
 }
+
+uint64_t tdg_vp_vmcall_map_gpa(uint64_t address, uint64_t size, uint64_t *data_out)
+{
+	uint64_t ret;
+	struct tdx_hypercall_args args = {
+		.r11 = TDG_VP_VMCALL_MAP_GPA,
+		.r12 = address,
+		.r13 = size
+	};
+
+	ret = __tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT);
+
+	if (data_out)
+		*data_out = args.r11;
+	return ret;
+}
diff --git a/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx_util.c b/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx_util.c
index 2e9679d24a843..4d6615b97770a 100644
--- a/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx_util.c
+++ b/tools/testing/selftests/kvm/lib/x86_64/tdx/tdx_util.c
@@ -505,3 +505,33 @@ void td_finalize(struct kvm_vm *vm)
 
 	tdx_td_finalizemr(vm);
 }
+
+/**
+ * Handle conversion of memory with @size beginning @gpa for @vm. Set
+ * @shared_to_private to true for shared to private conversions and false
+ * otherwise.
+ *
+ * Since this is just for selftests, we will just keep both pieces of backing
+ * memory allocated and not deallocate/allocate memory; we'll just do the
+ * minimum of calling KVM_MEMORY_ENCRYPT_REG_REGION and
+ * KVM_MEMORY_ENCRYPT_UNREG_REGION.
+ */
+void handle_memory_conversion(struct kvm_vm *vm, uint64_t gpa, uint64_t size,
+			bool shared_to_private)
+{
+	struct kvm_enc_region range;
+	char *ioctl_string = shared_to_private
+		? "KVM_MEMORY_ENCRYPT_REG_REGION"
+		: "KVM_MEMORY_ENCRYPT_UNREG_REGION";
+
+	range.addr = gpa;
+	range.size = size;
+
+	printf("\t ... calling %s ioctl with gpa=%#lx, size=%#lx\n",
+		ioctl_string, gpa, size);
+
+	if (shared_to_private)
+		vm_ioctl(vm, KVM_MEMORY_ENCRYPT_REG_REGION, &range);
+	else
+		vm_ioctl(vm, KVM_MEMORY_ENCRYPT_UNREG_REGION, &range);
+}
diff --git a/tools/testing/selftests/kvm/x86_64/tdx_shared_mem_test.c b/tools/testing/selftests/kvm/x86_64/tdx_shared_mem_test.c
new file mode 100644
index 0000000000000..eb4cf64ae83a8
--- /dev/null
+++ b/tools/testing/selftests/kvm/x86_64/tdx_shared_mem_test.c
@@ -0,0 +1,137 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include <linux/kvm.h>
+#include <stdint.h>
+
+#include "kvm_util_base.h"
+#include "processor.h"
+#include "tdx/tdcall.h"
+#include "tdx/tdx.h"
+#include "tdx/tdx_util.h"
+#include "tdx/test_util.h"
+#include "test_util.h"
+
+#define TDX_SHARED_MEM_TEST_PRIVATE_GVA (0x80000000)
+#define TDX_SHARED_MEM_TEST_VADDR_SHARED_MASK BIT_ULL(30)
+#define TDX_SHARED_MEM_TEST_SHARED_GVA     \
+	(TDX_SHARED_MEM_TEST_PRIVATE_GVA | \
+	 TDX_SHARED_MEM_TEST_VADDR_SHARED_MASK)
+
+#define TDX_SHARED_MEM_TEST_GUEST_WRITE_VALUE (0xcafecafe)
+#define TDX_SHARED_MEM_TEST_HOST_WRITE_VALUE (0xabcdabcd)
+
+#define TDX_SHARED_MEM_TEST_INFO_PORT 0x87
+
+/*
+ * Shared variables between guest and host
+ */
+static uint64_t test_mem_private_gpa;
+static uint64_t test_mem_shared_gpa;
+
+void guest_shared_mem(void)
+{
+	uint32_t *test_mem_shared_gva =
+		(uint32_t *)TDX_SHARED_MEM_TEST_SHARED_GVA;
+
+	uint64_t placeholder;
+	uint64_t ret;
+
+	/* Map gpa as shared */
+	ret = tdg_vp_vmcall_map_gpa(test_mem_shared_gpa, PAGE_SIZE,
+				    &placeholder);
+	if (ret)
+		tdx_test_fatal_with_data(ret, __LINE__);
+
+	*test_mem_shared_gva = TDX_SHARED_MEM_TEST_GUEST_WRITE_VALUE;
+
+	/* Exit so host can read shared value */
+	ret = tdg_vp_vmcall_instruction_io(TDX_SHARED_MEM_TEST_INFO_PORT, 4,
+					   TDG_VP_VMCALL_INSTRUCTION_IO_WRITE,
+					   &placeholder);
+	if (ret)
+		tdx_test_fatal_with_data(ret, __LINE__);
+
+	/* Read value written by host and send it back out for verification */
+	ret = tdg_vp_vmcall_instruction_io(TDX_SHARED_MEM_TEST_INFO_PORT, 4,
+					   TDG_VP_VMCALL_INSTRUCTION_IO_WRITE,
+					   (uint64_t *)test_mem_shared_gva);
+	if (ret)
+		tdx_test_fatal_with_data(ret, __LINE__);
+}
+
+int verify_shared_mem(void)
+{
+	struct kvm_vm *vm;
+	struct kvm_vcpu *vcpu;
+
+	vm_vaddr_t test_mem_private_gva;
+	uint32_t *test_mem_hva;
+
+	vm = td_create();
+	td_initialize(vm, VM_MEM_SRC_ANONYMOUS, 0);
+	vcpu = td_vcpu_add(vm, 0, guest_shared_mem);
+
+	/*
+	 * Set up shared memory page for testing by first allocating as private
+	 * and then mapping the same GPA again as shared. This way, the TD does
+	 * not have to remap its page tables at runtime.
+	 */
+	test_mem_private_gva = vm_vaddr_alloc(vm, vm->page_size,
+					      TDX_SHARED_MEM_TEST_PRIVATE_GVA);
+	ASSERT_EQ(test_mem_private_gva, TDX_SHARED_MEM_TEST_PRIVATE_GVA);
+
+	test_mem_hva = addr_gva2hva(vm, test_mem_private_gva);
+	TEST_ASSERT(test_mem_hva != NULL,
+		    "Guest address not found in guest memory regions\n");
+
+	test_mem_private_gpa = addr_gva2gpa(vm, test_mem_private_gva);
+	virt_pg_map_shared(vm, TDX_SHARED_MEM_TEST_SHARED_GVA,
+			   test_mem_private_gpa);
+
+	test_mem_shared_gpa = test_mem_private_gpa | BIT_ULL(vm->pa_bits - 1);
+	sync_global_to_guest(vm, test_mem_private_gpa);
+	sync_global_to_guest(vm, test_mem_shared_gpa);
+
+	td_finalize(vm);
+
+	printf("Verifying shared memory accesses for TDX\n");
+
+	/* Begin guest execution; guest writes to shared memory. */
+	printf("\t ... Starting guest execution\n");
+
+	/* Handle map gpa as shared */
+	/* TODO: MapGPA should exit to the host VMM, but now it doesn't */
+	// vcpu_run(vcpu);
+	// ASSERT_EQ(vcpu->run->exit_reason, KVM_EXIT_MEMORY_FAULT);
+	// handle_memory_conversion(vm, vcpu->run->memory.gpa, vcpu->run->memory.size,
+	//                          vcpu->run->memory.flags == KVM_MEMORY_EXIT_FLAG_PRIVATE);
+
+	vcpu_run(vcpu);
+	TDX_TEST_ASSERT_IO(vcpu, TDX_SHARED_MEM_TEST_INFO_PORT, 4,
+			   TDG_VP_VMCALL_INSTRUCTION_IO_WRITE);
+	ASSERT_EQ(*test_mem_hva, TDX_SHARED_MEM_TEST_GUEST_WRITE_VALUE);
+
+	*test_mem_hva = TDX_SHARED_MEM_TEST_HOST_WRITE_VALUE;
+	vcpu_run(vcpu);
+	TDX_TEST_ASSERT_IO(vcpu, TDX_SHARED_MEM_TEST_INFO_PORT, 4,
+			   TDG_VP_VMCALL_INSTRUCTION_IO_WRITE);
+	ASSERT_EQ(*(uint32_t *)((void *)vcpu->run + vcpu->run->io.data_offset),
+		  TDX_SHARED_MEM_TEST_HOST_WRITE_VALUE);
+
+	printf("\t ... PASSED\n");
+
+	kvm_vm_free(vm);
+
+	return 0;
+}
+
+int main(int argc, char **argv)
+{
+	if (!is_tdx_enabled()) {
+		printf("TDX is not supported by the KVM\n"
+		       "Skipping the TDX tests.\n");
+		return 0;
+	}
+
+	return verify_shared_mem();
+}
-- 
2.39.0.246.g2a6d74b583-goog


  parent reply	other threads:[~2023-01-21  0:19 UTC|newest]

Thread overview: 43+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-01-21  0:15 [RFC PATCH v3 00/31] TDX KVM selftests Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 01/31] KVM: selftests: Add function to allow one-to-one GVA to GPA mappings Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 02/31] KVM: selftests: Add support for creating non-default type VMs Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 03/31] KVM: selftests: Expose function that sets up sregs based on VM's mode Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 04/31] KVM: selftests: Store initial stack address in struct kvm_vcpu Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 05/31] KVM: selftests: Refactor steps in vCPU descriptor table initialization Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 06/31] KVM: selftests: Add helper functions to create TDX VMs Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 07/31] KVM: selftests: TDX: Use KVM_TDX_CAPABILITIES to validate TDs' attribute configuration Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 08/31] KVM: selftests: Require GCC to realign stacks on function entry Ackerley Tng
2023-01-21  0:27   ` Sean Christopherson
2023-01-23 18:30     ` Erdem Aktas
2023-01-23 18:50       ` Maciej S. Szmigiero
2023-01-23 18:53         ` Sean Christopherson
2023-01-24  0:04           ` Erdem Aktas
2023-01-24  1:21             ` Sean Christopherson
2023-02-15  0:50               ` Ackerley Tng
2023-02-15 18:44                 ` Maciej S. Szmigiero
2023-02-15 22:19                   ` Sean Christopherson
2023-02-15 22:24                 ` Sean Christopherson
2023-02-17 18:57                   ` Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 09/31] KVM: selftests: TDX: Add TDX lifecycle test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 10/31] KVM: selftests: TDX: Add report_fatal_error test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 11/31] KVM: selftests: TDX: Adding test case for TDX port IO Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 12/31] KVM: selftests: TDX: Add basic TDX CPUID test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 13/31] KVM: selftests: TDX: Add basic get_td_vmcall_info test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 14/31] KVM: selftests: TDX: Add TDX IO writes test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 15/31] KVM: selftests: TDX: Add TDX IO reads test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 16/31] KVM: selftests: TDX: Add TDX MSR read/write tests Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 17/31] KVM: selftests: TDX: Add TDX HLT exit test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 18/31] KVM: selftests: TDX: Add TDX MMIO reads test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 19/31] KVM: selftests: TDX: Add TDX MMIO writes test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 20/31] KVM: selftests: TDX: Add TDX CPUID TDVMCALL test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 21/31] KVM: selftests: TDX: Verify the behavior when host consumes a TD private memory Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 22/31] KVM: selftests: TDX: Add TDG.VP.INFO test Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 23/31] KVM: selftests: Add functions to allow mapping as shared Ackerley Tng
2023-01-21  0:15 ` Ackerley Tng [this message]
2023-01-21  0:15 ` [RFC PATCH v3 25/31] KVM: selftests: Add support for restricted memory Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 26/31] KVM: selftests: TDX: Update load_td_memory_region for VM memory backed by restricted memfd Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 27/31] KVM: selftests: Expose _vm_vaddr_alloc Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 28/31] KVM: selftests: TDX: Add support for TDG.MEM.PAGE.ACCEPT Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 29/31] KVM: selftests: TDX: Add support for TDG.VP.VEINFO.GET Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 30/31] KVM: selftests: TDX: Add TDX UPM selftest Ackerley Tng
2023-01-21  0:15 ` [RFC PATCH v3 31/31] KVM: selftests: TDX: Add TDX UPM selftests for implicit conversion Ackerley Tng

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=20230121001542.2472357-25-ackerleytng@google.com \
    --to=ackerleytng@google.com \
    --cc=aaronlewis@google.com \
    --cc=afranji@google.com \
    --cc=axelrasmussen@google.com \
    --cc=bgardon@google.com \
    --cc=borntraeger@de.ibm.com \
    --cc=dmatlack@google.com \
    --cc=drjones@redhat.com \
    --cc=eesposit@redhat.com \
    --cc=erdemaktas@google.com \
    --cc=eric.auger@redhat.com \
    --cc=isaku.yamahata@intel.com \
    --cc=jmattson@google.com \
    --cc=kvm@vger.kernel.org \
    --cc=like.xu@linux.intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=maciej.szmigiero@oracle.com \
    --cc=marcorr@google.com \
    --cc=maz@kernel.org \
    --cc=oupton@google.com \
    --cc=pbonzini@redhat.com \
    --cc=peterx@redhat.com \
    --cc=pgonda@google.com \
    --cc=pshier@google.com \
    --cc=ricarkol@google.com \
    --cc=runanwang@google.com \
    --cc=sagis@google.com \
    --cc=seanjc@google.com \
    --cc=shuah@kernel.org \
    --cc=vkuznets@redhat.com \
    --cc=wangyanan55@huawei.com \
    --cc=wei.w.wang@intel.com \
    --cc=xiaoyao.li@intel.com \
    --cc=yang.zhong@intel.com \
    --cc=zhenzhong.duan@intel.com \
    /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.