Skip to content

Commit 4ff8a35

Browse files
author
Al Viro
committed
ia64: switch to ->regset_get()
Signed-off-by: Al Viro <[email protected]>
1 parent 5a806e0 commit 4ff8a35

File tree

1 file changed

+58
-91
lines changed

1 file changed

+58
-91
lines changed

arch/ia64/kernel/ptrace.c

Lines changed: 58 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -1489,9 +1489,17 @@ access_elf_reg(struct task_struct *target, struct unw_frame_info *info,
14891489
return access_elf_areg(target, info, addr, data, write_access);
14901490
}
14911491

1492+
struct regset_membuf {
1493+
struct membuf to;
1494+
int ret;
1495+
};
1496+
14921497
void do_gpregs_get(struct unw_frame_info *info, void *arg)
14931498
{
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;
14951503

14961504
if (unw_unwind_to_user(info) < 0)
14971505
return;
@@ -1509,35 +1517,13 @@ void do_gpregs_get(struct unw_frame_info *info, void *arg)
15091517

15101518

15111519
/* 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;
15181524
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-
}
15351525
}
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);
15411527
}
15421528
}
15431529

@@ -1588,60 +1574,36 @@ void do_gpregs_set(struct unw_frame_info *info, void *arg)
15881574

15891575
void do_fpregs_get(struct unw_frame_info *info, void *arg)
15901576
{
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;
15951582

15961583
if (unw_unwind_to_user(info) < 0)
15971584
return;
15981585

15991586
/* 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));
16081588

16091589
/* 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;
16261593
return;
1594+
}
1595+
membuf_write(&to, &reg, sizeof(reg));
16271596
}
16281597

16291598
/* 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));
16451607
}
16461608

16471609
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)
17171679
}
17181680
}
17191681

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+
17201696
static int
17211697
do_regset_call(void (*call)(struct unw_frame_info *, void *),
17221698
struct task_struct *target,
@@ -1728,27 +1704,18 @@ do_regset_call(void (*call)(struct unw_frame_info *, void *),
17281704
.pos = pos, .count = count,
17291705
.u.set = { .kbuf = kbuf, .ubuf = ubuf },
17301706
.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);
17411708
return info.ret;
17421709
}
17431710

17441711
static int
17451712
gpregs_get(struct task_struct *target,
17461713
const struct user_regset *regset,
1747-
unsigned int pos, unsigned int count,
1748-
void *kbuf, void __user *ubuf)
1714+
struct membuf to)
17491715
{
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;
17521719
}
17531720

17541721
static int gpregs_set(struct task_struct *target,
@@ -1790,11 +1757,11 @@ fpregs_active(struct task_struct *target, const struct user_regset *regset)
17901757

17911758
static int fpregs_get(struct task_struct *target,
17921759
const struct user_regset *regset,
1793-
unsigned int pos, unsigned int count,
1794-
void *kbuf, void __user *ubuf)
1760+
struct membuf to)
17951761
{
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;
17981765
}
17991766

18001767
static int fpregs_set(struct task_struct *target,
@@ -2033,14 +2000,14 @@ static const struct user_regset native_regsets[] = {
20332000
.core_note_type = NT_PRSTATUS,
20342001
.n = ELF_NGREG,
20352002
.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,
20372004
.writeback = gpregs_writeback
20382005
},
20392006
{
20402007
.core_note_type = NT_PRFPREG,
20412008
.n = ELF_NFPREG,
20422009
.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
20442011
},
20452012
};
20462013

0 commit comments

Comments
 (0)