From patchwork Wed Feb 26 22:02:11 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11407373 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 3460814B4 for ; Wed, 26 Feb 2020 22:03:00 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 0D72321D7E for ; Wed, 26 Feb 2020 22:03:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="NQTvNh0x"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="CRtXOued" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0D72321D7E Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=wdc.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id: Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-Id:Date :Subject:To:From:Reply-To:Content-Type:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=QP/7Hmzuy55zFPDrv5rYCEb1TKFrYfnt7THOVTNwwH8=; b=NQTvNh0xd1qcKM HB7bkdnv3tn8bCueiErNmYbN34BhKWgQ61Kko7e0GdQuTOOULMFpNG6CyLzYLwgp0gwTxId1REGwA WvDpvpRDSAZoPWYd2ihWmm1qlnro45uIwzxjLM+NGy+iShkzu5pw77DlPQGW6sP8MITdBFB67bxvH IppKq+vJG845lGuHslNYc+77LUYvio8dawkEO4pyoWrSVnCdD8NrcEUXMPkO1XV8lIt/ylNEm9zx0 5mS/I70fJON2jYl499W5aWkzYWN1jR7mujt95QGAUh3NLDIHmoBxSy6UMOeK+tifBHDEZLYNfAdOK FUEX2jSkkEeLvlztKgBg==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1j74lb-0004OA-6Y; Wed, 26 Feb 2020 22:02:55 +0000 Received: from esa1.hgst.iphmx.com ([68.232.141.245]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1j74lC-0003oY-LS for linux-riscv@lists.infradead.org; Wed, 26 Feb 2020 22:02:32 +0000 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1582754550; x=1614290550; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=U35XF1CKYWzhgzuZboVKa7NT7J12Ff9SA644B0PoBj4=; b=CRtXOuedS9FwZIINzj6/htChT08XT/T+dxdK5BxTLQF83V4H8cttW2se fRtcghsGcscrpNw9EdtBFywz5bBsZB9k+i4KHpg9HPWy+TKM9bdKV0Hkg opXiYR1nJxUv9nvET7IYK8BpVqj9LaeKBM5GRAg8uyDyYr3p7NRshpQMq Xt3CzIKU4FzLLL/SwF8jIZsOcfJqnHYacU+MlZH/Vg27wqMS0U+co7uXz Fzupm5Cwzi1ESLH33t1lhq4oi9ER4YWRCjc+hqTv2G4vlaYWyFrWOwvIb +nND0Y6YFigX6rkwwziD4EtqiZ382bHY0cwDm5umaYMx6SJq52t4twnJ1 Q==; IronPort-SDR: sIOT5m3Tp7cUxSKit+R2GEAGBgw+UdwEUJ2bmgQ6y26r23L8oC3gAqV4w56QW5zDhIIKNdA30B 2jHJ9mRQNHTx3yXOlgGMZY3/lunbjj/vo8ORO2Jl8AyPvkSjExW5MuBnwEEqepOZoHbLGvOXFZ Q2HUuueoHFjfrCcldWPppIsgE1Gc68SPHzinGRLCwxIjzAfOMQEgszokPSJ8pJ51rpX1hoKUAA 3PTJZcLhWby5ZpYwltD3ZqUlMIHK/ow4PXSPSCKXea4QdcnQ/31hAwdkjVinz3PU4bxVVk5JOz KZU= X-IronPort-AV: E=Sophos;i="5.70,489,1574092800"; d="scan'208";a="238981880" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 27 Feb 2020 06:02:26 +0800 IronPort-SDR: 03sm/W0iL1wAseElkkXYrMhHOhMvmbq4l2Ke9EJTV1NYn5F2g53Hq5oDeOcTNPZcfyAYLkywOI qZDV62AJj7458VK5mKkhpesAXxZH3dJAsvRLi/BLByCckbhThxTjmljViYfErLK3wnp6ydyHdr FnneB7b6OVE/BtL14m4U86qOG3u67lZ57Lh+nBiE8a9tcZWoJvtpPOjzotP8ueGHyrF5WNg8oc 2wiyshUi72raqKQRZBJ5ZVKWreS6MndIH8k44Ag+275zJ4Un71cm702s4g8Sipde1X1Ml5bo+u HFD8QN81UQ3mH3jUEia9CMdG Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 26 Feb 2020 13:54:50 -0800 IronPort-SDR: MChZIQlV3kwaNbOdz59YG+WCoUltZSHgUoYSW1LtcIx9y9LNcojbjRpcXKJMRVdbQVeGoFwvI7 gPipAKxPAkyJqAu++DTcXJuY90eJZgbyFuOkrsFiaLbrxR6CHPS72+CJV4sDhwt8J+41dlj8kI JuKpTS5nPm2CuX5tzHYuGxQt2YQlP2fDZxf6MN8CDVzic3qK3imZ2Um4bCiYup7N853Wxc2LT1 +AV2G03cz9ZSLaOFgU/eZI8v1GP0MV3d+mt0KL25UDtswjlNlvudG/50/wwzyUjs+8KgIcTkDB oBo= WDCIronportException: Internal Received: from yoda.sdcorp.global.sandisk.com (HELO yoda.int.fusionio.com) ([10.196.158.80]) by uls-op-cesaip02.wdc.com with ESMTP; 26 Feb 2020 14:02:25 -0800 From: Atish Patra To: linux-kernel@vger.kernel.org Subject: [PATCH v10 10/12] RISC-V: Add supported for ordered booting method using HSM Date: Wed, 26 Feb 2020 14:02:11 -0800 Message-Id: <20200226220213.27423-11-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.0 In-Reply-To: <20200226220213.27423-1-atish.patra@wdc.com> References: <20200226220213.27423-1-atish.patra@wdc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200226_140230_769658_646F2002 X-CRM114-Status: GOOD ( 18.56 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.3 on bombadil.infradead.org summary: Content analysis details: (-2.5 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at https://www.dnswl.org/, medium trust [68.232.141.245 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature X-BeenThere: linux-riscv@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kate Stewart , Madhavan Srinivasan , Zong Li , Heiko Carstens , Michael Kelley , Atish Patra , Gary Guo , linux-riscv@lists.infradead.org, Mike Rapoport , Kees Cook , Marc Zyngier , "Rafael J. Wysocki" , Daniel Jordan , Geert Uytterhoeven , Greentime Hu , Borislav Petkov , Mao Han , Albert Ou , Jason Cooper , Sudeep Holla , Alexios Zavras , Paul Walmsley , Thomas Gleixner , Nick Hu , Greg Kroah-Hartman , Vincent Chen , Palmer Dabbelt , "Eric W. Biederman" , Anup Patel , Steven Price Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.org Currently, all harts have to jump Linux in RISC-V. This complicates the multi-stage boot process as every transient stage also has to ensure all harts enter to that stage and jump to Linux afterwards. It also obstructs a clean Kexec implementation. SBI HSM extension provides alternate solutions where only a single hart need to boot and enter Linux. The booting hart can bring up secondary harts one by one afterwards. Add SBI HSM based cpu_ops that implements an ordered booting method in RISC-V. This change is also backward compatible with older firmware not implementing HSM extension. If a latest kernel is used with older firmware, it will continue to use the default spinning booting method. Signed-off-by: Atish Patra Reviewed-by: Anup Patel --- arch/riscv/kernel/Makefile | 3 ++ arch/riscv/kernel/cpu_ops.c | 10 +++- arch/riscv/kernel/cpu_ops_sbi.c | 81 +++++++++++++++++++++++++++++++++ arch/riscv/kernel/head.S | 26 +++++++++++ arch/riscv/kernel/smpboot.c | 2 +- arch/riscv/kernel/traps.c | 2 +- 6 files changed, 121 insertions(+), 3 deletions(-) create mode 100644 arch/riscv/kernel/cpu_ops_sbi.c diff --git a/arch/riscv/kernel/Makefile b/arch/riscv/kernel/Makefile index f81a6ff88005..a0be34b96846 100644 --- a/arch/riscv/kernel/Makefile +++ b/arch/riscv/kernel/Makefile @@ -44,5 +44,8 @@ obj-$(CONFIG_PERF_EVENTS) += perf_event.o obj-$(CONFIG_PERF_EVENTS) += perf_callchain.o obj-$(CONFIG_HAVE_PERF_REGS) += perf_regs.o obj-$(CONFIG_RISCV_SBI) += sbi.o +ifeq ($(CONFIG_RISCV_SBI), y) +obj-$(CONFIG_SMP) += cpu_ops_sbi.o +endif clean: diff --git a/arch/riscv/kernel/cpu_ops.c b/arch/riscv/kernel/cpu_ops.c index e950ae5bee9c..afa90f711a2b 100644 --- a/arch/riscv/kernel/cpu_ops.c +++ b/arch/riscv/kernel/cpu_ops.c @@ -18,6 +18,7 @@ const struct cpu_operations *cpu_ops[NR_CPUS] __ro_after_init; void *__cpu_up_stack_pointer[NR_CPUS]; void *__cpu_up_task_pointer[NR_CPUS]; +extern const struct cpu_operations cpu_ops_sbi; extern const struct cpu_operations cpu_ops_spinwait; void cpu_update_secondary_bootdata(unsigned int cpuid, @@ -34,5 +35,12 @@ void cpu_update_secondary_bootdata(unsigned int cpuid, void __init cpu_set_ops(int cpuid) { - cpu_ops[cpuid] = &cpu_ops_spinwait; +#if IS_ENABLED(CONFIG_RISCV_SBI) + if (sbi_probe_extension(SBI_EXT_HSM) > 0) { + if (!cpuid) + pr_info("SBI v0.2 HSM extension detected\n"); + cpu_ops[cpuid] = &cpu_ops_sbi; + } else +#endif + cpu_ops[cpuid] = &cpu_ops_spinwait; } diff --git a/arch/riscv/kernel/cpu_ops_sbi.c b/arch/riscv/kernel/cpu_ops_sbi.c new file mode 100644 index 000000000000..70d02dfe0ab8 --- /dev/null +++ b/arch/riscv/kernel/cpu_ops_sbi.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * HSM extension and cpu_ops implementation. + * + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + */ + +#include +#include +#include +#include +#include + +extern char secondary_start_sbi[]; +const struct cpu_operations cpu_ops_sbi; + +static int sbi_hsm_hart_start(unsigned long hartid, unsigned long saddr, + unsigned long priv) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_START, + hartid, saddr, priv, 0, 0, 0); + if (ret.error) + return sbi_err_map_linux_errno(ret.error); + else + return 0; +} + +#ifdef CONFIG_HOTPLUG_CPU +static int sbi_hsm_hart_stop(void) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_STOP, 0, 0, 0, 0, 0, 0); + + if (ret.error) + return sbi_err_map_linux_errno(ret.error); + else + return 0; +} + +static int sbi_hsm_hart_get_status(unsigned long hartid) +{ + struct sbiret ret; + + ret = sbi_ecall(SBI_EXT_HSM, SBI_EXT_HSM_HART_STATUS, + hartid, 0, 0, 0, 0, 0); + if (ret.error) + return sbi_err_map_linux_errno(ret.error); + else + return ret.value; +} +#endif + +static int sbi_cpu_start(unsigned int cpuid, struct task_struct *tidle) +{ + int rc; + unsigned long boot_addr = __pa_symbol(secondary_start_sbi); + int hartid = cpuid_to_hartid_map(cpuid); + + cpu_update_secondary_bootdata(cpuid, tidle); + rc = sbi_hsm_hart_start(hartid, boot_addr, 0); + + return rc; +} + +static int sbi_cpu_prepare(unsigned int cpuid) +{ + if (!cpu_ops_sbi.cpu_start) { + pr_err("cpu start method not defined for CPU [%d]\n", cpuid); + return -ENODEV; + } + return 0; +} + +const struct cpu_operations cpu_ops_sbi = { + .name = "sbi", + .cpu_prepare = sbi_cpu_prepare, + .cpu_start = sbi_cpu_start, +}; diff --git a/arch/riscv/kernel/head.S b/arch/riscv/kernel/head.S index b85376d84098..ac5b0e0a02f6 100644 --- a/arch/riscv/kernel/head.S +++ b/arch/riscv/kernel/head.S @@ -99,11 +99,37 @@ relocate: ret #endif /* CONFIG_MMU */ #ifdef CONFIG_SMP + .global secondary_start_sbi +secondary_start_sbi: + /* Mask all interrupts */ + csrw CSR_IE, zero + csrw CSR_IP, zero + + /* Load the global pointer */ + .option push + .option norelax + la gp, __global_pointer$ + .option pop + + /* + * Disable FPU to detect illegal usage of + * floating point in kernel space + */ + li t0, SR_FS + csrc CSR_STATUS, t0 + /* Set trap vector to spin forever to help debug */ la a3, .Lsecondary_park csrw CSR_TVEC, a3 slli a3, a0, LGREG + la a4, __cpu_up_stack_pointer + la a5, __cpu_up_task_pointer + add a4, a3, a4 + add a5, a3, a5 + REG_L sp, (a4) + REG_L tp, (a5) + .global secondary_start_common secondary_start_common: diff --git a/arch/riscv/kernel/smpboot.c b/arch/riscv/kernel/smpboot.c index e89396a2a1af..4e9922790f6e 100644 --- a/arch/riscv/kernel/smpboot.c +++ b/arch/riscv/kernel/smpboot.c @@ -143,7 +143,7 @@ void __init smp_cpus_done(unsigned int max_cpus) /* * C entry point for a secondary processor. */ -asmlinkage __visible void __init smp_callin(void) +asmlinkage __visible void smp_callin(void) { struct mm_struct *mm = &init_mm; diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index ffb3d94bf0cc..8e13ad45ccaa 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -147,7 +147,7 @@ int is_valid_bugaddr(unsigned long pc) } #endif /* CONFIG_GENERIC_BUG */ -void __init trap_init(void) +void trap_init(void) { /* * Set sup0 scratch register to 0, indicating to exception vector