.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | |
---|
2 | 3 | /* |
---|
3 | 4 | * Local APIC virtualization |
---|
.. | .. |
---|
13 | 14 | * Yaozu (Eddie) Dong <eddie.dong@intel.com> |
---|
14 | 15 | * |
---|
15 | 16 | * Based on Xen 3.1 code, Copyright (c) 2004, Intel Corporation. |
---|
16 | | - * |
---|
17 | | - * This work is licensed under the terms of the GNU GPL, version 2. See |
---|
18 | | - * the COPYING file in the top-level directory. |
---|
19 | 17 | */ |
---|
20 | 18 | |
---|
21 | 19 | #include <linux/kvm_host.h> |
---|
.. | .. |
---|
38 | 36 | #include <linux/jump_label.h> |
---|
39 | 37 | #include "kvm_cache_regs.h" |
---|
40 | 38 | #include "irq.h" |
---|
| 39 | +#include "ioapic.h" |
---|
41 | 40 | #include "trace.h" |
---|
42 | 41 | #include "x86.h" |
---|
43 | 42 | #include "cpuid.h" |
---|
.. | .. |
---|
54 | 53 | #define PRIu64 "u" |
---|
55 | 54 | #define PRIo64 "o" |
---|
56 | 55 | |
---|
57 | | -/* #define apic_debug(fmt,arg...) printk(KERN_WARNING fmt,##arg) */ |
---|
58 | | -#define apic_debug(fmt, arg...) do {} while (0) |
---|
59 | | - |
---|
60 | 56 | /* 14 is the version for Xeon and Pentium 8.4.8*/ |
---|
61 | 57 | #define APIC_VERSION (0x14UL | ((KVM_APIC_LVT_NUM - 1) << 16)) |
---|
62 | 58 | #define LAPIC_MMIO_LENGTH (1 << 12) |
---|
63 | 59 | /* followed define is not in apicdef.h */ |
---|
64 | | -#define APIC_SHORT_MASK 0xc0000 |
---|
65 | | -#define APIC_DEST_NOSHORT 0x0 |
---|
66 | | -#define APIC_DEST_MASK 0x800 |
---|
67 | 60 | #define MAX_APIC_VECTOR 256 |
---|
68 | 61 | #define APIC_VECTORS_PER_REG 32 |
---|
69 | 62 | |
---|
70 | | -#define APIC_BROADCAST 0xFF |
---|
71 | | -#define X2APIC_BROADCAST 0xFFFFFFFFul |
---|
| 63 | +static bool lapic_timer_advance_dynamic __read_mostly; |
---|
| 64 | +#define LAPIC_TIMER_ADVANCE_ADJUST_MIN 100 /* clock cycles */ |
---|
| 65 | +#define LAPIC_TIMER_ADVANCE_ADJUST_MAX 10000 /* clock cycles */ |
---|
| 66 | +#define LAPIC_TIMER_ADVANCE_NS_INIT 1000 |
---|
| 67 | +#define LAPIC_TIMER_ADVANCE_NS_MAX 5000 |
---|
| 68 | +/* step-by-step approximation to mitigate fluctuation */ |
---|
| 69 | +#define LAPIC_TIMER_ADVANCE_ADJUST_STEP 8 |
---|
72 | 70 | |
---|
73 | 71 | static inline int apic_test_vector(int vec, void *bitmap) |
---|
74 | 72 | { |
---|
.. | .. |
---|
81 | 79 | |
---|
82 | 80 | return apic_test_vector(vector, apic->regs + APIC_ISR) || |
---|
83 | 81 | apic_test_vector(vector, apic->regs + APIC_IRR); |
---|
84 | | -} |
---|
85 | | - |
---|
86 | | -static inline void apic_clear_vector(int vec, void *bitmap) |
---|
87 | | -{ |
---|
88 | | - clear_bit(VEC_POS(vec), (bitmap) + REG_POS(vec)); |
---|
89 | 82 | } |
---|
90 | 83 | |
---|
91 | 84 | static inline int __apic_test_and_set_vector(int vec, void *bitmap) |
---|
.. | .. |
---|
113 | 106 | (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \ |
---|
114 | 107 | APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER) |
---|
115 | 108 | |
---|
116 | | -static inline u8 kvm_xapic_id(struct kvm_lapic *apic) |
---|
117 | | -{ |
---|
118 | | - return kvm_lapic_get_reg(apic, APIC_ID) >> 24; |
---|
119 | | -} |
---|
120 | | - |
---|
121 | 109 | static inline u32 kvm_x2apic_id(struct kvm_lapic *apic) |
---|
122 | 110 | { |
---|
123 | 111 | return apic->vcpu->vcpu_id; |
---|
| 112 | +} |
---|
| 113 | + |
---|
| 114 | +static bool kvm_can_post_timer_interrupt(struct kvm_vcpu *vcpu) |
---|
| 115 | +{ |
---|
| 116 | + return pi_inject_timer && kvm_vcpu_apicv_active(vcpu) && |
---|
| 117 | + (kvm_mwait_in_guest(vcpu->kvm) || kvm_hlt_in_guest(vcpu->kvm)); |
---|
| 118 | +} |
---|
| 119 | + |
---|
| 120 | +bool kvm_can_use_hv_timer(struct kvm_vcpu *vcpu) |
---|
| 121 | +{ |
---|
| 122 | + return kvm_x86_ops.set_hv_timer |
---|
| 123 | + && !(kvm_mwait_in_guest(vcpu->kvm) || |
---|
| 124 | + kvm_can_post_timer_interrupt(vcpu)); |
---|
| 125 | +} |
---|
| 126 | +EXPORT_SYMBOL_GPL(kvm_can_use_hv_timer); |
---|
| 127 | + |
---|
| 128 | +static bool kvm_use_posted_timer_interrupt(struct kvm_vcpu *vcpu) |
---|
| 129 | +{ |
---|
| 130 | + return kvm_can_post_timer_interrupt(vcpu) && vcpu->mode == IN_GUEST_MODE; |
---|
124 | 131 | } |
---|
125 | 132 | |
---|
126 | 133 | static inline bool kvm_apic_map_get_logical_dest(struct kvm_apic_map *map, |
---|
.. | .. |
---|
163 | 170 | kvfree(map); |
---|
164 | 171 | } |
---|
165 | 172 | |
---|
166 | | -static void recalculate_apic_map(struct kvm *kvm) |
---|
| 173 | +/* |
---|
| 174 | + * CLEAN -> DIRTY and UPDATE_IN_PROGRESS -> DIRTY changes happen without a lock. |
---|
| 175 | + * |
---|
| 176 | + * DIRTY -> UPDATE_IN_PROGRESS and UPDATE_IN_PROGRESS -> CLEAN happen with |
---|
| 177 | + * apic_map_lock_held. |
---|
| 178 | + */ |
---|
| 179 | +enum { |
---|
| 180 | + CLEAN, |
---|
| 181 | + UPDATE_IN_PROGRESS, |
---|
| 182 | + DIRTY |
---|
| 183 | +}; |
---|
| 184 | + |
---|
| 185 | +void kvm_recalculate_apic_map(struct kvm *kvm) |
---|
167 | 186 | { |
---|
168 | 187 | struct kvm_apic_map *new, *old = NULL; |
---|
169 | 188 | struct kvm_vcpu *vcpu; |
---|
170 | 189 | int i; |
---|
171 | 190 | u32 max_id = 255; /* enough space for any xAPIC ID */ |
---|
172 | 191 | |
---|
| 192 | + /* Read kvm->arch.apic_map_dirty before kvm->arch.apic_map. */ |
---|
| 193 | + if (atomic_read_acquire(&kvm->arch.apic_map_dirty) == CLEAN) |
---|
| 194 | + return; |
---|
| 195 | + |
---|
173 | 196 | mutex_lock(&kvm->arch.apic_map_lock); |
---|
| 197 | + /* |
---|
| 198 | + * Read kvm->arch.apic_map_dirty before kvm->arch.apic_map |
---|
| 199 | + * (if clean) or the APIC registers (if dirty). |
---|
| 200 | + */ |
---|
| 201 | + if (atomic_cmpxchg_acquire(&kvm->arch.apic_map_dirty, |
---|
| 202 | + DIRTY, UPDATE_IN_PROGRESS) == CLEAN) { |
---|
| 203 | + /* Someone else has updated the map. */ |
---|
| 204 | + mutex_unlock(&kvm->arch.apic_map_lock); |
---|
| 205 | + return; |
---|
| 206 | + } |
---|
174 | 207 | |
---|
175 | 208 | kvm_for_each_vcpu(i, vcpu, kvm) |
---|
176 | 209 | if (kvm_apic_present(vcpu)) |
---|
177 | 210 | max_id = max(max_id, kvm_x2apic_id(vcpu->arch.apic)); |
---|
178 | 211 | |
---|
179 | 212 | new = kvzalloc(sizeof(struct kvm_apic_map) + |
---|
180 | | - sizeof(struct kvm_lapic *) * ((u64)max_id + 1), GFP_KERNEL); |
---|
| 213 | + sizeof(struct kvm_lapic *) * ((u64)max_id + 1), |
---|
| 214 | + GFP_KERNEL_ACCOUNT); |
---|
181 | 215 | |
---|
182 | 216 | if (!new) |
---|
183 | 217 | goto out; |
---|
.. | .. |
---|
234 | 268 | old = rcu_dereference_protected(kvm->arch.apic_map, |
---|
235 | 269 | lockdep_is_held(&kvm->arch.apic_map_lock)); |
---|
236 | 270 | rcu_assign_pointer(kvm->arch.apic_map, new); |
---|
| 271 | + /* |
---|
| 272 | + * Write kvm->arch.apic_map before clearing apic->apic_map_dirty. |
---|
| 273 | + * If another update has come in, leave it DIRTY. |
---|
| 274 | + */ |
---|
| 275 | + atomic_cmpxchg_release(&kvm->arch.apic_map_dirty, |
---|
| 276 | + UPDATE_IN_PROGRESS, CLEAN); |
---|
237 | 277 | mutex_unlock(&kvm->arch.apic_map_lock); |
---|
238 | 278 | |
---|
239 | 279 | if (old) |
---|
.. | .. |
---|
250 | 290 | |
---|
251 | 291 | if (enabled != apic->sw_enabled) { |
---|
252 | 292 | apic->sw_enabled = enabled; |
---|
253 | | - if (enabled) { |
---|
| 293 | + if (enabled) |
---|
254 | 294 | static_key_slow_dec_deferred(&apic_sw_disabled); |
---|
255 | | - recalculate_apic_map(apic->vcpu->kvm); |
---|
256 | | - } else |
---|
| 295 | + else |
---|
257 | 296 | static_key_slow_inc(&apic_sw_disabled.key); |
---|
258 | 297 | |
---|
259 | | - recalculate_apic_map(apic->vcpu->kvm); |
---|
| 298 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); |
---|
260 | 299 | } |
---|
| 300 | + |
---|
| 301 | + /* Check if there are APF page ready requests pending */ |
---|
| 302 | + if (enabled) |
---|
| 303 | + kvm_make_request(KVM_REQ_APF_READY, apic->vcpu); |
---|
261 | 304 | } |
---|
262 | 305 | |
---|
263 | 306 | static inline void kvm_apic_set_xapic_id(struct kvm_lapic *apic, u8 id) |
---|
264 | 307 | { |
---|
265 | 308 | kvm_lapic_set_reg(apic, APIC_ID, id << 24); |
---|
266 | | - recalculate_apic_map(apic->vcpu->kvm); |
---|
| 309 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); |
---|
267 | 310 | } |
---|
268 | 311 | |
---|
269 | 312 | static inline void kvm_apic_set_ldr(struct kvm_lapic *apic, u32 id) |
---|
270 | 313 | { |
---|
271 | 314 | kvm_lapic_set_reg(apic, APIC_LDR, id); |
---|
272 | | - recalculate_apic_map(apic->vcpu->kvm); |
---|
| 315 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); |
---|
| 316 | +} |
---|
| 317 | + |
---|
| 318 | +static inline void kvm_apic_set_dfr(struct kvm_lapic *apic, u32 val) |
---|
| 319 | +{ |
---|
| 320 | + kvm_lapic_set_reg(apic, APIC_DFR, val); |
---|
| 321 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); |
---|
273 | 322 | } |
---|
274 | 323 | |
---|
275 | 324 | static inline u32 kvm_apic_calc_x2apic_ldr(u32 id) |
---|
.. | .. |
---|
285 | 334 | |
---|
286 | 335 | kvm_lapic_set_reg(apic, APIC_ID, id); |
---|
287 | 336 | kvm_lapic_set_reg(apic, APIC_LDR, ldr); |
---|
288 | | - recalculate_apic_map(apic->vcpu->kvm); |
---|
| 337 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); |
---|
289 | 338 | } |
---|
290 | 339 | |
---|
291 | 340 | static inline int apic_lvt_enabled(struct kvm_lapic *apic, int lvt_type) |
---|
292 | 341 | { |
---|
293 | 342 | return !(kvm_lapic_get_reg(apic, lvt_type) & APIC_LVT_MASKED); |
---|
294 | | -} |
---|
295 | | - |
---|
296 | | -static inline int apic_lvt_vector(struct kvm_lapic *apic, int lvt_type) |
---|
297 | | -{ |
---|
298 | | - return kvm_lapic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK; |
---|
299 | 343 | } |
---|
300 | 344 | |
---|
301 | 345 | static inline int apic_lvtt_oneshot(struct kvm_lapic *apic) |
---|
.. | .. |
---|
321 | 365 | void kvm_apic_set_version(struct kvm_vcpu *vcpu) |
---|
322 | 366 | { |
---|
323 | 367 | struct kvm_lapic *apic = vcpu->arch.apic; |
---|
324 | | - struct kvm_cpuid_entry2 *feat; |
---|
325 | 368 | u32 v = APIC_VERSION; |
---|
326 | 369 | |
---|
327 | 370 | if (!lapic_in_kernel(vcpu)) |
---|
.. | .. |
---|
334 | 377 | * version first and level-triggered interrupts never get EOIed in |
---|
335 | 378 | * IOAPIC. |
---|
336 | 379 | */ |
---|
337 | | - feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0); |
---|
338 | | - if (feat && (feat->ecx & (1 << (X86_FEATURE_X2APIC & 31))) && |
---|
| 380 | + if (guest_cpuid_has(vcpu, X86_FEATURE_X2APIC) && |
---|
339 | 381 | !ioapic_in_kernel(vcpu->kvm)) |
---|
340 | 382 | v |= APIC_LVR_DIRECTED_EOI; |
---|
341 | 383 | kvm_lapic_set_reg(apic, APIC_LVR, v); |
---|
.. | .. |
---|
446 | 488 | |
---|
447 | 489 | if (unlikely(vcpu->arch.apicv_active)) { |
---|
448 | 490 | /* need to update RVI */ |
---|
449 | | - apic_clear_vector(vec, apic->regs + APIC_IRR); |
---|
450 | | - kvm_x86_ops->hwapic_irr_update(vcpu, |
---|
| 491 | + kvm_lapic_clear_vector(vec, apic->regs + APIC_IRR); |
---|
| 492 | + kvm_x86_ops.hwapic_irr_update(vcpu, |
---|
451 | 493 | apic_find_highest_irr(apic)); |
---|
452 | 494 | } else { |
---|
453 | 495 | apic->irr_pending = false; |
---|
454 | | - apic_clear_vector(vec, apic->regs + APIC_IRR); |
---|
| 496 | + kvm_lapic_clear_vector(vec, apic->regs + APIC_IRR); |
---|
455 | 497 | if (apic_search_irr(apic) != -1) |
---|
456 | 498 | apic->irr_pending = true; |
---|
457 | 499 | } |
---|
458 | 500 | } |
---|
| 501 | + |
---|
| 502 | +void kvm_apic_clear_irr(struct kvm_vcpu *vcpu, int vec) |
---|
| 503 | +{ |
---|
| 504 | + apic_clear_irr(vec, vcpu->arch.apic); |
---|
| 505 | +} |
---|
| 506 | +EXPORT_SYMBOL_GPL(kvm_apic_clear_irr); |
---|
459 | 507 | |
---|
460 | 508 | static inline void apic_set_isr(int vec, struct kvm_lapic *apic) |
---|
461 | 509 | { |
---|
.. | .. |
---|
472 | 520 | * just set SVI. |
---|
473 | 521 | */ |
---|
474 | 522 | if (unlikely(vcpu->arch.apicv_active)) |
---|
475 | | - kvm_x86_ops->hwapic_isr_update(vcpu, vec); |
---|
| 523 | + kvm_x86_ops.hwapic_isr_update(vcpu, vec); |
---|
476 | 524 | else { |
---|
477 | 525 | ++apic->isr_count; |
---|
478 | 526 | BUG_ON(apic->isr_count > MAX_APIC_VECTOR); |
---|
.. | .. |
---|
520 | 568 | * and must be left alone. |
---|
521 | 569 | */ |
---|
522 | 570 | if (unlikely(vcpu->arch.apicv_active)) |
---|
523 | | - kvm_x86_ops->hwapic_isr_update(vcpu, |
---|
| 571 | + kvm_x86_ops.hwapic_isr_update(vcpu, |
---|
524 | 572 | apic_find_highest_isr(apic)); |
---|
525 | 573 | else { |
---|
526 | 574 | --apic->isr_count; |
---|
.. | .. |
---|
553 | 601 | irq->level, irq->trig_mode, dest_map); |
---|
554 | 602 | } |
---|
555 | 603 | |
---|
| 604 | +static int __pv_send_ipi(unsigned long *ipi_bitmap, struct kvm_apic_map *map, |
---|
| 605 | + struct kvm_lapic_irq *irq, u32 min) |
---|
| 606 | +{ |
---|
| 607 | + int i, count = 0; |
---|
| 608 | + struct kvm_vcpu *vcpu; |
---|
| 609 | + |
---|
| 610 | + if (min > map->max_apic_id) |
---|
| 611 | + return 0; |
---|
| 612 | + |
---|
| 613 | + for_each_set_bit(i, ipi_bitmap, |
---|
| 614 | + min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) { |
---|
| 615 | + if (map->phys_map[min + i]) { |
---|
| 616 | + vcpu = map->phys_map[min + i]->vcpu; |
---|
| 617 | + count += kvm_apic_set_irq(vcpu, irq, NULL); |
---|
| 618 | + } |
---|
| 619 | + } |
---|
| 620 | + |
---|
| 621 | + return count; |
---|
| 622 | +} |
---|
| 623 | + |
---|
556 | 624 | int kvm_pv_send_ipi(struct kvm *kvm, unsigned long ipi_bitmap_low, |
---|
557 | 625 | unsigned long ipi_bitmap_high, u32 min, |
---|
558 | 626 | unsigned long icr, int op_64_bit) |
---|
559 | 627 | { |
---|
560 | | - int i; |
---|
561 | 628 | struct kvm_apic_map *map; |
---|
562 | | - struct kvm_vcpu *vcpu; |
---|
563 | 629 | struct kvm_lapic_irq irq = {0}; |
---|
564 | 630 | int cluster_size = op_64_bit ? 64 : 32; |
---|
565 | | - int count = 0; |
---|
| 631 | + int count; |
---|
| 632 | + |
---|
| 633 | + if (icr & (APIC_DEST_MASK | APIC_SHORT_MASK)) |
---|
| 634 | + return -KVM_EINVAL; |
---|
566 | 635 | |
---|
567 | 636 | irq.vector = icr & APIC_VECTOR_MASK; |
---|
568 | 637 | irq.delivery_mode = icr & APIC_MODE_MASK; |
---|
569 | 638 | irq.level = (icr & APIC_INT_ASSERT) != 0; |
---|
570 | 639 | irq.trig_mode = icr & APIC_INT_LEVELTRIG; |
---|
571 | 640 | |
---|
572 | | - if (icr & APIC_DEST_MASK) |
---|
573 | | - return -KVM_EINVAL; |
---|
574 | | - if (icr & APIC_SHORT_MASK) |
---|
575 | | - return -KVM_EINVAL; |
---|
576 | | - |
---|
577 | 641 | rcu_read_lock(); |
---|
578 | 642 | map = rcu_dereference(kvm->arch.apic_map); |
---|
579 | 643 | |
---|
580 | | - if (unlikely(!map)) { |
---|
581 | | - count = -EOPNOTSUPP; |
---|
582 | | - goto out; |
---|
| 644 | + count = -EOPNOTSUPP; |
---|
| 645 | + if (likely(map)) { |
---|
| 646 | + count = __pv_send_ipi(&ipi_bitmap_low, map, &irq, min); |
---|
| 647 | + min += cluster_size; |
---|
| 648 | + count += __pv_send_ipi(&ipi_bitmap_high, map, &irq, min); |
---|
583 | 649 | } |
---|
584 | 650 | |
---|
585 | | - if (min > map->max_apic_id) |
---|
586 | | - goto out; |
---|
587 | | - /* Bits above cluster_size are masked in the caller. */ |
---|
588 | | - for_each_set_bit(i, &ipi_bitmap_low, |
---|
589 | | - min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) { |
---|
590 | | - if (map->phys_map[min + i]) { |
---|
591 | | - vcpu = map->phys_map[min + i]->vcpu; |
---|
592 | | - count += kvm_apic_set_irq(vcpu, &irq, NULL); |
---|
593 | | - } |
---|
594 | | - } |
---|
595 | | - |
---|
596 | | - min += cluster_size; |
---|
597 | | - |
---|
598 | | - if (min > map->max_apic_id) |
---|
599 | | - goto out; |
---|
600 | | - |
---|
601 | | - for_each_set_bit(i, &ipi_bitmap_high, |
---|
602 | | - min((u32)BITS_PER_LONG, (map->max_apic_id - min + 1))) { |
---|
603 | | - if (map->phys_map[min + i]) { |
---|
604 | | - vcpu = map->phys_map[min + i]->vcpu; |
---|
605 | | - count += kvm_apic_set_irq(vcpu, &irq, NULL); |
---|
606 | | - } |
---|
607 | | - } |
---|
608 | | - |
---|
609 | | -out: |
---|
610 | 651 | rcu_read_unlock(); |
---|
611 | 652 | return count; |
---|
612 | 653 | } |
---|
.. | .. |
---|
634 | 675 | { |
---|
635 | 676 | u8 val; |
---|
636 | 677 | if (pv_eoi_get_user(vcpu, &val) < 0) { |
---|
637 | | - apic_debug("Can't read EOI MSR value: 0x%llx\n", |
---|
| 678 | + printk(KERN_WARNING "Can't read EOI MSR value: 0x%llx\n", |
---|
638 | 679 | (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
---|
639 | 680 | return false; |
---|
640 | 681 | } |
---|
.. | .. |
---|
644 | 685 | static void pv_eoi_set_pending(struct kvm_vcpu *vcpu) |
---|
645 | 686 | { |
---|
646 | 687 | if (pv_eoi_put_user(vcpu, KVM_PV_EOI_ENABLED) < 0) { |
---|
647 | | - apic_debug("Can't set EOI MSR value: 0x%llx\n", |
---|
| 688 | + printk(KERN_WARNING "Can't set EOI MSR value: 0x%llx\n", |
---|
648 | 689 | (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
---|
649 | 690 | return; |
---|
650 | 691 | } |
---|
.. | .. |
---|
654 | 695 | static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu) |
---|
655 | 696 | { |
---|
656 | 697 | if (pv_eoi_put_user(vcpu, KVM_PV_EOI_DISABLED) < 0) { |
---|
657 | | - apic_debug("Can't clear EOI MSR value: 0x%llx\n", |
---|
| 698 | + printk(KERN_WARNING "Can't clear EOI MSR value: 0x%llx\n", |
---|
658 | 699 | (unsigned long long)vcpu->arch.pv_eoi.msr_val); |
---|
659 | 700 | return; |
---|
660 | 701 | } |
---|
.. | .. |
---|
665 | 706 | { |
---|
666 | 707 | int highest_irr; |
---|
667 | 708 | if (apic->vcpu->arch.apicv_active) |
---|
668 | | - highest_irr = kvm_x86_ops->sync_pir_to_irr(apic->vcpu); |
---|
| 709 | + highest_irr = kvm_x86_ops.sync_pir_to_irr(apic->vcpu); |
---|
669 | 710 | else |
---|
670 | 711 | highest_irr = apic_find_highest_irr(apic); |
---|
671 | 712 | if (highest_irr == -1 || (highest_irr & 0xF0) <= ppr) |
---|
.. | .. |
---|
687 | 728 | ppr = tpr & 0xff; |
---|
688 | 729 | else |
---|
689 | 730 | ppr = isrv & 0xf0; |
---|
690 | | - |
---|
691 | | - apic_debug("vlapic %p, ppr 0x%x, isr 0x%x, isrv 0x%x", |
---|
692 | | - apic, ppr, isr, isrv); |
---|
693 | 731 | |
---|
694 | 732 | *new_ppr = ppr; |
---|
695 | 733 | if (old_ppr != ppr) |
---|
.. | .. |
---|
767 | 805 | return ((logical_id >> 4) == (mda >> 4)) |
---|
768 | 806 | && (logical_id & mda & 0xf) != 0; |
---|
769 | 807 | default: |
---|
770 | | - apic_debug("Bad DFR vcpu %d: %08x\n", |
---|
771 | | - apic->vcpu->vcpu_id, kvm_lapic_get_reg(apic, APIC_DFR)); |
---|
772 | 808 | return false; |
---|
773 | 809 | } |
---|
774 | 810 | } |
---|
.. | .. |
---|
802 | 838 | } |
---|
803 | 839 | |
---|
804 | 840 | bool kvm_apic_match_dest(struct kvm_vcpu *vcpu, struct kvm_lapic *source, |
---|
805 | | - int short_hand, unsigned int dest, int dest_mode) |
---|
| 841 | + int shorthand, unsigned int dest, int dest_mode) |
---|
806 | 842 | { |
---|
807 | 843 | struct kvm_lapic *target = vcpu->arch.apic; |
---|
808 | 844 | u32 mda = kvm_apic_mda(vcpu, dest, source, target); |
---|
809 | 845 | |
---|
810 | | - apic_debug("target %p, source %p, dest 0x%x, " |
---|
811 | | - "dest_mode 0x%x, short_hand 0x%x\n", |
---|
812 | | - target, source, dest, dest_mode, short_hand); |
---|
813 | | - |
---|
814 | 846 | ASSERT(target); |
---|
815 | | - switch (short_hand) { |
---|
| 847 | + switch (shorthand) { |
---|
816 | 848 | case APIC_DEST_NOSHORT: |
---|
817 | 849 | if (dest_mode == APIC_DEST_PHYSICAL) |
---|
818 | 850 | return kvm_apic_match_physical_addr(target, mda); |
---|
.. | .. |
---|
825 | 857 | case APIC_DEST_ALLBUT: |
---|
826 | 858 | return target != source; |
---|
827 | 859 | default: |
---|
828 | | - apic_debug("kvm: apic: Bad dest shorthand value %x\n", |
---|
829 | | - short_hand); |
---|
830 | 860 | return false; |
---|
831 | 861 | } |
---|
832 | 862 | } |
---|
.. | .. |
---|
961 | 991 | *r = -1; |
---|
962 | 992 | |
---|
963 | 993 | if (irq->shorthand == APIC_DEST_SELF) { |
---|
| 994 | + if (KVM_BUG_ON(!src, kvm)) { |
---|
| 995 | + *r = 0; |
---|
| 996 | + return true; |
---|
| 997 | + } |
---|
964 | 998 | *r = kvm_apic_set_irq(src->vcpu, irq, dest_map); |
---|
965 | 999 | return true; |
---|
966 | 1000 | } |
---|
.. | .. |
---|
969 | 1003 | map = rcu_dereference(kvm->arch.apic_map); |
---|
970 | 1004 | |
---|
971 | 1005 | ret = kvm_apic_map_get_dest_lapic(kvm, &src, irq, map, &dst, &bitmap); |
---|
972 | | - if (ret) |
---|
| 1006 | + if (ret) { |
---|
| 1007 | + *r = 0; |
---|
973 | 1008 | for_each_set_bit(i, &bitmap, 16) { |
---|
974 | 1009 | if (!dst[i]) |
---|
975 | 1010 | continue; |
---|
976 | | - if (*r < 0) |
---|
977 | | - *r = 0; |
---|
978 | 1011 | *r += kvm_apic_set_irq(dst[i]->vcpu, irq, dest_map); |
---|
979 | 1012 | } |
---|
| 1013 | + } |
---|
980 | 1014 | |
---|
981 | 1015 | rcu_read_unlock(); |
---|
982 | 1016 | return ret; |
---|
983 | 1017 | } |
---|
984 | 1018 | |
---|
985 | 1019 | /* |
---|
986 | | - * This routine tries to handler interrupts in posted mode, here is how |
---|
| 1020 | + * This routine tries to handle interrupts in posted mode, here is how |
---|
987 | 1021 | * it deals with different cases: |
---|
988 | 1022 | * - For single-destination interrupts, handle it in posted mode |
---|
989 | 1023 | * - Else if vector hashing is enabled and it is a lowest-priority |
---|
990 | 1024 | * interrupt, handle it in posted mode and use the following mechanism |
---|
991 | | - * to find the destinaiton vCPU. |
---|
| 1025 | + * to find the destination vCPU. |
---|
992 | 1026 | * 1. For lowest-priority interrupts, store all the possible |
---|
993 | 1027 | * destination vCPUs in an array. |
---|
994 | 1028 | * 2. Use "guest vector % max number of destination vCPUs" to find |
---|
.. | .. |
---|
1040 | 1074 | switch (delivery_mode) { |
---|
1041 | 1075 | case APIC_DM_LOWEST: |
---|
1042 | 1076 | vcpu->arch.apic_arb_prio++; |
---|
| 1077 | + fallthrough; |
---|
1043 | 1078 | case APIC_DM_FIXED: |
---|
1044 | 1079 | if (unlikely(trig_mode && !level)) |
---|
1045 | 1080 | break; |
---|
.. | .. |
---|
1057 | 1092 | |
---|
1058 | 1093 | if (apic_test_vector(vector, apic->regs + APIC_TMR) != !!trig_mode) { |
---|
1059 | 1094 | if (trig_mode) |
---|
1060 | | - kvm_lapic_set_vector(vector, apic->regs + APIC_TMR); |
---|
| 1095 | + kvm_lapic_set_vector(vector, |
---|
| 1096 | + apic->regs + APIC_TMR); |
---|
1061 | 1097 | else |
---|
1062 | | - apic_clear_vector(vector, apic->regs + APIC_TMR); |
---|
| 1098 | + kvm_lapic_clear_vector(vector, |
---|
| 1099 | + apic->regs + APIC_TMR); |
---|
1063 | 1100 | } |
---|
1064 | 1101 | |
---|
1065 | | - if (kvm_x86_ops->deliver_posted_interrupt(vcpu, vector)) { |
---|
| 1102 | + if (kvm_x86_ops.deliver_posted_interrupt(vcpu, vector)) { |
---|
1066 | 1103 | kvm_lapic_set_irr(vector, apic); |
---|
1067 | 1104 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
---|
1068 | 1105 | kvm_vcpu_kick(vcpu); |
---|
.. | .. |
---|
1093 | 1130 | result = 1; |
---|
1094 | 1131 | /* assumes that there are only KVM_APIC_INIT/SIPI */ |
---|
1095 | 1132 | apic->pending_events = (1UL << KVM_APIC_INIT); |
---|
1096 | | - /* make sure pending_events is visible before sending |
---|
1097 | | - * the request */ |
---|
1098 | | - smp_wmb(); |
---|
1099 | 1133 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
---|
1100 | 1134 | kvm_vcpu_kick(vcpu); |
---|
1101 | | - } else { |
---|
1102 | | - apic_debug("Ignoring de-assert INIT to vcpu %d\n", |
---|
1103 | | - vcpu->vcpu_id); |
---|
1104 | 1135 | } |
---|
1105 | 1136 | break; |
---|
1106 | 1137 | |
---|
1107 | 1138 | case APIC_DM_STARTUP: |
---|
1108 | | - apic_debug("SIPI to vcpu %d vector 0x%02x\n", |
---|
1109 | | - vcpu->vcpu_id, vector); |
---|
1110 | 1139 | result = 1; |
---|
1111 | 1140 | apic->sipi_vector = vector; |
---|
1112 | 1141 | /* make sure sipi_vector is visible for the receiver */ |
---|
.. | .. |
---|
1130 | 1159 | break; |
---|
1131 | 1160 | } |
---|
1132 | 1161 | return result; |
---|
| 1162 | +} |
---|
| 1163 | + |
---|
| 1164 | +/* |
---|
| 1165 | + * This routine identifies the destination vcpus mask meant to receive the |
---|
| 1166 | + * IOAPIC interrupts. It either uses kvm_apic_map_get_dest_lapic() to find |
---|
| 1167 | + * out the destination vcpus array and set the bitmap or it traverses to |
---|
| 1168 | + * each available vcpu to identify the same. |
---|
| 1169 | + */ |
---|
| 1170 | +void kvm_bitmap_or_dest_vcpus(struct kvm *kvm, struct kvm_lapic_irq *irq, |
---|
| 1171 | + unsigned long *vcpu_bitmap) |
---|
| 1172 | +{ |
---|
| 1173 | + struct kvm_lapic **dest_vcpu = NULL; |
---|
| 1174 | + struct kvm_lapic *src = NULL; |
---|
| 1175 | + struct kvm_apic_map *map; |
---|
| 1176 | + struct kvm_vcpu *vcpu; |
---|
| 1177 | + unsigned long bitmap; |
---|
| 1178 | + int i, vcpu_idx; |
---|
| 1179 | + bool ret; |
---|
| 1180 | + |
---|
| 1181 | + rcu_read_lock(); |
---|
| 1182 | + map = rcu_dereference(kvm->arch.apic_map); |
---|
| 1183 | + |
---|
| 1184 | + ret = kvm_apic_map_get_dest_lapic(kvm, &src, irq, map, &dest_vcpu, |
---|
| 1185 | + &bitmap); |
---|
| 1186 | + if (ret) { |
---|
| 1187 | + for_each_set_bit(i, &bitmap, 16) { |
---|
| 1188 | + if (!dest_vcpu[i]) |
---|
| 1189 | + continue; |
---|
| 1190 | + vcpu_idx = dest_vcpu[i]->vcpu->vcpu_idx; |
---|
| 1191 | + __set_bit(vcpu_idx, vcpu_bitmap); |
---|
| 1192 | + } |
---|
| 1193 | + } else { |
---|
| 1194 | + kvm_for_each_vcpu(i, vcpu, kvm) { |
---|
| 1195 | + if (!kvm_apic_present(vcpu)) |
---|
| 1196 | + continue; |
---|
| 1197 | + if (!kvm_apic_match_dest(vcpu, NULL, |
---|
| 1198 | + irq->shorthand, |
---|
| 1199 | + irq->dest_id, |
---|
| 1200 | + irq->dest_mode)) |
---|
| 1201 | + continue; |
---|
| 1202 | + __set_bit(i, vcpu_bitmap); |
---|
| 1203 | + } |
---|
| 1204 | + } |
---|
| 1205 | + rcu_read_unlock(); |
---|
1133 | 1206 | } |
---|
1134 | 1207 | |
---|
1135 | 1208 | int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2) |
---|
.. | .. |
---|
1204 | 1277 | } |
---|
1205 | 1278 | EXPORT_SYMBOL_GPL(kvm_apic_set_eoi_accelerated); |
---|
1206 | 1279 | |
---|
1207 | | -static void apic_send_ipi(struct kvm_lapic *apic) |
---|
| 1280 | +void kvm_apic_send_ipi(struct kvm_lapic *apic, u32 icr_low, u32 icr_high) |
---|
1208 | 1281 | { |
---|
1209 | | - u32 icr_low = kvm_lapic_get_reg(apic, APIC_ICR); |
---|
1210 | | - u32 icr_high = kvm_lapic_get_reg(apic, APIC_ICR2); |
---|
1211 | 1282 | struct kvm_lapic_irq irq; |
---|
1212 | 1283 | |
---|
1213 | 1284 | irq.vector = icr_low & APIC_VECTOR_MASK; |
---|
.. | .. |
---|
1223 | 1294 | irq.dest_id = GET_APIC_DEST_FIELD(icr_high); |
---|
1224 | 1295 | |
---|
1225 | 1296 | trace_kvm_apic_ipi(icr_low, irq.dest_id); |
---|
1226 | | - |
---|
1227 | | - apic_debug("icr_high 0x%x, icr_low 0x%x, " |
---|
1228 | | - "short_hand 0x%x, dest 0x%x, trig_mode 0x%x, level 0x%x, " |
---|
1229 | | - "dest_mode 0x%x, delivery_mode 0x%x, vector 0x%x, " |
---|
1230 | | - "msi_redir_hint 0x%x\n", |
---|
1231 | | - icr_high, icr_low, irq.shorthand, irq.dest_id, |
---|
1232 | | - irq.trig_mode, irq.level, irq.dest_mode, irq.delivery_mode, |
---|
1233 | | - irq.vector, irq.msi_redir_hint); |
---|
1234 | 1297 | |
---|
1235 | 1298 | kvm_irq_delivery_to_apic(apic->vcpu->kvm, apic, &irq, NULL); |
---|
1236 | 1299 | } |
---|
.. | .. |
---|
1285 | 1348 | |
---|
1286 | 1349 | switch (offset) { |
---|
1287 | 1350 | case APIC_ARBPRI: |
---|
1288 | | - apic_debug("Access APIC ARBPRI register which is for P6\n"); |
---|
1289 | 1351 | break; |
---|
1290 | 1352 | |
---|
1291 | 1353 | case APIC_TMCCT: /* Timer CCR */ |
---|
.. | .. |
---|
1300 | 1362 | break; |
---|
1301 | 1363 | case APIC_TASKPRI: |
---|
1302 | 1364 | report_tpr_access(apic, false); |
---|
1303 | | - /* fall thru */ |
---|
| 1365 | + fallthrough; |
---|
1304 | 1366 | default: |
---|
1305 | 1367 | val = kvm_lapic_get_reg(apic, offset); |
---|
1306 | 1368 | break; |
---|
.. | .. |
---|
1314 | 1376 | return container_of(dev, struct kvm_lapic, dev); |
---|
1315 | 1377 | } |
---|
1316 | 1378 | |
---|
| 1379 | +#define APIC_REG_MASK(reg) (1ull << ((reg) >> 4)) |
---|
| 1380 | +#define APIC_REGS_MASK(first, count) \ |
---|
| 1381 | + (APIC_REG_MASK(first) * ((1ull << (count)) - 1)) |
---|
| 1382 | + |
---|
1317 | 1383 | int kvm_lapic_reg_read(struct kvm_lapic *apic, u32 offset, int len, |
---|
1318 | 1384 | void *data) |
---|
1319 | 1385 | { |
---|
1320 | 1386 | unsigned char alignment = offset & 0xf; |
---|
1321 | 1387 | u32 result; |
---|
1322 | 1388 | /* this bitmask has a bit cleared for each reserved register */ |
---|
1323 | | - static const u64 rmask = 0x43ff01ffffffe70cULL; |
---|
| 1389 | + u64 valid_reg_mask = |
---|
| 1390 | + APIC_REG_MASK(APIC_ID) | |
---|
| 1391 | + APIC_REG_MASK(APIC_LVR) | |
---|
| 1392 | + APIC_REG_MASK(APIC_TASKPRI) | |
---|
| 1393 | + APIC_REG_MASK(APIC_PROCPRI) | |
---|
| 1394 | + APIC_REG_MASK(APIC_LDR) | |
---|
| 1395 | + APIC_REG_MASK(APIC_DFR) | |
---|
| 1396 | + APIC_REG_MASK(APIC_SPIV) | |
---|
| 1397 | + APIC_REGS_MASK(APIC_ISR, APIC_ISR_NR) | |
---|
| 1398 | + APIC_REGS_MASK(APIC_TMR, APIC_ISR_NR) | |
---|
| 1399 | + APIC_REGS_MASK(APIC_IRR, APIC_ISR_NR) | |
---|
| 1400 | + APIC_REG_MASK(APIC_ESR) | |
---|
| 1401 | + APIC_REG_MASK(APIC_ICR) | |
---|
| 1402 | + APIC_REG_MASK(APIC_ICR2) | |
---|
| 1403 | + APIC_REG_MASK(APIC_LVTT) | |
---|
| 1404 | + APIC_REG_MASK(APIC_LVTTHMR) | |
---|
| 1405 | + APIC_REG_MASK(APIC_LVTPC) | |
---|
| 1406 | + APIC_REG_MASK(APIC_LVT0) | |
---|
| 1407 | + APIC_REG_MASK(APIC_LVT1) | |
---|
| 1408 | + APIC_REG_MASK(APIC_LVTERR) | |
---|
| 1409 | + APIC_REG_MASK(APIC_TMICT) | |
---|
| 1410 | + APIC_REG_MASK(APIC_TMCCT) | |
---|
| 1411 | + APIC_REG_MASK(APIC_TDCR); |
---|
1324 | 1412 | |
---|
1325 | | - if ((alignment + len) > 4) { |
---|
1326 | | - apic_debug("KVM_APIC_READ: alignment error %x %d\n", |
---|
1327 | | - offset, len); |
---|
1328 | | - return 1; |
---|
1329 | | - } |
---|
| 1413 | + /* ARBPRI is not valid on x2APIC */ |
---|
| 1414 | + if (!apic_x2apic_mode(apic)) |
---|
| 1415 | + valid_reg_mask |= APIC_REG_MASK(APIC_ARBPRI); |
---|
1330 | 1416 | |
---|
1331 | | - if (offset > 0x3f0 || !(rmask & (1ULL << (offset >> 4)))) { |
---|
1332 | | - apic_debug("KVM_APIC_READ: read reserved register %x\n", |
---|
1333 | | - offset); |
---|
| 1417 | + if (alignment + len > 4) |
---|
1334 | 1418 | return 1; |
---|
1335 | | - } |
---|
| 1419 | + |
---|
| 1420 | + if (offset > 0x3f0 || !(valid_reg_mask & APIC_REG_MASK(offset))) |
---|
| 1421 | + return 1; |
---|
1336 | 1422 | |
---|
1337 | 1423 | result = __apic_read(apic, offset & ~0xf); |
---|
1338 | 1424 | |
---|
.. | .. |
---|
1390 | 1476 | tmp1 = tdcr & 0xf; |
---|
1391 | 1477 | tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1; |
---|
1392 | 1478 | apic->divide_count = 0x1 << (tmp2 & 0x7); |
---|
1393 | | - |
---|
1394 | | - apic_debug("timer divide count is 0x%x\n", |
---|
1395 | | - apic->divide_count); |
---|
1396 | 1479 | } |
---|
1397 | 1480 | |
---|
1398 | 1481 | static void limit_periodic_timer_frequency(struct kvm_lapic *apic) |
---|
.. | .. |
---|
1416 | 1499 | } |
---|
1417 | 1500 | } |
---|
1418 | 1501 | |
---|
| 1502 | +static void cancel_hv_timer(struct kvm_lapic *apic); |
---|
| 1503 | + |
---|
1419 | 1504 | static void apic_update_lvtt(struct kvm_lapic *apic) |
---|
1420 | 1505 | { |
---|
1421 | 1506 | u32 timer_mode = kvm_lapic_get_reg(apic, APIC_LVTT) & |
---|
.. | .. |
---|
1425 | 1510 | if (apic_lvtt_tscdeadline(apic) != (timer_mode == |
---|
1426 | 1511 | APIC_LVT_TIMER_TSCDEADLINE)) { |
---|
1427 | 1512 | hrtimer_cancel(&apic->lapic_timer.timer); |
---|
| 1513 | + preempt_disable(); |
---|
| 1514 | + if (apic->lapic_timer.hv_timer_in_use) |
---|
| 1515 | + cancel_hv_timer(apic); |
---|
| 1516 | + preempt_enable(); |
---|
1428 | 1517 | kvm_lapic_set_reg(apic, APIC_TMICT, 0); |
---|
1429 | 1518 | apic->lapic_timer.period = 0; |
---|
1430 | 1519 | apic->lapic_timer.tscdeadline = 0; |
---|
.. | .. |
---|
1432 | 1521 | apic->lapic_timer.timer_mode = timer_mode; |
---|
1433 | 1522 | limit_periodic_timer_frequency(apic); |
---|
1434 | 1523 | } |
---|
1435 | | -} |
---|
1436 | | - |
---|
1437 | | -static void apic_timer_expired(struct kvm_lapic *apic) |
---|
1438 | | -{ |
---|
1439 | | - struct kvm_vcpu *vcpu = apic->vcpu; |
---|
1440 | | - struct swait_queue_head *q = &vcpu->wq; |
---|
1441 | | - struct kvm_timer *ktimer = &apic->lapic_timer; |
---|
1442 | | - |
---|
1443 | | - if (atomic_read(&apic->lapic_timer.pending)) |
---|
1444 | | - return; |
---|
1445 | | - |
---|
1446 | | - atomic_inc(&apic->lapic_timer.pending); |
---|
1447 | | - kvm_set_pending_timer(vcpu); |
---|
1448 | | - |
---|
1449 | | - /* |
---|
1450 | | - * For x86, the atomic_inc() is serialized, thus |
---|
1451 | | - * using swait_active() is safe. |
---|
1452 | | - */ |
---|
1453 | | - if (swait_active(q)) |
---|
1454 | | - swake_up_one(q); |
---|
1455 | | - |
---|
1456 | | - if (apic_lvtt_tscdeadline(apic) || ktimer->hv_timer_in_use) |
---|
1457 | | - ktimer->expired_tscdeadline = ktimer->tscdeadline; |
---|
1458 | 1524 | } |
---|
1459 | 1525 | |
---|
1460 | 1526 | /* |
---|
.. | .. |
---|
1480 | 1546 | return false; |
---|
1481 | 1547 | } |
---|
1482 | 1548 | |
---|
1483 | | -void wait_lapic_expire(struct kvm_vcpu *vcpu) |
---|
| 1549 | +static inline void __wait_lapic_expire(struct kvm_vcpu *vcpu, u64 guest_cycles) |
---|
| 1550 | +{ |
---|
| 1551 | + u64 timer_advance_ns = vcpu->arch.apic->lapic_timer.timer_advance_ns; |
---|
| 1552 | + |
---|
| 1553 | + /* |
---|
| 1554 | + * If the guest TSC is running at a different ratio than the host, then |
---|
| 1555 | + * convert the delay to nanoseconds to achieve an accurate delay. Note |
---|
| 1556 | + * that __delay() uses delay_tsc whenever the hardware has TSC, thus |
---|
| 1557 | + * always for VMX enabled hardware. |
---|
| 1558 | + */ |
---|
| 1559 | + if (vcpu->arch.tsc_scaling_ratio == kvm_default_tsc_scaling_ratio) { |
---|
| 1560 | + __delay(min(guest_cycles, |
---|
| 1561 | + nsec_to_cycles(vcpu, timer_advance_ns))); |
---|
| 1562 | + } else { |
---|
| 1563 | + u64 delay_ns = guest_cycles * 1000000ULL; |
---|
| 1564 | + do_div(delay_ns, vcpu->arch.virtual_tsc_khz); |
---|
| 1565 | + ndelay(min_t(u32, delay_ns, timer_advance_ns)); |
---|
| 1566 | + } |
---|
| 1567 | +} |
---|
| 1568 | + |
---|
| 1569 | +static inline void adjust_lapic_timer_advance(struct kvm_vcpu *vcpu, |
---|
| 1570 | + s64 advance_expire_delta) |
---|
| 1571 | +{ |
---|
| 1572 | + struct kvm_lapic *apic = vcpu->arch.apic; |
---|
| 1573 | + u32 timer_advance_ns = apic->lapic_timer.timer_advance_ns; |
---|
| 1574 | + u64 ns; |
---|
| 1575 | + |
---|
| 1576 | + /* Do not adjust for tiny fluctuations or large random spikes. */ |
---|
| 1577 | + if (abs(advance_expire_delta) > LAPIC_TIMER_ADVANCE_ADJUST_MAX || |
---|
| 1578 | + abs(advance_expire_delta) < LAPIC_TIMER_ADVANCE_ADJUST_MIN) |
---|
| 1579 | + return; |
---|
| 1580 | + |
---|
| 1581 | + /* too early */ |
---|
| 1582 | + if (advance_expire_delta < 0) { |
---|
| 1583 | + ns = -advance_expire_delta * 1000000ULL; |
---|
| 1584 | + do_div(ns, vcpu->arch.virtual_tsc_khz); |
---|
| 1585 | + timer_advance_ns -= ns/LAPIC_TIMER_ADVANCE_ADJUST_STEP; |
---|
| 1586 | + } else { |
---|
| 1587 | + /* too late */ |
---|
| 1588 | + ns = advance_expire_delta * 1000000ULL; |
---|
| 1589 | + do_div(ns, vcpu->arch.virtual_tsc_khz); |
---|
| 1590 | + timer_advance_ns += ns/LAPIC_TIMER_ADVANCE_ADJUST_STEP; |
---|
| 1591 | + } |
---|
| 1592 | + |
---|
| 1593 | + if (unlikely(timer_advance_ns > LAPIC_TIMER_ADVANCE_NS_MAX)) |
---|
| 1594 | + timer_advance_ns = LAPIC_TIMER_ADVANCE_NS_INIT; |
---|
| 1595 | + apic->lapic_timer.timer_advance_ns = timer_advance_ns; |
---|
| 1596 | +} |
---|
| 1597 | + |
---|
| 1598 | +static void __kvm_wait_lapic_expire(struct kvm_vcpu *vcpu) |
---|
1484 | 1599 | { |
---|
1485 | 1600 | struct kvm_lapic *apic = vcpu->arch.apic; |
---|
1486 | 1601 | u64 guest_tsc, tsc_deadline; |
---|
1487 | 1602 | |
---|
1488 | | - if (!lapic_in_kernel(vcpu)) |
---|
1489 | | - return; |
---|
1490 | | - |
---|
1491 | | - if (apic->lapic_timer.expired_tscdeadline == 0) |
---|
1492 | | - return; |
---|
1493 | | - |
---|
1494 | | - if (!lapic_timer_int_injected(vcpu)) |
---|
1495 | | - return; |
---|
1496 | | - |
---|
1497 | 1603 | tsc_deadline = apic->lapic_timer.expired_tscdeadline; |
---|
1498 | 1604 | apic->lapic_timer.expired_tscdeadline = 0; |
---|
1499 | 1605 | guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc()); |
---|
1500 | | - trace_kvm_wait_lapic_expire(vcpu->vcpu_id, guest_tsc - tsc_deadline); |
---|
| 1606 | + apic->lapic_timer.advance_expire_delta = guest_tsc - tsc_deadline; |
---|
1501 | 1607 | |
---|
1502 | | - /* __delay is delay_tsc whenever the hardware has TSC, thus always. */ |
---|
1503 | 1608 | if (guest_tsc < tsc_deadline) |
---|
1504 | | - __delay(min(tsc_deadline - guest_tsc, |
---|
1505 | | - nsec_to_cycles(vcpu, lapic_timer_advance_ns))); |
---|
| 1609 | + __wait_lapic_expire(vcpu, tsc_deadline - guest_tsc); |
---|
| 1610 | + |
---|
| 1611 | + if (lapic_timer_advance_dynamic) |
---|
| 1612 | + adjust_lapic_timer_advance(vcpu, apic->lapic_timer.advance_expire_delta); |
---|
| 1613 | +} |
---|
| 1614 | + |
---|
| 1615 | +void kvm_wait_lapic_expire(struct kvm_vcpu *vcpu) |
---|
| 1616 | +{ |
---|
| 1617 | + if (lapic_in_kernel(vcpu) && |
---|
| 1618 | + vcpu->arch.apic->lapic_timer.expired_tscdeadline && |
---|
| 1619 | + vcpu->arch.apic->lapic_timer.timer_advance_ns && |
---|
| 1620 | + lapic_timer_int_injected(vcpu)) |
---|
| 1621 | + __kvm_wait_lapic_expire(vcpu); |
---|
| 1622 | +} |
---|
| 1623 | +EXPORT_SYMBOL_GPL(kvm_wait_lapic_expire); |
---|
| 1624 | + |
---|
| 1625 | +static void kvm_apic_inject_pending_timer_irqs(struct kvm_lapic *apic) |
---|
| 1626 | +{ |
---|
| 1627 | + struct kvm_timer *ktimer = &apic->lapic_timer; |
---|
| 1628 | + |
---|
| 1629 | + kvm_apic_local_deliver(apic, APIC_LVTT); |
---|
| 1630 | + if (apic_lvtt_tscdeadline(apic)) { |
---|
| 1631 | + ktimer->tscdeadline = 0; |
---|
| 1632 | + } else if (apic_lvtt_oneshot(apic)) { |
---|
| 1633 | + ktimer->tscdeadline = 0; |
---|
| 1634 | + ktimer->target_expiration = 0; |
---|
| 1635 | + } |
---|
| 1636 | +} |
---|
| 1637 | + |
---|
| 1638 | +static void apic_timer_expired(struct kvm_lapic *apic, bool from_timer_fn) |
---|
| 1639 | +{ |
---|
| 1640 | + struct kvm_vcpu *vcpu = apic->vcpu; |
---|
| 1641 | + struct kvm_timer *ktimer = &apic->lapic_timer; |
---|
| 1642 | + |
---|
| 1643 | + if (atomic_read(&apic->lapic_timer.pending)) |
---|
| 1644 | + return; |
---|
| 1645 | + |
---|
| 1646 | + if (apic_lvtt_tscdeadline(apic) || ktimer->hv_timer_in_use) |
---|
| 1647 | + ktimer->expired_tscdeadline = ktimer->tscdeadline; |
---|
| 1648 | + |
---|
| 1649 | + if (!from_timer_fn && vcpu->arch.apicv_active) { |
---|
| 1650 | + WARN_ON(kvm_get_running_vcpu() != vcpu); |
---|
| 1651 | + kvm_apic_inject_pending_timer_irqs(apic); |
---|
| 1652 | + return; |
---|
| 1653 | + } |
---|
| 1654 | + |
---|
| 1655 | + if (kvm_use_posted_timer_interrupt(apic->vcpu)) { |
---|
| 1656 | + /* |
---|
| 1657 | + * Ensure the guest's timer has truly expired before posting an |
---|
| 1658 | + * interrupt. Open code the relevant checks to avoid querying |
---|
| 1659 | + * lapic_timer_int_injected(), which will be false since the |
---|
| 1660 | + * interrupt isn't yet injected. Waiting until after injecting |
---|
| 1661 | + * is not an option since that won't help a posted interrupt. |
---|
| 1662 | + */ |
---|
| 1663 | + if (vcpu->arch.apic->lapic_timer.expired_tscdeadline && |
---|
| 1664 | + vcpu->arch.apic->lapic_timer.timer_advance_ns) |
---|
| 1665 | + __kvm_wait_lapic_expire(vcpu); |
---|
| 1666 | + kvm_apic_inject_pending_timer_irqs(apic); |
---|
| 1667 | + return; |
---|
| 1668 | + } |
---|
| 1669 | + |
---|
| 1670 | + atomic_inc(&apic->lapic_timer.pending); |
---|
| 1671 | + kvm_make_request(KVM_REQ_PENDING_TIMER, vcpu); |
---|
| 1672 | + if (from_timer_fn) |
---|
| 1673 | + kvm_vcpu_kick(vcpu); |
---|
1506 | 1674 | } |
---|
1507 | 1675 | |
---|
1508 | 1676 | static void start_sw_tscdeadline(struct kvm_lapic *apic) |
---|
1509 | 1677 | { |
---|
1510 | | - u64 guest_tsc, tscdeadline = apic->lapic_timer.tscdeadline; |
---|
| 1678 | + struct kvm_timer *ktimer = &apic->lapic_timer; |
---|
| 1679 | + u64 guest_tsc, tscdeadline = ktimer->tscdeadline; |
---|
1511 | 1680 | u64 ns = 0; |
---|
1512 | 1681 | ktime_t expire; |
---|
1513 | 1682 | struct kvm_vcpu *vcpu = apic->vcpu; |
---|
.. | .. |
---|
1522 | 1691 | |
---|
1523 | 1692 | now = ktime_get(); |
---|
1524 | 1693 | guest_tsc = kvm_read_l1_tsc(vcpu, rdtsc()); |
---|
1525 | | - if (likely(tscdeadline > guest_tsc)) { |
---|
1526 | | - ns = (tscdeadline - guest_tsc) * 1000000ULL; |
---|
1527 | | - do_div(ns, this_tsc_khz); |
---|
| 1694 | + |
---|
| 1695 | + ns = (tscdeadline - guest_tsc) * 1000000ULL; |
---|
| 1696 | + do_div(ns, this_tsc_khz); |
---|
| 1697 | + |
---|
| 1698 | + if (likely(tscdeadline > guest_tsc) && |
---|
| 1699 | + likely(ns > apic->lapic_timer.timer_advance_ns)) { |
---|
1528 | 1700 | expire = ktime_add_ns(now, ns); |
---|
1529 | | - expire = ktime_sub_ns(expire, lapic_timer_advance_ns); |
---|
1530 | | - hrtimer_start(&apic->lapic_timer.timer, |
---|
1531 | | - expire, HRTIMER_MODE_ABS_PINNED); |
---|
| 1701 | + expire = ktime_sub_ns(expire, ktimer->timer_advance_ns); |
---|
| 1702 | + hrtimer_start(&ktimer->timer, expire, HRTIMER_MODE_ABS_HARD); |
---|
1532 | 1703 | } else |
---|
1533 | | - apic_timer_expired(apic); |
---|
| 1704 | + apic_timer_expired(apic, false); |
---|
1534 | 1705 | |
---|
1535 | 1706 | local_irq_restore(flags); |
---|
| 1707 | +} |
---|
| 1708 | + |
---|
| 1709 | +static inline u64 tmict_to_ns(struct kvm_lapic *apic, u32 tmict) |
---|
| 1710 | +{ |
---|
| 1711 | + return (u64)tmict * APIC_BUS_CYCLE_NS * (u64)apic->divide_count; |
---|
1536 | 1712 | } |
---|
1537 | 1713 | |
---|
1538 | 1714 | static void update_target_expiration(struct kvm_lapic *apic, uint32_t old_divisor) |
---|
.. | .. |
---|
1540 | 1716 | ktime_t now, remaining; |
---|
1541 | 1717 | u64 ns_remaining_old, ns_remaining_new; |
---|
1542 | 1718 | |
---|
1543 | | - apic->lapic_timer.period = (u64)kvm_lapic_get_reg(apic, APIC_TMICT) |
---|
1544 | | - * APIC_BUS_CYCLE_NS * apic->divide_count; |
---|
| 1719 | + apic->lapic_timer.period = |
---|
| 1720 | + tmict_to_ns(apic, kvm_lapic_get_reg(apic, APIC_TMICT)); |
---|
1545 | 1721 | limit_periodic_timer_frequency(apic); |
---|
1546 | 1722 | |
---|
1547 | 1723 | now = ktime_get(); |
---|
.. | .. |
---|
1559 | 1735 | apic->lapic_timer.target_expiration = ktime_add_ns(now, ns_remaining_new); |
---|
1560 | 1736 | } |
---|
1561 | 1737 | |
---|
1562 | | -static bool set_target_expiration(struct kvm_lapic *apic) |
---|
| 1738 | +static bool set_target_expiration(struct kvm_lapic *apic, u32 count_reg) |
---|
1563 | 1739 | { |
---|
1564 | 1740 | ktime_t now; |
---|
1565 | 1741 | u64 tscl = rdtsc(); |
---|
| 1742 | + s64 deadline; |
---|
1566 | 1743 | |
---|
1567 | 1744 | now = ktime_get(); |
---|
1568 | | - apic->lapic_timer.period = (u64)kvm_lapic_get_reg(apic, APIC_TMICT) |
---|
1569 | | - * APIC_BUS_CYCLE_NS * apic->divide_count; |
---|
| 1745 | + apic->lapic_timer.period = |
---|
| 1746 | + tmict_to_ns(apic, kvm_lapic_get_reg(apic, APIC_TMICT)); |
---|
1570 | 1747 | |
---|
1571 | 1748 | if (!apic->lapic_timer.period) { |
---|
1572 | 1749 | apic->lapic_timer.tscdeadline = 0; |
---|
.. | .. |
---|
1574 | 1751 | } |
---|
1575 | 1752 | |
---|
1576 | 1753 | limit_periodic_timer_frequency(apic); |
---|
| 1754 | + deadline = apic->lapic_timer.period; |
---|
1577 | 1755 | |
---|
1578 | | - apic_debug("%s: bus cycle is %" PRId64 "ns, now 0x%016" |
---|
1579 | | - PRIx64 ", " |
---|
1580 | | - "timer initial count 0x%x, period %lldns, " |
---|
1581 | | - "expire @ 0x%016" PRIx64 ".\n", __func__, |
---|
1582 | | - APIC_BUS_CYCLE_NS, ktime_to_ns(now), |
---|
1583 | | - kvm_lapic_get_reg(apic, APIC_TMICT), |
---|
1584 | | - apic->lapic_timer.period, |
---|
1585 | | - ktime_to_ns(ktime_add_ns(now, |
---|
1586 | | - apic->lapic_timer.period))); |
---|
| 1756 | + if (apic_lvtt_period(apic) || apic_lvtt_oneshot(apic)) { |
---|
| 1757 | + if (unlikely(count_reg != APIC_TMICT)) { |
---|
| 1758 | + deadline = tmict_to_ns(apic, |
---|
| 1759 | + kvm_lapic_get_reg(apic, count_reg)); |
---|
| 1760 | + if (unlikely(deadline <= 0)) |
---|
| 1761 | + deadline = apic->lapic_timer.period; |
---|
| 1762 | + else if (unlikely(deadline > apic->lapic_timer.period)) { |
---|
| 1763 | + pr_info_ratelimited( |
---|
| 1764 | + "kvm: vcpu %i: requested lapic timer restore with " |
---|
| 1765 | + "starting count register %#x=%u (%lld ns) > initial count (%lld ns). " |
---|
| 1766 | + "Using initial count to start timer.\n", |
---|
| 1767 | + apic->vcpu->vcpu_id, |
---|
| 1768 | + count_reg, |
---|
| 1769 | + kvm_lapic_get_reg(apic, count_reg), |
---|
| 1770 | + deadline, apic->lapic_timer.period); |
---|
| 1771 | + kvm_lapic_set_reg(apic, count_reg, 0); |
---|
| 1772 | + deadline = apic->lapic_timer.period; |
---|
| 1773 | + } |
---|
| 1774 | + } |
---|
| 1775 | + } |
---|
1587 | 1776 | |
---|
1588 | 1777 | apic->lapic_timer.tscdeadline = kvm_read_l1_tsc(apic->vcpu, tscl) + |
---|
1589 | | - nsec_to_cycles(apic->vcpu, apic->lapic_timer.period); |
---|
1590 | | - apic->lapic_timer.target_expiration = ktime_add_ns(now, apic->lapic_timer.period); |
---|
| 1778 | + nsec_to_cycles(apic->vcpu, deadline); |
---|
| 1779 | + apic->lapic_timer.target_expiration = ktime_add_ns(now, deadline); |
---|
1591 | 1780 | |
---|
1592 | 1781 | return true; |
---|
1593 | 1782 | } |
---|
.. | .. |
---|
1620 | 1809 | |
---|
1621 | 1810 | if (ktime_after(ktime_get(), |
---|
1622 | 1811 | apic->lapic_timer.target_expiration)) { |
---|
1623 | | - apic_timer_expired(apic); |
---|
| 1812 | + apic_timer_expired(apic, false); |
---|
1624 | 1813 | |
---|
1625 | 1814 | if (apic_lvtt_oneshot(apic)) |
---|
1626 | 1815 | return; |
---|
.. | .. |
---|
1630 | 1819 | |
---|
1631 | 1820 | hrtimer_start(&apic->lapic_timer.timer, |
---|
1632 | 1821 | apic->lapic_timer.target_expiration, |
---|
1633 | | - HRTIMER_MODE_ABS_PINNED); |
---|
| 1822 | + HRTIMER_MODE_ABS_HARD); |
---|
1634 | 1823 | } |
---|
1635 | 1824 | |
---|
1636 | 1825 | bool kvm_lapic_hv_timer_in_use(struct kvm_vcpu *vcpu) |
---|
.. | .. |
---|
1646 | 1835 | { |
---|
1647 | 1836 | WARN_ON(preemptible()); |
---|
1648 | 1837 | WARN_ON(!apic->lapic_timer.hv_timer_in_use); |
---|
1649 | | - kvm_x86_ops->cancel_hv_timer(apic->vcpu); |
---|
| 1838 | + kvm_x86_ops.cancel_hv_timer(apic->vcpu); |
---|
1650 | 1839 | apic->lapic_timer.hv_timer_in_use = false; |
---|
1651 | 1840 | } |
---|
1652 | 1841 | |
---|
1653 | 1842 | static bool start_hv_timer(struct kvm_lapic *apic) |
---|
1654 | 1843 | { |
---|
1655 | 1844 | struct kvm_timer *ktimer = &apic->lapic_timer; |
---|
1656 | | - int r; |
---|
| 1845 | + struct kvm_vcpu *vcpu = apic->vcpu; |
---|
| 1846 | + bool expired; |
---|
1657 | 1847 | |
---|
1658 | 1848 | WARN_ON(preemptible()); |
---|
1659 | | - if (!kvm_x86_ops->set_hv_timer) |
---|
1660 | | - return false; |
---|
1661 | | - |
---|
1662 | | - if (!apic_lvtt_period(apic) && atomic_read(&ktimer->pending)) |
---|
| 1849 | + if (!kvm_can_use_hv_timer(vcpu)) |
---|
1663 | 1850 | return false; |
---|
1664 | 1851 | |
---|
1665 | 1852 | if (!ktimer->tscdeadline) |
---|
1666 | 1853 | return false; |
---|
1667 | 1854 | |
---|
1668 | | - r = kvm_x86_ops->set_hv_timer(apic->vcpu, ktimer->tscdeadline); |
---|
1669 | | - if (r < 0) |
---|
| 1855 | + if (kvm_x86_ops.set_hv_timer(vcpu, ktimer->tscdeadline, &expired)) |
---|
1670 | 1856 | return false; |
---|
1671 | 1857 | |
---|
1672 | 1858 | ktimer->hv_timer_in_use = true; |
---|
1673 | 1859 | hrtimer_cancel(&ktimer->timer); |
---|
1674 | 1860 | |
---|
1675 | 1861 | /* |
---|
1676 | | - * Also recheck ktimer->pending, in case the sw timer triggered in |
---|
1677 | | - * the window. For periodic timer, leave the hv timer running for |
---|
1678 | | - * simplicity, and the deadline will be recomputed on the next vmexit. |
---|
| 1862 | + * To simplify handling the periodic timer, leave the hv timer running |
---|
| 1863 | + * even if the deadline timer has expired, i.e. rely on the resulting |
---|
| 1864 | + * VM-Exit to recompute the periodic timer's target expiration. |
---|
1679 | 1865 | */ |
---|
1680 | | - if (!apic_lvtt_period(apic) && (r || atomic_read(&ktimer->pending))) { |
---|
1681 | | - if (r) |
---|
1682 | | - apic_timer_expired(apic); |
---|
1683 | | - return false; |
---|
| 1866 | + if (!apic_lvtt_period(apic)) { |
---|
| 1867 | + /* |
---|
| 1868 | + * Cancel the hv timer if the sw timer fired while the hv timer |
---|
| 1869 | + * was being programmed, or if the hv timer itself expired. |
---|
| 1870 | + */ |
---|
| 1871 | + if (atomic_read(&ktimer->pending)) { |
---|
| 1872 | + cancel_hv_timer(apic); |
---|
| 1873 | + } else if (expired) { |
---|
| 1874 | + apic_timer_expired(apic, false); |
---|
| 1875 | + cancel_hv_timer(apic); |
---|
| 1876 | + } |
---|
1684 | 1877 | } |
---|
1685 | 1878 | |
---|
1686 | | - trace_kvm_hv_timer_state(apic->vcpu->vcpu_id, true); |
---|
| 1879 | + trace_kvm_hv_timer_state(vcpu->vcpu_id, ktimer->hv_timer_in_use); |
---|
| 1880 | + |
---|
1687 | 1881 | return true; |
---|
1688 | 1882 | } |
---|
1689 | 1883 | |
---|
.. | .. |
---|
1707 | 1901 | static void restart_apic_timer(struct kvm_lapic *apic) |
---|
1708 | 1902 | { |
---|
1709 | 1903 | preempt_disable(); |
---|
| 1904 | + |
---|
| 1905 | + if (!apic_lvtt_period(apic) && atomic_read(&apic->lapic_timer.pending)) |
---|
| 1906 | + goto out; |
---|
| 1907 | + |
---|
1710 | 1908 | if (!start_hv_timer(apic)) |
---|
1711 | 1909 | start_sw_timer(apic); |
---|
| 1910 | +out: |
---|
1712 | 1911 | preempt_enable(); |
---|
1713 | 1912 | } |
---|
1714 | 1913 | |
---|
.. | .. |
---|
1720 | 1919 | /* If the preempt notifier has already run, it also called apic_timer_expired */ |
---|
1721 | 1920 | if (!apic->lapic_timer.hv_timer_in_use) |
---|
1722 | 1921 | goto out; |
---|
1723 | | - WARN_ON(swait_active(&vcpu->wq)); |
---|
| 1922 | + WARN_ON(rcuwait_active(&vcpu->wait)); |
---|
| 1923 | + apic_timer_expired(apic, false); |
---|
1724 | 1924 | cancel_hv_timer(apic); |
---|
1725 | | - apic_timer_expired(apic); |
---|
1726 | 1925 | |
---|
1727 | 1926 | if (apic_lvtt_period(apic) && apic->lapic_timer.period) { |
---|
1728 | 1927 | advance_periodic_target_expiration(apic); |
---|
.. | .. |
---|
1759 | 1958 | restart_apic_timer(apic); |
---|
1760 | 1959 | } |
---|
1761 | 1960 | |
---|
1762 | | -static void start_apic_timer(struct kvm_lapic *apic) |
---|
| 1961 | +static void __start_apic_timer(struct kvm_lapic *apic, u32 count_reg) |
---|
1763 | 1962 | { |
---|
1764 | 1963 | atomic_set(&apic->lapic_timer.pending, 0); |
---|
1765 | 1964 | |
---|
1766 | 1965 | if ((apic_lvtt_period(apic) || apic_lvtt_oneshot(apic)) |
---|
1767 | | - && !set_target_expiration(apic)) |
---|
| 1966 | + && !set_target_expiration(apic, count_reg)) |
---|
1768 | 1967 | return; |
---|
1769 | 1968 | |
---|
1770 | 1969 | restart_apic_timer(apic); |
---|
| 1970 | +} |
---|
| 1971 | + |
---|
| 1972 | +static void start_apic_timer(struct kvm_lapic *apic) |
---|
| 1973 | +{ |
---|
| 1974 | + __start_apic_timer(apic, APIC_TMICT); |
---|
1771 | 1975 | } |
---|
1772 | 1976 | |
---|
1773 | 1977 | static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) |
---|
.. | .. |
---|
1777 | 1981 | if (apic->lvt0_in_nmi_mode != lvt0_in_nmi_mode) { |
---|
1778 | 1982 | apic->lvt0_in_nmi_mode = lvt0_in_nmi_mode; |
---|
1779 | 1983 | if (lvt0_in_nmi_mode) { |
---|
1780 | | - apic_debug("Receive NMI setting on APIC_LVT0 " |
---|
1781 | | - "for cpu %d\n", apic->vcpu->vcpu_id); |
---|
1782 | 1984 | atomic_inc(&apic->vcpu->kvm->arch.vapics_in_nmi_mode); |
---|
1783 | 1985 | } else |
---|
1784 | 1986 | atomic_dec(&apic->vcpu->kvm->arch.vapics_in_nmi_mode); |
---|
.. | .. |
---|
1816 | 2018 | break; |
---|
1817 | 2019 | |
---|
1818 | 2020 | case APIC_DFR: |
---|
1819 | | - if (!apic_x2apic_mode(apic)) { |
---|
1820 | | - kvm_lapic_set_reg(apic, APIC_DFR, val | 0x0FFFFFFF); |
---|
1821 | | - recalculate_apic_map(apic->vcpu->kvm); |
---|
1822 | | - } else |
---|
| 2021 | + if (!apic_x2apic_mode(apic)) |
---|
| 2022 | + kvm_apic_set_dfr(apic, val | 0x0FFFFFFF); |
---|
| 2023 | + else |
---|
1823 | 2024 | ret = 1; |
---|
1824 | 2025 | break; |
---|
1825 | 2026 | |
---|
.. | .. |
---|
1846 | 2047 | } |
---|
1847 | 2048 | case APIC_ICR: |
---|
1848 | 2049 | /* No delay here, so we always clear the pending bit */ |
---|
1849 | | - kvm_lapic_set_reg(apic, APIC_ICR, val & ~(1 << 12)); |
---|
1850 | | - apic_send_ipi(apic); |
---|
| 2050 | + val &= ~(1 << 12); |
---|
| 2051 | + kvm_apic_send_ipi(apic, val, kvm_lapic_get_reg(apic, APIC_ICR2)); |
---|
| 2052 | + kvm_lapic_set_reg(apic, APIC_ICR, val); |
---|
1851 | 2053 | break; |
---|
1852 | 2054 | |
---|
1853 | 2055 | case APIC_ICR2: |
---|
.. | .. |
---|
1858 | 2060 | |
---|
1859 | 2061 | case APIC_LVT0: |
---|
1860 | 2062 | apic_manage_nmi_watchdog(apic, val); |
---|
| 2063 | + fallthrough; |
---|
1861 | 2064 | case APIC_LVTTHMR: |
---|
1862 | 2065 | case APIC_LVTPC: |
---|
1863 | 2066 | case APIC_LVT1: |
---|
.. | .. |
---|
1896 | 2099 | case APIC_TDCR: { |
---|
1897 | 2100 | uint32_t old_divisor = apic->divide_count; |
---|
1898 | 2101 | |
---|
1899 | | - if (val & 4) |
---|
1900 | | - apic_debug("KVM_WRITE:TDCR %x\n", val); |
---|
1901 | | - kvm_lapic_set_reg(apic, APIC_TDCR, val); |
---|
| 2102 | + kvm_lapic_set_reg(apic, APIC_TDCR, val & 0xb); |
---|
1902 | 2103 | update_divide_count(apic); |
---|
1903 | 2104 | if (apic->divide_count != old_divisor && |
---|
1904 | 2105 | apic->lapic_timer.period) { |
---|
.. | .. |
---|
1909 | 2110 | break; |
---|
1910 | 2111 | } |
---|
1911 | 2112 | case APIC_ESR: |
---|
1912 | | - if (apic_x2apic_mode(apic) && val != 0) { |
---|
1913 | | - apic_debug("KVM_WRITE:ESR not zero %x\n", val); |
---|
| 2113 | + if (apic_x2apic_mode(apic) && val != 0) |
---|
1914 | 2114 | ret = 1; |
---|
1915 | | - } |
---|
1916 | 2115 | break; |
---|
1917 | 2116 | |
---|
1918 | 2117 | case APIC_SELF_IPI: |
---|
1919 | | - if (apic_x2apic_mode(apic)) { |
---|
1920 | | - kvm_lapic_reg_write(apic, APIC_ICR, 0x40000 | (val & 0xff)); |
---|
1921 | | - } else |
---|
| 2118 | + /* |
---|
| 2119 | + * Self-IPI exists only when x2APIC is enabled. Bits 7:0 hold |
---|
| 2120 | + * the vector, everything else is reserved. |
---|
| 2121 | + */ |
---|
| 2122 | + if (!apic_x2apic_mode(apic) || (val & ~APIC_VECTOR_MASK)) |
---|
1922 | 2123 | ret = 1; |
---|
| 2124 | + else |
---|
| 2125 | + kvm_apic_send_ipi(apic, APIC_DEST_SELF | val, 0); |
---|
1923 | 2126 | break; |
---|
1924 | 2127 | default: |
---|
1925 | 2128 | ret = 1; |
---|
1926 | 2129 | break; |
---|
1927 | 2130 | } |
---|
1928 | | - if (ret) |
---|
1929 | | - apic_debug("Local APIC Write to read-only register %x\n", reg); |
---|
| 2131 | + |
---|
| 2132 | + kvm_recalculate_apic_map(apic->vcpu->kvm); |
---|
| 2133 | + |
---|
1930 | 2134 | return ret; |
---|
1931 | 2135 | } |
---|
1932 | 2136 | EXPORT_SYMBOL_GPL(kvm_lapic_reg_write); |
---|
.. | .. |
---|
1954 | 2158 | * 32/64/128 bits registers must be accessed thru 32 bits. |
---|
1955 | 2159 | * Refer SDM 8.4.1 |
---|
1956 | 2160 | */ |
---|
1957 | | - if (len != 4 || (offset & 0xf)) { |
---|
1958 | | - /* Don't shout loud, $infamous_os would cause only noise. */ |
---|
1959 | | - apic_debug("apic write: bad size=%d %lx\n", len, (long)address); |
---|
| 2161 | + if (len != 4 || (offset & 0xf)) |
---|
1960 | 2162 | return 0; |
---|
1961 | | - } |
---|
1962 | 2163 | |
---|
1963 | 2164 | val = *(u32*)data; |
---|
1964 | | - |
---|
1965 | | - /* too common printing */ |
---|
1966 | | - if (offset != APIC_EOI) |
---|
1967 | | - apic_debug("%s: offset 0x%x with length 0x%x, and value is " |
---|
1968 | | - "0x%x\n", __func__, offset, len, val); |
---|
1969 | 2165 | |
---|
1970 | 2166 | kvm_lapic_reg_write(apic, offset & 0xff0, val); |
---|
1971 | 2167 | |
---|
.. | .. |
---|
2023 | 2219 | { |
---|
2024 | 2220 | struct kvm_lapic *apic = vcpu->arch.apic; |
---|
2025 | 2221 | |
---|
2026 | | - if (!lapic_in_kernel(vcpu) || |
---|
2027 | | - !apic_lvtt_tscdeadline(apic)) |
---|
| 2222 | + if (!kvm_apic_present(vcpu) || !apic_lvtt_tscdeadline(apic)) |
---|
2028 | 2223 | return 0; |
---|
2029 | 2224 | |
---|
2030 | 2225 | return apic->lapic_timer.tscdeadline; |
---|
.. | .. |
---|
2034 | 2229 | { |
---|
2035 | 2230 | struct kvm_lapic *apic = vcpu->arch.apic; |
---|
2036 | 2231 | |
---|
2037 | | - if (!kvm_apic_present(vcpu) || apic_lvtt_oneshot(apic) || |
---|
2038 | | - apic_lvtt_period(apic)) |
---|
| 2232 | + if (!kvm_apic_present(vcpu) || !apic_lvtt_tscdeadline(apic)) |
---|
2039 | 2233 | return; |
---|
2040 | 2234 | |
---|
2041 | 2235 | hrtimer_cancel(&apic->lapic_timer.timer); |
---|
.. | .. |
---|
2045 | 2239 | |
---|
2046 | 2240 | void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8) |
---|
2047 | 2241 | { |
---|
2048 | | - struct kvm_lapic *apic = vcpu->arch.apic; |
---|
2049 | | - |
---|
2050 | | - apic_set_tpr(apic, ((cr8 & 0x0f) << 4) |
---|
2051 | | - | (kvm_lapic_get_reg(apic, APIC_TASKPRI) & 4)); |
---|
| 2242 | + apic_set_tpr(vcpu->arch.apic, (cr8 & 0x0f) << 4); |
---|
2052 | 2243 | } |
---|
2053 | 2244 | |
---|
2054 | 2245 | u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) |
---|
.. | .. |
---|
2071 | 2262 | vcpu->arch.apic_base = value; |
---|
2072 | 2263 | |
---|
2073 | 2264 | if ((old_value ^ value) & MSR_IA32_APICBASE_ENABLE) |
---|
2074 | | - kvm_update_cpuid(vcpu); |
---|
| 2265 | + kvm_update_cpuid_runtime(vcpu); |
---|
2075 | 2266 | |
---|
2076 | 2267 | if (!apic) |
---|
2077 | 2268 | return; |
---|
.. | .. |
---|
2081 | 2272 | if (value & MSR_IA32_APICBASE_ENABLE) { |
---|
2082 | 2273 | kvm_apic_set_xapic_id(apic, vcpu->vcpu_id); |
---|
2083 | 2274 | static_key_slow_dec_deferred(&apic_hw_disabled); |
---|
| 2275 | + /* Check if there are APF page ready requests pending */ |
---|
| 2276 | + kvm_make_request(KVM_REQ_APF_READY, vcpu); |
---|
2084 | 2277 | } else { |
---|
2085 | 2278 | static_key_slow_inc(&apic_hw_disabled.key); |
---|
2086 | | - recalculate_apic_map(vcpu->kvm); |
---|
| 2279 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); |
---|
2087 | 2280 | } |
---|
2088 | 2281 | } |
---|
2089 | 2282 | |
---|
.. | .. |
---|
2091 | 2284 | kvm_apic_set_x2apic_id(apic, vcpu->vcpu_id); |
---|
2092 | 2285 | |
---|
2093 | 2286 | if ((old_value ^ value) & (MSR_IA32_APICBASE_ENABLE | X2APIC_ENABLE)) |
---|
2094 | | - kvm_x86_ops->set_virtual_apic_mode(vcpu); |
---|
| 2287 | + kvm_x86_ops.set_virtual_apic_mode(vcpu); |
---|
2095 | 2288 | |
---|
2096 | 2289 | apic->base_address = apic->vcpu->arch.apic_base & |
---|
2097 | 2290 | MSR_IA32_APICBASE_BASE; |
---|
.. | .. |
---|
2099 | 2292 | if ((value & MSR_IA32_APICBASE_ENABLE) && |
---|
2100 | 2293 | apic->base_address != APIC_DEFAULT_PHYS_BASE) |
---|
2101 | 2294 | pr_warn_once("APIC base relocation is unsupported by KVM"); |
---|
2102 | | - |
---|
2103 | | - /* with FSB delivery interrupt, we can restart APIC functionality */ |
---|
2104 | | - apic_debug("apic base msr is 0x%016" PRIx64 ", and base address is " |
---|
2105 | | - "0x%lx.\n", apic->vcpu->arch.apic_base, apic->base_address); |
---|
2106 | | - |
---|
2107 | 2295 | } |
---|
| 2296 | + |
---|
| 2297 | +void kvm_apic_update_apicv(struct kvm_vcpu *vcpu) |
---|
| 2298 | +{ |
---|
| 2299 | + struct kvm_lapic *apic = vcpu->arch.apic; |
---|
| 2300 | + |
---|
| 2301 | + if (vcpu->arch.apicv_active) { |
---|
| 2302 | + /* irr_pending is always true when apicv is activated. */ |
---|
| 2303 | + apic->irr_pending = true; |
---|
| 2304 | + apic->isr_count = 1; |
---|
| 2305 | + } else { |
---|
| 2306 | + apic->irr_pending = (apic_search_irr(apic) != -1); |
---|
| 2307 | + apic->isr_count = count_vectors(apic->regs + APIC_ISR); |
---|
| 2308 | + } |
---|
| 2309 | +} |
---|
| 2310 | +EXPORT_SYMBOL_GPL(kvm_apic_update_apicv); |
---|
2108 | 2311 | |
---|
2109 | 2312 | void kvm_lapic_reset(struct kvm_vcpu *vcpu, bool init_event) |
---|
2110 | 2313 | { |
---|
.. | .. |
---|
2113 | 2316 | |
---|
2114 | 2317 | if (!apic) |
---|
2115 | 2318 | return; |
---|
2116 | | - |
---|
2117 | | - apic_debug("%s\n", __func__); |
---|
2118 | 2319 | |
---|
2119 | 2320 | /* Stop the timer in case it's a reset to an active apic */ |
---|
2120 | 2321 | hrtimer_cancel(&apic->lapic_timer.timer); |
---|
.. | .. |
---|
2135 | 2336 | SET_APIC_DELIVERY_MODE(0, APIC_MODE_EXTINT)); |
---|
2136 | 2337 | apic_manage_nmi_watchdog(apic, kvm_lapic_get_reg(apic, APIC_LVT0)); |
---|
2137 | 2338 | |
---|
2138 | | - kvm_lapic_set_reg(apic, APIC_DFR, 0xffffffffU); |
---|
| 2339 | + kvm_apic_set_dfr(apic, 0xffffffffU); |
---|
2139 | 2340 | apic_set_spiv(apic, 0xff); |
---|
2140 | 2341 | kvm_lapic_set_reg(apic, APIC_TASKPRI, 0); |
---|
2141 | 2342 | if (!apic_x2apic_mode(apic)) |
---|
.. | .. |
---|
2150 | 2351 | kvm_lapic_set_reg(apic, APIC_ISR + 0x10 * i, 0); |
---|
2151 | 2352 | kvm_lapic_set_reg(apic, APIC_TMR + 0x10 * i, 0); |
---|
2152 | 2353 | } |
---|
2153 | | - apic->irr_pending = vcpu->arch.apicv_active; |
---|
2154 | | - apic->isr_count = vcpu->arch.apicv_active ? 1 : 0; |
---|
| 2354 | + kvm_apic_update_apicv(vcpu); |
---|
2155 | 2355 | apic->highest_isr_cache = -1; |
---|
2156 | 2356 | update_divide_count(apic); |
---|
2157 | 2357 | atomic_set(&apic->lapic_timer.pending, 0); |
---|
.. | .. |
---|
2161 | 2361 | vcpu->arch.pv_eoi.msr_val = 0; |
---|
2162 | 2362 | apic_update_ppr(apic); |
---|
2163 | 2363 | if (vcpu->arch.apicv_active) { |
---|
2164 | | - kvm_x86_ops->apicv_post_state_restore(vcpu); |
---|
2165 | | - kvm_x86_ops->hwapic_irr_update(vcpu, -1); |
---|
2166 | | - kvm_x86_ops->hwapic_isr_update(vcpu, -1); |
---|
| 2364 | + kvm_x86_ops.apicv_post_state_restore(vcpu); |
---|
| 2365 | + kvm_x86_ops.hwapic_irr_update(vcpu, -1); |
---|
| 2366 | + kvm_x86_ops.hwapic_isr_update(vcpu, -1); |
---|
2167 | 2367 | } |
---|
2168 | 2368 | |
---|
2169 | 2369 | vcpu->arch.apic_arb_prio = 0; |
---|
2170 | 2370 | vcpu->arch.apic_attention = 0; |
---|
2171 | 2371 | |
---|
2172 | | - apic_debug("%s: vcpu=%p, id=0x%x, base_msr=" |
---|
2173 | | - "0x%016" PRIx64 ", base_address=0x%0lx.\n", __func__, |
---|
2174 | | - vcpu, kvm_lapic_get_reg(apic, APIC_ID), |
---|
2175 | | - vcpu->arch.apic_base, apic->base_address); |
---|
| 2372 | + kvm_recalculate_apic_map(vcpu->kvm); |
---|
2176 | 2373 | } |
---|
2177 | 2374 | |
---|
2178 | 2375 | /* |
---|
.. | .. |
---|
2229 | 2426 | struct kvm_timer *ktimer = container_of(data, struct kvm_timer, timer); |
---|
2230 | 2427 | struct kvm_lapic *apic = container_of(ktimer, struct kvm_lapic, lapic_timer); |
---|
2231 | 2428 | |
---|
2232 | | - apic_timer_expired(apic); |
---|
| 2429 | + apic_timer_expired(apic, true); |
---|
2233 | 2430 | |
---|
2234 | 2431 | if (lapic_is_periodic(apic)) { |
---|
2235 | 2432 | advance_periodic_target_expiration(apic); |
---|
.. | .. |
---|
2239 | 2436 | return HRTIMER_NORESTART; |
---|
2240 | 2437 | } |
---|
2241 | 2438 | |
---|
2242 | | -int kvm_create_lapic(struct kvm_vcpu *vcpu) |
---|
| 2439 | +int kvm_create_lapic(struct kvm_vcpu *vcpu, int timer_advance_ns) |
---|
2243 | 2440 | { |
---|
2244 | 2441 | struct kvm_lapic *apic; |
---|
2245 | 2442 | |
---|
2246 | 2443 | ASSERT(vcpu != NULL); |
---|
2247 | | - apic_debug("apic_init %d\n", vcpu->vcpu_id); |
---|
2248 | 2444 | |
---|
2249 | | - apic = kzalloc(sizeof(*apic), GFP_KERNEL); |
---|
| 2445 | + apic = kzalloc(sizeof(*apic), GFP_KERNEL_ACCOUNT); |
---|
2250 | 2446 | if (!apic) |
---|
2251 | 2447 | goto nomem; |
---|
2252 | 2448 | |
---|
2253 | 2449 | vcpu->arch.apic = apic; |
---|
2254 | 2450 | |
---|
2255 | | - apic->regs = (void *)get_zeroed_page(GFP_KERNEL); |
---|
| 2451 | + apic->regs = (void *)get_zeroed_page(GFP_KERNEL_ACCOUNT); |
---|
2256 | 2452 | if (!apic->regs) { |
---|
2257 | 2453 | printk(KERN_ERR "malloc apic regs error for vcpu %x\n", |
---|
2258 | 2454 | vcpu->vcpu_id); |
---|
.. | .. |
---|
2261 | 2457 | apic->vcpu = vcpu; |
---|
2262 | 2458 | |
---|
2263 | 2459 | hrtimer_init(&apic->lapic_timer.timer, CLOCK_MONOTONIC, |
---|
2264 | | - HRTIMER_MODE_ABS_PINNED); |
---|
| 2460 | + HRTIMER_MODE_ABS_HARD); |
---|
2265 | 2461 | apic->lapic_timer.timer.function = apic_timer_fn; |
---|
| 2462 | + if (timer_advance_ns == -1) { |
---|
| 2463 | + apic->lapic_timer.timer_advance_ns = LAPIC_TIMER_ADVANCE_NS_INIT; |
---|
| 2464 | + lapic_timer_advance_dynamic = true; |
---|
| 2465 | + } else { |
---|
| 2466 | + apic->lapic_timer.timer_advance_ns = timer_advance_ns; |
---|
| 2467 | + lapic_timer_advance_dynamic = false; |
---|
| 2468 | + } |
---|
2266 | 2469 | |
---|
2267 | 2470 | /* |
---|
2268 | 2471 | * APIC is created enabled. This will prevent kvm_lapic_set_base from |
---|
2269 | | - * thinking that APIC satet has changed. |
---|
| 2472 | + * thinking that APIC state has changed. |
---|
2270 | 2473 | */ |
---|
2271 | 2474 | vcpu->arch.apic_base = MSR_IA32_APICBASE_ENABLE; |
---|
2272 | 2475 | static_key_slow_inc(&apic_sw_disabled.key); /* sw disabled at reset */ |
---|
.. | .. |
---|
2275 | 2478 | return 0; |
---|
2276 | 2479 | nomem_free_apic: |
---|
2277 | 2480 | kfree(apic); |
---|
| 2481 | + vcpu->arch.apic = NULL; |
---|
2278 | 2482 | nomem: |
---|
2279 | 2483 | return -ENOMEM; |
---|
2280 | 2484 | } |
---|
.. | .. |
---|
2290 | 2494 | __apic_update_ppr(apic, &ppr); |
---|
2291 | 2495 | return apic_has_interrupt_for_ppr(apic, ppr); |
---|
2292 | 2496 | } |
---|
| 2497 | +EXPORT_SYMBOL_GPL(kvm_apic_has_interrupt); |
---|
2293 | 2498 | |
---|
2294 | 2499 | int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu) |
---|
2295 | 2500 | { |
---|
2296 | 2501 | u32 lvt0 = kvm_lapic_get_reg(vcpu->arch.apic, APIC_LVT0); |
---|
2297 | | - int r = 0; |
---|
2298 | 2502 | |
---|
2299 | 2503 | if (!kvm_apic_hw_enabled(vcpu->arch.apic)) |
---|
2300 | | - r = 1; |
---|
| 2504 | + return 1; |
---|
2301 | 2505 | if ((lvt0 & APIC_LVT_MASKED) == 0 && |
---|
2302 | 2506 | GET_APIC_DELIVERY_MODE(lvt0) == APIC_MODE_EXTINT) |
---|
2303 | | - r = 1; |
---|
2304 | | - return r; |
---|
| 2507 | + return 1; |
---|
| 2508 | + return 0; |
---|
2305 | 2509 | } |
---|
2306 | 2510 | |
---|
2307 | 2511 | void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) |
---|
.. | .. |
---|
2309 | 2513 | struct kvm_lapic *apic = vcpu->arch.apic; |
---|
2310 | 2514 | |
---|
2311 | 2515 | if (atomic_read(&apic->lapic_timer.pending) > 0) { |
---|
2312 | | - kvm_apic_local_deliver(apic, APIC_LVTT); |
---|
2313 | | - if (apic_lvtt_tscdeadline(apic)) |
---|
2314 | | - apic->lapic_timer.tscdeadline = 0; |
---|
2315 | | - if (apic_lvtt_oneshot(apic)) { |
---|
2316 | | - apic->lapic_timer.tscdeadline = 0; |
---|
2317 | | - apic->lapic_timer.target_expiration = 0; |
---|
2318 | | - } |
---|
| 2516 | + kvm_apic_inject_pending_timer_irqs(apic); |
---|
2319 | 2517 | atomic_set(&apic->lapic_timer.pending, 0); |
---|
2320 | 2518 | } |
---|
2321 | 2519 | } |
---|
.. | .. |
---|
2386 | 2584 | int kvm_apic_get_state(struct kvm_vcpu *vcpu, struct kvm_lapic_state *s) |
---|
2387 | 2585 | { |
---|
2388 | 2586 | memcpy(s->regs, vcpu->arch.apic->regs, sizeof(*s)); |
---|
| 2587 | + |
---|
| 2588 | + /* |
---|
| 2589 | + * Get calculated timer current count for remaining timer period (if |
---|
| 2590 | + * any) and store it in the returned register set. |
---|
| 2591 | + */ |
---|
| 2592 | + __kvm_lapic_set_reg(s->regs, APIC_TMCCT, |
---|
| 2593 | + __apic_read(vcpu->arch.apic, APIC_TMCCT)); |
---|
| 2594 | + |
---|
2389 | 2595 | return kvm_apic_state_fixup(vcpu, s, false); |
---|
2390 | 2596 | } |
---|
2391 | 2597 | |
---|
.. | .. |
---|
2394 | 2600 | struct kvm_lapic *apic = vcpu->arch.apic; |
---|
2395 | 2601 | int r; |
---|
2396 | 2602 | |
---|
2397 | | - |
---|
2398 | 2603 | kvm_lapic_set_base(vcpu, vcpu->arch.apic_base); |
---|
2399 | 2604 | /* set SPIV separately to get count of SW disabled APICs right */ |
---|
2400 | 2605 | apic_set_spiv(apic, *((u32 *)(s->regs + APIC_SPIV))); |
---|
2401 | 2606 | |
---|
2402 | 2607 | r = kvm_apic_state_fixup(vcpu, s, true); |
---|
2403 | | - if (r) |
---|
| 2608 | + if (r) { |
---|
| 2609 | + kvm_recalculate_apic_map(vcpu->kvm); |
---|
2404 | 2610 | return r; |
---|
2405 | | - memcpy(vcpu->arch.apic->regs, s->regs, sizeof *s); |
---|
| 2611 | + } |
---|
| 2612 | + memcpy(vcpu->arch.apic->regs, s->regs, sizeof(*s)); |
---|
2406 | 2613 | |
---|
2407 | | - recalculate_apic_map(vcpu->kvm); |
---|
| 2614 | + atomic_set_release(&apic->vcpu->kvm->arch.apic_map_dirty, DIRTY); |
---|
| 2615 | + kvm_recalculate_apic_map(vcpu->kvm); |
---|
2408 | 2616 | kvm_apic_set_version(vcpu); |
---|
2409 | 2617 | |
---|
2410 | 2618 | apic_update_ppr(apic); |
---|
.. | .. |
---|
2412 | 2620 | apic_update_lvtt(apic); |
---|
2413 | 2621 | apic_manage_nmi_watchdog(apic, kvm_lapic_get_reg(apic, APIC_LVT0)); |
---|
2414 | 2622 | update_divide_count(apic); |
---|
2415 | | - start_apic_timer(apic); |
---|
2416 | | - apic->irr_pending = true; |
---|
2417 | | - apic->isr_count = vcpu->arch.apicv_active ? |
---|
2418 | | - 1 : count_vectors(apic->regs + APIC_ISR); |
---|
| 2623 | + __start_apic_timer(apic, APIC_TMCCT); |
---|
| 2624 | + kvm_apic_update_apicv(vcpu); |
---|
2419 | 2625 | apic->highest_isr_cache = -1; |
---|
2420 | 2626 | if (vcpu->arch.apicv_active) { |
---|
2421 | | - kvm_x86_ops->apicv_post_state_restore(vcpu); |
---|
2422 | | - kvm_x86_ops->hwapic_irr_update(vcpu, |
---|
| 2627 | + kvm_x86_ops.apicv_post_state_restore(vcpu); |
---|
| 2628 | + kvm_x86_ops.hwapic_irr_update(vcpu, |
---|
2423 | 2629 | apic_find_highest_irr(apic)); |
---|
2424 | | - kvm_x86_ops->hwapic_isr_update(vcpu, |
---|
| 2630 | + kvm_x86_ops.hwapic_isr_update(vcpu, |
---|
2425 | 2631 | apic_find_highest_isr(apic)); |
---|
2426 | 2632 | } |
---|
2427 | 2633 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
---|
.. | .. |
---|
2437 | 2643 | { |
---|
2438 | 2644 | struct hrtimer *timer; |
---|
2439 | 2645 | |
---|
2440 | | - if (!lapic_in_kernel(vcpu)) |
---|
| 2646 | + if (!lapic_in_kernel(vcpu) || |
---|
| 2647 | + kvm_can_post_timer_interrupt(vcpu)) |
---|
2441 | 2648 | return; |
---|
2442 | 2649 | |
---|
2443 | 2650 | timer = &vcpu->arch.apic->lapic_timer.timer; |
---|
2444 | 2651 | if (hrtimer_cancel(timer)) |
---|
2445 | | - hrtimer_start_expires(timer, HRTIMER_MODE_ABS_PINNED); |
---|
| 2652 | + hrtimer_start_expires(timer, HRTIMER_MODE_ABS_HARD); |
---|
2446 | 2653 | } |
---|
2447 | 2654 | |
---|
2448 | 2655 | /* |
---|
.. | .. |
---|
2590 | 2797 | if (!lapic_in_kernel(vcpu) || !apic_x2apic_mode(apic)) |
---|
2591 | 2798 | return 1; |
---|
2592 | 2799 | |
---|
2593 | | - if (reg == APIC_DFR || reg == APIC_ICR2) { |
---|
2594 | | - apic_debug("KVM_APIC_READ: read x2apic reserved register %x\n", |
---|
2595 | | - reg); |
---|
| 2800 | + if (reg == APIC_DFR || reg == APIC_ICR2) |
---|
2596 | 2801 | return 1; |
---|
2597 | | - } |
---|
2598 | 2802 | |
---|
2599 | 2803 | if (kvm_lapic_reg_read(apic, reg, 4, &low)) |
---|
2600 | 2804 | return 1; |
---|
.. | .. |
---|
2668 | 2872 | return; |
---|
2669 | 2873 | |
---|
2670 | 2874 | /* |
---|
2671 | | - * INITs are latched while in SMM. Because an SMM CPU cannot |
---|
2672 | | - * be in KVM_MP_STATE_INIT_RECEIVED state, just eat SIPIs |
---|
2673 | | - * and delay processing of INIT until the next RSM. |
---|
| 2875 | + * INITs are latched while CPU is in specific states |
---|
| 2876 | + * (SMM, VMX non-root mode, SVM with GIF=0). |
---|
| 2877 | + * Because a CPU cannot be in these states immediately |
---|
| 2878 | + * after it has processed an INIT signal (and thus in |
---|
| 2879 | + * KVM_MP_STATE_INIT_RECEIVED state), just eat SIPIs |
---|
| 2880 | + * and leave the INIT pending. |
---|
2674 | 2881 | */ |
---|
2675 | | - if (is_smm(vcpu)) { |
---|
| 2882 | + if (kvm_vcpu_latch_init(vcpu)) { |
---|
2676 | 2883 | WARN_ON_ONCE(vcpu->arch.mp_state == KVM_MP_STATE_INIT_RECEIVED); |
---|
2677 | 2884 | if (test_bit(KVM_APIC_SIPI, &apic->pending_events)) |
---|
2678 | 2885 | clear_bit(KVM_APIC_SIPI, &apic->pending_events); |
---|
.. | .. |
---|
2692 | 2899 | /* evaluate pending_events before reading the vector */ |
---|
2693 | 2900 | smp_rmb(); |
---|
2694 | 2901 | sipi_vector = apic->sipi_vector; |
---|
2695 | | - apic_debug("vcpu %d received sipi with vector # %x\n", |
---|
2696 | | - vcpu->vcpu_id, sipi_vector); |
---|
2697 | 2902 | kvm_vcpu_deliver_sipi_vector(vcpu, sipi_vector); |
---|
2698 | 2903 | vcpu->arch.mp_state = KVM_MP_STATE_RUNNABLE; |
---|
2699 | 2904 | } |
---|