aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndre Przywara <andre.przywara@arm.com>2016-07-15 07:43:23 -0400
committerMarc Zyngier <marc.zyngier@arm.com>2016-07-18 13:10:08 -0400
commit42c8870f90098796c2ed7c9eaa3e7526407502a8 (patch)
tree05610f90cd7a20be3f551b391bc6aafa678c2cfb
parent8f6cdc1c2eec20c3bbf3a83ad0e1db165f709917 (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.c15
-rw-r--r--virt/kvm/arm/vgic/vgic-v2.c11
-rw-r--r--virt/kvm/arm/vgic/vgic-v3.c15
-rw-r--r--virt/kvm/arm/vgic/vgic.h2
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
213void kvm_register_vgic_device(unsigned long type) 213int 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:
296int vgic_v3_probe(const struct gic_kvm_info *info) 296int 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
127void kvm_register_vgic_device(unsigned long type); 127int kvm_register_vgic_device(unsigned long type);
128int vgic_lazy_init(struct kvm *kvm); 128int vgic_lazy_init(struct kvm *kvm);
129int vgic_init(struct kvm *kvm); 129int vgic_init(struct kvm *kvm);
130 130