0001
0002
0003 #include "../cpuflags.h"
0004 #include "../string.h"
0005 #include "../io.h"
0006 #include "error.h"
0007
0008 #include <vdso/limits.h>
0009 #include <uapi/asm/vmx.h>
0010
0011 #include <asm/shared/tdx.h>
0012
0013
0014 void __tdx_hypercall_failed(void)
0015 {
0016 error("TDVMCALL failed. TDX module bug?");
0017 }
0018
0019 static inline unsigned int tdx_io_in(int size, u16 port)
0020 {
0021 struct tdx_hypercall_args args = {
0022 .r10 = TDX_HYPERCALL_STANDARD,
0023 .r11 = EXIT_REASON_IO_INSTRUCTION,
0024 .r12 = size,
0025 .r13 = 0,
0026 .r14 = port,
0027 };
0028
0029 if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
0030 return UINT_MAX;
0031
0032 return args.r11;
0033 }
0034
0035 static inline void tdx_io_out(int size, u16 port, u32 value)
0036 {
0037 struct tdx_hypercall_args args = {
0038 .r10 = TDX_HYPERCALL_STANDARD,
0039 .r11 = EXIT_REASON_IO_INSTRUCTION,
0040 .r12 = size,
0041 .r13 = 1,
0042 .r14 = port,
0043 .r15 = value,
0044 };
0045
0046 __tdx_hypercall(&args, 0);
0047 }
0048
0049 static inline u8 tdx_inb(u16 port)
0050 {
0051 return tdx_io_in(1, port);
0052 }
0053
0054 static inline void tdx_outb(u8 value, u16 port)
0055 {
0056 tdx_io_out(1, port, value);
0057 }
0058
0059 static inline void tdx_outw(u16 value, u16 port)
0060 {
0061 tdx_io_out(2, port, value);
0062 }
0063
0064 void early_tdx_detect(void)
0065 {
0066 u32 eax, sig[3];
0067
0068 cpuid_count(TDX_CPUID_LEAF_ID, 0, &eax, &sig[0], &sig[2], &sig[1]);
0069
0070 if (memcmp(TDX_IDENT, sig, sizeof(sig)))
0071 return;
0072
0073
0074 pio_ops.f_inb = tdx_inb;
0075 pio_ops.f_outb = tdx_outb;
0076 pio_ops.f_outw = tdx_outw;
0077 }