[ia64] ptrace_[sg]etregs(): use access_elf_reg() instead of access_uarea()
authorAl Viro <viro@zeniv.linux.org.uk>
Sat, 6 Jun 2020 16:59:11 +0000 (12:59 -0400)
committerAl Viro <viro@zeniv.linux.org.uk>
Mon, 26 Oct 2020 00:03:04 +0000 (20:03 -0400)
In case of positions passed by ptrace_[sg]etregs() to access_uarea()
the latter sets the stack unwind up, walks all the way up the stack
and proceeds to pass the resulting info to access_elf_reg().  The thing
is, we'd *already* obtained that info, so we can bloody well call
access_elf_reg() directly.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
arch/ia64/kernel/ptrace.c

index 96f0852..c3490ee 100644 (file)
@@ -817,8 +817,8 @@ access_nat_bits (struct task_struct *child, struct pt_regs *pt,
 }
 
 static int
-access_uarea (struct task_struct *child, unsigned long addr,
-             unsigned long *data, int write_access);
+access_elf_reg(struct task_struct *target, struct unw_frame_info *info,
+               unsigned long addr, unsigned long *data, int write_access);
 
 static long
 ptrace_getregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
@@ -847,13 +847,13 @@ ptrace_getregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
                return -EIO;
        }
 
-       if (access_uarea(child, PT_CR_IPSR, &psr, 0) < 0
-           || access_uarea(child, PT_AR_EC, &ec, 0) < 0
-           || access_uarea(child, PT_AR_LC, &lc, 0) < 0
-           || access_uarea(child, PT_AR_RNAT, &rnat, 0) < 0
-           || access_uarea(child, PT_AR_BSP, &bsp, 0) < 0
-           || access_uarea(child, PT_CFM, &cfm, 0)
-           || access_uarea(child, PT_NAT_BITS, &nat_bits, 0))
+       if (access_elf_reg(child, &info, ELF_CR_IPSR_OFFSET, &psr, 0) < 0 ||
+           access_elf_reg(child, &info, ELF_AR_EC_OFFSET, &ec, 0) < 0 ||
+           access_elf_reg(child, &info, ELF_AR_LC_OFFSET, &lc, 0) < 0 ||
+           access_elf_reg(child, &info, ELF_AR_RNAT_OFFSET, &rnat, 0) < 0 ||
+           access_elf_reg(child, &info, ELF_AR_BSP_OFFSET, &bsp, 0) < 0 ||
+           access_elf_reg(child, &info, ELF_CFM_OFFSET, &cfm, 0) < 0 ||
+           access_elf_reg(child, &info, ELF_NAT_OFFSET, &nat_bits, 0) < 0)
                return -EIO;
 
        /* control regs */
@@ -972,7 +972,7 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
        struct switch_stack *sw;
        struct ia64_fpreg fpval;
        struct pt_regs *pt;
-       long ret, retval = 0;
+       long retval = 0;
        int i;
 
        memset(&fpval, 0, sizeof(fpval));
@@ -1097,17 +1097,16 @@ ptrace_setregs (struct task_struct *child, struct pt_all_user_regs __user *ppr)
 
        retval |= __get_user(nat_bits, &ppr->nat);
 
-       retval |= access_uarea(child, PT_CR_IPSR, &psr, 1);
-       retval |= access_uarea(child, PT_AR_RSC, &rsc, 1);
-       retval |= access_uarea(child, PT_AR_EC, &ec, 1);
-       retval |= access_uarea(child, PT_AR_LC, &lc, 1);
-       retval |= access_uarea(child, PT_AR_RNAT, &rnat, 1);
-       retval |= access_uarea(child, PT_AR_BSP, &bsp, 1);
-       retval |= access_uarea(child, PT_CFM, &cfm, 1);
-       retval |= access_uarea(child, PT_NAT_BITS, &nat_bits, 1);
+       retval |= access_elf_reg(child, &info, ELF_CR_IPSR_OFFSET, &psr, 1);
+       retval |= access_elf_reg(child, &info, ELF_AR_RSC_OFFSET, &rsc, 1);
+       retval |= access_elf_reg(child, &info, ELF_AR_EC_OFFSET, &ec, 1);
+       retval |= access_elf_reg(child, &info, ELF_AR_LC_OFFSET, &lc, 1);
+       retval |= access_elf_reg(child, &info, ELF_AR_RNAT_OFFSET, &rnat, 1);
+       retval |= access_elf_reg(child, &info, ELF_AR_BSP_OFFSET, &bsp, 1);
+       retval |= access_elf_reg(child, &info, ELF_CFM_OFFSET, &cfm, 1);
+       retval |= access_elf_reg(child, &info, ELF_NAT_OFFSET, &nat_bits, 1);
 
-       ret = retval ? -EIO : 0;
-       return ret;
+       return retval ? -EIO : 0;
 }
 
 void
@@ -1150,6 +1149,10 @@ ptrace_disable (struct task_struct *child)
        user_disable_single_step(child);
 }
 
+static int
+access_uarea (struct task_struct *child, unsigned long addr,
+             unsigned long *data, int write_access);
+
 long
 arch_ptrace (struct task_struct *child, long request,
             unsigned long addr, unsigned long data)