diff options
author | Cornelia Huck <cornelia.huck@de.ibm.com> | 2012-06-26 10:06:41 -0400 |
---|---|---|
committer | Marcelo Tosatti <mtosatti@redhat.com> | 2012-07-03 13:55:37 -0400 |
commit | 21b26c08535c992802402c7ba2d789ca9e1a5707 (patch) | |
tree | 97f8dad7b76e055f57503846eb470d99f2ec3300 /arch/s390 | |
parent | ea1918dd3d1a8fcb7ce26816fdf31a50f7d04689 (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.h | 1 | ||||
-rw-r--r-- | arch/s390/kvm/sigp.c | 14 |
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); |