From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from g1t5425.austin.hp.com ([15.216.225.55]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YvFHw-00075O-FK for kexec@lists.infradead.org; Thu, 21 May 2015 01:28:45 +0000 Message-ID: <555D3470.7060902@hp.com> Date: Thu, 21 May 2015 09:27:12 +0800 From: "Li, ZhenHua" MIME-Version: 1.0 Subject: Re: [PATCH v11 08/10] iommu/vt-d: assign new page table for dma_map References: <1431337974-545-1-git-send-email-zhen-hual@hp.com> <1431337974-545-9-git-send-email-zhen-hual@hp.com> <20150520235242.GA2342@dhcp-17-102.nay.redhat.com> In-Reply-To: <20150520235242.GA2342@dhcp-17-102.nay.redhat.com> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: 7bit Content-Type: text/plain; charset="us-ascii"; Format="flowed" Sender: "kexec" Errors-To: kexec-bounces+dwmw2=infradead.org@lists.infradead.org To: Baoquan He Cc: alex.williamson@redhat.com, indou.takao@jp.fujitsu.com, tom.vaden@hp.com, rwright@hp.com, dwmw2@infradead.org, joro@8bytes.org, kexec@lists.infradead.org, linux-kernel@vger.kernel.org, lisa.mitchell@hp.com, jerry.hoemann@hp.com, iommu@lists.linux-foundation.org, "Li, ZhenHua" , ddutile@redhat.com, doug.hatch@hp.com, ishii.hironobu@jp.fujitsu.com, linux-pci@vger.kernel.org, bhelgaas@google.com, billsumnerlinux@gmail.com, li.zhang6@hp.com, dyoung@redhat.com, vgoyal@redhat.com Hi Baoquan, In the early version of this patchset, old page tables are used by new kernel. But as discussed, we need to make kernel use new pages when there is a new dma request , so we need to unmap the pages which were mapped in old kernel, and this is what this patch does. Thanks Zhenhua On 05/21/2015 07:52 AM, Baoquan He wrote: > On 05/11/15 at 05:52pm, Li, Zhen-Hua wrote: >> When a device driver issues the first dma_map command for a device, we >> assign a new and empty page-table, thus removing all mappings from the >> old kernel for the device. > > Hi Zhenhua, > > From your patch I got it will remove all mappings, assign a new > page-table. But I didn't got why you stress an empty page-table. Did I > miss anything? > > Thanks > Baoquan > >> >> Signed-off-by: Li, Zhen-Hua >> --- >> drivers/iommu/intel-iommu.c | 58 ++++++++++++++++++++++++++++++++++++++------- >> 1 file changed, 50 insertions(+), 8 deletions(-) >> >> diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c >> index 91545bf..3cc1027 100644 >> --- a/drivers/iommu/intel-iommu.c >> +++ b/drivers/iommu/intel-iommu.c >> @@ -396,6 +396,9 @@ static int copy_root_entry_table(struct intel_iommu *iommu); >> >> static int intel_iommu_load_translation_tables(struct intel_iommu *iommu); >> >> +static void unmap_device_dma(struct dmar_domain *domain, >> + struct device *dev, >> + struct intel_iommu *iommu); >> static void iommu_check_pre_te_status(struct intel_iommu *iommu); >> static u8 g_translation_pre_enabled; >> >> @@ -3115,6 +3118,7 @@ static struct iova *intel_alloc_iova(struct device *dev, >> static struct dmar_domain *__get_valid_domain_for_dev(struct device *dev) >> { >> struct dmar_domain *domain; >> + struct intel_iommu *iommu; >> int ret; >> >> domain = get_domain_for_dev(dev, DEFAULT_DOMAIN_ADDRESS_WIDTH); >> @@ -3124,14 +3128,30 @@ static struct dmar_domain *__get_valid_domain_for_dev(struct device *dev) >> return NULL; >> } >> >> - /* make sure context mapping is ok */ >> - if (unlikely(!domain_context_mapped(dev))) { >> - ret = domain_context_mapping(domain, dev, CONTEXT_TT_MULTI_LEVEL); >> - if (ret) { >> - printk(KERN_ERR "Domain context map for %s failed", >> - dev_name(dev)); >> - return NULL; >> - } >> + /* if in kdump kernel, we need to unmap the mapped dma pages, >> + * detach this device first. >> + */ >> + if (likely(domain_context_mapped(dev))) { >> + iommu = domain_get_iommu(domain); >> + if (iommu->pre_enabled_trans) { >> + unmap_device_dma(domain, dev, iommu); >> + >> + domain = get_domain_for_dev(dev, >> + DEFAULT_DOMAIN_ADDRESS_WIDTH); >> + if (!domain) { >> + pr_err("Allocating domain for %s failed", >> + dev_name(dev)); >> + return NULL; >> + } >> + } else >> + return domain; >> + } >> + >> + ret = domain_context_mapping(domain, dev, CONTEXT_TT_MULTI_LEVEL); >> + if (ret) { >> + pr_err("Domain context map for %s failed", >> + dev_name(dev)); >> + return NULL; >> } >> >> return domain; >> @@ -5168,6 +5188,28 @@ static int intel_iommu_load_translation_tables(struct intel_iommu *iommu) >> return ret; >> } >> >> +static void unmap_device_dma(struct dmar_domain *domain, >> + struct device *dev, >> + struct intel_iommu *iommu) >> +{ >> + struct context_entry *ce; >> + struct iova *iova; >> + phys_addr_t phys_addr; >> + dma_addr_t dev_addr; >> + struct pci_dev *pdev; >> + >> + pdev = to_pci_dev(dev); >> + ce = iommu_context_addr(iommu, pdev->bus->number, pdev->devfn, 1); >> + phys_addr = context_address_root(ce) << VTD_PAGE_SHIFT; >> + dev_addr = phys_to_dma(dev, phys_addr); >> + >> + iova = find_iova(&domain->iovad, IOVA_PFN(dev_addr)); >> + if (iova) >> + intel_unmap(dev, dev_addr); >> + >> + domain_remove_one_dev_info(domain, dev); >> +} >> + >> static void iommu_check_pre_te_status(struct intel_iommu *iommu) >> { >> u32 sts; >> -- >> 2.0.0-rc0 >> _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec