All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] powerpc: Fix Little Endian Bugs in Single Step Code
@ 2013-10-18 19:38 Tom Musta
  2013-10-18 19:40 ` [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode Tom Musta
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Tom Musta @ 2013-10-18 19:38 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: tmusta

This patch series addresses bugs in the PowerPC single-step emulation
code (arch/powerpc/lib/sstep.c) pertaining to Little Endian.

The existing code has a chicken switch for little endian.  The first
patch softens the restriction so that only cross-endian modes are not
supported.

There is a general problem with unaligned little endian loads and stores.
This is addressed by the second patch.

Finally, there is a problem with unaligned single precision floating point
loads and stores which is addressed by the third patch.

Tom Musta (3):
  powerpc: Enable emulate_step In Little Endian Mode
  powerpc: Fix Unaligned Fixed Point Loads and Stores
  powerpc: Fix Unaligned LE Floating Point Loads and Stores

 arch/powerpc/lib/sstep.c |  109 +++++++++++++++++++++++++++++++++++++++------
 1 files changed, 94 insertions(+), 15 deletions(-)

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

* [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode
  2013-10-18 19:38 [PATCH 0/3] powerpc: Fix Little Endian Bugs in Single Step Code Tom Musta
@ 2013-10-18 19:40 ` Tom Musta
  2013-10-30  0:13   ` Benjamin Herrenschmidt
  2013-10-30 17:43   ` Andreas Schwab
  2013-10-18 19:42 ` [PATCH 2/3] powerpc: Fix Unaligned Loads and Stores Tom Musta
  2013-10-18 19:44 ` [PATCH 3/3] powerpc: Fix Unaligned LE Floating Point " Tom Musta
  2 siblings, 2 replies; 9+ messages in thread
From: Tom Musta @ 2013-10-18 19:40 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: tmusta

This patch modifies the endian chicken switch in the single step
emulation code (emulate_step()).  The old (big endian) code bailed
early if a load or store instruction was to be emulated in little
endian mode.

The new code modifies the check and only bails in a cross-endian
situation (LE mode in a kernel compiled for BE and vice verse).

Signed-off-by: Tom Musta <tmusta@gmail.com>
---
 arch/powerpc/lib/sstep.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index b1faa15..5e0d0e9 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -1222,12 +1222,18 @@ int __kprobes emulate_step(struct pt_regs *regs,
unsigned int instr)
 	}
 
 	/*
-	 * Following cases are for loads and stores, so bail out
-	 * if we're in little-endian mode.
+	 * Following cases are for loads and stores and this
+	 * implementation does not support cross-endian.  So
+	 * bail out if this is the case.
 	 */
+#ifdef __BIG_ENDIAN__
 	if (regs->msr & MSR_LE)
 		return 0;
-
+#endif
+#ifdef __LITTLE_ENDIAN__
+	if (!regs->msr & MSR_LE)
+		return 0;
+#endif
 	/*
 	 * Save register RA in case it's an update form load or store
 	 * and the access faults.
-- 
1.7.1

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

* [PATCH 2/3] powerpc: Fix Unaligned Loads and Stores
  2013-10-18 19:38 [PATCH 0/3] powerpc: Fix Little Endian Bugs in Single Step Code Tom Musta
  2013-10-18 19:40 ` [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode Tom Musta
@ 2013-10-18 19:42 ` Tom Musta
  2013-10-18 19:44 ` [PATCH 3/3] powerpc: Fix Unaligned LE Floating Point " Tom Musta
  2 siblings, 0 replies; 9+ messages in thread
From: Tom Musta @ 2013-10-18 19:42 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: tmusta

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.   This is implemented by
breaking an unaligned little endian access into a combination of
single byte accesses plus an overal byte reversal operation.

Signed-off-by: Tom Musta <tmusta@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 5e0d0e9..570f2af 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);
-- 
1.7.1

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

* [PATCH 3/3] powerpc: Fix Unaligned LE Floating Point Loads and Stores
  2013-10-18 19:38 [PATCH 0/3] powerpc: Fix Little Endian Bugs in Single Step Code Tom Musta
  2013-10-18 19:40 ` [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode Tom Musta
  2013-10-18 19:42 ` [PATCH 2/3] powerpc: Fix Unaligned Loads and Stores Tom Musta
@ 2013-10-18 19:44 ` Tom Musta
  2 siblings, 0 replies; 9+ messages in thread
From: Tom Musta @ 2013-10-18 19:44 UTC (permalink / raw)
  To: linuxppc-dev; +Cc: tmusta

This patch addresses unaligned single precision floating point loads
and stores in the single-step code.  The old implementation
improperly treated an 8 byte structure as an array of two 4 byte
words, which is a classic little endian bug.

Signed-off-by: Tom Musta <tmusta@gmail.com>
---
 arch/powerpc/lib/sstep.c |   52 +++++++++++++++++++++++++++++++++++----------
 1 files changed, 40 insertions(+), 12 deletions(-)

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 570f2af..f6f17aa 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -355,22 +355,36 @@ static int __kprobes do_fp_load(int rn, int (*func)(int, unsigned long),
 				struct pt_regs *regs)
 {
 	int err;
-	unsigned long val[sizeof(double) / sizeof(long)];
+	union {
+		double dbl;
+		unsigned long ul[2];
+		struct {
+#ifdef __BIG_ENDIAN__
+			unsigned _pad_;
+			unsigned word;
+#endif
+#ifdef __LITTLE_ENDIAN__
+			unsigned word;
+			unsigned _pad_;
+#endif
+		} single;
+	} data;
 	unsigned long ptr;
 
 	if (!address_ok(regs, ea, nb))
 		return -EFAULT;
 	if ((ea & 3) == 0)
 		return (*func)(rn, ea);
-	ptr = (unsigned long) &val[0];
+	ptr = (unsigned long) &data.ul;
 	if (sizeof(unsigned long) == 8 || nb == 4) {
-		err = read_mem_unaligned(&val[0], ea, nb, regs);
-		ptr += sizeof(unsigned long) - nb;
+		err = read_mem_unaligned(&data.ul[0], ea, nb, regs);
+		if (nb == 4)
+			ptr = (unsigned long)&(data.single.word);
 	} else {
 		/* reading a double on 32-bit */
