linux/arch/arm64/kernel/insn.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013 Huawei Ltd.
   3 * Author: Jiang Liu <liuj97@gmail.com>
   4 *
   5 * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
   6 *
   7 * This program is free software; you can redistribute it and/or modify
   8 * it under the terms of the GNU General Public License version 2 as
   9 * published by the Free Software Foundation.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
  18 */
  19#include <linux/bitops.h>
  20#include <linux/bug.h>
  21#include <linux/compiler.h>
  22#include <linux/kernel.h>
  23#include <linux/mm.h>
  24#include <linux/smp.h>
  25#include <linux/spinlock.h>
  26#include <linux/stop_machine.h>
  27#include <linux/types.h>
  28#include <linux/uaccess.h>
  29
  30#include <asm/cacheflush.h>
  31#include <asm/debug-monitors.h>
  32#include <asm/fixmap.h>
  33#include <asm/insn.h>
  34#include <asm/kprobes.h>
  35
  36#define AARCH64_INSN_SF_BIT     BIT(31)
  37#define AARCH64_INSN_N_BIT      BIT(22)
  38
  39static int aarch64_insn_encoding_class[] = {
  40        AARCH64_INSN_CLS_UNKNOWN,
  41        AARCH64_INSN_CLS_UNKNOWN,
  42        AARCH64_INSN_CLS_UNKNOWN,
  43        AARCH64_INSN_CLS_UNKNOWN,
  44        AARCH64_INSN_CLS_LDST,
  45        AARCH64_INSN_CLS_DP_REG,
  46        AARCH64_INSN_CLS_LDST,
  47        AARCH64_INSN_CLS_DP_FPSIMD,
  48        AARCH64_INSN_CLS_DP_IMM,
  49        AARCH64_INSN_CLS_DP_IMM,
  50        AARCH64_INSN_CLS_BR_SYS,
  51        AARCH64_INSN_CLS_BR_SYS,
  52        AARCH64_INSN_CLS_LDST,
  53        AARCH64_INSN_CLS_DP_REG,
  54        AARCH64_INSN_CLS_LDST,
  55        AARCH64_INSN_CLS_DP_FPSIMD,
  56};
  57
  58enum aarch64_insn_encoding_class __kprobes aarch64_get_insn_class(u32 insn)
  59{
  60        return aarch64_insn_encoding_class[(insn >> 25) & 0xf];
  61}
  62
  63/* NOP is an alias of HINT */
  64bool __kprobes aarch64_insn_is_nop(u32 insn)
  65{
  66        if (!aarch64_insn_is_hint(insn))
  67                return false;
  68
  69        switch (insn & 0xFE0) {
  70        case AARCH64_INSN_HINT_YIELD:
  71        case AARCH64_INSN_HINT_WFE:
  72        case AARCH64_INSN_HINT_WFI:
  73        case AARCH64_INSN_HINT_SEV:
  74        case AARCH64_INSN_HINT_SEVL:
  75                return false;
  76        default:
  77                return true;
  78        }
  79}
  80
  81bool aarch64_insn_is_branch_imm(u32 insn)
  82{
  83        return (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn) ||
  84                aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn) ||
  85                aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
  86                aarch64_insn_is_bcond(insn));
  87}
  88
  89static DEFINE_RAW_SPINLOCK(patch_lock);
  90
  91static void __kprobes *patch_map(void *addr, int fixmap)
  92{
  93        unsigned long uintaddr = (uintptr_t) addr;
  94        bool module = !core_kernel_text(uintaddr);
  95        struct page *page;
  96
  97        if (module && IS_ENABLED(CONFIG_STRICT_MODULE_RWX))
  98                page = vmalloc_to_page(addr);
  99        else if (!module)
 100                page = phys_to_page(__pa_symbol(addr));
 101        else
 102                return addr;
 103
 104        BUG_ON(!page);
 105        return (void *)set_fixmap_offset(fixmap, page_to_phys(page) +
 106                        (uintaddr & ~PAGE_MASK));
 107}
 108
 109static void __kprobes patch_unmap(int fixmap)
 110{
 111        clear_fixmap(fixmap);
 112}
 113/*
 114 * In ARMv8-A, A64 instructions have a fixed length of 32 bits and are always
 115 * little-endian.
 116 */
 117int __kprobes aarch64_insn_read(void *addr, u32 *insnp)
 118{
 119        int ret;
 120        __le32 val;
 121
 122        ret = probe_kernel_read(&val, addr, AARCH64_INSN_SIZE);
 123        if (!ret)
 124                *insnp = le32_to_cpu(val);
 125
 126        return ret;
 127}
 128
 129static int __kprobes __aarch64_insn_write(void *addr, __le32 insn)
 130{
 131        void *waddr = addr;
 132        unsigned long flags = 0;
 133        int ret;
 134
 135        raw_spin_lock_irqsave(&patch_lock, flags);
 136        waddr = patch_map(addr, FIX_TEXT_POKE0);
 137
 138        ret = probe_kernel_write(waddr, &insn, AARCH64_INSN_SIZE);
 139
 140        patch_unmap(FIX_TEXT_POKE0);
 141        raw_spin_unlock_irqrestore(&patch_lock, flags);
 142
 143        return ret;
 144}
 145
 146int __kprobes aarch64_insn_write(void *addr, u32 insn)
 147{
 148        return __aarch64_insn_write(addr, cpu_to_le32(insn));
 149}
 150
 151static bool __kprobes __aarch64_insn_hotpatch_safe(u32 insn)
 152{
 153        if (aarch64_get_insn_class(insn) != AARCH64_INSN_CLS_BR_SYS)
 154                return false;
 155
 156        return  aarch64_insn_is_b(insn) ||
 157                aarch64_insn_is_bl(insn) ||
 158                aarch64_insn_is_svc(insn) ||
 159                aarch64_insn_is_hvc(insn) ||
 160                aarch64_insn_is_smc(insn) ||
 161                aarch64_insn_is_brk(insn) ||
 162                aarch64_insn_is_nop(insn);
 163}
 164
 165bool __kprobes aarch64_insn_uses_literal(u32 insn)
 166{
 167        /* ldr/ldrsw (literal), prfm */
 168
 169        return aarch64_insn_is_ldr_lit(insn) ||
 170                aarch64_insn_is_ldrsw_lit(insn) ||
 171                aarch64_insn_is_adr_adrp(insn) ||
 172                aarch64_insn_is_prfm_lit(insn);
 173}
 174
 175bool __kprobes aarch64_insn_is_branch(u32 insn)
 176{
 177        /* b, bl, cb*, tb*, b.cond, br, blr */
 178
 179        return aarch64_insn_is_b(insn) ||
 180                aarch64_insn_is_bl(insn) ||
 181                aarch64_insn_is_cbz(insn) ||
 182                aarch64_insn_is_cbnz(insn) ||
 183                aarch64_insn_is_tbz(insn) ||
 184                aarch64_insn_is_tbnz(insn) ||
 185                aarch64_insn_is_ret(insn) ||
 186                aarch64_insn_is_br(insn) ||
 187                aarch64_insn_is_blr(insn) ||
 188                aarch64_insn_is_bcond(insn);
 189}
 190
 191/*
 192 * ARM Architecture Reference Manual for ARMv8 Profile-A, Issue A.a
 193 * Section B2.6.5 "Concurrent modification and execution of instructions":
 194 * Concurrent modification and execution of instructions can lead to the
 195 * resulting instruction performing any behavior that can be achieved by
 196 * executing any sequence of instructions that can be executed from the
 197 * same Exception level, except where the instruction before modification
 198 * and the instruction after modification is a B, BL, NOP, BKPT, SVC, HVC,
 199 * or SMC instruction.
 200 */
 201bool __kprobes aarch64_insn_hotpatch_safe(u32 old_insn, u32 new_insn)
 202{
 203        return __aarch64_insn_hotpatch_safe(old_insn) &&
 204               __aarch64_insn_hotpatch_safe(new_insn);
 205}
 206
 207int __kprobes aarch64_insn_patch_text_nosync(void *addr, u32 insn)
 208{
 209        u32 *tp = addr;
 210        int ret;
 211
 212        /* A64 instructions must be word aligned */
 213        if ((uintptr_t)tp & 0x3)
 214                return -EINVAL;
 215
 216        ret = aarch64_insn_write(tp, insn);
 217        if (ret == 0)
 218                flush_icache_range((uintptr_t)tp,
 219                                   (uintptr_t)tp + AARCH64_INSN_SIZE);
 220
 221        return ret;
 222}
 223
 224struct aarch64_insn_patch {
 225        void            **text_addrs;
 226        u32             *new_insns;
 227        int             insn_cnt;
 228        atomic_t        cpu_count;
 229};
 230
 231static int __kprobes aarch64_insn_patch_text_cb(void *arg)
 232{
 233        int i, ret = 0;
 234        struct aarch64_insn_patch *pp = arg;
 235
 236        /* The first CPU becomes master */
 237        if (atomic_inc_return(&pp->cpu_count) == 1) {
 238                for (i = 0; ret == 0 && i < pp->insn_cnt; i++)
 239                        ret = aarch64_insn_patch_text_nosync(pp->text_addrs[i],
 240                                                             pp->new_insns[i]);
 241                /*
 242                 * aarch64_insn_patch_text_nosync() calls flush_icache_range(),
 243                 * which ends with "dsb; isb" pair guaranteeing global
 244                 * visibility.
 245                 */
 246                /* Notify other processors with an additional increment. */
 247                atomic_inc(&pp->cpu_count);
 248        } else {
 249                while (atomic_read(&pp->cpu_count) <= num_online_cpus())
 250                        cpu_relax();
 251                isb();
 252        }
 253
 254        return ret;
 255}
 256
 257static
 258int __kprobes aarch64_insn_patch_text_sync(void *addrs[], u32 insns[], int cnt)
 259{
 260        struct aarch64_insn_patch patch = {
 261                .text_addrs = addrs,
 262                .new_insns = insns,
 263                .insn_cnt = cnt,
 264                .cpu_count = ATOMIC_INIT(0),
 265        };
 266
 267        if (cnt <= 0)
 268                return -EINVAL;
 269
 270        return stop_machine_cpuslocked(aarch64_insn_patch_text_cb, &patch,
 271                                       cpu_online_mask);
 272}
 273
 274int __kprobes aarch64_insn_patch_text(void *addrs[], u32 insns[], int cnt)
 275{
 276        int ret;
 277        u32 insn;
 278
 279        /* Unsafe to patch multiple instructions without synchronizaiton */
 280        if (cnt == 1) {
 281                ret = aarch64_insn_read(addrs[0], &insn);
 282                if (ret)
 283                        return ret;
 284
 285                if (aarch64_insn_hotpatch_safe(insn, insns[0])) {
 286                        /*
 287                         * ARMv8 architecture doesn't guarantee all CPUs see
 288                         * the new instruction after returning from function
 289                         * aarch64_insn_patch_text_nosync(). So send IPIs to
 290                         * all other CPUs to achieve instruction
 291                         * synchronization.
 292                         */
 293                        ret = aarch64_insn_patch_text_nosync(addrs[0], insns[0]);
 294                        kick_all_cpus_sync();
 295                        return ret;
 296                }
 297        }
 298
 299        return aarch64_insn_patch_text_sync(addrs, insns, cnt);
 300}
 301
 302static int __kprobes aarch64_get_imm_shift_mask(enum aarch64_insn_imm_type type,
 303                                                u32 *maskp, int *shiftp)
 304{
 305        u32 mask;
 306        int shift;
 307
 308        switch (type) {
 309        case AARCH64_INSN_IMM_26:
 310                mask = BIT(26) - 1;
 311                shift = 0;
 312                break;
 313        case AARCH64_INSN_IMM_19:
 314                mask = BIT(19) - 1;
 315                shift = 5;
 316                break;
 317        case AARCH64_INSN_IMM_16:
 318                mask = BIT(16) - 1;
 319                shift = 5;
 320                break;
 321        case AARCH64_INSN_IMM_14:
 322                mask = BIT(14) - 1;
 323                shift = 5;
 324                break;
 325        case AARCH64_INSN_IMM_12:
 326                mask = BIT(12) - 1;
 327                shift = 10;
 328                break;
 329        case AARCH64_INSN_IMM_9:
 330                mask = BIT(9) - 1;
 331                shift = 12;
 332                break;
 333        case AARCH64_INSN_IMM_7:
 334                mask = BIT(7) - 1;
 335                shift = 15;
 336                break;
 337        case AARCH64_INSN_IMM_6:
 338        case AARCH64_INSN_IMM_S:
 339                mask = BIT(6) - 1;
 340                shift = 10;
 341                break;
 342        case AARCH64_INSN_IMM_R:
 343                mask = BIT(6) - 1;
 344                shift = 16;
 345                break;
 346        default:
 347                return -EINVAL;
 348        }
 349
 350        *maskp = mask;
 351        *shiftp = shift;
 352
 353        return 0;
 354}
 355
 356#define ADR_IMM_HILOSPLIT       2
 357#define ADR_IMM_SIZE            SZ_2M
 358#define ADR_IMM_LOMASK          ((1 << ADR_IMM_HILOSPLIT) - 1)
 359#define ADR_IMM_HIMASK          ((ADR_IMM_SIZE >> ADR_IMM_HILOSPLIT) - 1)
 360#define ADR_IMM_LOSHIFT         29
 361#define ADR_IMM_HISHIFT         5
 362
 363u64 aarch64_insn_decode_immediate(enum aarch64_insn_imm_type type, u32 insn)
 364{
 365        u32 immlo, immhi, mask;
 366        int shift;
 367
 368        switch (type) {
 369        case AARCH64_INSN_IMM_ADR:
 370                shift = 0;
 371                immlo = (insn >> ADR_IMM_LOSHIFT) & ADR_IMM_LOMASK;
 372                immhi = (insn >> ADR_IMM_HISHIFT) & ADR_IMM_HIMASK;
 373                insn = (immhi << ADR_IMM_HILOSPLIT) | immlo;
 374                mask = ADR_IMM_SIZE - 1;
 375                break;
 376        default:
 377                if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
 378                        pr_err("aarch64_insn_decode_immediate: unknown immediate encoding %d\n",
 379                               type);
 380                        return 0;
 381                }
 382        }
 383
 384        return (insn >> shift) & mask;
 385}
 386
 387u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
 388                                  u32 insn, u64 imm)
 389{
 390        u32 immlo, immhi, mask;
 391        int shift;
 392
 393        if (insn == AARCH64_BREAK_FAULT)
 394                return AARCH64_BREAK_FAULT;
 395
 396        switch (type) {
 397        case AARCH64_INSN_IMM_ADR:
 398                shift = 0;
 399                immlo = (imm & ADR_IMM_LOMASK) << ADR_IMM_LOSHIFT;
 400                imm >>= ADR_IMM_HILOSPLIT;
 401                immhi = (imm & ADR_IMM_HIMASK) << ADR_IMM_HISHIFT;
 402                imm = immlo | immhi;
 403                mask = ((ADR_IMM_LOMASK << ADR_IMM_LOSHIFT) |
 404                        (ADR_IMM_HIMASK << ADR_IMM_HISHIFT));
 405                break;
 406        default:
 407                if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
 408                        pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n",
 409                               type);
 410                        return AARCH64_BREAK_FAULT;
 411                }
 412        }
 413
 414        /* Update the immediate field. */
 415        insn &= ~(mask << shift);
 416        insn |= (imm & mask) << shift;
 417
 418        return insn;
 419}
 420
 421u32 aarch64_insn_decode_register(enum aarch64_insn_register_type type,
 422                                        u32 insn)
 423{
 424        int shift;
 425
 426        switch (type) {
 427        case AARCH64_INSN_REGTYPE_RT:
 428        case AARCH64_INSN_REGTYPE_RD:
 429                shift = 0;
 430                break;
 431        case AARCH64_INSN_REGTYPE_RN:
 432                shift = 5;
 433                break;
 434        case AARCH64_INSN_REGTYPE_RT2:
 435        case AARCH64_INSN_REGTYPE_RA:
 436                shift = 10;
 437                break;
 438        case AARCH64_INSN_REGTYPE_RM:
 439                shift = 16;
 440                break;
 441        default:
 442                pr_err("%s: unknown register type encoding %d\n", __func__,
 443                       type);
 444                return 0;
 445        }
 446
 447        return (insn >> shift) & GENMASK(4, 0);
 448}
 449
 450static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
 451                                        u32 insn,
 452                                        enum aarch64_insn_register reg)
 453{
 454        int shift;
 455
 456        if (insn == AARCH64_BREAK_FAULT)
 457                return AARCH64_BREAK_FAULT;
 458
 459        if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) {
 460                pr_err("%s: unknown register encoding %d\n", __func__, reg);
 461                return AARCH64_BREAK_FAULT;
 462        }
 463
 464        switch (type) {
 465        case AARCH64_INSN_REGTYPE_RT:
 466        case AARCH64_INSN_REGTYPE_RD:
 467                shift = 0;
 468                break;
 469        case AARCH64_INSN_REGTYPE_RN:
 470                shift = 5;
 471                break;
 472        case AARCH64_INSN_REGTYPE_RT2:
 473        case AARCH64_INSN_REGTYPE_RA:
 474                shift = 10;
 475                break;
 476        case AARCH64_INSN_REGTYPE_RM:
 477        case AARCH64_INSN_REGTYPE_RS:
 478                shift = 16;
 479                break;
 480        default:
 481                pr_err("%s: unknown register type encoding %d\n", __func__,
 482                       type);
 483                return AARCH64_BREAK_FAULT;
 484        }
 485
 486        insn &= ~(GENMASK(4, 0) << shift);
 487        insn |= reg << shift;
 488
 489        return insn;
 490}
 491
 492static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
 493                                         u32 insn)
 494{
 495        u32 size;
 496
 497        switch (type) {
 498        case AARCH64_INSN_SIZE_8:
 499                size = 0;
 500                break;
 501        case AARCH64_INSN_SIZE_16:
 502                size = 1;
 503                break;
 504        case AARCH64_INSN_SIZE_32:
 505                size = 2;
 506                break;
 507        case AARCH64_INSN_SIZE_64:
 508                size = 3;
 509                break;
 510        default:
 511                pr_err("%s: unknown size encoding %d\n", __func__, type);
 512                return AARCH64_BREAK_FAULT;
 513        }
 514
 515        insn &= ~GENMASK(31, 30);
 516        insn |= size << 30;
 517
 518        return insn;
 519}
 520
 521static inline long branch_imm_common(unsigned long pc, unsigned long addr,
 522                                     long range)
 523{
 524        long offset;
 525
 526        if ((pc & 0x3) || (addr & 0x3)) {
 527                pr_err("%s: A64 instructions must be word aligned\n", __func__);
 528                return range;
 529        }
 530
 531        offset = ((long)addr - (long)pc);
 532
 533        if (offset < -range || offset >= range) {
 534                pr_err("%s: offset out of range\n", __func__);
 535                return range;
 536        }
 537
 538        return offset;
 539}
 540
 541u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
 542                                          enum aarch64_insn_branch_type type)
 543{
 544        u32 insn;
 545        long offset;
 546
 547        /*
 548         * B/BL support [-128M, 128M) offset
 549         * ARM64 virtual address arrangement guarantees all kernel and module
 550         * texts are within +/-128M.
 551         */
 552        offset = branch_imm_common(pc, addr, SZ_128M);
 553        if (offset >= SZ_128M)
 554                return AARCH64_BREAK_FAULT;
 555
 556        switch (type) {
 557        case AARCH64_INSN_BRANCH_LINK:
 558                insn = aarch64_insn_get_bl_value();
 559                break;
 560        case AARCH64_INSN_BRANCH_NOLINK:
 561                insn = aarch64_insn_get_b_value();
 562                break;
 563        default:
 564                pr_err("%s: unknown branch encoding %d\n", __func__, type);
 565                return AARCH64_BREAK_FAULT;
 566        }
 567
 568        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn,
 569                                             offset >> 2);
 570}
 571
 572u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
 573                                     enum aarch64_insn_register reg,
 574                                     enum aarch64_insn_variant variant,
 575                                     enum aarch64_insn_branch_type type)
 576{
 577        u32 insn;
 578        long offset;
 579
 580        offset = branch_imm_common(pc, addr, SZ_1M);
 581        if (offset >= SZ_1M)
 582                return AARCH64_BREAK_FAULT;
 583
 584        switch (type) {
 585        case AARCH64_INSN_BRANCH_COMP_ZERO:
 586                insn = aarch64_insn_get_cbz_value();
 587                break;
 588        case AARCH64_INSN_BRANCH_COMP_NONZERO:
 589                insn = aarch64_insn_get_cbnz_value();
 590                break;
 591        default:
 592                pr_err("%s: unknown branch encoding %d\n", __func__, type);
 593                return AARCH64_BREAK_FAULT;
 594        }
 595
 596        switch (variant) {
 597        case AARCH64_INSN_VARIANT_32BIT:
 598                break;
 599        case AARCH64_INSN_VARIANT_64BIT:
 600                insn |= AARCH64_INSN_SF_BIT;
 601                break;
 602        default:
 603                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
 604                return AARCH64_BREAK_FAULT;
 605        }
 606
 607        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
 608
 609        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
 610                                             offset >> 2);
 611}
 612
 613u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr,
 614                                     enum aarch64_insn_condition cond)
 615{
 616        u32 insn;
 617        long offset;
 618
 619        offset = branch_imm_common(pc, addr, SZ_1M);
 620
 621        insn = aarch64_insn_get_bcond_value();
 622
 623        if (cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL) {
 624                pr_err("%s: unknown condition encoding %d\n", __func__, cond);
 625                return AARCH64_BREAK_FAULT;
 626        }
 627        insn |= cond;
 628
 629        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
 630                                             offset >> 2);
 631}
 632
 633u32 __kprobes aarch64_insn_gen_hint(enum aarch64_insn_hint_op op)
 634{
 635        return aarch64_insn_get_hint_value() | op;
 636}
 637
 638u32 __kprobes aarch64_insn_gen_nop(void)
 639{
 640        return aarch64_insn_gen_hint(AARCH64_INSN_HINT_NOP);
 641}
 642
 643u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg,
 644                                enum aarch64_insn_branch_type type)
 645{
 646        u32 insn;
 647
 648        switch (type) {
 649        case AARCH64_INSN_BRANCH_NOLINK:
 650                insn = aarch64_insn_get_br_value();
 651                break;
 652        case AARCH64_INSN_BRANCH_LINK:
 653                insn = aarch64_insn_get_blr_value();
 654                break;
 655        case AARCH64_INSN_BRANCH_RETURN:
 656                insn = aarch64_insn_get_ret_value();
 657                break;
 658        default:
 659                pr_err("%s: unknown branch encoding %d\n", __func__, type);
 660                return AARCH64_BREAK_FAULT;
 661        }
 662
 663        return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, reg);
 664}
 665
 666u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
 667                                    enum aarch64_insn_register base,
 668                                    enum aarch64_insn_register offset,
 669                                    enum aarch64_insn_size_type size,
 670                                    enum aarch64_insn_ldst_type type)
 671{
 672        u32 insn;
 673
 674        switch (type) {
 675        case AARCH64_INSN_LDST_LOAD_REG_OFFSET:
 676                insn = aarch64_insn_get_ldr_reg_value();
 677                break;
 678        case AARCH64_INSN_LDST_STORE_REG_OFFSET:
 679                insn = aarch64_insn_get_str_reg_value();
 680                break;
 681        default:
 682                pr_err("%s: unknown load/store encoding %d\n", __func__, type);
 683                return AARCH64_BREAK_FAULT;
 684        }
 685
 686        insn = aarch64_insn_encode_ldst_size(size, insn);
 687
 688        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn, reg);
 689
 690        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
 691                                            base);
 692
 693        return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn,
 694                                            offset);
 695}
 696
 697u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1,
 698                                     enum aarch64_insn_register reg2,
 699                                     enum aarch64_insn_register base,
 700                                     int offset,
 701                                     enum aarch64_insn_variant variant,
 702                                     enum aarch64_insn_ldst_type type)
 703{
 704        u32 insn;
 705        int shift;
 706
 707        switch (type) {
 708        case AARCH64_INSN_LDST_LOAD_PAIR_PRE_INDEX:
 709                insn = aarch64_insn_get_ldp_pre_value();
 710                break;
 711        case AARCH64_INSN_LDST_STORE_PAIR_PRE_INDEX:
 712                insn = aarch64_insn_get_stp_pre_value();
 713                break;
 714        case AARCH64_INSN_LDST_LOAD_PAIR_POST_INDEX:
 715                insn = aarch64_insn_get_ldp_post_value();
 716                break;
 717        case AARCH64_INSN_LDST_STORE_PAIR_POST_INDEX:
 718                insn = aarch64_insn_get_stp_post_value();
 719                break;
 720        default:
 721                pr_err("%s: unknown load/store encoding %d\n", __func__, type);
 722                return AARCH64_BREAK_FAULT;
 723        }
 724
 725        switch (variant) {
 726        case AARCH64_INSN_VARIANT_32BIT:
 727                if ((offset & 0x3) || (offset < -256) || (offset > 252)) {
 728                        pr_err("%s: offset must be multiples of 4 in the range of [-256, 252] %d\n",
 729                               __func__, offset);
 730                        return AARCH64_BREAK_FAULT;
 731                }
 732                shift = 2;
 733                break;
 734        case AARCH64_INSN_VARIANT_64BIT:
 735                if ((offset & 0x7) || (offset < -512) || (offset > 504)) {
 736                        pr_err("%s: offset must be multiples of 8 in the range of [-512, 504] %d\n",
 737                               __func__, offset);
 738                        return AARCH64_BREAK_FAULT;
 739                }
 740                shift = 3;
 741                insn |= AARCH64_INSN_SF_BIT;
 742                break;
 743        default:
 744                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
 745                return AARCH64_BREAK_FAULT;
 746        }
 747
 748        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
 749                                            reg1);
 750
 751        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn,
 752                                            reg2);
 753
 754        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
 755                                            base);
 756
 757        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_7, insn,
 758                                             offset >> shift);
 759}
 760
 761u32 aarch64_insn_gen_load_store_ex(enum aarch64_insn_register reg,
 762                                   enum aarch64_insn_register base,
 763                                   enum aarch64_insn_register state,
 764                                   enum aarch64_insn_size_type size,
 765                                   enum aarch64_insn_ldst_type type)
 766{
 767        u32 insn;
 768
 769        switch (type) {
 770        case AARCH64_INSN_LDST_LOAD_EX:
 771                insn = aarch64_insn_get_load_ex_value();
 772                break;
 773        case AARCH64_INSN_LDST_STORE_EX:
 774                insn = aarch64_insn_get_store_ex_value();
 775                break;
 776        default:
 777                pr_err("%s: unknown load/store exclusive encoding %d\n", __func__, type);
 778                return AARCH64_BREAK_FAULT;
 779        }
 780
 781        insn = aarch64_insn_encode_ldst_size(size, insn);
 782
 783        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT, insn,
 784                                            reg);
 785
 786        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
 787                                            base);
 788
 789        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RT2, insn,
 790                                            AARCH64_INSN_REG_ZR);
 791
 792        return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RS, insn,
 793                                            state);
 794}
 795
 796static u32 aarch64_insn_encode_prfm_imm(enum aarch64_insn_prfm_type type,
 797                                        enum aarch64_insn_prfm_target target,
 798                                        enum aarch64_insn_prfm_policy policy,
 799                                        u32 insn)
 800{
 801        u32 imm_type = 0, imm_target = 0, imm_policy = 0;
 802
 803        switch (type) {
 804        case AARCH64_INSN_PRFM_TYPE_PLD:
 805                break;
 806        case AARCH64_INSN_PRFM_TYPE_PLI:
 807                imm_type = BIT(0);
 808                break;
 809        case AARCH64_INSN_PRFM_TYPE_PST:
 810                imm_type = BIT(1);
 811                break;
 812        default:
 813                pr_err("%s: unknown prfm type encoding %d\n", __func__, type);
 814                return AARCH64_BREAK_FAULT;
 815        }
 816
 817        switch (target) {
 818        case AARCH64_INSN_PRFM_TARGET_L1:
 819                break;
 820        case AARCH64_INSN_PRFM_TARGET_L2:
 821                imm_target = BIT(0);
 822                break;
 823        case AARCH64_INSN_PRFM_TARGET_L3:
 824                imm_target = BIT(1);
 825                break;
 826        default:
 827                pr_err("%s: unknown prfm target encoding %d\n", __func__, target);
 828                return AARCH64_BREAK_FAULT;
 829        }
 830
 831        switch (policy) {
 832        case AARCH64_INSN_PRFM_POLICY_KEEP:
 833                break;
 834        case AARCH64_INSN_PRFM_POLICY_STRM:
 835                imm_policy = BIT(0);
 836                break;
 837        default:
 838                pr_err("%s: unknown prfm policy encoding %d\n", __func__, policy);
 839                return AARCH64_BREAK_FAULT;
 840        }
 841
 842        /* In this case, imm5 is encoded into Rt field. */
 843        insn &= ~GENMASK(4, 0);
 844        insn |= imm_policy | (imm_target << 1) | (imm_type << 3);
 845
 846        return insn;
 847}
 848
 849u32 aarch64_insn_gen_prefetch(enum aarch64_insn_register base,
 850                              enum aarch64_insn_prfm_type type,
 851                              enum aarch64_insn_prfm_target target,
 852                              enum aarch64_insn_prfm_policy policy)
 853{
 854        u32 insn = aarch64_insn_get_prfm_value();
 855
 856        insn = aarch64_insn_encode_ldst_size(AARCH64_INSN_SIZE_64, insn);
 857
 858        insn = aarch64_insn_encode_prfm_imm(type, target, policy, insn);
 859
 860        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
 861                                            base);
 862
 863        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, 0);
 864}
 865
 866u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
 867                                 enum aarch64_insn_register src,
 868                                 int imm, enum aarch64_insn_variant variant,
 869                                 enum aarch64_insn_adsb_type type)
 870{
 871        u32 insn;
 872
 873        switch (type) {
 874        case AARCH64_INSN_ADSB_ADD:
 875                insn = aarch64_insn_get_add_imm_value();
 876                break;
 877        case AARCH64_INSN_ADSB_SUB:
 878                insn = aarch64_insn_get_sub_imm_value();
 879                break;
 880        case AARCH64_INSN_ADSB_ADD_SETFLAGS:
 881                insn = aarch64_insn_get_adds_imm_value();
 882                break;
 883        case AARCH64_INSN_ADSB_SUB_SETFLAGS:
 884                insn = aarch64_insn_get_subs_imm_value();
 885                break;
 886        default:
 887                pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
 888                return AARCH64_BREAK_FAULT;
 889        }
 890
 891        switch (variant) {
 892        case AARCH64_INSN_VARIANT_32BIT:
 893                break;
 894        case AARCH64_INSN_VARIANT_64BIT:
 895                insn |= AARCH64_INSN_SF_BIT;
 896                break;
 897        default:
 898                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
 899                return AARCH64_BREAK_FAULT;
 900        }
 901
 902        if (imm & ~(SZ_4K - 1)) {
 903                pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
 904                return AARCH64_BREAK_FAULT;
 905        }
 906
 907        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
 908
 909        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
 910
 911        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_12, insn, imm);
 912}
 913
 914u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
 915                              enum aarch64_insn_register src,
 916                              int immr, int imms,
 917                              enum aarch64_insn_variant variant,
 918                              enum aarch64_insn_bitfield_type type)
 919{
 920        u32 insn;
 921        u32 mask;
 922
 923        switch (type) {
 924        case AARCH64_INSN_BITFIELD_MOVE:
 925                insn = aarch64_insn_get_bfm_value();
 926                break;
 927        case AARCH64_INSN_BITFIELD_MOVE_UNSIGNED:
 928                insn = aarch64_insn_get_ubfm_value();
 929                break;
 930        case AARCH64_INSN_BITFIELD_MOVE_SIGNED:
 931                insn = aarch64_insn_get_sbfm_value();
 932                break;
 933        default:
 934                pr_err("%s: unknown bitfield encoding %d\n", __func__, type);
 935                return AARCH64_BREAK_FAULT;
 936        }
 937
 938        switch (variant) {
 939        case AARCH64_INSN_VARIANT_32BIT:
 940                mask = GENMASK(4, 0);
 941                break;
 942        case AARCH64_INSN_VARIANT_64BIT:
 943                insn |= AARCH64_INSN_SF_BIT | AARCH64_INSN_N_BIT;
 944                mask = GENMASK(5, 0);
 945                break;
 946        default:
 947                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
 948                return AARCH64_BREAK_FAULT;
 949        }
 950
 951        if (immr & ~mask) {
 952                pr_err("%s: invalid immr encoding %d\n", __func__, immr);
 953                return AARCH64_BREAK_FAULT;
 954        }
 955        if (imms & ~mask) {
 956                pr_err("%s: invalid imms encoding %d\n", __func__, imms);
 957                return AARCH64_BREAK_FAULT;
 958        }
 959
 960        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
 961
 962        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
 963
 964        insn = aarch64_insn_encode_immediate(AARCH64_INSN_IMM_R, insn, immr);
 965
 966        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_S, insn, imms);
 967}
 968
 969u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
 970                              int imm, int shift,
 971                              enum aarch64_insn_variant variant,
 972                              enum aarch64_insn_movewide_type type)
 973{
 974        u32 insn;
 975
 976        switch (type) {
 977        case AARCH64_INSN_MOVEWIDE_ZERO:
 978                insn = aarch64_insn_get_movz_value();
 979                break;
 980        case AARCH64_INSN_MOVEWIDE_KEEP:
 981                insn = aarch64_insn_get_movk_value();
 982                break;
 983        case AARCH64_INSN_MOVEWIDE_INVERSE:
 984                insn = aarch64_insn_get_movn_value();
 985                break;
 986        default:
 987                pr_err("%s: unknown movewide encoding %d\n", __func__, type);
 988                return AARCH64_BREAK_FAULT;
 989        }
 990
 991        if (imm & ~(SZ_64K - 1)) {
 992                pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
 993                return AARCH64_BREAK_FAULT;
 994        }
 995
 996        switch (variant) {
 997        case AARCH64_INSN_VARIANT_32BIT:
 998                if (shift != 0 && shift != 16) {
 999                        pr_err("%s: invalid shift encoding %d\n", __func__,
1000                               shift);
1001                        return AARCH64_BREAK_FAULT;
1002                }
1003                break;
1004        case AARCH64_INSN_VARIANT_64BIT:
1005                insn |= AARCH64_INSN_SF_BIT;
1006                if (shift != 0 && shift != 16 && shift != 32 && shift != 48) {
1007                        pr_err("%s: invalid shift encoding %d\n", __func__,
1008                               shift);
1009                        return AARCH64_BREAK_FAULT;
1010                }
1011                break;
1012        default:
1013                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
1014                return AARCH64_BREAK_FAULT;
1015        }
1016
1017        insn |= (shift >> 4) << 21;
1018
1019        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
1020
1021        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_16, insn, imm);
1022}
1023
1024u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst,
1025                                         enum aarch64_insn_register src,
1026                                         enum aarch64_insn_register reg,
1027                                         int shift,
1028                                         enum aarch64_insn_variant variant,
1029                                         enum aarch64_insn_adsb_type type)
1030{
1031        u32 insn;
1032
1033        switch (type) {
1034        case AARCH64_INSN_ADSB_ADD:
1035                insn = aarch64_insn_get_add_value();
1036                break;
1037        case AARCH64_INSN_ADSB_SUB:
1038                insn = aarch64_insn_get_sub_value();
1039                break;
1040        case AARCH64_INSN_ADSB_ADD_SETFLAGS:
1041                insn = aarch64_insn_get_adds_value();
1042                break;
1043        case AARCH64_INSN_ADSB_SUB_SETFLAGS:
1044                insn = aarch64_insn_get_subs_value();
1045                break;
1046        default:
1047                pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
1048                return AARCH64_BREAK_FAULT;
1049        }
1050
1051        switch (variant) {
1052        case AARCH64_INSN_VARIANT_32BIT:
1053                if (shift & ~(SZ_32 - 1)) {
1054                        pr_err("%s: invalid shift encoding %d\n", __func__,
1055                               shift);
1056                        return AARCH64_BREAK_FAULT;
1057                }
1058                break;
1059        case AARCH64_INSN_VARIANT_64BIT:
1060                insn |= AARCH64_INSN_SF_BIT;
1061                if (shift & ~(SZ_64 - 1)) {
1062                        pr_err("%s: invalid shift encoding %d\n", __func__,
1063                               shift);
1064                        return AARCH64_BREAK_FAULT;
1065                }
1066                break;
1067        default:
1068                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
1069                return AARCH64_BREAK_FAULT;
1070        }
1071
1072
1073        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
1074
1075        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
1076
1077        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
1078
1079        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
1080}
1081
1082u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
1083                           enum aarch64_insn_register src,
1084                           enum aarch64_insn_variant variant,
1085                           enum aarch64_insn_data1_type type)
1086{
1087        u32 insn;
1088
1089        switch (type) {
1090        case AARCH64_INSN_DATA1_REVERSE_16:
1091                insn = aarch64_insn_get_rev16_value();
1092                break;
1093        case AARCH64_INSN_DATA1_REVERSE_32:
1094                insn = aarch64_insn_get_rev32_value();
1095                break;
1096        case AARCH64_INSN_DATA1_REVERSE_64:
1097                if (variant != AARCH64_INSN_VARIANT_64BIT) {
1098                        pr_err("%s: invalid variant for reverse64 %d\n",
1099                               __func__, variant);
1100                        return AARCH64_BREAK_FAULT;
1101                }
1102                insn = aarch64_insn_get_rev64_value();
1103                break;
1104        default:
1105                pr_err("%s: unknown data1 encoding %d\n", __func__, type);
1106                return AARCH64_BREAK_FAULT;
1107        }
1108
1109        switch (variant) {
1110        case AARCH64_INSN_VARIANT_32BIT:
1111                break;
1112        case AARCH64_INSN_VARIANT_64BIT:
1113                insn |= AARCH64_INSN_SF_BIT;
1114                break;
1115        default:
1116                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
1117                return AARCH64_BREAK_FAULT;
1118        }
1119
1120        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
1121
1122        return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
1123}
1124
1125u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
1126                           enum aarch64_insn_register src,
1127                           enum aarch64_insn_register reg,
1128                           enum aarch64_insn_variant variant,
1129                           enum aarch64_insn_data2_type type)
1130{
1131        u32 insn;
1132
1133        switch (type) {
1134        case AARCH64_INSN_DATA2_UDIV:
1135                insn = aarch64_insn_get_udiv_value();
1136                break;
1137        case AARCH64_INSN_DATA2_SDIV:
1138                insn = aarch64_insn_get_sdiv_value();
1139                break;
1140        case AARCH64_INSN_DATA2_LSLV:
1141                insn = aarch64_insn_get_lslv_value();
1142                break;
1143        case AARCH64_INSN_DATA2_LSRV:
1144                insn = aarch64_insn_get_lsrv_value();
1145                break;
1146        case AARCH64_INSN_DATA2_ASRV:
1147                insn = aarch64_insn_get_asrv_value();
1148                break;
1149        case AARCH64_INSN_DATA2_RORV:
1150                insn = aarch64_insn_get_rorv_value();
1151                break;
1152        default:
1153                pr_err("%s: unknown data2 encoding %d\n", __func__, type);
1154                return AARCH64_BREAK_FAULT;
1155        }
1156
1157        switch (variant) {
1158        case AARCH64_INSN_VARIANT_32BIT:
1159                break;
1160        case AARCH64_INSN_VARIANT_64BIT:
1161                insn |= AARCH64_INSN_SF_BIT;
1162                break;
1163        default:
1164                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
1165                return AARCH64_BREAK_FAULT;
1166        }
1167
1168        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
1169
1170        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
1171
1172        return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
1173}
1174
1175u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
1176                           enum aarch64_insn_register src,
1177                           enum aarch64_insn_register reg1,
1178                           enum aarch64_insn_register reg2,
1179                           enum aarch64_insn_variant variant,
1180                           enum aarch64_insn_data3_type type)
1181{
1182        u32 insn;
1183
1184        switch (type) {
1185        case AARCH64_INSN_DATA3_MADD:
1186                insn = aarch64_insn_get_madd_value();
1187                break;
1188        case AARCH64_INSN_DATA3_MSUB:
1189                insn = aarch64_insn_get_msub_value();
1190                break;
1191        default:
1192                pr_err("%s: unknown data3 encoding %d\n", __func__, type);
1193                return AARCH64_BREAK_FAULT;
1194        }
1195
1196        switch (variant) {
1197        case AARCH64_INSN_VARIANT_32BIT:
1198                break;
1199        case AARCH64_INSN_VARIANT_64BIT:
1200                insn |= AARCH64_INSN_SF_BIT;
1201                break;
1202        default:
1203                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
1204                return AARCH64_BREAK_FAULT;
1205        }
1206
1207        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
1208
1209        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RA, insn, src);
1210
1211        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn,
1212                                            reg1);
1213
1214        return aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn,
1215                                            reg2);
1216}
1217
1218u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst,
1219                                         enum aarch64_insn_register src,
1220                                         enum aarch64_insn_register reg,
1221                                         int shift,
1222                                         enum aarch64_insn_variant variant,
1223                                         enum aarch64_insn_logic_type type)
1224{
1225        u32 insn;
1226
1227        switch (type) {
1228        case AARCH64_INSN_LOGIC_AND:
1229                insn = aarch64_insn_get_and_value();
1230                break;
1231        case AARCH64_INSN_LOGIC_BIC:
1232                insn = aarch64_insn_get_bic_value();
1233                break;
1234        case AARCH64_INSN_LOGIC_ORR:
1235                insn = aarch64_insn_get_orr_value();
1236                break;
1237        case AARCH64_INSN_LOGIC_ORN:
1238                insn = aarch64_insn_get_orn_value();
1239                break;
1240        case AARCH64_INSN_LOGIC_EOR:
1241                insn = aarch64_insn_get_eor_value();
1242                break;
1243        case AARCH64_INSN_LOGIC_EON:
1244                insn = aarch64_insn_get_eon_value();
1245                break;
1246        case AARCH64_INSN_LOGIC_AND_SETFLAGS:
1247                insn = aarch64_insn_get_ands_value();
1248                break;
1249        case AARCH64_INSN_LOGIC_BIC_SETFLAGS:
1250                insn = aarch64_insn_get_bics_value();
1251                break;
1252        default:
1253                pr_err("%s: unknown logical encoding %d\n", __func__, type);
1254                return AARCH64_BREAK_FAULT;
1255        }
1256
1257        switch (variant) {
1258        case AARCH64_INSN_VARIANT_32BIT:
1259                if (shift & ~(SZ_32 - 1)) {
1260                        pr_err("%s: invalid shift encoding %d\n", __func__,
1261                               shift);
1262                        return AARCH64_BREAK_FAULT;
1263                }
1264                break;
1265        case AARCH64_INSN_VARIANT_64BIT:
1266                insn |= AARCH64_INSN_SF_BIT;
1267                if (shift & ~(SZ_64 - 1)) {
1268                        pr_err("%s: invalid shift encoding %d\n", __func__,
1269                               shift);
1270                        return AARCH64_BREAK_FAULT;
1271                }
1272                break;
1273        default:
1274                pr_err("%s: unknown variant encoding %d\n", __func__, variant);
1275                return AARCH64_BREAK_FAULT;
1276        }
1277
1278
1279        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
1280
1281        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RN, insn, src);
1282
1283        insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RM, insn, reg);
1284
1285        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_6, insn, shift);
1286}
1287
1288/*
1289 * Decode the imm field of a branch, and return the byte offset as a
1290 * signed value (so it can be used when computing a new branch
1291 * target).
1292 */
1293s32 aarch64_get_branch_offset(u32 insn)
1294{
1295        s32 imm;
1296
1297        if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn)) {
1298                imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_26, insn);
1299                return (imm << 6) >> 4;
1300        }
1301
1302        if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
1303            aarch64_insn_is_bcond(insn)) {
1304                imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_19, insn);
1305                return (imm << 13) >> 11;
1306        }
1307
1308        if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn)) {
1309                imm = aarch64_insn_decode_immediate(AARCH64_INSN_IMM_14, insn);
1310                return (imm << 18) >> 16;
1311        }
1312
1313        /* Unhandled instruction */
1314        BUG();
1315}
1316
1317/*
1318 * Encode the displacement of a branch in the imm field and return the
1319 * updated instruction.
1320 */
1321u32 aarch64_set_branch_offset(u32 insn, s32 offset)
1322{
1323        if (aarch64_insn_is_b(insn) || aarch64_insn_is_bl(insn))
1324                return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_26, insn,
1325                                                     offset >> 2);
1326
1327        if (aarch64_insn_is_cbz(insn) || aarch64_insn_is_cbnz(insn) ||
1328            aarch64_insn_is_bcond(insn))
1329                return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
1330                                                     offset >> 2);
1331
1332        if (aarch64_insn_is_tbz(insn) || aarch64_insn_is_tbnz(insn))
1333                return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_14, insn,
1334                                                     offset >> 2);
1335
1336        /* Unhandled instruction */
1337        BUG();
1338}
1339
1340s32 aarch64_insn_adrp_get_offset(u32 insn)
1341{
1342        BUG_ON(!aarch64_insn_is_adrp(insn));
1343        return aarch64_insn_decode_immediate(AARCH64_INSN_IMM_ADR, insn) << 12;
1344}
1345
1346u32 aarch64_insn_adrp_set_offset(u32 insn, s32 offset)
1347{
1348        BUG_ON(!aarch64_insn_is_adrp(insn));
1349        return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_ADR, insn,
1350                                                offset >> 12);
1351}
1352
1353/*
1354 * Extract the Op/CR data from a msr/mrs instruction.
1355 */
1356u32 aarch64_insn_extract_system_reg(u32 insn)
1357{
1358        return (insn & 0x1FFFE0) >> 5;
1359}
1360
1361bool aarch32_insn_is_wide(u32 insn)
1362{
1363        return insn >= 0xe800;
1364}
1365
1366/*
1367 * Macros/defines for extracting register numbers from instruction.
1368 */
1369u32 aarch32_insn_extract_reg_num(u32 insn, int offset)
1370{
1371        return (insn & (0xf << offset)) >> offset;
1372}
1373
1374#define OPC2_MASK       0x7
1375#define OPC2_OFFSET     5
1376u32 aarch32_insn_mcr_extract_opc2(u32 insn)
1377{
1378        return (insn & (OPC2_MASK << OPC2_OFFSET)) >> OPC2_OFFSET;
1379}
1380
1381#define CRM_MASK        0xf
1382u32 aarch32_insn_mcr_extract_crm(u32 insn)
1383{
1384        return insn & CRM_MASK;
1385}
1386
1387static bool __kprobes __check_eq(unsigned long pstate)
1388{
1389        return (pstate & PSR_Z_BIT) != 0;
1390}
1391
1392static bool __kprobes __check_ne(unsigned long pstate)
1393{
1394        return (pstate & PSR_Z_BIT) == 0;
1395}
1396
1397static bool __kprobes __check_cs(unsigned long pstate)
1398{
1399        return (pstate & PSR_C_BIT) != 0;
1400}
1401
1402static bool __kprobes __check_cc(unsigned long pstate)
1403{
1404        return (pstate & PSR_C_BIT) == 0;
1405}
1406
1407static bool __kprobes __check_mi(unsigned long pstate)
1408{
1409        return (pstate & PSR_N_BIT) != 0;
1410}
1411
1412static bool __kprobes __check_pl(unsigned long pstate)
1413{
1414        return (pstate & PSR_N_BIT) == 0;
1415}
1416
1417static bool __kprobes __check_vs(unsigned long pstate)
1418{
1419        return (pstate & PSR_V_BIT) != 0;
1420}
1421
1422static bool __kprobes __check_vc(unsigned long pstate)
1423{
1424        return (pstate & PSR_V_BIT) == 0;
1425}
1426
1427static bool __kprobes __check_hi(unsigned long pstate)
1428{
1429        pstate &= ~(pstate >> 1);       /* PSR_C_BIT &= ~PSR_Z_BIT */
1430        return (pstate & PSR_C_BIT) != 0;
1431}
1432
1433static bool __kprobes __check_ls(unsigned long pstate)
1434{
1435        pstate &= ~(pstate >> 1);       /* PSR_C_BIT &= ~PSR_Z_BIT */
1436        return (pstate & PSR_C_BIT) == 0;
1437}
1438
1439static bool __kprobes __check_ge(unsigned long pstate)
1440{
1441        pstate ^= (pstate << 3);        /* PSR_N_BIT ^= PSR_V_BIT */
1442        return (pstate & PSR_N_BIT) == 0;
1443}
1444
1445static bool __kprobes __check_lt(unsigned long pstate)
1446{
1447        pstate ^= (pstate << 3);        /* PSR_N_BIT ^= PSR_V_BIT */
1448        return (pstate & PSR_N_BIT) != 0;
1449}
1450
1451static bool __kprobes __check_gt(unsigned long pstate)
1452{
1453        /*PSR_N_BIT ^= PSR_V_BIT */
1454        unsigned long temp = pstate ^ (pstate << 3);
1455
1456        temp |= (pstate << 1);  /*PSR_N_BIT |= PSR_Z_BIT */
1457        return (temp & PSR_N_BIT) == 0;
1458}
1459
1460static bool __kprobes __check_le(unsigned long pstate)
1461{
1462        /*PSR_N_BIT ^= PSR_V_BIT */
1463        unsigned long temp = pstate ^ (pstate << 3);
1464
1465        temp |= (pstate << 1);  /*PSR_N_BIT |= PSR_Z_BIT */
1466        return (temp & PSR_N_BIT) != 0;
1467}
1468
1469static bool __kprobes __check_al(unsigned long pstate)
1470{
1471        return true;
1472}
1473
1474/*
1475 * Note that the ARMv8 ARM calls condition code 0b1111 "nv", but states that
1476 * it behaves identically to 0b1110 ("al").
1477 */
1478pstate_check_t * const aarch32_opcode_cond_checks[16] = {
1479        __check_eq, __check_ne, __check_cs, __check_cc,
1480        __check_mi, __check_pl, __check_vs, __check_vc,
1481        __check_hi, __check_ls, __check_ge, __check_lt,
1482        __check_gt, __check_le, __check_al, __check_al
1483};
1484