Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bcf0b088 authored by Kumar Gala's avatar Kumar Gala
Browse files

[POWERPC] Move to runtime allocated exception stacks



For the additonal exception levels (critical, debug, machine check) on
40x/book-e we were using "static" allocations of the stack in the
associated head.S.

Move to a runtime allocation to make the code a bit easier to read as
we mimic how we handle IRQ stacks.  Its also a bit easier to setup the
stack with a "dummy" thread_info in C code.

Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
Acked-by: default avatarPaul Mackerras <paulus@samba.org>
parent c054065b
Loading
Loading
Loading
Loading
+4 −14
Original line number Original line Diff line number Diff line
@@ -148,14 +148,14 @@ _ENTRY(crit_r11)
	mfcr	r10;			/* save CR in r10 for now	   */\
	mfcr	r10;			/* save CR in r10 for now	   */\
	mfspr	r11,SPRN_SRR3;		/* check whether user or kernel    */\
	mfspr	r11,SPRN_SRR3;		/* check whether user or kernel    */\
	andi.	r11,r11,MSR_PR;						     \
	andi.	r11,r11,MSR_PR;						     \
	lis	r11,critical_stack_top@h;				     \
	lis	r11,critirq_ctx@ha;					     \
	ori	r11,r11,critical_stack_top@l;				     \
	tophys(r11,r11);						     \
	lwz	r11,critirq_ctx@l(r11);					     \
	beq	1f;							     \
	beq	1f;							     \
	/* COMING FROM USER MODE */					     \
	/* COMING FROM USER MODE */					     \
	mfspr	r11,SPRN_SPRG3;		/* if from user, start at top of   */\
	mfspr	r11,SPRN_SPRG3;		/* if from user, start at top of   */\
	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
	lwz	r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
	addi	r11,r11,THREAD_SIZE;					     \
1:	addi	r11,r11,THREAD_SIZE-INT_FRAME_SIZE; /* Alloc an excpt frm  */\
1:	subi	r11,r11,INT_FRAME_SIZE;	/* Allocate an exception frame     */\
	tophys(r11,r11);						     \
	tophys(r11,r11);						     \
	stw	r10,_CCR(r11);          /* save various registers	   */\
	stw	r10,_CCR(r11);          /* save various registers	   */\
	stw	r12,GPR12(r11);						     \
	stw	r12,GPR12(r11);						     \
@@ -996,16 +996,6 @@ empty_zero_page:
swapper_pg_dir:
swapper_pg_dir:
	.space	PGD_TABLE_SIZE
	.space	PGD_TABLE_SIZE



/* Stack for handling critical exceptions from kernel mode */
	.section .bss
        .align 12
exception_stack_bottom:
	.space	4096
critical_stack_top:
	.globl	exception_stack_top
exception_stack_top:

/* Room for two PTE pointers, usually the kernel and current user pointers
/* Room for two PTE pointers, usually the kernel and current user pointers
 * to their respective root page table.
 * to their respective root page table.
 */
 */
+0 −9
Original line number Original line Diff line number Diff line
@@ -737,15 +737,6 @@ empty_zero_page:
swapper_pg_dir:
swapper_pg_dir:
	.space	PGD_TABLE_SIZE
	.space	PGD_TABLE_SIZE


/* Reserved 4k for the critical exception stack & 4k for the machine
 * check stack per CPU for kernel mode exceptions */
	.section .bss
        .align 12
exception_stack_bottom:
	.space	BOOKE_EXCEPTION_STACK_SIZE
	.globl	exception_stack_top
exception_stack_top:

/*
/*
 * Room for two PTE pointers, usually the kernel and current user pointers
 * Room for two PTE pointers, usually the kernel and current user pointers
 * to their respective root page table.
 * to their respective root page table.
+11 −18
Original line number Original line Diff line number Diff line
@@ -43,9 +43,7 @@
	SAVE_2GPRS(7, r11)
	SAVE_2GPRS(7, r11)


/* To handle the additional exception priority levels on 40x and Book-E
/* To handle the additional exception priority levels on 40x and Book-E
 * processors we allocate a 4k stack per additional priority level. The various
 * processors we allocate a stack per additional priority level.
 * head_xxx.S files allocate space (exception_stack_top) for each priority's
 * stack times the number of CPUs
 *
 *
 * On 40x critical is the only additional level
 * On 40x critical is the only additional level
 * On 44x/e500 we have critical and machine check
 * On 44x/e500 we have critical and machine check
@@ -61,36 +59,31 @@
 * going to critical or their own debug level we aren't currently
 * going to critical or their own debug level we aren't currently
 * providing configurations that micro-optimize space usage.
 * providing configurations that micro-optimize space usage.
 */
 */
#ifdef CONFIG_44x
#define NUM_EXCEPTION_LVLS	2
#else
#define NUM_EXCEPTION_LVLS	3
#endif
#define BOOKE_EXCEPTION_STACK_SIZE	(4096 * NUM_EXCEPTION_LVLS)


/* CRIT_SPRG only used in critical exception handling */
/* CRIT_SPRG only used in critical exception handling */
#define CRIT_SPRG	SPRN_SPRG2
#define CRIT_SPRG	SPRN_SPRG2
/* MCHECK_SPRG only used in machine check exception handling */
/* MCHECK_SPRG only used in machine check exception handling */
#define MCHECK_SPRG	SPRN_SPRG6W
#define MCHECK_SPRG	SPRN_SPRG6W


#define MCHECK_STACK_TOP	(exception_stack_top - 4096)
#define MCHECK_STACK_BASE	mcheckirq_ctx
#define CRIT_STACK_TOP		(exception_stack_top)
#define CRIT_STACK_BASE		critirq_ctx


/* only on e200 for now */
/* only on e200 for now */
#define DEBUG_STACK_TOP		(exception_stack_top - 8192)
#define DEBUG_STACK_BASE	dbgirq_ctx
#define DEBUG_SPRG		SPRN_SPRG6W
#define DEBUG_SPRG		SPRN_SPRG6W


#ifdef CONFIG_SMP
#ifdef CONFIG_SMP
#define BOOKE_LOAD_EXC_LEVEL_STACK(level)		\
#define BOOKE_LOAD_EXC_LEVEL_STACK(level)		\
	mfspr	r8,SPRN_PIR;				\
	mfspr	r8,SPRN_PIR;				\
	mulli	r8,r8,BOOKE_EXCEPTION_STACK_SIZE;	\
	slwi	r8,r8,2;				\
	neg	r8,r8;					\
	addis	r8,r8,level##_STACK_BASE@ha;		\
	addis	r8,r8,level##_STACK_TOP@ha;		\
	lwz	r8,level##_STACK_BASE@l(r8);		\
	addi	r8,r8,level##_STACK_TOP@l
	addi	r8,r8,THREAD_SIZE;
#else
#else
#define BOOKE_LOAD_EXC_LEVEL_STACK(level)		\
#define BOOKE_LOAD_EXC_LEVEL_STACK(level)		\
	lis	r8,level##_STACK_TOP@h;			\
	lis	r8,level##_STACK_BASE@ha;		\
	ori	r8,r8,level##_STACK_TOP@l
	lwz	r8,level##_STACK_BASE@l(r8);		\
	addi	r8,r8,THREAD_SIZE;
#endif
#endif


/*
/*
+0 −9
Original line number Original line Diff line number Diff line
@@ -1080,15 +1080,6 @@ empty_zero_page:
swapper_pg_dir:
swapper_pg_dir:
	.space	PGD_TABLE_SIZE
	.space	PGD_TABLE_SIZE


/* Reserved 4k for the critical exception stack & 4k for the machine
 * check stack per CPU for kernel mode exceptions */
	.section .bss
	.align 12
exception_stack_bottom:
	.space	BOOKE_EXCEPTION_STACK_SIZE * NR_CPUS
	.globl	exception_stack_top
exception_stack_top:

/*
/*
 * Room for two PTE pointers, usually the kernel and current user pointers
 * Room for two PTE pointers, usually the kernel and current user pointers
 * to their respective root page table.
 * to their respective root page table.
+33 −0
Original line number Original line Diff line number Diff line
@@ -356,9 +356,42 @@ void __init init_IRQ(void)
{
{
	if (ppc_md.init_IRQ)
	if (ppc_md.init_IRQ)
		ppc_md.init_IRQ();
		ppc_md.init_IRQ();

	exc_lvl_ctx_init();

	irq_ctx_init();
	irq_ctx_init();
}
}


#if defined(CONFIG_BOOKE) || defined(CONFIG_40x)
struct thread_info   *critirq_ctx[NR_CPUS] __read_mostly;
struct thread_info    *dbgirq_ctx[NR_CPUS] __read_mostly;
struct thread_info *mcheckirq_ctx[NR_CPUS] __read_mostly;

void exc_lvl_ctx_init(void)
{
	struct thread_info *tp;
	int i;

	for_each_possible_cpu(i) {
		memset((void *)critirq_ctx[i], 0, THREAD_SIZE);
		tp = critirq_ctx[i];
		tp->cpu = i;
		tp->preempt_count = 0;

#ifdef CONFIG_BOOKE
		memset((void *)dbgirq_ctx[i], 0, THREAD_SIZE);
		tp = dbgirq_ctx[i];
		tp->cpu = i;
		tp->preempt_count = 0;

		memset((void *)mcheckirq_ctx[i], 0, THREAD_SIZE);
		tp = mcheckirq_ctx[i];
		tp->cpu = i;
		tp->preempt_count = HARDIRQ_OFFSET;
#endif
	}
}
#endif


#ifdef CONFIG_IRQSTACKS
#ifdef CONFIG_IRQSTACKS
struct thread_info *softirq_ctx[NR_CPUS] __read_mostly;
struct thread_info *softirq_ctx[NR_CPUS] __read_mostly;
Loading