lapic.c (b4eef9b36db461ca44832226fbca614db58c0c33) lapic.c (d0659d946be05e098883b6955d2764595997f6a4)
1
2/*
3 * Local APIC virtualization
4 *
5 * Copyright (C) 2006 Qumranet, Inc.
6 * Copyright (C) 2007 Novell
7 * Copyright (C) 2007 Intel
8 * Copyright 2009 Red Hat, Inc. and/or its affiliates.

--- 19 unchanged lines hidden (view full) ---

28#include <linux/module.h>
29#include <linux/math64.h>
30#include <linux/slab.h>
31#include <asm/processor.h>
32#include <asm/msr.h>
33#include <asm/page.h>
34#include <asm/current.h>
35#include <asm/apicdef.h>
1
2/*
3 * Local APIC virtualization
4 *
5 * Copyright (C) 2006 Qumranet, Inc.
6 * Copyright (C) 2007 Novell
7 * Copyright (C) 2007 Intel
8 * Copyright 2009 Red Hat, Inc. and/or its affiliates.

--- 19 unchanged lines hidden (view full) ---

28#include <linux/module.h>
29#include <linux/math64.h>
30#include <linux/slab.h>
31#include <asm/processor.h>
32#include <asm/msr.h>
33#include <asm/page.h>
34#include <asm/current.h>
35#include <asm/apicdef.h>
36#include <asm/delay.h>
36#include <linux/atomic.h>
37#include <linux/jump_label.h>
38#include "kvm_cache_regs.h"
39#include "irq.h"
40#include "trace.h"
41#include "x86.h"
42#include "cpuid.h"
43

--- 1024 unchanged lines hidden (view full) ---

1068 apic_debug("timer divide count is 0x%x\n",
1069 apic->divide_count);
1070}
1071
1072static void apic_timer_expired(struct kvm_lapic *apic)
1073{
1074 struct kvm_vcpu *vcpu = apic->vcpu;
1075 wait_queue_head_t *q = &vcpu->wq;
37#include <linux/atomic.h>
38#include <linux/jump_label.h>
39#include "kvm_cache_regs.h"
40#include "irq.h"
41#include "trace.h"
42#include "x86.h"
43#include "cpuid.h"
44

--- 1024 unchanged lines hidden (view full) ---

1069 apic_debug("timer divide count is 0x%x\n",
1070 apic->divide_count);
1071}
1072
1073static void apic_timer_expired(struct kvm_lapic *apic)
1074{
1075 struct kvm_vcpu *vcpu = apic->vcpu;
1076 wait_queue_head_t *q = &vcpu->wq;
1077 struct kvm_timer *ktimer = &apic->lapic_timer;
1076
1077 /*
1078 * Note: KVM_REQ_PENDING_TIMER is implicitly checked in
1079 * vcpu_enter_guest.
1080 */
1081 if (atomic_read(&apic->lapic_timer.pending))
1082 return;
1083
1084 atomic_inc(&apic->lapic_timer.pending);
1085 /* FIXME: this code should not know anything about vcpus */
1086 kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
1087
1088 if (waitqueue_active(q))
1089 wake_up_interruptible(q);
1078
1079 /*
1080 * Note: KVM_REQ_PENDING_TIMER is implicitly checked in
1081 * vcpu_enter_guest.
1082 */
1083 if (atomic_read(&apic->lapic_timer.pending))
1084 return;
1085
1086 atomic_inc(&apic->lapic_timer.pending);
1087 /* FIXME: this code should not know anything about vcpus */
1088 kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu);
1089
1090 if (waitqueue_active(q))
1091 wake_up_interruptible(q);
1092
1093 if (apic_lvtt_tscdeadline(apic))
1094 ktimer->expired_tscdeadline = ktimer->tscdeadline;
1090}
1091
1095}
1096
1097/*
1098 * On APICv, this test will cause a busy wait
1099 * during a higher-priority task.
1100 */
1101
1102static bool lapic_timer_int_injected(struct kvm_vcpu *vcpu)
1103{
1104 struct kvm_lapic *apic = vcpu->arch.apic;
1105 u32 reg = kvm_apic_get_reg(apic, APIC_LVTT);
1106
1107 if (kvm_apic_hw_enabled(apic)) {
1108 int vec = reg & APIC_VECTOR_MASK;
1109
1110 if (kvm_x86_ops->test_posted_interrupt)
1111 return kvm_x86_ops->test_posted_interrupt(vcpu, vec);
1112 else {
1113 if (apic_test_vector(vec, apic->regs + APIC_ISR))
1114 return true;
1115 }
1116 }
1117 return false;
1118}
1119
1120void wait_lapic_expire(struct kvm_vcpu *vcpu)
1121{
1122 struct kvm_lapic *apic = vcpu->arch.apic;
1123 u64 guest_tsc, tsc_deadline;
1124
1125 if (!kvm_vcpu_has_lapic(vcpu))
1126 return;
1127
1128 if (apic->lapic_timer.expired_tscdeadline == 0)
1129 return;
1130
1131 if (!lapic_timer_int_injected(vcpu))
1132 return;
1133
1134 tsc_deadline = apic->lapic_timer.expired_tscdeadline;
1135 apic->lapic_timer.expired_tscdeadline = 0;
1136 guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu, native_read_tsc());
1137
1138 /* __delay is delay_tsc whenever the hardware has TSC, thus always. */
1139 if (guest_tsc < tsc_deadline)
1140 __delay(tsc_deadline - guest_tsc);
1141}
1142
1092static void start_apic_timer(struct kvm_lapic *apic)
1093{
1094 ktime_t now;
1143static void start_apic_timer(struct kvm_lapic *apic)
1144{
1145 ktime_t now;
1146
1095 atomic_set(&apic->lapic_timer.pending, 0);
1096
1097 if (apic_lvtt_period(apic) || apic_lvtt_oneshot(apic)) {
1098 /* lapic timer in oneshot or periodic mode */
1099 now = apic->lapic_timer.timer.base->get_time();
1100 apic->lapic_timer.period = (u64)kvm_apic_get_reg(apic, APIC_TMICT)
1101 * APIC_BUS_CYCLE_NS * apic->divide_count;
1102

--- 29 unchanged lines hidden (view full) ---

1132 kvm_apic_get_reg(apic, APIC_TMICT),
1133 apic->lapic_timer.period,
1134 ktime_to_ns(ktime_add_ns(now,
1135 apic->lapic_timer.period)));
1136 } else if (apic_lvtt_tscdeadline(apic)) {
1137 /* lapic timer in tsc deadline mode */
1138 u64 guest_tsc, tscdeadline = apic->lapic_timer.tscdeadline;
1139 u64 ns = 0;
1147 atomic_set(&apic->lapic_timer.pending, 0);
1148
1149 if (apic_lvtt_period(apic) || apic_lvtt_oneshot(apic)) {
1150 /* lapic timer in oneshot or periodic mode */
1151 now = apic->lapic_timer.timer.base->get_time();
1152 apic->lapic_timer.period = (u64)kvm_apic_get_reg(apic, APIC_TMICT)
1153 * APIC_BUS_CYCLE_NS * apic->divide_count;
1154

--- 29 unchanged lines hidden (view full) ---

1184 kvm_apic_get_reg(apic, APIC_TMICT),
1185 apic->lapic_timer.period,
1186 ktime_to_ns(ktime_add_ns(now,
1187 apic->lapic_timer.period)));
1188 } else if (apic_lvtt_tscdeadline(apic)) {
1189 /* lapic timer in tsc deadline mode */
1190 u64 guest_tsc, tscdeadline = apic->lapic_timer.tscdeadline;
1191 u64 ns = 0;
1192 ktime_t expire;
1140 struct kvm_vcpu *vcpu = apic->vcpu;
1141 unsigned long this_tsc_khz = vcpu->arch.virtual_tsc_khz;
1142 unsigned long flags;
1143
1144 if (unlikely(!tscdeadline || !this_tsc_khz))
1145 return;
1146
1147 local_irq_save(flags);
1148
1149 now = apic->lapic_timer.timer.base->get_time();
1150 guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu, native_read_tsc());
1151 if (likely(tscdeadline > guest_tsc)) {
1152 ns = (tscdeadline - guest_tsc) * 1000000ULL;
1153 do_div(ns, this_tsc_khz);
1193 struct kvm_vcpu *vcpu = apic->vcpu;
1194 unsigned long this_tsc_khz = vcpu->arch.virtual_tsc_khz;
1195 unsigned long flags;
1196
1197 if (unlikely(!tscdeadline || !this_tsc_khz))
1198 return;
1199
1200 local_irq_save(flags);
1201
1202 now = apic->lapic_timer.timer.base->get_time();
1203 guest_tsc = kvm_x86_ops->read_l1_tsc(vcpu, native_read_tsc());
1204 if (likely(tscdeadline > guest_tsc)) {
1205 ns = (tscdeadline - guest_tsc) * 1000000ULL;
1206 do_div(ns, this_tsc_khz);
1207 expire = ktime_add_ns(now, ns);
1208 expire = ktime_sub_ns(expire, lapic_timer_advance_ns);
1154 hrtimer_start(&apic->lapic_timer.timer,
1209 hrtimer_start(&apic->lapic_timer.timer,
1155 ktime_add_ns(now, ns), HRTIMER_MODE_ABS);
1210 expire, HRTIMER_MODE_ABS);
1156 } else
1157 apic_timer_expired(apic);
1158
1159 local_irq_restore(flags);
1160 }
1161}
1162
1163static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)

--- 841 unchanged lines hidden ---
1211 } else
1212 apic_timer_expired(apic);
1213
1214 local_irq_restore(flags);
1215 }
1216}
1217
1218static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val)

--- 841 unchanged lines hidden ---