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 --- |