aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorThomas Huth <thuth@linux.vnet.ibm.com>2013-11-13 14:48:51 -0500
committerCornelia Huck <cornelia.huck@de.ibm.com>2013-11-28 05:08:16 -0500
commit00e9e435f97b409db8986f9cd35d126ae2d02a0c (patch)
tree5ff9f7547d23f7332c3ffb35d2ba6d4948657de2 /arch/s390
parent743db27c526e0f31cc507959d662e97e2048a86f (diff)
KVM: s390: Add SIGP store-status-at-address order
The STORE STATUS AT ADDRESS order of SIGP was still missing. Now it is supported, using the common kvm_s390_store_status() function. Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/kvm/sigp.c35
-rw-r--r--arch/s390/kvm/trace.h1
2 files changed, 36 insertions, 0 deletions
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 6805601262e0..c137ed35a86d 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -275,6 +275,37 @@ out_fi:
275 return rc; 275 return rc;
276} 276}
277 277
278static int __sigp_store_status_at_addr(struct kvm_vcpu *vcpu, u16 cpu_id,
279 u32 addr, u64 *reg)
280{
281 struct kvm_vcpu *dst_vcpu = NULL;
282 int flags;
283 int rc;
284
285 if (cpu_id < KVM_MAX_VCPUS)
286 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_id);
287 if (!dst_vcpu)
288 return SIGP_CC_NOT_OPERATIONAL;
289
290 spin_lock_bh(&dst_vcpu->arch.local_int.lock);
291 flags = atomic_read(dst_vcpu->arch.local_int.cpuflags);
292 spin_unlock_bh(&dst_vcpu->arch.local_int.lock);
293 if (!(flags & CPUSTAT_STOPPED)) {
294 *reg &= 0xffffffff00000000UL;
295 *reg |= SIGP_STATUS_INCORRECT_STATE;
296 return SIGP_CC_STATUS_STORED;
297 }
298
299 addr &= 0x7ffffe00;
300 rc = kvm_s390_store_status_unloaded(dst_vcpu, addr);
301 if (rc == -EFAULT) {
302 *reg &= 0xffffffff00000000UL;
303 *reg |= SIGP_STATUS_INVALID_PARAMETER;
304 rc = SIGP_CC_STATUS_STORED;
305 }
306 return rc;
307}
308
278static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, 309static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
279 u64 *reg) 310 u64 *reg)
280{ 311{
@@ -379,6 +410,10 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
379 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP | 410 rc = __sigp_stop(vcpu, cpu_addr, ACTION_STORE_ON_STOP |
380 ACTION_STOP_ON_STOP); 411 ACTION_STOP_ON_STOP);
381 break; 412 break;
413 case SIGP_STORE_STATUS_AT_ADDRESS:
414 rc = __sigp_store_status_at_addr(vcpu, cpu_addr, parameter,
415 &vcpu->run->s.regs.gprs[r1]);
416 break;
382 case SIGP_SET_ARCHITECTURE: 417 case SIGP_SET_ARCHITECTURE:
383 vcpu->stat.instruction_sigp_arch++; 418 vcpu->stat.instruction_sigp_arch++;
384 rc = __sigp_set_arch(vcpu, parameter); 419 rc = __sigp_set_arch(vcpu, parameter);
diff --git a/arch/s390/kvm/trace.h b/arch/s390/kvm/trace.h
index 0c991c6748ab..3db76b2daed7 100644
--- a/arch/s390/kvm/trace.h
+++ b/arch/s390/kvm/trace.h
@@ -175,6 +175,7 @@ TRACE_EVENT(kvm_s390_intercept_validity,
175 {SIGP_STOP_AND_STORE_STATUS, "stop and store status"}, \ 175 {SIGP_STOP_AND_STORE_STATUS, "stop and store status"}, \
176 {SIGP_SET_ARCHITECTURE, "set architecture"}, \ 176 {SIGP_SET_ARCHITECTURE, "set architecture"}, \
177 {SIGP_SET_PREFIX, "set prefix"}, \ 177 {SIGP_SET_PREFIX, "set prefix"}, \
178 {SIGP_STORE_STATUS_AT_ADDRESS, "store status at addr"}, \
178 {SIGP_SENSE_RUNNING, "sense running"}, \ 179 {SIGP_SENSE_RUNNING, "sense running"}, \
179 {SIGP_RESTART, "restart"} 180 {SIGP_RESTART, "restart"}
180 181