From patchwork Thu Aug 25 13:37:25 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konrad Rzeszutek Wilk X-Patchwork-Id: 9299373 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id A853B60459 for ; Thu, 25 Aug 2016 13:40:27 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 99F8F29332 for ; Thu, 25 Aug 2016 13:40:27 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 8EC3529334; Thu, 25 Aug 2016 13:40:27 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=2.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 174A529338 for ; Thu, 25 Aug 2016 13:40:27 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bcur8-0000w6-N3; Thu, 25 Aug 2016 13:38:06 +0000 Received: from mail6.bemta5.messagelabs.com ([195.245.231.135]) by lists.xenproject.org with esmtp (Exim 4.84_2) (envelope-from ) id 1bcur6-0000uQ-I0 for xen-devel@lists.xenproject.org; Thu, 25 Aug 2016 13:38:04 +0000 Received: from [85.158.139.211] by server-3.bemta-5.messagelabs.com id 8C/19-01957-BB4FEB75; Thu, 25 Aug 2016 13:38:03 +0000 X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFvrFLMWRWlGSWpSXmKPExsUyZ7p8oO7uL/v CDeb94bT4vmUykwOjx+EPV1gCGKNYM/OS8isSWDOmzv7HUjBXpeLQl8IGxh75LkYuDiGByUwS 0+5fZIdw/jJKrLt2namLkRPI2cgo0X8iGSIxjVHi36NLjF2MHBxsAiYSb1Y5gsRFBPoYJQ4f3 cQM0sAsYCQxufEdC4gtLJAicenzHlYQm0VAVeLixF6wGl4Bd4m5He3sIHMkBOQlnt2uBwlzAo V/N2xmg9jrJvH9UgfYGAkBY4n2txfZJjDyLWBkWMWoUZxaVJZapGtoqZdUlJmeUZKbmJmja2h gqpebWlycmJ6ak5hUrJecn7uJERgm9QwMjDsYH/X7HWKU5GBSEuXVXrEvXIgvKT+lMiOxOCO+ qDQntfgQowwHh5IE75TPQDnBotT01Iq0zBxgwMKkJTh4lER414GkeYsLEnOLM9MhUqcYFaXEe atAEgIgiYzSPLg2WJRcYpSVEuZlZGBgEOIpSC3KzSxBlX/FKM7BqCTMWw0yhSczrwRu+iugxU xAi1vu7wZZXJKIkJJqYLSeUqft0fJRSLjQdtsiK3u+IxvFVxTxrn/qVLErelGGxdS8+7ZfNu3 TPiB9Yo5dsVDq89eF4fe+fe/k3u7oxfvk+xzOeZXGEz3WrPx0du2GSeoWf/prDKOd5EXDbjt4 6NveF/p5KPefyTwp9Sm8jiJ+NpabTzGe6/7Jup53HdvXnoJrKlPK4pVYijMSDbWYi4oTAYA7+ deNAgAA X-Env-Sender: konrad.wilk@oracle.com X-Msg-Ref: server-9.tower-206.messagelabs.com!1472132281!56339448!1 X-Originating-IP: [156.151.31.81] X-SpamReason: No, hits=0.0 required=7.0 tests=sa_preprocessor: VHJ1c3RlZCBJUDogMTU2LjE1MS4zMS44MSA9PiAyODgzMzk=\n X-StarScan-Received: X-StarScan-Version: 8.84; banners=-,-,- X-VirusChecked: Checked Received: (qmail 64329 invoked from network); 25 Aug 2016 13:38:02 -0000 Received: from userp1040.oracle.com (HELO userp1040.oracle.com) (156.151.31.81) by server-9.tower-206.messagelabs.com with DHE-RSA-AES256-GCM-SHA384 encrypted SMTP; 25 Aug 2016 13:38:02 -0000 Received: from aserv0022.oracle.com (aserv0022.oracle.com [141.146.126.234]) by userp1040.oracle.com (Sentrion-MTA-4.3.2/Sentrion-MTA-4.3.2) with ESMTP id u7PDbriX030565 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 25 Aug 2016 13:37:53 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserv0022.oracle.com (8.14.4/8.14.4) with ESMTP id u7PDbreP009276 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Thu, 25 Aug 2016 13:37:53 GMT Received: from abhmp0017.oracle.com (abhmp0017.oracle.com [141.146.116.23]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id u7PDbqtf020711; Thu, 25 Aug 2016 13:37:52 GMT Received: from localhost.event.rightround.com (/75.98.193.200) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Thu, 25 Aug 2016 06:37:52 -0700 From: Konrad Rzeszutek Wilk To: xen-devel@lists.xenproject.org, konrad@kernel.org, ross.lagerwall@citrix.com, sstabellini@kernel.org, julien.grall@arm.com Date: Thu, 25 Aug 2016 09:37:25 -0400 Message-Id: <1472132255-23470-11-git-send-email-konrad.wilk@oracle.com> X-Mailer: git-send-email 2.4.11 In-Reply-To: <1472132255-23470-1-git-send-email-konrad.wilk@oracle.com> References: <1472132255-23470-1-git-send-email-konrad.wilk@oracle.com> X-Source-IP: aserv0022.oracle.com [141.146.126.234] Cc: Konrad Rzeszutek Wilk Subject: [Xen-devel] [PATCH v2 10/20] arm64/insn: introduce aarch64_insn_gen_{nop|branch_imm}() helper functions X-BeenThere: xen-devel@lists.xen.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: xen-devel-bounces@lists.xen.org Sender: "Xen-devel" X-Virus-Scanned: ClamAV using ClamSMTP This is copied from Linux 4.7, and the initial commit that put this in is 5c5bf25d4f7a950382f94fc120a5818197b48fe9 "arm64: introduce aarch64_insn_gen_{nop|branch_imm}() helper functions" This lays the groundwork for Livepatch to generate the trampoline to jump to the new replacement function. Also allows us to NOP the callsites. This lays the groundwork for Livepatch to generate the trampoline to jump to the new replacement function. And also to NOP insns. Signed-off-by: Konrad Rzeszutek Wilk Acked-by: Julien Grall --- Cc: Ross Lagerwall Cc: Stefano Stabellini Cc: Julien Grall RFC: First submission v1: The full copy of insn_gen_branch instead of just the code to make branch --- xen/arch/arm/arm64/insn.c | 61 ++++++++++++++++++++++++++++++++++++++++ xen/include/asm-arm/arm64/insn.h | 23 +++++++++++++++ 2 files changed, 84 insertions(+) diff --git a/xen/arch/arm/arm64/insn.c b/xen/arch/arm/arm64/insn.c index 12b4d96..c5f7e93 100644 --- a/xen/arch/arm/arm64/insn.c +++ b/xen/arch/arm/arm64/insn.c @@ -157,6 +157,67 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, return insn; } +static inline long branch_imm_common(unsigned long pc, unsigned long addr, + long range) +{ + long offset; + + if ((pc & 0x3) || (addr & 0x3)) { + pr_err("%s: A64 instructions must be word aligned\n", __func__); + return range; + } + + offset = ((long)addr - (long)pc); + + if (offset < -range || offset >= range) { + pr_err("%s: offset out of range\n", __func__); + return range; + } + + return offset; +} + +u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, + enum aarch64_insn_branch_type type) +{ + u32 insn; + long offset; + + /* + * B/BL support [-128M, 128M) offset + * ARM64 virtual address arrangement guarantees all kernel and module + * texts are within +/-128M. + */ + offset = branch_imm_common(pc, addr, SZ_128M); + if (offset >= SZ_128M) + return AARCH64_BREAK_FAULT; + + switch (type) { + case AARCH64_INSN_BRANCH_LINK: + insn = aarch64_insn_get_bl_value(); + break; + case AARCH64_INSN_BRANCH_NOLINK: + insn = aarch64_insn_get_b_value(); + break; + default: + pr_err("%s: unknown branch encoding %d\n", __func__, type); + return AARCH64_BREAK_FAULT; + } + + return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn, + offset >> 2); +} + +u32 __kprobes aarch64_insn_gen_hint(enum aarch64_insn_hint_op op) +{ + return aarch64_insn_get_hint_value() | op; +} + +u32 __kprobes aarch64_insn_gen_nop(void) +{ + return aarch64_insn_gen_hint(AARCH64_INSN_HINT_NOP); +} + /* * Decode the imm field of a branch, and return the byte offset as a * signed value (so it can be used when computing a new branch diff --git a/xen/include/asm-arm/arm64/insn.h b/xen/include/asm-arm/arm64/insn.h index 6ce37be..c8362e5 100644 --- a/xen/include/asm-arm/arm64/insn.h +++ b/xen/include/asm-arm/arm64/insn.h @@ -23,6 +23,15 @@ #include #include +enum aarch64_insn_hint_op { + AARCH64_INSN_HINT_NOP = 0x0 << 5, + AARCH64_INSN_HINT_YIELD = 0x1 << 5, + AARCH64_INSN_HINT_WFE = 0x2 << 5, + AARCH64_INSN_HINT_WFI = 0x3 << 5, + AARCH64_INSN_HINT_SEV = 0x4 << 5, + AARCH64_INSN_HINT_SEVL = 0x5 << 5, +}; + enum aarch64_insn_imm_type { AARCH64_INSN_IMM_ADR, AARCH64_INSN_IMM_26, @@ -38,6 +47,14 @@ enum aarch64_insn_imm_type { AARCH64_INSN_IMM_MAX }; +enum aarch64_insn_branch_type { + AARCH64_INSN_BRANCH_NOLINK, + AARCH64_INSN_BRANCH_LINK, + AARCH64_INSN_BRANCH_RETURN, + AARCH64_INSN_BRANCH_COMP_ZERO, + AARCH64_INSN_BRANCH_COMP_NONZERO, +}; + #define __AARCH64_INSN_FUNCS(abbr, mask, val) \ static always_inline bool_t aarch64_insn_is_##abbr(u32 code) \ { return (code & (mask)) == (val); } \ @@ -51,6 +68,7 @@ __AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000) __AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000) __AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000) __AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000) +__AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F) bool aarch64_insn_is_branch_imm(u32 insn); @@ -61,6 +79,11 @@ u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, s32 aarch64_get_branch_offset(u32 insn); u32 aarch64_set_branch_offset(u32 insn, s32 offset); +u32 aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, + enum aarch64_insn_branch_type type); +u32 aarch64_insn_gen_hint(enum aarch64_insn_hint_op op); +u32 aarch64_insn_gen_nop(void); + /* Wrapper for common code */ static inline bool insn_is_branch_imm(u32 insn) {