aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/x86/include/asm/intel_rdt.h6
-rw-r--r--arch/x86/kernel/cpu/intel_rdt.c8
-rw-r--r--arch/x86/kernel/cpu/intel_rdt_schemata.c31
3 files changed, 31 insertions, 14 deletions
diff --git a/arch/x86/include/asm/intel_rdt.h b/arch/x86/include/asm/intel_rdt.h
index 167fe10f00b9..4a9005766d96 100644
--- a/arch/x86/include/asm/intel_rdt.h
+++ b/arch/x86/include/asm/intel_rdt.h
@@ -152,6 +152,8 @@ struct rdt_membw {
152 * @cache: Cache allocation related data 152 * @cache: Cache allocation related data
153 * @info_files: resctrl info files for the resource 153 * @info_files: resctrl info files for the resource
154 * @nr_info_files: Number of info files 154 * @nr_info_files: Number of info files
155 * @format_str: Per resource format string to show domain value
156 * @parse_ctrlval: Per resource function pointer to parse control values
155 */ 157 */
156struct rdt_resource { 158struct rdt_resource {
157 bool enabled; 159 bool enabled;
@@ -171,10 +173,14 @@ struct rdt_resource {
171 }; 173 };
172 struct rftype *info_files; 174 struct rftype *info_files;
173 int nr_info_files; 175 int nr_info_files;
176 const char *format_str;
177 int (*parse_ctrlval) (char *buf, struct rdt_resource *r,
178 struct rdt_domain *d);
174}; 179};
175 180
176void rdt_get_cache_infofile(struct rdt_resource *r); 181void rdt_get_cache_infofile(struct rdt_resource *r);
177void rdt_get_mba_infofile(struct rdt_resource *r); 182void rdt_get_mba_infofile(struct rdt_resource *r);
183int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d);
178 184
179extern struct mutex rdtgroup_mutex; 185extern struct mutex rdtgroup_mutex;
180 186
diff --git a/arch/x86/kernel/cpu/intel_rdt.c b/arch/x86/kernel/cpu/intel_rdt.c
index 438efefd6862..1e410ea6905e 100644
--- a/arch/x86/kernel/cpu/intel_rdt.c
+++ b/arch/x86/kernel/cpu/intel_rdt.c
@@ -65,6 +65,8 @@ struct rdt_resource rdt_resources_all[] = {
65 .cbm_idx_mult = 1, 65 .cbm_idx_mult = 1,
66 .cbm_idx_offset = 0, 66 .cbm_idx_offset = 0,
67 }, 67 },
68 .parse_ctrlval = parse_cbm,
69 .format_str = "%d=%0*x",
68 }, 70 },
69 { 71 {
70 .name = "L3DATA", 72 .name = "L3DATA",
@@ -77,6 +79,8 @@ struct rdt_resource rdt_resources_all[] = {
77 .cbm_idx_mult = 2, 79 .cbm_idx_mult = 2,
78 .cbm_idx_offset = 0, 80 .cbm_idx_offset = 0,
79 }, 81 },
82 .parse_ctrlval = parse_cbm,
83 .format_str = "%d=%0*x",
80 }, 84 },
81 { 85 {
82 .name = "L3CODE", 86 .name = "L3CODE",
@@ -89,6 +93,8 @@ struct rdt_resource rdt_resources_all[] = {
89 .cbm_idx_mult = 2, 93 .cbm_idx_mult = 2,
90 .cbm_idx_offset = 1, 94 .cbm_idx_offset = 1,
91 }, 95 },
96 .parse_ctrlval = parse_cbm,
97 .format_str = "%d=%0*x",
92 }, 98 },
93 { 99 {
94 .name = "L2", 100 .name = "L2",
@@ -101,6 +107,8 @@ struct rdt_resource rdt_resources_all[] = {
101 .cbm_idx_mult = 1, 107 .cbm_idx_mult = 1,
102 .cbm_idx_offset = 0, 108 .cbm_idx_offset = 0,
103 }, 109 },
110 .parse_ctrlval = parse_cbm,
111 .format_str = "%d=%0*x",
104 }, 112 },
105 { 113 {
106 .name = "MB", 114 .name = "MB",
diff --git a/arch/x86/kernel/cpu/intel_rdt_schemata.c b/arch/x86/kernel/cpu/intel_rdt_schemata.c
index 5097ac65d002..c72c9cc17aac 100644
--- a/arch/x86/kernel/cpu/intel_rdt_schemata.c
+++ b/arch/x86/kernel/cpu/intel_rdt_schemata.c
@@ -34,22 +34,29 @@
34 * are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.). 34 * are allowed (e.g. FFFFH, 0FF0H, 003CH, etc.).
35 * Additionally Haswell requires at least two bits set. 35 * Additionally Haswell requires at least two bits set.
36 */ 36 */
37static bool cbm_validate(unsigned long var, struct rdt_resource *r) 37static bool cbm_validate(char *buf, unsigned long *data, struct rdt_resource *r)
38{ 38{
39 unsigned long first_bit, zero_bit; 39 unsigned long first_bit, zero_bit, val;
40 unsigned int cbm_len = r->cache.cbm_len; 40 unsigned int cbm_len = r->cache.cbm_len;
41 int ret;
42
43 ret = kstrtoul(buf, 16, &val);
44 if (ret)
45 return false;
41 46
42 if (var == 0 || var > r->default_ctrl) 47 if (val == 0 || val > r->default_ctrl)
43 return false; 48 return false;
44 49
45 first_bit = find_first_bit(&var, cbm_len); 50 first_bit = find_first_bit(&val, cbm_len);
46 zero_bit = find_next_zero_bit(&var, cbm_len, first_bit); 51 zero_bit = find_next_zero_bit(&val, cbm_len, first_bit);
47 52
48 if (find_next_bit(&var, cbm_len, zero_bit) < cbm_len) 53 if (find_next_bit(&val, cbm_len, zero_bit) < cbm_len)
49 return false; 54 return false;
50 55
51 if ((zero_bit - first_bit) < r->cache.min_cbm_bits) 56 if ((zero_bit - first_bit) < r->cache.min_cbm_bits)
52 return false; 57 return false;
58
59 *data = val;
53 return true; 60 return true;
54} 61}
55 62
@@ -57,18 +64,14 @@ static bool cbm_validate(unsigned long var, struct rdt_resource *r)
57 * Read one cache bit mask (hex). Check that it is valid for the current 64 * Read one cache bit mask (hex). Check that it is valid for the current
58 * resource type. 65 * resource type.
59 */ 66 */
60static int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d) 67int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d)
61{ 68{
62 unsigned long data; 69 unsigned long data;
63 int ret;
64 70
65 if (d->have_new_ctrl) 71 if (d->have_new_ctrl)
66 return -EINVAL; 72 return -EINVAL;
67 73
68 ret = kstrtoul(buf, 16, &data); 74 if(!cbm_validate(buf, &data, r))
69 if (ret)
70 return ret;
71 if (!cbm_validate(data, r))
72 return -EINVAL; 75 return -EINVAL;
73 d->new_ctrl = data; 76 d->new_ctrl = data;
74 d->have_new_ctrl = true; 77 d->have_new_ctrl = true;
@@ -97,7 +100,7 @@ next:
97 return -EINVAL; 100 return -EINVAL;
98 list_for_each_entry(d, &r->domains, list) { 101 list_for_each_entry(d, &r->domains, list) {
99 if (d->id == dom_id) { 102 if (d->id == dom_id) {
100 if (parse_cbm(dom, r, d)) 103 if (r->parse_ctrlval(dom, r, d))
101 return -EINVAL; 104 return -EINVAL;
102 goto next; 105 goto next;
103 } 106 }
@@ -208,7 +211,7 @@ static void show_doms(struct seq_file *s, struct rdt_resource *r, int closid)
208 list_for_each_entry(dom, &r->domains, list) { 211 list_for_each_entry(dom, &r->domains, list) {
209 if (sep) 212 if (sep)
210 seq_puts(s, ";"); 213 seq_puts(s, ";");
211 seq_printf(s, "%d=%0*x", dom->id, max_data_width, 214 seq_printf(s, r->format_str, dom->id, max_data_width,
212 dom->ctrl_val[closid]); 215 dom->ctrl_val[closid]);
213 sep = true; 216 sep = true;
214 } 217 }