KVM: s390: Fix sigp sense handling.
authorCornelia Huck <cornelia.huck@de.ibm.com>
Tue, 26 Jun 2012 14:06:41 +0000 (16:06 +0200)
committerMarcelo Tosatti <mtosatti@redhat.com>
Tue, 3 Jul 2012 17:55:37 +0000 (14:55 -0300)
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>
arch/s390/include/asm/sigp.h
arch/s390/kvm/sigp.c

index 7306270b5b8482ddeae6b2da11670ce982a7561c..5a87d16d3e7c949c420d91558f5bb3513079e0f9 100644 (file)
@@ -24,6 +24,7 @@
 
 #define SIGP_STATUS_CHECK_STOP         0x00000010UL
 #define SIGP_STATUS_STOPPED            0x00000040UL
+#define SIGP_STATUS_EXT_CALL_PENDING   0x00000080UL
 #define SIGP_STATUS_INVALID_PARAMETER  0x00000100UL
 #define SIGP_STATUS_INCORRECT_STATE    0x00000200UL
 #define SIGP_STATUS_NOT_RUNNING                0x00000400UL
index 97c9f36a4533bcdef79f95fdcd34a48ad325b759..6ed8175ca7e76a52d6b576294dc7da53be011604 100644 (file)
@@ -32,12 +32,16 @@ static int __sigp_sense(struct kvm_vcpu *vcpu, u16 cpu_addr,
        if (fi->local_int[cpu_addr] == NULL)
                rc = SIGP_CC_NOT_OPERATIONAL;
        else if (!(atomic_read(fi->local_int[cpu_addr]->cpuflags)
-                 & CPUSTAT_STOPPED)) {
-               *reg &= 0xffffffff00000000UL;
-               rc = SIGP_CC_STATUS_STORED;
-       } else {
+                  & (CPUSTAT_ECALL_PEND | CPUSTAT_STOPPED)))
+               rc = SIGP_CC_ORDER_CODE_ACCEPTED;
+       else {
                *reg &= 0xffffffff00000000UL;
-               *reg |= SIGP_STATUS_STOPPED;
+               if (atomic_read(fi->local_int[cpu_addr]->cpuflags)
+                   & CPUSTAT_ECALL_PEND)
+                       *reg |= SIGP_STATUS_EXT_CALL_PENDING;
+               if (atomic_read(fi->local_int[cpu_addr]->cpuflags)
+                   & CPUSTAT_STOPPED)
+                       *reg |= SIGP_STATUS_STOPPED;
                rc = SIGP_CC_STATUS_STORED;
        }
        spin_unlock(&fi->lock);