From patchwork Mon Aug 3 17:58:41 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11698507 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 D16D613B6 for ; Mon, 3 Aug 2020 17:59:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id DBB7422BF3 for ; Mon, 3 Aug 2020 17:59:18 +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="ldIiBbwi" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728597AbgHCR7S (ORCPT ); Mon, 3 Aug 2020 13:59:18 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:64728 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726802AbgHCR7R (ORCPT ); Mon, 3 Aug 2020 13:59:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1596477556; x=1628013556; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=/WuBKKqQJ2DS9gLpxSbna82b/Rj8bNfTeDN1/MeY4to=; b=ldIiBbwi01R8GjOrznEfGRVF91p35hAR0FPw2lTYTs87y9JjAOW15NkB zfyVA7JENPYaSmcW78RjzjLvNySUBxiaOoM4ujX844OelayDqOVWeKNRl nPr5lo7oaRjyprQrTKhrxY/7xtnIMDL3N2vz+mh9bgdtEErFB8K1J5Do5 qynOt+d22XVMr72LyZrMnWXiMPcWGJaavLqI4IVG4aj8ATlMOVa8j79Es d6sH/IIeKr9QXm8iyiWxtNWxjiJjNSS1WFphXXwCxoJCJrbxbz0iAOxIP AI61/mvIhUHuWEbaOqow0NOVuHQpDndAmt/6SD2Pv9tylBY//Gv4SULXl w==; IronPort-SDR: hjvCoNLI7Qmdt/N/TBHIluW8PrnS1zVkC7z/tsj0dJ2B4JyjoyiVDlrc/9rm1P6iFo/UhOD0s1 gq81Aei+iE4DNGTNP6gdHw1g9ehNc48cB7Et9I4z4OgvxMqM8/OsIvd3QbX8DQRaegDuuhTlXu QsrP7VPZEQob2+xQuVB3gipO+jY8oY6uTWGeXSC8pe2h/8db0uSSqmt91UHK0yZyg7nUChEccY ObL2I/dAf5aKkZRDW97N6a9EfPnKwDB92V6JCM5bLwDBYdlG8ReMEx+lguWmqW00fkS8f2+Hrr nMs= X-IronPort-AV: E=Sophos;i="5.75,430,1589212800"; d="scan'208";a="144033181" 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; 04 Aug 2020 01:59:04 +0800 IronPort-SDR: 4VAC0m8TM8E3fJxPustvPVkRIyVs3DuwvS4bCPK7ne4qP583hDFvVWsO+RdpJnSZdbnFBoifzF u6y28LnvxXiw== 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; 03 Aug 2020 10:47:06 -0700 IronPort-SDR: b+L5ix2uhA5t3rcfUs2Aw7nrz9gwA9OaAzaqQxbJ4RQos5fVRvplQWg6A9RrXVtMjAiNbZUBpf aiMRiMpi9kvA== WDCIronportException: Internal Received: from cnf007830.ad.shared (HELO jedi-01.hgst.com) ([10.86.58.196]) by uls-op-cesaip01.wdc.com with ESMTP; 03 Aug 2020 10:59:03 -0700 From: Atish Patra To: kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Palmer Dabbelt , Paul Walmsley , Thomas Gleixner , Alexander Graf , Paolo Bonzini , Alistair Francis Subject: [PATCH 1/6] RISC-V: Add a non-void return for sbi v02 functions Date: Mon, 3 Aug 2020 10:58:41 -0700 Message-Id: <20200803175846.26272-2-atish.patra@wdc.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200803175846.26272-1-atish.patra@wdc.com> References: <20200803175846.26272-1-atish.patra@wdc.com> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org SBI v0.2 functions can return an error code from SBI implementation. We are already processing the SBI error code and coverts it to the Linux error code. Propagate to the error code to the caller as well. As of now, kvm is the only user of these error codes. Signed-off-by: Atish Patra --- arch/riscv/include/asm/sbi.h | 8 ++++---- arch/riscv/kernel/sbi.c | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 653edb25d495..2355515785eb 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -100,13 +100,13 @@ int sbi_console_getchar(void); void sbi_set_timer(uint64_t stime_value); void sbi_shutdown(void); void sbi_clear_ipi(void); -void sbi_send_ipi(const unsigned long *hart_mask); -void sbi_remote_fence_i(const unsigned long *hart_mask); -void sbi_remote_sfence_vma(const unsigned long *hart_mask, +int sbi_send_ipi(const unsigned long *hart_mask); +int sbi_remote_fence_i(const unsigned long *hart_mask); +int sbi_remote_sfence_vma(const unsigned long *hart_mask, unsigned long start, unsigned long size); -void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, +int sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start, unsigned long size, unsigned long asid); diff --git a/arch/riscv/kernel/sbi.c b/arch/riscv/kernel/sbi.c index f383ef5672b2..53c44c831eb8 100644 --- a/arch/riscv/kernel/sbi.c +++ b/arch/riscv/kernel/sbi.c @@ -351,7 +351,7 @@ static int __sbi_rfence_v02(int fid, const unsigned long *hart_mask, * sbi_set_timer() - Program the timer for next timer event. * @stime_value: The value after which next timer event should fire. * - * Return: None + * Return: None. */ void sbi_set_timer(uint64_t stime_value) { @@ -362,11 +362,11 @@ void sbi_set_timer(uint64_t stime_value) * sbi_send_ipi() - Send an IPI to any hart. * @hart_mask: A cpu mask containing all the target harts. * - * Return: None + * Return: 0 on success, appropriate linux error code otherwise. */ -void sbi_send_ipi(const unsigned long *hart_mask) +int sbi_send_ipi(const unsigned long *hart_mask) { - __sbi_send_ipi(hart_mask); + return __sbi_send_ipi(hart_mask); } EXPORT_SYMBOL(sbi_send_ipi); @@ -374,12 +374,12 @@ EXPORT_SYMBOL(sbi_send_ipi); * sbi_remote_fence_i() - Execute FENCE.I instruction on given remote harts. * @hart_mask: A cpu mask containing all the target harts. * - * Return: None + * Return: 0 on success, appropriate linux error code otherwise. */ -void sbi_remote_fence_i(const unsigned long *hart_mask) +int sbi_remote_fence_i(const unsigned long *hart_mask) { - __sbi_rfence(SBI_EXT_RFENCE_REMOTE_FENCE_I, - hart_mask, 0, 0, 0, 0); + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_FENCE_I, + hart_mask, 0, 0, 0, 0); } EXPORT_SYMBOL(sbi_remote_fence_i); @@ -390,14 +390,14 @@ EXPORT_SYMBOL(sbi_remote_fence_i); * @start: Start of the virtual address * @size: Total size of the virtual address range. * - * Return: None + * Return: 0 on success, appropriate linux error code otherwise. */ -void sbi_remote_sfence_vma(const unsigned long *hart_mask, +int sbi_remote_sfence_vma(const unsigned long *hart_mask, unsigned long start, unsigned long size) { - __sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, - hart_mask, start, size, 0, 0); + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA, + hart_mask, start, size, 0, 0); } EXPORT_SYMBOL(sbi_remote_sfence_vma); @@ -410,15 +410,15 @@ EXPORT_SYMBOL(sbi_remote_sfence_vma); * @size: Total size of the virtual address range. * @asid: The value of address space identifier (ASID). * - * Return: None + * Return: 0 on success, appropriate linux error code otherwise. */ -void sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, +int sbi_remote_sfence_vma_asid(const unsigned long *hart_mask, unsigned long start, unsigned long size, unsigned long asid) { - __sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, - hart_mask, start, size, asid, 0); + return __sbi_rfence(SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID, + hart_mask, start, size, asid, 0); } EXPORT_SYMBOL(sbi_remote_sfence_vma_asid); From patchwork Mon Aug 3 17:58:42 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11698521 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 8E09613B6 for ; Mon, 3 Aug 2020 17:59:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 97AF722BF3 for ; Mon, 3 Aug 2020 17:59:46 +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="kbi6L6J9" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728715AbgHCR7n (ORCPT ); Mon, 3 Aug 2020 13:59:43 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:64734 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726239AbgHCR7R (ORCPT ); Mon, 3 Aug 2020 13:59:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1596477556; x=1628013556; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=J48c9CMVcpNd9/xfvB5cFP78zFHASwu4Ms53OM3QH0Y=; b=kbi6L6J9zL2z/AZqje2r0rMXxa0PaBhGuhybFmfj52HpIFV3djQYR2EI jb++/oADn5uSTCsfmvD6WoW7dc0WgtIvj0lUTOGXCzwrdnDkcaaQRVzNY 0eVmIwx2LRBTaEflEaZBb2K222FRiyxh1aUYfIwebwoEWAJjwsZMKk2LC 9HOuoDlYULP7b0XN9ceeRY21vCs9eSNSqn+xIVOziknZ6/lDtebSCEd1I SFMh4uP7CNzZy1JNgZlFHINdQFOIm/NimpQH+QBnbZLRDWT/mzZfxWh5q anIAV0SSh9y1rL7SKVC9FyVkKWA5mYLMz7v3B6wbeUZbFDqoqfAJGmqnF g==; IronPort-SDR: Br0BDvhXcbuGDmlvE8NNjXkmaVtyR//lRzAIk6z68aBS3ZQBwicV8MziKf5aYGVSget7yoUeDC 9xaznXN4Jg/0PVDWeWmfxAa4k4h0pupQIAVUD7WbBkoC8LIa/U/KQU/mBHY1SiYv9Oq6NwCF5e ooG2T6Pg3lmjECpAxVgYpQj6DoYn+/PAZOO4+l7/N2oLVbRARzPnaTk0ZC2h6dn0tnhSa/7JX7 tEdZaNKP9Ysb+hBTJ3ZfMg2HeVfL0O/E+RS2vI+t3OmXfAgeqhpO5QI/BvP/PyqB+ohS53jG+T l+A= X-IronPort-AV: E=Sophos;i="5.75,430,1589212800"; d="scan'208";a="144033182" 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; 04 Aug 2020 01:59:05 +0800 IronPort-SDR: TdTh5uTFvg06Ef+hPbtksScCCiq7IUt63Ytj9DUTl+IbMPIeDI0Xyg+d/LimdP7vcSJSHvh0IS JXcSxebKFqrw== 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; 03 Aug 2020 10:47:07 -0700 IronPort-SDR: lAHSaJ05SBqBTitq+ZNgXJB5xXEHPGtl3dA5Q830eNmi8+17NBPwWKkm8VM9UzsSNe5a0n3P2k JpZVw/cFaEXg== WDCIronportException: Internal Received: from cnf007830.ad.shared (HELO jedi-01.hgst.com) ([10.86.58.196]) by uls-op-cesaip01.wdc.com with ESMTP; 03 Aug 2020 10:59:04 -0700 From: Atish Patra To: kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Palmer Dabbelt , Paul Walmsley , Thomas Gleixner , Alexander Graf , Paolo Bonzini , Alistair Francis Subject: [PATCH 2/6] RISC-V: Mark the existing SBI v0.1 implementation as legacy Date: Mon, 3 Aug 2020 10:58:42 -0700 Message-Id: <20200803175846.26272-3-atish.patra@wdc.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200803175846.26272-1-atish.patra@wdc.com> References: <20200803175846.26272-1-atish.patra@wdc.com> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The existing SBI specification impelementation follows v0.1 or legacy specification. The latest specification known as v0.2 allows more scalability and performance improvements. Rename the existing implementation as legacy and provide a way to allow future extensions. Signed-off-by: Atish Patra --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 29 +++++ arch/riscv/kvm/vcpu_sbi.c | 149 ++++++++++++++++++++------ 2 files changed, 148 insertions(+), 30 deletions(-) create mode 100644 arch/riscv/include/asm/kvm_vcpu_sbi.h diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h new file mode 100644 index 000000000000..5b3523a01bce --- /dev/null +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/** + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: + * Atish Patra + */ + +#ifndef __RISCV_KVM_VCPU_SBI_H__ +#define __RISCV_KVM_VCPU_SBI_H__ + +#define KVM_SBI_VERSION_MAJOR 0 +#define KVM_SBI_VERSION_MINOR 2 + +struct kvm_vcpu_sbi_extension { + unsigned long extid_start; + unsigned long extid_end; + /** + * SBI extension handler. It can be defined for a given extension or group of + * extension. But it should always return linux error codes rather than SBI + * specific error codes. + */ + int (*handler)(struct kvm_vcpu *vcpu, struct kvm_run *run, + unsigned long *out_val, struct kvm_cpu_trap *utrap, + bool *exit); +}; + +const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid); +#endif /* __RISCV_KVM_VCPU_SBI_H__ */ diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 9d1d25cf217f..efddac5362a9 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -12,9 +12,25 @@ #include #include #include +#include -#define SBI_VERSION_MAJOR 0 -#define SBI_VERSION_MINOR 1 +static int kvm_linux_err_map_sbi(int err) +{ + switch (err) { + case 0: + return SBI_SUCCESS; + case -EPERM: + return SBI_ERR_DENIED; + case -EINVAL: + return SBI_ERR_INVALID_PARAM; + case -EFAULT: + return SBI_ERR_INVALID_ADDRESS; + case -ENOTSUPP: + return SBI_ERR_NOT_SUPPORTED; + default: + return SBI_ERR_FAILURE; + }; +} static void kvm_sbi_system_shutdown(struct kvm_vcpu *vcpu, struct kvm_run *run, u32 type) @@ -70,16 +86,17 @@ int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run) return 0; } -int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) +static int kvm_sbi_ext_legacy_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + unsigned long *out_val, + struct kvm_cpu_trap *utrap, + bool *exit) { ulong hmask; - int i, ret = 1; + int i, ret = 0; u64 next_cycle; struct kvm_vcpu *rvcpu; - bool next_sepc = true; struct cpumask cm, hm; struct kvm *kvm = vcpu->kvm; - struct kvm_cpu_trap utrap = { 0 }; struct kvm_cpu_context *cp = &vcpu->arch.guest_context; if (!cp) @@ -93,8 +110,7 @@ int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) * handled in kernel so we forward these to user-space */ kvm_riscv_vcpu_sbi_forward(vcpu, run); - next_sepc = false; - ret = 0; + *exit = true; break; case SBI_EXT_0_1_SET_TIMER: #if __riscv_xlen == 32 @@ -102,47 +118,42 @@ int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) #else next_cycle = (u64)cp->a0; #endif - kvm_riscv_vcpu_timer_next_event(vcpu, next_cycle); + ret = kvm_riscv_vcpu_timer_next_event(vcpu, next_cycle); break; case SBI_EXT_0_1_CLEAR_IPI: - kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_SOFT); + ret = kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_SOFT); break; case SBI_EXT_0_1_SEND_IPI: if (cp->a0) hmask = kvm_riscv_vcpu_unpriv_read(vcpu, false, cp->a0, - &utrap); + utrap); else hmask = (1UL << atomic_read(&kvm->online_vcpus)) - 1; - if (utrap.scause) { - utrap.sepc = cp->sepc; - kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); - next_sepc = false; + if (utrap->scause) break; - } + for_each_set_bit(i, &hmask, BITS_PER_LONG) { rvcpu = kvm_get_vcpu_by_id(vcpu->kvm, i); - kvm_riscv_vcpu_set_interrupt(rvcpu, IRQ_VS_SOFT); + ret = kvm_riscv_vcpu_set_interrupt(rvcpu, IRQ_VS_SOFT); + if (ret < 0) + break; } break; case SBI_EXT_0_1_SHUTDOWN: kvm_sbi_system_shutdown(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN); - next_sepc = false; - ret = 0; + *exit = true; break; case SBI_EXT_0_1_REMOTE_FENCE_I: case SBI_EXT_0_1_REMOTE_SFENCE_VMA: case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID: if (cp->a0) hmask = kvm_riscv_vcpu_unpriv_read(vcpu, false, cp->a0, - &utrap); + utrap); else hmask = (1UL << atomic_read(&kvm->online_vcpus)) - 1; - if (utrap.scause) { - utrap.sepc = cp->sepc; - kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); - next_sepc = false; + if (utrap->scause) break; - } + cpumask_clear(&cm); for_each_set_bit(i, &hmask, BITS_PER_LONG) { rvcpu = kvm_get_vcpu_by_id(vcpu->kvm, i); @@ -152,22 +163,100 @@ int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) } riscv_cpuid_to_hartid_mask(&cm, &hm); if (cp->a7 == SBI_EXT_0_1_REMOTE_FENCE_I) - sbi_remote_fence_i(cpumask_bits(&hm)); + ret = sbi_remote_fence_i(cpumask_bits(&hm)); else if (cp->a7 == SBI_EXT_0_1_REMOTE_SFENCE_VMA) - sbi_remote_hfence_vvma(cpumask_bits(&hm), + ret = sbi_remote_hfence_vvma(cpumask_bits(&hm), cp->a1, cp->a2); else - sbi_remote_hfence_vvma_asid(cpumask_bits(&hm), + ret = sbi_remote_hfence_vvma_asid(cpumask_bits(&hm), cp->a1, cp->a2, cp->a3); break; default: - /* Return error for unsupported SBI calls */ - cp->a0 = SBI_ERR_NOT_SUPPORTED; + ret = -EINVAL; break; }; + return ret; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_legacy = { + .extid_start = SBI_EXT_0_1_SET_TIMER, + .extid_end = SBI_EXT_0_1_SHUTDOWN, + .handler = kvm_sbi_ext_legacy_handler, +}; + +static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { + &vcpu_sbi_ext_legacy, +}; + +const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid) +{ + int i = 0; + + for (i = 0; i < ARRAY_SIZE(sbi_ext); i++) { + if (sbi_ext[i]->extid_start <= extid && + sbi_ext[i]->extid_end >= extid) + return sbi_ext[i]; + } + + return NULL; +} + +int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) +{ + int ret = 1; + bool next_sepc = true; + bool userspace_exit = false; + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + const struct kvm_vcpu_sbi_extension *sbi_ext; + struct kvm_cpu_trap utrap = { 0 }; + unsigned long out_val = 0; + bool ext_is_v01 = false; + + if (!cp) + return -EINVAL; + + sbi_ext = kvm_vcpu_sbi_find_ext(cp->a7); + if (sbi_ext && sbi_ext->handler) { + if (cp->a7 >= SBI_EXT_0_1_SET_TIMER && + cp->a7 <= SBI_EXT_0_1_SHUTDOWN) + ext_is_v01 = true; + ret = sbi_ext->handler(vcpu, run, &out_val, &utrap, &userspace_exit); + } else { + /* Return error for unsupported SBI calls */ + cp->a0 = SBI_ERR_NOT_SUPPORTED; + goto ecall_done; + } + + /* Handle special error cases i.e trap, exit or userspace forward */ + if (utrap.scause) { + /* No need to increment sepc or exit ioctl loop */ + ret = 1; + utrap.sepc = cp->sepc; + kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); + next_sepc = false; + goto ecall_done; + } + + /* Exit ioctl loop or Propagate the error code the guest */ + if (userspace_exit) { + next_sepc = false; + ret = 0; + } else { + /** + * SBI extension handler always returns an Linux error code. Convert + * it to the SBI specific error code that can be propagated the SBI + * caller. + */ + ret = kvm_linux_err_map_sbi(ret); + cp->a0 = ret; + ret = 1; + } +ecall_done: if (next_sepc) cp->sepc += 4; + if (!ext_is_v01) + cp->a1 = out_val; return ret; } From patchwork Mon Aug 3 17:58:43 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11698511 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 5814C912 for ; Mon, 3 Aug 2020 17:59:27 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 61DEB22B45 for ; Mon, 3 Aug 2020 17:59:27 +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="RALJME09" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728622AbgHCR7T (ORCPT ); Mon, 3 Aug 2020 13:59:19 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:64728 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728588AbgHCR7S (ORCPT ); Mon, 3 Aug 2020 13:59:18 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1596477557; x=1628013557; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=cdgZA81qAts7J/fCdnfoWyqZdWwyvDZqQNei0eHBaQM=; b=RALJME09xHn0prPgHC8nZSPfvWgZcBfdSKKEE7kbzOgXa8LTS4MVMU1I GfpnvYFy/NbkK7A643AeYuYwi5NfSHGqNzS2muPLfRjTwdIk5S4zDEThF mQ+zFyl8sjkoBaoc51FksnGAgrpn6C6P8cIhYp+KdjjHP7nV17wa7SpL+ mqncjKj/g7EL3X4a0fA/TrlPrvXq+hmk+zsfUwQe32VYvgq62JV7ub46C 5TRbLl05phJFfQ9U6aWhAC3/+EWBuSqOz1jo8CPH+O+QIxlEirEHpWxq/ npuVOQ47J6Tq9OSGmWyOALqTop1PJTU7ECNJJnSvCjFMxm6GMcN7ajb0a g==; IronPort-SDR: CUPhC58WMESGeFnrxNohOeQDSstbF7KbiV/jg3PzjOtHzxBvXSkzVs8dtto2DyVByKb7YANeJp HEaf28wK9CxbxDrSh9Zo9uyYqeBlIh8yfDTe0VIdf9FWlwR2qiLH4G0my0F03E6eShiQ8AuEgS /r5cocZeWspetOHdC9jSZkySX3ifZBlf7rplPtnqRzArxOb7Ev5VOkA7I5Hz3QYqbf3rjnFm4V XQM090RpkIqQtj6kXHWLfYSfSXe9lPRKDWwpr0QWMK3HwT4viV7p/SrbGWRnBKSHGxRyJ60DBj mtg= X-IronPort-AV: E=Sophos;i="5.75,430,1589212800"; d="scan'208";a="144033183" 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; 04 Aug 2020 01:59:05 +0800 IronPort-SDR: 8run6bm5bt5S9kI9/4PGd6DpXv71XbhBSDgHz69cQxfKupFGyRJOOyLyTD4G6sK2hzzoOwwF6y NDAxKSbjgEnA== 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; 03 Aug 2020 10:47:07 -0700 IronPort-SDR: 1x2QuS0MR7qUV0C0wIlAdoyBvN9vLmVNMq5tUgACPwMS0Dp4oey0umX8iQzwMY64mB7zwtD+3B Hc3f8iBW1+0w== WDCIronportException: Internal Received: from cnf007830.ad.shared (HELO jedi-01.hgst.com) ([10.86.58.196]) by uls-op-cesaip01.wdc.com with ESMTP; 03 Aug 2020 10:59:05 -0700 From: Atish Patra To: kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Palmer Dabbelt , Paul Walmsley , Thomas Gleixner , Alexander Graf , Paolo Bonzini , Alistair Francis Subject: [PATCH 3/6] RISC-V: Reorganize SBI code by moving legacy SBI to its own file Date: Mon, 3 Aug 2020 10:58:43 -0700 Message-Id: <20200803175846.26272-4-atish.patra@wdc.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200803175846.26272-1-atish.patra@wdc.com> References: <20200803175846.26272-1-atish.patra@wdc.com> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org With SBI v0.2, there may be more SBI extensions in future. It makes more sense to group related extensions in separate files. Guest kernel will choose appropriate SBI version dynamically. Move the existing implementation to a separate file so that it can be removed in future without much conflict. Signed-off-by: Atish Patra --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 1 + arch/riscv/kvm/Makefile | 2 +- arch/riscv/kvm/vcpu_sbi.c | 126 +------------------------ arch/riscv/kvm/vcpu_sbi_legacy.c | 129 ++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 122 deletions(-) create mode 100644 arch/riscv/kvm/vcpu_sbi_legacy.c diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index 5b3523a01bce..743c71f0c331 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -25,5 +25,6 @@ struct kvm_vcpu_sbi_extension { bool *exit); }; +void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run); const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid); #endif /* __RISCV_KVM_VCPU_SBI_H__ */ diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile index b56dc1650d2c..8efb78faab5a 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -9,6 +9,6 @@ ccflags-y := -Ivirt/kvm -Iarch/riscv/kvm kvm-objs := $(common-objs-y) kvm-objs += main.o vm.o vmid.o tlb.o mmu.o -kvm-objs += vcpu.o vcpu_exit.o vcpu_switch.o vcpu_timer.o vcpu_sbi.o +kvm-objs += vcpu.o vcpu_exit.o vcpu_switch.o vcpu_timer.o vcpu_sbi.o vcpu_sbi_legacy.o obj-$(CONFIG_KVM) += kvm.o diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index efddac5362a9..85bb7491c0e0 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -9,9 +9,7 @@ #include #include #include -#include #include -#include #include static int kvm_linux_err_map_sbi(int err) @@ -32,23 +30,12 @@ static int kvm_linux_err_map_sbi(int err) }; } -static void kvm_sbi_system_shutdown(struct kvm_vcpu *vcpu, - struct kvm_run *run, u32 type) -{ - int i; - struct kvm_vcpu *tmp; - - kvm_for_each_vcpu(i, tmp, vcpu->kvm) - tmp->arch.power_off = true; - kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP); - - memset(&run->system_event, 0, sizeof(run->system_event)); - run->system_event.type = type; - run->exit_reason = KVM_EXIT_SYSTEM_EVENT; -} +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_legacy; +static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { + &vcpu_sbi_ext_legacy, +}; -static void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, - struct kvm_run *run) +void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct kvm_cpu_context *cp = &vcpu->arch.guest_context; @@ -86,109 +73,6 @@ int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run) return 0; } -static int kvm_sbi_ext_legacy_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, - unsigned long *out_val, - struct kvm_cpu_trap *utrap, - bool *exit) -{ - ulong hmask; - int i, ret = 0; - u64 next_cycle; - struct kvm_vcpu *rvcpu; - struct cpumask cm, hm; - struct kvm *kvm = vcpu->kvm; - struct kvm_cpu_context *cp = &vcpu->arch.guest_context; - - if (!cp) - return -EINVAL; - - switch (cp->a7) { - case SBI_EXT_0_1_CONSOLE_GETCHAR: - case SBI_EXT_0_1_CONSOLE_PUTCHAR: - /* - * The CONSOLE_GETCHAR/CONSOLE_PUTCHAR SBI calls cannot be - * handled in kernel so we forward these to user-space - */ - kvm_riscv_vcpu_sbi_forward(vcpu, run); - *exit = true; - break; - case SBI_EXT_0_1_SET_TIMER: -#if __riscv_xlen == 32 - next_cycle = ((u64)cp->a1 << 32) | (u64)cp->a0; -#else - next_cycle = (u64)cp->a0; -#endif - ret = kvm_riscv_vcpu_timer_next_event(vcpu, next_cycle); - break; - case SBI_EXT_0_1_CLEAR_IPI: - ret = kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_SOFT); - break; - case SBI_EXT_0_1_SEND_IPI: - if (cp->a0) - hmask = kvm_riscv_vcpu_unpriv_read(vcpu, false, cp->a0, - utrap); - else - hmask = (1UL << atomic_read(&kvm->online_vcpus)) - 1; - if (utrap->scause) - break; - - for_each_set_bit(i, &hmask, BITS_PER_LONG) { - rvcpu = kvm_get_vcpu_by_id(vcpu->kvm, i); - ret = kvm_riscv_vcpu_set_interrupt(rvcpu, IRQ_VS_SOFT); - if (ret < 0) - break; - } - break; - case SBI_EXT_0_1_SHUTDOWN: - kvm_sbi_system_shutdown(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN); - *exit = true; - break; - case SBI_EXT_0_1_REMOTE_FENCE_I: - case SBI_EXT_0_1_REMOTE_SFENCE_VMA: - case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID: - if (cp->a0) - hmask = kvm_riscv_vcpu_unpriv_read(vcpu, false, cp->a0, - utrap); - else - hmask = (1UL << atomic_read(&kvm->online_vcpus)) - 1; - if (utrap->scause) - break; - - cpumask_clear(&cm); - for_each_set_bit(i, &hmask, BITS_PER_LONG) { - rvcpu = kvm_get_vcpu_by_id(vcpu->kvm, i); - if (rvcpu->cpu < 0) - continue; - cpumask_set_cpu(rvcpu->cpu, &cm); - } - riscv_cpuid_to_hartid_mask(&cm, &hm); - if (cp->a7 == SBI_EXT_0_1_REMOTE_FENCE_I) - ret = sbi_remote_fence_i(cpumask_bits(&hm)); - else if (cp->a7 == SBI_EXT_0_1_REMOTE_SFENCE_VMA) - ret = sbi_remote_hfence_vvma(cpumask_bits(&hm), - cp->a1, cp->a2); - else - ret = sbi_remote_hfence_vvma_asid(cpumask_bits(&hm), - cp->a1, cp->a2, cp->a3); - break; - default: - ret = -EINVAL; - break; - }; - - return ret; -} - -const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_legacy = { - .extid_start = SBI_EXT_0_1_SET_TIMER, - .extid_end = SBI_EXT_0_1_SHUTDOWN, - .handler = kvm_sbi_ext_legacy_handler, -}; - -static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { - &vcpu_sbi_ext_legacy, -}; - const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid) { int i = 0; diff --git a/arch/riscv/kvm/vcpu_sbi_legacy.c b/arch/riscv/kvm/vcpu_sbi_legacy.c new file mode 100644 index 000000000000..126d97b1292d --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_legacy.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: + * Atish Patra + */ + +#include +#include +#include +#include +#include +#include +#include + +static void kvm_sbi_system_shutdown(struct kvm_vcpu *vcpu, + struct kvm_run *run, u32 type) +{ + int i; + struct kvm_vcpu *tmp; + + kvm_for_each_vcpu(i, tmp, vcpu->kvm) + tmp->arch.power_off = true; + kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_SLEEP); + + memset(&run->system_event, 0, sizeof(run->system_event)); + run->system_event.type = type; + run->exit_reason = KVM_EXIT_SYSTEM_EVENT; +} + +static int kvm_sbi_ext_legacy_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + unsigned long *out_val, + struct kvm_cpu_trap *utrap, + bool *exit) +{ + ulong hmask; + int i, ret = 0; + u64 next_cycle; + struct kvm_vcpu *rvcpu; + struct cpumask cm, hm; + struct kvm *kvm = vcpu->kvm; + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + + if (!cp) + return -EINVAL; + + switch (cp->a7) { + case SBI_EXT_0_1_CONSOLE_GETCHAR: + case SBI_EXT_0_1_CONSOLE_PUTCHAR: + /* + * The CONSOLE_GETCHAR/CONSOLE_PUTCHAR SBI calls cannot be + * handled in kernel so we forward these to user-space + */ + kvm_riscv_vcpu_sbi_forward(vcpu, run); + *exit = true; + break; + case SBI_EXT_0_1_SET_TIMER: +#if __riscv_xlen == 32 + next_cycle = ((u64)cp->a1 << 32) | (u64)cp->a0; +#else + next_cycle = (u64)cp->a0; +#endif + ret = kvm_riscv_vcpu_timer_next_event(vcpu, next_cycle); + break; + case SBI_EXT_0_1_CLEAR_IPI: + ret = kvm_riscv_vcpu_unset_interrupt(vcpu, IRQ_VS_SOFT); + break; + case SBI_EXT_0_1_SEND_IPI: + if (cp->a0) + hmask = kvm_riscv_vcpu_unpriv_read(vcpu, false, cp->a0, + utrap); + else + hmask = (1UL << atomic_read(&kvm->online_vcpus)) - 1; + if (utrap->scause) + break; + + for_each_set_bit(i, &hmask, BITS_PER_LONG) { + rvcpu = kvm_get_vcpu_by_id(vcpu->kvm, i); + ret = kvm_riscv_vcpu_set_interrupt(rvcpu, IRQ_VS_SOFT); + if (ret < 0) + break; + } + break; + case SBI_EXT_0_1_SHUTDOWN: + kvm_sbi_system_shutdown(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN); + *exit = true; + break; + case SBI_EXT_0_1_REMOTE_FENCE_I: + case SBI_EXT_0_1_REMOTE_SFENCE_VMA: + case SBI_EXT_0_1_REMOTE_SFENCE_VMA_ASID: + if (cp->a0) + hmask = kvm_riscv_vcpu_unpriv_read(vcpu, false, cp->a0, + utrap); + else + hmask = (1UL << atomic_read(&kvm->online_vcpus)) - 1; + if (utrap->scause) + break; + + cpumask_clear(&cm); + for_each_set_bit(i, &hmask, BITS_PER_LONG) { + rvcpu = kvm_get_vcpu_by_id(vcpu->kvm, i); + if (rvcpu->cpu < 0) + continue; + cpumask_set_cpu(rvcpu->cpu, &cm); + } + riscv_cpuid_to_hartid_mask(&cm, &hm); + if (cp->a7 == SBI_EXT_0_1_REMOTE_FENCE_I) + ret = sbi_remote_fence_i(cpumask_bits(&hm)); + else if (cp->a7 == SBI_EXT_0_1_REMOTE_SFENCE_VMA) + ret = sbi_remote_hfence_vvma(cpumask_bits(&hm), + cp->a1, cp->a2); + else + ret = sbi_remote_hfence_vvma_asid(cpumask_bits(&hm), + cp->a1, cp->a2, cp->a3); + break; + default: + ret = -EINVAL; + break; + }; + + return ret; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_legacy = { + .extid_start = SBI_EXT_0_1_SET_TIMER, + .extid_end = SBI_EXT_0_1_SHUTDOWN, + .handler = kvm_sbi_ext_legacy_handler, +}; From patchwork Mon Aug 3 17:58:44 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11698515 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 6DD74912 for ; Mon, 3 Aug 2020 17:59:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7CC1822B4E for ; Mon, 3 Aug 2020 17:59:39 +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="DDS/iYyO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728695AbgHCR7f (ORCPT ); Mon, 3 Aug 2020 13:59:35 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:64734 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728606AbgHCR7T (ORCPT ); Mon, 3 Aug 2020 13:59:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1596477558; x=1628013558; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=qPmtegxxbSB9RTlj4BBlMzdfmESXwNOsCOxFYG1zCtU=; b=DDS/iYyOzQGyLaJo9TjRmDvPqerGZWY2CrwCIkGsyqHqlWXyjEKEIur8 v1yuI1DGkCOHoAUMXzKbIbJmddowhVvLCxrL4kuBGpd+fXyJskB43RS0O eIt+87lNJ/xhbGFKnYArEw5LmiDEKIiYsQAtsWZuDI6DSKqCK2pkEoF78 ZNQzv8XO29qbmalCT2b2cnmuMnKk+7wVfcX79cTVDEbrOFKkjdMM7M5Ay z9BMPjuVRkM8Ewe5zEzVCgxQ5eWIU/uHfiAZiPe931olzG6r7w6Cup6rB GUVH1X7hYAZclmDsnAoh6sTOaEYwvAWMwQ5XgfvyURZZj/PMf2wY6gLVO g==; IronPort-SDR: 6iPYMzoH1Jh8d+/5u8yW8wzoLmyL76h/dSESfQkOARKf6OrXVbEjeKMvS/yNLwJ1FVxYutIzNZ zlY1m1pyx5AnDwjDvVgt1IJXov0XI1Yd6XYMmv/6R7XFIUze5njBBnThvDrkBkawMdMPV28ZC+ kZ7EisT/IMNEjWBMFWcgY207/g4bamUABHiHl4uhTboYe38LfjbZ5ywPksDGABfhnNARF9ZhpO ZrRT80UZyw5sShg4CLNMf04ZT1LckE213jZmkM/E7LRIS5Ew/pdtKhh11hYTpMQc1TmzlyWf0A Uww= X-IronPort-AV: E=Sophos;i="5.75,430,1589212800"; d="scan'208";a="144033184" 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; 04 Aug 2020 01:59:06 +0800 IronPort-SDR: C5ZawVlqjA8Q14PscUal99ZcGUk7D/5xHy97TELczxeytcZjngeTw7FAZy6i4Wf3EhLxthrZ8d WVTwCaPGawIg== 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; 03 Aug 2020 10:47:08 -0700 IronPort-SDR: UhN4Hz3RhIS2TGFKWzyLUGEL5Rl/ZPk/mOR0AYzlA2gP8UjJrOWPq+7kvyHh2CZEt0zFX4mrMY 0V9dAC21SUMA== WDCIronportException: Internal Received: from cnf007830.ad.shared (HELO jedi-01.hgst.com) ([10.86.58.196]) by uls-op-cesaip01.wdc.com with ESMTP; 03 Aug 2020 10:59:05 -0700 From: Atish Patra To: kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Palmer Dabbelt , Paul Walmsley , Thomas Gleixner , Alexander Graf , Paolo Bonzini , Alistair Francis Subject: [PATCH 4/6] RISC-V: Add SBI v0.2 base extension Date: Mon, 3 Aug 2020 10:58:44 -0700 Message-Id: <20200803175846.26272-5-atish.patra@wdc.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200803175846.26272-1-atish.patra@wdc.com> References: <20200803175846.26272-1-atish.patra@wdc.com> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org SBI v0.2 base extension defined to allow backward compatibility and probing of future extensions. This is also the only mandatory SBI extension that must be implemented by SBI implementors. Signed-off-by: Atish Patra --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 2 + arch/riscv/include/asm/sbi.h | 8 +++ arch/riscv/kvm/Makefile | 4 +- arch/riscv/kvm/vcpu_sbi.c | 3 ++ arch/riscv/kvm/vcpu_sbi_base.c | 73 +++++++++++++++++++++++++++ 5 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 arch/riscv/kvm/vcpu_sbi_base.c diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index 743c71f0c331..e208c8ac57fe 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -9,6 +9,8 @@ #ifndef __RISCV_KVM_VCPU_SBI_H__ #define __RISCV_KVM_VCPU_SBI_H__ +#define KVM_SBI_IMPID 3 + #define KVM_SBI_VERSION_MAJOR 0 #define KVM_SBI_VERSION_MINOR 2 diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 2355515785eb..7d8f2b389253 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -27,6 +27,14 @@ enum sbi_ext_id { SBI_EXT_IPI = 0x735049, SBI_EXT_RFENCE = 0x52464E43, SBI_EXT_HSM = 0x48534D, + + /* Experimentals extensions must lie within this range */ + SBI_EXT_EXPERIMENTAL_START = 0x0800000, + SBI_EXT_EXPERIMENTAL_END = 0x08FFFFFF, + + /* Vendor extensions must lie within this range */ + SBI_EXT_VENDOR_START = 0x09000000, + SBI_EXT_VENDOR_END = 0x09FFFFFF, }; enum sbi_ext_base_fid { diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile index 8efb78faab5a..a95c91ba9a51 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -9,6 +9,6 @@ ccflags-y := -Ivirt/kvm -Iarch/riscv/kvm kvm-objs := $(common-objs-y) kvm-objs += main.o vm.o vmid.o tlb.o mmu.o -kvm-objs += vcpu.o vcpu_exit.o vcpu_switch.o vcpu_timer.o vcpu_sbi.o vcpu_sbi_legacy.o - +kvm-objs += vcpu.o vcpu_exit.o vcpu_switch.o vcpu_timer.o +kvm-objs += vcpu_sbi.o vcpu_sbi_base.o vcpu_sbi_legacy.o obj-$(CONFIG_KVM) += kvm.o diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 85bb7491c0e0..bb50d63f78e7 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -31,8 +31,11 @@ static int kvm_linux_err_map_sbi(int err) } extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_legacy; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base; + static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { &vcpu_sbi_ext_legacy, + &vcpu_sbi_ext_base, }; void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) diff --git a/arch/riscv/kvm/vcpu_sbi_base.c b/arch/riscv/kvm/vcpu_sbi_base.c new file mode 100644 index 000000000000..025d0eae50b0 --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_base.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: + * Atish Patra + */ + +#include +#include +#include +#include +#include +#include +#include + +static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + unsigned long *out_val, + struct kvm_cpu_trap *trap, bool *exit) +{ + int ret = 0; + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + struct sbiret ecall_ret; + + if (!cp) + return -EINVAL; + + switch (cp->a6) { + case SBI_EXT_BASE_GET_SPEC_VERSION: + *out_val = (KVM_SBI_VERSION_MAJOR << + SBI_SPEC_VERSION_MAJOR_SHIFT) | + KVM_SBI_VERSION_MINOR; + break; + case SBI_EXT_BASE_GET_IMP_ID: + *out_val = KVM_SBI_IMPID; + break; + case SBI_EXT_BASE_GET_IMP_VERSION: + *out_val = 0; + break; + case SBI_EXT_BASE_PROBE_EXT: + *out_val = kvm_vcpu_sbi_find_ext(cp->a0) ? 1 : 0; + if ((!*out_val) && + ((cp->a0 >= SBI_EXT_EXPERIMENTAL_START && + cp->a0 <= SBI_EXT_EXPERIMENTAL_END) || + ((cp->a0 >= SBI_EXT_VENDOR_START && + cp->a0 <= SBI_EXT_VENDOR_END)))) { + /* For experimental/vendor extensions forward to the userspace*/ + kvm_riscv_vcpu_sbi_forward(vcpu, run); + *exit = true; + } + break; + case SBI_EXT_BASE_GET_MVENDORID: + case SBI_EXT_BASE_GET_MARCHID: + case SBI_EXT_BASE_GET_MIMPID: + ecall_ret = sbi_ecall(SBI_EXT_BASE, cp->a6, 0, 0, 0, 0, 0, 0); + if (!ecall_ret.error) + *out_val = ecall_ret.value; + /*TODO: We are unnecessarily converting the error twice */ + ret = sbi_err_map_linux_errno(ecall_ret.error); + break; + default: + ret = -ENOTSUPP; + break; + } + + return ret; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base = { + .extid_start = SBI_EXT_BASE, + .extid_end = SBI_EXT_BASE, + .handler = kvm_sbi_ext_base_handler, +}; From patchwork Mon Aug 3 17:58:45 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11698513 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 1FE24912 for ; Mon, 3 Aug 2020 17:59:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 28E8622B4E for ; Mon, 3 Aug 2020 17:59:31 +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="bB41/+VY" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728678AbgHCR73 (ORCPT ); Mon, 3 Aug 2020 13:59:29 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:64741 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728607AbgHCR7T (ORCPT ); Mon, 3 Aug 2020 13:59:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1596477558; x=1628013558; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=jU9YUiaLBL5uWBVTinVot5g73YeyDZgqDfT7h5RHaK0=; b=bB41/+VYlAhY6QYPsGv8Lih0Nfa8fRs5wlSpjJg4exCRaBRKnNw+JfVy OAAQOD0ov0Vg17efpQm3QMa377zFfq200VpJqOra6vumDbQwLpOvQuXC1 FQlI6vUTaT+h4T/CvtZSYInRXwZ3Th4AUK37TbSNa+WS2qvbE8kYzaATc D5IKBMtCdBUYIEX3Oo8R8v8Vhy6dFcJJTheTLboA3B1At5K0v5ZHuwY85 KtJXeAZlfaIrm+pN0p+EDRwQrcZV9GcGDsfDsQNMiTmrNbF8HL0H35HL2 S3MXw/eUofUKu1C1ZUJJ2AryUnEtjJoelJfiFn1EjLip66dArUcQ9yKlQ w==; IronPort-SDR: 5XKXjpNL9kHDPWXk+ikxoV2mA3uZNPUPUJp/zYuO4gE4PesyUqIzGIdTIYfAhwciqL0K6jKUWV rudlMUJbiSuOw5mIA/8LB16kuvz2Po6yjBra97rKMqD1wD2oFKVIzsSATb7+o3q/mFP78JfyBW 1pw/PgTH6mWIW7b9cUrS+OcYJSuvJz6vlTvbFfs8mzwjyQE/LtpCqDejpBMmsG/TBBmu1VnAAn Yo1e56cJ1aQ7dBr29uyW35+XlgkhyYxo0SxP+tuYcEIu51AyeGTB3nx2gqskyaVrCWS9ApQyLc Bpc= X-IronPort-AV: E=Sophos;i="5.75,430,1589212800"; d="scan'208";a="144033187" 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; 04 Aug 2020 01:59:06 +0800 IronPort-SDR: C655FkzNbXDHtYLNB0Aj1hPKjL7wMjSVCkyDioz6yPM1a3Zp33zNO+LKObGAuOq2Mn/CGiL48U y8c7pDHZprtg== 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; 03 Aug 2020 10:47:08 -0700 IronPort-SDR: UG53wW/fsc7pTLfYnTrWL5HIO4RpvYc7yZ62ccSKI1De9f1BmKIPMtdK31OiH8/TfRKOylDfwP Pacm67hl6K2A== WDCIronportException: Internal Received: from cnf007830.ad.shared (HELO jedi-01.hgst.com) ([10.86.58.196]) by uls-op-cesaip01.wdc.com with ESMTP; 03 Aug 2020 10:59:06 -0700 From: Atish Patra To: kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Palmer Dabbelt , Paul Walmsley , Thomas Gleixner , Alexander Graf , Paolo Bonzini , Alistair Francis Subject: [PATCH 5/6] RISC-V: Add v0.1 replacement SBI extensions defined in v02 Date: Mon, 3 Aug 2020 10:58:45 -0700 Message-Id: <20200803175846.26272-6-atish.patra@wdc.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200803175846.26272-1-atish.patra@wdc.com> References: <20200803175846.26272-1-atish.patra@wdc.com> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The SBI v0.2 contains some of the improved versions of required v0.1 extensions such as remote fence, timer and IPI. This patch implements those extensions. Signed-off-by: Atish Patra --- arch/riscv/kvm/Makefile | 2 +- arch/riscv/kvm/vcpu_sbi.c | 6 ++ arch/riscv/kvm/vcpu_sbi_replace.c | 136 ++++++++++++++++++++++++++++++ 3 files changed, 143 insertions(+), 1 deletion(-) create mode 100644 arch/riscv/kvm/vcpu_sbi_replace.c diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile index a95c91ba9a51..b0e8b760fda0 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -10,5 +10,5 @@ kvm-objs := $(common-objs-y) kvm-objs += main.o vm.o vmid.o tlb.o mmu.o kvm-objs += vcpu.o vcpu_exit.o vcpu_switch.o vcpu_timer.o -kvm-objs += vcpu_sbi.o vcpu_sbi_base.o vcpu_sbi_legacy.o +kvm-objs += vcpu_sbi.o vcpu_sbi_base.o vcpu_sbi_legacy.o vcpu_sbi_replace.o obj-$(CONFIG_KVM) += kvm.o diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index bb50d63f78e7..8c3ca522dddb 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -32,10 +32,16 @@ static int kvm_linux_err_map_sbi(int err) extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_legacy; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence; static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { &vcpu_sbi_ext_legacy, &vcpu_sbi_ext_base, + &vcpu_sbi_ext_time, + &vcpu_sbi_ext_ipi, + &vcpu_sbi_ext_rfence, }; void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c new file mode 100644 index 000000000000..8e6b57fc1622 --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_replace.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: + * Atish Patra + */ + +#include +#include +#include +#include +#include +#include +#include + +static int kvm_sbi_ext_time_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + unsigned long *out_val, + struct kvm_cpu_trap *utrap, bool *exit) +{ + int ret = 0; + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + u64 next_cycle; + + if (!cp || (cp->a6 != SBI_EXT_TIME_SET_TIMER)) + return -EINVAL; + +#if __riscv_xlen == 32 + next_cycle = ((u64)cp->a1 << 32) | (u64)cp->a0; +#else + next_cycle = (u64)cp->a0; +#endif + kvm_riscv_vcpu_timer_next_event(vcpu, next_cycle); + + return ret; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time = { + .extid_start = SBI_EXT_TIME, + .extid_end = SBI_EXT_TIME, + .handler = kvm_sbi_ext_time_handler, +}; + +static int kvm_sbi_ext_ipi_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + unsigned long *out_val, + struct kvm_cpu_trap *utrap, bool *exit) +{ + int i, ret = 0; + struct kvm_vcpu *tmp; + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + unsigned long hmask = cp->a0; + unsigned long hbase = cp->a1; + + if (!cp || (cp->a6 != SBI_EXT_IPI_SEND_IPI)) + return -EINVAL; + + kvm_for_each_vcpu(i, tmp, vcpu->kvm) { + if (hbase != -1UL) { + if (tmp->vcpu_id < hbase) + continue; + if (!(hmask & (1UL << (tmp->vcpu_id - hbase)))) + continue; + } + ret = kvm_riscv_vcpu_set_interrupt(tmp, IRQ_VS_SOFT); + if (ret < 0) + break; + } + + return ret; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi = { + .extid_start = SBI_EXT_IPI, + .extid_end = SBI_EXT_IPI, + .handler = kvm_sbi_ext_ipi_handler, +}; + +static int kvm_sbi_ext_rfence_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + unsigned long *out_val, + struct kvm_cpu_trap *utrap, bool *exit) +{ + int i, ret = 0; + struct cpumask cm, hm; + struct kvm_vcpu *tmp; + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + unsigned long hmask = cp->a0; + unsigned long hbase = cp->a1; + unsigned long funcid = cp->a6; + + if (!cp) + return -EINVAL; + + cpumask_clear(&cm); + cpumask_clear(&hm); + kvm_for_each_vcpu(i, tmp, vcpu->kvm) { + if (hbase != -1UL) { + if (tmp->vcpu_id < hbase) + continue; + if (!(hmask & (1UL << (tmp->vcpu_id - hbase)))) + continue; + } + if (tmp->cpu < 0) + continue; + cpumask_set_cpu(tmp->cpu, &cm); + } + + riscv_cpuid_to_hartid_mask(&cm, &hm); + + switch (funcid) { + case SBI_EXT_RFENCE_REMOTE_FENCE_I: + ret = sbi_remote_fence_i(cpumask_bits(&hm)); + break; + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA: + ret = sbi_remote_hfence_vvma(cpumask_bits(&hm), cp->a2, cp->a3); + break; + case SBI_EXT_RFENCE_REMOTE_SFENCE_VMA_ASID: + ret = sbi_remote_hfence_vvma_asid(cpumask_bits(&hm), cp->a2, + cp->a3, cp->a4); + break; + case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA: + case SBI_EXT_RFENCE_REMOTE_HFENCE_GVMA_VMID: + case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA: + case SBI_EXT_RFENCE_REMOTE_HFENCE_VVMA_ASID: + /* TODO: implement for nested hypervisor case */ + default: + ret = -ENOTSUPP; + } + + return ret; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence = { + .extid_start = SBI_EXT_RFENCE, + .extid_end = SBI_EXT_RFENCE, + .handler = kvm_sbi_ext_rfence_handler, +}; From patchwork Mon Aug 3 17:58:46 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 11698509 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 928CA912 for ; Mon, 3 Aug 2020 17:59:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9C89522CE3 for ; Mon, 3 Aug 2020 17:59:25 +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="S7yypu5q" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728661AbgHCR7V (ORCPT ); Mon, 3 Aug 2020 13:59:21 -0400 Received: from esa4.hgst.iphmx.com ([216.71.154.42]:64728 "EHLO esa4.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728608AbgHCR7T (ORCPT ); Mon, 3 Aug 2020 13:59:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1596477558; x=1628013558; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=NetUIh98Lh3twSMeBSYk+d3Kbtv98SHWIpPw/siizNE=; b=S7yypu5q1Wtpc75cy4bwS33Q+5olIS9R4ifCrS76bwq0yzjf99T2kxBC LN9h9Pu92Ao7DPgPYdttRATZSyIK0KzK31oG6d9imbwK9RTldBOejahAh XXP12SlgR/pxXJ3JqO9eGHTcmZRt5eiz+CaHye7xqPQE4px/1OBkZA7Cm DzgSGQncYjPdCF8exUJtipn3VWHbsBfPVZXHOGFbCmJpmtQQFVZrXHtNX T2gbyCJgRuMXlvadlt2Pk3Bbdf7OnmHX/EjGWYKz4EHfwIuwlGf0jMIM0 e847KDgbSeOKdSXG2LKu6wQJJJeiAUNvSTPE393cJ2ka9XTRlpp7kpWFn Q==; IronPort-SDR: +cqPQVBLj0cY/M+eu7sZSydhwKwiUKRfWmyzSzyt6uaYe9NHeIvadLQbiCHi2F8jK2ROe6cEE1 syD1UPkRxjr+CXXRw3rCnA+zYVCyW0Kit26vb5ILmu46d949NyURo8L01dtDzGUQiQKkHagXYP 0VQTiYJSFBWIkxHLSThPWlPqr3OdbBJfE5MCDXkKDu+ClYRE9nnBZ72sK6mUELbGMLoVw787Ln SIzeWgdzEwbzZp+lfmajmlrVs/NNvWDF5guvpmG07gn8I/QqxfhuSmsjsKIGkKZojo63sK620O /J8= X-IronPort-AV: E=Sophos;i="5.75,430,1589212800"; d="scan'208";a="144033188" 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; 04 Aug 2020 01:59:07 +0800 IronPort-SDR: Ad2+ucYIEEFTnT7EL0k2nG8uTHgHswcGGSc+Fk+RUl0MuwKKqVFXji4ld/2XMaI2FzebZO7wPC TtEOH2PcKFsA== 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; 03 Aug 2020 10:47:09 -0700 IronPort-SDR: 7X+6upqgL4IKeTt7Dwe+wA4Ydqh+2t9rQWgGRVP6Oub5IbMwTdcLxybcvMUXZQzYh6OcQ00nD+ oAvQYMf10Thw== WDCIronportException: Internal Received: from cnf007830.ad.shared (HELO jedi-01.hgst.com) ([10.86.58.196]) by uls-op-cesaip01.wdc.com with ESMTP; 03 Aug 2020 10:59:06 -0700 From: Atish Patra To: kvm-riscv@lists.infradead.org, linux-riscv@lists.infradead.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Palmer Dabbelt , Paul Walmsley , Thomas Gleixner , Alexander Graf , Paolo Bonzini , Alistair Francis Subject: [PATCH 6/6] RISC-V: Add SBI HSM extension in KVM Date: Mon, 3 Aug 2020 10:58:46 -0700 Message-Id: <20200803175846.26272-7-atish.patra@wdc.com> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20200803175846.26272-1-atish.patra@wdc.com> References: <20200803175846.26272-1-atish.patra@wdc.com> MIME-Version: 1.0 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org SBI HSM extension allows OS to start/stop harts any time. It also allows ordered booting of harts instead of random booting. Implement SBI HSM exntesion and designate the vcpu 0 as the boot vcpu id. All other non-zero non-booting vcpus should be brought up by the OS implementing HSM extension. If the guest OS doesn't implement HSM extension, only single vcpu will be available to OS. Signed-off-by: Atish Patra --- arch/riscv/include/asm/sbi.h | 1 + arch/riscv/kvm/Makefile | 2 +- arch/riscv/kvm/vcpu.c | 19 ++++++ arch/riscv/kvm/vcpu_sbi.c | 4 ++ arch/riscv/kvm/vcpu_sbi_hsm.c | 109 ++++++++++++++++++++++++++++++++++ 5 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 arch/riscv/kvm/vcpu_sbi_hsm.c diff --git a/arch/riscv/include/asm/sbi.h b/arch/riscv/include/asm/sbi.h index 7d8f2b389253..e18ba15fc9e1 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -90,6 +90,7 @@ enum sbi_hsm_hart_status { #define SBI_ERR_INVALID_PARAM -3 #define SBI_ERR_DENIED -4 #define SBI_ERR_INVALID_ADDRESS -5 +#define SBI_ERR_ALREADY_AVAILABLE -6 extern unsigned long sbi_spec_version; struct sbiret { diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile index b0e8b760fda0..5c3c40636067 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -10,5 +10,5 @@ kvm-objs := $(common-objs-y) kvm-objs += main.o vm.o vmid.o tlb.o mmu.o kvm-objs += vcpu.o vcpu_exit.o vcpu_switch.o vcpu_timer.o -kvm-objs += vcpu_sbi.o vcpu_sbi_base.o vcpu_sbi_legacy.o vcpu_sbi_replace.o +kvm-objs += vcpu_sbi.o vcpu_sbi_base.o vcpu_sbi_legacy.o vcpu_sbi_replace.o vcpu_sbi_hsm.o obj-$(CONFIG_KVM) += kvm.o diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index adb0815951aa..f921d7771f40 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -130,6 +130,13 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu) struct kvm_vcpu_csr *reset_csr = &vcpu->arch.guest_reset_csr; struct kvm_cpu_context *cntx = &vcpu->arch.guest_context; struct kvm_cpu_context *reset_cntx = &vcpu->arch.guest_reset_context; + bool loaded; + + /* Disable preemption to avoid race with preempt notifiers */ + preempt_disable(); + loaded = (vcpu->cpu != -1); + if (loaded) + kvm_arch_vcpu_put(vcpu); memcpy(csr, reset_csr, sizeof(*csr)); @@ -141,6 +148,11 @@ static void kvm_riscv_reset_vcpu(struct kvm_vcpu *vcpu) WRITE_ONCE(vcpu->arch.irqs_pending, 0); WRITE_ONCE(vcpu->arch.irqs_pending_mask, 0); + + /* Reset the guest CSRs for hotplug usecase */ + if (loaded) + kvm_arch_vcpu_load(vcpu, smp_processor_id()); + preempt_enable(); } int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id) @@ -182,6 +194,13 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu) void kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) { + /** + * vcpu with id 0 is the designated boot cpu. + * Keep all vcpus with non-zero cpu id in power-off state so that they + * can brought to online using SBI HSM extension. + */ + if (vcpu->vcpu_idx != 0) + kvm_riscv_vcpu_power_off(vcpu); } void kvm_arch_vcpu_destroy(struct kvm_vcpu *vcpu) diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 8c3ca522dddb..2f59b56d8640 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -25,6 +25,8 @@ static int kvm_linux_err_map_sbi(int err) return SBI_ERR_INVALID_ADDRESS; case -ENOTSUPP: return SBI_ERR_NOT_SUPPORTED; + case -EALREADY: + return SBI_ERR_ALREADY_AVAILABLE; default: return SBI_ERR_FAILURE; }; @@ -35,6 +37,7 @@ extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_time; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_ipi; extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm; static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { &vcpu_sbi_ext_legacy, @@ -42,6 +45,7 @@ static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { &vcpu_sbi_ext_time, &vcpu_sbi_ext_ipi, &vcpu_sbi_ext_rfence, + &vcpu_sbi_ext_hsm, }; void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) diff --git a/arch/riscv/kvm/vcpu_sbi_hsm.c b/arch/riscv/kvm/vcpu_sbi_hsm.c new file mode 100644 index 000000000000..f8ab64f5f344 --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_hsm.c @@ -0,0 +1,109 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * Copyright (c) 2020 Western Digital Corporation or its affiliates. + * + * Authors: + * Atish Patra + */ + +#include +#include +#include +#include +#include +#include + +static int kvm_sbi_hsm_vcpu_start(struct kvm_vcpu *vcpu) +{ + struct kvm_cpu_context *reset_cntx; + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + struct kvm_vcpu *target_vcpu; + unsigned long target_vcpuid = cp->a0; + + target_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, target_vcpuid); + if (!target_vcpu) + return -EINVAL; + if (!target_vcpu->arch.power_off) + return -EALREADY; + + reset_cntx = &target_vcpu->arch.guest_reset_context; + /* start address */ + reset_cntx->sepc = cp->a1; + /* target vcpu id to start */ + reset_cntx->a0 = target_vcpuid; + /* private data passed from kernel */ + reset_cntx->a1 = cp->a2; + kvm_make_request(KVM_REQ_VCPU_RESET, target_vcpu); + + /* Make sure that the reset request is enqueued before power on */ + smp_wmb(); + kvm_riscv_vcpu_power_on(target_vcpu); + + return 0; +} + +static int kvm_sbi_hsm_vcpu_stop(struct kvm_vcpu *vcpu) +{ + if ((!vcpu) || (vcpu->arch.power_off)) + return -EINVAL; + + kvm_riscv_vcpu_power_off(vcpu); + + return 0; +} + +static int kvm_sbi_hsm_vcpu_get_status(struct kvm_vcpu *vcpu) +{ + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + unsigned long target_vcpuid = cp->a0; + struct kvm_vcpu *target_vcpu; + + target_vcpu = kvm_get_vcpu_by_id(vcpu->kvm, target_vcpuid); + if (!target_vcpu) + return -EINVAL; + if (!target_vcpu->arch.power_off) + return SBI_HSM_HART_STATUS_STARTED; + else + return SBI_HSM_HART_STATUS_STOPPED; +} + +static int kvm_sbi_ext_hsm_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, + unsigned long *out_val, + struct kvm_cpu_trap *utrap, + bool *exit) +{ + int ret = 0; + struct kvm_cpu_context *cp = &vcpu->arch.guest_context; + struct kvm *kvm = vcpu->kvm; + unsigned long funcid = cp->a6; + + if (!cp) + return -EINVAL; + switch (funcid) { + case SBI_EXT_HSM_HART_START: + mutex_lock(&kvm->lock); + ret = kvm_sbi_hsm_vcpu_start(vcpu); + mutex_unlock(&kvm->lock); + break; + case SBI_EXT_HSM_HART_STOP: + ret = kvm_sbi_hsm_vcpu_stop(vcpu); + break; + case SBI_EXT_HSM_HART_STATUS: + ret = kvm_sbi_hsm_vcpu_get_status(vcpu); + if (ret >= 0) { + *out_val = ret; + ret = 0; + } + break; + default: + ret = -ENOTSUPP; + } + + return ret; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_hsm = { + .extid_start = SBI_EXT_HSM, + .extid_end = SBI_EXT_HSM, + .handler = kvm_sbi_ext_hsm_handler, +};