linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* alignment handler instruction endian-ness
@ 2013-07-19 10:58 Ben Dooks
  2013-07-19 11:09 ` Russell King - ARM Linux
  0 siblings, 1 reply; 12+ messages in thread
From: Ben Dooks @ 2013-07-19 10:58 UTC (permalink / raw)
  To: linux-arm-kernel

I ran in to an issue with the alignment handler when running BE8 where
it loads instructions and fails to swap.

Is there a better way of swapping instructions for ARM when loading
from arbitrary places? Have I missed any other places this could happen?

The following patch is my first attempt at solving the problem for the
alignment handler:

> Author: Ben Dooks <ben.dooks@codethink.co.uk>
> Date:   Thu Jul 18 21:10:56 2013 +0100
>
>     arm: alignment: deal with be8 mode when decoding instructions
>
>     If we are in BE8 mode, we must deal with the instruction stream being
>     in LE order when data is being loaded in BE order. Ensure the data is
>     swapped before processing to avoid thre following:
>
>     Alignment trap: not handling instruction 030091e8 at [<80333e8c>]
>     Unhandled fault: alignment exception (0x001) at 0xbfa09567
>
>     Signed-off-by: Ben Dooks <ben.dooks@codethink.co.uk>
 >
> diff --git a/arch/arm/mm/alignment.c b/arch/arm/mm/alignment.c
> index db26e2e..e8793a7 100644
> --- a/arch/arm/mm/alignment.c
> +++ b/arch/arm/mm/alignment.c
> @@ -87,6 +87,12 @@ core_param(alignment, ai_usermode, int, 0600);
>  #define UM_FIXUP       (1 << 1)
>  #define UM_SIGNAL      (1 << 2)
>
> +#ifdef CONFIG_CPU_ENDIAN_BE8
> +#define need_swap()    true
> +#else
> +#define need_swap()    false
> +#endif
> +
>  /* Return true if and only if the ARMv6 unaligned access model is in use. */
>  static bool cpu_is_v6_unaligned(void)
>  {
> @@ -762,12 +768,16 @@ do_alignment(unsigned long addr, unsigned int fsr, struct
>         if (thumb_mode(regs)) {
>                 u16 *ptr = (u16 *)(instrptr & ~1);
>                 fault = probe_kernel_address(ptr, tinstr);
> +               if (need_swap())
> +                       tinstr = cpu_to_le16(tinstr);
>                 if (!fault) {
>                         if (cpu_architecture() >= CPU_ARCH_ARMv7 &&
>                             IS_T32(tinstr)) {
>                                 /* Thumb-2 32-bit */
>                                 u16 tinst2 = 0;
>                                 fault = probe_kernel_address(ptr + 1, tinst2);
> +                               if (need_swap())
> +                                       tinst2 = cpu_to_le16(tinst2);
>                                 instr = (tinstr << 16) | tinst2;
>                                 thumb2_32b = 1;
>                         } else {
> @@ -775,8 +785,11 @@ do_alignment(unsigned long addr, unsigned int fsr, struct p
>                                 instr = thumb2arm(tinstr);
>                         }
>                 }
> -       } else
> +       } else {
>                 fault = probe_kernel_address(instrptr, instr);
> +               if (need_swap())
> +                       instr = cpu_to_le32(instr);
> +       }
>
>         if (fault) {
>                 type = TYPE_FAULT;


-- 
Ben Dooks				http://www.codethink.co.uk/
Senior Engineer				Codethink - Providing Genius

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2013-07-22 18:34 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-07-19 10:58 alignment handler instruction endian-ness Ben Dooks
2013-07-19 11:09 ` Russell King - ARM Linux
2013-07-19 11:26   ` Ben Dooks
2013-07-19 12:15   ` Ben Dooks
2013-07-19 12:32     ` Russell King - ARM Linux
2013-07-19 13:19       ` Ben Dooks
2013-07-22 18:31         ` Nicolas Pitre
2013-07-22 18:34           ` Ben Dooks
2013-07-19 14:01   ` Jon Medhurst (Tixy)
2013-07-19 14:05     ` Russell King - ARM Linux
2013-07-19 14:50       ` Ben Dooks
2013-07-19 14:56         ` Russell King - ARM Linux

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).