Re: [PATCH] powerpc/32: Fix critical and debug interrupts on BOOKE

2021-08-13 Thread Michael Ellerman
On Wed, 7 Jul 2021 05:55:07 + (UTC), Christophe Leroy wrote:
> 32 bits BOOKE have special interrupts for debug and other
> critical events.
> 
> When handling those interrupts, dedicated registers are saved
> in the stack frame in addition to the standard registers, leading
> to a shift of the pt_regs struct.
> 
> [...]

Applied to powerpc/fixes.

[1/1] powerpc/32: Fix critical and debug interrupts on BOOKE
  https://git.kernel.org/powerpc/c/b5cfc9cd7b0426e94ffd9e9ed79d1b00ace7780a

cheers


Re: [PATCH] powerpc/32: Fix critical and debug interrupts on BOOKE

2021-08-04 Thread Radu Rendec
Hi Christophe,

On Wed, 2021-08-04 at 07:52 +0200, Christophe Leroy wrote:
> Le 07/07/2021 à 07:55, Christophe Leroy a écrit :
> > 32 bits BOOKE have special interrupts for debug and other
> > critical events.
> 
> Were you able to test this patch ?

I tested it three weeks ago and it works like a charm!

I'm so sorry I forgot to let you know. I got distracted testing the
old ptrace() problem. In fact, I wouldn't have been able to test that
if your interrupts patch hadn't been working.

Thanks,
Radu

> > When handling those interrupts, dedicated registers are saved
> > in the stack frame in addition to the standard registers, leading
> > to a shift of the pt_regs struct.
> > 
> > Since commit db297c3b07af ("powerpc/32: Don't save thread.regs on
> > interrupt entry"), the pt_regs struct is expected to be at the
> > same place all the time.
> > 
> > Instead of handling a special struct in addition to pt_regs, just
> > add those special registers to struct pt_regs.
> > 
> > Reported-by: Radu Rendec 
> > Signed-off-by: Christophe Leroy 
> > Fixes: db297c3b07af ("powerpc/32: Don't save thread.regs on
> > interrupt entry")
> > Cc: sta...@vger.kernel.org
> > ---
> >   arch/powerpc/include/asm/ptrace.h | 16 
> >   arch/powerpc/kernel/asm-offsets.c | 31
> > ++-
> >   arch/powerpc/kernel/head_booke.h  | 27
> > +++
> >   3 files changed, 33 insertions(+), 41 deletions(-)
> > 
> > diff --git a/arch/powerpc/include/asm/ptrace.h
> > b/arch/powerpc/include/asm/ptrace.h
> > index 3e5d470a6155..14422e851494 100644
> > --- a/arch/powerpc/include/asm/ptrace.h
> > +++ b/arch/powerpc/include/asm/ptrace.h
> > @@ -70,6 +70,22 @@ struct pt_regs
> > unsigned long __pad[4]; /* Maintain 16 byte
> > interrupt stack alignment */
> > };
> >   #endif
> > +#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
> > +   struct { /* Must be a multiple of 16 bytes */
> > +   unsigned long mas0;
> > +   unsigned long mas1;
> > +   unsigned long mas2;
> > +   unsigned long mas3;
> > +   unsigned long mas6;
> > +   unsigned long mas7;
> > +   unsigned long srr0;
> > +   unsigned long srr1;
> > +   unsigned long csrr0;
> > +   unsigned long csrr1;
> > +   unsigned long dsrr0;
> > +   unsigned long dsrr1;
> > +   };
> > +#endif
> >   };
> >   #endif
> >   
> > diff --git a/arch/powerpc/kernel/asm-offsets.c
> > b/arch/powerpc/kernel/asm-offsets.c
> > index a47eefa09bcb..5bee245d832b 100644
> > --- a/arch/powerpc/kernel/asm-offsets.c
> > +++ b/arch/powerpc/kernel/asm-offsets.c
> > @@ -309,24 +309,21 @@ int main(void)
> > STACK_PT_REGS_OFFSET(STACK_REGS_IAMR, iamr);
> >   #endif
> >   
> > -#if defined(CONFIG_PPC32)
> > -#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
> > -   DEFINE(EXC_LVL_SIZE, STACK_EXC_LVL_FRAME_SIZE);
> > -   DEFINE(MAS0, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, mas0));
> > +#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
> > +   STACK_PT_REGS_OFFSET(MAS0, mas0);
> > /* we overload MMUCR for 44x on MAS0 since they are
> > mutually exclusive */
> > -   DEFINE(MMUCR, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, mas0));
> > -   DEFINE(MAS1, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, mas1));
> > -   DEFINE(MAS2, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, mas2));
> > -   DEFINE(MAS3, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, mas3));
> > -   DEFINE(MAS6, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, mas6));
> > -   DEFINE(MAS7, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, mas7));
> > -   DEFINE(_SRR0, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, srr0));
> > -   DEFINE(_SRR1, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, srr1));
> > -   DEFINE(_CSRR0, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, csrr0));
> > -   DEFINE(_CSRR1, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, csrr1));
> > -   DEFINE(_DSRR0, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, dsrr0));
> > -   DEFINE(_DSRR1, STACK_INT_FRAME_SIZE+offsetof(struct
> > exception_regs, dsrr1));
> > -#endif
> > +   STACK_PT_REGS_OFFSET(MMUCR, mas0);
> > +   STACK_PT_REGS_OFFSET(MAS1, mas1);
> > +   STACK_PT_REGS_OFFSET(MAS2, mas2);
> > +   STACK_PT_REGS_OFFSET(MAS3, mas3);
> > +   STACK_PT_REGS_OFFSET(MAS6, mas6);
> > +   STACK_PT_REGS_OFFSET(MAS7, mas7);
> > +   STACK_PT_REGS_OFFSET(_SRR0, srr0);
> > +   STACK_PT_REGS_OFFSET(_SRR1, srr1);
> > +   STACK_PT_REGS_OFFSET(_CSRR0, csrr0);
> > +   STACK_PT_REGS_OFFSET(_CSRR1, csrr1);
> > +   STACK_PT_REGS_OFFSET(_DSRR0, dsrr0);
> > +   STACK_PT_REGS_OFFSET(_DSRR1, dsrr1);
> >   #endif
> >   
> > /* About the CPU features 

Re: [PATCH] powerpc/32: Fix critical and debug interrupts on BOOKE

2021-08-03 Thread Christophe Leroy

Hi Radu,

Le 07/07/2021 à 07:55, Christophe Leroy a écrit :

32 bits BOOKE have special interrupts for debug and other
critical events.


Were you able to test this patch ?

Thanks
Christophe




When handling those interrupts, dedicated registers are saved
in the stack frame in addition to the standard registers, leading
to a shift of the pt_regs struct.

Since commit db297c3b07af ("powerpc/32: Don't save thread.regs on
interrupt entry"), the pt_regs struct is expected to be at the
same place all the time.

Instead of handling a special struct in addition to pt_regs, just
add those special registers to struct pt_regs.

Reported-by: Radu Rendec 
Signed-off-by: Christophe Leroy 
Fixes: db297c3b07af ("powerpc/32: Don't save thread.regs on interrupt entry")
Cc: sta...@vger.kernel.org
---
  arch/powerpc/include/asm/ptrace.h | 16 
  arch/powerpc/kernel/asm-offsets.c | 31 ++-
  arch/powerpc/kernel/head_booke.h  | 27 +++
  3 files changed, 33 insertions(+), 41 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index 3e5d470a6155..14422e851494 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -70,6 +70,22 @@ struct pt_regs
unsigned long __pad[4]; /* Maintain 16 byte interrupt stack 
alignment */
};
  #endif
+#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
+   struct { /* Must be a multiple of 16 bytes */
+   unsigned long mas0;
+   unsigned long mas1;
+   unsigned long mas2;
+   unsigned long mas3;
+   unsigned long mas6;
+   unsigned long mas7;
+   unsigned long srr0;
+   unsigned long srr1;
+   unsigned long csrr0;
+   unsigned long csrr1;
+   unsigned long dsrr0;
+   unsigned long dsrr1;
+   };
+#endif
  };
  #endif
  
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c

index a47eefa09bcb..5bee245d832b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -309,24 +309,21 @@ int main(void)
STACK_PT_REGS_OFFSET(STACK_REGS_IAMR, iamr);
  #endif
  
-#if defined(CONFIG_PPC32)

-#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
-   DEFINE(EXC_LVL_SIZE, STACK_EXC_LVL_FRAME_SIZE);
-   DEFINE(MAS0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas0));
+#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
+   STACK_PT_REGS_OFFSET(MAS0, mas0);
/* we overload MMUCR for 44x on MAS0 since they are mutually exclusive 
*/
-   DEFINE(MMUCR, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas0));
-   DEFINE(MAS1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas1));
-   DEFINE(MAS2, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas2));
-   DEFINE(MAS3, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas3));
-   DEFINE(MAS6, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas6));
-   DEFINE(MAS7, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas7));
-   DEFINE(_SRR0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
srr0));
-   DEFINE(_SRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
srr1));
-   DEFINE(_CSRR0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
csrr0));
-   DEFINE(_CSRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
csrr1));
-   DEFINE(_DSRR0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
dsrr0));
-   DEFINE(_DSRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
dsrr1));
-#endif
+   STACK_PT_REGS_OFFSET(MMUCR, mas0);
+   STACK_PT_REGS_OFFSET(MAS1, mas1);
+   STACK_PT_REGS_OFFSET(MAS2, mas2);
+   STACK_PT_REGS_OFFSET(MAS3, mas3);
+   STACK_PT_REGS_OFFSET(MAS6, mas6);
+   STACK_PT_REGS_OFFSET(MAS7, mas7);
+   STACK_PT_REGS_OFFSET(_SRR0, srr0);
+   STACK_PT_REGS_OFFSET(_SRR1, srr1);
+   STACK_PT_REGS_OFFSET(_CSRR0, csrr0);
+   STACK_PT_REGS_OFFSET(_CSRR1, csrr1);
+   STACK_PT_REGS_OFFSET(_DSRR0, dsrr0);
+   STACK_PT_REGS_OFFSET(_DSRR1, dsrr1);
  #endif
  
  	/* About the CPU features table */

diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 87b806e8eded..e5503420b6c6 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -168,20 +168,18 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
  /* only on e500mc */
  #define DBG_STACK_BASEdbgirq_ctx
  
-#define EXC_LVL_FRAME_OVERHEAD	(THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE)

-
  #ifdef CONFIG_SMP
  #define BOOKE_LOAD_EXC_LEVEL_STACK(level) \
mfspr   r8,SPRN_PIR;\
slwir8,r8,2;\
addis   r8,r8,level##_STACK_BASE@ha;\
lwz r8,level##_STACK_BASE@l(r8);\
- 

[PATCH] powerpc/32: Fix critical and debug interrupts on BOOKE

2021-07-06 Thread Christophe Leroy
32 bits BOOKE have special interrupts for debug and other
critical events.

When handling those interrupts, dedicated registers are saved
in the stack frame in addition to the standard registers, leading
to a shift of the pt_regs struct.

Since commit db297c3b07af ("powerpc/32: Don't save thread.regs on
interrupt entry"), the pt_regs struct is expected to be at the
same place all the time.

Instead of handling a special struct in addition to pt_regs, just
add those special registers to struct pt_regs.

Reported-by: Radu Rendec 
Signed-off-by: Christophe Leroy 
Fixes: db297c3b07af ("powerpc/32: Don't save thread.regs on interrupt entry")
Cc: sta...@vger.kernel.org
---
 arch/powerpc/include/asm/ptrace.h | 16 
 arch/powerpc/kernel/asm-offsets.c | 31 ++-
 arch/powerpc/kernel/head_booke.h  | 27 +++
 3 files changed, 33 insertions(+), 41 deletions(-)

diff --git a/arch/powerpc/include/asm/ptrace.h 
b/arch/powerpc/include/asm/ptrace.h
index 3e5d470a6155..14422e851494 100644
--- a/arch/powerpc/include/asm/ptrace.h
+++ b/arch/powerpc/include/asm/ptrace.h
@@ -70,6 +70,22 @@ struct pt_regs
unsigned long __pad[4]; /* Maintain 16 byte interrupt stack 
alignment */
};
 #endif
+#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
+   struct { /* Must be a multiple of 16 bytes */
+   unsigned long mas0;
+   unsigned long mas1;
+   unsigned long mas2;
+   unsigned long mas3;
+   unsigned long mas6;
+   unsigned long mas7;
+   unsigned long srr0;
+   unsigned long srr1;
+   unsigned long csrr0;
+   unsigned long csrr1;
+   unsigned long dsrr0;
+   unsigned long dsrr1;
+   };
+#endif
 };
 #endif
 
diff --git a/arch/powerpc/kernel/asm-offsets.c 
b/arch/powerpc/kernel/asm-offsets.c
index a47eefa09bcb..5bee245d832b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -309,24 +309,21 @@ int main(void)
STACK_PT_REGS_OFFSET(STACK_REGS_IAMR, iamr);
 #endif
 
-#if defined(CONFIG_PPC32)
-#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
-   DEFINE(EXC_LVL_SIZE, STACK_EXC_LVL_FRAME_SIZE);
-   DEFINE(MAS0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas0));
+#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
+   STACK_PT_REGS_OFFSET(MAS0, mas0);
/* we overload MMUCR for 44x on MAS0 since they are mutually exclusive 
*/
-   DEFINE(MMUCR, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas0));
-   DEFINE(MAS1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas1));
-   DEFINE(MAS2, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas2));
-   DEFINE(MAS3, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas3));
-   DEFINE(MAS6, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas6));
-   DEFINE(MAS7, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
mas7));
-   DEFINE(_SRR0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
srr0));
-   DEFINE(_SRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
srr1));
-   DEFINE(_CSRR0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
csrr0));
-   DEFINE(_CSRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
csrr1));
-   DEFINE(_DSRR0, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
dsrr0));
-   DEFINE(_DSRR1, STACK_INT_FRAME_SIZE+offsetof(struct exception_regs, 
dsrr1));
-#endif
+   STACK_PT_REGS_OFFSET(MMUCR, mas0);
+   STACK_PT_REGS_OFFSET(MAS1, mas1);
+   STACK_PT_REGS_OFFSET(MAS2, mas2);
+   STACK_PT_REGS_OFFSET(MAS3, mas3);
+   STACK_PT_REGS_OFFSET(MAS6, mas6);
+   STACK_PT_REGS_OFFSET(MAS7, mas7);
+   STACK_PT_REGS_OFFSET(_SRR0, srr0);
+   STACK_PT_REGS_OFFSET(_SRR1, srr1);
+   STACK_PT_REGS_OFFSET(_CSRR0, csrr0);
+   STACK_PT_REGS_OFFSET(_CSRR1, csrr1);
+   STACK_PT_REGS_OFFSET(_DSRR0, dsrr0);
+   STACK_PT_REGS_OFFSET(_DSRR1, dsrr1);
 #endif
 
/* About the CPU features table */
diff --git a/arch/powerpc/kernel/head_booke.h b/arch/powerpc/kernel/head_booke.h
index 87b806e8eded..e5503420b6c6 100644
--- a/arch/powerpc/kernel/head_booke.h
+++ b/arch/powerpc/kernel/head_booke.h
@@ -168,20 +168,18 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
 /* only on e500mc */
 #define DBG_STACK_BASE dbgirq_ctx
 
-#define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE)
-
 #ifdef CONFIG_SMP
 #define BOOKE_LOAD_EXC_LEVEL_STACK(level)  \
mfspr   r8,SPRN_PIR;\
slwir8,r8,2;\
addis   r8,r8,level##_STACK_BASE@ha;\
lwz r8,level##_STACK_BASE@l(r8);\
-   addir8,r8,EXC_LVL_FRAME_OVERHEAD;
+   addir8,r8,THREAD_SIZE - INT_FRAME_SIZE;
 #else
 #define