Commit f7d3e466 authored by Thomas Huth's avatar Thomas Huth Committed by Christian Borntraeger
Browse files

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: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: default avatarThomas Huth <thuth@linux.vnet.ibm.com>
Reviewed-by: default avatarCornelia Huck <cornelia.huck@de.ibm.com>
Signed-off-by: default avatarChristian Borntraeger <borntraeger@de.ibm.com>
parent 49f5c9e9
Loading
Loading
Loading
Loading
+7 −18
Original line number Diff line number Diff line
@@ -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);