|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH] x86/fred: Send an EVENT_CHECK IPI on exit from NMI
Returning from an NMI which hits guest context needs special casing in FRED
mode just like it does in IDT mode.
Break nmi_exit_to_guest() out of handle_ist_exception(), and use it in
entry_FRED_R3() also.
Expand the comment a little, and invert the conditional jump to
compat_restore_all_guest() to avoid needing an #else clause for CONFIG_PV32.
Signed-off-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
CC: Jan Beulich <jbeulich@xxxxxxxx>
CC: Roger Pau Monné <roger.pau@xxxxxxxxxx>
CC: Teddy Astie <teddy.astie@xxxxxxxxxx>
CC: Oleksii Kurochko <oleksii.kurochko@xxxxxxxxx>
Slightly RFC, not tested yet. (My AMD system takes an eternity to reboot)
For 4.22. Found during testing of FRED. The consqeuence is that we can end
up scheduling while still in NMI context, after which things like the watchdog
and other diagnostics don't work properly.
---
xen/arch/x86/x86_64/entry-fred.S | 6 ++++
xen/arch/x86/x86_64/entry.S | 49 +++++++++++++++++++-------------
2 files changed, 36 insertions(+), 19 deletions(-)
diff --git a/xen/arch/x86/x86_64/entry-fred.S b/xen/arch/x86/x86_64/entry-fred.S
index e9c84423dacd..1ad9694a043b 100644
--- a/xen/arch/x86/x86_64/entry-fred.S
+++ b/xen/arch/x86/x86_64/entry-fred.S
@@ -20,6 +20,12 @@ FUNC(entry_FRED_R3, 4096)
GET_STACK_END(14)
movq STACK_CPUINFO_FIELD(current_vcpu)(%r14), %rbx
+ /* NMIs need special handling on return to guest. */
+ movzbl UREGS_ss + 6(%rsp), %eax
+ and $0xf, %eax
+ cmp $X86_ET_NMI, %al
+ je nmi_exit_to_guest
+
jmp test_all_events
#else
BUG /* Not Reached */
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index 17ca6a493906..de5d854f5533 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -146,6 +146,35 @@ process_trap:
jmp test_all_events
END(switch_to_kernel)
+/*
+ * When returning to guest from an NMI, we must execute an IRET/ERETU to
+ * re-enable NMIs, and must not process softirqs which can e.g. schedule
+ * rather than returning to guest context.
+ *
+ * If a softirq is pending, send ourselves an EVENT_CHECK IPI to compensate.
+ * This will cause softirq processing to occur upon leaving NMI context.
+ *
+ * %rbx: struct vcpu, %r14 stack_end
+ */
+FUNC(nmi_exit_to_guest)
+ mov STACK_CPUINFO_FIELD(processor_id)(%r14), %eax
+ shl $IRQSTAT_shift, %eax
+ lea irq_stat + IRQSTAT_softirq_pending(%rip), %rcx
+ cmpl $0, (%rcx, %rax, 1)
+ je 1f
+ mov $EVENT_CHECK_VECTOR, %edi
+ call send_IPI_self
+1:
+ /* For restore_all_guest. */
+ mov STACK_CPUINFO_FIELD(current_vcpu)(%r14), %rbx
+#ifdef CONFIG_PV32
+ mov VCPU_domain(%rbx), %rax
+ cmpb $0, DOMAIN_is_32bit_pv(%rax)
+ jne compat_restore_all_guest
+#endif
+ jmp restore_all_guest
+END(nmi_exit_to_guest)
+
.section .text.entry, "ax", @progbits
/* %rbx: struct vcpu, interrupts disabled */
@@ -1209,25 +1238,7 @@ FUNC(handle_ist_exception)
#ifdef CONFIG_PV
testb $3,UREGS_cs(%rsp)
jz restore_all_xen
- /* Send an IPI to ourselves to cover for the lack of event checking. */
- mov STACK_CPUINFO_FIELD(processor_id)(%r14), %eax
- shll $IRQSTAT_shift,%eax
- leaq irq_stat+IRQSTAT_softirq_pending(%rip),%rcx
- cmpl $0,(%rcx,%rax,1)
- je 1f
- movl $EVENT_CHECK_VECTOR,%edi
- call send_IPI_self
-1:
- /* For restore_all_guest. */
- mov STACK_CPUINFO_FIELD(current_vcpu)(%r14), %rbx
-#ifdef CONFIG_PV32
- movq VCPU_domain(%rbx),%rax
- cmpb $0,DOMAIN_is_32bit_pv(%rax)
- je restore_all_guest
- jmp compat_restore_all_guest
-#else
- jmp restore_all_guest
-#endif
+ jmp nmi_exit_to_guest
#else
ASSERT_CONTEXT_IS_XEN
jmp restore_all_xen
base-commit: d42ace60290a4b4184ee2133b245b134fdf96fed
--
2.39.5
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |