diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 14:35:30 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-08-07 14:35:30 -0400 |
commit | 66bb0aa077978dbb76e6283531eb3cc7a878de38 (patch) | |
tree | 62a28a96cb43df2d8f7c6eb14d4676a1e2ce3887 /arch/x86/kvm | |
parent | e306e3be1cbe5b11d0f8a53a557c205cf27e4979 (diff) | |
parent | c77dcacb397519b6ade8f08201a4a90a7f4f751e (diff) |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull second round of KVM changes from Paolo Bonzini:
"Here are the PPC and ARM changes for KVM, which I separated because
they had small conflicts (respectively within KVM documentation, and
with 3.16-rc changes). Since they were all within the subsystem, I
took care of them.
Stephen Rothwell reported some snags in PPC builds, but they are all
fixed now; the latest linux-next report was clean.
New features for ARM include:
- KVM VGIC v2 emulation on GICv3 hardware
- Big-Endian support for arm/arm64 (guest and host)
- Debug Architecture support for arm64 (arm32 is on Christoffer's todo list)
And for PPC:
- Book3S: Good number of LE host fixes, enable HV on LE
- Book3S HV: Add in-guest debug support
This release drops support for KVM on the PPC440. As a result, the
PPC merge removes more lines than it adds. :)
I also included an x86 change, since Davidlohr tied it to an
independent bug report and the reporter quickly provided a Tested-by;
there was no reason to wait for -rc2"
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (122 commits)
KVM: Move more code under CONFIG_HAVE_KVM_IRQFD
KVM: nVMX: fix "acknowledge interrupt on exit" when APICv is in use
KVM: nVMX: Fix nested vmexit ack intr before load vmcs01
KVM: PPC: Enable IRQFD support for the XICS interrupt controller
KVM: Give IRQFD its own separate enabling Kconfig option
KVM: Move irq notifier implementation into eventfd.c
KVM: Move all accesses to kvm::irq_routing into irqchip.c
KVM: irqchip: Provide and use accessors for irq routing table
KVM: Don't keep reference to irq routing table in irqfd struct
KVM: PPC: drop duplicate tracepoint
arm64: KVM: fix 64bit CP15 VM access for 32bit guests
KVM: arm64: GICv3: mandate page-aligned GICV region
arm64: KVM: GICv3: move system register access to msr_s/mrs_s
KVM: PPC: PR: Handle FSCR feature deselects
KVM: PPC: HV: Remove generic instruction emulation
KVM: PPC: BOOKEHV: rename e500hv_spr to bookehv_spr
KVM: PPC: Remove DCR handling
KVM: PPC: Expose helper functions for data/inst faults
KVM: PPC: Separate loadstore emulation from priv emulation
KVM: PPC: Handle magic page in kvmppc_ld/st
...
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r-- | arch/x86/kvm/Kconfig | 1 | ||||
-rw-r--r-- | arch/x86/kvm/irq.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 52 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 4 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 2 |
5 files changed, 44 insertions, 17 deletions
diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig index 287e4c85fff9..f9d16ff56c6b 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig | |||
@@ -27,6 +27,7 @@ config KVM | |||
27 | select MMU_NOTIFIER | 27 | select MMU_NOTIFIER |
28 | select ANON_INODES | 28 | select ANON_INODES |
29 | select HAVE_KVM_IRQCHIP | 29 | select HAVE_KVM_IRQCHIP |
30 | select HAVE_KVM_IRQFD | ||
30 | select HAVE_KVM_IRQ_ROUTING | 31 | select HAVE_KVM_IRQ_ROUTING |
31 | select HAVE_KVM_EVENTFD | 32 | select HAVE_KVM_EVENTFD |
32 | select KVM_APIC_ARCHITECTURE | 33 | select KVM_APIC_ARCHITECTURE |
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c index bd0da433e6d7..a1ec6a50a05a 100644 --- a/arch/x86/kvm/irq.c +++ b/arch/x86/kvm/irq.c | |||
@@ -108,7 +108,7 @@ int kvm_cpu_get_interrupt(struct kvm_vcpu *v) | |||
108 | 108 | ||
109 | vector = kvm_cpu_get_extint(v); | 109 | vector = kvm_cpu_get_extint(v); |
110 | 110 | ||
111 | if (kvm_apic_vid_enabled(v->kvm) || vector != -1) | 111 | if (vector != -1) |
112 | return vector; /* PIC */ | 112 | return vector; /* PIC */ |
113 | 113 | ||
114 | return kvm_get_apic_interrupt(v); /* APIC */ | 114 | return kvm_get_apic_interrupt(v); /* APIC */ |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 3855103f71fd..08e8a899e005 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -352,25 +352,46 @@ static inline int apic_find_highest_irr(struct kvm_lapic *apic) | |||
352 | 352 | ||
353 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) | 353 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) |
354 | { | 354 | { |
355 | apic->irr_pending = false; | 355 | struct kvm_vcpu *vcpu; |
356 | |||
357 | vcpu = apic->vcpu; | ||
358 | |||
356 | apic_clear_vector(vec, apic->regs + APIC_IRR); | 359 | apic_clear_vector(vec, apic->regs + APIC_IRR); |
357 | if (apic_search_irr(apic) != -1) | 360 | if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) |
358 | apic->irr_pending = true; | 361 | /* try to update RVI */ |
362 | kvm_make_request(KVM_REQ_EVENT, vcpu); | ||
363 | else { | ||
364 | vec = apic_search_irr(apic); | ||
365 | apic->irr_pending = (vec != -1); | ||
366 | } | ||
359 | } | 367 | } |
360 | 368 | ||
361 | static inline void apic_set_isr(int vec, struct kvm_lapic *apic) | 369 | static inline void apic_set_isr(int vec, struct kvm_lapic *apic) |
362 | { | 370 | { |
363 | /* Note that we never get here with APIC virtualization enabled. */ | 371 | struct kvm_vcpu *vcpu; |
372 | |||
373 | if (__apic_test_and_set_vector(vec, apic->regs + APIC_ISR)) | ||
374 | return; | ||
375 | |||
376 | vcpu = apic->vcpu; | ||
364 | 377 | ||
365 | if (!__apic_test_and_set_vector(vec, apic->regs + APIC_ISR)) | ||
366 | ++apic->isr_count; | ||
367 | BUG_ON(apic->isr_count > MAX_APIC_VECTOR); | ||
368 | /* | 378 | /* |
369 | * ISR (in service register) bit is set when injecting an interrupt. | 379 | * With APIC virtualization enabled, all caching is disabled |
370 | * The highest vector is injected. Thus the latest bit set matches | 380 | * because the processor can modify ISR under the hood. Instead |
371 | * the highest bit in ISR. | 381 | * just set SVI. |
372 | */ | 382 | */ |
373 | apic->highest_isr_cache = vec; | 383 | if (unlikely(kvm_apic_vid_enabled(vcpu->kvm))) |
384 | kvm_x86_ops->hwapic_isr_update(vcpu->kvm, vec); | ||
385 | else { | ||
386 | ++apic->isr_count; | ||
387 | BUG_ON(apic->isr_count > MAX_APIC_VECTOR); | ||
388 | /* | ||
389 | * ISR (in service register) bit is set when injecting an interrupt. | ||
390 | * The highest vector is injected. Thus the latest bit set matches | ||
391 | * the highest bit in ISR. | ||
392 | */ | ||
393 | apic->highest_isr_cache = vec; | ||
394 | } | ||
374 | } | 395 | } |
375 | 396 | ||
376 | static inline int apic_find_highest_isr(struct kvm_lapic *apic) | 397 | static inline int apic_find_highest_isr(struct kvm_lapic *apic) |
@@ -1627,11 +1648,16 @@ int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu) | |||
1627 | int vector = kvm_apic_has_interrupt(vcpu); | 1648 | int vector = kvm_apic_has_interrupt(vcpu); |
1628 | struct kvm_lapic *apic = vcpu->arch.apic; | 1649 | struct kvm_lapic *apic = vcpu->arch.apic; |
1629 | 1650 | ||
1630 | /* Note that we never get here with APIC virtualization enabled. */ | ||
1631 | |||
1632 | if (vector == -1) | 1651 | if (vector == -1) |
1633 | return -1; | 1652 | return -1; |
1634 | 1653 | ||
1654 | /* | ||
1655 | * We get here even with APIC virtualization enabled, if doing | ||
1656 | * nested virtualization and L1 runs with the "acknowledge interrupt | ||
1657 | * on exit" mode. Then we cannot inject the interrupt via RVI, | ||
1658 | * because the process would deliver it through the IDT. | ||
1659 | */ | ||
1660 | |||
1635 | apic_set_isr(vector, apic); | 1661 | apic_set_isr(vector, apic); |
1636 | apic_update_ppr(apic); | 1662 | apic_update_ppr(apic); |
1637 | apic_clear_irr(vector, apic); | 1663 | apic_clear_irr(vector, apic); |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index e618f34bde2d..bfe11cf124a1 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -8754,6 +8754,8 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, | |||
8754 | prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info, | 8754 | prepare_vmcs12(vcpu, vmcs12, exit_reason, exit_intr_info, |
8755 | exit_qualification); | 8755 | exit_qualification); |
8756 | 8756 | ||
8757 | vmx_load_vmcs01(vcpu); | ||
8758 | |||
8757 | if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT) | 8759 | if ((exit_reason == EXIT_REASON_EXTERNAL_INTERRUPT) |
8758 | && nested_exit_intr_ack_set(vcpu)) { | 8760 | && nested_exit_intr_ack_set(vcpu)) { |
8759 | int irq = kvm_cpu_get_interrupt(vcpu); | 8761 | int irq = kvm_cpu_get_interrupt(vcpu); |
@@ -8769,8 +8771,6 @@ static void nested_vmx_vmexit(struct kvm_vcpu *vcpu, u32 exit_reason, | |||
8769 | vmcs12->vm_exit_intr_error_code, | 8771 | vmcs12->vm_exit_intr_error_code, |
8770 | KVM_ISA_VMX); | 8772 | KVM_ISA_VMX); |
8771 | 8773 | ||
8772 | vmx_load_vmcs01(vcpu); | ||
8773 | |||
8774 | vm_entry_controls_init(vmx, vmcs_read32(VM_ENTRY_CONTROLS)); | 8774 | vm_entry_controls_init(vmx, vmcs_read32(VM_ENTRY_CONTROLS)); |
8775 | vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS)); | 8775 | vm_exit_controls_init(vmx, vmcs_read32(VM_EXIT_CONTROLS)); |
8776 | vmx_segment_cache_clear(vmx); | 8776 | vmx_segment_cache_clear(vmx); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index ca3d760dd581..8f1e22d3b286 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2636,7 +2636,7 @@ out: | |||
2636 | return r; | 2636 | return r; |
2637 | } | 2637 | } |
2638 | 2638 | ||
2639 | int kvm_dev_ioctl_check_extension(long ext) | 2639 | int kvm_vm_ioctl_check_extension(struct kvm *kvm, long ext) |
2640 | { | 2640 | { |
2641 | int r; | 2641 | int r; |
2642 | 2642 | ||