From: Paul Durrant <Paul.Durrant@citrix.com>
To: "xen-devel@lists.xenproject.org" <xen-devel@lists.xenproject.org>
Cc: Paul Durrant <Paul.Durrant@citrix.com>,
Brian Woods <brian.woods@amd.com>,
Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
Subject: Re: [PATCH v3] amd-iommu: remove page merging code
Date: Tue, 11 Dec 2018 11:00:34 +0000 [thread overview]
Message-ID: <f2713f3dedf044d09c9551e837329d3c@AMSPEX02CL03.citrite.net> (raw)
In-Reply-To: <20181128095559.5101-1-paul.durrant@citrix.com>
Ping? This has acks from Andy and Brian now, but has not been committed. Is there anything holding it up?
> -----Original Message-----
> From: Paul Durrant [mailto:paul.durrant@citrix.com]
> Sent: 28 November 2018 09:56
> To: xen-devel@lists.xenproject.org
> Cc: Paul Durrant <Paul.Durrant@citrix.com>; Suravee Suthikulpanit
> <suravee.suthikulpanit@amd.com>; Brian Woods <brian.woods@amd.com>
> Subject: [PATCH v3] amd-iommu: remove page merging code
>
> The page merging logic makes use of bits 1-8 and bit 63 of a PTE, which
> used to be specified as 'ignored'. However, bits 5 and 6 are now specified
> as 'accessed' and 'dirty' bits and their use only remains safe as long as
> the DTE 'Host Access Dirty' bits remain unused by Xen, or by hardware
> before the domain starts running. (XSA-275 disabled the operation of the
> code after domain creation completes).
>
> With the page merging logic present in its current form there are no spare
> ignored bits in the PTE at all, but PV-IOMMU support will require at least
> one spare bit to track which PTEs are added by hypercall.
>
> This patch removes the code, freeing up the remaining PTE ignored bits
> for other use, including PV-IOMMU support, as well as significantly
> simplifying and shortening the source by ~170 lines. There may be some
> marginal performance cost (but none has been observed in manual testing
> with a passed-through NVIDIA GPU) since higher order mappings will now be
> ruled out until a mapping order parameter is passed to iommu_ops. That
> will
> be dealt with by a subsequent patch though.
>
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> Cc: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
> Cc: Brian Woods <brian.woods@amd.com>
>
> v3:
> - Further expand commit comment
>
> v2:
> - Remove 'no_merge' boolean
> - Expand commit comment
> ---
> xen/drivers/passthrough/amd/iommu_map.c | 175 +--------------------------
> -----
> xen/include/asm-x86/iommu.h | 1 -
> 2 files changed, 1 insertion(+), 175 deletions(-)
>
> diff --git a/xen/drivers/passthrough/amd/iommu_map.c
> b/xen/drivers/passthrough/amd/iommu_map.c
> index 0ac3f473b3..04cb7b3182 100644
> --- a/xen/drivers/passthrough/amd/iommu_map.c
> +++ b/xen/drivers/passthrough/amd/iommu_map.c
> @@ -323,134 +323,6 @@ uint64_t amd_iommu_get_address_from_pte(void *pte)
> return ptr;
> }
>
> -/* For each pde, We use ignored bits (bit 1 - bit 8 and bit 63)
> - * to save pde count, pde count = 511 is a candidate of page coalescing.
> - */
> -static unsigned int get_pde_count(uint64_t pde)
> -{
> - unsigned int count;
> - uint64_t upper_mask = 1ULL << 63 ;
> - uint64_t lower_mask = 0xFF << 1;
> -
> - count = ((pde & upper_mask) >> 55) | ((pde & lower_mask) >> 1);
> - return count;
> -}
> -
> -/* Convert pde count into iommu pte ignored bits */
> -static void set_pde_count(uint64_t *pde, unsigned int count)
> -{
> - uint64_t upper_mask = 1ULL << 8 ;
> - uint64_t lower_mask = 0xFF;
> - uint64_t pte_mask = (~(1ULL << 63)) & (~(0xFF << 1));
> -
> - *pde &= pte_mask;
> - *pde |= ((count & upper_mask ) << 55) | ((count & lower_mask ) << 1);
> -}
> -
> -/* Return 1, if pages are suitable for merging at merge_level.
> - * otherwise increase pde count if mfn is contigous with mfn - 1
> - */
> -static bool iommu_update_pde_count(struct domain *d, unsigned long
> pt_mfn,
> - unsigned long dfn, unsigned long mfn,
> - unsigned int merge_level)
> -{
> - unsigned int pde_count, next_level;
> - unsigned long first_mfn;
> - uint64_t *table, *pde, *ntable;
> - uint64_t ntable_maddr, mask;
> - struct domain_iommu *hd = dom_iommu(d);
> - bool ok = false;
> -
> - ASSERT( spin_is_locked(&hd->arch.mapping_lock) && pt_mfn );
> -
> - next_level = merge_level - 1;
> -
> - /* get pde at merge level */
> - table = map_domain_page(_mfn(pt_mfn));
> - pde = table + pfn_to_pde_idx(dfn, merge_level);
> -
> - /* get page table of next level */
> - ntable_maddr = amd_iommu_get_address_from_pte(pde);
> - ntable = map_domain_page(_mfn(paddr_to_pfn(ntable_maddr)));
> -
> - /* get the first mfn of next level */
> - first_mfn = amd_iommu_get_address_from_pte(ntable) >> PAGE_SHIFT;
> -
> - if ( first_mfn == 0 )
> - goto out;
> -
> - mask = (1ULL<< (PTE_PER_TABLE_SHIFT * next_level)) - 1;
> -
> - if ( ((first_mfn & mask) == 0) &&
> - (((dfn & mask) | first_mfn) == mfn) )
> - {
> - pde_count = get_pde_count(*pde);
> -
> - if ( pde_count == (PTE_PER_TABLE_SIZE - 1) )
> - ok = true;
> - else if ( pde_count < (PTE_PER_TABLE_SIZE - 1))
> - {
> - pde_count++;
> - set_pde_count(pde, pde_count);
> - }
> - }
> -
> - else
> - /* non-contiguous mapping */
> - set_pde_count(pde, 0);
> -
> -out:
> - unmap_domain_page(ntable);
> - unmap_domain_page(table);
> -
> - return ok;
> -}
> -
> -static int iommu_merge_pages(struct domain *d, unsigned long pt_mfn,
> - unsigned long dfn, unsigned int flags,
> - unsigned int merge_level)
> -{
> - uint64_t *table, *pde, *ntable;
> - uint64_t ntable_mfn;
> - unsigned long first_mfn;
> - struct domain_iommu *hd = dom_iommu(d);
> -
> - ASSERT( spin_is_locked(&hd->arch.mapping_lock) && pt_mfn );
> -
> - table = map_domain_page(_mfn(pt_mfn));
> - pde = table + pfn_to_pde_idx(dfn, merge_level);
> -
> - /* get first mfn */
> - ntable_mfn = amd_iommu_get_address_from_pte(pde) >> PAGE_SHIFT;
> -
> - if ( ntable_mfn == 0 )
> - {
> - unmap_domain_page(table);
> - return 1;
> - }
> -
> - ntable = map_domain_page(_mfn(ntable_mfn));
> - first_mfn = amd_iommu_get_address_from_pte(ntable) >> PAGE_SHIFT;
> -
> - if ( first_mfn == 0 )
> - {
> - unmap_domain_page(ntable);
> - unmap_domain_page(table);
> - return 1;
> - }
> -
> - /* setup super page mapping, next level = 0 */
> - set_iommu_pde_present((uint32_t *)pde, first_mfn, 0,
> - !!(flags & IOMMUF_writable),
> - !!(flags & IOMMUF_readable));
> -
> - amd_iommu_flush_all_pages(d);
> -
> - unmap_domain_page(ntable);
> - unmap_domain_page(table);
> - return 0;
> -}
> -
> /* Walk io page tables and build level page tables if necessary
> * {Re, un}mapping super page frames causes re-allocation of io
> * page tables.
> @@ -656,7 +528,6 @@ int amd_iommu_map_page(struct domain *d, dfn_t dfn,
> mfn_t mfn,
> struct domain_iommu *hd = dom_iommu(d);
> int rc;
> unsigned long pt_mfn[7];
> - unsigned int merge_level;
>
> if ( iommu_use_hap_pt(d) )
> return 0;
> @@ -698,55 +569,14 @@ int amd_iommu_map_page(struct domain *d, dfn_t dfn,
> mfn_t mfn,
> return -EFAULT;
> }
>
> - /* Install 4k mapping first */
> + /* Install 4k mapping */
> need_flush = set_iommu_pte_present(pt_mfn[1], dfn_x(dfn), mfn_x(mfn),
> 1,
> !!(flags & IOMMUF_writable),
> !!(flags & IOMMUF_readable));
>
> if ( need_flush )
> - {
> amd_iommu_flush_pages(d, dfn_x(dfn), 0);
> - /* No further merging, as the logic doesn't cope. */
> - hd->arch.no_merge = true;
> - }
>
> - /*
> - * Suppress merging of non-R/W mappings or after initial table
> creation,
> - * as the merge logic does not cope with this.
> - */
> - if ( hd->arch.no_merge || flags != (IOMMUF_writable |
> IOMMUF_readable) )
> - goto out;
> - if ( d->creation_finished )
> - {
> - hd->arch.no_merge = true;
> - goto out;
> - }
> -
> - for ( merge_level = 2; merge_level <= hd->arch.paging_mode;
> - merge_level++ )
> - {
> - if ( pt_mfn[merge_level] == 0 )
> - break;
> - if ( !iommu_update_pde_count(d, pt_mfn[merge_level],
> - dfn_x(dfn), mfn_x(mfn), merge_level)
> )
> - break;
> -
> - if ( iommu_merge_pages(d, pt_mfn[merge_level], dfn_x(dfn),
> - flags, merge_level) )
> - {
> - spin_unlock(&hd->arch.mapping_lock);
> - AMD_IOMMU_DEBUG("Merge iommu page failed at level %d, "
> - "dfn = %"PRI_dfn" mfn = %"PRI_mfn"\n",
> - merge_level, dfn_x(dfn), mfn_x(mfn));
> - domain_crash(d);
> - return -EFAULT;
> - }
> -
> - /* Deallocate lower level page table */
> - free_amd_iommu_pgtable(mfn_to_page(_mfn(pt_mfn[merge_level -
> 1])));
> - }
> -
> -out:
> spin_unlock(&hd->arch.mapping_lock);
> return 0;
> }
> @@ -798,9 +628,6 @@ int amd_iommu_unmap_page(struct domain *d, dfn_t dfn)
> /* mark PTE as 'page not present' */
> clear_iommu_pte_present(pt_mfn[1], dfn_x(dfn));
>
> - /* No further merging in amd_iommu_map_page(), as the logic doesn't
> cope. */
> - hd->arch.no_merge = true;
> -
> spin_unlock(&hd->arch.mapping_lock);
>
> amd_iommu_flush_pages(d, dfn_x(dfn), 0);
> diff --git a/xen/include/asm-x86/iommu.h b/xen/include/asm-x86/iommu.h
> index 055466b5bf..8dc392473d 100644
> --- a/xen/include/asm-x86/iommu.h
> +++ b/xen/include/asm-x86/iommu.h
> @@ -52,7 +52,6 @@ struct arch_iommu
>
> /* amd iommu support */
> int paging_mode;
> - bool no_merge;
> struct page_info *root_table;
> struct guest_iommu *g_iommu;
> };
> --
> 2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2018-12-11 11:00 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-11-28 9:55 [PATCH v3] amd-iommu: remove page merging code Paul Durrant
2018-11-28 10:41 ` Andrew Cooper
2018-12-03 10:27 ` Paul Durrant
2018-12-04 23:31 ` Woods, Brian
2018-12-05 8:50 ` Paul Durrant
2018-12-11 11:00 ` Paul Durrant [this message]
2018-12-11 11:22 ` Jan Beulich
2018-12-11 11:30 ` Paul Durrant
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=f2713f3dedf044d09c9551e837329d3c@AMSPEX02CL03.citrite.net \
--to=paul.durrant@citrix.com \
--cc=brian.woods@amd.com \
--cc=suravee.suthikulpanit@amd.com \
--cc=xen-devel@lists.xenproject.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).