@@ -25,6 +25,9 @@ enum riscv_regset {
2525#ifdef CONFIG_FPU
2626 REGSET_F ,
2727#endif
28+ #ifdef CONFIG_RISCV_ISA_V
29+ REGSET_V ,
30+ #endif
2831};
2932
3033static int riscv_gpr_get (struct task_struct * target ,
@@ -81,6 +84,71 @@ static int riscv_fpr_set(struct task_struct *target,
8184}
8285#endif
8386
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+
84152static const struct user_regset riscv_user_regset [] = {
85153 [REGSET_X ] = {
86154 .core_note_type = NT_PRSTATUS ,
@@ -100,6 +168,17 @@ static const struct user_regset riscv_user_regset[] = {
100168 .set = riscv_fpr_set ,
101169 },
102170#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
103182};
104183
105184static const struct user_regset_view riscv_user_native_view = {
0 commit comments