[PATCH v2 15/15] x86/hyperlaunch: add capabilities to boot domain

Daniel P. Smith posted 15 patches 1 year, 1 month ago
There is a newer version of this series
[PATCH v2 15/15] x86/hyperlaunch: add capabilities to boot domain
Posted by Daniel P. Smith 1 year, 1 month ago
Introduce the ability to assign capabilities to a domain via its definition in
device tree. The first capability enabled to select is the control domain
capability. The capability property is a bitfield in both the device tree and
`struct boot_domain`.

Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Reviewed-by: Jason Andryuk <jason.andryuk@amd.com>
---
Changes since v1:
- switch to nested else if
- switch from match_fdt to strncmp
- drop ternary for name selection
- coding style changes
---
 xen/arch/x86/domain-builder/core.c    |  1 +
 xen/arch/x86/domain-builder/fdt.c     | 12 ++++++++++++
 xen/arch/x86/include/asm/bootdomain.h |  4 ++++
 xen/arch/x86/setup.c                  |  6 +++++-
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/xen/arch/x86/domain-builder/core.c b/xen/arch/x86/domain-builder/core.c
index 91d1b7367e76..589496b6a3e1 100644
--- a/xen/arch/x86/domain-builder/core.c
+++ b/xen/arch/x86/domain-builder/core.c
@@ -96,6 +96,7 @@ void __init builder_init(struct boot_info *bi)
         i = first_boot_module_index(bi, BOOTMOD_UNKNOWN);
         bi->mods[i].type = BOOTMOD_KERNEL;
         bi->domains[0].kernel = &bi->mods[i];
+        bi->domains[0].capabilities |= BUILD_CAPS_CONTROL;
         bi->nr_domains = 1;
     }
 }
diff --git a/xen/arch/x86/domain-builder/fdt.c b/xen/arch/x86/domain-builder/fdt.c
index 70a793db199b..e90b230eeffe 100644
--- a/xen/arch/x86/domain-builder/fdt.c
+++ b/xen/arch/x86/domain-builder/fdt.c
@@ -158,6 +158,18 @@ static int __init process_domain_node(
             bd->max_vcpus = val;
             printk("  max vcpus: %d\n", bd->max_vcpus);
         }
+        else if ( strncmp(prop_name, "capabilities", name_len) == 0 )
+        {
+            if ( fdt_prop_as_u32(prop, &bd->capabilities) != 0 )
+            {
+                printk("  failed processing domain id for domain %s\n", name);
+                return -EINVAL;
+            }
+            printk("  caps: ");
+            if ( bd->capabilities & BUILD_CAPS_CONTROL )
+                printk("c");
+            printk("\n");
+        }
     }
 
     fdt_for_each_subnode(node, fdt, dom_node)