-		err = read_mem_unaligned(&val[0], ea, 4, regs);
+		err = read_mem_unaligned(&data.ul[0], ea, 4, regs);
 		if (!err)
-			err = read_mem_unaligned(&val[1], ea + 4, 4, regs);
+			err = read_mem_unaligned(&data.ul[1], ea + 4, 4, regs);
 	}
 	if (err)
 		return err;
@@ -382,28 +396,42 @@ static int __kprobes do_fp_store(int rn, int (*func)(int, unsigned long),
 				 struct pt_regs *regs)
 {
 	int err;
-	unsigned long val[sizeof(double) / sizeof(long)];
+	union {
+		double dbl;
+		unsigned long ul[2];
+		struct {
+#ifdef __BIG_ENDIAN__
+			unsigned _pad_;
+			unsigned word;
+#endif
+#ifdef __LITTLE_ENDIAN__
+			unsigned word;
+			unsigned _pad_;
+#endif
+		} single;
+	} data;
 	unsigned long ptr;
 
 	if (!address_ok(regs, ea, nb))
 		return -EFAULT;
 	if ((ea & 3) == 0)
 		return (*func)(rn, ea);
-	ptr = (unsigned long) &val[0];
+	ptr = (unsigned long) &data.ul[0];
 	if (sizeof(unsigned long) == 8 || nb == 4) {
-		ptr += sizeof(unsigned long) - nb;
+		if (nb == 4)
+			ptr = (unsigned long)&(data.single.word);
 		err = (*func)(rn, ptr);
 		if (err)
 			return err;
-		err = write_mem_unaligned(val[0], ea, nb, regs);
+		err = write_mem_unaligned(data.ul[0], ea, nb, regs);
 	} else {
 		/* writing a double on 32-bit */
 		err = (*func)(rn, ptr);
 		if (err)
 			return err;
-		err = write_mem_unaligned(val[0], ea, 4, regs);
+		err = write_mem_unaligned(data.ul[0], ea, 4, regs);
 		if (!err)
-			err = write_mem_unaligned(val[1], ea + 4, 4, regs);
+			err = write_mem_unaligned(data.ul[1], ea + 4, 4, regs);
 	}
 	return err;
 }
-- 
1.7.1

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

