]> xenbits.xensource.com Git - xtf.git/commitdiff
Implement exec_user_param()
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 23 Aug 2016 14:55:22 +0000 (15:55 +0100)
committerAndrew Cooper <andrew.cooper3@citrix.com>
Fri, 16 Dec 2016 20:54:13 +0000 (20:54 +0000)
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
arch/x86/entry_32.S
arch/x86/entry_64.S
include/xtf/lib.h

index 2f2435bc25ea45e2a937a57856b181a635f97d97..0ac041633eea6f07a693b2565b19550af1e8d8c0 100644 (file)
@@ -109,7 +109,12 @@ ENTRY(entry_ret_to_kernel)      /* int $X86_VEC_RET2KERN */
 
 ENDFUNC(entry_ret_to_kernel)
 
-ENTRY(exec_user)                /* void (*fn)(void) */
+ENTRY(exec_user_param)
+        /*
+         * 2*4(%esp) ulong p1
+         * 1*4(%esp) ulong (*fn)(ulong)
+         * 0*4(%esp) return address
+         */
 
         push $__USER_DS         /* SS */
         push %esp
@@ -125,11 +130,25 @@ ENTRY(exec_user)                /* void (*fn)(void) */
 
         env_IRET                /* Drop to user privilege. */
 1:
-        call *4(%esp)           /* fn() */
+        push 2*4(%esp)          /* Re-push p1 for fn()'s call frame. */
+        call *(1+1)*4(%esp)     /* fn(p1) */
+        add $1*4, %esp          /* Pop p1. */
 
         int $X86_VEC_RET2KERN   /* Return to kernel privilege. */
         ret
 
+ENDFUNC(exec_user_param)
+
+ENTRY(exec_user)
+        /*
+         * 1*4(%esp) ulong (*fn)(ulong)
+         * 0*4(%esp) return address
+         */
+        push $0xdead0000        /* Poison unused p1. */
+        push (1+1)*4(%esp)      /* Re-push fn for exec_user_param()'s call frame. */
+        call exec_user_param
+        add $2*4, %esp          /* Pop fn/p1. */
+        ret
 ENDFUNC(exec_user)
 
 /*
index d76d326501405e869c59d71a195e766269554ae8..76a25f7a324f863372fc60202210eea8dc40c218 100644 (file)
@@ -110,7 +110,7 @@ ENTRY(entry_ret_to_kernel)      /* int $X86_VEC_RET2KERN */
 
 ENDFUNC(entry_ret_to_kernel)
 
-ENTRY(exec_user)                /* void (*fn)(void) */
+ENTRY(exec_user_param)          /* ulong (*fn)(ulong), ulong p1 */
 
         push $__USER_DS         /* SS */
         push %rsp
@@ -126,11 +126,17 @@ ENTRY(exec_user)                /* void (*fn)(void) */
 
         env_IRETQ               /* Drop to user privilege. */
 1:
-        call *%rdi              /* fn() */
+        xchg %rdi, %rsi         /* Swap p1 to be first parameter to fn(). */
+        call *%rsi              /* fn(p1) */
 
         int $X86_VEC_RET2KERN   /* Return to kernel privilege. */
         ret
 
+ENDFUNC(exec_user_param)
+
+ENTRY(exec_user)                /* ulong (*fn)(ulong) */
+        mov $0xdead0000, %esi   /* Poison unused p1. */
+        jmp exec_user_param
 ENDFUNC(exec_user)
 
 /*
index 9db282dd7fe111b2004eb21821399cf741d96460..3441254655868c8237b5f5be2268d3d2d2d490a9 100644 (file)
@@ -67,6 +67,10 @@ static inline void exec_user_void(void (*fn)(void))
     exec_user((void *)fn);
 }
 
+/* Execute fn(p1) at user privilege. */
+unsigned long exec_user_param(unsigned long (*fn)(unsigned long),
+                              unsigned long p1);
+
 /**
  * Probe for the SYSCTL_INTERFACE_VERSION in use by the hypervisor
  * @returns version, or -1 on failure.