|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH v12 1/9] x86: add generic resource (e.g. MSR) access hypercall
Add a generic resource access hypercall for tool stack or other
components, e.g., accessing MSR, port I/O, etc.
Signed-off-by: Dongxiao Xu <dongxiao.xu@xxxxxxxxx>
---
xen/arch/x86/Makefile | 1 +
xen/arch/x86/platform_hypercall.c | 39 ++++++++++++
xen/arch/x86/resource.c | 119 +++++++++++++++++++++++++++++++++++++
xen/include/asm-x86/resource.h | 40 +++++++++++++
xen/include/public/platform.h | 24 ++++++++
xen/include/xlat.lst | 1 +
6 files changed, 224 insertions(+)
create mode 100644 xen/arch/x86/resource.c
create mode 100644 xen/include/asm-x86/resource.h
diff --git a/xen/arch/x86/Makefile b/xen/arch/x86/Makefile
index 6c90b1b..e0cee24 100644
--- a/xen/arch/x86/Makefile
+++ b/xen/arch/x86/Makefile
@@ -59,6 +59,7 @@ obj-y += crash.o
obj-y += tboot.o
obj-y += hpet.o
obj-y += xstate.o
+obj-y += resource.o
obj-$(crash_debug) += gdbstub.o
diff --git a/xen/arch/x86/platform_hypercall.c
b/xen/arch/x86/platform_hypercall.c
index 2162811..da3d6c4 100644
--- a/xen/arch/x86/platform_hypercall.c
+++ b/xen/arch/x86/platform_hypercall.c
@@ -32,6 +32,7 @@
#include <asm/setup.h>
#include "cpu/mtrr/mtrr.h"
#include <xsm/xsm.h>
+#include <asm/resource.h>
#ifndef COMPAT
typedef long ret_t;
@@ -601,6 +602,44 @@ 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 info;
+
+ info.nr = op->u.resource_op.nr;
+ info.type = op->u.resource_op.type;
+ info.data = xmalloc_array(xenpf_resource_data_t, info.nr);
+ if ( !info.data )
+ {
+ ret = -ENOMEM;
+ break;
+ }
+
+ if ( copy_from_guest(info.data, op->u.resource_op.data, info.nr) )
+ {
+ xfree(info.data);
+ ret = -EFAULT;
+ break;
+ }
+
+ ret = resource_access_helper(&info);
+ if ( ret )
+ {
+ xfree(info.data);
+ break;
+ }
+
+ if ( copy_to_guest(op->u.resource_op.data, info.data, info.nr) )
+ {
+ xfree(info.data);
+ ret = -EFAULT;
+ break;
+ }
+
+ xfree(info.data);
+ }
+ break;
+
default:
ret = -ENOSYS;
break;
diff --git a/xen/arch/x86/resource.c b/xen/arch/x86/resource.c
new file mode 100644
index 0000000..cc548cd
--- /dev/null
+++ b/xen/arch/x86/resource.c
@@ -0,0 +1,119 @@
+/*
+ * resource.c: Helpers for Dom0 to access system resource
+ *
+ * Copyright (c) 2014, Intel Corporation
+ * Author: Dongxiao Xu <dongxiao.xu@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+
+#include <xen/types.h>
+#include <xen/domain.h>
+#include <xen/guest_access.h>
+#include <public/platform.h>
+#include <asm/msr.h>
+#include <asm/event.h>
+#include <asm/resource.h>
+
+static int resource_access_one(uint32_t type, uint32_t cmd,
+ uint64_t idx, uint64_t *val)
+{
+ int ret = 0;
+
+ switch ( type )
+ {
+ case XEN_RESOURCE_TYPE_MSR:
+ if ( cmd == XEN_RESOURCE_OP_READ )
+ ret = rdmsr_safe(idx, *val);
+ else if ( cmd == XEN_RESOURCE_OP_WRITE )
+ ret = wrmsr_safe(idx, *val);
+ break;
+
+ default:
+ gdprintk(XENLOG_WARNING, "unsupported resource type: %d\n", type);
+ ret = -ENOSYS;
+ break;
+ }
+
+ return ret;
+}
+
+static void resource_access_multi(void *param)
+{
+ struct xen_resource_access *info = param;
+ unsigned int i;
+ int ret = 0;
+
+ for ( i = 0; i < info->nr; i++ )
+ {
+ if ( !is_idle_vcpu(current) && hypercall_preempt_check() )
+ {
+ ret = -ERESTART;
+ break;
+ }
+ ret = resource_access_one(info->type, info->data[i].cmd,
+ info->data[i].idx, &info->data[i].val);
+ if ( ret )
+ break;
+ }
+
+ info->ret = ret;
+}
+
+int resource_access_helper(struct xen_resource_access *info)
+{
+ struct xen_resource_access iter;
+ unsigned int i, last_cpu = ~0;
+
+ iter.ret = 0;
+ iter.nr = 0;
+ iter.type = info->type;
+ iter.data = info->data;
+
+ for ( i = 0; i < info->nr; i++ )
+ {
+ if ( iter.nr && info->data[i].cpu != last_cpu )
+ {
+ if ( last_cpu == smp_processor_id() )
+ resource_access_multi(&iter);
+ else
+ /* Set wait=1 to ensure the access order */
+ on_selected_cpus(cpumask_of(last_cpu),
+ resource_access_multi, &iter, 1);
+
+ if ( iter.ret )
+ return iter.ret;
+
+ iter.nr = 0;
+ iter.data = &info->data[i];
+ }
+
+ last_cpu = info->data[i].cpu;
+ iter.nr++;
+ }
+
+ if ( last_cpu == smp_processor_id() )
+ resource_access_multi(&iter);
+ else
+ on_selected_cpus(cpumask_of(last_cpu),
+ resource_access_multi, &iter, 1);
+
+ return iter.ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/asm-x86/resource.h b/xen/include/asm-x86/resource.h
new file mode 100644
index 0000000..74b46be
--- /dev/null
+++ b/xen/include/asm-x86/resource.h
@@ -0,0 +1,40 @@
+/*
+ * resource.h: Helpers for Dom0 to access system resource
+ *
+ * Copyright (c) 2014, Intel Corporation
+ * Author: Dongxiao Xu <dongxiao.xu@xxxxxxxxx>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ */
+#ifndef __ASM_RESOURCE_H__
+#define __ASM_RESOURCE_H__
+
+#include <public/platform.h>
+
+struct xen_resource_access {
+ int32_t ret;
+ uint32_t nr;
+ uint32_t type;
+ xenpf_resource_data_t *data;
+};
+
+int resource_access_helper(struct xen_resource_access *info);
+
+#endif /* __ASM_RESOURCE_H__ */
+
+/*
+ * Local variables:
+ * mode: C
+ * c-file-style: "BSD"
+ * c-basic-offset: 4
+ * tab-width: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/xen/include/public/platform.h b/xen/include/public/platform.h
index 053b9fa..eafdc8a 100644
--- a/xen/include/public/platform.h
+++ b/xen/include/public/platform.h
@@ -527,6 +527,29 @@ struct xenpf_core_parking {
typedef struct xenpf_core_parking xenpf_core_parking_t;
DEFINE_XEN_GUEST_HANDLE(xenpf_core_parking_t);
+#define XENPF_resource_op 61
+
+#define XEN_RESOURCE_OP_READ 0
+#define XEN_RESOURCE_OP_WRITE 1
+
+#define XEN_RESOURCE_TYPE_MSR 0
+
+struct xenpf_resource_data {
+ uint32_t cmd; /* XEN_RESOURCE_OP_* */
+ uint32_t cpu;
+ uint64_t idx;
+ uint64_t val;
+};
+typedef struct xenpf_resource_data xenpf_resource_data_t;
+DEFINE_XEN_GUEST_HANDLE(xenpf_resource_data_t);
+struct xenpf_resource_op {
+ uint32_t nr;
+ uint32_t type; /* XEN_RESOURCE_TYPE_* */
+ XEN_GUEST_HANDLE(xenpf_resource_data_t) data;
+};
+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 +576,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..06ed7b9 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_op platform.h
! sched_poll sched.h
? sched_remote_shutdown sched.h
? sched_shutdown sched.h
--
1.7.9.5
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |