From: Erdem Aktas <[email protected]> Implement the tdx_mmio_write() to allow TDX VMs to request MMIO emulation.
Follow the Intel Guest-Hypervisor Communication Interface (GHCI) spec to the minimum extent that a spec-abiding TDX module will pass the request to KVM. Skip implementing the #VE handler as described in the GHCI spec so selftests will not take a dependency on having a working To perform emulated I/O, VMs use the TDG.VP.VMCALL instruction to request MMIO. Signed-off-by: Erdem Aktas <[email protected]> Co-developed-by: Sagi Shahar <[email protected]> Signed-off-by: Sagi Shahar <[email protected]> Co-developed-by: Lisa Wang <[email protected]> Signed-off-by: Lisa Wang <[email protected]> --- tools/testing/selftests/kvm/Makefile.kvm | 1 + tools/testing/selftests/kvm/include/x86/tdx/tdx.h | 16 ++++++++++++ tools/testing/selftests/kvm/lib/x86/tdx/tdx.c | 30 +++++++++++++++++++++++ 3 files changed, 47 insertions(+) diff --git a/tools/testing/selftests/kvm/Makefile.kvm b/tools/testing/selftests/kvm/Makefile.kvm index a651a876c522..489324cecf83 100644 --- a/tools/testing/selftests/kvm/Makefile.kvm +++ b/tools/testing/selftests/kvm/Makefile.kvm @@ -33,6 +33,7 @@ LIBKVM_x86 += lib/x86/ucall.c LIBKVM_x86 += lib/x86/vmx.c LIBKVM_x86 += lib/x86/tdx/tdx_util.c LIBKVM_x86 += lib/x86/tdx/td_boot.S +LIBKVM_x86 += lib/x86/tdx/tdx.c LIBKVM_arm64 += lib/arm64/gic.c LIBKVM_arm64 += lib/arm64/gic_v3.c diff --git a/tools/testing/selftests/kvm/include/x86/tdx/tdx.h b/tools/testing/selftests/kvm/include/x86/tdx/tdx.h new file mode 100644 index 000000000000..810ca7423c84 --- /dev/null +++ b/tools/testing/selftests/kvm/include/x86/tdx/tdx.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef SELFTESTS_TDX_TDX_H +#define SELFTESTS_TDX_TDX_H + +#include <linux/types.h> + +enum mmio_size { + MMIO_SIZE_1B = 1, + MMIO_SIZE_2B = 2, + MMIO_SIZE_4B = 4, + MMIO_SIZE_8B = 8 +}; + +u64 tdx_mmio_write(u64 address, enum mmio_size size, u64 data_in); + +#endif // SELFTESTS_TDX_TDX_H diff --git a/tools/testing/selftests/kvm/lib/x86/tdx/tdx.c b/tools/testing/selftests/kvm/lib/x86/tdx/tdx.c new file mode 100644 index 000000000000..f19be79fe11f --- /dev/null +++ b/tools/testing/selftests/kvm/lib/x86/tdx/tdx.c @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: GPL-2.0-only + +#include "tdx/tdx.h" + +#define TDG_VP_VMCALL 0 +#define TDG_VP_VMCALL_VE_REQUEST_MMIO 48 +#define TDVMCALL_MMIO_WRITE 1 +#define TDVMCALL_EXPOSE_REGS_MASK 0xFC00 + +u64 tdx_mmio_write(u64 address, enum mmio_size size, u64 data_in) +{ + register u64 r10_reg asm("r10") = TDG_VP_VMCALL; + register u64 r11_reg asm("r11") = TDG_VP_VMCALL_VE_REQUEST_MMIO; + register u64 r12_reg asm("r12") = size; + register u64 r13_reg asm("r13") = TDVMCALL_MMIO_WRITE; + register u64 r14_reg asm("r14") = address; + register u64 r15_reg asm("r15") = data_in; + register u64 rax_reg asm("rax") = TDG_VP_VMCALL; + register u64 rcx_reg asm("rcx") = TDVMCALL_EXPOSE_REGS_MASK; + + asm volatile( + ".byte 0x66,0x0f,0x01,0xcc" /* tdcall */ + : "+r" (r10_reg), "+r" (r11_reg) + : "r" (r12_reg), "r" (r13_reg), "r" (r14_reg), "r" (r15_reg), + "r" (rax_reg), "r" (rcx_reg) + : "cc", "memory" + ); + + return r10_reg; +} -- 2.54.0.746.g67dd491aae-goog

