From patchwork Tue Apr 4 19:32:31 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Levin, Alexander \(Sasha Levin\)" X-Patchwork-Id: 96762 Delivered-To: patch@linaro.org Received: by 10.140.89.233 with SMTP id v96csp345490qgd; Tue, 4 Apr 2017 12:34:07 -0700 (PDT) X-Received: by 10.99.209.85 with SMTP id c21mr25705037pgj.147.1491334446934; Tue, 04 Apr 2017 12:34:06 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id p89si18339852pfa.239.2017.04.04.12.34.06; Tue, 04 Apr 2017 12:34:06 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of stable-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=@verizon.com; dkim=pass header.i=@verizon.com; dkim=pass header.i=@verizon.com; spf=pass (google.com: best guess record for domain of stable-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=stable-owner@vger.kernel.org; dmarc=pass (p=QUARANTINE sp=NONE dis=NONE) header.from=verizon.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932237AbdDDTeG (ORCPT + 6 others); Tue, 4 Apr 2017 15:34:06 -0400 Received: from omzsmtpe02.verizonbusiness.com ([199.249.25.209]:5250 "EHLO omzsmtpe02.verizonbusiness.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932227AbdDDTeF (ORCPT ); Tue, 4 Apr 2017 15:34:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=verizon.com; i=@verizon.com; q=dns/txt; s=corp; t=1491334444; x=1522870444; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=iElmIqTIgwpMF9Gwe8LCgUO7r3tzSc7bFONLtwlQJlw=; b=jqdRfjLX1A9by+FbokmEN9MByr9c+NxttO3v4PpMWbulC2IyLJy/idqO ITfN3IgoO5ClKvQawI9jhTcHC4/bHhupzM58WtMVUHxaSMFO7szlb79VC aRIyLcgm1m6jt2CJwo+MQp6l/rre5caKvUJ1G5+ujLTPTOKYun31kN8CX M=; X-IronPort-Anti-Spam-Filtered: false Received: from unknown (HELO fldsmtpi03.verizon.com) ([166.68.71.145]) by omzsmtpe02.verizonbusiness.com with ESMTP; 04 Apr 2017 19:34:04 +0000 X-IronPort-AV: E=Sophos;i="5.36,275,1486425600"; d="scan'208";a="325501745" Received: from rogue-10-255-192-101.rogue.vzwcorp.com (HELO atlantis.verizonwireless.com) ([10.255.192.101]) by fldsmtpi03.verizon.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 04 Apr 2017 19:34:04 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=verizon.com; i=@verizon.com; q=dns/txt; s=corp; t=1491334444; x=1522870444; h=from:to:cc:subject:date:message-id:references: in-reply-to:content-transfer-encoding:mime-version; bh=iElmIqTIgwpMF9Gwe8LCgUO7r3tzSc7bFONLtwlQJlw=; b=jqdRfjLX1A9by+FbokmEN9MByr9c+NxttO3v4PpMWbulC2IyLJy/idqO ITfN3IgoO5ClKvQawI9jhTcHC4/bHhupzM58WtMVUHxaSMFO7szlb79VC aRIyLcgm1m6jt2CJwo+MQp6l/rre5caKvUJ1G5+ujLTPTOKYun31kN8CX M=; Received: from viking.odc.vzwcorp.com (HELO mercury.verizonwireless.com) ([10.255.240.26]) by atlantis.verizonwireless.com with ESMTP/TLS/DHE-RSA-AES256-SHA; 04 Apr 2017 15:34:03 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=verizon.com; i=@verizon.com; q=dns/txt; s=corp; t=1491334443; x=1522870443; h=to:cc:subject:date:message-id:references:in-reply-to: content-transfer-encoding:mime-version:from; bh=iElmIqTIgwpMF9Gwe8LCgUO7r3tzSc7bFONLtwlQJlw=; b=W316syLIJjfe58GCqmDQTOGJf4fTSah0Lv7aRU44qkDhrpNWw+PthJ2t slryxrUdkq5zWH7tgmIzdWcoowcMTYPYuBxpO198wFIBoB8EBJjTUqQkE X/DoTZR+OETmfCPKmgcqPrA35yjrqqmJyrsphuguk/eTfGhQ07QplBQuW c=; From: alexander.levin@verizon.com X-Host: viking.odc.vzwcorp.com Received: from nyora1hub002.uswin.ad.vzwcorp.com ([10.170.34.217]) by mercury.verizonwireless.com with ESMTP/TLS/AES256-SHA; 04 Apr 2017 19:33:56 +0000 Received: from OMZP1LUMXCA19.uswin.ad.vzwcorp.com (144.8.22.197) by NYORA1HUB002.uswin.ad.vzwcorp.com (10.170.34.217) with Microsoft SMTP Server (TLS) id 8.3.406.0; Tue, 4 Apr 2017 15:33:54 -0400 Received: from OMZP1LUMXCA17.uswin.ad.vzwcorp.com (144.8.22.195) by OMZP1LUMXCA19.uswin.ad.vzwcorp.com (144.8.22.197) with Microsoft SMTP Server (TLS) id 15.0.1210.3; Tue, 4 Apr 2017 14:33:53 -0500 Received: from OMZP1LUMXCA17.uswin.ad.vzwcorp.com ([144.8.22.195]) by OMZP1LUMXCA17.uswin.ad.vzwcorp.com ([144.8.22.195]) with mapi id 15.00.1210.000; Tue, 4 Apr 2017 14:33:53 -0500 To: "gregkh@linuxfoundation.org" CC: "stable@vger.kernel.org" Subject: [PATCH for 4.9 78/98] arm: kernel: Add SMC structure parameter Thread-Topic: [PATCH for 4.9 78/98] arm: kernel: Add SMC structure parameter Thread-Index: AQHSrXoz8unuIEnz6Um1Nfkk+ujGZQ== Date: Tue, 4 Apr 2017 19:32:31 +0000 Message-ID: <20170404193158.19041-79-alexander.levin@verizon.com> References: <20170404193158.19041-1-alexander.levin@verizon.com> In-Reply-To: <20170404193158.19041-1-alexander.levin@verizon.com> Accept-Language: en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-ms-exchange-messagesentrepresentingtype: 1 x-ms-exchange-transport-fromentityheader: Hosted x-originating-ip: [10.144.60.250] MIME-Version: 1.0 Sender: stable-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org From: Andy Gross [ Upstream commit 680a0873e193bae666439f4b5e32c758e68f114c ] This patch adds a quirk parameter to the arm_smccc_(smc/hvc) calls. The quirk structure allows for specialized SMC operations due to SoC specific requirements. The current arm_smccc_(smc/hvc) is renamed and macros are used instead to specify the standard arm_smccc_(smc/hvc) or the arm_smccc_(smc/hvc)_quirk function. This patch and partial implementation was suggested by Will Deacon. Signed-off-by: Andy Gross Reviewed-by: Will Deacon Signed-off-by: Will Deacon Signed-off-by: Sasha Levin --- arch/arm/kernel/armksyms.c | 4 ++-- arch/arm/kernel/smccc-call.S | 14 ++++++++------ arch/arm64/kernel/arm64ksyms.c | 4 ++-- arch/arm64/kernel/asm-offsets.c | 7 +++++-- arch/arm64/kernel/smccc-call.S | 14 ++++++++------ include/linux/arm-smccc.h | 40 ++++++++++++++++++++++++++++++++-------- 6 files changed, 57 insertions(+), 26 deletions(-) -- 2.9.3 diff --git a/arch/arm/kernel/armksyms.c b/arch/arm/kernel/armksyms.c index 7e45f69..8e8d20c 100644 --- a/arch/arm/kernel/armksyms.c +++ b/arch/arm/kernel/armksyms.c @@ -178,6 +178,6 @@ EXPORT_SYMBOL(__pv_offset); #endif #ifdef CONFIG_HAVE_ARM_SMCCC -EXPORT_SYMBOL(arm_smccc_smc); -EXPORT_SYMBOL(arm_smccc_hvc); +EXPORT_SYMBOL(__arm_smccc_smc); +EXPORT_SYMBOL(__arm_smccc_hvc); #endif diff --git a/arch/arm/kernel/smccc-call.S b/arch/arm/kernel/smccc-call.S index 2e48b67..e5d4306 100644 --- a/arch/arm/kernel/smccc-call.S +++ b/arch/arm/kernel/smccc-call.S @@ -46,17 +46,19 @@ UNWIND( .fnend) /* * void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, * unsigned long a3, unsigned long a4, unsigned long a5, - * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) + * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, + * struct arm_smccc_quirk *quirk) */ -ENTRY(arm_smccc_smc) +ENTRY(__arm_smccc_smc) SMCCC SMCCC_SMC -ENDPROC(arm_smccc_smc) +ENDPROC(__arm_smccc_smc) /* * void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, * unsigned long a3, unsigned long a4, unsigned long a5, - * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) + * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, + * struct arm_smccc_quirk *quirk) */ -ENTRY(arm_smccc_hvc) +ENTRY(__arm_smccc_hvc) SMCCC SMCCC_HVC -ENDPROC(arm_smccc_hvc) +ENDPROC(__arm_smccc_hvc) diff --git a/arch/arm64/kernel/arm64ksyms.c b/arch/arm64/kernel/arm64ksyms.c index 78f3680..e9c4dc9 100644 --- a/arch/arm64/kernel/arm64ksyms.c +++ b/arch/arm64/kernel/arm64ksyms.c @@ -73,5 +73,5 @@ NOKPROBE_SYMBOL(_mcount); #endif /* arm-smccc */ -EXPORT_SYMBOL(arm_smccc_smc); -EXPORT_SYMBOL(arm_smccc_hvc); +EXPORT_SYMBOL(__arm_smccc_smc); +EXPORT_SYMBOL(__arm_smccc_hvc); diff --git a/arch/arm64/kernel/asm-offsets.c b/arch/arm64/kernel/asm-offsets.c index 4a2f0f0..c58ddf8 100644 --- a/arch/arm64/kernel/asm-offsets.c +++ b/arch/arm64/kernel/asm-offsets.c @@ -140,8 +140,11 @@ int main(void) DEFINE(SLEEP_STACK_DATA_SYSTEM_REGS, offsetof(struct sleep_stack_data, system_regs)); DEFINE(SLEEP_STACK_DATA_CALLEE_REGS, offsetof(struct sleep_stack_data, callee_saved_regs)); #endif - DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); - DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); + DEFINE(ARM_SMCCC_RES_X0_OFFS, offsetof(struct arm_smccc_res, a0)); + DEFINE(ARM_SMCCC_RES_X2_OFFS, offsetof(struct arm_smccc_res, a2)); + DEFINE(ARM_SMCCC_QUIRK_ID_OFFS, offsetof(struct arm_smccc_quirk, id)); + DEFINE(ARM_SMCCC_QUIRK_STATE_OFFS, offsetof(struct arm_smccc_quirk, state)); + BLANK(); DEFINE(HIBERN_PBE_ORIG, offsetof(struct pbe, orig_address)); DEFINE(HIBERN_PBE_ADDR, offsetof(struct pbe, address)); diff --git a/arch/arm64/kernel/smccc-call.S b/arch/arm64/kernel/smccc-call.S index ae0496f..ba60a8c 100644 --- a/arch/arm64/kernel/smccc-call.S +++ b/arch/arm64/kernel/smccc-call.S @@ -27,17 +27,19 @@ /* * void arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, * unsigned long a3, unsigned long a4, unsigned long a5, - * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) + * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, + * struct arm_smccc_quirk *quirk) */ -ENTRY(arm_smccc_smc) +ENTRY(__arm_smccc_smc) SMCCC smc -ENDPROC(arm_smccc_smc) +ENDPROC(__arm_smccc_smc) /* * void arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, * unsigned long a3, unsigned long a4, unsigned long a5, - * unsigned long a6, unsigned long a7, struct arm_smccc_res *res) + * unsigned long a6, unsigned long a7, struct arm_smccc_res *res, + * struct arm_smccc_quirk *quirk) */ -ENTRY(arm_smccc_hvc) +ENTRY(__arm_smccc_hvc) SMCCC hvc -ENDPROC(arm_smccc_hvc) +ENDPROC(__arm_smccc_hvc) diff --git a/include/linux/arm-smccc.h b/include/linux/arm-smccc.h index b5abfda..c66f8ae 100644 --- a/include/linux/arm-smccc.h +++ b/include/linux/arm-smccc.h @@ -72,33 +72,57 @@ struct arm_smccc_res { }; /** - * arm_smccc_smc() - make SMC calls + * struct arm_smccc_quirk - Contains quirk information + * @id: quirk identification + * @state: quirk specific information + * @a6: Qualcomm quirk entry for returning post-smc call contents of a6 + */ +struct arm_smccc_quirk { + int id; + union { + unsigned long a6; + } state; +}; + +/** + * __arm_smccc_smc() - make SMC calls * @a0-a7: arguments passed in registers 0 to 7 * @res: result values from registers 0 to 3 + * @quirk: points to an arm_smccc_quirk, or NULL when no quirks are required. * * This function is used to make SMC calls following SMC Calling Convention. * The content of the supplied param are copied to registers 0 to 7 prior * to the SMC instruction. The return values are updated with the content - * from register 0 to 3 on return from the SMC instruction. + * from register 0 to 3 on return from the SMC instruction. An optional + * quirk structure provides vendor specific behavior. */ -asmlinkage void arm_smccc_smc(unsigned long a0, unsigned long a1, +asmlinkage void __arm_smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7, - struct arm_smccc_res *res); + struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); /** - * arm_smccc_hvc() - make HVC calls + * __arm_smccc_hvc() - make HVC calls * @a0-a7: arguments passed in registers 0 to 7 * @res: result values from registers 0 to 3 * * This function is used to make HVC calls following SMC Calling * Convention. The content of the supplied param are copied to registers 0 * to 7 prior to the HVC instruction. The return values are updated with - * the content from register 0 to 3 on return from the HVC instruction. + * the content from register 0 to 3 on return from the HVC instruction. An + * optional quirk structure provides vendor specific behavior. */ -asmlinkage void arm_smccc_hvc(unsigned long a0, unsigned long a1, +asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2, unsigned long a3, unsigned long a4, unsigned long a5, unsigned long a6, unsigned long a7, - struct arm_smccc_res *res); + struct arm_smccc_res *res, struct arm_smccc_quirk *quirk); + +#define arm_smccc_smc(...) __arm_smccc_smc(__VA_ARGS__, NULL) + +#define arm_smccc_smc_quirk(...) __arm_smccc_smc(__VA_ARGS__) + +#define arm_smccc_hvc(...) __arm_smccc_hvc(__VA_ARGS__, NULL) + +#define arm_smccc_hvc_quirk(...) __arm_smccc_hvc(__VA_ARGS__) #endif /*__LINUX_ARM_SMCCC_H*/