diff options
author | Alexander Graf <agraf@suse.de> | 2013-02-13 06:56:14 -0500 |
---|---|---|
committer | Alexander Graf <agraf@suse.de> | 2013-02-13 06:56:14 -0500 |
commit | dd92d6f2749c43ebab91c4762a1bc79e6523e936 (patch) | |
tree | 6e6730bdd09284679c0861df6d0fcbec08ea7a87 /arch/x86 | |
parent | b9e3e208935e95ad62bd1b1bc4408c23a9ae3ada (diff) | |
parent | b0da5bec30eca7ffbb2c89afa6fe503fd418d3a6 (diff) |
Merge commit 'origin/next' into kvm-ppc-next
Diffstat (limited to 'arch/x86')
-rw-r--r-- | arch/x86/include/asm/kvm_host.h | 6 | ||||
-rw-r--r-- | arch/x86/include/asm/vmx.h | 21 | ||||
-rw-r--r-- | arch/x86/kvm/emulate.c | 2 | ||||
-rw-r--r-- | arch/x86/kvm/irq.c | 56 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.c | 140 | ||||
-rw-r--r-- | arch/x86/kvm/lapic.h | 34 | ||||
-rw-r--r-- | arch/x86/kvm/mmu.c | 32 | ||||
-rw-r--r-- | arch/x86/kvm/paging_tmpl.h | 3 | ||||
-rw-r--r-- | arch/x86/kvm/svm.c | 24 | ||||
-rw-r--r-- | arch/x86/kvm/vmx.c | 336 | ||||
-rw-r--r-- | arch/x86/kvm/x86.c | 25 |
11 files changed, 590 insertions, 89 deletions
diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h index 77d56a4ba89c..635a74d22409 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h | |||
@@ -699,6 +699,11 @@ struct kvm_x86_ops { | |||
699 | void (*enable_nmi_window)(struct kvm_vcpu *vcpu); | 699 | void (*enable_nmi_window)(struct kvm_vcpu *vcpu); |
700 | void (*enable_irq_window)(struct kvm_vcpu *vcpu); | 700 | void (*enable_irq_window)(struct kvm_vcpu *vcpu); |
701 | void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr); | 701 | void (*update_cr8_intercept)(struct kvm_vcpu *vcpu, int tpr, int irr); |
702 | int (*vm_has_apicv)(struct kvm *kvm); | ||
703 | void (*hwapic_irr_update)(struct kvm_vcpu *vcpu, int max_irr); | ||
704 | void (*hwapic_isr_update)(struct kvm *kvm, int isr); | ||
705 | void (*load_eoi_exitmap)(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap); | ||
706 | void (*set_virtual_x2apic_mode)(struct kvm_vcpu *vcpu, bool set); | ||
702 | int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); | 707 | int (*set_tss_addr)(struct kvm *kvm, unsigned int addr); |
703 | int (*get_tdp_level)(void); | 708 | int (*get_tdp_level)(void); |
704 | u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); | 709 | u64 (*get_mt_mask)(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio); |
@@ -993,6 +998,7 @@ int kvm_age_hva(struct kvm *kvm, unsigned long hva); | |||
993 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); | 998 | int kvm_test_age_hva(struct kvm *kvm, unsigned long hva); |
994 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); | 999 | void kvm_set_spte_hva(struct kvm *kvm, unsigned long hva, pte_t pte); |
995 | int cpuid_maxphyaddr(struct kvm_vcpu *vcpu); | 1000 | int cpuid_maxphyaddr(struct kvm_vcpu *vcpu); |
1001 | int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v); | ||
996 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); | 1002 | int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); |
997 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); | 1003 | int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); |
998 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v); | 1004 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v); |
diff --git a/arch/x86/include/asm/vmx.h b/arch/x86/include/asm/vmx.h index e385df97bfdc..5c9dbadd364a 100644 --- a/arch/x86/include/asm/vmx.h +++ b/arch/x86/include/asm/vmx.h | |||
@@ -62,10 +62,12 @@ | |||
62 | #define EXIT_REASON_MCE_DURING_VMENTRY 41 | 62 | #define EXIT_REASON_MCE_DURING_VMENTRY 41 |
63 | #define EXIT_REASON_TPR_BELOW_THRESHOLD 43 | 63 | #define EXIT_REASON_TPR_BELOW_THRESHOLD 43 |
64 | #define EXIT_REASON_APIC_ACCESS 44 | 64 | #define EXIT_REASON_APIC_ACCESS 44 |
65 | #define EXIT_REASON_EOI_INDUCED 45 | ||
65 | #define EXIT_REASON_EPT_VIOLATION 48 | 66 | #define EXIT_REASON_EPT_VIOLATION 48 |
66 | #define EXIT_REASON_EPT_MISCONFIG 49 | 67 | #define EXIT_REASON_EPT_MISCONFIG 49 |
67 | #define EXIT_REASON_WBINVD 54 | 68 | #define EXIT_REASON_WBINVD 54 |
68 | #define EXIT_REASON_XSETBV 55 | 69 | #define EXIT_REASON_XSETBV 55 |
70 | #define EXIT_REASON_APIC_WRITE 56 | ||
69 | #define EXIT_REASON_INVPCID 58 | 71 | #define EXIT_REASON_INVPCID 58 |
70 | 72 | ||
71 | #define VMX_EXIT_REASONS \ | 73 | #define VMX_EXIT_REASONS \ |
@@ -103,7 +105,12 @@ | |||
103 | { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \ | 105 | { EXIT_REASON_APIC_ACCESS, "APIC_ACCESS" }, \ |
104 | { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \ | 106 | { EXIT_REASON_EPT_VIOLATION, "EPT_VIOLATION" }, \ |
105 | { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \ | 107 | { EXIT_REASON_EPT_MISCONFIG, "EPT_MISCONFIG" }, \ |
106 | { EXIT_REASON_WBINVD, "WBINVD" } | 108 | { EXIT_REASON_WBINVD, "WBINVD" }, \ |
109 | { EXIT_REASON_APIC_WRITE, "APIC_WRITE" }, \ | ||
110 | { EXIT_REASON_EOI_INDUCED, "EOI_INDUCED" }, \ | ||
111 | { EXIT_REASON_INVALID_STATE, "INVALID_STATE" }, \ | ||
112 | { EXIT_REASON_INVD, "INVD" }, \ | ||
113 | { EXIT_REASON_INVPCID, "INVPCID" } | ||
107 | 114 | ||
108 | #ifdef __KERNEL__ | 115 | #ifdef __KERNEL__ |
109 | 116 | ||
@@ -138,9 +145,12 @@ | |||
138 | #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 | 145 | #define SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES 0x00000001 |
139 | #define SECONDARY_EXEC_ENABLE_EPT 0x00000002 | 146 | #define SECONDARY_EXEC_ENABLE_EPT 0x00000002 |
140 | #define SECONDARY_EXEC_RDTSCP 0x00000008 | 147 | #define SECONDARY_EXEC_RDTSCP 0x00000008 |
148 | #define SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE 0x00000010 | ||
141 | #define SECONDARY_EXEC_ENABLE_VPID 0x00000020 | 149 | #define SECONDARY_EXEC_ENABLE_VPID 0x00000020 |
142 | #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 | 150 | #define SECONDARY_EXEC_WBINVD_EXITING 0x00000040 |
143 | #define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080 | 151 | #define SECONDARY_EXEC_UNRESTRICTED_GUEST 0x00000080 |
152 | #define SECONDARY_EXEC_APIC_REGISTER_VIRT 0x00000100 | ||
153 | #define SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY 0x00000200 | ||
144 | #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 | 154 | #define SECONDARY_EXEC_PAUSE_LOOP_EXITING 0x00000400 |
145 | #define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 | 155 | #define SECONDARY_EXEC_ENABLE_INVPCID 0x00001000 |
146 | 156 | ||
@@ -178,6 +188,7 @@ enum vmcs_field { | |||
178 | GUEST_GS_SELECTOR = 0x0000080a, | 188 | GUEST_GS_SELECTOR = 0x0000080a, |
179 | GUEST_LDTR_SELECTOR = 0x0000080c, | 189 | GUEST_LDTR_SELECTOR = 0x0000080c, |
180 | GUEST_TR_SELECTOR = 0x0000080e, | 190 | GUEST_TR_SELECTOR = 0x0000080e, |
191 | GUEST_INTR_STATUS = 0x00000810, | ||
181 | HOST_ES_SELECTOR = 0x00000c00, | 192 | HOST_ES_SELECTOR = 0x00000c00, |
182 | HOST_CS_SELECTOR = 0x00000c02, | 193 | HOST_CS_SELECTOR = 0x00000c02, |
183 | HOST_SS_SELECTOR = 0x00000c04, | 194 | HOST_SS_SELECTOR = 0x00000c04, |
@@ -205,6 +216,14 @@ enum vmcs_field { | |||
205 | APIC_ACCESS_ADDR_HIGH = 0x00002015, | 216 | APIC_ACCESS_ADDR_HIGH = 0x00002015, |
206 | EPT_POINTER = 0x0000201a, | 217 | EPT_POINTER = 0x0000201a, |
207 | EPT_POINTER_HIGH = 0x0000201b, | 218 | EPT_POINTER_HIGH = 0x0000201b, |
219 | EOI_EXIT_BITMAP0 = 0x0000201c, | ||
220 | EOI_EXIT_BITMAP0_HIGH = 0x0000201d, | ||
221 | EOI_EXIT_BITMAP1 = 0x0000201e, | ||
222 | EOI_EXIT_BITMAP1_HIGH = 0x0000201f, | ||
223 | EOI_EXIT_BITMAP2 = 0x00002020, | ||
224 | EOI_EXIT_BITMAP2_HIGH = 0x00002021, | ||
225 | EOI_EXIT_BITMAP3 = 0x00002022, | ||
226 | EOI_EXIT_BITMAP3_HIGH = 0x00002023, | ||
208 | GUEST_PHYSICAL_ADDRESS = 0x00002400, | 227 | GUEST_PHYSICAL_ADDRESS = 0x00002400, |
209 | GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401, | 228 | GUEST_PHYSICAL_ADDRESS_HIGH = 0x00002401, |
210 | VMCS_LINK_POINTER = 0x00002800, | 229 | VMCS_LINK_POINTER = 0x00002800, |
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index e99fb72cd4c5..2b11318151a4 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c | |||
@@ -1013,7 +1013,7 @@ static u8 test_cc(unsigned int condition, unsigned long flags) | |||
1013 | void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf); | 1013 | void (*fop)(void) = (void *)em_setcc + 4 * (condition & 0xf); |
1014 | 1014 | ||
1015 | flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF; | 1015 | flags = (flags & EFLAGS_MASK) | X86_EFLAGS_IF; |
1016 | asm("pushq %[flags]; popf; call *%[fastop]" | 1016 | asm("push %[flags]; popf; call *%[fastop]" |
1017 | : "=a"(rc) : [fastop]"r"(fop), [flags]"r"(flags)); | 1017 | : "=a"(rc) : [fastop]"r"(fop), [flags]"r"(flags)); |
1018 | return rc; | 1018 | return rc; |
1019 | } | 1019 | } |
diff --git a/arch/x86/kvm/irq.c b/arch/x86/kvm/irq.c index b111aee815f8..484bc874688b 100644 --- a/arch/x86/kvm/irq.c +++ b/arch/x86/kvm/irq.c | |||
@@ -38,6 +38,38 @@ int kvm_cpu_has_pending_timer(struct kvm_vcpu *vcpu) | |||
38 | EXPORT_SYMBOL(kvm_cpu_has_pending_timer); | 38 | EXPORT_SYMBOL(kvm_cpu_has_pending_timer); |
39 | 39 | ||
40 | /* | 40 | /* |
41 | * check if there is pending interrupt from | ||
42 | * non-APIC source without intack. | ||
43 | */ | ||
44 | static int kvm_cpu_has_extint(struct kvm_vcpu *v) | ||
45 | { | ||
46 | if (kvm_apic_accept_pic_intr(v)) | ||
47 | return pic_irqchip(v->kvm)->output; /* PIC */ | ||
48 | else | ||
49 | return 0; | ||
50 | } | ||
51 | |||
52 | /* | ||
53 | * check if there is injectable interrupt: | ||
54 | * when virtual interrupt delivery enabled, | ||
55 | * interrupt from apic will handled by hardware, | ||
56 | * we don't need to check it here. | ||
57 | */ | ||
58 | int kvm_cpu_has_injectable_intr(struct kvm_vcpu *v) | ||
59 | { | ||
60 | if (!irqchip_in_kernel(v->kvm)) | ||
61 | return v->arch.interrupt.pending; | ||
62 | |||
63 | if (kvm_cpu_has_extint(v)) | ||
64 | return 1; | ||
65 | |||
66 | if (kvm_apic_vid_enabled(v->kvm)) | ||
67 | return 0; | ||
68 | |||
69 | return kvm_apic_has_interrupt(v) != -1; /* LAPIC */ | ||
70 | } | ||
71 | |||
72 | /* | ||
41 | * check if there is pending interrupt without | 73 | * check if there is pending interrupt without |
42 | * intack. | 74 | * intack. |
43 | */ | 75 | */ |
@@ -46,27 +78,41 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *v) | |||
46 | if (!irqchip_in_kernel(v->kvm)) | 78 | if (!irqchip_in_kernel(v->kvm)) |
47 | return v->arch.interrupt.pending; | 79 | return v->arch.interrupt.pending; |
48 | 80 | ||
49 | if (kvm_apic_accept_pic_intr(v) && pic_irqchip(v->kvm)->output) | 81 | if (kvm_cpu_has_extint(v)) |
50 | return pic_irqchip(v->kvm)->output; /* PIC */ | 82 | return 1; |
51 | 83 | ||
52 | return kvm_apic_has_interrupt(v) != -1; /* LAPIC */ | 84 | return kvm_apic_has_interrupt(v) != -1; /* LAPIC */ |
53 | } | 85 | } |
54 | EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); | 86 | EXPORT_SYMBOL_GPL(kvm_cpu_has_interrupt); |
55 | 87 | ||
56 | /* | 88 | /* |
89 | * Read pending interrupt(from non-APIC source) | ||
90 | * vector and intack. | ||
91 | */ | ||
92 | static int kvm_cpu_get_extint(struct kvm_vcpu *v) | ||
93 | { | ||
94 | if (kvm_cpu_has_extint(v)) | ||
95 | return kvm_pic_read_irq(v->kvm); /* PIC */ | ||
96 | return -1; | ||
97 | } | ||
98 | |||
99 | /* | ||
57 | * Read pending interrupt vector and intack. | 100 | * Read pending interrupt vector and intack. |
58 | */ | 101 | */ |
59 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v) | 102 | int kvm_cpu_get_interrupt(struct kvm_vcpu *v) |
60 | { | 103 | { |
104 | int vector; | ||
105 | |||
61 | if (!irqchip_in_kernel(v->kvm)) | 106 | if (!irqchip_in_kernel(v->kvm)) |
62 | return v->arch.interrupt.nr; | 107 | return v->arch.interrupt.nr; |
63 | 108 | ||
64 | if (kvm_apic_accept_pic_intr(v) && pic_irqchip(v->kvm)->output) | 109 | vector = kvm_cpu_get_extint(v); |
65 | return kvm_pic_read_irq(v->kvm); /* PIC */ | 110 | |
111 | if (kvm_apic_vid_enabled(v->kvm) || vector != -1) | ||
112 | return vector; /* PIC */ | ||
66 | 113 | ||
67 | return kvm_get_apic_interrupt(v); /* APIC */ | 114 | return kvm_get_apic_interrupt(v); /* APIC */ |
68 | } | 115 | } |
69 | EXPORT_SYMBOL_GPL(kvm_cpu_get_interrupt); | ||
70 | 116 | ||
71 | void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu) | 117 | void kvm_inject_pending_timer_irqs(struct kvm_vcpu *vcpu) |
72 | { | 118 | { |
diff --git a/arch/x86/kvm/lapic.c b/arch/x86/kvm/lapic.c index 9392f527f107..02b51dd4e4ad 100644 --- a/arch/x86/kvm/lapic.c +++ b/arch/x86/kvm/lapic.c | |||
@@ -140,31 +140,56 @@ static inline int apic_enabled(struct kvm_lapic *apic) | |||
140 | (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \ | 140 | (LVT_MASK | APIC_MODE_MASK | APIC_INPUT_POLARITY | \ |
141 | APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER) | 141 | APIC_LVT_REMOTE_IRR | APIC_LVT_LEVEL_TRIGGER) |
142 | 142 | ||
143 | static inline int apic_x2apic_mode(struct kvm_lapic *apic) | ||
144 | { | ||
145 | return apic->vcpu->arch.apic_base & X2APIC_ENABLE; | ||
146 | } | ||
147 | |||
148 | static inline int kvm_apic_id(struct kvm_lapic *apic) | 143 | static inline int kvm_apic_id(struct kvm_lapic *apic) |
149 | { | 144 | { |
150 | return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; | 145 | return (kvm_apic_get_reg(apic, APIC_ID) >> 24) & 0xff; |
151 | } | 146 | } |
152 | 147 | ||
153 | static inline u16 apic_cluster_id(struct kvm_apic_map *map, u32 ldr) | 148 | void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu, |
149 | struct kvm_lapic_irq *irq, | ||
150 | u64 *eoi_exit_bitmap) | ||
154 | { | 151 | { |
155 | u16 cid; | 152 | struct kvm_lapic **dst; |
156 | ldr >>= 32 - map->ldr_bits; | 153 | struct kvm_apic_map *map; |
157 | cid = (ldr >> map->cid_shift) & map->cid_mask; | 154 | unsigned long bitmap = 1; |
155 | int i; | ||
158 | 156 | ||
159 | BUG_ON(cid >= ARRAY_SIZE(map->logical_map)); | 157 | rcu_read_lock(); |
158 | map = rcu_dereference(vcpu->kvm->arch.apic_map); | ||
160 | 159 | ||
161 | return cid; | 160 | if (unlikely(!map)) { |
162 | } | 161 | __set_bit(irq->vector, (unsigned long *)eoi_exit_bitmap); |
162 | goto out; | ||
163 | } | ||
163 | 164 | ||
164 | static inline u16 apic_logical_id(struct kvm_apic_map *map, u32 ldr) | 165 | if (irq->dest_mode == 0) { /* physical mode */ |
165 | { | 166 | if (irq->delivery_mode == APIC_DM_LOWEST || |
166 | ldr >>= (32 - map->ldr_bits); | 167 | irq->dest_id == 0xff) { |
167 | return ldr & map->lid_mask; | 168 | __set_bit(irq->vector, |
169 | (unsigned long *)eoi_exit_bitmap); | ||
170 | goto out; | ||
171 | } | ||
172 | dst = &map->phys_map[irq->dest_id & 0xff]; | ||
173 | } else { | ||
174 | u32 mda = irq->dest_id << (32 - map->ldr_bits); | ||
175 | |||
176 | dst = map->logical_map[apic_cluster_id(map, mda)]; | ||
177 | |||
178 | bitmap = apic_logical_id(map, mda); | ||
179 | } | ||
180 | |||
181 | for_each_set_bit(i, &bitmap, 16) { | ||
182 | if (!dst[i]) | ||
183 | continue; | ||
184 | if (dst[i]->vcpu == vcpu) { | ||
185 | __set_bit(irq->vector, | ||
186 | (unsigned long *)eoi_exit_bitmap); | ||
187 | break; | ||
188 | } | ||
189 | } | ||
190 | |||
191 | out: | ||
192 | rcu_read_unlock(); | ||
168 | } | 193 | } |
169 | 194 | ||
170 | static void recalculate_apic_map(struct kvm *kvm) | 195 | static void recalculate_apic_map(struct kvm *kvm) |
@@ -230,6 +255,8 @@ out: | |||
230 | 255 | ||
231 | if (old) | 256 | if (old) |
232 | kfree_rcu(old, rcu); | 257 | kfree_rcu(old, rcu); |
258 | |||
259 | kvm_ioapic_make_eoibitmap_request(kvm); | ||
233 | } | 260 | } |
234 | 261 | ||
235 | static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id) | 262 | static inline void kvm_apic_set_id(struct kvm_lapic *apic, u8 id) |
@@ -345,6 +372,10 @@ static inline int apic_find_highest_irr(struct kvm_lapic *apic) | |||
345 | { | 372 | { |
346 | int result; | 373 | int result; |
347 | 374 | ||
375 | /* | ||
376 | * Note that irr_pending is just a hint. It will be always | ||
377 | * true with virtual interrupt delivery enabled. | ||
378 | */ | ||
348 | if (!apic->irr_pending) | 379 | if (!apic->irr_pending) |
349 | return -1; | 380 | return -1; |
350 | 381 | ||
@@ -461,6 +492,8 @@ static void pv_eoi_clr_pending(struct kvm_vcpu *vcpu) | |||
461 | static inline int apic_find_highest_isr(struct kvm_lapic *apic) | 492 | static inline int apic_find_highest_isr(struct kvm_lapic *apic) |
462 | { | 493 | { |
463 | int result; | 494 | int result; |
495 | |||
496 | /* Note that isr_count is always 1 with vid enabled */ | ||
464 | if (!apic->isr_count) | 497 | if (!apic->isr_count) |
465 | return -1; | 498 | return -1; |
466 | if (likely(apic->highest_isr_cache != -1)) | 499 | if (likely(apic->highest_isr_cache != -1)) |
@@ -740,6 +773,19 @@ int kvm_apic_compare_prio(struct kvm_vcpu *vcpu1, struct kvm_vcpu *vcpu2) | |||
740 | return vcpu1->arch.apic_arb_prio - vcpu2->arch.apic_arb_prio; | 773 | return vcpu1->arch.apic_arb_prio - vcpu2->arch.apic_arb_prio; |
741 | } | 774 | } |
742 | 775 | ||
776 | static void kvm_ioapic_send_eoi(struct kvm_lapic *apic, int vector) | ||
777 | { | ||
778 | if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) && | ||
779 | kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) { | ||
780 | int trigger_mode; | ||
781 | if (apic_test_vector(vector, apic->regs + APIC_TMR)) | ||
782 | trigger_mode = IOAPIC_LEVEL_TRIG; | ||
783 | else | ||
784 | trigger_mode = IOAPIC_EDGE_TRIG; | ||
785 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); | ||
786 | } | ||
787 | } | ||
788 | |||
743 | static int apic_set_eoi(struct kvm_lapic *apic) | 789 | static int apic_set_eoi(struct kvm_lapic *apic) |
744 | { | 790 | { |
745 | int vector = apic_find_highest_isr(apic); | 791 | int vector = apic_find_highest_isr(apic); |
@@ -756,19 +802,26 @@ static int apic_set_eoi(struct kvm_lapic *apic) | |||
756 | apic_clear_isr(vector, apic); | 802 | apic_clear_isr(vector, apic); |
757 | apic_update_ppr(apic); | 803 | apic_update_ppr(apic); |
758 | 804 | ||
759 | if (!(kvm_apic_get_reg(apic, APIC_SPIV) & APIC_SPIV_DIRECTED_EOI) && | 805 | kvm_ioapic_send_eoi(apic, vector); |
760 | kvm_ioapic_handles_vector(apic->vcpu->kvm, vector)) { | ||
761 | int trigger_mode; | ||
762 | if (apic_test_vector(vector, apic->regs + APIC_TMR)) | ||
763 | trigger_mode = IOAPIC_LEVEL_TRIG; | ||
764 | else | ||
765 | trigger_mode = IOAPIC_EDGE_TRIG; | ||
766 | kvm_ioapic_update_eoi(apic->vcpu->kvm, vector, trigger_mode); | ||
767 | } | ||
768 | kvm_make_request(KVM_REQ_EVENT, apic->vcpu); | 806 | kvm_make_request(KVM_REQ_EVENT, apic->vcpu); |
769 | return vector; | 807 | return vector; |
770 | } | 808 | } |
771 | 809 | ||
810 | /* | ||
811 | * this interface assumes a trap-like exit, which has already finished | ||
812 | * desired side effect including vISR and vPPR update. | ||
813 | */ | ||
814 | void kvm_apic_set_eoi_accelerated(struct kvm_vcpu *vcpu, int vector) | ||
815 | { | ||
816 | struct kvm_lapic *apic = vcpu->arch.apic; | ||
817 | |||
818 | trace_kvm_eoi(apic, vector); | ||
819 | |||
820 | kvm_ioapic_send_eoi(apic, vector); | ||
821 | kvm_make_request(KVM_REQ_EVENT, apic->vcpu); | ||
822 | } | ||
823 | EXPORT_SYMBOL_GPL(kvm_apic_set_eoi_accelerated); | ||
824 | |||
772 | static void apic_send_ipi(struct kvm_lapic *apic) | 825 | static void apic_send_ipi(struct kvm_lapic *apic) |
773 | { | 826 | { |
774 | u32 icr_low = kvm_apic_get_reg(apic, APIC_ICR); | 827 | u32 icr_low = kvm_apic_get_reg(apic, APIC_ICR); |
@@ -1212,6 +1265,21 @@ void kvm_lapic_set_eoi(struct kvm_vcpu *vcpu) | |||
1212 | } | 1265 | } |
1213 | EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi); | 1266 | EXPORT_SYMBOL_GPL(kvm_lapic_set_eoi); |
1214 | 1267 | ||
1268 | /* emulate APIC access in a trap manner */ | ||
1269 | void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset) | ||
1270 | { | ||
1271 | u32 val = 0; | ||
1272 | |||
1273 | /* hw has done the conditional check and inst decode */ | ||
1274 | offset &= 0xff0; | ||
1275 | |||
1276 | apic_reg_read(vcpu->arch.apic, offset, 4, &val); | ||
1277 | |||
1278 | /* TODO: optimize to just emulate side effect w/o one more write */ | ||
1279 | apic_reg_write(vcpu->arch.apic, offset, val); | ||
1280 | } | ||
1281 | EXPORT_SYMBOL_GPL(kvm_apic_write_nodecode); | ||
1282 | |||
1215 | void kvm_free_lapic(struct kvm_vcpu *vcpu) | 1283 | void kvm_free_lapic(struct kvm_vcpu *vcpu) |
1216 | { | 1284 | { |
1217 | struct kvm_lapic *apic = vcpu->arch.apic; | 1285 | struct kvm_lapic *apic = vcpu->arch.apic; |
@@ -1288,6 +1356,7 @@ u64 kvm_lapic_get_cr8(struct kvm_vcpu *vcpu) | |||
1288 | 1356 | ||
1289 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | 1357 | void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) |
1290 | { | 1358 | { |
1359 | u64 old_value = vcpu->arch.apic_base; | ||
1291 | struct kvm_lapic *apic = vcpu->arch.apic; | 1360 | struct kvm_lapic *apic = vcpu->arch.apic; |
1292 | 1361 | ||
1293 | if (!apic) { | 1362 | if (!apic) { |
@@ -1309,11 +1378,16 @@ void kvm_lapic_set_base(struct kvm_vcpu *vcpu, u64 value) | |||
1309 | value &= ~MSR_IA32_APICBASE_BSP; | 1378 | value &= ~MSR_IA32_APICBASE_BSP; |
1310 | 1379 | ||
1311 | vcpu->arch.apic_base = value; | 1380 | vcpu->arch.apic_base = value; |
1312 | if (apic_x2apic_mode(apic)) { | 1381 | if ((old_value ^ value) & X2APIC_ENABLE) { |
1313 | u32 id = kvm_apic_id(apic); | 1382 | if (value & X2APIC_ENABLE) { |
1314 | u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf)); | 1383 | u32 id = kvm_apic_id(apic); |
1315 | kvm_apic_set_ldr(apic, ldr); | 1384 | u32 ldr = ((id >> 4) << 16) | (1 << (id & 0xf)); |
1385 | kvm_apic_set_ldr(apic, ldr); | ||
1386 | kvm_x86_ops->set_virtual_x2apic_mode(vcpu, true); | ||
1387 | } else | ||
1388 | kvm_x86_ops->set_virtual_x2apic_mode(vcpu, false); | ||
1316 | } | 1389 | } |
1390 | |||
1317 | apic->base_address = apic->vcpu->arch.apic_base & | 1391 | apic->base_address = apic->vcpu->arch.apic_base & |
1318 | MSR_IA32_APICBASE_BASE; | 1392 | MSR_IA32_APICBASE_BASE; |
1319 | 1393 | ||
@@ -1359,8 +1433,8 @@ void kvm_lapic_reset(struct kvm_vcpu *vcpu) | |||
1359 | apic_set_reg(apic, APIC_ISR + 0x10 * i, 0); | 1433 | apic_set_reg(apic, APIC_ISR + 0x10 * i, 0); |
1360 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); | 1434 | apic_set_reg(apic, APIC_TMR + 0x10 * i, 0); |
1361 | } | 1435 | } |
1362 | apic->irr_pending = false; | 1436 | apic->irr_pending = kvm_apic_vid_enabled(vcpu->kvm); |
1363 | apic->isr_count = 0; | 1437 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm); |
1364 | apic->highest_isr_cache = -1; | 1438 | apic->highest_isr_cache = -1; |
1365 | update_divide_count(apic); | 1439 | update_divide_count(apic); |
1366 | atomic_set(&apic->lapic_timer.pending, 0); | 1440 | atomic_set(&apic->lapic_timer.pending, 0); |
@@ -1575,8 +1649,10 @@ void kvm_apic_post_state_restore(struct kvm_vcpu *vcpu, | |||
1575 | update_divide_count(apic); | 1649 | update_divide_count(apic); |
1576 | start_apic_timer(apic); | 1650 | start_apic_timer(apic); |
1577 | apic->irr_pending = true; | 1651 | apic->irr_pending = true; |
1578 | apic->isr_count = count_vectors(apic->regs + APIC_ISR); | 1652 | apic->isr_count = kvm_apic_vid_enabled(vcpu->kvm) ? |
1653 | 1 : count_vectors(apic->regs + APIC_ISR); | ||
1579 | apic->highest_isr_cache = -1; | 1654 | apic->highest_isr_cache = -1; |
1655 | kvm_x86_ops->hwapic_isr_update(vcpu->kvm, apic_find_highest_isr(apic)); | ||
1580 | kvm_make_request(KVM_REQ_EVENT, vcpu); | 1656 | kvm_make_request(KVM_REQ_EVENT, vcpu); |
1581 | } | 1657 | } |
1582 | 1658 | ||
diff --git a/arch/x86/kvm/lapic.h b/arch/x86/kvm/lapic.h index e5ebf9f3571f..1676d34ddb4e 100644 --- a/arch/x86/kvm/lapic.h +++ b/arch/x86/kvm/lapic.h | |||
@@ -64,6 +64,9 @@ int kvm_lapic_find_highest_irr(struct kvm_vcpu *vcpu); | |||
64 | u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu); | 64 | u64 kvm_get_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu); |
65 | void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data); | 65 | void kvm_set_lapic_tscdeadline_msr(struct kvm_vcpu *vcpu, u64 data); |
66 | 66 | ||
67 | void kvm_apic_write_nodecode(struct kvm_vcpu *vcpu, u32 offset); | ||
68 | void kvm_apic_set_eoi_accelerated(struct kvm_vcpu *vcpu, int vector); | ||
69 | |||
67 | void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); | 70 | void kvm_lapic_set_vapic_addr(struct kvm_vcpu *vcpu, gpa_t vapic_addr); |
68 | void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); | 71 | void kvm_lapic_sync_from_vapic(struct kvm_vcpu *vcpu); |
69 | void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu); | 72 | void kvm_lapic_sync_to_vapic(struct kvm_vcpu *vcpu); |
@@ -124,4 +127,35 @@ static inline int kvm_lapic_enabled(struct kvm_vcpu *vcpu) | |||
124 | return kvm_apic_present(vcpu) && kvm_apic_sw_enabled(vcpu->arch.apic); | 127 | return kvm_apic_present(vcpu) && kvm_apic_sw_enabled(vcpu->arch.apic); |
125 | } | 128 | } |
126 | 129 | ||
130 | static inline int apic_x2apic_mode(struct kvm_lapic *apic) | ||
131 | { | ||
132 | return apic->vcpu->arch.apic_base & X2APIC_ENABLE; | ||
133 | } | ||
134 | |||
135 | static inline bool kvm_apic_vid_enabled(struct kvm *kvm) | ||
136 | { | ||
137 | return kvm_x86_ops->vm_has_apicv(kvm); | ||
138 | } | ||
139 | |||
140 | static inline u16 apic_cluster_id(struct kvm_apic_map *map, u32 ldr) | ||
141 | { | ||
142 | u16 cid; | ||
143 | ldr >>= 32 - map->ldr_bits; | ||
144 | cid = (ldr >> map->cid_shift) & map->cid_mask; | ||
145 | |||
146 | BUG_ON(cid >= ARRAY_SIZE(map->logical_map)); | ||
147 | |||
148 | return cid; | ||
149 | } | ||
150 | |||
151 | static inline u16 apic_logical_id(struct kvm_apic_map *map, u32 ldr) | ||
152 | { | ||
153 | ldr >>= (32 - map->ldr_bits); | ||
154 | return ldr & map->lid_mask; | ||
155 | } | ||
156 | |||
157 | void kvm_calculate_eoi_exitmap(struct kvm_vcpu *vcpu, | ||
158 | struct kvm_lapic_irq *irq, | ||
159 | u64 *eoi_bitmap); | ||
160 | |||
127 | #endif | 161 | #endif |
diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 9f628f7a40b2..0242a8a1b2e2 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c | |||
@@ -448,7 +448,8 @@ static bool __check_direct_spte_mmio_pf(u64 spte) | |||
448 | 448 | ||
449 | static bool spte_is_locklessly_modifiable(u64 spte) | 449 | static bool spte_is_locklessly_modifiable(u64 spte) |
450 | { | 450 | { |
451 | return !(~spte & (SPTE_HOST_WRITEABLE | SPTE_MMU_WRITEABLE)); | 451 | return (spte & (SPTE_HOST_WRITEABLE | SPTE_MMU_WRITEABLE)) == |
452 | (SPTE_HOST_WRITEABLE | SPTE_MMU_WRITEABLE); | ||
452 | } | 453 | } |
453 | 454 | ||
454 | static bool spte_has_volatile_bits(u64 spte) | 455 | static bool spte_has_volatile_bits(u64 spte) |
@@ -1460,28 +1461,14 @@ static inline void kvm_mod_used_mmu_pages(struct kvm *kvm, int nr) | |||
1460 | percpu_counter_add(&kvm_total_used_mmu_pages, nr); | 1461 | percpu_counter_add(&kvm_total_used_mmu_pages, nr); |
1461 | } | 1462 | } |
1462 | 1463 | ||
1463 | /* | 1464 | static void kvm_mmu_free_page(struct kvm_mmu_page *sp) |
1464 | * Remove the sp from shadow page cache, after call it, | ||
1465 | * we can not find this sp from the cache, and the shadow | ||
1466 | * page table is still valid. | ||
1467 | * It should be under the protection of mmu lock. | ||
1468 | */ | ||
1469 | static void kvm_mmu_isolate_page(struct kvm_mmu_page *sp) | ||
1470 | { | 1465 | { |
1471 | ASSERT(is_empty_shadow_page(sp->spt)); | 1466 | ASSERT(is_empty_shadow_page(sp->spt)); |
1472 | hlist_del(&sp->hash_link); | 1467 | hlist_del(&sp->hash_link); |
1473 | if (!sp->role.direct) | ||
1474 | free_page((unsigned long)sp->gfns); | ||
1475 | } | ||
1476 | |||
1477 | /* | ||
1478 | * Free the shadow page table and the sp, we can do it | ||
1479 | * out of the protection of mmu lock. | ||
1480 | */ | ||
1481 | static void kvm_mmu_free_page(struct kvm_mmu_page *sp) | ||
1482 | { | ||
1483 | list_del(&sp->link); | 1468 | list_del(&sp->link); |
1484 | free_page((unsigned long)sp->spt); | 1469 | free_page((unsigned long)sp->spt); |
1470 | if (!sp->role.direct) | ||
1471 | free_page((unsigned long)sp->gfns); | ||
1485 | kmem_cache_free(mmu_page_header_cache, sp); | 1472 | kmem_cache_free(mmu_page_header_cache, sp); |
1486 | } | 1473 | } |
1487 | 1474 | ||
@@ -2125,7 +2112,6 @@ static void kvm_mmu_commit_zap_page(struct kvm *kvm, | |||
2125 | do { | 2112 | do { |
2126 | sp = list_first_entry(invalid_list, struct kvm_mmu_page, link); | 2113 | sp = list_first_entry(invalid_list, struct kvm_mmu_page, link); |
2127 | WARN_ON(!sp->role.invalid || sp->root_count); | 2114 | WARN_ON(!sp->role.invalid || sp->root_count); |
2128 | kvm_mmu_isolate_page(sp); | ||
2129 | kvm_mmu_free_page(sp); | 2115 | kvm_mmu_free_page(sp); |
2130 | } while (!list_empty(invalid_list)); | 2116 | } while (!list_empty(invalid_list)); |
2131 | } | 2117 | } |
@@ -2327,9 +2313,8 @@ static int mmu_need_write_protect(struct kvm_vcpu *vcpu, gfn_t gfn, | |||
2327 | if (s->role.level != PT_PAGE_TABLE_LEVEL) | 2313 | if (s->role.level != PT_PAGE_TABLE_LEVEL) |
2328 | return 1; | 2314 | return 1; |
2329 | 2315 | ||
2330 | if (!need_unsync && !s->unsync) { | 2316 | if (!s->unsync) |
2331 | need_unsync = true; | 2317 | need_unsync = true; |
2332 | } | ||
2333 | } | 2318 | } |
2334 | if (need_unsync) | 2319 | if (need_unsync) |
2335 | kvm_unsync_pages(vcpu, gfn); | 2320 | kvm_unsync_pages(vcpu, gfn); |
@@ -3687,6 +3672,7 @@ int kvm_init_shadow_mmu(struct kvm_vcpu *vcpu, struct kvm_mmu *context) | |||
3687 | else | 3672 | else |
3688 | r = paging32_init_context(vcpu, context); | 3673 | r = paging32_init_context(vcpu, context); |
3689 | 3674 | ||
3675 | vcpu->arch.mmu.base_role.nxe = is_nx(vcpu); | ||
3690 | vcpu->arch.mmu.base_role.cr4_pae = !!is_pae(vcpu); | 3676 | vcpu->arch.mmu.base_role.cr4_pae = !!is_pae(vcpu); |
3691 | vcpu->arch.mmu.base_role.cr0_wp = is_write_protection(vcpu); | 3677 | vcpu->arch.mmu.base_role.cr0_wp = is_write_protection(vcpu); |
3692 | vcpu->arch.mmu.base_role.smep_andnot_wp | 3678 | vcpu->arch.mmu.base_role.smep_andnot_wp |
@@ -3853,7 +3839,7 @@ static u64 mmu_pte_write_fetch_gpte(struct kvm_vcpu *vcpu, gpa_t *gpa, | |||
3853 | /* Handle a 32-bit guest writing two halves of a 64-bit gpte */ | 3839 | /* Handle a 32-bit guest writing two halves of a 64-bit gpte */ |
3854 | *gpa &= ~(gpa_t)7; | 3840 | *gpa &= ~(gpa_t)7; |
3855 | *bytes = 8; | 3841 | *bytes = 8; |
3856 | r = kvm_read_guest(vcpu->kvm, *gpa, &gentry, min(*bytes, 8)); | 3842 | r = kvm_read_guest(vcpu->kvm, *gpa, &gentry, 8); |
3857 | if (r) | 3843 | if (r) |
3858 | gentry = 0; | 3844 | gentry = 0; |
3859 | new = (const u8 *)&gentry; | 3845 | new = (const u8 *)&gentry; |
@@ -4007,7 +3993,7 @@ void kvm_mmu_pte_write(struct kvm_vcpu *vcpu, gpa_t gpa, | |||
4007 | !((sp->role.word ^ vcpu->arch.mmu.base_role.word) | 3993 | !((sp->role.word ^ vcpu->arch.mmu.base_role.word) |
4008 | & mask.word) && rmap_can_add(vcpu)) | 3994 | & mask.word) && rmap_can_add(vcpu)) |
4009 | mmu_pte_write_new_pte(vcpu, sp, spte, &gentry); | 3995 | mmu_pte_write_new_pte(vcpu, sp, spte, &gentry); |
4010 | if (!remote_flush && need_remote_flush(entry, *spte)) | 3996 | if (need_remote_flush(entry, *spte)) |
4011 | remote_flush = true; | 3997 | remote_flush = true; |
4012 | ++spte; | 3998 | ++spte; |
4013 | } | 3999 | } |
diff --git a/arch/x86/kvm/paging_tmpl.h b/arch/x86/kvm/paging_tmpl.h index ca69dcccbe31..34c5c99323f4 100644 --- a/arch/x86/kvm/paging_tmpl.h +++ b/arch/x86/kvm/paging_tmpl.h | |||
@@ -409,9 +409,6 @@ static int FNAME(fetch)(struct kvm_vcpu *vcpu, gva_t addr, | |||
409 | unsigned direct_access, access = gw->pt_access; | 409 | unsigned direct_access, access = gw->pt_access; |
410 | int top_level, emulate = 0; | 410 | int top_level, emulate = 0; |
411 | 411 | ||
412 | if (!is_present_gpte(gw->ptes[gw->level - 1])) | ||
413 | return 0; | ||
414 | |||
415 | direct_access = gw->pte_access; | 412 | direct_access = gw->pte_access; |
416 | 413 | ||
417 | top_level = vcpu->arch.mmu.root_level; | 414 | top_level = vcpu->arch.mmu.root_level; |
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index d29d3cd1c156..e1b1ce21bc00 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -3571,6 +3571,26 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) | |||
3571 | set_cr_intercept(svm, INTERCEPT_CR8_WRITE); | 3571 | set_cr_intercept(svm, INTERCEPT_CR8_WRITE); |
3572 | } | 3572 | } |
3573 | 3573 | ||
3574 | static void svm_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set) | ||
3575 | { | ||
3576 | return; | ||
3577 | } | ||
3578 | |||
3579 | static int svm_vm_has_apicv(struct kvm *kvm) | ||
3580 | { | ||
3581 | return 0; | ||
3582 | } | ||
3583 | |||
3584 | static void svm_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) | ||
3585 | { | ||
3586 | return; | ||
3587 | } | ||
3588 | |||
3589 | static void svm_hwapic_isr_update(struct kvm *kvm, int isr) | ||
3590 | { | ||
3591 | return; | ||
3592 | } | ||
3593 | |||
3574 | static int svm_nmi_allowed(struct kvm_vcpu *vcpu) | 3594 | static int svm_nmi_allowed(struct kvm_vcpu *vcpu) |
3575 | { | 3595 | { |
3576 | struct vcpu_svm *svm = to_svm(vcpu); | 3596 | struct vcpu_svm *svm = to_svm(vcpu); |
@@ -4290,6 +4310,10 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
4290 | .enable_nmi_window = enable_nmi_window, | 4310 | .enable_nmi_window = enable_nmi_window, |
4291 | .enable_irq_window = enable_irq_window, | 4311 | .enable_irq_window = enable_irq_window, |
4292 | .update_cr8_intercept = update_cr8_intercept, | 4312 | .update_cr8_intercept = update_cr8_intercept, |
4313 | .set_virtual_x2apic_mode = svm_set_virtual_x2apic_mode, | ||
4314 | .vm_has_apicv = svm_vm_has_apicv, | ||
4315 | .load_eoi_exitmap = svm_load_eoi_exitmap, | ||
4316 | .hwapic_isr_update = svm_hwapic_isr_update, | ||
4293 | 4317 | ||
4294 | .set_tss_addr = svm_set_tss_addr, | 4318 | .set_tss_addr = svm_set_tss_addr, |
4295 | .get_tdp_level = get_npt_level, | 4319 | .get_tdp_level = get_npt_level, |
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c index 02eeba86328d..fe9a9cfadbd6 100644 --- a/arch/x86/kvm/vmx.c +++ b/arch/x86/kvm/vmx.c | |||
@@ -84,6 +84,9 @@ module_param(vmm_exclusive, bool, S_IRUGO); | |||
84 | static bool __read_mostly fasteoi = 1; | 84 | static bool __read_mostly fasteoi = 1; |
85 | module_param(fasteoi, bool, S_IRUGO); | 85 | module_param(fasteoi, bool, S_IRUGO); |
86 | 86 | ||
87 | static bool __read_mostly enable_apicv_reg_vid = 1; | ||
88 | module_param(enable_apicv_reg_vid, bool, S_IRUGO); | ||
89 | |||
87 | /* | 90 | /* |
88 | * If nested=1, nested virtualization is supported, i.e., guests may use | 91 | * If nested=1, nested virtualization is supported, i.e., guests may use |
89 | * VMX and be a hypervisor for its own guests. If nested=0, guests may not | 92 | * VMX and be a hypervisor for its own guests. If nested=0, guests may not |
@@ -640,6 +643,8 @@ static unsigned long *vmx_io_bitmap_a; | |||
640 | static unsigned long *vmx_io_bitmap_b; | 643 | static unsigned long *vmx_io_bitmap_b; |
641 | static unsigned long *vmx_msr_bitmap_legacy; | 644 | static unsigned long *vmx_msr_bitmap_legacy; |
642 | static unsigned long *vmx_msr_bitmap_longmode; | 645 | static unsigned long *vmx_msr_bitmap_longmode; |
646 | static unsigned long *vmx_msr_bitmap_legacy_x2apic; | ||
647 | static unsigned long *vmx_msr_bitmap_longmode_x2apic; | ||
643 | 648 | ||
644 | static bool cpu_has_load_ia32_efer; | 649 | static bool cpu_has_load_ia32_efer; |
645 | static bool cpu_has_load_perf_global_ctrl; | 650 | static bool cpu_has_load_perf_global_ctrl; |
@@ -764,6 +769,24 @@ static inline bool cpu_has_vmx_virtualize_apic_accesses(void) | |||
764 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; | 769 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; |
765 | } | 770 | } |
766 | 771 | ||
772 | static inline bool cpu_has_vmx_virtualize_x2apic_mode(void) | ||
773 | { | ||
774 | return vmcs_config.cpu_based_2nd_exec_ctrl & | ||
775 | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE; | ||
776 | } | ||
777 | |||
778 | static inline bool cpu_has_vmx_apic_register_virt(void) | ||
779 | { | ||
780 | return vmcs_config.cpu_based_2nd_exec_ctrl & | ||
781 | SECONDARY_EXEC_APIC_REGISTER_VIRT; | ||
782 | } | ||
783 | |||
784 | static inline bool cpu_has_vmx_virtual_intr_delivery(void) | ||
785 | { | ||
786 | return vmcs_config.cpu_based_2nd_exec_ctrl & | ||
787 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY; | ||
788 | } | ||
789 | |||
767 | static inline bool cpu_has_vmx_flexpriority(void) | 790 | static inline bool cpu_has_vmx_flexpriority(void) |
768 | { | 791 | { |
769 | return cpu_has_vmx_tpr_shadow() && | 792 | return cpu_has_vmx_tpr_shadow() && |
@@ -1821,6 +1844,25 @@ static void move_msr_up(struct vcpu_vmx *vmx, int from, int to) | |||
1821 | vmx->guest_msrs[from] = tmp; | 1844 | vmx->guest_msrs[from] = tmp; |
1822 | } | 1845 | } |
1823 | 1846 | ||
1847 | static void vmx_set_msr_bitmap(struct kvm_vcpu *vcpu) | ||
1848 | { | ||
1849 | unsigned long *msr_bitmap; | ||
1850 | |||
1851 | if (irqchip_in_kernel(vcpu->kvm) && apic_x2apic_mode(vcpu->arch.apic)) { | ||
1852 | if (is_long_mode(vcpu)) | ||
1853 | msr_bitmap = vmx_msr_bitmap_longmode_x2apic; | ||
1854 | else | ||
1855 | msr_bitmap = vmx_msr_bitmap_legacy_x2apic; | ||
1856 | } else { | ||
1857 | if (is_long_mode(vcpu)) | ||
1858 | msr_bitmap = vmx_msr_bitmap_longmode; | ||
1859 | else | ||
1860 | msr_bitmap = vmx_msr_bitmap_legacy; | ||
1861 | } | ||
1862 | |||
1863 | vmcs_write64(MSR_BITMAP, __pa(msr_bitmap)); | ||
1864 | } | ||
1865 | |||
1824 | /* | 1866 | /* |
1825 | * Set up the vmcs to automatically save and restore system | 1867 | * Set up the vmcs to automatically save and restore system |
1826 | * msrs. Don't touch the 64-bit msrs if the guest is in legacy | 1868 | * msrs. Don't touch the 64-bit msrs if the guest is in legacy |
@@ -1829,7 +1871,6 @@ static void move_msr_up(struct vcpu_vmx *vmx, int from, int to) | |||
1829 | static void setup_msrs(struct vcpu_vmx *vmx) | 1871 | static void setup_msrs(struct vcpu_vmx *vmx) |
1830 | { | 1872 | { |
1831 | int save_nmsrs, index; | 1873 | int save_nmsrs, index; |
1832 | unsigned long *msr_bitmap; | ||
1833 | 1874 | ||
1834 | save_nmsrs = 0; | 1875 | save_nmsrs = 0; |
1835 | #ifdef CONFIG_X86_64 | 1876 | #ifdef CONFIG_X86_64 |
@@ -1861,14 +1902,8 @@ static void setup_msrs(struct vcpu_vmx *vmx) | |||
1861 | 1902 | ||
1862 | vmx->save_nmsrs = save_nmsrs; | 1903 | vmx->save_nmsrs = save_nmsrs; |
1863 | 1904 | ||
1864 | if (cpu_has_vmx_msr_bitmap()) { | 1905 | if (cpu_has_vmx_msr_bitmap()) |
1865 | if (is_long_mode(&vmx->vcpu)) | 1906 | vmx_set_msr_bitmap(&vmx->vcpu); |
1866 | msr_bitmap = vmx_msr_bitmap_longmode; | ||
1867 | else | ||
1868 | msr_bitmap = vmx_msr_bitmap_legacy; | ||
1869 | |||
1870 | vmcs_write64(MSR_BITMAP, __pa(msr_bitmap)); | ||
1871 | } | ||
1872 | } | 1907 | } |
1873 | 1908 | ||
1874 | /* | 1909 | /* |
@@ -2534,13 +2569,16 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
2534 | if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) { | 2569 | if (_cpu_based_exec_control & CPU_BASED_ACTIVATE_SECONDARY_CONTROLS) { |
2535 | min2 = 0; | 2570 | min2 = 0; |
2536 | opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | | 2571 | opt2 = SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES | |
2572 | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | | ||
2537 | SECONDARY_EXEC_WBINVD_EXITING | | 2573 | SECONDARY_EXEC_WBINVD_EXITING | |
2538 | SECONDARY_EXEC_ENABLE_VPID | | 2574 | SECONDARY_EXEC_ENABLE_VPID | |
2539 | SECONDARY_EXEC_ENABLE_EPT | | 2575 | SECONDARY_EXEC_ENABLE_EPT | |
2540 | SECONDARY_EXEC_UNRESTRICTED_GUEST | | 2576 | SECONDARY_EXEC_UNRESTRICTED_GUEST | |
2541 | SECONDARY_EXEC_PAUSE_LOOP_EXITING | | 2577 | SECONDARY_EXEC_PAUSE_LOOP_EXITING | |
2542 | SECONDARY_EXEC_RDTSCP | | 2578 | SECONDARY_EXEC_RDTSCP | |
2543 | SECONDARY_EXEC_ENABLE_INVPCID; | 2579 | SECONDARY_EXEC_ENABLE_INVPCID | |
2580 | SECONDARY_EXEC_APIC_REGISTER_VIRT | | ||
2581 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY; | ||
2544 | if (adjust_vmx_controls(min2, opt2, | 2582 | if (adjust_vmx_controls(min2, opt2, |
2545 | MSR_IA32_VMX_PROCBASED_CTLS2, | 2583 | MSR_IA32_VMX_PROCBASED_CTLS2, |
2546 | &_cpu_based_2nd_exec_control) < 0) | 2584 | &_cpu_based_2nd_exec_control) < 0) |
@@ -2551,6 +2589,13 @@ static __init int setup_vmcs_config(struct vmcs_config *vmcs_conf) | |||
2551 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) | 2589 | SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES)) |
2552 | _cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW; | 2590 | _cpu_based_exec_control &= ~CPU_BASED_TPR_SHADOW; |
2553 | #endif | 2591 | #endif |
2592 | |||
2593 | if (!(_cpu_based_exec_control & CPU_BASED_TPR_SHADOW)) | ||
2594 | _cpu_based_2nd_exec_control &= ~( | ||
2595 | SECONDARY_EXEC_APIC_REGISTER_VIRT | | ||
2596 | SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE | | ||
2597 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY); | ||
2598 | |||
2554 | if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) { | 2599 | if (_cpu_based_2nd_exec_control & SECONDARY_EXEC_ENABLE_EPT) { |
2555 | /* CR3 accesses and invlpg don't need to cause VM Exits when EPT | 2600 | /* CR3 accesses and invlpg don't need to cause VM Exits when EPT |
2556 | enabled */ | 2601 | enabled */ |
@@ -2748,6 +2793,15 @@ static __init int hardware_setup(void) | |||
2748 | if (!cpu_has_vmx_ple()) | 2793 | if (!cpu_has_vmx_ple()) |
2749 | ple_gap = 0; | 2794 | ple_gap = 0; |
2750 | 2795 | ||
2796 | if (!cpu_has_vmx_apic_register_virt() || | ||
2797 | !cpu_has_vmx_virtual_intr_delivery()) | ||
2798 | enable_apicv_reg_vid = 0; | ||
2799 | |||
2800 | if (enable_apicv_reg_vid) | ||
2801 | kvm_x86_ops->update_cr8_intercept = NULL; | ||
2802 | else | ||
2803 | kvm_x86_ops->hwapic_irr_update = NULL; | ||
2804 | |||
2751 | if (nested) | 2805 | if (nested) |
2752 | nested_vmx_setup_ctls_msrs(); | 2806 | nested_vmx_setup_ctls_msrs(); |
2753 | 2807 | ||
@@ -3173,6 +3227,14 @@ static int vmx_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | |||
3173 | if (!is_paging(vcpu)) { | 3227 | if (!is_paging(vcpu)) { |
3174 | hw_cr4 &= ~X86_CR4_PAE; | 3228 | hw_cr4 &= ~X86_CR4_PAE; |
3175 | hw_cr4 |= X86_CR4_PSE; | 3229 | hw_cr4 |= X86_CR4_PSE; |
3230 | /* | ||
3231 | * SMEP is disabled if CPU is in non-paging mode in | ||
3232 | * hardware. However KVM always uses paging mode to | ||
3233 | * emulate guest non-paging mode with TDP. | ||
3234 | * To emulate this behavior, SMEP needs to be manually | ||
3235 | * disabled when guest switches to non-paging mode. | ||
3236 | */ | ||
3237 | hw_cr4 &= ~X86_CR4_SMEP; | ||
3176 | } else if (!(cr4 & X86_CR4_PAE)) { | 3238 | } else if (!(cr4 & X86_CR4_PAE)) { |
3177 | hw_cr4 &= ~X86_CR4_PAE; | 3239 | hw_cr4 &= ~X86_CR4_PAE; |
3178 | } | 3240 | } |
@@ -3707,7 +3769,10 @@ static void free_vpid(struct vcpu_vmx *vmx) | |||
3707 | spin_unlock(&vmx_vpid_lock); | 3769 | spin_unlock(&vmx_vpid_lock); |
3708 | } | 3770 | } |
3709 | 3771 | ||
3710 | static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, u32 msr) | 3772 | #define MSR_TYPE_R 1 |
3773 | #define MSR_TYPE_W 2 | ||
3774 | static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, | ||
3775 | u32 msr, int type) | ||
3711 | { | 3776 | { |
3712 | int f = sizeof(unsigned long); | 3777 | int f = sizeof(unsigned long); |
3713 | 3778 | ||
@@ -3720,20 +3785,93 @@ static void __vmx_disable_intercept_for_msr(unsigned long *msr_bitmap, u32 msr) | |||
3720 | * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff. | 3785 | * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff. |
3721 | */ | 3786 | */ |
3722 | if (msr <= 0x1fff) { | 3787 | if (msr <= 0x1fff) { |
3723 | __clear_bit(msr, msr_bitmap + 0x000 / f); /* read-low */ | 3788 | if (type & MSR_TYPE_R) |
3724 | __clear_bit(msr, msr_bitmap + 0x800 / f); /* write-low */ | 3789 | /* read-low */ |
3790 | __clear_bit(msr, msr_bitmap + 0x000 / f); | ||
3791 | |||
3792 | if (type & MSR_TYPE_W) | ||
3793 | /* write-low */ | ||
3794 | __clear_bit(msr, msr_bitmap + 0x800 / f); | ||
3795 | |||
3725 | } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { | 3796 | } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { |
3726 | msr &= 0x1fff; | 3797 | msr &= 0x1fff; |
3727 | __clear_bit(msr, msr_bitmap + 0x400 / f); /* read-high */ | 3798 | if (type & MSR_TYPE_R) |
3728 | __clear_bit(msr, msr_bitmap + 0xc00 / f); /* write-high */ | 3799 | /* read-high */ |
3800 | __clear_bit(msr, msr_bitmap + 0x400 / f); | ||
3801 | |||
3802 | if (type & MSR_TYPE_W) | ||
3803 | /* write-high */ | ||
3804 | __clear_bit(msr, msr_bitmap + 0xc00 / f); | ||
3805 | |||
3806 | } | ||
3807 | } | ||
3808 | |||
3809 | static void __vmx_enable_intercept_for_msr(unsigned long *msr_bitmap, | ||
3810 | u32 msr, int type) | ||
3811 | { | ||
3812 | int f = sizeof(unsigned long); | ||
3813 | |||
3814 | if (!cpu_has_vmx_msr_bitmap()) | ||
3815 | return; | ||
3816 | |||
3817 | /* | ||
3818 | * See Intel PRM Vol. 3, 20.6.9 (MSR-Bitmap Address). Early manuals | ||
3819 | * have the write-low and read-high bitmap offsets the wrong way round. | ||
3820 | * We can control MSRs 0x00000000-0x00001fff and 0xc0000000-0xc0001fff. | ||
3821 | */ | ||
3822 | if (msr <= 0x1fff) { | ||
3823 | if (type & MSR_TYPE_R) | ||
3824 | /* read-low */ | ||
3825 | __set_bit(msr, msr_bitmap + 0x000 / f); | ||
3826 | |||
3827 | if (type & MSR_TYPE_W) | ||
3828 | /* write-low */ | ||
3829 | __set_bit(msr, msr_bitmap + 0x800 / f); | ||
3830 | |||
3831 | } else if ((msr >= 0xc0000000) && (msr <= 0xc0001fff)) { | ||
3832 | msr &= 0x1fff; | ||
3833 | if (type & MSR_TYPE_R) | ||
3834 | /* read-high */ | ||
3835 | __set_bit(msr, msr_bitmap + 0x400 / f); | ||
3836 | |||
3837 | if (type & MSR_TYPE_W) | ||
3838 | /* write-high */ | ||
3839 | __set_bit(msr, msr_bitmap + 0xc00 / f); | ||
3840 | |||
3729 | } | 3841 | } |
3730 | } | 3842 | } |
3731 | 3843 | ||
3732 | static void vmx_disable_intercept_for_msr(u32 msr, bool longmode_only) | 3844 | static void vmx_disable_intercept_for_msr(u32 msr, bool longmode_only) |
3733 | { | 3845 | { |
3734 | if (!longmode_only) | 3846 | if (!longmode_only) |
3735 | __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy, msr); | 3847 | __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy, |
3736 | __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode, msr); | 3848 | msr, MSR_TYPE_R | MSR_TYPE_W); |
3849 | __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode, | ||
3850 | msr, MSR_TYPE_R | MSR_TYPE_W); | ||
3851 | } | ||
3852 | |||
3853 | static void vmx_enable_intercept_msr_read_x2apic(u32 msr) | ||
3854 | { | ||
3855 | __vmx_enable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic, | ||
3856 | msr, MSR_TYPE_R); | ||
3857 | __vmx_enable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic, | ||
3858 | msr, MSR_TYPE_R); | ||
3859 | } | ||
3860 | |||
3861 | static void vmx_disable_intercept_msr_read_x2apic(u32 msr) | ||
3862 | { | ||
3863 | __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic, | ||
3864 | msr, MSR_TYPE_R); | ||
3865 | __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic, | ||
3866 | msr, MSR_TYPE_R); | ||
3867 | } | ||
3868 | |||
3869 | static void vmx_disable_intercept_msr_write_x2apic(u32 msr) | ||
3870 | { | ||
3871 | __vmx_disable_intercept_for_msr(vmx_msr_bitmap_legacy_x2apic, | ||
3872 | msr, MSR_TYPE_W); | ||
3873 | __vmx_disable_intercept_for_msr(vmx_msr_bitmap_longmode_x2apic, | ||
3874 | msr, MSR_TYPE_W); | ||
3737 | } | 3875 | } |
3738 | 3876 | ||
3739 | /* | 3877 | /* |
@@ -3812,6 +3950,11 @@ static u32 vmx_exec_control(struct vcpu_vmx *vmx) | |||
3812 | return exec_control; | 3950 | return exec_control; |
3813 | } | 3951 | } |
3814 | 3952 | ||
3953 | static int vmx_vm_has_apicv(struct kvm *kvm) | ||
3954 | { | ||
3955 | return enable_apicv_reg_vid && irqchip_in_kernel(kvm); | ||
3956 | } | ||
3957 | |||
3815 | static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx) | 3958 | static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx) |
3816 | { | 3959 | { |
3817 | u32 exec_control = vmcs_config.cpu_based_2nd_exec_ctrl; | 3960 | u32 exec_control = vmcs_config.cpu_based_2nd_exec_ctrl; |
@@ -3829,6 +3972,10 @@ static u32 vmx_secondary_exec_control(struct vcpu_vmx *vmx) | |||
3829 | exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST; | 3972 | exec_control &= ~SECONDARY_EXEC_UNRESTRICTED_GUEST; |
3830 | if (!ple_gap) | 3973 | if (!ple_gap) |
3831 | exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING; | 3974 | exec_control &= ~SECONDARY_EXEC_PAUSE_LOOP_EXITING; |
3975 | if (!vmx_vm_has_apicv(vmx->vcpu.kvm)) | ||
3976 | exec_control &= ~(SECONDARY_EXEC_APIC_REGISTER_VIRT | | ||
3977 | SECONDARY_EXEC_VIRTUAL_INTR_DELIVERY); | ||
3978 | exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE; | ||
3832 | return exec_control; | 3979 | return exec_control; |
3833 | } | 3980 | } |
3834 | 3981 | ||
@@ -3873,6 +4020,15 @@ static int vmx_vcpu_setup(struct vcpu_vmx *vmx) | |||
3873 | vmx_secondary_exec_control(vmx)); | 4020 | vmx_secondary_exec_control(vmx)); |
3874 | } | 4021 | } |
3875 | 4022 | ||
4023 | if (enable_apicv_reg_vid) { | ||
4024 | vmcs_write64(EOI_EXIT_BITMAP0, 0); | ||
4025 | vmcs_write64(EOI_EXIT_BITMAP1, 0); | ||
4026 | vmcs_write64(EOI_EXIT_BITMAP2, 0); | ||
4027 | vmcs_write64(EOI_EXIT_BITMAP3, 0); | ||
4028 | |||
4029 | vmcs_write16(GUEST_INTR_STATUS, 0); | ||
4030 | } | ||
4031 | |||
3876 | if (ple_gap) { | 4032 | if (ple_gap) { |
3877 | vmcs_write32(PLE_GAP, ple_gap); | 4033 | vmcs_write32(PLE_GAP, ple_gap); |
3878 | vmcs_write32(PLE_WINDOW, ple_window); | 4034 | vmcs_write32(PLE_WINDOW, ple_window); |
@@ -4787,6 +4943,26 @@ static int handle_apic_access(struct kvm_vcpu *vcpu) | |||
4787 | return emulate_instruction(vcpu, 0) == EMULATE_DONE; | 4943 | return emulate_instruction(vcpu, 0) == EMULATE_DONE; |
4788 | } | 4944 | } |
4789 | 4945 | ||
4946 | static int handle_apic_eoi_induced(struct kvm_vcpu *vcpu) | ||
4947 | { | ||
4948 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | ||
4949 | int vector = exit_qualification & 0xff; | ||
4950 | |||
4951 | /* EOI-induced VM exit is trap-like and thus no need to adjust IP */ | ||
4952 | kvm_apic_set_eoi_accelerated(vcpu, vector); | ||
4953 | return 1; | ||
4954 | } | ||
4955 | |||
4956 | static int handle_apic_write(struct kvm_vcpu *vcpu) | ||
4957 | { | ||
4958 | unsigned long exit_qualification = vmcs_readl(EXIT_QUALIFICATION); | ||
4959 | u32 offset = exit_qualification & 0xfff; | ||
4960 | |||
4961 | /* APIC-write VM exit is trap-like and thus no need to adjust IP */ | ||
4962 | kvm_apic_write_nodecode(vcpu, offset); | ||
4963 | return 1; | ||
4964 | } | ||
4965 | |||
4790 | static int handle_task_switch(struct kvm_vcpu *vcpu) | 4966 | static int handle_task_switch(struct kvm_vcpu *vcpu) |
4791 | { | 4967 | { |
4792 | struct vcpu_vmx *vmx = to_vmx(vcpu); | 4968 | struct vcpu_vmx *vmx = to_vmx(vcpu); |
@@ -5721,6 +5897,8 @@ static int (*const kvm_vmx_exit_handlers[])(struct kvm_vcpu *vcpu) = { | |||
5721 | [EXIT_REASON_VMON] = handle_vmon, | 5897 | [EXIT_REASON_VMON] = handle_vmon, |
5722 | [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, | 5898 | [EXIT_REASON_TPR_BELOW_THRESHOLD] = handle_tpr_below_threshold, |
5723 | [EXIT_REASON_APIC_ACCESS] = handle_apic_access, | 5899 | [EXIT_REASON_APIC_ACCESS] = handle_apic_access, |
5900 | [EXIT_REASON_APIC_WRITE] = handle_apic_write, | ||
5901 | [EXIT_REASON_EOI_INDUCED] = handle_apic_eoi_induced, | ||
5724 | [EXIT_REASON_WBINVD] = handle_wbinvd, | 5902 | [EXIT_REASON_WBINVD] = handle_wbinvd, |
5725 | [EXIT_REASON_XSETBV] = handle_xsetbv, | 5903 | [EXIT_REASON_XSETBV] = handle_xsetbv, |
5726 | [EXIT_REASON_TASK_SWITCH] = handle_task_switch, | 5904 | [EXIT_REASON_TASK_SWITCH] = handle_task_switch, |
@@ -6070,6 +6248,85 @@ static void update_cr8_intercept(struct kvm_vcpu *vcpu, int tpr, int irr) | |||
6070 | vmcs_write32(TPR_THRESHOLD, irr); | 6248 | vmcs_write32(TPR_THRESHOLD, irr); |
6071 | } | 6249 | } |
6072 | 6250 | ||
6251 | static void vmx_set_virtual_x2apic_mode(struct kvm_vcpu *vcpu, bool set) | ||
6252 | { | ||
6253 | u32 sec_exec_control; | ||
6254 | |||
6255 | /* | ||
6256 | * There is not point to enable virtualize x2apic without enable | ||
6257 | * apicv | ||
6258 | */ | ||
6259 | if (!cpu_has_vmx_virtualize_x2apic_mode() || | ||
6260 | !vmx_vm_has_apicv(vcpu->kvm)) | ||
6261 | return; | ||
6262 | |||
6263 | if (!vm_need_tpr_shadow(vcpu->kvm)) | ||
6264 | return; | ||
6265 | |||
6266 | sec_exec_control = vmcs_read32(SECONDARY_VM_EXEC_CONTROL); | ||
6267 | |||
6268 | if (set) { | ||
6269 | sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; | ||
6270 | sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE; | ||
6271 | } else { | ||
6272 | sec_exec_control &= ~SECONDARY_EXEC_VIRTUALIZE_X2APIC_MODE; | ||
6273 | sec_exec_control |= SECONDARY_EXEC_VIRTUALIZE_APIC_ACCESSES; | ||
6274 | } | ||
6275 | vmcs_write32(SECONDARY_VM_EXEC_CONTROL, sec_exec_control); | ||
6276 | |||
6277 | vmx_set_msr_bitmap(vcpu); | ||
6278 | } | ||
6279 | |||
6280 | static void vmx_hwapic_isr_update(struct kvm *kvm, int isr) | ||
6281 | { | ||
6282 | u16 status; | ||
6283 | u8 old; | ||
6284 | |||
6285 | if (!vmx_vm_has_apicv(kvm)) | ||
6286 | return; | ||
6287 | |||
6288 | if (isr == -1) | ||
6289 | isr = 0; | ||
6290 | |||
6291 | status = vmcs_read16(GUEST_INTR_STATUS); | ||
6292 | old = status >> 8; | ||
6293 | if (isr != old) { | ||
6294 | status &= 0xff; | ||
6295 | status |= isr << 8; | ||
6296 | vmcs_write16(GUEST_INTR_STATUS, status); | ||
6297 | } | ||
6298 | } | ||
6299 | |||
6300 | static void vmx_set_rvi(int vector) | ||
6301 | { | ||
6302 | u16 status; | ||
6303 | u8 old; | ||
6304 | |||
6305 | status = vmcs_read16(GUEST_INTR_STATUS); | ||
6306 | old = (u8)status & 0xff; | ||
6307 | if ((u8)vector != old) { | ||
6308 | status &= ~0xff; | ||
6309 | status |= (u8)vector; | ||
6310 | vmcs_write16(GUEST_INTR_STATUS, status); | ||
6311 | } | ||
6312 | } | ||
6313 | |||
6314 | static void vmx_hwapic_irr_update(struct kvm_vcpu *vcpu, int max_irr) | ||
6315 | { | ||
6316 | if (max_irr == -1) | ||
6317 | return; | ||
6318 | |||
6319 | vmx_set_rvi(max_irr); | ||
6320 | } | ||
6321 | |||
6322 | static void vmx_load_eoi_exitmap(struct kvm_vcpu *vcpu, u64 *eoi_exit_bitmap) | ||
6323 | { | ||
6324 | vmcs_write64(EOI_EXIT_BITMAP0, eoi_exit_bitmap[0]); | ||
6325 | vmcs_write64(EOI_EXIT_BITMAP1, eoi_exit_bitmap[1]); | ||
6326 | vmcs_write64(EOI_EXIT_BITMAP2, eoi_exit_bitmap[2]); | ||
6327 | vmcs_write64(EOI_EXIT_BITMAP3, eoi_exit_bitmap[3]); | ||
6328 | } | ||
6329 | |||
6073 | static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx) | 6330 | static void vmx_complete_atomic_exit(struct vcpu_vmx *vmx) |
6074 | { | 6331 | { |
6075 | u32 exit_intr_info; | 6332 | u32 exit_intr_info; |
@@ -7333,6 +7590,11 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
7333 | .enable_nmi_window = enable_nmi_window, | 7590 | .enable_nmi_window = enable_nmi_window, |
7334 | .enable_irq_window = enable_irq_window, | 7591 | .enable_irq_window = enable_irq_window, |
7335 | .update_cr8_intercept = update_cr8_intercept, | 7592 | .update_cr8_intercept = update_cr8_intercept, |
7593 | .set_virtual_x2apic_mode = vmx_set_virtual_x2apic_mode, | ||
7594 | .vm_has_apicv = vmx_vm_has_apicv, | ||
7595 | .load_eoi_exitmap = vmx_load_eoi_exitmap, | ||
7596 | .hwapic_irr_update = vmx_hwapic_irr_update, | ||
7597 | .hwapic_isr_update = vmx_hwapic_isr_update, | ||
7336 | 7598 | ||
7337 | .set_tss_addr = vmx_set_tss_addr, | 7599 | .set_tss_addr = vmx_set_tss_addr, |
7338 | .get_tdp_level = get_ept_level, | 7600 | .get_tdp_level = get_ept_level, |
@@ -7365,7 +7627,7 @@ static struct kvm_x86_ops vmx_x86_ops = { | |||
7365 | 7627 | ||
7366 | static int __init vmx_init(void) | 7628 | static int __init vmx_init(void) |
7367 | { | 7629 | { |
7368 | int r, i; | 7630 | int r, i, msr; |
7369 | 7631 | ||
7370 | rdmsrl_safe(MSR_EFER, &host_efer); | 7632 | rdmsrl_safe(MSR_EFER, &host_efer); |
7371 | 7633 | ||
@@ -7386,11 +7648,19 @@ static int __init vmx_init(void) | |||
7386 | if (!vmx_msr_bitmap_legacy) | 7648 | if (!vmx_msr_bitmap_legacy) |
7387 | goto out1; | 7649 | goto out1; |
7388 | 7650 | ||
7651 | vmx_msr_bitmap_legacy_x2apic = | ||
7652 | (unsigned long *)__get_free_page(GFP_KERNEL); | ||
7653 | if (!vmx_msr_bitmap_legacy_x2apic) | ||
7654 | goto out2; | ||
7389 | 7655 | ||
7390 | vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL); | 7656 | vmx_msr_bitmap_longmode = (unsigned long *)__get_free_page(GFP_KERNEL); |
7391 | if (!vmx_msr_bitmap_longmode) | 7657 | if (!vmx_msr_bitmap_longmode) |
7392 | goto out2; | 7658 | goto out3; |
7393 | 7659 | ||
7660 | vmx_msr_bitmap_longmode_x2apic = | ||
7661 | (unsigned long *)__get_free_page(GFP_KERNEL); | ||
7662 | if (!vmx_msr_bitmap_longmode_x2apic) | ||
7663 | goto out4; | ||
7394 | 7664 | ||
7395 | /* | 7665 | /* |
7396 | * Allow direct access to the PC debug port (it is often used for I/O | 7666 | * Allow direct access to the PC debug port (it is often used for I/O |
@@ -7422,6 +7692,28 @@ static int __init vmx_init(void) | |||
7422 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); | 7692 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_CS, false); |
7423 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); | 7693 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_ESP, false); |
7424 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); | 7694 | vmx_disable_intercept_for_msr(MSR_IA32_SYSENTER_EIP, false); |
7695 | memcpy(vmx_msr_bitmap_legacy_x2apic, | ||
7696 | vmx_msr_bitmap_legacy, PAGE_SIZE); | ||
7697 | memcpy(vmx_msr_bitmap_longmode_x2apic, | ||
7698 | vmx_msr_bitmap_longmode, PAGE_SIZE); | ||
7699 | |||
7700 | if (enable_apicv_reg_vid) { | ||
7701 | for (msr = 0x800; msr <= 0x8ff; msr++) | ||
7702 | vmx_disable_intercept_msr_read_x2apic(msr); | ||
7703 | |||
7704 | /* According SDM, in x2apic mode, the whole id reg is used. | ||
7705 | * But in KVM, it only use the highest eight bits. Need to | ||
7706 | * intercept it */ | ||
7707 | vmx_enable_intercept_msr_read_x2apic(0x802); | ||
7708 | /* TMCCT */ | ||
7709 | vmx_enable_intercept_msr_read_x2apic(0x839); | ||
7710 | /* TPR */ | ||
7711 | vmx_disable_intercept_msr_write_x2apic(0x808); | ||
7712 | /* EOI */ | ||
7713 | vmx_disable_intercept_msr_write_x2apic(0x80b); | ||
7714 | /* SELF-IPI */ | ||
7715 | vmx_disable_intercept_msr_write_x2apic(0x83f); | ||
7716 | } | ||
7425 | 7717 | ||
7426 | if (enable_ept) { | 7718 | if (enable_ept) { |
7427 | kvm_mmu_set_mask_ptes(0ull, | 7719 | kvm_mmu_set_mask_ptes(0ull, |
@@ -7435,8 +7727,10 @@ static int __init vmx_init(void) | |||
7435 | 7727 | ||
7436 | return 0; | 7728 | return 0; |
7437 | 7729 | ||
7438 | out3: | 7730 | out4: |
7439 | free_page((unsigned long)vmx_msr_bitmap_longmode); | 7731 | free_page((unsigned long)vmx_msr_bitmap_longmode); |
7732 | out3: | ||
7733 | free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); | ||
7440 | out2: | 7734 | out2: |
7441 | free_page((unsigned long)vmx_msr_bitmap_legacy); | 7735 | free_page((unsigned long)vmx_msr_bitmap_legacy); |
7442 | out1: | 7736 | out1: |
@@ -7448,6 +7742,8 @@ out: | |||
7448 | 7742 | ||
7449 | static void __exit vmx_exit(void) | 7743 | static void __exit vmx_exit(void) |
7450 | { | 7744 | { |
7745 | free_page((unsigned long)vmx_msr_bitmap_legacy_x2apic); | ||
7746 | free_page((unsigned long)vmx_msr_bitmap_longmode_x2apic); | ||
7451 | free_page((unsigned long)vmx_msr_bitmap_legacy); | 7747 | free_page((unsigned long)vmx_msr_bitmap_legacy); |
7452 | free_page((unsigned long)vmx_msr_bitmap_longmode); | 7748 | free_page((unsigned long)vmx_msr_bitmap_longmode); |
7453 | free_page((unsigned long)vmx_io_bitmap_b); | 7749 | free_page((unsigned long)vmx_io_bitmap_b); |
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index b9f55299ed7e..373e17a0d398 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c | |||
@@ -870,8 +870,6 @@ static int set_efer(struct kvm_vcpu *vcpu, u64 efer) | |||
870 | 870 | ||
871 | kvm_x86_ops->set_efer(vcpu, efer); | 871 | kvm_x86_ops->set_efer(vcpu, efer); |
872 | 872 | ||
873 | vcpu->arch.mmu.base_role.nxe = (efer & EFER_NX) && !tdp_enabled; | ||
874 | |||
875 | /* Update reserved bits */ | 873 | /* Update reserved bits */ |
876 | if ((efer ^ old_efer) & EFER_NX) | 874 | if ((efer ^ old_efer) & EFER_NX) |
877 | kvm_mmu_reset_context(vcpu); | 875 | kvm_mmu_reset_context(vcpu); |
@@ -5565,7 +5563,7 @@ static void inject_pending_event(struct kvm_vcpu *vcpu) | |||
5565 | vcpu->arch.nmi_injected = true; | 5563 | vcpu->arch.nmi_injected = true; |
5566 | kvm_x86_ops->set_nmi(vcpu); | 5564 | kvm_x86_ops->set_nmi(vcpu); |
5567 | } | 5565 | } |
5568 | } else if (kvm_cpu_has_interrupt(vcpu)) { | 5566 | } else if (kvm_cpu_has_injectable_intr(vcpu)) { |
5569 | if (kvm_x86_ops->interrupt_allowed(vcpu)) { | 5567 | if (kvm_x86_ops->interrupt_allowed(vcpu)) { |
5570 | kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), | 5568 | kvm_queue_interrupt(vcpu, kvm_cpu_get_interrupt(vcpu), |
5571 | false); | 5569 | false); |
@@ -5633,6 +5631,16 @@ static void kvm_gen_update_masterclock(struct kvm *kvm) | |||
5633 | #endif | 5631 | #endif |
5634 | } | 5632 | } |
5635 | 5633 | ||
5634 | static void update_eoi_exitmap(struct kvm_vcpu *vcpu) | ||
5635 | { | ||
5636 | u64 eoi_exit_bitmap[4]; | ||
5637 | |||
5638 | memset(eoi_exit_bitmap, 0, 32); | ||
5639 | |||
5640 | kvm_ioapic_calculate_eoi_exitmap(vcpu, eoi_exit_bitmap); | ||
5641 | kvm_x86_ops->load_eoi_exitmap(vcpu, eoi_exit_bitmap); | ||
5642 | } | ||
5643 | |||
5636 | static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | 5644 | static int vcpu_enter_guest(struct kvm_vcpu *vcpu) |
5637 | { | 5645 | { |
5638 | int r; | 5646 | int r; |
@@ -5686,6 +5694,8 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
5686 | kvm_handle_pmu_event(vcpu); | 5694 | kvm_handle_pmu_event(vcpu); |
5687 | if (kvm_check_request(KVM_REQ_PMI, vcpu)) | 5695 | if (kvm_check_request(KVM_REQ_PMI, vcpu)) |
5688 | kvm_deliver_pmi(vcpu); | 5696 | kvm_deliver_pmi(vcpu); |
5697 | if (kvm_check_request(KVM_REQ_EOIBITMAP, vcpu)) | ||
5698 | update_eoi_exitmap(vcpu); | ||
5689 | } | 5699 | } |
5690 | 5700 | ||
5691 | if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) { | 5701 | if (kvm_check_request(KVM_REQ_EVENT, vcpu) || req_int_win) { |
@@ -5694,10 +5704,17 @@ static int vcpu_enter_guest(struct kvm_vcpu *vcpu) | |||
5694 | /* enable NMI/IRQ window open exits if needed */ | 5704 | /* enable NMI/IRQ window open exits if needed */ |
5695 | if (vcpu->arch.nmi_pending) | 5705 | if (vcpu->arch.nmi_pending) |
5696 | kvm_x86_ops->enable_nmi_window(vcpu); | 5706 | kvm_x86_ops->enable_nmi_window(vcpu); |
5697 | else if (kvm_cpu_has_interrupt(vcpu) || req_int_win) | 5707 | else if (kvm_cpu_has_injectable_intr(vcpu) || req_int_win) |
5698 | kvm_x86_ops->enable_irq_window(vcpu); | 5708 | kvm_x86_ops->enable_irq_window(vcpu); |
5699 | 5709 | ||
5700 | if (kvm_lapic_enabled(vcpu)) { | 5710 | if (kvm_lapic_enabled(vcpu)) { |
5711 | /* | ||
5712 | * Update architecture specific hints for APIC | ||
5713 | * virtual interrupt delivery. | ||
5714 | */ | ||
5715 | if (kvm_x86_ops->hwapic_irr_update) | ||
5716 | kvm_x86_ops->hwapic_irr_update(vcpu, | ||
5717 | kvm_lapic_find_highest_irr(vcpu)); | ||
5701 | update_cr8_intercept(vcpu); | 5718 | update_cr8_intercept(vcpu); |
5702 | kvm_lapic_sync_to_vapic(vcpu); | 5719 | kvm_lapic_sync_to_vapic(vcpu); |
5703 | } | 5720 | } |