diff options
author | Andrey Smetanin <asmetanin@virtuozzo.com> | 2015-11-10 07:36:32 -0500 |
---|---|---|
committer | Paolo Bonzini <pbonzini@redhat.com> | 2015-11-25 11:24:21 -0500 |
commit | 6308630bd3dbb6a8a883c4c571ce5e5a759a8a0e (patch) | |
tree | 3f4e51bee7ece38a7784090634906639954227d7 | |
parent | abdb080f7ac8a85547f5e0246362790043bbd3f2 (diff) |
kvm/x86: split ioapic-handled and EOI exit bitmaps
The function to determine if the vector is handled by ioapic used to
rely on the fact that only ioapic-handled vectors were set up to
cause vmexits when virtual apic was in use.
We're going to break this assumption when introducing Hyper-V
synthetic interrupts: they may need to cause vmexits too.
To achieve that, introduce a new bitmap dedicated specifically for
ioapic-handled vectors, and populate EOI exit bitmap from it for now.
Signed-off-by: Andrey Smetanin <asmetanin@virtuozzo.com>
Reviewed-by: Roman Kagan <rkagan@virtuozzo.com>
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Gleb Natapov <gleb@kernel.org>
CC: Paolo Bonzini <pbonzini@redhat.com>
CC: Roman Kagan <rkagan@virtuozzo.com>
CC: Denis V. Lunev <den@openvz.org>
CC: qemu-devel@nongnu.org
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 4 | ||||
-rw-r--r-- | arch/x86/kvm/ioapic.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/ioapic.h | 7 | ||||
-rw-r--r-- | arch/x86/kvm/irq_comm.c | 5 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 11 |
8 files changed, 20 insertions, 18 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 30cfd64295a0..f6d8894f25b4 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -400,7 +400,7 @@ struct kvm_vcpu_arch { | |||
400 | u64 efer; | 400 | u64 efer; |
401 | u64 apic_base; | 401 | u64 apic_base; |
402 | struct kvm_lapic *apic; /* kernel irqchip context */ | 402 | struct kvm_lapic *apic; /* kernel irqchip context */ |
403 | u64 eoi_exit_bitmap[4]; | 403 | DECLARE_BITMAP(ioapic_handled_vectors, 256); |
404 | unsigned long apic_attention; | 404 | unsigned long apic_attention; |
405 | int32_t apic_arb_prio; | 405 | int32_t apic_arb_prio; |
406 | int mp_state; | 406 | int mp_state; |
@@ -834,7 +834,7 @@ struct kvm_x86_ops { | |||
834 | int (*cpu_uses_apicv)(struct kvm_vcpu *vcpu); | 834 | int (*cpu_uses_apicv)(struct kvm_vcpu *vcpu); |
835 | void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr); | 835 | void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr); |
836 | void (*hwapic_isr_update)(struct kvm *kvm, int isr); | 836 | void (*hwapic_isr_update)(struct kvm *kvm, int isr); |
837 | void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu); | 837 | void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap); |
838 | void (*set_virtual_x2apic_mode)(struct kvm_vcpu *vcpu, bool set); | 838 | void (*set_virtual_x2apic_mode)(struct kvm_vcpu *vcpu, bool set); |
839 | void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa); | 839 | void (*set_apic_access_page_addr)(struct kvm_vcpu *vcpu, hpa_t hpa); |
840 | void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); | 840 | void (*deliver_posted_interrupt)(struct kvm_vcpu *vcpu, int vector); |
diff --git a/arch/x86/kvm/ioapic.c b/arch/x86/kvm/ioapic.c index 88d0a92d3f94..1facfd60b04a 100644 --- a/arch/x86/kvm/ioapic.c +++ b/arch/x86/kvm/ioapic.c | |||
@@ -233,7 +233,7 @@ static void kvm_ioapic_inject_all(struct kvm_ioapic *ioapic, unsigned long irr) | |||
233 | } | 233 | } |
234 | 234 | ||
235 | 235 | ||
236 | void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) | 236 | void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, ulong *ioapic_handled_vectors) |
237 | { | 237 | { |
238 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; | 238 | struct kvm_ioapic *ioapic = vcpu->kvm->arch.vioapic; |
239 | union kvm_ioapic_redirect_entry *e; | 239 | union kvm_ioapic_redirect_entry *e; |
@@ -250,7 +250,7 @@ void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) | |||
250 | (e->fields.trig_mode == IOAPIC_EDGE_TRIG && | 250 | (e->fields.trig_mode == IOAPIC_EDGE_TRIG && |
251 | kvm_apic_pending_eoi(vcpu, e->fields.vector))) | 251 | kvm_apic_pending_eoi(vcpu, e->fields.vector))) |
252 | __set_bit(e->fields.vector, | 252 | __set_bit(e->fields.vector, |
253 | (unsigned long *)eoi_exit_bitmap); | 253 | ioapic_handled_vectors); |
254 | } | 254 | } |
255 | } | 255 | } |
256 | spin_unlock(&ioapic->lock); | 256 | spin_unlock(&ioapic->lock); |
diff --git a/arch/x86/kvm/ioapic.h b/arch/x86/kvm/ioapic.h index 084617d37c74..2d16dc251d81 100644 --- a/arch/x86/kvm/ioapic.h +++ b/arch/x86/kvm/ioapic.h | |||
@@ -121,7 +121,8 @@ int kvm_irq_delivery_to_apic(struct kvm *kvm, struct kvm_lapic *src, | |||
121 | struct kvm_lapic_irq *irq, unsigned long *dest_map); | 121 | struct kvm_lapic_irq *irq, unsigned long *dest_map); |
122 | int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); | 122 | int kvm_get_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); |
123 | int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); | 123 | int kvm_set_ioapic(struct kvm *kvm, struct kvm_ioapic_state *state); |
124 | void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap); | 124 | void kvm_ioapic_scan_entry(struct kvm_vcpu *vcpu, |
125 | void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap); | 125 | ulong *ioapic_handled_vectors); |
126 | 126 | void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, | |
127 | ulong *ioapic_handled_vectors); | ||
127 | #endif | 128 | #endif |
diff --git a/arch/x86/kvm/irq_comm.c b/arch/x86/kvm/irq_comm.c index e39768ca8285..ece901c29351 100644 --- a/arch/x86/kvm/irq_comm.c +++ b/arch/x86/kvm/irq_comm.c | |||
@@ -339,7 +339,8 @@ void kvm_arch_post_irq_routing_update(struct kvm *kvm) | |||
339 | kvm_make_scan_ioapic_request(kvm); | 339 | kvm_make_scan_ioapic_request(kvm); |
340 | } | 340 | } |
341 | 341 | ||
342 | void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) | 342 | void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, |
343 | ulong *ioapic_handled_vectors) | ||
343 | { | 344 | { |
344 | struct kvm *kvm = vcpu->kvm; | 345 | struct kvm *kvm = vcpu->kvm; |
345 | struct kvm_kernel_irq_routing_entry *entry; | 346 | struct kvm_kernel_irq_routing_entry *entry; |
@@ -369,7 +370,7 @@ void kvm_scan_ioapic_routes(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) | |||
369 | u32 vector = entry->msi.data & 0xff; | 370 | u32 vector = entry->msi.data & 0xff; |
370 | 371 | ||
371 | __set_bit(vector, | 372 | __set_bit(vector, |
372 | (unsigned long *) eoi_exit_bitmap); | 373 | ioapic_handled_vectors); |
373 | } | 374 | } |
374 | } | 375 | } |
375 | } | 376 | } |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 4d30b865be30..9469d453abc8 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -932,7 +932,7 @@ int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2) | |||
932 | 932 | ||
933 | static bool kvm_ioapic_handles_vector(struct kvm_lapic *apic, int vector) | 933 | static bool kvm_ioapic_handles_vector(struct kvm_lapic *apic, int vector) |
934 | { | 934 | { |
935 | return test_bit(vector, (ulong *)apic->vcpu->arch.eoi_exit_bitmap); | 935 | return test_bit(vector, apic->vcpu->arch.ioapic_handled_vectors); |
936 | } | 936 | } |
937 | 937 | ||
938 | static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector) | 938 | static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector) |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 83a1c643f9a5..ebb76e8a91e1 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -3564,7 +3564,7 @@ static int svm_cpu_uses_apicv(struct kvm_vcpu *vcpu) | |||
3564 | return 0; | 3564 | return 0; |
3565 | } | 3565 | } |
3566 | 3566 | ||
3567 | static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu) | 3567 | static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) |
3568 | { | 3568 | { |
3569 | return; | 3569 | return; |
3570 | } | 3570 | } |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index af823a388c19..c8a87c94dc81 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -8257,9 +8257,8 @@ static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr) | |||
8257 | } | 8257 | } |
8258 | } | 8258 | } |
8259 | 8259 | ||
8260 | static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu) | 8260 | static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) |
8261 | { | 8261 | { |
8262 | u64 *eoi_exit_bitmap = vcpu->arch.eoi_exit_bitmap; | ||
8263 | if (!vmx_cpu_uses_apicv(vcpu)) | 8262 | if (!vmx_cpu_uses_apicv(vcpu)) |
8264 | return; | 8263 | return; |
8265 | 8264 | ||
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index eed32283d22c..9c69337a3d61 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -6301,15 +6301,16 @@ static void vcpu_scan_ioapic(struct kvm_vcpu *vcpu) | |||
6301 | if (!kvm_apic_hw_enabled(vcpu->arch.apic)) | 6301 | if (!kvm_apic_hw_enabled(vcpu->arch.apic)) |
6302 | return; | 6302 | return; |
6303 | 6303 | ||
6304 | memset(vcpu->arch.eoi_exit_bitmap, 0, 256 / 8); | 6304 | bitmap_zero(vcpu->arch.ioapic_handled_vectors, 256); |
6305 | 6305 | ||
6306 | if (irqchip_split(vcpu->kvm)) | 6306 | if (irqchip_split(vcpu->kvm)) |
6307 | kvm_scan_ioapic_routes(vcpu, vcpu->arch.eoi_exit_bitmap); | 6307 | kvm_scan_ioapic_routes(vcpu, vcpu->arch.ioapic_handled_vectors); |
6308 | else { | 6308 | else { |
6309 | kvm_x86_ops->sync_pir_to_irr(vcpu); | 6309 | kvm_x86_ops->sync_pir_to_irr(vcpu); |
6310 | kvm_ioapic_scan_entry(vcpu, vcpu->arch.eoi_exit_bitmap); | 6310 | kvm_ioapic_scan_entry(vcpu, vcpu->arch.ioapic_handled_vectors); |
6311 | } | 6311 | } |
6312 | kvm_x86_ops->load_eoi_exitmap(vcpu); | 6312 | kvm_x86_ops->load_eoi_exitmap(vcpu, |
6313 | (u64 *)vcpu->arch.ioapic_handled_vectors); | ||
6313 | } | 6314 | } |
6314 | 6315 | ||
6315 | static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu) | 6316 | static void kvm_vcpu_flush_tlb(struct kvm_vcpu *vcpu) |
@@ -6417,7 +6418,7 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
6417 | if (kvm_check_request(KVM_REQ_IOAPIC_EOI_EXIT, vcpu)) { | 6418 | if (kvm_check_request(KVM_REQ_IOAPIC_EOI_EXIT, vcpu)) { |
6418 | BUG_ON(vcpu->arch.pending_ioapic_eoi > 255); | 6419 | BUG_ON(vcpu->arch.pending_ioapic_eoi > 255); |
6419 | if (test_bit(vcpu->arch.pending_ioapic_eoi, | 6420 | if (test_bit(vcpu->arch.pending_ioapic_eoi, |
6420 | (void *) vcpu->arch.eoi_exit_bitmap)) { | 6421 | vcpu->arch.ioapic_handled_vectors)) { |
6421 | vcpu->run->exit_reason = KVM_EXIT_IOAPIC_EOI; | 6422 | vcpu->run->exit_reason = KVM_EXIT_IOAPIC_EOI; |
6422 | vcpu->run->eoi.vector = | 6423 | vcpu->run->eoi.vector = |
6423 | vcpu->arch.pending_ioapic_eoi; | 6424 | vcpu->arch.pending_ioapic_eoi; |