[go: up one dir, main page]

Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Wrong number of MAX_FIXED_MTRR #26

Closed
1 of 3 tasks
wbenny opened this issue Jul 23, 2018 · 1 comment
Closed
1 of 3 tasks

Wrong number of MAX_FIXED_MTRR #26

wbenny opened this issue Jul 23, 2018 · 1 comment

Comments

@wbenny
Copy link
Contributor
wbenny commented Jul 23, 2018

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
@asamy
Copy link
Owner
asamy commented Jul 24, 2018

Thanks, applied.

@asamy asamy closed this as completed Jul 24, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants