Skip to content

Commit 1b20773

Browse files
chleroympe
authored andcommitted
powerpc/ptrace: split out ALTIVEC related functions.
Move CONFIG_ALTIVEC functions out of ptrace.c, into ptrace-altivec.c Signed-off-by: Christophe Leroy <[email protected]> Signed-off-by: Michael Ellerman <[email protected]> Link: https://lore.kernel.org/r/35dae891d01c817fca0fd6ab406a3a2c7bf07f60.1582848567.git.christophe.leroy@c-s.fr
1 parent 7b99ed4 commit 1b20773

File tree

4 files changed

+138
-124
lines changed

4 files changed

+138
-124
lines changed

arch/powerpc/kernel/ptrace/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,4 @@ obj-$(CONFIG_VSX) += ptrace-vsx.o
1111
ifneq ($(CONFIG_VSX),y)
1212
obj-y += ptrace-novsx.o
1313
endif
14+
obj-$(CONFIG_ALTIVEC) += ptrace-altivec.o
Lines changed: 128 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
3+
#include <linux/regset.h>
4+
#include <linux/elf.h>
5+
6+
#include <asm/switch_to.h>
7+
8+
#include "ptrace-decl.h"
9+
10+
/*
11+
* Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
12+
* The transfer totals 34 quadword. Quadwords 0-31 contain the
13+
* corresponding vector registers. Quadword 32 contains the vscr as the
14+
* last word (offset 12) within that quadword. Quadword 33 contains the
15+
* vrsave as the first word (offset 0) within the quadword.
16+
*
17+
* This definition of the VMX state is compatible with the current PPC32
18+
* ptrace interface. This allows signal handling and ptrace to use the
19+
* same structures. This also simplifies the implementation of a bi-arch
20+
* (combined (32- and 64-bit) gdb.
21+
*/
22+
23+
int vr_active(struct task_struct *target, const struct user_regset *regset)
24+
{
25+
flush_altivec_to_thread(target);
26+
return target->thread.used_vr ? regset->n : 0;
27+
}
28+
29+
/*
30+
* Regardless of transactions, 'vr_state' holds the current running
31+
* value of all the VMX registers and 'ckvr_state' holds the last
32+
* checkpointed value of all the VMX registers for the current
33+
* transaction to fall back on in case it aborts.
34+
*
35+
* Userspace interface buffer layout:
36+
*
37+
* struct data {
38+
* vector128 vr[32];
39+
* vector128 vscr;
40+
* vector128 vrsave;
41+
* };
42+
*/
43+
int vr_get(struct task_struct *target, const struct user_regset *regset,
44+
unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf)
45+
{
46+
int ret;
47+
48+
flush_altivec_to_thread(target);
49+
50+
BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
51+
offsetof(struct thread_vr_state, vr[32]));
52+
53+
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
54+
&target->thread.vr_state, 0,
55+
33 * sizeof(vector128));
56+
if (!ret) {
57+
/*
58+
* Copy out only the low-order word of vrsave.
59+
*/
60+
int start, end;
61+
union {
62+
elf_vrreg_t reg;
63+
u32 word;
64+
} vrsave;
65+
memset(&vrsave, 0, sizeof(vrsave));
66+
67+
vrsave.word = target->thread.vrsave;
68+
69+
start = 33 * sizeof(vector128);
70+
end = start + sizeof(vrsave);
71+
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
72+
start, end);
73+
}
74+
75+
return ret;
76+
}
77+
78+
/*
79+
* Regardless of transactions, 'vr_state' holds the current running
80+
* value of all the VMX registers and 'ckvr_state' holds the last
81+
* checkpointed value of all the VMX registers for the current
82+
* transaction to fall back on in case it aborts.
83+
*
84+
* Userspace interface buffer layout:
85+
*
86+
* struct data {
87+
* vector128 vr[32];
88+
* vector128 vscr;
89+
* vector128 vrsave;
90+
* };
91+
*/
92+
int vr_set(struct task_struct *target, const struct user_regset *regset,
93+
unsigned int pos, unsigned int count,
94+
const void *kbuf, const void __user *ubuf)
95+
{
96+
int ret;
97+
98+
flush_altivec_to_thread(target);
99+
100+
BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
101+
offsetof(struct thread_vr_state, vr[32]));
102+
103+
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
104+
&target->thread.vr_state, 0,
105+
33 * sizeof(vector128));
106+
if (!ret && count > 0) {
107+
/*
108+
* We use only the first word of vrsave.
109+
*/
110+
int start, end;
111+
union {
112+
elf_vrreg_t reg;
113+
u32 word;
114+
} vrsave;
115+
memset(&vrsave, 0, sizeof(vrsave));
116+
117+
vrsave.word = target->thread.vrsave;
118+
119+
start = 33 * sizeof(vector128);
120+
end = start + sizeof(vrsave);
121+
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
122+
start, end);
123+
if (!ret)
124+
target->thread.vrsave = vrsave.word;
125+
}
126+
127+
return ret;
128+
}

arch/powerpc/kernel/ptrace/ptrace-decl.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,15 @@ int vsr_set(struct task_struct *target, const struct user_regset *regset,
1717
unsigned int pos, unsigned int count,
1818
const void *kbuf, const void __user *ubuf);
1919

