Commit 9bf41833 authored by Jan Kiszka's avatar Jan Kiszka Committed by Paolo Bonzini

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: default avatarJan Kiszka <jan.kiszka@siemens.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
parent 62baf44c
...@@ -2116,22 +2116,27 @@ static void nested_svm_unmap(struct page *page) ...@@ -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;
iopm_len = (start_bit + size > 8) ? 2 : 1;
mask = (0xf >> (4 - size)) << start_bit;
val = 0; 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)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment