linuxppc-dev.lists.ozlabs.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/4] powerpc: misc interrupt and context tracking fixes
@ 2022-10-06 14:04 Nicholas Piggin
  2022-10-06 14:04 ` [PATCH 1/4] KVM: PPC: BookS PR-KVM and BookE do not support context tracking Nicholas Piggin
                   ` (4 more replies)
  0 siblings, 5 replies; 6+ messages in thread
From: Nicholas Piggin @ 2022-10-06 14:04 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

These are several fixes for regressions and bugs that can crash
the host.

Thanks,
Nick

Nicholas Piggin (4):
  KVM: PPC: BookS PR-KVM and BookE do not support context tracking
  powerpc/64s/interrupt: Perf NMI should not take normal exit path
  powerpc/64e/interrupt: Prevent NMI PMI causing a dangerous warning
  powerpc/64: Fix perf profiling asynchronous interrupt handlers

 arch/powerpc/include/asm/hw_irq.h    | 41 ++++++++++++++++++++--------
 arch/powerpc/kernel/dbell.c          |  2 +-
 arch/powerpc/kernel/exceptions-64e.S |  7 +++++
 arch/powerpc/kernel/exceptions-64s.S | 14 +++++++++-
 arch/powerpc/kernel/interrupt.c      | 13 +++++++--
 arch/powerpc/kernel/irq.c            |  2 +-
 arch/powerpc/kernel/time.c           |  2 +-
 arch/powerpc/kernel/traps.c          |  2 --
 arch/powerpc/kvm/Kconfig             |  4 +++
 9 files changed, 66 insertions(+), 21 deletions(-)

-- 
2.37.2


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [PATCH 1/4] KVM: PPC: BookS PR-KVM and BookE do not support context tracking
  2022-10-06 14:04 [PATCH 0/4] powerpc: misc interrupt and context tracking fixes Nicholas Piggin
@ 2022-10-06 14:04 ` Nicholas Piggin
  2022-10-06 14:04 ` [PATCH 2/4] powerpc/64s/interrupt: Perf NMI should not take normal exit path Nicholas Piggin
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Nicholas Piggin @ 2022-10-06 14:04 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

The context tracking code in PR-KVM and BookE implementations is not
complete, and can cause host crashes if context tracking is enabled.

Make these implementations depend on !CONTEXT_TRACKING_USER.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/kvm/Kconfig | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig
index 61cdd782d3c5..a9f57dad6d91 100644
--- a/arch/powerpc/kvm/Kconfig
+++ b/arch/powerpc/kvm/Kconfig
@@ -51,6 +51,7 @@ config KVM_BOOK3S_HV_POSSIBLE
 config KVM_BOOK3S_32
 	tristate "KVM support for PowerPC book3s_32 processors"
 	depends on PPC_BOOK3S_32 && !SMP && !PTE_64BIT
+	depends on !CONTEXT_TRACKING_USER
 	select KVM
 	select KVM_BOOK3S_32_HANDLER
 	select KVM_BOOK3S_PR_POSSIBLE
@@ -105,6 +106,7 @@ config KVM_BOOK3S_64_HV
 config KVM_BOOK3S_64_PR
 	tristate "KVM support without using hypervisor mode in host"
 	depends on KVM_BOOK3S_64
+	depends on !CONTEXT_TRACKING_USER
 	select KVM_BOOK3S_PR_POSSIBLE
 	help
 	  Support running guest kernels in virtual machines on processors
@@ -190,6 +192,7 @@ config KVM_EXIT_TIMING
 config KVM_E500V2
 	bool "KVM support for PowerPC E500v2 processors"
 	depends on PPC_E500 && !PPC_E500MC
+	depends on !CONTEXT_TRACKING_USER
 	select KVM
 	select KVM_MMIO
 	select MMU_NOTIFIER
@@ -205,6 +208,7 @@ config KVM_E500V2
 config KVM_E500MC
 	bool "KVM support for PowerPC E500MC/E5500/E6500 processors"
 	depends on PPC_E500MC
+	depends on !CONTEXT_TRACKING_USER
 	select KVM
 	select KVM_MMIO
 	select KVM_BOOKE_HV
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/4] powerpc/64s/interrupt: Perf NMI should not take normal exit path
  2022-10-06 14:04 [PATCH 0/4] powerpc: misc interrupt and context tracking fixes Nicholas Piggin
  2022-10-06 14:04 ` [PATCH 1/4] KVM: PPC: BookS PR-KVM and BookE do not support context tracking Nicholas Piggin
@ 2022-10-06 14:04 ` Nicholas Piggin
  2022-10-06 14:04 ` [PATCH 3/4] powerpc/64e/interrupt: Prevent NMI PMI causing a dangerous warning Nicholas Piggin
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 6+ messages in thread
From: Nicholas Piggin @ 2022-10-06 14:04 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

NMI interrupts should exit with EXCEPTION_RESTORE_REGS not with
interrupt_return_srr, which is what the perf NMI handler currently does.
This breaks if a PMI hits after interrupt_exit_user_prepare_main() has
switched the context tracking to user mode, then the CT_WARN_ON() in
interrupt_exit_kernel_prepare() fires because it returns to kernel with
context set to user.

This could possibly be solved by soft-disabling PMIs in the exit path,
but that reduces our ability to profile that code. The warning could be
removed, but it's potentially useful.

All other NMIs and soft-NMIs return using EXCEPTION_RESTORE_REGS, so
this makes perf interrupts consistent with that and seems like the best
fix.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/kernel/exceptions-64s.S | 14 +++++++++++++-
 arch/powerpc/kernel/traps.c          |  2 --
 2 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S
index 5381a43e50fe..651c36b056bd 100644
--- a/arch/powerpc/kernel/exceptions-64s.S
+++ b/arch/powerpc/kernel/exceptions-64s.S
@@ -2357,9 +2357,21 @@ EXC_VIRT_END(performance_monitor, 0x4f00, 0x20)
 EXC_COMMON_BEGIN(performance_monitor_common)
 	GEN_COMMON performance_monitor
 	addi	r3,r1,STACK_FRAME_OVERHEAD
-	bl	performance_monitor_exception
+	lbz	r4,PACAIRQSOFTMASK(r13)
+	cmpdi	r4,IRQS_ENABLED
+	bne	1f
+	bl	performance_monitor_exception_async
 	b	interrupt_return_srr
+1:
+	bl	performance_monitor_exception_nmi
+	/* Clear MSR_RI before setting SRR0 and SRR1. */
+	li	r9,0
+	mtmsrd	r9,1
 
+	kuap_kernel_restore r9, r10
+
+	EXCEPTION_RESTORE_REGS hsrr=0
+	RFI_TO_KERNEL
 
 /**
  * Interrupt 0xf20 - Vector Unavailable Interrupt.
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index 9bdd79aa51cf..6138ee22d06c 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -1899,7 +1899,6 @@ DEFINE_INTERRUPT_HANDLER(vsx_unavailable_tm)
 #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
 
 #ifdef CONFIG_PPC64
-DECLARE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi);
 DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
 {
 	__this_cpu_inc(irq_stat.pmu_irqs);
@@ -1910,7 +1909,6 @@ DEFINE_INTERRUPT_HANDLER_NMI(performance_monitor_exception_nmi)
 }
 #endif
 
-DECLARE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async);
 DEFINE_INTERRUPT_HANDLER_ASYNC(performance_monitor_exception_async)
 {
 	__this_cpu_inc(irq_stat.pmu_irqs);
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/4] powerpc/64e/interrupt: Prevent NMI PMI causing a dangerous warning
  2022-10-06 14:04 [PATCH 0/4] powerpc: misc interrupt and context tracking fixes Nicholas Piggin
  2022-10-06 14:04 ` [PATCH 1/4] KVM: PPC: BookS PR-KVM and BookE do not support context tracking Nicholas Piggin
  2022-10-06 14:04 ` [PATCH 2/4] powerpc/64s/interrupt: Perf NMI should not take normal exit path Nicholas Piggin
@ 2022-10-06 14:04 ` Nicholas Piggin
  2022-10-06 14:04 ` [PATCH 4/4] powerpc/64: Fix perf profiling asynchronous interrupt handlers Nicholas Piggin
  2022-10-28 11:49 ` (subset) [PATCH 0/4] powerpc: misc interrupt and context tracking fixes Michael Ellerman
  4 siblings, 0 replies; 6+ messages in thread
