aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/mips/kernel/signal.c45
-rw-r--r--arch/mips/kernel/signal32.c43
-rw-r--r--arch/mips/math-emu/kernel_linkage.c75
3 files changed, 76 insertions, 87 deletions
diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c
index 5199563c4403..b7e4614d41b5 100644
--- a/arch/mips/kernel/signal.c
+++ b/arch/mips/kernel/signal.c
@@ -46,9 +46,6 @@ static int (*restore_fp_context)(struct sigcontext __user *sc);
46extern asmlinkage int _save_fp_context(struct sigcontext __user *sc); 46extern asmlinkage int _save_fp_context(struct sigcontext __user *sc);
47extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc); 47extern asmlinkage int _restore_fp_context(struct sigcontext __user *sc);
48 48
49extern asmlinkage int fpu_emulator_save_context(struct sigcontext __user *sc);
50extern asmlinkage int fpu_emulator_restore_context(struct sigcontext __user *sc);
51
52struct sigframe { 49struct sigframe {
53 u32 sf_ass[4]; /* argument save space for o32 */ 50 u32 sf_ass[4]; /* argument save space for o32 */
54 u32 sf_pad[2]; /* Was: signal trampoline */ 51 u32 sf_pad[2]; /* Was: signal trampoline */
@@ -64,6 +61,40 @@ struct rt_sigframe {
64}; 61};
65 62
66/* 63/*
64 * Thread saved context copy to/from a signal context presumed to be on the
65 * user stack, and therefore accessed with appropriate macros from uaccess.h.
66 */
67static int copy_fp_to_sigcontext(struct sigcontext __user *sc)
68{
69 int i;
70 int err = 0;
71
72 for (i = 0; i < 32; i++) {
73 err |=
74 __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
75 &sc->sc_fpregs[i]);
76 }
77 err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
78
79 return err;
80}
81
82static int copy_fp_from_sigcontext(struct sigcontext __user *sc)
83{
84 int i;
85 int err = 0;
86 u64 fpr_val;
87
88 for (i = 0; i < 32; i++) {
89 err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
90 set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
91 }
92 err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
93
94 return err;
95}
96
97/*
67 * Helper routines 98 * Helper routines
68 */ 99 */
69static int protected_save_fp_context(struct sigcontext __user *sc) 100static int protected_save_fp_context(struct sigcontext __user *sc)
@@ -595,14 +626,14 @@ static int smp_save_fp_context(struct sigcontext __user *sc)
595{ 626{
596 return raw_cpu_has_fpu 627 return raw_cpu_has_fpu
597 ? _save_fp_context(sc) 628 ? _save_fp_context(sc)
598 : fpu_emulator_save_context(sc); 629 : copy_fp_to_sigcontext(sc);
599} 630}
600 631
601static int smp_restore_fp_context(struct sigcontext __user *sc) 632static int smp_restore_fp_context(struct sigcontext __user *sc)
602{ 633{
603 return raw_cpu_has_fpu 634 return raw_cpu_has_fpu
604 ? _restore_fp_context(sc) 635 ? _restore_fp_context(sc)
605 : fpu_emulator_restore_context(sc); 636 : copy_fp_from_sigcontext(sc);
606} 637}
607#endif 638#endif
608 639
@@ -617,8 +648,8 @@ static int signal_setup(void)
617 save_fp_context = _save_fp_context; 648 save_fp_context = _save_fp_context;
618 restore_fp_context = _restore_fp_context; 649 restore_fp_context = _restore_fp_context;
619 } else { 650 } else {
620 save_fp_context = fpu_emulator_save_context; 651 save_fp_context = copy_fp_from_sigcontext;
621 restore_fp_context = fpu_emulator_restore_context; 652 restore_fp_context = copy_fp_to_sigcontext;
622 } 653 }
623#endif 654#endif
624 655
diff --git a/arch/mips/kernel/signal32.c b/arch/mips/kernel/signal32.c
index 3d60f7750fa8..dc09206d8c7b 100644
--- a/arch/mips/kernel/signal32.c
+++ b/arch/mips/kernel/signal32.c
@@ -42,9 +42,6 @@ static int (*restore_fp_context32)(struct sigcontext32 __user *sc);
42extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc); 42extern asmlinkage int _save_fp_context32(struct sigcontext32 __user *sc);
43extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc); 43extern asmlinkage int _restore_fp_context32(struct sigcontext32 __user *sc);
44 44
45extern asmlinkage int fpu_emulator_save_context32(struct sigcontext32 __user *sc);
46extern asmlinkage int fpu_emulator_restore_context32(struct sigcontext32 __user *sc);
47
48/* 45/*
49 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ... 46 * Including <asm/unistd.h> would give use the 64-bit syscall numbers ...
50 */ 47 */
@@ -78,6 +75,42 @@ struct rt_sigframe32 {
78}; 75};
79 76
80/* 77/*
78 * Thread saved context copy to/from a signal context presumed to be on the
79 * user stack, and therefore accessed with appropriate macros from uaccess.h.
80 */
81static int copy_fp_to_sigcontext32(struct sigcontext32 __user *sc)
82{
83 int i;
84 int err = 0;
85 int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
86
87 for (i = 0; i < 32; i += inc) {
88 err |=
89 __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
90 &sc->sc_fpregs[i]);
91 }
92 err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
93
94 return err;
95}
96
97static int copy_fp_from_sigcontext32(struct sigcontext32 __user *sc)
98{
99 int i;
100 int err = 0;
101 int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
102 u64 fpr_val;
103
104 for (i = 0; i < 32; i += inc) {
105 err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
106 set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
107 }
108 err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
109
110 return err;
111}
112
113/*
81 * sigcontext handlers 114 * sigcontext handlers
82 */ 115 */
83static int protected_save_fp_context32(struct sigcontext32 __user *sc) 116static int protected_save_fp_context32(struct sigcontext32 __user *sc)
@@ -566,8 +599,8 @@ static int signal32_init(void)
566 save_fp_context32 = _save_fp_context32; 599 save_fp_context32 = _save_fp_context32;
567 restore_fp_context32 = _restore_fp_context32; 600 restore_fp_context32 = _restore_fp_context32;
568 } else { 601 } else {
569 save_fp_context32 = fpu_emulator_save_context32; 602 save_fp_context32 = copy_fp_to_sigcontext32;
570 restore_fp_context32 = fpu_emulator_restore_context32; 603 restore_fp_context32 = copy_fp_from_sigcontext32;
571 } 604 }
572 605
573 return 0; 606 return 0;
diff --git a/arch/mips/math-emu/kernel_linkage.c b/arch/mips/math-emu/kernel_linkage.c
index 9b46213b1035..eb58a85b3157 100644
--- a/arch/mips/math-emu/kernel_linkage.c
+++ b/arch/mips/math-emu/kernel_linkage.c
@@ -43,78 +43,3 @@ void fpu_emulator_init_fpu(void)
43 for (i = 0; i < 32; i++) 43 for (i = 0; i < 32; i++)
44 set_fpr64(&current->thread.fpu.fpr[i], 0, SIGNALLING_NAN); 44 set_fpr64(&current->thread.fpu.fpr[i], 0, SIGNALLING_NAN);
45} 45}
46
47
48/*
49 * Emulator context save/restore to/from a signal context
50 * presumed to be on the user stack, and therefore accessed
51 * with appropriate macros from uaccess.h
52 */
53
54int fpu_emulator_save_context(struct sigcontext __user *sc)
55{
56 int i;
57 int err = 0;
58
59 for (i = 0; i < 32; i++) {
60 err |=
61 __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
62 &sc->sc_fpregs[i]);
63 }
64 err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
65
66 return err;
67}
68
69int fpu_emulator_restore_context(struct sigcontext __user *sc)
70{
71 int i;
72 int err = 0;
73 u64 fpr_val;
74
75 for (i = 0; i < 32; i++) {
76 err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
77 set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
78 }
79 err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
80
81 return err;
82}
83
84#ifdef CONFIG_64BIT
85/*
86 * This is the o32 version
87 */
88
89int fpu_emulator_save_context32(struct sigcontext32 __user *sc)
90{
91 int i;
92 int err = 0;
93 int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
94
95 for (i = 0; i < 32; i += inc) {
96 err |=
97 __put_user(get_fpr64(&current->thread.fpu.fpr[i], 0),
98 &sc->sc_fpregs[i]);
99 }
100 err |= __put_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
101
102 return err;
103}
104
105int fpu_emulator_restore_context32(struct sigcontext32 __user *sc)
106{
107 int i;
108 int err = 0;
109 int inc = test_thread_flag(TIF_32BIT_FPREGS) ? 2 : 1;
110 u64 fpr_val;
111
112 for (i = 0; i < 32; i += inc) {
113 err |= __get_user(fpr_val, &sc->sc_fpregs[i]);
114 set_fpr64(&current->thread.fpu.fpr[i], 0, fpr_val);
115 }
116 err |= __get_user(current->thread.fpu.fcr31, &sc->sc_fpc_csr);
117
118 return err;
119}
120#endif