Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a532239b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "arm64: insn: remove BUG_ON from codegen"

parents 4af58b8a 69887b8c
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -910,7 +910,7 @@ config RANDOMIZE_BASE


config RANDOMIZE_MODULE_REGION_FULL
config RANDOMIZE_MODULE_REGION_FULL
	bool "Randomize the module region independently from the core kernel"
	bool "Randomize the module region independently from the core kernel"
	depends on RANDOMIZE_BASE
	depends on RANDOMIZE_BASE && !DYNAMIC_FTRACE
	default y
	default y
	help
	help
	  Randomizes the location of the module region without considering the
	  Randomizes the location of the module region without considering the
+112 −53
Original line number Original line Diff line number Diff line
@@ -2,7 +2,7 @@
 * Copyright (C) 2013 Huawei Ltd.
 * Copyright (C) 2013 Huawei Ltd.
 * Author: Jiang Liu <liuj97@gmail.com>
 * Author: Jiang Liu <liuj97@gmail.com>
 *
 *
 * Copyright (C) 2014 Zi Shen Lim <zlim.lnx@gmail.com>
 * Copyright (C) 2014-2016 Zi Shen Lim <zlim.lnx@gmail.com>
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * it under the terms of the GNU General Public License version 2 as
@@ -364,6 +364,9 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
	u32 immlo, immhi, mask;
	u32 immlo, immhi, mask;
	int shift;
	int shift;


	if (insn == AARCH64_BREAK_FAULT)
		return AARCH64_BREAK_FAULT;

	switch (type) {
	switch (type) {
	case AARCH64_INSN_IMM_ADR:
	case AARCH64_INSN_IMM_ADR:
		shift = 0;
		shift = 0;
@@ -378,7 +381,7 @@ u32 __kprobes aarch64_insn_encode_immediate(enum aarch64_insn_imm_type type,
		if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
		if (aarch64_get_imm_shift_mask(type, &mask, &shift) < 0) {
			pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n",
			pr_err("aarch64_insn_encode_immediate: unknown immediate encoding %d\n",
			       type);
			       type);
			return 0;
			return AARCH64_BREAK_FAULT;
		}
		}
	}
	}


