|
11 | 11 |
|
12 | 12 | #define pr_fmt(fmt) "resctrl: " fmt |
13 | 13 |
|
| 14 | +#include <linux/bits.h> |
14 | 15 | #include <linux/compiler_types.h> |
| 16 | +#include <linux/container_of.h> |
15 | 17 | #include <linux/err.h> |
| 18 | +#include <linux/errno.h> |
16 | 19 | #include <linux/init.h> |
17 | 20 | #include <linux/intel_pmt_features.h> |
18 | 21 | #include <linux/intel_vsec.h> |
| 22 | +#include <linux/io.h> |
19 | 23 | #include <linux/printk.h> |
20 | 24 | #include <linux/resctrl.h> |
21 | 25 | #include <linux/resctrl_types.h> |
@@ -232,3 +236,50 @@ void __exit intel_aet_exit(void) |
232 | 236 | } |
233 | 237 | } |
234 | 238 | } |
| 239 | + |
| 240 | +#define DATA_VALID BIT_ULL(63) |
| 241 | +#define DATA_BITS GENMASK_ULL(62, 0) |
| 242 | + |
| 243 | +/* |
| 244 | + * Read counter for an event on a domain (summing all aggregators on the |
| 245 | + * domain). If an aggregator hasn't received any data for a specific RMID, |
| 246 | + * the MMIO read indicates that data is not valid. Return success if at |
| 247 | + * least one aggregator has valid data. |
| 248 | + */ |
| 249 | +int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val) |
| 250 | +{ |
| 251 | + struct pmt_event *pevt = arch_priv; |
| 252 | + struct event_group *e; |
| 253 | + bool valid = false; |
| 254 | + u64 total = 0; |
| 255 | + u64 evtcount; |
| 256 | + void *pevt0; |
| 257 | + u32 idx; |
| 258 | + |
| 259 | + pevt0 = pevt - pevt->idx; |
| 260 | + e = container_of(pevt0, struct event_group, evts); |
| 261 | + idx = rmid * e->num_events; |
| 262 | + idx += pevt->idx; |
| 263 | + |
| 264 | + if (idx * sizeof(u64) + sizeof(u64) > e->mmio_size) { |
| 265 | + pr_warn_once("MMIO index %u out of range\n", idx); |
| 266 | + return -EIO; |
| 267 | + } |
| 268 | + |
| 269 | + for (int i = 0; i < e->pfg->count; i++) { |
| 270 | + if (!e->pfg->regions[i].addr) |
| 271 | + continue; |
| 272 | + if (e->pfg->regions[i].plat_info.package_id != domid) |
| 273 | + continue; |
| 274 | + evtcount = readq(e->pfg->regions[i].addr + idx * sizeof(u64)); |
| 275 | + if (!(evtcount & DATA_VALID)) |
| 276 | + continue; |
| 277 | + total += evtcount & DATA_BITS; |
| 278 | + valid = true; |
| 279 | + } |
| 280 | + |
| 281 | + if (valid) |
| 282 | + *val = total; |
| 283 | + |
| 284 | + return valid ? 0 : -EINVAL; |
| 285 | +} |
0 commit comments