From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-14.4 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,INCLUDES_CR_TRAILER,INCLUDES_PATCH,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3FFB2C433B4 for ; Tue, 18 May 2021 10:55:54 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C172961209 for ; Tue, 18 May 2021 10:55:53 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C172961209 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=kernel.org Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Transfer-Encoding :Content-Type:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Subject:Cc:To: From:Message-ID:Date:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=cB6KI/buWIae69Uvn1Sw0WnVGjH1R6nxNjy3Ely//l8=; b=LNWLKK+u1uzlMlsB2o2BNG3bQ N5J/lrRzQF7dIU4os9J3ffTRbRweULr4Zuz6ZRZdUUR0Q1IHekLBj8eI+EMvgrwcD5rbGnb2BQZkv rxGTuA6kB7dYYjwZqmia/KkjgsV6mF5pfH7YTDoqzLoleUSHqE7EndKvIpeVtcFE1j3H2o3oa0VZ1 v5sqkSGuOaZ2RBWiRq5KgH9KiVfC4gfO+WkLbAOHa/wJeeAoToJZvB3RvmRtzttyVy273JwtVQHMA j6kNfs2dvNRPEZjH7nwVT2mlCqkq9rP31T6o8oRpNNCmgN61TEDPtQ523JUIJIGt8j5gogc8NBvS9 QoeyvJ0jw==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1lixMX-000SOK-15; Tue, 18 May 2021 10:54:09 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lixML-000SMK-4c for linux-arm-kernel@desiato.infradead.org; Tue, 18 May 2021 10:53:57 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Type:MIME-Version:References: In-Reply-To:Subject:Cc:To:From:Message-ID:Date:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=Ob3dxxFuk0Z2+TW0GpLavRARkx1mtrg/ids9u3XNV/0=; b=z+Krt1n/W170FaHalVlyKW87AQ 94kzdDf7ezD1Ymr6v6bpiqTEOv9hRxwq2EuFVB6h8L86hC843teIR7q22j06BhY1a5ZUrLS6UOTbx VaXUFUqPv90okSs4WjPa6U0NOqDCDkwrqfpcg31+4snQw3YBAIkm/1LPQDy9MDw+HBQ7BsF4G6Ds4 uC27jX7lXiLEymepmZUPsjvYyEj34BMZ0S1TAr/rjMWm88vNc6b/CmjBpGuFeuodvWlqx8Lhy/udw n0YRXHRlJX+dcXW+rLcvb2KKvaWdinsPvefTnJhGEqCBcoiUEpoGJw4wxkEfIUIJXv2YVFz4aaOqg L2GsUrkg==; Received: from mail.kernel.org ([198.145.29.99]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1lixMI-00Ea9i-A8 for linux-arm-kernel@lists.infradead.org; Tue, 18 May 2021 10:53:55 +0000 Received: from disco-boy.misterjones.org (disco-boy.misterjones.org [51.254.78.96]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id E4AEC6124C; Tue, 18 May 2021 10:53:53 +0000 (UTC) Received: from 78.163-31-62.static.virginmediabusiness.co.uk ([62.31.163.78] helo=wait-a-minute.misterjones.org) by disco-boy.misterjones.org with esmtpsa (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1lixMF-0023Lt-W4; Tue, 18 May 2021 11:53:52 +0100 Date: Tue, 18 May 2021 11:53:50 +0100 Message-ID: <87pmxotirl.wl-maz@kernel.org> From: Marc Zyngier To: Mark Brown Cc: Catalin Marinas , Will Deacon , Mark Rutland , Lorenzo Pieralisi , Sudeep Holla , linux-arm-kernel@lists.infradead.org Subject: Re: [PATCH v1 2/2] arm64: smccc: Support SMCCC v1.3 SVE register saving hint In-Reply-To: <20210518100919.6674-3-broonie@kernel.org> References: <20210518100919.6674-1-broonie@kernel.org> <20210518100919.6674-3-broonie@kernel.org> User-Agent: Wanderlust/2.15.9 (Almost Unreal) SEMI-EPG/1.14.7 (Harue) FLIM-LB/1.14.9 (=?UTF-8?B?R29qxY0=?=) APEL-LB/10.8 EasyPG/1.0.0 Emacs/27.1 (x86_64-pc-linux-gnu) MULE/6.0 (HANACHIRUSATO) MIME-Version: 1.0 (generated by SEMI-EPG 1.14.7 - "Harue") X-SA-Exim-Connect-IP: 62.31.163.78 X-SA-Exim-Rcpt-To: broonie@kernel.org, catalin.marinas@arm.com, will@kernel.org, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, linux-arm-kernel@lists.infradead.org X-SA-Exim-Mail-From: maz@kernel.org X-SA-Exim-Scanned: No (on disco-boy.misterjones.org); SAEximRunCond expanded to false X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210518_035354_413168_BBDBEDB7 X-CRM114-Status: GOOD ( 38.62 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Hi Mark, On Tue, 18 May 2021 11:09:19 +0100, Mark Brown wrote: > > SMCCC v1.2 requires that all SVE state be preserved over SMC calls which > introduces substantial overhead in the common case where there is no SVE > state in the registers. To avoid this SMCCC v1.3 introduces a flag which > allows the caller to say that there is no state that needs to be preserved > in the registers. Make use of this flag, setting it if the SMCCC version > indicates support for it and the TIF_ flags indicate that there is no live > SVE state in the registers, this avoids placing any constraints on when > SMCCC calls can be done or triggering extra saving and reloading of SVE > register state in the kernel. > > This would be straightforward enough except for the rather entertaining > inline assembly we use to do SMCCC v1.1 calls to allow us to take advantage > of the limited number of registers it clobbers. Deal with this by having a > slightly non-standard function which we call immediately before issuing the > SMCCC call to make our checks. This causes an extra function call on any > system built with SVE support, and extra checks when SVE is detected at > runtime, but these costs are expected to be reasonable in the context of > doing a SMCCC call in the first place. > > Signed-off-by: Mark Brown > --- > arch/arm64/kernel/smccc-call.S | 39 ++++++++++++++++++++++++++++++++++ > drivers/firmware/smccc/smccc.c | 4 ++++ > include/linux/arm-smccc.h | 22 +++++++++++++++++-- > 3 files changed, 63 insertions(+), 2 deletions(-) > > diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S > index d62447964ed9..217bfb03a6c9 100644 > --- a/arch/arm64/kernel/smccc-call.S > +++ b/arch/arm64/kernel/smccc-call.S > @@ -7,8 +7,47 @@ > > #include > #include > +#include > + > +/* > + * If we have SMCCC v1.3 and (as is likely) no SVE state in > + * the registers then set the SMCCC hint bit to say there's no > + * need to preserve it. Do this by directly adjusting the SMCCC > + * function value which is already stored in x0 ready to be called. > + * > + * Since we need scratch registers but wish to avoid having to handle > + * the stack we expect the caller to preserve x15 and x16 if needed, > + * the only callers are expected to be the call below and the inline > + * asm in linux/arm-smccc.h for SMCCC 1.1 and later calls. > + */ > +SYM_CODE_START(__smccc_sve_check) > + BTI_C > + > +alternative_if ARM64_SVE > + > + adrp x15, smccc_has_sve_hint The adrp instruction will give you a 4kB aligned address, which results in 1 chance out of 512 to point to the right location. The adr_l macro is probably what you want. > + ldr x15, [x15] > + cbz x15, 1f > + > + get_current_task x15 > + ldr x15, [x15, #TSK_TI_FLAGS] > + and x16, x15, #TIF_FOREIGN_FPSTATE // Any live FP state? > + cbnz x16, 1f > + mov x16, #TIF_SVE // Does that state include SVE? > + and x16, x15, x16 > + cbnz x16, 2f > + > +1: orr x0, x0, ARM_SMCCC_1_3_SVE_HINT > +alternative_else_nop_endif > + > +2: ret > +SYM_CODE_END(__smccc_sve_check) > +EXPORT_SYMBOL(__smccc_sve_check) > > .macro SMCCC instr > +alternative_if ARM64_SVE > + bl __smccc_sve_check > +alternative_else_nop_endif > \instr #0 > ldr x4, [sp] > stp x0, x1, [x4, #ARM_SMCCC_RES_X0_OFFS] > diff --git a/drivers/firmware/smccc/smccc.c b/drivers/firmware/smccc/smccc.c > index 028f81d702cc..9f937b125ab0 100644 > --- a/drivers/firmware/smccc/smccc.c > +++ b/drivers/firmware/smccc/smccc.c > @@ -15,6 +15,7 @@ static u32 smccc_version = ARM_SMCCC_VERSION_1_0; > static enum arm_smccc_conduit smccc_conduit = SMCCC_CONDUIT_NONE; > > bool __ro_after_init smccc_trng_available = false; > +u64 __ro_after_init smccc_has_sve_hint = false; > > void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit) > { > @@ -22,6 +23,9 @@ void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit) > smccc_conduit = conduit; > > smccc_trng_available = smccc_probe_trng(); > + if (IS_ENABLED(CONFIG_ARM64_SVE) && > + smccc_version >= ARM_SMCCC_VERSION_1_3) > + smccc_has_sve_hint = true; > } > > enum arm_smccc_conduit arm_smccc_1_1_get_conduit(void) > diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h > index 6861489a1890..611f3bc9c131 100644 > --- a/include/linux/arm-smccc.h > +++ b/include/linux/arm-smccc.h > @@ -63,6 +63,9 @@ > #define ARM_SMCCC_VERSION_1_0 0x10000 > #define ARM_SMCCC_VERSION_1_1 0x10001 > #define ARM_SMCCC_VERSION_1_2 0x10002 > +#define ARM_SMCCC_VERSION_1_3 0x10003 > + > +#define ARM_SMCCC_1_3_SVE_HINT 0x10000 > > #define ARM_SMCCC_VERSION_FUNC_ID \ > ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ > @@ -216,6 +219,8 @@ u32 arm_smccc_get_version(void); > > void __init arm_smccc_version_init(u32 version, enum arm_smccc_conduit conduit); > > +extern u64 smccc_has_sve_hint; > + > /** > * struct arm_smccc_res - Result from SMC/HVC call > * @a0-a3 result values from registers 0 to 3 > @@ -297,6 +302,18 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, > > #endif > > +#ifdef CONFIG_ARM64_SVE > + > +#define SMCCC_SVE_CHECK "bl __smccc_sve_check \n" > +#define smccc_sve_clobbers "x15", "x16", "lr", > + > +#else > + > +#define SMCCC_SVE_CHECK > +#define smccc_sve_clobbers > + > +#endif > + > #define ___count_args(_0, _1, _2, _3, _4, _5, _6, _7, _8, x, ...) x > > #define __count_args(...) \ > @@ -364,7 +381,7 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, > > #define ___constraints(count) \ > : __constraint_read_ ## count \ > - : "memory" > + : smccc_sve_clobbers "memory" > #define __constraints(count) ___constraints(count) > > /* > @@ -379,7 +396,8 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, > register unsigned long r2 asm("r2"); \ > register unsigned long r3 asm("r3"); \ > __declare_args(__count_args(__VA_ARGS__), __VA_ARGS__); \ > - asm volatile(inst "\n" : \ > + asm volatile(SMCCC_SVE_CHECK \ What happens when this is called from a context where __smccc_sve_check isn't mapped, nor does "current" mean anything? See arch/arm64/kvm/hyp/nvhe/psci-relay.c for an example. > + inst "\n" : \ > "=r" (r0), "=r" (r1), "=r" (r2), "=r" (r3) \ > __constraints(__count_args(__VA_ARGS__))); \ > if (___res) \ Thanks, M. -- Without deviation from the norm, progress is not possible. _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel