Commit 459a40172e7ee1be269771c355dbb3ef3c3903db

Authored by bellard
1 parent eeeac3f3

removed warnings - improved sparc32/64 signal frame setup - disabled x86 frame setup for x86_64


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@3608 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 1 changed file with 92 additions and 59 deletions
linux-user/signal.c
@@ -143,7 +143,7 @@ static void host_to_target_sigset_internal(target_sigset_t *d, @@ -143,7 +143,7 @@ static void host_to_target_sigset_internal(target_sigset_t *d,
143 d->sig[0] = target_sigmask; 143 d->sig[0] = target_sigmask;
144 d->sig[1] = sigmask >> 32; 144 d->sig[1] = sigmask >> 32;
145 #else 145 #else
146 -#warning host_to_target_sigset 146 + /* XXX: do it */
147 #endif 147 #endif
148 } 148 }
149 149
@@ -177,7 +177,7 @@ void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s) @@ -177,7 +177,7 @@ void target_to_host_sigset_internal(sigset_t *d, const target_sigset_t *s)
177 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2 177 #elif TARGET_ABI_BITS == 32 && HOST_LONG_BITS == 64 && TARGET_NSIG_WORDS == 2
178 ((unsigned long *)d)[0] = sigmask | ((unsigned long)(s->sig[1]) << 32); 178 ((unsigned long *)d)[0] = sigmask | ((unsigned long)(s->sig[1]) << 32);
179 #else 179 #else
180 -#warning target_to_host_sigset 180 + /* XXX: do it */
181 #endif /* TARGET_ABI_BITS */ 181 #endif /* TARGET_ABI_BITS */
182 } 182 }
183 183
@@ -233,7 +233,7 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo, @@ -233,7 +233,7 @@ static inline void host_to_target_siginfo_noswap(target_siginfo_t *tinfo,
233 tinfo->_sifields._rt._uid = info->si_uid; 233 tinfo->_sifields._rt._uid = info->si_uid;
234 /* XXX: potential problem if 64 bit */ 234 /* XXX: potential problem if 64 bit */
235 tinfo->_sifields._rt._sigval.sival_ptr = 235 tinfo->_sifields._rt._sigval.sival_ptr =
236 - (abi_ulong)info->si_value.sival_ptr; 236 + (abi_ulong)(unsigned long)info->si_value.sival_ptr;
237 } 237 }
238 } 238 }
239 239
@@ -276,7 +276,7 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo) @@ -276,7 +276,7 @@ void target_to_host_siginfo(siginfo_t *info, const target_siginfo_t *tinfo)
276 info->si_pid = tswap32(tinfo->_sifields._rt._pid); 276 info->si_pid = tswap32(tinfo->_sifields._rt._pid);
277 info->si_uid = tswap32(tinfo->_sifields._rt._uid); 277 info->si_uid = tswap32(tinfo->_sifields._rt._uid);
278 info->si_value.sival_ptr = 278 info->si_value.sival_ptr =
279 - (void *)tswapl(tinfo->_sifields._rt._sigval.sival_ptr); 279 + (void *)(long)tswapl(tinfo->_sifields._rt._sigval.sival_ptr);
280 } 280 }
281 281
282 void signal_init(void) 282 void signal_init(void)
@@ -562,7 +562,7 @@ static inline int copy_siginfo_to_user(target_siginfo_t *tinfo, @@ -562,7 +562,7 @@ static inline int copy_siginfo_to_user(target_siginfo_t *tinfo,
562 return 0; 562 return 0;
563 } 563 }
564 564
565 -#ifdef TARGET_I386 565 +#if defined(TARGET_I386) && TARGET_ABI_BITS == 32
566 566
567 /* from the Linux kernel */ 567 /* from the Linux kernel */
568 568
@@ -773,11 +773,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -773,11 +773,7 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
773 /* This is popl %eax ; movl $,%eax ; int $0x80 */ 773 /* This is popl %eax ; movl $,%eax ; int $0x80 */
774 val16 = 0xb858; 774 val16 = 0xb858;
775 err |= __put_user(val16, (uint16_t *)(frame->retcode+0)); 775 err |= __put_user(val16, (uint16_t *)(frame->retcode+0));
776 -#if defined(TARGET_X86_64)  
777 -#warning "Fix this !"  
778 -#else  
779 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2)); 776 err |= __put_user(TARGET_NR_sigreturn, (int *)(frame->retcode+2));
780 -#endif  
781 val16 = 0x80cd; 777 val16 = 0x80cd;
782 err |= __put_user(val16, (uint16_t *)(frame->retcode+6)); 778 err |= __put_user(val16, (uint16_t *)(frame->retcode+6));
783 } 779 }
@@ -1486,9 +1482,10 @@ struct target_rt_signal_frame { @@ -1486,9 +1482,10 @@ struct target_rt_signal_frame {
1486 #define UREG_FP UREG_I6 1482 #define UREG_FP UREG_I6
1487 #define UREG_SP UREG_O6 1483 #define UREG_SP UREG_O6
1488 1484
1489 -static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, unsigned long framesize) 1485 +static inline abi_ulong get_sigframe(struct emulated_sigaction *sa,
  1486 + CPUState *env, unsigned long framesize)
1490 { 1487 {
1491 - unsigned long sp; 1488 + abi_ulong sp;
1492 1489
1493 sp = env->regwptr[UREG_FP]; 1490 sp = env->regwptr[UREG_FP];
1494 1491
@@ -1498,7 +1495,7 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u @@ -1498,7 +1495,7 @@ static inline void *get_sigframe(struct emulated_sigaction *sa, CPUState *env, u
1498 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7)) 1495 && !((target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size) & 7))
1499 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size; 1496 sp = target_sigaltstack_used.ss_sp + target_sigaltstack_used.ss_size;
1500 } 1497 }
1501 - return g2h(sp - framesize); 1498 + return sp - framesize;
1502 } 1499 }
1503 1500
1504 static int 1501 static int
@@ -1543,6 +1540,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/ @@ -1543,6 +1540,7 @@ setup_sigcontext(struct target_sigcontext *sc, /*struct _fpstate *fpstate,*/
1543 static void setup_frame(int sig, struct emulated_sigaction *ka, 1540 static void setup_frame(int sig, struct emulated_sigaction *ka,
1544 target_sigset_t *set, CPUState *env) 1541 target_sigset_t *set, CPUState *env)
1545 { 1542 {
  1543 + abi_ulong sf_addr;
1546 struct target_signal_frame *sf; 1544 struct target_signal_frame *sf;
1547 int sigframe_size, err, i; 1545 int sigframe_size, err, i;
1548 1546
@@ -1550,10 +1548,13 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -1550,10 +1548,13 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1550 //synchronize_user_stack(); 1548 //synchronize_user_stack();
1551 1549
1552 sigframe_size = NF_ALIGNEDSZ; 1550 sigframe_size = NF_ALIGNEDSZ;
  1551 + sf_addr = get_sigframe(ka, env, sigframe_size);
1553 1552
1554 - sf = (struct target_signal_frame *)  
1555 - get_sigframe(ka, env, sigframe_size);  
1556 - 1553 + sf = lock_user(VERIFY_WRITE, sf_addr,
  1554 + sizeof(struct target_signal_frame), 0);
  1555 + if (!sf)
  1556 + goto sigsegv;
  1557 +
1557 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]); 1558 //fprintf(stderr, "sf: %x pc %x fp %x sp %x\n", sf, env->pc, env->regwptr[UREG_FP], env->regwptr[UREG_SP]);
1558 #if 0 1559 #if 0
1559 if (invalid_frame_pointer(sf, sigframe_size)) 1560 if (invalid_frame_pointer(sf, sigframe_size))
@@ -1581,20 +1582,24 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -1581,20 +1582,24 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1581 goto sigsegv; 1582 goto sigsegv;
1582 1583
1583 /* 3. signal handler back-trampoline and parameters */ 1584 /* 3. signal handler back-trampoline and parameters */
1584 - env->regwptr[UREG_FP] = h2g(sf); 1585 + env->regwptr[UREG_FP] = sf_addr;
1585 env->regwptr[UREG_I0] = sig; 1586 env->regwptr[UREG_I0] = sig;
1586 - env->regwptr[UREG_I1] = h2g(&sf->info);  
1587 - env->regwptr[UREG_I2] = h2g(&sf->info); 1587 + env->regwptr[UREG_I1] = sf_addr +
  1588 + offsetof(struct target_signal_frame, info);
  1589 + env->regwptr[UREG_I2] = sf_addr +
  1590 + offsetof(struct target_signal_frame, info);
1588 1591
1589 /* 4. signal handler */ 1592 /* 4. signal handler */
1590 - env->pc = (unsigned long) ka->sa._sa_handler; 1593 + env->pc = ka->sa._sa_handler;
1591 env->npc = (env->pc + 4); 1594 env->npc = (env->pc + 4);
1592 /* 5. return to kernel instructions */ 1595 /* 5. return to kernel instructions */
1593 if (ka->sa.sa_restorer) 1596 if (ka->sa.sa_restorer)
1594 - env->regwptr[UREG_I7] = (unsigned long)ka->sa.sa_restorer; 1597 + env->regwptr[UREG_I7] = ka->sa.sa_restorer;
1595 else { 1598 else {
1596 uint32_t val32; 1599 uint32_t val32;
1597 - env->regwptr[UREG_I7] = h2g(&(sf->insns[0]) - 2); 1600 +
  1601 + env->regwptr[UREG_I7] = sf_addr +
  1602 + offsetof(struct target_signal_frame, insns) - 2 * 4;
1598 1603
1599 /* mov __NR_sigreturn, %g1 */ 1604 /* mov __NR_sigreturn, %g1 */
1600 val32 = 0x821020d8; 1605 val32 = 0x821020d8;
@@ -1610,12 +1615,15 @@ static void setup_frame(int sig, struct emulated_sigaction *ka, @@ -1610,12 +1615,15 @@ static void setup_frame(int sig, struct emulated_sigaction *ka,
1610 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0])); 1615 //flush_sig_insns(current->mm, (unsigned long) &(sf->insns[0]));
1611 // tb_flush(env); 1616 // tb_flush(env);
1612 } 1617 }
  1618 + unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1613 return; 1619 return;
