diff options
Diffstat (limited to 'arch/powerpc/mm/hugepage-hash64.c')
-rw-r--r-- | arch/powerpc/mm/hugepage-hash64.c | 60 |
1 files changed, 5 insertions, 55 deletions
diff --git a/arch/powerpc/mm/hugepage-hash64.c b/arch/powerpc/mm/hugepage-hash64.c index 5f5e6328c21c..86686514ae13 100644 --- a/arch/powerpc/mm/hugepage-hash64.c +++ b/arch/powerpc/mm/hugepage-hash64.c | |||
@@ -18,60 +18,9 @@ | |||
18 | #include <linux/mm.h> | 18 | #include <linux/mm.h> |
19 | #include <asm/machdep.h> | 19 | #include <asm/machdep.h> |
20 | 20 | ||
21 | static void invalidate_old_hpte(unsigned long vsid, unsigned long addr, | ||
22 | pmd_t *pmdp, unsigned int psize, int ssize) | ||
23 | { | ||
24 | int i, max_hpte_count, valid; | ||
25 | unsigned long s_addr; | ||
26 | unsigned char *hpte_slot_array; | ||
27 | unsigned long hidx, shift, vpn, hash, slot; | ||
28 | |||
29 | s_addr = addr & HPAGE_PMD_MASK; | ||
30 | hpte_slot_array = get_hpte_slot_array(pmdp); | ||
31 | /* | ||
32 | * IF we try to do a HUGE PTE update after a withdraw is done. | ||
33 | * we will find the below NULL. This happens when we do | ||
34 | * split_huge_page_pmd | ||
35 | */ | ||
36 | if (!hpte_slot_array) | ||
37 | return; | ||
38 | |||
39 | if (ppc_md.hugepage_invalidate) | ||
40 | return ppc_md.hugepage_invalidate(vsid, s_addr, hpte_slot_array, | ||
41 | psize, ssize); | ||
42 | /* | ||
43 | * No bluk hpte removal support, invalidate each entry | ||
44 | */ | ||
45 | shift = mmu_psize_defs[psize].shift; | ||
46 | max_hpte_count = HPAGE_PMD_SIZE >> shift; | ||
47 | for (i = 0; i < max_hpte_count; i++) { | ||
48 | /* | ||
49 | * 8 bits per each hpte entries | ||
50 | * 000| [ secondary group (one bit) | hidx (3 bits) | valid bit] | ||
51 | */ | ||
52 | valid = hpte_valid(hpte_slot_array, i); | ||
53 | if (!valid) | ||
54 | continue; | ||
55 | hidx = hpte_hash_index(hpte_slot_array, i); | ||
56 | |||
57 | /* get the vpn */ | ||
58 | addr = s_addr + (i * (1ul << shift)); | ||
59 | vpn = hpt_vpn(addr, vsid, ssize); | ||
60 | hash = hpt_hash(vpn, shift, ssize); | ||
61 | if (hidx & _PTEIDX_SECONDARY) | ||
62 | hash = ~hash; | ||
63 | |||
64 | slot = (hash & htab_hash_mask) * HPTES_PER_GROUP; | ||
65 | slot += hidx & _PTEIDX_GROUP_IX; | ||
66 | ppc_md.hpte_invalidate(slot, vpn, psize, | ||
67 | MMU_PAGE_16M, ssize, 0); | ||
68 | } | ||
69 | } | ||
70 | |||
71 | |||
72 | int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid, | 21 | int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid, |
73 | pmd_t *pmdp, unsigned long trap, int local, int ssize, | 22 | pmd_t *pmdp, unsigned long trap, unsigned long flags, |
74 | unsigned int psize) | 23 | int ssize, unsigned int psize) |
75 | { | 24 | { |
76 | unsigned int index, valid; | 25 | unsigned int index, valid; |
77 | unsigned char *hpte_slot_array; | 26 | unsigned char *hpte_slot_array; |
@@ -145,7 +94,8 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid, | |||
145 | * hash page table entries. | 94 | * hash page table entries. |
146 | */ | 95 | */ |
147 | if ((old_pmd & _PAGE_HASHPTE) && !(old_pmd & _PAGE_COMBO)) | 96 | if ((old_pmd & _PAGE_HASHPTE) && !(old_pmd & _PAGE_COMBO)) |
148 | invalidate_old_hpte(vsid, ea, pmdp, MMU_PAGE_64K, ssize); | 97 | flush_hash_hugepage(vsid, ea, pmdp, MMU_PAGE_64K, |
98 | ssize, flags); | ||
149 | } | 99 | } |
150 | 100 | ||
151 | valid = hpte_valid(hpte_slot_array, index); | 101 | valid = hpte_valid(hpte_slot_array, index); |
@@ -158,7 +108,7 @@ int __hash_page_thp(unsigned long ea, unsigned long access, unsigned long vsid, | |||
158 | slot += hidx & _PTEIDX_GROUP_IX; | 108 | slot += hidx & _PTEIDX_GROUP_IX; |
159 | 109 | ||
160 | ret = ppc_md.hpte_updatepp(slot, rflags, vpn, | 110 | ret = ppc_md.hpte_updatepp(slot, rflags, vpn, |
161 | psize, lpsize, ssize, local); | 111 | psize, lpsize, ssize, flags); |
162 | /* | 112 | /* |
163 | * We failed to update, try to insert a new entry. | 113 | * We failed to update, try to insert a new entry. |
164 | */ | 114 | */ |