| .. | .. |
|---|
| 2 | 2 | /* |
|---|
| 3 | 3 | * handling diagnose instructions |
|---|
| 4 | 4 | * |
|---|
| 5 | | - * Copyright IBM Corp. 2008, 2011 |
|---|
| 5 | + * Copyright IBM Corp. 2008, 2020 |
|---|
| 6 | 6 | * |
|---|
| 7 | 7 | * Author(s): Carsten Otte <cotte@de.ibm.com> |
|---|
| 8 | 8 | * Christian Borntraeger <borntraeger@de.ibm.com> |
|---|
| .. | .. |
|---|
| 10 | 10 | |
|---|
| 11 | 11 | #include <linux/kvm.h> |
|---|
| 12 | 12 | #include <linux/kvm_host.h> |
|---|
| 13 | | -#include <asm/pgalloc.h> |
|---|
| 14 | 13 | #include <asm/gmap.h> |
|---|
| 15 | 14 | #include <asm/virtio-ccw.h> |
|---|
| 16 | 15 | #include "kvm-s390.h" |
|---|
| .. | .. |
|---|
| 158 | 157 | |
|---|
| 159 | 158 | tid = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4]; |
|---|
| 160 | 159 | vcpu->stat.diagnose_9c++; |
|---|
| 161 | | - VCPU_EVENT(vcpu, 5, "diag time slice end directed to %d", tid); |
|---|
| 162 | 160 | |
|---|
| 161 | + /* yield to self */ |
|---|
| 163 | 162 | if (tid == vcpu->vcpu_id) |
|---|
| 164 | | - return 0; |
|---|
| 163 | + goto no_yield; |
|---|
| 165 | 164 | |
|---|
| 165 | + /* yield to invalid */ |
|---|
| 166 | 166 | tcpu = kvm_get_vcpu_by_id(vcpu->kvm, tid); |
|---|
| 167 | | - if (tcpu) |
|---|
| 168 | | - kvm_vcpu_yield_to(tcpu); |
|---|
| 167 | + if (!tcpu) |
|---|
| 168 | + goto no_yield; |
|---|
| 169 | + |
|---|
| 170 | + /* target already running */ |
|---|
| 171 | + if (READ_ONCE(tcpu->cpu) >= 0) |
|---|
| 172 | + goto no_yield; |
|---|
| 173 | + |
|---|
| 174 | + if (kvm_vcpu_yield_to(tcpu) <= 0) |
|---|
| 175 | + goto no_yield; |
|---|
| 176 | + |
|---|
| 177 | + VCPU_EVENT(vcpu, 5, "diag time slice end directed to %d: done", tid); |
|---|
| 178 | + return 0; |
|---|
| 179 | +no_yield: |
|---|
| 180 | + VCPU_EVENT(vcpu, 5, "diag time slice end directed to %d: ignored", tid); |
|---|
| 181 | + vcpu->stat.diagnose_9c_ignored++; |
|---|
| 169 | 182 | return 0; |
|---|
| 170 | 183 | } |
|---|
| 171 | 184 | |
|---|
| .. | .. |
|---|
| 187 | 200 | return -EOPNOTSUPP; |
|---|
| 188 | 201 | } |
|---|
| 189 | 202 | |
|---|
| 203 | + /* |
|---|
| 204 | + * no need to check the return value of vcpu_stop as it can only have |
|---|
| 205 | + * an error for protvirt, but protvirt means user cpu state |
|---|
| 206 | + */ |
|---|
| 190 | 207 | if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm)) |
|---|
| 191 | 208 | kvm_s390_vcpu_stop(vcpu); |
|---|
| 192 | 209 | vcpu->run->s390_reset_flags |= KVM_S390_RESET_SUBSYSTEM; |
|---|