1614 -  
1615 - //sigill_and_return: 1620 +#if 0
  1621 +sigill_and_return:
1616 force_sig(TARGET_SIGILL); 1622 force_sig(TARGET_SIGILL);
  1623 +#endif
1617 sigsegv: 1624 sigsegv:
1618 //fprintf(stderr, "force_sig\n"); 1625 //fprintf(stderr, "force_sig\n");
  1626 + unlock_user(sf, sf_addr, sizeof(struct target_signal_frame));
1619 force_sig(TARGET_SIGSEGV); 1627 force_sig(TARGET_SIGSEGV);
1620 } 1628 }
1621 static inline int 1629 static inline int
@@ -1744,7 +1752,7 @@ long do_rt_sigreturn(CPUState *env) @@ -1744,7 +1752,7 @@ long do_rt_sigreturn(CPUState *env)
1744 return -ENOSYS; 1752 return -ENOSYS;
1745 } 1753 }
1746 1754
1747 -#ifdef TARGET_SPARC64 1755 +#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
1748 #define MC_TSTATE 0 1756 #define MC_TSTATE 0
1749 #define MC_PC 1 1757 #define MC_PC 1
1750 #define MC_NPC 2 1758 #define MC_NPC 2
@@ -1815,16 +1823,18 @@ struct target_reg_window { @@ -1815,16 +1823,18 @@ struct target_reg_window {
1815 /* {set, get}context() needed for 64-bit SparcLinux userland. */ 1823 /* {set, get}context() needed for 64-bit SparcLinux userland. */
1816 void sparc64_set_context(CPUSPARCState *env) 1824 void sparc64_set_context(CPUSPARCState *env)
1817 { 1825 {
1818 - struct target_ucontext *ucp = (struct target_ucontext *)  
1819 - env->regwptr[UREG_I0]; 1826 + abi_ulong ucp_addr;
  1827 + struct target_ucontext *ucp;
1820 target_mc_gregset_t *grp; 1828 target_mc_gregset_t *grp;
1821 abi_ulong pc, npc, tstate; 1829 abi_ulong pc, npc, tstate;
1822 - abi_ulong fp, i7; 1830 + abi_ulong fp, i7, w_addr;
1823 unsigned char fenab; 1831 unsigned char fenab;
1824 int err; 1832 int err;
1825 unsigned int i; 1833 unsigned int i;
1826 - abi_ulong *src, *dst;  
1827 1834
  1835 + ucp_addr = env->regwptr[UREG_I0];
  1836 + if (!lock_user_struct(VERIFY_READ, ucp, ucp_addr, 1))
  1837 + goto do_sigsegv;
1828 grp = &ucp->uc_mcontext.mc_gregs; 1838 grp = &ucp->uc_mcontext.mc_gregs;
1829 err = __get_user(pc, &((*grp)[MC_PC])); 1839 err = __get_user(pc, &((*grp)[MC_PC]));
1830 err |= __get_user(npc, &((*grp)[MC_NPC])); 1840 err |= __get_user(npc, &((*grp)[MC_NPC]));
@@ -1838,11 +1848,12 @@ void sparc64_set_context(CPUSPARCState *env) @@ -1838,11 +1848,12 @@ void sparc64_set_context(CPUSPARCState *env)
1838 if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0])) 1848 if (__get_user(target_set.sig[0], &ucp->uc_sigmask.sig[0]))
1839 goto do_sigsegv; 1849 goto do_sigsegv;
1840 } else { 1850 } else {
1841 - src = &ucp->uc_sigmask;  
1842 - dst = &target_set; 1851 + abi_ulong *src, *dst;
  1852 + src = ucp->uc_sigmask.sig;
  1853 + dst = target_set.sig;
1843 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); 1854 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
1844 i++, dst++, src++) 1855 i++, dst++, src++)
1845 - err |= __get_user(dst, src); 1856 + err |= __get_user(*dst, src);
1846 if (err) 1857 if (err)
1847 goto do_sigsegv; 1858 goto do_sigsegv;
1848 } 1859 }
@@ -1874,42 +1885,53 @@ void sparc64_set_context(CPUSPARCState *env) @@ -1874,42 +1885,53 @@ void sparc64_set_context(CPUSPARCState *env)
1874 1885
1875 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp)); 1886 err |= __get_user(fp, &(ucp->uc_mcontext.mc_fp));
1876 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7)); 1887 err |= __get_user(i7, &(ucp->uc_mcontext.mc_i7));
1877 - err |= __put_user(fp,  
1878 - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));  
1879 - err |= __put_user(i7,  
1880 - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7])));  
1881 1888
  1889 + w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
  1890 + if (put_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
  1891 + abi_ulong) != 0)
  1892 + goto do_sigsegv;
  1893 + if (put_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
  1894 + abi_ulong) != 0)
  1895 + goto do_sigsegv;
