From: "Yang, Xiaowei" <xiaowei.yang@intel.com>
To: espen.skoglund@netronome.com
Cc: xen-devel@lists.xensource.com
Subject: Re: [PATCH] VT-d: IOTLB flush fixups
Date: Wed, 28 May 2008 17:01:18 +0800 [thread overview]
Message-ID: <1211965278.16052.20.camel@ip6-localhost> (raw)
In-Reply-To: <1211950777.17461.0.camel@ip6-localhost>
[-- Attachment #1: Type: text/plain, Size: 783 bytes --]
> On map: only flush when old PTE was valid or invalid PTE may be cached.
> On unmap: always flush old entry, but skip flush for unaffected IOMMUs.
>
> Signed-off-by: Espen Skoglund <espen.skoglund@netronome.com>
>
> --
> iommu.c | 17 +++++++++++------
> 1 file changed, 11 insertions(+), 6 deletions(-)
> --
Seems my last mail sent to the xen-devel is lost and I have no local
copy so I have to write again...
Espen,
Thanks for the patch! I also noticed context/iotlb flush need a cleanup.
As flush of present/non-present entry are different, your change to
iommu_intel_map_page are not that correct. So I made up anther patch.
iommu_flush is also removed, as VTd table is not shared with p2m any
more.
Signed-off-by: Xiaowei Yang <xiaowei.yang@intel.com>
Thanks,
Xiaowei
[-- Attachment #2: flush.diff --]
[-- Type: text/x-patch, Size: 7951 bytes --]
diff -r c93a913c221f xen/arch/x86/mm/hap/p2m-ept.c
--- a/xen/arch/x86/mm/hap/p2m-ept.c Tue May 27 13:03:05 2008 +0100
+++ b/xen/arch/x86/mm/hap/p2m-ept.c Wed May 28 06:24:27 2008 +0800
@@ -266,12 +266,6 @@ out:
iommu_unmap_page(d, gfn);
}
}
-
-#ifdef P2M_SHARE_WITH_VTD_PAGE_TABLE
- /* If p2m table is shared with vtd page-table. */
- if ( iommu_enabled && is_hvm_domain(d) && (p2mt == p2m_mmio_direct) )
- iommu_flush(d, gfn, (u64*)ept_entry);
-#endif
return rv;
}
diff -r c93a913c221f xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c Tue May 27 13:03:05 2008 +0100
+++ b/xen/drivers/passthrough/vtd/iommu.c Wed May 28 06:59:25 2008 +0800
@@ -485,9 +485,12 @@ static int flush_iotlb_reg(void *_iommu,
/* check IOTLB invalidation granularity */
if ( DMA_TLB_IAIG(val) == 0 )
printk(KERN_ERR VTDPREFIX "IOMMU: flush IOTLB failed\n");
+
+#ifdef VTD_DEBUG
if ( DMA_TLB_IAIG(val) != DMA_TLB_IIRG(type) )
printk(KERN_ERR VTDPREFIX "IOMMU: tlb flush request %x, actual %x\n",
(u32)DMA_TLB_IIRG(type), (u32)DMA_TLB_IAIG(val));
+#endif
/* flush context entry will implictly flush write buffer */
return 0;
}
@@ -581,30 +584,29 @@ static void dma_pte_clear_one(struct dom
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
/* get last level pte */
- pg_maddr = dma_addr_level_page_maddr(domain, addr, 1);
+ pg_maddr = dma_addr_level_page_maddr(domain, addr, 2);
if ( pg_maddr == 0 )
return;
page = (struct dma_pte *)map_vtd_domain_page(pg_maddr);
pte = page + address_level_offset(addr, 1);
- if ( pte )
- {
- dma_clear_pte(*pte);
- iommu_flush_cache_entry(drhd->iommu, pte);
-
- for_each_drhd_unit ( drhd )
- {
- iommu = drhd->iommu;
-
- if ( !test_bit(iommu->index, &hd->iommu_bitmap) )
- continue;
-
- if ( cap_caching_mode(iommu->cap) )
- iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
- addr, 1, 0);
- else if (cap_rwbf(iommu->cap))
- iommu_flush_write_buffer(iommu);
- }
- }
+
+ if ( !dma_pte_present(*pte) )
+ {
+ unmap_vtd_domain_page(page);
+ return;
+ }
+
+ dma_clear_pte(*pte);
+ iommu_flush_cache_entry(drhd->iommu, pte);
+
+ for_each_drhd_unit ( drhd )
+ {
+ iommu = drhd->iommu;
+
+ if ( test_bit(iommu->index, &hd->iommu_bitmap) )
+ iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain), addr, 1, 0);
+ }
+
unmap_vtd_domain_page(page);
}
@@ -1191,12 +1193,13 @@ static int domain_context_mapping_one(
unmap_vtd_domain_page(context_entries);
+ /* it's a non-present to present mapping */
if ( iommu_flush_context_device(iommu, domain_iommu_domid(domain),
(((u16)bus) << 8) | devfn,
DMA_CCMD_MASK_NOBIT, 1) )
iommu_flush_write_buffer(iommu);
else
- iommu_flush_iotlb_dsi(iommu, domain_iommu_domid(domain), 0);
+ iommu_flush_iotlb_dsi(iommu, 0, 0);
set_bit(iommu->index, &hd->iommu_bitmap);
spin_unlock_irqrestore(&iommu->lock, flags);
@@ -1526,6 +1529,7 @@ int intel_iommu_map_page(
struct iommu *iommu;
struct dma_pte *page = NULL, *pte = NULL;
u64 pg_maddr;
+ int pte_present;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
iommu = drhd->iommu;
@@ -1541,6 +1545,7 @@ int intel_iommu_map_page(
return -ENOMEM;
page = (struct dma_pte *)map_vtd_domain_page(pg_maddr);
pte = page + (gfn & LEVEL_MASK);
+ pte_present = dma_pte_present(*pte);
dma_set_pte_addr(*pte, (paddr_t)mfn << PAGE_SHIFT_4K);
dma_set_pte_prot(*pte, DMA_PTE_READ | DMA_PTE_WRITE);
iommu_flush_cache_entry(iommu, pte);
@@ -1553,10 +1558,11 @@ int intel_iommu_map_page(
if ( !test_bit(iommu->index, &hd->iommu_bitmap) )
continue;
- if ( cap_caching_mode(iommu->cap) )
+ if ( pte_present )
iommu_flush_iotlb_psi(iommu, domain_iommu_domid(d),
(paddr_t)gfn << PAGE_SHIFT_4K, 1, 0);
- else if ( cap_rwbf(iommu->cap) )
+ else if ( iommu_flush_iotlb_psi(iommu, domain_iommu_domid(d),
+ (paddr_t)gfn << PAGE_SHIFT_4K, 1, 1) )
iommu_flush_write_buffer(iommu);
}
@@ -1567,8 +1573,6 @@ int intel_iommu_unmap_page(struct domain
{
struct acpi_drhd_unit *drhd;
struct iommu *iommu;
- struct dma_pte *page = NULL, *pte = NULL;
- u64 pg_maddr;
drhd = list_entry(acpi_drhd_units.next, typeof(*drhd), list);
iommu = drhd->iommu;
@@ -1579,24 +1583,7 @@ int intel_iommu_unmap_page(struct domain
return 0;
#endif
- pg_maddr = addr_to_dma_page_maddr(d, (paddr_t)gfn << PAGE_SHIFT_4K);
- if ( pg_maddr == 0 )
- return -ENOMEM;
- page = (struct dma_pte *)map_vtd_domain_page(pg_maddr);
- pte = page + (gfn & LEVEL_MASK);
- dma_clear_pte(*pte);
- iommu_flush_cache_entry(drhd->iommu, pte);
- unmap_vtd_domain_page(page);
-
- for_each_drhd_unit ( drhd )
- {
- iommu = drhd->iommu;
- if ( cap_caching_mode(iommu->cap) )
- iommu_flush_iotlb_psi(iommu, domain_iommu_domid(d),
- (paddr_t)gfn << PAGE_SHIFT_4K, 1, 0);
- else if ( cap_rwbf(iommu->cap) )
- iommu_flush_write_buffer(iommu);
- }
+ dma_pte_clear_one(d, (paddr_t)gfn << PAGE_SHIFT_4K);
return 0;
}
@@ -1642,10 +1629,8 @@ int iommu_page_mapping(struct domain *do
if ( !test_bit(iommu->index, &hd->iommu_bitmap) )
continue;
- if ( cap_caching_mode(iommu->cap) )
- iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
- iova, index, 0);
- else if ( cap_rwbf(iommu->cap) )
+ if ( iommu_flush_iotlb_psi(iommu, domain_iommu_domid(domain),
+ iova, index, 1) )
iommu_flush_write_buffer(iommu);
}
@@ -1657,30 +1642,6 @@ int iommu_page_unmapping(struct domain *
dma_pte_clear_range(domain, addr, addr + size);
return 0;
-}
-
-void iommu_flush(struct domain *d, unsigned long gfn, u64 *p2m_entry)
-{
- struct hvm_iommu *hd = domain_hvm_iommu(d);
- struct acpi_drhd_unit *drhd;
- struct iommu *iommu = NULL;
- struct dma_pte *pte = (struct dma_pte *) p2m_entry;
-
- for_each_drhd_unit ( drhd )
- {
- iommu = drhd->iommu;
-
- if ( !test_bit(iommu->index, &hd->iommu_bitmap) )
- continue;
-
- if ( cap_caching_mode(iommu->cap) )
- iommu_flush_iotlb_psi(iommu, domain_iommu_domid(d),
- (paddr_t)gfn << PAGE_SHIFT_4K, 1, 0);
- else if ( cap_rwbf(iommu->cap) )
- iommu_flush_write_buffer(iommu);
- }
-
- iommu_flush_cache_entry(iommu, pte);
}
static int iommu_prepare_rmrr_dev(
diff -r c93a913c221f xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h Tue May 27 13:03:05 2008 +0100
+++ b/xen/include/xen/iommu.h Wed May 28 06:24:44 2008 +0800
@@ -65,7 +65,6 @@ void reassign_device_ownership(struct do
u8 bus, u8 devfn);
int iommu_map_page(struct domain *d, unsigned long gfn, unsigned long mfn);
int iommu_unmap_page(struct domain *d, unsigned long gfn);
-void iommu_flush(struct domain *d, unsigned long gfn, u64 *p2m_entry);
void iommu_set_pgd(struct domain *d);
void iommu_free_pgd(struct domain *d);
void iommu_domain_teardown(struct domain *d);
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next parent reply other threads:[~2008-05-28 9:01 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <1211950777.17461.0.camel@ip6-localhost>
2008-05-28 9:01 ` Yang, Xiaowei [this message]
[not found] ` <1211965013.16052.16.camel@ip6-localhost>
2008-05-28 15:00 ` [PATCH] VT-d: IOTLB flush fixups Espen Skoglund
2008-05-29 4:13 ` Yang, Xiaowei
2008-05-27 16:21 Espen Skoglund
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=1211965278.16052.20.camel@ip6-localhost \
--to=xiaowei.yang@intel.com \
--cc=espen.skoglund@netronome.com \
--cc=xen-devel@lists.xensource.com \
/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.