diff mbox

[RFC,27/31] cpufreq: hack: perf->states isn't a real guest handle on ARM

Message ID 1510247421-24094-28-git-send-email-olekstysh@gmail.com (mailing list archive)
State New, archived
Headers show

Commit Message

Oleksandr Tyshchenko Nov. 9, 2017, 5:10 p.m. UTC
From: Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>

This patch is just a temp solution to highlight a problem which
should be resolved in a proper way.

set_px_pminfo() is intended to be called from platform hypercall
where "perf" argument was entirely filled in by hwdom.

But unlike x86 we don't get this info from hwdom on ARM,
we get it from other sources (device tree + firmware). In order to
retain function interface, we emulate receiving hypercall and
pass argument which function expects to see. Although "perf->states"
looks like a guest handle it is not a real handle and we can't use
copy_from_guest() over it. As only scpi-cpufreq sets XEN_PX_DATA flag
use it as an indicator to do memcpy.

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>
---
 xen/drivers/cpufreq/cpufreq.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)
diff mbox

Patch

diff --git a/xen/drivers/cpufreq/cpufreq.c b/xen/drivers/cpufreq/cpufreq.c
index 64e1ae7..1022cd1 100644
--- a/xen/drivers/cpufreq/cpufreq.c
+++ b/xen/drivers/cpufreq/cpufreq.c
@@ -558,11 +558,22 @@  int set_px_pminfo(uint32_t acpi_id, struct xen_processor_performance *dom0_px_in
             ret = -ENOMEM;
             goto out;
         }
-        if ( copy_from_guest(pxpt->states, dom0_px_info->states,
-                             dom0_px_info->state_count) )
+
+        if ( dom0_px_info->flags == XEN_PX_DATA )
         {
-            ret = -EFAULT;
-            goto out;
+            struct xen_processor_px *states = (dom0_px_info->states).p;
+
+            memcpy(pxpt->states, states,
+                   dom0_px_info->state_count * sizeof(struct xen_processor_px));
+        }
+        else
+        {
+            if ( copy_from_guest(pxpt->states, dom0_px_info->states,
+                                 dom0_px_info->state_count) )
+            {
+                ret = -EFAULT;
+                goto out;
+            }
         }
         pxpt->state_count = dom0_px_info->state_count;