The test verifies IO reads of various sizes from the host to the guest.
Signed-off-by: Sagi Shahar sagis@google.com --- tools/testing/selftests/kvm/x86/tdx_vm_test.c | 76 ++++++++++++++++++- 1 file changed, 75 insertions(+), 1 deletion(-)
diff --git a/tools/testing/selftests/kvm/x86/tdx_vm_test.c b/tools/testing/selftests/kvm/x86/tdx_vm_test.c index f646da032004..ae5749e5c605 100644 --- a/tools/testing/selftests/kvm/x86/tdx_vm_test.c +++ b/tools/testing/selftests/kvm/x86/tdx_vm_test.c @@ -383,6 +383,78 @@ void verify_guest_writes(void) printf("\t ... PASSED\n"); }
+#define TDX_IO_READS_TEST_PORT 0x52 + +/* + * Verifies IO functionality by reading values of different sizes + * from the host. + */ +void guest_io_reads(void) +{ + uint64_t data; + uint64_t ret; + + ret = tdg_vp_vmcall_instruction_io(TDX_IO_READS_TEST_PORT, 1, + PORT_READ, &data); + tdx_assert_error(ret); + if (data != 0xAB) + tdx_test_fatal(1); + + ret = tdg_vp_vmcall_instruction_io(TDX_IO_READS_TEST_PORT, 2, + PORT_READ, &data); + tdx_assert_error(ret); + if (data != 0xABCD) + tdx_test_fatal(2); + + ret = tdg_vp_vmcall_instruction_io(TDX_IO_READS_TEST_PORT, 4, + PORT_READ, &data); + tdx_assert_error(ret); + if (data != 0xFFABCDEF) + tdx_test_fatal(4); + + /* Read an invalid number of bytes. */ + ret = tdg_vp_vmcall_instruction_io(TDX_IO_READS_TEST_PORT, 5, + PORT_READ, &data); + tdx_assert_error(ret); + + tdx_test_success(); +} + +void verify_guest_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_io_reads); + td_finalize(vm); + + printf("Verifying guest reads:\n"); + + tdx_run(vcpu); + tdx_test_assert_io(vcpu, TDX_IO_READS_TEST_PORT, 1, PORT_READ); + *(uint8_t *)((void *)vcpu->run + vcpu->run->io.data_offset) = 0xAB; + + tdx_run(vcpu); + tdx_test_assert_io(vcpu, TDX_IO_READS_TEST_PORT, 2, PORT_READ); + *(uint16_t *)((void *)vcpu->run + vcpu->run->io.data_offset) = 0xABCD; + + tdx_run(vcpu); + tdx_test_assert_io(vcpu, TDX_IO_READS_TEST_PORT, 4, PORT_READ); + *(uint32_t *)((void *)vcpu->run + vcpu->run->io.data_offset) = 0xFFABCDEF; + + 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(); @@ -390,7 +462,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(6); + ksft_set_plan(7); 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), @@ -403,6 +475,8 @@ int main(int argc, char **argv) "verify_get_td_vmcall_info\n"); ksft_test_result(!run_in_new_process(&verify_guest_writes), "verify_guest_writes\n"); + ksft_test_result(!run_in_new_process(&verify_guest_reads), + "verify_guest_reads\n");
ksft_finished(); return 0;