* [PATCH 2/4] powerpc: Use names rather than numbers for SPRGs (v2)
From: Benjamin Herrenschmidt @ 2009-07-15 6:52 UTC (permalink / raw)
To: linuxppc-dev
The kernel uses SPRG registers for various purposes, typically in
low level assembly code as scratch registers or to hold per-cpu
global infos such as the PACA or the current thread_info pointer.
We want to be able to easily shuffle the usage of those registers
as some implementations have specific constraints realted to some
of them, for example, some have userspace readable aliases, etc..
and the current choice isn't always the best.
This patch should not change any code generation, and replaces the
usage of SPRN_SPRGn everywhere in the kernel with a named replacement
and adds documentation next to the definition of the names as to
what those are used for on each processor family.
The only parts that still use the original numbers are bits of KVM
or suspend/resume code that just blindly needs to save/restore all
the SPRGs.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
--
v2. Missed some iseries bits
arch/powerpc/include/asm/exception-64s.h | 18 ++--
arch/powerpc/include/asm/reg.h | 113 ++++++++++++++++++++++++++
arch/powerpc/kernel/cpu_setup_6xx.S | 2
arch/powerpc/kernel/entry_32.S | 20 ++--
arch/powerpc/kernel/entry_64.S | 4
arch/powerpc/kernel/exceptions-64s.S | 44 +++-------
arch/powerpc/kernel/fpu.S | 2
arch/powerpc/kernel/head_32.S | 40 ++++-----
arch/powerpc/kernel/head_40x.S | 124 ++++++++++++++---------------
arch/powerpc/kernel/head_44x.S | 56 ++++++-------
arch/powerpc/kernel/head_64.S | 14 +--
arch/powerpc/kernel/head_8xx.S | 13 +--
arch/powerpc/kernel/head_booke.h | 50 ++++-------
arch/powerpc/kernel/head_fsl_booke.S | 60 +++++++-------
arch/powerpc/kernel/setup_64.c | 4
arch/powerpc/kernel/vector.S | 2
arch/powerpc/kvm/booke_interrupts.S | 18 ++--
arch/powerpc/mm/hash_low_32.S | 4
arch/powerpc/platforms/iseries/exception.S | 28 +++---
arch/powerpc/platforms/iseries/exception.h | 4
20 files changed, 356 insertions(+), 264 deletions(-)
--- linux-work.orig/arch/powerpc/include/asm/reg.h 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/include/asm/reg.h 2009-07-15 15:08:10.000000000 +1000
@@ -646,6 +646,119 @@
#endif
/*
+ * SPRG usage:
+ *
+ * All 64-bit:
+ * - SPRG3 stores PACA pointer
+ *
+ * 64-bit server:
+ * - SPRG0 unused (reserved for HV on Power4)
+ * - SPRG1 scratch for exception vectors
+ * - SPRG2 scratch for exception vectors
+ *
+ * All 32-bit:
+ * - SPRG3 current thread_info pointer
+ * (virtual on BookE, physical on others)
+ *
+ * 32-bit classic:
+ * - SPRG0 scratch for exception vectors
+ * - SPRG1 scratch for exception vectors
+ * - SPRG2 indicator that we are in RTAS
+ * - SPRG4 (603 only) pseudo TLB LRU data
+ *
+ * 32-bit 40x:
+ * - SPRG0 scratch for exception vectors
+ * - SPRG1 scratch for exception vectors
+ * - SPRG2 scratch for exception vectors
+ * - SPRG4 scratch for exception vectors (not 403)
+ * - SPRG5 scratch for exception vectors (not 403)
+ * - SPRG6 scratch for exception vectors (not 403)
+ * - SPRG7 scratch for exception vectors (not 403)
+ *
+ * 32-bit 440 and FSL BookE:
+ * - SPRG0 scratch for exception vectors
+ * - SPRG1 scratch for exception vectors (*)
+ * - SPRG2 scratch for crit interrupts handler
+ * - SPRG4 scratch for exception vectors
+ * - SPRG5 scratch for exception vectors
+ * - SPRG6 scratch for machine check handler
+ * - SPRG7 scratch for exception vectors
+ * - SPRG9 scratch for debug vectors (e500 only)
+ *
+ * Additionally, BookE separates "read" and "write"
+ * of those registers. That allows to use the userspace
+ * readable variant for reads, which can avoid a fault
+ * with KVM type virtualization.
+ *
+ * (*) Under KVM, the host SPRG1 is used to point to
+ * the current VCPU data structure
+ *
+ * 32-bit 8xx:
+ * - SPRG0 scratch for exception vectors
+ * - SPRG1 scratch for exception vectors
+ * - SPRG2 apparently unused but initialized
+ *
+ */
+#ifdef CONFIG_PPC64
+#define SPRN_SPRG_PACA SPRN_SPRG3
+#else
+#define SPRN_SPRG_THREAD SPRN_SPRG3
+#endif
+
+#ifdef CONFIG_PPC_BOOK3S_64
+#define SPRN_SPRG_SCRATCH0 SPRN_SPRG1
+#define SPRN_SPRG_SCRATCH1 SPRN_SPRG2
+#endif
+
+#ifdef CONFIG_PPC_BOOK3S_32
+#define SPRN_SPRG_SCRATCH0 SPRN_SPRG0
+#define SPRN_SPRG_SCRATCH1 SPRN_SPRG1
+#define SPRN_SPRG_RTAS SPRN_SPRG2
+#define SPRN_SPRG_603_LRU SPRN_SPRG4
+#endif
+
+#ifdef CONFIG_40x
+#define SPRN_SPRG_SCRATCH0 SPRN_SPRG0
+#define SPRN_SPRG_SCRATCH1 SPRN_SPRG1
+#define SPRN_SPRG_SCRATCH2 SPRN_SPRG2
+#define SPRN_SPRG_SCRATCH3 SPRN_SPRG4
+#define SPRN_SPRG_SCRATCH4 SPRN_SPRG5
+#define SPRN_SPRG_SCRATCH5 SPRN_SPRG6
+#define SPRN_SPRG_SCRATCH6 SPRN_SPRG7
+#endif
+
+#ifdef CONFIG_BOOKE
+#define SPRN_SPRG_RSCRATCH0 SPRN_SPRG0
+#define SPRN_SPRG_WSCRATCH0 SPRN_SPRG0
+#define SPRN_SPRG_RSCRATCH1 SPRN_SPRG1
+#define SPRN_SPRG_WSCRATCH1 SPRN_SPRG1
+#define SPRN_SPRG_RSCRATCH_CRIT SPRN_SPRG2
+#define SPRN_SPRG_WSCRATCH_CRIT SPRN_SPRG2
+#define SPRN_SPRG_RSCRATCH2 SPRN_SPRG4R
+#define SPRN_SPRG_WSCRATCH2 SPRN_SPRG4W
+#define SPRN_SPRG_RSCRATCH3 SPRN_SPRG5R
+#define SPRN_SPRG_WSCRATCH3 SPRN_SPRG5W
+#define SPRN_SPRG_RSCRATCH_MC SPRN_SPRG6R
+#define SPRN_SPRG_WSCRATCH_MC SPRN_SPRG6W
+#define SPRN_SPRG_RSCRATCH4 SPRN_SPRG7R
+#define SPRN_SPRG_WSCRATCH4 SPRN_SPRG7W
+#ifdef CONFIG_E200
+#define SPRN_SPRG_RSCRATCH_DBG SPRN_SPRG6R
+#define SPRN_SPRG_WSCRATCH_DBG SPRN_SPRG6W
+#else
+#define SPRN_SPRG_RSCRATCH_DBG SPRN_SPRG9
+#define SPRN_SPRG_WSCRATCH_DBG SPRN_SPRG9
+#endif
+#define SPRN_SPRG_RVCPU SPRN_SPRG1
+#define SPRN_SPRG_WVCPU SPRN_SPRG1
+#endif
+
+#ifdef CONFIG_8xx
+#define SPRN_SPRG_SCRATCH0 SPRN_SPRG0
+#define SPRN_SPRG_SCRATCH1 SPRN_SPRG1
+#endif
+
+/*
* An mtfsf instruction with the L bit set. On CPUs that support this a
* full 64bits of FPSCR is restored and on other CPUs the L bit is ignored.
*
Index: linux-work/arch/powerpc/include/asm/exception-64s.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/exception-64s.h 2009-07-13 11:35:45.000000000 +1000
+++ linux-work/arch/powerpc/include/asm/exception-64s.h 2009-07-15 15:07:50.000000000 +1000
@@ -57,12 +57,12 @@
addi reg,reg,(label)-_stext; /* virt addr of handler ... */
#define EXCEPTION_PROLOG_1(area) \
- mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
+ mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \
std r9,area+EX_R9(r13); /* save r9 - r12 */ \
std r10,area+EX_R10(r13); \
std r11,area+EX_R11(r13); \
std r12,area+EX_R12(r13); \
- mfspr r9,SPRN_SPRG1; \
+ mfspr r9,SPRN_SPRG_SCRATCH0; \
std r9,area+EX_R13(r13); \
mfcr r9
@@ -144,7 +144,7 @@
.globl label##_pSeries; \
label##_pSeries: \
HMT_MEDIUM; \
- mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
#define HSTD_EXCEPTION_PSERIES(n, label) \
@@ -152,13 +152,13 @@ label##_pSeries: \
.globl label##_pSeries; \
label##_pSeries: \
HMT_MEDIUM; \
- mtspr SPRN_SPRG1,r20; /* save r20 */ \
+ mtspr SPRN_SPRG_SCRATCH0,r20; /* save r20 */ \
mfspr r20,SPRN_HSRR0; /* copy HSRR0 to SRR0 */ \
mtspr SPRN_SRR0,r20; \
mfspr r20,SPRN_HSRR1; /* copy HSRR0 to SRR0 */ \
mtspr SPRN_SRR1,r20; \
- mfspr r20,SPRN_SPRG1; /* restore r20 */ \
- mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ mfspr r20,SPRN_SPRG_SCRATCH0; /* restore r20 */ \
+ mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
@@ -167,15 +167,15 @@ label##_pSeries: \
.globl label##_pSeries; \
label##_pSeries: \
HMT_MEDIUM; \
- mtspr SPRN_SPRG1,r13; /* save r13 */ \
- mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
+ mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \
+ mfspr r13,SPRN_SPRG_PACA; /* get paca address into r13 */ \
std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \
std r10,PACA_EXGEN+EX_R10(r13); \
lbz r10,PACASOFTIRQEN(r13); \
mfcr r9; \
cmpwi r10,0; \
beq masked_interrupt; \
- mfspr r10,SPRN_SPRG1; \
+ mfspr r10,SPRN_SPRG_SCRATCH0; \
std r10,PACA_EXGEN+EX_R13(r13); \
std r11,PACA_EXGEN+EX_R11(r13); \
std r12,PACA_EXGEN+EX_R12(r13); \
Index: linux-work/arch/powerpc/kernel/cpu_setup_6xx.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/cpu_setup_6xx.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/cpu_setup_6xx.S 2009-07-13 11:35:46.000000000 +1000
@@ -21,7 +21,7 @@ _GLOBAL(__setup_cpu_603)
mflr r4
BEGIN_MMU_FTR_SECTION
li r10,0
- mtspr SPRN_SPRG4,r10 /* init SW LRU tracking */
+ mtspr SPRN_SPRG_603_LRU,r10 /* init SW LRU tracking */
END_MMU_FTR_SECTION_IFSET(MMU_FTR_NEED_DTLB_SW_LRU)
BEGIN_FTR_SECTION
bl __init_fpu_registers
Index: linux-work/arch/powerpc/kernel/entry_32.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/entry_32.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/entry_32.S 2009-07-13 11:35:46.000000000 +1000
@@ -88,7 +88,7 @@ crit_transfer_to_handler:
mfspr r0,SPRN_SRR1
stw r0,_SRR1(r11)
- mfspr r8,SPRN_SPRG3
+ mfspr r8,SPRN_SPRG_THREAD
lwz r0,KSP_LIMIT(r8)
stw r0,SAVED_KSP_LIMIT(r11)
rlwimi r0,r1,0,0,(31-THREAD_SHIFT)
@@ -108,7 +108,7 @@ crit_transfer_to_handler:
mfspr r0,SPRN_SRR1
stw r0,crit_srr1@l(0)
- mfspr r8,SPRN_SPRG3
+ mfspr r8,SPRN_SPRG_THREAD
lwz r0,KSP_LIMIT(r8)
stw r0,saved_ksp_limit@l(0)
rlwimi r0,r1,0,0,(31-THREAD_SHIFT)
@@ -138,7 +138,7 @@ transfer_to_handler:
mfspr r2,SPRN_XER
stw r12,_CTR(r11)
stw r2,_XER(r11)
- mfspr r12,SPRN_SPRG3
+ mfspr r12,SPRN_SPRG_THREAD
addi r2,r12,-THREAD
tovirt(r2,r2) /* set r2 to current */
beq 2f /* if from user, fix up THREAD.regs */
@@ -680,7 +680,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_SPE)
tophys(r0,r4)
CLR_TOP32(r0)
- mtspr SPRN_SPRG3,r0 /* Update current THREAD phys addr */
+ mtspr SPRN_SPRG_THREAD,r0 /* Update current THREAD phys addr */
lwz r1,KSP(r4) /* Load new stack pointer */
/* save the old current 'last' for return value */
@@ -1057,7 +1057,7 @@ exc_exit_restart_end:
#ifdef CONFIG_40x
.globl ret_from_crit_exc
ret_from_crit_exc:
- mfspr r9,SPRN_SPRG3
+ mfspr r9,SPRN_SPRG_THREAD
lis r10,saved_ksp_limit@ha;
lwz r10,saved_ksp_limit@l(r10);
tovirt(r9,r9);
@@ -1074,7 +1074,7 @@ ret_from_crit_exc:
#ifdef CONFIG_BOOKE
.globl ret_from_crit_exc
ret_from_crit_exc:
- mfspr r9,SPRN_SPRG3
+ mfspr r9,SPRN_SPRG_THREAD
lwz r10,SAVED_KSP_LIMIT(r1)
stw r10,KSP_LIMIT(r9)
RESTORE_xSRR(SRR0,SRR1);
@@ -1083,7 +1083,7 @@ ret_from_crit_exc:
.globl ret_from_debug_exc
ret_from_debug_exc:
- mfspr r9,SPRN_SPRG3
+ mfspr r9,SPRN_SPRG_THREAD
lwz r10,SAVED_KSP_LIMIT(r1)
stw r10,KSP_LIMIT(r9)
lwz r9,THREAD_INFO-THREAD(r9)
@@ -1097,7 +1097,7 @@ ret_from_debug_exc:
.globl ret_from_mcheck_exc
ret_from_mcheck_exc:
- mfspr r9,SPRN_SPRG3
+ mfspr r9,SPRN_SPRG_THREAD
lwz r10,SAVED_KSP_LIMIT(r1)
stw r10,KSP_LIMIT(r9)
RESTORE_xSRR(SRR0,SRR1);
@@ -1255,7 +1255,7 @@ _GLOBAL(enter_rtas)
MTMSRD(r0) /* don't get trashed */
li r9,MSR_KERNEL & ~(MSR_IR|MSR_DR)
mtlr r6
- mtspr SPRN_SPRG2,r7
+ mtspr SPRN_SPRG_RTAS,r7
mtspr SPRN_SRR0,r8
mtspr SPRN_SRR1,r9
RFI
@@ -1265,7 +1265,7 @@ _GLOBAL(enter_rtas)
FIX_SRR1(r9,r0)
addi r1,r1,INT_FRAME_SIZE
li r0,0
- mtspr SPRN_SPRG2,r0
+ mtspr SPRN_SPRG_RTAS,r0
mtspr SPRN_SRR0,r8
mtspr SPRN_SRR1,r9
RFI /* return to caller */
Index: linux-work/arch/powerpc/kernel/exceptions-64s.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/exceptions-64s.S 2009-07-13 11:35:45.000000000 +1000
+++ linux-work/arch/powerpc/kernel/exceptions-64s.S 2009-07-15 15:07:50.000000000 +1000
@@ -24,18 +24,6 @@
* 0x8000 - : Early init and support code
*/
-
-/*
- * SPRG Usage
- *
- * Register Definition
- *
- * SPRG0 reserved for hypervisor
- * SPRG1 temp - used to save gpr
- * SPRG2 temp - used to save gpr
- * SPRG3 virt addr of paca
- */
-
/*
* This is the start of the interrupt handlers for pSeries
* This code runs with relocation off.
@@ -53,16 +41,16 @@ __start_interrupts:
. = 0x200
_machine_check_pSeries:
HMT_MEDIUM
- mtspr SPRN_SPRG1,r13 /* save r13 */
+ mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
. = 0x300
.globl data_access_pSeries
data_access_pSeries:
HMT_MEDIUM
- mtspr SPRN_SPRG1,r13
+ mtspr SPRN_SPRG_SCRATCH0,r13
BEGIN_FTR_SECTION
- mtspr SPRN_SPRG2,r12
+ mtspr SPRN_SPRG_SCRATCH1,r12
mfspr r13,SPRN_DAR
mfspr r12,SPRN_DSISR
srdi r13,r13,60
@@ -71,7 +59,7 @@ BEGIN_FTR_SECTION
cmpwi r13,0x2c
beq do_stab_bolted_pSeries
mtcrf 0x80,r12
- mfspr r12,SPRN_SPRG2
+ mfspr r12,SPRN_SPRG_SCRATCH1
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
@@ -79,8 +67,8 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
.globl data_access_slb_pSeries
data_access_slb_pSeries:
HMT_MEDIUM
- mtspr SPRN_SPRG1,r13
- mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ mtspr SPRN_SPRG_SCRATCH0,r13
+ mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
mfspr r3,SPRN_DAR
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
@@ -93,7 +81,7 @@ data_access_slb_pSeries:
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
- mfspr r10,SPRN_SPRG1
+ mfspr r10,SPRN_SPRG_SCRATCH0
std r10,PACA_EXSLB+EX_R13(r13)
mfspr r12,SPRN_SRR1 /* and SRR1 */
#ifndef CONFIG_RELOCATABLE
@@ -117,8 +105,8 @@ data_access_slb_pSeries:
.globl instruction_access_slb_pSeries
instruction_access_slb_pSeries:
HMT_MEDIUM
- mtspr SPRN_SPRG1,r13
- mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ mtspr SPRN_SPRG_SCRATCH0,r13
+ mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
mfspr r3,SPRN_SRR0 /* SRR0 is faulting address */
std r9,PACA_EXSLB+EX_R9(r13) /* save r9 - r12 */
@@ -131,7 +119,7 @@ instruction_access_slb_pSeries:
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
- mfspr r10,SPRN_SPRG1
+ mfspr r10,SPRN_SPRG_SCRATCH0
std r10,PACA_EXSLB+EX_R13(r13)
mfspr r12,SPRN_SRR1 /* and SRR1 */
#ifndef CONFIG_RELOCATABLE
@@ -161,7 +149,7 @@ BEGIN_FTR_SECTION
beq- 1f
END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE)
mr r9,r13
- mfspr r13,SPRN_SPRG3
+ mfspr r13,SPRN_SPRG_PACA
mfspr r11,SPRN_SRR0
ld r12,PACAKBASE(r13)
ld r10,PACAKMSR(r13)
@@ -230,14 +218,14 @@ masked_interrupt:
rotldi r10,r10,16
mtspr SPRN_SRR1,r10
ld r10,PACA_EXGEN+EX_R10(r13)
- mfspr r13,SPRN_SPRG1
+ mfspr r13,SPRN_SPRG_SCRATCH0
rfid
b .
.align 7
do_stab_bolted_pSeries:
mtcrf 0x80,r12
- mfspr r12,SPRN_SPRG2
+ mfspr r12,SPRN_SPRG_SCRATCH1
EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
#ifdef CONFIG_PPC_PSERIES
@@ -248,14 +236,14 @@ do_stab_bolted_pSeries:
.align 7
system_reset_fwnmi:
HMT_MEDIUM
- mtspr SPRN_SPRG1,r13 /* save r13 */
+ mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */
EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, system_reset_common)
.globl machine_check_fwnmi
.align 7
machine_check_fwnmi:
HMT_MEDIUM
- mtspr SPRN_SPRG1,r13 /* save r13 */
+ mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */
EXCEPTION_PROLOG_PSERIES(PACA_EXMC, machine_check_common)
#endif /* CONFIG_PPC_PSERIES */
@@ -270,7 +258,7 @@ slb_miss_user_pseries:
std r10,PACA_EXGEN+EX_R10(r13)
std r11,PACA_EXGEN+EX_R11(r13)
std r12,PACA_EXGEN+EX_R12(r13)
- mfspr r10,SPRG1
+ mfspr r10,SPRG_SCRATCH0
ld r11,PACA_EXSLB+EX_R9(r13)
ld r12,PACA_EXSLB+EX_R3(r13)
std r10,PACA_EXGEN+EX_R13(r13)
Index: linux-work/arch/powerpc/kernel/fpu.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/fpu.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/fpu.S 2009-07-13 11:35:46.000000000 +1000
@@ -91,7 +91,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_VSX)
#endif /* CONFIG_SMP */
/* enable use of FP after return */
#ifdef CONFIG_PPC32
- mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
+ mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */
lwz r4,THREAD_FPEXC_MODE(r5)
ori r9,r9,MSR_FP /* enable FP for current */
or r9,r9,r4
Index: linux-work/arch/powerpc/kernel/head_32.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_32.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/head_32.S 2009-07-13 11:35:46.000000000 +1000
@@ -244,8 +244,8 @@ __secondary_hold_acknowledge:
* task's thread_struct.
*/
#define EXCEPTION_PROLOG \
- mtspr SPRN_SPRG0,r10; \
- mtspr SPRN_SPRG1,r11; \
+ mtspr SPRN_SPRG_SCRATCH0,r10; \
+ mtspr SPRN_SPRG_SCRATCH1,r11; \
mfcr r10; \
EXCEPTION_PROLOG_1; \
EXCEPTION_PROLOG_2
@@ -255,7 +255,7 @@ __secondary_hold_acknowledge:
andi. r11,r11,MSR_PR; \
tophys(r11,r1); /* use tophys(r1) if kernel */ \
beq 1f; \
- mfspr r11,SPRN_SPRG3; \
+ mfspr r11,SPRN_SPRG_THREAD; \
lwz r11,THREAD_INFO-THREAD(r11); \
addi r11,r11,THREAD_SIZE; \
tophys(r11,r11); \
@@ -267,9 +267,9 @@ __secondary_hold_acknowledge:
stw r10,_CCR(r11); /* save registers */ \
stw r12,GPR12(r11); \
stw r9,GPR9(r11); \
- mfspr r10,SPRN_SPRG0; \
+ mfspr r10,SPRN_SPRG_SCRATCH0; \
stw r10,GPR10(r11); \
- mfspr r12,SPRN_SPRG1; \
+ mfspr r12,SPRN_SPRG_SCRATCH1; \
stw r12,GPR11(r11); \
mflr r10; \
stw r10,_LINK(r11); \
@@ -355,11 +355,11 @@ i##n: \
* -- paulus.
*/
. = 0x200
- mtspr SPRN_SPRG0,r10
- mtspr SPRN_SPRG1,r11
+ mtspr SPRN_SPRG_SCRATCH0,r10
+ mtspr SPRN_SPRG_SCRATCH1,r11
mfcr r10
#ifdef CONFIG_PPC_CHRP
- mfspr r11,SPRN_SPRG2
+ mfspr r11,SPRN_SPRG_RTAS
cmpwi 0,r11,0
bne 7f
#endif /* CONFIG_PPC_CHRP */
@@ -367,7 +367,7 @@ i##n: \
7: EXCEPTION_PROLOG_2
addi r3,r1,STACK_FRAME_OVERHEAD
#ifdef CONFIG_PPC_CHRP
- mfspr r4,SPRN_SPRG2
+ mfspr r4,SPRN_SPRG_RTAS
cmpwi cr1,r4,0
bne cr1,1f
#endif
@@ -485,7 +485,7 @@ InstructionTLBMiss:
mfspr r3,SPRN_IMISS
lis r1,PAGE_OFFSET@h /* check if kernel address */
cmplw 0,r1,r3
- mfspr r2,SPRN_SPRG3
+ mfspr r2,SPRN_SPRG_THREAD
li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
lwz r2,PGDIR(r2)
bge- 112f
@@ -559,7 +559,7 @@ DataLoadTLBMiss:
mfspr r3,SPRN_DMISS
lis r1,PAGE_OFFSET@h /* check if kernel address */
cmplw 0,r1,r3
- mfspr r2,SPRN_SPRG3
+ mfspr r2,SPRN_SPRG_THREAD
li r1,_PAGE_USER|_PAGE_PRESENT /* low addresses tested as user */
lwz r2,PGDIR(r2)
bge- 112f
@@ -598,12 +598,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHER
mtcrf 0x80,r2
BEGIN_MMU_FTR_SECTION
li r0,1
- mfspr r1,SPRN_SPRG4
+ mfspr r1,SPRN_SPRG_603_LRU
rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */
slw r0,r0,r2
xor r1,r0,r1
srw r0,r1,r2
- mtspr SPRN_SPRG4,r1
+ mtspr SPRN_SPRG_603_LRU,r1
mfspr r2,SPRN_SRR1
rlwimi r2,r0,31-14,14,14
mtspr SPRN_SRR1,r2
@@ -643,7 +643,7 @@ DataStoreTLBMiss:
mfspr r3,SPRN_DMISS
lis r1,PAGE_OFFSET@h /* check if kernel address */
cmplw 0,r1,r3
- mfspr r2,SPRN_SPRG3
+ mfspr r2,SPRN_SPRG_THREAD
li r1,_PAGE_RW|_PAGE_USER|_PAGE_PRESENT /* access flags */
lwz r2,PGDIR(r2)
bge- 112f
@@ -678,12 +678,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_NEED_COHER
mtcrf 0x80,r2
BEGIN_MMU_FTR_SECTION
li r0,1
- mfspr r1,SPRN_SPRG4
+ mfspr r1,SPRN_SPRG_603_LRU
rlwinm r2,r3,20,27,31 /* Get Address bits 15:19 */
slw r0,r0,r2
xor r1,r0,r1
srw r0,r1,r2
- mtspr SPRN_SPRG4,r1
+ mtspr SPRN_SPRG_603_LRU,r1
mfspr r2,SPRN_SRR1
rlwimi r2,r0,31-14,14,14
mtspr SPRN_SRR1,r2
@@ -864,9 +864,9 @@ __secondary_start:
tophys(r4,r2)
addi r4,r4,THREAD /* phys address of our thread_struct */
CLR_TOP32(r4)
- mtspr SPRN_SPRG3,r4
+ mtspr SPRN_SPRG_THREAD,r4
li r3,0
- mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */
+ mtspr SPRN_SPRG_RTAS,r3 /* 0 => not in RTAS */
/* enable MMU and jump to start_secondary */
li r4,MSR_KERNEL
@@ -947,9 +947,9 @@ start_here:
tophys(r4,r2)
addi r4,r4,THREAD /* init task's THREAD */
CLR_TOP32(r4)
- mtspr SPRN_SPRG3,r4
+ mtspr SPRN_SPRG_THREAD,r4
li r3,0
- mtspr SPRN_SPRG2,r3 /* 0 => not in RTAS */
+ mtspr SPRN_SPRG_RTAS,r3 /* 0 => not in RTAS */
/* stack */
lis r1,init_thread_union@ha
Index: linux-work/arch/powerpc/kernel/setup_64.c
===================================================================
--- linux-work.orig/arch/powerpc/kernel/setup_64.c 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/setup_64.c 2009-07-15 13:18:34.000000000 +1000
@@ -142,11 +142,11 @@ early_param("smt-enabled", early_smt_ena
#define check_smt_enabled()
#endif /* CONFIG_SMP */
-/* Put the paca pointer into r13 and SPRG3 */
+/* Put the paca pointer into r13 and SPRG_PACA */
void __init setup_paca(int cpu)
{
local_paca = &paca[cpu];
- mtspr(SPRN_SPRG3, local_paca);
+ mtspr(SPRN_SPRG_PACA, local_paca);
}
/*
Index: linux-work/arch/powerpc/kernel/vector.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/vector.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/vector.S 2009-07-13 11:35:46.000000000 +1000
@@ -65,7 +65,7 @@ _GLOBAL(load_up_altivec)
1:
/* enable use of VMX after return */
#ifdef CONFIG_PPC32
- mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
+ mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */
oris r9,r9,MSR_VEC@h
#else
ld r4,PACACURRENT(r13)
Index: linux-work/arch/powerpc/kernel/head_fsl_booke.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_fsl_booke.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/head_fsl_booke.S 2009-07-13 11:35:47.000000000 +1000
@@ -361,7 +361,7 @@ skpinv: addi r6,r6,1 /* Increment */
/* ptr to current thread */
addi r4,r2,THREAD /* init task's THREAD */
- mtspr SPRN_SPRG3,r4
+ mtspr SPRN_SPRG_THREAD,r4
/* stack */
lis r1,init_thread_union@h
@@ -532,12 +532,12 @@ interrupt_base:
/* Data TLB Error Interrupt */
START_EXCEPTION(DataTLBError)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
+ mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG_WSCRATCH1, r11
+ mtspr SPRN_SPRG_WSCRATCH2, r12
+ mtspr SPRN_SPRG_WSCRATCH3, r13
mfcr r11
- mtspr SPRN_SPRG7W, r11
+ mtspr SPRN_SPRG_WSCRATCH4, r11
mfspr r10, SPRN_DEAR /* Get faulting address */
/* If we are faulting a kernel address, we have to use the
@@ -557,7 +557,7 @@ interrupt_base:
/* Get the PGD for the current thread */
3:
- mfspr r11,SPRN_SPRG3
+ mfspr r11,SPRN_SPRG_THREAD
lwz r11,PGDIR(r11)
4:
@@ -598,12 +598,12 @@ interrupt_base:
/* The bailout. Restore registers to pre-exception conditions
* and call the heavyweights to help us out.
*/
- mfspr r11, SPRN_SPRG7R
+ mfspr r11, SPRN_SPRG_RSCRATCH4
mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r13, SPRN_SPRG_RSCRATCH3
+ mfspr r12, SPRN_SPRG_RSCRATCH2
+ mfspr r11, SPRN_SPRG_RSCRATCH1
+ mfspr r10, SPRN_SPRG_RSCRATCH0
b DataStorage
/* Instruction TLB Error Interrupt */
@@ -613,12 +613,12 @@ interrupt_base:
* to a different point.
*/
START_EXCEPTION(InstructionTLBError)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
+ mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG_WSCRATCH1, r11
+ mtspr SPRN_SPRG_WSCRATCH2, r12
+ mtspr SPRN_SPRG_WSCRATCH3, r13
mfcr r11
- mtspr SPRN_SPRG7W, r11
+ mtspr SPRN_SPRG_WSCRATCH4, r11
mfspr r10, SPRN_SRR0 /* Get faulting address */
/* If we are faulting a kernel address, we have to use the
@@ -638,7 +638,7 @@ interrupt_base:
/* Get the PGD for the current thread */
3:
- mfspr r11,SPRN_SPRG3
+ mfspr r11,SPRN_SPRG_THREAD
lwz r11,PGDIR(r11)
4:
@@ -666,12 +666,12 @@ interrupt_base:
/* The bailout. Restore registers to pre-exception conditions
* and call the heavyweights to help us out.
*/
- mfspr r11, SPRN_SPRG7R
+ mfspr r11, SPRN_SPRG_RSCRATCH4
mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r13, SPRN_SPRG_RSCRATCH3
+ mfspr r12, SPRN_SPRG_RSCRATCH2
+ mfspr r11, SPRN_SPRG_RSCRATCH1
+ mfspr r10, SPRN_SPRG_RSCRATCH0
b InstructionStorage
#ifdef CONFIG_SPE
@@ -790,12 +790,12 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PH
tlbwe
/* Done...restore registers and get out of here. */
- mfspr r11, SPRN_SPRG7R
+ mfspr r11, SPRN_SPRG_RSCRATCH4
mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r13, SPRN_SPRG_RSCRATCH3
+ mfspr r12, SPRN_SPRG_RSCRATCH2
+ mfspr r11, SPRN_SPRG_RSCRATCH1
+ mfspr r10, SPRN_SPRG_RSCRATCH0
rfi /* Force context change */
#ifdef CONFIG_SPE
@@ -839,7 +839,7 @@ load_up_spe:
#endif /* !CONFIG_SMP */
/* enable use of SPE after return */
oris r9,r9,MSR_SPE@h
- mfspr r5,SPRN_SPRG3 /* current task's THREAD (phys) */
+ mfspr r5,SPRN_SPRG_THREAD /* current task's THREAD (phys) */
li r4,1
li r10,THREAD_ACC
stw r4,THREAD_USED_SPE(r5)
@@ -1118,7 +1118,7 @@ __secondary_start:
/* ptr to current thread */
addi r4,r2,THREAD /* address of our thread_struct */
- mtspr SPRN_SPRG3,r4
+ mtspr SPRN_SPRG_THREAD,r4
/* Setup the defaults for TLB entries */
li r4,(MAS4_TSIZED(BOOK3E_PAGESZ_4K))@l
Index: linux-work/arch/powerpc/kernel/head_40x.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_40x.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/head_40x.S 2009-07-13 11:35:47.000000000 +1000
@@ -103,21 +103,21 @@ _ENTRY(saved_ksp_limit)
/*
* Exception vector entry code. This code runs with address translation
- * turned off (i.e. using physical addresses). We assume SPRG3 has the
- * physical address of the current task thread_struct.
+ * turned off (i.e. using physical addresses). We assume SPRG_THREAD has
+ * the physical address of the current task thread_struct.
* Note that we have to have decremented r1 before we write to any fields
* of the exception frame, since a critical interrupt could occur at any
* time, and it will write to the area immediately below the current r1.
*/
#define NORMAL_EXCEPTION_PROLOG \
- mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
- mtspr SPRN_SPRG1,r11; \
- mtspr SPRN_SPRG2,r1; \
+ mtspr SPRN_SPRG_SCRATCH0,r10; /* save two registers to work with */\
+ mtspr SPRN_SPRG_SCRATCH1,r11; \
+ mtspr SPRN_SPRG_SCRATCH2,r1; \
mfcr r10; /* save CR in r10 for now */\
mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \
beq 1f; \
- mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
+ mfspr r1,SPRN_SPRG_THREAD; /* if from user, start at top of */\
lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
addi r1,r1,THREAD_SIZE; \
1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
@@ -125,13 +125,13 @@ _ENTRY(saved_ksp_limit)
stw r10,_CCR(r11); /* save various registers */\
stw r12,GPR12(r11); \
stw r9,GPR9(r11); \
- mfspr r10,SPRN_SPRG0; \
+ mfspr r10,SPRN_SPRG_SCRATCH0; \
stw r10,GPR10(r11); \
- mfspr r12,SPRN_SPRG1; \
+ mfspr r12,SPRN_SPRG_SCRATCH1; \
stw r12,GPR11(r11); \
mflr r10; \
stw r10,_LINK(r11); \
- mfspr r10,SPRN_SPRG2; \
+ mfspr r10,SPRN_SPRG_SCRATCH2; \
mfspr r12,SPRN_SRR0; \
stw r10,GPR1(r11); \
mfspr r9,SPRN_SRR1; \
@@ -160,7 +160,7 @@ _ENTRY(saved_ksp_limit)
lwz r11,critirq_ctx@l(r11); \
beq 1f; \
/* COMING FROM USER MODE */ \
- mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
+ mfspr r11,SPRN_SPRG_THREAD; /* if from user, start at top of */\
lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
1: addi r11,r11,THREAD_SIZE-INT_FRAME_SIZE; /* Alloc an excpt frm */\
tophys(r11,r11); \
@@ -265,8 +265,8 @@ label:
* and exit. Otherwise, we call heavywight functions to do the work.
*/
START_EXCEPTION(0x0300, DataStorage)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG_SCRATCH0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG_SCRATCH1, r11
#ifdef CONFIG_403GCX
stw r12, 0(r0)
stw r9, 4(r0)
@@ -275,12 +275,12 @@ label:
stw r11, 8(r0)
stw r12, 12(r0)
#else
- mtspr SPRN_SPRG4, r12
- mtspr SPRN_SPRG5, r9
+ mtspr SPRN_SPRG_SCRATCH3, r12
+ mtspr SPRN_SPRG_SCRATCH4, r9
mfcr r11
mfspr r12, SPRN_PID
- mtspr SPRN_SPRG7, r11
- mtspr SPRN_SPRG6, r12
+ mtspr SPRN_SPRG_SCRATCH6, r11
+ mtspr SPRN_SPRG_SCRATCH5, r12
#endif
/* First, check if it was a zone fault (which means a user
@@ -308,7 +308,7 @@ label:
/* Get the PGD for the current thread.
*/
3:
- mfspr r11,SPRN_SPRG3
+ mfspr r11,SPRN_SPRG_THREAD
lwz r11,PGDIR(r11)
4:
tophys(r11, r11)
@@ -355,15 +355,15 @@ label:
lwz r9, 4(r0)
lwz r12, 0(r0)
#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
+ mfspr r12, SPRN_SPRG_SCRATCH5
+ mfspr r11, SPRN_SPRG_SCRATCH6
mtspr SPRN_PID, r12
mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
+ mfspr r9, SPRN_SPRG_SCRATCH4
+ mfspr r12, SPRN_SPRG_SCRATCH3
#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r11, SPRN_SPRG_SCRATCH1
+ mfspr r10, SPRN_SPRG_SCRATCH0
PPC405_ERR77_SYNC
rfi /* Should sync shadow TLBs */
b . /* prevent prefetch past rfi */
@@ -380,15 +380,15 @@ label:
lwz r9, 4(r0)
lwz r12, 0(r0)
#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
+ mfspr r12, SPRN_SPRG_SCRATCH5
+ mfspr r11, SPRN_SPRG_SCRATCH6
mtspr SPRN_PID, r12
mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
+ mfspr r9, SPRN_SPRG_SCRATCH4
+ mfspr r12, SPRN_SPRG_SCRATCH3
#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r11, SPRN_SPRG_SCRATCH1
+ mfspr r10, SPRN_SPRG_SCRATCH0
b DataAccess
/*
@@ -466,8 +466,8 @@ label:
* load TLB entries from the page table if they exist.
*/
START_EXCEPTION(0x1100, DTLBMiss)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG_SCRATCH0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG_SCRATCH1, r11
#ifdef CONFIG_403GCX
stw r12, 0(r0)
stw r9, 4(r0)
@@ -476,12 +476,12 @@ label:
stw r11, 8(r0)
stw r12, 12(r0)
#else
- mtspr SPRN_SPRG4, r12
- mtspr SPRN_SPRG5, r9
+ mtspr SPRN_SPRG_SCRATCH3, r12
+ mtspr SPRN_SPRG_SCRATCH4, r9
mfcr r11
mfspr r12, SPRN_PID
- mtspr SPRN_SPRG7, r11
- mtspr SPRN_SPRG6, r12
+ mtspr SPRN_SPRG_SCRATCH6, r11
+ mtspr SPRN_SPRG_SCRATCH5, r12
#endif
mfspr r10, SPRN_DEAR /* Get faulting address */
@@ -500,7 +500,7 @@ label:
/* Get the PGD for the current thread.
*/
3:
- mfspr r11,SPRN_SPRG3
+ mfspr r11,SPRN_SPRG_THREAD
lwz r11,PGDIR(r11)
4:
tophys(r11, r11)
@@ -550,15 +550,15 @@ label:
lwz r9, 4(r0)
lwz r12, 0(r0)
#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
+ mfspr r12, SPRN_SPRG_SCRATCH5
+ mfspr r11, SPRN_SPRG_SCRATCH6
mtspr SPRN_PID, r12
mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
+ mfspr r9, SPRN_SPRG_SCRATCH4
+ mfspr r12, SPRN_SPRG_SCRATCH3
#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r11, SPRN_SPRG_SCRATCH1
+ mfspr r10, SPRN_SPRG_SCRATCH0
b DataAccess
/* 0x1200 - Instruction TLB Miss Exception
@@ -566,8 +566,8 @@ label:
* registers and bailout to a different point.
*/
START_EXCEPTION(0x1200, ITLBMiss)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
+ mtspr SPRN_SPRG_SCRATCH0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG_SCRATCH1, r11
#ifdef CONFIG_403GCX
stw r12, 0(r0)
stw r9, 4(r0)
@@ -576,12 +576,12 @@ label:
stw r11, 8(r0)
stw r12, 12(r0)
#else
- mtspr SPRN_SPRG4, r12
- mtspr SPRN_SPRG5, r9
+ mtspr SPRN_SPRG_SCRATCH3, r12
+ mtspr SPRN_SPRG_SCRATCH4, r9
mfcr r11
mfspr r12, SPRN_PID
- mtspr SPRN_SPRG7, r11
- mtspr SPRN_SPRG6, r12
+ mtspr SPRN_SPRG_SCRATCH6, r11
+ mtspr SPRN_SPRG_SCRATCH5, r12
#endif
mfspr r10, SPRN_SRR0 /* Get faulting address */
@@ -600,7 +600,7 @@ label:
/* Get the PGD for the current thread.
*/
3:
- mfspr r11,SPRN_SPRG3
+ mfspr r11,SPRN_SPRG_THREAD
lwz r11,PGDIR(r11)
4:
tophys(r11, r11)
@@ -650,15 +650,15 @@ label:
lwz r9, 4(r0)
lwz r12, 0(r0)
#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
+ mfspr r12, SPRN_SPRG_SCRATCH5
+ mfspr r11, SPRN_SPRG_SCRATCH6
mtspr SPRN_PID, r12
mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
+ mfspr r9, SPRN_SPRG_SCRATCH4
+ mfspr r12, SPRN_SPRG_SCRATCH3
#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r11, SPRN_SPRG_SCRATCH1
+ mfspr r10, SPRN_SPRG_SCRATCH0
b InstructionAccess
EXCEPTION(0x1300, Trap_13, unknown_exception, EXC_XFER_EE)
@@ -803,15 +803,15 @@ finish_tlb_load:
lwz r9, 4(r0)
lwz r12, 0(r0)
#else
- mfspr r12, SPRN_SPRG6
- mfspr r11, SPRN_SPRG7
+ mfspr r12, SPRN_SPRG_SCRATCH5
+ mfspr r11, SPRN_SPRG_SCRATCH6
mtspr SPRN_PID, r12
mtcr r11
- mfspr r9, SPRN_SPRG5
- mfspr r12, SPRN_SPRG4
+ mfspr r9, SPRN_SPRG_SCRATCH4
+ mfspr r12, SPRN_SPRG_SCRATCH3
#endif
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r11, SPRN_SPRG_SCRATCH1
+ mfspr r10, SPRN_SPRG_SCRATCH0
PPC405_ERR77_SYNC
rfi /* Should sync shadow TLBs */
b . /* prevent prefetch past rfi */
@@ -835,7 +835,7 @@ start_here:
/* ptr to phys current thread */
tophys(r4,r2)
addi r4,r4,THREAD /* init task's THREAD */
- mtspr SPRN_SPRG3,r4
+ mtspr SPRN_SPRG_THREAD,r4
/* stack */
lis r1,init_thread_union@ha
Index: linux-work/arch/powerpc/kernel/head_44x.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_44x.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/head_44x.S 2009-07-13 11:35:47.000000000 +1000
@@ -239,7 +239,7 @@ skpinv: addi r4,r4,1 /* Increment */
/* ptr to current thread */
addi r4,r2,THREAD /* init task's THREAD */
- mtspr SPRN_SPRG3,r4
+ mtspr SPRN_SPRG_THREAD,r4
/* stack */
lis r1,init_thread_union@h
@@ -350,12 +350,12 @@ interrupt_base:
/* Data TLB Error Interrupt */
START_EXCEPTION(DataTLBError)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
+ mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG_WSCRATCH1, r11
+ mtspr SPRN_SPRG_WSCRATCH2, r12
+ mtspr SPRN_SPRG_WSCRATCH3, r13
mfcr r11
- mtspr SPRN_SPRG7W, r11
+ mtspr SPRN_SPRG_WSCRATCH4, r11
mfspr r10, SPRN_DEAR /* Get faulting address */
/* If we are faulting a kernel address, we have to use the
@@ -374,7 +374,7 @@ interrupt_base:
/* Get the PGD for the current thread */
3:
- mfspr r11,SPRN_SPRG3
+ mfspr r11,SPRN_SPRG_THREAD
lwz r11,PGDIR(r11)
/* Load PID into MMUCR TID */
@@ -446,12 +446,12 @@ tlb_44x_patch_hwater_D:
/* The bailout. Restore registers to pre-exception conditions
* and call the heavyweights to help us out.
*/
- mfspr r11, SPRN_SPRG7R
+ mfspr r11, SPRN_SPRG_RSCRATCH4
mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r13, SPRN_SPRG_RSCRATCH3
+ mfspr r12, SPRN_SPRG_RSCRATCH2
+ mfspr r11, SPRN_SPRG_RSCRATCH1
+ mfspr r10, SPRN_SPRG_RSCRATCH0
b DataStorage
/* Instruction TLB Error Interrupt */
@@ -461,12 +461,12 @@ tlb_44x_patch_hwater_D:
* to a different point.
*/
START_EXCEPTION(InstructionTLBError)
- mtspr SPRN_SPRG0, r10 /* Save some working registers */
- mtspr SPRN_SPRG1, r11
- mtspr SPRN_SPRG4W, r12
- mtspr SPRN_SPRG5W, r13
+ mtspr SPRN_SPRG_WSCRATCH0, r10 /* Save some working registers */
+ mtspr SPRN_SPRG_WSCRATCH1, r11
+ mtspr SPRN_SPRG_WSCRATCH2, r12
+ mtspr SPRN_SPRG_WSCRATCH3, r13
mfcr r11
- mtspr SPRN_SPRG7W, r11
+ mtspr SPRN_SPRG_WSCRATCH4, r11
mfspr r10, SPRN_SRR0 /* Get faulting address */
/* If we are faulting a kernel address, we have to use the
@@ -485,7 +485,7 @@ tlb_44x_patch_hwater_D:
/* Get the PGD for the current thread */
3:
- mfspr r11,SPRN_SPRG3
+ mfspr r11,SPRN_SPRG_THREAD
lwz r11,PGDIR(r11)
/* Load PID into MMUCR TID */
@@ -542,12 +542,12 @@ tlb_44x_patch_hwater_I:
/* The bailout. Restore registers to pre-exception conditions
* and call the heavyweights to help us out.
*/
- mfspr r11, SPRN_SPRG7R
+ mfspr r11, SPRN_SPRG_RSCRATCH4
mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r13, SPRN_SPRG_RSCRATCH3
+ mfspr r12, SPRN_SPRG_RSCRATCH2
+ mfspr r11, SPRN_SPRG_RSCRATCH1
+ mfspr r10, SPRN_SPRG_RSCRATCH0
b InstructionStorage
/* Debug Interrupt */
@@ -593,12 +593,12 @@ finish_tlb_load:
/* Done...restore registers and get out of here.
*/
- mfspr r11, SPRN_SPRG7R
+ mfspr r11, SPRN_SPRG_RSCRATCH4
mtcr r11
- mfspr r13, SPRN_SPRG5R
- mfspr r12, SPRN_SPRG4R
- mfspr r11, SPRN_SPRG1
- mfspr r10, SPRN_SPRG0
+ mfspr r13, SPRN_SPRG_RSCRATCH3
+ mfspr r12, SPRN_SPRG_RSCRATCH2
+ mfspr r11, SPRN_SPRG_RSCRATCH1
+ mfspr r10, SPRN_SPRG_RSCRATCH0
rfi /* Force context change */
/*
Index: linux-work/arch/powerpc/kernel/head_64.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_64.S 2009-07-13 11:35:45.000000000 +1000
+++ linux-work/arch/powerpc/kernel/head_64.S 2009-07-15 13:18:34.000000000 +1000
@@ -195,7 +195,7 @@ _GLOBAL(generic_secondary_smp_init)
mr r3,r24 /* not found, copy phys to r3 */
b .kexec_wait /* next kernel might do better */
-2: mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+2: mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG */
/* From now on, r24 is expected to be logical cpuid */
mr r24,r5
3: HMT_LOW
@@ -484,7 +484,7 @@ _GLOBAL(pmac_secondary_start)
LOAD_REG_ADDR(r4,paca) /* Get base vaddr of paca array */
mulli r13,r24,PACA_SIZE /* Calculate vaddr of right paca */
add r13,r13,r4 /* for this processor. */
- mtspr SPRN_SPRG3,r13 /* Save vaddr of paca in SPRG3 */
+ mtspr SPRN_SPRG_PACA,r13 /* Save vaddr of paca in an SPRG*/
/* Create a temp kernel stack for use before relocation is on. */
ld r1,PACAEMERGSP(r13)
@@ -502,10 +502,10 @@ _GLOBAL(pmac_secondary_start)
* 1. Processor number
* 2. Segment table pointer (virtual address)
* On entry the following are set:
- * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries
- * r24 = cpu# (in Linux terms)
- * r13 = paca virtual address
- * SPRG3 = paca virtual address
+ * r1 = stack pointer. vaddr for iSeries, raddr (temp stack) for pSeries
+ * r24 = cpu# (in Linux terms)
+ * r13 = paca virtual address
+ * SPRG_PACA = paca virtual address
*/
.globl __secondary_start
__secondary_start:
@@ -641,7 +641,7 @@ _INIT_STATIC(start_here_multiplatform)
/* Restore parameters passed from prom_init/kexec */
mr r3,r31
- bl .early_setup /* also sets r13 and SPRG3 */
+ bl .early_setup /* also sets r13 and SPRG_PACA */
LOAD_REG_ADDR(r3, .start_here_common)
ld r4,PACAKMSR(r13)
Index: linux-work/arch/powerpc/kernel/head_8xx.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_8xx.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/head_8xx.S 2009-07-13 11:35:47.000000000 +1000
@@ -110,8 +110,8 @@ turn_on_mmu:
* task's thread_struct.
*/
#define EXCEPTION_PROLOG \
- mtspr SPRN_SPRG0,r10; \
- mtspr SPRN_SPRG1,r11; \
+ mtspr SPRN_SPRG_SCRATCH0,r10; \
+ mtspr SPRN_SPRG_SCRATCH1,r11; \
mfcr r10; \
EXCEPTION_PROLOG_1; \
EXCEPTION_PROLOG_2
@@ -121,7 +121,7 @@ turn_on_mmu:
andi. r11,r11,MSR_PR; \
tophys(r11,r1); /* use tophys(r1) if kernel */ \
beq 1f; \
- mfspr r11,SPRN_SPRG3; \
+ mfspr r11,SPRN_SPRG_THREAD; \
lwz r11,THREAD_INFO-THREAD(r11); \
addi r11,r11,THREAD_SIZE; \
tophys(r11,r11); \
@@ -133,9 +133,9 @@ turn_on_mmu:
stw r10,_CCR(r11); /* save registers */ \
stw r12,GPR12(r11); \
stw r9,GPR9(r11); \
- mfspr r10,SPRN_SPRG0; \
+ mfspr r10,SPRN_SPRG_SCRATCH0; \
stw r10,GPR10(r11); \
- mfspr r12,SPRN_SPRG1; \
+ mfspr r12,SPRN_SPRG_SCRATCH1; \
stw r12,GPR11(r11); \
mflr r10; \
stw r10,_LINK(r11); \
@@ -603,8 +603,9 @@ start_here:
/* ptr to phys current thread */
tophys(r4,r2)
addi r4,r4,THREAD /* init task's THREAD */
- mtspr SPRN_SPRG3,r4
+ mtspr SPRN_SPRG_THREAD,r4
li r3,0
+ /* XXX What is that for ? SPRG2 appears otherwise unused on 8xx */
mtspr SPRN_SPRG2,r3 /* 0 => r1 has kernel sp */
/* stack */
Index: linux-work/arch/powerpc/kernel/head_booke.h
===================================================================
--- linux-work.orig/arch/powerpc/kernel/head_booke.h 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/head_booke.h 2009-07-13 11:35:47.000000000 +1000
@@ -20,14 +20,14 @@
#endif
#define NORMAL_EXCEPTION_PROLOG \
- mtspr SPRN_SPRG0,r10; /* save two registers to work with */\
- mtspr SPRN_SPRG1,r11; \
- mtspr SPRN_SPRG4W,r1; \
+ mtspr SPRN_SPRG_WSCRATCH0,r10;/* save two registers to work with */\
+ mtspr SPRN_SPRG_WSCRATCH1,r11; \
+ mtspr SPRN_SPRG_WSCRATCH2,r1; \
mfcr r10; /* save CR in r10 for now */\
mfspr r11,SPRN_SRR1; /* check whether user or kernel */\
andi. r11,r11,MSR_PR; \
beq 1f; \
- mfspr r1,SPRN_SPRG3; /* if from user, start at top of */\
+ mfspr r1,SPRN_SPRG_THREAD; /* if from user, start at top of */\
lwz r1,THREAD_INFO-THREAD(r1); /* this thread's kernel stack */\
ALLOC_STACK_FRAME(r1, THREAD_SIZE); \
1: subi r1,r1,INT_FRAME_SIZE; /* Allocate an exception frame */\
@@ -35,13 +35,13 @@
stw r10,_CCR(r11); /* save various registers */\
stw r12,GPR12(r11); \
stw r9,GPR9(r11); \
- mfspr r10,SPRN_SPRG0; \
+ mfspr r10,SPRN_SPRG_RSCRATCH0; \
stw r10,GPR10(r11); \
- mfspr r12,SPRN_SPRG1; \
+ mfspr r12,SPRN_SPRG_RSCRATCH1; \
stw r12,GPR11(r11); \
mflr r10; \
stw r10,_LINK(r11); \
- mfspr r10,SPRN_SPRG4R; \
+ mfspr r10,SPRN_SPRG_RSCRATCH2; \
mfspr r12,SPRN_SRR0; \
stw r10,GPR1(r11); \
mfspr r9,SPRN_SRR1; \
@@ -69,21 +69,11 @@
* providing configurations that micro-optimize space usage.
*/
-/* CRIT_SPRG only used in critical exception handling */
-#define CRIT_SPRG SPRN_SPRG2
-/* MCHECK_SPRG only used in machine check exception handling */
-#define MCHECK_SPRG SPRN_SPRG6W
-
-#define MCHECK_STACK_BASE mcheckirq_ctx
+#define MC_STACK_BASE mcheckirq_ctx
#define CRIT_STACK_BASE critirq_ctx
/* only on e500mc/e200 */
-#define DEBUG_STACK_BASE dbgirq_ctx
-#ifdef CONFIG_E200
-#define DEBUG_SPRG SPRN_SPRG6W
-#else
-#define DEBUG_SPRG SPRN_SPRG9
-#endif
+#define DBG_STACK_BASE dbgirq_ctx
#define EXC_LVL_FRAME_OVERHEAD (THREAD_SIZE - INT_FRAME_SIZE - EXC_LVL_SIZE)
@@ -110,7 +100,7 @@
* critical/machine check exception stack at low physical addresses.
*/
#define EXC_LEVEL_EXCEPTION_PROLOG(exc_level, exc_level_srr0, exc_level_srr1) \
- mtspr exc_level##_SPRG,r8; \
+ mtspr SPRN_SPRG_WSCRATCH_##exc_level,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(exc_level);/* r8 points to the exc_level stack*/ \
stw r9,GPR9(r8); /* save various registers */\
mfcr r9; /* save CR in r9 for now */\
@@ -119,7 +109,7 @@
stw r9,_CCR(r8); /* save CR on stack */\
mfspr r10,exc_level_srr1; /* check whether user or kernel */\
andi. r10,r10,MSR_PR; \
- mfspr r11,SPRN_SPRG3; /* if from user, start at top of */\
+ mfspr r11,SPRN_SPRG_THREAD; /* if from user, start at top of */\
lwz r11,THREAD_INFO-THREAD(r11); /* this thread's kernel stack */\
addi r11,r11,EXC_LVL_FRAME_OVERHEAD; /* allocate stack frame */\
beq 1f; \
@@ -140,7 +130,7 @@
lwz r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r11); \
stw r9,TI_TASK-EXC_LVL_FRAME_OVERHEAD(r8); \
mr r11,r8; \
-2: mfspr r8,exc_level##_SPRG; \
+2: mfspr r8,SPRN_SPRG_RSCRATCH_##exc_level; \
stw r12,GPR12(r11); /* save various registers */\
mflr r10; \
stw r10,_LINK(r11); \
@@ -161,9 +151,9 @@
#define CRITICAL_EXCEPTION_PROLOG \
EXC_LEVEL_EXCEPTION_PROLOG(CRIT, SPRN_CSRR0, SPRN_CSRR1)
#define DEBUG_EXCEPTION_PROLOG \
- EXC_LEVEL_EXCEPTION_PROLOG(DEBUG, SPRN_DSRR0, SPRN_DSRR1)
+ EXC_LEVEL_EXCEPTION_PROLOG(DBG, SPRN_DSRR0, SPRN_DSRR1)
#define MCHECK_EXCEPTION_PROLOG \
- EXC_LEVEL_EXCEPTION_PROLOG(MCHECK, SPRN_MCSRR0, SPRN_MCSRR1)
+ EXC_LEVEL_EXCEPTION_PROLOG(MC, SPRN_MCSRR0, SPRN_MCSRR1)
/*
* Exception vectors.
@@ -282,13 +272,13 @@ label:
mtspr SPRN_DSRR1,r9; \
lwz r9,GPR9(r11); \
lwz r12,GPR12(r11); \
- mtspr DEBUG_SPRG,r8; \
- BOOKE_LOAD_EXC_LEVEL_STACK(DEBUG); /* r8 points to the debug stack */ \
+ mtspr SPRN_SPRG_WSCRATCH_DBG,r8; \
+ BOOKE_LOAD_EXC_LEVEL_STACK(DBG); /* r8 points to the debug stack */ \
lwz r10,GPR10(r8); \
lwz r11,GPR11(r8); \
- mfspr r8,DEBUG_SPRG; \
+ mfspr r8,SPRN_SPRG_RSCRATCH_DBG; \
\
- PPC_RFDI; \
+ PPC_RFDI; \
b .; \
\
/* continue normal handling for a debug exception... */ \
@@ -335,11 +325,11 @@ label:
mtspr SPRN_CSRR1,r9; \
lwz r9,GPR9(r11); \
lwz r12,GPR12(r11); \
- mtspr CRIT_SPRG,r8; \
+ mtspr SPRN_SPRG_WSCRATCH_CRIT,r8; \
BOOKE_LOAD_EXC_LEVEL_STACK(CRIT); /* r8 points to the debug stack */ \
lwz r10,GPR10(r8); \
lwz r11,GPR11(r8); \
- mfspr r8,CRIT_SPRG; \
+ mfspr r8,SPRN_SPRG_RSCRATCH_CRIT; \
\
rfci; \
b .; \
Index: linux-work/arch/powerpc/kvm/booke_interrupts.S
===================================================================
--- linux-work.orig/arch/powerpc/kvm/booke_interrupts.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kvm/booke_interrupts.S 2009-07-13 11:35:47.000000000 +1000
@@ -56,8 +56,8 @@
.macro KVM_HANDLER ivor_nr
_GLOBAL(kvmppc_handler_\ivor_nr)
/* Get pointer to vcpu and record exit number. */
- mtspr SPRN_SPRG0, r4
- mfspr r4, SPRN_SPRG1
+ mtspr SPRN_SPRG_WSCRATCH0, r4
+ mfspr r4, SPRN_SPRG_RVCPU
stw r5, VCPU_GPR(r5)(r4)
stw r6, VCPU_GPR(r6)(r4)
mfctr r5
@@ -95,7 +95,7 @@ _GLOBAL(kvmppc_handler_len)
/* Registers:
- * SPRG0: guest r4
+ * SPRG_SCRATCH0: guest r4
* r4: vcpu pointer
* r5: KVM exit number
*/
@@ -181,7 +181,7 @@ _GLOBAL(kvmppc_resume_host)
stw r3, VCPU_LR(r4)
mfxer r3
stw r3, VCPU_XER(r4)
- mfspr r3, SPRN_SPRG0
+ mfspr r3, SPRN_SPRG_RSCRATCH0
stw r3, VCPU_GPR(r4)(r4)
mfspr r3, SPRN_SRR0
stw r3, VCPU_PC(r4)
@@ -374,7 +374,7 @@ lightweight_exit:
mtspr SPRN_IVPR, r8
/* Save vcpu pointer for the exception handlers. */
- mtspr SPRN_SPRG1, r4
+ mtspr SPRN_SPRG_WVCPU, r4
/* Can't switch the stack pointer until after IVPR is switched,
* because host interrupt handlers would get confused. */
@@ -384,13 +384,13 @@ lightweight_exit:
/* Host interrupt handlers may have clobbered these guest-readable
* SPRGs, so we need to reload them here with the guest's values. */
lwz r3, VCPU_SPRG4(r4)
- mtspr SPRN_SPRG4, r3
+ mtspr SPRN_SPRG4W, r3
lwz r3, VCPU_SPRG5(r4)
- mtspr SPRN_SPRG5, r3
+ mtspr SPRN_SPRG5W, r3
lwz r3, VCPU_SPRG6(r4)
- mtspr SPRN_SPRG6, r3
+ mtspr SPRN_SPRG6W, r3
lwz r3, VCPU_SPRG7(r4)
- mtspr SPRN_SPRG7, r3
+ mtspr SPRN_SPRG7W, r3
#ifdef CONFIG_KVM_EXIT_TIMING
/* save enter time */
Index: linux-work/arch/powerpc/mm/hash_low_32.S
===================================================================
--- linux-work.orig/arch/powerpc/mm/hash_low_32.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/mm/hash_low_32.S 2009-07-13 11:35:47.000000000 +1000
@@ -40,7 +40,7 @@ mmu_hash_lock:
* The address is in r4, and r3 contains an access flag:
* _PAGE_RW (0x400) if a write.
* r9 contains the SRR1 value, from which we use the MSR_PR bit.
- * SPRG3 contains the physical address of the current task's thread.
+ * SPRG_THREAD contains the physical address of the current task's thread.
*
* Returns to the caller if the access is illegal or there is no
* mapping for the address. Otherwise it places an appropriate PTE
@@ -68,7 +68,7 @@ _GLOBAL(hash_page)
/* Get PTE (linux-style) and check access */
lis r0,KERNELBASE@h /* check if kernel address */
cmplw 0,r4,r0
- mfspr r8,SPRN_SPRG3 /* current task's THREAD (phys) */
+ mfspr r8,SPRN_SPRG_THREAD /* current task's THREAD (phys) */
ori r3,r3,_PAGE_USER|_PAGE_PRESENT /* test low addresses as user */
lwz r5,PGDIR(r8) /* virt page-table root */
blt+ 112f /* assume user more likely */
Index: linux-work/arch/powerpc/platforms/iseries/exception.S
===================================================================
--- linux-work.orig/arch/powerpc/platforms/iseries/exception.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/platforms/iseries/exception.S 2009-07-15 15:07:50.000000000 +1000
@@ -47,7 +47,7 @@ system_reset_iSeries:
LOAD_REG_ADDR(r13, paca)
mulli r0,r23,PACA_SIZE
add r13,r13,r0
- mtspr SPRN_SPRG3,r13 /* Save it away for the future */
+ mtspr SPRN_SPRG_PACA,r13 /* Save it away for the future */
mfmsr r24
ori r24,r24,MSR_RI
mtmsrd r24 /* RI on */
@@ -116,7 +116,7 @@ iSeries_secondary_smp_loop:
#endif /* CONFIG_SMP */
li r0,-1 /* r0=-1 indicates a Hypervisor call */
sc /* Invoke the hypervisor via a system call */
- mfspr r13,SPRN_SPRG3 /* Put r13 back ???? */
+ mfspr r13,SPRN_SPRG_PACA /* Put r13 back ???? */
b 2b /* If SMP not configured, secondaries
* loop forever */
@@ -126,9 +126,9 @@ iSeries_secondary_smp_loop:
.globl data_access_iSeries
data_access_iSeries:
- mtspr SPRN_SPRG1,r13
+ mtspr SPRN_SPRG_SCRATCH0,r13
BEGIN_FTR_SECTION
- mtspr SPRN_SPRG2,r12
+ mtspr SPRN_SPRG_SCRATCH1,r12
mfspr r13,SPRN_DAR
mfspr r12,SPRN_DSISR
srdi r13,r13,60
@@ -137,7 +137,7 @@ BEGIN_FTR_SECTION
cmpwi r13,0x2c
beq .do_stab_bolted_iSeries
mtcrf 0x80,r12
- mfspr r12,SPRN_SPRG2
+ mfspr r12,SPRN_SPRG_SCRATCH1
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
EXCEPTION_PROLOG_1(PACA_EXGEN)
EXCEPTION_PROLOG_ISERIES_1
@@ -145,15 +145,15 @@ END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
.do_stab_bolted_iSeries:
mtcrf 0x80,r12
- mfspr r12,SPRN_SPRG2
+ mfspr r12,SPRN_SPRG_SCRATCH1
EXCEPTION_PROLOG_1(PACA_EXSLB)
EXCEPTION_PROLOG_ISERIES_1
b .do_stab_bolted
.globl data_access_slb_iSeries
data_access_slb_iSeries:
- mtspr SPRN_SPRG1,r13 /* save r13 */
- mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */
+ mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
mfspr r3,SPRN_DAR
std r9,PACA_EXSLB+EX_R9(r13)
@@ -165,7 +165,7 @@ data_access_slb_iSeries:
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
- mfspr r10,SPRN_SPRG1
+ mfspr r10,SPRN_SPRG_SCRATCH0
std r10,PACA_EXSLB+EX_R13(r13)
ld r12,PACALPPACAPTR(r13)
ld r12,LPPACASRR1(r12)
@@ -175,8 +175,8 @@ data_access_slb_iSeries:
.globl instruction_access_slb_iSeries
instruction_access_slb_iSeries:
- mtspr SPRN_SPRG1,r13 /* save r13 */
- mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
+ mtspr SPRN_SPRG_SCRATCH0,r13 /* save r13 */
+ mfspr r13,SPRN_SPRG_PACA /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
ld r3,PACALPPACAPTR(r13)
ld r3,LPPACASRR0(r3) /* get SRR0 value */
@@ -189,7 +189,7 @@ instruction_access_slb_iSeries:
std r10,PACA_EXSLB+EX_R10(r13)
std r11,PACA_EXSLB+EX_R11(r13)
std r12,PACA_EXSLB+EX_R12(r13)
- mfspr r10,SPRN_SPRG1
+ mfspr r10,SPRN_SPRG_SCRATCH0
std r10,PACA_EXSLB+EX_R13(r13)
ld r12,PACALPPACAPTR(r13)
ld r12,LPPACASRR1(r12)
@@ -200,7 +200,7 @@ slb_miss_user_iseries:
std r10,PACA_EXGEN+EX_R10(r13)
std r11,PACA_EXGEN+EX_R11(r13)
std r12,PACA_EXGEN+EX_R12(r13)
- mfspr r10,SPRG1
+ mfspr r10,SPRG_SCRATCH0
ld r11,PACA_EXSLB+EX_R9(r13)
ld r12,PACA_EXSLB+EX_R3(r13)
std r10,PACA_EXGEN+EX_R13(r13)
@@ -221,7 +221,7 @@ slb_miss_user_iseries:
.globl system_call_iSeries
system_call_iSeries:
mr r9,r13
- mfspr r13,SPRN_SPRG3
+ mfspr r13,SPRN_SPRG_PACA
EXCEPTION_PROLOG_ISERIES_1
b system_call_common
Index: linux-work/arch/powerpc/platforms/iseries/exception.h
===================================================================
--- linux-work.orig/arch/powerpc/platforms/iseries/exception.h 2009-07-13 11:35:45.000000000 +1000
+++ linux-work/arch/powerpc/platforms/iseries/exception.h 2009-07-13 11:35:47.000000000 +1000
@@ -38,7 +38,7 @@
.globl label##_iSeries; \
label##_iSeries: \
HMT_MEDIUM; \
- mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \
EXCEPTION_PROLOG_1(area); \
EXCEPTION_PROLOG_ISERIES_1; \
b label##_common
@@ -47,7 +47,7 @@ label##_iSeries: \
.globl label##_iSeries; \
label##_iSeries: \
HMT_MEDIUM; \
- mtspr SPRN_SPRG1,r13; /* save r13 */ \
+ mtspr SPRN_SPRG_SCRATCH0,r13; /* save r13 */ \
EXCEPTION_PROLOG_1(PACA_EXGEN); \
lbz r10,PACASOFTIRQEN(r13); \
cmpwi 0,r10,0; \
Index: linux-work/arch/powerpc/kernel/entry_64.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/entry_64.S 2009-07-13 10:54:38.000000000 +1000
+++ linux-work/arch/powerpc/kernel/entry_64.S 2009-07-13 11:35:47.000000000 +1000
@@ -762,7 +762,7 @@ _GLOBAL(enter_rtas)
_STATIC(rtas_return_loc)
/* relocation is off at this point */
- mfspr r4,SPRN_SPRG3 /* Get PACA */
+ mfspr r4,SPRN_SPRG_PACA /* Get PACA */
clrldi r4,r4,2 /* convert to realmode address */
bcl 20,31,$+4
@@ -793,7 +793,7 @@ _STATIC(rtas_restore_regs)
REST_8GPRS(14, r1) /* Restore the non-volatiles */
REST_10GPRS(22, r1) /* ditto */
- mfspr r13,SPRN_SPRG3
+ mfspr r13,SPRN_SPRG_PACA
ld r4,_CCR(r1)
mtcr r4
^ permalink raw reply
* [PATCH 3/4] powerpc: Remove use of a second scratch SPRG in STAB code
From: Benjamin Herrenschmidt @ 2009-07-15 6:52 UTC (permalink / raw)
To: linuxppc-dev
The STAB code used on Power3 and RS/64 uses a second scratch SPRG to
save a GPR in order to decide whether to go to do_stab_bolted_* or
to handle a normal data access exception.
This prevents our scheme of freeing SPRG3 which is user visible for
user uses since we cannot use SPRG0 which, on RS/64, seems to be
read-only for supervisor mode (like POWER4).
This reworks the STAB exception entry to use the PACA as temporary
storage instead.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/exception-64s.h | 7 ++++-
arch/powerpc/include/asm/reg.h | 3 --
arch/powerpc/kernel/exceptions-64s.S | 36 ++++++++++++++++++-----------
arch/powerpc/platforms/iseries/exception.S | 34 ++++++++++++++++-----------
4 files changed, 50 insertions(+), 30 deletions(-)
--- linux-work.orig/arch/powerpc/include/asm/exception-64s.h 2009-07-15 15:07:50.000000000 +1000
+++ linux-work/arch/powerpc/include/asm/exception-64s.h 2009-07-15 15:15:36.000000000 +1000
@@ -66,8 +66,7 @@
std r9,area+EX_R13(r13); \
mfcr r9
-#define EXCEPTION_PROLOG_PSERIES(area, label) \
- EXCEPTION_PROLOG_1(area); \
+#define EXCEPTION_PROLOG_PSERIES_1(label) \
ld r12,PACAKBASE(r13); /* get high part of &label */ \
ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \
mfspr r11,SPRN_SRR0; /* save SRR0 */ \
@@ -78,6 +77,10 @@
rfid; \
b . /* prevent speculative execution */
+#define EXCEPTION_PROLOG_PSERIES(area, label) \
+ EXCEPTION_PROLOG_1(area); \
+ EXCEPTION_PROLOG_PSERIES_1(label);
+
/*
* The common exception prolog is used for all except a few exceptions
* such as a segment miss on a kernel address. We have to be prepared
Index: linux-work/arch/powerpc/kernel/exceptions-64s.S
===================================================================
--- linux-work.orig/arch/powerpc/kernel/exceptions-64s.S 2009-07-15 15:07:50.000000000 +1000
+++ linux-work/arch/powerpc/kernel/exceptions-64s.S 2009-07-15 15:39:12.000000000 +1000
@@ -50,18 +50,26 @@ data_access_pSeries:
HMT_MEDIUM
mtspr SPRN_SPRG_SCRATCH0,r13
BEGIN_FTR_SECTION
- mtspr SPRN_SPRG_SCRATCH1,r12
- mfspr r13,SPRN_DAR
- mfspr r12,SPRN_DSISR
- srdi r13,r13,60
- rlwimi r13,r12,16,0x20
- mfcr r12
- cmpwi r13,0x2c
+ mfspr r13,SPRN_SPRG_PACA
+ std r9,PACA_EXSLB+EX_R9(r13)
+ std r10,PACA_EXSLB+EX_R10(r13)
+ mfspr r10,SPRN_DAR
+ mfspr r9,SPRN_DSISR
+ srdi r10,r10,60
+ rlwimi r10,r9,16,0x20
+ mfcr r9
+ cmpwi r10,0x2c
beq do_stab_bolted_pSeries
- mtcrf 0x80,r12
- mfspr r12,SPRN_SPRG_SCRATCH1
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXGEN+EX_R11(r13)
+ ld r11,PACA_EXSLB+EX_R9(r13)
+ std r12,PACA_EXGEN+EX_R12(r13)
+ mfspr r12,SPRN_SPRG_SCRATCH0
+ std r10,PACA_EXGEN+EX_R10(r13)
+ std r11,PACA_EXGEN+EX_R9(r13)
+ std r12,PACA_EXGEN+EX_R13(r13)
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
- EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, data_access_common)
+ EXCEPTION_PROLOG_PSERIES_1(data_access_common)
. = 0x380
.globl data_access_slb_pSeries
@@ -224,9 +232,11 @@ masked_interrupt:
.align 7
do_stab_bolted_pSeries:
- mtcrf 0x80,r12
- mfspr r12,SPRN_SPRG_SCRATCH1
- EXCEPTION_PROLOG_PSERIES(PACA_EXSLB, .do_stab_bolted)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ mfspr r10,SPRN_SPRG_SCRATCH0
+ std r10,PACA_EXSLB+EX_R13(r13)
+ EXCEPTION_PROLOG_PSERIES_1(.do_stab_bolted)
#ifdef CONFIG_PPC_PSERIES
/*
Index: linux-work/arch/powerpc/platforms/iseries/exception.S
===================================================================
--- linux-work.orig/arch/powerpc/platforms/iseries/exception.S 2009-07-15 15:07:50.000000000 +1000
+++ linux-work/arch/powerpc/platforms/iseries/exception.S 2009-07-15 15:39:14.000000000 +1000
@@ -128,25 +128,33 @@ iSeries_secondary_smp_loop:
data_access_iSeries:
mtspr SPRN_SPRG_SCRATCH0,r13
BEGIN_FTR_SECTION
- mtspr SPRN_SPRG_SCRATCH1,r12
- mfspr r13,SPRN_DAR
- mfspr r12,SPRN_DSISR
- srdi r13,r13,60
- rlwimi r13,r12,16,0x20
- mfcr r12
- cmpwi r13,0x2c
+ mfspr r13,SPRN_SPRG_PACA
+ std r9,PACA_EXSLB+EX_R9(r13)
+ std r10,PACA_EXSLB+EX_R10(r13)
+ mfspr r10,SPRN_DAR
+ mfspr r9,SPRN_DSISR
+ srdi r10,r10,60
+ rlwimi r10,r9,16,0x20
+ mfcr r9
+ cmpwi r10,0x2c
beq .do_stab_bolted_iSeries
- mtcrf 0x80,r12
- mfspr r12,SPRN_SPRG_SCRATCH1
+ ld r10,PACA_EXSLB+EX_R10(r13)
+ std r11,PACA_EXGEN+EX_R11(r13)
+ ld r11,PACA_EXSLB+EX_R9(r13)
+ std r12,PACA_EXGEN+EX_R12(r13)
+ mfspr r12,SPRN_SPRG_SCRATCH0
+ std r10,PACA_EXGEN+EX_R10(r13)
+ std r11,PACA_EXGEN+EX_R9(r13)
+ std r12,PACA_EXGEN+EX_R13(r13)
END_FTR_SECTION_IFCLR(CPU_FTR_SLB)
- EXCEPTION_PROLOG_1(PACA_EXGEN)
EXCEPTION_PROLOG_ISERIES_1
b data_access_common
.do_stab_bolted_iSeries:
- mtcrf 0x80,r12
- mfspr r12,SPRN_SPRG_SCRATCH1
- EXCEPTION_PROLOG_1(PACA_EXSLB)
+ std r11,PACA_EXSLB+EX_R11(r13)
+ std r12,PACA_EXSLB+EX_R12(r13)
+ mfspr r10,SPRN_SPRG_SCRATCH0
+ std r10,PACA_EXSLB+EX_R13(r13)
EXCEPTION_PROLOG_ISERIES_1
b .do_stab_bolted
Index: linux-work/arch/powerpc/include/asm/reg.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/reg.h 2009-07-15 15:23:52.000000000 +1000
+++ linux-work/arch/powerpc/include/asm/reg.h 2009-07-15 15:24:07.000000000 +1000
@@ -654,7 +654,7 @@
* 64-bit server:
* - SPRG0 unused (reserved for HV on Power4)
* - SPRG1 scratch for exception vectors
- * - SPRG2 scratch for exception vectors
+ * - SPRG2 unused
*
* All 32-bit:
* - SPRG3 current thread_info pointer
@@ -707,7 +707,6 @@
#ifdef CONFIG_PPC_BOOK3S_64
#define SPRN_SPRG_SCRATCH0 SPRN_SPRG1
-#define SPRN_SPRG_SCRATCH1 SPRN_SPRG2
#endif
#ifdef CONFIG_PPC_BOOK3S_32
^ permalink raw reply
* [PATCH 4/4] powerpc: Change PACA from SPRG3 to SPRG1
From: Benjamin Herrenschmidt @ 2009-07-15 6:52 UTC (permalink / raw)
To: linuxppc-dev
This change the SPRG used to store the PACA on ppc64 from
SPRG3 to SPRG1. SPRG3 is user readable on most processors
and we want to use it for other things. We change the scratch
SPRG used by exception vectors from SRPG1 to SPRG2.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
arch/powerpc/include/asm/reg.h | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
--- linux-work.orig/arch/powerpc/include/asm/reg.h 2009-07-15 15:24:07.000000000 +1000
+++ linux-work/arch/powerpc/include/asm/reg.h 2009-07-15 15:56:42.000000000 +1000
@@ -649,12 +649,12 @@
* SPRG usage:
*
* All 64-bit:
- * - SPRG3 stores PACA pointer
+ * - SPRG1 stores PACA pointer
*
* 64-bit server:
* - SPRG0 unused (reserved for HV on Power4)
- * - SPRG1 scratch for exception vectors
- * - SPRG2 unused
+ * - SPRG2 scratch for exception vectors
+ * - SPRG3 unused (user visible)
*
* All 32-bit:
* - SPRG3 current thread_info pointer
@@ -700,13 +700,13 @@
*
*/
#ifdef CONFIG_PPC64
-#define SPRN_SPRG_PACA SPRN_SPRG3
+#define SPRN_SPRG_PACA SPRN_SPRG1
#else
#define SPRN_SPRG_THREAD SPRN_SPRG3
#endif
#ifdef CONFIG_PPC_BOOK3S_64
-#define SPRN_SPRG_SCRATCH0 SPRN_SPRG1
+#define SPRN_SPRG_SCRATCH0 SPRN_SPRG2
#endif
#ifdef CONFIG_PPC_BOOK3S_32
^ permalink raw reply
* [PATCH] powerpc/pmac: Fix PowerSurge SMP IPI allocation
From: Benjamin Herrenschmidt @ 2009-07-15 6:56 UTC (permalink / raw)
To: linuxppc-dev
The code for setting up the IPIs for SMP PowerSurge marchines bitrot,
it needs to properly map the HW interrupt number
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
--
arch/powerpc/platforms/powermac/smp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- linux-work.orig/arch/powerpc/platforms/powermac/smp.c 2009-07-15 16:55:28.000000000 +1000
+++ linux-work/arch/powerpc/platforms/powermac/smp.c 2009-07-15 16:55:36.000000000 +1000
@@ -408,7 +408,7 @@ static void __init smp_psurge_setup_cpu(
/* reset the entry point so if we get another intr we won't
* try to startup again */
out_be32(psurge_start, 0x100);
- if (setup_irq(30, &psurge_irqaction))
+ if (setup_irq(irq_create_mapping(NULL, 30), &psurge_irqaction))
printk(KERN_ERR "Couldn't get primary IPI interrupt");
}
^ permalink raw reply
* [RFC/PATCH] mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
From: Benjamin Herrenschmidt @ 2009-07-15 7:49 UTC (permalink / raw)
To: Linux Memory Management, Linux-Arch, linux-kernel, linuxppc-dev
Cc: Nick Piggin, Hugh Dickins
Upcoming paches to support the new 64-bit "BookE" powerpc architecture
will need to have the virtual address corresponding to PTE page when
freeing it, due to the way the HW table walker works.
Basically, the TLB can be loaded with "large" pages that cover the whole
virtual space (well, sort-of, half of it actually) represented by a PTE
page, and which contain an "indirect" bit indicating that this TLB entry
RPN points to an array of PTEs from which the TLB can then create direct
entries. Thus, in order to invalidate those when PTE pages are deleted,
we need the virtual address to pass to tlbilx or tlbivax instructions.
The old trick of sticking it somewhere in the PTE page struct page sucks
too much, the address is almost readily available in all call sites and
almost everybody implemets these as macros, so we may as well add the
argument everywhere. I added it to the pmd and pud variants for consistency.
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
---
I would like to merge the new support that depends on this in 2.6.32,
so unless there's major objections, I'd like this to go in early during
the merge window. We can sort out separately how to carry the patch
around in -next until then since the powerpc tree will have a dependency
on it.
I haven't had a chance to test or even build on most architectures, the
patch is reasonably trivial but I may have screwed up regardless, I
appologize in advance, let me know if something is wrong.
arch/alpha/include/asm/tlb.h | 4 ++--
arch/arm/include/asm/tlb.h | 4 ++--
arch/avr32/include/asm/pgalloc.h | 2 +-
arch/cris/include/asm/pgalloc.h | 2 +-
arch/frv/include/asm/pgalloc.h | 4 ++--
arch/frv/include/asm/pgtable.h | 2 +-
arch/ia64/include/asm/pgalloc.h | 6 +++---
arch/ia64/include/asm/tlb.h | 12 ++++++------
arch/m32r/include/asm/pgalloc.h | 4 ++--
arch/m68k/include/asm/motorola_pgalloc.h | 6 ++++--
arch/m68k/include/asm/sun3_pgalloc.h | 4 ++--
arch/microblaze/include/asm/pgalloc.h | 4 ++--
arch/mips/include/asm/pgalloc.h | 6 +++---
arch/mn10300/include/asm/pgalloc.h | 2 +-
arch/parisc/include/asm/tlb.h | 4 ++--
arch/powerpc/include/asm/pgalloc-32.h | 2 +-
arch/powerpc/include/asm/pgalloc-64.h | 4 ++--
arch/powerpc/include/asm/pgalloc.h | 6 +++---
arch/powerpc/mm/hugetlbpage.c | 4 ++--
arch/s390/include/asm/tlb.h | 9 ++++++---
arch/sh/include/asm/pgalloc.h | 4 ++--
arch/sh/include/asm/tlb.h | 6 +++---
arch/sparc/include/asm/pgalloc_32.h | 8 ++++----
arch/sparc/include/asm/tlb_64.h | 6 +++---
arch/um/include/asm/pgalloc.h | 4 ++--
arch/um/include/asm/tlb.h | 6 +++---
arch/x86/include/asm/pgalloc.h | 25 ++++++++++++++++++++++---
arch/x86/mm/pgtable.c | 6 +++---
arch/xtensa/include/asm/tlb.h | 2 +-
include/asm-generic/4level-fixup.h | 4 ++--
include/asm-generic/pgtable-nopmd.h | 2 +-
include/asm-generic/pgtable-nopud.h | 2 +-
include/asm-generic/tlb.h | 12 ++++++------
mm/memory.c | 11 ++++++-----
34 files changed, 107 insertions(+), 82 deletions(-)
--- linux-work.orig/arch/powerpc/include/asm/pgalloc-32.h 2009-02-05 16:22:24.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pgalloc-32.h 2009-07-15 17:42:43.000000000 +1000
@@ -16,7 +16,7 @@ extern void pgd_free(struct mm_struct *m
*/
/* #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) */
#define pmd_free(mm, x) do { } while (0)
-#define __pmd_free_tlb(tlb,x) do { } while (0)
+#define __pmd_free_tlb(tlb,x,a) do { } while (0)
/* #define pgd_populate(mm, pmd, pte) BUG() */
#ifndef CONFIG_BOOKE
Index: linux-work/arch/powerpc/include/asm/pgalloc-64.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/pgalloc-64.h 2009-02-05 16:22:24.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pgalloc-64.h 2009-07-15 17:42:43.000000000 +1000
@@ -118,11 +118,11 @@ static inline void pgtable_free(pgtable_
kmem_cache_free(pgtable_cache[cachenum], p);
}
-#define __pmd_free_tlb(tlb, pmd) \
+#define __pmd_free_tlb(tlb, pmd,addr) \
pgtable_free_tlb(tlb, pgtable_free_cache(pmd, \
PMD_CACHE_NUM, PMD_TABLE_SIZE-1))
#ifndef CONFIG_PPC_64K_PAGES
-#define __pud_free_tlb(tlb, pud) \
+#define __pud_free_tlb(tlb, pud, addr) \
pgtable_free_tlb(tlb, pgtable_free_cache(pud, \
PUD_CACHE_NUM, PUD_TABLE_SIZE-1))
#endif /* CONFIG_PPC_64K_PAGES */
Index: linux-work/arch/powerpc/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/powerpc/include/asm/pgalloc.h 2009-02-05 16:22:24.000000000 +1100
+++ linux-work/arch/powerpc/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -38,14 +38,14 @@ static inline pgtable_free_t pgtable_fre
extern void pgtable_free_tlb(struct mmu_gather *tlb, pgtable_free_t pgf);
#ifdef CONFIG_SMP
-#define __pte_free_tlb(tlb,ptepage) \
+#define __pte_free_tlb(tlb,ptepage,address) \
do { \
pgtable_page_dtor(ptepage); \
pgtable_free_tlb(tlb, pgtable_free_cache(page_address(ptepage), \
- PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
+ PTE_NONCACHE_NUM, PTE_TABLE_SIZE-1)); \
} while (0)
#else
-#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte))
+#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, (pte))
#endif
Index: linux-work/include/asm-generic/pgtable-nopmd.h
===================================================================
--- linux-work.orig/include/asm-generic/pgtable-nopmd.h 2009-02-05 16:23:01.000000000 +1100
+++ linux-work/include/asm-generic/pgtable-nopmd.h 2009-07-15 17:42:43.000000000 +1000
@@ -59,7 +59,7 @@ static inline pmd_t * pmd_offset(pud_t *
static inline void pmd_free(struct mm_struct *mm, pmd_t *pmd)
{
}
-#define __pmd_free_tlb(tlb, x) do { } while (0)
+#define __pmd_free_tlb(tlb, x, a) do { } while (0)
#undef pmd_addr_end
#define pmd_addr_end(addr, end) (end)
Index: linux-work/include/asm-generic/pgtable-nopud.h
===================================================================
--- linux-work.orig/include/asm-generic/pgtable-nopud.h 2009-02-05 16:23:01.000000000 +1100
+++ linux-work/include/asm-generic/pgtable-nopud.h 2009-07-15 17:42:43.000000000 +1000
@@ -52,7 +52,7 @@ static inline pud_t * pud_offset(pgd_t *
*/
#define pud_alloc_one(mm, address) NULL
#define pud_free(mm, x) do { } while (0)
-#define __pud_free_tlb(tlb, x) do { } while (0)
+#define __pud_free_tlb(tlb, x, a) do { } while (0)
#undef pud_addr_end
#define pud_addr_end(addr, end) (end)
Index: linux-work/include/asm-generic/tlb.h
===================================================================
--- linux-work.orig/include/asm-generic/tlb.h 2009-02-05 16:23:01.000000000 +1100
+++ linux-work/include/asm-generic/tlb.h 2009-07-15 17:42:43.000000000 +1000
@@ -123,24 +123,24 @@ static inline void tlb_remove_page(struc
__tlb_remove_tlb_entry(tlb, ptep, address); \
} while (0)
-#define pte_free_tlb(tlb, ptep) \
+#define pte_free_tlb(tlb, ptep, address) \
do { \
tlb->need_flush = 1; \
- __pte_free_tlb(tlb, ptep); \
+ __pte_free_tlb(tlb, ptep, address); \
} while (0)
#ifndef __ARCH_HAS_4LEVEL_HACK
-#define pud_free_tlb(tlb, pudp) \
+#define pud_free_tlb(tlb, pudp, address) \
do { \
tlb->need_flush = 1; \
- __pud_free_tlb(tlb, pudp); \
+ __pud_free_tlb(tlb, pudp, address); \
} while (0)
#endif
-#define pmd_free_tlb(tlb, pmdp) \
+#define pmd_free_tlb(tlb, pmdp, address) \
do { \
tlb->need_flush = 1; \
- __pmd_free_tlb(tlb, pmdp); \
+ __pmd_free_tlb(tlb, pmdp, address); \
} while (0)
#define tlb_migrate_finish(mm) do {} while (0)
Index: linux-work/mm/memory.c
===================================================================
--- linux-work.orig/mm/memory.c 2009-07-08 15:53:55.000000000 +1000
+++ linux-work/mm/memory.c 2009-07-15 17:42:43.000000000 +1000
@@ -135,11 +135,12 @@ void pmd_clear_bad(pmd_t *pmd)
* Note: this doesn't free the actual pages themselves. That
* has been handled earlier when unmapping all the memory regions.
*/
-static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd)
+static void free_pte_range(struct mmu_gather *tlb, pmd_t *pmd,
+ unsigned long addr)
{
pgtable_t token = pmd_pgtable(*pmd);
pmd_clear(pmd);
- pte_free_tlb(tlb, token);
+ pte_free_tlb(tlb, token, addr);
tlb->mm->nr_ptes--;
}
@@ -157,7 +158,7 @@ static inline void free_pmd_range(struct
next = pmd_addr_end(addr, end);
if (pmd_none_or_clear_bad(pmd))
continue;
- free_pte_range(tlb, pmd);
+ free_pte_range(tlb, pmd, addr);
} while (pmd++, addr = next, addr != end);
start &= PUD_MASK;
@@ -173,7 +174,7 @@ static inline void free_pmd_range(struct
pmd = pmd_offset(pud, start);
pud_clear(pud);
- pmd_free_tlb(tlb, pmd);
+ pmd_free_tlb(tlb, pmd, start);
}
static inline void free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
@@ -206,7 +207,7 @@ static inline void free_pud_range(struct
pud = pud_offset(pgd, start);
pgd_clear(pgd);
- pud_free_tlb(tlb, pud);
+ pud_free_tlb(tlb, pud, start);
}
/*
Index: linux-work/arch/powerpc/mm/hugetlbpage.c
===================================================================
--- linux-work.orig/arch/powerpc/mm/hugetlbpage.c 2009-02-05 16:22:25.000000000 +1100
+++ linux-work/arch/powerpc/mm/hugetlbpage.c 2009-07-15 17:42:43.000000000 +1000
@@ -305,7 +305,7 @@ static void hugetlb_free_pmd_range(struc
pmd = pmd_offset(pud, start);
pud_clear(pud);
- pmd_free_tlb(tlb, pmd);
+ pmd_free_tlb(tlb, pmd, start);
}
static void hugetlb_free_pud_range(struct mmu_gather *tlb, pgd_t *pgd,
@@ -348,7 +348,7 @@ static void hugetlb_free_pud_range(struc
pud = pud_offset(pgd, start);
pgd_clear(pgd);
- pud_free_tlb(tlb, pud);
+ pud_free_tlb(tlb, pud, start);
}
/*
Index: linux-work/arch/alpha/include/asm/tlb.h
===================================================================
--- linux-work.orig/arch/alpha/include/asm/tlb.h 2009-02-05 16:22:17.000000000 +1100
+++ linux-work/arch/alpha/include/asm/tlb.h 2009-07-15 17:42:43.000000000 +1000
@@ -9,7 +9,7 @@
#include <asm-generic/tlb.h>
-#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte)
-#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd)
+#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte)
+#define __pmd_free_tlb(tlb, pmd, address) pmd_free((tlb)->mm, pmd)
#endif
Index: linux-work/arch/avr32/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/avr32/include/asm/pgalloc.h 2009-02-05 16:22:19.000000000 +1100
+++ linux-work/arch/avr32/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -83,7 +83,7 @@ static inline void pte_free(struct mm_st
quicklist_free_page(QUICK_PT, NULL, pte);
}
-#define __pte_free_tlb(tlb,pte) \
+#define __pte_free_tlb(tlb,pte,addr) \
do { \
pgtable_page_dtor(pte); \
tlb_remove_page((tlb), pte); \
Index: linux-work/arch/cris/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/cris/include/asm/pgalloc.h 2009-02-05 16:22:19.000000000 +1100
+++ linux-work/arch/cris/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -47,7 +47,7 @@ static inline void pte_free(struct mm_st
__free_page(pte);
}
-#define __pte_free_tlb(tlb,pte) \
+#define __pte_free_tlb(tlb,pte,address) \
do { \
pgtable_page_dtor(pte); \
tlb_remove_page((tlb), pte); \
Index: linux-work/arch/frv/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/frv/include/asm/pgalloc.h 2009-04-30 14:19:03.000000000 +1000
+++ linux-work/arch/frv/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -49,7 +49,7 @@ static inline void pte_free(struct mm_st
__free_page(pte);
}
-#define __pte_free_tlb(tlb,pte) \
+#define __pte_free_tlb(tlb,pte,address) \
do { \
pgtable_page_dtor(pte); \
tlb_remove_page((tlb),(pte)); \
@@ -62,7 +62,7 @@ do { \
*/
#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *) 2); })
#define pmd_free(mm, x) do { } while (0)
-#define __pmd_free_tlb(tlb,x) do { } while (0)
+#define __pmd_free_tlb(tlb,x,a) do { } while (0)
#endif /* CONFIG_MMU */
Index: linux-work/arch/ia64/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/ia64/include/asm/pgalloc.h 2009-02-05 16:22:19.000000000 +1100
+++ linux-work/arch/ia64/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -48,7 +48,7 @@ static inline void pud_free(struct mm_st
{
quicklist_free(0, NULL, pud);
}
-#define __pud_free_tlb(tlb, pud) pud_free((tlb)->mm, pud)
+#define __pud_free_tlb(tlb, pud, address) pud_free((tlb)->mm, pud)
#endif /* CONFIG_PGTABLE_4 */
static inline void
@@ -67,7 +67,7 @@ static inline void pmd_free(struct mm_st
quicklist_free(0, NULL, pmd);
}
-#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd)
+#define __pmd_free_tlb(tlb, pmd, address) pmd_free((tlb)->mm, pmd)
static inline void
pmd_populate(struct mm_struct *mm, pmd_t * pmd_entry, pgtable_t pte)
@@ -117,6 +117,6 @@ static inline void check_pgt_cache(void)
quicklist_trim(0, NULL, 25, 16);
}
-#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte)
+#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte)
#endif /* _ASM_IA64_PGALLOC_H */
Index: linux-work/arch/ia64/include/asm/tlb.h
===================================================================
--- linux-work.orig/arch/ia64/include/asm/tlb.h 2009-02-05 16:22:19.000000000 +1100
+++ linux-work/arch/ia64/include/asm/tlb.h 2009-07-15 17:42:43.000000000 +1000
@@ -236,22 +236,22 @@ do { \
__tlb_remove_tlb_entry(tlb, ptep, addr); \
} while (0)
-#define pte_free_tlb(tlb, ptep) \
+#define pte_free_tlb(tlb, ptep, address) \
do { \
tlb->need_flush = 1; \
- __pte_free_tlb(tlb, ptep); \
+ __pte_free_tlb(tlb, ptep, address); \
} while (0)
-#define pmd_free_tlb(tlb, ptep) \
+#define pmd_free_tlb(tlb, ptep, address) \
do { \
tlb->need_flush = 1; \
- __pmd_free_tlb(tlb, ptep); \
+ __pmd_free_tlb(tlb, ptep, address); \
} while (0)
-#define pud_free_tlb(tlb, pudp) \
+#define pud_free_tlb(tlb, pudp, address) \
do { \
tlb->need_flush = 1; \
- __pud_free_tlb(tlb, pudp); \
+ __pud_free_tlb(tlb, pudp, address); \
} while (0)
#endif /* _ASM_IA64_TLB_H */
Index: linux-work/arch/m32r/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/m32r/include/asm/pgalloc.h 2009-04-30 14:19:03.000000000 +1000
+++ linux-work/arch/m32r/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -58,7 +58,7 @@ static inline void pte_free(struct mm_st
__free_page(pte);
}
-#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte))
+#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte))
/*
* allocating and freeing a pmd is trivial: the 1-entry pmd is
@@ -68,7 +68,7 @@ static inline void pte_free(struct mm_st
#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); })
#define pmd_free(mm, x) do { } while (0)
-#define __pmd_free_tlb(tlb, x) do { } while (0)
+#define __pmd_free_tlb(tlb, x, addr) do { } while (0)
#define pgd_populate(mm, pmd, pte) BUG()
#define check_pgt_cache() do { } while (0)
Index: linux-work/arch/m68k/include/asm/motorola_pgalloc.h
===================================================================
--- linux-work.orig/arch/m68k/include/asm/motorola_pgalloc.h 2009-02-05 16:22:20.000000000 +1100
+++ linux-work/arch/m68k/include/asm/motorola_pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -54,7 +54,8 @@ static inline void pte_free(struct mm_st
__free_page(page);
}
-static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page)
+static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t page,
+ unsigned long address)
{
pgtable_page_dtor(page);
cache_page(kmap(page));
@@ -73,7 +74,8 @@ static inline int pmd_free(struct mm_str
return free_pointer_table(pmd);
}
-static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
+static inline int __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
+ unsigned long address)
{
return free_pointer_table(pmd);
}
Index: linux-work/arch/m68k/include/asm/sun3_pgalloc.h
===================================================================
--- linux-work.orig/arch/m68k/include/asm/sun3_pgalloc.h 2009-02-05 16:22:20.000000000 +1100
+++ linux-work/arch/m68k/include/asm/sun3_pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -32,7 +32,7 @@ static inline void pte_free(struct mm_st
__free_page(page);
}
-#define __pte_free_tlb(tlb,pte) \
+#define __pte_free_tlb(tlb,pte,addr) \
do { \
pgtable_page_dtor(pte); \
tlb_remove_page((tlb), pte); \
@@ -80,7 +80,7 @@ static inline void pmd_populate(struct m
* inside the pgd, so has no extra memory associated with it.
*/
#define pmd_free(mm, x) do { } while (0)
-#define __pmd_free_tlb(tlb, x) do { } while (0)
+#define __pmd_free_tlb(tlb, x, addr) do { } while (0)
static inline void pgd_free(struct mm_struct *mm, pgd_t *pgd)
{
Index: linux-work/arch/microblaze/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/microblaze/include/asm/pgalloc.h 2009-07-08 15:53:49.000000000 +1000
+++ linux-work/arch/microblaze/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -180,7 +180,7 @@ extern inline void pte_free(struct mm_st
__free_page(ptepage);
}
-#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, (pte))
+#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, (pte))
#define pmd_populate(mm, pmd, pte) (pmd_val(*(pmd)) = page_address(pte))
@@ -193,7 +193,7 @@ extern inline void pte_free(struct mm_st
*/
#define pmd_alloc_one(mm, address) ({ BUG(); ((pmd_t *)2); })
/*#define pmd_free(mm, x) do { } while (0)*/
-#define __pmd_free_tlb(tlb, x) do { } while (0)
+#define __pmd_free_tlb(tlb, x, addr) do { } while (0)
#define pgd_populate(mm, pmd, pte) BUG()
extern int do_check_pgt_cache(int, int);
Index: linux-work/arch/mips/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/mips/include/asm/pgalloc.h 2009-02-05 16:22:21.000000000 +1100
+++ linux-work/arch/mips/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -98,7 +98,7 @@ static inline void pte_free(struct mm_st
__free_pages(pte, PTE_ORDER);
}
-#define __pte_free_tlb(tlb,pte) \
+#define __pte_free_tlb(tlb,pte,address) \
do { \
pgtable_page_dtor(pte); \
tlb_remove_page((tlb), pte); \
@@ -111,7 +111,7 @@ do { \
* inside the pgd, so has no extra memory associated with it.
*/
#define pmd_free(mm, x) do { } while (0)
-#define __pmd_free_tlb(tlb, x) do { } while (0)
+#define __pmd_free_tlb(tlb, x, addr) do { } while (0)
#endif
@@ -132,7 +132,7 @@ static inline void pmd_free(struct mm_st
free_pages((unsigned long)pmd, PMD_ORDER);
}
-#define __pmd_free_tlb(tlb, x) pmd_free((tlb)->mm, x)
+#define __pmd_free_tlb(tlb, x, addr) pmd_free((tlb)->mm, x)
#endif
Index: linux-work/arch/mn10300/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/mn10300/include/asm/pgalloc.h 2009-04-30 14:19:03.000000000 +1000
+++ linux-work/arch/mn10300/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -51,6 +51,6 @@ static inline void pte_free(struct mm_st
}
-#define __pte_free_tlb(tlb, pte) tlb_remove_page((tlb), (pte))
+#define __pte_free_tlb(tlb, pte, addr) tlb_remove_page((tlb), (pte))
#endif /* _ASM_PGALLOC_H */
Index: linux-work/arch/parisc/include/asm/tlb.h
===================================================================
--- linux-work.orig/arch/parisc/include/asm/tlb.h 2009-02-05 16:22:21.000000000 +1100
+++ linux-work/arch/parisc/include/asm/tlb.h 2009-07-15 17:42:43.000000000 +1000
@@ -21,7 +21,7 @@ do { if (!(tlb)->fullmm) \
#include <asm-generic/tlb.h>
-#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd)
-#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte)
+#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd)
+#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
#endif
Index: linux-work/arch/s390/include/asm/tlb.h
===================================================================
--- linux-work.orig/arch/s390/include/asm/tlb.h 2009-02-05 16:22:25.000000000 +1100
+++ linux-work/arch/s390/include/asm/tlb.h 2009-07-15 17:42:43.000000000 +1000
@@ -96,7 +96,8 @@ static inline void tlb_remove_page(struc
* pte_free_tlb frees a pte table and clears the CRSTE for the
* page table from the tlb.
*/
-static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte)
+static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte,
+ unsigned long address)
{
if (!tlb->fullmm) {
tlb->array[tlb->nr_ptes++] = pte;
@@ -113,7 +114,8 @@ static inline void pte_free_tlb(struct m
* as the pgd. pmd_free_tlb checks the asce_limit against 2GB
* to avoid the double free of the pmd in this case.
*/
-static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
+static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
+ unsigned long address)
{
#ifdef __s390x__
if (tlb->mm->context.asce_limit <= (1UL << 31))
@@ -134,7 +136,8 @@ static inline void pmd_free_tlb(struct m
* as the pgd. pud_free_tlb checks the asce_limit against 4TB
* to avoid the double free of the pud in this case.
*/
-static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
+static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
+ unsigned long address)
{
#ifdef __s390x__
if (tlb->mm->context.asce_limit <= (1UL << 42))
Index: linux-work/arch/sh/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/sh/include/asm/pgalloc.h 2009-02-05 16:22:26.000000000 +1100
+++ linux-work/arch/sh/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -73,7 +73,7 @@ static inline void pte_free(struct mm_st
quicklist_free_page(QUICK_PT, NULL, pte);
}
-#define __pte_free_tlb(tlb,pte) \
+#define __pte_free_tlb(tlb,pte,addr) \
do { \
pgtable_page_dtor(pte); \
tlb_remove_page((tlb), (pte)); \
@@ -85,7 +85,7 @@ do { \
*/
#define pmd_free(mm, x) do { } while (0)
-#define __pmd_free_tlb(tlb,x) do { } while (0)
+#define __pmd_free_tlb(tlb,x,addr) do { } while (0)
static inline void check_pgt_cache(void)
{
Index: linux-work/arch/sh/include/asm/tlb.h
===================================================================
--- linux-work.orig/arch/sh/include/asm/tlb.h 2009-03-31 13:22:05.000000000 +1100
+++ linux-work/arch/sh/include/asm/tlb.h 2009-07-15 17:42:43.000000000 +1000
@@ -91,9 +91,9 @@ tlb_end_vma(struct mmu_gather *tlb, stru
}
#define tlb_remove_page(tlb,page) free_page_and_swap_cache(page)
-#define pte_free_tlb(tlb, ptep) pte_free((tlb)->mm, ptep)
-#define pmd_free_tlb(tlb, pmdp) pmd_free((tlb)->mm, pmdp)
-#define pud_free_tlb(tlb, pudp) pud_free((tlb)->mm, pudp)
+#define pte_free_tlb(tlb, ptep, addr) pte_free((tlb)->mm, ptep)
+#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp)
+#define pud_free_tlb(tlb, pudp, addr) pud_free((tlb)->mm, pudp)
#define tlb_migrate_finish(mm) do { } while (0)
Index: linux-work/arch/sparc/include/asm/pgalloc_32.h
===================================================================
--- linux-work.orig/arch/sparc/include/asm/pgalloc_32.h 2009-02-05 16:22:26.000000000 +1100
+++ linux-work/arch/sparc/include/asm/pgalloc_32.h 2009-07-15 17:42:43.000000000 +1000
@@ -44,8 +44,8 @@ BTFIXUPDEF_CALL(pmd_t *, pmd_alloc_one,
BTFIXUPDEF_CALL(void, free_pmd_fast, pmd_t *)
#define free_pmd_fast(pmd) BTFIXUP_CALL(free_pmd_fast)(pmd)
-#define pmd_free(mm, pmd) free_pmd_fast(pmd)
-#define __pmd_free_tlb(tlb, pmd) pmd_free((tlb)->mm, pmd)
+#define pmd_free(mm, pmd) free_pmd_fast(pmd)
+#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tlb)->mm, pmd)
BTFIXUPDEF_CALL(void, pmd_populate, pmd_t *, struct page *)
#define pmd_populate(MM, PMD, PTE) BTFIXUP_CALL(pmd_populate)(PMD, PTE)
@@ -62,7 +62,7 @@ BTFIXUPDEF_CALL(void, free_pte_fast, pte
#define pte_free_kernel(mm, pte) BTFIXUP_CALL(free_pte_fast)(pte)
BTFIXUPDEF_CALL(void, pte_free, pgtable_t )
-#define pte_free(mm, pte) BTFIXUP_CALL(pte_free)(pte)
-#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte)
+#define pte_free(mm, pte) BTFIXUP_CALL(pte_free)(pte)
+#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte)
#endif /* _SPARC_PGALLOC_H */
Index: linux-work/arch/sparc/include/asm/tlb_64.h
===================================================================
--- linux-work.orig/arch/sparc/include/asm/tlb_64.h 2009-03-31 13:22:05.000000000 +1100
+++ linux-work/arch/sparc/include/asm/tlb_64.h 2009-07-15 17:42:43.000000000 +1000
@@ -100,9 +100,9 @@ static inline void tlb_remove_page(struc
}
#define tlb_remove_tlb_entry(mp,ptep,addr) do { } while (0)
-#define pte_free_tlb(mp, ptepage) pte_free((mp)->mm, ptepage)
-#define pmd_free_tlb(mp, pmdp) pmd_free((mp)->mm, pmdp)
-#define pud_free_tlb(tlb,pudp) __pud_free_tlb(tlb,pudp)
+#define pte_free_tlb(mp, ptepage, addr) pte_free((mp)->mm, ptepage)
+#define pmd_free_tlb(mp, pmdp, addr) pmd_free((mp)->mm, pmdp)
+#define pud_free_tlb(tlb,pudp, addr) __pud_free_tlb(tlb,pudp,addr)
#define tlb_migrate_finish(mm) do { } while (0)
#define tlb_start_vma(tlb, vma) do { } while (0)
Index: linux-work/arch/um/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/um/include/asm/pgalloc.h 2009-04-30 14:19:04.000000000 +1000
+++ linux-work/arch/um/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -40,7 +40,7 @@ static inline void pte_free(struct mm_st
__free_page(pte);
}
-#define __pte_free_tlb(tlb,pte) \
+#define __pte_free_tlb(tlb,pte, address) \
do { \
pgtable_page_dtor(pte); \
tlb_remove_page((tlb),(pte)); \
@@ -53,7 +53,7 @@ static inline void pmd_free(struct mm_st
free_page((unsigned long)pmd);
}
-#define __pmd_free_tlb(tlb,x) tlb_remove_page((tlb),virt_to_page(x))
+#define __pmd_free_tlb(tlb,x, address) tlb_remove_page((tlb),virt_to_page(x))
#endif
#define check_pgt_cache() do { } while (0)
Index: linux-work/arch/um/include/asm/tlb.h
===================================================================
--- linux-work.orig/arch/um/include/asm/tlb.h 2009-02-05 16:22:28.000000000 +1100
+++ linux-work/arch/um/include/asm/tlb.h 2009-07-15 17:42:43.000000000 +1000
@@ -116,11 +116,11 @@ static inline void tlb_remove_page(struc
__tlb_remove_tlb_entry(tlb, ptep, address); \
} while (0)
-#define pte_free_tlb(tlb, ptep) __pte_free_tlb(tlb, ptep)
+#define pte_free_tlb(tlb, ptep, addr) __pte_free_tlb(tlb, ptep, addr)
-#define pud_free_tlb(tlb, pudp) __pud_free_tlb(tlb, pudp)
+#define pud_free_tlb(tlb, pudp, addr) __pud_free_tlb(tlb, pudp, addr)
-#define pmd_free_tlb(tlb, pmdp) __pmd_free_tlb(tlb, pmdp)
+#define pmd_free_tlb(tlb, pmdp, addr) __pmd_free_tlb(tlb, pmdp, addr)
#define tlb_migrate_finish(mm) do {} while (0)
Index: linux-work/arch/x86/include/asm/pgalloc.h
===================================================================
--- linux-work.orig/arch/x86/include/asm/pgalloc.h 2009-02-05 16:22:28.000000000 +1100
+++ linux-work/arch/x86/include/asm/pgalloc.h 2009-07-15 17:42:43.000000000 +1000
@@ -46,7 +46,13 @@ static inline void pte_free(struct mm_st
__free_page(pte);
}
-extern void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte);
+extern void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte);
+
+static inline void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte,
+ unsigned long address)
+{
+ ___pte_free_tlb(tlb, pte);
+}
static inline void pmd_populate_kernel(struct mm_struct *mm,
pmd_t *pmd, pte_t *pte)
@@ -78,7 +84,13 @@ static inline void pmd_free(struct mm_st
free_page((unsigned long)pmd);
}
-extern void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd);
+extern void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd);
+
+static inline void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd,
+ unsigned long adddress)
+{
+ ___pmd_free_tlb(tlb, pmd);
+}
#ifdef CONFIG_X86_PAE
extern void pud_populate(struct mm_struct *mm, pud_t *pudp, pmd_t *pmd);
@@ -108,7 +120,14 @@ static inline void pud_free(struct mm_st
free_page((unsigned long)pud);
}
-extern void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud);
+extern void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud);
+
+static inline void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud,
+ unsigned long address)
+{
+ ___pud_free_tlb(tlb, pud);
+}
+
#endif /* PAGETABLE_LEVELS > 3 */
#endif /* PAGETABLE_LEVELS > 2 */
Index: linux-work/arch/x86/mm/pgtable.c
===================================================================
--- linux-work.orig/arch/x86/mm/pgtable.c 2009-07-08 15:53:51.000000000 +1000
+++ linux-work/arch/x86/mm/pgtable.c 2009-07-15 17:42:43.000000000 +1000
@@ -25,7 +25,7 @@ pgtable_t pte_alloc_one(struct mm_struct
return pte;
}
-void __pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
+void ___pte_free_tlb(struct mmu_gather *tlb, struct page *pte)
{
pgtable_page_dtor(pte);
paravirt_release_pte(page_to_pfn(pte));
@@ -33,14 +33,14 @@ void __pte_free_tlb(struct mmu_gather *t
}
#if PAGETABLE_LEVELS > 2
-void __pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
+void ___pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd)
{
paravirt_release_pmd(__pa(pmd) >> PAGE_SHIFT);
tlb_remove_page(tlb, virt_to_page(pmd));
}
#if PAGETABLE_LEVELS > 3
-void __pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
+void ___pud_free_tlb(struct mmu_gather *tlb, pud_t *pud)
{
paravirt_release_pud(__pa(pud) >> PAGE_SHIFT);
tlb_remove_page(tlb, virt_to_page(pud));
Index: linux-work/arch/xtensa/include/asm/tlb.h
===================================================================
--- linux-work.orig/arch/xtensa/include/asm/tlb.h 2009-02-05 16:22:29.000000000 +1100
+++ linux-work/arch/xtensa/include/asm/tlb.h 2009-07-15 17:42:43.000000000 +1000
@@ -42,6 +42,6 @@
#include <asm-generic/tlb.h>
-#define __pte_free_tlb(tlb, pte) pte_free((tlb)->mm, pte)
+#define __pte_free_tlb(tlb, pte, address) pte_free((tlb)->mm, pte)
#endif /* _XTENSA_TLB_H */
Index: linux-work/arch/arm/include/asm/tlb.h
===================================================================
--- linux-work.orig/arch/arm/include/asm/tlb.h 2009-07-15 17:45:18.000000000 +1000
+++ linux-work/arch/arm/include/asm/tlb.h 2009-07-15 17:45:28.000000000 +1000
@@ -102,8 +102,8 @@ tlb_end_vma(struct mmu_gather *tlb, stru
}
#define tlb_remove_page(tlb,page) free_page_and_swap_cache(page)
-#define pte_free_tlb(tlb, ptep) pte_free((tlb)->mm, ptep)
-#define pmd_free_tlb(tlb, pmdp) pmd_free((tlb)->mm, pmdp)
+#define pte_free_tlb(tlb, ptep, addr) pte_free((tlb)->mm, ptep)
+#define pmd_free_tlb(tlb, pmdp, addr) pmd_free((tlb)->mm, pmdp)
#define tlb_migrate_finish(mm) do { } while (0)
Index: linux-work/arch/frv/include/asm/pgtable.h
===================================================================
--- linux-work.orig/arch/frv/include/asm/pgtable.h 2009-07-15 17:45:52.000000000 +1000
+++ linux-work/arch/frv/include/asm/pgtable.h 2009-07-15 17:45:59.000000000 +1000
@@ -225,7 +225,7 @@ static inline pud_t *pud_offset(pgd_t *p
*/
#define pud_alloc_one(mm, address) NULL
#define pud_free(mm, x) do { } while (0)
-#define __pud_free_tlb(tlb, x) do { } while (0)
+#define __pud_free_tlb(tlb, x, address) do { } while (0)
/*
* The "pud_xxx()" functions here are trivial for a folded two-level
Index: linux-work/include/asm-generic/4level-fixup.h
===================================================================
--- linux-work.orig/include/asm-generic/4level-fixup.h 2009-07-15 17:44:05.000000000 +1000
+++ linux-work/include/asm-generic/4level-fixup.h 2009-07-15 17:44:25.000000000 +1000
@@ -27,9 +27,9 @@
#define pud_page_vaddr(pud) pgd_page_vaddr(pud)
#undef pud_free_tlb
-#define pud_free_tlb(tlb, x) do { } while (0)
+#define pud_free_tlb(tlb, x, addr) do { } while (0)
#define pud_free(mm, x) do { } while (0)
-#define __pud_free_tlb(tlb, x) do { } while (0)
+#define __pud_free_tlb(tlb, x, addr) do { } while (0)
#undef pud_addr_end
#define pud_addr_end(addr, end) (end)
^ permalink raw reply
* ethernet driver - problem capturing own packet in promiscous mode
From: sudheer a @ 2009-07-15 8:36 UTC (permalink / raw)
To: linuxppc-dev
[-- Attachment #1: Type: text/plain, Size: 729 bytes --]
Hi all
In ethernet driver i need to enable promiscous mode and have to capture the
packet that is sent by the same ethernet.
The board is connected to a packet generator and could send/receive packets
whenever i need .
In the board ethernet driver , I made sure that am sending only broadcast
packets and promisc mode is enabled but the packets are not captured. If i
am sending a packet to the board from packetgenerator it is receiving.
Could any one please suggest me any clues.
Having the promisc enabled:
Packet sent by packetgenerator is received by board.
Packet sent by board is received by packetgenerator, The same packet should
be captured by board as promiscuous is enabled. but not happening.
Thanks
Sudheer
[-- Attachment #2: Type: text/html, Size: 958 bytes --]
^ permalink raw reply
* RE: ethernet driver - problem capturing own packet in promiscous mode
From: Cote, Sylvain @ 2009-07-15 12:22 UTC (permalink / raw)
To: sudheer a; +Cc: linuxppc-dev@lists.ozlabs.org
In-Reply-To: <4312c3250907150136y4c98c78ak1b4fe50534248442@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1728 bytes --]
> Hi all
> In ethernet driver i need to enable promiscous mode and have to capture the packet that is sent by the same ethernet.
> The board is connected to a packet generator and could send/receive packets whenever i need .
> In the board ethernet driver , I made sure that am sending only broadcast packets and promisc mode is enabled but the packets are not captured. If i am sending a packet to the board from packetgenerator it is receiving.
> Could any one please suggest me any clues.
> Having the promisc enabled:
> Packet sent by packetgenerator is received by board.
> Packet sent by board is received by packetgenerator, The same packet should be captured by board as promiscuous is enabled. but not happening.
The Ethernet interface that sent the packet will never receive the packet it sent even if you are in promiscuous mode. To be able to do that you should put your interface in loopback mode.
In promiscuous mode, you will be able to receive any packets sent by other interfaces (broadcast, multicast and also unicast that is not directed to you interface MAC address). But not
from your interface.
Regards
Sylvain
This electronic message may contain proprietary and confidential information of Verint Systems Inc., its affiliates and/or subsidiaries.
The information is intended to be for the use of the individual(s) or
entity(ies) named above. If you are not the intended recipient (or authorized to receive this e-mail for the intended recipient), you may not use, copy, disclose or distribute to anyone this message or any information contained in this message. If you have received this electronic message in error, please notify us by replying to this e-mail.
\r
[-- Attachment #2: Type: text/html, Size: 6177 bytes --]
^ permalink raw reply
* Re: [RFC/PATCH] mm: Pass virtual address to [__]p{te, ud, md}_free_tlb()
From: Nick Piggin @ 2009-07-15 13:56 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Linux-Arch, Linux Memory Management, Hugh Dickins, linux-kernel,
linuxppc-dev
In-Reply-To: <20090715074952.A36C7DDDB2@ozlabs.org>
On Wed, Jul 15, 2009 at 05:49:47PM +1000, Benjamin Herrenschmidt wrote:
> Upcoming paches to support the new 64-bit "BookE" powerpc architecture
> will need to have the virtual address corresponding to PTE page when
> freeing it, due to the way the HW table walker works.
>
> Basically, the TLB can be loaded with "large" pages that cover the whole
> virtual space (well, sort-of, half of it actually) represented by a PTE
> page, and which contain an "indirect" bit indicating that this TLB entry
> RPN points to an array of PTEs from which the TLB can then create direct
> entries.
RPN is PFN in ppc speak, right?
> Thus, in order to invalidate those when PTE pages are deleted,
> we need the virtual address to pass to tlbilx or tlbivax instructions.
Interesting arrangement. So are these last level ptes modifieable
from userspace or something? If not, I wonder if you could manage
them as another level of pointers with the existing pagetable
functions?
> The old trick of sticking it somewhere in the PTE page struct page sucks
> too much, the address is almost readily available in all call sites and
> almost everybody implemets these as macros, so we may as well add the
> argument everywhere. I added it to the pmd and pud variants for consistency.
>
> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> ---
>
> I would like to merge the new support that depends on this in 2.6.32,
> so unless there's major objections, I'd like this to go in early during
> the merge window. We can sort out separately how to carry the patch
> around in -next until then since the powerpc tree will have a dependency
> on it.
Can't see any problem with that.
^ permalink raw reply
* having access to interrupt specifier in map() function
From: Kumar Gala @ 2009-07-15 14:11 UTC (permalink / raw)
To: Benjamin Herrenschmidt; +Cc: linuxppc-dev@ozlabs.org list
Ben,
Do you have any ideas on keeping access to the interrupt specifier
around so when we call map() we have access to it. Our HV guys are
looking at using additional bits in the interrupt specifier to encode
information beyond just level/sense of the IRQ and want to make
decisions based on it during map().
Maybe we can keep it around in irq_map[].
thoughts?
- k
^ permalink raw reply
* booting MPC8313 based board with yaffs2 RFS
From: Rupesh Kumar @ 2009-07-15 14:58 UTC (permalink / raw)
To: linuxppc-dev
Hi
I am using MPC8313 board which is currently booting with JFFS2 root file
system.
I am using linux kernel version 2.6.23 from FreeScale's LTIB for MPC8313.
As, I want it to boot with YAFFS2 root file system, I did compile kernel
with yaffs2 support, craeted yaffs2 rootfile system and passed yaffs2
partiton of nand in bootargs. However it didnot work.
If any one has done it successfully, can please share the steps to be
followed ?
Thanks
Rupesh
^ permalink raw reply
* [PATCH 1/2 v3] fs_enet/mii-fec.c: fix MII speed calculation
From: Wolfgang Denk @ 2009-07-15 15:18 UTC (permalink / raw)
To: linuxppc-dev; +Cc: netdev, Wolfgang Denk
In-Reply-To: <1247578966-9847-1-git-send-email-wd@denx.de>
The MII speed calculation was based on the CPU clock (ppc_proc_freq),
but for MPC512x we must use the bus clock instead.
This patch makes it use the correct clock and makes sure we don't
clobber reserved bits in the MII_SPEED register.
Signed-off-by: Wolfgang Denk <wd@denx.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: <netdev@vger.kernel.org>
---
Please ignore patch v2, it's crap.
Hope this is a bit better.
arch/powerpc/include/asm/mpc5xxx.h | 10 +++++++++
arch/powerpc/sysdev/mpc5xxx_clocks.c | 37 ++++++++++++++++++++++++++++++++++
drivers/net/fs_enet/mii-fec.c | 13 +++++++++--
3 files changed, 57 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/mpc5xxx.h b/arch/powerpc/include/asm/mpc5xxx.h
index 5ce9c5f..86ab29f 100644
--- a/arch/powerpc/include/asm/mpc5xxx.h
+++ b/arch/powerpc/include/asm/mpc5xxx.h
@@ -15,8 +15,18 @@
#ifndef __ASM_POWERPC_MPC5xxx_H__
#define __ASM_POWERPC_MPC5xxx_H__
+#include <linux/of_platform.h>
extern unsigned long mpc5xxx_get_bus_frequency(struct device_node *node);
+#if defined(CONFIG_PPC_MPC512x) || defined(CONFIG_PPC_MPC52xx)
+extern int mpc5xxx_get_mii_speed(struct of_device *ofdev);
+#else
+static inline int mpc5xxx_get_mii_speed(struct of_device *ofdev)
+{
+ return -1;
+}
+#endif
+
#endif /* __ASM_POWERPC_MPC5xxx_H__ */
diff --git a/arch/powerpc/sysdev/mpc5xxx_clocks.c b/arch/powerpc/sysdev/mpc5xxx_clocks.c
index 34e12f9..e26d12b 100644
--- a/arch/powerpc/sysdev/mpc5xxx_clocks.c
+++ b/arch/powerpc/sysdev/mpc5xxx_clocks.c
@@ -31,3 +31,40 @@ mpc5xxx_get_bus_frequency(struct device_node *node)
return p_bus_freq ? *p_bus_freq : 0;
}
EXPORT_SYMBOL(mpc5xxx_get_bus_frequency);
+
+/**
+ * mpc5xxx_get_mii_speed - Get the MII_SPEED value
+ * @node: device node
+ *
+ * Returns the MII_SPEED value for MPC512x and MPC52xx systems.
+ * The value gets computed such that the resulting MDC frequency
+ * is 2.5 MHz or lower.
+ */
+
+int
+mpc5xxx_get_mii_speed(struct of_device *ofdev)
+{
+ unsigned int clock, speed;
+
+ clock = mpc5xxx_get_bus_frequency(ofdev->node);
+
+ if (!clock) {
+ dev_err(&ofdev->dev, "could not determine IPS/IPB clock\n");
+ return -ENODEV;
+ }
+
+ /* scale for a MII clock <= 2.5 MHz */
+ speed = (clock + 2499999) / 2500000;
+
+ /* only 6 bits available for MII speed */
+ if (speed > 0x3F) {
+ speed = 0x3F;
+ dev_err(&ofdev->dev,
+ "MII clock (%d MHz) exceeds max (2.5 MHz)\n",
+ clock / speed);
+ }
+
+ /* Field is in bits 25:30 of MII_SPEED register */
+ return speed << 1;
+}
+EXPORT_SYMBOL(mpc5xxx_get_mii_speed);
diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.c
index 75a0999..a28d39f 100644
--- a/drivers/net/fs_enet/mii-fec.c
+++ b/drivers/net/fs_enet/mii-fec.c
@@ -36,6 +36,7 @@
#include <asm/pgtable.h>
#include <asm/irq.h>
#include <asm/uaccess.h>
+#include <asm/mpc5xxx.h>
#include "fs_enet.h"
#include "fec.h"
@@ -103,7 +104,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
const struct of_device_id *match)
{
- struct device_node *np = NULL;
struct resource res;
struct mii_bus *new_bus;
struct fec_info *fec;
@@ -133,13 +133,20 @@ static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
if (!fec->fecp)
goto out_fec;
- fec->mii_speed = ((ppc_proc_freq + 4999999) / 5000000) << 1;
+ if (of_device_is_compatible(ofdev->node, "fsl,mpc5121-fec-mdio")) {
+ i = mpc5xxx_get_mii_speed(ofdev);
+ if (i < 0)
+ goto out_unmap_regs;
+ fec->mii_speed = i;
+ } else {
+ fec->mii_speed = ((ppc_proc_freq + 4999999) / 5000000) << 1;
+ }
setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX |
FEC_ECNTRL_ETHER_EN);
out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII);
- out_be32(&fec->fecp->fec_mii_speed, fec->mii_speed);
+ clrsetbits_be32(&fec->fecp->fec_mii_speed, 0x7E, fec->mii_speed);
new_bus->phy_mask = ~0;
new_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
--
1.6.0.6
^ permalink raw reply related
* [PATCH 2/2] MPC52xx FEC: be more conservative when setting MII_SPEED register
From: Wolfgang Denk @ 2009-07-15 15:18 UTC (permalink / raw)
To: linuxppc-dev; +Cc: netdev, Wolfgang Denk
In-Reply-To: <1247578966-9847-1-git-send-email-wd@denx.de>
This patch adds error checking and prevents clobbering unrelated bits
(reserved bits or the DIS_PREAMBLE bit) when writing the MII_SPEED
register on MPC52xx systems.
Signed-off-by: Wolfgang Denk <wd@denx.de>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Kumar Gala <galak@kernel.crashing.org>
Cc: <netdev@vger.kernel.org>
---
drivers/net/fec_mpc52xx.c | 2 +-
drivers/net/fec_mpc52xx_phy.c | 6 ++++--
2 files changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
index cc78633..b69d440 100644
--- a/drivers/net/fec_mpc52xx.c
+++ b/drivers/net/fec_mpc52xx.c
@@ -639,7 +639,7 @@ static void mpc52xx_fec_hw_init(struct net_device *dev)
/* set phy speed.
* this can't be done in phy driver, since it needs to be called
* before fec stuff (even on resume) */
- out_be32(&fec->mii_speed, priv->mdio_speed);
+ clrsetbits_be32(&fec->mii_speed, 0x7E, priv->mdio_speed);
}
/**
diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.c
index 31e6d62..f733d43 100644
--- a/drivers/net/fec_mpc52xx_phy.c
+++ b/drivers/net/fec_mpc52xx_phy.c
@@ -105,8 +105,10 @@ static int mpc52xx_fec_mdio_probe(struct of_device *of,
dev_set_drvdata(dev, bus);
/* set MII speed */
- out_be32(&priv->regs->mii_speed,
- ((mpc5xxx_get_bus_frequency(of->node) >> 20) / 5) << 1);
+ i = mpc5xxx_get_mii_speed(of);
+ if (i<0)
+ goto out_unmap;
+ clrsetbits_be32(&priv->regs->mii_speed, 0x7E, i);
err = of_mdiobus_register(bus, np);
if (err)
--
1.6.0.6
^ permalink raw reply related
* Re: [PATCH 1/2 v3] fs_enet/mii-fec.c: fix MII speed calculation
From: Grant Likely @ 2009-07-15 17:17 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-dev, netdev
In-Reply-To: <1247671133-12148-1-git-send-email-wd@denx.de>
On Wed, Jul 15, 2009 at 9:18 AM, Wolfgang Denk<wd@denx.de> wrote:
> The MII speed calculation was based on the CPU clock (ppc_proc_freq),
> but for MPC512x we must use the bus clock instead.
>
> This patch makes it use the correct clock and makes sure we don't
> clobber reserved bits in the MII_SPEED register.
>
> Signed-off-by: Wolfgang Denk <wd@denx.de>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Kumar Gala <galak@kernel.crashing.org>
> Cc: <netdev@vger.kernel.org>
> ---
> Please ignore patch v2, it's crap.
> Hope this is a bit better.
>
> =A0arch/powerpc/include/asm/mpc5xxx.h =A0 | =A0 10 +++++++++
> =A0arch/powerpc/sysdev/mpc5xxx_clocks.c | =A0 37 ++++++++++++++++++++++++=
++++++++++
Drop the common code bit. The 5200 and 5121 are different devices and
it is a tiny bit of code. I don't think there is any benefit to
having it as a common function. Just roll the get_mii_speed function
in the mii-fec driver itself.
Also, this patch can be quite a bit simpler if you use the .data
pointer in the drivers match table to specify the function used to
return the bus clock speed. Something like this:
static struct of_device_id fs_enet_mdio_fec_match[] =3D {
{
.compatible =3D "fsl,pq1-fec-mdio",
},
#if defined(CONFIG_PPC_MPC512x)
{
.compatible =3D "fsl,mpc5121-fec-mdio",
.data =3D mpc5xxx_get_bus_frequency,
},
#endif
{},
};
and
int *get_bus_freq(of_node *) =3D data;
if (get_bus_freq)
bus_freq =3D get_bus_freq(np);
else
bus_freq =3D ppc_proc_freq / 2;
... then do the regular calculation here and add in the additional
robustification you did in this patch.
Heck, you could even eliminate the if/else above if the normal case
you have a get_bus_speed function for the original ppc_proc_freq case,
but I'm not sure if it is worth it.
> =A0drivers/net/fs_enet/mii-fec.c =A0 =A0 =A0 =A0| =A0 13 +++++++++--
> =A03 files changed, 57 insertions(+), 3 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/mpc5xxx.h b/arch/powerpc/include/as=
m/mpc5xxx.h
> index 5ce9c5f..86ab29f 100644
> --- a/arch/powerpc/include/asm/mpc5xxx.h
> +++ b/arch/powerpc/include/asm/mpc5xxx.h
> @@ -15,8 +15,18 @@
>
> =A0#ifndef __ASM_POWERPC_MPC5xxx_H__
> =A0#define __ASM_POWERPC_MPC5xxx_H__
> +#include <linux/of_platform.h>
>
> =A0extern unsigned long mpc5xxx_get_bus_frequency(struct device_node *nod=
e);
>
> +#if defined(CONFIG_PPC_MPC512x) || defined(CONFIG_PPC_MPC52xx)
> +extern int mpc5xxx_get_mii_speed(struct of_device *ofdev);
> +#else
> +static inline int mpc5xxx_get_mii_speed(struct of_device *ofdev)
> +{
> + =A0 =A0 =A0 return -1;
> +}
> +#endif
> +
> =A0#endif /* __ASM_POWERPC_MPC5xxx_H__ */
>
> diff --git a/arch/powerpc/sysdev/mpc5xxx_clocks.c b/arch/powerpc/sysdev/m=
pc5xxx_clocks.c
> index 34e12f9..e26d12b 100644
> --- a/arch/powerpc/sysdev/mpc5xxx_clocks.c
> +++ b/arch/powerpc/sysdev/mpc5xxx_clocks.c
> @@ -31,3 +31,40 @@ mpc5xxx_get_bus_frequency(struct device_node *node)
> =A0 =A0 =A0 =A0return p_bus_freq ? *p_bus_freq : 0;
> =A0}
> =A0EXPORT_SYMBOL(mpc5xxx_get_bus_frequency);
> +
> +/**
> + * =A0 =A0 mpc5xxx_get_mii_speed - Get the MII_SPEED value
> + * =A0 =A0 @node: =A0device node
> + *
> + * =A0 =A0 Returns the MII_SPEED value for MPC512x and MPC52xx systems.
> + * =A0 =A0 The value gets computed such that the resulting MDC frequency
> + * =A0 =A0 is 2.5 MHz or lower.
> + */
> +
> +int
> +mpc5xxx_get_mii_speed(struct of_device *ofdev)
> +{
> + =A0 =A0 =A0 unsigned int clock, speed;
> +
> + =A0 =A0 =A0 clock =3D mpc5xxx_get_bus_frequency(ofdev->node);
> +
> + =A0 =A0 =A0 if (!clock) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&ofdev->dev, "could not determine I=
PS/IPB clock\n");
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 return -ENODEV;
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 /* scale for a MII clock <=3D 2.5 MHz */
> + =A0 =A0 =A0 speed =3D (clock + 2499999) / 2500000;
> +
> + =A0 =A0 =A0 /* only 6 bits available for MII speed */
> + =A0 =A0 =A0 if (speed > 0x3F) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 speed =3D 0x3F;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 dev_err(&ofdev->dev,
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 "MII clock (%d MHz) exceeds=
max (2.5 MHz)\n",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 clock / speed);
> + =A0 =A0 =A0 }
> +
> + =A0 =A0 =A0 /* Field is in bits 25:30 of MII_SPEED register */
> + =A0 =A0 =A0 return speed << 1;
> +}
> +EXPORT_SYMBOL(mpc5xxx_get_mii_speed);
> diff --git a/drivers/net/fs_enet/mii-fec.c b/drivers/net/fs_enet/mii-fec.=
c
> index 75a0999..a28d39f 100644
> --- a/drivers/net/fs_enet/mii-fec.c
> +++ b/drivers/net/fs_enet/mii-fec.c
> @@ -36,6 +36,7 @@
> =A0#include <asm/pgtable.h>
> =A0#include <asm/irq.h>
> =A0#include <asm/uaccess.h>
> +#include <asm/mpc5xxx.h>
>
> =A0#include "fs_enet.h"
> =A0#include "fec.h"
> @@ -103,7 +104,6 @@ static int fs_enet_fec_mii_reset(struct mii_bus *bus)
> =A0static int __devinit fs_enet_mdio_probe(struct of_device *ofdev,
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 const struct of_device_id *match)
> =A0{
> - =A0 =A0 =A0 struct device_node *np =3D NULL;
> =A0 =A0 =A0 =A0struct resource res;
> =A0 =A0 =A0 =A0struct mii_bus *new_bus;
> =A0 =A0 =A0 =A0struct fec_info *fec;
> @@ -133,13 +133,20 @@ static int __devinit fs_enet_mdio_probe(struct of_d=
evice *ofdev,
> =A0 =A0 =A0 =A0if (!fec->fecp)
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0goto out_fec;
>
> - =A0 =A0 =A0 fec->mii_speed =3D ((ppc_proc_freq + 4999999) / 5000000) <<=
1;
> + =A0 =A0 =A0 if (of_device_is_compatible(ofdev->node, "fsl,mpc5121-fec-m=
dio")) {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 i =3D mpc5xxx_get_mii_speed(ofdev);
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 if (i < 0)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out_unmap_regs;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 fec->mii_speed =3D i;
> + =A0 =A0 =A0 } else {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 fec->mii_speed =3D ((ppc_proc_freq + 499999=
9) / 5000000) << 1;
> + =A0 =A0 =A0 }
>
> =A0 =A0 =A0 =A0setbits32(&fec->fecp->fec_r_cntrl, FEC_RCNTRL_MII_MODE);
> =A0 =A0 =A0 =A0setbits32(&fec->fecp->fec_ecntrl, FEC_ECNTRL_PINMUX |
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0 =A0 =A0FEC_ECNTRL_ETHER_EN);
> =A0 =A0 =A0 =A0out_be32(&fec->fecp->fec_ievent, FEC_ENET_MII);
> - =A0 =A0 =A0 out_be32(&fec->fecp->fec_mii_speed, fec->mii_speed);
> + =A0 =A0 =A0 clrsetbits_be32(&fec->fecp->fec_mii_speed, 0x7E, fec->mii_s=
peed);
>
> =A0 =A0 =A0 =A0new_bus->phy_mask =3D ~0;
> =A0 =A0 =A0 =A0new_bus->irq =3D kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_K=
ERNEL);
> --
> 1.6.0.6
>
>
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: [PATCH 2/2] MPC52xx FEC: be more conservative when setting MII_SPEED register
From: Grant Likely @ 2009-07-15 17:18 UTC (permalink / raw)
To: Wolfgang Denk; +Cc: linuxppc-dev, netdev
In-Reply-To: <1247671133-12148-2-git-send-email-wd@denx.de>
On Wed, Jul 15, 2009 at 9:18 AM, Wolfgang Denk<wd@denx.de> wrote:
> This patch adds error checking and prevents clobbering unrelated bits
> (reserved bits or the DIS_PREAMBLE bit) when writing the MII_SPEED
> register on MPC52xx systems.
>
> Signed-off-by: Wolfgang Denk <wd@denx.de>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Kumar Gala <galak@kernel.crashing.org>
> Cc: <netdev@vger.kernel.org>
As I mentioned in the other patch, I don't want the 5121 and 5200 FEC
devices using common code for this. It is a tiny block of code and
they are different devices. Just open code the needed calculation
into this driver.
g.
> ---
> =A0drivers/net/fec_mpc52xx.c =A0 =A0 | =A0 =A02 +-
> =A0drivers/net/fec_mpc52xx_phy.c | =A0 =A06 ++++--
> =A02 files changed, 5 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/fec_mpc52xx.c b/drivers/net/fec_mpc52xx.c
> index cc78633..b69d440 100644
> --- a/drivers/net/fec_mpc52xx.c
> +++ b/drivers/net/fec_mpc52xx.c
> @@ -639,7 +639,7 @@ static void mpc52xx_fec_hw_init(struct net_device *de=
v)
> =A0 =A0 =A0 =A0/* set phy speed.
> =A0 =A0 =A0 =A0 * this can't be done in phy driver, since it needs to be =
called
> =A0 =A0 =A0 =A0 * before fec stuff (even on resume) */
> - =A0 =A0 =A0 out_be32(&fec->mii_speed, priv->mdio_speed);
> + =A0 =A0 =A0 clrsetbits_be32(&fec->mii_speed, 0x7E, priv->mdio_speed);
> =A0}
>
> =A0/**
> diff --git a/drivers/net/fec_mpc52xx_phy.c b/drivers/net/fec_mpc52xx_phy.=
c
> index 31e6d62..f733d43 100644
> --- a/drivers/net/fec_mpc52xx_phy.c
> +++ b/drivers/net/fec_mpc52xx_phy.c
> @@ -105,8 +105,10 @@ static int mpc52xx_fec_mdio_probe(struct of_device *=
of,
> =A0 =A0 =A0 =A0dev_set_drvdata(dev, bus);
>
> =A0 =A0 =A0 =A0/* set MII speed */
> - =A0 =A0 =A0 out_be32(&priv->regs->mii_speed,
> - =A0 =A0 =A0 =A0 =A0 =A0 =A0 ((mpc5xxx_get_bus_frequency(of->node) >> 20=
) / 5) << 1);
> + =A0 =A0 =A0 i =3D mpc5xxx_get_mii_speed(of);
> + =A0 =A0 =A0 if (i<0)
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 goto out_unmap;
> + =A0 =A0 =A0 clrsetbits_be32(&priv->regs->mii_speed, 0x7E, i);
>
> =A0 =A0 =A0 =A0err =3D of_mdiobus_register(bus, np);
> =A0 =A0 =A0 =A0if (err)
> --
> 1.6.0.6
>
>
--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply
* Re: Support for PCI Express reset type in EEH
From: Mike Mason @ 2009-07-15 18:32 UTC (permalink / raw)
To: linuxppc-dev, linux-pci, Paul Mackerras, benh, linasvepstas; +Cc: Richard Lary
In-Reply-To: <4A5CCFDF.7000901@us.ibm.com>
This patch was simultaneously submitted to Red Hat for review. As a result of that review, I'm withdrawing this patch and will submit a new version shortly.
Mike
Mike Mason wrote:
> By default, EEH does what's known as a "hot reset" during error recovery
> of a PCI Express device. We've found a case where the device needs a
> "fundamental reset" to recover properly. The current PCI error recovery
> and EEH frameworks do not support this distinction.
>
> The attached patch (courtesy of Richard Lary) implements a reset type
> callback that can be used to determine what type of reset a device
> requires. It is backwards compatible with all other drivers that
> implement PCI error recovery callbacks. Only drivers that require a
> fundamental reset need to be changed. So far we're only aware of one
> driver that has the requirement (qla2xxx). The patch touches mostly EEH
> and pseries code, but does require a couple of minor additions to the
> overall PCI error recovery framework.
>
> Signed-off-by: Mike Mason <mmlnx@us.ibm.com>
>
> --- a/arch/powerpc/include/asm/ppc-pci.h 2009-06-09
> 20:05:27.000000000 -0700
> +++ b/arch/powerpc/include/asm/ppc-pci.h 2009-07-13
> 16:12:31.000000000 -0700
> @@ -90,7 +90,9 @@ int rtas_pci_enable(struct pci_dn *pdn,
> *
> * Returns a non-zero value if the reset failed.
> */
> -int rtas_set_slot_reset (struct pci_dn *);
> +#define HOT_RESET 1
> +#define FUNDAMENTAL_RESET 3
> +int rtas_set_slot_reset (struct pci_dn *, int reset_type);
> int eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs);
>
> /** --- a/arch/powerpc/platforms/pseries/eeh.c 2009-06-09
> 20:05:27.000000000 -0700
> +++ b/arch/powerpc/platforms/pseries/eeh.c 2009-07-13
> 16:27:27.000000000 -0700
> @@ -666,7 +666,7 @@ rtas_pci_enable(struct pci_dn *pdn, int
> /**
> * rtas_pci_slot_reset - raises/lowers the pci #RST line
> * @pdn pci device node
> - * @state: 1/0 to raise/lower the #RST
> + * @state: 1/3/0 to raise hot-reset/fundamental-reset/lower the #RST
> *
> * Clear the EEH-frozen condition on a slot. This routine
> * asserts the PCI #RST line if the 'state' argument is '1',
> @@ -742,9 +742,9 @@ int pcibios_set_pcie_reset_state(struct
> * Return 0 if success, else a non-zero value.
> */
>
> -static void __rtas_set_slot_reset(struct pci_dn *pdn)
> +static void __rtas_set_slot_reset(struct pci_dn *pdn, int reset_type)
> {
> - rtas_pci_slot_reset (pdn, 1);
> + rtas_pci_slot_reset (pdn, reset_type);
>
> /* The PCI bus requires that the reset be held high for at least
> * a 100 milliseconds. We wait a bit longer 'just in case'. */
> @@ -766,13 +766,13 @@ static void __rtas_set_slot_reset(struct
> msleep (PCI_BUS_SETTLE_TIME_MSEC);
> }
>
> -int rtas_set_slot_reset(struct pci_dn *pdn)
> +int rtas_set_slot_reset(struct pci_dn *pdn, int reset_type)
> {
> int i, rc;
>
> /* Take three shots at resetting the bus */
> for (i=0; i<3; i++) {
> - __rtas_set_slot_reset(pdn);
> + __rtas_set_slot_reset(pdn, reset_type);
>
> rc = eeh_wait_for_slot_status(pdn, PCI_BUS_RESET_WAIT_MSEC);
> if (rc == 0)
> --- a/arch/powerpc/platforms/pseries/eeh_driver.c 2009-07-13
> 14:25:24.000000000 -0700
> +++ b/arch/powerpc/platforms/pseries/eeh_driver.c 2009-07-13
> 16:39:16.000000000 -0700
> @@ -115,6 +115,34 @@ static void eeh_enable_irq(struct pci_de
>
> /* ------------------------------------------------------- */
> /**
> + * eeh_query_reset_type - query each device driver for reset type
> + *
> + * Query each device driver for special reset type if required
> + * merge the device driver responses. Cumulative response
> + * passed back in "userdata".
> + */
> +
> +static int eeh_query_reset_type(struct pci_dev *dev, void *userdata)
> +{
> + enum pci_ers_result rc, *res = userdata;
> + struct pci_driver *driver = dev->driver;
> +
> + if (!driver)
> + return 0;
> +
> + if (!driver->err_handler ||
> + !driver->err_handler->reset_type)
> + return 0;
> +
> + rc = driver->err_handler->reset_type (dev);
> +
> + /* A driver that needs a special reset trumps all others */
> + if (rc == PCI_ERS_RESULT_FUNDAMENTAL_RESET ) *res = rc;
> +
> + return 0;
> +}
> +
> +/**
> * eeh_report_error - report pci error to each device driver
> * * Report an EEH error to each device driver, collect up and @@ -282,9
> +310,12 @@ static int eeh_report_failure(struct pci
> * @pe_dn: pointer to a "Partionable Endpoint" device node.
> * This is the top-level structure on which pci
> * bus resets can be performed.
> + *
> + * reset_type: some devices may require type other than default hot reset.
> */
>
> -static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
> +static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus,
> + int reset_type)
> {
> struct device_node *dn;
> int cnt, rc;
> @@ -298,7 +329,7 @@ static int eeh_reset_device (struct pci_
> /* Reset the pci controller. (Asserts RST#; resets config space).
> * Reconfigure bridges and devices. Don't try to bring the system
> * up if the reset failed for some reason. */
> - rc = rtas_set_slot_reset(pe_dn);
> + rc = rtas_set_slot_reset(pe_dn, reset_type);
> if (rc)
> return rc;
>
> @@ -343,6 +374,7 @@ struct pci_dn * handle_eeh_events (struc
> struct pci_dn *frozen_pdn;
> struct pci_bus *frozen_bus;
> int rc = 0;
> + int reset_type = HOT_RESET;
> enum pci_ers_result result = PCI_ERS_RESULT_NONE;
> const char *location, *pci_str, *drv_str;
>
> @@ -400,10 +432,16 @@ struct pci_dn * handle_eeh_events (struc
>
> /* Walk the various device drivers attached to this slot through
> * a reset sequence, giving each an opportunity to do what it needs
> - * to accomplish the reset. Each child gets a report of the
> - * status ... if any child can't handle the reset, then the entire
> - * slot is dlpar removed and added.
> + * to accomplish the reset. Query device driver for special reset
> + * requiements. Report eeh error to each child with cumulative
> + * result status... if any child can't handle the reset,
> + * then the entire slot is dlpar removed and added.
> */
> + pci_walk_bus(frozen_bus, eeh_query_reset_type, &result);
> + if ( result == PCI_ERS_RESULT_FUNDAMENTAL_RESET )
> + reset_type = FUNDAMENTAL_RESET;
> +
> + result = PCI_ERS_RESULT_NONE;
> pci_walk_bus(frozen_bus, eeh_report_error, &result);
>
> /* Get the current PCI slot state. This can take a long time,
> @@ -425,7 +463,8 @@ struct pci_dn * handle_eeh_events (struc
> * go down willingly, without panicing the system.
> */
> if (result == PCI_ERS_RESULT_NONE) {
> - rc = eeh_reset_device(frozen_pdn, frozen_bus);
> + rc = eeh_reset_device(frozen_pdn, frozen_bus, reset_type);
> +
> if (rc) {
> printk(KERN_WARNING "EEH: Unable to reset, rc=%d\n", rc);
> goto hard_fail;
> @@ -466,7 +505,7 @@ struct pci_dn * handle_eeh_events (struc
>
> /* If any device called out for a reset, then reset the slot */
> if (result == PCI_ERS_RESULT_NEED_RESET) {
> - rc = eeh_reset_device(frozen_pdn, NULL);
> + rc = eeh_reset_device(frozen_pdn, NULL, reset_type);
> if (rc) {
> printk(KERN_WARNING "EEH: Cannot reset, rc=%d\n", rc);
> goto hard_fail;
> --- a/include/linux/pci.h 2009-07-13 14:25:37.000000000 -0700
> +++ b/include/linux/pci.h 2009-07-13 16:12:31.000000000 -0700
> @@ -446,6 +446,9 @@ enum pci_ers_result {
>
> /* Device driver is fully recovered and operational */
> PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5,
> +
> + /* Device driver requires fundamental reset to recover */
> + PCI_ERS_RESULT_FUNDAMENTAL_RESET = (__force pci_ers_result_t) 6,
> };
>
> /* PCI bus error event callbacks */
> @@ -465,6 +468,9 @@ struct pci_error_handlers {
>
> /* Device driver may resume normal operations */
> void (*resume)(struct pci_dev *dev);
> +
> + /* PCI slot requires special reset type for recovery */
> + pci_ers_result_t (*reset_type)(struct pci_dev *dev);
> };
>
> /* ---------------------------------------------------------------- */
> --- a/arch/powerpc/include/asm/ppc-pci.h 2009-06-09
> 20:05:27.000000000 -0700
> +++ b/arch/powerpc/include/asm/ppc-pci.h 2009-07-13
> 16:12:31.000000000 -0700
> @@ -90,7 +90,9 @@ int rtas_pci_enable(struct pci_dn *pdn,
> *
> * Returns a non-zero value if the reset failed.
> */
> -int rtas_set_slot_reset (struct pci_dn *);
> +#define HOT_RESET 1
> +#define FUNDAMENTAL_RESET 3
> +int rtas_set_slot_reset (struct pci_dn *, int reset_type);
> int eeh_wait_for_slot_status(struct pci_dn *pdn, int max_wait_msecs);
>
> /** --- a/arch/powerpc/platforms/pseries/eeh.c 2009-06-09
> 20:05:27.000000000 -0700
> +++ b/arch/powerpc/platforms/pseries/eeh.c 2009-07-13
> 16:27:27.000000000 -0700
> @@ -666,7 +666,7 @@ rtas_pci_enable(struct pci_dn *pdn, int
> /**
> * rtas_pci_slot_reset - raises/lowers the pci #RST line
> * @pdn pci device node
> - * @state: 1/0 to raise/lower the #RST
> + * @state: 1/3/0 to raise hot-reset/fundamental-reset/lower the #RST
> *
> * Clear the EEH-frozen condition on a slot. This routine
> * asserts the PCI #RST line if the 'state' argument is '1',
> @@ -742,9 +742,9 @@ int pcibios_set_pcie_reset_state(struct
> * Return 0 if success, else a non-zero value.
> */
>
> -static void __rtas_set_slot_reset(struct pci_dn *pdn)
> +static void __rtas_set_slot_reset(struct pci_dn *pdn, int reset_type)
> {
> - rtas_pci_slot_reset (pdn, 1);
> + rtas_pci_slot_reset (pdn, reset_type);
>
> /* The PCI bus requires that the reset be held high for at least
> * a 100 milliseconds. We wait a bit longer 'just in case'. */
> @@ -766,13 +766,13 @@ static void __rtas_set_slot_reset(struct
> msleep (PCI_BUS_SETTLE_TIME_MSEC);
> }
>
> -int rtas_set_slot_reset(struct pci_dn *pdn)
> +int rtas_set_slot_reset(struct pci_dn *pdn, int reset_type)
> {
> int i, rc;
>
> /* Take three shots at resetting the bus */
> for (i=0; i<3; i++) {
> - __rtas_set_slot_reset(pdn);
> + __rtas_set_slot_reset(pdn, reset_type);
>
> rc = eeh_wait_for_slot_status(pdn, PCI_BUS_RESET_WAIT_MSEC);
> if (rc == 0)
> --- a/arch/powerpc/platforms/pseries/eeh_driver.c 2009-07-13
> 14:25:24.000000000 -0700
> +++ b/arch/powerpc/platforms/pseries/eeh_driver.c 2009-07-13
> 16:39:16.000000000 -0700
> @@ -115,6 +115,34 @@ static void eeh_enable_irq(struct pci_de
>
> /* ------------------------------------------------------- */
> /**
> + * eeh_query_reset_type - query each device driver for reset type
> + *
> + * Query each device driver for special reset type if required
> + * merge the device driver responses. Cumulative response
> + * passed back in "userdata".
> + */
> +
> +static int eeh_query_reset_type(struct pci_dev *dev, void *userdata)
> +{
> + enum pci_ers_result rc, *res = userdata;
> + struct pci_driver *driver = dev->driver;
> +
> + if (!driver)
> + return 0;
> +
> + if (!driver->err_handler ||
> + !driver->err_handler->reset_type)
> + return 0;
> +
> + rc = driver->err_handler->reset_type (dev);
> +
> + /* A driver that needs a special reset trumps all others */
> + if (rc == PCI_ERS_RESULT_FUNDAMENTAL_RESET ) *res = rc;
> +
> + return 0;
> +}
> +
> +/**
> * eeh_report_error - report pci error to each device driver
> * * Report an EEH error to each device driver, collect up and @@ -282,9
> +310,12 @@ static int eeh_report_failure(struct pci
> * @pe_dn: pointer to a "Partionable Endpoint" device node.
> * This is the top-level structure on which pci
> * bus resets can be performed.
> + *
> + * reset_type: some devices may require type other than default hot reset.
> */
>
> -static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus)
> +static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus,
> + int reset_type)
> {
> struct device_node *dn;
> int cnt, rc;
> @@ -298,7 +329,7 @@ static int eeh_reset_device (struct pci_
> /* Reset the pci controller. (Asserts RST#; resets config space).
> * Reconfigure bridges and devices. Don't try to bring the system
> * up if the reset failed for some reason. */
> - rc = rtas_set_slot_reset(pe_dn);
> + rc = rtas_set_slot_reset(pe_dn, reset_type);
> if (rc)
> return rc;
>
> @@ -343,6 +374,7 @@ struct pci_dn * handle_eeh_events (struc
> struct pci_dn *frozen_pdn;
> struct pci_bus *frozen_bus;
> int rc = 0;
> + int reset_type = HOT_RESET;
> enum pci_ers_result result = PCI_ERS_RESULT_NONE;
> const char *location, *pci_str, *drv_str;
>
> @@ -400,10 +432,16 @@ struct pci_dn * handle_eeh_events (struc
>
> /* Walk the various device drivers attached to this slot through
> * a reset sequence, giving each an opportunity to do what it needs
> - * to accomplish the reset. Each child gets a report of the
> - * status ... if any child can't handle the reset, then the entire
> - * slot is dlpar removed and added.
> + * to accomplish the reset. Query device driver for special reset
> + * requiements. Report eeh error to each child with cumulative
> + * result status... if any child can't handle the reset,
> + * then the entire slot is dlpar removed and added.
> */
> + pci_walk_bus(frozen_bus, eeh_query_reset_type, &result);
> + if ( result == PCI_ERS_RESULT_FUNDAMENTAL_RESET )
> + reset_type = FUNDAMENTAL_RESET;
> +
> + result = PCI_ERS_RESULT_NONE;
> pci_walk_bus(frozen_bus, eeh_report_error, &result);
>
> /* Get the current PCI slot state. This can take a long time,
> @@ -425,7 +463,8 @@ struct pci_dn * handle_eeh_events (struc
> * go down willingly, without panicing the system.
> */
> if (result == PCI_ERS_RESULT_NONE) {
> - rc = eeh_reset_device(frozen_pdn, frozen_bus);
> + rc = eeh_reset_device(frozen_pdn, frozen_bus, reset_type);
> +
> if (rc) {
> printk(KERN_WARNING "EEH: Unable to reset, rc=%d\n", rc);
> goto hard_fail;
> @@ -466,7 +505,7 @@ struct pci_dn * handle_eeh_events (struc
>
> /* If any device called out for a reset, then reset the slot */
> if (result == PCI_ERS_RESULT_NEED_RESET) {
> - rc = eeh_reset_device(frozen_pdn, NULL);
> + rc = eeh_reset_device(frozen_pdn, NULL, reset_type);
> if (rc) {
> printk(KERN_WARNING "EEH: Cannot reset, rc=%d\n", rc);
> goto hard_fail;
> --- a/include/linux/pci.h 2009-07-13 14:25:37.000000000 -0700
> +++ b/include/linux/pci.h 2009-07-13 16:12:31.000000000 -0700
> @@ -446,6 +446,9 @@ enum pci_ers_result {
>
> /* Device driver is fully recovered and operational */
> PCI_ERS_RESULT_RECOVERED = (__force pci_ers_result_t) 5,
> +
> + /* Device driver requires fundamental reset to recover */
> + PCI_ERS_RESULT_FUNDAMENTAL_RESET = (__force pci_ers_result_t) 6,
> };
>
> /* PCI bus error event callbacks */
> @@ -465,6 +468,9 @@ struct pci_error_handlers {
>
> /* Device driver may resume normal operations */
> void (*resume)(struct pci_dev *dev);
> +
> + /* PCI slot requires special reset type for recovery */
> + pci_ers_result_t (*reset_type)(struct pci_dev *dev);
> };
>
> /* ---------------------------------------------------------------- */
>
>
^ permalink raw reply
* [PATCH] Support for PCI Express reset type in EEH
From: Mike Mason @ 2009-07-15 18:45 UTC (permalink / raw)
To: linuxppc-dev, linux-pci, Paul Mackerras, benh, linasvepstas; +Cc: Richard Lary
In-Reply-To: <4A5CCFDF.7000901@us.ibm.com>
By default, EEH does what's known as a "hot reset" during error recovery of a PCI Express device. We've found a case where the device needs a "fundamental reset" to recover properly. The current PCI error recovery and EEH frameworks do not support this distinction.
The attached patch (courtesy of Richard Lary) adds a bit field to pci_dev that indicates whether the device requires a fundamental reset during error recovery. This bit can be checked by EEH to determine which reset type is required.
This patch supersedes the previously submitted patch that implemented a reset type callback.
Please review and let me know of any concerns.
Signed-off-by: Mike Mason <mmlnx@us.ibm.com>
diff -uNrp a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
--- a/arch/powerpc/kernel/pci_64.c 2009-07-13 14:25:24.000000000 -0700
+++ b/arch/powerpc/kernel/pci_64.c 2009-07-15 10:26:26.000000000 -0700
@@ -143,6 +143,7 @@ struct pci_dev *of_create_pci_dev(struct
dev->dev.bus = &pci_bus_type;
dev->devfn = devfn;
dev->multifunction = 0; /* maybe a lie? */
+ dev->fndmntl_rst_rqd = 0; /* pcie fundamental reset required */
dev->vendor = get_int_prop(node, "vendor-id", 0xffff);
dev->device = get_int_prop(node, "device-id", 0xffff);
diff -uNrp a/arch/powerpc/platforms/pseries/eeh.c b/arch/powerpc/platforms/pseries/eeh.c
--- a/arch/powerpc/platforms/pseries/eeh.c 2009-06-09 20:05:27.000000000 -0700
+++ b/arch/powerpc/platforms/pseries/eeh.c 2009-07-15 10:29:04.000000000 -0700
@@ -744,7 +744,15 @@ int pcibios_set_pcie_reset_state(struct
static void __rtas_set_slot_reset(struct pci_dn *pdn)
{
- rtas_pci_slot_reset (pdn, 1);
+ struct pci_dev *dev = pdn->pcidev;
+
+ /* Determine type of EEH reset required by device,
+ * default hot reset or fundamental reset
+ */
+ if (dev->fndmntl_rst_rqd)
+ rtas_pci_slot_reset(pdn, 3);
+ else
+ rtas_pci_slot_reset(pdn, 1);
/* The PCI bus requires that the reset be held high for at least
* a 100 milliseconds. We wait a bit longer 'just in case'. */
diff -uNrp a/include/linux/pci.h b/include/linux/pci.h
--- a/include/linux/pci.h 2009-07-13 14:25:37.000000000 -0700
+++ b/include/linux/pci.h 2009-07-15 10:25:37.000000000 -0700
@@ -273,6 +273,7 @@ struct pci_dev {
unsigned int ari_enabled:1; /* ARI forwarding */
unsigned int is_managed:1;
unsigned int is_pcie:1;
+ unsigned int fndmntl_rst_rqd:1; /* Dev requires fundamental reset */
unsigned int state_saved:1;
unsigned int is_physfn:1;
unsigned int is_virtfn:1;
^ permalink raw reply
* Re: [00/15] swiotlb cleanup
From: Becky Bruce @ 2009-07-15 20:24 UTC (permalink / raw)
To: Ingo Molnar
Cc: Jeremy Fitzhardinge, tony.luck, linux-ia64, Ian Campbell,
Joerg Roedel, x86, linux-kernel@vger.kernel.org Mailing List,
FUJITA Tomonori, linuxppc-dev@ozlabs.org list
In-Reply-To: <68EFFAF6-EF5B-4148-BC54-70BF2AF2456E@kernel.crashing.org>
On Jul 13, 2009, at 10:13 PM, Becky Bruce wrote:
>
> On Jul 10, 2009, at 12:12 AM, Ingo Molnar wrote:
>
>>
>> * FUJITA Tomonori <fujita.tomonori@lab.ntt.co.jp> wrote:
>>
>>> - removes unused (and unnecessary) hooks in swiotlb.
>>>
>>> - adds dma_capable() and converts swiotlb to use it. It can be
>>> used to
>>> know if a memory area is dma capable or not. I added
>>> is_buffer_dma_capable() for the same purpose long ago but it turned
>>> out that the function doesn't work on POWERPC.
>>>
>>> This can be applied cleanly to linux-next, -mm, and mainline. This
>>> patchset touches multiple architectures (ia64, powerpc, x86) so I
>>> guess that -mm is appropriate for this patchset (I don't care much
>>> what tree would merge this though).
>>>
>>> This is tested on x86 but only compile tested on POWERPC and IA64.
>>>
>>> Thanks,
>>>
>>> =
>>> arch/ia64/include/asm/dma-mapping.h | 18 ++++++
>>> arch/powerpc/include/asm/dma-mapping.h | 23 +++++++
>>> arch/powerpc/kernel/dma-swiotlb.c | 48 +---------------
>>> arch/x86/include/asm/dma-mapping.h | 18 ++++++
>>> arch/x86/kernel/pci-dma.c | 2 +-
>>> arch/x86/kernel/pci-gart_64.c | 5 +-
>>> arch/x86/kernel/pci-nommu.c | 2 +-
>>> arch/x86/kernel/pci-swiotlb.c | 25 --------
>>> include/linux/dma-mapping.h | 5 --
>>> include/linux/swiotlb.h | 11 ----
>>> lib/swiotlb.c | 102 ++++++++
>>> +-----------------------
>>> 11 files changed, 92 insertions(+), 167 deletions(-)
>>
>> Hm, the functions and facilities you remove here were added as part
>> of preparatory patches for Xen guest support. You were aware of
>> them, you were involved in discussions about those aspects with Ian
>> and Jeremy but still you chose not to Cc: either of them and you
>> failed to address that aspect in the changelogs.
>>
>> I'd like the Xen code to become cleaner more than anyone else here i
>> guess, but patch submission methods like this are not really
>> helpful. A far better method is to be open about such disagreements,
>> to declare them, to Cc: everyone who disagrees, and to line out the
>> arguments in the changelogs as well - instead of just curtly
>> declaring those APIs 'unused' and failing to Cc: involved parties.
>>
>> Alas, on the technical level the cleanups themselves look mostly
>> fine to me. Ian, Jeremy, the changes will alter Xen's use of
>> swiotlb, but can the Xen side still live with these new methods - in
>> particular is dma_capable() sufficient as a mechanism and can the
>> Xen side filter out DMA allocations to make them physically
>> continuous?
>>
>> Ben, Tony, Becky, any objections wrt. the PowerPC / IA64 impact? If
>> everyone agrees i can apply them to the IOMMU tree, test it and push
>> it out to -next, etc.
>>
>
> Ingo,
>
> With the exception of the patch I commented on, I think these look
> OK from the powerpc point of view. I've successfully booted one of
> my test platforms with the entire series applied and will run some
> more extensive (i.e. not "Whee! A prompt!") tests tomorrow.
Well, I am still testing. I've observed one unexpected LTP testcase
failure with these patches applied, but so far have been unable to
reproduce it. So these patches are probably OK, but I will look into
this some more next week.
-Becky
>
>
> -Becky
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev
^ permalink raw reply
* [PATCH] Hold reference to device_node during EEH event handling
From: Mike Mason @ 2009-07-15 21:43 UTC (permalink / raw)
To: linuxppc-dev, Paul Mackerras, benh, linasvepstas
This patch increments the device_node reference counter when an EEH error occurs and decrements the counter when the event has been handled. This is to prevent the device_node from being released until eeh_event_handler() has had a chance to deal with the event. We've seen cases where the device_node is released too soon when an EEH event occurs during a dlpar remove, causing the event handler to attempt to access bad memory locations.
Please review and let me know of any concerns.
Signed-off-by: Mike Mason <mmlnx@us.ibm.com>
--- a/arch/powerpc/platforms/pseries/eeh_event.c 2008-10-09 15:13:53.000000000 -0700
+++ b/arch/powerpc/platforms/pseries/eeh_event.c 2009-07-14 14:14:00.000000000 -0700
@@ -75,6 +75,14 @@ static int eeh_event_handler(void * dumm
if (event == NULL)
return 0;
+ /* EEH holds a reference to the device_node, so if it
+ * equals 1 it's no longer valid and the event should
+ * be ignored */
+ if (atomic_read(&event->dn->kref.refcount) == 1) {
+ of_node_put(event->dn);
+ return 0;
+ }
+
/* Serialize processing of EEH events */
mutex_lock(&eeh_event_mutex);
eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
@@ -86,6 +94,7 @@ static int eeh_event_handler(void * dumm
eeh_clear_slot(event->dn, EEH_MODE_RECOVERING);
pci_dev_put(event->dev);
+ of_node_put(event->dn);
kfree(event);
mutex_unlock(&eeh_event_mutex);
@@ -140,7 +149,7 @@ int eeh_send_failure_event (struct devic
if (dev)
pci_dev_get(dev);
- event->dn = dn;
+ event->dn = of_node_get(dn);
event->dev = dev;
/* We may or may not be called in an interrupt context */
^ permalink raw reply
* Re: having access to interrupt specifier in map() function
From: Benjamin Herrenschmidt @ 2009-07-15 22:33 UTC (permalink / raw)
To: Kumar Gala; +Cc: linuxppc-dev@ozlabs.org list
In-Reply-To: <761CE7B3-A7FD-41FD-A828-B9F17F73DF32@kernel.crashing.org>
On Wed, 2009-07-15 at 09:11 -0500, Kumar Gala wrote:
> Ben,
>
> Do you have any ideas on keeping access to the interrupt specifier
> around so when we call map() we have access to it. Our HV guys are
> looking at using additional bits in the interrupt specifier to encode
> information beyond just level/sense of the IRQ and want to make
> decisions based on it during map().
>
> Maybe we can keep it around in irq_map[].
Or we could translate those additional info into flags in the IRQ desc ?
Might be possible to request some arch specific flags in there.
Cheers,
Ben.
^ permalink raw reply
* Re: removing addr_needs_map in struct dma_mapping_ops
From: Becky Bruce @ 2009-07-15 23:59 UTC (permalink / raw)
To: FUJITA Tomonori; +Cc: linuxppc-dev, linux-kernel
In-Reply-To: <20090714094919V.fujita.tomonori@lab.ntt.co.jp>
On Jul 13, 2009, at 7:49 PM, FUJITA Tomonori wrote:
> On Mon, 13 Jul 2009 16:50:43 -0500
> Becky Bruce <beckyb@kernel.crashing.org> wrote:
>
>>> talked about defining something like struct dma_data. Then we could
>>>
>>> struct dev_archdata {
>>> ...
>>>
>>> struct dma_data *ddata;
>>> };
>>>
>>> or
>>>
>>> struct dev_archdata {
>>> ...
>>>
>>> struct dma_data ddata;
>>> };
>>>
>>>
>>> struct dma_data needs dma_direct_offset, iommu_table, dma_base, and
>>> dma_window_size, anything else?
>>
>> IIRC, what we had talked about was simpler - we talked about changing
>> the current dev_archdata from this:
>>
>> struct dev_archdata {
>> struct device_node *of_node;
>> struct dma_mapping_ops *dma_ops;
>> void *dma_data;
>> };
>>
>> to this:
>>
>> struct dev_archdata {
>> struct device_node *of_node;
>> struct dma_mapping_ops *dma_ops;
>> unsigned long long dma_data;
>> #ifdef CONFIG_SWIOTLB
>> dma_addr_t max_direct_dma_addr;
>> #endif
>> };
>>
>> Where max_direct_dma_addr is the address beyond which a specific
>> device must use swiotlb, and dma_data is the offset like it is now
>> (but wider on 32-bit systems than void *). I believe Ben had
>> mentioned
>> wanting to make the max_direct_dma_addr part conditional so we don't
>> bloat archdata on platforms that don't ever bounce.
>
> Only maximum address is enough? The minimum (dma_window_base_cur in
> swiotlb_pci_addr_needs_map) is not necessary?
>
>
>> The change to the type of dma_data is actually in preparation for an
>> optimization I have planned for 64-bit PCI devices (and which
>> probably
>> requires more discussion), so that doesn't need to happen now - just
>> leave it as a void *, and I can post a followup patch.
>>
>> Let me know if I can help or do any testing - I've been meaning to
>> look into switching to dma_map_ops for a while now but it hasn't
>> managed to pop off my todo stack.
>
> Ok, how about this? I'm not familiar with POWERPC so I might
> misunderstand something.
This is close, but it misses the setup for non-pci devices. We have a
bus notifier that we use to set up archdata for those devices -
ppc_swiotlb_bus_notify() in arch/powerpc/kernel/dma-swiotlb.c. It
won't cause breakage to not have this set up, because those will fall
through to the dma_capable(), but I think we should initialize it
anyway (who knows what it will end up used for later....).
>
>
>
> diff --git a/arch/powerpc/include/asm/device.h b/arch/powerpc/
> include/asm/device.h
> index 7d2277c..0086f8d 100644
> --- a/arch/powerpc/include/asm/device.h
> +++ b/arch/powerpc/include/asm/device.h
> @@ -16,6 +16,9 @@ struct dev_archdata {
> /* DMA operations on that device */
> struct dma_mapping_ops *dma_ops;
> void *dma_data;
> +#ifdef CONFIG_SWIOTLB
> + dma_addr_t max_direct_dma_addr;
> +#endif
> };
>
> static inline void dev_archdata_set_node(struct dev_archdata *ad,
> diff --git a/arch/powerpc/include/asm/swiotlb.h b/arch/powerpc/
> include/asm/swiotlb.h
> index 30891d6..b23a4f1 100644
> --- a/arch/powerpc/include/asm/swiotlb.h
> +++ b/arch/powerpc/include/asm/swiotlb.h
> @@ -24,4 +24,6 @@ static inline void dma_mark_clean(void *addr,
> size_t size) {}
> extern unsigned int ppc_swiotlb_enable;
> int __init swiotlb_setup_bus_notifier(void);
>
> +extern void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev);
> +
> #endif /* __ASM_SWIOTLB_H */
> diff --git a/arch/powerpc/kernel/dma-swiotlb.c b/arch/powerpc/kernel/
> dma-swiotlb.c
> index 68ccf11..e21359e 100644
> --- a/arch/powerpc/kernel/dma-swiotlb.c
> +++ b/arch/powerpc/kernel/dma-swiotlb.c
> @@ -56,39 +56,16 @@ swiotlb_arch_address_needs_mapping(struct device
> *hwdev, dma_addr_t addr,
> size_t size)
> {
> struct dma_mapping_ops *dma_ops = get_dma_ops(hwdev);
> + struct dev_archdata *sd = &hwdev->archdata;
>
> BUG_ON(!dma_ops);
> - return dma_ops->addr_needs_map(hwdev, addr, size);
> -}
You can get rid of the dma_ops stuff here.... it's no longer needed.
>
>
> -/*
> - * Determine if an address is reachable by a pci device, or if we
> must bounce.
> - */
> -static int
> -swiotlb_pci_addr_needs_map(struct device *hwdev, dma_addr_t addr,
> size_t size)
> -{
> - u64 mask = dma_get_mask(hwdev);
> - dma_addr_t max;
> - struct pci_controller *hose;
> - struct pci_dev *pdev = to_pci_dev(hwdev);
> -
> - hose = pci_bus_to_host(pdev->bus);
> - max = hose->dma_window_base_cur + hose->dma_window_size;
> -
> - /* check that we're within mapped pci window space */
> - if ((addr + size > max) | (addr < hose->dma_window_base_cur))
> + if (sd->max_direct_dma_addr && addr + size > sd-
> >max_direct_dma_addr)
> return 1;
>
> - return !is_buffer_dma_capable(mask, addr, size);
> -}
> -
> -static int
> -swiotlb_addr_needs_map(struct device *hwdev, dma_addr_t addr,
> size_t size)
> -{
> return !is_buffer_dma_capable(dma_get_mask(hwdev), addr, size);
> }
>
> -
> /*
> * At the moment, all platforms that use this code only require
> * swiotlb to be used if we're operating on HIGHMEM. Since
> @@ -104,7 +81,6 @@ struct dma_mapping_ops swiotlb_dma_ops = {
> .dma_supported = swiotlb_dma_supported,
> .map_page = swiotlb_map_page,
> .unmap_page = swiotlb_unmap_page,
> - .addr_needs_map = swiotlb_addr_needs_map,
> .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
> .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
> .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
> @@ -119,13 +95,23 @@ struct dma_mapping_ops swiotlb_pci_dma_ops = {
> .dma_supported = swiotlb_dma_supported,
> .map_page = swiotlb_map_page,
> .unmap_page = swiotlb_unmap_page,
> - .addr_needs_map = swiotlb_pci_addr_needs_map,
> .sync_single_range_for_cpu = swiotlb_sync_single_range_for_cpu,
> .sync_single_range_for_device = swiotlb_sync_single_range_for_device,
> .sync_sg_for_cpu = swiotlb_sync_sg_for_cpu,
> .sync_sg_for_device = swiotlb_sync_sg_for_device
> };
>
> +void pci_dma_dev_setup_swiotlb(struct pci_dev *pdev)
> +{
> + struct pci_controller *hose;
> + struct dev_archdata *sd;
> +
> + hose = pci_bus_to_host(pdev->bus);
> + sd = &pdev->dev.archdata;
> + sd->max_direct_dma_addr =
> + hose->dma_window_base_cur + hose->dma_window_size;
> +}
> +
> static int ppc_swiotlb_bus_notify(struct notifier_block *nb,
> unsigned long action, void *data)
> {
> diff --git a/arch/powerpc/platforms/85xx/mpc8536_ds.c b/arch/powerpc/
> platforms/85xx/mpc8536_ds.c
> index 055ff41..401751b 100644
> --- a/arch/powerpc/platforms/85xx/mpc8536_ds.c
> +++ b/arch/powerpc/platforms/85xx/mpc8536_ds.c
> @@ -136,6 +136,7 @@ define_machine(mpc8536_ds) {
> .init_IRQ = mpc8536_ds_pic_init,
> #ifdef CONFIG_PCI
> .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
> + .pci_dma_dev_setup = pci_dma_dev_setup_swiotlb,
> #endif
> .get_irq = mpic_get_irq,
> .restart = fsl_rstcr_restart,
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ds.c b/arch/powerpc/
> platforms/85xx/mpc85xx_ds.c
> index 849c0ac..1ba8e38 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_ds.c
> @@ -277,6 +277,7 @@ define_machine(mpc8544_ds) {
> .init_IRQ = mpc85xx_ds_pic_init,
> #ifdef CONFIG_PCI
> .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
> + .pci_dma_dev_setup = pci_dma_dev_setup_swiotlb,
> #endif
> .get_irq = mpic_get_irq,
> .restart = fsl_rstcr_restart,
> @@ -291,6 +292,7 @@ define_machine(mpc8572_ds) {
> .init_IRQ = mpc85xx_ds_pic_init,
> #ifdef CONFIG_PCI
> .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
> + .pci_dma_dev_setup = pci_dma_dev_setup_swiotlb,
> #endif
> .get_irq = mpic_get_irq,
> .restart = fsl_rstcr_restart,
> @@ -305,6 +307,7 @@ define_machine(p2020_ds) {
> .init_IRQ = mpc85xx_ds_pic_init,
> #ifdef CONFIG_PCI
> .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
> + .pci_dma_dev_setup = pci_dma_dev_setup_swiotlb,
> #endif
> .get_irq = mpic_get_irq,
> .restart = fsl_rstcr_restart,
> diff --git a/arch/powerpc/platforms/85xx/mpc85xx_mds.c b/arch/
> powerpc/platforms/85xx/mpc85xx_mds.c
> index 60ed9c0..165a2de 100644
> --- a/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> +++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
> @@ -356,6 +356,7 @@ define_machine(mpc8568_mds) {
> .progress = udbg_progress,
> #ifdef CONFIG_PCI
> .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
> + .pci_dma_dev_setup = pci_dma_dev_setup_swiotlb,
> #endif
> };
>
> @@ -377,5 +378,6 @@ define_machine(mpc8569_mds) {
> .progress = udbg_progress,
> #ifdef CONFIG_PCI
> .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
> + .pci_dma_dev_setup = pci_dma_dev_setup_swiotlb,
> #endif
> };
> diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/
> powerpc/platforms/86xx/mpc86xx_hpcn.c
> index 6632702..d1878f3 100644
> --- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
> +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
> @@ -187,5 +187,6 @@ define_machine(mpc86xx_hpcn) {
> .progress = udbg_progress,
> #ifdef CONFIG_PCI
> .pcibios_fixup_bus = fsl_pcibios_fixup_bus,
> + .pci_dma_dev_setup = pci_dma_dev_setup_swiotlb,
> #endif
> };
Instead of initializing this here (which has problems if !
CONFIG_SWIOTLB), place this in the xxxxx_xxxx_setup_arch function in
the same files, which already have an #ifdef CONFIG_SWIOTLB in which
this can be embedded.
I'm about to be off-list for a few days but will be happy to help when
I'm back next week.
Thanks!
Becky
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-
> kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at http://www.tux.org/lkml/
^ permalink raw reply
* Re: [PATCH 2/4] edac: mpc85xx add mpc83xx support
From: Doug Thompson @ 2009-07-16 0:14 UTC (permalink / raw)
To: Andrew Morton
Cc: Ira W. Snyder, linux-kernel, Dave Jiang, linuxppc-dev,
bluesmoke-devel
In-Reply-To: <20090715125249.e746496f.akpm@linux-foundation.org>
=0AIra or Kumar,=0A=0Acan you address Andrew's concerns below and what was =
posted in prior posts on this?=0A=0Athanks=0A=0Adoug t=0A=0A--- On Wed, 7/1=
5/09, Andrew Morton <akpm@linux-foundation.org> wrote:=0A=0A> From: Andrew =
Morton <akpm@linux-foundation.org>=0A> Subject: Re: [PATCH 2/4] edac: mpc85=
xx add mpc83xx support=0A> To: dougthompson@xmission.com=0A> Cc: bluesmoke-=
devel@lists.sourceforge.net, linux-kernel@vger.kernel.org=0A> Date: Wednesd=
ay, July 15, 2009, 1:52 PM=0A> On Wed, 15 Jul 2009 11:38:49 -0600=0A> dougt=
hompson@xmission.com=0A> wrote:=0A> =0A> > =0A> > Add support for the Frees=
cale MPC83xx memory=0A> controller to the existing=0A> > driver for the Fre=
escale MPC85xx memory controller.=0A> The only difference=0A> > between the=
two processors are in the CS_BNDS register=0A> parsing code, which=0A> > h=
as been changed so it will work on both processors.=0A> > =0A> > The L2 cac=
he controller does not exist on the MPC83xx,=0A> but the OF subsystem=0A> >=
will not use the driver if the device is not present=0A> in the OF device =
tree.=0A> > =0A> > =0A> > Kumar, I had to change the nr_pages calculation t=
o=0A> make the math work=0A> > out. I checked it on my board and did the ma=
th by hand=0A> for a 64GB 85xx=0A> > using 64K pages. In both cases, nr_pag=
es * PAGE_SIZE=0A> comes out to the=0A> > correct value. Thanks for the hel=
p.=0A> > =0A> > v1 -> v2:=0A> >=A0=A0=A0* Use PAGE_SHIFT to parse cs_bnds=
=0A> regardless of board type=0A> >=A0=A0=A0* Remove special-casing for the=
83xx=0A> processor=0A> > =0A> > ...=0A> >=0A> > @@ -789,19 +791,20 @@ stat=
ic void __devinit=0A> mpc85xx_init_csrow=0A> >=A0 =A0=A0=A0 =A0=A0=A0 csrow=
=3D=0A> &mci->csrows[index];=0A> >=A0 =A0=A0=A0 =A0=A0=A0 cs_bnds =3D=0A> =
in_be32(pdata->mc_vbase + MPC85XX_MC_CS_BNDS_0 +=0A> >=A0 =A0=A0=A0 =A0=A0=
=A0=0A> =A0=A0=A0 =A0=A0=A0 =A0 (index *=0A> MPC85XX_MC_CS_BNDS_OFS));=0A> =
> -=A0=A0=A0 =A0=A0=A0 start =3D=0A> (cs_bnds & 0xfff0000) << 4;=0A> > -=A0=
=A0=A0 =A0=A0=A0 end =3D ((cs_bnds=0A> & 0xfff) << 20);=0A> > -=A0=A0=A0 =
=A0=A0=A0 if (start)=0A> > -=A0=A0=A0 =A0=A0=A0=0A> =A0=A0=A0 start |=3D 0x=
fffff;=0A> > -=A0=A0=A0 =A0=A0=A0 if (end)=0A> > -=A0=A0=A0 =A0=A0=A0=0A> =
=A0=A0=A0 end |=3D 0xfffff;=0A> > +=0A> > +=A0=A0=A0 =A0=A0=A0 start =3D=0A=
> (cs_bnds & 0xffff0000) >> 16;=0A> > +=A0=A0=A0 =A0=A0=A0=0A> end=A0=A0=A0=
=3D (cs_bnds & 0x0000ffff);=0A> >=A0 =0A> >=A0 =A0=A0=A0 =A0=A0=A0 if (star=
t=0A> =3D=3D end)=0A> >=A0 =A0=A0=A0 =A0=A0=A0=0A> =A0=A0=A0 continue;=A0=
=A0=A0 /* not=0A> populated */=0A> >=A0 =0A> > +=A0=A0=A0 =A0=A0=A0 start <=
<=3D=0A> (24 - PAGE_SHIFT);=0A> > +=A0=A0=A0 =A0=A0=A0=0A> end=A0=A0=A0<<=
=3D (24 - PAGE_SHIFT);=0A> > +=A0=A0=A0 =A0=A0=A0 end=A0=0A> =A0 |=3D (1 <<=
(24 - PAGE_SHIFT)) - 1;=0A> =0A> <stares for a while>=0A> =0A> That looks =
like the original code was really really wrong.=0A> =0A> The setting of all=
the lower bits in `end' is=0A> funny-looking.=A0 What's=0A> happening here=
?=A0 Should it be commented?=0A> =0A> =0A> >=A0 =A0=A0=A0 =A0=A0=A0=0A> csr=
ow->first_page =3D start >> PAGE_SHIFT;=0A> >=A0 =A0=A0=A0 =A0=A0=A0=0A> cs=
row->last_page =3D end >> PAGE_SHIFT;=0A> > -=A0=A0=A0 =A0=A0=A0=0A> csrow-=
>nr_pages =3D csrow->last_page + 1 -=0A> csrow->first_page;=0A> > +=A0=A0=
=A0 =A0=A0=A0=0A> csrow->nr_pages =3D end + 1 - start;=0A> >=A0 =A0=A0=A0 =
=A0=A0=A0=0A> csrow->grain =3D 8;=0A> >=A0 =A0=A0=A0 =A0=A0=A0=0A> csrow->m=
type =3D mtype;=0A> >=A0 =A0=A0=A0 =A0=A0=A0=0A> csrow->dtype =3D DEV_UNKNO=
WN;=0A> > @@ -985,6 +988,7 @@ static struct of_device_id=0A> mpc85xx_mc_er=
=0A> >=A0 =A0=A0=A0 { .compatible =3D=0A> "fsl,mpc8560-memory-controller", =
},=0A> >=A0 =A0=A0=A0 { .compatible =3D=0A> "fsl,mpc8568-memory-controller"=
, },=0A> >=A0 =A0=A0=A0 { .compatible =3D=0A> "fsl,mpc8572-memory-controlle=
r", },=0A> > +=A0=A0=A0 { .compatible =3D=0A> "fsl,mpc8349-memory-controlle=
r", },=0A> >=A0 =A0=A0=A0 { .compatible =3D=0A> "fsl,p2020-memory-controlle=
r", },=0A> >=A0 =A0=A0=A0 {},=0A> >=A0 };=0A> > @@ -1001,13 +1005,13 @@ sta=
tic struct=0A> of_platform_driver mpc85xx=0A> >=A0 =A0=A0=A0 =A0=A0=A0=0A> =
=A0=A0=A0},=0A> >=A0 };=0A> >=A0 =0A> > -=0A> > +#ifdef CONFIG_MPC85xx=0A> =
>=A0 static void __init mpc85xx_mc_clear_rfxe(void=0A> *data)=0A> >=A0 {=0A=
> >=A0 =A0=A0=A0 orig_hid1[smp_processor_id()]=0A> =3D mfspr(SPRN_HID1);=0A=
> >=A0 =A0=A0=A0 mtspr(SPRN_HID1,=0A> (orig_hid1[smp_processor_id()] & ~0x2=
0000));=0A> >=A0 }=0A> > -=0A> > +#endif=0A> >=A0 =0A> >=A0 static int __in=
it mpc85xx_mc_init(void)=0A> >=A0 {=0A> > @@ -1040,26 +1044,32 @@ static in=
t __init=0A> mpc85xx_mc_init(void)=0A> >=A0 =A0=A0=A0 =A0=A0=A0=0A> printk(=
KERN_WARNING EDAC_MOD_STR "PCI fails to=0A> register\n");=0A> >=A0 #endif=
=0A> >=A0 =0A> > +#ifdef CONFIG_MPC85xx=0A> >=A0 =A0=A0=A0 /*=0A> >=A0 =A0=
=A0=A0=A0=A0* need to clear=0A> HID1[RFXE] to disable machine check int=0A>=
>=A0 =A0=A0=A0=A0=A0* so we can catch=0A> it=0A> >=A0 =A0=A0=A0=A0=A0*/=0A=
> >=A0 =A0=A0=A0 if (edac_op_state =3D=3D=0A> EDAC_OPSTATE_INT)=0A> >=A0 =
=A0=A0=A0 =A0=A0=A0=0A> on_each_cpu(mpc85xx_mc_clear_rfxe, NULL, 0);=0A> > =
+#endif=0A> >=A0 =0A> >=A0 =A0=A0=A0 return 0;=0A> >=A0 }=0A> =0A> The patc=
h adds lots of ifdefs :(=0A> =0A> >=A0 module_init(mpc85xx_mc_init);=0A> >=
=A0 =0A> > +#ifdef CONFIG_MPC85xx=0A> >=A0 static void __exit mpc85xx_mc_re=
store_hid1(void=0A> *data)=0A> >=A0 {=0A> >=A0 =A0=A0=A0 mtspr(SPRN_HID1,=
=0A> orig_hid1[smp_processor_id()]);=0A> >=A0 }=0A> > +#endif=0A> =0A> afac=
it this will run smp_processor_id() from within=0A> preemptible code,=0A> w=
hich is often buggy on preemptible kernels and will cause=0A> runtime=0A> w=
arnings on at least some architectures.=0A> =0A> >=A0 static void __exit mp=
c85xx_mc_exit(void)=0A> >=A0 {=0A> > +#ifdef CONFIG_MPC85xx=0A> >=A0 =A0=A0=
=A0=0A> on_each_cpu(mpc85xx_mc_restore_hid1, NULL, 0);=0A> > +#endif=0A> >=
=A0 #ifdef CONFIG_PCI=0A> >=A0 =A0=A0=A0=0A> of_unregister_platform_driver(=
&mpc85xx_pci_err_driver);=0A> >=A0 #endif=0A>
^ permalink raw reply
* [PATCH] kmemleak: Allow kmemleak to be built on powerpc
From: Michael Ellerman @ 2009-07-16 1:25 UTC (permalink / raw)
To: catalin.marinas; +Cc: linuxppc-dev
Very lightly tested, doesn't crash the kernel.
Signed-off-by: Michael Ellerman <michael@ellerman.id.au>
---
It doesn't look like we actually need to add any support in the
arch code - or is there something I'm missing?
lib/Kconfig.debug | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 12327b2..d5ca9a5 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -338,7 +338,7 @@ config SLUB_STATS
config DEBUG_KMEMLEAK
bool "Kernel memory leak detector"
- depends on DEBUG_KERNEL && EXPERIMENTAL && (X86 || ARM) && \
+ depends on DEBUG_KERNEL && EXPERIMENTAL && (X86 || ARM || PPC) && \
!MEMORY_HOTPLUG
select DEBUG_FS if SYSFS
select STACKTRACE if STACKTRACE_SUPPORT
--
1.6.2.1
^ permalink raw reply related
* Re: [RFC/PATCH] mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
From: Michael Ellerman @ 2009-07-16 1:36 UTC (permalink / raw)
To: Benjamin Herrenschmidt
Cc: Linux-Arch, Nick Piggin, linuxppc-dev, Hugh Dickins, linux-kernel,
Linux Memory Management
In-Reply-To: <20090715074952.A36C7DDDB2@ozlabs.org>
[-- Attachment #1: Type: text/plain, Size: 670 bytes --]
On Wed, 2009-07-15 at 17:49 +1000, Benjamin Herrenschmidt wrote:
> Upcoming paches to support the new 64-bit "BookE" powerpc architecture
> will need to have the virtual address corresponding to PTE page when
> freeing it, due to the way the HW table walker works.
> I haven't had a chance to test or even build on most architectures, the
> patch is reasonably trivial but I may have screwed up regardless, I
> appologize in advance, let me know if something is wrong.
Builds for the important architectures, powerpc, ia64, arm, sparc,
sparc64, oh and x86:
http://kisskb.ellerman.id.au/kisskb/head/1976/
(based on your test branch 34f25476)
cheers
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [PATCH] Hold reference to device_node during EEH event handling
From: Michael Ellerman @ 2009-07-16 1:41 UTC (permalink / raw)
To: Mike Mason; +Cc: linuxppc-dev, linasvepstas, Paul Mackerras
In-Reply-To: <4A5E4D68.6070909@us.ibm.com>
[-- Attachment #1: Type: text/plain, Size: 1456 bytes --]
On Wed, 2009-07-15 at 14:43 -0700, Mike Mason wrote:
> This patch increments the device_node reference counter when an EEH
> error occurs and decrements the counter when the event has been
> handled. This is to prevent the device_node from being released until
> eeh_event_handler() has had a chance to deal with the event. We've
> seen cases where the device_node is released too soon when an EEH
> event occurs during a dlpar remove, causing the event handler to
> attempt to access bad memory locations.
>
> Please review and let me know of any concerns.
Taking a reference sounds sane, but ...
> Signed-off-by: Mike Mason <mmlnx@us.ibm.com>
>
> --- a/arch/powerpc/platforms/pseries/eeh_event.c 2008-10-09 15:13:53.000000000 -0700
> +++ b/arch/powerpc/platforms/pseries/eeh_event.c 2009-07-14 14:14:00.000000000 -0700
> @@ -75,6 +75,14 @@ static int eeh_event_handler(void * dumm
> if (event == NULL)
> return 0;
>
> + /* EEH holds a reference to the device_node, so if it
> + * equals 1 it's no longer valid and the event should
> + * be ignored */
> + if (atomic_read(&event->dn->kref.refcount) == 1) {
> + of_node_put(event->dn);
> + return 0;
> + }
That's really gross :)
And what happens if the refcount goes to 1 just after the check? ie.
here.
> /* Serialize processing of EEH events */
> mutex_lock(&eeh_event_mutex);
> eeh_mark_slot(event->dn, EEH_MODE_RECOVERING);
cheers
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 197 bytes --]
^ permalink raw reply
* Re: [RFC/PATCH] mm: Pass virtual address to [__]p{te,ud,md}_free_tlb()
From: Benjamin Herrenschmidt @ 2009-07-16 1:54 UTC (permalink / raw)
To: Nick Piggin
Cc: Linux-Arch, Linux Memory Management, Hugh Dickins, linux-kernel,
linuxppc-dev
In-Reply-To: <20090715135620.GD7298@wotan.suse.de>
On Wed, 2009-07-15 at 15:56 +0200, Nick Piggin wrote:
> On Wed, Jul 15, 2009 at 05:49:47PM +1000, Benjamin Herrenschmidt wrote:
> > Upcoming paches to support the new 64-bit "BookE" powerpc architecture
> > will need to have the virtual address corresponding to PTE page when
> > freeing it, due to the way the HW table walker works.
> >
> > Basically, the TLB can be loaded with "large" pages that cover the whole
> > virtual space (well, sort-of, half of it actually) represented by a PTE
> > page, and which contain an "indirect" bit indicating that this TLB entry
> > RPN points to an array of PTEs from which the TLB can then create direct
> > entries.
>
> RPN is PFN in ppc speak, right?
Ah right, real page number in ppc slang :-)
> > Thus, in order to invalidate those when PTE pages are deleted,
> > we need the virtual address to pass to tlbilx or tlbivax instructions.
>
> Interesting arrangement. So are these last level ptes modifieable
> from userspace or something? If not, I wonder if you could manage
> them as another level of pointers with the existing pagetable
> functions?
I don't understand what you mean. Basically, the TLB contains PMD's.
There's nothing to change to the existing page table layout :-) But
because they appear as large page TLB entries that cover the virtual
space covered by a PMD, they need to be invalidated using virtual
addresses when PMDs are removed.
> > The old trick of sticking it somewhere in the PTE page struct page sucks
> > too much, the address is almost readily available in all call sites and
> > almost everybody implemets these as macros, so we may as well add the
> > argument everywhere. I added it to the pmd and pud variants for consistency.
> >
> > Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
> > ---
> >
> > I would like to merge the new support that depends on this in 2.6.32,
> > so unless there's major objections, I'd like this to go in early during
> > the merge window. We can sort out separately how to carry the patch
> > around in -next until then since the powerpc tree will have a dependency
> > on it.
>
> Can't see any problem with that.
Thanks, can I get an Ack then ? :-)
Cheers,
Ben.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox