]> xenbits.xensource.com Git - people/andrewcoop/xen-test-framework.git/commitdiff
Modify exec_user() to pass a return value back from the called function
authorAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 14 Oct 2016 13:18:35 +0000 (14:18 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 14 Oct 2016 13:42:57 +0000 (14:42 +0100)
This turns out to be rather more useful in general, and the only changes
required to make it work is not to clobber %eax on the return back to kernel.

A compatability exec_user_void() is introduced to wrap exec_user() for
existing users with void functions.  The exec_user selftest is updated to use
the new functionality, instead of passing a result back via a static variable.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/entry_32.S
arch/x86/entry_64.S
include/xtf/lib.h
tests/selftest/main.c
tests/swint-emulation/main.c

index ee3c6b01a675845e043e605caaa1f890e6042126..395bd15662e28144eb077234eac1b2a8f89ed001 100644 (file)
@@ -91,9 +91,9 @@ ENTRY(entry_ret_to_kernel)      /* int $X86_VEC_RET2KERN */
 
         /* User required to ensure this is called from CPL > KERNEL_RPL */
 
-        mov 0*4(%esp), %eax     /* Stash %eip from iret frame */
+        mov 0*4(%esp), %ecx     /* Stash %eip from iret frame */
         mov 3*4(%esp), %esp     /* Load %esp from iret frame  */
-        jmp *%eax               /* Jump back                  */
+        jmp *%ecx               /* Jump back                  */
 
 ENDFUNC(entry_ret_to_kernel)
 
index 01b0156f4bb29b7accf91b7d4fd4b79b86b3741c..d76d326501405e869c59d71a195e766269554ae8 100644 (file)
@@ -104,9 +104,9 @@ ENDFUNC(handle_exception)
 ENTRY(entry_ret_to_kernel)      /* int $X86_VEC_RET2KERN */
         env_ADJUST_FRAME
 
-        mov 0*8(%rsp), %rax     /* Stash %rip from iret frame */
+        mov 0*8(%rsp), %rdi     /* Stash %rip from iret frame */
         mov 3*8(%rsp), %rsp     /* Load %esp from iret frame  */
-        jmp *%rax               /* Jump back                  */
+        jmp *%rdi               /* Jump back                  */
 
 ENDFUNC(entry_ret_to_kernel)
 
index 36b018b3ab51e0ddd6fb347331c04f9475b5bdbe..b0ae39d23486591501661461e0135d7184536f5a 100644 (file)
@@ -51,8 +51,19 @@ void heapsort(void *base, size_t nmemb, size_t size,
               int (*compar)(const void *, const void *),
               void (*swap)(void *, void *));
 
-/* Execute fn() at user privilege on the current stack. */
-void exec_user(void (*fn)(void));
+/*
+ * Execute fn() at user privilege on the current stack, passing its return
+ * value back.
+ */
+unsigned long exec_user(unsigned long (*fn)(void));
+
+/*
+ * Wrapper around exec_user() which calls a void function.
+ */
+static inline void exec_user_void(void (*fn)(void))
+{
+    exec_user((void *)fn);
+}
 
 #endif /* XTF_LIB_H */
 
index 5ff24674203e66de66a4b3b6794f25d232662351..84aa6376f0dc9d8892db4ee3e6f1b0a02a12f79b 100644 (file)
@@ -139,41 +139,38 @@ static void test_exlog(void)
     xtf_exlog_stop();
 }
 
-static enum {
+enum {
     USER_not_seen,
     USER_seen,
     USER_bad_cs,
-} seen_from_userspace = USER_not_seen;
+};
 
-static void test_exec_user_cpl3(void)
+static unsigned long test_exec_user_cpl3(void)
 {
-    unsigned int cs = read_cs();
-
-    if ( (cs & 3) == 3 )
-        seen_from_userspace = USER_seen;
-    else
-        seen_from_userspace = USER_bad_cs;
+    return ((read_cs() & 3) == 3) ? USER_seen : USER_bad_cs;
 }
 
 static void test_exec_user(void)
 {
+    unsigned int res;
+
     printk("Test: Userspace execution\n");
 
-    exec_user(test_exec_user_cpl3);
+    res = exec_user(test_exec_user_cpl3);
 
-    switch ( seen_from_userspace )
+    switch ( res )
     {
     case USER_seen:
         /* Success */
         break;
 
-    case USER_not_seen:
-        xtf_failure("Fail: Did not execute function\n");
-        break;
-
     case USER_bad_cs:
         xtf_failure("Fail: Not at cpl3\n");
         break;
+
+    default:
+        xtf_failure("Fail: Did not execute function\n");
+        break;
     }
 }
 
index 1f9f5053a4a5ca6a8462fe65842d11d17784ff5f..34adf1723fa37f4b6a4beae80f27534df6265a06 100644 (file)
@@ -237,7 +237,7 @@ void test_seq(struct sequence *seq, unsigned int vector,
                fault ? s->fault : s->trap,
                vector, error);
 
-        user ? exec_user(s->fn) : s->fn();
+        user ? exec_user_void(s->fn) : s->fn();
 
         check();