aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2008-01-15 11:01:48 -0500
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2008-01-15 11:01:48 -0500
commitf885b51967fb5f611c462841e5119853df00cc97 (patch)
tree29ba7f6eb9dd607980e63917e7f68e88578e7aca
parent5d5d80001df3fbd06bd2b8893b6e3847e38a12d6 (diff)
parentdfbe0d3b6be52596b5694b1bb75b19562e769021 (diff)
Merge branch 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc
* 'merge' of git://git.kernel.org/pub/scm/linux/kernel/git/paulus/powerpc: [POWERPC] Fix boot failure on POWER6 [POWERPC] Workaround for iommu page alignment
-rw-r--r--arch/powerpc/kernel/iommu.c17
-rw-r--r--arch/powerpc/mm/slb.c10
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c1
-rw-r--r--include/asm-powerpc/mmu-hash64.h1
4 files changed, 16 insertions, 13 deletions
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index 2d0c9ef555e9..79a85d656871 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -278,6 +278,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
278 unsigned long flags; 278 unsigned long flags;
279 struct scatterlist *s, *outs, *segstart; 279 struct scatterlist *s, *outs, *segstart;
280 int outcount, incount, i; 280 int outcount, incount, i;
281 unsigned int align;
281 unsigned long handle; 282 unsigned long handle;
282 283
283 BUG_ON(direction == DMA_NONE); 284 BUG_ON(direction == DMA_NONE);
@@ -309,7 +310,12 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
309 /* Allocate iommu entries for that segment */ 310 /* Allocate iommu entries for that segment */
310 vaddr = (unsigned long) sg_virt(s); 311 vaddr = (unsigned long) sg_virt(s);
311 npages = iommu_num_pages(vaddr, slen); 312 npages = iommu_num_pages(vaddr, slen);
312 entry = iommu_range_alloc(tbl, npages, &handle, mask >> IOMMU_PAGE_SHIFT, 0); 313 align = 0;
314 if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && slen >= PAGE_SIZE &&
315 (vaddr & ~PAGE_MASK) == 0)
316 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
317 entry = iommu_range_alloc(tbl, npages, &handle,
318 mask >> IOMMU_PAGE_SHIFT, align);
313 319
314 DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen); 320 DBG(" - vaddr: %lx, size: %lx\n", vaddr, slen);
315 321
@@ -572,7 +578,7 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
572{ 578{
573 dma_addr_t dma_handle = DMA_ERROR_CODE; 579 dma_addr_t dma_handle = DMA_ERROR_CODE;
574 unsigned long uaddr; 580 unsigned long uaddr;
575 unsigned int npages; 581 unsigned int npages, align;
576 582
577 BUG_ON(direction == DMA_NONE); 583 BUG_ON(direction == DMA_NONE);
578 584
@@ -580,8 +586,13 @@ dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
580 npages = iommu_num_pages(uaddr, size); 586 npages = iommu_num_pages(uaddr, size);
581 587
582 if (tbl) { 588 if (tbl) {
589 align = 0;
590 if (IOMMU_PAGE_SHIFT < PAGE_SHIFT && size >= PAGE_SIZE &&
591 ((unsigned long)vaddr & ~PAGE_MASK) == 0)
592 align = PAGE_SHIFT - IOMMU_PAGE_SHIFT;
593
583 dma_handle = iommu_alloc(tbl, vaddr, npages, direction, 594 dma_handle = iommu_alloc(tbl, vaddr, npages, direction,
584 mask >> IOMMU_PAGE_SHIFT, 0); 595 mask >> IOMMU_PAGE_SHIFT, align);
585 if (dma_handle == DMA_ERROR_CODE) { 596 if (dma_handle == DMA_ERROR_CODE) {
586 if (printk_ratelimit()) { 597 if (printk_ratelimit()) {
587 printk(KERN_INFO "iommu_alloc failed, " 598 printk(KERN_INFO "iommu_alloc failed, "
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index a282bc212e80..50d7372bc2ce 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -82,14 +82,6 @@ static inline void slb_shadow_clear(unsigned long entry)
82 get_slb_shadow()->save_area[entry].esid = 0; 82 get_slb_shadow()->save_area[entry].esid = 0;
83} 83}
84 84
85void slb_shadow_clear_all(void)
86{
87 int i;
88
89 for (i = 0; i < SLB_NUM_BOLTED; i++)
90 slb_shadow_clear(i);
91}
92
93static inline void create_shadowed_slbe(unsigned long ea, int ssize, 85static inline void create_shadowed_slbe(unsigned long ea, int ssize,
94 unsigned long flags, 86 unsigned long flags,
95 unsigned long entry) 87 unsigned long entry)
@@ -300,6 +292,8 @@ void slb_initialize(void)
300 292
301 create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1); 293 create_shadowed_slbe(VMALLOC_START, mmu_kernel_ssize, vflags, 1);
302 294
295 slb_shadow_clear(2);
296
303 /* We don't bolt the stack for the time being - we're in boot, 297 /* We don't bolt the stack for the time being - we're in boot,
304 * so the stack is in the bolted segment. By the time it goes 298 * so the stack is in the bolted segment. By the time it goes
305 * elsewhere, we'll call _switch() which will bolt in the new 299 * elsewhere, we'll call _switch() which will bolt in the new
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 34317aa148a8..9a455d46379d 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -272,7 +272,6 @@ void vpa_init(int cpu)
272 */ 272 */
273 addr = __pa(&slb_shadow[cpu]); 273 addr = __pa(&slb_shadow[cpu]);
274 if (firmware_has_feature(FW_FEATURE_SPLPAR)) { 274 if (firmware_has_feature(FW_FEATURE_SPLPAR)) {
275 slb_shadow_clear_all();
276 ret = register_slb_shadow(hwcpu, addr); 275 ret = register_slb_shadow(hwcpu, addr);
277 if (ret) 276 if (ret)
278 printk(KERN_ERR 277 printk(KERN_ERR
diff --git a/include/asm-powerpc/mmu-hash64.h b/include/asm-powerpc/mmu-hash64.h
index 951e2487aa69..82328dec2b52 100644
--- a/include/asm-powerpc/mmu-hash64.h
+++ b/include/asm-powerpc/mmu-hash64.h
@@ -286,7 +286,6 @@ extern void hpte_init_iSeries(void);
286extern void hpte_init_beat(void); 286extern void hpte_init_beat(void);
287extern void hpte_init_beat_v3(void); 287extern void hpte_init_beat_v3(void);
288 288
289extern void slb_shadow_clear_all(void);
290extern void stabs_alloc(void); 289extern void stabs_alloc(void);
291extern void slb_initialize(void); 290extern void slb_initialize(void);
292extern void slb_flush_and_rebolt(void); 291extern void slb_flush_and_rebolt(void);