| .. | .. |
|---|
| 256 | 256 | } |
|---|
| 257 | 257 | |
|---|
| 258 | 258 | int regset_tls_get(struct task_struct *target, const struct user_regset *regset, |
|---|
| 259 | | - unsigned int pos, unsigned int count, |
|---|
| 260 | | - void *kbuf, void __user *ubuf) |
|---|
| 259 | + struct membuf to) |
|---|
| 261 | 260 | { |
|---|
| 262 | 261 | const struct desc_struct *tls; |
|---|
| 262 | + struct user_desc v; |
|---|
| 263 | + int pos; |
|---|
| 263 | 264 | |
|---|
| 264 | | - if (pos >= GDT_ENTRY_TLS_ENTRIES * sizeof(struct user_desc) || |
|---|
| 265 | | - (pos % sizeof(struct user_desc)) != 0 || |
|---|
| 266 | | - (count % sizeof(struct user_desc)) != 0) |
|---|
| 267 | | - return -EINVAL; |
|---|
| 268 | | - |
|---|
| 269 | | - pos /= sizeof(struct user_desc); |
|---|
| 270 | | - count /= sizeof(struct user_desc); |
|---|
| 271 | | - |
|---|
| 272 | | - tls = &target->thread.tls_array[pos]; |
|---|
| 273 | | - |
|---|
| 274 | | - if (kbuf) { |
|---|
| 275 | | - struct user_desc *info = kbuf; |
|---|
| 276 | | - while (count-- > 0) |
|---|
| 277 | | - fill_user_desc(info++, GDT_ENTRY_TLS_MIN + pos++, |
|---|
| 278 | | - tls++); |
|---|
| 279 | | - } else { |
|---|
| 280 | | - struct user_desc __user *u_info = ubuf; |
|---|
| 281 | | - while (count-- > 0) { |
|---|
| 282 | | - struct user_desc info; |
|---|
| 283 | | - fill_user_desc(&info, GDT_ENTRY_TLS_MIN + pos++, tls++); |
|---|
| 284 | | - if (__copy_to_user(u_info++, &info, sizeof(info))) |
|---|
| 285 | | - return -EFAULT; |
|---|
| 286 | | - } |
|---|
| 265 | + for (pos = 0, tls = target->thread.tls_array; to.left; pos++, tls++) { |
|---|
| 266 | + fill_user_desc(&v, GDT_ENTRY_TLS_MIN + pos, tls); |
|---|
| 267 | + membuf_write(&to, &v, sizeof(v)); |
|---|
| 287 | 268 | } |
|---|
| 288 | | - |
|---|
| 289 | 269 | return 0; |
|---|
| 290 | 270 | } |
|---|
| 291 | 271 | |
|---|