diff mbox

[1/2] powerpc: Fix emulation of mcrf in emulate_step()

Message ID 20170614234639.11997-1-anton@ozlabs.org (mailing list archive)
State Accepted
Commit 87c4b83e0fe234a1f0eed131ab6fa232036860d5
Headers show

Commit Message

Anton Blanchard June 14, 2017, 11:46 p.m. UTC
From: Anton Blanchard <anton@samba.org>

The mcrf emulation code was looking at the CR fields in the reverse
order. It also relied on reserved fields being zero which is somewhat
fragile, so fix that too.

Cc: stable@vger.kernel.org
Signed-off-by: Anton Blanchard <anton@samba.org>
---
 arch/powerpc/lib/sstep.c | 6 ++++--
 1 file changed, 4 insertions(+), 2 deletions(-)

Comments

Segher Boessenkool June 15, 2017, 4:18 a.m. UTC | #1
Hi Anton,

On Thu, Jun 15, 2017 at 09:46:38AM +1000, Anton Blanchard wrote:
> The mcrf emulation code was looking at the CR fields in the reverse
> order. It also relied on reserved fields being zero which is somewhat
> fragile, so fix that too.

It masked out the reserved bits.  I find the new code to be less
readable (but also more correct ;-) ).  Maybe there should be (inline)
helper function to insert/extract CR fields?


Segher


> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -683,8 +683,10 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
>  	case 19:
>  		switch ((instr >> 1) & 0x3ff) {
>  		case 0:		/* mcrf */
> -			rd = (instr >> 21) & 0x1c;
> -			ra = (instr >> 16) & 0x1c;
> +			rd = 7 - ((instr >> 23) & 0x7);
> +			ra = 7 - ((instr >> 18) & 0x7);
> +			rd *= 4;
> +			ra *= 4;
>  			val = (regs->ccr >> ra) & 0xf;
>  			regs->ccr = (regs->ccr & ~(0xfUL << rd)) | (val << rd);
>  			goto instr_done;
Anton Blanchard June 15, 2017, 6:47 a.m. UTC | #2
Hi Segher,

> On Thu, Jun 15, 2017 at 09:46:38AM +1000, Anton Blanchard wrote:
> > The mcrf emulation code was looking at the CR fields in the reverse
> > order. It also relied on reserved fields being zero which is
> > somewhat fragile, so fix that too.  
> 
> It masked out the reserved bits.  I find the new code to be less
> readable (but also more correct ;-) ). 

Thanks for that, not sure how I missed it :) I'll respin a simpler
patch.

> Maybe there should be (inline)
> helper function to insert/extract CR fields?

That would be nice, there are quite a few places that could use it.

Anton

> Segher
> 
> 
> > --- a/arch/powerpc/lib/sstep.c
> > +++ b/arch/powerpc/lib/sstep.c
> > @@ -683,8 +683,10 @@ int analyse_instr(struct instruction_op *op,
> > struct pt_regs *regs, case 19:
> >  		switch ((instr >> 1) & 0x3ff) {
> >  		case 0:		/* mcrf */
> > -			rd = (instr >> 21) & 0x1c;
> > -			ra = (instr >> 16) & 0x1c;
> > +			rd = 7 - ((instr >> 23) & 0x7);
> > +			ra = 7 - ((instr >> 18) & 0x7);
> > +			rd *= 4;
> > +			ra *= 4;
> >  			val = (regs->ccr >> ra) & 0xf;
> >  			regs->ccr = (regs->ccr & ~(0xfUL << rd)) |
> > (val << rd); goto instr_done;  
>
Segher Boessenkool June 15, 2017, 8:41 a.m. UTC | #3
On Thu, Jun 15, 2017 at 04:47:29PM +1000, Anton Blanchard wrote:
> > Maybe there should be (inline)
> > helper function to insert/extract CR fields?
> 
> That would be nice, there are quite a few places that could use it.

Like patch 2/2, hint hint.


Segher
Naveen N. Rao June 15, 2017, 5:27 p.m. UTC | #4
On 2017/06/15 09:46AM, Anton Blanchard wrote:
> From: Anton Blanchard <anton@samba.org>
> 
> The mcrf emulation code was looking at the CR fields in the reverse
> order. It also relied on reserved fields being zero which is somewhat
> fragile, so fix that too.

Yikes! Amazing catch!
Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>

Thanks,
Naveen

> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Anton Blanchard <anton@samba.org>
> ---
>  arch/powerpc/lib/sstep.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
> index 33117f8a0882..fb84f51b1f0b 100644
> --- a/arch/powerpc/lib/sstep.c
> +++ b/arch/powerpc/lib/sstep.c
> @@ -683,8 +683,10 @@ int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
>  	case 19:
>  		switch ((instr >> 1) & 0x3ff) {
>  		case 0:		/* mcrf */
> -			rd = (instr >> 21) & 0x1c;
> -			ra = (instr >> 16) & 0x1c;
> +			rd = 7 - ((instr >> 23) & 0x7);
> +			ra = 7 - ((instr >> 18) & 0x7);
> +			rd *= 4;
> +			ra *= 4;
>  			val = (regs->ccr >> ra) & 0xf;
>  			regs->ccr = (regs->ccr & ~(0xfUL << rd)) | (val << rd);
>  			goto instr_done;
> -- 
> 2.11.0
>
Michael Ellerman July 13, 2017, 12:46 p.m. UTC | #5
On Wed, 2017-06-14 at 23:46:38 UTC, Anton Blanchard wrote:
> From: Anton Blanchard <anton@samba.org>
> 
> The mcrf emulation code was looking at the CR fields in the reverse
> order. It also relied on reserved fields being zero which is somewhat
> fragile, so fix that too.
> 
> Cc: stable@vger.kernel.org
> Signed-off-by: Anton Blanchard <anton@samba.org>
> Acked-by: Naveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>

Applied to powerpc fixes, thanks.

https://git.kernel.org/powerpc/c/87c4b83e0fe234a1f0eed131ab6fa2

cheers
diff mbox

Patch

diff --git a/arch/powerpc/lib/sstep.c b/arch/powerpc/lib/sstep.c
index 33117f8a0882..fb84f51b1f0b 100644
--- a/arch/powerpc/lib/sstep.c
+++ b/arch/powerpc/lib/sstep.c
@@ -683,8 +683,10 @@  int analyse_instr(struct instruction_op *op, struct pt_regs *regs,
 	case 19:
 		switch ((instr >> 1) & 0x3ff) {
 		case 0:		/* mcrf */
-			rd = (instr >> 21) & 0x1c;
-			ra = (instr >> 16) & 0x1c;
+			rd = 7 - ((instr >> 23) & 0x7);
+			ra = 7 - ((instr >> 18) & 0x7);
+			rd *= 4;
+			ra *= 4;
 			val = (regs->ccr >> ra) & 0xf;
 			regs->ccr = (regs->ccr & ~(0xfUL << rd)) | (val << rd);
 			goto instr_done;