From: Nicholas Piggin @ 2022-10-06 14:04 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

As explained in the fix for 64s, NMI PMIs should not return using
the normal interrupt_return function. If such a PMI hits in code
returning to user with the context switched to user mode, this warning
can fire. This was enough to cause crashes when reproducing on 64s,
because another perf interrupt would hit while reporting bug, and
that would cause another bug, and so on.

Work around this for now just by disabling that warning on 64e, which
improves stability. Make a note of what the cleaner fix would be.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/kernel/exceptions-64e.S |  7 +++++++
 arch/powerpc/kernel/interrupt.c      | 13 ++++++++++---
 2 files changed, 17 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 930e36099015..d8bf8b94401b 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -813,6 +813,13 @@ kernel_dbg_exc:
 	EXCEPTION_COMMON(0x260)
 	CHECK_NAPPING()
 	addi	r3,r1,STACK_FRAME_OVERHEAD
+	/*
+	 * XXX: Returning from performance_monitor_exception taken as a
+	 * soft-NMI (Linux irqs disabled) may be risky to use interrupt_return
+	 * and could cause bugs in return or elsewhere. That case should just
+	 * restore registers and return. There is a workaround for this for one
+	 * known problem in interrupt_exit_kernel_prepare().
+	 */
 	bl	performance_monitor_exception
 	b	interrupt_return
 
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index f9db0a172401..299683d1f8e5 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -374,10 +374,17 @@ notrace unsigned long interrupt_exit_kernel_prepare(struct pt_regs *regs)
 	if (regs_is_unrecoverable(regs))
 		unrecoverable_exception(regs);
 	/*
-	 * CT_WARN_ON comes here via program_check_exception,
-	 * so avoid recursion.
+	 * CT_WARN_ON comes here via program_check_exception, so avoid
+	 * recursion.
+	 *
+	 * Skip the assertion if 64e to work around a problem caused by NMI
+	 * PMIs incorrectly taking this interrupt return path, it's possible
+	 * for this to hit after interrupt exit to user switches context to
+	 * user. See also the performance monitor handler in
+	 * exceptions-64e.S
 	 */
-	if (TRAP(regs) != INTERRUPT_PROGRAM)
+	if (TRAP(regs) != INTERRUPT_PROGRAM &&
+			!(IS_ENABLED(CONFIG_PPC_BOOK3E_64)))
 		CT_WARN_ON(ct_state() == CONTEXT_USER);
 
 	kuap = kuap_get_and_assert_locked();
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/4] powerpc/64: Fix perf profiling asynchronous interrupt handlers
  2022-10-06 14:04 [PATCH 0/4] powerpc: misc interrupt and context tracking fixes Nicholas Piggin
                   ` (2 preceding siblings ...)
  2022-10-06 14:04 ` [PATCH 3/4] powerpc/64e/interrupt: Prevent NMI PMI causing a dangerous warning Nicholas Piggin
@ 2022-10-06 14:04 ` Nicholas Piggin
  2022-10-28 11:49 ` (subset) [PATCH 0/4] powerpc: misc interrupt and context tracking fixes Michael Ellerman
  4 siblings, 0 replies; 6+ messages in thread
From: Nicholas Piggin @ 2022-10-06 14:04 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: Nicholas Piggin

Interrupt entry sets the soft mask to IRQS_ALL_DISABLED to match the
hard irq disabled state. So when should_hard_irq_enable() reutrns true
because we want PMI interrupts in irq handlers, MSR[EE] is enabled but
any PMI just gets masked. Fix this by clearing IRQS_PMI_DISABLED before
enabling MSR[EE].

