Commit 4e286099 authored by Justin Terry (VM)'s avatar Justin Terry (VM) Committed by Paolo Bonzini
Browse files

WHPX improve vcpu_post_run perf



This removes the additional call to WHvGetVirtualProcessorRegisters in
whpx_vcpu_post_run now that the WHV_VP_EXIT_CONTEXT is returned in all
WHV_RUN_VP_EXIT_CONTEXT structures.

Signed-off-by: default avatarJustin Terry (VM) <juterry@microsoft.com>
Message-Id: <1521039163-138-4-git-send-email-juterry@microsoft.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 60168541
Loading
Loading
Loading
Loading
+11 −30
Original line number Diff line number Diff line
@@ -153,7 +153,7 @@ struct whpx_vcpu {
    bool interruptable;
    uint64_t tpr;
    uint64_t apic_base;
    WHV_X64_PENDING_INTERRUPTION_REGISTER interrupt_in_flight;
    bool interruption_pending;

    /* Must be the last field as it may have a tail */
    WHV_RUN_VP_EXIT_CONTEXT exit_ctx;
@@ -695,7 +695,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
    qemu_mutex_lock_iothread();

    /* Inject NMI */
    if (!vcpu->interrupt_in_flight.InterruptionPending &&
    if (!vcpu->interruption_pending &&
        cpu->interrupt_request & (CPU_INTERRUPT_NMI | CPU_INTERRUPT_SMI)) {
        if (cpu->interrupt_request & CPU_INTERRUPT_NMI) {
            cpu->interrupt_request &= ~CPU_INTERRUPT_NMI;
@@ -724,7 +724,7 @@ static void whpx_vcpu_pre_run(CPUState *cpu)
    }

    /* Get pending hard interruption or replay one that was overwritten */
    if (!vcpu->interrupt_in_flight.InterruptionPending &&
    if (!vcpu->interruption_pending &&
        vcpu->interruptable && (env->eflags & IF_MASK)) {
        assert(!new_int.InterruptionPending);
        if (cpu->interrupt_request & CPU_INTERRUPT_HARD) {
@@ -781,44 +781,25 @@ static void whpx_vcpu_pre_run(CPUState *cpu)

static void whpx_vcpu_post_run(CPUState *cpu)
{
    HRESULT hr;
    struct whpx_state *whpx = &whpx_global;
    struct whpx_vcpu *vcpu = get_whpx_vcpu(cpu);
    struct CPUX86State *env = (CPUArchState *)(cpu->env_ptr);
    X86CPU *x86_cpu = X86_CPU(cpu);
    WHV_REGISTER_VALUE reg_values[4];
    const WHV_REGISTER_NAME reg_names[4] = {
        WHvX64RegisterRflags,
        WHvX64RegisterCr8,
        WHvRegisterPendingInterruption,
        WHvRegisterInterruptState,
    };

    hr = WHvGetVirtualProcessorRegisters(whpx->partition, cpu->cpu_index,
                                         reg_names, 4, reg_values);
    if (FAILED(hr)) {
        error_report("WHPX: Failed to get interrupt state regusters,"
                     " hr=%08lx", hr);
        vcpu->interruptable = false;
        return;
    }

    assert(reg_names[0] == WHvX64RegisterRflags);
    env->eflags = reg_values[0].Reg64;
    env->eflags = vcpu->exit_ctx.VpContext.Rflags;

    assert(reg_names[1] == WHvX64RegisterCr8);
    if (vcpu->tpr != reg_values[1].Reg64) {
        vcpu->tpr = reg_values[1].Reg64;
    uint64_t tpr = vcpu->exit_ctx.VpContext.Cr8;
    if (vcpu->tpr != tpr) {
        vcpu->tpr = tpr;
        qemu_mutex_lock_iothread();
        cpu_set_apic_tpr(x86_cpu->apic_state, vcpu->tpr);
        qemu_mutex_unlock_iothread();
    }

    assert(reg_names[2] == WHvRegisterPendingInterruption);
    vcpu->interrupt_in_flight = reg_values[2].PendingInterruption;
    vcpu->interruption_pending =
        vcpu->exit_ctx.VpContext.ExecutionState.InterruptionPending;

    assert(reg_names[3] == WHvRegisterInterruptState);
    vcpu->interruptable = !reg_values[3].InterruptState.InterruptShadow;
    vcpu->interruptable =
        !vcpu->exit_ctx.VpContext.ExecutionState.InterruptShadow;

    return;
}