From: Sergiu Moga Date: Sat, 4 Nov 2023 14:54:34 +0000 (+0200) Subject: plat/common/x86: Save `ss`/`rsp`/`eflags`/`cs`/`rip` on syscall frame X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=f0188fff661529c403ea7e88d2333807fda3d512;p=unikraft%2Funikraft.git plat/common/x86: Save `ss`/`rsp`/`eflags`/`cs`/`rip` on syscall frame Previously, we would save zeroes on the syscall entry frame instead of using the actual values for the registers that would normally be popped off the stack since they would not be used anyway by a syscall. For completeness's sake, do still save them, to offer those that may view the structure a clear view of what the syscall will return to. Furthermore, we no longer need to clear the stack before syscall exit (the previous `addq $(6 * 8), %rsp`) because the auxiliary stack is used instead, so do not do this operation anymore. Signed-off-by: Sergiu Moga --- diff --git a/plat/common/x86/syscall.S b/plat/common/x86/syscall.S index 5604dd36d..68565f133 100644 --- a/plat/common/x86/syscall.S +++ b/plat/common/x86/syscall.S @@ -31,7 +31,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ +#include #include +#include #include #include @@ -63,6 +65,8 @@ ENTRY(_ukplat_syscall) */ movq %gs:LCPU_AUXSP_OFFSET, %rsp + pushq_cfi $(GDT_DESC_OFFSET(GDT_DESC_DATA)) + /* Store application's stack pointer at the top of current thread's * auxiliary stack. We have to do this because we obviously can't * rely on the scratch register being maintained between thread switches @@ -73,8 +77,11 @@ ENTRY(_ukplat_syscall) /* We are now in a state where the stack looks like this: * --------------- <-- auxsp (i.e. lcpu_get_current()->auxsp OR * | app's saved | uk_thread_current()->auxsp) + * | %ss | + * --------------- + * | app's saved | * | %rsp | - * --------------- <-- (auxsp - 8) OR (**current %rsp**) + * --------------- <-- (auxsp - 16) OR (**current %rsp**) * | | * | | * ... @@ -83,25 +90,18 @@ ENTRY(_ukplat_syscall) * END OF AUXSP */ - /* Make a final alignment so that we preserve syscall semantics where - * register pushes on the stack are happening on an initially 16-byte - * aligned stack. - * Therefore, all in-syscall context operations, buffer and function - * frames must fit into (CONFIG_UKPLAT_AUXSP_SIZE - 16) bytes. - */ - subq $8, %rsp - .cfi_adjust_cfa_offset 8 - /* * Push arguments in the order of 'struct __regs' to the stack. * We are going to handover a refernce to this stack area as * `struct __regs *` argument to the system call handler. */ - pushq_cfi $0 /* exception frame filled with zeros */ - pushq_cfi $0 /* (rip, cs, eflags, rsp, ss) */ - pushq_cfi $0 /* */ - pushq_cfi $0 /* */ - pushq_cfi $0 /* */ + /* We now have %ss and %rsp on the frame, finish classic trap frame */ + pushfq /* eflags */ + .cfi_adjust_cfa_offset 8 + + pushq_cfi $(GDT_DESC_OFFSET(GDT_DESC_CODE)) /* cs */ + pushq_reg_cfi rcx /* rcx contains the next rip on syscall exit */ + pushq_reg_cfi rax /* orig_rax */ pushq_reg_cfi rdi pushq_reg_cfi rsi @@ -167,19 +167,8 @@ ENTRY(_ukplat_syscall) popq_reg_cfi rdx popq_reg_cfi rsi popq_reg_cfi rdi - /* orig_rax and exception frame */ - addq $(6 * 8), %rsp - .cfi_adjust_cfa_offset -(6 * 8) - - /* Undo alignment done after storing application %rsp */ - addq $8, %rsp - .cfi_adjust_cfa_offset -8 - /* We are now back in the state where the stack was looking like the - * diagram above. Restore application %rsp! - */ - movq 8(%rsp), %rsp - .cfi_adjust_cfa_offset -__REGS_PAD_SIZE + movq 32(%rsp), %rsp /* Restore application's gs_base register */ swapgs