KVM: s390/diag: fix racy access of physical cpu number in diag 9c handler
authorChristian Borntraeger <borntraeger@linux.ibm.com>
Mon, 15 May 2023 08:42:34 +0000 (10:42 +0200)
committerJanosch Frank <frankja@linux.ibm.com>
Fri, 16 Jun 2023 09:08:09 +0000 (11:08 +0200)
We do check for target CPU == -1, but this might change at the time we
are going to use it. Hold the physical target CPU in a local variable to
avoid out-of-bound accesses to the cpu arrays.

Cc: Pierre Morel <pmorel@linux.ibm.com>
Fixes: 87e28a15c42c ("KVM: s390: diag9c (directed yield) forwarding")
Reported-by: Marc Hartmayer <mhartmay@linux.ibm.com>
Reviewed-by: Nico Boehr <nrb@linux.ibm.com>
Reviewed-by: Pierre Morel <pmorel@linux.ibm.com>
Signed-off-by: Christian Borntraeger <borntraeger@linux.ibm.com>
Signed-off-by: Janosch Frank <frankja@linux.ibm.com>
arch/s390/kvm/diag.c

index 807fa9da1e721d59b637189309f7c1681d1b8b24..3c65b8258ae67ad4b28589494e663034e69dffdd 100644 (file)
@@ -166,6 +166,7 @@ static int diag9c_forwarding_overrun(void)
 static int __diag_time_slice_end_directed(struct kvm_vcpu *vcpu)
 {
        struct kvm_vcpu *tcpu;
+       int tcpu_cpu;
        int tid;
 
        tid = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
@@ -181,14 +182,15 @@ static int __diag_time_slice_end_directed(struct kvm_vcpu *vcpu)
                goto no_yield;
 
        /* target guest VCPU already running */
-       if (READ_ONCE(tcpu->cpu) >= 0) {
+       tcpu_cpu = READ_ONCE(tcpu->cpu);
+       if (tcpu_cpu >= 0) {
                if (!diag9c_forwarding_hz || diag9c_forwarding_overrun())
                        goto no_yield;
 
                /* target host CPU already running */
-               if (!vcpu_is_preempted(tcpu->cpu))
+               if (!vcpu_is_preempted(tcpu_cpu))
                        goto no_yield;
-               smp_yield_cpu(tcpu->cpu);
+               smp_yield_cpu(tcpu_cpu);
                VCPU_EVENT(vcpu, 5,
                           "diag time slice end directed to %d: yield forwarded",
                           tid);