All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM
@ 2014-07-02 18:42 Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
                   ` (14 more replies)
  0 siblings, 15 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Hello,

here is finally the nineth version of my implementation proposal for the
hypercall XEN_DOMCTL_memory_mapping for the ARM architecture. First of all,
I am deeply sorry for the delay and for blocking patchsets of which this one
is a dependency. As usual, I'm trying to keep this cover letter as brief as
I can by listing here only the most relevant changes, while a more detailed
description can be found in the commit message and in the changelog of each
patch. Also, more information about the patch series can be found in the
last full cover letter ([1]).
Please note that the one that was the series' first patch has been merged
two weeks ago by Ian Campbell ([2]), and this is why it is missing from this
patchset.

Patch 0001 has been fixed according to suggestions provided by Julien Grall
and Ian Campbell; it is also worthy to say that now the added checks don't stop
unmapping when failing to unmap an I/O-memory mapping, but merely emit a
warning. This choice has two benefits: it prevents I/O-memory regions from
remaining partially accessible to a domain, and it lets the handling of such a
failure match the one introduced for x86 by patch 0005 in the lighter warn-
only form requested by Jan Beulich.

Patch 0004 has been modified according to directives given by Julien Grall and
Ian Campbell: it now lets the function apply_p2m_changes() unwind its own
progress when failing to INSERT a new mapping.

Patch 0007 now adds the MTRR-related memory_type_changed() function for ARM
as just a stub instead of creating and ad-hoc file and header, as suggested by
Julien Grall and seconded by Jan Beulich and Ian Campbell.

Patch 0008 has been fixed according to requests from Jan Beulich.

Patch 0009 no more exposes mfn_t to the common code, as requested by Julien
Grall and approved by Ian Campbell and Tim Deegan.

Patch 0011 has been fixed as per Julien Grall's indications.

A new patch 0012 has been added to the patch series. The patch attempts to
address an issue pointed out by Jan Beulich, concerning the passthru of
different GPUs to different domain, each one designed as primary VGA device
of its own domain with gfx_passthru = 1 in the domain config. Patch 0013
would grant access permission to the VGA framebuffer to each domain with
gfx_passthru in its config, while access permission must be granted only to
the domain having the primary GPU passthru to it.
Unfortunately, I haven't found a way to distinguish the primary GPU from the
other ones, and I decided to rely on user input. Patch 0012, in fact, adds a
new option to libxl configuration, which allows the user to specify if one of
the passthru VGA devices is primary. Only a domain with both gfx_passthru = 1
and gfx_passthru_primary = 1 (and its stubdomain, see the comment on patch
0013 below) will have access permission to VGA-specific I/O-memory regions.
Please note that the default for the new option is true, to avoid breaking
interaction with QEMU when possible; AFAIK QEMU will however try to map the
I/O-memory region to all guests requesting GFX passthrough.

Patch 0013 now grants access permission to VGA-specific I/O-memory regions
both to the domain with gfx_passthru = 1 and gfx_passthru_primary = 1 and its
stubdomain, as, after patch 0014, the memory_mapping DOMCTL will check for
both, as pointed out by Julien Grall.

The code has again been tested on a cubieboard2, with Linux v3.15-rc3 as a dom0
and ERIKA Enterprise ([3]) as a domU. The x86 bits have been tested on an x86_64
machine with Linux 3.15.0-rc5 as both dom0 and domU.
Any feedback about this new version of the patchset is more than welcome,
Arianna

[1] http://lists.xen.org/archives/html/xen-devel/2014-03/msg01724.html
[2] http://markmail.org/message/svp3byd62eol375y
[3] http://erika.tuxfamily.org/drupal/

Arianna Avanzini (14):
  arch/arm: add consistency check to REMOVE p2m changes
  arch/arm: let map_mmio_regions() take pfn as parameters
  arch/arm: let map_mmio_regions() use start and count
  arch/arm: unmap partially-mapped I/O-memory regions
  arch/x86: warn if to-be-removed mapping does not exist
  arch/x86: cleanup memory_mapping DOMCTL
  xen/common: add ARM stub for the function memory_type_changed()
  xen/x86: factor out map and unmap from the memory_mapping DOMCTL
  xen/common: move the memory_mapping DOMCTL hypercall to common code
  tools/libxl: parse optional start gfn from the iomem config option
  tools/libxl: handle the iomem parameter with the memory_mapping hcall
  tools/libxl: read from config if passing through primary GPU
  tools/libxl: explicitly grant access to needed I/O-memory ranges
  xen/common: do not implicitly permit access to mapped I/O memory

 docs/man/xl.cfg.pod.5                | 25 +++++++++---
 tools/libxc/xc_domain.c              | 10 +++++
 tools/libxl/libxl.h                  | 17 ++++++++
 tools/libxl/libxl_create.c           | 51 ++++++++++++++++++++++++
 tools/libxl/libxl_internal.h         |  1 +
 tools/libxl/libxl_pci.c              | 26 +++++-------
 tools/libxl/libxl_types.idl          |  7 +++-
 tools/libxl/xl_cmdimpl.c             | 19 +++++----
 xen/arch/arm/domain_build.c          |  7 ++--
 xen/arch/arm/gic.c                   | 15 +++----
 xen/arch/arm/p2m.c                   | 77 ++++++++++++++++++++++++++++++------
 xen/arch/arm/platforms/exynos5.c     |  9 ++---
 xen/arch/arm/platforms/omap5.c       | 17 ++++----
 xen/arch/arm/platforms/xgene-storm.c | 16 +++++---
 xen/arch/x86/domctl.c                | 76 -----------------------------------
 xen/arch/x86/mm/p2m.c                | 55 ++++++++++++++++++++++++--
 xen/common/domctl.c                  | 54 ++++++++++++++++++++++++-
 xen/include/asm-arm/mm.h             |  2 +
 xen/include/asm-arm/p2m.h            | 11 +++---
 xen/include/asm-x86/p2m.h            |  3 +-
 xen/include/xen/p2m-common.h         | 16 ++++++++
 21 files changed, 354 insertions(+), 160 deletions(-)
 create mode 100644 xen/include/xen/p2m-common.h

-- 
1.9.3

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-03 10:24   ` Julien Grall
  2014-07-03 11:03   ` Julien Grall
  2014-07-02 18:42 ` [PATCH v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters Arianna Avanzini
                   ` (13 subsequent siblings)
  14 siblings, 2 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the REMOVE case of the switch in apply_p2m_changes()
does not perform any consistency check on the mapping to be removed.
More in detail, the code does not check if the guest address to be
unmapped is actually mapped to the machine address given as a
parameter.
This commit adds the above-described consistency check to the REMOVE
path of apply_p2m_changes() and lets a warning be emitted when trying
to remove a non-existent mapping. This is instrumental to one of the
following commits, which implements the possibility to trigger the
removal of p2m ranges via the memory_mapping DOMCTL for ARM.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Don't return with an error when failing to remove a mapping, but
          simply keep unmapping.
        - Don't force assignment to the flush variable, as it is already
          set before the switch.
        - Change warning message to be more appropriate and clear; use the
          correct format for paddr_t and gdprintk(), which is more restricted
          than regular printk()s.

    v8:
        - Re-add erroneously-removed increments to the maddr variable.
        - When failing to remove a mapping, add previously-mapped PT entry,
          unlock the p2m_lock and flush TLBs if necessary.
        - Emit an error message when failing to remove a mapping.
        - Remove tentative phrases from commit description.

    v7:
        - Silently ignore the fact that, when removing a mapping, the specified
          gfn is not mapped at all.
        - Remove spurious spacing change.

    v6:
        - Don't update "count" on REMOVE as it is only used inside the
          RELINQUISH case of the switch in apply_p2m_changes().
        - Return with an error if removal of a page fails instead of just
          skipping the page.

    v5:
        - Do not use a temporary variable to hold the machine address:
          use the "maddr" function parameter itself.
        - Increment the machine address also when first and second level
          mappings are not valid.
        - Get the actual machine frame number mapped to the guest frame
          number given as parameter to the function directly in the
          REMOVE case of the switch construct, as it might not be valid
          in other cases and its value might be uncorrectly used in the
          future.
        - Remove useless and/or harmful ASSERT; check however if the
          mapping is valid and skip the page if it is not.

    v4:
        - Remove useless and slow lookup and use already-available
          data from pte instead.
        - Correctly increment the local variable used to keep the
          machine address whose mapping is currently being removed.
        - Return with an error upon finding a mismatch between the
          actual machine address mapped to the guest address and
          the machine address passed as parameter, instead of just
          skipping the page.

---
 xen/arch/arm/p2m.c | 32 ++++++++++++++++++++++++++++++--
 1 file changed, 30 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 9960e17..7cb4a27 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -348,6 +348,7 @@ static int apply_p2m_changes(struct domain *d,
             if ( !populate )
             {
                 addr = (addr + FIRST_SIZE) & FIRST_MASK;
+                maddr = (maddr + FIRST_SIZE) & FIRST_MASK;
                 continue;
             }
 
@@ -375,6 +376,7 @@ static int apply_p2m_changes(struct domain *d,
             if ( !populate )
             {
                 addr = (addr + SECOND_SIZE) & SECOND_MASK;
+                maddr = (maddr + SECOND_SIZE) & SECOND_MASK;
                 continue;
             }
 
@@ -439,12 +441,37 @@ static int apply_p2m_changes(struct domain *d,
                     pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr, t);
                     p2m_write_pte(&third[third_table_offset(addr)],
                                   pte, flush_pt);
-                    maddr += PAGE_SIZE;
                 }
                 break;
-            case RELINQUISH:
             case REMOVE:
                 {
+                    unsigned long mfn = pte.p2m.base;
+
+                    /*
+                     * Ensure that the guest address addr currently being
+                     * handled (that is in the range given as argument to
+                     * this function) is actually mapped to the corresponding
+                     * machine address in the specified range. maddr here is
+                     * the machine address given to the function, while mfn
+                     * is the machine frame number actually mapped to the
+                     * guest address: check if the two correspond.
+                     */
+                    if ( !pte.p2m.valid || maddr != pfn_to_paddr(mfn) )
+                    {
+                        gdprintk(XENLOG_WARNING,
+                                 "p2m_remove: mapping at %"PRIpaddr" is of maddr %"PRIpaddr" not %"PRIpaddr" as expected",
+                                 addr, pfn_to_paddr(mfn), maddr);
+                        /*
+                         * Continue to process the range even if an error is
+                         * encountered, to prevent I/O-memory regions from
+                         * being partially accessible to a domain.
+                         */
+                       continue;
+                    }
+                }
+                /* fall through */
+            case RELINQUISH:
+                {
                     if ( !pte.p2m.valid )
                     {
                         count++;
@@ -484,6 +511,7 @@ static int apply_p2m_changes(struct domain *d,
 
         /* Got the next page */
         addr += PAGE_SIZE;
+        maddr += PAGE_SIZE;
     }
 
     if ( flush )
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-03 10:26   ` Julien Grall
  2014-07-02 18:42 ` [PATCH v9 03/14] arch/arm: let map_mmio_regions() use start and count Arianna Avanzini
                   ` (12 subsequent siblings)
  14 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the map_mmio_regions() function, defined for the ARM
architecture, has parameters with paddr_t type. This interface,
however, needs caller functions to correctly page-align addresses
given as parameters to map_mmio_regions(). This commit changes the
function's interface to accept page frame numbers as parameters.
This commit also modifies caller functions in an attempt to adapt
them to the new interface.
This commit is meant to produce the minimum indispensable needed
changes; these are also instrumental to making the interface of
map_mmio_regions() symmetric with the unmap_mmio_regions() function,
that will be introduced in one of the next commits of the series
and will feature a pfn-based interface.

NOTE: platform-specific code has not been tested, save for the
      sunxi and the Arndale Exynos 5 platforms (see the Tested-by
      below for the latter).

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Tested-by: Julien Grall <julien.grall@citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v7:
        - Remove useless decrements when using paddr_to_pfn_aligned().

    v5:
        - Add a macro for the paddr_to_pfn(PAGE_ALIGN(...)) pattern.
        - Hopefully improve commit description.

---
 xen/arch/arm/domain_build.c          |  7 ++++---
 xen/arch/arm/gic.c                   | 20 +++++++++++---------
 xen/arch/arm/p2m.c                   | 13 ++++++++-----
 xen/arch/arm/platforms/exynos5.c     | 11 ++++++-----
 xen/arch/arm/platforms/omap5.c       | 21 ++++++++++++---------
 xen/arch/arm/platforms/xgene-storm.c |  4 +++-
 xen/include/asm-arm/mm.h             |  2 ++
 xen/include/asm-arm/p2m.h            | 11 ++++++-----
 8 files changed, 52 insertions(+), 37 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 9d9cba9..6300fe3 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -774,9 +774,10 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
                    addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1);
             return res;
         }
-        res = map_mmio_regions(d, addr & PAGE_MASK,
-                               PAGE_ALIGN(addr + size) - 1,
-                               addr & PAGE_MASK);
+        res = map_mmio_regions(d,
+                               paddr_to_pfn(addr & PAGE_MASK),
+                               paddr_to_pfn_aligned(addr + size),
+                               paddr_to_pfn(addr & PAGE_MASK));
         if ( res )
         {
             printk(XENLOG_ERR "Unable to map 0x%"PRIx64
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 4d2a92d..34b1070 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -912,20 +912,22 @@ int gicv_setup(struct domain *d)
      * The second page is always mapped at +4K irrespective of the
      * GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
      */
-    ret = map_mmio_regions(d, d->arch.vgic.cbase,
-                           d->arch.vgic.cbase + PAGE_SIZE - 1,
-                           gic.vbase);
+    ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase),
+                           paddr_to_pfn_aligned(d->arch.vgic.cbase + PAGE_SIZE),
+                           paddr_to_pfn(gic.vbase));
     if (ret)
         return ret;
 
     if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
-        ret = map_mmio_regions(d, d->arch.vgic.cbase + PAGE_SIZE,
-                               d->arch.vgic.cbase + (2 * PAGE_SIZE) - 1,
-                               gic.vbase + PAGE_SIZE);
+        ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
+                               paddr_to_pfn_aligned(d->arch.vgic.cbase +
+                                                    (2 * PAGE_SIZE)),
+                               paddr_to_pfn(gic.vbase + PAGE_SIZE));
     else
-        ret = map_mmio_regions(d, d->arch.vgic.cbase + PAGE_SIZE,
-                               d->arch.vgic.cbase + (2 * PAGE_SIZE) - 1,
-                               gic.vbase + 16*PAGE_SIZE);
+        ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
+                               paddr_to_pfn_aligned(d->arch.vgic.cbase +
+			                            (2 * PAGE_SIZE)),
+                               paddr_to_pfn(gic.vbase + 16*PAGE_SIZE));
 
     return ret;
 
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 7cb4a27..c474707 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -553,12 +553,15 @@ int p2m_populate_ram(struct domain *d,
 }
 
 int map_mmio_regions(struct domain *d,
-                     paddr_t start_gaddr,
-                     paddr_t end_gaddr,
-                     paddr_t maddr)
+                     unsigned long start_gfn,
+                     unsigned long end_gfn,
+                     unsigned long mfn)
 {
-    return apply_p2m_changes(d, INSERT, start_gaddr, end_gaddr,
-                             maddr, MATTR_DEV, p2m_mmio_direct);
+    return apply_p2m_changes(d, INSERT,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(end_gfn),
+                             pfn_to_paddr(mfn),
+                             MATTR_DEV, p2m_mmio_direct);
 }
 
 int guest_physmap_add_entry(struct domain *d,
diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index 65e584f..078b020 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -54,13 +54,14 @@ static int exynos5_init_time(void)
 static int exynos5_specific_mapping(struct domain *d)
 {
     /* Map the chip ID */
-    map_mmio_regions(d, EXYNOS5_PA_CHIPID, EXYNOS5_PA_CHIPID + PAGE_SIZE - 1,
-                     EXYNOS5_PA_CHIPID);
+    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_CHIPID),
+                     paddr_to_pfn_aligned(EXYNOS5_PA_CHIPID + PAGE_SIZE),
+                     paddr_to_pfn(EXYNOS5_PA_CHIPID));
 
     /* Map the PWM region */
-    map_mmio_regions(d, EXYNOS5_PA_TIMER,
-                     EXYNOS5_PA_TIMER + (PAGE_SIZE * 2) - 1,
-                     EXYNOS5_PA_TIMER);
+    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_TIMER),
+                     paddr_to_pfn_aligned(EXYNOS5_PA_TIMER + (PAGE_SIZE * 2)),
+                     paddr_to_pfn(EXYNOS5_PA_TIMER));
 
     return 0;
 }
diff --git a/xen/arch/arm/platforms/omap5.c b/xen/arch/arm/platforms/omap5.c
index 76d4d9b..f51810e 100644
--- a/xen/arch/arm/platforms/omap5.c
+++ b/xen/arch/arm/platforms/omap5.c
@@ -102,21 +102,24 @@ static int omap5_init_time(void)
 static int omap5_specific_mapping(struct domain *d)
 {
     /* Map the PRM module */
-    map_mmio_regions(d, OMAP5_PRM_BASE, OMAP5_PRM_BASE + (PAGE_SIZE * 2) - 1,
-                     OMAP5_PRM_BASE);
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRM_BASE),
+                     paddr_to_pfn_aligned(OMAP5_PRM_BASE + (PAGE_SIZE * 2)),
+                     paddr_to_pfn(OMAP5_PRM_BASE));
 
     /* Map the PRM_MPU */
-    map_mmio_regions(d, OMAP5_PRCM_MPU_BASE,
-                     OMAP5_PRCM_MPU_BASE + PAGE_SIZE - 1,
-                     OMAP5_PRCM_MPU_BASE);
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRCM_MPU_BASE),
+                     paddr_to_pfn_aligned(OMAP5_PRCM_MPU_BASE + PAGE_SIZE),
+                     paddr_to_pfn(OMAP5_PRCM_MPU_BASE));
 
     /* Map the Wakeup Gen */
-    map_mmio_regions(d, OMAP5_WKUPGEN_BASE, OMAP5_WKUPGEN_BASE + PAGE_SIZE - 1,
-                     OMAP5_WKUPGEN_BASE);
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_WKUPGEN_BASE),
+                     paddr_to_pfn_aligned(OMAP5_WKUPGEN_BASE + PAGE_SIZE),
+                     paddr_to_pfn(OMAP5_WKUPGEN_BASE));
 
     /* Map the on-chip SRAM */
-    map_mmio_regions(d, OMAP5_SRAM_PA, OMAP5_SRAM_PA + (PAGE_SIZE * 32) - 1,
-                     OMAP5_SRAM_PA);
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_SRAM_PA),
+                     paddr_to_pfn_aligned(OMAP5_SRAM_PA + (PAGE_SIZE * 32)),
+                     paddr_to_pfn(OMAP5_SRAM_PA));
 
     return 0;
 }
diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
index c9dd63c..4945906 100644
--- a/xen/arch/arm/platforms/xgene-storm.c
+++ b/xen/arch/arm/platforms/xgene-storm.c
@@ -47,7 +47,9 @@ static int map_one_mmio(struct domain *d, const char *what,
 
     printk("Additional MMIO %"PRIpaddr"-%"PRIpaddr" (%s)\n",
            start, end, what);
-    ret = map_mmio_regions(d, start, end, start);
+    ret = map_mmio_regions(d, paddr_to_pfn(start),
+                           paddr_to_pfn_aligned(end),
+                           paddr_to_pfn(start));
     if ( ret )
         printk("Failed to map %s @ %"PRIpaddr" to dom%d\n",
                what, start, d->domain_id);
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index 2552d34..9fa80a4 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -210,6 +210,8 @@ static inline void __iomem *ioremap_wc(paddr_t start, size_t len)
 #define paddr_to_pfn(pa)  ((unsigned long)((pa) >> PAGE_SHIFT))
 #define paddr_to_pdx(pa)    pfn_to_pdx(paddr_to_pfn(pa))
 
+/* Page-align address and convert to frame number format */
+#define paddr_to_pfn_aligned(paddr)    paddr_to_pfn(PAGE_ALIGN(paddr))
 
 static inline paddr_t __virt_to_maddr(vaddr_t va)
 {
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 911d32d..a9168fc 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -87,11 +87,12 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
 
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
-/* Map MMIO regions in the p2m: start_gaddr and end_gaddr is the range
- * in the guest physical address space to map, starting from the machine
- * address maddr. */
-int map_mmio_regions(struct domain *d, paddr_t start_gaddr,
-                     paddr_t end_gaddr, paddr_t maddr);
+/* Map MMIO regions in the p2m: start_gfn and end_gfn is the range in the guest
+ * physical address space to map, starting from the machine frame number mfn. */
+int map_mmio_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long end_gfn,
+                     unsigned long mfn);
 
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 03/14] arch/arm: let map_mmio_regions() use start and count
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions Arianna Avanzini
                   ` (11 subsequent siblings)
  14 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the arguments given to the function map_mmio_regions() to
describe the memory range to be mapped are the start and end page frame
numbers of the range to be mapped. However, this could give rise to
issues due to the range being inclusive or exclusive of the end gfn
given as parameter. This commit changes the interface of the function
to accept the start gfn and the number of gfns to be mapped.
This commit also changes the interface of the function map_one_mmio(),
helper for the xgene-storm platform, which is a wrapper for the function
map_mmio_regions() and does not need its arguments to be paddr_t.

NOTE: platform-specific code has not been tested, save for the
      sunxi and the Arndale Exynos 5 platforms (see the Tested-by
      below for the latter).

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>
Tested-by: Julien Grall <julien.grall@citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v8:
        - Fix incorrect count used by map_mmio_regions() when calling
          apply_p2m_changes().
        - Use pfns as arguments to map_one_mmio().
        - Use the DIV_ROUND_UP() macro when appropriate.

---
 xen/arch/arm/domain_build.c          |  2 +-
 xen/arch/arm/gic.c                   | 11 +++--------
 xen/arch/arm/p2m.c                   |  4 ++--
 xen/arch/arm/platforms/exynos5.c     |  6 ++----
 xen/arch/arm/platforms/omap5.c       | 12 ++++--------
 xen/arch/arm/platforms/xgene-storm.c | 18 ++++++++++--------
 xen/include/asm-arm/p2m.h            |  7 ++++---
 7 files changed, 26 insertions(+), 34 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 6300fe3..c3783cf 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -776,7 +776,7 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
         }
         res = map_mmio_regions(d,
                                paddr_to_pfn(addr & PAGE_MASK),
-                               paddr_to_pfn_aligned(addr + size),
+                               DIV_ROUND_UP(size, PAGE_SIZE),
                                paddr_to_pfn(addr & PAGE_MASK));
         if ( res )
         {
diff --git a/xen/arch/arm/gic.c b/xen/arch/arm/gic.c
index 34b1070..cb015a6 100644
--- a/xen/arch/arm/gic.c
+++ b/xen/arch/arm/gic.c
@@ -912,22 +912,17 @@ int gicv_setup(struct domain *d)
      * The second page is always mapped at +4K irrespective of the
      * GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
      */
-    ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase),
-                           paddr_to_pfn_aligned(d->arch.vgic.cbase + PAGE_SIZE),
+    ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase), 1,
                            paddr_to_pfn(gic.vbase));
     if (ret)
         return ret;
 
     if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
         ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
-                               paddr_to_pfn_aligned(d->arch.vgic.cbase +
-                                                    (2 * PAGE_SIZE)),
-                               paddr_to_pfn(gic.vbase + PAGE_SIZE));
+                               2, paddr_to_pfn(gic.vbase + PAGE_SIZE));
     else
         ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
-                               paddr_to_pfn_aligned(d->arch.vgic.cbase +
-			                            (2 * PAGE_SIZE)),
-                               paddr_to_pfn(gic.vbase + 16*PAGE_SIZE));
+                               2, paddr_to_pfn(gic.vbase + 16*PAGE_SIZE));
 
     return ret;
 
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index c474707..22646e9 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -554,12 +554,12 @@ int p2m_populate_ram(struct domain *d,
 
 int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
-                     unsigned long end_gfn,
+                     unsigned long nr_mfns,
                      unsigned long mfn)
 {
     return apply_p2m_changes(d, INSERT,
                              pfn_to_paddr(start_gfn),
-                             pfn_to_paddr(end_gfn),
+                             pfn_to_paddr(start_gfn + nr_mfns),
                              pfn_to_paddr(mfn),
                              MATTR_DEV, p2m_mmio_direct);
 }
diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index 078b020..b65c2c2 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -54,13 +54,11 @@ static int exynos5_init_time(void)
 static int exynos5_specific_mapping(struct domain *d)
 {
     /* Map the chip ID */
-    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_CHIPID),
-                     paddr_to_pfn_aligned(EXYNOS5_PA_CHIPID + PAGE_SIZE),
+    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_CHIPID), 1,
                      paddr_to_pfn(EXYNOS5_PA_CHIPID));
 
     /* Map the PWM region */
-    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_TIMER),
-                     paddr_to_pfn_aligned(EXYNOS5_PA_TIMER + (PAGE_SIZE * 2)),
+    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_TIMER), 2,
                      paddr_to_pfn(EXYNOS5_PA_TIMER));
 
     return 0;
diff --git a/xen/arch/arm/platforms/omap5.c b/xen/arch/arm/platforms/omap5.c
index f51810e..a47c1cc 100644
--- a/xen/arch/arm/platforms/omap5.c
+++ b/xen/arch/arm/platforms/omap5.c
@@ -102,23 +102,19 @@ static int omap5_init_time(void)
 static int omap5_specific_mapping(struct domain *d)
 {
     /* Map the PRM module */
-    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRM_BASE),
-                     paddr_to_pfn_aligned(OMAP5_PRM_BASE + (PAGE_SIZE * 2)),
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRM_BASE), 2,
                      paddr_to_pfn(OMAP5_PRM_BASE));
 
     /* Map the PRM_MPU */
-    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRCM_MPU_BASE),
-                     paddr_to_pfn_aligned(OMAP5_PRCM_MPU_BASE + PAGE_SIZE),
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRCM_MPU_BASE), 1,
                      paddr_to_pfn(OMAP5_PRCM_MPU_BASE));
 
     /* Map the Wakeup Gen */
-    map_mmio_regions(d, paddr_to_pfn(OMAP5_WKUPGEN_BASE),
-                     paddr_to_pfn_aligned(OMAP5_WKUPGEN_BASE + PAGE_SIZE),
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_WKUPGEN_BASE), 1,
                      paddr_to_pfn(OMAP5_WKUPGEN_BASE));
 
     /* Map the on-chip SRAM */
-    map_mmio_regions(d, paddr_to_pfn(OMAP5_SRAM_PA),
-                     paddr_to_pfn_aligned(OMAP5_SRAM_PA + (PAGE_SIZE * 32)),
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_SRAM_PA), 32,
                      paddr_to_pfn(OMAP5_SRAM_PA));
 
     return 0;
diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
index 4945906..b524501 100644
--- a/xen/arch/arm/platforms/xgene-storm.c
+++ b/xen/arch/arm/platforms/xgene-storm.c
@@ -41,15 +41,13 @@ static uint32_t xgene_storm_quirks(void)
 }
 
 static int map_one_mmio(struct domain *d, const char *what,
-                         paddr_t start, paddr_t end)
+                         unsigned long start, unsigned long end)
 {
     int ret;
 
     printk("Additional MMIO %"PRIpaddr"-%"PRIpaddr" (%s)\n",
            start, end, what);
-    ret = map_mmio_regions(d, paddr_to_pfn(start),
-                           paddr_to_pfn_aligned(end),
-                           paddr_to_pfn(start));
+    ret = map_mmio_regions(d, start, end, end - start + 1, start);
     if ( ret )
         printk("Failed to map %s @ %"PRIpaddr" to dom%d\n",
                what, start, d->domain_id);
@@ -91,18 +89,22 @@ static int xgene_storm_specific_mapping(struct domain *d)
     int ret;
 
     /* Map the PCIe bus resources */
-    ret = map_one_mmio(d, "PCI MEM REGION", 0xe000000000UL, 0xe010000000UL);
+    ret = map_one_mmio(d, "PCI MEM REGION", paddr_to_pfn(0xe000000000UL),
+                                            paddr_to_pfn(0xe010000000UL));
     if ( ret )
         goto err;
 
-    ret = map_one_mmio(d, "PCI IO REGION", 0xe080000000UL, 0xe080010000UL);
+    ret = map_one_mmio(d, "PCI IO REGION", paddr_to_pfn(0xe080000000UL),
+                                           paddr_to_pfn(0xe080010000UL));
     if ( ret )
         goto err;
 
-    ret = map_one_mmio(d, "PCI CFG REGION", 0xe0d0000000UL, 0xe0d0200000UL);
+    ret = map_one_mmio(d, "PCI CFG REGION", paddr_to_pfn(0xe0d0000000UL),
+                                            paddr_to_pfn(0xe0d0200000UL));
     if ( ret )
         goto err;
-    ret = map_one_mmio(d, "PCI MSI REGION", 0xe010000000UL, 0xe010800000UL);
+    ret = map_one_mmio(d, "PCI MSI REGION", paddr_to_pfn(0xe010000000UL),
+                                            paddr_to_pfn(0xe010800000UL));
     if ( ret )
         goto err;
 
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index a9168fc..0ef396c 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -87,11 +87,12 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
 
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
-/* Map MMIO regions in the p2m: start_gfn and end_gfn is the range in the guest
- * physical address space to map, starting from the machine frame number mfn. */
+/* Map MMIO regions in the p2m: start_gfn and nr_mfns describe the range
+ * in the guest physical address space to map, starting from the machine
+ * frame number mfn. */
 int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
-                     unsigned long end_gfn,
+                     unsigned long nr_mfns,
                      unsigned long mfn);
 
 int guest_physmap_add_entry(struct domain *d,
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (2 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 03/14] arch/arm: let map_mmio_regions() use start and count Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-03 14:40   ` Ian Campbell
  2014-07-02 18:42 ` [PATCH v9 05/14] arch/x86: warn if to-be-removed mapping does not exist Arianna Avanzini
                   ` (10 subsequent siblings)
  14 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit changes the function apply_p2m_changes() to unwind changes
performed while mapping an I/O-memory region, if errors are seen during
the operation. This is useful to avoid that I/O-memory areas are
partially accessible to guests.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Let apply_p2m_ranges() unwind its own progress instead of relying on
          the caller to unmap partially-mapped I/O-memory regions.

---
 xen/arch/arm/p2m.c | 16 ++++++++++++----
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 22646e9..92fc4ec 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -314,7 +314,7 @@ static int apply_p2m_changes(struct domain *d,
     unsigned long cur_first_page = ~0,
                   cur_first_offset = ~0,
                   cur_second_offset = ~0;
-    unsigned long count = 0;
+    unsigned long count = 0, inserted = 0;
     unsigned int flush = 0;
     bool_t populate = (op == INSERT || op == ALLOCATE);
     lpae_t pte;
@@ -328,6 +328,7 @@ static int apply_p2m_changes(struct domain *d,
 
     spin_lock(&p2m->lock);
 
+unwind:
     addr = start_gpaddr;
     while ( addr < end_gpaddr )
     {
@@ -338,7 +339,9 @@ static int apply_p2m_changes(struct domain *d,
             if ( !first )
             {
                 rc = -EINVAL;
-                goto out;
+                end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;
+                op = REMOVE;
+                goto unwind;
             }
             cur_first_page = p2m_first_level_index(addr);
         }
@@ -357,7 +360,9 @@ static int apply_p2m_changes(struct domain *d,
             if ( rc < 0 )
             {
                 printk("p2m_populate_ram: L1 failed\n");
-                goto out;
+                end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;
+                op = REMOVE;
+                goto unwind;
             }
         }
 
@@ -384,7 +389,9 @@ static int apply_p2m_changes(struct domain *d,
                                   flush_pt);
             if ( rc < 0 ) {
                 printk("p2m_populate_ram: L2 failed\n");
-                goto out;
+                end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;
+                op = REMOVE;
+                goto unwind;
             }
         }
 
@@ -441,6 +448,7 @@ static int apply_p2m_changes(struct domain *d,
                     pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr, t);
                     p2m_write_pte(&third[third_table_offset(addr)],
                                   pte, flush_pt);
+                    inserted++;
                 }
                 break;
             case REMOVE:
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 05/14] arch/x86: warn if to-be-removed mapping does not exist
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (3 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 06/14] arch/x86: cleanup memory_mapping DOMCTL Arianna Avanzini
                   ` (9 subsequent siblings)
  14 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, when a memory mapping is removed with the memory_mapping
DOMCTL, no check is performed on the existence of such a mapping.
This commit adds such a consistency check to the code performing the
unmap, emitting a warning message if the check fails.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v8:
        - Fix commit description and subject to better fit the contents of
          the patch.
        - Remove tentative phrases from commit description.

    v7:
        - Do not fail with an error when attempting to remove a non-existent
          mapping: just emit a warning.

---
 xen/arch/x86/domctl.c     |  4 ++--
 xen/arch/x86/mm/p2m.c     | 12 ++++++++----
 xen/include/asm-x86/p2m.h |  2 +-
 3 files changed, 11 insertions(+), 7 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index a4effc3..4184f92 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -679,7 +679,7 @@ long arch_do_domctl(
                            "memory_map:fail: dom%d gfn=%lx mfn=%lx ret:%ld\n",
                            d->domain_id, gfn + i, mfn + i, ret);
                     while ( i-- )
-                        clear_mmio_p2m_entry(d, gfn + i);
+                        clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
                     if ( iomem_deny_access(d, mfn, mfn + nr_mfns - 1) &&
                          is_hardware_domain(current->domain) )
                         printk(XENLOG_ERR
@@ -699,7 +699,7 @@ long arch_do_domctl(
             if ( paging_mode_translate(d) )
                 for ( i = 0; i < nr_mfns; i++ )
                 {
-                    ret = clear_mmio_p2m_entry(d, gfn + i);
+                    ret = clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
                     if ( ret )
                         tmp_rc = ret;
                 }
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 642ec28..f5feb70 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -859,10 +859,10 @@ int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
 }
 
 /* Returns: 0 for success, -errno for failure */
-int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn)
+int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
 {
     int rc = -EINVAL;
-    mfn_t mfn;
+    mfn_t actual_mfn;
     p2m_access_t a;
     p2m_type_t t;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
@@ -871,15 +871,19 @@ int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn)
         return -EIO;
 
     gfn_lock(p2m, gfn, 0);
-    mfn = p2m->get_entry(p2m, gfn, &t, &a, 0, NULL);
+    actual_mfn = p2m->get_entry(p2m, gfn, &t, &a, 0, NULL);
 
     /* Do not use mfn_valid() here as it will usually fail for MMIO pages. */
-    if ( (INVALID_MFN == mfn_x(mfn)) || (t != p2m_mmio_direct) )
+    if ( (INVALID_MFN == mfn_x(actual_mfn)) || (t != p2m_mmio_direct) )
     {
         gdprintk(XENLOG_ERR,
                  "gfn_to_mfn failed! gfn=%08lx type:%d\n", gfn, t);
         goto out;
     }
+    if ( mfn_x(mfn) != mfn_x(actual_mfn) )
+        gdprintk(XENLOG_WARNING,
+                 "no mapping between mfn %08lx and gfn %08lx\n",
+                 mfn_x(mfn), gfn);
     rc = p2m_set_entry(p2m, gfn, _mfn(INVALID_MFN), PAGE_ORDER_4K, p2m_invalid,
                        p2m->default_access);
 
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 0ddbadb..5ab7cb4 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -534,7 +534,7 @@ int p2m_is_logdirty_range(struct p2m_domain *, unsigned long start,
 
 /* Set mmio addresses in the p2m table (for pass-through) */
 int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
-int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn);
+int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
 
 /* Add foreign mapping to the guest's p2m table. */
 int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 06/14] arch/x86: cleanup memory_mapping DOMCTL
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (4 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 05/14] arch/x86: warn if to-be-removed mapping does not exist Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 07/14] xen/common: add ARM stub for the function memory_type_changed() Arianna Avanzini
                   ` (8 subsequent siblings)
  14 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit lets the end mfn be computed only once while handling a
