diff options
Diffstat (limited to 'arch/x86/kernel/i387.c')
-rw-r--r-- | arch/x86/kernel/i387.c | 105 |
1 files changed, 9 insertions, 96 deletions
diff --git a/arch/x86/kernel/i387.c b/arch/x86/kernel/i387.c index f7f7568dd7bc..26719bd2c77c 100644 --- a/arch/x86/kernel/i387.c +++ b/arch/x86/kernel/i387.c | |||
@@ -454,113 +454,26 @@ int restore_i387_ia32(struct _fpstate_ia32 __user *buf) | |||
454 | return err; | 454 | return err; |
455 | } | 455 | } |
456 | 456 | ||
457 | #endif /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */ | ||
458 | |||
459 | #ifdef CONFIG_X86_64 | ||
460 | |||
461 | int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *tsk) | ||
462 | { | ||
463 | return xfpregs_get(tsk, NULL, 0, sizeof(*buf), NULL, buf); | ||
464 | } | ||
465 | |||
466 | int set_fpregs(struct task_struct *tsk, struct user_i387_struct __user *buf) | ||
467 | { | ||
468 | return xfpregs_set(tsk, NULL, 0, sizeof(*buf), NULL, buf); | ||
469 | } | ||
470 | |||
471 | #else | ||
472 | |||
473 | int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *tsk) | ||
474 | { | ||
475 | return fpregs_get(tsk, NULL, 0, sizeof(*buf), NULL, buf); | ||
476 | } | ||
477 | |||
478 | int set_fpregs(struct task_struct *tsk, struct user_i387_struct __user *buf) | ||
479 | { | ||
480 | return fpregs_set(tsk, NULL, 0, sizeof(*buf), NULL, buf); | ||
481 | } | ||
482 | |||
483 | int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *tsk) | ||
484 | { | ||
485 | return xfpregs_get(tsk, NULL, 0, sizeof(*buf), NULL, buf); | ||
486 | } | ||
487 | |||
488 | int set_fpxregs(struct task_struct *tsk, struct user_fxsr_struct __user *buf) | ||
489 | { | ||
490 | return xfpregs_get(tsk, NULL, 0, sizeof(*buf), NULL, buf); | ||
491 | } | ||
492 | |||
493 | #endif | ||
494 | |||
495 | /* | 457 | /* |
496 | * FPU state for core dumps. | 458 | * FPU state for core dumps. |
459 | * This is only used for a.out dumps now. | ||
460 | * It is declared generically using elf_fpregset_t (which is | ||
461 | * struct user_i387_struct) but is in fact only used for 32-bit | ||
462 | * dumps, so on 64-bit it is really struct user_i387_ia32_struct. | ||
497 | */ | 463 | */ |
498 | |||
499 | static inline void copy_fpu_fsave(struct task_struct *tsk, | ||
500 | struct user_i387_struct *fpu) | ||
501 | { | ||
502 | memcpy(fpu, &tsk->thread.i387.fsave, | ||
503 | sizeof(struct user_i387_struct)); | ||
504 | } | ||
505 | |||
506 | static inline void copy_fpu_fxsave(struct task_struct *tsk, | ||
507 | struct user_i387_struct *fpu) | ||
508 | { | ||
509 | unsigned short *to; | ||
510 | unsigned short *from; | ||
511 | int i; | ||
512 | |||
513 | memcpy(fpu, &tsk->thread.i387.fxsave, 7 * sizeof(long)); | ||
514 | |||
515 | to = (unsigned short *)&fpu->st_space[0]; | ||
516 | from = (unsigned short *)&tsk->thread.i387.fxsave.st_space[0]; | ||
517 | for (i = 0; i < 8; i++, to += 5, from += 8) | ||
518 | memcpy(to, from, 5 * sizeof(unsigned short)); | ||
519 | } | ||
520 | |||
521 | int dump_fpu(struct pt_regs *regs, struct user_i387_struct *fpu) | 464 | int dump_fpu(struct pt_regs *regs, struct user_i387_struct *fpu) |
522 | { | 465 | { |
523 | int fpvalid; | 466 | int fpvalid; |
524 | struct task_struct *tsk = current; | 467 | struct task_struct *tsk = current; |
525 | 468 | ||
526 | fpvalid = !!used_math(); | 469 | fpvalid = !!used_math(); |
527 | if (fpvalid) { | 470 | if (fpvalid) |
528 | unlazy_fpu(tsk); | 471 | fpvalid = !fpregs_get(tsk, NULL, |
529 | if (cpu_has_fxsr) { | 472 | 0, sizeof(struct user_i387_ia32_struct), |
530 | copy_fpu_fxsave(tsk, fpu); | 473 | fpu, NULL); |
531 | } else { | ||
532 | copy_fpu_fsave(tsk, fpu); | ||
533 | } | ||
534 | } | ||
535 | 474 | ||
536 | return fpvalid; | 475 | return fpvalid; |
537 | } | 476 | } |
538 | EXPORT_SYMBOL(dump_fpu); | 477 | EXPORT_SYMBOL(dump_fpu); |
539 | 478 | ||
540 | int dump_task_fpu(struct task_struct *tsk, struct user_i387_struct *fpu) | 479 | #endif /* CONFIG_X86_32 || CONFIG_IA32_EMULATION */ |
541 | { | ||
542 | int fpvalid = !!tsk_used_math(tsk); | ||
543 | |||
544 | if (fpvalid) { | ||
545 | if (tsk == current) | ||
546 | unlazy_fpu(tsk); | ||
547 | if (cpu_has_fxsr) | ||
548 | copy_fpu_fxsave(tsk, fpu); | ||
549 | else | ||
550 | copy_fpu_fsave(tsk, fpu); | ||
551 | } | ||
552 | return fpvalid; | ||
553 | } | ||
554 | |||
555 | int dump_task_extended_fpu(struct task_struct *tsk, | ||
556 | struct user32_fxsr_struct *fpu) | ||
557 | { | ||
558 | int fpvalid = tsk_used_math(tsk) && cpu_has_fxsr; | ||
559 | |||
560 | if (fpvalid) { | ||
561 | if (tsk == current) | ||
562 | unlazy_fpu(tsk); | ||
563 | memcpy(fpu, &tsk->thread.i387.fxsave, sizeof(*fpu)); | ||
564 | } | ||
565 | return fpvalid; | ||
566 | } | ||