+----------------------+-------------------------------+
| ``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
#########################
.max_maptrack_frames = -1,
.grant_opts = XEN_DOMCTL_GRANT_version(opt_gnttab_max_version),
};
+ unsigned int flags = CDF_privileged;
int rc;
/* The vGIC for DOM0 is exactly emulating the hardware GIC */
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) )
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 )
panic("Error creating domain 0 vcpu0\n");
integer_param("llc-nr-ways", llc_nr_ways);
/* Number of colors available in the LLC */
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)
{
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)
{
- unsigned int way_size;
+ unsigned int way_size, i;
llc_coloring_enabled = (opt_llc_coloring >= 1);
if ( (opt_llc_coloring != 0) && llc_size && llc_nr_ways )
else if ( max_nr_colors < 2 )
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();
}
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:
* mode: C