XEN_DOMCTL_memory_mapping hypercall. Also, the name of the tmp_rc
local variable is changed to rc.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Jan Beulich <JBeulich@suse.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
---
 xen/arch/x86/domctl.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 4184f92..5674029 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -646,19 +646,20 @@ long arch_do_domctl(
         unsigned long gfn = domctl->u.memory_mapping.first_gfn;
         unsigned long mfn = domctl->u.memory_mapping.first_mfn;
         unsigned long nr_mfns = domctl->u.memory_mapping.nr_mfns;
+        unsigned long mfn_end = mfn + nr_mfns - 1;
         int add = domctl->u.memory_mapping.add_mapping;
 
         ret = -EINVAL;
-        if ( (mfn + nr_mfns - 1) < mfn || /* wrap? */
-             ((mfn | (mfn + nr_mfns - 1)) >> (paddr_bits - PAGE_SHIFT)) ||
+        if ( mfn_end < mfn || /* wrap? */
+             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
              (gfn + nr_mfns - 1) < gfn ) /* wrap? */
             break;
 
         ret = -EPERM;
-        if ( !iomem_access_permitted(current->domain, mfn, mfn + nr_mfns - 1) )
+        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
             break;
 
-        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, add);
+        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
         if ( ret )
             break;
 
@@ -668,7 +669,7 @@ long arch_do_domctl(
                    "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
                    d->domain_id, gfn, mfn, nr_mfns);
 
-            ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
+            ret = iomem_permit_access(d, mfn, mfn_end);
             if ( !ret && paging_mode_translate(d) )
             {
                 for ( i = 0; !ret && i < nr_mfns; i++ )
@@ -680,17 +681,17 @@ long arch_do_domctl(
                            d->domain_id, gfn + i, mfn + i, ret);
                     while ( i-- )
                         clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
-                    if ( iomem_deny_access(d, mfn, mfn + nr_mfns - 1) &&
+                    if ( iomem_deny_access(d, mfn, mfn_end) &&
                          is_hardware_domain(current->domain) )
                         printk(XENLOG_ERR
                                "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
-                               d->domain_id, mfn, mfn + nr_mfns - 1);
+                               d->domain_id, mfn, mfn_end);
                 }
             }
         }
         else
         {
-            int tmp_rc = 0;
+            int rc = 0;
 
             printk(XENLOG_G_INFO
                    "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
@@ -701,16 +702,16 @@ long arch_do_domctl(
                 {
                     ret = clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
                     if ( ret )
-                        tmp_rc = ret;
+                        rc = ret;
                 }
-            ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
+            ret = iomem_deny_access(d, mfn, mfn_end);
             if ( !ret )
-                ret = tmp_rc;
+                ret = rc;
             if ( ret && is_hardware_domain(current->domain) )
                 printk(XENLOG_ERR
                        "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
-                       ret, tmp_rc ? "removing" : "denying", d->domain_id,
-                       mfn, mfn + nr_mfns - 1);
+                       ret, rc ? "removing" : "denying", d->domain_id,
+                       mfn, mfn_end);
         }
         /* Do this unconditionally to cover errors on above failure paths. */
         memory_type_changed(d);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 07/14] xen/common: add ARM stub for the function memory_type_changed()
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (5 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 06/14] arch/x86: cleanup memory_mapping DOMCTL Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-03 14:41   ` Ian Campbell
  2014-07-02 18:42 ` [PATCH v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL Arianna Avanzini
                   ` (7 subsequent siblings)
  14 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

MTRR-related code is not available for the ARM architecture. Given
that the memory_type_changed() function would be called also from
common code, its invocation is currently ifdef'd out to be only
compiled in on an x86 machine. This commit adds an empty stub for ARM.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Don't expose the memory_type_changed() function to common code,
          just add an empty stub in arch/arm/p2m.c and in the related header
          for ARM.

---
 xen/arch/arm/p2m.c        | 4 ++++
 xen/common/domctl.c       | 2 --
 xen/include/asm-arm/p2m.h | 2 ++
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 92fc4ec..1b87a4e 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -14,6 +14,10 @@
 #define P2M_FIRST_ORDER 1
 #define P2M_FIRST_ENTRIES (LPAE_ENTRIES<<P2M_FIRST_ORDER)
 
+void memory_type_changed(struct domain *d)
+{
+}
+
 void dump_p2m_lookup(struct domain *d, paddr_t addr)
 {
     struct p2m_domain *p2m = &d->arch.p2m;
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 000993f..afcd9bc 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -905,10 +905,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
         else
             ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
-#ifdef CONFIG_X86
         if ( !ret )
             memory_type_changed(d);
-#endif
     }
     break;
 
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 0ef396c..0ee7cb2 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -5,6 +5,8 @@
 
 struct domain;
 
+extern void memory_type_changed(struct domain *);
+
 /* Per-p2m-table state */
 struct p2m_domain {
     /* Lock that protects updates to the p2m */
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (6 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 07/14] xen/common: add ARM stub for the function memory_type_changed() Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-03 10:43   ` Jan Beulich
  2014-07-02 18:42 ` [PATCH v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code Arianna Avanzini
                   ` (6 subsequent siblings)
  14 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit factors out from the XEN_DOMCTL_memory_mapping hypercall
implementation, currently available only for x86, the operations
related to memory ranges map and unmap. The code is factored out
into two {map|unmap}_mmio_regions() functions for x86, that will match
the corresponding pair of ARM functions when the DOMCTL will be moved
to common code in the following commit. This commit also adds an
unmap_mmio_regions() function for ARM so that the following transition
to common code is cleaner.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Don't ignore an error if it doesn't happen while unmapping the last
          I/O-memory mapping in unmap_mmio_regions() for x86.
        - Fix wrong argument in the call to unmap_mmio_regions() performed on
          failure by map_mmio_regions() for x86.
        - Explicitly specify nr_mfns in the commit message emitted when the
          function map_mmio_regions() fails in the DOMCTL handling code.
        - Change "nr_mfns" to "nr" in the arch-specific map/unmap functions
          for x86.

    v8:
        - Latch the ret variable in {map|unmap}_mmio_regions() to the
          first or last errors encountered during mapping or unmapping
          operations.
        - Separate cleanup-related changes from refactoring ones.
        - Use correct count in unmap_mmio_regions().

    v7:
        - Use unmap_mmio_regions() for the error recovery path in
          map_mmio_regions().
        - Fix wrong use of memory-handling functions.
        - Use mfn_t as last parameter to {map|unmap}_mmio_regions().
        - Don't split format strings.
        - Remove spurious changes, such as those to already-existing format
          strings that are not necessary.

    v6:
        - Fix uncorrect usage of [mg]fn_end which, in the initial checks,
          was subtracted 1 twice.
        - Pass p2m_invalid as last parameter to unmap_mmio_regions() for ARM
          as it is not (and currently must not be) used.
        - Remove useless comment about the handling of errors in the
          remove path of the hypercall.
        - Replace stray hard tab with spaces.

    v5:
        - Let the unmap_mmio_regions() function for x86 return a proper
          error code upon failure.
        - Restore correct handling of errors in the remove path of the
          hypercall, assigning to the "ret" local variable the error
          code returned by the unmap_mmio_regions() function only if
          iomem_deny_access() didn't return with an error.
        - Compute gfn_end - 1 and mfn_end - 1 only once in the DOMCTL.
        - Use a local variable to keep the return value of the function
          unmap_mmio_regions() instead of re-using the "add" variable.
        - Add a comment to make hopefully clearer how error values of
          functions are handled in the remove path of the DOMCTL.

    v4:
        - Fix type and signedness of local variables used as indexes in
          map_mmio_regions() and unmap_mmio_regions() for x86.
        - Clear p2m entries in map_mmio_regions() for x86 only if
          set_mmio_p2m_entry() returned with an error.
        - Make ranges inclusive of the end address in map_mmio_regions()
          and unmap_mmio_regions() for x86.
        - Turn hard tabs into spaces.

    v3:
        - Add map_mmio_regions() and unmap_mmio_regions() functions for x86;
        - Use pfn as parameters to the unmap_mmio_regions() function.
        - Compute gfn + nr_mfns and mfn + nr_mfns only once.

    v2:
        - Use the already-defined PADDR_BITS constant in the new DOMCTL.
        - Use paddr_t as arguments to the map_mmio_regions() function.
        - Page-align addresses given as arguments to map_mmio_regions() and
          unmap_mmio_regions().

---
 xen/arch/arm/p2m.c        | 12 ++++++++++++
 xen/arch/x86/domctl.c     | 19 +++++--------------
 xen/arch/x86/mm/p2m.c     | 43 +++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/p2m.h |  4 ++++
 xen/include/asm-x86/p2m.h | 12 ++++++++++++
 5 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 1b87a4e..47b7682 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -576,6 +576,18 @@ int map_mmio_regions(struct domain *d,
                              MATTR_DEV, p2m_mmio_direct);
 }
 
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr_mfns,
+                       unsigned long mfn)
+{
+    return apply_p2m_changes(d, REMOVE,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(start_gfn + nr_mfns),
+                             pfn_to_paddr(mfn),
+                             MATTR_DEV, p2m_invalid);
+}
+
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gpfn,
                             unsigned long mfn,
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 5674029..1947f77 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -670,17 +670,14 @@ long arch_do_domctl(
                    d->domain_id, gfn, mfn, nr_mfns);
 
             ret = iomem_permit_access(d, mfn, mfn_end);
-            if ( !ret && paging_mode_translate(d) )
+            if ( !ret )
             {
-                for ( i = 0; !ret && i < nr_mfns; i++ )
-                    ret = set_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
+                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
                 if ( ret )
                 {
                     printk(XENLOG_G_WARNING
-                           "memory_map:fail: dom%d gfn=%lx mfn=%lx ret:%ld\n",
-                           d->domain_id, gfn + i, mfn + i, ret);
-                    while ( i-- )
-                        clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
+                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
+                           d->domain_id, gfn, mfn, nr_mfns, ret);
                     if ( iomem_deny_access(d, mfn, mfn_end) &&
                          is_hardware_domain(current->domain) )
                         printk(XENLOG_ERR
@@ -697,13 +694,7 @@ long arch_do_domctl(
                    "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
                    d->domain_id, gfn, mfn, nr_mfns);
 
-            if ( paging_mode_translate(d) )
-                for ( i = 0; i < nr_mfns; i++ )
-                {
-                    ret = clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
-                    if ( ret )
-                        rc = ret;
-                }
+            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
             ret = iomem_deny_access(d, mfn, mfn_end);
             if ( !ret )
                 ret = rc;
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index f5feb70..29df616 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1704,6 +1704,49 @@ unsigned long paging_gva_to_gfn(struct vcpu *v,
     return hostmode->gva_to_gfn(v, hostp2m, va, pfec);
 }
 
+int map_mmio_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long nr,
+                     unsigned long mfn)
+{
+    int ret = 0;
+    unsigned long i;
+
+    if ( !paging_mode_translate(d) )
+        return 0;
+
+    for ( i = 0; !ret && i < nr; i++ )
+    {
+        ret = set_mmio_p2m_entry(d, start_gfn + i, _mfn(mfn + i));
+        if ( ret )
+        {
+            unmap_mmio_regions(d, start_gfn, i, mfn);
+            break;
+        }
+    }
+
+    return ret;
+}
+
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr,
+                       unsigned long mfn)
+{
+    int ret = 0, err = 0;
+    unsigned long i;
+
+    if ( !paging_mode_translate(d) )
+        return 0;
+
+    for ( i = 0; i < nr; i++ ) {
+        ret = clear_mmio_p2m_entry(d, start_gfn + i, _mfn(mfn + i));
+        if ( ret ) err = ret;
+    }
+
+    return err;
+}
+
 /*** Audit ***/
 
 #if P2M_AUDIT
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 0ee7cb2..d0840a5 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -96,6 +96,10 @@ int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
                      unsigned long nr_mfns,
                      unsigned long mfn);
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr_mfns,
+                       unsigned long mfn);
 
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 5ab7cb4..cea46e1 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -32,6 +32,18 @@
 #include <asm/mem_sharing.h>
 #include <asm/page.h>    /* for pagetable_t */
 
+/* Map MMIO regions in the p2m: start_gfn and nr describe the range in
+ * the guest physical address space to map, starting from the machine
+ * frame number mfn. */
+int map_mmio_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long nr,
+                     unsigned long mfn);
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr,
+                       unsigned long mfn);
+
 extern bool_t opt_hap_1gb, opt_hap_2mb;
 
 /*
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (7 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 10/14] tools/libxl: parse optional start gfn from the iomem config option Arianna Avanzini
                   ` (5 subsequent siblings)
  14 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit moves to common code the implementation of the memory_mapping
DOMCTL, currently available only for the x86 architecture. It also adds
a definition for the PADDR_BITS constant for ARM, that is to be used in
common code and currently not available for the ARM architecture.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Jan Beulich <JBeulich@suse.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Don't expose the type mfn_t to common code; let the x86-specific map/
          unmap functions perform the type cast and use unsigned long in common
          code.

    v7:
        - Change the name of tmp_rc to rc. Also, do not uselessly initialize it.
        - ifdef out the invocation of memory_type_changed() to be called only
          if the architecture is x86 instead of adding an useless empty stub
          for ARM.

    v6:
        - Add an empty definition of the memory_type_changed() function for ARM.

    v5:
        - Rename new header to p2m-common.h.

    v4:
        - Use a define for paddr_bits instead of a new variable.
        - Define prototypes for common functions map_mmio_regions() and
          unmap_mmio_regions() only once in a common header.

    v3:
        - Add a paddr_bits variable for ARM.

    v2:
        - Move code to xen/arm/domctl.c.

---
 xen/arch/arm/p2m.c           |  8 +++---
 xen/arch/x86/domctl.c        | 68 --------------------------------------------
 xen/common/domctl.c          | 68 ++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/p2m.h    | 15 +++-------
 xen/include/asm-x86/p2m.h    | 13 +--------
 xen/include/xen/p2m-common.h | 16 +++++++++++
 6 files changed, 93 insertions(+), 95 deletions(-)
 create mode 100644 xen/include/xen/p2m-common.h

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 47b7682..f11f73d 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -566,24 +566,24 @@ int p2m_populate_ram(struct domain *d,
 
 int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
-                     unsigned long nr_mfns,
+                     unsigned long nr,
                      unsigned long mfn)
 {
     return apply_p2m_changes(d, INSERT,
                              pfn_to_paddr(start_gfn),
-                             pfn_to_paddr(start_gfn + nr_mfns),
+                             pfn_to_paddr(start_gfn + nr),
                              pfn_to_paddr(mfn),
                              MATTR_DEV, p2m_mmio_direct);
 }
 
 int unmap_mmio_regions(struct domain *d,
                        unsigned long start_gfn,
-                       unsigned long nr_mfns,
+                       unsigned long nr,
                        unsigned long mfn)
 {
     return apply_p2m_changes(d, REMOVE,
                              pfn_to_paddr(start_gfn),
-                             pfn_to_paddr(start_gfn + nr_mfns),
+                             pfn_to_paddr(start_gfn + nr),
                              pfn_to_paddr(mfn),
                              MATTR_DEV, p2m_invalid);
 }
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 1947f77..437ba11 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -641,74 +641,6 @@ long arch_do_domctl(
     }
     break;
 
-    case XEN_DOMCTL_memory_mapping:
-    {
-        unsigned long gfn = domctl->u.memory_mapping.first_gfn;
-        unsigned long mfn = domctl->u.memory_mapping.first_mfn;
-        unsigned long nr_mfns = domctl->u.memory_mapping.nr_mfns;
-        unsigned long mfn_end = mfn + nr_mfns - 1;
-        int add = domctl->u.memory_mapping.add_mapping;
-
-        ret = -EINVAL;
-        if ( mfn_end < mfn || /* wrap? */
-             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
-             (gfn + nr_mfns - 1) < gfn ) /* wrap? */
-            break;
-
-        ret = -EPERM;
-        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
-            break;
-
-        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
-        if ( ret )
-            break;
-
-        if ( add )
-        {
-            printk(XENLOG_G_INFO
-                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
-                   d->domain_id, gfn, mfn, nr_mfns);
-
-            ret = iomem_permit_access(d, mfn, mfn_end);
-            if ( !ret )
-            {
-                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
-                if ( ret )
-                {
-                    printk(XENLOG_G_WARNING
-                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
-                           d->domain_id, gfn, mfn, nr_mfns, ret);
-                    if ( iomem_deny_access(d, mfn, mfn_end) &&
-                         is_hardware_domain(current->domain) )
-                        printk(XENLOG_ERR
-                               "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
-                               d->domain_id, mfn, mfn_end);
-                }
-            }
-        }
-        else
-        {
-            int rc = 0;
-
-            printk(XENLOG_G_INFO
-                   "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
-                   d->domain_id, gfn, mfn, nr_mfns);
-
-            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
-            ret = iomem_deny_access(d, mfn, mfn_end);
-            if ( !ret )
-                ret = rc;
-            if ( ret && is_hardware_domain(current->domain) )
-                printk(XENLOG_ERR
-                       "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
-                       ret, rc ? "removing" : "denying", d->domain_id,
-                       mfn, mfn_end);
-        }
-        /* Do this unconditionally to cover errors on above failure paths. */
-        memory_type_changed(d);
-    }
-    break;
-
     case XEN_DOMCTL_ioport_mapping:
     {
         struct hvm_iommu *hd;
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index afcd9bc..abc8d60 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -910,6 +910,74 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
     }
     break;
 
+    case XEN_DOMCTL_memory_mapping:
+    {
+        unsigned long gfn = op->u.memory_mapping.first_gfn;
+        unsigned long mfn = op->u.memory_mapping.first_mfn;
+        unsigned long nr_mfns = op->u.memory_mapping.nr_mfns;
+        unsigned long mfn_end = mfn + nr_mfns - 1;
+        int add = op->u.memory_mapping.add_mapping;
+
+        ret = -EINVAL;
+        if ( mfn_end < mfn || /* wrap? */
+             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
+             (gfn + nr_mfns - 1) < gfn ) /* wrap? */
+            break;
+
+        ret = -EPERM;
+        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
+            break;
+
+        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
+        if ( ret )
+            break;
+
+        if ( add )
+        {
+            printk(XENLOG_G_INFO
+                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
+                   d->domain_id, gfn, mfn, nr_mfns);
+
+            ret = iomem_permit_access(d, mfn, mfn_end);
+            if ( !ret )
+            {
+                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
+                if ( ret )
+                {
+                    printk(XENLOG_G_WARNING
+                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
+                           d->domain_id, gfn, mfn, nr_mfns, ret);
+                    if ( iomem_deny_access(d, mfn, mfn_end) &&
+                         is_hardware_domain(current->domain) )
+                        printk(XENLOG_ERR
+                               "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
+                               d->domain_id, mfn, mfn_end);
+                }
+            }
+        }
+        else
+        {
+            int rc = 0;
+
+            printk(XENLOG_G_INFO
+                   "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
+                   d->domain_id, gfn, mfn, nr_mfns);
+
+            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
+            ret = iomem_deny_access(d, mfn, mfn_end);
+            if ( !ret )
+                ret = rc;
+            if ( ret && is_hardware_domain(current->domain) )
+                printk(XENLOG_ERR
+                       "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
+                       ret, rc ? "removing" : "denying", d->domain_id,
+                       mfn, mfn_end);
+        }
+        /* Do this unconditionally to cover errors on above failure paths. */
+        memory_type_changed(d);
+    }
+    break;
+
     case XEN_DOMCTL_settimeoffset:
     {
         domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index d0840a5..717fcc5 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -3,6 +3,10 @@
 
 #include <xen/mm.h>
 
+#include <xen/p2m-common.h>
+
+#define paddr_bits PADDR_BITS
+
 struct domain;
 
 extern void memory_type_changed(struct domain *);
@@ -89,17 +93,6 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
 
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
-/* Map MMIO regions in the p2m: start_gfn and nr_mfns describe the range
- * in the guest physical address space to map, starting from the machine
- * frame number mfn. */
-int map_mmio_regions(struct domain *d,
-                     unsigned long start_gfn,
-                     unsigned long nr_mfns,
-                     unsigned long mfn);
-int unmap_mmio_regions(struct domain *d,
-                       unsigned long start_gfn,
-                       unsigned long nr_mfns,
-                       unsigned long mfn);
 
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index cea46e1..2a65848 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -29,21 +29,10 @@
 
 #include <xen/config.h>
 #include <xen/paging.h>
+#include <xen/p2m-common.h>
 #include <asm/mem_sharing.h>
 #include <asm/page.h>    /* for pagetable_t */
 
-/* Map MMIO regions in the p2m: start_gfn and nr describe the range in
- * the guest physical address space to map, starting from the machine
- * frame number mfn. */
-int map_mmio_regions(struct domain *d,
-                     unsigned long start_gfn,
-                     unsigned long nr,
-                     unsigned long mfn);
-int unmap_mmio_regions(struct domain *d,
-                       unsigned long start_gfn,
-                       unsigned long nr,
-                       unsigned long mfn);
-
 extern bool_t opt_hap_1gb, opt_hap_2mb;
 
 /*
diff --git a/xen/include/xen/p2m-common.h b/xen/include/xen/p2m-common.h
new file mode 100644
index 0000000..9f1b771
--- /dev/null
+++ b/xen/include/xen/p2m-common.h
@@ -0,0 +1,16 @@
+#ifndef _XEN_P2M_COMMON_H
+#define _XEN_P2M_COMMON_H
+
+/* Map MMIO regions in the p2m: start_gfn and nr describe the range in
+ *  * the guest physical address space to map, starting from the machine
+ *   * frame number mfn. */
+int map_mmio_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long nr,
+                     unsigned long mfn);
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr,
+                       unsigned long mfn);
+
+#endif /* _XEN_P2M_COMMON_H */
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 10/14] tools/libxl: parse optional start gfn from the iomem config option
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (8 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall Arianna Avanzini
                   ` (4 subsequent siblings)
  14 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the "iomem" domU config option allows to specify a machine
address range to be mapped to the domU. However, there is no way to
specify the guest address range used for the mapping. This commit
extends the iomem option handling code to parse an additional, optional
parameter: this parameter, if given, specifies the start guest address
used for the mapping; if no start guest address is given, a 1:1 mapping
is performed as default.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>
Acked-by: Julien Grall <julien.grall@citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v7:
        - Use LIBXL_INVALID_GFN when needed.
        - Add to the manpage a note about the mapping defaulting to 1:1 when
          the gfn parameter is not specified, and about the option being for
          auto-translated guests.
        - Remove spurious change.

    v6:
        - Document what happens if the new "gfn" parameter is omitted
          while specifying the "iomem" option in the domain configuration.
        - Add LIBXL_INVALID_GFN macro with value "~(uint64_t)0".
        - Fix typo in the comment to the LIBXL_HAVE_BUILDINFO_IOMEM_START_GFN
          macro.

    v5:
        - Initialize the gfn field of the iomem structure with the
          value "(uint64_t)-1".
        - Defer the assignment of the value of "start" to "gfn", if
          "gfn" has been initialized to the default value, in libxl.
        - Use a local variable to keep the return value of sscanf()
          for better code readability.

    v4:
        - Add definition of a LIBXL_HAVE_BUILDINFO_IOMEM_START_GFN macro
          to indicate the availability of the new option.
        - Simplify the code parsing the new optional parameter by using
          the switch construct on the return value of the sscanf() function
          instead of calling the function twice.
        - Add a short paragraph to the manpage about the use of the iomem
          option to passthrough devices protected by an IOMMU.
        - Add comments to the fields of the "iomem" structure.

---
 docs/man/xl.cfg.pod.5        | 18 +++++++++++++-----
 tools/libxl/libxl.h          | 10 ++++++++++
 tools/libxl/libxl_create.c   |  6 ++++++
 tools/libxl/libxl_internal.h |  1 +
 tools/libxl/libxl_types.idl  |  4 ++++
 tools/libxl/xl_cmdimpl.c     | 17 ++++++++++-------
 6 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index c087cbc..025df27 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -610,12 +610,20 @@ is given in hexadecimal and may either a span e.g. C<2f8-2ff>
 It is recommended to use this option only for trusted VMs under
 administrator control.
 
-=item B<iomem=[ "IOMEM_START,NUM_PAGES", "IOMEM_START,NUM_PAGES", ... ]>
+=item B<iomem=[ "IOMEM_START,NUM_PAGES[@GFN]", "IOMEM_START,NUM_PAGES[@GFN]", ... ]>
 
-Allow guest to access specific hardware I/O memory pages. B<IOMEM_START>
-is a physical page number. B<NUM_PAGES> is the number
-of pages beginning with B<START_PAGE> to allow access. Both values
-must be given in hexadecimal.
+Allow auto-translated domains to access specific hardware I/O memory pages.
+
+B<IOMEM_START> is a physical page number. B<NUM_PAGES> is the number of pages
+beginning with B<START_PAGE> to allow access. B<GFN> specifies the guest frame
+number where the mapping will start in the domU's address space. If B<GFN> is
+not given, the mapping will be performed using B<IOMEM_START> as a start in the
+domU's address space, therefore performing an 1:1 mapping as default.
+All of these values must be given in hexadecimal.
+
+Note that the IOMMU won't be updated with the mappings specified with this
+option. This option therefore should not be used to passthrough any
+IOMMU-protected device.
 
 It is recommended to use this option only for trusted VMs under
 administrator control.
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 69ceac8..ce0d2c2 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -116,6 +116,16 @@
 #define LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_ENABLE 1
 
 /*
+ * LIBXL_HAVE_BUILDINFO_IOMEM_START_GFN indicates that it is possible
+ * to specify the start guest frame number used to map a range of I/O
+ * memory machine frame numbers via the 'gfn' field (of type uint64)
+ * of the 'iomem' structure. An array of iomem structures is embedded
+ * in libxl_domain_build_info and used to map the indicated memory
+ * ranges during domain build.
+ */
+#define LIBXL_HAVE_BUILDINFO_IOMEM_START_GFN 1
+
+/*
  * libxl ABI compatibility
  *
  * The only guarantee which libxl makes regarding ABI compatibility
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index d6b8a29..99dddc0 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -102,6 +102,8 @@ static int sched_params_valid(libxl__gc *gc,
 int libxl__domain_build_info_setdefault(libxl__gc *gc,
                                         libxl_domain_build_info *b_info)
 {
+    int i;
+
     if (b_info->type != LIBXL_DOMAIN_TYPE_HVM &&
         b_info->type != LIBXL_DOMAIN_TYPE_PV)
         return ERROR_INVAL;
@@ -212,6 +214,10 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
 
     libxl_defbool_setdefault(&b_info->disable_migrate, false);
 
+    for (i = 0 ; i < b_info->num_iomem; i++)
+        if (b_info->iomem[i].gfn == LIBXL_INVALID_GFN)
+            b_info->iomem[i].gfn = b_info->iomem[i].start;
+
     if (!b_info->event_channels)
         b_info->event_channels = 1023;
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index a0d4f24..60d6f1d 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -91,6 +91,7 @@
 #define LIBXL_PV_EXTRA_MEMORY 1024
 #define LIBXL_HVM_EXTRA_MEMORY 2048
 #define LIBXL_MIN_DOM0_MEM (128*1024)
+#define LIBXL_INVALID_GFN (~(uint64_t)0)
 /* use 0 as the domid of the toolstack domain for now */
 #define LIBXL_TOOLSTACK_DOMID 0
 #define QEMU_SIGNATURE "DeviceModelRecord0002"
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 1018142..e37e579 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -170,8 +170,12 @@ libxl_ioport_range = Struct("ioport_range", [
     ])
 
 libxl_iomem_range = Struct("iomem_range", [
+    # start host frame number to be mapped to the guest
     ("start", uint64),
+    # number of frames to be mapped
     ("number", uint64),
+    # guest frame number used as a start for the mapping
+    ("gfn", uint64, {'init_val': "LIBXL_INVALID_GFN"}),
     ])
 
 libxl_vga_interface_info = Struct("vga_interface_info", [
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index be041f2..513b404 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1139,6 +1139,7 @@ static void parse_config_data(const char *config_source,
     }
 
     if (!xlu_cfg_get_list(config, "iomem", &iomem, &num_iomem, 0)) {
+        int ret;
         b_info->num_iomem = num_iomem;
         b_info->iomem = calloc(num_iomem, sizeof(*b_info->iomem));
         if (b_info->iomem == NULL) {
@@ -1152,13 +1153,15 @@ static void parse_config_data(const char *config_source,
                         "xl: Unable to get element %d in iomem list\n", i);
                 exit(1);
             }
-            if(sscanf(buf, "%" SCNx64",%" SCNx64,
-                     &b_info->iomem[i].start,
-                     &b_info->iomem[i].number)
-                  != 2) {
-               fprintf(stderr,
-                       "xl: Invalid argument parsing iomem: %s\n", buf);
-               exit(1);
+            libxl_iomem_range_init(&b_info->iomem[i]);
+            ret = sscanf(buf, "%" SCNx64",%" SCNx64"@%" SCNx64,
+                         &b_info->iomem[i].start,
+                         &b_info->iomem[i].number,
+                         &b_info->iomem[i].gfn);
+            if (ret < 2) {
+                fprintf(stderr,
+                        "xl: Invalid argument parsing iomem: %s\n", buf);
+                exit(1);
             }
         }
     }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (9 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 10/14] tools/libxl: parse optional start gfn from the iomem config option Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU Arianna Avanzini
                   ` (3 subsequent siblings)
  14 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the configuration-parsing code concerning the handling of the
iomem parameter only invokes the XEN_DOMCTL_iomem_permission hypercall.
This commit lets the XEN_DOMCTL_memory_mapping hypercall be invoked
after XEN_DOMCTL_iomem_permission when the iomem parameter is parsed
from a domU configuration file, so that the address range can be mapped
to the address space of the domU. The hypercall is invoked only in case
of domains using an auto-translated physmap.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Enforce checks on return value of xc_domain_getinfo() as it could
          return information concerning the wrong domain.
        - Don't use PERROR for xc_core_* functions.
        - Avoid emitting an error message if xc_core_auto_translated_physmap()
          fails.

    v8:
        - Fix wrong error message emitted when the memory_mapping DOMCTL is
          called by a domain that is not auto-translated.

    v7:
        - Move the check for an auto-translated physmap to xc to avoid having
          to expose the information to libxl.

    v4:
        - Let the hypercall be called only in case the guest uses an
          auto-translated physmap.

    v3:
        - Add ifdefs to let the hypercall be called only by ARM or x86
          HVM guests, with a whitelist approach.
        - Remove the NOTE comment.

    v2:
        - Add a comment explaining outstanding issues.

---
 tools/libxc/xc_domain.c    | 10 ++++++++++
 tools/libxl/libxl_create.c | 11 +++++++++++
 2 files changed, 21 insertions(+)

diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index d5d6d12..e781be8 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -1922,6 +1922,16 @@ int xc_domain_memory_mapping(
     uint32_t add_mapping)
 {
     DECLARE_DOMCTL;
+    xc_dominfo_t info;
+
+    if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 ||
+         info.domid != domid )
+    {
+        PERROR("Could not get info for domain");
+        return -EINVAL;
+    }
+    if ( !xc_core_arch_auto_translated_physmap(&info) )
+        return 0;
 
     domctl.cmd = XEN_DOMCTL_memory_mapping;
     domctl.domain = domid;
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 99dddc0..b5506b1 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1176,6 +1176,17 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
                  "failed give dom%d access to iomem range %"PRIx64"-%"PRIx64,
                  domid, io->start, io->start + io->number - 1);
             ret = ERROR_FAIL;
