xen-devel.lists.xenproject.org archive mirror
 help / color / mirror / Atom feed
From: Chao Peng <chao.p.peng@linux.intel.com>
To: xen-devel@lists.xen.org
Cc: keir@xen.org, Ian.Campbell@citrix.com,
	stefano.stabellini@eu.citrix.com, George.Dunlap@eu.citrix.com,
	andrew.cooper3@citrix.com, Ian.Jackson@eu.citrix.com,
	JBeulich@suse.com, dgdegra@tycho.nsa.gov
Subject: [PATCH v17 01/10] x86: add generic resource (e.g. MSR) access hypercall
Date: Mon, 29 Sep 2014 18:40:30 +0800	[thread overview]
Message-ID: <1411987239-3509-2-git-send-email-chao.p.peng@linux.intel.com> (raw)
In-Reply-To: <1411987239-3509-1-git-send-email-chao.p.peng@linux.intel.com>

Add a generic resource access hypercall for tool stack or other
components, e.g., accessing MSR, port I/O, etc.

The resource is abstracted as a resource address/value pair.
The resource access can be any type of XEN_RESOURCE_OP_*(current
only support MSR and it's white-listed). The resource operations
are always runs on cpu that caller specified. If caller does not
care this, it should use current cpu to eliminate the IPI overhead.

Batch resource operations in one call are also supported but the
max number currently is limited to 2. The operations in a batch are
non-preemptible and execute in their original order. If preemptible
batch is desirable, then multicall mechanism can be used.

Signed-off-by: Dongxiao Xu <dongxiao.xu@intel.com>
Signed-off-by: Chao Peng <chao.p.peng@linux.intel.com>
---
 xen/arch/x86/platform_hypercall.c        |  140 ++++++++++++++++++++++++++++++
 xen/arch/x86/x86_64/platform_hypercall.c |    4 +
 xen/include/public/platform.h            |   28 ++++++
 xen/include/xlat.lst                     |    1 +
 4 files changed, 173 insertions(+)

diff --git a/xen/arch/x86/platform_hypercall.c b/xen/arch/x86/platform_hypercall.c
index 2162811..4b92b56 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -61,6 +61,77 @@ long cpu_down_helper(void *data);
 long core_parking_helper(void *data);
 uint32_t get_cur_idle_nums(void);
 
+struct xen_resource_access {
+    int32_t ret;
+    uint32_t nr_entries;
+    xenpf_resource_entry_t *entries;
+};
+
+static bool_t allow_access_msr(unsigned int msr)
+{
+    return 0;
+}
+
+static int check_resource_access(struct xen_resource_access *ra)
+{
+    xenpf_resource_entry_t *entry;
+    unsigned int i;
+
+    for ( i = 0; i < ra->nr_entries; i++ )
+    {
+        entry = ra->entries + i;
+
+        if ( entry->rsvd )
+            return -EINVAL;
+
+        switch ( entry->cmd )
+        {
+        case XEN_RESOURCE_OP_MSR_READ:
+        case XEN_RESOURCE_OP_MSR_WRITE:
+            if ( entry->idx >> 32 )
+                return -EINVAL;
+            else if ( !allow_access_msr(entry->idx) )
+                return -EACCES;
+        default:
+            return -EINVAL;
+        }
+    }
+
+    return 0;
+}
+
+static void resource_access(void *info)
+{
+    struct xen_resource_access *ra = info;
+    xenpf_resource_entry_t *entry;
+    int ret = 0;
+    unsigned int i;
+
+    for ( i = 0; i < ra->nr_entries; i++ )
+    {
+        entry = ra->entries + i;
+
+        switch ( entry->cmd )
+        {
+        case XEN_RESOURCE_OP_MSR_READ:
+        case XEN_RESOURCE_OP_MSR_WRITE:
+            if ( entry->cmd == XEN_RESOURCE_OP_MSR_READ )
+                ret = rdmsr_safe(entry->idx, entry->val);
+            else
+                ret = wrmsr_safe(entry->idx, entry->val);
+            break;
+        default:
+            ret = -EINVAL;
+            break;
+        }
+
+        if ( ret )
+            break;
+    }
+
+    ra->ret = ret;
+}
+
 ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
 {
     ret_t ret = 0;
@@ -601,6 +672,75 @@ ret_t do_platform_op(XEN_GUEST_HANDLE_PARAM(xen_platform_op_t) u_xenpf_op)
     }
     break;
 
+    case XENPF_resource_op:
+    {
+        struct xen_resource_access ra;
+        uint32_t cpu;
+        XEN_GUEST_HANDLE(xenpf_resource_entry_t) guest_entries;
+
+#define MAX_SUPPORTED_ENTRIES   2
+
+        ra.nr_entries = op->u.resource_op.nr_entries;
+        if ( ra.nr_entries == 0 || ra.nr_entries > MAX_SUPPORTED_ENTRIES )
+        {
+            ret = -EINVAL;
+            break;
+        }
+
+        ra.entries = xmalloc_array(xenpf_resource_entry_t, ra.nr_entries);
+        if ( !ra.entries )
+        {
+            ret = -ENOMEM;
+            break;
+        }
+
+        guest_from_compat_handle(guest_entries, op->u.resource_op.entries);
+
+        if ( copy_from_guest(ra.entries, guest_entries, ra.nr_entries) )
+        {
+            xfree(ra.entries);
+            ret = -EFAULT;
+            break;
+        }
+
+        /* Do sanity check earlier to omit the potential IPI overhead. */
+        ret = check_resource_access(&ra);
+        if ( ret )
+        {
+            xfree(ra.entries);
+            break;
+        }
+
+        cpu = op->u.resource_op.cpu;
+        if ( cpu == smp_processor_id() )
+            resource_access(&ra);
+        else if ( cpu_online(cpu) )
+            on_selected_cpus(cpumask_of(cpu), resource_access, &ra, 1);
+        else
+        {
+            xfree(ra.entries);
+            ret = -ENODEV;
+            break;
+        }
+
+        if ( ra.ret )
+        {
+            xfree(ra.entries);
+            ret = ra.ret;
+            break;
+        }
+
+        if ( __copy_to_guest(guest_entries, ra.entries, ra.nr_entries) )
+        {
+            xfree(ra.entries);
+            ret = -EFAULT;
+            break;
+        }
+
+        xfree(ra.entries);
+    }
+    break;
+
     default:
         ret = -ENOSYS;
         break;
diff --git a/xen/arch/x86/x86_64/platform_hypercall.c b/xen/arch/x86/x86_64/platform_hypercall.c
index b6f380e..ccfd30d 100644
--- a/xen/arch/x86/x86_64/platform_hypercall.c
+++ b/xen/arch/x86/x86_64/platform_hypercall.c
@@ -32,6 +32,10 @@ CHECK_pf_pcpu_version;
 CHECK_pf_enter_acpi_sleep;
 #undef xen_pf_enter_acpi_sleep
 
+#define xen_pf_resource_entry xenpf_resource_entry
+CHECK_pf_resource_entry;
+#undef xen_pf_resource_entry
+
 #define COMPAT
 #define _XEN_GUEST_HANDLE(t) XEN_GUEST_HANDLE(t)
 #define _XEN_GUEST_HANDLE_PARAM(t) XEN_GUEST_HANDLE_PARAM(t)
diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h
index 053b9fa..5951848 100644
--- a/xen/include/public/platform.h
+++ b/xen/include/public/platform.h
@@ -528,6 +528,33 @@ typedef struct xenpf_core_parking xenpf_core_parking_t;
 DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t);
 
 /*
+ * Access generic platform resources(e.g., accessing MSR, port I/O, etc)
+ * in unified way. Batch resource operations in one call are supported and
+ * thay are always non-preemptible and execute in their original order.
+ */
+#define XENPF_resource_op   61
+
+#define XEN_RESOURCE_OP_MSR_READ  0
+#define XEN_RESOURCE_OP_MSR_WRITE 1
+
+struct xenpf_resource_entry {
+    uint32_t cmd;       /* IN: XEN_RESOURCE_OP_* */
+    uint32_t rsvd;      /* IN: padding and must be zero */
+    uint64_t idx;       /* IN: resource address to access */
+    uint64_t val;       /* IN/OUT: resource value to set/get */
+};
+typedef struct xenpf_resource_entry xenpf_resource_entry_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_resource_entry_t);
+
+struct xenpf_resource_op {
+    uint32_t nr_entries;    /* number of resource entry */
+    uint32_t cpu;           /* which cpu to run */
+    XEN_GUEST_HANDLE(xenpf_resource_entry_t) entries;
+};
+typedef struct xenpf_resource_op xenpf_resource_op_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_resource_op_t);
+
+/*
  * ` enum neg_errnoval
  * ` HYPERVISOR_platform_op(const struct xen_platform_op*);
  */
