aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kiszka <jan.kiszka@siemens.com>2014-06-30 04:54:17 -0400
committerPaolo Bonzini <pbonzini@redhat.com>2014-07-09 12:09:55 -0400
commit9bf418335e24da995ea682a028926d7e1036be6f (patch)
tree2744a9564a101286b60272ff7eff4c216326d19c
parent62baf44cad3bc6b37115cc21e4228fe53d4f3474 (diff)
KVM: nSVM: Fix IOIO bitmap evaluation
First, kvm_read_guest returns 0 on success. And then we need to take the access size into account when testing the bitmap: intercept if any of bits corresponding to the access is set. Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
-rw-r--r--arch/x86/kvm/svm.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index c79766e1f1e0..3483ac978c76 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -2116,22 +2116,27 @@ static void nested_svm_unmap(struct page *page)
2116 2116
2117static int nested_svm_intercept_ioio(struct vcpu_svm *svm) 2117static int nested_svm_intercept_ioio(struct vcpu_svm *svm)
2118{ 2118{
2119 unsigned port; 2119 unsigned port, size, iopm_len;
2120 u8 val, bit; 2120 u16 val, mask;
2121 u8 start_bit;
2121 u64 gpa; 2122 u64 gpa;
2122 2123
2123 if (!(svm->nested.intercept & (1ULL << INTERCEPT_IOIO_PROT))) 2124 if (!(svm->nested.intercept & (1ULL << INTERCEPT_IOIO_PROT)))
2124 return NESTED_EXIT_HOST; 2125 return NESTED_EXIT_HOST;
2125 2126
2126 port = svm->vmcb->control.exit_info_1 >> 16; 2127 port = svm->vmcb->control.exit_info_1 >> 16;
2128 size = (svm->vmcb->control.exit_info_1 & SVM_IOIO_SIZE_MASK) >>
2129 SVM_IOIO_SIZE_SHIFT;
2127 gpa = svm->nested.vmcb_iopm + (port / 8); 2130 gpa = svm->nested.vmcb_iopm + (port / 8);
2128 bit = port % 8; 2131 start_bit = port % 8;
2129 val = 0; 2132 iopm_len = (start_bit + size > 8) ? 2 : 1;
2133 mask = (0xf >> (4 - size)) << start_bit;
2134 val = 0;
2130 2135
2131 if (kvm_read_guest(svm->vcpu.kvm, gpa, &val, 1)) 2136 if (kvm_read_guest(svm->vcpu.kvm, gpa, &val, iopm_len))
2132 val &= (1 << bit); 2137 return NESTED_EXIT_DONE;
2133 2138
2134 return val ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; 2139 return (val & mask) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST;
2135} 2140}
2136 2141
2137static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) 2142static int nested_svm_exit_handled_msr(struct vcpu_svm *svm)