aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/kernel/iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/kernel/iommu.c')
-rw-r--r--arch/powerpc/kernel/iommu.c69
1 files changed, 37 insertions, 32 deletions
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index ea1ba89f9c90..3857d7e2af0c 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -458,6 +458,42 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
458 spin_unlock_irqrestore(&(tbl->it_lock), flags); 458 spin_unlock_irqrestore(&(tbl->it_lock), flags);
459} 459}
460 460
461static void iommu_table_clear(struct iommu_table *tbl)
462{
463 if (!__kdump_flag) {
464 /* Clear the table in case firmware left allocations in it */
465 ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
466 return;
467 }
468
469#ifdef CONFIG_CRASH_DUMP
470 if (ppc_md.tce_get) {
471 unsigned long index, tceval, tcecount = 0;
472
473 /* Reserve the existing mappings left by the first kernel. */
474 for (index = 0; index < tbl->it_size; index++) {
475 tceval = ppc_md.tce_get(tbl, index + tbl->it_offset);
476 /*
477 * Freed TCE entry contains 0x7fffffffffffffff on JS20
478 */
479 if (tceval && (tceval != 0x7fffffffffffffffUL)) {
480 __set_bit(index, tbl->it_map);
481 tcecount++;
482 }
483 }
484
485 if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) {
486 printk(KERN_WARNING "TCE table is full; freeing ");
487 printk(KERN_WARNING "%d entries for the kdump boot\n",
488 KDUMP_MIN_TCE_ENTRIES);
489 for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES;
490 index < tbl->it_size; index++)
491 __clear_bit(index, tbl->it_map);
492 }
493 }
494#endif
495}
496
461/* 497/*
462 * Build a iommu_table structure. This contains a bit map which 498 * Build a iommu_table structure. This contains a bit map which
463 * is used to manage allocation of the tce space. 499 * is used to manage allocation of the tce space.
@@ -484,38 +520,7 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid)
484 tbl->it_largehint = tbl->it_halfpoint; 520 tbl->it_largehint = tbl->it_halfpoint;
485 spin_lock_init(&tbl->it_lock); 521 spin_lock_init(&tbl->it_lock);
486 522
487#ifdef CONFIG_CRASH_DUMP 523 iommu_table_clear(tbl);
488 if (ppc_md.tce_get) {
489 unsigned long index;
490 unsigned long tceval;
491 unsigned long tcecount = 0;
492
493 /*
494 * Reserve the existing mappings left by the first kernel.
495 */
496 for (index = 0; index < tbl->it_size; index++) {
497 tceval = ppc_md.tce_get(tbl, index + tbl->it_offset);
498 /*
499 * Freed TCE entry contains 0x7fffffffffffffff on JS20
500 */
501 if (tceval && (tceval != 0x7fffffffffffffffUL)) {
502 __set_bit(index, tbl->it_map);
503 tcecount++;
504 }
505 }
506 if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) {
507 printk(KERN_WARNING "TCE table is full; ");
508 printk(KERN_WARNING "freeing %d entries for the kdump boot\n",
509 KDUMP_MIN_TCE_ENTRIES);
510 for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES;
511 index < tbl->it_size; index++)
512 __clear_bit(index, tbl->it_map);
513 }
514 }
515#else
516 /* Clear the hardware table in case firmware left allocations in it */
517 ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
518#endif
519 524
520 if (!welcomed) { 525 if (!welcomed) {
521 printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", 526 printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",