From: Oleksandr Tyshchenko <olekstysh@gmail.com>
To: xen-devel@lists.xenproject.org
Cc: Stefano Stabellini <sstabellini@kernel.org>,
Andrew Cooper <andrew.cooper3@citrix.com>,
Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>,
Julien Grall <julien.grall@linaro.org>,
Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>,
Jan Beulich <jbeulich@suse.com>
Subject: [RFC PATCH 03/31] pmstat: move pmstat.c file to the xen/drivers/pm/stat.c location
Date: Thu, 9 Nov 2017 19:09:53 +0200 [thread overview]
Message-ID: <1510247421-24094-4-git-send-email-olekstysh@gmail.com> (raw)
In-Reply-To: <1510247421-24094-1-git-send-email-olekstysh@gmail.com>
From: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
Cpufreq driver should be more generalizable (not ACPI-specific).
Thus this file should be placed to more convenient location.
This is a rebased version of the original patch:
https://lists.xen.org/archives/html/xen-devel/2014-11/msg00935.html
Signed-off-by: Oleksandr Dmytryshyn <oleksandr.dmytryshyn@globallogic.com>
Signed-off-by: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>
CC: Jan Beulich <jbeulich@suse.com>
CC: Andrew Cooper <andrew.cooper3@citrix.com>
CC: Stefano Stabellini <sstabellini@kernel.org>
CC: Julien Grall <julien.grall@linaro.org>
---
MAINTAINERS | 1 +
xen/arch/x86/Kconfig | 1 +
xen/common/sysctl.c | 2 +-
xen/drivers/Kconfig | 2 +
xen/drivers/Makefile | 1 +
xen/drivers/acpi/Makefile | 1 -
xen/drivers/acpi/pmstat.c | 526 ----------------------------------------------
xen/drivers/pm/Kconfig | 3 +
xen/drivers/pm/Makefile | 1 +
xen/drivers/pm/stat.c | 526 ++++++++++++++++++++++++++++++++++++++++++++++
10 files changed, 536 insertions(+), 528 deletions(-)
delete mode 100644 xen/drivers/acpi/pmstat.c
create mode 100644 xen/drivers/pm/Kconfig
create mode 100644 xen/drivers/pm/Makefile
create mode 100644 xen/drivers/pm/stat.c
diff --git a/MAINTAINERS b/MAINTAINERS
index 9794a81..87ade6f 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -294,6 +294,7 @@ F: xen/arch/x86/acpi/
X: xen/arch/x86/acpi/boot.c
X: xen/arch/x86/acpi/lib.c
F: xen/drivers/cpufreq/
+F: xen/drivers/pm/
F: xen/include/xen/cpufreq.h
F: xen/include/xen/processor_perf.h
diff --git a/xen/arch/x86/Kconfig b/xen/arch/x86/Kconfig
index 30c2769..86c8eca 100644
--- a/xen/arch/x86/Kconfig
+++ b/xen/arch/x86/Kconfig
@@ -23,6 +23,7 @@ config X86
select HAS_PDX
select NUMA
select VGA
+ select HAS_PM
config ARCH_DEFCONFIG
string
diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c
index a6882d1..ac96347 100644
--- a/xen/common/sysctl.c
+++ b/xen/common/sysctl.c
@@ -171,7 +171,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
op->u.availheap.avail_bytes <<= PAGE_SHIFT;
break;
-#if defined (CONFIG_ACPI) && defined (CONFIG_HAS_CPUFREQ)
+#if defined (CONFIG_HAS_PM) && defined (CONFIG_HAS_CPUFREQ)
case XEN_SYSCTL_get_pmstat:
ret = do_get_pm_info(&op->u.get_pmstat);
break;
diff --git a/xen/drivers/Kconfig b/xen/drivers/Kconfig
index bc3a54f..ddaec11 100644
--- a/xen/drivers/Kconfig
+++ b/xen/drivers/Kconfig
@@ -12,4 +12,6 @@ source "drivers/pci/Kconfig"
source "drivers/video/Kconfig"
+source "drivers/pm/Kconfig"
+
endmenu
diff --git a/xen/drivers/Makefile b/xen/drivers/Makefile
index 1939180..dd0b496 100644
--- a/xen/drivers/Makefile
+++ b/xen/drivers/Makefile
@@ -4,3 +4,4 @@ subdir-$(CONFIG_HAS_PCI) += pci
subdir-$(CONFIG_HAS_PASSTHROUGH) += passthrough
subdir-$(CONFIG_ACPI) += acpi
subdir-$(CONFIG_VIDEO) += video
+subdir-$(CONFIG_HAS_PM) += pm
diff --git a/xen/drivers/acpi/Makefile b/xen/drivers/acpi/Makefile
index 444b11d..6f6470a 100644
--- a/xen/drivers/acpi/Makefile
+++ b/xen/drivers/acpi/Makefile
@@ -5,7 +5,6 @@ subdir-$(CONFIG_X86) += apei
obj-bin-y += tables.init.o
obj-$(CONFIG_NUMA) += numa.o
obj-y += osl.o
-obj-$(CONFIG_HAS_CPUFREQ) += pmstat.o
obj-$(CONFIG_X86) += hwregs.o
obj-$(CONFIG_X86) += reboot.o
diff --git a/xen/drivers/acpi/pmstat.c b/xen/drivers/acpi/pmstat.c
deleted file mode 100644
index 2dbde1c..0000000
--- a/xen/drivers/acpi/pmstat.c
+++ /dev/null
@@ -1,526 +0,0 @@
-/*****************************************************************************
-# pmstat.c - Power Management statistic information (Px/Cx/Tx, etc.)
-#
-# Copyright (c) 2008, Liu Jinsong <jinsong.liu@intel.com>
-#
-# 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, see <http://www.gnu.org/licenses/>.
-#
-# The full GNU General Public License is included in this distribution in the
-# file called LICENSE.
-#
-*****************************************************************************/
-
-#include <xen/lib.h>
-#include <xen/errno.h>
-#include <xen/sched.h>
-#include <xen/event.h>
-#include <xen/irq.h>
-#include <xen/iocap.h>
-#include <xen/compat.h>
-#include <xen/guest_access.h>
-#include <asm/current.h>
-#include <public/xen.h>
-#include <xen/cpumask.h>
-#include <asm/processor.h>
-#include <xen/percpu.h>
-#include <xen/domain.h>
-#include <xen/acpi.h>
-
-#include <public/sysctl.h>
-#include <xen/cpufreq.h>
-#include <xen/pmstat.h>
-
-DEFINE_PER_CPU_READ_MOSTLY(struct pm_px *, cpufreq_statistic_data);
-
-/*
- * Get PM statistic info
- */
-int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
-{
- int ret = 0;
- const struct processor_pminfo *pmpt;
-
- if ( !op || (op->cpuid >= nr_cpu_ids) || !cpu_online(op->cpuid) )
- return -EINVAL;
- pmpt = processor_pminfo[op->cpuid];
-
- switch ( op->type & PMSTAT_CATEGORY_MASK )
- {
- case PMSTAT_CX:
- if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_CX) )
- return -ENODEV;
- break;
- case PMSTAT_PX:
- if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
- return -ENODEV;
- if ( !cpufreq_driver )
- return -ENODEV;
- if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
- return -EINVAL;
- break;
- default:
- return -ENODEV;
- }
-
- switch ( op->type )
- {
- case PMSTAT_get_max_px:
- {
- op->u.getpx.total = pmpt->perf.state_count;
- break;
- }
-
- case PMSTAT_get_pxstat:
- {
- uint32_t ct;
- struct pm_px *pxpt;
- spinlock_t *cpufreq_statistic_lock =
- &per_cpu(cpufreq_statistic_lock, op->cpuid);
-
- spin_lock(cpufreq_statistic_lock);
-
- pxpt = per_cpu(cpufreq_statistic_data, op->cpuid);
- if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt )
- {
- spin_unlock(cpufreq_statistic_lock);
- return -ENODATA;
- }
-
- pxpt->u.usable = pmpt->perf.state_count - pmpt->perf.platform_limit;
-
- cpufreq_residency_update(op->cpuid, pxpt->u.cur);
-
- ct = pmpt->perf.state_count;
- if ( copy_to_guest(op->u.getpx.trans_pt, pxpt->u.trans_pt, ct*ct) )
- {
- spin_unlock(cpufreq_statistic_lock);
- ret = -EFAULT;
- break;
- }
-
- if ( copy_to_guest(op->u.getpx.pt, pxpt->u.pt, ct) )
- {
- spin_unlock(cpufreq_statistic_lock);
- ret = -EFAULT;
- break;
- }
-
- op->u.getpx.total = pxpt->u.total;
- op->u.getpx.usable = pxpt->u.usable;
- op->u.getpx.last = pxpt->u.last;
- op->u.getpx.cur = pxpt->u.cur;
-
- spin_unlock(cpufreq_statistic_lock);
-
- break;
- }
-
- case PMSTAT_reset_pxstat:
- {
- cpufreq_statistic_reset(op->cpuid);
- break;
- }
-
- case PMSTAT_get_max_cx:
- {
- op->u.getcx.nr = pmstat_get_cx_nr(op->cpuid);
- ret = 0;
- break;
- }
-
- case PMSTAT_get_cxstat:
- {
- ret = pmstat_get_cx_stat(op->cpuid, &op->u.getcx);
- break;
- }
-
- case PMSTAT_reset_cxstat:
- {
- ret = pmstat_reset_cx_stat(op->cpuid);
- break;
- }
-
- default:
- printk("not defined sub-hypercall @ do_get_pm_info\n");
- ret = -ENOSYS;
- break;
- }
-
- return ret;
-}
-
-/*
- * 1. Get PM parameter
- * 2. Provide user PM control
- */
-static int read_scaling_available_governors(char *scaling_available_governors,
- unsigned int size)
-{
- unsigned int i = 0;
- struct cpufreq_governor *t;
-
- if ( !scaling_available_governors )
- return -EINVAL;
-
- list_for_each_entry(t, &cpufreq_governor_list, governor_list)
- {
- i += scnprintf(&scaling_available_governors[i],
- CPUFREQ_NAME_LEN, "%s ", t->name);
- if ( i > size )
- return -EINVAL;
- }
- scaling_available_governors[i-1] = '\0';
-
- return 0;
-}
-
-static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
-{
- uint32_t ret = 0;
- const struct processor_pminfo *pmpt;
- struct cpufreq_policy *policy;
- uint32_t gov_num = 0;
- uint32_t *affected_cpus;
- uint32_t *scaling_available_frequencies;
- char *scaling_available_governors;
- struct list_head *pos;
- uint32_t cpu, i, j = 0;
-
- pmpt = processor_pminfo[op->cpuid];
- policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
-
- if ( !pmpt || !pmpt->perf.states ||
- !policy || !policy->governor )
- return -EINVAL;
-
- list_for_each(pos, &cpufreq_governor_list)
- gov_num++;
-
- if ( (op->u.get_para.cpu_num != cpumask_weight(policy->cpus)) ||
- (op->u.get_para.freq_num != pmpt->perf.state_count) ||
- (op->u.get_para.gov_num != gov_num) )
- {
- op->u.get_para.cpu_num = cpumask_weight(policy->cpus);
- op->u.get_para.freq_num = pmpt->perf.state_count;
- op->u.get_para.gov_num = gov_num;
- return -EAGAIN;
- }
-
- if ( !(affected_cpus = xzalloc_array(uint32_t, op->u.get_para.cpu_num)) )
- return -ENOMEM;
- for_each_cpu(cpu, policy->cpus)
- affected_cpus[j++] = cpu;
- ret = copy_to_guest(op->u.get_para.affected_cpus,
- affected_cpus, op->u.get_para.cpu_num);
- xfree(affected_cpus);
- if ( ret )
- return ret;
-
- if ( !(scaling_available_frequencies =
- xzalloc_array(uint32_t, op->u.get_para.freq_num)) )
- return -ENOMEM;
- for ( i = 0; i < op->u.get_para.freq_num; i++ )
- scaling_available_frequencies[i] =
- pmpt->perf.states[i].core_frequency * 1000;
- ret = copy_to_guest(op->u.get_para.scaling_available_frequencies,
- scaling_available_frequencies, op->u.get_para.freq_num);
- xfree(scaling_available_frequencies);
- if ( ret )
- return ret;
-
- if ( !(scaling_available_governors =
- xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) )
- return -ENOMEM;
- if ( (ret = read_scaling_available_governors(scaling_available_governors,
- gov_num * CPUFREQ_NAME_LEN * sizeof(char))) )
- {
- xfree(scaling_available_governors);
- return ret;
- }
- ret = copy_to_guest(op->u.get_para.scaling_available_governors,
- scaling_available_governors, gov_num * CPUFREQ_NAME_LEN);
- xfree(scaling_available_governors);
- if ( ret )
- return ret;
-
- op->u.get_para.cpuinfo_cur_freq =
- cpufreq_driver->get ? cpufreq_driver->get(op->cpuid) : policy->cur;
- op->u.get_para.cpuinfo_max_freq = policy->cpuinfo.max_freq;
- op->u.get_para.cpuinfo_min_freq = policy->cpuinfo.min_freq;
- op->u.get_para.scaling_cur_freq = policy->cur;
- op->u.get_para.scaling_max_freq = policy->max;
- op->u.get_para.scaling_min_freq = policy->min;
-
- if ( cpufreq_driver->name[0] )
- strlcpy(op->u.get_para.scaling_driver,
- cpufreq_driver->name, CPUFREQ_NAME_LEN);
- else
- strlcpy(op->u.get_para.scaling_driver, "Unknown", CPUFREQ_NAME_LEN);
-
- if ( policy->governor->name[0] )
- strlcpy(op->u.get_para.scaling_governor,
- policy->governor->name, CPUFREQ_NAME_LEN);
- else
- strlcpy(op->u.get_para.scaling_governor, "Unknown", CPUFREQ_NAME_LEN);
-
- /* governor specific para */
- if ( !strnicmp(op->u.get_para.scaling_governor,
- "userspace", CPUFREQ_NAME_LEN) )
- {
- op->u.get_para.u.userspace.scaling_setspeed = policy->cur;
- }
-
- if ( !strnicmp(op->u.get_para.scaling_governor,
- "ondemand", CPUFREQ_NAME_LEN) )
- {
- ret = get_cpufreq_ondemand_para(
- &op->u.get_para.u.ondemand.sampling_rate_max,
- &op->u.get_para.u.ondemand.sampling_rate_min,
- &op->u.get_para.u.ondemand.sampling_rate,
- &op->u.get_para.u.ondemand.up_threshold);
- }
- op->u.get_para.turbo_enabled = cpufreq_get_turbo_status(op->cpuid);
-
- return ret;
-}
-
-static int set_cpufreq_gov(struct xen_sysctl_pm_op *op)
-{
- struct cpufreq_policy new_policy, *old_policy;
-
- old_policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
- if ( !old_policy )
- return -EINVAL;
-
- memcpy(&new_policy, old_policy, sizeof(struct cpufreq_policy));
-
- new_policy.governor = __find_governor(op->u.set_gov.scaling_governor);
- if (new_policy.governor == NULL)
- return -EINVAL;
-
- return __cpufreq_set_policy(old_policy, &new_policy);
-}
-
-static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
-{
- int ret = 0;
- struct cpufreq_policy *policy;
-
- policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
-
- if ( !policy || !policy->governor )
- return -EINVAL;
-
- switch(op->u.set_para.ctrl_type)
- {
- case SCALING_MAX_FREQ:
- {
- struct cpufreq_policy new_policy;
-
- memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
- new_policy.max = op->u.set_para.ctrl_value;
- ret = __cpufreq_set_policy(policy, &new_policy);
-
- break;
- }
-
- case SCALING_MIN_FREQ:
- {
- struct cpufreq_policy new_policy;
-
- memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
- new_policy.min = op->u.set_para.ctrl_value;
- ret = __cpufreq_set_policy(policy, &new_policy);
-
- break;
- }
-
- case SCALING_SETSPEED:
- {
- unsigned int freq =op->u.set_para.ctrl_value;
-
- if ( !strnicmp(policy->governor->name,
- "userspace", CPUFREQ_NAME_LEN) )
- ret = write_userspace_scaling_setspeed(op->cpuid, freq);
- else
- ret = -EINVAL;
-
- break;
- }
-
- case SAMPLING_RATE:
- {
- unsigned int sampling_rate = op->u.set_para.ctrl_value;
-
- if ( !strnicmp(policy->governor->name,
- "ondemand", CPUFREQ_NAME_LEN) )
- ret = write_ondemand_sampling_rate(sampling_rate);
- else
- ret = -EINVAL;
-
- break;
- }
-
- case UP_THRESHOLD:
- {
- unsigned int up_threshold = op->u.set_para.ctrl_value;
-
- if ( !strnicmp(policy->governor->name,
- "ondemand", CPUFREQ_NAME_LEN) )
- ret = write_ondemand_up_threshold(up_threshold);
- else
- ret = -EINVAL;
-
- break;
- }
-
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-}
-
-int do_pm_op(struct xen_sysctl_pm_op *op)
-{
- int ret = 0;
- const struct processor_pminfo *pmpt;
-
- if ( !op || op->cpuid >= nr_cpu_ids || !cpu_online(op->cpuid) )
- return -EINVAL;
- pmpt = processor_pminfo[op->cpuid];
-
- switch ( op->cmd & PM_PARA_CATEGORY_MASK )
- {
- case CPUFREQ_PARA:
- if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
- return -ENODEV;
- if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
- return -EINVAL;
- break;
- }
-
- switch ( op->cmd )
- {
- case GET_CPUFREQ_PARA:
- {
- ret = get_cpufreq_para(op);
- break;
- }
-
- case SET_CPUFREQ_GOV:
- {
- ret = set_cpufreq_gov(op);
- break;
- }
-
- case SET_CPUFREQ_PARA:
- {
- ret = set_cpufreq_para(op);
- break;
- }
-
- case GET_CPUFREQ_AVGFREQ:
- {
- op->u.get_avgfreq = cpufreq_driver_getavg(op->cpuid, USR_GETAVG);
- break;
- }
-
- case XEN_SYSCTL_pm_op_set_sched_opt_smt:
- {
- uint32_t saved_value;
-
- saved_value = sched_smt_power_savings;
- sched_smt_power_savings = !!op->u.set_sched_opt_smt;
- op->u.set_sched_opt_smt = saved_value;
-
- break;
- }
-
- case XEN_SYSCTL_pm_op_set_vcpu_migration_delay:
- {
- set_vcpu_migration_delay(op->u.set_vcpu_migration_delay);
- break;
- }
-
- case XEN_SYSCTL_pm_op_get_vcpu_migration_delay:
- {
- op->u.get_vcpu_migration_delay = get_vcpu_migration_delay();
- break;
- }
-
- case XEN_SYSCTL_pm_op_get_max_cstate:
- {
- op->u.get_max_cstate = acpi_get_cstate_limit();
- break;
- }
-
- case XEN_SYSCTL_pm_op_set_max_cstate:
- {
- acpi_set_cstate_limit(op->u.set_max_cstate);
- break;
- }
-
- case XEN_SYSCTL_pm_op_enable_turbo:
- {
- ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_ENABLED);
- break;
- }
-
- case XEN_SYSCTL_pm_op_disable_turbo:
- {
- ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_DISABLED);
- break;
- }
-
- default:
- printk("not defined sub-hypercall @ do_pm_op\n");
- ret = -ENOSYS;
- break;
- }
-
- return ret;
-}
-
-int acpi_set_pdc_bits(u32 acpi_id, XEN_GUEST_HANDLE_PARAM(uint32) pdc)
-{
- u32 bits[3];
- int ret;
-
- if ( copy_from_guest(bits, pdc, 2) )
- ret = -EFAULT;
- else if ( bits[0] != ACPI_PDC_REVISION_ID || !bits[1] )
- ret = -EINVAL;
- else if ( copy_from_guest_offset(bits + 2, pdc, 2, 1) )
- ret = -EFAULT;
- else
- {
- u32 mask = 0;
-
- if ( xen_processor_pmbits & XEN_PROCESSOR_PM_CX )
- mask |= ACPI_PDC_C_MASK | ACPI_PDC_SMP_C1PT;
- if ( xen_processor_pmbits & XEN_PROCESSOR_PM_PX )
- mask |= ACPI_PDC_P_MASK | ACPI_PDC_SMP_C1PT;
- if ( xen_processor_pmbits & XEN_PROCESSOR_PM_TX )
- mask |= ACPI_PDC_T_MASK | ACPI_PDC_SMP_C1PT;
- bits[2] &= (ACPI_PDC_C_MASK | ACPI_PDC_P_MASK | ACPI_PDC_T_MASK |
- ACPI_PDC_SMP_C1PT) & ~mask;
- ret = arch_acpi_set_pdc_bits(acpi_id, bits, mask);
- }
- if ( !ret && __copy_to_guest_offset(pdc, 2, bits + 2, 1) )
- ret = -EFAULT;
-
- return ret;
-}
diff --git a/xen/drivers/pm/Kconfig b/xen/drivers/pm/Kconfig
new file mode 100644
index 0000000..6d4fda1
--- /dev/null
+++ b/xen/drivers/pm/Kconfig
@@ -0,0 +1,3 @@
+
+config HAS_PM
+ bool
diff --git a/xen/drivers/pm/Makefile b/xen/drivers/pm/Makefile
new file mode 100644
index 0000000..2073683
--- /dev/null
+++ b/xen/drivers/pm/Makefile
@@ -0,0 +1 @@
+obj-y += stat.o
diff --git a/xen/drivers/pm/stat.c b/xen/drivers/pm/stat.c
new file mode 100644
index 0000000..2dbde1c
--- /dev/null
+++ b/xen/drivers/pm/stat.c
@@ -0,0 +1,526 @@
+/*****************************************************************************
+# pmstat.c - Power Management statistic information (Px/Cx/Tx, etc.)
+#
+# Copyright (c) 2008, Liu Jinsong <jinsong.liu@intel.com>
+#
+# 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, see <http://www.gnu.org/licenses/>.
+#
+# The full GNU General Public License is included in this distribution in the
+# file called LICENSE.
+#
+*****************************************************************************/
+
+#include <xen/lib.h>
+#include <xen/errno.h>
+#include <xen/sched.h>
+#include <xen/event.h>
+#include <xen/irq.h>
+#include <xen/iocap.h>
+#include <xen/compat.h>
+#include <xen/guest_access.h>
+#include <asm/current.h>
+#include <public/xen.h>
+#include <xen/cpumask.h>
+#include <asm/processor.h>
+#include <xen/percpu.h>
+#include <xen/domain.h>
+#include <xen/acpi.h>
+
+#include <public/sysctl.h>
+#include <xen/cpufreq.h>
+#include <xen/pmstat.h>
+
+DEFINE_PER_CPU_READ_MOSTLY(struct pm_px *, cpufreq_statistic_data);
+
+/*
+ * Get PM statistic info
+ */
+int do_get_pm_info(struct xen_sysctl_get_pmstat *op)
+{
+ int ret = 0;
+ const struct processor_pminfo *pmpt;
+
+ if ( !op || (op->cpuid >= nr_cpu_ids) || !cpu_online(op->cpuid) )
+ return -EINVAL;
+ pmpt = processor_pminfo[op->cpuid];
+
+ switch ( op->type & PMSTAT_CATEGORY_MASK )
+ {
+ case PMSTAT_CX:
+ if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_CX) )
+ return -ENODEV;
+ break;
+ case PMSTAT_PX:
+ if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
+ return -ENODEV;
+ if ( !cpufreq_driver )
+ return -ENODEV;
+ if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
+ return -EINVAL;
+ break;
+ default:
+ return -ENODEV;
+ }
+
+ switch ( op->type )
+ {
+ case PMSTAT_get_max_px:
+ {
+ op->u.getpx.total = pmpt->perf.state_count;
+ break;
+ }
+
+ case PMSTAT_get_pxstat:
+ {
+ uint32_t ct;
+ struct pm_px *pxpt;
+ spinlock_t *cpufreq_statistic_lock =
+ &per_cpu(cpufreq_statistic_lock, op->cpuid);
+
+ spin_lock(cpufreq_statistic_lock);
+
+ pxpt = per_cpu(cpufreq_statistic_data, op->cpuid);
+ if ( !pxpt || !pxpt->u.pt || !pxpt->u.trans_pt )
+ {
+ spin_unlock(cpufreq_statistic_lock);
+ return -ENODATA;
+ }
+
+ pxpt->u.usable = pmpt->perf.state_count - pmpt->perf.platform_limit;
+
+ cpufreq_residency_update(op->cpuid, pxpt->u.cur);
+
+ ct = pmpt->perf.state_count;
+ if ( copy_to_guest(op->u.getpx.trans_pt, pxpt->u.trans_pt, ct*ct) )
+ {
+ spin_unlock(cpufreq_statistic_lock);
+ ret = -EFAULT;
+ break;
+ }
+
+ if ( copy_to_guest(op->u.getpx.pt, pxpt->u.pt, ct) )
+ {
+ spin_unlock(cpufreq_statistic_lock);
+ ret = -EFAULT;
+ break;
+ }
+
+ op->u.getpx.total = pxpt->u.total;
+ op->u.getpx.usable = pxpt->u.usable;
+ op->u.getpx.last = pxpt->u.last;
+ op->u.getpx.cur = pxpt->u.cur;
+
+ spin_unlock(cpufreq_statistic_lock);
+
+ break;
+ }
+
+ case PMSTAT_reset_pxstat:
+ {
+ cpufreq_statistic_reset(op->cpuid);
+ break;
+ }
+
+ case PMSTAT_get_max_cx:
+ {
+ op->u.getcx.nr = pmstat_get_cx_nr(op->cpuid);
+ ret = 0;
+ break;
+ }
+
+ case PMSTAT_get_cxstat:
+ {
+ ret = pmstat_get_cx_stat(op->cpuid, &op->u.getcx);
+ break;
+ }
+
+ case PMSTAT_reset_cxstat:
+ {
+ ret = pmstat_reset_cx_stat(op->cpuid);
+ break;
+ }
+
+ default:
+ printk("not defined sub-hypercall @ do_get_pm_info\n");
+ ret = -ENOSYS;
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * 1. Get PM parameter
+ * 2. Provide user PM control
+ */
+static int read_scaling_available_governors(char *scaling_available_governors,
+ unsigned int size)
+{
+ unsigned int i = 0;
+ struct cpufreq_governor *t;
+
+ if ( !scaling_available_governors )
+ return -EINVAL;
+
+ list_for_each_entry(t, &cpufreq_governor_list, governor_list)
+ {
+ i += scnprintf(&scaling_available_governors[i],
+ CPUFREQ_NAME_LEN, "%s ", t->name);
+ if ( i > size )
+ return -EINVAL;
+ }
+ scaling_available_governors[i-1] = '\0';
+
+ return 0;
+}
+
+static int get_cpufreq_para(struct xen_sysctl_pm_op *op)
+{
+ uint32_t ret = 0;
+ const struct processor_pminfo *pmpt;
+ struct cpufreq_policy *policy;
+ uint32_t gov_num = 0;
+ uint32_t *affected_cpus;
+ uint32_t *scaling_available_frequencies;
+ char *scaling_available_governors;
+ struct list_head *pos;
+ uint32_t cpu, i, j = 0;
+
+ pmpt = processor_pminfo[op->cpuid];
+ policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
+
+ if ( !pmpt || !pmpt->perf.states ||
+ !policy || !policy->governor )
+ return -EINVAL;
+
+ list_for_each(pos, &cpufreq_governor_list)
+ gov_num++;
+
+ if ( (op->u.get_para.cpu_num != cpumask_weight(policy->cpus)) ||
+ (op->u.get_para.freq_num != pmpt->perf.state_count) ||
+ (op->u.get_para.gov_num != gov_num) )
+ {
+ op->u.get_para.cpu_num = cpumask_weight(policy->cpus);
+ op->u.get_para.freq_num = pmpt->perf.state_count;
+ op->u.get_para.gov_num = gov_num;
+ return -EAGAIN;
+ }
+
+ if ( !(affected_cpus = xzalloc_array(uint32_t, op->u.get_para.cpu_num)) )
+ return -ENOMEM;
+ for_each_cpu(cpu, policy->cpus)
+ affected_cpus[j++] = cpu;
+ ret = copy_to_guest(op->u.get_para.affected_cpus,
+ affected_cpus, op->u.get_para.cpu_num);
+ xfree(affected_cpus);
+ if ( ret )
+ return ret;
+
+ if ( !(scaling_available_frequencies =
+ xzalloc_array(uint32_t, op->u.get_para.freq_num)) )
+ return -ENOMEM;
+ for ( i = 0; i < op->u.get_para.freq_num; i++ )
+ scaling_available_frequencies[i] =
+ pmpt->perf.states[i].core_frequency * 1000;
+ ret = copy_to_guest(op->u.get_para.scaling_available_frequencies,
+ scaling_available_frequencies, op->u.get_para.freq_num);
+ xfree(scaling_available_frequencies);
+ if ( ret )
+ return ret;
+
+ if ( !(scaling_available_governors =
+ xzalloc_array(char, gov_num * CPUFREQ_NAME_LEN)) )
+ return -ENOMEM;
+ if ( (ret = read_scaling_available_governors(scaling_available_governors,
+ gov_num * CPUFREQ_NAME_LEN * sizeof(char))) )
+ {
+ xfree(scaling_available_governors);
+ return ret;
+ }
+ ret = copy_to_guest(op->u.get_para.scaling_available_governors,
+ scaling_available_governors, gov_num * CPUFREQ_NAME_LEN);
+ xfree(scaling_available_governors);
+ if ( ret )
+ return ret;
+
+ op->u.get_para.cpuinfo_cur_freq =
+ cpufreq_driver->get ? cpufreq_driver->get(op->cpuid) : policy->cur;
+ op->u.get_para.cpuinfo_max_freq = policy->cpuinfo.max_freq;
+ op->u.get_para.cpuinfo_min_freq = policy->cpuinfo.min_freq;
+ op->u.get_para.scaling_cur_freq = policy->cur;
+ op->u.get_para.scaling_max_freq = policy->max;
+ op->u.get_para.scaling_min_freq = policy->min;
+
+ if ( cpufreq_driver->name[0] )
+ strlcpy(op->u.get_para.scaling_driver,
+ cpufreq_driver->name, CPUFREQ_NAME_LEN);
+ else
+ strlcpy(op->u.get_para.scaling_driver, "Unknown", CPUFREQ_NAME_LEN);
+
+ if ( policy->governor->name[0] )
+ strlcpy(op->u.get_para.scaling_governor,
+ policy->governor->name, CPUFREQ_NAME_LEN);
+ else
+ strlcpy(op->u.get_para.scaling_governor, "Unknown", CPUFREQ_NAME_LEN);
+
+ /* governor specific para */
+ if ( !strnicmp(op->u.get_para.scaling_governor,
+ "userspace", CPUFREQ_NAME_LEN) )
+ {
+ op->u.get_para.u.userspace.scaling_setspeed = policy->cur;
+ }
+
+ if ( !strnicmp(op->u.get_para.scaling_governor,
+ "ondemand", CPUFREQ_NAME_LEN) )
+ {
+ ret = get_cpufreq_ondemand_para(
+ &op->u.get_para.u.ondemand.sampling_rate_max,
+ &op->u.get_para.u.ondemand.sampling_rate_min,
+ &op->u.get_para.u.ondemand.sampling_rate,
+ &op->u.get_para.u.ondemand.up_threshold);
+ }
+ op->u.get_para.turbo_enabled = cpufreq_get_turbo_status(op->cpuid);
+
+ return ret;
+}
+
+static int set_cpufreq_gov(struct xen_sysctl_pm_op *op)
+{
+ struct cpufreq_policy new_policy, *old_policy;
+
+ old_policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
+ if ( !old_policy )
+ return -EINVAL;
+
+ memcpy(&new_policy, old_policy, sizeof(struct cpufreq_policy));
+
+ new_policy.governor = __find_governor(op->u.set_gov.scaling_governor);
+ if (new_policy.governor == NULL)
+ return -EINVAL;
+
+ return __cpufreq_set_policy(old_policy, &new_policy);
+}
+
+static int set_cpufreq_para(struct xen_sysctl_pm_op *op)
+{
+ int ret = 0;
+ struct cpufreq_policy *policy;
+
+ policy = per_cpu(cpufreq_cpu_policy, op->cpuid);
+
+ if ( !policy || !policy->governor )
+ return -EINVAL;
+
+ switch(op->u.set_para.ctrl_type)
+ {
+ case SCALING_MAX_FREQ:
+ {
+ struct cpufreq_policy new_policy;
+
+ memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+ new_policy.max = op->u.set_para.ctrl_value;
+ ret = __cpufreq_set_policy(policy, &new_policy);
+
+ break;
+ }
+
+ case SCALING_MIN_FREQ:
+ {
+ struct cpufreq_policy new_policy;
+
+ memcpy(&new_policy, policy, sizeof(struct cpufreq_policy));
+ new_policy.min = op->u.set_para.ctrl_value;
+ ret = __cpufreq_set_policy(policy, &new_policy);
+
+ break;
+ }
+
+ case SCALING_SETSPEED:
+ {
+ unsigned int freq =op->u.set_para.ctrl_value;
+
+ if ( !strnicmp(policy->governor->name,
+ "userspace", CPUFREQ_NAME_LEN) )
+ ret = write_userspace_scaling_setspeed(op->cpuid, freq);
+ else
+ ret = -EINVAL;
+
+ break;
+ }
+
+ case SAMPLING_RATE:
+ {
+ unsigned int sampling_rate = op->u.set_para.ctrl_value;
+
+ if ( !strnicmp(policy->governor->name,
+ "ondemand", CPUFREQ_NAME_LEN) )
+ ret = write_ondemand_sampling_rate(sampling_rate);
+ else
+ ret = -EINVAL;
+
+ break;
+ }
+
+ case UP_THRESHOLD:
+ {
+ unsigned int up_threshold = op->u.set_para.ctrl_value;
+
+ if ( !strnicmp(policy->governor->name,
+ "ondemand", CPUFREQ_NAME_LEN) )
+ ret = write_ondemand_up_threshold(up_threshold);
+ else
+ ret = -EINVAL;
+
+ break;
+ }
+
+ default:
+ ret = -EINVAL;
+ break;
+ }
+
+ return ret;
+}
+
+int do_pm_op(struct xen_sysctl_pm_op *op)
+{
+ int ret = 0;
+ const struct processor_pminfo *pmpt;
+
+ if ( !op || op->cpuid >= nr_cpu_ids || !cpu_online(op->cpuid) )
+ return -EINVAL;
+ pmpt = processor_pminfo[op->cpuid];
+
+ switch ( op->cmd & PM_PARA_CATEGORY_MASK )
+ {
+ case CPUFREQ_PARA:
+ if ( !(xen_processor_pmbits & XEN_PROCESSOR_PM_PX) )
+ return -ENODEV;
+ if ( !pmpt || !(pmpt->perf.init & XEN_PX_INIT) )
+ return -EINVAL;
+ break;
+ }
+
+ switch ( op->cmd )
+ {
+ case GET_CPUFREQ_PARA:
+ {
+ ret = get_cpufreq_para(op);
+ break;
+ }
+
+ case SET_CPUFREQ_GOV:
+ {
+ ret = set_cpufreq_gov(op);
+ break;
+ }
+
+ case SET_CPUFREQ_PARA:
+ {
+ ret = set_cpufreq_para(op);
+ break;
+ }
+
+ case GET_CPUFREQ_AVGFREQ:
+ {
+ op->u.get_avgfreq = cpufreq_driver_getavg(op->cpuid, USR_GETAVG);
+ break;
+ }
+
+ case XEN_SYSCTL_pm_op_set_sched_opt_smt:
+ {
+ uint32_t saved_value;
+
+ saved_value = sched_smt_power_savings;
+ sched_smt_power_savings = !!op->u.set_sched_opt_smt;
+ op->u.set_sched_opt_smt = saved_value;
+
+ break;
+ }
+
+ case XEN_SYSCTL_pm_op_set_vcpu_migration_delay:
+ {
+ set_vcpu_migration_delay(op->u.set_vcpu_migration_delay);
+ break;
+ }
+
+ case XEN_SYSCTL_pm_op_get_vcpu_migration_delay:
+ {
+ op->u.get_vcpu_migration_delay = get_vcpu_migration_delay();
+ break;
+ }
+
+ case XEN_SYSCTL_pm_op_get_max_cstate:
+ {
+ op->u.get_max_cstate = acpi_get_cstate_limit();
+ break;
+ }
+
+ case XEN_SYSCTL_pm_op_set_max_cstate:
+ {
+ acpi_set_cstate_limit(op->u.set_max_cstate);
+ break;
+ }
+
+ case XEN_SYSCTL_pm_op_enable_turbo:
+ {
+ ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_ENABLED);
+ break;
+ }
+
+ case XEN_SYSCTL_pm_op_disable_turbo:
+ {
+ ret = cpufreq_update_turbo(op->cpuid, CPUFREQ_TURBO_DISABLED);
+ break;
+ }
+
+ default:
+ printk("not defined sub-hypercall @ do_pm_op\n");
+ ret = -ENOSYS;
+ break;
+ }
+
+ return ret;
+}
+
+int acpi_set_pdc_bits(u32 acpi_id, XEN_GUEST_HANDLE_PARAM(uint32) pdc)
+{
+ u32 bits[3];
+ int ret;
+
+ if ( copy_from_guest(bits, pdc, 2) )
+ ret = -EFAULT;
+ else if ( bits[0] != ACPI_PDC_REVISION_ID || !bits[1] )
+ ret = -EINVAL;
+ else if ( copy_from_guest_offset(bits + 2, pdc, 2, 1) )
+ ret = -EFAULT;
+ else
+ {
+ u32 mask = 0;
+
+ if ( xen_processor_pmbits & XEN_PROCESSOR_PM_CX )
+ mask |= ACPI_PDC_C_MASK | ACPI_PDC_SMP_C1PT;
+ if ( xen_processor_pmbits & XEN_PROCESSOR_PM_PX )
+ mask |= ACPI_PDC_P_MASK | ACPI_PDC_SMP_C1PT;
+ if ( xen_processor_pmbits & XEN_PROCESSOR_PM_TX )
+ mask |= ACPI_PDC_T_MASK | ACPI_PDC_SMP_C1PT;
+ bits[2] &= (ACPI_PDC_C_MASK | ACPI_PDC_P_MASK | ACPI_PDC_T_MASK |
+ ACPI_PDC_SMP_C1PT) & ~mask;
+ ret = arch_acpi_set_pdc_bits(acpi_id, bits, mask);
+ }
+ if ( !ret && __copy_to_guest_offset(pdc, 2, bits + 2, 1) )
+ ret = -EFAULT;
+
+ return ret;
+}
--
2.7.4
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel
next prev parent reply other threads:[~2017-11-09 17:10 UTC|newest]
Thread overview: 108+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-09 17:09 [RFC PATCH 00/31] CPUFreq on ARM Oleksandr Tyshchenko
2017-11-09 17:09 ` [RFC PATCH 01/31] cpufreq: move cpufreq.h file to the xen/include/xen location Oleksandr Tyshchenko
2017-12-02 0:35 ` Stefano Stabellini
2017-11-09 17:09 ` [RFC PATCH 02/31] pm: move processor_perf.h " Oleksandr Tyshchenko
2017-12-02 0:41 ` Stefano Stabellini
2017-11-09 17:09 ` Oleksandr Tyshchenko [this message]
2017-12-02 0:47 ` [RFC PATCH 03/31] pmstat: move pmstat.c file to the xen/drivers/pm/stat.c location Stefano Stabellini
2018-05-07 15:36 ` Jan Beulich
2018-05-18 11:14 ` Oleksandr Tyshchenko
2018-05-18 11:35 ` Jan Beulich
2018-05-18 14:13 ` Oleksandr Tyshchenko
2018-05-18 14:21 ` Jan Beulich
2017-11-09 17:09 ` [RFC PATCH 04/31] cpufreq: make turbo settings to be configurable Oleksandr Tyshchenko
2017-12-02 1:06 ` Stefano Stabellini
2017-12-02 17:25 ` Oleksandr Tyshchenko
2017-12-04 11:58 ` Andre Przywara
2017-12-05 15:23 ` Oleksandr Tyshchenko
2017-12-04 22:18 ` Stefano Stabellini
2017-12-05 11:13 ` Oleksandr Tyshchenko
2017-12-05 19:24 ` Stefano Stabellini
2017-12-06 11:28 ` Oleksandr Tyshchenko
2018-05-07 15:39 ` Jan Beulich
2018-05-18 14:36 ` Oleksandr Tyshchenko
2018-05-18 14:41 ` Jan Beulich
2017-11-09 17:09 ` [RFC PATCH 05/31] pmstat: make pmstat functions more generalizable Oleksandr Tyshchenko
2017-12-02 1:21 ` Stefano Stabellini
2017-12-04 16:21 ` Oleksandr Tyshchenko
2017-12-04 22:30 ` Stefano Stabellini
2017-11-09 17:09 ` [RFC PATCH 06/31] cpufreq: make cpufreq driver " Oleksandr Tyshchenko
2017-12-02 1:37 ` Stefano Stabellini
2017-12-04 19:34 ` Oleksandr Tyshchenko
2017-12-04 22:46 ` Stefano Stabellini
2017-12-05 19:29 ` Oleksandr Tyshchenko
2017-12-05 20:48 ` Stefano Stabellini
2017-12-06 7:54 ` Jan Beulich
2017-12-06 23:44 ` Stefano Stabellini
2017-12-07 8:45 ` Jan Beulich
2017-12-07 20:31 ` Oleksandr Tyshchenko
2017-12-08 8:07 ` Jan Beulich
2017-12-08 12:16 ` Oleksandr Tyshchenko
2017-11-09 17:09 ` [RFC PATCH 07/31] xenpm: Clarify xenpm usage Oleksandr Tyshchenko
2017-11-09 17:13 ` Wei Liu
2017-12-02 1:28 ` Stefano Stabellini
2017-11-09 17:09 ` [RFC PATCH 08/31] xen/device-tree: Add dt_count_phandle_with_args helper Oleksandr Tyshchenko
2017-11-09 17:09 ` [RFC PATCH 09/31] xen/device-tree: Add dt_property_for_each_string macros Oleksandr Tyshchenko
2017-12-04 23:24 ` Stefano Stabellini
2017-12-05 14:19 ` Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 10/31] xen/device-tree: Add dt_property_read_u32_index helper Oleksandr Tyshchenko
2017-12-04 23:29 ` Stefano Stabellini
2017-11-09 17:10 ` [RFC PATCH 11/31] xen/device-tree: Add dt_property_count_elems_of_size helper Oleksandr Tyshchenko
2017-12-04 23:29 ` Stefano Stabellini
2017-11-09 17:10 ` [RFC PATCH 12/31] xen/device-tree: Add dt_property_read_string_helper and friends Oleksandr Tyshchenko
2017-12-04 23:29 ` Stefano Stabellini
2017-11-09 17:10 ` [RFC PATCH 13/31] xen/arm: Add driver_data field to struct device Oleksandr Tyshchenko
2017-12-04 23:31 ` Stefano Stabellini
2017-12-05 11:26 ` Julien Grall
2017-12-05 12:57 ` Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 14/31] xen/arm: Add DEVICE_MAILBOX device class Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 15/31] xen/arm: Store device-tree node per cpu Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 16/31] arm: add SMC wrapper that is compatible with SMCCC Oleksandr Tyshchenko
2017-12-05 2:30 ` Stefano Stabellini
2017-12-05 15:33 ` Volodymyr Babchuk
2017-12-05 17:21 ` Stefano Stabellini
2017-12-05 14:58 ` Julien Grall
2017-12-05 17:08 ` Volodymyr Babchuk
2017-12-05 17:08 ` Julien Grall
2017-12-05 17:20 ` Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 17/31] xen/arm: Add ARM System Control and Power Interface (SCPI) protocol Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 18/31] xen/arm: Add mailbox infrastructure Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 19/31] xen/arm: Introduce ARM SMC based mailbox Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 20/31] xen/arm: Add common header file wrappers.h Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 21/31] xen/arm: Add rxdone_auto flag to mbox_controller structure Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 22/31] xen/arm: Add Xen changes to SCPI protocol Oleksandr Tyshchenko
2017-12-05 21:20 ` Stefano Stabellini
2017-12-05 21:41 ` Julien Grall
2017-12-06 10:08 ` Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 23/31] xen/arm: Add Xen changes to mailbox infrastructure Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 24/31] xen/arm: Add Xen changes to ARM SMC based mailbox Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 25/31] xen/arm: Use non-blocking mode for SCPI protocol Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 26/31] xen/arm: Don't set txdone_poll flag for ARM SMC mailbox Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 27/31] cpufreq: hack: perf->states isn't a real guest handle on ARM Oleksandr Tyshchenko
2017-12-05 21:34 ` Stefano Stabellini
2017-11-09 17:10 ` [RFC PATCH 28/31] xen/arm: Introduce SCPI based CPUFreq driver Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 29/31] xen/arm: Introduce CPUFreq Interface component Oleksandr Tyshchenko
2017-12-05 22:25 ` Stefano Stabellini
2017-12-06 10:54 ` Oleksandr Tyshchenko
2017-12-07 1:40 ` Stefano Stabellini
2017-11-09 17:10 ` [RFC PATCH 30/31] xen/arm: Build CPUFreq components Oleksandr Tyshchenko
2017-11-09 17:10 ` [RFC PATCH 31/31] xen/arm: Enable CPUFreq on ARM Oleksandr Tyshchenko
2017-11-09 17:18 ` [RFC PATCH 00/31] " Andrii Anisov
2017-11-13 19:40 ` Oleksandr Tyshchenko
2017-11-13 15:21 ` Andre Przywara
2017-11-13 19:40 ` Oleksandr Tyshchenko
2017-11-14 10:49 ` Andre Przywara
2017-11-14 20:46 ` Oleksandr Tyshchenko
2017-11-15 3:03 ` Jassi Brar
2017-11-15 13:28 ` Andre Przywara
2017-11-15 15:18 ` Jassi Brar
2017-11-15 14:28 ` Andre Przywara
2017-11-16 14:57 ` Oleksandr Tyshchenko
2017-11-16 17:04 ` Andre Przywara
2017-11-17 14:01 ` Julien Grall
2017-11-17 18:36 ` Oleksandr Tyshchenko
2017-11-17 14:55 ` Oleksandr Tyshchenko
2017-11-17 16:41 ` Andre Przywara
2017-11-17 17:22 ` Oleksandr Tyshchenko
2017-12-05 22:26 ` Stefano Stabellini
2017-12-06 10:10 ` Oleksandr Tyshchenko
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=1510247421-24094-4-git-send-email-olekstysh@gmail.com \
--to=olekstysh@gmail.com \
--cc=andrew.cooper3@citrix.com \
--cc=jbeulich@suse.com \
--cc=julien.grall@linaro.org \
--cc=oleksandr.dmytryshyn@globallogic.com \
--cc=oleksandr_tyshchenko@epam.com \
--cc=sstabellini@kernel.org \
--cc=xen-devel@lists.xenproject.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).