aboutsummaryrefslogtreecommitdiffstats
path: root/virt/kvm
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-04-14 19:21:28 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2014-04-14 19:21:28 -0400
commit55101e2d6ce1c780f6ee8fee5f37306971aac6cd (patch)
tree348adcfd97517ee9b5041f31df15cdd7fedb8ea7 /virt/kvm
parentdafe344d2288f0ebc0e3d4c6a5eb15bc82189c53 (diff)
parentb351c39cc9e0151cee9b8d52a1e714928faabb38 (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.c25
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
100static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
101
102static 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
100static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) 108static 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
128void kvm_rtc_eoi_tracking_restore_one(struct kvm_vcpu *vcpu) 135void 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
150static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu) 157static 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
158static bool rtc_irq_check_coalesced(struct kvm_ioapic *ioapic) 165static 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