lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Fri, 17 Feb 2017 11:58:54 -0800 From: Vikas Shivappa <vikas.shivappa@...ux.intel.com> To: vikas.shivappa@...el.com Cc: linux-kernel@...r.kernel.org, x86@...nel.org, hpa@...or.com, tglx@...utronix.de, mingo@...nel.org, peterz@...radead.org, ravi.v.shankar@...el.com, tony.luck@...el.com, fenghua.yu@...el.com, andi.kleen@...el.com, vikas.shivappa@...ux.intel.com Subject: [PATCH 7/8] x86/intel_rdt: schemata file support for MBA prepare Add support to introduce generic APIs for control validation and writing QOS_MSRs for RDT resources. The control validation api is meant to validate the control values like cache bit mask for CAT and memory b/w percentage for MBA. A resource generic display format is also added and used for the resources depending on whether its displayed in hex/decimal. Signed-off-by: Vikas Shivappa <vikas.shivappa@...ux.intel.com> --- arch/x86/include/asm/intel_rdt.h | 8 +++++++ arch/x86/kernel/cpu/intel_rdt.c | 33 +++++++++++++++++++++----- arch/x86/kernel/cpu/intel_rdt_schemata.c | 40 ++++++++++++++++++-------------- 3 files changed, 58 insertions(+), 23 deletions(-) diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h index 24de64c..8748b0d 100644 --- a/arch/x86/include/asm/intel_rdt.h +++ b/arch/x86/include/asm/intel_rdt.h @@ -77,6 +77,9 @@ struct rftype { * @default_ctrl: Specifies default cache cbm or mem b/w percent. * @min_cbm_bits: Minimum number of consecutive bits to be set * in a cache bit mask + * @format_str: Per resource format string to show domain val + * @parse_ctrlval: Per resource API to parse the ctrl values + * @msr_update: API to update QOS MSRs * @info_files: resctrl info files for the resource * @infofiles_len: Number of info files * @max_delay: Max throttle delay. Delay is the hardware @@ -105,6 +108,9 @@ struct rdt_resource { int cbm_len; int min_cbm_bits; u32 default_ctrl; + const char *format_str; + int (*parse_ctrlval) (char *buf, struct rdt_resource *r); + void (*msr_update) (void *a1, void *a2, struct rdt_resource *r); struct rftype *info_files; int infofiles_len; u32 max_delay; @@ -150,6 +156,8 @@ struct msr_param { void rdt_get_cache_infofile(struct rdt_resource *r); void rdt_get_mba_infofile(struct rdt_resource *r); +int parse_cbm(char *buf, struct rdt_resource *r); +void cqm_wrmsr(void *a1, void *a2, struct rdt_resource *r); extern struct mutex rdtgroup_mutex; diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c index 353c476b4..7ce4453 100644 --- a/arch/x86/kernel/cpu/intel_rdt.c +++ b/arch/x86/kernel/cpu/intel_rdt.c @@ -44,6 +44,9 @@ struct rdt_resource rdt_resources_all[] = { .name = "L3", .domains = domain_init(RDT_RESOURCE_L3), .msr_base = IA32_L3_CBM_BASE, + .parse_ctrlval = parse_cbm, + .msr_update = cqm_wrmsr, + .format_str = "%d=%x", .min_cbm_bits = 1, .cache_level = 3, .cbm_idx_multi = 1, @@ -53,6 +56,9 @@ struct rdt_resource rdt_resources_all[] = { .name = "L3DATA", .domains = domain_init(RDT_RESOURCE_L3DATA), .msr_base = IA32_L3_CBM_BASE, + .parse_ctrlval = parse_cbm, + .msr_update = cqm_wrmsr, + .format_str = "%d=%x", .min_cbm_bits = 1, .cache_level = 3, .cbm_idx_multi = 2, @@ -62,6 +68,9 @@ struct rdt_resource rdt_resources_all[] = { .name = "L3CODE", .domains = domain_init(RDT_RESOURCE_L3CODE), .msr_base = IA32_L3_CBM_BASE, + .parse_ctrlval = parse_cbm, + .msr_update = cqm_wrmsr, + .format_str = "%d=%x", .min_cbm_bits = 1, .cache_level = 3, .cbm_idx_multi = 2, @@ -71,6 +80,9 @@ struct rdt_resource rdt_resources_all[] = { .name = "L2", .domains = domain_init(RDT_RESOURCE_L2), .msr_base = IA32_L2_CBM_BASE, + .parse_ctrlval = parse_cbm, + .msr_update = cqm_wrmsr, + .format_str = "%d=%x", .min_cbm_bits = 1, .cache_level = 2, .cbm_idx_multi = 1, @@ -258,11 +270,24 @@ static int get_cache_id(int cpu, int level) return -1; } +void cqm_wrmsr(void *a1, void *a2, struct rdt_resource *r) +{ + struct rdt_domain *d = (struct rdt_domain *)a2; + struct msr_param *m = (struct msr_param *)a1; + int i; + + for (i = m->low; i < m->high; i++) { + int idx = cbm_idx(r, i); + + wrmsrl(r->msr_base + idx, d->ctrl_val[i]); + } +} + void rdt_ctrl_update(void *arg) { struct msr_param *m = (struct msr_param *)arg; struct rdt_resource *r = m->res; - int i, cpu = smp_processor_id(); + int cpu = smp_processor_id(); struct rdt_domain *d; list_for_each_entry(d, &r->domains, list) { @@ -276,11 +301,7 @@ void rdt_ctrl_update(void *arg) return; found: - for (i = m->low; i < m->high; i++) { - int idx = cbm_idx(r, i); - - wrmsrl(r->msr_base + idx, d->ctrl_val[i]); - } + r->msr_update(m, d, r); } /* diff --git a/arch/x86/kernel/cpu/intel_rdt_schemata.c b/arch/x86/kernel/cpu/intel_rdt_schemata.c index 3cde1e8..4141662 100644 --- a/arch/x86/kernel/cpu/intel_rdt_schemata.c +++ b/arch/x86/kernel/cpu/intel_rdt_schemata.c @@ -34,41 +34,46 @@ * are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.). * Additionally Haswell requires at least two bits set. */ -static bool cbm_validate(unsigned long var, struct rdt_resource *r) +static int cbm_validate(char *buf, unsigned long *data, struct rdt_resource *r) { - unsigned long first_bit, zero_bit; + unsigned long first_bit, zero_bit, var; + int ret; + + ret = kstrtoul(buf, 16, &var); + if (ret) + return ret; if (var == 0 || var > r->default_ctrl) - return false; + return -EINVAL; first_bit = find_first_bit(&var, r->cbm_len); zero_bit = find_next_zero_bit(&var, r->cbm_len, first_bit); if (find_next_bit(&var, r->cbm_len, zero_bit) < r->cbm_len) - return false; + return -EINVAL; if ((zero_bit - first_bit) < r->min_cbm_bits) - return false; - return true; + return -EINVAL; + + *data = var; + + return 0; } /* - * Read one cache bit mask (hex). Check that it is valid for the current - * resource type. + * Read the user RDT control value into tempory buffer: + * Cache bit mask (hex) or Memory b/w throttle (decimal). + * Check that it is valid for the current resource type. */ -static int parse_cbm(char *buf, struct rdt_resource *r) +int parse_cbm(char *buf, struct rdt_resource *r) { unsigned long data; int ret; - ret = kstrtoul(buf, 16, &data); - if (ret) - return ret; - if (!cbm_validate(data, r)) - return -EINVAL; + ret = cbm_validate(buf, &data, r); r->tmp_ctrl[r->num_tmp_ctrl++] = data; - return 0; + return ret; } /* @@ -90,7 +95,7 @@ static int parse_line(char *line, struct rdt_resource *r) id = strsep(&dom, "="); if (kstrtoul(id, 10, &dom_id) || dom_id != d->id) return -EINVAL; - if (parse_cbm(dom, r)) + if (r->parse_ctrlval(dom, r)) return -EINVAL; } @@ -240,7 +245,8 @@ static void show_doms(struct seq_file *s, struct rdt_resource *r, int closid) list_for_each_entry(dom, &r->domains, list) { if (sep) seq_puts(s, ";"); - seq_printf(s, "%d=%x", dom->id, dom->ctrl_val[closid]); + + seq_printf(s, r->format_str, dom->id, dom->ctrl_val[closid]); sep = true; } seq_puts(s, "\n"); -- 1.9.1
Powered by blists - more mailing lists