diff options
authorSuresh Siddha <>2009-01-28 16:51:53 -0800
committerGreg Kroah-Hartman <>2009-02-02 09:53:28 -0800
commitd3349f421244ed74c091810ec204ecc34f607f03 (patch)
parent0998e51b3d7f860438fb1971d667c2b2f1cc2e48 (diff)
x86, pat: fix PTE corruption issue while mapping RAM using /dev/mem
commit 9597134218300c045cf219be3664615e97cb239c upstream. Beschorner Daniel reported: > hwinfo problem since 2.6.28, showing this in the oops: > Corrupted page table at address 7fd04de3ec00 Also, PaX Team reported a regression with this commit: > commit 9542ada803198e6eba29d3289abb39ea82047b92 > Author: Suresh Siddha <> > Date: Wed Sep 24 08:53:33 2008 -0700 > > x86: track memtype for RAM in page struct This commit breaks mapping any RAM page through /dev/mem, as the reserve_memtype() was not initializing the return attribute type and as such corrupting the PTE entry that was setup with the return attribute type. Because of this bug, application mapping this RAM page through /dev/mem will die with "Corrupted page table at address xxxx" message in the kernel log and also the kernel identity mapping which maps the underlying RAM page gets converted to UC. Fix this by initializing the return attribute type before calling reserve_ram_pages_type() Reported-by: PaX Team <> Reported-and-tested-by: Beschorner Daniel <> Tested-and-Acked-by: PaX Team <> Signed-off-by: Suresh Siddha <> Signed-off-by: Venkatesh Pallipadi <> Signed-off-by: Ingo Molnar <> Signed-off-by: Greg Kroah-Hartman <>
1 files changed, 3 insertions, 3 deletions
diff --git a/arch/x86/mm/pat.c b/arch/x86/mm/pat.c
index 54738f2abd04..bd8bcce44238 100644
--- a/arch/x86/mm/pat.c
+++ b/arch/x86/mm/pat.c
@@ -333,6 +333,9 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
req_type & _PAGE_CACHE_MASK);
+ if (new_type)
+ *new_type = actual_type;
* For legacy reasons, some parts of the physical address range in the
* legacy 1MB region is treated as non-RAM (even when listed as RAM in
@@ -356,9 +359,6 @@ int reserve_memtype(u64 start, u64 end, unsigned long req_type,
new->end = end;
new->type = actual_type;
- if (new_type)
- *new_type = actual_type;
if (cached_entry && start >= cached_start)