Commit 6c645b01 authored by Nicholas Piggin's avatar Nicholas Piggin Committed by Michael Ellerman
Browse files

KVM: PPC: Book3E: Fix CONFIG_TRACE_IRQFLAGS support



32-bit does not trace_irqs_off() to match the trace_irqs_on() call in
kvmppc_fix_ee_before_entry(). This can lead to irqs being enabled twice
in the trace, and the irqs-off region between guest exit and the host
enabling local irqs again is not properly traced.

64-bit code does call this, but from asm code where volatiles are live
and so incorrectly get clobbered.

Move the irq reconcile into C to fix both problems.

Signed-off-by: default avatarNicholas Piggin <npiggin@gmail.com>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20221127124942.1665522-2-npiggin@gmail.com
parent a96b2075
Loading
Loading
Loading
Loading
+12 −0
Original line number Diff line number Diff line
@@ -1014,6 +1014,18 @@ static inline void kvmppc_fix_ee_before_entry(void)
#endif
}

static inline void kvmppc_fix_ee_after_exit(void)
{
#ifdef CONFIG_PPC64
	/* Only need to enable IRQs by hard enabling them after this */
	local_paca->irq_happened = PACA_IRQ_HARD_DIS;
	irq_soft_mask_set(IRQS_ALL_DISABLED);
#endif

	trace_hardirqs_off();
}


static inline ulong kvmppc_get_ea_indexed(struct kvm_vcpu *vcpu, int ra, int rb)
{
	ulong ea;
+3 −0
Original line number Diff line number Diff line
@@ -1015,6 +1015,9 @@ int kvmppc_handle_exit(struct kvm_vcpu *vcpu, unsigned int exit_nr)
	u32 last_inst = KVM_INST_FETCH_FAILED;
	enum emulation_result emulated = EMULATE_DONE;

	/* Fix irq state (pairs with kvmppc_fix_ee_before_entry()) */
	kvmppc_fix_ee_after_exit();

	/* update before a new last_exit_type is rewritten */
	kvmppc_update_timing_stats(vcpu);

+0 −9
Original line number Diff line number Diff line
@@ -424,15 +424,6 @@ _GLOBAL(kvmppc_resume_host)
	mtspr	SPRN_EPCR, r3
	isync

#ifdef CONFIG_64BIT
	/*
	 * We enter with interrupts disabled in hardware, but
	 * we need to call RECONCILE_IRQ_STATE to ensure
	 * that the software state is kept in sync.
	 */
	RECONCILE_IRQ_STATE(r3,r5)
#endif

	/* Switch to kernel stack and jump to handler. */
	mr	r3, r4
	mr	r5, r14 /* intno */