@@ -1811,7 +1811,6 @@ access_uarea(struct task_struct *child, unsigned long addr,
1811
1811
unsigned long * data , int write_access )
1812
1812
{
1813
1813
unsigned int pos = -1 ; /* an invalid value */
1814
- int ret ;
1815
1814
unsigned long * ptr , regnum ;
1816
1815
1817
1816
if ((addr & 0x7 ) != 0 ) {
@@ -1843,14 +1842,39 @@ access_uarea(struct task_struct *child, unsigned long addr,
1843
1842
}
1844
1843
1845
1844
if (pos != -1 ) {
1846
- if (write_access )
1847
- ret = fpregs_set (child , NULL , pos ,
1848
- sizeof (unsigned long ), data , NULL );
1849
- else
1850
- ret = fpregs_get (child , NULL , pos ,
1851
- sizeof (unsigned long ), data , NULL );
1852
- if (ret != 0 )
1853
- return -1 ;
1845
+ unsigned reg = pos / sizeof (elf_fpreg_t );
1846
+ int which_half = (pos / sizeof (unsigned long )) & 1 ;
1847
+
1848
+ if (reg < 32 ) { /* fr2-fr31 */
1849
+ struct unw_frame_info info ;
1850
+ elf_fpreg_t fpreg ;
1851
+
1852
+ memset (& info , 0 , sizeof (info ));
1853
+ unw_init_from_blocked_task (& info , child );
1854
+ if (unw_unwind_to_user (& info ) < 0 )
1855
+ return 0 ;
1856
+
1857
+ if (unw_get_fr (& info , reg , & fpreg ))
1858
+ return -1 ;
1859
+ if (write_access ) {
1860
+ fpreg .u .bits [which_half ] = * data ;
1861
+ if (unw_set_fr (& info , reg , fpreg ))
1862
+ return -1 ;
1863
+ } else {
1864
+ * data = fpreg .u .bits [which_half ];
1865
+ }
1866
+ } else { /* fph */
1867
+ elf_fpreg_t * p = & child -> thread .fph [reg - 32 ];
1868
+ unsigned long * bits = & p -> u .bits [which_half ];
1869
+
1870
+ ia64_sync_fph (child );
1871
+ if (write_access )
1872
+ * bits = * data ;
1873
+ else if (child -> thread .flags & IA64_THREAD_FPH_VALID )
1874
+ * data = * bits ;
1875
+ else
1876
+ * data = 0 ;
1877
+ }
1854
1878
return 0 ;
1855
1879
}
1856
1880
0 commit comments