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 /**
41 * struct rdt_hw_ctrl_domain - Arch private attributes of a set of CPUs that share
42 * a resource for a control function
43 * @d_resctrl: Properties exposed to the resctrl file system
44 * @ctrl_val: array of cache or mem ctrl values (indexed by CLOSID)
45 *
46 * Members of this structure are accessed via helpers that provide abstraction.
47 */
48 struct rdt_hw_ctrl_domain {
49 struct rdt_ctrl_domain d_resctrl;
50 u32 *ctrl_val;
51 };
52
53 /**
54 * struct rdt_hw_mon_domain - Arch private attributes of a set of CPUs that share
55 * a resource for a monitor function
56 * @d_resctrl: Properties exposed to the resctrl file system
57 * @arch_mbm_total: arch private state for MBM total bandwidth
58 * @arch_mbm_local: arch private state for MBM local bandwidth
59 *
60 * Members of this structure are accessed via helpers that provide abstraction.
61 */
62 struct rdt_hw_mon_domain {
63 struct rdt_mon_domain d_resctrl;
64 struct arch_mbm_state *arch_mbm_total;
65 struct arch_mbm_state *arch_mbm_local;
66 };
67
resctrl_to_arch_ctrl_dom(struct rdt_ctrl_domain * r)68 static inline struct rdt_hw_ctrl_domain *resctrl_to_arch_ctrl_dom(struct rdt_ctrl_domain *r)
69 {
70 return container_of(r, struct rdt_hw_ctrl_domain, d_resctrl);
71 }
72
resctrl_to_arch_mon_dom(struct rdt_mon_domain * r)73 static inline struct rdt_hw_mon_domain *resctrl_to_arch_mon_dom(struct rdt_mon_domain *r)
74 {
75 return container_of(r, struct rdt_hw_mon_domain, d_resctrl);
76 }
77
78 /**
79 * struct msr_param - set a range of MSRs from a domain
80 * @res: The resource to use
81 * @dom: The domain to update
82 * @low: Beginning index from base MSR
83 * @high: End index
84 */
85 struct msr_param {
86 struct rdt_resource *res;
87 struct rdt_ctrl_domain *dom;
88 u32 low;
89 u32 high;
90 };
91
92 /**
93 * struct rdt_hw_resource - arch private attributes of a resctrl resource
94 * @r_resctrl: Attributes of the resource used directly by resctrl.
95 * @num_closid: Maximum number of closid this hardware can support,
96 * regardless of CDP. This is exposed via
97 * resctrl_arch_get_num_closid() to avoid confusion
98 * with struct resctrl_schema's property of the same name,
99 * which has been corrected for features like CDP.
100 * @msr_base: Base MSR address for CBMs
101 * @msr_update: Function pointer to update QOS MSRs
102 * @mon_scale: cqm counter * mon_scale = occupancy in bytes
103 * @mbm_width: Monitor width, to detect and correct for overflow.
104 * @cdp_enabled: CDP state of this resource
105 *
106 * Members of this structure are either private to the architecture
107 * e.g. mbm_width, or accessed via helpers that provide abstraction. e.g.
108 * msr_update and msr_base.
109 */
110 struct rdt_hw_resource {
111 struct rdt_resource r_resctrl;
112 u32 num_closid;
113 unsigned int msr_base;
114 void (*msr_update)(struct msr_param *m);
115 unsigned int mon_scale;
116 unsigned int mbm_width;
117 bool cdp_enabled;
118 };
119
resctrl_to_arch_res(struct rdt_resource * r)120 static inline struct rdt_hw_resource *resctrl_to_arch_res(struct rdt_resource *r)
121 {
122 return container_of(r, struct rdt_hw_resource, r_resctrl);
123 }
124
125 extern struct rdt_hw_resource rdt_resources_all[];
126
127 void arch_mon_domain_online(struct rdt_resource *r, struct rdt_mon_domain *d);
128
129 /* CPUID.(EAX=10H, ECX=ResID=1).EAX */
130 union cpuid_0x10_1_eax {
131 struct {
132 unsigned int cbm_len:5;
133 } split;
134 unsigned int full;
135 };
136
137 /* CPUID.(EAX=10H, ECX=ResID=3).EAX */
138 union cpuid_0x10_3_eax {
139 struct {
140 unsigned int max_delay:12;
141 } split;
142 unsigned int full;
143 };
144
145 /* CPUID.(EAX=10H, ECX=ResID).ECX */
146 union cpuid_0x10_x_ecx {
147 struct {
148 unsigned int reserved:3;
149 unsigned int noncont:1;
150 } split;
151 unsigned int full;
152 };
153
154 /* CPUID.(EAX=10H, ECX=ResID).EDX */
155 union cpuid_0x10_x_edx {
156 struct {
157 unsigned int cos_max:16;
158 } split;
159 unsigned int full;
160 };
161
162 void rdt_ctrl_update(void *arg);
163
164 int rdt_get_mon_l3_config(struct rdt_resource *r);
165
166 bool rdt_cpu_has(int flag);
167
168 void __init intel_rdt_mbm_apply_quirk(void);
169
170 void rdt_domain_reconfigure_cdp(struct rdt_resource *r);
171
172 #endif /* _ASM_X86_RESCTRL_INTERNAL_H */
173