Loading arch/riscv/kvm/vcpu.c +31 −17 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id) int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) { struct kvm_cpu_context *cntx; struct kvm_vcpu_csr *reset_csr = &vcpu->arch.guest_reset_csr; /* Mark this VCPU never ran */ vcpu->arch.ran_atleast_once = false; Loading @@ -106,6 +107,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) cntx->hstatus |= HSTATUS_SPVP; cntx->hstatus |= HSTATUS_SPV; /* By default, make CY, TM, and IR counters accessible in VU mode */ reset_csr->scounteren = 0x7; /* Setup VCPU timer */ kvm_riscv_vcpu_timer_init(vcpu); Loading Loading @@ -699,6 +703,20 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu) csr_write(CSR_HVIP, csr->hvip); } /* * Actually run the vCPU, entering an RCU extended quiescent state (EQS) while * the vCPU is running. * * 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) { guest_state_enter_irqoff(); __kvm_riscv_switch_to(&vcpu->arch); guest_state_exit_irqoff(); } int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) { int ret; Loading Loading @@ -790,9 +808,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) continue; } guest_enter_irqoff(); guest_timing_enter_irqoff(); __kvm_riscv_switch_to(&vcpu->arch); kvm_riscv_vcpu_enter_exit(vcpu); vcpu->mode = OUTSIDE_GUEST_MODE; vcpu->stat.exits++; Loading @@ -812,25 +830,21 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) kvm_riscv_vcpu_sync_interrupts(vcpu); /* * We may have taken a host interrupt in VS/VU-mode (i.e. * while executing the guest). This interrupt is still * pending, as we haven't serviced it yet! * We must ensure that any pending interrupts are taken before * we exit guest timing so that timer ticks are accounted as * guest time. Transiently unmask interrupts so that any * pending interrupts are taken. * * We're now back in HS-mode with interrupts disabled * so enabling the interrupts now will have the effect * of taking the interrupt again, in HS-mode this time. * There's no barrier which ensures that pending interrupts are * recognised, so we just hope that the CPU takes any pending * interrupts between the enable and disable. */ local_irq_enable(); local_irq_disable(); /* * We do local_irq_enable() before calling guest_exit() so * that if a timer interrupt hits while running the guest * we account that tick as being spent in the guest. We * enable preemption after calling guest_exit() so that if * we get preempted we make sure ticks after that is not * counted as guest time. */ guest_exit(); guest_timing_exit_irqoff(); local_irq_enable(); preempt_enable(); Loading arch/riscv/kvm/vcpu_sbi_base.c +2 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/kvm_host.h> #include <linux/version.h> #include <asm/csr.h> #include <asm/sbi.h> #include <asm/kvm_vcpu_timer.h> Loading @@ -32,7 +33,7 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, *out_val = KVM_SBI_IMPID; break; case SBI_EXT_BASE_GET_IMP_VERSION: *out_val = 0; *out_val = LINUX_VERSION_CODE; break; case SBI_EXT_BASE_PROBE_EXT: if ((cp->a0 >= SBI_EXT_EXPERIMENTAL_START && Loading Loading
arch/riscv/kvm/vcpu.c +31 −17 Original line number Diff line number Diff line Loading @@ -90,6 +90,7 @@ int kvm_arch_vcpu_precreate(struct kvm *kvm, unsigned int id) int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) { struct kvm_cpu_context *cntx; struct kvm_vcpu_csr *reset_csr = &vcpu->arch.guest_reset_csr; /* Mark this VCPU never ran */ vcpu->arch.ran_atleast_once = false; Loading @@ -106,6 +107,9 @@ int kvm_arch_vcpu_create(struct kvm_vcpu *vcpu) cntx->hstatus |= HSTATUS_SPVP; cntx->hstatus |= HSTATUS_SPV; /* By default, make CY, TM, and IR counters accessible in VU mode */ reset_csr->scounteren = 0x7; /* Setup VCPU timer */ kvm_riscv_vcpu_timer_init(vcpu); Loading Loading @@ -699,6 +703,20 @@ static void kvm_riscv_update_hvip(struct kvm_vcpu *vcpu) csr_write(CSR_HVIP, csr->hvip); } /* * Actually run the vCPU, entering an RCU extended quiescent state (EQS) while * the vCPU is running. * * 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) { guest_state_enter_irqoff(); __kvm_riscv_switch_to(&vcpu->arch); guest_state_exit_irqoff(); } int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) { int ret; Loading Loading @@ -790,9 +808,9 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) continue; } guest_enter_irqoff(); guest_timing_enter_irqoff(); __kvm_riscv_switch_to(&vcpu->arch); kvm_riscv_vcpu_enter_exit(vcpu); vcpu->mode = OUTSIDE_GUEST_MODE; vcpu->stat.exits++; Loading @@ -812,25 +830,21 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) kvm_riscv_vcpu_sync_interrupts(vcpu); /* * We may have taken a host interrupt in VS/VU-mode (i.e. * while executing the guest). This interrupt is still * pending, as we haven't serviced it yet! * We must ensure that any pending interrupts are taken before * we exit guest timing so that timer ticks are accounted as * guest time. Transiently unmask interrupts so that any * pending interrupts are taken. * * We're now back in HS-mode with interrupts disabled * so enabling the interrupts now will have the effect * of taking the interrupt again, in HS-mode this time. * There's no barrier which ensures that pending interrupts are * recognised, so we just hope that the CPU takes any pending * interrupts between the enable and disable. */ local_irq_enable(); local_irq_disable(); /* * We do local_irq_enable() before calling guest_exit() so * that if a timer interrupt hits while running the guest * we account that tick as being spent in the guest. We * enable preemption after calling guest_exit() so that if * we get preempted we make sure ticks after that is not * counted as guest time. */ guest_exit(); guest_timing_exit_irqoff(); local_irq_enable(); preempt_enable(); Loading
arch/riscv/kvm/vcpu_sbi_base.c +2 −1 Original line number Diff line number Diff line Loading @@ -9,6 +9,7 @@ #include <linux/errno.h> #include <linux/err.h> #include <linux/kvm_host.h> #include <linux/version.h> #include <asm/csr.h> #include <asm/sbi.h> #include <asm/kvm_vcpu_timer.h> Loading @@ -32,7 +33,7 @@ static int kvm_sbi_ext_base_handler(struct kvm_vcpu *vcpu, struct kvm_run *run, *out_val = KVM_SBI_IMPID; break; case SBI_EXT_BASE_GET_IMP_VERSION: *out_val = 0; *out_val = LINUX_VERSION_CODE; break; case SBI_EXT_BASE_PROBE_EXT: if ((cp->a0 >= SBI_EXT_EXPERIMENTAL_START && Loading