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 <borntraeger@xxxxxxxxxx> --- 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html