aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm/svm.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/kvm/svm.c')
-rw-r--r--drivers/kvm/svm.c197
1 files changed, 125 insertions, 72 deletions
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 3d8ea7ac2ecc..9c15f32eea18 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -44,6 +44,10 @@ MODULE_LICENSE("GPL");
44#define KVM_EFER_LMA (1 << 10) 44#define KVM_EFER_LMA (1 << 10)
45#define KVM_EFER_LME (1 << 8) 45#define KVM_EFER_LME (1 << 8)
46 46
47#define SVM_FEATURE_NPT (1 << 0)
48#define SVM_FEATURE_LBRV (1 << 1)
49#define SVM_DEATURE_SVML (1 << 2)
50
47unsigned long iopm_base; 51unsigned long iopm_base;
48unsigned long msrpm_base; 52unsigned long msrpm_base;
49 53
@@ -59,15 +63,16 @@ struct kvm_ldttss_desc {
59struct svm_cpu_data { 63struct svm_cpu_data {
60 int cpu; 64 int cpu;
61 65
62 uint64_t asid_generation; 66 u64 asid_generation;
63 uint32_t max_asid; 67 u32 max_asid;
64 uint32_t next_asid; 68 u32 next_asid;
65 struct kvm_ldttss_desc *tss_desc; 69 struct kvm_ldttss_desc *tss_desc;
66 70
67 struct page *save_area; 71 struct page *save_area;
68}; 72};
69 73
70static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data); 74static DEFINE_PER_CPU(struct svm_cpu_data *, svm_data);
75static uint32_t svm_features;
71 76
72struct svm_init_data { 77struct svm_init_data {
73 int cpu; 78 int cpu;
@@ -82,6 +87,11 @@ static u32 msrpm_ranges[] = {0, 0xc0000000, 0xc0010000};
82 87
83#define MAX_INST_SIZE 15 88#define MAX_INST_SIZE 15
84 89
90static inline u32 svm_has(u32 feat)
91{
92 return svm_features & feat;
93}
94
85static unsigned get_addr_size(struct kvm_vcpu *vcpu) 95static unsigned get_addr_size(struct kvm_vcpu *vcpu)
86{ 96{
87 struct vmcb_save_area *sa = &vcpu->svm->vmcb->save; 97 struct vmcb_save_area *sa = &vcpu->svm->vmcb->save;
@@ -203,13 +213,6 @@ static void inject_ud(struct kvm_vcpu *vcpu)
203 UD_VECTOR; 213 UD_VECTOR;
204} 214}
205 215
206static void inject_db(struct kvm_vcpu *vcpu)
207{
208 vcpu->svm->vmcb->control.event_inj = SVM_EVTINJ_VALID |
209 SVM_EVTINJ_TYPE_EXEPT |
210 DB_VECTOR;
211}
212
213static int is_page_fault(uint32_t info) 216static int is_page_fault(uint32_t info)
214{ 217{
215 info &= SVM_EVTINJ_VEC_MASK | SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID; 218 info &= SVM_EVTINJ_VEC_MASK | SVM_EVTINJ_TYPE_MASK | SVM_EVTINJ_VALID;
@@ -309,6 +312,7 @@ static void svm_hardware_enable(void *garbage)
309 svm_data->asid_generation = 1; 312 svm_data->asid_generation = 1;
310 svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1; 313 svm_data->max_asid = cpuid_ebx(SVM_CPUID_FUNC) - 1;
311 svm_data->next_asid = svm_data->max_asid + 1; 314 svm_data->next_asid = svm_data->max_asid + 1;
315 svm_features = cpuid_edx(SVM_CPUID_FUNC);
312 316
313 asm volatile ( "sgdt %0" : "=m"(gdt_descr) ); 317 asm volatile ( "sgdt %0" : "=m"(gdt_descr) );
314 gdt = (struct desc_struct *)gdt_descr.address; 318 gdt = (struct desc_struct *)gdt_descr.address;
@@ -459,7 +463,6 @@ static void init_vmcb(struct vmcb *vmcb)
459{ 463{
460 struct vmcb_control_area *control = &vmcb->control; 464 struct vmcb_control_area *control = &vmcb->control;
461 struct vmcb_save_area *save = &vmcb->save; 465 struct vmcb_save_area *save = &vmcb->save;
462 u64 tsc;
463 466
464 control->intercept_cr_read = INTERCEPT_CR0_MASK | 467 control->intercept_cr_read = INTERCEPT_CR0_MASK |
465 INTERCEPT_CR3_MASK | 468 INTERCEPT_CR3_MASK |
@@ -511,12 +514,13 @@ static void init_vmcb(struct vmcb *vmcb)
511 (1ULL << INTERCEPT_VMSAVE) | 514 (1ULL << INTERCEPT_VMSAVE) |
512 (1ULL << INTERCEPT_STGI) | 515 (1ULL << INTERCEPT_STGI) |
513 (1ULL << INTERCEPT_CLGI) | 516 (1ULL << INTERCEPT_CLGI) |
514 (1ULL << INTERCEPT_SKINIT); 517 (1ULL << INTERCEPT_SKINIT) |
518 (1ULL << INTERCEPT_MONITOR) |
519 (1ULL << INTERCEPT_MWAIT);
515 520
516 control->iopm_base_pa = iopm_base; 521 control->iopm_base_pa = iopm_base;
517 control->msrpm_base_pa = msrpm_base; 522 control->msrpm_base_pa = msrpm_base;
518 rdtscll(tsc); 523 control->tsc_offset = 0;
519 control->tsc_offset = -tsc;
520 control->int_ctl = V_INTR_MASKING_MASK; 524 control->int_ctl = V_INTR_MASKING_MASK;
521 525
522 init_seg(&save->es); 526 init_seg(&save->es);
@@ -576,12 +580,15 @@ static int svm_create_vcpu(struct kvm_vcpu *vcpu)
576 vcpu->svm->vmcb = page_address(page); 580 vcpu->svm->vmcb = page_address(page);
577 memset(vcpu->svm->vmcb, 0, PAGE_SIZE); 581 memset(vcpu->svm->vmcb, 0, PAGE_SIZE);
578 vcpu->svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT; 582 vcpu->svm->vmcb_pa = page_to_pfn(page) << PAGE_SHIFT;
579 vcpu->svm->cr0 = 0x00000010;
580 vcpu->svm->asid_generation = 0; 583 vcpu->svm->asid_generation = 0;
581 memset(vcpu->svm->db_regs, 0, sizeof(vcpu->svm->db_regs)); 584 memset(vcpu->svm->db_regs, 0, sizeof(vcpu->svm->db_regs));
582 init_vmcb(vcpu->svm->vmcb); 585 init_vmcb(vcpu->svm->vmcb);
583 586
584 fx_init(vcpu); 587 fx_init(vcpu);
588 vcpu->fpu_active = 1;
589 vcpu->apic_base = 0xfee00000 |
590 /*for vcpu 0*/ MSR_IA32_APICBASE_BSP |
591 MSR_IA32_APICBASE_ENABLE;
585 592
586 return 0; 593 return 0;
587 594
@@ -602,11 +609,34 @@ static void svm_free_vcpu(struct kvm_vcpu *vcpu)
602 609
603static void svm_vcpu_load(struct kvm_vcpu *vcpu) 610static void svm_vcpu_load(struct kvm_vcpu *vcpu)
604{ 611{
605 get_cpu(); 612 int cpu, i;
613
614 cpu = get_cpu();
615 if (unlikely(cpu != vcpu->cpu)) {
616 u64 tsc_this, delta;
617
618 /*
619 * Make sure that the guest sees a monotonically
620 * increasing TSC.
621 */
622 rdtscll(tsc_this);
623 delta = vcpu->host_tsc - tsc_this;
624 vcpu->svm->vmcb->control.tsc_offset += delta;
625 vcpu->cpu = cpu;
626 }
627
628 for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
629 rdmsrl(host_save_user_msrs[i], vcpu->svm->host_user_msrs[i]);
606} 630}
607 631
608static void svm_vcpu_put(struct kvm_vcpu *vcpu) 632static void svm_vcpu_put(struct kvm_vcpu *vcpu)
609{ 633{
634 int i;
635
636 for (i = 0; i < NR_HOST_SAVE_USER_MSRS; i++)
637 wrmsrl(host_save_user_msrs[i], vcpu->svm->host_user_msrs[i]);
638
639 rdtscll(vcpu->host_tsc);
610 put_cpu(); 640 put_cpu();
611} 641}
612 642
@@ -714,7 +744,7 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt)
714 vcpu->svm->vmcb->save.gdtr.base = dt->base ; 744 vcpu->svm->vmcb->save.gdtr.base = dt->base ;
715} 745}
716 746
717static void svm_decache_cr0_cr4_guest_bits(struct kvm_vcpu *vcpu) 747static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu)
718{ 748{
719} 749}
720 750
@@ -733,9 +763,15 @@ static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0)
733 } 763 }
734 } 764 }
735#endif 765#endif
736 vcpu->svm->cr0 = cr0; 766 if ((vcpu->cr0 & CR0_TS_MASK) && !(cr0 & CR0_TS_MASK)) {
737 vcpu->svm->vmcb->save.cr0 = cr0 | CR0_PG_MASK | CR0_WP_MASK; 767 vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
768 vcpu->fpu_active = 1;
769 }
770
738 vcpu->cr0 = cr0; 771 vcpu->cr0 = cr0;
772 cr0 |= CR0_PG_MASK | CR0_WP_MASK;
773 cr0 &= ~(CR0_CD_MASK | CR0_NW_MASK);
774 vcpu->svm->vmcb->save.cr0 = cr0;
739} 775}
740 776
741static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) 777static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4)
@@ -785,18 +821,16 @@ static int svm_guest_debug(struct kvm_vcpu *vcpu, struct kvm_debug_guest *dbg)
785 821
786static void load_host_msrs(struct kvm_vcpu *vcpu) 822static void load_host_msrs(struct kvm_vcpu *vcpu)
787{ 823{
788 int i; 824#ifdef CONFIG_X86_64
789 825 wrmsrl(MSR_GS_BASE, vcpu->svm->host_gs_base);
790 for ( i = 0; i < NR_HOST_SAVE_MSRS; i++) 826#endif
791 wrmsrl(host_save_msrs[i], vcpu->svm->host_msrs[i]);
792} 827}
793 828
794static void save_host_msrs(struct kvm_vcpu *vcpu) 829static void save_host_msrs(struct kvm_vcpu *vcpu)
795{ 830{
796 int i; 831#ifdef CONFIG_X86_64
797 832 rdmsrl(MSR_GS_BASE, vcpu->svm->host_gs_base);
798 for ( i = 0; i < NR_HOST_SAVE_MSRS; i++) 833#endif
799 rdmsrl(host_save_msrs[i], vcpu->svm->host_msrs[i]);
800} 834}
801 835
802static void new_asid(struct kvm_vcpu *vcpu, struct svm_cpu_data *svm_data) 836static void new_asid(struct kvm_vcpu *vcpu, struct svm_cpu_data *svm_data)
@@ -890,7 +924,7 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
890 case EMULATE_DONE: 924 case EMULATE_DONE:
891 return 1; 925 return 1;
892 case EMULATE_DO_MMIO: 926 case EMULATE_DO_MMIO:
893 ++kvm_stat.mmio_exits; 927 ++vcpu->stat.mmio_exits;
894 kvm_run->exit_reason = KVM_EXIT_MMIO; 928 kvm_run->exit_reason = KVM_EXIT_MMIO;
895 return 0; 929 return 0;
896 case EMULATE_FAIL: 930 case EMULATE_FAIL:
@@ -904,6 +938,16 @@ static int pf_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
904 return 0; 938 return 0;
905} 939}
906 940
941static int nm_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
942{
943 vcpu->svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR);
944 if (!(vcpu->cr0 & CR0_TS_MASK))
945 vcpu->svm->vmcb->save.cr0 &= ~CR0_TS_MASK;
946 vcpu->fpu_active = 1;
947
948 return 1;
949}
950
907static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 951static int shutdown_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
908{ 952{
909 /* 953 /*
@@ -981,7 +1025,7 @@ static int io_get_override(struct kvm_vcpu *vcpu,
981 return 0; 1025 return 0;
982} 1026}
983 1027
984static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, u64 *address) 1028static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, gva_t *address)
985{ 1029{
986 unsigned long addr_mask; 1030 unsigned long addr_mask;
987 unsigned long *reg; 1031 unsigned long *reg;
@@ -1025,38 +1069,38 @@ static unsigned long io_adress(struct kvm_vcpu *vcpu, int ins, u64 *address)
1025static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1069static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1026{ 1070{
1027 u32 io_info = vcpu->svm->vmcb->control.exit_info_1; //address size bug? 1071 u32 io_info = vcpu->svm->vmcb->control.exit_info_1; //address size bug?
1028 int _in = io_info & SVM_IOIO_TYPE_MASK; 1072 int size, down, in, string, rep;
1073 unsigned port;
1074 unsigned long count;
1075 gva_t address = 0;
1029 1076
1030 ++kvm_stat.io_exits; 1077 ++vcpu->stat.io_exits;
1031 1078
1032 vcpu->svm->next_rip = vcpu->svm->vmcb->control.exit_info_2; 1079 vcpu->svm->next_rip = vcpu->svm->vmcb->control.exit_info_2;
1033 1080
1034 kvm_run->exit_reason = KVM_EXIT_IO; 1081 in = (io_info & SVM_IOIO_TYPE_MASK) != 0;
1035 kvm_run->io.port = io_info >> 16; 1082 port = io_info >> 16;
1036 kvm_run->io.direction = (_in) ? KVM_EXIT_IO_IN : KVM_EXIT_IO_OUT; 1083 size = (io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT;
1037 kvm_run->io.size = ((io_info & SVM_IOIO_SIZE_MASK) >> SVM_IOIO_SIZE_SHIFT); 1084 string = (io_info & SVM_IOIO_STR_MASK) != 0;
1038 kvm_run->io.string = (io_info & SVM_IOIO_STR_MASK) != 0; 1085 rep = (io_info & SVM_IOIO_REP_MASK) != 0;
1039 kvm_run->io.rep = (io_info & SVM_IOIO_REP_MASK) != 0; 1086 count = 1;
1087 down = (vcpu->svm->vmcb->save.rflags & X86_EFLAGS_DF) != 0;
1040 1088
1041 if (kvm_run->io.string) { 1089 if (string) {
1042 unsigned addr_mask; 1090 unsigned addr_mask;
1043 1091
1044 addr_mask = io_adress(vcpu, _in, &kvm_run->io.address); 1092 addr_mask = io_adress(vcpu, in, &address);
1045 if (!addr_mask) { 1093 if (!addr_mask) {
1046 printk(KERN_DEBUG "%s: get io address failed\n", 1094 printk(KERN_DEBUG "%s: get io address failed\n",
1047 __FUNCTION__); 1095 __FUNCTION__);
1048 return 1; 1096 return 1;
1049 } 1097 }
1050 1098
1051 if (kvm_run->io.rep) { 1099 if (rep)
1052 kvm_run->io.count 1100 count = vcpu->regs[VCPU_REGS_RCX] & addr_mask;
1053 = vcpu->regs[VCPU_REGS_RCX] & addr_mask; 1101 }
1054 kvm_run->io.string_down = (vcpu->svm->vmcb->save.rflags 1102 return kvm_setup_pio(vcpu, kvm_run, in, size, count, string, down,
1055 & X86_EFLAGS_DF) != 0; 1103 address, rep, port);
1056 }
1057 } else
1058 kvm_run->io.value = vcpu->svm->vmcb->save.rax;
1059 return 0;
1060} 1104}
1061 1105
1062static int nop_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1106static int nop_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -1072,13 +1116,14 @@ static int halt_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1072 return 1; 1116 return 1;
1073 1117
1074 kvm_run->exit_reason = KVM_EXIT_HLT; 1118 kvm_run->exit_reason = KVM_EXIT_HLT;
1075 ++kvm_stat.halt_exits; 1119 ++vcpu->stat.halt_exits;
1076 return 0; 1120 return 0;
1077} 1121}
1078 1122
1079static int vmmcall_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1123static int vmmcall_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1080{ 1124{
1081 vcpu->svm->vmcb->save.rip += 3; 1125 vcpu->svm->next_rip = vcpu->svm->vmcb->save.rip + 3;
1126 skip_emulated_instruction(vcpu);
1082 return kvm_hypercall(vcpu, kvm_run); 1127 return kvm_hypercall(vcpu, kvm_run);
1083} 1128}
1084 1129
@@ -1098,8 +1143,8 @@ static int task_switch_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_r
1098static int cpuid_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1143static int cpuid_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1099{ 1144{
1100 vcpu->svm->next_rip = vcpu->svm->vmcb->save.rip + 2; 1145 vcpu->svm->next_rip = vcpu->svm->vmcb->save.rip + 2;
1101 kvm_run->exit_reason = KVM_EXIT_CPUID; 1146 kvm_emulate_cpuid(vcpu);
1102 return 0; 1147 return 1;
1103} 1148}
1104 1149
1105static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run) 1150static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
@@ -1239,7 +1284,7 @@ static int interrupt_window_interception(struct kvm_vcpu *vcpu,
1239 */ 1284 */
1240 if (kvm_run->request_interrupt_window && 1285 if (kvm_run->request_interrupt_window &&
1241 !vcpu->irq_summary) { 1286 !vcpu->irq_summary) {
1242 ++kvm_stat.irq_window_exits; 1287 ++vcpu->stat.irq_window_exits;
1243 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN; 1288 kvm_run->exit_reason = KVM_EXIT_IRQ_WINDOW_OPEN;
1244 return 0; 1289 return 0;
1245 } 1290 }
@@ -1267,6 +1312,7 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu,
1267 [SVM_EXIT_WRITE_DR5] = emulate_on_interception, 1312 [SVM_EXIT_WRITE_DR5] = emulate_on_interception,
1268 [SVM_EXIT_WRITE_DR7] = emulate_on_interception, 1313 [SVM_EXIT_WRITE_DR7] = emulate_on_interception,
1269 [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception, 1314 [SVM_EXIT_EXCP_BASE + PF_VECTOR] = pf_interception,
1315 [SVM_EXIT_EXCP_BASE + NM_VECTOR] = nm_interception,
1270 [SVM_EXIT_INTR] = nop_on_interception, 1316 [SVM_EXIT_INTR] = nop_on_interception,
1271 [SVM_EXIT_NMI] = nop_on_interception, 1317 [SVM_EXIT_NMI] = nop_on_interception,
1272 [SVM_EXIT_SMI] = nop_on_interception, 1318 [SVM_EXIT_SMI] = nop_on_interception,
@@ -1288,6 +1334,8 @@ static int (*svm_exit_handlers[])(struct kvm_vcpu *vcpu,
1288 [SVM_EXIT_STGI] = invalid_op_interception, 1334 [SVM_EXIT_STGI] = invalid_op_interception,
1289 [SVM_EXIT_CLGI] = invalid_op_interception, 1335 [SVM_EXIT_CLGI] = invalid_op_interception,
1290 [SVM_EXIT_SKINIT] = invalid_op_interception, 1336 [SVM_EXIT_SKINIT] = invalid_op_interception,
1337 [SVM_EXIT_MONITOR] = invalid_op_interception,
1338 [SVM_EXIT_MWAIT] = invalid_op_interception,
1291}; 1339};
1292 1340
1293 1341
@@ -1295,8 +1343,6 @@ static int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1295{ 1343{
1296 u32 exit_code = vcpu->svm->vmcb->control.exit_code; 1344 u32 exit_code = vcpu->svm->vmcb->control.exit_code;
1297 1345
1298 kvm_run->exit_type = KVM_EXIT_TYPE_VM_EXIT;
1299
1300 if (is_external_interrupt(vcpu->svm->vmcb->control.exit_int_info) && 1346 if (is_external_interrupt(vcpu->svm->vmcb->control.exit_int_info) &&
1301 exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR) 1347 exit_code != SVM_EXIT_EXCP_BASE + PF_VECTOR)
1302 printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x " 1348 printk(KERN_ERR "%s: unexpected exit_ini_info 0x%x "
@@ -1307,12 +1353,7 @@ static int handle_exit(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1307 if (exit_code >= ARRAY_SIZE(svm_exit_handlers) 1353 if (exit_code >= ARRAY_SIZE(svm_exit_handlers)
1308 || svm_exit_handlers[exit_code] == 0) { 1354 || svm_exit_handlers[exit_code] == 0) {
1309 kvm_run->exit_reason = KVM_EXIT_UNKNOWN; 1355 kvm_run->exit_reason = KVM_EXIT_UNKNOWN;
1310 printk(KERN_ERR "%s: 0x%x @ 0x%llx cr0 0x%lx rflags 0x%llx\n", 1356 kvm_run->hw.hardware_exit_reason = exit_code;
1311 __FUNCTION__,
1312 exit_code,
1313 vcpu->svm->vmcb->save.rip,
1314 vcpu->cr0,
1315 vcpu->svm->vmcb->save.rflags);
1316 return 0; 1357 return 0;
1317 } 1358 }
1318 1359
@@ -1461,8 +1502,10 @@ again:
1461 load_db_regs(vcpu->svm->db_regs); 1502 load_db_regs(vcpu->svm->db_regs);
1462 } 1503 }
1463 1504
1464 fx_save(vcpu->host_fx_image); 1505 if (vcpu->fpu_active) {
1465 fx_restore(vcpu->guest_fx_image); 1506 fx_save(vcpu->host_fx_image);
1507 fx_restore(vcpu->guest_fx_image);
1508 }
1466 1509
1467 asm volatile ( 1510 asm volatile (
1468#ifdef CONFIG_X86_64 1511#ifdef CONFIG_X86_64
@@ -1573,8 +1616,10 @@ again:
1573#endif 1616#endif
1574 : "cc", "memory" ); 1617 : "cc", "memory" );
1575 1618
1576 fx_save(vcpu->guest_fx_image); 1619 if (vcpu->fpu_active) {
1577 fx_restore(vcpu->host_fx_image); 1620 fx_save(vcpu->guest_fx_image);
1621 fx_restore(vcpu->host_fx_image);
1622 }
1578 1623
1579 if ((vcpu->svm->vmcb->save.dr7 & 0xff)) 1624 if ((vcpu->svm->vmcb->save.dr7 & 0xff))
1580 load_db_regs(vcpu->svm->host_db_regs); 1625 load_db_regs(vcpu->svm->host_db_regs);
@@ -1606,8 +1651,9 @@ again:
1606 vcpu->svm->next_rip = 0; 1651 vcpu->svm->next_rip = 0;
1607 1652
1608 if (vcpu->svm->vmcb->control.exit_code == SVM_EXIT_ERR) { 1653 if (vcpu->svm->vmcb->control.exit_code == SVM_EXIT_ERR) {
1609 kvm_run->exit_type = KVM_EXIT_TYPE_FAIL_ENTRY; 1654 kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY;
1610 kvm_run->exit_reason = vcpu->svm->vmcb->control.exit_code; 1655 kvm_run->fail_entry.hardware_entry_failure_reason
1656 = vcpu->svm->vmcb->control.exit_code;
1611 post_kvm_run_save(vcpu, kvm_run); 1657 post_kvm_run_save(vcpu, kvm_run);
1612 return 0; 1658 return 0;
1613 } 1659 }
@@ -1615,14 +1661,16 @@ again:
1615 r = handle_exit(vcpu, kvm_run); 1661 r = handle_exit(vcpu, kvm_run);
1616 if (r > 0) { 1662 if (r > 0) {
1617 if (signal_pending(current)) { 1663 if (signal_pending(current)) {
1618 ++kvm_stat.signal_exits; 1664 ++vcpu->stat.signal_exits;
1619 post_kvm_run_save(vcpu, kvm_run); 1665 post_kvm_run_save(vcpu, kvm_run);
1666 kvm_run->exit_reason = KVM_EXIT_INTR;
1620 return -EINTR; 1667 return -EINTR;
1621 } 1668 }
1622 1669
1623 if (dm_request_for_irq_injection(vcpu, kvm_run)) { 1670 if (dm_request_for_irq_injection(vcpu, kvm_run)) {
1624 ++kvm_stat.request_irq_exits; 1671 ++vcpu->stat.request_irq_exits;
1625 post_kvm_run_save(vcpu, kvm_run); 1672 post_kvm_run_save(vcpu, kvm_run);
1673 kvm_run->exit_reason = KVM_EXIT_INTR;
1626 return -EINTR; 1674 return -EINTR;
1627 } 1675 }
1628 kvm_resched(vcpu); 1676 kvm_resched(vcpu);
@@ -1641,6 +1689,12 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root)
1641{ 1689{
1642 vcpu->svm->vmcb->save.cr3 = root; 1690 vcpu->svm->vmcb->save.cr3 = root;
1643 force_new_asid(vcpu); 1691 force_new_asid(vcpu);
1692
1693 if (vcpu->fpu_active) {
1694 vcpu->svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR);
1695 vcpu->svm->vmcb->save.cr0 |= CR0_TS_MASK;
1696 vcpu->fpu_active = 0;
1697 }
1644} 1698}
1645 1699
1646static void svm_inject_page_fault(struct kvm_vcpu *vcpu, 1700static void svm_inject_page_fault(struct kvm_vcpu *vcpu,
@@ -1649,7 +1703,7 @@ static void svm_inject_page_fault(struct kvm_vcpu *vcpu,
1649{ 1703{
1650 uint32_t exit_int_info = vcpu->svm->vmcb->control.exit_int_info; 1704 uint32_t exit_int_info = vcpu->svm->vmcb->control.exit_int_info;
1651 1705
1652 ++kvm_stat.pf_guest; 1706 ++vcpu->stat.pf_guest;
1653 1707
1654 if (is_page_fault(exit_int_info)) { 1708 if (is_page_fault(exit_int_info)) {
1655 1709
@@ -1709,9 +1763,8 @@ static struct kvm_arch_ops svm_arch_ops = {
1709 .get_segment = svm_get_segment, 1763 .get_segment = svm_get_segment,
1710 .set_segment = svm_set_segment, 1764 .set_segment = svm_set_segment,
1711 .get_cs_db_l_bits = svm_get_cs_db_l_bits, 1765 .get_cs_db_l_bits = svm_get_cs_db_l_bits,
1712 .decache_cr0_cr4_guest_bits = svm_decache_cr0_cr4_guest_bits, 1766 .decache_cr4_guest_bits = svm_decache_cr4_guest_bits,
1713 .set_cr0 = svm_set_cr0, 1767 .set_cr0 = svm_set_cr0,
1714 .set_cr0_no_modeswitch = svm_set_cr0,
1715 .set_cr3 = svm_set_cr3, 1768 .set_cr3 = svm_set_cr3,
1716 .set_cr4 = svm_set_cr4, 1769 .set_cr4 = svm_set_cr4,
1717 .set_efer = svm_set_efer, 1770 .set_efer = svm_set_efer,