Received: by 10.223.176.5 with SMTP id f5csp4247878wra; Tue, 30 Jan 2018 04:30:50 -0800 (PST) X-Google-Smtp-Source: AH8x226sTkiKe2ADFnSkDCy9x7KRh8P+ov9+8yXOhOBHuvqLhLUff/U3jXSqvnaTeYxDYGyX9n/3 X-Received: by 2002:a17:902:6909:: with SMTP id j9-v6mr24869961plk.372.1517315450093; Tue, 30 Jan 2018 04:30:50 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1517315450; cv=none; d=google.com; s=arc-20160816; b=ZMWWB2uiZz79KkmWoYsJZEsYoyPb1lZswqFOJKFWbaB6PoOj72xuv8FVyun7qfOSy5 oeDRldrrnq885amFNhrlSn49ZMScwmJRLngN3korC7QTi07ktSYCcQoC9uFJodVMxHG/ RAQbAKE1hXaltolBxglZ1Eao83pMpe5UlTDvcIJsbkI2b3gx05mFDy+uCgveCNRG5t5A KZZ3udh0JndVzPggxmTiRODrMzKGQ0CfEACgmCtq3pl8mf6cG7LyiHPMrbZ1tvLGlxdd 3MevcrgaVy1vz8p9p0/XvuKG+wJ30wNswJFn2x0lwyud+E8B6F1dkfZpsHR/DUj6xUoX vAlQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :references:in-reply-to:mime-version:dkim-signature :arc-authentication-results; bh=Wr99hqvnN+QRFSeLSwxgpwip8fXOspOgeJ9WIyGKMZc=; b=x+rxJi9ovR/ule9u2iXXr7jJ4fqBPMvUfiZeuSrZ6oGrDhPk//Xx5jgW63SJzKtMaO OE+ldLQse1CcuPJudKihdwWSu3lvoXpyXskiutWpdtDIPV4lVS9A0FqCYNPwXr6qWB50 9V5cf2igUIwe6LQZ7dC9cYrVx0HCx+bhmwmNv5GuFSC98jpeo1tVvap3+IpygIFql1YF oEzUWSv7B33YkW0sjkayQvIL2BwxbHesol5GXcpJndgpXzFvTWcPBLoKGzzLfOy+XvOK M1xhPVJehf2SIKZjslDDjPXiaC/i94oY/+U80nZnnF3rCvOXdqmv19VWOXOAmVGSd0fF b64g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=CFQEqohw; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id o3-v6si2140983pld.605.2018.01.30.04.30.34; Tue, 30 Jan 2018 04:30:50 -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; dkim=pass header.i=@linaro.org header.s=google header.b=CFQEqohw; 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; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751962AbeA3M3d (ORCPT + 99 others); Tue, 30 Jan 2018 07:29:33 -0500 Received: from mail-io0-f196.google.com ([209.85.223.196]:35852 "EHLO mail-io0-f196.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751638AbeA3M3b (ORCPT ); Tue, 30 Jan 2018 07:29:31 -0500 Received: by mail-io0-f196.google.com with SMTP id l17so11285330ioc.3 for ; Tue, 30 Jan 2018 04:29:31 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=Wr99hqvnN+QRFSeLSwxgpwip8fXOspOgeJ9WIyGKMZc=; b=CFQEqohwZqoPT3jlUzQtmK2rqpeRyY5/d7LVbo3nZRfPjUXyjzTqqq/3bOWtqyk5+A jLxPIM0CKD9sUBb6CcIamOrCAMr2Lfjfb1ltr9QHL+rJD0iWz+FI4LyPhpqt/mFUJ858 a/w9jt5OAGR7IFfBWMR0+0LcTWx1/uaA/c1MY= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=Wr99hqvnN+QRFSeLSwxgpwip8fXOspOgeJ9WIyGKMZc=; b=A57xOioG7R3UelF0Q4pcshsjsxqPzCDwzgbuMlNUaH2iRWatCeUAFqcsEtb8B28xrz YrAmqe1LGrG6dGT40jfYXllAyHd85ZhWYBZF418BYQocdF4et6z/yVEn2nFd9oKg/218 +Css5J815s1N0UIQywd+/MWuvJPZcdixlWUQ8jdk1f7+wY7EW0GSdL1LygiyRjRlKbBM 1XKeXUP5g5i7rwscj6eWrIItwMws2BiYeUhOiRuTHBjPIfbvb+jcgxUoWqZmBEPRbI5q +XOmYOiMJjHQCGHFHHKKnxWuOav8VK9DxwFU29od4XQ8gXzoJvyDPhnb7TpJMRaGPBJA YzHw== X-Gm-Message-State: AKwxytcwZAua/3AMevIUwNcbeJ0JB1/i++o171Nwjy4z5QaAoi0qVWPC agIylybehG+A26ftK98KdGvMwvM9/AS8WgMNhjVvBg== X-Received: by 10.107.25.195 with SMTP id 186mr16057352ioz.200.1517315370739; Tue, 30 Jan 2018 04:29:30 -0800 (PST) MIME-Version: 1.0 Received: by 10.107.112.13 with HTTP; Tue, 30 Jan 2018 04:29:30 -0800 (PST) In-Reply-To: <03484caa-2e18-7126-7d99-8d0b1e0a83c6@arm.com> References: <20180129174559.1866-1-marc.zyngier@arm.com> <20180129174559.1866-16-marc.zyngier@arm.com> <03484caa-2e18-7126-7d99-8d0b1e0a83c6@arm.com> From: Ard Biesheuvel Date: Tue, 30 Jan 2018 12:29:30 +0000 Message-ID: Subject: Re: [PATCH v2 15/16] arm/arm64: smccc: Implement SMCCC v1.1 inline primitive To: Marc Zyngier Cc: Linux Kernel Mailing List , linux-arm-kernel , kvmarm , Catalin Marinas , Will Deacon , Peter Maydell , Christoffer Dall , Lorenzo Pieralisi , Mark Rutland , Robin Murphy , Jon Masters Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 30 January 2018 at 12:27, Marc Zyngier wrote: > On 29/01/18 21:45, Ard Biesheuvel wrote: >> On 29 January 2018 at 17:45, Marc Zyngier wrote: >>> One of the major improvement of SMCCC v1.1 is that it only clobbers >>> the first 4 registers, both on 32 and 64bit. This means that it >>> becomes very easy to provide an inline version of the SMC call >>> primitive, and avoid performing a function call to stash the >>> registers that would otherwise be clobbered by SMCCC v1.0. >>> >>> Signed-off-by: Marc Zyngier >>> --- >>> include/linux/arm-smccc.h | 157 ++++++++++++++++++++++++++++++++++++++++++++++ >>> 1 file changed, 157 insertions(+) >>> >>> diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h >>> index dd44d8458c04..bc5843728909 100644 >>> --- a/include/linux/arm-smccc.h >>> +++ b/include/linux/arm-smccc.h >>> @@ -150,5 +150,162 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, >>> >>> #define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__) >>> >>> +/* SMCCC v1.1 implementation madness follows */ >>> +#ifdef CONFIG_ARM64 >>> + >>> +#define SMCCC_SMC_INST "smc #0" >>> +#define SMCCC_HVC_INST "hvc #0" >>> + >>> +#define __arm_smccc_1_1_prologue(inst) \ >>> + inst "\n" \ >>> + "cbz %[ptr], 1f\n" \ >>> + "stp %x[r0], %x[r1], %[ra0]\n" \ >>> + "stp %x[r2], %x[r3], %[ra2]\n" \ >>> + "1:\n" \ >>> + : [ra0] "=Ump" (*(&___res->a0)), \ >>> + [ra2] "=Ump" (*(&___res->a2)), >>> + >>> +#define __arm_smccc_1_1_epilogue : "memory" >>> + >>> +#endif >>> + >>> +#ifdef CONFIG_ARM >>> +#include >>> +#include >>> + >>> +#define SMCCC_SMC_INST __SMC(0) >>> +#define SMCCC_HVC_INST __HVC(0) >>> + >>> +#define __arm_smccc_1_1_prologue(inst) \ >>> + inst "\n" \ >>> + "cmp %[ptr], #0\n" \ >>> + "stmne %[ptr], {%[r0], %[r1], %[r2], %[r3]}\n" \ >>> + : "=m" (*___res), >>> + >>> +#define __arm_smccc_1_1_epilogue : "memory", "cc" >>> + >>> +#endif >>> + >>> +#define __constraint_write_0 \ >>> + [r0] "+r" (r0), [r1] "=r" (r1), [r2] "=r" (r2), [r3] "=r" (r3) >>> +#define __constraint_write_1 \ >>> + [r0] "+r" (r0), [r1] "+r" (r1), [r2] "=r" (r2), [r3] "=r" (r3) >>> +#define __constraint_write_2 \ >>> + [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2), [r3] "=r" (r3) >>> +#define __constraint_write_3 \ >>> + [r0] "+r" (r0), [r1] "+r" (r1), [r2] "+r" (r2), [r3] "+r" (r3) >> >> It seems you need +r for all arguments, otherwise the compiler will >> notice that the value is never used, and may assign the register to >> 'res' instead, i.e., >> >> 3e4: 320107e0 mov w0, #0x80000001 // #-2147483647 >> 3e8: 320183e1 mov w1, #0x80008000 // #-2147450880 >> 3ec: 910123a2 add x2, x29, #0x48 >> 3f0: d4000002 hvc #0x0 >> 3f4: b4000062 cbz x2, 400 >> 3f8: a90487a0 stp x0, x1, [x29, #72] >> 3fc: a9058fa2 stp x2, x3, [x29, #88] >> >> (for the code generated in the next patch) > > Well spotted. > > I think this is because of the lack of early-clobber for the unassigned > registers. The compiler assumes the whole sequence is a single > instruction, with the output registers being affected at the end. If we > mark those with '=&r', we will prevent GCC from emitting this kind of > horror. > Tried that, actually, but it still doesn't help. It simply notices that r2 (in this case) is not referenced after the asm () [nor before] and so it simply seems to forget all about it, and reassigns it to something else. > Note that with Robin's trick of moving the assignment back to C code, > this is a bit moot as this is really a single instruction (smc/hvc), and > there is no intermediate register evaluation. > Yeah, that does look much better.