mirror of
https://github.com/torvalds/linux.git
synced 2026-09-22 04:34:03 +02:00
powerpc fixes for 7.2 #3
- Ensure vpa,slb_shadow & dtl are unregistered during crash - fix nap return address corruption on async interrupt exit in 970 platform - Fix exit_flags field placement in pt_regs for ptrace - Fix map failure path in dma_ioc0_map_pages() in ps3 platfrom - MAINTAINERS: Demote myself to reviewer - misc fixes and cleanup Thanks to: Amit Machhiwal, Andreas Schwab, Anushree Mathur, Athira Rajeev, Christophe Leroy (CS GROUP), Dmitry V. Levin, Geert Uytterhoeven, John Ogness, Michael Ellerman, Mukesh Kumar Chaurasiya (IBM), Ritesh Harjani (IBM), Thorsten Blum, Vaibhav Jain -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEqX2DNAOgU8sBX3pRpnEsdPSHZJQFAmpq5/gACgkQpnEsdPSH ZJR3NQ//d2RIqe/XzW6VOoU0k0KS0mldkj8B8pykkO1XgsWRirJNdq4l+/DNwfsq OpIaB7dHoDQP8NIbruYC6tDnDLsEpaQMR6SIr2EeH4H5xHQWUKLiFRQMKOhdzujy MHc6EzazEFjW2/ItbcxLOkW8+zhP5K02Zwmj/sF9hsSKFTq4dAnc9LX8OunJfEbz /JTXS+SK+Z4BQmDlL22b5rEk432zFtvE33Dw0401Vdsn3x/dEKpynlc1LTdbHJXL rkmt3Kc41SnQlFBSO2NzKs6lzz1kQYSC3DdlYOwQ1evvBNqdhzMotg0jKOXFC3C7 m4FbJKpQjTXHhtJZx4+Vrr5k4MFp6fUg5LIbe+rBeN8Ckgk3Yj7qCw8UVjlXyUTp KlkqG6J1Eteg3KMGQClZzZz0kyqWrSsnO7eR8O41wSRmAv27vBxsn9nOKBHcV9Cq gzG0IJTIP+4/qTbXhUjBQLlgRpoCjz5UnmAbisKHBXGUI+wz58Uhf2b8/M53RH1b qnrb81Vp6nLEtPJrjRXeCwYnTRT4qQ8ON9PB1uAIImG8phdxfsfhTivftLJVQqUA DGjFNLpbME2WbyLd0YxDj8jzHp1845/vR+jwyHMQAoQHFJjvAf4/RZ58zKVUtFVR susxnX6YodNMfZisVwcZTaj1pds8YSz72gOE44Qn0K3YjqAej9w= =On4C -----END PGP SIGNATURE----- Merge tag 'powerpc-7.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux Pull powerpc fixes from Madhavan Srinivasan: - ensure vpa,slb_shadow & dtl are unregistered during crash - fix nap return address corruption on async interrupt exit in 970 platform - fix exit_flags field placement in pt_regs for ptrace - fix map failure path in dma_ioc0_map_pages() in ps3 platfrom - MAINTAINERS: Michael Ellerman demotes himself to reviewer - misc fixes and cleanup Thanks to Amit Machhiwal, Andreas Schwab, Anushree Mathur, Athira Rajeev, Christophe Leroy (CS GROUP), Dmitry V. Levin, Geert Uytterhoeven, John Ogness, Michael Ellerman, Mukesh Kumar Chaurasiya (IBM), Ritesh Harjani (IBM), Thorsten Blum, and Vaibhav Jain * tag 'powerpc-7.2-3' of git://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux: MAINTAINERS: Demote myself to reviewer powerpc/serial: Fix include guard comment powerpc/perf: Use strstarts() to simplify is_thread_imc_pmu() powerpc/ps3: Fix map failure path in dma_ioc0_map_pages() powerpc/ps3: Remove unused struct table in setup_areas() powerpc/boot: Fix treeboot-akebono CPU node lookup check powerpc/boot: Fix treeboot-currituck CPU node lookup check powerpc/boot: Fix simpleboot CPU node lookup check powerpc: Fix exit_flags field placement in pt_regs for ptrace powerpc/970: fix nap return address corruption on async interrupt exit powerpc/pseries: Skip vpa_init() for boot cpu in smp_setup_cpu() powerpc/pseries: Ensure vpa,slb_shadow & dtl are unregistered during crash
This commit is contained in:
commit
b96890b3e5
|
|
@ -14887,7 +14887,7 @@ X: drivers/macintosh/via-macii.c
|
|||
|
||||
LINUX FOR POWERPC (32-BIT AND 64-BIT)
|
||||
M: Madhavan Srinivasan <maddy@linux.ibm.com>
|
||||
M: Michael Ellerman <mpe@ellerman.id.au>
|
||||
R: Michael Ellerman <mpe@ellerman.id.au>
|
||||
R: Nicholas Piggin <npiggin@gmail.com>
|
||||
R: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
|
||||
L: linuxppc-dev@lists.ozlabs.org
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
|
|||
/* finally, setup the timebase */
|
||||
node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
|
||||
"cpu", sizeof("cpu"));
|
||||
if (!node)
|
||||
if (node < 0)
|
||||
fatal("Cannot find cpu node\n");
|
||||
timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
|
||||
if (timebase && (size == 4))
|
||||
|
|
|
|||
|
|
@ -146,7 +146,7 @@ void platform_init(char *userdata)
|
|||
|
||||
node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
|
||||
"cpu", sizeof("cpu"));
|
||||
if (!node)
|
||||
if (node < 0)
|
||||
fatal("Cannot find cpu node\n");
|
||||
timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
|
||||
if (timebase && (size == 4))
|
||||
|
|
|
|||
|
|
@ -102,7 +102,7 @@ void platform_init(void)
|
|||
|
||||
node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
|
||||
"cpu", sizeof("cpu"));
|
||||
if (!node)
|
||||
if (node < 0)
|
||||
fatal("Cannot find cpu node\n");
|
||||
timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
|
||||
if (timebase && (size == 4))
|
||||
|
|
|
|||
|
|
@ -66,6 +66,13 @@ static inline void srr_regs_clobbered(void)
|
|||
static inline void nap_adjust_return(struct pt_regs *regs)
|
||||
{
|
||||
#ifdef CONFIG_PPC_970_NAP
|
||||
/*
|
||||
* Adjust the nap return address before irq_exit_rcu(). irq_exit_rcu()
|
||||
* may invoke softirqs with interrupts re-enabled, allowing a nested
|
||||
* async interrupt to arrive. If _TLF_NAPPING is still set at that
|
||||
* point, the nested interrupt would erroneously redirect its own
|
||||
* return address to power4_idle_nap_return, corrupting the stack.
|
||||
*/
|
||||
if (unlikely(test_thread_local_flags(_TLF_NAPPING))) {
|
||||
/* Can avoid a test-and-clear because NMIs do not call this */
|
||||
clear_thread_local_flags(_TLF_NAPPING);
|
||||
|
|
@ -286,14 +293,6 @@ static inline void arch_interrupt_async_enter_prepare(struct pt_regs *regs)
|
|||
|
||||
static inline void arch_interrupt_async_exit_prepare(struct pt_regs *regs)
|
||||
{
|
||||
/*
|
||||
* Adjust at exit so the main handler sees the true NIA. This must
|
||||
* come before irq_exit() because irq_exit can enable interrupts, and
|
||||
* if another interrupt is taken before nap_adjust_return has run
|
||||
* here, then that interrupt would return directly to idle nap return.
|
||||
*/
|
||||
nap_adjust_return(regs);
|
||||
|
||||
arch_interrupt_exit_prepare(regs);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -246,6 +246,7 @@ interrupt_handler void func(struct pt_regs *regs) \
|
|||
instrumentation_begin(); \
|
||||
irq_enter_rcu(); \
|
||||
____##func (regs); \
|
||||
nap_adjust_return(regs); \
|
||||
irq_exit_rcu(); \
|
||||
instrumentation_end(); \
|
||||
arch_interrupt_async_exit_prepare(regs); \
|
||||
|
|
|
|||
|
|
@ -53,9 +53,6 @@ struct pt_regs
|
|||
unsigned long esr;
|
||||
};
|
||||
unsigned long result;
|
||||
unsigned long exit_flags;
|
||||
/* Maintain 16 byte interrupt stack alignment */
|
||||
unsigned long __pt_regs_pad[3];
|
||||
};
|
||||
};
|
||||
#if defined(CONFIG_PPC64) || defined(CONFIG_PPC_KUAP)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,4 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
/*
|
||||
*/
|
||||
#ifndef _ASM_POWERPC_SERIAL_H
|
||||
#define _ASM_POWERPC_SERIAL_H
|
||||
|
||||
|
|
@ -18,4 +16,4 @@ extern void find_legacy_serial_ports(void);
|
|||
#define find_legacy_serial_ports() do { } while (0)
|
||||
#endif
|
||||
|
||||
#endif /* _PPC64_SERIAL_H */
|
||||
#endif /* _ASM_POWERPC_SERIAL_H */
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ struct thread_info {
|
|||
#ifdef CONFIG_SMP
|
||||
unsigned int cpu;
|
||||
#endif
|
||||
unsigned long exit_flags; /* Exit Flags for entry/exit */
|
||||
unsigned long syscall_work; /* SYSCALL_WORK_ flags */
|
||||
unsigned long local_flags; /* private flags for thread */
|
||||
#ifdef CONFIG_LIVEPATCH_64
|
||||
|
|
|
|||
|
|
@ -55,8 +55,6 @@ struct pt_regs
|
|||
unsigned long dar; /* Fault registers */
|
||||
unsigned long dsisr; /* on 4xx/Book-E used for ESR */
|
||||
unsigned long result; /* Result of a system call */
|
||||
unsigned long exit_flags; /* System call exit flags */
|
||||
unsigned long __pt_regs_pad[3]; /* Maintain 16 byte interrupt stack alignment */
|
||||
};
|
||||
|
||||
#endif /* __ASSEMBLER__ */
|
||||
|
|
@ -116,12 +114,10 @@ struct pt_regs
|
|||
#define PT_DAR 41
|
||||
#define PT_DSISR 42
|
||||
#define PT_RESULT 43
|
||||
#define PT_EXIT_FLAGS 44
|
||||
#define PT_PAD 47 /* 3 times */
|
||||
#define PT_DSCR 48
|
||||
#define PT_REGS_COUNT 48
|
||||
#define PT_DSCR 44
|
||||
#define PT_REGS_COUNT 44
|
||||
|
||||
#define PT_FPR0 (PT_REGS_COUNT + 4) /* each FP reg occupies 2 slots in this space */
|
||||
#define PT_FPR0 48 /* each FP reg occupies 2 slots in this space */
|
||||
|
||||
#ifndef __powerpc64__
|
||||
|
||||
|
|
@ -133,7 +129,7 @@ struct pt_regs
|
|||
#define PT_FPSCR (PT_FPR0 + 32) /* each FP reg occupies 1 slot in 64-bit space */
|
||||
|
||||
|
||||
#define PT_VR0 (PT_FPSCR + 2) /* <82> each Vector reg occupies 2 slots in 64-bit */
|
||||
#define PT_VR0 82 /* each Vector reg occupies 2 slots in 64-bit */
|
||||
#define PT_VSCR (PT_VR0 + 32*2 + 1)
|
||||
#define PT_VRSAVE (PT_VR0 + 33*2)
|
||||
|
||||
|
|
@ -141,7 +137,7 @@ struct pt_regs
|
|||
/*
|
||||
* Only store first 32 VSRs here. The second 32 VSRs in VR0-31
|
||||
*/
|
||||
#define PT_VSR0 (PT_VRSAVE + 2) /* each VSR reg occupies 2 slots in 64-bit */
|
||||
#define PT_VSR0 150 /* each VSR reg occupies 2 slots in 64-bit */
|
||||
#define PT_VSR31 (PT_VSR0 + 2*31)
|
||||
#endif /* __powerpc64__ */
|
||||
|
||||
|
|
|
|||
|
|
@ -89,15 +89,17 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3,
|
|||
long scv)
|
||||
{
|
||||
unsigned long ti_flags;
|
||||
unsigned long ret = 0;
|
||||
bool is_not_scv = !IS_ENABLED(CONFIG_PPC_BOOK3S_64) || !scv;
|
||||
|
||||
kuap_assert_locked();
|
||||
|
||||
regs->result = r3;
|
||||
regs->exit_flags = 0;
|
||||
|
||||
/* Clear exit_flags so only flags set during this exit are visible */
|
||||
current->thread_info.exit_flags = 0;
|
||||
|
||||
ti_flags = read_thread_flags();
|
||||
|
||||
if (unlikely(r3 >= (unsigned long)-MAX_ERRNO) && is_not_scv) {
|
||||
if (likely(!(ti_flags & (_TIF_NOERROR | _TIF_RESTOREALL)))) {
|
||||
r3 = -r3;
|
||||
|
|
@ -107,7 +109,7 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3,
|
|||
|
||||
if (unlikely(ti_flags & _TIF_PERSYSCALL_MASK)) {
|
||||
if (ti_flags & _TIF_RESTOREALL)
|
||||
regs->exit_flags = _TIF_RESTOREALL;
|
||||
ret = _TIF_RESTOREALL;
|
||||
else
|
||||
regs->gpr[3] = r3;
|
||||
clear_bits(_TIF_PERSYSCALL_MASK, ¤t_thread_info()->flags);
|
||||
|
|
@ -116,7 +118,7 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3,
|
|||
}
|
||||
|
||||
if (unlikely(ti_flags & _TIF_SYSCALL_DOTRACE)) {
|
||||
regs->exit_flags |= _TIF_RESTOREALL;
|
||||
ret |= _TIF_RESTOREALL;
|
||||
}
|
||||
|
||||
syscall_exit_to_user_mode(regs);
|
||||
|
|
@ -132,17 +134,19 @@ notrace unsigned long syscall_exit_prepare(unsigned long r3,
|
|||
|
||||
/* Restore user access locks last */
|
||||
kuap_user_restore(regs);
|
||||
|
||||
ret |= current->thread_info.exit_flags;
|
||||
#ifdef CONFIG_PPC64
|
||||
regs->exit_result = regs->exit_flags;
|
||||
regs->exit_result = ret;
|
||||
#endif
|
||||
|
||||
return regs->exit_flags;
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PPC64
|
||||
notrace unsigned long syscall_exit_restart(unsigned long r3, struct pt_regs *regs)
|
||||
{
|
||||
unsigned long ret;
|
||||
|
||||
/*
|
||||
* This is called when detecting a soft-pending interrupt as well as
|
||||
* an alternate-return interrupt. So we can't just have the alternate
|
||||
|
|
@ -167,9 +171,11 @@ notrace unsigned long syscall_exit_restart(unsigned long r3, struct pt_regs *reg
|
|||
}
|
||||
|
||||
kuap_user_restore(regs);
|
||||
regs->exit_result |= regs->exit_flags;
|
||||
ret = current_thread_info()->exit_flags & _TIF_RESTOREALL;
|
||||
current_thread_info()->exit_flags &= ~_TIF_RESTOREALL;
|
||||
regs->exit_result |= ret;
|
||||
|
||||
return regs->exit_result;
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
@ -186,8 +192,10 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs)
|
|||
*/
|
||||
kuap_assert_locked();
|
||||
|
||||
/* Clear exit_flags so only flags set during this exit are visible */
|
||||
current_thread_info()->exit_flags = 0;
|
||||
|
||||
local_irq_disable();
|
||||
regs->exit_flags = 0;
|
||||
again:
|
||||
check_return_regs_valid(regs);
|
||||
user_enter_irqoff();
|
||||
|
|
@ -200,9 +208,7 @@ notrace unsigned long interrupt_exit_user_prepare(struct pt_regs *regs)
|
|||
|
||||
/* Restore user access locks last */
|
||||
kuap_user_restore(regs);
|
||||
|
||||
ret = regs->exit_flags;
|
||||
|
||||
ret = current_thread_info()->exit_flags & _TIF_RESTOREALL;
|
||||
#ifdef CONFIG_PPC64
|
||||
regs->exit_result = ret;
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -291,7 +291,6 @@ void __init pt_regs_check(void)
|
|||
CHECK_REG(PT_DAR, dar);
|
||||
CHECK_REG(PT_DSISR, dsisr);
|
||||
CHECK_REG(PT_RESULT, result);
|
||||
CHECK_REG(PT_EXIT_FLAGS, exit_flags);
|
||||
#undef CHECK_REG
|
||||
|
||||
BUILD_BUG_ON(PT_REGS_COUNT != sizeof(struct user_pt_regs) / sizeof(unsigned long));
|
||||
|
|
|
|||
|
|
@ -356,6 +356,6 @@ void signal_fault(struct task_struct *tsk, struct pt_regs *regs,
|
|||
void arch_do_signal_or_restart(struct pt_regs *regs)
|
||||
{
|
||||
BUG_ON(regs != current->thread.regs);
|
||||
regs->exit_flags |= _TIF_RESTOREALL;
|
||||
current_thread_info()->exit_flags |= _TIF_RESTOREALL;
|
||||
do_signal(current);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1023,10 +1023,7 @@ static int thread_imc_event_init(struct perf_event *event)
|
|||
|
||||
static bool is_thread_imc_pmu(struct perf_event *event)
|
||||
{
|
||||
if (!strncmp(event->pmu->name, "thread_imc", strlen("thread_imc")))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
return strstarts(event->pmu->name, "thread_imc");
|
||||
}
|
||||
|
||||
static __be64 *get_event_base_addr(struct perf_event *event)
|
||||
|
|
|
|||
|
|
@ -615,6 +615,7 @@ static int dma_ioc0_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
|
|||
|
||||
fail_map:
|
||||
for (iopage--; 0 <= iopage; iopage--) {
|
||||
offset = (1 << r->page_size) * iopage;
|
||||
lv1_put_iopte(0,
|
||||
c->bus_addr + offset,
|
||||
c->lpar_addr + offset,
|
||||
|
|
|
|||
|
|
@ -191,8 +191,6 @@ static void spu_unmap(struct spu *spu)
|
|||
|
||||
static int __init setup_areas(struct spu *spu)
|
||||
{
|
||||
struct table {char* name; unsigned long addr; unsigned long size;};
|
||||
|
||||
spu_pdata(spu)->shadow = ioremap_prot(spu_pdata(spu)->shadow_addr,
|
||||
sizeof(struct spe_shadow),
|
||||
pgprot_noncached_wc(PAGE_KERNEL_RO));
|
||||
|
|
|
|||
|
|
@ -20,12 +20,15 @@
|
|||
void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
|
||||
{
|
||||
/*
|
||||
* Don't risk a hypervisor call if we're crashing
|
||||
* XXX: Why? The hypervisor is not crashing. It might be better
|
||||
* to at least attempt unregister to avoid the hypervisor stepping
|
||||
* on our memory.
|
||||
* Ensure vpa/slb_shadow/dtl cleanup even while we are crashing.
|
||||
* Why? The hypervisor is not crashing so at least attempt unregister to
|
||||
* avoid the hypervisor stepping on our memory. If hypervisor or kexec
|
||||
* kernel steps on the old memory allocated to these areas before the
|
||||
* new kexec-kernel happens to allocate and register new areas,
|
||||
* the hypervisor will see invalid content which may cause
|
||||
* unexpected behavior.
|
||||
*/
|
||||
if (firmware_has_feature(FW_FEATURE_SPLPAR) && !crash_shutdown) {
|
||||
if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
|
||||
int ret;
|
||||
int cpu = smp_processor_id();
|
||||
int hwcpu = hard_smp_processor_id();
|
||||
|
|
|
|||
|
|
@ -128,7 +128,12 @@ static void smp_setup_cpu(int cpu)
|
|||
else if (cpu != boot_cpuid)
|
||||
xics_setup_cpu();
|
||||
|
||||
if (firmware_has_feature(FW_FEATURE_SPLPAR))
|
||||
/*
|
||||
* Initialize VPA on non-boot cpus since boot-cpu vpa was
|
||||
* already initialized in pSeries_setup_arch()
|
||||
*/
|
||||
if (firmware_has_feature(FW_FEATURE_SPLPAR) &&
|
||||
cpu != boot_cpuid)
|
||||
vpa_init(cpu);
|
||||
|
||||
cpumask_clear_cpu(cpu, of_spin_mask);
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user