[PATCH] LoongArch: KVM: Fix TOCTOU race on pv_features
Tao Cui <[email protected]>
| Newsgroups | dev.linux.lists.loongarch,org.kernel.vger.kvm,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
From: Tao Cui <[email protected]> kvm_loongarch_cpucfg_set_attr() validates and writes the VM-wide pv_features with a lockless check-then-set, so two vCPUs racing it can both pass the "all-vCPUs-must-match" check and install divergent values. Make the check-then-set atomic with a cmpxchg loop; the UPDATED bit already packs the configured state into the same word. Signed-off-by: Tao Cui <[email protected]> --- arch/loongarch/kvm/vcpu.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c index 20c207d80e31..55030c37cf06 100644 --- a/arch/loongarch/kvm/vcpu.c +++ b/arch/loongarch/kvm/vcpu.c @@ -1164,12 +1164,18 @@ static int kvm_loongarch_cpucfg_set_attr(struct kvm_vcpu *vcpu, if (val & ~valid) return -EINVAL; - /* All vCPUs need set the same PV features */ - if ((kvm->arch.pv_features & LOONGARCH_PV_FEAT_UPDATED) - && ((kvm->arch.pv_features & valid) != val)) - return -EINVAL; - kvm->arch.pv_features = val | LOONGARCH_PV_FEAT_UPDATED; - return 0; + /* Atomically install val; the cmpxchg serializes concurrent setters. */ + for (;;) { + unsigned long old, new; + + old = READ_ONCE(kvm->arch.pv_features); + if ((old & LOONGARCH_PV_FEAT_UPDATED) && + ((old & valid) != val)) + return -EINVAL; + new = val | LOONGARCH_PV_FEAT_UPDATED; + if (cmpxchg(&kvm->arch.pv_features, old, new) == old) + return 0; + } default: return -ENXIO; } -- 2.43.0