Skip to content

Commit 694a20d

Browse files
committed
Merge tag 'powerpc-4.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: "A larger batch of fixes than we'd like. Roughly 1/3 fixes for new code, 1/3 fixes for stable and 1/3 minor things. There's four commits fixing bugs when using 16GB huge pages on hash, caused by some of the preparatory changes for pkeys. Two fixes for bugs in the enhanced IRQ soft masking for local_t, one of which broke KVM in some circumstances. Four fixes for Power9. The most bizarre being a bug where futexes stopped working because a NULL pointer dereference didn't trap during early boot (it aliased the kernel mapping). A fix for memory hotplug when using the Radix MMU, and a fix for live migration of guests using the Radix MMU. Two fixes for hotplug on pseries machines. One where we weren't correctly updating NUMA info when CPUs are added and removed. And the other fixes crashes/hangs seen when doing memory hot remove during boot, which is apparently a thing people do. Finally a handful of build fixes for obscure configs and other minor fixes. Thanks to: Alexey Kardashevskiy, Aneesh Kumar K.V, Balbir Singh, Colin Ian King, Daniel Henrique Barboza, Florian Weimer, Guenter Roeck, Harish, Laurent Vivier, Madhavan Srinivasan, Mauricio Faria de Oliveira, Nathan Fontenot, Nicholas Piggin, Sam Bobroff" * tag 'powerpc-4.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: selftests/powerpc: Fix to use ucontext_t instead of struct ucontext powerpc/kdump: Fix powernv build break when KEXEC_CORE=n powerpc/pseries: Fix build break for SPLPAR=n and CPU hotplug powerpc/mm/hash64: Zero PGD pages on allocation powerpc/mm/hash64: Store the slot information at the right offset for hugetlb powerpc/mm/hash64: Allocate larger PMD table if hugetlb config is enabled powerpc/mm: Fix crashes with 16G huge pages powerpc/mm: Flush radix process translations when setting MMU type powerpc/vas: Don't set uses_vas for kernel windows powerpc/pseries: Enable RAS hotplug events later powerpc/mm/radix: Split linear mapping on hot-unplug powerpc/64s/radix: Boot-time NULL pointer protection using a guard-PID ocxl: fix signed comparison with less than zero powerpc/64s: Fix may_hard_irq_enable() for PMI soft masking powerpc/64s: Fix MASKABLE_RELON_EXCEPTION_HV_OOL macro powerpc/numa: Invalidate numa_cpu_lookup_table on cpu remove
2 parents 61f14c0 + ecdf06e commit 694a20d

File tree

28 files changed

+231
-79
lines changed

28 files changed

+231
-79
lines changed

arch/powerpc/include/asm/book3s/32/pgtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
#define PGD_INDEX_SIZE (32 - PGDIR_SHIFT)
1717

1818
#define PMD_CACHE_INDEX PMD_INDEX_SIZE
19+
#define PUD_CACHE_INDEX PUD_INDEX_SIZE
1920

2021
#ifndef __ASSEMBLY__
2122
#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE)

arch/powerpc/include/asm/book3s/64/hash-4k.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ static inline int hash__hugepd_ok(hugepd_t hpd)
6363
* keeping the prototype consistent across the two formats.
6464
*/
6565
static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
66-
unsigned int subpg_index, unsigned long hidx)
66+
unsigned int subpg_index, unsigned long hidx,
67+
int offset)
6768
{
6869
return (hidx << H_PAGE_F_GIX_SHIFT) &
6970
(H_PAGE_F_SECOND | H_PAGE_F_GIX);

arch/powerpc/include/asm/book3s/64/hash-64k.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
* generic accessors and iterators here
4646
*/
4747
#define __real_pte __real_pte
48-
static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
48+
static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep, int offset)
4949
{
5050
real_pte_t rpte;
5151
unsigned long *hidxp;
@@ -59,7 +59,7 @@ static inline real_pte_t __real_pte(pte_t pte, pte_t *ptep)
5959
*/
6060
smp_rmb();
6161

62-
hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
62+
hidxp = (unsigned long *)(ptep + offset);
6363
rpte.hidx = *hidxp;
6464
return rpte;
6565
}
@@ -86,9 +86,10 @@ static inline unsigned long __rpte_to_hidx(real_pte_t rpte, unsigned long index)
8686
* expected to modify the PTE bits accordingly and commit the PTE to memory.
8787
*/
8888
static inline unsigned long pte_set_hidx(pte_t *ptep, real_pte_t rpte,
89-
unsigned int subpg_index, unsigned long hidx)
89+
unsigned int subpg_index,
90+
unsigned long hidx, int offset)
9091
{
91-
unsigned long *hidxp = (unsigned long *)(ptep + PTRS_PER_PTE);
92+
unsigned long *hidxp = (unsigned long *)(ptep + offset);
9293

9394
rpte.hidx &= ~HIDX_BITS(0xfUL, subpg_index);
9495
*hidxp = rpte.hidx | HIDX_BITS(HIDX_SHIFT_BY_ONE(hidx), subpg_index);
@@ -140,13 +141,18 @@ static inline int hash__remap_4k_pfn(struct vm_area_struct *vma, unsigned long a
140141
}
141142

142143
#define H_PTE_TABLE_SIZE PTE_FRAG_SIZE
143-
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
144+
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined (CONFIG_HUGETLB_PAGE)
144145
#define H_PMD_TABLE_SIZE ((sizeof(pmd_t) << PMD_INDEX_SIZE) + \
145146
(sizeof(unsigned long) << PMD_INDEX_SIZE))
146147
#else
147148
#define H_PMD_TABLE_SIZE (sizeof(pmd_t) << PMD_INDEX_SIZE)
148149
#endif
150+
#ifdef CONFIG_HUGETLB_PAGE
151+
#define H_PUD_TABLE_SIZE ((sizeof(pud_t) << PUD_INDEX_SIZE) + \
152+
(sizeof(unsigned long) << PUD_INDEX_SIZE))
153+
#else
149154
#define H_PUD_TABLE_SIZE (sizeof(pud_t) << PUD_INDEX_SIZE)
155+
#endif
150156
#define H_PGD_TABLE_SIZE (sizeof(pgd_t) << PGD_INDEX_SIZE)
151157

152158
#ifdef CONFIG_TRANSPARENT_HUGEPAGE

arch/powerpc/include/asm/book3s/64/hash.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323
H_PUD_INDEX_SIZE + H_PGD_INDEX_SIZE + PAGE_SHIFT)
2424
#define H_PGTABLE_RANGE (ASM_CONST(1) << H_PGTABLE_EADDR_SIZE)
2525

26-
#if defined(CONFIG_TRANSPARENT_HUGEPAGE) && defined(CONFIG_PPC_64K_PAGES)
26+
#if (defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)) && \
27+
defined(CONFIG_PPC_64K_PAGES)
2728
/*
2829
* only with hash 64k we need to use the second half of pmd page table
2930
* to store pointer to deposited pgtable_t
@@ -32,6 +33,16 @@
3233
#else
3334
#define H_PMD_CACHE_INDEX H_PMD_INDEX_SIZE
3435
#endif
36+
/*
37+
* We store the slot details in the second half of page table.
38+
* Increase the pud level table so that hugetlb ptes can be stored
39+
* at pud level.
40+
*/
41+
#if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_PPC_64K_PAGES)
42+
#define H_PUD_CACHE_INDEX (H_PUD_INDEX_SIZE + 1)
43+
#else
44+
#define H_PUD_CACHE_INDEX (H_PUD_INDEX_SIZE)
45+
#endif
3546
/*
3647
* Define the address range of the kernel non-linear virtual area
3748
*/

arch/powerpc/include/asm/book3s/64/pgalloc.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,16 @@ static inline void radix__pgd_free(struct mm_struct *mm, pgd_t *pgd)
7373

7474
static inline pgd_t *pgd_alloc(struct mm_struct *mm)
7575
{
76+
pgd_t *pgd;
77+
7678
if (radix_enabled())
7779
return radix__pgd_alloc(mm);
78-
return kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE),
79-
pgtable_gfp_flags(mm, GFP_KERNEL));
80+
81+
pgd = kmem_cache_alloc(PGT_CACHE(PGD_INDEX_SIZE),
82+
pgtable_gfp_flags(mm, GFP_KERNEL));
83+
memset(pgd, 0, PGD_TABLE_SIZE);
84+
85+
return pgd;
8086
}
8187

8288
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
@@ -93,13 +99,13 @@ static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud)
9399