This also tidies some of the warnings, no need to duplicate them in
both should_hard_irq_enable() and do_hard_irq_enable().

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
---
 arch/powerpc/include/asm/hw_irq.h | 41 ++++++++++++++++++++++---------
 arch/powerpc/kernel/dbell.c       |  2 +-
 arch/powerpc/kernel/irq.c         |  2 +-
 arch/powerpc/kernel/time.c        |  2 +-
 4 files changed, 32 insertions(+), 15 deletions(-)

diff --git a/arch/powerpc/include/asm/hw_irq.h b/arch/powerpc/include/asm/hw_irq.h
index 77fa88c2aed0..265d0eb7ed79 100644
--- a/arch/powerpc/include/asm/hw_irq.h
+++ b/arch/powerpc/include/asm/hw_irq.h
@@ -173,6 +173,15 @@ static inline notrace unsigned long irq_soft_mask_or_return(unsigned long mask)
 	return flags;
 }
 
+static inline notrace unsigned long irq_soft_mask_andc_return(unsigned long mask)
+{
+	unsigned long flags = irq_soft_mask_return();
+
+	irq_soft_mask_set(flags & ~mask);
+
+	return flags;
+}
+
 static inline unsigned long arch_local_save_flags(void)
 {
 	return irq_soft_mask_return();
@@ -331,10 +340,11 @@ bool power_pmu_wants_prompt_pmi(void);
  * is a different soft-masked interrupt pending that requires hard
  * masking.
  */
-static inline bool should_hard_irq_enable(void)
+static inline bool should_hard_irq_enable(struct pt_regs *regs)
 {
 	if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) {
-		WARN_ON(irq_soft_mask_return() == IRQS_ENABLED);
+		WARN_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED);
+		WARN_ON(!(get_paca()->irq_happened & PACA_IRQ_HARD_DIS));
 		WARN_ON(mfmsr() & MSR_EE);
 	}
 
@@ -347,8 +357,17 @@ static inline bool should_hard_irq_enable(void)
 	 *
 	 * TODO: Add test for 64e
 	 */
-	if (IS_ENABLED(CONFIG_PPC_BOOK3S_64) && !power_pmu_wants_prompt_pmi())
-		return false;
+	if (IS_ENABLED(CONFIG_PPC_BOOK3S_64)) {
+		if (!power_pmu_wants_prompt_pmi())
+			return false;
+		/*
+		 * If PMIs are disabled then IRQs should be disabled as well,
+		 * so we shouldn't see this condition, check for it just in
+		 * case because we are about to enable PMIs.
+		 */
+		if (WARN_ON_ONCE(regs->softe & IRQS_PMI_DISABLED))
+			return false;
+	}
 
 	if (get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK)
 		return false;
@@ -358,18 +377,16 @@ static inline bool should_hard_irq_enable(void)
 
 /*
  * Do the hard enabling, only call this if should_hard_irq_enable is true.
+ * This allows PMI interrupts to profile irq handlers.
  */
 static inline void do_hard_irq_enable(void)
 {
-	if (IS_ENABLED(CONFIG_PPC_IRQ_SOFT_MASK_DEBUG)) {
-		WARN_ON(irq_soft_mask_return() == IRQS_ENABLED);
-		WARN_ON(get_paca()->irq_happened & PACA_IRQ_MUST_HARD_MASK);
-		WARN_ON(mfmsr() & MSR_EE);
-	}
 	/*
-	 * This allows PMI interrupts (and watchdog soft-NMIs) through.
-	 * There is no other reason to enable this way.
+	 * Asynch interrupts come in with IRQS_ALL_DISABLED,
+	 * PACA_IRQ_HARD_DIS, and MSR[EE]=0.
 	 */
+	if (IS_ENABLED(CONFIG_PPC_BOOK3S_64))
+		irq_soft_mask_andc_return(IRQS_PMI_DISABLED);
 	get_paca()->irq_happened &= ~PACA_IRQ_HARD_DIS;
 	__hard_irq_enable();
 }
@@ -452,7 +469,7 @@ static inline bool arch_irq_disabled_regs(struct pt_regs *regs)
 	return !(regs->msr & MSR_EE);
 }
 
