|
@@ -458,6 +458,42 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
|
|
|
spin_unlock_irqrestore(&(tbl->it_lock), flags);
|
|
|
}
|
|
|
|
|
|
+static void iommu_table_clear(struct iommu_table *tbl)
|
|
|
+{
|
|
|
+ if (!__kdump_flag) {
|
|
|
+ /* Clear the table in case firmware left allocations in it */
|
|
|
+ ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+#ifdef CONFIG_CRASH_DUMP
|
|
|
+ if (ppc_md.tce_get) {
|
|
|
+ unsigned long index, tceval, tcecount = 0;
|
|
|
+
|
|
|
+ /* Reserve the existing mappings left by the first kernel. */
|
|
|
+ for (index = 0; index < tbl->it_size; index++) {
|
|
|
+ tceval = ppc_md.tce_get(tbl, index + tbl->it_offset);
|
|
|
+ /*
|
|
|
+ * Freed TCE entry contains 0x7fffffffffffffff on JS20
|
|
|
+ */
|
|
|
+ if (tceval && (tceval != 0x7fffffffffffffffUL)) {
|
|
|
+ __set_bit(index, tbl->it_map);
|
|
|
+ tcecount++;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) {
|
|
|
+ printk(KERN_WARNING "TCE table is full; freeing ");
|
|
|
+ printk(KERN_WARNING "%d entries for the kdump boot\n",
|
|
|
+ KDUMP_MIN_TCE_ENTRIES);
|
|
|
+ for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES;
|
|
|
+ index < tbl->it_size; index++)
|
|
|
+ __clear_bit(index, tbl->it_map);
|
|
|
+ }
|
|
|
+ }
|
|
|
+#endif
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Build a iommu_table structure. This contains a bit map which
|
|
|
* 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)
|
|
|
tbl->it_largehint = tbl->it_halfpoint;
|
|
|
spin_lock_init(&tbl->it_lock);
|
|
|
|
|
|
-#ifdef CONFIG_CRASH_DUMP
|
|
|
- if (ppc_md.tce_get) {
|
|
|
- unsigned long index;
|
|
|
- unsigned long tceval;
|
|
|
- unsigned long tcecount = 0;
|
|
|
-
|
|
|
- /*
|
|
|
- * Reserve the existing mappings left by the first kernel.
|
|
|
- */
|
|
|
- for (index = 0; index < tbl->it_size; index++) {
|
|
|
- tceval = ppc_md.tce_get(tbl, index + tbl->it_offset);
|
|
|
- /*
|
|
|
- * Freed TCE entry contains 0x7fffffffffffffff on JS20
|
|
|
- */
|
|
|
- if (tceval && (tceval != 0x7fffffffffffffffUL)) {
|
|
|
- __set_bit(index, tbl->it_map);
|
|
|
- tcecount++;
|
|
|
- }
|
|
|
- }
|
|
|
- if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) {
|
|
|
- printk(KERN_WARNING "TCE table is full; ");
|
|
|
- printk(KERN_WARNING "freeing %d entries for the kdump boot\n",
|
|
|
- KDUMP_MIN_TCE_ENTRIES);
|
|
|
- for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES;
|
|
|
- index < tbl->it_size; index++)
|
|
|
- __clear_bit(index, tbl->it_map);
|
|
|
- }
|
|
|
- }
|
|
|
-#else
|
|
|
- /* Clear the hardware table in case firmware left allocations in it */
|
|
|
- ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size);
|
|
|
-#endif
|
|
|
+ iommu_table_clear(tbl);
|
|
|
|
|
|
if (!welcomed) {
|
|
|
printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n",
|