20+
/* ptrace-altivec */
21+
22+
int vr_active(struct task_struct *target, const struct user_regset *regset);
23+
int vr_get(struct task_struct *target, const struct user_regset *regset,
24+
unsigned int pos, unsigned int count, void *kbuf, void __user *ubuf);
25+
int vr_set(struct task_struct *target, const struct user_regset *regset,
26+
unsigned int pos, unsigned int count,
27+
const void *kbuf, const void __user *ubuf);
28+
2029
/* ptrace */
2130

2231
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM

arch/powerpc/kernel/ptrace/ptrace.c

Lines changed: 0 additions & 124 deletions
Original file line numberDiff line numberDiff line change
@@ -403,130 +403,6 @@ static int gpr_set(struct task_struct *target, const struct user_regset *regset,
403403
return ret;
404404
}
405405

406-
#ifdef CONFIG_ALTIVEC
407-
/*
408-
* Get/set all the altivec registers vr0..vr31, vscr, vrsave, in one go.
409-
* The transfer totals 34 quadword. Quadwords 0-31 contain the
410-
* corresponding vector registers. Quadword 32 contains the vscr as the
411-
* last word (offset 12) within that quadword. Quadword 33 contains the
412-
* vrsave as the first word (offset 0) within the quadword.
413-
*
414-
* This definition of the VMX state is compatible with the current PPC32
415-
* ptrace interface. This allows signal handling and ptrace to use the
416-
* same structures. This also simplifies the implementation of a bi-arch
417-
* (combined (32- and 64-bit) gdb.
418-
*/
419-
420-
static int vr_active(struct task_struct *target,
421-
const struct user_regset *regset)
422-
{
423-
flush_altivec_to_thread(target);
424-
return target->thread.used_vr ? regset->n : 0;
425-
}
426-
427-
/*
428-
* Regardless of transactions, 'vr_state' holds the current running
429-
* value of all the VMX registers and 'ckvr_state' holds the last
430-
* checkpointed value of all the VMX registers for the current
431-
* transaction to fall back on in case it aborts.
432-
*
433-
* Userspace interface buffer layout:
434-
*
435-
* struct data {
436-
* vector128 vr[32];
437-
* vector128 vscr;
438-
* vector128 vrsave;
439-
* };
440-
*/
441-
static int vr_get(struct task_struct *target, const struct user_regset *regset,
442-
unsigned int pos, unsigned int count,
443-
void *kbuf, void __user *ubuf)
444-
{
445-
int ret;
446-
447-
flush_altivec_to_thread(target);
448-
449-
BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
450-
offsetof(struct thread_vr_state, vr[32]));
451-
452-
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf,
453-
&target->thread.vr_state, 0,
454-
33 * sizeof(vector128));
455-
if (!ret) {
456-
/*
457-
* Copy out only the low-order word of vrsave.
458-
*/
459-
int start, end;
460-
union {
461-
elf_vrreg_t reg;
462-
u32 word;
463-
} vrsave;
464-
memset(&vrsave, 0, sizeof(vrsave));
465-
466-
vrsave.word = target->thread.vrsave;
467-
468-
start = 33 * sizeof(vector128);
469-
end = start + sizeof(vrsave);
470-
ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, &vrsave,
471-
start, end);
472-
}
473-
474-
return ret;
475-
}
476-
477-
/*
478-
* Regardless of transactions, 'vr_state' holds the current running
479-
* value of all the VMX registers and 'ckvr_state' holds the last
480-
* checkpointed value of all the VMX registers for the current
481-
* transaction to fall back on in case it aborts.
482-
*
483-
* Userspace interface buffer layout:
484-
*
485-
* struct data {
486-
* vector128 vr[32];
487-
* vector128 vscr;
488-
* vector128 vrsave;
489-
* };
490-
*/
491-
static int vr_set(struct task_struct *target, const struct user_regset *regset,
492-
unsigned int pos, unsigned int count,
493-
const void *kbuf, const void __user *ubuf)
494-
{
495-
int ret;
496-
497-
flush_altivec_to_thread(target);
498-
499-
BUILD_BUG_ON(offsetof(struct thread_vr_state, vscr) !=
500-
offsetof(struct thread_vr_state, vr[32]));
501-
502-
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf,
503-
&target->thread.vr_state, 0,
504-
33 * sizeof(vector128));
505-
if (!ret && count > 0) {
506-
/*
507-
* We use only the first word of vrsave.
508-
*/
509-
int start, end;
510-
union {
511-
elf_vrreg_t reg;
512-
u32 word;
513-
} vrsave;
514-
memset(&vrsave, 0, sizeof(vrsave));
515-
516-
vrsave.word = target->thread.vrsave;
517-
518-
start = 33 * sizeof(vector128);
519-
end = start + sizeof(vrsave);
520-
ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &vrsave,
521-
start, end);
522-
if (!ret)
523-
target->thread.vrsave = vrsave.word;
524-
}
525-
526-
return ret;
527-
}
528-
#endif /* CONFIG_ALTIVEC */
529-
530406
#ifdef CONFIG_SPE
531407

532408
/*

0 commit comments

Comments
 (0)