diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-30 12:57:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-06-30 12:57:52 -0400 |
commit | 1a0a02d1efa066001fd315c1b4df583d939fa2c4 (patch) | |
tree | da3b7edf1abd667c732725d9b39374cb9827e383 | |
parent | 284341d2605da0ab231bc7486ff032c4f1563819 (diff) | |
parent | f5c5c225fce4cb98fe4451d4c4d654e3f18b9f82 (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.c | 1 | ||||
-rw-r--r-- | arch/x86/include/asm/pvclock.h | 25 | ||||
-rw-r--r-- | arch/x86/kernel/pvclock.c | 11 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 23 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 6 | ||||
-rw-r--r-- | arch/x86/kvm/x86.h | 7 | ||||
-rw-r--r-- | include/kvm/arm_pmu.h | 4 |
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 | ||
71 | static __always_inline | 71 | static __always_inline |
72 | u64 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 | |||
79 | static __always_inline | ||
80 | unsigned __pvclock_read_cycles(const struct pvclock_vcpu_time_info *src, | 72 | unsigned __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) | |||
61 | u8 pvclock_read_flags(struct pvclock_vcpu_time_info *src) | 61 | u8 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 | ||
1316 | static void start_apic_timer(struct kvm_lapic *apic) | 1317 | static 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); | |||
1244 | static DEFINE_PER_CPU(unsigned long, cpu_tsc_khz); | 1244 | static DEFINE_PER_CPU(unsigned long, cpu_tsc_khz); |
1245 | static unsigned long max_tsc_khz; | 1245 | static unsigned long max_tsc_khz; |
1246 | 1246 | ||
1247 | static 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 | |||
1253 | static u32 adjust_tsc_khz(u32 khz, s32 ppm) | 1247 | static 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 | ||
196 | extern struct static_key kvm_no_apic_vcpu; | 197 | extern struct static_key kvm_no_apic_vcpu; |
197 | 198 | ||
199 | static 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 | |||
28 | struct kvm_pmc { | 28 | struct 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; |