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

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

Merge "ARM: fix user unalignment prefetch abort"

parents 86a8b18a de51ecb8
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -675,6 +675,21 @@ config SWP_EMULATE

	  If unsure, say Y.

config FORCE_INSTRUCTION_ALIGNMENT
	bool "Force instructions address alignment"
	depends on CPU_V7 && ALIGNMENT_TRAP
	help
	  Branching to an address in ARM state which is not word aligned,
	  where this is defined to be UNPREDICTABLE, can cause one of the
	  following two behaviours: 1. The unaligned location is forced to
	  be aligned. 2. Using the unaligned address generates a Prefetch
	  Abort on the first instruction using the unaligned PC value.

	  To be consistant for the user space binaries, the unaligned location
	  is forced aligned with this config.

	  If unsure, say Y.

config CPU_BIG_ENDIAN
	bool "Build big-endian kernel"
	depends on ARCH_SUPPORTS_BIG_ENDIAN
+35 −0
Original line number Diff line number Diff line
@@ -742,6 +742,36 @@ do_alignment_t32_to_handler(unsigned long *pinstr, struct pt_regs *regs,
	return NULL;
}

#ifdef CONFIG_FORCE_INSTRUCTION_ALIGNMENT
static int
do_ialignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
	/*
	 * Branching to an address in ARM state which is not word aligned,
	 * where this is defined to be UNPREDICTABLE,
	 * can cause one of the following two behaviours:
	 *     1. The unaligned location is forced to be aligned.
	 *     2. Using the unaligned address generates a Prefetch Abort on
	 *        the first instruction using the unaligned PC value.
	 */
	int isize = 4;

	if (user_mode(regs) && !thumb_mode(regs)) {
		ai_sys += 1;

		/*
		* Force align the instruction in software to be following
		* a single behaviour for the unpredicatable cases.
		*/
		instruction_pointer(regs) &= ~(isize + (-1UL));
		return 0;
	}

	ai_skipped += 1;
	return 1;
}
#endif

static int
do_alignment(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
{
@@ -973,6 +1003,11 @@ static int __init alignment_init(void)
	hook_fault_code(FAULT_CODE_ALIGNMENT, do_alignment, SIGBUS, BUS_ADRALN,
			"alignment exception");

#ifdef CONFIG_FORCE_INSTRUCTION_ALIGNMENT
	hook_ifault_code(FAULT_CODE_ALIGNMENT, do_ialignment, SIGBUS,
			BUS_ADRALN, "alignment exception");
#endif

	/*
	 * ARMv6K and ARMv7 use fault status 3 (0b00011) as Access Flag section
	 * fault, not as alignment error.