From 659ca5cd102d61cdcbd06ee56f8f987401082953 Mon Sep 17 00:00:00 2001 From: Joerg Roedel Date: Mon, 1 Mar 2010 15:34:38 +0100 Subject: [PATCH] --- yaml --- r: 197649 b: refs/heads/master c: 0d6b35378e80c555e20ca3aa3d3cc609b403cbb6 h: refs/heads/master i: 197647: a1079cd1c6756a6803d0a6187e368cfb367182d1 v: v3 --- [refs] | 2 +- trunk/arch/x86/kvm/svm.c | 47 +++++++++++++++------------------------- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/[refs] b/[refs] index c405ff215d93..277c420a86bc 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 323c3d809b8bd42d6d557c734d4bdfdefa110445 +refs/heads/master: 0d6b35378e80c555e20ca3aa3d3cc609b403cbb6 diff --git a/trunk/arch/x86/kvm/svm.c b/trunk/arch/x86/kvm/svm.c index 45a287e51e18..7cb2eb906eca 100644 --- a/trunk/arch/x86/kvm/svm.c +++ b/trunk/arch/x86/kvm/svm.c @@ -1660,40 +1660,27 @@ static void nested_svm_unmap(struct page *page) static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) { - u32 param = svm->vmcb->control.exit_info_1 & 1; - u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; - u32 t0, t1; - int ret; - u8 val; + u32 offset, msr, value; + int write, mask; if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) return NESTED_EXIT_HOST; - switch (msr) { - case 0 ... 0x1fff: - t0 = (msr * 2) % 8; - t1 = msr / 8; - break; - case 0xc0000000 ... 0xc0001fff: - t0 = (8192 + msr - 0xc0000000) * 2; - t1 = (t0 / 8); - t0 %= 8; - break; - case 0xc0010000 ... 0xc0011fff: - t0 = (16384 + msr - 0xc0010000) * 2; - t1 = (t0 / 8); - t0 %= 8; - break; - default: - ret = NESTED_EXIT_DONE; - goto out; - } + msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; + offset = svm_msrpm_offset(msr); + write = svm->vmcb->control.exit_info_1 & 1; + mask = 1 << ((2 * (msr & 0xf)) + write); - if (!kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + t1, &val, 1)) - ret = val & ((1 << param) << t0) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; + if (offset == MSR_INVALID) + return NESTED_EXIT_DONE; -out: - return ret; + /* Offset is in 32 bit units but need in 8 bit units */ + offset *= 4; + + if (kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + offset, &value, 4)) + return NESTED_EXIT_DONE; + + return (value & mask) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; } static int nested_svm_exit_special(struct vcpu_svm *svm) @@ -1954,8 +1941,8 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) if (msrpm_offsets[i] == 0xffffffff) break; - offset = svm->nested.vmcb_msrpm + msrpm_offsets[i]; - p = msrpm_offsets[i] / 4; + p = msrpm_offsets[i]; + offset = svm->nested.vmcb_msrpm + (p * 4); if (kvm_read_guest(svm->vcpu.kvm, offset, &value, 4)) return false;