[PATCH v2 6/8] x86/mtrr: don't let mtrr_type_lookup() return MTRR_TYPE_INVALID

From: Juergen Gross
Date: Thu Feb 09 2023 - 02:23:28 EST


mtrr_type_lookup() should always return a valid memory type. In case
there is no information available, it should return the default UC.
At the same time the mtrr_type_lookup() stub for the !CONFIG_MTRR
case should set uniform to 1, as if the memory range would be
covered by no MTRR at all.

In the CONFIG_MTRR case make sure uniform is always set to either 0
or 1. Without mtrr_state_set set it to 0, as it isn't known yet whether
the covered range is uniform or not (in fact there is currently no
caller interested in the uniform value before mtrr_state_set is being
set). With MTRRs disabled uniform can be set to 1.

Suggested-by: Linus Torvalds <torvalds@xxxxxxxxxxxxxxxxxxxx>
Signed-off-by: Juergen Gross <jgross@xxxxxxxx>
---
V2:
- always set uniform
- set uniform to 1 in case of disabled MTRRs (Linus Torvalds)
---
arch/x86/include/asm/mtrr.h | 7 +++++--
arch/x86/kernel/cpu/mtrr/generic.c | 12 ++++++++----
2 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 0b8f51d683dc..f362c33e3d74 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -53,9 +53,12 @@ void mtrr_generic_set_state(void);
static inline u8 mtrr_type_lookup(u64 addr, u64 end, u8 *uniform)
{
/*
- * Return no-MTRRs:
+ * Return the default MTRR type, without any known other types in
+ * that range.
*/
- return MTRR_TYPE_INVALID;
+ *uniform = 1;
+
+ return MTRR_TYPE_UNCACHABLE;
}
#define mtrr_save_fixed_ranges(arg) do {} while (0)
#define mtrr_save_state() do {} while (0)
diff --git a/arch/x86/kernel/cpu/mtrr/generic.c b/arch/x86/kernel/cpu/mtrr/generic.c
index 788bc16888a5..afb59ff2cc00 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -299,11 +299,15 @@ u8 mtrr_type_lookup(u64 start, u64 end, u8 *uniform)
/* Make end inclusive instead of exclusive */
end--;

- if (!mtrr_state_set)
- return MTRR_TYPE_INVALID;
+ if (!mtrr_state_set) {
+ *uniform = 0; /* Uniformity is unknown. */
+ return MTRR_TYPE_UNCACHABLE;
+ }

- if (!(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED))
- return MTRR_TYPE_INVALID;
+ if (!(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED)) {
+ *uniform = 1;
+ return MTRR_TYPE_UNCACHABLE;
+ }

/*
* Look up the fixed ranges first, which take priority over
--
2.35.3