aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Gibson <david@gibson.dropbear.id.au>2006-01-12 18:26:42 -0500
committerPaul Mackerras <paulus@samba.org>2006-01-13 05:17:39 -0500
commit3356bb9f7ba378a6e2709f9df95f4ea52111f4df (patch)
tree84f370df6e58cec63132f9acce492d585226e671
parente58c3495e6007af59382540bb21ee941e470d88d (diff)
[PATCH] powerpc: Remove lppaca structure from the PACA
At present the lppaca - the structure shared with the iSeries hypervisor and phyp - is contained within the PACA, our own low-level per-cpu structure. This doesn't have to be so, the patch below removes it, making a separate array of lppaca structures. This saves approximately 500*NR_CPUS bytes of image size and kernel memory, because we don't need aligning gap between the Linux and hypervisor portions of every PACA. On the other hand it means an extra level of dereference in many accesses to the lppaca. The patch also gets rid of several places where we assign the paca address to a local variable for no particular reason. Signed-off-by: David Gibson <dwg@au1.ibm.com> Signed-off-by: Paul Mackerras <paulus@samba.org>
-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
-rw-r--r--arch/powerpc/lib/locks.c8
-rw-r--r--arch/powerpc/platforms/iseries/irq.c6
-rw-r--r--arch/powerpc/platforms/iseries/misc.S3
-rw-r--r--arch/powerpc/platforms/iseries/setup.c8
-rw-r--r--arch/powerpc/platforms/iseries/smp.c2
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c4
-rw-r--r--arch/powerpc/platforms/pseries/setup.c20
-rw-r--r--include/asm-powerpc/lppaca.h6
-rw-r--r--include/asm-powerpc/paca.h14
-rw-r--r--include/asm-powerpc/spinlock.h2
-rw-r--r--include/asm-powerpc/time.h5
18 files changed, 84 insertions, 87 deletions
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index 56399c5c931a..840aad43a98b 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -135,7 +135,7 @@ int main(void)
135 DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc)); 135 DEFINE(PACA_EXMC, offsetof(struct paca_struct, exmc));
136 DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb)); 136 DEFINE(PACA_EXSLB, offsetof(struct paca_struct, exslb));
137 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp)); 137 DEFINE(PACAEMERGSP, offsetof(struct paca_struct, emergency_sp));
138 DEFINE(PACALPPACA, offsetof(struct paca_struct, lppaca)); 138 DEFINE(PACALPPACAPTR, offsetof(struct paca_struct, lppaca_ptr));
139 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id)); 139 DEFINE(PACAHWCPUID, offsetof(struct paca_struct, hw_cpu_id));
140 140
141 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0)); 141 DEFINE(LPPACASRR0, offsetof(struct lppaca, saved_srr0));
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 4ba81e1b6bf1..542036318866 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -511,7 +511,8 @@ restore:
511 cmpdi 0,r5,0 511 cmpdi 0,r5,0
512 beq 4f 512 beq 4f
513 /* Check for pending interrupts (iSeries) */ 513 /* Check for pending interrupts (iSeries) */
514 ld r3,PACALPPACA+LPPACAANYINT(r13) 514 ld r3,PACALPPACAPTR(r13)
515 ld r3,LPPACAANYINT(r3)
515 cmpdi r3,0 516 cmpdi r3,0
516 beq+ 4f /* skip do_IRQ if no interrupts */ 517 beq+ 4f /* skip do_IRQ if no interrupts */
517 518
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index b3718f3eb7b5..308268466342 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -255,8 +255,9 @@ exception_marker:
255 255
256#define EXCEPTION_PROLOG_ISERIES_2 \ 256#define EXCEPTION_PROLOG_ISERIES_2 \
257 mfmsr r10; \ 257 mfmsr r10; \
258 ld r11,PACALPPACA+LPPACASRR0(r13); \ 258 ld r12,PACALPPACAPTR(r13); \
259 ld r12,PACALPPACA+LPPACASRR1(r13); \ 259 ld r11,LPPACASRR0(r12); \
260 ld r12,LPPACASRR1(r12); \
260 ori r10,r10,MSR_RI; \ 261 ori r10,r10,MSR_RI; \
261 mtmsrd r10,1 262 mtmsrd r10,1
262 263
@@ -635,7 +636,8 @@ data_access_slb_iSeries:
635 std r12,PACA_EXSLB+EX_R12(r13) 636 std r12,PACA_EXSLB+EX_R12(r13)
636 mfspr r10,SPRN_SPRG1 637 mfspr r10,SPRN_SPRG1
637 std r10,PACA_EXSLB+EX_R13(r13) 638 std r10,PACA_EXSLB+EX_R13(r13)
638 ld r12,PACALPPACA+LPPACASRR1(r13); 639 ld r12,PACALPPACAPTR(r13)
640 ld r12,LPPACASRR1(r12)
639 b .slb_miss_realmode 641 b .slb_miss_realmode
640 642
641 STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN) 643 STD_EXCEPTION_ISERIES(0x400, instruction_access, PACA_EXGEN)
@@ -645,7 +647,8 @@ instruction_access_slb_iSeries:
645 mtspr SPRN_SPRG1,r13 /* save r13 */ 647 mtspr SPRN_SPRG1,r13 /* save r13 */
646 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */ 648 mfspr r13,SPRN_SPRG3 /* get paca address into r13 */
647 std r3,PACA_EXSLB+EX_R3(r13) 649 std r3,PACA_EXSLB+EX_R3(r13)
648 ld r3,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */ 650 ld r3,PACALPPACAPTR(r13)
651 ld r3,LPPACASRR0(r3) /* get SRR0 value */
649 std r9,PACA_EXSLB+EX_R9(r13) 652 std r9,PACA_EXSLB+EX_R9(r13)
650 mfcr r9 653 mfcr r9
651#ifdef __DISABLED__ 654#ifdef __DISABLED__
@@ -657,7 +660,8 @@ instruction_access_slb_iSeries:
657 std r12,PACA_EXSLB+EX_R12(r13) 660 std r12,PACA_EXSLB+EX_R12(r13)
658 mfspr r10,SPRN_SPRG1 661 mfspr r10,SPRN_SPRG1
659 std r10,PACA_EXSLB+EX_R13(r13) 662 std r10,PACA_EXSLB+EX_R13(r13)
660 ld r12,PACALPPACA+LPPACASRR1(r13); 663 ld r12,PACALPPACAPTR(r13)
664 ld r12,LPPACASRR1(r12)
661 b .slb_miss_realmode 665 b .slb_miss_realmode
662 666
663#ifdef __DISABLED__ 667#ifdef __DISABLED__
@@ -746,7 +750,8 @@ iSeries_secondary_smp_loop:
746 .globl decrementer_iSeries_masked 750 .globl decrementer_iSeries_masked
747decrementer_iSeries_masked: 751decrementer_iSeries_masked:
748 li r11,1 752 li r11,1
749 stb r11,PACALPPACA+LPPACADECRINT(r13) 753 ld r12,PACALPPACAPTR(r13)
754 stb r11,LPPACADECRINT(r12)
750 LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy) 755 LOAD_REG_ADDRBASE(r12,tb_ticks_per_jiffy)
751 lwz r12,ADDROFF(tb_ticks_per_jiffy)(r12) 756 lwz r12,ADDROFF(tb_ticks_per_jiffy)(r12)
752 mtspr SPRN_DEC,r12 757 mtspr SPRN_DEC,r12
@@ -755,8 +760,9 @@ decrementer_iSeries_masked:
755 .globl hardware_interrupt_iSeries_masked 760 .globl hardware_interrupt_iSeries_masked
756hardware_interrupt_iSeries_masked: 761hardware_interrupt_iSeries_masked:
757 mtcrf 0x80,r9 /* Restore regs */ 762 mtcrf 0x80,r9 /* Restore regs */
758 ld r11,PACALPPACA+LPPACASRR0(r13) 763 ld r12,PACALPPACAPTR(r13)
759 ld r12,PACALPPACA+LPPACASRR1(r13) 764 ld r11,LPPACASRR0(r12)
765 ld r12,LPPACASRR1(r12)
760 mtspr SPRN_SRR0,r11 766 mtspr SPRN_SRR0,r11
761 mtspr SPRN_SRR1,r12 767 mtspr SPRN_SRR1,r12
762 ld r9,PACA_EXGEN+EX_R9(r13) 768 ld r9,PACA_EXGEN+EX_R9(r13)
@@ -995,7 +1001,8 @@ _GLOBAL(slb_miss_realmode)
995 ld r3,PACA_EXSLB+EX_R3(r13) 1001 ld r3,PACA_EXSLB+EX_R3(r13)
996 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */ 1002 lwz r9,PACA_EXSLB+EX_CCR(r13) /* get saved CR */
997#ifdef CONFIG_PPC_ISERIES 1003#ifdef CONFIG_PPC_ISERIES
998 ld r11,PACALPPACA+LPPACASRR0(r13) /* get SRR0 value */ 1004 ld r11,PACALPPACAPTR(r13)
1005 ld r11,LPPACASRR0(r11) /* get SRR0 value */
999#endif /* CONFIG_PPC_ISERIES */ 1006#endif /* CONFIG_PPC_ISERIES */
1000 1007
1001 mtlr r10 1008 mtlr r10
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5651032d8706..d1fffce86df9 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -238,14 +238,10 @@ void do_IRQ(struct pt_regs *regs)
238 irq_exit(); 238 irq_exit();
239 239
240#ifdef CONFIG_PPC_ISERIES 240#ifdef CONFIG_PPC_ISERIES
241 { 241 if (get_lppaca()->int_dword.fields.decr_int) {
242 struct paca_struct *lpaca = get_paca(); 242 get_lppaca()->int_dword.fields.decr_int = 0;
243 243 /* Signal a fake decrementer interrupt */
244 if (lpaca->lppaca.int_dword.fields.decr_int) { 244 timer_interrupt(regs);
245 lpaca->lppaca.int_dword.fields.decr_int = 0;
246 /* Signal a fake decrementer interrupt */
247 timer_interrupt(regs);
248 }
249 } 245 }
250#endif 246#endif
251} 247}
diff --git a/arch/powerpc/kernel/lparcfg.c b/arch/powerpc/kernel/lparcfg.c
index 9dda16ccde78..1ae96a8ed7e2 100644
--- a/arch/powerpc/kernel/lparcfg.c
+++ b/arch/powerpc/kernel/lparcfg.c
@@ -55,15 +55,13 @@ static unsigned long get_purr(void)
55{ 55{
56 unsigned long sum_purr = 0; 56 unsigned long sum_purr = 0;
57 int cpu; 57 int cpu;
58 struct paca_struct *lpaca;
59 58
60 for_each_cpu(cpu) { 59 for_each_cpu(cpu) {
61 lpaca = paca + cpu; 60 sum_purr += lppaca[cpu].emulated_time_base;
62 sum_purr += lpaca->lppaca.emulated_time_base;
63 61
64#ifdef PURR_DEBUG 62#ifdef PURR_DEBUG
65 printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", 63 printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n",
66 cpu, lpaca->lppaca.emulated_time_base); 64 cpu, lppaca[cpu].emulated_time_base);
67#endif 65#endif
68 } 66 }
69 return sum_purr; 67 return sum_purr;
@@ -79,12 +77,11 @@ static int lparcfg_data(struct seq_file *m, void *v)
79 unsigned long pool_id, lp_index; 77 unsigned long pool_id, lp_index;
80 int shared, entitled_capacity, max_entitled_capacity; 78 int shared, entitled_capacity, max_entitled_capacity;
81 int processors, max_processors; 79 int processors, max_processors;
82 struct paca_struct *lpaca = get_paca();
83 unsigned long purr = get_purr(); 80 unsigned long purr = get_purr();
84 81
85 seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); 82 seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS);
86 83
87 shared = (int)(lpaca->lppaca_ptr->shared_proc); 84 shared = (int)(get_lppaca()->shared_proc);
88 seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", 85 seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n",
89 e2a(xItExtVpdPanel.mfgID[2]), 86 e2a(xItExtVpdPanel.mfgID[2]),
90 e2a(xItExtVpdPanel.mfgID[3]), 87 e2a(xItExtVpdPanel.mfgID[3]),
@@ -402,7 +399,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
402 (h_resource >> 0 * 8) & 0xffff); 399 (h_resource >> 0 * 8) & 0xffff);
403 400
404 /* pool related entries are apropriate for shared configs */ 401 /* pool related entries are apropriate for shared configs */
405 if (paca[0].lppaca.shared_proc) { 402 if (lppaca[0].shared_proc) {
406 403
407 h_pic(&pool_idle_time, &pool_procs); 404 h_pic(&pool_idle_time, &pool_procs);
408 405
@@ -451,7 +448,7 @@ static int lparcfg_data(struct seq_file *m, void *v)
451 seq_printf(m, "partition_potential_processors=%d\n", 448 seq_printf(m, "partition_potential_processors=%d\n",
452 partition_potential_processors); 449 partition_potential_processors);
453 450
454 seq_printf(m, "shared_processor_mode=%d\n", paca[0].lppaca.shared_proc); 451 seq_printf(m, "shared_processor_mode=%d\n", lppaca[0].shared_proc);
455 452
456 return 0; 453 return 0;
457} 454}
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 999bdd816769..5d1b708086bd 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -25,6 +25,28 @@
25 * field correctly */ 25 * field correctly */
26extern unsigned long __toc_start; 26extern unsigned long __toc_start;
27 27
28/*
29 * iSeries structure which the hypervisor knows about - this structure
30 * should not cross a page boundary. The vpa_init/register_vpa call
31 * is now known to fail if the lppaca structure crosses a page
32 * boundary. The lppaca is also used on POWER5 pSeries boxes. The
33 * lppaca is 640 bytes long, and cannot readily change since the
34 * hypervisor knows its layout, so a 1kB alignment will suffice to
35 * ensure that it doesn't cross a page boundary.
36 */
37struct lppaca lppaca[] = {
38 [0 ... (NR_CPUS-1)] = {
39 .desc = 0xd397d781, /* "LpPa" */
40 .size = sizeof(struct lppaca),
41 .dyn_proc_status = 2,
42 .decr_val = 0x00ff0000,
43 .fpregs_in_use = 1,
44 .end_of_quantum = 0xfffffffffffffffful,
45 .slb_count = 64,
46 .vmxregs_in_use = 0,
47 },
48};
49
28/* The Paca is an array with one entry per processor. Each contains an 50/* The Paca is an array with one entry per processor. Each contains an
29 * lppaca, which contains the information shared between the 51 * lppaca, which contains the information shared between the
30 * hypervisor and Linux. 52 * hypervisor and Linux.
@@ -35,27 +57,17 @@ extern unsigned long __toc_start;
35 * processor (not thread). 57 * processor (not thread).
36 */ 58 */
37#define PACA_INIT_COMMON(number, start, asrr, asrv) \ 59#define PACA_INIT_COMMON(number, start, asrr, asrv) \
60 .lppaca_ptr = &lppaca[number], \
38 .lock_token = 0x8000, \ 61 .lock_token = 0x8000, \
39 .paca_index = (number), /* Paca Index */ \ 62 .paca_index = (number), /* Paca Index */ \
40 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \ 63 .kernel_toc = (unsigned long)(&__toc_start) + 0x8000UL, \
41 .stab_real = (asrr), /* Real pointer to segment table */ \ 64 .stab_real = (asrr), /* Real pointer to segment table */ \
42 .stab_addr = (asrv), /* Virt pointer to segment table */ \ 65 .stab_addr = (asrv), /* Virt pointer to segment table */ \
43 .cpu_start = (start), /* Processor start */ \ 66 .cpu_start = (start), /* Processor start */ \
44 .hw_cpu_id = 0xffff, \ 67 .hw_cpu_id = 0xffff,
45 .lppaca = { \
46 .desc = 0xd397d781, /* "LpPa" */ \
47 .size = sizeof(struct lppaca), \
48 .dyn_proc_status = 2, \
49 .decr_val = 0x00ff0000, \
50 .fpregs_in_use = 1, \
51 .end_of_quantum = 0xfffffffffffffffful, \
52 .slb_count = 64, \
53 .vmxregs_in_use = 0, \
54 }, \
55 68
56#ifdef CONFIG_PPC_ISERIES 69#ifdef CONFIG_PPC_ISERIES
57#define PACA_INIT_ISERIES(number) \ 70#define PACA_INIT_ISERIES(number) \
58 .lppaca_ptr = &paca[number].lppaca, \
59 .reg_save_ptr = &iseries_reg_save[number], 71 .reg_save_ptr = &iseries_reg_save[number],
60 72
61#define PACA_INIT(number) \ 73#define PACA_INIT(number) \
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 56f50e91bddb..c4a294d657b9 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -431,7 +431,7 @@ void timer_interrupt(struct pt_regs * regs)
431 profile_tick(CPU_PROFILING, regs); 431 profile_tick(CPU_PROFILING, regs);
432 432
433#ifdef CONFIG_PPC_ISERIES 433#ifdef CONFIG_PPC_ISERIES
434 get_paca()->lppaca.int_dword.fields.decr_int = 0; 434 get_lppaca()->int_dword.fields.decr_int = 0;
435#endif 435#endif
436 436
437 while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu))) 437 while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))
diff --git a/arch/powerpc/lib/locks.c b/arch/powerpc/lib/locks.c
index 35bd03c41dd1..8362fa272ca5 100644
--- a/arch/powerpc/lib/locks.c
+++ b/arch/powerpc/lib/locks.c
@@ -28,15 +28,13 @@
28void __spin_yield(raw_spinlock_t *lock) 28void __spin_yield(raw_spinlock_t *lock)
29{ 29{
30 unsigned int lock_value, holder_cpu, yield_count; 30 unsigned int lock_value, holder_cpu, yield_count;
31 struct paca_struct *holder_paca;
32 31
33 lock_value = lock->slock; 32 lock_value = lock->slock;
34 if (lock_value == 0) 33 if (lock_value == 0)
35 return; 34 return;
36 holder_cpu = lock_value & 0xffff; 35 holder_cpu = lock_value & 0xffff;
37 BUG_ON(holder_cpu >= NR_CPUS); 36 BUG_ON(holder_cpu >= NR_CPUS);
38 holder_paca = &paca[holder_cpu]; 37 yield_count = lppaca[holder_cpu].yield_count;
39 yield_count = holder_paca->lppaca.yield_count;
40 if ((yield_count & 1) == 0) 38 if ((yield_count & 1) == 0)
41 return; /* virtual cpu is currently running */ 39 return; /* virtual cpu is currently running */
42 rmb(); 40 rmb();
@@ -60,15 +58,13 @@ void __rw_yield(raw_rwlock_t *rw)
60{ 58{
61 int lock_value; 59 int lock_value;
62 unsigned int holder_cpu, yield_count; 60 unsigned int holder_cpu, yield_count;
63 struct paca_struct *holder_paca;
64 61
65 lock_value = rw->lock; 62 lock_value = rw->lock;
66 if (lock_value >= 0) 63 if (lock_value >= 0)
67 return; /* no write lock at present */ 64 return; /* no write lock at present */
68 holder_cpu = lock_value & 0xffff; 65 holder_cpu = lock_value & 0xffff;
69 BUG_ON(holder_cpu >= NR_CPUS); 66 BUG_ON(holder_cpu >= NR_CPUS);
70 holder_paca = &paca[holder_cpu]; 67 yield_count = lppaca[holder_cpu].yield_count;
71 yield_count = holder_paca->lppaca.yield_count;
72 if ((yield_count & 1) == 0) 68 if ((yield_count & 1) == 0)
73 return; /* virtual cpu is currently running */ 69 return; /* virtual cpu is currently running */
74 rmb(); 70 rmb();
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c
index 83442ea77476..be3fbfc24e6c 100644
--- a/arch/powerpc/platforms/iseries/irq.c
+++ b/arch/powerpc/platforms/iseries/irq.c
@@ -334,14 +334,12 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus,
334 */ 334 */
335int iSeries_get_irq(struct pt_regs *regs) 335int iSeries_get_irq(struct pt_regs *regs)
336{ 336{
337 struct paca_struct *lpaca;
338 /* -2 means ignore this interrupt */ 337 /* -2 means ignore this interrupt */
339 int irq = -2; 338 int irq = -2;
340 339
341 lpaca = get_paca();
342#ifdef CONFIG_SMP 340#ifdef CONFIG_SMP
343 if (lpaca->lppaca.int_dword.fields.ipi_cnt) { 341 if (get_lppaca()->int_dword.fields.ipi_cnt) {
344 lpaca->lppaca.int_dword.fields.ipi_cnt = 0; 342 get_lppaca()->int_dword.fields.ipi_cnt = 0;
345 iSeries_smp_message_recv(regs); 343 iSeries_smp_message_recv(regs);
346 } 344 }
347#endif /* CONFIG_SMP */ 345#endif /* CONFIG_SMP */
diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S
index dfe7aa1ba098..7641fc7e550a 100644
--- a/arch/powerpc/platforms/iseries/misc.S
+++ b/arch/powerpc/platforms/iseries/misc.S
@@ -44,7 +44,8 @@ _GLOBAL(local_irq_restore)
44 /* Check pending interrupts */ 44 /* Check pending interrupts */
45 /* A decrementer, IPI or PMC interrupt may have occurred 45 /* A decrementer, IPI or PMC interrupt may have occurred
46 * while we were in the hypervisor (which enables) */ 46 * while we were in the hypervisor (which enables) */
47 ld r4,PACALPPACA+LPPACAANYINT(r13) 47 ld r4,PACALPPACAPTR(r13)
48 ld r4,LPPACAANYINT(r4)
48 cmpdi r4,0 49 cmpdi r4,0
49 beqlr 50 beqlr
50 51
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index c6bbe5c25107..3f8790146b00 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -538,7 +538,7 @@ static unsigned long __init build_iSeries_Memory_Map(void)
538 */ 538 */
539static void __init iSeries_setup_arch(void) 539static void __init iSeries_setup_arch(void)
540{ 540{
541 if (get_paca()->lppaca.shared_proc) { 541 if (get_lppaca()->shared_proc) {
542 ppc_md.idle_loop = iseries_shared_idle; 542 ppc_md.idle_loop = iseries_shared_idle;
543 printk(KERN_INFO "Using shared processor idle loop\n"); 543 printk(KERN_INFO "Using shared processor idle loop\n");
544 } else { 544 } else {
@@ -647,7 +647,7 @@ static void yield_shared_processor(void)
647 * The decrementer stops during the yield. Force a fake decrementer 647 * The decrementer stops during the yield. Force a fake decrementer
648 * here and let the timer_interrupt code sort out the actual time. 648 * here and let the timer_interrupt code sort out the actual time.
649 */ 649 */
650 get_paca()->lppaca.int_dword.fields.decr_int = 1; 650 get_lppaca()->int_dword.fields.decr_int = 1;
651 process_iSeries_events(); 651 process_iSeries_events();
652} 652}
653 653
@@ -883,7 +883,7 @@ void dt_cpus(struct iseries_flat_dt *dt)
883 pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); 883 pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE);
884 884
885 for (i = 0; i < NR_CPUS; i++) { 885 for (i = 0; i < NR_CPUS; i++) {
886 if (paca[i].lppaca.dyn_proc_status >= 2) 886 if (lppaca[i].dyn_proc_status >= 2)
887 continue; 887 continue;
888 888
889 snprintf(p, 32 - (p - buf), "@%d", i); 889 snprintf(p, 32 - (p - buf), "@%d", i);
@@ -891,7 +891,7 @@ void dt_cpus(struct iseries_flat_dt *dt)
891 891
892 dt_prop_str(dt, "device_type", "cpu"); 892 dt_prop_str(dt, "device_type", "cpu");
893 893
894 index = paca[i].lppaca.dyn_hv_phys_proc_index; 894 index = lppaca[i].dyn_hv_phys_proc_index;
895 d = &xIoHriProcessorVpd[index]; 895 d = &xIoHriProcessorVpd[index];
896 896
897 dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); 897 dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024);
diff --git a/arch/powerpc/platforms/iseries/smp.c b/arch/powerpc/platforms/iseries/smp.c
index fcb094ec6aec..6f9d407a709f 100644
--- a/arch/powerpc/platforms/iseries/smp.c
+++ b/arch/powerpc/platforms/iseries/smp.c
@@ -91,7 +91,7 @@ static void smp_iSeries_kick_cpu(int nr)
91 BUG_ON((nr < 0) || (nr >= NR_CPUS)); 91 BUG_ON((nr < 0) || (nr >= NR_CPUS));
92 92
93 /* Verify that our partition has a processor nr */ 93 /* Verify that our partition has a processor nr */
94 if (paca[nr].lppaca.dyn_proc_status >= 2) 94 if (lppaca[nr].dyn_proc_status >= 2)
95 return; 95 return;
96 96
97 /* The processor is currently spinning, waiting 97 /* The processor is currently spinning, waiting
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 1fe445ab78a6..8952528d31ac 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -254,11 +254,11 @@ out:
254void vpa_init(int cpu) 254void vpa_init(int cpu)
255{ 255{
256 int hwcpu = get_hard_smp_processor_id(cpu); 256 int hwcpu = get_hard_smp_processor_id(cpu);
257 unsigned long vpa = __pa(&paca[cpu].lppaca); 257 unsigned long vpa = __pa(&lppaca[cpu]);
258 long ret; 258 long ret;
259 259
260 if (cpu_has_feature(CPU_FTR_ALTIVEC)) 260 if (cpu_has_feature(CPU_FTR_ALTIVEC))
261 paca[cpu].lppaca.vmxregs_in_use = 1; 261 lppaca[cpu].vmxregs_in_use = 1;
262 262
263 ret = register_vpa(hwcpu, vpa); 263 ret = register_vpa(hwcpu, vpa);
264 264
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 68b7f086d63d..da6cebaf72cd 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -190,7 +190,7 @@ static void pseries_lpar_enable_pmcs(void)
190 190
191 /* instruct hypervisor to maintain PMCs */ 191 /* instruct hypervisor to maintain PMCs */
192 if (firmware_has_feature(FW_FEATURE_SPLPAR)) 192 if (firmware_has_feature(FW_FEATURE_SPLPAR))
193 get_paca()->lppaca.pmcregs_in_use = 1; 193 get_lppaca()->pmcregs_in_use = 1;
194} 194}
195 195
196static void __init pSeries_setup_arch(void) 196static void __init pSeries_setup_arch(void)
@@ -234,7 +234,7 @@ static void __init pSeries_setup_arch(void)
234 /* Choose an idle loop */ 234 /* Choose an idle loop */
235 if (firmware_has_feature(FW_FEATURE_SPLPAR)) { 235 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
236 vpa_init(boot_cpuid); 236 vpa_init(boot_cpuid);
237 if (get_paca()->lppaca.shared_proc) { 237 if (get_lppaca()->shared_proc) {
238 printk(KERN_INFO "Using shared processor idle loop\n"); 238 printk(KERN_INFO "Using shared processor idle loop\n");
239 ppc_md.idle_loop = pseries_shared_idle; 239 ppc_md.idle_loop = pseries_shared_idle;
240 } else { 240 } else {
@@ -444,10 +444,10 @@ DECLARE_PER_CPU(unsigned long, smt_snooze_delay);
444 444
445static inline void dedicated_idle_sleep(unsigned int cpu) 445static inline void dedicated_idle_sleep(unsigned int cpu)
446{ 446{
447 struct paca_struct *ppaca = &paca[cpu ^ 1]; 447 struct lppaca *plppaca = &lppaca[cpu ^ 1];
448 448
449 /* Only sleep if the other thread is not idle */ 449 /* Only sleep if the other thread is not idle */
450 if (!(ppaca->lppaca.idle)) { 450 if (!(plppaca->idle)) {
451 local_irq_disable(); 451 local_irq_disable();
452 452
453 /* 453 /*
@@ -480,7 +480,6 @@ static inline void dedicated_idle_sleep(unsigned int cpu)
480 480
481static void pseries_dedicated_idle(void) 481static void pseries_dedicated_idle(void)
482{ 482{
483 struct paca_struct *lpaca = get_paca();
484 unsigned int cpu = smp_processor_id(); 483 unsigned int cpu = smp_processor_id();
485 unsigned long start_snooze; 484 unsigned long start_snooze;
486 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay); 485 unsigned long *smt_snooze_delay = &__get_cpu_var(smt_snooze_delay);
@@ -491,7 +490,7 @@ static void pseries_dedicated_idle(void)
491 * Indicate to the HV that we are idle. Now would be 490 * Indicate to the HV that we are idle. Now would be
492 * a good time to find other work to dispatch. 491 * a good time to find other work to dispatch.
493 */ 492 */
494 lpaca->lppaca.idle = 1; 493 get_lppaca()->idle = 1;
495 494
496 if (!need_resched()) { 495 if (!need_resched()) {
497 start_snooze = get_tb() + 496 start_snooze = get_tb() +
@@ -518,7 +517,7 @@ static void pseries_dedicated_idle(void)
518 HMT_medium(); 517 HMT_medium();
519 } 518 }
520 519
521 lpaca->lppaca.idle = 0; 520 get_lppaca()->idle = 0;
522 ppc64_runlatch_on(); 521 ppc64_runlatch_on();
523 522
524 preempt_enable_no_resched(); 523 preempt_enable_no_resched();
@@ -532,7 +531,6 @@ static void pseries_dedicated_idle(void)
532 531
533static void pseries_shared_idle(void) 532static void pseries_shared_idle(void)
534{ 533{
535 struct paca_struct *lpaca = get_paca();
536 unsigned int cpu = smp_processor_id(); 534 unsigned int cpu = smp_processor_id();
537 535
538 while (1) { 536 while (1) {
@@ -540,7 +538,7 @@ static void pseries_shared_idle(void)
540 * Indicate to the HV that we are idle. Now would be 538 * Indicate to the HV that we are idle. Now would be
541 * a good time to find other work to dispatch. 539 * a good time to find other work to dispatch.
542 */ 540 */
543 lpaca->lppaca.idle = 1; 541 get_lppaca()->idle = 1;
544 542
545 while (!need_resched() && !cpu_is_offline(cpu)) { 543 while (!need_resched() && !cpu_is_offline(cpu)) {
546 local_irq_disable(); 544 local_irq_disable();
@@ -564,7 +562,7 @@ static void pseries_shared_idle(void)
564 HMT_medium(); 562 HMT_medium();
565 } 563 }
566 564
567 lpaca->lppaca.idle = 0; 565 get_lppaca()->idle = 0;
568 ppc64_runlatch_on(); 566 ppc64_runlatch_on();
569 567
570 preempt_enable_no_resched(); 568 preempt_enable_no_resched();
@@ -588,7 +586,7 @@ static void pseries_kexec_cpu_down(int crash_shutdown, int secondary)
588{ 586{
589 /* Don't risk a hypervisor call if we're crashing */ 587 /* Don't risk a hypervisor call if we're crashing */
590 if (!crash_shutdown) { 588 if (!crash_shutdown) {
591 unsigned long vpa = __pa(&get_paca()->lppaca); 589 unsigned long vpa = __pa(get_lppaca());
592 590
593 if (unregister_vpa(hard_smp_processor_id(), vpa)) { 591 if (unregister_vpa(hard_smp_processor_id(), vpa)) {
594 printk("VPA deregistration of cpu %u (hw_cpu_id %d) " 592 printk("VPA deregistration of cpu %u (hw_cpu_id %d) "
diff --git a/include/asm-powerpc/lppaca.h b/include/asm-powerpc/lppaca.h
index ff82ea7c4829..cd9f11f1ef14 100644
--- a/include/asm-powerpc/lppaca.h
+++ b/include/asm-powerpc/lppaca.h
@@ -29,7 +29,9 @@
29//---------------------------------------------------------------------------- 29//----------------------------------------------------------------------------
30#include <asm/types.h> 30#include <asm/types.h>
31 31
32struct lppaca { 32/* The Hypervisor barfs if the lppaca crosses a page boundary. A 1k
33 * alignment is sufficient to prevent this */
34struct __attribute__((__aligned__(0x400))) lppaca {
33//============================================================================= 35//=============================================================================
34// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data 36// CACHE_LINE_1 0x0000 - 0x007F Contains read-only data
35// NOTE: The xDynXyz fields are fields that will be dynamically changed by 37// NOTE: The xDynXyz fields are fields that will be dynamically changed by
@@ -129,5 +131,7 @@ struct lppaca {
129 u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF 131 u8 pmc_save_area[256]; // PMC interrupt Area x00-xFF
130}; 132};
131 133
134extern struct lppaca lppaca[];
135
132#endif /* __KERNEL__ */ 136#endif /* __KERNEL__ */
133#endif /* _ASM_POWERPC_LPPACA_H */ 137#endif /* _ASM_POWERPC_LPPACA_H */
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index a64b4d425dab..c9add8f1ad94 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -23,6 +23,7 @@
23 23
24register struct paca_struct *local_paca asm("r13"); 24register struct paca_struct *local_paca asm("r13");
25#define get_paca() local_paca 25#define get_paca() local_paca
26#define get_lppaca() (get_paca()->lppaca_ptr)
26 27
27struct task_struct; 28struct task_struct;
28 29
@@ -95,19 +96,6 @@ struct paca_struct {
95 u64 saved_r1; /* r1 save for RTAS calls */ 96 u64 saved_r1; /* r1 save for RTAS calls */
96 u64 saved_msr; /* MSR saved here by enter_rtas */ 97 u64 saved_msr; /* MSR saved here by enter_rtas */
97 u8 proc_enabled; /* irq soft-enable flag */ 98 u8 proc_enabled; /* irq soft-enable flag */
98
99 /*
100 * iSeries structure which the hypervisor knows about -
101 * this structure should not cross a page boundary.
102 * The vpa_init/register_vpa call is now known to fail if the
103 * lppaca structure crosses a page boundary.
104 * The lppaca is also used on POWER5 pSeries boxes.
105 * The lppaca is 640 bytes long, and cannot readily change
106 * since the hypervisor knows its layout, so a 1kB
107 * alignment will suffice to ensure that it doesn't
108 * cross a page boundary.
109 */
110 struct lppaca lppaca __attribute__((__aligned__(0x400)));
111}; 99};
112 100
113extern struct paca_struct paca[]; 101extern struct paca_struct paca[];
diff --git a/include/asm-powerpc/spinlock.h b/include/asm-powerpc/spinlock.h
index 754900901cd8..26b8744ed529 100644
--- a/include/asm-powerpc/spinlock.h
+++ b/include/asm-powerpc/spinlock.h
@@ -80,7 +80,7 @@ static int __inline__ __raw_spin_trylock(raw_spinlock_t *lock)
80 80
81#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES) 81#if defined(CONFIG_PPC_SPLPAR) || defined(CONFIG_PPC_ISERIES)
82/* We only yield to the hypervisor if we are in shared processor mode */ 82/* We only yield to the hypervisor if we are in shared processor mode */
83#define SHARED_PROCESSOR (get_paca()->lppaca.shared_proc) 83#define SHARED_PROCESSOR (get_lppaca()->shared_proc)
84extern void __spin_yield(raw_spinlock_t *lock); 84extern void __spin_yield(raw_spinlock_t *lock);
85extern void __rw_yield(raw_rwlock_t *lock); 85extern void __rw_yield(raw_rwlock_t *lock);
86#else /* SPLPAR || ISERIES */ 86#else /* SPLPAR || ISERIES */
diff --git a/include/asm-powerpc/time.h b/include/asm-powerpc/time.h
index d9b86a17271b..baddc9ab57ad 100644
--- a/include/asm-powerpc/time.h
+++ b/include/asm-powerpc/time.h
@@ -175,11 +175,10 @@ static inline void set_dec(int val)
175 set_dec_cpu6(val); 175 set_dec_cpu6(val);
176#else 176#else
177#ifdef CONFIG_PPC_ISERIES 177#ifdef CONFIG_PPC_ISERIES
178 struct paca_struct *lpaca = get_paca();
179 int cur_dec; 178 int cur_dec;
180 179
181 if (lpaca->lppaca.shared_proc) { 180 if (get_lppaca()->shared_proc) {
182 lpaca->lppaca.virtual_decr = val; 181 get_lppaca()->virtual_decr = val;
183 cur_dec = get_dec(); 182 cur_dec = get_dec();
184 if (cur_dec > val) 183 if (cur_dec > val)
185 HvCall_setVirtualDecr(); 184 HvCall_setVirtualDecr();