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

[Xen-devel] [PATCH 2/3] x86emul: deliver correct math exceptions



#MF only applies to x87 instructions. SSE and AVX ones need #XM to be
raised instead, unless CR4.OSXMMEXCPT is clear, in which case #UD needs
to result. (But note that this is only a latent issue - we don't
emulate any instructions so far which could result in #XM.)

Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>

--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -427,6 +427,7 @@ typedef union {
 
 #define CR4_TSD        (1<<2)
 #define CR4_OSFXSR     (1<<9)
+#define CR4_OSXMMEXCPT (1<<10)
 #define CR4_UMIP       (1<<11)
 #define CR4_OSXSAVE    (1<<18)
 
@@ -462,6 +463,7 @@ typedef union {
 #define EXC_GP 13
 #define EXC_PF 14
 #define EXC_MF 16
+#define EXC_XM 19
 
 /* Segment selector error code bits. */
 #define ECODE_EXT (1 << 0)
@@ -745,13 +747,14 @@ do {
 
 struct fpu_insn_ctxt {
     uint8_t insn_bytes;
-    uint8_t exn_raised;
+    int8_t exn_raised;
 };
 
 static void fpu_handle_exception(void *_fic, struct cpu_user_regs *regs)
 {
     struct fpu_insn_ctxt *fic = _fic;
-    fic->exn_raised = 1;
+    ASSERT(regs->entry_vector < 0x20);
+    fic->exn_raised = regs->entry_vector;
     regs->eip += fic->insn_bytes;
 }
 
@@ -763,7 +766,7 @@ static int _get_fpu(
 {
     int rc;
 
-    fic->exn_raised = 0;
+    fic->exn_raised = -1;
 
     fail_if(!ops->get_fpu);
     rc = ops->get_fpu(fpu_handle_exception, fic, type, ctxt);
@@ -818,7 +821,15 @@ do {
 #define put_fpu(_fic)                                           \
 do {                                                            \
     _put_fpu();                                                 \
-    generate_exception_if((_fic)->exn_raised, EXC_MF, -1);      \
+    if( (_fic)->exn_raised == EXC_XM && ops->read_cr )          \
+    {                                                           \
+        unsigned long cr4;                                      \
+        if ( (ops->read_cr(4, &cr4, ctxt) == X86EMUL_OKAY) &&   \
+             !(cr4 & CR4_OSXMMEXCPT) )                          \
+            (_fic)->exn_raised = EXC_UD;                        \
+    }                                                           \
+    generate_exception_if((_fic)->exn_raised >= 0,              \
+                          (_fic)->exn_raised, -1);              \
 } while (0)
 
 #define emulate_fpu_insn(_op)                           \



Attachment: x86emul-math-exceptions.patch
Description: Text document

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

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