[V2 PATCH 2/3] powerpc: Fix Unaligned Fixed Point Loads and Stores

Benjamin Herrenschmidt benh at kernel.crashing.org
Mon Nov 4 13:34:22 EST 2013


On Thu, 2013-10-31 at 13:38 -0500, Tom wrote:
> From: Tom Musta <tommusta at gmail.com>
> 
> This patch modifies the unaligned access routines of the sstep.c
> module so that it properly reverses the bytes of storage operands
> in the little endian kernel kernel.

Do that patch differ from v1 ? (I already merged v1)

Cheers,
Ben.
 
> Signed-off-by: Tom Musta <tommusta at gmail.com>
> ---
>  arch/powerpc/lib/sstep.c |   45 +++++++++++++++++++++++++++++++++++++++++++++
>  1 files changed, 45 insertions(+), 0 deletions(-)
> 
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index 7bfaa9d..c8743e1 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -212,11 +212,19 @@ static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea,
>  {
>  	int err;
>  	unsigned long x, b, c;
> +#ifdef __LITTLE_ENDIAN__
> +	int len = nb; /* save a copy of the length for byte reversal */
> +#endif
>  
>  	/* unaligned, do this in pieces */
>  	x = 0;
>  	for (; nb > 0; nb -= c) {
> +#ifdef __LITTLE_ENDIAN__
> +		c = 1;
> +#endif
> +#ifdef __BIG_ENDIAN__
>  		c = max_align(ea);
> +#endif
>  		if (c > nb)
>  			c = max_align(nb);
>  		err = read_mem_aligned(&b, ea, c);
> @@ -225,7 +233,24 @@ static int __kprobes read_mem_unaligned(unsigned long *dest, unsigned long ea,
>  		x = (x << (8 * c)) + b;
>  		ea += c;
>  	}
> +#ifdef __LITTLE_ENDIAN__
> +	switch (len) {
> +	case 2:
> +		*dest = byterev_2(x);
> +		break;
> +	case 4:
> +		*dest = byterev_4(x);
> +		break;
> +#ifdef __powerpc64__
> +	case 8:
> +		*dest = byterev_8(x);
> +		break;
> +#endif
> +	}
> +#endif
> +#ifdef __BIG_ENDIAN__
>  	*dest = x;
> +#endif
>  	return 0;
>  }
>  
> @@ -273,9 +298,29 @@ static int __kprobes write_mem_unaligned(unsigned long val, unsigned long ea,
>  	int err;
>  	unsigned long c;
>  
> +#ifdef __LITTLE_ENDIAN__
> +	switch (nb) {
> +	case 2:
> +		val = byterev_2(val);
> +		break;
> +	case 4:
> +		val = byterev_4(val);
> +		break;
> +#ifdef __powerpc64__
> +	case 8:
> +		val = byterev_8(val);
> +		break;
> +#endif
> +	}
> +#endif
>  	/* unaligned or little-endian, do this in pieces */
>  	for (; nb > 0; nb -= c) {
> +#ifdef __LITTLE_ENDIAN__
> +		c = 1;
> +#endif
> +#ifdef __BIG_ENDIAN__
>  		c = max_align(ea);
> +#endif
>  		if (c > nb)
>  			c = max_align(nb);
>  		err = write_mem_aligned(val >> (nb - c) * 8, ea, c);




More information about the Linuxppc-dev mailing list