History

KVM: x86: Add KVM exit for IOAPIC EOIs

Adds KVM_EXIT_IOAPIC_EOI which allows the kernel to EOI level-triggered IOAPIC interrupts. Uses a per VCPU exit bitmap to decide whether or not the IOAPIC needs to be informed (which is identical to the EOI_EXIT_BITMAP field used by modern x86 processors, but can also be used to elide kvm IOAPIC EOI exits on older processors). [Note: A prototype using ResampleFDs found that decoupling the EOI from the VCPU's thread made it possible for the VCPU to not see a recent EOI after reentering the guest. This does not match real hardware.] Compile tested for Intel x86.

Steve Rutherford committed 11 years ago

Commit 7543a631 parent 49df6396 files · +48 −8Browse files

Unified · Split

6 files
  1. Documentation/virtual/kvm/api.txt +12 −0
  2. arch/x86/include/asm/kvm_host.h +2 −0
  3. arch/x86/kvm/lapic.c +17 −7
  4. arch/x86/kvm/x86.c +11 −0
  5. include/linux/kvm_host.h +1 −1
  6. include/uapi/linux/kvm.h +5 −0
Documentation/virtual/kvm/api.txt+12−0
@@ -3309,6 +3309,18 @@ Valid values for 'type' are: · 3308 unmodified lines
3309 to ignore the request, or to gather VM memory core dump and/or3309 to ignore the request, or to gather VM memory core dump and/or
3310 reset/shutdown of the VM.3310 reset/shutdown of the VM.
3311 3311
3312 /* KVM_EXIT_IOAPIC_EOI */
3313 struct {
3314 __u8 vector;
3315 } eoi;
3316
3317Indicates that the VCPU's in-kernel local APIC received an EOI for a
3318level-triggered IOAPIC interrupt. This exit only triggers when the
3319IOAPIC is implemented in userspace (i.e. KVM_CAP_SPLIT_IRQCHIP is enabled);
3320the userspace IOAPIC should process the EOI and retrigger the interrupt if
3321it is still asserted. Vector is the LAPIC interrupt vector for which the
3322EOI was received.
3323
3312 /* Fix the size of the union. */3324 /* Fix the size of the union. */
3313 char padding[256];3325 char padding[256];
3314 };3326 };
arch/x86/include/asm/kvm_host.h+2−0
@@ -574,6 +574,8 @@ struct kvm_vcpu_arch { · 573 unmodified lines
574 struct {574 struct {
575 bool pv_unhalted;575 bool pv_unhalted;
576 } pv;576 } pv;
577
578 int pending_ioapic_eoi;
577};579};
578 580
579struct kvm_lpage_info {581struct kvm_lpage_info {
arch/x86/kvm/lapic.c+17−7
@@ -877,15 +877,25 @@ static bool kvm_ioapic_handles_vector(struct kvm_lapic *apic, int vector) · 876 unmodified lines
877 877
878static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector)878static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector)
879{879{
880 if (kvm_ioapic_handles_vector(apic, vector)) {880 int trigger_mode;
881 int trigger_mode;881
882 if (apic_test_vector(vector, apic->regs + APIC_TMR))882 /* Eoi the ioapic only if the ioapic doesn't own the vector. */
883 trigger_mode = IOAPIC_LEVEL_TRIG;883 if (!kvm_ioapic_handles_vector(apic, vector))
884 else884 return;
885 trigger_mode = IOAPIC_EDGE_TRIG;
886 885
887 kvm_ioapic_update_eoi(apic->vcpu, vector, trigger_mode);886 /* Request a KVM exit to inform the userspace IOAPIC. */
887 if (irqchip_split(apic->vcpu->kvm)) {
888 apic->vcpu->arch.pending_ioapic_eoi = vector;
889 kvm_make_request(KVM_REQ_IOAPIC_EOI_EXIT, apic->vcpu);
890 return;
888 }891 }
892
893 if (apic_test_vector(vector, apic->regs + APIC_TMR))
894 trigger_mode = IOAPIC_LEVEL_TRIG;
895 else
896 trigger_mode = IOAPIC_EDGE_TRIG;
897
898 kvm_ioapic_update_eoi(apic->vcpu, vector, trigger_mode);
889}899}
890 900
891static int apic_set_eoi(struct kvm_lapic *apic)901static int apic_set_eoi(struct kvm_lapic *apic)
arch/x86/kvm/x86.c+11−0
@@ -6271,6 +6271,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) · 6270 unmodified lines
6271 kvm_pmu_handle_event(vcpu);6271 kvm_pmu_handle_event(vcpu);
6272 if (kvm_check_request(KVM_REQ_PMI, vcpu))6272 if (kvm_check_request(KVM_REQ_PMI, vcpu))
6273 kvm_pmu_deliver_pmi(vcpu);6273 kvm_pmu_deliver_pmi(vcpu);
6274 if (kvm_check_request(KVM_REQ_IOAPIC_EOI_EXIT, vcpu)) {
6275 BUG_ON(vcpu->arch.pending_ioapic_eoi > 255);
6276 if (test_bit(vcpu->arch.pending_ioapic_eoi,
6277 (void *) vcpu->arch.eoi_exit_bitmap)) {
6278 vcpu->run->exit_reason = KVM_EXIT_IOAPIC_EOI;
6279 vcpu->run->eoi.vector =
6280 vcpu->arch.pending_ioapic_eoi;
6281 r = 0;
6282 goto out;
6283 }
6284 }
6274 if (kvm_check_request(KVM_REQ_SCAN_IOAPIC, vcpu))6285 if (kvm_check_request(KVM_REQ_SCAN_IOAPIC, vcpu))
6275 vcpu_scan_ioapic(vcpu);6286 vcpu_scan_ioapic(vcpu);
6276 if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))6287 if (kvm_check_request(KVM_REQ_APIC_PAGE_RELOAD, vcpu))
include/linux/kvm_host.h+1−1
@@ -140,6 +140,7 @@ static inline bool is_error_page(struct page *page) · 139 unmodified lines
140#define KVM_REQ_APIC_PAGE_RELOAD 25140#define KVM_REQ_APIC_PAGE_RELOAD 25
141#define KVM_REQ_SMI 26141#define KVM_REQ_SMI 26
142#define KVM_REQ_HV_CRASH 27142#define KVM_REQ_HV_CRASH 27
143#define KVM_REQ_IOAPIC_EOI_EXIT 28
143 144
144#define KVM_USERSPACE_IRQ_SOURCE_ID 0145#define KVM_USERSPACE_IRQ_SOURCE_ID 0
145#define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID 1146#define KVM_IRQFD_RESAMPLE_IRQ_SOURCE_ID 1
@@ -1146,4 +1147,3 @@ static inline void kvm_vcpu_set_dy_eligible(struct kvm_vcpu *vcpu, bool val) · 1000 unmodified lines
1146}1147}
1147#endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */1148#endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
1148#endif1149#endif
1149
include/uapi/linux/kvm.h+5−0
@@ -183,6 +183,7 @@ struct kvm_s390_skeys { · 182 unmodified lines
183#define KVM_EXIT_EPR 23183#define KVM_EXIT_EPR 23
184#define KVM_EXIT_SYSTEM_EVENT 24184#define KVM_EXIT_SYSTEM_EVENT 24
185#define KVM_EXIT_S390_STSI 25185#define KVM_EXIT_S390_STSI 25
186#define KVM_EXIT_IOAPIC_EOI 26
186 187
187/* For KVM_EXIT_INTERNAL_ERROR */188/* For KVM_EXIT_INTERNAL_ERROR */
188/* Emulate instruction failed. */189/* Emulate instruction failed. */
@@ -333,6 +334,10 @@ struct kvm_run { · 144 unmodified lines
333 __u8 sel1;334 __u8 sel1;
334 __u16 sel2;335 __u16 sel2;
335 } s390_stsi;336 } s390_stsi;
337 /* KVM_EXIT_IOAPIC_EOI */
338 struct {
339 __u8 vector;
340 } eoi;
336 /* Fix the size of the union. */341 /* Fix the size of the union. */
337 char padding[256];342 char padding[256];
338 };343 };

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t