+            continue;
+        }
+        ret = xc_domain_memory_mapping(CTX->xch, domid,
+                                       io->gfn, io->start,
+                                       io->number, 1);
+        if (ret < 0) {
+            LOGE(ERROR,
+                 "failed to map to dom%d iomem range %"PRIx64"-%"PRIx64
+                 " to guest address %"PRIx64,
+                 domid, io->start, io->start + io->number - 1, io->gfn);
+            ret = ERROR_FAIL;
         }
     }
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (10 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-02 19:00   ` Sander Eikelenboom
  2014-07-03 14:47   ` Ian Campbell
  2014-07-02 18:42 ` [PATCH v9 13/14] tools/libxl: explicitly grant access to needed I/O-memory ranges Arianna Avanzini
                   ` (2 subsequent siblings)
  14 siblings, 2 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit adds a new option available for any domU libxl
configuration that allows the user to specify if one of the
VGA adapters passed through to the domain is the primary one.
This way, libxl can arrange the correct I/O-memory access
permission for its stubdomain.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
---
 docs/man/xl.cfg.pod.5       | 7 +++++++
 tools/libxl/libxl.h         | 7 +++++++
 tools/libxl/libxl_create.c  | 1 +
 tools/libxl/libxl_types.idl | 3 ++-
 tools/libxl/xl_cmdimpl.c    | 2 ++
 5 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index 025df27..07f9723 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -601,6 +601,13 @@ More information about Xen gfx_passthru feature is available
 on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
 wiki page.
 
+=item B<gfx_passthru_primary=BOOLEAN>
+
+If set to true, indicates that one of the GPUs passed through to the
+domain is the primary one; therefore allows to the domain's stubdoman
+access permissions for the VGA framebuffer. Note that this option
+defaults to true.
+
 =item B<ioports=[ "IOPORT_RANGE", "IOPORT_RANGE", ... ]>
 
 Allow guest to access specific legacy I/O ports. Each B<IOPORT_RANGE>
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index ce0d2c2..c59b3c7 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -84,6 +84,13 @@
 #define LIBXL_HAVE_FIRMWARE_PASSTHROUGH 1
 
 /*
+ * LIBXL_HAVE_GFX_PASSTHROUGH_PRIMARY indicates that the user must
+ * specify in the domain configuration whether one of the passthru
+ * VGA devices is the primary one.
+ */
+#define LIBXL_HAVE_GFX_PASSTHROUGH_PRIMARY 1
+
+/*
  * LIBXL_HAVE_DOMAIN_NODEAFFINITY indicates that a 'nodemap' field
  * (of libxl_bitmap type) is present in libxl_domain_build_info,
  * containing the node-affinity for the domain.
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index b5506b1..a44c42a 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -349,6 +349,7 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
         libxl_defbool_setdefault(&b_info->u.hvm.nographic, false);
 
         libxl_defbool_setdefault(&b_info->u.hvm.gfx_passthru, false);
+        libxl_defbool_setdefault(&b_info->u.hvm.gfx_passthru_primary, true);
 
         break;
     case LIBXL_DOMAIN_TYPE_PV:
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index e37e579..754e89d 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -367,7 +367,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ("sdl",              libxl_sdl_info),
                                        ("spice",            libxl_spice_info),
                                        
-                                       ("gfx_passthru",     libxl_defbool),
+                                       ("gfx_passthru",             libxl_defbool),
+                                       ("gfx_passthru_primary",     libxl_defbool),
                                        
                                        ("serial",           string),
                                        ("boot",             string),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 513b404..98b5a6e 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1645,6 +1645,8 @@ skip_vfb:
         xlu_cfg_get_defbool(config, "nographic", &b_info->u.hvm.nographic, 0);
         xlu_cfg_get_defbool(config, "gfx_passthru", 
                             &b_info->u.hvm.gfx_passthru, 0);
+        xlu_cfg_get_defbool(config, "gfx_passthru_primary",
+                            &b_info->u.hvm.gfx_passthru_primary, 0);
         xlu_cfg_replace_string (config, "serial", &b_info->u.hvm.serial, 0);
         xlu_cfg_replace_string (config, "boot", &b_info->u.hvm.boot, 0);
         xlu_cfg_get_defbool(config, "usb", &b_info->u.hvm.usb, 0);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 13/14] tools/libxl: explicitly grant access to needed I/O-memory ranges
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (11 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-02 18:42 ` [PATCH v9 14/14] xen/common: do not implicitly permit access to mapped I/O memory Arianna Avanzini
  2014-07-11 13:51 ` [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Julien Grall
  14 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit changes the existing libxl code to be sure to grant access
permission to PCI-related I/O memory ranges, while setting up passthrough
of PCI devices specified in the domain's configuration, and to VGA-related
memory ranges, while setting up VGA passthrough (if gfx_passthru = 1 and
gfx_passthru_primary = 1 in the domain's configuration).
As for the latter, the newly-added code does not replace any existing one,
but instead matches the calls to xc_domain_memory_mapping() performed by
QEMU on the path that is executed if gfx passthru is enabled and follows
the registration of a new VGA controller (in register_vga_regions(),
defined in hw/pt-graphics.c). In fact, VGA needs some extra memory
ranges to be mapped with respect to PCI; QEMU expects that access to those
memory ranges is implicitly granted when he calls the hypervisor with the
function xc_domain_memory_mapping(): this commit calls iomem_permission
for it when needed for a primary GPU.

This commit is instrumental to the following one, which will separate
the functions of the iomem_permission and memory_mapping DOMCTLs, so
that requesting an I/O-memory range will not imply that access to such a
range is implicitly granted.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Allow a domain access to the VGA framebuffer only if the user has
          signaled that one of the passthru GPUs is primary via domain config.

    v8:
        - Explain better in the commit description VGA-related code additions.
        - Fix v6 changelog which, being too generic, ended up to uncorrectly
          state that one of the requests had been addressed.
        - Remove tentative phrases from commit description.

    v7:
        - Let libxl not handle I/O ports and I/O memory differently when access
          to a PCI device is allowed to a domain.
        - Change the construct used by libxl during PCI-related initialization
          from a switch to an if to better suit the new execution flow.

---
 tools/libxl/libxl_create.c | 33 +++++++++++++++++++++++++++++++++
 tools/libxl/libxl_pci.c    | 26 ++++++++++----------------
 2 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index a44c42a..42d8c41 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1213,6 +1213,39 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
             libxl__spawn_stub_dm(egc, &dcs->dmss);
         else
             libxl__spawn_local_dm(egc, &dcs->dmss.dm);
+
+        /*
+         * If VGA passthru is enabled by domain config and one of the
+         * passthru GPUs has been indicated by the user to be the
+         * primary, be sure that the related stubdomain and the domain
+         * itself can access the VGA framebuffer.
+         */
+        if (d_config->b_info.u.hvm.gfx_passthru.val &&
+            d_config->b_info.u.hvm.gfx_passthru_primary.val) {
+            uint64_t vga_iomem_start = 0xa0000 >> XC_PAGE_SHIFT;
+            int stubdom_domid = libxl_get_stubdom_id(CTX, domid);
+
+            ret = xc_domain_iomem_permission(CTX->xch, stubdom_domid,
+                                             vga_iomem_start, 0x20, 1);
+            if (ret < 0) {
+                LOGE(ERROR,
+                     "failed to give stubdom%d access to iomem range "
+                     "%"PRIx64"-%"PRIx64" for VGA passthru",
+                     stubdom_domid,
+                     vga_iomem_start, (vga_iomem_start + 0x20 - 1));
+                goto error_out;
+            }
+            ret = xc_domain_iomem_permission(CTX->xch, domid,
+                                             vga_iomem_start, 0x20, 1);
+            if (ret < 0) {
+                LOGE(ERROR,
+                     "failed to give dom%d access to iomem range "
+                     "%"PRIx64"-%"PRIx64" for VGA passthru",
+                     domid, vga_iomem_start, (vga_iomem_start + 0x20 - 1));
+                goto error_out;
+            }
+        }
+
         return;
     }
     case LIBXL_DOMAIN_TYPE_PV:
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 44d0453..032e981 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -846,10 +846,13 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
 static int do_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, int starting)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
+    libxl_domain_type type = libxl__domain_type(gc, domid);
     int rc, hvm = 0;
 
-    switch (libxl__domain_type(gc, domid)) {
-    case LIBXL_DOMAIN_TYPE_HVM:
+    if (type == LIBXL_DOMAIN_TYPE_INVALID)
+        return ERROR_FAIL;
+
+    if (type == LIBXL_DOMAIN_TYPE_HVM) {
         hvm = 1;
         if (libxl__wait_for_device_model_deprecated(gc, domid, "running",
                                          NULL, NULL, NULL) < 0) {
@@ -867,8 +870,7 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, i
         }
         if ( rc )
             return ERROR_FAIL;
-        break;
-    case LIBXL_DOMAIN_TYPE_PV:
+    }
     {
         char *sysfs_path = libxl__sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
                                          pcidev->bus, pcidev->dev, pcidev->func);
@@ -937,10 +939,6 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, i
                 return ERROR_FAIL;
             }
         }
-        break;
-    }
-    case LIBXL_DOMAIN_TYPE_INVALID:
-        return ERROR_FAIL;
     }
 out:
     if (!libxl_is_stubdom(ctx, domid, NULL)) {
@@ -1166,6 +1164,7 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     libxl_device_pci *assigned;
+    libxl_domain_type type = libxl__domain_type(gc, domid);
     int hvm = 0, rc, num;
     int stubdomid = 0;
 
@@ -1181,8 +1180,7 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
     }
 
     rc = ERROR_FAIL;
-    switch (libxl__domain_type(gc, domid)) {
-    case LIBXL_DOMAIN_TYPE_HVM:
+    if (type == LIBXL_DOMAIN_TYPE_HVM) {
         hvm = 1;
         if (libxl__wait_for_device_model_deprecated(gc, domid, "running",
                                          NULL, NULL, NULL) < 0)
@@ -1203,8 +1201,8 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
             rc = ERROR_FAIL;
             goto out_fail;
         }
-        break;
-    case LIBXL_DOMAIN_TYPE_PV:
+    } else if (type != LIBXL_DOMAIN_TYPE_PV)
+        abort();
     {
         char *sysfs_path = libxl__sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
                                          pcidev->bus, pcidev->dev, pcidev->func);
@@ -1254,10 +1252,6 @@ skip1:
             }
         }
         fclose(f);
-        break;
-    }
-    default:
-        abort();
     }
 out:
     /* don't do multiple resets while some functions are still passed through */
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH v9 14/14] xen/common: do not implicitly permit access to mapped I/O memory
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (12 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 13/14] tools/libxl: explicitly grant access to needed I/O-memory ranges Arianna Avanzini
@ 2014-07-02 18:42 ` Arianna Avanzini
  2014-07-11 13:51 ` [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Julien Grall
  14 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-02 18:42 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the XEN_DOMCTL_memory_mapping hypercall implicitly grants
to a domain access permission to the I/O memory areas mapped in its
guest address space. This conflicts with the presence of a specific
hypercall (XEN_DOMCTL_iomem_permission) used to grant such a permission
to a domain.
This commit separates the functions of the two hypercalls by having only
the latter be able to permit I/O memory access to a domain, and the
former just performing the mapping after a permissions check on both the
granting and the grantee domains.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v8:
        - Drop iomem_permission-related changes.
        - Conservatively check both the granting and the grantee domains'
          permissions in the memory_mapping DOMCTL.
        - Remove tentative phrases from commit description.

    v7:
        - Let iomem_permission check if the calling domain is allowed to access
          memory ranges to be mapped to a domain. Remove such a check from the
          memory_mapping hypercall.

---
 xen/common/domctl.c | 36 ++++++++++--------------------------
 1 file changed, 10 insertions(+), 26 deletions(-)

diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index abc8d60..2e8d57e 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -925,7 +925,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             break;
 
         ret = -EPERM;
-        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
+        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) ||
+             !iomem_access_permitted(d, mfn, mfn_end) )
             break;
 
         ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
@@ -938,40 +939,23 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
                    "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
                    d->domain_id, gfn, mfn, nr_mfns);
 
-            ret = iomem_permit_access(d, mfn, mfn_end);
-            if ( !ret )
-            {
-                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
-                if ( ret )
-                {
-                    printk(XENLOG_G_WARNING
-                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
-                           d->domain_id, gfn, mfn, nr_mfns, ret);
-                    if ( iomem_deny_access(d, mfn, mfn_end) &&
-                         is_hardware_domain(current->domain) )
-                        printk(XENLOG_ERR
-                               "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
-                               d->domain_id, mfn, mfn_end);
-                }
-            }
+            ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
+            if ( ret )
+                printk(XENLOG_G_WARNING
+                       "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
+                       d->domain_id, gfn, mfn, nr_mfns, ret);
         }
         else
         {
-            int rc = 0;
-
             printk(XENLOG_G_INFO
                    "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
                    d->domain_id, gfn, mfn, nr_mfns);
 
-            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
-            ret = iomem_deny_access(d, mfn, mfn_end);
-            if ( !ret )
-                ret = rc;
+            ret = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
             if ( ret && is_hardware_domain(current->domain) )
                 printk(XENLOG_ERR
-                       "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
-                       ret, rc ? "removing" : "denying", d->domain_id,
-                       mfn, mfn_end);
+                       "memory_map: error %ld removing dom%d access to [%lx,%lx]\n",
+                       ret, d->domain_id, mfn, mfn_end);
         }
         /* Do this unconditionally to cover errors on above failure paths. */
         memory_type_changed(d);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-02 18:42 ` [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU Arianna Avanzini
@ 2014-07-02 19:00   ` Sander Eikelenboom
  2014-07-03 10:30     ` Jan Beulich
  2014-07-03 14:47   ` Ian Campbell
  1 sibling, 1 reply; 69+ messages in thread
From: Sander Eikelenboom @ 2014-07-02 19:00 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: julien.grall, paolo.valente, keir, stefano.stabellini, tim,
	dario.faggioli, Ian.Jackson, xen-devel, Ian.Campbell, etrudeau,
	JBeulich, andrew.cooper3, viktor.kleinik


Wednesday, July 2, 2014, 8:42:21 PM, you wrote:

> This commit adds a new option available for any domU libxl
> configuration that allows the user to specify if one of the
> VGA adapters passed through to the domain is the primary one.
> This way, libxl can arrange the correct I/O-memory access
> permission for its stubdomain.

> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
> Cc: Julien Grall <julien.grall@citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Jan Beulich <JBeulich@suse.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Eric Trudeau <etrudeau@broadcom.com>
> Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
> ---
>  docs/man/xl.cfg.pod.5       | 7 +++++++
>  tools/libxl/libxl.h         | 7 +++++++
>  tools/libxl/libxl_create.c  | 1 +
>  tools/libxl/libxl_types.idl | 3 ++-
>  tools/libxl/xl_cmdimpl.c    | 2 ++
>  5 files changed, 19 insertions(+), 1 deletion(-)

> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
> index 025df27..07f9723 100644
> --- a/docs/man/xl.cfg.pod.5
> +++ b/docs/man/xl.cfg.pod.5
> @@ -601,6 +601,13 @@ More information about Xen gfx_passthru feature is available
>  on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
>  wiki page.
>  
> +=item B<gfx_passthru_primary=BOOLEAN>
> +
> +If set to true, indicates that one of the GPUs passed through to the
> +domain is the primary one; therefore allows to the domain's stubdoman
> +access permissions for the VGA framebuffer. Note that this option
> +defaults to true.
> +

Wouldn't it make sense to make it a pci <BDF> instead of boolean, 
so that instead of: "one of the GPU's passed is the primary",
you could actually specify: "this *specific* GPU passed through i would like to be the primary" ?

--
Sander

>  =item B<ioports=[ "IOPORT_RANGE", "IOPORT_RANGE", ... ]>
>  
>  Allow guest to access specific legacy I/O ports. Each B<IOPORT_RANGE>
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index ce0d2c2..c59b3c7 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -84,6 +84,13 @@
>  #define LIBXL_HAVE_FIRMWARE_PASSTHROUGH 1
>  
>  /*
> + * LIBXL_HAVE_GFX_PASSTHROUGH_PRIMARY indicates that the user must
> + * specify in the domain configuration whether one of the passthru
> + * VGA devices is the primary one.
> + */
> +#define LIBXL_HAVE_GFX_PASSTHROUGH_PRIMARY 1
> +
> +/*
>   * LIBXL_HAVE_DOMAIN_NODEAFFINITY indicates that a 'nodemap' field
>   * (of libxl_bitmap type) is present in libxl_domain_build_info,
>   * containing the node-affinity for the domain.
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index b5506b1..a44c42a 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -349,6 +349,7 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
>          libxl_defbool_setdefault(&b_info->u.hvm.nographic, false);
>  
>          libxl_defbool_setdefault(&b_info->u.hvm.gfx_passthru, false);
> +        libxl_defbool_setdefault(&b_info->u.hvm.gfx_passthru_primary, true);
>  
>          break;
>      case LIBXL_DOMAIN_TYPE_PV:
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index e37e579..754e89d 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -367,7 +367,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
>                                         ("sdl",              libxl_sdl_info),
>                                         ("spice",            libxl_spice_info),
>                                         
> -                                       ("gfx_passthru",     libxl_defbool),
> +                                       ("gfx_passthru",             libxl_defbool),
> +                                       ("gfx_passthru_primary",     libxl_defbool),
>                                         
>                                         ("serial",           string),
>                                         ("boot",             string),
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> index 513b404..98b5a6e 100644
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -1645,6 +1645,8 @@ skip_vfb:
>          xlu_cfg_get_defbool(config, "nographic", &b_info->u.hvm.nographic, 0);
>          xlu_cfg_get_defbool(config, "gfx_passthru", 
>                              &b_info->u.hvm.gfx_passthru, 0);
> +        xlu_cfg_get_defbool(config, "gfx_passthru_primary",
> +                            &b_info->u.hvm.gfx_passthru_primary, 0);
>          xlu_cfg_replace_string (config, "serial", &b_info->u.hvm.serial, 0);
>          xlu_cfg_replace_string (config, "boot", &b_info->u.hvm.boot, 0);
>          xlu_cfg_get_defbool(config, "usb", &b_info->u.hvm.usb, 0);

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes
  2014-07-02 18:42 ` [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
@ 2014-07-03 10:24   ` Julien Grall
  2014-07-03 11:03   ` Julien Grall
  1 sibling, 0 replies; 69+ messages in thread
From: Julien Grall @ 2014-07-03 10:24 UTC (permalink / raw)
  To: Arianna Avanzini, xen-devel
  Cc: julien.grall, paolo.valente, keir, stefano.stabellini, tim,
	dario.faggioli, Ian.Jackson, Ian.Campbell, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

Hi Arianna,

On 07/02/2014 07:42 PM, Arianna Avanzini wrote:
>  xen/arch/arm/p2m.c | 32 ++++++++++++++++++++++++++++++--
>  1 file changed, 30 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 9960e17..7cb4a27 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c

[..]

> @@ -439,12 +441,37 @@ static int apply_p2m_changes(struct domain *d,
>                      pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr, t);
>                      p2m_write_pte(&third[third_table_offset(addr)],
>                                    pte, flush_pt);
> -                    maddr += PAGE_SIZE;
>                  }
>                  break;
> -            case RELINQUISH:
>              case REMOVE:
>                  {
> +                    unsigned long mfn = pte.p2m.base;
> +
> +                    /*
> +                     * Ensure that the guest address addr currently being
> +                     * handled (that is in the range given as argument to
> +                     * this function) is actually mapped to the corresponding
> +                     * machine address in the specified range. maddr here is
> +                     * the machine address given to the function, while mfn
> +                     * is the machine frame number actually mapped to the
> +                     * guest address: check if the two correspond.
> +                     */
> +                    if ( !pte.p2m.valid || maddr != pfn_to_paddr(mfn) )
> +                    {
> +                        gdprintk(XENLOG_WARNING,
> +                                 "p2m_remove: mapping at %"PRIpaddr" is of maddr %"PRIpaddr" not %"PRIpaddr" as expected",
> +                                 addr, pfn_to_paddr(mfn), maddr);
> +                        /*
> +                         * Continue to process the range even if an error is
> +                         * encountered, to prevent I/O-memory regions from
> +                         * being partially accessible to a domain.
> +                         */
> +                       continue;

This is buggy, you never update addr and maddr. So if a mapping is not
there, the code will end up in infinite loop.

Regards,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters
  2014-07-02 18:42 ` [PATCH v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters Arianna Avanzini
@ 2014-07-03 10:26   ` Julien Grall
  0 siblings, 0 replies; 69+ messages in thread
From: Julien Grall @ 2014-07-03 10:26 UTC (permalink / raw)
  To: Arianna Avanzini, xen-devel
  Cc: julien.grall, paolo.valente, keir, stefano.stabellini, tim,
	dario.faggioli, Ian.Jackson, Ian.Campbell, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

Hi Arianna,

On 07/02/2014 07:42 PM, Arianna Avanzini wrote:
> Currently, the map_mmio_regions() function, defined for the ARM
> architecture, has parameters with paddr_t type. This interface,
> however, needs caller functions to correctly page-align addresses
> given as parameters to map_mmio_regions(). This commit changes the
> function's interface to accept page frame numbers as parameters.
> This commit also modifies caller functions in an attempt to adapt
> them to the new interface.
> This commit is meant to produce the minimum indispensable needed
> changes; these are also instrumental to making the interface of
> map_mmio_regions() symmetric with the unmap_mmio_regions() function,
> that will be introduced in one of the next commits of the series
> and will feature a pfn-based interface.
> 
> NOTE: platform-specific code has not been tested, save for the
>       sunxi and the Arndale Exynos 5 platforms (see the Tested-by
>       below for the latter).
> 
> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Tested-by: Julien Grall <julien.grall@citrix.com>
> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
> Cc: Jan Beulich <JBeulich@suse.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Eric Trudeau <etrudeau@broadcom.com>
> Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
> 
> ---
> 
>     v7:
>         - Remove useless decrements when using paddr_to_pfn_aligned().
> 
>     v5:
>         - Add a macro for the paddr_to_pfn(PAGE_ALIGN(...)) pattern.
>         - Hopefully improve commit description.
> 
> ---
>  xen/arch/arm/domain_build.c          |  7 ++++---
>  xen/arch/arm/gic.c                   | 20 +++++++++++---------

For this patch and the following (#3), the code has heavily change in
gic.c. Everything related to the mapping for GICv2 is now done in a
separate file gic-v2.c (see the function gicv_v2_init).

So both patches won't apply cleanly on the latest branch.

Regards,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-02 19:00   ` Sander Eikelenboom
@ 2014-07-03 10:30     ` Jan Beulich
  2014-07-03 10:49       ` Sander Eikelenboom
  2014-07-03 14:50       ` Ian Campbell
  0 siblings, 2 replies; 69+ messages in thread
From: Jan Beulich @ 2014-07-03 10:30 UTC (permalink / raw)
  To: Sander Eikelenboom, Arianna Avanzini
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	andrew.cooper3, dario.faggioli, Ian.Jackson, xen-devel,
	julien.grall, etrudeau, tim, viktor.kleinik

>>> On 02.07.14 at 21:00, <linux@eikelenboom.it> wrote:
> Wednesday, July 2, 2014, 8:42:21 PM, you wrote:
>> --- a/docs/man/xl.cfg.pod.5
>> +++ b/docs/man/xl.cfg.pod.5
>> @@ -601,6 +601,13 @@ More information about Xen gfx_passthru feature is available
>>  on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
>>  wiki page.
>>  
>> +=item B<gfx_passthru_primary=BOOLEAN>
>> +
>> +If set to true, indicates that one of the GPUs passed through to the
>> +domain is the primary one; therefore allows to the domain's stubdoman
>> +access permissions for the VGA framebuffer. Note that this option
>> +defaults to true.
>> +
> 
> Wouldn't it make sense to make it a pci <BDF> instead of boolean, 
> so that instead of: "one of the GPU's passed is the primary",
> you could actually specify: "this *specific* GPU passed through i would like 
> to be the primary" ?

No. You can't just make some card primary (with "primary" really
meaning accessible via the legacy VGA interface). Within a host
there's exactly one card that can be primary. If that card gets
passed through, it can also be primary in the guest. Any other
card, not having the legacy VGA ports routed through the
corresponding circuitry, can't all of the sudden become the
primary one in a guest.

Consequently this shouldn't be a config file setting, but something
that gets worked out by looking at the PCI config spaces of the
passed through card and eventual upstream bridges.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL
  2014-07-02 18:42 ` [PATCH v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL Arianna Avanzini
@ 2014-07-03 10:43   ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2014-07-03 10:43 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	andrew.cooper3, dario.faggioli, Ian.Jackson, xen-devel,
	julien.grall, etrudeau, tim, viktor.kleinik

>>> On 02.07.14 at 20:42, <avanzini.arianna@gmail.com> wrote:
> +int unmap_mmio_regions(struct domain *d,
> +                       unsigned long start_gfn,
> +                       unsigned long nr,
> +                       unsigned long mfn)
> +{
> +    int ret = 0, err = 0;
> +    unsigned long i;
> +
> +    if ( !paging_mode_translate(d) )
> +        return 0;
> +
> +    for ( i = 0; i < nr; i++ ) {
> +        ret = clear_mmio_p2m_entry(d, start_gfn + i, _mfn(mfn + i));
> +        if ( ret ) err = ret;
> +    }

There are two coding style problems here ({ on a separate line, and
bodies of if()'s belong on separate lines). Additionally the initializer of
"ret" is pointless; in fact you could move that variable into the for()
scope, with the call to clear_mmio_p2m_entry() being the initializer.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-03 10:30     ` Jan Beulich
@ 2014-07-03 10:49       ` Sander Eikelenboom
  2014-07-03 10:58         ` Jan Beulich
  2014-07-03 14:50       ` Ian Campbell
  1 sibling, 1 reply; 69+ messages in thread
From: Sander Eikelenboom @ 2014-07-03 10:49 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	andrew.cooper3, dario.faggioli, Ian.Jackson, xen-devel,
	julien.grall, etrudeau, tim, Arianna Avanzini, viktor.kleinik


Thursday, July 3, 2014, 12:30:13 PM, you wrote:

>>>> On 02.07.14 at 21:00, <linux@eikelenboom.it> wrote:
>> Wednesday, July 2, 2014, 8:42:21 PM, you wrote:
>>> --- a/docs/man/xl.cfg.pod.5
>>> +++ b/docs/man/xl.cfg.pod.5
>>> @@ -601,6 +601,13 @@ More information about Xen gfx_passthru feature is available
>>>  on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
>>>  wiki page.
>>>  
>>> +=item B<gfx_passthru_primary=BOOLEAN>
>>> +
>>> +If set to true, indicates that one of the GPUs passed through to the
>>> +domain is the primary one; therefore allows to the domain's stubdoman
>>> +access permissions for the VGA framebuffer. Note that this option
>>> +defaults to true.
>>> +
>> 
>> Wouldn't it make sense to make it a pci <BDF> instead of boolean, 
>> so that instead of: "one of the GPU's passed is the primary",
>> you could actually specify: "this *specific* GPU passed through i would like 
>> to be the primary" ?

> No. You can't just make some card primary (with "primary" really
> meaning accessible via the legacy VGA interface). Within a host
> there's exactly one card that can be primary. If that card gets
> passed through, it can also be primary in the guest. Any other
> card, not having the legacy VGA ports routed through the
> corresponding circuitry, can't all of the sudden become the
> primary one in a guest.

Is that also true for a HVM guest ?
- aren't the legacy VGA ports emulated without passthrough (by hvmloader / 
  seabios, with the cirrus or stdvga)
- couldn't they be rerouted to a device that is passed through ?

Or would that make the VGA card do legacy stuff on the host instead of in the 
guest (since it's lowlevel legacy stuff) ?

> Consequently this shouldn't be a config file setting, but something
> that gets worked out by looking at the PCI config spaces of the
> passed through card and eventual upstream bridges.

> Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-03 10:49       ` Sander Eikelenboom
@ 2014-07-03 10:58         ` Jan Beulich
  0 siblings, 0 replies; 69+ messages in thread
From: Jan Beulich @ 2014-07-03 10:58 UTC (permalink / raw)
  To: Sander Eikelenboom
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	andrew.cooper3, dario.faggioli, Ian.Jackson, xen-devel,
	julien.grall, etrudeau, tim, Arianna Avanzini, viktor.kleinik

>>> On 03.07.14 at 12:49, <linux@eikelenboom.it> wrote:

> Thursday, July 3, 2014, 12:30:13 PM, you wrote:
> 
>>>>> On 02.07.14 at 21:00, <linux@eikelenboom.it> wrote:
>>> Wednesday, July 2, 2014, 8:42:21 PM, you wrote:
>>>> --- a/docs/man/xl.cfg.pod.5
>>>> +++ b/docs/man/xl.cfg.pod.5
>>>> @@ -601,6 +601,13 @@ More information about Xen gfx_passthru feature is 
> available
>>>>  on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
>>>>  wiki page.
>>>>  
>>>> +=item B<gfx_passthru_primary=BOOLEAN>
>>>> +
>>>> +If set to true, indicates that one of the GPUs passed through to the
>>>> +domain is the primary one; therefore allows to the domain's stubdoman
>>>> +access permissions for the VGA framebuffer. Note that this option
>>>> +defaults to true.
>>>> +
>>> 
>>> Wouldn't it make sense to make it a pci <BDF> instead of boolean, 
>>> so that instead of: "one of the GPU's passed is the primary",
>>> you could actually specify: "this *specific* GPU passed through i would like 
> 
>>> to be the primary" ?
> 
>> No. You can't just make some card primary (with "primary" really
>> meaning accessible via the legacy VGA interface). Within a host
>> there's exactly one card that can be primary. If that card gets
>> passed through, it can also be primary in the guest. Any other
>> card, not having the legacy VGA ports routed through the
>> corresponding circuitry, can't all of the sudden become the
>> primary one in a guest.
> 
> Is that also true for a HVM guest ?
> - aren't the legacy VGA ports emulated without passthrough (by hvmloader / 
>   seabios, with the cirrus or stdvga)

Sure, but we're only talking about a passed through card here.

> - couldn't they be rerouted to a device that is passed through ?

No idea how you imagine to do that.

> Or would that make the VGA card do legacy stuff on the host instead of in 
> the 
> guest (since it's lowlevel legacy stuff) ?

Depends on whose port space you think of.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes
  2014-07-02 18:42 ` [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
  2014-07-03 10:24   ` Julien Grall
@ 2014-07-03 11:03   ` Julien Grall
  2014-07-03 14:28     ` Ian Campbell
  1 sibling, 1 reply; 69+ messages in thread
From: Julien Grall @ 2014-07-03 11:03 UTC (permalink / raw)
  To: Arianna Avanzini, xen-devel
  Cc: julien.grall, paolo.valente, keir, stefano.stabellini, tim,
	dario.faggioli, Ian.Jackson, Ian.Campbell, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

On 07/02/2014 07:42 PM, Arianna Avanzini wrote:
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 9960e17..7cb4a27 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -439,12 +441,37 @@ static int apply_p2m_changes(struct domain *d,
>                      pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr, t);
>                      p2m_write_pte(&third[third_table_offset(addr)],
>                                    pte, flush_pt);
> -                    maddr += PAGE_SIZE;
>                  }
>                  break;
> -            case RELINQUISH:
>              case REMOVE:
>                  {
> +                    unsigned long mfn = pte.p2m.base;
> +
> +                    /*
> +                     * Ensure that the guest address addr currently being
> +                     * handled (that is in the range given as argument to
> +                     * this function) is actually mapped to the corresponding
> +                     * machine address in the specified range. maddr here is
> +                     * the machine address given to the function, while mfn
> +                     * is the machine frame number actually mapped to the
> +                     * guest address: check if the two correspond.
> +                     */
> +                    if ( !pte.p2m.valid || maddr != pfn_to_paddr(mfn) )
> +                    {
> +                        gdprintk(XENLOG_WARNING,
> +                                 "p2m_remove: mapping at %"PRIpaddr" is of maddr %"PRIpaddr" not %"PRIpaddr" as expected",
> +                                 addr, pfn_to_paddr(mfn), maddr);

gdprintk is using the current domain to print the domid. We are not
necessarily remove the mapping from the current domain.

> +                        /*
> +                         * Continue to process the range even if an error is
> +                         * encountered, to prevent I/O-memory regions from
> +                         * being partially accessible to a domain.
> +                         */
> +                       continue;


I've just reviewed the patch #5 (which does the similar check for x86)
and I'm surprised that you differ. Here you let the mapping in place if
something is wrong rather than clearing it.

That made me think there is a possible security issue here. If you are
trying to clear a page that it's actually a foreign mapping, we already
drop the reference above. Xen may reallocate this page for anything
else, so the domain will have a mapping to a page which potentially
belong to another domain or Xen. Therefore we will leak information.

I would drop the continue here and just print a warning.

Regards,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes
  2014-07-03 11:03   ` Julien Grall
@ 2014-07-03 14:28     ` Ian Campbell
  2014-07-03 14:44       ` Julien Grall
  0 siblings, 1 reply; 69+ messages in thread
From: Ian Campbell @ 2014-07-03 14:28 UTC (permalink / raw)
  To: Julien Grall
  Cc: paolo.valente, keir, stefano.stabellini, tim, dario.faggioli,
	Ian.Jackson, xen-devel, julien.grall, etrudeau, andrew.cooper3,
	JBeulich, Arianna Avanzini, viktor.kleinik

On Thu, 2014-07-03 at 12:03 +0100, Julien Grall wrote:
> On 07/02/2014 07:42 PM, Arianna Avanzini wrote:
> > diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> > index 9960e17..7cb4a27 100644
> > --- a/xen/arch/arm/p2m.c
> > +++ b/xen/arch/arm/p2m.c
> > @@ -439,12 +441,37 @@ static int apply_p2m_changes(struct domain *d,
> >                      pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr, t);
> >                      p2m_write_pte(&third[third_table_offset(addr)],
> >                                    pte, flush_pt);
> > -                    maddr += PAGE_SIZE;
> >                  }
> >                  break;
> > -            case RELINQUISH:
> >              case REMOVE:
> >                  {
> > +                    unsigned long mfn = pte.p2m.base;
> > +
> > +                    /*
> > +                     * Ensure that the guest address addr currently being
> > +                     * handled (that is in the range given as argument to
> > +                     * this function) is actually mapped to the corresponding
> > +                     * machine address in the specified range. maddr here is
> > +                     * the machine address given to the function, while mfn
> > +                     * is the machine frame number actually mapped to the
> > +                     * guest address: check if the two correspond.
> > +                     */
> > +                    if ( !pte.p2m.valid || maddr != pfn_to_paddr(mfn) )
> > +                    {
> > +                        gdprintk(XENLOG_WARNING,
> > +                                 "p2m_remove: mapping at %"PRIpaddr" is of maddr %"PRIpaddr" not %"PRIpaddr" as expected",
> > +                                 addr, pfn_to_paddr(mfn), maddr);
> 
> gdprintk is using the current domain to print the domid. We are not
> necessarily remove the mapping from the current domain.
> 
> > +                        /*
> > +                         * Continue to process the range even if an error is
> > +                         * encountered, to prevent I/O-memory regions from
> > +                         * being partially accessible to a domain.
> > +                         */
> > +                       continue;
> 
> 
> I've just reviewed the patch #5 (which does the similar check for x86)
> and I'm surprised that you differ. Here you let the mapping in place if
> something is wrong rather than clearing it.

I agree that we should be consistent. The x86 behaviour (that is: warn
and nuke the mapping whatever it is) seems safer to me.

> That made me think there is a possible security issue here. If you are
> trying to clear a page that it's actually a foreign mapping, we already
> drop the reference above. Xen may reallocate this page for anything
> else, so the domain will have a mapping to a page which potentially
> belong to another domain or Xen. Therefore we will leak information.

Even if the unmap on failure something must be keeping the page live
from the put_page until the mapping actually gets cleared. What is that?

ISTR debating this at the time during 4.4, but I don't recall the
answer, or we've subsequently broken it.

Something else must be holding a reference for the duration of this
call. Right?

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions
  2014-07-02 18:42 ` [PATCH v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions Arianna Avanzini
@ 2014-07-03 14:40   ` Ian Campbell
  2014-07-03 15:00     ` Julien Grall
  0 siblings, 1 reply; 69+ messages in thread
From: Ian Campbell @ 2014-07-03 14:40 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: paolo.valente, keir, stefano.stabellini, Ian.Jackson,
	dario.faggioli, tim, xen-devel, julien.grall, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

On Wed, 2014-07-02 at 20:42 +0200, Arianna Avanzini wrote:
> This commit changes the function apply_p2m_changes() to unwind changes
> performed while mapping an I/O-memory region, if errors are seen during
> the operation. This is useful to avoid that I/O-memory areas are
> partially accessible to guests.

I think it won't quite unwind, since it will actually destroy whatever
was there before we tried to put something new.

Is there anything here which is specific to I/O memory areas? It seems
to affect all mapping types.

> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Julien Grall <julien.grall@citrix.com>
> Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Eric Trudeau <etrudeau@broadcom.com>
> Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
> 
> ---
> 
>     v9:
>         - Let apply_p2m_ranges() unwind its own progress instead of relying on
>           the caller to unmap partially-mapped I/O-memory regions.
> 
> ---
>  xen/arch/arm/p2m.c | 16 ++++++++++++----
>  1 file changed, 12 insertions(+), 4 deletions(-)
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 22646e9..92fc4ec 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -314,7 +314,7 @@ static int apply_p2m_changes(struct domain *d,
>      unsigned long cur_first_page = ~0,
>                    cur_first_offset = ~0,
>                    cur_second_offset = ~0;
> -    unsigned long count = 0;
> +    unsigned long count = 0, inserted = 0;
>      unsigned int flush = 0;
>      bool_t populate = (op == INSERT || op == ALLOCATE);
>      lpae_t pte;
> @@ -328,6 +328,7 @@ static int apply_p2m_changes(struct domain *d,
>  
>      spin_lock(&p2m->lock);
>  
> +unwind:

I think I'd prefer a recursive call to the use of goto.

In particular the use of goto will result in the overall function
appearing to succeed, won't it? Because the REMOVE will have succeeded.

>      addr = start_gpaddr;
>      while ( addr < end_gpaddr )
>      {
> @@ -338,7 +339,9 @@ static int apply_p2m_changes(struct domain *d,
>              if ( !first )
>              {
>                  rc = -EINVAL;
> -                goto out;
> +                end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;

Isn't start_gpaddr + inserted * PAGE_SIZE == addr at any given moment?

Or you could just recurse on the entire region, which is much simpler I
think, especially when you consider that you are clearing the region
rather than unwinding it.

> @@ -384,7 +389,9 @@ static int apply_p2m_changes(struct domain *d,
>                                    flush_pt);
>              if ( rc < 0 ) {
>                  printk("p2m_populate_ram: L2 failed\n");
> -                goto out;
> +                end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;
> +                op = REMOVE;
> +                goto unwind;
>              }

What about the L3 ALLOCATE case? Or is you intention only to handle
INSERT (but you partially handle ALLOCATE)?

>          }
>  
> @@ -441,6 +448,7 @@ static int apply_p2m_changes(struct domain *d,
>                      pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr, t);
>                      p2m_write_pte(&third[third_table_offset(addr)],
>                                    pte, flush_pt);
> +                    inserted++;
>                  }
>                  break;
>              case REMOVE:

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 07/14] xen/common: add ARM stub for the function memory_type_changed()
  2014-07-02 18:42 ` [PATCH v9 07/14] xen/common: add ARM stub for the function memory_type_changed() Arianna Avanzini
@ 2014-07-03 14:41   ` Ian Campbell
  0 siblings, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-03 14:41 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: paolo.valente, keir, stefano.stabellini, Ian.Jackson,
	dario.faggioli, tim, xen-devel, julien.grall, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

On Wed, 2014-07-02 at 20:42 +0200, Arianna Avanzini wrote:
> MTRR-related code is not available for the ARM architecture. Given
> that the memory_type_changed() function would be called also from
> common code, its invocation is currently ifdef'd out to be only
> compiled in on an x86 machine. This commit adds an empty stub for ARM.
> 
> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>

> Cc: Jan Beulich <JBeulich@suse.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Eric Trudeau <etrudeau@broadcom.com>
> Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
> 
> ---
> 
>     v9:
>         - Don't expose the memory_type_changed() function to common code,
>           just add an empty stub in arch/arm/p2m.c and in the related header
>           for ARM.
> 
> ---
>  xen/arch/arm/p2m.c        | 4 ++++
>  xen/common/domctl.c       | 2 --
>  xen/include/asm-arm/p2m.h | 2 ++
>  3 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index 92fc4ec..1b87a4e 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -14,6 +14,10 @@
>  #define P2M_FIRST_ORDER 1
>  #define P2M_FIRST_ENTRIES (LPAE_ENTRIES<<P2M_FIRST_ORDER)
>  
> +void memory_type_changed(struct domain *d)
> +{
> +}
> +
>  void dump_p2m_lookup(struct domain *d, paddr_t addr)
>  {
>      struct p2m_domain *p2m = &d->arch.p2m;
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index 000993f..afcd9bc 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -905,10 +905,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>              ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
>          else
>              ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
> -#ifdef CONFIG_X86
>          if ( !ret )
>              memory_type_changed(d);
> -#endif
>      }
>      break;
>  
> diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
> index 0ef396c..0ee7cb2 100644
> --- a/xen/include/asm-arm/p2m.h
> +++ b/xen/include/asm-arm/p2m.h
> @@ -5,6 +5,8 @@
>  
>  struct domain;
>  
> +extern void memory_type_changed(struct domain *);
> +
>  /* Per-p2m-table state */
>  struct p2m_domain {
>      /* Lock that protects updates to the p2m */

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes
  2014-07-03 14:28     ` Ian Campbell
@ 2014-07-03 14:44       ` Julien Grall
  0 siblings, 0 replies; 69+ messages in thread
From: Julien Grall @ 2014-07-03 14:44 UTC (permalink / raw)
  To: Ian Campbell
  Cc: paolo.valente, keir, stefano.stabellini, tim, dario.faggioli,
	Ian.Jackson, xen-devel, julien.grall, etrudeau, andrew.cooper3,
	JBeulich, Arianna Avanzini, viktor.kleinik

On 07/03/2014 03:28 PM, Ian Campbell wrote:
> On Thu, 2014-07-03 at 12:03 +0100, Julien Grall wrote:
>> On 07/02/2014 07:42 PM, Arianna Avanzini wrote:
>>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>>> index 9960e17..7cb4a27 100644
>>> --- a/xen/arch/arm/p2m.c
>>> +++ b/xen/arch/arm/p2m.c
>>> @@ -439,12 +441,37 @@ static int apply_p2m_changes(struct domain *d,
>>>                      pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr, t);
>>>                      p2m_write_pte(&third[third_table_offset(addr)],
>>>                                    pte, flush_pt);
>>> -                    maddr += PAGE_SIZE;
>>>                  }
>>>                  break;
>>> -            case RELINQUISH:
>>>              case REMOVE:
>>>                  {
>>> +                    unsigned long mfn = pte.p2m.base;
>>> +
>>> +                    /*
>>> +                     * Ensure that the guest address addr currently being
>>> +                     * handled (that is in the range given as argument to
>>> +                     * this function) is actually mapped to the corresponding
>>> +                     * machine address in the specified range. maddr here is
>>> +                     * the machine address given to the function, while mfn
>>> +                     * is the machine frame number actually mapped to the
>>> +                     * guest address: check if the two correspond.
>>> +                     */
>>> +                    if ( !pte.p2m.valid || maddr != pfn_to_paddr(mfn) )
>>> +                    {
>>> +                        gdprintk(XENLOG_WARNING,
>>> +                                 "p2m_remove: mapping at %"PRIpaddr" is of maddr %"PRIpaddr" not %"PRIpaddr" as expected",
>>> +                                 addr, pfn_to_paddr(mfn), maddr);
>>
>> gdprintk is using the current domain to print the domid. We are not
>> necessarily remove the mapping from the current domain.
>>
>>> +                        /*
>>> +                         * Continue to process the range even if an error is
>>> +                         * encountered, to prevent I/O-memory regions from
>>> +                         * being partially accessible to a domain.
>>> +                         */
>>> +                       continue;
>>
>>
>> I've just reviewed the patch #5 (which does the similar check for x86)
>> and I'm surprised that you differ. Here you let the mapping in place if
>> something is wrong rather than clearing it.
> 
> I agree that we should be consistent. The x86 behaviour (that is: warn
> and nuke the mapping whatever it is) seems safer to me.
> 
>> That made me think there is a possible security issue here. If you are
>> trying to clear a page that it's actually a foreign mapping, we already
>> drop the reference above. Xen may reallocate this page for anything
>> else, so the domain will have a mapping to a page which potentially
>> belong to another domain or Xen. Therefore we will leak information.
> 
> Even if the unmap on failure something must be keeping the page live
> from the put_page until the mapping actually gets cleared. What is that?
> 
> ISTR debating this at the time during 4.4, but I don't recall the
> answer, or we've subsequently broken it.
> 
> Something else must be holding a reference for the duration of this
> call. Right?

We don't take any reference on mapping for now. We rely on the caller of
guest_physmap_remove_page to take a reference before removing the page
from the p2m.

IIRC we talked about implementing reference counting for mapping for Xen
4.5. It looks we won't have time for that. Anyway, the code was safe
before, and if we do the same as x86 (i.e don't put the continue in the
code) we are still safe.

Regards,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-02 18:42 ` [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU Arianna Avanzini
  2014-07-02 19:00   ` Sander Eikelenboom
@ 2014-07-03 14:47   ` Ian Campbell
  1 sibling, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-03 14:47 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: paolo.valente, keir, stefano.stabellini, Ian.Jackson,
	dario.faggioli, tim, xen-devel, julien.grall, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

On Wed, 2014-07-02 at 20:42 +0200, Arianna Avanzini wrote:
> This commit adds a new option available for any domU libxl
> configuration that allows the user to specify if one of the
> VGA adapters passed through to the domain is the primary one.
> This way, libxl can arrange the correct I/O-memory access
> permission for its stubdomain.

How does this differ from the existing gfx_passthru option? It doesn't
look like anything here consumes the setting so I can't guess.

> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
> Cc: Julien Grall <julien.grall@citrix.com>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Jan Beulich <JBeulich@suse.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Eric Trudeau <etrudeau@broadcom.com>
> Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
> ---
>  docs/man/xl.cfg.pod.5       | 7 +++++++
>  tools/libxl/libxl.h         | 7 +++++++
>  tools/libxl/libxl_create.c  | 1 +
>  tools/libxl/libxl_types.idl | 3 ++-
>  tools/libxl/xl_cmdimpl.c    | 2 ++
>  5 files changed, 19 insertions(+), 1 deletion(-)
> 
> diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
> index 025df27..07f9723 100644
> --- a/docs/man/xl.cfg.pod.5
> +++ b/docs/man/xl.cfg.pod.5
> @@ -601,6 +601,13 @@ More information about Xen gfx_passthru feature is available
>  on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
>  wiki page.
>  
> +=item B<gfx_passthru_primary=BOOLEAN>
> +
> +If set to true, indicates that one of the GPUs passed through to the
> +domain is the primary one; therefore allows to the domain's stubdoman
> +access permissions for the VGA framebuffer. Note that this option
> +defaults to true.

Under what circumstances would I set it to false?

Is this purely a stubdom related flag or does it affect non-stub qemu
too?

> +
>  =item B<ioports=[ "IOPORT_RANGE", "IOPORT_RANGE", ... ]>
>  
>  Allow guest to access specific legacy I/O ports. Each B<IOPORT_RANGE>
> diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
> index ce0d2c2..c59b3c7 100644
> --- a/tools/libxl/libxl.h
> +++ b/tools/libxl/libxl.h
> @@ -84,6 +84,13 @@
>  #define LIBXL_HAVE_FIRMWARE_PASSTHROUGH 1
>  
>  /*
> + * LIBXL_HAVE_GFX_PASSTHROUGH_PRIMARY indicates that the user must

Not must, can. It's a defbool so they can (and normally will) just
accept the default.

> + * specify in the domain configuration whether one of the passthru
> + * VGA devices is the primary one.
> + */
> +#define LIBXL_HAVE_GFX_PASSTHROUGH_PRIMARY 1
> +
> +/*
>   * LIBXL_HAVE_DOMAIN_NODEAFFINITY indicates that a 'nodemap' field
>   * (of libxl_bitmap type) is present in libxl_domain_build_info,
>   * containing the node-affinity for the domain.
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index b5506b1..a44c42a 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -349,6 +349,7 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
>          libxl_defbool_setdefault(&b_info->u.hvm.nographic, false);
>  
>          libxl_defbool_setdefault(&b_info->u.hvm.gfx_passthru, false);
> +        libxl_defbool_setdefault(&b_info->u.hvm.gfx_passthru_primary, true);
>  
>          break;
>      case LIBXL_DOMAIN_TYPE_PV:
> diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
> index e37e579..754e89d 100644
> --- a/tools/libxl/libxl_types.idl
> +++ b/tools/libxl/libxl_types.idl
> @@ -367,7 +367,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
>                                         ("sdl",              libxl_sdl_info),
>                                         ("spice",            libxl_spice_info),
>                                         
> -                                       ("gfx_passthru",     libxl_defbool),
> +                                       ("gfx_passthru",             libxl_defbool),
> +                                       ("gfx_passthru_primary",     libxl_defbool),
>                                         
>                                         ("serial",           string),
>                                         ("boot",             string),
> diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
> index 513b404..98b5a6e 100644
> --- a/tools/libxl/xl_cmdimpl.c
> +++ b/tools/libxl/xl_cmdimpl.c
> @@ -1645,6 +1645,8 @@ skip_vfb:
>          xlu_cfg_get_defbool(config, "nographic", &b_info->u.hvm.nographic, 0);
>          xlu_cfg_get_defbool(config, "gfx_passthru", 
>                              &b_info->u.hvm.gfx_passthru, 0);
> +        xlu_cfg_get_defbool(config, "gfx_passthru_primary",
> +                            &b_info->u.hvm.gfx_passthru_primary, 0);
>          xlu_cfg_replace_string (config, "serial", &b_info->u.hvm.serial, 0);
>          xlu_cfg_replace_string (config, "boot", &b_info->u.hvm.boot, 0);
>          xlu_cfg_get_defbool(config, "usb", &b_info->u.hvm.usb, 0);

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-03 10:30     ` Jan Beulich
  2014-07-03 10:49       ` Sander Eikelenboom
@ 2014-07-03 14:50       ` Ian Campbell
  2014-07-03 14:53         ` Ian Campbell
  1 sibling, 1 reply; 69+ messages in thread
From: Ian Campbell @ 2014-07-03 14:50 UTC (permalink / raw)
  To: Jan Beulich
  Cc: tim, paolo.valente, keir, stefano.stabellini, andrew.cooper3,
	dario.faggioli, Ian.Jackson, xen-devel, julien.grall,
	Sander Eikelenboom, etrudeau, Arianna Avanzini, viktor.kleinik

On Thu, 2014-07-03 at 11:30 +0100, Jan Beulich wrote:
> >>> On 02.07.14 at 21:00, <linux@eikelenboom.it> wrote:
> > Wednesday, July 2, 2014, 8:42:21 PM, you wrote:
> >> --- a/docs/man/xl.cfg.pod.5
> >> +++ b/docs/man/xl.cfg.pod.5
> >> @@ -601,6 +601,13 @@ More information about Xen gfx_passthru feature is available
> >>  on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
> >>  wiki page.
> >>  
> >> +=item B<gfx_passthru_primary=BOOLEAN>
> >> +
> >> +If set to true, indicates that one of the GPUs passed through to the
> >> +domain is the primary one; therefore allows to the domain's stubdoman
> >> +access permissions for the VGA framebuffer. Note that this option
> >> +defaults to true.
> >> +
> > 
> > Wouldn't it make sense to make it a pci <BDF> instead of boolean, 
> > so that instead of: "one of the GPU's passed is the primary",
> > you could actually specify: "this *specific* GPU passed through i would like 
> > to be the primary" ?
> 
> No. You can't just make some card primary (with "primary" really
> meaning accessible via the legacy VGA interface). Within a host
> there's exactly one card that can be primary. If that card gets
> passed through, it can also be primary in the guest. Any other
> card, not having the legacy VGA ports routed through the
> corresponding circuitry, can't all of the sudden become the
> primary one in a guest.
> 
> Consequently this shouldn't be a config file setting, but something
> that gets worked out by looking at the PCI config spaces of the
> passed through card and eventual upstream bridges.

What specifically should Arianna be looking for? THe PCI device class or
something else?

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-03 14:50       ` Ian Campbell
@ 2014-07-03 14:53         ` Ian Campbell
  2014-07-03 15:17           ` Jan Beulich
  0 siblings, 1 reply; 69+ messages in thread
From: Ian Campbell @ 2014-07-03 14:53 UTC (permalink / raw)
  To: Jan Beulich
  Cc: tim, paolo.valente, keir, stefano.stabellini, andrew.cooper3,
	dario.faggioli, Ian.Jackson, xen-devel, julien.grall,
	Sander Eikelenboom, etrudeau, Arianna Avanzini, viktor.kleinik

On Thu, 2014-07-03 at 15:50 +0100, Ian Campbell wrote:
> On Thu, 2014-07-03 at 11:30 +0100, Jan Beulich wrote:
> > >>> On 02.07.14 at 21:00, <linux@eikelenboom.it> wrote:
> > > Wednesday, July 2, 2014, 8:42:21 PM, you wrote:
> > >> --- a/docs/man/xl.cfg.pod.5
> > >> +++ b/docs/man/xl.cfg.pod.5
> > >> @@ -601,6 +601,13 @@ More information about Xen gfx_passthru feature is available
> > >>  on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
> > >>  wiki page.
> > >>  
> > >> +=item B<gfx_passthru_primary=BOOLEAN>
> > >> +
> > >> +If set to true, indicates that one of the GPUs passed through to the
> > >> +domain is the primary one; therefore allows to the domain's stubdoman
> > >> +access permissions for the VGA framebuffer. Note that this option
> > >> +defaults to true.
> > >> +
> > > 
> > > Wouldn't it make sense to make it a pci <BDF> instead of boolean, 
> > > so that instead of: "one of the GPU's passed is the primary",
> > > you could actually specify: "this *specific* GPU passed through i would like 
> > > to be the primary" ?
> > 
> > No. You can't just make some card primary (with "primary" really
> > meaning accessible via the legacy VGA interface). Within a host
> > there's exactly one card that can be primary. If that card gets
> > passed through, it can also be primary in the guest. Any other
> > card, not having the legacy VGA ports routed through the
> > corresponding circuitry, can't all of the sudden become the
> > primary one in a guest.
> > 
> > Consequently this shouldn't be a config file setting, but something
> > that gets worked out by looking at the PCI config spaces of the
> > passed through card and eventual upstream bridges.
> 
> What specifically should Arianna be looking for? THe PCI device class or
> something else?

Qemu-trad seems to use:
    if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 )
        return ret;

Is that sufficient?

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions
  2014-07-03 14:40   ` Ian Campbell
@ 2014-07-03 15:00     ` Julien Grall
  2014-07-03 15:15       ` Ian Campbell
  0 siblings, 1 reply; 69+ messages in thread
From: Julien Grall @ 2014-07-03 15:00 UTC (permalink / raw)
  To: xen-devel

On 07/03/2014 03:40 PM, Ian Campbell wrote:
> On Wed, 2014-07-02 at 20:42 +0200, Arianna Avanzini wrote:
>> This commit changes the function apply_p2m_changes() to unwind changes
>> performed while mapping an I/O-memory region, if errors are seen during
>> the operation. This is useful to avoid that I/O-memory areas are
>> partially accessible to guests.
> 
> I think it won't quite unwind, since it will actually destroy whatever
> was there before we tried to put something new.
> 
> Is there anything here which is specific to I/O memory areas? It seems
> to affect all mapping types.

I think it's fine to unmap for mapping types.

>> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
>> Cc: Dario Faggioli <dario.faggioli@citrix.com>
>> Cc: Paolo Valente <paolo.valente@unimore.it>
>> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
>> Cc: Julien Grall <julien.grall@citrix.com>
>> Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
>> Cc: Jan Beulich <jbeulich@suse.com>
>> Cc: Keir Fraser <keir@xen.org>
>> Cc: Tim Deegan <tim@xen.org>
>> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>> Cc: Eric Trudeau <etrudeau@broadcom.com>
>> Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
>>
>> ---
>>
>>     v9:
>>         - Let apply_p2m_ranges() unwind its own progress instead of relying on
>>           the caller to unmap partially-mapped I/O-memory regions.
>>
>> ---
>>  xen/arch/arm/p2m.c | 16 ++++++++++++----
>>  1 file changed, 12 insertions(+), 4 deletions(-)
>>
>> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
>> index 22646e9..92fc4ec 100644
>> --- a/xen/arch/arm/p2m.c
>> +++ b/xen/arch/arm/p2m.c
>> @@ -314,7 +314,7 @@ static int apply_p2m_changes(struct domain *d,
>>      unsigned long cur_first_page = ~0,
>>                    cur_first_offset = ~0,
>>                    cur_second_offset = ~0;
>> -    unsigned long count = 0;
>> +    unsigned long count = 0, inserted = 0;
>>      unsigned int flush = 0;
>>      bool_t populate = (op == INSERT || op == ALLOCATE);
>>      lpae_t pte;
>> @@ -328,6 +328,7 @@ static int apply_p2m_changes(struct domain *d,
>>  
>>      spin_lock(&p2m->lock);
>>  
>> +unwind:
> 
> I think I'd prefer a recursive call to the use of goto.
> 
> In particular the use of goto will result in the overall function
> appearing to succeed, won't it? Because the REMOVE will have succeeded.
> 
>>      addr = start_gpaddr;
>>      while ( addr < end_gpaddr )
>>      {
>> @@ -338,7 +339,9 @@ static int apply_p2m_changes(struct domain *d,
>>              if ( !first )
>>              {
>>                  rc = -EINVAL;
>> -                goto out;
>> +                end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;
> 
> Isn't start_gpaddr + inserted * PAGE_SIZE == addr at any given moment?
> 
> Or you could just recurse on the entire region, which is much simpler I
> think, especially when you consider that you are clearing the region
> rather than unwinding it.
> 
>> @@ -384,7 +389,9 @@ static int apply_p2m_changes(struct domain *d,
>>                                    flush_pt);
>>              if ( rc < 0 ) {
>>                  printk("p2m_populate_ram: L2 failed\n");
>> -                goto out;
>> +                end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;
>> +                op = REMOVE;
>> +                goto unwind;
>>              }
> 
> What about the L3 ALLOCATE case? Or is you intention only to handle
> INSERT (but you partially handle ALLOCATE)?
> 
>>          }
>>  
>> @@ -441,6 +448,7 @@ static int apply_p2m_changes(struct domain *d,
>>                      pte = mfn_to_p2m_entry(maddr >> PAGE_SHIFT, mattr, t);
>>                      p2m_write_pte(&third[third_table_offset(addr)],
>>                                    pte, flush_pt);
>> +                    inserted++;
>>                  }
>>                  break;
>>              case REMOVE:
> 
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> http://lists.xen.org/xen-devel
> 


-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions
  2014-07-03 15:00     ` Julien Grall
@ 2014-07-03 15:15       ` Ian Campbell
  0 siblings, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-03 15:15 UTC (permalink / raw)
  To: Julien Grall; +Cc: xen-devel

On Thu, 2014-07-03 at 16:00 +0100, Julien Grall wrote:
> On 07/03/2014 03:40 PM, Ian Campbell wrote:
> > On Wed, 2014-07-02 at 20:42 +0200, Arianna Avanzini wrote:
> >> This commit changes the function apply_p2m_changes() to unwind changes
> >> performed while mapping an I/O-memory region, if errors are seen during
> >> the operation. This is useful to avoid that I/O-memory areas are
> >> partially accessible to guests.
> > 
> > I think it won't quite unwind, since it will actually destroy whatever
> > was there before we tried to put something new.
> > 
> > Is there anything here which is specific to I/O memory areas? It seems
> > to affect all mapping types.
> 
> I think it's fine to unmap for mapping types.

Agreed, but the commit message doesn't reflect that.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-03 14:53         ` Ian Campbell
@ 2014-07-03 15:17           ` Jan Beulich
  2014-07-03 15:25             ` Ian Campbell
  0 siblings, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-07-03 15:17 UTC (permalink / raw)
  To: Ian Campbell
  Cc: tim, paolo.valente, keir, stefano.stabellini, andrew.cooper3,
	dario.faggioli, Ian.Jackson, xen-devel, julien.grall,
	Sander Eikelenboom, etrudeau, Arianna Avanzini, viktor.kleinik

>>> On 03.07.14 at 16:53, <Ian.Campbell@citrix.com> wrote:
> On Thu, 2014-07-03 at 15:50 +0100, Ian Campbell wrote:
>> What specifically should Arianna be looking for? THe PCI device class or
>> something else?
> 
> Qemu-trad seems to use:
>     if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 )
>         return ret;
> 
> Is that sufficient?

I don't think so - I'd expect secondary cards to also be showing this
class/sub-class (but I have no system with two or more cards where
I could at least empirically check), i.e. that would only be sufficient
when there's no upstream bridge. PCI_BRIDGE_CTL_VGA (on
upstream bridges) and maybe (but unlikely)
PCI_COMMAND_VGA_PALETTE (on the device itself and perhaps also
upstream bridges) would seem to be the indicators. But I'm afraid
this really needs to be properly answered by a PCI expert.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-03 15:17           ` Jan Beulich
@ 2014-07-03 15:25             ` Ian Campbell
  2014-07-03 15:37               ` Jan Beulich
  2014-07-03 15:45               ` Sander Eikelenboom
  0 siblings, 2 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-03 15:25 UTC (permalink / raw)
  To: Jan Beulich
  Cc: tim, paolo.valente, keir, stefano.stabellini, andrew.cooper3,
	dario.faggioli, Ian.Jackson, xen-devel, julien.grall,
	Sander Eikelenboom, etrudeau, Arianna Avanzini, viktor.kleinik

On Thu, 2014-07-03 at 16:17 +0100, Jan Beulich wrote:
> >>> On 03.07.14 at 16:53, <Ian.Campbell@citrix.com> wrote:
> > On Thu, 2014-07-03 at 15:50 +0100, Ian Campbell wrote:
> >> What specifically should Arianna be looking for? THe PCI device class or
> >> something else?
> > 
> > Qemu-trad seems to use:
> >     if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 )
> >         return ret;
> > 
> > Is that sufficient?
> 
> I don't think so - I'd expect secondary cards to also be showing this
> class/sub-class (but I have no system with two or more cards where
> I could at least empirically check), i.e. that would only be sufficient
> when there's no upstream bridge. PCI_BRIDGE_CTL_VGA (on
> upstream bridges) and maybe (but unlikely)
> PCI_COMMAND_VGA_PALETTE (on the device itself and perhaps also
> upstream bridges) would seem to be the indicators. But I'm afraid
> this really needs to be properly answered by a PCI expert.

Hrm, I'm not sure I see that happening any time soon...

Given that the above class-based check has apparently been fine since
however long could we live with it in the context of this series?

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-03 15:25             ` Ian Campbell
@ 2014-07-03 15:37               ` Jan Beulich
  2014-07-03 16:11                 ` Ian Campbell
  2014-07-03 15:45               ` Sander Eikelenboom
  1 sibling, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-07-03 15:37 UTC (permalink / raw)
  To: Ian Campbell
  Cc: tim, paolo.valente, keir, stefano.stabellini, andrew.cooper3,
	dario.faggioli, Ian.Jackson, xen-devel, julien.grall,
	Sander Eikelenboom, etrudeau, Arianna Avanzini, viktor.kleinik

>>> On 03.07.14 at 17:25, <Ian.Campbell@citrix.com> wrote:
> On Thu, 2014-07-03 at 16:17 +0100, Jan Beulich wrote:
>> >>> On 03.07.14 at 16:53, <Ian.Campbell@citrix.com> wrote:
>> > On Thu, 2014-07-03 at 15:50 +0100, Ian Campbell wrote:
>> >> What specifically should Arianna be looking for? THe PCI device class or
>> >> something else?
>> > 
>> > Qemu-trad seems to use:
>> >     if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 )
>> >         return ret;
>> > 
>> > Is that sufficient?
>> 
>> I don't think so - I'd expect secondary cards to also be showing this
>> class/sub-class (but I have no system with two or more cards where
>> I could at least empirically check), i.e. that would only be sufficient
>> when there's no upstream bridge. PCI_BRIDGE_CTL_VGA (on
>> upstream bridges) and maybe (but unlikely)
>> PCI_COMMAND_VGA_PALETTE (on the device itself and perhaps also
>> upstream bridges) would seem to be the indicators. But I'm afraid
>> this really needs to be properly answered by a PCI expert.
> 
> Hrm, I'm not sure I see that happening any time soon...
> 
> Given that the above class-based check has apparently been fine since
> however long could we live with it in the context of this series?

As said on an earlier version of the series - this is tools code, so
ultimately you judge. I'm merely pointing out that we're apparently
spreading a pre-existing shortcoming.

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-03 15:25             ` Ian Campbell
  2014-07-03 15:37               ` Jan Beulich
@ 2014-07-03 15:45               ` Sander Eikelenboom
  1 sibling, 0 replies; 69+ messages in thread
From: Sander Eikelenboom @ 2014-07-03 15:45 UTC (permalink / raw)
  To: Ian Campbell
  Cc: tim, paolo.valente, keir, stefano.stabellini, andrew.cooper3,
	dario.faggioli, Ian.Jackson, xen-devel, julien.grall, etrudeau,
	Jan Beulich, Arianna Avanzini, viktor.kleinik


Thursday, July 3, 2014, 5:25:56 PM, you wrote:

> On Thu, 2014-07-03 at 16:17 +0100, Jan Beulich wrote:
>> >>> On 03.07.14 at 16:53, <Ian.Campbell@citrix.com> wrote:
>> > On Thu, 2014-07-03 at 15:50 +0100, Ian Campbell wrote:
>> >> What specifically should Arianna be looking for? THe PCI device class or
>> >> something else?
>> > 
>> > Qemu-trad seems to use:
>> >     if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 )
>> >         return ret;
>> > 
>> > Is that sufficient?
>> 
>> I don't think so - I'd expect secondary cards to also be showing this
>> class/sub-class (but I have no system with two or more cards where
>> I could at least empirically check), i.e. that would only be sufficient
>> when there's no upstream bridge. PCI_BRIDGE_CTL_VGA (on
>> upstream bridges) and maybe (but unlikely)
>> PCI_COMMAND_VGA_PALETTE (on the device itself and perhaps also
>> upstream bridges) would seem to be the indicators. But I'm afraid
>> this really needs to be properly answered by a PCI expert.

> Hrm, I'm not sure I see that happening any time soon...

I'm by *NOOOO* means an expert, however:

There has been some dicussion on the lkml / qemu list which has some comments 
about what is in specs:
https://lists.gnu.org/archive/html/qemu-devel/2014-01/msg01985.html

So the most prominent seems to be the ordering of the pci devices, boot vga ==  
first vga adapter. An other way suggested of setting the primary card was indeed 
with  PCI_BRIDGE_CTL_VGA, but that required the other VGA devices not being on 
the root bus (as it is now in qemu). Perhaps that would make things more 
flexible, putting passed through devices behind bridges in guests ?

> Given that the above class-based check has apparently been fine since
> however long could we live with it in the context of this series?

> Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-03 15:37               ` Jan Beulich
@ 2014-07-03 16:11                 ` Ian Campbell
  0 siblings, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-03 16:11 UTC (permalink / raw)
  To: Jan Beulich
  Cc: tim, paolo.valente, keir, stefano.stabellini, andrew.cooper3,
	dario.faggioli, Ian.Jackson, xen-devel, julien.grall,
	Sander Eikelenboom, etrudeau, Arianna Avanzini, viktor.kleinik


On Thu, 2014-07-03 at 16:37 +0100, Jan Beulich wrote:
> >>> On 03.07.14 at 17:25, <Ian.Campbell@citrix.com> wrote:
> > On Thu, 2014-07-03 at 16:17 +0100, Jan Beulich wrote:
> >> >>> On 03.07.14 at 16:53, <Ian.Campbell@citrix.com> wrote:
> >> > On Thu, 2014-07-03 at 15:50 +0100, Ian Campbell wrote:
> >> >> What specifically should Arianna be looking for? THe PCI device class or
> >> >> something else?
> >> > 
> >> > Qemu-trad seems to use:
> >> >     if ( !gfx_passthru || real_device->pci_dev->device_class != 0x0300 )
> >> >         return ret;
> >> > 
> >> > Is that sufficient?
> >> 
> >> I don't think so - I'd expect secondary cards to also be showing this
> >> class/sub-class (but I have no system with two or more cards where
> >> I could at least empirically check), i.e. that would only be sufficient
> >> when there's no upstream bridge. PCI_BRIDGE_CTL_VGA (on
> >> upstream bridges) and maybe (but unlikely)
> >> PCI_COMMAND_VGA_PALETTE (on the device itself and perhaps also
> >> upstream bridges) would seem to be the indicators. But I'm afraid
> >> this really needs to be properly answered by a PCI expert.
> > 
> > Hrm, I'm not sure I see that happening any time soon...
> > 
> > Given that the above class-based check has apparently been fine since
> > however long could we live with it in the context of this series?
> 
> As said on an earlier version of the series - this is tools code, so
> ultimately you judge. I'm merely pointing out that we're apparently
> spreading a pre-existing shortcoming.

OK, IMHO given that it's totally orthogonal to the actual aim of the
series and given that it is not making things worse nor backing us into
a corner which we cannot get out we can live with it.

So we can go with the PCI device class based check.

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM
  2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
                   ` (13 preceding siblings ...)
  2014-07-02 18:42 ` [PATCH v9 14/14] xen/common: do not implicitly permit access to mapped I/O memory Arianna Avanzini
@ 2014-07-11 13:51 ` Julien Grall
  2014-07-11 14:24   ` Ian Campbell
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
  14 siblings, 2 replies; 69+ messages in thread
From: Julien Grall @ 2014-07-11 13:51 UTC (permalink / raw)
  To: Arianna Avanzini, xen-devel
  Cc: julien.grall, paolo.valente, keir, stefano.stabellini, tim,
	dario.faggioli, Ian.Jackson, Ian.Campbell, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

Hi Arianna,

Lots of patches has been pushed upstream since last week (GICv2 and P2M,
reworking).

This series doesn't apply cleanly anymore and need some rework. Could
you rebase it to the latest master?

Thanks,

On 07/02/2014 07:42 PM, Arianna Avanzini wrote:
> Hello,
> here is finally the nineth version of my implementation proposal for the
> hypercall XEN_DOMCTL_memory_mapping for the ARM architecture. First of all,
> I am deeply sorry for the delay and for blocking patchsets of which this one
> is a dependency. As usual, I'm trying to keep this cover letter as brief as
> I can by listing here only the most relevant changes, while a more detailed
> description can be found in the commit message and in the changelog of each
> patch. Also, more information about the patch series can be found in the
> last full cover letter ([1]).
> Please note that the one that was the series' first patch has been merged
> two weeks ago by Ian Campbell ([2]), and this is why it is missing from this
> patchset.
> 
> Patch 0001 has been fixed according to suggestions provided by Julien Grall
> and Ian Campbell; it is also worthy to say that now the added checks don't stop
> unmapping when failing to unmap an I/O-memory mapping, but merely emit a
> warning. This choice has two benefits: it prevents I/O-memory regions from
> remaining partially accessible to a domain, and it lets the handling of such a
> failure match the one introduced for x86 by patch 0005 in the lighter warn-
> only form requested by Jan Beulich.
> 
> Patch 0004 has been modified according to directives given by Julien Grall and
> Ian Campbell: it now lets the function apply_p2m_changes() unwind its own
> progress when failing to INSERT a new mapping.
> 
> Patch 0007 now adds the MTRR-related memory_type_changed() function for ARM
> as just a stub instead of creating and ad-hoc file and header, as suggested by
> Julien Grall and seconded by Jan Beulich and Ian Campbell.
> 
> Patch 0008 has been fixed according to requests from Jan Beulich.
> 
> Patch 0009 no more exposes mfn_t to the common code, as requested by Julien
> Grall and approved by Ian Campbell and Tim Deegan.
> 
> Patch 0011 has been fixed as per Julien Grall's indications.
> 
> A new patch 0012 has been added to the patch series. The patch attempts to
> address an issue pointed out by Jan Beulich, concerning the passthru of
> different GPUs to different domain, each one designed as primary VGA device
> of its own domain with gfx_passthru = 1 in the domain config. Patch 0013
> would grant access permission to the VGA framebuffer to each domain with
> gfx_passthru in its config, while access permission must be granted only to
> the domain having the primary GPU passthru to it.
> Unfortunately, I haven't found a way to distinguish the primary GPU from the
> other ones, and I decided to rely on user input. Patch 0012, in fact, adds a
> new option to libxl configuration, which allows the user to specify if one of
> the passthru VGA devices is primary. Only a domain with both gfx_passthru = 1
> and gfx_passthru_primary = 1 (and its stubdomain, see the comment on patch
> 0013 below) will have access permission to VGA-specific I/O-memory regions.
> Please note that the default for the new option is true, to avoid breaking
> interaction with QEMU when possible; AFAIK QEMU will however try to map the
> I/O-memory region to all guests requesting GFX passthrough.
> 
> Patch 0013 now grants access permission to VGA-specific I/O-memory regions
> both to the domain with gfx_passthru = 1 and gfx_passthru_primary = 1 and its
> stubdomain, as, after patch 0014, the memory_mapping DOMCTL will check for
> both, as pointed out by Julien Grall.
> 
> The code has again been tested on a cubieboard2, with Linux v3.15-rc3 as a dom0
> and ERIKA Enterprise ([3]) as a domU. The x86 bits have been tested on an x86_64
> machine with Linux 3.15.0-rc5 as both dom0 and domU.
> Any feedback about this new version of the patchset is more than welcome,
> Arianna
> 
> [1] http://lists.xen.org/archives/html/xen-devel/2014-03/msg01724.html
> [2] http://markmail.org/message/svp3byd62eol375y
> [3] http://erika.tuxfamily.org/drupal/
> 
> Arianna Avanzini (14):
>   arch/arm: add consistency check to REMOVE p2m changes
>   arch/arm: let map_mmio_regions() take pfn as parameters
>   arch/arm: let map_mmio_regions() use start and count
>   arch/arm: unmap partially-mapped I/O-memory regions
>   arch/x86: warn if to-be-removed mapping does not exist
>   arch/x86: cleanup memory_mapping DOMCTL
>   xen/common: add ARM stub for the function memory_type_changed()
>   xen/x86: factor out map and unmap from the memory_mapping DOMCTL
>   xen/common: move the memory_mapping DOMCTL hypercall to common code
>   tools/libxl: parse optional start gfn from the iomem config option
>   tools/libxl: handle the iomem parameter with the memory_mapping hcall
>   tools/libxl: read from config if passing through primary GPU
>   tools/libxl: explicitly grant access to needed I/O-memory ranges
>   xen/common: do not implicitly permit access to mapped I/O memory
> 
>  docs/man/xl.cfg.pod.5                | 25 +++++++++---
>  tools/libxc/xc_domain.c              | 10 +++++
>  tools/libxl/libxl.h                  | 17 ++++++++
>  tools/libxl/libxl_create.c           | 51 ++++++++++++++++++++++++
>  tools/libxl/libxl_internal.h         |  1 +
>  tools/libxl/libxl_pci.c              | 26 +++++-------
>  tools/libxl/libxl_types.idl          |  7 +++-
>  tools/libxl/xl_cmdimpl.c             | 19 +++++----
>  xen/arch/arm/domain_build.c          |  7 ++--
>  xen/arch/arm/gic.c                   | 15 +++----
>  xen/arch/arm/p2m.c                   | 77 ++++++++++++++++++++++++++++++------
>  xen/arch/arm/platforms/exynos5.c     |  9 ++---
>  xen/arch/arm/platforms/omap5.c       | 17 ++++----
>  xen/arch/arm/platforms/xgene-storm.c | 16 +++++---
>  xen/arch/x86/domctl.c                | 76 -----------------------------------
>  xen/arch/x86/mm/p2m.c                | 55 ++++++++++++++++++++++++--
>  xen/common/domctl.c                  | 54 ++++++++++++++++++++++++-
>  xen/include/asm-arm/mm.h             |  2 +
>  xen/include/asm-arm/p2m.h            | 11 +++---
>  xen/include/asm-x86/p2m.h            |  3 +-
>  xen/include/xen/p2m-common.h         | 16 ++++++++
>  21 files changed, 354 insertions(+), 160 deletions(-)
>  create mode 100644 xen/include/xen/p2m-common.h
> 


-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM
  2014-07-11 13:51 ` [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Julien Grall
@ 2014-07-11 14:24   ` Ian Campbell
  2014-07-11 17:00     ` Arianna Avanzini
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
  1 sibling, 1 reply; 69+ messages in thread
From: Ian Campbell @ 2014-07-11 14:24 UTC (permalink / raw)
  To: Julien Grall
  Cc: paolo.valente, keir, stefano.stabellini, tim, dario.faggioli,
	Ian.Jackson, xen-devel, julien.grall, etrudeau, andrew.cooper3,
	JBeulich, Arianna Avanzini, viktor.kleinik

On Fri, 2014-07-11 at 14:51 +0100, Julien Grall wrote:
> Hi Arianna,
> 
> Lots of patches has been pushed upstream since last week (GICv2 and P2M,
> reworking).

Sorry Arianna, this series had slipped my mind, I should have
coordinated with you on the P2M changes.

I think the new p2m structure is more regular and probably a bit easier
to work with, but if you have any questions about it please shout.

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM
  2014-07-11 14:24   ` Ian Campbell
@ 2014-07-11 17:00     ` Arianna Avanzini
  2014-07-14  8:54       ` Ian Campbell
  0 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-11 17:00 UTC (permalink / raw)
  To: Ian Campbell, Julien Grall
  Cc: paolo.valente, keir, stefano.stabellini, tim, dario.faggioli,
	Ian.Jackson, xen-devel, julien.grall, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

On 07/11/2014 04:24 PM, Ian Campbell wrote:
> On Fri, 2014-07-11 at 14:51 +0100, Julien Grall wrote:
>> Hi Arianna,
>>
>> Lots of patches has been pushed upstream since last week (GICv2 and P2M,
>> reworking).
> 
> Sorry Arianna, this series had slipped my mind, I should have
> coordinated with you on the P2M changes.
> 
> I think the new p2m structure is more regular and probably a bit easier
> to work with, but if you have any questions about it please shout.
> 

Thank you both, I will certainly do. I'll provide a version of the series
updated to the new p2m structure in the weekend, while I'll send a v10
addressing all of your very useful comments within the next week.

Thank you,
Arianna


> Ian.
> 


-- 
/*
 * Arianna Avanzini
 * avanzini.arianna@gmail.com
 * 73628@studenti.unimore.it
 */

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM
  2014-07-11 13:51 ` [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Julien Grall
  2014-07-11 14:24   ` Ian Campbell
@ 2014-07-14  0:50   ` Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
                       ` (13 more replies)
  1 sibling, 14 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Hello,

I have adapted the v9 patchset to work on top of commit 7bddc6b, which I see
as head of the development repository's master branch. The changes with
respect to the original v9 have ultimately affected only patches from 0001 to
0005: I hope I haven't missed anything else, in case of any issue please do
not hesitate to tell me.

Also, please note that this resend patchset does not address any of the
comments made for the original v9; I will be sending a v10 patchset within
the upcoming week. The implementation of this resend patchset is described
in the changelog of each patch and in the original cover letter of v9 ([1]).

The patchset has been tested on a cubieboard2 with Linux 3.15 as dom0 and
both ERIKA Enterprise ([2]) and Linux 3.15 as domU. The x86 bits have been also
tested on an x86_64 machine with Linux 3.15 as both dom0 and domU.

Thank you,
Arianna

[1] http://markmail.org/thread/3hvcainjehch4756
[2] http://erika.tuxfamily.org/drupal/

Arianna Avanzini (14):
  arch/arm: add consistency check to REMOVE p2m changes
  arch/arm: let map_mmio_regions() take pfn as parameters
  arch/arm: let map_mmio_regions() use start and count
  arch/arm: unmap partially-mapped I/O-memory regions
  arch/x86: warn if to-be-removed mapping does not exist
  arch/x86: cleanup memory_mapping DOMCTL
  xen/common: add ARM stub for the function memory_type_changed()
  xen/x86: factor out map and unmap from the memory_mapping DOMCTL
  xen/common: move the memory_mapping DOMCTL hypercall to common code
  tools/libxl: parse optional start gfn from the iomem config option
  tools/libxl: handle the iomem parameter with the memory_mapping hcall
  tools/libxl: read from config if passing through primary GPU
  tools/libxl: explicitly grant access to needed I/O-memory ranges
  xen/common: do not implicitly permit access to mapped I/O memory

 docs/man/xl.cfg.pod.5                | 25 ++++++++---
 tools/libxc/xc_domain.c              | 10 +++++
 tools/libxl/libxl.h                  | 17 ++++++++
 tools/libxl/libxl_create.c           | 51 ++++++++++++++++++++++
 tools/libxl/libxl_internal.h         |  1 +
 tools/libxl/libxl_pci.c              | 26 +++++------
 tools/libxl/libxl_types.idl          |  7 ++-
 tools/libxl/xl_cmdimpl.c             | 19 ++++++---
 xen/arch/arm/domain_build.c          |  7 +--
 xen/arch/arm/gic-v2.c                | 15 +++----
 xen/arch/arm/p2m.c                   | 83 +++++++++++++++++++++++++++++++-----
 xen/arch/arm/platforms/exynos5.c     |  9 ++--
 xen/arch/arm/platforms/omap5.c       | 17 ++++----
 xen/arch/arm/platforms/xgene-storm.c | 16 ++++---
 xen/arch/x86/domctl.c                | 76 ---------------------------------
 xen/arch/x86/mm/p2m.c                | 55 ++++++++++++++++++++++--
 xen/common/domctl.c                  | 54 ++++++++++++++++++++++-
 xen/common/memory.c                  |  2 +-
 xen/include/asm-arm/mm.h             |  2 +
 xen/include/asm-arm/p2m.h            | 11 ++---
 xen/include/asm-x86/p2m.h            |  3 +-
 xen/include/xen/p2m-common.h         | 16 +++++++
 22 files changed, 362 insertions(+), 160 deletions(-)
 create mode 100644 xen/include/xen/p2m-common.h

-- 
1.9.3

^ permalink raw reply	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 01/14] arch/arm: add consistency check to REMOVE p2m changes
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-14 10:57       ` Julien Grall
  2014-07-14  0:50     ` [PATCH RESEND v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters Arianna Avanzini
                       ` (12 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the REMOVE case of the switch in apply_p2m_changes()
does not perform any consistency check on the mapping to be removed.
More in detail, the code does not check if the guest address to be
unmapped is actually mapped to the machine address given as a
parameter.
This commit adds the above-described consistency check to the REMOVE
path of apply_p2m_changes() and lets a warning be emitted when trying
to remove a non-existent mapping. This is instrumental to one of the
following commits, which implements the possibility to trigger the
removal of p2m ranges via the memory_mapping DOMCTL for ARM.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Don't return with an error when failing to remove a mapping, but
          simply keep unmapping.
        - Don't force assignment to the flush variable, as it is already
          set before the switch.
        - Change warning message to be more appropriate and clear; use the
          correct format for paddr_t and gdprintk(), which is more restricted
          than regular printk()s.
        - Adapt to rework of p2m-related functions for ARM.

    v8:
        - Re-add erroneously-removed increments to the maddr variable.
        - When failing to remove a mapping, add previously-mapped PT entry,
          unlock the p2m_lock and flush TLBs if necessary.
        - Emit an error message when failing to remove a mapping.
        - Remove tentative phrases from commit description.

    v7:
        - Silently ignore the fact that, when removing a mapping, the specified
          gfn is not mapped at all.
        - Remove spurious spacing change.

    v6:
        - Don't update "count" on REMOVE as it is only used inside the
          RELINQUISH case of the switch in apply_p2m_changes().
        - Return with an error if removal of a page fails instead of just
          skipping the page.

    v5:
        - Do not use a temporary variable to hold the machine address:
          use the "maddr" function parameter itself.
        - Increment the machine address also when first and second level
          mappings are not valid.
        - Get the actual machine frame number mapped to the guest frame
          number given as parameter to the function directly in the
          REMOVE case of the switch construct, as it might not be valid
          in other cases and its value might be uncorrectly used in the
          future.
        - Remove useless and/or harmful ASSERT; check however if the
          mapping is valid and skip the page if it is not.

    v4:
        - Remove useless and slow lookup and use already-available
          data from pte instead.
        - Correctly increment the local variable used to keep the
          machine address whose mapping is currently being removed.
        - Return with an error upon finding a mismatch between the
          actual machine address mapped to the guest address and
          the machine address passed as parameter, instead of just
          skipping the page.

---
 xen/arch/arm/p2m.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index c0c011a..5a77189 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -596,12 +596,30 @@ static int apply_one_level(struct domain *d,
 
         break;
 
-    case RELINQUISH:
     case REMOVE:
+        if ( is_mapping_aligned(*addr, end_gpaddr, *maddr, level_size) )
+        {
+            unsigned long mfn = orig_pte.p2m.base;
+            /*
+             * Ensure that the guest address addr currently being
+             * handled (that is in the range given as argument to
+             * this function) is actually mapped to the corresponding
+             * machine address in the specified range. maddr here is
+             * the machine address given to the function, while mfn
+             * is the machine frame number actually mapped to the
+             * guest address: check if the two correspond.
+             */
+             if ( p2m_valid(orig_pte) && *maddr != pfn_to_paddr(mfn) )
+                 printk("p2m_remove: mapping at %"PRIpaddr" is of maddr %"PRIpaddr" not %"PRIpaddr" as expected\n",
+                        *addr, pfn_to_paddr(mfn), *maddr);
+        }
+        /* fall through */
+    case RELINQUISH:
         if ( !p2m_valid(orig_pte) )
         {
             /* Progress up to next boundary */
             *addr = (*addr + level_size) & level_mask;
+            *maddr = (*maddr + level_size) & level_mask;
             return P2M_ONE_PROGRESS_NOP;
         }
 
@@ -614,6 +632,7 @@ static int apply_one_level(struct domain *d,
         p2m_write_pte(entry, pte, flush_cache);
 
         *addr += level_size;
+        *maddr += level_size;
 
         p2m->stats.mappings[level]--;
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-17 12:57       ` Ian Campbell
  2014-07-14  0:50     ` [PATCH RESEND v9 03/14] arch/arm: let map_mmio_regions() use start and count Arianna Avanzini
                       ` (11 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the map_mmio_regions() function, defined for the ARM
architecture, has parameters with paddr_t type. This interface,
however, needs caller functions to correctly page-align addresses
given as parameters to map_mmio_regions(). This commit changes the
function's interface to accept page frame numbers as parameters.
This commit also modifies caller functions in an attempt to adapt
them to the new interface.
This commit is meant to produce the minimum indispensable needed
changes; these are also instrumental to making the interface of
map_mmio_regions() symmetric with the unmap_mmio_regions() function,
that will be introduced in one of the next commits of the series
and will feature a pfn-based interface.

NOTE: platform-specific code has not been tested, save for the
      sunxi and the Arndale Exynos 5 platforms (see the Tested-by
      below for the latter).

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Tested-by: Julien Grall <julien.grall@citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Adapt to GIC rework.

    v7:
        - Remove useless decrements when using paddr_to_pfn_aligned().

    v5:
        - Add a macro for the paddr_to_pfn(PAGE_ALIGN(...)) pattern.
        - Hopefully improve commit description.

---
 xen/arch/arm/domain_build.c          |  7 ++++---
 xen/arch/arm/gic-v2.c                | 20 +++++++++++---------
 xen/arch/arm/p2m.c                   | 13 ++++++++-----
 xen/arch/arm/platforms/exynos5.c     | 11 ++++++-----
 xen/arch/arm/platforms/omap5.c       | 21 ++++++++++++---------
 xen/arch/arm/platforms/xgene-storm.c |  4 +++-
 xen/include/asm-arm/mm.h             |  2 ++
 xen/include/asm-arm/p2m.h            | 11 ++++++-----
 8 files changed, 52 insertions(+), 37 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 69188a4..f150933 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1018,9 +1018,10 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
                    addr & PAGE_MASK, PAGE_ALIGN(addr + size) - 1);
             return res;
         }
-        res = map_mmio_regions(d, addr & PAGE_MASK,
-                               PAGE_ALIGN(addr + size) - 1,
-                               addr & PAGE_MASK);
+        res = map_mmio_regions(d,
+                               paddr_to_pfn(addr & PAGE_MASK),
+                               paddr_to_pfn_aligned(addr + size),
+                               paddr_to_pfn(addr & PAGE_MASK));
         if ( res )
         {
             printk(XENLOG_ERR "Unable to map 0x%"PRIx64
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 843f5a1..8db5cd8 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -440,20 +440,22 @@ static int gicv2v_setup(struct domain *d)
      * The second page is always mapped at +4K irrespective of the
      * GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
      */
-    ret = map_mmio_regions(d, d->arch.vgic.cbase,
-                           d->arch.vgic.cbase + PAGE_SIZE - 1,
-                           gicv2.vbase);
+    ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase),
+                           paddr_to_pfn_aligned(d->arch.vgic.cbase + PAGE_SIZE),
+                           paddr_to_pfn(gicv2.vbase));
     if ( ret )
         return ret;
 
     if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
-        ret = map_mmio_regions(d, d->arch.vgic.cbase + PAGE_SIZE,
-                               d->arch.vgic.cbase + (2 * PAGE_SIZE) - 1,
-                               gicv2.vbase + PAGE_SIZE);
+        ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
+                               paddr_to_pfn_aligned(d->arch.vgic.cbase +
+                                                    (2 * PAGE_SIZE)),
+                               paddr_to_pfn(gicv2.vbase + PAGE_SIZE));
     else
-        ret = map_mmio_regions(d, d->arch.vgic.cbase + PAGE_SIZE,
-                               d->arch.vgic.cbase + (2 * PAGE_SIZE) - 1,
-                               gicv2.vbase + 16*PAGE_SIZE);
+        ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
+                               paddr_to_pfn_aligned(d->arch.vgic.cbase +
+			                            (2 * PAGE_SIZE)),
+                               paddr_to_pfn(gicv2.vbase + 16*PAGE_SIZE));
 
     return ret;
 }
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 5a77189..4555dc3 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -832,12 +832,15 @@ int p2m_populate_ram(struct domain *d,
 }
 
 int map_mmio_regions(struct domain *d,
-                     paddr_t start_gaddr,
-                     paddr_t end_gaddr,
-                     paddr_t maddr)
+                     unsigned long start_gfn,
+                     unsigned long end_gfn,
+                     unsigned long mfn)
 {
-    return apply_p2m_changes(d, INSERT, start_gaddr, end_gaddr,
-                             maddr, MATTR_DEV, p2m_mmio_direct);
+    return apply_p2m_changes(d, INSERT,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(end_gfn),
+                             pfn_to_paddr(mfn),
+                             MATTR_DEV, p2m_mmio_direct);
 }
 
 int guest_physmap_add_entry(struct domain *d,
diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index 65e584f..078b020 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -54,13 +54,14 @@ static int exynos5_init_time(void)
 static int exynos5_specific_mapping(struct domain *d)
 {
     /* Map the chip ID */
-    map_mmio_regions(d, EXYNOS5_PA_CHIPID, EXYNOS5_PA_CHIPID + PAGE_SIZE - 1,
-                     EXYNOS5_PA_CHIPID);
+    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_CHIPID),
+                     paddr_to_pfn_aligned(EXYNOS5_PA_CHIPID + PAGE_SIZE),
+                     paddr_to_pfn(EXYNOS5_PA_CHIPID));
 
     /* Map the PWM region */