-static __always_inline bool should_hard_irq_enable(void)
+static __always_inline bool should_hard_irq_enable(struct pt_regs *regs)
 {
 	return false;
 }
diff --git a/arch/powerpc/kernel/dbell.c b/arch/powerpc/kernel/dbell.c
index f55c6fb34a3a..5712dd846263 100644
--- a/arch/powerpc/kernel/dbell.c
+++ b/arch/powerpc/kernel/dbell.c
@@ -27,7 +27,7 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(doorbell_exception)
 
 	ppc_msgsync();
 
-	if (should_hard_irq_enable())
+	if (should_hard_irq_enable(regs))
 		do_hard_irq_enable();
 
 	kvmppc_clear_host_ipi(smp_processor_id());
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 0f17268c1f0b..58e8774793b8 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -238,7 +238,7 @@ static void __do_irq(struct pt_regs *regs, unsigned long oldsp)
 	irq = static_call(ppc_get_irq)();
 
 	/* We can hard enable interrupts now to allow perf interrupts */
-	if (should_hard_irq_enable())
+	if (should_hard_irq_enable(regs))
 		do_hard_irq_enable();
 
 	/* And finally process it */
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index d68de3618741..e26eb6618ae5 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -515,7 +515,7 @@ DEFINE_INTERRUPT_HANDLER_ASYNC(timer_interrupt)
 	}
 
 	/* Conditionally hard-enable interrupts. */
-	if (should_hard_irq_enable()) {
+	if (should_hard_irq_enable(regs)) {
 		/*
 		 * Ensure a positive value is written to the decrementer, or
 		 * else some CPUs will continue to take decrementer exceptions.
-- 
2.37.2


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: (subset) [PATCH 0/4] powerpc: misc interrupt and context tracking fixes
  2022-10-06 14:04 [PATCH 0/4] powerpc: misc interrupt and context tracking fixes Nicholas Piggin
                   ` (3 preceding siblings ...)
  2022-10-06 14:04 ` [PATCH 4/4] powerpc/64: Fix perf profiling asynchronous interrupt handlers Nicholas Piggin
@ 2022-10-28 11:49 ` Michael Ellerman
  4 siblings, 0 replies; 6+ messages in thread
From: Michael Ellerman @ 2022-10-28 11:49 UTC (permalink / raw)
  To: linuxppc-dev, Nicholas Piggin

On Fri, 7 Oct 2022 00:04:09 +1000, Nicholas Piggin wrote:
> These are several fixes for regressions and bugs that can crash
> the host.
> 
> Thanks,
> Nick
> 
> Nicholas Piggin (4):
>   KVM: PPC: BookS PR-KVM and BookE do not support context tracking
>   powerpc/64s/interrupt: Perf NMI should not take normal exit path
>   powerpc/64e/interrupt: Prevent NMI PMI causing a dangerous warning
>   powerpc/64: Fix perf profiling asynchronous interrupt handlers
> 
> [...]

Applied to powerpc/fixes.

[2/4] powerpc/64s/interrupt: Perf NMI should not take normal exit path
      https://git.kernel.org/powerpc/c/dc398a084d459f065658855454e09f2778f8c5cc

cheers

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2022-10-28 11:51 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2022-10-06 14:04 [PATCH 0/4] powerpc: misc interrupt and context tracking fixes Nicholas Piggin
2022-10-06 14:04 ` [PATCH 1/4] KVM: PPC: BookS PR-KVM and BookE do not support context tracking Nicholas Piggin
2022-10-06 14:04 ` [PATCH 2/4] powerpc/64s/interrupt: Perf NMI should not take normal exit path Nicholas Piggin
2022-10-06 14:04 ` [PATCH 3/4] powerpc/64e/interrupt: Prevent NMI PMI causing a dangerous warning Nicholas Piggin
2022-10-06 14:04 ` [PATCH 4/4] powerpc/64: Fix perf profiling asynchronous interrupt handlers Nicholas Piggin
2022-10-28 11:49 ` (subset) [PATCH 0/4] powerpc: misc interrupt and context tracking fixes Michael Ellerman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).