@@ -66,6 +66,7 @@ struct pt_regs_offset {
66
66
67
67
#define TVSO (f ) (offsetof(struct thread_vr_state, f))
68
68
#define TFSO (f ) (offsetof(struct thread_fp_state, f))
69
+ #define TSO (f ) (offsetof(struct thread_struct, f))
69
70
70
71
static const struct pt_regs_offset regoffset_table [] = {
71
72
GPR_OFFSET_NAME (0 ),
@@ -1412,7 +1413,136 @@ static int tm_cvsx_set(struct task_struct *target,
1412
1413
1413
1414
return ret ;
1414
1415
}
1415
- #endif
1416
+
1417
+ /**
1418
+ * tm_spr_active - get active number of registers in TM SPR
1419
+ * @target: The target task.
1420
+ * @regset: The user regset structure.
1421
+ *
1422
+ * This function checks the active number of available
1423
+ * regisers in the transactional memory SPR category.
1424
+ */
1425
+ static int tm_spr_active (struct task_struct * target ,
1426
+ const struct user_regset * regset )
1427
+ {
1428
+ if (!cpu_has_feature (CPU_FTR_TM ))
1429
+ return - ENODEV ;
1430
+
1431
+ return regset -> n ;
1432
+ }
1433
+
1434
+ /**
1435
+ * tm_spr_get - get the TM related SPR registers
1436
+ * @target: The target task.
1437
+ * @regset: The user regset structure.
1438
+ * @pos: The buffer position.
1439
+ * @count: Number of bytes to copy.
1440
+ * @kbuf: Kernel buffer to copy from.
1441
+ * @ubuf: User buffer to copy into.
1442
+ *
1443
+ * This function gets transactional memory related SPR registers.
1444
+ * The userspace interface buffer layout is as follows.
1445
+ *
1446
+ * struct {
1447
+ * u64 tm_tfhar;
1448
+ * u64 tm_texasr;
1449
+ * u64 tm_tfiar;
1450
+ * };
1451
+ */
1452
+ static int tm_spr_get (struct task_struct * target ,
1453
+ const struct user_regset * regset ,
1454
+ unsigned int pos , unsigned int count ,
1455
+ void * kbuf , void __user * ubuf )
1456
+ {
1457
+ int ret ;
1458
+
1459
+ /* Build tests */
1460
+ BUILD_BUG_ON (TSO (tm_tfhar ) + sizeof (u64 ) != TSO (tm_texasr ));
1461
+ BUILD_BUG_ON (TSO (tm_texasr ) + sizeof (u64 ) != TSO (tm_tfiar ));
1462
+ BUILD_BUG_ON (TSO (tm_tfiar ) + sizeof (u64 ) != TSO (ckpt_regs ));
1463
+
1464
+ if (!cpu_has_feature (CPU_FTR_TM ))
1465
+ return - ENODEV ;
1466
+
1467
+ /* Flush the states */
1468
+ flush_fp_to_thread (target );
1469
+ flush_altivec_to_thread (target );
1470
+ flush_tmregs_to_thread (target );
1471
+
1472
+ /* TFHAR register */
1473
+ ret = user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
1474
+ & target -> thread .tm_tfhar , 0 , sizeof (u64 ));
1475
+
1476
+ /* TEXASR register */
1477
+ if (!ret )
1478
+ ret = user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
1479
+ & target -> thread .tm_texasr , sizeof (u64 ),
1480
+ 2 * sizeof (u64 ));
1481
+
1482
+ /* TFIAR register */
1483
+ if (!ret )
1484
+ ret = user_regset_copyout (& pos , & count , & kbuf , & ubuf ,
1485
+ & target -> thread .tm_tfiar ,
1486
+ 2 * sizeof (u64 ), 3 * sizeof (u64 ));
1487
+ return ret ;
1488
+ }
1489
+
1490
+ /**
1491
+ * tm_spr_set - set the TM related SPR registers
1492
+ * @target: The target task.
1493
+ * @regset: The user regset structure.
1494
+ * @pos: The buffer position.
1495
+ * @count: Number of bytes to copy.
1496
+ * @kbuf: Kernel buffer to copy into.
1497
+ * @ubuf: User buffer to copy from.
1498
+ *
1499
+ * This function sets transactional memory related SPR registers.
1500
+ * The userspace interface buffer layout is as follows.
1501
+ *
1502
+ * struct {
1503
+ * u64 tm_tfhar;
1504
+ * u64 tm_texasr;
1505
+ * u64 tm_tfiar;
1506
+ * };
1507
+ */
1508
+ static int tm_spr_set (struct task_struct * target ,
1509
+ const struct user_regset * regset ,
1510
+ unsigned int pos , unsigned int count ,
1511
+ const void * kbuf , const void __user * ubuf )
1512
+ {
1513
+ int ret ;
1514
+
1515
+ /* Build tests */
1516
+ BUILD_BUG_ON (TSO (tm_tfhar ) + sizeof (u64 ) != TSO (tm_texasr ));
1517
+ BUILD_BUG_ON (TSO (tm_texasr ) + sizeof (u64 ) != TSO (tm_tfiar ));
1518
+ BUILD_BUG_ON (TSO (tm_tfiar ) + sizeof (u64 ) != TSO (ckpt_regs ));
1519
+
1520
+ if (!cpu_has_feature (CPU_FTR_TM ))
1521
+ return - ENODEV ;
1522
+
1523
+ /* Flush the states */
1524
+ flush_fp_to_thread (target );
1525
+ flush_altivec_to_thread (target );
1526
+ flush_tmregs_to_thread (target );
1527
+
1528
+ /* TFHAR register */
1529
+ ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
1530
+ & target -> thread .tm_tfhar , 0 , sizeof (u64 ));
1531
+
1532
+ /* TEXASR register */
1533
+ if (!ret )
1534
+ ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
1535
+ & target -> thread .tm_texasr , sizeof (u64 ),
1536
+ 2 * sizeof (u64 ));
1537
+
1538
+ /* TFIAR register */
1539
+ if (!ret )
1540
+ ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf ,
1541
+ & target -> thread .tm_tfiar ,
1542
+ 2 * sizeof (u64 ), 3 * sizeof (u64 ));
1543
+ return ret ;
1544
+ }
1545
+ #endif /* CONFIG_PPC_TRANSACTIONAL_MEM */
1416
1546
1417
1547
/*
1418
1548
* These are our native regset flavors.
@@ -1434,6 +1564,7 @@ enum powerpc_regset {
1434
1564
REGSET_TM_CFPR , /* TM checkpointed FPR registers */
1435
1565
REGSET_TM_CVMX , /* TM checkpointed VMX registers */
1436
1566
REGSET_TM_CVSX , /* TM checkpointed VSX registers */
1567
+ REGSET_TM_SPR , /* TM specific SPR registers */
1437
1568
#endif
1438
1569
};
1439
1570
@@ -1490,6 +1621,11 @@ static const struct user_regset native_regsets[] = {
1490
1621
.size = sizeof (double ), .align = sizeof (double ),
1491
1622
.active = tm_cvsx_active , .get = tm_cvsx_get , .set = tm_cvsx_set
1492
1623
},
1624
+ [REGSET_TM_SPR ] = {
1625
+ .core_note_type = NT_PPC_TM_SPR , .n = ELF_NTMSPRREG ,
1626
+ .size = sizeof (u64 ), .align = sizeof (u64 ),
1627
+ .active = tm_spr_active , .get = tm_spr_get , .set = tm_spr_set
1628
+ },
1493
1629
#endif
1494
1630
};
1495
1631
@@ -1737,6 +1873,11 @@ static const struct user_regset compat_regsets[] = {
1737
1873
.size = sizeof (double ), .align = sizeof (double ),
1738
1874
.active = tm_cvsx_active , .get = tm_cvsx_get , .set = tm_cvsx_set
1739
1875
},
1876
+ [REGSET_TM_SPR ] = {
1877
+ .core_note_type = NT_PPC_TM_SPR , .n = ELF_NTMSPRREG ,
1878
+ .size = sizeof (u64 ), .align = sizeof (u64 ),
1879
+ .active = tm_spr_active , .get = tm_spr_get , .set = tm_spr_set
1880
+ },
1740
1881
#endif
1741
1882
};
1742
1883
0 commit comments