From: Yijing Wang <wangyijing-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
To: Jiang Liu <jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>,
Yinghai Lu <yinghai-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>,
Joerg Roedel <joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org>,
David Woodhouse <dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org>,
Dan Williams
<dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
Vinod Koul <vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>,
Ashok Raj <ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org>
Cc: dmaengine-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: Re: [Patch Part1 V2 01/17] iommu/vt-d: use dedicated bitmap to track remapping entry allocation status
Date: Mon, 2 Dec 2013 09:38:26 +0800 [thread overview]
Message-ID: <529BE492.5020201@huawei.com> (raw)
In-Reply-To: <1385715030-20553-2-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Tested-and-reviewed-by: Yijing Wang <wangyijing-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
On 2013/11/29 16:50, Jiang Liu wrote:
> Currently Intel interrupt remapping drivers uses the "present" flag bit
> in remapping entry to track whether an entry is allocated or not.
> It works as follow:
> 1) allocate a remapping entry and set its "present" flag bit to 1
> 2) compose other fields for the entry
> 3) update the remapping entry with the composed value
>
> The remapping hardware may access the entry between step 1 and step 3,
> which then obervers an entry with the "present" flag set but random
> values in all other fields.
>
> This patch introduces a dedicated bitmap to track remapping entry
> allocation status instead of sharing the "present" flag with hardware,
> thus eliminate the race window. It also simplifies the implementation.
>
> Signed-off-by: Jiang Liu <jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> ---
> drivers/iommu/intel_irq_remapping.c | 51 +++++++++++++++++------------------
> include/linux/intel-iommu.h | 1 +
> 2 files changed, 25 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
> index bab10b1..282d392 100644
> --- a/drivers/iommu/intel_irq_remapping.c
> +++ b/drivers/iommu/intel_irq_remapping.c
> @@ -72,7 +72,6 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
> u16 index, start_index;
> unsigned int mask = 0;
> unsigned long flags;
> - int i;
>
> if (!count || !irq_iommu)
> return -1;
> @@ -96,32 +95,17 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
> }
>
> raw_spin_lock_irqsave(&irq_2_ir_lock, flags);
> - do {
> - for (i = index; i < index + count; i++)
> - if (table->base[i].present)
> - break;
> - /* empty index found */
> - if (i == index + count)
> - break;
> -
> - index = (index + count) % INTR_REMAP_TABLE_ENTRIES;
> -
> - if (index == start_index) {
> - raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
> - printk(KERN_ERR "can't allocate an IRTE\n");
> - return -1;
> - }
> - } while (1);
> -
> - for (i = index; i < index + count; i++)
> - table->base[i].present = 1;
> -
> - cfg->remapped = 1;
> - irq_iommu->iommu = iommu;
> - irq_iommu->irte_index = index;
> - irq_iommu->sub_handle = 0;
> - irq_iommu->irte_mask = mask;
> -
> + index = bitmap_find_free_region(table->bitmap,
> + INTR_REMAP_TABLE_ENTRIES, mask);
> + if (index < 0) {
> + printk(KERN_ERR "can't allocate an IRTE\n");
> + } else {
> + cfg->remapped = 1;
> + irq_iommu->iommu = iommu;
> + irq_iommu->irte_index = index;
> + irq_iommu->sub_handle = 0;
> + irq_iommu->irte_mask = mask;
> + }
> raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
>
> return index;
> @@ -254,6 +238,8 @@ static int clear_entries(struct irq_2_iommu *irq_iommu)
> set_64bit(&entry->low, 0);
> set_64bit(&entry->high, 0);
> }
> + bitmap_release_region(iommu->ir_table->bitmap, index,
> + irq_iommu->irte_mask);
>
> return qi_flush_iec(iommu, index, irq_iommu->irte_mask);
> }
> @@ -453,6 +439,7 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode)
> {
> struct ir_table *ir_table;
> struct page *pages;
> + unsigned long *bitmap;
>
> ir_table = iommu->ir_table = kzalloc(sizeof(struct ir_table),
> GFP_ATOMIC);
> @@ -470,7 +457,17 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode)
> return -ENOMEM;
> }
>
> + bitmap = kcalloc(BITS_TO_LONGS(INTR_REMAP_TABLE_ENTRIES),
> + sizeof(long), GFP_ATOMIC);
> + if (bitmap == NULL) {
> + printk(KERN_ERR "failed to allocate bitmap\n");
> + __free_pages(pages, INTR_REMAP_PAGE_ORDER);
> + kfree(ir_table);
> + return -ENOMEM;
> + }
> +
> ir_table->base = page_address(pages);
> + ir_table->bitmap = bitmap;
>
> iommu_set_irq_remapping(iommu, mode);
> return 0;
> diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
> index d380c5e..de1e5e9 100644
> --- a/include/linux/intel-iommu.h
> +++ b/include/linux/intel-iommu.h
> @@ -288,6 +288,7 @@ struct q_inval {
>
> struct ir_table {
> struct irte *base;
> + unsigned long *bitmap;
> };
> #endif
>
>
--
Thanks!
Yijing
WARNING: multiple messages have this Message-ID (diff)
From: Yijing Wang <wangyijing@huawei.com>
To: Jiang Liu <jiang.liu@linux.intel.com>,
Yinghai Lu <yinghai@kernel.org>, Joerg Roedel <joro@8bytes.org>,
David Woodhouse <dwmw2@infradead.org>,
"Dan Williams" <dan.j.williams@intel.com>,
Vinod Koul <vinod.koul@intel.com>,
Ashok Raj <ashok.raj@intel.com>
Cc: <iommu@lists.linux-foundation.org>, <linux-pci@vger.kernel.org>,
<linux-kernel@vger.kernel.org>, <dmaengine@vger.kernel.org>
Subject: Re: [Patch Part1 V2 01/17] iommu/vt-d: use dedicated bitmap to track remapping entry allocation status
Date: Mon, 2 Dec 2013 09:38:26 +0800 [thread overview]
Message-ID: <529BE492.5020201@huawei.com> (raw)
In-Reply-To: <1385715030-20553-2-git-send-email-jiang.liu@linux.intel.com>
Tested-and-reviewed-by: Yijing Wang <wangyijing@huawei.com>
On 2013/11/29 16:50, Jiang Liu wrote:
> Currently Intel interrupt remapping drivers uses the "present" flag bit
> in remapping entry to track whether an entry is allocated or not.
> It works as follow:
> 1) allocate a remapping entry and set its "present" flag bit to 1
> 2) compose other fields for the entry
> 3) update the remapping entry with the composed value
>
> The remapping hardware may access the entry between step 1 and step 3,
> which then obervers an entry with the "present" flag set but random
> values in all other fields.
>
> This patch introduces a dedicated bitmap to track remapping entry
> allocation status instead of sharing the "present" flag with hardware,
> thus eliminate the race window. It also simplifies the implementation.
>
> Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
> ---
> drivers/iommu/intel_irq_remapping.c | 51 +++++++++++++++++------------------
> include/linux/intel-iommu.h | 1 +
> 2 files changed, 25 insertions(+), 27 deletions(-)
>
> diff --git a/drivers/iommu/intel_irq_remapping.c b/drivers/iommu/intel_irq_remapping.c
> index bab10b1..282d392 100644
> --- a/drivers/iommu/intel_irq_remapping.c
> +++ b/drivers/iommu/intel_irq_remapping.c
> @@ -72,7 +72,6 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
> u16 index, start_index;
> unsigned int mask = 0;
> unsigned long flags;
> - int i;
>
> if (!count || !irq_iommu)
> return -1;
> @@ -96,32 +95,17 @@ static int alloc_irte(struct intel_iommu *iommu, int irq, u16 count)
> }
>
> raw_spin_lock_irqsave(&irq_2_ir_lock, flags);
> - do {
> - for (i = index; i < index + count; i++)
> - if (table->base[i].present)
> - break;
> - /* empty index found */
> - if (i == index + count)
> - break;
> -
> - index = (index + count) % INTR_REMAP_TABLE_ENTRIES;
> -
> - if (index == start_index) {
> - raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
> - printk(KERN_ERR "can't allocate an IRTE\n");
> - return -1;
> - }
> - } while (1);
> -
> - for (i = index; i < index + count; i++)
> - table->base[i].present = 1;
> -
> - cfg->remapped = 1;
> - irq_iommu->iommu = iommu;
> - irq_iommu->irte_index = index;
> - irq_iommu->sub_handle = 0;
> - irq_iommu->irte_mask = mask;
> -
> + index = bitmap_find_free_region(table->bitmap,
> + INTR_REMAP_TABLE_ENTRIES, mask);
> + if (index < 0) {
> + printk(KERN_ERR "can't allocate an IRTE\n");
> + } else {
> + cfg->remapped = 1;
> + irq_iommu->iommu = iommu;
> + irq_iommu->irte_index = index;
> + irq_iommu->sub_handle = 0;
> + irq_iommu->irte_mask = mask;
> + }
> raw_spin_unlock_irqrestore(&irq_2_ir_lock, flags);
>
> return index;
> @@ -254,6 +238,8 @@ static int clear_entries(struct irq_2_iommu *irq_iommu)
> set_64bit(&entry->low, 0);
> set_64bit(&entry->high, 0);
> }
> + bitmap_release_region(iommu->ir_table->bitmap, index,
> + irq_iommu->irte_mask);
>
> return qi_flush_iec(iommu, index, irq_iommu->irte_mask);
> }
> @@ -453,6 +439,7 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode)
> {
> struct ir_table *ir_table;
> struct page *pages;
> + unsigned long *bitmap;
>
> ir_table = iommu->ir_table = kzalloc(sizeof(struct ir_table),
> GFP_ATOMIC);
> @@ -470,7 +457,17 @@ static int intel_setup_irq_remapping(struct intel_iommu *iommu, int mode)
> return -ENOMEM;
> }
>
> + bitmap = kcalloc(BITS_TO_LONGS(INTR_REMAP_TABLE_ENTRIES),
> + sizeof(long), GFP_ATOMIC);
> + if (bitmap == NULL) {
> + printk(KERN_ERR "failed to allocate bitmap\n");
> + __free_pages(pages, INTR_REMAP_PAGE_ORDER);
> + kfree(ir_table);
> + return -ENOMEM;
> + }
> +
> ir_table->base = page_address(pages);
> + ir_table->bitmap = bitmap;
>
> iommu_set_irq_remapping(iommu, mode);
> return 0;
> diff --git a/include/linux/intel-iommu.h b/include/linux/intel-iommu.h
> index d380c5e..de1e5e9 100644
> --- a/include/linux/intel-iommu.h
> +++ b/include/linux/intel-iommu.h
> @@ -288,6 +288,7 @@ struct q_inval {
>
> struct ir_table {
> struct irte *base;
> + unsigned long *bitmap;
> };
> #endif
>
>
--
Thanks!
Yijing
next parent reply other threads:[~2013-12-02 1:38 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1385715030-20553-1-git-send-email-jiang.liu@linux.intel.com>
[not found] ` <1385715030-20553-2-git-send-email-jiang.liu@linux.intel.com>
[not found] ` <1385715030-20553-2-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-12-02 1:38 ` Yijing Wang [this message]
2013-12-02 1:38 ` [Patch Part1 V2 01/17] iommu/vt-d: use dedicated bitmap to track remapping entry allocation status Yijing Wang
[not found] ` <1385715030-20553-3-git-send-email-jiang.liu@linux.intel.com>
[not found] ` <1385715030-20553-3-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-12-02 1:40 ` [Patch Part1 V2 02/17] iommu/vt-d: fix PCI device reference leakage on error recovery path Yijing Wang
2013-12-02 1:40 ` Yijing Wang
[not found] ` <1385715030-20553-5-git-send-email-jiang.liu@linux.intel.com>
[not found] ` <1385715030-20553-5-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-12-02 1:41 ` [Patch Part1 V2 04/17] iommu/vt-d: fix resource leakage on error recovery path in iommu_init_domains() Yijing Wang
2013-12-02 1:41 ` Yijing Wang
[not found] ` <1385715030-20553-9-git-send-email-jiang.liu@linux.intel.com>
[not found] ` <1385715030-20553-9-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-12-02 1:42 ` [Patch Part1 V2 07/17] iommu/vt-d. trivial: check suitable flag in function detect_intel_iommu() Yijing Wang
2013-12-02 1:42 ` Yijing Wang
[not found] ` <1385715030-20553-8-git-send-email-jiang.liu@linux.intel.com>
[not found] ` <1385715030-20553-8-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-12-02 1:44 ` [Patch Part1 V2 07/17] iommu/vt-d, " Yijing Wang
2013-12-02 1:44 ` Yijing Wang
[not found] ` <1385715030-20553-14-git-send-email-jiang.liu@linux.intel.com>
[not found] ` <1385715030-20553-14-git-send-email-jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
2013-12-02 1:47 ` [Patch Part1 V2 12/17] iommu/vt-d: fix invalid memory access when freeing DMAR irq Yijing Wang
2013-12-02 1:47 ` Yijing Wang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=529BE492.5020201@huawei.com \
--to=wangyijing-hv44wf8li93qt0dzr+alfa@public.gmane.org \
--cc=ashok.raj-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=dan.j.williams-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=dmaengine-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=dwmw2-wEGCiKHe2LqWVfeAwA7xHQ@public.gmane.org \
--cc=iommu-cunTk1MwBs9QetFLy7KEm3xJsTq8ys+cHZ5vskTnxNA@public.gmane.org \
--cc=jiang.liu-VuQAYsv1563Yd54FQh9/CA@public.gmane.org \
--cc=joro-zLv9SwRftAIdnm+yROfE0A@public.gmane.org \
--cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=linux-pci-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
--cc=vinod.koul-ral2JQCrhuEAvxtiuMwx3w@public.gmane.org \
--cc=yinghai-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.