diff options
author | Paul Mackerras <paulus@ozlabs.org> | 2018-07-26 07:38:41 +0200 |
---|---|---|
committer | Paul Mackerras <paulus@ozlabs.org> | 2018-07-26 07:38:41 +0200 |
commit | b5c6f7607b908b1445f2556c8d2f3b1ec5fc5aa8 (patch) | |
tree | 8f2b60ec1b6dc6462210929f2ede6f3a25f9de63 /arch | |
parent | KVM: PPC: Book3S HV: Allow creating max number of VCPUs on POWER9 (diff) | |
download | linux-b5c6f7607b908b1445f2556c8d2f3b1ec5fc5aa8.tar.xz linux-b5c6f7607b908b1445f2556c8d2f3b1ec5fc5aa8.zip |
KVM: PPC: Book3S HV: Read kvm->arch.emul_smt_mode under kvm->lock
Commit 1e175d2 ("KVM: PPC: Book3S HV: Pack VCORE IDs to access full
VCPU ID space", 2018-07-25) added code that uses kvm->arch.emul_smt_mode
before any VCPUs are created. However, userspace can change
kvm->arch.emul_smt_mode at any time up until the first VCPU is created.
Hence it is (theoretically) possible for the check in
kvmppc_core_vcpu_create_hv() to race with another userspace thread
changing kvm->arch.emul_smt_mode.
This fixes it by moving the test that uses kvm->arch.emul_smt_mode into
the block where kvm->lock is held.
Signed-off-by: Paul Mackerras <paulus@ozlabs.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/kvm/book3s_hv.c | 17 |
1 files changed, 8 insertions, 9 deletions
diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 785245e09f32..113f81577668 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -1989,16 +1989,10 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, unsigned int id) { struct kvm_vcpu *vcpu; - int err = -EINVAL; + int err; int core; struct kvmppc_vcore *vcore; - if (id >= (KVM_MAX_VCPUS * kvm->arch.emul_smt_mode) && - cpu_has_feature(CPU_FTR_ARCH_300)) { - pr_devel("DNCI: VCPU ID too high\n"); - goto out; - } - err = -ENOMEM; vcpu = kmem_cache_zalloc(kvm_vcpu_cache, GFP_KERNEL); if (!vcpu) @@ -2055,8 +2049,13 @@ static struct kvm_vcpu *kvmppc_core_vcpu_create_hv(struct kvm *kvm, vcore = NULL; err = -EINVAL; if (cpu_has_feature(CPU_FTR_ARCH_300)) { - BUG_ON(kvm->arch.smt_mode != 1); - core = kvmppc_pack_vcpu_id(kvm, id); + if (id >= (KVM_MAX_VCPUS * kvm->arch.emul_smt_mode)) { + pr_devel("KVM: VCPU ID too high\n"); + core = KVM_MAX_VCORES; + } else { + BUG_ON(kvm->arch.smt_mode != 1); + core = kvmppc_pack_vcpu_id(kvm, id); + } } else { core = id / kvm->arch.smt_mode; } |