-    map_mmio_regions(d, EXYNOS5_PA_TIMER,
-                     EXYNOS5_PA_TIMER + (PAGE_SIZE * 2) - 1,
-                     EXYNOS5_PA_TIMER);
+    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_TIMER),
+                     paddr_to_pfn_aligned(EXYNOS5_PA_TIMER + (PAGE_SIZE * 2)),
+                     paddr_to_pfn(EXYNOS5_PA_TIMER));
 
     return 0;
 }
diff --git a/xen/arch/arm/platforms/omap5.c b/xen/arch/arm/platforms/omap5.c
index c0f8537..16acd0c 100644
--- a/xen/arch/arm/platforms/omap5.c
+++ b/xen/arch/arm/platforms/omap5.c
@@ -102,21 +102,24 @@ static int omap5_init_time(void)
 static int omap5_specific_mapping(struct domain *d)
 {
     /* Map the PRM module */
-    map_mmio_regions(d, OMAP5_PRM_BASE, OMAP5_PRM_BASE + (PAGE_SIZE * 2) - 1,
-                     OMAP5_PRM_BASE);
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRM_BASE),
+                     paddr_to_pfn_aligned(OMAP5_PRM_BASE + (PAGE_SIZE * 2)),
+                     paddr_to_pfn(OMAP5_PRM_BASE));
 
     /* Map the PRM_MPU */
-    map_mmio_regions(d, OMAP5_PRCM_MPU_BASE,
-                     OMAP5_PRCM_MPU_BASE + PAGE_SIZE - 1,
-                     OMAP5_PRCM_MPU_BASE);
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRCM_MPU_BASE),
+                     paddr_to_pfn_aligned(OMAP5_PRCM_MPU_BASE + PAGE_SIZE),
+                     paddr_to_pfn(OMAP5_PRCM_MPU_BASE));
 
     /* Map the Wakeup Gen */
-    map_mmio_regions(d, OMAP5_WKUPGEN_BASE, OMAP5_WKUPGEN_BASE + PAGE_SIZE - 1,
-                     OMAP5_WKUPGEN_BASE);
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_WKUPGEN_BASE),
+                     paddr_to_pfn_aligned(OMAP5_WKUPGEN_BASE + PAGE_SIZE),
+                     paddr_to_pfn(OMAP5_WKUPGEN_BASE));
 
     /* Map the on-chip SRAM */
-    map_mmio_regions(d, OMAP5_SRAM_PA, OMAP5_SRAM_PA + (PAGE_SIZE * 32) - 1,
-                     OMAP5_SRAM_PA);
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_SRAM_PA),
+                     paddr_to_pfn_aligned(OMAP5_SRAM_PA + (PAGE_SIZE * 32)),
+                     paddr_to_pfn(OMAP5_SRAM_PA));
 
     return 0;
 }
diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
index 837d8e6..e50b916 100644
--- a/xen/arch/arm/platforms/xgene-storm.c
+++ b/xen/arch/arm/platforms/xgene-storm.c
@@ -47,7 +47,9 @@ static int map_one_mmio(struct domain *d, const char *what,
 
     printk("Additional MMIO %"PRIpaddr"-%"PRIpaddr" (%s)\n",
            start, end, what);
-    ret = map_mmio_regions(d, start, end, start);
+    ret = map_mmio_regions(d, paddr_to_pfn(start),
+                           paddr_to_pfn_aligned(end),
+                           paddr_to_pfn(start));
     if ( ret )
         printk("Failed to map %s @ %"PRIpaddr" to dom%d\n",
                what, start, d->domain_id);
diff --git a/xen/include/asm-arm/mm.h b/xen/include/asm-arm/mm.h
index 2552d34..9fa80a4 100644
--- a/xen/include/asm-arm/mm.h
+++ b/xen/include/asm-arm/mm.h
@@ -210,6 +210,8 @@ static inline void __iomem *ioremap_wc(paddr_t start, size_t len)
 #define paddr_to_pfn(pa)  ((unsigned long)((pa) >> PAGE_SHIFT))
 #define paddr_to_pdx(pa)    pfn_to_pdx(paddr_to_pfn(pa))
 
+/* Page-align address and convert to frame number format */
+#define paddr_to_pfn_aligned(paddr)    paddr_to_pfn(PAGE_ALIGN(paddr))
 
 static inline paddr_t __virt_to_maddr(vaddr_t va)
 {
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 327a79d..eea9c55 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -99,11 +99,12 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
 
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
-/* Map MMIO regions in the p2m: start_gaddr and end_gaddr is the range
- * in the guest physical address space to map, starting from the machine
- * address maddr. */
-int map_mmio_regions(struct domain *d, paddr_t start_gaddr,
-                     paddr_t end_gaddr, paddr_t maddr);
+/* Map MMIO regions in the p2m: start_gfn and end_gfn is the range in the guest
+ * physical address space to map, starting from the machine frame number mfn. */
+int map_mmio_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long end_gfn,
+                     unsigned long mfn);
 
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 03/14] arch/arm: let map_mmio_regions() use start and count
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions Arianna Avanzini
                       ` (10 subsequent siblings)
  13 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the arguments given to the function map_mmio_regions() to
describe the memory range to be mapped are the start and end page frame
numbers of the range to be mapped. However, this could give rise to
issues due to the range being inclusive or exclusive of the end gfn
given as parameter. This commit changes the interface of the function
to accept the start gfn and the number of gfns to be mapped.
This commit also changes the interface of the function map_one_mmio(),
helper for the xgene-storm platform, which is a wrapper for the function
map_mmio_regions() and does not need its arguments to be paddr_t.

NOTE: platform-specific code has not been tested, save for the
      sunxi and the Arndale Exynos 5 platforms (see the Tested-by
      below for the latter).

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Julien Grall <julien.grall@citrix.com>
Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>
Tested-by: Julien Grall <julien.grall@citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Adapt to GIC rework.

    v8:
        - Fix incorrect count used by map_mmio_regions() when calling
          apply_p2m_changes().
        - Use pfns as arguments to map_one_mmio().
        - Use the DIV_ROUND_UP() macro when appropriate.

---
 xen/arch/arm/domain_build.c          |  2 +-
 xen/arch/arm/gic-v2.c                | 13 ++++---------
 xen/arch/arm/p2m.c                   |  4 ++--
 xen/arch/arm/platforms/exynos5.c     |  6 ++----
 xen/arch/arm/platforms/omap5.c       | 12 ++++--------
 xen/arch/arm/platforms/xgene-storm.c | 18 ++++++++++--------
 xen/include/asm-arm/p2m.h            |  7 ++++---
 7 files changed, 27 insertions(+), 35 deletions(-)

diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index f150933..c58ad75 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -1020,7 +1020,7 @@ static int map_device(struct domain *d, struct dt_device_node *dev)
         }
         res = map_mmio_regions(d,
                                paddr_to_pfn(addr & PAGE_MASK),
-                               paddr_to_pfn_aligned(addr + size),
+                               DIV_ROUND_UP(size, PAGE_SIZE),
                                paddr_to_pfn(addr & PAGE_MASK));
         if ( res )
         {
diff --git a/xen/arch/arm/gic-v2.c b/xen/arch/arm/gic-v2.c
index 8db5cd8..1305542 100644
--- a/xen/arch/arm/gic-v2.c
+++ b/xen/arch/arm/gic-v2.c
@@ -440,22 +440,17 @@ static int gicv2v_setup(struct domain *d)
      * The second page is always mapped at +4K irrespective of the
      * GIC_64K_STRIDE quirk. The DTB passed to the guest reflects this.
      */
-    ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase),
-                           paddr_to_pfn_aligned(d->arch.vgic.cbase + PAGE_SIZE),
-                           paddr_to_pfn(gicv2.vbase));
+    ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase), 1,
+                            paddr_to_pfn(gicv2.vbase));
     if ( ret )
         return ret;
 
     if ( !platform_has_quirk(PLATFORM_QUIRK_GIC_64K_STRIDE) )
         ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
-                               paddr_to_pfn_aligned(d->arch.vgic.cbase +
-                                                    (2 * PAGE_SIZE)),
-                               paddr_to_pfn(gicv2.vbase + PAGE_SIZE));
+                               2, paddr_to_pfn(gicv2.vbase + PAGE_SIZE));
     else
         ret = map_mmio_regions(d, paddr_to_pfn(d->arch.vgic.cbase + PAGE_SIZE),
-                               paddr_to_pfn_aligned(d->arch.vgic.cbase +
-			                            (2 * PAGE_SIZE)),
-                               paddr_to_pfn(gicv2.vbase + 16*PAGE_SIZE));
+                               2, paddr_to_pfn(gicv2.vbase + 16*PAGE_SIZE));
 
     return ret;
 }
diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 4555dc3..1e6579f 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -833,12 +833,12 @@ int p2m_populate_ram(struct domain *d,
 
 int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
-                     unsigned long end_gfn,
+                     unsigned long nr_mfns,
                      unsigned long mfn)
 {
     return apply_p2m_changes(d, INSERT,
                              pfn_to_paddr(start_gfn),
-                             pfn_to_paddr(end_gfn),
+                             pfn_to_paddr(start_gfn + nr_mfns),
                              pfn_to_paddr(mfn),
                              MATTR_DEV, p2m_mmio_direct);
 }
diff --git a/xen/arch/arm/platforms/exynos5.c b/xen/arch/arm/platforms/exynos5.c
index 078b020..b65c2c2 100644
--- a/xen/arch/arm/platforms/exynos5.c
+++ b/xen/arch/arm/platforms/exynos5.c
@@ -54,13 +54,11 @@ static int exynos5_init_time(void)
 static int exynos5_specific_mapping(struct domain *d)
 {
     /* Map the chip ID */
-    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_CHIPID),
-                     paddr_to_pfn_aligned(EXYNOS5_PA_CHIPID + PAGE_SIZE),
+    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_CHIPID), 1,
                      paddr_to_pfn(EXYNOS5_PA_CHIPID));
 
     /* Map the PWM region */
-    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_TIMER),
-                     paddr_to_pfn_aligned(EXYNOS5_PA_TIMER + (PAGE_SIZE * 2)),
+    map_mmio_regions(d, paddr_to_pfn(EXYNOS5_PA_TIMER), 2,
                      paddr_to_pfn(EXYNOS5_PA_TIMER));
 
     return 0;
diff --git a/xen/arch/arm/platforms/omap5.c b/xen/arch/arm/platforms/omap5.c
index 16acd0c..9d6e504 100644
--- a/xen/arch/arm/platforms/omap5.c
+++ b/xen/arch/arm/platforms/omap5.c
@@ -102,23 +102,19 @@ static int omap5_init_time(void)
 static int omap5_specific_mapping(struct domain *d)
 {
     /* Map the PRM module */
-    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRM_BASE),
-                     paddr_to_pfn_aligned(OMAP5_PRM_BASE + (PAGE_SIZE * 2)),
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRM_BASE), 2,
                      paddr_to_pfn(OMAP5_PRM_BASE));
 
     /* Map the PRM_MPU */
-    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRCM_MPU_BASE),
-                     paddr_to_pfn_aligned(OMAP5_PRCM_MPU_BASE + PAGE_SIZE),
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_PRCM_MPU_BASE), 1,
                      paddr_to_pfn(OMAP5_PRCM_MPU_BASE));
 
     /* Map the Wakeup Gen */
-    map_mmio_regions(d, paddr_to_pfn(OMAP5_WKUPGEN_BASE),
-                     paddr_to_pfn_aligned(OMAP5_WKUPGEN_BASE + PAGE_SIZE),
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_WKUPGEN_BASE), 1,
                      paddr_to_pfn(OMAP5_WKUPGEN_BASE));
 
     /* Map the on-chip SRAM */
-    map_mmio_regions(d, paddr_to_pfn(OMAP5_SRAM_PA),
-                     paddr_to_pfn_aligned(OMAP5_SRAM_PA + (PAGE_SIZE * 32)),
+    map_mmio_regions(d, paddr_to_pfn(OMAP5_SRAM_PA), 32,
                      paddr_to_pfn(OMAP5_SRAM_PA));
 
     return 0;
diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
index e50b916..2980c0d 100644
--- a/xen/arch/arm/platforms/xgene-storm.c
+++ b/xen/arch/arm/platforms/xgene-storm.c
@@ -41,15 +41,13 @@ static uint32_t xgene_storm_quirks(void)
 }
 
 static int map_one_mmio(struct domain *d, const char *what,
-                         paddr_t start, paddr_t end)
+                         unsigned long start, unsigned long end)
 {
     int ret;
 
     printk("Additional MMIO %"PRIpaddr"-%"PRIpaddr" (%s)\n",
            start, end, what);
-    ret = map_mmio_regions(d, paddr_to_pfn(start),
-                           paddr_to_pfn_aligned(end),
-                           paddr_to_pfn(start));
+    ret = map_mmio_regions(d, start, end, end - start + 1, start);
     if ( ret )
         printk("Failed to map %s @ %"PRIpaddr" to dom%d\n",
                what, start, d->domain_id);
@@ -91,18 +89,22 @@ static int xgene_storm_specific_mapping(struct domain *d)
     int ret;
 
     /* Map the PCIe bus resources */
-    ret = map_one_mmio(d, "PCI MEM REGION", 0xe000000000UL, 0xe010000000UL);
+    ret = map_one_mmio(d, "PCI MEM REGION", paddr_to_pfn(0xe000000000UL),
+                                            paddr_to_pfn(0xe010000000UL));
     if ( ret )
         goto err;
 
-    ret = map_one_mmio(d, "PCI IO REGION", 0xe080000000UL, 0xe080010000UL);
+    ret = map_one_mmio(d, "PCI IO REGION", paddr_to_pfn(0xe080000000UL),
+                                           paddr_to_pfn(0xe080010000UL));
     if ( ret )
         goto err;
 
-    ret = map_one_mmio(d, "PCI CFG REGION", 0xe0d0000000UL, 0xe0d0200000UL);
+    ret = map_one_mmio(d, "PCI CFG REGION", paddr_to_pfn(0xe0d0000000UL),
+                                            paddr_to_pfn(0xe0d0200000UL));
     if ( ret )
         goto err;
-    ret = map_one_mmio(d, "PCI MSI REGION", 0xe010000000UL, 0xe010800000UL);
+    ret = map_one_mmio(d, "PCI MSI REGION", paddr_to_pfn(0xe010000000UL),
+                                            paddr_to_pfn(0xe010800000UL));
     if ( ret )
         goto err;
 
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index eea9c55..06c93a0 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -99,11 +99,12 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
 
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
-/* Map MMIO regions in the p2m: start_gfn and end_gfn is the range in the guest
- * physical address space to map, starting from the machine frame number mfn. */
+/* Map MMIO regions in the p2m: start_gfn and nr_mfns describe the range
+ * in the guest physical address space to map, starting from the machine
+ * frame number mfn. */
 int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
-                     unsigned long end_gfn,
+                     unsigned long nr_mfns,
                      unsigned long mfn);
 
 int guest_physmap_add_entry(struct domain *d,
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (2 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 03/14] arch/arm: let map_mmio_regions() use start and count Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 05/14] arch/x86: warn if to-be-removed mapping does not exist Arianna Avanzini
                       ` (9 subsequent siblings)
  13 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit changes the function apply_p2m_changes() to unwind changes
