/* 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)
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)
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 */
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;
}
}
fault ? s->fault : s->trap,
vector, error);
- user ? exec_user(s->fn) : s->fn();
+ user ? exec_user_void(s->fn) : s->fn();
check();