All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] KVM: nSVM: Fix IOIO size reported on emulation
@ 2014-06-30  9:07 Jan Kiszka
  2014-06-30  9:27 ` nSVM: interception checks on emulation (was: [PATCH] KVM: nSVM: Fix IOIO size reported on emulation) Jan Kiszka
  0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2014-06-30  9:07 UTC (permalink / raw)
  To: Paolo Bonzini, kvm; +Cc: Joerg Roedel, Valentine Sinitsyn

[-- Attachment #1: Type: text/plain, Size: 1363 bytes --]

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(-)

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 ||
-- 
1.8.4.5


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* nSVM: interception checks on emulation (was: [PATCH] KVM: nSVM: Fix IOIO size reported on emulation)
  2014-06-30  9:07 [PATCH] KVM: nSVM: Fix IOIO size reported on emulation Jan Kiszka
@ 2014-06-30  9:27 ` Jan Kiszka
  2014-06-30 10:52   ` [PATCH] KVM: nSVM: Set correct port for IOIO interception evaluation Jan Kiszka
  0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2014-06-30  9:27 UTC (permalink / raw)
  To: Paolo Bonzini, kvm; +Cc: Joerg Roedel, Valentine Sinitsyn

[-- Attachment #1: Type: text/plain, Size: 2490 bytes --]

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



[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH] KVM: nSVM: Set correct port for IOIO interception evaluation
  2014-06-30  9:27 ` nSVM: interception checks on emulation (was: [PATCH] KVM: nSVM: Fix IOIO size reported on emulation) Jan Kiszka
@ 2014-06-30 10:52   ` Jan Kiszka
  2014-07-01 15:37     ` Joerg Roedel
  0 siblings, 1 reply; 4+ messages in thread
From: Jan Kiszka @ 2014-06-30 10:52 UTC (permalink / raw)
  To: Paolo Bonzini, kvm; +Cc: Joerg Roedel, Valentine Sinitsyn

[-- Attachment #1: Type: text/plain, Size: 2476 bytes --]

From: Jan Kiszka <jan.kiszka@siemens.com>

Obtaining the port number from DX is bogus as a) there are immediate
port accesses and b) user space may have changed the register content
while processing the PIO access. Forward the correct value from the
instruction emulator instead.

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

Valentine, I've a stable Jailhouse root cell under QEMU now :)

 arch/x86/include/asm/kvm_emulate.h | 1 +
 arch/x86/kvm/emulate.c             | 1 +
 arch/x86/kvm/svm.c                 | 6 +++---
 3 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index ffa2671..0e0151c 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -37,6 +37,7 @@ struct x86_instruction_info {
 	u8  modrm_reg;          /* index of register used               */
 	u8  modrm_rm;		/* rm part of modrm			*/
 	u64 src_val;            /* value of source operand              */
+	u64 dst_val;            /* value of destination operand         */
 	u8  src_bytes;          /* size of source operand               */
 	u8  dst_bytes;          /* size of destination operand          */
 	u8  ad_bytes;           /* size of src/dst address              */
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index 84dc4ba..15453e5 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -426,6 +426,7 @@ static int emulator_check_intercept(struct x86_emulate_ctxt *ctxt,
 		.modrm_reg  = ctxt->modrm_reg,
 		.modrm_rm   = ctxt->modrm_rm,
 		.src_val    = ctxt->src.val64,
+		.dst_val    = ctxt->dst.val64,
 		.src_bytes  = ctxt->src.bytes,
 		.dst_bytes  = ctxt->dst.bytes,
 		.ad_bytes   = ctxt->ad_bytes,
diff --git a/arch/x86/kvm/svm.c b/arch/x86/kvm/svm.c
index 1824949..85d4458 100644
--- a/arch/x86/kvm/svm.c
+++ b/arch/x86/kvm/svm.c
@@ -4256,13 +4256,13 @@ static int svm_check_intercept(struct kvm_vcpu *vcpu,
 		u64 exit_info;
 		u32 bytes;
 
-		exit_info = (vcpu->arch.regs[VCPU_REGS_RDX] & 0xffff) << 16;
-
 		if (info->intercept == x86_intercept_in ||
 		    info->intercept == x86_intercept_ins) {
-			exit_info |= SVM_IOIO_TYPE_MASK;
+			exit_info = ((info->src_val & 0xffff) << 16) |
+				SVM_IOIO_TYPE_MASK;
 			bytes = info->dst_bytes;
 		} else {
+			exit_info = (info->dst_val & 0xffff) << 16;
 			bytes = info->src_bytes;
 		}
 
-- 
1.8.4.5


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 263 bytes --]

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH] KVM: nSVM: Set correct port for IOIO interception evaluation
  2014-06-30 10:52   ` [PATCH] KVM: nSVM: Set correct port for IOIO interception evaluation Jan Kiszka
@ 2014-07-01 15:37     ` Joerg Roedel
  0 siblings, 0 replies; 4+ messages in thread
From: Joerg Roedel @ 2014-07-01 15:37 UTC (permalink / raw)
  To: Jan Kiszka; +Cc: Paolo Bonzini, kvm, Valentine Sinitsyn

On Mon, Jun 30, 2014 at 12:52:55PM +0200, Jan Kiszka wrote:
> From: Jan Kiszka <jan.kiszka@siemens.com>
> 
> Obtaining the port number from DX is bogus as a) there are immediate
> port accesses and b) user space may have changed the register content
> while processing the PIO access. Forward the correct value from the
> instruction emulator instead.
> 
> Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>

Reviewed-by: Joerg Roedel <jroedel@suse.de>
Acked-by: Joerg Roedel <jroedel@suse.de>



^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2014-07-01 15:37 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-06-30  9:07 [PATCH] KVM: nSVM: Fix IOIO size reported on emulation Jan Kiszka
2014-06-30  9:27 ` nSVM: interception checks on emulation (was: [PATCH] KVM: nSVM: Fix IOIO size reported on emulation) Jan Kiszka
2014-06-30 10:52   ` [PATCH] KVM: nSVM: Set correct port for IOIO interception evaluation Jan Kiszka
2014-07-01 15:37     ` Joerg Roedel

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.