Skip to content

Commit 7561393

Browse files
committed
Merge tag 'powerpc-5.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux
Pull powerpc fixes from Michael Ellerman: - One fix for the interrupt rework we did last release which broke KVM-PR - Three commits fixing some fallout from the READ_ONCE() changes interacting badly with our 8xx 16K pages support, which uses a pte_t that is a structure of 4 actual PTEs - A cleanup of the 8xx pte_update() to use the newly added pmd_off() - A fix for a crash when handling an oops if CONFIG_DEBUG_VIRTUAL is enabled - A minor fix for the SPU syscall generation Thanks to Aneesh Kumar K.V, Christian Zigotzky, Christophe Leroy, Mike Rapoport, Nicholas Piggin. * tag 'powerpc-5.8-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: powerpc/8xx: Provide ptep_get() with 16k pages mm: Allow arches to provide ptep_get() mm/gup: Use huge_ptep_get() in gup_hugepte() powerpc/syscalls: Use the number when building SPU syscall table powerpc/8xx: use pmd_off() to access a PMD entry in pte_update() powerpc/64s: Fix KVM interrupt using wrong save area powerpc: Fix kernel crash in show_instructions() w/DEBUG_VIRTUAL
2 parents 93bbca2 + c0e1c8c commit 7561393

File tree

7 files changed

+37
-20
lines changed

7 files changed

+37
-20
lines changed

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

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -205,10 +205,6 @@ static inline void pmd_clear(pmd_t *pmdp)
205205
*pmdp = __pmd(0);
206206
}
207207

208-
/* to find an entry in a page-table-directory */
209-
#define pgd_index(address) ((address) >> PGDIR_SHIFT)
210-
#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
211-
212208
/*
213209
* PTE updates. This function is called whenever an existing
214210
* valid PTE is updated. This does -not- include set_pte_at()
@@ -230,14 +226,16 @@ static inline void pmd_clear(pmd_t *pmdp)
230226
* For other page sizes, we have a single entry in the table.
231227
*/
232228
#ifdef CONFIG_PPC_8xx
229+
static pmd_t *pmd_off(struct mm_struct *mm, unsigned long addr);
230+
233231
static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
234232
unsigned long clr, unsigned long set, int huge)
235233
{
236234
pte_basic_t *entry = &p->pte;
237235
pte_basic_t old = pte_val(*p);
238236
pte_basic_t new = (old & ~(pte_basic_t)clr) | set;
239237
int num, i;
240-
pmd_t *pmd = pmd_offset(pud_offset(p4d_offset(pgd_offset(mm, addr), addr), addr), addr);
238+
pmd_t *pmd = pmd_off(mm, addr);
241239

242240
if (!huge)
243241
num = PAGE_SIZE / SZ_4K;
@@ -286,6 +284,16 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
286284
return __pte(pte_update(mm, addr, ptep, ~0, 0, 0));
287285
}
288286

287+
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
288+
#define __HAVE_ARCH_PTEP_GET
289+
static inline pte_t ptep_get(pte_t *ptep)
290+
{
291+
pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
292+
293+
return pte;
294+
}
295+
#endif
296+
289297
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
290298
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
291299
pte_t *ptep)

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -270,7 +270,7 @@ BEGIN_FTR_SECTION
270270
END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
271271
.endif
272272

273-
ld r10,PACA_EXGEN+EX_CTR(r13)
273+
ld r10,IAREA+EX_CTR(r13)
274274
mtctr r10
275275
BEGIN_FTR_SECTION
276276
ld r10,IAREA+EX_PPR(r13)
@@ -298,7 +298,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
298298

299299
.if IKVM_SKIP
300300
89: mtocrf 0x80,r9
301-
ld r10,PACA_EXGEN+EX_CTR(r13)
301+
ld r10,IAREA+EX_CTR(r13)
302302
mtctr r10
303303
ld r9,IAREA+EX_R9(r13)
304304
ld r10,IAREA+EX_R10(r13)

arch/powerpc/kernel/process.c

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1252,29 +1252,31 @@ struct task_struct *__switch_to(struct task_struct *prev,
12521252
static void show_instructions(struct pt_regs *regs)
12531253
{
12541254
int i;
1255+
unsigned long nip = regs->nip;
12551256
unsigned long pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int));
12561257

12571258
printk("Instruction dump:");
12581259

1260+
/*
1261+
* If we were executing with the MMU off for instructions, adjust pc
1262+
* rather than printing XXXXXXXX.
1263+
*/
1264+
if (!IS_ENABLED(CONFIG_BOOKE) && !(regs->msr & MSR_IR)) {
1265+
pc = (unsigned long)phys_to_virt(pc);
1266+
nip = (unsigned long)phys_to_virt(regs->nip);
1267+
}
1268+
12591269
for (i = 0; i < NR_INSN_TO_PRINT; i++) {
12601270
int instr;
12611271

12621272
if (!(i % 8))
12631273
pr_cont("\n");
12641274

1265-
#if !defined(CONFIG_BOOKE)
1266-
/* If executing with the IMMU off, adjust pc rather
1267-
* than print XXXXXXXX.
1268-
*/
1269-
if (!(regs->msr & MSR_IR))
1270-
pc = (unsigned long)phys_to_virt(pc);
1271-
#endif
1272-
12731275
if (!__kernel_text_address(pc) ||
12741276
get_kernel_nofault(instr, (const void *)pc)) {
12751277
pr_cont("XXXXXXXX ");
12761278
} else {
1277-
if (regs->nip == pc)
1279+
if (nip == pc)
12781280
pr_cont("<%08x> ", instr);
12791281
else
12801282
pr_cont("%08x ", instr);

arch/powerpc/platforms/cell/spu_callbacks.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
*/
3636

3737
static void *spu_syscall_table[] = {
38-
#define __SYSCALL(nr, entry) entry,
38+
#define __SYSCALL(nr, entry) [nr] = entry,
3939
#include <asm/syscall_table_spu.h>
4040
#undef __SYSCALL
4141
};

include/asm-generic/hugetlb.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
122122
#ifndef __HAVE_ARCH_HUGE_PTEP_GET
123123
static inline pte_t huge_ptep_get(pte_t *ptep)
124124
{
125-
return READ_ONCE(*ptep);
125+
return ptep_get(ptep);
126126
}
127127
#endif
128128

include/linux/pgtable.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,13 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
249249
}
250250
#endif
251251

252+
#ifndef __HAVE_ARCH_PTEP_GET
253+
static inline pte_t ptep_get(pte_t *ptep)
254+
{
255+
return READ_ONCE(*ptep);
256+
}
257+
#endif
258+
252259
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
253260
#ifndef __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
254261
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,

mm/gup.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2196,7 +2196,7 @@ static inline pte_t gup_get_pte(pte_t *ptep)
21962196
*/
21972197
static inline pte_t gup_get_pte(pte_t *ptep)
21982198
{
2199-
return READ_ONCE(*ptep);
2199+
return ptep_get(ptep);
22002200
}
22012201
#endif /* CONFIG_GUP_GET_PTE_LOW_HIGH */
22022202

@@ -2425,7 +2425,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
24252425
if (pte_end < end)
24262426
end = pte_end;
24272427

2428-
pte = READ_ONCE(*ptep);
2428+
pte = huge_ptep_get(ptep);
24292429

24302430
if (!pte_access_permitted(pte, flags & FOLL_WRITE))
24312431
return 0;

0 commit comments

Comments
 (0)