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

[RFC PATCH 1/4] sysctl: Introduce XEN_SYSCTL_get_cpu_status_map



Introduce XEN_SYSCTL_get_cpu_status_map as a way to get bitmaps of
cpu_online_map, cpu_present_map and cpu_possible_map (if available).

Signed-off-by: Teddy Astie <teddy.astie@xxxxxxxxxx>
---
On x86, cpu_possible_map doesn't exist, that may not be expected.

Should we add additional infos like cpu_sibling_mask and cpu_core_mask ?

 tools/include/xenctrl.h     |  4 ++++
 tools/libs/ctrl/xc_misc.c   | 45 +++++++++++++++++++++++++++++++++++++
 xen/common/sysctl.c         | 34 ++++++++++++++++++++++++++++
 xen/include/public/sysctl.h | 13 +++++++++++
 xen/xsm/flask/hooks.c       |  1 +
 5 files changed, 97 insertions(+)

diff --git a/tools/include/xenctrl.h b/tools/include/xenctrl.h
index 9f00d4a19d..55804f2f1c 100644
--- a/tools/include/xenctrl.h
+++ b/tools/include/xenctrl.h
@@ -1145,6 +1145,10 @@ typedef uint32_t xc_node_to_node_dist_t;
 int xc_physinfo(xc_interface *xch, xc_physinfo_t *info);
 int xc_cputopoinfo(xc_interface *xch, unsigned *max_cpus,
                    xc_cputopo_t *cputopo);
+int xc_get_cpu_status_map(xc_interface *xch, unsigned nr_cpus,
+                          xc_cpumap_t cpu_online_map,
+                          xc_cpumap_t cpu_present_map,
+                          xc_cpumap_t cpu_possible_map);
 int xc_microcode_update(xc_interface *xch, const void *buf,
                         size_t len, unsigned int flags);
 int xc_get_cpu_version(xc_interface *xch, struct xenpf_pcpu_version *cpu_ver);
diff --git a/tools/libs/ctrl/xc_misc.c b/tools/libs/ctrl/xc_misc.c
index 10ddf85667..bff4f5ff01 100644
--- a/tools/libs/ctrl/xc_misc.c
+++ b/tools/libs/ctrl/xc_misc.c
@@ -264,6 +264,51 @@ int xc_get_ucode_revision(xc_interface *xch,
     return 0;
 }
 
+int xc_get_cpu_status_map(xc_interface *xch, unsigned nr_cpus,
+                          xc_cpumap_t cpu_online_map,
+                          xc_cpumap_t cpu_present_map,
+                          xc_cpumap_t cpu_possible_map)
+{
+    int ret;
+    struct xen_sysctl sysctl = {};
+    struct xen_sysctl_cpu_status_map cpu_status_map;
+    DECLARE_HYPERCALL_BOUNCE(cpu_online_map, (nr_cpus + 7) / 8,
+                             XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+    DECLARE_HYPERCALL_BOUNCE(cpu_present_map, (nr_cpus + 7) / 8,
+                             XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+    DECLARE_HYPERCALL_BOUNCE(cpu_possible_map, (nr_cpus + 7) / 8,
+                             XC_HYPERCALL_BUFFER_BOUNCE_OUT);
+
+    if ( (ret = xc_hypercall_bounce_pre(xch, cpu_online_map)) )
+        goto out;
+
+    if ( (ret = xc_hypercall_bounce_pre(xch, cpu_present_map)) )
+        goto out;
+
+    if ( (ret = xc_hypercall_bounce_pre(xch, cpu_possible_map)) )
+        goto out;
+
+    sysctl.cmd = XEN_SYSCTL_get_cpu_status_map;
+
+    set_xen_guest_handle(cpu_status_map.cpu_online_map.bitmap, cpu_online_map);
+    cpu_status_map.cpu_online_map.nr_bits = nr_cpus;
+    set_xen_guest_handle(cpu_status_map.cpu_present_map.bitmap, 
cpu_present_map);
+    cpu_status_map.cpu_present_map.nr_bits = nr_cpus;
+    set_xen_guest_handle(cpu_status_map.cpu_possible_map.bitmap, 
cpu_possible_map);
+    cpu_status_map.cpu_possible_map.nr_bits = nr_cpus;
+
+    sysctl.u.cpu_status_map = cpu_status_map;
+
+    ret = do_sysctl(xch, &sysctl);
+
+out:
+    xc_hypercall_bounce_post(xch, cpu_online_map);
+    xc_hypercall_bounce_post(xch, cpu_present_map);
+    xc_hypercall_bounce_post(xch, cpu_possible_map);
+
+    return ret;
+}
+
 int xc_cputopoinfo(xc_interface *xch, unsigned *max_cpus,
                    xc_cputopo_t *cputopo)
 {
diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c
index 8fb5ff0af3..840b2243bf 100644
--- a/xen/common/sysctl.c
+++ b/xen/common/sysctl.c
@@ -474,6 +474,40 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) 
u_sysctl)
         if ( ret != -ENOSYS && ret != -EOPNOTSUPP )
             copyback = 1;
         break;
+    
+    case XEN_SYSCTL_get_cpu_status_map:
+    {
+        struct xen_sysctl_cpu_status_map *csm = &op->u.cpu_status_map;
+
+        if ( !guest_handle_is_null(csm->cpu_online_map.bitmap) )
+        {
+            ret = cpumask_to_xenctl_bitmap(&csm->cpu_online_map,
+                                           &cpu_online_map);
+            if ( ret )
+                break;
+        }
+
+        if ( !guest_handle_is_null(csm->cpu_present_map.bitmap) )
+        {
+            ret = cpumask_to_xenctl_bitmap(&csm->cpu_present_map,
+                                           &cpu_present_map);
+            if ( ret )
+                break;
+        }
+
+        if ( !guest_handle_is_null(csm->cpu_possible_map.bitmap) )
+        {
+#ifdef CONFIG_X86
+            /* On x86, cpu_possible_map doesn't exist, use cpumask_all 
instead. */
+            ret = cpumask_to_xenctl_bitmap(&csm->cpu_possible_map,
+                                           &cpumask_all);
+#else
+            ret = cpumask_to_xenctl_bitmap(&csm->cpu_possible_map,
+                                           &cpu_possible_map);
+#endif
+        }
+        break;
+    }
 
     default:
         ret = arch_do_sysctl(op, u_sysctl);
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index 63d0ee062b..3a2a1d2402 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -1181,6 +1181,17 @@ struct xen_sysctl_livepatch_op {
     } u;
 };
 
+/* 
+ * XEN_SYSCTL_get_cpu_status_map
+ *
+ * Get bitmaps of CPU status (possible, online, present).
+ */
+struct xen_sysctl_cpu_status_map {
+    struct xenctl_bitmap cpu_online_map;
+    struct xenctl_bitmap cpu_present_map;
+    struct xenctl_bitmap cpu_possible_map;
+};
+
 #if defined(__i386__) || defined(__x86_64__)
 /*
  * XEN_SYSCTL_get_cpu_policy (x86 specific)
@@ -1262,6 +1273,7 @@ struct xen_sysctl {
 /* #define XEN_SYSCTL_set_parameter              28 */
 #define XEN_SYSCTL_get_cpu_policy                29
 #define XEN_SYSCTL_dt_overlay                    30
+#define XEN_SYSCTL_get_cpu_status_map            31
     uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
     union {
         struct xen_sysctl_readconsole       readconsole;
@@ -1288,6 +1300,7 @@ struct xen_sysctl {
         struct xen_sysctl_psr_alloc         psr_alloc;
         struct xen_sysctl_cpu_featureset    cpu_featureset;
         struct xen_sysctl_livepatch_op      livepatch;
+        struct xen_sysctl_cpu_status_map    cpu_status_map;
 #if defined(__i386__) || defined(__x86_64__)
         struct xen_sysctl_cpu_policy        cpu_policy;
 #endif
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index d65ba0aeae..4ea0aeb1bb 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -952,6 +952,7 @@ static int cf_check flask_sysctl(const struct xen_sysctl 
*op)
     case XEN_SYSCTL_numainfo:
     case XEN_SYSCTL_pcitopoinfo:
     case XEN_SYSCTL_get_cpu_policy:
+    case XEN_SYSCTL_get_cpu_status_map:
         return domain_has_xen(current->domain, XEN__PHYSINFO);
 
     case XEN_SYSCTL_getdomaininfolist:
-- 
2.55.0



--
Teddy Astie | Vates XCP-ng Developer

XCP-ng & Xen Orchestra - Vates solutions

web: https://vates.tech

 


Rackspace

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