]> Pileus Git - ~andy/linux/blobdiff - arch/arm64/kernel/ptrace.c
arm64: ptrace: avoid using HW_BREAKPOINT_EMPTY for disabled events
[~andy/linux] / arch / arm64 / kernel / ptrace.c
index fecdbf7de82e9a94d6f467f5999428cfcf623145..6a8928bba03c9e8135c4481b497268f7018ca393 100644 (file)
@@ -214,31 +214,29 @@ static int ptrace_hbp_fill_attr_ctrl(unsigned int note_type,
 {
        int err, len, type, disabled = !ctrl.enabled;
 
-       if (disabled) {
-               len = 0;
-               type = HW_BREAKPOINT_EMPTY;
-       } else {
-               err = arch_bp_generic_fields(ctrl, &len, &type);
-               if (err)
-                       return err;
-
-               switch (note_type) {
-               case NT_ARM_HW_BREAK:
-                       if ((type & HW_BREAKPOINT_X) != type)
-                               return -EINVAL;
-                       break;
-               case NT_ARM_HW_WATCH:
-                       if ((type & HW_BREAKPOINT_RW) != type)
-                               return -EINVAL;
-                       break;
-               default:
+       attr->disabled = disabled;
+       if (disabled)
+               return 0;
+
+       err = arch_bp_generic_fields(ctrl, &len, &type);
+       if (err)
+               return err;
+
+       switch (note_type) {
+       case NT_ARM_HW_BREAK:
+               if ((type & HW_BREAKPOINT_X) != type)
                        return -EINVAL;
-               }
+               break;
+       case NT_ARM_HW_WATCH:
+               if ((type & HW_BREAKPOINT_RW) != type)
+                       return -EINVAL;
+               break;
+       default:
+               return -EINVAL;
        }
 
        attr->bp_len    = len;
        attr->bp_type   = type;
-       attr->disabled  = disabled;
 
        return 0;
 }
@@ -636,28 +634,27 @@ static int compat_gpr_get(struct task_struct *target,
 
        for (i = 0; i < num_regs; ++i) {
                unsigned int idx = start + i;
-               void *reg;
+               compat_ulong_t reg;
 
                switch (idx) {
                case 15:
-                       reg = (void *)&task_pt_regs(target)->pc;
+                       reg = task_pt_regs(target)->pc;
                        break;
                case 16:
-                       reg = (void *)&task_pt_regs(target)->pstate;
+                       reg = task_pt_regs(target)->pstate;
                        break;
                case 17:
-                       reg = (void *)&task_pt_regs(target)->orig_x0;
+                       reg = task_pt_regs(target)->orig_x0;
                        break;
                default:
-                       reg = (void *)&task_pt_regs(target)->regs[idx];
+                       reg = task_pt_regs(target)->regs[idx];
                }
 
-               ret = copy_to_user(ubuf, reg, sizeof(compat_ulong_t));
-
+               ret = copy_to_user(ubuf, &reg, sizeof(reg));
                if (ret)
                        break;
-               else
-                       ubuf += sizeof(compat_ulong_t);
+
+               ubuf += sizeof(reg);
        }
 
        return ret;
@@ -685,28 +682,28 @@ static int compat_gpr_set(struct task_struct *target,
 
        for (i = 0; i < num_regs; ++i) {
                unsigned int idx = start + i;
-               void *reg;
+               compat_ulong_t reg;
+
+               ret = copy_from_user(&reg, ubuf, sizeof(reg));
+               if (ret)
+                       return ret;
+
+               ubuf += sizeof(reg);
 
                switch (idx) {
                case 15:
-                       reg = (void *)&newregs.pc;
+                       newregs.pc = reg;
                        break;
                case 16:
-                       reg = (void *)&newregs.pstate;
+                       newregs.pstate = reg;
                        break;
                case 17:
-                       reg = (void *)&newregs.orig_x0;
+                       newregs.orig_x0 = reg;
                        break;
                default:
-                       reg = (void *)&newregs.regs[idx];
+                       newregs.regs[idx] = reg;
                }
 
-               ret = copy_from_user(reg, ubuf, sizeof(compat_ulong_t));
-
-               if (ret)
-                       goto out;
-               else
-                       ubuf += sizeof(compat_ulong_t);
        }
 
        if (valid_user_regs(&newregs.user_regs))
@@ -714,7 +711,6 @@ static int compat_gpr_set(struct task_struct *target,
        else
                ret = -EINVAL;
 
-out:
        return ret;
 }