KVM/arm64 fixes for 5.13, take #2 - Another state update on exit to userspace fix - Prevent the creation of mixed 32/64 VMs
Unified · Split
| @@ -463,4 +463,9 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu) · 462 unmodified lines | |||
| 463 | vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC; | 463 | vcpu->arch.flags |= KVM_ARM64_INCREMENT_PC; |
| 464 | } | 464 | } |
| 465 | 465 | ||
| 466 | static inline bool vcpu_has_feature(struct kvm_vcpu *vcpu, int feature) | ||
| 467 | { | ||
| 468 | return test_bit(feature, vcpu->arch.features); | ||
| 469 | } | ||
| 470 | |||
| 466 | #endif /* __ARM64_KVM_EMULATE_H__ */ | 471 | #endif /* __ARM64_KVM_EMULATE_H__ */ |
| @@ -720,11 +720,13 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) · 719 unmodified lines | |||
| 720 | return ret; | 720 | return ret; |
| 721 | } | 721 | } |
| 722 | 722 | ||
| 723 | if (run->immediate_exit) | ||
| 724 | return -EINTR; | ||
| 725 | |||
| 726 | vcpu_load(vcpu); | 723 | vcpu_load(vcpu); |
| 727 | 724 | ||
| 725 | if (run->immediate_exit) { | ||
| 726 | ret = -EINTR; | ||
| 727 | goto out; | ||
| 728 | } | ||
| 729 | |||
| 728 | kvm_sigset_activate(vcpu); | 730 | kvm_sigset_activate(vcpu); |
| 729 | 731 | ||
| 730 | ret = 1; | 732 | ret = 1; |
| @@ -897,6 +899,7 @@ int kvm_arch_vcpu_ioctl_run(struct kvm_vcpu *vcpu) · 166 unmodified lines | |||
| 897 | 899 | ||
| 898 | kvm_sigset_deactivate(vcpu); | 900 | kvm_sigset_deactivate(vcpu); |
| 899 | 901 | ||
| 902 | out: | ||
| 900 | /* | 903 | /* |
| 901 | * In the unlikely event that we are returning to userspace | 904 | * In the unlikely event that we are returning to userspace |
| 902 | * with pending exceptions or PC adjustment, commit these | 905 | * with pending exceptions or PC adjustment, commit these |
| @@ -166,6 +166,25 @@ static int kvm_vcpu_enable_ptrauth(struct kvm_vcpu *vcpu) · 165 unmodified lines | |||
| 166 | return 0; | 166 | return 0; |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 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 | |||
| 169 | /** | 188 | /** |
| 170 | * kvm_reset_vcpu - sets core registers and sys_regs to reset value | 189 | * kvm_reset_vcpu - sets core registers and sys_regs to reset value |
| 171 | * @vcpu: The VCPU pointer | 190 | * @vcpu: The VCPU pointer |
| @@ -217,13 +236,14 @@ int kvm_reset_vcpu(struct kvm_vcpu *vcpu) · 45 unmodified lines | |||
| 217 | } | 236 | } |
| 218 | } | 237 | } |
| 219 | 238 | ||
| 239 | if (!vcpu_allowed_register_width(vcpu)) { | ||
| 240 | ret = -EINVAL; | ||
| 241 | goto out; | ||
| 242 | } | ||
| 243 | |||
| 220 | switch (vcpu->arch.target) { | 244 | switch (vcpu->arch.target) { |
| 221 | default: | 245 | default: |
| 222 | if (test_bit(KVM_ARM_VCPU_EL1_32BIT, vcpu->arch.features)) { | 246 | 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 | } | ||
| 227 | pstate = VCPU_RESET_PSTATE_SVC; | 247 | pstate = VCPU_RESET_PSTATE_SVC; |
| 228 | } else { | 248 | } else { |
| 229 | pstate = VCPU_RESET_PSTATE_EL1; | 249 | pstate = VCPU_RESET_PSTATE_EL1; |