x86/tdx: Drop flags from __tdx_hypercall()
After TDX_HCALL_ISSUE_STI got dropped, the only flag left is TDX_HCALL_HAS_OUTPUT. The flag indicates if the caller wants to see tdx_hypercall_args updated based on the hypercall output. Drop the flags and provide __tdx_hypercall_ret() that matches TDX_HCALL_HAS_OUTPUT semantics. Suggested-by: Peter Zijlstra <peterz@infradead.org> Signed-off-by: Kirill A. Shutemov <kirill.shutemov@linux.intel.com> Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com> Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org> Link: https://lore.kernel.org/all/20230321003511.9469-1-kirill.shutemov%40linux.intel.com
This commit is contained in:
parent
e8d018dd02
commit
7a3a401874
|
@ -26,7 +26,7 @@ static inline unsigned int tdx_io_in(int size, u16 port)
|
||||||
.r14 = port,
|
.r14 = port,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
|
if (__tdx_hypercall_ret(&args))
|
||||||
return UINT_MAX;
|
return UINT_MAX;
|
||||||
|
|
||||||
return args.r11;
|
return args.r11;
|
||||||
|
@ -43,7 +43,7 @@ static inline void tdx_io_out(int size, u16 port, u32 value)
|
||||||
.r15 = value,
|
.r15 = value,
|
||||||
};
|
};
|
||||||
|
|
||||||
__tdx_hypercall(&args, 0);
|
__tdx_hypercall(&args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline u8 tdx_inb(u16 port)
|
static inline u8 tdx_inb(u16 port)
|
||||||
|
|
|
@ -85,12 +85,12 @@ SYM_FUNC_START(__tdx_module_call)
|
||||||
SYM_FUNC_END(__tdx_module_call)
|
SYM_FUNC_END(__tdx_module_call)
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* __tdx_hypercall() - Make hypercalls to a TDX VMM using TDVMCALL leaf
|
* TDX_HYPERCALL - Make hypercalls to a TDX VMM using TDVMCALL leaf of TDCALL
|
||||||
* of TDCALL instruction
|
* instruction
|
||||||
*
|
*
|
||||||
* Transforms values in function call argument struct tdx_hypercall_args @args
|
* Transforms values in function call argument struct tdx_hypercall_args @args
|
||||||
* into the TDCALL register ABI. After TDCALL operation, VMM output is saved
|
* 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:
|
* TD VMCALL ABI:
|
||||||
|
@ -105,26 +105,18 @@ SYM_FUNC_END(__tdx_module_call)
|
||||||
* specification. Non zero value indicates vendor
|
* specification. Non zero value indicates vendor
|
||||||
* specific ABI.
|
* specific ABI.
|
||||||
* R11 - VMCALL sub function number
|
* 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.
|
* R8-R9, R12-R15 - Same as above.
|
||||||
*
|
*
|
||||||
* Output Registers:
|
* Output Registers:
|
||||||
*
|
*
|
||||||
* RAX - TDCALL instruction status (Not related to hypercall
|
* RAX - TDCALL instruction status (Not related to hypercall
|
||||||
* output).
|
* output).
|
||||||
* R10 - Hypercall output error code.
|
* RBX, RDX, RDI, RSI - Hypercall sub function specific output values.
|
||||||
* R11-R15 - 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
|
FRAME_BEGIN
|
||||||
|
|
||||||
/* Save callee-saved GPRs as mandated by the x86_64 ABI */
|
/* Save callee-saved GPRs as mandated by the x86_64 ABI */
|
||||||
|
@ -134,9 +126,8 @@ SYM_FUNC_START(__tdx_hypercall)
|
||||||
push %r12
|
push %r12
|
||||||
push %rbx
|
push %rbx
|
||||||
|
|
||||||
/* Free RDI and RSI to be used as TDVMCALL arguments */
|
/* Free RDI to be used as TDVMCALL arguments */
|
||||||
movq %rdi, %rax
|
movq %rdi, %rax
|
||||||
push %rsi
|
|
||||||
|
|
||||||
/* Copy hypercall registers from arg struct: */
|
/* Copy hypercall registers from arg struct: */
|
||||||
movq TDX_HYPERCALL_r8(%rax), %r8
|
movq TDX_HYPERCALL_r8(%rax), %r8
|
||||||
|
@ -171,14 +162,11 @@ SYM_FUNC_START(__tdx_hypercall)
|
||||||
* and are handled by callers.
|
* and are handled by callers.
|
||||||
*/
|
*/
|
||||||
testq %rax, %rax
|
testq %rax, %rax
|
||||||
jne .Lpanic
|
jne .Lpanic\@
|
||||||
|
|
||||||
pop %rax
|
pop %rax
|
||||||
|
|
||||||
/* Copy hypercall result registers to arg struct if needed */
|
.if \ret
|
||||||
testq $TDX_HCALL_HAS_OUTPUT, (%rsp)
|
|
||||||
jz .Lout
|
|
||||||
|
|
||||||
movq %r8, TDX_HYPERCALL_r8(%rax)
|
movq %r8, TDX_HYPERCALL_r8(%rax)
|
||||||
movq %r9, TDX_HYPERCALL_r9(%rax)
|
movq %r9, TDX_HYPERCALL_r9(%rax)
|
||||||
movq %r10, TDX_HYPERCALL_r10(%rax)
|
movq %r10, TDX_HYPERCALL_r10(%rax)
|
||||||
|
@ -191,7 +179,8 @@ SYM_FUNC_START(__tdx_hypercall)
|
||||||
movq %rsi, TDX_HYPERCALL_rsi(%rax)
|
movq %rsi, TDX_HYPERCALL_rsi(%rax)
|
||||||
movq %rbx, TDX_HYPERCALL_rbx(%rax)
|
movq %rbx, TDX_HYPERCALL_rbx(%rax)
|
||||||
movq %rdx, TDX_HYPERCALL_rdx(%rax)
|
movq %rdx, TDX_HYPERCALL_rdx(%rax)
|
||||||
.Lout:
|
.endif
|
||||||
|
|
||||||
/* TDVMCALL leaf return code is in R10 */
|
/* TDVMCALL leaf return code is in R10 */
|
||||||
movq %r10, %rax
|
movq %r10, %rax
|
||||||
|
|
||||||
|
@ -208,9 +197,6 @@ SYM_FUNC_START(__tdx_hypercall)
|
||||||
xor %rdi, %rdi
|
xor %rdi, %rdi
|
||||||
xor %rdx, %rdx
|
xor %rdx, %rdx
|
||||||
|
|
||||||
/* Remove TDX_HCALL_* flags from the stack */
|
|
||||||
pop %rsi
|
|
||||||
|
|
||||||
/* Restore callee-saved GPRs as mandated by the x86_64 ABI */
|
/* Restore callee-saved GPRs as mandated by the x86_64 ABI */
|
||||||
pop %rbx
|
pop %rbx
|
||||||
pop %r12
|
pop %r12
|
||||||
|
@ -221,9 +207,33 @@ SYM_FUNC_START(__tdx_hypercall)
|
||||||
FRAME_END
|
FRAME_END
|
||||||
|
|
||||||
RET
|
RET
|
||||||
.Lpanic:
|
.Lpanic\@:
|
||||||
call __tdx_hypercall_failed
|
call __tdx_hypercall_failed
|
||||||
/* __tdx_hypercall_failed never returns */
|
/* __tdx_hypercall_failed never returns */
|
||||||
REACHABLE
|
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)
|
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)
|
||||||
|
|
|
@ -66,7 +66,7 @@ static inline u64 _tdx_hypercall(u64 fn, u64 r12, u64 r13, u64 r14, u64 r15)
|
||||||
.r15 = r15,
|
.r15 = r15,
|
||||||
};
|
};
|
||||||
|
|
||||||
return __tdx_hypercall(&args, 0);
|
return __tdx_hypercall(&args);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called from __tdx_hypercall() for unrecoverable failure */
|
/* 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,
|
.r14 = p4,
|
||||||
};
|
};
|
||||||
|
|
||||||
return __tdx_hypercall(&args, 0);
|
return __tdx_hypercall(&args);
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(tdx_kvm_hypercall);
|
EXPORT_SYMBOL_GPL(tdx_kvm_hypercall);
|
||||||
#endif
|
#endif
|
||||||
|
@ -179,7 +179,7 @@ static void __noreturn tdx_panic(const char *msg)
|
||||||
* happens to return.
|
* happens to return.
|
||||||
*/
|
*/
|
||||||
while (1)
|
while (1)
|
||||||
__tdx_hypercall(&args, 0);
|
__tdx_hypercall(&args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tdx_parse_tdinfo(u64 *cc_mask)
|
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
|
* can keep the vCPU in virtual HLT, even if an IRQ is
|
||||||
* pending, without hanging/breaking the guest.
|
* pending, without hanging/breaking the guest.
|
||||||
*/
|
*/
|
||||||
return __tdx_hypercall(&args, 0);
|
return __tdx_hypercall(&args);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_halt(struct ve_info *ve)
|
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
|
* can be found in TDX Guest-Host-Communication Interface
|
||||||
* (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>".
|
* (GHCI), section titled "TDG.VP.VMCALL<Instruction.RDMSR>".
|
||||||
*/
|
*/
|
||||||
if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
|
if (__tdx_hypercall_ret(&args))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
regs->ax = lower_32_bits(args.r11);
|
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
|
* can be found in TDX Guest-Host-Communication Interface
|
||||||
* (GHCI) section titled "TDG.VP.VMCALL<Instruction.WRMSR>".
|
* (GHCI) section titled "TDG.VP.VMCALL<Instruction.WRMSR>".
|
||||||
*/
|
*/
|
||||||
if (__tdx_hypercall(&args, 0))
|
if (__tdx_hypercall(&args))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
return ve_instr_len(ve);
|
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
|
* ABI can be found in TDX Guest-Host-Communication Interface
|
||||||
* (GHCI), section titled "VP.VMCALL<Instruction.CPUID>".
|
* (GHCI), section titled "VP.VMCALL<Instruction.CPUID>".
|
||||||
*/
|
*/
|
||||||
if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
|
if (__tdx_hypercall_ret(&args))
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -407,7 +407,7 @@ static bool mmio_read(int size, unsigned long addr, unsigned long *val)
|
||||||
.r15 = *val,
|
.r15 = *val,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (__tdx_hypercall(&args, TDX_HCALL_HAS_OUTPUT))
|
if (__tdx_hypercall_ret(&args))
|
||||||
return false;
|
return false;
|
||||||
*val = args.r11;
|
*val = args.r11;
|
||||||
return true;
|
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
|
* in TDX Guest-Host-Communication Interface (GHCI) section titled
|
||||||
* "TDG.VP.VMCALL<Instruction.IO>".
|
* "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 */
|
/* Update part of the register affected by the emulated instruction */
|
||||||
regs->ax &= ~mask;
|
regs->ax &= ~mask;
|
||||||
|
|
|
@ -7,8 +7,6 @@
|
||||||
|
|
||||||
#define TDX_HYPERCALL_STANDARD 0
|
#define TDX_HYPERCALL_STANDARD 0
|
||||||
|
|
||||||
#define TDX_HCALL_HAS_OUTPUT BIT(0)
|
|
||||||
|
|
||||||
#define TDX_CPUID_LEAF_ID 0x21
|
#define TDX_CPUID_LEAF_ID 0x21
|
||||||
#define TDX_IDENT "IntelTDX "
|
#define TDX_IDENT "IntelTDX "
|
||||||
|
|
||||||
|
@ -36,7 +34,8 @@ struct tdx_hypercall_args {
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Used to request services from the VMM */
|
/* 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 */
|
/* Called from __tdx_hypercall() for unrecoverable failure */
|
||||||
void __tdx_hypercall_failed(void);
|
void __tdx_hypercall_failed(void);
|
||||||
|
|
Loading…
Reference in New Issue