Skip to content

Commit 5ff17b1

Browse files
committed
Merge tag 'kvmarm-fixes-7.1-4' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 fixes for 7.1, take #4 - Restore CONFIG_PKVM_DISABLE_STAGE2_ON_PANIC to its former glory by making sure the config symbol is correctly spelled out in the code - Don't reset the AArch32 view of the PMU counters to zero when the guest is writing to them - Fix an assorted collection of memory leaks in the newly added tracing code - Fix the capping of ZCR_EL2 which could be used in an unsanitised way by an L2 guest
2 parents b397897 + 8372633 commit 5ff17b1

7 files changed

Lines changed: 28 additions & 21 deletions

File tree

arch/arm64/include/asm/kvm_host.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -511,7 +511,6 @@ enum vcpu_sysreg {
511511
ACTLR_EL2, /* Auxiliary Control Register (EL2) */
512512
CPTR_EL2, /* Architectural Feature Trap Register (EL2) */
513513
HACR_EL2, /* Hypervisor Auxiliary Control Register */
514-
ZCR_EL2, /* SVE Control Register (EL2) */
515514
TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */
516515
TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */
517516
TCR_EL2, /* Translation Control Register (EL2) */
@@ -543,6 +542,7 @@ enum vcpu_sysreg {
543542
SCTLR2_EL2, /* System Control Register 2 (EL2) */
544543
MDCR_EL2, /* Monitor Debug Configuration Register (EL2) */
545544
CNTHCTL_EL2, /* Counter-timer Hypervisor Control register */
545+
ZCR_EL2, /* SVE Control Register (EL2) */
546546

547547
/* Any VNCR-capable reg goes after this point */
548548
MARKER(__VNCR_START__),

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -462,11 +462,13 @@ static inline bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
462462

463463
static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
464464
{
465+
u64 zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
466+
465467
/*
466468
* The vCPU's saved SVE state layout always matches the max VL of the
467469
* vCPU. Start off with the max VL so we can load the SVE state.
468470
*/
469-
sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
471+
sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2);
470472
__sve_restore_state(vcpu_sve_pffr(vcpu),
471473
&vcpu->arch.ctxt.fp_regs.fpsr,
472474
true);
@@ -476,8 +478,10 @@ static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
476478
* nested guest, as the guest hypervisor could select a smaller VL. Slap
477479
* that into hardware before wrapping up.
478480
*/
479-
if (is_nested_ctxt(vcpu))
480-
sve_cond_update_zcr_vq(__vcpu_sys_reg(vcpu, ZCR_EL2), SYS_ZCR_EL2);
481+
if (is_nested_ctxt(vcpu)) {
482+
zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2));
483+
sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2);
484+
}
481485

482486
write_sysreg_el1(__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)), SYS_ZCR);
483487
}
@@ -501,11 +505,11 @@ static inline void fpsimd_lazy_switch_to_guest(struct kvm_vcpu *vcpu)
501505
return;
502506

503507
if (vcpu_has_sve(vcpu)) {
508+
zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
509+
504510
/* A guest hypervisor may restrict the effective max VL. */
505511
if (is_nested_ctxt(vcpu))
506-
zcr_el2 = __vcpu_sys_reg(vcpu, ZCR_EL2);
507-
else
508-
zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
512+
zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2));
509513

510514
write_sysreg_el2(zcr_el2, SYS_ZCR);
511515

arch/arm64/kvm/hyp/nvhe/host.S

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ SYM_FUNC_START(__hyp_do_panic)
120120

121121
mov x29, x0
122122

123-
#ifdef PKVM_DISABLE_STAGE2_ON_PANIC
123+
#ifdef CONFIG_PKVM_DISABLE_STAGE2_ON_PANIC
124124
/* Ensure host stage-2 is disabled */
125125
mrs x0, hcr_el2
126126
bic x0, x0, #HCR_VM

arch/arm64/kvm/hyp_trace.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ static void hyp_trace_buffer_unshare_hyp(struct hyp_trace_buffer *trace_buffer,
189189
if (cpu > last_cpu)
190190
break;
191191

192-
__share_page(rb_desc->meta_va);
192+
__unshare_page(rb_desc->meta_va);
193193
for (p = 0; p < rb_desc->nr_page_va; p++)
194194
__unshare_page(rb_desc->page_va[p]);
195195
}
@@ -212,14 +212,15 @@ static int hyp_trace_buffer_share_hyp(struct hyp_trace_buffer *trace_buffer)
212212
}
213213

