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>
This commit is contained in:
Jan Kiszka 2014-06-30 10:54:17 +02:00 committed by Paolo Bonzini
parent 62baf44cad
commit 9bf418335e

View File

@ -2116,22 +2116,27 @@ static void nested_svm_unmap(struct page *page)
static int nested_svm_intercept_ioio(struct vcpu_svm *svm) static int nested_svm_intercept_ioio(struct vcpu_svm *svm)
{ {
unsigned port; unsigned port, size, iopm_len;
u8 val, bit; u16 val, mask;
u8 start_bit;
u64 gpa; u64 gpa;
if (!(svm->nested.intercept & (1ULL << INTERCEPT_IOIO_PROT))) if (!(svm->nested.intercept & (1ULL << INTERCEPT_IOIO_PROT)))
return NESTED_EXIT_HOST; return NESTED_EXIT_HOST;
port = svm->vmcb->control.exit_info_1 >> 16; port = svm->vmcb->control.exit_info_1 >> 16;
size = (svm->vmcb->control.exit_info_1 & SVM_IOIO_SIZE_MASK) >>
SVM_IOIO_SIZE_SHIFT;
gpa = svm->nested.vmcb_iopm + (port / 8); gpa = svm->nested.vmcb_iopm + (port / 8);
bit = port % 8; start_bit = port % 8;
val = 0; iopm_len = (start_bit + size > 8) ? 2 : 1;
mask = (0xf >> (4 - size)) << start_bit;
val = 0;
if (kvm_read_guest(svm->vcpu.kvm, gpa, &val, 1)) if (kvm_read_guest(svm->vcpu.kvm, gpa, &val, iopm_len))
val &= (1 << bit); return NESTED_EXIT_DONE;
return val ? NESTED_EXIT_DONE : NESTED_EXIT_HOST; return (val & mask) ? NESTED_EXIT_DONE : NESTED_EXIT_HOST;
} }
static int nested_svm_exit_handled_msr(struct vcpu_svm *svm) static int nested_svm_exit_handled_msr(struct vcpu_svm *svm)