From patchwork Fri Mar 20 05:17:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258633 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kBwD6LH7z9sP7 for ; Fri, 20 Mar 2020 16:21:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=JUI+wUVQ; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kBwD63tLzDrWV for ; Fri, 20 Mar 2020 16:21:48 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1043; helo=mail-pj1-x1043.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=JUI+wUVQ; dkim-atps=neutral Received: from mail-pj1-x1043.google.com (mail-pj1-x1043.google.com [IPv6:2607:f8b0:4864:20::1043]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBrt19N6zDrQg for ; Fri, 20 Mar 2020 16:18:54 +1100 (AEDT) Received: by mail-pj1-x1043.google.com with SMTP id j20so1976049pjz.0 for ; Thu, 19 Mar 2020 22:18:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=xoZA3SXUairwdsevsTvI8dJewt4/e6ZJ6Wp3eA/jccU=; b=JUI+wUVQXZcAmTchZiJnq5mbKgq/B0whvR9QAxvDWXMYvEkYSEtjF8clJc8UI0k9VY tG3T2bozzdc2Owzl/ElFKDDu9kgXr1BeJGhGm+TJ0O0Qo6hxU3ON+0rTXCwrd4LWwFDt 4hB6u/TwR3MsmiOXwJr5vbMRBSBggFyURovzYC8dERz71UgDTPueznvlLpSr39Ev5sbA fTaMS7vrhjAU0XAIROl5BNmxhXVV3ihRnARdhZ3AbSJCvA5T60SPmN9A3kY8JTwGEJMy RpCrwdoqtsiEsHf5/ySwfpd0bmc52tDiLsdv/tlB6l1ti9DHzdy2xqIvfHq+trhdSb++ KuFw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=xoZA3SXUairwdsevsTvI8dJewt4/e6ZJ6Wp3eA/jccU=; b=Yd2Z7OOHPYNbal1wo63C4kJYTMg2FBMeu8Mr1tUftft6Qs2Ow9degR3tA0jqVz0R3K SubNcU4iRs56qSdyU/8Ij6GBxn4uKpivb5bdh74oYaco0LsueKnHQO7DyFK8rfkdnXN9 h9Rr1x7LCgFciU+oe09EFn4aXDtJqSvOivg9U3T1cdOWg6tf1d5FbxM3xNRXVE9e2ce5 hTleQsqAVPCmkvqkVEUsrBc3aJl8HY2upYkf783IZNCfWw4TvCZEW4wH5GOZJOhGvBYA poBgsCP5Rv5kY4lqn5ROPiTup1n/3oTRY5HL6cVJav4Z2jopSa7FAZQzpBlhl4pgWM7I erVA== X-Gm-Message-State: ANhLgQ1TeCQ/BfDBC206CVa2VyMLs9+ZzCiSKJ/Y6cZBqHPCo4uAo3Zh ACNGBBN1aNOZ9oi42+X+UKTAErBvE9g= X-Google-Smtp-Source: ADFU+vuwILnKBsWDmB6QmsPLxfaLYSNmPGEfJrBFNEEZzaKbA6BKoiNRVk1MwHSRQzK+iA2Z9mBXjQ== X-Received: by 2002:a17:90b:19ca:: with SMTP id nm10mr7486569pjb.157.1584681531556; Thu, 19 Mar 2020 22:18:51 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.18.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:18:51 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 01/16] powerpc/xmon: Remove store_inst() for patch_instruction() Date: Fri, 20 Mar 2020 16:17:54 +1100 Message-Id: <20200320051809.24332-2-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" For modifying instructions in xmon, patch_instruction() can serve the same role that store_inst() is performing with the advantage of not being specific to xmon. In some places patch_instruction() is already being using followed by store_inst(). In these cases just remove the store_inst(). Otherwise replace store_inst() with patch_instruction(). Signed-off-by: Jordan Niethe Reviewed-by: Nicholas Piggin --- v4: Read into a local variable --- arch/powerpc/xmon/xmon.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index e8c84d265602..02e3bd62cab4 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -325,11 +325,6 @@ static inline void sync(void) asm volatile("sync; isync"); } -static inline void store_inst(void *p) -{ - asm volatile ("dcbst 0,%0; sync; icbi 0,%0; isync" : : "r" (p)); -} - static inline void cflush(void *p) { asm volatile ("dcbf 0,%0; icbi 0,%0" : : "r" (p)); @@ -881,8 +876,7 @@ static struct bpt *new_breakpoint(unsigned long a) for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { if (!bp->enabled && atomic_read(&bp->ref_count) == 0) { bp->address = a; - bp->instr[1] = bpinstr; - store_inst(&bp->instr[1]); + patch_instruction(&bp->instr[1], bpinstr); return bp; } } @@ -894,25 +888,26 @@ static struct bpt *new_breakpoint(unsigned long a) static void insert_bpts(void) { int i; + unsigned int instr; struct bpt *bp; bp = bpts; for (i = 0; i < NBPTS; ++i, ++bp) { if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0) continue; - if (mread(bp->address, &bp->instr[0], 4) != 4) { + if (mread(bp->address, &instr, 4) != 4) { printf("Couldn't read instruction at %lx, " "disabling breakpoint there\n", bp->address); bp->enabled = 0; continue; } - if (IS_MTMSRD(bp->instr[0]) || IS_RFID(bp->instr[0])) { + if (IS_MTMSRD(instr) || IS_RFID(instr)) { printf("Breakpoint at %lx is on an mtmsrd or rfid " "instruction, disabling it\n", bp->address); bp->enabled = 0; continue; } - store_inst(&bp->instr[0]); + patch_instruction(bp->instr, instr); if (bp->enabled & BP_CIABR) continue; if (patch_instruction((unsigned int *)bp->address, @@ -922,7 +917,6 @@ static void insert_bpts(void) bp->enabled &= ~BP_TRAP; continue; } - store_inst((void *)bp->address); } } @@ -957,8 +951,6 @@ static void remove_bpts(void) (unsigned int *)bp->address, bp->instr[0]) != 0) printf("Couldn't remove breakpoint at %lx\n", bp->address); - else - store_inst((void *)bp->address); } } From patchwork Fri Mar 20 05:17:55 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258634 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kBxt5hpbz9sP7 for ; Fri, 20 Mar 2020 16:23:14 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=pNrUKXou; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kBxt4T7SzDrdV for ; Fri, 20 Mar 2020 16:23:14 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::542; helo=mail-pg1-x542.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=pNrUKXou; dkim-atps=neutral Received: from mail-pg1-x542.google.com (mail-pg1-x542.google.com [IPv6:2607:f8b0:4864:20::542]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBrx4q9qzDrTy for ; Fri, 20 Mar 2020 16:18:57 +1100 (AEDT) Received: by mail-pg1-x542.google.com with SMTP id x7so2492598pgh.5 for ; Thu, 19 Mar 2020 22:18:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Za/HqvZ7ZH2R48HLp9KQlG4Fu2psoORjHVcl8a33Em4=; b=pNrUKXou/JUuRo8LxfwwlT4mAXcrSOTbJs+8PiFgU/+zHhgKpczilXA5tz347iE5tI 46Ze6TuK35Ca5NHGn7KQHS57E+2RQBT405SJGQITHzCThw8Px0ME0nzPBhhGnrRywh3A F9OJvYeWm2a7Y3dmu+rygyR53w53RNA36f8yp8aSbIs09+iwnmUsG3PoyhWc4ujzA/bP f79SkZk1MZQzkYsWB3olc+9cn72hw3+HBxDHnGQaWKfNu57Rc7qKEItB0GdlB8Hylv4q M2E9kEyy5QrhQyw+w4e9fL16qRcPBphhDPW+edEzLHSueCQD7nToVSZXfDD649DAi6f7 T8VQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Za/HqvZ7ZH2R48HLp9KQlG4Fu2psoORjHVcl8a33Em4=; b=fRyalbZ2fm9UHlL/c+ZfVABBNbxAla67i1move5U2IaXxN039eFNbnGDNHCHSHRrqz bW4B6syMNQ+Ga/4F0eq9JpeP8Y+uutdQ+aXM2zKISFe8pBc6XiOkcS15a+/6YXEs5a3o bhzahoVglTU3iyT8omwgLGI+Xr9mI6qIzx0vzePT5XiKgjb1WWhLidso/kW73CgilIbf Bnpg8CYpZ6FpfUSfcn2uGYqUtYJZwzNDhTrWAwS3Az/79WAGueac6BPbwGZi/euXk1EV CGZSsqQ6CCJJT0B29dZp8iAnDXoxGWdtsjXRlMMSda2VeH5vCFRMbiDQdmlzR5Ldcd/n D2Dw== X-Gm-Message-State: ANhLgQ2p068K1nSgI0rvw3lBrJpvgWssyAtqfqmMQxmEB+KU3ywdgtCU YMyLyuEKIQk2YE4rsjKrWCsV3rLhI90= X-Google-Smtp-Source: ADFU+vvbdaJx4zykaEthVzjRI6RcsiHcYt7I7uiqlM4OuLPJZJiovTFiQKo7iD16qJLZgfcJ8O2f1Q== X-Received: by 2002:a63:2882:: with SMTP id o124mr6571696pgo.390.1584681535336; Thu, 19 Mar 2020 22:18:55 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.18.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:18:54 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 02/16] xmon: Move out-of-line instructions to text section Date: Fri, 20 Mar 2020 16:17:55 +1100 Message-Id: <20200320051809.24332-3-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" To execute an instruction out of line after a breakpoint, the NIP is set to the address of struct bpt::instr. Here a copy of the instruction that was replaced with a breakpoint is kept, along with a trap so normal flow can be resumed after XOLing. The struct bpt's are located within the data section. This is problematic as the data section may be marked as no execute. Instead of each struct bpt holding the instructions to be XOL'd, make a new array, bpt_table[], with enough space to hold instructions for the number of supported breakpoints. Place this array in the text section. Make struct bpt::instr a pointer to the instructions in bpt_table[] associated with that breakpoint. This association is a simple mapping: bpts[n] -> bpt_table[n * words per breakpoint]. Currently we only need the copied instruction followed by a trap, so 2 words per breakpoint. Signed-off-by: Jordan Niethe Reviewed-by: Nicholas Piggin --- v4: New to series --- arch/powerpc/kernel/vmlinux.lds.S | 2 +- arch/powerpc/xmon/xmon.c | 22 +++++++++++++--------- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S index b4c89a1acebb..e90845b8c300 100644 --- a/arch/powerpc/kernel/vmlinux.lds.S +++ b/arch/powerpc/kernel/vmlinux.lds.S @@ -86,7 +86,7 @@ SECTIONS ALIGN_FUNCTION(); #endif /* careful! __ftr_alt_* sections need to be close to .text */ - *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text); + *(.text.hot TEXT_MAIN .text.fixup .text.unlikely .fixup __ftr_alt_* .ref.text .text.xmon_bpts); #ifdef CONFIG_PPC64 *(.tramp.ftrace.text); #endif diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 02e3bd62cab4..7875d1a37770 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -97,7 +97,7 @@ static long *xmon_fault_jmp[NR_CPUS]; /* Breakpoint stuff */ struct bpt { unsigned long address; - unsigned int instr[2]; + unsigned int *instr; atomic_t ref_count; int enabled; unsigned long pad; @@ -109,6 +109,7 @@ struct bpt { #define BP_DABR 4 #define NBPTS 256 +#define BPT_WORDS 2 static struct bpt bpts[NBPTS]; static struct bpt dabr; static struct bpt *iabr; @@ -116,6 +117,8 @@ static unsigned bpinstr = 0x7fe00008; /* trap */ #define BP_NUM(bp) ((bp) - bpts + 1) +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS]; + /* Prototypes */ static int cmds(struct pt_regs *); static int mread(unsigned long, void *, int); @@ -852,16 +855,16 @@ static struct bpt *at_breakpoint(unsigned long pc) static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp) { unsigned long off; + unsigned long bp_off; - off = nip - (unsigned long) bpts; - if (off >= sizeof(bpts)) + off = nip - (unsigned long) bpt_table; + if (off >= sizeof(bpt_table)) return NULL; - off %= sizeof(struct bpt); - if (off != offsetof(struct bpt, instr[0]) - && off != offsetof(struct bpt, instr[1])) + bp_off = off % (sizeof(unsigned int) * BPT_WORDS); + if (bp_off != 0 && bp_off != 4) return NULL; - *offp = off - offsetof(struct bpt, instr[0]); - return (struct bpt *) (nip - off); + *offp = bp_off; + return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS)); } static struct bpt *new_breakpoint(unsigned long a) @@ -876,7 +879,8 @@ static struct bpt *new_breakpoint(unsigned long a) for (bp = bpts; bp < &bpts[NBPTS]; ++bp) { if (!bp->enabled && atomic_read(&bp->ref_count) == 0) { bp->address = a; - patch_instruction(&bp->instr[1], bpinstr); + bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS); + patch_instruction(bp->instr + 1, bpinstr); return bp; } } From patchwork Fri Mar 20 05:17:56 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258635 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kC024Hzqz9sP7 for ; Fri, 20 Mar 2020 16:25:06 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=AhAuy7ly; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kC016LKbzDrWy for ; Fri, 20 Mar 2020 16:25:05 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1044; helo=mail-pj1-x1044.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=AhAuy7ly; dkim-atps=neutral Received: from mail-pj1-x1044.google.com (mail-pj1-x1044.google.com [IPv6:2607:f8b0:4864:20::1044]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBs21qrKzDrWW for ; Fri, 20 Mar 2020 16:19:02 +1100 (AEDT) Received: by mail-pj1-x1044.google.com with SMTP id np9so1973572pjb.4 for ; Thu, 19 Mar 2020 22:19:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=GMunP9tUyCq2huENyF63KF0D+LaI8AxaotsXN6BDSeQ=; b=AhAuy7lyzqwzpE1DfkKZaZW2G+xMCnMEHhWOZeOyXqbDPhp5zlYI5ErkQRiuMzBZWj e577TlTKmzZaqoXPSOCxR31hfUqtJVtAJymm0cGS8bh6GkWdAU+VQxiOS1M1X8j9kO5U a3Hl+NQKdZghX5wW3yWn3xmHCGPHJSrWO/CtaCNOby7RTEnUTDoUqfBKwFbusaGmdv0R +gG/4rE5+WlwkIcrFnFb5klalp/64h6KtqciKJMwA9j7+iH9XEqKBqb0xHmagzgYOqUl OUdPH0dQJNV3+vHpCy3I9xiWkVY/jMmKNFxZF7lks+7qAFa5tNWXP+ym/m0OiyzoNIdV OZ9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=GMunP9tUyCq2huENyF63KF0D+LaI8AxaotsXN6BDSeQ=; b=EMS+UR7z1FzRi5RyKWfJ3oKlQhTWH5r1Dc5UJkzPP6HmV6a0DLvs2n/aHigSBtWnLM wgoriBJQgX6petLVJTsO6s/hBKPaZsbYIY3ic5qVB0F34jXMpZacyEfwxKQucDt1/odd mbhXRgZ84G4kbuUPjACFlkMRVM1YxMVno9I/cuSb8yUXjeySAQAFf9A78UpTSB5pjUuP mc8v5TCWCKqzWwzcjP7BaqemxuX3PM1MMuX5+0tJGlyZLviFQPqf56piwd7MeS3XgnGm pemyKajFacmW/ejYkp7n+vLvlCUJz4Bi8TzMenFvDetbJnpEB6aDFCK5j85YVrp+U/fH ugzA== X-Gm-Message-State: ANhLgQ2fFEl+sgAHpvthM3S4o3CfVK1/lQcw+LxnrtSWuurpz3SwL6Zi P2B+vI1gZI6j5zzcHrl/6gf2yawtAM8= X-Google-Smtp-Source: ADFU+vt4fiD3AumsnUy15mUZdR8llmS6ovV08CFRvYFbaZmIzAg6wnAc6gIS5V9PAJsGWRT8Pzu66A== X-Received: by 2002:a17:90a:2042:: with SMTP id n60mr7530755pjc.0.1584681539280; Thu, 19 Mar 2020 22:18:59 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.18.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:18:58 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 03/16] powerpc: Use a datatype for instructions Date: Fri, 20 Mar 2020 16:17:56 +1100 Message-Id: <20200320051809.24332-4-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Currently unsigned ints are used to represent instructions on powerpc. This has worked well as instructions have always been 4 byte words. However, a future ISA version will introduce some changes to instructions that mean this scheme will no longer work as well. This change is Prefixed Instructions. A prefixed instruction is made up of a word prefix followed by a word suffix to make an 8 byte double word instruction. No matter the endianess of the system the prefix always comes first. Prefixed instructions are only planned for powerpc64. Introduce a ppc_inst type to represent both prefixed and word instructions on powerpc64 while keeping it possible to exclusively have word instructions on powerpc32, A latter patch will expand the type to include prefixed instructions but for now just typedef it to a u32. Later patches will introduce helper functions and macros for manipulating the instructions so that powerpc64 and powerpc32 might maintain separate type definitions. Signed-off-by: Jordan Niethe Reviewed-by: Nicholas Piggin --- arch/powerpc/include/asm/code-patching.h | 31 +++++------ arch/powerpc/include/asm/inst.h | 53 +++++++++++++++++++ arch/powerpc/include/asm/sstep.h | 5 +- arch/powerpc/kernel/align.c | 2 +- arch/powerpc/kernel/hw_breakpoint.c | 3 +- arch/powerpc/kernel/kprobes.c | 2 +- arch/powerpc/kernel/mce_power.c | 5 +- arch/powerpc/kernel/optprobes.c | 10 ++-- arch/powerpc/kernel/trace/ftrace.c | 66 ++++++++++++------------ arch/powerpc/kvm/emulate_loadstore.c | 1 + arch/powerpc/lib/code-patching.c | 54 +++++++++---------- arch/powerpc/lib/sstep.c | 4 +- arch/powerpc/lib/test_emulate_step.c | 9 ++-- arch/powerpc/xmon/xmon.c | 12 ++--- 14 files changed, 160 insertions(+), 97 deletions(-) create mode 100644 arch/powerpc/include/asm/inst.h diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 898b54262881..cb5106f92d67 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -11,6 +11,7 @@ #include #include #include +#include /* Flags for create_branch: * "b" == create_branch(addr, target, 0); @@ -22,27 +23,27 @@ #define BRANCH_ABSOLUTE 0x2 bool is_offset_in_branch_range(long offset); -unsigned int create_branch(const unsigned int *addr, +ppc_inst create_branch(const ppc_inst *addr, unsigned long target, int flags); -unsigned int create_cond_branch(const unsigned int *addr, +unsigned int create_cond_branch(const ppc_inst *addr, unsigned long target, int flags); -int patch_branch(unsigned int *addr, unsigned long target, int flags); -int patch_instruction(unsigned int *addr, unsigned int instr); -int raw_patch_instruction(unsigned int *addr, unsigned int instr); +int patch_branch(ppc_inst *addr, unsigned long target, int flags); +int patch_instruction(ppc_inst *addr, ppc_inst instr); +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr); static inline unsigned long patch_site_addr(s32 *site) { return (unsigned long)site + *site; } -static inline int patch_instruction_site(s32 *site, unsigned int instr) +static inline int patch_instruction_site(s32 *site, ppc_inst instr) { - return patch_instruction((unsigned int *)patch_site_addr(site), instr); + return patch_instruction((ppc_inst *)patch_site_addr(site), instr); } static inline int patch_branch_site(s32 *site, unsigned long target, int flags) { - return patch_branch((unsigned int *)patch_site_addr(site), target, flags); + return patch_branch((ppc_inst *)patch_site_addr(site), target, flags); } static inline int modify_instruction(unsigned int *addr, unsigned int clr, @@ -56,13 +57,13 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned return modify_instruction((unsigned int *)patch_site_addr(site), clr, set); } -int instr_is_relative_branch(unsigned int instr); -int instr_is_relative_link_branch(unsigned int instr); -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr); -unsigned long branch_target(const unsigned int *instr); -unsigned int translate_branch(const unsigned int *dest, - const unsigned int *src); -extern bool is_conditional_branch(unsigned int instr); +int instr_is_relative_branch(ppc_inst instr); +int instr_is_relative_link_branch(ppc_inst instr); +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr); +unsigned long branch_target(const ppc_inst *instr); +ppc_inst translate_branch(const ppc_inst *dest, + const ppc_inst *src); +extern bool is_conditional_branch(ppc_inst instr); #ifdef CONFIG_PPC_BOOK3E_64 void __patch_exception(int exc, unsigned long addr); #define patch_exception(exc, name) do { \ diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h new file mode 100644 index 000000000000..7c8596ee411e --- /dev/null +++ b/arch/powerpc/include/asm/inst.h @@ -0,0 +1,53 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ +#ifndef _ASM_INST_H +#define _ASM_INST_H + +/* + * Instruction data type for POWER + */ + +typedef u32 ppc_inst; + +#define PPC_INST(x) (x) + +static inline int ppc_inst_len(ppc_inst x) +{ + return sizeof(ppc_inst); +} + +static inline int ppc_inst_opcode(ppc_inst x) +{ + return x >> 26; +} + +static inline u32 ppc_inst_word(ppc_inst x) +{ + return x; +} + +static inline ppc_inst ppc_inst_read(const ppc_inst *ptr) +{ + return *(ppc_inst *)ptr; +} + +static inline void ppc_inst_write(void *ptr, ppc_inst x) +{ + *(ppc_inst *)ptr = x; +} + +static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y) +{ + return x == y; +} + +static inline bool ppc_inst_null(ppc_inst x) +{ + return x == 0; +} + +static inline u32 ppc_inst_mask(ppc_inst x, u32 mask) +{ + return ppc_inst_word(x) & mask; +} + +#endif /* _ASM_INST_H */ diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h index 769f055509c9..9353916fcba7 100644 --- a/arch/powerpc/include/asm/sstep.h +++ b/arch/powerpc/include/asm/sstep.h @@ -2,6 +2,7 @@ /* * Copyright (C) 2004 Paul Mackerras , IBM */ +#include struct pt_regs; @@ -132,7 +133,7 @@ union vsx_reg { * otherwise. */ extern int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, - unsigned int instr); + ppc_inst instr); /* * Emulate an instruction that can be executed just by updating @@ -149,7 +150,7 @@ void emulate_update_regs(struct pt_regs *reg, struct instruction_op *op); * 0 if it could not be emulated, or -1 for an instruction that * should not be emulated (rfid, mtmsrd clearing MSR_RI, etc.). */ -extern int emulate_step(struct pt_regs *regs, unsigned int instr); +extern int emulate_step(struct pt_regs *regs, ppc_inst instr); /* * Emulate a load or store instruction by reading/writing the diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 92045ed64976..34594aaa44de 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -293,7 +293,7 @@ static int emulate_spe(struct pt_regs *regs, unsigned int reg, int fix_alignment(struct pt_regs *regs) { - unsigned int instr; + ppc_inst instr; struct instruction_op op; int r, type; diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index 2462cd7c565c..06b97353d231 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -24,6 +24,7 @@ #include #include #include +#include #include /* @@ -243,7 +244,7 @@ dar_range_overlaps(unsigned long dar, int size, struct arch_hw_breakpoint *info) static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp, struct arch_hw_breakpoint *info) { - unsigned int instr = 0; + ppc_inst instr = 0; int ret, type, size; struct instruction_op op; unsigned long addr = info->address; diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 337516df17d4..e7205adc9820 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -225,7 +225,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe); static int try_to_emulate(struct kprobe *p, struct pt_regs *regs) { int ret; - unsigned int insn = *p->ainsn.insn; + ppc_inst insn = *p->ainsn.insn; /* regs->nip is also adjusted if emulate_step returns 1 */ ret = emulate_step(regs, insn); diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index 1cbf7f1a4e3d..e65616bb3a3e 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -20,6 +20,7 @@ #include #include #include +#include /* * Convert an address related to an mm to a PFN. NOTE: we are in real @@ -365,7 +366,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr, * in real-mode is tricky and can lead to recursive * faults */ - int instr; + ppc_inst instr; unsigned long pfn, instr_addr; struct instruction_op op; struct pt_regs tmp = *regs; @@ -373,7 +374,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr, pfn = addr_to_pfn(regs, regs->nip); if (pfn != ULONG_MAX) { instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK); - instr = *(unsigned int *)(instr_addr); + instr = *(ppc_inst *)(instr_addr); if (!analyse_instr(&op, &tmp, instr)) { pfn = addr_to_pfn(regs, op.ea); *addr = op.ea; diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index 024f7aad1952..f5e8cce438a3 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -189,8 +189,8 @@ void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr) int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) { - kprobe_opcode_t *buff, branch_op_callback, branch_emulate_step; - kprobe_opcode_t *op_callback_addr, *emulate_step_addr; + ppc_inst branch_op_callback, branch_emulate_step; + kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff; long b_offset; unsigned long nip, size; int rc, i; @@ -251,11 +251,11 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) goto error; } - branch_op_callback = create_branch((unsigned int *)buff + TMPL_CALL_HDLR_IDX, + branch_op_callback = create_branch((ppc_inst *)buff + TMPL_CALL_HDLR_IDX, (unsigned long)op_callback_addr, BRANCH_SET_LINK); - branch_emulate_step = create_branch((unsigned int *)buff + TMPL_EMULATE_IDX, + branch_emulate_step = create_branch((ppc_inst *)buff + TMPL_EMULATE_IDX, (unsigned long)emulate_step_addr, BRANCH_SET_LINK); @@ -316,7 +316,7 @@ void arch_optimize_kprobes(struct list_head *oplist) memcpy(op->optinsn.copied_insn, op->kp.addr, RELATIVEJUMP_SIZE); patch_instruction(op->kp.addr, - create_branch((unsigned int *)op->kp.addr, + create_branch((ppc_inst *)op->kp.addr, (unsigned long)op->optinsn.insn, 0)); list_del_init(&op->list); } diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index 7ea0ca044b65..5787ccffb4df 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -27,6 +27,7 @@ #include #include #include +#include #ifdef CONFIG_DYNAMIC_FTRACE @@ -40,23 +41,23 @@ #define NUM_FTRACE_TRAMPS 8 static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS]; -static unsigned int +static ppc_inst ftrace_call_replace(unsigned long ip, unsigned long addr, int link) { - unsigned int op; + ppc_inst op; addr = ppc_function_entry((void *)addr); /* if (link) set op to 'bl' else 'b' */ - op = create_branch((unsigned int *)ip, addr, link ? 1 : 0); + op = create_branch((ppc_inst *)ip, addr, link ? 1 : 0); return op; } static int -ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) +ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new) { - unsigned int replaced; + ppc_inst replaced; /* * Note: @@ -78,7 +79,7 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) } /* replace the text with the new text */ - if (patch_instruction((unsigned int *)ip, new)) + if (patch_instruction((ppc_inst *)ip, new)) return -EPERM; return 0; @@ -87,25 +88,25 @@ ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) /* * Helper functions that are the same for both PPC64 and PPC32. */ -static int test_24bit_addr(unsigned long ip, unsigned long addr) +static ppc_inst test_24bit_addr(unsigned long ip, unsigned long addr) { addr = ppc_function_entry((void *)addr); /* use the create_branch to verify that this offset can be branched */ - return create_branch((unsigned int *)ip, addr, 0); + return create_branch((ppc_inst *)ip, addr, 0); } -static int is_bl_op(unsigned int op) +static int is_bl_op(ppc_inst op) { return (op & 0xfc000003) == 0x48000001; } -static int is_b_op(unsigned int op) +static int is_b_op(ppc_inst op) { return (op & 0xfc000003) == 0x48000000; } -static unsigned long find_bl_target(unsigned long ip, unsigned int op) +static unsigned long find_bl_target(unsigned long ip, ppc_inst op) { int offset; @@ -125,7 +126,7 @@ __ftrace_make_nop(struct module *mod, { unsigned long entry, ptr, tramp; unsigned long ip = rec->ip; - unsigned int op, pop; + ppc_inst op, pop; /* read where this goes */ if (probe_kernel_read(&op, (void *)ip, sizeof(int))) { @@ -204,7 +205,7 @@ __ftrace_make_nop(struct module *mod, } #endif /* CONFIG_MPROFILE_KERNEL */ - if (patch_instruction((unsigned int *)ip, pop)) { + if (patch_instruction((ppc_inst *)ip, pop)) { pr_err("Patching NOP failed.\n"); return -EPERM; } @@ -217,7 +218,7 @@ static int __ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) { - unsigned int op; + ppc_inst op; unsigned int jmp[4]; unsigned long ip = rec->ip; unsigned long tramp; @@ -276,7 +277,7 @@ __ftrace_make_nop(struct module *mod, op = PPC_INST_NOP; - if (patch_instruction((unsigned int *)ip, op)) + if (patch_instruction((ppc_inst *)ip, op)) return -EPERM; return 0; @@ -322,7 +323,8 @@ static int add_ftrace_tramp(unsigned long tramp) */ static int setup_mcount_compiler_tramp(unsigned long tramp) { - int i, op; + int i; + ppc_inst op; unsigned long ptr; static unsigned long ftrace_plt_tramps[NUM_FTRACE_TRAMPS]; @@ -388,7 +390,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp) static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr) { unsigned long tramp, ip = rec->ip; - unsigned int op; + ppc_inst op; /* Read where this goes */ if (probe_kernel_read(&op, (void *)ip, sizeof(int))) { @@ -416,7 +418,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr) } } - if (patch_instruction((unsigned int *)ip, PPC_INST_NOP)) { + if (patch_instruction((ppc_inst *)ip, PPC_INST_NOP)) { pr_err("Patching NOP failed.\n"); return -EPERM; } @@ -428,7 +430,7 @@ int ftrace_make_nop(struct module *mod, struct dyn_ftrace *rec, unsigned long addr) { unsigned long ip = rec->ip; - unsigned int old, new; + ppc_inst old, new; /* * If the calling address is more that 24 bits away, @@ -481,7 +483,7 @@ int ftrace_make_nop(struct module *mod, */ #ifndef CONFIG_MPROFILE_KERNEL static int -expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) +expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1) { /* * We expect to see: @@ -510,7 +512,7 @@ expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) static int __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) { - unsigned int op[2]; + ppc_inst op[2]; void *ip = (void *)rec->ip; unsigned long entry, ptr, tramp; struct module *mod = rec->arch.mod; @@ -574,7 +576,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) static int __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) { - unsigned int op; + ppc_inst op; unsigned long ip = rec->ip; /* read where this goes */ @@ -594,7 +596,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) } /* create the branch to the trampoline */ - op = create_branch((unsigned int *)ip, + op = create_branch((ppc_inst *)ip, rec->arch.mod->arch.tramp, BRANCH_SET_LINK); if (!op) { pr_err("REL24 out of range!\n"); @@ -613,7 +615,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr) { - unsigned int op; + ppc_inst op; void *ip = (void *)rec->ip; unsigned long tramp, entry, ptr; @@ -661,7 +663,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr) int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) { unsigned long ip = rec->ip; - unsigned int old, new; + ppc_inst old, new; /* * If the calling address is more that 24 bits away, @@ -700,7 +702,7 @@ static int __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, unsigned long addr) { - unsigned int op; + ppc_inst op; unsigned long ip = rec->ip; unsigned long entry, ptr, tramp; struct module *mod = rec->arch.mod; @@ -748,7 +750,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, /* The new target may be within range */ if (test_24bit_addr(ip, addr)) { /* within range */ - if (patch_branch((unsigned int *)ip, addr, BRANCH_SET_LINK)) { + if (patch_branch((ppc_inst *)ip, addr, BRANCH_SET_LINK)) { pr_err("REL24 out of range!\n"); return -EINVAL; } @@ -776,7 +778,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, } /* Ensure branch is within 24 bits */ - if (!create_branch((unsigned int *)ip, tramp, BRANCH_SET_LINK)) { + if (!create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK)) { pr_err("Branch out of range\n"); return -EINVAL; } @@ -794,7 +796,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, unsigned long addr) { unsigned long ip = rec->ip; - unsigned int old, new; + ppc_inst old, new; /* * If the calling address is more that 24 bits away, @@ -834,7 +836,7 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, int ftrace_update_ftrace_func(ftrace_func_t func) { unsigned long ip = (unsigned long)(&ftrace_call); - unsigned int old, new; + ppc_inst old, new; int ret; old = *(unsigned int *)&ftrace_call; @@ -919,7 +921,7 @@ int ftrace_enable_ftrace_graph_caller(void) unsigned long ip = (unsigned long)(&ftrace_graph_call); unsigned long addr = (unsigned long)(&ftrace_graph_caller); unsigned long stub = (unsigned long)(&ftrace_graph_stub); - unsigned int old, new; + ppc_inst old, new; old = ftrace_call_replace(ip, stub, 0); new = ftrace_call_replace(ip, addr, 0); @@ -932,7 +934,7 @@ int ftrace_disable_ftrace_graph_caller(void) unsigned long ip = (unsigned long)(&ftrace_graph_call); unsigned long addr = (unsigned long)(&ftrace_graph_caller); unsigned long stub = (unsigned long)(&ftrace_graph_stub); - unsigned int old, new; + ppc_inst old, new; old = ftrace_call_replace(ip, addr, 0); new = ftrace_call_replace(ip, stub, 0); diff --git a/arch/powerpc/kvm/emulate_loadstore.c b/arch/powerpc/kvm/emulate_loadstore.c index 1139bc56e004..1c9bcbfeb924 100644 --- a/arch/powerpc/kvm/emulate_loadstore.c +++ b/arch/powerpc/kvm/emulate_loadstore.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "timing.h" #include "trace.h" diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 3345f039a876..8492b9e2b8db 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -17,9 +17,10 @@ #include #include #include +#include -static int __patch_instruction(unsigned int *exec_addr, unsigned int instr, - unsigned int *patch_addr) +static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr, + ppc_inst *patch_addr) { int err = 0; @@ -33,7 +34,7 @@ static int __patch_instruction(unsigned int *exec_addr, unsigned int instr, return 0; } -int raw_patch_instruction(unsigned int *addr, unsigned int instr) +int raw_patch_instruction(ppc_inst *addr, ppc_inst instr) { return __patch_instruction(addr, instr, addr); } @@ -136,10 +137,10 @@ static inline int unmap_patch_area(unsigned long addr) return 0; } -static int do_patch_instruction(unsigned int *addr, unsigned int instr) +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr) { int err; - unsigned int *patch_addr = NULL; + ppc_inst *patch_addr = NULL; unsigned long flags; unsigned long text_poke_addr; unsigned long kaddr = (unsigned long)addr; @@ -176,7 +177,7 @@ static int do_patch_instruction(unsigned int *addr, unsigned int instr) } #else /* !CONFIG_STRICT_KERNEL_RWX */ -static int do_patch_instruction(unsigned int *addr, unsigned int instr) +static int do_patch_instruction(ppc_inst *addr, ppc_inst instr) { return raw_patch_instruction(addr, instr); } @@ -194,7 +195,7 @@ int patch_instruction(unsigned int *addr, unsigned int instr) } NOKPROBE_SYMBOL(patch_instruction); -int patch_branch(unsigned int *addr, unsigned long target, int flags) +int patch_branch(ppc_inst *addr, unsigned long target, int flags) { return patch_instruction(addr, create_branch(addr, target, flags)); } @@ -225,7 +226,7 @@ bool is_offset_in_branch_range(long offset) * Helper to check if a given instruction is a conditional branch * Derived from the conditional checks in analyse_instr() */ -bool is_conditional_branch(unsigned int instr) +bool is_conditional_branch(ppc_inst instr) { unsigned int opcode = instr >> 26; @@ -243,10 +244,10 @@ bool is_conditional_branch(unsigned int instr) } NOKPROBE_SYMBOL(is_conditional_branch); -unsigned int create_branch(const unsigned int *addr, +ppc_inst create_branch(const ppc_inst *addr, unsigned long target, int flags) { - unsigned int instruction; + ppc_inst instruction; long offset; offset = target; @@ -266,7 +267,7 @@ unsigned int create_branch(const unsigned int *addr, unsigned int create_cond_branch(const unsigned int *addr, unsigned long target, int flags) { - unsigned int instruction; + ppc_inst instruction; long offset; offset = target; @@ -283,22 +284,22 @@ unsigned int create_cond_branch(const unsigned int *addr, return instruction; } -static unsigned int branch_opcode(unsigned int instr) +static unsigned int branch_opcode(ppc_inst instr) { return (instr >> 26) & 0x3F; } -static int instr_is_branch_iform(unsigned int instr) +static int instr_is_branch_iform(ppc_inst instr) { return branch_opcode(instr) == 18; } -static int instr_is_branch_bform(unsigned int instr) +static int instr_is_branch_bform(ppc_inst instr) { return branch_opcode(instr) == 16; } -int instr_is_relative_branch(unsigned int instr) +int instr_is_relative_branch(ppc_inst instr) { if (instr & BRANCH_ABSOLUTE) return 0; @@ -306,12 +307,12 @@ int instr_is_relative_branch(unsigned int instr) return instr_is_branch_iform(instr) || instr_is_branch_bform(instr); } -int instr_is_relative_link_branch(unsigned int instr) +int instr_is_relative_link_branch(ppc_inst instr) { return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK); } -static unsigned long branch_iform_target(const unsigned int *instr) +static unsigned long branch_iform_target(const ppc_inst *instr) { signed long imm; @@ -327,7 +328,7 @@ static unsigned long branch_iform_target(const unsigned int *instr) return (unsigned long)imm; } -static unsigned long branch_bform_target(const unsigned int *instr) +static unsigned long branch_bform_target(const ppc_inst *instr) { signed long imm; @@ -343,7 +344,7 @@ static unsigned long branch_bform_target(const unsigned int *instr) return (unsigned long)imm; } -unsigned long branch_target(const unsigned int *instr) +unsigned long branch_target(const ppc_inst *instr) { if (instr_is_branch_iform(*instr)) return branch_iform_target(instr); @@ -353,7 +354,7 @@ unsigned long branch_target(const unsigned int *instr) return 0; } -int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr) +int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr) { if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr)) return branch_target(instr) == addr; @@ -361,7 +362,7 @@ int instr_is_branch_to_addr(const unsigned int *instr, unsigned long addr) return 0; } -unsigned int translate_branch(const unsigned int *dest, const unsigned int *src) +ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src) { unsigned long target; @@ -403,7 +404,7 @@ static void __init test_trampoline(void) static void __init test_branch_iform(void) { - unsigned int instr; + ppc_inst instr; unsigned long addr; addr = (unsigned long)&instr; @@ -478,11 +479,11 @@ static void __init test_branch_iform(void) static void __init test_create_function_call(void) { - unsigned int *iptr; + ppc_inst *iptr; unsigned long dest; /* Check we can create a function call */ - iptr = (unsigned int *)ppc_function_entry(test_trampoline); + iptr = (ppc_inst *)ppc_function_entry(test_trampoline); dest = ppc_function_entry(test_create_function_call); patch_instruction(iptr, create_branch(iptr, dest, BRANCH_SET_LINK)); check(instr_is_branch_to_addr(iptr, dest)); @@ -491,7 +492,8 @@ static void __init test_create_function_call(void) static void __init test_branch_bform(void) { unsigned long addr; - unsigned int *iptr, instr, flags; + ppc_inst *iptr, instr; + unsigned int flags; iptr = &instr; addr = (unsigned long)iptr; @@ -561,7 +563,7 @@ static void __init test_branch_bform(void) static void __init test_translate_branch(void) { unsigned long addr; - unsigned int *p, *q; + ppc_inst *p, *q; void *buf; buf = vmalloc(PAGE_ALIGN(0x2000000 + 1)); diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index c077acb983a1..1d9c766a89fe 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -1163,7 +1163,7 @@ static nokprobe_inline int trap_compare(long v1, long v2) * otherwise. */ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, - unsigned int instr) + ppc_inst instr) { unsigned int opcode, ra, rb, rc, rd, spr, u; unsigned long int imm; @@ -3101,7 +3101,7 @@ NOKPROBE_SYMBOL(emulate_loadstore); * or -1 if the instruction is one that should not be stepped, * such as an rfid, or a mtmsrd that would clear MSR_RI. */ -int emulate_step(struct pt_regs *regs, unsigned int instr) +int emulate_step(struct pt_regs *regs, ppc_inst instr) { struct instruction_op op; int r, err, type; diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c index 42347067739c..158efc8a0f53 100644 --- a/arch/powerpc/lib/test_emulate_step.c +++ b/arch/powerpc/lib/test_emulate_step.c @@ -460,7 +460,7 @@ struct compute_test { struct { char *descr; unsigned long flags; - unsigned int instr; + ppc_inst instr; struct pt_regs regs; } subtests[MAX_SUBTESTS + 1]; }; @@ -841,7 +841,7 @@ static struct compute_test compute_tests[] = { }; static int __init emulate_compute_instr(struct pt_regs *regs, - unsigned int instr) + ppc_inst instr) { struct instruction_op op; @@ -859,7 +859,7 @@ static int __init emulate_compute_instr(struct pt_regs *regs, } static int __init execute_compute_instr(struct pt_regs *regs, - unsigned int instr) + ppc_inst instr) { extern int exec_instr(struct pt_regs *regs); extern s32 patch__exec_instr; @@ -890,7 +890,8 @@ static void __init run_tests_compute(void) unsigned long flags; struct compute_test *test; struct pt_regs *regs, exp, got; - unsigned int i, j, k, instr; + unsigned int i, j, k; + ppc_inst instr; bool ignore_gpr, ignore_xer, ignore_ccr, passed; for (i = 0; i < ARRAY_SIZE(compute_tests); i++) { diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 7875d1a37770..a0bc442f9557 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -892,7 +892,7 @@ static struct bpt *new_breakpoint(unsigned long a) static void insert_bpts(void) { int i; - unsigned int instr; + ppc_inst instr; struct bpt *bp; bp = bpts; @@ -914,7 +914,7 @@ static void insert_bpts(void) patch_instruction(bp->instr, instr); if (bp->enabled & BP_CIABR) continue; - if (patch_instruction((unsigned int *)bp->address, + if (patch_instruction((ppc_inst *)bp->address, bpinstr) != 0) { printf("Couldn't write instruction at %lx, " "disabling breakpoint there\n", bp->address); @@ -943,7 +943,7 @@ static void remove_bpts(void) { int i; struct bpt *bp; - unsigned instr; + ppc_inst instr; bp = bpts; for (i = 0; i < NBPTS; ++i, ++bp) { @@ -952,7 +952,7 @@ static void remove_bpts(void) if (mread(bp->address, &instr, 4) == 4 && instr == bpinstr && patch_instruction( - (unsigned int *)bp->address, bp->instr[0]) != 0) + (ppc_inst *)bp->address, bp->instr[0]) != 0) printf("Couldn't remove breakpoint at %lx\n", bp->address); } @@ -1159,7 +1159,7 @@ static int do_step(struct pt_regs *regs) */ static int do_step(struct pt_regs *regs) { - unsigned int instr; + ppc_inst instr; int stepped; force_enable_xmon(); @@ -1325,7 +1325,7 @@ csum(void) */ static long check_bp_loc(unsigned long addr) { - unsigned int instr; + ppc_inst instr; addr &= ~3; if (!is_kernel_addr(addr)) { From patchwork Fri Mar 20 05:17:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258636 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kC2N6Mznz9sP7 for ; Fri, 20 Mar 2020 16:27:08 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=alBbNAUo; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kC2N633rzDrdp for ; Fri, 20 Mar 2020 16:27:08 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::444; helo=mail-pf1-x444.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=alBbNAUo; dkim-atps=neutral Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBs62BvgzDrWV for ; Fri, 20 Mar 2020 16:19:06 +1100 (AEDT) Received: by mail-pf1-x444.google.com with SMTP id h72so417895pfe.4 for ; Thu, 19 Mar 2020 22:19:06 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dqeMGrxodA+CYnGK5c5KdAC9+4fYmINBb4xFNckuNws=; b=alBbNAUo34peKgcv9bd61dOLZP2+Z1HZz3hdHcGbqWE1VA9PLJbwXdQe16bLOrxDkP htF6DLuD5g5YFr4FK2kjrIymEucTvpwr2dt/V8VjQri0AQAVmQGfyELAXXyDsfzPct1r LbJLvmP/m9gZ5e2mi/4lzqhXIGvfXlJ7qPCpBy+42IBQAZ9FV3oaKyC/VSD0t+iNSi1Q aDeCzcZSBRiMvZuBzXx2KVm3dt0DgrSBuTc4aXhouCoZOJdlRgdnKD6Qq7G2ZxXEbr4O qEM6jMpCp+sC3lD9XZSRLpcAd5DFJPuvyMfbZBWGST0mX3twN1O3Nq5XCtOzZypcNTC8 h+yw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=dqeMGrxodA+CYnGK5c5KdAC9+4fYmINBb4xFNckuNws=; b=asAYDHZVNtuFSCP/64kbFY0qND0W/1lx5lJxyeavsT4YeINF125XK2x2zq/MFLYDpH 67WwSHxmoSyi6b79xtr1fO8aiLdeZZf2VjT46rv3YvRuKI49efxiVnsxdlDAEdByaygl P+/C78+z6Rj7+Etxy8LbIbaj2CmUySFBdQmWfq9dMiKB4yHZWRYtdkTWC2wLlP8jwPlX fhAjodSflK5Mri1jXomKuWRs/txsf/Vxz9Da7iFReL+r1F2X2CMzG5WkICOgyTysPV77 /m8SDHPXFRHAsOy5Zm8iGglEkeVE4aju7OcGCtQBqL/Jym7lBfPh994AliHwiewCa+k4 y0Og== X-Gm-Message-State: ANhLgQ1Eow1C0jL7rMsbQBGl7onEhIfI9FrXF0eMUx0+/uNu6CTb7CtH bDt+ZzTnSQNQrTdFNMlI5vyQSzvwc7g= X-Google-Smtp-Source: ADFU+vuqIjX/igDphiwvQJTGVo/eGSOestELHLwFAUCEhGJLvsz+Jt7YD5pZdqf3dZlBzsv1mZhisg== X-Received: by 2002:a63:a504:: with SMTP id n4mr6753282pgf.373.1584681543401; Thu, 19 Mar 2020 22:19:03 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.18.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:03 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 04/16] powerpc: Use a macro for creating instructions from u32s Date: Fri, 20 Mar 2020 16:17:57 +1100 Message-Id: <20200320051809.24332-5-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" In preparation for instructions having a more complex data type start using a macro, PPC_INST(), for making an instruction out of a u32. Currently this does nothing, but it will allow for creating a data type that can represent prefixed instructions. Signed-off-by: Jordan Niethe --- v4: New to series --- arch/powerpc/include/asm/code-patching.h | 2 +- arch/powerpc/kernel/align.c | 2 +- arch/powerpc/kernel/hw_breakpoint.c | 2 +- arch/powerpc/kernel/jump_label.c | 2 +- arch/powerpc/kernel/kprobes.c | 4 +- arch/powerpc/kernel/module_64.c | 2 +- arch/powerpc/kernel/optprobes.c | 30 +++++------ arch/powerpc/kernel/security.c | 8 +-- arch/powerpc/kernel/trace/ftrace.c | 24 ++++----- arch/powerpc/kvm/emulate_loadstore.c | 2 +- arch/powerpc/lib/code-patching.c | 64 ++++++++++++------------ arch/powerpc/lib/feature-fixups.c | 39 ++++++++------- arch/powerpc/lib/test_emulate_step.c | 39 ++++++++------- arch/powerpc/xmon/xmon.c | 11 ++-- 14 files changed, 117 insertions(+), 114 deletions(-) diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index cb5106f92d67..68bd9db334bd 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -49,7 +49,7 @@ static inline int patch_branch_site(s32 *site, unsigned long target, int flags) static inline int modify_instruction(unsigned int *addr, unsigned int clr, unsigned int set) { - return patch_instruction(addr, (*addr & ~clr) | set); + return patch_instruction(addr, PPC_INST((*addr & ~clr) | set)); } static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned int set) diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 34594aaa44de..6008f14a145b 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -309,7 +309,7 @@ int fix_alignment(struct pt_regs *regs) /* We don't handle PPC little-endian any more... */ if (cpu_has_feature(CPU_FTR_PPC_LE)) return -EIO; - instr = swab32(instr); + instr = PPC_INST(swab32(instr)); } #ifdef CONFIG_SPE diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index 06b97353d231..f001de471b98 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -244,7 +244,7 @@ dar_range_overlaps(unsigned long dar, int size, struct arch_hw_breakpoint *info) static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp, struct arch_hw_breakpoint *info) { - ppc_inst instr = 0; + ppc_inst instr = PPC_INST(0); int ret, type, size; struct instruction_op op; unsigned long addr = info->address; diff --git a/arch/powerpc/kernel/jump_label.c b/arch/powerpc/kernel/jump_label.c index ca37702bde97..8d86d1101782 100644 --- a/arch/powerpc/kernel/jump_label.c +++ b/arch/powerpc/kernel/jump_label.c @@ -15,5 +15,5 @@ void arch_jump_label_transform(struct jump_entry *entry, if (type == JUMP_LABEL_JMP) patch_branch(addr, entry->target, 0); else - patch_instruction(addr, PPC_INST_NOP); + patch_instruction(addr, PPC_INST(PPC_INST_NOP)); } diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index e7205adc9820..4c2b656615a6 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -147,13 +147,13 @@ NOKPROBE_SYMBOL(arch_prepare_kprobe); void arch_arm_kprobe(struct kprobe *p) { - patch_instruction(p->addr, BREAKPOINT_INSTRUCTION); + patch_instruction(p->addr, PPC_INST(BREAKPOINT_INSTRUCTION)); } NOKPROBE_SYMBOL(arch_arm_kprobe); void arch_disarm_kprobe(struct kprobe *p) { - patch_instruction(p->addr, p->opcode); + patch_instruction(p->addr, PPC_INST(p->opcode)); } NOKPROBE_SYMBOL(arch_disarm_kprobe); diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 007606a48fd9..fdec1be9cec8 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -506,7 +506,7 @@ static int restore_r2(const char *name, u32 *instruction, struct module *me) * "link" branches and they don't return, so they don't need the r2 * restore afterwards. */ - if (!instr_is_relative_link_branch(*prev_insn)) + if (!instr_is_relative_link_branch(PPC_INST(*prev_insn))) return 1; if (*instruction != PPC_INST_NOP) { diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index f5e8cce438a3..1025a7a3b3a8 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -147,13 +147,13 @@ void arch_remove_optimized_kprobe(struct optimized_kprobe *op) void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr) { /* addis r4,0,(insn)@h */ - patch_instruction(addr, PPC_INST_ADDIS | ___PPC_RT(4) | - ((val >> 16) & 0xffff)); + patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(4) | + ((val >> 16) & 0xffff))); addr++; /* ori r4,r4,(insn)@l */ - patch_instruction(addr, PPC_INST_ORI | ___PPC_RA(4) | - ___PPC_RS(4) | (val & 0xffff)); + patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(4) | + ___PPC_RS(4) | (val & 0xffff))); } /* @@ -163,28 +163,28 @@ void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr) void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr) { /* lis r3,(op)@highest */ - patch_instruction(addr, PPC_INST_ADDIS | ___PPC_RT(3) | - ((val >> 48) & 0xffff)); + patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(3) | + ((val >> 48) & 0xffff))); addr++; /* ori r3,r3,(op)@higher */ - patch_instruction(addr, PPC_INST_ORI | ___PPC_RA(3) | - ___PPC_RS(3) | ((val >> 32) & 0xffff)); + patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) | + ___PPC_RS(3) | ((val >> 32) & 0xffff))); addr++; /* rldicr r3,r3,32,31 */ - patch_instruction(addr, PPC_INST_RLDICR | ___PPC_RA(3) | - ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31)); + patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(3) | + ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31))); addr++; /* oris r3,r3,(op)@h */ - patch_instruction(addr, PPC_INST_ORIS | ___PPC_RA(3) | - ___PPC_RS(3) | ((val >> 16) & 0xffff)); + patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(3) | + ___PPC_RS(3) | ((val >> 16) & 0xffff))); addr++; /* ori r3,r3,(op)@l */ - patch_instruction(addr, PPC_INST_ORI | ___PPC_RA(3) | - ___PPC_RS(3) | (val & 0xffff)); + patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) | + ___PPC_RS(3) | (val & 0xffff))); } int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) @@ -230,7 +230,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) size = (TMPL_END_IDX * sizeof(kprobe_opcode_t)) / sizeof(int); pr_devel("Copying template to %p, size %lu\n", buff, size); for (i = 0; i < size; i++) { - rc = patch_instruction(buff + i, *(optprobe_template_entry + i)); + rc = patch_instruction(buff + i, PPC_INST(*(optprobe_template_entry + i))); if (rc < 0) goto error; } diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c index bd70f5be1c27..693c68e2aa67 100644 --- a/arch/powerpc/kernel/security.c +++ b/arch/powerpc/kernel/security.c @@ -403,9 +403,9 @@ static void toggle_count_cache_flush(bool enable) enable = false; if (!enable) { - patch_instruction_site(&patch__call_flush_count_cache, PPC_INST_NOP); + patch_instruction_site(&patch__call_flush_count_cache, PPC_INST(PPC_INST_NOP)); #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE - patch_instruction_site(&patch__call_kvm_flush_link_stack, PPC_INST_NOP); + patch_instruction_site(&patch__call_kvm_flush_link_stack, PPC_INST(PPC_INST_NOP)); #endif pr_info("link-stack-flush: software flush disabled.\n"); link_stack_flush_enabled = false; @@ -428,7 +428,7 @@ static void toggle_count_cache_flush(bool enable) // If we just need to flush the link stack, patch an early return if (!security_ftr_enabled(SEC_FTR_FLUSH_COUNT_CACHE)) { - patch_instruction_site(&patch__flush_link_stack_return, PPC_INST_BLR); + patch_instruction_site(&patch__flush_link_stack_return, PPC_INST(PPC_INST_BLR)); no_count_cache_flush(); return; } @@ -439,7 +439,7 @@ static void toggle_count_cache_flush(bool enable) return; } - patch_instruction_site(&patch__flush_count_cache_return, PPC_INST_BLR); + patch_instruction_site(&patch__flush_count_cache_return, PPC_INST(PPC_INST_BLR)); count_cache_flush_type = COUNT_CACHE_FLUSH_HW; pr_info("count-cache-flush: hardware assisted flush sequence enabled\n"); } diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index 5787ccffb4df..380f1ce77715 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -161,7 +161,7 @@ __ftrace_make_nop(struct module *mod, #ifdef CONFIG_MPROFILE_KERNEL /* When using -mkernel_profile there is no load to jump over */ - pop = PPC_INST_NOP; + pop = PPC_INST(PPC_INST_NOP); if (probe_kernel_read(&op, (void *)(ip - 4), 4)) { pr_err("Fetching instruction at %lx failed.\n", ip - 4); @@ -169,7 +169,7 @@ __ftrace_make_nop(struct module *mod, } /* We expect either a mflr r0, or a std r0, LRSAVE(r1) */ - if (op != PPC_INST_MFLR && op != PPC_INST_STD_LR) { + if (op != PPC_INST(PPC_INST_MFLR) && op != PPC_INST(PPC_INST_STD_LR)) { pr_err("Unexpected instruction %08x around bl _mcount\n", op); return -EINVAL; } @@ -188,7 +188,7 @@ __ftrace_make_nop(struct module *mod, * Use a b +8 to jump over the load. */ - pop = PPC_INST_BRANCH | 8; /* b +8 */ + pop = PPC_INST(PPC_INST_BRANCH | 8); /* b +8 */ /* * Check what is in the next instruction. We can see ld r2,40(r1), but @@ -199,7 +199,7 @@ __ftrace_make_nop(struct module *mod, return -EFAULT; } - if (op != PPC_INST_LD_TOC) { + if (op != PPC_INST(PPC_INST_LD_TOC)) { pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op); return -EINVAL; } @@ -275,7 +275,7 @@ __ftrace_make_nop(struct module *mod, return -EINVAL; } - op = PPC_INST_NOP; + op = PPC_INST(PPC_INST_NOP); if (patch_instruction((ppc_inst *)ip, op)) return -EPERM; @@ -418,7 +418,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr) } } - if (patch_instruction((ppc_inst *)ip, PPC_INST_NOP)) { + if (patch_instruction((ppc_inst *)ip, PPC_INST(PPC_INST_NOP))) { pr_err("Patching NOP failed.\n"); return -EPERM; } @@ -440,7 +440,7 @@ int ftrace_make_nop(struct module *mod, if (test_24bit_addr(ip, addr)) { /* within range */ old = ftrace_call_replace(ip, addr, 1); - new = PPC_INST_NOP; + new = PPC_INST(PPC_INST_NOP); return ftrace_modify_code(ip, old, new); } else if (core_kernel_text(ip)) return __ftrace_make_nop_kernel(rec, addr); @@ -500,10 +500,10 @@ expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1) } #else static int -expected_nop_sequence(void *ip, unsigned int op0, unsigned int op1) +expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1) { /* look for patched "NOP" on ppc64 with -mprofile-kernel */ - if (op0 != PPC_INST_NOP) + if (op0 != PPC_INST(PPC_INST_NOP)) return 0; return 1; } @@ -584,7 +584,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) return -EFAULT; /* It should be pointing to a nop */ - if (op != PPC_INST_NOP) { + if (op != PPC_INST(PPC_INST_NOP)) { pr_err("Expected NOP but have %x\n", op); return -EINVAL; } @@ -641,7 +641,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr) return -EFAULT; } - if (op != PPC_INST_NOP) { + if (op != PPC_INST(PPC_INST_NOP)) { pr_err("Unexpected call sequence at %p: %x\n", ip, op); return -EINVAL; } @@ -672,7 +672,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) */ if (test_24bit_addr(ip, addr)) { /* within range */ - old = PPC_INST_NOP; + old = PPC_INST(PPC_INST_NOP); new = ftrace_call_replace(ip, addr, 1); return ftrace_modify_code(ip, old, new); } else if (core_kernel_text(ip)) diff --git a/arch/powerpc/kvm/emulate_loadstore.c b/arch/powerpc/kvm/emulate_loadstore.c index 1c9bcbfeb924..ed8cd109f884 100644 --- a/arch/powerpc/kvm/emulate_loadstore.c +++ b/arch/powerpc/kvm/emulate_loadstore.c @@ -96,7 +96,7 @@ int kvmppc_emulate_loadstore(struct kvm_vcpu *vcpu) emulated = EMULATE_FAIL; vcpu->arch.regs.msr = vcpu->arch.shared->msr; - if (analyse_instr(&op, &vcpu->arch.regs, inst) == 0) { + if (analyse_instr(&op, &vcpu->arch.regs, PPC_INST(inst)) == 0) { int type = op.type & INSTR_TYPE_MASK; int size = GETSIZE(op.type); diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 8492b9e2b8db..5d69e836337d 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -256,10 +256,10 @@ ppc_inst create_branch(const ppc_inst *addr, /* Check we can represent the target in the instruction format */ if (!is_offset_in_branch_range(offset)) - return 0; + return PPC_INST(0); /* Mask out the flags and target, so they don't step on each other. */ - instruction = 0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC); + instruction = PPC_INST(0x48000000 | (flags & 0x3) | (offset & 0x03FFFFFC)); return instruction; } @@ -276,10 +276,10 @@ unsigned int create_cond_branch(const unsigned int *addr, /* Check we can represent the target in the instruction format */ if (offset < -0x8000 || offset > 0x7FFF || offset & 0x3) - return 0; + return PPC_INST(0); /* Mask out the flags and target, so they don't step on each other. */ - instruction = 0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC); + instruction = PPC_INST(0x40000000 | (flags & 0x3FF0003) | (offset & 0xFFFC)); return instruction; } @@ -373,7 +373,7 @@ ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src) else if (instr_is_branch_bform(*src)) return create_cond_branch(dest, target, *src); - return 0; + return PPC_INST(0); } #ifdef CONFIG_PPC_BOOK3E_64 @@ -410,37 +410,37 @@ static void __init test_branch_iform(void) addr = (unsigned long)&instr; /* The simplest case, branch to self, no flags */ - check(instr_is_branch_iform(0x48000000)); + check(instr_is_branch_iform(PPC_INST(0x48000000))); /* All bits of target set, and flags */ - check(instr_is_branch_iform(0x4bffffff)); + check(instr_is_branch_iform(PPC_INST(0x4bffffff))); /* High bit of opcode set, which is wrong */ - check(!instr_is_branch_iform(0xcbffffff)); + check(!instr_is_branch_iform(PPC_INST(0xcbffffff))); /* Middle bits of opcode set, which is wrong */ - check(!instr_is_branch_iform(0x7bffffff)); + check(!instr_is_branch_iform(PPC_INST(0x7bffffff))); /* Simplest case, branch to self with link */ - check(instr_is_branch_iform(0x48000001)); + check(instr_is_branch_iform(PPC_INST(0x48000001))); /* All bits of targets set */ - check(instr_is_branch_iform(0x4bfffffd)); + check(instr_is_branch_iform(PPC_INST(0x4bfffffd))); /* Some bits of targets set */ - check(instr_is_branch_iform(0x4bff00fd)); + check(instr_is_branch_iform(PPC_INST(0x4bff00fd))); /* Must be a valid branch to start with */ - check(!instr_is_branch_iform(0x7bfffffd)); + check(!instr_is_branch_iform(PPC_INST(0x7bfffffd))); /* Absolute branch to 0x100 */ - instr = 0x48000103; + instr = PPC_INST(0x48000103); check(instr_is_branch_to_addr(&instr, 0x100)); /* Absolute branch to 0x420fc */ - instr = 0x480420ff; + instr = PPC_INST(0x480420ff); check(instr_is_branch_to_addr(&instr, 0x420fc)); /* Maximum positive relative branch, + 20MB - 4B */ - instr = 0x49fffffc; + instr = PPC_INST(0x49fffffc); check(instr_is_branch_to_addr(&instr, addr + 0x1FFFFFC)); /* Smallest negative relative branch, - 4B */ - instr = 0x4bfffffc; + instr = PPC_INST(0x4bfffffc); check(instr_is_branch_to_addr(&instr, addr - 4)); /* Largest negative relative branch, - 32 MB */ - instr = 0x4a000000; + instr = PPC_INST(0x4a000000); check(instr_is_branch_to_addr(&instr, addr - 0x2000000)); /* Branch to self, with link */ @@ -474,7 +474,7 @@ static void __init test_branch_iform(void) /* Check flags are masked correctly */ instr = create_branch(&instr, addr, 0xFFFFFFFC); check(instr_is_branch_to_addr(&instr, addr)); - check(instr == 0x48000000); + check(instr == PPC_INST(0x48000000)); } static void __init test_create_function_call(void) @@ -499,28 +499,28 @@ static void __init test_branch_bform(void) addr = (unsigned long)iptr; /* The simplest case, branch to self, no flags */ - check(instr_is_branch_bform(0x40000000)); + check(instr_is_branch_bform(PPC_INST(0x40000000))); /* All bits of target set, and flags */ - check(instr_is_branch_bform(0x43ffffff)); + check(instr_is_branch_bform(PPC_INST(0x43ffffff))); /* High bit of opcode set, which is wrong */ - check(!instr_is_branch_bform(0xc3ffffff)); + check(!instr_is_branch_bform(PPC_INST(0xc3ffffff))); /* Middle bits of opcode set, which is wrong */ - check(!instr_is_branch_bform(0x7bffffff)); + check(!instr_is_branch_bform(PPC_INST(0x7bffffff))); /* Absolute conditional branch to 0x100 */ - instr = 0x43ff0103; + instr = PPC_INST(0x43ff0103); check(instr_is_branch_to_addr(&instr, 0x100)); /* Absolute conditional branch to 0x20fc */ - instr = 0x43ff20ff; + instr = PPC_INST(0x43ff20ff); check(instr_is_branch_to_addr(&instr, 0x20fc)); /* Maximum positive relative conditional branch, + 32 KB - 4B */ - instr = 0x43ff7ffc; + instr = PPC_INST(0x43ff7ffc); check(instr_is_branch_to_addr(&instr, addr + 0x7FFC)); /* Smallest negative relative conditional branch, - 4B */ - instr = 0x43fffffc; + instr = PPC_INST(0x43fffffc); check(instr_is_branch_to_addr(&instr, addr - 4)); /* Largest negative relative conditional branch, - 32 KB */ - instr = 0x43ff8000; + instr = PPC_INST(0x43ff8000); check(instr_is_branch_to_addr(&instr, addr - 0x8000)); /* All condition code bits set & link */ @@ -588,7 +588,7 @@ static void __init test_translate_branch(void) patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(p, addr)); check(instr_is_branch_to_addr(q, addr)); - check(*q == 0x4a000000); + check(*q == PPC_INST(0x4a000000)); /* Maximum positive case, move x to x - 32 MB + 4 */ p = buf + 0x2000000; @@ -598,7 +598,7 @@ static void __init test_translate_branch(void) patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(p, addr)); check(instr_is_branch_to_addr(q, addr)); - check(*q == 0x49fffffc); + check(*q == PPC_INST(0x49fffffc)); /* Jump to x + 16 MB moved to x + 20 MB */ p = buf; @@ -638,7 +638,7 @@ static void __init test_translate_branch(void) patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(p, addr)); check(instr_is_branch_to_addr(q, addr)); - check(*q == 0x43ff8000); + check(*q == PPC_INST(0x43ff8000)); /* Maximum positive case, move x to x - 32 KB + 4 */ p = buf + 0x8000; @@ -648,7 +648,7 @@ static void __init test_translate_branch(void) patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(p, addr)); check(instr_is_branch_to_addr(q, addr)); - check(*q == 0x43ff7ffc); + check(*q == PPC_INST(0x43ff7ffc)); /* Jump to x + 12 KB moved to x + 20 KB */ p = buf; diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 4ba634b89ce5..a5f3d98862e9 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -21,6 +21,7 @@ #include #include #include +#include struct fixup_entry { unsigned long mask; @@ -88,7 +89,7 @@ static int patch_feature_section(unsigned long value, struct fixup_entry *fcur) } for (; dest < end; dest++) - raw_patch_instruction(dest, PPC_INST_NOP); + raw_patch_instruction(dest, PPC_INST(PPC_INST_NOP)); return 0; } @@ -145,15 +146,15 @@ static void do_stf_entry_barrier_fixups(enum stf_barrier_type types) pr_devel("patching dest %lx\n", (unsigned long)dest); - patch_instruction(dest, instrs[0]); + patch_instruction(dest, PPC_INST(instrs[0])); if (types & STF_BARRIER_FALLBACK) patch_branch(dest + 1, (unsigned long)&stf_barrier_fallback, BRANCH_SET_LINK); else - patch_instruction(dest + 1, instrs[1]); + patch_instruction(dest + 1, PPC_INST(instrs[1])); - patch_instruction(dest + 2, instrs[2]); + patch_instruction(dest + 2, PPC_INST(instrs[2])); } printk(KERN_DEBUG "stf-barrier: patched %d entry locations (%s barrier)\n", i, @@ -206,12 +207,12 @@ static void do_stf_exit_barrier_fixups(enum stf_barrier_type types) pr_devel("patching dest %lx\n", (unsigned long)dest); - patch_instruction(dest, instrs[0]); - patch_instruction(dest + 1, instrs[1]); - patch_instruction(dest + 2, instrs[2]); - patch_instruction(dest + 3, instrs[3]); - patch_instruction(dest + 4, instrs[4]); - patch_instruction(dest + 5, instrs[5]); + patch_instruction(dest, PPC_INST(instrs[0])); + patch_instruction(dest + 1, PPC_INST(instrs[1])); + patch_instruction(dest + 2, PPC_INST(instrs[2])); + patch_instruction(dest + 3, PPC_INST(instrs[3])); + patch_instruction(dest + 4, PPC_INST(instrs[4])); + patch_instruction(dest + 5, PPC_INST(instrs[5])); } printk(KERN_DEBUG "stf-barrier: patched %d exit locations (%s barrier)\n", i, (types == STF_BARRIER_NONE) ? "no" : @@ -259,9 +260,9 @@ void do_rfi_flush_fixups(enum l1d_flush_type types) pr_devel("patching dest %lx\n", (unsigned long)dest); - patch_instruction(dest, instrs[0]); - patch_instruction(dest + 1, instrs[1]); - patch_instruction(dest + 2, instrs[2]); + patch_instruction(dest, PPC_INST(instrs[0])); + patch_instruction(dest + 1, PPC_INST(instrs[1])); + patch_instruction(dest + 2, PPC_INST(instrs[2])); } printk(KERN_DEBUG "rfi-flush: patched %d locations (%s flush)\n", i, @@ -294,7 +295,7 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_ dest = (void *)start + *start; pr_devel("patching dest %lx\n", (unsigned long)dest); - patch_instruction(dest, instr); + patch_instruction(dest, PPC_INST(instr)); } printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i); @@ -337,8 +338,8 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_ dest = (void *)start + *start; pr_devel("patching dest %lx\n", (unsigned long)dest); - patch_instruction(dest, instr[0]); - patch_instruction(dest + 1, instr[1]); + patch_instruction(dest, PPC_INST(instr[0])); + patch_instruction(dest + 1, PPC_INST(instr[1])); } printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i); @@ -352,7 +353,7 @@ static void patch_btb_flush_section(long *curr) end = (void *)curr + *(curr + 1); for (; start < end; start++) { pr_devel("patching dest %lx\n", (unsigned long)start); - patch_instruction(start, PPC_INST_NOP); + patch_instruction(start, PPC_INST(PPC_INST_NOP)); } } @@ -381,7 +382,7 @@ void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end) for (; start < end; start++) { dest = (void *)start + *start; - raw_patch_instruction(dest, PPC_INST_LWSYNC); + raw_patch_instruction(dest, PPC_INST(PPC_INST_LWSYNC)); } } @@ -399,7 +400,7 @@ static void do_final_fixups(void) length = (__end_interrupts - _stext) / sizeof(int); while (length--) { - raw_patch_instruction(dest, *src); + raw_patch_instruction(dest, PPC_INST(*src)); src++; dest++; } diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c index 158efc8a0f53..227ebae9ba5a 100644 --- a/arch/powerpc/lib/test_emulate_step.c +++ b/arch/powerpc/lib/test_emulate_step.c @@ -11,6 +11,7 @@ #include #include #include +#include #define IMM_L(i) ((uintptr_t)(i) & 0xffff) @@ -18,40 +19,40 @@ * Defined with TEST_ prefix so it does not conflict with other * definitions. */ -#define TEST_LD(r, base, i) (PPC_INST_LD | ___PPC_RT(r) | \ +#define TEST_LD(r, base, i) PPC_INST(PPC_INST_LD | ___PPC_RT(r) | \ ___PPC_RA(base) | IMM_L(i)) -#define TEST_LWZ(r, base, i) (PPC_INST_LWZ | ___PPC_RT(r) | \ +#define TEST_LWZ(r, base, i) PPC_INST(PPC_INST_LWZ | ___PPC_RT(r) | \ ___PPC_RA(base) | IMM_L(i)) -#define TEST_LWZX(t, a, b) (PPC_INST_LWZX | ___PPC_RT(t) | \ +#define TEST_LWZX(t, a, b) PPC_INST(PPC_INST_LWZX | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_STD(r, base, i) (PPC_INST_STD | ___PPC_RS(r) | \ +#define TEST_STD(r, base, i) PPC_INST(PPC_INST_STD | ___PPC_RS(r) | \ ___PPC_RA(base) | ((i) & 0xfffc)) -#define TEST_LDARX(t, a, b, eh) (PPC_INST_LDARX | ___PPC_RT(t) | \ +#define TEST_LDARX(t, a, b, eh) PPC_INST(PPC_INST_LDARX | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b) | \ __PPC_EH(eh)) -#define TEST_STDCX(s, a, b) (PPC_INST_STDCX | ___PPC_RS(s) | \ +#define TEST_STDCX(s, a, b) PPC_INST(PPC_INST_STDCX | ___PPC_RS(s) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_LFSX(t, a, b) (PPC_INST_LFSX | ___PPC_RT(t) | \ +#define TEST_LFSX(t, a, b) PPC_INST(PPC_INST_LFSX | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_STFSX(s, a, b) (PPC_INST_STFSX | ___PPC_RS(s) | \ +#define TEST_STFSX(s, a, b) PPC_INST(PPC_INST_STFSX | ___PPC_RS(s) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_LFDX(t, a, b) (PPC_INST_LFDX | ___PPC_RT(t) | \ +#define TEST_LFDX(t, a, b) PPC_INST(PPC_INST_LFDX | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_STFDX(s, a, b) (PPC_INST_STFDX | ___PPC_RS(s) | \ +#define TEST_STFDX(s, a, b) PPC_INST(PPC_INST_STFDX | ___PPC_RS(s) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_LVX(t, a, b) (PPC_INST_LVX | ___PPC_RT(t) | \ +#define TEST_LVX(t, a, b) PPC_INST(PPC_INST_LVX | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_STVX(s, a, b) (PPC_INST_STVX | ___PPC_RS(s) | \ +#define TEST_STVX(s, a, b) PPC_INST(PPC_INST_STVX | ___PPC_RS(s) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_LXVD2X(s, a, b) (PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b)) -#define TEST_STXVD2X(s, a, b) (PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b)) -#define TEST_ADD(t, a, b) (PPC_INST_ADD | ___PPC_RT(t) | \ +#define TEST_LXVD2X(s, a, b) PPC_INST(PPC_INST_LXVD2X | VSX_XX1((s), R##a, R##b)) +#define TEST_STXVD2X(s, a, b) PPC_INST(PPC_INST_STXVD2X | VSX_XX1((s), R##a, R##b)) +#define TEST_ADD(t, a, b) PPC_INST(PPC_INST_ADD | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_ADD_DOT(t, a, b) (PPC_INST_ADD | ___PPC_RT(t) | \ +#define TEST_ADD_DOT(t, a, b) PPC_INST(PPC_INST_ADD | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b) | 0x1) -#define TEST_ADDC(t, a, b) (PPC_INST_ADDC | ___PPC_RT(t) | \ +#define TEST_ADDC(t, a, b) PPC_INST(PPC_INST_ADDC | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b)) -#define TEST_ADDC_DOT(t, a, b) (PPC_INST_ADDC | ___PPC_RT(t) | \ +#define TEST_ADDC_DOT(t, a, b) PPC_INST(PPC_INST_ADDC | ___PPC_RT(t) | \ ___PPC_RA(a) | ___PPC_RB(b) | 0x1) #define MAX_SUBTESTS 16 @@ -471,7 +472,7 @@ static struct compute_test compute_tests[] = { .subtests = { { .descr = "R0 = LONG_MAX", - .instr = PPC_INST_NOP, + .instr = PPC_INST(PPC_INST_NOP), .regs = { .gpr[0] = LONG_MAX, } diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index a0bc442f9557..f8a7a55e6ab2 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -54,6 +54,7 @@ #include #include #include +#include #ifdef CONFIG_PPC64 #include @@ -880,7 +881,7 @@ static struct bpt *new_breakpoint(unsigned long a) if (!bp->enabled && atomic_read(&bp->ref_count) == 0) { bp->address = a; bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS); - patch_instruction(bp->instr + 1, bpinstr); + patch_instruction(bp->instr + 1, PPC_INST(bpinstr)); return bp; } } @@ -915,7 +916,7 @@ static void insert_bpts(void) if (bp->enabled & BP_CIABR) continue; if (patch_instruction((ppc_inst *)bp->address, - bpinstr) != 0) { + PPC_INST(bpinstr)) != 0) { printf("Couldn't write instruction at %lx, " "disabling breakpoint there\n", bp->address); bp->enabled &= ~BP_TRAP; @@ -950,7 +951,7 @@ static void remove_bpts(void) if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP) continue; if (mread(bp->address, &instr, 4) == 4 - && instr == bpinstr + && instr == PPC_INST(bpinstr) && patch_instruction( (ppc_inst *)bp->address, bp->instr[0]) != 0) printf("Couldn't remove breakpoint at %lx\n", @@ -2846,7 +2847,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr, { int nr, dotted; unsigned long first_adr; - unsigned int inst, last_inst = 0; + ppc_inst inst, last_inst = PPC_INST(0); unsigned char val[4]; dotted = 0; @@ -2859,7 +2860,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr, } break; } - inst = GETWORD(val); + inst = PPC_INST(GETWORD(val)); if (adr > first_adr && inst == last_inst) { if (!dotted) { printf(" ...\n"); From patchwork Fri Mar 20 05:17:58 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258637 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kC4Q1VChz9sPF for ; Fri, 20 Mar 2020 16:28:54 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=JMLQHdcx; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kC4Q0NLnzDrSc for ; Fri, 20 Mar 2020 16:28:54 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::442; helo=mail-pf1-x442.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=JMLQHdcx; dkim-atps=neutral Received: from mail-pf1-x442.google.com (mail-pf1-x442.google.com [IPv6:2607:f8b0:4864:20::442]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBs93BgNzDrTs for ; Fri, 20 Mar 2020 16:19:09 +1100 (AEDT) Received: by mail-pf1-x442.google.com with SMTP id x2so2631435pfn.9 for ; Thu, 19 Mar 2020 22:19:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=S/r32Q7grwQQf3uHgdNTaaRJ9xKAmkDdHphVshqxgn0=; b=JMLQHdcxkOh40BGu5bSQaFy04CDLFvWuwC1l60DUkEp887HDbr97WKEcFFTU4V9wOA oNAx0/8MWlpvwa1QVrfMLNI8ROOt8BhRdbu2ULIjL/5a9mY0yc9wR7TMhQ/cw6l/88jg 4RgZwhs2vNdcuQzZ0kg4sSDinrmriix49FeMNx0mlofROj+zO8DjguBdAGD4Rsbay/zL ApsP7em6uU2mogx7FJwQWyZ+FvgPJ+AX6ItvqoBQQUCTjWWqdyVM752qaM6d42bkyCZI rPPpqoDPJCBSOixCFNw+g+aryAsDrFB+zioqHO5UHPJI/YkIVgPqOEIowbqcGfsOMySu JdFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=S/r32Q7grwQQf3uHgdNTaaRJ9xKAmkDdHphVshqxgn0=; b=VjAmpYeR4sktlz0pmlhVietFy57PI6MQQqv9KoAqik1/TXy4Aac+blRosGRQbWZ0D3 iSHe6GO2o8FxfySFGFlq5VctqoBxRtqehUU0lzMnCXoxqfelQb7M0H3XmmoKiyyWMUkr AkVhJevUhypXss3a4F7HrhOuZDlB20JH4eYNz9cvpcrJp6TFZ8tAvLfuWm4ErXuSQSvC aWo0yqjl5BNqZtf042w7IiJtO7I0PmdsA5oOeXB4LNW3jXoc7JZUOJY/EelwzrapmENo wwHT3pDc5eUi3noZa0F/DUqwHFOYI00boZt/dYjqKZUu8hg7/4dmpMeFbGABnp/UvpVI sTTA== X-Gm-Message-State: ANhLgQ2o7blLCt8D/5Isf2Eu2vsAoPMCo3peu4KDeq4JlbjuEdLa+GHe x/+QOiD1hhVeAmMJc9DFkx+yNU4I8j8= X-Google-Smtp-Source: ADFU+vsZSShlTCWaOtJb+1ECsrRwCD5re4N9C8Noh+hX2FuExN+cXWyuSRNrNR8kYDs6fiuRiNJLRQ== X-Received: by 2002:a05:6a00:2a5:: with SMTP id q5mr7621431pfs.183.1584681547113; Thu, 19 Mar 2020 22:19:07 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:06 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 05/16] powerpc: Use a function for masking instructions Date: Fri, 20 Mar 2020 16:17:58 +1100 Message-Id: <20200320051809.24332-6-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" In preparation for using an instruction data type that can not be used directly with the '&' operator, use a function to mask instructions. Signed-off-by: Jordan Niethe --- v4: New to series --- arch/powerpc/include/asm/sstep.h | 6 +++--- arch/powerpc/kernel/align.c | 2 +- arch/powerpc/kernel/trace/ftrace.c | 8 ++++---- arch/powerpc/lib/code-patching.c | 12 ++++++------ 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h index 9353916fcba7..ef5483288920 100644 --- a/arch/powerpc/include/asm/sstep.h +++ b/arch/powerpc/include/asm/sstep.h @@ -16,9 +16,9 @@ struct pt_regs; * Note that IS_MTMSRD returns true for both an mtmsr (32-bit) * and an mtmsrd (64-bit). */ -#define IS_MTMSRD(instr) (((instr) & 0xfc0007be) == 0x7c000124) -#define IS_RFID(instr) (((instr) & 0xfc0007fe) == 0x4c000024) -#define IS_RFI(instr) (((instr) & 0xfc0007fe) == 0x4c000064) +#define IS_MTMSRD(instr) ((ppc_inst_mask((instr), 0xfc0007be) == 0x7c000124)) +#define IS_RFID(instr) ((ppc_inst_mask((instr), 0xfc0007fe) == 0x4c000024)) +#define IS_RFI(instr) ((ppc_inst_mask((instr), 0xfc0007fe) == 0x4c000064)) enum instruction_type { COMPUTE, /* arith/logical/CR op, etc. */ diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 6008f14a145b..38542fffa179 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -331,7 +331,7 @@ int fix_alignment(struct pt_regs *regs) * when pasting to a co-processor. Furthermore, paste_last is the * synchronisation point for preceding copy/paste sequences. */ - if ((instr & 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe)) + if (ppc_inst_mask(instr, 0xfc0006fe) == (PPC_INST_COPY & 0xfc0006fe)) return -EIO; r = analyse_instr(&op, regs, instr); diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index 380f1ce77715..b189a34baaa2 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -98,19 +98,19 @@ static ppc_inst test_24bit_addr(unsigned long ip, unsigned long addr) static int is_bl_op(ppc_inst op) { - return (op & 0xfc000003) == 0x48000001; + return ppc_inst_mask(op, 0xfc000003) == 0x48000001; } static int is_b_op(ppc_inst op) { - return (op & 0xfc000003) == 0x48000000; + return ppc_inst_mask(op, 0xfc000003) == 0x48000000; } static unsigned long find_bl_target(unsigned long ip, ppc_inst op) { int offset; - offset = (op & 0x03fffffc); + offset = ppc_inst_mask(op, 0x03fffffc); /* make it signed */ if (offset & 0x02000000) offset |= 0xfe000000; @@ -494,7 +494,7 @@ expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1) * The load offset is different depending on the ABI. For simplicity * just mask it out when doing the compare. */ - if ((op0 != 0x48000008) || ((op1 & 0xffff0000) != 0xe8410000)) + if ((op0 != 0x48000008) || (ppc_inst_mask(op1, 0xffff0000) != 0xe8410000)) return 0; return 1; } diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 5d69e836337d..e2ba23fd6f4d 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -301,7 +301,7 @@ static int instr_is_branch_bform(ppc_inst instr) int instr_is_relative_branch(ppc_inst instr) { - if (instr & BRANCH_ABSOLUTE) + if (ppc_inst_mask(instr, BRANCH_ABSOLUTE)) return 0; return instr_is_branch_iform(instr) || instr_is_branch_bform(instr); @@ -309,20 +309,20 @@ int instr_is_relative_branch(ppc_inst instr) int instr_is_relative_link_branch(ppc_inst instr) { - return instr_is_relative_branch(instr) && (instr & BRANCH_SET_LINK); + return instr_is_relative_branch(instr) && ppc_inst_mask(instr, BRANCH_SET_LINK); } static unsigned long branch_iform_target(const ppc_inst *instr) { signed long imm; - imm = *instr & 0x3FFFFFC; + imm = ppc_inst_mask(*instr, 0x3FFFFFC); /* If the top bit of the immediate value is set this is negative */ if (imm & 0x2000000) imm -= 0x4000000; - if ((*instr & BRANCH_ABSOLUTE) == 0) + if ((ppc_inst_mask(*instr, BRANCH_ABSOLUTE)) == 0) imm += (unsigned long)instr; return (unsigned long)imm; @@ -332,13 +332,13 @@ static unsigned long branch_bform_target(const ppc_inst *instr) { signed long imm; - imm = *instr & 0xFFFC; + imm = ppc_inst_mask(*instr, 0xFFFC); /* If the top bit of the immediate value is set this is negative */ if (imm & 0x8000) imm -= 0x10000; - if ((*instr & BRANCH_ABSOLUTE) == 0) + if ((ppc_inst_mask(*instr, BRANCH_ABSOLUTE)) == 0) imm += (unsigned long)instr; return (unsigned long)imm; From patchwork Fri Mar 20 05:17:59 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258638 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kC6p1kXPz9sPF for ; Fri, 20 Mar 2020 16:30:58 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=VwUWpO8a; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kC6n3jb4zDrfK for ; Fri, 20 Mar 2020 16:30:57 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::544; helo=mail-pg1-x544.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=VwUWpO8a; dkim-atps=neutral Received: from mail-pg1-x544.google.com (mail-pg1-x544.google.com [IPv6:2607:f8b0:4864:20::544]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBsG15bdzDrT2 for ; Fri, 20 Mar 2020 16:19:13 +1100 (AEDT) Received: by mail-pg1-x544.google.com with SMTP id d17so1921763pgo.0 for ; Thu, 19 Mar 2020 22:19:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=47ZTgaT4e6mi0NjK6miw5fls+T/eF1jO5otBlIoDje0=; b=VwUWpO8aEBq+6EjcCwobvUSkqWfqLpkOLH52oBdGVKdomWVJvK3ErX/2AfWeHD4Xd2 RI5ARhDMVdGaLtBvS+xUWcRF0g3QEnN5nJ0fF5Gs9dOndojEh7PdhhzmaZtNWdSJcnps 1CTQthafLOtiD8lRS2ZbIit03Mm1bMpsvVlanExssmVHD48qke15Y+DZe6BTLW7ZkQ1f vy3caWoDBkRncEk4ApxZpq0uqj7Cm04Pk7w5h1Q0E3pQRKbzA3Be/dB2cBES91pI0Lxt WDpb2wDmoSpKqemW7pWaXkYwQTShWOe2uEOhrdy30D/I7JUje/jHCodmp866zgx3t9UL iDPg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=47ZTgaT4e6mi0NjK6miw5fls+T/eF1jO5otBlIoDje0=; b=N3ZMpRcW8fypHdWdJ4jdGChRXL7QESMbQB6PquGedsYbAyYriGxjlNtzLamKqLokU5 xakg9Xf6YRG0z8D4po16tb/gToz2xykIUOg2Xi09a0jQOS/v3ordsdE44dzsin5nINvX uIDul0elRaK1Udr/Fd2PVj9LrYEIzwF+KtfuosBCbA/KilecSSfhwvzdYxOZEqwEdu+E e2j0MUUGyXK1/CnUUlUgbU7WcclPDg2WGAHnRGMZHQ5akY4/zF5/h4L59CP0XYjivRhw Aa44PTBq+rkN+WVbcgkijLYAN08yLDKjP5kG9Fm7CqtiGozISbN9xHY54kUWHrq3YdmN 4jKQ== X-Gm-Message-State: ANhLgQ2KhWykwlmKmCQqK7MFShYU1QjqurC4padmhvUg9A2dWQO7eIc7 Duh1tt4HPqJVByofkyMnRas6Y3obReE= X-Google-Smtp-Source: ADFU+vsxM8s0oGo3MWyrwF2hnZK+6g4QWIOwPROrdqv9d74aIAm8LgD3vOEGOHS7PtMEngQZvjffXA== X-Received: by 2002:a62:d144:: with SMTP id t4mr179899pfl.10.1584681551349; Thu, 19 Mar 2020 22:19:11 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:10 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 06/16] powerpc: Use a function for getting the instruction op code Date: Fri, 20 Mar 2020 16:17:59 +1100 Message-Id: <20200320051809.24332-7-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" In preparation for using a data type for instructions that can not be directly used with the '>>' operator use a function for getting the op code of an instruction. Signed-off-by: Jordan Niethe --- v4: New to series --- arch/powerpc/kernel/align.c | 4 ++-- arch/powerpc/lib/code-patching.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 38542fffa179..77c49dfdc1b4 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -313,8 +313,8 @@ int fix_alignment(struct pt_regs *regs) } #ifdef CONFIG_SPE - if ((instr >> 26) == 0x4) { - int reg = (instr >> 21) & 0x1f; + if (ppc_inst_opcode(instr) == 0x4) { + int reg = (ppc_inst_word(instr) >> 21) & 0x1f; PPC_WARN_ALIGNMENT(spe, regs); return emulate_spe(regs, reg, instr); } diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index e2ba23fd6f4d..04a303c059e2 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -228,7 +228,7 @@ bool is_offset_in_branch_range(long offset) */ bool is_conditional_branch(ppc_inst instr) { - unsigned int opcode = instr >> 26; + unsigned int opcode = ppc_inst_opcode(instr); if (opcode == 16) /* bc, bca, bcl, bcla */ return true; @@ -286,7 +286,7 @@ unsigned int create_cond_branch(const unsigned int *addr, static unsigned int branch_opcode(ppc_inst instr) { - return (instr >> 26) & 0x3F; + return ppc_inst_opcode(instr) & 0x3F; } static int instr_is_branch_iform(ppc_inst instr) From patchwork Fri Mar 20 05:18:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258639 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kC8m3Q1Kz9sPF for ; Fri, 20 Mar 2020 16:32:40 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=cGUJZ0HY; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kC8m1Lg2zDrdC for ; Fri, 20 Mar 2020 16:32:40 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::442; helo=mail-pf1-x442.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=cGUJZ0HY; dkim-atps=neutral Received: from mail-pf1-x442.google.com (mail-pf1-x442.google.com [IPv6:2607:f8b0:4864:20::442]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBsK3C49zDrQg for ; Fri, 20 Mar 2020 16:19:17 +1100 (AEDT) Received: by mail-pf1-x442.google.com with SMTP id b72so2620141pfb.11 for ; Thu, 19 Mar 2020 22:19:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=5h6ggFzcy3V91w/AOwjRs0iFE0F6SWUzKuIEtGHr8EQ=; b=cGUJZ0HYpxjhb1OMlM8mRzeyyXD2wwbq+9ZL8IPi0GGMp2JFU80DAZC37ow72xnGqY dJyEQ+ZPUEaFh2nL63/le/jv7T22scoCWShIOJWHM8O5bRylC3tdOUUDFbeNZwQngu98 LDtsbqkdItGdTJ7Nlc7Vcyv05BmhV3SEQ6FrHXKaUaeN0s1ZIyje0MutqGFqaxyS84Al /noa2q1O34+sOHM0icLRrrZvzd2u/PK8rihvJZOP6zIWMalqyKDJKmVoUAmF0z9qh587 NJVdYFmS67BvoxL5Bspzlv2mk6KZDa94xsZIC2hNKiEzq12S6saTIaBbRE2uuOhmQ54n 24Rw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=5h6ggFzcy3V91w/AOwjRs0iFE0F6SWUzKuIEtGHr8EQ=; b=sxCM/KRaffSO1AIwxGMNFldXhIC+8ctZ1sNkRFLgbSnnhpdRNpB4Lf+/8rrIhhQ+7p QGdqZ/P+9NbOSXFmr02trj7G521p2AHxNdCMFAtNuROTlYlxeBX6F4CVNEOvAwjwaU8W 32B46V5L2ReSvpGJhxrtZGT6sBXzIjB2tGzDSDkgMp+Qze520SId3uq73Vfih9sPGalU ABOLn7NARXcdNHZjnoveXYPphmLEckFAMsSd1J4On2nJM4F2Q8m1baZNJIil7DiNCvJ0 2EjL2cqDNV3cgI0ox4GUAmKvGdMiLgo9FyV2pOdL4wFHzWKIN666602C29zU+Yd91wSD bZdQ== X-Gm-Message-State: ANhLgQ1u6QSoCxDtN8MKcOR+RXlCJEWkTrEcH0egG/jfgp43w6OXuH0A BvjC1YM+y1oQO9KKdQmD/HUNyHmiFYw= X-Google-Smtp-Source: ADFU+vusMLYGCMDqx86uFBcy2ld5LkXeOJtS2igV93ekSHI09Wtb3HMGneOq7LUFo8HEKOPFm5mggg== X-Received: by 2002:a62:1513:: with SMTP id 19mr7719887pfv.85.1584681555229; Thu, 19 Mar 2020 22:19:15 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:14 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 07/16] powerpc: Introduce functions for instruction nullity and equality Date: Fri, 20 Mar 2020 16:18:00 +1100 Message-Id: <20200320051809.24332-8-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" In preparation for an instruction data type that can not be directly used with the '==' operator use functions for checking equality and nullity. Signed-off-by: Jordan Niethe --- arch/powerpc/kernel/optprobes.c | 2 +- arch/powerpc/kernel/trace/ftrace.c | 33 +++++++++++++++------------- arch/powerpc/lib/code-patching.c | 16 +++++++------- arch/powerpc/lib/feature-fixups.c | 2 +- arch/powerpc/lib/test_emulate_step.c | 4 ++-- arch/powerpc/xmon/xmon.c | 4 ++-- 6 files changed, 32 insertions(+), 29 deletions(-) diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index 1025a7a3b3a8..6027425a85f2 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -259,7 +259,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) (unsigned long)emulate_step_addr, BRANCH_SET_LINK); - if (!branch_op_callback || !branch_emulate_step) + if (ppc_inst_null(branch_op_callback) || ppc_inst_null(branch_emulate_step)) goto error; patch_instruction(buff + TMPL_CALL_HDLR_IDX, branch_op_callback); diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index b189a34baaa2..b3645b664819 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -72,7 +72,7 @@ ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new) return -EFAULT; /* Make sure it is what we expect it to be */ - if (replaced != old) { + if (!ppc_inst_equal(replaced, old)) { pr_err("%p: replaced (%#x) != old (%#x)", (void *)ip, replaced, old); return -EINVAL; @@ -169,7 +169,8 @@ __ftrace_make_nop(struct module *mod, } /* We expect either a mflr r0, or a std r0, LRSAVE(r1) */ - if (op != PPC_INST(PPC_INST_MFLR) && op != PPC_INST(PPC_INST_STD_LR)) { + if (!ppc_inst_equal(op, PPC_INST(PPC_INST_MFLR)) && + !ppc_inst_equal(op, PPC_INST(PPC_INST_STD_LR))) { pr_err("Unexpected instruction %08x around bl _mcount\n", op); return -EINVAL; } @@ -199,7 +200,7 @@ __ftrace_make_nop(struct module *mod, return -EFAULT; } - if (op != PPC_INST(PPC_INST_LD_TOC)) { + if (!ppc_inst_equal(op, PPC_INST(PPC_INST_LD_TOC))) { pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op); return -EINVAL; } @@ -296,7 +297,7 @@ static unsigned long find_ftrace_tramp(unsigned long ip) for (i = NUM_FTRACE_TRAMPS - 1; i >= 0; i--) if (!ftrace_tramps[i]) continue; - else if (create_branch((void *)ip, ftrace_tramps[i], 0)) + else if (!ppc_inst_null(create_branch((void *)ip, ftrace_tramps[i], 0))) return ftrace_tramps[i]; return 0; @@ -368,7 +369,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp) #else ptr = ppc_global_function_entry((void *)ftrace_caller); #endif - if (!create_branch((void *)tramp, ptr, 0)) { + if (ppc_inst_null(create_branch((void *)tramp, ptr, 0))) { pr_debug("%ps is not reachable from existing mcount tramp\n", (void *)ptr); return -1; @@ -437,7 +438,7 @@ int ftrace_make_nop(struct module *mod, * then we had to use a trampoline to make the call. * Otherwise just update the call site. */ - if (test_24bit_addr(ip, addr)) { + if (!ppc_inst_null(test_24bit_addr(ip, addr))) { /* within range */ old = ftrace_call_replace(ip, addr, 1); new = PPC_INST(PPC_INST_NOP); @@ -494,7 +495,8 @@ expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1) * The load offset is different depending on the ABI. For simplicity * just mask it out when doing the compare. */ - if ((op0 != 0x48000008) || (ppc_inst_mask(op1, 0xffff0000) != 0xe8410000)) + if ((!ppc_inst_equal(op0, PPC_INST(0x48000008)) || + ((ppc_inst_mask(op1, 0xffff0000) != 0xe8410000)) return 0; return 1; } @@ -503,7 +505,7 @@ static int expected_nop_sequence(void *ip, ppc_inst op0, ppc_inst op1) { /* look for patched "NOP" on ppc64 with -mprofile-kernel */ - if (op0 != PPC_INST(PPC_INST_NOP)) + if (!ppc_inst_equal(op0, PPC_INST(PPC_INST_NOP))) return 0; return 1; } @@ -559,7 +561,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) } /* Ensure branch is within 24 bits */ - if (!create_branch(ip, tramp, BRANCH_SET_LINK)) { + if (ppc_inst_null(create_branch(ip, tramp, BRANCH_SET_LINK))) { pr_err("Branch out of range\n"); return -EINVAL; } @@ -584,7 +586,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) return -EFAULT; /* It should be pointing to a nop */ - if (op != PPC_INST(PPC_INST_NOP)) { + if (!ppc_inst_equal(op, PPC_INST(PPC_INST_NOP))) { pr_err("Expected NOP but have %x\n", op); return -EINVAL; } @@ -641,7 +643,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr) return -EFAULT; } - if (op != PPC_INST(PPC_INST_NOP)) { + if (!ppc_inst_equal(op, PPC_INST(PPC_INST_NOP))) { pr_err("Unexpected call sequence at %p: %x\n", ip, op); return -EINVAL; } @@ -670,7 +672,7 @@ int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) * then we had to use a trampoline to make the call. * Otherwise just update the call site. */ - if (test_24bit_addr(ip, addr)) { + if (!ppc_inst_null(test_24bit_addr(ip, addr))) { /* within range */ old = PPC_INST(PPC_INST_NOP); new = ftrace_call_replace(ip, addr, 1); @@ -748,7 +750,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, } /* The new target may be within range */ - if (test_24bit_addr(ip, addr)) { + if (!ppc_inst_null(test_24bit_addr(ip, addr))) { /* within range */ if (patch_branch((ppc_inst *)ip, addr, BRANCH_SET_LINK)) { pr_err("REL24 out of range!\n"); @@ -778,7 +780,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, } /* Ensure branch is within 24 bits */ - if (!create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK)) { + if (ppc_inst_null(create_branch((ppc_inst *)ip, tramp, BRANCH_SET_LINK))) { pr_err("Branch out of range\n"); return -EINVAL; } @@ -803,7 +805,8 @@ int ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, * then we had to use a trampoline to make the call. * Otherwise just update the call site. */ - if (test_24bit_addr(ip, addr) && test_24bit_addr(ip, old_addr)) { + if (!ppc_inst_null(test_24bit_addr(ip, addr)) && + !ppc_inst_null(test_24bit_addr(ip, old_addr))) { /* within range */ old = ftrace_call_replace(ip, old_addr, 1); new = ftrace_call_replace(ip, addr, 1); diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 04a303c059e2..ec3abe1a6927 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -461,20 +461,20 @@ static void __init test_branch_iform(void) /* Out of range relative negative offset, - 32 MB + 4*/ instr = create_branch(&instr, addr - 0x2000004, BRANCH_SET_LINK); - check(instr == 0); + check(ppc_inst_null(instr)); /* Out of range relative positive offset, + 32 MB */ instr = create_branch(&instr, addr + 0x2000000, BRANCH_SET_LINK); - check(instr == 0); + check(ppc_inst_null(instr)); /* Unaligned target */ instr = create_branch(&instr, addr + 3, BRANCH_SET_LINK); - check(instr == 0); + check(ppc_inst_null(instr)); /* Check flags are masked correctly */ instr = create_branch(&instr, addr, 0xFFFFFFFC); check(instr_is_branch_to_addr(&instr, addr)); - check(instr == PPC_INST(0x48000000)); + check(ppc_inst_equal(instr, PPC_INST(0x48000000))); } static void __init test_create_function_call(void) @@ -544,20 +544,20 @@ static void __init test_branch_bform(void) /* Out of range relative negative offset, - 32 KB + 4*/ instr = create_cond_branch(iptr, addr - 0x8004, flags); - check(instr == 0); + check(ppc_inst_null(instr)); /* Out of range relative positive offset, + 32 KB */ instr = create_cond_branch(iptr, addr + 0x8000, flags); - check(instr == 0); + check(ppc_inst_null(instr)); /* Unaligned target */ instr = create_cond_branch(iptr, addr + 3, flags); - check(instr == 0); + check(ppc_inst_null(instr)); /* Check flags are masked correctly */ instr = create_cond_branch(iptr, addr, 0xFFFFFFFC); check(instr_is_branch_to_addr(&instr, addr)); - check(instr == 0x43FF0000); + check(ppc_inst_equal(instr, PPC_INST(0x43FF0000))); } static void __init test_translate_branch(void) diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index a5f3d98862e9..552106d1f64a 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -55,7 +55,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest, /* Branch within the section doesn't need translating */ if (target < alt_start || target > alt_end) { instr = translate_branch(dest, src); - if (!instr) + if (ppc_inst_null(instr)) return 1; } } diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c index 227ebae9ba5a..486e057e5be1 100644 --- a/arch/powerpc/lib/test_emulate_step.c +++ b/arch/powerpc/lib/test_emulate_step.c @@ -846,7 +846,7 @@ static int __init emulate_compute_instr(struct pt_regs *regs, { struct instruction_op op; - if (!regs || !instr) + if (!regs || ppc_inst_null(instr)) return -EINVAL; if (analyse_instr(&op, regs, instr) != 1 || @@ -865,7 +865,7 @@ static int __init execute_compute_instr(struct pt_regs *regs, extern int exec_instr(struct pt_regs *regs); extern s32 patch__exec_instr; - if (!regs || !instr) + if (!regs || ppc_inst_null(instr)) return -EINVAL; /* Patch the NOP with the actual instruction */ diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index f8a7a55e6ab2..d045e583f1c9 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -951,7 +951,7 @@ static void remove_bpts(void) if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP) continue; if (mread(bp->address, &instr, 4) == 4 - && instr == PPC_INST(bpinstr) + && ppc_inst_equal(instr, PPC_INST(bpinstr)) && patch_instruction( (ppc_inst *)bp->address, bp->instr[0]) != 0) printf("Couldn't remove breakpoint at %lx\n", @@ -2861,7 +2861,7 @@ generic_inst_dump(unsigned long adr, long count, int praddr, break; } inst = PPC_INST(GETWORD(val)); - if (adr > first_adr && inst == last_inst) { + if (adr > first_adr && ppc_inst_equal(inst, last_inst)) { if (!dotted) { printf(" ...\n"); dotted = 1; From patchwork Fri Mar 20 05:18:01 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258640 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kCBc4B6Yz9sPF for ; Fri, 20 Mar 2020 16:34:16 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=mmYieBoc; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kCBc3XJjzDrh9 for ; Fri, 20 Mar 2020 16:34:16 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::644; helo=mail-pl1-x644.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=mmYieBoc; dkim-atps=neutral Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBsR0SLMzDrSJ for ; Fri, 20 Mar 2020 16:19:22 +1100 (AEDT) Received: by mail-pl1-x644.google.com with SMTP id r3so2005814pls.13 for ; Thu, 19 Mar 2020 22:19:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Gki9s0Z1fz3RJJfYb55WIAVyWc1UytjmukUl2i/97Ww=; b=mmYieBocsIFFuqeyb1Jo8JJfbop2LZHldHt7ploXyU3ttgLM7Ps3XRMGpHbvx1DDqJ 9EW7SgdRjIgk1BfstdjWpHLNfHCAXPXZGvZHfDKsmVTcz3BYVSoKbuqB3sddXFvqTWC5 t3YumFdJCCV5h0TTt8fdq7bFRjTBooMKLd52Q8TnDf8uL22dCOznfZRMCrcAoEY29h8c 3Sg00jsKCCQ8LB1WocKSuQJYbD080F/khjhqveXmyqv9SONXCUXHps28KJxxL4Zh7vey 8SxPqOuEN9fP7p34qsSFuhk+lovQ1V+PJoZbEcw1ffIUHe1LCmd6+hzuWANEh4RC3x0X YR4A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Gki9s0Z1fz3RJJfYb55WIAVyWc1UytjmukUl2i/97Ww=; b=Pw66mJoDI0hUvKTPzWRB0zGjfUX4kyRxr+EuiIiQi9701rBW0ZO6nYyp+0s5B/pAJ/ vaU7cpf0LjQNmcVFfzhOdU3jzUsPV7zwcBvFpDCRy5nsMw42JXVw+qMv2kRDM2QC4UQU jsrYxjUtZFibu4bfVh6eLsgE1DfWNKpA++AJQJoGqOToRK1J09dknEQ9fNodF3kA75Og h0cAEbRJyutMbP55JaEuk1gbWdrkrGQqd4ow3YH1Yli9H9one8pE07uAM7dAdF1HDH4b TeZwgx2VzxGo7JOjorRH2uAfajG+GCxkJ0Fx7oPQYJvV0nVtBNhiHLc55zYtnk+i83Le tm7Q== X-Gm-Message-State: ANhLgQ2F+byJumNJmwC3l/iOOXmpadmd/zaycPU97pq24e8asurBYCXE GcQXoKMMO67DQJrzqO7CvzMAO2b1G6o= X-Google-Smtp-Source: ADFU+vuei8tmibgTm5STa4nIYCWPn8R4aK7/DXuAvU03/igGf2mSKA7S1DBTEjFuSGK8yVBERYk3TA== X-Received: by 2002:a17:90a:7105:: with SMTP id h5mr7575999pjk.54.1584681559130; Thu, 19 Mar 2020 22:19:19 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:18 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 08/16] powerpc: Use an accessor for word instructions Date: Fri, 20 Mar 2020 16:18:01 +1100 Message-Id: <20200320051809.24332-9-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" In preparation for prefixed instructions where all instructions are no longer words, use an accessor for getting a word instruction as a u32 from the instruction data type. Signed-off-by: Jordan Niethe --- v4: New to series --- arch/powerpc/kernel/align.c | 2 +- arch/powerpc/kernel/kprobes.c | 2 +- arch/powerpc/kernel/trace/ftrace.c | 16 +- arch/powerpc/lib/code-patching.c | 2 +- arch/powerpc/lib/feature-fixups.c | 4 +- arch/powerpc/lib/sstep.c | 270 ++++++++++++++------------- arch/powerpc/lib/test_emulate_step.c | 4 +- arch/powerpc/xmon/xmon.c | 4 +- 8 files changed, 153 insertions(+), 151 deletions(-) diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index 77c49dfdc1b4..b246ca124931 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -309,7 +309,7 @@ int fix_alignment(struct pt_regs *regs) /* We don't handle PPC little-endian any more... */ if (cpu_has_feature(CPU_FTR_PPC_LE)) return -EIO; - instr = PPC_INST(swab32(instr)); + instr = PPC_INST(swab32(ppc_inst_word(instr))); } #ifdef CONFIG_SPE diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 4c2b656615a6..0c600b6e4ead 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -242,7 +242,7 @@ static int try_to_emulate(struct kprobe *p, struct pt_regs *regs) * So, we should never get here... but, its still * good to catch them, just in case... */ - printk("Can't step on instruction %x\n", insn); + printk("Can't step on instruction %x\n", ppc_inst_word(insn)); BUG(); } else { /* diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index b3645b664819..7614a9f537fd 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -74,7 +74,7 @@ ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new) /* Make sure it is what we expect it to be */ if (!ppc_inst_equal(replaced, old)) { pr_err("%p: replaced (%#x) != old (%#x)", - (void *)ip, replaced, old); + (void *)ip, ppc_inst_word(replaced), ppc_inst_word(old)); return -EINVAL; } @@ -136,7 +136,7 @@ __ftrace_make_nop(struct module *mod, /* Make sure that that this is still a 24bit jump */ if (!is_bl_op(op)) { - pr_err("Not expected bl: opcode is %x\n", op); + pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op)); return -EINVAL; } @@ -171,7 +171,7 @@ __ftrace_make_nop(struct module *mod, /* We expect either a mflr r0, or a std r0, LRSAVE(r1) */ if (!ppc_inst_equal(op, PPC_INST(PPC_INST_MFLR)) && !ppc_inst_equal(op, PPC_INST(PPC_INST_STD_LR))) { - pr_err("Unexpected instruction %08x around bl _mcount\n", op); + pr_err("Unexpected instruction %08x around bl _mcount\n", ppc_inst_word(op)); return -EINVAL; } #else @@ -201,7 +201,7 @@ __ftrace_make_nop(struct module *mod, } if (!ppc_inst_equal(op, PPC_INST(PPC_INST_LD_TOC))) { - pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, op); + pr_err("Expected %08x found %08x\n", PPC_INST_LD_TOC, ppc_inst_word(op)); return -EINVAL; } #endif /* CONFIG_MPROFILE_KERNEL */ @@ -401,7 +401,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr) /* Make sure that that this is still a 24bit jump */ if (!is_bl_op(op)) { - pr_err("Not expected bl: opcode is %x\n", op); + pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op)); return -EINVAL; } @@ -525,7 +525,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) if (!expected_nop_sequence(ip, op[0], op[1])) { pr_err("Unexpected call sequence at %p: %x %x\n", - ip, op[0], op[1]); + ip, ppc_inst_word(op[0]), ppc_inst_word(op[1])); return -EINVAL; } @@ -644,7 +644,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr) } if (!ppc_inst_equal(op, PPC_INST(PPC_INST_NOP))) { - pr_err("Unexpected call sequence at %p: %x\n", ip, op); + pr_err("Unexpected call sequence at %p: %x\n", ip, ppc_inst_word(op)); return -EINVAL; } @@ -723,7 +723,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, /* Make sure that that this is still a 24bit jump */ if (!is_bl_op(op)) { - pr_err("Not expected bl: opcode is %x\n", op); + pr_err("Not expected bl: opcode is %x\n", ppc_inst_word(op)); return -EINVAL; } diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index ec3abe1a6927..849eee63df3d 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -233,7 +233,7 @@ bool is_conditional_branch(ppc_inst instr) if (opcode == 16) /* bc, bca, bcl, bcla */ return true; if (opcode == 19) { - switch ((instr >> 1) & 0x3ff) { + switch ((ppc_inst_word(instr) >> 1) & 0x3ff) { case 16: /* bclr, bclrl */ case 528: /* bcctr, bcctrl */ case 560: /* bctar, bctarl */ diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index 552106d1f64a..fe8ec099aa96 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -54,8 +54,8 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest, /* Branch within the section doesn't need translating */ if (target < alt_start || target > alt_end) { - instr = translate_branch(dest, src); - if (ppc_inst_null(instr)) + instr = ppc_inst_word(translate_branch((ppc_inst *)dest, (ppc_inst *)src)); + if (!instr) return 1; } } diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index 1d9c766a89fe..bae878a83fa5 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -1169,26 +1169,28 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, unsigned long int imm; unsigned long int val, val2; unsigned int mb, me, sh; + unsigned int word; long ival; + word = ppc_inst_word(instr); op->type = COMPUTE; - opcode = instr >> 26; + opcode = word >> 26; switch (opcode) { case 16: /* bc */ op->type = BRANCH; - imm = (signed short)(instr & 0xfffc); - if ((instr & 2) == 0) + imm = (signed short)(word & 0xfffc); + if ((word & 2) == 0) imm += regs->nip; op->val = truncate_if_32bit(regs->msr, imm); - if (instr & 1) + if (word & 1) op->type |= SETLK; - if (branch_taken(instr, regs, op)) + if (branch_taken(word, regs, op)) op->type |= BRTAKEN; return 1; #ifdef CONFIG_PPC64 case 17: /* sc */ - if ((instr & 0xfe2) == 2) + if ((word & 0xfe2) == 2) op->type = SYSCALL; else op->type = UNKNOWN; @@ -1196,21 +1198,21 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #endif case 18: /* b */ op->type = BRANCH | BRTAKEN; - imm = instr & 0x03fffffc; + imm = word & 0x03fffffc; if (imm & 0x02000000) imm -= 0x04000000; - if ((instr & 2) == 0) + if ((word & 2) == 0) imm += regs->nip; op->val = truncate_if_32bit(regs->msr, imm); - if (instr & 1) + if (word & 1) op->type |= SETLK; return 1; case 19: - switch ((instr >> 1) & 0x3ff) { + switch ((word >> 1) & 0x3ff) { case 0: /* mcrf */ op->type = COMPUTE + SETCC; - rd = 7 - ((instr >> 23) & 0x7); - ra = 7 - ((instr >> 18) & 0x7); + rd = 7 - ((word >> 23) & 0x7); + ra = 7 - ((word >> 18) & 0x7); rd *= 4; ra *= 4; val = (regs->ccr >> ra) & 0xf; @@ -1220,11 +1222,11 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 16: /* bclr */ case 528: /* bcctr */ op->type = BRANCH; - imm = (instr & 0x400)? regs->ctr: regs->link; + imm = (word & 0x400)? regs->ctr: regs->link; op->val = truncate_if_32bit(regs->msr, imm); - if (instr & 1) + if (word & 1) op->type |= SETLK; - if (branch_taken(instr, regs, op)) + if (branch_taken(word, regs, op)) op->type |= BRTAKEN; return 1; @@ -1247,23 +1249,23 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 417: /* crorc */ case 449: /* cror */ op->type = COMPUTE + SETCC; - ra = (instr >> 16) & 0x1f; - rb = (instr >> 11) & 0x1f; - rd = (instr >> 21) & 0x1f; + ra = (word >> 16) & 0x1f; + rb = (word >> 11) & 0x1f; + rd = (word >> 21) & 0x1f; ra = (regs->ccr >> (31 - ra)) & 1; rb = (regs->ccr >> (31 - rb)) & 1; - val = (instr >> (6 + ra * 2 + rb)) & 1; + val = (word >> (6 + ra * 2 + rb)) & 1; op->ccval = (regs->ccr & ~(1UL << (31 - rd))) | (val << (31 - rd)); return 1; } break; case 31: - switch ((instr >> 1) & 0x3ff) { + switch ((word >> 1) & 0x3ff) { case 598: /* sync */ op->type = BARRIER + BARRIER_SYNC; #ifdef __powerpc64__ - switch ((instr >> 21) & 3) { + switch ((word >> 21) & 3) { case 1: /* lwsync */ op->type = BARRIER + BARRIER_LWSYNC; break; @@ -1285,20 +1287,20 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, if (!FULL_REGS(regs)) return -1; - rd = (instr >> 21) & 0x1f; - ra = (instr >> 16) & 0x1f; - rb = (instr >> 11) & 0x1f; - rc = (instr >> 6) & 0x1f; + rd = (word >> 21) & 0x1f; + ra = (word >> 16) & 0x1f; + rb = (word >> 11) & 0x1f; + rc = (word >> 6) & 0x1f; switch (opcode) { #ifdef __powerpc64__ case 2: /* tdi */ - if (rd & trap_compare(regs->gpr[ra], (short) instr)) + if (rd & trap_compare(regs->gpr[ra], (short) word)) goto trap; return 1; #endif case 3: /* twi */ - if (rd & trap_compare((int)regs->gpr[ra], (short) instr)) + if (rd & trap_compare((int)regs->gpr[ra], (short) word)) goto trap; return 1; @@ -1307,7 +1309,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, if (!cpu_has_feature(CPU_FTR_ARCH_300)) return -1; - switch (instr & 0x3f) { + switch (word & 0x3f) { case 48: /* maddhd */ asm volatile(PPC_MADDHD(%0, %1, %2, %3) : "=r" (op->val) : "r" (regs->gpr[ra]), @@ -1335,16 +1337,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #endif case 7: /* mulli */ - op->val = regs->gpr[ra] * (short) instr; + op->val = regs->gpr[ra] * (short) word; goto compute_done; case 8: /* subfic */ - imm = (short) instr; + imm = (short) word; add_with_carry(regs, op, rd, ~regs->gpr[ra], imm, 1); return 1; case 10: /* cmpli */ - imm = (unsigned short) instr; + imm = (unsigned short) word; val = regs->gpr[ra]; #ifdef __powerpc64__ if ((rd & 1) == 0) @@ -1354,7 +1356,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, return 1; case 11: /* cmpi */ - imm = (short) instr; + imm = (short) word; val = regs->gpr[ra]; #ifdef __powerpc64__ if ((rd & 1) == 0) @@ -1364,35 +1366,35 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, return 1; case 12: /* addic */ - imm = (short) instr; + imm = (short) word; add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0); return 1; case 13: /* addic. */ - imm = (short) instr; + imm = (short) word; add_with_carry(regs, op, rd, regs->gpr[ra], imm, 0); set_cr0(regs, op); return 1; case 14: /* addi */ - imm = (short) instr; + imm = (short) word; if (ra) imm += regs->gpr[ra]; op->val = imm; goto compute_done; case 15: /* addis */ - imm = ((short) instr) << 16; + imm = ((short) word) << 16; if (ra) imm += regs->gpr[ra]; op->val = imm; goto compute_done; case 19: - if (((instr >> 1) & 0x1f) == 2) { + if (((word >> 1) & 0x1f) == 2) { /* addpcis */ - imm = (short) (instr & 0xffc1); /* d0 + d2 fields */ - imm |= (instr >> 15) & 0x3e; /* d1 field */ + imm = (short) (word & 0xffc1); /* d0 + d2 fields */ + imm |= (word >> 15) & 0x3e; /* d1 field */ op->val = regs->nip + (imm << 16) + 4; goto compute_done; } @@ -1400,65 +1402,65 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, return 0; case 20: /* rlwimi */ - mb = (instr >> 6) & 0x1f; - me = (instr >> 1) & 0x1f; + mb = (word >> 6) & 0x1f; + me = (word >> 1) & 0x1f; val = DATA32(regs->gpr[rd]); imm = MASK32(mb, me); op->val = (regs->gpr[ra] & ~imm) | (ROTATE(val, rb) & imm); goto logical_done; case 21: /* rlwinm */ - mb = (instr >> 6) & 0x1f; - me = (instr >> 1) & 0x1f; + mb = (word >> 6) & 0x1f; + me = (word >> 1) & 0x1f; val = DATA32(regs->gpr[rd]); op->val = ROTATE(val, rb) & MASK32(mb, me); goto logical_done; case 23: /* rlwnm */ - mb = (instr >> 6) & 0x1f; - me = (instr >> 1) & 0x1f; + mb = (word >> 6) & 0x1f; + me = (word >> 1) & 0x1f; rb = regs->gpr[rb] & 0x1f; val = DATA32(regs->gpr[rd]); op->val = ROTATE(val, rb) & MASK32(mb, me); goto logical_done; case 24: /* ori */ - op->val = regs->gpr[rd] | (unsigned short) instr; + op->val = regs->gpr[rd] | (unsigned short) word; goto logical_done_nocc; case 25: /* oris */ - imm = (unsigned short) instr; + imm = (unsigned short) word; op->val = regs->gpr[rd] | (imm << 16); goto logical_done_nocc; case 26: /* xori */ - op->val = regs->gpr[rd] ^ (unsigned short) instr; + op->val = regs->gpr[rd] ^ (unsigned short) word; goto logical_done_nocc; case 27: /* xoris */ - imm = (unsigned short) instr; + imm = (unsigned short) word; op->val = regs->gpr[rd] ^ (imm << 16); goto logical_done_nocc; case 28: /* andi. */ - op->val = regs->gpr[rd] & (unsigned short) instr; + op->val = regs->gpr[rd] & (unsigned short) word; set_cr0(regs, op); goto logical_done_nocc; case 29: /* andis. */ - imm = (unsigned short) instr; + imm = (unsigned short) word; op->val = regs->gpr[rd] & (imm << 16); set_cr0(regs, op); goto logical_done_nocc; #ifdef __powerpc64__ case 30: /* rld* */ - mb = ((instr >> 6) & 0x1f) | (instr & 0x20); + mb = ((word >> 6) & 0x1f) | (word & 0x20); val = regs->gpr[rd]; - if ((instr & 0x10) == 0) { - sh = rb | ((instr & 2) << 4); + if ((word & 0x10) == 0) { + sh = rb | ((word & 2) << 4); val = ROTATE(val, sh); - switch ((instr >> 2) & 3) { + switch ((word >> 2) & 3) { case 0: /* rldicl */ val &= MASK64_L(mb); break; @@ -1478,7 +1480,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, } else { sh = regs->gpr[rb] & 0x3f; val = ROTATE(val, sh); - switch ((instr >> 1) & 7) { + switch ((word >> 1) & 7) { case 0: /* rldcl */ op->val = val & MASK64_L(mb); goto logical_done; @@ -1493,8 +1495,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 31: /* isel occupies 32 minor opcodes */ - if (((instr >> 1) & 0x1f) == 15) { - mb = (instr >> 6) & 0x1f; /* bc field */ + if (((word >> 1) & 0x1f) == 15) { + mb = (word >> 6) & 0x1f; /* bc field */ val = (regs->ccr >> (31 - mb)) & 1; val2 = (ra) ? regs->gpr[ra] : 0; @@ -1502,7 +1504,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, goto compute_done; } - switch ((instr >> 1) & 0x3ff) { + switch ((word >> 1) & 0x3ff) { case 4: /* tw */ if (rd == 0x1f || (rd & trap_compare((int)regs->gpr[ra], @@ -1536,17 +1538,17 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->reg = rd; /* only MSR_EE and MSR_RI get changed if bit 15 set */ /* mtmsrd doesn't change MSR_HV, MSR_ME or MSR_LE */ - imm = (instr & 0x10000)? 0x8002: 0xefffffffffffeffeUL; + imm = (word & 0x10000)? 0x8002: 0xefffffffffffeffeUL; op->val = imm; return 0; #endif case 19: /* mfcr */ imm = 0xffffffffUL; - if ((instr >> 20) & 1) { + if ((word >> 20) & 1) { imm = 0xf0000000UL; for (sh = 0; sh < 8; ++sh) { - if (instr & (0x80000 >> sh)) + if (word & (0x80000 >> sh)) break; imm >>= 4; } @@ -1560,7 +1562,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, val = regs->gpr[rd]; op->ccval = regs->ccr; for (sh = 0; sh < 8; ++sh) { - if (instr & (0x80000 >> sh)) + if (word & (0x80000 >> sh)) op->ccval = (op->ccval & ~imm) | (val & imm); imm >>= 4; @@ -1568,7 +1570,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, return 1; case 339: /* mfspr */ - spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); + spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0); op->type = MFSPR; op->reg = rd; op->spr = spr; @@ -1578,7 +1580,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, return 0; case 467: /* mtspr */ - spr = ((instr >> 16) & 0x1f) | ((instr >> 6) & 0x3e0); + spr = ((word >> 16) & 0x1f) | ((word >> 6) & 0x3e0); op->type = MTSPR; op->val = regs->gpr[rd]; op->spr = spr; @@ -1948,7 +1950,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 826: /* sradi with sh_5 = 0 */ case 827: /* sradi with sh_5 = 1 */ op->type = COMPUTE + SETREG + SETXER; - sh = rb | ((instr & 2) << 4); + sh = rb | ((word & 2) << 4); ival = (signed long int) regs->gpr[rd]; op->val = ival >> sh; op->xerval = regs->xer; @@ -1964,7 +1966,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, if (!cpu_has_feature(CPU_FTR_ARCH_300)) return -1; op->type = COMPUTE + SETREG; - sh = rb | ((instr & 2) << 4); + sh = rb | ((word & 2) << 4); val = (signed int) regs->gpr[rd]; if (sh) op->val = ROTATE(val, sh) & MASK64(0, 63 - sh); @@ -1979,34 +1981,34 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, */ case 54: /* dcbst */ op->type = MKOP(CACHEOP, DCBST, 0); - op->ea = xform_ea(instr, regs); + op->ea = xform_ea(word, regs); return 0; case 86: /* dcbf */ op->type = MKOP(CACHEOP, DCBF, 0); - op->ea = xform_ea(instr, regs); + op->ea = xform_ea(word, regs); return 0; case 246: /* dcbtst */ op->type = MKOP(CACHEOP, DCBTST, 0); - op->ea = xform_ea(instr, regs); + op->ea = xform_ea(word, regs); op->reg = rd; return 0; case 278: /* dcbt */ op->type = MKOP(CACHEOP, DCBTST, 0); - op->ea = xform_ea(instr, regs); + op->ea = xform_ea(word, regs); op->reg = rd; return 0; case 982: /* icbi */ op->type = MKOP(CACHEOP, ICBI, 0); - op->ea = xform_ea(instr, regs); + op->ea = xform_ea(word, regs); return 0; case 1014: /* dcbz */ op->type = MKOP(CACHEOP, DCBZ, 0); - op->ea = xform_ea(instr, regs); + op->ea = xform_ea(word, regs); return 0; } break; @@ -2019,14 +2021,14 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, op->update_reg = ra; op->reg = rd; op->val = regs->gpr[rd]; - u = (instr >> 20) & UPDATE; + u = (word >> 20) & UPDATE; op->vsx_flags = 0; switch (opcode) { case 31: - u = instr & UPDATE; - op->ea = xform_ea(instr, regs); - switch ((instr >> 1) & 0x3ff) { + u = word & UPDATE; + op->ea = xform_ea(word, regs); + switch ((word >> 1) & 0x3ff) { case 20: /* lwarx */ op->type = MKOP(LARX, 0, 4); break; @@ -2271,25 +2273,25 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #ifdef CONFIG_VSX case 12: /* lxsiwzx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 4); op->element_size = 8; break; case 76: /* lxsiwax */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, SIGNEXT, 4); op->element_size = 8; break; case 140: /* stxsiwx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 4); op->element_size = 8; break; case 268: /* lxvx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 16); op->element_size = 16; op->vsx_flags = VSX_CHECK_VEC; @@ -2298,33 +2300,33 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 269: /* lxvl */ case 301: { /* lxvll */ int nb; - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->ea = ra ? regs->gpr[ra] : 0; nb = regs->gpr[rb] & 0xff; if (nb > 16) nb = 16; op->type = MKOP(LOAD_VSX, 0, nb); op->element_size = 16; - op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) | + op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) | VSX_CHECK_VEC; break; } case 332: /* lxvdsx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 8); op->element_size = 8; op->vsx_flags = VSX_SPLAT; break; case 364: /* lxvwsx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 4); op->element_size = 4; op->vsx_flags = VSX_SPLAT | VSX_CHECK_VEC; break; case 396: /* stxvx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 16); op->element_size = 16; op->vsx_flags = VSX_CHECK_VEC; @@ -2333,118 +2335,118 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 397: /* stxvl */ case 429: { /* stxvll */ int nb; - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->ea = ra ? regs->gpr[ra] : 0; nb = regs->gpr[rb] & 0xff; if (nb > 16) nb = 16; op->type = MKOP(STORE_VSX, 0, nb); op->element_size = 16; - op->vsx_flags = ((instr & 0x20) ? VSX_LDLEFT : 0) | + op->vsx_flags = ((word & 0x20) ? VSX_LDLEFT : 0) | VSX_CHECK_VEC; break; } case 524: /* lxsspx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 4); op->element_size = 8; op->vsx_flags = VSX_FPCONV; break; case 588: /* lxsdx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 8); op->element_size = 8; break; case 652: /* stxsspx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 4); op->element_size = 8; op->vsx_flags = VSX_FPCONV; break; case 716: /* stxsdx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 8); op->element_size = 8; break; case 780: /* lxvw4x */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 16); op->element_size = 4; break; case 781: /* lxsibzx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 1); op->element_size = 8; op->vsx_flags = VSX_CHECK_VEC; break; case 812: /* lxvh8x */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 16); op->element_size = 2; op->vsx_flags = VSX_CHECK_VEC; break; case 813: /* lxsihzx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 2); op->element_size = 8; op->vsx_flags = VSX_CHECK_VEC; break; case 844: /* lxvd2x */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 16); op->element_size = 8; break; case 876: /* lxvb16x */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(LOAD_VSX, 0, 16); op->element_size = 1; op->vsx_flags = VSX_CHECK_VEC; break; case 908: /* stxvw4x */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 16); op->element_size = 4; break; case 909: /* stxsibx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 1); op->element_size = 8; op->vsx_flags = VSX_CHECK_VEC; break; case 940: /* stxvh8x */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 16); op->element_size = 2; op->vsx_flags = VSX_CHECK_VEC; break; case 941: /* stxsihx */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 2); op->element_size = 8; op->vsx_flags = VSX_CHECK_VEC; break; case 972: /* stxvd2x */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 16); op->element_size = 8; break; case 1004: /* stxvb16x */ - op->reg = rd | ((instr & 1) << 5); + op->reg = rd | ((word & 1) << 5); op->type = MKOP(STORE_VSX, 0, 16); op->element_size = 1; op->vsx_flags = VSX_CHECK_VEC; @@ -2457,80 +2459,80 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 32: /* lwz */ case 33: /* lwzu */ op->type = MKOP(LOAD, u, 4); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 34: /* lbz */ case 35: /* lbzu */ op->type = MKOP(LOAD, u, 1); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 36: /* stw */ case 37: /* stwu */ op->type = MKOP(STORE, u, 4); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 38: /* stb */ case 39: /* stbu */ op->type = MKOP(STORE, u, 1); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 40: /* lhz */ case 41: /* lhzu */ op->type = MKOP(LOAD, u, 2); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 42: /* lha */ case 43: /* lhau */ op->type = MKOP(LOAD, SIGNEXT | u, 2); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 44: /* sth */ case 45: /* sthu */ op->type = MKOP(STORE, u, 2); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 46: /* lmw */ if (ra >= rd) break; /* invalid form, ra in range to load */ op->type = MKOP(LOAD_MULTI, 0, 4 * (32 - rd)); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 47: /* stmw */ op->type = MKOP(STORE_MULTI, 0, 4 * (32 - rd)); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; #ifdef CONFIG_PPC_FPU case 48: /* lfs */ case 49: /* lfsu */ op->type = MKOP(LOAD_FP, u | FPCONV, 4); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 50: /* lfd */ case 51: /* lfdu */ op->type = MKOP(LOAD_FP, u, 8); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 52: /* stfs */ case 53: /* stfsu */ op->type = MKOP(STORE_FP, u | FPCONV, 4); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; case 54: /* stfd */ case 55: /* stfdu */ op->type = MKOP(STORE_FP, u, 8); - op->ea = dform_ea(instr, regs); + op->ea = dform_ea(word, regs); break; #endif @@ -2538,14 +2540,14 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 56: /* lq */ if (!((rd & 1) || (rd == ra))) op->type = MKOP(LOAD, 0, 16); - op->ea = dqform_ea(instr, regs); + op->ea = dqform_ea(word, regs); break; #endif #ifdef CONFIG_VSX case 57: /* lfdp, lxsd, lxssp */ - op->ea = dsform_ea(instr, regs); - switch (instr & 3) { + op->ea = dsform_ea(word, regs); + switch (word & 3) { case 0: /* lfdp */ if (rd & 1) break; /* reg must be even */ @@ -2569,8 +2571,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #ifdef __powerpc64__ case 58: /* ld[u], lwa */ - op->ea = dsform_ea(instr, regs); - switch (instr & 3) { + op->ea = dsform_ea(word, regs); + switch (word & 3) { case 0: /* ld */ op->type = MKOP(LOAD, 0, 8); break; @@ -2586,16 +2588,16 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #ifdef CONFIG_VSX case 61: /* stfdp, lxv, stxsd, stxssp, stxv */ - switch (instr & 7) { + switch (word & 7) { case 0: /* stfdp with LSB of DS field = 0 */ case 4: /* stfdp with LSB of DS field = 1 */ - op->ea = dsform_ea(instr, regs); + op->ea = dsform_ea(word, regs); op->type = MKOP(STORE_FP, 0, 16); break; case 1: /* lxv */ - op->ea = dqform_ea(instr, regs); - if (instr & 8) + op->ea = dqform_ea(word, regs); + if (word & 8) op->reg = rd + 32; op->type = MKOP(LOAD_VSX, 0, 16); op->element_size = 16; @@ -2604,7 +2606,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 2: /* stxsd with LSB of DS field = 0 */ case 6: /* stxsd with LSB of DS field = 1 */ - op->ea = dsform_ea(instr, regs); + op->ea = dsform_ea(word, regs); op->reg = rd + 32; op->type = MKOP(STORE_VSX, 0, 8); op->element_size = 8; @@ -2613,7 +2615,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, case 3: /* stxssp with LSB of DS field = 0 */ case 7: /* stxssp with LSB of DS field = 1 */ - op->ea = dsform_ea(instr, regs); + op->ea = dsform_ea(word, regs); op->reg = rd + 32; op->type = MKOP(STORE_VSX, 0, 4); op->element_size = 8; @@ -2621,8 +2623,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; case 5: /* stxv */ - op->ea = dqform_ea(instr, regs); - if (instr & 8) + op->ea = dqform_ea(word, regs); + if (word & 8) op->reg = rd + 32; op->type = MKOP(STORE_VSX, 0, 16); op->element_size = 16; @@ -2634,8 +2636,8 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, #ifdef __powerpc64__ case 62: /* std[u] */ - op->ea = dsform_ea(instr, regs); - switch (instr & 3) { + op->ea = dsform_ea(word, regs); + switch (word & 3) { case 0: /* std */ op->type = MKOP(STORE, 0, 8); break; @@ -2663,7 +2665,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, return 0; logical_done: - if (instr & 1) + if (word & 1) set_cr0(regs, op); logical_done_nocc: op->reg = ra; @@ -2671,7 +2673,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, return 1; arith_done: - if (instr & 1) + if (word & 1) set_cr0(regs, op); compute_done: op->reg = rd; diff --git a/arch/powerpc/lib/test_emulate_step.c b/arch/powerpc/lib/test_emulate_step.c index 486e057e5be1..d6275a9b8ce6 100644 --- a/arch/powerpc/lib/test_emulate_step.c +++ b/arch/powerpc/lib/test_emulate_step.c @@ -851,7 +851,7 @@ static int __init emulate_compute_instr(struct pt_regs *regs, if (analyse_instr(&op, regs, instr) != 1 || GETTYPE(op.type) != COMPUTE) { - pr_info("emulation failed, instruction = 0x%08x\n", instr); + pr_info("emulation failed, instruction = 0x%08x\n", ppc_inst_word(instr)); return -EFAULT; } @@ -871,7 +871,7 @@ static int __init execute_compute_instr(struct pt_regs *regs, /* Patch the NOP with the actual instruction */ patch_instruction_site(&patch__exec_instr, instr); if (exec_instr(regs)) { - pr_info("execution failed, instruction = 0x%08x\n", instr); + pr_info("execution failed, instruction = 0x%08x\n", ppc_inst_word(instr)); return -EFAULT; } diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index d045e583f1c9..dec522fa8201 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -2871,9 +2871,9 @@ generic_inst_dump(unsigned long adr, long count, int praddr, dotted = 0; last_inst = inst; if (praddr) - printf(REG" %.8x", adr, inst); + printf(REG" %.8x", adr, ppc_inst_word(inst)); printf("\t"); - dump_func(inst, adr); + dump_func(ppc_inst_word(inst), adr); printf("\n"); } return adr - first_adr; From patchwork Fri Mar 20 05:18:02 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258641 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kCDq35nlz9sPF for ; Fri, 20 Mar 2020 16:36:11 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=I12YHPSG; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kCDq24WMzDrdl for ; Fri, 20 Mar 2020 16:36:11 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::442; helo=mail-pf1-x442.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=I12YHPSG; dkim-atps=neutral Received: from mail-pf1-x442.google.com (mail-pf1-x442.google.com [IPv6:2607:f8b0:4864:20::442]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBsV3HGDzDrSF for ; Fri, 20 Mar 2020 16:19:26 +1100 (AEDT) Received: by mail-pf1-x442.google.com with SMTP id c19so2619828pfo.13 for ; Thu, 19 Mar 2020 22:19:26 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=iI/+gXjNcOSCm0Mx95mHELj2Urj3BVXmlvBj/aXPvxg=; b=I12YHPSGh5qxEjZJoc09A5lkuYtlG2IAvC/6DXTVRbORPxxMzMSbh2XOPEJz+6dIm+ QublQ/MGzys1XNKi8pqaLfBNAgL7f+EYFyYnvg08/zclPB0huCyactyRVs5vb/rDRg6a XMJ8OZg48hUxKIvzaRLNpim0/0/0jn708d5jzRUJFOVC6NMbNFz0oeax6fiS8yn4/EY6 N5G7x807eLdjQyg7B0Lo+9BRYqdVyO+znRt+8VSpc5y8cxOrStBtrBZ1SDzJ0/v9YrQQ vKz53kSqdsfU9gcjvyaAb5HYLn0O86dnEzFSQk5mGoaGaBEn+nuAyWEbUF5MaXgOUKXD UpNQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=iI/+gXjNcOSCm0Mx95mHELj2Urj3BVXmlvBj/aXPvxg=; b=LyTgDSJd4f6DFKGBWZyMJSQBnqPwYM7lL61pN28syiTfqYJOo/oHGBsMFh7XS3p6OH Bevll3ovf6MvIHMtl6XXapSvNcC1jK2ZoSyf5uLsy4F76MHSuCVatmD28GgH+XPqFaYO mVF/PMkDpM8tynGKGZPyjP+y59uJwKCfmw6PU2OmK9tEwK1j4I5iP2goPYINWzZwd4Wg GZGvPgcBrCyQCDlBKv6xSO1Bh3fPe1yWxW73Rm9bwKZeu5zEYhjmlwQrdKnUzvcbViiE R8p/oKjlrVlXtanBn3WAVqO/3ytOsOVnsddrfSAeMN9ir8ygn10d1LZZdqxz6G+hSGBK KMaA== X-Gm-Message-State: ANhLgQ0vzMLUaK7gQGRjTMsKLjZQm/ZowTf915nv9X5MZncZavVR8CyQ 6eICzfsshO+9HIp2G24LxEcVryvJTZI= X-Google-Smtp-Source: ADFU+vs+uQBikXq7Q/mHurPkjhEAw9QIUDMOU47uacHt5BmPU4pR4zur0636J5NoRnQaukXwRSo6Qw== X-Received: by 2002:a62:6244:: with SMTP id w65mr7919015pfb.89.1584681562960; Thu, 19 Mar 2020 22:19:22 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:22 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 09/16] powerpc: Use a function for reading instructions Date: Fri, 20 Mar 2020 16:18:02 +1100 Message-Id: <20200320051809.24332-10-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Prefixed instructions will mean there are instructions of different length. As a result dereferencing a pointer to an instruction will not necessarily give the desired result. Introduce a function for reading instructions from memory into the instruction data type. Signed-off-by: Jordan Niethe --- v4: New to series --- arch/powerpc/include/asm/uprobes.h | 4 ++-- arch/powerpc/kernel/kprobes.c | 8 ++++---- arch/powerpc/kernel/mce_power.c | 2 +- arch/powerpc/kernel/optprobes.c | 6 +++--- arch/powerpc/kernel/trace/ftrace.c | 33 +++++++++++++++++++----------- arch/powerpc/kernel/uprobes.c | 2 +- arch/powerpc/lib/code-patching.c | 22 ++++++++++---------- arch/powerpc/lib/feature-fixups.c | 6 +++--- arch/powerpc/xmon/xmon.c | 6 +++--- 9 files changed, 49 insertions(+), 40 deletions(-) diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h index 2bbdf27d09b5..fff3c5fc90b5 100644 --- a/arch/powerpc/include/asm/uprobes.h +++ b/arch/powerpc/include/asm/uprobes.h @@ -23,8 +23,8 @@ typedef ppc_opcode_t uprobe_opcode_t; struct arch_uprobe { union { - u32 insn; - u32 ixol; + u8 insn[MAX_UINSN_BYTES]; + u8 ixol[MAX_UINSN_BYTES]; }; }; diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index 0c600b6e4ead..f142d11d7b48 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -117,7 +117,7 @@ void *alloc_insn_page(void) int arch_prepare_kprobe(struct kprobe *p) { int ret = 0; - kprobe_opcode_t insn = *p->addr; + ppc_inst insn = ppc_inst_read(p->addr); if ((unsigned long)p->addr & 0x03) { printk("Attempt to register kprobe at an unaligned address\n"); @@ -136,8 +136,8 @@ int arch_prepare_kprobe(struct kprobe *p) } if (!ret) { - patch_instruction(p->ainsn.insn, *p->addr); - p->opcode = *p->addr; + patch_instruction(p->ainsn.insn, insn); + p->opcode = ppc_inst_word(insn); } p->ainsn.boostable = 0; @@ -225,7 +225,7 @@ NOKPROBE_SYMBOL(arch_prepare_kretprobe); static int try_to_emulate(struct kprobe *p, struct pt_regs *regs) { int ret; - ppc_inst insn = *p->ainsn.insn; + ppc_inst insn = ppc_inst_read((ppc_inst *)p->ainsn.insn); /* regs->nip is also adjusted if emulate_step returns 1 */ ret = emulate_step(regs, insn); diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index e65616bb3a3e..d1fdb5105d32 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -374,7 +374,7 @@ static int mce_find_instr_ea_and_phys(struct pt_regs *regs, uint64_t *addr, pfn = addr_to_pfn(regs, regs->nip); if (pfn != ULONG_MAX) { instr_addr = (pfn << PAGE_SHIFT) + (regs->nip & ~PAGE_MASK); - instr = *(ppc_inst *)(instr_addr); + instr = ppc_inst_read((ppc_inst *)instr_addr); if (!analyse_instr(&op, &tmp, instr)) { pfn = addr_to_pfn(regs, op.ea); *addr = op.ea; diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index 6027425a85f2..5b53c373373b 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -99,8 +99,8 @@ static unsigned long can_optimize(struct kprobe *p) * Ensure that the instruction is not a conditional branch, * and that can be emulated. */ - if (!is_conditional_branch(*p->ainsn.insn) && - analyse_instr(&op, ®s, *p->ainsn.insn) == 1) { + if (!is_conditional_branch(ppc_inst_read(p->ainsn.insn)) && + analyse_instr(&op, ®s, ppc_inst_read(p->ainsn.insn)) == 1) { emulate_update_regs(®s, &op); nip = regs.nip; } @@ -268,7 +268,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) /* * 3. load instruction to be emulated into relevant register, and */ - patch_imm32_load_insns(*p->ainsn.insn, buff + TMPL_INSN_IDX); + patch_imm32_load_insns(*(unsigned int *)p->ainsn.insn, buff + TMPL_INSN_IDX); /* * 4. branch back from trampoline diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index 7614a9f537fd..ad451205f268 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -41,6 +41,12 @@ #define NUM_FTRACE_TRAMPS 8 static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS]; +static long +read_inst(ppc_inst *inst, const void *src) +{ + return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE); +} + static ppc_inst ftrace_call_replace(unsigned long ip, unsigned long addr, int link) { @@ -68,7 +74,7 @@ ftrace_modify_code(unsigned long ip, ppc_inst old, ppc_inst new) */ /* read the text we want to modify */ - if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE)) + if (read_inst(&replaced, (void *)ip)) return -EFAULT; /* Make sure it is what we expect it to be */ @@ -129,7 +135,7 @@ __ftrace_make_nop(struct module *mod, ppc_inst op, pop; /* read where this goes */ - if (probe_kernel_read(&op, (void *)ip, sizeof(int))) { + if (read_inst(&op, (void *)ip)) { pr_err("Fetching opcode failed.\n"); return -EFAULT; } @@ -163,7 +169,7 @@ __ftrace_make_nop(struct module *mod, /* When using -mkernel_profile there is no load to jump over */ pop = PPC_INST(PPC_INST_NOP); - if (probe_kernel_read(&op, (void *)(ip - 4), 4)) { + if (read_inst(&op, (void *)(ip - 4))) { pr_err("Fetching instruction at %lx failed.\n", ip - 4); return -EFAULT; } @@ -195,7 +201,7 @@ __ftrace_make_nop(struct module *mod, * Check what is in the next instruction. We can see ld r2,40(r1), but * on first pass after boot we will see mflr r0. */ - if (probe_kernel_read(&op, (void *)(ip+4), MCOUNT_INSN_SIZE)) { + if (read_inst(&op, (void *)(ip+4))) { pr_err("Fetching op failed.\n"); return -EFAULT; } @@ -344,7 +350,7 @@ static int setup_mcount_compiler_tramp(unsigned long tramp) return -1; /* New trampoline -- read where this goes */ - if (probe_kernel_read(&op, (void *)tramp, sizeof(int))) { + if (read_inst(&op, (void *)tramp)) { pr_debug("Fetching opcode failed.\n"); return -1; } @@ -394,7 +400,7 @@ static int __ftrace_make_nop_kernel(struct dyn_ftrace *rec, unsigned long addr) ppc_inst op; /* Read where this goes */ - if (probe_kernel_read(&op, (void *)ip, sizeof(int))) { + if (read_inst(&op, (void *)ip)) { pr_err("Fetching opcode failed.\n"); return -EFAULT; } @@ -520,7 +526,10 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) struct module *mod = rec->arch.mod; /* read where this goes */ - if (probe_kernel_read(op, ip, sizeof(op))) + if (read_inst(op, ip)) + return -EFAULT; + + if (read_inst(op + 1, ip + 4)) return -EFAULT; if (!expected_nop_sequence(ip, op[0], op[1])) { @@ -582,7 +591,7 @@ __ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) unsigned long ip = rec->ip; /* read where this goes */ - if (probe_kernel_read(&op, (void *)ip, MCOUNT_INSN_SIZE)) + if (read_inst(&op, (void *)ip)) return -EFAULT; /* It should be pointing to a nop */ @@ -638,7 +647,7 @@ static int __ftrace_make_call_kernel(struct dyn_ftrace *rec, unsigned long addr) } /* Make sure we have a nop */ - if (probe_kernel_read(&op, ip, sizeof(op))) { + if (read_inst(&op, ip)) { pr_err("Unable to read ftrace location %p\n", ip); return -EFAULT; } @@ -716,7 +725,7 @@ __ftrace_modify_call(struct dyn_ftrace *rec, unsigned long old_addr, } /* read where this goes */ - if (probe_kernel_read(&op, (void *)ip, sizeof(int))) { + if (read_inst(&op, (void *)ip)) { pr_err("Fetching opcode failed.\n"); return -EFAULT; } @@ -842,7 +851,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func) ppc_inst old, new; int ret; - old = *(unsigned int *)&ftrace_call; + old = ppc_inst_read((ppc_inst *)&ftrace_call); new = ftrace_call_replace(ip, (unsigned long)func, 1); ret = ftrace_modify_code(ip, old, new); @@ -850,7 +859,7 @@ int ftrace_update_ftrace_func(ftrace_func_t func) /* Also update the regs callback function */ if (!ret) { ip = (unsigned long)(&ftrace_regs_call); - old = *(unsigned int *)&ftrace_regs_call; + old = ppc_inst_read((ppc_inst *)&ftrace_regs_call); new = ftrace_call_replace(ip, (unsigned long)func, 1); ret = ftrace_modify_code(ip, old, new); } diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c index 1cfef0e5fec5..d1dff1dc3a11 100644 --- a/arch/powerpc/kernel/uprobes.c +++ b/arch/powerpc/kernel/uprobes.c @@ -173,7 +173,7 @@ bool arch_uprobe_skip_sstep(struct arch_uprobe *auprobe, struct pt_regs *regs) * emulate_step() returns 1 if the insn was successfully emulated. * For all other cases, we need to single-step in hardware. */ - ret = emulate_step(regs, auprobe->insn); + ret = emulate_step(regs, ppc_inst_read((ppc_inst *)auprobe->insn)); if (ret > 0) return true; diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 849eee63df3d..88ee03ff55f1 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -346,9 +346,9 @@ static unsigned long branch_bform_target(const ppc_inst *instr) unsigned long branch_target(const ppc_inst *instr) { - if (instr_is_branch_iform(*instr)) + if (instr_is_branch_iform(ppc_inst_read(instr))) return branch_iform_target(instr); - else if (instr_is_branch_bform(*instr)) + else if (instr_is_branch_bform(ppc_inst_read(instr))) return branch_bform_target(instr); return 0; @@ -356,7 +356,7 @@ unsigned long branch_target(const ppc_inst *instr) int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr) { - if (instr_is_branch_iform(*instr) || instr_is_branch_bform(*instr)) + if (instr_is_branch_iform(ppc_inst_read(instr)) || instr_is_branch_bform(ppc_inst_read(instr))) return branch_target(instr) == addr; return 0; @@ -368,10 +368,10 @@ ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src) target = branch_target(src); - if (instr_is_branch_iform(*src)) - return create_branch(dest, target, *src); - else if (instr_is_branch_bform(*src)) - return create_cond_branch(dest, target, *src); + if (instr_is_branch_iform(ppc_inst_read(src))) + return create_branch(dest, target, ppc_inst_word(ppc_inst_read(src))); + else if (instr_is_branch_bform(ppc_inst_read(src))) + return create_cond_branch(dest, target, ppc_inst_word(ppc_inst_read(src))); return PPC_INST(0); } @@ -588,7 +588,7 @@ static void __init test_translate_branch(void) patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(p, addr)); check(instr_is_branch_to_addr(q, addr)); - check(*q == PPC_INST(0x4a000000)); + check(ppc_inst_equal(ppc_inst_read(q), PPC_INST(0x4a000000))); /* Maximum positive case, move x to x - 32 MB + 4 */ p = buf + 0x2000000; @@ -598,7 +598,7 @@ static void __init test_translate_branch(void) patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(p, addr)); check(instr_is_branch_to_addr(q, addr)); - check(*q == PPC_INST(0x49fffffc)); + check(ppc_inst_equal(ppc_inst_read(q), PPC_INST(0x49fffffc))); /* Jump to x + 16 MB moved to x + 20 MB */ p = buf; @@ -638,7 +638,7 @@ static void __init test_translate_branch(void) patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(p, addr)); check(instr_is_branch_to_addr(q, addr)); - check(*q == PPC_INST(0x43ff8000)); + check(ppc_inst_equal(ppc_inst_read(q), PPC_INST(0x43ff8000))); /* Maximum positive case, move x to x - 32 KB + 4 */ p = buf + 0x8000; @@ -648,7 +648,7 @@ static void __init test_translate_branch(void) patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(p, addr)); check(instr_is_branch_to_addr(q, addr)); - check(*q == PPC_INST(0x43ff7ffc)); + check(ppc_inst_equal(ppc_inst_read(q), PPC_INST(0x43ff7ffc))); /* Jump to x + 12 KB moved to x + 20 KB */ p = buf; diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c index fe8ec099aa96..9e322f701e32 100644 --- a/arch/powerpc/lib/feature-fixups.c +++ b/arch/powerpc/lib/feature-fixups.c @@ -49,8 +49,8 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest, instr = *src; - if (instr_is_relative_branch(*src)) { - unsigned int *target = (unsigned int *)branch_target(src); + if (instr_is_relative_branch(PPC_INST(*src))) { + unsigned int *target = (unsigned int *)branch_target((ppc_inst *)src); /* Branch within the section doesn't need translating */ if (target < alt_start || target > alt_end) { @@ -60,7 +60,7 @@ static int patch_alt_instruction(unsigned int *src, unsigned int *dest, } } - raw_patch_instruction(dest, instr); + raw_patch_instruction((ppc_inst *)dest, PPC_INST(instr)); return 0; } diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index dec522fa8201..ee084411f2f5 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -704,13 +704,13 @@ static int xmon_core(struct pt_regs *regs, int fromipi) if ((regs->msr & (MSR_IR|MSR_PR|MSR_64BIT)) == (MSR_IR|MSR_64BIT)) { bp = at_breakpoint(regs->nip); if (bp != NULL) { - int stepped = emulate_step(regs, bp->instr[0]); + int stepped = emulate_step(regs, ppc_inst_read(bp->instr)); if (stepped == 0) { regs->nip = (unsigned long) &bp->instr[0]; atomic_inc(&bp->ref_count); } else if (stepped < 0) { printf("Couldn't single-step %s instruction\n", - (IS_RFID(bp->instr[0])? "rfid": "mtmsrd")); + IS_RFID(ppc_inst_read(bp->instr))? "rfid": "mtmsrd"); } } } @@ -953,7 +953,7 @@ static void remove_bpts(void) if (mread(bp->address, &instr, 4) == 4 && ppc_inst_equal(instr, PPC_INST(bpinstr)) && patch_instruction( - (ppc_inst *)bp->address, bp->instr[0]) != 0) + (ppc_inst *)bp->address, ppc_inst_read(bp->instr)) != 0) printf("Couldn't remove breakpoint at %lx\n", bp->address); } From patchwork Fri Mar 20 05:18:03 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258642 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kCGP1xjrz9sRN for ; Fri, 20 Mar 2020 16:37:33 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=dSbc6/Jm; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kCGN5YMKzDrdj for ; Fri, 20 Mar 2020 16:37:32 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1041; helo=mail-pj1-x1041.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=dSbc6/Jm; dkim-atps=neutral Received: from mail-pj1-x1041.google.com (mail-pj1-x1041.google.com [IPv6:2607:f8b0:4864:20::1041]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBsZ3Lz5zDrSF for ; Fri, 20 Mar 2020 16:19:30 +1100 (AEDT) Received: by mail-pj1-x1041.google.com with SMTP id hg10so1976129pjb.1 for ; Thu, 19 Mar 2020 22:19:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=+H54qxJPpdqIdmINWOLFwRUZ62EakrRU7Y6sQkZDKqM=; b=dSbc6/Jmv6fGESuwRUe+z0hBNkJnRc1Kor7djvuWozxnQWL/06Uyu4/QF0kO99RvcP C70j6WYLDmlZf+hY3mTCX1fwgwGIXspNxqbHcgyWCirih6aMn3kHUX8yfqzY4cULFm2T 6H6ER4vxvM54MZknM2eB3MRimK6k6ktXbD8e9TyIFjEL2k8McoUvrHrSMZlqazPoGoHQ /LPwStR/I1nkhr9nNVp3piC/wOszMNO5lZmjwFEL7pZoSFr6UkADRNxHg9JnC0djVKnG pJfaFKXMqolxNGmni8cX+H1gDpd0eWBiAXBON93qtRg6KuSJnIXuZfkOx5MGwVtQGX7n 9UUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=+H54qxJPpdqIdmINWOLFwRUZ62EakrRU7Y6sQkZDKqM=; b=BMcT1amHBgwGxbEiRSDmpdjjT0NtL6P89ehjX6Pr5yUsavW/9QfIPHBnnZJhJxiRTU O5qUMV4VogFx1Waz/2C1BGBJ4nykL3/pPKPIPNQq9BakyF5C8yb3jfAVxxtbdc7L18Rp 1UbEUsp0BvISGiPWU7xUxr6X2t8YU8bNKQqyBSB0yIvLhgQIitlD+nZeuC0HKbFwUBwr zLtUh4O+4i4qWMM+4yQ5mc0cAefuArZPeSxQvMqrJgR75J/eVHYrdIA7jJQR/8kadmcn IlvhCYEBbx8ffbcCSlO7kob6ZUt9aMULIkpZR5YJ9F9ktn4mohJh2Gzqn7ebfzu1qJDI 29zQ== X-Gm-Message-State: ANhLgQ3yf37AE599eXteS7PxJ/UFGy6NhhM3DDR6Wl78dSTR2xEaH4ns R2UJy65Fp5emKDa40OnluSzgCpFmPfU= X-Google-Smtp-Source: ADFU+vsZz07yP35RQ/5qfDCMzn9zpAqUT4Tc40XmIgYjBAK/11cfgvt1kRpEPex++g6uIQxB/ohdIw== X-Received: by 2002:a17:902:a701:: with SMTP id w1mr6163826plq.165.1584681566990; Thu, 19 Mar 2020 22:19:26 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:26 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 10/16] powerpc: Make test_translate_branch() independent of instruction length Date: Fri, 20 Mar 2020 16:18:03 +1100 Message-Id: <20200320051809.24332-11-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" test_translate_branch() uses two pointers to instructions within a buffer, p and q, to test patch_branch(). The pointer arithmetic done on them assumes a size of 4. This will not work if the instruction length changes. Instead do the arithmetic relative to the void * to the buffer. Signed-off-by: Jordan Niethe --- v4: New to series --- arch/powerpc/lib/code-patching.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index 88ee03ff55f1..fa7f32adf029 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -563,7 +563,7 @@ static void __init test_branch_bform(void) static void __init test_translate_branch(void) { unsigned long addr; - ppc_inst *p, *q; + void *p, *q; void *buf; buf = vmalloc(PAGE_ALIGN(0x2000000 + 1)); @@ -576,7 +576,7 @@ static void __init test_translate_branch(void) addr = (unsigned long)p; patch_branch(p, addr, 0); check(instr_is_branch_to_addr(p, addr)); - q = p + 1; + q = buf + 4; patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(q, addr)); @@ -626,7 +626,7 @@ static void __init test_translate_branch(void) addr = (unsigned long)p; patch_instruction(p, create_cond_branch(p, addr, 0)); check(instr_is_branch_to_addr(p, addr)); - q = p + 1; + q = buf + 4; patch_instruction(q, translate_branch(q, p)); check(instr_is_branch_to_addr(q, addr)); From patchwork Fri Mar 20 05:18:04 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258646 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kCJp3cyMz9sRN for ; Fri, 20 Mar 2020 16:39:38 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=iPMj33YC; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kCJp3BGvzDrcC for ; Fri, 20 Mar 2020 16:39:38 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::642; helo=mail-pl1-x642.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=iPMj33YC; dkim-atps=neutral Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBsd5SQDzDrVL for ; Fri, 20 Mar 2020 16:19:33 +1100 (AEDT) Received: by mail-pl1-x642.google.com with SMTP id m1so2022159pll.6 for ; Thu, 19 Mar 2020 22:19:33 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=kZ1o4WX6hAPN7c5dpLC+hTxSEBgkXrrxIKkJV1CSAqE=; b=iPMj33YCLbH/hb8UjtbhwFJepPTw6PBfzkRE2nGpojvqJHLXp/tj9EhXgWPNgngmF3 qpcKX8niSnWUYvw8cX8GxK6HT+wf1TueBGycLLk8s9xj3HsJZklD+Z2DjMjJf252vs/1 aZFqNm8rwg0RdFvKUQtQK8z5vAUYn51QJkfm9v5APn8no/KkvfM2uVP5ur5FPYOsgT8y JJxgzm/sFksXd4H1EzgeIoNUP6hx4rL9RmQkzRg5EktniegBfzfnFpEiBlsCvGQ9ZDCn PS70w7EOM2KlMeSxX45aOYcMClCOzXKliEqgq04u9Xb2gAbtxJFHPR4MblYRkBTjOcuk 2tjA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=kZ1o4WX6hAPN7c5dpLC+hTxSEBgkXrrxIKkJV1CSAqE=; b=KZhrTDQPQ9iQmcCIbee4+PdPBq0mH5ND4NTYFvAJZ5HqOrBvVEhKY50MzluZOZ6Lqv TUXkKnuVVi8/QgggNhqMGuzF1kuZTu4FZtoRdfFN5ftNpxnt6P1fVXvFu9Yhiab/U2eV yPiBCnhAGKx6jeSOuBKSzVe1A34lc4HE2NYf9qiVskv/2A5nQPSMU71TTMLjeCxVRxDR eyWpk2GQajPMV3VF8lsdOK2dYRoX9S/Fe+hoN0vF2aerxwLhPYc80fA22smlGvYyvcdA +VkUwHcaVE4UfxLJ6UxKKlc+Iv3EarPc695KgfUzpicV6vkm71LHyz/1+OJZJn7Cpn+T zsdA== X-Gm-Message-State: ANhLgQ3aGZAewzv+83ZNG/0suBiFm0TLuBTMxcfd4GijtiaRd8SD0Sk7 Z6Kta61jqwTMQEXYUMqNSrYq+NVQPqY= X-Google-Smtp-Source: ADFU+vtxfjRB37I/KhZn37JhqFZzTHOki4eFRHevbZj1X0EXPqIVn/7eopzGVwzKUvwSDvcF2oqW+w== X-Received: by 2002:a17:90b:d8d:: with SMTP id bg13mr7647818pjb.29.1584681570874; Thu, 19 Mar 2020 22:19:30 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.27 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:30 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 11/16] powerpc: Enable Prefixed Instructions Date: Fri, 20 Mar 2020 16:18:04 +1100 Message-Id: <20200320051809.24332-12-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" From: Alistair Popple Prefix instructions have their own FSCR bit which needs to enabled via a CPU feature. The kernel will save the FSCR for problem state but it needs to be enabled initially. If prefixed instructions are made unavailable by the [H]FSCR, attempting to use them will cause a facility unavailable exception. Add "PREFIX" to the facility_strings[]. Currently there are no prefixed instructions that are actually emulated by emulate_instruction() within facility_unavailable_exception(). However, when caused by a prefixed instructions the SRR1 PREFIXED bit is set. Prepare for dealing with emulated prefixed instructions by checking for this bit. Signed-off-by: Alistair Popple Signed-off-by: Jordan Niethe Reviewed-by: Nicholas Piggin --- v4: - Squash "Check for prefixed instructions in facility_unavailable_exception()" here - Remove dt parts for now --- arch/powerpc/include/asm/reg.h | 3 +++ arch/powerpc/kernel/traps.c | 1 + 2 files changed, 4 insertions(+) diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index 1aa46dff0957..c7758c2ccc5f 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -397,6 +397,7 @@ #define SPRN_RWMR 0x375 /* Region-Weighting Mode Register */ /* HFSCR and FSCR bit numbers are the same */ +#define FSCR_PREFIX_LG 13 /* Enable Prefix Instructions */ #define FSCR_SCV_LG 12 /* Enable System Call Vectored */ #define FSCR_MSGP_LG 10 /* Enable MSGP */ #define FSCR_TAR_LG 8 /* Enable Target Address Register */ @@ -408,11 +409,13 @@ #define FSCR_VECVSX_LG 1 /* Enable VMX/VSX */ #define FSCR_FP_LG 0 /* Enable Floating Point */ #define SPRN_FSCR 0x099 /* Facility Status & Control Register */ +#define FSCR_PREFIX __MASK(FSCR_PREFIX_LG) #define FSCR_SCV __MASK(FSCR_SCV_LG) #define FSCR_TAR __MASK(FSCR_TAR_LG) #define FSCR_EBB __MASK(FSCR_EBB_LG) #define FSCR_DSCR __MASK(FSCR_DSCR_LG) #define SPRN_HFSCR 0xbe /* HV=1 Facility Status & Control Register */ +#define HFSCR_PREFIX __MASK(FSCR_PREFIX_LG) #define HFSCR_MSGP __MASK(FSCR_MSGP_LG) #define HFSCR_TAR __MASK(FSCR_TAR_LG) #define HFSCR_EBB __MASK(FSCR_EBB_LG) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index 82a3438300fd..a4764b039749 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -1720,6 +1720,7 @@ void facility_unavailable_exception(struct pt_regs *regs) [FSCR_TAR_LG] = "TAR", [FSCR_MSGP_LG] = "MSGP", [FSCR_SCV_LG] = "SCV", + [FSCR_PREFIX_LG] = "PREFIX", }; char *facility = "unknown"; u64 value; From patchwork Fri Mar 20 05:18:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258648 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kCLr6YF2z9sRN for ; Fri, 20 Mar 2020 16:41:24 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=s6HkSl73; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kCLr2vSNzDrqc for ; Fri, 20 Mar 2020 16:41:24 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::444; helo=mail-pf1-x444.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=s6HkSl73; dkim-atps=neutral Received: from mail-pf1-x444.google.com (mail-pf1-x444.google.com [IPv6:2607:f8b0:4864:20::444]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBsj14mHzDrRv for ; Fri, 20 Mar 2020 16:19:37 +1100 (AEDT) Received: by mail-pf1-x444.google.com with SMTP id h72so418454pfe.4 for ; Thu, 19 Mar 2020 22:19:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=N803Rlxjqi2Zye/wf/1l803z+FJx9F8eXRhqPNShi8I=; b=s6HkSl73dcGB3NZnYKc7CMVuBUM5sZjwBZXg+RgK56LP8/xH/hhEGhwCzTDsD5d0GA Xx2hiMx7XQbRV5rr1XclteEHeP6pXYf8bFgyOW7D+2oySqJRyxqmatAShgzjGPFvtBRe 9u3W+4XlGV2uac+d1ZYV9OVk24olF85xFPcVMUsGnb48wC6V8pm6u5FBWwTFHJutiNfK mKGy98h1rDWkHT6ipnzgWFlVscB4BBc6+DDwKr6foyun+Of4+kIqRu9uvXLwoisqlnCK hA8YcdX9cOcexi+P8US7KwYuBPJnHNucr9txN8xEGl2jl7XaHJjv52rEbjlQmGzXzPIm TWwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=N803Rlxjqi2Zye/wf/1l803z+FJx9F8eXRhqPNShi8I=; b=W/TCj+GoTR0hqhkpbjey9pLvkErhOf/A27uyffAkViOUjk0jdN43TnhnoI7YF0K2EP WEyZVI6CA4VdtN4RGfNQEbSRGhB76wK1qP1AtOPMiDC0sU2w+gZfUN+lxuhGaIDMt4t5 a6yEC1w2GcmzmNxAkfdgA66zseqff7K8EFeqWu/UpPt3k3y9KzSoHLFtg6LMVD8QFFGA VPTjpJ2qir4wAiCz8IQxqVrKmT1pFbpp300Y70Oas5aRieiWSOTrrCVLXo1DV4uJwrXl 0flsVVfpSnK/Hq9OSqapG3/n/1oHlmd6iF8lrmwoiXLgp0MZveFRQrFqC6hqGkimpw1z dzPQ== X-Gm-Message-State: ANhLgQ2NNy3bbdm2ae1lioweFYcd7xe3H4qLwqH0i3N7DT7JPZk5T5aA uEGPism6F4hvnufl78jEq2EeUJnFcT4= X-Google-Smtp-Source: ADFU+vufQauG5AqUTsikyIqdFCawPHRPdbA5/Cze6Nhn5E5Z4gLhKfAcf8FgV3VPM+fpmdYvwjSgAA== X-Received: by 2002:a63:195a:: with SMTP id 26mr6427488pgz.400.1584681575017; Thu, 19 Mar 2020 22:19:35 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:34 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 12/16] powerpc: Define new SRR1 bits for a future ISA version Date: Fri, 20 Mar 2020 16:18:05 +1100 Message-Id: <20200320051809.24332-13-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Add the BOUNDARY SRR1 bit definition for when the cause of an alignment exception is a prefixed instruction that crosses a 64-byte boundary. Add the PREFIXED SRR1 bit definition for exceptions caused by prefixed instructions. Bit 35 of SRR1 is called SRR1_ISI_N_OR_G. This name comes from it being used to indicate that an ISI was due to the access being no-exec or guarded. A future ISA version adds another purpose. It is also set if there is an access in a cache-inhibited location for prefixed instruction. Rename from SRR1_ISI_N_OR_G to SRR1_ISI_N_G_OR_CIP. Signed-off-by: Jordan Niethe --- v2: Combined all the commits concerning SRR1 bits. --- arch/powerpc/include/asm/reg.h | 4 +++- arch/powerpc/kvm/book3s_hv_nested.c | 2 +- arch/powerpc/kvm/book3s_hv_rm_mmu.c | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/arch/powerpc/include/asm/reg.h b/arch/powerpc/include/asm/reg.h index c7758c2ccc5f..173f33df4fab 100644 --- a/arch/powerpc/include/asm/reg.h +++ b/arch/powerpc/include/asm/reg.h @@ -762,7 +762,7 @@ #endif #define SRR1_ISI_NOPT 0x40000000 /* ISI: Not found in hash */ -#define SRR1_ISI_N_OR_G 0x10000000 /* ISI: Access is no-exec or G */ +#define SRR1_ISI_N_G_OR_CIP 0x10000000 /* ISI: Access is no-exec or G or CI for a prefixed instruction */ #define SRR1_ISI_PROT 0x08000000 /* ISI: Other protection fault */ #define SRR1_WAKEMASK 0x00380000 /* reason for wakeup */ #define SRR1_WAKEMASK_P8 0x003c0000 /* reason for wakeup on POWER8 and 9 */ @@ -789,6 +789,8 @@ #define SRR1_PROGADDR 0x00010000 /* SRR0 contains subsequent addr */ #define SRR1_MCE_MCP 0x00080000 /* Machine check signal caused interrupt */ +#define SRR1_BOUNDARY 0x10000000 /* Prefixed instruction crosses 64-byte boundary */ +#define SRR1_PREFIXED 0x20000000 /* Exception caused by prefixed instruction */ #define SPRN_HSRR0 0x13A /* Save/Restore Register 0 */ #define SPRN_HSRR1 0x13B /* Save/Restore Register 1 */ diff --git a/arch/powerpc/kvm/book3s_hv_nested.c b/arch/powerpc/kvm/book3s_hv_nested.c index dc97e5be76f6..6ab685227574 100644 --- a/arch/powerpc/kvm/book3s_hv_nested.c +++ b/arch/powerpc/kvm/book3s_hv_nested.c @@ -1169,7 +1169,7 @@ static int kvmhv_translate_addr_nested(struct kvm_vcpu *vcpu, } else if (vcpu->arch.trap == BOOK3S_INTERRUPT_H_INST_STORAGE) { /* Can we execute? */ if (!gpte_p->may_execute) { - flags |= SRR1_ISI_N_OR_G; + flags |= SRR1_ISI_N_G_OR_CIP; goto forward_to_l1; } } else { diff --git a/arch/powerpc/kvm/book3s_hv_rm_mmu.c b/arch/powerpc/kvm/book3s_hv_rm_mmu.c index 220305454c23..b53a9f1c1a46 100644 --- a/arch/powerpc/kvm/book3s_hv_rm_mmu.c +++ b/arch/powerpc/kvm/book3s_hv_rm_mmu.c @@ -1260,7 +1260,7 @@ long kvmppc_hpte_hv_fault(struct kvm_vcpu *vcpu, unsigned long addr, status &= ~DSISR_NOHPTE; /* DSISR_NOHPTE == SRR1_ISI_NOPT */ if (!data) { if (gr & (HPTE_R_N | HPTE_R_G)) - return status | SRR1_ISI_N_OR_G; + return status | SRR1_ISI_N_G_OR_CIP; if (!hpte_read_permission(pp, slb_v & key)) return status | SRR1_ISI_PROT; } else if (status & DSISR_ISSTORE) { From patchwork Fri Mar 20 05:18:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258649 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kCNx5xFjz9sSN for ; Fri, 20 Mar 2020 16:43:13 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=LNNKW5Fw; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kCNx4rhwzDsMs for ; Fri, 20 Mar 2020 16:43:13 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::642; helo=mail-pl1-x642.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=LNNKW5Fw; dkim-atps=neutral Received: from mail-pl1-x642.google.com (mail-pl1-x642.google.com [IPv6:2607:f8b0:4864:20::642]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBsn0nvTzDrVL for ; Fri, 20 Mar 2020 16:19:41 +1100 (AEDT) Received: by mail-pl1-x642.google.com with SMTP id f16so2025425plj.4 for ; Thu, 19 Mar 2020 22:19:40 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=rwpdKuT9qWHTuGfbbXHwN1t+fqx2VFbWGReeY56xnts=; b=LNNKW5FwXakViJy8D4H3B5sjEaBKOc4llw3TbixXvwj/vVSUgfoSclJPkhpEYvKZCC gRLzE2BkWI9YlvDxuo6oM05mK1Ga/RRUiXBWDZB3yVj7taUCQ/HXVbkGGlzwH5xKdm87 IMKGX8o1PkveGbqrqa4K7e/l89tyq+0bXgCAdjSBMp9ii/+lqi8Vr/9FGOBOCjosMXuQ HnuAsZmxdo+PZgA/fh0oA5TrN2LgKu2U3hDd49RYUrrfHh28ln3Yht5qCLRHfOFGivHz uB3t7kxwoK+H0L2oUR18tGC+t5h7KQbVKA/0mkKOX5sJqoxEM7spANqs133FIA95uu+4 WdBw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=rwpdKuT9qWHTuGfbbXHwN1t+fqx2VFbWGReeY56xnts=; b=HTAN7URD/BbCw+oNeHY+uIc2tWXcUY3Bf7x6ixOPS8DsChbVxlyazNoyIfv3gAzj6Q Jr3TEZhZRhylnGYZRyJm/hnnCLSALUCklQvigoxkX61TDyCcPY6vn1DDv9++5X/jLTqD 2BPOp7KQv1uv4Hon8w/H2w88jl3LN/mCZ9GDIuL14wu3Ggp1UzOwA7hAwtkNepACkdv+ 3ZU4vCItcerzFVteySX5ZehNA5y+OkmzNpIQD4gW6QIxbmjPJLMRc2VhkWWmetc1YTfR k2DBQnJ71bo+LSOqlCFiwXUlOuWcDRHnt05KIODxpRXgv41+ibCY+1JNVYoXtGFyKV5m cNxg== X-Gm-Message-State: ANhLgQ2kc1IA3SXrKVJpZ37cf9N0P78BIx/OBWPDAZxuN50KywH0OOBy RC/DcM/CLLB4RGmff50dSdZcjdno57U= X-Google-Smtp-Source: ADFU+vuPqz365PGhrakGSD50bLdcNg3GLIEw7Qe1y9kS6VG5IuRvLlZkvouGZFI7RzKhSQjOuxrTqA== X-Received: by 2002:a17:90a:bd01:: with SMTP id y1mr7836154pjr.129.1584681578896; Thu, 19 Mar 2020 22:19:38 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:38 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 13/16] powerpc: Support prefixed instructions in alignment handler Date: Fri, 20 Mar 2020 16:18:06 +1100 Message-Id: <20200320051809.24332-14-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" Alignment interrupts can be caused by prefixed instructions accessing memory. Prefixed instructions are not permitted to cross 64-byte boundaries. If they do the alignment interrupt is invoked with SRR1 BOUNDARY bit set. If this occurs send a SIGBUS to the offending process if in user mode. If in kernel mode call bad_page_fault(). Signed-off-by: Jordan Niethe --- v2: - Move __get_user_instr() and __get_user_instr_inatomic() to this commit (previously in "powerpc sstep: Prepare to support prefixed instructions"). - Rename sufx to suffix - Use a macro for calculating instruction length v3: Move __get_user_{instr(), instr_inatomic()} up with the other get_user definitions and remove nested if. v4: Just do the things for alignment_exception(). Other changes handled elsewhere. --- arch/powerpc/kernel/traps.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c index a4764b039749..cd8b3043c268 100644 --- a/arch/powerpc/kernel/traps.c +++ b/arch/powerpc/kernel/traps.c @@ -583,6 +583,10 @@ static inline int check_io_access(struct pt_regs *regs) #define REASON_ILLEGAL (ESR_PIL | ESR_PUO) #define REASON_PRIVILEGED ESR_PPR #define REASON_TRAP ESR_PTR +#define REASON_PREFIXED 0 +#define REASON_BOUNDARY 0 + +#define inst_length(reason) 4 /* single-step stuff */ #define single_stepping(regs) (current->thread.debug.dbcr0 & DBCR0_IC) @@ -597,6 +601,10 @@ static inline int check_io_access(struct pt_regs *regs) #define REASON_ILLEGAL SRR1_PROGILL #define REASON_PRIVILEGED SRR1_PROGPRIV #define REASON_TRAP SRR1_PROGTRAP +#define REASON_PREFIXED SRR1_PREFIXED +#define REASON_BOUNDARY SRR1_BOUNDARY + +#define inst_length(reason) (((reason) & REASON_PREFIXED) ? 8 : 4) #define single_stepping(regs) ((regs)->msr & MSR_SE) #define clear_single_step(regs) ((regs)->msr &= ~MSR_SE) @@ -1593,11 +1601,20 @@ void alignment_exception(struct pt_regs *regs) { enum ctx_state prev_state = exception_enter(); int sig, code, fixed = 0; + unsigned long reason; /* We restore the interrupt state now */ if (!arch_irq_disabled_regs(regs)) local_irq_enable(); + reason = get_reason(regs); + + if (reason & REASON_BOUNDARY) { + sig = SIGBUS; + code = BUS_ADRALN; + goto bad; + } + if (tm_abort_check(regs, TM_CAUSE_ALIGNMENT | TM_CAUSE_PERSISTENT)) goto bail; @@ -1606,7 +1623,8 @@ void alignment_exception(struct pt_regs *regs) fixed = fix_alignment(regs); if (fixed == 1) { - regs->nip += 4; /* skip over emulated instruction */ + /* skip over emulated instruction */ + regs->nip += inst_length(reason); emulate_single_step(regs); goto bail; } @@ -1619,6 +1637,7 @@ void alignment_exception(struct pt_regs *regs) sig = SIGBUS; code = BUS_ADRALN; } +bad: if (user_mode(regs)) _exception(sig, regs, code, regs->dar); else From patchwork Fri Mar 20 05:18:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258651 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kCQm11Mjz9sRN for ; Fri, 20 Mar 2020 16:44:48 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=MovF7N+w; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kCQm0HmNzDrHp for ; Fri, 20 Mar 2020 16:44:48 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::644; helo=mail-pl1-x644.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=MovF7N+w; dkim-atps=neutral Received: from mail-pl1-x644.google.com (mail-pl1-x644.google.com [IPv6:2607:f8b0:4864:20::644]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBst2dZkzDrS2 for ; Fri, 20 Mar 2020 16:19:46 +1100 (AEDT) Received: by mail-pl1-x644.google.com with SMTP id h11so2009407plr.11 for ; Thu, 19 Mar 2020 22:19:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=elVhSeM7Rq7+/taveabK8kDZfKJLto7i3lUZ5L8caIE=; b=MovF7N+wj52ncNukz5OlHTxAVOcFiNkMaXFuDtnpTdu2SqqWG3+ZkU+gTzKCxFC4l8 /6524CObus712hSAJv7WdF9NZLpLpS3DkIYwMzU0kzgI31ZcT9p00EjaEljGO+ZdN5Fd 7PUFIKqH0paw5Af3sFn3Lzm78Y2NbaQ8JCre4ufM5GupL7p9hZOKHPNmopP6VzRdN9gk Vcykdeah1Brp7vjKa/ddwsCJQvzaR/X7uKqo9HsQS+4wmTmLpWksdsu/+wXks6r2AFf/ qWJqvqTHzyZkGlY6Jagh0UD1pSv/7aZ6/vmxVO9f5Mv0H/PoYOznnQXLBNAIWocqU1uX nQbA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=elVhSeM7Rq7+/taveabK8kDZfKJLto7i3lUZ5L8caIE=; b=ipiIJnRFUNLV6sJ0Zd4sd02WJzVrdT0pX5k2clKPMf1l2qOb3GjHxA1XMUPlPDHCmz Rgb0KSYQBw10WxV1hEWJSdH4dENSR4NbsAvIWFjUZVU3EHUIg/oAhGzUFoWIB9VGKwau pVb9nPiwSBFeLdFvjoUbJoY7ssUqVWVE4jBS+bLvkKNj8gbU79YA1ETRI/OBgXeAGiEp FzAVtYa8cJ+df/VNwx82xBpaHiBTusKjuOx4BBwoLLF2Jkr64raHG9zsd9mtK32XgOzi 5OMH+0C9OBIdoAPeVav5Vtk9Lfg+aKZAYrW7WuhnncCAvChdZ5/vg8yc6HZCWiO3DlYP kUxA== X-Gm-Message-State: ANhLgQ3XT85TV6i7iXHs76glNklqk/k5z4af1vSN+id17ikh+tHf+/vy zr3o4WXoz1mdbynZfc8Xb6ZJcYHxl78= X-Google-Smtp-Source: ADFU+vthPeHueF19wH9nxRK5A+zXc5Lh0Fn/ROPYSdo9YFmubA6fhLUhpbqUyENCtUev1wZHy1OqqA== X-Received: by 2002:a17:90a:d156:: with SMTP id t22mr7421433pjw.138.1584681583142; Thu, 19 Mar 2020 22:19:43 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.39 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:42 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 14/16] powerpc64: Add prefixed instructions to instruction data type Date: Fri, 20 Mar 2020 16:18:07 +1100 Message-Id: <20200320051809.24332-15-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" For powerpc64, redefine the ppc_inst type so both word and prefixed instructions can be represented. On powerpc32 the type will remain the same. Update places which had assumed instructions to be 4 bytes long. Signed-off-by: Jordan Niethe --- v4: New to series --- arch/powerpc/include/asm/code-patching.h | 10 +-- arch/powerpc/include/asm/inst.h | 90 ++++++++++++++++++++++++ arch/powerpc/include/asm/kprobes.h | 2 +- arch/powerpc/include/asm/sstep.h | 4 ++ arch/powerpc/include/asm/uaccess.h | 22 ++++++ arch/powerpc/include/asm/uprobes.h | 2 +- arch/powerpc/kernel/align.c | 5 +- arch/powerpc/kernel/hw_breakpoint.c | 2 +- arch/powerpc/kernel/kprobes.c | 7 +- arch/powerpc/kernel/optprobes.c | 42 ++++++----- arch/powerpc/kernel/optprobes_head.S | 3 + arch/powerpc/kernel/trace/ftrace.c | 19 ++++- arch/powerpc/kernel/uprobes.c | 2 +- arch/powerpc/lib/code-patching.c | 22 ++++-- arch/powerpc/lib/sstep.c | 4 +- arch/powerpc/xmon/xmon.c | 38 +++++++--- 16 files changed, 221 insertions(+), 53 deletions(-) diff --git a/arch/powerpc/include/asm/code-patching.h b/arch/powerpc/include/asm/code-patching.h index 68bd9db334bd..bd41e1558707 100644 --- a/arch/powerpc/include/asm/code-patching.h +++ b/arch/powerpc/include/asm/code-patching.h @@ -25,11 +25,11 @@ bool is_offset_in_branch_range(long offset); ppc_inst create_branch(const ppc_inst *addr, unsigned long target, int flags); -unsigned int create_cond_branch(const ppc_inst *addr, +ppc_inst create_cond_branch(const void *addr, unsigned long target, int flags); -int patch_branch(ppc_inst *addr, unsigned long target, int flags); -int patch_instruction(ppc_inst *addr, ppc_inst instr); -int raw_patch_instruction(ppc_inst *addr, ppc_inst instr); +int patch_branch(void *addr, unsigned long target, int flags); +int patch_instruction(void *addr, ppc_inst instr); +int raw_patch_instruction(void *addr, ppc_inst instr); static inline unsigned long patch_site_addr(s32 *site) { @@ -60,7 +60,7 @@ static inline int modify_instruction_site(s32 *site, unsigned int clr, unsigned int instr_is_relative_branch(ppc_inst instr); int instr_is_relative_link_branch(ppc_inst instr); int instr_is_branch_to_addr(const ppc_inst *instr, unsigned long addr); -unsigned long branch_target(const ppc_inst *instr); +unsigned long branch_target(const void *instr); ppc_inst translate_branch(const ppc_inst *dest, const ppc_inst *src); extern bool is_conditional_branch(ppc_inst instr); diff --git a/arch/powerpc/include/asm/inst.h b/arch/powerpc/include/asm/inst.h index 7c8596ee411e..1a40b0a71128 100644 --- a/arch/powerpc/include/asm/inst.h +++ b/arch/powerpc/include/asm/inst.h @@ -6,6 +6,95 @@ * Instruction data type for POWER */ +#ifdef __powerpc64__ + +typedef struct ppc_inst { + union { + struct { + u32 word; + u32 pad; + } __packed; + struct { + u32 prefix; + u32 suffix; + } __packed; + }; +} ppc_inst; + +#define PPC_INST(x) ((ppc_inst) { .word = (x), .pad = 0 }) +#define PPC_INST_PREFIXED(x, y) ((ppc_inst) { .prefix = (x), .suffix = (y) }) + +static inline int ppc_inst_opcode(ppc_inst x) +{ + return x.word >> 26; +} + +static inline bool ppc_inst_prefixed(ppc_inst x) { + return ppc_inst_opcode(x) == 1; +} + +static inline int ppc_inst_len(ppc_inst x) +{ + if (ppc_inst_prefixed(x)) + return 8; + else + return 4; +} + +static inline u32 ppc_inst_word(ppc_inst x) +{ + return x.word; +} + +static inline u32 ppc_inst_prefix(ppc_inst x) +{ + return x.prefix; +} + +static inline u32 ppc_inst_suffix(ppc_inst x) +{ + return x.suffix; +} + + +static inline ppc_inst ppc_inst_read(const void *ptr) +{ + ppc_inst inst; + inst.word = *(u32 *)ptr; + if (ppc_inst_prefixed(inst)) + inst.suffix = *((u32 *)ptr + 1); + else + inst.pad = 0; + return inst; +} + +static inline void ppc_inst_write(ppc_inst *ptr, ppc_inst x) +{ + if (ppc_inst_prefixed(x)) { + *(u32 *)ptr = x.prefix; + *((u32 *)ptr + 1) = x.suffix; + } else { + *(u32 *)ptr = x.word; + } +} + +static inline bool ppc_inst_equal(ppc_inst x, ppc_inst y) +{ + return !memcmp(&x, &y, sizeof(struct ppc_inst)); +} + +static inline bool ppc_inst_null(ppc_inst x) +{ + return x.word == 0 && x.pad == 0; +} + +static inline u32 ppc_inst_mask(ppc_inst x, u32 mask) +{ + return ppc_inst_word(x) & mask; +} + +#else /* !__powerpc64__ */ + typedef u32 ppc_inst; #define PPC_INST(x) (x) @@ -50,4 +139,5 @@ static inline u32 ppc_inst_mask(ppc_inst x, u32 mask) return ppc_inst_word(x) & mask; } +#endif /* __powerpc64__ */ #endif /* _ASM_INST_H */ diff --git a/arch/powerpc/include/asm/kprobes.h b/arch/powerpc/include/asm/kprobes.h index 66b3f2983b22..4fc0e15e23a5 100644 --- a/arch/powerpc/include/asm/kprobes.h +++ b/arch/powerpc/include/asm/kprobes.h @@ -43,7 +43,7 @@ extern kprobe_opcode_t optprobe_template_ret[]; extern kprobe_opcode_t optprobe_template_end[]; /* Fixed instruction size for powerpc */ -#define MAX_INSN_SIZE 1 +#define MAX_INSN_SIZE 2 #define MAX_OPTIMIZED_LENGTH sizeof(kprobe_opcode_t) /* 4 bytes */ #define MAX_OPTINSN_SIZE (optprobe_template_end - optprobe_template_entry) #define RELATIVEJUMP_SIZE sizeof(kprobe_opcode_t) /* 4 bytes */ diff --git a/arch/powerpc/include/asm/sstep.h b/arch/powerpc/include/asm/sstep.h index ef5483288920..5eb825fb77cd 100644 --- a/arch/powerpc/include/asm/sstep.h +++ b/arch/powerpc/include/asm/sstep.h @@ -90,11 +90,15 @@ enum instruction_type { #define VSX_LDLEFT 4 /* load VSX register from left */ #define VSX_CHECK_VEC 8 /* check MSR_VEC not MSR_VSX for reg >= 32 */ +/* Prefixed flag, ORed in with type */ +#define PREFIXED 0x800 + /* Size field in type word */ #define SIZE(n) ((n) << 12) #define GETSIZE(w) ((w) >> 12) #define GETTYPE(t) ((t) & INSTR_TYPE_MASK) +#define GETLENGTH(t) (((t) & PREFIXED) ? 8 : 4) #define MKOP(t, f, s) ((t) | (f) | SIZE(s)) diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index 2f500debae21..dee4fa1cd3ec 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -105,6 +105,28 @@ static inline int __access_ok(unsigned long addr, unsigned long size, #define __put_user_inatomic(x, ptr) \ __put_user_nosleep((__typeof__(*(ptr)))(x), (ptr), sizeof(*(ptr))) +/* + * When reading an instruction iff it is a prefix, the suffix needs to be also + * loaded. + */ +#define __get_user_instr(x, ptr) \ +({ \ + long __gui_ret = 0; \ + __gui_ret = __get_user(x.prefix, (unsigned int __user *)ptr); \ + if (!__gui_ret && ppc_inst_prefixed(x)) \ + __gui_ret = __get_user(x.suffix, (unsigned int __user *)ptr + 1); \ + __gui_ret; \ +}) + +#define __get_user_instr_inatomic(x, ptr) \ +({ \ + long __gui_ret = 0; \ + __gui_ret = __get_user_inatomic(x.prefix, (unsigned int __user *)ptr); \ + if (!__gui_ret && ppc_inst_prefixed(x)) \ + __gui_ret = __get_user_inatomic(x.suffix, (unsigned int __user *)ptr + 1); \ + __gui_ret; \ +}) + extern long __put_user_bad(void); /* diff --git a/arch/powerpc/include/asm/uprobes.h b/arch/powerpc/include/asm/uprobes.h index fff3c5fc90b5..7896a7125fa9 100644 --- a/arch/powerpc/include/asm/uprobes.h +++ b/arch/powerpc/include/asm/uprobes.h @@ -14,7 +14,7 @@ typedef ppc_opcode_t uprobe_opcode_t; -#define MAX_UINSN_BYTES 4 +#define MAX_UINSN_BYTES 8 #define UPROBE_XOL_SLOT_BYTES (MAX_UINSN_BYTES) /* The following alias is needed for reference from arch-agnostic code */ diff --git a/arch/powerpc/kernel/align.c b/arch/powerpc/kernel/align.c index b246ca124931..110eadd85c58 100644 --- a/arch/powerpc/kernel/align.c +++ b/arch/powerpc/kernel/align.c @@ -303,13 +303,14 @@ int fix_alignment(struct pt_regs *regs) */ CHECK_FULL_REGS(regs); - if (unlikely(__get_user(instr, (unsigned int __user *)regs->nip))) + if (unlikely(__get_user_instr(instr, (void __user *)regs->nip))) return -EFAULT; if ((regs->msr & MSR_LE) != (MSR_KERNEL & MSR_LE)) { /* We don't handle PPC little-endian any more... */ if (cpu_has_feature(CPU_FTR_PPC_LE)) return -EIO; - instr = PPC_INST(swab32(ppc_inst_word(instr))); + instr = PPC_INST_PREFIXED(swab32(ppc_inst_word(instr)), + swab32(ppc_inst_suffix(instr))); } #ifdef CONFIG_SPE diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index f001de471b98..212e0abfda43 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -249,7 +249,7 @@ static bool stepping_handler(struct pt_regs *regs, struct perf_event *bp, struct instruction_op op; unsigned long addr = info->address; - if (__get_user_inatomic(instr, (unsigned int *)regs->nip)) + if (__get_user_instr_inatomic(instr, (void __user*)regs->nip)) goto fail; ret = analyse_instr(&op, regs, instr); diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c index f142d11d7b48..1a5370a3c7c8 100644 --- a/arch/powerpc/kernel/kprobes.c +++ b/arch/powerpc/kernel/kprobes.c @@ -153,7 +153,7 @@ NOKPROBE_SYMBOL(arch_arm_kprobe); void arch_disarm_kprobe(struct kprobe *p) { - patch_instruction(p->addr, PPC_INST(p->opcode)); + patch_instruction(p->addr, ppc_inst_read(p->ainsn.insn)); } NOKPROBE_SYMBOL(arch_disarm_kprobe); @@ -487,12 +487,13 @@ int kprobe_post_handler(struct pt_regs *regs) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); + int len = ppc_inst_len(ppc_inst_read(cur->ainsn.insn)); if (!cur || user_mode(regs)) return 0; /* make sure we got here for instruction we have a kprobe on */ - if (((unsigned long)cur->ainsn.insn + 4) != regs->nip) + if ((unsigned long)cur->ainsn.insn + len != regs->nip) return 0; if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { @@ -501,7 +502,7 @@ int kprobe_post_handler(struct pt_regs *regs) } /* Adjust nip to after the single-stepped instruction */ - regs->nip = (unsigned long)cur->addr + 4; + regs->nip = (unsigned long)cur->addr + len; regs->msr |= kcb->kprobe_saved_msr; /*Restore back the original saved kprobes variables and continue. */ diff --git a/arch/powerpc/kernel/optprobes.c b/arch/powerpc/kernel/optprobes.c index 5b53c373373b..af6761859fba 100644 --- a/arch/powerpc/kernel/optprobes.c +++ b/arch/powerpc/kernel/optprobes.c @@ -158,38 +158,38 @@ void patch_imm32_load_insns(unsigned int val, kprobe_opcode_t *addr) /* * Generate instructions to load provided immediate 64-bit value - * to register 'r3' and patch these instructions at 'addr'. + * to register 'reg' and patch these instructions at 'addr'. */ -void patch_imm64_load_insns(unsigned long val, kprobe_opcode_t *addr) +void patch_imm64_load_insns(unsigned long val, int reg, kprobe_opcode_t *addr) { - /* lis r3,(op)@highest */ - patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(3) | + /* lis reg,(op)@highest */ + patch_instruction(addr, PPC_INST(PPC_INST_ADDIS | ___PPC_RT(reg) | ((val >> 48) & 0xffff))); addr++; - /* ori r3,r3,(op)@higher */ - patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) | - ___PPC_RS(3) | ((val >> 32) & 0xffff))); + /* ori reg,reg,(op)@higher */ + patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) | + ___PPC_RS(reg) | ((val >> 32) & 0xffff))); addr++; - /* rldicr r3,r3,32,31 */ - patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(3) | - ___PPC_RS(3) | __PPC_SH64(32) | __PPC_ME64(31))); + /* rldicr reg,reg,32,31 */ + patch_instruction(addr, PPC_INST(PPC_INST_RLDICR | ___PPC_RA(reg) | + ___PPC_RS(reg) | __PPC_SH64(32) | __PPC_ME64(31))); addr++; - /* oris r3,r3,(op)@h */ - patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(3) | - ___PPC_RS(3) | ((val >> 16) & 0xffff))); + /* oris reg,reg,(op)@h */ + patch_instruction(addr, PPC_INST(PPC_INST_ORIS | ___PPC_RA(reg) | + ___PPC_RS(reg) | ((val >> 16) & 0xffff))); addr++; - /* ori r3,r3,(op)@l */ - patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(3) | - ___PPC_RS(3) | (val & 0xffff))); + /* ori reg,reg,(op)@l */ + patch_instruction(addr, PPC_INST(PPC_INST_ORI | ___PPC_RA(reg) | + ___PPC_RS(reg) | (val & 0xffff))); } int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) { - ppc_inst branch_op_callback, branch_emulate_step; + ppc_inst branch_op_callback, branch_emulate_step, temp; kprobe_opcode_t *op_callback_addr, *emulate_step_addr, *buff; long b_offset; unsigned long nip, size; @@ -239,7 +239,7 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) * Fixup the template with instructions to: * 1. load the address of the actual probepoint */ - patch_imm64_load_insns((unsigned long)op, buff + TMPL_OP_IDX); + patch_imm64_load_insns((unsigned long)op, 3, buff + TMPL_OP_IDX); /* * 2. branch to optimized_callback() and emulate_step() @@ -268,7 +268,11 @@ int arch_prepare_optimized_kprobe(struct optimized_kprobe *op, struct kprobe *p) /* * 3. load instruction to be emulated into relevant register, and */ - patch_imm32_load_insns(*(unsigned int *)p->ainsn.insn, buff + TMPL_INSN_IDX); + temp = ppc_inst_read(p->ainsn.insn); + patch_imm64_load_insns(ppc_inst_word(temp) | + ((u64)ppc_inst_suffix(temp) << 32), + 4, + buff + TMPL_INSN_IDX); /* * 4. branch back from trampoline diff --git a/arch/powerpc/kernel/optprobes_head.S b/arch/powerpc/kernel/optprobes_head.S index cf383520843f..ff8ba4d3824d 100644 --- a/arch/powerpc/kernel/optprobes_head.S +++ b/arch/powerpc/kernel/optprobes_head.S @@ -94,6 +94,9 @@ optprobe_template_insn: /* 2, Pass instruction to be emulated in r4 */ nop nop + nop + nop + nop .global optprobe_template_call_emulate optprobe_template_call_emulate: diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index ad451205f268..3b8655f57b4a 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -42,9 +42,24 @@ static unsigned long ftrace_tramps[NUM_FTRACE_TRAMPS]; static long -read_inst(ppc_inst *inst, const void *src) +read_inst(ppc_inst *p, const void *src) { - return probe_kernel_read((void *)inst, src, MCOUNT_INSN_SIZE); + ppc_inst inst; + long err; + + err = probe_kernel_read((void *)&inst.prefix, + src, MCOUNT_INSN_SIZE); + if (err) + return err; + + if (ppc_inst_prefixed(inst)) + err = probe_kernel_read((void *)&inst.suffix, + src + 4, MCOUNT_INSN_SIZE); + if (err) + return err; + + ppc_inst_write(p, inst); + return 0; } static ppc_inst diff --git a/arch/powerpc/kernel/uprobes.c b/arch/powerpc/kernel/uprobes.c index d1dff1dc3a11..3e4fbb5c1b1e 100644 --- a/arch/powerpc/kernel/uprobes.c +++ b/arch/powerpc/kernel/uprobes.c @@ -111,7 +111,7 @@ int arch_uprobe_post_xol(struct arch_uprobe *auprobe, struct pt_regs *regs) * support doesn't exist and have to fix-up the next instruction * to be executed. */ - regs->nip = utask->vaddr + MAX_UINSN_BYTES; + regs->nip = utask->vaddr + ppc_inst_len(ppc_inst_read(auprobe->insn)); user_disable_single_step(current); return 0; diff --git a/arch/powerpc/lib/code-patching.c b/arch/powerpc/lib/code-patching.c index fa7f32adf029..3b8277a64b8f 100644 --- a/arch/powerpc/lib/code-patching.c +++ b/arch/powerpc/lib/code-patching.c @@ -24,17 +24,27 @@ static int __patch_instruction(ppc_inst *exec_addr, ppc_inst instr, { int err = 0; - __put_user_asm(instr, patch_addr, err, "stw"); + __put_user_asm(ppc_inst_word(instr), patch_addr, err, "stw"); if (err) return err; asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr), "r" (exec_addr)); + if (!ppc_inst_prefixed(instr)) + return 0; + + __put_user_asm(ppc_inst_suffix(instr), patch_addr + 4, err, "stw"); + if (err) + return err; + + asm ("dcbst 0, %0; sync; icbi 0,%1; sync; isync" :: "r" (patch_addr + 4), + "r" (exec_addr + 4)); + return 0; } -int raw_patch_instruction(ppc_inst *addr, ppc_inst instr) +int raw_patch_instruction(void *addr, ppc_inst instr) { return __patch_instruction(addr, instr, addr); } @@ -184,7 +194,7 @@ static int do_patch_instruction(ppc_inst *addr, ppc_inst instr) #endif /* CONFIG_STRICT_KERNEL_RWX */ -int patch_instruction(unsigned int *addr, unsigned int instr) +int patch_instruction(void *addr, ppc_inst instr) { /* Make sure we aren't patching a freed init section */ if (init_mem_is_free && init_section_contains(addr, 4)) { @@ -195,7 +205,7 @@ int patch_instruction(unsigned int *addr, unsigned int instr) } NOKPROBE_SYMBOL(patch_instruction); -int patch_branch(ppc_inst *addr, unsigned long target, int flags) +int patch_branch(void *addr, unsigned long target, int flags) { return patch_instruction(addr, create_branch(addr, target, flags)); } @@ -264,7 +274,7 @@ ppc_inst create_branch(const ppc_inst *addr, return instruction; } -unsigned int create_cond_branch(const unsigned int *addr, +ppc_inst create_cond_branch(const void *addr, unsigned long target, int flags) { ppc_inst instruction; @@ -344,7 +354,7 @@ static unsigned long branch_bform_target(const ppc_inst *instr) return (unsigned long)imm; } -unsigned long branch_target(const ppc_inst *instr) +unsigned long branch_target(const void *instr) { if (instr_is_branch_iform(ppc_inst_read(instr))) return branch_iform_target(instr); diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index bae878a83fa5..ab4c71c43c8c 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -1169,10 +1169,12 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, unsigned long int imm; unsigned long int val, val2; unsigned int mb, me, sh; - unsigned int word; + unsigned int word, suffix; long ival; word = ppc_inst_word(instr); + suffix = ppc_inst_suffix(instr); + op->type = COMPUTE; opcode = word >> 26; diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index ee084411f2f5..c5536e1a3356 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -110,7 +110,7 @@ struct bpt { #define BP_DABR 4 #define NBPTS 256 -#define BPT_WORDS 2 +#define BPT_WORDS 4 static struct bpt bpts[NBPTS]; static struct bpt dabr; static struct bpt *iabr; @@ -118,12 +118,13 @@ static unsigned bpinstr = 0x7fe00008; /* trap */ #define BP_NUM(bp) ((bp) - bpts + 1) -static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS]; +static unsigned int __section(.text.xmon_bpts) bpt_table[NBPTS * BPT_WORDS] __aligned(64); /* Prototypes */ static int cmds(struct pt_regs *); static int mread(unsigned long, void *, int); static int mwrite(unsigned long, void *, int); +static int mread_instr(unsigned long, ppc_inst *); static int handle_fault(struct pt_regs *); static void byterev(unsigned char *, int); static void memex(void); @@ -759,8 +760,8 @@ static int xmon_bpt(struct pt_regs *regs) /* Are we at the trap at bp->instr[1] for some bp? */ bp = in_breakpoint_table(regs->nip, &offset); - if (bp != NULL && offset == 4) { - regs->nip = bp->address + 4; + if (bp != NULL && (offset == 4 || offset == 8)) { + regs->nip = bp->address + offset; atomic_dec(&bp->ref_count); return 1; } @@ -862,7 +863,7 @@ static struct bpt *in_breakpoint_table(unsigned long nip, unsigned long *offp) if (off >= sizeof(bpt_table)) return NULL; bp_off = off % (sizeof(unsigned int) * BPT_WORDS); - if (bp_off != 0 && bp_off != 4) + if (bp_off != 0 && bp_off != 4 && bp_off != 8) return NULL; *offp = bp_off; return bpts + ((off - bp_off) / (sizeof(unsigned int) * BPT_WORDS)); @@ -881,7 +882,6 @@ static struct bpt *new_breakpoint(unsigned long a) if (!bp->enabled && atomic_read(&bp->ref_count) == 0) { bp->address = a; bp->instr = bpt_table + ((bp - bpts) * BPT_WORDS); - patch_instruction(bp->instr + 1, PPC_INST(bpinstr)); return bp; } } @@ -900,7 +900,7 @@ static void insert_bpts(void) for (i = 0; i < NBPTS; ++i, ++bp) { if ((bp->enabled & (BP_TRAP|BP_CIABR)) == 0) continue; - if (mread(bp->address, &instr, 4) != 4) { + if (!mread_instr(bp->address, &instr)) { printf("Couldn't read instruction at %lx, " "disabling breakpoint there\n", bp->address); bp->enabled = 0; @@ -913,9 +913,10 @@ static void insert_bpts(void) continue; } patch_instruction(bp->instr, instr); + patch_instruction(bp->instr + ppc_inst_len(instr), PPC_INST(bpinstr)); if (bp->enabled & BP_CIABR) continue; - if (patch_instruction((ppc_inst *)bp->address, + if (patch_instruction((void *)bp->address, PPC_INST(bpinstr)) != 0) { printf("Couldn't write instruction at %lx, " "disabling breakpoint there\n", bp->address); @@ -950,7 +951,7 @@ static void remove_bpts(void) for (i = 0; i < NBPTS; ++i, ++bp) { if ((bp->enabled & (BP_TRAP|BP_CIABR)) != BP_TRAP) continue; - if (mread(bp->address, &instr, 4) == 4 + if (mread_instr(bp->address, &instr) && ppc_inst_equal(instr, PPC_INST(bpinstr)) && patch_instruction( (ppc_inst *)bp->address, ppc_inst_read(bp->instr)) != 0) @@ -1166,7 +1167,7 @@ static int do_step(struct pt_regs *regs) force_enable_xmon(); /* check we are in 64-bit kernel mode, translation enabled */ if ((regs->msr & (MSR_64BIT|MSR_PR|MSR_IR)) == (MSR_64BIT|MSR_IR)) { - if (mread(regs->nip, &instr, 4) == 4) { + if (mread_instr(regs->nip, &instr)) { stepped = emulate_step(regs, instr); if (stepped < 0) { printf("Couldn't single-step %s instruction\n", @@ -1333,7 +1334,7 @@ static long check_bp_loc(unsigned long addr) printf("Breakpoints may only be placed at kernel addresses\n"); return 0; } - if (!mread(addr, &instr, sizeof(instr))) { + if (!mread_instr(addr, &instr)) { printf("Can't read instruction at address %lx\n", addr); return 0; } @@ -2126,6 +2127,21 @@ mwrite(unsigned long adrs, void *buf, int size) return n; } +static int +mread_instr(unsigned long adrs, ppc_inst *instr) +{ + if (setjmp(bus_error_jmp) == 0) { + catch_memory_errors = 1; + sync(); + *instr = ppc_inst_read((void *)adrs); + sync(); + /* wait a little while to see if we get a machine check */ + __delay(200); + } + catch_memory_errors = 0; + return ppc_inst_len(*instr); +} + static int fault_type; static int fault_except; static char *fault_chars[] = { "--", "**", "##" }; From patchwork Fri Mar 20 05:18:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258653 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kCT05bKTz9sRf for ; Fri, 20 Mar 2020 16:46:44 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Z766tROY; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kCT05Hb2zDsRY for ; Fri, 20 Mar 2020 16:46:44 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::1042; helo=mail-pj1-x1042.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=Z766tROY; dkim-atps=neutral Received: from mail-pj1-x1042.google.com (mail-pj1-x1042.google.com [IPv6:2607:f8b0:4864:20::1042]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBsy4hgRzDrTQ for ; Fri, 20 Mar 2020 16:19:50 +1100 (AEDT) Received: by mail-pj1-x1042.google.com with SMTP id m15so1972279pje.3 for ; Thu, 19 Mar 2020 22:19:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=Fj7OIHh+P/mMO3kNKWMPWKCkhlppM+3F2mvflwmTM6g=; b=Z766tROYX1xCgO67ay0nBl36bZuTHSIp9KDsIgg4LXvj0W+IWWHOnjrQ8tdMDWnPRT THcKKmxZBetmaDMUt7GrHXFGrlzupGjWmgFnTFjBgMH4uWIh5B5csVqElMksJlfAFfjF O2Fy/wuHw5GijH+1rKRrcPGVhxrq+I2Z4QcvwH/CxZiZhK2scEiTIDW6Vy1cKM3QQz1i +BIkFmVtdOgmvIb5v8imbHiRNGBudpWhVe18UH91XoBbp3mNJNqBksPLx61+mv4uDSfV pylO/vZApxzPh5U7d7gDH5/GBhL9nt+HMkXgZ4PygwsP53BCnxKdcPNMCnWX9zohmQrH jaAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Fj7OIHh+P/mMO3kNKWMPWKCkhlppM+3F2mvflwmTM6g=; b=uEXxBTOa82DBjDRjKuZaLL0lHCI1j5IHsRbEWsDPxcNWzz5ObF3YnZhWE3G6tHovFk WMkRDJr5GUyqiQoDwfYtFU0/DcmVC3TqGNVaDgz8HayCEu6UA6BGdnkeeIwfQh5xFvz9 m9jjXkwxPxnhE/d1sDQgac5ThlCLrkpqF/YlkTw6esh6VBTqvGkCF0q3lQc9KJEwtXQ4 yhLvBCo1oIbC/6sMXiat95/mceBMExVVVcKPZo2OO8ZMvJ3Fu1YArwK1c0ffEKL24ZAX 7EVwBRbGh0oORjDRbVB23JdGbX/kd3FobPLos5pea4FYKbmwxYG4sxUn8kLBkjyyiQxu hC8g== X-Gm-Message-State: ANhLgQ2RffXk1AbAwLUsGthkOdOmtkiA7uFRU97de3Ai/HRxbKIhr1nR i0zgcGxbWAO1vrAJAVrxCpXhthDzHpI= X-Google-Smtp-Source: ADFU+vu0xWtUYcreYFj6FtuvEVyHSx5gk3piDa8qjR2pSq3eYKVqtYUsa7OWSyaZpZxMsGh30vZTpg== X-Received: by 2002:a17:90a:1697:: with SMTP id o23mr7531059pja.62.1584681587317; Thu, 19 Mar 2020 22:19:47 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:46 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 15/16] powerpc sstep: Add support for prefixed load/stores Date: Fri, 20 Mar 2020 16:18:08 +1100 Message-Id: <20200320051809.24332-16-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" This adds emulation support for the following prefixed integer load/stores: * Prefixed Load Byte and Zero (plbz) * Prefixed Load Halfword and Zero (plhz) * Prefixed Load Halfword Algebraic (plha) * Prefixed Load Word and Zero (plwz) * Prefixed Load Word Algebraic (plwa) * Prefixed Load Doubleword (pld) * Prefixed Store Byte (pstb) * Prefixed Store Halfword (psth) * Prefixed Store Word (pstw) * Prefixed Store Doubleword (pstd) * Prefixed Load Quadword (plq) * Prefixed Store Quadword (pstq) the follow prefixed floating-point load/stores: * Prefixed Load Floating-Point Single (plfs) * Prefixed Load Floating-Point Double (plfd) * Prefixed Store Floating-Point Single (pstfs) * Prefixed Store Floating-Point Double (pstfd) and for the following prefixed VSX load/stores: * Prefixed Load VSX Scalar Doubleword (plxsd) * Prefixed Load VSX Scalar Single-Precision (plxssp) * Prefixed Load VSX Vector [0|1] (plxv, plxv0, plxv1) * Prefixed Store VSX Scalar Doubleword (pstxsd) * Prefixed Store VSX Scalar Single-Precision (pstxssp) * Prefixed Store VSX Vector [0|1] (pstxv, pstxv0, pstxv1) Signed-off-by: Jordan Niethe Reviewed-by: Balamuruhan S --- v2: - Combine all load/store patches - Fix the name of Type 01 instructions - Remove sign extension flag from pstd/pld - Rename sufx -> suffix v3: - Move prefixed loads and stores into the switch statement --- arch/powerpc/lib/sstep.c | 159 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index ab4c71c43c8c..daef70eb8e22 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -187,6 +187,44 @@ static nokprobe_inline unsigned long xform_ea(unsigned int instr, return ea; } +/* + * Calculate effective address for a MLS:D-form / 8LS:D-form + * prefixed instruction + */ +static nokprobe_inline unsigned long mlsd_8lsd_ea(unsigned int instr, + unsigned int suffix, + const struct pt_regs *regs) +{ + int ra, prefix_r; + unsigned int dd; + unsigned long ea, d0, d1, d; + + prefix_r = instr & (1ul << 20); + ra = (suffix >> 16) & 0x1f; + + d0 = instr & 0x3ffff; + d1 = suffix & 0xffff; + d = (d0 << 16) | d1; + + /* + * sign extend a 34 bit number + */ + dd = (unsigned int)(d >> 2); + ea = (signed int)dd; + ea = (ea << 2) | (d & 0x3); + + if (!prefix_r && ra) + ea += regs->gpr[ra]; + else if (!prefix_r && !ra) + ; /* Leave ea as is */ + else if (prefix_r && !ra) + ea += regs->nip; + else if (prefix_r && ra) + ; /* Invalid form. Should already be checked for by caller! */ + + return ea; +} + /* * Return the largest power of 2, not greater than sizeof(unsigned long), * such that x is a multiple of it. @@ -1166,6 +1204,7 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, ppc_inst instr) { unsigned int opcode, ra, rb, rc, rd, spr, u; + unsigned int suffixopcode, prefixtype, prefix_r; unsigned long int imm; unsigned long int val, val2; unsigned int mb, me, sh; @@ -2652,6 +2691,126 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, break; } break; + case 1: /* Prefixed instructions */ + prefix_r = word & (1ul << 20); + ra = (suffix >> 16) & 0x1f; + op->update_reg = ra; + rd = (suffix >> 21) & 0x1f; + op->reg = rd; + op->val = regs->gpr[rd]; + + suffixopcode = suffix >> 26; + prefixtype = (word >> 24) & 0x3; + switch (prefixtype) { + case 0: /* Type 00 Eight-Byte Load/Store */ + if (prefix_r && ra) + break; + op->ea = mlsd_8lsd_ea(word, suffix, regs); + switch (suffixopcode) { + case 41: /* plwa */ + op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 4); + break; + case 42: /* plxsd */ + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, PREFIXED, 8); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 43: /* plxssp */ + op->reg = rd + 32; + op->type = MKOP(LOAD_VSX, PREFIXED, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; + break; + case 46: /* pstxsd */ + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, PREFIXED, 8); + op->element_size = 8; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 47: /* pstxssp */ + op->reg = rd + 32; + op->type = MKOP(STORE_VSX, PREFIXED, 4); + op->element_size = 8; + op->vsx_flags = VSX_FPCONV | VSX_CHECK_VEC; + break; + case 51: /* plxv1 */ + op->reg += 32; + + /* fallthru */ + case 50: /* plxv0 */ + op->type = MKOP(LOAD_VSX, PREFIXED, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 55: /* pstxv1 */ + op->reg = rd + 32; + + /* fallthru */ + case 54: /* pstxv0 */ + op->type = MKOP(STORE_VSX, PREFIXED, 16); + op->element_size = 16; + op->vsx_flags = VSX_CHECK_VEC; + break; + case 56: /* plq */ + op->type = MKOP(LOAD, PREFIXED, 16); + break; + case 57: /* pld */ + op->type = MKOP(LOAD, PREFIXED, 8); + break; + case 60: /* stq */ + op->type = MKOP(STORE, PREFIXED, 16); + break; + case 61: /* pstd */ + op->type = MKOP(STORE, PREFIXED, 8); + break; + } + break; + case 1: /* Type 01 Eight-Byte Register-to-Register */ + break; + case 2: /* Type 10 Modified Load/Store */ + if (prefix_r && ra) + break; + op->ea = mlsd_8lsd_ea(word, suffix, regs); + switch (suffixopcode) { + case 32: /* plwz */ + op->type = MKOP(LOAD, PREFIXED, 4); + break; + case 34: /* plbz */ + op->type = MKOP(LOAD, PREFIXED, 1); + break; + case 36: /* pstw */ + op->type = MKOP(STORE, PREFIXED, 4); + break; + case 38: /* pstb */ + op->type = MKOP(STORE, PREFIXED, 1); + break; + case 40: /* plhz */ + op->type = MKOP(LOAD, PREFIXED, 2); + break; + case 42: /* plha */ + op->type = MKOP(LOAD, PREFIXED | SIGNEXT, 2); + break; + case 44: /* psth */ + op->type = MKOP(STORE, PREFIXED, 2); + break; + case 48: /* plfs */ + op->type = MKOP(LOAD_FP, PREFIXED | FPCONV, 4); + break; + case 50: /* plfd */ + op->type = MKOP(LOAD_FP, PREFIXED, 8); + break; + case 52: /* pstfs */ + op->type = MKOP(STORE_FP, PREFIXED | FPCONV, 4); + break; + case 54: /* pstfd */ + op->type = MKOP(STORE_FP, PREFIXED, 8); + break; + } + break; + case 3: /* Type 11 Modified Register-to-Register */ + break; + } #endif /* __powerpc64__ */ } From patchwork Fri Mar 20 05:18:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jordan Niethe X-Patchwork-Id: 1258654 Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 48kCVc03Ccz9sRN for ; Fri, 20 Mar 2020 16:48:08 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=OrGx5OjZ; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 48kCVb559szDsNg for ; Fri, 20 Mar 2020 16:48:07 +1100 (AEDT) X-Original-To: linuxppc-dev@lists.ozlabs.org Delivered-To: linuxppc-dev@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::442; helo=mail-pf1-x442.google.com; envelope-from=jniethe5@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=OrGx5OjZ; dkim-atps=neutral Received: from mail-pf1-x442.google.com (mail-pf1-x442.google.com [IPv6:2607:f8b0:4864:20::442]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 48kBt12WflzDrTs for ; Fri, 20 Mar 2020 16:19:53 +1100 (AEDT) Received: by mail-pf1-x442.google.com with SMTP id j10so2622206pfi.12 for ; Thu, 19 Mar 2020 22:19:53 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=lrodgxN9VD9fhpwpSQLxuM6sRha44sWyBbPlSRZN2LY=; b=OrGx5OjZ8wgSRmqBsg3WEpXBFfXY9h4Fin43QoTa4OAL/XtCslSn0RO/m1oPcH/346 Azgl4m6Znget46bOhEUkkHRXrIeXxFMKWw30qYo4R2370lrc+2z+DzPWQa3JRpEQfd93 m1OGpvI6f+tSQygAcj5H9ikNH9JO1DUCaMI9rBP1fwO0J6GaXv91WH12wmksNbat33jo nai1J3WHQvdEhjqUf1JSIO5kB1Fo2rmr08VggIlkxqtIYV7XWCF7AWH0RMZ4XPumpChW Qr+vF/3cUTJ7xEP/wLaoe4E0uSnHAWTnQIfS3AYo/BmEr99OzLW7n5g7ehuN9IeHlpxU Ppag== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=lrodgxN9VD9fhpwpSQLxuM6sRha44sWyBbPlSRZN2LY=; b=PhOaba3Bj/QKj/CpI1wZoljEAfKzrPz9mIWs7NdZBZcgrSQqaIZt4mKPb+nfUDqClv p8GcLB4xd3AqU5XX0S7liWHjW4sPxu20RXlDnCA68Ozld5Yponh/mzyQUV1803YgM206 03jguYE3es+OFg5th0y1FaqXpdqYChZj39dx9MLd462adtTS6xAbq8n9J3Vx0uwjP4Jf 0JNwnwtWmLTPcE6Fhz2i+S0reqMXUYyBIuvO0S6bpjgK5gNxj8JyKbiRnGcYYymzlSOk W7taZQOs0WnRYPltKYD0A2fz6sFl5LuXplg4d7rXKCL+0G5ZRH826FFWp1/YlbMKHjyk jM1w== X-Gm-Message-State: ANhLgQ1efxydK2BqUFgwmCQ0f3PeadNcLozUt1cFudvZil7Fm1bwGd78 vZ1hPG283BJMp3QazZgfTzprkCgz1+Q= X-Google-Smtp-Source: ADFU+vs1U3/svoLgtcADOXbJSCMX4tLbHSFdC6UoXC+raiH7XkiI1MfLsprvHnr5hvznDTaWqxN/3g== X-Received: by 2002:a63:82c6:: with SMTP id w189mr6730172pgd.357.1584681591350; Thu, 19 Mar 2020 22:19:51 -0700 (PDT) Received: from localhost.localdomain (180-150-65-4.b49641.syd.nbn.aussiebb.net. [180.150.65.4]) by smtp.gmail.com with ESMTPSA id c207sm3988716pfb.47.2020.03.19.22.19.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 Mar 2020 22:19:50 -0700 (PDT) From: Jordan Niethe To: linuxppc-dev@lists.ozlabs.org Subject: [PATCH v4 16/16] powerpc sstep: Add support for prefixed fixed-point arithmetic Date: Fri, 20 Mar 2020 16:18:09 +1100 Message-Id: <20200320051809.24332-17-jniethe5@gmail.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20200320051809.24332-1-jniethe5@gmail.com> References: <20200320051809.24332-1-jniethe5@gmail.com> X-BeenThere: linuxppc-dev@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux on PowerPC Developers Mail List List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: alistair@popple.id.au, npiggin@gmail.com, bala24@linux.ibm.com, Jordan Niethe , dja@axtens.net Errors-To: linuxppc-dev-bounces+patchwork-incoming=ozlabs.org@lists.ozlabs.org Sender: "Linuxppc-dev" This adds emulation support for the following prefixed Fixed-Point Arithmetic instructions: * Prefixed Add Immediate (paddi) Signed-off-by: Jordan Niethe Reviewed-by: Balamuruhan S --- v3: Since we moved the prefixed loads/stores into the load/store switch statement it no longer makes sense to have paddi in there, so move it out. --- arch/powerpc/lib/sstep.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c index daef70eb8e22..6862fc019258 100644 --- a/arch/powerpc/lib/sstep.c +++ b/arch/powerpc/lib/sstep.c @@ -1335,6 +1335,26 @@ int analyse_instr(struct instruction_op *op, const struct pt_regs *regs, switch (opcode) { #ifdef __powerpc64__ + case 1: + prefix_r = word & (1ul << 20); + ra = (suffix >> 16) & 0x1f; + rd = (suffix >> 21) & 0x1f; + op->reg = rd; + op->val = regs->gpr[rd]; + suffixopcode = suffix >> 26; + prefixtype = (word >> 24) & 0x3; + switch (prefixtype) { + case 2: + if (prefix_r && ra) + return 0; + switch (suffixopcode) { + case 14: /* paddi */ + op->type = COMPUTE | PREFIXED; + op->val = mlsd_8lsd_ea(word, suffix, regs); + goto compute_done; + } + } + break; case 2: /* tdi */ if (rd & trap_compare(regs->gpr[ra], (short) word)) goto trap;