214214
if (ret) {
215-
for (p--; p >= 0; p--)
215+
while (--p >= 0)
216216
__unshare_page(rb_desc->page_va[p]);
217+
__unshare_page(rb_desc->meta_va);
217218
break;
218219
}
219220
}
220221

221222
if (ret)
222-
hyp_trace_buffer_unshare_hyp(trace_buffer, cpu--);
223+
hyp_trace_buffer_unshare_hyp(trace_buffer, --cpu);
223224

224225
return ret;
225226
}
@@ -248,6 +249,7 @@ static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv)
248249
goto err_free_desc;
249250

250251
trace_buffer->desc = desc;
252+
trace_buffer->desc_size = desc_size;
251253

252254
ret = hyp_trace_buffer_alloc_bpages_backing(trace_buffer, size);
253255
if (ret)
@@ -297,6 +299,7 @@ static void hyp_trace_unload(struct trace_buffer_desc *desc, void *priv)
297299
hyp_trace_buffer_free_bpages_backing(trace_buffer);
298300
free_pages_exact(trace_buffer->desc, trace_buffer->desc_size);
299301
trace_buffer->desc = NULL;
302+
trace_buffer->desc_size = 0;
300303
}
301304

302305
static int hyp_trace_enable_tracing(bool enable, void *priv)

arch/arm64/kvm/nested.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1834,6 +1834,11 @@ int kvm_init_nv_sysregs(struct kvm_vcpu *vcpu)
18341834
resx.res1 = VNCR_EL2_RES1;
18351835
set_sysreg_masks(kvm, VNCR_EL2, resx);
18361836

1837+
/* ZCR_EL2 - bits 8:4 are RAZ/WI so treat them as RES0 */
1838+
resx.res0 = ZCR_ELx_RES0 | GENMASK_ULL(8, 4);
1839+
resx.res1 = ZCR_ELx_RES1;
1840+
set_sysreg_masks(kvm, ZCR_EL2, resx);
1841+
18371842
out:
18381843
for (enum vcpu_sysreg sr = __SANITISED_REG_START__; sr < NR_SYS_REGS; sr++)
18391844
__vcpu_rmw_sys_reg(vcpu, sr, |=, 0);

arch/arm64/kvm/pmu-emul.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ static void kvm_pmu_set_pmc_value(struct kvm_pmc *pmc, u64 val, bool force)
174174
* action is to use PMCR.P, which will reset them to
175175
* 0 (the only use of the 'force' parameter).
176176
*/
177-
val = __vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32);
178-
val |= lower_32_bits(val);
177+
val = (__vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32)) |
178+
lower_32_bits(val);
179179
}
180180

181181
__vcpu_assign_sys_reg(vcpu, reg, val);

arch/arm64/kvm/sys_regs.c

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2862,21 +2862,16 @@ static bool access_zcr_el2(struct kvm_vcpu *vcpu,
28622862
struct sys_reg_params *p,
28632863
const struct sys_reg_desc *r)
28642864
{
2865-
unsigned int vq;
2866-
28672865
if (guest_hyp_sve_traps_enabled(vcpu)) {
28682866
kvm_inject_nested_sve_trap(vcpu);
28692867
return false;
28702868
}
28712869

2872-
if (!p->is_write) {
2870+
if (!p->is_write)
28732871
p->regval = __vcpu_sys_reg(vcpu, ZCR_EL2);
2874-
return true;
2875-
}
2872+
else
2873+
__vcpu_assign_sys_reg(vcpu, ZCR_EL2, p->regval);
28762874

2877-
vq = SYS_FIELD_GET(ZCR_ELx, LEN, p->regval) + 1;
2878-
vq = min(vq, vcpu_sve_max_vq(vcpu));
2879-
__vcpu_assign_sys_reg(vcpu, ZCR_EL2, vq - 1);
28802875
return true;
28812876
}
28822877

0 commit comments

Comments
 (0)