Received: by 2002:a25:1506:0:0:0:0:0 with SMTP id 6csp1557117ybv; Thu, 20 Feb 2020 23:09:43 -0800 (PST) X-Google-Smtp-Source: APXvYqzT8krqFiQXqqT1BVnlw0cHMPobHyCmFBLR5z64T2abrSF0wJ+g0AgrU58qnRDdCwEisWPl X-Received: by 2002:aca:1a10:: with SMTP id a16mr848169oia.9.1582268983199; Thu, 20 Feb 2020 23:09:43 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1582268983; cv=none; d=google.com; s=arc-20160816; b=tu+iM/bfQ9mjktznct7xUnD+eBOwyjrhMDY3CspY9C7K9XF99aOELPzkwUEuXFKPta 9Ce7Bzu2hecFitKXY0ZnHTLD1x8eodFv5TYXtE2jiCV+r8phaCTHit6EUGvh0ddHSUN3 UkAXz//rDTCr4ou74Ym5lHynyT+EgUVt7xxt7VM8Ju5z0pKLe4kLPLM8J7s8Ok5F0NDV zSjRL7Aqa8lwXy682Ylin6nG8WGZL+HEt+0UAdp2updRUjikMtF7IX3lGXsDsHldZwnL 7h31td0DtvQLR3013YuZKUBUxZ8ymTb5x5+Q+WVDljGk+6r/QTRXICsz+rZcSnZNOfAB eAyg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:in-reply-to:content-disposition :mime-version:references:message-id:subject:cc:to:from:date; bh=Qi52t4WhzHttRq2jqjF4AiZ6bEG1D90zCwn9OdT7rYw=; b=EB2vBcl0vTRn8SztoY2C7nDDbWp398vW6vqgjPh8QyUYa9dO3aKLhMGiCe7B6pgRgu 1mPAE0yXhkhAkx3XMLAaP31tA1jwm6CpRZoc3rH4p4tYglyobFiXcHQjJZu2Kv5zpjF2 joheVtE8ldLhT8hF90Ha9/IOvnVN65juRSS5vEEWlAnUw8lq+eBrrml2KsEIlhGTFjRm ZhZphJAsn4KkCElYqtSCWw/uxkboTtlvKx4JTlK8EHnTUuX7iICsrfH2pbfYX3V08r/T dfvxA6l7pAFo96Uj0GXd0xzSPuytvrx0IgiRo52POfm2AdpXjTRAoUHpJTMJsEr1HiaB mi5g== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i12si401692oik.171.2020.02.20.23.09.31; Thu, 20 Feb 2020 23:09:43 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727391AbgBUHH0 (ORCPT + 99 others); Fri, 21 Feb 2020 02:07:26 -0500 Received: from isilmar-4.linta.de ([136.243.71.142]:34414 "EHLO isilmar-4.linta.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727193AbgBUHH0 (ORCPT ); Fri, 21 Feb 2020 02:07:26 -0500 X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES X-isilmar-external: YES Received: from light.dominikbrodowski.net (brodo.linta [10.1.0.102]) by isilmar-4.linta.de (Postfix) with ESMTPSA id 8754A20074B; Fri, 21 Feb 2020 07:07:24 +0000 (UTC) Received: by light.dominikbrodowski.net (Postfix, from userid 1000) id 96C1520AA7; Fri, 21 Feb 2020 07:47:43 +0100 (CET) Date: Fri, 21 Feb 2020 07:47:43 +0100 From: Dominik Brodowski To: Brian Gerst Cc: linux-kernel@vger.kernel.org, x86@kernel.org, Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H . Peter Anvin" , Andy Lutomirski Subject: Re: [PATCH 1/5] x86: Refactor syscall_wrapper.h Message-ID: <20200221064743.GB3368@light.dominikbrodowski.net> References: <20200221050934.719152-1-brgerst@gmail.com> <20200221050934.719152-2-brgerst@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20200221050934.719152-2-brgerst@gmail.com> Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org > + * Instead of the generic __SYSCALL_DEFINEx() definition, this macro takes If you move the description to the top (the reason for that is understandable), you can't talk about "this macro" any more -- as "this macro" is "__SYSCALL_DEFINEx()" which is defined far further below. > + * struct pt_regs *regs as the only argument of the syscall stub named > + * __x64_sys_*(). It decodes just the registers it needs and passes them on to > + * the __se_sys_*() wrapper performing sign extension and then to the > + * __do_sys_*() function doing the actual job. These wrappers and functions > + * are inlined (at least in very most cases), meaning that the assembly looks > + * as follows (slightly re-ordered for better readability): > + * > + * <__x64_sys_recv>: <-- syscall with 4 parameters > + * callq <__fentry__> > + * > + * mov 0x70(%rdi),%rdi <-- decode regs->di > + * mov 0x68(%rdi),%rsi <-- decode regs->si > + * mov 0x60(%rdi),%rdx <-- decode regs->dx > + * mov 0x38(%rdi),%rcx <-- decode regs->r10 > + * > + * xor %r9d,%r9d <-- clear %r9 > + * xor %r8d,%r8d <-- clear %r8 > + * > + * callq __sys_recvfrom <-- do the actual work in __sys_recvfrom() > + * which takes 6 arguments > + * > + * cltq <-- extend return value to 64-bit > + * retq <-- return > + * > + * This approach avoids leaking random user-provided register content down > + * the call chain. ... maybe add the rationale for x86-32 here (in patch 3/5)? > + * If IA32_EMULATION is enabled, this macro generates an additional wrapper > + * named __ia32_sys_*() which decodes the struct pt_regs *regs according > + * to the i386 calling convention (bx, cx, dx, si, di, bp). ... and this likely needs an update in patch 3/5 as well > -#define __IA32_COMPAT_SYS_STUBx(x, name, ...) \ > - asmlinkage long __ia32_compat_sys##name(const struct pt_regs *regs);\ > - ALLOW_ERROR_INJECTION(__ia32_compat_sys##name, ERRNO); \ > - asmlinkage long __ia32_compat_sys##name(const struct pt_regs *regs)\ > +#define __SYS_STUB0(abi, name) \ > + asmlinkage long __##abi##_##name(const struct pt_regs *regs); \ > + ALLOW_ERROR_INJECTION(__##abi##_##name, ERRNO); \ > + asmlinkage long __##abi##_##name(const struct pt_regs *regs) \ > { \ > - return __se_compat_sys##name(SC_IA32_REGS_TO_ARGS(x,__VA_ARGS__));\ > + return __do_##name(); \ > } Instead of __se_compat_sys##name, now __do_comapt_sys##name is called. This should be equivalent for zero-argument syscalls, but maybe make that change explicit. In general terms, I am not sure that the new code is more readable (but I may be biased) as the conversion to the proper calling convention for the ABI has to be done by the callee and is not done in the caller. Also, there are now three levels of macros instead of two. > +#ifdef CONFIG_X86_64 > +#define __X64_SYS_STUBx(x, name, ...) \ > + __SYS_STUBx(x64, name, SC_X86_64_REGS_TO_ARGS(x, __VA_ARGS__)) s/name/sys_name/g please -- this isn't the name of the syscall any more, but appended by sys (applies to a number of macros) > - * named __ia32_sys_*() > + * As the generic SYSCALL_DEFINE0() macro does not decode any parameters for > + * obvious reasons, and passing struct pt_regs *regs to it in %rdi does not > + * hurt, we only need to re-define it here to keep the naming congruent to > + * SYSCALL_DEFINEx() -- which is essential for the COND_SYSCALL() and SYS_NI() > + * macros to work correctly. > */ > +#define SYSCALL_DEFINE0(name) \ > + SYSCALL_METADATA(_##name, 0); \ > + static inline long __do_sys_##name(void); \ > + __X64_SYS_STUB0(sys_##name) \ > + __IA32_SYS_STUB0(sys_##name) \ > + static inline long __do_sys_##name(void) > > -#define SYSCALL_DEFINE0(sname) \ > - SYSCALL_METADATA(_##sname, 0); \ > - asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused);\ > - ALLOW_ERROR_INJECTION(__x64_sys_##sname, ERRNO); \ > - SYSCALL_ALIAS(__ia32_sys_##sname, __x64_sys_##sname); \ > - asmlinkage long __x64_sys_##sname(const struct pt_regs *__unused) OK, this is a bit more complex change -- you don't use SYSCALL_ALIAS any more, but define two asmlinakge functions which then call __do_sys_##name(). Maybe needs an explanation in the changelog... > +#define __IA32_COMPAT_SYS_STUBx(x, name, ...) \ > + __SYS_STUBx(ia32, name, SC_IA32_REGS_TO_ARGS(x, __VA_ARGS__)) s/name/compat_sys_name/g/ -- please make it a bit more explicit what "name" we are talking about here, > +#define __IA32_COMPAT_SYS_STUB0(name) \ > + __SYS_STUB0(ia32, name) and here, > +#define __IA32_COMPAT_COND_SYSCALL(name) \ > + __COND_SYSCALL(ia32, name) and here, > +#define __IA32_COMPAT_SYS_NI(name) \ > + SYSCALL_ALIAS(__ia32_compat_sys_##name, sys_ni_posix_timers) ... but not here, as here "name" is actually "name". Thanks, Dominik