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

KVM: arm64: nv: Reset VCPU to EL2 registers if VCPU nested virt is set

Reset the VCPU with PSTATE.M = EL2h when the nested virtualization
feature is enabled on the VCPU.

Reviewed-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
Reviewed-by: Alexandru Elisei <alexandru.elisei@arm.com>
Signed-off-by: Christoffer Dall <christoffer.dall@arm.com>
[maz: rework register reset not to use empty data structures]
Signed-off-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20230209175820.1939006-5-maz@kernel.org
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>

authored by

Christoffer Dall and committed by
Oliver Upton
2fb32357 89b0e7de

+16
+16
arch/arm64/kvm/reset.c
··· 27 27 #include <asm/kvm_asm.h> 28 28 #include <asm/kvm_emulate.h> 29 29 #include <asm/kvm_mmu.h> 30 + #include <asm/kvm_nested.h> 30 31 #include <asm/virt.h> 31 32 32 33 /* Maximum phys_shift supported for any VM on this host */ ··· 37 36 * ARMv8 Reset Values 38 37 */ 39 38 #define VCPU_RESET_PSTATE_EL1 (PSR_MODE_EL1h | PSR_A_BIT | PSR_I_BIT | \ 39 + PSR_F_BIT | PSR_D_BIT) 40 + 41 + #define VCPU_RESET_PSTATE_EL2 (PSR_MODE_EL2h | PSR_A_BIT | PSR_I_BIT | \ 40 42 PSR_F_BIT | PSR_D_BIT) 41 43 42 44 #define VCPU_RESET_PSTATE_SVC (PSR_AA32_MODE_SVC | PSR_AA32_A_BIT | \ ··· 224 220 if (kvm_has_mte(kvm) && is32bit) 225 221 return -EINVAL; 226 222 223 + /* NV is incompatible with AArch32 */ 224 + if (vcpu_has_nv(vcpu) && is32bit) 225 + return -EINVAL; 226 + 227 227 if (is32bit) 228 228 set_bit(KVM_ARCH_FLAG_EL1_32BIT, &kvm->arch.flags); 229 229 ··· 280 272 if (loaded) 281 273 kvm_arch_vcpu_put(vcpu); 282 274 275 + /* Disallow NV+SVE for the time being */ 276 + if (vcpu_has_nv(vcpu) && vcpu_has_feature(vcpu, KVM_ARM_VCPU_SVE)) { 277 + ret = -EINVAL; 278 + goto out; 279 + } 280 + 283 281 if (!kvm_arm_vcpu_sve_finalized(vcpu)) { 284 282 if (test_bit(KVM_ARM_VCPU_SVE, vcpu->arch.features)) { 285 283 ret = kvm_vcpu_enable_sve(vcpu); ··· 308 294 default: 309 295 if (vcpu_el1_is_32bit(vcpu)) { 310 296 pstate = VCPU_RESET_PSTATE_SVC; 297 + } else if (vcpu_has_nv(vcpu)) { 298 + pstate = VCPU_RESET_PSTATE_EL2; 311 299 } else { 312 300 pstate = VCPU_RESET_PSTATE_EL1; 313 301 }