x86: switch to ->regset_get()
All instances of ->get() in arch/x86 switched; that might or might not be worth splitting up. Notes: * for xstateregs_get() the amount we want to store is determined at the boot time; see init_xstate_size() and update_regset_xstate_info() for details. task->thread.fpu.state.xsave ends with a flexible array member and the amount of data in it depends upon the FPU features supported/enabled. * fpregs_get() writes slightly less than full ->thread.fpu.state.fsave (the last word is not copied); we pass the full size of state.fsave and let membuf_write() trim to the amount declared by regset - __regset_get() will make sure that the space in buffer is no more than that. * copy_xstate_to_user() and its helpers are gone now. * fpregs_soft_get() was getting user_regset_copyout() arguments wrong. Since "x86: x86 user_regset math_emu" back in 2008... I really doubt that it's worth splitting out for -stable, though - you need a 486SX box for that to trigger... [Kevin's braino fix for copy_xstate_to_kernel() essentially duplicated here] Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -256,36 +256,16 @@ int regset_tls_active(struct task_struct *target,
|
||||
}
|
||||
|
||||
int regset_tls_get(struct task_struct *target, const struct user_regset *regset,
|
||||
unsigned int pos, unsigned int count,
|
||||
void *kbuf, void __user *ubuf)
|
||||
struct membuf to)
|
||||
{
|
||||
const struct desc_struct *tls;
|
||||
struct user_desc v;
|
||||
int pos;
|
||||
|
||||
if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) ||
|
||||
(pos % sizeof(struct user_desc)) != 0 ||
|
||||
(count % sizeof(struct user_desc)) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
pos /= sizeof(struct user_desc);
|
||||
count /= sizeof(struct user_desc);
|
||||
|
||||
tls = &target->thread.tls_array[pos];
|
||||
|
||||
if (kbuf) {
|
||||
struct user_desc *info = kbuf;
|
||||
while (count-- > 0)
|
||||
fill_user_desc(info++, GDT_ENTRY_TLS_MIN + pos++,
|
||||
tls++);
|
||||
} else {
|
||||
struct user_desc __user *u_info = ubuf;
|
||||
while (count-- > 0) {
|
||||
struct user_desc info;
|
||||
fill_user_desc(&info, GDT_ENTRY_TLS_MIN + pos++, tls++);
|
||||
if (__copy_to_user(u_info++, &info, sizeof(info)))
|
||||
return -EFAULT;
|
||||
}
|
||||
for (pos = 0, tls = target->thread.tls_array; to.left; pos++, tls++) {
|
||||
fill_user_desc(&v, GDT_ENTRY_TLS_MIN + pos, tls);
|
||||
membuf_write(&to, &v, sizeof(v));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user