performed while mapping an I/O-memory region, if errors are seen during
the operation. This is useful to avoid that I/O-memory areas are
partially accessible to guests.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Let apply_p2m_ranges() unwind its own progress instead of relying on
          the caller to unmap partially-mapped I/O-memory regions.
        - Adapt to rework of p2m-related functions for ARM.

---
 xen/arch/arm/p2m.c | 33 +++++++++++++++++++++++++++++----
 1 file changed, 29 insertions(+), 4 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 1e6579f..e9f7c96 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -694,7 +694,7 @@ static int apply_p2m_changes(struct domain *d,
     unsigned long cur_first_page = ~0,
                   cur_first_offset = ~0,
                   cur_second_offset = ~0;
-    unsigned long count = 0;
+    unsigned long count = 0, inserted = 0;
     bool_t flush = false;
     bool_t flush_pt;
 
@@ -706,6 +706,7 @@ static int apply_p2m_changes(struct domain *d,
 
     spin_lock(&p2m->lock);
 
+unwind:
     addr = start_gpaddr;
     while ( addr < end_gpaddr )
     {
@@ -749,7 +750,15 @@ static int apply_p2m_changes(struct domain *d,
                               start_gpaddr, end_gpaddr,
                               &addr, &maddr, &flush,
                               mattr, t);
-        if ( ret < 0 ) { rc = ret ; goto out; }
+        if ( ret < 0 )
+        {
+            rc = ret ;
+            if ( op != INSERT ) goto out;
+            end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;
+            op = REMOVE;
+            goto unwind;
+        }
+        if ( op == INSERT ) inserted++;
         count += ret;
         if ( ret != P2M_ONE_DESCEND ) continue;
 
@@ -768,7 +777,15 @@ static int apply_p2m_changes(struct domain *d,
                               start_gpaddr, end_gpaddr,
                               &addr, &maddr, &flush,
                               mattr, t);
-        if ( ret < 0 ) { rc = ret ; goto out; }
+        if ( ret < 0 )
+        {
+            rc = ret ;
+            if ( op != INSERT ) goto out;
+            end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;
+            op = REMOVE;
+            goto unwind;
+        }
+        if ( op == INSERT ) inserted++;
         count += ret;
         if ( ret != P2M_ONE_DESCEND ) continue;
 
@@ -787,9 +804,17 @@ static int apply_p2m_changes(struct domain *d,
                               start_gpaddr, end_gpaddr,
                               &addr, &maddr, &flush,
                               mattr, t);
-        if ( ret < 0 ) { rc = ret ; goto out; }
+        if ( ret < 0 )
+        {
+            rc = ret ;
+            if ( op != INSERT ) goto out;
+            end_gpaddr = start_gpaddr + inserted * PAGE_SIZE;
+            op = REMOVE;
+            goto unwind;
+        }
         /* L3 had better have done something! We cannot descend any further */
         BUG_ON(ret == P2M_ONE_DESCEND);
+        if ( op == INSERT ) inserted++;
         count += ret;
     }
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 05/14] arch/x86: warn if to-be-removed mapping does not exist
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (3 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 06/14] arch/x86: cleanup memory_mapping DOMCTL Arianna Avanzini
                       ` (8 subsequent siblings)
  13 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, when a memory mapping is removed with the memory_mapping
DOMCTL, no check is performed on the existence of such a mapping.
This commit adds such a consistency check to the code performing the
unmap, emitting a warning message if the check fails.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v8:
        - Fix commit description and subject to better fit the contents of
          the patch.
        - Remove tentative phrases from commit description.

    v7:
        - Do not fail with an error when attempting to remove a non-existent
          mapping: just emit a warning.

---
 xen/arch/x86/domctl.c     |  4 ++--
 xen/arch/x86/mm/p2m.c     | 12 ++++++++----
 xen/common/memory.c       |  2 +-
 xen/include/asm-x86/p2m.h |  2 +-
 4 files changed, 12 insertions(+), 8 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index d62c715..db64ee0 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -679,7 +679,7 @@ long arch_do_domctl(
                            "memory_map:fail: dom%d gfn=%lx mfn=%lx ret:%ld\n",
                            d->domain_id, gfn + i, mfn + i, ret);
                     while ( i-- )
-                        clear_mmio_p2m_entry(d, gfn + i);
+                        clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
                     if ( iomem_deny_access(d, mfn, mfn + nr_mfns - 1) &&
                          is_hardware_domain(current->domain) )
                         printk(XENLOG_ERR
@@ -699,7 +699,7 @@ long arch_do_domctl(
             if ( paging_mode_translate(d) )
                 for ( i = 0; i < nr_mfns; i++ )
                 {
-                    ret = clear_mmio_p2m_entry(d, gfn + i);
+                    ret = clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
                     if ( ret )
                         tmp_rc = ret;
                 }
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index 642ec28..f5feb70 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -859,10 +859,10 @@ int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
 }
 
 /* Returns: 0 for success, -errno for failure */
-int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn)
+int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
 {
     int rc = -EINVAL;
-    mfn_t mfn;
+    mfn_t actual_mfn;
     p2m_access_t a;
     p2m_type_t t;
     struct p2m_domain *p2m = p2m_get_hostp2m(d);
@@ -871,15 +871,19 @@ int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn)
         return -EIO;
 
     gfn_lock(p2m, gfn, 0);
-    mfn = p2m->get_entry(p2m, gfn, &t, &a, 0, NULL);
+    actual_mfn = p2m->get_entry(p2m, gfn, &t, &a, 0, NULL);
 
     /* Do not use mfn_valid() here as it will usually fail for MMIO pages. */
-    if ( (INVALID_MFN == mfn_x(mfn)) || (t != p2m_mmio_direct) )
+    if ( (INVALID_MFN == mfn_x(actual_mfn)) || (t != p2m_mmio_direct) )
     {
         gdprintk(XENLOG_ERR,
                  "gfn_to_mfn failed! gfn=%08lx type:%d\n", gfn, t);
         goto out;
     }
+    if ( mfn_x(mfn) != mfn_x(actual_mfn) )
+        gdprintk(XENLOG_WARNING,
+                 "no mapping between mfn %08lx and gfn %08lx\n",
+                 mfn_x(mfn), gfn);
     rc = p2m_set_entry(p2m, gfn, _mfn(INVALID_MFN), PAGE_ORDER_4K, p2m_invalid,
                        p2m->default_access);
 
diff --git a/xen/common/memory.c b/xen/common/memory.c
index c2dd31b..2433111 100644
--- a/xen/common/memory.c
+++ b/xen/common/memory.c
@@ -206,7 +206,7 @@ int guest_remove_page(struct domain *d, unsigned long gmfn)
     }
     if ( p2mt == p2m_mmio_direct )
     {
-        clear_mmio_p2m_entry(d, gmfn);
+        clear_mmio_p2m_entry(d, gmfn, _mfn(mfn));
         put_gfn(d, gmfn);
         return 1;
     }
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 0ddbadb..5ab7cb4 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -534,7 +534,7 @@ int p2m_is_logdirty_range(struct p2m_domain *, unsigned long start,
 
 /* Set mmio addresses in the p2m table (for pass-through) */
 int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
-int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn);
+int clear_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
 
 /* Add foreign mapping to the guest's p2m table. */
 int p2m_add_foreign(struct domain *tdom, unsigned long fgfn,
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 06/14] arch/x86: cleanup memory_mapping DOMCTL
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (4 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 05/14] arch/x86: warn if to-be-removed mapping does not exist Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 07/14] xen/common: add ARM stub for the function memory_type_changed() Arianna Avanzini
                       ` (7 subsequent siblings)
  13 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit lets the end mfn be computed only once while handling a
XEN_DOMCTL_memory_mapping hypercall. Also, the name of the tmp_rc
local variable is changed to rc.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Jan Beulich <JBeulich@suse.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
---
 xen/arch/x86/domctl.c | 27 ++++++++++++++-------------
 1 file changed, 14 insertions(+), 13 deletions(-)

diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index db64ee0..f991bbb 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -646,19 +646,20 @@ long arch_do_domctl(
         unsigned long gfn = domctl->u.memory_mapping.first_gfn;
         unsigned long mfn = domctl->u.memory_mapping.first_mfn;
         unsigned long nr_mfns = domctl->u.memory_mapping.nr_mfns;
+        unsigned long mfn_end = mfn + nr_mfns - 1;
         int add = domctl->u.memory_mapping.add_mapping;
 
         ret = -EINVAL;
-        if ( (mfn + nr_mfns - 1) < mfn || /* wrap? */
-             ((mfn | (mfn + nr_mfns - 1)) >> (paddr_bits - PAGE_SHIFT)) ||
+        if ( mfn_end < mfn || /* wrap? */
+             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
              (gfn + nr_mfns - 1) < gfn ) /* wrap? */
             break;
 
         ret = -EPERM;
-        if ( !iomem_access_permitted(current->domain, mfn, mfn + nr_mfns - 1) )
+        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
             break;
 
-        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn + nr_mfns - 1, add);
+        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
         if ( ret )
             break;
 
@@ -668,7 +669,7 @@ long arch_do_domctl(
                    "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
                    d->domain_id, gfn, mfn, nr_mfns);
 
-            ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
+            ret = iomem_permit_access(d, mfn, mfn_end);
             if ( !ret && paging_mode_translate(d) )
             {
                 for ( i = 0; !ret && i < nr_mfns; i++ )
@@ -680,17 +681,17 @@ long arch_do_domctl(
                            d->domain_id, gfn + i, mfn + i, ret);
                     while ( i-- )
                         clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
-                    if ( iomem_deny_access(d, mfn, mfn + nr_mfns - 1) &&
+                    if ( iomem_deny_access(d, mfn, mfn_end) &&
                          is_hardware_domain(current->domain) )
                         printk(XENLOG_ERR
                                "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
-                               d->domain_id, mfn, mfn + nr_mfns - 1);
+                               d->domain_id, mfn, mfn_end);
                 }
             }
         }
         else
         {
-            int tmp_rc = 0;
+            int rc = 0;
 
             printk(XENLOG_G_INFO
                    "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
@@ -701,16 +702,16 @@ long arch_do_domctl(
                 {
                     ret = clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
                     if ( ret )
-                        tmp_rc = ret;
+                        rc = ret;
                 }
-            ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
+            ret = iomem_deny_access(d, mfn, mfn_end);
             if ( !ret )
-                ret = tmp_rc;
+                ret = rc;
             if ( ret && is_hardware_domain(current->domain) )
                 printk(XENLOG_ERR
                        "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
-                       ret, tmp_rc ? "removing" : "denying", d->domain_id,
-                       mfn, mfn + nr_mfns - 1);
+                       ret, rc ? "removing" : "denying", d->domain_id,
+                       mfn, mfn_end);
         }
         /* Do this unconditionally to cover errors on above failure paths. */
         memory_type_changed(d);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 07/14] xen/common: add ARM stub for the function memory_type_changed()
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (5 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 06/14] arch/x86: cleanup memory_mapping DOMCTL Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-17 12:59       ` Ian Campbell
  2014-07-24 14:07       ` Julien Grall
  2014-07-14  0:50     ` [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL Arianna Avanzini
                       ` (6 subsequent siblings)
  13 siblings, 2 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

MTRR-related code is not available for the ARM architecture. Given
that the memory_type_changed() function would be called also from
common code, its invocation is currently ifdef'd out to be only
compiled in on an x86 machine. This commit adds an empty stub for ARM.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Don't expose the memory_type_changed() function to common code,
          just add an empty stub in arch/arm/p2m.c and in the related header
          for ARM.

---
 xen/arch/arm/p2m.c        | 4 ++++
 xen/common/domctl.c       | 2 --
 xen/include/asm-arm/p2m.h | 2 ++
 3 files changed, 6 insertions(+), 2 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index e9f7c96..6add407 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -47,6 +47,10 @@ void p2m_dump_info(struct domain *d)
     spin_unlock(&p2m->lock);
 }
 
+void memory_type_changed(struct domain *d)
+{
+}
+
 void dump_p2m_lookup(struct domain *d, paddr_t addr)
 {
     struct p2m_domain *p2m = &d->arch.p2m;
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index c326aba..24102c0 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -897,10 +897,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
         else
             ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
-#ifdef CONFIG_X86
         if ( !ret )
             memory_type_changed(d);
-#endif
     }
     break;
 
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 06c93a0..13fea36 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -5,6 +5,8 @@
 
 struct domain;
 
+extern void memory_type_changed(struct domain *);
+
 /* Per-p2m-table state */
 struct p2m_domain {
     /* Lock that protects updates to the p2m */
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (6 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 07/14] xen/common: add ARM stub for the function memory_type_changed() Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-17 13:00       ` Ian Campbell
  2014-07-23 11:59       ` Jan Beulich
  2014-07-14  0:50     ` [PATCH RESEND v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code Arianna Avanzini
                       ` (5 subsequent siblings)
  13 siblings, 2 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit factors out from the XEN_DOMCTL_memory_mapping hypercall
implementation, currently available only for x86, the operations
related to memory ranges map and unmap. The code is factored out
into two {map|unmap}_mmio_regions() functions for x86, that will match
the corresponding pair of ARM functions when the DOMCTL will be moved
to common code in the following commit. This commit also adds an
unmap_mmio_regions() function for ARM so that the following transition
to common code is cleaner.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Don't ignore an error if it doesn't happen while unmapping the last
          I/O-memory mapping in unmap_mmio_regions() for x86.
        - Fix wrong argument in the call to unmap_mmio_regions() performed on
          failure by map_mmio_regions() for x86.
        - Explicitly specify nr_mfns in the commit message emitted when the
          function map_mmio_regions() fails in the DOMCTL handling code.
        - Change "nr_mfns" to "nr" in the arch-specific map/unmap functions
          for x86.

    v8:
        - Latch the ret variable in {map|unmap}_mmio_regions() to the
          first or last errors encountered during mapping or unmapping
          operations.
        - Separate cleanup-related changes from refactoring ones.
        - Use correct count in unmap_mmio_regions().

    v7:
        - Use unmap_mmio_regions() for the error recovery path in
          map_mmio_regions().
        - Fix wrong use of memory-handling functions.
        - Use mfn_t as last parameter to {map|unmap}_mmio_regions().
        - Don't split format strings.
        - Remove spurious changes, such as those to already-existing format
          strings that are not necessary.

    v6:
        - Fix uncorrect usage of [mg]fn_end which, in the initial checks,
          was subtracted 1 twice.
        - Pass p2m_invalid as last parameter to unmap_mmio_regions() for ARM
          as it is not (and currently must not be) used.
        - Remove useless comment about the handling of errors in the
          remove path of the hypercall.
        - Replace stray hard tab with spaces.

    v5:
        - Let the unmap_mmio_regions() function for x86 return a proper
          error code upon failure.
        - Restore correct handling of errors in the remove path of the
          hypercall, assigning to the "ret" local variable the error
          code returned by the unmap_mmio_regions() function only if
          iomem_deny_access() didn't return with an error.
        - Compute gfn_end - 1 and mfn_end - 1 only once in the DOMCTL.
        - Use a local variable to keep the return value of the function
          unmap_mmio_regions() instead of re-using the "add" variable.
        - Add a comment to make hopefully clearer how error values of
          functions are handled in the remove path of the DOMCTL.

    v4:
        - Fix type and signedness of local variables used as indexes in
          map_mmio_regions() and unmap_mmio_regions() for x86.
        - Clear p2m entries in map_mmio_regions() for x86 only if
          set_mmio_p2m_entry() returned with an error.
        - Make ranges inclusive of the end address in map_mmio_regions()
          and unmap_mmio_regions() for x86.
        - Turn hard tabs into spaces.

    v3:
        - Add map_mmio_regions() and unmap_mmio_regions() functions for x86;
        - Use pfn as parameters to the unmap_mmio_regions() function.
        - Compute gfn + nr_mfns and mfn + nr_mfns only once.

    v2:
        - Use the already-defined PADDR_BITS constant in the new DOMCTL.
        - Use paddr_t as arguments to the map_mmio_regions() function.
        - Page-align addresses given as arguments to map_mmio_regions() and
          unmap_mmio_regions().

---
 xen/arch/arm/p2m.c        | 12 ++++++++++++
 xen/arch/x86/domctl.c     | 19 +++++--------------
 xen/arch/x86/mm/p2m.c     | 43 +++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/p2m.h |  4 ++++
 xen/include/asm-x86/p2m.h | 12 ++++++++++++
 5 files changed, 76 insertions(+), 14 deletions(-)

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index 6add407..a85e58d 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -872,6 +872,18 @@ int map_mmio_regions(struct domain *d,
                              MATTR_DEV, p2m_mmio_direct);
 }
 
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr_mfns,
+                       unsigned long mfn)
+{
+    return apply_p2m_changes(d, REMOVE,
+                             pfn_to_paddr(start_gfn),
+                             pfn_to_paddr(start_gfn + nr_mfns),
+                             pfn_to_paddr(mfn),
+                             MATTR_DEV, p2m_invalid);
+}
+
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gpfn,
                             unsigned long mfn,
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index f991bbb..15af792 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -670,17 +670,14 @@ long arch_do_domctl(
                    d->domain_id, gfn, mfn, nr_mfns);
 
             ret = iomem_permit_access(d, mfn, mfn_end);
-            if ( !ret && paging_mode_translate(d) )
+            if ( !ret )
             {
-                for ( i = 0; !ret && i < nr_mfns; i++ )
-                    ret = set_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
+                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
                 if ( ret )
                 {
                     printk(XENLOG_G_WARNING
-                           "memory_map:fail: dom%d gfn=%lx mfn=%lx ret:%ld\n",
-                           d->domain_id, gfn + i, mfn + i, ret);
-                    while ( i-- )
-                        clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
+                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
+                           d->domain_id, gfn, mfn, nr_mfns, ret);
                     if ( iomem_deny_access(d, mfn, mfn_end) &&
                          is_hardware_domain(current->domain) )
                         printk(XENLOG_ERR
@@ -697,13 +694,7 @@ long arch_do_domctl(
                    "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
                    d->domain_id, gfn, mfn, nr_mfns);
 
-            if ( paging_mode_translate(d) )
-                for ( i = 0; i < nr_mfns; i++ )
-                {
-                    ret = clear_mmio_p2m_entry(d, gfn + i, _mfn(mfn + i));
-                    if ( ret )
-                        rc = ret;
-                }
+            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
             ret = iomem_deny_access(d, mfn, mfn_end);
             if ( !ret )
                 ret = rc;
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index f5feb70..29df616 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1704,6 +1704,49 @@ unsigned long paging_gva_to_gfn(struct vcpu *v,
     return hostmode->gva_to_gfn(v, hostp2m, va, pfec);
 }
 
+int map_mmio_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long nr,
+                     unsigned long mfn)
+{
+    int ret = 0;
+    unsigned long i;
+
+    if ( !paging_mode_translate(d) )
+        return 0;
+
+    for ( i = 0; !ret && i < nr; i++ )
+    {
+        ret = set_mmio_p2m_entry(d, start_gfn + i, _mfn(mfn + i));
+        if ( ret )
+        {
+            unmap_mmio_regions(d, start_gfn, i, mfn);
+            break;
+        }
+    }
+
+    return ret;
+}
+
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr,
+                       unsigned long mfn)
+{
+    int ret = 0, err = 0;
+    unsigned long i;
+
+    if ( !paging_mode_translate(d) )
+        return 0;
+
+    for ( i = 0; i < nr; i++ ) {
+        ret = clear_mmio_p2m_entry(d, start_gfn + i, _mfn(mfn + i));
+        if ( ret ) err = ret;
+    }
+
+    return err;
+}
+
 /*** Audit ***/
 
 #if P2M_AUDIT
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 13fea36..648144f 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -108,6 +108,10 @@ int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
                      unsigned long nr_mfns,
                      unsigned long mfn);
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr_mfns,
+                       unsigned long mfn);
 
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 5ab7cb4..cea46e1 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -32,6 +32,18 @@
 #include <asm/mem_sharing.h>
 #include <asm/page.h>    /* for pagetable_t */
 
+/* Map MMIO regions in the p2m: start_gfn and nr describe the range in
+ * the guest physical address space to map, starting from the machine
+ * frame number mfn. */
+int map_mmio_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long nr,
+                     unsigned long mfn);
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr,
+                       unsigned long mfn);
+
 extern bool_t opt_hap_1gb, opt_hap_2mb;
 
 /*
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (7 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-24 14:10       ` Julien Grall
  2014-07-14  0:50     ` [PATCH RESEND v9 10/14] tools/libxl: parse optional start gfn from the iomem config option Arianna Avanzini
                       ` (4 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit moves to common code the implementation of the memory_mapping
DOMCTL, currently available only for the x86 architecture. It also adds
a definition for the PADDR_BITS constant for ARM, that is to be used in
common code and currently not available for the ARM architecture.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Jan Beulich <JBeulich@suse.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Don't expose the type mfn_t to common code; let the x86-specific map/
          unmap functions perform the type cast and use unsigned long in common
          code.

    v7:
        - Change the name of tmp_rc to rc. Also, do not uselessly initialize it.
        - ifdef out the invocation of memory_type_changed() to be called only
          if the architecture is x86 instead of adding an useless empty stub
          for ARM.

    v6:
        - Add an empty definition of the memory_type_changed() function for ARM.

    v5:
        - Rename new header to p2m-common.h.

    v4:
        - Use a define for paddr_bits instead of a new variable.
        - Define prototypes for common functions map_mmio_regions() and
          unmap_mmio_regions() only once in a common header.

    v3:
        - Add a paddr_bits variable for ARM.

    v2:
        - Move code to xen/arm/domctl.c.

---
 xen/arch/arm/p2m.c           |  8 +++---
 xen/arch/x86/domctl.c        | 68 --------------------------------------------
 xen/common/domctl.c          | 68 ++++++++++++++++++++++++++++++++++++++++++++
 xen/include/asm-arm/p2m.h    | 15 +++-------
 xen/include/asm-x86/p2m.h    | 13 +--------
 xen/include/xen/p2m-common.h | 16 +++++++++++
 6 files changed, 93 insertions(+), 95 deletions(-)
 create mode 100644 xen/include/xen/p2m-common.h

diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
index a85e58d..57e36b2 100644
--- a/xen/arch/arm/p2m.c
+++ b/xen/arch/arm/p2m.c
@@ -862,24 +862,24 @@ int p2m_populate_ram(struct domain *d,
 
 int map_mmio_regions(struct domain *d,
                      unsigned long start_gfn,
-                     unsigned long nr_mfns,
+                     unsigned long nr,
                      unsigned long mfn)
 {
     return apply_p2m_changes(d, INSERT,
                              pfn_to_paddr(start_gfn),
-                             pfn_to_paddr(start_gfn + nr_mfns),
+                             pfn_to_paddr(start_gfn + nr),
                              pfn_to_paddr(mfn),
                              MATTR_DEV, p2m_mmio_direct);
 }
 
 int unmap_mmio_regions(struct domain *d,
                        unsigned long start_gfn,
-                       unsigned long nr_mfns,
+                       unsigned long nr,
                        unsigned long mfn)
 {
     return apply_p2m_changes(d, REMOVE,
                              pfn_to_paddr(start_gfn),
-                             pfn_to_paddr(start_gfn + nr_mfns),
+                             pfn_to_paddr(start_gfn + nr),
                              pfn_to_paddr(mfn),
                              MATTR_DEV, p2m_invalid);
 }
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 15af792..c211818 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -641,74 +641,6 @@ long arch_do_domctl(
     }
     break;
 
-    case XEN_DOMCTL_memory_mapping:
-    {
-        unsigned long gfn = domctl->u.memory_mapping.first_gfn;
-        unsigned long mfn = domctl->u.memory_mapping.first_mfn;
-        unsigned long nr_mfns = domctl->u.memory_mapping.nr_mfns;
-        unsigned long mfn_end = mfn + nr_mfns - 1;
-        int add = domctl->u.memory_mapping.add_mapping;
-
-        ret = -EINVAL;
-        if ( mfn_end < mfn || /* wrap? */
-             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
-             (gfn + nr_mfns - 1) < gfn ) /* wrap? */
-            break;
-
-        ret = -EPERM;
-        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
-            break;
-
-        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
-        if ( ret )
-            break;
-
-        if ( add )
-        {
-            printk(XENLOG_G_INFO
-                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
-                   d->domain_id, gfn, mfn, nr_mfns);
-
-            ret = iomem_permit_access(d, mfn, mfn_end);
-            if ( !ret )
-            {
-                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
-                if ( ret )
-                {
-                    printk(XENLOG_G_WARNING
-                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
-                           d->domain_id, gfn, mfn, nr_mfns, ret);
-                    if ( iomem_deny_access(d, mfn, mfn_end) &&
-                         is_hardware_domain(current->domain) )
-                        printk(XENLOG_ERR
-                               "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
-                               d->domain_id, mfn, mfn_end);
-                }
-            }
-        }
-        else
-        {
-            int rc = 0;
-
-            printk(XENLOG_G_INFO
-                   "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
-                   d->domain_id, gfn, mfn, nr_mfns);
-
-            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
-            ret = iomem_deny_access(d, mfn, mfn_end);
-            if ( !ret )
-                ret = rc;
-            if ( ret && is_hardware_domain(current->domain) )
-                printk(XENLOG_ERR
-                       "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
-                       ret, rc ? "removing" : "denying", d->domain_id,
-                       mfn, mfn_end);
-        }
-        /* Do this unconditionally to cover errors on above failure paths. */
-        memory_type_changed(d);
-    }
-    break;
-
     case XEN_DOMCTL_ioport_mapping:
     {
         struct hvm_iommu *hd;
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 24102c0..80b7800 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -902,6 +902,74 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
     }
     break;
 
