1 /* SPDX-License-Identifier: GPL-2.0 */ 2 // Copyright (C) 2025 Arm Ltd. 3 4 #ifndef MPAM_INTERNAL_H 5 #define MPAM_INTERNAL_H 6 7 #include <linux/arm_mpam.h> 8 #include <linux/cpumask.h> 9 #include <linux/io.h> 10 #include <linux/llist.h> 11 #include <linux/mutex.h> 12 #include <linux/srcu.h> 13 #include <linux/types.h> 14 15 #define MPAM_MSC_MAX_NUM_RIS 16 16 17 struct platform_device; 18 19 /* 20 * Structures protected by SRCU may not be freed for a surprising amount of 21 * time (especially if perf is running). To ensure the MPAM error interrupt can 22 * tear down all the structures, build a list of objects that can be garbage 23 * collected once synchronize_srcu() has returned. 24 * If pdev is non-NULL, use devm_kfree(). 25 */ 26 struct mpam_garbage { 27 /* member of mpam_garbage */ 28 struct llist_node llist; 29 30 void *to_free; 31 struct platform_device *pdev; 32 }; 33 34 struct mpam_msc { 35 /* member of mpam_all_msc */ 36 struct list_head all_msc_list; 37 38 int id; 39 struct platform_device *pdev; 40 41 /* Not modified after mpam_is_enabled() becomes true */ 42 enum mpam_msc_iface iface; 43 u32 nrdy_usec; 44 cpumask_t accessibility; 45 46 /* 47 * probe_lock is only taken during discovery. After discovery these 48 * properties become read-only and the lists are protected by SRCU. 49 */ 50 struct mutex probe_lock; 51 unsigned long ris_idxs; 52 u32 ris_max; 53 54 /* mpam_msc_ris of this component */ 55 struct list_head ris; 56 57 /* 58 * part_sel_lock protects access to the MSC hardware registers that are 59 * affected by MPAMCFG_PART_SEL. (including the ID registers that vary 60 * by RIS). 61 * If needed, take msc->probe_lock first. 62 */ 63 struct mutex part_sel_lock; 64 65 void __iomem *mapped_hwpage; 66 size_t mapped_hwpage_sz; 67 68 struct mpam_garbage garbage; 69 }; 70 71 struct mpam_class { 72 /* mpam_components in this class */ 73 struct list_head components; 74 75 cpumask_t affinity; 76 77 u8 level; 78 enum mpam_class_types type; 79 80 /* member of mpam_classes */ 81 struct list_head classes_list; 82 83 struct mpam_garbage garbage; 84 }; 85 86 struct mpam_component { 87 u32 comp_id; 88 89 /* mpam_vmsc in this component */ 90 struct list_head vmsc; 91 92 cpumask_t affinity; 93 94 /* member of mpam_class:components */ 95 struct list_head class_list; 96 97 /* parent: */ 98 struct mpam_class *class; 99 100 struct mpam_garbage garbage; 101 }; 102 103 struct mpam_vmsc { 104 /* member of mpam_component:vmsc_list */ 105 struct list_head comp_list; 106 107 /* mpam_msc_ris in this vmsc */ 108 struct list_head ris; 109 110 /* All RIS in this vMSC are members of this MSC */ 111 struct mpam_msc *msc; 112 113 /* parent: */ 114 struct mpam_component *comp; 115 116 struct mpam_garbage garbage; 117 }; 118 119 struct mpam_msc_ris { 120 u8 ris_idx; 121 122 cpumask_t affinity; 123 124 /* member of mpam_vmsc:ris */ 125 struct list_head vmsc_list; 126 127 /* member of mpam_msc:ris */ 128 struct list_head msc_list; 129 130 /* parent: */ 131 struct mpam_vmsc *vmsc; 132 133 struct mpam_garbage garbage; 134 }; 135 136 /* List of all classes - protected by srcu*/ 137 extern struct srcu_struct mpam_srcu; 138 extern struct list_head mpam_classes; 139 140 int mpam_get_cpumask_from_cache_id(unsigned long cache_id, u32 cache_level, 141 cpumask_t *affinity); 142 143 #endif /* MPAM_INTERNAL_H */ 144