[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH] x86/HVM: correctly deal with benign exceptions when combining two



Benign exceptions, no matter whether they're first or second, will never
cause #DF (a benign exception being second can basically only be #AC, as
in the XSA-156 scenario).

Sadly neither AMD nor Intel really define what happens with two benign
exceptions - the term "sequentially" used by both is poisoned by how the
combining of benign and non-benign exceptions is described. Since NMI,
#MC, and hardware interrupts are all benign and (perhaps with the
exception of #MC) can't occur second, favor the first in order to not
lose it.

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
---
As to 4.12, this being a bug fix (and a backporting candidate) it
certainly should be considered. But us having lived with the bug for so
long, I wouldn't call it mandatory.

--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -247,20 +247,27 @@ uint8_t hvm_combine_hw_exceptions(uint8_
         (1 << TRAP_page_fault) |
         (1 << TRAP_virtualisation);
 
-    /* Exception during double-fault delivery always causes a triple fault. */
+    /* If the second exception is benign, deliver the first. */
+    if ( !((1u << vec2) & (contributory_exceptions | page_faults)) )
+        return vec1;
+
+    /* If the first exception is benign, deliver the second. */
+    if ( !((1u << vec1) & (contributory_exceptions | page_faults)) )
+        return vec2;
+
+    /* Non-benign exceptions during #DF delivery cause a triple fault. */
     if ( vec1 == TRAP_double_fault )
     {
         hvm_triple_fault();
         return TRAP_double_fault; /* dummy return */
     }
 
-    /* Exception during page-fault delivery always causes a double fault. */
+    /* Non-benign exceptions during #PF delivery cause #DF. */
     if ( (1u << vec1) & page_faults )
         return TRAP_double_fault;
 
-    /* Discard the first exception if it's benign or if we now have a #PF. */
-    if ( !((1u << vec1) & contributory_exceptions) ||
-         ((1u << vec2) & page_faults) )
+    /* Discard the first exception if we now have a #PF. */
+    if ( (1u << vec2) & page_faults )
         return vec2;
 
     /* Cannot combine the exceptions: double fault. */





_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxxx
https://lists.xenproject.org/mailman/listinfo/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.