Re: [PATCH v4 03/12] x86/mtrr: support setting MTRR state for software defined MTRRs

From: Juergen Gross
Date: Tue Mar 21 2023 - 02:01:06 EST


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

Attachment: OpenPGP_0xB0DE9DD628BF132F.asc
Description: OpenPGP public key

Attachment: OpenPGP_signature
Description: OpenPGP digital signature