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

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



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);
+    }
+}
+
 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);
+        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;
+};
+
 
 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;
 };
-- 
1.8.1.5


_______________________________________________
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®.