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

[Xen-changelog] [linux-2.6.18-xen] IA64: add ia64 cpufreq notify hypercall



# HG changeset patch
# User Isaku Yamahata <yamahata@xxxxxxxxxxxxx>
# Date 1223533434 -32400
# Node ID 55ec2b18fe7f1877cedf5ff367e7c05cdcdebb66
# Parent  7d2d7b1deda42a8542f98697ad8f86195432b04b
IA64: add ia64 cpufreq notify hypercall

This patch adds ia64 notify hypercall to pass cpufreq ACPI information to
hypervisor, and get cpufreq statistic data from hypervisor.

Signed-off-by: Yu Ke <ke.yu@xxxxxxxxx>
Signed-off-by: Liu Jinsong <jinsong.liu@xxxxxxxxx>
---
 arch/ia64/kernel/Makefile                |    3 
 arch/ia64/kernel/processor_extcntl_xen.c |  164 +++++++++++++++++++++++++++++++
 arch/ia64/xen/xcom_hcall.c               |    9 +
 arch/ia64/xen/xcom_privcmd.c             |   25 ++++
 drivers/acpi/Kconfig                     |    2 
 include/asm-ia64/hypercall.h             |    1 
 include/asm-ia64/xen/xcom_hcall.h        |    2 
 7 files changed, 205 insertions(+), 1 deletion(-)

diff -r 7d2d7b1deda4 -r 55ec2b18fe7f arch/ia64/kernel/Makefile
--- a/arch/ia64/kernel/Makefile Fri Oct 03 13:08:44 2008 +0900
+++ b/arch/ia64/kernel/Makefile Thu Oct 09 15:23:54 2008 +0900
@@ -16,6 +16,9 @@ obj-$(CONFIG_IA64_HP_ZX1_SWIOTLB) += acp
 
 ifneq ($(CONFIG_ACPI_PROCESSOR),)
 obj-y                          += acpi-processor.o