94100
static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long addr)
95101
{
96-
return kmem_cache_alloc(PGT_CACHE(PUD_INDEX_SIZE),
102+
return kmem_cache_alloc(PGT_CACHE(PUD_CACHE_INDEX),
97103
pgtable_gfp_flags(mm, GFP_KERNEL));
98104
}
99105

100106
static inline void pud_free(struct mm_struct *mm, pud_t *pud)
101107
{
102-
kmem_cache_free(PGT_CACHE(PUD_INDEX_SIZE), pud);
108+
kmem_cache_free(PGT_CACHE(PUD_CACHE_INDEX), pud);
103109
}
104110

105111
static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd)
@@ -115,7 +121,7 @@ static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
115121
* ahead and flush the page walk cache
116122
*/
117123
flush_tlb_pgtable(tlb, address);
118-
pgtable_free_tlb(tlb, pud, PUD_INDEX_SIZE);
124+
pgtable_free_tlb(tlb, pud, PUD_CACHE_INDEX);
119125
}
120126

121127
static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long addr)

arch/powerpc/include/asm/book3s/64/pgtable.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,11 +232,13 @@ extern unsigned long __pmd_index_size;
232232
extern unsigned long __pud_index_size;
233233
extern unsigned long __pgd_index_size;
234234
extern unsigned long __pmd_cache_index;
235+
extern unsigned long __pud_cache_index;
235236
#define PTE_INDEX_SIZE __pte_index_size
236237
#define PMD_INDEX_SIZE __pmd_index_size
237238
#define PUD_INDEX_SIZE __pud_index_size
238239
#define PGD_INDEX_SIZE __pgd_index_size
239240
#define PMD_CACHE_INDEX __pmd_cache_index
241+
#define PUD_CACHE_INDEX __pud_cache_index
240242
/*
241243
* Because of use of pte fragments and THP, size of page table
242244
* are not always derived out of index size above.
@@ -348,7 +350,7 @@ extern unsigned long pci_io_base;
348350
*/
349351
#ifndef __real_pte
350352

351-
#define __real_pte(e,p) ((real_pte_t){(e)})
353+
#define __real_pte(e, p, o) ((real_pte_t){(e)})
352354
#define __rpte_to_pte(r) ((r).pte)
353355
#define __rpte_to_hidx(r,index) (pte_val(__rpte_to_pte(r)) >> H_PAGE_F_GIX_SHIFT)
354356

arch/powerpc/include/asm/exception-64s.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -645,7 +645,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943)
645645
EXC_HV, SOFTEN_TEST_HV, bitmask)
646646

647647
#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label, bitmask) \
648-
MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_HV, vec, bitmask);\
648+
MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\
649649
EXCEPTION_RELON_PROLOG_PSERIES_1(label, EXC_HV)
650650

651651
/*

arch/powerpc/include/asm/hw_irq.h

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@
2929
#define PACA_IRQ_HMI 0x20
3030
#define PACA_IRQ_PMI 0x40
3131

32+
/*
33+
* Some soft-masked interrupts must be hard masked until they are replayed
34+
* (e.g., because the soft-masked handler does not clear the exception).
35+
*/
36+
#ifdef CONFIG_PPC_BOOK3S
37+
#define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE|PACA_IRQ_PMI)
38+
#else
39+
#define PACA_IRQ_MUST_HARD_MASK (PACA_IRQ_EE)
40+
#endif
41+
3242
/*
3343
* flags for paca->irq_soft_mask
3444
*/
@@ -244,7 +254,7 @@ static inline bool lazy_irq_pending(void)
244254
static inline void may_hard_irq_enable(void)
245255
{
246256
get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
247-
if (!(get_paca()->irq_happened & PACA_IRQ_EE))
257+
if (!(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK))
248258
__hard_irq_enable();
249259
}
250260

arch/powerpc/include/asm/kexec.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,12 @@ static inline bool kdump_in_progress(void)
140140
return false;
141141
}
142142

143+
static inline void crash_ipi_callback(struct pt_regs *regs) { }
144+
145+
static inline void crash_send_ipi(void (*crash_ipi_callback)(struct pt_regs *))
146+
{
147+
}
148+
143149
#endif /* CONFIG_KEXEC_CORE */
144150
#endif /* ! __ASSEMBLY__ */
145151
#endif /* __KERNEL__ */

arch/powerpc/include/asm/nohash/32/pgtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ extern int icache_44x_need_flush;
2424
#define PGD_INDEX_SIZE (32 - PGDIR_SHIFT)
2525

2626
#define PMD_CACHE_INDEX PMD_INDEX_SIZE
27+
#define PUD_CACHE_INDEX PUD_INDEX_SIZE
2728

2829
#ifndef __ASSEMBLY__
2930
#define PTE_TABLE_SIZE (sizeof(pte_t) << PTE_INDEX_SIZE)

arch/powerpc/include/asm/nohash/64/pgtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#else
2828
#define PMD_CACHE_INDEX PMD_INDEX_SIZE
2929
#endif
30+
#define PUD_CACHE_INDEX PUD_INDEX_SIZE
3031

3132
/*
3233
* Define the address range of the kernel non-linear virtual area

arch/powerpc/include/asm/topology.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ extern int sysfs_add_device_to_node(struct device *dev, int nid);
4444
extern void sysfs_remove_device_from_node(struct device *dev, int nid);
4545
extern int numa_update_cpu_topology(bool cpus_locked);
4646

47+
static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node)
48+
{
49+
numa_cpu_lookup_table[cpu] = node;
50+
}
51+
4752
static inline int early_cpu_to_node(int cpu)
4853
{
4954
int nid;
@@ -82,6 +87,7 @@ static inline int numa_update_cpu_topology(bool cpus_locked)
8287
extern int start_topology_update(void);
8388
extern int stop_topology_update(void);
8489
extern int prrn_is_enabled(void);
90+
extern int find_and_online_cpu_nid(int cpu);
8591
#else
8692
static inline int start_topology_update(void)
8793
{
@@ -95,6 +101,10 @@ static inline int prrn_is_enabled(void)
95101
{
96102
return 0;
97103
}
104+
static inline int find_and_online_cpu_nid(int cpu)
105+
{
106+
return 0;
107+
}
98108
#endif /* CONFIG_NUMA && CONFIG_PPC_SPLPAR */
99109

100110
#if defined(CONFIG_HOTPLUG_CPU) || defined(CONFIG_NEED_MULTIPLE_NODES)

arch/powerpc/kernel/exceptions-64e.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,8 @@ kernel_dbg_exc:
943943
/*
944944
* An interrupt came in while soft-disabled; We mark paca->irq_happened
945945
* accordingly and if the interrupt is level sensitive, we hard disable
946+
* hard disable (full_mask) corresponds to PACA_IRQ_MUST_HARD_MASK, so
947+
* keep these in synch.
946948
*/
947949

948950
.macro masked_interrupt_book3e paca_irq full_mask

arch/powerpc/kernel/exceptions-64s.S

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,7 +1426,7 @@ EXC_COMMON_BEGIN(soft_nmi_common)
14261426
* triggered and won't automatically refire.
14271427
* - If it was a HMI we return immediately since we handled it in realmode
14281428
* and it won't refire.
1429-
* - else we hard disable and return.
1429+
* - Else it is one of PACA_IRQ_MUST_HARD_MASK, so hard disable and return.
14301430
* This is called with r10 containing the value to OR to the paca field.
14311431
*/
14321432
#define MASKED_INTERRUPT(_H) \
@@ -1441,8 +1441,8 @@ masked_##_H##interrupt: \
14411441
ori r10,r10,0xffff; \
14421442
mtspr SPRN_DEC,r10; \
14431443
b MASKED_DEC_HANDLER_LABEL; \
1444-
1: andi. r10,r10,(PACA_IRQ_DBELL|PACA_IRQ_HMI); \
1445-
bne 2f; \
1444+
1: andi. r10,r10,PACA_IRQ_MUST_HARD_MASK; \
1445+
beq 2f; \
14461446
mfspr r10,SPRN_##_H##SRR1; \
14471447
xori r10,r10,MSR_EE; /* clear MSR_EE */ \
14481448
mtspr SPRN_##_H##SRR1,r10; \

arch/powerpc/mm/hash64_4k.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
5555
* need to add in 0x1 if it's a read-only user page
5656
*/
5757
rflags = htab_convert_pte_flags(new_pte);
58-
rpte = __real_pte(__pte(old_pte), ptep);
58+
rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE);
5959

6060
if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
6161
!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
@@ -117,7 +117,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
117117
return -1;
118118
}
119119
new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE;
120-
new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
120+
new_pte |= pte_set_hidx(ptep, rpte, 0, slot, PTRS_PER_PTE);
121121
}
122122
*ptep = __pte(new_pte & ~H_PAGE_BUSY);
123123
return 0;

