Received: by 2002:a25:8b91:0:0:0:0:0 with SMTP id j17csp4181767ybl; Mon, 27 Jan 2020 18:30:52 -0800 (PST) X-Google-Smtp-Source: APXvYqxVWcXp419y6bG7fWABkCpg0lZEUfIzlhi3Ill6kZrwp1TQcYJZzssnb1QZz+505ae830I+ X-Received: by 2002:a05:6808:4c7:: with SMTP id a7mr1480583oie.83.1580178652062; Mon, 27 Jan 2020 18:30:52 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1580178652; cv=none; d=google.com; s=arc-20160816; b=u5eU0x1mAPg28gzmAA07Wh1emwZoTBm6v8diaHPd9t0qVDusnJZWFZoYy/b8ZKIli/ nQ9pGFaBCQaYvSMSV4nWR4eth3Nxg5NnshebH7Cn5gBvPbxXakFz5rIXziwzMGOOJTCa o9Bk1nyQ/Rvt0SkGdLtWo90oY7LykJSMq53eu8MvKL+xz2wXfSGvN5hTzBIJx0wZZOpI RvtDfzoFGr/6PibsMInTmEunSBeU9bcxbzptgnIf/+CHgCZdu3uYkUrhr5Lfdh2vkxOt 4nQTZ93WicVt0mQOPjdexUq3+KFd2atkDMSAJwAzAhUzobQyyAZdTpfe3ZQzyTFarXO5 b1aw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :wdcironportexception:ironport-sdr:ironport-sdr:ironport-sdr :dkim-signature; bh=cYGWuP7p+OY5r5djdIR4zZ1YI5BsuaATzEjCZHq2qdc=; b=ybtyoaRBlgtot+2RZs+zZajteowGjSCSccHL9pVIgJ4BnzEKkhQj9EoectuK5takpk i591tsOl1GApvvaind5v3orw3228auoFc3eBnbSVSG+b18tkEkMFanaSQ1X1uNMCysf7 SnNuH7JqjLDYl+DEixlTS/Ji2EAvW6zUEsUPLMuyjGmF641riaYe06XpChrYfWTyKMiP TZJ6ZVmyNIkdbOSSGUb+Zq5zVCOvqJgb2TmE/9PFbP0ss1E+NOxTOiZdcT67yEy9ynoX 05/fVcW0w2bG8lU8flAq4NIFlihrPbZDNCncQytUSttHLRVQjf9+O5Ihmk7224h3NV5+ xc4A== ARC-Authentication-Results: i=1; mx.google.com; dkim=fail header.i=@wdc.com header.s=dkim.wdc.com header.b=d+DscFqG; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=wdc.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id r21si6232549ota.204.2020.01.27.18.30.22; Mon, 27 Jan 2020 18:30:52 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=fail header.i=@wdc.com header.s=dkim.wdc.com header.b=d+DscFqG; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=wdc.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727306AbgA1C2L (ORCPT + 99 others); Mon, 27 Jan 2020 21:28:11 -0500 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:43171 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727066AbgA1C2K (ORCPT ); Mon, 27 Jan 2020 21:28:10 -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=1580178490; x=1611714490; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=JHpPLFr6vGVpqUFOcQ9VONtgOFfqP4DecPnVFjv5he8=; b=d+DscFqGFbLgmRhnoPdlHp6XesnYLHuWgNlwzc0OpBjJacM12y8+nhUt 9xGsLRHmiz4A62g7lLsoQtKFZkQeNvm/rwy7xb5YHOAS9a0CFgRhypCIS Ig9cVxvud81pv3zDw0dmDTabHk7u/tKTUIxNQZq8V7BiBvS2AyeLqlMRH tmw7BNIljIp/+WQl44T1WZw2FNwjebkboD8I/0D3iObqekBVwZDEvWg0E kOBSgnZFPILOwv2BufFHrLS3lplzrUV5rBM5jFzFoPhQMwOcacea8+Bxu wixr7UReeH2Iq0nu5DbscHzlVP1EVm02a5bE67VYTqmK+U+4+pLKbrnDR A==; IronPort-SDR: OU+iuWaEQojignrPaE4dtlRFbq818E31SjoX/a5kFFtwWv+AkLPvvvvkHC9EKlqpW+wNEcBT/F TaBeltYIiHMaLg5O+LiP/UJrVTnA7rriqm2TPLOtQO7FSYSpdDU/8AjVaprSOmG3Eb/LziPlzD wWb2LsohJUfj0WyrYE8Lu27MtJ/6VystKCHnvuCfgx7vXunzlS1Xx1mNZgpv0UlGsOZQqXHlzU Xu8DvJbbRZ5x1JJfOerOMu3IWGV/0vL4jjm/yBZ64HhcAZWvbl4g6xWWr2MubdsZZ6nFyMVdI4 Rv0= X-IronPort-AV: E=Sophos;i="5.70,372,1574092800"; d="scan'208";a="132899401" 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; 28 Jan 2020 10:28:09 +0800 IronPort-SDR: 4c6OIh+c4lZYh6GQmsuJLFclG8fzS/qAp5tTB2swHdUxlhrAIc6V4Cgt79ZBhDGaPSpf983u3m PPSVTa2iS7PYDMHtPDbJZUluCvphhr/rzfAlT4t3lfUcxuvD99TNh/9gtFHmS7isWWPgOlNYtr egB+pcunWeFAnzDeQ47/9OdnQbdJZX+IYe0O+HFG7herXrm5NcGQbe3TxUeZwK0kMXvS8g5QzG BfA53llzoO+reGaWdhsEIqHGViazSzS3sSvh73DoIWbq+E4/nmYcaXbbvja1NwXuzip9uaFLU1 wDveY5sSF8qkEZKRwvT0Zmq9 Received: from uls-op-cesaip01.wdc.com ([10.248.3.36]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 27 Jan 2020 18:21:24 -0800 IronPort-SDR: aPHdvZjkLORq5xZwWPHojsFiJ0wTJEj59qMq2ru77ik/GzwSIBtwSoUzyKNyQIMsM/uyPR6P44 5XJr3iqKeak23qkYiR8GlGPOirOi9U4lGX/Kfl0x2xostWWAMkos3aoVJe1F+2jo/35YMGPeD8 d3OWVM0IxCZ/rrzRL8jjsg4BTQXURp4ZDTp4FWbGNP3NFgLKb6xdE5dlw2fzaGWwMzotmdObCI eL12jM8ddB8KlXHA0NeM4Z2Tz3hOq3rXgpVy35Sfoqld5yOWEH+9b+lnD0kjZTWWJXB+VKi7FK IXE= WDCIronportException: Internal Received: from jedi-01.sdcorp.global.sandisk.com (HELO jedi-01.int.fusionio.com) ([10.11.143.218]) by uls-op-cesaip01.wdc.com with ESMTP; 27 Jan 2020 18:28:10 -0800 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Anup Patel , Albert Ou , Borislav Petkov , "Eric W. Biederman" , Geert Uytterhoeven , Greentime Hu , Greg Kroah-Hartman , Heiko Carstens , Kees Cook , linux-riscv@lists.infradead.org, Mao Han , Mike Rapoport , Palmer Dabbelt , Paul Walmsley , Thomas Gleixner , Vincent Chen , abner.chang@hpe.com, clin@suse.com, nickhu@andestech.com, Palmer Dabbelt Subject: [PATCH v7 05/10] RISC-V: Implement new SBI v0.2 extensions Date: Mon, 27 Jan 2020 18:27:32 -0800 Message-Id: <20200128022737.15371-6-atish.patra@wdc.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200128022737.15371-1-atish.patra@wdc.com> References: <20200128022737.15371-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/include/asm/smp.h | 7 ++ arch/riscv/kernel/sbi.c | 199 ++++++++++++++++++++++++++++++++++- 3 files changed, 216 insertions(+), 4 deletions(-) diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 4d67bef8f894..d55d8090ab5c 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/include/asm/smp.h b/arch/riscv/include/asm/smp.h index a83451d73a4e..023f74fb8b3b 100644 --- a/arch/riscv/include/asm/smp.h +++ b/arch/riscv/include/asm/smp.h @@ -61,5 +61,12 @@ static inline unsigned long cpuid_to_hartid_map(int cpu) return boot_cpu_hartid; } +static inline void riscv_cpuid_to_hartid_mask(const struct cpumask *in, + struct cpumask *out) +{ + cpumask_clear(out); + cpumask_set_cpu(boot_cpu_hartid, out); +} + #endif /* CONFIG_SMP */ #endif /* _ASM_RISCV_SMP_H */ diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c index 265637cb5eb0..3c34aba30f6f 100644 --- a/arch/riscv/kernel/sbi.c +++ b/arch/riscv/kernel/sbi.c @@ -8,6 +8,7 @@ #include #include #include +#include /* default SBI version is 0.1 */ unsigned long sbi_spec_version = SBI_SPEC_VERSION_DEFAULT; @@ -193,6 +194,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 +366,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 +511,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