Skip to content

Commit 78393fd

Browse files
amlutoIngo Molnar
authored andcommitted
selftests/x86/entry_from_vm86: Add test cases for POPF
POPF is currently broken -- add tests to catch the error. This results in: [RUN] POPF with VIP set and IF clear from vm86 mode [INFO] Exited vm86 mode due to STI [FAIL] Incorrect return reason (started at eip = 0xd, ended at eip = 0xf) because POPF currently fails to check IF before reporting a pending interrupt. This patch also makes the FAIL message a bit more informative. Reported-by: Bart Oldeman <[email protected]> Signed-off-by: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Stas Sergeev <[email protected]> Cc: Thomas Gleixner <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/a16270b5cfe7832d6d00c479d0f871066cbdb52b.1521003603.git.luto@kernel.org Signed-off-by: Ingo Molnar <[email protected]>
1 parent 327d53d commit 78393fd

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

tools/testing/selftests/x86/entry_from_vm86.c

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,10 @@ asm (
9595
"int3\n\t"
9696
"vmcode_int80:\n\t"
9797
"int $0x80\n\t"
98+
"vmcode_popf_hlt:\n\t"
99+
"push %ax\n\t"
100+
"popf\n\t"
101+
"hlt\n\t"
98102
"vmcode_umip:\n\t"
99103
/* addressing via displacements */
100104
"smsw (2052)\n\t"
@@ -124,8 +128,8 @@ asm (
124128

125129
extern unsigned char vmcode[], end_vmcode[];
126130
extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[],
127-
vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_umip[],
128-
vmcode_umip_str[], vmcode_umip_sldt[];
131+
vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_popf_hlt[],
132+
vmcode_umip[], vmcode_umip_str[], vmcode_umip_sldt[];
129133

130134
/* Returns false if the test was skipped. */
131135
static 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,
175179
(VM86_TYPE(ret) == rettype && VM86_ARG(ret) == retarg)) {
176180
printf("[OK]\tReturned correctly\n");
177181
} 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);
179183
nerrs++;
180184
}
181185

@@ -264,6 +268,9 @@ int main(void)
264268
v86.regs.ds = load_addr / 16;
265269
v86.regs.es = load_addr / 16;
266270

271+
/* Use the end of the page as our stack. */
272+
v86.regs.esp = 4096;
273+
267274
assert((v86.regs.cs & 3) == 0); /* Looks like RPL = 0 */
268275

269276
/* #BR -- should deliver SIG??? */
@@ -295,6 +302,23 @@ int main(void)
295302
v86.regs.eflags &= ~X86_EFLAGS_IF;
296303
do_test(&v86, vmcode_sti - vmcode, VM86_STI, 0, "STI with VIP set");
297304

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+
298322
/* INT3 -- should cause #BP */
299323
do_test(&v86, vmcode_int3 - vmcode, VM86_TRAP, 3, "INT3");
300324

0 commit comments

Comments
 (0)