From 3796f0e1cda41eacf4fc915e7edaf54f2279466c Mon Sep 17 00:00:00 2001 From: Thomas Huth Date: Tue, 17 Dec 2013 14:22:09 +0100 Subject: s390x/kvm: Fixed condition code for unknown SIGP orders 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 Reviewed-by: Cornelia Huck Signed-off-by: Jens Freimann Signed-off-by: Alexander Graf --- target-s390x/kvm.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'target-s390x') diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c index 0bf3d1f49e..f7b772668c 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; } -- cgit v1.2.1