1882 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab)); 1896 err |= __get_user(fenab, &(ucp->uc_mcontext.mc_fpregs.mcfpu_enab));
1883 err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs)); 1897 err |= __get_user(env->fprs, &(ucp->uc_mcontext.mc_fpregs.mcfpu_fprs));
1884 - src = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);  
1885 - dst = &env->fpr;  
1886 - for (i = 0; i < 64; i++, dst++, src++)  
1887 - err |= __get_user(dst, src); 1898 + {
  1899 + uint32_t *src, *dst;
  1900 + src = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
  1901 + dst = env->fpr;
  1902 + /* XXX: check that the CPU storage is the same as user context */
  1903 + for (i = 0; i < 64; i++, dst++, src++)
  1904 + err |= __get_user(*dst, src);
  1905 + }
1888 err |= __get_user(env->fsr, 1906 err |= __get_user(env->fsr,
1889 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr)); 1907 &(ucp->uc_mcontext.mc_fpregs.mcfpu_fsr));
1890 err |= __get_user(env->gsr, 1908 err |= __get_user(env->gsr,
1891 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr)); 1909 &(ucp->uc_mcontext.mc_fpregs.mcfpu_gsr));
1892 if (err) 1910 if (err)
1893 goto do_sigsegv; 1911 goto do_sigsegv;
1894 - 1912 + unlock_user_struct(ucp, ucp_addr, 0);
1895 return; 1913 return;
1896 do_sigsegv: 1914 do_sigsegv:
  1915 + unlock_user_struct(ucp, ucp_addr, 0);
