|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v1] x86/nestedsvm: honour L2's EFLAGS.IF when L1 clears V_INTR_MASKING
From: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>
L0 always runs L2 with V_INTR_MASKING set, so a physical interrupt exits to
L0 regardless of L2's EFLAGS.IF. nsvm_intr_blocked() only blocks when L1
requested V_INTR_MASKING=1 and L1's IF was clear. With V_INTR_MASKING=0
and L2's IF clear, nestedsvm_vcpu_interrupt() would still inject
VMEXIT(INTR) into L1.
Per the APM (vol.2 rev 3.44 "Physical Interrupt Masking in EFLAGS"), with
V_INTR_MASKING=0 L2's IF masks physical interrupts, and a masked interrupt
must stay pending. Return NSVM_INTR_MASKED for external interrupts in
that case.
Signed-off-by: Chunjie Zhu <chunjie.zhu@xxxxxxxxxx>
---
xen/arch/x86/hvm/svm/nestedsvm.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index faacfe007832..a419b47eb5f6 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -1514,6 +1514,17 @@ nestedsvm_vcpu_interrupt(struct vcpu *v, const struct
hvm_intack intack)
case hvm_intsrc_pic:
case hvm_intsrc_lapic:
case hvm_intsrc_vector:
+ /*
+ * Without V_INTR_MASKING, L2's EFLAGS.IF masks physical interrupts
+ * (APM vol.2 rev 3.44 "Physical Interrupt Masking in EFLAGS"). L0
+ * always runs L2 with V_INTR_MASKING set, so the interrupt would
+ * otherwise exit to L0 and be forwarded to L1 even with L2's IF
+ * clear. Leave it pending instead.
+ */
+ if ( !vcpu_nestedsvm(v).ns_hostflags.fields.vintrmask &&
+ !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
+ return NSVM_INTR_MASKED;
+
exitcode = VMEXIT_INTR;
exitinfo2 = intack.vector;
break;
--
2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |