mirror of
https://github.com/torvalds/linux.git
synced 2026-07-29 10:41:49 +02:00
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 <maz@kernel.org> Link: https://lore.kernel.org/r/20250724062805.2658919-3-oliver.upton@linux.dev Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
This commit is contained in:
parent
82221a4e66
commit
ef364c5b43
|
|
@ -303,12 +303,6 @@ static int vgic_get_common_attr(struct kvm_device *dev,
|
|||
VGIC_NR_PRIVATE_IRQS, uaddr);
|
||||
break;
|
||||
}
|
||||
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {
|
||||
u32 __user *uaddr = (u32 __user *)(long)attr->addr;
|
||||
|
||||
r = put_user(dev->kvm->arch.vgic.mi_intid, uaddr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return r;
|
||||
|
|
@ -523,7 +517,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
|
|||
struct vgic_reg_attr reg_attr;
|
||||
gpa_t addr;
|
||||
struct kvm_vcpu *vcpu;
|
||||
bool uaccess, post_init = true;
|
||||
bool uaccess;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
|
|
@ -539,9 +533,6 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
|
|||
/* Sysregs uaccess is performed by the sysreg handling code */
|
||||
uaccess = false;
|
||||
break;
|
||||
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
|
||||
post_init = false;
|
||||
fallthrough;
|
||||
default:
|
||||
uaccess = true;
|
||||
}
|
||||
|
|
@ -561,7 +552,7 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
|
|||
|
||||
mutex_lock(&dev->kvm->arch.config_lock);
|
||||
|
||||
if (post_init != vgic_initialized(dev->kvm)) {
|
||||
if (!vgic_initialized(dev->kvm)) {
|
||||
ret = -EBUSY;
|
||||
goto out;
|
||||
}
|
||||
|
|
@ -591,19 +582,6 @@ static int vgic_v3_attr_regs_access(struct kvm_device *dev,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
|
||||
if (!is_write) {
|
||||
val = dev->kvm->arch.vgic.mi_intid;
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
if ((val < VGIC_NR_PRIVATE_IRQS) && (val >= VGIC_NR_SGIS)) {
|
||||
dev->kvm->arch.vgic.mi_intid = val;
|
||||
ret = 0;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
|
|
@ -630,8 +608,24 @@ static int vgic_v3_set_attr(struct kvm_device *dev,
|
|||
case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
|
||||
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
|
||||
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO:
|
||||
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
|
||||
return vgic_v3_attr_regs_access(dev, attr, true);
|
||||
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {
|
||||
u32 __user *uaddr = (u32 __user *)attr->addr;
|
||||
u32 val;
|
||||
|
||||
if (get_user(val, uaddr))
|
||||
return -EFAULT;
|
||||
|
||||
guard(mutex)(&dev->kvm->arch.config_lock);
|
||||
if (vgic_initialized(dev->kvm))
|
||||
return -EBUSY;
|
||||
|
||||
if (!irq_is_ppi(val))
|
||||
return -EINVAL;
|
||||
|
||||
dev->kvm->arch.vgic.mi_intid = val;
|
||||
return 0;
|
||||
}
|
||||
default:
|
||||
return vgic_set_common_attr(dev, attr);
|
||||
}
|
||||
|
|
@ -645,8 +639,13 @@ static int vgic_v3_get_attr(struct kvm_device *dev,
|
|||
case KVM_DEV_ARM_VGIC_GRP_REDIST_REGS:
|
||||
case KVM_DEV_ARM_VGIC_GRP_CPU_SYSREGS:
|
||||
case KVM_DEV_ARM_VGIC_GRP_LEVEL_INFO:
|
||||
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ:
|
||||
return vgic_v3_attr_regs_access(dev, attr, false);
|
||||
case KVM_DEV_ARM_VGIC_GRP_MAINT_IRQ: {
|
||||
u32 __user *uaddr = (u32 __user *)(long)attr->addr;
|
||||
|
||||
guard(mutex)(&dev->kvm->arch.config_lock);
|
||||
return put_user(dev->kvm->arch.vgic.mi_intid, uaddr);
|
||||
}
|
||||
default:
|
||||
return vgic_get_common_attr(dev, attr);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user