From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752326AbbEGHuH (ORCPT ); Thu, 7 May 2015 03:50:07 -0400 Received: from mx1.redhat.com ([209.132.183.28]:40417 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752310AbbEGHuB (ORCPT ); Thu, 7 May 2015 03:50:01 -0400 Date: Thu, 7 May 2015 15:49:16 +0800 From: Baoquan He To: "Li, Zhen-Hua" Cc: dwmw2@infradead.org, indou.takao@jp.fujitsu.com, joro@8bytes.org, vgoyal@redhat.com, dyoung@redhat.com, iommu@lists.linux-foundation.org, linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org, kexec@lists.infradead.org, alex.williamson@redhat.com, ddutile@redhat.com, ishii.hironobu@jp.fujitsu.com, bhelgaas@google.com, doug.hatch@hp.com, jerry.hoemann@hp.com, tom.vaden@hp.com, li.zhang6@hp.com, lisa.mitchell@hp.com, billsumnerlinux@gmail.com, rwright@hp.com Subject: Re: [PATCH v10 04/10] iommu/vt-d: functions to copy data from old mem Message-ID: <20150507074916.GA16815@dhcp-16-116.nay.redhat.com> References: <1428655333-19504-1-git-send-email-zhen-hual@hp.com> <1428655333-19504-5-git-send-email-zhen-hual@hp.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1428655333-19504-5-git-send-email-zhen-hual@hp.com> User-Agent: Mutt/1.5.21 (2010-09-15) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 04/10/15 at 04:42pm, Li, Zhen-Hua wrote: > 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 | 102 ++++++++++++++++++++++++++++++++++++++++++++ > include/linux/intel-iommu.h | 6 +++ > 2 files changed, 108 insertions(+) > > diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c > index ff5ac04..5ba403a 100644 > --- a/drivers/iommu/intel-iommu.c > +++ b/drivers/iommu/intel-iommu.c > @@ -373,6 +373,17 @@ static struct context_entry *device_to_existing_context_entry( > struct intel_iommu *iommu, > u8 bus, u8 devfn); > > +/* > + * A structure used to store the address allocated by ioremap(); > + * The we need to call iounmap() to free them out of spin_lock_irqsave/unlock; > + */ > +struct iommu_remapped_entry { > + struct list_head list; > + void __iomem *mem; > +}; > +static LIST_HEAD(__iommu_remapped_mem); > +static DEFINE_MUTEX(__iommu_mem_list_lock); > + > > /* > * This domain is a statically identity mapping domain. > @@ -4817,3 +4828,94 @@ static struct context_entry *device_to_existing_context_entry( > return ret; > } > > +/* > + * Copy memory from a physically-addressed area into a virtually-addressed area > + */ I don't find where __iommu_load_from_oldmem is called. Obsolete code of this patch? > +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; > +} > + > diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h > index a65208a..4bca7b5 100644 > --- a/include/linux/intel-iommu.h > +++ b/include/linux/intel-iommu.h > @@ -368,4 +368,10 @@ extern int dmar_ir_support(void); > > extern const struct attribute_group *intel_iommu_groups[]; > > +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 > -- > 2.0.0-rc0 > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-path: Received: from mx1.redhat.com ([209.132.183.28]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1YqGZD-0007S7-0W for kexec@lists.infradead.org; Thu, 07 May 2015 07:49:59 +0000 Date: Thu, 7 May 2015 15:49:16 +0800 From: Baoquan He Subject: Re: [PATCH v10 04/10] iommu/vt-d: functions to copy data from old mem Message-ID: <20150507074916.GA16815@dhcp-16-116.nay.redhat.com> References: <1428655333-19504-1-git-send-email-zhen-hual@hp.com> <1428655333-19504-5-git-send-email-zhen-hual@hp.com> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <1428655333-19504-5-git-send-email-zhen-hual@hp.com> List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "kexec" Errors-To: kexec-bounces+dwmw2=infradead.org@lists.infradead.org To: "Li, Zhen-Hua" 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, 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 On 04/10/15 at 04:42pm, Li, Zhen-Hua wrote: > 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 | 102 ++++++++++++++++++++++++++++++++++++++++++++ > include/linux/intel-iommu.h | 6 +++ > 2 files changed, 108 insertions(+) > > diff --git a/drivers/iommu/intel-iommu.c b/drivers/iommu/intel-iommu.c > index ff5ac04..5ba403a 100644 > --- a/drivers/iommu/intel-iommu.c > +++ b/drivers/iommu/intel-iommu.c > @@ -373,6 +373,17 @@ static struct context_entry *device_to_existing_context_entry( > struct intel_iommu *iommu, > u8 bus, u8 devfn); > > +/* > + * A structure used to store the address allocated by ioremap(); > + * The we need to call iounmap() to free them out of spin_lock_irqsave/unlock; > + */ > +struct iommu_remapped_entry { > + struct list_head list; > + void __iomem *mem; > +}; > +static LIST_HEAD(__iommu_remapped_mem); > +static DEFINE_MUTEX(__iommu_mem_list_lock); > + > > /* > * This domain is a statically identity mapping domain. > @@ -4817,3 +4828,94 @@ static struct context_entry *device_to_existing_context_entry( > return ret; > } > > +/* > + * Copy memory from a physically-addressed area into a virtually-addressed area > + */ I don't find where __iommu_load_from_oldmem is called. Obsolete code of this patch? > +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; > +} > + > diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h > index a65208a..4bca7b5 100644 > --- a/include/linux/intel-iommu.h > +++ b/include/linux/intel-iommu.h > @@ -368,4 +368,10 @@ extern int dmar_ir_support(void); > > extern const struct attribute_group *intel_iommu_groups[]; > > +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 > -- > 2.0.0-rc0 > _______________________________________________ kexec mailing list kexec@lists.infradead.org http://lists.infradead.org/mailman/listinfo/kexec