diff options
author | Joerg Roedel <joerg.roedel@amd.com> | 2010-03-01 09:34:38 -0500 |
---|---|---|
committer | Avi Kivity <avi@redhat.com> | 2010-05-17 05:15:13 -0400 |
commit | 0d6b35378e80c555e20ca3aa3d3cc609b403cbb6 (patch) | |
tree | 1a6ca5829b5a9073efc4774d6c1bc7c734682449 /arch | |
parent | 323c3d809b8bd42d6d557c734d4bdfdefa110445 (diff) |
KVM: SVM: Use svm_msrpm_offset in nested_svm_exit_handled_msr
There is a generic function now to calculate msrpm offsets.
Use that function in nested_svm_exit_handled_msr() remove
the duplicate logic (which had a bug anyway).
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/x86/kvm/svm.c | 47 |
1 files changed, 17 insertions, 30 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c index 45a287e51e18..7cb2eb906eca 100644 --- a/arch/x86/kvm/svm.c +++ b/arch/x86/kvm/svm.c | |||
@@ -1660,40 +1660,27 @@ static void nested_svm_unmap(struct page *page) | |||
1660 | 1660 | ||
1661 | static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) | 1661 | static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) |
1662 | { | 1662 | { |
1663 | u32 param = svm->vmcb->control.exit_info_1 & 1; | 1663 | u32 offset, msr, value; |
1664 | u32 msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; | 1664 | int write, mask; |
1665 | u32 t0, t1; | ||
1666 | int ret; | ||
1667 | u8 val; | ||
1668 | 1665 | ||
1669 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) | 1666 | if (!(svm->nested.intercept & (1ULL << INTERCEPT_MSR_PROT))) |
1670 | return NESTED_EXIT_HOST; | 1667 | return NESTED_EXIT_HOST; |
1671 | 1668 | ||
1672 | switch (msr) { | 1669 | msr = svm->vcpu.arch.regs[VCPU_REGS_RCX]; |
1673 | case 0 ... 0x1fff: | 1670 | offset = svm_msrpm_offset(msr); |
1674 | t0 = (msr * 2) % 8; | 1671 | write = svm->vmcb->control.exit_info_1 & 1; |
1675 | t1 = msr / 8; | 1672 | mask = 1 << ((2 * (msr & 0xf)) + write); |
1676 | break; | ||
1677 | case 0xc0000000 ... 0xc0001fff: | ||
1678 | t0 = (8192 + msr - 0xc0000000) * 2; | ||
1679 | t1 = (t0 / 8); | ||
1680 | t0 %= 8; | ||
1681 | break; | ||
1682 | case 0xc0010000 ... 0xc0011fff: | ||
1683 | t0 = (16384 + msr - 0xc0010000) * 2; | ||
1684 | t1 = (t0 / 8); | ||
1685 | t0 %= 8; | ||
1686 | break; | ||
1687 | default: | ||
1688 | ret = NESTED_EXIT_DONE; | ||
1689 | goto out; | ||
1690 | } | ||
1691 | 1673 | ||
1692 | if (!kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + t1, &val, 1)) | 1674 | if (offset == MSR_INVALID) |
1693 | ret = val & ((1 << param) << t0) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; | 1675 | return NESTED_EXIT_DONE; |
1694 | 1676 | ||
1695 | out: | 1677 | /* Offset is in 32 bit units but need in 8 bit units */ |
1696 | return ret; | 1678 | offset *= 4; |
1679 | |||
1680 | if (kvm_read_guest(svm->vcpu.kvm, svm->nested.vmcb_msrpm + offset, &value, 4)) | ||
1681 | return NESTED_EXIT_DONE; | ||
1682 | |||
1683 | return (value & mask) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; | ||
1697 | } | 1684 | } |
1698 | 1685 | ||
1699 | static int nested_svm_exit_special(struct vcpu_svm *svm) | 1686 | static int nested_svm_exit_special(struct vcpu_svm *svm) |
@@ -1954,8 +1941,8 @@ static bool nested_svm_vmrun_msrpm(struct vcpu_svm *svm) | |||
1954 | if (msrpm_offsets[i] == 0xffffffff) | 1941 | if (msrpm_offsets[i] == 0xffffffff) |
1955 | break; | 1942 | break; |
1956 | 1943 | ||
1957 | offset = svm->nested.vmcb_msrpm + msrpm_offsets[i]; | 1944 | p = msrpm_offsets[i]; |
1958 | p = msrpm_offsets[i] / 4; | 1945 | offset = svm->nested.vmcb_msrpm + (p * 4); |
1959 | 1946 | ||
1960 | if (kvm_read_guest(svm->vcpu.kvm, offset, &value, 4)) | 1947 | if (kvm_read_guest(svm->vcpu.kvm, offset, &value, 4)) |
1961 | return false; | 1948 | return false; |