get:
Show a patch.

patch:
Update a patch.

put:
Update a patch.

GET /api/patches/805445/?format=api
HTTP 200 OK
Allow: GET, PUT, PATCH, HEAD, OPTIONS
Content-Type: application/json
Vary: Accept

{
    "id": 805445,
    "url": "http://patchwork.ozlabs.org/api/patches/805445/?format=api",
    "web_url": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/1503571797-16885-1-git-send-email-mpe@ellerman.id.au/",
    "project": {
        "id": 2,
        "url": "http://patchwork.ozlabs.org/api/projects/2/?format=api",
        "name": "Linux PPC development",
        "link_name": "linuxppc-dev",
        "list_id": "linuxppc-dev.lists.ozlabs.org",
        "list_email": "linuxppc-dev@lists.ozlabs.org",
        "web_url": "https://github.com/linuxppc/wiki/wiki",
        "scm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git",
        "webscm_url": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/",
        "list_archive_url": "https://lore.kernel.org/linuxppc-dev/",
        "list_archive_url_format": "https://lore.kernel.org/linuxppc-dev/{}/",
        "commit_url_format": "https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git/commit/?id={}"
    },
    "msgid": "<1503571797-16885-1-git-send-email-mpe@ellerman.id.au>",
    "list_archive_url": "https://lore.kernel.org/linuxppc-dev/1503571797-16885-1-git-send-email-mpe@ellerman.id.au/",
    "date": "2017-08-24T10:49:57",
    "name": "powerpc: Fix DAR reporting when alignment handler faults",
    "commit_ref": "f9effe925039cf54489b5c04e0d40073bb3a123d",
    "pull_url": null,
    "state": "accepted",
    "archived": false,
    "hash": "3f8e7768393544787fd73b83faba3140fdf0a5d0",
    "submitter": {
        "id": 46580,
        "url": "http://patchwork.ozlabs.org/api/people/46580/?format=api",
        "name": "Michael Ellerman",
        "email": "mpe@ellerman.id.au"
    },
    "delegate": null,
    "mbox": "http://patchwork.ozlabs.org/project/linuxppc-dev/patch/1503571797-16885-1-git-send-email-mpe@ellerman.id.au/mbox/",
    "series": [],
    "comments": "http://patchwork.ozlabs.org/api/patches/805445/comments/",
    "check": "pending",
    "checks": "http://patchwork.ozlabs.org/api/patches/805445/checks/",
    "tags": {},
    "related": [],
    "headers": {
        "Return-Path": "<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>",
        "X-Original-To": [
            "patchwork-incoming@ozlabs.org",
            "linuxppc-dev@lists.ozlabs.org"
        ],
        "Delivered-To": [
            "patchwork-incoming@ozlabs.org",
            "linuxppc-dev@lists.ozlabs.org",
            "linuxppc-dev@ozlabs.org"
        ],
        "Received": [
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby ozlabs.org (Postfix) with ESMTPS id 3xdLgq3djzz9s65\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu, 24 Aug 2017 20:51:19 +1000 (AEST)",
            "from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3])\n\tby lists.ozlabs.org (Postfix) with ESMTP id 3xdLgq2gHwzDrLW\n\tfor <patchwork-incoming@ozlabs.org>;\n\tThu, 24 Aug 2017 20:51:19 +1000 (AEST)",
            "from ozlabs.org (ozlabs.org [IPv6:2401:3900:2:1::2])\n\t(using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby lists.ozlabs.org (Postfix) with ESMTPS id 3xdLfM2hSTzDrJx\n\tfor <linuxppc-dev@lists.ozlabs.org>;\n\tThu, 24 Aug 2017 20:50:03 +1000 (AEST)",
            "by ozlabs.org (Postfix)\n\tid 3xdLfM1mGfz9s65; Thu, 24 Aug 2017 20:50:03 +1000 (AEST)",
            "by ozlabs.org (Postfix, from userid 1034)\n\tid 3xdLfM1Jmdz9sPk; Thu, 24 Aug 2017 20:50:03 +1000 (AEST)"
        ],
        "From": "Michael Ellerman <mpe@ellerman.id.au>",
        "To": "linuxppc-dev@ozlabs.org",
        "Subject": "[PATCH] powerpc: Fix DAR reporting when alignment handler faults",
        "Date": "Thu, 24 Aug 2017 20:49:57 +1000",
        "Message-Id": "<1503571797-16885-1-git-send-email-mpe@ellerman.id.au>",
        "X-Mailer": "git-send-email 2.7.4",
        "X-BeenThere": "linuxppc-dev@lists.ozlabs.org",
        "X-Mailman-Version": "2.1.23",
        "Precedence": "list",
        "List-Id": "Linux on PowerPC Developers Mail List\n\t<linuxppc-dev.lists.ozlabs.org>",
        "List-Unsubscribe": "<https://lists.ozlabs.org/options/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=unsubscribe>",
        "List-Archive": "<http://lists.ozlabs.org/pipermail/linuxppc-dev/>",
        "List-Post": "<mailto:linuxppc-dev@lists.ozlabs.org>",
        "List-Help": "<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=help>",
        "List-Subscribe": "<https://lists.ozlabs.org/listinfo/linuxppc-dev>,\n\t<mailto:linuxppc-dev-request@lists.ozlabs.org?subject=subscribe>",
        "Cc": "paulus@samba.org, anton@samba.org",
        "Errors-To": "linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org",
        "Sender": "\"Linuxppc-dev\"\n\t<linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org>"
    },
    "content": "Anton noticed that if we fault part way through emulating an unaligned\ninstruction, we don't update the DAR to reflect that.\n\nThe DAR value is eventually reported back to userspace as the address\nin the SEGV signal, and if userspace is using that value to demand\nfault then it can be confused by us not setting the value correctly.\n\nThis patch is ugly as hell, but is intended to be the minimal fix and\nback ports easily.\n\nSigned-off-by: Michael Ellerman <mpe@ellerman.id.au>\n---\n arch/powerpc/kernel/align.c | 119 +++++++++++++++++++++++++++-----------------\n 1 file changed, 74 insertions(+), 45 deletions(-)",
    "diff": "diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c\nindex ec7a8b099dd9..fd3c1fcc73eb 100644\n--- a/arch/powerpc/kernel/align.c\n+++ b/arch/powerpc/kernel/align.c\n@@ -235,6 +235,28 @@ static int emulate_dcbz(struct pt_regs *regs, unsigned char __user *addr)\n \n #define SWIZ_PTR(p)\t\t((unsigned char __user *)((p) ^ swiz))\n \n+#define __get_user_or_set_dar(_regs, _dest, _addr)\t\t\\\n+\t({\t\t\t\t\t\t\t\\\n+\t\tint rc = 0;\t\t\t\t\t\\\n+\t\ttypeof(_addr) __addr = (_addr);\t\t\t\\\n+\t\tif (__get_user_inatomic(_dest, __addr)) {\t\\\n+\t\t\t_regs->dar = (unsigned long)__addr;\t\\\n+\t\t\trc = -EFAULT;\t\t\t\t\\\n+\t\t}\t\t\t\t\t\t\\\n+\t\trc;\t\t\t\t\t\t\\\n+\t})\n+\n+#define __put_user_or_set_dar(_regs, _src, _addr)\t\t\\\n+\t({\t\t\t\t\t\t\t\\\n+\t\tint rc = 0;\t\t\t\t\t\\\n+\t\ttypeof(_addr) __addr = (_addr);\t\t\t\\\n+\t\tif (__put_user_inatomic(_src, __addr)) {\t\\\n+\t\t\t_regs->dar = (unsigned long)__addr;\t\\\n+\t\t\trc = -EFAULT;\t\t\t\t\\\n+\t\t}\t\t\t\t\t\t\\\n+\t\trc;\t\t\t\t\t\t\\\n+\t})\n+\n static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,\n \t\t\t    unsigned int reg, unsigned int nb,\n \t\t\t    unsigned int flags, unsigned int instr,\n@@ -263,9 +285,10 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,\n \t\t} else {\n \t\t\tunsigned long pc = regs->nip ^ (swiz & 4);\n \n-\t\t\tif (__get_user_inatomic(instr,\n-\t\t\t\t\t\t(unsigned int __user *)pc))\n+\t\t\tif (__get_user_or_set_dar(regs, instr,\n+\t\t\t\t\t\t  (unsigned int __user *)pc))\n \t\t\t\treturn -EFAULT;\n+\n \t\t\tif (swiz == 0 && (flags & SW))\n \t\t\t\tinstr = cpu_to_le32(instr);\n \t\t\tnb = (instr >> 11) & 0x1f;\n@@ -309,31 +332,31 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,\n \t\t\t       ((nb0 + 3) / 4) * sizeof(unsigned long));\n \n \t\tfor (i = 0; i < nb; ++i, ++p)\n-\t\t\tif (__get_user_inatomic(REG_BYTE(rptr, i ^ bswiz),\n-\t\t\t\t\t\tSWIZ_PTR(p)))\n+\t\t\tif (__get_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz),\n+\t\t\t\t\t\t  SWIZ_PTR(p)))\n \t\t\t\treturn -EFAULT;\n \t\tif (nb0 > 0) {\n \t\t\trptr = &regs->gpr[0];\n \t\t\taddr += nb;\n \t\t\tfor (i = 0; i < nb0; ++i, ++p)\n-\t\t\t\tif (__get_user_inatomic(REG_BYTE(rptr,\n-\t\t\t\t\t\t\t\t i ^ bswiz),\n-\t\t\t\t\t\t\tSWIZ_PTR(p)))\n+\t\t\t\tif (__get_user_or_set_dar(regs,\n+\t\t\t\t\t\t\t  REG_BYTE(rptr, i ^ bswiz),\n+\t\t\t\t\t\t\t  SWIZ_PTR(p)))\n \t\t\t\t\treturn -EFAULT;\n \t\t}\n \n \t} else {\n \t\tfor (i = 0; i < nb; ++i, ++p)\n-\t\t\tif (__put_user_inatomic(REG_BYTE(rptr, i ^ bswiz),\n-\t\t\t\t\t\tSWIZ_PTR(p)))\n+\t\t\tif (__put_user_or_set_dar(regs, REG_BYTE(rptr, i ^ bswiz),\n+\t\t\t\t\t\t  SWIZ_PTR(p)))\n \t\t\t\treturn -EFAULT;\n \t\tif (nb0 > 0) {\n \t\t\trptr = &regs->gpr[0];\n \t\t\taddr += nb;\n \t\t\tfor (i = 0; i < nb0; ++i, ++p)\n-\t\t\t\tif (__put_user_inatomic(REG_BYTE(rptr,\n-\t\t\t\t\t\t\t\t i ^ bswiz),\n-\t\t\t\t\t\t\tSWIZ_PTR(p)))\n+\t\t\t\tif (__put_user_or_set_dar(regs,\n+\t\t\t\t\t\t\t  REG_BYTE(rptr, i ^ bswiz),\n+\t\t\t\t\t\t\t  SWIZ_PTR(p)))\n \t\t\t\t\treturn -EFAULT;\n \t\t}\n \t}\n@@ -345,29 +368,32 @@ static int emulate_multiple(struct pt_regs *regs, unsigned char __user *addr,\n  * Only POWER6 has these instructions, and it does true little-endian,\n  * so we don't need the address swizzling.\n  */\n-static int emulate_fp_pair(unsigned char __user *addr, unsigned int reg,\n-\t\t\t   unsigned int flags)\n+static int emulate_fp_pair(struct pt_regs *regs, unsigned char __user *addr,\n+\t\t\t   unsigned int reg, unsigned int flags)\n {\n \tchar *ptr0 = (char *) &current->thread.TS_FPR(reg);\n \tchar *ptr1 = (char *) &current->thread.TS_FPR(reg+1);\n-\tint i, ret, sw = 0;\n+\tint i, sw = 0;\n \n \tif (reg & 1)\n \t\treturn 0;\t/* invalid form: FRS/FRT must be even */\n \tif (flags & SW)\n \t\tsw = 7;\n-\tret = 0;\n+\n \tfor (i = 0; i < 8; ++i) {\n \t\tif (!(flags & ST)) {\n-\t\t\tret |= __get_user(ptr0[i^sw], addr + i);\n-\t\t\tret |= __get_user(ptr1[i^sw], addr + i + 8);\n+\t\t\tif (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i))\n+\t\t\t\treturn -EFAULT;\n+\t\t\tif (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))\n+\t\t\t\treturn -EFAULT;\n \t\t} else {\n-\t\t\tret |= __put_user(ptr0[i^sw], addr + i);\n-\t\t\tret |= __put_user(ptr1[i^sw], addr + i + 8);\n+\t\t\tif (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i))\n+\t\t\t\treturn -EFAULT;\n+\t\t\tif (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))\n+\t\t\t\treturn -EFAULT;\n \t\t}\n \t}\n-\tif (ret)\n-\t\treturn -EFAULT;\n+\n \treturn 1;\t/* exception handled and fixed up */\n }\n \n@@ -377,24 +403,27 @@ static int emulate_lq_stq(struct pt_regs *regs, unsigned char __user *addr,\n {\n \tchar *ptr0 = (char *)&regs->gpr[reg];\n \tchar *ptr1 = (char *)&regs->gpr[reg+1];\n-\tint i, ret, sw = 0;\n+\tint i, sw = 0;\n \n \tif (reg & 1)\n \t\treturn 0;\t/* invalid form: GPR must be even */\n \tif (flags & SW)\n \t\tsw = 7;\n-\tret = 0;\n+\n \tfor (i = 0; i < 8; ++i) {\n \t\tif (!(flags & ST)) {\n-\t\t\tret |= __get_user(ptr0[i^sw], addr + i);\n-\t\t\tret |= __get_user(ptr1[i^sw], addr + i + 8);\n+\t\t\tif (__get_user_or_set_dar(regs, ptr0[i^sw], addr + i))\n+\t\t\t\treturn -EFAULT;\n+\t\t\tif (__get_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))\n+\t\t\t\treturn -EFAULT;\n \t\t} else {\n-\t\t\tret |= __put_user(ptr0[i^sw], addr + i);\n-\t\t\tret |= __put_user(ptr1[i^sw], addr + i + 8);\n+\t\t\tif (__put_user_or_set_dar(regs, ptr0[i^sw], addr + i))\n+\t\t\t\treturn -EFAULT;\n+\t\t\tif (__put_user_or_set_dar(regs, ptr1[i^sw], addr + i + 8))\n+\t\t\t\treturn -EFAULT;\n \t\t}\n \t}\n-\tif (ret)\n-\t\treturn -EFAULT;\n+\n \treturn 1;\t/* exception handled and fixed up */\n }\n #endif /* CONFIG_PPC64 */\n@@ -687,9 +716,14 @@ static int emulate_vsx(unsigned char __user *addr, unsigned int reg,\n \tfor (j = 0; j < length; j += elsize) {\n \t\tfor (i = 0; i < elsize; ++i) {\n \t\t\tif (flags & ST)\n-\t\t\t\tret |= __put_user(ptr[i^sw], addr + i);\n+\t\t\t\tret = __put_user_or_set_dar(regs, ptr[i^sw],\n+\t\t\t\t\t\t\t    addr + i);\n \t\t\telse\n-\t\t\t\tret |= __get_user(ptr[i^sw], addr + i);\n+\t\t\t\tret = __get_user_or_set_dar(regs, ptr[i^sw],\n+\t\t\t\t\t\t\t    addr + i);\n+\n+\t\t\tif (ret)\n+\t\t\t\treturn ret;\n \t\t}\n \t\tptr  += elsize;\n #ifdef __LITTLE_ENDIAN__\n@@ -739,7 +773,7 @@ int fix_alignment(struct pt_regs *regs)\n \tunsigned int dsisr;\n \tunsigned char __user *addr;\n \tunsigned long p, swiz;\n-\tint ret, i;\n+\tint i;\n \tunion data {\n \t\tu64 ll;\n \t\tdouble dd;\n@@ -936,7 +970,7 @@ int fix_alignment(struct pt_regs *regs)\n \t\tif (flags & F) {\n \t\t\t/* Special case for 16-byte FP loads and stores */\n \t\t\tPPC_WARN_ALIGNMENT(fp_pair, regs);\n-\t\t\treturn emulate_fp_pair(addr, reg, flags);\n+\t\t\treturn emulate_fp_pair(regs, addr, reg, flags);\n \t\t} else {\n #ifdef CONFIG_PPC64\n \t\t\t/* Special case for 16-byte loads and stores */\n@@ -966,15 +1000,12 @@ int fix_alignment(struct pt_regs *regs)\n \t\t}\n \n \t\tdata.ll = 0;\n-\t\tret = 0;\n \t\tp = (unsigned long)addr;\n \n \t\tfor (i = 0; i < nb; i++)\n-\t\t\tret |= __get_user_inatomic(data.v[start + i],\n-\t\t\t\t\t\t   SWIZ_PTR(p++));\n-\n-\t\tif (unlikely(ret))\n-\t\t\treturn -EFAULT;\n+\t\t\tif (__get_user_or_set_dar(regs, data.v[start + i],\n+\t\t\t\t\t\t  SWIZ_PTR(p++)))\n+\t\t\t\treturn -EFAULT;\n \n \t} else if (flags & F) {\n \t\tdata.ll = current->thread.TS_FPR(reg);\n@@ -1046,15 +1077,13 @@ int fix_alignment(struct pt_regs *regs)\n \t\t\tbreak;\n \t\t}\n \n-\t\tret = 0;\n \t\tp = (unsigned long)addr;\n \n \t\tfor (i = 0; i < nb; i++)\n-\t\t\tret |= __put_user_inatomic(data.v[start + i],\n-\t\t\t\t\t\t   SWIZ_PTR(p++));\n+\t\t\tif (__put_user_or_set_dar(regs, data.v[start + i],\n+\t\t\t\t\t\t  SWIZ_PTR(p++)))\n+\t\t\t\treturn -EFAULT;\n \n-\t\tif (unlikely(ret))\n-\t\t\treturn -EFAULT;\n \t} else if (flags & F)\n \t\tcurrent->thread.TS_FPR(reg) = data.ll;\n \telse\n",
    "prefixes": []
}