+ifneq ($(CONFIG_PROCESSOR_EXTERNAL_CONTROL),)
+obj-$(CONFIG_XEN)              += processor_extcntl_xen.o
+endif
 endif
 
 obj-$(CONFIG_IA64_PALINFO)     += palinfo.o
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f arch/ia64/kernel/processor_extcntl_xen.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/arch/ia64/kernel/processor_extcntl_xen.c  Thu Oct 09 15:23:54 2008 +0900
@@ -0,0 +1,164 @@
+/*
+ * processor_extcntl_xen.c - interface to notify Xen
+ *
+ *  Copyright (C) 2008, Intel corporation
+ *
+ * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or (at
+ *  your option) any later version.
+ *
+ *  This program is distributed in the hope that 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.
+ *
+ *  You should have received a copy of the GNU General Public License along
+ *  with this program; if not, write to the Free Software Foundation, Inc.,
+ *  59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ */
+
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/acpi.h>
+#include <linux/pm.h>
+#include <linux/cpu.h>
+#include <linux/cpufreq.h>
+#include <acpi/processor.h>
+#include <asm/hypercall.h>
+#include <asm/xen/xencomm.h>
+#include <xen/interface/platform.h>
+
+static int xen_cx_notifier(struct acpi_processor *pr, int action)
+{
+       printk(KERN_WARNING "Cx is not supported yet\n");
+
+       return -EINVAL;
+}
+
+static int xen_px_notifier(struct acpi_processor *pr, int action)
+{
+       int ret = -EINVAL;
+       xen_platform_op_t op = {
+               .cmd                    = XENPF_set_processor_pminfo,
+               .interface_version      = XENPF_INTERFACE_VERSION,
+               .u.set_pminfo.id        = pr->acpi_id,
+               .u.set_pminfo.type      = XEN_PM_PX,
+       };
+       struct xen_processor_performance *perf;
+       struct xen_processor_px *states = NULL;
+       struct acpi_processor_performance *px;
+       struct acpi_psd_package *pdomain;
+       struct xencomm_handle *states_desc;
+
+       if (!pr || !pr->performance)
+               return -EINVAL;
+
+       perf = &op.u.set_pminfo.perf;
+       px = pr->performance;
+
+       switch(action) {
+               case PROCESSOR_PM_CHANGE:
+                       /* ppc dynamic handle */
+                       perf->flags = XEN_PX_PPC;
+                       perf->platform_limit = pr->performance_platform_limit;
+
+                       ret = HYPERVISOR_platform_op(&op);
+                       break;
+
+               case PROCESSOR_PM_INIT:
+                       /* px normal init */
+                       perf->flags = XEN_PX_PPC |
+                               XEN_PX_PCT |
+                               XEN_PX_PSS |
+                               XEN_PX_PSD;
+
+                       /* ppc */
+                       perf->platform_limit = pr->performance_platform_limit;
+
+                       /* pct */
+                       xen_convert_pct_reg(&perf->control_register,
+                                           &px->control_register);
+                       xen_convert_pct_reg(&perf->status_register,
+                                           &px->status_register);
+
+                       /* pss */
+                       perf->state_count = px->state_count;
+                       states = kzalloc(
+                               px->state_count * sizeof(xen_processor_px_t),
+                               GFP_KERNEL);
+                       if (!states){
+                               ret = -ENOMEM;
+                               break;
+                       }
+                       xen_convert_pss_states(states, px->states,
+                                              px->state_count);
+                       set_xen_guest_handle(perf->states, states);
+                       states_desc = xencomm_map_no_alloc(
+                                       xen_guest_handle(perf->states),
+                                       
sizeof(*xen_guest_handle(perf->states)));
+                       set_xen_guest_handle(perf->states,
+                                            (xen_processor_px_t*)states_desc);
+
+                       /* psd */
+                       pdomain = &px->domain_info;
+                       xen_convert_psd_pack(&perf->domain_info, pdomain);
+                       if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ALL)
+                               perf->shared_type = CPUFREQ_SHARED_TYPE_ALL;
+                       else if (pdomain->coord_type ==
+                                DOMAIN_COORD_TYPE_SW_ANY)
+                               perf->shared_type = CPUFREQ_SHARED_TYPE_ANY;
+                       else if (pdomain->coord_type ==
+                                DOMAIN_COORD_TYPE_HW_ALL)
+                               perf->shared_type = CPUFREQ_SHARED_TYPE_HW;
+                       else {
+                               ret = -ENODEV;
+                               kfree(states);
+                               break;
+                       }
+
+                       ret = HYPERVISOR_platform_op(&op);
+                       kfree(states);
+                       break;
+
+               default:
+                       ret = -EINVAL;
+       }
+
+       return ret;
+}
+
+static int xen_tx_notifier(struct acpi_processor *pr, int action)
+{
+       return -EINVAL;
+}
+static int xen_hotplug_notifier(struct acpi_processor *pr, int event)
+{
+       return -EINVAL;
+}
+
+static struct processor_extcntl_ops xen_extcntl_ops = {
+       .hotplug                = xen_hotplug_notifier,
+};
+
+void arch_acpi_processor_init_extcntl(const struct processor_extcntl_ops **ops)
+{
+       unsigned int pmbits = (xen_start_info->flags & SIF_PM_MASK) >> 8;
+
+       if (!pmbits)
+               return;
+
+       if (pmbits & XEN_PROCESSOR_PM_CX)
+               xen_extcntl_ops.pm_ops[PM_TYPE_IDLE] = xen_cx_notifier;
+       if (pmbits & XEN_PROCESSOR_PM_PX)
+               xen_extcntl_ops.pm_ops[PM_TYPE_PERF] = xen_px_notifier;
+       if (pmbits & XEN_PROCESSOR_PM_TX)
+               xen_extcntl_ops.pm_ops[PM_TYPE_THR] = xen_tx_notifier;
+
+       *ops = &xen_extcntl_ops;
+}
+EXPORT_SYMBOL(arch_acpi_processor_init_extcntl);
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f arch/ia64/xen/xcom_hcall.c
--- a/arch/ia64/xen/xcom_hcall.c        Fri Oct 03 13:08:44 2008 +0900
+++ b/arch/ia64/xen/xcom_hcall.c        Thu Oct 09 15:23:54 2008 +0900
@@ -285,6 +285,15 @@ xencomm_hypercall_sched_op(int cmd, void
 }
 EXPORT_SYMBOL_GPL(xencomm_hypercall_sched_op);
 
+int xencomm_hypercall_platform_op(struct xen_platform_op *arg)
+{
+       return xencomm_arch_hypercall_platform_op(
+                       xencomm_map_no_alloc(arg,
+                       sizeof(struct xen_platform_op))
+                       );
+}
+EXPORT_SYMBOL_GPL(xencomm_hypercall_platform_op);
+
 int
 xencomm_hypercall_multicall(void *call_list, int nr_calls)
 {
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f arch/ia64/xen/xcom_privcmd.c
--- a/arch/ia64/xen/xcom_privcmd.c      Fri Oct 03 13:08:44 2008 +0900
+++ b/arch/ia64/xen/xcom_privcmd.c      Thu Oct 09 15:23:54 2008 +0900
@@ -193,6 +193,31 @@ xencomm_privcmd_sysctl(privcmd_hypercall
                set_xen_guest_handle(kern_op.u.physinfo.cpu_to_node,
                                     (void *)desc);
                break;
+
+       case XEN_SYSCTL_get_pmstat:
+               if (kern_op.u.get_pmstat.type == PMSTAT_get_pxstat) {
+                       struct pm_px_stat *getpx =
+                               &kern_op.u.get_pmstat.u.getpx;
+                       desc = xencomm_map(
+                               xen_guest_handle(getpx->trans_pt),
+                               getpx->total * getpx->total *
+                               sizeof(uint64_t));
+                       if (xen_guest_handle(getpx->trans_pt) != NULL &&
+                           getpx->total > 0 && desc == NULL)
+                               return -ENOMEM;
+
+                       set_xen_guest_handle(getpx->trans_pt, (void *)desc);
+
+                       desc1 = xencomm_map(xen_guest_handle(getpx->pt),
+                               getpx->total * sizeof(pm_px_val_t));
+                       if (xen_guest_handle(getpx->pt) != NULL &&
+                           getpx->total > 0 && desc1 == NULL)
+                               return -ENOMEM;
+
+                       set_xen_guest_handle(getpx->pt, (void *)desc1);
+               }
+               break;
+
        default:
                printk("%s: unknown sysctl cmd %d\n", __func__, kern_op.cmd);
                return -ENOSYS;
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f drivers/acpi/Kconfig
--- a/drivers/acpi/Kconfig      Fri Oct 03 13:08:44 2008 +0900
+++ b/drivers/acpi/Kconfig      Thu Oct 09 15:23:54 2008 +0900
@@ -370,7 +370,7 @@ config ACPI_PV_SLEEP
 
 config PROCESSOR_EXTERNAL_CONTROL
        bool
-       depends on X86 && XEN
+       depends on (X86 || IA64) && XEN
        default y
 endif  # ACPI
 
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f include/asm-ia64/hypercall.h
--- a/include/asm-ia64/hypercall.h      Fri Oct 03 13:08:44 2008 +0900
+++ b/include/asm-ia64/hypercall.h      Thu Oct 09 15:23:54 2008 +0900
@@ -444,6 +444,7 @@ xencomm_arch_hypercall_kexec_op(int cmd,
 
 /* Use xencomm to do hypercalls.  */
 #define HYPERVISOR_sched_op xencomm_hypercall_sched_op
+#define HYPERVISOR_platform_op xencomm_hypercall_platform_op
 #define HYPERVISOR_event_channel_op xencomm_hypercall_event_channel_op
 #define HYPERVISOR_callback_op xencomm_hypercall_callback_op
 #define HYPERVISOR_multicall xencomm_hypercall_multicall
diff -r 7d2d7b1deda4 -r 55ec2b18fe7f include/asm-ia64/xen/xcom_hcall.h
--- a/include/asm-ia64/xen/xcom_hcall.h Fri Oct 03 13:08:44 2008 +0900
+++ b/include/asm-ia64/xen/xcom_hcall.h Thu Oct 09 15:23:54 2008 +0900
@@ -36,6 +36,8 @@ extern int xencomm_hypercall_grant_table
 
 extern int xencomm_hypercall_sched_op(int cmd, void *arg);
 
+extern int xencomm_hypercall_platform_op(struct xen_platform_op *arg);
+
 extern int xencomm_hypercall_multicall(void *call_list, int nr_calls);
 
 extern int xencomm_hypercall_callback_op(int cmd, void *arg);

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

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