Skip to content

Commit 08e1c01

Browse files
Anshuman Khandualmpe
authored andcommitted
powerpc/ptrace: Enable support for TM SPR state
This patch enables support for TM SPR state related ELF core note NT_PPC_TM_SPR based ptrace requests through PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved through adding a register set REGSET_TM_SPR in powerpc corresponding to the ELF core note section added. It implements the get, set and active functions for this new register set added. Signed-off-by: Anshuman Khandual <[email protected]> Signed-off-by: Simon Guo <[email protected]> Signed-off-by: Michael Ellerman <[email protected]>
1 parent 9d3918f commit 08e1c01

File tree

2 files changed

+143
-1
lines changed

2 files changed

+143
-1
lines changed

arch/powerpc/include/uapi/asm/elf.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@
9393
#define ELF_NFPREG 33 /* includes fpscr */
9494
#define ELF_NVMX 34 /* includes all vector registers */
9595
#define ELF_NVSX 32 /* includes all VSX registers */
96+
#define ELF_NTMSPRREG 3 /* include tfhar, tfiar, texasr */
9697

9798
typedef unsigned long elf_greg_t64;
9899
typedef elf_greg_t64 elf_gregset_t64[ELF_NGREG];

arch/powerpc/kernel/ptrace.c

Lines changed: 142 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ struct pt_regs_offset {
6666

6767
#define TVSO(f) (offsetof(struct thread_vr_state, f))
6868
#define TFSO(f) (offsetof(struct thread_fp_state, f))
69+
#define TSO(f) (offsetof(struct thread_struct, f))
6970

7071
static const struct pt_regs_offset regoffset_table[] = {
7172
GPR_OFFSET_NAME(0),
@@ -1412,7 +1413,136 @@ static int tm_cvsx_set(struct task_struct *target,
14121413

14131414
return ret;
14141415
}
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 */
14161546

14171547
/*
14181548
* These are our native regset flavors.
@@ -1434,6 +1564,7 @@ enum powerpc_regset {
14341564
REGSET_TM_CFPR, /* TM checkpointed FPR registers */
14351565
REGSET_TM_CVMX, /* TM checkpointed VMX registers */
14361566
REGSET_TM_CVSX, /* TM checkpointed VSX registers */
1567+
REGSET_TM_SPR, /* TM specific SPR registers */
14371568
#endif
14381569
};
14391570

@@ -1490,6 +1621,11 @@ static const struct user_regset native_regsets[] = {
14901621
.size = sizeof(double), .align = sizeof(double),
14911622
.active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set
14921623
},
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+
},
14931629
#endif
14941630
};
14951631

@@ -1737,6 +1873,11 @@ static const struct user_regset compat_regsets[] = {
17371873
.size = sizeof(double), .align = sizeof(double),
17381874
.active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set
17391875
},
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+
},
17401881
#endif
17411882
};
17421883

0 commit comments

Comments
 (0)