KVM: nSVM: Set correct port for IOIO interception evaluation
authorJan Kiszka <jan.kiszka@siemens.com>
Mon, 30 Jun 2014 10:52:55 +0000 (12:52 +0200)
committerPaolo Bonzini <pbonzini@redhat.com>
Wed, 9 Jul 2014 16:09:56 +0000 (18:09 +0200)
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>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
arch/x86/include/asm/kvm_emulate.h
arch/x86/kvm/emulate.c
arch/x86/kvm/svm.c

index ffa2671a7f2f8f3403955144b3bd6447dea90d96..0e0151c13b2c9867773203526d3fc915c90961ea 100644 (file)
@@ -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              */
index 84dc4ba0364dae1ed5d05ea8972bdb0e98b70f47..15453e569f3d612114fc344444eac314c152c2df 100644 (file)
@@ -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,
index 1824949821f9be538ed886d1901378c22061bdd6..85d4458a0b35900afdcf791d43eccf2b3008185f 100644 (file)
@@ -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;
                }