* Re: [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode
  2013-10-18 19:40 ` [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode Tom Musta
@ 2013-10-30  0:13   ` Benjamin Herrenschmidt
  2013-10-30 17:43   ` Andreas Schwab
  1 sibling, 0 replies; 9+ messages in thread
From: Benjamin Herrenschmidt @ 2013-10-30  0:13 UTC (permalink / raw)
  To: Tom Musta; +Cc: tmusta, linuxppc-dev

On Fri, 2013-10-18 at 14:40 -0500, Tom Musta wrote:
> This patch modifies the endian chicken switch in the single step
> emulation code (emulate_step()).  The old (big endian) code bailed
> early if a load or store instruction was to be emulated in little
> endian mode.
> 
> The new code modifies the check and only bails in a cross-endian
> situation (LE mode in a kernel compiled for BE and vice verse).

I get a malformed patch error, looks like it got wrapped.

Cheers,
Ben.

> Signed-off-by: Tom Musta <tmusta@gmail.com>
> ---
>  arch/powerpc/lib/sstep.c |   12 +++++++++---
>  1 files changed, 9 insertions(+), 3 deletions(-)
> 
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index b1faa15..5e0d0e9 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -1222,12 +1222,18 @@ int __kprobes emulate_step(struct pt_regs *regs,
> unsigned int instr)
>  	}
>  
>  	/*
> -	 * Following cases are for loads and stores, so bail out
> -	 * if we're in little-endian mode.
> +	 * Following cases are for loads and stores and this
> +	 * implementation does not support cross-endian.  So
> +	 * bail out if this is the case.
>  	 */
> +#ifdef __BIG_ENDIAN__
>  	if (regs->msr & MSR_LE)
>  		return 0;
> -
> +#endif
> +#ifdef __LITTLE_ENDIAN__
> +	if (!regs->msr & MSR_LE)
> +		return 0;
> +#endif
>  	/*
>  	 * Save register RA in case it's an update form load or store
>  	 * and the access faults.

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

* Re: [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode
  2013-10-18 19:40 ` [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode Tom Musta
  2013-10-30  0:13   ` Benjamin Herrenschmidt
@ 2013-10-30 17:43   ` Andreas Schwab
  2013-10-30 19:35     ` Tom Musta
  1 sibling, 1 reply; 9+ messages in thread
From: Andreas Schwab @ 2013-10-30 17:43 UTC (permalink / raw)
  To: Tom Musta; +Cc: tmusta, linuxppc-dev

Tom Musta <tommusta@gmail.com> writes:

> +#ifdef __LITTLE_ENDIAN__
> +	if (!regs->msr & MSR_LE)

That won't work.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

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

* Re: [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode
  2013-10-30 17:43   ` Andreas Schwab
@ 2013-10-30 19:35     ` Tom Musta
  2013-10-30 19:43       ` Geert Uytterhoeven
  0 siblings, 1 reply; 9+ messages in thread
From: Tom Musta @ 2013-10-30 19:35 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: tmusta, linuxppc-dev

On 10/30/2013 12:43 PM, Andreas Schwab wrote:
> Tom Musta <tommusta@gmail.com> writes:
>
>> +#ifdef __LITTLE_ENDIAN__
>> +	if (!regs->msr & MSR_LE)
>
> That won't work.
>
> Andreas.
>

Please elaborate.

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

* Re: [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode
  2013-10-30 19:35     ` Tom Musta
@ 2013-10-30 19:43       ` Geert Uytterhoeven
  2013-10-30 21:45         ` Tom Musta
  0 siblings, 1 reply; 9+ messages in thread
From: Geert Uytterhoeven @ 2013-10-30 19:43 UTC (permalink / raw)
  To: Tom Musta; +Cc: linuxppc-dev, tmusta, Andreas Schwab

On Wed, Oct 30, 2013 at 8:35 PM, Tom Musta <tommusta@gmail.com> wrote:
> On 10/30/2013 12:43 PM, Andreas Schwab wrote:
>>
>> Tom Musta <tommusta@gmail.com> writes:
>>
>>> +#ifdef __LITTLE_ENDIAN__
>>> +       if (!regs->msr & MSR_LE)
>>
>>
>> That won't work.
>>
>> Andreas.
>>
>
> Please elaborate.

You want to test for "!(regs & MSR_LE)".

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode
  2013-10-30 19:43       ` Geert Uytterhoeven
@ 2013-10-30 21:45         ` Tom Musta
  0 siblings, 0 replies; 9+ messages in thread
From: Tom Musta @ 2013-10-30 21:45 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: linuxppc-dev, tmusta, Andreas Schwab

On 10/30/2013 2:43 PM, Geert Uytterhoeven wrote:
> On Wed, Oct 30, 2013 at 8:35 PM, Tom Musta <tommusta@gmail.com> wrote:
>> On 10/30/2013 12:43 PM, Andreas Schwab wrote:
>>>
>>> Tom Musta <tommusta@gmail.com> writes:
>>>
>>>> +#ifdef __LITTLE_ENDIAN__
>>>> +       if (!regs->msr & MSR_LE)
>>>
>>>
>>> That won't work.
>>>
>>> Andreas.
>>>
>>
>> Please elaborate.
>
> You want to test for "!(regs & MSR_LE)".
>
> Gr{oetje,eeting}s,
>
>                          Geert
>
> --
> Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org
>
> In personal conversations with technical people, I call myself a hacker. But
> when I'm talking to journalists I just say "programmer" or something like that.
>                                  -- Linus Torvalds
>

Thanks Adnreas and Geert.  I will fix and resubmit.

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

end of thread, other threads:[~2013-10-30 21:46 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-10-18 19:38 [PATCH 0/3] powerpc: Fix Little Endian Bugs in Single Step Code Tom Musta
2013-10-18 19:40 ` [PATCH 1/3] powerpc: Enable emulate_step In Little Endian Mode Tom Musta
2013-10-30  0:13   ` Benjamin Herrenschmidt
2013-10-30 17:43   ` Andreas Schwab
2013-10-30 19:35     ` Tom Musta
2013-10-30 19:43       ` Geert Uytterhoeven
2013-10-30 21:45         ` Tom Musta
2013-10-18 19:42 ` [PATCH 2/3] powerpc: Fix Unaligned Loads and Stores Tom Musta
2013-10-18 19:44 ` [PATCH 3/3] powerpc: Fix Unaligned LE Floating Point " Tom Musta

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.