aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/kvm
diff options
context:
space:
mode:
authorAvi Kivity <avi@qumranet.com>2006-12-29 19:49:48 -0500
committerLinus Torvalds <torvalds@woody.osdl.org>2006-12-30 13:56:44 -0500
commit3bab1f5dda3443043cc8fe68c5ae75530339f28f (patch)
treed1b675e8f5328094c1a3d651da5e7563ad692252 /drivers/kvm
parent671d6564796e0c90398aab30f89b5e48fc5a3fbe (diff)
[PATCH] KVM: Move common msr handling to arch independent code
Signed-off-by: Avi Kivity <avi@qumranet.com> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/kvm')
-rw-r--r--drivers/kvm/kvm.h5
-rw-r--r--drivers/kvm/kvm_main.c71
-rw-r--r--drivers/kvm/svm.c47
-rw-r--r--drivers/kvm/vmx.c59
4 files changed, 84 insertions, 98 deletions
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index c2db4218d6cc..2670219a9264 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -374,9 +374,8 @@ void set_cr4(struct kvm_vcpu *vcpu, unsigned long cr0);
374void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0); 374void set_cr8(struct kvm_vcpu *vcpu, unsigned long cr0);
375void lmsw(struct kvm_vcpu *vcpu, unsigned long msw); 375void lmsw(struct kvm_vcpu *vcpu, unsigned long msw);
376 376
377#ifdef CONFIG_X86_64 377int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata);
378void set_efer(struct kvm_vcpu *vcpu, u64 efer); 378int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data);
379#endif
380 379
381void fx_init(struct kvm_vcpu *vcpu); 380void fx_init(struct kvm_vcpu *vcpu);
382 381
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 06314071c6d2..567121d9142a 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1103,6 +1103,47 @@ void realmode_set_cr(struct kvm_vcpu *vcpu, int cr, unsigned long val,
1103 } 1103 }
1104} 1104}
1105 1105
1106int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
1107{
1108 u64 data;
1109
1110 switch (msr) {
1111 case 0xc0010010: /* SYSCFG */
1112 case 0xc0010015: /* HWCR */
1113 case MSR_IA32_PLATFORM_ID:
1114 case MSR_IA32_P5_MC_ADDR:
1115 case MSR_IA32_P5_MC_TYPE:
1116 case MSR_IA32_MC0_CTL:
1117 case MSR_IA32_MCG_STATUS:
1118 case MSR_IA32_MCG_CAP:
1119 case MSR_IA32_MC0_MISC:
1120 case MSR_IA32_MC0_MISC+4:
1121 case MSR_IA32_MC0_MISC+8:
1122 case MSR_IA32_MC0_MISC+12:
1123 case MSR_IA32_MC0_MISC+16:
1124 case MSR_IA32_UCODE_REV:
1125 /* MTRR registers */
1126 case 0xfe:
1127 case 0x200 ... 0x2ff:
1128 data = 0;
1129 break;
1130 case MSR_IA32_APICBASE:
1131 data = vcpu->apic_base;
1132 break;
1133#ifdef CONFIG_X86_64
1134 case MSR_EFER:
1135 data = vcpu->shadow_efer;
1136 break;
1137#endif
1138 default:
1139 printk(KERN_ERR "kvm: unhandled rdmsr: 0x%x\n", msr);
1140 return 1;
1141 }
1142 *pdata = data;
1143 return 0;
1144}
1145EXPORT_SYMBOL_GPL(kvm_get_msr_common);
1146
1106/* 1147/*
1107 * Reads an msr value (of 'msr_index') into 'pdata'. 1148 * Reads an msr value (of 'msr_index') into 'pdata'.
1108 * Returns 0 on success, non-0 otherwise. 1149 * Returns 0 on success, non-0 otherwise.
@@ -1115,7 +1156,7 @@ static int get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
1115 1156
1116#ifdef CONFIG_X86_64 1157#ifdef CONFIG_X86_64
1117 1158
1118void set_efer(struct kvm_vcpu *vcpu, u64 efer) 1159static void set_efer(struct kvm_vcpu *vcpu, u64 efer)
1119{ 1160{
1120 if (efer & EFER_RESERVED_BITS) { 1161 if (efer & EFER_RESERVED_BITS) {
1121 printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n", 1162 printk(KERN_DEBUG "set_efer: 0x%llx #GP, reserved bits\n",
@@ -1138,10 +1179,36 @@ void set_efer(struct kvm_vcpu *vcpu, u64 efer)
1138 1179
1139 vcpu->shadow_efer = efer; 1180 vcpu->shadow_efer = efer;
1140} 1181}
1141EXPORT_SYMBOL_GPL(set_efer);
1142 1182
1143#endif 1183#endif
1144 1184
1185int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
1186{
1187 switch (msr) {
1188#ifdef CONFIG_X86_64
1189 case MSR_EFER:
1190 set_efer(vcpu, data);
1191 break;
1192#endif
1193 case MSR_IA32_MC0_STATUS:
1194 printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n",
1195 __FUNCTION__, data);
1196 break;
1197 case MSR_IA32_UCODE_REV:
1198 case MSR_IA32_UCODE_WRITE:
1199 case 0x200 ... 0x2ff: /* MTRRs */
1200 break;
1201 case MSR_IA32_APICBASE:
1202 vcpu->apic_base = data;
1203 break;
1204 default:
1205 printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr);
1206 return 1;
1207 }
1208 return 0;
1209}
1210EXPORT_SYMBOL_GPL(kvm_set_msr_common);
1211
1145/* 1212/*
1146 * Writes msr value into into the appropriate "register". 1213 * Writes msr value into into the appropriate "register".
1147 * Returns 0 on success, non-0 otherwise. 1214 * Returns 0 on success, non-0 otherwise.
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 6cd97c69ab3b..fa0428735717 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1068,25 +1068,6 @@ static int emulate_on_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_ru
1068static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data) 1068static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
1069{ 1069{
1070 switch (ecx) { 1070 switch (ecx) {
1071 case 0xc0010010: /* SYSCFG */
1072 case 0xc0010015: /* HWCR */
1073 case MSR_IA32_PLATFORM_ID:
1074 case MSR_IA32_P5_MC_ADDR:
1075 case MSR_IA32_P5_MC_TYPE:
1076 case MSR_IA32_MC0_CTL:
1077 case MSR_IA32_MCG_STATUS:
1078 case MSR_IA32_MCG_CAP:
1079 case MSR_IA32_MC0_MISC:
1080 case MSR_IA32_MC0_MISC+4:
1081 case MSR_IA32_MC0_MISC+8:
1082 case MSR_IA32_MC0_MISC+12:
1083 case MSR_IA32_MC0_MISC+16:
1084 case MSR_IA32_UCODE_REV:
1085 /* MTRR registers */
1086 case 0xfe:
1087 case 0x200 ... 0x2ff:
1088 *data = 0;
1089 break;
1090 case MSR_IA32_TIME_STAMP_COUNTER: { 1071 case MSR_IA32_TIME_STAMP_COUNTER: {
1091 u64 tsc; 1072 u64 tsc;
1092 1073
@@ -1094,12 +1075,6 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
1094 *data = vcpu->svm->vmcb->control.tsc_offset + tsc; 1075 *data = vcpu->svm->vmcb->control.tsc_offset + tsc;
1095 break; 1076 break;
1096 } 1077 }
1097 case MSR_EFER:
1098 *data = vcpu->shadow_efer;
1099 break;
1100 case MSR_IA32_APICBASE:
1101 *data = vcpu->apic_base;
1102 break;
1103 case MSR_K6_STAR: 1078 case MSR_K6_STAR:
1104 *data = vcpu->svm->vmcb->save.star; 1079 *data = vcpu->svm->vmcb->save.star;
1105 break; 1080 break;
@@ -1127,8 +1102,7 @@ static int svm_get_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 *data)
1127 *data = vcpu->svm->vmcb->save.sysenter_esp; 1102 *data = vcpu->svm->vmcb->save.sysenter_esp;
1128 break; 1103 break;
1129 default: 1104 default:
1130 printk(KERN_ERR "kvm: unhandled rdmsr: 0x%x\n", ecx); 1105 return kvm_get_msr_common(vcpu, ecx, data);
1131 return 1;
1132 } 1106 }
1133 return 0; 1107 return 0;
1134} 1108}
@@ -1152,15 +1126,6 @@ static int rdmsr_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
1152static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) 1126static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
1153{ 1127{
1154 switch (ecx) { 1128 switch (ecx) {
1155#ifdef CONFIG_X86_64
1156 case MSR_EFER:
1157 set_efer(vcpu, data);
1158 break;
1159#endif
1160 case MSR_IA32_MC0_STATUS:
1161 printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n"
1162 , __FUNCTION__, data);
1163 break;
1164 case MSR_IA32_TIME_STAMP_COUNTER: { 1129 case MSR_IA32_TIME_STAMP_COUNTER: {
1165 u64 tsc; 1130 u64 tsc;
1166 1131
@@ -1168,13 +1133,6 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
1168 vcpu->svm->vmcb->control.tsc_offset = data - tsc; 1133 vcpu->svm->vmcb->control.tsc_offset = data - tsc;
1169 break; 1134 break;
1170 } 1135 }
1171 case MSR_IA32_UCODE_REV:
1172 case MSR_IA32_UCODE_WRITE:
1173 case 0x200 ... 0x2ff: /* MTRRs */
1174 break;
1175 case MSR_IA32_APICBASE:
1176 vcpu->apic_base = data;
1177 break;
1178 case MSR_K6_STAR: 1136 case MSR_K6_STAR:
1179 vcpu->svm->vmcb->save.star = data; 1137 vcpu->svm->vmcb->save.star = data;
1180 break; 1138 break;
@@ -1202,8 +1160,7 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
1202 vcpu->svm->vmcb->save.sysenter_esp = data; 1160 vcpu->svm->vmcb->save.sysenter_esp = data;
1203 break; 1161 break;
1204 default: 1162 default:
1205 printk(KERN_ERR "kvm: unhandled wrmsr: %x\n", ecx); 1163 return kvm_set_msr_common(vcpu, ecx, data);
1206 return 1;
1207 } 1164 }
1208 return 0; 1165 return 0;
1209} 1166}
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index e5358a8b01f1..5561c5936c3d 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -344,8 +344,7 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
344 data = vmcs_readl(GUEST_GS_BASE); 344 data = vmcs_readl(GUEST_GS_BASE);
345 break; 345 break;
346 case MSR_EFER: 346 case MSR_EFER:
347 data = vcpu->shadow_efer; 347 return kvm_get_msr_common(vcpu, msr_index, pdata);
348 break;
349#endif 348#endif
350 case MSR_IA32_TIME_STAMP_COUNTER: 349 case MSR_IA32_TIME_STAMP_COUNTER:
351 data = guest_read_tsc(); 350 data = guest_read_tsc();
@@ -359,36 +358,13 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
359 case MSR_IA32_SYSENTER_ESP: 358 case MSR_IA32_SYSENTER_ESP:
360 data = vmcs_read32(GUEST_SYSENTER_ESP); 359 data = vmcs_read32(GUEST_SYSENTER_ESP);
361 break; 360 break;
362 case 0xc0010010: /* SYSCFG */
363 case 0xc0010015: /* HWCR */
364 case MSR_IA32_PLATFORM_ID:
365 case MSR_IA32_P5_MC_ADDR:
366 case MSR_IA32_P5_MC_TYPE:
367 case MSR_IA32_MC0_CTL:
368 case MSR_IA32_MCG_STATUS:
369 case MSR_IA32_MCG_CAP:
370 case MSR_IA32_MC0_MISC:
371 case MSR_IA32_MC0_MISC+4:
372 case MSR_IA32_MC0_MISC+8:
373 case MSR_IA32_MC0_MISC+12:
374 case MSR_IA32_MC0_MISC+16:
375 case MSR_IA32_UCODE_REV:
376 /* MTRR registers */
377 case 0xfe:
378 case 0x200 ... 0x2ff:
379 data = 0;
380 break;
381 case MSR_IA32_APICBASE:
382 data = vcpu->apic_base;
383 break;
384 default: 361 default:
385 msr = find_msr_entry(vcpu, msr_index); 362 msr = find_msr_entry(vcpu, msr_index);
386 if (!msr) { 363 if (msr) {
387 printk(KERN_ERR "kvm: unhandled rdmsr: %x\n", msr_index); 364 data = msr->data;
388 return 1; 365 break;
389 } 366 }
390 data = msr->data; 367 return kvm_get_msr_common(vcpu, msr_index, pdata);
391 break;
392 } 368 }
393 369
394 *pdata = data; 370 *pdata = data;
@@ -405,6 +381,8 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
405 struct vmx_msr_entry *msr; 381 struct vmx_msr_entry *msr;
406 switch (msr_index) { 382 switch (msr_index) {
407#ifdef CONFIG_X86_64 383#ifdef CONFIG_X86_64
384 case MSR_EFER:
385 return kvm_set_msr_common(vcpu, msr_index, data);
408 case MSR_FS_BASE: 386 case MSR_FS_BASE:
409 vmcs_writel(GUEST_FS_BASE, data); 387 vmcs_writel(GUEST_FS_BASE, data);
410 break; 388 break;
@@ -421,32 +399,17 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
421 case MSR_IA32_SYSENTER_ESP: 399 case MSR_IA32_SYSENTER_ESP:
422 vmcs_write32(GUEST_SYSENTER_ESP, data); 400 vmcs_write32(GUEST_SYSENTER_ESP, data);
423 break; 401 break;
424#ifdef __x86_64
425 case MSR_EFER:
426 set_efer(vcpu, data);
427 break;
428 case MSR_IA32_MC0_STATUS:
429 printk(KERN_WARNING "%s: MSR_IA32_MC0_STATUS 0x%llx, nop\n"
430 , __FUNCTION__, data);
431 break;
432#endif
433 case MSR_IA32_TIME_STAMP_COUNTER: { 402 case MSR_IA32_TIME_STAMP_COUNTER: {
434 guest_write_tsc(data); 403 guest_write_tsc(data);
435 break; 404 break;
436 } 405 }
437 case MSR_IA32_UCODE_REV:
438 case MSR_IA32_UCODE_WRITE:
439 case 0x200 ... 0x2ff: /* MTRRs */
440 break;
441 case MSR_IA32_APICBASE:
442 vcpu->apic_base = data;
443 break;
444 default: 406 default:
445 msr = find_msr_entry(vcpu, msr_index); 407 msr = find_msr_entry(vcpu, msr_index);
446 if (!msr) { 408 if (msr) {
447 printk(KERN_ERR "kvm: unhandled wrmsr: 0x%x\n", msr_index); 409 msr->data = data;
448 return 1; 410 break;
449 } 411 }
412 return kvm_set_msr_common(vcpu, msr_index, data);
450 msr->data = data; 413 msr->data = data;
451 break; 414 break;
452 } 415 }