@@ -395,9 +398,12 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
{
{
	int shift;
	int shift;


	if (insn == AARCH64_BREAK_FAULT)
		return AARCH64_BREAK_FAULT;

	if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) {
	if (reg < AARCH64_INSN_REG_0 || reg > AARCH64_INSN_REG_SP) {
		pr_err("%s: unknown register encoding %d\n", __func__, reg);
		pr_err("%s: unknown register encoding %d\n", __func__, reg);
		return 0;
		return AARCH64_BREAK_FAULT;
	}
	}


	switch (type) {
	switch (type) {
@@ -418,7 +424,7 @@ static u32 aarch64_insn_encode_register(enum aarch64_insn_register_type type,
	default:
	default:
		pr_err("%s: unknown register type encoding %d\n", __func__,
		pr_err("%s: unknown register type encoding %d\n", __func__,
		       type);
		       type);
		return 0;
		return AARCH64_BREAK_FAULT;
	}
	}


	insn &= ~(GENMASK(4, 0) << shift);
	insn &= ~(GENMASK(4, 0) << shift);
@@ -447,7 +453,7 @@ static u32 aarch64_insn_encode_ldst_size(enum aarch64_insn_size_type type,
		break;
		break;
	default:
	default:
		pr_err("%s: unknown size encoding %d\n", __func__, type);
		pr_err("%s: unknown size encoding %d\n", __func__, type);
		return 0;
		return AARCH64_BREAK_FAULT;
	}
	}


	insn &= ~GENMASK(31, 30);
	insn &= ~GENMASK(31, 30);
@@ -461,14 +467,17 @@ static inline long branch_imm_common(unsigned long pc, unsigned long addr,
{
{
	long offset;
	long offset;


	/*
	if ((pc & 0x3) || (addr & 0x3)) {
	 * PC: A 64-bit Program Counter holding the address of the current
		pr_err("%s: A64 instructions must be word aligned\n", __func__);
	 * instruction. A64 instructions must be word-aligned.
		return range;
	 */
	}
	BUG_ON((pc & 0x3) || (addr & 0x3));


	offset = ((long)addr - (long)pc);
	offset = ((long)addr - (long)pc);
	BUG_ON(offset < -range || offset >= range);

	if (offset < -range || offset >= range) {
		pr_err("%s: offset out of range\n", __func__);
		return range;
	}


	return offset;
	return offset;
}
}
@@ -485,6 +494,8 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
	 * texts are within +/-128M.
	 * texts are within +/-128M.
	 */
	 */
	offset = branch_imm_common(pc, addr, SZ_128M);
	offset = branch_imm_common(pc, addr, SZ_128M);
	if (offset >= SZ_128M)
		return AARCH64_BREAK_FAULT;


	switch (type) {
	switch (type) {
	case AARCH64_INSN_BRANCH_LINK:
	case AARCH64_INSN_BRANCH_LINK:
@@ -494,7 +505,7 @@ u32 __kprobes aarch64_insn_gen_branch_imm(unsigned long pc, unsigned long addr,
		insn = aarch64_insn_get_b_value();
		insn = aarch64_insn_get_b_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown branch encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -511,6 +522,8 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
	long offset;
	long offset;


	offset = branch_imm_common(pc, addr, SZ_1M);
	offset = branch_imm_common(pc, addr, SZ_1M);
	if (offset >= SZ_1M)
		return AARCH64_BREAK_FAULT;


	switch (type) {
	switch (type) {
	case AARCH64_INSN_BRANCH_COMP_ZERO:
	case AARCH64_INSN_BRANCH_COMP_ZERO:
@@ -520,7 +533,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
		insn = aarch64_insn_get_cbnz_value();
		insn = aarch64_insn_get_cbnz_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown branch encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -531,7 +544,7 @@ u32 aarch64_insn_gen_comp_branch_imm(unsigned long pc, unsigned long addr,
		insn |= AARCH64_INSN_SF_BIT;
		insn |= AARCH64_INSN_SF_BIT;
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -551,7 +564,10 @@ u32 aarch64_insn_gen_cond_branch_imm(unsigned long pc, unsigned long addr,


	insn = aarch64_insn_get_bcond_value();
	insn = aarch64_insn_get_bcond_value();


	BUG_ON(cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL);
	if (cond < AARCH64_INSN_COND_EQ || cond > AARCH64_INSN_COND_AL) {
		pr_err("%s: unknown condition encoding %d\n", __func__, cond);
		return AARCH64_BREAK_FAULT;
	}
	insn |= cond;
	insn |= cond;


	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
	return aarch64_insn_encode_immediate(AARCH64_INSN_IMM_19, insn,
@@ -584,7 +600,7 @@ u32 aarch64_insn_gen_branch_reg(enum aarch64_insn_register reg,
		insn = aarch64_insn_get_ret_value();
		insn = aarch64_insn_get_ret_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown branch encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -607,7 +623,7 @@ u32 aarch64_insn_gen_load_store_reg(enum aarch64_insn_register reg,
		insn = aarch64_insn_get_str_reg_value();
		insn = aarch64_insn_get_str_reg_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown load/store encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -646,26 +662,30 @@ u32 aarch64_insn_gen_load_store_pair(enum aarch64_insn_register reg1,
		insn = aarch64_insn_get_stp_post_value();
		insn = aarch64_insn_get_stp_post_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown load/store encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


	switch (variant) {
	switch (variant) {
	case AARCH64_INSN_VARIANT_32BIT:
	case AARCH64_INSN_VARIANT_32BIT:
		/* offset must be multiples of 4 in the range [-256, 252] */
		if ((offset & 0x3) || (offset < -256) || (offset > 252)) {
		BUG_ON(offset & 0x3);
			pr_err("%s: offset must be multiples of 4 in the range of [-256, 252] %d\n",
		BUG_ON(offset < -256 || offset > 252);
			       __func__, offset);
			return AARCH64_BREAK_FAULT;
		}
		shift = 2;
		shift = 2;
		break;
		break;
	case AARCH64_INSN_VARIANT_64BIT:
	case AARCH64_INSN_VARIANT_64BIT:
		/* offset must be multiples of 8 in the range [-512, 504] */
		if ((offset & 0x7) || (offset < -512) || (offset > 504)) {
		BUG_ON(offset & 0x7);
			pr_err("%s: offset must be multiples of 8 in the range of [-512, 504] %d\n",
		BUG_ON(offset < -512 || offset > 504);
			       __func__, offset);
			return AARCH64_BREAK_FAULT;
		}
		shift = 3;
		shift = 3;
		insn |= AARCH64_INSN_SF_BIT;
		insn |= AARCH64_INSN_SF_BIT;
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -703,7 +723,7 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
		insn = aarch64_insn_get_subs_imm_value();
		insn = aarch64_insn_get_subs_imm_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -714,11 +734,14 @@ u32 aarch64_insn_gen_add_sub_imm(enum aarch64_insn_register dst,
		insn |= AARCH64_INSN_SF_BIT;
		insn |= AARCH64_INSN_SF_BIT;
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


	BUG_ON(imm & ~(SZ_4K - 1));
	if (imm & ~(SZ_4K - 1)) {
		pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
		return AARCH64_BREAK_FAULT;
	}


	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);


@@ -747,7 +770,7 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
		insn = aarch64_insn_get_sbfm_value();
		insn = aarch64_insn_get_sbfm_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown bitfield encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -760,12 +783,18 @@ u32 aarch64_insn_gen_bitfield(enum aarch64_insn_register dst,
		mask = GENMASK(5, 0);
		mask = GENMASK(5, 0);
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


	BUG_ON(immr & ~mask);
	if (immr & ~mask) {
	BUG_ON(imms & ~mask);
		pr_err("%s: invalid immr encoding %d\n", __func__, immr);
		return AARCH64_BREAK_FAULT;
	}
	if (imms & ~mask) {
		pr_err("%s: invalid imms encoding %d\n", __func__, imms);
		return AARCH64_BREAK_FAULT;
	}


	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);
	insn = aarch64_insn_encode_register(AARCH64_INSN_REGTYPE_RD, insn, dst);


@@ -794,23 +823,33 @@ u32 aarch64_insn_gen_movewide(enum aarch64_insn_register dst,
		insn = aarch64_insn_get_movn_value();
		insn = aarch64_insn_get_movn_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown movewide encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


	BUG_ON(imm & ~(SZ_64K - 1));
	if (imm & ~(SZ_64K - 1)) {
		pr_err("%s: invalid immediate encoding %d\n", __func__, imm);
		return AARCH64_BREAK_FAULT;
	}


	switch (variant) {
	switch (variant) {
	case AARCH64_INSN_VARIANT_32BIT:
	case AARCH64_INSN_VARIANT_32BIT:
		BUG_ON(shift != 0 && shift != 16);
		if (shift != 0 && shift != 16) {
			pr_err("%s: invalid shift encoding %d\n", __func__,
			       shift);
			return AARCH64_BREAK_FAULT;
		}
		break;
		break;
	case AARCH64_INSN_VARIANT_64BIT:
	case AARCH64_INSN_VARIANT_64BIT:
		insn |= AARCH64_INSN_SF_BIT;
		insn |= AARCH64_INSN_SF_BIT;
		BUG_ON(shift != 0 && shift != 16 && shift != 32 &&
		if (shift != 0 && shift != 16 && shift != 32 && shift != 48) {
		       shift != 48);
			pr_err("%s: invalid shift encoding %d\n", __func__,
			       shift);
			return AARCH64_BREAK_FAULT;
		}
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -844,20 +883,28 @@ u32 aarch64_insn_gen_add_sub_shifted_reg(enum aarch64_insn_register dst,
		insn = aarch64_insn_get_subs_value();
		insn = aarch64_insn_get_subs_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown add/sub encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


	switch (variant) {
	switch (variant) {
	case AARCH64_INSN_VARIANT_32BIT:
	case AARCH64_INSN_VARIANT_32BIT:
		BUG_ON(shift & ~(SZ_32 - 1));
		if (shift & ~(SZ_32 - 1)) {
			pr_err("%s: invalid shift encoding %d\n", __func__,
			       shift);
			return AARCH64_BREAK_FAULT;
		}
		break;
		break;
	case AARCH64_INSN_VARIANT_64BIT:
	case AARCH64_INSN_VARIANT_64BIT:
		insn |= AARCH64_INSN_SF_BIT;
		insn |= AARCH64_INSN_SF_BIT;
		BUG_ON(shift & ~(SZ_64 - 1));
		if (shift & ~(SZ_64 - 1)) {
			pr_err("%s: invalid shift encoding %d\n", __func__,
			       shift);
			return AARCH64_BREAK_FAULT;
		}
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -886,11 +933,15 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
		insn = aarch64_insn_get_rev32_value();
		insn = aarch64_insn_get_rev32_value();
		break;
		break;
	case AARCH64_INSN_DATA1_REVERSE_64:
	case AARCH64_INSN_DATA1_REVERSE_64:
		BUG_ON(variant != AARCH64_INSN_VARIANT_64BIT);
		if (variant != AARCH64_INSN_VARIANT_64BIT) {
			pr_err("%s: invalid variant for reverse64 %d\n",
			       __func__, variant);
			return AARCH64_BREAK_FAULT;
		}
		insn = aarch64_insn_get_rev64_value();
		insn = aarch64_insn_get_rev64_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown data1 encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -901,7 +952,7 @@ u32 aarch64_insn_gen_data1(enum aarch64_insn_register dst,
		insn |= AARCH64_INSN_SF_BIT;
		insn |= AARCH64_INSN_SF_BIT;
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -938,7 +989,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
		insn = aarch64_insn_get_rorv_value();
		insn = aarch64_insn_get_rorv_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown data2 encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -949,7 +1000,7 @@ u32 aarch64_insn_gen_data2(enum aarch64_insn_register dst,
		insn |= AARCH64_INSN_SF_BIT;
		insn |= AARCH64_INSN_SF_BIT;
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -977,7 +1028,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
		insn = aarch64_insn_get_msub_value();
		insn = aarch64_insn_get_msub_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown data3 encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -988,7 +1039,7 @@ u32 aarch64_insn_gen_data3(enum aarch64_insn_register dst,
		insn |= AARCH64_INSN_SF_BIT;
		insn |= AARCH64_INSN_SF_BIT;
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


@@ -1038,20 +1089,28 @@ u32 aarch64_insn_gen_logical_shifted_reg(enum aarch64_insn_register dst,
		insn = aarch64_insn_get_bics_value();
		insn = aarch64_insn_get_bics_value();
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown logical encoding %d\n", __func__, type);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}


	switch (variant) {
	switch (variant) {
	case AARCH64_INSN_VARIANT_32BIT:
	case AARCH64_INSN_VARIANT_32BIT:
		BUG_ON(shift & ~(SZ_32 - 1));
		if (shift & ~(SZ_32 - 1)) {
			pr_err("%s: invalid shift encoding %d\n", __func__,
			       shift);
			return AARCH64_BREAK_FAULT;
		}
		break;
		break;
	case AARCH64_INSN_VARIANT_64BIT:
	case AARCH64_INSN_VARIANT_64BIT:
		insn |= AARCH64_INSN_SF_BIT;
		insn |= AARCH64_INSN_SF_BIT;
		BUG_ON(shift & ~(SZ_64 - 1));
		if (shift & ~(SZ_64 - 1)) {
			pr_err("%s: invalid shift encoding %d\n", __func__,
			       shift);
			return AARCH64_BREAK_FAULT;
		}
		break;
		break;
	default:
	default:
		BUG_ON(1);
		pr_err("%s: unknown variant encoding %d\n", __func__, variant);
		return AARCH64_BREAK_FAULT;
		return AARCH64_BREAK_FAULT;
	}
	}