]> xenbits.xensource.com Git - people/royger/xen-test-framework.git/commitdiff
Test `into` even in 64bit
authorAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 7 Mar 2016 09:09:21 +0000 (09:09 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Mon, 21 Mar 2016 18:03:58 +0000 (18:03 +0000)
In 64bit, the instruction should fail unilaterally with #UD.  Check that the
emulator provides this behaviour.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
tests/swint-emulation/lowlevel.S
tests/swint-emulation/lowlevel.h
tests/swint-emulation/main.c

index 413a09d93cf19767114c13601b13546a08a4c12f..6925f13d7f4f29bfb20ab1418af7e355bb780938 100644 (file)
@@ -48,7 +48,7 @@ GLOBAL(label_\insn\()_\type\()_fault)
         .elseif \insn == int_0x1
             int $0x1
         .elseif \insn == into
-            into
+            .byte 0xce           /* Raw opcode to avoid failure in 64bit build. */
         .endif
 
         /* Label where a trap should occur.  e.g. label_int3_red_trap. */
@@ -75,9 +75,7 @@ GEN_SEQUENCE int3
 GEN_SEQUENCE int_0x3
 GEN_SEQUENCE icebp
 GEN_SEQUENCE int_0x1
-#ifdef __i386__
 GEN_SEQUENCE into
-#endif
 
 /*
  * Local variables:
index f4eaa2bf6b57569d574d2fc550962b7ded7900a2..1cbe8cb71a1204765383c5b65fb9e4090fe0d022 100644 (file)
@@ -70,7 +70,6 @@ extern unsigned long label_int_0x1_red_trap[], label_int_0x1_red_fault[];
 extern unsigned long label_int_0x1_force_trap[], label_int_0x1_force_fault[];
 extern unsigned long label_int_0x1_forcered_trap[], label_int_0x1_forcered_fault[];
 
-#ifdef __i386__
 void stub_into_reg(void);
 void stub_into_red(void);
 void stub_into_force(void);
@@ -79,7 +78,6 @@ extern unsigned long label_into_reg_trap[], label_into_reg_fault[];
 extern unsigned long label_into_red_trap[], label_into_red_fault[];
 extern unsigned long label_into_force_trap[], label_into_force_fault[];
 extern unsigned long label_into_forcered_trap[], label_into_forcered_fault[];
-#endif
 
 #endif /* __LOWLEVEL_H__ */
 
index 6efe54ccc5a106ea6f07511f9da4a9c59146e72e..b266c5a1602b9e9aaf9e9416a568662c79f575fe 100644 (file)
@@ -15,7 +15,7 @@
  * - `int $3` (`0xcd 0x03`)
  * - `icebp`  (`0xf1`)
  * - `int $1` (`0xcd 0x01`)
- * - `into`   (`0xce`) (32bit only)
+ * - `into`   (`0xce`)
  *
  * with and without a redundant prefix (address size override specifically, as
  * it has no effect on instructs like these).  Each combination is executed
  * - cpl3, descriptors dpl0 - expect @#GP faults (except `icebp`)
  * - cpl3, descriptors not present - expect @#NP faults
  *
+ * Handling of `into` is more complicated.  In 32bit it is tested as normal,
+ * but the instruction isn't recognised in 64bit.  Instead, it is just tested
+ * to unconditionally generate a @#UD fault.
+ *
  * In all cases, the exception frame is verified to be correct.
  *
  * @sa tests/swint-emulation/main.c
@@ -134,7 +138,6 @@ struct sequence int_0x1 =
   },
 };
 
-#ifdef __i386__
 /** Sequence for `into`. */
 struct sequence into =
 { "into",
@@ -152,7 +155,6 @@ struct sequence into =
        label_into_forcered_trap, label_into_forcered_fault},
   },
 };
-#endif
 
 /** Whether to run the stub in user or supervisor mode. */
 static bool user = false;
@@ -218,7 +220,8 @@ bool unhandled_exception(struct cpu_regs *regs)
 }
 
 /** Test a single sequence of related instructions. */
-void test_seq(struct sequence *seq, unsigned int vector, unsigned int error)
+void test_seq(struct sequence *seq, unsigned int vector,
+              unsigned int error, bool fault)
 {
     unsigned int i;
 
@@ -229,7 +232,7 @@ void test_seq(struct sequence *seq, unsigned int vector, unsigned int error)
         struct single *s = &seq->tests[i];
 
         expect(s->type,
-               error == 0 ? s->trap : s->fault,
+               fault ? s->fault : s->trap,
                vector, error);
 
         user ? exec_user(s->fn) : s->fn();
@@ -245,14 +248,14 @@ void test_seq(struct sequence *seq, unsigned int vector, unsigned int error)
 /** test_seq() wrapper, for caller clarity. */
 static void test_trap(struct sequence *seq, unsigned int vector)
 {
-    test_seq(seq, vector, 0);
+    test_seq(seq, vector, 0, false);
 }
 
 /** test_seq() wrapper, for caller clarity. */
 static void test_fault(struct sequence *seq,
                        unsigned int vector, unsigned int error)
 {
-    test_seq(seq, vector, error);
+    test_seq(seq, vector, error, true);
 }
 
 /** Modify the present flag on the IDT entries under test. */
@@ -284,6 +287,8 @@ void cpl3_tests(void)
         test_trap(&int_0x1, X86_EXC_DB);
 #ifdef __i386__
         test_trap(&into,    X86_EXC_OF);
+#else
+        test_fault(&into,   X86_EXC_UD, 0);
 #endif
     }
 
@@ -297,6 +302,8 @@ void cpl3_tests(void)
         test_fault(&int_0x1, X86_EXC_NP, EXC_EC_SYM(DB));
 #ifdef __i386__
         test_fault(&into,    X86_EXC_NP, EXC_EC_SYM(OF));
+#else
+        test_fault(&into,    X86_EXC_UD, 0);
 #endif
 
         set_idt_entries_present(true);
@@ -313,6 +320,8 @@ void cpl3_tests(void)
         test_fault(&int_0x1, X86_EXC_GP, EXC_EC_SYM(DB));
 #ifdef __i386__
         test_fault(&into,    X86_EXC_GP, EXC_EC_SYM(OF));
+#else
+        test_fault(&into,    X86_EXC_UD, 0);
 #endif
 
         set_idt_entries_dpl(3);
@@ -332,6 +341,8 @@ void cpl0_tests(void)
         test_trap(&int_0x1, X86_EXC_DB);
 #ifdef __i386__
         test_trap(&into,    X86_EXC_OF);
+#else
+        test_fault(&into,   X86_EXC_UD, 0);
 #endif
     }
 
@@ -345,6 +356,8 @@ void cpl0_tests(void)
         test_fault(&int_0x1, X86_EXC_NP, EXC_EC_SYM(DB));
 #ifdef __i386__
         test_fault(&into,    X86_EXC_NP, EXC_EC_SYM(OF));
+#else
+        test_fault(&into,    X86_EXC_UD, 0);
 #endif
 
         set_idt_entries_present(true);