@@ -199,16 +199,25 @@ static void kvm_on_user_return(struct user_return_notifier *urn)
199199 struct kvm_shared_msrs * locals
200200 = container_of (urn , struct kvm_shared_msrs , urn );
201201 struct kvm_shared_msr_values * values ;
202+ unsigned long flags ;
202203
204+ /*
205+ * Disabling irqs at this point since the following code could be
206+ * interrupted and executed through kvm_arch_hardware_disable()
207+ */
208+ local_irq_save (flags );
209+ if (locals -> registered ) {
210+ locals -> registered = false;
211+ user_return_notifier_unregister (urn );
212+ }
213+ local_irq_restore (flags );
203214 for (slot = 0 ; slot < shared_msrs_global .nr ; ++ slot ) {
204215 values = & locals -> values [slot ];
205216 if (values -> host != values -> curr ) {
206217 wrmsrl (shared_msrs_global .msrs [slot ], values -> host );
207218 values -> curr = values -> host ;
208219 }
209220 }
210- locals -> registered = false;
211- user_return_notifier_unregister (urn );
212221}
213222
214223static void shared_msr_update (unsigned slot , u32 msr )
@@ -3317,14 +3326,17 @@ long kvm_arch_vcpu_ioctl(struct file *filp,
33173326 };
33183327 case KVM_SET_VAPIC_ADDR : {
33193328 struct kvm_vapic_addr va ;
3329+ int idx ;
33203330
33213331 r = - EINVAL ;
33223332 if (!lapic_in_kernel (vcpu ))
33233333 goto out ;
33243334 r = - EFAULT ;
33253335 if (copy_from_user (& va , argp , sizeof va ))
33263336 goto out ;
3337+ idx = srcu_read_lock (& vcpu -> kvm -> srcu );
33273338 r = kvm_lapic_set_vapic_addr (vcpu , va .vapic_addr );
3339+ srcu_read_unlock (& vcpu -> kvm -> srcu , idx );
33283340 break ;
33293341 }
33303342 case KVM_X86_SETUP_MCE : {
0 commit comments