[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [PATCH v11 1/9] x86: add generic MSR access hypercall



> -----Original Message-----
> From: Andrew Cooper [mailto:andrew.cooper3@xxxxxxxxxx]
> Sent: Friday, June 20, 2014 10:57 PM
> To: Xu, Dongxiao; xen-devel@xxxxxxxxxxxxx
> Cc: keir@xxxxxxx; JBeulich@xxxxxxxx; Ian.Jackson@xxxxxxxxxxxxx;
> Ian.Campbell@xxxxxxxxxx; stefano.stabellini@xxxxxxxxxxxxx;
> konrad.wilk@xxxxxxxxxx; dgdegra@xxxxxxxxxxxxx;
> George.Dunlap@xxxxxxxxxxxxx
> Subject: Re: [PATCH v11 1/9] x86: add generic MSR access hypercall
> 
> On 20/06/14 15:31, Dongxiao Xu wrote:
> > Add a generic MSR access hypercall for tool stack or other components to
> > read or write certain system MSRs.
> >
> > Signed-off-by: Dongxiao Xu <dongxiao.xu@xxxxxxxxx>
> > ---
> >  xen/arch/x86/sysctl.c       | 54
> +++++++++++++++++++++++++++++++++++++++++++++
> >  xen/include/public/sysctl.h | 25 +++++++++++++++++++++
> >  2 files changed, 79 insertions(+)
> >
> > diff --git a/xen/arch/x86/sysctl.c b/xen/arch/x86/sysctl.c
> > index 15d4b91..49f95e4 100644
> > --- a/xen/arch/x86/sysctl.c
> > +++ b/xen/arch/x86/sysctl.c
> > @@ -66,10 +66,27 @@ void arch_do_physinfo(xen_sysctl_physinfo_t *pi)
> >          pi->capabilities |= XEN_SYSCTL_PHYSCAP_hvm_directio;
> >  }
> >
> > +static void msr_access_helper(void *data)
> > +{
> > +    struct msr_access_info *info = data;
> > +    xen_sysctl_msr_data_t *msr_data;
> > +    unsigned int i;
> > +
> > +    for ( i = 0; i < info->nr_ops; i++ )
> > +    {
> > +        msr_data = &info->msr_data[i];
> > +        if ( msr_data->cmd == XEN_SYSCTL_MSR_read )
> > +            rdmsrl(msr_data->msr, msr_data->val);
> > +        else if ( msr_data->cmd == XEN_SYSCTL_MSR_write )
> > +            wrmsrl(msr_data->msr, msr_data->val);
> 
> These must be the _safe() variants, otherwise it is trivial for a
> privileged domain to cause Xen to die with #GP faults.

Okay, thanks!

> 
> > +    }
> > +}
> > +
> >  long arch_do_sysctl(
> >      struct xen_sysctl *sysctl, XEN_GUEST_HANDLE_PARAM(xen_sysctl_t)
> u_sysctl)
> >  {
> >      long ret = 0;
> > +    bool_t copyback = 0;
> >
> >      switch ( sysctl->cmd )
> >      {
> > @@ -101,11 +118,48 @@ long arch_do_sysctl(
> >      }
> >      break;
> >
> > +    case XEN_SYSCTL_msr_op:
> > +    {
> > +        unsigned int cpu = sysctl->u.msr_op.cpu;
> > +        struct msr_access_info info;
> > +
> > +        info.nr_ops = sysctl->u.msr_op.nr_ops;
> > +        info.msr_data = xzalloc_array(xen_sysctl_msr_data_t, info.nr_ops);
> 
> This memory allocation can be avoided.  Do a copy_from_user() on the
> msr_op structure and pass the guest handle and nr into msr_access_helper().
> 
> It can then do copy_to/from_user on the individual entries.

This implementation pack all operations together towards one CPU. Jan is 
suggesting if we can specify one CPU for each operation.
If that's the case, I will think about whether we can eliminate the memory 
allocation here.

> 
> > +        if ( !info.msr_data )
> > +            return -ENOMEM;
> > +
> > +        if ( copy_from_guest(info.msr_data, sysctl->u.msr_op.msr_data,
> > +                             info.nr_ops) )
> > +        {
> > +            xfree(info.msr_data);
> > +            return -EFAULT;
> > +        }
> > +
> > +        if ( cpu == smp_processor_id() )
> > +            msr_access_helper(&info);
> > +        else
> > +            on_selected_cpus(cpumask_of(cpu), msr_access_helper, &info,
> 1);
> > +
> > +        if ( copy_to_guest(sysctl->u.msr_op.msr_data, info.msr_data,
> > +                           info.nr_ops ) )
> > +        {
> > +            xfree(info.msr_data);
> > +            return -EFAULT;
> > +        }
> > +
> > +        xfree(info.msr_data);
> > +        copyback = 1;
> > +    }
> > +    break;
> > +
> >      default:
> >          ret = -ENOSYS;
> >          break;
> >      }
> >
> > +    if ( copyback && __copy_to_guest(u_sysctl, sysctl, 1) )
> > +        ret = -EFAULT;
> > +
> >      return ret;
> >  }
> >
> > diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
> > index 3588698..fd042bb 100644
> > --- a/xen/include/public/sysctl.h
> > +++ b/xen/include/public/sysctl.h
> > @@ -636,6 +636,29 @@ struct xen_sysctl_coverage_op {
> >  typedef struct xen_sysctl_coverage_op xen_sysctl_coverage_op_t;
> >  DEFINE_XEN_GUEST_HANDLE(xen_sysctl_coverage_op_t);
> >
> > +#define XEN_SYSCTL_MSR_read                0
> > +#define XEN_SYSCTL_MSR_write               1
> > +
> > +struct xen_sysctl_msr_data {
> > +    uint32_t cmd;       /* XEN_SYSCTL_MSR_* */
> > +    uint32_t msr;
> > +    uint64_t val;
> > +};
> > +typedef struct xen_sysctl_msr_data xen_sysctl_msr_data_t;
> > +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_msr_data_t);
> > +struct xen_sysctl_msr_op {
> > +    uint32_t nr_ops;
> > +    uint32_t cpu;
> > +    XEN_GUEST_HANDLE_64(xen_sysctl_msr_data_t) msr_data;
> > +};
> > +typedef struct xen_sysctl_msr_op xen_sysctl_msr_op_t;
> > +DEFINE_XEN_GUEST_HANDLE(xen_sysctl_msr_op_t);
> > +
> > +struct msr_access_info {
> > +    uint32_t nr_ops;
> > +    xen_sysctl_msr_data_t *msr_data;
> > +};
> 
> This is private to Xen.  It should not be here in a public header.

Okay, thanks!

Dongxiao

> 
> ~Andrew
> 
> > +
> >
> >  struct xen_sysctl {
> >      uint32_t cmd;
> > @@ -658,6 +681,7 @@ struct xen_sysctl {
> >  #define XEN_SYSCTL_cpupool_op                    18
> >  #define XEN_SYSCTL_scheduler_op                  19
> >  #define XEN_SYSCTL_coverage_op                   20
> > +#define XEN_SYSCTL_msr_op                        21
> >      uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
> >      union {
> >          struct xen_sysctl_readconsole       readconsole;
> > @@ -679,6 +703,7 @@ struct xen_sysctl {
> >          struct xen_sysctl_cpupool_op        cpupool_op;
> >          struct xen_sysctl_scheduler_op      scheduler_op;
> >          struct xen_sysctl_coverage_op       coverage_op;
> > +        struct xen_sysctl_msr_op            msr_op;
> >          uint8_t                             pad[128];
> >      } u;
> >  };


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.