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

[Xen-changelog] [xen master] x86emul: deliver correct math exceptions



commit beeeaa920049c88af035b3dee8e20926d9d426f8
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed Oct 5 14:19:43 2016 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed Oct 5 14:19:43 2016 +0200

    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>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/x86_emulate/x86_emulate.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/xen/arch/x86/x86_emulate/x86_emulate.c 
b/xen/arch/x86/x86_emulate/x86_emulate.c
index f3af15a..265dadf 100644
--- a/xen/arch/x86/x86_emulate/x86_emulate.c
+++ b/xen/arch/x86/x86_emulate/x86_emulate.c
@@ -424,6 +424,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)
 
@@ -459,6 +460,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)
@@ -742,13 +744,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;
 }
 
@@ -760,7 +763,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)                           \
--
generated by git-patchbot for /home/xen/git/xen.git#master

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

 


Rackspace

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