diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-14 19:21:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2014-04-14 19:21:28 -0400 |
commit | 55101e2d6ce1c780f6ee8fee5f37306971aac6cd (patch) | |
tree | 348adcfd97517ee9b5041f31df15cdd7fedb8ea7 /virt/kvm | |
parent | dafe344d2288f0ebc0e3d4c6a5eb15bc82189c53 (diff) | |
parent | b351c39cc9e0151cee9b8d52a1e714928faabb38 (diff) |
Merge git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Marcelo Tosatti:
- Fix for guest triggerable BUG_ON (CVE-2014-0155)
- CR4.SMAP support
- Spurious WARN_ON() fix
* git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: x86: remove WARN_ON from get_kernel_ns()
KVM: Rename variable smep to cr4_smep
KVM: expose SMAP feature to guest
KVM: Disable SMAP for guests in EPT realmode and EPT unpaging mode
KVM: Add SMAP support when setting CR4
KVM: Remove SMAP bit from CR4_RESERVED_BITS
KVM: ioapic: try to recover if pending_eoi goes out of range
KVM: ioapic: fix assignment of ioapic->rtc_status.pending_eoi (CVE-2014-0155)
Diffstat (limited to 'virt/kvm')
-rw-r--r-- | virt/kvm/ioapic.c | 25 |
1 files changed, 19 insertions, 6 deletions
diff --git a/virt/kvm/ioapic.c b/virt/kvm/ioapic.c index d4b601547f1f..2458a1dc2ba9 100644 --- a/virt/kvm/ioapic.c +++ b/virt/kvm/ioapic.c | |||
@@ -97,6 +97,14 @@ static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic) | |||
97 | bitmap_zero(ioapic->rtc_status.dest_map, KVM_MAX_VCPUS); | 97 | bitmap_zero(ioapic->rtc_status.dest_map, KVM_MAX_VCPUS); |
98 | } | 98 | } |
99 | 99 | ||
100 | static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic); | ||
101 | |||
102 | static void rtc_status_pending_eoi_check_valid(struct kvm_ioapic *ioapic) | ||
103 | { | ||
104 | if (WARN_ON(ioapic->rtc_status.pending_eoi < 0)) | ||
105 | kvm_rtc_eoi_tracking_restore_all(ioapic); | ||
106 | } | ||
107 | |||
100 | static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) | 108 | static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) |
101 | { | 109 | { |
102 | bool new_val, old_val; | 110 | bool new_val, old_val; |
@@ -120,9 +128,8 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) | |||
120 | } else { | 128 | } else { |
121 | __clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map); | 129 | __clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map); |
122 | ioapic->rtc_status.pending_eoi--; | 130 | ioapic->rtc_status.pending_eoi--; |
131 | rtc_status_pending_eoi_check_valid(ioapic); | ||
123 | } | 132 | } |
124 | |||
125 | WARN_ON(ioapic->rtc_status.pending_eoi < 0); | ||
126 | } | 133 | } |
127 | 134 | ||
128 | void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) | 135 | void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) |
@@ -149,10 +156,10 @@ static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic) | |||
149 | 156 | ||
150 | static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu) | 157 | static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu) |
151 | { | 158 | { |
152 | if (test_and_clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map)) | 159 | if (test_and_clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map)) { |
153 | --ioapic->rtc_status.pending_eoi; | 160 | --ioapic->rtc_status.pending_eoi; |
154 | 161 | rtc_status_pending_eoi_check_valid(ioapic); | |
155 | WARN_ON(ioapic->rtc_status.pending_eoi < 0); | 162 | } |
156 | } | 163 | } |
157 | 164 | ||
158 | static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic) | 165 | static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic) |
@@ -353,10 +360,16 @@ static int ioapic_service(struct kvm_ioapic *ioapic, int irq, bool line_status) | |||
353 | ioapic->irr &= ~(1 << irq); | 360 | ioapic->irr &= ~(1 << irq); |
354 | 361 | ||
355 | if (irq == RTC_GSI && line_status) { | 362 | if (irq == RTC_GSI && line_status) { |
363 | /* | ||
364 | * pending_eoi cannot ever become negative (see | ||
365 | * rtc_status_pending_eoi_check_valid) and the caller | ||
366 | * ensures that it is only called if it is >= zero, namely | ||
367 | * if rtc_irq_check_coalesced returns false). | ||
368 | */ | ||
356 | BUG_ON(ioapic->rtc_status.pending_eoi != 0); | 369 | BUG_ON(ioapic->rtc_status.pending_eoi != 0); |
357 | ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, | 370 | ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, |
358 | ioapic->rtc_status.dest_map); | 371 | ioapic->rtc_status.dest_map); |
359 | ioapic->rtc_status.pending_eoi = ret; | 372 | ioapic->rtc_status.pending_eoi = (ret < 0 ? 0 : ret); |
360 | } else | 373 | } else |
361 | ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL); | 374 | ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL); |
362 | 375 | ||