Messages in this thread Patch in this message | | | From | "Kirill A. Shutemov" <> | Subject | [PATCH 3/3] x86/boot/compressed: Support TDX guest port I/O at decompression time | Date | Thu, 20 Jan 2022 05:15:44 +0300 |
| |
Port I/O instructions trigger #VE in the TDX environment. In response to the exception, kernel emulates these instructions using hypercalls.
But during early boot, on the decompression stage, it is cumbersome to deal with #VE. It is cleaner to go to hypercalls directly, bypassing #VE handling.
Hook up TDX-specific port I/O helpers if booting in TDX environment.
Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> --- arch/x86/boot/compressed/Makefile | 2 +- arch/x86/boot/compressed/tdcall.S | 3 ++ arch/x86/boot/compressed/tdx.c | 62 +++++++++++++++++++++++++++++++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 arch/x86/boot/compressed/tdcall.S
diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile index 22a2a6cc2ab4..3215442d8d2d 100644 --- a/arch/x86/boot/compressed/Makefile +++ b/arch/x86/boot/compressed/Makefile @@ -98,7 +98,7 @@ ifdef CONFIG_X86_64 endif vmlinux-objs-$(CONFIG_ACPI) += $(obj)/acpi.o -vmlinux-objs-$(CONFIG_INTEL_TDX_GUEST) += $(obj)/tdx.o +vmlinux-objs-$(CONFIG_INTEL_TDX_GUEST) += $(obj)/tdx.o $(obj)/tdcall.o vmlinux-objs-$(CONFIG_EFI_MIXED) += $(obj)/efi_thunk_$(BITS).o efi-obj-$(CONFIG_EFI_STUB) = $(objtree)/drivers/firmware/efi/libstub/lib.a diff --git a/arch/x86/boot/compressed/tdcall.S b/arch/x86/boot/compressed/tdcall.S new file mode 100644 index 000000000000..aafadc136c88 --- /dev/null +++ b/arch/x86/boot/compressed/tdcall.S @@ -0,0 +1,3 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#include "../../kernel/tdcall.S" diff --git a/arch/x86/boot/compressed/tdx.c b/arch/x86/boot/compressed/tdx.c index ae8c57ea00d8..265359131b92 100644 --- a/arch/x86/boot/compressed/tdx.c +++ b/arch/x86/boot/compressed/tdx.c @@ -5,6 +5,11 @@ #include "../cpuflags.h" #include "../string.h" +#include "../io.h" + +#include <vdso/limits.h> +#include <uapi/asm/vmx.h> +#include <asm/tdx.h> #define TDX_CPUID_LEAF_ID 0x21 #define TDX_IDENT "IntelTDX " @@ -16,6 +21,54 @@ bool early_is_tdx_guest(void) return tdx_guest_detected; } +static inline unsigned int tdx_io_in(int size, int port) +{ + struct tdx_hypercall_output out; + + __tdx_hypercall(TDX_HYPERCALL_STANDARD, EXIT_REASON_IO_INSTRUCTION, + size, 0, port, 0, &out); + + return out.r10 ? UINT_MAX : out.r11; +} + +static inline void tdx_io_out(int size, int port, u64 value) +{ + struct tdx_hypercall_output out; + + __tdx_hypercall(TDX_HYPERCALL_STANDARD, EXIT_REASON_IO_INSTRUCTION, + size, 1, port, value, &out); +} + +static inline unsigned char tdx_inb(int port) +{ + return tdx_io_in(1, port); +} + +static inline unsigned short tdx_inw(int port) +{ + return tdx_io_in(2, port); +} + +static inline unsigned int tdx_inl(int port) +{ + return tdx_io_in(4, port); +} + +static inline void tdx_outb(unsigned char value, int port) +{ + tdx_io_out(1, port, value); +} + +static inline void tdx_outw(unsigned short value, int port) +{ + tdx_io_out(2, port, value); +} + +static inline void tdx_outl(unsigned int value, int port) +{ + tdx_io_out(4, port, value); +} + void early_tdx_detect(void) { u32 eax, sig[3]; @@ -27,4 +80,13 @@ void early_tdx_detect(void) /* Cache TDX guest feature status */ tdx_guest_detected = true; + + pio_ops = (struct port_io_ops) { + .inb = tdx_inb, + .inw = tdx_inw, + .inl = tdx_inl, + .outb = tdx_outb, + .outw = tdx_outw, + .outl = tdx_outl, + }; } -- 2.34.1
| |