diff options
author | David Gibson <david@gibson.dropbear.id.au> | 2009-10-26 15:24:31 -0400 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2009-10-30 02:21:23 -0400 |
commit | 0895ecda79428df48501e48dd0a868e0c8e1aae2 (patch) | |
tree | 8ecfc6e0bf9c47c793df4c1a1bf1f503c9351281 /arch/powerpc/mm/hugetlbpage-hash64.c | |
parent | 883a3e523672ebba2ec3969837ba02af4f70fae2 (diff) |
powerpc/mm: Bring hugepage PTE accessor functions back into sync with normal accessors
The hugepage arch code provides a number of hook functions/macros
which mirror the functionality of various normal page pte access
functions. Various changes in the normal page accessors (in
particular BenH's recent changes to the handling of lazy icache
flushing and PAGE_EXEC) have caused the hugepage versions to get out
of sync with the originals. In some cases, this is a bug, at least on
some MMU types.
One of the reasons that some hooks were not identical to the normal
page versions, is that the fact we're dealing with a hugepage needed
to be passed down do use the correct dcache-icache flush function.
This patch makes the main flush_dcache_icache_page() function hugepage
aware (by checking for the PageCompound flag). That in turn means we
can make set_huge_pte_at() just a call to set_pte_at() bringing it
back into sync. As a bonus, this lets us remove the
hash_huge_page_do_lazy_icache() function, replacing it with a call to
the hash_page_do_lazy_icache() function it was based on.
Some other hugepage pte access hooks - huge_ptep_get_and_clear() and
huge_ptep_clear_flush() - are not so easily unified, but this patch at
least brings them back into sync with the current versions of the
corresponding normal page functions.
Signed-off-by: David Gibson <dwg@au1.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc/mm/hugetlbpage-hash64.c')
-rw-r--r-- | arch/powerpc/mm/hugetlbpage-hash64.c | 30 |
1 files changed, 1 insertions, 29 deletions
diff --git a/arch/powerpc/mm/hugetlbpage-hash64.c b/arch/powerpc/mm/hugetlbpage-hash64.c index 1508ffc1e1e1..199539882f92 100644 --- a/arch/powerpc/mm/hugetlbpage-hash64.c +++ b/arch/powerpc/mm/hugetlbpage-hash64.c | |||
@@ -14,33 +14,6 @@ | |||
14 | #include <asm/cacheflush.h> | 14 | #include <asm/cacheflush.h> |
15 | #include <asm/machdep.h> | 15 | #include <asm/machdep.h> |
16 | 16 | ||
17 | /* | ||
18 | * Called by asm hashtable.S for doing lazy icache flush | ||
19 | */ | ||
20 | static unsigned int hash_huge_page_do_lazy_icache(unsigned long rflags, | ||
21 | pte_t pte, int trap, unsigned long sz) | ||
22 | { | ||
23 | struct page *page; | ||
24 | int i; | ||
25 | |||
26 | if (!pfn_valid(pte_pfn(pte))) | ||
27 | return rflags; | ||
28 | |||
29 | page = pte_page(pte); | ||
30 | |||
31 | /* page is dirty */ | ||
32 | if (!test_bit(PG_arch_1, &page->flags) && !PageReserved(page)) { | ||
33 | if (trap == 0x400) { | ||
34 | for (i = 0; i < (sz / PAGE_SIZE); i++) | ||
35 | __flush_dcache_icache(page_address(page+i)); | ||
36 | set_bit(PG_arch_1, &page->flags); | ||
37 | } else { | ||
38 | rflags |= HPTE_R_N; | ||
39 | } | ||
40 | } | ||
41 | return rflags; | ||
42 | } | ||
43 | |||
44 | int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | 17 | int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, |
45 | pte_t *ptep, unsigned long trap, int local, int ssize, | 18 | pte_t *ptep, unsigned long trap, int local, int ssize, |
46 | unsigned int shift, unsigned int mmu_psize) | 19 | unsigned int shift, unsigned int mmu_psize) |
@@ -89,8 +62,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid, | |||
89 | if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) | 62 | if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE)) |
90 | /* No CPU has hugepages but lacks no execute, so we | 63 | /* No CPU has hugepages but lacks no execute, so we |
91 | * don't need to worry about that case */ | 64 | * don't need to worry about that case */ |
92 | rflags = hash_huge_page_do_lazy_icache(rflags, __pte(old_pte), | 65 | rflags = hash_page_do_lazy_icache(rflags, __pte(old_pte), trap); |
93 | trap, sz); | ||
94 | 66 | ||
95 | /* Check if pte already has an hpte (case 2) */ | 67 | /* Check if pte already has an hpte (case 2) */ |
96 | if (unlikely(old_pte & _PAGE_HASHPTE)) { | 68 | if (unlikely(old_pte & _PAGE_HASHPTE)) { |