From patchwork Wed Dec 18 21:39:18 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11302037 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 D0F951580 for ; Wed, 18 Dec 2019 21:39:52 +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 A291621582 for ; Wed, 18 Dec 2019 21:39:52 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="WufV+y8i"; dkim=fail reason="signature verification failed" (2048-bit key) header.d=wdc.com header.i=@wdc.com header.b="HrzKt8Hq" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org A291621582 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=qsHI/e9zfEXBJKDfiur13NsoIYTjE2xZJOVQYBnkevg=; b=WufV+y8idDx26i p720HuAI689fn4gBaqvbekDyVWcFjIsLCMxDOlRTMGwqJ5GJ8BzAnfzJ/aDtWE07LRk6zFbRBCdG1 TzaKlNDmhe+ZhmDnRkh4Wl1KtnLP+BJ1BcH21h2zZdoq9Kifs3OppcDiNqJe8gVjAgKLI7OwToFP8 OXDL2u4gdB285AjYFhJ/a6vpE3E9rvWerTLYSPElsShfwIjcY/RXZvsjVFRxvrVwt8g0mbfV/+gei XlGEXuVX/BB+QG4pZITc3spZV+mOi9XrDPmczioxj/FQ2F7KVW7Th7ki/VIyMvXzWrFoiLiZOo2Mg hyfogP4f6YROETYfxKJQ==; 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 1ihh2u-0007IZ-0P; Wed, 18 Dec 2019 21:39:52 +0000 Received: from esa3.hgst.iphmx.com ([216.71.153.141]) by bombadil.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1ihh2k-00073o-Ri for linux-riscv@lists.infradead.org; Wed, 18 Dec 2019 21:39:44 +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=1576705183; x=1608241183; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=F2H6D12MySAfOlwF8FaySn8H/TScW25G6FHJflaZfyA=; b=HrzKt8HqZmUvMnSmBg98peTxtlzi/iAvDNW4lDAE8IZiSugFuHmjm9go C6nVtQVIR7HbCY7zc6baDNWqLDX9iGDOy8Kfz7ZxchtOMwbh/Yq2vYtT/ boFFmKMEt38eFhnhsC31RKBqwPMe1GSZXx5ad4uiVL0QY8pifQ0hvx8Jx Ew1VWHjMdEXu/C1TiXo3KYK2SLY9ofEr5HwsGGRwv7IvR9HDXk20rB2Gc rwlCxFco2JnH2Yb0uh/SviOH8Kn1nPyE14HR+etCH2cdWstMPyXLGm7+F bgkySLQ/yVo8tr+39/OmFz4xZmQGhrP2jbYrexKMlqhs104zIWyttFhyJ g==; IronPort-SDR: 4Hivq3yf51fva1G4gjx5dDUBol0NSGHhwMn6/93GZOpF8RjGONQGtV4p3FJuKYS08r3Sga3iGg AGz25ieZ/t8CgHrvD+iwAsKvyQ6+tLp7ATfFMvnX+7z/QJzIjl0YJ/zcJrW/wTZEOBYzEDJ/6k vG6QG+3/JdVjqrtcZc78PuNwkXsC6Y3t1Obyy0ss7qRhyV1mi6wB8jsU7ah5SZzMsZM0Ohe1cR Z+EXzCt1J5z3bjLtB0SogOE42ca05OAGujtXQESiGBjpEUe+oNDx8+050r10t6L4SHTgdKFKp2 bMo= X-IronPort-AV: E=Sophos;i="5.69,330,1571673600"; d="scan'208";a="130100636" Received: from h199-255-45-14.hgst.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 19 Dec 2019 05:39:39 +0800 IronPort-SDR: UthFQaumrOY3/bKyp1Ahw7OVUbKUH1nMeScXcPvWcoWsZPmHY5w7OnG1+sij8N68AuUWGteKgY n3OPWUbqqSvKQ/uaxsEV06V0ySPnajt4ahsoHnpBCrRV53b2ahSsN+Nl2LCYJBFAIA0VjiPaoA Uyzq1YrETRU0f5e5BwQwsFB+zc6zD5sfLcBdf9xmDV4ehhQNwLRliDQyBL0xQ+HSTyqB2c5yUN +ujyPBAm3kPnwykfLmrRF5cEOx8EYdjxmgq7Kx9De/2CWoo/JHNhhf+OXHLcIrI7qzEnEgSUzQ Q2ZN6FbAwVebVEFTp1qrLoku 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; 18 Dec 2019 13:34:01 -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 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 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20191218_133942_917223_A3FBC332 X-CRM114-Status: GOOD ( 14.30 ) X-Spam-Score: -2.5 (--) X-Spam-Report: SpamAssassin version 3.4.2 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 [216.71.153.141 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 Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from envelope-from domain -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from author's domain 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: Albert Ou , Anup Patel , Atish Patra , Mike Rapoport , Atish Patra , Palmer Dabbelt , Paul Walmsley , Palmer Dabbelt , linux-riscv@lists.infradead.org, Thomas Gleixner Sender: "linux-riscv" Errors-To: linux-riscv-bounces+patchwork-linux-riscv=patchwork.kernel.org@lists.infradead.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; }