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: Justin Terry (VM) <juterry@microsoft.com>
Message-Id: <1521039163-138-4-git-send-email-juterry@microsoft.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
Justin Terry (VM) 2018-03-14 07:52:43 -07:00 committed by Paolo Bonzini
parent 60168541da
commit 4e286099fe
1 changed files with 11 additions and 30 deletions

View File

@ -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;
}
env->eflags = vcpu->exit_ctx.VpContext.Rflags;
assert(reg_names[0] == WHvX64RegisterRflags);
env->eflags = reg_values[0].Reg64;
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;
}