From nobody Fri Jun 17 19:40:33 2022 X-Original-To: dev-commits-src-branches@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id A71D385D23C; Fri, 17 Jun 2022 19:40:35 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4LPqC60bw9z3hfD; Fri, 17 Jun 2022 19:40:34 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655494834; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vvt7A+BDK/Ts4JT8T9mFbC3rUNckj4khfr8TCW5BsDw=; b=gs3J/ZPySAzBRmI57ozk+w1U345VLq0ODgjhX5HCADbg5W2+Tz46m7FDx8UZHK8nRVBXxQ zVR0fjkBdLK4wQYt/RqOffE+IzgXyc2Le6X9y+L6BdE5qrdtZpwBDX9ZlGxqCwscUuuC9E uZWfZmhnvF9VXbiSb0/rLiSyxnTdBUr+vLc797NXEJWulcLX6eqTucNPDo5Pla8Flrtola uWJv4KYGt4jcQQO72Y02VRq0R9zMhUJOroQwEonO7pAVVuA167HSSge6ZDbi5HZTrIqki0 H5CMfrrxo7Qgv5f7VQ9h+r5GtguMH4v8nU35jEx27aKbs+xipJM7c2OmhwzzPQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 970C125C65; Fri, 17 Jun 2022 19:40:33 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 25HJeXDv025963; Fri, 17 Jun 2022 19:40:33 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 25HJeXJV025962; Fri, 17 Jun 2022 19:40:33 GMT (envelope-from git) Date: Fri, 17 Jun 2022 19:40:33 GMT Message-Id: <202206171940.25HJeXJV025962@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Dmitry Chagin Subject: git: 0fae97fd1c7b - stable/13 - linux(4): Cleanup signal trampolines List-Id: Commits to the stable branches of the FreeBSD src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-branches List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-branches@freebsd.org X-BeenThere: dev-commits-src-branches@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: dchagin X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: 0fae97fd1c7b77c11b8f4bd239ce547bf5bf5aca Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1655494834; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=vvt7A+BDK/Ts4JT8T9mFbC3rUNckj4khfr8TCW5BsDw=; b=ufnqyQnCUsValBJKLRD3lACVYPJLGtLAlyYznajk+JdC99J545nxKtPctvG/bmaRSGxUUs JZ2D47Dv26H5UTJzdPEogxYiLs1ru/P53/iD9EOZLOkV+OVd48VZUgqlva+Tfsd6AQt6v6 HFpwk/92W8ObkOGyPQ4u413bboWKvo5bJ037Nkc9bel3gR6tvPN889f2I7AAuxON/8RsRv tSv7Sb6Yjgqw0CEW391Ts1XMSJv6QBsHIcd0JD0iaVEIwuwvvkmMQHJ/t10d2O+mLxUV39 hKKPymlgk0QJogZeUEAr2io1K1/o2lLUVN0eP6nfEKfQN9BRc/V2BhA0/ws9pg== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1655494834; a=rsa-sha256; cv=none; b=gvNY2FRJs9iFZ3hgGLyudzIEgwKpNuBnw//TlWk9FrRYNfmEChcngDsoviUeGcXClCuuCl UGaRb9AZjNcM514CPZaX1adoQ+4uF3D17WFSnG3cz9wsfQCtm3mYAJ+shTTREL9D6HK6Fm Lp9u/evEHGINn/Mluc06K9CxLncf27stugTbL1MP/YSohXAUwXdhhaIvCLNvCFMLL2CmdP mhMqqAEusJFSls5cfxFXHRD7D6lmWE/RhO4UzpifD/+X3VMHKrxgeX+SM3lLCWPtcdd8Gu kIf3YBICRtTuCtwjEQ7r59odi9G/6V3oKAuL+WKWSwofddtAq6M5rMGyOxQ/8w== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch stable/13 has been updated by dchagin: URL: https://cgit.FreeBSD.org/src/commit/?id=0fae97fd1c7b77c11b8f4bd239ce547bf5bf5aca commit 0fae97fd1c7b77c11b8f4bd239ce547bf5bf5aca Author: Dmitry Chagin AuthorDate: 2022-05-15 18:00:05 +0000 Commit: Dmitry Chagin CommitDate: 2022-06-17 19:35:19 +0000 linux(4): Cleanup signal trampolines This is the first stage of a signal trampolines refactoring. From trampolines retired emulation of the 'call' instruction, which is replaced by direct call of a signal handler. The signal handler address is in the register. The previous trampoline implemenatation used semi-Linux-way to call a signal handler via the 'jmp' instruction. Wherefore the trampoline emulated a 'call' instruction to into the stack the return address for signal handler's 'ret' instruction. Wherefore handmade DWARD annotations was used. While here rephrased and removed excessive comments. MFC after: 2 weeks (cherry picked from commit ba279bcd6d75aa236bcb9ccf11aeb6f51a2f8514) --- sys/amd64/linux/linux.h | 1 - sys/amd64/linux/linux_genassym.c | 1 - sys/amd64/linux/linux_locore.asm | 19 +++++-------------- sys/amd64/linux/linux_sysvec.c | 2 +- sys/amd64/linux32/linux.h | 4 ---- sys/amd64/linux32/linux32_genassym.c | 2 -- sys/amd64/linux32/linux32_locore.asm | 34 +++++++++------------------------- sys/amd64/linux32/linux32_sysvec.c | 4 ++-- sys/i386/linux/linux.h | 4 ---- sys/i386/linux/linux_genassym.c | 2 -- sys/i386/linux/linux_locore.asm | 32 ++++++++------------------------ sys/i386/linux/linux_sysvec.c | 4 ++-- 12 files changed, 27 insertions(+), 82 deletions(-) diff --git a/sys/amd64/linux/linux.h b/sys/amd64/linux/linux.h index 920ca98ce01b..08cf3d4b6bbd 100644 --- a/sys/amd64/linux/linux.h +++ b/sys/amd64/linux/linux.h @@ -314,7 +314,6 @@ typedef struct l_siginfo { struct l_rt_sigframe { struct l_ucontext sf_sc; struct l_siginfo sf_si; - l_handler_t sf_handler; }; /* diff --git a/sys/amd64/linux/linux_genassym.c b/sys/amd64/linux/linux_genassym.c index 0edb6a043531..73febbe6ef40 100644 --- a/sys/amd64/linux/linux_genassym.c +++ b/sys/amd64/linux/linux_genassym.c @@ -8,7 +8,6 @@ __FBSDID("$FreeBSD$"); #include #include -ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler)); ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE); diff --git a/sys/amd64/linux/linux_locore.asm b/sys/amd64/linux/linux_locore.asm index 8f7431d42737..92f0886185b1 100644 --- a/sys/amd64/linux/linux_locore.asm +++ b/sys/amd64/linux/linux_locore.asm @@ -11,23 +11,14 @@ linux_platform: .asciz "x86_64" - .text -/* - * To avoid excess stack frame the signal trampoline code emulates - * the 'call' instruction. - */ + ENTRY(linux_rt_sigcode) - movq %rsp, %rbx /* preserve sigframe */ - call .getip -.getip: - popq %rax - add $.startrtsigcode-.getip, %rax /* ret address */ - pushq %rax - jmp *LINUX_RT_SIGF_HANDLER(%rbx) + movq %rsp, %rbx /* rt_sigframe for rt_sigreturn */ + call *%rcx /* call signal handler */ .startrtsigcode: - movq $LINUX_SYS_linux_rt_sigreturn,%rax /* linux_rt_sigreturn() */ - syscall /* enter kernel with args */ + movq $LINUX_SYS_linux_rt_sigreturn, %rax + syscall hlt .endrtsigcode: 0: jmp 0b diff --git a/sys/amd64/linux/linux_sysvec.c b/sys/amd64/linux/linux_sysvec.c index cccf0bff1d5b..4c0806cc5c03 100644 --- a/sys/amd64/linux/linux_sysvec.c +++ b/sys/amd64/linux/linux_sysvec.c @@ -685,10 +685,10 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) regs->tf_rax = 0; regs->tf_rsi = (register_t)&sfp->sf_si; /* arg 2 in %rsi */ regs->tf_rdx = (register_t)&sfp->sf_sc; /* arg 3 in %rdx */ + regs->tf_rcx = (register_t)catcher; /* Fill in POSIX parts. */ siginfo_to_lsiginfo(&ksi->ksi_info, &sf.sf_si, sig); - sf.sf_handler = catcher; mtx_unlock(&psp->ps_mtx); PROC_UNLOCK(p); diff --git a/sys/amd64/linux32/linux.h b/sys/amd64/linux32/linux.h index 1273ff485dd9..ba7aeac517e1 100644 --- a/sys/amd64/linux32/linux.h +++ b/sys/amd64/linux32/linux.h @@ -429,15 +429,12 @@ struct l_fpstate { /* * We make the stack look like Linux expects it when calling a signal * handler, but use the BSD way of calling the handler and sigreturn(). - * This means that we need to pass the pointer to the handler too. - * It is appended to the frame to not interfere with the rest of it. */ struct l_sigframe { l_int sf_sig; struct l_sigcontext sf_sc; struct l_fpstate sf_fpstate; l_uint sf_extramask[1]; - l_handler_t sf_handler; }; struct l_rt_sigframe { @@ -446,7 +443,6 @@ struct l_rt_sigframe { l_uintptr_t sf_ucontext; l_siginfo_t sf_si; struct l_ucontext sf_sc; - l_handler_t sf_handler; } __packed; /* diff --git a/sys/amd64/linux32/linux32_genassym.c b/sys/amd64/linux32/linux32_genassym.c index bc94139c226d..ca618c01ffab 100644 --- a/sys/amd64/linux32/linux32_genassym.c +++ b/sys/amd64/linux32/linux32_genassym.c @@ -9,9 +9,7 @@ __FBSDID("$FreeBSD$"); #include #include -ASSYM(LINUX_SIGF_HANDLER, offsetof(struct l_sigframe, sf_handler)); ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc)); -ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler)); ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); ASSYM(LINUX_VERSION_CODE, LINUX_VERSION_CODE); diff --git a/sys/amd64/linux32/linux32_locore.asm b/sys/amd64/linux32/linux32_locore.asm index f96b3e730f9f..e0409969ee3b 100644 --- a/sys/amd64/linux32/linux32_locore.asm +++ b/sys/amd64/linux32/linux32_locore.asm @@ -14,38 +14,22 @@ linux_platform: .text .code32 -/* - * To avoid excess stack frame the signal trampoline code emulates - * the 'call' instruction. - */ ENTRY(__kernel_sigreturn) - movl %esp, %ebx /* preserve sigframe */ - call .getip0 -.getip0: - popl %eax - add $.startsigcode-.getip0, %eax /* ret address */ - push %eax - jmp *LINUX_SIGF_HANDLER(%ebx) + movl %esp, %ebx /* sigframe for sigreturn */ + call *%edi /* call signal handler */ .startsigcode: - popl %eax - movl $LINUX32_SYS_linux_sigreturn,%eax /* linux_sigreturn() */ - int $0x80 /* enter kernel with args */ + popl %eax /* gcc unwind code need this */ + movl $LINUX32_SYS_linux_sigreturn, %eax + int $0x80 .endsigcode: 0: jmp 0b ENTRY(__kernel_rt_sigreturn) - leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */ - leal LINUX_RT_SIGF_SC(%ebx),%ecx /* linux sigcontext */ - movl %esp, %edi - call .getip1 -.getip1: - popl %eax - add $.startrtsigcode-.getip1, %eax /* ret address */ - push %eax - jmp *LINUX_RT_SIGF_HANDLER(%edi) + leal LINUX_RT_SIGF_UC(%esp), %ebx /* linux ucontext for rt_sigreturn */ + call *%edi /* call signal handler */ .startrtsigcode: - movl $LINUX32_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */ - int $0x80 /* enter kernel with args */ + movl $LINUX32_SYS_linux_rt_sigreturn, %eax + int $0x80 .endrtsigcode: 0: jmp 0b diff --git a/sys/amd64/linux32/linux32_sysvec.c b/sys/amd64/linux32/linux32_sysvec.c index 998691223d44..967a5135fab9 100644 --- a/sys/amd64/linux32/linux32_sysvec.c +++ b/sys/amd64/linux32/linux32_sysvec.c @@ -314,7 +314,6 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) bzero(&frame, sizeof(frame)); - frame.sf_handler = PTROUT(catcher); frame.sf_sig = sig; frame.sf_siginfo = PTROUT(&fp->sf_si); frame.sf_ucontext = PTROUT(&fp->sf_sc); @@ -367,6 +366,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Build context to run handler in. */ regs->tf_rsp = PTROUT(fp); regs->tf_rip = __kernel_rt_sigreturn; + regs->tf_rdi = PTROUT(catcher); regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; regs->tf_ss = _udatasel; @@ -431,7 +431,6 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) bzero(&frame, sizeof(frame)); - frame.sf_handler = PTROUT(catcher); frame.sf_sig = sig; bsd_to_linux_sigset(mask, &lmask); @@ -473,6 +472,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Build context to run handler in. */ regs->tf_rsp = PTROUT(fp); regs->tf_rip = __kernel_sigreturn; + regs->tf_rdi = PTROUT(catcher); regs->tf_rflags &= ~(PSL_T | PSL_D); regs->tf_cs = _ucode32sel; regs->tf_ss = _udatasel; diff --git a/sys/i386/linux/linux.h b/sys/i386/linux/linux.h index 7fed468239a8..c26294ddc178 100644 --- a/sys/i386/linux/linux.h +++ b/sys/i386/linux/linux.h @@ -404,15 +404,12 @@ struct l_fpstate { /* * We make the stack look like Linux expects it when calling a signal * handler, but use the BSD way of calling the handler and sigreturn(). - * This means that we need to pass the pointer to the handler too. - * It is appended to the frame to not interfere with the rest of it. */ struct l_sigframe { l_int sf_sig; struct l_sigcontext sf_sc; struct l_fpstate sf_fpstate; l_uint sf_extramask[LINUX_NSIG_WORDS-1]; - l_handler_t sf_handler; }; struct l_rt_sigframe { @@ -421,7 +418,6 @@ struct l_rt_sigframe { struct l_ucontext *sf_ucontext; l_siginfo_t sf_si; struct l_ucontext sf_sc; - l_handler_t sf_handler; }; extern struct sysentvec linux_sysvec; diff --git a/sys/i386/linux/linux_genassym.c b/sys/i386/linux/linux_genassym.c index 9735110b0472..08aa0979d793 100644 --- a/sys/i386/linux/linux_genassym.c +++ b/sys/i386/linux/linux_genassym.c @@ -8,11 +8,9 @@ __FBSDID("$FreeBSD$"); #include #include -ASSYM(LINUX_SIGF_HANDLER, offsetof(struct l_sigframe, sf_handler)); ASSYM(LINUX_SIGF_SC, offsetof(struct l_sigframe, sf_sc)); ASSYM(LINUX_SC_GS, offsetof(struct l_sigcontext, sc_gs)); ASSYM(LINUX_SC_EFLAGS, offsetof(struct l_sigcontext, sc_eflags)); -ASSYM(LINUX_RT_SIGF_HANDLER, offsetof(struct l_rt_sigframe, sf_handler)); ASSYM(LINUX_RT_SIGF_UC, offsetof(struct l_rt_sigframe, sf_sc)); ASSYM(LINUX_RT_SIGF_SC, offsetof(struct l_ucontext, uc_mcontext)); ASSYM(LINUX_SC_ESP, offsetof(struct l_sigcontext, sc_esp)); diff --git a/sys/i386/linux/linux_locore.asm b/sys/i386/linux/linux_locore.asm index 4c5246bd5725..3459fb5a56de 100644 --- a/sys/i386/linux/linux_locore.asm +++ b/sys/i386/linux/linux_locore.asm @@ -15,38 +15,22 @@ linux_platform: .text -/* - * To avoid excess stack frame the signal trampoline code emulates - * the 'call' instruction. - */ ENTRY(__kernel_sigreturn) - movl %esp, %ebx /* preserve sigframe */ - call .getip0 -.getip0: - popl %eax - add $.startsigcode-.getip0, %eax /* ret address */ - push %eax - jmp *LINUX_SIGF_HANDLER(%ebx) + movl %esp, %ebx /* sigframe for sigreturn */ + call *%edi /* call signal handler */ .startsigcode: popl %eax /* gcc unwind code need this */ - movl $LINUX_SYS_linux_sigreturn,%eax /* linux_sigreturn() */ - int $0x80 /* enter kernel with args */ + movl $LINUX_SYS_linux_sigreturn, %eax + int $0x80 .endsigcode: 0: jmp 0b ENTRY(__kernel_rt_sigreturn) - leal LINUX_RT_SIGF_UC(%esp),%ebx /* linux ucp */ - leal LINUX_RT_SIGF_SC(%ebx),%ecx /* linux sigcontext */ - movl %esp, %edi - call .getip1 -.getip1: - popl %eax - add $.startrtsigcode-.getip1, %eax /* ret address */ - push %eax - jmp *LINUX_RT_SIGF_HANDLER(%edi) + leal LINUX_RT_SIGF_UC(%esp), %ebx /* linux ucontext for rt_sigreturn */ + call *%edi /* call signal handler */ .startrtsigcode: - movl $LINUX_SYS_linux_rt_sigreturn,%eax /* linux_rt_sigreturn() */ - int $0x80 /* enter kernel with args */ + movl $LINUX_SYS_linux_rt_sigreturn, %eax + int $0x80 .endrtsigcode: 0: jmp 0b diff --git a/sys/i386/linux/linux_sysvec.c b/sys/i386/linux/linux_sysvec.c index fa45057939ff..13591c569aae 100644 --- a/sys/i386/linux/linux_sysvec.c +++ b/sys/i386/linux/linux_sysvec.c @@ -422,7 +422,6 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) bzero(&frame, sizeof(frame)); - frame.sf_handler = catcher; frame.sf_sig = sig; frame.sf_siginfo = &fp->sf_si; frame.sf_ucontext = &fp->sf_sc; @@ -473,6 +472,7 @@ linux_rt_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Build context to run handler in. */ regs->tf_esp = (int)fp; regs->tf_eip = __kernel_rt_sigreturn; + regs->tf_edi = catcher; regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel; @@ -532,7 +532,6 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) bzero(&frame, sizeof(frame)); - frame.sf_handler = catcher; frame.sf_sig = sig; bsd_to_linux_sigset(mask, &lmask); @@ -574,6 +573,7 @@ linux_sendsig(sig_t catcher, ksiginfo_t *ksi, sigset_t *mask) /* Build context to run handler in. */ regs->tf_esp = (int)fp; regs->tf_eip = __kernel_sigreturn; + regs->tf_edi = catcher; regs->tf_eflags &= ~(PSL_T | PSL_VM | PSL_D); regs->tf_cs = _ucodesel; regs->tf_ds = _udatasel;