powerpc fixes for 5.8 #3
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. -----BEGIN PGP SIGNATURE----- iQJHBAABCAAxFiEEJFGtCPCthwEv2Y/bUevqPMjhpYAFAl7vNVsTHG1wZUBlbGxl cm1hbi5pZC5hdQAKCRBR6+o8yOGlgO3rD/46cXJQ9AMQqtZh3+sgWu95Zd6JOviL vfhWeH/kbt/p6OGPoLXoYChoFD44Mf7BmTEDflslYICrxvhu9zI2lYN+948zfrEY lIjjP+Dd6fr1D2o3+hnOOX/LHAVyyZJTsZp5i6ehTOXeUw8KOCF1ulVB3o5GgQK0 I/0oewL/SXNFnZS5qLgF2/OFS/BH3OnDG6mpICxCetZC9mNbHrTzos403ijyrvcX AsE4JSzI2UM9kT0pWXLa9QR3RgfBZ4wtMrnKAwdGI/E+YqAa7TuHZatPDAqoCJYY aePEZdweaeLWHQaQYSqlNP7YLAHuSdvZ2SvU65c2EKaaXug9sZJImyboJl/fo0Xo EtZiVbfaTfqsyi7EVQnsLMFYmtquacXoUH//nIoTro4pRkeMsM94BiK2HISa+8Bs KGQxBsnK2UaTgWERZHiK2VaKY/Tl1vGs09u7R21GiE2aD25ly+/q1Uo+WUr6iRKh 1v42AsH1VCeEZKAog43gBGOr7bCez8/90GNtTJnKTKndSRSybCH68ME/zBKdNACn A7M9E0CNNjTOQNJyQ2UhyiBJzUK6kT/5g+C4mEH5WG4FkO6YHT1JyEusvsfj6Oe9 RwDr98iNuM8AhaT30XmUXithDAl6JA5+3S0OcC2bL2xQ0O/VBPGZhIzgSFU8T7BY qpDj8l/8zk64Fw== =qws5 -----END PGP SIGNATURE----- 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:
commit
7561393908
|
@ -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,
|
||||
|
|
4
mm/gup.c
4
mm/gup.c
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue