[PATCH v2] x86/HVM: adjust hvm_interrupt_blocked()

Jan Beulich posted 1 patch 7 months, 3 weeks ago
Failed in applying to current master (apply log)
[PATCH v2] x86/HVM: adjust hvm_interrupt_blocked()
Posted by Jan Beulich 7 months, 3 weeks ago
First of all, hvm_intsrc_mce was not considered here at all, yet nothing
blocks #MC (other than an already in-progress #MC, but dealing with this
is not the purpose of this patch).

While nominally STI-shadow only blocks maskable interrupts, but not NMI,
at least Intel offers more leeway: "Nonmaskable interrupts and system-
management interrupts may also be inhibited on the instruction boundary
following such an execution of STI." In case guest kernels might rely on
such behavior, keep the STI check together with the MOV-SS one.

Additionally EFLAGS.IF being clear affects neither #MC nor NMI.

Signed-off-by: Jan Beulich <jbeulich@suse.com>
---
The EFLAGS.IF check may want moving yet further down, i.e. also past the
TPR check. Otoh it may also be okay to keep the original condition, just
after the added MCE conditional. Except for hvm_intblk_tpr, the specific
types returned here aren't really of interest to callers. The special
case in vmx_intr_assist() concering hvm_intblk_tpr looks to prefer to
have the check done last (i.e. all other blocking reasons to be
prefered). For the one in nvmx_intr_intercept() it's not as clear to me,
though.
---
v2: Keep STI and MOV-SS together.

--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -3904,9 +3904,8 @@ enum hvm_intblk hvm_interrupt_blocked(st
             return intr;
     }
 
-    if ( (intack.source != hvm_intsrc_nmi) &&
-         !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
-        return hvm_intblk_rflags_ie;
+    if ( intack.source == hvm_intsrc_mce )
+        return hvm_intblk_none;
 
     intr_shadow = alternative_call(hvm_funcs.get_interrupt_shadow, v);
 
@@ -3917,6 +3916,9 @@ enum hvm_intblk hvm_interrupt_blocked(st
         return ((intr_shadow & HVM_INTR_SHADOW_NMI) ?
                 hvm_intblk_nmi_iret : hvm_intblk_none);
 
+    if ( !(guest_cpu_user_regs()->eflags & X86_EFLAGS_IF) )
+        return hvm_intblk_rflags_ie;
+
     if ( intack.source == hvm_intsrc_lapic )
     {
         uint32_t tpr = vlapic_get_reg(vcpu_vlapic(v), APIC_TASKPRI) & 0xF0;