mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
xen/arm: add Dom0 cache coloring support
Add a command line parameter to allow the user to set the coloring configuration for Dom0. A common configuration syntax for cache colors is introduced and documented. Take the opportunity to also add: - default configuration notion. - function to check well-formed configurations. Direct mapping Dom0 isn't possible when coloring is enabled, so CDF_directmap flag is removed when creating it. 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> Reviewed-by: Michal Orzel <michal.orzel@amd.com>
This commit is contained in:
1 parent
02975cc383
commit
6cdea3444e
5 files changed
+166
-2
No files matched your search
@@ -107,6 +107,35 @@ Specific documentation is available at `docs/misc/xen-command-line.pandoc`.
|
|||||||
+----------------------+-------------------------------+
|
+----------------------+-------------------------------+
|
||||||
| ``llc-nr-ways`` | Set the LLC number of ways |
|
| ``llc-nr-ways`` | Set the LLC number of ways |
|
||||||
+----------------------+-------------------------------+
|
+----------------------+-------------------------------+
|
||||||
|
| ``dom0-llc-colors`` | Dom0 color configuration |
|
||||||
|
+----------------------+-------------------------------+
|
||||||
|
|
||||||
|
Colors selection format
|
||||||
|
***********************
|
||||||
|
|
||||||
|
Regardless of the memory pool that has to be colored (Xen, Dom0/DomUs),
|
||||||
|
the color selection can be expressed using the same syntax. In particular a
|
||||||
|
comma-separated list of colors or ranges of colors is used.
|
||||||
|
Ranges are hyphen-separated intervals (such as `0-4`) and are inclusive on both
|
||||||
|
sides.
|
||||||
|
|
||||||
|
Note that:
|
||||||
|
|
||||||
|
- no spaces are allowed between values.
|
||||||
|
- no overlapping ranges or duplicated colors are allowed.
|
||||||
|
- values must be written in ascending order.
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
|
||||||
|
+-------------------+-----------------------------+
|
||||||
|
| **Configuration** | **Actual selection** |
|
||||||
|
+-------------------+-----------------------------+
|
||||||
|
| 1-2,5-8 | [1, 2, 5, 6, 7, 8] |
|
||||||
|
+-------------------+-----------------------------+
|
||||||
|
| 4-8,10,11,12 | [4, 5, 6, 7, 8, 10, 11, 12] |
|
||||||
|
+-------------------+-----------------------------+
|
||||||
|
| 0 | [0] |
|
||||||
|
+-------------------+-----------------------------+
|
||||||
|
|
||||||
Auto-probing of LLC specs
|
Auto-probing of LLC specs
|
||||||
#########################
|
#########################
|
||||||
|
|||||||
@@ -965,6 +965,15 @@ Controls for the dom0 IOMMU setup.
|
|||||||
|
|
||||||
Specify a list of IO ports to be excluded from dom0 access.
|
Specify a list of IO ports to be excluded from dom0 access.
|
||||||
|
|
||||||
|
### dom0-llc-colors (arm64)
|
||||||
|
> `= List of [ <integer> | <integer>-<integer> ]`
|
||||||
|
|
||||||
|
> Default: `All available LLC colors`
|
||||||
|
|
||||||
|
Specify dom0 LLC color configuration. This option is available only when
|
||||||
|
`CONFIG_LLC_COLORING` is enabled. If the parameter is not set, all available
|
||||||
|
colors are used.
|
||||||
|
|
||||||
### dom0_max_vcpus
|
### dom0_max_vcpus
|
||||||
|
|
||||||
Either:
|
Either:
|
||||||
|
|||||||
@@ -2356,6 +2356,7 @@ void __init create_dom0(void)
|
|||||||
.max_maptrack_frames = -1,
|
.max_maptrack_frames = -1,
|
||||||
.grant_opts = XEN_DOMCTL_GRANT_version(opt_gnttab_max_version),
|
.grant_opts = XEN_DOMCTL_GRANT_version(opt_gnttab_max_version),
|
||||||
};
|
};
|
||||||
|
unsigned int flags = CDF_privileged;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
/* The vGIC for DOM0 is exactly emulating the hardware GIC */
|
/* The vGIC for DOM0 is exactly emulating the hardware GIC */
|
||||||
@@ -2383,10 +2384,16 @@ void __init create_dom0(void)
|
|||||||
panic("SVE vector length error\n");
|
panic("SVE vector length error\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
dom0 = domain_create(0, &dom0_cfg, CDF_privileged | CDF_directmap);
|
if ( !llc_coloring_enabled )
|
||||||
|
flags |= CDF_directmap;
|
||||||
|
|
||||||
|
dom0 = domain_create(0, &dom0_cfg, flags);
|
||||||
if ( IS_ERR(dom0) )
|
if ( IS_ERR(dom0) )
|
||||||
panic("Error creating domain 0 (rc = %ld)\n", PTR_ERR(dom0));
|
panic("Error creating domain 0 (rc = %ld)\n", PTR_ERR(dom0));
|
||||||
|
|
||||||
|
if ( llc_coloring_enabled && (rc = dom0_set_llc_colors(dom0)) )
|
||||||
|
panic("Error initializing LLC coloring for domain 0 (rc = %d)\n", rc);
|
||||||
|
|
||||||
if ( alloc_dom0_vcpu0(dom0) == NULL )
|
if ( alloc_dom0_vcpu0(dom0) == NULL )
|
||||||
panic("Error creating domain 0 vcpu0\n");
|
panic("Error creating domain 0 vcpu0\n");
|
||||||
|
|
||||||
|
|||||||
+119
-1
@@ -29,6 +29,66 @@ static unsigned int __initdata llc_nr_ways;
|
|||||||
integer_param("llc-nr-ways", llc_nr_ways);
|
integer_param("llc-nr-ways", llc_nr_ways);
|
||||||
/* Number of colors available in the LLC */
|
/* Number of colors available in the LLC */
|
||||||
static unsigned int __ro_after_init max_nr_colors;
|
static unsigned int __ro_after_init max_nr_colors;
|
||||||
|
/* Default coloring configuration */
|
||||||
|
static unsigned int __ro_after_init default_colors[NR_LLC_COLORS];
|
||||||
|
|
||||||
|
static unsigned int __initdata dom0_colors[NR_LLC_COLORS];
|
||||||
|
static unsigned int __initdata dom0_num_colors;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Parse the coloring configuration given in the buf string, following the
|
||||||
|
* syntax below.
|
||||||
|
*
|
||||||
|
* COLOR_CONFIGURATION ::= COLOR | RANGE,...,COLOR | RANGE
|
||||||
|
* RANGE ::= COLOR-COLOR
|
||||||
|
*
|
||||||
|
* Example: "0,2-6,15-16" represents the set of colors: 0,2,3,4,5,6,15,16.
|
||||||
|
*/
|
||||||
|
static int __init parse_color_config(const char *buf, unsigned int colors[],
|
||||||
|
unsigned int max_num_colors,
|
||||||
|
unsigned int *num_colors)
|
||||||
|
{
|
||||||
|
const char *s = buf;
|
||||||
|
|
||||||
|
*num_colors = 0;
|
||||||
|
|
||||||
|
while ( *s != '\0' )
|
||||||
|
{
|
||||||
|
unsigned int color, start, end;
|
||||||
|
|
||||||
|
start = simple_strtoul(s, &s, 0);
|
||||||
|
|
||||||
|
if ( *s == '-' ) /* Range */
|
||||||
|
{
|
||||||
|
s++;
|
||||||
|
end = simple_strtoul(s, &s, 0);
|
||||||
|
}
|
||||||
|
else /* Single value */
|
||||||
|
end = start;
|
||||||
|
|
||||||
|
if ( start > end || (end - start) > (UINT_MAX - *num_colors) ||
|
||||||
|
(*num_colors + (end - start)) >= max_num_colors )
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
/* Colors are range checked in check_colors() */
|
||||||
|
for ( color = start; color <= end; color++ )
|
||||||
|
colors[(*num_colors)++] = color;
|
||||||
|
|
||||||
|
if ( *s == ',' )
|
||||||
|
s++;
|
||||||
|
else if ( *s != '\0' )
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return *s ? -EINVAL : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int __init parse_dom0_colors(const char *s)
|
||||||
|
{
|
||||||
|
return parse_color_config(s, dom0_colors, ARRAY_SIZE(dom0_colors),
|
||||||
|
&dom0_num_colors);
|
||||||
|
}
|
||||||
|
custom_param("dom0-llc-colors", parse_dom0_colors);
|
||||||
|
|
||||||
static void print_colors(const unsigned int colors[], unsigned int num_colors)
|
static void print_colors(const unsigned int colors[], unsigned int num_colors)
|
||||||
{
|
{
|
||||||
@@ -53,9 +113,27 @@ static void print_colors(const unsigned int colors[], unsigned int num_colors)
|
|||||||
printk(" }\n");
|
printk(" }\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool __init check_colors(const unsigned int colors[],
|
||||||
|
unsigned int num_colors)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for ( i = 0; i < num_colors; i++ )
|
||||||
|
{
|
||||||
|
if ( colors[i] >= max_nr_colors )
|
||||||
|
{
|
||||||
|
printk(XENLOG_ERR "LLC color %u >= %u (max allowed)\n", colors[i],
|
||||||
|
max_nr_colors);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void __init llc_coloring_init(void)
|
void __init llc_coloring_init(void)
|
||||||
{
|
{
|
||||||
unsigned int way_size;
|
unsigned int way_size, i;
|
||||||
|
|
||||||
llc_coloring_enabled = (opt_llc_coloring >= 1);
|
llc_coloring_enabled = (opt_llc_coloring >= 1);
|
||||||
if ( (opt_llc_coloring != 0) && llc_size && llc_nr_ways )
|
if ( (opt_llc_coloring != 0) && llc_size && llc_nr_ways )
|
||||||
@@ -94,6 +172,9 @@ void __init llc_coloring_init(void)
|
|||||||
else if ( max_nr_colors < 2 )
|
else if ( max_nr_colors < 2 )
|
||||||
panic("Number of LLC colors %u < 2\n", max_nr_colors);
|
panic("Number of LLC colors %u < 2\n", max_nr_colors);
|
||||||
|
|
||||||
|
for ( i = 0; i < max_nr_colors; i++ )
|
||||||
|
default_colors[i] = i;
|
||||||
|
|
||||||
arch_llc_coloring_init();
|
arch_llc_coloring_init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,6 +196,43 @@ void domain_dump_llc_colors(const struct domain *d)
|
|||||||
print_colors(d->llc_colors, d->num_llc_colors);
|
print_colors(d->llc_colors, d->num_llc_colors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void __init domain_set_default_colors(struct domain *d)
|
||||||
|
{
|
||||||
|
printk(XENLOG_WARNING
|
||||||
|
"LLC color config not found for %pd, using all colors\n", d);
|
||||||
|
|
||||||
|
d->llc_colors = default_colors;
|
||||||
|
d->num_llc_colors = max_nr_colors;
|
||||||
|
}
|
||||||
|
|
||||||
|
int __init dom0_set_llc_colors(struct domain *d)
|
||||||
|
{
|
||||||
|
typeof(*dom0_colors) *colors;
|
||||||
|
|
||||||
|
if ( !dom0_num_colors )
|
||||||
|
{
|
||||||
|
domain_set_default_colors(d);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( (dom0_num_colors > max_nr_colors) ||
|
||||||
|
!check_colors(dom0_colors, dom0_num_colors) )
|
||||||
|
{
|
||||||
|
printk(XENLOG_ERR "%pd: bad LLC color config\n", d);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
colors = xmalloc_array(typeof(*dom0_colors), dom0_num_colors);
|
||||||
|
if ( !colors )
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
memcpy(colors, dom0_colors, sizeof(*colors) * dom0_num_colors);
|
||||||
|
d->llc_colors = colors;
|
||||||
|
d->num_llc_colors = dom0_num_colors;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Local variables:
|
* Local variables:
|
||||||
* mode: C
|
* mode: C
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ static inline void domain_dump_llc_colors(const struct domain *d) {}
|
|||||||
|
|
||||||
unsigned int get_llc_way_size(void);
|
unsigned int get_llc_way_size(void);
|
||||||
void arch_llc_coloring_init(void);
|
void arch_llc_coloring_init(void);
|
||||||
|
int dom0_set_llc_colors(struct domain *d);
|
||||||
|
|
||||||
#endif /* __XEN_LLC_COLORING_H__ */
|
#endif /* __XEN_LLC_COLORING_H__ */
|
||||||
|
|
||||||
|
|||||||