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
This commit is contained in:
@@ -205,10 +205,6 @@ static inline void pmd_clear(pmd_t *pmdp)
|
||||
*pmdp = __pmd(0);
|
||||
}
|
||||
|
||||
/* to find an entry in a page-table-directory */
|
||||
#define pgd_index(address) ((address) >> PGDIR_SHIFT)
|
||||
#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address))
|
||||
|
||||
/*
|
||||
* PTE updates. This function is called whenever an existing
|
||||
* valid PTE is updated. This does -not- include set_pte_at()
|
||||
@@ -230,6 +226,8 @@ static inline void pmd_clear(pmd_t *pmdp)
|
||||
* For other page sizes, we have a single entry in the table.
|
||||
*/
|
||||
#ifdef CONFIG_PPC_8xx
|
||||
static pmd_t *pmd_off(struct mm_struct *mm, unsigned long addr);
|
||||
|
||||
static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, pte_t *p,
|
||||
unsigned long clr, unsigned long set, int huge)
|
||||
{
|
||||
@@ -237,7 +235,7 @@ static inline pte_basic_t pte_update(struct mm_struct *mm, unsigned long addr, p
|
||||
pte_basic_t old = pte_val(*p);
|
||||
pte_basic_t new = (old & ~(pte_basic_t)clr) | set;
|
||||
int num, i;
|
||||
pmd_t *pmd = pmd_offset(pud_offset(p4d_offset(pgd_offset(mm, addr), addr), addr), addr);
|
||||
pmd_t *pmd = pmd_off(mm, addr);
|
||||
|
||||
if (!huge)
|
||||
num = PAGE_SIZE / SZ_4K;
|
||||
@@ -286,6 +284,16 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr,
|
||||
return __pte(pte_update(mm, addr, ptep, ~0, 0, 0));
|
||||
}
|
||||
|
||||
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PPC_16K_PAGES)
|
||||
#define __HAVE_ARCH_PTEP_GET
|
||||
static inline pte_t ptep_get(pte_t *ptep)
|
||||
{
|
||||
pte_t pte = {READ_ONCE(ptep->pte), 0, 0, 0};
|
||||
|
||||
return pte;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define __HAVE_ARCH_PTEP_SET_WRPROTECT
|
||||
static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep)
|
||||
|
||||
@@ -270,7 +270,7 @@ BEGIN_FTR_SECTION
|
||||
END_FTR_SECTION_IFSET(CPU_FTR_CFAR)
|
||||
.endif
|
||||
|
||||
ld r10,PACA_EXGEN+EX_CTR(r13)
|
||||
ld r10,IAREA+EX_CTR(r13)
|
||||
mtctr r10
|
||||
BEGIN_FTR_SECTION
|
||||
ld r10,IAREA+EX_PPR(r13)
|
||||
@@ -298,7 +298,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_HAS_PPR)
|
||||
|
||||
.if IKVM_SKIP
|
||||
89: mtocrf 0x80,r9
|
||||
ld r10,PACA_EXGEN+EX_CTR(r13)
|
||||
ld r10,IAREA+EX_CTR(r13)
|
||||
mtctr r10
|
||||
ld r9,IAREA+EX_R9(r13)
|
||||
ld r10,IAREA+EX_R10(r13)
|
||||
|
||||
@@ -1252,29 +1252,31 @@ struct task_struct *__switch_to(struct task_struct *prev,
|
||||
static void show_instructions(struct pt_regs *regs)
|
||||
{
|
||||
int i;
|
||||
unsigned long nip = regs->nip;
|
||||
unsigned long pc = regs->nip - (NR_INSN_TO_PRINT * 3 / 4 * sizeof(int));
|
||||
|
||||
printk("Instruction dump:");
|
||||
|
||||
/*
|
||||
* If we were executing with the MMU off for instructions, adjust pc
|
||||
* rather than printing XXXXXXXX.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_BOOKE) && !(regs->msr & MSR_IR)) {
|
||||
pc = (unsigned long)phys_to_virt(pc);
|
||||
nip = (unsigned long)phys_to_virt(regs->nip);
|
||||
}
|
||||
|
||||
for (i = 0; i < NR_INSN_TO_PRINT; i++) {
|
||||
int instr;
|
||||
|
||||
if (!(i % 8))
|
||||
pr_cont("\n");
|
||||
|
||||
#if !defined(CONFIG_BOOKE)
|
||||
/* If executing with the IMMU off, adjust pc rather
|
||||
* than print XXXXXXXX.
|
||||
*/
|
||||
if (!(regs->msr & MSR_IR))
|
||||
pc = (unsigned long)phys_to_virt(pc);
|
||||
#endif
|
||||
|
||||
if (!__kernel_text_address(pc) ||
|
||||
get_kernel_nofault(instr, (const void *)pc)) {
|
||||
pr_cont("XXXXXXXX ");
|
||||
} else {
|
||||
if (regs->nip == pc)
|
||||
if (nip == pc)
|
||||
pr_cont("<%08x> ", instr);
|
||||
else
|
||||
pr_cont("%08x ", instr);
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
*/
|
||||
|
||||
static void *spu_syscall_table[] = {
|
||||
#define __SYSCALL(nr, entry) entry,
|
||||
#define __SYSCALL(nr, entry) [nr] = entry,
|
||||
#include <asm/syscall_table_spu.h>
|
||||
#undef __SYSCALL
|
||||
};
|
||||
|
||||
@@ -122,7 +122,7 @@ static inline int huge_ptep_set_access_flags(struct vm_area_struct *vma,
|
||||
#ifndef __HAVE_ARCH_HUGE_PTEP_GET
|
||||
static inline pte_t huge_ptep_get(pte_t *ptep)
|
||||
{
|
||||
return READ_ONCE(*ptep);
|
||||
return ptep_get(ptep);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -249,6 +249,13 @@ static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_PTEP_GET
|
||||
static inline pte_t ptep_get(pte_t *ptep)
|
||||
{
|
||||
return READ_ONCE(*ptep);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
#ifndef __HAVE_ARCH_PMDP_HUGE_GET_AND_CLEAR
|
||||
static inline pmd_t pmdp_huge_get_and_clear(struct mm_struct *mm,
|
||||
|
||||
@@ -2196,7 +2196,7 @@ static inline pte_t gup_get_pte(pte_t *ptep)
|
||||
*/
|
||||
static inline pte_t gup_get_pte(pte_t *ptep)
|
||||
{
|
||||
return READ_ONCE(*ptep);
|
||||
return ptep_get(ptep);
|
||||
}
|
||||
#endif /* CONFIG_GUP_GET_PTE_LOW_HIGH */
|
||||
|
||||
@@ -2425,7 +2425,7 @@ static int gup_hugepte(pte_t *ptep, unsigned long sz, unsigned long addr,
|
||||
if (pte_end < end)
|
||||
end = pte_end;
|
||||
|
||||
pte = READ_ONCE(*ptep);
|
||||
pte = huge_ptep_get(ptep);
|
||||
|
||||
if (!pte_access_permitted(pte, flags & FOLL_WRITE))
|
||||
return 0;
|
||||
|
||||
Reference in New Issue
Block a user