@@ -25,6 +25,9 @@ enum riscv_regset {
25
25
#ifdef CONFIG_FPU
26
26
REGSET_F ,
27
27
#endif
28
+ #ifdef CONFIG_RISCV_ISA_V
29
+ REGSET_V ,
30
+ #endif
28
31
};
29
32
30
33
static int riscv_gpr_get (struct task_struct * target ,
@@ -81,6 +84,71 @@ static int riscv_fpr_set(struct task_struct *target,
81
84
}
82
85
#endif
83
86
87
+ #ifdef CONFIG_RISCV_ISA_V
88
+ static int riscv_vr_get (struct task_struct * target ,
89
+ const struct user_regset * regset ,
90
+ struct membuf to )
91
+ {
92
+ struct __riscv_v_ext_state * vstate = & target -> thread .vstate ;
93
+ struct __riscv_v_regset_state ptrace_vstate ;
94
+
95
+ if (!riscv_v_vstate_query (task_pt_regs (target )))
96
+ return - EINVAL ;
97
+
98
+ /*
99
+ * Ensure the vector registers have been saved to the memory before
100
+ * copying them to membuf.
101
+ */
102
+ if (target == current )
103
+ riscv_v_vstate_save (current , task_pt_regs (current ));
104
+
105
+ ptrace_vstate .vstart = vstate -> vstart ;
106
+ ptrace_vstate .vl = vstate -> vl ;
107
+ ptrace_vstate .vtype = vstate -> vtype ;
108
+ ptrace_vstate .vcsr = vstate -> vcsr ;
109
+ ptrace_vstate .vlenb = vstate -> vlenb ;
110
+
111
+ /* Copy vector header from vstate. */
112
+ membuf_write (& to , & ptrace_vstate , sizeof (struct __riscv_v_regset_state ));
113
+
114
+ /* Copy all the vector registers from vstate. */
115
+ return membuf_write (& to , vstate -> datap , riscv_v_vsize );
116
+ }
117
+
118
+ static int riscv_vr_set (struct task_struct * target ,
119
+ const struct user_regset * regset ,
120
+ unsigned int pos , unsigned int count ,
121
+ const void * kbuf , const void __user * ubuf )
122
+ {
123
+ int ret ;
124
+ struct __riscv_v_ext_state * vstate = & target -> thread .vstate ;
125
+ struct __riscv_v_regset_state ptrace_vstate ;
126
+
127
+ if (!riscv_v_vstate_query (task_pt_regs (target )))
128
+ return - EINVAL ;
129
+
130
+ /* Copy rest of the vstate except datap */
131
+ ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf , & ptrace_vstate , 0 ,
132
+ sizeof (struct __riscv_v_regset_state ));
133
+ if (unlikely (ret ))
134
+ return ret ;
135
+
136
+ if (vstate -> vlenb != ptrace_vstate .vlenb )
137
+ return - EINVAL ;
138
+
139
+ vstate -> vstart = ptrace_vstate .vstart ;
140
+ vstate -> vl = ptrace_vstate .vl ;
141
+ vstate -> vtype = ptrace_vstate .vtype ;
142
+ vstate -> vcsr = ptrace_vstate .vcsr ;
143
+
144
+ /* Copy all the vector registers. */
145
+ pos = 0 ;
146
+ ret = user_regset_copyin (& pos , & count , & kbuf , & ubuf , vstate -> datap ,
147
+ 0 , riscv_v_vsize );
148
+ return ret ;
149
+ }
150
+ #endif
151
+
84
152
static const struct user_regset riscv_user_regset [] = {
85
153
[REGSET_X ] = {
86
154
.core_note_type = NT_PRSTATUS ,
@@ -100,6 +168,17 @@ static const struct user_regset riscv_user_regset[] = {
100
168
.set = riscv_fpr_set ,
101
169
},
102
170
#endif
171
+ #ifdef CONFIG_RISCV_ISA_V
172
+ [REGSET_V ] = {
173
+ .core_note_type = NT_RISCV_VECTOR ,
174
+ .align = 16 ,
175
+ .n = ((32 * RISCV_MAX_VLENB ) +
176
+ sizeof (struct __riscv_v_regset_state )) / sizeof (__u32 ),
177
+ .size = sizeof (__u32 ),
178
+ .regset_get = riscv_vr_get ,
179
+ .set = riscv_vr_set ,
180
+ },
181
+ #endif
103
182
};
104
183
105
184
static const struct user_regset_view riscv_user_native_view = {
0 commit comments