arch/powerpc/mm/hash64_64k.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
8686

8787
subpg_index = (ea & (PAGE_SIZE - 1)) >> shift;
8888
vpn = hpt_vpn(ea, vsid, ssize);
89-
rpte = __real_pte(__pte(old_pte), ptep);
89+
rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE);
9090
/*
9191
*None of the sub 4k page is hashed
9292
*/
@@ -214,7 +214,7 @@ int __hash_page_4K(unsigned long ea, unsigned long access, unsigned long vsid,
214214
return -1;
215215
}
216216

217-
new_pte |= pte_set_hidx(ptep, rpte, subpg_index, slot);
217+
new_pte |= pte_set_hidx(ptep, rpte, subpg_index, slot, PTRS_PER_PTE);
218218
new_pte |= H_PAGE_HASHPTE;
219219

220220
*ptep = __pte(new_pte & ~H_PAGE_BUSY);
@@ -262,7 +262,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
262262
} while (!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
263263

264264
rflags = htab_convert_pte_flags(new_pte);
265-
rpte = __real_pte(__pte(old_pte), ptep);
265+
rpte = __real_pte(__pte(old_pte), ptep, PTRS_PER_PTE);
266266

267267
if (cpu_has_feature(CPU_FTR_NOEXECUTE) &&
268268
!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
@@ -327,7 +327,7 @@ int __hash_page_64K(unsigned long ea, unsigned long access,
327327
}
328328

329329
new_pte = (new_pte & ~_PAGE_HPTEFLAGS) | H_PAGE_HASHPTE;
330-
new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
330+
new_pte |= pte_set_hidx(ptep, rpte, 0, slot, PTRS_PER_PTE);
331331
}
332332
*ptep = __pte(new_pte & ~H_PAGE_BUSY);
333333
return 0;

arch/powerpc/mm/hash_utils_64.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,6 +1008,7 @@ void __init hash__early_init_mmu(void)
10081008
__pmd_index_size = H_PMD_INDEX_SIZE;
10091009
__pud_index_size = H_PUD_INDEX_SIZE;
10101010
__pgd_index_size = H_PGD_INDEX_SIZE;
1011+
__pud_cache_index = H_PUD_CACHE_INDEX;
10111012
__pmd_cache_index = H_PMD_CACHE_INDEX;
10121013
__pte_table_size = H_PTE_TABLE_SIZE;
10131014
__pmd_table_size = H_PMD_TABLE_SIZE;

arch/powerpc/mm/hugetlbpage-hash64.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
2727
unsigned long vpn;
2828
unsigned long old_pte, new_pte;
2929
unsigned long rflags, pa, sz;
30-
long slot;
30+
long slot, offset;
3131

3232
BUG_ON(shift != mmu_psize_defs[mmu_psize].shift);
3333

@@ -63,7 +63,11 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
6363
} while(!pte_xchg(ptep, __pte(old_pte), __pte(new_pte)));
6464

6565
rflags = htab_convert_pte_flags(new_pte);
66-
rpte = __real_pte(__pte(old_pte), ptep);
66+
if (unlikely(mmu_psize == MMU_PAGE_16G))
67+
offset = PTRS_PER_PUD;
68+
else
69+
offset = PTRS_PER_PMD;
70+
rpte = __real_pte(__pte(old_pte), ptep, offset);
6771

6872
sz = ((1UL) << shift);
6973
if (!cpu_has_feature(CPU_FTR_COHERENT_ICACHE))
@@ -104,7 +108,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
104108
return -1;
105109
}
106110

107-
new_pte |= pte_set_hidx(ptep, rpte, 0, slot);
111+
new_pte |= pte_set_hidx(ptep, rpte, 0, slot, offset);
108112
}
109113

110114
/*

arch/powerpc/mm/init-common.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,6 @@ void pgtable_cache_init(void)
100100
* same size as either the pgd or pmd index except with THP enabled
101101
* on book3s 64
102102
*/
103-
if (PUD_INDEX_SIZE && !PGT_CACHE(PUD_INDEX_SIZE))
104-
pgtable_cache_add(PUD_INDEX_SIZE, pud_ctor);
103+
if (PUD_CACHE_INDEX && !PGT_CACHE(PUD_CACHE_INDEX))
104+
pgtable_cache_add(PUD_CACHE_INDEX, pud_ctor);
105105
}

0 commit comments

Comments
 (0)