Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

KVM: arm64: nv: Emulate EL12 register accesses from the virtual EL2

With HCR_EL2.NV bit set, accesses to EL12 registers in the virtual EL2
trap to EL2. Handle those traps just like we do for EL1 registers.

One exception is CNTKCTL_EL12. We don't trap on CNTKCTL_EL1 for non-VHE
virtual EL2 because we don't have to. However, accessing CNTKCTL_EL12
will trap since it's one of the EL12 registers controlled by HCR_EL2.NV
bit. Therefore, add a handler for it and don't treat it as a
non-trap-registers when preparing a shadow context.

These registers, being only a view on their EL1 counterpart, are
permanently hidden from userspace.

Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Jintack Lim <jintack.lim@linaro.org>
[maz: EL12_REG(), register visibility]
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230209175820.1939006-17-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>

authored by

Jintack Lim and committed by
Oliver Upton
280b748e e6b367db

+37
+37
arch/arm64/kvm/sys_regs.c
··· 1482 1482 .val = v, \ 1483 1483 } 1484 1484 1485 + /* 1486 + * EL{0,1}2 registers are the EL2 view on an EL0 or EL1 register when 1487 + * HCR_EL2.E2H==1, and only in the sysreg table for convenience of 1488 + * handling traps. Given that, they are always hidden from userspace. 1489 + */ 1490 + static unsigned int elx2_visibility(const struct kvm_vcpu *vcpu, 1491 + const struct sys_reg_desc *rd) 1492 + { 1493 + return REG_HIDDEN_USER; 1494 + } 1495 + 1496 + #define EL12_REG(name, acc, rst, v) { \ 1497 + SYS_DESC(SYS_##name##_EL12), \ 1498 + .access = acc, \ 1499 + .reset = rst, \ 1500 + .reg = name##_EL1, \ 1501 + .val = v, \ 1502 + .visibility = elx2_visibility, \ 1503 + } 1504 + 1485 1505 /* sys_reg_desc initialiser for known cpufeature ID registers */ 1486 1506 #define ID_SANITISED(name) { \ 1487 1507 SYS_DESC(SYS_##name), \ ··· 2050 2030 2051 2031 EL2_REG(CNTVOFF_EL2, access_rw, reset_val, 0), 2052 2032 EL2_REG(CNTHCTL_EL2, access_rw, reset_val, 0), 2033 + 2034 + EL12_REG(SCTLR, access_vm_reg, reset_val, 0x00C50078), 2035 + EL12_REG(CPACR, access_rw, reset_val, 0), 2036 + EL12_REG(TTBR0, access_vm_reg, reset_unknown, 0), 2037 + EL12_REG(TTBR1, access_vm_reg, reset_unknown, 0), 2038 + EL12_REG(TCR, access_vm_reg, reset_val, 0), 2039 + { SYS_DESC(SYS_SPSR_EL12), access_spsr}, 2040 + { SYS_DESC(SYS_ELR_EL12), access_elr}, 2041 + EL12_REG(AFSR0, access_vm_reg, reset_unknown, 0), 2042 + EL12_REG(AFSR1, access_vm_reg, reset_unknown, 0), 2043 + EL12_REG(ESR, access_vm_reg, reset_unknown, 0), 2044 + EL12_REG(FAR, access_vm_reg, reset_unknown, 0), 2045 + EL12_REG(MAIR, access_vm_reg, reset_unknown, 0), 2046 + EL12_REG(AMAIR, access_vm_reg, reset_amair_el1, 0), 2047 + EL12_REG(VBAR, access_rw, reset_val, 0), 2048 + EL12_REG(CONTEXTIDR, access_vm_reg, reset_val, 0), 2049 + EL12_REG(CNTKCTL, access_rw, reset_val, 0), 2053 2050 2054 2051 EL2_REG(SP_EL2, NULL, reset_unknown, 0), 2055 2052 };