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

[Xen-changelog] [xen master] x86/traps: honor EXT bit in error codes



commit 84064d11a40a6d6b55de8a97049042fc6d67dbb3
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Thu Nov 12 17:01:53 2015 +0100
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Thu Nov 12 17:01:53 2015 +0100

    x86/traps: honor EXT bit in error codes
    
    The specification does not explicitly limit the use of this bit to
    exceptions that can have selector style error codes, so to be on the
    safe side we should deal with it being set even on error codes formally
    documented to be always zero (if they're indeed always zero, the change
    is simply dead code in those cases).
    
    Introduce and use (where suitable) X86_XEC_* constants to make the code
    easier to read.
    
    To match the placement of the "hardware_trap" label, the "hardware_gp"
    one gets moved slightly too.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Reviewed-by: Andrew Cooper <andrew.cooper3@xxxxxxxxxx>
---
 xen/arch/x86/traps.c            |   18 ++++++++++++------
 xen/arch/x86/x86_64/entry.S     |    2 +-
 xen/include/asm-x86/processor.h |    5 +++++
 3 files changed, 18 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/traps.c b/xen/arch/x86/traps.c
index b32f696..e21fb78 100644
--- a/xen/arch/x86/traps.c
+++ b/xen/arch/x86/traps.c
@@ -615,6 +615,9 @@ static void do_trap(struct cpu_user_regs *regs, int 
use_error_code)
     unsigned int trapnr = regs->entry_vector;
     unsigned long fixup;
 
+    if ( regs->error_code & X86_XEC_EXT )
+        goto hardware_trap;
+
     DEBUGGER_trap_entry(trapnr, regs);
 
     if ( guest_mode(regs) )
@@ -641,6 +644,7 @@ static void do_trap(struct cpu_user_regs *regs, int 
use_error_code)
         return;
     }
 
+ hardware_trap:
     DEBUGGER_trap_fatal(trapnr, regs);
 
     show_execution_state(regs);
@@ -1262,13 +1266,14 @@ static int handle_gdt_ldt_mapping_fault(
             tb = propagate_page_fault(curr->arch.pv_vcpu.ldt_base + offset,
                                       regs->error_code);
             if ( tb )
-                tb->error_code = ((u16)offset & ~3) | 4;
+                tb->error_code = (offset & ~(X86_XEC_EXT | X86_XEC_IDT)) |
+                                 X86_XEC_TI;
         }
     }
     else
     {
         /* GDT fault: handle the fault as #GP(selector). */
-        regs->error_code = (u16)offset & ~7;
+        regs->error_code = offset & ~(X86_XEC_EXT | X86_XEC_IDT | X86_XEC_TI);
         (void)do_general_protection(regs);
     }
 
@@ -3221,7 +3226,7 @@ void do_general_protection(struct cpu_user_regs *regs)
 
     DEBUGGER_trap_entry(TRAP_gp_fault, regs);
 
-    if ( regs->error_code & 1 )
+    if ( regs->error_code & X86_XEC_EXT )
         goto hardware_gp;
 
     if ( !guest_mode(regs) )
@@ -3240,14 +3245,15 @@ void do_general_protection(struct cpu_user_regs *regs)
      * 
      * Instead, a GPF occurs with the faulting IDT vector in the error code.
      * Bit 1 is set to indicate that an IDT entry caused the fault. Bit 0 is 
-     * clear to indicate that it's a software fault, not hardware.
+     * clear (which got already checked above) to indicate that it's a software
+     * fault, not a hardware one.
      * 
      * NOTE: Vectors 3 and 4 are dealt with from their own handler. This is
      * okay because they can only be triggered by an explicit DPL-checked
      * instruction. The DPL specified by the guest OS for these vectors is NOT
      * CHECKED!!
      */
-    if ( (regs->error_code & 3) == 2 )
+    if ( regs->error_code & X86_XEC_IDT )
     {
         /* This fault must be due to <INT n> instruction. */
         const struct trap_info *ti;
@@ -3289,9 +3295,9 @@ void do_general_protection(struct cpu_user_regs *regs)
         return;
     }
 
+ hardware_gp:
     DEBUGGER_trap_fatal(TRAP_gp_fault, regs);
 
- hardware_gp:
     show_execution_state(regs);
     panic("GENERAL PROTECTION FAULT\n[error_code=%04x]", regs->error_code);
 }
diff --git a/xen/arch/x86/x86_64/entry.S b/xen/arch/x86/x86_64/entry.S
index d4dd8e8..94a54aa 100644
--- a/xen/arch/x86/x86_64/entry.S
+++ b/xen/arch/x86/x86_64/entry.S
@@ -338,7 +338,7 @@ int80_slow_path:
          * Setup entry vector and error code as if this was a GPF caused by an
          * IDT entry with DPL==0.
          */
-        movl  $((0x80 << 3) | 0x2),UREGS_error_code(%rsp)
+        movl  $((0x80 << 3) | X86_XEC_IDT),UREGS_error_code(%rsp)
         SAVE_PRESERVED
         movl  $TRAP_gp_fault,UREGS_entry_vector(%rsp)
         /* A GPF wouldn't have incremented the instruction pointer. */
diff --git a/xen/include/asm-x86/processor.h b/xen/include/asm-x86/processor.h
index fcfa7dd..a40c18e 100644
--- a/xen/include/asm-x86/processor.h
+++ b/xen/include/asm-x86/processor.h
@@ -143,6 +143,11 @@
 #define PFEC_page_paged     (1U<<5)
 #define PFEC_page_shared    (1U<<6)
 
+/* Other exception error code values. */
+#define X86_XEC_EXT         (_AC(1,U) << 0)
+#define X86_XEC_IDT         (_AC(1,U) << 1)
+#define X86_XEC_TI          (_AC(1,U) << 2)
+
 #define XEN_MINIMAL_CR4 (X86_CR4_PGE | X86_CR4_PAE)
 
 #define XEN_SYSCALL_MASK (X86_EFLAGS_AC|X86_EFLAGS_VM|X86_EFLAGS_RF|    \
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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