All of lore.kernel.org
 help / color / mirror / Atom feed
From: Sagi Shahar <sagis@google.com>
To: linux-kselftest@vger.kernel.org,
	Paolo Bonzini <pbonzini@redhat.com>,
	 Shuah Khan <shuah@kernel.org>,
	Sean Christopherson <seanjc@google.com>,
	 Ackerley Tng <ackerleytng@google.com>,
	Ryan Afranji <afranji@google.com>,
	 Andrew Jones <ajones@ventanamicro.com>,
	Isaku Yamahata <isaku.yamahata@intel.com>,
	 Erdem Aktas <erdemaktas@google.com>,
	Rick Edgecombe <rick.p.edgecombe@intel.com>,
	 Sagi Shahar <sagis@google.com>,
	Roger Wang <runanwang@google.com>,
	 Binbin Wu <binbin.wu@linux.intel.com>,
	Oliver Upton <oliver.upton@linux.dev>,
	 "Pratik R. Sampat" <pratikrajesh.sampat@amd.com>,
	Reinette Chatre <reinette.chatre@intel.com>,
	 Ira Weiny <ira.weiny@intel.com>
Cc: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Subject: [PATCH v8 18/30] KVM: selftests: TDX: Add TDX MMIO reads test
Date: Thu,  7 Aug 2025 13:16:14 -0700	[thread overview]
Message-ID: <20250807201628.1185915-19-sagis@google.com> (raw)
In-Reply-To: <20250807201628.1185915-1-sagis@google.com>

The test verifies MMIO reads of various sizes from the host to the guest.

Co-developed-by: Isaku Yamahata <isaku.yamahata@intel.com>
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
Signed-off-by: Sagi Shahar <sagis@google.com>
---
 .../selftests/kvm/include/x86/tdx/tdx.h       |  4 +
 .../selftests/kvm/include/x86/tdx/tdx_util.h  |  1 +
 .../selftests/kvm/include/x86/tdx/test_util.h | 11 +++
 tools/testing/selftests/kvm/lib/x86/tdx/tdx.c | 20 +++++
 .../selftests/kvm/lib/x86/tdx/test_util.c     | 19 ++++
 tools/testing/selftests/kvm/x86/tdx_vm_test.c | 89 ++++++++++++++++++-
 6 files changed, 143 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/kvm/include/x86/tdx/tdx.h b/tools/testing/selftests/kvm/include/x86/tdx/tdx.h
index b5831919a215..fa0b24873a8f 100644
--- a/tools/testing/selftests/kvm/include/x86/tdx/tdx.h
+++ b/tools/testing/selftests/kvm/include/x86/tdx/tdx.h
@@ -13,6 +13,7 @@
 #define TDG_VP_VMCALL_INSTRUCTION_IO 30
 #define TDG_VP_VMCALL_INSTRUCTION_RDMSR 31
 #define TDG_VP_VMCALL_INSTRUCTION_WRMSR 32
+#define TDG_VP_VMCALL_VE_REQUEST_MMIO 48
 
 uint64_t tdg_vp_vmcall_instruction_io(uint64_t port, uint64_t size,
 				      uint64_t write, uint64_t *data);
