virt: kvm: arm: vgic: Process the failure case when kvm_register_device_ops() fails
Subsystems (4)
PATCH v2 1/1 virt: kvm: arm: vgic: Process the failure case when kvm_register_device_ops() fails
When kvm_register_device_ops() fails, need disable_percpu_irq(), need vgic_arch_unsetup(), need __unregister_cpu_notifier(), and also need free_percpu_irq().
At present, there is no vgic_arch_unsetup(), so add it for resetting '__vgic_sr_vectors'.
--- arch/arm/include/asm/kvm_host.h | 1 + arch/arm64/include/asm/kvm_host.h | 8 ++++++++ virt/kvm/arm/vgic.c | 19 +++++++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-)
arch/arm/include/asm/kvm_host.h +1 -0
@@ -232,6 +232,7 @@ static inline void vgic_arch_setup(const struct vgic_params *vgic) {BUG_ON (vgic->type !=VGIC_V2 ); } +static inline void vgic_arch_unsetup (void ) {}int kvm_perf_init (void );int kvm_perf_teardown (void );
arch/arm64/include/asm/kvm_host.h +8 -0
@@ -248,6 +248,14 @@ static inline void vgic_arch_setup(const struct vgic_params *vgic) } } +static inline void vgic_arch_unsetup (void ) +{ +extern struct vgic_sr_vectors __vgic_sr_vectors; + + __vgic_sr_vectors.save_vgic =0 ; + __vgic_sr_vectors.restore_vgic =0 ; +} +static inline void kvm_arch_hardware_disable (void ) {}static inline void kvm_arch_hardware_unsetup (void ) {}static inline void kvm_arch_sync_events (struct kvm *kvm) {}
virt/kvm/arm/vgic.c +17 -2
@@ -2405,6 +2405,11 @@ static void vgic_init_maintenance_interrupt(void *info)enable_percpu_irq (vgic->maint_irq,0 ); } +static void vgic_uninit_maintenance_interrupt (void *info) +{ +disable_percpu_irq (vgic->maint_irq); +} +static int vgic_cpu_notify (struct notifier_block *self,unsigned long action,void *cpu) {
@@ -2470,9 +2475,19 @@ int kvm_vgic_hyp_init(void)on_each_cpu (vgic_init_maintenance_interrupt,NULL ,1 ); -return kvm_register_device_ops (&kvm_arm_vgic_v2_ops, -KVM_DEV_TYPE_ARM_VGIC_V2 ); + ret =kvm_register_device_ops (&kvm_arm_vgic_v2_ops, +KVM_DEV_TYPE_ARM_VGIC_V2 ); +if (ret) { +kvm_err ("Cannot register device ops\n" ); + goto out_disable_irq; + } + +return 0 ; +out_disable_irq: +on_each_cpu (vgic_uninit_maintenance_interrupt,NULL ,1 ); +vgic_arch_unsetup (); +__unregister_cpu_notifier (&vgic_cpu_nb); out_free_irq:free_percpu_irq (vgic->maint_irq,kvm_get_running_vcpus ());return ret;
Signature · 1 line
1.9.3
Quoted 75 lines · Chen Gang
When
kvm_register_device_ops()fails, needdisable_percpu_irq(), needvgic_arch_unsetup(), need__unregister_cpu_notifier(), and also needfree_percpu_irq().At present, there is no
vgic_arch_unsetup(), so add it for resetting '__vgic_sr_vectors'.Signed-off-by Chen Gang <[email protected]>--- arch/arm/include/asm/kvm_host.h | 1 + arch/arm64/include/asm/kvm_host.h | 8 ++++++++ virt/kvm/arm/vgic.c | 19 +++++++++++++++++-- 3 files changed, 26 insertions(+), 2 deletions(-)arch/arm/include/asm/kvm_host.h +1
-0@@ -232,6 +232,7 @@ static inline void vgic_arch_setup(const struct vgic_params *vgic) {BUG_ON (vgic->type !=VGIC_V2 ); } +static inline void vgic_arch_unsetup (void ) {}int kvm_perf_init (void );int kvm_perf_teardown (void );arch/arm64/include/asm/kvm_host.h +8
-0@@ -248,6 +248,14 @@ static inline void vgic_arch_setup(const struct vgic_params *vgic) } } +static inline void vgic_arch_unsetup (void ) +{ +extern struct vgic_sr_vectors __vgic_sr_vectors; + + __vgic_sr_vectors.save_vgic =0 ; + __vgic_sr_vectors.restore_vgic =0 ; +} +static inline void kvm_arch_hardware_disable (void ) {}static inline void kvm_arch_hardware_unsetup (void ) {}static inline void kvm_arch_sync_events (struct kvm *kvm) {}virt/kvm/arm/vgic.c +11
-2@@ -2405,6 +2405,11 @@ static void vgic_init_maintenance_interrupt(void *info)enable_percpu_irq (vgic->maint_irq,0 ); } +static void vgic_uninit_maintenance_interrupt (void *info) +{ +disable_percpu_irq (vgic->maint_irq); +} +static int vgic_cpu_notify (struct notifier_block *self,unsigned long action,void *cpu) {@@ -2470,9 +2475,19 @@ int kvm_vgic_hyp_init(void)on_each_cpu (vgic_init_maintenance_interrupt,NULL ,1 ); -return kvm_register_device_ops (&kvm_arm_vgic_v2_ops, -KVM_DEV_TYPE_ARM_VGIC_V2 ); + ret =kvm_register_device_ops (&kvm_arm_vgic_v2_ops, +KVM_DEV_TYPE_ARM_VGIC_V2 ); +if (ret) { +kvm_err ("Cannot register device ops\n" ); + goto out_disable_irq; + }
virt/kvm/arm/vgic.c int kvm_vgic_hyp_init(void) · line 2493
Quoted 10 lines
virt/kvm/arm/vgic.c +6
-0+ +return 0 ; +out_disable_irq: +on_each_cpu (vgic_uninit_maintenance_interrupt,NULL ,1 ); +vgic_arch_unsetup (); +__unregister_cpu_notifier (&vgic_cpu_nb); out_free_irq:free_percpu_irq (vgic->maint_irq,kvm_get_running_vcpus ());return ret;
No. This is completely overdesigned, and fixes something that really cannot happen. What is wrong with:
virt/kvm/arm/vgic.c +6 -2
@@ -2465,13 +2465,17 @@ int kvm_vgic_hyp_init(void) goto out_free_irq; } + ret =kvm_register_device_ops (&kvm_arm_vgic_v2_ops, +KVM_DEV_TYPE_ARM_VGIC_V2 ); +if (ret) + goto out_free_irq; +/* Callback into for arch code for setup */ vgic_arch_setup (vgic);on_each_cpu (vgic_init_maintenance_interrupt,NULL ,1 ); -return kvm_register_device_ops (&kvm_arm_vgic_v2_ops, -KVM_DEV_TYPE_ARM_VGIC_V2 ); +return 0 ; out_free_irq:free_percpu_irq (vgic->maint_irq,kvm_get_running_vcpus ());
This achieves the exact same effect.
Thanks,
M.
Signature · 1 line
Jazz is not dead. It just smells funny...
According to your taste, we need improve 2 contents below:
Quoted 9 lines · Marc Zyngier
No. This is completely overdesigned, and fixes something that really cannot happen. What is wrong with:
virt/kvm/arm/vgic.c +0
-0
virt/kvm/arm/vgic.c int kvm_vgic_hyp_init(void) · line 2472
Quoted 8 lines
virt/kvm/arm/vgic.c +5
-0@@ -2465,13 +2465,17 @@ int kvm_vgic_hyp_init(void) goto out_free_irq; } + ret =kvm_register_device_ops (&kvm_arm_vgic_v2_ops, +KVM_DEV_TYPE_ARM_VGIC_V2 ); +if (ret) + goto out_free_irq; +
Need call __unregister_cpu_notifier(), since __register_cpu_notifier() is already successfully called.
Need print some information for failure via kvm_err().
Thanks.
Quoted 18 lines
virt/kvm/arm/vgic.c +1
-2/* Callback into for arch code for setup */ vgic_arch_setup (vgic);on_each_cpu (vgic_init_maintenance_interrupt,NULL ,1 ); -return kvm_register_device_ops (&kvm_arm_vgic_v2_ops, -KVM_DEV_TYPE_ARM_VGIC_V2 ); +return 0 ; out_free_irq:free_percpu_irq (vgic->maint_irq,kvm_get_running_vcpus ());This achieves the exact same effect.
Thanks,
M.
Signature · 3 lines
Chen Gang Open share and attitude like air water and life which God blessed
Hello maintainers:
Is this discussion OK? If necessary, I shall send patch v3 according to your taste.
Thanks.
Quoted 48 lines · Chen Gang
According to your taste, we need improve 2 contents below:
Quoted 9 lines · Marc Zyngier
No. This is completely overdesigned, and fixes something that really cannot happen. What is wrong with:
virt/kvm/arm/vgic.c +0
-0virt/kvm/arm/vgic.c int kvm_vgic_hyp_init(void) · line 2472
Quoted 8 lines
virt/kvm/arm/vgic.c +5
-0@@ -2465,13 +2465,17 @@ int kvm_vgic_hyp_init(void) goto out_free_irq; } + ret =kvm_register_device_ops (&kvm_arm_vgic_v2_ops, +KVM_DEV_TYPE_ARM_VGIC_V2 ); +if (ret) + goto out_free_irq; +Need call
__unregister_cpu_notifier(), since__register_cpu_notifier()is already successfully called.Need print some information for failure via
kvm_err().Thanks.
Quoted 18 lines
virt/kvm/arm/vgic.c +1
-2/* Callback into for arch code for setup */ vgic_arch_setup (vgic);on_each_cpu (vgic_init_maintenance_interrupt,NULL ,1 ); -return kvm_register_device_ops (&kvm_arm_vgic_v2_ops, -KVM_DEV_TYPE_ARM_VGIC_V2 ); +return 0 ; out_free_irq:free_percpu_irq (vgic->maint_irq,kvm_get_running_vcpus ());This achieves the exact same effect.
Thanks,
M.
Signature · 3 lines
Chen Gang Open, share, and attitude like air, water, and life which God blessed