aboutsummaryrefslogtreecommitdiff
path: root/target-s390x
diff options
context:
space:
mode:
authorThomas Huth <thuth@linux.vnet.ibm.com>2014-01-24 16:39:54 +0100
committerChristian Borntraeger <borntraeger@de.ibm.com>2014-02-27 09:51:26 +0100
commitf7d3e466764e0258d0883d90edb7e98ad0b56e18 (patch)
tree9d4b1762c8780d0ae87aee8fa9ba33f4797eb713 /target-s390x
parent49f5c9e98ab44700b58e23ca8c17e21850328da1 (diff)
s390x/kvm: Rework SIGP INITIAL CPU RESET handler
The s390_cpu_initial_reset() function had two deficiencies: First, it used an ioctl for the destination CPU, and this ioctl could block nearly forever, as long as the destination CPU was running in the SIE loop. Second, it also cleared the general purpose registers - something it should not do according to the Principles of Operations. Since we've already got another function for the initial CPU reset in cpu.c, we can also use that function instead. And by using run_on_cpu() for executing this code, we make sure that the destination CPU is correctly kicked out of kernel mode now. Suggested-by: Christian Borntraeger <borntraeger@de.ibm.com> Signed-off-by: Thomas Huth <thuth@linux.vnet.ibm.com> Reviewed-by: Cornelia Huck <cornelia.huck@de.ibm.com> Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Diffstat (limited to 'target-s390x')
-rw-r--r--target-s390x/kvm.c25
1 files changed, 7 insertions, 18 deletions
diff --git a/target-s390x/kvm.c b/target-s390x/kvm.c
index d3f0d4a7b2..75e88224e3 100644
--- a/target-s390x/kvm.c
+++ b/target-s390x/kvm.c
@@ -626,25 +626,13 @@ int kvm_s390_cpu_restart(S390CPU *cpu)
return 0;
}
-static int s390_cpu_initial_reset(S390CPU *cpu)
+static void sigp_initial_cpu_reset(void *arg)
{
- CPUState *cs = CPU(cpu);
- CPUS390XState *env = &cpu->env;
- int i;
-
- s390_del_running_cpu(cpu);
- if (kvm_vcpu_ioctl(cs, KVM_S390_INITIAL_RESET, NULL) < 0) {
- perror("cannot init reset vcpu");
- }
+ CPUState *cpu = arg;
+ S390CPUClass *scc = S390_CPU_GET_CLASS(cpu);
- /* Manually zero out all registers */
- cpu_synchronize_state(cs);
- for (i = 0; i < 16; i++) {
- env->regs[i] = 0;
- }
-
- DPRINTF("DONE: SIGP initial reset: %p\n", env);
- return 0;
+ cpu_synchronize_state(cpu);
+ scc->initial_cpu_reset(cpu);
}
#define SIGP_ORDER_MASK 0x000000ff
@@ -683,7 +671,8 @@ static int handle_sigp(S390CPU *cpu, struct kvm_run *run, uint8_t ipa1)
cc = 1; /* status stored */
break;
case SIGP_INITIAL_CPU_RESET:
- cc = s390_cpu_initial_reset(target_cpu);
+ run_on_cpu(CPU(target_cpu), sigp_initial_cpu_reset, CPU(target_cpu));
+ cc = 0;
break;
default:
DPRINTF("KVM: unknown SIGP: 0x%x\n", order_code);