.. | .. |
---|
15 | 15 | */ |
---|
16 | 16 | int regset_fpregs_active(struct task_struct *target, const struct user_regset *regset) |
---|
17 | 17 | { |
---|
18 | | - struct fpu *target_fpu = &target->thread.fpu; |
---|
19 | | - |
---|
20 | | - return target_fpu->initialized ? regset->n : 0; |
---|
| 18 | + return regset->n; |
---|
21 | 19 | } |
---|
22 | 20 | |
---|
23 | 21 | int regset_xregset_fpregs_active(struct task_struct *target, const struct user_regset *regset) |
---|
24 | 22 | { |
---|
25 | | - struct fpu *target_fpu = &target->thread.fpu; |
---|
26 | | - |
---|
27 | | - if (boot_cpu_has(X86_FEATURE_FXSR) && target_fpu->initialized) |
---|
| 23 | + if (boot_cpu_has(X86_FEATURE_FXSR)) |
---|
28 | 24 | return regset->n; |
---|
29 | 25 | else |
---|
30 | 26 | return 0; |
---|
31 | 27 | } |
---|
32 | 28 | |
---|
33 | 29 | int xfpregs_get(struct task_struct *target, const struct user_regset *regset, |
---|
34 | | - unsigned int pos, unsigned int count, |
---|
35 | | - void *kbuf, void __user *ubuf) |
---|
| 30 | + struct membuf to) |
---|
36 | 31 | { |
---|
37 | 32 | struct fpu *fpu = &target->thread.fpu; |
---|
38 | 33 | |
---|
.. | .. |
---|
42 | 37 | fpu__prepare_read(fpu); |
---|
43 | 38 | fpstate_sanitize_xstate(fpu); |
---|
44 | 39 | |
---|
45 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
46 | | - &fpu->state.fxsave, 0, -1); |
---|
| 40 | + return membuf_write(&to, &fpu->state.fxsave, sizeof(struct fxregs_state)); |
---|
47 | 41 | } |
---|
48 | 42 | |
---|
49 | 43 | int xfpregs_set(struct task_struct *target, const struct user_regset *regset, |
---|
.. | .. |
---|
78 | 72 | } |
---|
79 | 73 | |
---|
80 | 74 | int xstateregs_get(struct task_struct *target, const struct user_regset *regset, |
---|
81 | | - unsigned int pos, unsigned int count, |
---|
82 | | - void *kbuf, void __user *ubuf) |
---|
| 75 | + struct membuf to) |
---|
83 | 76 | { |
---|
84 | 77 | struct fpu *fpu = &target->thread.fpu; |
---|
85 | 78 | struct xregs_state *xsave; |
---|
86 | | - int ret; |
---|
87 | 79 | |
---|
88 | 80 | if (!boot_cpu_has(X86_FEATURE_XSAVE)) |
---|
89 | 81 | return -ENODEV; |
---|
.. | .. |
---|
93 | 85 | fpu__prepare_read(fpu); |
---|
94 | 86 | |
---|
95 | 87 | if (using_compacted_format()) { |
---|
96 | | - if (kbuf) |
---|
97 | | - ret = copy_xstate_to_kernel(kbuf, xsave, pos, count); |
---|
98 | | - else |
---|
99 | | - ret = copy_xstate_to_user(ubuf, xsave, pos, count); |
---|
| 88 | + copy_xstate_to_kernel(to, xsave); |
---|
| 89 | + return 0; |
---|
100 | 90 | } else { |
---|
101 | 91 | fpstate_sanitize_xstate(fpu); |
---|
102 | 92 | /* |
---|
.. | .. |
---|
109 | 99 | /* |
---|
110 | 100 | * Copy the xstate memory layout. |
---|
111 | 101 | */ |
---|
112 | | - ret = user_regset_copyout(&pos, &count, &kbuf, &ubuf, xsave, 0, -1); |
---|
| 102 | + return membuf_write(&to, xsave, fpu_user_xstate_size); |
---|
113 | 103 | } |
---|
114 | | - return ret; |
---|
115 | 104 | } |
---|
116 | 105 | |
---|
117 | 106 | int xstateregs_set(struct task_struct *target, const struct user_regset *regset, |
---|
.. | .. |
---|
143 | 132 | } else { |
---|
144 | 133 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, xsave, 0, -1); |
---|
145 | 134 | if (!ret) |
---|
146 | | - ret = validate_xstate_header(&xsave->header); |
---|
| 135 | + ret = validate_user_xstate_header(&xsave->header); |
---|
147 | 136 | } |
---|
148 | 137 | |
---|
149 | 138 | /* |
---|
.. | .. |
---|
269 | 258 | memcpy(&to[i], &from[i], sizeof(to[0])); |
---|
270 | 259 | } |
---|
271 | 260 | |
---|
272 | | -void convert_to_fxsr(struct task_struct *tsk, |
---|
| 261 | +void convert_to_fxsr(struct fxregs_state *fxsave, |
---|
273 | 262 | const struct user_i387_ia32_struct *env) |
---|
274 | 263 | |
---|
275 | 264 | { |
---|
276 | | - struct fxregs_state *fxsave = &tsk->thread.fpu.state.fxsave; |
---|
277 | 265 | struct _fpreg *from = (struct _fpreg *) &env->st_space[0]; |
---|
278 | 266 | struct _fpxreg *to = (struct _fpxreg *) &fxsave->st_space[0]; |
---|
279 | 267 | int i; |
---|
.. | .. |
---|
298 | 286 | } |
---|
299 | 287 | |
---|
300 | 288 | int fpregs_get(struct task_struct *target, const struct user_regset *regset, |
---|
301 | | - unsigned int pos, unsigned int count, |
---|
302 | | - void *kbuf, void __user *ubuf) |
---|
| 289 | + struct membuf to) |
---|
303 | 290 | { |
---|
304 | 291 | struct fpu *fpu = &target->thread.fpu; |
---|
305 | 292 | struct user_i387_ia32_struct env; |
---|
.. | .. |
---|
307 | 294 | fpu__prepare_read(fpu); |
---|
308 | 295 | |
---|
309 | 296 | if (!boot_cpu_has(X86_FEATURE_FPU)) |
---|
310 | | - return fpregs_soft_get(target, regset, pos, count, kbuf, ubuf); |
---|
| 297 | + return fpregs_soft_get(target, regset, to); |
---|
311 | 298 | |
---|
312 | | - if (!boot_cpu_has(X86_FEATURE_FXSR)) |
---|
313 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, |
---|
314 | | - &fpu->state.fsave, 0, |
---|
315 | | - -1); |
---|
| 299 | + if (!boot_cpu_has(X86_FEATURE_FXSR)) { |
---|
| 300 | + return membuf_write(&to, &fpu->state.fsave, |
---|
| 301 | + sizeof(struct fregs_state)); |
---|
| 302 | + } |
---|
316 | 303 | |
---|
317 | 304 | fpstate_sanitize_xstate(fpu); |
---|
318 | 305 | |
---|
319 | | - if (kbuf && pos == 0 && count == sizeof(env)) { |
---|
320 | | - convert_from_fxsr(kbuf, target); |
---|
| 306 | + if (to.left == sizeof(env)) { |
---|
| 307 | + convert_from_fxsr(to.p, target); |
---|
321 | 308 | return 0; |
---|
322 | 309 | } |
---|
323 | 310 | |
---|
324 | 311 | convert_from_fxsr(&env, target); |
---|
325 | | - |
---|
326 | | - return user_regset_copyout(&pos, &count, &kbuf, &ubuf, &env, 0, -1); |
---|
| 312 | + return membuf_write(&to, &env, sizeof(env)); |
---|
327 | 313 | } |
---|
328 | 314 | |
---|
329 | 315 | int fpregs_set(struct task_struct *target, const struct user_regset *regset, |
---|
.. | .. |
---|
350 | 336 | |
---|
351 | 337 | ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &env, 0, -1); |
---|
352 | 338 | if (!ret) |
---|
353 | | - convert_to_fxsr(target, &env); |
---|
| 339 | + convert_to_fxsr(&target->thread.fpu.state.fxsave, &env); |
---|
354 | 340 | |
---|
355 | 341 | /* |
---|
356 | 342 | * update the header bit in the xsave header, indicating the |
---|
.. | .. |
---|
360 | 346 | fpu->state.xsave.header.xfeatures |= XFEATURE_MASK_FP; |
---|
361 | 347 | return ret; |
---|
362 | 348 | } |
---|
363 | | - |
---|
364 | | -/* |
---|
365 | | - * FPU state for core dumps. |
---|
366 | | - * This is only used for a.out dumps now. |
---|
367 | | - * It is declared generically using elf_fpregset_t (which is |
---|
368 | | - * struct user_i387_struct) but is in fact only used for 32-bit |
---|
369 | | - * dumps, so on 64-bit it is really struct user_i387_ia32_struct. |
---|
370 | | - */ |
---|
371 | | -int dump_fpu(struct pt_regs *regs, struct user_i387_struct *ufpu) |
---|
372 | | -{ |
---|
373 | | - struct task_struct *tsk = current; |
---|
374 | | - struct fpu *fpu = &tsk->thread.fpu; |
---|
375 | | - int fpvalid; |
---|
376 | | - |
---|
377 | | - fpvalid = fpu->initialized; |
---|
378 | | - if (fpvalid) |
---|
379 | | - fpvalid = !fpregs_get(tsk, NULL, |
---|
380 | | - 0, sizeof(struct user_i387_ia32_struct), |
---|
381 | | - ufpu, NULL); |
---|
382 | | - |
---|
383 | | - return fpvalid; |
---|
384 | | -} |
---|
385 | | -EXPORT_SYMBOL(dump_fpu); |
---|
386 | 349 | |
---|
387 | 350 | #endif /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */ |
---|