Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965098AbdGTU45 (ORCPT ); Thu, 20 Jul 2017 16:56:57 -0400 Received: from mx1.redhat.com ([209.132.183.28]:58484 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S935802AbdGTU44 (ORCPT ); Thu, 20 Jul 2017 16:56:56 -0400 DMARC-Filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 48F9EC056827 Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com Authentication-Results: ext-mx08.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=jpoimboe@redhat.com DKIM-Filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 48F9EC056827 Date: Thu, 20 Jul 2017 15:56:52 -0500 From: Josh Poimboeuf To: Andrey Ryabinin Cc: Matthias Kaehlcke , Chris J Arges , Borislav Petkov , Thomas Gleixner , Ingo Molnar , "H . Peter Anvin" , "x86@kernel.org" , LKML , Douglas Anderson , Michael Davidson , Greg Hackmann , Nick Desaulniers , Stephen Hines , Kees Cook , Arnd Bergmann , Bernhard =?utf-8?Q?Rosenkr=C3=A4nzer?= Subject: Re: [PATCH] Revert "x86/uaccess: Add stack frame output operand in get_user() inline asm" Message-ID: <20170720205652.patvjnfqymrv73ho@treble> References: <20170713184748.GF95735@google.com> <75850bb7-a60e-057d-d88b-afa0c79e94a0@gmail.com> <20170713203416.isvijqbwbcgupgj7@treble> <20170713211245.GG95735@google.com> <20170713213406.gx4ixkx6kxa4ppps@treble> <20170713215704.GJ95735@google.com> <20170719174630.kz5g553evcrnirmr@treble> <20170720151813.5wnpsb5wy7bqrpec@treble> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.6.0.1 (2016-04-01) X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Thu, 20 Jul 2017 20:56:55 +0000 (UTC) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 2378 Lines: 57 On Thu, Jul 20, 2017 at 06:30:24PM +0300, Andrey Ryabinin wrote: > FWIW bellow is my understanding of what's going on. > > It seems clang treats local named register almost the same as ordinary > local variables. > The only difference is that before reading the register variable clang > puts variable's value into the specified register. > > So clang just assigns stack slot for the variable __sp where it's > going to keep variable's value. > But since __sp is unitialized (we haven't assign anything to it), the > value of the __sp is some garbage from stack. > inline asm specifies __sp as input, so clang assumes that it have to > load __sp into 'rsp' because inline asm is going to use > it. And it just loads garbage from stack into 'rsp' > > In fact, such behavior (I mean storing the value on stack and loading > into reg before the use) is very useful. > Clang's behavior allows to keep the value assigned to the > call-clobbered register across the function calls. > > Unlike clang, gcc assigns value to the register right away and doesn't > store the value anywhere else. So if the reg is > call clobbered register you have to be absolutely sure that there is > no subsequent function call that might clobber the register. > > E.g. see some real examples > https://patchwork.kernel.org/patch/4111971/ or 98d4ded60bda("msm: scm: > Fix improper register assignment"). > These bugs shouldn't happen with clang. > > But the global named register works slightly differently in clang. For > the global, the value is just the value of the register itself, > whatever it is. Read/write from global named register is just like > direct read/write to the register Thanks, that clears up a lot of the confusion for me. Still, unfortunately, I don't think that's going to work for GCC. Changing the '__sp' register variable to global in the header file causes it to make a *bunch* of changes across the kernel, even in functions which don't do inline asm. It seems to be disabling some optimizations across the board. I do have another idea, which is to replace all uses of asm(" ... call foo ... " : outputs : inputs : clobbers); with a new ASM_CALL macro: ASM_CALL(" ... call foo ... ", outputs, inputs, clobbers); Then the compiler differences can be abstracted out, with GCC adding "sp" as an output constraint and clang doing nothing (for now). -- Josh