From patchwork Mon Apr 20 20:19:43 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Long X-Patchwork-Id: 6244201 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id 9E11B9F313 for ; Mon, 20 Apr 2015 20:23:10 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id 9E0CD20361 for ; Mon, 20 Apr 2015 20:23:09 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B2ADD20172 for ; Mon, 20 Apr 2015 20:23:08 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1YkIBP-0007vz-Cd; Mon, 20 Apr 2015 20:20:43 +0000 Received: from mail-qc0-f182.google.com ([209.85.216.182]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YkIAy-0006dt-MI for linux-arm-kernel@lists.infradead.org; Mon, 20 Apr 2015 20:20:18 +0000 Received: by qcrf4 with SMTP id f4so65017683qcr.0 for ; Mon, 20 Apr 2015 13:19:52 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=Ssp7R5m24jToA+OWMSCqkb+CBm6QxNQDHMcMdM4CjQ0=; b=HYUCY+4/f0fUY+bH1x1Sw9NmG+kPPMKU+RsEuZkljk3MZ/e9ggPyee0UV5k8OBS5np UcbbTcy8a+2+gRnU6V53sPkfEiC2BQj9U5AGeNplpBt2xesXqsO97x3/3kr5SYYGpvss X4nV8AFBROEYoWwYUW6WZGfsFr0NO0hZKBG17tYIt87U5VQxbs4PWQmighnkrrjeRoz6 RYxe1CRaw8Dyn0oJ2oCAvdhVjda4lBsjANQS4orncbV843ISwxJDGgY+0HWMqhdy0VgS qq2/RA00AsBoU0fEfNQB34N9JHds8rSv1Mpw/fJjHKORb6N2JSlFWkF/VMyUL3QbNjTl l3/g== X-Gm-Message-State: ALoCoQkzuea4YGzvWV/S3N2NW2VTiyoylU6XMTXDFXo1lO55H1MNs/jTZCnQpqEKd5ijYQiHNpZ4 X-Received: by 10.55.20.139 with SMTP id 11mr31180340qku.28.1429561192895; Mon, 20 Apr 2015 13:19:52 -0700 (PDT) Received: from localhost.localdomain (pool-72-71-243-249.cncdnh.fast00.myfairpoint.net. [72.71.243.249]) by mx.google.com with ESMTPSA id 77sm15240386qhf.44.2015.04.20.13.19.51 (version=TLSv1.1 cipher=ECDHE-RSA-RC4-SHA bits=128/128); Mon, 20 Apr 2015 13:19:52 -0700 (PDT) From: David Long To: linux-arm-kernel@lists.infradead.org, Russell King Subject: [PATCH v6 2/6] arm64: Add more test functions to insn.c Date: Mon, 20 Apr 2015 16:19:43 -0400 Message-Id: <1429561187-3661-3-git-send-email-dave.long@linaro.org> X-Mailer: git-send-email 1.8.1.2 In-Reply-To: <1429561187-3661-1-git-send-email-dave.long@linaro.org> References: <1429561187-3661-1-git-send-email-dave.long@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20150420_132016_898326_D8903780 X-CRM114-Status: GOOD ( 10.45 ) X-Spam-Score: -0.7 (/) Cc: "Jon Medhurst \(Tixy\)" , Steve Capper , Ananth N Mavinakayanahalli , Catalin Marinas , Will Deacon , linux-kernel@vger.kernel.org, Anil S Keshavamurthy , Masami Hiramatsu , sandeepa.s.prabhu@gmail.com, William Cohen , davem@davemloft.net X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.18-1 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP From: "David A. Long" Certain instructions are hard to execute correctly out-of-line (as in kprobes). Test functions are added to insn.[hc] to identify these. The instructions include any that use PC-relative addressing, change the PC, or change interrupt masking. For efficiency and simplicity test functions are also added for small collections of related instructions. Signed-off-by: David A. Long --- arch/arm64/include/asm/insn.h | 18 ++++++++++++++++++ arch/arm64/kernel/insn.c | 28 ++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/arch/arm64/include/asm/insn.h b/arch/arm64/include/asm/insn.h index d2f4942..0626404 100644 --- a/arch/arm64/include/asm/insn.h +++ b/arch/arm64/include/asm/insn.h @@ -223,8 +223,13 @@ static __always_inline bool aarch64_insn_is_##abbr(u32 code) \ static __always_inline u32 aarch64_insn_get_##abbr##_value(void) \ { return (val); } +__AARCH64_INSN_FUNCS(adr_adrp, 0x1F000000, 0x10000000) +__AARCH64_INSN_FUNCS(prfm_lit, 0xFF000000, 0xD8000000) __AARCH64_INSN_FUNCS(str_reg, 0x3FE0EC00, 0x38206800) __AARCH64_INSN_FUNCS(ldr_reg, 0x3FE0EC00, 0x38606800) +__AARCH64_INSN_FUNCS(ldr_lit, 0xBF000000, 0x18000000) +__AARCH64_INSN_FUNCS(ldrsw_lit, 0xFF000000, 0x98000000) +__AARCH64_INSN_FUNCS(exclusive, 0x3F000000, 0x08000000) __AARCH64_INSN_FUNCS(stp_post, 0x7FC00000, 0x28800000) __AARCH64_INSN_FUNCS(ldp_post, 0x7FC00000, 0x28C00000) __AARCH64_INSN_FUNCS(stp_pre, 0x7FC00000, 0x29800000) @@ -264,19 +269,29 @@ __AARCH64_INSN_FUNCS(ands, 0x7F200000, 0x6A000000) __AARCH64_INSN_FUNCS(bics, 0x7F200000, 0x6A200000) __AARCH64_INSN_FUNCS(b, 0xFC000000, 0x14000000) __AARCH64_INSN_FUNCS(bl, 0xFC000000, 0x94000000) +__AARCH64_INSN_FUNCS(b_bl, 0x7C000000, 0x14000000) +__AARCH64_INSN_FUNCS(cb, 0x7E000000, 0x34000000) __AARCH64_INSN_FUNCS(cbz, 0x7F000000, 0x34000000) __AARCH64_INSN_FUNCS(cbnz, 0x7F000000, 0x35000000) +__AARCH64_INSN_FUNCS(tb, 0x7E000000, 0x36000000) __AARCH64_INSN_FUNCS(tbz, 0x7F000000, 0x36000000) __AARCH64_INSN_FUNCS(tbnz, 0x7F000000, 0x37000000) +__AARCH64_INSN_FUNCS(b_bl_cb_tb, 0x5C000000, 0x14000000) __AARCH64_INSN_FUNCS(bcond, 0xFF000010, 0x54000000) __AARCH64_INSN_FUNCS(svc, 0xFFE0001F, 0xD4000001) __AARCH64_INSN_FUNCS(hvc, 0xFFE0001F, 0xD4000002) __AARCH64_INSN_FUNCS(smc, 0xFFE0001F, 0xD4000003) __AARCH64_INSN_FUNCS(brk, 0xFFE0001F, 0xD4200000) +__AARCH64_INSN_FUNCS(exception, 0xFF000000, 0xD4000000) __AARCH64_INSN_FUNCS(hint, 0xFFFFF01F, 0xD503201F) __AARCH64_INSN_FUNCS(br, 0xFFFFFC1F, 0xD61F0000) __AARCH64_INSN_FUNCS(blr, 0xFFFFFC1F, 0xD63F0000) +__AARCH64_INSN_FUNCS(br_blr, 0xFFDFFC1F, 0xD61F0000) __AARCH64_INSN_FUNCS(ret, 0xFFFFFC1F, 0xD65F0000) +__AARCH64_INSN_FUNCS(msr_imm, 0xFFF8F000, 0xD5004000) +__AARCH64_INSN_FUNCS(msr_reg, 0xFFF00000, 0xD5100000) +__AARCH64_INSN_FUNCS(set_clr_daif, 0xFFFFF0DF, 0xD50340DF) +__AARCH64_INSN_FUNCS(rd_wr_daif, 0xFFDFFFE0, 0xD51B4220) #undef __AARCH64_INSN_FUNCS @@ -285,6 +300,9 @@ bool aarch64_insn_is_nop(u32 insn); int aarch64_insn_read(void *addr, u32 *insnp); int aarch64_insn_write(void *addr, u32 insn); enum aarch64_insn_encoding_class aarch64_get_insn_class(u32 insn); +bool aarch64_insn_uses_literal(u32 insn); +bool aarch64_insn_is_branch(u32 insn); +bool aarch64_insn_is_daif_access(u32 insn); u32 aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type, u32 insn, u64 imm); u32 aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr, diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c index c8eca88..cda1b3b 100644 --- a/arch/arm64/kernel/insn.c +++ b/arch/arm64/kernel/insn.c @@ -155,6 +155,34 @@ static bool __kprobes __aarch64_insn_hotpatch_safe(u32 insn) aarch64_insn_is_nop(insn); } +bool __kprobes aarch64_insn_uses_literal(u32 insn) +{ + /* ldr/ldrsw (literal), prfm */ + + return aarch64_insn_is_ldr_lit(insn) || + aarch64_insn_is_ldrsw_lit(insn) || + aarch64_insn_is_adr_adrp(insn) || + aarch64_insn_is_prfm_lit(insn); +} + +bool __kprobes aarch64_insn_is_branch(u32 insn) +{ + /* b, bl, cb*, tb*, b.cond, br, blr */ + + return aarch64_insn_is_b_bl_cb_tb(insn) || + aarch64_insn_is_br_blr(insn) || + aarch64_insn_is_ret(insn) || + aarch64_insn_is_bcond(insn); +} + +bool __kprobes aarch64_insn_is_daif_access(u32 insn) +{ + /* msr daif, mrs daif, msr daifset, msr daifclr */ + + return aarch64_insn_is_rd_wr_daif(insn) || + aarch64_insn_is_set_clr_daif(insn); +} + /* * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a * Section B2.6.5 "Concurrent modification and execution of instructions":