aboutsummaryrefslogtreecommitdiff
path: root/arch/powerpc/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel')
-rw-r--r--arch/powerpc/kernel/asm-offsets.c2
-rw-r--r--arch/powerpc/kernel/entry_64.S3
-rw-r--r--arch/powerpc/kernel/head_64.S25
-rw-r--r--arch/powerpc/kernel/irq.c12
-rw-r--r--arch/powerpc/kernel/lparcfg.c13
-rw-r--r--arch/powerpc/kernel/paca.c36
-rw-r--r--arch/powerpc/kernel/time.c2
7 files changed, 53 insertions, 40 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 56399c5c931..840aad43a98 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -135,7 +135,7 @@ int main(void)
DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
- DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca));
+ DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 4ba81e1b6bf..54203631886 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -511,7 +511,8 @@ restore:
cmpdi 0,r5,0
beq 4f
/* Check for pending interrupts (iSeries) */
- ld r3,PACALPPACA+LPPACAANYINT(r13)
+ ld r3,PACALPPACAPTR(r13)
+ ld r3,LPPACAANYINT(r3)
cmpdi r3,0
beq+ 4f /* skip do_IRQ if no interrupts */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index b3718f3eb7b..30826846634 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -255,8 +255,9 @@ exception_marker:
#define EXCEPTION_PROLOG_ISERIES_2 \
mfmsr r10; \
- ld r11,PACALPPACA+LPPACASRR0(r13); \
- ld r12,PACALPPACA+LPPACASRR1(r13); \
+ ld r12,PACALPPACAPTR(r13); \
+ ld r11,LPPACASRR0(r12); \
+ ld r12,LPPACASRR1(r12); \
ori r10,r10,MSR_RI; \
mtmsrd r10,1
@@ -635,7 +636,8 @@ data_access_slb_iSeries:
std r12,PACA_EXSLB+EX_R12(r13)
mfspr r10,SPRN_SPRG1
std r10,PACA_EXSLB+EX_R13(r13)
- ld r12,PACALPPACA+LPPACASRR1(r13);
+ ld r12,PACALPPACAPTR(r13)
+ ld r12,LPPACASRR1(r12)
b .slb_miss_realmode
STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
@@ -645,7 +647,8 @@ instruction_access_slb_iSeries:
mtspr SPRN_SPRG1,r13 /* save r13 */
mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
std r3,PACA_EXSLB+EX_R3(r13)
- ld r3,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
+ ld r3,PACALPPACAPTR(r13)
+ ld r3,LPPACASRR0(r3) /* get SRR0 value */
std r9,PACA_EXSLB+EX_R9(r13)
mfcr r9
#ifdef __DISABLED__
@@ -657,7 +660,8 @@ instruction_access_slb_iSeries:
std r12,PACA_EXSLB+EX_R12(r13)
mfspr r10,SPRN_SPRG1
std r10,PACA_EXSLB+EX_R13(r13)
- ld r12,PACALPPACA+LPPACASRR1(r13);
+ ld r12,PACALPPACAPTR(r13)
+ ld r12,LPPACASRR1(r12)
b .slb_miss_realmode
#ifdef __DISABLED__
@@ -746,7 +750,8 @@ iSeries_secondary_smp_loop:
.globl decrementer_iSeries_masked
decrementer_iSeries_masked:
li r11,1
- stb r11,PACALPPACA+LPPACADECRINT(r13)
+ ld r12,PACALPPACAPTR(r13)
+ stb r11,LPPACADECRINT(r12)
LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy)
lwz r12,ADDROFF(tb_ticks_per_jiffy)(r12)
mtspr SPRN_DEC,r12
@@ -755,8 +760,9 @@ decrementer_iSeries_masked:
.globl hardware_interrupt_iSeries_masked
hardware_interrupt_iSeries_masked:
mtcrf 0x80,r9 /* Restore regs */
- ld r11,PACALPPACA+LPPACASRR0(r13)
- ld r12,PACALPPACA+LPPACASRR1(r13)
+ ld r12,PACALPPACAPTR(r13)
+ ld r11,LPPACASRR0(r12)
+ ld r12,LPPACASRR1(r12)
mtspr SPRN_SRR0,r11
mtspr SPRN_SRR1,r12
ld r9,PACA_EXGEN+EX_R9(r13)
@@ -995,7 +1001,8 @@ _GLOBAL(slb_miss_realmode)
ld r3,PACA_EXSLB+EX_R3(r13)
lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
#ifdef CONFIG_PPC_ISERIES
- ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */
+ ld r11,PACALPPACAPTR(r13)
+ ld r11,LPPACASRR0(r11) /* get SRR0 value */
#endif /* CONFIG_PPC_ISERIES */
mtlr r10
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5651032d870..d1fffce86df 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -238,14 +238,10 @@ void do_IRQ(struct pt_regs *regs)
irq_exit();
#ifdef CONFIG_PPC_ISERIES
- {
- struct paca_struct *lpaca = get_paca();
-
- if (lpaca->lppaca.int_dword.fields.decr_int) {
- lpaca->lppaca.int_dword.fields.decr_int = 0;
- /* Signal a fake decrementer interrupt */
- timer_interrupt(regs);
- }
+ if (get_lppaca()->int_dword.fields.decr_int) {
+ get_lppaca()->int_dword.fields.decr_int = 0;
+ /* Signal a fake decrementer interrupt */
+ timer_interrupt(regs);
}
#endif
}
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 9dda16ccde7..1ae96a8ed7e 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -55,15 +55,13 @@ static unsigned long get_purr(void)
{
unsigned long sum_purr = 0;
int cpu;
- struct paca_struct *lpaca;
for_each_cpu(cpu) {
- lpaca = paca + cpu;
- sum_purr += lpaca->lppaca.emulated_time_base;
+ sum_purr += lppaca[cpu].emulated_time_base;
#ifdef PURR_DEBUG
printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n",
- cpu, lpaca->lppaca.emulated_time_base);
+ cpu, lppaca[cpu].emulated_time_base);
#endif
}
return sum_purr;
@@ -79,12 +77,11 @@ static int lparcfg_data(struct seq_file *m, void *v)
unsigned long pool_id, lp_index;
int shared, entitled_capacity, max_entitled_capacity;
int processors, max_processors;
- struct paca_struct *lpaca = get_paca();
unsigned long purr = get_purr();
seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
- shared = (int)(lpaca->lppaca_ptr->shared_proc);
+ shared = (int)(get_lppaca()->shared_proc);
seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n",
e2a(xItExtVpdPanel.mfgID[2]),
e2a(xItExtVpdPanel.mfgID[3]),
@@ -402,7 +399,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
(h_resource >> 0 * 8) & 0xffff);
/* pool related entries are apropriate for shared configs */
- if (paca[0].lppaca.shared_proc) {
+ if (lppaca[0].shared_proc) {
h_pic(&pool_idle_time, &pool_procs);
@@ -451,7 +448,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
seq_printf(m, "partition_potential_processors=%d\n",
partition_potential_processors);
- seq_printf(m, "shared_processor_mode=%d\n", paca[0].lppaca.shared_proc);
+ seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc);
return 0;
}
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 999bdd81676..5d1b708086b 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -25,6 +25,28 @@
* field correctly */
extern unsigned long __toc_start;
+/*
+ * iSeries structure which the hypervisor knows about - this structure
+ * should not cross a page boundary. The vpa_init/register_vpa call
+ * is now known to fail if the lppaca structure crosses a page
+ * boundary. The lppaca is also used on POWER5 pSeries boxes. The
+ * lppaca is 640 bytes long, and cannot readily change since the
+ * hypervisor knows its layout, so a 1kB alignment will suffice to
+ * ensure that it doesn't cross a page boundary.
+ */
+struct lppaca lppaca[] = {
+ [0 ... (NR_CPUS-1)] = {
+ .desc = 0xd397d781, /* "LpPa" */
+ .size = sizeof(struct lppaca),
+ .dyn_proc_status = 2,
+ .decr_val = 0x00ff0000,
+ .fpregs_in_use = 1,
+ .end_of_quantum = 0xfffffffffffffffful,
+ .slb_count = 64,
+ .vmxregs_in_use = 0,
+ },
+};
+
/* The Paca is an array with one entry per processor. Each contains an
* lppaca, which contains the information shared between the
* hypervisor and Linux.
@@ -35,27 +57,17 @@ extern unsigned long __toc_start;
* processor (not thread).
*/
#define PACA_INIT_COMMON(number, start, asrr, asrv) \
+ .lppaca_ptr = &lppaca[number], \
.lock_token = 0x8000, \
.paca_index = (number), /* Paca Index */ \
.kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
.stab_real = (asrr), /* Real pointer to segment table */ \
.stab_addr = (asrv), /* Virt pointer to segment table */ \
.cpu_start = (start), /* Processor start */ \
- .hw_cpu_id = 0xffff, \
- .lppaca = { \
- .desc = 0xd397d781, /* "LpPa" */ \
- .size = sizeof(struct lppaca), \
- .dyn_proc_status = 2, \
- .decr_val = 0x00ff0000, \
- .fpregs_in_use = 1, \
- .end_of_quantum = 0xfffffffffffffffful, \
- .slb_count = 64, \
- .vmxregs_in_use = 0, \
- }, \
+ .hw_cpu_id = 0xffff,
#ifdef CONFIG_PPC_ISERIES
#define PACA_INIT_ISERIES(number) \
- .lppaca_ptr = &paca[number].lppaca, \
.reg_save_ptr = &iseries_reg_save[number],
#define PACA_INIT(number) \
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 56f50e91bdd..c4a294d657b 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -431,7 +431,7 @@ void timer_interrupt(struct pt_regs * regs)
profile_tick(CPU_PROFILING, regs);
#ifdef CONFIG_PPC_ISERIES
- get_paca()->lppaca.int_dword.fields.decr_int = 0;
+ get_lppaca()->int_dword.fields.decr_int = 0;
#endif
while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))