1897 force_sig(SIGSEGV); 1916 force_sig(SIGSEGV);
1898 } 1917 }
1899 1918
1900 void sparc64_get_context(CPUSPARCState *env) 1919 void sparc64_get_context(CPUSPARCState *env)
1901 { 1920 {
1902 - struct target_ucontext *ucp = (struct target_ucontext *)  
1903 - env->regwptr[UREG_I0]; 1921 + abi_ulong ucp_addr;
  1922 + struct target_ucontext *ucp;
1904 target_mc_gregset_t *grp; 1923 target_mc_gregset_t *grp;
1905 target_mcontext_t *mcp; 1924 target_mcontext_t *mcp;
1906 - abi_ulong fp, i7; 1925 + abi_ulong fp, i7, w_addr;
1907 int err; 1926 int err;
1908 unsigned int i; 1927 unsigned int i;
1909 - abi_ulong *src, *dst;  
1910 target_sigset_t target_set; 1928 target_sigset_t target_set;
1911 sigset_t set; 1929 sigset_t set;
1912 1930
  1931 + ucp_addr = env->regwptr[UREG_I0];
  1932 + if (!lock_user_struct(VERIFY_WRITE, ucp, ucp_addr, 0))
  1933 + goto do_sigsegv;
  1934 +
1913 mcp = &ucp->uc_mcontext; 1935 mcp = &ucp->uc_mcontext;
1914 grp = &mcp->mc_gregs; 1936 grp = &mcp->mc_gregs;
1915 1937
@@ -1921,20 +1943,22 @@ void sparc64_get_context(CPUSPARCState *env) @@ -1921,20 +1943,22 @@ void sparc64_get_context(CPUSPARCState *env)
1921 1943
1922 sigprocmask(0, NULL, &set); 1944 sigprocmask(0, NULL, &set);
1923 host_to_target_sigset_internal(&target_set, &set); 1945 host_to_target_sigset_internal(&target_set, &set);
1924 - if (TARGET_NSIG_WORDS == 1) 1946 + if (TARGET_NSIG_WORDS == 1) {
1925 err |= __put_user(target_set.sig[0], 1947 err |= __put_user(target_set.sig[0],
1926 (abi_ulong *)&ucp->uc_sigmask); 1948 (abi_ulong *)&ucp->uc_sigmask);
1927 - else {  
1928 - src = &target_set;  
1929 - dst = &ucp->uc_sigmask; 1949 + } else {
  1950 + abi_ulong *src, *dst;
  1951 + src = target_set.sig;
  1952 + dst = ucp->uc_sigmask.sig;
1930 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong); 1953 for (i = 0; i < sizeof(target_sigset_t) / sizeof(abi_ulong);
1931 i++, dst++, src++) 1954 i++, dst++, src++)
1932 - err |= __put_user(src, dst); 1955 + err |= __put_user(*src, dst);
1933 if (err) 1956 if (err)
1934 goto do_sigsegv; 1957 goto do_sigsegv;
1935 } 1958 }
1936 1959
1937 - err |= __put_user(env->tstate, &((*grp)[MC_TSTATE])); 1960 + /* XXX: tstate must be saved properly */
  1961 + // err |= __put_user(env->tstate, &((*grp)[MC_TSTATE]));
