@@ -2036,18 +2036,17 @@ static void its_write_baser(struct its_node *its, struct its_baser *baser,
2036
2036
}
2037
2037
2038
2038
static int its_setup_baser (struct its_node * its , struct its_baser * baser ,
2039
- u64 cache , u64 shr , u32 psz , u32 order ,
2040
- bool indirect )
2039
+ u64 cache , u64 shr , u32 order , bool indirect )
2041
2040
{
2042
2041
u64 val = its_read_baser (its , baser );
2043
2042
u64 esz = GITS_BASER_ENTRY_SIZE (val );
2044
2043
u64 type = GITS_BASER_TYPE (val );
2045
2044
u64 baser_phys , tmp ;
2046
- u32 alloc_pages ;
2045
+ u32 alloc_pages , psz ;
2047
2046
struct page * page ;
2048
2047
void * base ;
2049
2048
2050
- retry_alloc_baser :
2049
+ psz = baser -> psz ;
2051
2050
alloc_pages = (PAGE_ORDER_TO_SIZE (order ) / psz );
2052
2051
if (alloc_pages > GITS_BASER_PAGES_MAX ) {
2053
2052
pr_warn ("ITS@%pa: %s too large, reduce ITS pages %u->%u\n" ,
@@ -2120,25 +2119,6 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
2120
2119
goto retry_baser ;
2121
2120
}
2122
2121
2123
- if ((val ^ tmp ) & GITS_BASER_PAGE_SIZE_MASK ) {
2124
- /*
2125
- * Page size didn't stick. Let's try a smaller
2126
- * size and retry. If we reach 4K, then
2127
- * something is horribly wrong...
2128
- */
2129
- free_pages ((unsigned long )base , order );
2130
- baser -> base = NULL ;
2131
-
2132
- switch (psz ) {
2133
- case SZ_16K :
2134
- psz = SZ_4K ;
2135
- goto retry_alloc_baser ;
2136
- case SZ_64K :
2137
- psz = SZ_16K ;
2138
- goto retry_alloc_baser ;
2139
- }
2140
- }
2141
-
2142
2122
if (val != tmp ) {
2143
2123
pr_err ("ITS@%pa: %s doesn't stick: %llx %llx\n" ,
2144
2124
& its -> phys_base , its_base_type_string [type ],
@@ -2164,13 +2144,14 @@ static int its_setup_baser(struct its_node *its, struct its_baser *baser,
2164
2144
2165
2145
static bool its_parse_indirect_baser (struct its_node * its ,
2166
2146
struct its_baser * baser ,
2167
- u32 psz , u32 * order , u32 ids )
2147
+ u32 * order , u32 ids )
2168
2148
{
2169
2149
u64 tmp = its_read_baser (its , baser );
2170
2150
u64 type = GITS_BASER_TYPE (tmp );
2171
2151
u64 esz = GITS_BASER_ENTRY_SIZE (tmp );
2172
2152
u64 val = GITS_BASER_InnerShareable | GITS_BASER_RaWaWb ;
2173
2153
u32 new_order = * order ;
2154
+ u32 psz = baser -> psz ;
2174
2155
bool indirect = false;
2175
2156
2176
2157
/* No need to enable Indirection if memory requirement < (psz*2)bytes */
@@ -2288,11 +2269,58 @@ static void its_free_tables(struct its_node *its)
2288
2269
}
2289
2270
}
2290
2271
2272
+ static int its_probe_baser_psz (struct its_node * its , struct its_baser * baser )
2273
+ {
2274
+ u64 psz = SZ_64K ;
2275
+
2276
+ while (psz ) {
2277
+ u64 val , gpsz ;
2278
+
2279
+ val = its_read_baser (its , baser );
2280
+ val &= ~GITS_BASER_PAGE_SIZE_MASK ;
2281
+
2282
+ switch (psz ) {
2283
+ case SZ_64K :
2284
+ gpsz = GITS_BASER_PAGE_SIZE_64K ;
2285
+ break ;
2286
+ case SZ_16K :
2287
+ gpsz = GITS_BASER_PAGE_SIZE_16K ;
2288
+ break ;
2289
+ case SZ_4K :
2290
+ default :
2291
+ gpsz = GITS_BASER_PAGE_SIZE_4K ;
2292
+ break ;
2293
+ }
2294
+
2295
+ gpsz >>= GITS_BASER_PAGE_SIZE_SHIFT ;
2296
+
2297
+ val |= FIELD_PREP (GITS_BASER_PAGE_SIZE_MASK , gpsz );
2298
+ its_write_baser (its , baser , val );
2299
+
2300
+ if (FIELD_GET (GITS_BASER_PAGE_SIZE_MASK , baser -> val ) == gpsz )
2301
+ break ;
2302
+
2303
+ switch (psz ) {
2304
+ case SZ_64K :
2305
+ psz = SZ_16K ;
2306
+ break ;
2307
+ case SZ_16K :
2308
+ psz = SZ_4K ;
2309
+ break ;
2310
+ case SZ_4K :
2311
+ default :
2312
+ return -1 ;
2313
+ }
2314
+ }
2315
+
2316
+ baser -> psz = psz ;
2317
+ return 0 ;
2318
+ }
2319
+
2291
2320
static int its_alloc_tables (struct its_node * its )
2292
2321
{
2293
2322
u64 shr = GITS_BASER_InnerShareable ;
2294
2323
u64 cache = GITS_BASER_RaWaWb ;
2295
- u32 psz = SZ_64K ;
2296
2324
int err , i ;
2297
2325
2298
2326
if (its -> flags & ITS_FLAGS_WORKAROUND_CAVIUM_22375 )
@@ -2303,16 +2331,22 @@ static int its_alloc_tables(struct its_node *its)
2303
2331
struct its_baser * baser = its -> tables + i ;
2304
2332
u64 val = its_read_baser (its , baser );
2305
2333
u64 type = GITS_BASER_TYPE (val );
2306
- u32 order = get_order (psz );
2307
2334
bool indirect = false;
2335
+ u32 order ;
2308
2336
2309
- switch (type ) {
2310
- case GITS_BASER_TYPE_NONE :
2337
+ if (type == GITS_BASER_TYPE_NONE )
2311
2338
continue ;
2312
2339
2340
+ if (its_probe_baser_psz (its , baser )) {
2341
+ its_free_tables (its );
2342
+ return - ENXIO ;
2343
+ }
2344
+
2345
+ order = get_order (baser -> psz );
2346
+
2347
+ switch (type ) {
2313
2348
case GITS_BASER_TYPE_DEVICE :
2314
- indirect = its_parse_indirect_baser (its , baser ,
2315
- psz , & order ,
2349
+ indirect = its_parse_indirect_baser (its , baser , & order ,
2316
2350
device_ids (its ));
2317
2351
break ;
2318
2352
@@ -2328,20 +2362,18 @@ static int its_alloc_tables(struct its_node *its)
2328
2362
}
2329
2363
}
2330
2364
2331
- indirect = its_parse_indirect_baser (its , baser ,
2332
- psz , & order ,
2365
+ indirect = its_parse_indirect_baser (its , baser , & order ,
2333
2366
ITS_MAX_VPEID_BITS );
2334
2367
break ;
2335
2368
}
2336
2369
2337
- err = its_setup_baser (its , baser , cache , shr , psz , order , indirect );
2370
+ err = its_setup_baser (its , baser , cache , shr , order , indirect );
2338
2371
if (err < 0 ) {
2339
2372
its_free_tables (its );
2340
2373
return err ;
2341
2374
}
2342
2375
2343
2376
/* Update settings which will be used for next BASERn */
2344
- psz = baser -> psz ;
2345
2377
cache = baser -> val & GITS_BASER_CACHEABILITY_MASK ;
2346
2378
shr = baser -> val & GITS_BASER_SHAREABILITY_MASK ;
2347
2379
}
0 commit comments