12
12
#include <errno.h>
13
13
#include <logmsg.h>
14
14
#include <rdt.h>
15
+ #include <bits.h>
15
16
#include <board.h>
16
17
#include <vm_config.h>
17
18
#include <msr.h>
18
19
19
- struct cat_hw_info cat_cap_info = {false, 0U , 0U , 0U , 0U };
20
+ static struct rdt_info res_cap_info [RDT_NUM_RESOURCES ] = {
21
+ [RDT_RESOURCE_L3 ] = {
22
+ .bitmask = 0U ,
23
+ .cbm_len = 0U ,
24
+ .clos_max = 0U ,
25
+ .res_id = RDT_RESID_L3 ,
26
+ .msr_base = MSR_IA32_L3_MASK_BASE ,
27
+ .platform_clos_array = NULL
28
+ },
29
+ [RDT_RESOURCE_L2 ] = {
30
+ .bitmask = 0U ,
31
+ .cbm_len = 0U ,
32
+ .clos_max = 0U ,
33
+ .res_id = RDT_RESID_L2 ,
34
+ .msr_base = MSR_IA32_L2_MASK_BASE ,
35
+ .platform_clos_array = NULL
36
+ },
37
+ };
20
38
const uint16_t hv_clos = 0U ;
21
- uint16_t platform_clos_num = MAX_PLATFORM_CLOS_NUM ;
39
+ /* RDT features can support different numbers of CLOS. Set the lowers numerical
40
+ * clos value (platform_clos_num) that is common between the resources as
41
+ * each resource's clos max value to have consistent allocation.
42
+ */
43
+ const uint16_t platform_clos_num = MAX_PLATFORM_CLOS_NUM ;
44
+
45
+ static void rdt_read_cat_capability (int res )
46
+ {
47
+ uint32_t eax = 0U , ebx = 0U , ecx = 0U , edx = 0U ;
22
48
23
- int32_t init_cat_cap_info (void )
49
+ /* CPUID.(EAX=0x10,ECX=ResID):EAX[4:0] reports the length of CBM supported
50
+ * CPUID.(EAX=0x10,ECX=ResID):EBX[31:0] indicates shared cache mask bits
51
+ * that are used by other entities such as graphic and H/W outside processor.
52
+ * CPUID.(EAX=0x10,ECX=ResID):EDX[15:0] reports the maximun CLOS supported
53
+ */
54
+ cpuid_subleaf (CPUID_RDT_ALLOCATION , res_cap_info [res ].res_id , & eax , & ebx , & ecx , & edx );
55
+ res_cap_info [res ].cbm_len = (uint16_t )((eax & 0xfU ) + 1U );
56
+ res_cap_info [res ].bitmask = ebx ;
57
+ res_cap_info [res ].clos_max = (uint16_t )(edx & 0xffffU ) + 1 ;
58
+ }
59
+
60
+ int32_t init_rdt_cap_info (void )
24
61
{
62
+ uint8_t i ;
25
63
uint32_t eax = 0U , ebx = 0U , ecx = 0U , edx = 0U ;
26
64
int32_t ret = 0 ;
27
65
28
- if (pcpu_has_cap (X86_FEATURE_CAT )) {
29
- cpuid_subleaf (CPUID_RSD_ALLOCATION , 0 , & eax , & ebx , & ecx , & edx );
30
- /* If support L3 CAT, EBX[1] is set */
66
+ if (pcpu_has_cap (X86_FEATURE_RDT_A )) {
67
+ cpuid_subleaf (CPUID_RDT_ALLOCATION , 0 , & eax , & ebx , & ecx , & edx );
68
+
69
+ /* If HW supports L3 CAT, EBX[1] is set */
31
70
if ((ebx & 2U ) != 0U ) {
32
- cat_cap_info .enabled = true;
33
- cat_cap_info .res_id = CAT_RESID_L3 ;
71
+ rdt_read_cat_capability (RDT_RESOURCE_L3 );
34
72
}
35
73
36
- /* If support L2 CAT, EBX[2] is set */
74
+ /* If HW supports L2 CAT, EBX[2] is set */
37
75
if ((ebx & 4U ) != 0U ) {
38
- cat_cap_info .enabled = true;
39
- cat_cap_info .res_id = CAT_RESID_L2 ;
76
+ rdt_read_cat_capability (RDT_RESOURCE_L2 );
40
77
}
41
78
42
- /* CPUID.(EAX=0x10,ECX=ResID):EAX[4:0] reports the length of CBM supported
43
- * CPUID.(EAX=0x10,ECX=ResID):EBX[31:0] indicates the corresponding uints
44
- * may be used by other entities such as graphic and H/W outside processor.
45
- * CPUID.(EAX=0x10,ECX=ResID):EDX[15:0] reports the maximun CLOS supported
46
- */
47
- cpuid_subleaf (CPUID_RSD_ALLOCATION , cat_cap_info .res_id , & eax , & ebx , & ecx , & edx );
48
- cat_cap_info .cbm_len = (uint16_t )((eax & 0x1fU ) + 1U );
49
- cat_cap_info .bitmask = ebx ;
50
- cat_cap_info .clos_max = (uint16_t )(edx & 0xffffU );
51
-
52
- if ((platform_clos_num != 0U ) && ((cat_cap_info .clos_max + 1U ) != platform_clos_num )) {
53
- pr_err ("%s clos_max:%hu, platform_clos_num:%u\n" ,
54
- __func__ , cat_cap_info .clos_max , platform_clos_num );
55
- ret = - EINVAL ;
79
+ for (i = 0U ; i < RDT_NUM_RESOURCES ; i ++ ) {
80
+ /* If clos_max == 0, the resource is not supported
81
+ * so skip checking and updating the clos_max
82
+ */
83
+ if (res_cap_info [i ].clos_max > 0U ) {
84
+ if ((platform_clos_num == 0U ) || (res_cap_info [i ].clos_max < platform_clos_num )) {
85
+ pr_err ("Invalid Res_ID %d clos max:platform_clos_max=%d, res_clos_max=%d\n" ,
86
+ res_cap_info [i ].res_id , platform_clos_num , res_cap_info [i ].clos_max );
87
+ ret = - EINVAL ;
88
+ break ;
89
+ }
90
+ /*Store user configured platform clos mask and MSR in the rdt_info struct*/
91
+ if (res_cap_info [i ].res_id == RDT_RESID_L3 ) {
92
+ res_cap_info [i ].platform_clos_array = platform_l3_clos_array ;
93
+ } else if (res_cap_info [i ].res_id == RDT_RESID_L2 ) {
94
+ res_cap_info [i ].platform_clos_array = platform_l2_clos_array ;
95
+ } else {
96
+ res_cap_info [i ].platform_clos_array = NULL ;
97
+ }
98
+ }
56
99
}
57
100
}
58
-
59
101
return ret ;
60
102
}
61
103
62
- void setup_clos (uint16_t pcpu_id )
104
+ static bool setup_res_clos_msr (uint16_t pcpu_id , struct platform_clos_info * res_clos_info )
63
105
{
106
+ bool ret = true;
64
107
uint16_t i ;
65
108
uint32_t msr_index ;
66
109
uint64_t val ;
67
110
68
- if (cat_cap_info .enabled ) {
69
- for (i = 0 ; i < platform_clos_num ; i ++ ) {
70
- switch (cat_cap_info .res_id ) {
71
- case CAT_RESID_L2 :
72
- msr_index = platform_l2_clos_array [i ].msr_index ;
73
- val = (uint64_t )platform_l2_clos_array [i ].clos_mask ;
74
- msr_write_pcpu (msr_index , val , pcpu_id );
75
- break ;
76
- case CAT_RESID_L3 :
77
- msr_index = platform_l3_clos_array [i ].msr_index ;
78
- val = (uint64_t )platform_l3_clos_array [i ].clos_mask ;
79
- msr_write_pcpu (msr_index , val , pcpu_id );
111
+ for (i = 0 ; i < platform_clos_num ; i ++ ) {
112
+ if ((fls32 (res_clos_info -> clos_mask ) >= res_cap_info -> cbm_len ) ||
113
+ (res_clos_info -> msr_index != (res_cap_info -> msr_base + i ))) {
114
+ ret = false;
115
+ pr_err ("Incorrect CLOS %d Mask=0x%x and(/or) MSR index=0x%x for Res_ID %d in board.c" ,
116
+ i , res_clos_info -> clos_mask , res_clos_info -> msr_index , res_cap_info [i ].res_id );
117
+ break ;
118
+ }
119
+ msr_index = res_clos_info -> msr_index ;
120
+ val = (uint64_t )res_clos_info -> clos_mask ;
121
+ msr_write_pcpu (msr_index , val , pcpu_id );
122
+ res_clos_info ++ ;
123
+ }
124
+
125
+ return ret ;
126
+ }
127
+
128
+ bool setup_clos (uint16_t pcpu_id )
129
+ {
130
+ bool ret = true;
131
+ uint16_t i ;
132
+
133
+ for (i = 0U ; i < RDT_NUM_RESOURCES ; i ++ ) {
134
+ /* If clos_max == 0, the resource is not supported
135
+ * so skip setting up resource MSR.
136
+ */
137
+ if (res_cap_info [i ].clos_max > 0U ) {
138
+ ret = setup_res_clos_msr (pcpu_id , res_cap_info [i ].platform_clos_array );
139
+ if (!ret )
80
140
break ;
81
- default :
82
- pr_err ("Invalid RDT resource configuration\n" );
83
- }
84
141
}
85
- /* set hypervisor CAT clos */
142
+ }
143
+
144
+ if (ret ) {
145
+ /* set hypervisor RDT resource clos */
86
146
msr_write_pcpu (MSR_IA32_PQR_ASSOC , clos2pqr_msr (hv_clos ), pcpu_id );
87
147
}
148
+
149
+ return ret ;
88
150
}
89
151
90
152
uint64_t clos2pqr_msr (uint16_t clos )
@@ -99,5 +161,12 @@ uint64_t clos2pqr_msr(uint16_t clos)
99
161
100
162
bool is_platform_rdt_capable (void )
101
163
{
102
- return cat_cap_info .enabled ;
164
+ bool ret = false;
165
+
166
+ if ((res_cap_info [RDT_RESOURCE_L3 ].clos_max > 0U ) ||
167
+ (res_cap_info [RDT_RESOURCE_L2 ].clos_max > 0U )) {
168
+ ret = true;
169
+ }
170
+
171
+ return ret ;
103
172
}
0 commit comments