aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--target-s390x/kvm.c17
1 files changed, 11 insertions, 6 deletions
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;
}