Re: [RFC PATCH v2 07/19] RISC-V: KVM: Implement KVM_GET_ONE_REG/KVM_SET_ONE_REG ioctls

From: Anup Patel
Date: Mon Aug 05 2019 - 02:55:36 EST


On Fri, Aug 2, 2019 at 2:33 PM Paolo Bonzini <pbonzini@xxxxxxxxxx> wrote:
>
> On 02/08/19 09:47, Anup Patel wrote:
> > + if (reg_num == KVM_REG_RISCV_CSR_REG(sip))
> > + kvm_riscv_vcpu_flush_interrupts(vcpu, false);
>
> Not updating the vsip CSR here can cause an interrupt to be lost, if the
> next call to kvm_riscv_vcpu_flush_interrupts finds a zero mask.

Thanks for catching this issue. I will address it in v3.

If we think more on similar lines then we also need to handle the case
where Guest VCPU had pending interrupts and we suddenly stopped it
for Guest migration. In this case, we would eventually use SET_ONE_REG
ioctl on destination Host which should set vsip_shadow instead of vsip so
that we force update HW after resuming Guest VCPU on destination host.

>
> You could add a new field vcpu->vsip_shadow that is updated every time
> CSR_VSIP is written (including kvm_arch_vcpu_load) with a function like
>
> void kvm_riscv_update_vsip(struct kvm_vcpu *vcpu)
> {
> if (vcpu->vsip_shadow != vcpu->arch.guest_csr.vsip) {
> csr_write(CSR_VSIP, vcpu->arch.guest_csr.vsip);
> vcpu->vsip_shadow = vcpu->arch.guest_csr.vsip;
> }
> }
>
> And just call this unconditionally from kvm_vcpu_ioctl_run. The cost is
> just a memory load per VS-mode entry, it should hardly be measurable.
>

I think we can do this at start of kvm_riscv_vcpu_flush_interrupts() as well.

Regards,
Anup