aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorPaolo Bonzini <pbonzini@redhat.com>2013-12-12 05:41:33 -0500
committerPaolo Bonzini <pbonzini@redhat.com>2013-12-12 05:41:33 -0500
commit6bb05ef78553491b2e2e0710dde364331dc3cdd2 (patch)
tree02e15152f1fa25c21155d1e021d20972ac57ea36 /arch/s390
parent6dfacadd5858882eee1983995854d4e1fb1b966e (diff)
parentff1f3cb4b3ac5d039f02679f34cb1498d110d241 (diff)
Merge tag 'kvm-s390-20131211' of git://git.kernel.org/pub/scm/linux/kernel/git/kvms390/linux into kvm-next
Some further s390 patches for kvm-next. Various improvements and bugfixes in the signal processor handling. Document kvm support for diagnose (s390 hypercalls). And last but not least, fix a bug in the s390 ioeventfd backend that was causing us grief in scenarios with 4G+ memory.
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/sigp.h2
-rw-r--r--arch/s390/kvm/diag.c2
-rw-r--r--arch/s390/kvm/sigp.c64
3 files changed, 56 insertions, 12 deletions
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index 5a87d16d3e7c..d091aa1aaf11 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -5,6 +5,7 @@
5#define SIGP_SENSE 1 5#define SIGP_SENSE 1
6#define SIGP_EXTERNAL_CALL 2 6#define SIGP_EXTERNAL_CALL 2
7#define SIGP_EMERGENCY_SIGNAL 3 7#define SIGP_EMERGENCY_SIGNAL 3
8#define SIGP_START 4
8#define SIGP_STOP 5 9#define SIGP_STOP 5
9#define SIGP_RESTART 6 10#define SIGP_RESTART 6
10#define SIGP_STOP_AND_STORE_STATUS 9 11#define SIGP_STOP_AND_STORE_STATUS 9
@@ -12,6 +13,7 @@
12#define SIGP_SET_PREFIX 13 13#define SIGP_SET_PREFIX 13
13#define SIGP_STORE_STATUS_AT_ADDRESS 14 14#define SIGP_STORE_STATUS_AT_ADDRESS 14
14#define SIGP_SET_ARCHITECTURE 18 15#define SIGP_SET_ARCHITECTURE 18
16#define SIGP_COND_EMERGENCY_SIGNAL 19
15#define SIGP_SENSE_RUNNING 21 17#define SIGP_SENSE_RUNNING 21
16 18
17/* SIGP condition codes */ 19/* SIGP condition codes */
diff --git a/arch/s390/kvm/diag.c b/arch/s390/kvm/diag.c
index 5ff29be7d87a..8216c0e0b2e2 100644
--- a/arch/s390/kvm/diag.c
+++ b/arch/s390/kvm/diag.c
@@ -121,7 +121,7 @@ static int __diag_virtio_hypercall(struct kvm_vcpu *vcpu)
121 * - gpr 4 contains the index on the bus (optionally) 121 * - gpr 4 contains the index on the bus (optionally)
122 */ 122 */
123 ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS, 123 ret = kvm_io_bus_write_cookie(vcpu->kvm, KVM_VIRTIO_CCW_NOTIFY_BUS,
124 vcpu->run->s.regs.gprs[2], 124 vcpu->run->s.regs.gprs[2] & 0xffffffff,
125 8, &vcpu->run->s.regs.gprs[3], 125 8, &vcpu->run->s.regs.gprs[3],
126 vcpu->run->s.regs.gprs[4]); 126 vcpu->run->s.regs.gprs[4]);
127 127
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index c3700585b4bb..87c2b3a3bd3e 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * handling interprocessor communication 2 * handling interprocessor communication
3 * 3 *
4 * Copyright IBM Corp. 2008, 2009 4 * Copyright IBM Corp. 2008, 2013
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License (version 2 only) 7 * it under the terms of the GNU General Public License (version 2 only)
@@ -89,6 +89,37 @@ unlock:
89 return rc; 89 return rc;
90} 90}
91 91
92static int __sigp_conditional_emergency(struct kvm_vcpu *vcpu, u16 cpu_addr,
93 u16 asn, u64 *reg)
94{
95 struct kvm_vcpu *dst_vcpu = NULL;
96 const u64 psw_int_mask = PSW_MASK_IO | PSW_MASK_EXT;
97 u16 p_asn, s_asn;
98 psw_t *psw;
99 u32 flags;
100
101 if (cpu_addr < KVM_MAX_VCPUS)
102 dst_vcpu = kvm_get_vcpu(vcpu->kvm, cpu_addr);
103 if (!dst_vcpu)
104 return SIGP_CC_NOT_OPERATIONAL;
105 flags = atomic_read(&dst_vcpu->arch.sie_block->cpuflags);
106 psw = &dst_vcpu->arch.sie_block->gpsw;
107 p_asn = dst_vcpu->arch.sie_block->gcr[4] & 0xffff; /* Primary ASN */
108 s_asn = dst_vcpu->arch.sie_block->gcr[3] & 0xffff; /* Secondary ASN */
109
110 /* Deliver the emergency signal? */
111 if (!(flags & CPUSTAT_STOPPED)
112 || (psw->mask & psw_int_mask) != psw_int_mask
113 || ((flags & CPUSTAT_WAIT) && psw->addr != 0)
114 || (!(flags & CPUSTAT_WAIT) && (asn == p_asn || asn == s_asn))) {
115 return __sigp_emergency(vcpu, cpu_addr);
116 } else {
117 *reg &= 0xffffffff00000000UL;
118 *reg |= SIGP_STATUS_INCORRECT_STATE;
119 return SIGP_CC_STATUS_STORED;
120 }
121}
122
92static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr) 123static int __sigp_external_call(struct kvm_vcpu *vcpu, u16 cpu_addr)
93{ 124{
94 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 125 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
@@ -332,7 +363,8 @@ static int __sigp_sense_running(struct kvm_vcpu *vcpu, u16 cpu_addr,
332 return rc; 363 return rc;
333} 364}
334 365
335static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr) 366/* Test whether the destination CPU is available and not busy */
367static int sigp_check_callable(struct kvm_vcpu *vcpu, u16 cpu_addr)
336{ 368{
337 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int; 369 struct kvm_s390_float_interrupt *fi = &vcpu->kvm->arch.float_int;
338 struct kvm_s390_local_interrupt *li; 370 struct kvm_s390_local_interrupt *li;
@@ -351,9 +383,6 @@ static int __sigp_restart(struct kvm_vcpu *vcpu, u16 cpu_addr)
351 spin_lock_bh(&li->lock); 383 spin_lock_bh(&li->lock);
352 if (li->action_bits & ACTION_STOP_ON_STOP) 384 if (li->action_bits & ACTION_STOP_ON_STOP)
353 rc = SIGP_CC_BUSY; 385 rc = SIGP_CC_BUSY;
354 else
355 VCPU_EVENT(vcpu, 4, "sigp restart %x to handle userspace",
356 cpu_addr);
357 spin_unlock_bh(&li->lock); 386 spin_unlock_bh(&li->lock);
358out: 387out:
359 spin_unlock(&fi->lock); 388 spin_unlock(&fi->lock);
@@ -417,17 +446,31 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
417 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter, 446 rc = __sigp_set_prefix(vcpu, cpu_addr, parameter,
418 &vcpu->run->s.regs.gprs[r1]); 447 &vcpu->run->s.regs.gprs[r1]);
419 break; 448 break;
449 case SIGP_COND_EMERGENCY_SIGNAL:
450 rc = __sigp_conditional_emergency(vcpu, cpu_addr, parameter,
451 &vcpu->run->s.regs.gprs[r1]);
452 break;
420 case SIGP_SENSE_RUNNING: 453 case SIGP_SENSE_RUNNING:
421 vcpu->stat.instruction_sigp_sense_running++; 454 vcpu->stat.instruction_sigp_sense_running++;
422 rc = __sigp_sense_running(vcpu, cpu_addr, 455 rc = __sigp_sense_running(vcpu, cpu_addr,
423 &vcpu->run->s.regs.gprs[r1]); 456 &vcpu->run->s.regs.gprs[r1]);
424 break; 457 break;
458 case SIGP_START:
459 rc = sigp_check_callable(vcpu, cpu_addr);
460 if (rc == SIGP_CC_ORDER_CODE_ACCEPTED)
461 rc = -EOPNOTSUPP; /* Handle START in user space */
462 break;
425 case SIGP_RESTART: 463 case SIGP_RESTART:
426 vcpu->stat.instruction_sigp_restart++; 464 vcpu->stat.instruction_sigp_restart++;
427 rc = __sigp_restart(vcpu, cpu_addr); 465 rc = sigp_check_callable(vcpu, cpu_addr);
428 if (rc == SIGP_CC_BUSY) 466 if (rc == SIGP_CC_ORDER_CODE_ACCEPTED) {
429 break; 467 VCPU_EVENT(vcpu, 4,
430 /* user space must know about restart */ 468 "sigp restart %x to handle userspace",
469 cpu_addr);
470 /* user space must know about restart */
471 rc = -EOPNOTSUPP;
472 }
473 break;
431 default: 474 default:
432 return -EOPNOTSUPP; 475 return -EOPNOTSUPP;
433 } 476 }
@@ -435,7 +478,6 @@ int kvm_s390_handle_sigp(struct kvm_vcpu *vcpu)
435 if (rc < 0) 478 if (rc < 0)
436 return rc; 479 return rc;
437 480
438 vcpu->arch.sie_block->gpsw.mask &= ~(3ul << 44); 481 kvm_s390_set_psw_cc(vcpu, rc);
439 vcpu->arch.sie_block->gpsw.mask |= (rc & 3ul) << 44;
440 return 0; 482 return 0;
441} 483}