diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-12 18:35:14 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2019-07-12 18:35:14 -0400 |
commit | 39d7530d7494b4e47ba1856e741f513dafd17e3d (patch) | |
tree | 6b16a744047cff9ff77f26bc5811fe9d953a9b91 /virt | |
parent | 16c97650a56abdd067f7da079007b7e00b307083 (diff) | |
parent | a45ff5994c9cde41af627c46abb9f32beae68943 (diff) |
Merge tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm
Pull KVM updates from Paolo Bonzini:
"ARM:
- support for chained PMU counters in guests
- improved SError handling
- handle Neoverse N1 erratum #1349291
- allow side-channel mitigation status to be migrated
- standardise most AArch64 system register accesses to msr_s/mrs_s
- fix host MPIDR corruption on 32bit
- selftests ckleanups
x86:
- PMU event {white,black}listing
- ability for the guest to disable host-side interrupt polling
- fixes for enlightened VMCS (Hyper-V pv nested virtualization),
- new hypercall to yield to IPI target
- support for passing cstate MSRs through to the guest
- lots of cleanups and optimizations
Generic:
- Some txt->rST conversions for the documentation"
* tag 'for-linus' of git://git.kernel.org/pub/scm/virt/kvm/kvm: (128 commits)
Documentation: virtual: Add toctree hooks
Documentation: kvm: Convert cpuid.txt to .rst
Documentation: virtual: Convert paravirt_ops.txt to .rst
KVM: x86: Unconditionally enable irqs in guest context
KVM: x86: PMU Event Filter
kvm: x86: Fix -Wmissing-prototypes warnings
KVM: Properly check if "page" is valid in kvm_vcpu_unmap
KVM: arm/arm64: Initialise host's MPIDRs by reading the actual register
KVM: LAPIC: Retry tune per-vCPU timer_advance_ns if adaptive tuning goes insane
kvm: LAPIC: write down valid APIC registers
KVM: arm64: Migrate _elx sysreg accessors to msr_s/mrs_s
KVM: doc: Add API documentation on the KVM_REG_ARM_WORKAROUNDS register
KVM: arm/arm64: Add save/restore support for firmware workaround state
arm64: KVM: Propagate full Spectre v2 workaround state to KVM guests
KVM: arm/arm64: Support chained PMU counters
KVM: arm/arm64: Remove pmc->bitmask
KVM: arm/arm64: Re-create event when setting counter value
KVM: arm/arm64: Extract duplicated code to own function
KVM: arm/arm64: Rename kvm_pmu_{enable/disable}_counter functions
KVM: LAPIC: ARBPRI is a reserved register for x2APIC
...
Diffstat (limited to 'virt')
-rw-r--r-- | virt/kvm/arm/arch_timer.c | 24 | ||||
-rw-r--r-- | virt/kvm/arm/arm.c | 7 | ||||
-rw-r--r-- | virt/kvm/arm/pmu.c | 350 | ||||
-rw-r--r-- | virt/kvm/arm/psci.c | 149 | ||||
-rw-r--r-- | virt/kvm/irqchip.c | 4 | ||||
-rw-r--r-- | virt/kvm/kvm_main.c | 41 |
6 files changed, 455 insertions, 120 deletions
diff --git a/virt/kvm/arm/arch_timer.c b/virt/kvm/arm/arch_timer.c index 1be486d5d7cb..e2bb5bd60227 100644 --- a/virt/kvm/arm/arch_timer.c +++ b/virt/kvm/arm/arch_timer.c | |||
@@ -237,10 +237,10 @@ static bool kvm_timer_should_fire(struct arch_timer_context *timer_ctx) | |||
237 | 237 | ||
238 | switch (index) { | 238 | switch (index) { |
239 | case TIMER_VTIMER: | 239 | case TIMER_VTIMER: |
240 | cnt_ctl = read_sysreg_el0(cntv_ctl); | 240 | cnt_ctl = read_sysreg_el0(SYS_CNTV_CTL); |
241 | break; | 241 | break; |
242 | case TIMER_PTIMER: | 242 | case TIMER_PTIMER: |
243 | cnt_ctl = read_sysreg_el0(cntp_ctl); | 243 | cnt_ctl = read_sysreg_el0(SYS_CNTP_CTL); |
244 | break; | 244 | break; |
245 | case NR_KVM_TIMERS: | 245 | case NR_KVM_TIMERS: |
246 | /* GCC is braindead */ | 246 | /* GCC is braindead */ |
@@ -350,20 +350,20 @@ static void timer_save_state(struct arch_timer_context *ctx) | |||
350 | 350 | ||
351 | switch (index) { | 351 | switch (index) { |
352 | case TIMER_VTIMER: | 352 | case TIMER_VTIMER: |
353 | ctx->cnt_ctl = read_sysreg_el0(cntv_ctl); | 353 | ctx->cnt_ctl = read_sysreg_el0(SYS_CNTV_CTL); |
354 | ctx->cnt_cval = read_sysreg_el0(cntv_cval); | 354 | ctx->cnt_cval = read_sysreg_el0(SYS_CNTV_CVAL); |
355 | 355 | ||
356 | /* Disable the timer */ | 356 | /* Disable the timer */ |
357 | write_sysreg_el0(0, cntv_ctl); | 357 | write_sysreg_el0(0, SYS_CNTV_CTL); |
358 | isb(); | 358 | isb(); |
359 | 359 | ||
360 | break; | 360 | break; |
361 | case TIMER_PTIMER: | 361 | case TIMER_PTIMER: |
362 | ctx->cnt_ctl = read_sysreg_el0(cntp_ctl); | 362 | ctx->cnt_ctl = read_sysreg_el0(SYS_CNTP_CTL); |
363 | ctx->cnt_cval = read_sysreg_el0(cntp_cval); | 363 | ctx->cnt_cval = read_sysreg_el0(SYS_CNTP_CVAL); |
364 | 364 | ||
365 | /* Disable the timer */ | 365 | /* Disable the timer */ |
366 | write_sysreg_el0(0, cntp_ctl); | 366 | write_sysreg_el0(0, SYS_CNTP_CTL); |
367 | isb(); | 367 | isb(); |
368 | 368 | ||
369 | break; | 369 | break; |
@@ -429,14 +429,14 @@ static void timer_restore_state(struct arch_timer_context *ctx) | |||
429 | 429 | ||
430 | switch (index) { | 430 | switch (index) { |
431 | case TIMER_VTIMER: | 431 | case TIMER_VTIMER: |
432 | write_sysreg_el0(ctx->cnt_cval, cntv_cval); | 432 | write_sysreg_el0(ctx->cnt_cval, SYS_CNTV_CVAL); |
433 | isb(); | 433 | isb(); |
434 | write_sysreg_el0(ctx->cnt_ctl, cntv_ctl); | 434 | write_sysreg_el0(ctx->cnt_ctl, SYS_CNTV_CTL); |
435 | break; | 435 | break; |
436 | case TIMER_PTIMER: | 436 | case TIMER_PTIMER: |
437 | write_sysreg_el0(ctx->cnt_cval, cntp_cval); | 437 | write_sysreg_el0(ctx->cnt_cval, SYS_CNTP_CVAL); |
438 | isb(); | 438 | isb(); |
439 | write_sysreg_el0(ctx->cnt_ctl, cntp_ctl); | 439 | write_sysreg_el0(ctx->cnt_ctl, SYS_CNTP_CTL); |
440 | break; | 440 | break; |
441 | case NR_KVM_TIMERS: | 441 | case NR_KVM_TIMERS: |
442 | BUG(); | 442 | BUG(); |
diff --git a/virt/kvm/arm/arm.c b/virt/kvm/arm/arm.c index bd5c55916d0d..f645c0fbf7ec 100644 --- a/virt/kvm/arm/arm.c +++ b/virt/kvm/arm/arm.c | |||
@@ -93,9 +93,9 @@ int kvm_arch_hardware_setup(void) | |||
93 | return 0; | 93 | return 0; |
94 | } | 94 | } |
95 | 95 | ||
96 | void kvm_arch_check_processor_compat(void *rtn) | 96 | int kvm_arch_check_processor_compat(void) |
97 | { | 97 | { |
98 | *(int *)rtn = 0; | 98 | return 0; |
99 | } | 99 | } |
100 | 100 | ||
101 | 101 | ||
@@ -1332,6 +1332,8 @@ static void cpu_hyp_reset(void) | |||
1332 | 1332 | ||
1333 | static void cpu_hyp_reinit(void) | 1333 | static void cpu_hyp_reinit(void) |
1334 | { | 1334 | { |
1335 | kvm_init_host_cpu_context(&this_cpu_ptr(&kvm_host_data)->host_ctxt); | ||
1336 | |||
1335 | cpu_hyp_reset(); | 1337 | cpu_hyp_reset(); |
1336 | 1338 | ||
1337 | if (is_kernel_in_hyp_mode()) | 1339 | if (is_kernel_in_hyp_mode()) |
@@ -1569,7 +1571,6 @@ static int init_hyp_mode(void) | |||
1569 | kvm_host_data_t *cpu_data; | 1571 | kvm_host_data_t *cpu_data; |
1570 | 1572 | ||
1571 | cpu_data = per_cpu_ptr(&kvm_host_data, cpu); | 1573 | cpu_data = per_cpu_ptr(&kvm_host_data, cpu); |
1572 | kvm_init_host_cpu_context(&cpu_data->host_ctxt, cpu); | ||
1573 | err = create_hyp_mappings(cpu_data, cpu_data + 1, PAGE_HYP); | 1574 | err = create_hyp_mappings(cpu_data, cpu_data + 1, PAGE_HYP); |
1574 | 1575 | ||
1575 | if (err) { | 1576 | if (err) { |
diff --git a/virt/kvm/arm/pmu.c b/virt/kvm/arm/pmu.c index da740764a7ee..3dd8238ed246 100644 --- a/virt/kvm/arm/pmu.c +++ b/virt/kvm/arm/pmu.c | |||
@@ -13,29 +13,144 @@ | |||
13 | #include <kvm/arm_pmu.h> | 13 | #include <kvm/arm_pmu.h> |
14 | #include <kvm/arm_vgic.h> | 14 | #include <kvm/arm_vgic.h> |
15 | 15 | ||
16 | static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx); | ||
17 | |||
18 | #define PERF_ATTR_CFG1_KVM_PMU_CHAINED 0x1 | ||
19 | |||
16 | /** | 20 | /** |
17 | * kvm_pmu_get_counter_value - get PMU counter value | 21 | * kvm_pmu_idx_is_64bit - determine if select_idx is a 64bit counter |
18 | * @vcpu: The vcpu pointer | 22 | * @vcpu: The vcpu pointer |
19 | * @select_idx: The counter index | 23 | * @select_idx: The counter index |
20 | */ | 24 | */ |
21 | u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx) | 25 | static bool kvm_pmu_idx_is_64bit(struct kvm_vcpu *vcpu, u64 select_idx) |
22 | { | 26 | { |
23 | u64 counter, reg, enabled, running; | 27 | return (select_idx == ARMV8_PMU_CYCLE_IDX && |
24 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 28 | __vcpu_sys_reg(vcpu, PMCR_EL0) & ARMV8_PMU_PMCR_LC); |
25 | struct kvm_pmc *pmc = &pmu->pmc[select_idx]; | 29 | } |
26 | 30 | ||
27 | reg = (select_idx == ARMV8_PMU_CYCLE_IDX) | 31 | static struct kvm_vcpu *kvm_pmc_to_vcpu(struct kvm_pmc *pmc) |
28 | ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + select_idx; | 32 | { |
29 | counter = __vcpu_sys_reg(vcpu, reg); | 33 | struct kvm_pmu *pmu; |
34 | struct kvm_vcpu_arch *vcpu_arch; | ||
35 | |||
36 | pmc -= pmc->idx; | ||
37 | pmu = container_of(pmc, struct kvm_pmu, pmc[0]); | ||
38 | vcpu_arch = container_of(pmu, struct kvm_vcpu_arch, pmu); | ||
39 | return container_of(vcpu_arch, struct kvm_vcpu, arch); | ||
40 | } | ||
41 | |||
42 | /** | ||
43 | * kvm_pmu_pmc_is_chained - determine if the pmc is chained | ||
44 | * @pmc: The PMU counter pointer | ||
45 | */ | ||
46 | static bool kvm_pmu_pmc_is_chained(struct kvm_pmc *pmc) | ||
47 | { | ||
48 | struct kvm_vcpu *vcpu = kvm_pmc_to_vcpu(pmc); | ||
30 | 49 | ||
31 | /* The real counter value is equal to the value of counter register plus | 50 | return test_bit(pmc->idx >> 1, vcpu->arch.pmu.chained); |
51 | } | ||
52 | |||
53 | /** | ||
54 | * kvm_pmu_idx_is_high_counter - determine if select_idx is a high/low counter | ||
55 | * @select_idx: The counter index | ||
56 | */ | ||
57 | static bool kvm_pmu_idx_is_high_counter(u64 select_idx) | ||
58 | { | ||
59 | return select_idx & 0x1; | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * kvm_pmu_get_canonical_pmc - obtain the canonical pmc | ||
64 | * @pmc: The PMU counter pointer | ||
65 | * | ||
66 | * When a pair of PMCs are chained together we use the low counter (canonical) | ||
67 | * to hold the underlying perf event. | ||
68 | */ | ||
69 | static struct kvm_pmc *kvm_pmu_get_canonical_pmc(struct kvm_pmc *pmc) | ||
70 | { | ||
71 | if (kvm_pmu_pmc_is_chained(pmc) && | ||
72 | kvm_pmu_idx_is_high_counter(pmc->idx)) | ||
73 | return pmc - 1; | ||
74 | |||
75 | return pmc; | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * kvm_pmu_idx_has_chain_evtype - determine if the event type is chain | ||
80 | * @vcpu: The vcpu pointer | ||
81 | * @select_idx: The counter index | ||
82 | */ | ||
83 | static bool kvm_pmu_idx_has_chain_evtype(struct kvm_vcpu *vcpu, u64 select_idx) | ||
84 | { | ||
85 | u64 eventsel, reg; | ||
86 | |||
87 | select_idx |= 0x1; | ||
88 | |||
89 | if (select_idx == ARMV8_PMU_CYCLE_IDX) | ||
90 | return false; | ||
91 | |||
92 | reg = PMEVTYPER0_EL0 + select_idx; | ||
93 | eventsel = __vcpu_sys_reg(vcpu, reg) & ARMV8_PMU_EVTYPE_EVENT; | ||
94 | |||
95 | return eventsel == ARMV8_PMUV3_PERFCTR_CHAIN; | ||
96 | } | ||
97 | |||
98 | /** | ||
99 | * kvm_pmu_get_pair_counter_value - get PMU counter value | ||
100 | * @vcpu: The vcpu pointer | ||
101 | * @pmc: The PMU counter pointer | ||
102 | */ | ||
103 | static u64 kvm_pmu_get_pair_counter_value(struct kvm_vcpu *vcpu, | ||
104 | struct kvm_pmc *pmc) | ||
105 | { | ||
106 | u64 counter, counter_high, reg, enabled, running; | ||
107 | |||
108 | if (kvm_pmu_pmc_is_chained(pmc)) { | ||
109 | pmc = kvm_pmu_get_canonical_pmc(pmc); | ||
110 | reg = PMEVCNTR0_EL0 + pmc->idx; | ||
111 | |||
112 | counter = __vcpu_sys_reg(vcpu, reg); | ||
113 | counter_high = __vcpu_sys_reg(vcpu, reg + 1); | ||
114 | |||
115 | counter = lower_32_bits(counter) | (counter_high << 32); | ||
116 | } else { | ||
117 | reg = (pmc->idx == ARMV8_PMU_CYCLE_IDX) | ||
118 | ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + pmc->idx; | ||
119 | counter = __vcpu_sys_reg(vcpu, reg); | ||
120 | } | ||
121 | |||
122 | /* | ||
123 | * The real counter value is equal to the value of counter register plus | ||
32 | * the value perf event counts. | 124 | * the value perf event counts. |
33 | */ | 125 | */ |
34 | if (pmc->perf_event) | 126 | if (pmc->perf_event) |
35 | counter += perf_event_read_value(pmc->perf_event, &enabled, | 127 | counter += perf_event_read_value(pmc->perf_event, &enabled, |
36 | &running); | 128 | &running); |
37 | 129 | ||
38 | return counter & pmc->bitmask; | 130 | return counter; |
131 | } | ||
132 | |||
133 | /** | ||
134 | * kvm_pmu_get_counter_value - get PMU counter value | ||
135 | * @vcpu: The vcpu pointer | ||
136 | * @select_idx: The counter index | ||
137 | */ | ||
138 | u64 kvm_pmu_get_counter_value(struct kvm_vcpu *vcpu, u64 select_idx) | ||
139 | { | ||
140 | u64 counter; | ||
141 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | ||
142 | struct kvm_pmc *pmc = &pmu->pmc[select_idx]; | ||
143 | |||
144 | counter = kvm_pmu_get_pair_counter_value(vcpu, pmc); | ||
145 | |||
146 | if (kvm_pmu_pmc_is_chained(pmc) && | ||
147 | kvm_pmu_idx_is_high_counter(select_idx)) | ||
148 | counter = upper_32_bits(counter); | ||
149 | |||
150 | else if (!kvm_pmu_idx_is_64bit(vcpu, select_idx)) | ||
151 | counter = lower_32_bits(counter); | ||
152 | |||
153 | return counter; | ||
39 | } | 154 | } |
40 | 155 | ||
41 | /** | 156 | /** |
@@ -51,6 +166,23 @@ void kvm_pmu_set_counter_value(struct kvm_vcpu *vcpu, u64 select_idx, u64 val) | |||
51 | reg = (select_idx == ARMV8_PMU_CYCLE_IDX) | 166 | reg = (select_idx == ARMV8_PMU_CYCLE_IDX) |
52 | ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + select_idx; | 167 | ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + select_idx; |
53 | __vcpu_sys_reg(vcpu, reg) += (s64)val - kvm_pmu_get_counter_value(vcpu, select_idx); | 168 | __vcpu_sys_reg(vcpu, reg) += (s64)val - kvm_pmu_get_counter_value(vcpu, select_idx); |
169 | |||
170 | /* Recreate the perf event to reflect the updated sample_period */ | ||
171 | kvm_pmu_create_perf_event(vcpu, select_idx); | ||
172 | } | ||
173 | |||
174 | /** | ||
175 | * kvm_pmu_release_perf_event - remove the perf event | ||
176 | * @pmc: The PMU counter pointer | ||
177 | */ | ||
178 | static void kvm_pmu_release_perf_event(struct kvm_pmc *pmc) | ||
179 | { | ||
180 | pmc = kvm_pmu_get_canonical_pmc(pmc); | ||
181 | if (pmc->perf_event) { | ||
182 | perf_event_disable(pmc->perf_event); | ||
183 | perf_event_release_kernel(pmc->perf_event); | ||
184 | pmc->perf_event = NULL; | ||
185 | } | ||
54 | } | 186 | } |
55 | 187 | ||
56 | /** | 188 | /** |
@@ -63,15 +195,23 @@ static void kvm_pmu_stop_counter(struct kvm_vcpu *vcpu, struct kvm_pmc *pmc) | |||
63 | { | 195 | { |
64 | u64 counter, reg; | 196 | u64 counter, reg; |
65 | 197 | ||
66 | if (pmc->perf_event) { | 198 | pmc = kvm_pmu_get_canonical_pmc(pmc); |
67 | counter = kvm_pmu_get_counter_value(vcpu, pmc->idx); | 199 | if (!pmc->perf_event) |
200 | return; | ||
201 | |||
202 | counter = kvm_pmu_get_pair_counter_value(vcpu, pmc); | ||
203 | |||
204 | if (kvm_pmu_pmc_is_chained(pmc)) { | ||
205 | reg = PMEVCNTR0_EL0 + pmc->idx; | ||
206 | __vcpu_sys_reg(vcpu, reg) = lower_32_bits(counter); | ||
207 | __vcpu_sys_reg(vcpu, reg + 1) = upper_32_bits(counter); | ||
208 | } else { | ||
68 | reg = (pmc->idx == ARMV8_PMU_CYCLE_IDX) | 209 | reg = (pmc->idx == ARMV8_PMU_CYCLE_IDX) |
69 | ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + pmc->idx; | 210 | ? PMCCNTR_EL0 : PMEVCNTR0_EL0 + pmc->idx; |
70 | __vcpu_sys_reg(vcpu, reg) = counter; | 211 | __vcpu_sys_reg(vcpu, reg) = lower_32_bits(counter); |
71 | perf_event_disable(pmc->perf_event); | ||
72 | perf_event_release_kernel(pmc->perf_event); | ||
73 | pmc->perf_event = NULL; | ||
74 | } | 212 | } |
213 | |||
214 | kvm_pmu_release_perf_event(pmc); | ||
75 | } | 215 | } |
76 | 216 | ||
77 | /** | 217 | /** |
@@ -87,8 +227,9 @@ void kvm_pmu_vcpu_reset(struct kvm_vcpu *vcpu) | |||
87 | for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) { | 227 | for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) { |
88 | kvm_pmu_stop_counter(vcpu, &pmu->pmc[i]); | 228 | kvm_pmu_stop_counter(vcpu, &pmu->pmc[i]); |
89 | pmu->pmc[i].idx = i; | 229 | pmu->pmc[i].idx = i; |
90 | pmu->pmc[i].bitmask = 0xffffffffUL; | ||
91 | } | 230 | } |
231 | |||
232 | bitmap_zero(vcpu->arch.pmu.chained, ARMV8_PMU_MAX_COUNTER_PAIRS); | ||
92 | } | 233 | } |
93 | 234 | ||
94 | /** | 235 | /** |
@@ -101,15 +242,8 @@ void kvm_pmu_vcpu_destroy(struct kvm_vcpu *vcpu) | |||
101 | int i; | 242 | int i; |
102 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 243 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
103 | 244 | ||
104 | for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) { | 245 | for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) |
105 | struct kvm_pmc *pmc = &pmu->pmc[i]; | 246 | kvm_pmu_release_perf_event(&pmu->pmc[i]); |
106 | |||
107 | if (pmc->perf_event) { | ||
108 | perf_event_disable(pmc->perf_event); | ||
109 | perf_event_release_kernel(pmc->perf_event); | ||
110 | pmc->perf_event = NULL; | ||
111 | } | ||
112 | } | ||
113 | } | 247 | } |
114 | 248 | ||
115 | u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu) | 249 | u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu) |
@@ -124,13 +258,13 @@ u64 kvm_pmu_valid_counter_mask(struct kvm_vcpu *vcpu) | |||
124 | } | 258 | } |
125 | 259 | ||
126 | /** | 260 | /** |
127 | * kvm_pmu_enable_counter - enable selected PMU counter | 261 | * kvm_pmu_enable_counter_mask - enable selected PMU counters |
128 | * @vcpu: The vcpu pointer | 262 | * @vcpu: The vcpu pointer |
129 | * @val: the value guest writes to PMCNTENSET register | 263 | * @val: the value guest writes to PMCNTENSET register |
130 | * | 264 | * |
131 | * Call perf_event_enable to start counting the perf event | 265 | * Call perf_event_enable to start counting the perf event |
132 | */ | 266 | */ |
133 | void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, u64 val) | 267 | void kvm_pmu_enable_counter_mask(struct kvm_vcpu *vcpu, u64 val) |
134 | { | 268 | { |
135 | int i; | 269 | int i; |
136 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 270 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
@@ -144,6 +278,18 @@ void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, u64 val) | |||
144 | continue; | 278 | continue; |
145 | 279 | ||
146 | pmc = &pmu->pmc[i]; | 280 | pmc = &pmu->pmc[i]; |
281 | |||
282 | /* | ||
283 | * For high counters of chained events we must recreate the | ||
284 | * perf event with the long (64bit) attribute set. | ||
285 | */ | ||
286 | if (kvm_pmu_pmc_is_chained(pmc) && | ||
287 | kvm_pmu_idx_is_high_counter(i)) { | ||
288 | kvm_pmu_create_perf_event(vcpu, i); | ||
289 | continue; | ||
290 | } | ||
291 | |||
292 | /* At this point, pmc must be the canonical */ | ||
147 | if (pmc->perf_event) { | 293 | if (pmc->perf_event) { |
148 | perf_event_enable(pmc->perf_event); | 294 | perf_event_enable(pmc->perf_event); |
149 | if (pmc->perf_event->state != PERF_EVENT_STATE_ACTIVE) | 295 | if (pmc->perf_event->state != PERF_EVENT_STATE_ACTIVE) |
@@ -153,13 +299,13 @@ void kvm_pmu_enable_counter(struct kvm_vcpu *vcpu, u64 val) | |||
153 | } | 299 | } |
154 | 300 | ||
155 | /** | 301 | /** |
156 | * kvm_pmu_disable_counter - disable selected PMU counter | 302 | * kvm_pmu_disable_counter_mask - disable selected PMU counters |
157 | * @vcpu: The vcpu pointer | 303 | * @vcpu: The vcpu pointer |
158 | * @val: the value guest writes to PMCNTENCLR register | 304 | * @val: the value guest writes to PMCNTENCLR register |
159 | * | 305 | * |
160 | * Call perf_event_disable to stop counting the perf event | 306 | * Call perf_event_disable to stop counting the perf event |
161 | */ | 307 | */ |
162 | void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, u64 val) | 308 | void kvm_pmu_disable_counter_mask(struct kvm_vcpu *vcpu, u64 val) |
163 | { | 309 | { |
164 | int i; | 310 | int i; |
165 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 311 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
@@ -173,6 +319,18 @@ void kvm_pmu_disable_counter(struct kvm_vcpu *vcpu, u64 val) | |||
173 | continue; | 319 | continue; |
174 | 320 | ||
175 | pmc = &pmu->pmc[i]; | 321 | pmc = &pmu->pmc[i]; |
322 | |||
323 | /* | ||
324 | * For high counters of chained events we must recreate the | ||
325 | * perf event with the long (64bit) attribute unset. | ||
326 | */ | ||
327 | if (kvm_pmu_pmc_is_chained(pmc) && | ||
328 | kvm_pmu_idx_is_high_counter(i)) { | ||
329 | kvm_pmu_create_perf_event(vcpu, i); | ||
330 | continue; | ||
331 | } | ||
332 | |||
333 | /* At this point, pmc must be the canonical */ | ||
176 | if (pmc->perf_event) | 334 | if (pmc->perf_event) |
177 | perf_event_disable(pmc->perf_event); | 335 | perf_event_disable(pmc->perf_event); |
178 | } | 336 | } |
@@ -262,17 +420,6 @@ void kvm_pmu_sync_hwstate(struct kvm_vcpu *vcpu) | |||
262 | kvm_pmu_update_state(vcpu); | 420 | kvm_pmu_update_state(vcpu); |
263 | } | 421 | } |
264 | 422 | ||
265 | static inline struct kvm_vcpu *kvm_pmc_to_vcpu(struct kvm_pmc *pmc) | ||
266 | { | ||
267 | struct kvm_pmu *pmu; | ||
268 | struct kvm_vcpu_arch *vcpu_arch; | ||
269 | |||
270 | pmc -= pmc->idx; | ||
271 | pmu = container_of(pmc, struct kvm_pmu, pmc[0]); | ||
272 | vcpu_arch = container_of(pmu, struct kvm_vcpu_arch, pmu); | ||
273 | return container_of(vcpu_arch, struct kvm_vcpu, arch); | ||
274 | } | ||
275 | |||
276 | /** | 423 | /** |
277 | * When the perf event overflows, set the overflow status and inform the vcpu. | 424 | * When the perf event overflows, set the overflow status and inform the vcpu. |
278 | */ | 425 | */ |
@@ -329,17 +476,15 @@ void kvm_pmu_software_increment(struct kvm_vcpu *vcpu, u64 val) | |||
329 | */ | 476 | */ |
330 | void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) | 477 | void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) |
331 | { | 478 | { |
332 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | ||
333 | struct kvm_pmc *pmc; | ||
334 | u64 mask; | 479 | u64 mask; |
335 | int i; | 480 | int i; |
336 | 481 | ||
337 | mask = kvm_pmu_valid_counter_mask(vcpu); | 482 | mask = kvm_pmu_valid_counter_mask(vcpu); |
338 | if (val & ARMV8_PMU_PMCR_E) { | 483 | if (val & ARMV8_PMU_PMCR_E) { |
339 | kvm_pmu_enable_counter(vcpu, | 484 | kvm_pmu_enable_counter_mask(vcpu, |
340 | __vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask); | 485 | __vcpu_sys_reg(vcpu, PMCNTENSET_EL0) & mask); |
341 | } else { | 486 | } else { |
342 | kvm_pmu_disable_counter(vcpu, mask); | 487 | kvm_pmu_disable_counter_mask(vcpu, mask); |
343 | } | 488 | } |
344 | 489 | ||
345 | if (val & ARMV8_PMU_PMCR_C) | 490 | if (val & ARMV8_PMU_PMCR_C) |
@@ -349,11 +494,6 @@ void kvm_pmu_handle_pmcr(struct kvm_vcpu *vcpu, u64 val) | |||
349 | for (i = 0; i < ARMV8_PMU_CYCLE_IDX; i++) | 494 | for (i = 0; i < ARMV8_PMU_CYCLE_IDX; i++) |
350 | kvm_pmu_set_counter_value(vcpu, i, 0); | 495 | kvm_pmu_set_counter_value(vcpu, i, 0); |
351 | } | 496 | } |
352 | |||
353 | if (val & ARMV8_PMU_PMCR_LC) { | ||
354 | pmc = &pmu->pmc[ARMV8_PMU_CYCLE_IDX]; | ||
355 | pmc->bitmask = 0xffffffffffffffffUL; | ||
356 | } | ||
357 | } | 497 | } |
358 | 498 | ||
359 | static bool kvm_pmu_counter_is_enabled(struct kvm_vcpu *vcpu, u64 select_idx) | 499 | static bool kvm_pmu_counter_is_enabled(struct kvm_vcpu *vcpu, u64 select_idx) |
@@ -363,50 +503,75 @@ static bool kvm_pmu_counter_is_enabled(struct kvm_vcpu *vcpu, u64 select_idx) | |||
363 | } | 503 | } |
364 | 504 | ||
365 | /** | 505 | /** |
366 | * kvm_pmu_set_counter_event_type - set selected counter to monitor some event | 506 | * kvm_pmu_create_perf_event - create a perf event for a counter |
367 | * @vcpu: The vcpu pointer | 507 | * @vcpu: The vcpu pointer |
368 | * @data: The data guest writes to PMXEVTYPER_EL0 | ||
369 | * @select_idx: The number of selected counter | 508 | * @select_idx: The number of selected counter |
370 | * | ||
371 | * When OS accesses PMXEVTYPER_EL0, that means it wants to set a PMC to count an | ||
372 | * event with given hardware event number. Here we call perf_event API to | ||
373 | * emulate this action and create a kernel perf event for it. | ||
374 | */ | 509 | */ |
375 | void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data, | 510 | static void kvm_pmu_create_perf_event(struct kvm_vcpu *vcpu, u64 select_idx) |
376 | u64 select_idx) | ||
377 | { | 511 | { |
378 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | 512 | struct kvm_pmu *pmu = &vcpu->arch.pmu; |
379 | struct kvm_pmc *pmc = &pmu->pmc[select_idx]; | 513 | struct kvm_pmc *pmc; |
380 | struct perf_event *event; | 514 | struct perf_event *event; |
381 | struct perf_event_attr attr; | 515 | struct perf_event_attr attr; |
382 | u64 eventsel, counter; | 516 | u64 eventsel, counter, reg, data; |
517 | |||
518 | /* | ||
519 | * For chained counters the event type and filtering attributes are | ||
520 | * obtained from the low/even counter. We also use this counter to | ||
521 | * determine if the event is enabled/disabled. | ||
522 | */ | ||
523 | pmc = kvm_pmu_get_canonical_pmc(&pmu->pmc[select_idx]); | ||
524 | |||
525 | reg = (pmc->idx == ARMV8_PMU_CYCLE_IDX) | ||
526 | ? PMCCFILTR_EL0 : PMEVTYPER0_EL0 + pmc->idx; | ||
527 | data = __vcpu_sys_reg(vcpu, reg); | ||
383 | 528 | ||
384 | kvm_pmu_stop_counter(vcpu, pmc); | 529 | kvm_pmu_stop_counter(vcpu, pmc); |
385 | eventsel = data & ARMV8_PMU_EVTYPE_EVENT; | 530 | eventsel = data & ARMV8_PMU_EVTYPE_EVENT; |
386 | 531 | ||
387 | /* Software increment event does't need to be backed by a perf event */ | 532 | /* Software increment event does't need to be backed by a perf event */ |
388 | if (eventsel == ARMV8_PMUV3_PERFCTR_SW_INCR && | 533 | if (eventsel == ARMV8_PMUV3_PERFCTR_SW_INCR && |
389 | select_idx != ARMV8_PMU_CYCLE_IDX) | 534 | pmc->idx != ARMV8_PMU_CYCLE_IDX) |
390 | return; | 535 | return; |
391 | 536 | ||
392 | memset(&attr, 0, sizeof(struct perf_event_attr)); | 537 | memset(&attr, 0, sizeof(struct perf_event_attr)); |
393 | attr.type = PERF_TYPE_RAW; | 538 | attr.type = PERF_TYPE_RAW; |
394 | attr.size = sizeof(attr); | 539 | attr.size = sizeof(attr); |
395 | attr.pinned = 1; | 540 | attr.pinned = 1; |
396 | attr.disabled = !kvm_pmu_counter_is_enabled(vcpu, select_idx); | 541 | attr.disabled = !kvm_pmu_counter_is_enabled(vcpu, pmc->idx); |
397 | attr.exclude_user = data & ARMV8_PMU_EXCLUDE_EL0 ? 1 : 0; | 542 | attr.exclude_user = data & ARMV8_PMU_EXCLUDE_EL0 ? 1 : 0; |
398 | attr.exclude_kernel = data & ARMV8_PMU_EXCLUDE_EL1 ? 1 : 0; | 543 | attr.exclude_kernel = data & ARMV8_PMU_EXCLUDE_EL1 ? 1 : 0; |
399 | attr.exclude_hv = 1; /* Don't count EL2 events */ | 544 | attr.exclude_hv = 1; /* Don't count EL2 events */ |
400 | attr.exclude_host = 1; /* Don't count host events */ | 545 | attr.exclude_host = 1; /* Don't count host events */ |
401 | attr.config = (select_idx == ARMV8_PMU_CYCLE_IDX) ? | 546 | attr.config = (pmc->idx == ARMV8_PMU_CYCLE_IDX) ? |
402 | ARMV8_PMUV3_PERFCTR_CPU_CYCLES : eventsel; | 547 | ARMV8_PMUV3_PERFCTR_CPU_CYCLES : eventsel; |
403 | 548 | ||
404 | counter = kvm_pmu_get_counter_value(vcpu, select_idx); | 549 | counter = kvm_pmu_get_pair_counter_value(vcpu, pmc); |
405 | /* The initial sample period (overflow count) of an event. */ | ||
406 | attr.sample_period = (-counter) & pmc->bitmask; | ||
407 | 550 | ||
408 | event = perf_event_create_kernel_counter(&attr, -1, current, | 551 | if (kvm_pmu_idx_has_chain_evtype(vcpu, pmc->idx)) { |
552 | /** | ||
553 | * The initial sample period (overflow count) of an event. For | ||
554 | * chained counters we only support overflow interrupts on the | ||
555 | * high counter. | ||
556 | */ | ||
557 | attr.sample_period = (-counter) & GENMASK(63, 0); | ||
558 | event = perf_event_create_kernel_counter(&attr, -1, current, | ||
559 | kvm_pmu_perf_overflow, | ||
560 | pmc + 1); | ||
561 | |||
562 | if (kvm_pmu_counter_is_enabled(vcpu, pmc->idx + 1)) | ||
563 | attr.config1 |= PERF_ATTR_CFG1_KVM_PMU_CHAINED; | ||
564 | } else { | ||
565 | /* The initial sample period (overflow count) of an event. */ | ||
566 | if (kvm_pmu_idx_is_64bit(vcpu, pmc->idx)) | ||
567 | attr.sample_period = (-counter) & GENMASK(63, 0); | ||
568 | else | ||
569 | attr.sample_period = (-counter) & GENMASK(31, 0); | ||
570 | |||
571 | event = perf_event_create_kernel_counter(&attr, -1, current, | ||
409 | kvm_pmu_perf_overflow, pmc); | 572 | kvm_pmu_perf_overflow, pmc); |
573 | } | ||
574 | |||
410 | if (IS_ERR(event)) { | 575 | if (IS_ERR(event)) { |
411 | pr_err_once("kvm: pmu event creation failed %ld\n", | 576 | pr_err_once("kvm: pmu event creation failed %ld\n", |
412 | PTR_ERR(event)); | 577 | PTR_ERR(event)); |
@@ -416,6 +581,57 @@ void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data, | |||
416 | pmc->perf_event = event; | 581 | pmc->perf_event = event; |
417 | } | 582 | } |
418 | 583 | ||
584 | /** | ||
585 | * kvm_pmu_update_pmc_chained - update chained bitmap | ||
586 | * @vcpu: The vcpu pointer | ||
587 | * @select_idx: The number of selected counter | ||
588 | * | ||
589 | * Update the chained bitmap based on the event type written in the | ||
590 | * typer register. | ||
591 | */ | ||
592 | static void kvm_pmu_update_pmc_chained(struct kvm_vcpu *vcpu, u64 select_idx) | ||
593 | { | ||
594 | struct kvm_pmu *pmu = &vcpu->arch.pmu; | ||
595 | struct kvm_pmc *pmc = &pmu->pmc[select_idx]; | ||
596 | |||
597 | if (kvm_pmu_idx_has_chain_evtype(vcpu, pmc->idx)) { | ||
598 | /* | ||
599 | * During promotion from !chained to chained we must ensure | ||
600 | * the adjacent counter is stopped and its event destroyed | ||
601 | */ | ||
602 | if (!kvm_pmu_pmc_is_chained(pmc)) | ||
603 | kvm_pmu_stop_counter(vcpu, pmc); | ||
604 | |||
605 | set_bit(pmc->idx >> 1, vcpu->arch.pmu.chained); | ||
606 | } else { | ||
607 | clear_bit(pmc->idx >> 1, vcpu->arch.pmu.chained); | ||
608 | } | ||
609 | } | ||
610 | |||
611 | /** | ||
612 | * kvm_pmu_set_counter_event_type - set selected counter to monitor some event | ||
613 | * @vcpu: The vcpu pointer | ||
614 | * @data: The data guest writes to PMXEVTYPER_EL0 | ||
615 | * @select_idx: The number of selected counter | ||
616 | * | ||
617 | * When OS accesses PMXEVTYPER_EL0, that means it wants to set a PMC to count an | ||
618 | * event with given hardware event number. Here we call perf_event API to | ||
619 | * emulate this action and create a kernel perf event for it. | ||
620 | */ | ||
621 | void kvm_pmu_set_counter_event_type(struct kvm_vcpu *vcpu, u64 data, | ||
622 | u64 select_idx) | ||
623 | { | ||
624 | u64 reg, event_type = data & ARMV8_PMU_EVTYPE_MASK; | ||
625 | |||
626 | reg = (select_idx == ARMV8_PMU_CYCLE_IDX) | ||
627 | ? PMCCFILTR_EL0 : PMEVTYPER0_EL0 + select_idx; | ||
628 | |||
629 | __vcpu_sys_reg(vcpu, reg) = event_type; | ||
630 | |||
631 | kvm_pmu_update_pmc_chained(vcpu, select_idx); | ||
632 | kvm_pmu_create_perf_event(vcpu, select_idx); | ||
633 | } | ||
634 | |||
419 | bool kvm_arm_support_pmu_v3(void) | 635 | bool kvm_arm_support_pmu_v3(void) |
420 | { | 636 | { |
421 | /* | 637 | /* |
diff --git a/virt/kvm/arm/psci.c b/virt/kvm/arm/psci.c index be3c9cdca9f3..87927f7e1ee7 100644 --- a/virt/kvm/arm/psci.c +++ b/virt/kvm/arm/psci.c | |||
@@ -401,8 +401,16 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) | |||
401 | feature = smccc_get_arg1(vcpu); | 401 | feature = smccc_get_arg1(vcpu); |
402 | switch(feature) { | 402 | switch(feature) { |
403 | case ARM_SMCCC_ARCH_WORKAROUND_1: | 403 | case ARM_SMCCC_ARCH_WORKAROUND_1: |
404 | if (kvm_arm_harden_branch_predictor()) | 404 | switch (kvm_arm_harden_branch_predictor()) { |
405 | case KVM_BP_HARDEN_UNKNOWN: | ||
406 | break; | ||
407 | case KVM_BP_HARDEN_WA_NEEDED: | ||
405 | val = SMCCC_RET_SUCCESS; | 408 | val = SMCCC_RET_SUCCESS; |
409 | break; | ||
410 | case KVM_BP_HARDEN_NOT_REQUIRED: | ||
411 | val = SMCCC_RET_NOT_REQUIRED; | ||
412 | break; | ||
413 | } | ||
406 | break; | 414 | break; |
407 | case ARM_SMCCC_ARCH_WORKAROUND_2: | 415 | case ARM_SMCCC_ARCH_WORKAROUND_2: |
408 | switch (kvm_arm_have_ssbd()) { | 416 | switch (kvm_arm_have_ssbd()) { |
@@ -430,42 +438,103 @@ int kvm_hvc_call_handler(struct kvm_vcpu *vcpu) | |||
430 | 438 | ||
431 | int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) | 439 | int kvm_arm_get_fw_num_regs(struct kvm_vcpu *vcpu) |
432 | { | 440 | { |
433 | return 1; /* PSCI version */ | 441 | return 3; /* PSCI version and two workaround registers */ |
434 | } | 442 | } |
435 | 443 | ||
436 | int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) | 444 | int kvm_arm_copy_fw_reg_indices(struct kvm_vcpu *vcpu, u64 __user *uindices) |
437 | { | 445 | { |
438 | if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices)) | 446 | if (put_user(KVM_REG_ARM_PSCI_VERSION, uindices++)) |
447 | return -EFAULT; | ||
448 | |||
449 | if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1, uindices++)) | ||
450 | return -EFAULT; | ||
451 | |||
452 | if (put_user(KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2, uindices++)) | ||
439 | return -EFAULT; | 453 | return -EFAULT; |
440 | 454 | ||
441 | return 0; | 455 | return 0; |
442 | } | 456 | } |
443 | 457 | ||
458 | #define KVM_REG_FEATURE_LEVEL_WIDTH 4 | ||
459 | #define KVM_REG_FEATURE_LEVEL_MASK (BIT(KVM_REG_FEATURE_LEVEL_WIDTH) - 1) | ||
460 | |||
461 | /* | ||
462 | * Convert the workaround level into an easy-to-compare number, where higher | ||
463 | * values mean better protection. | ||
464 | */ | ||
465 | static int get_kernel_wa_level(u64 regid) | ||
466 | { | ||
467 | switch (regid) { | ||
468 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: | ||
469 | switch (kvm_arm_harden_branch_predictor()) { | ||
470 | case KVM_BP_HARDEN_UNKNOWN: | ||
471 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL; | ||
472 | case KVM_BP_HARDEN_WA_NEEDED: | ||
473 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_AVAIL; | ||
474 | case KVM_BP_HARDEN_NOT_REQUIRED: | ||
475 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_REQUIRED; | ||
476 | } | ||
477 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1_NOT_AVAIL; | ||
478 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: | ||
479 | switch (kvm_arm_have_ssbd()) { | ||
480 | case KVM_SSBD_FORCE_DISABLE: | ||
481 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_AVAIL; | ||
482 | case KVM_SSBD_KERNEL: | ||
483 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL; | ||
484 | case KVM_SSBD_FORCE_ENABLE: | ||
485 | case KVM_SSBD_MITIGATED: | ||
486 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED; | ||
487 | case KVM_SSBD_UNKNOWN: | ||
488 | default: | ||
489 | return KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_UNKNOWN; | ||
490 | } | ||
491 | } | ||
492 | |||
493 | return -EINVAL; | ||
494 | } | ||
495 | |||
444 | int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | 496 | int kvm_arm_get_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) |
445 | { | 497 | { |
446 | if (reg->id == KVM_REG_ARM_PSCI_VERSION) { | 498 | void __user *uaddr = (void __user *)(long)reg->addr; |
447 | void __user *uaddr = (void __user *)(long)reg->addr; | 499 | u64 val; |
448 | u64 val; | ||
449 | 500 | ||
501 | switch (reg->id) { | ||
502 | case KVM_REG_ARM_PSCI_VERSION: | ||
450 | val = kvm_psci_version(vcpu, vcpu->kvm); | 503 | val = kvm_psci_version(vcpu, vcpu->kvm); |
451 | if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id))) | 504 | break; |
452 | return -EFAULT; | 505 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: |
506 | val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK; | ||
507 | break; | ||
508 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: | ||
509 | val = get_kernel_wa_level(reg->id) & KVM_REG_FEATURE_LEVEL_MASK; | ||
453 | 510 | ||
454 | return 0; | 511 | if (val == KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL && |
512 | kvm_arm_get_vcpu_workaround_2_flag(vcpu)) | ||
513 | val |= KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED; | ||
514 | break; | ||
515 | default: | ||
516 | return -ENOENT; | ||
455 | } | 517 | } |
456 | 518 | ||
457 | return -EINVAL; | 519 | if (copy_to_user(uaddr, &val, KVM_REG_SIZE(reg->id))) |
520 | return -EFAULT; | ||
521 | |||
522 | return 0; | ||
458 | } | 523 | } |
459 | 524 | ||
460 | int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | 525 | int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) |
461 | { | 526 | { |
462 | if (reg->id == KVM_REG_ARM_PSCI_VERSION) { | 527 | void __user *uaddr = (void __user *)(long)reg->addr; |
463 | void __user *uaddr = (void __user *)(long)reg->addr; | 528 | u64 val; |
464 | bool wants_02; | 529 | int wa_level; |
465 | u64 val; | ||
466 | 530 | ||
467 | if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id))) | 531 | if (copy_from_user(&val, uaddr, KVM_REG_SIZE(reg->id))) |
468 | return -EFAULT; | 532 | return -EFAULT; |
533 | |||
534 | switch (reg->id) { | ||
535 | case KVM_REG_ARM_PSCI_VERSION: | ||
536 | { | ||
537 | bool wants_02; | ||
469 | 538 | ||
470 | wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features); | 539 | wants_02 = test_bit(KVM_ARM_VCPU_PSCI_0_2, vcpu->arch.features); |
471 | 540 | ||
@@ -482,6 +551,54 @@ int kvm_arm_set_fw_reg(struct kvm_vcpu *vcpu, const struct kvm_one_reg *reg) | |||
482 | vcpu->kvm->arch.psci_version = val; | 551 | vcpu->kvm->arch.psci_version = val; |
483 | return 0; | 552 | return 0; |
484 | } | 553 | } |
554 | break; | ||
555 | } | ||
556 | |||
557 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_1: | ||
558 | if (val & ~KVM_REG_FEATURE_LEVEL_MASK) | ||
559 | return -EINVAL; | ||
560 | |||
561 | if (get_kernel_wa_level(reg->id) < val) | ||
562 | return -EINVAL; | ||
563 | |||
564 | return 0; | ||
565 | |||
566 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2: | ||
567 | if (val & ~(KVM_REG_FEATURE_LEVEL_MASK | | ||
568 | KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED)) | ||
569 | return -EINVAL; | ||
570 | |||
571 | wa_level = val & KVM_REG_FEATURE_LEVEL_MASK; | ||
572 | |||
573 | if (get_kernel_wa_level(reg->id) < wa_level) | ||
574 | return -EINVAL; | ||
575 | |||
576 | /* The enabled bit must not be set unless the level is AVAIL. */ | ||
577 | if (wa_level != KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL && | ||
578 | wa_level != val) | ||
579 | return -EINVAL; | ||
580 | |||
581 | /* Are we finished or do we need to check the enable bit ? */ | ||
582 | if (kvm_arm_have_ssbd() != KVM_SSBD_KERNEL) | ||
583 | return 0; | ||
584 | |||
585 | /* | ||
586 | * If this kernel supports the workaround to be switched on | ||
587 | * or off, make sure it matches the requested setting. | ||
588 | */ | ||
589 | switch (wa_level) { | ||
590 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_AVAIL: | ||
591 | kvm_arm_set_vcpu_workaround_2_flag(vcpu, | ||
592 | val & KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_ENABLED); | ||
593 | break; | ||
594 | case KVM_REG_ARM_SMCCC_ARCH_WORKAROUND_2_NOT_REQUIRED: | ||
595 | kvm_arm_set_vcpu_workaround_2_flag(vcpu, true); | ||
596 | break; | ||
597 | } | ||
598 | |||
599 | return 0; | ||
600 | default: | ||
601 | return -ENOENT; | ||
485 | } | 602 | } |
486 | 603 | ||
487 | return -EINVAL; | 604 | return -EINVAL; |
diff --git a/virt/kvm/irqchip.c b/virt/kvm/irqchip.c index 2e6fc7c66a11..58e4f88b2b9f 100644 --- a/virt/kvm/irqchip.c +++ b/virt/kvm/irqchip.c | |||
@@ -184,9 +184,7 @@ int kvm_set_irq_routing(struct kvm *kvm, | |||
184 | 184 | ||
185 | nr_rt_entries += 1; | 185 | nr_rt_entries += 1; |
186 | 186 | ||
187 | new = kzalloc(sizeof(*new) + (nr_rt_entries * sizeof(struct hlist_head)), | 187 | new = kzalloc(struct_size(new, map, nr_rt_entries), GFP_KERNEL_ACCOUNT); |
188 | GFP_KERNEL_ACCOUNT); | ||
189 | |||
190 | if (!new) | 188 | if (!new) |
191 | return -ENOMEM; | 189 | return -ENOMEM; |
192 | 190 | ||
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c index 2f2d24a4dd5c..b4ab59dd6846 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c | |||
@@ -95,7 +95,7 @@ EXPORT_SYMBOL_GPL(halt_poll_ns_shrink); | |||
95 | * kvm->lock --> kvm->slots_lock --> kvm->irq_lock | 95 | * kvm->lock --> kvm->slots_lock --> kvm->irq_lock |
96 | */ | 96 | */ |
97 | 97 | ||
98 | DEFINE_SPINLOCK(kvm_lock); | 98 | DEFINE_MUTEX(kvm_lock); |
99 | static DEFINE_RAW_SPINLOCK(kvm_count_lock); | 99 | static DEFINE_RAW_SPINLOCK(kvm_count_lock); |
100 | LIST_HEAD(vm_list); | 100 | LIST_HEAD(vm_list); |
101 | 101 | ||
@@ -680,9 +680,9 @@ static struct kvm *kvm_create_vm(unsigned long type) | |||
680 | if (r) | 680 | if (r) |
681 | goto out_err; | 681 | goto out_err; |
682 | 682 | ||
683 | spin_lock(&kvm_lock); | 683 | mutex_lock(&kvm_lock); |
684 | list_add(&kvm->vm_list, &vm_list); | 684 | list_add(&kvm->vm_list, &vm_list); |
685 | spin_unlock(&kvm_lock); | 685 | mutex_unlock(&kvm_lock); |
686 | 686 | ||
687 | preempt_notifier_inc(); | 687 | preempt_notifier_inc(); |
688 | 688 | ||
@@ -728,9 +728,9 @@ static void kvm_destroy_vm(struct kvm *kvm) | |||
728 | kvm_uevent_notify_change(KVM_EVENT_DESTROY_VM, kvm); | 728 | kvm_uevent_notify_change(KVM_EVENT_DESTROY_VM, kvm); |
729 | kvm_destroy_vm_debugfs(kvm); | 729 | kvm_destroy_vm_debugfs(kvm); |
730 | kvm_arch_sync_events(kvm); | 730 | kvm_arch_sync_events(kvm); |
731 | spin_lock(&kvm_lock); | 731 | mutex_lock(&kvm_lock); |
732 | list_del(&kvm->vm_list); | 732 | list_del(&kvm->vm_list); |
733 | spin_unlock(&kvm_lock); | 733 | mutex_unlock(&kvm_lock); |
734 | kvm_free_irq_routing(kvm); | 734 | kvm_free_irq_routing(kvm); |
735 | for (i = 0; i < KVM_NR_BUSES; i++) { | 735 | for (i = 0; i < KVM_NR_BUSES; i++) { |
736 | struct kvm_io_bus *bus = kvm_get_bus(kvm, i); | 736 | struct kvm_io_bus *bus = kvm_get_bus(kvm, i); |
@@ -1790,7 +1790,7 @@ void kvm_vcpu_unmap(struct kvm_vcpu *vcpu, struct kvm_host_map *map, | |||
1790 | if (!map->hva) | 1790 | if (!map->hva) |
1791 | return; | 1791 | return; |
1792 | 1792 | ||
1793 | if (map->page) | 1793 | if (map->page != KVM_UNMAPPED_PAGE) |
1794 | kunmap(map->page); | 1794 | kunmap(map->page); |
1795 | #ifdef CONFIG_HAS_IOMEM | 1795 | #ifdef CONFIG_HAS_IOMEM |
1796 | else | 1796 | else |
@@ -4031,13 +4031,13 @@ static int vm_stat_get(void *_offset, u64 *val) | |||
4031 | u64 tmp_val; | 4031 | u64 tmp_val; |
4032 | 4032 | ||
4033 | *val = 0; | 4033 | *val = 0; |
4034 | spin_lock(&kvm_lock); | 4034 | mutex_lock(&kvm_lock); |
4035 | list_for_each_entry(kvm, &vm_list, vm_list) { | 4035 | list_for_each_entry(kvm, &vm_list, vm_list) { |
4036 | stat_tmp.kvm = kvm; | 4036 | stat_tmp.kvm = kvm; |
4037 | vm_stat_get_per_vm((void *)&stat_tmp, &tmp_val); | 4037 | vm_stat_get_per_vm((void *)&stat_tmp, &tmp_val); |
4038 | *val += tmp_val; | 4038 | *val += tmp_val; |
4039 | } | 4039 | } |
4040 | spin_unlock(&kvm_lock); | 4040 | mutex_unlock(&kvm_lock); |
4041 | return 0; | 4041 | return 0; |
4042 | } | 4042 | } |
4043 | 4043 | ||
@@ -4050,12 +4050,12 @@ static int vm_stat_clear(void *_offset, u64 val) | |||
4050 | if (val) | 4050 | if (val) |
4051 | return -EINVAL; | 4051 | return -EINVAL; |
4052 | 4052 | ||
4053 | spin_lock(&kvm_lock); | 4053 | mutex_lock(&kvm_lock); |
4054 | list_for_each_entry(kvm, &vm_list, vm_list) { | 4054 | list_for_each_entry(kvm, &vm_list, vm_list) { |
4055 | stat_tmp.kvm = kvm; | 4055 | stat_tmp.kvm = kvm; |
4056 | vm_stat_clear_per_vm((void *)&stat_tmp, 0); | 4056 | vm_stat_clear_per_vm((void *)&stat_tmp, 0); |
4057 | } | 4057 | } |
4058 | spin_unlock(&kvm_lock); | 4058 | mutex_unlock(&kvm_lock); |
4059 | 4059 | ||
4060 | return 0; | 4060 | return 0; |
4061 | } | 4061 | } |
@@ -4070,13 +4070,13 @@ static int vcpu_stat_get(void *_offset, u64 *val) | |||
4070 | u64 tmp_val; | 4070 | u64 tmp_val; |
4071 | 4071 | ||
4072 | *val = 0; | 4072 | *val = 0; |
4073 | spin_lock(&kvm_lock); | 4073 | mutex_lock(&kvm_lock); |
4074 | list_for_each_entry(kvm, &vm_list, vm_list) { | 4074 | list_for_each_entry(kvm, &vm_list, vm_list) { |
4075 | stat_tmp.kvm = kvm; | 4075 | stat_tmp.kvm = kvm; |
4076 | vcpu_stat_get_per_vm((void *)&stat_tmp, &tmp_val); | 4076 | vcpu_stat_get_per_vm((void *)&stat_tmp, &tmp_val); |
4077 | *val += tmp_val; | 4077 | *val += tmp_val; |
4078 | } | 4078 | } |
4079 | spin_unlock(&kvm_lock); | 4079 | mutex_unlock(&kvm_lock); |
4080 | return 0; | 4080 | return 0; |
4081 | } | 4081 | } |
4082 | 4082 | ||
@@ -4089,12 +4089,12 @@ static int vcpu_stat_clear(void *_offset, u64 val) | |||
4089 | if (val) | 4089 | if (val) |
4090 | return -EINVAL; | 4090 | return -EINVAL; |
4091 | 4091 | ||
4092 | spin_lock(&kvm_lock); | 4092 | mutex_lock(&kvm_lock); |
4093 | list_for_each_entry(kvm, &vm_list, vm_list) { | 4093 | list_for_each_entry(kvm, &vm_list, vm_list) { |
4094 | stat_tmp.kvm = kvm; | 4094 | stat_tmp.kvm = kvm; |
4095 | vcpu_stat_clear_per_vm((void *)&stat_tmp, 0); | 4095 | vcpu_stat_clear_per_vm((void *)&stat_tmp, 0); |
4096 | } | 4096 | } |
4097 | spin_unlock(&kvm_lock); | 4097 | mutex_unlock(&kvm_lock); |
4098 | 4098 | ||
4099 | return 0; | 4099 | return 0; |
4100 | } | 4100 | } |
@@ -4115,7 +4115,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm) | |||
4115 | if (!kvm_dev.this_device || !kvm) | 4115 | if (!kvm_dev.this_device || !kvm) |
4116 | return; | 4116 | return; |
4117 | 4117 | ||
4118 | spin_lock(&kvm_lock); | 4118 | mutex_lock(&kvm_lock); |
4119 | if (type == KVM_EVENT_CREATE_VM) { | 4119 | if (type == KVM_EVENT_CREATE_VM) { |
4120 | kvm_createvm_count++; | 4120 | kvm_createvm_count++; |
4121 | kvm_active_vms++; | 4121 | kvm_active_vms++; |
@@ -4124,7 +4124,7 @@ static void kvm_uevent_notify_change(unsigned int type, struct kvm *kvm) | |||
4124 | } | 4124 | } |
4125 | created = kvm_createvm_count; | 4125 | created = kvm_createvm_count; |
4126 | active = kvm_active_vms; | 4126 | active = kvm_active_vms; |
4127 | spin_unlock(&kvm_lock); | 4127 | mutex_unlock(&kvm_lock); |
4128 | 4128 | ||
4129 | env = kzalloc(sizeof(*env), GFP_KERNEL_ACCOUNT); | 4129 | env = kzalloc(sizeof(*env), GFP_KERNEL_ACCOUNT); |
4130 | if (!env) | 4130 | if (!env) |
@@ -4221,6 +4221,11 @@ static void kvm_sched_out(struct preempt_notifier *pn, | |||
4221 | kvm_arch_vcpu_put(vcpu); | 4221 | kvm_arch_vcpu_put(vcpu); |
4222 | } | 4222 | } |
4223 | 4223 | ||
4224 | static void check_processor_compat(void *rtn) | ||
4225 | { | ||
4226 | *(int *)rtn = kvm_arch_check_processor_compat(); | ||
4227 | } | ||
4228 | |||
4224 | int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, | 4229 | int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, |
4225 | struct module *module) | 4230 | struct module *module) |
4226 | { | 4231 | { |
@@ -4252,9 +4257,7 @@ int kvm_init(void *opaque, unsigned vcpu_size, unsigned vcpu_align, | |||
4252 | goto out_free_0a; | 4257 | goto out_free_0a; |
4253 | 4258 | ||
4254 | for_each_online_cpu(cpu) { | 4259 | for_each_online_cpu(cpu) { |
4255 | smp_call_function_single(cpu, | 4260 | smp_call_function_single(cpu, check_processor_compat, &r, 1); |
4256 | kvm_arch_check_processor_compat, | ||
4257 | &r, 1); | ||
4258 | if (r < 0) | 4261 | if (r < 0) |
4259 | goto out_free_1; | 4262 | goto out_free_1; |
4260 | } | 4263 | } |