aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kvm
diff options
context:
space:
mode:
authorWill Auld <will.auld.intel@gmail.com>2012-11-29 15:42:12 -0500
committerMarcelo Tosatti <mtosatti@redhat.com>2012-11-30 15:26:12 -0500
commit8fe8ab46be06fcd9abfe6fe9928fd95b54ab079a (patch)
tree38c355d8451076da9259f45db598763f91aaf941 /arch/x86/kvm
parent5419369ed6bd4cf711fdda5e52a5999b940413f5 (diff)
KVM: x86: Add code to track call origin for msr assignment
In order to track who initiated the call (host or guest) to modify an msr value I have changed function call parameters along the call path. The specific change is to add a struct pointer parameter that points to (index, data, caller) information rather than having this information passed as individual parameters. The initial use for this capability is for updating the IA32_TSC_ADJUST msr while setting the tsc value. It is anticipated that this capability is useful for other tasks. Signed-off-by: Will Auld <will.auld@intel.com> Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch/x86/kvm')
-rw-r--r--arch/x86/kvm/svm.c14
-rw-r--r--arch/x86/kvm/vmx.c18
-rw-r--r--arch/x86/kvm/x86.c31
-rw-r--r--arch/x86/kvm/x86.h2
4 files changed, 47 insertions, 18 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 161a5fa66d82..fc22e58d23b7 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -3127,13 +3127,15 @@ static int svm_set_vm_cr(struct kvm_vcpu *vcpu, u64 data)
3127 return 0; 3127 return 0;
3128} 3128}
3129 3129
3130static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data) 3130static int svm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
3131{ 3131{
3132 struct vcpu_svm *svm = to_svm(vcpu); 3132 struct vcpu_svm *svm = to_svm(vcpu);
3133 3133
3134 u32 ecx = msr->index;
3135 u64 data = msr->data;
3134 switch (ecx) { 3136 switch (ecx) {
3135 case MSR_IA32_TSC: 3137 case MSR_IA32_TSC:
3136 kvm_write_tsc(vcpu, data); 3138 kvm_write_tsc(vcpu, msr);
3137 break; 3139 break;
3138 case MSR_STAR: 3140 case MSR_STAR:
3139 svm->vmcb->save.star = data; 3141 svm->vmcb->save.star = data;
@@ -3188,20 +3190,24 @@ static int svm_set_msr(struct kvm_vcpu *vcpu, unsigned ecx, u64 data)
3188 vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data); 3190 vcpu_unimpl(vcpu, "unimplemented wrmsr: 0x%x data 0x%llx\n", ecx, data);
3189 break; 3191 break;
3190 default: 3192 default:
3191 return kvm_set_msr_common(vcpu, ecx, data); 3193 return kvm_set_msr_common(vcpu, msr);
3192 } 3194 }
3193 return 0; 3195 return 0;
3194} 3196}
3195 3197
3196static int wrmsr_interception(struct vcpu_svm *svm) 3198static int wrmsr_interception(struct vcpu_svm *svm)
3197{ 3199{
3200 struct msr_data msr;
3198 u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX]; 3201 u32 ecx = svm->vcpu.arch.regs[VCPU_REGS_RCX];
3199 u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u) 3202 u64 data = (svm->vcpu.arch.regs[VCPU_REGS_RAX] & -1u)
3200 | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32); 3203 | ((u64)(svm->vcpu.arch.regs[VCPU_REGS_RDX] & -1u) << 32);
3201 3204
3205 msr.data = data;
3206 msr.index = ecx;
3207 msr.host_initiated = false;
3202 3208
3203 svm->next_rip = kvm_rip_read(&svm->vcpu) + 2; 3209 svm->next_rip = kvm_rip_read(&svm->vcpu) + 2;
3204 if (svm_set_msr(&svm->vcpu, ecx, data)) { 3210 if (svm_set_msr(&svm->vcpu, &msr)) {
3205 trace_kvm_msr_write_ex(ecx, data); 3211 trace_kvm_msr_write_ex(ecx, data);
3206 kvm_inject_gp(&svm->vcpu, 0); 3212 kvm_inject_gp(&svm->vcpu, 0);
3207 } else { 3213 } else {
diff --git a/arch/x86/kvm/vmx.c b/arch/x86/kvm/vmx.c
index 3606154bbc8b..45ffa32352f1 100644
--- a/arch/x86/kvm/vmx.c
+++ b/arch/x86/kvm/vmx.c
@@ -2220,15 +2220,17 @@ static int vmx_get_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata)
2220 * Returns 0 on success, non-0 otherwise. 2220 * Returns 0 on success, non-0 otherwise.
2221 * Assumes vcpu_load() was already called. 2221 * Assumes vcpu_load() was already called.
2222 */ 2222 */
2223static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) 2223static int vmx_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
2224{ 2224{
2225 struct vcpu_vmx *vmx = to_vmx(vcpu); 2225 struct vcpu_vmx *vmx = to_vmx(vcpu);
2226 struct shared_msr_entry *msr; 2226 struct shared_msr_entry *msr;
2227 int ret = 0; 2227 int ret = 0;
2228 u32 msr_index = msr_info->index;
2229 u64 data = msr_info->data;
2228 2230
2229 switch (msr_index) { 2231 switch (msr_index) {
2230 case MSR_EFER: 2232 case MSR_EFER:
2231 ret = kvm_set_msr_common(vcpu, msr_index, data); 2233 ret = kvm_set_msr_common(vcpu, msr_info);
2232 break; 2234 break;
2233#ifdef CONFIG_X86_64 2235#ifdef CONFIG_X86_64
2234 case MSR_FS_BASE: 2236 case MSR_FS_BASE:
@@ -2254,7 +2256,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
2254 vmcs_writel(GUEST_SYSENTER_ESP, data); 2256 vmcs_writel(GUEST_SYSENTER_ESP, data);
2255 break; 2257 break;
2256 case MSR_IA32_TSC: 2258 case MSR_IA32_TSC:
2257 kvm_write_tsc(vcpu, data); 2259 kvm_write_tsc(vcpu, msr_info);
2258 break; 2260 break;
2259 case MSR_IA32_CR_PAT: 2261 case MSR_IA32_CR_PAT:
2260 if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) { 2262 if (vmcs_config.vmentry_ctrl & VM_ENTRY_LOAD_IA32_PAT) {
@@ -2262,7 +2264,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
2262 vcpu->arch.pat = data; 2264 vcpu->arch.pat = data;
2263 break; 2265 break;
2264 } 2266 }
2265 ret = kvm_set_msr_common(vcpu, msr_index, data); 2267 ret = kvm_set_msr_common(vcpu, msr_info);
2266 break; 2268 break;
2267 case MSR_TSC_AUX: 2269 case MSR_TSC_AUX:
2268 if (!vmx->rdtscp_enabled) 2270 if (!vmx->rdtscp_enabled)
@@ -2285,7 +2287,7 @@ static int vmx_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
2285 } 2287 }
2286 break; 2288 break;
2287 } 2289 }
2288 ret = kvm_set_msr_common(vcpu, msr_index, data); 2290 ret = kvm_set_msr_common(vcpu, msr_info);
2289 } 2291 }
2290 2292
2291 return ret; 2293 return ret;
@@ -4648,11 +4650,15 @@ static int handle_rdmsr(struct kvm_vcpu *vcpu)
4648 4650
4649static int handle_wrmsr(struct kvm_vcpu *vcpu) 4651static int handle_wrmsr(struct kvm_vcpu *vcpu)
4650{ 4652{
4653 struct msr_data msr;
4651 u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX]; 4654 u32 ecx = vcpu->arch.regs[VCPU_REGS_RCX];
4652 u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u) 4655 u64 data = (vcpu->arch.regs[VCPU_REGS_RAX] & -1u)
4653 | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32); 4656 | ((u64)(vcpu->arch.regs[VCPU_REGS_RDX] & -1u) << 32);
4654 4657
4655 if (vmx_set_msr(vcpu, ecx, data) != 0) { 4658 msr.data = data;
4659 msr.index = ecx;
4660 msr.host_initiated = false;
4661 if (vmx_set_msr(vcpu, &msr) != 0) {
4656 trace_kvm_msr_write_ex(ecx, data); 4662 trace_kvm_msr_write_ex(ecx, data);
4657 kvm_inject_gp(vcpu, 0); 4663 kvm_inject_gp(vcpu, 0);
4658 return 1; 4664 return 1;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index fd766214d9da..95f66136f2d5 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -890,9 +890,9 @@ EXPORT_SYMBOL_GPL(kvm_enable_efer_bits);
890 * Returns 0 on success, non-0 otherwise. 890 * Returns 0 on success, non-0 otherwise.
891 * Assumes vcpu_load() was already called. 891 * Assumes vcpu_load() was already called.
892 */ 892 */
893int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data) 893int kvm_set_msr(struct kvm_vcpu *vcpu, struct msr_data *msr)
894{ 894{
895 return kvm_x86_ops->set_msr(vcpu, msr_index, data); 895 return kvm_x86_ops->set_msr(vcpu, msr);
896} 896}
897 897
898/* 898/*
@@ -900,7 +900,12 @@ int kvm_set_msr(struct kvm_vcpu *vcpu, u32 msr_index, u64 data)
900 */ 900 */
901static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data) 901static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
902{ 902{
903 return kvm_set_msr(vcpu, index, *data); 903 struct msr_data msr;
904
905 msr.data = *data;
906 msr.index = index;
907 msr.host_initiated = true;
908 return kvm_set_msr(vcpu, &msr);
904} 909}
905 910
906#ifdef CONFIG_X86_64 911#ifdef CONFIG_X86_64
@@ -1130,13 +1135,14 @@ void kvm_track_tsc_matching(struct kvm_vcpu *vcpu)
1130#endif 1135#endif
1131} 1136}
1132 1137
1133void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data) 1138void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr)
1134{ 1139{
1135 struct kvm *kvm = vcpu->kvm; 1140 struct kvm *kvm = vcpu->kvm;
1136 u64 offset, ns, elapsed; 1141 u64 offset, ns, elapsed;
1137 unsigned long flags; 1142 unsigned long flags;
1138 s64 usdiff; 1143 s64 usdiff;
1139 bool matched; 1144 bool matched;
1145 u64 data = msr->data;
1140 1146
1141 raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags); 1147 raw_spin_lock_irqsave(&kvm->arch.tsc_write_lock, flags);
1142 offset = kvm_x86_ops->compute_tsc_offset(vcpu, data); 1148 offset = kvm_x86_ops->compute_tsc_offset(vcpu, data);
@@ -1857,9 +1863,11 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
1857 &vcpu->arch.st.steal, sizeof(struct kvm_steal_time)); 1863 &vcpu->arch.st.steal, sizeof(struct kvm_steal_time));
1858} 1864}
1859 1865
1860int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data) 1866int kvm_set_msr_common(struct kvm_vcpu *vcpu, struct msr_data *msr_info)
1861{ 1867{
1862 bool pr = false; 1868 bool pr = false;
1869 u32 msr = msr_info->index;
1870 u64 data = msr_info->data;
1863 1871
1864 switch (msr) { 1872 switch (msr) {
1865 case MSR_EFER: 1873 case MSR_EFER:
@@ -4531,7 +4539,12 @@ static int emulator_get_msr(struct x86_emulate_ctxt *ctxt,
4531static int emulator_set_msr(struct x86_emulate_ctxt *ctxt, 4539static int emulator_set_msr(struct x86_emulate_ctxt *ctxt,
4532 u32 msr_index, u64 data) 4540 u32 msr_index, u64 data)
4533{ 4541{
4534 return kvm_set_msr(emul_to_vcpu(ctxt), msr_index, data); 4542 struct msr_data msr;
4543
4544 msr.data = data;
4545 msr.index = msr_index;
4546 msr.host_initiated = false;
4547 return kvm_set_msr(emul_to_vcpu(ctxt), &msr);
4535} 4548}
4536 4549
4537static int emulator_read_pmc(struct x86_emulate_ctxt *ctxt, 4550static int emulator_read_pmc(struct x86_emulate_ctxt *ctxt,
@@ -6375,11 +6388,15 @@ int kvm_arch_vcpu_setup(struct kvm_vcpu *vcpu)
6375int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu) 6388int kvm_arch_vcpu_postcreate(struct kvm_vcpu *vcpu)
6376{ 6389{
6377 int r; 6390 int r;
6391 struct msr_data msr;
6378 6392
6379 r = vcpu_load(vcpu); 6393 r = vcpu_load(vcpu);
6380 if (r) 6394 if (r)
6381 return r; 6395 return r;
6382 kvm_write_tsc(vcpu, 0); 6396 msr.data = 0x0;
6397 msr.index = MSR_IA32_TSC;
6398 msr.host_initiated = true;
6399 kvm_write_tsc(vcpu, &msr);
6383 vcpu_put(vcpu); 6400 vcpu_put(vcpu);
6384 6401
6385 return r; 6402 return r;
diff --git a/arch/x86/kvm/x86.h b/arch/x86/kvm/x86.h
index 2b5219c12ac8..e224f7a671b6 100644
--- a/arch/x86/kvm/x86.h
+++ b/arch/x86/kvm/x86.h
@@ -112,7 +112,7 @@ void kvm_before_handle_nmi(struct kvm_vcpu *vcpu);
112void kvm_after_handle_nmi(struct kvm_vcpu *vcpu); 112void kvm_after_handle_nmi(struct kvm_vcpu *vcpu);
113int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip); 113int kvm_inject_realmode_interrupt(struct kvm_vcpu *vcpu, int irq, int inc_eip);
114 114
115void kvm_write_tsc(struct kvm_vcpu *vcpu, u64 data); 115void kvm_write_tsc(struct kvm_vcpu *vcpu, struct msr_data *msr);
116 116
117int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt, 117int kvm_read_guest_virt(struct x86_emulate_ctxt *ctxt,
118 gva_t addr, void *val, unsigned int bytes, 118 gva_t addr, void *val, unsigned int bytes,