Skip to content

Commit 9f968c9

Browse files
author
Marc Zyngier
committed
KVM: arm64: vgic-v2: Add helper for legacy dist/cpuif base address setting
We carry a legacy interface to set the base addresses for GICv2. As this is currently plumbed into the same handling code as the modern interface, it limits the evolution we can make there. Add a helper dedicated to this handling, with a view of maybe removing this in the future. Signed-off-by: Marc Zyngier <[email protected]>
1 parent d7df6f2 commit 9f968c9

File tree

3 files changed

+35
-9
lines changed

3 files changed

+35
-9
lines changed

arch/arm64/kvm/arm.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,18 +1414,11 @@ void kvm_arch_flush_remote_tlbs_memslot(struct kvm *kvm,
14141414
static int kvm_vm_ioctl_set_device_addr(struct kvm *kvm,
14151415
struct kvm_arm_device_addr *dev_addr)
14161416
{
1417-
unsigned long dev_id, type;
1418-
1419-
dev_id = (dev_addr->id & KVM_ARM_DEVICE_ID_MASK) >>
1420-
KVM_ARM_DEVICE_ID_SHIFT;
1421-
type = (dev_addr->id & KVM_ARM_DEVICE_TYPE_MASK) >>
1422-
KVM_ARM_DEVICE_TYPE_SHIFT;
1423-
1424-
switch (dev_id) {
1417+
switch (FIELD_GET(KVM_ARM_DEVICE_ID_MASK, dev_addr->id)) {
14251418
case KVM_ARM_DEVICE_VGIC_V2:
14261419
if (!vgic_present)
14271420
return -ENXIO;
1428-
return kvm_vgic_addr(kvm, type, &dev_addr->addr, true);
1421+
return kvm_set_legacy_vgic_v2_addr(kvm, dev_addr);
14291422
default:
14301423
return -ENODEV;
14311424
}

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

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,38 @@ static int vgic_check_type(struct kvm *kvm, int type_needed)
4141
return 0;
4242
}
4343

44+
int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev_addr)
45+
{
46+
struct vgic_dist *vgic = &kvm->arch.vgic;
47+
int r;
48+
49+
mutex_lock(&kvm->lock);
50+
switch (FIELD_GET(KVM_ARM_DEVICE_TYPE_MASK, dev_addr->id)) {
51+
case KVM_VGIC_V2_ADDR_TYPE_DIST:
52+
r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
53+
if (!r)
54+
r = vgic_check_iorange(kvm, vgic->vgic_dist_base, dev_addr->addr,
55+
SZ_4K, KVM_VGIC_V2_DIST_SIZE);
56+
if (!r)
57+
vgic->vgic_dist_base = dev_addr->addr;
58+
break;
59+
case KVM_VGIC_V2_ADDR_TYPE_CPU:
60+
r = vgic_check_type(kvm, KVM_DEV_TYPE_ARM_VGIC_V2);
61+
if (!r)
62+
r = vgic_check_iorange(kvm, vgic->vgic_cpu_base, dev_addr->addr,
63+
SZ_4K, KVM_VGIC_V2_CPU_SIZE);
64+
if (!r)
65+
vgic->vgic_cpu_base = dev_addr->addr;
66+
break;
67+
default:
68+
r = -ENODEV;
69+
}
70+
71+
mutex_unlock(&kvm->lock);
72+
73+
return r;
74+
}
75+
4476
/**
4577
* kvm_vgic_addr - set or get vgic VM base addresses
4678
* @kvm: pointer to the vm struct

include/kvm/arm_vgic.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ extern struct static_key_false vgic_v2_cpuif_trap;
365365
extern struct static_key_false vgic_v3_cpuif_trap;
366366

367367
int kvm_vgic_addr(struct kvm *kvm, unsigned long type, u64 *addr, bool write);
368+
int kvm_set_legacy_vgic_v2_addr(struct kvm *kvm, struct kvm_arm_device_addr *dev_addr);
368369
void kvm_vgic_early_init(struct kvm *kvm);
369370
int kvm_vgic_vcpu_init(struct kvm_vcpu *vcpu);
370371
int kvm_vgic_create(struct kvm *kvm, u32 type);

0 commit comments

Comments
 (0)