diff --git a/xen/arch/x86/include/asm/bootdomain.h b/xen/arch/x86/include/asm/bootdomain.h
index 1a15273043f5..67f43c13e905 100644
--- a/xen/arch/x86/include/asm/bootdomain.h
+++ b/xen/arch/x86/include/asm/bootdomain.h
@@ -15,6 +15,10 @@ struct boot_domain {
 
     domid_t domid;
 
+#define BUILD_CAPS_NONE          (0)
+#define BUILD_CAPS_CONTROL       (1 << 0)
+    uint32_t capabilities;
+
                                           /* On     | Off    */
 #define BUILD_MODE_PARAVIRT      (1 << 0) /* PV     | PVH/HVM */
 #define BUILD_MODE_ENABLE_DM     (1 << 1) /* HVM    | PVH     */
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index a87e122b5a61..0fb8572b7145 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -1002,6 +1002,7 @@ static size_t __init domain_cmdline_size(
 static struct domain *__init create_dom0(struct boot_info *bi)
 {
     char *cmdline = NULL;
+    unsigned int create_flags = 0;
     struct xen_domctl_createdomain dom0_cfg = {
         .flags = IS_ENABLED(CONFIG_TBOOT) ? XEN_DOMCTL_CDF_s3_integrity : 0,
         .max_evtchn_port = -1,
@@ -1033,7 +1034,10 @@ static struct domain *__init create_dom0(struct boot_info *bi)
     if ( bd->domid == DOMID_INVALID )
         /* Create initial domain.  Not d0 for pvshim. */
         bd->domid = get_initial_domain_id();
-    d = domain_create(bd->domid, &dom0_cfg, pv_shim ? 0 : CDF_privileged);
+    if ( bd->capabilities & BUILD_CAPS_CONTROL )
+        create_flags |= CDF_privileged;
+    d = domain_create(bd->domid, &dom0_cfg,
+                      pv_shim ? 0 : create_flags);
     if ( IS_ERR(d) )
         panic("Error creating d%u: %ld\n", bd->domid, PTR_ERR(d));
 
-- 
2.30.2
Re: [PATCH v2 15/15] x86/hyperlaunch: add capabilities to boot domain
Posted by Jan Beulich 1 year ago
On 26.12.2024 17:57, Daniel P. Smith wrote:
> Introduce the ability to assign capabilities to a domain via its definition in
> device tree. The first capability enabled to select is the control domain
> capability.

Hmm, and not at the same time another one to select "hardware domain"?

> --- a/xen/arch/x86/domain-builder/fdt.c
> +++ b/xen/arch/x86/domain-builder/fdt.c
> @@ -158,6 +158,18 @@ static int __init process_domain_node(
>              bd->max_vcpus = val;
>              printk("  max vcpus: %d\n", bd->max_vcpus);
>          }
> +        else if ( strncmp(prop_name, "capabilities", name_len) == 0 )
> +        {
> +            if ( fdt_prop_as_u32(prop, &bd->capabilities) != 0 )
> +            {
> +                printk("  failed processing domain id for domain %s\n", name);

"domain id"?

Jan
Re: [PATCH v2 15/15] x86/hyperlaunch: add capabilities to boot domain
Posted by Jason Andryuk 1 year ago
On 2025-02-04 06:13, Jan Beulich wrote:
> On 26.12.2024 17:57, Daniel P. Smith wrote:
>> Introduce the ability to assign capabilities to a domain via its definition in
>> device tree. The first capability enabled to select is the control domain
>> capability.
> 
> Hmm, and not at the same time another one to select "hardware domain"?

Dan has an un-submitted patch that adds in hardware domain.  Related, I 
was preparing a dom0less patch that adds control, hardware, and xenstore 
capabilities.

I've included it below.  To keep them aligned, it creates a new common 
public header with defines for the capabilities.

Regards,
Jason

commit 5d329e6ef7128a4999b28de6745810c595a7f9e8
Author: Jason Andryuk <jason.andryuk@amd.com>
Date:   Fri Jan 31 14:50:53 2025 -0500

     xen/arm: Add capabilities to dom0less

     Add capabilities property to dom0less to allow building a
     disaggregated system.

     Introduce bootfdt.h to contain these constants.

     Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
     ---
     There is overlap with hyperlaunch.  The numeric values are the same.
     Hyperlaunch doesn't expose the values in a public header as done here.
     Is this to be expected for dom0less?  It seems most of dom0less 
isn't in
     a header, but just in docs.

     Hyperlaunch uses BUILD_CAPS_, but I chose DOMAIN_CAPS_ since there are
     domain-level capabilities.

diff --git a/docs/misc/arm/device-tree/booting.txt 
b/docs/misc/arm/device-tree/booting.txt
index 4346953a71..2cd99f9b79 100644
--- a/docs/misc/arm/device-tree/booting.txt
+++ b/docs/misc/arm/device-tree/booting.txt
@@ -167,6 +167,17 @@ with the following properties:
      Refer to docs/misc/cache_coloring.rst for syntax. This option is 
applicable
      only to Arm64 guests.

+- capabilities
+    Optional.  A bit field of domain capabilities for a disaggregated
+    system.  A traditional dom0 has all all of these capabilities, and a
+    domU has none of them.
+
+    0x1 DOMAIN_CAPS_CONTROL  - A privileged, control domain
+    0x2 DOMAIN_CAPS_HARDWARE - The hardware domain - there can be only 1
+    0x4 DOMAIN_CAPS_XENSTORE - The xenstore domain - there can be only 1
+
+    The default is no capabilities.
+
  - vpl011

      An empty property to enable/disable a virtual pl011 for the guest to
diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
index 9f24463ebd..bb49142d24 100644
--- a/xen/arch/arm/dom0less-build.c
+++ b/xen/arch/arm/dom0less-build.c
@@ -12,6 +12,7 @@
  #include <xen/sizes.h>
  #include <xen/vmap.h>

+#include <public/bootfdt.h>
  #include <public/io/xs_wire.h>

  #include <asm/arm64/sve.h>
@@ -1236,6 +1237,18 @@ void __init create_domUs(void)
              d_cfg.max_maptrack_frames = val;
          }

+        if ( dt_property_read_u32(node, "capabilities", &val) )
+        {
+            if ( val & ~DOMAIN_CAPS_MASK )
+                panic("invalid capabilities (%"PRIu32") overflow\n", val);
+            if ( val & DOMAIN_CAPS_CONTROL )
+                flags |= CDF_privileged;
+            if ( val & DOMAIN_CAPS_HARDWARE )
+                flags |= CDF_hardware;
+            if ( val & DOMAIN_CAPS_XENSTORE )
+                d_cfg.flags |= XEN_DOMCTL_CDF_xs_domain;
+        }
+
          if ( dt_get_property(node, "sve", &val) )
          {
  #ifdef CONFIG_ARM64_SVE
diff --git a/xen/common/domain.c b/xen/common/domain.c
index c170597410..dbeda908be 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -701,6 +701,10 @@ struct domain *domain_create(domid_t domid,
      /* Sort out our idea of is_hardware_domain(). */
      if ( flags & CDF_hardware || domid == hardware_domid )
      {
+        if ( hardware_domain )
+            panic("Can't set %pd - %pd is already hardware domain\n", d,
+                  hardware_domain);
+
          if ( hardware_domid < 0 || hardware_domid >= 
DOMID_FIRST_RESERVED )
              panic("The value of hardware_dom must be a valid domain 
ID\n");

diff --git a/xen/include/public/bootfdt.h b/xen/include/public/bootfdt.h
new file mode 100644
index 0000000000..4e87aca8ac
--- /dev/null
+++ b/xen/include/public/bootfdt.h
@@ -0,0 +1,27 @@
+/* SPDX-License-Identifier: MIT */
+/*
+ * Xen Device Tree boot information
+ *
+ * Information for configuring Xen domains created at boot time.
+ */
+
+#ifndef __XEN_PUBLIC_BOOTFDT_H__
+#define __XEN_PUBLIC_BOOTFDT_H__
+
+/* Domain Capabilities specified in the "capabilities" property.  Use of
+ * this property allows splitting up the monolithic dom0 into separate,
+ * less privileged components.  A regular domU has no capabilities
+ * (which is the default if nothing is specified).  A traditional dom0
+ * has all three capabilities.*/
+
+/* Control/Privileged domain capable of affecting other domains. */
+#define DOMAIN_CAPS_CONTROL  (1 << 0)
+/* Hardware domain controlling physical hardware.  Typically providing
+ * backends to other domains.  */
+#define DOMAIN_CAPS_HARDWARE (1 << 1)
+/* Xenstore domain. */
+#define DOMAIN_CAPS_XENSTORE (1 << 2)
+#define DOMAIN_CAPS_MASK     (DOMAIN_CAPS_CONTROL | 
DOMAIN_CAPS_HARDWARE | \
+                              DOMAIN_CAPS_XENSTORE)
+
+#endif /* __XEN_PUBLIC_BOOTFDT_H__ */