mirror of
https://github.com/torvalds/linux.git
synced 2026-03-08 03:44:45 +01:00
KVM: arm64: Disambiguate support for vSGIs v. vLPIs
vgic_supports_direct_msis() is a bit of a misnomer, as it returns true if either vSGIs or vLPIs are supported. Pick it apart into a few predicates and replace some open-coded checks for vSGIs, including an opportunistic fix to always check if the CPUIF is capable of handling vSGIs. Reviewed-by: Marc Zyngier <maz@kernel.org> Link: https://lore.kernel.org/r/20250724062805.2658919-2-oliver.upton@linux.dev Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
This commit is contained in:
parent
86731a2a65
commit
82221a4e66
5 changed files with 25 additions and 15 deletions
|
|
@ -391,11 +391,10 @@ int vgic_init(struct kvm *kvm)
|
|||
goto out;
|
||||
|
||||
/*
|
||||
* If we have GICv4.1 enabled, unconditionally request enable the
|
||||
* v4 support so that we get HW-accelerated vSGIs. Otherwise, only
|
||||
* enable it if we present a virtual ITS to the guest.
|
||||
* Ensure vPEs are allocated if direct IRQ injection (e.g. vSGIs,
|
||||
* vLPIs) is supported.
|
||||
*/
|
||||
if (vgic_supports_direct_msis(kvm)) {
|
||||
if (vgic_supports_direct_irqs(kvm)) {
|
||||
ret = vgic_v4_init(kvm);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
|
@ -443,7 +442,7 @@ static void kvm_vgic_dist_destroy(struct kvm *kvm)
|
|||
dist->vgic_cpu_base = VGIC_ADDR_UNDEF;
|
||||
}
|
||||
|
||||
if (vgic_supports_direct_msis(kvm))
|
||||
if (vgic_supports_direct_irqs(kvm))
|
||||
vgic_v4_teardown(kvm);
|
||||
|
||||
xa_destroy(&dist->lpi_xa);
|
||||
|
|
|
|||
|
|
@ -50,8 +50,12 @@ bool vgic_has_its(struct kvm *kvm)
|
|||
|
||||
bool vgic_supports_direct_msis(struct kvm *kvm)
|
||||
{
|
||||
return (kvm_vgic_global_state.has_gicv4_1 ||
|
||||
(kvm_vgic_global_state.has_gicv4 && vgic_has_its(kvm)));
|
||||
return kvm_vgic_global_state.has_gicv4 && vgic_has_its(kvm);
|
||||
}
|
||||
|
||||
bool vgic_supports_direct_sgis(struct kvm *kvm)
|
||||
{
|
||||
return kvm_vgic_global_state.has_gicv4_1 && gic_cpuif_has_vsgi();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -86,7 +90,7 @@ static unsigned long vgic_mmio_read_v3_misc(struct kvm_vcpu *vcpu,
|
|||
}
|
||||
break;
|
||||
case GICD_TYPER2:
|
||||
if (kvm_vgic_global_state.has_gicv4_1 && gic_cpuif_has_vsgi())
|
||||
if (vgic_supports_direct_sgis(vcpu->kvm))
|
||||
value = GICD_TYPER2_nASSGIcap;
|
||||
break;
|
||||
case GICD_IIDR:
|
||||
|
|
@ -119,7 +123,7 @@ static void vgic_mmio_write_v3_misc(struct kvm_vcpu *vcpu,
|
|||
dist->enabled = val & GICD_CTLR_ENABLE_SS_G1;
|
||||
|
||||
/* Not a GICv4.1? No HW SGIs */
|
||||
if (!kvm_vgic_global_state.has_gicv4_1 || !gic_cpuif_has_vsgi())
|
||||
if (!vgic_supports_direct_sgis(vcpu->kvm))
|
||||
val &= ~GICD_CTLR_nASSGIreq;
|
||||
|
||||
/* Dist stays enabled? nASSGIreq is RO */
|
||||
|
|
@ -133,7 +137,7 @@ static void vgic_mmio_write_v3_misc(struct kvm_vcpu *vcpu,
|
|||
if (is_hwsgi != dist->nassgireq)
|
||||
vgic_v4_configure_vsgis(vcpu->kvm);
|
||||
|
||||
if (kvm_vgic_global_state.has_gicv4_1 &&
|
||||
if (vgic_supports_direct_sgis(vcpu->kvm) &&
|
||||
was_enabled != dist->enabled)
|
||||
kvm_make_all_cpus_request(vcpu->kvm, KVM_REQ_RELOAD_GICv4);
|
||||
else if (!was_enabled && dist->enabled)
|
||||
|
|
@ -178,7 +182,7 @@ static int vgic_mmio_uaccess_write_v3_misc(struct kvm_vcpu *vcpu,
|
|||
}
|
||||
case GICD_CTLR:
|
||||
/* Not a GICv4.1? No HW SGIs */
|
||||
if (!kvm_vgic_global_state.has_gicv4_1)
|
||||
if (!vgic_supports_direct_sgis(vcpu->kvm))
|
||||
val &= ~GICD_CTLR_nASSGIreq;
|
||||
|
||||
dist->enabled = val & GICD_CTLR_ENABLE_SS_G1;
|
||||
|
|
|
|||
|
|
@ -356,7 +356,7 @@ int vgic_v4_put(struct kvm_vcpu *vcpu)
|
|||
{
|
||||
struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
|
||||
|
||||
if (!vgic_supports_direct_msis(vcpu->kvm) || !vpe->resident)
|
||||
if (!vgic_supports_direct_irqs(vcpu->kvm) || !vpe->resident)
|
||||
return 0;
|
||||
|
||||
return its_make_vpe_non_resident(vpe, vgic_v4_want_doorbell(vcpu));
|
||||
|
|
@ -367,7 +367,7 @@ int vgic_v4_load(struct kvm_vcpu *vcpu)
|
|||
struct its_vpe *vpe = &vcpu->arch.vgic_cpu.vgic_v3.its_vpe;
|
||||
int err;
|
||||
|
||||
if (!vgic_supports_direct_msis(vcpu->kvm) || vpe->resident)
|
||||
if (!vgic_supports_direct_irqs(vcpu->kvm) || vpe->resident)
|
||||
return 0;
|
||||
|
||||
if (vcpu_get_flag(vcpu, IN_WFI))
|
||||
|
|
|
|||
|
|
@ -951,7 +951,7 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
|
|||
* can be directly injected (GICv4).
|
||||
*/
|
||||
if (list_empty(&vcpu->arch.vgic_cpu.ap_list_head) &&
|
||||
!vgic_supports_direct_msis(vcpu->kvm))
|
||||
!vgic_supports_direct_irqs(vcpu->kvm))
|
||||
return;
|
||||
|
||||
DEBUG_SPINLOCK_BUG_ON(!irqs_disabled());
|
||||
|
|
@ -965,7 +965,7 @@ void kvm_vgic_flush_hwstate(struct kvm_vcpu *vcpu)
|
|||
if (can_access_vgic_from_kernel())
|
||||
vgic_restore_state(vcpu);
|
||||
|
||||
if (vgic_supports_direct_msis(vcpu->kvm))
|
||||
if (vgic_supports_direct_irqs(vcpu->kvm))
|
||||
vgic_v4_commit(vcpu);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -370,6 +370,13 @@ int vgic_its_inv_lpi(struct kvm *kvm, struct vgic_irq *irq);
|
|||
int vgic_its_invall(struct kvm_vcpu *vcpu);
|
||||
|
||||
bool vgic_supports_direct_msis(struct kvm *kvm);
|
||||
bool vgic_supports_direct_sgis(struct kvm *kvm);
|
||||
|
||||
static inline bool vgic_supports_direct_irqs(struct kvm *kvm)
|
||||
{
|
||||
return vgic_supports_direct_msis(kvm) || vgic_supports_direct_sgis(kvm);
|
||||
}
|
||||
|
||||
int vgic_v4_init(struct kvm *kvm);
|
||||
void vgic_v4_teardown(struct kvm *kvm);
|
||||
void vgic_v4_configure_vsgis(struct kvm *kvm);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue