|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [PATCH v1] x86/nestedsvm: honour L2's EFLAGS.IF when L1 clears V_INTR_MASKING
> From: Xen-devel <xen-devel-bounces@xxxxxxxxxxxxxxxxxxxx> on behalf of
> chunjie.zhu@xxxxxxxxxx <chunjie.zhu@xxxxxxxxxx>
> Sent: Friday, October 16, 2026 11:00
> To: xen-devel@xxxxxxxxxxxxxxxxxxxx <xen-devel@xxxxxxxxxxxxxxxxxxxx>
> Cc: jbeulich@xxxxxxxx <jbeulich@xxxxxxxx>; Andrew Cooper
> <andrew.cooper3@xxxxxxxxxx>; roger@xxxxxxxxxxxxxx <roger@xxxxxxxxxxxxxx>;
> jason.andryuk@xxxxxxx <jason.andryuk@xxxxxxx>; teddy.astie@xxxxxxxxxx
> <teddy.astie@xxxxxxxxxx>; Chunjie Zhu (朱春杰) <chunjie.zhu@xxxxxxxxxx>
> Subject: [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
>
Would it not make sense to check this in nsvm_intr_blocked() instead?
There is already a similar (inverse) check there so extending that seems
more logical to me.
E.g. something like this (untested):
diff --git a/xen/arch/x86/hvm/svm/nestedsvm.c b/xen/arch/x86/hvm/svm/nestedsvm.c
index b192be0d56b1..8bded8b9a9c2 100644
--- a/xen/arch/x86/hvm/svm/nestedsvm.c
+++ b/xen/arch/x86/hvm/svm/nestedsvm.c
@@ -1213,8 +1213,9 @@ enum hvm_intblk cf_check nsvm_intr_blocked(struct vcpu *v)
{
struct vmcb_struct *n2vmcb = nv->nv_n2vmcx;
- if ( svm->ns_hostflags.fields.vintrmask &&
- !svm->ns_hostflags.fields.rflagsif )
+ if ( svm->ns_hostflags.fields.vintrmask ?
+ !svm->ns_hostflags.fields.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
Ross
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |