selftests/x86/entry_from_vm86: Add test cases for POPF

Linux-MTD Mailing List linux-mtd at lists.infradead.org
Mon Mar 19 02:59:07 PDT 2018


Gitweb:     http://git.infradead.org/?p=mtd-2.6.git;a=commit;h=78393fdde2a456cafa414b171c90f26a3df98b20
Commit:     78393fdde2a456cafa414b171c90f26a3df98b20
Parent:     327d53d005ca47b10eae940616ed11c569f75a9b
Author:     Andy Lutomirski <luto at kernel.org>
AuthorDate: Tue Mar 13 22:03:11 2018 -0700
Committer:  Ingo Molnar <mingo at kernel.org>
CommitDate: Wed Mar 14 09:21:01 2018 +0100

    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 <bartoldeman at gmail.com>
    Signed-off-by: Andy Lutomirski <luto at kernel.org>
    Cc: Borislav Petkov <bp at alien8.de>
    Cc: Brian Gerst <brgerst at gmail.com>
    Cc: Denys Vlasenko <dvlasenk at redhat.com>
    Cc: H. Peter Anvin <hpa at zytor.com>
    Cc: Josh Poimboeuf <jpoimboe at redhat.com>
    Cc: Linus Torvalds <torvalds at linux-foundation.org>
    Cc: Peter Zijlstra <peterz at infradead.org>
    Cc: Stas Sergeev <stsp at list.ru>
    Cc: Thomas Gleixner <tglx at linutronix.de>
    Cc: stable at vger.kernel.org
    Link: http://lkml.kernel.org/r/a16270b5cfe7832d6d00c479d0f871066cbdb52b.1521003603.git.luto@kernel.org
    Signed-off-by: Ingo Molnar <mingo at kernel.org>
---
 tools/testing/selftests/x86/entry_from_vm86.c | 30 ++++++++++++++++++++++++---
 1 file changed, 27 insertions(+), 3 deletions(-)

diff --git a/tools/testing/selftests/x86/entry_from_vm86.c b/tools/testing/selftests/x86/entry_from_vm86.c
index 6e85f0d0498d..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 (
 	"int3\n\t"
 	"vmcode_int80:\n\t"
 	"int $0x80\n\t"
+	"vmcode_popf_hlt:\n\t"
+	"push %ax\n\t"
+	"popf\n\t"
+	"hlt\n\t"
 	"vmcode_umip:\n\t"
 	/* addressing via displacements */
 	"smsw (2052)\n\t"
@@ -124,8 +128,8 @@ asm (
 
 extern unsigned char vmcode[], end_vmcode[];
 extern unsigned char vmcode_bound[], vmcode_sysenter[], vmcode_syscall[],
-	vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_umip[],
-	vmcode_umip_str[], vmcode_umip_sldt[];
+	vmcode_sti[], vmcode_int3[], vmcode_int80[], vmcode_popf_hlt[],
+	vmcode_umip[], vmcode_umip_str[], vmcode_umip_sldt[];
 
 /* Returns false if the test was skipped. */
 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,
 	    (VM86_TYPE(ret) == rettype && VM86_ARG(ret) == retarg)) {
 		printf("[OK]\tReturned correctly\n");
 	} else {
-		printf("[FAIL]\tIncorrect return reason\n");
+		printf("[FAIL]\tIncorrect return reason (started at eip = 0x%lx, ended at eip = 0x%lx)\n", eip, v86->regs.eip);
 		nerrs++;
 	}
 
@@ -264,6 +268,9 @@ int main(void)
 	v86.regs.ds = load_addr / 16;
 	v86.regs.es = load_addr / 16;
 
+	/* Use the end of the page as our stack. */
+	v86.regs.esp = 4096;
+
 	assert((v86.regs.cs & 3) == 0);	/* Looks like RPL = 0 */
 
 	/* #BR -- should deliver SIG??? */
@@ -295,6 +302,23 @@ int main(void)
 	v86.regs.eflags &= ~X86_EFLAGS_IF;
 	do_test(&v86, vmcode_sti - vmcode, VM86_STI, 0, "STI with VIP set");
 
+	/* POPF with VIP set but IF clear: should not trap */
+	v86.regs.eflags = X86_EFLAGS_VIP;
+	v86.regs.eax = 0;
+	do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP set and IF clear");
+
+	/* POPF with VIP set and IF set: should trap */
+	v86.regs.eflags = X86_EFLAGS_VIP;
+	v86.regs.eax = X86_EFLAGS_IF;
+	do_test(&v86, vmcode_popf_hlt - vmcode, VM86_STI, 0, "POPF with VIP and IF set");
+
+	/* POPF with VIP clear and IF set: should not trap */
+	v86.regs.eflags = 0;
+	v86.regs.eax = X86_EFLAGS_IF;
+	do_test(&v86, vmcode_popf_hlt - vmcode, VM86_UNKNOWN, 0, "POPF with VIP clear and IF set");
+
+	v86.regs.eflags = 0;
+
 	/* INT3 -- should cause #BP */
 	do_test(&v86, vmcode_int3 - vmcode, VM86_TRAP, 3, "INT3");
 



More information about the linux-mtd-cvs mailing list