On Wed, Sep 16, 2009 at 03:45:33PM +0300, Avi Kivity wrote: > The various syscall-related MSRs are fairly expensive to switch. Currently > we switch them on every vcpu preemption, which is far too often: > > - if we're switching to a kernel thread (idle task, threaded interrupt, > kernel-mode virtio server (vhost-net), for example) and back, then > there's no need to switch those MSRs since kernel threasd won't > be exiting to userspace. > > - if we're switching to another guest running an identical OS, most likely > those MSRs will have the same value, so there's little point in reloading > them. > > - if we're running the same OS on the guest and host, the MSRs will have > identical values and reloading is unnecessary. > > This patch uses the new user return notifiers to implement last-minute > switching, and checks the msr values to avoid unnecessary reloading. > > Signed-off-by: Avi Kivity <avi@xxxxxxxxxx> > --- > arch/x86/include/asm/kvm_host.h | 3 + > arch/x86/kvm/Kconfig | 1 + > arch/x86/kvm/x86.c | 79 +++++++++++++++++++++++++++++++++++++++ > 3 files changed, 83 insertions(+), 0 deletions(-) > > diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h > index 45226f0..863bde8 100644 > --- a/arch/x86/include/asm/kvm_host.h > +++ b/arch/x86/include/asm/kvm_host.h > @@ -799,4 +799,7 @@ int kvm_cpu_has_interrupt(struct kvm_vcpu *vcpu); > int kvm_arch_interrupt_allowed(struct kvm_vcpu *vcpu); > int kvm_cpu_get_interrupt(struct kvm_vcpu *v); > > +void kvm_define_shared_msr(unsigned index, u32 msr); > +void kvm_set_shared_msr(unsigned index, u64 val); > + > #endif /* _ASM_X86_KVM_HOST_H */ > diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig > index b84e571..4cd4983 100644 > --- a/arch/x86/kvm/Kconfig > +++ b/arch/x86/kvm/Kconfig > @@ -28,6 +28,7 @@ config KVM > select HAVE_KVM_IRQCHIP > select HAVE_KVM_EVENTFD > select KVM_APIC_ARCHITECTURE > + select USER_RETURN_NOTIFIER > ---help--- > Support hosting fully virtualized guest machines using hardware > virtualization extensions. You will need a fairly recent > diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c > index 1d454d9..0e7c40c 100644 > --- a/arch/x86/kvm/x86.c > +++ b/arch/x86/kvm/x86.c > @@ -37,6 +37,7 @@ > #include <linux/iommu.h> > #include <linux/intel-iommu.h> > #include <linux/cpufreq.h> > +#include <linux/user-return-notifier.h> > #include <trace/events/kvm.h> > #undef TRACE_INCLUDE_FILE > #define CREATE_TRACE_POINTS > @@ -87,6 +88,25 @@ EXPORT_SYMBOL_GPL(kvm_x86_ops); > int ignore_msrs = 0; > module_param_named(ignore_msrs, ignore_msrs, bool, S_IRUGO | S_IWUSR); > > +#define KVM_NR_SHARED_MSRS 16 > + > +struct kvm_shared_msrs_global { > + int nr; > + struct kvm_shared_msr { > + u32 msr; > + u64 value; > + } msrs[KVM_NR_SHARED_MSRS]; > +}; > + > +struct kvm_shared_msrs { > + struct user_return_notifier urn; > + bool registered; > + u64 current_value[KVM_NR_SHARED_MSRS]; > +}; > + > +static struct kvm_shared_msrs_global __read_mostly shared_msrs_global; Does this assume the MSRs in question are consistent across CPUs? I guess that is not true with arch_prctl(ARCH_SET_GS/ARCH_GET_GS) ? -- 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