When KVM_ENABLE_VCPU_VLPI is enabled, vCPU vPEs are dynamically allocated and dislocated ad-hoc. vSGI direct injection requires receiving vCPUs to have vPEs, meaning we must couple vSGI enablement with vPE allocation to avoid injecting vSGIs to nonexistent vPEs.
Modify vgic_v4_configure_sgis() to validate whether a target vCPU has an assigned vPE before calling vgic_v4_enable_vsgis() on boot. Call vgic_v4_enable_vsgis() and vgic_v4_disable_vsgis() during vCPU vPE alloc and free within vLPI enablement and disablement functions.
Signed-off-by: Maximilian Dittgen mdittgen@amazon.de --- arch/arm64/kvm/vgic/vgic-v4.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kvm/vgic/vgic-v4.c b/arch/arm64/kvm/vgic/vgic-v4.c index b7dbc1789c90..5d6694d366b5 100644 --- a/arch/arm64/kvm/vgic/vgic-v4.c +++ b/arch/arm64/kvm/vgic/vgic-v4.c @@ -198,7 +198,7 @@ void vgic_v4_configure_vsgis(struct kvm *kvm) kvm_arm_halt_guest(kvm);
kvm_for_each_vcpu(i, vcpu, kvm) { - if (dist->nassgireq) + if (dist->nassgireq && kvm_vgic_query_vcpu_vlpi(vcpu) > 0) vgic_v4_enable_vsgis(vcpu); else vgic_v4_disable_vsgis(vcpu); @@ -838,6 +838,13 @@ int kvm_vgic_enable_vcpu_vlpi(struct kvm_vcpu *vcpu) if (ret) return ret;
+ /* Enable direct vSGIs */ + if (kvm_vgic_global_state.has_gicv4_1 && vcpu->kvm->arch.vgic.nassgireq) { + mutex_lock(&vcpu->kvm->arch.config_lock); + vgic_v4_enable_vsgis(vcpu); + mutex_unlock(&vcpu->kvm->arch.config_lock); + } + /* * Upgrade existing LPIs to vLPIs. We * do not need to error check since @@ -859,6 +866,8 @@ int kvm_vgic_disable_vcpu_vlpi(struct kvm_vcpu *vcpu)
downgrade_existing_vlpis_to_lpis(vcpu);
+ vgic_v4_disable_vsgis(vcpu); + return vgic_v4_vcpu_teardown(vcpu); }