Commit 7b664cc3 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull x86 tdx update from Dave Hansen:
 "The original tdx hypercall assembly code took two flags in %RSI to
  tweak its behavior at runtime. PeterZ recently axed one flag in commit
  e80a48ba ("x86/tdx: Remove TDX_HCALL_ISSUE_STI").

  Kill the other flag too and tweak the 'output' mode with an assembly
  macro instead. This results in elimination of one push/pop pair and
  overall easier to read assembly.

   - Do conditional __tdx_hypercall() 'output' processing via an
     assembly macro argument rather than a runtime register"

* tag 'x86_tdx_for_6.4' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip:
  x86/tdx: Drop flags from __tdx_hypercall()
parents e54debe6 7a3a4018
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -26,7 +26,7 @@ static inline unsigned int tdx_io_in(int size, u16 port)
		.r14 = port,
	};

	if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
	if (__tdx_hypercall_ret(&args))
		return UINT_MAX;

	return args.r11;
@@ -43,7 +43,7 @@ static inline void tdx_io_out(int size, u16 port, u32 value)
		.r15 = value,
	};

	__tdx_hypercall(&args, 0);
	__tdx_hypercall(&args);
}

static inline u8 tdx_inb(u16 port)
+38 −28
Original line number Diff line number Diff line
@@ -85,12 +85,12 @@ SYM_FUNC_START(__tdx_module_call)
SYM_FUNC_END(__tdx_module_call)

/*
 * __tdx_hypercall() - Make hypercalls to a TDX VMM using TDVMCALL leaf
 * of TDCALL instruction
 * TDX_HYPERCALL - Make hypercalls to a TDX VMM using TDVMCALL leaf of TDCALL
 * instruction
 *
 * Transforms values in  function call argument struct tdx_hypercall_args @args
 * into the TDCALL register ABI. After TDCALL operation, VMM output is saved
 * back in @args.
 * back in @args, if \ret is 1.
 *
 *-------------------------------------------------------------------------
 * TD VMCALL ABI:
@@ -105,26 +105,18 @@ SYM_FUNC_END(__tdx_module_call)
 *                       specification. Non zero value indicates vendor
 *                       specific ABI.
 * R11                 - VMCALL sub function number
 * RBX, RBP, RDI, RSI  - Used to pass VMCALL sub function specific arguments.
 * RBX, RDX, RDI, RSI  - Used to pass VMCALL sub function specific arguments.
 * R8-R9, R12-R15      - Same as above.
 *
 * Output Registers:
 *
 * RAX                 - TDCALL instruction status (Not related to hypercall
 *                        output).
 * R10                 - Hypercall output error code.
 * R11-R15             - Hypercall sub function specific output values.
 * RBX, RDX, RDI, RSI  - Hypercall sub function specific output values.
 * R8-R15              - Same as above.
 *
 *-------------------------------------------------------------------------
 *
 * __tdx_hypercall() function ABI:
 *
 * @args  (RDI)        - struct tdx_hypercall_args for input and output
 * @flags (RSI)        - TDX_HCALL_* flags
 *
 * On successful completion, return the hypercall error code.
 */
SYM_FUNC_START(__tdx_hypercall)
.macro TDX_HYPERCALL ret:req
	FRAME_BEGIN

	/* Save callee-saved GPRs as mandated by the x86_64 ABI */
@@ -134,9 +126,8 @@ SYM_FUNC_START(__tdx_hypercall)
	push %r12
	push %rbx

	/* Free RDI and RSI to be used as TDVMCALL arguments */
	/* Free RDI to be used as TDVMCALL arguments */
	movq %rdi, %rax
	push %rsi

	/* Copy hypercall registers from arg struct: */
	movq TDX_HYPERCALL_r8(%rax),  %r8
@@ -171,14 +162,11 @@ SYM_FUNC_START(__tdx_hypercall)
	 * and are handled by callers.
	 */
	testq %rax, %rax
	jne .Lpanic
	jne .Lpanic\@

	pop %rax

	/* Copy hypercall result registers to arg struct if needed */
	testq $TDX_HCALL_HAS_OUTPUT, (%rsp)
	jz .Lout

	.if \ret
	movq %r8,  TDX_HYPERCALL_r8(%rax)
	movq %r9,  TDX_HYPERCALL_r9(%rax)
	movq %r10, TDX_HYPERCALL_r10(%rax)
@@ -191,7 +179,8 @@ SYM_FUNC_START(__tdx_hypercall)
	movq %rsi, TDX_HYPERCALL_rsi(%rax)
	movq %rbx, TDX_HYPERCALL_rbx(%rax)
	movq %rdx, TDX_HYPERCALL_rdx(%rax)
.Lout:
	.endif

	/* TDVMCALL leaf return code is in R10 */
	movq %r10, %rax

@@ -208,9 +197,6 @@ SYM_FUNC_START(__tdx_hypercall)
	xor %rdi,  %rdi
	xor %rdx,  %rdx

	/* Remove TDX_HCALL_* flags from the stack */
	pop %rsi

	/* Restore callee-saved GPRs as mandated by the x86_64 ABI */
	pop %rbx
	pop %r12
