On some cpus the overhead for virtualization instructions is in the same
range as a system call. Having to call multiple ioctls to get set registers
will make certain userspace handled exits more expensive than necessary.
Lets provide two sections in kvm_run to have a shared save area for
guest registers.
1. the first section is read-only, to handle registers that have side-effects
2. the second section is read/write, e.g. for general purpose registers.
We also provide two 64bit flags fields (architecture specific), that will
specify which parts of these fields are valid. Each bit will define that
a group of registers (like general purpose) or a single register is valid.
In that way we can extend and shrink the interface. (The structure definition
itself can only grow of course).

Signed-off-by: Christian Borntraeger <borntrae...@de.ibm.com>
---
 Documentation/virtual/kvm/api.txt |   28 ++++++++++++++++++++++++++++
 arch/ia64/include/asm/kvm.h       |    7 +++++++
 arch/powerpc/include/asm/kvm.h    |    7 +++++++
 arch/s390/include/asm/kvm.h       |    6 ++++++
 arch/x86/include/asm/kvm.h        |    7 +++++++
 include/linux/kvm.h               |   20 ++++++++++++++++++++
 6 files changed, 75 insertions(+), 0 deletions(-)

diff --git a/Documentation/virtual/kvm/api.txt 
b/Documentation/virtual/kvm/api.txt
index da1f8fd..a149e22 100644
--- a/Documentation/virtual/kvm/api.txt
+++ b/Documentation/virtual/kvm/api.txt
@@ -1693,6 +1693,34 @@ developer registration required to access it).
                /* Fix the size of the union. */
                char padding[256];
        };
+
+       /*
+        * Here are two fields that allow to access often used registers
+         * directly, to avoid the overhead of the ioctl system call. Each
+         * register can be extended or reduced by having flag bits specifying
+         * if a group of registers is valid.
+         */
+       __u64 kvm_valid_sync_ro_regs;
+       __u64 kvm_valid_sync_rw_regs;
+       union {
+               /* registers which can be only read */
+               struct kvm_sync_ro_regs sync_ro;
+               char padding[1024];
+       };
+       union {
+               /* read/write guest registers */
+               struct kvm_sync_rw_regs sync_rw;
+               char padding[1024];
+       };
+
+If KVM_CAP_SYNC_REGS is defined, these fields allow userspace to access
+certain guest registers without having to call SET/GET_*REGS. Thus we can
+avoid some system call overhead if userspace has to handle the exit.
+Userspace can query the validity of the structure by checking
+kvm_valid_sync_r[wo]_regs for specific bits. These bits are architecture
+specific and usually define the validity of a groups of registers. (e.g.
+one bit for general purpose registers)
+
 };
 
 6. Capabilities that can be enabled
diff --git a/arch/ia64/include/asm/kvm.h b/arch/ia64/include/asm/kvm.h
index bc90c75..bae1f1e 100644
--- a/arch/ia64/include/asm/kvm.h
+++ b/arch/ia64/include/asm/kvm.h
@@ -261,4 +261,11 @@ struct kvm_debug_exit_arch {
 struct kvm_guest_debug_arch {
 };
 
+/* definition of registers in kvm_run */
+struct kvm_sync_ro_regs {
+};
+
+struct kvm_sync_rw_regs {
+};
+
 #endif
diff --git a/arch/powerpc/include/asm/kvm.h b/arch/powerpc/include/asm/kvm.h
index f7727d9..14b766b 100644
--- a/arch/powerpc/include/asm/kvm.h
+++ b/arch/powerpc/include/asm/kvm.h
@@ -265,6 +265,13 @@ struct kvm_debug_exit_arch {
 struct kvm_guest_debug_arch {
 };
 
+/* definition of registers in kvm_run */
+struct kvm_sync_ro_regs {
+};
+
+struct kvm_sync_rw_regs {
+};
+
 #define KVM_REG_MASK           0x001f
 #define KVM_REG_EXT_MASK       0xffe0
 #define KVM_REG_GPR            0x0000
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h
index 82b32a1..dda27a0 100644
--- a/arch/s390/include/asm/kvm.h
+++ b/arch/s390/include/asm/kvm.h
@@ -41,4 +41,10 @@ struct kvm_debug_exit_arch {
 struct kvm_guest_debug_arch {
 };
 
+/* definition of registers in kvm_run */
+struct kvm_sync_ro_regs {
+};
+
+struct kvm_sync_rw_regs {
+};
 #endif
diff --git a/arch/x86/include/asm/kvm.h b/arch/x86/include/asm/kvm.h
index 4d8dcbd..fb32847 100644
--- a/arch/x86/include/asm/kvm.h
+++ b/arch/x86/include/asm/kvm.h
@@ -321,4 +321,11 @@ struct kvm_xcrs {
        __u64 padding[16];
 };
 
+/* definition of registers in kvm_run */
+struct kvm_sync_ro_regs {
+};
+
+struct kvm_sync_rw_regs {
+};
+
 #endif /* _ASM_X86_KVM_H */
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 68e67e5..9398672 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -273,6 +273,25 @@ struct kvm_run {
                /* Fix the size of the union. */
                char padding[256];
        };
+
+       /*
+        * Here are two fields that allow to access often used registers
+        * directly, to avoid the overhead of the ioctl system call. Each
+        * register can be extended or reduced by having flag bits specifying
+        * if a group of registers is valid.
+        */
+       __u64 kvm_valid_sync_ro_regs;
+       __u64 kvm_valid_sync_rw_regs;
+       union {
+               /* registers which can be only read */
+               struct kvm_sync_ro_regs sync_ro;
+               char padding[1024];
+       };
+       union {
+               /* read/write guest registers */
+               struct kvm_sync_rw_regs sync_rw;
+               char padding[1024];
+       };
 };
 
 /* for KVM_REGISTER_COALESCED_MMIO / KVM_UNREGISTER_COALESCED_MMIO */
@@ -558,6 +577,7 @@ struct kvm_ppc_pvinfo {
 #define KVM_CAP_PPC_PAPR 68
 #define KVM_CAP_S390_GMAP 71
 #define KVM_CAP_TSC_DEADLINE_TIMER 72
+#define KVM_CAP_SYNC_REGS 73
 
 #ifdef KVM_CAP_IRQ_ROUTING
 
-- 
1.7.8.2

--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to