Skip to content

Commit a3d2ec9

Browse files
committed
Merge tag 'kvmarm-fixes-5.13-2' of git://git.kernel.org/pub/scm/linux/kernel/git/kvmarm/kvmarm into HEAD
KVM/arm64 fixes for 5.13, take Rust-for-Linux#2 - Another state update on exit to userspace fix - Prevent the creation of mixed 32/64 VMs
2 parents b35491e + 66e94d5 commit a3d2ec9

File tree

3 files changed

+35
-7
lines changed

3 files changed

+35
-7
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/arm.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -720,11 +720,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
720720
return ret;
721721
}
722722

723-
if (run->immediate_exit)
724-
return -EINTR;
725-
726723
vcpu_load(vcpu);
727724

725+
if (run->immediate_exit) {
726+
ret = -EINTR;
727+
goto out;
728+
}
729+
728730
kvm_sigset_activate(vcpu);
729731

730732
ret = 1;
@@ -897,6 +899,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu)
897899

898900
kvm_sigset_deactivate(vcpu);
899901

902+
out:
900903
/*
901904
* In the unlikely event that we are returning to userspace
902905
* with pending exceptions or PC adjustment, commit these

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)