On 13/09/19 21:00, Suthikulpanit, Suravee wrote: > + kvm_for_each_vcpu(i, v, kvm) > + kvm_clear_request(KVM_REQ_APICV_DEACTIVATE, v); > + > + if (kvm_x86_ops->pre_update_apicv_exec_ctrl) > + kvm_x86_ops->pre_update_apicv_exec_ctrl(vcpu, true); > + > + kvm->arch.apicv_state = APICV_ACTIVATED; > + > + kvm_make_all_cpus_request(kvm, KVM_REQ_APICV_ACTIVATE); > + > + mutex_unlock(&kvm->arch.apicv_lock); I think a lot of this logic can be simplified. In particular, I would have: - a single KVM_REQ_APICV_TOGGLE request that unifies kvm_vcpu_activate_apicv and kvm_vcpu_deactivate_apicv. The invariant is that, at the end of the function, (vcpu->arch.apicv_active == (kvm->arch.apicv_state = APICV_ACTIVATED)). The apicv_lock then becomes an rwsem, so that kvm_activate_apic and kvm_deactivate_apic will down_write it, while the processing of KVM_REQ_APICV_TOGGLE can down_read it. - the srcu_read_unlock/srcu_read_lock should be hidden in svm_request_activate_avic/svm_request_deactivate_avic. Everything else should only take struct kvm*, following what you've started with patch 1. In particular kvm_vcpu_deactivate_apicv should be changed to take a struct kvm*, so that Hyper-V can do kvm_deactivate_apic(kvm, APIC_DISABLED). Hyper-V should not care about srcu_read_lock/srcu_read_unlock. avic_setup_access_page and avic_destroy_access_page also can be changed to take struct kvm*. Paolo