Wrong number of MAX_FIXED_MTRR
wbenny opened this issue · 1 comments
Type of this issue (please specify)
- This is a bug in the upstream tree as-is unmodified.
- This is a support matter (i.e. your own modified tree)
- This is a technical question
Issue description
mtrr_ranges array has wrong size and may eventually overflow if user gets really REALLY unlucky
Current Behavior
Let's deconstruct this issue:
in ksm.h:
struct mtrr_range mtrr_ranges[MAX_MTRR];
in mm.h:
#define MAX_VAR_MTRR 255
#define MAX_FIXED_MTRR 11
#define MAX_MTRR MAX_VAR_MTRR + MAX_FIXED_MTRR
in ksm.c:
mm_cache_mtrr_ranges(&k->mtrr_ranges[0], &k->mtrr_count, &k->mtrr_def);
in mm.c:
for (msr = __readmsr(MSR_MTRRfix64K_00000), offset = 0x10000, base = 0;
msr != 0; msr >>= 8, base += offset)
make_mtrr_range(&ranges[idx++], true, msr & 0xff, base, base + 0x10000);
for (val = MSR_MTRRfix16K_80000, offset = 0x4000; val <= MSR_MTRRfix16K_A0000; ++val)
for (msr = __readmsr(val), base = 0x80000;
msr != 0; msr >>= 8, base += offset)
make_mtrr_range(&ranges[idx++], true, msr & 0xff, base, base + 0x4000);
for (val = MSR_MTRRfix4K_C0000, offset = 0x1000; val <= MSR_MTRRfix4K_F8000; ++val)
for (msr = __readmsr(val), base = 0xC0000;
msr != 0; msr >>= 8, base += offset)
make_mtrr_range(&ranges[idx++], true, msr & 0xff, base, base + 0x1000);
Here's the problem: for each fixed MTRR, there are actually 8 subranges.
Intel manual says:
11.11.2.2 Fixed Range MTRRs
The fixed memory ranges are mapped with 11 fixed-range registers of 64 bits each. Each of these registers is
divided into 8-bit fields that are used to specify the memory type for each of the sub-ranges the register controls:
• Register IA32_MTRR_FIX64K_00000 — Maps the 512-KByte address range from 0H to 7FFFFH. This range
is divided into eight 64-KByte sub-ranges.
• Registers IA32_MTRR_FIX16K_80000 and IA32_MTRR_FIX16K_A0000 — Maps the two 128-KByte
address ranges from 80000H to BFFFFH. This range is divided into sixteen 16-KByte sub-ranges, 8 ranges per
register.
• Registers IA32_MTRR_FIX4K_C0000 through IA32_MTRR_FIX4K_F8000 — Maps eight 32-KByte
address ranges from C0000H to FFFFFH. This range is divided into sixty-four 4-KByte sub-ranges, 8 ranges per
register.
Expected Behavior
I think fix is as simple as defining MAX_FIXED_MTRR to 11*8.
Inline code / patches to be used when reproducing
From 57ad5c11ab9d5d8c353379b21207902c3e47ba4d Mon Sep 17 00:00:00 2001
From: Petr Benes <w.benny@outlook.com>
Date: Tue, 24 Jul 2018 00:43:12 +0200
Subject: [PATCH] fix MAX_FIXED_MTRR definition
---
mm.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mm.h b/mm.h
index 1a79519..d9863a4 100644
--- a/mm.h
+++ b/mm.h
@@ -406,7 +406,7 @@ struct mtrr_range {
};
#define MAX_VAR_MTRR 255
-#define MAX_FIXED_MTRR 11
+#define MAX_FIXED_MTRR 11*8
#define MAX_MTRR MAX_VAR_MTRR + MAX_FIXED_MTRR
extern void mm_cache_mtrr_ranges(struct mtrr_range *ranges, int *count, u8 *def_type);
--
2.17.0.windows.1
Thanks, applied.