show_hvm_stack() requires interrupts to be enabled to avoid triggering
the consistency check in check_lock() for the p2m lock. Add a respective
check. To avoid this check triggering when coming through
spurious_interrupt() requires adding reentrancy protection / handling
there alongside transiently (re-)enabling IRQs.
Fixes: adb715db698b ("x86/HVM: also dump stacks from show_execution_state()")
Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
v2: Check IRQs enabled before calling show_hvm_stack(). Re-base.
--- a/xen/arch/x86/apic.c
+++ b/xen/arch/x86/apic.c
@@ -1384,22 +1384,40 @@ void smp_send_state_dump(unsigned int cp
*/
void cf_check spurious_interrupt(struct cpu_user_regs *regs)
{
+ static DEFINE_PER_CPU(unsigned int, recursed);
+ unsigned int cpu = smp_processor_id();
+
/*
* Check if this is a vectored interrupt (most likely, as this is probably
* a request to dump local CPU state or to continue NMI handling).
* Vectored interrupts are ACKed; spurious interrupts are not.
*/
- if (apic_isr_read(SPURIOUS_APIC_VECTOR)) {
+ while ( apic_isr_read(SPURIOUS_APIC_VECTOR) )
+ {
bool is_spurious;
+ if ( per_cpu(recursed, cpu)++ )
+ return;
+
ack_APIC_irq();
is_spurious = !nmi_check_continuation();
- if (this_cpu(state_dump_pending)) {
- this_cpu(state_dump_pending) = false;
+
+ if ( per_cpu(state_dump_pending, cpu) )
+ {
+ per_cpu(state_dump_pending, cpu) = false;
+
+ local_irq_enable();
+
dump_execstate(regs);
- is_spurious = false;
+
+ local_irq_disable();
+
+ /* (Ab)use is_spurious to arrange for loop continuation. */
+ is_spurious = per_cpu(recursed, cpu) > 1;
}
+ per_cpu(recursed, cpu) = 0;
+
if ( !is_spurious )
return;
}
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -660,7 +660,9 @@ void show_execution_state(const struct c
{
struct vcpu *curr = current;
- if ( is_hvm_vcpu(curr) )
+ if ( !is_hvm_vcpu(curr) )
+ show_guest_stack(curr, regs);
+ else if ( flags & X86_EFLAGS_IF )
{
/*
* Stop interleaving prevention: The necessary P2M lookups
@@ -671,8 +673,6 @@ void show_execution_state(const struct c
show_hvm_stack(curr, regs);
return;
}
-
- show_guest_stack(curr, regs);
}
else
{
© 2016 - 2024 Red Hat, Inc.