Skip to content

Commit ef364c5

Browse files
committed
KVM: arm64: vgic-v3: Consolidate MAINT_IRQ handling
Consolidate the duplicated handling of the VGICv3 maintenance IRQ attribute as a regular GICv3 attribute, as it is neither a register nor a common attribute. As this is now handled separately from the VGIC registers, the locking is relaxed to only acquire the intended config_lock. Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 82221a4 commit ef364c5

File tree

1 file changed

+25
-26
lines changed

1 file changed

+25
-26
lines changed

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

Lines changed: 25 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -303,12 +303,6 @@ static int vgic_get_common_attr(struct kvm_device *dev,
303303
VGIC_NR_PRIVATE_IRQS, uaddr);
304304
break;
305305
}
306-
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {
307-
u32 __user *uaddr = (u32 __user *)(long)attr->addr;
308-
309-
r = put_user(dev->kvm->arch.vgic.mi_intid, uaddr);
310-
break;
311-
}
312306
}
313307

314308
return r;
@@ -523,7 +517,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
523517
struct vgic_reg_attr reg_attr;
524518
gpa_t addr;
525519
struct kvm_vcpu *vcpu;
526-
bool uaccess, post_init = true;
520+
bool uaccess;
527521
u32 val;
528522
int ret;
529523

@@ -539,9 +533,6 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
539533
/* Sysregs uaccess is performed by the sysreg handling code */
540534
uaccess = false;
541535
break;
542-
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
543-
post_init = false;
544-
fallthrough;
545536
default:
546537
uaccess = true;
547538
}
@@ -561,7 +552,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
561552

562553
mutex_lock(&dev->kvm->arch.config_lock);
563554

564-
if (post_init != vgic_initialized(dev->kvm)) {
555+
if (!vgic_initialized(dev->kvm)) {
565556
ret = -EBUSY;
566557
goto out;
567558
}
@@ -591,19 +582,6 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
591582
}
592583
break;
593584
}
594-
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
595-
if (!is_write) {
596-
val = dev->kvm->arch.vgic.mi_intid;
597-
ret = 0;
598-
break;
599-
}
600-
601-
ret = -EINVAL;
602-
if ((val < VGIC_NR_PRIVATE_IRQS) && (val >= VGIC_NR_SGIS)) {
603-
dev->kvm->arch.vgic.mi_intid = val;
604-
ret = 0;
605-
}
606-
break;
607585
default:
608586
ret = -EINVAL;
609587
break;
@@ -630,8 +608,24 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
630608
case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
631609
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
632610
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO:
633-
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
634611
return vgic_v3_attr_regs_access(dev, attr, true);
612+
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {
613+
u32 __user *uaddr = (u32 __user *)attr->addr;
614+
u32 val;
615+
616+
if (get_user(val, uaddr))
617+
return -EFAULT;
618+
619+
guard(mutex)(&dev->kvm->arch.config_lock);
620+
if (vgic_initialized(dev->kvm))
621+
return -EBUSY;
622+
623+
if (!irq_is_ppi(val))
624+
return -EINVAL;
625+
626+
dev->kvm->arch.vgic.mi_intid = val;
627+
return 0;
628+
}
635629
default:
636630
return vgic_set_common_attr(dev, attr);
637631
}
@@ -645,8 +639,13 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
645639
case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
646640
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
647641
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO:
648-
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
649642
return vgic_v3_attr_regs_access(dev, attr, false);
643+
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {
644+
u32 __user *uaddr = (u32 __user *)(long)attr->addr;
645+
646+
guard(mutex)(&dev->kvm->arch.config_lock);
647+
return put_user(dev->kvm->arch.vgic.mi_intid, uaddr);
648+
}
650649
default:
651650
return vgic_get_common_attr(dev, attr);
652651
}

0 commit comments

Comments
 (0)