aboutsummaryrefslogtreecommitdiffstats
path: root/arch/s390
diff options
context:
space:
mode:
authorCornelia Huck <cornelia.huck@de.ibm.com>2012-06-26 10:06:41 -0400
committerMarcelo Tosatti <mtosatti@redhat.com>2012-07-03 13:55:37 -0400
commit21b26c08535c992802402c7ba2d789ca9e1a5707 (patch)
tree97f8dad7b76e055f57503846eb470d99f2ec3300 /arch/s390
parentea1918dd3d1a8fcb7ce26816fdf31a50f7d04689 (diff)
KVM: s390: Fix sigp sense handling.
If sigp sense doesn't have any status bits to report, it should set cc 0 and leave the register as-is. Since we know about the external call pending bit, we should report it if it is set as well. Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> Reviewed-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/s390')
-rw-r--r--arch/s390/include/asm/sigp.h1
-rw-r--r--arch/s390/kvm/sigp.c14
2 files changed, 10 insertions, 5 deletions
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index 7306270b5b84..5a87d16d3e7c 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -24,6 +24,7 @@
24 24
25#define SIGP_STATUS_CHECK_STOP 0x00000010UL 25#define SIGP_STATUS_CHECK_STOP 0x00000010UL
26#define SIGP_STATUS_STOPPED 0x00000040UL 26#define SIGP_STATUS_STOPPED 0x00000040UL
27#define SIGP_STATUS_EXT_CALL_PENDING 0x00000080UL
27#define SIGP_STATUS_INVALID_PARAMETER 0x00000100UL 28#define SIGP_STATUS_INVALID_PARAMETER 0x00000100UL
28#define SIGP_STATUS_INCORRECT_STATE 0x00000200UL 29#define SIGP_STATUS_INCORRECT_STATE 0x00000200UL
29#define SIGP_STATUS_NOT_RUNNING 0x00000400UL 30#define SIGP_STATUS_NOT_RUNNING 0x00000400UL
diff --git a/arch/s390/kvm/sigp.c b/arch/s390/kvm/sigp.c
index 97c9f36a4533..6ed8175ca7e7 100644
--- a/arch/s390/kvm/sigp.c
+++ b/arch/s390/kvm/sigp.c
@@ -32,12 +32,16 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,
32 if (fi->local_int[cpu_addr] == NULL) 32 if (fi->local_int[cpu_addr] == NULL)
33 rc = SIGP_CC_NOT_OPERATIONAL; 33 rc = SIGP_CC_NOT_OPERATIONAL;
34 else if (!(atomic_read(fi->local_int[cpu_addr]->cpuflags) 34 else if (!(atomic_read(fi->local_int[cpu_addr]->cpuflags)
35 & CPUSTAT_STOPPED)) { 35 & (CPUSTAT_ECALL_PEND | CPUSTAT_STOPPED)))
36 *reg &= 0xffffffff00000000UL; 36 rc = SIGP_CC_ORDER_CODE_ACCEPTED;
37 rc = SIGP_CC_STATUS_STORED; 37 else {
38 } else {
39 *reg &= 0xffffffff00000000UL; 38 *reg &= 0xffffffff00000000UL;
40 *reg |= SIGP_STATUS_STOPPED; 39 if (atomic_read(fi->local_int[cpu_addr]->cpuflags)
40 & CPUSTAT_ECALL_PEND)
41 *reg |= SIGP_STATUS_EXT_CALL_PENDING;
42 if (atomic_read(fi->local_int[cpu_addr]->cpuflags)
43 & CPUSTAT_STOPPED)
44 *reg |= SIGP_STATUS_STOPPED;
41 rc = SIGP_CC_STATUS_STORED; 45 rc = SIGP_CC_STATUS_STORED;
42 } 46 }
43 spin_unlock(&fi->lock); 47 spin_unlock(&fi->lock);