Skip to content

Commit 9d3918f

Browse files
Anshuman Khandualmpe
authored andcommitted
powerpc/ptrace: Enable support for NT_PPC_CVSX
This patch enables support for TM checkpointed VSX register set ELF core note NT_PPC_CVSX based ptrace requests through PTRACE_GETREGSET, PTRACE_SETREGSET calls. This is achieved through adding a register set REGSET_CVSX 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 8c13f59 commit 9d3918f

File tree

2 files changed

+130
-0
lines changed

2 files changed

+130
-0
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,7 @@
9292
#define ELF_NGREG 48 /* includes nip, msr, lr, etc. */
9393
#define ELF_NFPREG 33 /* includes fpscr */
9494
#define ELF_NVMX 34 /* includes all vector registers */
95+
#define ELF_NVSX 32 /* includes all VSX registers */
9596

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

arch/powerpc/kernel/ptrace.c

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ struct pt_regs_offset {
6565
#define REG_OFFSET_END {.name = NULL, .offset = 0}
6666

6767
#define TVSO(f) (offsetof(struct thread_vr_state, f))
68+
#define TFSO(f) (offsetof(struct thread_fp_state, f))
6869

6970
static const struct pt_regs_offset regoffset_table[] = {
7071
GPR_OFFSET_NAME(0),
@@ -1294,6 +1295,123 @@ static int tm_cvmx_set(struct task_struct *target,
12941295

12951296
return ret;
12961297
}
1298+
1299+
/**
1300+
* tm_cvsx_active - get active number of registers in CVSX
1301+
* @target: The target task.
1302+
* @regset: The user regset structure.
1303+
*
1304+
* This function checks for the active number of available
1305+
* regisers in transaction checkpointed VSX category.
1306+
*/
1307+
static int tm_cvsx_active(struct task_struct *target,
1308+
const struct user_regset *regset)
1309+
{
1310+
if (!cpu_has_feature(CPU_FTR_TM))
1311+
return -ENODEV;
1312+
1313+
if (!MSR_TM_ACTIVE(target->thread.regs->msr))
1314+
return 0;
1315+
1316+
flush_vsx_to_thread(target);
1317+
return target->thread.used_vsr ? regset->n : 0;
1318+
}
1319+
1320+
/**
1321+
* tm_cvsx_get - get CVSX registers
1322+
* @target: The target task.
1323+
* @regset: The user regset structure.
1324+
* @pos: The buffer position.
1325+
* @count: Number of bytes to copy.
1326+
* @kbuf: Kernel buffer to copy from.
1327+
* @ubuf: User buffer to copy into.
1328+
*
1329+
* This function gets in transaction checkpointed VSX registers.
1330+
*
1331+
* When the transaction is active 'fp_state' holds the checkpointed
1332+
* values for the current transaction to fall back on if it aborts
1333+
* in between. This function gets those checkpointed VSX registers.
1334+
* The userspace interface buffer layout is as follows.
1335+
*
1336+
* struct data {
1337+
* u64 vsx[32];
1338+
*};
1339+
*/
1340+
static int tm_cvsx_get(struct task_struct *target,
1341+
const struct user_regset *regset,
1342+
unsigned int pos, unsigned int count,
1343+
void *kbuf, void __user *ubuf)
1344+
{
1345+
u64 buf[32];
1346+
int ret, i;
1347+
1348+
if (!cpu_has_feature(CPU_FTR_TM))
1349+
return -ENODEV;
1350+
1351+
if (!MSR_TM_ACTIVE(target->thread.regs->msr))
1352+
return -ENODATA;
1353+
1354+
/* Flush the state */
1355+
flush_fp_to_thread(target);
1356+
flush_altivec_to_thread(target);
1357+
flush_tmregs_to_thread(target);
1358+
flush_vsx_to_thread(target);
1359+
1360+
for (i = 0; i < 32 ; i++)
1361+
buf[i] = target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET];
1362+
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
1363+
buf, 0, 32 * sizeof(double));
1364+
1365+
return ret;
1366+
}
1367+
1368+
/**
1369+
* tm_cvsx_set - set CFPR registers
1370+
* @target: The target task.
1371+
* @regset: The user regset structure.
1372+
* @pos: The buffer position.
1373+
* @count: Number of bytes to copy.
1374+
* @kbuf: Kernel buffer to copy into.
1375+
* @ubuf: User buffer to copy from.
1376+
*
1377+
* This function sets in transaction checkpointed VSX registers.
1378+
*
1379+
* When the transaction is active 'fp_state' holds the checkpointed
1380+
* VSX register values for the current transaction to fall back on
1381+
* if it aborts in between. This function sets these checkpointed
1382+
* FPR registers. The userspace interface buffer layout is as follows.
1383+
*
1384+
* struct data {
1385+
* u64 vsx[32];
1386+
*};
1387+
*/
1388+
static int tm_cvsx_set(struct task_struct *target,
1389+
const struct user_regset *regset,
1390+
unsigned int pos, unsigned int count,
1391+
const void *kbuf, const void __user *ubuf)
1392+
{
1393+
u64 buf[32];
1394+
int ret, i;
1395+
1396+
if (!cpu_has_feature(CPU_FTR_TM))
1397+
return -ENODEV;
1398+
1399+
if (!MSR_TM_ACTIVE(target->thread.regs->msr))
1400+
return -ENODATA;
1401+
1402+
/* Flush the state */
1403+
flush_fp_to_thread(target);
1404+
flush_altivec_to_thread(target);
1405+
flush_tmregs_to_thread(target);
1406+
flush_vsx_to_thread(target);
1407+
1408+
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
1409+
buf, 0, 32 * sizeof(double));
1410+
for (i = 0; i < 32 ; i++)
1411+
target->thread.fp_state.fpr[i][TS_VSRLOWOFFSET] = buf[i];
1412+
1413+
return ret;
1414+
}
12971415
#endif
12981416

12991417
/*
@@ -1315,6 +1433,7 @@ enum powerpc_regset {
13151433
REGSET_TM_CGPR, /* TM checkpointed GPR registers */
13161434
REGSET_TM_CFPR, /* TM checkpointed FPR registers */
13171435
REGSET_TM_CVMX, /* TM checkpointed VMX registers */
1436+
REGSET_TM_CVSX, /* TM checkpointed VSX registers */
13181437
#endif
13191438
};
13201439

@@ -1366,6 +1485,11 @@ static const struct user_regset native_regsets[] = {
13661485
.size = sizeof(vector128), .align = sizeof(vector128),
13671486
.active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
13681487
},
1488+
[REGSET_TM_CVSX] = {
1489+
.core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX,
1490+
.size = sizeof(double), .align = sizeof(double),
1491+
.active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set
1492+
},
13691493
#endif
13701494
};
13711495

@@ -1608,6 +1732,11 @@ static const struct user_regset compat_regsets[] = {
16081732
.size = sizeof(vector128), .align = sizeof(vector128),
16091733
.active = tm_cvmx_active, .get = tm_cvmx_get, .set = tm_cvmx_set
16101734
},
1735+
[REGSET_TM_CVSX] = {
1736+
.core_note_type = NT_PPC_TM_CVSX, .n = ELF_NVSX,
1737+
.size = sizeof(double), .align = sizeof(double),
1738+
.active = tm_cvsx_active, .get = tm_cvsx_get, .set = tm_cvsx_set
1739+
},
16111740
#endif
16121741
};
16131742

0 commit comments

Comments
 (0)