On 20.03.23 20:05, Borislav Petkov wrote: > On Mon, Mar 06, 2023 at 05:34:16PM +0100, Juergen Gross wrote: >> +/** >> + * mtrr_overwrite_state - set static MTRR state >> + * >> + * Used to set MTRR state via different means (e.g. with data obtained from >> + * a hypervisor). >> + * Is allowed only for special cases when running virtualized. Must be called >> + * from the x86_init.hyper.init_platform() hook. X86_FEATURE_MTRR must be off. >> + */ >> +void mtrr_overwrite_state(struct mtrr_var_range *var, unsigned int num_var, >> + mtrr_type def_type) >> +{ >> + unsigned int i; >> + >> + if (WARN_ON(mtrr_state_set || >> + hypervisor_is_type(X86_HYPER_NATIVE) || > > Why that check? I guess you are asking because the next test seems to catch the same case? I think it doesn't, e.g. for the case of unknown hypervisors (which shows that X86_HYPER_NATIVE in theory should be named X86_HYPER_NATIVE_OR_UNKNOWN, or it should be split into X86_HYPER_NATIVE and X86_HYPER_UNKNOWN). > >> + !cpu_feature_enabled(X86_FEATURE_HYPERVISOR) || >> + (!cc_platform_has(CC_ATTR_GUEST_SEV_SNP) && >> + !hv_is_isolation_supported() && >> + !cpu_feature_enabled(X86_FEATURE_XENPV) && >> + !cpu_feature_enabled(X86_FEATURE_TDX_GUEST)))) > > This is unparseable. Please split it into separate checks: > > if (WARN_ON(mtrr_state_set)) > return; > > if (WARN_ON(!cpu_feature_enabled(X86_FEATURE_HYPERVISOR))) > return; > > ... > > and add comments above each one why we're testing this. Okay. > > >> + return; >> + >> + /* Disable MTRR in order to disable MTRR modifications. */ >> + setup_clear_cpu_cap(X86_FEATURE_MTRR); >> + >> + if (var) { >> + if (num_var > MTRR_MAX_VAR_RANGES) { >> + pr_warn("Trying to overwrite MTRR state with %u variable entries\n", >> + num_var); >> + num_var = MTRR_MAX_VAR_RANGES; >> + } >> + for (i = 0; i < num_var; i++) >> + mtrr_state.var_ranges[i] = var[i]; >> + num_var_ranges = num_var; >> + } >> + >> + mtrr_state.def_type = def_type; >> + mtrr_state.enabled |= MTRR_STATE_MTRR_ENABLED; >> + >> + mtrr_state_set = 1; >> +} >> + >> /** >> * mtrr_type_lookup - look up memory type in MTRR >> * >> diff --git a/arch/x86/kernel/cpu/mtrr/mtrr.c b/arch/x86/kernel/cpu/mtrr/mtrr.c >> index 7596ebeab929..5fe62ee0361b 100644 >> --- a/arch/x86/kernel/cpu/mtrr/mtrr.c >> +++ b/arch/x86/kernel/cpu/mtrr/mtrr.c >> @@ -666,6 +666,15 @@ void __init mtrr_bp_init(void) >> const char *why = "(not available)"; >> unsigned int phys_addr; >> >> + if (mtrr_state.enabled) { > > I'm guessing the proper detection of that weird state should be: > > /* > * Check for the software overwrite of MTRR state, only for generic case. > * See mtrr_overwrite_state(). > */ > if (!cpu_feature_enabled(X86_FEATURE_MTRR) && > mtrr_state.enabled) { > ... It basically doesn't matter. The only possibility of mtrr_state.enabled to be set at this point is a previous call of mtrr_overwrite_state(). Juergen