Skip to content

Commit cb4f084

Browse files
committed
Merge tag 'kvm-riscv-fixes-5.17-1' of https://github.com/kvm-riscv/linux into HEAD
KVM/riscv fixes for 5.17, take #1 - Rework guest entry logic - Make CY, TM, and IR counters accessible in VU mode - Fix SBI implementation version
2 parents 8cfe148 + 4032715 commit cb4f084

File tree

2 files changed

+33
-18
lines changed

2 files changed

+33
-18
lines changed

arch/riscv/kvm/vcpu.c

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id)
9090
int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
9191
{
9292
struct kvm_cpu_context *cntx;
93+
struct kvm_vcpu_csr *reset_csr = &vcpu->arch.guest_reset_csr;
9394

9495
/* Mark this VCPU never ran */
9596
vcpu->arch.ran_atleast_once = false;
@@ -106,6 +107,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu)
106107
cntx->hstatus |= HSTATUS_SPVP;
107108
cntx->hstatus |= HSTATUS_SPV;
108109

110+
/* By default, make CY, TM, and IR counters accessible in VU mode */
111+
reset_csr->scounteren = 0x7;
112+
109113
/* Setup VCPU timer */
110114
kvm_riscv_vcpu_timer_init(vcpu);
111115

@@ -699,6 +703,20 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu)
699703
csr_write(CSR_HVIP, csr->hvip);
700704
}
701705

706+
/*
707+
* Actually run the vCPU, entering an RCU extended quiescent state (EQS) while
708+
* the vCPU is running.
709+
*
710+
* This must be noinstr as instrumentation may make use of RCU, and this is not
711+
* safe during the EQS.
712+
*/
713+
static void noinstr kvm_riscv_vcpu_enter_exit(struct kvm_vcpu *vcpu)
714+
{
715+
guest_state_enter_irqoff();
716+
__kvm_riscv_switch_to(&vcpu->arch);
717+
guest_state_exit_irqoff();
718+
}
719+
702720
int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
703721
{
704722
int ret;
@@ -790,9 +808,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
790808
continue;
791809
}
792810

793-
guest_enter_irqoff();
811+
guest_timing_enter_irqoff();
794812

795-
__kvm_riscv_switch_to(&vcpu->arch);
813+
kvm_riscv_vcpu_enter_exit(vcpu);
796814

797815
vcpu->mode = OUTSIDE_GUEST_MODE;
798816
vcpu->stat.exits++;
@@ -812,25 +830,21 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
812830
kvm_riscv_vcpu_sync_interrupts(vcpu);
813831

814832
/*
815-
* We may have taken a host interrupt in VS/VU-mode (i.e.
816-
* while executing the guest). This interrupt is still
817-
* pending, as we haven't serviced it yet!
833+
* We must ensure that any pending interrupts are taken before
834+
* we exit guest timing so that timer ticks are accounted as
835+
* guest time. Transiently unmask interrupts so that any
836+
* pending interrupts are taken.
818837
*
819-
* We're now back in HS-mode with interrupts disabled
820-
* so enabling the interrupts now will have the effect
821-
* of taking the interrupt again, in HS-mode this time.
838+
* There's no barrier which ensures that pending interrupts are
839+
* recognised, so we just hope that the CPU takes any pending
840+
* interrupts between the enable and disable.
822841
*/
823842
local_irq_enable();
843+
local_irq_disable();
824844

825-
/*
826-
* We do local_irq_enable() before calling guest_exit() so
827-
* that if a timer interrupt hits while running the guest
828-
* we account that tick as being spent in the guest. We
829-
* enable preemption after calling guest_exit() so that if
830-
* we get preempted we make sure ticks after that is not
831-
* counted as guest time.
832-
*/
833-
guest_exit();
845+
guest_timing_exit_irqoff();
846+
847+
local_irq_enable();
834848

835849
preempt_enable();
836850

arch/riscv/kvm/vcpu_sbi_base.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/errno.h>
1010
#include <linux/err.h>
1111
#include <linux/kvm_host.h>
12+
#include <linux/version.h>
1213
#include <asm/csr.h>
1314
#include <asm/sbi.h>
1415
#include <asm/kvm_vcpu_timer.h>
@@ -32,7 +33,7 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run,
3233
*out_val = KVM_SBI_IMPID;
3334
break;
3435
case SBI_EXT_BASE_GET_IMP_VERSION:
35-
*out_val = 0;
36+
*out_val = LINUX_VERSION_CODE;
3637
break;
3738
case SBI_EXT_BASE_PROBE_EXT:
3839
if ((cp->a0 >= SBI_EXT_EXPERIMENTAL_START &&

0 commit comments

Comments
 (0)