All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC] allow userspace to set MSR no-ops
@ 2009-10-28 18:06 David Windsor
  0 siblings, 0 replies; 6+ messages in thread
From: David Windsor @ 2009-10-28 18:06 UTC (permalink / raw)
  To: kvm

Hi,

I've encountered a situation in which I would like to allow userspace
to set the MSRs which KVM should not emulate and instead implement
these as no-ops.

I have not seen any work in this space, furthermore there is an item
on the KVM TODO that is very similar to what I'm trying to do.

The userspace interface is an extension of kvm_vcpu_ioctl, adding the
KVM_SET_MSRS_NOOP flag.  It takes a struct kvm_msrs as a list of which
MSRs should be no-ops and adds the field noop to struct kvm_msr_entry.
 This patch only affects vmx, but if the approach is sane, I can
extend it to support svm as well.



diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm.h
linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h
--- linux-2.6.32-rc5/arch/x86/include/asm/kvm.h 2009-10-15
20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h   2009-10-27
22:44:58.000000000 -0400
@@ -144,6 +144,7 @@ struct kvm_msr_entry {
      __u32 index;
      __u32 reserved;
      __u64 data;
+       __u8 noop;
 };

 /* for KVM_GET_MSRS and KVM_SET_MSRS */
diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h
linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h
--- linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h    2009-10-15
20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h
 2009-10-27
22:44:58.000000000 -0400
@@ -481,6 +481,7 @@ struct kvm_x86_ops {
                             struct kvm_guest_debug *dbg);
      int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
      int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
+       int (*set_msr_noop)(struct kvm_vcpu *vcpu, u32 msr_index);
      u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
      void (*get_segment)(struct kvm_vcpu *vcpu,
                          struct kvm_segment *var, int seg);
diff -purN linux-2.6.32-rc5/arch/x86/kvm/vmx.c
linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c
--- linux-2.6.32-rc5/arch/x86/kvm/vmx.c 2009-10-15 20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c   2009-10-27
22:44:58.000000000 -0400
@@ -983,6 +983,13 @@ static int vmx_get_msr(struct kvm_vcpu *
              return -EINVAL;
      }

