diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2009-02-23 08:57:41 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2009-06-10 04:48:25 -0400 |
commit | d3c7b77d1a6e7a0a27035a7ba723a3455317883e (patch) | |
tree | 65053ca8122dda5772c48ce70c9d99e8127f8cdd /arch/x86/kvm/i8254.c | |
parent | fd66842370e32f3bbe429677280a326c07e508c1 (diff) |
KVM: unify part of generic timer handling
Hide the internals of vcpu awakening / injection from the in-kernel
emulated timers. This makes future changes in this logic easier and
decreases the distance to more generic timer handling.
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@redhat.com>
Diffstat (limited to 'arch/x86/kvm/i8254.c')
-rw-r--r-- | arch/x86/kvm/i8254.c | 57 |
1 files changed, 20 insertions, 37 deletions
diff --git a/arch/x86/kvm/i8254.c b/arch/x86/kvm/i8254.c index 09ae841ff462..4e2e3f26dbf8 100644 --- a/arch/x86/kvm/i8254.c +++ b/arch/x86/kvm/i8254.c | |||
@@ -219,25 +219,6 @@ static void pit_latch_status(struct kvm *kvm, int channel) | |||
219 | } | 219 | } |
220 | } | 220 | } |
221 | 221 | ||
222 | static int __pit_timer_fn(struct kvm_kpit_state *ps) | ||
223 | { | ||
224 | struct kvm_vcpu *vcpu0 = ps->pit->kvm->vcpus[0]; | ||
225 | struct kvm_kpit_timer *pt = &ps->pit_timer; | ||
226 | |||
227 | if (!atomic_inc_and_test(&pt->pending)) | ||
228 | set_bit(KVM_REQ_PENDING_TIMER, &vcpu0->requests); | ||
229 | |||
230 | if (!pt->reinject) | ||
231 | atomic_set(&pt->pending, 1); | ||
232 | |||
233 | if (vcpu0 && waitqueue_active(&vcpu0->wq)) | ||
234 | wake_up_interruptible(&vcpu0->wq); | ||
235 | |||
236 | hrtimer_add_expires_ns(&pt->timer, pt->period); | ||
237 | |||
238 | return (pt->period == 0 ? 0 : 1); | ||
239 | } | ||
240 | |||
241 | int pit_has_pending_timer(struct kvm_vcpu *vcpu) | 222 | int pit_has_pending_timer(struct kvm_vcpu *vcpu) |
242 | { | 223 | { |
243 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; | 224 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; |
@@ -258,21 +239,6 @@ static void kvm_pit_ack_irq(struct kvm_irq_ack_notifier *kian) | |||
258 | spin_unlock(&ps->inject_lock); | 239 | spin_unlock(&ps->inject_lock); |
259 | } | 240 | } |
260 | 241 | ||
261 | static enum hrtimer_restart pit_timer_fn(struct hrtimer *data) | ||
262 | { | ||
263 | struct kvm_kpit_state *ps; | ||
264 | int restart_timer = 0; | ||
265 | |||
266 | ps = container_of(data, struct kvm_kpit_state, pit_timer.timer); | ||
267 | |||
268 | restart_timer = __pit_timer_fn(ps); | ||
269 | |||
270 | if (restart_timer) | ||
271 | return HRTIMER_RESTART; | ||
272 | else | ||
273 | return HRTIMER_NORESTART; | ||
274 | } | ||
275 | |||
276 | void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) | 242 | void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) |
277 | { | 243 | { |
278 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; | 244 | struct kvm_pit *pit = vcpu->kvm->arch.vpit; |
@@ -286,15 +252,26 @@ void __kvm_migrate_pit_timer(struct kvm_vcpu *vcpu) | |||
286 | hrtimer_start_expires(timer, HRTIMER_MODE_ABS); | 252 | hrtimer_start_expires(timer, HRTIMER_MODE_ABS); |
287 | } | 253 | } |
288 | 254 | ||
289 | static void destroy_pit_timer(struct kvm_kpit_timer *pt) | 255 | static void destroy_pit_timer(struct kvm_timer *pt) |
290 | { | 256 | { |
291 | pr_debug("pit: execute del timer!\n"); | 257 | pr_debug("pit: execute del timer!\n"); |
292 | hrtimer_cancel(&pt->timer); | 258 | hrtimer_cancel(&pt->timer); |
293 | } | 259 | } |
294 | 260 | ||
261 | static bool kpit_is_periodic(struct kvm_timer *ktimer) | ||
262 | { | ||
263 | struct kvm_kpit_state *ps = container_of(ktimer, struct kvm_kpit_state, | ||
264 | pit_timer); | ||
265 | return ps->is_periodic; | ||
266 | } | ||
267 | |||
268 | struct kvm_timer_ops kpit_ops = { | ||
269 | .is_periodic = kpit_is_periodic, | ||
270 | }; | ||
271 | |||
295 | static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) | 272 | static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) |
296 | { | 273 | { |
297 | struct kvm_kpit_timer *pt = &ps->pit_timer; | 274 | struct kvm_timer *pt = &ps->pit_timer; |
298 | s64 interval; | 275 | s64 interval; |
299 | 276 | ||
300 | interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ); | 277 | interval = muldiv64(val, NSEC_PER_SEC, KVM_PIT_FREQ); |
@@ -304,7 +281,13 @@ static void create_pit_timer(struct kvm_kpit_state *ps, u32 val, int is_period) | |||
304 | /* TODO The new value only affected after the retriggered */ | 281 | /* TODO The new value only affected after the retriggered */ |
305 | hrtimer_cancel(&pt->timer); | 282 | hrtimer_cancel(&pt->timer); |
306 | pt->period = (is_period == 0) ? 0 : interval; | 283 | pt->period = (is_period == 0) ? 0 : interval; |
307 | pt->timer.function = pit_timer_fn; | 284 | ps->is_periodic = is_period; |
285 | |||
286 | pt->timer.function = kvm_timer_fn; | ||
287 | pt->t_ops = &kpit_ops; | ||
288 | pt->kvm = ps->pit->kvm; | ||
289 | pt->vcpu_id = 0; | ||
290 | |||
308 | atomic_set(&pt->pending, 0); | 291 | atomic_set(&pt->pending, 0); |
309 | ps->irq_ack = 1; | 292 | ps->irq_ack = 1; |
310 | 293 | ||