Skip to content

Commit 93dff2f

Browse files
jsmattsonjrbonzini
authored andcommitted
KVM: nVMX: Migrate the VMX-preemption timer
The hrtimer used to emulate the VMX-preemption timer must be pinned to the same logical processor as the vCPU thread to be interrupted if we want to have any hope of adhering to the architectural specification of the VMX-preemption timer. Even with this change, the emulated VMX-preemption timer VM-exit occasionally arrives too late. Signed-off-by: Jim Mattson <[email protected]> Reviewed-by: Peter Shier <[email protected]> Reviewed-by: Oliver Upton <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent ada0098 commit 93dff2f

File tree

3 files changed

+15
-0
lines changed

3 files changed

+15
-0
lines changed

arch/x86/include/asm/kvm_host.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1247,6 +1247,8 @@ struct kvm_x86_ops {
12471247

12481248
bool (*apic_init_signal_blocked)(struct kvm_vcpu *vcpu);
12491249
int (*enable_direct_tlbflush)(struct kvm_vcpu *vcpu);
1250+
1251+
void (*migrate_timers)(struct kvm_vcpu *vcpu);
12501252
};
12511253

12521254
struct kvm_x86_nested_ops {

arch/x86/kvm/irq.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,8 @@ void __kvm_migrate_timers(struct kvm_vcpu *vcpu)
159159
{
160160
__kvm_migrate_apic_timer(vcpu);
161161
__kvm_migrate_pit_timer(vcpu);
162+
if (kvm_x86_ops.migrate_timers)
163+
kvm_x86_ops.migrate_timers(vcpu);
162164
}
163165

164166
bool kvm_arch_irqfd_allowed(struct kvm *kvm, struct kvm_irqfd *args)

arch/x86/kvm/vmx/vmx.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7814,6 +7814,16 @@ static bool vmx_apic_init_signal_blocked(struct kvm_vcpu *vcpu)
78147814
return to_vmx(vcpu)->nested.vmxon;
78157815
}
78167816

7817+
static void vmx_migrate_timers(struct kvm_vcpu *vcpu)
7818+
{
7819+
if (is_guest_mode(vcpu)) {
7820+
struct hrtimer *timer = &to_vmx(vcpu)->nested.preemption_timer;
7821+
7822+
if (hrtimer_try_to_cancel(timer) == 1)
7823+
hrtimer_start_expires(timer, HRTIMER_MODE_ABS_PINNED);
7824+
}
7825+
}
7826+
78177827
static void hardware_unsetup(void)
78187828
{
78197829
if (nested)
@@ -7957,6 +7967,7 @@ static struct kvm_x86_ops vmx_x86_ops __initdata = {
79577967

79587968
.need_emulation_on_page_fault = vmx_need_emulation_on_page_fault,
79597969
.apic_init_signal_blocked = vmx_apic_init_signal_blocked,
7970+
.migrate_timers = vmx_migrate_timers,
79607971
};
79617972

79627973
static __init int hardware_setup(void)

0 commit comments

Comments
 (0)