diff options
Diffstat (limited to 'drivers/kvm')
-rw-r--r-- | drivers/kvm/kvm.h | 1 | ||||
-rw-r--r-- | drivers/kvm/kvm_main.c | 19 | ||||
-rw-r--r-- | drivers/kvm/mmu.c | 16 | ||||
-rw-r--r-- | drivers/kvm/paging_tmpl.h | 79 | ||||
-rw-r--r-- | drivers/kvm/svm.c | 28 | ||||
-rw-r--r-- | drivers/kvm/vmx.c | 5 | ||||
-rw-r--r-- | drivers/kvm/x86_emulate.c | 98 |
7 files changed, 151 insertions, 95 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h index 91e0c75aca8f..2db1ca4c6800 100644 --- a/drivers/kvm/kvm.h +++ b/drivers/kvm/kvm.h | |||
@@ -242,6 +242,7 @@ struct kvm_vcpu { | |||
242 | u64 pdptrs[4]; /* pae */ | 242 | u64 pdptrs[4]; /* pae */ |
243 | u64 shadow_efer; | 243 | u64 shadow_efer; |
244 | u64 apic_base; | 244 | u64 apic_base; |
245 | u64 ia32_misc_enable_msr; | ||
245 | int nmsrs; | 246 | int nmsrs; |
246 | struct vmx_msr_entry *guest_msrs; | 247 | struct vmx_msr_entry *guest_msrs; |
247 | struct vmx_msr_entry *host_msrs; | 248 | struct vmx_msr_entry *host_msrs; |
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c index 67c1154960f0..b10972ed0c9f 100644 --- a/drivers/kvm/kvm_main.c +++ b/drivers/kvm/kvm_main.c | |||
@@ -272,7 +272,9 @@ static void kvm_free_physmem(struct kvm *kvm) | |||
272 | 272 | ||
273 | static void kvm_free_vcpu(struct kvm_vcpu *vcpu) | 273 | static void kvm_free_vcpu(struct kvm_vcpu *vcpu) |
274 | { | 274 | { |
275 | vcpu_load(vcpu->kvm, vcpu_slot(vcpu)); | ||
275 | kvm_mmu_destroy(vcpu); | 276 | kvm_mmu_destroy(vcpu); |
277 | vcpu_put(vcpu); | ||
276 | kvm_arch_ops->vcpu_free(vcpu); | 278 | kvm_arch_ops->vcpu_free(vcpu); |
277 | } | 279 | } |
278 | 280 | ||
@@ -1224,6 +1226,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata) | |||
1224 | case MSR_IA32_APICBASE: | 1226 | case MSR_IA32_APICBASE: |
1225 | data = vcpu->apic_base; | 1227 | data = vcpu->apic_base; |
1226 | break; | 1228 | break; |
1229 | case MSR_IA32_MISC_ENABLE: | ||
1230 | data = vcpu->ia32_misc_enable_msr; | ||
1231 | break; | ||
1227 | #ifdef CONFIG_X86_64 | 1232 | #ifdef CONFIG_X86_64 |
1228 | case MSR_EFER: | 1233 | case MSR_EFER: |
1229 | data = vcpu->shadow_efer; | 1234 | data = vcpu->shadow_efer; |
@@ -1295,6 +1300,9 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) | |||
1295 | case MSR_IA32_APICBASE: | 1300 | case MSR_IA32_APICBASE: |
1296 | vcpu->apic_base = data; | 1301 | vcpu->apic_base = data; |
1297 | break; | 1302 | break; |
1303 | case MSR_IA32_MISC_ENABLE: | ||
1304 | vcpu->ia32_misc_enable_msr = data; | ||
1305 | break; | ||
1298 | default: | 1306 | default: |
1299 | printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr); | 1307 | printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr); |
1300 | return 1; | 1308 | return 1; |
@@ -1598,6 +1606,10 @@ static u32 msrs_to_save[] = { | |||
1598 | 1606 | ||
1599 | static unsigned num_msrs_to_save; | 1607 | static unsigned num_msrs_to_save; |
1600 | 1608 | ||
1609 | static u32 emulated_msrs[] = { | ||
1610 | MSR_IA32_MISC_ENABLE, | ||
1611 | }; | ||
1612 | |||
1601 | static __init void kvm_init_msr_list(void) | 1613 | static __init void kvm_init_msr_list(void) |
1602 | { | 1614 | { |
1603 | u32 dummy[2]; | 1615 | u32 dummy[2]; |
@@ -1923,7 +1935,7 @@ static long kvm_dev_ioctl(struct file *filp, | |||
1923 | if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) | 1935 | if (copy_from_user(&msr_list, user_msr_list, sizeof msr_list)) |
1924 | goto out; | 1936 | goto out; |
1925 | n = msr_list.nmsrs; | 1937 | n = msr_list.nmsrs; |
1926 | msr_list.nmsrs = num_msrs_to_save; | 1938 | msr_list.nmsrs = num_msrs_to_save + ARRAY_SIZE(emulated_msrs); |
1927 | if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) | 1939 | if (copy_to_user(user_msr_list, &msr_list, sizeof msr_list)) |
1928 | goto out; | 1940 | goto out; |
1929 | r = -E2BIG; | 1941 | r = -E2BIG; |
@@ -1933,6 +1945,11 @@ static long kvm_dev_ioctl(struct file *filp, | |||
1933 | if (copy_to_user(user_msr_list->indices, &msrs_to_save, | 1945 | if (copy_to_user(user_msr_list->indices, &msrs_to_save, |
1934 | num_msrs_to_save * sizeof(u32))) | 1946 | num_msrs_to_save * sizeof(u32))) |
1935 | goto out; | 1947 | goto out; |
1948 | if (copy_to_user(user_msr_list->indices | ||
1949 | + num_msrs_to_save * sizeof(u32), | ||
1950 | &emulated_msrs, | ||
1951 | ARRAY_SIZE(emulated_msrs) * sizeof(u32))) | ||
1952 | goto out; | ||
1936 | r = 0; | 1953 | r = 0; |
1937 | break; | 1954 | break; |
1938 | } | 1955 | } |
diff --git a/drivers/kvm/mmu.c b/drivers/kvm/mmu.c index c6f972914f08..22c426cd8cb2 100644 --- a/drivers/kvm/mmu.c +++ b/drivers/kvm/mmu.c | |||
@@ -143,6 +143,7 @@ static int dbg = 1; | |||
143 | #define PFERR_PRESENT_MASK (1U << 0) | 143 | #define PFERR_PRESENT_MASK (1U << 0) |
144 | #define PFERR_WRITE_MASK (1U << 1) | 144 | #define PFERR_WRITE_MASK (1U << 1) |
145 | #define PFERR_USER_MASK (1U << 2) | 145 | #define PFERR_USER_MASK (1U << 2) |
146 | #define PFERR_FETCH_MASK (1U << 4) | ||
146 | 147 | ||
147 | #define PT64_ROOT_LEVEL 4 | 148 | #define PT64_ROOT_LEVEL 4 |
148 | #define PT32_ROOT_LEVEL 2 | 149 | #define PT32_ROOT_LEVEL 2 |
@@ -168,6 +169,11 @@ static int is_cpuid_PSE36(void) | |||
168 | return 1; | 169 | return 1; |
169 | } | 170 | } |
170 | 171 | ||
172 | static int is_nx(struct kvm_vcpu *vcpu) | ||
173 | { | ||
174 | return vcpu->shadow_efer & EFER_NX; | ||
175 | } | ||
176 | |||
171 | static int is_present_pte(unsigned long pte) | 177 | static int is_present_pte(unsigned long pte) |
172 | { | 178 | { |
173 | return pte & PT_PRESENT_MASK; | 179 | return pte & PT_PRESENT_MASK; |
@@ -992,16 +998,6 @@ static inline int fix_read_pf(u64 *shadow_ent) | |||
992 | return 0; | 998 | return 0; |
993 | } | 999 | } |
994 | 1000 | ||
995 | static int may_access(u64 pte, int write, int user) | ||
996 | { | ||
997 | |||
998 | if (user && !(pte & PT_USER_MASK)) | ||
999 | return 0; | ||
1000 | if (write && !(pte & PT_WRITABLE_MASK)) | ||
1001 | return 0; | ||
1002 | return 1; | ||
1003 | } | ||
1004 | |||
1005 | static void paging_free(struct kvm_vcpu *vcpu) | 1001 | static void paging_free(struct kvm_vcpu *vcpu) |
1006 | { | 1002 | { |
1007 | nonpaging_free(vcpu); | 1003 | nonpaging_free(vcpu); |
diff --git a/drivers/kvm/paging_tmpl.h b/drivers/kvm/paging_tmpl.h index 2dbf4307ed9e..149fa45fd9a5 100644 --- a/drivers/kvm/paging_tmpl.h +++ b/drivers/kvm/paging_tmpl.h | |||
@@ -63,13 +63,15 @@ struct guest_walker { | |||
63 | pt_element_t *ptep; | 63 | pt_element_t *ptep; |
64 | pt_element_t inherited_ar; | 64 | pt_element_t inherited_ar; |
65 | gfn_t gfn; | 65 | gfn_t gfn; |
66 | u32 error_code; | ||
66 | }; | 67 | }; |
67 | 68 | ||
68 | /* | 69 | /* |
69 | * Fetch a guest pte for a guest virtual address | 70 | * Fetch a guest pte for a guest virtual address |
70 | */ | 71 | */ |
71 | static void FNAME(walk_addr)(struct guest_walker *walker, | 72 | static int FNAME(walk_addr)(struct guest_walker *walker, |
72 | struct kvm_vcpu *vcpu, gva_t addr) | 73 | struct kvm_vcpu *vcpu, gva_t addr, |
74 | int write_fault, int user_fault, int fetch_fault) | ||
73 | { | 75 | { |
74 | hpa_t hpa; | 76 | hpa_t hpa; |
75 | struct kvm_memory_slot *slot; | 77 | struct kvm_memory_slot *slot; |
@@ -86,7 +88,7 @@ static void FNAME(walk_addr)(struct guest_walker *walker, | |||
86 | walker->ptep = &vcpu->pdptrs[(addr >> 30) & 3]; | 88 | walker->ptep = &vcpu->pdptrs[(addr >> 30) & 3]; |
87 | root = *walker->ptep; | 89 | root = *walker->ptep; |
88 | if (!(root & PT_PRESENT_MASK)) | 90 | if (!(root & PT_PRESENT_MASK)) |
89 | return; | 91 | goto not_present; |
90 | --walker->level; | 92 | --walker->level; |
91 | } | 93 | } |
92 | #endif | 94 | #endif |
@@ -111,11 +113,23 @@ static void FNAME(walk_addr)(struct guest_walker *walker, | |||
111 | ASSERT(((unsigned long)walker->table & PAGE_MASK) == | 113 | ASSERT(((unsigned long)walker->table & PAGE_MASK) == |
112 | ((unsigned long)ptep & PAGE_MASK)); | 114 | ((unsigned long)ptep & PAGE_MASK)); |
113 | 115 | ||
114 | if (is_present_pte(*ptep) && !(*ptep & PT_ACCESSED_MASK)) | ||
115 | *ptep |= PT_ACCESSED_MASK; | ||
116 | |||
117 | if (!is_present_pte(*ptep)) | 116 | if (!is_present_pte(*ptep)) |
118 | break; | 117 | goto not_present; |
118 | |||
119 | if (write_fault && !is_writeble_pte(*ptep)) | ||
120 | if (user_fault || is_write_protection(vcpu)) | ||
121 | goto access_error; | ||
122 | |||
123 | if (user_fault && !(*ptep & PT_USER_MASK)) | ||
124 | goto access_error; | ||
125 | |||
126 | #if PTTYPE == 64 | ||
127 | if (fetch_fault && is_nx(vcpu) && (*ptep & PT64_NX_MASK)) | ||
128 | goto access_error; | ||
129 | #endif | ||
130 | |||
131 | if (!(*ptep & PT_ACCESSED_MASK)) | ||
132 | *ptep |= PT_ACCESSED_MASK; /* avoid rmw */ | ||
119 | 133 | ||
120 | if (walker->level == PT_PAGE_TABLE_LEVEL) { | 134 | if (walker->level == PT_PAGE_TABLE_LEVEL) { |
121 | walker->gfn = (*ptep & PT_BASE_ADDR_MASK) | 135 | walker->gfn = (*ptep & PT_BASE_ADDR_MASK) |
@@ -146,6 +160,23 @@ static void FNAME(walk_addr)(struct guest_walker *walker, | |||
146 | } | 160 | } |
147 | walker->ptep = ptep; | 161 | walker->ptep = ptep; |
148 | pgprintk("%s: pte %llx\n", __FUNCTION__, (u64)*ptep); | 162 | pgprintk("%s: pte %llx\n", __FUNCTION__, (u64)*ptep); |
163 | return 1; | ||
164 | |||
165 | not_present: | ||
166 | walker->error_code = 0; | ||
167 | goto err; | ||
168 | |||
169 | access_error: | ||
170 | walker->error_code = PFERR_PRESENT_MASK; | ||
171 | |||
172 | err: | ||
173 | if (write_fault) | ||
174 | walker->error_code |= PFERR_WRITE_MASK; | ||
175 | if (user_fault) | ||
176 | walker->error_code |= PFERR_USER_MASK; | ||
177 | if (fetch_fault) | ||
178 | walker->error_code |= PFERR_FETCH_MASK; | ||
179 | return 0; | ||
149 | } | 180 | } |
150 | 181 | ||
151 | static void FNAME(release_walker)(struct guest_walker *walker) | 182 | static void FNAME(release_walker)(struct guest_walker *walker) |
@@ -274,7 +305,7 @@ static int FNAME(fix_write_pf)(struct kvm_vcpu *vcpu, | |||
274 | struct kvm_mmu_page *page; | 305 | struct kvm_mmu_page *page; |
275 | 306 | ||
276 | if (is_writeble_pte(*shadow_ent)) | 307 | if (is_writeble_pte(*shadow_ent)) |
277 | return 0; | 308 | return !user || (*shadow_ent & PT_USER_MASK); |
278 | 309 | ||
279 | writable_shadow = *shadow_ent & PT_SHADOW_WRITABLE_MASK; | 310 | writable_shadow = *shadow_ent & PT_SHADOW_WRITABLE_MASK; |
280 | if (user) { | 311 | if (user) { |
@@ -347,8 +378,8 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
347 | u32 error_code) | 378 | u32 error_code) |
348 | { | 379 | { |
349 | int write_fault = error_code & PFERR_WRITE_MASK; | 380 | int write_fault = error_code & PFERR_WRITE_MASK; |
350 | int pte_present = error_code & PFERR_PRESENT_MASK; | ||
351 | int user_fault = error_code & PFERR_USER_MASK; | 381 | int user_fault = error_code & PFERR_USER_MASK; |
382 | int fetch_fault = error_code & PFERR_FETCH_MASK; | ||
352 | struct guest_walker walker; | 383 | struct guest_walker walker; |
353 | u64 *shadow_pte; | 384 | u64 *shadow_pte; |
354 | int fixed; | 385 | int fixed; |
@@ -365,19 +396,20 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
365 | /* | 396 | /* |
366 | * Look up the shadow pte for the faulting address. | 397 | * Look up the shadow pte for the faulting address. |
367 | */ | 398 | */ |
368 | FNAME(walk_addr)(&walker, vcpu, addr); | 399 | r = FNAME(walk_addr)(&walker, vcpu, addr, write_fault, user_fault, |
369 | shadow_pte = FNAME(fetch)(vcpu, addr, &walker); | 400 | fetch_fault); |
370 | 401 | ||
371 | /* | 402 | /* |
372 | * The page is not mapped by the guest. Let the guest handle it. | 403 | * The page is not mapped by the guest. Let the guest handle it. |
373 | */ | 404 | */ |
374 | if (!shadow_pte) { | 405 | if (!r) { |
375 | pgprintk("%s: not mapped\n", __FUNCTION__); | 406 | pgprintk("%s: guest page fault\n", __FUNCTION__); |
376 | inject_page_fault(vcpu, addr, error_code); | 407 | inject_page_fault(vcpu, addr, walker.error_code); |
377 | FNAME(release_walker)(&walker); | 408 | FNAME(release_walker)(&walker); |
378 | return 0; | 409 | return 0; |
379 | } | 410 | } |
380 | 411 | ||
412 | shadow_pte = FNAME(fetch)(vcpu, addr, &walker); | ||
381 | pgprintk("%s: shadow pte %p %llx\n", __FUNCTION__, | 413 | pgprintk("%s: shadow pte %p %llx\n", __FUNCTION__, |
382 | shadow_pte, *shadow_pte); | 414 | shadow_pte, *shadow_pte); |
383 | 415 | ||
@@ -399,22 +431,7 @@ static int FNAME(page_fault)(struct kvm_vcpu *vcpu, gva_t addr, | |||
399 | * mmio: emulate if accessible, otherwise its a guest fault. | 431 | * mmio: emulate if accessible, otherwise its a guest fault. |
400 | */ | 432 | */ |
401 | if (is_io_pte(*shadow_pte)) { | 433 | if (is_io_pte(*shadow_pte)) { |
402 | if (may_access(*shadow_pte, write_fault, user_fault)) | 434 | return 1; |
403 | return 1; | ||
404 | pgprintk("%s: io work, no access\n", __FUNCTION__); | ||
405 | inject_page_fault(vcpu, addr, | ||
406 | error_code | PFERR_PRESENT_MASK); | ||
407 | kvm_mmu_audit(vcpu, "post page fault (io)"); | ||
408 | return 0; | ||
409 | } | ||
410 | |||
411 | /* | ||
412 | * pte not present, guest page fault. | ||
413 | */ | ||
414 | if (pte_present && !fixed && !write_pt) { | ||
415 | inject_page_fault(vcpu, addr, error_code); | ||
416 | kvm_mmu_audit(vcpu, "post page fault (guest)"); | ||
417 | return 0; | ||
418 | } | 435 | } |
419 | 436 | ||
420 | ++kvm_stat.pf_fixed; | 437 | ++kvm_stat.pf_fixed; |
@@ -429,7 +446,7 @@ static gpa_t FNAME(gva_to_gpa)(struct kvm_vcpu *vcpu, gva_t vaddr) | |||
429 | pt_element_t guest_pte; | 446 | pt_element_t guest_pte; |
430 | gpa_t gpa; | 447 | gpa_t gpa; |
431 | 448 | ||
432 | FNAME(walk_addr)(&walker, vcpu, vaddr); | 449 | FNAME(walk_addr)(&walker, vcpu, vaddr, 0, 0, 0); |
433 | guest_pte = *walker.ptep; | 450 | guest_pte = *walker.ptep; |
434 | FNAME(release_walker)(&walker); | 451 | FNAME(release_walker)(&walker); |
435 | 452 | ||
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c index 714f6a7841cd..c79df79307ed 100644 --- a/drivers/kvm/svm.c +++ b/drivers/kvm/svm.c | |||
@@ -502,6 +502,7 @@ static void init_vmcb(struct vmcb *vmcb) | |||
502 | (1ULL << INTERCEPT_IOIO_PROT) | | 502 | (1ULL << INTERCEPT_IOIO_PROT) | |
503 | (1ULL << INTERCEPT_MSR_PROT) | | 503 | (1ULL << INTERCEPT_MSR_PROT) | |
504 | (1ULL << INTERCEPT_TASK_SWITCH) | | 504 | (1ULL << INTERCEPT_TASK_SWITCH) | |
505 | (1ULL << INTERCEPT_SHUTDOWN) | | ||
505 | (1ULL << INTERCEPT_VMRUN) | | 506 | (1ULL << INTERCEPT_VMRUN) | |
506 | (1ULL << INTERCEPT_VMMCALL) | | 507 | (1ULL << INTERCEPT_VMMCALL) | |
507 | (1ULL << INTERCEPT_VMLOAD) | | 508 | (1ULL << INTERCEPT_VMLOAD) | |
@@ -680,14 +681,14 @@ static void svm_get_cs_db_l_bits(struct kvm_vcpu *vcpu, int *db, int *l) | |||
680 | 681 | ||
681 | static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 682 | static void svm_get_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) |
682 | { | 683 | { |
683 | dt->limit = vcpu->svm->vmcb->save.ldtr.limit; | 684 | dt->limit = vcpu->svm->vmcb->save.idtr.limit; |
684 | dt->base = vcpu->svm->vmcb->save.ldtr.base; | 685 | dt->base = vcpu->svm->vmcb->save.idtr.base; |
685 | } | 686 | } |
686 | 687 | ||
687 | static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 688 | static void svm_set_idt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) |
688 | { | 689 | { |
689 | vcpu->svm->vmcb->save.ldtr.limit = dt->limit; | 690 | vcpu->svm->vmcb->save.idtr.limit = dt->limit; |
690 | vcpu->svm->vmcb->save.ldtr.base = dt->base ; | 691 | vcpu->svm->vmcb->save.idtr.base = dt->base ; |
691 | } | 692 | } |
692 | 693 | ||
693 | static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | 694 | static void svm_get_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) |
@@ -892,6 +893,19 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
892 | return 0; | 893 | return 0; |
893 | } | 894 | } |
894 | 895 | ||
896 | static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | ||
897 | { | ||
898 | /* | ||
899 | * VMCB is undefined after a SHUTDOWN intercept | ||
900 | * so reinitialize it. | ||
901 | */ | ||
902 | memset(vcpu->svm->vmcb, 0, PAGE_SIZE); | ||
903 | init_vmcb(vcpu->svm->vmcb); | ||
904 | |||
905 | kvm_run->exit_reason = KVM_EXIT_SHUTDOWN; | ||
906 | return 0; | ||
907 | } | ||
908 | |||
895 | static int io_get_override(struct kvm_vcpu *vcpu, | 909 | static int io_get_override(struct kvm_vcpu *vcpu, |
896 | struct vmcb_seg **seg, | 910 | struct vmcb_seg **seg, |
897 | int *addr_override) | 911 | int *addr_override) |
@@ -1149,7 +1163,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) | |||
1149 | case MSR_K6_STAR: | 1163 | case MSR_K6_STAR: |
1150 | vcpu->svm->vmcb->save.star = data; | 1164 | vcpu->svm->vmcb->save.star = data; |
1151 | break; | 1165 | break; |
1152 | #ifdef CONFIG_X86_64_ | 1166 | #ifdef CONFIG_X86_64 |
1153 | case MSR_LSTAR: | 1167 | case MSR_LSTAR: |
1154 | vcpu->svm->vmcb->save.lstar = data; | 1168 | vcpu->svm->vmcb->save.lstar = data; |
1155 | break; | 1169 | break; |
@@ -1249,6 +1263,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu, | |||
1249 | [SVM_EXIT_IOIO] = io_interception, | 1263 | [SVM_EXIT_IOIO] = io_interception, |
1250 | [SVM_EXIT_MSR] = msr_interception, | 1264 | [SVM_EXIT_MSR] = msr_interception, |
1251 | [SVM_EXIT_TASK_SWITCH] = task_switch_interception, | 1265 | [SVM_EXIT_TASK_SWITCH] = task_switch_interception, |
1266 | [SVM_EXIT_SHUTDOWN] = shutdown_interception, | ||
1252 | [SVM_EXIT_VMRUN] = invalid_op_interception, | 1267 | [SVM_EXIT_VMRUN] = invalid_op_interception, |
1253 | [SVM_EXIT_VMMCALL] = invalid_op_interception, | 1268 | [SVM_EXIT_VMMCALL] = invalid_op_interception, |
1254 | [SVM_EXIT_VMLOAD] = invalid_op_interception, | 1269 | [SVM_EXIT_VMLOAD] = invalid_op_interception, |
@@ -1407,7 +1422,8 @@ static int svm_vcpu_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) | |||
1407 | int r; | 1422 | int r; |
1408 | 1423 | ||
1409 | again: | 1424 | again: |
1410 | do_interrupt_requests(vcpu, kvm_run); | 1425 | if (!vcpu->mmio_read_completed) |
1426 | do_interrupt_requests(vcpu, kvm_run); | ||
1411 | 1427 | ||
1412 | clgi(); | 1428 | clgi(); |
1413 | 1429 | ||
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c index 0aa2659f6ae5..54c35c0b3181 100644 --- a/drivers/kvm/vmx.c +++ b/drivers/kvm/vmx.c | |||
@@ -1116,6 +1116,8 @@ static int vmx_vcpu_setup(struct kvm_vcpu *vcpu) | |||
1116 | 1116 | ||
1117 | if (rdmsr_safe(index, &data_low, &data_high) < 0) | 1117 | if (rdmsr_safe(index, &data_low, &data_high) < 0) |
1118 | continue; | 1118 | continue; |
1119 | if (wrmsr_safe(index, data_low, data_high) < 0) | ||
1120 | continue; | ||
1119 | data = data_low | ((u64)data_high << 32); | 1121 | data = data_low | ((u64)data_high << 32); |
1120 | vcpu->host_msrs[j].index = index; | 1122 | vcpu->host_msrs[j].index = index; |
1121 | vcpu->host_msrs[j].reserved = 0; | 1123 | vcpu->host_msrs[j].reserved = 0; |
@@ -1717,7 +1719,8 @@ again: | |||
1717 | vmcs_writel(HOST_GS_BASE, segment_base(gs_sel)); | 1719 | vmcs_writel(HOST_GS_BASE, segment_base(gs_sel)); |
1718 | #endif | 1720 | #endif |
1719 | 1721 | ||
1720 | do_interrupt_requests(vcpu, kvm_run); | 1722 | if (!vcpu->mmio_read_completed) |
1723 | do_interrupt_requests(vcpu, kvm_run); | ||
1721 | 1724 | ||
1722 | if (vcpu->guest_debug.enabled) | 1725 | if (vcpu->guest_debug.enabled) |
1723 | kvm_guest_debug_pre(vcpu); | 1726 | kvm_guest_debug_pre(vcpu); |
diff --git a/drivers/kvm/x86_emulate.c b/drivers/kvm/x86_emulate.c index be70795b4822..7513cddb929f 100644 --- a/drivers/kvm/x86_emulate.c +++ b/drivers/kvm/x86_emulate.c | |||
@@ -61,6 +61,7 @@ | |||
61 | #define ModRM (1<<6) | 61 | #define ModRM (1<<6) |
62 | /* Destination is only written; never read. */ | 62 | /* Destination is only written; never read. */ |
63 | #define Mov (1<<7) | 63 | #define Mov (1<<7) |
64 | #define BitOp (1<<8) | ||
64 | 65 | ||
65 | static u8 opcode_table[256] = { | 66 | static u8 opcode_table[256] = { |
66 | /* 0x00 - 0x07 */ | 67 | /* 0x00 - 0x07 */ |
@@ -148,7 +149,7 @@ static u8 opcode_table[256] = { | |||
148 | 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM | 149 | 0, 0, ByteOp | DstMem | SrcNone | ModRM, DstMem | SrcNone | ModRM |
149 | }; | 150 | }; |
150 | 151 | ||
151 | static u8 twobyte_table[256] = { | 152 | static u16 twobyte_table[256] = { |
152 | /* 0x00 - 0x0F */ | 153 | /* 0x00 - 0x0F */ |
153 | 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0, | 154 | 0, SrcMem | ModRM | DstReg, 0, 0, 0, 0, ImplicitOps, 0, |
154 | 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, | 155 | 0, 0, 0, 0, 0, ImplicitOps | ModRM, 0, 0, |
@@ -180,16 +181,16 @@ static u8 twobyte_table[256] = { | |||
180 | /* 0x90 - 0x9F */ | 181 | /* 0x90 - 0x9F */ |
181 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 182 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
182 | /* 0xA0 - 0xA7 */ | 183 | /* 0xA0 - 0xA7 */ |
183 | 0, 0, 0, DstMem | SrcReg | ModRM, 0, 0, 0, 0, | 184 | 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, |
184 | /* 0xA8 - 0xAF */ | 185 | /* 0xA8 - 0xAF */ |
185 | 0, 0, 0, DstMem | SrcReg | ModRM, 0, 0, 0, 0, | 186 | 0, 0, 0, DstMem | SrcReg | ModRM | BitOp, 0, 0, 0, 0, |
186 | /* 0xB0 - 0xB7 */ | 187 | /* 0xB0 - 0xB7 */ |
187 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, | 188 | ByteOp | DstMem | SrcReg | ModRM, DstMem | SrcReg | ModRM, 0, |
188 | DstMem | SrcReg | ModRM, | 189 | DstMem | SrcReg | ModRM | BitOp, |
189 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, | 190 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, |
190 | DstReg | SrcMem16 | ModRM | Mov, | 191 | DstReg | SrcMem16 | ModRM | Mov, |
191 | /* 0xB8 - 0xBF */ | 192 | /* 0xB8 - 0xBF */ |
192 | 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM, | 193 | 0, 0, DstMem | SrcImmByte | ModRM, DstMem | SrcReg | ModRM | BitOp, |
193 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, | 194 | 0, 0, ByteOp | DstReg | SrcMem | ModRM | Mov, |
194 | DstReg | SrcMem16 | ModRM | Mov, | 195 | DstReg | SrcMem16 | ModRM | Mov, |
195 | /* 0xC0 - 0xCF */ | 196 | /* 0xC0 - 0xCF */ |
@@ -469,7 +470,8 @@ static int read_descriptor(struct x86_emulate_ctxt *ctxt, | |||
469 | int | 470 | int |
470 | x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) | 471 | x86_emulate_memop(struct x86_emulate_ctxt *ctxt, struct x86_emulate_ops *ops) |
471 | { | 472 | { |
472 | u8 b, d, sib, twobyte = 0, rex_prefix = 0; | 473 | unsigned d; |
474 | u8 b, sib, twobyte = 0, rex_prefix = 0; | ||
473 | u8 modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; | 475 | u8 modrm, modrm_mod = 0, modrm_reg = 0, modrm_rm = 0; |
474 | unsigned long *override_base = NULL; | 476 | unsigned long *override_base = NULL; |
475 | unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; | 477 | unsigned int op_bytes, ad_bytes, lock_prefix = 0, rep_prefix = 0, i; |
@@ -726,46 +728,6 @@ done_prefixes: | |||
726 | ; | 728 | ; |
727 | } | 729 | } |
728 | 730 | ||
729 | /* Decode and fetch the destination operand: register or memory. */ | ||
730 | switch (d & DstMask) { | ||
731 | case ImplicitOps: | ||
732 | /* Special instructions do their own operand decoding. */ | ||
733 | goto special_insn; | ||
734 | case DstReg: | ||
735 | dst.type = OP_REG; | ||
736 | if ((d & ByteOp) | ||
737 | && !(twobyte_table && (b == 0xb6 || b == 0xb7))) { | ||
738 | dst.ptr = decode_register(modrm_reg, _regs, | ||
739 | (rex_prefix == 0)); | ||
740 | dst.val = *(u8 *) dst.ptr; | ||
741 | dst.bytes = 1; | ||
742 | } else { | ||
743 | dst.ptr = decode_register(modrm_reg, _regs, 0); | ||
744 | switch ((dst.bytes = op_bytes)) { | ||
745 | case 2: | ||
746 | dst.val = *(u16 *)dst.ptr; | ||
747 | break; | ||
748 | case 4: | ||
749 | dst.val = *(u32 *)dst.ptr; | ||
750 | break; | ||
751 | case 8: | ||
752 | dst.val = *(u64 *)dst.ptr; | ||
753 | break; | ||
754 | } | ||
755 | } | ||
756 | break; | ||
757 | case DstMem: | ||
758 | dst.type = OP_MEM; | ||
759 | dst.ptr = (unsigned long *)cr2; | ||
760 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; | ||
761 | if (!(d & Mov) && /* optimisation - avoid slow emulated read */ | ||
762 | ((rc = ops->read_emulated((unsigned long)dst.ptr, | ||
763 | &dst.val, dst.bytes, ctxt)) != 0)) | ||
764 | goto done; | ||
765 | break; | ||
766 | } | ||
767 | dst.orig_val = dst.val; | ||
768 | |||
769 | /* | 731 | /* |
770 | * Decode and fetch the source operand: register, memory | 732 | * Decode and fetch the source operand: register, memory |
771 | * or immediate. | 733 | * or immediate. |
@@ -838,6 +800,50 @@ done_prefixes: | |||
838 | break; | 800 | break; |
839 | } | 801 | } |
840 | 802 | ||
803 | /* Decode and fetch the destination operand: register or memory. */ | ||
804 | switch (d & DstMask) { | ||
805 | case ImplicitOps: | ||
806 | /* Special instructions do their own operand decoding. */ | ||
807 | goto special_insn; | ||
808 | case DstReg: | ||
809 | dst.type = OP_REG; | ||
810 | if ((d & ByteOp) | ||
811 | && !(twobyte_table && (b == 0xb6 || b == 0xb7))) { | ||
812 | dst.ptr = decode_register(modrm_reg, _regs, | ||
813 | (rex_prefix == 0)); | ||
814 | dst.val = *(u8 *) dst.ptr; | ||
815 | dst.bytes = 1; | ||
816 | } else { | ||
817 | dst.ptr = decode_register(modrm_reg, _regs, 0); | ||
818 | switch ((dst.bytes = op_bytes)) { | ||
819 | case 2: | ||
820 | dst.val = *(u16 *)dst.ptr; | ||
821 | break; | ||
822 | case 4: | ||
823 | dst.val = *(u32 *)dst.ptr; | ||
824 | break; | ||
825 | case 8: | ||
826 | dst.val = *(u64 *)dst.ptr; | ||
827 | break; | ||
828 | } | ||
829 | } | ||
830 | break; | ||
831 | case DstMem: | ||
832 | dst.type = OP_MEM; | ||
833 | dst.ptr = (unsigned long *)cr2; | ||
834 | dst.bytes = (d & ByteOp) ? 1 : op_bytes; | ||
835 | if (d & BitOp) { | ||
836 | dst.ptr += src.val / BITS_PER_LONG; | ||
837 | dst.bytes = sizeof(long); | ||
838 | } | ||
839 | if (!(d & Mov) && /* optimisation - avoid slow emulated read */ | ||
840 | ((rc = ops->read_emulated((unsigned long)dst.ptr, | ||
841 | &dst.val, dst.bytes, ctxt)) != 0)) | ||
842 | goto done; | ||
843 | break; | ||
844 | } | ||
845 | dst.orig_val = dst.val; | ||
846 | |||
841 | if (twobyte) | 847 | if (twobyte) |
842 | goto twobyte_insn; | 848 | goto twobyte_insn; |
843 | 849 | ||