aboutsummaryrefslogtreecommitdiffstats
path: root/tools/testing/selftests/x86/entry_from_vm86.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/testing/selftests/x86/entry_from_vm86.c')
-rw-r--r--tools/testing/selftests/x86/entry_from_vm86.c32
1 files changed, 28 insertions, 4 deletions
diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c
index 361466a2eaef..ade443a88421 100644
--- a/tools/testing/selftests/x86/entry_from_vm86.c
+++ b/tools/testing/selftests/x86/entry_from_vm86.c
@@ -95,6 +95,10 @@ asm (
95 "int3\n\t" 95 "int3\n\t"
96 "vmcode_int80:\n\t" 96 "vmcode_int80:\n\t"
97 "int $0x80\n\t" 97 "int $0x80\n\t"
98 "vmcode_popf_hlt:\n\t"
99 "push %ax\n\t"
100 "popf\n\t"
101 "hlt\n\t"
98 "vmcode_umip:\n\t" 102 "vmcode_umip:\n\t"
99 /* addressing via displacements */ 103 /* addressing via displacements */
100 "smsw (2052)\n\t" 104 "smsw (2052)\n\t"
@@ -124,8 +128,8 @@ asm (
124 128
125extern unsigned char vmcode[], end_vmcode[]; 129extern unsigned char vmcode[], end_vmcode[];
126extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[], 130extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[],
127 vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_umip[], 131 vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_popf_hlt[],
128 vmcode_umip_str[], vmcode_umip_sldt[]; 132 vmcode_umip[], vmcode_umip_str[], vmcode_umip_sldt[];
129 133
130/* Returns false if the test was skipped. */ 134/* Returns false if the test was skipped. */
131static bool do_test(struct vm86plus_struct *v86, unsigned long eip, 135static bool do_test(struct vm86plus_struct *v86, unsigned long eip,
@@ -175,7 +179,7 @@ static bool do_test(struct vm86plus_struct *v86, unsigned long eip,
175 (VM86_TYPE(ret) == rettype && VM86_ARG(ret) == retarg)) { 179 (VM86_TYPE(ret) == rettype && VM86_ARG(ret) == retarg)) {
176 printf("[OK]\tReturned correctly\n"); 180 printf("[OK]\tReturned correctly\n");
177 } else { 181 } else {
178 printf("[FAIL]\tIncorrect return reason\n"); 182 printf("[FAIL]\tIncorrect return reason (started at eip = 0x%lx, ended at eip = 0x%lx)\n", eip, v86->regs.eip);
179 nerrs++; 183 nerrs++;
180 } 184 }
181 185
@@ -264,6 +268,9 @@ int main(void)
264 v86.regs.ds = load_addr / 16; 268 v86.regs.ds = load_addr / 16;
265 v86.regs.es = load_addr / 16; 269 v86.regs.es = load_addr / 16;
266 270
271 /* Use the end of the page as our stack. */
272 v86.regs.esp = 4096;
273
267 assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */ 274 assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */
268 275
269 /* #BR -- should deliver SIG??? */ 276 /* #BR -- should deliver SIG??? */
@@ -295,6 +302,23 @@ int main(void)
295 v86.regs.eflags &= ~X86_EFLAGS_IF; 302 v86.regs.eflags &= ~X86_EFLAGS_IF;
296 do_test(&v86, vmcode_sti - vmcode, VM86_STI, 0, "STI with VIP set"); 303 do_test(&v86, vmcode_sti - vmcode, VM86_STI, 0, "STI with VIP set");
297 304
305 /* POPF with VIP set but IF clear: should not trap */
306 v86.regs.eflags = X86_EFLAGS_VIP;
307 v86.regs.eax = 0;
308 do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP set and IF clear");
309
310 /* POPF with VIP set and IF set: should trap */
311 v86.regs.eflags = X86_EFLAGS_VIP;
312 v86.regs.eax = X86_EFLAGS_IF;
313 do_test(&v86, vmcode_popf_hlt - vmcode, VM86_STI, 0, "POPF with VIP and IF set");
314
315 /* POPF with VIP clear and IF set: should not trap */
316 v86.regs.eflags = 0;
317 v86.regs.eax = X86_EFLAGS_IF;
318 do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP clear and IF set");
319
320 v86.regs.eflags = 0;
321
298 /* INT3 -- should cause #BP */ 322 /* INT3 -- should cause #BP */
299 do_test(&v86, vmcode_int3 - vmcode, VM86_TRAP, 3, "INT3"); 323 do_test(&v86, vmcode_int3 - vmcode, VM86_TRAP, 3, "INT3");
300 324
@@ -318,7 +342,7 @@ int main(void)
318 clearhandler(SIGSEGV); 342 clearhandler(SIGSEGV);
319 343
320 /* Make sure nothing explodes if we fork. */ 344 /* Make sure nothing explodes if we fork. */
321 if (fork() > 0) 345 if (fork() == 0)
322 return 0; 346 return 0;
323 347
324 return (nerrs == 0 ? 0 : 1); 348 return (nerrs == 0 ? 0 : 1);