diff options
-rw-r--r-- | arch/x86/include/asm/intel_rdt.h | 6 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel_rdt.c | 8 | ||||
-rw-r--r-- | arch/x86/kernel/cpu/intel_rdt_schemata.c | 31 |
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 | */ |
156 | struct rdt_resource { | 158 | struct 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 | ||
176 | void rdt_get_cache_infofile(struct rdt_resource *r); | 181 | void rdt_get_cache_infofile(struct rdt_resource *r); |
177 | void rdt_get_mba_infofile(struct rdt_resource *r); | 182 | void rdt_get_mba_infofile(struct rdt_resource *r); |
183 | int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d); | ||
178 | 184 | ||
179 | extern struct mutex rdtgroup_mutex; | 185 | extern 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 | */ |
37 | static bool cbm_validate(unsigned long var, struct rdt_resource *r) | 37 | static 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 | */ |
60 | static int parse_cbm(char *buf, struct rdt_resource *r, struct rdt_domain *d) | 67 | int 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 | } |