On 05/11/15 at 05:52pm, Li, Zhen-Hua wrote:
> Populate it with support functions to copy iommu translation tables from
> from the panicked kernel into the kdump kernel in the event of a crash.
> 
> Functions:
>     Use old root entry table, and load the old data to root_entry as cache.
>     Malloc new context table and copy old context table to the new one.
> 
> Bill Sumner:
>     Original version, the creation of the data types and functions.
> 
> Li, Zhenhua:
>     Create new function iommu_check_pre_te_status() to check status.
>     Update the caller of context_get_* and context_put*, use context_*
>         and context_set_* for replacement.
>     Update the name of the function that loads root entry table.
>     Use new function to copy old context entry tables and page tables.
>     Use "unsigned long" for physical address.
>     Remove the functions to copy page table in Bill's version.
>     Remove usage of dve and ppap in Bill's version.
> 
> Signed-off-by: Bill Sumner <billsumnerli...@gmail.com>
> Signed-off-by: Li, Zhen-Hua <zhen-h...@hp.com>
> ---
>  drivers/iommu/intel-iommu.c | 121 
> ++++++++++++++++++++++++++++++++++++++++++++
>  include/linux/intel-iommu.h |   3 ++
>  2 files changed, 124 insertions(+)
> 
> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c
> index 3a5d446..28c3c64 100644
> --- a/drivers/iommu/intel-iommu.c
> +++ b/drivers/iommu/intel-iommu.c
> @@ -386,6 +386,18 @@ struct iommu_remapped_entry {
>  static LIST_HEAD(__iommu_remapped_mem);
>  static DEFINE_MUTEX(__iommu_mem_list_lock);
>  
> +/* ========================================================================
> + * Copy iommu translation tables from old kernel into new  kernel.
> + * Entry to this set of functions is: intel_iommu_load_translation_tables()
> + * ------------------------------------------------------------------------
> + */
> +
> +static int copy_root_entry_table(struct intel_iommu *iommu);
> +
> +static int intel_iommu_load_translation_tables(struct intel_iommu *iommu);
> +
> +static void iommu_check_pre_te_status(struct intel_iommu *iommu);
> +
>  /*
>   * This domain is a statically identity mapping domain.
>   *   1. This domain creats a static 1:1 mapping to all usable memory.
> @@ -4987,3 +4999,112 @@ static void __iommu_update_old_root_entry(struct 
> intel_iommu *iommu, int index)
>       __iommu_flush_cache(iommu, to + start, size);
>  }
>  
> +/*
> + * Load root entry tables from old kernel.
> + */
> +static int copy_root_entry_table(struct intel_iommu *iommu)
> +{
> +     u32 bus;                                /* Index: root-entry-table */
> +     struct root_entry  *re;                 /* Virt(iterator: new table) */
> +     unsigned long context_old_phys;         /* Phys(context table entry) */
> +     struct context_entry *context_new_virt; /* Virt(new context_entry) */
> +
> +     /*
> +      * A new root entry table has been allocated ,
> +      * we need copy re from old kernel to the new allocated one.
> +      */
> +
> +     if (!iommu->root_entry_old_phys)
> +             return -ENOMEM;
> +
> +     for (bus = 0, re = iommu->root_entry; bus < 256; bus += 1, re += 1) {
> +             if (!root_present(re))
> +                     continue;
> +
> +             context_old_phys = get_context_phys_from_root(re);
> +
> +             if (!context_old_phys)
> +                     continue;
> +
> +             context_new_virt =
> +                     (struct context_entry *)alloc_pgtable_page(iommu->node);
> +
> +             if (!context_new_virt)
> +                     return -ENOMEM;
> +
> +             __iommu_load_from_oldmem(context_new_virt,
> +                                     context_old_phys,
> +                                     VTD_PAGE_SIZE);
> +
> +             __iommu_flush_cache(iommu, context_new_virt, VTD_PAGE_SIZE);
> +
> +             set_root_value(re, virt_to_phys(context_new_virt));
> +     }
> +
> +     return 0;
> +}
> +
> +/*
> + * Interface to the "load translation tables" set of functions
> + * from mainline code.
> + */
> +static int intel_iommu_load_translation_tables(struct intel_iommu *iommu)
> +{
> +     unsigned long long q;           /* quadword scratch */
> +     int ret = 0;                    /* Integer return code */
> +     unsigned long flags;
> +
> +     q = dmar_readq(iommu->reg + DMAR_RTADDR_REG);
> +     if (!q)
> +             return -1;
> +
> +     spin_lock_irqsave(&iommu->lock, flags);
> +
> +     /* Load the root-entry table from the old kernel
> +      * foreach context_entry_table in root_entry
> +      *   Copy each entry table from old kernel
> +      */
> +     if (!iommu->root_entry) {
> +             iommu->root_entry =
> +                     (struct root_entry *)alloc_pgtable_page(iommu->node);
> +             if (!iommu->root_entry) {
> +                     spin_unlock_irqrestore(&iommu->lock, flags);
> +                     return -ENOMEM;
> +             }
> +     }
> +
> +     iommu->root_entry_old_phys = q & VTD_PAGE_MASK;
> +     if (!iommu->root_entry_old_phys) {
> +             pr_err("Could not read old root entry address.");
> +             return -1;
> +     }
> +

I didn't find where you call iounmap to free mapping of
iommu->root_entry_old_phys. Am I missing anything?

> +     iommu->root_entry_old_virt = ioremap_cache(iommu->root_entry_old_phys,
> +                                             VTD_PAGE_SIZE);
> +     if (!iommu->root_entry_old_virt) {
> +             pr_err("Could not map the old root entry.");
> +             return -ENOMEM;
> +     }
_______________________________________________
iommu mailing list
iommu@lists.linux-foundation.org
https://lists.linuxfoundation.org/mailman/listinfo/iommu

Reply via email to