From: Paolo Bonzini <pbonzini@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: kvm@vger.kernel.org, bsd@redhat.com
Subject: [RFC PATCH 2/4] KVM: emulate: avoid repeated calls to do_insn_fetch_bytes
Date: Tue, 6 May 2014 20:16:13 +0200 [thread overview]
Message-ID: <1399400175-23754-3-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1399400175-23754-1-git-send-email-pbonzini@redhat.com>
do_insn_fetch_bytes will only be called once in a given insn_fetch and
insn_fetch_arr, because in fact it will only be called at most twice
for any instruction and the first call is explicit in x86_decode_insn.
This observation lets us hoist the call out of the memory copying loop.
It does not buy performance, because most fetches are one byte long
anyway, but it prepares for the next patch.
The overflow check is tricky, but correct. Because do_insn_fetch_bytes
has already been called once, we know that fc->end is at least 15. So
it is okay to subtract the number of bytes we want to read.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/x86/kvm/emulate.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/arch/x86/kvm/emulate.c b/arch/x86/kvm/emulate.c
index c7b625bf0b5d..886f9a88010f 100644
--- a/arch/x86/kvm/emulate.c
+++ b/arch/x86/kvm/emulate.c
@@ -706,7 +706,7 @@ static int segmented_read_std(struct x86_emulate_ctxt *ctxt,
* Prefetch the remaining bytes of the instruction without crossing page
* boundary if they are not in fetch_cache yet.
*/
-static int do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt)
+static int do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt, int op_size)
{
struct fetch_cache *fc = &ctxt->fetch;
int rc;
@@ -718,7 +718,14 @@ static int do_insn_fetch_bytes(struct x86_emulate_ctxt *ctxt)
cur_size = fc->end - fc->start;
size = min(15UL - cur_size,
PAGE_SIZE - offset_in_page(fc->end));
- if (unlikely(size == 0))
+
+ /*
+ * One instruction can only straddle two pages,
+ * and one has been loaded at the beginning of
+ * x86_decode_insn. So, if not enough bytes
+ * still, we must have hit the 15-byte boundary.
+ */
+ if (unlikely(size < op_size))
return X86EMUL_UNHANDLEABLE;
rc = __linearize(ctxt, addr, size, false, true, &linear);
if (unlikely(rc != X86EMUL_CONTINUE))
@@ -739,12 +746,14 @@ static int do_insn_fetch(struct x86_emulate_ctxt *ctxt,
u8 *dest = __dest;
u8 *src = &fc->data[ctxt->_eip - fc->start];
+ /* We have to be careful about overflow! */
+ if (unlikely(ctxt->_eip > fc->end - size)) {
+ rc != do_insn_fetch_bytes(ctxt, size);
+ if (rc != X86EMUL_CONTINNUE)
+ goto done;
+ }
+
while (size--) {
- if (unlikely(ctxt->_eip == fc->end)) {
- rc = do_insn_fetch_bytes(ctxt);
- if (rc != X86EMUL_CONTINUE)
- return rc;
- }
*dest++ = *src++;
ctxt->_eip++;
continue;
@@ -4273,7 +4282,7 @@ int x86_decode_insn(struct x86_emulate_ctxt *ctxt, void *insn, int insn_len)
if (insn_len > 0)
memcpy(ctxt->fetch.data, insn, insn_len);
else {
- rc = do_insn_fetch_bytes(ctxt);
+ rc = do_insn_fetch_bytes(ctxt, 1);
if (rc != X86EMUL_CONTINUE)
return rc;
}
--
1.8.3.1
next prev parent reply other threads:[~2014-05-06 18:16 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-06 18:16 [RFC PATCH 0/4] KVM: emulator: speed up instruction fetch Paolo Bonzini
2014-05-06 18:16 ` [RFC PATCH 1/4] KVM: emulate: speed up do_insn_fetch Paolo Bonzini
2014-05-07 2:30 ` Bandan Das
2014-05-07 8:32 ` Paolo Bonzini
2014-05-06 18:16 ` Paolo Bonzini [this message]
2014-05-07 4:21 ` [RFC PATCH 2/4] KVM: emulate: avoid repeated calls to do_insn_fetch_bytes Bandan Das
2014-05-07 8:34 ` Paolo Bonzini
2014-05-06 18:16 ` [RFC PATCH 3/4] KVM: emulate: avoid per-byte copying in instruction fetches Paolo Bonzini
2014-05-07 4:36 ` Bandan Das
2014-05-07 8:40 ` Paolo Bonzini
2014-05-06 18:16 ` [RFC PATCH 4/4] KVM: emulate: put pointers in the fetch_cache Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1399400175-23754-3-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=bsd@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®