diff options
-rw-r--r-- | arch/x86/kvm/lapic.c | 143 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.h | 45 |
2 files changed, 96 insertions, 92 deletions
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 650379ba73af..333c27fa6e9f 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -73,11 +73,6 @@ | |||
73 | static unsigned int min_timer_period_us = 500; | 73 | static unsigned int min_timer_period_us = 500; |
74 | module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR); | 74 | module_param(min_timer_period_us, uint, S_IRUGO | S_IWUSR); |
75 | 75 | ||
76 | static inline u32 apic_get_reg(struct kvm_lapic *apic, int reg_off) | ||
77 | { | ||
78 | return *((u32 *) (apic->regs + reg_off)); | ||
79 | } | ||
80 | |||
81 | static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val) | 76 | static inline void apic_set_reg(struct kvm_lapic *apic, int reg_off, u32 val) |
82 | { | 77 | { |
83 | *((u32 *) (apic->regs + reg_off)) = val; | 78 | *((u32 *) (apic->regs + reg_off)) = val; |
@@ -119,19 +114,11 @@ static inline int __apic_test_and_clear_vector(int vec, void *bitmap) | |||
119 | } | 114 | } |
120 | 115 | ||
121 | struct static_key_deferred apic_hw_disabled __read_mostly; | 116 | struct static_key_deferred apic_hw_disabled __read_mostly; |
122 | |||
123 | static inline int apic_hw_enabled(struct kvm_lapic *apic) | ||
124 | { | ||
125 | if (static_key_false(&apic_hw_disabled.key)) | ||
126 | return apic->vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE; | ||
127 | return MSR_IA32_APICBASE_ENABLE; | ||
128 | } | ||
129 | |||
130 | struct static_key_deferred apic_sw_disabled __read_mostly; | 117 | struct static_key_deferred apic_sw_disabled __read_mostly; |
131 | 118 | ||
132 | static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) | 119 | static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) |
133 | { | 120 | { |
134 | if ((apic_get_reg(apic, APIC_SPIV) ^ val) & APIC_SPIV_APIC_ENABLED) { | 121 | if ((kvm_apic_get_reg(apic, APIC_SPIV) ^ val) & APIC_SPIV_APIC_ENABLED) { |
135 | if (val & APIC_SPIV_APIC_ENABLED) | 122 | if (val & APIC_SPIV_APIC_ENABLED) |
136 | static_key_slow_dec_deferred(&apic_sw_disabled); | 123 | static_key_slow_dec_deferred(&apic_sw_disabled); |
137 | else | 124 | else |
@@ -140,23 +127,9 @@ static inline void apic_set_spiv(struct kvm_lapic *apic, u32 val) | |||
140 | apic_set_reg(apic, APIC_SPIV, val); | 127 | apic_set_reg(apic, APIC_SPIV, val); |
141 | } | 128 | } |
142 | 129 | ||
143 | static inline int apic_sw_enabled(struct kvm_lapic *apic) | ||
144 | { | ||
145 | if (static_key_false(&apic_sw_disabled.key)) | ||
146 | return apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED; | ||
147 | return APIC_SPIV_APIC_ENABLED; | ||
148 | } | ||
149 | |||
150 | static inline int apic_enabled(struct kvm_lapic *apic) | 130 | static inline int apic_enabled(struct kvm_lapic *apic) |
151 | { | 131 | { |
152 | return apic_sw_enabled(apic) && apic_hw_enabled(apic); | 132 | return kvm_apic_sw_enabled(apic) && kvm_apic_hw_enabled(apic); |
153 | } | ||
154 | |||
155 | static inline bool vcpu_has_lapic(struct kvm_vcpu *vcpu) | ||
156 | { | ||
157 | if (static_key_false(&kvm_no_apic_vcpu)) | ||
158 | return vcpu->arch.apic; | ||
159 | return true; | ||
160 | } | 133 | } |
161 | 134 | ||
162 | #define LVT_MASK \ | 135 | #define LVT_MASK \ |
@@ -168,34 +141,34 @@ static inline bool vcpu_has_lapic(struct kvm_vcpu *vcpu) | |||
168 | 141 | ||
169 | static inline int kvm_apic_id(struct kvm_lapic *apic) | 142 | static inline int kvm_apic_id(struct kvm_lapic *apic) |
170 | { | 143 | { |
171 | return (apic_get_reg(apic, APIC_ID) >> 24) & 0xff; | 144 | return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; |
172 | } | 145 | } |
173 | 146 | ||
174 | static inline int apic_lvt_enabled(struct kvm_lapic *apic, int lvt_type) | 147 | static inline int apic_lvt_enabled(struct kvm_lapic *apic, int lvt_type) |
175 | { | 148 | { |
176 | return !(apic_get_reg(apic, lvt_type) & APIC_LVT_MASKED); | 149 | return !(kvm_apic_get_reg(apic, lvt_type) & APIC_LVT_MASKED); |
177 | } | 150 | } |
178 | 151 | ||
179 | static inline int apic_lvt_vector(struct kvm_lapic *apic, int lvt_type) | 152 | static inline int apic_lvt_vector(struct kvm_lapic *apic, int lvt_type) |
180 | { | 153 | { |
181 | return apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK; | 154 | return kvm_apic_get_reg(apic, lvt_type) & APIC_VECTOR_MASK; |
182 | } | 155 | } |
183 | 156 | ||
184 | static inline int apic_lvtt_oneshot(struct kvm_lapic *apic) | 157 | static inline int apic_lvtt_oneshot(struct kvm_lapic *apic) |
185 | { | 158 | { |
186 | return ((apic_get_reg(apic, APIC_LVTT) & | 159 | return ((kvm_apic_get_reg(apic, APIC_LVTT) & |
187 | apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_ONESHOT); | 160 | apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_ONESHOT); |
188 | } | 161 | } |
189 | 162 | ||
190 | static inline int apic_lvtt_period(struct kvm_lapic *apic) | 163 | static inline int apic_lvtt_period(struct kvm_lapic *apic) |
191 | { | 164 | { |
192 | return ((apic_get_reg(apic, APIC_LVTT) & | 165 | return ((kvm_apic_get_reg(apic, APIC_LVTT) & |
193 | apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_PERIODIC); | 166 | apic->lapic_timer.timer_mode_mask) == APIC_LVT_TIMER_PERIODIC); |
194 | } | 167 | } |
195 | 168 | ||
196 | static inline int apic_lvtt_tscdeadline(struct kvm_lapic *apic) | 169 | static inline int apic_lvtt_tscdeadline(struct kvm_lapic *apic) |
197 | { | 170 | { |
198 | return ((apic_get_reg(apic, APIC_LVTT) & | 171 | return ((kvm_apic_get_reg(apic, APIC_LVTT) & |
199 | apic->lapic_timer.timer_mode_mask) == | 172 | apic->lapic_timer.timer_mode_mask) == |
200 | APIC_LVT_TIMER_TSCDEADLINE); | 173 | APIC_LVT_TIMER_TSCDEADLINE); |
201 | } | 174 | } |
@@ -211,7 +184,7 @@ void kvm_apic_set_version(struct kvm_vcpu *vcpu) | |||
211 | struct kvm_cpuid_entry2 *feat; | 184 | struct kvm_cpuid_entry2 *feat; |
212 | u32 v = APIC_VERSION; | 185 | u32 v = APIC_VERSION; |
213 | 186 | ||
214 | if (!vcpu_has_lapic(vcpu)) | 187 | if (!kvm_vcpu_has_lapic(vcpu)) |
215 | return; | 188 | return; |
216 | 189 | ||
217 | feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0); | 190 | feat = kvm_find_cpuid_entry(apic->vcpu, 0x1, 0); |
@@ -319,7 +292,7 @@ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu) | |||
319 | * will cause vmexit immediately and the value will be recalculated | 292 | * will cause vmexit immediately and the value will be recalculated |
320 | * on the next vmentry. | 293 | * on the next vmentry. |
321 | */ | 294 | */ |
322 | if (!vcpu_has_lapic(vcpu)) | 295 | if (!kvm_vcpu_has_lapic(vcpu)) |
323 | return 0; | 296 | return 0; |
324 | highest_irr = apic_find_highest_irr(vcpu->arch.apic); | 297 | highest_irr = apic_find_highest_irr(vcpu->arch.apic); |
325 | 298 | ||
@@ -404,8 +377,8 @@ static void apic_update_ppr(struct kvm_lapic *apic) | |||
404 | u32 tpr, isrv, ppr, old_ppr; | 377 | u32 tpr, isrv, ppr, old_ppr; |
405 | int isr; | 378 | int isr; |
406 | 379 | ||
407 | old_ppr = apic_get_reg(apic, APIC_PROCPRI); | 380 | old_ppr = kvm_apic_get_reg(apic, APIC_PROCPRI); |
408 | tpr = apic_get_reg(apic, APIC_TASKPRI); | 381 | tpr = kvm_apic_get_reg(apic, APIC_TASKPRI); |
409 | isr = apic_find_highest_isr(apic); | 382 | isr = apic_find_highest_isr(apic); |
410 | isrv = (isr != -1) ? isr : 0; | 383 | isrv = (isr != -1) ? isr : 0; |
411 | 384 | ||
@@ -441,13 +414,13 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | |||
441 | u32 logical_id; | 414 | u32 logical_id; |
442 | 415 | ||
443 | if (apic_x2apic_mode(apic)) { | 416 | if (apic_x2apic_mode(apic)) { |
444 | logical_id = apic_get_reg(apic, APIC_LDR); | 417 | logical_id = kvm_apic_get_reg(apic, APIC_LDR); |
445 | return logical_id & mda; | 418 | return logical_id & mda; |
446 | } | 419 | } |
447 | 420 | ||
448 | logical_id = GET_APIC_LOGICAL_ID(apic_get_reg(apic, APIC_LDR)); | 421 | logical_id = GET_APIC_LOGICAL_ID(kvm_apic_get_reg(apic, APIC_LDR)); |
449 | 422 | ||
450 | switch (apic_get_reg(apic, APIC_DFR)) { | 423 | switch (kvm_apic_get_reg(apic, APIC_DFR)) { |
451 | case APIC_DFR_FLAT: | 424 | case APIC_DFR_FLAT: |
452 | if (logical_id & mda) | 425 | if (logical_id & mda) |
453 | result = 1; | 426 | result = 1; |
@@ -459,7 +432,7 @@ int kvm_apic_match_logical_addr(struct kvm_lapic *apic, u8 mda) | |||
459 | break; | 432 | break; |
460 | default: | 433 | default: |
461 | apic_debug("Bad DFR vcpu %d: %08x\n", | 434 | apic_debug("Bad DFR vcpu %d: %08x\n", |
462 | apic->vcpu->vcpu_id, apic_get_reg(apic, APIC_DFR)); | 435 | apic->vcpu->vcpu_id, kvm_apic_get_reg(apic, APIC_DFR)); |
463 | break; | 436 | break; |
464 | } | 437 | } |
465 | 438 | ||
@@ -617,7 +590,7 @@ static int apic_set_eoi(struct kvm_lapic *apic) | |||
617 | apic_clear_isr(vector, apic); | 590 | apic_clear_isr(vector, apic); |
618 | apic_update_ppr(apic); | 591 | apic_update_ppr(apic); |
619 | 592 | ||
620 | if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) && | 593 | if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) && |
621 | kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) { | 594 | kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) { |
622 | int trigger_mode; | 595 | int trigger_mode; |
623 | if (apic_test_vector(vector, apic->regs + APIC_TMR)) | 596 | if (apic_test_vector(vector, apic->regs + APIC_TMR)) |
@@ -632,8 +605,8 @@ static int apic_set_eoi(struct kvm_lapic *apic) | |||
632 | 605 | ||
633 | static void apic_send_ipi(struct kvm_lapic *apic) | 606 | static void apic_send_ipi(struct kvm_lapic *apic) |
634 | { | 607 | { |
635 | u32 icr_low = apic_get_reg(apic, APIC_ICR); | 608 | u32 icr_low = kvm_apic_get_reg(apic, APIC_ICR); |
636 | u32 icr_high = apic_get_reg(apic, APIC_ICR2); | 609 | u32 icr_high = kvm_apic_get_reg(apic, APIC_ICR2); |
637 | struct kvm_lapic_irq irq; | 610 | struct kvm_lapic_irq irq; |
638 | 611 | ||
639 | irq.vector = icr_low & APIC_VECTOR_MASK; | 612 | irq.vector = icr_low & APIC_VECTOR_MASK; |
@@ -668,7 +641,7 @@ static u32 apic_get_tmcct(struct kvm_lapic *apic) | |||
668 | ASSERT(apic != NULL); | 641 | ASSERT(apic != NULL); |
669 | 642 | ||
670 | /* if initial count is 0, current count should also be 0 */ | 643 | /* if initial count is 0, current count should also be 0 */ |
671 | if (apic_get_reg(apic, APIC_TMICT) == 0) | 644 | if (kvm_apic_get_reg(apic, APIC_TMICT) == 0) |
672 | return 0; | 645 | return 0; |
673 | 646 | ||
674 | remaining = hrtimer_get_remaining(&apic->lapic_timer.timer); | 647 | remaining = hrtimer_get_remaining(&apic->lapic_timer.timer); |
@@ -724,13 +697,13 @@ static u32 __apic_read(struct kvm_lapic *apic, unsigned int offset) | |||
724 | break; | 697 | break; |
725 | case APIC_PROCPRI: | 698 | case APIC_PROCPRI: |
726 | apic_update_ppr(apic); | 699 | apic_update_ppr(apic); |
727 | val = apic_get_reg(apic, offset); | 700 | val = kvm_apic_get_reg(apic, offset); |
728 | break; | 701 | break; |
729 | case APIC_TASKPRI: | 702 | case APIC_TASKPRI: |
730 | report_tpr_access(apic, false); | 703 | report_tpr_access(apic, false); |
731 | /* fall thru */ | 704 | /* fall thru */ |
732 | default: | 705 | default: |
733 | val = apic_get_reg(apic, offset); | 706 | val = kvm_apic_get_reg(apic, offset); |
734 | break; | 707 | break; |
735 | } | 708 | } |
736 | 709 | ||
@@ -782,7 +755,7 @@ static int apic_reg_read(struct kvm_lapic *apic, u32 offset, int len, | |||
782 | 755 | ||
783 | static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr) | 756 | static int apic_mmio_in_range(struct kvm_lapic *apic, gpa_t addr) |
784 | { | 757 | { |
785 | return apic_hw_enabled(apic) && | 758 | return kvm_apic_hw_enabled(apic) && |
786 | addr >= apic->base_address && | 759 | addr >= apic->base_address && |
787 | addr < apic->base_address + LAPIC_MMIO_LENGTH; | 760 | addr < apic->base_address + LAPIC_MMIO_LENGTH; |
788 | } | 761 | } |
@@ -805,7 +778,7 @@ static void update_divide_count(struct kvm_lapic *apic) | |||
805 | { | 778 | { |
806 | u32 tmp1, tmp2, tdcr; | 779 | u32 tmp1, tmp2, tdcr; |
807 | 780 | ||
808 | tdcr = apic_get_reg(apic, APIC_TDCR); | 781 | tdcr = kvm_apic_get_reg(apic, APIC_TDCR); |
809 | tmp1 = tdcr & 0xf; | 782 | tmp1 = tdcr & 0xf; |
810 | tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1; | 783 | tmp2 = ((tmp1 & 0x3) | ((tmp1 & 0x8) >> 1)) + 1; |
811 | apic->divide_count = 0x1 << (tmp2 & 0x7); | 784 | apic->divide_count = 0x1 << (tmp2 & 0x7); |
@@ -822,7 +795,7 @@ static void start_apic_timer(struct kvm_lapic *apic) | |||
822 | if (apic_lvtt_period(apic) || apic_lvtt_oneshot(apic)) { | 795 | if (apic_lvtt_period(apic) || apic_lvtt_oneshot(apic)) { |
823 | /* lapic timer in oneshot or periodic mode */ | 796 | /* lapic timer in oneshot or periodic mode */ |
824 | now = apic->lapic_timer.timer.base->get_time(); | 797 | now = apic->lapic_timer.timer.base->get_time(); |
825 | apic->lapic_timer.period = (u64)apic_get_reg(apic, APIC_TMICT) | 798 | apic->lapic_timer.period = (u64)kvm_apic_get_reg(apic, APIC_TMICT) |
826 | * APIC_BUS_CYCLE_NS * apic->divide_count; | 799 | * APIC_BUS_CYCLE_NS * apic->divide_count; |
827 | 800 | ||
828 | if (!apic->lapic_timer.period) | 801 | if (!apic->lapic_timer.period) |
@@ -854,7 +827,7 @@ static void start_apic_timer(struct kvm_lapic *apic) | |||
854 | "timer initial count 0x%x, period %lldns, " | 827 | "timer initial count 0x%x, period %lldns, " |
855 | "expire @ 0x%016" PRIx64 ".\n", __func__, | 828 | "expire @ 0x%016" PRIx64 ".\n", __func__, |
856 | APIC_BUS_CYCLE_NS, ktime_to_ns(now), | 829 | APIC_BUS_CYCLE_NS, ktime_to_ns(now), |
857 | apic_get_reg(apic, APIC_TMICT), | 830 | kvm_apic_get_reg(apic, APIC_TMICT), |
858 | apic->lapic_timer.period, | 831 | apic->lapic_timer.period, |
859 | ktime_to_ns(ktime_add_ns(now, | 832 | ktime_to_ns(ktime_add_ns(now, |
860 | apic->lapic_timer.period))); | 833 | apic->lapic_timer.period))); |
@@ -886,7 +859,7 @@ static void start_apic_timer(struct kvm_lapic *apic) | |||
886 | 859 | ||
887 | static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) | 860 | static void apic_manage_nmi_watchdog(struct kvm_lapic *apic, u32 lvt0_val) |
888 | { | 861 | { |
889 | int nmi_wd_enabled = apic_lvt_nmi_mode(apic_get_reg(apic, APIC_LVT0)); | 862 | int nmi_wd_enabled = apic_lvt_nmi_mode(kvm_apic_get_reg(apic, APIC_LVT0)); |
890 | 863 | ||
891 | if (apic_lvt_nmi_mode(lvt0_val)) { | 864 | if (apic_lvt_nmi_mode(lvt0_val)) { |
892 | if (!nmi_wd_enabled) { | 865 | if (!nmi_wd_enabled) { |
@@ -937,7 +910,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) | |||
937 | 910 | ||
938 | case APIC_SPIV: { | 911 | case APIC_SPIV: { |
939 | u32 mask = 0x3ff; | 912 | u32 mask = 0x3ff; |
940 | if (apic_get_reg(apic, APIC_LVR) & APIC_LVR_DIRECTED_EOI) | 913 | if (kvm_apic_get_reg(apic, APIC_LVR) & APIC_LVR_DIRECTED_EOI) |
941 | mask |= APIC_SPIV_DIRECTED_EOI; | 914 | mask |= APIC_SPIV_DIRECTED_EOI; |
942 | apic_set_spiv(apic, val & mask); | 915 | apic_set_spiv(apic, val & mask); |
943 | if (!(val & APIC_SPIV_APIC_ENABLED)) { | 916 | if (!(val & APIC_SPIV_APIC_ENABLED)) { |
@@ -945,7 +918,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) | |||
945 | u32 lvt_val; | 918 | u32 lvt_val; |
946 | 919 | ||
947 | for (i = 0; i < APIC_LVT_NUM; i++) { | 920 | for (i = 0; i < APIC_LVT_NUM; i++) { |
948 | lvt_val = apic_get_reg(apic, | 921 | lvt_val = kvm_apic_get_reg(apic, |
949 | APIC_LVTT + 0x10 * i); | 922 | APIC_LVTT + 0x10 * i); |
950 | apic_set_reg(apic, APIC_LVTT + 0x10 * i, | 923 | apic_set_reg(apic, APIC_LVTT + 0x10 * i, |
951 | lvt_val | APIC_LVT_MASKED); | 924 | lvt_val | APIC_LVT_MASKED); |
@@ -974,7 +947,7 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) | |||
974 | case APIC_LVT1: | 947 | case APIC_LVT1: |
975 | case APIC_LVTERR: | 948 | case APIC_LVTERR: |
976 | /* TODO: Check vector */ | 949 | /* TODO: Check vector */ |
977 | if (!apic_sw_enabled(apic)) | 950 | if (!kvm_apic_sw_enabled(apic)) |
978 | val |= APIC_LVT_MASKED; | 951 | val |= APIC_LVT_MASKED; |
979 | 952 | ||
980 | val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4]; | 953 | val &= apic_lvt_mask[(reg - APIC_LVTT) >> 4]; |
@@ -983,12 +956,12 @@ static int apic_reg_write(struct kvm_lapic *apic, u32 reg, u32 val) | |||
983 | break; | 956 | break; |
984 | 957 | ||
985 | case APIC_LVTT: | 958 | case APIC_LVTT: |
986 | if ((apic_get_reg(apic, APIC_LVTT) & | 959 | if ((kvm_apic_get_reg(apic, APIC_LVTT) & |
987 | apic->lapic_timer.timer_mode_mask) != | 960 | apic->lapic_timer.timer_mode_mask) != |
988 | (val & apic->lapic_timer.timer_mode_mask)) | 961 | (val & apic->lapic_timer.timer_mode_mask)) |
989 | hrtimer_cancel(&apic->lapic_timer.timer); | 962 | hrtimer_cancel(&apic->lapic_timer.timer); |
990 | 963 | ||
991 | if (!apic_sw_enabled(apic)) | 964 | if (!kvm_apic_sw_enabled(apic)) |
992 | val |= APIC_LVT_MASKED; | 965 | val |= APIC_LVT_MASKED; |
993 | val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask); | 966 | val &= (apic_lvt_mask[0] | apic->lapic_timer.timer_mode_mask); |
994 | apic_set_reg(apic, APIC_LVTT, val); | 967 | apic_set_reg(apic, APIC_LVTT, val); |
@@ -1067,7 +1040,7 @@ static int apic_mmio_write(struct kvm_io_device *this, | |||
1067 | 1040 | ||
1068 | void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu) | 1041 | void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu) |
1069 | { | 1042 | { |
1070 | if (vcpu_has_lapic(vcpu)) | 1043 | if (kvm_vcpu_has_lapic(vcpu)) |
1071 | apic_reg_write(vcpu->arch.apic, APIC_EOI, 0); | 1044 | apic_reg_write(vcpu->arch.apic, APIC_EOI, 0); |
1072 | } | 1045 | } |
1073 | EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi); | 1046 | EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi); |
@@ -1084,7 +1057,7 @@ void kvm_free_lapic(struct kvm_vcpu *vcpu) | |||
1084 | if (!(vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE)) | 1057 | if (!(vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE)) |
1085 | static_key_slow_dec_deferred(&apic_hw_disabled); | 1058 | static_key_slow_dec_deferred(&apic_hw_disabled); |
1086 | 1059 | ||
1087 | if (!(apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED)) | 1060 | if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED)) |
1088 | static_key_slow_dec_deferred(&apic_sw_disabled); | 1061 | static_key_slow_dec_deferred(&apic_sw_disabled); |
1089 | 1062 | ||
1090 | if (apic->regs) | 1063 | if (apic->regs) |
@@ -1103,7 +1076,7 @@ u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu) | |||
1103 | { | 1076 | { |
1104 | struct kvm_lapic *apic = vcpu->arch.apic; | 1077 | struct kvm_lapic *apic = vcpu->arch.apic; |
1105 | 1078 | ||
1106 | if (!vcpu_has_lapic(vcpu) || apic_lvtt_oneshot(apic) || | 1079 | if (!kvm_vcpu_has_lapic(vcpu) || apic_lvtt_oneshot(apic) || |
1107 | apic_lvtt_period(apic)) | 1080 | apic_lvtt_period(apic)) |
1108 | return 0; | 1081 | return 0; |
1109 | 1082 | ||
@@ -1114,7 +1087,7 @@ void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data) | |||
1114 | { | 1087 | { |
1115 | struct kvm_lapic *apic = vcpu->arch.apic; | 1088 | struct kvm_lapic *apic = vcpu->arch.apic; |
1116 | 1089 | ||
1117 | if (!vcpu_has_lapic(vcpu) || apic_lvtt_oneshot(apic) || | 1090 | if (!kvm_vcpu_has_lapic(vcpu) || apic_lvtt_oneshot(apic) || |
1118 | apic_lvtt_period(apic)) | 1091 | apic_lvtt_period(apic)) |
1119 | return; | 1092 | return; |
1120 | 1093 | ||
@@ -1127,21 +1100,21 @@ void kvm_lapic_set_tpr(struct kvm_vcpu *vcpu, unsigned long cr8) | |||
1127 | { | 1100 | { |
1128 | struct kvm_lapic *apic = vcpu->arch.apic; | 1101 | struct kvm_lapic *apic = vcpu->arch.apic; |
1129 | 1102 | ||
1130 | if (!vcpu_has_lapic(vcpu)) | 1103 | if (!kvm_vcpu_has_lapic(vcpu)) |
1131 | return; | 1104 | return; |
1132 | 1105 | ||
1133 | apic_set_tpr(apic, ((cr8 & 0x0f) << 4) | 1106 | apic_set_tpr(apic, ((cr8 & 0x0f) << 4) |
1134 | | (apic_get_reg(apic, APIC_TASKPRI) & 4)); | 1107 | | (kvm_apic_get_reg(apic, APIC_TASKPRI) & 4)); |
1135 | } | 1108 | } |
1136 | 1109 | ||
1137 | u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) | 1110 | u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) |
1138 | { | 1111 | { |
1139 | u64 tpr; | 1112 | u64 tpr; |
1140 | 1113 | ||
1141 | if (!vcpu_has_lapic(vcpu)) | 1114 | if (!kvm_vcpu_has_lapic(vcpu)) |
1142 | return 0; | 1115 | return 0; |
1143 | 1116 | ||
1144 | tpr = (u64) apic_get_reg(vcpu->arch.apic, APIC_TASKPRI); | 1117 | tpr = (u64) kvm_apic_get_reg(vcpu->arch.apic, APIC_TASKPRI); |
1145 | 1118 | ||
1146 | return (tpr & 0xf0) >> 4; | 1119 | return (tpr & 0xf0) >> 4; |
1147 | } | 1120 | } |
@@ -1238,16 +1211,6 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
1238 | vcpu->arch.apic_base, apic->base_address); | 1211 | vcpu->arch.apic_base, apic->base_address); |
1239 | } | 1212 | } |
1240 | 1213 | ||
1241 | bool kvm_apic_present(struct kvm_vcpu *vcpu) | ||
1242 | { | ||
1243 | return vcpu_has_lapic(vcpu) && apic_hw_enabled(vcpu->arch.apic); | ||
1244 | } | ||
1245 | |||
1246 | int kvm_lapic_enabled(struct kvm_vcpu *vcpu) | ||
1247 | { | ||
1248 | return kvm_apic_present(vcpu) && apic_sw_enabled(vcpu->arch.apic); | ||
1249 | } | ||
1250 | |||
1251 | /* | 1214 | /* |
1252 | *---------------------------------------------------------------------- | 1215 | *---------------------------------------------------------------------- |
1253 | * timer interface | 1216 | * timer interface |
@@ -1263,7 +1226,7 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu) | |||
1263 | { | 1226 | { |
1264 | struct kvm_lapic *apic = vcpu->arch.apic; | 1227 | struct kvm_lapic *apic = vcpu->arch.apic; |
1265 | 1228 | ||
1266 | if (vcpu_has_lapic(vcpu) && apic_enabled(apic) && | 1229 | if (kvm_vcpu_has_lapic(vcpu) && apic_enabled(apic) && |
1267 | apic_lvt_enabled(apic, APIC_LVTT)) | 1230 | apic_lvt_enabled(apic, APIC_LVTT)) |
1268 | return atomic_read(&apic->lapic_timer.pending); | 1231 | return atomic_read(&apic->lapic_timer.pending); |
1269 | 1232 | ||
@@ -1272,10 +1235,10 @@ int apic_has_pending_timer(struct kvm_vcpu *vcpu) | |||
1272 | 1235 | ||
1273 | int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type) | 1236 | int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type) |
1274 | { | 1237 | { |
1275 | u32 reg = apic_get_reg(apic, lvt_type); | 1238 | u32 reg = kvm_apic_get_reg(apic, lvt_type); |
1276 | int vector, mode, trig_mode; | 1239 | int vector, mode, trig_mode; |
1277 | 1240 | ||
1278 | if (apic_hw_enabled(apic) && !(reg & APIC_LVT_MASKED)) { | 1241 | if (kvm_apic_hw_enabled(apic) && !(reg & APIC_LVT_MASKED)) { |
1279 | vector = reg & APIC_VECTOR_MASK; | 1242 | vector = reg & APIC_VECTOR_MASK; |
1280 | mode = reg & APIC_MODE_MASK; | 1243 | mode = reg & APIC_MODE_MASK; |
1281 | trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; | 1244 | trig_mode = reg & APIC_LVT_LEVEL_TRIGGER; |
@@ -1375,23 +1338,23 @@ int kvm_apic_has_interrupt(struct kvm_vcpu *vcpu) | |||
1375 | struct kvm_lapic *apic = vcpu->arch.apic; | 1338 | struct kvm_lapic *apic = vcpu->arch.apic; |
1376 | int highest_irr; | 1339 | int highest_irr; |
1377 | 1340 | ||
1378 | if (!vcpu_has_lapic(vcpu) || !apic_enabled(apic)) | 1341 | if (!kvm_vcpu_has_lapic(vcpu) || !apic_enabled(apic)) |
1379 | return -1; | 1342 | return -1; |
1380 | 1343 | ||
1381 | apic_update_ppr(apic); | 1344 | apic_update_ppr(apic); |
1382 | highest_irr = apic_find_highest_irr(apic); | 1345 | highest_irr = apic_find_highest_irr(apic); |
1383 | if ((highest_irr == -1) || | 1346 | if ((highest_irr == -1) || |
1384 | ((highest_irr & 0xF0) <= apic_get_reg(apic, APIC_PROCPRI))) | 1347 | ((highest_irr & 0xF0) <= kvm_apic_get_reg(apic, APIC_PROCPRI))) |
1385 | return -1; | 1348 | return -1; |
1386 | return highest_irr; | 1349 | return highest_irr; |
1387 | } | 1350 | } |
1388 | 1351 | ||
1389 | int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu) | 1352 | int kvm_apic_accept_pic_intr(struct kvm_vcpu *vcpu) |
1390 | { | 1353 | { |
1391 | u32 lvt0 = apic_get_reg(vcpu->arch.apic, APIC_LVT0); | 1354 | u32 lvt0 = kvm_apic_get_reg(vcpu->arch.apic, APIC_LVT0); |
1392 | int r = 0; | 1355 | int r = 0; |
1393 | 1356 | ||
1394 | if (!apic_hw_enabled(vcpu->arch.apic)) | 1357 | if (!kvm_apic_hw_enabled(vcpu->arch.apic)) |
1395 | r = 1; | 1358 | r = 1; |
1396 | if ((lvt0 & APIC_LVT_MASKED) == 0 && | 1359 | if ((lvt0 & APIC_LVT_MASKED) == 0 && |
1397 | GET_APIC_DELIVERY_MODE(lvt0) == APIC_MODE_EXTINT) | 1360 | GET_APIC_DELIVERY_MODE(lvt0) == APIC_MODE_EXTINT) |
@@ -1403,7 +1366,7 @@ void kvm_inject_apic_timer_irqs(struct kvm_vcpu *vcpu) | |||
1403 | { | 1366 | { |
1404 | struct kvm_lapic *apic = vcpu->arch.apic; | 1367 | struct kvm_lapic *apic = vcpu->arch.apic; |
1405 | 1368 | ||
1406 | if (!vcpu_has_lapic(vcpu)) | 1369 | if (!kvm_vcpu_has_lapic(vcpu)) |
1407 | return; | 1370 | return; |
1408 | 1371 | ||
1409 | if (atomic_read(&apic->lapic_timer.pending) > 0) { | 1372 | if (atomic_read(&apic->lapic_timer.pending) > 0) { |
@@ -1432,7 +1395,7 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu) | |||
1432 | 1395 | ||
1433 | kvm_lapic_set_base(vcpu, vcpu->arch.apic_base); | 1396 | kvm_lapic_set_base(vcpu, vcpu->arch.apic_base); |
1434 | kvm_apic_set_version(vcpu); | 1397 | kvm_apic_set_version(vcpu); |
1435 | apic_set_spiv(apic, apic_get_reg(apic, APIC_SPIV)); | 1398 | apic_set_spiv(apic, kvm_apic_get_reg(apic, APIC_SPIV)); |
1436 | 1399 | ||
1437 | apic_update_ppr(apic); | 1400 | apic_update_ppr(apic); |
1438 | hrtimer_cancel(&apic->lapic_timer.timer); | 1401 | hrtimer_cancel(&apic->lapic_timer.timer); |
@@ -1448,7 +1411,7 @@ void __kvm_migrate_apic_timer(struct kvm_vcpu *vcpu) | |||
1448 | { | 1411 | { |
1449 | struct hrtimer *timer; | 1412 | struct hrtimer *timer; |
1450 | 1413 | ||
1451 | if (!vcpu_has_lapic(vcpu)) | 1414 | if (!kvm_vcpu_has_lapic(vcpu)) |
1452 | return; | 1415 | return; |
1453 | 1416 | ||
1454 | timer = &vcpu->arch.apic->lapic_timer.timer; | 1417 | timer = &vcpu->arch.apic->lapic_timer.timer; |
@@ -1549,7 +1512,7 @@ void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu) | |||
1549 | if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention)) | 1512 | if (!test_bit(KVM_APIC_CHECK_VAPIC, &vcpu->arch.apic_attention)) |
1550 | return; | 1513 | return; |
1551 | 1514 | ||
1552 | tpr = apic_get_reg(apic, APIC_TASKPRI) & 0xff; | 1515 | tpr = kvm_apic_get_reg(apic, APIC_TASKPRI) & 0xff; |
1553 | max_irr = apic_find_highest_irr(apic); | 1516 | max_irr = apic_find_highest_irr(apic); |
1554 | if (max_irr < 0) | 1517 | if (max_irr < 0) |
1555 | max_irr = 0; | 1518 | max_irr = 0; |
@@ -1608,7 +1571,7 @@ int kvm_hv_vapic_msr_write(struct kvm_vcpu *vcpu, u32 reg, u64 data) | |||
1608 | { | 1571 | { |
1609 | struct kvm_lapic *apic = vcpu->arch.apic; | 1572 | struct kvm_lapic *apic = vcpu->arch.apic; |
1610 | 1573 | ||
1611 | if (!vcpu_has_lapic(vcpu)) | 1574 | if (!kvm_vcpu_has_lapic(vcpu)) |
1612 | return 1; | 1575 | return 1; |
1613 | 1576 | ||
1614 | /* if this is ICR write vector before command */ | 1577 | /* if this is ICR write vector before command */ |
@@ -1622,7 +1585,7 @@ int kvm_hv_vapic_msr_read(struct kvm_vcpu *vcpu, u32 reg, u64 *data) | |||
1622 | struct kvm_lapic *apic = vcpu->arch.apic; | 1585 | struct kvm_lapic *apic = vcpu->arch.apic; |
1623 | u32 low, high = 0; | 1586 | u32 low, high = 0; |
1624 | 1587 | ||
1625 | if (!vcpu_has_lapic(vcpu)) | 1588 | if (!kvm_vcpu_has_lapic(vcpu)) |
1626 | return 1; | 1589 | return 1; |
1627 | 1590 | ||
1628 | if (apic_reg_read(apic, reg, 4, &low)) | 1591 | if (apic_reg_read(apic, reg, 4, &low)) |
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index 73fa299b68e8..2ad9caa06f94 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h | |||
@@ -55,8 +55,6 @@ int kvm_apic_local_deliver(struct kvm_lapic *apic, int lvt_type); | |||
55 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); | 55 | u64 kvm_get_apic_base(struct kvm_vcpu *vcpu); |
56 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); | 56 | void kvm_set_apic_base(struct kvm_vcpu *vcpu, u64 data); |
57 | void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); | 57 | void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu); |
58 | int kvm_lapic_enabled(struct kvm_vcpu *vcpu); | ||
59 | bool kvm_apic_present(struct kvm_vcpu *vcpu); | ||
60 | int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); | 58 | int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); |
61 | 59 | ||
62 | u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu); | 60 | u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu); |
@@ -79,4 +77,47 @@ static inline bool kvm_hv_vapic_assist_page_enabled(struct kvm_vcpu *vcpu) | |||
79 | 77 | ||
80 | int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data); | 78 | int kvm_lapic_enable_pv_eoi(struct kvm_vcpu *vcpu, u64 data); |
81 | void kvm_lapic_init(void); | 79 | void kvm_lapic_init(void); |
80 | |||
81 | static inline u32 kvm_apic_get_reg(struct kvm_lapic *apic, int reg_off) | ||
82 | { | ||
83 | return *((u32 *) (apic->regs + reg_off)); | ||
84 | } | ||
85 | |||
86 | extern struct static_key kvm_no_apic_vcpu; | ||
87 | |||
88 | static inline bool kvm_vcpu_has_lapic(struct kvm_vcpu *vcpu) | ||
89 | { | ||
90 | if (static_key_false(&kvm_no_apic_vcpu)) | ||
91 | return vcpu->arch.apic; | ||
92 | return true; | ||
93 | } | ||
94 | |||
95 | extern struct static_key_deferred apic_hw_disabled; | ||
96 | |||
97 | static inline int kvm_apic_hw_enabled(struct kvm_lapic *apic) | ||
98 | { | ||
99 | if (static_key_false(&apic_hw_disabled.key)) | ||
100 | return apic->vcpu->arch.apic_base & MSR_IA32_APICBASE_ENABLE; | ||
101 | return MSR_IA32_APICBASE_ENABLE; | ||
102 | } | ||
103 | |||
104 | extern struct static_key_deferred apic_sw_disabled; | ||
105 | |||
106 | static inline int kvm_apic_sw_enabled(struct kvm_lapic *apic) | ||
107 | { | ||
108 | if (static_key_false(&apic_sw_disabled.key)) | ||
109 | return kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_APIC_ENABLED; | ||
110 | return APIC_SPIV_APIC_ENABLED; | ||
111 | } | ||
112 | |||
113 | static inline bool kvm_apic_present(struct kvm_vcpu *vcpu) | ||
114 | { | ||
115 | return kvm_vcpu_has_lapic(vcpu) && kvm_apic_hw_enabled(vcpu->arch.apic); | ||
116 | } | ||
117 | |||
118 | static inline int kvm_lapic_enabled(struct kvm_vcpu *vcpu) | ||
119 | { | ||
120 | return kvm_apic_present(vcpu) && kvm_apic_sw_enabled(vcpu->arch.apic); | ||
121 | } | ||
122 | |||
82 | #endif | 123 | #endif |