forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/arch/s390/kvm/diag.c
....@@ -2,7 +2,7 @@
22 /*
33 * handling diagnose instructions
44 *
5
- * Copyright IBM Corp. 2008, 2011
5
+ * Copyright IBM Corp. 2008, 2020
66 *
77 * Author(s): Carsten Otte <cotte@de.ibm.com>
88 * Christian Borntraeger <borntraeger@de.ibm.com>
....@@ -10,7 +10,6 @@
1010
1111 #include <linux/kvm.h>
1212 #include <linux/kvm_host.h>
13
-#include <asm/pgalloc.h>
1413 #include <asm/gmap.h>
1514 #include <asm/virtio-ccw.h>
1615 #include "kvm-s390.h"
....@@ -158,14 +157,28 @@
158157
159158 tid = vcpu->run->s.regs.gprs[(vcpu->arch.sie_block->ipa & 0xf0) >> 4];
160159 vcpu->stat.diagnose_9c++;
161
- VCPU_EVENT(vcpu, 5, "diag time slice end directed to %d", tid);
162160
161
+ /* yield to self */
163162 if (tid == vcpu->vcpu_id)
164
- return 0;
163
+ goto no_yield;
165164
165
+ /* yield to invalid */
166166 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++;
169182 return 0;
170183 }
171184
....@@ -187,6 +200,10 @@
187200 return -EOPNOTSUPP;
188201 }
189202
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
+ */
190207 if (!kvm_s390_user_cpu_state_ctrl(vcpu->kvm))
191208 kvm_s390_vcpu_stop(vcpu);
192209 vcpu->run->s390_reset_flags |= KVM_S390_RESET_SUBSYSTEM;