History

Merge git://git.kernel.org/pub/scm/virt/kvm/kvm

Pull kvm fixes from Marcelo Tosatti. * git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: Fix bounds checking in ioapic indirect register reads (CVE-2013-1798) KVM: x86: Convert MSR_KVM_SYSTEM_TIME to use gfn_to_hva_cache functions (CVE-2013-1797) KVM: x86: fix for buffer overflow in handling of MSR_KVM_SYSTEM_TIME (CVE-2013-1796) KVM: x86: fix deadlock in clock-in-progress request handling KVM: allow host header to be included even for !CONFIG_KVM

Linus Torvalds committed 13 years ago

Commit ea4a0ce2 parents 10b3866 a2c118b4 files · +44 −38Browse files

Unified · Split

4 files
  1. arch/x86/include/asm/kvm_host.h +2 −2
  2. arch/x86/kvm/x86.c +31 −33
  3. include/linux/kvm_host.h +6 −1
  4. virt/kvm/ioapic.c +5 −2
arch/x86/include/asm/kvm_host.h+2−2
@@ -414,8 +414,8 @@ struct kvm_vcpu_arch { · 413 unmodified lines
414414 gpa_t time;
415415 struct pvclock_vcpu_time_info hv_clock;
416416 unsigned int hw_tsc_khz;
417− unsigned int time_offset;
418− struct page *time_page;
417+ struct gfn_to_hva_cache pv_time;
418+ bool pv_time_enabled;
419419 /* set guest stopped flag in pvclock flags field */
420420 bool pvclock_set_guest_stopped_request;
421421
arch/x86/kvm/x86.c+31−33
@@ -1406,25 +1406,15 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) · 1405 unmodified lines
14061406 unsigned long flags, this_tsc_khz;
14071407 struct kvm_vcpu_arch *vcpu = &v->arch;
14081408 struct kvm_arch *ka = &v->kvm->arch;
1409− void *shared_kaddr;
14101409 s64 kernel_ns, max_kernel_ns;
14111410 u64 tsc_timestamp, host_tsc;
1412− struct pvclock_vcpu_time_info *guest_hv_clock;
1411+ struct pvclock_vcpu_time_info guest_hv_clock;
14131412 u8 pvclock_flags;
14141413 bool use_master_clock;
14151414
14161415 kernel_ns = 0;
14171416 host_tsc = 0;
14181417
1419− /* Keep irq disabled to prevent changes to the clock */
1420− local_irq_save(flags);
1421− this_tsc_khz = __get_cpu_var(cpu_tsc_khz);
1422− if (unlikely(this_tsc_khz == 0)) {
1423− local_irq_restore(flags);
1424− kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
1425− return 1;
1426− }
1427−
14281418 /*
14291419 * If the host uses TSC clock, then passthrough TSC as stable
14301420 * to the guest.
@@ -1436,6 +1426,15 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) · 5 unmodified lines
14361426 kernel_ns = ka->master_kernel_ns;
14371427 }
14381428 spin_unlock(&ka->pvclock_gtod_sync_lock);
1429+
1430+ /* Keep irq disabled to prevent changes to the clock */
1431+ local_irq_save(flags);
1432+ this_tsc_khz = __get_cpu_var(cpu_tsc_khz);
1433+ if (unlikely(this_tsc_khz == 0)) {
1434+ local_irq_restore(flags);
1435+ kvm_make_request(KVM_REQ_CLOCK_UPDATE, v);
1436+ return 1;
1437+ }
14391438 if (!use_master_clock) {
14401439 host_tsc = native_read_tsc();
14411440 kernel_ns = get_kernel_ns();
@@ -1463,7 +1462,7 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) · 21 unmodified lines
14631462
14641463 local_irq_restore(flags);
14651464
1466− if (!vcpu->time_page)
1465+ if (!vcpu->pv_time_enabled)
14671466 return 0;
14681467
14691468 /*
@@ -1525,12 +1524,12 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) · 55 unmodified lines
15251524 */
15261525 vcpu->hv_clock.version += 2;
15271526
1528− shared_kaddr = kmap_atomic(vcpu->time_page);
1529−
1530− guest_hv_clock = shared_kaddr + vcpu->time_offset;
1527+ if (unlikely(kvm_read_guest_cached(v->kvm, &vcpu->pv_time,
1528+ &guest_hv_clock, sizeof(guest_hv_clock))))
1529+ return 0;
15311530
15321531 /* retain PVCLOCK_GUEST_STOPPED if set in guest copy */
1533− pvclock_flags = (guest_hv_clock->flags & PVCLOCK_GUEST_STOPPED);
1532+ pvclock_flags = (guest_hv_clock.flags & PVCLOCK_GUEST_STOPPED);
15341533
15351534 if (vcpu->pvclock_set_guest_stopped_request) {
15361535 pvclock_flags |= PVCLOCK_GUEST_STOPPED;
@@ -1543,12 +1542,9 @@ static int kvm_guest_time_update(struct kvm_vcpu *v) · 6 unmodified lines
15431542
15441543 vcpu->hv_clock.flags = pvclock_flags;
15451544
1546− memcpy(shared_kaddr + vcpu->time_offset, &vcpu->hv_clock,
1547− sizeof(vcpu->hv_clock));
1548−
1549− kunmap_atomic(shared_kaddr);
1550−
1551− mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
1545+ kvm_write_guest_cached(v->kvm, &vcpu->pv_time,
1546+ &vcpu->hv_clock,
1547+ sizeof(vcpu->hv_clock));
15521548 return 0;
15531549 }
15541550
@@ -1837,10 +1833,7 @@ static int kvm_pv_enable_async_pf(struct kvm_vcpu *vcpu, u64 data) · 282 unmodified lines
18371833
18381834 static void kvmclock_reset(struct kvm_vcpu *vcpu)
18391835 {
1840− if (vcpu->arch.time_page) {
1841− kvm_release_page_dirty(vcpu->arch.time_page);
1842− vcpu->arch.time_page = NULL;
1843− }
1836+ vcpu->arch.pv_time_enabled = false;
18441837 }
18451838
18461839 static void accumulate_steal_time(struct kvm_vcpu *vcpu)
@@ -1947,6 +1940,7 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 100 unmodified lines
19471940 break;
19481941 case MSR_KVM_SYSTEM_TIME_NEW:
19491942 case MSR_KVM_SYSTEM_TIME: {
1943+ u64 gpa_offset;
19501944 kvmclock_reset(vcpu);
19511945
19521946 vcpu->arch.time = data;
@@ -1956,14 +1950,17 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info) · 3 unmodified lines
19561950 if (!(data & 1))
19571951 break;
19581952
1959− /* ...but clean it before doing the actual write */
1960− vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
1953+ gpa_offset = data & ~(PAGE_MASK | 1);
19611954
1962− vcpu->arch.time_page =
1963− gfn_to_page(vcpu->kvm, data >> PAGE_SHIFT);
1955+ /* Check that the address is 32-byte aligned. */
1956+ if (gpa_offset & (sizeof(struct pvclock_vcpu_time_info) - 1))
1957+ break;
19641958
1965− if (is_error_page(vcpu->arch.time_page))
1966− vcpu->arch.time_page = NULL;
1959+ if (kvm_gfn_to_hva_cache_init(vcpu->kvm,
1960+ &vcpu->arch.pv_time, data & ~1ULL))
1961+ vcpu->arch.pv_time_enabled = false;
1962+ else
1963+ vcpu->arch.pv_time_enabled = true;
19671964
19681965 break;
19691966 }
@@ -2967,7 +2964,7 @@ static int kvm_vcpu_ioctl_x86_set_xcrs(struct kvm_vcpu *vcpu, · 997 unmodified lines
29672964 */
29682965 static int kvm_set_guest_paused(struct kvm_vcpu *vcpu)
29692966 {
2970− if (!vcpu->arch.time_page)
2967+ if (!vcpu->arch.pv_time_enabled)
29712968 return -EINVAL;
29722969 vcpu->arch.pvclock_set_guest_stopped_request = true;
29732970 kvm_make_request(KVM_REQ_CLOCK_UPDATE, vcpu);
@@ -6718,6 +6715,7 @@ int kvm_arch_vcpu_init(struct kvm_vcpu *vcpu) · 3744 unmodified lines
67186715 goto fail_free_wbinvd_dirty_mask;
67196716
67206717 vcpu->arch.ia32_tsc_adjust_msr = 0x0;
6718+ vcpu->arch.pv_time_enabled = false;
67216719 kvm_async_pf_hash_reset(vcpu);
67226720 kvm_pmu_init(vcpu);
67236721
include/linux/kvm_host.h+6−1
@@ -1,6 +1,8 @@
11 #ifndef __KVM_HOST_H
22 #define __KVM_HOST_H
33
4+#if IS_ENABLED(CONFIG_KVM)
5+
46 /*
57 * This work is licensed under the terms of the GNU GPL, version 2. See
68 * the COPYING file in the top-level directory.
@@ -1055,5 +1057,8 @@ static inline bool kvm_vcpu_eligible_for_directed_yield(struct kvm_vcpu *vcpu) · 1048 unmodified lines
10551057 }
10561058
10571059 #endif /* CONFIG_HAVE_KVM_CPU_RELAX_INTERCEPT */
1060+#else
1061+static inline void __guest_enter(void) { return; }
1062+static inline void __guest_exit(void) { return; }
1063+#endif /* IS_ENABLED(CONFIG_KVM) */
10581064 #endif
1059−
virt/kvm/ioapic.c+5−2
@@ -74,9 +74,12 @@ static unsigned long ioapic_read_indirect(struct kvm_ioapic *ioapic, · 73 unmodified lines
7474 u32 redir_index = (ioapic->ioregsel - 0x10) >> 1;
7575 u64 redir_content;
7676
77− ASSERT(redir_index < IOAPIC_NUM_PINS);
77+ if (redir_index < IOAPIC_NUM_PINS)
78+ redir_content =
79+ ioapic->redirtbl[redir_index].bits;
80+ else
81+ redir_content = ~0ULL;
7882
79− redir_content = ioapic->redirtbl[redir_index].bits;
8083 result = (ioapic->ioregsel & 0x1) ?
8184 (redir_content >> 32) & 0xffffffff :
8285 redir_content & 0xffffffff;

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t