Gleb Natapov wrote on 2013-04-07: > On Mon, Apr 01, 2013 at 11:32:32AM +0800, Yang Zhang wrote: >> From: Yang Zhang <yang.z.zhang@xxxxxxxxx> >> >> Both TMR and EOI exit bitmap need to be updated when ioapic changed >> or vcpu's id/ldr/dfr changed. So use common function instead eoi exit >> bitmap specific function. >> >> Signed-off-by: Yang Zhang <yang.z.zhang@xxxxxxxxx> >> --- >> arch/ia64/kvm/lapic.h | 6 ------ >> arch/x86/kvm/lapic.c | 2 +- >> arch/x86/kvm/vmx.c | 3 +++ >> arch/x86/kvm/x86.c | 11 +++++++---- >> include/linux/kvm_host.h | 4 ++-- >> virt/kvm/ioapic.c | 26 +++++++++++++++----------- >> virt/kvm/ioapic.h | 7 +++---- >> virt/kvm/irq_comm.c | 4 ++-- >> virt/kvm/kvm_main.c | 4 ++-- >> 9 files changed, 35 insertions(+), 32 deletions(-) >> diff --git a/arch/ia64/kvm/lapic.h b/arch/ia64/kvm/lapic.h >> index c3e2935..c5f92a9 100644 >> --- a/arch/ia64/kvm/lapic.h >> +++ b/arch/ia64/kvm/lapic.h >> @@ -27,10 +27,4 @@ int kvm_apic_set_irq(struct kvm_vcpu *vcpu, struct > kvm_lapic_irq *irq); >> #define kvm_apic_present(x) (true) >> #define kvm_lapic_enabled(x) (true) >> -static inline bool kvm_apic_vid_enabled(void) >> -{ >> - /* IA64 has no apicv supporting, do nothing here */ >> - return false; >> -} >> - >> #endif >> diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c >> index e227474..ce8d6f6 100644 >> --- a/arch/x86/kvm/lapic.c >> +++ b/arch/x86/kvm/lapic.c >> @@ -209,7 +209,7 @@ out: >> if (old) >> kfree_rcu(old, rcu); >> - kvm_ioapic_make_eoibitmap_request(kvm); >> + kvm_vcpu_scan_ioapic(kvm); >> } >> >> static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id) >> diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index >> b2e95bc..edfc87a 100644 --- a/arch/x86/kvm/vmx.c +++ >> b/arch/x86/kvm/vmx.c @@ -6420,6 +6420,9 @@ static void >> vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr) >> >> static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 >> *eoi_exit_bitmap) { >> + if (!vmx_vm_has_apicv(vcpu->kvm)) >> + return; >> + >> vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]); >> vmcs_write64(EOI_EXIT_BITMAP1, eoi_exit_bitmap[1]); >> vmcs_write64(EOI_EXIT_BITMAP2, eoi_exit_bitmap[2]); >> diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c >> index 4d42fe1..64241b6 100644 >> --- a/arch/x86/kvm/x86.c >> +++ b/arch/x86/kvm/x86.c >> @@ -5647,13 +5647,16 @@ static void kvm_gen_update_masterclock(struct > kvm *kvm) >> #endif >> } >> -static void update_eoi_exitmap(struct kvm_vcpu *vcpu) >> +static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) >> { >> u64 eoi_exit_bitmap[4]; >> + if (!kvm_lapic_enabled(vcpu)) >> + return; >> + > Why is this needed here? We don't need to calculate eoi_exit_bitmap and TMR if lapic is not enabled. Also, ioapic is meaningless for the vcpu that doesn't enable the lapic. > >> memset(eoi_exit_bitmap, 0, 32); >> - kvm_ioapic_calculate_eoi_exitmap(vcpu, eoi_exit_bitmap); >> + kvm_ioapic_scan_entry(vcpu, (unsigned long *)eoi_exit_bitmap); >> kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap); >> } >> @@ -5710,8 +5713,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) >> kvm_handle_pmu_event(vcpu); >> if (kvm_check_request(KVM_REQ_PMI, vcpu)) >> kvm_deliver_pmi(vcpu); >> - if (kvm_check_request(KVM_REQ_EOIBITMAP, vcpu)) >> - update_eoi_exitmap(vcpu); >> + if (kvm_check_request(KVM_REQ_SCAN_IOAPIC, vcpu)) >> + vcpu_scan_ioapic(vcpu); >> } >> >> if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) { >> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h >> index 1c0be23..ef1b3e3 100644 >> --- a/include/linux/kvm_host.h >> +++ b/include/linux/kvm_host.h >> @@ -126,7 +126,7 @@ static inline bool is_error_page(struct page *page) >> #define KVM_REQ_MASTERCLOCK_UPDATE 19 >> #define KVM_REQ_MCLOCK_INPROGRESS 20 >> #define KVM_REQ_EPR_EXIT 21 >> -#define KVM_REQ_EOIBITMAP 22 >> +#define KVM_REQ_SCAN_IOAPIC 22 >> >> #define KVM_USERSPACE_IRQ_SOURCE_ID 0 #define >> KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID 1 @@ -571,7 +571,7 @@ void >> kvm_put_guest_fpu(struct kvm_vcpu *vcpu); void >> kvm_flush_remote_tlbs(struct kvm *kvm); void >> kvm_reload_remote_mmus(struct kvm *kvm); void >> kvm_make_mclock_inprogress_request(struct kvm *kvm); >> -void kvm_make_update_eoibitmap_request(struct kvm *kvm); >> +void kvm_make_scan_ioapic_request(struct kvm *kvm); >> >> long kvm_arch_dev_ioctl(struct file *filp, >> unsigned int ioctl, unsigned long arg); >> diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c >> index fbd0556..f37c889 100644 >> --- a/virt/kvm/ioapic.c >> +++ b/virt/kvm/ioapic.c >> @@ -119,8 +119,8 @@ static void update_handled_vectors(struct kvm_ioapic > *ioapic) >> smp_wmb(); >> } >> -void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu, >> - u64 *eoi_exit_bitmap) >> +void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, >> + unsigned long *eoi_exit_bitmap) >> { >> struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; >> union kvm_ioapic_redirect_entry *e; >> @@ -128,7 +128,6 @@ void kvm_ioapic_calculate_eoi_exitmap(struct > kvm_vcpu *vcpu, >> int index; >> >> spin_lock(&ioapic->lock); - /* traverse ioapic entry to set eoi exit >> bitmap*/ for (index = 0; index < IOAPIC_NUM_PINS; index++) { e = >> &ioapic->redirtbl[index]; if (!e->fields.mask && >> @@ -137,22 +136,27 @@ void kvm_ioapic_calculate_eoi_exitmap(struct > kvm_vcpu *vcpu, >> index))) { >> if (kvm_apic_match_dest(vcpu, NULL, 0, >> e->fields.dest_id, e->fields.dest_mode)) >> - __set_bit(irqe.vector, >> - (unsigned long *)eoi_exit_bitmap); >> + __set_bit(irqe.vector, eoi_exit_bitmap); > I prefer the old way of casting as deep in the call chain as possible. Sure. It make sense. > >> } >> } >> spin_unlock(&ioapic->lock); >> } >> -EXPORT_SYMBOL_GPL(kvm_ioapic_calculate_eoi_exitmap); >> >> -void kvm_ioapic_make_eoibitmap_request(struct kvm *kvm) >> +#ifdef CONFIG_X86 >> +void kvm_vcpu_scan_ioapic(struct kvm *kvm) > The name is too similar to vcpu_scan_ioapic and does not describe well > that the function does not actually scan anything, but only makes a > request. Call it kvm_vcpu_request_scan_ioapic(); Sure. > >> { >> struct kvm_ioapic *ioapic = kvm->arch.vioapic; >> - if (!kvm_apic_vid_enabled(kvm) || !ioapic) >> + if (!ioapic) >> return; >> - kvm_make_update_eoibitmap_request(kvm); >> + kvm_make_scan_ioapic_request(kvm); >> } >> +#else >> +void kvm_vcpu_scan_ioapic(struct kvm *kvm) >> +{ >> + return; >> +} >> +#endif >> >> static void ioapic_write_indirect(struct kvm_ioapic *ioapic, u32 val) >> { >> @@ -195,7 +199,7 @@ static void ioapic_write_indirect(struct kvm_ioapic > *ioapic, u32 val) >> if (e->fields.trig_mode == IOAPIC_LEVEL_TRIG >> && ioapic->irr & (1 << index)) >> ioapic_service(ioapic, index); >> - kvm_ioapic_make_eoibitmap_request(ioapic->kvm); >> + kvm_vcpu_scan_ioapic(ioapic->kvm); >> break; >> } >> } >> @@ -495,7 +499,7 @@ int kvm_set_ioapic(struct kvm *kvm, struct > kvm_ioapic_state *state) >> spin_lock(&ioapic->lock); >> memcpy(ioapic, state, sizeof(struct kvm_ioapic_state)); >> update_handled_vectors(ioapic); >> - kvm_ioapic_make_eoibitmap_request(kvm); >> + kvm_vcpu_scan_ioapic(kvm); >> spin_unlock(&ioapic->lock); >> return 0; >> } >> diff --git a/virt/kvm/ioapic.h b/virt/kvm/ioapic.h >> index 0400a46..e3538ba 100644 >> --- a/virt/kvm/ioapic.h >> +++ b/virt/kvm/ioapic.h >> @@ -82,9 +82,8 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct > kvm_lapic *src, >> struct kvm_lapic_irq *irq); >> int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); >> int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); >> -void kvm_ioapic_make_eoibitmap_request(struct kvm *kvm); >> -void kvm_ioapic_calculate_eoi_exitmap(struct kvm_vcpu *vcpu, >> - u64 *eoi_exit_bitmap); >> - >> +void kvm_vcpu_scan_ioapic(struct kvm *kvm); >> +void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, >> + unsigned long *eoi_exit_bitmap); >> >> #endif >> diff --git a/virt/kvm/irq_comm.c b/virt/kvm/irq_comm.c >> index e9073cf..b5cc1e1 100644 >> --- a/virt/kvm/irq_comm.c >> +++ b/virt/kvm/irq_comm.c >> @@ -280,7 +280,7 @@ void kvm_register_irq_ack_notifier(struct kvm *kvm, >> mutex_lock(&kvm->irq_lock); >> hlist_add_head_rcu(&kian->link, &kvm->irq_ack_notifier_list); >> mutex_unlock(&kvm->irq_lock); >> - kvm_ioapic_make_eoibitmap_request(kvm); >> + kvm_vcpu_scan_ioapic(kvm); >> } >> >> void kvm_unregister_irq_ack_notifier(struct kvm *kvm, @@ -290,7 +290,7 >> @@ void kvm_unregister_irq_ack_notifier(struct kvm *kvm, >> hlist_del_init_rcu(&kian->link); mutex_unlock(&kvm->irq_lock); >> synchronize_rcu(); >> - kvm_ioapic_make_eoibitmap_request(kvm); >> + kvm_vcpu_scan_ioapic(kvm); >> } >> >> int kvm_request_irq_source_id(struct kvm *kvm) >> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c >> index ff71541..2d44013 100644 >> --- a/virt/kvm/kvm_main.c >> +++ b/virt/kvm/kvm_main.c >> @@ -217,9 +217,9 @@ void kvm_make_mclock_inprogress_request(struct > kvm *kvm) >> make_all_cpus_request(kvm, KVM_REQ_MCLOCK_INPROGRESS); >> } >> -void kvm_make_update_eoibitmap_request(struct kvm *kvm) >> +void kvm_make_scan_ioapic_request(struct kvm *kvm) >> { >> - make_all_cpus_request(kvm, KVM_REQ_EOIBITMAP); >> + make_all_cpus_request(kvm, KVM_REQ_SCAN_IOAPIC); >> } >> >> int kvm_vcpu_init(struct kvm_vcpu *vcpu, struct kvm *kvm, unsigned id) >> -- >> 1.7.1 > > -- > Gleb. Best regards, Yang -- To unsubscribe from this list: send the line "unsubscribe kvm" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html