xref: /linux/drivers/resctrl/mpam_devices.c (revision d02beb06ca2a624e17004659c79d26a23484aa8b)
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2025 Arm Ltd.
3 
4 #define pr_fmt(fmt) "%s:%s: " fmt, KBUILD_MODNAME, __func__
5 
6 #include <linux/acpi.h>
7 #include <linux/atomic.h>
8 #include <linux/arm_mpam.h>
9 #include <linux/bitfield.h>
10 #include <linux/cacheinfo.h>
11 #include <linux/cpu.h>
12 #include <linux/cpumask.h>
13 #include <linux/device.h>
14 #include <linux/errno.h>
15 #include <linux/gfp.h>
16 #include <linux/list.h>
17 #include <linux/lockdep.h>
18 #include <linux/mutex.h>
19 #include <linux/platform_device.h>
20 #include <linux/printk.h>
21 #include <linux/srcu.h>
22 #include <linux/spinlock.h>
23 #include <linux/types.h>
24 #include <linux/workqueue.h>
25 
26 #include "mpam_internal.h"
27 
28 /*
29  * mpam_list_lock protects the SRCU lists when writing. Once the
30  * mpam_enabled key is enabled these lists are read-only,
31  * unless the error interrupt disables the driver.
32  */
33 static DEFINE_MUTEX(mpam_list_lock);
34 static LIST_HEAD(mpam_all_msc);
35 
36 struct srcu_struct mpam_srcu;
37 
38 /*
39  * Number of MSCs that have been probed. Once all MSCs have been probed MPAM
40  * can be enabled.
41  */
42 static atomic_t mpam_num_msc;
43 
44 static int mpam_cpuhp_state;
45 static DEFINE_MUTEX(mpam_cpuhp_state_lock);
46 
47 /*
48  * The smallest common values for any CPU or MSC in the system.
49  * Generating traffic outside this range will result in screaming interrupts.
50  */
51 u16 mpam_partid_max;
52 u8 mpam_pmg_max;
53 static bool partid_max_init, partid_max_published;
54 static DEFINE_SPINLOCK(partid_max_lock);
55 
56 /*
57  * mpam is enabled once all devices have been probed from CPU online callbacks,
58  * scheduled via this work_struct. If access to an MSC depends on a CPU that
59  * was not brought online at boot, this can happen surprisingly late.
60  */
61 static DECLARE_WORK(mpam_enable_work, &mpam_enable);
62 
63 /*
64  * All mpam error interrupts indicate a software bug. On receipt, disable the
65  * driver.
66  */
67 static DECLARE_WORK(mpam_broken_work, &mpam_disable);
68 
69 /* When mpam is disabled, the printed reason to aid debugging */
70 static char *mpam_disable_reason;
71 
72 /*
73  * An MSC is a physical container for controls and monitors, each identified by
74  * their RIS index. These share a base-address, interrupts and some MMIO
75  * registers. A vMSC is a virtual container for RIS in an MSC that control or
76  * monitor the same thing. Members of a vMSC are all RIS in the same MSC, but
77  * not all RIS in an MSC share a vMSC.
78  *
79  * Components are a group of vMSC that control or monitor the same thing but
80  * are from different MSC, so have different base-address, interrupts etc.
81  * Classes are the set components of the same type.
82  *
83  * The features of a vMSC is the union of the RIS it contains.
84  * The features of a Class and Component are the common subset of the vMSC
85  * they contain.
86  *
87  * e.g. The system cache may have bandwidth controls on multiple interfaces,
88  * for regulating traffic from devices independently of traffic from CPUs.
89  * If these are two RIS in one MSC, they will be treated as controlling
90  * different things, and will not share a vMSC/component/class.
91  *
92  * e.g. The L2 may have one MSC and two RIS, one for cache-controls another
93  * for bandwidth. These two RIS are members of the same vMSC.
94  *
95  * e.g. The set of RIS that make up the L2 are grouped as a component. These
96  * are sometimes termed slices. They should be configured the same, as if there
97  * were only one.
98  *
99  * e.g. The SoC probably has more than one L2, each attached to a distinct set
100  * of CPUs. All the L2 components are grouped as a class.
101  *
102  * When creating an MSC, struct mpam_msc is added to the all mpam_all_msc list,
103  * then linked via struct mpam_ris to a vmsc, component and class.
104  * The same MSC may exist under different class->component->vmsc paths, but the
105  * RIS index will be unique.
106  */
107 LIST_HEAD(mpam_classes);
108 
109 /* List of all objects that can be free()d after synchronise_srcu() */
110 static LLIST_HEAD(mpam_garbage);
111 
112 static inline void init_garbage(struct mpam_garbage *garbage)
113 {
114 	init_llist_node(&garbage->llist);
115 }
116 
117 #define add_to_garbage(x)				\
118 do {							\
119 	__typeof__(x) _x = (x);				\
120 	_x->garbage.to_free = _x;			\
121 	llist_add(&_x->garbage.llist, &mpam_garbage);	\
122 } while (0)
123 
124 static void mpam_free_garbage(void)
125 {
126 	struct mpam_garbage *iter, *tmp;
127 	struct llist_node *to_free = llist_del_all(&mpam_garbage);
128 
129 	if (!to_free)
130 		return;
131 
132 	synchronize_srcu(&mpam_srcu);
133 
134 	llist_for_each_entry_safe(iter, tmp, to_free, llist) {
135 		if (iter->pdev)
136 			devm_kfree(&iter->pdev->dev, iter->to_free);
137 		else
138 			kfree(iter->to_free);
139 	}
140 }
141 
142 static u32 __mpam_read_reg(struct mpam_msc *msc, u16 reg)
143 {
144 	WARN_ON_ONCE(!cpumask_test_cpu(smp_processor_id(), &msc->accessibility));
145 
146 	return readl_relaxed(msc->mapped_hwpage + reg);
147 }
148 
149 static inline u32 _mpam_read_partsel_reg(struct mpam_msc *msc, u16 reg)
150 {
151 	lockdep_assert_held_once(&msc->part_sel_lock);
152 	return __mpam_read_reg(msc, reg);
153 }
154 
155 #define mpam_read_partsel_reg(msc, reg) _mpam_read_partsel_reg(msc, MPAMF_##reg)
156 
157 static void __mpam_write_reg(struct mpam_msc *msc, u16 reg, u32 val)
158 {
159 	WARN_ON_ONCE(reg + sizeof(u32) > msc->mapped_hwpage_sz);
160 	WARN_ON_ONCE(!cpumask_test_cpu(smp_processor_id(), &msc->accessibility));
161 
162 	writel_relaxed(val, msc->mapped_hwpage + reg);
163 }
164 
165 static inline void _mpam_write_partsel_reg(struct mpam_msc *msc, u16 reg, u32 val)
166 {
167 	lockdep_assert_held_once(&msc->part_sel_lock);
168 	__mpam_write_reg(msc, reg, val);
169 }
170 
171 #define mpam_write_partsel_reg(msc, reg, val)  _mpam_write_partsel_reg(msc, MPAMCFG_##reg, val)
172 
173 static u64 mpam_msc_read_idr(struct mpam_msc *msc)
174 {
175 	u64 idr_high = 0, idr_low;
176 
177 	lockdep_assert_held(&msc->part_sel_lock);
178 
179 	idr_low = mpam_read_partsel_reg(msc, IDR);
180 	if (FIELD_GET(MPAMF_IDR_EXT, idr_low))
181 		idr_high = mpam_read_partsel_reg(msc, IDR + 4);
182 
183 	return (idr_high << 32) | idr_low;
184 }
185 
186 static void __mpam_part_sel_raw(u32 partsel, struct mpam_msc *msc)
187 {
188 	lockdep_assert_held(&msc->part_sel_lock);
189 
190 	mpam_write_partsel_reg(msc, PART_SEL, partsel);
191 }
192 
193 static void __mpam_part_sel(u8 ris_idx, u16 partid, struct mpam_msc *msc)
194 {
195 	u32 partsel = FIELD_PREP(MPAMCFG_PART_SEL_RIS, ris_idx) |
196 		      FIELD_PREP(MPAMCFG_PART_SEL_PARTID_SEL, partid);
197 
198 	__mpam_part_sel_raw(partsel, msc);
199 }
200 
201 int mpam_register_requestor(u16 partid_max, u8 pmg_max)
202 {
203 	guard(spinlock)(&partid_max_lock);
204 	if (!partid_max_init) {
205 		mpam_partid_max = partid_max;
206 		mpam_pmg_max = pmg_max;
207 		partid_max_init = true;
208 	} else if (!partid_max_published) {
209 		mpam_partid_max = min(mpam_partid_max, partid_max);
210 		mpam_pmg_max = min(mpam_pmg_max, pmg_max);
211 	} else {
212 		/* New requestors can't lower the values */
213 		if (partid_max < mpam_partid_max || pmg_max < mpam_pmg_max)
214 			return -EBUSY;
215 	}
216 
217 	return 0;
218 }
219 EXPORT_SYMBOL(mpam_register_requestor);
220 
221 static struct mpam_class *
222 mpam_class_alloc(u8 level_idx, enum mpam_class_types type)
223 {
224 	struct mpam_class *class;
225 
226 	lockdep_assert_held(&mpam_list_lock);
227 
228 	class = kzalloc(sizeof(*class), GFP_KERNEL);
229 	if (!class)
230 		return ERR_PTR(-ENOMEM);
231 	init_garbage(&class->garbage);
232 
233 	INIT_LIST_HEAD_RCU(&class->components);
234 	/* Affinity is updated when ris are added */
235 	class->level = level_idx;
236 	class->type = type;
237 	INIT_LIST_HEAD_RCU(&class->classes_list);
238 
239 	list_add_rcu(&class->classes_list, &mpam_classes);
240 
241 	return class;
242 }
243 
244 static void mpam_class_destroy(struct mpam_class *class)
245 {
246 	lockdep_assert_held(&mpam_list_lock);
247 
248 	list_del_rcu(&class->classes_list);
249 	add_to_garbage(class);
250 }
251 
252 static struct mpam_class *
253 mpam_class_find(u8 level_idx, enum mpam_class_types type)
254 {
255 	struct mpam_class *class;
256 
257 	lockdep_assert_held(&mpam_list_lock);
258 
259 	list_for_each_entry(class, &mpam_classes, classes_list) {
260 		if (class->type == type && class->level == level_idx)
261 			return class;
262 	}
263 
264 	return mpam_class_alloc(level_idx, type);
265 }
266 
267 static struct mpam_component *
268 mpam_component_alloc(struct mpam_class *class, int id)
269 {
270 	struct mpam_component *comp;
271 
272 	lockdep_assert_held(&mpam_list_lock);
273 
274 	comp = kzalloc(sizeof(*comp), GFP_KERNEL);
275 	if (!comp)
276 		return ERR_PTR(-ENOMEM);
277 	init_garbage(&comp->garbage);
278 
279 	comp->comp_id = id;
280 	INIT_LIST_HEAD_RCU(&comp->vmsc);
281 	/* Affinity is updated when RIS are added */
282 	INIT_LIST_HEAD_RCU(&comp->class_list);
283 	comp->class = class;
284 
285 	list_add_rcu(&comp->class_list, &class->components);
286 
287 	return comp;
288 }
289 
290 static void mpam_component_destroy(struct mpam_component *comp)
291 {
292 	struct mpam_class *class = comp->class;
293 
294 	lockdep_assert_held(&mpam_list_lock);
295 
296 	list_del_rcu(&comp->class_list);
297 	add_to_garbage(comp);
298 
299 	if (list_empty(&class->components))
300 		mpam_class_destroy(class);
301 }
302 
303 static struct mpam_component *
304 mpam_component_find(struct mpam_class *class, int id)
305 {
306 	struct mpam_component *comp;
307 
308 	lockdep_assert_held(&mpam_list_lock);
309 
310 	list_for_each_entry(comp, &class->components, class_list) {
311 		if (comp->comp_id == id)
312 			return comp;
313 	}
314 
315 	return mpam_component_alloc(class, id);
316 }
317 
318 static struct mpam_vmsc *
319 mpam_vmsc_alloc(struct mpam_component *comp, struct mpam_msc *msc)
320 {
321 	struct mpam_vmsc *vmsc;
322 
323 	lockdep_assert_held(&mpam_list_lock);
324 
325 	vmsc = kzalloc(sizeof(*vmsc), GFP_KERNEL);
326 	if (!vmsc)
327 		return ERR_PTR(-ENOMEM);
328 	init_garbage(&vmsc->garbage);
329 
330 	INIT_LIST_HEAD_RCU(&vmsc->ris);
331 	INIT_LIST_HEAD_RCU(&vmsc->comp_list);
332 	vmsc->comp = comp;
333 	vmsc->msc = msc;
334 
335 	list_add_rcu(&vmsc->comp_list, &comp->vmsc);
336 
337 	return vmsc;
338 }
339 
340 static void mpam_vmsc_destroy(struct mpam_vmsc *vmsc)
341 {
342 	struct mpam_component *comp = vmsc->comp;
343 
344 	lockdep_assert_held(&mpam_list_lock);
345 
346 	list_del_rcu(&vmsc->comp_list);
347 	add_to_garbage(vmsc);
348 
349 	if (list_empty(&comp->vmsc))
350 		mpam_component_destroy(comp);
351 }
352 
353 static struct mpam_vmsc *
354 mpam_vmsc_find(struct mpam_component *comp, struct mpam_msc *msc)
355 {
356 	struct mpam_vmsc *vmsc;
357 
358 	lockdep_assert_held(&mpam_list_lock);
359 
360 	list_for_each_entry(vmsc, &comp->vmsc, comp_list) {
361 		if (vmsc->msc->id == msc->id)
362 			return vmsc;
363 	}
364 
365 	return mpam_vmsc_alloc(comp, msc);
366 }
367 
368 /*
369  * The cacheinfo structures are only populated when CPUs are online.
370  * This helper walks the acpi tables to include offline CPUs too.
371  */
372 int mpam_get_cpumask_from_cache_id(unsigned long cache_id, u32 cache_level,
373 				   cpumask_t *affinity)
374 {
375 	return acpi_pptt_get_cpumask_from_cache_id(cache_id, affinity);
376 }
377 
378 /*
379  * cpumask_of_node() only knows about online CPUs. This can't tell us whether
380  * a class is represented on all possible CPUs.
381  */
382 static void get_cpumask_from_node_id(u32 node_id, cpumask_t *affinity)
383 {
384 	int cpu;
385 
386 	for_each_possible_cpu(cpu) {
387 		if (node_id == cpu_to_node(cpu))
388 			cpumask_set_cpu(cpu, affinity);
389 	}
390 }
391 
392 static int mpam_ris_get_affinity(struct mpam_msc *msc, cpumask_t *affinity,
393 				 enum mpam_class_types type,
394 				 struct mpam_class *class,
395 				 struct mpam_component *comp)
396 {
397 	int err;
398 
399 	switch (type) {
400 	case MPAM_CLASS_CACHE:
401 		err = mpam_get_cpumask_from_cache_id(comp->comp_id, class->level,
402 						     affinity);
403 		if (err) {
404 			dev_warn_once(&msc->pdev->dev,
405 				      "Failed to determine CPU affinity\n");
406 			return err;
407 		}
408 
409 		if (cpumask_empty(affinity))
410 			dev_warn_once(&msc->pdev->dev, "no CPUs associated with cache node\n");
411 
412 		break;
413 	case MPAM_CLASS_MEMORY:
414 		get_cpumask_from_node_id(comp->comp_id, affinity);
415 		/* affinity may be empty for CPU-less memory nodes */
416 		break;
417 	case MPAM_CLASS_UNKNOWN:
418 		return 0;
419 	}
420 
421 	cpumask_and(affinity, affinity, &msc->accessibility);
422 
423 	return 0;
424 }
425 
426 static int mpam_ris_create_locked(struct mpam_msc *msc, u8 ris_idx,
427 				  enum mpam_class_types type, u8 class_id,
428 				  int component_id)
429 {
430 	int err;
431 	struct mpam_vmsc *vmsc;
432 	struct mpam_msc_ris *ris;
433 	struct mpam_class *class;
434 	struct mpam_component *comp;
435 	struct platform_device *pdev = msc->pdev;
436 
437 	lockdep_assert_held(&mpam_list_lock);
438 
439 	if (ris_idx > MPAM_MSC_MAX_NUM_RIS)
440 		return -EINVAL;
441 
442 	if (test_and_set_bit(ris_idx, &msc->ris_idxs))
443 		return -EBUSY;
444 
445 	ris = devm_kzalloc(&msc->pdev->dev, sizeof(*ris), GFP_KERNEL);
446 	if (!ris)
447 		return -ENOMEM;
448 	init_garbage(&ris->garbage);
449 	ris->garbage.pdev = pdev;
450 
451 	class = mpam_class_find(class_id, type);
452 	if (IS_ERR(class))
453 		return PTR_ERR(class);
454 
455 	comp = mpam_component_find(class, component_id);
456 	if (IS_ERR(comp)) {
457 		if (list_empty(&class->components))
458 			mpam_class_destroy(class);
459 		return PTR_ERR(comp);
460 	}
461 
462 	vmsc = mpam_vmsc_find(comp, msc);
463 	if (IS_ERR(vmsc)) {
464 		if (list_empty(&comp->vmsc))
465 			mpam_component_destroy(comp);
466 		return PTR_ERR(vmsc);
467 	}
468 
469 	err = mpam_ris_get_affinity(msc, &ris->affinity, type, class, comp);
470 	if (err) {
471 		if (list_empty(&vmsc->ris))
472 			mpam_vmsc_destroy(vmsc);
473 		return err;
474 	}
475 
476 	ris->ris_idx = ris_idx;
477 	INIT_LIST_HEAD_RCU(&ris->msc_list);
478 	INIT_LIST_HEAD_RCU(&ris->vmsc_list);
479 	ris->vmsc = vmsc;
480 
481 	cpumask_or(&comp->affinity, &comp->affinity, &ris->affinity);
482 	cpumask_or(&class->affinity, &class->affinity, &ris->affinity);
483 	list_add_rcu(&ris->vmsc_list, &vmsc->ris);
484 	list_add_rcu(&ris->msc_list, &msc->ris);
485 
486 	return 0;
487 }
488 
489 static void mpam_ris_destroy(struct mpam_msc_ris *ris)
490 {
491 	struct mpam_vmsc *vmsc = ris->vmsc;
492 	struct mpam_msc *msc = vmsc->msc;
493 	struct mpam_component *comp = vmsc->comp;
494 	struct mpam_class *class = comp->class;
495 
496 	lockdep_assert_held(&mpam_list_lock);
497 
498 	/*
499 	 * It is assumed affinities don't overlap. If they do the class becomes
500 	 * unusable immediately.
501 	 */
502 	cpumask_andnot(&class->affinity, &class->affinity, &ris->affinity);
503 	cpumask_andnot(&comp->affinity, &comp->affinity, &ris->affinity);
504 	clear_bit(ris->ris_idx, &msc->ris_idxs);
505 	list_del_rcu(&ris->msc_list);
506 	list_del_rcu(&ris->vmsc_list);
507 	add_to_garbage(ris);
508 
509 	if (list_empty(&vmsc->ris))
510 		mpam_vmsc_destroy(vmsc);
511 }
512 
513 int mpam_ris_create(struct mpam_msc *msc, u8 ris_idx,
514 		    enum mpam_class_types type, u8 class_id, int component_id)
515 {
516 	int err;
517 
518 	mutex_lock(&mpam_list_lock);
519 	err = mpam_ris_create_locked(msc, ris_idx, type, class_id,
520 				     component_id);
521 	mutex_unlock(&mpam_list_lock);
522 	if (err)
523 		mpam_free_garbage();
524 
525 	return err;
526 }
527 
528 static struct mpam_msc_ris *mpam_get_or_create_ris(struct mpam_msc *msc,
529 						   u8 ris_idx)
530 {
531 	int err;
532 	struct mpam_msc_ris *ris;
533 
534 	lockdep_assert_held(&mpam_list_lock);
535 
536 	if (!test_bit(ris_idx, &msc->ris_idxs)) {
537 		err = mpam_ris_create_locked(msc, ris_idx, MPAM_CLASS_UNKNOWN,
538 					     0, 0);
539 		if (err)
540 			return ERR_PTR(err);
541 	}
542 
543 	list_for_each_entry(ris, &msc->ris, msc_list) {
544 		if (ris->ris_idx == ris_idx)
545 			return ris;
546 	}
547 
548 	return ERR_PTR(-ENOENT);
549 }
550 
551 static int mpam_msc_hw_probe(struct mpam_msc *msc)
552 {
553 	u64 idr;
554 	u16 partid_max;
555 	u8 ris_idx, pmg_max;
556 	struct mpam_msc_ris *ris;
557 	struct device *dev = &msc->pdev->dev;
558 
559 	lockdep_assert_held(&msc->probe_lock);
560 
561 	idr = __mpam_read_reg(msc, MPAMF_AIDR);
562 	if ((idr & MPAMF_AIDR_ARCH_MAJOR_REV) != MPAM_ARCHITECTURE_V1) {
563 		dev_err_once(dev, "MSC does not match MPAM architecture v1.x\n");
564 		return -EIO;
565 	}
566 
567 	/* Grab an IDR value to find out how many RIS there are */
568 	mutex_lock(&msc->part_sel_lock);
569 	idr = mpam_msc_read_idr(msc);
570 	mutex_unlock(&msc->part_sel_lock);
571 
572 	msc->ris_max = FIELD_GET(MPAMF_IDR_RIS_MAX, idr);
573 
574 	/* Use these values so partid/pmg always starts with a valid value */
575 	msc->partid_max = FIELD_GET(MPAMF_IDR_PARTID_MAX, idr);
576 	msc->pmg_max = FIELD_GET(MPAMF_IDR_PMG_MAX, idr);
577 
578 	for (ris_idx = 0; ris_idx <= msc->ris_max; ris_idx++) {
579 		mutex_lock(&msc->part_sel_lock);
580 		__mpam_part_sel(ris_idx, 0, msc);
581 		idr = mpam_msc_read_idr(msc);
582 		mutex_unlock(&msc->part_sel_lock);
583 
584 		partid_max = FIELD_GET(MPAMF_IDR_PARTID_MAX, idr);
585 		pmg_max = FIELD_GET(MPAMF_IDR_PMG_MAX, idr);
586 		msc->partid_max = min(msc->partid_max, partid_max);
587 		msc->pmg_max = min(msc->pmg_max, pmg_max);
588 
589 		mutex_lock(&mpam_list_lock);
590 		ris = mpam_get_or_create_ris(msc, ris_idx);
591 		mutex_unlock(&mpam_list_lock);
592 		if (IS_ERR(ris))
593 			return PTR_ERR(ris);
594 	}
595 
596 	spin_lock(&partid_max_lock);
597 	mpam_partid_max = min(mpam_partid_max, msc->partid_max);
598 	mpam_pmg_max = min(mpam_pmg_max, msc->pmg_max);
599 	spin_unlock(&partid_max_lock);
600 
601 	msc->probed = true;
602 
603 	return 0;
604 }
605 
606 static int mpam_cpu_online(unsigned int cpu)
607 {
608 	return 0;
609 }
610 
611 /* Before mpam is enabled, try to probe new MSC */
612 static int mpam_discovery_cpu_online(unsigned int cpu)
613 {
614 	int err = 0;
615 	struct mpam_msc *msc;
616 	bool new_device_probed = false;
617 
618 	guard(srcu)(&mpam_srcu);
619 	list_for_each_entry_srcu(msc, &mpam_all_msc, all_msc_list,
620 				 srcu_read_lock_held(&mpam_srcu)) {
621 		if (!cpumask_test_cpu(cpu, &msc->accessibility))
622 			continue;
623 
624 		mutex_lock(&msc->probe_lock);
625 		if (!msc->probed)
626 			err = mpam_msc_hw_probe(msc);
627 		mutex_unlock(&msc->probe_lock);
628 
629 		if (err)
630 			break;
631 		new_device_probed = true;
632 	}
633 
634 	if (new_device_probed && !err)
635 		schedule_work(&mpam_enable_work);
636 	if (err) {
637 		mpam_disable_reason = "error during probing";
638 		schedule_work(&mpam_broken_work);
639 	}
640 
641 	return err;
642 }
643 
644 static int mpam_cpu_offline(unsigned int cpu)
645 {
646 	return 0;
647 }
648 
649 static void mpam_register_cpuhp_callbacks(int (*online)(unsigned int online),
650 					  int (*offline)(unsigned int offline),
651 					  char *name)
652 {
653 	mutex_lock(&mpam_cpuhp_state_lock);
654 	if (mpam_cpuhp_state) {
655 		cpuhp_remove_state(mpam_cpuhp_state);
656 		mpam_cpuhp_state = 0;
657 	}
658 
659 	mpam_cpuhp_state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, name, online,
660 					     offline);
661 	if (mpam_cpuhp_state <= 0) {
662 		pr_err("Failed to register cpuhp callbacks");
663 		mpam_cpuhp_state = 0;
664 	}
665 	mutex_unlock(&mpam_cpuhp_state_lock);
666 }
667 
668 /*
669  * An MSC can control traffic from a set of CPUs, but may only be accessible
670  * from a (hopefully wider) set of CPUs. The common reason for this is power
671  * management. If all the CPUs in a cluster are in PSCI:CPU_SUSPEND, the
672  * corresponding cache may also be powered off. By making accesses from
673  * one of those CPUs, we ensure we don't access a cache that's powered off.
674  */
675 static void update_msc_accessibility(struct mpam_msc *msc)
676 {
677 	u32 affinity_id;
678 	int err;
679 
680 	err = device_property_read_u32(&msc->pdev->dev, "cpu_affinity",
681 				       &affinity_id);
682 	if (err)
683 		cpumask_copy(&msc->accessibility, cpu_possible_mask);
684 	else
685 		acpi_pptt_get_cpus_from_container(affinity_id, &msc->accessibility);
686 }
687 
688 /*
689  * There are two ways of reaching a struct mpam_msc_ris. Via the
690  * class->component->vmsc->ris, or via the msc.
691  * When destroying the msc, the other side needs unlinking and cleaning up too.
692  */
693 static void mpam_msc_destroy(struct mpam_msc *msc)
694 {
695 	struct platform_device *pdev = msc->pdev;
696 	struct mpam_msc_ris *ris, *tmp;
697 
698 	lockdep_assert_held(&mpam_list_lock);
699 
700 	list_for_each_entry_safe(ris, tmp, &msc->ris, msc_list)
701 		mpam_ris_destroy(ris);
702 
703 	list_del_rcu(&msc->all_msc_list);
704 	platform_set_drvdata(pdev, NULL);
705 
706 	add_to_garbage(msc);
707 }
708 
709 static void mpam_msc_drv_remove(struct platform_device *pdev)
710 {
711 	struct mpam_msc *msc = platform_get_drvdata(pdev);
712 
713 	mutex_lock(&mpam_list_lock);
714 	mpam_msc_destroy(msc);
715 	mutex_unlock(&mpam_list_lock);
716 
717 	mpam_free_garbage();
718 }
719 
720 static struct mpam_msc *do_mpam_msc_drv_probe(struct platform_device *pdev)
721 {
722 	int err;
723 	u32 tmp;
724 	struct mpam_msc *msc;
725 	struct resource *msc_res;
726 	struct device *dev = &pdev->dev;
727 
728 	lockdep_assert_held(&mpam_list_lock);
729 
730 	msc = devm_kzalloc(&pdev->dev, sizeof(*msc), GFP_KERNEL);
731 	if (!msc)
732 		return ERR_PTR(-ENOMEM);
733 	init_garbage(&msc->garbage);
734 	msc->garbage.pdev = pdev;
735 
736 	err = devm_mutex_init(dev, &msc->probe_lock);
737 	if (err)
738 		return ERR_PTR(err);
739 
740 	err = devm_mutex_init(dev, &msc->part_sel_lock);
741 	if (err)
742 		return ERR_PTR(err);
743 
744 	mpam_mon_sel_lock_init(msc);
745 	msc->id = pdev->id;
746 	msc->pdev = pdev;
747 	INIT_LIST_HEAD_RCU(&msc->all_msc_list);
748 	INIT_LIST_HEAD_RCU(&msc->ris);
749 
750 	update_msc_accessibility(msc);
751 	if (cpumask_empty(&msc->accessibility)) {
752 		dev_err_once(dev, "MSC is not accessible from any CPU!");
753 		return ERR_PTR(-EINVAL);
754 	}
755 
756 	if (device_property_read_u32(&pdev->dev, "pcc-channel", &tmp))
757 		msc->iface = MPAM_IFACE_MMIO;
758 	else
759 		msc->iface = MPAM_IFACE_PCC;
760 
761 	if (msc->iface == MPAM_IFACE_MMIO) {
762 		void __iomem *io;
763 
764 		io = devm_platform_get_and_ioremap_resource(pdev, 0,
765 							    &msc_res);
766 		if (IS_ERR(io)) {
767 			dev_err_once(dev, "Failed to map MSC base address\n");
768 			return ERR_CAST(io);
769 		}
770 		msc->mapped_hwpage_sz = msc_res->end - msc_res->start;
771 		msc->mapped_hwpage = io;
772 	} else {
773 		return ERR_PTR(-EINVAL);
774 	}
775 
776 	list_add_rcu(&msc->all_msc_list, &mpam_all_msc);
777 	platform_set_drvdata(pdev, msc);
778 
779 	return msc;
780 }
781 
782 static int fw_num_msc;
783 
784 static int mpam_msc_drv_probe(struct platform_device *pdev)
785 {
786 	int err;
787 	struct mpam_msc *msc = NULL;
788 	void *plat_data = pdev->dev.platform_data;
789 
790 	mutex_lock(&mpam_list_lock);
791 	msc = do_mpam_msc_drv_probe(pdev);
792 	mutex_unlock(&mpam_list_lock);
793 
794 	if (IS_ERR(msc))
795 		return PTR_ERR(msc);
796 
797 	/* Create RIS entries described by firmware */
798 	err = acpi_mpam_parse_resources(msc, plat_data);
799 	if (err) {
800 		mpam_msc_drv_remove(pdev);
801 		return err;
802 	}
803 
804 	if (atomic_add_return(1, &mpam_num_msc) == fw_num_msc)
805 		mpam_register_cpuhp_callbacks(mpam_discovery_cpu_online, NULL,
806 					      "mpam:drv_probe");
807 
808 	return 0;
809 }
810 
811 static struct platform_driver mpam_msc_driver = {
812 	.driver = {
813 		.name = "mpam_msc",
814 	},
815 	.probe = mpam_msc_drv_probe,
816 	.remove = mpam_msc_drv_remove,
817 };
818 
819 static void mpam_enable_once(void)
820 {
821 	/*
822 	 * Once the cpuhp callbacks have been changed, mpam_partid_max can no
823 	 * longer change.
824 	 */
825 	spin_lock(&partid_max_lock);
826 	partid_max_published = true;
827 	spin_unlock(&partid_max_lock);
828 
829 	mpam_register_cpuhp_callbacks(mpam_cpu_online, mpam_cpu_offline,
830 				      "mpam:online");
831 
832 	/* Use printk() to avoid the pr_fmt adding the function name. */
833 	printk(KERN_INFO "MPAM enabled with %u PARTIDs and %u PMGs\n",
834 	       mpam_partid_max + 1, mpam_pmg_max + 1);
835 }
836 
837 void mpam_disable(struct work_struct *ignored)
838 {
839 	struct mpam_msc *msc, *tmp;
840 
841 	mutex_lock(&mpam_cpuhp_state_lock);
842 	if (mpam_cpuhp_state) {
843 		cpuhp_remove_state(mpam_cpuhp_state);
844 		mpam_cpuhp_state = 0;
845 	}
846 	mutex_unlock(&mpam_cpuhp_state_lock);
847 
848 	mutex_lock(&mpam_list_lock);
849 	list_for_each_entry_safe(msc, tmp, &mpam_all_msc, all_msc_list)
850 		mpam_msc_destroy(msc);
851 	mutex_unlock(&mpam_list_lock);
852 	mpam_free_garbage();
853 
854 	pr_err_once("MPAM disabled due to %s\n", mpam_disable_reason);
855 }
856 
857 /*
858  * Enable mpam once all devices have been probed.
859  * Scheduled by mpam_discovery_cpu_online() once all devices have been created.
860  * Also scheduled when new devices are probed when new CPUs come online.
861  */
862 void mpam_enable(struct work_struct *work)
863 {
864 	static atomic_t once;
865 	struct mpam_msc *msc;
866 	bool all_devices_probed = true;
867 
868 	/* Have we probed all the hw devices? */
869 	guard(srcu)(&mpam_srcu);
870 	list_for_each_entry_srcu(msc, &mpam_all_msc, all_msc_list,
871 				 srcu_read_lock_held(&mpam_srcu)) {
872 		mutex_lock(&msc->probe_lock);
873 		if (!msc->probed)
874 			all_devices_probed = false;
875 		mutex_unlock(&msc->probe_lock);
876 
877 		if (!all_devices_probed)
878 			break;
879 	}
880 
881 	if (all_devices_probed && !atomic_fetch_inc(&once))
882 		mpam_enable_once();
883 }
884 
885 static int __init mpam_msc_driver_init(void)
886 {
887 	if (!system_supports_mpam())
888 		return -EOPNOTSUPP;
889 
890 	init_srcu_struct(&mpam_srcu);
891 
892 	fw_num_msc = acpi_mpam_count_msc();
893 	if (fw_num_msc <= 0) {
894 		pr_err("No MSC devices found in firmware\n");
895 		return -EINVAL;
896 	}
897 
898 	return platform_driver_register(&mpam_msc_driver);
899 }
900 
901 /* Must occur after arm64_mpam_register_cpus() from arch_initcall() */
902 subsys_initcall(mpam_msc_driver_init);
903