All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Jan Beulich <JBeulich@suse.com>,
	xen-devel <xen-devel@lists.xenproject.org>
Cc: Kevin Tian <kevin.tian@intel.com>, Tim Deegan <tim@xen.org>,
	Sander Eikelenboom <linux@eikelenboom.it>,
	Aravind Gopalakrishnan <aravind.gopalakrishnan@amd.com>,
	suravee.suthikulpanit@amd.com,
	Yang Z Zhang <yang.z.zhang@intel.com>
Subject: Re: [PATCH] IOMMU/x86: avoid pages without GFN in page table creation/updating
Date: Thu, 7 May 2015 14:13:38 +0100	[thread overview]
Message-ID: <554B6502.8010206@citrix.com> (raw)
In-Reply-To: <554B7DEB020000780007793D@mail.emea.novell.com>

On 07/05/15 13:59, Jan Beulich wrote:
> Handing INVALID_GFN to functions like hd->platform_ops->map_page()
> just can't do any good, and the ioreq server code results in such pages
> being on the list of ones owned by a guest.
>
> While - as suggested by Tim - we should use get_gfn()/put_gfn() there
> to eliminate races, we really can't due to holding the domain's page
> alloc lock. Ultimately arch_iommu_populate_page_table() may need to be
> switched to be GFN based. Here is what Tim said in this regard:
> "Ideally this loop would be iterating over all gfns in the p2m rather
>  than over all owned MFNs.  As long as needs_iommu gets set first,
>  such a loop could safely be paused and restarted without worrying
>  about concurrent updates.  The code sould even stay in this file,
>  though exposing an iterator from the p2m code would be a lot more
>  efficient."
>
> Original by Andrew Cooper <andrew.cooper3@citrix.com>, using further
> suggestions from Tim Deegan <tim@xen.org>.
>
> Reported-by: Sander Eikelenboom <linux@eikelenboom.it>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> Tested-by: Sander Eikelenboom <linux@eikelenboom.it>
> Acked-by: Tim Deegan <tim@xen.org>

Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com>, albeit with one
further suggestion.

>
> --- a/xen/drivers/passthrough/amd/iommu_map.c
> +++ b/xen/drivers/passthrough/amd/iommu_map.c
> @@ -557,6 +557,10 @@ static int update_paging_mode(struct dom
>      unsigned long old_root_mfn;
>      struct hvm_iommu *hd = domain_hvm_iommu(d);
>  
> +    if ( gfn == INVALID_MFN )
> +        return -EADDRNOTAVAIL;
> +    ASSERT(!(gfn >> DEFAULT_DOMAIN_ADDRESS_WIDTH));
> +
>      level = hd->arch.paging_mode;
>      old_root = hd->arch.root_table;
>      offset = gfn >> (PTE_PER_TABLE_SHIFT * (level - 1));
> @@ -729,12 +733,15 @@ int amd_iommu_unmap_page(struct domain *
>       * we might need a deeper page table for lager gfn now */
>      if ( is_hvm_domain(d) )
>      {
> -        if ( update_paging_mode(d, gfn) )
> +        int rc = update_paging_mode(d, gfn);
> +
> +        if ( rc )
>          {
>              spin_unlock(&hd->arch.mapping_lock);
>              AMD_IOMMU_DEBUG("Update page mode failed gfn = %lx\n", gfn);

Given the domain_crash(), this should probably at error priority rather
than debug.

~Andrew

> -            domain_crash(d);
> -            return -EFAULT;
> +            if ( rc != -EADDRNOTAVAIL )
> +                domain_crash(d);
> +            return rc;
>          }
>      }
>  
> --- a/xen/drivers/passthrough/vtd/iommu.h
> +++ b/xen/drivers/passthrough/vtd/iommu.h
> @@ -482,7 +482,6 @@ struct qinval_entry {
>  #define VTD_PAGE_TABLE_LEVEL_3  3
>  #define VTD_PAGE_TABLE_LEVEL_4  4
>  
> -#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
>  #define MAX_IOMMU_REGS 0xc0
>  
>  extern struct list_head acpi_drhd_units;
> --- a/xen/drivers/passthrough/x86/iommu.c
> +++ b/xen/drivers/passthrough/x86/iommu.c
> @@ -59,10 +59,17 @@ int arch_iommu_populate_page_table(struc
>          if ( has_hvm_container_domain(d) ||
>              (page->u.inuse.type_info & PGT_type_mask) == PGT_writable_page )
>          {
> -            BUG_ON(SHARED_M2P(mfn_to_gmfn(d, page_to_mfn(page))));
> -            rc = hd->platform_ops->map_page(
> -                d, mfn_to_gmfn(d, page_to_mfn(page)), page_to_mfn(page),
> -                IOMMUF_readable|IOMMUF_writable);
> +            unsigned long mfn = page_to_mfn(page);
> +            unsigned long gfn = mfn_to_gmfn(d, mfn);
> +
> +            if ( gfn != INVALID_MFN )
> +            {
> +                ASSERT(!(gfn >> DEFAULT_DOMAIN_ADDRESS_WIDTH));
> +                BUG_ON(SHARED_M2P(gfn));
> +                rc = hd->platform_ops->map_page(d, gfn, mfn,
> +                                                IOMMUF_readable |
> +                                                IOMMUF_writable);
> +            }
>              if ( rc )
>              {
>                  page_list_add(page, &d->page_list);
> --- a/xen/include/asm-x86/hvm/iommu.h
> +++ b/xen/include/asm-x86/hvm/iommu.h
> @@ -46,6 +46,8 @@ struct g2m_ioport {
>      unsigned int np;
>  };
>  
> +#define DEFAULT_DOMAIN_ADDRESS_WIDTH 48
> +
>  struct arch_hvm_iommu
>  {
>      u64 pgd_maddr;                 /* io page directory machine address */
> --- a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
> +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
> @@ -464,8 +464,6 @@
>  #define IOMMU_CONTROL_DISABLED	0
>  #define IOMMU_CONTROL_ENABLED	1
>  
> -#define DEFAULT_DOMAIN_ADDRESS_WIDTH    48
> -
>  /* interrupt remapping table */
>  #define INT_REMAP_ENTRY_REMAPEN_MASK    0x00000001
>  #define INT_REMAP_ENTRY_REMAPEN_SHIFT   0
>
>

  reply	other threads:[~2015-05-07 13:27 UTC|newest]

Thread overview: 8+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-07 12:59 [PATCH] IOMMU/x86: avoid pages without GFN in page table creation/updating Jan Beulich
2015-05-07 13:13 ` Andrew Cooper [this message]
2015-05-07 13:50   ` Jan Beulich
2015-05-11  2:53 ` Zhang, Yang Z
2015-05-11  6:47   ` Jan Beulich
2015-05-11  6:56     ` Zhang, Yang Z
2015-05-13 13:11 ` Ping: " Jan Beulich
2015-05-13 13:42 ` Suravee Suthikulanit

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=554B6502.8010206@citrix.com \
    --to=andrew.cooper3@citrix.com \
    --cc=JBeulich@suse.com \
    --cc=aravind.gopalakrishnan@amd.com \
    --cc=kevin.tian@intel.com \
    --cc=linux@eikelenboom.it \
    --cc=suravee.suthikulpanit@amd.com \
    --cc=tim@xen.org \
    --cc=xen-devel@lists.xenproject.org \
    --cc=yang.z.zhang@intel.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.