From patchwork Thu Feb 4 05:32:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12066317 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 23869C433E0 for ; Thu, 4 Feb 2021 05:34:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CD0FD64DF0 for ; Thu, 4 Feb 2021 05:34:43 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231530AbhBDFeL (ORCPT ); Thu, 4 Feb 2021 00:34:11 -0500 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:38831 "EHLO esa5.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230322AbhBDFeC (ORCPT ); Thu, 4 Feb 2021 00:34:02 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1612416841; x=1643952841; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=KKoZm/yRaWYpbDjxNyImgz6OnxMRCIBlc1M6mN/Snb4=; b=ls1mwO3ObFWflehvMDiTOxWnhEo3rMPV3STbmPHztP6bFY+OLuPxCbPW AFoL+CvNsfWVF0fIgm3lZvCh0vjhS4+r+7PNqysPyiW+UVdAXo0mjOWXa MuqvOqehMrWhe2DeIdD5H/jaeyjYo3/qlZWNHzmqbWnabLmds5KmtvjP/ gfqK5smtz1nr+UB5A0tIknuZl7NUkoMnk/Cp4LvA/p5cwDhGvVbsS7zEc mma7zY5F6uFjFW6qMR5BW3fGhhEl8Mn4ZDxXM9YNOrVRTJb41MNwbeJjK SDvhza/tci3SK973EvA2okueTQZxaOmoMRDcevNE2PGJ5SAZPYpmKcFGj A==; IronPort-SDR: 3soR+W/kcUoUJJxHaEbz7lhn49813qTH65T39UoIPt7Zwq2Ykf3MC1mkfCHKp5S6Sdyk/td1s8 6iwxI970H9woqaYbeN8wZcroJfd2F8Xx1Xl+U4WA2GBsg0XnCZmu1VhbRfKQIGGRbQgwoaOMeK 1ohWNb9+N+6x/d6S0iwx8er2zSeLXXO/q/yEWQbkR0evL/10Zsjm6PawuOeNk1tPGIbsXs30e4 xu3zyyIZP9MVb64Rx7tX9bJH8AF6wKXdYb6MO0W33U4B1+I39B3wk6o5SKwOpTNC5dJ48r52qL RjM= X-IronPort-AV: E=Sophos;i="5.79,400,1602518400"; d="scan'208";a="159086432" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 04 Feb 2021 13:32:53 +0800 IronPort-SDR: OBvI8pSho5MYsCVWNGNjHHVBVmIPmW0Lt1sg5eDgOaT/BFUFXXb/mZXuJ6Y5kWG9m0Z/+w+rzj mdmF9YX360lS2Pe5noJ/L9mMHmHXPhUVuRGWZGCRLgJjA9FcG89TjqasO96s380CadSGtc9vuE nV8d4qQ1MuTSVBCEGSYbnvfzyaIMAHV0fvyquLXWgRk5AfIHn6s3RBa6i8+KCTVCVnDoSAYSye Sas10/Msf6SZejGoV/+brG1vc0I1i52wGj9dhaOGb/Yikb67h0L6SsffWPrvT1B4OWdMQhAFSM YS1yrdHw51TKv4e5ooVStTxZ Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 21:16:53 -0800 IronPort-SDR: alPokM4Ni8YztwJSBFlZvtaYzFjJvz7QCcB0erZK2+Wb5cT6Mxt0WIBRbZryZm9dHk7/ja734c iTWetN/DrwEXAgES68K1mA26oNtJjmfHnHm8tNkAYZrpHthQp/7vnQVuKszl3NcBv95wshIPR8 lVGqwM3o1OEojPUJoT6s3idyEtiMJDP53bOOlrtmMl6H14ism29w38eII3CNSVCIJtgBOPKJ/I wg6+FWvGe426rpHzljdP2zQLHXBVyAN5sXdmX9XRzTo/a76bk+m/5/mvyfDqyqwT96hdU5FoA+ 8Q8= WDCIronportException: Internal Received: from cnf008142.ad.shared (HELO jedi-01.hgst.com) ([10.86.63.165]) by uls-op-cesaip02.wdc.com with ESMTP; 03 Feb 2021 21:32:53 -0800 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley Subject: [PATCH v2 1/6] RISC-V: Mark the existing SBI v0.1 implementation as legacy Date: Wed, 3 Feb 2021 21:32:34 -0800 Message-Id: <20210204053239.1609558-2-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210204053239.1609558-1-atish.patra@wdc.com> References: <20210204053239.1609558-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 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..a96ed3e3a9a3 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_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 Thu Feb 4 05:32:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12066323 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 8E84BC433E0 for ; Thu, 4 Feb 2021 05:35:45 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 38EE964DF0 for ; Thu, 4 Feb 2021 05:35:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231712AbhBDFe5 (ORCPT ); Thu, 4 Feb 2021 00:34:57 -0500 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:38827 "EHLO esa5.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231622AbhBDFel (ORCPT ); Thu, 4 Feb 2021 00:34:41 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1612416880; x=1643952880; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=IOK4UTswE1NPODeHGHqIzkeqat1sNm/Kk7Q10PMGCio=; b=NhDD6ZDUKhZcWoSUFMXfs/7fq97qC7B1HQ4mRPRjV2BttX2Iq397CvdQ MsDu3AjLaFfUgtfy0dAzqS1m6pHiwEh6YxkGbauZJO0tLOIkzoUzrSeSD Z1+4lIBEXBcLmWNifIVoT7+Gnxui57HPCmAcw/QpIbQDHPHoH6M2SGw+y gq4SdB46m9DVH/oTBzLqniWZLAqh/8FNtPz2DrqzdU5fBo7QjJcHI6qCs GsMC4gEeffn9l2PufUZ0FaTCqRo2xRoqeZEnZwS4bmSMofb6Cr3oycmPx Y3ecFPHD51kKYcBHu1AgTP8eRMcWWE6fWSXcV5hALQ5u2hXKxq/1ktutT g==; IronPort-SDR: e7DdMsNAiaF7E9wJYOKm2RJMW58UzICS/wr/AtOd4d2DzP/RQjyYtkIfU4ZSsmSIS7bX6vr/N/ rxMRb83Xr392RYhFhxfq1WE2kZOGrFXu3ApkCZz4/7OIACpcowJUzjxPBRcTC+oCsu4bxseB4v dxCU2Amqr+OsiC1zFOkHfa9f9SopLx370otton95oxvuzm7dteXU+/1wC3Y30MxOkieOrBNtn+ h4sRy754ELO0XrxacnJB4P1Y7YfqLcty2tTKjUckWZO7ssAIPSywWXMeYaInourK6eFlOs9Wmm VLk= X-IronPort-AV: E=Sophos;i="5.79,400,1602518400"; d="scan'208";a="159086437" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 04 Feb 2021 13:32:54 +0800 IronPort-SDR: t3DCqQ3rGdHqcvBc1kgQGd/gdZ4dpZ8CHo6IDz19caTfw+5lzXFdwJKrKlkFDr9teEvbHsJFY4 MYj8yR/MLYT69a8qG/tj12aLZMyqvQ+fX6Tk5K+V2+hyUH7uVOud3NHXz6ofyiS0N3Uy0MoR0a gYKNghhSfQCJ0m6+1sGnqpSYGpN+RZsruAijff5Io8Pd+uWT5oNLOXiTBrNguMRFziTMwYIPc5 uEPkZh9bQJhCLhzLCrd7sdCBETJIHwtumLAeCK1Cf9dfKGCD6RkGvx1df5VRocPDvpYnjC5xmk 6MJy+kp5RFR/S3VLd8mSQJph Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 21:16:53 -0800 IronPort-SDR: gh2i3bdN2t7D2qvONDYOjfWtidHrKydscEsmK6KdMXRpTw5f0ANiCKTUVnaMCYhUDYELOKUY1W 9tqANDxEy21cR9n32D0VeksyGuP24gzYJqW6QegtARpm+laOoHqtgsrU0TjyxDKr2wa8SBQWuE UfeQ8bk7yEu4b6i3J6cGPcnObJrAxDKk5p5Ehjw2YQzS9TiZoY3mQe3owU8v0FSOhuQKzHSyzz uoEciFj+biHL5jYZ4FpKn+YSSO/BcJdaSeUTPt+txLH+oNuR8eY2tTpZk3E38UhNjQ0Bbbx3iV CZ0= WDCIronportException: Internal Received: from cnf008142.ad.shared (HELO jedi-01.hgst.com) ([10.86.63.165]) by uls-op-cesaip02.wdc.com with ESMTP; 03 Feb 2021 21:32:54 -0800 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley Subject: [PATCH v2 2/6] RISC-V: Reorganize SBI code by moving legacy SBI to its own file Date: Wed, 3 Feb 2021 21:32:35 -0800 Message-Id: <20210204053239.1609558-3-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210204053239.1609558-1-atish.patra@wdc.com> References: <20210204053239.1609558-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 --- 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 7cf0015d9142..1ba4afe112f1 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -10,6 +10,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 a96ed3e3a9a3..29eecf8cbdc3 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 Thu Feb 4 05:32:36 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12066319 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6F30C433E0 for ; Thu, 4 Feb 2021 05:35:17 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 9DE5364DF0 for ; Thu, 4 Feb 2021 05:35:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231696AbhBDFfA (ORCPT ); Thu, 4 Feb 2021 00:35:00 -0500 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:38831 "EHLO esa5.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231652AbhBDFeu (ORCPT ); Thu, 4 Feb 2021 00:34:50 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1612416890; x=1643952890; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=V5hcHtmAfeJBPF3g3umUzSrG8ecGlDvA9Hi3xImGAxk=; b=DGSHRaZoT48qwNIqi2WRHLDVHlPefILSycyd85PxrD2Bd6gpRFJQK/oN cFoqEpxkvkx76BpRjKQLKgJuoqJO1on+aFt5kgfQ4YJ8mvytSQfVblj52 oZQZcBiBRBvhSZEy5mC9UKVB7RG0fCMa+cR8ut50Q15g1b1vERalNQQ8R RwgCLJiRbAZx8yfcAYbJpyxlXnP3GaYsZPkEBbSBumitnWwHt7xGQK/Wn 7xXRHwm2Ya/puplneNFB/2tW6PDj95uL7AftYsseso/DxC466AOp17/GU 2QVbOtP/6nyVEfEo+ViMTmlIZCA/FrLi9ouOcWIpEJ6S4GuR8CTBCBPvk A==; IronPort-SDR: 6SafRo0sMEAk6dcfeGXfB+ahiWkcKAmsCdEOkW062GEJwud+vC8DELWV391eIkzxacAB9dvL3N iHkbb2sAO+O/df/jE6STbM8Lz1rgh9A/vfSqN3RD/nvQ/422djPDwrImZudlE3NcZlRrJr39DU 55uipiZxWw7x+Xhqe/PVI284ouroY0lKLH8/N7ytsuYNAnaLyI11fw5Hzc66whJDzcpikgGUAR 91ISACztrWFFQThIZmQwFYDtfFhoWZ8G4K8yDXrSKC8ol9tnuO/mWmGnTBM8gjJzj1MI+s/XuB Ngg= X-IronPort-AV: E=Sophos;i="5.79,400,1602518400"; d="scan'208";a="159086441" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 04 Feb 2021 13:32:54 +0800 IronPort-SDR: u1h3A4mrXeFhjOK18wOtjnYeRjBwP17o2YKHc4Fhe3ka0y3PK/E81pEh1f2a6QYmCnL0qlWcPY yiyW+LMiKz0mg04qmEhz4v34abLE9paaEYGixJYpiLSUgcQBpC1hckOGUuLr4qB6CFQGJK+MMD /uHzy3kUxtSf28j/P1z5MtK8rrYmooXwkpDhJqzCldVGXX+gfJtgFzRYuKlGhbSeewssOLpZDi xuikoXpKiluBIz1wpSz7l2BVi8/JCAi9a7oJW/XnOrbXZDyJjCEn/I7O4jgjoOMSmjj2vhYmGF wg6RIjw6Tk3v5U47w5o1tgsi Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 21:16:54 -0800 IronPort-SDR: 8ODTY/isjotPeAhGRXatURbVEIlwhpRnxPyBOdTHVOMPNr+zFaRzhtDw4m1KDvEUflWTUBs1HU LsFuc0ESb7yQrulZj7LfaY0iQxZd0lIuZOLNNRkotMokkj4hYEKxvDP+KLLZng/TSAoV1+8XbW nFSkP2OgtYXgQ3gA+bd93P3v/MHUwrkLpS1soAylLx0yq+PLLhwV5j9uk10EHjP/tmuNMoULqj 5OD+rB28GtWg+G2KxChNQmKe+R9iFcpL+gkpgPYwyMAQhy3U/qUM8cvUDeF5ddGnDqP37vmTcU Bz8= WDCIronportException: Internal Received: from cnf008142.ad.shared (HELO jedi-01.hgst.com) ([10.86.63.165]) by uls-op-cesaip02.wdc.com with ESMTP; 03 Feb 2021 21:32:54 -0800 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley Subject: [PATCH v2 3/6] RISC-V: Add SBI v0.2 base extension Date: Wed, 3 Feb 2021 21:32:36 -0800 Message-Id: <20210204053239.1609558-4-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210204053239.1609558-1-atish.patra@wdc.com> References: <20210204053239.1609558-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 --- 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 3e7141a7d11f..4a405f583d32 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -28,6 +28,14 @@ enum sbi_ext_id { SBI_EXT_RFENCE = 0x52464E43, SBI_EXT_HSM = 0x48534D, SBI_EXT_SRST = 0x53525354, + + /* 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 1ba4afe112f1..0f17dffe8d46 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -10,6 +10,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 29eecf8cbdc3..c85c3b1dd2eb 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..48f1164f189c --- /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 = -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 Thu Feb 4 05:32:37 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12066321 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 37BC1C433E9 for ; Thu, 4 Feb 2021 05:35:18 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id E5E3664F55 for ; Thu, 4 Feb 2021 05:35:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231862AbhBDFfL (ORCPT ); Thu, 4 Feb 2021 00:35:11 -0500 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:38918 "EHLO esa5.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231910AbhBDFfG (ORCPT ); Thu, 4 Feb 2021 00:35:06 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1612416905; x=1643952905; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=zkz7usoeD7H22CZL96Ux56lGImBj0Y0tKyEFaWX6wQE=; b=MlDTis74QSYxE6KDJZntJiGN44er/N0dqjZwQorxMv4IS2r4KVoHAS8+ RZJ6qxGTO8RJHXZPFxXGhe/PSOG5hW6oBzdWXNao6Uoq1EFsWX26B5btl Awpgl96kKTF/9YhGkwzon00RK+b3yY15SUl6KgZv15mkisYR/VP1QXIkk t7I6RHThuj9i+aju0xgAt2zNuvnc6dcdkUjxn1u8Hw7SXGJZ0su4pKcl9 szZqj7lR9l1Eh+Icvoc8KAlAcT4TUg5mnC5ZOG0RSNzXhW+3v6tWEbUhX 2ODNOt4/RcL/IJikaIeXppxQ9h8BGgEI1RGEFeV4YGS9NmEBogTZHzKpi g==; IronPort-SDR: 5I+XYCo47HOs1VQ59oabpIpD0wmIY5JACiUu2cd6AkUxGjAH9gsXtpD+wsAVLJdOMQCyb+NogW aRAWtcPpsInRUcfdwVsqu3fkbEQCzeZD9Ql9wdzojLSJj9OX1Y3PIH6OAamGSxiu/8sFjLxwiG XUSJbJtVoSwVdddUIb0Z54atpafmLy63BQ+EjkTvNUbOSvOrHr+a9kgDMp93D/G/iTOuF5TEDv VKOYVK/FDubcv9iszboTCWDXqNSniScvQKxsUSyfWPv/VuYonbYIFsoPdVr7xUcKPE4WWSwUXe UI0= X-IronPort-AV: E=Sophos;i="5.79,400,1602518400"; d="scan'208";a="159086446" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 04 Feb 2021 13:32:54 +0800 IronPort-SDR: y/AZzVlfMO7OO2HxqJpogOm2jFHLF/HuzCCb9uCARAVTGQc6jkg+rz/wqQ/se3PiUqHR1/owZn rfOFRj1YbgCjun0uqkX10gVJ3l+0ItbcQzsAhsRmV8HT+5ZmcXNz6QES2qtI5hFqYoMjrYqXTB ZSO/ynnDVXgU0Mv1oDg9ReJQVOQfyoZ6kDdO8zOP5lKeMRkjMf+pj0vXSRbkFZaGV8eoBkiRsr ohYoNXOiFxTC9jWCf3FgoJVPtpXgNSPaQYbFslB/SusopwOxkvAONl1OdW6hv2vOs07bcO1KmF jEhyye6/0UX9AONKW9tIVufM Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 21:16:54 -0800 IronPort-SDR: Oymd+BRq45I98/7mHFwaiDoPJ21T5pwZQXWJE5sq0waNsatNrFzyeyC2kQF3HolfPtZsN3amJf Qtvd/K/x4MYehN016BMKakZ3O2smkSv0KiZ5CuQw8deXQG1E2mk5oalyodKFk9KMklxAdWr+XM WIsgHqocevKHM9jEd2HSdZEjxc4d6QfIy60/+AW0BYbzmJy9yqZxRHX6+OSFrugi/Aajz4QN9i RLIxZjH4W6b7H0PKBG8vTIky/YGOCUTQweNFkBkj7a5c+naFedLTUmxPcIItIB81h7lVSPbn4Y 1nc= WDCIronportException: Internal Received: from cnf008142.ad.shared (HELO jedi-01.hgst.com) ([10.86.63.165]) by uls-op-cesaip02.wdc.com with ESMTP; 03 Feb 2021 21:32:55 -0800 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley Subject: [PATCH v2 4/6] RISC-V: Add v0.1 replacement SBI extensions defined in v02 Date: Wed, 3 Feb 2021 21:32:37 -0800 Message-Id: <20210204053239.1609558-5-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210204053239.1609558-1-atish.patra@wdc.com> References: <20210204053239.1609558-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 --- 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 0f17dffe8d46..302501295397 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -11,5 +11,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 c85c3b1dd2eb..e21ce1e69e03 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..dffb1930cada --- /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 = -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 Thu Feb 4 05:32:38 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12066325 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 9B8AFC433DB for ; Thu, 4 Feb 2021 05:36:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4715D64F47 for ; Thu, 4 Feb 2021 05:36:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229609AbhBDFfn (ORCPT ); Thu, 4 Feb 2021 00:35:43 -0500 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:38827 "EHLO esa5.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229790AbhBDFfc (ORCPT ); Thu, 4 Feb 2021 00:35:32 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1612416931; x=1643952931; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=iJJFwG2gkbnbjw60ClRHydP01kI34Va6crHsBOaLVlg=; b=KEnr6P134Z4Qp/s2SRNFi5mK0tLVHr17m+FgzvBKIlt/v3dmoOPBAMja ZnkDiCcF58KXjBzHw+EfpH3+vKwtaFzWQv8M9W/ryiTXCTnaBx1iHiZfY ZccxYY7tOZZRJJmGQOSYuHLbvQ3tn50LCCpijMzXGXRlOipYF0VMyv8pk V2krB+iLpaLZOBWi6WHy2phjft09ym6tQCfhWnhXkmlK/G3d63ctOMV5V 3FHwkIsLUtuP+5EC1owi1lVH7wbjhzyH2ZCT5IRrPISZtfgnIQjj/MXp5 Zc9TYY4hhWMsQrfURflaesjLczV7lr6fdio1nfM+VLZ9jIUNrjOfBBjfH Q==; IronPort-SDR: fKfwEcZ5E/5Tyje9b8TjhYoILLgqYpkxi05PiI1fz0+8uHx+SwZO4tbcpKoKzCjQ8+IB7CMV1V yjeWXt+Xj7weoo3G4/IpuHN8S8m/myOr3CGXmsNuHpN+kdBiCDGvUynds8ws85h6J+eBJcqeBS cpXJRaMVJ8c6L2axSWKPfO6V6QWfrH/WB9mH4Adw8YS9NnDQIAt0hS2J2BK0JIC7A+6FGsAw6r 72pxieo26AcxZfomSbyAfDMiHrwxZ6PH+eIrWRCwM9c3j8RgrW8vQRw0IFIfGiqKFeC579v0SO jfA= X-IronPort-AV: E=Sophos;i="5.79,400,1602518400"; d="scan'208";a="159086449" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 04 Feb 2021 13:32:55 +0800 IronPort-SDR: QGKVbJ8XpEX2PGFHNPWSr5IuHvnbFVCZqtlw7FHZDZ7VT/wkFqwSRUIOp0Bu1geSn8YXvipj5k rcDPNMw8uFOmfy5nk2vqUsf8tsGzh6KvC4MYkXb0owWZzi297ejbP5l2L3CZ5rxL5ARdbd02Hl E4We6ESHI9VMZS6qzXT5b3tzAoO7NHOhE4vFSwcIzLSVRwxUVnfmsQzGbJPWfPva7yElpkt547 feZY2NJ9CalTDipmwdqxHbtzqZkJohOfwxRxhFJuRmU65pzwNeK74up+6wnEnzfx/GZi4SA4Kj ys9TWHmICGzawY5yi1/3t5tz Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 21:16:54 -0800 IronPort-SDR: 4R48TJ4/jE8aBRDzH1Bve/9tnQIAQY1hzu5HSv0ZaOglyETzd51vYvYkiNrKl5znvMCta/BT6S 4PNQQ1106jmLs63vgZ1ARujbRdG4YRHR8ZKY83MfEd8We+BXODBSthzWf/ieH/Fb2Kz18b+PWy gLchyCfdpYZJexMrtvAcs0msiz8d/w9NupwdzdCpN3XAc8ghOTsd9S3q4ttPAq1l9cMAFnyiN9 kVXh7g1qoV+VabhHIQ0FBd1iSwl/MvL/fFhhOe76XWTfU4JOpwA/9/TlQranVwVcrAEHcvDKbv 1sM= WDCIronportException: Internal Received: from cnf008142.ad.shared (HELO jedi-01.hgst.com) ([10.86.63.165]) by uls-op-cesaip02.wdc.com with ESMTP; 03 Feb 2021 21:32:55 -0800 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley Subject: [PATCH v2 5/6] RISC-V: Add SBI HSM extension in KVM Date: Wed, 3 Feb 2021 21:32:38 -0800 Message-Id: <20210204053239.1609558-6-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210204053239.1609558-1-atish.patra@wdc.com> References: <20210204053239.1609558-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 --- 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 4a405f583d32..881e89078785 100644 --- a/arch/riscv/include/asm/sbi.h +++ b/arch/riscv/include/asm/sbi.h @@ -106,6 +106,7 @@ enum sbi_srst_reset_reason { #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 302501295397..5627c9c7f249 100644 --- a/arch/riscv/kvm/Makefile +++ b/arch/riscv/kvm/Makefile @@ -11,5 +11,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 bcc4af9d2fa9..99f94ab27cea 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 e21ce1e69e03..20ef59ed83a6 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; }; @@ -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..ce6cfe125559 --- /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 = -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, +}; From patchwork Thu Feb 4 05:32:39 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Atish Patra X-Patchwork-Id: 12066327 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-16.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 18162C433E6 for ; Thu, 4 Feb 2021 05:36:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id CA85D64DF0 for ; Thu, 4 Feb 2021 05:36:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232239AbhBDFfr (ORCPT ); Thu, 4 Feb 2021 00:35:47 -0500 Received: from esa5.hgst.iphmx.com ([216.71.153.144]:38831 "EHLO esa5.hgst.iphmx.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S231767AbhBDFfd (ORCPT ); Thu, 4 Feb 2021 00:35:33 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=wdc.com; i=@wdc.com; q=dns/txt; s=dkim.wdc.com; t=1612416932; x=1643952932; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=hAGw3mc5c81wiYWE6AxTQ0aXDt7RC+LEa6RwXEaS5ec=; b=QusDtWaNKZhTVdbc+poNVDBzP6XdNq8m9pyN1zOWTNvbmADInKLW+Th2 o8mr59ewYNwbUgVk3UdDc5kUx7zJZb9QHRN13p7UCWG+BSCUPfMkJF6ey SvRKJjzliOrK1El2QSmHEJpVKYzu9p4+yn+G5sU1Hvv7UiZMXSbhTAXPE I7MUMbT1LQgn3pL/x47PM6/ixcRsIa7UPl3fjjEPHQs721o+okjT4zWEs /gyCyTz+gkpnrMpBggTp5UF8gqMxq5nq7KDlgZ0axYC1aqJhUZWm08UY9 M3/psvITBl738H/rKzwOwhEDkOyHHpwOVO9+mkz0W13VtE4twNa2c48+/ w==; IronPort-SDR: Ha8m41EzsbbtAn+2II8esIthTyks8Oc7JngHmyqcl/2CBTvIRg2JdGeV3u8QV0qow3JVISJbna VF+1PAe20kSiaqD+s55Kppp1caoRDLQsoggckJtGZDL+zIq4YJz0t35QAGejYQ2OqBLlM1KctB E+ZJjqjH6xougCLGryGGWEklUlGywrmJ7pkUdoljp8/Zew7pQbtwVU7PC6WD90zCgJsy6d1YxC NzvKjCiZL/PQhu023eOkMfpkwekYojUXzgzp7rL18EXWgWk+M7EbJWqSSjYblSuVo2FuDVzKha 6aQ= X-IronPort-AV: E=Sophos;i="5.79,400,1602518400"; d="scan'208";a="159086451" Received: from uls-op-cesaip01.wdc.com (HELO uls-op-cesaep01.wdc.com) ([199.255.45.14]) by ob1.hgst.iphmx.com with ESMTP; 04 Feb 2021 13:32:55 +0800 IronPort-SDR: amaC/XNSArn65TQ5yCVnsRhLNBsOWBIfHpcsjYrbLZuPNODWJz9f4nX+XRzcSMRniPSaLrBios gq9RZc66ImPJeQCEIpIj7kdxoN3kGabCrZAT9t4ixNfrecWpXAX/rqf6OyQwSPwqKPbfI/8Bd4 6D7Z7g4obpw9rHPy7FSsaMG7vYF+Oy6fu+NL9lGEu/d8aYK34XzEx0J0d0RSpyHuWRIvsUUzk2 IwjgK76IpmzIoNHi3FeTpk/BS0Y7PjYxhb5NpxCgibbYwiAEdFM7UoDqtAzyTJN0QJEhewQCdX 6l/R//hmTFP7vVu6iQMaPlWe Received: from uls-op-cesaip02.wdc.com ([10.248.3.37]) by uls-op-cesaep01.wdc.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 03 Feb 2021 21:16:55 -0800 IronPort-SDR: ObOo8zL6/WOxtdUYwrJVpJCxxHnhG5Dn0G/P4QVyky7k7hnsjmnjgCudZBupjhxWFenHBJO2LW d0DKvbeIZ6PLUZE6me+CW57MSnxdogA1bq4NGFVxoKR7n4gOF/FFUZX9L+B6e3XA7Ngwfcc+88 7nIBqNTgUeeKA98mbcdaT49+2W6mtwDR40xn2jzOt/+9hA+NsFHIfh882MoLxmoXOOVkEoFm4j cHNZzj3hmD2AL0J8NgWzM02Nu/izgk9erzRtSP83IW2ADxH5FmTSjYlFUeuTrk5805lFnV/USM s8Y= WDCIronportException: Internal Received: from cnf008142.ad.shared (HELO jedi-01.hgst.com) ([10.86.63.165]) by uls-op-cesaip02.wdc.com with ESMTP; 03 Feb 2021 21:32:55 -0800 From: Atish Patra To: linux-kernel@vger.kernel.org Cc: Atish Patra , Albert Ou , Anup Patel , Kefeng Wang , kvm-riscv@lists.infradead.org, kvm@vger.kernel.org, linux-riscv@lists.infradead.org, Palmer Dabbelt , Paul Walmsley Subject: [PATCH v2 6/6] RISC-V: Add SBI RESET extension in KVM Date: Wed, 3 Feb 2021 21:32:39 -0800 Message-Id: <20210204053239.1609558-7-atish.patra@wdc.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20210204053239.1609558-1-atish.patra@wdc.com> References: <20210204053239.1609558-1-atish.patra@wdc.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org SBI RESET extension allows OS to initiate a system wide reboot or shutdown. Implement the SBI RESET extension so that guests can issue shutdown/reset requests as well. Signed-off-by: Atish Patra --- arch/riscv/include/asm/kvm_vcpu_sbi.h | 1 + arch/riscv/kvm/vcpu_sbi.c | 17 +++++++++++ arch/riscv/kvm/vcpu_sbi_legacy.c | 17 +---------- arch/riscv/kvm/vcpu_sbi_replace.c | 44 +++++++++++++++++++++++++++ 4 files changed, 63 insertions(+), 16 deletions(-) diff --git a/arch/riscv/include/asm/kvm_vcpu_sbi.h b/arch/riscv/include/asm/kvm_vcpu_sbi.h index e208c8ac57fe..4f08bb45d8ce 100644 --- a/arch/riscv/include/asm/kvm_vcpu_sbi.h +++ b/arch/riscv/include/asm/kvm_vcpu_sbi.h @@ -29,4 +29,5 @@ struct kvm_vcpu_sbi_extension { 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); +void kvm_sbi_system_event(struct kvm_vcpu *vcpu, struct kvm_run *run, u32 type); #endif /* __RISCV_KVM_VCPU_SBI_H__ */ diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 20ef59ed83a6..858203b46700 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -38,6 +38,7 @@ 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; +extern const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst; static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { &vcpu_sbi_ext_legacy, @@ -46,8 +47,24 @@ static const struct kvm_vcpu_sbi_extension *sbi_ext[] = { &vcpu_sbi_ext_ipi, &vcpu_sbi_ext_rfence, &vcpu_sbi_ext_hsm, + &vcpu_sbi_ext_srst, }; +void kvm_sbi_system_event(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; +} + void kvm_riscv_vcpu_sbi_forward(struct kvm_vcpu *vcpu, struct kvm_run *run) { struct kvm_cpu_context *cp = &vcpu->arch.guest_context; diff --git a/arch/riscv/kvm/vcpu_sbi_legacy.c b/arch/riscv/kvm/vcpu_sbi_legacy.c index 126d97b1292d..9fd7ea386d5f 100644 --- a/arch/riscv/kvm/vcpu_sbi_legacy.c +++ b/arch/riscv/kvm/vcpu_sbi_legacy.c @@ -14,21 +14,6 @@ #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, @@ -83,7 +68,7 @@ static int kvm_sbi_ext_legacy_handler(struct kvm_vcpu *vcpu, struct kvm_run *run } break; case SBI_EXT_0_1_SHUTDOWN: - kvm_sbi_system_shutdown(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN); + kvm_sbi_system_event(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN); *exit = true; break; case SBI_EXT_0_1_REMOTE_FENCE_I: diff --git a/arch/riscv/kvm/vcpu_sbi_replace.c b/arch/riscv/kvm/vcpu_sbi_replace.c index dffb1930cada..7504e36ededb 100644 --- a/arch/riscv/kvm/vcpu_sbi_replace.c +++ b/arch/riscv/kvm/vcpu_sbi_replace.c @@ -134,3 +134,47 @@ const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_rfence = { .extid_end = SBI_EXT_RFENCE, .handler = kvm_sbi_ext_rfence_handler, }; + +static int kvm_sbi_ext_srst_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; + unsigned long reset_type = cp->a0; + unsigned long reset_reason = cp->a1; + unsigned long funcid = cp->a6; + + if (!cp) + return -EINVAL; + + if ((((u32)-1U) <= ((u64)reset_type)) || + (((u32)-1U) <= ((u64)reset_reason))) + return -EINVAL; + + if ((funcid != SBI_EXT_SRST_RESET) || + (reset_reason > SBI_SRST_RESET_REASON_SYS_FAILURE)) + ret = -EOPNOTSUPP; + + switch (reset_type) { + case SBI_SRST_RESET_TYPE_SHUTDOWN: + kvm_sbi_system_event(vcpu, run, KVM_SYSTEM_EVENT_SHUTDOWN); + *exit = true; + break; + case SBI_SRST_RESET_TYPE_COLD_REBOOT: + case SBI_SRST_RESET_TYPE_WARM_REBOOT: + kvm_sbi_system_event(vcpu, run, KVM_SYSTEM_EVENT_RESET); + *exit = true; + break; + default: + ret = -EOPNOTSUPP; + }; + + return ret; +} + +const struct kvm_vcpu_sbi_extension vcpu_sbi_ext_srst = { + .extid_start = SBI_EXT_SRST, + .extid_end = SBI_EXT_SRST, + .handler = kvm_sbi_ext_srst_handler, +};