diff options
Diffstat (limited to 'arch/x86/kvm/lapic.c')
-rw-r--r-- | arch/x86/kvm/lapic.c | 334 |
1 files changed, 246 insertions, 88 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index ae99d83f81a3..1ae5ceba7eb2 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -32,8 +32,11 @@ | |||
32 | #include <asm/current.h> | 32 | #include <asm/current.h> |
33 | #include <asm/apicdef.h> | 33 | #include <asm/apicdef.h> |
34 | #include <asm/atomic.h> | 34 | #include <asm/atomic.h> |
35 | #include <asm/apicdef.h> | ||
35 | #include "kvm_cache_regs.h" | 36 | #include "kvm_cache_regs.h" |
36 | #include "irq.h" | 37 | #include "irq.h" |
38 | #include "trace.h" | ||
39 | #include "x86.h" | ||
37 | 40 | ||
38 | #ifndef CONFIG_X86_64 | 41 | #ifndef CONFIG_X86_64 |
39 | #define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) | 42 | #define mod_64(x, y) ((x) - (y) * div64_u64(x, y)) |
@@ -141,6 +144,26 @@ static inline int apic_lvt_nmi_mode(u32 lvt_val) | |||
141 | return (lvt_val & (APIC_MODE_MASK | APIC_LVT_MASKED)) == APIC_DM_NMI; | 144 | return (lvt_val & (APIC_MODE_MASK | APIC_LVT_MASKED)) == APIC_DM_NMI; |
142 | } | 145 | } |
143 | 146 | ||
147 | void kvm_apic_set_version(struct kvm_vcpu *vcpu) | ||
148 | { | ||
149 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
150 | struct kvm_cpuid_entry2 *feat; | ||
151 | u32 v = APIC_VERSION; | ||
152 | |||
153 | if (!irqchip_in_kernel(vcpu->kvm)) | ||
154 | return; | ||
155 | |||
156 | feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0); | ||
157 | if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31)))) | ||
158 | v |= APIC_LVR_DIRECTED_EOI; | ||
159 | apic_set_reg(apic, APIC_LVR, v); | ||
160 | } | ||
161 | |||
162 | static inline int apic_x2apic_mode(struct kvm_lapic *apic) | ||
163 | { | ||
164 | return apic->vcpu->arch.apic_base & X2APIC_ENABLE; | ||
165 | } | ||
166 | |||
144 | static unsigned int apic_lvt_mask[APIC_LVT_NUM] = { | 167 | static unsigned int apic_lvt_mask[APIC_LVT_NUM] = { |
145 | LVT_MASK | APIC_LVT_TIMER_PERIODIC, /* LVTT */ | 168 | LVT_MASK | APIC_LVT_TIMER_PERIODIC, /* LVTT */ |
146 | LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */ | 169 | LVT_MASK | APIC_MODE_MASK, /* LVTTHMR */ |
@@ -165,36 +188,52 @@ static int find_highest_vector(void *bitmap) | |||
165 | 188 | ||
166 | static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic) | 189 | static inline int apic_test_and_set_irr(int vec, struct kvm_lapic *apic) |
167 | { | 190 | { |
191 | apic->irr_pending = true; | ||
168 | return apic_test_and_set_vector(vec, apic->regs + APIC_IRR); | 192 | return apic_test_and_set_vector(vec, apic->regs + APIC_IRR); |
169 | } | 193 | } |
170 | 194 | ||
171 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) | 195 | static inline int apic_search_irr(struct kvm_lapic *apic) |
172 | { | 196 | { |
173 | apic_clear_vector(vec, apic->regs + APIC_IRR); | 197 | return find_highest_vector(apic->regs + APIC_IRR); |
174 | } | 198 | } |
175 | 199 | ||
176 | static inline int apic_find_highest_irr(struct kvm_lapic *apic) | 200 | static inline int apic_find_highest_irr(struct kvm_lapic *apic) |
177 | { | 201 | { |
178 | int result; | 202 | int result; |
179 | 203 | ||
180 | result = find_highest_vector(apic->regs + APIC_IRR); | 204 | if (!apic->irr_pending) |
205 | return -1; | ||
206 | |||
207 | result = apic_search_irr(apic); | ||
181 | ASSERT(result == -1 || result >= 16); | 208 | ASSERT(result == -1 || result >= 16); |
182 | 209 | ||
183 | return result; | 210 | return result; |
184 | } | 211 | } |
185 | 212 | ||
213 | static inline void apic_clear_irr(int vec, struct kvm_lapic *apic) | ||
214 | { | ||
215 | apic->irr_pending = false; | ||
216 | apic_clear_vector(vec, apic->regs + APIC_IRR); | ||
217 | if (apic_search_irr(apic) != -1) | ||
218 | apic->irr_pending = true; | ||
219 | } | ||
220 | |||
186 | int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) | 221 | int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) |
187 | { | 222 | { |
188 | struct kvm_lapic *apic = vcpu->arch.apic; | 223 | struct kvm_lapic *apic = vcpu->arch.apic; |
189 | int highest_irr; | 224 | int highest_irr; |
190 | 225 | ||
226 | /* This may race with setting of irr in __apic_accept_irq() and | ||
227 | * value returned may be wrong, but kvm_vcpu_kick() in __apic_accept_irq | ||
228 | * will cause vmexit immediately and the value will be recalculated | ||
229 | * on the next vmentry. | ||
230 | */ | ||
191 | if (!apic) | 231 | if (!apic) |
192 | return 0; | 232 | return 0; |
193 | highest_irr = apic_find_highest_irr(apic); | 233 | highest_irr = apic_find_highest_irr(apic); |
194 | 234 | ||
195 | return highest_irr; | 235 | return highest_irr; |
196 | } | 236 | } |
197 | EXPORT_SYMBOL_GPL(kvm_lapic_find_highest_irr); | ||
198 | 237 | ||
199 | static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | 238 | static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, |
200 | int vector, int level, int trig_mode); | 239 | int vector, int level, int trig_mode); |
@@ -251,7 +290,12 @@ int kvm_apic_match_physical_addr(struct kvm_lapic *apic, u16 dest) | |||
251 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | 290 | int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) |
252 | { | 291 | { |
253 | int result = 0; | 292 | int result = 0; |
254 | u8 logical_id; | 293 | u32 logical_id; |
294 | |||
295 | if (apic_x2apic_mode(apic)) { | ||
296 | logical_id = apic_get_reg(apic, APIC_LDR); | ||
297 | return logical_id & mda; | ||
298 | } | ||
255 | 299 | ||
256 | logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR)); | 300 | logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR)); |
257 | 301 | ||
@@ -331,6 +375,8 @@ static int __apic_accept_irq(struct kvm_lapic *apic, int delivery_mode, | |||
331 | break; | 375 | break; |
332 | 376 | ||
333 | result = !apic_test_and_set_irr(vector, apic); | 377 | result = !apic_test_and_set_irr(vector, apic); |
378 | trace_kvm_apic_accept_irq(vcpu->vcpu_id, delivery_mode, | ||
379 | trig_mode, vector, !result); | ||
334 | if (!result) { | 380 | if (!result) { |
335 | if (trig_mode) | 381 | if (trig_mode) |
336 | apic_debug("level trig mode repeatedly for " | 382 | apic_debug("level trig mode repeatedly for " |
@@ -425,7 +471,11 @@ static void apic_set_eoi(struct kvm_lapic *apic) | |||
425 | trigger_mode = IOAPIC_LEVEL_TRIG; | 471 | trigger_mode = IOAPIC_LEVEL_TRIG; |
426 | else | 472 | else |
427 | trigger_mode = IOAPIC_EDGE_TRIG; | 473 | trigger_mode = IOAPIC_EDGE_TRIG; |
428 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); | 474 | if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI)) { |
475 | mutex_lock(&apic->vcpu->kvm->irq_lock); | ||
476 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); | ||
477 | mutex_unlock(&apic->vcpu->kvm->irq_lock); | ||
478 | } | ||
429 | } | 479 | } |
430 | 480 | ||
431 | static void apic_send_ipi(struct kvm_lapic *apic) | 481 | static void apic_send_ipi(struct kvm_lapic *apic) |
@@ -440,7 +490,12 @@ static void apic_send_ipi(struct kvm_lapic *apic) | |||
440 | irq.level = icr_low & APIC_INT_ASSERT; | 490 | irq.level = icr_low & APIC_INT_ASSERT; |
441 | irq.trig_mode = icr_low & APIC_INT_LEVELTRIG; | 491 | irq.trig_mode = icr_low & APIC_INT_LEVELTRIG; |
442 | irq.shorthand = icr_low & APIC_SHORT_MASK; | 492 | irq.shorthand = icr_low & APIC_SHORT_MASK; |
443 | irq.dest_id = GET_APIC_DEST_FIELD(icr_high); | 493 | if (apic_x2apic_mode(apic)) |
494 | irq.dest_id = icr_high; | ||
495 | else | ||
496 | irq.dest_id = GET_APIC_DEST_FIELD(icr_high); | ||
497 | |||
498 | trace_kvm_apic_ipi(icr_low, irq.dest_id); | ||
444 | 499 | ||
445 | apic_debug("icr_high 0x%x, icr_low 0x%x, " | 500 | apic_debug("icr_high 0x%x, icr_low 0x%x, " |
446 | "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " | 501 | "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " |
@@ -449,7 +504,9 @@ static void apic_send_ipi(struct kvm_lapic *apic) | |||
449 | irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, | 504 | irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, |
450 | irq.vector); | 505 | irq.vector); |
451 | 506 | ||
507 | mutex_lock(&apic->vcpu->kvm->irq_lock); | ||
452 | kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq); | 508 | kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq); |
509 | mutex_unlock(&apic->vcpu->kvm->irq_lock); | ||
453 | } | 510 | } |
454 | 511 | ||
455 | static u32 apic_get_tmcct(struct kvm_lapic *apic) | 512 | static u32 apic_get_tmcct(struct kvm_lapic *apic) |
@@ -495,12 +552,16 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) | |||
495 | { | 552 | { |
496 | u32 val = 0; | 553 | u32 val = 0; |
497 | 554 | ||
498 | KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler); | ||
499 | |||
500 | if (offset >= LAPIC_MMIO_LENGTH) | 555 | if (offset >= LAPIC_MMIO_LENGTH) |
501 | return 0; | 556 | return 0; |
502 | 557 | ||
503 | switch (offset) { | 558 | switch (offset) { |
559 | case APIC_ID: | ||
560 | if (apic_x2apic_mode(apic)) | ||
561 | val = kvm_apic_id(apic); | ||
562 | else | ||
563 | val = kvm_apic_id(apic) << 24; | ||
564 | break; | ||
504 | case APIC_ARBPRI: | 565 | case APIC_ARBPRI: |
505 | printk(KERN_WARNING "Access APIC ARBPRI register " | 566 | printk(KERN_WARNING "Access APIC ARBPRI register " |
506 | "which is for P6\n"); | 567 | "which is for P6\n"); |
@@ -522,21 +583,35 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) | |||
522 | return val; | 583 | return val; |
523 | } | 584 | } |
524 | 585 | ||
525 | static void apic_mmio_read(struct kvm_io_device *this, | 586 | static inline struct kvm_lapic *to_lapic(struct kvm_io_device *dev) |
526 | gpa_t address, int len, void *data) | 587 | { |
588 | return container_of(dev, struct kvm_lapic, dev); | ||
589 | } | ||
590 | |||
591 | static int apic_reg_read(struct kvm_lapic *apic, u32 offset, int len, | ||
592 | void *data) | ||
527 | { | 593 | { |
528 | struct kvm_lapic *apic = (struct kvm_lapic *)this->private; | ||
529 | unsigned int offset = address - apic->base_address; | ||
530 | unsigned char alignment = offset & 0xf; | 594 | unsigned char alignment = offset & 0xf; |
531 | u32 result; | 595 | u32 result; |
596 | /* this bitmask has a bit cleared for each reserver register */ | ||
597 | static const u64 rmask = 0x43ff01ffffffe70cULL; | ||
532 | 598 | ||
533 | if ((alignment + len) > 4) { | 599 | if ((alignment + len) > 4) { |
534 | printk(KERN_ERR "KVM_APIC_READ: alignment error %lx %d", | 600 | apic_debug("KVM_APIC_READ: alignment error %x %d\n", |
535 | (unsigned long)address, len); | 601 | offset, len); |
536 | return; | 602 | return 1; |
537 | } | 603 | } |
604 | |||
605 | if (offset > 0x3f0 || !(rmask & (1ULL << (offset >> 4)))) { | ||
606 | apic_debug("KVM_APIC_READ: read reserved register %x\n", | ||
607 | offset); | ||
608 | return 1; | ||
609 | } | ||
610 | |||
538 | result = __apic_read(apic, offset & ~0xf); | 611 | result = __apic_read(apic, offset & ~0xf); |
539 | 612 | ||
613 | trace_kvm_apic_read(offset, result); | ||
614 | |||
540 | switch (len) { | 615 | switch (len) { |
541 | case 1: | 616 | case 1: |
542 | case 2: | 617 | case 2: |
@@ -548,6 +623,28 @@ static void apic_mmio_read(struct kvm_io_device *this, | |||
548 | "should be 1,2, or 4 instead\n", len); | 623 | "should be 1,2, or 4 instead\n", len); |
549 | break; | 624 | break; |
550 | } | 625 | } |
626 | return 0; | ||
627 | } | ||
628 | |||
629 | static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr) | ||
630 | { | ||
631 | return apic_hw_enabled(apic) && | ||
632 | addr >= apic->base_address && | ||
633 | addr < apic->base_address + LAPIC_MMIO_LENGTH; | ||
634 | } | ||
635 | |||
636 | static int apic_mmio_read(struct kvm_io_device *this, | ||
637 | gpa_t address, int len, void *data) | ||
638 | { | ||
639 | struct kvm_lapic *apic = to_lapic(this); | ||
640 | u32 offset = address - apic->base_address; | ||
641 | |||
642 | if (!apic_mmio_in_range(apic, address)) | ||
643 | return -EOPNOTSUPP; | ||
644 | |||
645 | apic_reg_read(apic, offset, len, data); | ||
646 | |||
647 | return 0; | ||
551 | } | 648 | } |
552 | 649 | ||
553 | static void update_divide_count(struct kvm_lapic *apic) | 650 | static void update_divide_count(struct kvm_lapic *apic) |
@@ -573,6 +670,15 @@ static void start_apic_timer(struct kvm_lapic *apic) | |||
573 | 670 | ||
574 | if (!apic->lapic_timer.period) | 671 | if (!apic->lapic_timer.period) |
575 | return; | 672 | return; |
673 | /* | ||
674 | * Do not allow the guest to program periodic timers with small | ||
675 | * interval, since the hrtimers are not throttled by the host | ||
676 | * scheduler. | ||
677 | */ | ||
678 | if (apic_lvtt_period(apic)) { | ||
679 | if (apic->lapic_timer.period < NSEC_PER_MSEC/2) | ||
680 | apic->lapic_timer.period = NSEC_PER_MSEC/2; | ||
681 | } | ||
576 | 682 | ||
577 | hrtimer_start(&apic->lapic_timer.timer, | 683 | hrtimer_start(&apic->lapic_timer.timer, |
578 | ktime_add_ns(now, apic->lapic_timer.period), | 684 | ktime_add_ns(now, apic->lapic_timer.period), |
@@ -603,40 +709,18 @@ static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) | |||
603 | apic->vcpu->kvm->arch.vapics_in_nmi_mode--; | 709 | apic->vcpu->kvm->arch.vapics_in_nmi_mode--; |
604 | } | 710 | } |
605 | 711 | ||
606 | static void apic_mmio_write(struct kvm_io_device *this, | 712 | static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) |
607 | gpa_t address, int len, const void *data) | ||
608 | { | 713 | { |
609 | struct kvm_lapic *apic = (struct kvm_lapic *)this->private; | 714 | int ret = 0; |
610 | unsigned int offset = address - apic->base_address; | ||
611 | unsigned char alignment = offset & 0xf; | ||
612 | u32 val; | ||
613 | |||
614 | /* | ||
615 | * APIC register must be aligned on 128-bits boundary. | ||
616 | * 32/64/128 bits registers must be accessed thru 32 bits. | ||
617 | * Refer SDM 8.4.1 | ||
618 | */ | ||
619 | if (len != 4 || alignment) { | ||
620 | /* Don't shout loud, $infamous_os would cause only noise. */ | ||
621 | apic_debug("apic write: bad size=%d %lx\n", | ||
622 | len, (long)address); | ||
623 | return; | ||
624 | } | ||
625 | |||
626 | val = *(u32 *) data; | ||
627 | |||
628 | /* too common printing */ | ||
629 | if (offset != APIC_EOI) | ||
630 | apic_debug("%s: offset 0x%x with length 0x%x, and value is " | ||
631 | "0x%x\n", __func__, offset, len, val); | ||
632 | |||
633 | offset &= 0xff0; | ||
634 | 715 | ||
635 | KVMTRACE_1D(APIC_ACCESS, apic->vcpu, (u32)offset, handler); | 716 | trace_kvm_apic_write(reg, val); |
636 | 717 | ||
637 | switch (offset) { | 718 | switch (reg) { |
638 | case APIC_ID: /* Local APIC ID */ | 719 | case APIC_ID: /* Local APIC ID */ |
639 | apic_set_reg(apic, APIC_ID, val); | 720 | if (!apic_x2apic_mode(apic)) |
721 | apic_set_reg(apic, APIC_ID, val); | ||
722 | else | ||
723 | ret = 1; | ||
640 | break; | 724 | break; |
641 | 725 | ||
642 | case APIC_TASKPRI: | 726 | case APIC_TASKPRI: |
@@ -649,15 +733,24 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
649 | break; | 733 | break; |
650 | 734 | ||
651 | case APIC_LDR: | 735 | case APIC_LDR: |
652 | apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK); | 736 | if (!apic_x2apic_mode(apic)) |
737 | apic_set_reg(apic, APIC_LDR, val & APIC_LDR_MASK); | ||
738 | else | ||
739 | ret = 1; | ||
653 | break; | 740 | break; |
654 | 741 | ||
655 | case APIC_DFR: | 742 | case APIC_DFR: |
656 | apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); | 743 | if (!apic_x2apic_mode(apic)) |
744 | apic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); | ||
745 | else | ||
746 | ret = 1; | ||
657 | break; | 747 | break; |
658 | 748 | ||
659 | case APIC_SPIV: | 749 | case APIC_SPIV: { |
660 | apic_set_reg(apic, APIC_SPIV, val & 0x3ff); | 750 | u32 mask = 0x3ff; |
751 | if (apic_get_reg(apic, APIC_LVR) & APIC_LVR_DIRECTED_EOI) | ||
752 | mask |= APIC_SPIV_DIRECTED_EOI; | ||
753 | apic_set_reg(apic, APIC_SPIV, val & mask); | ||
661 | if (!(val & APIC_SPIV_APIC_ENABLED)) { | 754 | if (!(val & APIC_SPIV_APIC_ENABLED)) { |
662 | int i; | 755 | int i; |
663 | u32 lvt_val; | 756 | u32 lvt_val; |
@@ -672,7 +765,7 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
672 | 765 | ||
673 | } | 766 | } |
674 | break; | 767 | break; |
675 | 768 | } | |
676 | case APIC_ICR: | 769 | case APIC_ICR: |
677 | /* No delay here, so we always clear the pending bit */ | 770 | /* No delay here, so we always clear the pending bit */ |
678 | apic_set_reg(apic, APIC_ICR, val & ~(1 << 12)); | 771 | apic_set_reg(apic, APIC_ICR, val & ~(1 << 12)); |
@@ -680,7 +773,9 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
680 | break; | 773 | break; |
681 | 774 | ||
682 | case APIC_ICR2: | 775 | case APIC_ICR2: |
683 | apic_set_reg(apic, APIC_ICR2, val & 0xff000000); | 776 | if (!apic_x2apic_mode(apic)) |
777 | val &= 0xff000000; | ||
778 | apic_set_reg(apic, APIC_ICR2, val); | ||
684 | break; | 779 | break; |
685 | 780 | ||
686 | case APIC_LVT0: | 781 | case APIC_LVT0: |
@@ -694,8 +789,8 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
694 | if (!apic_sw_enabled(apic)) | 789 | if (!apic_sw_enabled(apic)) |
695 | val |= APIC_LVT_MASKED; | 790 | val |= APIC_LVT_MASKED; |
696 | 791 | ||
697 | val &= apic_lvt_mask[(offset - APIC_LVTT) >> 4]; | 792 | val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4]; |
698 | apic_set_reg(apic, offset, val); | 793 | apic_set_reg(apic, reg, val); |
699 | 794 | ||
700 | break; | 795 | break; |
701 | 796 | ||
@@ -703,7 +798,7 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
703 | hrtimer_cancel(&apic->lapic_timer.timer); | 798 | hrtimer_cancel(&apic->lapic_timer.timer); |
704 | apic_set_reg(apic, APIC_TMICT, val); | 799 | apic_set_reg(apic, APIC_TMICT, val); |
705 | start_apic_timer(apic); | 800 | start_apic_timer(apic); |
706 | return; | 801 | break; |
707 | 802 | ||
708 | case APIC_TDCR: | 803 | case APIC_TDCR: |
709 | if (val & 4) | 804 | if (val & 4) |
@@ -712,27 +807,59 @@ static void apic_mmio_write(struct kvm_io_device *this, | |||
712 | update_divide_count(apic); | 807 | update_divide_count(apic); |
713 | break; | 808 | break; |
714 | 809 | ||
810 | case APIC_ESR: | ||
811 | if (apic_x2apic_mode(apic) && val != 0) { | ||
812 | printk(KERN_ERR "KVM_WRITE:ESR not zero %x\n", val); | ||
813 | ret = 1; | ||
814 | } | ||
815 | break; | ||
816 | |||
817 | case APIC_SELF_IPI: | ||
818 | if (apic_x2apic_mode(apic)) { | ||
819 | apic_reg_write(apic, APIC_ICR, 0x40000 | (val & 0xff)); | ||
820 | } else | ||
821 | ret = 1; | ||
822 | break; | ||
715 | default: | 823 | default: |
716 | apic_debug("Local APIC Write to read-only register %x\n", | 824 | ret = 1; |
717 | offset); | ||
718 | break; | 825 | break; |
719 | } | 826 | } |
720 | 827 | if (ret) | |
828 | apic_debug("Local APIC Write to read-only register %x\n", reg); | ||
829 | return ret; | ||
721 | } | 830 | } |
722 | 831 | ||
723 | static int apic_mmio_range(struct kvm_io_device *this, gpa_t addr, | 832 | static int apic_mmio_write(struct kvm_io_device *this, |
724 | int len, int size) | 833 | gpa_t address, int len, const void *data) |
725 | { | 834 | { |
726 | struct kvm_lapic *apic = (struct kvm_lapic *)this->private; | 835 | struct kvm_lapic *apic = to_lapic(this); |
727 | int ret = 0; | 836 | unsigned int offset = address - apic->base_address; |
837 | u32 val; | ||
728 | 838 | ||
839 | if (!apic_mmio_in_range(apic, address)) | ||
840 | return -EOPNOTSUPP; | ||
729 | 841 | ||
730 | if (apic_hw_enabled(apic) && | 842 | /* |
731 | (addr >= apic->base_address) && | 843 | * APIC register must be aligned on 128-bits boundary. |
732 | (addr < (apic->base_address + LAPIC_MMIO_LENGTH))) | 844 | * 32/64/128 bits registers must be accessed thru 32 bits. |
733 | ret = 1; | 845 | * Refer SDM 8.4.1 |
846 | */ | ||
847 | if (len != 4 || (offset & 0xf)) { | ||
848 | /* Don't shout loud, $infamous_os would cause only noise. */ | ||
849 | apic_debug("apic write: bad size=%d %lx\n", len, (long)address); | ||
850 | return 0; | ||
851 | } | ||
734 | 852 | ||
735 | return ret; | 853 | val = *(u32*)data; |
854 | |||
855 | /* too common printing */ | ||
856 | if (offset != APIC_EOI) | ||
857 | apic_debug("%s: offset 0x%x with length 0x%x, and value is " | ||
858 | "0x%x\n", __func__, offset, len, val); | ||
859 | |||
860 | apic_reg_write(apic, offset & 0xff0, val); | ||
861 | |||
862 | return 0; | ||
736 | } | 863 | } |
737 | 864 | ||
738 | void kvm_free_lapic(struct kvm_vcpu *vcpu) | 865 | void kvm_free_lapic(struct kvm_vcpu *vcpu) |
@@ -763,7 +890,6 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8) | |||
763 | apic_set_tpr(apic, ((cr8 & 0x0f) << 4) | 890 | apic_set_tpr(apic, ((cr8 & 0x0f) << 4) |
764 | | (apic_get_reg(apic, APIC_TASKPRI) & 4)); | 891 | | (apic_get_reg(apic, APIC_TASKPRI) & 4)); |
765 | } | 892 | } |
766 | EXPORT_SYMBOL_GPL(kvm_lapic_set_tpr); | ||
767 | 893 | ||
768 | u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) | 894 | u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) |
769 | { | 895 | { |
@@ -776,7 +902,6 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) | |||
776 | 902 | ||
777 | return (tpr & 0xf0) >> 4; | 903 | return (tpr & 0xf0) >> 4; |
778 | } | 904 | } |
779 | EXPORT_SYMBOL_GPL(kvm_lapic_get_cr8); | ||
780 | 905 | ||
781 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | 906 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) |
782 | { | 907 | { |
@@ -787,10 +912,16 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | |||
787 | vcpu->arch.apic_base = value; | 912 | vcpu->arch.apic_base = value; |
788 | return; | 913 | return; |
789 | } | 914 | } |
790 | if (apic->vcpu->vcpu_id) | 915 | |
916 | if (!kvm_vcpu_is_bsp(apic->vcpu)) | ||
791 | value &= ~MSR_IA32_APICBASE_BSP; | 917 | value &= ~MSR_IA32_APICBASE_BSP; |
792 | 918 | ||
793 | vcpu->arch.apic_base = value; | 919 | vcpu->arch.apic_base = value; |
920 | if (apic_x2apic_mode(apic)) { | ||
921 | u32 id = kvm_apic_id(apic); | ||
922 | u32 ldr = ((id & ~0xf) << 16) | (1 << (id & 0xf)); | ||
923 | apic_set_reg(apic, APIC_LDR, ldr); | ||
924 | } | ||
794 | apic->base_address = apic->vcpu->arch.apic_base & | 925 | apic->base_address = apic->vcpu->arch.apic_base & |
795 | MSR_IA32_APICBASE_BASE; | 926 | MSR_IA32_APICBASE_BASE; |
796 | 927 | ||
@@ -800,12 +931,6 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | |||
800 | 931 | ||
801 | } | 932 | } |
802 | 933 | ||
803 | u64 kvm_lapic_get_base(struct kvm_vcpu *vcpu) | ||
804 | { | ||
805 | return vcpu->arch.apic_base; | ||
806 | } | ||
807 | EXPORT_SYMBOL_GPL(kvm_lapic_get_base); | ||
808 | |||
809 | void kvm_lapic_reset(struct kvm_vcpu *vcpu) | 934 | void kvm_lapic_reset(struct kvm_vcpu *vcpu) |
810 | { | 935 | { |
811 | struct kvm_lapic *apic; | 936 | struct kvm_lapic *apic; |
@@ -821,7 +946,7 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
821 | hrtimer_cancel(&apic->lapic_timer.timer); | 946 | hrtimer_cancel(&apic->lapic_timer.timer); |
822 | 947 | ||
823 | apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24); | 948 | apic_set_reg(apic, APIC_ID, vcpu->vcpu_id << 24); |
824 | apic_set_reg(apic, APIC_LVR, APIC_VERSION); | 949 | kvm_apic_set_version(apic->vcpu); |
825 | 950 | ||
826 | for (i = 0; i < APIC_LVT_NUM; i++) | 951 | for (i = 0; i < APIC_LVT_NUM; i++) |
827 | apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); | 952 | apic_set_reg(apic, APIC_LVTT + 0x10 * i, APIC_LVT_MASKED); |
@@ -842,9 +967,10 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
842 | apic_set_reg(apic, APIC_ISR + 0x10 * i, 0); | 967 | apic_set_reg(apic, APIC_ISR + 0x10 * i, 0); |
843 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); | 968 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); |
844 | } | 969 | } |
970 | apic->irr_pending = false; | ||
845 | update_divide_count(apic); | 971 | update_divide_count(apic); |
846 | atomic_set(&apic->lapic_timer.pending, 0); | 972 | atomic_set(&apic->lapic_timer.pending, 0); |
847 | if (vcpu->vcpu_id == 0) | 973 | if (kvm_vcpu_is_bsp(vcpu)) |
848 | vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; | 974 | vcpu->arch.apic_base |= MSR_IA32_APICBASE_BSP; |
849 | apic_update_ppr(apic); | 975 | apic_update_ppr(apic); |
850 | 976 | ||
@@ -855,7 +981,6 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
855 | vcpu, kvm_apic_id(apic), | 981 | vcpu, kvm_apic_id(apic), |
856 | vcpu->arch.apic_base, apic->base_address); | 982 | vcpu->arch.apic_base, apic->base_address); |
857 | } | 983 | } |
858 | EXPORT_SYMBOL_GPL(kvm_lapic_reset); | ||
859 | 984 | ||
860 | bool kvm_apic_present(struct kvm_vcpu *vcpu) | 985 | bool kvm_apic_present(struct kvm_vcpu *vcpu) |
861 | { | 986 | { |
@@ -866,7 +991,6 @@ int kvm_lapic_enabled(struct kvm_vcpu *vcpu) | |||
866 | { | 991 | { |
867 | return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic); | 992 | return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic); |
868 | } | 993 | } |
869 | EXPORT_SYMBOL_GPL(kvm_lapic_enabled); | ||
870 | 994 | ||
871 | /* | 995 | /* |
872 | *---------------------------------------------------------------------- | 996 | *---------------------------------------------------------------------- |
@@ -917,6 +1041,11 @@ static struct kvm_timer_ops lapic_timer_ops = { | |||
917 | .is_periodic = lapic_is_periodic, | 1041 | .is_periodic = lapic_is_periodic, |
918 | }; | 1042 | }; |
919 | 1043 | ||
1044 | static const struct kvm_io_device_ops apic_mmio_ops = { | ||
1045 | .read = apic_mmio_read, | ||
1046 | .write = apic_mmio_write, | ||
1047 | }; | ||
1048 | |||
920 | int kvm_create_lapic(struct kvm_vcpu *vcpu) | 1049 | int kvm_create_lapic(struct kvm_vcpu *vcpu) |
921 | { | 1050 | { |
922 | struct kvm_lapic *apic; | 1051 | struct kvm_lapic *apic; |
@@ -945,16 +1074,13 @@ int kvm_create_lapic(struct kvm_vcpu *vcpu) | |||
945 | apic->lapic_timer.timer.function = kvm_timer_fn; | 1074 | apic->lapic_timer.timer.function = kvm_timer_fn; |
946 | apic->lapic_timer.t_ops = &lapic_timer_ops; | 1075 | apic->lapic_timer.t_ops = &lapic_timer_ops; |
947 | apic->lapic_timer.kvm = vcpu->kvm; | 1076 | apic->lapic_timer.kvm = vcpu->kvm; |
948 | apic->lapic_timer.vcpu_id = vcpu->vcpu_id; | 1077 | apic->lapic_timer.vcpu = vcpu; |
949 | 1078 | ||
950 | apic->base_address = APIC_DEFAULT_PHYS_BASE; | 1079 | apic->base_address = APIC_DEFAULT_PHYS_BASE; |
951 | vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE; | 1080 | vcpu->arch.apic_base = APIC_DEFAULT_PHYS_BASE; |
952 | 1081 | ||
953 | kvm_lapic_reset(vcpu); | 1082 | kvm_lapic_reset(vcpu); |
954 | apic->dev.read = apic_mmio_read; | 1083 | kvm_iodevice_init(&apic->dev, &apic_mmio_ops); |
955 | apic->dev.write = apic_mmio_write; | ||
956 | apic->dev.in_range = apic_mmio_range; | ||
957 | apic->dev.private = apic; | ||
958 | 1084 | ||
959 | return 0; | 1085 | return 0; |
960 | nomem_free_apic: | 1086 | nomem_free_apic: |
@@ -962,7 +1088,6 @@ nomem_free_apic: | |||
962 | nomem: | 1088 | nomem: |
963 | return -ENOMEM; | 1089 | return -ENOMEM; |
964 | } | 1090 | } |
965 | EXPORT_SYMBOL_GPL(kvm_create_lapic); | ||
966 | 1091 | ||
967 | int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu) | 1092 | int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu) |
968 | { | 1093 | { |
@@ -985,7 +1110,7 @@ int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu) | |||
985 | u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0); | 1110 | u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0); |
986 | int r = 0; | 1111 | int r = 0; |
987 | 1112 | ||
988 | if (vcpu->vcpu_id == 0) { | 1113 | if (kvm_vcpu_is_bsp(vcpu)) { |
989 | if (!apic_hw_enabled(vcpu->arch.apic)) | 1114 | if (!apic_hw_enabled(vcpu->arch.apic)) |
990 | r = 1; | 1115 | r = 1; |
991 | if ((lvt0 & APIC_LVT_MASKED) == 0 && | 1116 | if ((lvt0 & APIC_LVT_MASKED) == 0 && |
@@ -1025,7 +1150,8 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu) | |||
1025 | 1150 | ||
1026 | apic->base_address = vcpu->arch.apic_base & | 1151 | apic->base_address = vcpu->arch.apic_base & |
1027 | MSR_IA32_APICBASE_BASE; | 1152 | MSR_IA32_APICBASE_BASE; |
1028 | apic_set_reg(apic, APIC_LVR, APIC_VERSION); | 1153 | kvm_apic_set_version(vcpu); |
1154 | |||
1029 | apic_update_ppr(apic); | 1155 | apic_update_ppr(apic); |
1030 | hrtimer_cancel(&apic->lapic_timer.timer); | 1156 | hrtimer_cancel(&apic->lapic_timer.timer); |
1031 | update_divide_count(apic); | 1157 | update_divide_count(apic); |
@@ -1092,3 +1218,35 @@ void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr) | |||
1092 | 1218 | ||
1093 | vcpu->arch.apic->vapic_addr = vapic_addr; | 1219 | vcpu->arch.apic->vapic_addr = vapic_addr; |
1094 | } | 1220 | } |
1221 | |||
1222 | int kvm_x2apic_msr_write(struct kvm_vcpu *vcpu, u32 msr, u64 data) | ||
1223 | { | ||
1224 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
1225 | u32 reg = (msr - APIC_BASE_MSR) << 4; | ||
1226 | |||
1227 | if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) | ||
1228 | return 1; | ||
1229 | |||
1230 | /* if this is ICR write vector before command */ | ||
1231 | if (msr == 0x830) | ||
1232 | apic_reg_write(apic, APIC_ICR2, (u32)(data >> 32)); | ||
1233 | return apic_reg_write(apic, reg, (u32)data); | ||
1234 | } | ||
1235 | |||
1236 | int kvm_x2apic_msr_read(struct kvm_vcpu *vcpu, u32 msr, u64 *data) | ||
1237 | { | ||
1238 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
1239 | u32 reg = (msr - APIC_BASE_MSR) << 4, low, high = 0; | ||
1240 | |||
1241 | if (!irqchip_in_kernel(vcpu->kvm) || !apic_x2apic_mode(apic)) | ||
1242 | return 1; | ||
1243 | |||
1244 | if (apic_reg_read(apic, reg, 4, &low)) | ||
1245 | return 1; | ||
1246 | if (msr == 0x830) | ||
1247 | apic_reg_read(apic, APIC_ICR2, 4, &high); | ||
1248 | |||
1249 | *data = (((u64)high) << 32) | low; | ||
1250 | |||
1251 | return 0; | ||
1252 | } | ||