diff options
Diffstat (limited to 'arch/x86/kvm/svm.c')
-rw-r--r-- | arch/x86/kvm/svm.c | 237 |
1 files changed, 139 insertions, 98 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 1d9b33843c80..52f78dd03010 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -231,7 +231,7 @@ static void svm_set_efer(struct kvm_vcpu *vcpu, u64 efer) | |||
231 | efer &= ~EFER_LME; | 231 | efer &= ~EFER_LME; |
232 | 232 | ||
233 | to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME; | 233 | to_svm(vcpu)->vmcb->save.efer = efer | EFER_SVME; |
234 | vcpu->arch.shadow_efer = efer; | 234 | vcpu->arch.efer = efer; |
235 | } | 235 | } |
236 | 236 | ||
237 | static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, | 237 | static void svm_queue_exception(struct kvm_vcpu *vcpu, unsigned nr, |
@@ -540,6 +540,8 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
540 | struct vmcb_control_area *control = &svm->vmcb->control; | 540 | struct vmcb_control_area *control = &svm->vmcb->control; |
541 | struct vmcb_save_area *save = &svm->vmcb->save; | 541 | struct vmcb_save_area *save = &svm->vmcb->save; |
542 | 542 | ||
543 | svm->vcpu.fpu_active = 1; | ||
544 | |||
543 | control->intercept_cr_read = INTERCEPT_CR0_MASK | | 545 | control->intercept_cr_read = INTERCEPT_CR0_MASK | |
544 | INTERCEPT_CR3_MASK | | 546 | INTERCEPT_CR3_MASK | |
545 | INTERCEPT_CR4_MASK; | 547 | INTERCEPT_CR4_MASK; |
@@ -552,13 +554,19 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
552 | control->intercept_dr_read = INTERCEPT_DR0_MASK | | 554 | control->intercept_dr_read = INTERCEPT_DR0_MASK | |
553 | INTERCEPT_DR1_MASK | | 555 | INTERCEPT_DR1_MASK | |
554 | INTERCEPT_DR2_MASK | | 556 | INTERCEPT_DR2_MASK | |
555 | INTERCEPT_DR3_MASK; | 557 | INTERCEPT_DR3_MASK | |
558 | INTERCEPT_DR4_MASK | | ||
559 | INTERCEPT_DR5_MASK | | ||
560 | INTERCEPT_DR6_MASK | | ||
561 | INTERCEPT_DR7_MASK; | ||
556 | 562 | ||
557 | control->intercept_dr_write = INTERCEPT_DR0_MASK | | 563 | control->intercept_dr_write = INTERCEPT_DR0_MASK | |
558 | INTERCEPT_DR1_MASK | | 564 | INTERCEPT_DR1_MASK | |
559 | INTERCEPT_DR2_MASK | | 565 | INTERCEPT_DR2_MASK | |
560 | INTERCEPT_DR3_MASK | | 566 | INTERCEPT_DR3_MASK | |
567 | INTERCEPT_DR4_MASK | | ||
561 | INTERCEPT_DR5_MASK | | 568 | INTERCEPT_DR5_MASK | |
569 | INTERCEPT_DR6_MASK | | ||
562 | INTERCEPT_DR7_MASK; | 570 | INTERCEPT_DR7_MASK; |
563 | 571 | ||
564 | control->intercept_exceptions = (1 << PF_VECTOR) | | 572 | control->intercept_exceptions = (1 << PF_VECTOR) | |
@@ -569,6 +577,7 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
569 | control->intercept = (1ULL << INTERCEPT_INTR) | | 577 | control->intercept = (1ULL << INTERCEPT_INTR) | |
570 | (1ULL << INTERCEPT_NMI) | | 578 | (1ULL << INTERCEPT_NMI) | |
571 | (1ULL << INTERCEPT_SMI) | | 579 | (1ULL << INTERCEPT_SMI) | |
580 | (1ULL << INTERCEPT_SELECTIVE_CR0) | | ||
572 | (1ULL << INTERCEPT_CPUID) | | 581 | (1ULL << INTERCEPT_CPUID) | |
573 | (1ULL << INTERCEPT_INVD) | | 582 | (1ULL << INTERCEPT_INVD) | |
574 | (1ULL << INTERCEPT_HLT) | | 583 | (1ULL << INTERCEPT_HLT) | |
@@ -641,10 +650,8 @@ static void init_vmcb(struct vcpu_svm *svm) | |||
641 | control->intercept &= ~((1ULL << INTERCEPT_TASK_SWITCH) | | 650 | control->intercept &= ~((1ULL << INTERCEPT_TASK_SWITCH) | |
642 | (1ULL << INTERCEPT_INVLPG)); | 651 | (1ULL << INTERCEPT_INVLPG)); |
643 | control->intercept_exceptions &= ~(1 << PF_VECTOR); | 652 | control->intercept_exceptions &= ~(1 << PF_VECTOR); |
644 | control->intercept_cr_read &= ~(INTERCEPT_CR0_MASK| | 653 | control->intercept_cr_read &= ~INTERCEPT_CR3_MASK; |
645 | INTERCEPT_CR3_MASK); | 654 | control->intercept_cr_write &= ~INTERCEPT_CR3_MASK; |
646 | control->intercept_cr_write &= ~(INTERCEPT_CR0_MASK| | ||
647 | INTERCEPT_CR3_MASK); | ||
648 | save->g_pat = 0x0007040600070406ULL; | 655 | save->g_pat = 0x0007040600070406ULL; |
649 | save->cr3 = 0; | 656 | save->cr3 = 0; |
650 | save->cr4 = 0; | 657 | save->cr4 = 0; |
@@ -730,7 +737,6 @@ static struct kvm_vcpu *svm_create_vcpu(struct kvm *kvm, unsigned int id) | |||
730 | init_vmcb(svm); | 737 | init_vmcb(svm); |
731 | 738 | ||
732 | fx_init(&svm->vcpu); | 739 | fx_init(&svm->vcpu); |
733 | svm->vcpu.fpu_active = 1; | ||
734 | svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; | 740 | svm->vcpu.arch.apic_base = 0xfee00000 | MSR_IA32_APICBASE_ENABLE; |
735 | if (kvm_vcpu_is_bsp(&svm->vcpu)) | 741 | if (kvm_vcpu_is_bsp(&svm->vcpu)) |
736 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; | 742 | svm->vcpu.arch.apic_base |= MSR_IA32_APICBASE_BSP; |
@@ -765,14 +771,16 @@ static void svm_vcpu_load(struct kvm_vcpu *vcpu, int cpu) | |||
765 | if (unlikely(cpu != vcpu->cpu)) { | 771 | if (unlikely(cpu != vcpu->cpu)) { |
766 | u64 delta; | 772 | u64 delta; |
767 | 773 | ||
768 | /* | 774 | if (check_tsc_unstable()) { |
769 | * Make sure that the guest sees a monotonically | 775 | /* |
770 | * increasing TSC. | 776 | * Make sure that the guest sees a monotonically |
771 | */ | 777 | * increasing TSC. |
772 | delta = vcpu->arch.host_tsc - native_read_tsc(); | 778 | */ |
773 | svm->vmcb->control.tsc_offset += delta; | 779 | delta = vcpu->arch.host_tsc - native_read_tsc(); |
774 | if (is_nested(svm)) | 780 | svm->vmcb->control.tsc_offset += delta; |
775 | svm->nested.hsave->control.tsc_offset += delta; | 781 | if (is_nested(svm)) |
782 | svm->nested.hsave->control.tsc_offset += delta; | ||
783 | } | ||
776 | vcpu->cpu = cpu; | 784 | vcpu->cpu = cpu; |
777 | kvm_migrate_timers(vcpu); | 785 | kvm_migrate_timers(vcpu); |
778 | svm->asid_generation = 0; | 786 | svm->asid_generation = 0; |
@@ -954,42 +962,59 @@ static void svm_set_gdt(struct kvm_vcpu *vcpu, struct descriptor_table *dt) | |||
954 | svm->vmcb->save.gdtr.base = dt->base ; | 962 | svm->vmcb->save.gdtr.base = dt->base ; |
955 | } | 963 | } |
956 | 964 | ||
965 | static void svm_decache_cr0_guest_bits(struct kvm_vcpu *vcpu) | ||
966 | { | ||
967 | } | ||
968 | |||
957 | static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) | 969 | static void svm_decache_cr4_guest_bits(struct kvm_vcpu *vcpu) |
958 | { | 970 | { |
959 | } | 971 | } |
960 | 972 | ||
973 | static void update_cr0_intercept(struct vcpu_svm *svm) | ||
974 | { | ||
975 | ulong gcr0 = svm->vcpu.arch.cr0; | ||
976 | u64 *hcr0 = &svm->vmcb->save.cr0; | ||
977 | |||
978 | if (!svm->vcpu.fpu_active) | ||
979 | *hcr0 |= SVM_CR0_SELECTIVE_MASK; | ||
980 | else | ||
981 | *hcr0 = (*hcr0 & ~SVM_CR0_SELECTIVE_MASK) | ||
982 | | (gcr0 & SVM_CR0_SELECTIVE_MASK); | ||
983 | |||
984 | |||
985 | if (gcr0 == *hcr0 && svm->vcpu.fpu_active) { | ||
986 | svm->vmcb->control.intercept_cr_read &= ~INTERCEPT_CR0_MASK; | ||
987 | svm->vmcb->control.intercept_cr_write &= ~INTERCEPT_CR0_MASK; | ||
988 | } else { | ||
989 | svm->vmcb->control.intercept_cr_read |= INTERCEPT_CR0_MASK; | ||
990 | svm->vmcb->control.intercept_cr_write |= INTERCEPT_CR0_MASK; | ||
991 | } | ||
992 | } | ||
993 | |||
961 | static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) | 994 | static void svm_set_cr0(struct kvm_vcpu *vcpu, unsigned long cr0) |
962 | { | 995 | { |
963 | struct vcpu_svm *svm = to_svm(vcpu); | 996 | struct vcpu_svm *svm = to_svm(vcpu); |
964 | 997 | ||
965 | #ifdef CONFIG_X86_64 | 998 | #ifdef CONFIG_X86_64 |
966 | if (vcpu->arch.shadow_efer & EFER_LME) { | 999 | if (vcpu->arch.efer & EFER_LME) { |
967 | if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { | 1000 | if (!is_paging(vcpu) && (cr0 & X86_CR0_PG)) { |
968 | vcpu->arch.shadow_efer |= EFER_LMA; | 1001 | vcpu->arch.efer |= EFER_LMA; |
969 | svm->vmcb->save.efer |= EFER_LMA | EFER_LME; | 1002 | svm->vmcb->save.efer |= EFER_LMA | EFER_LME; |
970 | } | 1003 | } |
971 | 1004 | ||
972 | if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) { | 1005 | if (is_paging(vcpu) && !(cr0 & X86_CR0_PG)) { |
973 | vcpu->arch.shadow_efer &= ~EFER_LMA; | 1006 | vcpu->arch.efer &= ~EFER_LMA; |
974 | svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); | 1007 | svm->vmcb->save.efer &= ~(EFER_LMA | EFER_LME); |
975 | } | 1008 | } |
976 | } | 1009 | } |
977 | #endif | 1010 | #endif |
978 | if (npt_enabled) | 1011 | vcpu->arch.cr0 = cr0; |
979 | goto set; | ||
980 | 1012 | ||
981 | if ((vcpu->arch.cr0 & X86_CR0_TS) && !(cr0 & X86_CR0_TS)) { | 1013 | if (!npt_enabled) |
982 | svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); | 1014 | cr0 |= X86_CR0_PG | X86_CR0_WP; |
983 | vcpu->fpu_active = 1; | ||
984 | } | ||
985 | 1015 | ||
986 | vcpu->arch.cr0 = cr0; | 1016 | if (!vcpu->fpu_active) |
987 | cr0 |= X86_CR0_PG | X86_CR0_WP; | ||
988 | if (!vcpu->fpu_active) { | ||
989 | svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR); | ||
990 | cr0 |= X86_CR0_TS; | 1017 | cr0 |= X86_CR0_TS; |
991 | } | ||
992 | set: | ||
993 | /* | 1018 | /* |
994 | * re-enable caching here because the QEMU bios | 1019 | * re-enable caching here because the QEMU bios |
995 | * does not do it - this results in some delay at | 1020 | * does not do it - this results in some delay at |
@@ -997,6 +1022,7 @@ set: | |||
997 | */ | 1022 | */ |
998 | cr0 &= ~(X86_CR0_CD | X86_CR0_NW); | 1023 | cr0 &= ~(X86_CR0_CD | X86_CR0_NW); |
999 | svm->vmcb->save.cr0 = cr0; | 1024 | svm->vmcb->save.cr0 = cr0; |
1025 | update_cr0_intercept(svm); | ||
1000 | } | 1026 | } |
1001 | 1027 | ||
1002 | static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) | 1028 | static void svm_set_cr4(struct kvm_vcpu *vcpu, unsigned long cr4) |
@@ -1102,76 +1128,70 @@ static void new_asid(struct vcpu_svm *svm, struct svm_cpu_data *sd) | |||
1102 | svm->vmcb->control.asid = sd->next_asid++; | 1128 | svm->vmcb->control.asid = sd->next_asid++; |
1103 | } | 1129 | } |
1104 | 1130 | ||
1105 | static unsigned long svm_get_dr(struct kvm_vcpu *vcpu, int dr) | 1131 | static int svm_get_dr(struct kvm_vcpu *vcpu, int dr, unsigned long *dest) |
1106 | { | 1132 | { |
1107 | struct vcpu_svm *svm = to_svm(vcpu); | 1133 | struct vcpu_svm *svm = to_svm(vcpu); |
1108 | unsigned long val; | ||
1109 | 1134 | ||
1110 | switch (dr) { | 1135 | switch (dr) { |
1111 | case 0 ... 3: | 1136 | case 0 ... 3: |
1112 | val = vcpu->arch.db[dr]; | 1137 | *dest = vcpu->arch.db[dr]; |
1113 | break; | 1138 | break; |
1139 | case 4: | ||
1140 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
1141 | return EMULATE_FAIL; /* will re-inject UD */ | ||
1142 | /* fall through */ | ||
1114 | case 6: | 1143 | case 6: |
1115 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) | 1144 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) |
1116 | val = vcpu->arch.dr6; | 1145 | *dest = vcpu->arch.dr6; |
1117 | else | 1146 | else |
1118 | val = svm->vmcb->save.dr6; | 1147 | *dest = svm->vmcb->save.dr6; |
1119 | break; | 1148 | break; |
1149 | case 5: | ||
1150 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
1151 | return EMULATE_FAIL; /* will re-inject UD */ | ||
1152 | /* fall through */ | ||
1120 | case 7: | 1153 | case 7: |
1121 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) | 1154 | if (vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP) |
1122 | val = vcpu->arch.dr7; | 1155 | *dest = vcpu->arch.dr7; |
1123 | else | 1156 | else |
1124 | val = svm->vmcb->save.dr7; | 1157 | *dest = svm->vmcb->save.dr7; |
1125 | break; | 1158 | break; |
1126 | default: | ||
1127 | val = 0; | ||
1128 | } | 1159 | } |
1129 | 1160 | ||
1130 | return val; | 1161 | return EMULATE_DONE; |
1131 | } | 1162 | } |
1132 | 1163 | ||
1133 | static void svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value, | 1164 | static int svm_set_dr(struct kvm_vcpu *vcpu, int dr, unsigned long value) |
1134 | int *exception) | ||
1135 | { | 1165 | { |
1136 | struct vcpu_svm *svm = to_svm(vcpu); | 1166 | struct vcpu_svm *svm = to_svm(vcpu); |
1137 | 1167 | ||
1138 | *exception = 0; | ||
1139 | |||
1140 | switch (dr) { | 1168 | switch (dr) { |
1141 | case 0 ... 3: | 1169 | case 0 ... 3: |
1142 | vcpu->arch.db[dr] = value; | 1170 | vcpu->arch.db[dr] = value; |
1143 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) | 1171 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) |
1144 | vcpu->arch.eff_db[dr] = value; | 1172 | vcpu->arch.eff_db[dr] = value; |
1145 | return; | 1173 | break; |
1146 | case 4 ... 5: | 1174 | case 4: |
1147 | if (vcpu->arch.cr4 & X86_CR4_DE) | 1175 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) |
1148 | *exception = UD_VECTOR; | 1176 | return EMULATE_FAIL; /* will re-inject UD */ |
1149 | return; | 1177 | /* fall through */ |
1150 | case 6: | 1178 | case 6: |
1151 | if (value & 0xffffffff00000000ULL) { | ||
1152 | *exception = GP_VECTOR; | ||
1153 | return; | ||
1154 | } | ||
1155 | vcpu->arch.dr6 = (value & DR6_VOLATILE) | DR6_FIXED_1; | 1179 | vcpu->arch.dr6 = (value & DR6_VOLATILE) | DR6_FIXED_1; |
1156 | return; | 1180 | break; |
1181 | case 5: | ||
1182 | if (kvm_read_cr4_bits(vcpu, X86_CR4_DE)) | ||
1183 | return EMULATE_FAIL; /* will re-inject UD */ | ||
1184 | /* fall through */ | ||
1157 | case 7: | 1185 | case 7: |
1158 | if (value & 0xffffffff00000000ULL) { | ||
1159 | *exception = GP_VECTOR; | ||
1160 | return; | ||
1161 | } | ||
1162 | vcpu->arch.dr7 = (value & DR7_VOLATILE) | DR7_FIXED_1; | 1186 | vcpu->arch.dr7 = (value & DR7_VOLATILE) | DR7_FIXED_1; |
1163 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { | 1187 | if (!(vcpu->guest_debug & KVM_GUESTDBG_USE_HW_BP)) { |
1164 | svm->vmcb->save.dr7 = vcpu->arch.dr7; | 1188 | svm->vmcb->save.dr7 = vcpu->arch.dr7; |
1165 | vcpu->arch.switch_db_regs = (value & DR7_BP_EN_MASK); | 1189 | vcpu->arch.switch_db_regs = (value & DR7_BP_EN_MASK); |
1166 | } | 1190 | } |
1167 | return; | 1191 | break; |
1168 | default: | ||
1169 | /* FIXME: Possible case? */ | ||
1170 | printk(KERN_DEBUG "%s: unexpected dr %u\n", | ||
1171 | __func__, dr); | ||
1172 | *exception = UD_VECTOR; | ||
1173 | return; | ||
1174 | } | 1192 | } |
1193 | |||
1194 | return EMULATE_DONE; | ||
1175 | } | 1195 | } |
1176 | 1196 | ||
1177 | static int pf_interception(struct vcpu_svm *svm) | 1197 | static int pf_interception(struct vcpu_svm *svm) |
@@ -1239,13 +1259,17 @@ static int ud_interception(struct vcpu_svm *svm) | |||
1239 | return 1; | 1259 | return 1; |
1240 | } | 1260 | } |
1241 | 1261 | ||
1242 | static int nm_interception(struct vcpu_svm *svm) | 1262 | static void svm_fpu_activate(struct kvm_vcpu *vcpu) |
1243 | { | 1263 | { |
1264 | struct vcpu_svm *svm = to_svm(vcpu); | ||
1244 | svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); | 1265 | svm->vmcb->control.intercept_exceptions &= ~(1 << NM_VECTOR); |
1245 | if (!(svm->vcpu.arch.cr0 & X86_CR0_TS)) | ||
1246 | svm->vmcb->save.cr0 &= ~X86_CR0_TS; | ||
1247 | svm->vcpu.fpu_active = 1; | 1266 | svm->vcpu.fpu_active = 1; |
1267 | update_cr0_intercept(svm); | ||
1268 | } | ||
1248 | 1269 | ||
1270 | static int nm_interception(struct vcpu_svm *svm) | ||
1271 | { | ||
1272 | svm_fpu_activate(&svm->vcpu); | ||
1249 | return 1; | 1273 | return 1; |
1250 | } | 1274 | } |
1251 | 1275 | ||
@@ -1337,7 +1361,7 @@ static int vmmcall_interception(struct vcpu_svm *svm) | |||
1337 | 1361 | ||
1338 | static int nested_svm_check_permissions(struct vcpu_svm *svm) | 1362 | static int nested_svm_check_permissions(struct vcpu_svm *svm) |
1339 | { | 1363 | { |
1340 | if (!(svm->vcpu.arch.shadow_efer & EFER_SVME) | 1364 | if (!(svm->vcpu.arch.efer & EFER_SVME) |
1341 | || !is_paging(&svm->vcpu)) { | 1365 | || !is_paging(&svm->vcpu)) { |
1342 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); | 1366 | kvm_queue_exception(&svm->vcpu, UD_VECTOR); |
1343 | return 1; | 1367 | return 1; |
@@ -1740,8 +1764,8 @@ static bool nested_svm_vmrun(struct vcpu_svm *svm) | |||
1740 | hsave->save.ds = vmcb->save.ds; | 1764 | hsave->save.ds = vmcb->save.ds; |
1741 | hsave->save.gdtr = vmcb->save.gdtr; | 1765 | hsave->save.gdtr = vmcb->save.gdtr; |
1742 | hsave->save.idtr = vmcb->save.idtr; | 1766 | hsave->save.idtr = vmcb->save.idtr; |
1743 | hsave->save.efer = svm->vcpu.arch.shadow_efer; | 1767 | hsave->save.efer = svm->vcpu.arch.efer; |
1744 | hsave->save.cr0 = svm->vcpu.arch.cr0; | 1768 | hsave->save.cr0 = kvm_read_cr0(&svm->vcpu); |
1745 | hsave->save.cr4 = svm->vcpu.arch.cr4; | 1769 | hsave->save.cr4 = svm->vcpu.arch.cr4; |
1746 | hsave->save.rflags = vmcb->save.rflags; | 1770 | hsave->save.rflags = vmcb->save.rflags; |
1747 | hsave->save.rip = svm->next_rip; | 1771 | hsave->save.rip = svm->next_rip; |
@@ -2153,9 +2177,10 @@ static int rdmsr_interception(struct vcpu_svm *svm) | |||
2153 | u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; | 2177 | u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; |
2154 | u64 data; | 2178 | u64 data; |
2155 | 2179 | ||
2156 | if (svm_get_msr(&svm->vcpu, ecx, &data)) | 2180 | if (svm_get_msr(&svm->vcpu, ecx, &data)) { |
2181 | trace_kvm_msr_read_ex(ecx); | ||
2157 | kvm_inject_gp(&svm->vcpu, 0); | 2182 | kvm_inject_gp(&svm->vcpu, 0); |
2158 | else { | 2183 | } else { |
2159 | trace_kvm_msr_read(ecx, data); | 2184 | trace_kvm_msr_read(ecx, data); |
2160 | 2185 | ||
2161 | svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; | 2186 | svm->vcpu.arch.regs[VCPU_REGS_RAX] = data & 0xffffffff; |
@@ -2247,13 +2272,15 @@ static int wrmsr_interception(struct vcpu_svm *svm) | |||
2247 | u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) | 2272 | u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) |
2248 | | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); | 2273 | | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); |
2249 | 2274 | ||
2250 | trace_kvm_msr_write(ecx, data); | ||
2251 | 2275 | ||
2252 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; | 2276 | svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; |
2253 | if (svm_set_msr(&svm->vcpu, ecx, data)) | 2277 | if (svm_set_msr(&svm->vcpu, ecx, data)) { |
2278 | trace_kvm_msr_write_ex(ecx, data); | ||
2254 | kvm_inject_gp(&svm->vcpu, 0); | 2279 | kvm_inject_gp(&svm->vcpu, 0); |
2255 | else | 2280 | } else { |
2281 | trace_kvm_msr_write(ecx, data); | ||
2256 | skip_emulated_instruction(&svm->vcpu); | 2282 | skip_emulated_instruction(&svm->vcpu); |
2283 | } | ||
2257 | return 1; | 2284 | return 1; |
2258 | } | 2285 | } |
2259 | 2286 | ||
@@ -2297,7 +2324,7 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { | |||
2297 | [SVM_EXIT_READ_CR3] = emulate_on_interception, | 2324 | [SVM_EXIT_READ_CR3] = emulate_on_interception, |
2298 | [SVM_EXIT_READ_CR4] = emulate_on_interception, | 2325 | [SVM_EXIT_READ_CR4] = emulate_on_interception, |
2299 | [SVM_EXIT_READ_CR8] = emulate_on_interception, | 2326 | [SVM_EXIT_READ_CR8] = emulate_on_interception, |
2300 | /* for now: */ | 2327 | [SVM_EXIT_CR0_SEL_WRITE] = emulate_on_interception, |
2301 | [SVM_EXIT_WRITE_CR0] = emulate_on_interception, | 2328 | [SVM_EXIT_WRITE_CR0] = emulate_on_interception, |
2302 | [SVM_EXIT_WRITE_CR3] = emulate_on_interception, | 2329 | [SVM_EXIT_WRITE_CR3] = emulate_on_interception, |
2303 | [SVM_EXIT_WRITE_CR4] = emulate_on_interception, | 2330 | [SVM_EXIT_WRITE_CR4] = emulate_on_interception, |
@@ -2306,11 +2333,17 @@ static int (*svm_exit_handlers[])(struct vcpu_svm *svm) = { | |||
2306 | [SVM_EXIT_READ_DR1] = emulate_on_interception, | 2333 | [SVM_EXIT_READ_DR1] = emulate_on_interception, |
2307 | [SVM_EXIT_READ_DR2] = emulate_on_interception, | 2334 | [SVM_EXIT_READ_DR2] = emulate_on_interception, |
2308 | [SVM_EXIT_READ_DR3] = emulate_on_interception, | 2335 | [SVM_EXIT_READ_DR3] = emulate_on_interception, |
2336 | [SVM_EXIT_READ_DR4] = emulate_on_interception, | ||
2337 | [SVM_EXIT_READ_DR5] = emulate_on_interception, | ||
2338 | [SVM_EXIT_READ_DR6] = emulate_on_interception, | ||
2339 | [SVM_EXIT_READ_DR7] = emulate_on_interception, | ||
2309 | [SVM_EXIT_WRITE_DR0] = emulate_on_interception, | 2340 | [SVM_EXIT_WRITE_DR0] = emulate_on_interception, |
2310 | [SVM_EXIT_WRITE_DR1] = emulate_on_interception, | 2341 | [SVM_EXIT_WRITE_DR1] = emulate_on_interception, |
2311 | [SVM_EXIT_WRITE_DR2] = emulate_on_interception, | 2342 | [SVM_EXIT_WRITE_DR2] = emulate_on_interception, |
2312 | [SVM_EXIT_WRITE_DR3] = emulate_on_interception, | 2343 | [SVM_EXIT_WRITE_DR3] = emulate_on_interception, |
2344 | [SVM_EXIT_WRITE_DR4] = emulate_on_interception, | ||
2313 | [SVM_EXIT_WRITE_DR5] = emulate_on_interception, | 2345 | [SVM_EXIT_WRITE_DR5] = emulate_on_interception, |
2346 | [SVM_EXIT_WRITE_DR6] = emulate_on_interception, | ||
2314 | [SVM_EXIT_WRITE_DR7] = emulate_on_interception, | 2347 | [SVM_EXIT_WRITE_DR7] = emulate_on_interception, |
2315 | [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception, | 2348 | [SVM_EXIT_EXCP_BASE + DB_VECTOR] = db_interception, |
2316 | [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception, | 2349 | [SVM_EXIT_EXCP_BASE + BP_VECTOR] = bp_interception, |
@@ -2383,20 +2416,10 @@ static int handle_exit(struct kvm_vcpu *vcpu) | |||
2383 | 2416 | ||
2384 | svm_complete_interrupts(svm); | 2417 | svm_complete_interrupts(svm); |
2385 | 2418 | ||
2386 | if (npt_enabled) { | 2419 | if (!(svm->vmcb->control.intercept_cr_write & INTERCEPT_CR0_MASK)) |
2387 | int mmu_reload = 0; | ||
2388 | if ((vcpu->arch.cr0 ^ svm->vmcb->save.cr0) & X86_CR0_PG) { | ||
2389 | svm_set_cr0(vcpu, svm->vmcb->save.cr0); | ||
2390 | mmu_reload = 1; | ||
2391 | } | ||
2392 | vcpu->arch.cr0 = svm->vmcb->save.cr0; | 2420 | vcpu->arch.cr0 = svm->vmcb->save.cr0; |
2421 | if (npt_enabled) | ||
2393 | vcpu->arch.cr3 = svm->vmcb->save.cr3; | 2422 | vcpu->arch.cr3 = svm->vmcb->save.cr3; |
2394 | if (mmu_reload) { | ||
2395 | kvm_mmu_reset_context(vcpu); | ||
2396 | kvm_mmu_load(vcpu); | ||
2397 | } | ||
2398 | } | ||
2399 | |||
2400 | 2423 | ||
2401 | if (svm->vmcb->control.exit_code == SVM_EXIT_ERR) { | 2424 | if (svm->vmcb->control.exit_code == SVM_EXIT_ERR) { |
2402 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; | 2425 | kvm_run->exit_reason = KVM_EXIT_FAIL_ENTRY; |
@@ -2798,12 +2821,6 @@ static void svm_set_cr3(struct kvm_vcpu *vcpu, unsigned long root) | |||
2798 | 2821 | ||
2799 | svm->vmcb->save.cr3 = root; | 2822 | svm->vmcb->save.cr3 = root; |
2800 | force_new_asid(vcpu); | 2823 | force_new_asid(vcpu); |
2801 | |||
2802 | if (vcpu->fpu_active) { | ||
2803 | svm->vmcb->control.intercept_exceptions |= (1 << NM_VECTOR); | ||
2804 | svm->vmcb->save.cr0 |= X86_CR0_TS; | ||
2805 | vcpu->fpu_active = 0; | ||
2806 | } | ||
2807 | } | 2824 | } |
2808 | 2825 | ||
2809 | static int is_disabled(void) | 2826 | static int is_disabled(void) |
@@ -2852,6 +2869,10 @@ static u64 svm_get_mt_mask(struct kvm_vcpu *vcpu, gfn_t gfn, bool is_mmio) | |||
2852 | return 0; | 2869 | return 0; |
2853 | } | 2870 | } |
2854 | 2871 | ||
2872 | static void svm_cpuid_update(struct kvm_vcpu *vcpu) | ||
2873 | { | ||
2874 | } | ||
2875 | |||
2855 | static const struct trace_print_flags svm_exit_reasons_str[] = { | 2876 | static const struct trace_print_flags svm_exit_reasons_str[] = { |
2856 | { SVM_EXIT_READ_CR0, "read_cr0" }, | 2877 | { SVM_EXIT_READ_CR0, "read_cr0" }, |
2857 | { SVM_EXIT_READ_CR3, "read_cr3" }, | 2878 | { SVM_EXIT_READ_CR3, "read_cr3" }, |
@@ -2905,9 +2926,22 @@ static const struct trace_print_flags svm_exit_reasons_str[] = { | |||
2905 | { -1, NULL } | 2926 | { -1, NULL } |
2906 | }; | 2927 | }; |
2907 | 2928 | ||
2908 | static bool svm_gb_page_enable(void) | 2929 | static int svm_get_lpage_level(void) |
2909 | { | 2930 | { |
2910 | return true; | 2931 | return PT_PDPE_LEVEL; |
2932 | } | ||
2933 | |||
2934 | static bool svm_rdtscp_supported(void) | ||
2935 | { | ||
2936 | return false; | ||
2937 | } | ||
2938 | |||
2939 | static void svm_fpu_deactivate(struct kvm_vcpu *vcpu) | ||
2940 | { | ||
2941 | struct vcpu_svm *svm = to_svm(vcpu); | ||
2942 | |||
2943 | update_cr0_intercept(svm); | ||
2944 | svm->vmcb->control.intercept_exceptions |= 1 << NM_VECTOR; | ||
2911 | } | 2945 | } |
2912 | 2946 | ||
2913 | static struct kvm_x86_ops svm_x86_ops = { | 2947 | static struct kvm_x86_ops svm_x86_ops = { |
@@ -2936,6 +2970,7 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
2936 | .set_segment = svm_set_segment, | 2970 | .set_segment = svm_set_segment, |
2937 | .get_cpl = svm_get_cpl, | 2971 | .get_cpl = svm_get_cpl, |
2938 | .get_cs_db_l_bits = kvm_get_cs_db_l_bits, | 2972 | .get_cs_db_l_bits = kvm_get_cs_db_l_bits, |
2973 | .decache_cr0_guest_bits = svm_decache_cr0_guest_bits, | ||
2939 | .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, | 2974 | .decache_cr4_guest_bits = svm_decache_cr4_guest_bits, |
2940 | .set_cr0 = svm_set_cr0, | 2975 | .set_cr0 = svm_set_cr0, |
2941 | .set_cr3 = svm_set_cr3, | 2976 | .set_cr3 = svm_set_cr3, |
@@ -2950,6 +2985,8 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
2950 | .cache_reg = svm_cache_reg, | 2985 | .cache_reg = svm_cache_reg, |
2951 | .get_rflags = svm_get_rflags, | 2986 | .get_rflags = svm_get_rflags, |
2952 | .set_rflags = svm_set_rflags, | 2987 | .set_rflags = svm_set_rflags, |
2988 | .fpu_activate = svm_fpu_activate, | ||
2989 | .fpu_deactivate = svm_fpu_deactivate, | ||
2953 | 2990 | ||
2954 | .tlb_flush = svm_flush_tlb, | 2991 | .tlb_flush = svm_flush_tlb, |
2955 | 2992 | ||
@@ -2975,7 +3012,11 @@ static struct kvm_x86_ops svm_x86_ops = { | |||
2975 | .get_mt_mask = svm_get_mt_mask, | 3012 | .get_mt_mask = svm_get_mt_mask, |
2976 | 3013 | ||
2977 | .exit_reasons_str = svm_exit_reasons_str, | 3014 | .exit_reasons_str = svm_exit_reasons_str, |
2978 | .gb_page_enable = svm_gb_page_enable, | 3015 | .get_lpage_level = svm_get_lpage_level, |
3016 | |||
3017 | .cpuid_update = svm_cpuid_update, | ||
3018 | |||
3019 | .rdtscp_supported = svm_rdtscp_supported, | ||
2979 | }; | 3020 | }; |
2980 | 3021 | ||
2981 | static int __init svm_init(void) | 3022 | static int __init svm_init(void) |