@@ -553,6 +580,7 @@ struct xen_platform_op {
         struct xenpf_cpu_hotadd        cpu_add;
         struct xenpf_mem_hotadd        mem_add;
         struct xenpf_core_parking      core_parking;
+        struct xenpf_resource_op       resource_op;
         uint8_t                        pad[128];
     } u;
 };
diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst
index 9a35dd7..234b668 100644
--- a/xen/include/xlat.lst
+++ b/xen/include/xlat.lst
@@ -88,6 +88,7 @@
 ?	xenpf_enter_acpi_sleep		platform.h
 ?	xenpf_pcpuinfo			platform.h
 ?	xenpf_pcpu_version		platform.h
+?	xenpf_resource_entry		platform.h
 !	sched_poll			sched.h
 ?	sched_remote_shutdown		sched.h
 ?	sched_shutdown			sched.h
-- 
1.7.9.5

  reply	other threads:[~2014-09-29 10:40 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-09-29 10:40 [PATCH v17 00/10] enable Cache Monitoring Technology (CMT) feature Chao Peng
2014-09-29 10:40 ` Chao Peng [this message]
2014-09-29 13:47   ` [PATCH v17 01/10] x86: add generic resource (e.g. MSR) access hypercall Andrew Cooper
2014-09-29 13:55     ` Jan Beulich
2014-09-29 10:40 ` [PATCH v17 02/10] xsm: add resource operation related xsm policy Chao Peng
2014-09-29 10:40 ` [PATCH v17 03/10] tools: provide interface for generic resource access Chao Peng
2014-09-29 10:40 ` [PATCH v17 04/10] x86: detect and initialize Cache Monitoring Technology feature Chao Peng
2014-09-29 14:03   ` Andrew Cooper
2014-09-29 10:40 ` [PATCH v17 05/10] x86: dynamically attach/detach CMT service for a guest Chao Peng
2014-09-29 14:05   ` Andrew Cooper
2014-09-29 10:40 ` [PATCH v17 06/10] x86: collect global CMT information Chao Peng
2014-09-29 14:07   ` Andrew Cooper
2014-09-29 10:40 ` [PATCH v17 07/10] x86: enable CMT for each domain RMID Chao Peng
2014-09-29 14:08   ` Andrew Cooper
2014-09-29 10:40 ` [PATCH v17 08/10] x86: add CMT related MSRs in allowed list Chao Peng
2014-09-29 14:09   ` Andrew Cooper
2014-09-29 10:40 ` [PATCH v17 09/10] xsm: add CMT related xsm policies Chao Peng
2014-09-29 10:40 ` [PATCH v17 10/10] tools: CMDs and APIs for Cache Monitoring Technology Chao Peng

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1411987239-3509-2-git-send-email-chao.p.peng@linux.intel.com \
    --to=chao.p.peng@linux.intel.com \
    --cc=George.Dunlap@eu.citrix.com \
    --cc=Ian.Campbell@citrix.com \
    --cc=Ian.Jackson@eu.citrix.com \
    --cc=JBeulich@suse.com \
    --cc=andrew.cooper3@citrix.com \
    --cc=dgdegra@tycho.nsa.gov \
    --cc=keir@xen.org \
    --cc=stefano.stabellini@eu.citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).