Skip to content

Commit c652887

Browse files
rananta468oupton
authored andcommitted
KVM: arm64: vgic-v3: Allow userspace to write GICD_TYPER2.nASSGIcap
KVM unconditionally advertises GICD_TYPER2.nASSGIcap (which internally implies vSGIs) on GICv4.1 systems. Allow userspace to change whether a VM supports the feature. Only allow changes prior to VGIC initialization as at that point vPEs need to be allocated for the VM. For convenience, bundle support for vLPIs and vSGIs behind this feature, allowing userspace to control vPE allocation for VMs in environments that may be constrained on vPE IDs. Signed-off-by: Raghavendra Rao Ananta <[email protected]> Reviewed-by: Eric Auger <[email protected]> Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent f26e6af commit c652887

File tree

5 files changed

+34
-3
lines changed

5 files changed

+34
-3
lines changed

arch/arm64/kvm/vgic/vgic-init.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ int kvm_vgic_create(struct kvm *kvm, u32 type)
166166
else
167167
INIT_LIST_HEAD(&kvm->arch.vgic.rd_regions);
168168

169+
if (type == KVM_DEV_TYPE_ARM_VGIC_V3)
170+
kvm->arch.vgic.nassgicap = system_supports_direct_sgis();
171+
169172
out_unlock:
170173
mutex_unlock(&kvm->arch.config_lock);
171174
kvm_unlock_all_vcpus(kvm);

arch/arm64/kvm/vgic/vgic-kvm-device.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ static bool reg_allowed_pre_init(struct kvm_device_attr *attr)
515515

516516
switch (attr->attr & KVM_DEV_ARM_VGIC_OFFSET_MASK) {
517517
case GICD_IIDR:
518+
case GICD_TYPER2:
518519
return true;
519520
default:
520521
return false;

arch/arm64/kvm/vgic/vgic-mmio-v3.c

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -53,11 +53,16 @@ bool vgic_supports_direct_msis(struct kvm *kvm)
5353
return kvm_vgic_global_state.has_gicv4 && vgic_has_its(kvm);
5454
}
5555

56-
bool vgic_supports_direct_sgis(struct kvm *kvm)
56+
bool system_supports_direct_sgis(void)
5757
{
5858
return kvm_vgic_global_state.has_gicv4_1 && gic_cpuif_has_vsgi();
5959
}
6060

61+
bool vgic_supports_direct_sgis(struct kvm *kvm)
62+
{
63+
return kvm->arch.vgic.nassgicap;
64+
}
65+
6166
/*
6267
* The Revision field in the IIDR have the following meanings:
6368
*
@@ -163,8 +168,18 @@ static int vgic_mmio_uaccess_write_v3_misc(struct kvm_vcpu *vcpu,
163168

164169
switch (addr & 0x0c) {
165170
case GICD_TYPER2:
166-
if (val != vgic_mmio_read_v3_misc(vcpu, addr, len))
171+
reg = vgic_mmio_read_v3_misc(vcpu, addr, len);
172+
173+
if (reg == val)
174+
return 0;
175+
if (vgic_initialized(vcpu->kvm))
176+
return -EBUSY;
177+
if ((reg ^ val) & ~GICD_TYPER2_nASSGIcap)
167178
return -EINVAL;
179+
if (!system_supports_direct_sgis() && val)
180+
return -EINVAL;
181+
182+
dist->nassgicap = val & GICD_TYPER2_nASSGIcap;
168183
return 0;
169184
case GICD_IIDR:
170185
reg = vgic_mmio_read_v3_misc(vcpu, addr, len);

arch/arm64/kvm/vgic/vgic.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -369,12 +369,21 @@ void vgic_its_invalidate_all_caches(struct kvm *kvm);
369369
int vgic_its_inv_lpi(struct kvm *kvm, struct vgic_irq *irq);
370370
int vgic_its_invall(struct kvm_vcpu *vcpu);
371371

372+
bool system_supports_direct_sgis(void);
372373
bool vgic_supports_direct_msis(struct kvm *kvm);
373374
bool vgic_supports_direct_sgis(struct kvm *kvm);
374375

375376
static inline bool vgic_supports_direct_irqs(struct kvm *kvm)
376377
{
377-
return vgic_supports_direct_msis(kvm) || vgic_supports_direct_sgis(kvm);
378+
/*
379+
* Deliberately conflate vLPI and vSGI support on GICv4.1 hardware,
380+
* indirectly allowing userspace to control whether or not vPEs are
381+
* allocated for the VM.
382+
*/
383+
if (system_supports_direct_sgis())
384+
return vgic_supports_direct_sgis(kvm);
385+
386+
return vgic_supports_direct_msis(kvm);
378387
}
379388

380389
int vgic_v4_init(struct kvm *kvm);

include/kvm/arm_vgic.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,9 @@ struct vgic_dist {
264264
/* distributor enabled */
265265
bool enabled;
266266

267+
/* Supports SGIs without active state */
268+
bool nassgicap;
269+
267270
/* Wants SGIs without active state */
268271
bool nassgireq;
269272

0 commit comments

Comments
 (0)