From patchwork Mon Jan 12 07:06:22 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Li, Zhen-Hua" X-Patchwork-Id: 5608541 X-Patchwork-Delegate: bhelgaas@google.com Return-Path: X-Original-To: patchwork-linux-pci@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id AF1FAC058D for ; Mon, 12 Jan 2015 07:11:40 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BE5592063A for ; Mon, 12 Jan 2015 07:11:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id A229820605 for ; Mon, 12 Jan 2015 07:11:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751776AbbALHId (ORCPT ); Mon, 12 Jan 2015 02:08:33 -0500 Received: from g4t3426.houston.hp.com ([15.201.208.54]:39411 "EHLO g4t3426.houston.hp.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751774AbbALHIa (ORCPT ); Mon, 12 Jan 2015 02:08:30 -0500 Received: from g4t3433.houston.hp.com (g4t3433.houston.hp.com [16.210.25.219]) by g4t3426.houston.hp.com (Postfix) with ESMTP id DAD6162; Mon, 12 Jan 2015 07:08:29 +0000 (UTC) Received: from piepie.asiapacific.hpqcorp.net (piepie.asiapacific.hpqcorp.net [16.187.245.10]) by g4t3433.houston.hp.com (Postfix) with ESMTP id A13D3BE; Mon, 12 Jan 2015 07:08:24 +0000 (UTC) From: "Li, Zhen-Hua" To: , , , , , Cc: , , , , , , , , , , , , , , , Subject: [PATCH v8 04/10] iommu/vt-d: functions to copy data from old mem Date: Mon, 12 Jan 2015 15:06:22 +0800 Message-Id: <1421046388-27925-5-git-send-email-zhen-hual@hp.com> X-Mailer: git-send-email 2.0.0-rc0 In-Reply-To: <1421046388-27925-1-git-send-email-zhen-hual@hp.com> References: <1421046388-27925-1-git-send-email-zhen-hual@hp.com> Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, T_RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add some functions to copy the data from old kernel. These functions are used to copy context tables and page tables. To avoid calling iounmap between spin_lock_irqsave and spin_unlock_irqrestore, use a link here, store the pointers , and then use iounmap to free them in another place. Li, Zhen-hua: The functions and logics. Takao Indoh: Check if pfn is ram: if (page_is_ram(pfn)) Signed-off-by: Li, Zhen-Hua Signed-off-by: Takao Indoh --- drivers/iommu/intel-iommu.c | 97 +++++++++++++++++++++++++++++++++++++++++++++ include/linux/intel-iommu.h | 9 +++++ 2 files changed, 106 insertions(+) diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c index c594b2c..2335831 100644 --- a/drivers/iommu/intel-iommu.c +++ b/drivers/iommu/intel-iommu.c @@ -388,6 +388,13 @@ static int intel_iommu_get_dids_from_old_kernel(struct intel_iommu *iommu); static int device_to_domain_id(struct intel_iommu *iommu, u8 bus, u8 devfn); +struct iommu_remapped_entry { + struct list_head list; + void __iomem *mem; +}; +static LIST_HEAD(__iommu_remapped_mem); +static DEFINE_MUTEX(__iommu_mem_list_lock); + #endif /* CONFIG_CRASH_DUMP */ /* @@ -4839,6 +4846,96 @@ static void __init check_tylersburg_isoch(void) #ifdef CONFIG_CRASH_DUMP /* + * Copy memory from a physically-addressed area into a virtually-addressed area + */ +int __iommu_load_from_oldmem(void *to, unsigned long from, unsigned long size) +{ + unsigned long pfn; /* Page Frame Number */ + size_t csize = (size_t)size; /* Num(bytes to copy) */ + unsigned long offset; /* Lower 12 bits of to */ + void __iomem *virt_mem; + struct iommu_remapped_entry *mapped; + + pfn = from >> VTD_PAGE_SHIFT; + offset = from & (~VTD_PAGE_MASK); + + if (page_is_ram(pfn)) { + memcpy(to, pfn_to_kaddr(pfn) + offset, csize); + } else{ + + mapped = kzalloc(sizeof(struct iommu_remapped_entry), + GFP_KERNEL); + if (!mapped) + return -ENOMEM; + + virt_mem = ioremap_cache((unsigned long)from, size); + if (!virt_mem) { + kfree(mapped); + return -ENOMEM; + } + memcpy(to, virt_mem, size); + + mutex_lock(&__iommu_mem_list_lock); + mapped->mem = virt_mem; + list_add_tail(&mapped->list, &__iommu_remapped_mem); + mutex_unlock(&__iommu_mem_list_lock); + } + return size; +} + +/* + * Copy memory from a virtually-addressed area into a physically-addressed area + */ +int __iommu_save_to_oldmem(unsigned long to, void *from, unsigned long size) +{ + unsigned long pfn; /* Page Frame Number */ + size_t csize = (size_t)size; /* Num(bytes to copy) */ + unsigned long offset; /* Lower 12 bits of to */ + void __iomem *virt_mem; + struct iommu_remapped_entry *mapped; + + pfn = to >> VTD_PAGE_SHIFT; + offset = to & (~VTD_PAGE_MASK); + + if (page_is_ram(pfn)) { + memcpy(pfn_to_kaddr(pfn) + offset, from, csize); + } else{ + mapped = kzalloc(sizeof(struct iommu_remapped_entry), + GFP_KERNEL); + if (!mapped) + return -ENOMEM; + + virt_mem = ioremap_cache((unsigned long)to, size); + if (!virt_mem) { + kfree(mapped); + return -ENOMEM; + } + memcpy(virt_mem, from, size); + mutex_lock(&__iommu_mem_list_lock); + mapped->mem = virt_mem; + list_add_tail(&mapped->list, &__iommu_remapped_mem); + mutex_unlock(&__iommu_mem_list_lock); + } + return size; +} + +/* + * Free the mapped memory for ioremap; + */ +int __iommu_free_mapped_mem(void) +{ + struct iommu_remapped_entry *mem_entry, *tmp; + + mutex_lock(&__iommu_mem_list_lock); + list_for_each_entry_safe(mem_entry, tmp, &__iommu_remapped_mem, list) { + iounmap(mem_entry->mem); + list_del(&mem_entry->list); + kfree(mem_entry); + } + mutex_unlock(&__iommu_mem_list_lock); + return 0; +} +/* * Interfaces for when a new domain in the crashdump kernel needs some * values from the panicked kernel's context entries * diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h index a65208a..8ffa523 100644 --- a/include/linux/intel-iommu.h +++ b/include/linux/intel-iommu.h @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -368,4 +369,12 @@ extern int dmar_ir_support(void); extern const struct attribute_group *intel_iommu_groups[]; +#ifdef CONFIG_CRASH_DUMP +extern int __iommu_load_from_oldmem(void *to, unsigned long from, + unsigned long size); +extern int __iommu_save_to_oldmem(unsigned long to, void *from, + unsigned long size); +extern int __iommu_free_mapped_mem(void); +#endif /* CONFIG_CRASH_DUMP */ + #endif