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

Message ID 20230207072902.5528-5-jgross@suse.com
State New
Headers
Series x86/mtrr: fix handling with PAT but without MTRR |

Commit Message

Juergen Gross Feb. 7, 2023, 7:29 a.m. UTC
  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.

Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Juergen Gross <jgross@suse.com>
---
 arch/x86/include/asm/mtrr.h        | 7 +++++--
 arch/x86/kernel/cpu/mtrr/generic.c | 4 ++--
 2 files changed, 7 insertions(+), 4 deletions(-)
  

Comments

Linus Torvalds Feb. 7, 2023, 4:20 p.m. UTC | #1
On Mon, Feb 6, 2023 at 11:29 PM Juergen Gross <jgross@suse.com> wrote:
>
> mtrr_type_lookup() should always return a valid memory type. In case
> there is no information available, it should return the default UC.

Why isn't the second case (ie MTRR_STATE_MTRR_ENABLED not being set)
returning 'mtrr_state.def_type'. That's what the hw does, no?

> 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.

.. but you didn't do that for the CONFIG_MTRR, so now they return
MTRR_TYPE_UNCACHABLE, but don't set uniform=1.

              Linus
  
Juergen Gross Feb. 8, 2023, 6:20 a.m. UTC | #2
On 07.02.23 17:20, Linus Torvalds wrote:
> On Mon, Feb 6, 2023 at 11:29 PM Juergen Gross <jgross@suse.com> wrote:
>>
>> mtrr_type_lookup() should always return a valid memory type. In case
>> there is no information available, it should return the default UC.
> 
> Why isn't the second case (ie MTRR_STATE_MTRR_ENABLED not being set)
> returning 'mtrr_state.def_type'. That's what the hw does, no?

Are you sure? In the SDM I'm reading:

* E (MTRRs enabled) flag, bit 11 — MTRRs are enabled when set; all MTRRs are
   disabled when clear, and the UC memory type is applied to all of physical
   memory.

So UC it should be IMHO.

>> 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.
> 
> .. but you didn't do that for the CONFIG_MTRR, so now they return
> MTRR_TYPE_UNCACHABLE, but don't set uniform=1.

I agree that setting uniform should be done at least for the case of not
enabled MTRRs.

The case of !mtrr_state_set is different, as the data regarding setting
uniform isn't known yet. OTOH there is no caller of mtrr_type_lookup()
interested in the uniform setting so early in boot, so I guess not
setting it is fine (setting it would be okay for the same reason, but
it would be technically wrong IMO).


Juergen
  
Linus Torvalds Feb. 8, 2023, 3:42 p.m. UTC | #3
On Tue, Feb 7, 2023 at 10:20 PM Juergen Gross <jgross@suse.com> wrote:
>
> Are you sure? In the SDM I'm reading:
>
> * E (MTRRs enabled) flag, bit 11 — MTRRs are enabled when set; all MTRRs are
>    disabled when clear, and the UC memory type is applied to all of physical
>    memory.
>
> So UC it should be IMHO.

Right you are. I clearly misread that section when I did my original patch.

                Linus
  

Patch

diff --git a/arch/x86/include/asm/mtrr.h b/arch/x86/include/asm/mtrr.h
index 29ec2d6f0537..c12c73d48f08 100644
--- a/arch/x86/include/asm/mtrr.h
+++ b/arch/x86/include/asm/mtrr.h
@@ -57,9 +57,12 @@  static inline bool mtrr_enabled(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 ee09d359e08f..c749ec4436a1 100644
--- a/arch/x86/kernel/cpu/mtrr/generic.c
+++ b/arch/x86/kernel/cpu/mtrr/generic.c
@@ -262,10 +262,10 @@  u8 mtrr_type_lookup(u64 start, u64 end, u8 *uniform)
 	end--;
 
 	if (!mtrr_state_set)
-		return MTRR_TYPE_INVALID;
+		return MTRR_TYPE_UNCACHABLE;
 
 	if (!(mtrr_state.enabled & MTRR_STATE_MTRR_ENABLED))
-		return MTRR_TYPE_INVALID;
+		return MTRR_TYPE_UNCACHABLE;
 
 	/*
 	 * Look up the fixed ranges first, which take priority over