xref: /linux/arch/x86/kernel/cpu/resctrl/internal.h (revision f4e0cd80d3e7c31327459008b01d63804838a89d)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_X86_RESCTRL_INTERNAL_H
3 #define _ASM_X86_RESCTRL_INTERNAL_H
4 
5 #include <linux/resctrl.h>
6 
7 #define L3_QOS_CDP_ENABLE		0x01ULL
8 
9 #define L2_QOS_CDP_ENABLE		0x01ULL
10 
11 #define MBM_CNTR_WIDTH_BASE		24
12 
13 #define MBA_IS_LINEAR			0x4
14 
15 #define MBM_CNTR_WIDTH_OFFSET_AMD	20
16 
17 #define RMID_VAL_ERROR			BIT_ULL(63)
18 
19 #define RMID_VAL_UNAVAIL		BIT_ULL(62)
20 
21 /*
22  * With the above fields in use 62 bits remain in MSR_IA32_QM_CTR for
23  * data to be returned. The counter width is discovered from the hardware
24  * as an offset from MBM_CNTR_WIDTH_BASE.
25  */
26 #define MBM_CNTR_WIDTH_OFFSET_MAX (62 - MBM_CNTR_WIDTH_BASE)
27 
28 /**
29  * struct arch_mbm_state - values used to compute resctrl_arch_rmid_read()s
30  *			   return value.
31  * @chunks:	Total data moved (multiply by rdt_group.mon_scale to get bytes)
32  * @prev_msr:	Value of IA32_QM_CTR last time it was read for the RMID used to
33  *		find this struct.
34  */
35 struct arch_mbm_state {
36 	u64	chunks;
37 	u64	prev_msr;
38 };
39 
40 /* Setting bit 0 in L3_QOS_EXT_CFG enables the ABMC feature. */
41 #define ABMC_ENABLE_BIT			0
42 
43 /*
44  * Qos Event Identifiers.
45  */
46 #define ABMC_EXTENDED_EVT_ID		BIT(31)
47 #define ABMC_EVT_ID			BIT(0)
48 
49 /* Setting bit 1 in MSR_IA32_L3_QOS_EXT_CFG enables the SDCIAE feature. */
50 #define SDCIAE_ENABLE_BIT		1
51 
52 /**
53  * struct rdt_hw_ctrl_domain - Arch private attributes of a set of CPUs that share
54  *			       a resource for a control function
55  * @d_resctrl:	Properties exposed to the resctrl file system
56  * @ctrl_val:	array of cache or mem ctrl values (indexed by CLOSID)
57  *
58  * Members of this structure are accessed via helpers that provide abstraction.
59  */
60 struct rdt_hw_ctrl_domain {
61 	struct rdt_ctrl_domain		d_resctrl;
62 	u32				*ctrl_val;
63 };
64 
65 /**
66  * struct rdt_hw_l3_mon_domain - Arch private attributes of a set of CPUs sharing
67  *				 RDT_RESOURCE_L3 monitoring
68  * @d_resctrl:		Properties exposed to the resctrl file system
69  * @arch_mbm_states:	Per-event pointer to the MBM event's saved state.
70  *			An MBM event's state is an array of struct arch_mbm_state
71  *			indexed by RMID on x86.
72  *
73  * Members of this structure are accessed via helpers that provide abstraction.
74  */
75 struct rdt_hw_l3_mon_domain {
76 	struct rdt_l3_mon_domain	d_resctrl;
77 	struct arch_mbm_state		*arch_mbm_states[QOS_NUM_L3_MBM_EVENTS];
78 };
79 
80 static inline struct rdt_hw_ctrl_domain *resctrl_to_arch_ctrl_dom(struct rdt_ctrl_domain *r)
81 {
82 	return container_of(r, struct rdt_hw_ctrl_domain, d_resctrl);
83 }
84 
85 static inline struct rdt_hw_l3_mon_domain *resctrl_to_arch_mon_dom(struct rdt_l3_mon_domain *r)
86 {
87 	return container_of(r, struct rdt_hw_l3_mon_domain, d_resctrl);
88 }
89 
90 /**
91  * struct rdt_perf_pkg_mon_domain - CPUs sharing an package scoped resctrl monitor resource
92  * @hdr:	common header for different domain types
93  */
94 struct rdt_perf_pkg_mon_domain {
95 	struct rdt_domain_hdr	hdr;
96 };
97 
98 /**
99  * struct msr_param - set a range of MSRs from a domain
100  * @res:       The resource to use
101  * @dom:       The domain to update
102  * @low:       Beginning index from base MSR
103  * @high:      End index
104  */
105 struct msr_param {
106 	struct rdt_resource	*res;
107 	struct rdt_ctrl_domain	*dom;
108 	u32			low;
109 	u32			high;
110 };
111 
112 /**
113  * struct rdt_hw_resource - arch private attributes of a resctrl resource
114  * @r_resctrl:		Attributes of the resource used directly by resctrl.
115  * @num_closid:		Maximum number of closid this hardware can support,
116  *			regardless of CDP. This is exposed via
117  *			resctrl_arch_get_num_closid() to avoid confusion
118  *			with struct resctrl_schema's property of the same name,
119  *			which has been corrected for features like CDP.
120  * @msr_base:		Base MSR address for CBMs
121  * @msr_update:		Function pointer to update QOS MSRs
122  * @mon_scale:		cqm counter * mon_scale = occupancy in bytes
123  * @mbm_width:		Monitor width, to detect and correct for overflow.
124  * @cdp_enabled:	CDP state of this resource
125  * @mbm_cntr_assign_enabled:	ABMC feature is enabled
126  * @sdciae_enabled:	SDCIAE feature (backing "io_alloc") is enabled.
127  *
128  * Members of this structure are either private to the architecture
129  * e.g. mbm_width, or accessed via helpers that provide abstraction. e.g.
130  * msr_update and msr_base.
131  */
132 struct rdt_hw_resource {
133 	struct rdt_resource	r_resctrl;
134 	u32			num_closid;
135 	unsigned int		msr_base;
136 	void			(*msr_update)(struct msr_param *m);
137 	unsigned int		mon_scale;
138 	unsigned int		mbm_width;
139 	bool			cdp_enabled;
140 	bool			mbm_cntr_assign_enabled;
141 	bool			sdciae_enabled;
142 };
143 
144 static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r)
145 {
146 	return container_of(r, struct rdt_hw_resource, r_resctrl);
147 }
148 
149 extern struct rdt_hw_resource rdt_resources_all[];
150 
151 void arch_mon_domain_online(struct rdt_resource *r, struct rdt_l3_mon_domain *d);
152 
153 /* CPUID.(EAX=10H, ECX=ResID=1).EAX */
154 union cpuid_0x10_1_eax {
155 	struct {
156 		unsigned int cbm_len:5;
157 	} split;
158 	unsigned int full;
159 };
160 
161 /* CPUID.(EAX=10H, ECX=ResID=3).EAX */
162 union cpuid_0x10_3_eax {
163 	struct {
164 		unsigned int max_delay:12;
165 	} split;
166 	unsigned int full;
167 };
168 
169 /* CPUID.(EAX=10H, ECX=ResID).ECX */
170 union cpuid_0x10_x_ecx {
171 	struct {
172 		unsigned int reserved:3;
173 		unsigned int noncont:1;
174 	} split;
175 	unsigned int full;
176 };
177 
178 /* CPUID.(EAX=10H, ECX=ResID).EDX */
179 union cpuid_0x10_x_edx {
180 	struct {
181 		unsigned int cos_max:16;
182 	} split;
183 	unsigned int full;
184 };
185 
186 /*
187  * ABMC counters are configured by writing to MSR_IA32_L3_QOS_ABMC_CFG.
188  *
189  * @bw_type		: Event configuration that represents the memory
190  *			  transactions being tracked by the @cntr_id.
191  * @bw_src		: Bandwidth source (RMID or CLOSID).
192  * @reserved1		: Reserved.
193  * @is_clos		: @bw_src field is a CLOSID (not an RMID).
194  * @cntr_id		: Counter identifier.
195  * @reserved		: Reserved.
196  * @cntr_en		: Counting enable bit.
197  * @cfg_en		: Configuration enable bit.
198  *
199  * Configuration and counting:
200  * Counter can be configured across multiple writes to MSR. Configuration
201  * is applied only when @cfg_en = 1. Counter @cntr_id is reset when the
202  * configuration is applied.
203  * @cfg_en = 1, @cntr_en = 0 : Apply @cntr_id configuration but do not
204  *                             count events.
205  * @cfg_en = 1, @cntr_en = 1 : Apply @cntr_id configuration and start
206  *                             counting events.
207  */
208 union l3_qos_abmc_cfg {
209 	struct {
210 		unsigned long bw_type  :32,
211 			      bw_src   :12,
212 			      reserved1: 3,
213 			      is_clos  : 1,
214 			      cntr_id  : 5,
215 			      reserved : 9,
216 			      cntr_en  : 1,
217 			      cfg_en   : 1;
218 	} split;
219 	unsigned long full;
220 };
221 
222 void rdt_ctrl_update(void *arg);
223 
224 int rdt_get_l3_mon_config(struct rdt_resource *r);
225 
226 bool rdt_cpu_has(int flag);
227 
228 void __init intel_rdt_mbm_apply_quirk(void);
229 
230 void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
231 void resctrl_arch_mbm_cntr_assign_set_one(struct rdt_resource *r);
232 
233 #ifdef CONFIG_X86_CPU_RESCTRL_INTEL_AET
234 bool intel_aet_get_events(void);
235 void __exit intel_aet_exit(void);
236 int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val);
237 void intel_aet_mon_domain_setup(int cpu, int id, struct rdt_resource *r,
238 				struct list_head *add_pos);
239 #else
240 static inline bool intel_aet_get_events(void) { return false; }
241 static inline void __exit intel_aet_exit(void) { }
242 static inline int intel_aet_read_event(int domid, u32 rmid, void *arch_priv, u64 *val)
243 {
244 	return -EINVAL;
245 }
246 
247 static inline void intel_aet_mon_domain_setup(int cpu, int id, struct rdt_resource *r,
248 					      struct list_head *add_pos) { }
249 #endif
250 
251 #endif /* _ASM_X86_RESCTRL_INTERNAL_H */
252