@@ -22,4 +23,7 @@ uint64_t tdg_vp_vmcall_get_td_vmcall_info(uint64_t *r11, uint64_t *r12,
 uint64_t tdg_vp_vmcall_instruction_rdmsr(uint64_t index, uint64_t *ret_value);
 uint64_t tdg_vp_vmcall_instruction_wrmsr(uint64_t index, uint64_t value);
 uint64_t tdg_vp_vmcall_instruction_hlt(uint64_t interrupt_blocked_flag);
+uint64_t tdg_vp_vmcall_ve_request_mmio_read(uint64_t address, uint64_t size,
+					    uint64_t *data_out);
+
 #endif // SELFTEST_TDX_TDX_H
diff --git a/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h b/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
index d66cf17f03ea..c942aec7ad26 100644
--- a/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
+++ b/tools/testing/selftests/kvm/include/x86/tdx/tdx_util.h
@@ -6,6 +6,7 @@
 
 #include "kvm_util.h"
 
+extern uint64_t tdx_s_bit;
 void tdx_filter_cpuid(struct kvm_vm *vm, struct kvm_cpuid2 *cpuid_data);
 void __tdx_mask_cpuid_features(struct kvm_cpuid_entry2 *entry);
 
diff --git a/tools/testing/selftests/kvm/include/x86/tdx/test_util.h b/tools/testing/selftests/kvm/include/x86/tdx/test_util.h
index 91031e956462..3330d5a54698 100644
--- a/tools/testing/selftests/kvm/include/x86/tdx/test_util.h
+++ b/tools/testing/selftests/kvm/include/x86/tdx/test_util.h
@@ -17,6 +17,10 @@
 #define PORT_READ	0
 #define PORT_WRITE	1
 
+/* MMIO direction */
+#define MMIO_READ	0
+#define MMIO_WRITE	1
+
 /*
  * Assert that some IO operation involving tdg_vp_vmcall_instruction_io() was
  * called in the guest.
@@ -24,6 +28,13 @@
 void tdx_test_assert_io(struct kvm_vcpu *vcpu, uint16_t port, uint8_t size,
 			uint8_t direction);
 
+/*
+ * Assert that some MMIO operation involving TDG.VP.VMCALL <#VERequestMMIO> was
+ * called in the guest.
+ */
+void tdx_test_assert_mmio(struct kvm_vcpu *vcpu, uint64_t phys_addr,
+			  uint32_t size, uint8_t is_write);
+
 /*
  * Run the tdx vcpu and check if there was some failure in the guest, either
  * an exception like a triple fault, or if a tdx_test_fatal() was hit.
diff --git a/tools/testing/selftests/kvm/lib/x86/tdx/tdx.c b/tools/testing/selftests/kvm/lib/x86/tdx/tdx.c
index e89ca727286e..8bf41e667fc1 100644
--- a/tools/testing/selftests/kvm/lib/x86/tdx/tdx.c
+++ b/tools/testing/selftests/kvm/lib/x86/tdx/tdx.c
@@ -4,6 +4,7 @@
 
 #include "tdx/tdcall.h"
 #include "tdx/tdx.h"
+#include "tdx/test_util.h"
 
 uint64_t tdg_vp_vmcall_instruction_io(uint64_t port, uint64_t size,
 				      uint64_t write, uint64_t *data)
@@ -103,3 +104,22 @@ uint64_t tdg_vp_vmcall_instruction_hlt(uint64_t interrupt_blocked_flag)
 
 	return __tdx_hypercall(&args, 0);
 }
+
+uint64_t tdg_vp_vmcall_ve_request_mmio_read(uint64_t address, uint64_t size,
+					    uint64_t *data_out)
+{
+	struct tdx_hypercall_args args = {
+		.r11 = TDG_VP_VMCALL_VE_REQUEST_MMIO,
+		.r12 = size,
+		.r13 = MMIO_READ,
+		.r14 = address,
+	};
+	uint64_t ret;
+
+	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/tdx/test_util.c b/tools/testing/selftests/kvm/lib/x86/tdx/test_util.c
index 8c3b6802c37e..f92ddda2d1ac 100644
--- a/tools/testing/selftests/kvm/lib/x86/tdx/test_util.c
+++ b/tools/testing/selftests/kvm/lib/x86/tdx/test_util.c
@@ -31,6 +31,25 @@ void tdx_test_assert_io(struct kvm_vcpu *vcpu, uint16_t port, uint8_t size,
 		    vcpu->run->io.direction);
 }
 
+void tdx_test_assert_mmio(struct kvm_vcpu *vcpu, uint64_t phys_addr,
+			  uint32_t size, uint8_t is_write)
+{
+	TEST_ASSERT(vcpu->run->exit_reason == KVM_EXIT_MMIO,
+		    "Got exit_reason other than KVM_EXIT_MMIO: %u (%s)\n",
+		    vcpu->run->exit_reason,
+		    exit_reason_str(vcpu->run->exit_reason));
+
+	TEST_ASSERT(vcpu->run->exit_reason == KVM_EXIT_MMIO &&
+		    vcpu->run->mmio.phys_addr == phys_addr &&
+		    vcpu->run->mmio.len == size &&
+		    vcpu->run->mmio.is_write == is_write,
+		    "Got an unexpected MMIO exit values: %u (%s) %llu %u %u\n",
+		    vcpu->run->exit_reason,
+		    exit_reason_str(vcpu->run->exit_reason),
+		    vcpu->run->mmio.phys_addr, vcpu->run->mmio.len,
+		    vcpu->run->mmio.is_write);
+}
+
 void tdx_run(struct kvm_vcpu *vcpu)
 {
 	td_vcpu_run(vcpu);
diff --git a/tools/testing/selftests/kvm/x86/tdx_vm_test.c b/tools/testing/selftests/kvm/x86/tdx_vm_test.c
index 720ef5e87071..563f1025c8a3 100644
--- a/tools/testing/selftests/kvm/x86/tdx_vm_test.c
+++ b/tools/testing/selftests/kvm/x86/tdx_vm_test.c
@@ -719,6 +719,91 @@ void verify_guest_hlt(void)
 	_verify_guest_hlt(0);
 }
 
+/* Pick any address that was not mapped into the guest to test MMIO */
+#define TDX_MMIO_TEST_ADDR 0x200000000
+#define MMIO_SYNC_VALUE 0x42
+
+void guest_mmio_reads(void)
+{
+	uint64_t mmio_test_addr = TDX_MMIO_TEST_ADDR | tdx_s_bit;
+	uint64_t data;
+	uint64_t ret;
+
+	ret = tdg_vp_vmcall_ve_request_mmio_read(mmio_test_addr, 1, &data);
+	tdx_assert_error(ret);
+	if (data != 0x12)
+		tdx_test_fatal(1);
+
+	ret = tdg_vp_vmcall_ve_request_mmio_read(mmio_test_addr, 2, &data);
+	tdx_assert_error(ret);
+	if (data != 0x1234)
+		tdx_test_fatal(2);
+
+	ret = tdg_vp_vmcall_ve_request_mmio_read(mmio_test_addr, 4, &data);
+	tdx_assert_error(ret);
+	if (data != 0x12345678)
+		tdx_test_fatal(4);
+
+	ret = tdg_vp_vmcall_ve_request_mmio_read(mmio_test_addr, 8, &data);
+	tdx_assert_error(ret);
+	if (data != 0x1234567890ABCDEF)
+		tdx_test_fatal(8);
+
+	/* Make sure host and guest are synced to the same point of execution */
+	tdx_test_report_to_user_space(MMIO_SYNC_VALUE);
+
+	/* Read an invalid number of bytes. */
+	ret = tdg_vp_vmcall_ve_request_mmio_read(mmio_test_addr, 10, &data);
+	tdx_assert_error(ret);
+
+	tdx_test_success();
+}
+
+/*
+ * Verifies guest MMIO reads.
+ */
+void verify_mmio_reads(void)
+{
+	struct kvm_vcpu *vcpu;
+	struct kvm_vm *vm;
+
+	vm = td_create();
+	td_initialize(vm, VM_MEM_SRC_ANONYMOUS, 0);
+	vcpu = td_vcpu_add(vm, 0, guest_mmio_reads);
+	td_finalize(vm);
+
+	printf("Verifying TD MMIO reads:\n");
+
+	tdx_run(vcpu);
+	tdx_test_assert_mmio(vcpu, TDX_MMIO_TEST_ADDR, 1, MMIO_READ);
+	*(uint8_t *)vcpu->run->mmio.data = 0x12;
+
+	tdx_run(vcpu);
+	tdx_test_assert_mmio(vcpu, TDX_MMIO_TEST_ADDR, 2, MMIO_READ);
+	*(uint16_t *)vcpu->run->mmio.data = 0x1234;
+
+	tdx_run(vcpu);
+	tdx_test_assert_mmio(vcpu, TDX_MMIO_TEST_ADDR, 4, MMIO_READ);
+	*(uint32_t *)vcpu->run->mmio.data = 0x12345678;
+
+	tdx_run(vcpu);
+	tdx_test_assert_mmio(vcpu, TDX_MMIO_TEST_ADDR, 8, MMIO_READ);
+	*(uint64_t *)vcpu->run->mmio.data = 0x1234567890ABCDEF;
+
+	tdx_run(vcpu);
+	TEST_ASSERT_EQ(tdx_test_read_report_from_guest(vcpu), MMIO_SYNC_VALUE);
+
+	td_vcpu_run(vcpu);
+	TEST_ASSERT_EQ(vcpu->run->exit_reason, KVM_EXIT_SYSTEM_EVENT);
+	TEST_ASSERT_EQ(vcpu->run->system_event.data[12], TDG_VP_VMCALL_INVALID_OPERAND);
+
+	tdx_run(vcpu);
+	tdx_test_assert_success(vcpu);
+
+	kvm_vm_free(vm);
+	printf("\t ... PASSED\n");
+}
+
 int main(int argc, char **argv)
 {
 	ksft_print_header();
@@ -726,7 +811,7 @@ int main(int argc, char **argv)
 	if (!is_tdx_enabled())
 		ksft_exit_skip("TDX is not supported by the KVM. Exiting.\n");
 
-	ksft_set_plan(10);
+	ksft_set_plan(11);
 	ksft_test_result(!run_in_new_process(&verify_td_lifecycle),
 			 "verify_td_lifecycle\n");
 	ksft_test_result(!run_in_new_process(&verify_report_fatal_error),
@@ -747,6 +832,8 @@ int main(int argc, char **argv)
 			 "verify_guest_msr_reads\n");
 	ksft_test_result(!run_in_new_process(&verify_guest_hlt),
 			 "verify_guest_hlt\n");
+	ksft_test_result(!run_in_new_process(&verify_mmio_reads),
+			 "verify_mmio_reads\n");
 
 	ksft_finished();
 	return 0;
-- 
2.51.0.rc0.155.g4a0f42376b-goog


  parent reply	other threads:[~2025-08-07 20:17 UTC|newest]

Thread overview: 92+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-07 20:15 [PATCH v8 00/30] TDX KVM selftests Sagi Shahar
2025-08-07 20:15 ` [PATCH v8 01/30] KVM: selftests: Add function to allow one-to-one GVA to GPA mappings Sagi Shahar
2025-08-11 17:49   ` Sean Christopherson
2025-08-15  4:16     ` Sagi Shahar
2025-08-07 20:15 ` [PATCH v8 02/30] KVM: selftests: Expose function that sets up sregs based on VM's mode Sagi Shahar
2025-08-11 18:11   ` Sean Christopherson
2025-08-15  4:24     ` Sagi Shahar
2025-08-07 20:15 ` [PATCH v8 03/30] KVM: selftests: Store initial stack address in struct kvm_vcpu Sagi Shahar
2025-08-11 18:12   ` Sean Christopherson
2025-08-07 20:16 ` [PATCH v8 04/30] KVM: selftests: Add vCPU descriptor table initialization utility Sagi Shahar
2025-08-11 18:25   ` Sean Christopherson
2025-08-15  4:29     ` Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 05/30] KVM: selftests: Update kvm_init_vm_address_properties() for TDX Sagi Shahar
2025-08-11 18:34   ` Sean Christopherson
2025-08-15  4:31     ` Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 06/30] KVM: selftests: Add helper functions to create TDX VMs Sagi Shahar
2025-08-11 20:13   ` Sean Christopherson
2025-08-12 21:05     ` Ira Weiny
2025-08-13  4:22     ` Binbin Wu
2025-08-15  5:20       ` Sagi Shahar
2025-08-16  0:22         ` Sean Christopherson
2025-08-16  0:32           ` Reinette Chatre
2025-08-16  0:28         ` Reinette Chatre
2025-08-13  7:41     ` Binbin Wu
2025-08-15  2:20     ` Chao Gao
2025-08-21  4:08     ` Sagi Shahar
2025-08-14  0:48   ` Edgecombe, Rick P
2025-08-21  4:15     ` Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 07/30] KVM: selftests: TDX: Use KVM_TDX_CAPABILITIES to validate TDs' attribute configuration Sagi Shahar
2025-08-13 13:34   ` Chenyi Qiang
2025-08-20 21:18     ` Sagi Shahar
2025-08-20 21:49       ` Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 08/30] KVM: selftests: TDX: Update load_td_memory_region() for VM memory backed by guest memfd Sagi Shahar
2025-08-11 14:19   ` Ira Weiny
2025-08-11 20:31   ` Sean Christopherson
2025-08-13  9:23     ` Binbin Wu
2025-08-13 14:42       ` Reinette Chatre
2025-08-14  2:49         ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 09/30] KVM: selftests: TDX: Add TDX lifecycle test Sagi Shahar
2025-08-13 10:36   ` Binbin Wu
2025-08-21  4:19     ` Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 10/30] KVM: selftests: TDX: Add report_fatal_error test Sagi Shahar
2025-08-13 10:58   ` Binbin Wu
2025-08-14  7:05     ` Binbin Wu
2025-08-25 21:49       ` Sagi Shahar
2025-08-25 21:28     ` Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 11/30] KVM: selftests: TDX: Adding test case for TDX port IO Sagi Shahar
2025-08-14  3:24   ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 12/30] KVM: selftests: TDX: Add basic TDX CPUID test Sagi Shahar
2025-08-14  3:20   ` Chenyi Qiang
2025-08-14  6:11     ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 13/30] KVM: selftests: TDX: Add basic TDG.VP.VMCALL<GetTdVmCallInfo> test Sagi Shahar
2025-08-14  6:34   ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 14/30] KVM: selftests: TDX: Add TDX IO writes test Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 15/30] KVM: selftests: TDX: Add TDX IO reads test Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 16/30] KVM: selftests: TDX: Add TDX MSR read/write tests Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 17/30] KVM: selftests: TDX: Add TDX HLT exit test Sagi Shahar
2025-08-07 20:16 ` Sagi Shahar [this message]
2025-08-14  9:58   ` [PATCH v8 18/30] KVM: selftests: TDX: Add TDX MMIO reads test Binbin Wu
2025-08-07 20:16 ` [PATCH v8 19/30] KVM: selftests: TDX: Add TDX MMIO writes test Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 20/30] KVM: selftests: TDX: Add TDX CPUID TDVMCALL test Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 21/30] KVM: selftests: TDX: Verify the behavior when host consumes a TD private memory Sagi Shahar
2025-08-11 20:35   ` Sean Christopherson
2025-08-14 11:17   ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 22/30] KVM: selftests: TDX: Add TDG.VP.INFO test Sagi Shahar
2025-08-14  9:04   ` Chenyi Qiang
2025-08-14 11:48   ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 23/30] KVM: selftests: Add functions to allow mapping as shared Sagi Shahar
2025-08-11 18:49   ` Ira Weiny
2025-08-15  2:37   ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 24/30] KVM: selftests: TDX: Add shared memory test Sagi Shahar
2025-08-11 21:06   ` Sean Christopherson
2025-08-07 20:16 ` [PATCH v8 25/30] KVM: selftests: KVM: selftests: Expose new vm_vaddr_alloc_private() Sagi Shahar
2025-08-11 21:07   ` Sean Christopherson
2025-08-15  3:15     ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 26/30] KVM: selftests: TDX: Add support for TDG.MEM.PAGE.ACCEPT Sagi Shahar
2025-08-15  5:38   ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 27/30] KVM: selftests: TDX: Add support for TDG.VP.VEINFO.GET Sagi Shahar
2025-08-07 20:16 ` [PATCH v8 28/30] KVM: selftests: TDX: Add TDX UPM selftest Sagi Shahar
2025-08-13 16:05   ` Ira Weiny
2025-08-13 17:30     ` Reinette Chatre
2025-08-15  7:03   ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 29/30] KVM: selftests: TDX: Add TDX UPM selftests for implicit conversion Sagi Shahar
2025-08-15  7:18   ` Binbin Wu
2025-08-07 20:16 ` [PATCH v8 30/30] KVM: selftests: TDX: Test LOG_DIRTY_PAGES flag to a non-GUEST_MEMFD memslot Sagi Shahar
2025-08-13 16:10   ` Ira Weiny
2025-08-11 17:38 ` [PATCH v8 00/30] TDX KVM selftests Sean Christopherson
2025-08-11 18:11   ` Edgecombe, Rick P
2025-08-11 20:00     ` Sagi Shahar
2025-08-11 20:53     ` Sean Christopherson
2025-08-15  4:14       ` Sagi Shahar
2025-08-15 22:52         ` Sean Christopherson

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=20250807201628.1185915-19-sagis@google.com \
    --to=sagis@google.com \
    --cc=ackerleytng@google.com \
    --cc=afranji@google.com \
    --cc=ajones@ventanamicro.com \
    --cc=binbin.wu@linux.intel.com \
    --cc=erdemaktas@google.com \
    --cc=ira.weiny@intel.com \
    --cc=isaku.yamahata@intel.com \
    --cc=kvm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=oliver.upton@linux.dev \
    --cc=pbonzini@redhat.com \
    --cc=pratikrajesh.sampat@amd.com \
    --cc=reinette.chatre@intel.com \
    --cc=rick.p.edgecombe@intel.com \
    --cc=runanwang@google.com \
    --cc=seanjc@google.com \
    --cc=shuah@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.