From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: Andrew Morton <akpm-3NddpPZAyC0@public.gmane.org>,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH 02/15] KVM: Do not communicate to userspace through cpu registers during PIO
Date: Sun, 11 Mar 2007 15:53:14 +0200 [thread overview]
Message-ID: <11736212073047-git-send-email-avi@qumranet.com> (raw)
In-Reply-To: <11736212072915-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
Currently when passing the a PIO emulation request to userspace, we
rely on userspace updating %rax (on 'in' instructions) and %rsi/%rdi/%rcx
(on string instructions). This (a) requires two extra ioctls for getting
and setting the registers and (b) is unfriendly to non-x86 archs, when
they get kvm ports.
So fix by doing the register fixups in the kernel and passing to userspace
only an abstract description of the PIO to be done.
Signed-off-by: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
---
drivers/kvm/kvm.h | 1 +
drivers/kvm/kvm_main.c | 48 +++++++++++++++++++++++++++++++++++++++++++++---
drivers/kvm/svm.c | 1 +
drivers/kvm/vmx.c | 1 +
include/linux/kvm.h | 6 +++---
5 files changed, 51 insertions(+), 6 deletions(-)
diff --git a/drivers/kvm/kvm.h b/drivers/kvm/kvm.h
index 901b8d9..59cbc5b 100644
--- a/drivers/kvm/kvm.h
+++ b/drivers/kvm/kvm.h
@@ -274,6 +274,7 @@ struct kvm_vcpu {
int mmio_size;
unsigned char mmio_data[8];
gpa_t mmio_phys_addr;
+ int pio_pending;
struct {
int active;
diff --git a/drivers/kvm/kvm_main.c b/drivers/kvm/kvm_main.c
index 42be8a8..8a4984d 100644
--- a/drivers/kvm/kvm_main.c
+++ b/drivers/kvm/kvm_main.c
@@ -1504,6 +1504,44 @@ void save_msrs(struct vmx_msr_entry *e, int n)
}
EXPORT_SYMBOL_GPL(save_msrs);
+static void complete_pio(struct kvm_vcpu *vcpu)
+{
+ struct kvm_io *io = &vcpu->run->io;
+ long delta;
+
+ kvm_arch_ops->cache_regs(vcpu);
+
+ if (!io->string) {
+ if (io->direction == KVM_EXIT_IO_IN)
+ memcpy(&vcpu->regs[VCPU_REGS_RAX], &io->value,
+ io->size);
+ } else {
+ delta = 1;
+ if (io->rep) {
+ delta *= io->count;
+ /*
+ * The size of the register should really depend on
+ * current address size.
+ */
+ vcpu->regs[VCPU_REGS_RCX] -= delta;
+ }
+ if (io->string_down)
+ delta = -delta;
+ delta *= io->size;
+ if (io->direction == KVM_EXIT_IO_IN)
+ vcpu->regs[VCPU_REGS_RDI] += delta;
+ else
+ vcpu->regs[VCPU_REGS_RSI] += delta;
+ }
+
+ vcpu->pio_pending = 0;
+ vcpu->run->io_completed = 0;
+
+ kvm_arch_ops->decache_regs(vcpu);
+
+ kvm_arch_ops->skip_emulated_instruction(vcpu);
+}
+
static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
{
int r;
@@ -1518,9 +1556,13 @@ static int kvm_vcpu_ioctl_run(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_run->emulated = 0;
}
- if (kvm_run->mmio_completed) {
- memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
- vcpu->mmio_read_completed = 1;
+ if (kvm_run->io_completed) {
+ if (vcpu->pio_pending)
+ complete_pio(vcpu);
+ else {
+ memcpy(vcpu->mmio_data, kvm_run->mmio.data, 8);
+ vcpu->mmio_read_completed = 1;
+ }
}
vcpu->mmio_needed = 0;
diff --git a/drivers/kvm/svm.c b/drivers/kvm/svm.c
index 6787f11..b176f5a 100644
--- a/drivers/kvm/svm.c
+++ b/drivers/kvm/svm.c
@@ -1056,6 +1056,7 @@ static int io_interception(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
}
} else
kvm_run->io.value = vcpu->svm->vmcb->save.rax;
+ vcpu->pio_pending = 1;
return 0;
}
diff --git a/drivers/kvm/vmx.c b/drivers/kvm/vmx.c
index 910535d..7fd572a 100644
--- a/drivers/kvm/vmx.c
+++ b/drivers/kvm/vmx.c
@@ -1465,6 +1465,7 @@ static int handle_io(struct kvm_vcpu *vcpu, struct kvm_run *kvm_run)
kvm_run->io.address = vmcs_readl(GUEST_LINEAR_ADDRESS);
} else
kvm_run->io.value = vcpu->regs[VCPU_REGS_RAX]; /* rax */
+ vcpu->pio_pending = 1;
return 0;
}
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index d88e750..19aeb33 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -11,7 +11,7 @@
#include <asm/types.h>
#include <linux/ioctl.h>
-#define KVM_API_VERSION 5
+#define KVM_API_VERSION 6
/*
* Architectural interrupt line count, and the size of the bitmap needed
@@ -53,7 +53,7 @@ enum kvm_exit_reason {
struct kvm_run {
/* in */
__u32 emulated; /* skip current instruction */
- __u32 mmio_completed; /* mmio request completed */
+ __u32 io_completed; /* mmio/pio request completed */
__u8 request_interrupt_window;
__u8 padding1[7];
@@ -80,7 +80,7 @@ struct kvm_run {
__u32 error_code;
} ex;
/* KVM_EXIT_IO */
- struct {
+ struct kvm_io {
#define KVM_EXIT_IO_IN 0
#define KVM_EXIT_IO_OUT 1
__u8 direction;
--
1.5.0.2
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys-and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
next prev parent reply other threads:[~2007-03-11 13:53 UTC|newest]
Thread overview: 31+ messages / expand[flat|nested] mbox.gz Atom feed top
2007-03-11 13:53 [PATCH 0/15] KVM userspace interface updates Avi Kivity
[not found] ` <11736212072915-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-03-11 13:53 ` [PATCH 01/15] KVM: Use a shared page for kernel/user communication when runing a vcpu Avi Kivity
[not found] ` <1173621207773-git-send-email-avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-03-15 2:38 ` Hollis Blanchard
2007-03-15 3:09 ` [kvm-devel] " Hollis Blanchard
2007-03-11 13:53 ` Avi Kivity [this message]
2007-03-11 13:53 ` [PATCH 03/15] KVM: Initialize PIO I/O count Avi Kivity
2007-03-11 13:53 ` [PATCH 04/15] KVM: Handle cpuid in the kernel instead of punting to userspace Avi Kivity
2007-03-11 13:53 ` [PATCH 05/15] KVM: Remove the 'emulated' field from the userspace interface Avi Kivity
2007-03-11 13:53 ` [PATCH 06/15] KVM: Remove minor wart from KVM_CREATE_VCPU ioctl Avi Kivity
2007-03-11 13:53 ` [PATCH 07/15] KVM: Renumber ioctls Avi Kivity
2007-03-11 13:53 ` [PATCH 08/15] KVM: Add method to check for backwards-compatible API extensions Avi Kivity
2007-03-16 15:06 ` [kvm-devel] " Heiko Carstens
[not found] ` <20070316150622.GC8525-Pmgahw53EmNLmI7Nx2oIsGnsbthNF6/HVpNB7YpNyf8@public.gmane.org>
2007-03-18 8:20 ` Avi Kivity
2007-03-11 13:53 ` [PATCH 09/15] KVM: Allow userspace to process hypercalls which have no kernel handler Avi Kivity
2007-03-11 13:53 ` [PATCH 10/15] KVM: Fold kvm_run::exit_type into kvm_run::exit_reason Avi Kivity
2007-03-11 13:53 ` [PATCH 11/15] KVM: Add a special exit reason when exiting due to an interrupt Avi Kivity
2007-03-11 13:53 ` [PATCH 12/15] KVM: Initialize the apic_base msr on svm too Avi Kivity
2007-03-11 13:53 ` [PATCH 13/15] KVM: Add guest mode signal mask Avi Kivity
2007-03-11 13:53 ` [PATCH 14/15] KVM: Allow kernel to select size of mmap() buffer Avi Kivity
2007-03-11 13:53 ` [PATCH 15/15] KVM: Future-proof argument-less ioctls Avi Kivity
2007-03-16 8:36 ` [PATCH 0/15] KVM userspace interface updates Heiko Carstens
2007-03-16 14:03 ` [kvm-devel] " Anthony Liguori
2007-03-16 15:01 ` Heiko Carstens
2007-03-18 10:42 ` Avi Kivity
[not found] ` <45FD1778.6030602-7k6+44Jx4zn6gbPvEgmw2w@public.gmane.org>
2007-03-19 15:43 ` Heiko Carstens
[not found] ` <20070319154311.GB8331-Pmgahw53EmNLmI7Nx2oIsGnsbthNF6/HVpNB7YpNyf8@public.gmane.org>
2007-03-19 16:02 ` Avi Kivity
2007-03-19 16:37 ` [kvm-devel] " Heiko Carstens
[not found] ` <45FEB431.8030504-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-03-19 17:49 ` Avi Kivity
[not found] ` <20070316083650.GA8525-Pmgahw53EmNLmI7Nx2oIsGnsbthNF6/HVpNB7YpNyf8@public.gmane.org>
2007-03-18 5:20 ` Avi Kivity
[not found] ` <45FCCC39.7090104-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2007-03-18 10:22 ` Heiko Carstens
2007-03-18 10:32 ` [kvm-devel] " Avi Kivity
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=11736212073047-git-send-email-avi@qumranet.com \
--to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
--cc=akpm-3NddpPZAyC0@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.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