@@ -1489,9 +1489,17 @@ access_elf_reg(struct task_struct *target, struct unw_frame_info *info,
1489
1489
return access_elf_areg (target , info , addr , data , write_access );
1490
1490
}
1491
1491
1492
+ struct regset_membuf {
1493
+ struct membuf to ;
1494
+ int ret ;
1495
+ };
1496
+
1492
1497
void do_gpregs_get (struct unw_frame_info * info , void * arg )
1493
1498
{
1494
- struct regset_getset * dst = arg ;
1499
+ struct regset_membuf * dst = arg ;
1500
+ struct membuf to = dst -> to ;
1501
+ unsigned int n ;
1502
+ elf_greg_t reg ;
1495
1503
1496
1504
if (unw_unwind_to_user (info ) < 0 )
1497
1505
return ;
@@ -1509,35 +1517,13 @@ void do_gpregs_get(struct unw_frame_info *info, void *arg)
1509
1517
1510
1518
1511
1519
/* Skip r0 */
1512
- if (dst -> count > 0 && dst -> pos < ELF_GR_OFFSET (1 )) {
1513
- dst -> ret = user_regset_copyout_zero (& dst -> pos , & dst -> count ,
1514
- & dst -> u .get .kbuf ,
1515
- & dst -> u .get .ubuf ,
1516
- 0 , ELF_GR_OFFSET (1 ));
1517
- if (dst -> ret )
1520
+ membuf_zero (& to , 8 );
1521
+ for (n = 8 ; to .left && n < ELF_AR_END_OFFSET ; n += 8 ) {
1522
+ if (access_elf_reg (info -> task , info , n , & reg , 0 ) < 0 ) {
1523
+ dst -> ret = - EIO ;
1518
1524
return ;
1519
- }
1520
-
1521
- while (dst -> count && dst -> pos < ELF_AR_END_OFFSET ) {
1522
- unsigned int n , from , to ;
1523
- elf_greg_t tmp [16 ];
1524
-
1525
- from = dst -> pos ;
1526
- to = from + min (dst -> count , (unsigned )sizeof (tmp ));
1527
- if (to > ELF_AR_END_OFFSET )
1528
- to = ELF_AR_END_OFFSET ;
1529
- for (n = 0 ; from < to ; from += sizeof (elf_greg_t ), n ++ ) {
1530
- if (access_elf_reg (dst -> target , info , from ,
1531
- & tmp [n ], 0 ) < 0 ) {
1532
- dst -> ret = - EIO ;
1533
- return ;
1534
- }
1535
1525
}
1536
- dst -> ret = user_regset_copyout (& dst -> pos , & dst -> count ,
1537
- & dst -> u .get .kbuf , & dst -> u .get .ubuf , tmp ,
1538
- dst -> pos , to );
1539
- if (dst -> ret )
1540
- return ;
1526
+ membuf_store (& to , reg );
1541
1527
}
1542
1528
}
1543
1529
@@ -1588,60 +1574,36 @@ void do_gpregs_set(struct unw_frame_info *info, void *arg)
1588
1574
1589
1575
void do_fpregs_get (struct unw_frame_info * info , void * arg )
1590
1576
{
1591
- struct regset_getset * dst = arg ;
1592
- struct task_struct * task = dst -> target ;
1593
- elf_fpreg_t tmp [30 ];
1594
- int index , min_copy , i ;
1577
+ struct task_struct * task = info -> task ;
1578
+ struct regset_membuf * dst = arg ;
1579
+ struct membuf to = dst -> to ;
1580
+ elf_fpreg_t reg ;
1581
+ unsigned int n ;
1595
1582
1596
1583
if (unw_unwind_to_user (info ) < 0 )
1597
1584
return ;
1598
1585
1599
1586
/* Skip pos 0 and 1 */
1600
- if (dst -> count > 0 && dst -> pos < ELF_FP_OFFSET (2 )) {
1601
- dst -> ret = user_regset_copyout_zero (& dst -> pos , & dst -> count ,
1602
- & dst -> u .get .kbuf ,
1603
- & dst -> u .get .ubuf ,
1604
- 0 , ELF_FP_OFFSET (2 ));
1605
- if (dst -> count == 0 || dst -> ret )
1606
- return ;
1607
- }
1587
+ membuf_zero (& to , 2 * sizeof (elf_fpreg_t ));
1608
1588
1609
1589
/* fr2-fr31 */
1610
- if (dst -> count > 0 && dst -> pos < ELF_FP_OFFSET (32 )) {
1611
- index = (dst -> pos - ELF_FP_OFFSET (2 )) / sizeof (elf_fpreg_t );
1612
-
1613
- min_copy = min (((unsigned int )ELF_FP_OFFSET (32 )),
1614
- dst -> pos + dst -> count );
1615
- for (i = dst -> pos ; i < min_copy ; i += sizeof (elf_fpreg_t ),
1616
- index ++ )
1617
- if (unw_get_fr (info , i / sizeof (elf_fpreg_t ),
1618
- & tmp [index ])) {
1619
- dst -> ret = - EIO ;
1620
- return ;
1621
- }
1622
- dst -> ret = user_regset_copyout (& dst -> pos , & dst -> count ,
1623
- & dst -> u .get .kbuf , & dst -> u .get .ubuf , tmp ,
1624
- ELF_FP_OFFSET (2 ), ELF_FP_OFFSET (32 ));
1625
- if (dst -> count == 0 || dst -> ret )
1590
+ for (n = 2 ; to .left && n < 32 ; n ++ ) {
1591
+ if (unw_get_fr (info , n , & reg )) {
1592
+ dst -> ret = - EIO ;
1626
1593
return ;
1594
+ }
1595
+ membuf_write (& to , & reg , sizeof (reg ));
1627
1596
}
1628
1597
1629
1598
/* fph */
1630
- if (dst -> count > 0 ) {
1631
- ia64_flush_fph (dst -> target );
1632
- if (task -> thread .flags & IA64_THREAD_FPH_VALID )
1633
- dst -> ret = user_regset_copyout (
1634
- & dst -> pos , & dst -> count ,
1635
- & dst -> u .get .kbuf , & dst -> u .get .ubuf ,
1636
- & dst -> target -> thread .fph ,
1637
- ELF_FP_OFFSET (32 ), -1 );
1638
- else
1639
- /* Zero fill instead. */
1640
- dst -> ret = user_regset_copyout_zero (
1641
- & dst -> pos , & dst -> count ,
1642
- & dst -> u .get .kbuf , & dst -> u .get .ubuf ,
1643
- ELF_FP_OFFSET (32 ), -1 );
1644
- }
1599
+ if (!to .left )
1600
+ return ;
1601
+
1602
+ ia64_flush_fph (task );
1603
+ if (task -> thread .flags & IA64_THREAD_FPH_VALID )
1604
+ membuf_write (& to , & task -> thread .fph , 96 * sizeof (reg ));
1605
+ else
1606
+ membuf_zero (& to , 96 * sizeof (reg ));
1645
1607
}
1646
1608
1647
1609
void do_fpregs_set (struct unw_frame_info * info , void * arg )
@@ -1717,6 +1679,20 @@ void do_fpregs_set(struct unw_frame_info *info, void *arg)
1717
1679
}
1718
1680
}
1719
1681
1682
+ static void
1683
+ unwind_and_call (void (* call )(struct unw_frame_info * , void * ),
1684
+ struct task_struct * target , void * data )
1685
+ {
1686
+ if (target == current )
1687
+ unw_init_running (call , data );
1688
+ else {
1689
+ struct unw_frame_info info ;
1690
+ memset (& info , 0 , sizeof (info ));
1691
+ unw_init_from_blocked_task (& info , target );
1692
+ (* call )(& info , data );
1693
+ }
1694
+ }
1695
+
1720
1696
static int
1721
1697
do_regset_call (void (* call )(struct unw_frame_info * , void * ),
1722
1698
struct task_struct * target ,
@@ -1728,27 +1704,18 @@ do_regset_call(void (*call)(struct unw_frame_info *, void *),
1728
1704
.pos = pos , .count = count ,
1729
1705
.u .set = { .kbuf = kbuf , .ubuf = ubuf },
1730
1706
.ret = 0 };
1731
-
1732
- if (target == current )
1733
- unw_init_running (call , & info );
1734
- else {
1735
- struct unw_frame_info ufi ;
1736
- memset (& ufi , 0 , sizeof (ufi ));
1737
- unw_init_from_blocked_task (& ufi , target );
1738
- (* call )(& ufi , & info );
1739
- }
1740
-
1707
+ unwind_and_call (call , target , & info );
1741
1708
return info .ret ;
1742
1709
}
1743
1710
1744
1711
static int
1745
1712
gpregs_get (struct task_struct * target ,
1746
1713
const struct user_regset * regset ,
1747
- unsigned int pos , unsigned int count ,
1748
- void * kbuf , void __user * ubuf )
1714
+ struct membuf to )
1749
1715
{
1750
- return do_regset_call (do_gpregs_get , target , regset , pos , count ,
1751
- kbuf , ubuf );
1716
+ struct regset_membuf info = {.to = to };
1717
+ unwind_and_call (do_gpregs_get , target , & info );
1718
+ return info .ret ;
1752
1719
}
1753
1720
1754
1721
static int gpregs_set (struct task_struct * target ,
@@ -1790,11 +1757,11 @@ fpregs_active(struct task_struct *target, const struct user_regset *regset)
1790
1757
1791
1758
static int fpregs_get (struct task_struct * target ,
1792
1759
const struct user_regset * regset ,
1793
- unsigned int pos , unsigned int count ,
1794
- void * kbuf , void __user * ubuf )
1760
+ struct membuf to )
1795
1761
{
1796
- return do_regset_call (do_fpregs_get , target , regset , pos , count ,
1797
- kbuf , ubuf );
1762
+ struct regset_membuf info = {.to = to };
1763
+ unwind_and_call (do_fpregs_get , target , & info );
1764
+ return info .ret ;
1798
1765
}
1799
1766
1800
1767
static int fpregs_set (struct task_struct * target ,
@@ -2033,14 +2000,14 @@ static const struct user_regset native_regsets[] = {
2033
2000
.core_note_type = NT_PRSTATUS ,
2034
2001
.n = ELF_NGREG ,
2035
2002
.size = sizeof (elf_greg_t ), .align = sizeof (elf_greg_t ),
2036
- .get = gpregs_get , .set = gpregs_set ,
2003
+ .regset_get = gpregs_get , .set = gpregs_set ,
2037
2004
.writeback = gpregs_writeback
2038
2005
},
2039
2006
{
2040
2007
.core_note_type = NT_PRFPREG ,
2041
2008
.n = ELF_NFPREG ,
2042
2009
.size = sizeof (elf_fpreg_t ), .align = sizeof (elf_fpreg_t ),
2043
- .get = fpregs_get , .set = fpregs_set , .active = fpregs_active
2010
+ .regset_get = fpregs_get , .set = fpregs_set , .active = fpregs_active
2044
2011
},
2045
2012
};
2046
2013
0 commit comments