From: James Morse james.morse@arm.com
resctrl_arch_mon_event_config_write() writes a bitmap of events provided by user-space into the configuration register for the monitors.
This assumes that all architectures support all the features each bit corresponds to.
MPAM can filter monitors based on read, write, or both, but there are many more options in the existing bitmap. To allow this interface to work for machines with MPAM, allow the architecture helper to return an error if an incompatible bitmap is set.
Signed-off-by: James Morse james.morse@arm.com --- arch/x86/kernel/cpu/resctrl/rdtgroup.c | 10 ++++++++-- include/linux/resctrl.h | 2 ++ 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kernel/cpu/resctrl/rdtgroup.c b/arch/x86/kernel/cpu/resctrl/rdtgroup.c index a7dbd66927ba..47d0b9a73c5c 100644 --- a/arch/x86/kernel/cpu/resctrl/rdtgroup.c +++ b/arch/x86/kernel/cpu/resctrl/rdtgroup.c @@ -1684,16 +1684,18 @@ void resctrl_arch_mon_event_config_write(void *info) index = mon_event_config_index_get(mon_info->evtid); if (index == INVALID_CONFIG_INDEX) { pr_warn_once("Invalid event id %d\n", mon_info->evtid); + mon_info->err = -EINVAL; return; } wrmsr(MSR_IA32_EVT_CFG_BASE + index, mon_info->mon_config, 0); + + mon_info->err = 0; }
static int mbm_config_write_domain(struct rdt_resource *r, struct rdt_domain *d, u32 evtid, u32 val) { struct resctrl_mon_config_info mon_info = {0}; - int ret = 0;
/* mon_config cannot be more than the supported set of events */ if (val > MAX_EVT_CONFIG_BITS) { @@ -1722,6 +1724,10 @@ static int mbm_config_write_domain(struct rdt_resource *r, */ smp_call_function_any(&d->cpu_mask, resctrl_arch_mon_event_config_write, &mon_info, 1); + if (mon_info.err) { + rdt_last_cmd_puts("Invalid event configuration\n"); + goto out; + }
/* * When an Event Configuration is changed, the bandwidth counters @@ -1735,7 +1741,7 @@ static int mbm_config_write_domain(struct rdt_resource *r, resctrl_arch_reset_rmid_all(r, d);
out: - return ret; + return mon_info.err; }
static int mon_config_write(struct rdt_resource *r, char *tok, u32 evtid) diff --git a/include/linux/resctrl.h b/include/linux/resctrl.h index 975b80102fbe..1027421f233e 100644 --- a/include/linux/resctrl.h +++ b/include/linux/resctrl.h @@ -197,6 +197,8 @@ struct resctrl_mon_config_info { struct rdt_domain *d; u32 evtid; u32 mon_config; + + int err; };
/*