mirror of
https://github.com/torvalds/linux.git
synced 2026-06-01 11:03:43 +02:00
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 -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEn9UcU+C1Yxj9lZw9I9DQutE9ekMFAmoZbFAACgkQI9DQutE9 ekMqHA/+MUfOMP8C8q87SVWsb8JrtMoZKBl6YWsn19kSGXkR14HVTLwmTWsYCNfi KvuOf5p0ALvCt9KhE8EUpsIScwdcLMJWjwKbzKkgooX9YwlgMLxA5w3He6GgyTzB 0fCqQ/2H/frJP1kdQI567Zc4eO7JNcMJfI+/lrZxUM6xbo0KyhehQcFlTBVm5/h/ RptX9n1NqdJ1qqbJw7UkAAt0hDMIAvDxZyTKGYTQla/+ckK+UEa6UUl/1pfXPs6Y Domxu7OO9qQFSxR3KfFlHEml4lrLxNTiCFzoBgPCrf83vAkK0Ceudj3luCs7UDMX j4sH44ddHDoO/8BmueNzsQ+gHTqmDaQGRu3G8m/4EN0dCnD5TsQ9FtaB7LErRFze wZCTxiAuAxAaQC41H/Nul3S+7D92/vRW664b7HPf92uvD4QpGA96qvafnz9SK8AN CyiB4EBElau+D4nOBJ7MO9vu0doWwnTXRHSIvJv8mRkkYedhEv9G8OX8QOgLGi2r /uYtMYRcZ6tglvVhQzcOwpHe//oJ7CGxfACgwUhH2XjL1V3tDuCtCfQheo242UAe nBUfs1R38UyaWKZmlkzymHygAprw2s/idAIJV7i80rDGwAuNTdMV3SyjC1so7ZGP 1grcr7yi2aPr3phA1RWD5bbGZhTl8a+fzyKrwIltz3rTAaV7lOk= =bNQ/ -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
5ff17b1958
|
|
@ -511,7 +511,6 @@ enum vcpu_sysreg {
|
|||
ACTLR_EL2, /* Auxiliary Control Register (EL2) */
|
||||
CPTR_EL2, /* Architectural Feature Trap Register (EL2) */
|
||||
HACR_EL2, /* Hypervisor Auxiliary Control Register */
|
||||
ZCR_EL2, /* SVE Control Register (EL2) */
|
||||
TTBR0_EL2, /* Translation Table Base Register 0 (EL2) */
|
||||
TTBR1_EL2, /* Translation Table Base Register 1 (EL2) */
|
||||
TCR_EL2, /* Translation Control Register (EL2) */
|
||||
|
|
@ -543,6 +542,7 @@ enum vcpu_sysreg {
|
|||
SCTLR2_EL2, /* System Control Register 2 (EL2) */
|
||||
MDCR_EL2, /* Monitor Debug Configuration Register (EL2) */
|
||||
CNTHCTL_EL2, /* Counter-timer Hypervisor Control register */
|
||||
ZCR_EL2, /* SVE Control Register (EL2) */
|
||||
|
||||
/* Any VNCR-capable reg goes after this point */
|
||||
MARKER(__VNCR_START__),
|
||||
|
|
|
|||
|
|
@ -462,11 +462,13 @@ static inline bool kvm_hyp_handle_mops(struct kvm_vcpu *vcpu, u64 *exit_code)
|
|||
|
||||
static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
|
||||
{
|
||||
u64 zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
|
||||
|
||||
/*
|
||||
* The vCPU's saved SVE state layout always matches the max VL of the
|
||||
* vCPU. Start off with the max VL so we can load the SVE state.
|
||||
*/
|
||||
sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
|
||||
sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2);
|
||||
__sve_restore_state(vcpu_sve_pffr(vcpu),
|
||||
&vcpu->arch.ctxt.fp_regs.fpsr,
|
||||
true);
|
||||
|
|
@ -476,8 +478,10 @@ static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
|
|||
* nested guest, as the guest hypervisor could select a smaller VL. Slap
|
||||
* that into hardware before wrapping up.
|
||||
*/
|
||||
if (is_nested_ctxt(vcpu))
|
||||
sve_cond_update_zcr_vq(__vcpu_sys_reg(vcpu, ZCR_EL2), SYS_ZCR_EL2);
|
||||
if (is_nested_ctxt(vcpu)) {
|
||||
zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2));
|
||||
sve_cond_update_zcr_vq(zcr_el2, SYS_ZCR_EL2);
|
||||
}
|
||||
|
||||
write_sysreg_el1(__vcpu_sys_reg(vcpu, vcpu_sve_zcr_elx(vcpu)), SYS_ZCR);
|
||||
}
|
||||
|
|
@ -501,11 +505,11 @@ static inline void fpsimd_lazy_switch_to_guest(struct kvm_vcpu *vcpu)
|
|||
return;
|
||||
|
||||
if (vcpu_has_sve(vcpu)) {
|
||||
zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
|
||||
|
||||
/* A guest hypervisor may restrict the effective max VL. */
|
||||
if (is_nested_ctxt(vcpu))
|
||||
zcr_el2 = __vcpu_sys_reg(vcpu, ZCR_EL2);
|
||||
else
|
||||
zcr_el2 = vcpu_sve_max_vq(vcpu) - 1;
|
||||
zcr_el2 = min(zcr_el2, __vcpu_sys_reg(vcpu, ZCR_EL2));
|
||||
|
||||
write_sysreg_el2(zcr_el2, SYS_ZCR);
|
||||
|
||||
|
|
|
|||
|
|
@ -120,7 +120,7 @@ SYM_FUNC_START(__hyp_do_panic)
|
|||
|
||||
mov x29, x0
|
||||
|
||||
#ifdef PKVM_DISABLE_STAGE2_ON_PANIC
|
||||
#ifdef CONFIG_PKVM_DISABLE_STAGE2_ON_PANIC
|
||||
/* Ensure host stage-2 is disabled */
|
||||
mrs x0, hcr_el2
|
||||
bic x0, x0, #HCR_VM
|
||||
|
|
|
|||
|
|
@ -189,7 +189,7 @@ static void hyp_trace_buffer_unshare_hyp(struct hyp_trace_buffer *trace_buffer,
|
|||
if (cpu > last_cpu)
|
||||
break;
|
||||
|
||||
__share_page(rb_desc->meta_va);
|
||||
__unshare_page(rb_desc->meta_va);
|
||||
for (p = 0; p < rb_desc->nr_page_va; p++)
|
||||
__unshare_page(rb_desc->page_va[p]);
|
||||
}
|
||||
|
|
@ -212,14 +212,15 @@ static int hyp_trace_buffer_share_hyp(struct hyp_trace_buffer *trace_buffer)
|
|||
}
|
||||
|
||||
if (ret) {
|
||||
for (p--; p >= 0; p--)
|
||||
while (--p >= 0)
|
||||
__unshare_page(rb_desc->page_va[p]);
|
||||
__unshare_page(rb_desc->meta_va);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret)
|
||||
hyp_trace_buffer_unshare_hyp(trace_buffer, cpu--);
|
||||
hyp_trace_buffer_unshare_hyp(trace_buffer, --cpu);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -248,6 +249,7 @@ static struct trace_buffer_desc *hyp_trace_load(unsigned long size, void *priv)
|
|||
goto err_free_desc;
|
||||
|
||||
trace_buffer->desc = desc;
|
||||
trace_buffer->desc_size = desc_size;
|
||||
|
||||
ret = hyp_trace_buffer_alloc_bpages_backing(trace_buffer, size);
|
||||
if (ret)
|
||||
|
|
@ -297,6 +299,7 @@ static void hyp_trace_unload(struct trace_buffer_desc *desc, void *priv)
|
|||
hyp_trace_buffer_free_bpages_backing(trace_buffer);
|
||||
free_pages_exact(trace_buffer->desc, trace_buffer->desc_size);
|
||||
trace_buffer->desc = NULL;
|
||||
trace_buffer->desc_size = 0;
|
||||
}
|
||||
|
||||
static int hyp_trace_enable_tracing(bool enable, void *priv)
|
||||
|
|
|
|||
|
|
@ -1834,6 +1834,11 @@ int kvm_init_nv_sysregs(struct kvm_vcpu *vcpu)
|
|||
resx.res1 = VNCR_EL2_RES1;
|
||||
set_sysreg_masks(kvm, VNCR_EL2, resx);
|
||||
|
||||
/* ZCR_EL2 - bits 8:4 are RAZ/WI so treat them as RES0 */
|
||||
resx.res0 = ZCR_ELx_RES0 | GENMASK_ULL(8, 4);
|
||||
resx.res1 = ZCR_ELx_RES1;
|
||||
set_sysreg_masks(kvm, ZCR_EL2, resx);
|
||||
|
||||
out:
|
||||
for (enum vcpu_sysreg sr = __SANITISED_REG_START__; sr < NR_SYS_REGS; sr++)
|
||||
__vcpu_rmw_sys_reg(vcpu, sr, |=, 0);
|
||||
|
|
|
|||
|
|
@ -174,8 +174,8 @@ static void kvm_pmu_set_pmc_value(struct kvm_pmc *pmc, u64 val, bool force)
|
|||
* action is to use PMCR.P, which will reset them to
|
||||
* 0 (the only use of the 'force' parameter).
|
||||
*/
|
||||
val = __vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32);
|
||||
val |= lower_32_bits(val);
|
||||
val = (__vcpu_sys_reg(vcpu, reg) & GENMASK(63, 32)) |
|
||||
lower_32_bits(val);
|
||||
}
|
||||
|
||||
__vcpu_assign_sys_reg(vcpu, reg, val);
|
||||
|
|
|
|||
|
|
@ -2862,21 +2862,16 @@ static bool access_zcr_el2(struct kvm_vcpu *vcpu,
|
|||
struct sys_reg_params *p,
|
||||
const struct sys_reg_desc *r)
|
||||
{
|
||||
unsigned int vq;
|
||||
|
||||
if (guest_hyp_sve_traps_enabled(vcpu)) {
|
||||
kvm_inject_nested_sve_trap(vcpu);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!p->is_write) {
|
||||
if (!p->is_write)
|
||||
p->regval = __vcpu_sys_reg(vcpu, ZCR_EL2);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
__vcpu_assign_sys_reg(vcpu, ZCR_EL2, p->regval);
|
||||
|
||||
vq = SYS_FIELD_GET(ZCR_ELx, LEN, p->regval) + 1;
|
||||
vq = min(vq, vcpu_sve_max_vq(vcpu));
|
||||
__vcpu_assign_sys_reg(vcpu, ZCR_EL2, vq - 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user