From patchwork Tue Mar 9 14:09:21 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gleb Natapov X-Patchwork-Id: 84290 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o29E9fnQ029246 for ; Tue, 9 Mar 2010 14:09:41 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752953Ab0CIOJj (ORCPT ); Tue, 9 Mar 2010 09:09:39 -0500 Received: from mx1.redhat.com ([209.132.183.28]:65152 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752923Ab0CIOJ0 (ORCPT ); Tue, 9 Mar 2010 09:09:26 -0500 Received: from int-mx04.intmail.prod.int.phx2.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.17]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id o29E9QKb019110 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Tue, 9 Mar 2010 09:09:26 -0500 Received: from dhcp-1-237.tlv.redhat.com (dhcp-1-237.tlv.redhat.com [10.35.1.237]) by int-mx04.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id o29E9O3m013578 for ; Tue, 9 Mar 2010 09:09:25 -0500 Received: by dhcp-1-237.tlv.redhat.com (Postfix, from userid 13519) id 7DCCB1339AE; Tue, 9 Mar 2010 16:09:23 +0200 (IST) From: Gleb Natapov To: kvm@vger.kernel.org Subject: [PATCH 23/24] KVM: x86 emulator: introduce pio in string read ahead. Date: Tue, 9 Mar 2010 16:09:21 +0200 Message-Id: <1268143762-4000-24-git-send-email-gleb@redhat.com> In-Reply-To: <1268143762-4000-1-git-send-email-gleb@redhat.com> References: <1268143762-4000-1-git-send-email-gleb@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.17 Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 09 Mar 2010 14:09:41 +0000 (UTC) diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h index f74b4ad..da7a711 100644 --- a/arch/x86/include/asm/kvm_emulate.h +++ b/arch/x86/include/asm/kvm_emulate.h @@ -150,6 +150,12 @@ struct fetch_cache { unsigned long end; }; +struct read_cache { + u8 data[1024]; + unsigned long pos; + unsigned long end; +}; + struct decode_cache { u8 twobyte; u8 b; @@ -177,6 +183,7 @@ struct decode_cache { void *modrm_ptr; unsigned long modrm_val; struct fetch_cache fetch; + struct read_cache io_read; }; struct x86_emulate_ctxt { diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c index 76ed77d..987be2a 100644 --- a/arch/x86/kvm/emulate.c +++ b/arch/x86/kvm/emulate.c @@ -1222,6 +1222,28 @@ done: return (rc == X86EMUL_UNHANDLEABLE) ? -1 : 0; } +static int pio_in_emulated(struct x86_emulate_ctxt *ctxt, + struct x86_emulate_ops *ops, + unsigned int size, unsigned short port, + void *dest, unsigned int count) +{ + struct read_cache *mc = &ctxt->decode.io_read; + + if (mc->pos == mc->end) { /* refill pio read ahead */ + unsigned int n = sizeof(mc->data) / size; + n = min(n, count); + mc->pos = mc->end = 0; + if (!ops->pio_in_emulated(size, port, mc->data, n, + ctxt->vcpu)) + return 0; + mc->end = n * size; + } + + memcpy(dest, mc->data + mc->pos, size); + mc->pos += size; + return 1; +} + static u32 desc_limit_scaled(struct desc_struct *desc) { u32 limit = get_desc_limit(desc); @@ -2601,8 +2623,11 @@ special_insn: kvm_inject_gp(ctxt->vcpu, 0); goto done; } - if (!ops->pio_in_emulated(c->dst.bytes, c->regs[VCPU_REGS_RDX], - &c->dst.val, 1, ctxt->vcpu)) + if (c->rep_prefix) + ctxt->restart = true; + if (!pio_in_emulated(ctxt, ops, c->dst.bytes, + c->regs[VCPU_REGS_RDX], &c->dst.val, + c->rep_prefix ? c->regs[VCPU_REGS_RCX] : 1)) goto done; /* IO is needed, skip writeback */ register_address_increment(c, &c->regs[VCPU_REGS_RDI], @@ -2908,8 +2933,9 @@ special_insn: goto done; } if (io_dir_in) - ops->pio_in_emulated((c->d & ByteOp) ? 1 : c->op_bytes, - port, &c->dst.val, 1, ctxt->vcpu); + pio_in_emulated(ctxt, ops, + (c->d & ByteOp) ? 1 : c->op_bytes, + port, &c->dst.val, 1); else ops->pio_out_emulated((c->d & ByteOp) ? 1 : c->op_bytes, port, &c->regs[VCPU_REGS_RAX], 1,