|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH v3 2/3] 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>
---
v3:
* Add ASSERT(v == current), as suggested by Ross.
* Rebased on staging.
xen/arch/x86/hvm/svm/nestedsvm.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index 40c7717c5572..706aed8ed026 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -1150,6 +1150,7 @@ enum hvm_intblk cf_check nsvm_intr_blocked(struct vcpu *v)
struct nestedsvm *svm = &vcpu_nestedsvm(v);
struct nestedvcpu *nv = &vcpu_nestedhvm(v);
+ ASSERT(v == current);
ASSERT(nestedhvm_enabled(v->domain));
if ( !nestedsvm_gif_isset(v) )
@@ -1159,7 +1160,16 @@ enum hvm_intblk cf_check nsvm_intr_blocked(struct vcpu
*v)
{
struct vmcb_struct *n2vmcb = nv->nv_n2vmcx;
- if ( svm->ns_hostflags.vintrmask && !svm->ns_hostflags.rflagsif )
+ /*
+ * With V_INTR_MASKING, L1's EFLAGS.IF masks physical interrupts.
+ * Without it, L2's EFLAGS.IF does (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.
+ */
+ if ( svm->ns_hostflags.vintrmask
+ ? !svm->ns_hostflags.rflagsif
+ : !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
return hvm_intblk_rflags_ie;
/* when l1 guest passes its devices through to the l2 guest
--
2.34.1
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |