2013-10-23 09:31:37

by “tiejun.chen”

[permalink] [raw]
Subject: [v6][PATCH 0/5] powerpc/book3e: powerpc/book3e: make kgdb to work well

Scott,

Tested on fsl-p5040 DS.

v6:

* rebase
* change the C code to initialize the exception stack addresses in the PACA instead.
* Clear the PACA_IRQ_HARD_DIS force to exit directly from this debug exception
without replaying interrupt.
* so drop "book3e/kgdb: update thread's dbcr0".

v5:

* rebase on merge branch.

Note the original patch, [ATCH 5/7] kgdb/kgdbts: support ppc64, is already merged
by Jason.

v4:

* use DEFINE_PER_CPU to allocate kgdb's thread_info
* add patch 7 to make usre copy thread_info only !__check_irq_replay
* leave "andi. r14,r11,MSR_PR" out of "#ifndef CONFIG_KGDB"
since cr0 is still used lately.
* retest

v3:

* make work when enable CONFIG_RELOCATABLE
* fix one typo in patch,
"powerpc/book3e: store critical/machine/debug exception thread info":
ld r1,PACAKSAVE(r13);
-> ld r14,PACAKSAVE(r13);
* remove copying the thread_info since booke and book3e always copy
the thead_info now when we enter the debug exception, and so drop
the v2 patch, "book3e/kgdb: Fix a single stgep case of lazy IRQ"

v2:

* Make sure we cover CONFIG_PPC_BOOK3E_64 safely
* Use LOAD_REG_IMMEDIATE() to load properly
the value of the constant expression in load debug exception stack
* Copy thread infor form the kernel stack coming from usr
* Rebase latest powerpc git tree

v1:

* Copy thread info only when we are from !user mode since we'll get kernel stack
coming from usr directly.
* remove save/restore EX_R14/EX_R15 since DBG_EXCEPTION_PROLOG already covered
this.
* use CURRENT_THREAD_INFO() conveniently to get thread.
* fix some typos
* add a patch to make sure gdb can generate a single step properly to invoke a
kgdb state.
* add a patch to if we need to replay an interrupt, we shouldn't restore that
previous backup thread info to make sure we can replay an interrupt lately
with a proper thread info.
* rebase latest powerpc git tree

v0:

This patchset is used to support kgdb for book3e.

----------------------------------------------------------------
Tiejun Chen (5):
powerpc/book3e: initialize crit/mc/dbg kernel stack pointers
powerpc/book3e: store crit/mc/dbg exception thread info
powerpc/book3e: support kgdb for kernel space
powerpc/kgdb: use DEFINE_PER_CPU to allocate kgdb's thread_info
powerpc/book3e/kgdb: Fix a single stgep case of lazy IRQ

arch/powerpc/kernel/exceptions-64e.S | 26 ++++++++++++++++++++++----
arch/powerpc/kernel/kgdb.c | 13 ++++++++++---
arch/powerpc/kernel/setup_64.c | 18 ++++++++++++------
3 files changed, 44 insertions(+), 13 deletions(-)

Tiejun


2013-10-23 09:31:41

by “tiejun.chen”

[permalink] [raw]
Subject: [v6][PATCH 2/5] powerpc/book3e: store crit/mc/dbg exception thread info

We need to store thread info to these exception thread info like something
we already did for PPC32.

Signed-off-by: Tiejun Chen <[email protected]>
---
arch/powerpc/kernel/exceptions-64e.S | 22 +++++++++++++++++++---
1 file changed, 19 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 68d74b4..a55cf62 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -36,6 +36,19 @@
*/
#define SPECIAL_EXC_FRAME_SIZE INT_FRAME_SIZE

+/* Now we only store something to exception thread info */
+#define EXC_LEVEL_EXCEPTION_PROLOG(type) \
+ ld r14,PACAKSAVE(r13); \
+ CURRENT_THREAD_INFO(r14, r14); \
+ CURRENT_THREAD_INFO(r15, r1); \
+ ld r10,TI_FLAGS(r14); \
+ std r10,TI_FLAGS(r15); \
+ ld r10,TI_PREEMPT(r14); \
+ std r10,TI_PREEMPT(r15); \
+ ld r10,TI_TASK(r14); \
+ std r10,TI_TASK(r15);
+
+
/* Exception prolog code for all exceptions */
#define EXCEPTION_PROLOG(n, intnum, type, addition) \
mtspr SPRN_SPRG_##type##_SCRATCH,r13; /* get spare registers */ \
@@ -69,19 +82,22 @@

#define CRIT_SET_KSTACK \
ld r1,PACA_CRIT_STACK(r13); \
- subi r1,r1,SPECIAL_EXC_FRAME_SIZE;
+ subi r1,r1,SPECIAL_EXC_FRAME_SIZE; \
+ EXC_LEVEL_EXCEPTION_PROLOG(CRIT);
#define SPRN_CRIT_SRR0 SPRN_CSRR0
#define SPRN_CRIT_SRR1 SPRN_CSRR1

#define DBG_SET_KSTACK \
ld r1,PACA_DBG_STACK(r13); \
- subi r1,r1,SPECIAL_EXC_FRAME_SIZE;
+ subi r1,r1,SPECIAL_EXC_FRAME_SIZE; \
+ EXC_LEVEL_EXCEPTION_PROLOG(DBG);
#define SPRN_DBG_SRR0 SPRN_DSRR0
#define SPRN_DBG_SRR1 SPRN_DSRR1

#define MC_SET_KSTACK \
ld r1,PACA_MC_STACK(r13); \
- subi r1,r1,SPECIAL_EXC_FRAME_SIZE;
+ subi r1,r1,SPECIAL_EXC_FRAME_SIZE; \
+ EXC_LEVEL_EXCEPTION_PROLOG(MC);
#define SPRN_MC_SRR0 SPRN_MCSRR0
#define SPRN_MC_SRR1 SPRN_MCSRR1

--
1.7.9.5

2013-10-23 09:31:44

by “tiejun.chen”

[permalink] [raw]
Subject: [v6][PATCH 4/5] powerpc/kgdb: use DEFINE_PER_CPU to allocate kgdb's thread_info

Use DEFINE_PER_CPU to allocate thread_info statically instead of kmalloc().
This can avoid introducing more memory check codes.

Signed-off-by: Tiejun Chen <[email protected]>
---
arch/powerpc/kernel/kgdb.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index c1eef24..447c14b 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -151,15 +151,15 @@ static int kgdb_handle_breakpoint(struct pt_regs *regs)
return 1;
}

+static DEFINE_PER_CPU(struct thread_info, kgdb_thread_info);
static int kgdb_singlestep(struct pt_regs *regs)
{
struct thread_info *thread_info, *exception_thread_info;
- struct thread_info *backup_current_thread_info;
+ struct thread_info *backup_current_thread_info = &__get_cpu_var(kgdb_thread_info);

if (user_mode(regs))
return 0;

- backup_current_thread_info = kmalloc(sizeof(struct thread_info), GFP_KERNEL);
/*
* On Book E and perhaps other processors, singlestep is handled on
* the critical exception stack. This causes current_thread_info()
@@ -185,7 +185,6 @@ static int kgdb_singlestep(struct pt_regs *regs)
/* Restore current_thread_info lastly. */
memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info);

- kfree(backup_current_thread_info);
return 1;
}

--
1.7.9.5

2013-10-23 09:31:47

by “tiejun.chen”

[permalink] [raw]
Subject: [v6][PATCH 5/5] powerpc/book3e/kgdb: Fix a single stgep case of lazy IRQ

In lazy EE magic, we may have a lazy interrupt occured while
entering kgdb, but we really don't want to replay that interrupt
for kgdb, so we have to clear the PACA_IRQ_HARD_DIS force to
make sure we can exit directly from this debug exception.

Signed-off-by: Tiejun Chen <[email protected]>
---
arch/powerpc/kernel/kgdb.c | 8 ++++++++
1 file changed, 8 insertions(+)

diff --git a/arch/powerpc/kernel/kgdb.c b/arch/powerpc/kernel/kgdb.c
index 447c14b..9872f58 100644
--- a/arch/powerpc/kernel/kgdb.c
+++ b/arch/powerpc/kernel/kgdb.c
@@ -185,6 +185,14 @@ static int kgdb_singlestep(struct pt_regs *regs)
/* Restore current_thread_info lastly. */
memcpy(exception_thread_info, backup_current_thread_info, sizeof *thread_info);

+#ifdef CONFIG_PPC64
+ /*
+ * Clear the PACA_IRQ_HARD_DIS from the pending mask
+ * since we are about to exit this directly from debug
+ * exception without any replay interrupt in lazy EE case.
+ */
+ local_paca->irq_happened &= ~PACA_IRQ_HARD_DIS;
+#endif
return 1;
}

--
1.7.9.5

2013-10-23 09:33:51

by “tiejun.chen”

[permalink] [raw]
Subject: [v6][PATCH 3/5] powerpc/book3e: support kgdb for kernel space

Currently we need to skip this for supporting KGDB.

Signed-off-by: Tiejun Chen <[email protected]>
---
arch/powerpc/kernel/exceptions-64e.S | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index a55cf62..0b750c6 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -597,11 +597,13 @@ kernel_dbg_exc:
rfdi

/* Normal debug exception */
+1: andi. r14,r11,MSR_PR; /* check for userspace again */
+#ifndef CONFIG_KGDB
/* XXX We only handle coming from userspace for now since we can't
* quite save properly an interrupted kernel state yet
*/
-1: andi. r14,r11,MSR_PR; /* check for userspace again */
beq kernel_dbg_exc; /* if from kernel mode */
+#endif

/* Now we mash up things to make it look like we are coming on a
* normal exception
--
1.7.9.5

2013-10-23 09:34:27

by “tiejun.chen”

[permalink] [raw]
Subject: [v6][PATCH 1/5] powerpc/book3e: initialize crit/mc/dbg kernel stack pointers

We already allocated critical/machine/debug check exceptions, but
we also should initialize those associated kernel stack pointers
for use by special exceptions in the PACA.

Signed-off-by: Tiejun Chen <[email protected]>
---
arch/powerpc/kernel/setup_64.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)

diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 278ca93..5c96d92 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -526,14 +526,20 @@ static void __init exc_lvl_early_init(void)
extern unsigned int exc_debug_debug_book3e;

unsigned int i;
+ unsigned long sp;

for_each_possible_cpu(i) {
- critirq_ctx[i] = (struct thread_info *)
- __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
- dbgirq_ctx[i] = (struct thread_info *)
- __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
- mcheckirq_ctx[i] = (struct thread_info *)
- __va(memblock_alloc(THREAD_SIZE, THREAD_SIZE));
+ sp = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
+ critirq_ctx[i] = (struct thread_info *)__va(sp);
+ paca[i].crit_kstack = __va(sp + THREAD_SIZE);
+
+ sp = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
+ dbgirq_ctx[i] = (struct thread_info *)__va(sp);
+ paca[i].dbg_kstack = __va(sp + THREAD_SIZE);
+
+ sp = memblock_alloc(THREAD_SIZE, THREAD_SIZE);
+ mcheckirq_ctx[i] = (struct thread_info *)__va(sp);
+ paca[i].mc_kstack = __va(sp + THREAD_SIZE);
}

if (cpu_has_feature(CPU_FTR_DEBUG_LVL_EXC))
--
1.7.9.5

2014-01-15 01:27:35

by Scott Wood

[permalink] [raw]
Subject: Re: [v6,2/5] powerpc/book3e: store crit/mc/dbg exception thread info

On Wed, Oct 23, 2013 at 05:31:22PM +0800, Tiejun Chen wrote:
> We need to store thread info to these exception thread info like something
> we already did for PPC32.
>
> Signed-off-by: Tiejun Chen <[email protected]>
>
> ---
> arch/powerpc/kernel/exceptions-64e.S | 22 +++++++++++++++++++---
> 1 file changed, 19 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
> index 68d74b4..a55cf62 100644
> --- a/arch/powerpc/kernel/exceptions-64e.S
> +++ b/arch/powerpc/kernel/exceptions-64e.S
> @@ -36,6 +36,19 @@
> */
> #define SPECIAL_EXC_FRAME_SIZE INT_FRAME_SIZE
>
> +/* Now we only store something to exception thread info */

Now as opposed to when? Only as opposed to what else?

> +#define EXC_LEVEL_EXCEPTION_PROLOG(type) \

I'd prefer .macro over #define.

> + ld r14,PACAKSAVE(r13); \
> + CURRENT_THREAD_INFO(r14, r14); \
> + CURRENT_THREAD_INFO(r15, r1); \
> + ld r10,TI_FLAGS(r14); \
> + std r10,TI_FLAGS(r15); \
> + ld r10,TI_PREEMPT(r14); \
> + std r10,TI_PREEMPT(r15); \
> + ld r10,TI_TASK(r14); \
> + std r10,TI_TASK(r15);

This is a start, but we'll also need to save some more context to allow
TLB misses from within the exception (e.g. if a machine check handler or
GDB stub writes to a serial port, and the I/O registers aren't in the
TLB). At a minimum I think we need to save SRR0, SRR1,
SPRN_SPRG_GEN_SCRATCH, SPRN_SPRG_TLB_SCRATCH, and the MAS registers.
We'll also need to make the bolted TLB miss handlers capable of pointing
to different extables (though they won't need to auto-advance as the
original TLB miss handlers do -- we would advance SPRN_SPRG_TLB_EXFRAME
from this code), and the original TLB miss handlers will now need to
support more than 3 levels of nesting.

For the e6500 tablewalk TLB miss handler, we'll need to do something
special if we interrupt it when the lock is held, to revoke the lock and
return to code that retries.

Is there anything else I'm missing?

-Scott