diff options
author | Avi Kivity <avi@qumranet.com> | 2008-01-16 05:49:30 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 11:01:22 -0500 |
commit | 2f52d58c92d971bf421f461ad06eb93fb4f34981 (patch) | |
tree | 59e4bf7960686689606be7136f28ebfe32e7fb2d | |
parent | a03d7f4b544f699bbdd3cf14692bd8f476cb9d24 (diff) |
KVM: Move apic timer migration away from critical section
Migrating the apic timer in the critical section is not very nice, and is
absolutely horrible with the real-time port. Move migration to the regular
vcpu execution path, triggered by a new bitflag.
Cc: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Avi Kivity <avi@qumranet.com>
-rw-r--r-- | arch/x86/kvm/irq.h | 2 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 3 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 5 | ||||
-rw-r--r-- | include/linux/kvm_host.h | 6 |
4 files changed, 12 insertions, 4 deletions
diff --git a/arch/x86/kvm/irq.h b/arch/x86/kvm/irq.h index 53c7f48254be..fa5ed5d59b5d 100644 --- a/arch/x86/kvm/irq.h +++ b/arch/x86/kvm/irq.h | |||
@@ -83,6 +83,6 @@ void kvm_pic_reset(struct kvm_kpic_state *s); | |||
83 | void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec); | 83 | void kvm_timer_intr_post(struct kvm_vcpu *vcpu, int vec); |
84 | void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); | 84 | void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu); |
85 | void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); | 85 | void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu); |
86 | void kvm_migrate_apic_timer(struct kvm_vcpu *vcpu); | 86 | void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu); |
87 | 87 | ||
88 | #endif | 88 | #endif |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index e7513bb98af1..2cbee9479ce4 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -1092,7 +1092,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu) | |||
1092 | start_apic_timer(apic); | 1092 | start_apic_timer(apic); |
1093 | } | 1093 | } |
1094 | 1094 | ||
1095 | void kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) | 1095 | void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) |
1096 | { | 1096 | { |
1097 | struct kvm_lapic *apic = vcpu->arch.apic; | 1097 | struct kvm_lapic *apic = vcpu->arch.apic; |
1098 | struct hrtimer *timer; | 1098 | struct hrtimer *timer; |
@@ -1104,7 +1104,6 @@ void kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) | |||
1104 | if (hrtimer_cancel(timer)) | 1104 | if (hrtimer_cancel(timer)) |
1105 | hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS); | 1105 | hrtimer_start(timer, timer->expires, HRTIMER_MODE_ABS); |
1106 | } | 1106 | } |
1107 | EXPORT_SYMBOL_GPL(kvm_migrate_apic_timer); | ||
1108 | 1107 | ||
1109 | void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu) | 1108 | void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu) |
1110 | { | 1109 | { |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index f0493e7dcf0c..8f94a0b89dff 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -2518,13 +2518,16 @@ again: | |||
2518 | if (unlikely(r)) | 2518 | if (unlikely(r)) |
2519 | goto out; | 2519 | goto out; |
2520 | 2520 | ||
2521 | if (vcpu->requests) | 2521 | if (vcpu->requests) { |
2522 | if (test_and_clear_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests)) | ||
2523 | __kvm_migrate_apic_timer(vcpu); | ||
2522 | if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS, | 2524 | if (test_and_clear_bit(KVM_REQ_REPORT_TPR_ACCESS, |
2523 | &vcpu->requests)) { | 2525 | &vcpu->requests)) { |
2524 | kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS; | 2526 | kvm_run->exit_reason = KVM_EXIT_TPR_ACCESS; |
2525 | r = 0; | 2527 | r = 0; |
2526 | goto out; | 2528 | goto out; |
2527 | } | 2529 | } |
2530 | } | ||
2528 | 2531 | ||
2529 | kvm_inject_pending_timer_irqs(vcpu); | 2532 | kvm_inject_pending_timer_irqs(vcpu); |
2530 | 2533 | ||
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h index 2714068ee8bc..ea4764b0a2f4 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h | |||
@@ -35,6 +35,7 @@ | |||
35 | * vcpu->requests bit members | 35 | * vcpu->requests bit members |
36 | */ | 36 | */ |
37 | #define KVM_REQ_TLB_FLUSH 0 | 37 | #define KVM_REQ_TLB_FLUSH 0 |
38 | #define KVM_REQ_MIGRATE_TIMER 1 | ||
38 | #define KVM_REQ_REPORT_TPR_ACCESS 2 | 39 | #define KVM_REQ_REPORT_TPR_ACCESS 2 |
39 | 40 | ||
40 | struct kvm_vcpu; | 41 | struct kvm_vcpu; |
@@ -277,6 +278,11 @@ static inline gpa_t gfn_to_gpa(gfn_t gfn) | |||
277 | return (gpa_t)gfn << PAGE_SHIFT; | 278 | return (gpa_t)gfn << PAGE_SHIFT; |
278 | } | 279 | } |
279 | 280 | ||
281 | static inline void kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) | ||
282 | { | ||
283 | set_bit(KVM_REQ_MIGRATE_TIMER, &vcpu->requests); | ||
284 | } | ||
285 | |||
280 | enum kvm_stat_kind { | 286 | enum kvm_stat_kind { |
281 | KVM_STAT_VM, | 287 | KVM_STAT_VM, |
282 | KVM_STAT_VCPU, | 288 | KVM_STAT_VCPU, |