1938 err |= __put_user(env->pc, &((*grp)[MC_PC])); 1962 err |= __put_user(env->pc, &((*grp)[MC_PC]));
1939 err |= __put_user(env->npc, &((*grp)[MC_NPC])); 1963 err |= __put_user(env->npc, &((*grp)[MC_NPC]));
1940 err |= __put_user(env->y, &((*grp)[MC_Y])); 1964 err |= __put_user(env->y, &((*grp)[MC_Y]));
@@ -1954,26 +1978,35 @@ void sparc64_get_context(CPUSPARCState *env) @@ -1954,26 +1978,35 @@ void sparc64_get_context(CPUSPARCState *env)
1954 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6])); 1978 err |= __put_user(env->regwptr[UREG_I6], &((*grp)[MC_O6]));
1955 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7])); 1979 err |= __put_user(env->regwptr[UREG_I7], &((*grp)[MC_O7]));
1956 1980
1957 - err |= __get_user(fp,  
1958 - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[6])));  
1959 - err |= __get_user(i7,  
1960 - (&(((struct target_reg_window *)(TARGET_STACK_BIAS+env->regwptr[UREG_I6]))->ins[7]))); 1981 + w_addr = TARGET_STACK_BIAS+env->regwptr[UREG_I6];
  1982 + fp = i7 = 0;
  1983 + if (get_user(fp, w_addr + offsetof(struct target_reg_window, ins[6]),
  1984 + abi_ulong) != 0)
  1985 + goto do_sigsegv;
  1986 + if (get_user(i7, w_addr + offsetof(struct target_reg_window, ins[7]),
  1987 + abi_ulong) != 0)
  1988 + goto do_sigsegv;
