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)
This commit is contained in:
+19
-6
@@ -97,6 +97,14 @@ static void rtc_irq_eoi_tracking_reset(struct kvm_ioapic *ioapic)
|
||||
bitmap_zero(ioapic->rtc_status.dest_map, KVM_MAX_VCPUS);
|
||||
}
|
||||
|
||||
static void kvm_rtc_eoi_tracking_restore_all(struct kvm_ioapic *ioapic);
|
||||
|
||||
static void rtc_status_pending_eoi_check_valid(struct kvm_ioapic *ioapic)
|
||||
{
|
||||
if (WARN_ON(ioapic->rtc_status.pending_eoi < 0))
|
||||
kvm_rtc_eoi_tracking_restore_all(ioapic);
|
||||
}
|
||||
|
||||
static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
bool new_val, old_val;
|
||||
@@ -120,9 +128,8 @@ static void __rtc_irq_eoi_tracking_restore_one(struct kvm_vcpu *vcpu)
|
||||
} else {
|
||||
__clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map);
|
||||
ioapic->rtc_status.pending_eoi--;
|
||||
rtc_status_pending_eoi_check_valid(ioapic);
|
||||
}
|
||||
|
||||
WARN_ON(ioapic->rtc_status.pending_eoi < 0);
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
static void rtc_irq_eoi(struct kvm_ioapic *ioapic, struct kvm_vcpu *vcpu)
|
||||
{
|
||||
if (test_and_clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map))
|
||||
if (test_and_clear_bit(vcpu->vcpu_id, ioapic->rtc_status.dest_map)) {
|
||||
--ioapic->rtc_status.pending_eoi;
|
||||
|
||||
WARN_ON(ioapic->rtc_status.pending_eoi < 0);
|
||||
rtc_status_pending_eoi_check_valid(ioapic);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
ioapic->irr &= ~(1 << irq);
|
||||
|
||||
if (irq == RTC_GSI && line_status) {
|
||||
/*
|
||||
* pending_eoi cannot ever become negative (see
|
||||
* rtc_status_pending_eoi_check_valid) and the caller
|
||||
* ensures that it is only called if it is >= zero, namely
|
||||
* if rtc_irq_check_coalesced returns false).
|
||||
*/
|
||||
BUG_ON(ioapic->rtc_status.pending_eoi != 0);
|
||||
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe,
|
||||
ioapic->rtc_status.dest_map);
|
||||
ioapic->rtc_status.pending_eoi = ret;
|
||||
ioapic->rtc_status.pending_eoi = (ret < 0 ? 0 : ret);
|
||||
} else
|
||||
ret = kvm_irq_delivery_to_apic(ioapic->kvm, NULL, &irqe, NULL);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user