+    case XEN_DOMCTL_memory_mapping:
+    {
+        unsigned long gfn = op->u.memory_mapping.first_gfn;
+        unsigned long mfn = op->u.memory_mapping.first_mfn;
+        unsigned long nr_mfns = op->u.memory_mapping.nr_mfns;
+        unsigned long mfn_end = mfn + nr_mfns - 1;
+        int add = op->u.memory_mapping.add_mapping;
+
+        ret = -EINVAL;
+        if ( mfn_end < mfn || /* wrap? */
+             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
+             (gfn + nr_mfns - 1) < gfn ) /* wrap? */
+            break;
+
+        ret = -EPERM;
+        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
+            break;
+
+        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
+        if ( ret )
+            break;
+
+        if ( add )
+        {
+            printk(XENLOG_G_INFO
+                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
+                   d->domain_id, gfn, mfn, nr_mfns);
+
+            ret = iomem_permit_access(d, mfn, mfn_end);
+            if ( !ret )
+            {
+                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
+                if ( ret )
+                {
+                    printk(XENLOG_G_WARNING
+                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
+                           d->domain_id, gfn, mfn, nr_mfns, ret);
+                    if ( iomem_deny_access(d, mfn, mfn_end) &&
+                         is_hardware_domain(current->domain) )
+                        printk(XENLOG_ERR
+                               "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
+                               d->domain_id, mfn, mfn_end);
+                }
+            }
+        }
+        else
+        {
+            int rc = 0;
+
+            printk(XENLOG_G_INFO
+                   "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
+                   d->domain_id, gfn, mfn, nr_mfns);
+
+            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
+            ret = iomem_deny_access(d, mfn, mfn_end);
+            if ( !ret )
+                ret = rc;
+            if ( ret && is_hardware_domain(current->domain) )
+                printk(XENLOG_ERR
+                       "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
+                       ret, rc ? "removing" : "denying", d->domain_id,
+                       mfn, mfn_end);
+        }
+        /* Do this unconditionally to cover errors on above failure paths. */
+        memory_type_changed(d);
+    }
+    break;
+
     case XEN_DOMCTL_settimeoffset:
     {
         domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
index 648144f..08ce07b 100644
--- a/xen/include/asm-arm/p2m.h
+++ b/xen/include/asm-arm/p2m.h
@@ -3,6 +3,10 @@
 
 #include <xen/mm.h>
 
+#include <xen/p2m-common.h>
+
+#define paddr_bits PADDR_BITS
+
 struct domain;
 
 extern void memory_type_changed(struct domain *);
@@ -101,17 +105,6 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
 
 /* Setup p2m RAM mapping for domain d from start-end. */
 int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
-/* Map MMIO regions in the p2m: start_gfn and nr_mfns describe the range
- * in the guest physical address space to map, starting from the machine
- * frame number mfn. */
-int map_mmio_regions(struct domain *d,
-                     unsigned long start_gfn,
-                     unsigned long nr_mfns,
-                     unsigned long mfn);
-int unmap_mmio_regions(struct domain *d,
-                       unsigned long start_gfn,
-                       unsigned long nr_mfns,
-                       unsigned long mfn);
 
 int guest_physmap_add_entry(struct domain *d,
                             unsigned long gfn,
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index cea46e1..2a65848 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -29,21 +29,10 @@
 
 #include <xen/config.h>
 #include <xen/paging.h>
+#include <xen/p2m-common.h>
 #include <asm/mem_sharing.h>
 #include <asm/page.h>    /* for pagetable_t */
 
-/* Map MMIO regions in the p2m: start_gfn and nr describe the range in
- * the guest physical address space to map, starting from the machine
- * frame number mfn. */
-int map_mmio_regions(struct domain *d,
-                     unsigned long start_gfn,
-                     unsigned long nr,
-                     unsigned long mfn);
-int unmap_mmio_regions(struct domain *d,
-                       unsigned long start_gfn,
-                       unsigned long nr,
-                       unsigned long mfn);
-
 extern bool_t opt_hap_1gb, opt_hap_2mb;
 
 /*
diff --git a/xen/include/xen/p2m-common.h b/xen/include/xen/p2m-common.h
new file mode 100644
index 0000000..9f1b771
--- /dev/null
+++ b/xen/include/xen/p2m-common.h
@@ -0,0 +1,16 @@
+#ifndef _XEN_P2M_COMMON_H
+#define _XEN_P2M_COMMON_H
+
+/* Map MMIO regions in the p2m: start_gfn and nr describe the range in
+ *  * the guest physical address space to map, starting from the machine
+ *   * frame number mfn. */
+int map_mmio_regions(struct domain *d,
+                     unsigned long start_gfn,
+                     unsigned long nr,
+                     unsigned long mfn);
+int unmap_mmio_regions(struct domain *d,
+                       unsigned long start_gfn,
+                       unsigned long nr,
+                       unsigned long mfn);
+
+#endif /* _XEN_P2M_COMMON_H */
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 10/14] tools/libxl: parse optional start gfn from the iomem config option
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (8 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall Arianna Avanzini
                       ` (3 subsequent siblings)
  13 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the "iomem" domU config option allows to specify a machine
address range to be mapped to the domU. However, there is no way to
specify the guest address range used for the mapping. This commit
extends the iomem option handling code to parse an additional, optional
parameter: this parameter, if given, specifies the start guest address
used for the mapping; if no start guest address is given, a 1:1 mapping
is performed as default.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>
Acked-by: Julien Grall <julien.grall@citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v7:
        - Use LIBXL_INVALID_GFN when needed.
        - Add to the manpage a note about the mapping defaulting to 1:1 when
          the gfn parameter is not specified, and about the option being for
          auto-translated guests.
        - Remove spurious change.

    v6:
        - Document what happens if the new "gfn" parameter is omitted
          while specifying the "iomem" option in the domain configuration.
        - Add LIBXL_INVALID_GFN macro with value "~(uint64_t)0".
        - Fix typo in the comment to the LIBXL_HAVE_BUILDINFO_IOMEM_START_GFN
          macro.

    v5:
        - Initialize the gfn field of the iomem structure with the
          value "(uint64_t)-1".
        - Defer the assignment of the value of "start" to "gfn", if
          "gfn" has been initialized to the default value, in libxl.
        - Use a local variable to keep the return value of sscanf()
          for better code readability.

    v4:
        - Add definition of a LIBXL_HAVE_BUILDINFO_IOMEM_START_GFN macro
          to indicate the availability of the new option.
        - Simplify the code parsing the new optional parameter by using
          the switch construct on the return value of the sscanf() function
          instead of calling the function twice.
        - Add a short paragraph to the manpage about the use of the iomem
          option to passthrough devices protected by an IOMMU.
        - Add comments to the fields of the "iomem" structure.

---
 docs/man/xl.cfg.pod.5        | 18 +++++++++++++-----
 tools/libxl/libxl.h          | 10 ++++++++++
 tools/libxl/libxl_create.c   |  6 ++++++
 tools/libxl/libxl_internal.h |  1 +
 tools/libxl/libxl_types.idl  |  4 ++++
 tools/libxl/xl_cmdimpl.c     | 17 ++++++++++-------
 6 files changed, 44 insertions(+), 12 deletions(-)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index ff9ea77..5bad491 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -610,12 +610,20 @@ is given in hexadecimal and may either a span e.g. C<2f8-2ff>
 It is recommended to use this option only for trusted VMs under
 administrator control.
 
-=item B<iomem=[ "IOMEM_START,NUM_PAGES", "IOMEM_START,NUM_PAGES", ... ]>
+=item B<iomem=[ "IOMEM_START,NUM_PAGES[@GFN]", "IOMEM_START,NUM_PAGES[@GFN]", ... ]>
 
-Allow guest to access specific hardware I/O memory pages. B<IOMEM_START>
-is a physical page number. B<NUM_PAGES> is the number
-of pages beginning with B<START_PAGE> to allow access. Both values
-must be given in hexadecimal.
+Allow auto-translated domains to access specific hardware I/O memory pages.
+
+B<IOMEM_START> is a physical page number. B<NUM_PAGES> is the number of pages
+beginning with B<START_PAGE> to allow access. B<GFN> specifies the guest frame
+number where the mapping will start in the domU's address space. If B<GFN> is
+not given, the mapping will be performed using B<IOMEM_START> as a start in the
+domU's address space, therefore performing an 1:1 mapping as default.
+All of these values must be given in hexadecimal.
+
+Note that the IOMMU won't be updated with the mappings specified with this
+option. This option therefore should not be used to passthrough any
+IOMMU-protected device.
 
 It is recommended to use this option only for trusted VMs under
 administrator control.
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index 5ae6532..b1a20da 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -128,6 +128,16 @@
 #define LIBXL_HAVE_LIBXL_DEVICE_DISK_DISCARD_ENABLE 1
 
 /*
+ * LIBXL_HAVE_BUILDINFO_IOMEM_START_GFN indicates that it is possible
+ * to specify the start guest frame number used to map a range of I/O
+ * memory machine frame numbers via the 'gfn' field (of type uint64)
+ * of the 'iomem' structure. An array of iomem structures is embedded
+ * in libxl_domain_build_info and used to map the indicated memory
+ * ranges during domain build.
+ */
+#define LIBXL_HAVE_BUILDINFO_IOMEM_START_GFN 1
+
+/*
  * libxl ABI compatibility
  *
  * The only guarantee which libxl makes regarding ABI compatibility
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 0686f96..3bfe65b 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -102,6 +102,8 @@ static int sched_params_valid(libxl__gc *gc,
 int libxl__domain_build_info_setdefault(libxl__gc *gc,
                                         libxl_domain_build_info *b_info)
 {
+    int i;
+
     if (b_info->type != LIBXL_DOMAIN_TYPE_HVM &&
         b_info->type != LIBXL_DOMAIN_TYPE_PV)
         return ERROR_INVAL;
@@ -200,6 +202,10 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
 
     libxl_defbool_setdefault(&b_info->disable_migrate, false);
 
+    for (i = 0 ; i < b_info->num_iomem; i++)
+        if (b_info->iomem[i].gfn == LIBXL_INVALID_GFN)
+            b_info->iomem[i].gfn = b_info->iomem[i].start;
+
     if (!b_info->event_channels)
         b_info->event_channels = 1023;
 
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index beb052e..04c9378 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -91,6 +91,7 @@
 #define LIBXL_PV_EXTRA_MEMORY 1024
 #define LIBXL_HVM_EXTRA_MEMORY 2048
 #define LIBXL_MIN_DOM0_MEM (128*1024)
+#define LIBXL_INVALID_GFN (~(uint64_t)0)
 /* use 0 as the domid of the toolstack domain for now */
 #define LIBXL_TOOLSTACK_DOMID 0
 #define QEMU_SIGNATURE "DeviceModelRecord0002"
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index a412f9c..75b5dd0 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -185,8 +185,12 @@ libxl_ioport_range = Struct("ioport_range", [
     ])
 
 libxl_iomem_range = Struct("iomem_range", [
+    # start host frame number to be mapped to the guest
     ("start", uint64),
+    # number of frames to be mapped
     ("number", uint64),
+    # guest frame number used as a start for the mapping
+    ("gfn", uint64, {'init_val': "LIBXL_INVALID_GFN"}),
     ])
 
 libxl_vga_interface_info = Struct("vga_interface_info", [
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index 68df548..b3b7df1 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1140,6 +1140,7 @@ static void parse_config_data(const char *config_source,
     }
 
     if (!xlu_cfg_get_list(config, "iomem", &iomem, &num_iomem, 0)) {
+        int ret;
         b_info->num_iomem = num_iomem;
         b_info->iomem = calloc(num_iomem, sizeof(*b_info->iomem));
         if (b_info->iomem == NULL) {
@@ -1153,13 +1154,15 @@ static void parse_config_data(const char *config_source,
                         "xl: Unable to get element %d in iomem list\n", i);
                 exit(1);
             }
-            if(sscanf(buf, "%" SCNx64",%" SCNx64,
-                     &b_info->iomem[i].start,
-                     &b_info->iomem[i].number)
-                  != 2) {
-               fprintf(stderr,
-                       "xl: Invalid argument parsing iomem: %s\n", buf);
-               exit(1);
+            libxl_iomem_range_init(&b_info->iomem[i]);
+            ret = sscanf(buf, "%" SCNx64",%" SCNx64"@%" SCNx64,
+                         &b_info->iomem[i].start,
+                         &b_info->iomem[i].number,
+                         &b_info->iomem[i].gfn);
+            if (ret < 2) {
+                fprintf(stderr,
+                        "xl: Invalid argument parsing iomem: %s\n", buf);
+                exit(1);
             }
         }
     }
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (9 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 10/14] tools/libxl: parse optional start gfn from the iomem config option Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-24 14:12       ` Julien Grall
  2014-07-14  0:50     ` [PATCH RESEND v9 12/14] tools/libxl: read from config if passing through primary GPU Arianna Avanzini
                       ` (2 subsequent siblings)
  13 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the configuration-parsing code concerning the handling of the
iomem parameter only invokes the XEN_DOMCTL_iomem_permission hypercall.
This commit lets the XEN_DOMCTL_memory_mapping hypercall be invoked
after XEN_DOMCTL_iomem_permission when the iomem parameter is parsed
from a domU configuration file, so that the address range can be mapped
to the address space of the domU. The hypercall is invoked only in case
of domains using an auto-translated physmap.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Enforce checks on return value of xc_domain_getinfo() as it could
          return information concerning the wrong domain.
        - Don't use PERROR for xc_core_* functions.
        - Avoid emitting an error message if xc_core_auto_translated_physmap()
          fails.

    v8:
        - Fix wrong error message emitted when the memory_mapping DOMCTL is
          called by a domain that is not auto-translated.

    v7:
        - Move the check for an auto-translated physmap to xc to avoid having
          to expose the information to libxl.

    v4:
        - Let the hypercall be called only in case the guest uses an
          auto-translated physmap.

    v3:
        - Add ifdefs to let the hypercall be called only by ARM or x86
          HVM guests, with a whitelist approach.
        - Remove the NOTE comment.

    v2:
        - Add a comment explaining outstanding issues.

---
 tools/libxc/xc_domain.c    | 10 ++++++++++
 tools/libxl/libxl_create.c | 11 +++++++++++
 2 files changed, 21 insertions(+)

diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 0230c6c..27fe3b6 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -1959,6 +1959,16 @@ int xc_domain_memory_mapping(
     uint32_t add_mapping)
 {
     DECLARE_DOMCTL;
+    xc_dominfo_t info;
+
+    if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 ||
+         info.domid != domid )
+    {
+        PERROR("Could not get info for domain");
+        return -EINVAL;
+    }
+    if ( !xc_core_arch_auto_translated_physmap(&info) )
+        return 0;
 
     domctl.cmd = XEN_DOMCTL_memory_mapping;
     domctl.domain = domid;
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 3bfe65b..1217310 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1158,6 +1158,17 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
                  "failed give dom%d access to iomem range %"PRIx64"-%"PRIx64,
                  domid, io->start, io->start + io->number - 1);
             ret = ERROR_FAIL;
+            continue;
+        }
+        ret = xc_domain_memory_mapping(CTX->xch, domid,
+                                       io->gfn, io->start,
+                                       io->number, 1);
+        if (ret < 0) {
+            LOGE(ERROR,
+                 "failed to map to dom%d iomem range %"PRIx64"-%"PRIx64
+                 " to guest address %"PRIx64,
+                 domid, io->start, io->start + io->number - 1, io->gfn);
+            ret = ERROR_FAIL;
         }
     }
 
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 12/14] tools/libxl: read from config if passing through primary GPU
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (10 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 13/14] tools/libxl: explicitly grant access to needed I/O-memory ranges Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 14/14] xen/common: do not implicitly permit access to mapped I/O memory Arianna Avanzini
  13 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit adds a new option available for any domU libxl
configuration that allows the user to specify if one of the
VGA adapters passed through to the domain is the primary one.
This way, libxl can arrange the correct I/O-memory access
permission for its stubdomain.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
---
 docs/man/xl.cfg.pod.5       | 7 +++++++
 tools/libxl/libxl.h         | 7 +++++++
 tools/libxl/libxl_create.c  | 1 +
 tools/libxl/libxl_types.idl | 3 ++-
 tools/libxl/xl_cmdimpl.c    | 2 ++
 5 files changed, 19 insertions(+), 1 deletion(-)

diff --git a/docs/man/xl.cfg.pod.5 b/docs/man/xl.cfg.pod.5
index 5bad491..37790ad 100644
--- a/docs/man/xl.cfg.pod.5
+++ b/docs/man/xl.cfg.pod.5
@@ -601,6 +601,13 @@ More information about Xen gfx_passthru feature is available
 on the XenVGAPassthrough L<http://wiki.xen.org/wiki/XenVGAPassthrough>
 wiki page.
 
+=item B<gfx_passthru_primary=BOOLEAN>
+
+If set to true, indicates that one of the GPUs passed through to the
+domain is the primary one; therefore allows to the domain's stubdoman
+access permissions for the VGA framebuffer. Note that this option
+defaults to true.
+
 =item B<ioports=[ "IOPORT_RANGE", "IOPORT_RANGE", ... ]>
 
 Allow guest to access specific legacy I/O ports. Each B<IOPORT_RANGE>
diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h
index b1a20da..2341ac0 100644
--- a/tools/libxl/libxl.h
+++ b/tools/libxl/libxl.h
@@ -84,6 +84,13 @@
 #define LIBXL_HAVE_FIRMWARE_PASSTHROUGH 1
 
 /*
+ * LIBXL_HAVE_GFX_PASSTHROUGH_PRIMARY indicates that the user must
+ * specify in the domain configuration whether one of the passthru
+ * VGA devices is the primary one.
+ */
+#define LIBXL_HAVE_GFX_PASSTHROUGH_PRIMARY 1
+
+/*
  * LIBXL_HAVE_DOMAIN_NODEAFFINITY indicates that a 'nodemap' field
  * (of libxl_bitmap type) is present in libxl_domain_build_info,
  * containing the node-affinity for the domain.
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 1217310..53cad9b 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -337,6 +337,7 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
         libxl_defbool_setdefault(&b_info->u.hvm.nographic, false);
 
         libxl_defbool_setdefault(&b_info->u.hvm.gfx_passthru, false);
+        libxl_defbool_setdefault(&b_info->u.hvm.gfx_passthru_primary, true);
 
         break;
     case LIBXL_DOMAIN_TYPE_PV:
diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl
index 75b5dd0..db9ea76 100644
--- a/tools/libxl/libxl_types.idl
+++ b/tools/libxl/libxl_types.idl
@@ -383,7 +383,8 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ("sdl",              libxl_sdl_info),
                                        ("spice",            libxl_spice_info),
                                        
-                                       ("gfx_passthru",     libxl_defbool),
+                                       ("gfx_passthru",             libxl_defbool),
+                                       ("gfx_passthru_primary",     libxl_defbool),
                                        
                                        ("serial",           string),
                                        ("boot",             string),
diff --git a/tools/libxl/xl_cmdimpl.c b/tools/libxl/xl_cmdimpl.c
index b3b7df1..6773f4a 100644
--- a/tools/libxl/xl_cmdimpl.c
+++ b/tools/libxl/xl_cmdimpl.c
@@ -1646,6 +1646,8 @@ skip_vfb:
         xlu_cfg_get_defbool(config, "nographic", &b_info->u.hvm.nographic, 0);
         xlu_cfg_get_defbool(config, "gfx_passthru", 
                             &b_info->u.hvm.gfx_passthru, 0);
+        xlu_cfg_get_defbool(config, "gfx_passthru_primary",
+                            &b_info->u.hvm.gfx_passthru_primary, 0);
         xlu_cfg_replace_string (config, "serial", &b_info->u.hvm.serial, 0);
         xlu_cfg_replace_string (config, "boot", &b_info->u.hvm.boot, 0);
         xlu_cfg_get_defbool(config, "usb", &b_info->u.hvm.usb, 0);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 13/14] tools/libxl: explicitly grant access to needed I/O-memory ranges
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (11 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 12/14] tools/libxl: read from config if passing through primary GPU Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  2014-07-14  0:50     ` [PATCH RESEND v9 14/14] xen/common: do not implicitly permit access to mapped I/O memory Arianna Avanzini
  13 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

This commit changes the existing libxl code to be sure to grant access
permission to PCI-related I/O memory ranges, while setting up passthrough
of PCI devices specified in the domain's configuration, and to VGA-related
memory ranges, while setting up VGA passthrough (if gfx_passthru = 1 and
gfx_passthru_primary = 1 in the domain's configuration).
As for the latter, the newly-added code does not replace any existing one,
but instead matches the calls to xc_domain_memory_mapping() performed by
QEMU on the path that is executed if gfx passthru is enabled and follows
the registration of a new VGA controller (in register_vga_regions(),
defined in hw/pt-graphics.c). In fact, VGA needs some extra memory
ranges to be mapped with respect to PCI; QEMU expects that access to those
memory ranges is implicitly granted when he calls the hypervisor with the
function xc_domain_memory_mapping(): this commit calls iomem_permission
for it when needed for a primary GPU.

This commit is instrumental to the following one, which will separate
the functions of the iomem_permission and memory_mapping DOMCTLs, so
that requesting an I/O-memory range will not imply that access to such a
range is implicitly granted.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v9:
        - Allow a domain access to the VGA framebuffer only if the user has
          signaled that one of the passthru GPUs is primary via domain config.

    v8:
        - Explain better in the commit description VGA-related code additions.
        - Fix v6 changelog which, being too generic, ended up to uncorrectly
          state that one of the requests had been addressed.
        - Remove tentative phrases from commit description.

    v7:
        - Let libxl not handle I/O ports and I/O memory differently when access
          to a PCI device is allowed to a domain.
        - Change the construct used by libxl during PCI-related initialization
          from a switch to an if to better suit the new execution flow.

---
 tools/libxl/libxl_create.c | 33 +++++++++++++++++++++++++++++++++
 tools/libxl/libxl_pci.c    | 26 ++++++++++----------------
 2 files changed, 43 insertions(+), 16 deletions(-)

diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 53cad9b..74d9063 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -1195,6 +1195,39 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
             libxl__spawn_stub_dm(egc, &dcs->dmss);
         else
             libxl__spawn_local_dm(egc, &dcs->dmss.dm);
+
+        /*
+         * If VGA passthru is enabled by domain config and one of the
+         * passthru GPUs has been indicated by the user to be the
+         * primary, be sure that the related stubdomain and the domain
+         * itself can access the VGA framebuffer.
+         */
+        if (d_config->b_info.u.hvm.gfx_passthru.val &&
+            d_config->b_info.u.hvm.gfx_passthru_primary.val) {
+            uint64_t vga_iomem_start = 0xa0000 >> XC_PAGE_SHIFT;
+            int stubdom_domid = libxl_get_stubdom_id(CTX, domid);
+
+            ret = xc_domain_iomem_permission(CTX->xch, stubdom_domid,
+                                             vga_iomem_start, 0x20, 1);
+            if (ret < 0) {
+                LOGE(ERROR,
+                     "failed to give stubdom%d access to iomem range "
+                     "%"PRIx64"-%"PRIx64" for VGA passthru",
+                     stubdom_domid,
+                     vga_iomem_start, (vga_iomem_start + 0x20 - 1));
+                goto error_out;
+            }
+            ret = xc_domain_iomem_permission(CTX->xch, domid,
+                                             vga_iomem_start, 0x20, 1);
+            if (ret < 0) {
+                LOGE(ERROR,
+                     "failed to give dom%d access to iomem range "
+                     "%"PRIx64"-%"PRIx64" for VGA passthru",
+                     domid, vga_iomem_start, (vga_iomem_start + 0x20 - 1));
+                goto error_out;
+            }
+        }
+
         return;
     }
     case LIBXL_DOMAIN_TYPE_PV:
diff --git a/tools/libxl/libxl_pci.c b/tools/libxl/libxl_pci.c
index 2782d0e..3c061ca 100644
--- a/tools/libxl/libxl_pci.c
+++ b/tools/libxl/libxl_pci.c
@@ -846,10 +846,13 @@ static int qemu_pci_add_xenstore(libxl__gc *gc, uint32_t domid,
 static int do_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, int starting)
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
+    libxl_domain_type type = libxl__domain_type(gc, domid);
     int rc, hvm = 0;
 
-    switch (libxl__domain_type(gc, domid)) {
-    case LIBXL_DOMAIN_TYPE_HVM:
+    if (type == LIBXL_DOMAIN_TYPE_INVALID)
+        return ERROR_FAIL;
+
+    if (type == LIBXL_DOMAIN_TYPE_HVM) {
         hvm = 1;
         if (libxl__wait_for_device_model_deprecated(gc, domid, "running",
                                          NULL, NULL, NULL) < 0) {
@@ -867,8 +870,7 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, i
         }
         if ( rc )
             return ERROR_FAIL;
-        break;
-    case LIBXL_DOMAIN_TYPE_PV:
+    }
     {
         char *sysfs_path = libxl__sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
                                          pcidev->bus, pcidev->dev, pcidev->func);
@@ -937,10 +939,6 @@ static int do_pci_add(libxl__gc *gc, uint32_t domid, libxl_device_pci *pcidev, i
                 return ERROR_FAIL;
             }
         }
-        break;
-    }
-    case LIBXL_DOMAIN_TYPE_INVALID:
-        return ERROR_FAIL;
     }
 out:
     if (!libxl_is_stubdom(ctx, domid, NULL)) {
@@ -1166,6 +1164,7 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
 {
     libxl_ctx *ctx = libxl__gc_owner(gc);
     libxl_device_pci *assigned;
+    libxl_domain_type type = libxl__domain_type(gc, domid);
     int hvm = 0, rc, num;
     int stubdomid = 0;
 
@@ -1181,8 +1180,7 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
     }
 
     rc = ERROR_FAIL;
-    switch (libxl__domain_type(gc, domid)) {
-    case LIBXL_DOMAIN_TYPE_HVM:
+    if (type == LIBXL_DOMAIN_TYPE_HVM) {
         hvm = 1;
         if (libxl__wait_for_device_model_deprecated(gc, domid, "running",
                                          NULL, NULL, NULL) < 0)
@@ -1203,8 +1201,8 @@ static int do_pci_remove(libxl__gc *gc, uint32_t domid,
             rc = ERROR_FAIL;
             goto out_fail;
         }
-        break;
-    case LIBXL_DOMAIN_TYPE_PV:
+    } else if (type != LIBXL_DOMAIN_TYPE_PV)
+        abort();
     {
         char *sysfs_path = libxl__sprintf(gc, SYSFS_PCI_DEV"/"PCI_BDF"/resource", pcidev->domain,
                                          pcidev->bus, pcidev->dev, pcidev->func);
@@ -1254,10 +1252,6 @@ skip1:
             }
         }
         fclose(f);
-        break;
-    }
-    default:
-        abort();
     }
 out:
     /* don't do multiple resets while some functions are still passed through */
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* [PATCH RESEND v9 14/14] xen/common: do not implicitly permit access to mapped I/O memory
  2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
                       ` (12 preceding siblings ...)
  2014-07-14  0:50     ` [PATCH RESEND v9 13/14] tools/libxl: explicitly grant access to needed I/O-memory ranges Arianna Avanzini
@ 2014-07-14  0:50     ` Arianna Avanzini
  13 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  0:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	Ian.Jackson, dario.faggioli, tim, julien.grall, etrudeau,
	andrew.cooper3, JBeulich, avanzini.arianna, viktor.kleinik

Currently, the XEN_DOMCTL_memory_mapping hypercall implicitly grants
to a domain access permission to the I/O memory areas mapped in its
guest address space. This conflicts with the presence of a specific
hypercall (XEN_DOMCTL_iomem_permission) used to grant such a permission
to a domain.
This commit separates the functions of the two hypercalls by having only
the latter be able to permit I/O memory access to a domain, and the
former just performing the mapping after a permissions check on both the
granting and the grantee domains.

Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Cc: Dario Faggioli <dario.faggioli@citrix.com>
Cc: Paolo Valente <paolo.valente@unimore.it>
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
Cc: Julien Grall <julien.grall@citrix.com>
Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
Cc: Jan Beulich <JBeulich@suse.com>
Cc: Keir Fraser <keir@xen.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Eric Trudeau <etrudeau@broadcom.com>
Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>

---

    v8:
        - Drop iomem_permission-related changes.
        - Conservatively check both the granting and the grantee domains'
          permissions in the memory_mapping DOMCTL.
        - Remove tentative phrases from commit description.

    v7:
        - Let iomem_permission check if the calling domain is allowed to access
          memory ranges to be mapped to a domain. Remove such a check from the
          memory_mapping hypercall.

---
 xen/common/domctl.c | 36 ++++++++++--------------------------
 1 file changed, 10 insertions(+), 26 deletions(-)

diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 80b7800..04ecd53 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -917,7 +917,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
             break;
 
         ret = -EPERM;
-        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
+        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) ||
+             !iomem_access_permitted(d, mfn, mfn_end) )
             break;
 
         ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
@@ -930,40 +931,23 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
                    "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
                    d->domain_id, gfn, mfn, nr_mfns);
 
-            ret = iomem_permit_access(d, mfn, mfn_end);
-            if ( !ret )
-            {
-                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
-                if ( ret )
-                {
-                    printk(XENLOG_G_WARNING
-                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
-                           d->domain_id, gfn, mfn, nr_mfns, ret);
-                    if ( iomem_deny_access(d, mfn, mfn_end) &&
-                         is_hardware_domain(current->domain) )
-                        printk(XENLOG_ERR
-                               "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
-                               d->domain_id, mfn, mfn_end);
-                }
-            }
+            ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
+            if ( ret )
+                printk(XENLOG_G_WARNING
+                       "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
+                       d->domain_id, gfn, mfn, nr_mfns, ret);
         }
         else
         {
-            int rc = 0;
-
             printk(XENLOG_G_INFO
                    "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
                    d->domain_id, gfn, mfn, nr_mfns);
 
-            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
-            ret = iomem_deny_access(d, mfn, mfn_end);
-            if ( !ret )
-                ret = rc;
+            ret = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
             if ( ret && is_hardware_domain(current->domain) )
                 printk(XENLOG_ERR
-                       "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
-                       ret, rc ? "removing" : "denying", d->domain_id,
-                       mfn, mfn_end);
+                       "memory_map: error %ld removing dom%d access to [%lx,%lx]\n",
+                       ret, d->domain_id, mfn, mfn_end);
         }
         /* Do this unconditionally to cover errors on above failure paths. */
         memory_type_changed(d);
-- 
1.9.3

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM
  2014-07-11 17:00     ` Arianna Avanzini
@ 2014-07-14  8:54       ` Ian Campbell
  2014-07-14  9:22         ` Arianna Avanzini
  0 siblings, 1 reply; 69+ messages in thread
From: Ian Campbell @ 2014-07-14  8:54 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: paolo.valente, keir, stefano.stabellini, tim, dario.faggioli,
	Julien Grall, Ian.Jackson, xen-devel, julien.grall, etrudeau,
	JBeulich, andrew.cooper3, viktor.kleinik

On Fri, 2014-07-11 at 19:00 +0200, Arianna Avanzini wrote:
> On 07/11/2014 04:24 PM, Ian Campbell wrote:
> > On Fri, 2014-07-11 at 14:51 +0100, Julien Grall wrote:
> >> Hi Arianna,
> >>
> >> Lots of patches has been pushed upstream since last week (GICv2 and P2M,
> >> reworking).
> > 
> > Sorry Arianna, this series had slipped my mind, I should have
> > coordinated with you on the P2M changes.
> > 
> > I think the new p2m structure is more regular and probably a bit easier
> > to work with, but if you have any questions about it please shout.
> > 
> 
> Thank you both, I will certainly do. I'll provide a version of the series
> updated to the new p2m structure in the weekend, while I'll send a v10
> addressing all of your very useful comments within the next week.

Thanks. Do I take it then that you don't consider the "RESEND v9" which
I have in my INBOX this morning suitable for application, only for
further review of the rebase I suppose if v10 is pending?

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM
  2014-07-14  8:54       ` Ian Campbell
@ 2014-07-14  9:22         ` Arianna Avanzini
  0 siblings, 0 replies; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-14  9:22 UTC (permalink / raw)
  To: Ian Campbell
  Cc: tim, paolo.valente, keir, Stefano Stabellini, andrew.cooper3,
	dario.faggioli, Julien Grall, Ian.Jackson, xen-devel,
	julien.grall, etrudeau, JBeulich, viktor.kleinik


