Complement commit 663f9e447b98 ("x86: Fix a #GP from occurring in usermode library's exception handlers") and restore SS on a regular return as well. The INT-based "syscall" will make it get loaded with the NULL selector (see SDM Vol. 1, Interrupt and Exception Behavior in 64-Bit Mode: "The new SS is set to NULL if there is a change in CPL.") which makes the "mov null, %%ss" test of emulator64.c dubious, as SS is already loaded with the NULL selector. Fix this by loading SS with KERNEL_DS after a successful userland function call as well, as we already do in case of exceptions. Signed-off-by: Mathias Krause <minipli@xxxxxxxxxxxxxx> --- lib/x86/usermode.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/lib/x86/usermode.c b/lib/x86/usermode.c index fd19551a7a2d..9ae4cb17fd63 100644 --- a/lib/x86/usermode.c +++ b/lib/x86/usermode.c @@ -97,6 +97,13 @@ uint64_t run_in_user(usermode_func func, unsigned int fault_vector, /* Kernel Mode */ "ret_to_kernel:\n\t" "mov %[rsp0], %%rsp\n\t" +#ifdef __x86_64__ + /* Restore SS, as it forcibly gets loaded with NULL */ + "push %%rax\n\t" + "mov %[kernel_ds], %%ax\n\t" + "mov %%ax, %%ss\n\t" + "pop %%rax\n\t" +#endif : "+a"(rax), [rsp0]"=m"(tss[0].rsp0) @@ -108,6 +115,7 @@ uint64_t run_in_user(usermode_func func, unsigned int fault_vector, [func]"m"(func), [user_ds]"i"(USER_DS), [user_cs]"i"(USER_CS), + [kernel_ds]"i"(KERNEL_DS), [user_stack_top]"r"(user_stack + sizeof(user_stack)), [kernel_entry_vector]"i"(RET_TO_KERNEL_IRQ)); -- 2.39.2