From: Bandan Das <bsd@redhat.com>
To: kvm@vger.kernel.org
Cc: Paolo Bonzini <pbonzini@redhat.com>,
Marcelo Tosatti <mtosatti@redhat.com>,
Gleb Natapov <gleb@kernel.org>,
linux-kernel@vger.kernel.org
Subject: [RFC PATCH 3/3] KVM: x86: cache userspace address for faster fetches
Date: Mon, 5 May 2014 20:40:59 -0400 [thread overview]
Message-ID: <1399336859-7227-4-git-send-email-bsd@redhat.com> (raw)
In-Reply-To: <1399336859-7227-1-git-send-email-bsd@redhat.com>
On every instruction fetch, kvm_read_guest_virt_helper
does the gva to gpa translation followed by searching for the
memslot. Store the gva hva mapping so that if there's a match
we can directly call __copy_from_user()
Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
Signed-off-by: Bandan Das <bsd@redhat.com>
---
arch/x86/include/asm/kvm_emulate.h | 7 ++++++-
arch/x86/kvm/x86.c | 33 +++++++++++++++++++++++----------
2 files changed, 29 insertions(+), 11 deletions(-)
diff --git a/arch/x86/include/asm/kvm_emulate.h b/arch/x86/include/asm/kvm_emulate.h
index 085d688..20ccde4 100644
--- a/arch/x86/include/asm/kvm_emulate.h
+++ b/arch/x86/include/asm/kvm_emulate.h
@@ -323,10 +323,11 @@ struct x86_emulate_ctxt {
int (*execute)(struct x86_emulate_ctxt *ctxt);
int (*check_perm)(struct x86_emulate_ctxt *ctxt);
/*
- * The following five fields are cleared together,
+ * The following six fields are cleared together,
* the rest are initialized unconditionally in x86_decode_insn
* or elsewhere
*/
+ bool addr_cache_valid;
u8 rex_prefix;
u8 lock_prefix;
u8 rep_prefix;
@@ -348,6 +349,10 @@ struct x86_emulate_ctxt {
struct fetch_cache fetch;
struct read_cache io_read;
struct read_cache mem_read;
+ struct {
+ gfn_t gfn;
+ unsigned long uaddr;
+ } addr_cache;
};
/* Repeat String Operation Prefix */
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index cf69e3b..7afcfc7 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -4072,26 +4072,38 @@ static int kvm_read_guest_virt_helper(gva_t addr, void *val, unsigned int bytes,
unsigned toread = min(bytes, (unsigned)PAGE_SIZE - offset);
int ret;
unsigned long uaddr;
+ gfn_t gfn = addr >> PAGE_SHIFT;
- ret = ctxt->ops->memory_prepare(ctxt, addr, toread,
- exception, false,
- NULL, &uaddr);
- if (ret != X86EMUL_CONTINUE)
- return ret;
+ if (ctxt->addr_cache_valid &&
+ (ctxt->addr_cache.gfn == gfn))
+ uaddr = (ctxt->addr_cache.uaddr << PAGE_SHIFT) +
+ offset_in_page(addr);
+ else {
+ ret = ctxt->ops->memory_prepare(ctxt, addr, toread,
+ exception, false,
+ NULL, &uaddr);
+ if (ret != X86EMUL_CONTINUE)
+ return ret;
+
+ if (unlikely(kvm_is_error_hva(uaddr))) {
+ r = X86EMUL_PROPAGATE_FAULT;
+ return r;
+ }
- if (unlikely(kvm_is_error_hva(uaddr))) {
- r = X86EMUL_PROPAGATE_FAULT;
- return r;
+ /* Cache gfn and hva */
+ ctxt->addr_cache.gfn = addr >> PAGE_SHIFT;
+ ctxt->addr_cache.uaddr = uaddr >> PAGE_SHIFT;
+ ctxt->addr_cache_valid = true;
}
ret = __copy_from_user(data, (void __user *)uaddr, toread);
if (ret < 0) {
r = X86EMUL_IO_NEEDED;
+ /* Where else should we invalidate cache ? */
+ ctxt->ops->memory_finish(ctxt, NULL, uaddr);
return r;
}
- ctxt->ops->memory_finish(ctxt, NULL, uaddr);
-
bytes -= toread;
data += toread;
addr += toread;
@@ -4339,6 +4351,7 @@ static void emulator_memory_finish(struct x86_emulate_ctxt *ctxt,
struct kvm_memory_slot *memslot;
gfn_t gfn;
+ ctxt->addr_cache_valid = false;
if (!opaque)
return;
--
1.8.3.1
next prev parent reply other threads:[~2014-05-06 0:41 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-05-06 0:40 [RFC PATCH 0/3] Emulator Speedups - Optimize Instruction fetches Bandan Das
2014-05-06 0:40 ` [RFC PATCH 1/3] KVM: x86: pass ctxt to fetch helper function Bandan Das
2014-05-06 0:40 ` [RFC PATCH 2/3] KVM: x86: use memory_prepare in " Bandan Das
2014-05-06 8:27 ` Paolo Bonzini
2014-05-06 9:46 ` Paolo Bonzini
2014-05-06 0:40 ` Bandan Das [this message]
2014-05-06 9:40 ` [RFC PATCH 3/3] KVM: x86: cache userspace address for faster fetches Paolo Bonzini
2014-05-07 4:45 ` Bandan Das
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=1399336859-7227-4-git-send-email-bsd@redhat.com \
--to=bsd@redhat.com \
--cc=gleb@kernel.org \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mtosatti@redhat.com \
--cc=pbonzini@redhat.com \
/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 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.