+       msr = find_msr_entry(to_vmx(vcpu), msr_index);
+       if (msr) {
+               if (msr->noop) {
+                       return 0;
+               }
+       }
+
      switch (msr_index) {
 #ifdef CONFIG_X86_64
      case MSR_FS_BASE:
@@ -1032,6 +1039,13 @@ static int vmx_set_msr(struct kvm_vcpu *
      u64 host_tsc;
      int ret = 0;

+       msr = find_msr_entry(to_vmx(vcpu), msr_index);
+       if (msr) {
+               if (msr->noop) {
+                       return ret;
+               }
+       }
+
      switch (msr_index) {
      case MSR_EFER:
              vmx_load_host_state(vmx);
@@ -1078,6 +1092,21 @@ static int vmx_set_msr(struct kvm_vcpu *
      return ret;
 }

+static int vmx_set_msr_noop(struct kvm_vcpu *vcpu, u32 msr)
+{
+       struct kvm_msr_entry *m;
+
+       if (!vcpu)
+               return -1;
+
+       m = find_msr_entry(to_vmx(vcpu), msr);
+       if (!m)
+               return -1;
+
+       m->noop = 1;
+       return 0;
+}
+
 static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
 {
      __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
@@ -3942,6 +3971,7 @@ static struct kvm_x86_ops vmx_x86_ops =
      .set_guest_debug = set_guest_debug,
      .get_msr = vmx_get_msr,
      .set_msr = vmx_set_msr,
+       .set_msr_noop = vmx_set_msr_noop,
      .get_segment_base = vmx_get_segment_base,
      .get_segment = vmx_get_segment,
      .set_segment = vmx_set_segment,
diff -purN linux-2.6.32-rc5/arch/x86/kvm/x86.c
linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c
--- linux-2.6.32-rc5/arch/x86/kvm/x86.c 2009-10-15 20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c   2009-10-27
22:44:58.000000000 -0400
@@ -975,6 +975,31 @@ int kvm_get_msr(struct kvm_vcpu *vcpu, u
      return kvm_x86_ops->get_msr(vcpu, msr_index, pdata);
 }

+static int kvm_set_msrs_noop(struct kvm_vcpu *vcpu, struct kvm_msrs
__user *user_msrs)
+{
+       int i, r;
+       int size;
+       struct kvm_msrs msrs;
+       struct kvm_msr_entry *entries;
+
+       if (copy_from_user(&msrs, user_msrs, sizeof msrs))
+               goto out;
+
+       size = sizeof(struct kvm_msr_entry) * msrs.nmsrs;
+       if (copy_from_user(entries, user_msrs->entries, size))
+               goto out;
+
+       for (i = 0; i < msrs.nmsrs; i++) {
+               r = kvm_x86_ops->set_msr_noop(vcpu, entries[i].index);
+               if (r)
+                       goto out;
+       }
+
+       return 0;
+out:
+       return -1;
+}
+
 static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 {
      u64 *p = (u64 *)&vcpu->arch.mtrr_state.fixed_ranges;
@@ -1864,6 +1889,9 @@ long kvm_arch_vcpu_ioctl(struct file *fi
      case KVM_SET_MSRS:
              r = msr_io(vcpu, argp, do_set_msr, 0);
              break;
+       case KVM_SET_MSRS_NOOP:
+               r = kvm_set_msrs_noop(vcpu, argp);
+               break;
      case KVM_TPR_ACCESS_REPORTING: {
              struct kvm_tpr_access_ctl tac;

diff -purN linux-2.6.32-rc5/include/linux/kvm.h
linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h
--- linux-2.6.32-rc5/include/linux/kvm.h        2009-10-15
20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h  2009-10-27
22:46:36.000000000 -0400
@@ -593,6 +593,7 @@ struct kvm_irqfd {
 #define KVM_X86_SETUP_MCE         _IOW(KVMIO,  0x9c, __u64)
 #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO,  0x9d, __u64)
 #define KVM_X86_SET_MCE           _IOW(KVMIO,  0x9e, struct kvm_x86_mce)
+#define KVM_SET_MSRS_NOOP        _IOW(KVMIO, 0x9f, struct kvm_msrs)

 /*
 * Deprecated interfaces


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC] allow userspace to set MSR no-ops
  2009-11-03 15:12 ` Marcelo Tosatti
@ 2009-11-04  9:10   ` Avi Kivity
  0 siblings, 0 replies; 6+ messages in thread
From: Avi Kivity @ 2009-11-04  9:10 UTC (permalink / raw)
  To: Marcelo Tosatti; +Cc: David Windsor, kvm

On 11/03/2009 05:12 PM, Marcelo Tosatti wrote:
> On Wed, Oct 28, 2009 at 01:23:07PM -0400, David Windsor wrote:
>    
>> Hi,
>>
>> I've encountered a situation in which I would like to allow userspace
>> to set the MSRs which KVM should not emulate and instead implement
>> these as no-ops.
>>
>> I have not seen any work in this space, furthermore there is an item
>> on the KVM TODO that is very similar to what I'm trying to do.
>>
>> The userspace interface is an extension of kvm_vcpu_ioctl, adding the
>> KVM_SET_MSRS_NOOP flag.  It takes a struct kvm_msrs as a list of which
>> MSRs should be no-ops and adds the field noop to struct kvm_msr_entry.
>>   This patch only affects vmx, but if the approach is sane, I can
>> extend it to support svm as well.
>>      
> Does the ignore_msrs kvm.ko parameter achieve what you want?
>
>    

Ah, I forgot all about that.

-- 
error compiling committee.c: too many arguments to function


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC] allow userspace to set MSR no-ops
  2009-10-28 17:23 David Windsor
  2009-10-28 18:31 ` Richard Winthers
       [not found] ` <944f46790910281128j345c13adre8d0dc533bc4abb1@mail.gmail.com>
@ 2009-11-03 15:12 ` Marcelo Tosatti
  2009-11-04  9:10   ` Avi Kivity
  2 siblings, 1 reply; 6+ messages in thread
From: Marcelo Tosatti @ 2009-11-03 15:12 UTC (permalink / raw)
  To: David Windsor; +Cc: kvm

On Wed, Oct 28, 2009 at 01:23:07PM -0400, David Windsor wrote:
> Hi,
> 
> I've encountered a situation in which I would like to allow userspace
> to set the MSRs which KVM should not emulate and instead implement
> these as no-ops.
> 
> I have not seen any work in this space, furthermore there is an item
> on the KVM TODO that is very similar to what I'm trying to do.
> 
> The userspace interface is an extension of kvm_vcpu_ioctl, adding the
> KVM_SET_MSRS_NOOP flag.  It takes a struct kvm_msrs as a list of which
> MSRs should be no-ops and adds the field noop to struct kvm_msr_entry.
>  This patch only affects vmx, but if the approach is sane, I can
> extend it to support svm as well.

Does the ignore_msrs kvm.ko parameter achieve what you want?


^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC] allow userspace to set MSR no-ops
       [not found] ` <944f46790910281128j345c13adre8d0dc533bc4abb1@mail.gmail.com>
@ 2009-10-28 21:04   ` David Windsor
  0 siblings, 0 replies; 6+ messages in thread
From: David Windsor @ 2009-10-28 21:04 UTC (permalink / raw)
  To: Richard Winthers; +Cc: kvm

It is intended to be used only during startup, typically by a launcher
that is aware which MSRs should be emulated as no-ops.

On Wed, Oct 28, 2009 at 2:28 PM, Richard Winthers <rwinthers@gmail.com> wrote:
> Is this interface supposed to support changing MSR handing at runtime or is
> the ioctl only meant to be called prior to KVM_RUN?
> Thanks,
> Richard
> On Wed, Oct 28, 2009 at 1:23 PM, David Windsor <dwindsor@gmail.com> wrote:
>>
>> Hi,
>>
>> I've encountered a situation in which I would like to allow userspace
>> to set the MSRs which KVM should not emulate and instead implement
>> these as no-ops.
>>
>> I have not seen any work in this space, furthermore there is an item
>> on the KVM TODO that is very similar to what I'm trying to do.
>>
>> The userspace interface is an extension of kvm_vcpu_ioctl, adding the
>> KVM_SET_MSRS_NOOP flag.  It takes a struct kvm_msrs as a list of which
>> MSRs should be no-ops and adds the field noop to struct kvm_msr_entry.
>>  This patch only affects vmx, but if the approach is sane, I can
>> extend it to support svm as well.
>>
>>
>>
>> diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm.h
>> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h
>> --- linux-2.6.32-rc5/arch/x86/include/asm/kvm.h 2009-10-15
>> 20:41:50.000000000 -0400
>> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h   2009-10-27
>> 22:44:58.000000000 -0400
>> @@ -144,6 +144,7 @@ struct kvm_msr_entry {
>>       __u32 index;
>>       __u32 reserved;
>>       __u64 data;
>> +       __u8 noop;
>>  };
>>
>>  /* for KVM_GET_MSRS and KVM_SET_MSRS */
>> diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h
>> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h
>> --- linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h    2009-10-15
>> 20:41:50.000000000 -0400
>> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h
>>  2009-10-27
>> 22:44:58.000000000 -0400
>> @@ -481,6 +481,7 @@ struct kvm_x86_ops {
>>                              struct kvm_guest_debug *dbg);
>>       int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
>>       int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
>> +       int (*set_msr_noop)(struct kvm_vcpu *vcpu, u32 msr_index);
>>       u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
>>       void (*get_segment)(struct kvm_vcpu *vcpu,
>>                           struct kvm_segment *var, int seg);
>> diff -purN linux-2.6.32-rc5/arch/x86/kvm/vmx.c
>> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c
>> --- linux-2.6.32-rc5/arch/x86/kvm/vmx.c 2009-10-15 20:41:50.000000000
>> -0400
>> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c   2009-10-27
>> 22:44:58.000000000 -0400
>> @@ -983,6 +983,13 @@ static int vmx_get_msr(struct kvm_vcpu *
>>               return -EINVAL;
>>       }
>>
>> +       msr = find_msr_entry(to_vmx(vcpu), msr_index);
>> +       if (msr) {
>> +               if (msr->noop) {
>> +                       return 0;
>> +               }
>> +       }
>> +
>>       switch (msr_index) {
>>  #ifdef CONFIG_X86_64
>>       case MSR_FS_BASE:
>> @@ -1032,6 +1039,13 @@ static int vmx_set_msr(struct kvm_vcpu *
>>       u64 host_tsc;
>>       int ret = 0;
>>
>> +       msr = find_msr_entry(to_vmx(vcpu), msr_index);
>> +       if (msr) {
>> +               if (msr->noop) {
>> +                       return ret;
>> +               }
>> +       }
>> +
>>       switch (msr_index) {
>>       case MSR_EFER:
>>               vmx_load_host_state(vmx);
>> @@ -1078,6 +1092,21 @@ static int vmx_set_msr(struct kvm_vcpu *
>>       return ret;
>>  }
>>
>> +static int vmx_set_msr_noop(struct kvm_vcpu *vcpu, u32 msr)
>> +{
>> +       struct kvm_msr_entry *m;
>> +
>> +       if (!vcpu)
>> +               return -1;
>> +
>> +       m = find_msr_entry(to_vmx(vcpu), msr);
>> +       if (!m)
>> +               return -1;
>> +
>> +       m->noop = 1;
>> +       return 0;
>> +}
>> +
>>  static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
>>  {
>>       __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
>> @@ -3942,6 +3971,7 @@ static struct kvm_x86_ops vmx_x86_ops =
>>       .set_guest_debug = set_guest_debug,
>>       .get_msr = vmx_get_msr,
>>       .set_msr = vmx_set_msr,
>> +       .set_msr_noop = vmx_set_msr_noop,
>>       .get_segment_base = vmx_get_segment_base,
>>       .get_segment = vmx_get_segment,
>>       .set_segment = vmx_set_segment,
>> diff -purN linux-2.6.32-rc5/arch/x86/kvm/x86.c
>> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c
>> --- linux-2.6.32-rc5/arch/x86/kvm/x86.c 2009-10-15 20:41:50.000000000
>> -0400
>> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c   2009-10-27
>> 22:44:58.000000000 -0400
>> @@ -975,6 +975,31 @@ int kvm_get_msr(struct kvm_vcpu *vcpu, u
>>       return kvm_x86_ops->get_msr(vcpu, msr_index, pdata);
>>  }
>>
>> +static int kvm_set_msrs_noop(struct kvm_vcpu *vcpu, struct kvm_msrs
>> __user *user_msrs)
>> +{
>> +       int i, r;
>> +       int size;
>> +       struct kvm_msrs msrs;
>> +       struct kvm_msr_entry *entries;
>> +
>> +       if (copy_from_user(&msrs, user_msrs, sizeof msrs))
>> +               goto out;
>> +
>> +       size = sizeof(struct kvm_msr_entry) * msrs.nmsrs;
>> +       if (copy_from_user(entries, user_msrs->entries, size))
>> +               goto out;
>> +
>> +       for (i = 0; i < msrs.nmsrs; i++) {
>> +               r = kvm_x86_ops->set_msr_noop(vcpu, entries[i].index);
>> +               if (r)
>> +                       goto out;
>> +       }
>> +
>> +       return 0;
>> +out:
>> +       return -1;
>> +}
>> +
>>  static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
>>  {
>>       u64 *p = (u64 *)&vcpu->arch.mtrr_state.fixed_ranges;
>> @@ -1864,6 +1889,9 @@ long kvm_arch_vcpu_ioctl(struct file *fi
>>       case KVM_SET_MSRS:
>>               r = msr_io(vcpu, argp, do_set_msr, 0);
>>               break;
>> +       case KVM_SET_MSRS_NOOP:
>> +               r = kvm_set_msrs_noop(vcpu, argp);
>> +               break;
>>       case KVM_TPR_ACCESS_REPORTING: {
>>               struct kvm_tpr_access_ctl tac;
>>
>> diff -purN linux-2.6.32-rc5/include/linux/kvm.h
>> linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h
>> --- linux-2.6.32-rc5/include/linux/kvm.h        2009-10-15
>> 20:41:50.000000000 -0400
>> +++ linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h  2009-10-27
>> 22:46:36.000000000 -0400
>> @@ -593,6 +593,7 @@ struct kvm_irqfd {
>>  #define KVM_X86_SETUP_MCE         _IOW(KVMIO,  0x9c, __u64)
>>  #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO,  0x9d, __u64)
>>  #define KVM_X86_SET_MCE           _IOW(KVMIO,  0x9e, struct kvm_x86_mce)
>> +#define KVM_SET_MSRS_NOOP        _IOW(KVMIO, 0x9f, struct kvm_msrs)
>>
>>  /*
>>  * Deprecated interfaces
>> --
>> To unsubscribe from this list: send the line "unsubscribe kvm" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [RFC] allow userspace to set MSR no-ops
  2009-10-28 17:23 David Windsor
@ 2009-10-28 18:31 ` Richard Winthers
       [not found] ` <944f46790910281128j345c13adre8d0dc533bc4abb1@mail.gmail.com>
  2009-11-03 15:12 ` Marcelo Tosatti
  2 siblings, 0 replies; 6+ messages in thread
From: Richard Winthers @ 2009-10-28 18:31 UTC (permalink / raw)
  To: David Windsor; +Cc: kvm

Is this interface supposed to support changing MSR handing at runtime
or is the ioctl only meant to be called prior to KVM_RUN?

Thanks,
Richard

On Wed, Oct 28, 2009 at 1:23 PM, David Windsor <dwindsor@gmail.com> wrote:
>
> Hi,
>
> I've encountered a situation in which I would like to allow userspace
> to set the MSRs which KVM should not emulate and instead implement
> these as no-ops.
>
> I have not seen any work in this space, furthermore there is an item
> on the KVM TODO that is very similar to what I'm trying to do.
>
> The userspace interface is an extension of kvm_vcpu_ioctl, adding the
> KVM_SET_MSRS_NOOP flag.  It takes a struct kvm_msrs as a list of which
> MSRs should be no-ops and adds the field noop to struct kvm_msr_entry.
>  This patch only affects vmx, but if the approach is sane, I can
> extend it to support svm as well.
>
>
>
> diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm.h
> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h
> --- linux-2.6.32-rc5/arch/x86/include/asm/kvm.h 2009-10-15
> 20:41:50.000000000 -0400
> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h   2009-10-27
> 22:44:58.000000000 -0400
> @@ -144,6 +144,7 @@ struct kvm_msr_entry {
>       __u32 index;
>       __u32 reserved;
>       __u64 data;
> +       __u8 noop;
>  };
>
>  /* for KVM_GET_MSRS and KVM_SET_MSRS */
> diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h
> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h
> --- linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h    2009-10-15
> 20:41:50.000000000 -0400
> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h
>  2009-10-27
> 22:44:58.000000000 -0400
> @@ -481,6 +481,7 @@ struct kvm_x86_ops {
>                              struct kvm_guest_debug *dbg);
>       int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
>       int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
> +       int (*set_msr_noop)(struct kvm_vcpu *vcpu, u32 msr_index);
>       u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
>       void (*get_segment)(struct kvm_vcpu *vcpu,
>                           struct kvm_segment *var, int seg);
> diff -purN linux-2.6.32-rc5/arch/x86/kvm/vmx.c
> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c
> --- linux-2.6.32-rc5/arch/x86/kvm/vmx.c 2009-10-15 20:41:50.000000000 -0400
> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c   2009-10-27
> 22:44:58.000000000 -0400
> @@ -983,6 +983,13 @@ static int vmx_get_msr(struct kvm_vcpu *
>               return -EINVAL;
>       }
>
> +       msr = find_msr_entry(to_vmx(vcpu), msr_index);
> +       if (msr) {
> +               if (msr->noop) {
> +                       return 0;
> +               }
> +       }
> +
>       switch (msr_index) {
>  #ifdef CONFIG_X86_64
>       case MSR_FS_BASE:
> @@ -1032,6 +1039,13 @@ static int vmx_set_msr(struct kvm_vcpu *
>       u64 host_tsc;
>       int ret = 0;
>
> +       msr = find_msr_entry(to_vmx(vcpu), msr_index);
> +       if (msr) {
> +               if (msr->noop) {
> +                       return ret;
> +               }
> +       }
> +
>       switch (msr_index) {
>       case MSR_EFER:
>               vmx_load_host_state(vmx);
> @@ -1078,6 +1092,21 @@ static int vmx_set_msr(struct kvm_vcpu *
>       return ret;
>  }
>
> +static int vmx_set_msr_noop(struct kvm_vcpu *vcpu, u32 msr)
> +{
> +       struct kvm_msr_entry *m;
> +
> +       if (!vcpu)
> +               return -1;
> +
> +       m = find_msr_entry(to_vmx(vcpu), msr);
> +       if (!m)
> +               return -1;
> +
> +       m->noop = 1;
> +       return 0;
> +}
> +
>  static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
>  {
>       __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
> @@ -3942,6 +3971,7 @@ static struct kvm_x86_ops vmx_x86_ops =
>       .set_guest_debug = set_guest_debug,
>       .get_msr = vmx_get_msr,
>       .set_msr = vmx_set_msr,
> +       .set_msr_noop = vmx_set_msr_noop,
>       .get_segment_base = vmx_get_segment_base,
>       .get_segment = vmx_get_segment,
>       .set_segment = vmx_set_segment,
> diff -purN linux-2.6.32-rc5/arch/x86/kvm/x86.c
> linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c
> --- linux-2.6.32-rc5/arch/x86/kvm/x86.c 2009-10-15 20:41:50.000000000 -0400
> +++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c   2009-10-27
> 22:44:58.000000000 -0400
> @@ -975,6 +975,31 @@ int kvm_get_msr(struct kvm_vcpu *vcpu, u
>       return kvm_x86_ops->get_msr(vcpu, msr_index, pdata);
>  }
>
> +static int kvm_set_msrs_noop(struct kvm_vcpu *vcpu, struct kvm_msrs
> __user *user_msrs)
> +{
> +       int i, r;
> +       int size;
> +       struct kvm_msrs msrs;
> +       struct kvm_msr_entry *entries;
> +
> +       if (copy_from_user(&msrs, user_msrs, sizeof msrs))
> +               goto out;
> +
> +       size = sizeof(struct kvm_msr_entry) * msrs.nmsrs;
> +       if (copy_from_user(entries, user_msrs->entries, size))
> +               goto out;
> +
> +       for (i = 0; i < msrs.nmsrs; i++) {
> +               r = kvm_x86_ops->set_msr_noop(vcpu, entries[i].index);
> +               if (r)
> +                       goto out;
> +       }
> +
> +       return 0;
> +out:
> +       return -1;
> +}
> +
>  static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
>  {
>       u64 *p = (u64 *)&vcpu->arch.mtrr_state.fixed_ranges;
> @@ -1864,6 +1889,9 @@ long kvm_arch_vcpu_ioctl(struct file *fi
>       case KVM_SET_MSRS:
>               r = msr_io(vcpu, argp, do_set_msr, 0);
>               break;
> +       case KVM_SET_MSRS_NOOP:
> +               r = kvm_set_msrs_noop(vcpu, argp);
> +               break;
>       case KVM_TPR_ACCESS_REPORTING: {
>               struct kvm_tpr_access_ctl tac;
>
> diff -purN linux-2.6.32-rc5/include/linux/kvm.h
> linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h
> --- linux-2.6.32-rc5/include/linux/kvm.h        2009-10-15
> 20:41:50.000000000 -0400
> +++ linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h  2009-10-27
> 22:46:36.000000000 -0400
> @@ -593,6 +593,7 @@ struct kvm_irqfd {
>  #define KVM_X86_SETUP_MCE         _IOW(KVMIO,  0x9c, __u64)
>  #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO,  0x9d, __u64)
>  #define KVM_X86_SET_MCE           _IOW(KVMIO,  0x9e, struct kvm_x86_mce)
> +#define KVM_SET_MSRS_NOOP        _IOW(KVMIO, 0x9f, struct kvm_msrs)
>
>  /*
>  * Deprecated interfaces
> --
> To unsubscribe from this list: send the line "unsubscribe kvm" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [RFC] allow userspace to set MSR no-ops
@ 2009-10-28 17:23 David Windsor
  2009-10-28 18:31 ` Richard Winthers
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: David Windsor @ 2009-10-28 17:23 UTC (permalink / raw)
  To: kvm

Hi,

I've encountered a situation in which I would like to allow userspace
to set the MSRs which KVM should not emulate and instead implement
these as no-ops.

I have not seen any work in this space, furthermore there is an item
on the KVM TODO that is very similar to what I'm trying to do.

The userspace interface is an extension of kvm_vcpu_ioctl, adding the
KVM_SET_MSRS_NOOP flag.  It takes a struct kvm_msrs as a list of which
MSRs should be no-ops and adds the field noop to struct kvm_msr_entry.
 This patch only affects vmx, but if the approach is sane, I can
extend it to support svm as well.



diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm.h
linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h
--- linux-2.6.32-rc5/arch/x86/include/asm/kvm.h 2009-10-15
20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm.h   2009-10-27
22:44:58.000000000 -0400
@@ -144,6 +144,7 @@ struct kvm_msr_entry {
       __u32 index;
       __u32 reserved;
       __u64 data;
+       __u8 noop;
 };

 /* for KVM_GET_MSRS and KVM_SET_MSRS */
diff -purN linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h
linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h
--- linux-2.6.32-rc5/arch/x86/include/asm/kvm_host.h    2009-10-15
20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/include/asm/kvm_host.h
 2009-10-27
22:44:58.000000000 -0400
@@ -481,6 +481,7 @@ struct kvm_x86_ops {
                              struct kvm_guest_debug *dbg);
       int (*get_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 *pdata);
       int (*set_msr)(struct kvm_vcpu *vcpu, u32 msr_index, u64 data);
+       int (*set_msr_noop)(struct kvm_vcpu *vcpu, u32 msr_index);
       u64 (*get_segment_base)(struct kvm_vcpu *vcpu, int seg);
       void (*get_segment)(struct kvm_vcpu *vcpu,
                           struct kvm_segment *var, int seg);
diff -purN linux-2.6.32-rc5/arch/x86/kvm/vmx.c
linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c
--- linux-2.6.32-rc5/arch/x86/kvm/vmx.c 2009-10-15 20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/vmx.c   2009-10-27
22:44:58.000000000 -0400
@@ -983,6 +983,13 @@ static int vmx_get_msr(struct kvm_vcpu *
               return -EINVAL;
       }

+       msr = find_msr_entry(to_vmx(vcpu), msr_index);
+       if (msr) {
+               if (msr->noop) {
+                       return 0;
+               }
+       }
+
       switch (msr_index) {
 #ifdef CONFIG_X86_64
       case MSR_FS_BASE:
@@ -1032,6 +1039,13 @@ static int vmx_set_msr(struct kvm_vcpu *
       u64 host_tsc;
       int ret = 0;

+       msr = find_msr_entry(to_vmx(vcpu), msr_index);
+       if (msr) {
+               if (msr->noop) {
+                       return ret;
+               }
+       }
+
       switch (msr_index) {
       case MSR_EFER:
               vmx_load_host_state(vmx);
@@ -1078,6 +1092,21 @@ static int vmx_set_msr(struct kvm_vcpu *
       return ret;
 }

+static int vmx_set_msr_noop(struct kvm_vcpu *vcpu, u32 msr)
+{
+       struct kvm_msr_entry *m;
+
+       if (!vcpu)
+               return -1;
+
+       m = find_msr_entry(to_vmx(vcpu), msr);
+       if (!m)
+               return -1;
+
+       m->noop = 1;
+       return 0;
+}
+
 static void vmx_cache_reg(struct kvm_vcpu *vcpu, enum kvm_reg reg)
 {
       __set_bit(reg, (unsigned long *)&vcpu->arch.regs_avail);
@@ -3942,6 +3971,7 @@ static struct kvm_x86_ops vmx_x86_ops =
       .set_guest_debug = set_guest_debug,
       .get_msr = vmx_get_msr,
       .set_msr = vmx_set_msr,
+       .set_msr_noop = vmx_set_msr_noop,
       .get_segment_base = vmx_get_segment_base,
       .get_segment = vmx_get_segment,
       .set_segment = vmx_set_segment,
diff -purN linux-2.6.32-rc5/arch/x86/kvm/x86.c
linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c
--- linux-2.6.32-rc5/arch/x86/kvm/x86.c 2009-10-15 20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/arch/x86/kvm/x86.c   2009-10-27
22:44:58.000000000 -0400
@@ -975,6 +975,31 @@ int kvm_get_msr(struct kvm_vcpu *vcpu, u
       return kvm_x86_ops->get_msr(vcpu, msr_index, pdata);
 }

+static int kvm_set_msrs_noop(struct kvm_vcpu *vcpu, struct kvm_msrs
__user *user_msrs)
+{
+       int i, r;
+       int size;
+       struct kvm_msrs msrs;
+       struct kvm_msr_entry *entries;
+
+       if (copy_from_user(&msrs, user_msrs, sizeof msrs))
+               goto out;
+
+       size = sizeof(struct kvm_msr_entry) * msrs.nmsrs;
+       if (copy_from_user(entries, user_msrs->entries, size))
+               goto out;
+
+       for (i = 0; i < msrs.nmsrs; i++) {
+               r = kvm_x86_ops->set_msr_noop(vcpu, entries[i].index);
+               if (r)
+                       goto out;
+       }
+
+       return 0;
+out:
+       return -1;
+}
+
 static int get_msr_mtrr(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
 {
       u64 *p = (u64 *)&vcpu->arch.mtrr_state.fixed_ranges;
@@ -1864,6 +1889,9 @@ long kvm_arch_vcpu_ioctl(struct file *fi
       case KVM_SET_MSRS:
               r = msr_io(vcpu, argp, do_set_msr, 0);
               break;
+       case KVM_SET_MSRS_NOOP:
+               r = kvm_set_msrs_noop(vcpu, argp);
+               break;
       case KVM_TPR_ACCESS_REPORTING: {
               struct kvm_tpr_access_ctl tac;

diff -purN linux-2.6.32-rc5/include/linux/kvm.h
linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h
--- linux-2.6.32-rc5/include/linux/kvm.h        2009-10-15
20:41:50.000000000 -0400
+++ linux-2.6.32-rc5-kvm-msrs-noop/include/linux/kvm.h  2009-10-27
22:46:36.000000000 -0400
@@ -593,6 +593,7 @@ struct kvm_irqfd {
 #define KVM_X86_SETUP_MCE         _IOW(KVMIO,  0x9c, __u64)
 #define KVM_X86_GET_MCE_CAP_SUPPORTED _IOR(KVMIO,  0x9d, __u64)
 #define KVM_X86_SET_MCE           _IOW(KVMIO,  0x9e, struct kvm_x86_mce)
+#define KVM_SET_MSRS_NOOP        _IOW(KVMIO, 0x9f, struct kvm_msrs)

 /*
 * Deprecated interfaces

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-11-04  9:10 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-10-28 18:06 [RFC] allow userspace to set MSR no-ops David Windsor
  -- strict thread matches above, loose matches on Subject: below --
2009-10-28 17:23 David Windsor
2009-10-28 18:31 ` Richard Winthers
     [not found] ` <944f46790910281128j345c13adre8d0dc533bc4abb1@mail.gmail.com>
2009-10-28 21:04   ` David Windsor
2009-11-03 15:12 ` Marcelo Tosatti
2009-11-04  9:10   ` Avi Kivity

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.