aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-06-30 12:57:52 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-06-30 12:57:52 -0400
commit1a0a02d1efa066001fd315c1b4df583d939fa2c4 (patch)
treeda3b7edf1abd667c732725d9b39374cb9827e383
parent284341d2605da0ab231bc7486ff032c4f1563819 (diff)
parentf5c5c225fce4cb98fe4451d4c4d654e3f18b9f82 (diff)
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM fixes from Paolo Bonzini: "ARM and x86 fixes" * tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: KVM: nVMX: VMX instructions: fix segment checks when L1 is in long mode. KVM: LAPIC: cap __delay at lapic_timer_advance_ns KVM: x86: move nsec_to_cycles from x86.c to x86.h pvclock: Get rid of __pvclock_read_cycles in function pvclock_read_flags pvclock: Cleanup to remove function pvclock_get_nsec_offset pvclock: Add CPU barriers to get correct version value KVM: arm/arm64: Stop leaking vcpu pid references arm64: KVM: fix build with CONFIG_ARM_PMU disabled
-rw-r--r--arch/arm/kvm/arm.c1
-rw-r--r--arch/x86/include/asm/pvclock.h25
-rw-r--r--arch/x86/kernel/pvclock.c11
-rw-r--r--arch/x86/kvm/lapic.c3
-rw-r--r--arch/x86/kvm/vmx.c23
-rw-r--r--arch/x86/kvm/x86.c6
-rw-r--r--arch/x86/kvm/x86.h7
-rw-r--r--include/kvm/arm_pmu.h4
8 files changed, 41 insertions, 39 deletions
diff --git a/arch/arm/kvm/arm.c b/arch/arm/kvm/arm.c
index 893941ec98dc..f1bde7c4e736 100644
--- a/arch/arm/kvm/arm.c
+++ b/arch/arm/kvm/arm.c
@@ -263,6 +263,7 @@ void kvm_arch_vcpu_free(struct kvm_vcpu *vcpu)
263 kvm_timer_vcpu_terminate(vcpu); 263 kvm_timer_vcpu_terminate(vcpu);
264 kvm_vgic_vcpu_destroy(vcpu); 264 kvm_vgic_vcpu_destroy(vcpu);
265 kvm_pmu_vcpu_destroy(vcpu); 265 kvm_pmu_vcpu_destroy(vcpu);
266 kvm_vcpu_uninit(vcpu);
266 kmem_cache_free(kvm_vcpu_cache, vcpu); 267 kmem_cache_free(kvm_vcpu_cache, vcpu);
267} 268}
268 269
diff --git a/arch/x86/include/asm/pvclock.h b/arch/x86/include/asm/pvclock.h
index fdcc04020636..7c1c89598688 100644
--- a/arch/x86/include/asm/pvclock.h
+++ b/arch/x86/include/asm/pvclock.h
@@ -69,29 +69,22 @@ static inline u64 pvclock_scale_delta(u64 delta, u32 mul_frac, int shift)
69} 69}
70 70
71static __always_inline 71static __always_inline
72u64 pvclock_get_nsec_offset(const struct pvclock_vcpu_time_info *src)
73{
74 u64 delta = rdtsc_ordered() - src->tsc_timestamp;
75 return pvclock_scale_delta(delta, src->tsc_to_system_mul,
76 src->tsc_shift);
77}
78
79static __always_inline
80unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src, 72unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src,
81 cycle_t *cycles, u8 *flags) 73 cycle_t *cycles, u8 *flags)
82{ 74{
83 unsigned version; 75 unsigned version;
84 cycle_t ret, offset; 76 cycle_t offset;
85 u8 ret_flags; 77 u64 delta;
86 78
87 version = src->version; 79 version = src->version;
80 /* Make the latest version visible */
81 smp_rmb();
88 82
89 offset = pvclock_get_nsec_offset(src); 83 delta = rdtsc_ordered() - src->tsc_timestamp;
90 ret = src->system_time + offset; 84 offset = pvclock_scale_delta(delta, src->tsc_to_system_mul,
91 ret_flags = src->flags; 85 src->tsc_shift);
92 86 *cycles = src->system_time + offset;
93 *cycles = ret; 87 *flags = src->flags;
94 *flags = ret_flags;
95 return version; 88 return version;
96} 89}
97 90
diff --git a/arch/x86/kernel/pvclock.c b/arch/x86/kernel/pvclock.c
index 99bfc025111d..06c58ce46762 100644
--- a/arch/x86/kernel/pvclock.c
+++ b/arch/x86/kernel/pvclock.c
@@ -61,11 +61,16 @@ void pvclock_resume(void)
61u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src) 61u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src)
62{ 62{
63 unsigned version; 63 unsigned version;
64 cycle_t ret;
65 u8 flags; 64 u8 flags;
66 65
67 do { 66 do {
68 version = __pvclock_read_cycles(src, &ret, &flags); 67 version = src->version;
68 /* Make the latest version visible */
69 smp_rmb();
70
71 flags = src->flags;
72 /* Make sure that the version double-check is last. */
73 smp_rmb();
69 } while ((src->version & 1) || version != src->version); 74 } while ((src->version & 1) || version != src->version);
70 75
71 return flags & valid_flags; 76 return flags & valid_flags;
@@ -80,6 +85,8 @@ cycle_t pvclock_clocksource_read(struct pvclock_vcpu_time_info *src)
80 85
81 do { 86 do {
82 version = __pvclock_read_cycles(src, &ret, &flags); 87 version = __pvclock_read_cycles(src, &ret, &flags);
88 /* Make sure that the version double-check is last. */
89 smp_rmb();
83 } while ((src->version & 1) || version != src->version); 90 } while ((src->version & 1) || version != src->version);
84 91
85 if (unlikely((flags & PVCLOCK_GUEST_STOPPED) != 0)) { 92 if (unlikely((flags & PVCLOCK_GUEST_STOPPED) != 0)) {
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c
index bbb5b283ff63..a397200281c1 100644
--- a/arch/x86/kvm/lapic.c
+++ b/arch/x86/kvm/lapic.c
@@ -1310,7 +1310,8 @@ void wait_lapic_expire(struct kvm_vcpu *vcpu)
1310 1310
1311 /* __delay is delay_tsc whenever the hardware has TSC, thus always. */ 1311 /* __delay is delay_tsc whenever the hardware has TSC, thus always. */
1312 if (guest_tsc < tsc_deadline) 1312 if (guest_tsc < tsc_deadline)
1313 __delay(tsc_deadline - guest_tsc); 1313 __delay(min(tsc_deadline - guest_tsc,
1314 nsec_to_cycles(vcpu, lapic_timer_advance_ns)));
1314} 1315}
1315 1316
1316static void start_apic_timer(struct kvm_lapic *apic) 1317static void start_apic_timer(struct kvm_lapic *apic)
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 003618e324ce..64a79f271276 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -6671,7 +6671,13 @@ static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
6671 6671
6672 /* Checks for #GP/#SS exceptions. */ 6672 /* Checks for #GP/#SS exceptions. */
6673 exn = false; 6673 exn = false;
6674 if (is_protmode(vcpu)) { 6674 if (is_long_mode(vcpu)) {
6675 /* Long mode: #GP(0)/#SS(0) if the memory address is in a
6676 * non-canonical form. This is the only check on the memory
6677 * destination for long mode!
6678 */
6679 exn = is_noncanonical_address(*ret);
6680 } else if (is_protmode(vcpu)) {
6675 /* Protected mode: apply checks for segment validity in the 6681 /* Protected mode: apply checks for segment validity in the
6676 * following order: 6682 * following order:
6677 * - segment type check (#GP(0) may be thrown) 6683 * - segment type check (#GP(0) may be thrown)
@@ -6688,17 +6694,10 @@ static int get_vmx_mem_address(struct kvm_vcpu *vcpu,
6688 * execute-only code segment 6694 * execute-only code segment
6689 */ 6695 */
6690 exn = ((s.type & 0xa) == 8); 6696 exn = ((s.type & 0xa) == 8);
6691 } 6697 if (exn) {
6692 if (exn) { 6698 kvm_queue_exception_e(vcpu, GP_VECTOR, 0);
6693 kvm_queue_exception_e(vcpu, GP_VECTOR, 0); 6699 return 1;
6694 return 1; 6700 }
6695 }
6696 if (is_long_mode(vcpu)) {
6697 /* Long mode: #GP(0)/#SS(0) if the memory address is in a
6698 * non-canonical form. This is an only check for long mode.
6699 */
6700 exn = is_noncanonical_address(*ret);
6701 } else if (is_protmode(vcpu)) {
6702 /* Protected mode: #GP(0)/#SS(0) if the segment is unusable. 6701 /* Protected mode: #GP(0)/#SS(0) if the segment is unusable.
6703 */ 6702 */
6704 exn = (s.unusable != 0); 6703 exn = (s.unusable != 0);
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 902d9da12392..7da5dd2057a9 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -1244,12 +1244,6 @@ static atomic_t kvm_guest_has_master_clock = ATOMIC_INIT(0);
1244static DEFINE_PER_CPU(unsigned long, cpu_tsc_khz); 1244static DEFINE_PER_CPU(unsigned long, cpu_tsc_khz);
1245static unsigned long max_tsc_khz; 1245static unsigned long max_tsc_khz;
1246 1246
1247static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
1248{
1249 return pvclock_scale_delta(nsec, vcpu->arch.virtual_tsc_mult,
1250 vcpu->arch.virtual_tsc_shift);
1251}
1252
1253static u32 adjust_tsc_khz(u32 khz, s32 ppm) 1247static u32 adjust_tsc_khz(u32 khz, s32 ppm)
1254{ 1248{
1255 u64 v = (u64)khz * (1000000 + ppm); 1249 u64 v = (u64)khz * (1000000 + ppm);
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 7ce3634ab5fe..a82ca466b62e 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -2,6 +2,7 @@
2#define ARCH_X86_KVM_X86_H 2#define ARCH_X86_KVM_X86_H
3 3
4#include <linux/kvm_host.h> 4#include <linux/kvm_host.h>
5#include <asm/pvclock.h>
5#include "kvm_cache_regs.h" 6#include "kvm_cache_regs.h"
6 7
7#define MSR_IA32_CR_PAT_DEFAULT 0x0007040600070406ULL 8#define MSR_IA32_CR_PAT_DEFAULT 0x0007040600070406ULL
@@ -195,6 +196,12 @@ extern unsigned int lapic_timer_advance_ns;
195 196
196extern struct static_key kvm_no_apic_vcpu; 197extern struct static_key kvm_no_apic_vcpu;
197 198
199static inline u64 nsec_to_cycles(struct kvm_vcpu *vcpu, u64 nsec)
200{
201 return pvclock_scale_delta(nsec, vcpu->arch.virtual_tsc_mult,
202 vcpu->arch.virtual_tsc_shift);
203}
204
198/* Same "calling convention" as do_div: 205/* Same "calling convention" as do_div:
199 * - divide (n << 32) by base 206 * - divide (n << 32) by base
200 * - put result in n 207 * - put result in n
diff --git a/include/kvm/arm_pmu.h b/include/kvm/arm_pmu.h
index fe389ac31489..92e7e97ca8ff 100644
--- a/include/kvm/arm_pmu.h
+++ b/include/kvm/arm_pmu.h
@@ -18,13 +18,13 @@
18#ifndef __ASM_ARM_KVM_PMU_H 18#ifndef __ASM_ARM_KVM_PMU_H
19#define __ASM_ARM_KVM_PMU_H 19#define __ASM_ARM_KVM_PMU_H
20 20
21#ifdef CONFIG_KVM_ARM_PMU
22
23#include <linux/perf_event.h> 21#include <linux/perf_event.h>
24#include <asm/perf_event.h> 22#include <asm/perf_event.h>
25 23
26#define ARMV8_PMU_CYCLE_IDX (ARMV8_PMU_MAX_COUNTERS - 1) 24#define ARMV8_PMU_CYCLE_IDX (ARMV8_PMU_MAX_COUNTERS - 1)
27 25
26#ifdef CONFIG_KVM_ARM_PMU
27
28struct kvm_pmc { 28struct kvm_pmc {
29 u8 idx; /* index into the pmu->pmc array */ 29 u8 idx; /* index into the pmu->pmc array */
30 struct perf_event *perf_event; 30 struct perf_event *perf_event;