1961 err |= __put_user(fp, &(mcp->mc_fp)); 1989 err |= __put_user(fp, &(mcp->mc_fp));
1962 err |= __put_user(i7, &(mcp->mc_i7)); 1990 err |= __put_user(i7, &(mcp->mc_i7));
1963 1991
1964 - src = &env->fpr;  
1965 - dst = &(ucp->uc_mcontext.mc_fpregs.mcfpu_fregs);  
1966 - for (i = 0; i < 64; i++, dst++, src++)  
1967 - err |= __put_user(src, dst); 1992 + {
  1993 + uint32_t *src, *dst;
  1994 + src = env->fpr;
  1995 + dst = ucp->uc_mcontext.mc_fpregs.mcfpu_fregs.sregs;
  1996 + /* XXX: check that the CPU storage is the same as user context */
  1997 + for (i = 0; i < 64; i++, dst++, src++)
  1998 + err |= __put_user(*src, dst);
  1999 + }
1968 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr)); 2000 err |= __put_user(env->fsr, &(mcp->mc_fpregs.mcfpu_fsr));
1969 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr)); 2001 err |= __put_user(env->gsr, &(mcp->mc_fpregs.mcfpu_gsr));
1970 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs)); 2002 err |= __put_user(env->fprs, &(mcp->mc_fpregs.mcfpu_fprs));
1971 2003
1972 if (err) 2004 if (err)
1973 goto do_sigsegv; 2005 goto do_sigsegv;
1974 - 2006 + unlock_user_struct(ucp, ucp_addr, 1);
1975 return; 2007 return;
1976 do_sigsegv: 2008 do_sigsegv:
  2009 + unlock_user_struct(ucp, ucp_addr, 1);
1977 force_sig(SIGSEGV); 2010 force_sig(SIGSEGV);
1978 } 2011 }
1979 #endif 2012 #endif