Add the "llc-colors" Device Tree property to express DomUs and Dom0less
color configurations.
Based on original work from: Luca Miccio <lucmiccio@gmail.com>
Signed-off-by: Carlo Nonato <carlo.nonato@minervasys.tech>
Signed-off-by: Marco Solieri <marco.solieri@minervasys.tech>
Reviewed-by: Jan Beulich <jbeulich@suse.com> # non-Arm
Reviewed-by: Michal Orzel <michal.orzel@amd.com>
---
v13:
- no changes
v12:
- no changes
v11:
- made clear that llc-colors device-tree property is Arm64-only in booting.txt
v10:
- no changes
v9:
- use best-effort allocation in domain_set_llc_colors_from_str()
v8:
- fixed memory leak on error path of domain_set_llc_colors_from_str()
- realloc colors array after parsing from string to reduce memory usage
v7:
- removed alloc_colors() helper usage from domain_set_llc_colors_from_str()
v6:
- rewrote domain_set_llc_colors_from_str() to be more explicit
v5:
- static-mem check has been moved in a previous patch
- added domain_set_llc_colors_from_str() to set colors after domain creation
---
docs/misc/arm/device-tree/booting.txt | 5 +++
docs/misc/cache-coloring.rst | 48 +++++++++++++++++++++++++++
xen/arch/arm/dom0less-build.c | 10 ++++++
xen/common/llc-coloring.c | 40 ++++++++++++++++++++++
xen/include/xen/llc-coloring.h | 1 +
xen/include/xen/xmalloc.h | 12 +++++++
6 files changed, 116 insertions(+)
diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-tree/booting.txt
index 3a04f5c57f..9c881baccc 100644
--- a/docs/misc/arm/device-tree/booting.txt
+++ b/docs/misc/arm/device-tree/booting.txt
@@ -162,6 +162,11 @@ with the following properties:
An integer specifying the number of vcpus to allocate to the guest.
+- llc-colors
+ A string specifying the LLC color configuration for the guest.
+ Refer to docs/misc/cache_coloring.rst for syntax. This option is applicable
+ only to Arm64 guests.
+
- vpl011
An empty property to enable/disable a virtual pl011 for the guest to
diff --git a/docs/misc/cache-coloring.rst b/docs/misc/cache-coloring.rst
index 7b47d0ed92..e097e74032 100644
--- a/docs/misc/cache-coloring.rst
+++ b/docs/misc/cache-coloring.rst
@@ -14,6 +14,7 @@ If needed, change the maximum number of colors with
``CONFIG_LLC_COLORS_ORDER=<n>``.
Runtime configuration is done via `Command line parameters`_.
+For DomUs follow `DomUs configuration`_.
Background
**********
@@ -149,6 +150,53 @@ LLC specs can be manually set via the above command line parameters. This
bypasses any auto-probing and it's used to overcome failing situations, such as
flawed probing logic, or for debugging/testing purposes.
+DomUs configuration
+*******************
+
+DomUs colors can be set either in the ``xl`` configuration file (documentation
+at `docs/man/xl.cfg.pod.5.in`) or via Device Tree (documentation at
+`docs/misc/arm/device-tree/booting.txt`) using the ``llc-colors`` option.
+For example:
+
+::
+
+ xen,xen-bootargs = "console=dtuart dtuart=serial0 dom0_mem=1G dom0_max_vcpus=1 sched=null llc-coloring=on dom0-llc-colors=2-6";
+ xen,dom0-bootargs "console=hvc0 earlycon=xen earlyprintk=xen root=/dev/ram0"
+
+ dom0 {
+ compatible = "xen,linux-zimage" "xen,multiboot-module";
+ reg = <0x0 0x1000000 0x0 15858176>;
+ };
+
+ dom0-ramdisk {
+ compatible = "xen,linux-initrd" "xen,multiboot-module";
+ reg = <0x0 0x2000000 0x0 20638062>;
+ };
+
+ domU0 {
+ #address-cells = <0x1>;
+ #size-cells = <0x1>;
+ compatible = "xen,domain";
+ memory = <0x0 0x40000>;
+ llc-colors = "4-8,10,11,12";
+ cpus = <0x1>;
+ vpl011 = <0x1>;
+
+ module@2000000 {
+ compatible = "multiboot,kernel", "multiboot,module";
+ reg = <0x2000000 0xffffff>;
+ bootargs = "console=ttyAMA0";
+ };
+
+ module@30000000 {
+ compatible = "multiboot,ramdisk", "multiboot,module";
+ reg = <0x3000000 0xffffff>;
+ };
+ };
+
+**Note:** If no color configuration is provided for a domain, the default one,
+which corresponds to all available colors is used instead.
+
Known issues and limitations
****************************
diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
index 67b1503647..49d1f14d65 100644
--- a/xen/arch/arm/dom0less-build.c
+++ b/xen/arch/arm/dom0less-build.c
@@ -817,6 +817,7 @@ void __init create_domUs(void)
bool iommu = false;
const struct dt_device_node *cpupool_node,
*chosen = dt_find_node_by_path("/chosen");
+ const char *llc_colors_str = NULL;
BUG_ON(chosen == NULL);
dt_for_each_child_node(chosen, node)
@@ -965,6 +966,10 @@ void __init create_domUs(void)
#endif
}
+ dt_property_read_string(node, "llc-colors", &llc_colors_str);
+ if ( !llc_coloring_enabled && llc_colors_str )
+ panic("'llc-colors' found, but LLC coloring is disabled\n");
+
/*
* The variable max_init_domid is initialized with zero, so here it's
* very important to use the pre-increment operator to call
@@ -975,6 +980,11 @@ void __init create_domUs(void)
panic("Error creating domain %s (rc = %ld)\n",
dt_node_name(node), PTR_ERR(d));
+ if ( llc_coloring_enabled &&
+ (rc = domain_set_llc_colors_from_str(d, llc_colors_str)) )
+ panic("Error initializing LLC coloring for domain %s (rc = %d)\n",
+ dt_node_name(node), rc);
+
d->is_console = true;
dt_device_set_used_by(node, d->domain_id);
diff --git a/xen/common/llc-coloring.c b/xen/common/llc-coloring.c
index 3dd1aaa4df..5a0e3bac59 100644
--- a/xen/common/llc-coloring.c
+++ b/xen/common/llc-coloring.c
@@ -282,6 +282,46 @@ void domain_llc_coloring_free(struct domain *d)
xfree(__va(__pa(d->llc_colors)));
}
+int __init domain_set_llc_colors_from_str(struct domain *d, const char *str)
+{
+ int err;
+ unsigned int *colors, num_colors;
+
+ if ( !str )
+ {
+ domain_set_default_colors(d);
+ return 0;
+ }
+
+ colors = xmalloc_array(unsigned int, max_nr_colors);
+ if ( !colors )
+ return -ENOMEM;
+
+ err = parse_color_config(str, colors, max_nr_colors, &num_colors);
+ if ( err )
+ {
+ printk(XENLOG_ERR "Error parsing LLC color configuration");
+ xfree(colors);
+ return err;
+ }
+
+ if ( !check_colors(colors, num_colors) )
+ {
+ printk(XENLOG_ERR "%pd: bad LLC color config\n", d);
+ xfree(colors);
+ return -EINVAL;
+ }
+
+ /* Adjust the size cause it was initially set to max_nr_colors */
+ d->llc_colors = xrealloc_array(colors, num_colors);
+ if ( !d->llc_colors )
+ d->llc_colors = colors;
+
+ d->num_llc_colors = num_colors;
+
+ return 0;
+}
+
/*
* Local variables:
* mode: C
diff --git a/xen/include/xen/llc-coloring.h b/xen/include/xen/llc-coloring.h
index 26353c808a..5d1355b3c9 100644
--- a/xen/include/xen/llc-coloring.h
+++ b/xen/include/xen/llc-coloring.h
@@ -34,6 +34,7 @@ void arch_llc_coloring_init(void);
int dom0_set_llc_colors(struct domain *d);
int domain_set_llc_colors(struct domain *d,
const struct xen_domctl_set_llc_colors *config);
+int domain_set_llc_colors_from_str(struct domain *d, const char *str);
#endif /* __XEN_LLC_COLORING_H__ */
diff --git a/xen/include/xen/xmalloc.h b/xen/include/xen/xmalloc.h
index b903fa2e26..f0412fb4e0 100644
--- a/xen/include/xen/xmalloc.h
+++ b/xen/include/xen/xmalloc.h
@@ -37,6 +37,9 @@
((_type *)_xmalloc_array(sizeof(_type), __alignof__(_type), _num))
#define xzalloc_array(_type, _num) \
((_type *)_xzalloc_array(sizeof(_type), __alignof__(_type), _num))
+#define xrealloc_array(_ptr, _num) \
+ ((typeof(_ptr))_xrealloc_array(_ptr, sizeof(typeof(*(_ptr))), \
+ __alignof__(typeof(*(_ptr))), _num))
/* Allocate space for a structure with a flexible array of typed objects. */
#define xzalloc_flex_struct(type, field, nr) \
@@ -98,6 +101,15 @@ static inline void *_xzalloc_array(
return _xzalloc(size * num, align);
}
+static inline void *_xrealloc_array(
+ void *ptr, unsigned long size, unsigned long align, unsigned long num)
+{
+ /* Check for overflow. */
+ if ( size && num > UINT_MAX / size )
+ return NULL;
+ return _xrealloc(ptr, size * num, align);
+}
+
/*
* Pooled allocator interface.
*/
--
2.43.0
Hi Carlo,
Thank you for the patch.
On 17/12/2024 19:06, Carlo Nonato wrote:
> Add the "llc-colors" Device Tree property to express DomUs and Dom0less
> color configurations.
>
> Based on original work from: Luca Miccio <lucmiccio@gmail.com>
>
> Signed-off-by: Carlo Nonato <carlo.nonato@minervasys.tech>
> Signed-off-by: Marco Solieri <marco.solieri@minervasys.tech>
> Reviewed-by: Jan Beulich <jbeulich@suse.com> # non-Arm
> Reviewed-by: Michal Orzel <michal.orzel@amd.com>
> ---
> v13:
> - no changes
> v12:
> - no changes
> v11:
> - made clear that llc-colors device-tree property is Arm64-only in booting.txt
> v10:
> - no changes
> v9:
> - use best-effort allocation in domain_set_llc_colors_from_str()
> v8:
> - fixed memory leak on error path of domain_set_llc_colors_from_str()
> - realloc colors array after parsing from string to reduce memory usage
> v7:
> - removed alloc_colors() helper usage from domain_set_llc_colors_from_str()
> v6:
> - rewrote domain_set_llc_colors_from_str() to be more explicit
> v5:
> - static-mem check has been moved in a previous patch
> - added domain_set_llc_colors_from_str() to set colors after domain creation
> ---
> docs/misc/arm/device-tree/booting.txt | 5 +++
> docs/misc/cache-coloring.rst | 48 +++++++++++++++++++++++++++
> xen/arch/arm/dom0less-build.c | 10 ++++++
> xen/common/llc-coloring.c | 40 ++++++++++++++++++++++
> xen/include/xen/llc-coloring.h | 1 +
> xen/include/xen/xmalloc.h | 12 +++++++
> 6 files changed, 116 insertions(+)
>
> diff --git a/docs/misc/arm/device-tree/booting.txt b/docs/misc/arm/device-tree/booting.txt
> index 3a04f5c57f..9c881baccc 100644
> --- a/docs/misc/arm/device-tree/booting.txt
> +++ b/docs/misc/arm/device-tree/booting.txt
> @@ -162,6 +162,11 @@ with the following properties:
>
> An integer specifying the number of vcpus to allocate to the guest.
>
> +- llc-colors
> + A string specifying the LLC color configuration for the guest.
> + Refer to docs/misc/cache_coloring.rst for syntax. This option is applicable
> + only to Arm64 guests.
> +
> - vpl011
>
> An empty property to enable/disable a virtual pl011 for the guest to
> diff --git a/docs/misc/cache-coloring.rst b/docs/misc/cache-coloring.rst
> index 7b47d0ed92..e097e74032 100644
> --- a/docs/misc/cache-coloring.rst
> +++ b/docs/misc/cache-coloring.rst
> @@ -14,6 +14,7 @@ If needed, change the maximum number of colors with
> ``CONFIG_LLC_COLORS_ORDER=<n>``.
>
> Runtime configuration is done via `Command line parameters`_.
> +For DomUs follow `DomUs configuration`_.
>
> Background
> **********
> @@ -149,6 +150,53 @@ LLC specs can be manually set via the above command line parameters. This
> bypasses any auto-probing and it's used to overcome failing situations, such as
> flawed probing logic, or for debugging/testing purposes.
>
> +DomUs configuration
> +*******************
> +
> +DomUs colors can be set either in the ``xl`` configuration file (documentation
> +at `docs/man/xl.cfg.pod.5.in`) or via Device Tree (documentation at
> +`docs/misc/arm/device-tree/booting.txt`) using the ``llc-colors`` option.
> +For example:
> +
> +::
> +
> + xen,xen-bootargs = "console=dtuart dtuart=serial0 dom0_mem=1G dom0_max_vcpus=1 sched=null llc-coloring=on dom0-llc-colors=2-6";
> + xen,dom0-bootargs "console=hvc0 earlycon=xen earlyprintk=xen root=/dev/ram0"
> +
> + dom0 {
> + compatible = "xen,linux-zimage" "xen,multiboot-module";
> + reg = <0x0 0x1000000 0x0 15858176>;
> + };
> +
> + dom0-ramdisk {
> + compatible = "xen,linux-initrd" "xen,multiboot-module";
> + reg = <0x0 0x2000000 0x0 20638062>;
> + };
> +
> + domU0 {
> + #address-cells = <0x1>;
> + #size-cells = <0x1>;
> + compatible = "xen,domain";
> + memory = <0x0 0x40000>;
> + llc-colors = "4-8,10,11,12";
> + cpus = <0x1>;
> + vpl011 = <0x1>;
> +
> + module@2000000 {
> + compatible = "multiboot,kernel", "multiboot,module";
> + reg = <0x2000000 0xffffff>;
> + bootargs = "console=ttyAMA0";
> + };
> +
> + module@30000000 {
> + compatible = "multiboot,ramdisk", "multiboot,module";
> + reg = <0x3000000 0xffffff>;
> + };
> + };
> +
> +**Note:** If no color configuration is provided for a domain, the default one,
> +which corresponds to all available colors is used instead.
> +
> Known issues and limitations
> ****************************
>
> diff --git a/xen/arch/arm/dom0less-build.c b/xen/arch/arm/dom0less-build.c
> index 67b1503647..49d1f14d65 100644
> --- a/xen/arch/arm/dom0less-build.c
> +++ b/xen/arch/arm/dom0less-build.c
> @@ -817,6 +817,7 @@ void __init create_domUs(void)
> bool iommu = false;
> const struct dt_device_node *cpupool_node,
> *chosen = dt_find_node_by_path("/chosen");
> + const char *llc_colors_str = NULL;
>
> BUG_ON(chosen == NULL);
> dt_for_each_child_node(chosen, node)
> @@ -965,6 +966,10 @@ void __init create_domUs(void)
> #endif
> }
>
> + dt_property_read_string(node, "llc-colors", &llc_colors_str);
> + if ( !llc_coloring_enabled && llc_colors_str )
> + panic("'llc-colors' found, but LLC coloring is disabled\n");
> +
> /*
> * The variable max_init_domid is initialized with zero, so here it's
> * very important to use the pre-increment operator to call
> @@ -975,6 +980,11 @@ void __init create_domUs(void)
> panic("Error creating domain %s (rc = %ld)\n",
> dt_node_name(node), PTR_ERR(d));
>
> + if ( llc_coloring_enabled &&
> + (rc = domain_set_llc_colors_from_str(d, llc_colors_str)) )
> + panic("Error initializing LLC coloring for domain %s (rc = %d)\n",
> + dt_node_name(node), rc);
> +
> d->is_console = true;
> dt_device_set_used_by(node, d->domain_id);
>
> diff --git a/xen/common/llc-coloring.c b/xen/common/llc-coloring.c
> index 3dd1aaa4df..5a0e3bac59 100644
> --- a/xen/common/llc-coloring.c
> +++ b/xen/common/llc-coloring.c
> @@ -282,6 +282,46 @@ void domain_llc_coloring_free(struct domain *d)
> xfree(__va(__pa(d->llc_colors)));
> }
>
> +int __init domain_set_llc_colors_from_str(struct domain *d, const char *str)
> +{
> + int err;
> + unsigned int *colors, num_colors;
> +
> + if ( !str )
> + {
> + domain_set_default_colors(d);
> + return 0;
> + }
> +
> + colors = xmalloc_array(unsigned int, max_nr_colors);
> + if ( !colors )
> + return -ENOMEM;
> +
> + err = parse_color_config(str, colors, max_nr_colors, &num_colors);
> + if ( err )
> + {
> + printk(XENLOG_ERR "Error parsing LLC color configuration");
Missing \n at the end of this printk.
> + xfree(colors);
> + return err;
> + }
> +
> + if ( !check_colors(colors, num_colors) )
> + {
> + printk(XENLOG_ERR "%pd: bad LLC color config\n", d);
> + xfree(colors);
> + return -EINVAL;
> + }
> +
> + /* Adjust the size cause it was initially set to max_nr_colors */
> + d->llc_colors = xrealloc_array(colors, num_colors);
> + if ( !d->llc_colors )
> + d->llc_colors = colors;
> +
> + d->num_llc_colors = num_colors;
> +
> + return 0;
> +}
> +
> /*
> * Local variables:
> * mode: C
> diff --git a/xen/include/xen/llc-coloring.h b/xen/include/xen/llc-coloring.h
> index 26353c808a..5d1355b3c9 100644
> --- a/xen/include/xen/llc-coloring.h
> +++ b/xen/include/xen/llc-coloring.h
> @@ -34,6 +34,7 @@ void arch_llc_coloring_init(void);
> int dom0_set_llc_colors(struct domain *d);
> int domain_set_llc_colors(struct domain *d,
> const struct xen_domctl_set_llc_colors *config);
> +int domain_set_llc_colors_from_str(struct domain *d, const char *str);
>
> #endif /* __XEN_LLC_COLORING_H__ */
>
> diff --git a/xen/include/xen/xmalloc.h b/xen/include/xen/xmalloc.h
> index b903fa2e26..f0412fb4e0 100644
> --- a/xen/include/xen/xmalloc.h
> +++ b/xen/include/xen/xmalloc.h
> @@ -37,6 +37,9 @@
> ((_type *)_xmalloc_array(sizeof(_type), __alignof__(_type), _num))
> #define xzalloc_array(_type, _num) \
> ((_type *)_xzalloc_array(sizeof(_type), __alignof__(_type), _num))
> +#define xrealloc_array(_ptr, _num) \
> + ((typeof(_ptr))_xrealloc_array(_ptr, sizeof(typeof(*(_ptr))), \
> + __alignof__(typeof(*(_ptr))), _num))
>
> /* Allocate space for a structure with a flexible array of typed objects. */
> #define xzalloc_flex_struct(type, field, nr) \
> @@ -98,6 +101,15 @@ static inline void *_xzalloc_array(
> return _xzalloc(size * num, align);
> }
>
> +static inline void *_xrealloc_array(
> + void *ptr, unsigned long size, unsigned long align, unsigned long num)
> +{
> + /* Check for overflow. */
> + if ( size && num > UINT_MAX / size )
> + return NULL;
> + return _xrealloc(ptr, size * num, align);
> +}
> +
> /*
> * Pooled allocator interface.
> */
Best regards,
Mykola
© 2016 - 2026 Red Hat, Inc.