diff mbox

[PULL,7/8] s390x/kvm: Fixed condition code for unknown SIGP orders

Message ID 1387373261-26398-8-git-send-email-agraf@suse.de
State New
Headers show

Commit Message

Alexander Graf Dec. 18, 2013, 1:27 p.m. UTC
From: Thomas Huth <thuth@linux.vnet.ibm.com>

If SIGP is called with an unknown order code, it has to return CC1
instead of CC3 and set the "invalid order" bit in the return status.

Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: Jens Freimann <jfrei@linux.vnet.ibm.com>
Signed-off-by: Alexander Graf <agraf@suse.de>
---
 target-s390x/kvm.c |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)
diff mbox

Patch

diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index 0bf3d1f..f7b7726 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -633,8 +633,9 @@  static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
     CPUS390XState *env = &cpu->env;
     uint8_t order_code;
     uint16_t cpu_addr;
-    int r = -1;
     S390CPU *target_cpu;
+    uint64_t *statusreg = &env->regs[ipa1 >> 4];
+    int cc;
 
     cpu_synchronize_state(CPU(cpu));
 
@@ -644,29 +645,33 @@  static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
     cpu_addr = env->regs[ipa1 & 0x0f];
     target_cpu = s390_cpu_addr2state(cpu_addr);
     if (target_cpu == NULL) {
+        cc = 3;    /* not operational */
         goto out;
     }
 
     switch (order_code) {
     case SIGP_START:
-        r = kvm_s390_cpu_start(target_cpu);
+        cc = kvm_s390_cpu_start(target_cpu);
         break;
     case SIGP_RESTART:
-        r = kvm_s390_cpu_restart(target_cpu);
+        cc = kvm_s390_cpu_restart(target_cpu);
         break;
     case SIGP_SET_ARCH:
         /* make the caller panic */
         return -1;
     case SIGP_INITIAL_CPU_RESET:
-        r = s390_cpu_initial_reset(target_cpu);
+        cc = s390_cpu_initial_reset(target_cpu);
         break;
     default:
-        fprintf(stderr, "KVM: unknown SIGP: 0x%x\n", order_code);
+        DPRINTF("KVM: unknown SIGP: 0x%x\n", order_code);
+        *statusreg &= 0xffffffff00000000UL;
+        *statusreg |= SIGP_STAT_INVALID_ORDER;
+        cc = 1;   /* status stored */
         break;
     }
 
 out:
-    setcc(cpu, r ? 3 : 0);
+    setcc(cpu, cc);
     return 0;
 }