diff options
author | Andre Przywara <andre.przywara@arm.com> | 2016-07-15 07:43:23 -0400 |
---|---|---|
committer | Marc Zyngier <marc.zyngier@arm.com> | 2016-07-18 13:10:08 -0400 |
commit | 42c8870f90098796c2ed7c9eaa3e7526407502a8 (patch) | |
tree | 05610f90cd7a20be3f551b391bc6aafa678c2cfb | |
parent | 8f6cdc1c2eec20c3bbf3a83ad0e1db165f709917 (diff) |
KVM: arm/arm64: vgic: Check return value for kvm_register_vgic_device
kvm_register_device_ops() can return an error, so lets check its return
value and propagate this up the call chain.
Signed-off-by: Andre Przywara <andre.przywara@arm.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Marc Zyngier <marc.zyngier@arm.com>
-rw-r--r-- | virt/kvm/arm/vgic/vgic-kvm-device.c | 15 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-v2.c | 11 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic-v3.c | 15 | ||||
-rw-r--r-- | virt/kvm/arm/vgic/vgic.h | 2 |
4 files changed, 31 insertions, 12 deletions
diff --git a/virt/kvm/arm/vgic/vgic-kvm-device.c b/virt/kvm/arm/vgic/vgic-kvm-device.c index 0130c4b147b7..2f24f13c6c90 100644 --- a/virt/kvm/arm/vgic/vgic-kvm-device.c +++ b/virt/kvm/arm/vgic/vgic-kvm-device.c | |||
@@ -210,20 +210,24 @@ static void vgic_destroy(struct kvm_device *dev) | |||
210 | kfree(dev); | 210 | kfree(dev); |
211 | } | 211 | } |
212 | 212 | ||
213 | void kvm_register_vgic_device(unsigned long type) | 213 | int kvm_register_vgic_device(unsigned long type) |
214 | { | 214 | { |
215 | int ret = -ENODEV; | ||
216 | |||
215 | switch (type) { | 217 | switch (type) { |
216 | case KVM_DEV_TYPE_ARM_VGIC_V2: | 218 | case KVM_DEV_TYPE_ARM_VGIC_V2: |
217 | kvm_register_device_ops(&kvm_arm_vgic_v2_ops, | 219 | ret = kvm_register_device_ops(&kvm_arm_vgic_v2_ops, |
218 | KVM_DEV_TYPE_ARM_VGIC_V2); | 220 | KVM_DEV_TYPE_ARM_VGIC_V2); |
219 | break; | 221 | break; |
220 | #ifdef CONFIG_KVM_ARM_VGIC_V3 | 222 | #ifdef CONFIG_KVM_ARM_VGIC_V3 |
221 | case KVM_DEV_TYPE_ARM_VGIC_V3: | 223 | case KVM_DEV_TYPE_ARM_VGIC_V3: |
222 | kvm_register_device_ops(&kvm_arm_vgic_v3_ops, | 224 | ret = kvm_register_device_ops(&kvm_arm_vgic_v3_ops, |
223 | KVM_DEV_TYPE_ARM_VGIC_V3); | 225 | KVM_DEV_TYPE_ARM_VGIC_V3); |
224 | break; | 226 | break; |
225 | #endif | 227 | #endif |
226 | } | 228 | } |
229 | |||
230 | return ret; | ||
227 | } | 231 | } |
228 | 232 | ||
229 | /** vgic_attr_regs_access: allows user space to read/write VGIC registers | 233 | /** vgic_attr_regs_access: allows user space to read/write VGIC registers |
@@ -428,4 +432,3 @@ struct kvm_device_ops kvm_arm_vgic_v3_ops = { | |||
428 | }; | 432 | }; |
429 | 433 | ||
430 | #endif /* CONFIG_KVM_ARM_VGIC_V3 */ | 434 | #endif /* CONFIG_KVM_ARM_VGIC_V3 */ |
431 | |||
diff --git a/virt/kvm/arm/vgic/vgic-v2.c b/virt/kvm/arm/vgic/vgic-v2.c index e31405ee5515..079bf670c451 100644 --- a/virt/kvm/arm/vgic/vgic-v2.c +++ b/virt/kvm/arm/vgic/vgic-v2.c | |||
@@ -332,20 +332,25 @@ int vgic_v2_probe(const struct gic_kvm_info *info) | |||
332 | vtr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VTR); | 332 | vtr = readl_relaxed(kvm_vgic_global_state.vctrl_base + GICH_VTR); |
333 | kvm_vgic_global_state.nr_lr = (vtr & 0x3f) + 1; | 333 | kvm_vgic_global_state.nr_lr = (vtr & 0x3f) + 1; |
334 | 334 | ||
335 | ret = kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V2); | ||
336 | if (ret) { | ||
337 | kvm_err("Cannot register GICv2 KVM device\n"); | ||
338 | iounmap(kvm_vgic_global_state.vctrl_base); | ||
339 | return ret; | ||
340 | } | ||
341 | |||
335 | ret = create_hyp_io_mappings(kvm_vgic_global_state.vctrl_base, | 342 | ret = create_hyp_io_mappings(kvm_vgic_global_state.vctrl_base, |
336 | kvm_vgic_global_state.vctrl_base + | 343 | kvm_vgic_global_state.vctrl_base + |
337 | resource_size(&info->vctrl), | 344 | resource_size(&info->vctrl), |
338 | info->vctrl.start); | 345 | info->vctrl.start); |
339 | |||
340 | if (ret) { | 346 | if (ret) { |
341 | kvm_err("Cannot map VCTRL into hyp\n"); | 347 | kvm_err("Cannot map VCTRL into hyp\n"); |
348 | kvm_unregister_device_ops(KVM_DEV_TYPE_ARM_VGIC_V2); | ||
342 | iounmap(kvm_vgic_global_state.vctrl_base); | 349 | iounmap(kvm_vgic_global_state.vctrl_base); |
343 | return ret; | 350 | return ret; |
344 | } | 351 | } |
345 | 352 | ||
346 | kvm_vgic_global_state.can_emulate_gicv2 = true; | 353 | kvm_vgic_global_state.can_emulate_gicv2 = true; |
347 | kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V2); | ||
348 | |||
349 | kvm_vgic_global_state.vcpu_base = info->vcpu.start; | 354 | kvm_vgic_global_state.vcpu_base = info->vcpu.start; |
350 | kvm_vgic_global_state.type = VGIC_V2; | 355 | kvm_vgic_global_state.type = VGIC_V2; |
351 | kvm_vgic_global_state.max_gic_vcpus = VGIC_V2_MAX_CPUS; | 356 | kvm_vgic_global_state.max_gic_vcpus = VGIC_V2_MAX_CPUS; |
diff --git a/virt/kvm/arm/vgic/vgic-v3.c b/virt/kvm/arm/vgic/vgic-v3.c index 346b4ad12b49..e48a22e9ee40 100644 --- a/virt/kvm/arm/vgic/vgic-v3.c +++ b/virt/kvm/arm/vgic/vgic-v3.c | |||
@@ -296,6 +296,7 @@ out: | |||
296 | int vgic_v3_probe(const struct gic_kvm_info *info) | 296 | int vgic_v3_probe(const struct gic_kvm_info *info) |
297 | { | 297 | { |
298 | u32 ich_vtr_el2 = kvm_call_hyp(__vgic_v3_get_ich_vtr_el2); | 298 | u32 ich_vtr_el2 = kvm_call_hyp(__vgic_v3_get_ich_vtr_el2); |
299 | int ret; | ||
299 | 300 | ||
300 | /* | 301 | /* |
301 | * The ListRegs field is 5 bits, but there is a architectural | 302 | * The ListRegs field is 5 bits, but there is a architectural |
@@ -319,12 +320,22 @@ int vgic_v3_probe(const struct gic_kvm_info *info) | |||
319 | } else { | 320 | } else { |
320 | kvm_vgic_global_state.vcpu_base = info->vcpu.start; | 321 | kvm_vgic_global_state.vcpu_base = info->vcpu.start; |
321 | kvm_vgic_global_state.can_emulate_gicv2 = true; | 322 | kvm_vgic_global_state.can_emulate_gicv2 = true; |
322 | kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V2); | 323 | ret = kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V2); |
324 | if (ret) { | ||
325 | kvm_err("Cannot register GICv2 KVM device.\n"); | ||
326 | return ret; | ||
327 | } | ||
323 | kvm_info("vgic-v2@%llx\n", info->vcpu.start); | 328 | kvm_info("vgic-v2@%llx\n", info->vcpu.start); |
324 | } | 329 | } |
330 | ret = kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V3); | ||
331 | if (ret) { | ||
332 | kvm_err("Cannot register GICv3 KVM device.\n"); | ||
333 | kvm_unregister_device_ops(KVM_DEV_TYPE_ARM_VGIC_V2); | ||
334 | return ret; | ||
335 | } | ||
336 | |||
325 | if (kvm_vgic_global_state.vcpu_base == 0) | 337 | if (kvm_vgic_global_state.vcpu_base == 0) |
326 | kvm_info("disabling GICv2 emulation\n"); | 338 | kvm_info("disabling GICv2 emulation\n"); |
327 | kvm_register_vgic_device(KVM_DEV_TYPE_ARM_VGIC_V3); | ||
328 | 339 | ||
329 | kvm_vgic_global_state.vctrl_base = NULL; | 340 | kvm_vgic_global_state.vctrl_base = NULL; |
330 | kvm_vgic_global_state.type = VGIC_V3; | 341 | kvm_vgic_global_state.type = VGIC_V3; |
diff --git a/virt/kvm/arm/vgic/vgic.h b/virt/kvm/arm/vgic/vgic.h index 7b300ca370b7..c752152e8248 100644 --- a/virt/kvm/arm/vgic/vgic.h +++ b/virt/kvm/arm/vgic/vgic.h | |||
@@ -124,7 +124,7 @@ static inline int vgic_register_redist_iodevs(struct kvm *kvm, | |||
124 | } | 124 | } |
125 | #endif | 125 | #endif |
126 | 126 | ||
127 | void kvm_register_vgic_device(unsigned long type); | 127 | int kvm_register_vgic_device(unsigned long type); |
128 | int vgic_lazy_init(struct kvm *kvm); | 128 | int vgic_lazy_init(struct kvm *kvm); |
129 | int vgic_init(struct kvm *kvm); | 129 | int vgic_init(struct kvm *kvm); |
130 | 130 | ||