]> xenbits.xensource.com Git - xtf.git/commitdiff
Allow for fine tuning of the exec_user_* infrastructure
authorAndrew Cooper <andrew.cooper3@citrix.com>
Wed, 7 Feb 2018 10:41:41 +0000 (10:41 +0000)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Thu, 15 Feb 2018 13:50:49 +0000 (13:50 +0000)
At the moment, %cs, %ss and eflags are hard coded.  Introduce
exec_user_{cs,ss,efl_{and,or}_mask} with suitable defaults.

This allows for the complete removal of exec_user_with_iopl() from the pv-iopl
test, which can now use the common infrastructure.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/entry_32.S
arch/x86/entry_64.S
arch/x86/include/arch/traps.h
arch/x86/traps.c
tests/pv-iopl/Makefile
tests/pv-iopl/asm.S [deleted file]
tests/pv-iopl/main.c

index 9869b78c70cc20a3cfca8b798b165029004ec8f2..b49b0e772b843561e2013353d366269c24937625 100644 (file)
@@ -119,16 +119,18 @@ ENTRY(exec_user_param)
         mov %esp, %ebp          /* Stash %esp for entry_ret_to_kernel(). */
 
         /* Prepare an IRET frame. */
-        push $__USER_DS         /* SS */
+        push exec_user_ss       /* SS */
                                 /* ESP */
         push $user_stack + PAGE_SIZE
         pushf                   /* EFLAGS */
 
-#if defined(CONFIG_PV)          /* PV guests see the real interrupt flag. Clobber it. */
-        andl $~X86_EFLAGS_IF, (%esp)
-#endif
+        /* Apply and/or masks to eflags. */
+        mov exec_user_efl_and_mask, %edx
+        and %edx, (%esp)
+        mov exec_user_efl_or_mask, %edx
+        or %edx, (%esp)
 
-        push $__USER_CS         /* CS */
+        push exec_user_cs       /* CS */
         push $exec_user_stub    /* EIP */
 
         env_IRET                /* Drop to user privilege. */
index e6a81f07f7843038f3eb6ac854dae54ad1bb9a66..c638e601821e2b0311883564f1eaeb36cc27c2df 100644 (file)
@@ -117,16 +117,18 @@ ENTRY(exec_user_param)          /* ulong (*fn)(ulong), ulong p1 */
         mov %rsp, %rbp          /* Stash %rsp for entry_ret_to_kernel(). */
 
         /* Prepare an IRET frame. */
-        push $__USER_DS         /* SS */
+        push exec_user_ss(%rip) /* SS */
                                 /* RSP */
         push $user_stack + PAGE_SIZE
         pushf                   /* RFLAGS */
 
-#if defined(CONFIG_PV)          /* PV guests see the real interrupt flag. Clobber it. */
-        andq $~X86_EFLAGS_IF, (%rsp)
-#endif
+        /* Apply and/or masks to eflags. */
+        mov exec_user_efl_and_mask(%rip), %rdx
+        and %rdx, (%esp)
+        mov exec_user_efl_or_mask(%rip), %rdx
+        or %rdx, (%esp)
 
-        push $__USER_CS         /* CS */
+        push exec_user_cs(%rip) /* CS */
         push $exec_user_stub    /* RIP */
 
         env_IRETQ               /* Drop to user privilege. */
index e2e7f6942f246a5ac32f74dfe3891b5c122853a6..0c6888b6a09f549dfed0342473a9659d5df750ca 100644 (file)
@@ -59,6 +59,13 @@ extern xen_pv_start_info_t *pv_start_info;
 extern xen_pvh_start_info_t *pvh_start_info;
 extern shared_info_t shared_info;
 
+/*
+ * Parameters for fine tuning the exec_user_*() behaviour.
+ */
+extern unsigned long exec_user_cs, exec_user_ss;
+extern unsigned long exec_user_efl_and_mask;
+extern unsigned long exec_user_efl_or_mask;
+
 #endif /* XTF_X86_TRAPS_H */
 
 /*
index a09c8e2873f2183fd606fd0c077344a2e1a29b8f..8fee587930d8a5d64ff0e459e44188d8e891f422 100644 (file)
@@ -6,6 +6,16 @@
 #include <arch/lib.h>
 #include <arch/processor.h>
 
+/*
+ * Parameters for fine tuning the exec_user_*() behaviour.  PV guests see the
+ * real interrupt flag, so mask it by default.
+ */
+unsigned long exec_user_cs = __USER_CS;
+unsigned long exec_user_ss = __USER_DS;
+unsigned long exec_user_efl_and_mask =
+    ~(IS_DEFINED(CONFIG_PV) ? X86_EFLAGS_IF : 0);
+unsigned long exec_user_efl_or_mask;
+
 bool (*xtf_unhandled_exception_hook)(struct cpu_regs *regs);
 
 /*
index ec2f829a9b3070c368f21f09ef1adb34ce6d03aa..ce28b3ac3bd9063167bb8a4c5195b2debc4a11e5 100644 (file)
@@ -6,6 +6,6 @@ TEST-ENVS := $(PV_ENVIRONMENTS)
 
 VARY-CFG  := hypercall vmassist
 
-obj-perenv += main.o asm.o
+obj-perenv += main.o
 
 include $(ROOT)/build/gen.mk
diff --git a/tests/pv-iopl/asm.S b/tests/pv-iopl/asm.S
deleted file mode 100644 (file)
index ac1c85d..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-#include <arch/processor.h>
-#include <arch/page.h>
-#include <arch/segment.h>
-#include <xtf/asm_macros.h>
-
-ENTRY(exec_user_with_iopl)      /* void (*fn)(void), unsigned int iopl */
-        push %_ASM_BP
-
-        /* Prepare to "call" exec_user_stub(). */
-#ifdef __i386__
-        mov (1+1)*4(%esp), %eax /* Pass fn() in %eax */
-#endif
-        push $1f                /* Fake return addr as if we'd called exec_user_stub(). */
-        mov %_ASM_SP, %_ASM_BP  /* Stash %esp for entry_ret_to_kernel(). */
-
-        /* Prepare an IRET frame. */
-        push $__USER_DS         /* SS */
-        push $user_stack + PAGE_SIZE
-                                /* ESP */
-        pushf                   /* EFLAGS */
-
-                                /* PV guests see the real interrupt flag. Clobber it. */
-        andl $~(X86_EFLAGS_IOPL | X86_EFLAGS_IF), (%_ASM_SP)
-#ifdef __i386__
-        mov  (5+2)*4(%esp), %ecx
-        shl  $12, %ecx
-        or   %ecx, (%esp)
-#else
-        shl  $12, %esi
-        or   %esi, (%rsp)
-#endif
-
-        push $__USER_CS         /* CS */
-        push $exec_user_stub    /* EIP */
-
-#ifdef __x86_64__
-        push $0
-#endif
-        jmp HYPERCALL_iret      /* Drop to user privilege. */
-
-1:      /* entry_ret_to_kernel() returns here with a sensible stack. */
-        pop %_ASM_BP
-        ret
-
-ENDFUNC(exec_user_with_iopl)
-
-/*
- * Local variables:
- * tab-width: 8
- * indent-tabs-mode: nil
- * End:
- */
index f6dc5ee7c1d4ac2a25f256c00973c9e708abd6c2..61b7194ebee34971933aa90c03ccee6e7fa6e344 100644 (file)
@@ -44,11 +44,6 @@ const char test_title[] = "PV IOPL emulation";
 
 bool test_wants_user_mappings = true;
 
-/**
- * Execute @p fn at user privilege, folding @p iopl into the iret frame.
- */
-void exec_user_with_iopl(void (*fn)(void), unsigned int iopl);
-
 /** Stub CLI instruction with @#GP fixup. */
 static void stub_cli(void)
 {
@@ -166,7 +161,8 @@ static void run_test(const struct test *t)
 
             /* Run insn in userspace. */
             expect(seq->name, 1, t->should_fault(1, iopl));
-            exec_user_with_iopl(seq->fn, iopl);
+            exec_user_void(seq->fn);
+
             check();
         }
     }
@@ -219,7 +215,8 @@ static void vmassist_set_iopl(unsigned int iopl)
      * with the appropriate iopl set.  Reuse the exec_user infrastructure to
      * issue the iret, and execute nothing interesting in user context.
      */
-    exec_user_with_iopl(nop, iopl);
+    exec_user_efl_or_mask = iopl << 12;
+    exec_user_void(nop);
 }
 
 static bool vmassist_should_fault(bool user, unsigned int iopl)