aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/lapic.c
diff options
context:
space:
mode:
authorEddie Dong <eddie.dong@intel.com>2007-09-12 03:58:04 -0400
committerAvi Kivity <avi@qumranet.com>2007-10-13 04:18:25 -0400
commit97222cc8316328965851ed28d23f6b64b4c912d2 (patch)
tree469b2f72e74046a7aec5061df194c3f68812a224 /drivers/kvm/lapic.c
parent7017fc3d1a12e30ea7df4992152978a188433457 (diff)
KVM: Emulate local APIC in kernel
Because lightweight exits (exits which don't involve userspace) are many times faster than heavyweight exits, it makes sense to emulate high usage devices in the kernel. The local APIC is one such device, especially for Windows and for SMP, so we add an APIC model to kvm. It also allows in-kernel host-side drivers to inject interrupts without going through userspace. [compile fix on i386 from Jindrich Makovicka] Signed-off-by: Yaozu (Eddie) Dong <Eddie.Dong@intel.com> Signed-off-by: Qing He <qing.he@intel.com> Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'drivers/kvm/lapic.c')
-rw-r--r--drivers/kvm/lapic.c933
1 files changed, 933 insertions, 0 deletions
diff --git a/drivers/kvm/lapic.c b/drivers/kvm/lapic.c
new file mode 100644
index 000000000000..4b5c77d8900d
--- /dev/null
+++ b/drivers/kvm/lapic.c
@@ -0,0 +1,933 @@
1
2/*
3 * Local APIC virtualization
4 *
5 * Copyright (C) 2006 Qumranet, Inc.
6 * Copyright (C) 2007 Novell
7 * Copyright (C) 2007 Intel
8 *
9 * Authors:
10 * Dor Laor <dor.laor@qumranet.com>
11 * Gregory Haskins <ghaskins@novell.com>
12 * Yaozu (Eddie) Dong <eddie.dong@intel.com>
13 *
14 * Based on Xen 3.1 code, Copyright (c) 2004, Intel Corporation.
15 *
16 * This work is licensed under the terms of the GNU GPL, version 2. See
17 * the COPYING file in the top-level directory.
18 */
19
20#include "kvm.h"
21#include <linux/kvm.h>
22#include <linux/mm.h>
23#include <linux/highmem.h>
24#include <linux/smp.h>
25#include <linux/hrtimer.h>
26#include <linux/io.h>
27#include <linux/module.h>
28#include <asm/processor.h>
29#include <asm/msr.h>
30#include <asm/page.h>
31#include <asm/current.h>
32#include <asm/apicdef.h>
33#include <asm/atomic.h>
34#include <asm/div64.h>
35#include "irq.h"
36
37#define PRId64 "d"
38#define PRIx64 "llx"
39#define PRIu64 "u"
40#define PRIo64 "o"
41
42#define APIC_BUS_CYCLE_NS 1
43
44/* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */
45#define apic_debug(fmt, arg...)
46
47#define APIC_LVT_NUM 6
48/* 14 is the version for Xeon and Pentium 8.4.8*/
49#define APIC_VERSION (0x14UL | ((APIC_LVT_NUM - 1) << 16))
50#define LAPIC_MMIO_LENGTH (1 << 12)
51/* followed define is not in apicdef.h */
52#define APIC_SHORT_MASK 0xc0000
53#define APIC_DEST_NOSHORT 0x0
54#define APIC_DEST_MASK 0x800
55#define MAX_APIC_VECTOR 256
56
57#define VEC_POS(v) ((v) & (32 - 1))
58#define REG_POS(v) (((v) >> 5) << 4)
59static inline u32 apic_get_reg(struct kvm_lapic *apic, int reg_off)
60{
61 return *((u32 *) (apic->regs + reg_off));
62}
63
64static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val)
65{
66 *((u32 *) (apic->regs + reg_off)) = val;
67}
68
69static inline int apic_test_and_set_vector(int vec, void *bitmap)
70{
71 return test_and_set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
72}
73
74static inline int apic_test_and_clear_vector(int vec, void *bitmap)
75{
76 return test_and_clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
77}
78
79static inline void apic_set_vector(int vec, void *bitmap)
80{
81 set_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
82}
83
84static inline void apic_clear_vector(int vec, void *bitmap)
85{
86 clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec));
87}
88
89static inline int apic_hw_enabled(struct kvm_lapic *apic)
90{
91 return (apic)->vcpu->apic_base & MSR_IA32_APICBASE_ENABLE;
92}
93
94static inline int apic_sw_enabled(struct kvm_lapic *apic)
95{
96 return apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED;
97}
98
99static inline int apic_enabled(struct kvm_lapic *apic)
100{
101 return apic_sw_enabled(apic) && apic_hw_enabled(apic);
102}
103
104#define LVT_MASK \
105 (APIC_LVT_MASKED | APIC_SEND_PENDING | APIC_VECTOR_MASK)
106
107#define LINT_MASK \
108 (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \
109 APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER)
110
111static inline int kvm_apic_id(struct kvm_lapic *apic)
112{
113 return (apic_get_reg(apic, APIC_ID) >> 24) & 0xff;
114}
115
116static inline int apic_lvt_enabled(struct kvm_lapic *apic, int lvt_type)
117{
118 return !(apic_get_reg(apic, lvt_type) & APIC_LVT_MASKED);
119}
120
121static inline int apic_lvt_vector(struct kvm_lapic *apic, int lvt_type)
122{
123 return apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK;
124}
125
126static inline int apic_lvtt_period(struct kvm_lapic *apic)
127{
128 return apic_get_reg(apic, APIC_LVTT) & APIC_LVT_TIMER_PERIODIC;
129}
130
131static unsigned int apic_lvt_mask[APIC_LVT_NUM] = {
132 LVT_MASK | APIC_LVT_TIMER_PERIODIC, /* LVTT */
133 LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */
134 LVT_MASK | APIC_MODE_MASK, /* LVTPC */
135 LINT_MASK, LINT_MASK, /* LVT0-1 */
136 LVT_MASK /* LVTERR */
137};
138
139static int find_highest_vector(void *bitmap)
140{
141 u32 *word = bitmap;
142 int word_offset = MAX_APIC_VECTOR >> 5;
143
144 while ((word_offset != 0) && (word[(--word_offset) << 2] == 0))
145 continue;
146
147 if (likely(!word_offset && !word[0]))
148 return -1;
149 else
150 return fls(word[word_offset << 2]) - 1 + (word_offset << 5);
151}
152
153static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic)
154{
155 return apic_test_and_set_vector(vec, apic->regs + APIC_IRR);
156}
157
158static inline void apic_clear_irr(int vec, struct kvm_lapic *apic)
159{
160 apic_clear_vector(vec, apic->regs + APIC_IRR);
161}
162
163static inline int apic_find_highest_irr(struct kvm_lapic *apic)
164{
165 int result;
166
167 result = find_highest_vector(apic->regs + APIC_IRR);
168 ASSERT(result == -1 || result >= 16);
169
170 return result;
171}
172
173int kvm_apic_set_irq(struct kvm_lapic *apic, u8 vec, u8 trig)
174{
175 if (!apic_test_and_set_irr(vec, apic)) {
176 /* a new pending irq is set in IRR */
177 if (trig)
178 apic_set_vector(vec, apic->regs + APIC_TMR);
179 else
180 apic_clear_vector(vec, apic->regs + APIC_TMR);
181 kvm_vcpu_kick(apic->vcpu);
182 return 1;
183 }
184 return 0;
185}
186
187static inline int apic_find_highest_isr(struct kvm_lapic *apic)
188{
189 int result;
190
191 result = find_highest_vector(apic->regs + APIC_ISR);
192 ASSERT(result == -1 || result >= 16);
193
194 return result;
195}
196
197static void apic_update_ppr(struct kvm_lapic *apic)
198{
199 u32 tpr, isrv, ppr;
200 int isr;
201
202 tpr = apic_get_reg(apic, APIC_TASKPRI);
203 isr = apic_find_highest_isr(apic);
204 isrv = (isr != -1) ? isr : 0;
205
206 if ((tpr & 0xf0) >= (isrv & 0xf0))
207 ppr = tpr & 0xff;
208 else
209 ppr = isrv & 0xf0;
210
211 apic_debug("vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x",
212 apic, ppr, isr, isrv);
213
214 apic_set_reg(apic, APIC_PROCPRI, ppr);
215}
216
217static void apic_set_tpr(struct kvm_lapic *apic, u32 tpr)
218{
219 apic_set_reg(apic, APIC_TASKPRI, tpr);
220 apic_update_ppr(apic);
221}
222
223int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest)
224{
225 return kvm_apic_id(apic) == dest;
226}
227
228int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda)
229{
230 int result = 0;
231 u8 logical_id;
232
233 logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR));
234
235 switch (apic_get_reg(apic, APIC_DFR)) {
236 case APIC_DFR_FLAT:
237 if (logical_id & mda)
238 result = 1;
239 break;
240 case APIC_DFR_CLUSTER:
241 if (((logical_id >> 4) == (mda >> 0x4))
242 && (logical_id & mda & 0xf))
243 result = 1;
244 break;
245 default:
246 printk(KERN_WARNING "Bad DFR vcpu %d: %08x\n",
247 apic->vcpu->vcpu_id, apic_get_reg(apic, APIC_DFR));
248 break;
249 }
250
251 return result;
252}
253
254static int apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source,
255 int short_hand, int dest, int dest_mode)
256{
257 int result = 0;
258 struct kvm_lapic *target = vcpu->apic;
259
260 apic_debug("target %p, source %p, dest 0x%x, "
261 "dest_mode 0x%x, short_hand 0x%x",
262 target, source, dest, dest_mode, short_hand);
263
264 ASSERT(!target);
265 switch (short_hand) {
266 case APIC_DEST_NOSHORT:
267 if (dest_mode == 0) {
268 /* Physical mode. */
269 if ((dest == 0xFF) || (dest == kvm_apic_id(target)))
270 result = 1;
271 } else
272 /* Logical mode. */
273 result = kvm_apic_match_logical_addr(target, dest);
274 break;
275 case APIC_DEST_SELF:
276 if (target == source)
277 result = 1;
278 break;
279 case APIC_DEST_ALLINC:
280 result = 1;
281 break;
282 case APIC_DEST_ALLBUT:
283 if (target != source)
284 result = 1;
285 break;
286 default:
287 printk(KERN_WARNING "Bad dest shorthand value %x\n",
288 short_hand);
289 break;
290 }
291
292 return result;
293}
294
295/*
296 * Add a pending IRQ into lapic.
297 * Return 1 if successfully added and 0 if discarded.
298 */
299static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode,
300 int vector, int level, int trig_mode)
301{
302 int result = 0;
303
304 switch (delivery_mode) {
305 case APIC_DM_FIXED:
306 case APIC_DM_LOWEST:
307 /* FIXME add logic for vcpu on reset */
308 if (unlikely(!apic_enabled(apic)))
309 break;
310
311 if (apic_test_and_set_irr(vector, apic) && trig_mode) {
312 apic_debug("level trig mode repeatedly for vector %d",
313 vector);
314 break;
315 }
316
317 if (trig_mode) {
318 apic_debug("level trig mode for vector %d", vector);
319 apic_set_vector(vector, apic->regs + APIC_TMR);
320 } else
321 apic_clear_vector(vector, apic->regs + APIC_TMR);
322
323 kvm_vcpu_kick(apic->vcpu);
324
325 result = 1;
326 break;
327
328 case APIC_DM_REMRD:
329 printk(KERN_DEBUG "Ignoring delivery mode 3\n");
330 break;
331
332 case APIC_DM_SMI:
333 printk(KERN_DEBUG "Ignoring guest SMI\n");
334 break;
335 case APIC_DM_NMI:
336 printk(KERN_DEBUG "Ignoring guest NMI\n");
337 break;
338
339 case APIC_DM_INIT:
340 printk(KERN_DEBUG "Ignoring guest INIT\n");
341 break;
342
343 case APIC_DM_STARTUP:
344 printk(KERN_DEBUG "Ignoring guest STARTUP\n");
345 break;
346
347 default:
348 printk(KERN_ERR "TODO: unsupported delivery mode %x\n",
349 delivery_mode);
350 break;
351 }
352 return result;
353}
354
355struct kvm_lapic *kvm_apic_round_robin(struct kvm *kvm, u8 vector,
356 unsigned long bitmap)
357{
358 int vcpu_id;
359
360 /* TODO for real round robin */
361 vcpu_id = fls(bitmap) - 1;
362 if (vcpu_id < 0)
363 printk(KERN_DEBUG "vcpu not ready for apic_round_robin\n");
364 return kvm->vcpus[vcpu_id]->apic;
365}
366
367static void apic_set_eoi(struct kvm_lapic *apic)
368{
369 int vector = apic_find_highest_isr(apic);
370
371 /*
372 * Not every write EOI will has corresponding ISR,
373 * one example is when Kernel check timer on setup_IO_APIC
374 */
375 if (vector == -1)
376 return;
377
378 apic_clear_vector(vector, apic->regs + APIC_ISR);
379 apic_update_ppr(apic);
380
381 if (apic_test_and_clear_vector(vector, apic->regs + APIC_TMR))
382 kvm_ioapic_update_eoi(apic->vcpu->kvm, vector);
383}
384
385static void apic_send_ipi(struct kvm_lapic *apic)
386{
387 u32 icr_low = apic_get_reg(apic, APIC_ICR);
388 u32 icr_high = apic_get_reg(apic, APIC_ICR2);
389
390 unsigned int dest = GET_APIC_DEST_FIELD(icr_high);
391 unsigned int short_hand = icr_low & APIC_SHORT_MASK;
392 unsigned int trig_mode = icr_low & APIC_INT_LEVELTRIG;
393 unsigned int level = icr_low & APIC_INT_ASSERT;
394 unsigned int dest_mode = icr_low & APIC_DEST_MASK;
395 unsigned int delivery_mode = icr_low & APIC_MODE_MASK;
396 unsigned int vector = icr_low & APIC_VECTOR_MASK;
397
398 struct kvm_lapic *target;
399 struct kvm_vcpu *vcpu;
400 unsigned long lpr_map = 0;
401 int i;
402
403 apic_debug("icr_high 0x%x, icr_low 0x%x, "
404 "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, "
405 "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x\n",
406 icr_high, icr_low, short_hand, dest,
407 trig_mode, level, dest_mode, delivery_mode, vector);
408
409 for (i = 0; i < KVM_MAX_VCPUS; i++) {
410 vcpu = apic->vcpu->kvm->vcpus[i];
411 if (!vcpu)
412 continue;
413
414 if (vcpu->apic &&
415 apic_match_dest(vcpu, apic, short_hand, dest, dest_mode)) {
416 if (delivery_mode == APIC_DM_LOWEST)
417 set_bit(vcpu->vcpu_id, &lpr_map);
418 else
419 __apic_accept_irq(vcpu->apic, delivery_mode,
420 vector, level, trig_mode);
421 }
422 }
423
424 if (delivery_mode == APIC_DM_LOWEST) {
425 target = kvm_apic_round_robin(vcpu->kvm, vector, lpr_map);
426 if (target != NULL)
427 __apic_accept_irq(target, delivery_mode,
428 vector, level, trig_mode);
429 }
430}
431
432static u32 apic_get_tmcct(struct kvm_lapic *apic)
433{
434 u32 counter_passed;
435 ktime_t passed, now = apic->timer.dev.base->get_time();
436 u32 tmcct = apic_get_reg(apic, APIC_TMICT);
437
438 ASSERT(apic != NULL);
439
440 if (unlikely(ktime_to_ns(now) <=
441 ktime_to_ns(apic->timer.last_update))) {
442 /* Wrap around */
443 passed = ktime_add(( {
444 (ktime_t) {
445 .tv64 = KTIME_MAX -
446 (apic->timer.last_update).tv64}; }
447 ), now);
448 apic_debug("time elapsed\n");
449 } else
450 passed = ktime_sub(now, apic->timer.last_update);
451
452 counter_passed = div64_64(ktime_to_ns(passed),
453 (APIC_BUS_CYCLE_NS * apic->timer.divide_count));
454 tmcct -= counter_passed;
455
456 if (tmcct <= 0) {
457 if (unlikely(!apic_lvtt_period(apic)))
458 tmcct = 0;
459 else
460 do {
461 tmcct += apic_get_reg(apic, APIC_TMICT);
462 } while (tmcct <= 0);
463 }
464
465 return tmcct;
466}
467
468static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset)
469{
470 u32 val = 0;
471
472 if (offset >= LAPIC_MMIO_LENGTH)
473 return 0;
474
475 switch (offset) {
476 case APIC_ARBPRI:
477 printk(KERN_WARNING "Access APIC ARBPRI register "
478 "which is for P6\n");
479 break;
480
481 case APIC_TMCCT: /* Timer CCR */
482 val = apic_get_tmcct(apic);
483 break;
484
485 default:
486 val = apic_get_reg(apic, offset);
487 break;
488 }
489
490 return val;
491}
492
493static void apic_mmio_read(struct kvm_io_device *this,
494 gpa_t address, int len, void *data)
495{
496 struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
497 unsigned int offset = address - apic->base_address;
498 unsigned char alignment = offset & 0xf;
499 u32 result;
500
501 if ((alignment + len) > 4) {
502 printk(KERN_ERR "KVM_APIC_READ: alignment error %lx %d",
503 (unsigned long)address, len);
504 return;
505 }
506 result = __apic_read(apic, offset & ~0xf);
507
508 switch (len) {
509 case 1:
510 case 2:
511 case 4:
512 memcpy(data, (char *)&result + alignment, len);
513 break;
514 default:
515 printk(KERN_ERR "Local APIC read with len = %x, "
516 "should be 1,2, or 4 instead\n", len);
517 break;
518 }
519}
520
521static void update_divide_count(struct kvm_lapic *apic)
522{
523 u32 tmp1, tmp2, tdcr;
524
525 tdcr = apic_get_reg(apic, APIC_TDCR);
526 tmp1 = tdcr & 0xf;
527 tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1;
528 apic->timer.divide_count = 0x1 << (tmp2 & 0x7);
529
530 apic_debug("timer divide count is 0x%x\n",
531 apic->timer.divide_count);
532}
533
534static void start_apic_timer(struct kvm_lapic *apic)
535{
536 ktime_t now = apic->timer.dev.base->get_time();
537
538 apic->timer.last_update = now;
539
540 apic->timer.period = apic_get_reg(apic, APIC_TMICT) *
541 APIC_BUS_CYCLE_NS * apic->timer.divide_count;
542 atomic_set(&apic->timer.pending, 0);
543 hrtimer_start(&apic->timer.dev,
544 ktime_add_ns(now, apic->timer.period),
545 HRTIMER_MODE_ABS);
546
547 apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016"
548 PRIx64 ", "
549 "timer initial count 0x%x, period %lldns, "
550 "expire @ 0x%016" PRIx64 ".\n", __FUNCTION__,
551 APIC_BUS_CYCLE_NS, ktime_to_ns(now),
552 apic_get_reg(apic, APIC_TMICT),
553 apic->timer.period,
554 ktime_to_ns(ktime_add_ns(now,
555 apic->timer.period)));
556}
557
558static void apic_mmio_write(struct kvm_io_device *this,
559 gpa_t address, int len, const void *data)
560{
561 struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
562 unsigned int offset = address - apic->base_address;
563 unsigned char alignment = offset & 0xf;
564 u32 val;
565
566 /*
567 * APIC register must be aligned on 128-bits boundary.
568 * 32/64/128 bits registers must be accessed thru 32 bits.
569 * Refer SDM 8.4.1
570 */
571 if (len != 4 || alignment) {
572 if (printk_ratelimit())
573 printk(KERN_ERR "apic write: bad size=%d %lx\n",
574 len, (long)address);
575 return;
576 }
577
578 val = *(u32 *) data;
579
580 /* too common printing */
581 if (offset != APIC_EOI)
582 apic_debug("%s: offset 0x%x with length 0x%x, and value is "
583 "0x%x\n", __FUNCTION__, offset, len, val);
584
585 offset &= 0xff0;
586
587 switch (offset) {
588 case APIC_ID: /* Local APIC ID */
589 apic_set_reg(apic, APIC_ID, val);
590 break;
591
592 case APIC_TASKPRI:
593 apic_set_tpr(apic, val & 0xff);
594 break;
595
596 case APIC_EOI:
597 apic_set_eoi(apic);
598 break;
599
600 case APIC_LDR:
601 apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK);
602 break;
603
604 case APIC_DFR:
605 apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF);
606 break;
607
608 case APIC_SPIV:
609 apic_set_reg(apic, APIC_SPIV, val & 0x3ff);
610 if (!(val & APIC_SPIV_APIC_ENABLED)) {
611 int i;
612 u32 lvt_val;
613
614 for (i = 0; i < APIC_LVT_NUM; i++) {
615 lvt_val = apic_get_reg(apic,
616 APIC_LVTT + 0x10 * i);
617 apic_set_reg(apic, APIC_LVTT + 0x10 * i,
618 lvt_val | APIC_LVT_MASKED);
619 }
620 atomic_set(&apic->timer.pending, 0);
621
622 }
623 break;
624
625 case APIC_ICR:
626 /* No delay here, so we always clear the pending bit */
627 apic_set_reg(apic, APIC_ICR, val & ~(1 << 12));
628 apic_send_ipi(apic);
629 break;
630
631 case APIC_ICR2:
632 apic_set_reg(apic, APIC_ICR2, val & 0xff000000);
633 break;
634
635 case APIC_LVTT:
636 case APIC_LVTTHMR:
637 case APIC_LVTPC:
638 case APIC_LVT0:
639 case APIC_LVT1:
640 case APIC_LVTERR:
641 /* TODO: Check vector */
642 if (!apic_sw_enabled(apic))
643 val |= APIC_LVT_MASKED;
644
645 val &= apic_lvt_mask[(offset - APIC_LVTT) >> 4];
646 apic_set_reg(apic, offset, val);
647
648 break;
649
650 case APIC_TMICT:
651 hrtimer_cancel(&apic->timer.dev);
652 apic_set_reg(apic, APIC_TMICT, val);
653 start_apic_timer(apic);
654 return;
655
656 case APIC_TDCR:
657 if (val & 4)
658 printk(KERN_ERR "KVM_WRITE:TDCR %x\n", val);
659 apic_set_reg(apic, APIC_TDCR, val);
660 update_divide_count(apic);
661 break;
662
663 default:
664 apic_debug("Local APIC Write to read-only register %x\n",
665 offset);
666 break;
667 }
668
669}
670
671static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr)
672{
673 struct kvm_lapic *apic = (struct kvm_lapic *)this->private;
674 int ret = 0;
675
676
677 if (apic_hw_enabled(apic) &&
678 (addr >= apic->base_address) &&
679 (addr < (apic->base_address + LAPIC_MMIO_LENGTH)))
680 ret = 1;
681
682 return ret;
683}
684
685void kvm_free_apic(struct kvm_lapic *apic)
686{
687 if (!apic)
688 return;
689
690 hrtimer_cancel(&apic->timer.dev);
691
692 if (apic->regs_page) {
693 __free_page(apic->regs_page);
694 apic->regs_page = 0;
695 }
696
697 kfree(apic);
698}
699
700/*
701 *----------------------------------------------------------------------
702 * LAPIC interface
703 *----------------------------------------------------------------------
704 */
705
706void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8)
707{
708 struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
709
710 if (!apic)
711 return;
712 apic_set_tpr(apic, ((cr8 & 0x0f) << 4));
713}
714
715u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu)
716{
717 struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
718 u64 tpr;
719
720 if (!apic)
721 return 0;
722 tpr = (u64) apic_get_reg(apic, APIC_TASKPRI);
723
724 return (tpr & 0xf0) >> 4;
725}
726
727void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value)
728{
729 struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
730
731 if (!apic) {
732 value |= MSR_IA32_APICBASE_BSP;
733 vcpu->apic_base = value;
734 return;
735 }
736 if (apic->vcpu->vcpu_id)
737 value &= ~MSR_IA32_APICBASE_BSP;
738
739 vcpu->apic_base = value;
740 apic->base_address = apic->vcpu->apic_base &
741 MSR_IA32_APICBASE_BASE;
742
743 /* with FSB delivery interrupt, we can restart APIC functionality */
744 apic_debug("apic base msr is 0x%016" PRIx64 ", and base address is "
745 "0x%lx.\n", apic->apic_base, apic->base_address);
746
747}
748
749u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu)
750{
751 return vcpu->apic_base;
752}
753EXPORT_SYMBOL_GPL(kvm_lapic_get_base);
754
755static void lapic_reset(struct kvm_vcpu *vcpu)
756{
757 struct kvm_lapic *apic;
758 int i;
759
760 apic_debug("%s\n", __FUNCTION__);
761
762 ASSERT(vcpu);
763 apic = vcpu->apic;
764 ASSERT(apic != NULL);
765
766 /* Stop the timer in case it's a reset to an active apic */
767 hrtimer_cancel(&apic->timer.dev);
768
769 apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24);
770 apic_set_reg(apic, APIC_LVR, APIC_VERSION);
771
772 for (i = 0; i < APIC_LVT_NUM; i++)
773 apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED);
774
775 apic_set_reg(apic, APIC_DFR, 0xffffffffU);
776 apic_set_reg(apic, APIC_SPIV, 0xff);
777 apic_set_reg(apic, APIC_TASKPRI, 0);
778 apic_set_reg(apic, APIC_LDR, 0);
779 apic_set_reg(apic, APIC_ESR, 0);
780 apic_set_reg(apic, APIC_ICR, 0);
781 apic_set_reg(apic, APIC_ICR2, 0);
782 apic_set_reg(apic, APIC_TDCR, 0);
783 apic_set_reg(apic, APIC_TMICT, 0);
784 for (i = 0; i < 8; i++) {
785 apic_set_reg(apic, APIC_IRR + 0x10 * i, 0);
786 apic_set_reg(apic, APIC_ISR + 0x10 * i, 0);
787 apic_set_reg(apic, APIC_TMR + 0x10 * i, 0);
788 }
789 apic->timer.divide_count = 0;
790 atomic_set(&apic->timer.pending, 0);
791 if (vcpu->vcpu_id == 0)
792 vcpu->apic_base |= MSR_IA32_APICBASE_BSP;
793 apic_update_ppr(apic);
794
795 apic_debug(KERN_INFO "%s: vcpu=%p, id=%d, base_msr="
796 "0x%016" PRIx64 ", base_address=0x%0lx.\n", __FUNCTION__,
797 vcpu, kvm_apic_id(apic),
798 vcpu->apic_base, apic->base_address);
799}
800
801int kvm_lapic_enabled(struct kvm_vcpu *vcpu)
802{
803 struct kvm_lapic *apic = (struct kvm_lapic *)vcpu->apic;
804 int ret = 0;
805
806 if (!apic)
807 return 0;
808 ret = apic_enabled(apic);
809
810 return ret;
811}
812
813/*
814 *----------------------------------------------------------------------
815 * timer interface
816 *----------------------------------------------------------------------
817 */
818static int __apic_timer_fn(struct kvm_lapic *apic)
819{
820 u32 vector;
821 int result = 0;
822
823 if (unlikely(!apic_enabled(apic) ||
824 !apic_lvt_enabled(apic, APIC_LVTT))) {
825 apic_debug("%s: time interrupt although apic is down\n",
826 __FUNCTION__);
827 return 0;
828 }
829
830 vector = apic_lvt_vector(apic, APIC_LVTT);
831 apic->timer.last_update = apic->timer.dev.expires;
832 atomic_inc(&apic->timer.pending);
833 __apic_accept_irq(apic, APIC_DM_FIXED, vector, 1, 0);
834
835 if (apic_lvtt_period(apic)) {
836 u32 offset;
837 u32 tmict = apic_get_reg(apic, APIC_TMICT);
838
839 offset = APIC_BUS_CYCLE_NS * apic->timer.divide_count * tmict;
840
841 result = 1;
842 apic->timer.dev.expires = ktime_add_ns(
843 apic->timer.dev.expires,
844 apic->timer.period);
845 }
846
847 return result;
848}
849
850static enum hrtimer_restart apic_timer_fn(struct hrtimer *data)
851{
852 struct kvm_lapic *apic;
853 int restart_timer = 0;
854
855 apic = container_of(data, struct kvm_lapic, timer.dev);
856
857 restart_timer = __apic_timer_fn(apic);
858
859 if (restart_timer)
860 return HRTIMER_RESTART;
861 else
862 return HRTIMER_NORESTART;
863}
864
865int kvm_create_lapic(struct kvm_vcpu *vcpu)
866{
867 struct kvm_lapic *apic;
868
869 ASSERT(vcpu != NULL);
870 apic_debug("apic_init %d\n", vcpu->vcpu_id);
871
872 apic = kzalloc(sizeof(*apic), GFP_KERNEL);
873 if (!apic)
874 goto nomem;
875
876 vcpu->apic = apic;
877
878 apic->regs_page = alloc_page(GFP_KERNEL);
879 if (apic->regs_page == NULL) {
880 printk(KERN_ERR "malloc apic regs error for vcpu %x\n",
881 vcpu->vcpu_id);
882 goto nomem;
883 }
884 apic->regs = page_address(apic->regs_page);
885 memset(apic->regs, 0, PAGE_SIZE);
886 apic->vcpu = vcpu;
887
888 hrtimer_init(&apic->timer.dev, CLOCK_MONOTONIC, HRTIMER_MODE_ABS);
889 apic->timer.dev.function = apic_timer_fn;
890 apic->base_address = APIC_DEFAULT_PHYS_BASE;
891 vcpu->apic_base = APIC_DEFAULT_PHYS_BASE;
892
893 lapic_reset(vcpu);
894 apic->dev.read = apic_mmio_read;
895 apic->dev.write = apic_mmio_write;
896 apic->dev.in_range = apic_mmio_range;
897 apic->dev.private = apic;
898
899 return 0;
900nomem:
901 kvm_free_apic(apic);
902 return -ENOMEM;
903}
904EXPORT_SYMBOL_GPL(kvm_create_lapic);
905
906int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu)
907{
908 struct kvm_lapic *apic = vcpu->apic;
909 int highest_irr;
910
911 if (!apic || !apic_enabled(apic))
912 return -1;
913
914 highest_irr = apic_find_highest_irr(apic);
915 if ((highest_irr == -1) ||
916 ((highest_irr & 0xF0) <= apic_get_reg(apic, APIC_PROCPRI)))
917 return -1;
918 return highest_irr;
919}
920
921int kvm_get_apic_interrupt(struct kvm_vcpu *vcpu)
922{
923 int vector = kvm_apic_has_interrupt(vcpu);
924 struct kvm_lapic *apic = vcpu->apic;
925
926 if (vector == -1)
927 return -1;
928
929 apic_set_vector(vector, apic->regs + APIC_ISR);
930 apic_update_ppr(apic);
931 apic_clear_irr(vector, apic);
932 return vector;
933}