Skip to content

Commit 66e94d5

Browse files
author
Marc Zyngier
committed
KVM: arm64: Prevent mixed-width VM creation
It looks like we have tolerated creating mixed-width VMs since... forever. However, that was never the intention, and we'd rather not have to support that pointless complexity. Forbid such a setup by making sure all the vcpus have the same register width. Reported-by: Steven Price <[email protected]> Signed-off-by: Marc Zyngier <[email protected]> Cc: [email protected] Acked-by: Mark Rutland <[email protected]> Link: https://lore.kernel.org/r/[email protected]
1 parent e3e880b commit 66e94d5

File tree

2 files changed

+29
-4
lines changed

2 files changed

+29
-4
lines changed

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -463,4 +463,9 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
463463
vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC;
464464
}
465465

466+
static inline bool vcpu_has_feature(struct kvm_vcpu *vcpu, int feature)
467+
{
468+
return test_bit(feature, vcpu->arch.features);
469+
}
470+
466471
#endif /* __ARM64_KVM_EMULATE_H__ */

arch/arm64/kvm/reset.c

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,25 @@ static int kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu)
166166
return 0;
167167
}
168168

169+
static bool vcpu_allowed_register_width(struct kvm_vcpu *vcpu)
170+
{
171+
struct kvm_vcpu *tmp;
172+
bool is32bit;
173+
int i;
174+
175+
is32bit = vcpu_has_feature(vcpu, KVM_ARM_VCPU_EL1_32BIT);
176+
if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1) && is32bit)
177+
return false;
178+
179+
/* Check that the vcpus are either all 32bit or all 64bit */
180+
kvm_for_each_vcpu(i, tmp, vcpu->kvm) {
181+
if (vcpu_has_feature(tmp, KVM_ARM_VCPU_EL1_32BIT) != is32bit)
182+
return false;
183+
}
184+
185+
return true;
186+
}
187+
169188
/**
170189
* kvm_reset_vcpu - sets core registers and sys_regs to reset value
171190
* @vcpu: The VCPU pointer
@@ -217,13 +236,14 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu)
217236
}
218237
}
219238

239+
if (!vcpu_allowed_register_width(vcpu)) {
240+
ret = -EINVAL;
241+
goto out;
242+
}
243+
220244
switch (vcpu->arch.target) {
221245
default:
222246
if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) {
223-
if (!cpus_have_const_cap(ARM64_HAS_32BIT_EL1)) {
224-
ret = -EINVAL;
225-
goto out;
226-
}
227247
pstate = VCPU_RESET_PSTATE_SVC;
228248
} else {
229249
pstate = VCPU_RESET_PSTATE_EL1;

0 commit comments

Comments
 (0)