@@ -221,9 +207,33 @@ SYM_FUNC_START(__tdx_hypercall)
	FRAME_END

	RET
.Lpanic:
.Lpanic\@:
	call __tdx_hypercall_failed
	/* __tdx_hypercall_failed never returns */
	REACHABLE
	jmp .Lpanic
	jmp .Lpanic\@
.endm

/*
 *
 * __tdx_hypercall() function ABI:
 *
 * @args  (RDI)        - struct tdx_hypercall_args for input
 *
 * On successful completion, return the hypercall error code.
 */
SYM_FUNC_START(__tdx_hypercall)
	TDX_HYPERCALL ret=0
SYM_FUNC_END(__tdx_hypercall)

/*
 *
 * __tdx_hypercall_ret() function ABI:
 *
 * @args  (RDI)        - struct tdx_hypercall_args for input and output
 *
 * On successful completion, return the hypercall error code.
 */
SYM_FUNC_START(__tdx_hypercall_ret)
	TDX_HYPERCALL ret=1
SYM_FUNC_END(__tdx_hypercall_ret)
+9 −9
Original line number Diff line number Diff line
@@ -66,7 +66,7 @@ static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15)
		.r15 = r15,
	};

	return __tdx_hypercall(&args, 0);
	return __tdx_hypercall(&args);
}

/* Called from __tdx_hypercall() for unrecoverable failure */
@@ -99,7 +99,7 @@ long tdx_kvm_hypercall(unsigned int nr, unsigned long p1, unsigned long p2,
		.r14 = p4,
	};

	return __tdx_hypercall(&args, 0);
	return __tdx_hypercall(&args);
}
EXPORT_SYMBOL_GPL(tdx_kvm_hypercall);
#endif
@@ -179,7 +179,7 @@ static void __noreturn tdx_panic(const char *msg)
	 * happens to return.
	 */
	while (1)
		__tdx_hypercall(&args, 0);
		__tdx_hypercall(&args);
}

static void tdx_parse_tdinfo(u64 *cc_mask)
@@ -289,7 +289,7 @@ static u64 __cpuidle __halt(const bool irq_disabled)
	 * can keep the vCPU in virtual HLT, even if an IRQ is
	 * pending, without hanging/breaking the guest.
	 */
	return __tdx_hypercall(&args, 0);
	return __tdx_hypercall(&args);
}

static int handle_halt(struct ve_info *ve)
@@ -326,7 +326,7 @@ static int read_msr(struct pt_regs *regs, struct ve_info *ve)
	 * can be found in TDX Guest-Host-Communication Interface
	 * (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>".
	 */
	if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
	if (__tdx_hypercall_ret(&args))
		return -EIO;

	regs->ax = lower_32_bits(args.r11);
@@ -348,7 +348,7 @@ static int write_msr(struct pt_regs *regs, struct ve_info *ve)
	 * can be found in TDX Guest-Host-Communication Interface
	 * (GHCI) section titled "TDG.VP.VMCALL<Instruction.WRMSR>".
	 */
	if (__tdx_hypercall(&args, 0))
	if (__tdx_hypercall(&args))
		return -EIO;

	return ve_instr_len(ve);
@@ -380,7 +380,7 @@ static int handle_cpuid(struct pt_regs *regs, struct ve_info *ve)
	 * ABI can be found in TDX Guest-Host-Communication Interface
	 * (GHCI), section titled "VP.VMCALL<Instruction.CPUID>".
	 */
	if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
	if (__tdx_hypercall_ret(&args))
		return -EIO;

	/*
@@ -407,7 +407,7 @@ static bool mmio_read(int size, unsigned long addr, unsigned long *val)
		.r15 = *val,
	};

	if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
	if (__tdx_hypercall_ret(&args))
		return false;
	*val = args.r11;
	return true;
@@ -541,7 +541,7 @@ static bool handle_in(struct pt_regs *regs, int size, int port)
	 * in TDX Guest-Host-Communication Interface (GHCI) section titled
	 * "TDG.VP.VMCALL<Instruction.IO>".
	 */
	success = !__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT);
	success = !__tdx_hypercall_ret(&args);

	/* Update part of the register affected by the emulated instruction */
	regs->ax &= ~mask;
+2 −3
Original line number Diff line number Diff line
@@ -7,8 +7,6 @@

#define TDX_HYPERCALL_STANDARD  0

#define TDX_HCALL_HAS_OUTPUT	BIT(0)

#define TDX_CPUID_LEAF_ID	0x21
#define TDX_IDENT		"IntelTDX    "

@@ -36,7 +34,8 @@ struct tdx_hypercall_args {
};

/* Used to request services from the VMM */
u64 __tdx_hypercall(struct tdx_hypercall_args *args, unsigned long flags);
u64 __tdx_hypercall(struct tdx_hypercall_args *args);
u64 __tdx_hypercall_ret(struct tdx_hypercall_args *args);

/* Called from __tdx_hypercall() for unrecoverable failure */
void __tdx_hypercall_failed(void);