aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRicardo Neri <ricardo.neri-calderon@linux.intel.com>2017-11-05 21:27:57 -0500
committerIngo Molnar <mingo@kernel.org>2017-11-08 05:16:25 -0500
commita9e017d5619eb371460c8e516f4684def62bef3a (patch)
tree13ae05e2179580b98d2b5b0bc22be34beb6feaa2
parent9390afebe1d3f5a0be18b1afdd0ce09d67cebf9e (diff)
selftests/x86: Add tests for the STR and SLDT instructions
The STR and SLDT instructions are not valid when running on virtual-8086 mode and generate an invalid operand exception. These two instructions are protected by the Intel User-Mode Instruction Prevention (UMIP) security feature. In protected mode, if UMIP is enabled, these instructions generate a general protection fault if called from CPL > 0. Linux traps the general protection fault and emulates the instructions sgdt, sidt and smsw; but not str and sldt. These tests are added to verify that the emulation code does not emulate these two instructions but the expected invalid operand exception is seen. Tests fallback to exit with INT3 in case emulation does happen. Signed-off-by: Ricardo Neri <ricardo.neri-calderon@linux.intel.com> Reviewed-by: Thomas Gleixner <tglx@linutronix.de> Cc: Andrew Morton <akpm@linux-foundation.org> Cc: Andy Lutomirski <luto@kernel.org> Cc: Borislav Petkov <bp@alien8.de> Cc: Borislav Petkov <bp@suse.de> Cc: Brian Gerst <brgerst@gmail.com> Cc: Chen Yucong <slaoub@gmail.com> Cc: Chris Metcalf <cmetcalf@mellanox.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: Denys Vlasenko <dvlasenk@redhat.com> Cc: Fenghua Yu <fenghua.yu@intel.com> Cc: H. Peter Anvin <hpa@zytor.com> Cc: Huang Rui <ray.huang@amd.com> Cc: Jiri Slaby <jslaby@suse.cz> Cc: Jonathan Corbet <corbet@lwn.net> Cc: Josh Poimboeuf <jpoimboe@redhat.com> Cc: Linus Torvalds <torvalds@linux-foundation.org> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Michael S. Tsirkin <mst@redhat.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Paul Gortmaker <paul.gortmaker@windriver.com> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Ravi V. Shankar <ravi.v.shankar@intel.com> Cc: Shuah Khan <shuah@kernel.org> Cc: Tony Luck <tony.luck@intel.com> Cc: Vlastimil Babka <vbabka@suse.cz> Cc: ricardo.neri@intel.com Link: http://lkml.kernel.org/r/1509935277-22138-13-git-send-email-ricardo.neri-calderon@linux.intel.com Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r--tools/testing/selftests/x86/entry_from_vm86.c18
1 files changed, 17 insertions, 1 deletions
diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c
index f7d9ceac7e06..361466a2eaef 100644
--- a/tools/testing/selftests/x86/entry_from_vm86.c
+++ b/tools/testing/selftests/x86/entry_from_vm86.c
@@ -111,6 +111,11 @@ asm (
111 "smsw %ax\n\t" 111 "smsw %ax\n\t"
112 "mov %ax, (2080)\n\t" 112 "mov %ax, (2080)\n\t"
113 "int3\n\t" 113 "int3\n\t"
114 "vmcode_umip_str:\n\t"
115 "str %eax\n\t"
116 "vmcode_umip_sldt:\n\t"
117 "sldt %eax\n\t"
118 "int3\n\t"
114 ".size vmcode, . - vmcode\n\t" 119 ".size vmcode, . - vmcode\n\t"
115 "end_vmcode:\n\t" 120 "end_vmcode:\n\t"
116 ".code32\n\t" 121 ".code32\n\t"
@@ -119,7 +124,8 @@ asm (
119 124
120extern unsigned char vmcode[], end_vmcode[]; 125extern unsigned char vmcode[], end_vmcode[];
121extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[], 126extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[],
122 vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_umip[]; 127 vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_umip[],
128 vmcode_umip_str[], vmcode_umip_sldt[];
123 129
124/* Returns false if the test was skipped. */ 130/* Returns false if the test was skipped. */
125static bool do_test(struct vm86plus_struct *v86, unsigned long eip, 131static bool do_test(struct vm86plus_struct *v86, unsigned long eip,
@@ -226,6 +232,16 @@ void do_umip_tests(struct vm86plus_struct *vm86, unsigned char *test_mem)
226 printf("[FAIL]\tAll the results of SIDT should be the same.\n"); 232 printf("[FAIL]\tAll the results of SIDT should be the same.\n");
227 else 233 else
228 printf("[PASS]\tAll the results from SIDT are identical.\n"); 234 printf("[PASS]\tAll the results from SIDT are identical.\n");
235
236 sethandler(SIGILL, sighandler, 0);
237 do_test(vm86, vmcode_umip_str - vmcode, VM86_SIGNAL, 0,
238 "STR instruction");
239 clearhandler(SIGILL);
240
241 sethandler(SIGILL, sighandler, 0);
242 do_test(vm86, vmcode_umip_sldt - vmcode, VM86_SIGNAL, 0,
243 "SLDT instruction");
244 clearhandler(SIGILL);
229} 245}
230 246
231int main(void) 247int main(void)