From patchwork Fri Nov 5 23:58:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12606155 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D0650C433EF for ; Fri, 5 Nov 2021 23:59:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AEF07610CD for ; Fri, 5 Nov 2021 23:59:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233511AbhKFABn (ORCPT ); Fri, 5 Nov 2021 20:01:43 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:4775 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231645AbhKFABm (ORCPT ); Fri, 5 Nov 2021 20:01:42 -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=1636156740; x=1667692740; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=oAAklw2+l3Z+7rUkDWJ+Pk60d+W6Gai8Zdl3z5WLmn4=; b=lqbP+tyi3LvmxvwPO0IiIEV9Hhm/uty7pc4b4G3htUmi34dpv2l9Z+gV O0+9lWosE/B+znoLYjEhheJLPdL7SYhAmzmXJq9BUBPxvBfTMYLloZ6aM nHn0LA+LRFS+PtQjeoOtg43heyeQay3ulCqkAime8F9z75R8UEky/iZBC q/ZHXK4EoHmUEggjny0xqbTsfNGvnvkuH9AbyFB+Rb003/PgMCN772Ffq 0OGwwU1IdLI87Bl/cRQAVdyZhMVlTRv44ky9eAch4sUnVvw4zJk0OiQBh TXyasiigEPeJDD+QkrseQyTWx/C+MQS5B6EpM9uHf3rSco/mTTN7zfyAv w==; X-IronPort-AV: E=Sophos;i="5.87,212,1631548800"; d="scan'208";a="189637761" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 06 Nov 2021 07:59:00 +0800 IronPort-SDR: 28uVNt3fSJFvL6qMiirJhNGSzWkKUGaPIVTBE9qvZLaTLPYbT7XOSPI4NEdng/AeOnS3VEs4VT vYk0ur/2bJzBb6mHOa2H5+IpHTfEsOvEHyWDFqrGkwTnplI4qqPhdhT5A3Yf0Im05r36gVli/0 RcsIe+VUlrtEAPzYrjTGMoOKu/wD0CnrL5GDWvC/R6POaw7FW0ZmHF2fLvLqR0j/lzNDE22g7z iTmYYNrW39ePYS/6K+n7hoz1YaWFgfI03tbNyy0B/OreXmpMEM3aDL70z5dk2QBN0+OeiSqnil 0d3r408hNRiTocLIeRGpYE6E 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; 05 Nov 2021 16:32:46 -0700 IronPort-SDR: 6I4QEXh2k8Tvp4lrFF0q9Fcf6ZEsiD2oVrlSCtYZzXFLRYzcdgtShfxX84k+ulbNGJhE/XVrb6 ShUzRzKhp0qFva7/JuG0AxkpQMF7jmxY8vbpsvKYcf+HB+6JDMbQ4zIAkbMRzWJ9s3gdHGyD6T dwqGTfGH2tgAGNWTzwckIQjx9R3qR7P17IlkbssJUw6etHwU9WHqVjh2ushANW1fkxPzHVp4Bt dnikvKdA5ApxHtsoClqFYEehIyRDvA+q5yQkH2ev3Z1e9RYtMnkZPemdO4bePKpqe5BrI0nyP5 yAs= WDCIronportException: Internal Received: from unknown (HELO hulk.wdc.com) ([10.225.167.48]) by uls-op-cesaip02.wdc.com with ESMTP; 05 Nov 2021 16:59:02 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Anup Patel , Heinrich Schuchardt , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley , Vincent Chen , pbonzini@redhat.com, Sean Christopherson Subject: [PATCH v4 1/5] RISC-V: KVM: Mark the existing SBI implementation as v01 Date: Fri, 5 Nov 2021 16:58:48 -0700 Message-Id: <20211105235852.3011900-2-atish.patra@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211105235852.3011900-1-atish.patra@wdc.com> References: <20211105235852.3011900-1-atish.patra@wdc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org The existing SBI specification impelementation follows v0.1 specification. The latest specification known as v0.2 allows more scalability and performance improvements. Rename the existing implementation as v01 and provide a way to allow future extensions. Signed-off-by: Atish Patra Reviewed-by: Anup Patel --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 29 +++++ arch/riscv/kvm/vcpu_sbi.c | 147 +++++++++++++++++++++----- 2 files changed, 147 insertions(+), 29 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..1a4cb0db2d0b --- /dev/null +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -0,0 +1,29 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/** + * Copyright (c) 2021 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 eb3c045edf11..05cab5f27eee 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 -EOPNOTSUPP: + return SBI_ERR_NOT_SUPPORTED; + default: + return SBI_ERR_FAILURE; + }; +} static void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) @@ -72,16 +88,17 @@ static void kvm_sbi_system_shutdown(struct kvm_vcpu *vcpu, run->exit_reason = KVM_EXIT_SYSTEM_EVENT; } -int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) +static int kvm_sbi_ext_v01_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) @@ -95,8 +112,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 @@ -104,47 +120,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); @@ -154,22 +165,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: + ret = -EINVAL; + break; + } + + return ret; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01 = { + .extid_start = SBI_EXT_0_1_SET_TIMER, + .extid_end = SBI_EXT_0_1_SHUTDOWN, + .handler = kvm_sbi_ext_v01_handler, +}; + +static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { + &vcpu_sbi_ext_v01, +}; + +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; - break; + 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 Fri Nov 5 23:58:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12606157 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6E84FC433F5 for ; Fri, 5 Nov 2021 23:59:07 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 52E526113A for ; Fri, 5 Nov 2021 23:59:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233527AbhKFABp (ORCPT ); Fri, 5 Nov 2021 20:01:45 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:4775 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233184AbhKFABn (ORCPT ); Fri, 5 Nov 2021 20:01:43 -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=1636156741; x=1667692741; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ry3CefX/Tp4xaLpui45N/sUnV2uYJCRDeodPmHhQp30=; b=Y8kSr9VZIveMc/hxAqJ2zmX86loPL2kUVMeT9+U8bgI2jpUKy6f1gv2g 4F+jbF4QmCpSyHdnREAuDu0mGudZUQjXhPc0H0vIfqZ/WFJYQIr3VawNT 0Xq3d5fhC6r0lJKGZKbt3wabh9wx8nDxs2+CE3rvfectSbHbH6QS85V49 jer4KSwdQ0dWXKBilO5EgBsWJILtrVPI39mjF/bE2zbEwmr2TFFh42cc1 VwOMxaSOwti/f7MojBSJtWrm7giU+6D+6jI2NK6bW37/EVaRZBX69OKiF uI0mTOxK+G7i5d77ATzxeC5o3klf1XH83R1mEKbEIFhDx35S5i1faK2+l g==; X-IronPort-AV: E=Sophos;i="5.87,212,1631548800"; d="scan'208";a="189637763" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 06 Nov 2021 07:59:00 +0800 IronPort-SDR: /V2O6IdDKg2ggcNCppBeOBsRP54uOb6LuNgQDgM/h3RqWtL3Ae1ymqYh7YJe6aRTA3pK69biVj CBjeYhlnu8J0Fuj7DyjGv5gc4vyckfiv1grRHPg4BcGtcq6VevVyAQ5nn1qJSthsDlajpk0KiU U4QB/W4k/lCQyeENtPLpctVqs6VgobVOp0XTax0Z7gVSVw/z/oaCOVNBBcyLcrt6ldu+44NFWl uIUEmGqIgQRmNHw9Vf8FiCn5lrU9GId1L9vwZvxKCwgmCUMhrlK52uWljyx+sIJtEFtrF344kx AgB56H/KcheuRUxOd7kXVJ3v 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; 05 Nov 2021 16:32:46 -0700 IronPort-SDR: nPfFgdVx3EqyS/bfu7H2v5XNaDKqbaygz/10P+fMvqqhGn/0V1iDl3bF00LnyxkfaQm9XaEr/g neXs+JNseTJBl9wDooouv0o8jYtvJjR8DJb/jyKkghJToE5QBUTLaQrGtAkC8MBhXuzWINwRU5 u5MYWgpzHVDFPGwElPzqE2zJdeu88HQBbQRoSmnW2mtmMb4G1Aq9XwfYkMAkID977O5O57iD6l ij+jfLiFA+OSi/A/jcJHUo3GCV4qn9aqZtZRllKyCQp8D9SRg08//mA97IkIrdy2IO5iNetpSi 8Fw= WDCIronportException: Internal Received: from unknown (HELO hulk.wdc.com) ([10.225.167.48]) by uls-op-cesaip02.wdc.com with ESMTP; 05 Nov 2021 16:59:03 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Anup Patel , Heinrich Schuchardt , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley , Vincent Chen , pbonzini@redhat.com, Sean Christopherson Subject: [PATCH v4 2/5] RISC-V: KVM: Reorganize SBI code by moving SBI v0.1 to its own file Date: Fri, 5 Nov 2021 16:58:49 -0700 Message-Id: <20211105235852.3011900-3-atish.patra@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211105235852.3011900-1-atish.patra@wdc.com> References: <20211105235852.3011900-1-atish.patra@wdc.com> MIME-Version: 1.0 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 Reviewed-by: Anup Patel --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 2 + arch/riscv/kvm/Makefile | 1 + arch/riscv/kvm/vcpu_sbi.c | 151 +++----------------------- arch/riscv/kvm/vcpu_sbi_v01.c | 129 ++++++++++++++++++++++ 4 files changed, 149 insertions(+), 134 deletions(-) create mode 100644 arch/riscv/kvm/vcpu_sbi_v01.c diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index 1a4cb0db2d0b..704151969ceb 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -25,5 +25,7 @@ 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 30cdd1df0098..d3d5ff3a6019 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -23,4 +23,5 @@ kvm-y += vcpu_exit.o kvm-y += vcpu_fp.o kvm-y += vcpu_switch.o kvm-y += vcpu_sbi.o +kvm-$(CONFIG_RISCV_SBI_V01) += vcpu_sbi_v01.o kvm-y += vcpu_timer.o diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 05cab5f27eee..06b42f6977e1 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,8 +30,21 @@ static int kvm_linux_err_map_sbi(int err) }; } -static void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, - struct kvm_run *run) +#ifdef CONFIG_RISCV_SBI_V01 +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01; +#else +static const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01 = { + .extid_start = -1UL, + .extid_end = -1UL, + .handler = NULL, +}; +#endif + +static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { + &vcpu_sbi_ext_v01, +}; + +void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct kvm_cpu_context *cp = &vcpu->arch.guest_context; @@ -71,126 +82,6 @@ int kvm_riscv_vcpu_sbi_return(struct kvm_vcpu *vcpu, struct kvm_run *run) return 0; } -#ifdef CONFIG_RISCV_SBI_V01 - -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_v01_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_v01 = { - .extid_start = SBI_EXT_0_1_SET_TIMER, - .extid_end = SBI_EXT_0_1_SHUTDOWN, - .handler = kvm_sbi_ext_v01_handler, -}; - -static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { - &vcpu_sbi_ext_v01, -}; - const struct kvm_vcpu_sbi_extension *kvm_vcpu_sbi_find_ext(unsigned long extid) { int i = 0; @@ -220,9 +111,11 @@ int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) sbi_ext = kvm_vcpu_sbi_find_ext(cp->a7); if (sbi_ext && sbi_ext->handler) { +#ifdef CONFIG_RISCV_SBI_V01 if (cp->a7 >= SBI_EXT_0_1_SET_TIMER && cp->a7 <= SBI_EXT_0_1_SHUTDOWN) ext_is_v01 = true; +#endif ret = sbi_ext->handler(vcpu, run, &out_val, &utrap, &userspace_exit); } else { /* Return error for unsupported SBI calls */ @@ -262,13 +155,3 @@ int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) return ret; } - -#else - -int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) -{ - kvm_riscv_vcpu_sbi_forward(vcpu, run); - return 0; -} - -#endif diff --git a/arch/riscv/kvm/vcpu_sbi_v01.c b/arch/riscv/kvm/vcpu_sbi_v01.c new file mode 100644 index 000000000000..5a8e2afc8a57 --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_v01.c @@ -0,0 +1,129 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 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_v01_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_v01 = { + .extid_start = SBI_EXT_0_1_SET_TIMER, + .extid_end = SBI_EXT_0_1_SHUTDOWN, + .handler = kvm_sbi_ext_v01_handler, +}; From patchwork Fri Nov 5 23:58:50 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12606159 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 14A9CC433F5 for ; Fri, 5 Nov 2021 23:59:10 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id F2354610CD for ; Fri, 5 Nov 2021 23:59:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233587AbhKFABs (ORCPT ); Fri, 5 Nov 2021 20:01:48 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:4775 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233495AbhKFABn (ORCPT ); Fri, 5 Nov 2021 20:01:43 -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=1636156741; x=1667692741; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=Er5RxKJadD7bsDIJOhUGnJYsnW6DU5RB+Akt9hHrrm4=; b=To0LSIoV6vzhiRia4VmWZo6w64Y7uW1+ZSsN0MyuSWmiQ6nh0kpiaJYO 5XkyXE+6cpvbHX8LgQZqHoN962QoaE3DlnaIvaRTVU9UACDCt7FzA8b2Q k2gm/To/T+n4B9KdpGW2M94AFFzoRcm3yYRSmbrG3H3e2rGDIB5kqIzw1 hqsApshz5IrFhzh113Q7eXA9mFDPWAnowgQKGBZ6uHpwqP8GZLgrcRFU1 Cnz5ozUtP7kMmXRoxHXb2ILph2rZ/c+5GQpJw6crW+kJF71UENZGSiT8O HjYuesszRL6S09OM3bTSM6Q6J/PrY5ealf+JABdF4FL+IKetlQKOkF6C8 A==; X-IronPort-AV: E=Sophos;i="5.87,212,1631548800"; d="scan'208";a="189637766" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 06 Nov 2021 07:59:01 +0800 IronPort-SDR: 2ogGqEr9sQrpYqWD8xZisJb4g6+qtkBUHCit/o+fKZb1s2hFlAYVxFB8ti2ii0OTJbJIpfmlN/ N7fp4yugAZr0B5kTreiRwI5K6k7RA8vw2pE1PiJjqdGx1KCXSHQ6jcFrwgoWRuCdqW3DGeCpZq /gIvIsqM1wq0zmBc51vY5bR52pkI8NfCXJOzzpNKsqeE01WqOvL4Q6abNzI7KLM5IJICVMIkCQ E9Klyy7rnGk2yfJ0uLCDn+epMsFXklxfBOwlN7F6AD6u4A4Ihwa926bOo2Gn2xnoJAvYp3N1Oi b9jZKKnM1/YmMsN+BJD/Jz5N 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; 05 Nov 2021 16:32:47 -0700 IronPort-SDR: 2pByQIwvnZxVNsg3qiQi15VIOnwm8U/03nFqck+hOmTJ9V+2z65HGPmvXtzj/luzCU8xUEV9n2 1rqeyVA+EfMFml9NNbMZgdTUiF96e1moODcXiQoRYvrfvmn/BRgvxh3GfefpamOyXCNHSU2Ypa xcj6+m0eocZpH7P2vQOQ5ETKhMiZ2MsDANAPsUkxqS5ANCTmvvPL5iqG1xwkjZdhuiqb/2O/kE kvIVHut1u2mzqLcNcjBjrlux8FtxBzrr/5Lx6CYvW07Aa640rNJ6X/eww0eZbygd7rGTEnik/7 Jho= WDCIronportException: Internal Received: from unknown (HELO hulk.wdc.com) ([10.225.167.48]) by uls-op-cesaip02.wdc.com with ESMTP; 05 Nov 2021 16:59:03 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Anup Patel , Heinrich Schuchardt , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley , Vincent Chen , pbonzini@redhat.com, Sean Christopherson Subject: [PATCH v4 3/5] RISC-V: KVM: Add SBI v0.2 base extension Date: Fri, 5 Nov 2021 16:58:50 -0700 Message-Id: <20211105235852.3011900-4-atish.patra@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211105235852.3011900-1-atish.patra@wdc.com> References: <20211105235852.3011900-1-atish.patra@wdc.com> MIME-Version: 1.0 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 Reviewed-by: Anup Patel --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 2 + arch/riscv/include/asm/sbi.h | 8 +++ arch/riscv/kvm/Makefile | 1 + arch/riscv/kvm/vcpu_sbi.c | 3 +- arch/riscv/kvm/vcpu_sbi_base.c | 73 +++++++++++++++++++++++++++ 5 files changed, 86 insertions(+), 1 deletion(-) 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 704151969ceb..76e4e17a3e00 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 0d42693cb65e..4f9370b6032e 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 d3d5ff3a6019..84c02922a329 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -24,4 +24,5 @@ kvm-y += vcpu_fp.o kvm-y += vcpu_switch.o kvm-y += vcpu_sbi.o kvm-$(CONFIG_RISCV_SBI_V01) += vcpu_sbi_v01.o +kvm-y += vcpu_sbi_base.o kvm-y += vcpu_timer.o diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 06b42f6977e1..92b682f4f29e 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -39,9 +39,10 @@ static const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01 = { .handler = NULL, }; #endif - +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_base; static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { &vcpu_sbi_ext_v01, + &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..1aeda3e10e7c --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_base.c @@ -0,0 +1,73 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 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 = -EOPNOTSUPP; + 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 Fri Nov 5 23:58:51 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12606161 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 6C87CC433EF for ; Fri, 5 Nov 2021 23:59:14 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 588CA611C4 for ; Fri, 5 Nov 2021 23:59:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233643AbhKFABv (ORCPT ); Fri, 5 Nov 2021 20:01:51 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:4775 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233506AbhKFABn (ORCPT ); Fri, 5 Nov 2021 20:01:43 -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=1636156743; x=1667692743; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=8N7I3xFAN4A0OtRWqWWyaemIsM7CmwJ3kiGZkFqV+q8=; b=OKbx9+6SFOsxgSkBnTslP3hpr62xaIN1SAoD9A4I7W52mT32dsgckEO1 PbhKG8gd140CV/iRWZ7g6iyrc/SbIzt5fz/etesvSUgMBDwBEpD6yaLcI PAK3GcKgJCPTS3wtPjN1mqH1NwB++NLaojJ5g83F7u0uwAsvJmiOZ5Ahh +K8YjBVVxtSYXsP0NDyR+ryA74eeHOoHvf3UAze6j0uT7BoZOn69Vp62b WTyMs3V2WhcvmUInyBXpzo7eAc18cNPLLWDVdEeBrkpZymgjT6vmIdjUG ggdQKWA7ohF8Djo2R9wgrto4lJMii4EUJq7ChhwsVyQ98X2GigqBrjy2K A==; X-IronPort-AV: E=Sophos;i="5.87,212,1631548800"; d="scan'208";a="189637769" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 06 Nov 2021 07:59:02 +0800 IronPort-SDR: ZP60XWkUpGj8m2OXwX54vUXBWIowWPhZvUh64/mXKNPiF/y359qRZkyVIwatG79SOKftiLufw1 2P8jNt470bi47GVZ/+534ZBHQ7BaLLRGaJ4VOOOil7YU0EmThn7OUxyYPtk5uFV5OrHsWjIiVV MHDGHm4cvwrjTYWRBt1paRH13VSBTgS3cJnV2ckG5Yl9kU8zsdOQojO/BDVITNbHltWFi2B9Pr pW/up+i1IqDScmAxXjL25pg+wDvpG+k5CFYGkM3/kVAwSISPpbBzn8Mcu4ougnqvs8dZc8Mucz DmmNjb/hbl7tgkq7ZIdJqVSk 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; 05 Nov 2021 16:32:47 -0700 IronPort-SDR: 4prbuhVOfYfRIJwLSL7Yjz1dLcKn/hge99idIBa14P8ZIIGPjNHHUfE2mCr/KBWIIEUhc2N+z7 swEaWYHUJpgwPYewqvPckC2DIO83iM7OGTRMRXgc6GFR0Z3HQZDL6BOGU2cb5JnX+KoyscMrUE 62+cSD7jew3dwEd4mD7TER/g/GMbZaE652DjJ1TB8iq1POah0vHAN4TPizZYNCXJv6DuRWqKfx XaAGNubSHyGQrkIeAHxR/EvZe6dAY0+hi7D6pPZaSDRmqAkXnqm7EU9pTuz1y1rO/BrpRFPXQ4 bFQ= WDCIronportException: Internal Received: from unknown (HELO hulk.wdc.com) ([10.225.167.48]) by uls-op-cesaip02.wdc.com with ESMTP; 05 Nov 2021 16:59:03 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Anup Patel , Heinrich Schuchardt , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley , Vincent Chen , pbonzini@redhat.com, Sean Christopherson Subject: [PATCH v4 4/5] RISC-V: KVM: Add v0.1 replacement SBI extensions defined in v02 Date: Fri, 5 Nov 2021 16:58:51 -0700 Message-Id: <20211105235852.3011900-5-atish.patra@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211105235852.3011900-1-atish.patra@wdc.com> References: <20211105235852.3011900-1-atish.patra@wdc.com> MIME-Version: 1.0 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 Reviewed-by: Anup Patel --- arch/riscv/kvm/Makefile | 1 + arch/riscv/kvm/vcpu_sbi.c | 7 ++ arch/riscv/kvm/vcpu_sbi_replace.c | 136 ++++++++++++++++++++++++++++++ 3 files changed, 144 insertions(+) create mode 100644 arch/riscv/kvm/vcpu_sbi_replace.c diff --git a/arch/riscv/kvm/Makefile b/arch/riscv/kvm/Makefile index 84c02922a329..4757ae158bf3 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -25,4 +25,5 @@ kvm-y += vcpu_switch.o kvm-y += vcpu_sbi.o kvm-$(CONFIG_RISCV_SBI_V01) += vcpu_sbi_v01.o kvm-y += vcpu_sbi_base.o +kvm-y += vcpu_sbi_replace.o kvm-y += vcpu_timer.o diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 92b682f4f29e..3502c6166eba 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -40,9 +40,16 @@ static const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_v01 = { }; #endif 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_v01, &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..a80fa7691b14 --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_replace.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 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 = -EOPNOTSUPP; + } + + 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 Fri Nov 5 23:58:52 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12606163 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3BF50C433F5 for ; Fri, 5 Nov 2021 23:59:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 24091611C4 for ; Fri, 5 Nov 2021 23:59:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233686AbhKFAB4 (ORCPT ); Fri, 5 Nov 2021 20:01:56 -0400 Received: from esa3.hgst.iphmx.com ([216.71.153.141]:4775 "EHLO esa3.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230262AbhKFABo (ORCPT ); Fri, 5 Nov 2021 20:01:44 -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=1636156743; x=1667692743; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=CPBkmZZLjh3iLG2oa7rF/7SGMXdLh45iugpgmq06jR0=; b=B6HaNlVJKcbgITTiy7kROnS4Gr7KqigJVfjoNuHXFdTDeF/vglFV0ep1 3sYGZGVDmQcxd1PxTLoFyqxmZ3u7VaiwOyog4r2+ZOcvZg/ObImEug+L+ NUvX7ojTk0DQ0ltd4BA1aMMdr5yDup7rFRJjfq0UYyVTGM/qzBc2f6m0a zhZP3g/NALgCJFyrGh59ps0OJpCEkNyWxIA32ztZY7eQ6H3DDzi4tKxQS If22xEvnympPV8OUm5rILVYoAW5v+hP+3YeFrkJVBhat44ladnxLn2Jd+ RISCiuhtfjKT4Ct8mZkeIVU/CTnBhF6GVIzmL6qlYLCA1IUxZu3IemKzT w==; X-IronPort-AV: E=Sophos;i="5.87,212,1631548800"; d="scan'208";a="189637770" Received: from uls-op-cesaip02.wdc.com (HELO uls-op-cesaep02.wdc.com) ([199.255.45.15]) by ob1.hgst.iphmx.com with ESMTP; 06 Nov 2021 07:59:03 +0800 IronPort-SDR: e41hfve6MU8Nr3H6gGZPc0rZtZXjXoI7R5XxPo5EBZN+qgae1KbjNBJsAQLcTfM9Ytf4RJm3x3 Hv3aQyDJnXEpE0bhsQyjc05moGu76Cs0+F2P/FVY4rdQgBnUIPvrsuMH4sQtKVQ8LgM9YfFpeP nF6uGvu0gvnFCy4nH+Q/e+kC1yLdJgLQNUg8zO2PTTxtSwCAQOObNcQjvZC1EgNFKHV65vtGzS O2KnYVxB3tWxjnEeyvwo7uAP3/EGCYjK2L/OOPBj7NMxoHv42OhY7Br/Z/c5+CJ3Oq6+bLKKyF xRgUkz52Ld9w57hwbxTkLH+L 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; 05 Nov 2021 16:32:48 -0700 IronPort-SDR: Usq9zpvtPvxj8wXdxBMHGJngbrSgxOMSBNgqyOohPmxmbffHG+jDOLZ3zyORCCSD9WL7vh51ok xMVcQONiQUfhc2EWL6VTd52yU8KHl46VmRh21ytS+gi1JRNH9tW/qDm9z4CMxfeBPo91/Rvdfg uRqw8OopCyvo2dz5A7h8m/huCh4/JZNrZrdukwZKhfqklLzuGDUuFXKmlUzyDaaT1t4NNn6OAI EAdS+lHgFYYcqFZfEloyvDfDmc6Jw1lo5x1LWYiAufwXrmwbhrKvfz2SvnOPgIfY2t0CvOV9DF MKY= WDCIronportException: Internal Received: from unknown (HELO hulk.wdc.com) ([10.225.167.48]) by uls-op-cesaip02.wdc.com with ESMTP; 05 Nov 2021 16:59:04 -0700 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Anup Patel , Heinrich Schuchardt , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley , Vincent Chen , pbonzini@redhat.com, Sean Christopherson Subject: [PATCH v4 5/5] RISC-V: KVM: Add SBI HSM extension in KVM Date: Fri, 5 Nov 2021 16:58:52 -0700 Message-Id: <20211105235852.3011900-6-atish.patra@wdc.com> X-Mailer: git-send-email 2.31.1 In-Reply-To: <20211105235852.3011900-1-atish.patra@wdc.com> References: <20211105235852.3011900-1-atish.patra@wdc.com> MIME-Version: 1.0 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 Reviewed-by: Anup Patel --- arch/riscv/include/asm/sbi.h | 1 + arch/riscv/kvm/Makefile | 1 + arch/riscv/kvm/vcpu.c | 23 ++++++++ arch/riscv/kvm/vcpu_sbi.c | 4 ++ arch/riscv/kvm/vcpu_sbi_hsm.c | 107 ++++++++++++++++++++++++++++++++++ 5 files changed, 136 insertions(+) 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 4f9370b6032e..79af25c45c8d 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 4757ae158bf3..aaf181a3d74b 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -26,4 +26,5 @@ kvm-y += vcpu_sbi.o kvm-$(CONFIG_RISCV_SBI_V01) += vcpu_sbi_v01.o kvm-y += vcpu_sbi_base.o kvm-y += vcpu_sbi_replace.o +kvm-y += vcpu_sbi_hsm.o kvm-y += vcpu_timer.o diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index e3d3aed46184..50158867406d 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -53,6 +53,17 @@ 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; + + /** + * The preemption should be disabled here because it races with + * kvm_sched_out/kvm_sched_in(called from preempt notifiers) which + * also calls vcpu_load/put. + */ + get_cpu(); + loaded = (vcpu->cpu != -1); + if (loaded) + kvm_arch_vcpu_put(vcpu); memcpy(csr, reset_csr, sizeof(*csr)); @@ -64,6 +75,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()); + put_cpu(); } int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id) @@ -100,6 +116,13 @@ int kvm_arch_vcpu_create(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 3502c6166eba..bff753b6e4b0 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 -EOPNOTSUPP: return SBI_ERR_NOT_SUPPORTED; + case -EALREADY: + return SBI_ERR_ALREADY_AVAILABLE; default: return SBI_ERR_FAILURE; }; @@ -43,6 +45,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_v01, @@ -50,6 +53,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..aefee16a1560 --- /dev/null +++ b/arch/riscv/kvm/vcpu_sbi_hsm.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2021 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); + + kvm_riscv_vcpu_power_on(target_vcpu); + + return 0; +} + +static int kvm_sbi_hsm_vcpu_stop(struct kvm_vcpu *vcpu) +{ + if (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 = -EOPNOTSUPP; + } + + 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, +};