From patchwork Thu Apr 18 14:26:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= X-Patchwork-Id: 1925072 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=lists.infradead.org header.i=@lists.infradead.org header.a=rsa-sha256 header.s=bombadil.20210309 header.b=0Jzm+UR6; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.a=rsa-sha256 header.s=20230601 header.b=1KRAWWUQ; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.infradead.org (client-ip=2607:7c80:54:3::133; helo=bombadil.infradead.org; envelope-from=kvm-riscv-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org; receiver=patchwork.ozlabs.org) Received: from bombadil.infradead.org (bombadil.infradead.org [IPv6:2607:7c80:54:3::133]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4VL0VN00Wcz1ymh for ; Fri, 19 Apr 2024 00:27:39 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=8Rq4sqhvcCEVhDNQuS+yMJnN+XS7NMNTmU24pbmlFbQ=; b=0Jzm+UR63QroUI eImN7U6WjytjYvg/3Lx7xOgkEVz++31wWcaTkPP486bU5F/1egrXljnpcrS5fpzo/juw/HSkHkmM9 ada0SlDBxznVwFBOi+CrjirIY5RKfMjVi/+nVnZE+6IaWuIYRJQZQgMF61WOZX5dWecNjEanjGn2y 75PFzit/4r1ndY/scVSIOFGNgTuHivXYlh1Vdt9oww5Q8UH0LP8aTxeSeW1WsJIPM2MY2gfq7p/i/ UJOxJbSCCHOnqXCeWG61fPk6LWRD9HkmgFJsQMVl5yQKCKtqEXRG+b6slDw1K4cAajZU/diAvpKkj xpACh3ekrWi6iHJE3JBw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1rxSji-00000002cei-1xxt; Thu, 18 Apr 2024 14:27:38 +0000 Received: from mail-wr1-f49.google.com ([209.85.221.49]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1rxSjQ-00000002cXy-3KrW for kvm-riscv@lists.infradead.org; Thu, 18 Apr 2024 14:27:28 +0000 Received: by mail-wr1-f49.google.com with SMTP id ffacd0b85a97d-349bd110614so164255f8f.3 for ; Thu, 18 Apr 2024 07:27:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1713450437; x=1714055237; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ux6Z0dvHS0AaHNoD8WJhlnEKIxWvWWXWdBe+6rPnELc=; b=1KRAWWUQeZvdXssoSeEqxlbXWdYKtBY069p++k346MVhpI2Sc6hRMlHgLzVOz+95kt ySdaGQK15SAOJMspJaI44+IrsLJscvS9QekK10o6J0U7T6bD8jI8UAxBK1Sg+V+S1nva mZ+WB886dTzRFR0mJIiW9Km886CHqFm4hrIRmYtN5xr5s3BRPNViDVC3pD1MA5w8K6tE 6wI2STGRZnlT/L69C1xN5y72nsEjm+x7zF7SDsGMiHqr2nut76wMNqhE2zWxIHrENRHs R79Gd7DYzNnVI3Cu4/re7k+/ngQGsyv9voE8RrVBWskr6diaom7PnnRfU0v7XV1f94Ur LAzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1713450437; x=1714055237; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ux6Z0dvHS0AaHNoD8WJhlnEKIxWvWWXWdBe+6rPnELc=; b=L91UEeo2WpllX5VhS//UZK4yz4atbA8S9jnpas7KXUXld6AlOFOCarCrTgWzv1xjGS Un8MSH2VUzBLaYzy0ASBhRR3dQs7WMcBUTq8Z8lyM76sYe4FlUtZK7F+d4WoFb/h1BaB BpK+VwjFhzKUgOgbRIKEo07aqWKT1UevW1KXkMiD0SSQ+jXlFcrg251nIJuySLFa9LMN cFWVJJw+o+Qyd4ihdz3V6guRsNjVSqdgE35M+h1plEvxBLQxCmsvnq3itEsyOgft4B3F PN1BhJTcCVuGuq5kTDibGU9t+vc0my/c87hk7SahGrF7jGCD48QN80X9M62dzvUdy1IV ZR/Q== X-Forwarded-Encrypted: i=1; AJvYcCU6cx++CXAA6GIqz6TCa9irN3/HHvdkH3fImesmW/rGF0lF6FZPj7d/g/kXNWGxZPJmveoWyNTa8jp14CQrD67Hk52wLAfETjvdELIfPQ== X-Gm-Message-State: AOJu0Yzkyy9b7mxi9dY7GAQGfvsTJMDdigty6ZQYjUoJHSCPkW4EB/pG Gq+fHOmTul7uHybUIinOW8BnuUQH/HkuDLtBawQMACpPfoc8euWfH3uER8qnpW0= X-Google-Smtp-Source: AGHT+IGBKkRXPRGYPrNf2xynAaVp5CuMPioqb/sz3tcbUIZ90ojHCdGDsQ+aqJS0cvtdtDhHjXauZw== X-Received: by 2002:a05:600c:5101:b0:416:a773:7d18 with SMTP id o1-20020a05600c510100b00416a7737d18mr2062486wms.0.1713450437373; Thu, 18 Apr 2024 07:27:17 -0700 (PDT) Received: from carbon-x1.. ([2a01:e0a:999:a3a0:7b64:4d1d:16d8:e38b]) by smtp.gmail.com with ESMTPSA id v10-20020a05600c470a00b00418a386c059sm2873645wmo.42.2024.04.18.07.27.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 18 Apr 2024 07:27:16 -0700 (PDT) From: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= To: Conor Dooley , Rob Herring , Krzysztof Kozlowski , Paul Walmsley , Palmer Dabbelt , Albert Ou , Anup Patel , Atish Patra Cc: =?utf-8?b?Q2zDqW1lbnQgTMOpZ2Vy?= , linux-riscv@lists.infradead.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, kvm@vger.kernel.org, kvm-riscv@lists.infradead.org, Ved Shanbhogue Subject: [RFC PATCH 7/7] RISC-V: KVM: add support for double trap exception Date: Thu, 18 Apr 2024 16:26:46 +0200 Message-ID: <20240418142701.1493091-8-cleger@rivosinc.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20240418142701.1493091-1-cleger@rivosinc.com> References: <20240418142701.1493091-1-cleger@rivosinc.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240418_072721_037099_39E20899 X-CRM114-Status: GOOD ( 19.32 ) X-Spam-Score: -0.0 (/) X-Spam-Report: Spam detection software, running on the system "bombadil.infradead.org", has NOT identified this incoming email as spam. The original message has been attached to this so you can view it or label similar future email. If you have any questions, see the administrator of that system for details. Content preview: When a double trap exception is generated from VS-mode, it should be delivered to M-mode which might redirect it to S-mode. Currently, the kvm double trap exception handling simply prints an error and [...] Content analysis details: (-0.0 points, 5.0 required) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, no trust [209.85.221.49 listed in list.dnswl.org] 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record -0.0 SPF_PASS SPF: sender matches SPF record -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature 0.1 DKIM_SIGNED Message has a DKIM or DK signature, not necessarily valid -0.0 RCVD_IN_MSPIKE_H2 RBL: Average reputation (+2) [209.85.221.49 listed in wl.mailspike.net] X-BeenThere: kvm-riscv@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "kvm-riscv" Errors-To: kvm-riscv-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org When a double trap exception is generated from VS-mode, it should be delivered to M-mode which might redirect it to S-mode. Currently, the kvm double trap exception handling simply prints an error and returns -EOPNOTSUPP to stop VM execution. In future, this might use KVM SBI SSE extension implementation to actually send an SSE event to the guest VM. Signed-off-by: Clément Léger --- arch/riscv/include/asm/kvm_host.h | 7 ++++--- arch/riscv/include/uapi/asm/kvm.h | 1 + arch/riscv/kvm/vcpu.c | 23 +++++++++------------ arch/riscv/kvm/vcpu_exit.c | 33 +++++++++++++++++++++++++------ arch/riscv/kvm/vcpu_insn.c | 15 +++++--------- arch/riscv/kvm/vcpu_onereg.c | 2 ++ arch/riscv/kvm/vcpu_sbi.c | 4 +--- arch/riscv/kvm/vcpu_switch.S | 19 +++++++++++++++--- 8 files changed, 65 insertions(+), 39 deletions(-) diff --git a/arch/riscv/include/asm/kvm_host.h b/arch/riscv/include/asm/kvm_host.h index be60aaa07f57..1d699bf44c45 100644 --- a/arch/riscv/include/asm/kvm_host.h +++ b/arch/riscv/include/asm/kvm_host.h @@ -358,12 +358,13 @@ unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu, bool read_insn, unsigned long guest_addr, struct kvm_cpu_trap *trap); -void kvm_riscv_vcpu_trap_redirect(struct kvm_vcpu *vcpu, - struct kvm_cpu_trap *trap); +int kvm_riscv_vcpu_trap_redirect(struct kvm_vcpu *vcpu, + struct kvm_cpu_trap *trap); int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, struct kvm_cpu_trap *trap); -void __kvm_riscv_switch_to(struct kvm_vcpu_arch *vcpu_arch); +void __kvm_riscv_switch_to(struct kvm_vcpu_arch *vcpu_arch, + struct kvm_cpu_trap *trap); void kvm_riscv_vcpu_setup_isa(struct kvm_vcpu *vcpu); unsigned long kvm_riscv_vcpu_num_regs(struct kvm_vcpu *vcpu); diff --git a/arch/riscv/include/uapi/asm/kvm.h b/arch/riscv/include/uapi/asm/kvm.h index fa3097da91c0..323f4e8380d2 100644 --- a/arch/riscv/include/uapi/asm/kvm.h +++ b/arch/riscv/include/uapi/asm/kvm.h @@ -166,6 +166,7 @@ enum KVM_RISCV_ISA_EXT_ID { KVM_RISCV_ISA_EXT_ZVFH, KVM_RISCV_ISA_EXT_ZVFHMIN, KVM_RISCV_ISA_EXT_ZFA, + KVM_RISCV_ISA_EXT_SSDBLTRP, KVM_RISCV_ISA_EXT_MAX, }; diff --git a/arch/riscv/kvm/vcpu.c b/arch/riscv/kvm/vcpu.c index 461ef60d4eda..89e663defe14 100644 --- a/arch/riscv/kvm/vcpu.c +++ b/arch/riscv/kvm/vcpu.c @@ -121,6 +121,8 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) /* Setup reset state of shadow SSTATUS and HSTATUS CSRs */ cntx = &vcpu->arch.guest_reset_context; cntx->sstatus = SR_SPP | SR_SPIE; + if (riscv_isa_extension_available(vcpu->arch.isa, SSDBLTRP)) + cntx->sstatus |= SR_SDT; cntx->hstatus = 0; cntx->hstatus |= HSTATUS_VTW; cntx->hstatus |= HSTATUS_SPVP; @@ -579,6 +581,9 @@ void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu) csr->hvip = csr_read(CSR_HVIP); csr->vsatp = csr_read(CSR_VSATP); cfg->hedeleg = csr_read(CSR_HEDELEG); + cfg->henvcfg = csr_read(CSR_HENVCFG); + if (IS_ENABLED(CONFIG_32BIT)) + cfg->henvcfg = csr_read(CSR_HENVCFGH) << 32; } static void kvm_riscv_check_vcpu_requests(struct kvm_vcpu *vcpu) @@ -670,11 +675,12 @@ static __always_inline void kvm_riscv_vcpu_swap_in_host_state(struct kvm_vcpu *v * This must be noinstr as instrumentation may make use of RCU, and this is not * safe during the EQS. */ -static void noinstr kvm_riscv_vcpu_enter_exit(struct kvm_vcpu *vcpu) +static void noinstr kvm_riscv_vcpu_enter_exit(struct kvm_vcpu *vcpu, + struct kvm_cpu_trap *trap) { kvm_riscv_vcpu_swap_in_guest_state(vcpu); guest_state_enter_irqoff(); - __kvm_riscv_switch_to(&vcpu->arch); + __kvm_riscv_switch_to(&vcpu->arch, trap); vcpu->arch.last_exit_cpu = vcpu->cpu; guest_state_exit_irqoff(); kvm_riscv_vcpu_swap_in_host_state(vcpu); @@ -789,22 +795,11 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) guest_timing_enter_irqoff(); - kvm_riscv_vcpu_enter_exit(vcpu); + kvm_riscv_vcpu_enter_exit(vcpu, &trap); vcpu->mode = OUTSIDE_GUEST_MODE; vcpu->stat.exits++; - /* - * Save SCAUSE, STVAL, HTVAL, and HTINST because we might - * get an interrupt between __kvm_riscv_switch_to() and - * local_irq_enable() which can potentially change CSRs. - */ - trap.sepc = vcpu->arch.guest_context.sepc; - trap.scause = csr_read(CSR_SCAUSE); - trap.stval = csr_read(CSR_STVAL); - trap.htval = csr_read(CSR_HTVAL); - trap.htinst = csr_read(CSR_HTINST); - /* Syncup interrupts state with HW */ kvm_riscv_vcpu_sync_interrupts(vcpu); diff --git a/arch/riscv/kvm/vcpu_exit.c b/arch/riscv/kvm/vcpu_exit.c index 2415722c01b8..892c6df97eaf 100644 --- a/arch/riscv/kvm/vcpu_exit.c +++ b/arch/riscv/kvm/vcpu_exit.c @@ -126,17 +126,34 @@ unsigned long kvm_riscv_vcpu_unpriv_read(struct kvm_vcpu *vcpu, return val; } +static int kvm_riscv_double_trap(struct kvm_vcpu *vcpu, + struct kvm_cpu_trap *trap) +{ + pr_err("Guest double trap"); + /* TODO: Implement SSE support */ + + return -EOPNOTSUPP; +} + /** * kvm_riscv_vcpu_trap_redirect -- Redirect trap to Guest * * @vcpu: The VCPU pointer * @trap: Trap details */ -void kvm_riscv_vcpu_trap_redirect(struct kvm_vcpu *vcpu, - struct kvm_cpu_trap *trap) +int kvm_riscv_vcpu_trap_redirect(struct kvm_vcpu *vcpu, + struct kvm_cpu_trap *trap) { unsigned long vsstatus = csr_read(CSR_VSSTATUS); + if (riscv_isa_extension_available(vcpu->arch.isa, SSDBLTRP)) { + if (vsstatus & SR_SDT) + return kvm_riscv_double_trap(vcpu, trap); + + /* Set Double Trap bit to enable double trap detection */ + vsstatus |= SR_SDT; + } + /* Change Guest SSTATUS.SPP bit */ vsstatus &= ~SR_SPP; if (vcpu->arch.guest_context.sstatus & SR_SPP) @@ -163,6 +180,8 @@ void kvm_riscv_vcpu_trap_redirect(struct kvm_vcpu *vcpu, /* Set Guest privilege mode to supervisor */ vcpu->arch.guest_context.sstatus |= SR_SPP; + + return 1; } /* @@ -185,10 +204,8 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, case EXC_INST_ILLEGAL: case EXC_LOAD_MISALIGNED: case EXC_STORE_MISALIGNED: - if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV) { - kvm_riscv_vcpu_trap_redirect(vcpu, trap); - ret = 1; - } + if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV) + ret = kvm_riscv_vcpu_trap_redirect(vcpu, trap); break; case EXC_VIRTUAL_INST_FAULT: if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV) @@ -204,6 +221,10 @@ int kvm_riscv_vcpu_exit(struct kvm_vcpu *vcpu, struct kvm_run *run, if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV) ret = kvm_riscv_vcpu_sbi_ecall(vcpu, run); break; + case EXC_DOUBLE_TRAP: + if (vcpu->arch.guest_context.hstatus & HSTATUS_SPV) + ret = kvm_riscv_double_trap(vcpu, trap); + break; default: break; } diff --git a/arch/riscv/kvm/vcpu_insn.c b/arch/riscv/kvm/vcpu_insn.c index 7a6abed41bc1..050e811204f2 100644 --- a/arch/riscv/kvm/vcpu_insn.c +++ b/arch/riscv/kvm/vcpu_insn.c @@ -159,9 +159,8 @@ static int truly_illegal_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, utrap.stval = insn; utrap.htval = 0; utrap.htinst = 0; - kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); - return 1; + return kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); } static int truly_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, @@ -175,9 +174,8 @@ static int truly_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, utrap.stval = insn; utrap.htval = 0; utrap.htinst = 0; - kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); - return 1; + return kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); } /** @@ -422,8 +420,7 @@ int kvm_riscv_vcpu_virtual_insn(struct kvm_vcpu *vcpu, struct kvm_run *run, &utrap); if (utrap.scause) { utrap.sepc = ct->sepc; - kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); - return 1; + return kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); } } if (INSN_IS_16BIT(insn)) @@ -478,8 +475,7 @@ int kvm_riscv_vcpu_mmio_load(struct kvm_vcpu *vcpu, struct kvm_run *run, if (utrap.scause) { /* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc; - kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); - return 1; + return kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); } insn_len = INSN_LEN(insn); } @@ -604,8 +600,7 @@ int kvm_riscv_vcpu_mmio_store(struct kvm_vcpu *vcpu, struct kvm_run *run, if (utrap.scause) { /* Redirect trap if we failed to read instruction */ utrap.sepc = ct->sepc; - kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); - return 1; + return kvm_riscv_vcpu_trap_redirect(vcpu, &utrap); } insn_len = INSN_LEN(insn); } diff --git a/arch/riscv/kvm/vcpu_onereg.c b/arch/riscv/kvm/vcpu_onereg.c index 5f7355e96008..fece0043871c 100644 --- a/arch/riscv/kvm/vcpu_onereg.c +++ b/arch/riscv/kvm/vcpu_onereg.c @@ -36,6 +36,7 @@ static const unsigned long kvm_isa_ext_arr[] = { /* Multi letter extensions (alphabetically sorted) */ KVM_ISA_EXT_ARR(SMSTATEEN), KVM_ISA_EXT_ARR(SSAIA), + KVM_ISA_EXT_ARR(SSDBLTRP), KVM_ISA_EXT_ARR(SSTC), KVM_ISA_EXT_ARR(SVINVAL), KVM_ISA_EXT_ARR(SVNAPOT), @@ -153,6 +154,7 @@ static bool kvm_riscv_vcpu_isa_disable_allowed(unsigned long ext) case KVM_RISCV_ISA_EXT_ZVKSED: case KVM_RISCV_ISA_EXT_ZVKSH: case KVM_RISCV_ISA_EXT_ZVKT: + case KVM_RISCV_ISA_EXT_SSDBLTRP: return false; /* Extensions which can be disabled using Smstateen */ case KVM_RISCV_ISA_EXT_SSAIA: diff --git a/arch/riscv/kvm/vcpu_sbi.c b/arch/riscv/kvm/vcpu_sbi.c index 76901f0f34b7..b839d578dc26 100644 --- a/arch/riscv/kvm/vcpu_sbi.c +++ b/arch/riscv/kvm/vcpu_sbi.c @@ -456,10 +456,8 @@ int kvm_riscv_vcpu_sbi_ecall(struct kvm_vcpu *vcpu, struct kvm_run *run) /* Handle special error cases i.e trap, exit or userspace forward */ if (sbi_ret.utrap->scause) { - /* No need to increment sepc or exit ioctl loop */ - ret = 1; sbi_ret.utrap->sepc = cp->sepc; - kvm_riscv_vcpu_trap_redirect(vcpu, sbi_ret.utrap); + ret = kvm_riscv_vcpu_trap_redirect(vcpu, sbi_ret.utrap); next_sepc = false; goto ecall_done; } diff --git a/arch/riscv/kvm/vcpu_switch.S b/arch/riscv/kvm/vcpu_switch.S index 0c26189aa01c..94d5eb9da788 100644 --- a/arch/riscv/kvm/vcpu_switch.S +++ b/arch/riscv/kvm/vcpu_switch.S @@ -154,7 +154,6 @@ SYM_FUNC_START(__kvm_riscv_switch_to) REG_L t2, (KVM_ARCH_HOST_SSCRATCH)(a0) REG_L t3, (KVM_ARCH_HOST_SCOUNTEREN)(a0) REG_L t4, (KVM_ARCH_HOST_HSTATUS)(a0) - REG_L t5, (KVM_ARCH_HOST_SSTATUS)(a0) /* Save Guest SEPC */ csrr t0, CSR_SEPC @@ -171,8 +170,8 @@ SYM_FUNC_START(__kvm_riscv_switch_to) /* Save Guest and Restore Host HSTATUS */ csrrw t4, CSR_HSTATUS, t4 - /* Save Guest and Restore Host SSTATUS */ - csrrw t5, CSR_SSTATUS, t5 + /* Save Guest SSTATUS */ + csrr t5, CSR_SSTATUS /* Store Guest CSR values */ REG_S t0, (KVM_ARCH_GUEST_SEPC)(a0) @@ -206,6 +205,20 @@ SYM_FUNC_START(__kvm_riscv_switch_to) REG_L s10, (KVM_ARCH_HOST_S10)(a0) REG_L s11, (KVM_ARCH_HOST_S11)(a0) + csrr t1, CSR_SCAUSE + csrr t2, CSR_STVAL + csrr t3, CSR_HTVAL + csrr t4, CSR_HTINST + REG_S t0, (KVM_ARCH_TRAP_SEPC)(a1) + REG_S t1, (KVM_ARCH_TRAP_SCAUSE)(a1) + REG_S t2, (KVM_ARCH_TRAP_STVAL)(a1) + REG_S t3, (KVM_ARCH_TRAP_HTVAL)(a1) + REG_S t4, (KVM_ARCH_TRAP_HTINST)(a1) + + /* Restore Host SSTATUS */ + REG_L t5, (KVM_ARCH_HOST_SSTATUS)(a0) + csrw CSR_SSTATUS, t5 + /* Return to C code */ ret SYM_FUNC_END(__kvm_riscv_switch_to)