diff mbox

KVM: nSVM: Fix IOIO size reported on emulation

Message ID 53B128B9.1030205@web.de (mailing list archive)
State New, archived
Headers show

Commit Message

Jan Kiszka June 30, 2014, 9:07 a.m. UTC
From: Jan Kiszka <jan.kiszka@siemens.com>

The access size of an in/ins is reported in dst_bytes, and that of
out/outs in src_bytes.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---

I'm seeing one more issue now: on emulation of "in (%dx),%eax", we leave
to user space several times and check interception also several times
after returning. We use dx to calculate the port number for the
interception check. But at some point, user space (QEMU) decides to
update that register during vmport access - and now we check the wrong
port in the bitmap (namely port 0). Ideas?

In general, the same interception checks are done multiple times. Once
after the exit, then again during emulation. Can't we avoid this somehow?

 arch/x86/kvm/svm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

Jan Kiszka June 30, 2014, 9:27 a.m. UTC | #1
On 2014-06-30 11:07, Jan Kiszka wrote:
> I'm seeing one more issue now: on emulation of "in (%dx),%eax", we leave
> to user space several times and check interception also several times

Correction: we only leave once for user space.

> after returning. We use dx to calculate the port number for the
> interception check. But at some point, user space (QEMU) decides to
> update that register during vmport access - and now we check the wrong
> port in the bitmap (namely port 0). Ideas?
> 
> In general, the same interception checks are done multiple times. Once
> after the exit, then again during emulation. Can't we avoid this somehow?
> 

OK, we have different interception stages, but it seems we take multiple
ones when we should only take a single:

 qemu-system-x86-4455  [000] 38083.617545: kvm_exit:             reason EXIT_IOIO rip 0x7fc6ead774e4 info 56580241 7fc6ead774e5
 qemu-system-x86-4455  [000] 38083.617547: kvm_nested_vmexit:    rip 7fc6ead774e4 reason EXIT_IOIO info1 56580241 info2 7fc6ead774e5 int_info 0 int_info_err 0
 qemu-system-x86-4455  [000] 38083.617548: bprint:               nested_svm_intercept: 5658 4 3c00bacb 0 1 f
 qemu-system-x86-4455  [000] 38083.617549: bprint:               nested_svm_intercept: f0
 qemu-system-x86-4455  [000] 38083.617553: kvm_emulate_insn:     0:7fc6ead774e4: ed
 qemu-system-x86-4455  [000] 38083.617555: bprint:               svm_check_intercept: 5658 2 4 43
 qemu-system-x86-4455  [000] 38083.617556: bprint:               nested_svm_intercept: 5658 4 3c00bacb 0 1 f
 qemu-system-x86-4455  [000] 38083.617556: bprint:               nested_svm_intercept: f0
 qemu-system-x86-4455  [000] 38083.617559: kvm_userspace_exit:   reason KVM_EXIT_IO (2)
 qemu-system-x86-4455  [000] 38083.617567: bprint:               kvm_arch_vcpu_ioctl_get_regs: 5658
 qemu-system-x86-4455  [000] 38083.617598: bprint:               kvm_arch_vcpu_ioctl_set_regs: 0
 qemu-system-x86-4455  [000] 38083.617628: bprint:               svm_check_intercept: 0 2 4 43
 qemu-system-x86-4455  [000] 38083.617629: bprint:               nested_svm_intercept: 0 4 3c00b000 0 1 f
 qemu-system-x86-4455  [000] 38083.617630: bprint:               nested_svm_intercept: ff
 qemu-system-x86-4455  [000] 38083.617631: kvm_nested_vmexit_inject: reason EXIT_IOIO info1 241 info2 7fc6ead774e4 int_info 0 int_info_err 0

And you can also see the rdx writing of user space here (rdx is printed
in kvm_arch_vcpu_ioctl_*).

Jan
diff mbox

Patch

diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 3483ac9..1824949 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -4261,9 +4261,9 @@  static int svm_check_intercept(struct kvm_vcpu *vcpu,
 		if (info->intercept == x86_intercept_in ||
 		    info->intercept == x86_intercept_ins) {
 			exit_info |= SVM_IOIO_TYPE_MASK;
-			bytes = info->src_bytes;
-		} else {
 			bytes = info->dst_bytes;
+		} else {
+			bytes = info->src_bytes;
 		}
 
 		if (info->intercept == x86_intercept_outs ||