Skip to content
Permalink
Browse files
x86/cpu/tsx: Add helper functions to save/restore IA32_TSX_CTRL MSR
The TDX SEAMCALLs, TDH.SYS.INIT and TDH.SYS.LP.INIT, require the
RTM_DISALBE (bit 0) and TSX_CPUID_CLEAR (bit 1) to be 0 if IA32_TSX_CRTL
MSR is supported by CPU (enumerated by IA32_ARCH_CAPABILITIES.TSX_CTRL).

Add helper functions to clear/restore RTM_DISABLE bit and TSX_CPUID_CLEAR
bit of IA32_TSX_CTRL around TDH.SYS.INIT and TDH.SYS.LP.INIT.

Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
Signed-off-by: Isaku Yamahata <isaku.yamahata@intel.com>
  • Loading branch information
yamahata committed Jan 21, 2022
1 parent aa336dc commit b4ba4adc54d3790157953208dc4deecc7d24005c
Show file tree
Hide file tree
Showing 3 changed files with 64 additions and 3 deletions.
@@ -47,6 +47,8 @@ extern bool handle_user_split_lock(struct pt_regs *regs, long error_code);
extern bool handle_guest_split_lock(unsigned long ip);
extern void handle_bus_lock(struct pt_regs *regs);
u8 get_this_hybrid_cpu_type(void);
extern u64 tsx_ctrl_clear(void);
extern void tsx_ctrl_restore(u64 tsx_ctrl);
#else
static inline void __init sld_setup(struct cpuinfo_x86 *c) {}
static inline void switch_to_sld(unsigned long tifn) {}
@@ -66,6 +68,13 @@ static inline u8 get_this_hybrid_cpu_type(void)
{
return 0;
}

static inline u64 tsx_ctrl_clear(void)
{
return 0;
}

static inline void tsx_ctrl_restore(u64 tsx_ctrl) {}
#endif
#ifdef CONFIG_IA32_FEAT_CTL
void init_ia32_feat_ctl(struct cpuinfo_x86 *c);
@@ -20,12 +20,37 @@ static inline u64 tdh_sys_info(u64 tdsysinfo, int nr_bytes, u64 cmr_info,

static inline u64 tdh_sys_init(u64 attributes, struct tdx_ex_ret *ex)
{
return seamcall(SEAMCALL_TDH_SYS_INIT, attributes, 0, 0, 0, ex);
u64 tsx_ctrl, ret;

/*
* TDH.SYS.INIT has special environment requirements that
* RTM_DISABLE(bit 0) and TSX_CPUID_CLEAR(bit 1) of IA32_TSX_CTRL must
* be 0 if it's supported.
*/
preempt_disable();
tsx_ctrl = tsx_ctrl_clear();
ret = seamcall(SEAMCALL_TDH_SYS_INIT, attributes, 0, 0, 0, ex);
tsx_ctrl_restore(tsx_ctrl);
preempt_enable();
return ret;
}

static inline u64 tdh_sys_lp_init(struct tdx_ex_ret *ex)
{
return seamcall(SEAMCALL_TDH_SYS_LP_INIT, 0, 0, 0, 0, ex);
u64 tsx_ctrl, ret;

/*
* TDH.SYS.LP.INIT has special environment requirements that
* RTM_DISABLE(bit 0) and TSX_CPUID_CLEAR(bit 1) of IA32_TSX_CTRL must
* be 0 if it's supported.
*/
preempt_disable();
tsx_ctrl = tsx_ctrl_clear();
ret = seamcall(SEAMCALL_TDH_SYS_LP_INIT, 0, 0, 0, 0, ex);
tsx_ctrl_restore(tsx_ctrl);
preempt_enable();

return ret;
}

static inline u64 tdh_sys_tdmr_init(u64 tdmr, struct tdx_ex_ret *ex)
@@ -19,6 +19,8 @@

enum tsx_ctrl_states tsx_ctrl_state __ro_after_init = TSX_CTRL_NOT_SUPPORTED;

static bool ia32_tsx_ctrl_supported __ro_after_init;

void tsx_disable(void)
{
u64 tsx;
@@ -73,7 +75,9 @@ static bool __init tsx_ctrl_is_supported(void)
* tsx= cmdline requests will do nothing on CPUs without
* MSR_IA32_TSX_CTRL support.
*/
return !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR);
ia32_tsx_ctrl_supported = !!(ia32_cap & ARCH_CAP_TSX_CTRL_MSR);

return ia32_tsx_ctrl_supported;
}

static enum tsx_ctrl_states x86_get_tsx_auto_mode(void)
@@ -175,3 +179,26 @@ void __init tsx_init(void)
setup_force_cpu_cap(X86_FEATURE_HLE);
}
}

#define MSR_TSX_CTRL_MASK (TSX_CTRL_RTM_DISABLE | TSX_CTRL_CPUID_CLEAR)

/* Clear the MSR_TSX_CTRL and return the old value if supported */
u64 tsx_ctrl_clear(void)
{
u64 tsx_ctrl = 0;

if (ia32_tsx_ctrl_supported) {
rdmsrl(MSR_IA32_TSX_CTRL, tsx_ctrl);
if (tsx_ctrl & MSR_TSX_CTRL_MASK)
wrmsrl(MSR_IA32_TSX_CTRL, tsx_ctrl & ~MSR_TSX_CTRL_MASK);
}
return tsx_ctrl;
}
EXPORT_SYMBOL_GPL(tsx_ctrl_clear);

void tsx_ctrl_restore(u64 tsx_ctrl)
{
if (ia32_tsx_ctrl_supported && (tsx_ctrl & MSR_TSX_CTRL_MASK))
wrmsrl(MSR_IA32_TSX_CTRL, tsx_ctrl);
}
EXPORT_SYMBOL_GPL(tsx_ctrl_restore);

0 comments on commit b4ba4ad

Please sign in to comment.