diff options
author | Thomas Huth <thuth@linux.vnet.ibm.com> | 2013-11-13 14:48:51 -0500 |
---|---|---|
committer | Cornelia Huck <cornelia.huck@de.ibm.com> | 2013-11-28 05:08:16 -0500 |
commit | 00e9e435f97b409db8986f9cd35d126ae2d02a0c (patch) | |
tree | 5ff9f7547d23f7332c3ffb35d2ba6d4948657de2 /arch/s390 | |
parent | 743db27c526e0f31cc507959d662e97e2048a86f (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.c | 35 | ||||
-rw-r--r-- | arch/s390/kvm/trace.h | 1 |
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 | ||
278 | static 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 | |||
278 | static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr, | 309 | static 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 | ||