Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fixes from Paolo Bonzini:
"Four security fixes for KVM on x86. Thanks to Andrew Honig and Lars
Bull from Google for reporting them"

* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm:
KVM: x86: fix guest-initiated crash with x2apic (CVE-2013-6376)
KVM: x86: Convert vapic synchronization to _cached functions (CVE-2013-6368)
KVM: x86: Fix potential divide by 0 in lapic (CVE-2013-6367)
KVM: Improve create VCPU parameter (CVE-2013-4587)

+27 -55
+21 -14
arch/x86/kvm/lapic.c
··· 143 143 return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; 144 144 } 145 145 146 + #define KVM_X2APIC_CID_BITS 0 147 + 146 148 static void recalculate_apic_map(struct kvm *kvm) 147 149 { 148 150 struct kvm_apic_map *new, *old = NULL; ··· 182 180 if (apic_x2apic_mode(apic)) { 183 181 new->ldr_bits = 32; 184 182 new->cid_shift = 16; 185 - new->cid_mask = new->lid_mask = 0xffff; 183 + new->cid_mask = (1 << KVM_X2APIC_CID_BITS) - 1; 184 + new->lid_mask = 0xffff; 186 185 } else if (kvm_apic_sw_enabled(apic) && 187 186 !new->cid_mask /* flat mode */ && 188 187 kvm_apic_get_reg(apic, APIC_DFR) == APIC_DFR_CLUSTER) { ··· 844 841 ASSERT(apic != NULL); 845 842 846 843 /* if initial count is 0, current count should also be 0 */ 847 - if (kvm_apic_get_reg(apic, APIC_TMICT) == 0) 844 + if (kvm_apic_get_reg(apic, APIC_TMICT) == 0 || 845 + apic->lapic_timer.period == 0) 848 846 return 0; 849 847 850 848 remaining = hrtimer_get_remaining(&apic->lapic_timer.timer); ··· 1695 1691 void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu) 1696 1692 { 1697 1693 u32 data; 1698 - void *vapic; 1699 1694 1700 1695 if (test_bit(KVM_APIC_PV_EOI_PENDING, &vcpu->arch.apic_attention)) 1701 1696 apic_sync_pv_eoi_from_guest(vcpu, vcpu->arch.apic); ··· 1702 1699 if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention)) 1703 1700 return; 1704 1701 1705 - vapic = kmap_atomic(vcpu->arch.apic->vapic_page); 1706 - data = *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)); 1707 - kunmap_atomic(vapic); 1702 + kvm_read_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data, 1703 + sizeof(u32)); 1708 1704 1709 1705 apic_set_tpr(vcpu->arch.apic, data & 0xff); 1710 1706 } ··· 1739 1737 u32 data, tpr; 1740 1738 int max_irr, max_isr; 1741 1739 struct kvm_lapic *apic = vcpu->arch.apic; 1742 - void *vapic; 1743 1740 1744 1741 apic_sync_pv_eoi_to_guest(vcpu, apic); 1745 1742 ··· 1754 1753 max_isr = 0; 1755 1754 data = (tpr & 0xff) | ((max_isr & 0xf0) << 8) | (max_irr << 24); 1756 1755 1757 - vapic = kmap_atomic(vcpu->arch.apic->vapic_page); 1758 - *(u32 *)(vapic + offset_in_page(vcpu->arch.apic->vapic_addr)) = data; 1759 - kunmap_atomic(vapic); 1756 + kvm_write_guest_cached(vcpu->kvm, &vcpu->arch.apic->vapic_cache, &data, 1757 + sizeof(u32)); 1760 1758 } 1761 1759 1762 - void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) 1760 + int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) 1763 1761 { 1764 - vcpu->arch.apic->vapic_addr = vapic_addr; 1765 - if (vapic_addr) 1762 + if (vapic_addr) { 1763 + if (kvm_gfn_to_hva_cache_init(vcpu->kvm, 1764 + &vcpu->arch.apic->vapic_cache, 1765 + vapic_addr, sizeof(u32))) 1766 + return -EINVAL; 1766 1767 __set_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention); 1767 - else 1768 + } else { 1768 1769 __clear_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention); 1770 + } 1771 + 1772 + vcpu->arch.apic->vapic_addr = vapic_addr; 1773 + return 0; 1769 1774 } 1770 1775 1771 1776 int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data)
+2 -2
arch/x86/kvm/lapic.h
··· 34 34 */ 35 35 void *regs; 36 36 gpa_t vapic_addr; 37 - struct page *vapic_page; 37 + struct gfn_to_hva_cache vapic_cache; 38 38 unsigned long pending_events; 39 39 unsigned int sipi_vector; 40 40 }; ··· 76 76 void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset); 77 77 void kvm_apic_set_eoi_accelerated(struct kvm_vcpu *vcpu, int vector); 78 78 79 - void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); 79 + int kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); 80 80 void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); 81 81 void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu); 82 82
+1 -39
arch/x86/kvm/x86.c
··· 3214 3214 r = -EFAULT; 3215 3215 if (copy_from_user(&va, argp, sizeof va)) 3216 3216 goto out; 3217 - r = 0; 3218 - kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); 3217 + r = kvm_lapic_set_vapic_addr(vcpu, va.vapic_addr); 3219 3218 break; 3220 3219 } 3221 3220 case KVM_X86_SETUP_MCE: { ··· 5738 5739 !kvm_event_needs_reinjection(vcpu); 5739 5740 } 5740 5741 5741 - static int vapic_enter(struct kvm_vcpu *vcpu) 5742 - { 5743 - struct kvm_lapic *apic = vcpu->arch.apic; 5744 - struct page *page; 5745 - 5746 - if (!apic || !apic->vapic_addr) 5747 - return 0; 5748 - 5749 - page = gfn_to_page(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); 5750 - if (is_error_page(page)) 5751 - return -EFAULT; 5752 - 5753 - vcpu->arch.apic->vapic_page = page; 5754 - return 0; 5755 - } 5756 - 5757 - static void vapic_exit(struct kvm_vcpu *vcpu) 5758 - { 5759 - struct kvm_lapic *apic = vcpu->arch.apic; 5760 - int idx; 5761 - 5762 - if (!apic || !apic->vapic_addr) 5763 - return; 5764 - 5765 - idx = srcu_read_lock(&vcpu->kvm->srcu); 5766 - kvm_release_page_dirty(apic->vapic_page); 5767 - mark_page_dirty(vcpu->kvm, apic->vapic_addr >> PAGE_SHIFT); 5768 - srcu_read_unlock(&vcpu->kvm->srcu, idx); 5769 - } 5770 - 5771 5742 static void update_cr8_intercept(struct kvm_vcpu *vcpu) 5772 5743 { 5773 5744 int max_irr, tpr; ··· 6038 6069 struct kvm *kvm = vcpu->kvm; 6039 6070 6040 6071 vcpu->srcu_idx = srcu_read_lock(&kvm->srcu); 6041 - r = vapic_enter(vcpu); 6042 - if (r) { 6043 - srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); 6044 - return r; 6045 - } 6046 6072 6047 6073 r = 1; 6048 6074 while (r > 0) { ··· 6095 6131 } 6096 6132 6097 6133 srcu_read_unlock(&kvm->srcu, vcpu->srcu_idx); 6098 - 6099 - vapic_exit(vcpu); 6100 6134 6101 6135 return r; 6102 6136 }
+3
virt/kvm/kvm_main.c
··· 1898 1898 int r; 1899 1899 struct kvm_vcpu *vcpu, *v; 1900 1900 1901 + if (id >= KVM_MAX_VCPUS) 1902 + return -EINVAL; 1903 + 1901 1904 vcpu = kvm_arch_vcpu_create(kvm, id); 1902 1905 if (IS_ERR(vcpu)) 1903 1906 return PTR_ERR(vcpu);