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=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT 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 35548C2D0CD for ; Wed, 18 Dec 2019 21:39:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E5A6D2176D for ; Wed, 18 Dec 2019 21:39:50 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="ceU98/++" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726776AbfLRVju (ORCPT ); Wed, 18 Dec 2019 16:39:50 -0500 Received: from esa6.hgst.iphmx.com ([216.71.154.45]:31480 "EHLO esa6.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726734AbfLRVjk (ORCPT ); Wed, 18 Dec 2019 16:39:40 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1576705180; x=1608241180; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=F2H6D12MySAfOlwF8FaySn8H/TScW25G6FHJflaZfyA=; b=ceU98/++cSrbEM4RpJEOXpMVJa1BZ+rheOLTGpbuhjfQYtV+cAqBNrL0 KlJB1XEizf6GYm6kgEWdf3ziNr/LdykxDEqQW8nZwZInlAx0A8YyQ/fg2 oYewvT9JPHSAo0prFkPkt1toO64fjCecCRr1K3jssr84Bf0Yp2veZG8Lh Sudgoziy9g81YvEDWcThKL70yqg5WK6aG91+V/Sa64iA5zrLuNg76ORqA geiT32UCxaP7Djc0+91bJO5WMuwjA9W5Xk5QfuYDrvga5Lm5YjRlP+/yf Pyrx6PCNm1xgEh+gVenw6oJplpEWeFwgMJctrze7EIH8LC3NSUasXlrUR A==; IronPort-SDR: RiLONMbGhDrpSN7pdkMZP46ssq/yv6kulHAcRqdqqwyJO5w2W66VMh9vl/LVUKdKqYPn7doiKK 66xauk+Rn2KCNzi0SwIALP33qzvcN4+xRIRuOUsoxhBMYumAcxVpwXbUUVeXAbBx6ajqhjgwg3 sUKYAjvxpLeRfGDqJ+TQOpw1ANXySPAaX5dIGRHnBBirRgNgAnyav5MMJxRp7RMV7f39b5SVPB Ii+UYGOdu1q/Q8Gf8w/rexaBH/yZLKagy6goACTaIYt4J3BKEae0eN17ynidRWB3p/NocZe32n 9QE= X-IronPort-AV: E=Sophos;i="5.69,330,1571673600"; d="scan'208";a="127281472" Received: from h199-255-45-15.hgst.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 19 Dec 2019 05:39:38 +0800 IronPort-SDR: er1MCqVzR9yI5EOU0JATSP/y1z6BfekBnFzMsCXPWyVN5s5Ia0epDDDDBEB1kJ5a5IT2s4RzNC z+R3nla3HeEoW516ydLnSk2CKpkHdbc2aURHlakCIN8x1D+9XOWsp3OAKQoiBq9bTbISBYVw1t wi0Tg+whCR9BJpwDTCyZAYg9CYhLpxF7dzPQ7PDPZxU5DmH0knkjaCXA1MiwBZpl8npUE+ZIl2 c4aw/G0PMEmrqZQYn8X8EAuE0naHEEMwZdYsjszU0OIwKqhT0p6LEEmcuCVefLpEgUoV7fVDkj hIeDje2lxL7AETnxWVR5Mpa2 Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep02.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 18 Dec 2019 13:33:39 -0800 IronPort-SDR: JxDb8vYJNxOikw61CO1ta0oYtgBCY1eUs72sisvQg2cECiSMkj2RJRApGIktOri7ZLCNlmPW8Y WfBDASJnAjiMV2fWl6VumL1cxXVALQxc4DiXzMlIie1exvulaWsrmCg8t+Eiq8G2M541n18k8Y p1dN93hw8nJMNESSBK9Qm33FWLpfhCygM/D0LPnRx+/P9wp46xwssdxaE9kYzKx/gZruffe5kx CC/5GybwfR2CaFmIqzkv5bvGEjG3OXGJhJ7LF7F+WwvqrdViku9dUtVG35AVKHRFbxaHlAmFDX gqI= WDCIronportException: Internal Received: from jedi-01.sdcorp.global.sandisk.com (HELO jedi-01.int.fusionio.com) ([10.11.143.218]) by uls-op-cesaip02.wdc.com with ESMTP; 18 Dec 2019 13:39:38 -0800 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Anup Patel , Albert Ou , linux-riscv@lists.infradead.org, Mike Rapoport , Palmer Dabbelt , Paul Walmsley , Thomas Gleixner , Atish Patra , Palmer Dabbelt Subject: [PATCH v6 5/5] RISC-V: Implement new SBI v0.2 extensions Date: Wed, 18 Dec 2019 13:39:18 -0800 Message-Id: <20191218213918.16676-6-atish.patra@wdc.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191218213918.16676-1-atish.patra@wdc.com> References: <20191218213918.16676-1-atish.patra@wdc.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Few v0.1 SBI calls are being replaced by new SBI calls that follows v0.2 calling convention. Implement the replacement extensions and few additional new SBI function calls that makes way for a better SBI interface in future. Signed-off-by: Atish Patra Reviewed-by: Anup Patel --- arch/riscv/include/asm/sbi.h | 14 +++ arch/riscv/kernel/sbi.c | 198 ++++++++++++++++++++++++++++++++++- 2 files changed, 208 insertions(+), 4 deletions(-) diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 89a25a049d12..e5569e7fdd7c 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -96,6 +96,20 @@ void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start, unsigned long size, unsigned long asid); +int sbi_remote_hfence_gvma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size); +int sbi_remote_hfence_gvma_vmid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long vmid); +int sbi_remote_hfence_vvma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size); +int sbi_remote_hfence_vvma_asid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long asid); int sbi_probe_extension(int ext); /* Check if current SBI specification version is 0.1 or not */ diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c index 265637cb5eb0..a1f2fca11f71 100644 --- a/arch/riscv/kernel/sbi.c +++ b/arch/riscv/kernel/sbi.c @@ -193,6 +193,102 @@ static int __sbi_rfence_v01(int fid, } #endif /* CONFIG_RISCV_SBI_V01 */ +static void __sbi_set_timer_v02(uint64_t stime_value) +{ +#if __riscv_xlen == 32 + sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, + stime_value >> 32, 0, 0, 0, 0); +#else + sbi_ecall(SBI_EXT_TIME, SBI_EXT_TIME_SET_TIMER, stime_value, 0, + 0, 0, 0, 0); +#endif +} + +static int __sbi_send_ipi_v02(const unsigned long *hart_mask) +{ + unsigned long hmask_val; + struct cpumask tmask; + struct sbiret ret = {0}; + int result; + + if (!hart_mask) { + riscv_cpuid_to_hartid_mask(cpu_online_mask, &tmask); + hmask_val = *(cpumask_bits(&tmask)); + } else + hmask_val = *hart_mask; + + ret = sbi_ecall(SBI_EXT_IPI, SBI_EXT_IPI_SEND_IPI, hmask_val, + 0, 0, 0, 0, 0); + if (ret.error) { + result = sbi_err_map_linux_errno(ret.error); + pr_err("%s: failed with error [%d]\n", __func__, result); + } else + result = ret.value; + + return result; +} + +static int __sbi_rfence_v02(int fid, const unsigned long *hart_mask, + unsigned long hbase, unsigned long start, + unsigned long size, unsigned long arg4, + unsigned long arg5) +{ + unsigned long hmask_val; + struct cpumask tmask; + struct sbiret ret = {0}; + int ext = SBI_EXT_RFENCE; + int result; + + if (!hart_mask) { + riscv_cpuid_to_hartid_mask(cpu_online_mask, &tmask); + hmask_val = *(cpumask_bits(&tmask)); + } else + hmask_val = *hart_mask; + + switch (fid) { + case SBI_EXT_RFENCE_REMOTE_FENCE_I: + ret = sbi_ecall(ext, fid, hmask_val, 0, 0, 0, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: + ret = sbi_ecall(ext, fid, hmask_val, 0, start, + size, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: + ret = sbi_ecall(ext, fid, hmask_val, 0, start, + size, arg4, 0); + break; + /*TODO: Handle non zero hbase cases */ + case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA: + ret = sbi_ecall(ext, fid, hmask_val, 0, start, + size, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID: + ret = sbi_ecall(ext, fid, hmask_val, 0, start, + size, arg4, 0); + break; + case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA: + ret = sbi_ecall(ext, fid, hmask_val, 0, start, + size, 0, 0); + break; + case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID: + ret = sbi_ecall(ext, fid, hmask_val, 0, start, + size, arg4, 0); + break; + default: + pr_err("unknown function ID [%d] for SBI extension [%d]\n", + fid, ext); + result = -EINVAL; + } + + if (ret.error) { + result = sbi_err_map_linux_errno(ret.error); + pr_err("%s: failed with error [%d]\n", __func__, result); + } else + result = ret.value; + + return result; +} + /** * sbi_set_timer() - Program the timer for next timer event. * @stime_value: The value after which next timer event should fire. @@ -269,6 +365,85 @@ void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, } EXPORT_SYMBOL(sbi_remote_sfence_vma_asid); +/** + * sbi_remote_hfence_gvma() - Execute HFENCE.GVMA instructions on given remote + * harts for the specified guest physical address range. + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the guest physical address + * @size: Total size of the guest physical address range. + * + * Return: None + */ +int sbi_remote_hfence_gvma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size) +{ + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA, + hart_mask, 0, start, size, 0, 0); +} +EXPORT_SYMBOL_GPL(sbi_remote_hfence_gvma); + +/** + * sbi_remote_hfence_gvma_vmid() - Execute HFENCE.GVMA instructions on given + * remote harts for a guest physical address range belonging to a specific VMID. + * + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the guest physical address + * @size: Total size of the guest physical address range. + * @vmid: The value of guest ID (VMID). + * + * Return: 0 if success, Error otherwise. + */ +int sbi_remote_hfence_gvma_vmid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long vmid) +{ + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID, + hart_mask, 0, start, size, vmid, 0); +} +EXPORT_SYMBOL(sbi_remote_hfence_gvma_vmid); + +/** + * sbi_remote_hfence_vvma() - Execute HFENCE.VVMA instructions on given remote + * harts for the current guest virtual address range. + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the current guest virtual address + * @size: Total size of the current guest virtual address range. + * + * Return: None + */ +int sbi_remote_hfence_vvma(const unsigned long *hart_mask, + unsigned long start, + unsigned long size) +{ + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA, + hart_mask, 0, start, size, 0, 0); +} +EXPORT_SYMBOL(sbi_remote_hfence_vvma); + +/** + * sbi_remote_hfence_vvma_asid() - Execute HFENCE.VVMA instructions on given + * remote harts for current guest virtual address range belonging to a specific + * ASID. + * + * @hart_mask: A cpu mask containing all the target harts. + * @start: Start of the current guest virtual address + * @size: Total size of the current guest virtual address range. + * @asid: The value of address space identifier (ASID). + * + * Return: None + */ +int sbi_remote_hfence_vvma_asid(const unsigned long *hart_mask, + unsigned long start, + unsigned long size, + unsigned long asid) +{ + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID, + hart_mask, 0, start, size, asid, 0); +} +EXPORT_SYMBOL(sbi_remote_hfence_vvma_asid); + /** * sbi_probe_extension() - Check if an SBI extension ID is supported or not. * @extid: The extension ID to be probed. @@ -335,11 +510,26 @@ int __init sbi_init(void) if (!sbi_spec_is_0_1()) { pr_info("SBI implementation ID=0x%lx Version=0x%lx\n", sbi_get_firmware_id(), sbi_get_firmware_version()); + if (sbi_probe_extension(SBI_EXT_TIME) > 0) { + __sbi_set_timer = __sbi_set_timer_v02; + pr_info("SBI v0.2 TIME extension detected\n"); + } else + __sbi_set_timer = __sbi_set_timer_v01; + if (sbi_probe_extension(SBI_EXT_IPI) > 0) { + __sbi_send_ipi = __sbi_send_ipi_v02; + pr_info("SBI v0.2 IPI extension detected\n"); + } else + __sbi_send_ipi = __sbi_send_ipi_v01; + if (sbi_probe_extension(SBI_EXT_RFENCE) > 0) { + __sbi_rfence = __sbi_rfence_v02; + pr_info("SBI v0.2 RFENCE extension detected\n"); + } else + __sbi_rfence = __sbi_rfence_v01; + } else { + __sbi_set_timer = __sbi_set_timer_v01; + __sbi_send_ipi = __sbi_send_ipi_v01; + __sbi_rfence = __sbi_rfence_v01; } - __sbi_set_timer = __sbi_set_timer_v01; - __sbi_send_ipi = __sbi_send_ipi_v01; - __sbi_rfence = __sbi_rfence_v01; - return 0; } -- 2.24.0