diff options
author | Hugh Dickins <hugh@veritas.com> | 2008-05-06 15:49:23 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-05-06 16:08:58 -0400 |
commit | aeed5fce37196e09b4dac3a1c00d8b7122e040ce (patch) | |
tree | d16a8f824ad06ac5dea6052f1986165a0d7fc865 /include/asm-x86 | |
parent | bb78be8397d3b0900af3d717672218ee3ea07985 (diff) |
x86: fix PAE pmd_bad bootup warning
Fix warning from pmd_bad() at bootup on a HIGHMEM64G HIGHPTE x86_32.
That came from 9fc34113f6880b215cbea4e7017fc818700384c2 x86: debug pmd_bad();
but we understand now that the typecasting was wrong for PAE in the previous
version: pagetable pages above 4GB looked bad and stopped Arjan from booting.
And revert that cded932b75ab0a5f9181ee3da34a0a488d1a14fd x86: fix pmd_bad
and pud_bad to support huge pages. It was the wrong way round: we shouldn't
weaken every pmd_bad and pud_bad check to let huge pages slip through - in
part they check that we _don't_ have a huge page where it's not expected.
Put the x86 pmd_bad() and pud_bad() definitions back to what they have long
been: they can be improved (x86_32 should use PTE_MASK, to stop PAE thinking
junk in the upper word is good; and x86_64 should follow x86_32's stricter
comparison, to stop thinking any subset of required bits is good); but that
should be a later patch.
Fix Hans' good observation that follow_page() will never find pmd_huge()
because that would have already failed the pmd_bad test: test pmd_huge in
between the pmd_none and pmd_bad tests. Tighten x86's pmd_huge() check?
No, once it's a hugepage entry, it can get quite far from a good pmd: for
example, PROT_NONE leaves it with only ACCESSED of the KERN_PGTABLE bits.
However... though follow_page() contains this and another test for huge
pages, so it's nice to keep it working on them, where does it actually get
called on a huge page? get_user_pages() checks is_vm_hugetlb_page(vma) to
to call alternative hugetlb processing, as does unmap_vmas() and others.
Signed-off-by: Hugh Dickins <hugh@veritas.com>
Earlier-version-tested-by: Ingo Molnar <mingo@elte.hu>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: Jeff Chua <jeff.chua.linux@gmail.com>
Cc: Hans Rosenfeld <hans.rosenfeld@amd.com>
Cc: Arjan van de Ven <arjan@linux.intel.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'include/asm-x86')
-rw-r--r-- | include/asm-x86/pgtable_32.h | 9 | ||||
-rw-r--r-- | include/asm-x86/pgtable_64.h | 6 |
2 files changed, 3 insertions, 12 deletions
diff --git a/include/asm-x86/pgtable_32.h b/include/asm-x86/pgtable_32.h index 577ab79c4c27..d7f0403bbecb 100644 --- a/include/asm-x86/pgtable_32.h +++ b/include/asm-x86/pgtable_32.h | |||
@@ -88,14 +88,7 @@ extern unsigned long pg0[]; | |||
88 | /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ | 88 | /* To avoid harmful races, pmd_none(x) should check only the lower when PAE */ |
89 | #define pmd_none(x) (!(unsigned long)pmd_val((x))) | 89 | #define pmd_none(x) (!(unsigned long)pmd_val((x))) |
90 | #define pmd_present(x) (pmd_val((x)) & _PAGE_PRESENT) | 90 | #define pmd_present(x) (pmd_val((x)) & _PAGE_PRESENT) |
91 | 91 | #define pmd_bad(x) ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE) | |
92 | extern int pmd_bad(pmd_t pmd); | ||
93 | |||
94 | #define pmd_bad_v1(x) \ | ||
95 | (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER))) | ||
96 | #define pmd_bad_v2(x) \ | ||
97 | (_KERNPG_TABLE != (pmd_val((x)) & ~(PAGE_MASK | _PAGE_USER | \ | ||
98 | _PAGE_PSE | _PAGE_NX))) | ||
99 | 92 | ||
100 | #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) | 93 | #define pages_to_mb(x) ((x) >> (20-PAGE_SHIFT)) |
101 | 94 | ||
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h index a3bbf8766c1d..efe83dcbd412 100644 --- a/include/asm-x86/pgtable_64.h +++ b/include/asm-x86/pgtable_64.h | |||
@@ -158,14 +158,12 @@ static inline unsigned long pgd_bad(pgd_t pgd) | |||
158 | 158 | ||
159 | static inline unsigned long pud_bad(pud_t pud) | 159 | static inline unsigned long pud_bad(pud_t pud) |
160 | { | 160 | { |
161 | return pud_val(pud) & | 161 | return pud_val(pud) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); |
162 | ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); | ||
163 | } | 162 | } |
164 | 163 | ||
165 | static inline unsigned long pmd_bad(pmd_t pmd) | 164 | static inline unsigned long pmd_bad(pmd_t pmd) |
166 | { | 165 | { |
167 | return pmd_val(pmd) & | 166 | return pmd_val(pmd) & ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER); |
168 | ~(PTE_MASK | _KERNPG_TABLE | _PAGE_USER | _PAGE_PSE | _PAGE_NX); | ||
169 | } | 167 | } |
170 | 168 | ||
171 | #define pte_none(x) (!pte_val((x))) | 169 | #define pte_none(x) (!pte_val((x))) |