@@ -56,6 +56,15 @@ EXPORT_SYMBOL(plpar_hcall);
56
56
EXPORT_SYMBOL (plpar_hcall9 );
57
57
EXPORT_SYMBOL (plpar_hcall_norets );
58
58
59
+ /*
60
+ * H_BLOCK_REMOVE supported block size for this page size in segment who's base
61
+ * page size is that page size.
62
+ *
63
+ * The first index is the segment base page size, the second one is the actual
64
+ * page size.
65
+ */
66
+ static int hblkrm_size [MMU_PAGE_COUNT ][MMU_PAGE_COUNT ] __ro_after_init ;
67
+
59
68
#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE
60
69
static u8 dtl_mask = DTL_LOG_PREEMPT ;
61
70
#else
@@ -1311,6 +1320,137 @@ static void do_block_remove(unsigned long number, struct ppc64_tlb_batch *batch,
1311
1320
(void )call_block_remove (pix , param , true);
1312
1321
}
1313
1322
1323
+ /*
1324
+ * TLB Block Invalidate Characteristics
1325
+ *
1326
+ * These characteristics define the size of the block the hcall H_BLOCK_REMOVE
1327
+ * is able to process for each couple segment base page size, actual page size.
1328
+ *
1329
+ * The ibm,get-system-parameter properties is returning a buffer with the
1330
+ * following layout:
1331
+ *
1332
+ * [ 2 bytes size of the RTAS buffer (excluding these 2 bytes) ]
1333
+ * -----------------
1334
+ * TLB Block Invalidate Specifiers:
1335
+ * [ 1 byte LOG base 2 of the TLB invalidate block size being specified ]
1336
+ * [ 1 byte Number of page sizes (N) that are supported for the specified
1337
+ * TLB invalidate block size ]
1338
+ * [ 1 byte Encoded segment base page size and actual page size
1339
+ * MSB=0 means 4k segment base page size and actual page size
1340
+ * MSB=1 the penc value in mmu_psize_def ]
1341
+ * ...
1342
+ * -----------------
1343
+ * Next TLB Block Invalidate Specifiers...
1344
+ * -----------------
1345
+ * [ 0 ]
1346
+ */
1347
+ static inline void set_hblkrm_bloc_size (int bpsize , int psize ,
1348
+ unsigned int block_size )
1349
+ {
1350
+ if (block_size > hblkrm_size [bpsize ][psize ])
1351
+ hblkrm_size [bpsize ][psize ] = block_size ;
1352
+ }
1353
+
1354
+ /*
1355
+ * Decode the Encoded segment base page size and actual page size.
1356
+ * PAPR specifies:
1357
+ * - bit 7 is the L bit
1358
+ * - bits 0-5 are the penc value
1359
+ * If the L bit is 0, this means 4K segment base page size and actual page size
1360
+ * otherwise the penc value should be read.
1361
+ */
1362
+ #define HBLKRM_L_MASK 0x80
1363
+ #define HBLKRM_PENC_MASK 0x3f
1364
+ static inline void __init check_lp_set_hblkrm (unsigned int lp ,
1365
+ unsigned int block_size )
1366
+ {
1367
+ unsigned int bpsize , psize ;
1368
+
1369
+ /* First, check the L bit, if not set, this means 4K */
1370
+ if ((lp & HBLKRM_L_MASK ) == 0 ) {
1371
+ set_hblkrm_bloc_size (MMU_PAGE_4K , MMU_PAGE_4K , block_size );
1372
+ return ;
1373
+ }
1374
+
1375
+ lp &= HBLKRM_PENC_MASK ;
1376
+ for (bpsize = 0 ; bpsize < MMU_PAGE_COUNT ; bpsize ++ ) {
1377
+ struct mmu_psize_def * def = & mmu_psize_defs [bpsize ];
1378
+
1379
+ for (psize = 0 ; psize < MMU_PAGE_COUNT ; psize ++ ) {
1380
+ if (def -> penc [psize ] == lp ) {
1381
+ set_hblkrm_bloc_size (bpsize , psize , block_size );
1382
+ return ;
1383
+ }
1384
+ }
1385
+ }
1386
+ }
1387
+
1388
+ #define SPLPAR_TLB_BIC_TOKEN 50
1389
+
1390
+ /*
1391
+ * The size of the TLB Block Invalidate Characteristics is variable. But at the
1392
+ * maximum it will be the number of possible page sizes *2 + 10 bytes.
1393
+ * Currently MMU_PAGE_COUNT is 16, which means 42 bytes. Use a cache line size
1394
+ * (128 bytes) for the buffer to get plenty of space.
1395
+ */
1396
+ #define SPLPAR_TLB_BIC_MAXLENGTH 128
1397
+
1398
+ void __init pseries_lpar_read_hblkrm_characteristics (void )
1399
+ {
1400
+ unsigned char local_buffer [SPLPAR_TLB_BIC_MAXLENGTH ];
1401
+ int call_status , len , idx , bpsize ;
1402
+
1403
+ spin_lock (& rtas_data_buf_lock );
1404
+ memset (rtas_data_buf , 0 , RTAS_DATA_BUF_SIZE );
1405
+ call_status = rtas_call (rtas_token ("ibm,get-system-parameter" ), 3 , 1 ,
1406
+ NULL ,
1407
+ SPLPAR_TLB_BIC_TOKEN ,
1408
+ __pa (rtas_data_buf ),
1409
+ RTAS_DATA_BUF_SIZE );
1410
+ memcpy (local_buffer , rtas_data_buf , SPLPAR_TLB_BIC_MAXLENGTH );
1411
+ local_buffer [SPLPAR_TLB_BIC_MAXLENGTH - 1 ] = '\0' ;
1412
+ spin_unlock (& rtas_data_buf_lock );
1413
+
1414
+ if (call_status != 0 ) {
1415
+ pr_warn ("%s %s Error calling get-system-parameter (0x%x)\n" ,
1416
+ __FILE__ , __func__ , call_status );
1417
+ return ;
1418
+ }
1419
+
1420
+ /*
1421
+ * The first two (2) bytes of the data in the buffer are the length of
1422
+ * the returned data, not counting these first two (2) bytes.
1423
+ */
1424
+ len = be16_to_cpu (* ((u16 * )local_buffer )) + 2 ;
1425
+ if (len > SPLPAR_TLB_BIC_MAXLENGTH ) {
1426
+ pr_warn ("%s too large returned buffer %d" , __func__ , len );
1427
+ return ;
1428
+ }
1429
+
1430
+ idx = 2 ;
1431
+ while (idx < len ) {
1432
+ u8 block_shift = local_buffer [idx ++ ];
1433
+ u32 block_size ;
1434
+ unsigned int npsize ;
1435
+
1436
+ if (!block_shift )
1437
+ break ;
1438
+
1439
+ block_size = 1 << block_shift ;
1440
+
1441
+ for (npsize = local_buffer [idx ++ ];
1442
+ npsize > 0 && idx < len ; npsize -- )
1443
+ check_lp_set_hblkrm ((unsigned int ) local_buffer [idx ++ ],
1444
+ block_size );
1445
+ }
1446
+
1447
+ for (bpsize = 0 ; bpsize < MMU_PAGE_COUNT ; bpsize ++ )
1448
+ for (idx = 0 ; idx < MMU_PAGE_COUNT ; idx ++ )
1449
+ if (hblkrm_size [bpsize ][idx ])
1450
+ pr_info ("H_BLOCK_REMOVE supports base psize:%d psize:%d block size:%d" ,
1451
+ bpsize , idx , hblkrm_size [bpsize ][idx ]);
1452
+ }
1453
+
1314
1454
/*
1315
1455
* Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
1316
1456
* lock.
0 commit comments