[-- Attachment #1.1: Type: text/plain, Size: 1340 bytes --]

Il 14/lug/2014 10:54 "Ian Campbell" <Ian.Campbell@eu.citrix.com> ha scritto:
>
> On Fri, 2014-07-11 at 19:00 +0200, Arianna Avanzini wrote:
> > On 07/11/2014 04:24 PM, Ian Campbell wrote:
> > > On Fri, 2014-07-11 at 14:51 +0100, Julien Grall wrote:
> > >> Hi Arianna,
> > >>
> > >> Lots of patches has been pushed upstream since last week (GICv2 and
P2M,
> > >> reworking).
> > >
> > > Sorry Arianna, this series had slipped my mind, I should have
> > > coordinated with you on the P2M changes.
> > >
> > > I think the new p2m structure is more regular and probably a bit
easier
> > > to work with, but if you have any questions about it please shout.
> > >
> >
> > Thank you both, I will certainly do. I'll provide a version of the
series
> > updated to the new p2m structure in the weekend, while I'll send a v10
> > addressing all of your very useful comments within the next week.
>
> Thanks. Do I take it then that you don't consider the "RESEND v9" which
> I have in my INBOX this morning suitable for application, only for
> further review of the rebase I suppose if v10 is pending?
>

Exactly. I sent the patchset on the mailing list and not privately only
because any comment on the rebase itself would be very useful and would
give me the chance to work on them directly for v10.

Sorry for flooding your inbox,
Arianna

> Ian.
>

[-- Attachment #1.2: Type: text/html, Size: 1786 bytes --]

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 01/14] arch/arm: add consistency check to REMOVE p2m changes
  2014-07-14  0:50     ` [PATCH RESEND v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
@ 2014-07-14 10:57       ` Julien Grall
  2014-07-17 12:56         ` Ian Campbell
  0 siblings, 1 reply; 69+ messages in thread
From: Julien Grall @ 2014-07-14 10:57 UTC (permalink / raw)
  To: Arianna Avanzini, xen-devel
  Cc: julien.grall, paolo.valente, keir, stefano.stabellini, tim,
	dario.faggioli, Ian.Jackson, Ian.Campbell, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

Hi Arianna,

On 14/07/14 01:50, Arianna Avanzini wrote:
>   xen/arch/arm/p2m.c | 21 ++++++++++++++++++++-
>   1 file changed, 20 insertions(+), 1 deletion(-)
>
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index c0c011a..5a77189 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -596,12 +596,30 @@ static int apply_one_level(struct domain *d,
>
>           break;
>
> -    case RELINQUISH:
>       case REMOVE:
> +        if ( is_mapping_aligned(*addr, end_gpaddr, *maddr, level_size) )
> +        {
> +            unsigned long mfn = orig_pte.p2m.base;

I think the check is misplaced, it should go after:

if ( level < 3 && p2m_table(orig_pte) )
   return P2M_ONE_DESCEND;

It's because this code path can now be called with either a P2M Table or 
a P2M entry. You will get wrong error message and may log many times the 
same issue.

Also I've reported an issue to Ian about this code path today. If the 
guest balloning driver or your MMIO unmap a single 4K entry, it may fail 
or remove a  superpage by mistake.

> +            /*
> +             * Ensure that the guest address addr currently being
> +             * handled (that is in the range given as argument to
> +             * this function) is actually mapped to the corresponding
> +             * machine address in the specified range. maddr here is
> +             * the machine address given to the function, while mfn
> +             * is the machine frame number actually mapped to the
> +             * guest address: check if the two correspond.
> +             */
> +             if ( p2m_valid(orig_pte) && *maddr != pfn_to_paddr(mfn) )
> +                 printk("p2m_remove: mapping at %"PRIpaddr" is of maddr %"PRIpaddr" not %"PRIpaddr" as expected\n",
> +                        *addr, pfn_to_paddr(mfn), *maddr);

You have to print the domain id, otherwise we don't know where the issue 
comes from.

As said on the previous version, you can't use gdprintk to print the 
domain id. So you will have to do it yourself.

Regards,

-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 01/14] arch/arm: add consistency check to REMOVE p2m changes
  2014-07-14 10:57       ` Julien Grall
@ 2014-07-17 12:56         ` Ian Campbell
  0 siblings, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-17 12:56 UTC (permalink / raw)
  To: Julien Grall
  Cc: paolo.valente, keir, stefano.stabellini, tim, dario.faggioli,
	Ian.Jackson, xen-devel, julien.grall, etrudeau, andrew.cooper3,
	JBeulich, Arianna Avanzini, viktor.kleinik

On Mon, 2014-07-14 at 11:57 +0100, Julien Grall wrote:
> Hi Arianna,
> 
> On 14/07/14 01:50, Arianna Avanzini wrote:
> >   xen/arch/arm/p2m.c | 21 ++++++++++++++++++++-
> >   1 file changed, 20 insertions(+), 1 deletion(-)
> >
> > diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> > index c0c011a..5a77189 100644
> > --- a/xen/arch/arm/p2m.c
> > +++ b/xen/arch/arm/p2m.c
> > @@ -596,12 +596,30 @@ static int apply_one_level(struct domain *d,
> >
> >           break;
> >
> > -    case RELINQUISH:
> >       case REMOVE:
> > +        if ( is_mapping_aligned(*addr, end_gpaddr, *maddr, level_size) )
> > +        {
> > +            unsigned long mfn = orig_pte.p2m.base;
> 
> I think the check is misplaced, it should go after:
> 
> if ( level < 3 && p2m_table(orig_pte) )
>    return P2M_ONE_DESCEND;

Correct.

Note that this also follows a check for non-present entries. so that
part of the check can be dropped as well.

> 
> It's because this code path can now be called with either a P2M Table or 
> a P2M entry. You will get wrong error message and may log many times the 
> same issue.
> 
> Also I've reported an issue to Ian about this code path today. If the 
> guest balloning driver or your MMIO unmap a single 4K entry, it may fail 
> or remove a  superpage by mistake.

Right, see my patch "xen: arm: correctly handle removing a subset of a
superpage mapping." from Monday.

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters
  2014-07-14  0:50     ` [PATCH RESEND v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters Arianna Avanzini
@ 2014-07-17 12:57       ` Ian Campbell
  2014-07-18 12:43         ` Ian Campbell
  0 siblings, 1 reply; 69+ messages in thread
From: Ian Campbell @ 2014-07-17 12:57 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: paolo.valente, keir, stefano.stabellini, Ian.Jackson,
	dario.faggioli, tim, xen-devel, julien.grall, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

On Mon, 2014-07-14 at 02:50 +0200, Arianna Avanzini wrote:
> Currently, the map_mmio_regions() function, defined for the ARM
> architecture, has parameters with paddr_t type. This interface,
> however, needs caller functions to correctly page-align addresses
> given as parameters to map_mmio_regions(). This commit changes the
> function's interface to accept page frame numbers as parameters.
> This commit also modifies caller functions in an attempt to adapt
> them to the new interface.
> This commit is meant to produce the minimum indispensable needed
> changes; these are also instrumental to making the interface of
> map_mmio_regions() symmetric with the unmap_mmio_regions() function,
> that will be introduced in one of the next commits of the series
> and will feature a pfn-based interface.
> 
> NOTE: platform-specific code has not been tested, save for the
>       sunxi and the Arndale Exynos 5 platforms (see the Tested-by
>       below for the latter).
> 
> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Tested-by: Julien Grall <julien.grall@citrix.com>
> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>

Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 07/14] xen/common: add ARM stub for the function memory_type_changed()
  2014-07-14  0:50     ` [PATCH RESEND v9 07/14] xen/common: add ARM stub for the function memory_type_changed() Arianna Avanzini
@ 2014-07-17 12:59       ` Ian Campbell
  2014-07-24 14:07       ` Julien Grall
  1 sibling, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-17 12:59 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: paolo.valente, keir, stefano.stabellini, Ian.Jackson,
	dario.faggioli, tim, xen-devel, julien.grall, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

On Mon, 2014-07-14 at 02:50 +0200, Arianna Avanzini wrote:
> MTRR-related code is not available for the ARM architecture. Given
> that the memory_type_changed() function would be called also from
> common code, its invocation is currently ifdef'd out to be only
> compiled in on an x86 machine. This commit adds an empty stub for ARM.
> 
> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Julien Grall <julien.grall@citrix.com>

Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL
  2014-07-14  0:50     ` [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL Arianna Avanzini
@ 2014-07-17 13:00       ` Ian Campbell
  2014-07-23 11:59       ` Jan Beulich
  1 sibling, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-17 13:00 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: paolo.valente, keir, stefano.stabellini, Ian.Jackson,
	dario.faggioli, tim, xen-devel, julien.grall, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

On Mon, 2014-07-14 at 02:50 +0200, Arianna Avanzini wrote:
> This commit factors out from the XEN_DOMCTL_memory_mapping hypercall
> implementation, currently available only for x86, the operations
> related to memory ranges map and unmap. The code is factored out
> into two {map|unmap}_mmio_regions() functions for x86, that will match
> the corresponding pair of ARM functions when the DOMCTL will be moved
> to common code in the following commit. This commit also adds an
> unmap_mmio_regions() function for ARM so that the following transition
> to common code is cleaner.
> 
> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Julien Grall <julien.grall@citrix.com>

For the (trivial) ARM bits:
Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters
  2014-07-17 12:57       ` Ian Campbell
@ 2014-07-18 12:43         ` Ian Campbell
  0 siblings, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-18 12:43 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: paolo.valente, keir, stefano.stabellini, tim, dario.faggioli,
	Ian.Jackson, xen-devel, julien.grall, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik


On Thu, 2014-07-17 at 13:57 +0100, Ian Campbell wrote:
> On Mon, 2014-07-14 at 02:50 +0200, Arianna Avanzini wrote:
> > Currently, the map_mmio_regions() function, defined for the ARM
> > architecture, has parameters with paddr_t type. This interface,
> > however, needs caller functions to correctly page-align addresses
> > given as parameters to map_mmio_regions(). This commit changes the
> > function's interface to accept page frame numbers as parameters.
> > This commit also modifies caller functions in an attempt to adapt
> > them to the new interface.
> > This commit is meant to produce the minimum indispensable needed
> > changes; these are also instrumental to making the interface of
> > map_mmio_regions() symmetric with the unmap_mmio_regions() function,
> > that will be introduced in one of the next commits of the series
> > and will feature a pfn-based interface.
> > 
> > NOTE: platform-specific code has not been tested, save for the
> >       sunxi and the Arndale Exynos 5 platforms (see the Tested-by
> >       below for the latter).
> > 
> > Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> > Tested-by: Julien Grall <julien.grall@citrix.com>
> > Cc: Dario Faggioli <dario.faggioli@citrix.com>
> > Cc: Paolo Valente <paolo.valente@unimore.it>
> > Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> 
> Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>

Since they represent an interface change which clashes with other
upcoming series I've applied this patch and the next one (arch/arm: let
map_mmio_regions() use start and count).

I had to apply a simple fixlet to the second patch:
diff --git a/xen/arch/arm/platforms/xgene-storm.c b/xen/arch/arm/platforms/xgene-storm.c
index 2980c0d..29c4752 100644
--- a/xen/arch/arm/platforms/xgene-storm.c
+++ b/xen/arch/arm/platforms/xgene-storm.c
@@ -47,7 +47,7 @@ static int map_one_mmio(struct domain *d, const char *what,
 
     printk("Additional MMIO %"PRIpaddr"-%"PRIpaddr" (%s)\n",
            start, end, what);
-    ret = map_mmio_regions(d, start, end, end - start + 1, start);
+    ret = map_mmio_regions(d, start, end - start + 1, start);
     if ( ret )
         printk("Failed to map %s @ %"PRIpaddr" to dom%d\n",
                what, start, d->domain_id);

Ian.

^ permalink raw reply related	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL
  2014-07-14  0:50     ` [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL Arianna Avanzini
  2014-07-17 13:00       ` Ian Campbell
@ 2014-07-23 11:59       ` Jan Beulich
  2014-07-23 12:54         ` Arianna Avanzini
  1 sibling, 1 reply; 69+ messages in thread
From: Jan Beulich @ 2014-07-23 11:59 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	andrew.cooper3, dario.faggioli, Ian.Jackson, xen-devel,
	julien.grall, etrudeau, tim, viktor.kleinik

>>> On 14.07.14 at 02:50, <avanzini.arianna@gmail.com> wrote:
>     v9:
>         - Don't ignore an error if it doesn't happen while unmapping the last
>           I/O-memory mapping in unmap_mmio_regions() for x86.
>         - Fix wrong argument in the call to unmap_mmio_regions() performed on
>           failure by map_mmio_regions() for x86.
>         - Explicitly specify nr_mfns in the commit message emitted when the
>           function map_mmio_regions() fails in the DOMCTL handling code.
>         - Change "nr_mfns" to "nr" in the arch-specific map/unmap functions
>           for x86.

A "resend" with actual changes is kind of odd anyway, and sadly
you didn't also address the coding style problems here which I
has pointed out on the original v9. That means you won't get
around sending a v10...

Jan

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL
  2014-07-23 11:59       ` Jan Beulich
@ 2014-07-23 12:54         ` Arianna Avanzini
  2014-07-23 13:04           ` Ian Campbell
  0 siblings, 1 reply; 69+ messages in thread
From: Arianna Avanzini @ 2014-07-23 12:54 UTC (permalink / raw)
  To: Jan Beulich
  Cc: Ian.Campbell, paolo.valente, keir, stefano.stabellini,
	andrew.cooper3, dario.faggioli, Ian.Jackson, xen-devel,
	julien.grall, etrudeau, tim, viktor.kleinik

On 07/23/2014 01:59 PM, Jan Beulich wrote:
>>>> On 14.07.14 at 02:50, <avanzini.arianna@gmail.com> wrote:
>>     v9:
>>         - Don't ignore an error if it doesn't happen while unmapping the last
>>           I/O-memory mapping in unmap_mmio_regions() for x86.
>>         - Fix wrong argument in the call to unmap_mmio_regions() performed on
>>           failure by map_mmio_regions() for x86.
>>         - Explicitly specify nr_mfns in the commit message emitted when the
>>           function map_mmio_regions() fails in the DOMCTL handling code.
>>         - Change "nr_mfns" to "nr" in the arch-specific map/unmap functions
>>           for x86.
> 
> A "resend" with actual changes is kind of odd anyway, and sadly
> you didn't also address the coding style problems here which I
> has pointed out on the original v9. That means you won't get
> around sending a v10...
> 

Thank you for your feedback. The changes above are related to the original v9
([1]); in the resend I only rebased the patchset on top of the latest
ARM-related changes. So, something actually changed, mostly in the first
patches, but it was only what was instrumental to let the patchset apply and
compile on top of those ARM-related GIC and p2m changes. I'm sorry if it was not
clear, most probably there is some more appropriate tag for a patchset with such
a purpose.

As of v10, I am working on it, and I have done my best to address the very
important coding style problems you pointed out; the reason why I haven't sent
it yet is that, due to my lack of experience, I am having some fun finding out a
way to pipe up to libxl information about the class of PCI devices. I however
hope to be proposing it very soon.

Thank you,
Arianna

[1] http://markmail.org/message/h4upm4ve7n7h4bnk

> Jan
> 


-- 
/*
 * Arianna Avanzini
 * avanzini.arianna@gmail.com
 * 73628@studenti.unimore.it
 */

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL
  2014-07-23 12:54         ` Arianna Avanzini
@ 2014-07-23 13:04           ` Ian Campbell
  0 siblings, 0 replies; 69+ messages in thread
From: Ian Campbell @ 2014-07-23 13:04 UTC (permalink / raw)
  To: Arianna Avanzini
  Cc: tim, paolo.valente, keir, stefano.stabellini, andrew.cooper3,
	dario.faggioli, Ian.Jackson, xen-devel, julien.grall, etrudeau,
	Jan Beulich, viktor.kleinik

On Wed, 2014-07-23 at 14:54 +0200, Arianna Avanzini wrote:
> I am having some fun finding out a
> way to pipe up to libxl information about the class of PCI devices. I however
> hope to be proposing it very soon.

I think you can just read it from SYSFS_PCI_DEV/BDF/class (see #defines
in tools/libxl/libxl_osdeps.h).

Ian.

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 07/14] xen/common: add ARM stub for the function memory_type_changed()
  2014-07-14  0:50     ` [PATCH RESEND v9 07/14] xen/common: add ARM stub for the function memory_type_changed() Arianna Avanzini
  2014-07-17 12:59       ` Ian Campbell
@ 2014-07-24 14:07       ` Julien Grall
  1 sibling, 0 replies; 69+ messages in thread
From: Julien Grall @ 2014-07-24 14:07 UTC (permalink / raw)
  To: Arianna Avanzini, xen-devel
  Cc: julien.grall, paolo.valente, keir, stefano.stabellini, tim,
	dario.faggioli, Ian.Jackson, Ian.Campbell, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

Hi Arianna,

On 07/14/2014 01:50 AM, Arianna Avanzini wrote:
> MTRR-related code is not available for the ARM architecture. Given
> that the memory_type_changed() function would be called also from
> common code, its invocation is currently ifdef'd out to be only
> compiled in on an x86 machine. This commit adds an empty stub for ARM.
> 
> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
Acked-by: Julien Grall <julien.grall@linaro.org>

Regards,

> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Julien Grall <julien.grall@citrix.com>
> Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
> Cc: Jan Beulich <JBeulich@suse.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Eric Trudeau <etrudeau@broadcom.com>
> Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
> 
> ---
> 
>     v9:
>         - Don't expose the memory_type_changed() function to common code,
>           just add an empty stub in arch/arm/p2m.c and in the related header
>           for ARM.
> 
> ---
>  xen/arch/arm/p2m.c        | 4 ++++
>  xen/common/domctl.c       | 2 --
>  xen/include/asm-arm/p2m.h | 2 ++
>  3 files changed, 6 insertions(+), 2 deletions(-)
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index e9f7c96..6add407 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -47,6 +47,10 @@ void p2m_dump_info(struct domain *d)
>      spin_unlock(&p2m->lock);
>  }
>  
> +void memory_type_changed(struct domain *d)
> +{
> +}
> +
>  void dump_p2m_lookup(struct domain *d, paddr_t addr)
>  {
>      struct p2m_domain *p2m = &d->arch.p2m;
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index c326aba..24102c0 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -897,10 +897,8 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>              ret = iomem_permit_access(d, mfn, mfn + nr_mfns - 1);
>          else
>              ret = iomem_deny_access(d, mfn, mfn + nr_mfns - 1);
> -#ifdef CONFIG_X86
>          if ( !ret )
>              memory_type_changed(d);
> -#endif
>      }
>      break;
>  
> diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
> index 06c93a0..13fea36 100644
> --- a/xen/include/asm-arm/p2m.h
> +++ b/xen/include/asm-arm/p2m.h
> @@ -5,6 +5,8 @@
>  
>  struct domain;
>  
> +extern void memory_type_changed(struct domain *);
> +
>  /* Per-p2m-table state */
>  struct p2m_domain {
>      /* Lock that protects updates to the p2m */
> 


-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code
  2014-07-14  0:50     ` [PATCH RESEND v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code Arianna Avanzini
@ 2014-07-24 14:10       ` Julien Grall
  0 siblings, 0 replies; 69+ messages in thread
From: Julien Grall @ 2014-07-24 14:10 UTC (permalink / raw)
  To: Arianna Avanzini, xen-devel
  Cc: julien.grall, paolo.valente, keir, stefano.stabellini, tim,
	dario.faggioli, Ian.Jackson, Ian.Campbell, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

Hi Arianna,

On 07/14/2014 01:50 AM, Arianna Avanzini wrote:
> This commit moves to common code the implementation of the memory_mapping
> DOMCTL, currently available only for the x86 architecture. It also adds
> a definition for the PADDR_BITS constant for ARM, that is to be used in
> common code and currently not available for the ARM architecture.
> 
> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Acked-by: Jan Beulich <JBeulich@suse.com>

Acked-by: Julien Grall <julien.grall@linaro.org>
Tested-by: Julien Grall <julien.grall@linaro.org>

Regards,

> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Julien Grall <julien.grall@citrix.com>
> Cc: Ian Campbell <Ian.Campbell@eu.citrix.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Eric Trudeau <etrudeau@broadcom.com>
> Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
> 
> ---
> 
>     v9:
>         - Don't expose the type mfn_t to common code; let the x86-specific map/
>           unmap functions perform the type cast and use unsigned long in common
>           code.
> 
>     v7:
>         - Change the name of tmp_rc to rc. Also, do not uselessly initialize it.
>         - ifdef out the invocation of memory_type_changed() to be called only
>           if the architecture is x86 instead of adding an useless empty stub
>           for ARM.
> 
>     v6:
>         - Add an empty definition of the memory_type_changed() function for ARM.
> 
>     v5:
>         - Rename new header to p2m-common.h.
> 
>     v4:
>         - Use a define for paddr_bits instead of a new variable.
>         - Define prototypes for common functions map_mmio_regions() and
>           unmap_mmio_regions() only once in a common header.
> 
>     v3:
>         - Add a paddr_bits variable for ARM.
> 
>     v2:
>         - Move code to xen/arm/domctl.c.
> 
> ---
>  xen/arch/arm/p2m.c           |  8 +++---
>  xen/arch/x86/domctl.c        | 68 --------------------------------------------
>  xen/common/domctl.c          | 68 ++++++++++++++++++++++++++++++++++++++++++++
>  xen/include/asm-arm/p2m.h    | 15 +++-------
>  xen/include/asm-x86/p2m.h    | 13 +--------
>  xen/include/xen/p2m-common.h | 16 +++++++++++
>  6 files changed, 93 insertions(+), 95 deletions(-)
>  create mode 100644 xen/include/xen/p2m-common.h
> 
> diff --git a/xen/arch/arm/p2m.c b/xen/arch/arm/p2m.c
> index a85e58d..57e36b2 100644
> --- a/xen/arch/arm/p2m.c
> +++ b/xen/arch/arm/p2m.c
> @@ -862,24 +862,24 @@ int p2m_populate_ram(struct domain *d,
>  
>  int map_mmio_regions(struct domain *d,
>                       unsigned long start_gfn,
> -                     unsigned long nr_mfns,
> +                     unsigned long nr,
>                       unsigned long mfn)
>  {
>      return apply_p2m_changes(d, INSERT,
>                               pfn_to_paddr(start_gfn),
> -                             pfn_to_paddr(start_gfn + nr_mfns),
> +                             pfn_to_paddr(start_gfn + nr),
>                               pfn_to_paddr(mfn),
>                               MATTR_DEV, p2m_mmio_direct);
>  }
>  
>  int unmap_mmio_regions(struct domain *d,
>                         unsigned long start_gfn,
> -                       unsigned long nr_mfns,
> +                       unsigned long nr,
>                         unsigned long mfn)
>  {
>      return apply_p2m_changes(d, REMOVE,
>                               pfn_to_paddr(start_gfn),
> -                             pfn_to_paddr(start_gfn + nr_mfns),
> +                             pfn_to_paddr(start_gfn + nr),
>                               pfn_to_paddr(mfn),
>                               MATTR_DEV, p2m_invalid);
>  }
> diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
> index 15af792..c211818 100644
> --- a/xen/arch/x86/domctl.c
> +++ b/xen/arch/x86/domctl.c
> @@ -641,74 +641,6 @@ long arch_do_domctl(
>      }
>      break;
>  
> -    case XEN_DOMCTL_memory_mapping:
> -    {
> -        unsigned long gfn = domctl->u.memory_mapping.first_gfn;
> -        unsigned long mfn = domctl->u.memory_mapping.first_mfn;
> -        unsigned long nr_mfns = domctl->u.memory_mapping.nr_mfns;
> -        unsigned long mfn_end = mfn + nr_mfns - 1;
> -        int add = domctl->u.memory_mapping.add_mapping;
> -
> -        ret = -EINVAL;
> -        if ( mfn_end < mfn || /* wrap? */
> -             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
> -             (gfn + nr_mfns - 1) < gfn ) /* wrap? */
> -            break;
> -
> -        ret = -EPERM;
> -        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
> -            break;
> -
> -        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
> -        if ( ret )
> -            break;
> -
> -        if ( add )
> -        {
> -            printk(XENLOG_G_INFO
> -                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
> -                   d->domain_id, gfn, mfn, nr_mfns);
> -
> -            ret = iomem_permit_access(d, mfn, mfn_end);
> -            if ( !ret )
> -            {
> -                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
> -                if ( ret )
> -                {
> -                    printk(XENLOG_G_WARNING
> -                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
> -                           d->domain_id, gfn, mfn, nr_mfns, ret);
> -                    if ( iomem_deny_access(d, mfn, mfn_end) &&
> -                         is_hardware_domain(current->domain) )
> -                        printk(XENLOG_ERR
> -                               "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
> -                               d->domain_id, mfn, mfn_end);
> -                }
> -            }
> -        }
> -        else
> -        {
> -            int rc = 0;
> -
> -            printk(XENLOG_G_INFO
> -                   "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
> -                   d->domain_id, gfn, mfn, nr_mfns);
> -
> -            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
> -            ret = iomem_deny_access(d, mfn, mfn_end);
> -            if ( !ret )
> -                ret = rc;
> -            if ( ret && is_hardware_domain(current->domain) )
> -                printk(XENLOG_ERR
> -                       "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
> -                       ret, rc ? "removing" : "denying", d->domain_id,
> -                       mfn, mfn_end);
> -        }
> -        /* Do this unconditionally to cover errors on above failure paths. */
> -        memory_type_changed(d);
> -    }
> -    break;
> -
>      case XEN_DOMCTL_ioport_mapping:
>      {
>          struct hvm_iommu *hd;
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index 24102c0..80b7800 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -902,6 +902,74 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>      }
>      break;
>  
> +    case XEN_DOMCTL_memory_mapping:
> +    {
> +        unsigned long gfn = op->u.memory_mapping.first_gfn;
> +        unsigned long mfn = op->u.memory_mapping.first_mfn;
> +        unsigned long nr_mfns = op->u.memory_mapping.nr_mfns;
> +        unsigned long mfn_end = mfn + nr_mfns - 1;
> +        int add = op->u.memory_mapping.add_mapping;
> +
> +        ret = -EINVAL;
> +        if ( mfn_end < mfn || /* wrap? */
> +             ((mfn | mfn_end) >> (paddr_bits - PAGE_SHIFT)) ||
> +             (gfn + nr_mfns - 1) < gfn ) /* wrap? */
> +            break;
> +
> +        ret = -EPERM;
> +        if ( !iomem_access_permitted(current->domain, mfn, mfn_end) )
> +            break;
> +
> +        ret = xsm_iomem_mapping(XSM_HOOK, d, mfn, mfn_end, add);
> +        if ( ret )
> +            break;
> +
> +        if ( add )
> +        {
> +            printk(XENLOG_G_INFO
> +                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
> +                   d->domain_id, gfn, mfn, nr_mfns);
> +
> +            ret = iomem_permit_access(d, mfn, mfn_end);
> +            if ( !ret )
> +            {
> +                ret = map_mmio_regions(d, gfn, nr_mfns, mfn);
> +                if ( ret )
> +                {
> +                    printk(XENLOG_G_WARNING
> +                           "memory_map:fail: dom%d gfn=%lx mfn=%lx nr=%lx ret:%ld\n",
> +                           d->domain_id, gfn, mfn, nr_mfns, ret);
> +                    if ( iomem_deny_access(d, mfn, mfn_end) &&
> +                         is_hardware_domain(current->domain) )
> +                        printk(XENLOG_ERR
> +                               "memory_map: failed to deny dom%d access to [%lx,%lx]\n",
> +                               d->domain_id, mfn, mfn_end);
> +                }
> +            }
> +        }
> +        else
> +        {
> +            int rc = 0;
> +
> +            printk(XENLOG_G_INFO
> +                   "memory_map:remove: dom%d gfn=%lx mfn=%lx nr=%lx\n",
> +                   d->domain_id, gfn, mfn, nr_mfns);
> +
> +            rc = unmap_mmio_regions(d, gfn, nr_mfns, mfn);
> +            ret = iomem_deny_access(d, mfn, mfn_end);
> +            if ( !ret )
> +                ret = rc;
> +            if ( ret && is_hardware_domain(current->domain) )
> +                printk(XENLOG_ERR
> +                       "memory_map: error %ld %s dom%d access to [%lx,%lx]\n",
> +                       ret, rc ? "removing" : "denying", d->domain_id,
> +                       mfn, mfn_end);
> +        }
> +        /* Do this unconditionally to cover errors on above failure paths. */
> +        memory_type_changed(d);
> +    }
> +    break;
> +
>      case XEN_DOMCTL_settimeoffset:
>      {
>          domain_set_time_offset(d, op->u.settimeoffset.time_offset_seconds);
> diff --git a/xen/include/asm-arm/p2m.h b/xen/include/asm-arm/p2m.h
> index 648144f..08ce07b 100644
> --- a/xen/include/asm-arm/p2m.h
> +++ b/xen/include/asm-arm/p2m.h
> @@ -3,6 +3,10 @@
>  
>  #include <xen/mm.h>
>  
> +#include <xen/p2m-common.h>
> +
> +#define paddr_bits PADDR_BITS
> +
>  struct domain;
>  
>  extern void memory_type_changed(struct domain *);
> @@ -101,17 +105,6 @@ int p2m_cache_flush(struct domain *d, xen_pfn_t start_mfn, xen_pfn_t end_mfn);
>  
>  /* Setup p2m RAM mapping for domain d from start-end. */
>  int p2m_populate_ram(struct domain *d, paddr_t start, paddr_t end);
> -/* Map MMIO regions in the p2m: start_gfn and nr_mfns describe the range
> - * in the guest physical address space to map, starting from the machine
> - * frame number mfn. */
> -int map_mmio_regions(struct domain *d,
> -                     unsigned long start_gfn,
> -                     unsigned long nr_mfns,
> -                     unsigned long mfn);
> -int unmap_mmio_regions(struct domain *d,
> -                       unsigned long start_gfn,
> -                       unsigned long nr_mfns,
> -                       unsigned long mfn);
>  
>  int guest_physmap_add_entry(struct domain *d,
>                              unsigned long gfn,
> diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
> index cea46e1..2a65848 100644
> --- a/xen/include/asm-x86/p2m.h
> +++ b/xen/include/asm-x86/p2m.h
> @@ -29,21 +29,10 @@
>  
>  #include <xen/config.h>
>  #include <xen/paging.h>
> +#include <xen/p2m-common.h>
>  #include <asm/mem_sharing.h>
>  #include <asm/page.h>    /* for pagetable_t */
>  
> -/* Map MMIO regions in the p2m: start_gfn and nr describe the range in
> - * the guest physical address space to map, starting from the machine
> - * frame number mfn. */
> -int map_mmio_regions(struct domain *d,
> -                     unsigned long start_gfn,
> -                     unsigned long nr,
> -                     unsigned long mfn);
> -int unmap_mmio_regions(struct domain *d,
> -                       unsigned long start_gfn,
> -                       unsigned long nr,
> -                       unsigned long mfn);
> -
>  extern bool_t opt_hap_1gb, opt_hap_2mb;
>  
>  /*
> diff --git a/xen/include/xen/p2m-common.h b/xen/include/xen/p2m-common.h
> new file mode 100644
> index 0000000..9f1b771
> --- /dev/null
> +++ b/xen/include/xen/p2m-common.h
> @@ -0,0 +1,16 @@
> +#ifndef _XEN_P2M_COMMON_H
> +#define _XEN_P2M_COMMON_H
> +
> +/* Map MMIO regions in the p2m: start_gfn and nr describe the range in
> + *  * the guest physical address space to map, starting from the machine
> + *   * frame number mfn. */
> +int map_mmio_regions(struct domain *d,
> +                     unsigned long start_gfn,
> +                     unsigned long nr,
> +                     unsigned long mfn);
> +int unmap_mmio_regions(struct domain *d,
> +                       unsigned long start_gfn,
> +                       unsigned long nr,
> +                       unsigned long mfn);
> +
> +#endif /* _XEN_P2M_COMMON_H */
> 


-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

* Re: [PATCH RESEND v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall
  2014-07-14  0:50     ` [PATCH RESEND v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall Arianna Avanzini
@ 2014-07-24 14:12       ` Julien Grall
  0 siblings, 0 replies; 69+ messages in thread
From: Julien Grall @ 2014-07-24 14:12 UTC (permalink / raw)
  To: Arianna Avanzini, xen-devel
  Cc: julien.grall, paolo.valente, keir, stefano.stabellini, tim,
	dario.faggioli, Ian.Jackson, Ian.Campbell, etrudeau, JBeulich,
	andrew.cooper3, viktor.kleinik

Hi Arianna,

On 07/14/2014 01:50 AM, Arianna Avanzini wrote:
> Currently, the configuration-parsing code concerning the handling of the
> iomem parameter only invokes the XEN_DOMCTL_iomem_permission hypercall.
> This commit lets the XEN_DOMCTL_memory_mapping hypercall be invoked
> after XEN_DOMCTL_iomem_permission when the iomem parameter is parsed
> from a domU configuration file, so that the address range can be mapped
> to the address space of the domU. The hypercall is invoked only in case
> of domains using an auto-translated physmap.
> 
> Signed-off-by: Arianna Avanzini <avanzini.arianna@gmail.com>
> Acked-by: Ian Campbell <Ian.Campbell@eu.citrix.com>
Acked-by: Julien Grall <julien.grall@linaro.org>

Regards,

> Cc: Dario Faggioli <dario.faggioli@citrix.com>
> Cc: Paolo Valente <paolo.valente@unimore.it>
> Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
> Cc: Julien Grall <julien.grall@citrix.com>
> Cc: Jan Beulich <JBeulich@suse.com>
> Cc: Keir Fraser <keir@xen.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Ian Jackson <Ian.Jackson@eu.citrix.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: Eric Trudeau <etrudeau@broadcom.com>
> Cc: Viktor Kleinik <viktor.kleinik@globallogic.com>
> 
> ---
> 
>     v9:
>         - Enforce checks on return value of xc_domain_getinfo() as it could
>           return information concerning the wrong domain.
>         - Don't use PERROR for xc_core_* functions.
>         - Avoid emitting an error message if xc_core_auto_translated_physmap()
>           fails.
> 
>     v8:
>         - Fix wrong error message emitted when the memory_mapping DOMCTL is
>           called by a domain that is not auto-translated.
> 
>     v7:
>         - Move the check for an auto-translated physmap to xc to avoid having
>           to expose the information to libxl.
> 
>     v4:
>         - Let the hypercall be called only in case the guest uses an
>           auto-translated physmap.
> 
>     v3:
>         - Add ifdefs to let the hypercall be called only by ARM or x86
>           HVM guests, with a whitelist approach.
>         - Remove the NOTE comment.
> 
>     v2:
>         - Add a comment explaining outstanding issues.
> 
> ---
>  tools/libxc/xc_domain.c    | 10 ++++++++++
>  tools/libxl/libxl_create.c | 11 +++++++++++
>  2 files changed, 21 insertions(+)
> 
> diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
> index 0230c6c..27fe3b6 100644
> --- a/tools/libxc/xc_domain.c
> +++ b/tools/libxc/xc_domain.c
> @@ -1959,6 +1959,16 @@ int xc_domain_memory_mapping(
>      uint32_t add_mapping)
>  {
>      DECLARE_DOMCTL;
> +    xc_dominfo_t info;
> +
> +    if ( xc_domain_getinfo(xch, domid, 1, &info) != 1 ||
> +         info.domid != domid )
> +    {
> +        PERROR("Could not get info for domain");
> +        return -EINVAL;
> +    }
> +    if ( !xc_core_arch_auto_translated_physmap(&info) )
> +        return 0;
>  
>      domctl.cmd = XEN_DOMCTL_memory_mapping;
>      domctl.domain = domid;
> diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
> index 3bfe65b..1217310 100644
> --- a/tools/libxl/libxl_create.c
> +++ b/tools/libxl/libxl_create.c
> @@ -1158,6 +1158,17 @@ static void domcreate_launch_dm(libxl__egc *egc, libxl__multidev *multidev,
>                   "failed give dom%d access to iomem range %"PRIx64"-%"PRIx64,
>                   domid, io->start, io->start + io->number - 1);
>              ret = ERROR_FAIL;
> +            continue;
> +        }
> +        ret = xc_domain_memory_mapping(CTX->xch, domid,
> +                                       io->gfn, io->start,
> +                                       io->number, 1);
> +        if (ret < 0) {
> +            LOGE(ERROR,
> +                 "failed to map to dom%d iomem range %"PRIx64"-%"PRIx64
> +                 " to guest address %"PRIx64,
> +                 domid, io->start, io->start + io->number - 1, io->gfn);
> +            ret = ERROR_FAIL;
>          }
>      }
>  
> 


-- 
Julien Grall

^ permalink raw reply	[flat|nested] 69+ messages in thread

end of thread, other threads:[~2014-07-24 14:12 UTC | newest]

Thread overview: 69+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-07-02 18:42 [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Arianna Avanzini
2014-07-02 18:42 ` [PATCH v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
2014-07-03 10:24   ` Julien Grall
2014-07-03 11:03   ` Julien Grall
2014-07-03 14:28     ` Ian Campbell
2014-07-03 14:44       ` Julien Grall
2014-07-02 18:42 ` [PATCH v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters Arianna Avanzini
2014-07-03 10:26   ` Julien Grall
2014-07-02 18:42 ` [PATCH v9 03/14] arch/arm: let map_mmio_regions() use start and count Arianna Avanzini
2014-07-02 18:42 ` [PATCH v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions Arianna Avanzini
2014-07-03 14:40   ` Ian Campbell
2014-07-03 15:00     ` Julien Grall
2014-07-03 15:15       ` Ian Campbell
2014-07-02 18:42 ` [PATCH v9 05/14] arch/x86: warn if to-be-removed mapping does not exist Arianna Avanzini
2014-07-02 18:42 ` [PATCH v9 06/14] arch/x86: cleanup memory_mapping DOMCTL Arianna Avanzini
2014-07-02 18:42 ` [PATCH v9 07/14] xen/common: add ARM stub for the function memory_type_changed() Arianna Avanzini
2014-07-03 14:41   ` Ian Campbell
2014-07-02 18:42 ` [PATCH v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL Arianna Avanzini
2014-07-03 10:43   ` Jan Beulich
2014-07-02 18:42 ` [PATCH v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code Arianna Avanzini
2014-07-02 18:42 ` [PATCH v9 10/14] tools/libxl: parse optional start gfn from the iomem config option Arianna Avanzini
2014-07-02 18:42 ` [PATCH v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall Arianna Avanzini
2014-07-02 18:42 ` [PATCH v9 12/14] tools/libxl: read from config if passing through primary GPU Arianna Avanzini
2014-07-02 19:00   ` Sander Eikelenboom
2014-07-03 10:30     ` Jan Beulich
2014-07-03 10:49       ` Sander Eikelenboom
2014-07-03 10:58         ` Jan Beulich
2014-07-03 14:50       ` Ian Campbell
2014-07-03 14:53         ` Ian Campbell
2014-07-03 15:17           ` Jan Beulich
2014-07-03 15:25             ` Ian Campbell
2014-07-03 15:37               ` Jan Beulich
2014-07-03 16:11                 ` Ian Campbell
2014-07-03 15:45               ` Sander Eikelenboom
2014-07-03 14:47   ` Ian Campbell
2014-07-02 18:42 ` [PATCH v9 13/14] tools/libxl: explicitly grant access to needed I/O-memory ranges Arianna Avanzini
2014-07-02 18:42 ` [PATCH v9 14/14] xen/common: do not implicitly permit access to mapped I/O memory Arianna Avanzini
2014-07-11 13:51 ` [PATCH v9 00/14] Implement the XEN_DOMCTL_memory_mapping hypercall for ARM Julien Grall
2014-07-11 14:24   ` Ian Campbell
2014-07-11 17:00     ` Arianna Avanzini
2014-07-14  8:54       ` Ian Campbell
2014-07-14  9:22         ` Arianna Avanzini
2014-07-14  0:50   ` [PATCH RESEND " Arianna Avanzini
2014-07-14  0:50     ` [PATCH RESEND v9 01/14] arch/arm: add consistency check to REMOVE p2m changes Arianna Avanzini
2014-07-14 10:57       ` Julien Grall
2014-07-17 12:56         ` Ian Campbell
2014-07-14  0:50     ` [PATCH RESEND v9 02/14] arch/arm: let map_mmio_regions() take pfn as parameters Arianna Avanzini
2014-07-17 12:57       ` Ian Campbell
2014-07-18 12:43         ` Ian Campbell
2014-07-14  0:50     ` [PATCH RESEND v9 03/14] arch/arm: let map_mmio_regions() use start and count Arianna Avanzini
2014-07-14  0:50     ` [PATCH RESEND v9 04/14] arch/arm: unmap partially-mapped I/O-memory regions Arianna Avanzini
2014-07-14  0:50     ` [PATCH RESEND v9 05/14] arch/x86: warn if to-be-removed mapping does not exist Arianna Avanzini
2014-07-14  0:50     ` [PATCH RESEND v9 06/14] arch/x86: cleanup memory_mapping DOMCTL Arianna Avanzini
2014-07-14  0:50     ` [PATCH RESEND v9 07/14] xen/common: add ARM stub for the function memory_type_changed() Arianna Avanzini
2014-07-17 12:59       ` Ian Campbell
2014-07-24 14:07       ` Julien Grall
2014-07-14  0:50     ` [PATCH RESEND v9 08/14] xen/x86: factor out map and unmap from the memory_mapping DOMCTL Arianna Avanzini
2014-07-17 13:00       ` Ian Campbell
2014-07-23 11:59       ` Jan Beulich
2014-07-23 12:54         ` Arianna Avanzini
2014-07-23 13:04           ` Ian Campbell
2014-07-14  0:50     ` [PATCH RESEND v9 09/14] xen/common: move the memory_mapping DOMCTL hypercall to common code Arianna Avanzini
2014-07-24 14:10       ` Julien Grall
2014-07-14  0:50     ` [PATCH RESEND v9 10/14] tools/libxl: parse optional start gfn from the iomem config option Arianna Avanzini
2014-07-14  0:50     ` [PATCH RESEND v9 11/14] tools/libxl: handle the iomem parameter with the memory_mapping hcall Arianna Avanzini
2014-07-24 14:12       ` Julien Grall
2014-07-14  0:50     ` [PATCH RESEND v9 12/14] tools/libxl: read from config if passing through primary GPU Arianna Avanzini
2014-07-14  0:50     ` [PATCH RESEND v9 13/14] tools/libxl: explicitly grant access to needed I/O-memory ranges Arianna Avanzini
2014-07-14  0:50     ` [PATCH RESEND v9 14/14] xen/common: do not implicitly permit access to mapped I/O memory Arianna Avanzini

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.