All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 REPOST 00/12] x86: guest resource mapping
@ 2017-08-22 14:50 Paul Durrant
  2017-08-22 14:50 ` [PATCH v2 REPOST 01/12] [x86|arm]: remove code duplication Paul Durrant
                   ` (11 more replies)
  0 siblings, 12 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Ian Jackson, Tim Deegan, Julien Grall, Paul Durrant, Jan Beulich

(REPOST after rebase and reference fix in patch #4 comment)

This series introduces support for direct mapping of guest resources.
The resources are:
 - Grant tables
 - IOREQ server pages

Paul Durrant (12):
  [x86|arm]: remove code duplication
  x86/mm: allow a privileged PV domain to map guest mfns
  x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  tools/libxenforeignmemory: add support for resource mapping
  tools/libxenctrl: use new xenforeignmemory API to seed grant table
  x86/hvm/ioreq: rename .*pfn and .*gmfn to .*gfn
  x86/hvm/ioreq: use bool rather than bool_t
  x86/hvm/ioreq: move is_default into struct hvm_ioreq_server
  x86/hvm/ioreq: simplify code and use consistent naming
  x86/hvm/ioreq: use gfn_t in struct hvm_ioreq_page
  x86/hvm/ioreq: defer mapping gfns until they are actually requsted
  x86/hvm/ioreq: add a new mappable resource type...

 tools/include/xen-sys/Linux/privcmd.h              |  11 +
 tools/libs/devicemodel/core.c                      |  18 +-
 tools/libs/devicemodel/include/xendevicemodel.h    |  14 +-
 tools/libs/foreignmemory/Makefile                  |   2 +-
 tools/libs/foreignmemory/core.c                    |  42 ++
 .../libs/foreignmemory/include/xenforeignmemory.h  |  39 ++
 tools/libs/foreignmemory/libxenforeignmemory.map   |   5 +
 tools/libs/foreignmemory/linux.c                   |  45 ++
 tools/libs/foreignmemory/private.h                 |  30 ++
 tools/libxc/include/xc_dom.h                       |   8 +-
 tools/libxc/xc_dom_boot.c                          | 102 ++++-
 tools/libxc/xc_sr_restore_x86_hvm.c                |  10 +-
 tools/libxc/xc_sr_restore_x86_pv.c                 |   2 +-
 tools/libxl/libxl_dom.c                            |   1 -
 tools/python/xen/lowlevel/xc/xc.c                  |   6 +-
 xen/arch/arm/mm.c                                  |  29 +-
 xen/arch/x86/hvm/dm.c                              |  11 +-
 xen/arch/x86/hvm/hvm.c                             |   8 +-
 xen/arch/x86/hvm/io.c                              |   4 +-
 xen/arch/x86/hvm/ioreq.c                           | 453 ++++++++++++---------
 xen/arch/x86/mm.c                                  | 177 ++++++--
 xen/arch/x86/mm/p2m.c                              |   3 +-
 xen/common/grant_table.c                           |  33 ++
 xen/include/asm-x86/hvm/domain.h                   |  11 +-
 xen/include/asm-x86/hvm/ioreq.h                    |  20 +-
 xen/include/asm-x86/p2m.h                          |   3 +
 xen/include/public/hvm/dm_op.h                     |  46 ++-
 xen/include/public/memory.h                        |  41 +-
 xen/include/xen/grant_table.h                      |   3 +
 29 files changed, 846 insertions(+), 331 deletions(-)

---
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <george.dunlap@eu.citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Wei Liu <wei.liu2@citrix.com>

v2:
 - Support for IOREQ server pages added

-- 
2.11.0


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

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

* [PATCH v2 REPOST 01/12] [x86|arm]: remove code duplication
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
@ 2017-08-22 14:50 ` Paul Durrant
  2017-08-24 14:12   ` Jan Beulich
  2017-08-22 14:50 ` [PATCH v2 REPOST 02/12] x86/mm: allow a privileged PV domain to map guest mfns Paul Durrant
                   ` (10 subsequent siblings)
  11 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:50 UTC (permalink / raw)
  To: xen-devel
  Cc: Andrew Cooper, Julien Grall, Paul Durrant, Stefano Stabellini,
	Jan Beulich

There is a substantial amount of code duplicated between the x86 and arm
implementations of mm.c:xenmem_add_to_physmap_one() for
XENMAPSPACE_grant_table. Also, the code in question looks like it really
should be in common/grant_table.c

This patch introduces a new function in common/grant_table.c to get the mfn
of a specified frame in the grant table of a specified guest, and calls to
that from the arch-specific code in mm.c.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Julien Grall <julien.grall@arm.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/arm/mm.c             | 29 ++++-------------------------
 xen/arch/x86/mm.c             | 26 +++-----------------------
 xen/common/grant_table.c      | 33 +++++++++++++++++++++++++++++++++
 xen/include/xen/grant_table.h |  3 +++
 4 files changed, 43 insertions(+), 48 deletions(-)

diff --git a/xen/arch/arm/mm.c b/xen/arch/arm/mm.c
index a810a056d7..5ae9607821 100644
--- a/xen/arch/arm/mm.c
+++ b/xen/arch/arm/mm.c
@@ -1229,32 +1229,11 @@ int xenmem_add_to_physmap_one(
     switch ( space )
     {
     case XENMAPSPACE_grant_table:
-        grant_write_lock(d->grant_table);
-
-        if ( d->grant_table->gt_version == 0 )
-            d->grant_table->gt_version = 1;
-
-        if ( d->grant_table->gt_version == 2 &&
-                (idx & XENMAPIDX_grant_table_status) )
-        {
-            idx &= ~XENMAPIDX_grant_table_status;
-            if ( idx < nr_status_frames(d->grant_table) )
-                mfn = virt_to_mfn(d->grant_table->status[idx]);
-            else
-                return -EINVAL;
-        }
-        else
-        {
-            if ( (idx >= nr_grant_frames(d->grant_table)) &&
-                 (idx < max_grant_frames) )
-                gnttab_grow_table(d, idx + 1);
-
-            if ( idx < nr_grant_frames(d->grant_table) )
-                mfn = virt_to_mfn(d->grant_table->shared_raw[idx]);
-            else
-                return -EINVAL;
-        }
+        mfn = gnttab_get_frame(d, idx);
+        if ( mfn_eq(mfn, INVALID_MFN) )
+            return -EINVAL;
 
+        grant_write_lock(d->grant_table);
         d->arch.grant_table_gfn[idx] = gfn;
 
         t = p2m_ram_rw;
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 5b863c6fa6..0abb1e284f 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4639,29 +4639,9 @@ int xenmem_add_to_physmap_one(
                 mfn = virt_to_mfn(d->shared_info);
             break;
         case XENMAPSPACE_grant_table:
-            grant_write_lock(d->grant_table);
-
-            if ( d->grant_table->gt_version == 0 )
-                d->grant_table->gt_version = 1;
-
-            if ( d->grant_table->gt_version == 2 &&
-                 (idx & XENMAPIDX_grant_table_status) )
-            {
-                idx &= ~XENMAPIDX_grant_table_status;
-                if ( idx < nr_status_frames(d->grant_table) )
-                    mfn = virt_to_mfn(d->grant_table->status[idx]);
-            }
-            else
-            {
-                if ( (idx >= nr_grant_frames(d->grant_table)) &&
-                     (idx < max_grant_frames) )
-                    gnttab_grow_table(d, idx + 1);
-
-                if ( idx < nr_grant_frames(d->grant_table) )
-                    mfn = virt_to_mfn(d->grant_table->shared_raw[idx]);
-            }
-
-            grant_write_unlock(d->grant_table);
+            mfn = mfn_x(gnttab_get_frame(d, idx));
+            if ( mfn_eq(_mfn(mfn), INVALID_MFN) )
+                return -EINVAL;
             break;
         case XENMAPSPACE_gmfn_range:
         case XENMAPSPACE_gmfn:
diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index 0f9dd1e706..b327458301 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -1621,6 +1621,39 @@ active_alloc_failed:
     return 0;
 }
 
+mfn_t
+gnttab_get_frame(struct domain *d, unsigned int idx)
+{
+    struct grant_table *gt = d->grant_table;
+    mfn_t mfn = INVALID_MFN;
+
+    grant_write_lock(gt);
+
+    if ( gt->gt_version == 0 )
+        gt->gt_version = 1;
+
+    if ( gt->gt_version == 2 &&
+         (idx & XENMAPIDX_grant_table_status) )
+    {
+        idx &= ~XENMAPIDX_grant_table_status;
+        if ( idx < nr_status_frames(gt) )
+            mfn = _mfn(virt_to_mfn(gt->status[idx]));
+    }
+    else
+    {
+        if ( (idx >= nr_grant_frames(gt)) &&
+             (idx < max_grant_frames) )
+            gnttab_grow_table(d, idx + 1);
+
+        if ( idx < nr_grant_frames(gt) )
+            mfn = _mfn(virt_to_mfn(gt->shared_raw[idx]));
+    }
+
+    grant_write_unlock(gt);
+
+    return mfn;
+}
+
 static long 
 gnttab_setup_table(
     XEN_GUEST_HANDLE_PARAM(gnttab_setup_table_t) uop, unsigned int count)
diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h
index b5af21b53c..079cf82a1e 100644
--- a/xen/include/xen/grant_table.h
+++ b/xen/include/xen/grant_table.h
@@ -129,6 +129,9 @@ gnttab_release_mappings(
 int
 gnttab_grow_table(struct domain *d, unsigned int req_nr_frames);
 
+/* Get mfn of grant frame */
+mfn_t gnttab_get_frame(struct domain *d, unsigned int idx);
+
 /* Number of grant table frames. Caller must hold d's grant table lock. */
 static inline unsigned int nr_grant_frames(struct grant_table *gt)
 {
-- 
2.11.0


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

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

* [PATCH v2 REPOST 02/12] x86/mm: allow a privileged PV domain to map guest mfns
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
  2017-08-22 14:50 ` [PATCH v2 REPOST 01/12] [x86|arm]: remove code duplication Paul Durrant
@ 2017-08-22 14:50 ` Paul Durrant
  2017-08-24 16:33   ` Wei Liu
  2017-08-22 14:50 ` [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources Paul Durrant
                   ` (9 subsequent siblings)
  11 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:50 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Paul Durrant, Jan Beulich

In the case where a PV domain is mapping guest resources then it needs make
the HYPERVISOR_mmu_update call using DOMID_SELF, rather than the guest
domid, so that the passed in gmfn values are correctly treated as mfns
rather than gfns present in the guest p2m.

This patch removes a check which currently disallows mapping of a page when
the owner of the page tables matches the domain passed to
HYPERVISOR_mmu_update, but that domain is not the real owner of the page.
The check was introduced by patch d3c6a215ca9 ("x86: Clean up
get_page_from_l1e() to correctly distinguish between owner-of-pte and
owner-of-data-page in all cases") but it's not clear why it was needed.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/mm.c | 13 ++++++++-----
 1 file changed, 8 insertions(+), 5 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 0abb1e284f..aaa9ff5197 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -989,12 +989,15 @@ get_page_from_l1e(
                    (real_pg_owner != dom_cow) ) )
     {
         /*
-         * Let privileged domains transfer the right to map their target
-         * domain's pages. This is used to allow stub-domain pvfb export to
-         * dom0, until pvfb supports granted mappings. At that time this
-         * minor hack can go away.
+         * If the real page owner is not the domain specified in the
+         * hypercall then establish that the specified domain has
+         * mapping privilege over the page owner.
+         * This is used to allow stub-domain pvfb export to dom0. It is
+         * also used to allow a privileged PV domain to map mfns using
+         * DOMID_SELF, which is needed for mapping guest resources such
+         * grant table frames.
          */
-        if ( (real_pg_owner == NULL) || (pg_owner == l1e_owner) ||
+        if ( (real_pg_owner == NULL) ||
              xsm_priv_mapping(XSM_TARGET, pg_owner, real_pg_owner) )
         {
             gdprintk(XENLOG_WARNING,
-- 
2.11.0


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

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

* [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
  2017-08-22 14:50 ` [PATCH v2 REPOST 01/12] [x86|arm]: remove code duplication Paul Durrant
  2017-08-22 14:50 ` [PATCH v2 REPOST 02/12] x86/mm: allow a privileged PV domain to map guest mfns Paul Durrant
@ 2017-08-22 14:50 ` Paul Durrant
  2017-08-28 15:01   ` Wei Liu
  2017-08-29 11:16   ` George Dunlap
  2017-08-22 14:50 ` [PATCH v2 REPOST 04/12] tools/libxenforeignmemory: add support for resource mapping Paul Durrant
                   ` (8 subsequent siblings)
  11 siblings, 2 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:50 UTC (permalink / raw)
  To: xen-devel; +Cc: George Dunlap, Andrew Cooper, Paul Durrant, Jan Beulich

Certain memory resources associated with a guest are not necessarily
present in the guest P2M and so are not necessarily available to be
foreign-mapped by a tools domain unless they are inserted, which risks
shattering a super-page mapping.

This patch adds a new memory op to allow such resourced to be priv-mapped
directly, by either a PV or HVM tools domain.

NOTE: Whilst the new op is not intrinsicly specific to the x86 architecture,
      I have no means to test it on an ARM platform and so cannot verify
      that it functions correctly. Hence it is currently only implemented
      for x86.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <george.dunlap@eu.citrix.com>
---
 xen/arch/x86/mm.c           | 111 ++++++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/mm/p2m.c       |   3 +-
 xen/include/asm-x86/p2m.h   |   3 ++
 xen/include/public/memory.h |  38 ++++++++++++++-
 4 files changed, 152 insertions(+), 3 deletions(-)

diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index aaa9ff5197..4e86f0a2ab 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -4717,6 +4717,107 @@ int xenmem_add_to_physmap_one(
     return rc;
 }
 
+static int xenmem_acquire_grant_table(struct domain *d,
+                                      unsigned long frame,
+                                      unsigned long nr_frames,
+                                      unsigned long mfn_list[])
+{
+    unsigned int i;
+
+    /*
+     * Iterate through the list backwards so that gnttab_get_frame() is
+     * first called for the highest numbered frame. This means that the
+     * out-of-bounds check will be done on the first iteration and, if
+     * the table needs to grow, it will only grow once.
+     */
+    i = nr_frames;
+    while ( i-- != 0 )
+    {
+        mfn_t mfn = gnttab_get_frame(d, frame + i);
+
+        if ( mfn_eq(mfn, INVALID_MFN) )
+            return -EINVAL;
+
+        mfn_list[i] = mfn_x(mfn);
+    }
+
+    return 0;
+}
+
+static int xenmem_acquire_resource(xen_mem_acquire_resource_t *xmar)
+{
+    struct domain *d, *currd = current->domain;
+    unsigned long *mfn_list;
+    int rc;
+
+    if ( xmar->nr_frames == 0 )
+        return -EINVAL;
+
+    d = rcu_lock_domain_by_any_id(xmar->domid);
+    if ( d == NULL )
+        return -ESRCH;
+
+    rc = xsm_domain_memory_map(XSM_TARGET, d);
+    if ( rc )
+        goto out;
+
+    mfn_list = xmalloc_array(unsigned long, xmar->nr_frames);
+
+    rc = -ENOMEM;
+    if ( !mfn_list )
+        goto out;
+
+    switch ( xmar->type )
+    {
+    case XENMEM_resource_grant_table:
+        rc = -EINVAL;
+        if ( xmar->id ) /* must be zero for grant_table */
+            break;
+
+        rc = xenmem_acquire_grant_table(d, xmar->frame, xmar->nr_frames,
+                                        mfn_list);
+        break;
+
+    default:
+        rc = -EOPNOTSUPP;
+        break;
+    }
+
+    if ( rc )
+        goto free_and_out;
+
+    if ( !paging_mode_translate(currd) )
+    {
+        if ( __copy_to_guest_offset(xmar->gmfn_list, 0, mfn_list,
+                                    xmar->nr_frames) )
+            rc = -EFAULT;
+    }
+    else
+    {
+        unsigned int i;
+
+        for ( i = 0; i < xmar->nr_frames; i++ )
+        {
+            xen_pfn_t gfn;
+
+            rc = -EFAULT;
+            if ( __copy_from_guest_offset(&gfn, xmar->gmfn_list, i, 1) )
+                goto free_and_out;
+
+            rc = set_foreign_p2m_entry(currd, gfn, _mfn(mfn_list[i]));
+            if ( rc )
+                goto free_and_out;
+        }
+    }
+
+ free_and_out:
+    xfree(mfn_list);
+
+ out:
+    rcu_unlock_domain(d);
+    return rc;
+}
+
 long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 {
     int rc;
@@ -4939,6 +5040,16 @@ long arch_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
         return rc;
     }
 
+    case XENMEM_acquire_resource:
+    {
+        xen_mem_acquire_resource_t xmar;
+
+        if ( copy_from_guest(&xmar, arg, 1) )
+            return -EFAULT;
+
+        return xenmem_acquire_resource(&xmar);
+    }
+
     default:
         return subarch_memory_op(cmd, arg);
     }
diff --git a/xen/arch/x86/mm/p2m.c b/xen/arch/x86/mm/p2m.c
index e8a57d118c..c503a7f1d2 100644
--- a/xen/arch/x86/mm/p2m.c
+++ b/xen/arch/x86/mm/p2m.c
@@ -1118,8 +1118,7 @@ static int set_typed_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
 }
 
 /* Set foreign mfn in the given guest's p2m table. */
-static int set_foreign_p2m_entry(struct domain *d, unsigned long gfn,
-                                 mfn_t mfn)
+int set_foreign_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn)
 {
     return set_typed_p2m_entry(d, gfn, mfn, PAGE_ORDER_4K, p2m_map_foreign,
                                p2m_get_hostp2m(d)->default_access);
diff --git a/xen/include/asm-x86/p2m.h b/xen/include/asm-x86/p2m.h
index 6395e8fd1d..3ccec250d8 100644
--- a/xen/include/asm-x86/p2m.h
+++ b/xen/include/asm-x86/p2m.h
@@ -613,6 +613,9 @@ void p2m_memory_type_changed(struct domain *d);
 int p2m_is_logdirty_range(struct p2m_domain *, unsigned long start,
                           unsigned long end);
 
+/* Set foreign entry in the p2m table (for priv-mapping) */
+int set_foreign_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn);
+
 /* Set mmio addresses in the p2m table (for pass-through) */
 int set_mmio_p2m_entry(struct domain *d, unsigned long gfn, mfn_t mfn,
                        unsigned int order, p2m_access_t access);
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 29386df98b..9bf58e7384 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -650,7 +650,43 @@ struct xen_vnuma_topology_info {
 typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t;
 DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t);
 
-/* Next available subop number is 28 */
+#if defined(__XEN__) || defined(__XEN_TOOLS__)
+
+/*
+ * Get the pages for a particular guest resource, so that they can be
+ * mapped directly by a tools domain.
+ */
+#define XENMEM_acquire_resource 28
+struct xen_mem_acquire_resource {
+    /* IN - the domain whose resource is to be mapped */
+    domid_t domid;
+    /* IN - the type of resource (defined below) */
+    uint16_t type;
+
+#define XENMEM_resource_grant_table 0
+
+    /*
+     * IN - a type-specific resource identifier, which must be zero
+     *      unless stated otherwise.
+     */
+    uint32_t id;
+    /* IN - number of (4K) frames of the resource to be mapped */
+    uint32_t nr_frames;
+    /* IN - the index of the initial frame to be mapped */
+    uint64_aligned_t frame;
+    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
+     *          will be populated with the MFNs of the resource.
+     *          If the tools domain is HVM then it is expected that, on
+     *          entry, gmfn_list will be populated with a list of GFNs
+     *          that will be mapped to the MFNs of the resource.
+     */
+    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
+};
+typedef struct xen_mem_acquire_resource xen_mem_acquire_resource_t;
+
+#endif /* defined(__XEN__) || defined(__XEN_TOOLS__) */
+
+/* Next available subop number is 29 */
 
 #endif /* __XEN_PUBLIC_MEMORY_H__ */
 
-- 
2.11.0


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

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

* [PATCH v2 REPOST 04/12] tools/libxenforeignmemory: add support for resource mapping
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
                   ` (2 preceding siblings ...)
  2017-08-22 14:50 ` [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources Paul Durrant
@ 2017-08-22 14:50 ` Paul Durrant
  2017-08-24 15:52   ` Roger Pau Monné
  2017-08-22 14:50 ` [PATCH v2 REPOST 05/12] tools/libxenctrl: use new xenforeignmemory API to seed grant table Paul Durrant
                   ` (7 subsequent siblings)
  11 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:50 UTC (permalink / raw)
  To: xen-devel; +Cc: Wei Liu, Paul Durrant, Ian Jackson

A previous patch introduced a new HYPERVISOR_memory_op to acquire guest
resources for direct priv-mapping.

This patch adds new functionality into libxenforeignmemory to make use
of a new privcmd ioctl [1] that uses the new memory op to make such
resources available via mmap(2).

[1] http://xenbits.xen.org/gitweb/?p=people/pauldu/linux.git;a=commit;h=ce59a05e6712

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>

v2:
 - Bump minor version up to 3
---
 tools/include/xen-sys/Linux/privcmd.h              | 11 ++++++
 tools/libs/foreignmemory/Makefile                  |  2 +-
 tools/libs/foreignmemory/core.c                    | 42 ++++++++++++++++++++
 .../libs/foreignmemory/include/xenforeignmemory.h  | 39 +++++++++++++++++++
 tools/libs/foreignmemory/libxenforeignmemory.map   |  5 +++
 tools/libs/foreignmemory/linux.c                   | 45 ++++++++++++++++++++++
 tools/libs/foreignmemory/private.h                 | 30 +++++++++++++++
 7 files changed, 173 insertions(+), 1 deletion(-)

diff --git a/tools/include/xen-sys/Linux/privcmd.h b/tools/include/xen-sys/Linux/privcmd.h
index 732ff7c15a..9531b728f9 100644
--- a/tools/include/xen-sys/Linux/privcmd.h
+++ b/tools/include/xen-sys/Linux/privcmd.h
@@ -86,6 +86,15 @@ typedef struct privcmd_dm_op {
 	const privcmd_dm_op_buf_t __user *ubufs;
 } privcmd_dm_op_t;
 
+typedef struct privcmd_mmap_resource {
+	domid_t dom;
+	__u32 type;
+	__u32 id;
+	__u32 idx;
+	__u64 num;
+	__u64 addr;
+} privcmd_mmap_resource_t;
+
 /*
  * @cmd: IOCTL_PRIVCMD_HYPERCALL
  * @arg: &privcmd_hypercall_t
@@ -103,5 +112,7 @@ typedef struct privcmd_dm_op {
 	_IOC(_IOC_NONE, 'P', 5, sizeof(privcmd_dm_op_t))
 #define IOCTL_PRIVCMD_RESTRICT					\
 	_IOC(_IOC_NONE, 'P', 6, sizeof(domid_t))
+#define IOCTL_PRIVCMD_MMAP_RESOURCE				\
+	_IOC(_IOC_NONE, 'P', 7, sizeof(privcmd_mmap_resource_t))
 
 #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */
diff --git a/tools/libs/foreignmemory/Makefile b/tools/libs/foreignmemory/Makefile
index b110076621..7eb59c78cb 100644
--- a/tools/libs/foreignmemory/Makefile
+++ b/tools/libs/foreignmemory/Makefile
@@ -2,7 +2,7 @@ XEN_ROOT = $(CURDIR)/../../..
 include $(XEN_ROOT)/tools/Rules.mk
 
 MAJOR    = 1
-MINOR    = 2
+MINOR    = 3
 SHLIB_LDFLAGS += -Wl,--version-script=libxenforeignmemory.map
 
 CFLAGS   += -Werror -Wmissing-prototypes
diff --git a/tools/libs/foreignmemory/core.c b/tools/libs/foreignmemory/core.c
index a6897dc561..291ee44516 100644
--- a/tools/libs/foreignmemory/core.c
+++ b/tools/libs/foreignmemory/core.c
@@ -120,6 +120,48 @@ int xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
     return osdep_xenforeignmemory_restrict(fmem, domid);
 }
 
+xenforeignmemory_resource_handle *xenforeignmemory_map_resource(
+    xenforeignmemory_handle *fmem, domid_t domid, unsigned int type,
+    unsigned int id, unsigned long frame, unsigned long nr_frames,
+    void **paddr, int prot, int flags)
+{
+    xenforeignmemory_resource_handle *fres;
+    int rc;
+
+    fres = calloc(1, sizeof(*fres));
+    if ( !fres )
+        return NULL;
+
+    fres->domid = domid;
+    fres->type = type;
+    fres->id = id;
+    fres->frame = frame;
+    fres->nr_frames = nr_frames;
+    fres->addr = *paddr;
+    fres->prot = prot;
+    fres->flags = flags;
+
+    rc = osdep_xenforeignmemory_map_resource(fmem, fres);
+    if ( rc )
+        goto fail;
+
+    *paddr = fres->addr;
+    return fres;
+
+fail:
+    free(fres);
+
+    return NULL;
+}
+
+void xenforeignmemory_unmap_resource(
+    xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+    osdep_xenforeignmemory_unmap_resource(fmem, fres);
+
+    free(fres);
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libs/foreignmemory/include/xenforeignmemory.h b/tools/libs/foreignmemory/include/xenforeignmemory.h
index f4814c390f..e56eb3c4d4 100644
--- a/tools/libs/foreignmemory/include/xenforeignmemory.h
+++ b/tools/libs/foreignmemory/include/xenforeignmemory.h
@@ -138,6 +138,45 @@ int xenforeignmemory_unmap(xenforeignmemory_handle *fmem,
 int xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
                               domid_t domid);
 
+typedef struct xenforeignmemory_resource_handle xenforeignmemory_resource_handle;
+
+/**
+ * This function maps a guest resource.
+ *
+ * @parm fmem handle to the open foreignmemory interface
+ * @parm domid the domain id
+ * @parm type the resource type
+ * @parm id the type-specific resource identifier
+ * @parm frame base frame index within the resource
+ * @parm nr_frames number of frames to map
+ * @parm paddr pointer to an address passed through to mmap(2)
+ * @parm prot passed through to mmap(2)
+ * @parm flags passed through to mmap(2)
+ * @return pointer to foreignmemory resource handle on success, NULL on
+ *         failure
+ *
+ * *paddr is used, on entry, as a hint address for foreign map placement
+ * (see mmap(2)) so should be set to NULL if no specific placement is
+ * required. On return *paddr contains the address where the resource is
+ * mapped.
+ * As for xenforeignmemory_map2() flags is a set of additional flags
+ * for mmap(2). Not all of the flag combinations are possible due to
+ * implementation details on different platforms.
+ */
+xenforeignmemory_resource_handle *xenforeignmemory_map_resource(
+    xenforeignmemory_handle *fmem, domid_t domid, unsigned int type,
+    unsigned int id, unsigned long frame, unsigned long nr_frames,
+    void **paddr, int prot, int flags);
+
+/**
+ * This function releases a previously acquired resource.
+ *
+ * @parm fmem handle to the open foreignmemory interface
+ * @parm fres handle to the acquired resource
+ */
+void xenforeignmemory_unmap_resource(
+    xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres);
+
 #endif
 
 /*
diff --git a/tools/libs/foreignmemory/libxenforeignmemory.map b/tools/libs/foreignmemory/libxenforeignmemory.map
index 716ecaf15c..d5323c87d9 100644
--- a/tools/libs/foreignmemory/libxenforeignmemory.map
+++ b/tools/libs/foreignmemory/libxenforeignmemory.map
@@ -14,3 +14,8 @@ VERS_1.2 {
 	global:
 		xenforeignmemory_map2;
 } VERS_1.1;
+VERS_1.3 {
+	global:
+		xenforeignmemory_map_resource;
+		xenforeignmemory_unmap_resource;
+} VERS_1.2;
diff --git a/tools/libs/foreignmemory/linux.c b/tools/libs/foreignmemory/linux.c
index 374e45aed5..4447723cb1 100644
--- a/tools/libs/foreignmemory/linux.c
+++ b/tools/libs/foreignmemory/linux.c
@@ -277,6 +277,51 @@ int osdep_xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
     return ioctl(fmem->fd, IOCTL_PRIVCMD_RESTRICT, &domid);
 }
 
+void osdep_xenforeignmemory_unmap_resource(
+    xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+    (void) munmap(fres->addr, fres->nr_frames << PAGE_SHIFT);
+}
+
+int osdep_xenforeignmemory_map_resource(
+    xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+    privcmd_mmap_resource_t mr;
+    int rc;
+
+    fres->addr = mmap(fres->addr, fres->nr_frames << PAGE_SHIFT,
+                      fres->prot, fres->flags | MAP_SHARED, fmem->fd, 0);
+    if ( fres->addr == MAP_FAILED )
+        return -1;
+
+    memset(&mr, 0, sizeof(mr));
+    mr.dom = fres->domid;
+    mr.type = fres->type;
+    mr.id = fres->id;
+    mr.idx = fres->frame;
+    mr.num = fres->nr_frames;
+    mr.addr = (uintptr_t)fres->addr;
+
+    rc = ioctl(fmem->fd, IOCTL_PRIVCMD_MMAP_RESOURCE, &mr);
+    if ( rc )
+    {
+        int saved_errno;
+
+        if ( errno != ENOTTY )
+            PERROR("ioctl failed");
+        else
+            errno = EOPNOTSUPP;
+
+        saved_errno = errno;
+        osdep_xenforeignmemory_unmap_resource(fmem, fres);
+        errno = saved_errno;
+
+        return -1;
+    }
+
+    return 0;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libs/foreignmemory/private.h b/tools/libs/foreignmemory/private.h
index c5c07cc4c4..2ae9382669 100644
--- a/tools/libs/foreignmemory/private.h
+++ b/tools/libs/foreignmemory/private.h
@@ -42,6 +42,36 @@ void *compat_mapforeign_batch(xenforeignmem_handle *fmem, uint32_t dom,
                               xen_pfn_t *arr, int num);
 #endif
 
+struct xenforeignmemory_resource_handle {
+    domid_t domid;
+    unsigned int type;
+    unsigned int id;
+    unsigned long frame;
+    unsigned long nr_frames;
+    void *addr;
+    int prot;
+    int flags;
+};
+
+#ifndef __linux__
+static inline int osdep_xenforeignmemory_map_resource(
+    xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+    errno = EOPNOTSUPP;
+    return -1;
+}
+
+void osdep_xenforeignmemory_unmap_resource(
+    xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres)
+{
+}
+#else
+int osdep_xenforeignmemory_map_resource(
+    xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres);
+void osdep_xenforeignmemory_unmap_resource(
+    xenforeignmemory_handle *fmem, xenforeignmemory_resource_handle *fres);
+#endif
+
 #define PERROR(_f...) \
     xtl_log(fmem->logger, XTL_ERROR, errno, "xenforeignmemory", _f)
 
-- 
2.11.0


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

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

* [PATCH v2 REPOST 05/12] tools/libxenctrl: use new xenforeignmemory API to seed grant table
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
                   ` (3 preceding siblings ...)
  2017-08-22 14:50 ` [PATCH v2 REPOST 04/12] tools/libxenforeignmemory: add support for resource mapping Paul Durrant
@ 2017-08-22 14:50 ` Paul Durrant
  2017-08-24 16:02   ` Roger Pau Monné
  2017-08-22 14:51 ` [PATCH v2 REPOST 06/12] x86/hvm/ioreq: rename .*pfn and .*gmfn to .*gfn Paul Durrant
                   ` (6 subsequent siblings)
  11 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:50 UTC (permalink / raw)
  To: xen-devel; +Cc: Wei Liu, Paul Durrant, Ian Jackson

A previous patch added support for priv-mapping guest resources directly
(rather than having to foreign-map, which requires P2M modification for
HVM guests).

This patch makes use of the new API to seed the guest grant table unless
the underlying infrastructure (i.e. privcmd) doesn't support it, in which
case the old scheme is used.

NOTE: The call to xc_dom_gnttab_hvm_seed() in hvm_build_set_params() was
      actually unnecessary, as the grant table has already been seeded
      by a prior call to xc_dom_gnttab_init() made by libxl__build_dom().

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
Acked-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxc/include/xc_dom.h        |   8 +--
 tools/libxc/xc_dom_boot.c           | 102 ++++++++++++++++++++++++++++--------
 tools/libxc/xc_sr_restore_x86_hvm.c |  10 ++--
 tools/libxc/xc_sr_restore_x86_pv.c  |   2 +-
 tools/libxl/libxl_dom.c             |   1 -
 tools/python/xen/lowlevel/xc/xc.c   |   6 +--
 6 files changed, 92 insertions(+), 37 deletions(-)

diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
index ce47058c41..d6ca0a8680 100644
--- a/tools/libxc/include/xc_dom.h
+++ b/tools/libxc/include/xc_dom.h
@@ -323,12 +323,8 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn,
 int xc_dom_boot_image(struct xc_dom_image *dom);
 int xc_dom_compat_check(struct xc_dom_image *dom);
 int xc_dom_gnttab_init(struct xc_dom_image *dom);
-int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
-                           xen_pfn_t console_gmfn,
-                           xen_pfn_t xenstore_gmfn,
-                           domid_t console_domid,
-                           domid_t xenstore_domid);
-int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
+int xc_dom_gnttab_seed(xc_interface *xch, domid_t guest_domid,
+                       bool is_hvm,
                        xen_pfn_t console_gmfn,
                        xen_pfn_t xenstore_gmfn,
                        domid_t console_domid,
diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
index c3b44dd399..fc3174ad7e 100644
--- a/tools/libxc/xc_dom_boot.c
+++ b/tools/libxc/xc_dom_boot.c
@@ -280,11 +280,11 @@ static xen_pfn_t xc_dom_gnttab_setup(xc_interface *xch, domid_t domid)
     return gmfn;
 }
 
-int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
-                       xen_pfn_t console_gmfn,
-                       xen_pfn_t xenstore_gmfn,
-                       domid_t console_domid,
-                       domid_t xenstore_domid)
+static int compat_gnttab_seed(xc_interface *xch, domid_t domid,
+                              xen_pfn_t console_gmfn,
+                              xen_pfn_t xenstore_gmfn,
+                              domid_t console_domid,
+                              domid_t xenstore_domid)
 {
 
     xen_pfn_t gnttab_gmfn;
@@ -337,11 +337,11 @@ int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
     return 0;
 }
 
-int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
-                           xen_pfn_t console_gpfn,
-                           xen_pfn_t xenstore_gpfn,
-                           domid_t console_domid,
-                           domid_t xenstore_domid)
+static int compat_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
+                                  xen_pfn_t console_gpfn,
+                                  xen_pfn_t xenstore_gpfn,
+                                  domid_t console_domid,
+                                  domid_t xenstore_domid)
 {
     int rc;
     xen_pfn_t scratch_gpfn;
@@ -380,7 +380,7 @@ int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
         return -1;
     }
 
-    rc = xc_dom_gnttab_seed(xch, domid,
+    rc = compat_gnttab_seed(xch, domid,
                             console_gpfn, xenstore_gpfn,
                             console_domid, xenstore_domid);
     if (rc != 0)
@@ -405,18 +405,78 @@ int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
     return 0;
 }
 
-int xc_dom_gnttab_init(struct xc_dom_image *dom)
+int xc_dom_gnttab_seed(xc_interface *xch, domid_t guest_domid,
+                       bool is_hvm, xen_pfn_t console_gmfn,
+                       xen_pfn_t xenstore_gmfn, domid_t console_domid,
+                       domid_t xenstore_domid)
 {
-    if ( xc_dom_translated(dom) ) {
-        return xc_dom_gnttab_hvm_seed(dom->xch, dom->guest_domid,
-                                      dom->console_pfn, dom->xenstore_pfn,
-                                      dom->console_domid, dom->xenstore_domid);
-    } else {
-        return xc_dom_gnttab_seed(dom->xch, dom->guest_domid,
-                                  xc_dom_p2m(dom, dom->console_pfn),
-                                  xc_dom_p2m(dom, dom->xenstore_pfn),
-                                  dom->console_domid, dom->xenstore_domid);
+    xenforeignmemory_handle* fmem = xch->fmem;
+    xenforeignmemory_resource_handle *fres;
+    void *addr = NULL;
+    grant_entry_v1_t *gnttab;
+
+    fres = xenforeignmemory_map_resource(fmem, guest_domid,
+                                         XENMEM_resource_grant_table,
+                                         0, 0, 1,
+                                         &addr, PROT_READ | PROT_WRITE, 0);
+    if ( !fres )
+    {
+        if ( errno == EOPNOTSUPP )
+            return is_hvm ?
+                compat_gnttab_hvm_seed(xch, guest_domid,
+                                       console_gmfn, xenstore_gmfn,
+                                       console_domid, xenstore_domid) :
+                compat_gnttab_seed(xch, guest_domid,
+                                   console_gmfn, xenstore_gmfn,
+                                   console_domid, xenstore_domid);
+
+        xc_dom_panic(xch, XC_INTERNAL_ERROR,
+                     "%s: failed to acquire grant table "
+                     "[errno=%d]\n",
+                     __FUNCTION__, errno);
+        return -1;
     }
+
+    gnttab = addr;
+
+    if ( guest_domid != console_domid  && console_gmfn != -1)
+    {
+        xc_dom_printf(xch, "%s: setting console pfn=0x%"PRI_xen_pfn,
+                      __FUNCTION__, console_gmfn);
+
+        gnttab[GNTTAB_RESERVED_CONSOLE].flags = GTF_permit_access;
+        gnttab[GNTTAB_RESERVED_CONSOLE].domid = console_domid;
+        gnttab[GNTTAB_RESERVED_CONSOLE].frame = console_gmfn;
+    }
+
+    if ( guest_domid != xenstore_domid && xenstore_gmfn != -1)
+    {
+        xc_dom_printf(xch, "%s: setting xenstore pfn=0x%"PRI_xen_pfn,
+                      __FUNCTION__, xenstore_gmfn);
+
+        gnttab[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access;
+        gnttab[GNTTAB_RESERVED_XENSTORE].domid = xenstore_domid;
+        gnttab[GNTTAB_RESERVED_XENSTORE].frame = xenstore_gmfn;
+    }
+
+    xenforeignmemory_unmap_resource(fmem, fres);
+
+    return 0;
+}
+
+int xc_dom_gnttab_init(struct xc_dom_image *dom)
+{
+    xc_interface *xch = dom->xch;
+    domid_t guest_domid = dom->guest_domid;
+    bool is_hvm = xc_dom_translated(dom);
+    xen_pfn_t console_gmfn = xc_dom_p2m(dom, dom->console_pfn);
+    xen_pfn_t xenstore_gmfn = xc_dom_p2m(dom, dom->xenstore_pfn);
+    domid_t console_domid = dom->console_domid;
+    domid_t xenstore_domid = dom->xenstore_domid;
+
+    return xc_dom_gnttab_seed(xch, guest_domid, is_hvm,
+                              console_gmfn, xenstore_gmfn,
+                              console_domid, xenstore_domid);
 }
 
 /*
diff --git a/tools/libxc/xc_sr_restore_x86_hvm.c b/tools/libxc/xc_sr_restore_x86_hvm.c
index 1dca85354a..a5c661da8f 100644
--- a/tools/libxc/xc_sr_restore_x86_hvm.c
+++ b/tools/libxc/xc_sr_restore_x86_hvm.c
@@ -207,11 +207,11 @@ static int x86_hvm_stream_complete(struct xc_sr_context *ctx)
         return rc;
     }
 
-    rc = xc_dom_gnttab_hvm_seed(xch, ctx->domid,
-                                ctx->restore.console_gfn,
-                                ctx->restore.xenstore_gfn,
-                                ctx->restore.console_domid,
-                                ctx->restore.xenstore_domid);
+    rc = xc_dom_gnttab_seed(xch, ctx->domid, true,
+                            ctx->restore.console_gfn,
+                            ctx->restore.xenstore_gfn,
+                            ctx->restore.console_domid,
+                            ctx->restore.xenstore_domid);
     if ( rc )
     {
         PERROR("Failed to seed grant table");
diff --git a/tools/libxc/xc_sr_restore_x86_pv.c b/tools/libxc/xc_sr_restore_x86_pv.c
index 50e25c162c..10635d436b 100644
--- a/tools/libxc/xc_sr_restore_x86_pv.c
+++ b/tools/libxc/xc_sr_restore_x86_pv.c
@@ -1104,7 +1104,7 @@ static int x86_pv_stream_complete(struct xc_sr_context *ctx)
     if ( rc )
         return rc;
 
-    rc = xc_dom_gnttab_seed(xch, ctx->domid,
+    rc = xc_dom_gnttab_seed(xch, ctx->domid, false,
                             ctx->restore.console_gfn,
                             ctx->restore.xenstore_gfn,
                             ctx->restore.console_domid,
diff --git a/tools/libxl/libxl_dom.c b/tools/libxl/libxl_dom.c
index f54fd49a73..0d3e462c12 100644
--- a/tools/libxl/libxl_dom.c
+++ b/tools/libxl/libxl_dom.c
@@ -851,7 +851,6 @@ static int hvm_build_set_params(xc_interface *handle, uint32_t domid,
     *store_mfn = str_mfn;
     *console_mfn = cons_mfn;
 
-    xc_dom_gnttab_hvm_seed(handle, domid, *console_mfn, *store_mfn, console_domid, store_domid);
     return 0;
 }
 
diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c
index aa9f8e4d9e..583ab52a6f 100644
--- a/tools/python/xen/lowlevel/xc/xc.c
+++ b/tools/python/xen/lowlevel/xc/xc.c
@@ -800,9 +800,9 @@ static PyObject *pyxc_gnttab_hvm_seed(XcObject *self,
 				      &console_domid, &xenstore_domid) )
         return NULL;
 
-    if ( xc_dom_gnttab_hvm_seed(self->xc_handle, dom,
-				console_gmfn, xenstore_gmfn,
-				console_domid, xenstore_domid) != 0 )
+    if ( xc_dom_gnttab_seed(self->xc_handle, dom, true,
+                            console_gmfn, xenstore_gmfn,
+                            console_domid, xenstore_domid) != 0 )
         return pyxc_error_to_exception(self->xc_handle);
 
     return Py_None;
-- 
2.11.0


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

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

* [PATCH v2 REPOST 06/12] x86/hvm/ioreq: rename .*pfn and .*gmfn to .*gfn
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
                   ` (4 preceding siblings ...)
  2017-08-22 14:50 ` [PATCH v2 REPOST 05/12] tools/libxenctrl: use new xenforeignmemory API to seed grant table Paul Durrant
@ 2017-08-22 14:51 ` Paul Durrant
  2017-08-24 16:06   ` Roger Pau Monné
  2017-08-28 15:01   ` Wei Liu
  2017-08-22 14:51 ` [PATCH v2 REPOST 07/12] x86/hvm/ioreq: use bool rather than bool_t Paul Durrant
                   ` (5 subsequent siblings)
  11 siblings, 2 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Paul Durrant, Jan Beulich

Since IOREQ servers are only relevant to HVM guests and all the names in
question unequivocally refer to guest frame numbers, name them all .*gfn
to avoid any confusion.

This patch is purely cosmetic. No semantic or functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 tools/libs/devicemodel/core.c                   | 10 ++--
 tools/libs/devicemodel/include/xendevicemodel.h | 12 ++--
 xen/arch/x86/hvm/dm.c                           |  4 +-
 xen/arch/x86/hvm/hvm.c                          |  6 +-
 xen/arch/x86/hvm/ioreq.c                        | 74 ++++++++++++-------------
 xen/include/asm-x86/hvm/domain.h                |  4 +-
 xen/include/asm-x86/hvm/ioreq.h                 |  4 +-
 xen/include/public/hvm/dm_op.h                  | 20 +++----
 8 files changed, 67 insertions(+), 67 deletions(-)

diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c
index d7c6476006..fcb260d29b 100644
--- a/tools/libs/devicemodel/core.c
+++ b/tools/libs/devicemodel/core.c
@@ -174,7 +174,7 @@ int xendevicemodel_create_ioreq_server(
 
 int xendevicemodel_get_ioreq_server_info(
     xendevicemodel_handle *dmod, domid_t domid, ioservid_t id,
-    xen_pfn_t *ioreq_pfn, xen_pfn_t *bufioreq_pfn,
+    xen_pfn_t *ioreq_gfn, xen_pfn_t *bufioreq_gfn,
     evtchn_port_t *bufioreq_port)
 {
     struct xen_dm_op op;
@@ -192,11 +192,11 @@ int xendevicemodel_get_ioreq_server_info(
     if (rc)
         return rc;
 
-    if (ioreq_pfn)
-        *ioreq_pfn = data->ioreq_pfn;
+    if (ioreq_gfn)
+        *ioreq_gfn = data->ioreq_gfn;
 
-    if (bufioreq_pfn)
-        *bufioreq_pfn = data->bufioreq_pfn;
+    if (bufioreq_gfn)
+        *bufioreq_gfn = data->bufioreq_gfn;
 
     if (bufioreq_port)
         *bufioreq_port = data->bufioreq_port;
diff --git a/tools/libs/devicemodel/include/xendevicemodel.h b/tools/libs/devicemodel/include/xendevicemodel.h
index 580fad2f49..13216db04a 100644
--- a/tools/libs/devicemodel/include/xendevicemodel.h
+++ b/tools/libs/devicemodel/include/xendevicemodel.h
@@ -60,17 +60,17 @@ int xendevicemodel_create_ioreq_server(
  * @parm dmod a handle to an open devicemodel interface.
  * @parm domid the domain id to be serviced
  * @parm id the IOREQ Server id.
- * @parm ioreq_pfn pointer to a xen_pfn_t to receive the synchronous ioreq
- *                  gmfn
- * @parm bufioreq_pfn pointer to a xen_pfn_t to receive the buffered ioreq
- *                    gmfn
+ * @parm ioreq_gfn pointer to a xen_pfn_t to receive the synchronous ioreq
+ *                  gfn
+ * @parm bufioreq_gfn pointer to a xen_pfn_t to receive the buffered ioreq
+ *                    gfn
  * @parm bufioreq_port pointer to a evtchn_port_t to receive the buffered
  *                     ioreq event channel
  * @return 0 on success, -1 on failure.
  */
 int xendevicemodel_get_ioreq_server_info(
     xendevicemodel_handle *dmod, domid_t domid, ioservid_t id,
-    xen_pfn_t *ioreq_pfn, xen_pfn_t *bufioreq_pfn,
+    xen_pfn_t *ioreq_gfn, xen_pfn_t *bufioreq_gfn,
     evtchn_port_t *bufioreq_port);
 
 /**
@@ -168,7 +168,7 @@ int xendevicemodel_destroy_ioreq_server(
  * This function sets IOREQ Server state. An IOREQ Server
  * will not be passed emulation requests until it is in
  * the enabled state.
- * Note that the contents of the ioreq_pfn and bufioreq_pfn are
+ * Note that the contents of the ioreq_gfn and bufioreq_gfn are
  * not meaningful until the IOREQ Server is in the enabled state.
  *
  * @parm dmod a handle to an open devicemodel interface.
diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index 4cf6deedc7..f7cb883fec 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -426,8 +426,8 @@ static int dm_op(const struct dmop_args *op_args)
             break;
 
         rc = hvm_get_ioreq_server_info(d, data->id,
-                                       &data->ioreq_pfn,
-                                       &data->bufioreq_pfn,
+                                       &data->ioreq_gfn,
+                                       &data->bufioreq_gfn,
                                        &data->bufioreq_port);
         break;
     }
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 6cb903def5..58b4afa1d1 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4185,20 +4185,20 @@ static int hvmop_set_param(
             rc = -EINVAL;
         break;
     case HVM_PARAM_IOREQ_SERVER_PFN:
-        d->arch.hvm_domain.ioreq_gmfn.base = a.value;
+        d->arch.hvm_domain.ioreq_gfn.base = a.value;
         break;
     case HVM_PARAM_NR_IOREQ_SERVER_PAGES:
     {
         unsigned int i;
 
         if ( a.value == 0 ||
-             a.value > sizeof(d->arch.hvm_domain.ioreq_gmfn.mask) * 8 )
+             a.value > sizeof(d->arch.hvm_domain.ioreq_gfn.mask) * 8 )
         {
             rc = -EINVAL;
             break;
         }
         for ( i = 0; i < a.value; i++ )
-            set_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
+            set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
 
         break;
     }
diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index b2a8b0e986..3e753ba224 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -181,17 +181,17 @@ bool_t handle_hvm_io_completion(struct vcpu *v)
     return 1;
 }
 
-static int hvm_alloc_ioreq_gmfn(struct domain *d, unsigned long *gmfn)
+static int hvm_alloc_ioreq_gfn(struct domain *d, unsigned long *gfn)
 {
     unsigned int i;
     int rc;
 
     rc = -ENOMEM;
-    for ( i = 0; i < sizeof(d->arch.hvm_domain.ioreq_gmfn.mask) * 8; i++ )
+    for ( i = 0; i < sizeof(d->arch.hvm_domain.ioreq_gfn.mask) * 8; i++ )
     {
-        if ( test_and_clear_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask) )
+        if ( test_and_clear_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask) )
         {
-            *gmfn = d->arch.hvm_domain.ioreq_gmfn.base + i;
+            *gfn = d->arch.hvm_domain.ioreq_gfn.base + i;
             rc = 0;
             break;
         }
@@ -200,12 +200,12 @@ static int hvm_alloc_ioreq_gmfn(struct domain *d, unsigned long *gmfn)
     return rc;
 }
 
-static void hvm_free_ioreq_gmfn(struct domain *d, unsigned long gmfn)
+static void hvm_free_ioreq_gfn(struct domain *d, unsigned long gfn)
 {
-    unsigned int i = gmfn - d->arch.hvm_domain.ioreq_gmfn.base;
+    unsigned int i = gfn - d->arch.hvm_domain.ioreq_gfn.base;
 
-    if ( gmfn != gfn_x(INVALID_GFN) )
-        set_bit(i, &d->arch.hvm_domain.ioreq_gmfn.mask);
+    if ( gfn != gfn_x(INVALID_GFN) )
+        set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
 }
 
 static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t buf)
@@ -216,7 +216,7 @@ static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t buf)
 }
 
 static int hvm_map_ioreq_page(
-    struct hvm_ioreq_server *s, bool_t buf, unsigned long gmfn)
+    struct hvm_ioreq_server *s, bool_t buf, unsigned long gfn)
 {
     struct domain *d = s->domain;
     struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
@@ -224,7 +224,7 @@ static int hvm_map_ioreq_page(
     void *va;
     int rc;
 
-    if ( (rc = prepare_ring_for_helper(d, gmfn, &page, &va)) )
+    if ( (rc = prepare_ring_for_helper(d, gfn, &page, &va)) )
         return rc;
 
     if ( (iorp->va != NULL) || d->is_dying )
@@ -235,7 +235,7 @@ static int hvm_map_ioreq_page(
 
     iorp->va = va;
     iorp->page = page;
-    iorp->gmfn = gmfn;
+    iorp->gfn = gfn;
 
     return 0;
 }
@@ -264,23 +264,23 @@ bool_t is_ioreq_server_page(struct domain *d, const struct page_info *page)
     return found;
 }
 
-static void hvm_remove_ioreq_gmfn(
+static void hvm_remove_ioreq_gfn(
     struct domain *d, struct hvm_ioreq_page *iorp)
 {
-    if ( guest_physmap_remove_page(d, _gfn(iorp->gmfn),
+    if ( guest_physmap_remove_page(d, _gfn(iorp->gfn),
                                    _mfn(page_to_mfn(iorp->page)), 0) )
         domain_crash(d);
     clear_page(iorp->va);
 }
 
-static int hvm_add_ioreq_gmfn(
+static int hvm_add_ioreq_gfn(
     struct domain *d, struct hvm_ioreq_page *iorp)
 {
     int rc;
 
     clear_page(iorp->va);
 
-    rc = guest_physmap_add_page(d, _gfn(iorp->gmfn),
+    rc = guest_physmap_add_page(d, _gfn(iorp->gfn),
                                 _mfn(page_to_mfn(iorp->page)), 0);
     if ( rc == 0 )
         paging_mark_dirty(d, _mfn(page_to_mfn(iorp->page)));
@@ -412,17 +412,17 @@ static void hvm_ioreq_server_remove_all_vcpus(struct hvm_ioreq_server *s)
 }
 
 static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
-                                      unsigned long ioreq_pfn,
-                                      unsigned long bufioreq_pfn)
+                                      unsigned long ioreq_gfn,
+                                      unsigned long bufioreq_gfn)
 {
     int rc;
 
-    rc = hvm_map_ioreq_page(s, 0, ioreq_pfn);
+    rc = hvm_map_ioreq_page(s, 0, ioreq_gfn);
     if ( rc )
         return rc;
 
-    if ( bufioreq_pfn != gfn_x(INVALID_GFN) )
-        rc = hvm_map_ioreq_page(s, 1, bufioreq_pfn);
+    if ( bufioreq_gfn != gfn_x(INVALID_GFN) )
+        rc = hvm_map_ioreq_page(s, 1, bufioreq_gfn);
 
     if ( rc )
         hvm_unmap_ioreq_page(s, 0);
@@ -435,8 +435,8 @@ static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
                                         bool_t handle_bufioreq)
 {
     struct domain *d = s->domain;
-    unsigned long ioreq_pfn = gfn_x(INVALID_GFN);
-    unsigned long bufioreq_pfn = gfn_x(INVALID_GFN);
+    unsigned long ioreq_gfn = gfn_x(INVALID_GFN);
+    unsigned long bufioreq_gfn = gfn_x(INVALID_GFN);
     int rc;
 
     if ( is_default )
@@ -451,18 +451,18 @@ static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
                    d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN]);
     }
 
-    rc = hvm_alloc_ioreq_gmfn(d, &ioreq_pfn);
+    rc = hvm_alloc_ioreq_gfn(d, &ioreq_gfn);
 
     if ( !rc && handle_bufioreq )
-        rc = hvm_alloc_ioreq_gmfn(d, &bufioreq_pfn);
+        rc = hvm_alloc_ioreq_gfn(d, &bufioreq_gfn);
 
     if ( !rc )
-        rc = hvm_ioreq_server_map_pages(s, ioreq_pfn, bufioreq_pfn);
+        rc = hvm_ioreq_server_map_pages(s, ioreq_gfn, bufioreq_gfn);
 
     if ( rc )
     {
-        hvm_free_ioreq_gmfn(d, ioreq_pfn);
-        hvm_free_ioreq_gmfn(d, bufioreq_pfn);
+        hvm_free_ioreq_gfn(d, ioreq_gfn);
+        hvm_free_ioreq_gfn(d, bufioreq_gfn);
     }
 
     return rc;
@@ -482,9 +482,9 @@ static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s,
     if ( !is_default )
     {
         if ( handle_bufioreq )
-            hvm_free_ioreq_gmfn(d, s->bufioreq.gmfn);
+            hvm_free_ioreq_gfn(d, s->bufioreq.gfn);
 
-        hvm_free_ioreq_gmfn(d, s->ioreq.gmfn);
+        hvm_free_ioreq_gfn(d, s->ioreq.gfn);
     }
 }
 
@@ -556,10 +556,10 @@ static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s,
 
     if ( !is_default )
     {
-        hvm_remove_ioreq_gmfn(d, &s->ioreq);
+        hvm_remove_ioreq_gfn(d, &s->ioreq);
 
         if ( handle_bufioreq )
-            hvm_remove_ioreq_gmfn(d, &s->bufioreq);
+            hvm_remove_ioreq_gfn(d, &s->bufioreq);
     }
 
     s->enabled = 1;
@@ -587,9 +587,9 @@ static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s,
     if ( !is_default )
     {
         if ( handle_bufioreq )
-            hvm_add_ioreq_gmfn(d, &s->bufioreq);
+            hvm_add_ioreq_gfn(d, &s->bufioreq);
 
-        hvm_add_ioreq_gmfn(d, &s->ioreq);
+        hvm_add_ioreq_gfn(d, &s->ioreq);
     }
 
     s->enabled = 0;
@@ -776,8 +776,8 @@ int hvm_destroy_ioreq_server(struct domain *d, ioservid_t id)
 }
 
 int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
-                              unsigned long *ioreq_pfn,
-                              unsigned long *bufioreq_pfn,
+                              unsigned long *ioreq_gfn,
+                              unsigned long *bufioreq_gfn,
                               evtchn_port_t *bufioreq_port)
 {
     struct hvm_ioreq_server *s;
@@ -796,11 +796,11 @@ int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
         if ( s->id != id )
             continue;
 
-        *ioreq_pfn = s->ioreq.gmfn;
+        *ioreq_gfn = s->ioreq.gfn;
 
         if ( s->bufioreq.va != NULL )
         {
-            *bufioreq_pfn = s->bufioreq.gmfn;
+            *bufioreq_gfn = s->bufioreq.gfn;
             *bufioreq_port = s->bufioreq_evtchn;
         }
 
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index d2899c9bb2..ce536f75ef 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -36,7 +36,7 @@
 #include <public/hvm/dm_op.h>
 
 struct hvm_ioreq_page {
-    unsigned long gmfn;
+    unsigned long gfn;
     struct page_info *page;
     void *va;
 };
@@ -105,7 +105,7 @@ struct hvm_domain {
     struct {
         unsigned long base;
         unsigned long mask;
-    } ioreq_gmfn;
+    } ioreq_gfn;
 
     /* Lock protects all other values in the sub-struct and the default */
     struct {
diff --git a/xen/include/asm-x86/hvm/ioreq.h b/xen/include/asm-x86/hvm/ioreq.h
index b43667a367..43fbe115dc 100644
--- a/xen/include/asm-x86/hvm/ioreq.h
+++ b/xen/include/asm-x86/hvm/ioreq.h
@@ -28,8 +28,8 @@ int hvm_create_ioreq_server(struct domain *d, domid_t domid,
                             ioservid_t *id);
 int hvm_destroy_ioreq_server(struct domain *d, ioservid_t id);
 int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
-                              unsigned long *ioreq_pfn,
-                              unsigned long *bufioreq_pfn,
+                              unsigned long *ioreq_gfn,
+                              unsigned long *bufioreq_gfn,
                               evtchn_port_t *bufioreq_port);
 int hvm_map_io_range_to_ioreq_server(struct domain *d, ioservid_t id,
                                      uint32_t type, uint64_t start,
diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h
index 2a4c3d938d..6bbab5fca3 100644
--- a/xen/include/public/hvm/dm_op.h
+++ b/xen/include/public/hvm/dm_op.h
@@ -41,9 +41,9 @@
  * A domain supports a single 'legacy' IOREQ Server which is instantiated if
  * parameter...
  *
- * HVM_PARAM_IOREQ_PFN is read (to get the gmfn containing the synchronous
+ * HVM_PARAM_IOREQ_PFN is read (to get the gfn containing the synchronous
  * ioreq structures), or...
- * HVM_PARAM_BUFIOREQ_PFN is read (to get the gmfn containing the buffered
+ * HVM_PARAM_BUFIOREQ_PFN is read (to get the gfn containing the buffered
  * ioreq ring), or...
  * HVM_PARAM_BUFIOREQ_EVTCHN is read (to get the event channel that Xen uses
  * to request buffered I/O emulation).
@@ -81,14 +81,14 @@ struct xen_dm_op_create_ioreq_server {
  *
  * The emulator needs to map the synchronous ioreq structures and buffered
  * ioreq ring (if it exists) that Xen uses to request emulation. These are
- * hosted in the target domain's gmfns <ioreq_pfn> and <bufioreq_pfn>
+ * hosted in the target domain's gmfns <ioreq_gfn> and <bufioreq_gfn>
  * respectively. In addition, if the IOREQ Server is handling buffered
  * emulation requests, the emulator needs to bind to event channel
  * <bufioreq_port> to listen for them. (The event channels used for
  * synchronous emulation requests are specified in the per-CPU ioreq
- * structures in <ioreq_pfn>).
+ * structures in <ioreq_gfn>).
  * If the IOREQ Server is not handling buffered emulation requests then the
- * values handed back in <bufioreq_pfn> and <bufioreq_port> will both be 0.
+ * values handed back in <bufioreq_gfn> and <bufioreq_port> will both be 0.
  */
 #define XEN_DMOP_get_ioreq_server_info 2
 
@@ -98,10 +98,10 @@ struct xen_dm_op_get_ioreq_server_info {
     uint16_t pad;
     /* OUT - buffered ioreq port */
     evtchn_port_t bufioreq_port;
-    /* OUT - sync ioreq pfn */
-    uint64_aligned_t ioreq_pfn;
-    /* OUT - buffered ioreq pfn */
-    uint64_aligned_t bufioreq_pfn;
+    /* OUT - sync ioreq gfn */
+    uint64_aligned_t ioreq_gfn;
+    /* OUT - buffered ioreq gfn */
+    uint64_aligned_t bufioreq_gfn;
 };
 
 /*
@@ -150,7 +150,7 @@ struct xen_dm_op_ioreq_server_range {
  *
  * The IOREQ Server will not be passed any emulation requests until it is
  * in the enabled state.
- * Note that the contents of the ioreq_pfn and bufioreq_fn (see
+ * Note that the contents of the ioreq_gfn and bufioreq_gfn (see
  * XEN_DMOP_get_ioreq_server_info) are not meaningful until the IOREQ Server
  * is in the enabled state.
  */
-- 
2.11.0


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

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

* [PATCH v2 REPOST 07/12] x86/hvm/ioreq: use bool rather than bool_t
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
                   ` (5 preceding siblings ...)
  2017-08-22 14:51 ` [PATCH v2 REPOST 06/12] x86/hvm/ioreq: rename .*pfn and .*gmfn to .*gfn Paul Durrant
@ 2017-08-22 14:51 ` Paul Durrant
  2017-08-24 16:11   ` Roger Pau Monné
  2017-08-22 14:51 ` [PATCH v2 REPOST 08/12] x86/hvm/ioreq: move is_default into struct hvm_ioreq_server Paul Durrant
                   ` (4 subsequent siblings)
  11 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Paul Durrant, Jan Beulich

This patch changes use of bool_t to bool in the IOREQ server code. It also
fixes an incorrect indentation in a continuation line.

This patch is purely cosmetic. No semantic or functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/dm.c            |   2 +-
 xen/arch/x86/hvm/hvm.c           |   2 +-
 xen/arch/x86/hvm/io.c            |   4 +-
 xen/arch/x86/hvm/ioreq.c         | 100 +++++++++++++++++++--------------------
 xen/include/asm-x86/hvm/domain.h |   6 +--
 xen/include/asm-x86/hvm/ioreq.h  |  14 +++---
 6 files changed, 64 insertions(+), 64 deletions(-)

diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index f7cb883fec..87ef4b6ca9 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -409,7 +409,7 @@ static int dm_op(const struct dmop_args *op_args)
         if ( data->pad[0] || data->pad[1] || data->pad[2] )
             break;
 
-        rc = hvm_create_ioreq_server(d, curr_d->domain_id, 0,
+        rc = hvm_create_ioreq_server(d, curr_d->domain_id, false,
                                      data->handle_bufioreq, &data->id);
         break;
     }
diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 58b4afa1d1..031d07baf0 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4361,7 +4361,7 @@ static int hvmop_get_param(
         {
             domid_t domid = d->arch.hvm_domain.params[HVM_PARAM_DM_DOMAIN];
 
-            rc = hvm_create_ioreq_server(d, domid, 1,
+            rc = hvm_create_ioreq_server(d, domid, true,
                                          HVM_IOREQSRV_BUFIOREQ_LEGACY, NULL);
             if ( rc != 0 && rc != -EEXIST )
                 goto out;
diff --git a/xen/arch/x86/hvm/io.c b/xen/arch/x86/hvm/io.c
index 214ab307c4..bfac993223 100644
--- a/xen/arch/x86/hvm/io.c
+++ b/xen/arch/x86/hvm/io.c
@@ -59,7 +59,7 @@ void send_timeoffset_req(unsigned long timeoff)
     if ( timeoff == 0 )
         return;
 
-    if ( hvm_broadcast_ioreq(&p, 1) != 0 )
+    if ( hvm_broadcast_ioreq(&p, true) != 0 )
         gprintk(XENLOG_ERR, "Unsuccessful timeoffset update\n");
 }
 
@@ -73,7 +73,7 @@ void send_invalidate_req(void)
         .data = ~0UL, /* flush all */
     };
 
-    if ( hvm_broadcast_ioreq(&p, 0) != 0 )
+    if ( hvm_broadcast_ioreq(&p, false) != 0 )
         gprintk(XENLOG_ERR, "Unsuccessful map-cache invalidate\n");
 }
 
diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index 3e753ba224..5e01e1a6d2 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -43,7 +43,7 @@ static ioreq_t *get_ioreq(struct hvm_ioreq_server *s, struct vcpu *v)
     return &p->vcpu_ioreq[v->vcpu_id];
 }
 
-bool_t hvm_io_pending(struct vcpu *v)
+bool hvm_io_pending(struct vcpu *v)
 {
     struct domain *d = v->domain;
     struct hvm_ioreq_server *s;
@@ -59,11 +59,11 @@ bool_t hvm_io_pending(struct vcpu *v)
                               list_entry )
         {
             if ( sv->vcpu == v && sv->pending )
-                return 1;
+                return true;
         }
     }
 
-    return 0;
+    return false;
 }
 
 static void hvm_io_assist(struct hvm_ioreq_vcpu *sv, uint64_t data)
@@ -82,10 +82,10 @@ static void hvm_io_assist(struct hvm_ioreq_vcpu *sv, uint64_t data)
     msix_write_completion(v);
     vcpu_end_shutdown_deferral(v);
 
-    sv->pending = 0;
+    sv->pending = false;
 }
 
-static bool_t hvm_wait_for_io(struct hvm_ioreq_vcpu *sv, ioreq_t *p)
+static bool hvm_wait_for_io(struct hvm_ioreq_vcpu *sv, ioreq_t *p)
 {
     while ( sv->pending )
     {
@@ -112,16 +112,16 @@ static bool_t hvm_wait_for_io(struct hvm_ioreq_vcpu *sv, ioreq_t *p)
             break;
         default:
             gdprintk(XENLOG_ERR, "Weird HVM iorequest state %u\n", state);
-            sv->pending = 0;
+            sv->pending = false;
             domain_crash(sv->vcpu->domain);
-            return 0; /* bail */
+            return false; /* bail */
         }
     }
 
-    return 1;
+    return true;
 }
 
-bool_t handle_hvm_io_completion(struct vcpu *v)
+bool handle_hvm_io_completion(struct vcpu *v)
 {
     struct domain *d = v->domain;
     struct hvm_vcpu_io *vio = &v->arch.hvm_vcpu.hvm_io;
@@ -141,7 +141,7 @@ bool_t handle_hvm_io_completion(struct vcpu *v)
             if ( sv->vcpu == v && sv->pending )
             {
                 if ( !hvm_wait_for_io(sv, get_ioreq(s, v)) )
-                    return 0;
+                    return false;
 
                 break;
             }
@@ -178,7 +178,7 @@ bool_t handle_hvm_io_completion(struct vcpu *v)
         break;
     }
 
-    return 1;
+    return true;
 }
 
 static int hvm_alloc_ioreq_gfn(struct domain *d, unsigned long *gfn)
@@ -208,7 +208,7 @@ static void hvm_free_ioreq_gfn(struct domain *d, unsigned long gfn)
         set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
 }
 
-static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t buf)
+static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool buf)
 {
     struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
 
@@ -216,7 +216,7 @@ static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool_t buf)
 }
 
 static int hvm_map_ioreq_page(
-    struct hvm_ioreq_server *s, bool_t buf, unsigned long gfn)
+    struct hvm_ioreq_server *s, bool buf, unsigned long gfn)
 {
     struct domain *d = s->domain;
     struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
@@ -240,10 +240,10 @@ static int hvm_map_ioreq_page(
     return 0;
 }
 
-bool_t is_ioreq_server_page(struct domain *d, const struct page_info *page)
+bool is_ioreq_server_page(struct domain *d, const struct page_info *page)
 {
     const struct hvm_ioreq_server *s;
-    bool_t found = 0;
+    bool found = false;
 
     spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
 
@@ -254,7 +254,7 @@ bool_t is_ioreq_server_page(struct domain *d, const struct page_info *page)
         if ( (s->ioreq.va && s->ioreq.page == page) ||
              (s->bufioreq.va && s->bufioreq.page == page) )
         {
-            found = 1;
+            found = true;
             break;
         }
     }
@@ -302,7 +302,7 @@ static void hvm_update_ioreq_evtchn(struct hvm_ioreq_server *s,
 }
 
 static int hvm_ioreq_server_add_vcpu(struct hvm_ioreq_server *s,
-                                     bool_t is_default, struct vcpu *v)
+                                     bool is_default, struct vcpu *v)
 {
     struct hvm_ioreq_vcpu *sv;
     int rc;
@@ -417,22 +417,22 @@ static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
 {
     int rc;
 
-    rc = hvm_map_ioreq_page(s, 0, ioreq_gfn);
+    rc = hvm_map_ioreq_page(s, false, ioreq_gfn);
     if ( rc )
         return rc;
 
     if ( bufioreq_gfn != gfn_x(INVALID_GFN) )
-        rc = hvm_map_ioreq_page(s, 1, bufioreq_gfn);
+        rc = hvm_map_ioreq_page(s, true, bufioreq_gfn);
 
     if ( rc )
-        hvm_unmap_ioreq_page(s, 0);
+        hvm_unmap_ioreq_page(s, false);
 
     return rc;
 }
 
 static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
-                                        bool_t is_default,
-                                        bool_t handle_bufioreq)
+                                        bool is_default,
+                                        bool handle_bufioreq)
 {
     struct domain *d = s->domain;
     unsigned long ioreq_gfn = gfn_x(INVALID_GFN);
@@ -469,15 +469,15 @@ static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
 }
 
 static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s,
-                                         bool_t is_default)
+                                         bool is_default)
 {
     struct domain *d = s->domain;
-    bool_t handle_bufioreq = ( s->bufioreq.va != NULL );
+    bool handle_bufioreq = !!s->bufioreq.va;
 
     if ( handle_bufioreq )
-        hvm_unmap_ioreq_page(s, 1);
+        hvm_unmap_ioreq_page(s, true);
 
-    hvm_unmap_ioreq_page(s, 0);
+    hvm_unmap_ioreq_page(s, false);
 
     if ( !is_default )
     {
@@ -489,7 +489,7 @@ static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s,
 }
 
 static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s,
-                                            bool_t is_default)
+                                            bool is_default)
 {
     unsigned int i;
 
@@ -501,7 +501,7 @@ static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s,
 }
 
 static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s,
-                                            bool_t is_default)
+                                            bool is_default)
 {
     unsigned int i;
     int rc;
@@ -537,17 +537,17 @@ static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s,
     return 0;
 
  fail:
-    hvm_ioreq_server_free_rangesets(s, 0);
+    hvm_ioreq_server_free_rangesets(s, false);
 
     return rc;
 }
 
 static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s,
-                                    bool_t is_default)
+                                    bool is_default)
 {
     struct domain *d = s->domain;
     struct hvm_ioreq_vcpu *sv;
-    bool_t handle_bufioreq = ( s->bufioreq.va != NULL );
+    bool handle_bufioreq = !!s->bufioreq.va;
 
     spin_lock(&s->lock);
 
@@ -562,7 +562,7 @@ static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s,
             hvm_remove_ioreq_gfn(d, &s->bufioreq);
     }
 
-    s->enabled = 1;
+    s->enabled = true;
 
     list_for_each_entry ( sv,
                           &s->ioreq_vcpu_list,
@@ -574,10 +574,10 @@ static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s,
 }
 
 static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s,
-                                    bool_t is_default)
+                                     bool is_default)
 {
     struct domain *d = s->domain;
-    bool_t handle_bufioreq = ( s->bufioreq.va != NULL );
+    bool handle_bufioreq = !!s->bufioreq.va;
 
     spin_lock(&s->lock);
 
@@ -592,7 +592,7 @@ static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s,
         hvm_add_ioreq_gfn(d, &s->ioreq);
     }
 
-    s->enabled = 0;
+    s->enabled = false;
 
  done:
     spin_unlock(&s->lock);
@@ -600,7 +600,7 @@ static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s,
 
 static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
                                  struct domain *d, domid_t domid,
-                                 bool_t is_default, int bufioreq_handling,
+                                 bool is_default, int bufioreq_handling,
                                  ioservid_t id)
 {
     struct vcpu *v;
@@ -619,7 +619,7 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
         return rc;
 
     if ( bufioreq_handling == HVM_IOREQSRV_BUFIOREQ_ATOMIC )
-        s->bufioreq_atomic = 1;
+        s->bufioreq_atomic = true;
 
     rc = hvm_ioreq_server_setup_pages(
              s, is_default, bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF);
@@ -646,7 +646,7 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
 }
 
 static void hvm_ioreq_server_deinit(struct hvm_ioreq_server *s,
-                                    bool_t is_default)
+                                    bool is_default)
 {
     ASSERT(!s->enabled);
     hvm_ioreq_server_remove_all_vcpus(s);
@@ -681,7 +681,7 @@ static ioservid_t next_ioservid(struct domain *d)
 }
 
 int hvm_create_ioreq_server(struct domain *d, domid_t domid,
-                            bool_t is_default, int bufioreq_handling,
+                            bool is_default, int bufioreq_handling,
                             ioservid_t *id)
 {
     struct hvm_ioreq_server *s;
@@ -713,7 +713,7 @@ int hvm_create_ioreq_server(struct domain *d, domid_t domid,
     if ( is_default )
     {
         d->arch.hvm_domain.default_ioreq_server = s;
-        hvm_ioreq_server_enable(s, 1);
+        hvm_ioreq_server_enable(s, true);
     }
 
     if ( id )
@@ -756,11 +756,11 @@ int hvm_destroy_ioreq_server(struct domain *d, ioservid_t id)
 
         p2m_set_ioreq_server(d, 0, s);
 
-        hvm_ioreq_server_disable(s, 0);
+        hvm_ioreq_server_disable(s, false);
 
         list_del(&s->list_entry);
 
-        hvm_ioreq_server_deinit(s, 0);
+        hvm_ioreq_server_deinit(s, false);
 
         domain_unpause(d);
 
@@ -968,7 +968,7 @@ int hvm_map_mem_type_to_ioreq_server(struct domain *d, ioservid_t id,
 }
 
 int hvm_set_ioreq_server_state(struct domain *d, ioservid_t id,
-                               bool_t enabled)
+                               bool enabled)
 {
     struct list_head *entry;
     int rc;
@@ -992,9 +992,9 @@ int hvm_set_ioreq_server_state(struct domain *d, ioservid_t id,
         domain_pause(d);
 
         if ( enabled )
-            hvm_ioreq_server_enable(s, 0);
+            hvm_ioreq_server_enable(s, false);
         else
-            hvm_ioreq_server_disable(s, 0);
+            hvm_ioreq_server_disable(s, false);
 
         domain_unpause(d);
 
@@ -1017,7 +1017,7 @@ int hvm_all_ioreq_servers_add_vcpu(struct domain *d, struct vcpu *v)
                           &d->arch.hvm_domain.ioreq_server.list,
                           list_entry )
     {
-        bool_t is_default = (s == d->arch.hvm_domain.default_ioreq_server);
+        bool is_default = (s == d->arch.hvm_domain.default_ioreq_server);
 
         rc = hvm_ioreq_server_add_vcpu(s, is_default, v);
         if ( rc )
@@ -1066,7 +1066,7 @@ void hvm_destroy_all_ioreq_servers(struct domain *d)
                                &d->arch.hvm_domain.ioreq_server.list,
                                list_entry )
     {
-        bool_t is_default = (s == d->arch.hvm_domain.default_ioreq_server);
+        bool is_default = (s == d->arch.hvm_domain.default_ioreq_server);
 
         hvm_ioreq_server_disable(s, is_default);
 
@@ -1349,7 +1349,7 @@ static int hvm_send_buffered_ioreq(struct hvm_ioreq_server *s, ioreq_t *p)
 }
 
 int hvm_send_ioreq(struct hvm_ioreq_server *s, ioreq_t *proto_p,
-                   bool_t buffered)
+                   bool buffered)
 {
     struct vcpu *curr = current;
     struct domain *d = curr->domain;
@@ -1400,7 +1400,7 @@ int hvm_send_ioreq(struct hvm_ioreq_server *s, ioreq_t *proto_p,
             p->state = STATE_IOREQ_READY;
             notify_via_xen_event_channel(d, port);
 
-            sv->pending = 1;
+            sv->pending = true;
             return X86EMUL_RETRY;
         }
     }
@@ -1408,7 +1408,7 @@ int hvm_send_ioreq(struct hvm_ioreq_server *s, ioreq_t *proto_p,
     return X86EMUL_UNHANDLEABLE;
 }
 
-unsigned int hvm_broadcast_ioreq(ioreq_t *p, bool_t buffered)
+unsigned int hvm_broadcast_ioreq(ioreq_t *p, bool buffered)
 {
     struct domain *d = current->domain;
     struct hvm_ioreq_server *s;
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index ce536f75ef..7f128c05ff 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -45,7 +45,7 @@ struct hvm_ioreq_vcpu {
     struct list_head list_entry;
     struct vcpu      *vcpu;
     evtchn_port_t    ioreq_evtchn;
-    bool_t           pending;
+    bool             pending;
 };
 
 #define NR_IO_RANGE_TYPES (XEN_DMOP_IO_RANGE_PCI + 1)
@@ -69,8 +69,8 @@ struct hvm_ioreq_server {
     spinlock_t             bufioreq_lock;
     evtchn_port_t          bufioreq_evtchn;
     struct rangeset        *range[NR_IO_RANGE_TYPES];
-    bool_t                 enabled;
-    bool_t                 bufioreq_atomic;
+    bool                   enabled;
+    bool                   bufioreq_atomic;
 };
 
 /*
diff --git a/xen/include/asm-x86/hvm/ioreq.h b/xen/include/asm-x86/hvm/ioreq.h
index 43fbe115dc..1829fcf43e 100644
--- a/xen/include/asm-x86/hvm/ioreq.h
+++ b/xen/include/asm-x86/hvm/ioreq.h
@@ -19,12 +19,12 @@
 #ifndef __ASM_X86_HVM_IOREQ_H__
 #define __ASM_X86_HVM_IOREQ_H__
 
-bool_t hvm_io_pending(struct vcpu *v);
-bool_t handle_hvm_io_completion(struct vcpu *v);
-bool_t is_ioreq_server_page(struct domain *d, const struct page_info *page);
+bool hvm_io_pending(struct vcpu *v);
+bool handle_hvm_io_completion(struct vcpu *v);
+bool is_ioreq_server_page(struct domain *d, const struct page_info *page);
 
 int hvm_create_ioreq_server(struct domain *d, domid_t domid,
-                            bool_t is_default, int bufioreq_handling,
+                            bool is_default, int bufioreq_handling,
                             ioservid_t *id);
 int hvm_destroy_ioreq_server(struct domain *d, ioservid_t id);
 int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
@@ -40,7 +40,7 @@ int hvm_unmap_io_range_from_ioreq_server(struct domain *d, ioservid_t id,
 int hvm_map_mem_type_to_ioreq_server(struct domain *d, ioservid_t id,
                                      uint32_t type, uint32_t flags);
 int hvm_set_ioreq_server_state(struct domain *d, ioservid_t id,
-                               bool_t enabled);
+                               bool enabled);
 
 int hvm_all_ioreq_servers_add_vcpu(struct domain *d, struct vcpu *v);
 void hvm_all_ioreq_servers_remove_vcpu(struct domain *d, struct vcpu *v);
@@ -51,8 +51,8 @@ int hvm_set_dm_domain(struct domain *d, domid_t domid);
 struct hvm_ioreq_server *hvm_select_ioreq_server(struct domain *d,
                                                  ioreq_t *p);
 int hvm_send_ioreq(struct hvm_ioreq_server *s, ioreq_t *proto_p,
-                   bool_t buffered);
-unsigned int hvm_broadcast_ioreq(ioreq_t *p, bool_t buffered);
+                   bool buffered);
+unsigned int hvm_broadcast_ioreq(ioreq_t *p, bool buffered);
 
 void hvm_ioreq_init(struct domain *d);
 
-- 
2.11.0


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

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

* [PATCH v2 REPOST 08/12] x86/hvm/ioreq: move is_default into struct hvm_ioreq_server
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
                   ` (6 preceding siblings ...)
  2017-08-22 14:51 ` [PATCH v2 REPOST 07/12] x86/hvm/ioreq: use bool rather than bool_t Paul Durrant
@ 2017-08-22 14:51 ` Paul Durrant
  2017-08-24 16:21   ` Roger Pau Monné
  2017-08-22 14:51 ` [PATCH v2 REPOST 09/12] x86/hvm/ioreq: simplify code and use consistent naming Paul Durrant
                   ` (3 subsequent siblings)
  11 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Paul Durrant, Jan Beulich

Legacy emulators use the 'default' IOREQ server which has slightly
different semantics than other, explicitly created, IOREQ servers.

Because of this, most of the initialization and teardown code needs to
know whether the server is default or not. This is currently achieved
by passing an is_default boolean argument to the functions in question,
whereas this argument could be avoided by adding a field to the
hvm_ioreq_server structure which is also passed as an argument to all
the relevant functions.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/ioreq.c         | 80 ++++++++++++++++++----------------------
 xen/include/asm-x86/hvm/domain.h |  1 +
 2 files changed, 36 insertions(+), 45 deletions(-)

diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index 5e01e1a6d2..5737082238 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -302,7 +302,7 @@ static void hvm_update_ioreq_evtchn(struct hvm_ioreq_server *s,
 }
 
 static int hvm_ioreq_server_add_vcpu(struct hvm_ioreq_server *s,
-                                     bool is_default, struct vcpu *v)
+                                     struct vcpu *v)
 {
     struct hvm_ioreq_vcpu *sv;
     int rc;
@@ -331,7 +331,7 @@ static int hvm_ioreq_server_add_vcpu(struct hvm_ioreq_server *s,
             goto fail3;
 
         s->bufioreq_evtchn = rc;
-        if ( is_default )
+        if ( s->is_default )
             d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_EVTCHN] =
                 s->bufioreq_evtchn;
     }
@@ -431,7 +431,6 @@ static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
 }
 
 static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
-                                        bool is_default,
                                         bool handle_bufioreq)
 {
     struct domain *d = s->domain;
@@ -439,7 +438,7 @@ static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
     unsigned long bufioreq_gfn = gfn_x(INVALID_GFN);
     int rc;
 
-    if ( is_default )
+    if ( s->is_default )
     {
         /*
          * The default ioreq server must handle buffered ioreqs, for
@@ -468,8 +467,7 @@ static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
     return rc;
 }
 
-static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s,
-                                         bool is_default)
+static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s)
 {
     struct domain *d = s->domain;
     bool handle_bufioreq = !!s->bufioreq.va;
@@ -479,7 +477,7 @@ static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s,
 
     hvm_unmap_ioreq_page(s, false);
 
-    if ( !is_default )
+    if ( !s->is_default )
     {
         if ( handle_bufioreq )
             hvm_free_ioreq_gfn(d, s->bufioreq.gfn);
@@ -488,25 +486,23 @@ static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s,
     }
 }
 
-static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s,
-                                            bool is_default)
+static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s)
 {
     unsigned int i;
 
-    if ( is_default )
+    if ( s->is_default )
         return;
 
     for ( i = 0; i < NR_IO_RANGE_TYPES; i++ )
         rangeset_destroy(s->range[i]);
 }
 
-static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s,
-                                            bool is_default)
+static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s)
 {
     unsigned int i;
     int rc;
 
-    if ( is_default )
+    if ( s->is_default )
         goto done;
 
     for ( i = 0; i < NR_IO_RANGE_TYPES; i++ )
@@ -537,13 +533,12 @@ static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s,
     return 0;
 
  fail:
-    hvm_ioreq_server_free_rangesets(s, false);
+    hvm_ioreq_server_free_rangesets(s);
 
     return rc;
 }
 
-static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s,
-                                    bool is_default)
+static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s)
 {
     struct domain *d = s->domain;
     struct hvm_ioreq_vcpu *sv;
@@ -554,7 +549,7 @@ static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s,
     if ( s->enabled )
         goto done;
 
-    if ( !is_default )
+    if ( !s->is_default )
     {
         hvm_remove_ioreq_gfn(d, &s->ioreq);
 
@@ -573,8 +568,7 @@ static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s,
     spin_unlock(&s->lock);
 }
 
-static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s,
-                                     bool is_default)
+static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s)
 {
     struct domain *d = s->domain;
     bool handle_bufioreq = !!s->bufioreq.va;
@@ -584,7 +578,7 @@ static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s,
     if ( !s->enabled )
         goto done;
 
-    if ( !is_default )
+    if ( !s->is_default )
     {
         if ( handle_bufioreq )
             hvm_add_ioreq_gfn(d, &s->bufioreq);
@@ -600,8 +594,7 @@ static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s,
 
 static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
                                  struct domain *d, domid_t domid,
-                                 bool is_default, int bufioreq_handling,
-                                 ioservid_t id)
+                                 int bufioreq_handling, ioservid_t id)
 {
     struct vcpu *v;
     int rc;
@@ -614,7 +607,7 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
     INIT_LIST_HEAD(&s->ioreq_vcpu_list);
     spin_lock_init(&s->bufioreq_lock);
 
-    rc = hvm_ioreq_server_alloc_rangesets(s, is_default);
+    rc = hvm_ioreq_server_alloc_rangesets(s);
     if ( rc )
         return rc;
 
@@ -622,13 +615,13 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
         s->bufioreq_atomic = true;
 
     rc = hvm_ioreq_server_setup_pages(
-             s, is_default, bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF);
+             s, bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF);
     if ( rc )
         goto fail_map;
 
     for_each_vcpu ( d, v )
     {
-        rc = hvm_ioreq_server_add_vcpu(s, is_default, v);
+        rc = hvm_ioreq_server_add_vcpu(s, v);
         if ( rc )
             goto fail_add;
     }
@@ -637,21 +630,20 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
 
  fail_add:
     hvm_ioreq_server_remove_all_vcpus(s);
-    hvm_ioreq_server_unmap_pages(s, is_default);
+    hvm_ioreq_server_unmap_pages(s);
 
  fail_map:
-    hvm_ioreq_server_free_rangesets(s, is_default);
+    hvm_ioreq_server_free_rangesets(s);
 
     return rc;
 }
 
-static void hvm_ioreq_server_deinit(struct hvm_ioreq_server *s,
-                                    bool is_default)
+static void hvm_ioreq_server_deinit(struct hvm_ioreq_server *s)
 {
     ASSERT(!s->enabled);
     hvm_ioreq_server_remove_all_vcpus(s);
-    hvm_ioreq_server_unmap_pages(s, is_default);
-    hvm_ioreq_server_free_rangesets(s, is_default);
+    hvm_ioreq_server_unmap_pages(s);
+    hvm_ioreq_server_free_rangesets(s);
 }
 
 static ioservid_t next_ioservid(struct domain *d)
@@ -695,6 +687,8 @@ int hvm_create_ioreq_server(struct domain *d, domid_t domid,
     if ( !s )
         goto fail1;
 
+    s->is_default = is_default;
+
     domain_pause(d);
     spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
 
@@ -702,7 +696,7 @@ int hvm_create_ioreq_server(struct domain *d, domid_t domid,
     if ( is_default && d->arch.hvm_domain.default_ioreq_server != NULL )
         goto fail2;
 
-    rc = hvm_ioreq_server_init(s, d, domid, is_default, bufioreq_handling,
+    rc = hvm_ioreq_server_init(s, d, domid, bufioreq_handling,
                                next_ioservid(d));
     if ( rc )
         goto fail3;
@@ -713,7 +707,7 @@ int hvm_create_ioreq_server(struct domain *d, domid_t domid,
     if ( is_default )
     {
         d->arch.hvm_domain.default_ioreq_server = s;
-        hvm_ioreq_server_enable(s, true);
+        hvm_ioreq_server_enable(s);
     }
 
     if ( id )
@@ -756,11 +750,11 @@ int hvm_destroy_ioreq_server(struct domain *d, ioservid_t id)
 
         p2m_set_ioreq_server(d, 0, s);
 
-        hvm_ioreq_server_disable(s, false);
+        hvm_ioreq_server_disable(s);
 
         list_del(&s->list_entry);
 
-        hvm_ioreq_server_deinit(s, false);
+        hvm_ioreq_server_deinit(s);
 
         domain_unpause(d);
 
@@ -992,9 +986,9 @@ int hvm_set_ioreq_server_state(struct domain *d, ioservid_t id,
         domain_pause(d);
 
         if ( enabled )
-            hvm_ioreq_server_enable(s, false);
+            hvm_ioreq_server_enable(s);
         else
-            hvm_ioreq_server_disable(s, false);
+            hvm_ioreq_server_disable(s);
 
         domain_unpause(d);
 
@@ -1017,9 +1011,7 @@ int hvm_all_ioreq_servers_add_vcpu(struct domain *d, struct vcpu *v)
                           &d->arch.hvm_domain.ioreq_server.list,
                           list_entry )
     {
-        bool is_default = (s == d->arch.hvm_domain.default_ioreq_server);
-
-        rc = hvm_ioreq_server_add_vcpu(s, is_default, v);
+        rc = hvm_ioreq_server_add_vcpu(s, v);
         if ( rc )
             goto fail;
     }
@@ -1066,16 +1058,14 @@ void hvm_destroy_all_ioreq_servers(struct domain *d)
                                &d->arch.hvm_domain.ioreq_server.list,
                                list_entry )
     {
-        bool is_default = (s == d->arch.hvm_domain.default_ioreq_server);
-
-        hvm_ioreq_server_disable(s, is_default);
+        hvm_ioreq_server_disable(s);
 
-        if ( is_default )
+        if ( s->is_default )
             d->arch.hvm_domain.default_ioreq_server = NULL;
 
         list_del(&s->list_entry);
 
-        hvm_ioreq_server_deinit(s, is_default);
+        hvm_ioreq_server_deinit(s);
 
         xfree(s);
     }
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 7f128c05ff..16344d173b 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -71,6 +71,7 @@ struct hvm_ioreq_server {
     struct rangeset        *range[NR_IO_RANGE_TYPES];
     bool                   enabled;
     bool                   bufioreq_atomic;
+    bool                   is_default;
 };
 
 /*
-- 
2.11.0


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

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

* [PATCH v2 REPOST 09/12] x86/hvm/ioreq: simplify code and use consistent naming
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
                   ` (7 preceding siblings ...)
  2017-08-22 14:51 ` [PATCH v2 REPOST 08/12] x86/hvm/ioreq: move is_default into struct hvm_ioreq_server Paul Durrant
@ 2017-08-22 14:51 ` Paul Durrant
  2017-08-24 17:02   ` Roger Pau Monné
  2017-08-22 14:51 ` [PATCH v2 REPOST 10/12] x86/hvm/ioreq: use gfn_t in struct hvm_ioreq_page Paul Durrant
                   ` (2 subsequent siblings)
  11 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Paul Durrant, Jan Beulich

This patch re-works much of the IOREQ server initialization and teardown
code:

- The hvm_map/unmap_ioreq_gfn() functions are expanded to call through
  to hvm_alloc/free_ioreq_gfn() rather than expecting them to be called
  separately by outer functions.
- Several functions now test the validity of the hvm_ioreq_page gfn value
  to determine whether they need to act. This means can be safely called
  for the bufioreq page even when it is not used.
- hvm_add/remove_ioreq_gfn() simply return in the case of the default
  IOREQ server so callers no longer need to test before calling.
- hvm_ioreq_server_setup_pages() is renamed to hvm_ioreq_server_map_pages()
  to mirror the existing hvm_ioreq_server_unmap_pages().

All of this significantly shortens the code.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
---
 xen/arch/x86/hvm/ioreq.c | 181 ++++++++++++++++++-----------------------------
 1 file changed, 69 insertions(+), 112 deletions(-)

diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index 5737082238..edfb394c59 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -181,63 +181,76 @@ bool handle_hvm_io_completion(struct vcpu *v)
     return true;
 }
 
-static int hvm_alloc_ioreq_gfn(struct domain *d, unsigned long *gfn)
+static unsigned long hvm_alloc_ioreq_gfn(struct hvm_ioreq_server *s)
 {
+    struct domain *d = s->domain;
     unsigned int i;
-    int rc;
 
-    rc = -ENOMEM;
+    ASSERT(!s->is_default);
+
     for ( i = 0; i < sizeof(d->arch.hvm_domain.ioreq_gfn.mask) * 8; i++ )
     {
         if ( test_and_clear_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask) )
         {
-            *gfn = d->arch.hvm_domain.ioreq_gfn.base + i;
-            rc = 0;
-            break;
+            return d->arch.hvm_domain.ioreq_gfn.base + i;
         }
     }
 
-    return rc;
+    return gfn_x(INVALID_GFN);
 }
 
-static void hvm_free_ioreq_gfn(struct domain *d, unsigned long gfn)
+static void hvm_free_ioreq_gfn(struct hvm_ioreq_server *s,
+                               unsigned long gfn)
 {
+    struct domain *d = s->domain;
     unsigned int i = gfn - d->arch.hvm_domain.ioreq_gfn.base;
 
-    if ( gfn != gfn_x(INVALID_GFN) )
-        set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
+    ASSERT(!s->is_default);
+
+    set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
 }
 
-static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool buf)
+static void hvm_unmap_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
 {
     struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
 
+    if ( iorp->gfn == gfn_x(INVALID_GFN) )
+        return;
+
     destroy_ring_for_helper(&iorp->va, iorp->page);
+    iorp->page = NULL;
+
+    if ( !s->is_default )
+        hvm_free_ioreq_gfn(s, iorp->gfn);
+
+    iorp->gfn = gfn_x(INVALID_GFN);
 }
 
-static int hvm_map_ioreq_page(
-    struct hvm_ioreq_server *s, bool buf, unsigned long gfn)
+static int hvm_map_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
 {
     struct domain *d = s->domain;
     struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
-    struct page_info *page;
-    void *va;
     int rc;
 
-    if ( (rc = prepare_ring_for_helper(d, gfn, &page, &va)) )
-        return rc;
-
-    if ( (iorp->va != NULL) || d->is_dying )
-    {
-        destroy_ring_for_helper(&va, page);
+    if ( d->is_dying )
         return -EINVAL;
-    }
 
-    iorp->va = va;
-    iorp->page = page;
-    iorp->gfn = gfn;
+    if ( s->is_default )
+        iorp->gfn = buf ?
+                    d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN] :
+                    d->arch.hvm_domain.params[HVM_PARAM_IOREQ_PFN];
+    else
+        iorp->gfn = hvm_alloc_ioreq_gfn(s);
+
+    if ( iorp->gfn == gfn_x(INVALID_GFN) )
+        return -ENOMEM;
 
-    return 0;
+    rc = prepare_ring_for_helper(d, iorp->gfn, &iorp->page, &iorp->va);
+
+    if ( rc )
+        hvm_unmap_ioreq_gfn(s, buf);
+
+    return rc;
 }
 
 bool is_ioreq_server_page(struct domain *d, const struct page_info *page)
@@ -251,8 +264,7 @@ bool is_ioreq_server_page(struct domain *d, const struct page_info *page)
                           &d->arch.hvm_domain.ioreq_server.list,
                           list_entry )
     {
-        if ( (s->ioreq.va && s->ioreq.page == page) ||
-             (s->bufioreq.va && s->bufioreq.page == page) )
+        if ( (s->ioreq.page == page) || (s->bufioreq.page == page) )
         {
             found = true;
             break;
@@ -264,20 +276,30 @@ bool is_ioreq_server_page(struct domain *d, const struct page_info *page)
     return found;
 }
 
-static void hvm_remove_ioreq_gfn(
-    struct domain *d, struct hvm_ioreq_page *iorp)
+static void hvm_remove_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
+
 {
+    struct domain *d = s->domain;
+    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
+
+    if ( s->is_default || iorp->gfn == gfn_x(INVALID_GFN) )
+        return;
+
     if ( guest_physmap_remove_page(d, _gfn(iorp->gfn),
                                    _mfn(page_to_mfn(iorp->page)), 0) )
         domain_crash(d);
     clear_page(iorp->va);
 }
 
-static int hvm_add_ioreq_gfn(
-    struct domain *d, struct hvm_ioreq_page *iorp)
+static int hvm_add_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
 {
+    struct domain *d = s->domain;
+    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
     int rc;
 
+    if ( s->is_default || iorp->gfn == gfn_x(INVALID_GFN) )
+        return 0;
+
     clear_page(iorp->va);
 
     rc = guest_physmap_add_page(d, _gfn(iorp->gfn),
@@ -412,78 +434,25 @@ static void hvm_ioreq_server_remove_all_vcpus(struct hvm_ioreq_server *s)
 }
 
 static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
-                                      unsigned long ioreq_gfn,
-                                      unsigned long bufioreq_gfn)
-{
-    int rc;
-
-    rc = hvm_map_ioreq_page(s, false, ioreq_gfn);
-    if ( rc )
-        return rc;
-
-    if ( bufioreq_gfn != gfn_x(INVALID_GFN) )
-        rc = hvm_map_ioreq_page(s, true, bufioreq_gfn);
-
-    if ( rc )
-        hvm_unmap_ioreq_page(s, false);
-
-    return rc;
-}
-
-static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
-                                        bool handle_bufioreq)
+                                      bool handle_bufioreq)
 {
-    struct domain *d = s->domain;
-    unsigned long ioreq_gfn = gfn_x(INVALID_GFN);
-    unsigned long bufioreq_gfn = gfn_x(INVALID_GFN);
-    int rc;
-
-    if ( s->is_default )
-    {
-        /*
-         * The default ioreq server must handle buffered ioreqs, for
-         * backwards compatibility.
-         */
-        ASSERT(handle_bufioreq);
-        return hvm_ioreq_server_map_pages(s,
-                   d->arch.hvm_domain.params[HVM_PARAM_IOREQ_PFN],
-                   d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN]);
-    }
+    int rc = -ENOMEM;
 
-    rc = hvm_alloc_ioreq_gfn(d, &ioreq_gfn);
+    rc = hvm_map_ioreq_gfn(s, false);
 
     if ( !rc && handle_bufioreq )
-        rc = hvm_alloc_ioreq_gfn(d, &bufioreq_gfn);
-
-    if ( !rc )
-        rc = hvm_ioreq_server_map_pages(s, ioreq_gfn, bufioreq_gfn);
+        rc = hvm_map_ioreq_gfn(s, true);
 
     if ( rc )
-    {
-        hvm_free_ioreq_gfn(d, ioreq_gfn);
-        hvm_free_ioreq_gfn(d, bufioreq_gfn);
-    }
+        hvm_unmap_ioreq_gfn(s, false);
 
     return rc;
 }
 
 static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s)
 {
-    struct domain *d = s->domain;
-    bool handle_bufioreq = !!s->bufioreq.va;
-
-    if ( handle_bufioreq )
-        hvm_unmap_ioreq_page(s, true);
-
-    hvm_unmap_ioreq_page(s, false);
-
-    if ( !s->is_default )
-    {
-        if ( handle_bufioreq )
-            hvm_free_ioreq_gfn(d, s->bufioreq.gfn);
-
-        hvm_free_ioreq_gfn(d, s->ioreq.gfn);
-    }
+    hvm_unmap_ioreq_gfn(s, true);
+    hvm_unmap_ioreq_gfn(s, false);
 }
 
 static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s)
@@ -540,22 +509,15 @@ static int hvm_ioreq_server_alloc_rangesets(struct hvm_ioreq_server *s)
 
 static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s)
 {
-    struct domain *d = s->domain;
     struct hvm_ioreq_vcpu *sv;
-    bool handle_bufioreq = !!s->bufioreq.va;
 
     spin_lock(&s->lock);
 
     if ( s->enabled )
         goto done;
 
-    if ( !s->is_default )
-    {
-        hvm_remove_ioreq_gfn(d, &s->ioreq);
-
-        if ( handle_bufioreq )
-            hvm_remove_ioreq_gfn(d, &s->bufioreq);
-    }
+    hvm_remove_ioreq_gfn(s, false);
+    hvm_remove_ioreq_gfn(s, true);
 
     s->enabled = true;
 
@@ -570,21 +532,13 @@ static void hvm_ioreq_server_enable(struct hvm_ioreq_server *s)
 
 static void hvm_ioreq_server_disable(struct hvm_ioreq_server *s)
 {
-    struct domain *d = s->domain;
-    bool handle_bufioreq = !!s->bufioreq.va;
-
     spin_lock(&s->lock);
 
     if ( !s->enabled )
         goto done;
 
-    if ( !s->is_default )
-    {
-        if ( handle_bufioreq )
-            hvm_add_ioreq_gfn(d, &s->bufioreq);
-
-        hvm_add_ioreq_gfn(d, &s->ioreq);
-    }
+    hvm_add_ioreq_gfn(s, true);
+    hvm_add_ioreq_gfn(s, false);
 
     s->enabled = false;
 
@@ -607,6 +561,9 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
     INIT_LIST_HEAD(&s->ioreq_vcpu_list);
     spin_lock_init(&s->bufioreq_lock);
 
+    s->ioreq.gfn = gfn_x(INVALID_GFN);
+    s->bufioreq.gfn = gfn_x(INVALID_GFN);
+
     rc = hvm_ioreq_server_alloc_rangesets(s);
     if ( rc )
         return rc;
@@ -614,7 +571,7 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
     if ( bufioreq_handling == HVM_IOREQSRV_BUFIOREQ_ATOMIC )
         s->bufioreq_atomic = true;
 
-    rc = hvm_ioreq_server_setup_pages(
+    rc = hvm_ioreq_server_map_pages(
              s, bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF);
     if ( rc )
         goto fail_map;
-- 
2.11.0


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

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

* [PATCH v2 REPOST 10/12] x86/hvm/ioreq: use gfn_t in struct hvm_ioreq_page
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
                   ` (8 preceding siblings ...)
  2017-08-22 14:51 ` [PATCH v2 REPOST 09/12] x86/hvm/ioreq: simplify code and use consistent naming Paul Durrant
@ 2017-08-22 14:51 ` Paul Durrant
  2017-08-24 17:05   ` Roger Pau Monné
  2017-08-22 14:51 ` [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted Paul Durrant
  2017-08-22 14:51 ` [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type Paul Durrant
  11 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:51 UTC (permalink / raw)
  To: xen-devel; +Cc: Andrew Cooper, Paul Durrant, Jan Beulich

This patch adjusts the IOREQ server code to use type-safe gfn_t values
where possible. No functional change.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
---
 xen/arch/x86/hvm/ioreq.c         | 42 ++++++++++++++++++++--------------------
 xen/include/asm-x86/hvm/domain.h |  2 +-
 2 files changed, 22 insertions(+), 22 deletions(-)

diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index edfb394c59..3a9aaf1f5d 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -181,7 +181,7 @@ bool handle_hvm_io_completion(struct vcpu *v)
     return true;
 }
 
-static unsigned long hvm_alloc_ioreq_gfn(struct hvm_ioreq_server *s)
+static gfn_t hvm_alloc_ioreq_gfn(struct hvm_ioreq_server *s)
 {
     struct domain *d = s->domain;
     unsigned int i;
@@ -192,18 +192,17 @@ static unsigned long hvm_alloc_ioreq_gfn(struct hvm_ioreq_server *s)
     {
         if ( test_and_clear_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask) )
         {
-            return d->arch.hvm_domain.ioreq_gfn.base + i;
+            return _gfn(d->arch.hvm_domain.ioreq_gfn.base + i);
         }
     }
 
-    return gfn_x(INVALID_GFN);
+    return INVALID_GFN;
 }
 
-static void hvm_free_ioreq_gfn(struct hvm_ioreq_server *s,
-                               unsigned long gfn)
+static void hvm_free_ioreq_gfn(struct hvm_ioreq_server *s, gfn_t gfn)
 {
     struct domain *d = s->domain;
-    unsigned int i = gfn - d->arch.hvm_domain.ioreq_gfn.base;
+    unsigned int i = gfn_x(gfn) - d->arch.hvm_domain.ioreq_gfn.base;
 
     ASSERT(!s->is_default);
 
@@ -214,7 +213,7 @@ static void hvm_unmap_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
 {
     struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
 
-    if ( iorp->gfn == gfn_x(INVALID_GFN) )
+    if ( gfn_eq(iorp->gfn, INVALID_GFN) )
         return;
 
     destroy_ring_for_helper(&iorp->va, iorp->page);
@@ -223,7 +222,7 @@ static void hvm_unmap_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
     if ( !s->is_default )
         hvm_free_ioreq_gfn(s, iorp->gfn);
 
-    iorp->gfn = gfn_x(INVALID_GFN);
+    iorp->gfn = INVALID_GFN;
 }
 
 static int hvm_map_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
@@ -236,16 +235,17 @@ static int hvm_map_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
         return -EINVAL;
 
     if ( s->is_default )
-        iorp->gfn = buf ?
-                    d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN] :
-                    d->arch.hvm_domain.params[HVM_PARAM_IOREQ_PFN];
+        iorp->gfn = _gfn(buf ?
+                         d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN] :
+                         d->arch.hvm_domain.params[HVM_PARAM_IOREQ_PFN]);
     else
         iorp->gfn = hvm_alloc_ioreq_gfn(s);
 
-    if ( iorp->gfn == gfn_x(INVALID_GFN) )
+    if ( gfn_eq(iorp->gfn, INVALID_GFN) )
         return -ENOMEM;
 
-    rc = prepare_ring_for_helper(d, iorp->gfn, &iorp->page, &iorp->va);
+    rc = prepare_ring_for_helper(d, gfn_x(iorp->gfn), &iorp->page,
+                                 &iorp->va);
 
     if ( rc )
         hvm_unmap_ioreq_gfn(s, buf);
@@ -282,10 +282,10 @@ static void hvm_remove_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
     struct domain *d = s->domain;
     struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
 
-    if ( s->is_default || iorp->gfn == gfn_x(INVALID_GFN) )
+    if ( s->is_default || gfn_eq(iorp->gfn, INVALID_GFN) )
         return;
 
-    if ( guest_physmap_remove_page(d, _gfn(iorp->gfn),
+    if ( guest_physmap_remove_page(d, iorp->gfn,
                                    _mfn(page_to_mfn(iorp->page)), 0) )
         domain_crash(d);
     clear_page(iorp->va);
@@ -297,12 +297,12 @@ static int hvm_add_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
     struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
     int rc;
 
-    if ( s->is_default || iorp->gfn == gfn_x(INVALID_GFN) )
+    if ( s->is_default || gfn_eq(iorp->gfn, INVALID_GFN) )
         return 0;
 
     clear_page(iorp->va);
 
-    rc = guest_physmap_add_page(d, _gfn(iorp->gfn),
+    rc = guest_physmap_add_page(d, iorp->gfn,
                                 _mfn(page_to_mfn(iorp->page)), 0);
     if ( rc == 0 )
         paging_mark_dirty(d, _mfn(page_to_mfn(iorp->page)));
@@ -561,8 +561,8 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
     INIT_LIST_HEAD(&s->ioreq_vcpu_list);
     spin_lock_init(&s->bufioreq_lock);
 
-    s->ioreq.gfn = gfn_x(INVALID_GFN);
-    s->bufioreq.gfn = gfn_x(INVALID_GFN);
+    s->ioreq.gfn = INVALID_GFN;
+    s->bufioreq.gfn = INVALID_GFN;
 
     rc = hvm_ioreq_server_alloc_rangesets(s);
     if ( rc )
@@ -747,11 +747,11 @@ int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
         if ( s->id != id )
             continue;
 
-        *ioreq_gfn = s->ioreq.gfn;
+        *ioreq_gfn = gfn_x(s->ioreq.gfn);
 
         if ( s->bufioreq.va != NULL )
         {
-            *bufioreq_gfn = s->bufioreq.gfn;
+            *bufioreq_gfn = gfn_x(s->bufioreq.gfn);
             *bufioreq_port = s->bufioreq_evtchn;
         }
 
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 16344d173b..7b93d10209 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -36,7 +36,7 @@
 #include <public/hvm/dm_op.h>
 
 struct hvm_ioreq_page {
-    unsigned long gfn;
+    gfn_t gfn;
     struct page_info *page;
     void *va;
 };
-- 
2.11.0


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

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

* [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
                   ` (9 preceding siblings ...)
  2017-08-22 14:51 ` [PATCH v2 REPOST 10/12] x86/hvm/ioreq: use gfn_t in struct hvm_ioreq_page Paul Durrant
@ 2017-08-22 14:51 ` Paul Durrant
  2017-08-24 17:21   ` Roger Pau Monné
  2017-08-28 15:08   ` Wei Liu
  2017-08-22 14:51 ` [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type Paul Durrant
  11 siblings, 2 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:51 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Ian Jackson, Tim Deegan, Paul Durrant, Jan Beulich

A subsequent patch will introduce a new scheme to allow an emulator to
map IOREQ server pages directly from Xen rather than the guest P2M.

This patch lays the groundwork for that change by deferring mapping of
gfns until their values are requested by an emulator. To that end, the
pad field of the xen_dm_op_get_ioreq_server_info structure is re-purposed
to a flags field and new flag, XEN_DMOP_no_gfns, defined which modifies the
behaviour of XEN_DMOP_get_ioreq_server_info to allow the caller to avoid
requesting the gfn values.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
---
 tools/libs/devicemodel/core.c                   |  8 +++++
 tools/libs/devicemodel/include/xendevicemodel.h |  6 ++--
 xen/arch/x86/hvm/dm.c                           |  9 +++--
 xen/arch/x86/hvm/ioreq.c                        | 44 ++++++++++++++-----------
 xen/include/asm-x86/hvm/domain.h                |  2 +-
 xen/include/public/hvm/dm_op.h                  | 32 ++++++++++--------
 6 files changed, 61 insertions(+), 40 deletions(-)

diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c
index fcb260d29b..907c894e77 100644
--- a/tools/libs/devicemodel/core.c
+++ b/tools/libs/devicemodel/core.c
@@ -188,6 +188,14 @@ int xendevicemodel_get_ioreq_server_info(
 
     data->id = id;
 
+    /*
+     * If the caller is not requesting gfn values then instruct the
+     * hypercall not to retrieve them as this may cause them to be
+     * mapped.
+     */
+    if (!ioreq_gfn && !bufioreq_gfn)
+        data->flags = XEN_DMOP_no_gfns;
+
     rc = xendevicemodel_op(dmod, domid, 1, &op, sizeof(op));
     if (rc)
         return rc;
diff --git a/tools/libs/devicemodel/include/xendevicemodel.h b/tools/libs/devicemodel/include/xendevicemodel.h
index 13216db04a..da6b253cfd 100644
--- a/tools/libs/devicemodel/include/xendevicemodel.h
+++ b/tools/libs/devicemodel/include/xendevicemodel.h
@@ -61,11 +61,11 @@ int xendevicemodel_create_ioreq_server(
  * @parm domid the domain id to be serviced
  * @parm id the IOREQ Server id.
  * @parm ioreq_gfn pointer to a xen_pfn_t to receive the synchronous ioreq
- *                  gfn
+ *                  gmfn. (May be NULL if not required)
  * @parm bufioreq_gfn pointer to a xen_pfn_t to receive the buffered ioreq
- *                    gfn
+ *                    gmfn. (May be NULL if not required)
  * @parm bufioreq_port pointer to a evtchn_port_t to receive the buffered
- *                     ioreq event channel
+ *                     ioreq event channel. (May be NULL if not required)
  * @return 0 on success, -1 on failure.
  */
 int xendevicemodel_get_ioreq_server_info(
diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c
index 87ef4b6ca9..c020f0c99f 100644
--- a/xen/arch/x86/hvm/dm.c
+++ b/xen/arch/x86/hvm/dm.c
@@ -418,16 +418,19 @@ static int dm_op(const struct dmop_args *op_args)
     {
         struct xen_dm_op_get_ioreq_server_info *data =
             &op.u.get_ioreq_server_info;
+        const uint16_t valid_flags = XEN_DMOP_no_gfns;
 
         const_op = false;
 
         rc = -EINVAL;
-        if ( data->pad )
+        if ( data->flags & ~valid_flags )
             break;
 
         rc = hvm_get_ioreq_server_info(d, data->id,
-                                       &data->ioreq_gfn,
-                                       &data->bufioreq_gfn,
+                                       (data->flags & XEN_DMOP_no_gfns) ?
+                                       NULL : &data->ioreq_gfn,
+                                       (data->flags & XEN_DMOP_no_gfns) ?
+                                       NULL : &data->bufioreq_gfn,
                                        &data->bufioreq_port);
         break;
     }
diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index 3a9aaf1f5d..795c198f95 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -344,7 +344,8 @@ static int hvm_ioreq_server_add_vcpu(struct hvm_ioreq_server *s,
 
     sv->ioreq_evtchn = rc;
 
-    if ( v->vcpu_id == 0 && s->bufioreq.va != NULL )
+    if ( v->vcpu_id == 0 &&
+         (s->bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF) )
     {
         struct domain *d = s->domain;
 
@@ -395,7 +396,8 @@ static void hvm_ioreq_server_remove_vcpu(struct hvm_ioreq_server *s,
 
         list_del(&sv->list_entry);
 
-        if ( v->vcpu_id == 0 && s->bufioreq.va != NULL )
+        if ( v->vcpu_id == 0 &&
+             (s->bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF) )
             free_xen_event_channel(v->domain, s->bufioreq_evtchn);
 
         free_xen_event_channel(v->domain, sv->ioreq_evtchn);
@@ -422,7 +424,8 @@ static void hvm_ioreq_server_remove_all_vcpus(struct hvm_ioreq_server *s)
 
         list_del(&sv->list_entry);
 
-        if ( v->vcpu_id == 0 && s->bufioreq.va != NULL )
+        if ( v->vcpu_id == 0 &&
+             (s->bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF) )
             free_xen_event_channel(v->domain, s->bufioreq_evtchn);
 
         free_xen_event_channel(v->domain, sv->ioreq_evtchn);
@@ -433,14 +436,13 @@ static void hvm_ioreq_server_remove_all_vcpus(struct hvm_ioreq_server *s)
     spin_unlock(&s->lock);
 }
 
-static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
-                                      bool handle_bufioreq)
+static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s)
 {
     int rc = -ENOMEM;
 
     rc = hvm_map_ioreq_gfn(s, false);
 
-    if ( !rc && handle_bufioreq )
+    if ( !rc && (s->bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF) )
         rc = hvm_map_ioreq_gfn(s, true);
 
     if ( rc )
@@ -568,13 +570,7 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
     if ( rc )
         return rc;
 
-    if ( bufioreq_handling == HVM_IOREQSRV_BUFIOREQ_ATOMIC )
-        s->bufioreq_atomic = true;
-
-    rc = hvm_ioreq_server_map_pages(
-             s, bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF);
-    if ( rc )
-        goto fail_map;
+    s->bufioreq_handling = bufioreq_handling;
 
     for_each_vcpu ( d, v )
     {
@@ -589,9 +585,6 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
     hvm_ioreq_server_remove_all_vcpus(s);
     hvm_ioreq_server_unmap_pages(s);
 
- fail_map:
-    hvm_ioreq_server_free_rangesets(s);
-
     return rc;
 }
 
@@ -747,11 +740,21 @@ int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
         if ( s->id != id )
             continue;
 
-        *ioreq_gfn = gfn_x(s->ioreq.gfn);
+        if ( ioreq_gfn || bufioreq_gfn )
+        {
+            rc = hvm_ioreq_server_map_pages(s);
+            if ( rc )
+                break;
+        }
+
+        if ( ioreq_gfn )
+            *ioreq_gfn = gfn_x(s->ioreq.gfn);
 
-        if ( s->bufioreq.va != NULL )
+        if ( s->bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF )
         {
-            *bufioreq_gfn = gfn_x(s->bufioreq.gfn);
+            if ( bufioreq_gfn )
+                *bufioreq_gfn = gfn_x(s->bufioreq.gfn);
+
             *bufioreq_port = s->bufioreq_evtchn;
         }
 
@@ -1278,7 +1281,8 @@ static int hvm_send_buffered_ioreq(struct hvm_ioreq_server *s, ioreq_t *p)
     pg->ptrs.write_pointer += qw ? 2 : 1;
 
     /* Canonicalize read/write pointers to prevent their overflow. */
-    while ( s->bufioreq_atomic && qw++ < IOREQ_BUFFER_SLOT_NUM &&
+    while ( (s->bufioreq_handling == HVM_IOREQSRV_BUFIOREQ_ATOMIC) &&
+            qw++ < IOREQ_BUFFER_SLOT_NUM &&
             pg->ptrs.read_pointer >= IOREQ_BUFFER_SLOT_NUM )
     {
         union bufioreq_pointers old = pg->ptrs, new;
diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
index 7b93d10209..b8bcd559a5 100644
--- a/xen/include/asm-x86/hvm/domain.h
+++ b/xen/include/asm-x86/hvm/domain.h
@@ -70,7 +70,7 @@ struct hvm_ioreq_server {
     evtchn_port_t          bufioreq_evtchn;
     struct rangeset        *range[NR_IO_RANGE_TYPES];
     bool                   enabled;
-    bool                   bufioreq_atomic;
+    int                    bufioreq_handling;
     bool                   is_default;
 };
 
diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h
index 6bbab5fca3..9677bd74e7 100644
--- a/xen/include/public/hvm/dm_op.h
+++ b/xen/include/public/hvm/dm_op.h
@@ -79,28 +79,34 @@ struct xen_dm_op_create_ioreq_server {
  * XEN_DMOP_get_ioreq_server_info: Get all the information necessary to
  *                                 access IOREQ Server <id>.
  *
- * The emulator needs to map the synchronous ioreq structures and buffered
- * ioreq ring (if it exists) that Xen uses to request emulation. These are
- * hosted in the target domain's gmfns <ioreq_gfn> and <bufioreq_gfn>
- * respectively. In addition, if the IOREQ Server is handling buffered
- * emulation requests, the emulator needs to bind to event channel
- * <bufioreq_port> to listen for them. (The event channels used for
- * synchronous emulation requests are specified in the per-CPU ioreq
- * structures in <ioreq_gfn>).
- * If the IOREQ Server is not handling buffered emulation requests then the
- * values handed back in <bufioreq_gfn> and <bufioreq_port> will both be 0.
+ * If the IOREQ Server is handling buffered emulation requests, the
+ * emulator needs to bind to event channel <bufioreq_port> to listen for
+ * them. (The event channels used for synchronous emulation requests are
+ * specified in the per-CPU ioreq structures).
+ * In addition, if the XENMEM_acquire_resource memory op cannot be used,
+ * the emulator will need to map the synchronous ioreq structures and
+ * buffered ioreq ring (if it exists) from guest memory. If <flags> does
+ * not contain XEN_DMOP_no_gfns then these pages will be made available and
+ * the frame numbers passed back in gfns <ioreq_gfn> and <bufioreq_gfn>
+ * respectively. (If the IOREQ Server is not handling buffered emulation
+ * only <ioreq_gfn> will be valid).
  */
 #define XEN_DMOP_get_ioreq_server_info 2
 
 struct xen_dm_op_get_ioreq_server_info {
     /* IN - server id */
     ioservid_t id;
-    uint16_t pad;
+    /* IN - flags */
+    uint16_t flags;
+
+#define _XEN_DMOP_no_gfns 0
+#define XEN_DMOP_no_gfns (1u << _XEN_DMOP_no_gfns)
+
     /* OUT - buffered ioreq port */
     evtchn_port_t bufioreq_port;
-    /* OUT - sync ioreq gfn */
+    /* OUT - sync ioreq gfn (see block comment above) */
     uint64_aligned_t ioreq_gfn;
-    /* OUT - buffered ioreq gfn */
+    /* OUT - buffered ioreq gfn (see block comment above)*/
     uint64_aligned_t bufioreq_gfn;
 };
 
-- 
2.11.0


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

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

* [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
                   ` (10 preceding siblings ...)
  2017-08-22 14:51 ` [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted Paul Durrant
@ 2017-08-22 14:51 ` Paul Durrant
  2017-08-25  9:32   ` Roger Pau Monné
  11 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-22 14:51 UTC (permalink / raw)
  To: xen-devel
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Ian Jackson, Tim Deegan, Paul Durrant, Jan Beulich

... XENMEM_resource_ioreq_server

This patch adds support for a new resource type that can be mapped using
the XENMEM_acquire_resource memory op.

If an emulator makes use of this resource type then, instead of mapping
gfns, the IOREQ server will allocate pages from the heap. These pages
will never be present in the P2M of the guest at any point and so are
not vulnerable to any direct attack by the guest. They are only ever
accessible by Xen and any domain that has mapping privilege over the
guest (which may or may not be limited to the domain running the emulator).

NOTE: Use of the new resource type is not compatible with use of
      XEN_DMOP_get_ioreq_server_info unless the XEN_DMOP_no_gfns flag is
      set.

Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
---
Cc: Jan Beulich <jbeulich@suse.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: George Dunlap <George.Dunlap@eu.citrix.com>
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Cc: Stefano Stabellini <sstabellini@kernel.org>
Cc: Tim Deegan <tim@xen.org>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 xen/arch/x86/hvm/ioreq.c        | 136 ++++++++++++++++++++++++++++++++++++++++
 xen/arch/x86/mm.c               |  27 ++++++++
 xen/include/asm-x86/hvm/ioreq.h |   2 +
 xen/include/public/hvm/dm_op.h  |   4 ++
 xen/include/public/memory.h     |   3 +
 5 files changed, 172 insertions(+)

diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
index 795c198f95..9e6838dab6 100644
--- a/xen/arch/x86/hvm/ioreq.c
+++ b/xen/arch/x86/hvm/ioreq.c
@@ -231,6 +231,15 @@ static int hvm_map_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
     struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
     int rc;
 
+    if ( iorp->page )
+    {
+        /* Make sure the page has not been allocated */
+        if ( gfn_eq(iorp->gfn, INVALID_GFN) )
+            return -EPERM;
+
+        return 0;
+    }
+
     if ( d->is_dying )
         return -EINVAL;
 
@@ -253,6 +262,60 @@ static int hvm_map_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
     return rc;
 }
 
+static int hvm_alloc_ioreq_mfn(struct hvm_ioreq_server *s, bool buf)
+{
+    struct domain *currd = current->domain;
+    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
+
+    if ( iorp->page )
+    {
+        /* Make sure the page has not been mapped */
+        if ( !gfn_eq(iorp->gfn, INVALID_GFN) )
+            return -EPERM;
+
+        return 0;
+    }
+
+    /*
+     * Allocated IOREQ server pages are assigned to the emulating
+     * domain, not the target domain. This is because the emulator is
+     * likely to be destroyed after the target domain has been torn
+     * down, and we must use MEMF_no_refcount otherwise page allocation
+     * could fail if the emulating domain has already reached its
+     * maximum allocation.
+     */
+    iorp->page = alloc_domheap_page(currd, MEMF_no_refcount);
+    if ( !iorp->page )
+        return -ENOMEM;
+
+    get_page(iorp->page, currd);
+
+    iorp->va = __map_domain_page_global(iorp->page);
+    if ( !iorp->va )
+    {
+        put_page(iorp->page);
+        iorp->page = NULL;
+        return -ENOMEM;
+    }
+
+    clear_page(iorp->va);
+    return 0;
+}
+
+static void hvm_free_ioreq_mfn(struct hvm_ioreq_server *s, bool buf)
+{
+    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
+
+    if ( !iorp->page )
+        return;
+
+    unmap_domain_page_global(iorp->va);
+    iorp->va = NULL;
+
+    put_page(iorp->page);
+    iorp->page = NULL;
+}
+
 bool is_ioreq_server_page(struct domain *d, const struct page_info *page)
 {
     const struct hvm_ioreq_server *s;
@@ -457,6 +520,27 @@ static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s)
     hvm_unmap_ioreq_gfn(s, false);
 }
 
+static int hvm_ioreq_server_alloc_pages(struct hvm_ioreq_server *s)
+{
+    int rc = -ENOMEM;
+
+    rc = hvm_alloc_ioreq_mfn(s, false);
+
+    if ( !rc && (s->bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF) )
+        rc = hvm_alloc_ioreq_mfn(s, true);
+
+    if ( rc )
+        hvm_free_ioreq_mfn(s, false);
+
+    return rc;
+}
+
+static void hvm_ioreq_server_free_pages(struct hvm_ioreq_server *s)
+{
+    hvm_free_ioreq_mfn(s, true);
+    hvm_free_ioreq_mfn(s, false);
+}
+
 static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s)
 {
     unsigned int i;
@@ -583,7 +667,18 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
 
  fail_add:
     hvm_ioreq_server_remove_all_vcpus(s);
+
+    /*
+     * NOTE: It is safe to call both hvm_ioreq_server_unmap_pages() and
+     *       hvm_ioreq_server_free_pages() in that order.
+     *       This is because the former will do nothing if the pages
+     *       are not mapped, leaving the page to be freed by the latter.
+     *       However if the pages are mapped then the former will set
+     *       the page_info pointer to NULL, meaning the latter will do
+     *       nothing.
+     */
     hvm_ioreq_server_unmap_pages(s);
+    hvm_ioreq_server_free_pages(s);
 
     return rc;
 }
@@ -593,6 +688,7 @@ static void hvm_ioreq_server_deinit(struct hvm_ioreq_server *s)
     ASSERT(!s->enabled);
     hvm_ioreq_server_remove_all_vcpus(s);
     hvm_ioreq_server_unmap_pages(s);
+    hvm_ioreq_server_free_pages(s);
     hvm_ioreq_server_free_rangesets(s);
 }
 
@@ -745,6 +841,9 @@ int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
             rc = hvm_ioreq_server_map_pages(s);
             if ( rc )
                 break;
+
+            gdprintk(XENLOG_INFO, "d%d ioreq server %u using gfns\n",
+                     d->domain_id, s->id);
         }
 
         if ( ioreq_gfn )
@@ -767,6 +866,43 @@ int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
     return rc;
 }
 
+mfn_t hvm_get_ioreq_server_frame(struct domain *d, ioservid_t id,
+                                 unsigned int idx)
+{
+    struct hvm_ioreq_server *s;
+    mfn_t mfn = INVALID_MFN;
+
+    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
+
+    list_for_each_entry ( s,
+                          &d->arch.hvm_domain.ioreq_server.list,
+                          list_entry )
+    {
+        int rc;
+
+        if ( s == d->arch.hvm_domain.default_ioreq_server )
+            continue;
+
+        if ( s->id != id )
+            continue;
+
+        rc = hvm_ioreq_server_alloc_pages(s);
+        if ( rc )
+            break;
+
+        if ( idx == 0 )
+            mfn = _mfn(page_to_mfn(s->bufioreq.page));
+        else if ( idx == 1 )
+            mfn = _mfn(page_to_mfn(s->ioreq.page));
+
+        break;
+    }
+
+    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
+
+    return mfn;
+}
+
 int hvm_map_io_range_to_ioreq_server(struct domain *d, ioservid_t id,
                                      uint32_t type, uint64_t start,
                                      uint64_t end)
diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
index 4e86f0a2ab..3e845af0e4 100644
--- a/xen/arch/x86/mm.c
+++ b/xen/arch/x86/mm.c
@@ -122,6 +122,7 @@
 #include <asm/fixmap.h>
 #include <asm/io_apic.h>
 #include <asm/pci.h>
+#include <asm/hvm/ioreq.h>
 
 /* Mapping of the fixmap space needed early. */
 l1_pgentry_t __section(".bss.page_aligned") __aligned(PAGE_SIZE)
@@ -4744,6 +4745,27 @@ static int xenmem_acquire_grant_table(struct domain *d,
     return 0;
 }
 
+static int xenmem_acquire_ioreq_server(struct domain *d,
+                                       unsigned int id,
+                                       unsigned long frame,
+                                       unsigned long nr_frames,
+                                       unsigned long mfn_list[])
+{
+    unsigned int i;
+
+    for ( i = 0; i < nr_frames; i++ )
+    {
+        mfn_t mfn = hvm_get_ioreq_server_frame(d, id, frame + i);
+
+        if ( mfn_eq(mfn, INVALID_MFN) )
+            return -EINVAL;
+
+        mfn_list[i] = mfn_x(mfn);
+    }
+
+    return 0;
+}
+
 static int xenmem_acquire_resource(xen_mem_acquire_resource_t *xmar)
 {
     struct domain *d, *currd = current->domain;
@@ -4778,6 +4800,11 @@ static int xenmem_acquire_resource(xen_mem_acquire_resource_t *xmar)
                                         mfn_list);
         break;
 
+    case XENMEM_resource_ioreq_server:
+        rc = xenmem_acquire_ioreq_server(d, xmar->id, xmar->frame,
+                                         xmar->nr_frames, mfn_list);
+        break;
+
     default:
         rc = -EOPNOTSUPP;
         break;
diff --git a/xen/include/asm-x86/hvm/ioreq.h b/xen/include/asm-x86/hvm/ioreq.h
index 1829fcf43e..032aeb6fa9 100644
--- a/xen/include/asm-x86/hvm/ioreq.h
+++ b/xen/include/asm-x86/hvm/ioreq.h
@@ -31,6 +31,8 @@ int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
                               unsigned long *ioreq_gfn,
                               unsigned long *bufioreq_gfn,
                               evtchn_port_t *bufioreq_port);
+mfn_t hvm_get_ioreq_server_frame(struct domain *d, ioservid_t id,
+                                 unsigned int idx);
 int hvm_map_io_range_to_ioreq_server(struct domain *d, ioservid_t id,
                                      uint32_t type, uint64_t start,
                                      uint64_t end);
diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h
index 9677bd74e7..59b6006910 100644
--- a/xen/include/public/hvm/dm_op.h
+++ b/xen/include/public/hvm/dm_op.h
@@ -90,6 +90,10 @@ struct xen_dm_op_create_ioreq_server {
  * the frame numbers passed back in gfns <ioreq_gfn> and <bufioreq_gfn>
  * respectively. (If the IOREQ Server is not handling buffered emulation
  * only <ioreq_gfn> will be valid).
+ *
+ * NOTE: To access the synchronous ioreq structures and buffered ioreq
+ *       ring, it is preferable to use the XENMEM_acquire_resource memory
+ *       op specifying resource type XENMEM_resource_ioreq_server.
  */
 #define XEN_DMOP_get_ioreq_server_info 2
 
diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h
index 9bf58e7384..716941dc0c 100644
--- a/xen/include/public/memory.h
+++ b/xen/include/public/memory.h
@@ -664,10 +664,13 @@ struct xen_mem_acquire_resource {
     uint16_t type;
 
 #define XENMEM_resource_grant_table 0
+#define XENMEM_resource_ioreq_server 1
 
     /*
      * IN - a type-specific resource identifier, which must be zero
      *      unless stated otherwise.
+     *
+     * type == XENMEM_resource_ioreq_server -> id == ioreq server id
      */
     uint32_t id;
     /* IN - number of (4K) frames of the resource to be mapped */
-- 
2.11.0


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

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

* Re: [PATCH v2 REPOST 01/12] [x86|arm]: remove code duplication
  2017-08-22 14:50 ` [PATCH v2 REPOST 01/12] [x86|arm]: remove code duplication Paul Durrant
@ 2017-08-24 14:12   ` Jan Beulich
  2017-08-24 14:16     ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Jan Beulich @ 2017-08-24 14:12 UTC (permalink / raw)
  To: Paul Durrant; +Cc: Andrew Cooper, Julien Grall, Stefano Stabellini, xen-devel

>>> On 22.08.17 at 16:50, <paul.durrant@citrix.com> wrote:
> There is a substantial amount of code duplicated between the x86 and arm
> implementations of mm.c:xenmem_add_to_physmap_one() for
> XENMAPSPACE_grant_table. Also, the code in question looks like it really
> should be in common/grant_table.c
> 
> This patch introduces a new function in common/grant_table.c to get the mfn
> of a specified frame in the grant table of a specified guest, and calls to
> that from the arch-specific code in mm.c.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

This would need re-basing over the XSA-235 fix, but I prefer
Jürgen's similar change, as it retains the present locking
properties better on ARM.

Jan

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

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

* Re: [PATCH v2 REPOST 01/12] [x86|arm]: remove code duplication
  2017-08-24 14:12   ` Jan Beulich
@ 2017-08-24 14:16     ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-24 14:16 UTC (permalink / raw)
  To: 'Jan Beulich'
  Cc: Andrew Cooper, Julien Grall, Stefano Stabellini, xen-devel

> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: 24 August 2017 15:13
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Julien Grall <julien.grall@arm.com>; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Stefano Stabellini <sstabellini@kernel.org>;
> xen-devel@lists.xenproject.org
> Subject: Re: [PATCH v2 REPOST 01/12] [x86|arm]: remove code duplication
> 
> >>> On 22.08.17 at 16:50, <paul.durrant@citrix.com> wrote:
> > There is a substantial amount of code duplicated between the x86 and arm
> > implementations of mm.c:xenmem_add_to_physmap_one() for
> > XENMAPSPACE_grant_table. Also, the code in question looks like it really
> > should be in common/grant_table.c
> >
> > This patch introduces a new function in common/grant_table.c to get the
> mfn
> > of a specified frame in the grant table of a specified guest, and calls to
> > that from the arch-specific code in mm.c.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> This would need re-basing over the XSA-235 fix, but I prefer
> Jürgen's similar change, as it retains the present locking
> properties better on ARM.

That's ok. I'm happy to rebase on that once it is committed.

  Paul

> 
> Jan
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

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

* Re: [PATCH v2 REPOST 04/12] tools/libxenforeignmemory: add support for resource mapping
  2017-08-22 14:50 ` [PATCH v2 REPOST 04/12] tools/libxenforeignmemory: add support for resource mapping Paul Durrant
@ 2017-08-24 15:52   ` Roger Pau Monné
  2017-08-24 15:58     ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Roger Pau Monné @ 2017-08-24 15:52 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Wei Liu, Ian Jackson

On Tue, Aug 22, 2017 at 03:50:58PM +0100, Paul Durrant wrote:
> diff --git a/tools/libs/foreignmemory/include/xenforeignmemory.h b/tools/libs/foreignmemory/include/xenforeignmemory.h
> index f4814c390f..e56eb3c4d4 100644
> --- a/tools/libs/foreignmemory/include/xenforeignmemory.h
> +++ b/tools/libs/foreignmemory/include/xenforeignmemory.h
> @@ -138,6 +138,45 @@ int xenforeignmemory_unmap(xenforeignmemory_handle *fmem,
>  int xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
>                                domid_t domid);
>  
> +typedef struct xenforeignmemory_resource_handle xenforeignmemory_resource_handle;
> +
> +/**
> + * This function maps a guest resource.
> + *
> + * @parm fmem handle to the open foreignmemory interface
> + * @parm domid the domain id
> + * @parm type the resource type
> + * @parm id the type-specific resource identifier
> + * @parm frame base frame index within the resource
> + * @parm nr_frames number of frames to map
> + * @parm paddr pointer to an address passed through to mmap(2)
> + * @parm prot passed through to mmap(2)
> + * @parm flags passed through to mmap(2)

Passing mmap flags directly can be troublesome, POSIX only defines
MAP_SHARED and MAP_PRIVATE, the rest is OS-specific AFAIK. So we
either limit this to POSIX only flags (and enforce it), or we replace
it with some xenforeignmemory specific flags that each OS can map to
it's equivalents.

> --- a/tools/libs/foreignmemory/private.h
> +++ b/tools/libs/foreignmemory/private.h
> @@ -42,6 +42,36 @@ void *compat_mapforeign_batch(xenforeignmem_handle *fmem, uint32_t dom,
>                                xen_pfn_t *arr, int num);
>  #endif
>  
> +struct xenforeignmemory_resource_handle {
> +    domid_t domid;
> +    unsigned int type;
> +    unsigned int id;
> +    unsigned long frame;
> +    unsigned long nr_frames;
> +    void *addr;
> +    int prot;
> +    int flags;
> +};
> +
> +#ifndef __linux__

The common practice in libxenforeign seems to be to add those dummy
handlers to each OS-specific file (see osdep_xenforeignmemory_restrict
for example) instead of doing it in the header file.

Roger.

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

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

* Re: [PATCH v2 REPOST 04/12] tools/libxenforeignmemory: add support for resource mapping
  2017-08-24 15:52   ` Roger Pau Monné
@ 2017-08-24 15:58     ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-24 15:58 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: xen-devel, Wei Liu, Ian Jackson

> -----Original Message-----
> From: Roger Pau Monne
> Sent: 24 August 2017 16:53
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; Wei Liu <wei.liu2@citrix.com>; Ian
> Jackson <Ian.Jackson@citrix.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 04/12]
> tools/libxenforeignmemory: add support for resource mapping
> 
> On Tue, Aug 22, 2017 at 03:50:58PM +0100, Paul Durrant wrote:
> > diff --git a/tools/libs/foreignmemory/include/xenforeignmemory.h
> b/tools/libs/foreignmemory/include/xenforeignmemory.h
> > index f4814c390f..e56eb3c4d4 100644
> > --- a/tools/libs/foreignmemory/include/xenforeignmemory.h
> > +++ b/tools/libs/foreignmemory/include/xenforeignmemory.h
> > @@ -138,6 +138,45 @@ int
> xenforeignmemory_unmap(xenforeignmemory_handle *fmem,
> >  int xenforeignmemory_restrict(xenforeignmemory_handle *fmem,
> >                                domid_t domid);
> >
> > +typedef struct xenforeignmemory_resource_handle
> xenforeignmemory_resource_handle;
> > +
> > +/**
> > + * This function maps a guest resource.
> > + *
> > + * @parm fmem handle to the open foreignmemory interface
> > + * @parm domid the domain id
> > + * @parm type the resource type
> > + * @parm id the type-specific resource identifier
> > + * @parm frame base frame index within the resource
> > + * @parm nr_frames number of frames to map
> > + * @parm paddr pointer to an address passed through to mmap(2)
> > + * @parm prot passed through to mmap(2)
> > + * @parm flags passed through to mmap(2)
> 
> Passing mmap flags directly can be troublesome, POSIX only defines
> MAP_SHARED and MAP_PRIVATE, the rest is OS-specific AFAIK. So we
> either limit this to POSIX only flags (and enforce it), or we replace
> it with some xenforeignmemory specific flags that each OS can map to
> it's equivalents.

Given that foreign memory mapping already passes through flags I guess that, for consistency, it would be best to limit use to POSIX-only flags in all cases.

> 
> > --- a/tools/libs/foreignmemory/private.h
> > +++ b/tools/libs/foreignmemory/private.h
> > @@ -42,6 +42,36 @@ void
> *compat_mapforeign_batch(xenforeignmem_handle *fmem, uint32_t dom,
> >                                xen_pfn_t *arr, int num);
> >  #endif
> >
> > +struct xenforeignmemory_resource_handle {
> > +    domid_t domid;
> > +    unsigned int type;
> > +    unsigned int id;
> > +    unsigned long frame;
> > +    unsigned long nr_frames;
> > +    void *addr;
> > +    int prot;
> > +    int flags;
> > +};
> > +
> > +#ifndef __linux__
> 
> The common practice in libxenforeign seems to be to add those dummy
> handlers to each OS-specific file (see osdep_xenforeignmemory_restrict
> for example) instead of doing it in the header file.

Yes, I know, I introduced that code :-) I think this way is actually neater. If no-one objects I can add a patch in to clean up xenforeignmemory_restrict() too.

Cheers,

  Paul

> 
> Roger.

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

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

* Re: [PATCH v2 REPOST 05/12] tools/libxenctrl: use new xenforeignmemory API to seed grant table
  2017-08-22 14:50 ` [PATCH v2 REPOST 05/12] tools/libxenctrl: use new xenforeignmemory API to seed grant table Paul Durrant
@ 2017-08-24 16:02   ` Roger Pau Monné
  2017-08-24 16:09     ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Roger Pau Monné @ 2017-08-24 16:02 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Wei Liu, Ian Jackson

On Tue, Aug 22, 2017 at 03:50:59PM +0100, Paul Durrant wrote:
> A previous patch added support for priv-mapping guest resources directly
> (rather than having to foreign-map, which requires P2M modification for
> HVM guests).
> 
> This patch makes use of the new API to seed the guest grant table unless
> the underlying infrastructure (i.e. privcmd) doesn't support it, in which
> case the old scheme is used.
> 
> NOTE: The call to xc_dom_gnttab_hvm_seed() in hvm_build_set_params() was
>       actually unnecessary, as the grant table has already been seeded
>       by a prior call to xc_dom_gnttab_init() made by libxl__build_dom().
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> Acked-by: Marek Marczykowski-Górecki <marmarek@invisiblethingslab.com>
> ---
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> ---
>  tools/libxc/include/xc_dom.h        |   8 +--
>  tools/libxc/xc_dom_boot.c           | 102 ++++++++++++++++++++++++++++--------
>  tools/libxc/xc_sr_restore_x86_hvm.c |  10 ++--
>  tools/libxc/xc_sr_restore_x86_pv.c  |   2 +-
>  tools/libxl/libxl_dom.c             |   1 -
>  tools/python/xen/lowlevel/xc/xc.c   |   6 +--
>  6 files changed, 92 insertions(+), 37 deletions(-)
> 
> diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
> index ce47058c41..d6ca0a8680 100644
> --- a/tools/libxc/include/xc_dom.h
> +++ b/tools/libxc/include/xc_dom.h
> @@ -323,12 +323,8 @@ void *xc_dom_boot_domU_map(struct xc_dom_image *dom, xen_pfn_t pfn,
>  int xc_dom_boot_image(struct xc_dom_image *dom);
>  int xc_dom_compat_check(struct xc_dom_image *dom);
>  int xc_dom_gnttab_init(struct xc_dom_image *dom);
> -int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
> -                           xen_pfn_t console_gmfn,
> -                           xen_pfn_t xenstore_gmfn,
> -                           domid_t console_domid,
> -                           domid_t xenstore_domid);
> -int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
> +int xc_dom_gnttab_seed(xc_interface *xch, domid_t guest_domid,
> +                       bool is_hvm,
>                         xen_pfn_t console_gmfn,
>                         xen_pfn_t xenstore_gmfn,
>                         domid_t console_domid,
> diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
> index c3b44dd399..fc3174ad7e 100644
> --- a/tools/libxc/xc_dom_boot.c
> +++ b/tools/libxc/xc_dom_boot.c
> @@ -280,11 +280,11 @@ static xen_pfn_t xc_dom_gnttab_setup(xc_interface *xch, domid_t domid)
>      return gmfn;
>  }
>  
> -int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
> -                       xen_pfn_t console_gmfn,
> -                       xen_pfn_t xenstore_gmfn,
> -                       domid_t console_domid,
> -                       domid_t xenstore_domid)
> +static int compat_gnttab_seed(xc_interface *xch, domid_t domid,
> +                              xen_pfn_t console_gmfn,
> +                              xen_pfn_t xenstore_gmfn,
> +                              domid_t console_domid,
> +                              domid_t xenstore_domid)
>  {
>  
>      xen_pfn_t gnttab_gmfn;
> @@ -337,11 +337,11 @@ int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
>      return 0;
>  }
>  
> -int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
> -                           xen_pfn_t console_gpfn,
> -                           xen_pfn_t xenstore_gpfn,
> -                           domid_t console_domid,
> -                           domid_t xenstore_domid)
> +static int compat_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
> +                                  xen_pfn_t console_gpfn,
> +                                  xen_pfn_t xenstore_gpfn,
> +                                  domid_t console_domid,
> +                                  domid_t xenstore_domid)
>  {
>      int rc;
>      xen_pfn_t scratch_gpfn;
> @@ -380,7 +380,7 @@ int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
>          return -1;
>      }
>  
> -    rc = xc_dom_gnttab_seed(xch, domid,
> +    rc = compat_gnttab_seed(xch, domid,
>                              console_gpfn, xenstore_gpfn,
>                              console_domid, xenstore_domid);
>      if (rc != 0)
> @@ -405,18 +405,78 @@ int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
>      return 0;
>  }
>  
> -int xc_dom_gnttab_init(struct xc_dom_image *dom)
> +int xc_dom_gnttab_seed(xc_interface *xch, domid_t guest_domid,
> +                       bool is_hvm, xen_pfn_t console_gmfn,
> +                       xen_pfn_t xenstore_gmfn, domid_t console_domid,
> +                       domid_t xenstore_domid)
>  {
> -    if ( xc_dom_translated(dom) ) {
> -        return xc_dom_gnttab_hvm_seed(dom->xch, dom->guest_domid,
> -                                      dom->console_pfn, dom->xenstore_pfn,
> -                                      dom->console_domid, dom->xenstore_domid);
> -    } else {
> -        return xc_dom_gnttab_seed(dom->xch, dom->guest_domid,
> -                                  xc_dom_p2m(dom, dom->console_pfn),
> -                                  xc_dom_p2m(dom, dom->xenstore_pfn),
> -                                  dom->console_domid, dom->xenstore_domid);
> +    xenforeignmemory_handle* fmem = xch->fmem;
> +    xenforeignmemory_resource_handle *fres;
> +    void *addr = NULL;
> +    grant_entry_v1_t *gnttab;
> +
> +    fres = xenforeignmemory_map_resource(fmem, guest_domid,
> +                                         XENMEM_resource_grant_table,
> +                                         0, 0, 1,
> +                                         &addr, PROT_READ | PROT_WRITE, 0);
> +    if ( !fres )
> +    {
> +        if ( errno == EOPNOTSUPP )
> +            return is_hvm ?
> +                compat_gnttab_hvm_seed(xch, guest_domid,
> +                                       console_gmfn, xenstore_gmfn,
> +                                       console_domid, xenstore_domid) :
> +                compat_gnttab_seed(xch, guest_domid,
> +                                   console_gmfn, xenstore_gmfn,
> +                                   console_domid, xenstore_domid);

Could be written as:

return (is_hvm ? compat_gnttab_hvm_seed : compat_gnttab_seed)
       (xch, guest_domid, console_gmfn, xenstore_gmfn, console_domid,
        xenstore_domid);

> +
> +        xc_dom_panic(xch, XC_INTERNAL_ERROR,
> +                     "%s: failed to acquire grant table "
> +                     "[errno=%d]\n",
> +                     __FUNCTION__, errno);
> +        return -1;
>      }
> +
> +    gnttab = addr;
> +
> +    if ( guest_domid != console_domid  && console_gmfn != -1)
                                        ^ extra space.
> +    {
> +        xc_dom_printf(xch, "%s: setting console pfn=0x%"PRI_xen_pfn,
> +                      __FUNCTION__, console_gmfn);
> +
> +        gnttab[GNTTAB_RESERVED_CONSOLE].flags = GTF_permit_access;
> +        gnttab[GNTTAB_RESERVED_CONSOLE].domid = console_domid;
> +        gnttab[GNTTAB_RESERVED_CONSOLE].frame = console_gmfn;
> +    }
> +
> +    if ( guest_domid != xenstore_domid && xenstore_gmfn != -1)
> +    {
> +        xc_dom_printf(xch, "%s: setting xenstore pfn=0x%"PRI_xen_pfn,
> +                      __FUNCTION__, xenstore_gmfn);
> +
> +        gnttab[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access;
> +        gnttab[GNTTAB_RESERVED_XENSTORE].domid = xenstore_domid;
> +        gnttab[GNTTAB_RESERVED_XENSTORE].frame = xenstore_gmfn;
> +    }

The code above is already present in xc_dom_gnttab_seed (now renamed
to compat_gnttab_seed, isn't there anyway that you could re-use it?

Roger.

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

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

* Re: [PATCH v2 REPOST 06/12] x86/hvm/ioreq: rename .*pfn and .*gmfn to .*gfn
  2017-08-22 14:51 ` [PATCH v2 REPOST 06/12] x86/hvm/ioreq: rename .*pfn and .*gmfn to .*gfn Paul Durrant
@ 2017-08-24 16:06   ` Roger Pau Monné
  2017-08-28 15:01   ` Wei Liu
  1 sibling, 0 replies; 56+ messages in thread
From: Roger Pau Monné @ 2017-08-24 16:06 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Jan Beulich, Andrew Cooper

On Tue, Aug 22, 2017 at 03:51:00PM +0100, Paul Durrant wrote:
> Since IOREQ servers are only relevant to HVM guests and all the names in
> question unequivocally refer to guest frame numbers, name them all .*gfn
> to avoid any confusion.
> 
> This patch is purely cosmetic. No semantic or functional change.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

LGTM:

Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>

Thanks, Roger.

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

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

* Re: [PATCH v2 REPOST 05/12] tools/libxenctrl: use new xenforeignmemory API to seed grant table
  2017-08-24 16:02   ` Roger Pau Monné
@ 2017-08-24 16:09     ` Paul Durrant
  2017-08-28 15:04       ` Wei Liu
  0 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-24 16:09 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: xen-devel, Wei Liu, Ian Jackson

> -----Original Message-----
> From: Roger Pau Monne
> Sent: 24 August 2017 17:03
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; Wei Liu <wei.liu2@citrix.com>; Ian
> Jackson <Ian.Jackson@citrix.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 05/12] tools/libxenctrl: use new
> xenforeignmemory API to seed grant table
> 
> On Tue, Aug 22, 2017 at 03:50:59PM +0100, Paul Durrant wrote:
> > A previous patch added support for priv-mapping guest resources directly
> > (rather than having to foreign-map, which requires P2M modification for
> > HVM guests).
> >
> > This patch makes use of the new API to seed the guest grant table unless
> > the underlying infrastructure (i.e. privcmd) doesn't support it, in which
> > case the old scheme is used.
> >
> > NOTE: The call to xc_dom_gnttab_hvm_seed() in hvm_build_set_params()
> was
> >       actually unnecessary, as the grant table has already been seeded
> >       by a prior call to xc_dom_gnttab_init() made by libxl__build_dom().
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > Acked-by: Marek Marczykowski-Górecki
> <marmarek@invisiblethingslab.com>
> > ---
> > Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> > Cc: Wei Liu <wei.liu2@citrix.com>
> > ---
> >  tools/libxc/include/xc_dom.h        |   8 +--
> >  tools/libxc/xc_dom_boot.c           | 102
> ++++++++++++++++++++++++++++--------
> >  tools/libxc/xc_sr_restore_x86_hvm.c |  10 ++--
> >  tools/libxc/xc_sr_restore_x86_pv.c  |   2 +-
> >  tools/libxl/libxl_dom.c             |   1 -
> >  tools/python/xen/lowlevel/xc/xc.c   |   6 +--
> >  6 files changed, 92 insertions(+), 37 deletions(-)
> >
> > diff --git a/tools/libxc/include/xc_dom.h b/tools/libxc/include/xc_dom.h
> > index ce47058c41..d6ca0a8680 100644
> > --- a/tools/libxc/include/xc_dom.h
> > +++ b/tools/libxc/include/xc_dom.h
> > @@ -323,12 +323,8 @@ void *xc_dom_boot_domU_map(struct
> xc_dom_image *dom, xen_pfn_t pfn,
> >  int xc_dom_boot_image(struct xc_dom_image *dom);
> >  int xc_dom_compat_check(struct xc_dom_image *dom);
> >  int xc_dom_gnttab_init(struct xc_dom_image *dom);
> > -int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
> > -                           xen_pfn_t console_gmfn,
> > -                           xen_pfn_t xenstore_gmfn,
> > -                           domid_t console_domid,
> > -                           domid_t xenstore_domid);
> > -int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
> > +int xc_dom_gnttab_seed(xc_interface *xch, domid_t guest_domid,
> > +                       bool is_hvm,
> >                         xen_pfn_t console_gmfn,
> >                         xen_pfn_t xenstore_gmfn,
> >                         domid_t console_domid,
> > diff --git a/tools/libxc/xc_dom_boot.c b/tools/libxc/xc_dom_boot.c
> > index c3b44dd399..fc3174ad7e 100644
> > --- a/tools/libxc/xc_dom_boot.c
> > +++ b/tools/libxc/xc_dom_boot.c
> > @@ -280,11 +280,11 @@ static xen_pfn_t
> xc_dom_gnttab_setup(xc_interface *xch, domid_t domid)
> >      return gmfn;
> >  }
> >
> > -int xc_dom_gnttab_seed(xc_interface *xch, domid_t domid,
> > -                       xen_pfn_t console_gmfn,
> > -                       xen_pfn_t xenstore_gmfn,
> > -                       domid_t console_domid,
> > -                       domid_t xenstore_domid)
> > +static int compat_gnttab_seed(xc_interface *xch, domid_t domid,
> > +                              xen_pfn_t console_gmfn,
> > +                              xen_pfn_t xenstore_gmfn,
> > +                              domid_t console_domid,
> > +                              domid_t xenstore_domid)
> >  {
> >
> >      xen_pfn_t gnttab_gmfn;
> > @@ -337,11 +337,11 @@ int xc_dom_gnttab_seed(xc_interface *xch,
> domid_t domid,
> >      return 0;
> >  }
> >
> > -int xc_dom_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
> > -                           xen_pfn_t console_gpfn,
> > -                           xen_pfn_t xenstore_gpfn,
> > -                           domid_t console_domid,
> > -                           domid_t xenstore_domid)
> > +static int compat_gnttab_hvm_seed(xc_interface *xch, domid_t domid,
> > +                                  xen_pfn_t console_gpfn,
> > +                                  xen_pfn_t xenstore_gpfn,
> > +                                  domid_t console_domid,
> > +                                  domid_t xenstore_domid)
> >  {
> >      int rc;
> >      xen_pfn_t scratch_gpfn;
> > @@ -380,7 +380,7 @@ int xc_dom_gnttab_hvm_seed(xc_interface *xch,
> domid_t domid,
> >          return -1;
> >      }
> >
> > -    rc = xc_dom_gnttab_seed(xch, domid,
> > +    rc = compat_gnttab_seed(xch, domid,
> >                              console_gpfn, xenstore_gpfn,
> >                              console_domid, xenstore_domid);
> >      if (rc != 0)
> > @@ -405,18 +405,78 @@ int xc_dom_gnttab_hvm_seed(xc_interface
> *xch, domid_t domid,
> >      return 0;
> >  }
> >
> > -int xc_dom_gnttab_init(struct xc_dom_image *dom)
> > +int xc_dom_gnttab_seed(xc_interface *xch, domid_t guest_domid,
> > +                       bool is_hvm, xen_pfn_t console_gmfn,
> > +                       xen_pfn_t xenstore_gmfn, domid_t console_domid,
> > +                       domid_t xenstore_domid)
> >  {
> > -    if ( xc_dom_translated(dom) ) {
> > -        return xc_dom_gnttab_hvm_seed(dom->xch, dom->guest_domid,
> > -                                      dom->console_pfn, dom->xenstore_pfn,
> > -                                      dom->console_domid, dom->xenstore_domid);
> > -    } else {
> > -        return xc_dom_gnttab_seed(dom->xch, dom->guest_domid,
> > -                                  xc_dom_p2m(dom, dom->console_pfn),
> > -                                  xc_dom_p2m(dom, dom->xenstore_pfn),
> > -                                  dom->console_domid, dom->xenstore_domid);
> > +    xenforeignmemory_handle* fmem = xch->fmem;
> > +    xenforeignmemory_resource_handle *fres;
> > +    void *addr = NULL;
> > +    grant_entry_v1_t *gnttab;
> > +
> > +    fres = xenforeignmemory_map_resource(fmem, guest_domid,
> > +                                         XENMEM_resource_grant_table,
> > +                                         0, 0, 1,
> > +                                         &addr, PROT_READ | PROT_WRITE, 0);
> > +    if ( !fres )
> > +    {
> > +        if ( errno == EOPNOTSUPP )
> > +            return is_hvm ?
> > +                compat_gnttab_hvm_seed(xch, guest_domid,
> > +                                       console_gmfn, xenstore_gmfn,
> > +                                       console_domid, xenstore_domid) :
> > +                compat_gnttab_seed(xch, guest_domid,
> > +                                   console_gmfn, xenstore_gmfn,
> > +                                   console_domid, xenstore_domid);
> 
> Could be written as:
> 
> return (is_hvm ? compat_gnttab_hvm_seed : compat_gnttab_seed)
>        (xch, guest_domid, console_gmfn, xenstore_gmfn, console_domid,
>         xenstore_domid);

Is that preferable?

> 
> > +
> > +        xc_dom_panic(xch, XC_INTERNAL_ERROR,
> > +                     "%s: failed to acquire grant table "
> > +                     "[errno=%d]\n",
> > +                     __FUNCTION__, errno);
> > +        return -1;
> >      }
> > +
> > +    gnttab = addr;
> > +
> > +    if ( guest_domid != console_domid  && console_gmfn != -1)
>                                         ^ extra space.
> > +    {
> > +        xc_dom_printf(xch, "%s: setting console pfn=0x%"PRI_xen_pfn,
> > +                      __FUNCTION__, console_gmfn);
> > +
> > +        gnttab[GNTTAB_RESERVED_CONSOLE].flags = GTF_permit_access;
> > +        gnttab[GNTTAB_RESERVED_CONSOLE].domid = console_domid;
> > +        gnttab[GNTTAB_RESERVED_CONSOLE].frame = console_gmfn;
> > +    }
> > +
> > +    if ( guest_domid != xenstore_domid && xenstore_gmfn != -1)
> > +    {
> > +        xc_dom_printf(xch, "%s: setting xenstore pfn=0x%"PRI_xen_pfn,
> > +                      __FUNCTION__, xenstore_gmfn);
> > +
> > +        gnttab[GNTTAB_RESERVED_XENSTORE].flags = GTF_permit_access;
> > +        gnttab[GNTTAB_RESERVED_XENSTORE].domid = xenstore_domid;
> > +        gnttab[GNTTAB_RESERVED_XENSTORE].frame = xenstore_gmfn;
> > +    }
> 
> The code above is already present in xc_dom_gnttab_seed (now renamed
> to compat_gnttab_seed, isn't there anyway that you could re-use it?

Hmm. Maybe. I'll see if I can re-work it to remove the duplication.

Thanks,

  Paul

> 
> Roger.

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

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

* Re: [PATCH v2 REPOST 07/12] x86/hvm/ioreq: use bool rather than bool_t
  2017-08-22 14:51 ` [PATCH v2 REPOST 07/12] x86/hvm/ioreq: use bool rather than bool_t Paul Durrant
@ 2017-08-24 16:11   ` Roger Pau Monné
  0 siblings, 0 replies; 56+ messages in thread
From: Roger Pau Monné @ 2017-08-24 16:11 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Jan Beulich, Andrew Cooper

On Tue, Aug 22, 2017 at 03:51:01PM +0100, Paul Durrant wrote:
> This patch changes use of bool_t to bool in the IOREQ server code. It also
> fixes an incorrect indentation in a continuation line.
> 
> This patch is purely cosmetic. No semantic or functional change.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

LGTM:

Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>

Thanks, Roger.

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

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

* Re: [PATCH v2 REPOST 08/12] x86/hvm/ioreq: move is_default into struct hvm_ioreq_server
  2017-08-22 14:51 ` [PATCH v2 REPOST 08/12] x86/hvm/ioreq: move is_default into struct hvm_ioreq_server Paul Durrant
@ 2017-08-24 16:21   ` Roger Pau Monné
  2017-08-24 16:31     ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Roger Pau Monné @ 2017-08-24 16:21 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Jan Beulich, Andrew Cooper

On Tue, Aug 22, 2017 at 03:51:02PM +0100, Paul Durrant wrote:
> Legacy emulators use the 'default' IOREQ server which has slightly
> different semantics than other, explicitly created, IOREQ servers.
> 
> Because of this, most of the initialization and teardown code needs to
> know whether the server is default or not. This is currently achieved
> by passing an is_default boolean argument to the functions in question,
> whereas this argument could be avoided by adding a field to the
> hvm_ioreq_server structure which is also passed as an argument to all
> the relevant functions.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

This looks fine, I've also seen that there's a hvm_domain.default_ioreq_server, which is used in a bunch of loops in the file like:

if ( s == d->arch.hvm_domain.default_ioreq_server )

AFAICT those could also be replaced with s->is_default.

Roger.

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

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

* Re: [PATCH v2 REPOST 08/12] x86/hvm/ioreq: move is_default into struct hvm_ioreq_server
  2017-08-24 16:21   ` Roger Pau Monné
@ 2017-08-24 16:31     ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-24 16:31 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: xen-devel, Jan Beulich, Andrew Cooper

> -----Original Message-----
> From: Roger Pau Monne
> Sent: 24 August 2017 17:22
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 08/12] x86/hvm/ioreq: move
> is_default into struct hvm_ioreq_server
> 
> On Tue, Aug 22, 2017 at 03:51:02PM +0100, Paul Durrant wrote:
> > Legacy emulators use the 'default' IOREQ server which has slightly
> > different semantics than other, explicitly created, IOREQ servers.
> >
> > Because of this, most of the initialization and teardown code needs to
> > know whether the server is default or not. This is currently achieved
> > by passing an is_default boolean argument to the functions in question,
> > whereas this argument could be avoided by adding a field to the
> > hvm_ioreq_server structure which is also passed as an argument to all
> > the relevant functions.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> This looks fine, I've also seen that there's a
> hvm_domain.default_ioreq_server, which is used in a bunch of loops in the
> file like:
> 
> if ( s == d->arch.hvm_domain.default_ioreq_server )
> 
> AFAICT those could also be replaced with s->is_default.

Yes, they should be. Thanks for spotting that.

Cheers,

  Paul

> 
> Roger.

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

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

* Re: [PATCH v2 REPOST 02/12] x86/mm: allow a privileged PV domain to map guest mfns
  2017-08-22 14:50 ` [PATCH v2 REPOST 02/12] x86/mm: allow a privileged PV domain to map guest mfns Paul Durrant
@ 2017-08-24 16:33   ` Wei Liu
  2017-08-25 10:05     ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Wei Liu @ 2017-08-24 16:33 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Wei Liu, Jan Beulich, Andrew Cooper

On Tue, Aug 22, 2017 at 03:50:56PM +0100, Paul Durrant wrote:
> In the case where a PV domain is mapping guest resources then it needs make
> the HYPERVISOR_mmu_update call using DOMID_SELF, rather than the guest
> domid, so that the passed in gmfn values are correctly treated as mfns
> rather than gfns present in the guest p2m.
> 

What would be the callchain like in this case?

I don't quite understand how this fits with the resource mapping code
in this series.

> This patch removes a check which currently disallows mapping of a page when
> the owner of the page tables matches the domain passed to
> HYPERVISOR_mmu_update, but that domain is not the real owner of the page.
> The check was introduced by patch d3c6a215ca9 ("x86: Clean up
> get_page_from_l1e() to correctly distinguish between owner-of-pte and
> owner-of-data-page in all cases") but it's not clear why it was needed.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
>  xen/arch/x86/mm.c | 13 ++++++++-----
>  1 file changed, 8 insertions(+), 5 deletions(-)
> 
> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index 0abb1e284f..aaa9ff5197 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -989,12 +989,15 @@ get_page_from_l1e(
>                     (real_pg_owner != dom_cow) ) )
>      {
>          /*
> -         * Let privileged domains transfer the right to map their target
> -         * domain's pages. This is used to allow stub-domain pvfb export to
> -         * dom0, until pvfb supports granted mappings. At that time this
> -         * minor hack can go away.
> +         * If the real page owner is not the domain specified in the
> +         * hypercall then establish that the specified domain has
> +         * mapping privilege over the page owner.
> +         * This is used to allow stub-domain pvfb export to dom0. It is
> +         * also used to allow a privileged PV domain to map mfns using
> +         * DOMID_SELF, which is needed for mapping guest resources such
> +         * grant table frames.
>           */
> -        if ( (real_pg_owner == NULL) || (pg_owner == l1e_owner) ||
> +        if ( (real_pg_owner == NULL) ||
>               xsm_priv_mapping(XSM_TARGET, pg_owner, real_pg_owner) )
>          {
>              gdprintk(XENLOG_WARNING,
> -- 
> 2.11.0
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

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

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

* Re: [PATCH v2 REPOST 09/12] x86/hvm/ioreq: simplify code and use consistent naming
  2017-08-22 14:51 ` [PATCH v2 REPOST 09/12] x86/hvm/ioreq: simplify code and use consistent naming Paul Durrant
@ 2017-08-24 17:02   ` Roger Pau Monné
  2017-08-25 10:18     ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Roger Pau Monné @ 2017-08-24 17:02 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Jan Beulich, Andrew Cooper

On Tue, Aug 22, 2017 at 03:51:03PM +0100, Paul Durrant wrote:
> This patch re-works much of the IOREQ server initialization and teardown
> code:
> 
> - The hvm_map/unmap_ioreq_gfn() functions are expanded to call through
>   to hvm_alloc/free_ioreq_gfn() rather than expecting them to be called
>   separately by outer functions.
> - Several functions now test the validity of the hvm_ioreq_page gfn value
>   to determine whether they need to act. This means can be safely called
>   for the bufioreq page even when it is not used.
> - hvm_add/remove_ioreq_gfn() simply return in the case of the default
>   IOREQ server so callers no longer need to test before calling.
> - hvm_ioreq_server_setup_pages() is renamed to hvm_ioreq_server_map_pages()
>   to mirror the existing hvm_ioreq_server_unmap_pages().
> 
> All of this significantly shortens the code.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> ---
>  xen/arch/x86/hvm/ioreq.c | 181 ++++++++++++++++++-----------------------------
>  1 file changed, 69 insertions(+), 112 deletions(-)
> 
> diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
> index 5737082238..edfb394c59 100644
> --- a/xen/arch/x86/hvm/ioreq.c
> +++ b/xen/arch/x86/hvm/ioreq.c
> @@ -181,63 +181,76 @@ bool handle_hvm_io_completion(struct vcpu *v)
>      return true;
>  }
>  
> -static int hvm_alloc_ioreq_gfn(struct domain *d, unsigned long *gfn)
> +static unsigned long hvm_alloc_ioreq_gfn(struct hvm_ioreq_server *s)

gfn_t as the return type instead? I see that you are moving it, so I
won't insist (I assume there's also some other refactoring involved in
making this return gfn_t). I see there are also further uses of
unsigned long to store gfns, I'm not going to point those out.

>  {
> +    struct domain *d = s->domain;
>      unsigned int i;
> -    int rc;
>  
> -    rc = -ENOMEM;
> +    ASSERT(!s->is_default);
> +
>      for ( i = 0; i < sizeof(d->arch.hvm_domain.ioreq_gfn.mask) * 8; i++ )
>      {
>          if ( test_and_clear_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask) )
>          {

The braces are not strictly needed anymore, but that's a question of
taste.

> -            *gfn = d->arch.hvm_domain.ioreq_gfn.base + i;
> -            rc = 0;
> -            break;
> +            return d->arch.hvm_domain.ioreq_gfn.base + i;
>          }
>      }
>  
> -    return rc;
> +    return gfn_x(INVALID_GFN);
>  }
>  
> -static void hvm_free_ioreq_gfn(struct domain *d, unsigned long gfn)
> +static void hvm_free_ioreq_gfn(struct hvm_ioreq_server *s,
> +                               unsigned long gfn)
>  {
> +    struct domain *d = s->domain;
>      unsigned int i = gfn - d->arch.hvm_domain.ioreq_gfn.base;
>  
> -    if ( gfn != gfn_x(INVALID_GFN) )
> -        set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
> +    ASSERT(!s->is_default);

I would maybe add a gfn != gfn_x(INVALID_GFN) in the ASSERT.

> +
> +    set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
>  }
>  
> -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool buf)
> +static void hvm_unmap_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)

I'm not sure if you need the buf parameter, it seems in all cases you
want to unmap everything when calling hvm_unmap_ioreq_gfn? (same
applies to hvm_remove_ioreq_gfn and hvm_add_ioreq_gfn)

>  static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
> -                                      unsigned long ioreq_gfn,
> -                                      unsigned long bufioreq_gfn)
> -{
> -    int rc;
> -
> -    rc = hvm_map_ioreq_page(s, false, ioreq_gfn);
> -    if ( rc )
> -        return rc;
> -
> -    if ( bufioreq_gfn != gfn_x(INVALID_GFN) )
> -        rc = hvm_map_ioreq_page(s, true, bufioreq_gfn);
> -
> -    if ( rc )
> -        hvm_unmap_ioreq_page(s, false);
> -
> -    return rc;
> -}
> -
> -static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
> -                                        bool handle_bufioreq)
> +                                      bool handle_bufioreq)
>  {
> -    struct domain *d = s->domain;
> -    unsigned long ioreq_gfn = gfn_x(INVALID_GFN);
> -    unsigned long bufioreq_gfn = gfn_x(INVALID_GFN);
> -    int rc;
> -
> -    if ( s->is_default )
> -    {
> -        /*
> -         * The default ioreq server must handle buffered ioreqs, for
> -         * backwards compatibility.
> -         */
> -        ASSERT(handle_bufioreq);
> -        return hvm_ioreq_server_map_pages(s,
> -                   d->arch.hvm_domain.params[HVM_PARAM_IOREQ_PFN],
> -                   d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN]);
> -    }
> +    int rc = -ENOMEM;

No need to set rc, you are just overwriting it in the next line.

Roger.

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

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

* Re: [PATCH v2 REPOST 10/12] x86/hvm/ioreq: use gfn_t in struct hvm_ioreq_page
  2017-08-22 14:51 ` [PATCH v2 REPOST 10/12] x86/hvm/ioreq: use gfn_t in struct hvm_ioreq_page Paul Durrant
@ 2017-08-24 17:05   ` Roger Pau Monné
  0 siblings, 0 replies; 56+ messages in thread
From: Roger Pau Monné @ 2017-08-24 17:05 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Jan Beulich, Andrew Cooper

On Tue, Aug 22, 2017 at 03:51:04PM +0100, Paul Durrant wrote:
> This patch adjusts the IOREQ server code to use type-safe gfn_t values
> where possible. No functional change.

Oh, forget my comment on the previous patch then.

Thanks.

> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Reviewed-by: Roger Pau Monné <roger.pau@citrix.com>

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

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

* Re: [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted
  2017-08-22 14:51 ` [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted Paul Durrant
@ 2017-08-24 17:21   ` Roger Pau Monné
  2017-08-25  9:52     ` Paul Durrant
  2017-08-28 15:08   ` Wei Liu
  1 sibling, 1 reply; 56+ messages in thread
From: Roger Pau Monné @ 2017-08-24 17:21 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Ian Jackson, Tim Deegan, Jan Beulich, xen-devel

On Tue, Aug 22, 2017 at 03:51:05PM +0100, Paul Durrant wrote:
> A subsequent patch will introduce a new scheme to allow an emulator to
> map IOREQ server pages directly from Xen rather than the guest P2M.
> 
> This patch lays the groundwork for that change by deferring mapping of
> gfns until their values are requested by an emulator. To that end, the
> pad field of the xen_dm_op_get_ioreq_server_info structure is re-purposed
> to a flags field and new flag, XEN_DMOP_no_gfns, defined which modifies the
> behaviour of XEN_DMOP_get_ioreq_server_info to allow the caller to avoid
> requesting the gfn values.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: George Dunlap <George.Dunlap@eu.citrix.com>
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Tim Deegan <tim@xen.org>
> ---
>  tools/libs/devicemodel/core.c                   |  8 +++++
>  tools/libs/devicemodel/include/xendevicemodel.h |  6 ++--
>  xen/arch/x86/hvm/dm.c                           |  9 +++--
>  xen/arch/x86/hvm/ioreq.c                        | 44 ++++++++++++++-----------
>  xen/include/asm-x86/hvm/domain.h                |  2 +-
>  xen/include/public/hvm/dm_op.h                  | 32 ++++++++++--------
>  6 files changed, 61 insertions(+), 40 deletions(-)
> 
> diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c
> index fcb260d29b..907c894e77 100644
> --- a/tools/libs/devicemodel/core.c
> +++ b/tools/libs/devicemodel/core.c
> @@ -188,6 +188,14 @@ int xendevicemodel_get_ioreq_server_info(
>  
>      data->id = id;
>  
> +    /*
> +     * If the caller is not requesting gfn values then instruct the
> +     * hypercall not to retrieve them as this may cause them to be
> +     * mapped.
> +     */
> +    if (!ioreq_gfn && !bufioreq_gfn)
> +        data->flags = XEN_DMOP_no_gfns;

Since this is memset to 0 I would use |= here, in case someone adds a
new flag further up.

Also, seeing the code below, don't you need to retry on error in case
you are dealing with an old hypervisor version? (that will choke on pad
being set).

> diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-x86/hvm/domain.h
> index 7b93d10209..b8bcd559a5 100644
> --- a/xen/include/asm-x86/hvm/domain.h
> +++ b/xen/include/asm-x86/hvm/domain.h
> @@ -70,7 +70,7 @@ struct hvm_ioreq_server {
>      evtchn_port_t          bufioreq_evtchn;
>      struct rangeset        *range[NR_IO_RANGE_TYPES];

I would place bufioreq_handling here in order to have a more compact
structure layout.

>      bool                   enabled;
> -    bool                   bufioreq_atomic;
> +    int                    bufioreq_handling;
>      bool                   is_default;
>  };
>  
> diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h
> index 6bbab5fca3..9677bd74e7 100644
> --- a/xen/include/public/hvm/dm_op.h
> +++ b/xen/include/public/hvm/dm_op.h
> @@ -79,28 +79,34 @@ struct xen_dm_op_create_ioreq_server {
>   * XEN_DMOP_get_ioreq_server_info: Get all the information necessary to
>   *                                 access IOREQ Server <id>.
>   *
> - * The emulator needs to map the synchronous ioreq structures and buffered
> - * ioreq ring (if it exists) that Xen uses to request emulation. These are
> - * hosted in the target domain's gmfns <ioreq_gfn> and <bufioreq_gfn>
> - * respectively. In addition, if the IOREQ Server is handling buffered
> - * emulation requests, the emulator needs to bind to event channel
> - * <bufioreq_port> to listen for them. (The event channels used for
> - * synchronous emulation requests are specified in the per-CPU ioreq
> - * structures in <ioreq_gfn>).
> - * If the IOREQ Server is not handling buffered emulation requests then the
> - * values handed back in <bufioreq_gfn> and <bufioreq_port> will both be 0.
> + * If the IOREQ Server is handling buffered emulation requests, the
> + * emulator needs to bind to event channel <bufioreq_port> to listen for
> + * them. (The event channels used for synchronous emulation requests are
> + * specified in the per-CPU ioreq structures).
> + * In addition, if the XENMEM_acquire_resource memory op cannot be used,
> + * the emulator will need to map the synchronous ioreq structures and
> + * buffered ioreq ring (if it exists) from guest memory. If <flags> does
> + * not contain XEN_DMOP_no_gfns then these pages will be made available and
> + * the frame numbers passed back in gfns <ioreq_gfn> and <bufioreq_gfn>
> + * respectively. (If the IOREQ Server is not handling buffered emulation
> + * only <ioreq_gfn> will be valid).
>   */
>  #define XEN_DMOP_get_ioreq_server_info 2
>  
>  struct xen_dm_op_get_ioreq_server_info {
>      /* IN - server id */
>      ioservid_t id;
> -    uint16_t pad;
> +    /* IN - flags */
> +    uint16_t flags;

Don't you need to bump some version or similar to let the consumers
know this field is now available? Or that's done using a compile test?

> +#define _XEN_DMOP_no_gfns 0
> +#define XEN_DMOP_no_gfns (1u << _XEN_DMOP_no_gfns)
> +
>      /* OUT - buffered ioreq port */
>      evtchn_port_t bufioreq_port;
> -    /* OUT - sync ioreq gfn */
> +    /* OUT - sync ioreq gfn (see block comment above) */
>      uint64_aligned_t ioreq_gfn;
> -    /* OUT - buffered ioreq gfn */
> +    /* OUT - buffered ioreq gfn (see block comment above)*/
>      uint64_aligned_t bufioreq_gfn;
>  };
>  
> -- 
> 2.11.0
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

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

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-22 14:51 ` [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type Paul Durrant
@ 2017-08-25  9:32   ` Roger Pau Monné
  2017-08-25  9:46     ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Roger Pau Monné @ 2017-08-25  9:32 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Ian Jackson, Tim Deegan, Jan Beulich, xen-devel

On Tue, Aug 22, 2017 at 03:51:06PM +0100, Paul Durrant wrote:
> ... XENMEM_resource_ioreq_server
> 
> This patch adds support for a new resource type that can be mapped using
> the XENMEM_acquire_resource memory op.
> 
> If an emulator makes use of this resource type then, instead of mapping
> gfns, the IOREQ server will allocate pages from the heap. These pages
> will never be present in the P2M of the guest at any point and so are
> not vulnerable to any direct attack by the guest. They are only ever
> accessible by Xen and any domain that has mapping privilege over the
> guest (which may or may not be limited to the domain running the emulator).
> 
> NOTE: Use of the new resource type is not compatible with use of
>       XEN_DMOP_get_ioreq_server_info unless the XEN_DMOP_no_gfns flag is
>       set.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> ---
> Cc: Jan Beulich <jbeulich@suse.com>
> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> Cc: George Dunlap <George.Dunlap@eu.citrix.com>
> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>
> Cc: Tim Deegan <tim@xen.org>
> Cc: Wei Liu <wei.liu2@citrix.com>
> ---
>  xen/arch/x86/hvm/ioreq.c        | 136 ++++++++++++++++++++++++++++++++++++++++
>  xen/arch/x86/mm.c               |  27 ++++++++
>  xen/include/asm-x86/hvm/ioreq.h |   2 +
>  xen/include/public/hvm/dm_op.h  |   4 ++
>  xen/include/public/memory.h     |   3 +
>  5 files changed, 172 insertions(+)
> 
> diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
> index 795c198f95..9e6838dab6 100644
> --- a/xen/arch/x86/hvm/ioreq.c
> +++ b/xen/arch/x86/hvm/ioreq.c
> @@ -231,6 +231,15 @@ static int hvm_map_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
>      struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
>      int rc;
>  
> +    if ( iorp->page )
> +    {
> +        /* Make sure the page has not been allocated */
> +        if ( gfn_eq(iorp->gfn, INVALID_GFN) )
> +            return -EPERM;
> +
> +        return 0;

EEXIST? (See comment below, which I think also applies here).

> +    }
> +
>      if ( d->is_dying )
>          return -EINVAL;
>  
> @@ -253,6 +262,60 @@ static int hvm_map_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
>      return rc;
>  }
>  
> +static int hvm_alloc_ioreq_mfn(struct hvm_ioreq_server *s, bool buf)
> +{
> +    struct domain *currd = current->domain;
> +    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> +
> +    if ( iorp->page )
> +    {
> +        /* Make sure the page has not been mapped */
> +        if ( !gfn_eq(iorp->gfn, INVALID_GFN) )
> +            return -EPERM;
> +
> +        return 0;

Shouldn't this return EEXIST? Page has already been allocated by a
previous call AFAICT, and it seems like a possible error/misbehavior
to try to do it twice.

> +    }
> +
> +    /*
> +     * Allocated IOREQ server pages are assigned to the emulating
> +     * domain, not the target domain. This is because the emulator is
> +     * likely to be destroyed after the target domain has been torn
> +     * down, and we must use MEMF_no_refcount otherwise page allocation
> +     * could fail if the emulating domain has already reached its
> +     * maximum allocation.
> +     */
> +    iorp->page = alloc_domheap_page(currd, MEMF_no_refcount);

I don't really like the fact that the page is not accounted for any
domain, but I can see the point in doing it like that (which you
argument in the comment).

IIRC there where talks about tightening the accounting of memory
pages, so that ideally everything would be accounted for in the memory
assigned to the domain.

Just some random through, but could the toolstack set aside some
memory pages (ie: not map them into the domain p2m), that could then
be used by this? (not asking you to do this here)

And how many pages are we expecting to use for each domain? I assume
the number will be quite low.

> +    if ( !iorp->page )
> +        return -ENOMEM;
> +
> +    get_page(iorp->page, currd);

Do you really need this get_page? (page is already assigned to currd).

> +
> +    iorp->va = __map_domain_page_global(iorp->page);
> +    if ( !iorp->va )
> +    {
> +        put_page(iorp->page);
> +        iorp->page = NULL;
> +        return -ENOMEM;
> +    }
> +
> +    clear_page(iorp->va);
> +    return 0;
> +}
> +
> +static void hvm_free_ioreq_mfn(struct hvm_ioreq_server *s, bool buf)
> +{
> +    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> +
> +    if ( !iorp->page )
> +        return;
> +
> +    unmap_domain_page_global(iorp->va);
> +    iorp->va = NULL;
> +
> +    put_page(iorp->page);
> +    iorp->page = NULL;
> +}
> +
>  bool is_ioreq_server_page(struct domain *d, const struct page_info *page)
>  {
>      const struct hvm_ioreq_server *s;
> @@ -457,6 +520,27 @@ static void hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s)
>      hvm_unmap_ioreq_gfn(s, false);
>  }
>  
> +static int hvm_ioreq_server_alloc_pages(struct hvm_ioreq_server *s)
> +{
> +    int rc = -ENOMEM;
> +
> +    rc = hvm_alloc_ioreq_mfn(s, false);
> +
> +    if ( !rc && (s->bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF) )
> +        rc = hvm_alloc_ioreq_mfn(s, true);
> +
> +    if ( rc )
> +        hvm_free_ioreq_mfn(s, false);
> +
> +    return rc;
> +}
> +
> +static void hvm_ioreq_server_free_pages(struct hvm_ioreq_server *s)
> +{
> +    hvm_free_ioreq_mfn(s, true);
> +    hvm_free_ioreq_mfn(s, false);
> +}
> +
>  static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server *s)
>  {
>      unsigned int i;
> @@ -583,7 +667,18 @@ static int hvm_ioreq_server_init(struct hvm_ioreq_server *s,
>  
>   fail_add:
>      hvm_ioreq_server_remove_all_vcpus(s);
> +
> +    /*
> +     * NOTE: It is safe to call both hvm_ioreq_server_unmap_pages() and
> +     *       hvm_ioreq_server_free_pages() in that order.
> +     *       This is because the former will do nothing if the pages
> +     *       are not mapped, leaving the page to be freed by the latter.
> +     *       However if the pages are mapped then the former will set
> +     *       the page_info pointer to NULL, meaning the latter will do
> +     *       nothing.
> +     */
>      hvm_ioreq_server_unmap_pages(s);
> +    hvm_ioreq_server_free_pages(s);
>  
>      return rc;
>  }
> @@ -593,6 +688,7 @@ static void hvm_ioreq_server_deinit(struct hvm_ioreq_server *s)
>      ASSERT(!s->enabled);
>      hvm_ioreq_server_remove_all_vcpus(s);
>      hvm_ioreq_server_unmap_pages(s);
> +    hvm_ioreq_server_free_pages(s);
>      hvm_ioreq_server_free_rangesets(s);
>  }
>  
> @@ -745,6 +841,9 @@ int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
>              rc = hvm_ioreq_server_map_pages(s);
>              if ( rc )
>                  break;
> +
> +            gdprintk(XENLOG_INFO, "d%d ioreq server %u using gfns\n",
> +                     d->domain_id, s->id);
>          }
>  
>          if ( ioreq_gfn )
> @@ -767,6 +866,43 @@ int hvm_get_ioreq_server_info(struct domain *d, ioservid_t id,
>      return rc;
>  }
>  
> +mfn_t hvm_get_ioreq_server_frame(struct domain *d, ioservid_t id,
> +                                 unsigned int idx)
> +{
> +    struct hvm_ioreq_server *s;
> +    mfn_t mfn = INVALID_MFN;
> +
> +    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
> +
> +    list_for_each_entry ( s,
> +                          &d->arch.hvm_domain.ioreq_server.list,
> +                          list_entry )
> +    {
> +        int rc;
> +
> +        if ( s == d->arch.hvm_domain.default_ioreq_server )
> +            continue;

s->is_default

> +
> +        if ( s->id != id )
> +            continue;
> +
> +        rc = hvm_ioreq_server_alloc_pages(s);
> +        if ( rc )
> +            break;
> +
> +        if ( idx == 0 )
> +            mfn = _mfn(page_to_mfn(s->bufioreq.page));
> +        else if ( idx == 1 )
> +            mfn = _mfn(page_to_mfn(s->ioreq.page));
> +
> +        break;
> +    }
> +
> +    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
> +
> +    return mfn;
> +}
> +
>  int hvm_map_io_range_to_ioreq_server(struct domain *d, ioservid_t id,
>                                       uint32_t type, uint64_t start,
>                                       uint64_t end)
> diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> index 4e86f0a2ab..3e845af0e4 100644
> --- a/xen/arch/x86/mm.c
> +++ b/xen/arch/x86/mm.c
> @@ -122,6 +122,7 @@
>  #include <asm/fixmap.h>
>  #include <asm/io_apic.h>
>  #include <asm/pci.h>
> +#include <asm/hvm/ioreq.h>
>  
>  /* Mapping of the fixmap space needed early. */
>  l1_pgentry_t __section(".bss.page_aligned") __aligned(PAGE_SIZE)
> @@ -4744,6 +4745,27 @@ static int xenmem_acquire_grant_table(struct domain *d,
>      return 0;
>  }
>  
> +static int xenmem_acquire_ioreq_server(struct domain *d,
> +                                       unsigned int id,
> +                                       unsigned long frame,
> +                                       unsigned long nr_frames,
> +                                       unsigned long mfn_list[])

mfn_t maybe?

> +{
> +    unsigned int i;

Either nr_frames wants to be unsigned int, or this needs to be
unsigned long.

> +
> +    for ( i = 0; i < nr_frames; i++ )
> +    {
> +        mfn_t mfn = hvm_get_ioreq_server_frame(d, id, frame + i);

Here you use unsigned long as the last parameter to
hvm_get_ioreq_server_frame, while the function takes an unsigned int.

Thanks, Roger.

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

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-25  9:32   ` Roger Pau Monné
@ 2017-08-25  9:46     ` Paul Durrant
  2017-08-25  9:53       ` Roger Pau Monne
                         ` (2 more replies)
  0 siblings, 3 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-25  9:46 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	George Dunlap, Jan Beulich, Ian Jackson, xen-devel

> -----Original Message-----
> From: Roger Pau Monne
> Sent: 25 August 2017 10:32
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>; Wei Liu <wei.liu2@citrix.com>; George Dunlap
> <George.Dunlap@citrix.com>; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Ian Jackson <Ian.Jackson@citrix.com>; Tim
> (Xen.org) <tim@xen.org>; Jan Beulich <jbeulich@suse.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a
> new mappable resource type...
> 
> On Tue, Aug 22, 2017 at 03:51:06PM +0100, Paul Durrant wrote:
> > ... XENMEM_resource_ioreq_server
> >
> > This patch adds support for a new resource type that can be mapped using
> > the XENMEM_acquire_resource memory op.
> >
> > If an emulator makes use of this resource type then, instead of mapping
> > gfns, the IOREQ server will allocate pages from the heap. These pages
> > will never be present in the P2M of the guest at any point and so are
> > not vulnerable to any direct attack by the guest. They are only ever
> > accessible by Xen and any domain that has mapping privilege over the
> > guest (which may or may not be limited to the domain running the
> emulator).
> >
> > NOTE: Use of the new resource type is not compatible with use of
> >       XEN_DMOP_get_ioreq_server_info unless the XEN_DMOP_no_gfns
> flag is
> >       set.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > Cc: Jan Beulich <jbeulich@suse.com>
> > Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> > Cc: George Dunlap <George.Dunlap@eu.citrix.com>
> > Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> > Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > Cc: Tim Deegan <tim@xen.org>
> > Cc: Wei Liu <wei.liu2@citrix.com>
> > ---
> >  xen/arch/x86/hvm/ioreq.c        | 136
> ++++++++++++++++++++++++++++++++++++++++
> >  xen/arch/x86/mm.c               |  27 ++++++++
> >  xen/include/asm-x86/hvm/ioreq.h |   2 +
> >  xen/include/public/hvm/dm_op.h  |   4 ++
> >  xen/include/public/memory.h     |   3 +
> >  5 files changed, 172 insertions(+)
> >
> > diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
> > index 795c198f95..9e6838dab6 100644
> > --- a/xen/arch/x86/hvm/ioreq.c
> > +++ b/xen/arch/x86/hvm/ioreq.c
> > @@ -231,6 +231,15 @@ static int hvm_map_ioreq_gfn(struct
> hvm_ioreq_server *s, bool buf)
> >      struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> >      int rc;
> >
> > +    if ( iorp->page )
> > +    {
> > +        /* Make sure the page has not been allocated */
> > +        if ( gfn_eq(iorp->gfn, INVALID_GFN) )
> > +            return -EPERM;
> > +
> > +        return 0;
> 
> EEXIST? (See comment below, which I think also applies here).
> 
> > +    }
> > +
> >      if ( d->is_dying )
> >          return -EINVAL;
> >
> > @@ -253,6 +262,60 @@ static int hvm_map_ioreq_gfn(struct
> hvm_ioreq_server *s, bool buf)
> >      return rc;
> >  }
> >
> > +static int hvm_alloc_ioreq_mfn(struct hvm_ioreq_server *s, bool buf)
> > +{
> > +    struct domain *currd = current->domain;
> > +    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> > +
> > +    if ( iorp->page )
> > +    {
> > +        /* Make sure the page has not been mapped */
> > +        if ( !gfn_eq(iorp->gfn, INVALID_GFN) )
> > +            return -EPERM;
> > +
> > +        return 0;
> 
> Shouldn't this return EEXIST? Page has already been allocated by a
> previous call AFAICT, and it seems like a possible error/misbehavior
> to try to do it twice.
> 

The checks are there to prevent a caller from trying to mix the legacy and new methods of mapping ioreq server pages so EPERM (i.e. 'operation not permitted') seems like the correct error. I agree that it's not obvious, at this inner level, that I do think this is right. I'm open to debate about this though.

> > +    }
> > +
> > +    /*
> > +     * Allocated IOREQ server pages are assigned to the emulating
> > +     * domain, not the target domain. This is because the emulator is
> > +     * likely to be destroyed after the target domain has been torn
> > +     * down, and we must use MEMF_no_refcount otherwise page
> allocation
> > +     * could fail if the emulating domain has already reached its
> > +     * maximum allocation.
> > +     */
> > +    iorp->page = alloc_domheap_page(currd, MEMF_no_refcount);
> 
> I don't really like the fact that the page is not accounted for any
> domain, but I can see the point in doing it like that (which you
> argument in the comment).
> 
> IIRC there where talks about tightening the accounting of memory
> pages, so that ideally everything would be accounted for in the memory
> assigned to the domain.
> 
> Just some random through, but could the toolstack set aside some
> memory pages (ie: not map them into the domain p2m), that could then
> be used by this? (not asking you to do this here)
> 
> And how many pages are we expecting to use for each domain? I assume
> the number will be quite low.
> 

Yes, I agree the use on MEMF_no_refcount is not ideal and you do highlight an issue: I don't think there is currently an upper limit on the number of ioreq servers so an emulating domain could exhaust memory using the new scheme. I'll need to introduce a limit to avoid that.

> > +    if ( !iorp->page )
> > +        return -ENOMEM;
> > +
> > +    get_page(iorp->page, currd);
> 
> Do you really need this get_page? (page is already assigned to currd).
> 

Hmm. I thought MEMF_no_refcount modified that behaviour, but I may have got confused with MEMF_no_owner.

> > +
> > +    iorp->va = __map_domain_page_global(iorp->page);
> > +    if ( !iorp->va )
> > +    {
> > +        put_page(iorp->page);
> > +        iorp->page = NULL;
> > +        return -ENOMEM;
> > +    }
> > +
> > +    clear_page(iorp->va);
> > +    return 0;
> > +}
> > +
> > +static void hvm_free_ioreq_mfn(struct hvm_ioreq_server *s, bool buf)
> > +{
> > +    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> > +
> > +    if ( !iorp->page )
> > +        return;
> > +
> > +    unmap_domain_page_global(iorp->va);
> > +    iorp->va = NULL;
> > +
> > +    put_page(iorp->page);
> > +    iorp->page = NULL;
> > +}
> > +
> >  bool is_ioreq_server_page(struct domain *d, const struct page_info
> *page)
> >  {
> >      const struct hvm_ioreq_server *s;
> > @@ -457,6 +520,27 @@ static void
> hvm_ioreq_server_unmap_pages(struct hvm_ioreq_server *s)
> >      hvm_unmap_ioreq_gfn(s, false);
> >  }
> >
> > +static int hvm_ioreq_server_alloc_pages(struct hvm_ioreq_server *s)
> > +{
> > +    int rc = -ENOMEM;
> > +
> > +    rc = hvm_alloc_ioreq_mfn(s, false);
> > +
> > +    if ( !rc && (s->bufioreq_handling != HVM_IOREQSRV_BUFIOREQ_OFF) )
> > +        rc = hvm_alloc_ioreq_mfn(s, true);
> > +
> > +    if ( rc )
> > +        hvm_free_ioreq_mfn(s, false);
> > +
> > +    return rc;
> > +}
> > +
> > +static void hvm_ioreq_server_free_pages(struct hvm_ioreq_server *s)
> > +{
> > +    hvm_free_ioreq_mfn(s, true);
> > +    hvm_free_ioreq_mfn(s, false);
> > +}
> > +
> >  static void hvm_ioreq_server_free_rangesets(struct hvm_ioreq_server
> *s)
> >  {
> >      unsigned int i;
> > @@ -583,7 +667,18 @@ static int hvm_ioreq_server_init(struct
> hvm_ioreq_server *s,
> >
> >   fail_add:
> >      hvm_ioreq_server_remove_all_vcpus(s);
> > +
> > +    /*
> > +     * NOTE: It is safe to call both hvm_ioreq_server_unmap_pages() and
> > +     *       hvm_ioreq_server_free_pages() in that order.
> > +     *       This is because the former will do nothing if the pages
> > +     *       are not mapped, leaving the page to be freed by the latter.
> > +     *       However if the pages are mapped then the former will set
> > +     *       the page_info pointer to NULL, meaning the latter will do
> > +     *       nothing.
> > +     */
> >      hvm_ioreq_server_unmap_pages(s);
> > +    hvm_ioreq_server_free_pages(s);
> >
> >      return rc;
> >  }
> > @@ -593,6 +688,7 @@ static void hvm_ioreq_server_deinit(struct
> hvm_ioreq_server *s)
> >      ASSERT(!s->enabled);
> >      hvm_ioreq_server_remove_all_vcpus(s);
> >      hvm_ioreq_server_unmap_pages(s);
> > +    hvm_ioreq_server_free_pages(s);
> >      hvm_ioreq_server_free_rangesets(s);
> >  }
> >
> > @@ -745,6 +841,9 @@ int hvm_get_ioreq_server_info(struct domain *d,
> ioservid_t id,
> >              rc = hvm_ioreq_server_map_pages(s);
> >              if ( rc )
> >                  break;
> > +
> > +            gdprintk(XENLOG_INFO, "d%d ioreq server %u using gfns\n",
> > +                     d->domain_id, s->id);
> >          }
> >
> >          if ( ioreq_gfn )
> > @@ -767,6 +866,43 @@ int hvm_get_ioreq_server_info(struct domain *d,
> ioservid_t id,
> >      return rc;
> >  }
> >
> > +mfn_t hvm_get_ioreq_server_frame(struct domain *d, ioservid_t id,
> > +                                 unsigned int idx)
> > +{
> > +    struct hvm_ioreq_server *s;
> > +    mfn_t mfn = INVALID_MFN;
> > +
> > +    spin_lock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
> > +
> > +    list_for_each_entry ( s,
> > +                          &d->arch.hvm_domain.ioreq_server.list,
> > +                          list_entry )
> > +    {
> > +        int rc;
> > +
> > +        if ( s == d->arch.hvm_domain.default_ioreq_server )
> > +            continue;
> 
> s->is_default
> 
> > +
> > +        if ( s->id != id )
> > +            continue;
> > +
> > +        rc = hvm_ioreq_server_alloc_pages(s);
> > +        if ( rc )
> > +            break;
> > +
> > +        if ( idx == 0 )
> > +            mfn = _mfn(page_to_mfn(s->bufioreq.page));
> > +        else if ( idx == 1 )
> > +            mfn = _mfn(page_to_mfn(s->ioreq.page));
> > +
> > +        break;
> > +    }
> > +
> > +    spin_unlock_recursive(&d->arch.hvm_domain.ioreq_server.lock);
> > +
> > +    return mfn;
> > +}
> > +
> >  int hvm_map_io_range_to_ioreq_server(struct domain *d, ioservid_t id,
> >                                       uint32_t type, uint64_t start,
> >                                       uint64_t end)
> > diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> > index 4e86f0a2ab..3e845af0e4 100644
> > --- a/xen/arch/x86/mm.c
> > +++ b/xen/arch/x86/mm.c
> > @@ -122,6 +122,7 @@
> >  #include <asm/fixmap.h>
> >  #include <asm/io_apic.h>
> >  #include <asm/pci.h>
> > +#include <asm/hvm/ioreq.h>
> >
> >  /* Mapping of the fixmap space needed early. */
> >  l1_pgentry_t __section(".bss.page_aligned") __aligned(PAGE_SIZE)
> > @@ -4744,6 +4745,27 @@ static int xenmem_acquire_grant_table(struct
> domain *d,
> >      return 0;
> >  }
> >
> > +static int xenmem_acquire_ioreq_server(struct domain *d,
> > +                                       unsigned int id,
> > +                                       unsigned long frame,
> > +                                       unsigned long nr_frames,
> > +                                       unsigned long mfn_list[])
> 
> mfn_t maybe?

No. The list is mapped in so use of typesafe variants is not appropriate.

> 
> > +{
> > +    unsigned int i;
> 
> Either nr_frames wants to be unsigned int, or this needs to be
> unsigned long.

Not sure which. I'll check.

> 
> > +
> > +    for ( i = 0; i < nr_frames; i++ )
> > +    {
> > +        mfn_t mfn = hvm_get_ioreq_server_frame(d, id, frame + i);
> 
> Here you use unsigned long as the last parameter to
> hvm_get_ioreq_server_frame, while the function takes an unsigned int.

Ok.

Thanks,

  Paul

> 
> Thanks, Roger.

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

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

* Re: [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted
  2017-08-24 17:21   ` Roger Pau Monné
@ 2017-08-25  9:52     ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-25  9:52 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	George Dunlap, Jan Beulich, Ian Jackson, xen-devel

> -----Original Message-----
> From: Roger Pau Monne
> Sent: 24 August 2017 18:21
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>; Wei Liu <wei.liu2@citrix.com>; George Dunlap
> <George.Dunlap@citrix.com>; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Ian Jackson <Ian.Jackson@citrix.com>; Tim
> (Xen.org) <tim@xen.org>; Jan Beulich <jbeulich@suse.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer
> mapping gfns until they are actually requsted
> 
> On Tue, Aug 22, 2017 at 03:51:05PM +0100, Paul Durrant wrote:
> > A subsequent patch will introduce a new scheme to allow an emulator to
> > map IOREQ server pages directly from Xen rather than the guest P2M.
> >
> > This patch lays the groundwork for that change by deferring mapping of
> > gfns until their values are requested by an emulator. To that end, the
> > pad field of the xen_dm_op_get_ioreq_server_info structure is re-
> purposed
> > to a flags field and new flag, XEN_DMOP_no_gfns, defined which modifies
> the
> > behaviour of XEN_DMOP_get_ioreq_server_info to allow the caller to
> avoid
> > requesting the gfn values.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > Cc: Ian Jackson <ian.jackson@eu.citrix.com>
> > Cc: Wei Liu <wei.liu2@citrix.com>
> > Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> > Cc: George Dunlap <George.Dunlap@eu.citrix.com>
> > Cc: Jan Beulich <jbeulich@suse.com>
> > Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
> > Cc: Stefano Stabellini <sstabellini@kernel.org>
> > Cc: Tim Deegan <tim@xen.org>
> > ---
> >  tools/libs/devicemodel/core.c                   |  8 +++++
> >  tools/libs/devicemodel/include/xendevicemodel.h |  6 ++--
> >  xen/arch/x86/hvm/dm.c                           |  9 +++--
> >  xen/arch/x86/hvm/ioreq.c                        | 44 ++++++++++++++-----------
> >  xen/include/asm-x86/hvm/domain.h                |  2 +-
> >  xen/include/public/hvm/dm_op.h                  | 32 ++++++++++--------
> >  6 files changed, 61 insertions(+), 40 deletions(-)
> >
> > diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c
> > index fcb260d29b..907c894e77 100644
> > --- a/tools/libs/devicemodel/core.c
> > +++ b/tools/libs/devicemodel/core.c
> > @@ -188,6 +188,14 @@ int xendevicemodel_get_ioreq_server_info(
> >
> >      data->id = id;
> >
> > +    /*
> > +     * If the caller is not requesting gfn values then instruct the
> > +     * hypercall not to retrieve them as this may cause them to be
> > +     * mapped.
> > +     */
> > +    if (!ioreq_gfn && !bufioreq_gfn)
> > +        data->flags = XEN_DMOP_no_gfns;
> 
> Since this is memset to 0 I would use |= here, in case someone adds a
> new flag further up.

Ok.

> 
> Also, seeing the code below, don't you need to retry on error in case
> you are dealing with an old hypervisor version? (that will choke on pad
> being set).
>

This is tools code so there should be no possibility of a mismatch with the hypervisor.
 
> > diff --git a/xen/include/asm-x86/hvm/domain.h b/xen/include/asm-
> x86/hvm/domain.h
> > index 7b93d10209..b8bcd559a5 100644
> > --- a/xen/include/asm-x86/hvm/domain.h
> > +++ b/xen/include/asm-x86/hvm/domain.h
> > @@ -70,7 +70,7 @@ struct hvm_ioreq_server {
> >      evtchn_port_t          bufioreq_evtchn;
> >      struct rangeset        *range[NR_IO_RANGE_TYPES];
> 
> I would place bufioreq_handling here in order to have a more compact
> structure layout.

Ok.

> 
> >      bool                   enabled;
> > -    bool                   bufioreq_atomic;
> > +    int                    bufioreq_handling;
> >      bool                   is_default;
> >  };
> >
> > diff --git a/xen/include/public/hvm/dm_op.h
> b/xen/include/public/hvm/dm_op.h
> > index 6bbab5fca3..9677bd74e7 100644
> > --- a/xen/include/public/hvm/dm_op.h
> > +++ b/xen/include/public/hvm/dm_op.h
> > @@ -79,28 +79,34 @@ struct xen_dm_op_create_ioreq_server {
> >   * XEN_DMOP_get_ioreq_server_info: Get all the information necessary
> to
> >   *                                 access IOREQ Server <id>.
> >   *
> > - * The emulator needs to map the synchronous ioreq structures and
> buffered
> > - * ioreq ring (if it exists) that Xen uses to request emulation. These are
> > - * hosted in the target domain's gmfns <ioreq_gfn> and <bufioreq_gfn>
> > - * respectively. In addition, if the IOREQ Server is handling buffered
> > - * emulation requests, the emulator needs to bind to event channel
> > - * <bufioreq_port> to listen for them. (The event channels used for
> > - * synchronous emulation requests are specified in the per-CPU ioreq
> > - * structures in <ioreq_gfn>).
> > - * If the IOREQ Server is not handling buffered emulation requests then
> the
> > - * values handed back in <bufioreq_gfn> and <bufioreq_port> will both be
> 0.
> > + * If the IOREQ Server is handling buffered emulation requests, the
> > + * emulator needs to bind to event channel <bufioreq_port> to listen for
> > + * them. (The event channels used for synchronous emulation requests
> are
> > + * specified in the per-CPU ioreq structures).
> > + * In addition, if the XENMEM_acquire_resource memory op cannot be
> used,
> > + * the emulator will need to map the synchronous ioreq structures and
> > + * buffered ioreq ring (if it exists) from guest memory. If <flags> does
> > + * not contain XEN_DMOP_no_gfns then these pages will be made
> available and
> > + * the frame numbers passed back in gfns <ioreq_gfn> and
> <bufioreq_gfn>
> > + * respectively. (If the IOREQ Server is not handling buffered emulation
> > + * only <ioreq_gfn> will be valid).
> >   */
> >  #define XEN_DMOP_get_ioreq_server_info 2
> >
> >  struct xen_dm_op_get_ioreq_server_info {
> >      /* IN - server id */
> >      ioservid_t id;
> > -    uint16_t pad;
> > +    /* IN - flags */
> > +    uint16_t flags;
> 
> Don't you need to bump some version or similar to let the consumers
> know this field is now available? Or that's done using a compile test?
> 

No. Again this is tools code so the caller should maintain compat based on the version of Xen.

Cheers,

  Paul

> > +#define _XEN_DMOP_no_gfns 0
> > +#define XEN_DMOP_no_gfns (1u << _XEN_DMOP_no_gfns)
> > +
> >      /* OUT - buffered ioreq port */
> >      evtchn_port_t bufioreq_port;
> > -    /* OUT - sync ioreq gfn */
> > +    /* OUT - sync ioreq gfn (see block comment above) */
> >      uint64_aligned_t ioreq_gfn;
> > -    /* OUT - buffered ioreq gfn */
> > +    /* OUT - buffered ioreq gfn (see block comment above)*/
> >      uint64_aligned_t bufioreq_gfn;
> >  };
> >
> > --
> > 2.11.0
> >
> >
> > _______________________________________________
> > Xen-devel mailing list
> > Xen-devel@lists.xen.org
> > https://lists.xen.org/xen-devel

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

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-25  9:46     ` Paul Durrant
@ 2017-08-25  9:53       ` Roger Pau Monne
  2017-08-25  9:58         ` Paul Durrant
  2017-08-29 11:36       ` George Dunlap
  2017-08-29 13:40       ` George Dunlap
  2 siblings, 1 reply; 56+ messages in thread
From: Roger Pau Monne @ 2017-08-25  9:53 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	George Dunlap, Jan Beulich, Ian Jackson, xen-devel

On Fri, Aug 25, 2017 at 10:46:48AM +0100, Paul Durrant wrote:
> > -----Original Message-----
> > From: Roger Pau Monne
> > > +static int hvm_alloc_ioreq_mfn(struct hvm_ioreq_server *s, bool buf)
> > > +{
> > > +    struct domain *currd = current->domain;
> > > +    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> > > +
> > > +    if ( iorp->page )
> > > +    {
> > > +        /* Make sure the page has not been mapped */
> > > +        if ( !gfn_eq(iorp->gfn, INVALID_GFN) )
> > > +            return -EPERM;
> > > +
> > > +        return 0;
> > 
> > Shouldn't this return EEXIST? Page has already been allocated by a
> > previous call AFAICT, and it seems like a possible error/misbehavior
> > to try to do it twice.
> > 
> 
> The checks are there to prevent a caller from trying to mix the legacy and new methods of mapping ioreq server pages so EPERM (i.e. 'operation not permitted') seems like the correct error. I agree that it's not obvious, at this inner level, that I do think this is right. I'm open to debate about this though.

Oh, I was referring to the 'return 0;', not the 'return -EPERM;' (that
looks fine to me).

The 'return 0;' means that the page is already setup (if I understood
this correctly), that's why I was wondering whether it should return
-EEXIST instead.

Roger.

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

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-25  9:53       ` Roger Pau Monne
@ 2017-08-25  9:58         ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-25  9:58 UTC (permalink / raw)
  To: Roger Pau Monne
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	George Dunlap, Jan Beulich, Ian Jackson, xen-devel

> -----Original Message-----
> From: Roger Pau Monne
> Sent: 25 August 2017 10:53
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; Stefano Stabellini
> <sstabellini@kernel.org>; Wei Liu <wei.liu2@citrix.com>; George Dunlap
> <George.Dunlap@citrix.com>; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Ian Jackson <Ian.Jackson@citrix.com>; Tim
> (Xen.org) <tim@xen.org>; Jan Beulich <jbeulich@suse.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a
> new mappable resource type...
> 
> On Fri, Aug 25, 2017 at 10:46:48AM +0100, Paul Durrant wrote:
> > > -----Original Message-----
> > > From: Roger Pau Monne
> > > > +static int hvm_alloc_ioreq_mfn(struct hvm_ioreq_server *s, bool buf)
> > > > +{
> > > > +    struct domain *currd = current->domain;
> > > > +    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
> > > > +
> > > > +    if ( iorp->page )
> > > > +    {
> > > > +        /* Make sure the page has not been mapped */
> > > > +        if ( !gfn_eq(iorp->gfn, INVALID_GFN) )
> > > > +            return -EPERM;
> > > > +
> > > > +        return 0;
> > >
> > > Shouldn't this return EEXIST? Page has already been allocated by a
> > > previous call AFAICT, and it seems like a possible error/misbehavior
> > > to try to do it twice.
> > >
> >
> > The checks are there to prevent a caller from trying to mix the legacy and
> new methods of mapping ioreq server pages so EPERM (i.e. 'operation not
> permitted') seems like the correct error. I agree that it's not obvious, at this
> inner level, that I do think this is right. I'm open to debate about this though.
> 
> Oh, I was referring to the 'return 0;', not the 'return -EPERM;' (that
> looks fine to me).
> 
> The 'return 0;' means that the page is already setup (if I understood
> this correctly), that's why I was wondering whether it should return
> -EEXIST instead.
> 

No, it has to be this way because of the 'on demand' nature of the allocation. If an emulator uses the new resource mapping scheme then the pages will be allocated on the first mapping attempt, but if the emulator unmaps and then re-maps that should succeed whereas if I return -EEXIST here then that would propagate back up through the second mapping hypercall.

  Paul

> Roger.

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

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

* Re: [PATCH v2 REPOST 02/12] x86/mm: allow a privileged PV domain to map guest mfns
  2017-08-24 16:33   ` Wei Liu
@ 2017-08-25 10:05     ` Paul Durrant
  2017-08-28 14:38       ` Wei Liu
  0 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-25 10:05 UTC (permalink / raw)
  Cc: xen-devel, Wei Liu, Jan Beulich, Andrew Cooper

> -----Original Message-----
> From: Wei Liu [mailto:wei.liu2@citrix.com]
> Sent: 24 August 2017 17:33
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>; Wei Liu
> <wei.liu2@citrix.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 02/12] x86/mm: allow a
> privileged PV domain to map guest mfns
> 
> On Tue, Aug 22, 2017 at 03:50:56PM +0100, Paul Durrant wrote:
> > In the case where a PV domain is mapping guest resources then it needs
> make
> > the HYPERVISOR_mmu_update call using DOMID_SELF, rather than the
> guest
> > domid, so that the passed in gmfn values are correctly treated as mfns
> > rather than gfns present in the guest p2m.
> >
> 
> What would be the callchain like in this case?

It's exactly like foreign mapping but passing DOMID_SELF. I.e. in privcmd (in a PV domain) you have an mfn in your hand that already belongs to you rather than the gmfn of a foreign domain.

> 
> I don't quite understand how this fits with the resource mapping code
> in this series.
> 

Because (for a PV caller) mapping a resource gives you back mfns that are assigned to the calling domain, and the most convenient way of using them is to use the existing code that normally deals with priv mapping from a foreign domain, but just allow it to use DOMID_SELF. This patch is all that's required to make that work.

  Paul

> > This patch removes a check which currently disallows mapping of a page
> when
> > the owner of the page tables matches the domain passed to
> > HYPERVISOR_mmu_update, but that domain is not the real owner of the
> page.
> > The check was introduced by patch d3c6a215ca9 ("x86: Clean up
> > get_page_from_l1e() to correctly distinguish between owner-of-pte and
> > owner-of-data-page in all cases") but it's not clear why it was needed.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > Cc: Jan Beulich <jbeulich@suse.com>
> > Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> > ---
> >  xen/arch/x86/mm.c | 13 ++++++++-----
> >  1 file changed, 8 insertions(+), 5 deletions(-)
> >
> > diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c
> > index 0abb1e284f..aaa9ff5197 100644
> > --- a/xen/arch/x86/mm.c
> > +++ b/xen/arch/x86/mm.c
> > @@ -989,12 +989,15 @@ get_page_from_l1e(
> >                     (real_pg_owner != dom_cow) ) )
> >      {
> >          /*
> > -         * Let privileged domains transfer the right to map their target
> > -         * domain's pages. This is used to allow stub-domain pvfb export to
> > -         * dom0, until pvfb supports granted mappings. At that time this
> > -         * minor hack can go away.
> > +         * If the real page owner is not the domain specified in the
> > +         * hypercall then establish that the specified domain has
> > +         * mapping privilege over the page owner.
> > +         * This is used to allow stub-domain pvfb export to dom0. It is
> > +         * also used to allow a privileged PV domain to map mfns using
> > +         * DOMID_SELF, which is needed for mapping guest resources such
> > +         * grant table frames.
> >           */
> > -        if ( (real_pg_owner == NULL) || (pg_owner == l1e_owner) ||
> > +        if ( (real_pg_owner == NULL) ||
> >               xsm_priv_mapping(XSM_TARGET, pg_owner, real_pg_owner) )
> >          {
> >              gdprintk(XENLOG_WARNING,
> > --
> > 2.11.0
> >
> >
> > _______________________________________________
> > Xen-devel mailing list
> > Xen-devel@lists.xen.org
> > https://lists.xen.org/xen-devel

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

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

* Re: [PATCH v2 REPOST 09/12] x86/hvm/ioreq: simplify code and use consistent naming
  2017-08-24 17:02   ` Roger Pau Monné
@ 2017-08-25 10:18     ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-25 10:18 UTC (permalink / raw)
  To: Roger Pau Monne; +Cc: xen-devel, Jan Beulich, Andrew Cooper

> -----Original Message-----
> From: Roger Pau Monne
> Sent: 24 August 2017 18:03
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 09/12] x86/hvm/ioreq: simplify
> code and use consistent naming
> 
> On Tue, Aug 22, 2017 at 03:51:03PM +0100, Paul Durrant wrote:
> > This patch re-works much of the IOREQ server initialization and teardown
> > code:
> >
> > - The hvm_map/unmap_ioreq_gfn() functions are expanded to call
> through
> >   to hvm_alloc/free_ioreq_gfn() rather than expecting them to be called
> >   separately by outer functions.
> > - Several functions now test the validity of the hvm_ioreq_page gfn value
> >   to determine whether they need to act. This means can be safely called
> >   for the bufioreq page even when it is not used.
> > - hvm_add/remove_ioreq_gfn() simply return in the case of the default
> >   IOREQ server so callers no longer need to test before calling.
> > - hvm_ioreq_server_setup_pages() is renamed to
> hvm_ioreq_server_map_pages()
> >   to mirror the existing hvm_ioreq_server_unmap_pages().
> >
> > All of this significantly shortens the code.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> > ---
> > Cc: Jan Beulich <jbeulich@suse.com>
> > Cc: Andrew Cooper <andrew.cooper3@citrix.com>
> > ---
> >  xen/arch/x86/hvm/ioreq.c | 181 ++++++++++++++++++----------------------
> -------
> >  1 file changed, 69 insertions(+), 112 deletions(-)
> >
> > diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
> > index 5737082238..edfb394c59 100644
> > --- a/xen/arch/x86/hvm/ioreq.c
> > +++ b/xen/arch/x86/hvm/ioreq.c
> > @@ -181,63 +181,76 @@ bool handle_hvm_io_completion(struct vcpu *v)
> >      return true;
> >  }
> >
> > -static int hvm_alloc_ioreq_gfn(struct domain *d, unsigned long *gfn)
> > +static unsigned long hvm_alloc_ioreq_gfn(struct hvm_ioreq_server *s)
> 
> gfn_t as the return type instead? I see that you are moving it, so I
> won't insist (I assume there's also some other refactoring involved in
> making this return gfn_t). I see there are also further uses of
> unsigned long to store gfns, I'm not going to point those out.
> 
> >  {
> > +    struct domain *d = s->domain;
> >      unsigned int i;
> > -    int rc;
> >
> > -    rc = -ENOMEM;
> > +    ASSERT(!s->is_default);
> > +
> >      for ( i = 0; i < sizeof(d->arch.hvm_domain.ioreq_gfn.mask) * 8; i++ )
> >      {
> >          if ( test_and_clear_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask) )
> >          {
> 
> The braces are not strictly needed anymore, but that's a question of
> taste.
> 
> > -            *gfn = d->arch.hvm_domain.ioreq_gfn.base + i;
> > -            rc = 0;
> > -            break;
> > +            return d->arch.hvm_domain.ioreq_gfn.base + i;
> >          }
> >      }
> >
> > -    return rc;
> > +    return gfn_x(INVALID_GFN);
> >  }
> >
> > -static void hvm_free_ioreq_gfn(struct domain *d, unsigned long gfn)
> > +static void hvm_free_ioreq_gfn(struct hvm_ioreq_server *s,
> > +                               unsigned long gfn)
> >  {
> > +    struct domain *d = s->domain;
> >      unsigned int i = gfn - d->arch.hvm_domain.ioreq_gfn.base;
> >
> > -    if ( gfn != gfn_x(INVALID_GFN) )
> > -        set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
> > +    ASSERT(!s->is_default);
> 
> I would maybe add a gfn != gfn_x(INVALID_GFN) in the ASSERT.
> 
> > +
> > +    set_bit(i, &d->arch.hvm_domain.ioreq_gfn.mask);
> >  }
> >
> > -static void hvm_unmap_ioreq_page(struct hvm_ioreq_server *s, bool
> buf)
> > +static void hvm_unmap_ioreq_gfn(struct hvm_ioreq_server *s, bool buf)
> 
> I'm not sure if you need the buf parameter, it seems in all cases you
> want to unmap everything when calling hvm_unmap_ioreq_gfn? (same
> applies to hvm_remove_ioreq_gfn and hvm_add_ioreq_gfn)

It's really just so map/unmap and add/remove mirror each other.

> 
> >  static int hvm_ioreq_server_map_pages(struct hvm_ioreq_server *s,
> > -                                      unsigned long ioreq_gfn,
> > -                                      unsigned long bufioreq_gfn)
> > -{
> > -    int rc;
> > -
> > -    rc = hvm_map_ioreq_page(s, false, ioreq_gfn);
> > -    if ( rc )
> > -        return rc;
> > -
> > -    if ( bufioreq_gfn != gfn_x(INVALID_GFN) )
> > -        rc = hvm_map_ioreq_page(s, true, bufioreq_gfn);
> > -
> > -    if ( rc )
> > -        hvm_unmap_ioreq_page(s, false);
> > -
> > -    return rc;
> > -}
> > -
> > -static int hvm_ioreq_server_setup_pages(struct hvm_ioreq_server *s,
> > -                                        bool handle_bufioreq)
> > +                                      bool handle_bufioreq)
> >  {
> > -    struct domain *d = s->domain;
> > -    unsigned long ioreq_gfn = gfn_x(INVALID_GFN);
> > -    unsigned long bufioreq_gfn = gfn_x(INVALID_GFN);
> > -    int rc;
> > -
> > -    if ( s->is_default )
> > -    {
> > -        /*
> > -         * The default ioreq server must handle buffered ioreqs, for
> > -         * backwards compatibility.
> > -         */
> > -        ASSERT(handle_bufioreq);
> > -        return hvm_ioreq_server_map_pages(s,
> > -                   d->arch.hvm_domain.params[HVM_PARAM_IOREQ_PFN],
> > -                   d->arch.hvm_domain.params[HVM_PARAM_BUFIOREQ_PFN]);
> > -    }
> > +    int rc = -ENOMEM;
> 
> No need to set rc, you are just overwriting it in the next line.
> 

Indeed.

Thanks,

  Paul

> Roger.

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

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

* Re: [PATCH v2 REPOST 02/12] x86/mm: allow a privileged PV domain to map guest mfns
  2017-08-25 10:05     ` Paul Durrant
@ 2017-08-28 14:38       ` Wei Liu
  2017-08-29  8:37         ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Wei Liu @ 2017-08-28 14:38 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Wei Liu, Jan Beulich, Andrew Cooper

On Fri, Aug 25, 2017 at 11:05:54AM +0100, Paul Durrant wrote:
> > -----Original Message-----
> > From: Wei Liu [mailto:wei.liu2@citrix.com]
> > Sent: 24 August 2017 17:33
> > To: Paul Durrant <Paul.Durrant@citrix.com>
> > Cc: xen-devel@lists.xenproject.org; Andrew Cooper
> > <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>; Wei Liu
> > <wei.liu2@citrix.com>
> > Subject: Re: [Xen-devel] [PATCH v2 REPOST 02/12] x86/mm: allow a
> > privileged PV domain to map guest mfns
> > 
> > On Tue, Aug 22, 2017 at 03:50:56PM +0100, Paul Durrant wrote:
> > > In the case where a PV domain is mapping guest resources then it needs
> > make
> > > the HYPERVISOR_mmu_update call using DOMID_SELF, rather than the
> > guest
> > > domid, so that the passed in gmfn values are correctly treated as mfns
> > > rather than gfns present in the guest p2m.
> > >
> > 
> > What would be the callchain like in this case?

> 
> It's exactly like foreign mapping but passing DOMID_SELF. I.e. in
> privcmd (in a PV domain) you have an mfn in your hand that already
> belongs to you rather than the gmfn of a foreign domain.
> 
> > 
> > I don't quite understand how this fits with the resource mapping
> > code in this series.
> > 
> 
> Because (for a PV caller) mapping a resource gives you back mfns that
> are assigned to the calling domain, and the most convenient way of
> using them is to use the existing code that normally deals with priv
> mapping from a foreign domain, but just allow it to use DOMID_SELF.
> This patch is all that's required to make that work.
> 

So the use case is as followed for PV guests:

1. A guest calls acquire_resource to obtain a list of mfns
2. The guest calls the foreign map API to map those mfns into its own
   address space via HYPERVISOR_mmu_update

The mfns belong to the guest itself.

In get_page_from_l1e, l1e contains a valid mfn, real_pg_owner is the
real owner of the page, pg_owner is the nominally owner of the page.
Shouldn't they be the same domain? I'm still quite baffled how you
manage to hit that place.

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

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

* Re: [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-22 14:50 ` [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources Paul Durrant
@ 2017-08-28 15:01   ` Wei Liu
  2017-08-29  8:32     ` Paul Durrant
  2017-08-29 11:16   ` George Dunlap
  1 sibling, 1 reply; 56+ messages in thread
From: Wei Liu @ 2017-08-28 15:01 UTC (permalink / raw)
  To: Paul Durrant
  Cc: George Dunlap, xen-devel, Wei Liu, Jan Beulich, Andrew Cooper

On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
> +
> +/*
> + * Get the pages for a particular guest resource, so that they can be
> + * mapped directly by a tools domain.
> + */
> +#define XENMEM_acquire_resource 28
> +struct xen_mem_acquire_resource {
> +    /* IN - the domain whose resource is to be mapped */
> +    domid_t domid;
> +    /* IN - the type of resource (defined below) */
> +    uint16_t type;
> +
> +#define XENMEM_resource_grant_table 0
> +
> +    /*
> +     * IN - a type-specific resource identifier, which must be zero
> +     *      unless stated otherwise.
> +     */
> +    uint32_t id;
> +    /* IN - number of (4K) frames of the resource to be mapped */
> +    uint32_t nr_frames;
> +    /* IN - the index of the initial frame to be mapped */
> +    uint64_aligned_t frame;
> +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
> +     *          will be populated with the MFNs of the resource.
> +     *          If the tools domain is HVM then it is expected that, on
> +     *          entry, gmfn_list will be populated with a list of GFNs
> +     *          that will be mapped to the MFNs of the resource.
> +     */
> +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;

Why is it not possible to make PV does the same thing as HVM?

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

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

* Re: [PATCH v2 REPOST 06/12] x86/hvm/ioreq: rename .*pfn and .*gmfn to .*gfn
  2017-08-22 14:51 ` [PATCH v2 REPOST 06/12] x86/hvm/ioreq: rename .*pfn and .*gmfn to .*gfn Paul Durrant
  2017-08-24 16:06   ` Roger Pau Monné
@ 2017-08-28 15:01   ` Wei Liu
  1 sibling, 0 replies; 56+ messages in thread
From: Wei Liu @ 2017-08-28 15:01 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Wei Liu, Jan Beulich, Andrew Cooper

On Tue, Aug 22, 2017 at 03:51:00PM +0100, Paul Durrant wrote:
> Since IOREQ servers are only relevant to HVM guests and all the names in
> question unequivocally refer to guest frame numbers, name them all .*gfn
> to avoid any confusion.
> 
> This patch is purely cosmetic. No semantic or functional change.
> 
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

Reviewed-by: Wei Liu <wei.liu2@citrix.com>

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

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

* Re: [PATCH v2 REPOST 05/12] tools/libxenctrl: use new xenforeignmemory API to seed grant table
  2017-08-24 16:09     ` Paul Durrant
@ 2017-08-28 15:04       ` Wei Liu
  0 siblings, 0 replies; 56+ messages in thread
From: Wei Liu @ 2017-08-28 15:04 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Ian Jackson, Wei Liu, Roger Pau Monne

On Thu, Aug 24, 2017 at 05:09:35PM +0100, Paul Durrant wrote:
> > 
> > Could be written as:
> > 
> > return (is_hvm ? compat_gnttab_hvm_seed : compat_gnttab_seed)
> >        (xch, guest_domid, console_gmfn, xenstore_gmfn, console_domid,
> >         xenstore_domid);
> 
> Is that preferable?
> 

I don't think I care either way.

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

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

* Re: [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted
  2017-08-22 14:51 ` [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted Paul Durrant
  2017-08-24 17:21   ` Roger Pau Monné
@ 2017-08-28 15:08   ` Wei Liu
  2017-08-29  8:51     ` Paul Durrant
  1 sibling, 1 reply; 56+ messages in thread
From: Wei Liu @ 2017-08-28 15:08 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Wei Liu, George Dunlap, Andrew Cooper,
	Ian Jackson, Tim Deegan, Jan Beulich, xen-devel

On Tue, Aug 22, 2017 at 03:51:05PM +0100, Paul Durrant wrote:
[...]
> diff --git a/tools/libs/devicemodel/include/xendevicemodel.h b/tools/libs/devicemodel/include/xendevicemodel.h
> index 13216db04a..da6b253cfd 100644
> --- a/tools/libs/devicemodel/include/xendevicemodel.h
> +++ b/tools/libs/devicemodel/include/xendevicemodel.h
> @@ -61,11 +61,11 @@ int xendevicemodel_create_ioreq_server(
>   * @parm domid the domain id to be serviced
>   * @parm id the IOREQ Server id.
>   * @parm ioreq_gfn pointer to a xen_pfn_t to receive the synchronous ioreq
> - *                  gfn
> + *                  gmfn. (May be NULL if not required)
>   * @parm bufioreq_gfn pointer to a xen_pfn_t to receive the buffered ioreq
> - *                    gfn
> + *                    gmfn. (May be NULL if not required)

Should be gfn here.

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

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

* Re: [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-28 15:01   ` Wei Liu
@ 2017-08-29  8:32     ` Paul Durrant
  2017-08-29  8:59       ` Jan Beulich
  0 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-29  8:32 UTC (permalink / raw)
  Cc: xen-devel, Wei Liu, George Dunlap, Jan Beulich, Andrew Cooper

> -----Original Message-----
> From: Wei Liu [mailto:wei.liu2@citrix.com]
> Sent: 28 August 2017 16:01
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; George Dunlap
> <George.Dunlap@citrix.com>; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>; Wei Liu
> <wei.liu2@citrix.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
> HYPERVISOR_memory_op to acquire guest resources
> 
> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
> > +
> > +/*
> > + * Get the pages for a particular guest resource, so that they can be
> > + * mapped directly by a tools domain.
> > + */
> > +#define XENMEM_acquire_resource 28
> > +struct xen_mem_acquire_resource {
> > +    /* IN - the domain whose resource is to be mapped */
> > +    domid_t domid;
> > +    /* IN - the type of resource (defined below) */
> > +    uint16_t type;
> > +
> > +#define XENMEM_resource_grant_table 0
> > +
> > +    /*
> > +     * IN - a type-specific resource identifier, which must be zero
> > +     *      unless stated otherwise.
> > +     */
> > +    uint32_t id;
> > +    /* IN - number of (4K) frames of the resource to be mapped */
> > +    uint32_t nr_frames;
> > +    /* IN - the index of the initial frame to be mapped */
> > +    uint64_aligned_t frame;
> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
> > +     *          will be populated with the MFNs of the resource.
> > +     *          If the tools domain is HVM then it is expected that, on
> > +     *          entry, gmfn_list will be populated with a list of GFNs
> > +     *          that will be mapped to the MFNs of the resource.
> > +     */
> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
> 
> Why is it not possible to make PV does the same thing as HVM?

Because PV guests don't use a P2M as such. An HVM guest can pass GFNs in and say 'I want the resource mapped here'. A PV guest can't do that since it's using MFNs directly... it has to deal with the resource wherever it may be.

  Paul

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

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

* Re: [PATCH v2 REPOST 02/12] x86/mm: allow a privileged PV domain to map guest mfns
  2017-08-28 14:38       ` Wei Liu
@ 2017-08-29  8:37         ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-29  8:37 UTC (permalink / raw)
  Cc: xen-devel, Wei Liu, Jan Beulich, Andrew Cooper

> -----Original Message-----
> From: Wei Liu [mailto:wei.liu2@citrix.com]
> Sent: 28 August 2017 15:38
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Wei Liu <wei.liu2@citrix.com>; xen-devel@lists.xenproject.org; Andrew
> Cooper <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 02/12] x86/mm: allow a
> privileged PV domain to map guest mfns
> 
> On Fri, Aug 25, 2017 at 11:05:54AM +0100, Paul Durrant wrote:
> > > -----Original Message-----
> > > From: Wei Liu [mailto:wei.liu2@citrix.com]
> > > Sent: 24 August 2017 17:33
> > > To: Paul Durrant <Paul.Durrant@citrix.com>
> > > Cc: xen-devel@lists.xenproject.org; Andrew Cooper
> > > <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>; Wei
> Liu
> > > <wei.liu2@citrix.com>
> > > Subject: Re: [Xen-devel] [PATCH v2 REPOST 02/12] x86/mm: allow a
> > > privileged PV domain to map guest mfns
> > >
> > > On Tue, Aug 22, 2017 at 03:50:56PM +0100, Paul Durrant wrote:
> > > > In the case where a PV domain is mapping guest resources then it
> needs
> > > make
> > > > the HYPERVISOR_mmu_update call using DOMID_SELF, rather than the
> > > guest
> > > > domid, so that the passed in gmfn values are correctly treated as mfns
> > > > rather than gfns present in the guest p2m.
> > > >
> > >
> > > What would be the callchain like in this case?
> 
> >
> > It's exactly like foreign mapping but passing DOMID_SELF. I.e. in
> > privcmd (in a PV domain) you have an mfn in your hand that already
> > belongs to you rather than the gmfn of a foreign domain.
> >
> > >
> > > I don't quite understand how this fits with the resource mapping
> > > code in this series.
> > >
> >
> > Because (for a PV caller) mapping a resource gives you back mfns that
> > are assigned to the calling domain, and the most convenient way of
> > using them is to use the existing code that normally deals with priv
> > mapping from a foreign domain, but just allow it to use DOMID_SELF.
> > This patch is all that's required to make that work.
> >
> 
> So the use case is as followed for PV guests:
> 
> 1. A guest calls acquire_resource to obtain a list of mfns
> 2. The guest calls the foreign map API to map those mfns into its own
>    address space via HYPERVISOR_mmu_update
> 
> The mfns belong to the guest itself.
> 
> In get_page_from_l1e, l1e contains a valid mfn, real_pg_owner is the
> real owner of the page, pg_owner is the nominally owner of the page.
> Shouldn't they be the same domain? I'm still quite baffled how you
> manage to hit that place.

The issue I hit was l1e_owner and pg_owner being dom0, but real_pg_owner was the guest. Obviously dom0 has privilege to map anything, but it was being denied because pg_owner == l1e_owner.

  Paul

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

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

* Re: [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted
  2017-08-28 15:08   ` Wei Liu
@ 2017-08-29  8:51     ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-29  8:51 UTC (permalink / raw)
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	George Dunlap, Jan Beulich, Ian Jackson, xen-devel

> -----Original Message-----
> From: Wei Liu [mailto:wei.liu2@citrix.com]
> Sent: 28 August 2017 16:09
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel@lists.xenproject.org; Ian Jackson <Ian.Jackson@citrix.com>;
> Wei Liu <wei.liu2@citrix.com>; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; George Dunlap
> <George.Dunlap@citrix.com>; Jan Beulich <jbeulich@suse.com>; Konrad
> Rzeszutek Wilk <konrad.wilk@oracle.com>; Stefano Stabellini
> <sstabellini@kernel.org>; Tim (Xen.org) <tim@xen.org>
> Subject: Re: [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns
> until they are actually requsted
> 
> On Tue, Aug 22, 2017 at 03:51:05PM +0100, Paul Durrant wrote:
> [...]
> > diff --git a/tools/libs/devicemodel/include/xendevicemodel.h
> b/tools/libs/devicemodel/include/xendevicemodel.h
> > index 13216db04a..da6b253cfd 100644
> > --- a/tools/libs/devicemodel/include/xendevicemodel.h
> > +++ b/tools/libs/devicemodel/include/xendevicemodel.h
> > @@ -61,11 +61,11 @@ int xendevicemodel_create_ioreq_server(
> >   * @parm domid the domain id to be serviced
> >   * @parm id the IOREQ Server id.
> >   * @parm ioreq_gfn pointer to a xen_pfn_t to receive the synchronous
> ioreq
> > - *                  gfn
> > + *                  gmfn. (May be NULL if not required)
> >   * @parm bufioreq_gfn pointer to a xen_pfn_t to receive the buffered
> ioreq
> > - *                    gfn
> > + *                    gmfn. (May be NULL if not required)
> 
> Should be gfn here.

Actually, yes. It will still be always gfn for the legacy call.


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

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

* Re: [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-29  8:32     ` Paul Durrant
@ 2017-08-29  8:59       ` Jan Beulich
  2017-08-29  9:13         ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Jan Beulich @ 2017-08-29  8:59 UTC (permalink / raw)
  To: Paul Durrant; +Cc: Andrew Cooper, Wei Liu, GeorgeDunlap, xen-devel

>>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
>> From: Wei Liu [mailto:wei.liu2@citrix.com]
>> Sent: 28 August 2017 16:01
>> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
>> > +
>> > +/*
>> > + * Get the pages for a particular guest resource, so that they can be
>> > + * mapped directly by a tools domain.
>> > + */
>> > +#define XENMEM_acquire_resource 28
>> > +struct xen_mem_acquire_resource {
>> > +    /* IN - the domain whose resource is to be mapped */
>> > +    domid_t domid;
>> > +    /* IN - the type of resource (defined below) */
>> > +    uint16_t type;
>> > +
>> > +#define XENMEM_resource_grant_table 0
>> > +
>> > +    /*
>> > +     * IN - a type-specific resource identifier, which must be zero
>> > +     *      unless stated otherwise.
>> > +     */
>> > +    uint32_t id;
>> > +    /* IN - number of (4K) frames of the resource to be mapped */
>> > +    uint32_t nr_frames;
>> > +    /* IN - the index of the initial frame to be mapped */
>> > +    uint64_aligned_t frame;
>> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
>> > +     *          will be populated with the MFNs of the resource.
>> > +     *          If the tools domain is HVM then it is expected that, on
>> > +     *          entry, gmfn_list will be populated with a list of GFNs
>> > +     *          that will be mapped to the MFNs of the resource.
>> > +     */
>> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
>> 
>> Why is it not possible to make PV does the same thing as HVM?
> 
> Because PV guests don't use a P2M as such.

They certainly do, just Xen can't rely on (and hence use) it.

> An HVM guest can pass GFNs in and 
> say 'I want the resource mapped here'. A PV guest can't do that since it's 
> using MFNs directly... it has to deal with the resource wherever it may be.

Xen does, however, maintain the M2P, so it would not be impossible
to return GFNs here for PV guests, requiring the caller to translate
them back to MFNs if so desired.

Jan


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

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

* Re: [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-29  8:59       ` Jan Beulich
@ 2017-08-29  9:13         ` Paul Durrant
  2017-08-29  9:27           ` Jan Beulich
  0 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-29  9:13 UTC (permalink / raw)
  To: 'Jan Beulich'; +Cc: Andrew Cooper, Wei Liu, George Dunlap, xen-devel

> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: 29 August 2017 10:00
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
> devel@lists.xenproject.org
> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
> HYPERVISOR_memory_op to acquire guest resources
> 
> >>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
> >> From: Wei Liu [mailto:wei.liu2@citrix.com]
> >> Sent: 28 August 2017 16:01
> >> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
> >> > +
> >> > +/*
> >> > + * Get the pages for a particular guest resource, so that they can be
> >> > + * mapped directly by a tools domain.
> >> > + */
> >> > +#define XENMEM_acquire_resource 28
> >> > +struct xen_mem_acquire_resource {
> >> > +    /* IN - the domain whose resource is to be mapped */
> >> > +    domid_t domid;
> >> > +    /* IN - the type of resource (defined below) */
> >> > +    uint16_t type;
> >> > +
> >> > +#define XENMEM_resource_grant_table 0
> >> > +
> >> > +    /*
> >> > +     * IN - a type-specific resource identifier, which must be zero
> >> > +     *      unless stated otherwise.
> >> > +     */
> >> > +    uint32_t id;
> >> > +    /* IN - number of (4K) frames of the resource to be mapped */
> >> > +    uint32_t nr_frames;
> >> > +    /* IN - the index of the initial frame to be mapped */
> >> > +    uint64_aligned_t frame;
> >> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
> >> > +     *          will be populated with the MFNs of the resource.
> >> > +     *          If the tools domain is HVM then it is expected that, on
> >> > +     *          entry, gmfn_list will be populated with a list of GFNs
> >> > +     *          that will be mapped to the MFNs of the resource.
> >> > +     */
> >> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
> >>
> >> Why is it not possible to make PV does the same thing as HVM?
> >
> > Because PV guests don't use a P2M as such.
> 
> They certainly do, just Xen can't rely on (and hence use) it.

Oh I know they have one but, as you say, Xen can't use it do put resources at a particular guest location.

> 
> > An HVM guest can pass GFNs in and
> > say 'I want the resource mapped here'. A PV guest can't do that since it's
> > using MFNs directly... it has to deal with the resource wherever it may be.
> 
> Xen does, however, maintain the M2P, so it would not be impossible
> to return GFNs here for PV guests, requiring the caller to translate
> them back to MFNs if so desired.
> 

That's possible, but still different to and HVM caller, which will pass GFNs in rather than using any values returned. So I don't really see any advantage in that.

  Paul

> Jan


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

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

* Re: [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-29  9:13         ` Paul Durrant
@ 2017-08-29  9:27           ` Jan Beulich
  2017-08-29  9:31             ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: Jan Beulich @ 2017-08-29  9:27 UTC (permalink / raw)
  To: Paul Durrant; +Cc: Andrew Cooper, Wei Liu, George Dunlap, xen-devel

>>> On 29.08.17 at 11:13, <Paul.Durrant@citrix.com> wrote:
>>  -----Original Message-----
>> From: Jan Beulich [mailto:JBeulich@suse.com]
>> Sent: 29 August 2017 10:00
>> To: Paul Durrant <Paul.Durrant@citrix.com>
>> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
>> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
>> devel@lists.xenproject.org 
>> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
>> HYPERVISOR_memory_op to acquire guest resources
>> 
>> >>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
>> >> From: Wei Liu [mailto:wei.liu2@citrix.com]
>> >> Sent: 28 August 2017 16:01
>> >> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
>> >> > +
>> >> > +/*
>> >> > + * Get the pages for a particular guest resource, so that they can be
>> >> > + * mapped directly by a tools domain.
>> >> > + */
>> >> > +#define XENMEM_acquire_resource 28
>> >> > +struct xen_mem_acquire_resource {
>> >> > +    /* IN - the domain whose resource is to be mapped */
>> >> > +    domid_t domid;
>> >> > +    /* IN - the type of resource (defined below) */
>> >> > +    uint16_t type;
>> >> > +
>> >> > +#define XENMEM_resource_grant_table 0
>> >> > +
>> >> > +    /*
>> >> > +     * IN - a type-specific resource identifier, which must be zero
>> >> > +     *      unless stated otherwise.
>> >> > +     */
>> >> > +    uint32_t id;
>> >> > +    /* IN - number of (4K) frames of the resource to be mapped */
>> >> > +    uint32_t nr_frames;
>> >> > +    /* IN - the index of the initial frame to be mapped */
>> >> > +    uint64_aligned_t frame;
>> >> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
>> >> > +     *          will be populated with the MFNs of the resource.
>> >> > +     *          If the tools domain is HVM then it is expected that, on
>> >> > +     *          entry, gmfn_list will be populated with a list of GFNs
>> >> > +     *          that will be mapped to the MFNs of the resource.
>> >> > +     */
>> >> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
>> >>
>> >> Why is it not possible to make PV does the same thing as HVM?
>> >
>> > Because PV guests don't use a P2M as such.
>> 
>> They certainly do, just Xen can't rely on (and hence use) it.
> 
> Oh I know they have one but, as you say, Xen can't use it do put resources 
> at a particular guest location.
> 
>> 
>> > An HVM guest can pass GFNs in and
>> > say 'I want the resource mapped here'. A PV guest can't do that since it's
>> > using MFNs directly... it has to deal with the resource wherever it may be.
>> 
>> Xen does, however, maintain the M2P, so it would not be impossible
>> to return GFNs here for PV guests, requiring the caller to translate
>> them back to MFNs if so desired.
> 
> That's possible, but still different to and HVM caller, which will pass GFNs 
> in rather than using any values returned. So I don't really see any advantage 
> in that.

What's wrong with PV passing in PFNs, and Xen installing the
resulting translations into the M2P right away (leaving it to the
caller to just fix up its P2M)? That would sufficiently
parallel XENMEM_exchange, for example.

Jan


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

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

* Re: [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-29  9:27           ` Jan Beulich
@ 2017-08-29  9:31             ` Paul Durrant
  2017-08-29  9:38               ` Jan Beulich
  0 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-29  9:31 UTC (permalink / raw)
  To: 'Jan Beulich'; +Cc: Andrew Cooper, Wei Liu, George Dunlap, xen-devel

> -----Original Message-----
> From: Jan Beulich [mailto:JBeulich@suse.com]
> Sent: 29 August 2017 10:28
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
> devel@lists.xenproject.org
> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
> HYPERVISOR_memory_op to acquire guest resources
> 
> >>> On 29.08.17 at 11:13, <Paul.Durrant@citrix.com> wrote:
> >>  -----Original Message-----
> >> From: Jan Beulich [mailto:JBeulich@suse.com]
> >> Sent: 29 August 2017 10:00
> >> To: Paul Durrant <Paul.Durrant@citrix.com>
> >> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
> >> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
> >> devel@lists.xenproject.org
> >> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
> >> HYPERVISOR_memory_op to acquire guest resources
> >>
> >> >>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
> >> >> From: Wei Liu [mailto:wei.liu2@citrix.com]
> >> >> Sent: 28 August 2017 16:01
> >> >> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
> >> >> > +
> >> >> > +/*
> >> >> > + * Get the pages for a particular guest resource, so that they can be
> >> >> > + * mapped directly by a tools domain.
> >> >> > + */
> >> >> > +#define XENMEM_acquire_resource 28
> >> >> > +struct xen_mem_acquire_resource {
> >> >> > +    /* IN - the domain whose resource is to be mapped */
> >> >> > +    domid_t domid;
> >> >> > +    /* IN - the type of resource (defined below) */
> >> >> > +    uint16_t type;
> >> >> > +
> >> >> > +#define XENMEM_resource_grant_table 0
> >> >> > +
> >> >> > +    /*
> >> >> > +     * IN - a type-specific resource identifier, which must be zero
> >> >> > +     *      unless stated otherwise.
> >> >> > +     */
> >> >> > +    uint32_t id;
> >> >> > +    /* IN - number of (4K) frames of the resource to be mapped */
> >> >> > +    uint32_t nr_frames;
> >> >> > +    /* IN - the index of the initial frame to be mapped */
> >> >> > +    uint64_aligned_t frame;
> >> >> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
> >> >> > +     *          will be populated with the MFNs of the resource.
> >> >> > +     *          If the tools domain is HVM then it is expected that, on
> >> >> > +     *          entry, gmfn_list will be populated with a list of GFNs
> >> >> > +     *          that will be mapped to the MFNs of the resource.
> >> >> > +     */
> >> >> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
> >> >>
> >> >> Why is it not possible to make PV does the same thing as HVM?
> >> >
> >> > Because PV guests don't use a P2M as such.
> >>
> >> They certainly do, just Xen can't rely on (and hence use) it.
> >
> > Oh I know they have one but, as you say, Xen can't use it do put resources
> > at a particular guest location.
> >
> >>
> >> > An HVM guest can pass GFNs in and
> >> > say 'I want the resource mapped here'. A PV guest can't do that since it's
> >> > using MFNs directly... it has to deal with the resource wherever it may
> be.
> >>
> >> Xen does, however, maintain the M2P, so it would not be impossible
> >> to return GFNs here for PV guests, requiring the caller to translate
> >> them back to MFNs if so desired.
> >
> > That's possible, but still different to and HVM caller, which will pass GFNs
> > in rather than using any values returned. So I don't really see any
> advantage
> > in that.
> 
> What's wrong with PV passing in PFNs, and Xen installing the
> resulting translations into the M2P right away (leaving it to the
> caller to just fix up its P2M)? That would sufficiently
> parallel XENMEM_exchange, for example.

How would that work when the mfns are assigned to a different domain? E.g. when I acquire domU's grant table for mapping in dom0, I don't want to take ownership of the mfns... they still belong to the domU.

  Paul

> 
> Jan


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

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

* Re: [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-29  9:31             ` Paul Durrant
@ 2017-08-29  9:38               ` Jan Beulich
  0 siblings, 0 replies; 56+ messages in thread
From: Jan Beulich @ 2017-08-29  9:38 UTC (permalink / raw)
  To: Paul Durrant; +Cc: Andrew Cooper, Wei Liu, George Dunlap, xen-devel

>>> On 29.08.17 at 11:31, <Paul.Durrant@citrix.com> wrote:
>>  -----Original Message-----
>> From: Jan Beulich [mailto:JBeulich@suse.com]
>> Sent: 29 August 2017 10:28
>> To: Paul Durrant <Paul.Durrant@citrix.com>
>> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
>> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
>> devel@lists.xenproject.org 
>> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
>> HYPERVISOR_memory_op to acquire guest resources
>> 
>> >>> On 29.08.17 at 11:13, <Paul.Durrant@citrix.com> wrote:
>> >>  -----Original Message-----
>> >> From: Jan Beulich [mailto:JBeulich@suse.com]
>> >> Sent: 29 August 2017 10:00
>> >> To: Paul Durrant <Paul.Durrant@citrix.com>
>> >> Cc: Andrew Cooper <Andrew.Cooper3@citrix.com>; George Dunlap
>> >> <George.Dunlap@citrix.com>; Wei Liu <wei.liu2@citrix.com>; xen-
>> >> devel@lists.xenproject.org 
>> >> Subject: RE: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
>> >> HYPERVISOR_memory_op to acquire guest resources
>> >>
>> >> >>> On 29.08.17 at 10:32, <Paul.Durrant@citrix.com> wrote:
>> >> >> From: Wei Liu [mailto:wei.liu2@citrix.com]
>> >> >> Sent: 28 August 2017 16:01
>> >> >> On Tue, Aug 22, 2017 at 03:50:57PM +0100, Paul Durrant wrote:
>> >> >> > +
>> >> >> > +/*
>> >> >> > + * Get the pages for a particular guest resource, so that they can be
>> >> >> > + * mapped directly by a tools domain.
>> >> >> > + */
>> >> >> > +#define XENMEM_acquire_resource 28
>> >> >> > +struct xen_mem_acquire_resource {
>> >> >> > +    /* IN - the domain whose resource is to be mapped */
>> >> >> > +    domid_t domid;
>> >> >> > +    /* IN - the type of resource (defined below) */
>> >> >> > +    uint16_t type;
>> >> >> > +
>> >> >> > +#define XENMEM_resource_grant_table 0
>> >> >> > +
>> >> >> > +    /*
>> >> >> > +     * IN - a type-specific resource identifier, which must be zero
>> >> >> > +     *      unless stated otherwise.
>> >> >> > +     */
>> >> >> > +    uint32_t id;
>> >> >> > +    /* IN - number of (4K) frames of the resource to be mapped */
>> >> >> > +    uint32_t nr_frames;
>> >> >> > +    /* IN - the index of the initial frame to be mapped */
>> >> >> > +    uint64_aligned_t frame;
>> >> >> > +    /* IN/OUT - If the tools domain is PV then, upon return, gmfn_list
>> >> >> > +     *          will be populated with the MFNs of the resource.
>> >> >> > +     *          If the tools domain is HVM then it is expected that, on
>> >> >> > +     *          entry, gmfn_list will be populated with a list of GFNs
>> >> >> > +     *          that will be mapped to the MFNs of the resource.
>> >> >> > +     */
>> >> >> > +    XEN_GUEST_HANDLE(xen_pfn_t) gmfn_list;
>> >> >>
>> >> >> Why is it not possible to make PV does the same thing as HVM?
>> >> >
>> >> > Because PV guests don't use a P2M as such.
>> >>
>> >> They certainly do, just Xen can't rely on (and hence use) it.
>> >
>> > Oh I know they have one but, as you say, Xen can't use it do put resources
>> > at a particular guest location.
>> >
>> >>
>> >> > An HVM guest can pass GFNs in and
>> >> > say 'I want the resource mapped here'. A PV guest can't do that since it's
>> >> > using MFNs directly... it has to deal with the resource wherever it may
>> be.
>> >>
>> >> Xen does, however, maintain the M2P, so it would not be impossible
>> >> to return GFNs here for PV guests, requiring the caller to translate
>> >> them back to MFNs if so desired.
>> >
>> > That's possible, but still different to and HVM caller, which will pass GFNs
>> > in rather than using any values returned. So I don't really see any
>> advantage
>> > in that.
>> 
>> What's wrong with PV passing in PFNs, and Xen installing the
>> resulting translations into the M2P right away (leaving it to the
>> caller to just fix up its P2M)? That would sufficiently
>> parallel XENMEM_exchange, for example.
> 
> How would that work when the mfns are assigned to a different domain? E.g. 
> when I acquire domU's grant table for mapping in dom0, I don't want to take 
> ownership of the mfns... they still belong to the domU.

Oh, right, these are foreign pages.

Jan

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

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

* Re: [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-22 14:50 ` [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources Paul Durrant
  2017-08-28 15:01   ` Wei Liu
@ 2017-08-29 11:16   ` George Dunlap
  2017-08-29 11:19     ` Paul Durrant
  1 sibling, 1 reply; 56+ messages in thread
From: George Dunlap @ 2017-08-29 11:16 UTC (permalink / raw)
  To: Paul Durrant; +Cc: xen-devel, Jan Beulich, Andrew Cooper

On Tue, Aug 22, 2017 at 3:50 PM, Paul Durrant <paul.durrant@citrix.com> wrote:
> Certain memory resources associated with a guest are not necessarily
> present in the guest P2M and so are not necessarily available to be
> foreign-mapped by a tools domain unless they are inserted, which risks
> shattering a super-page mapping.
>
> This patch adds a new memory op to allow such resourced to be priv-mapped
> directly, by either a PV or HVM tools domain.
>
> NOTE: Whilst the new op is not intrinsicly specific to the x86 architecture,
>       I have no means to test it on an ARM platform and so cannot verify
>       that it functions correctly. Hence it is currently only implemented
>       for x86.
>
> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>

p2m bits:
Acked-by: George Dunlap <george.dunlap@citrix.com>

You can retain that ack if the p2m.[ch] parts of the patch remain
substantially the same.

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

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

* Re: [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources
  2017-08-29 11:16   ` George Dunlap
@ 2017-08-29 11:19     ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-29 11:19 UTC (permalink / raw)
  To: George Dunlap; +Cc: xen-devel, Jan Beulich, Andrew Cooper

> -----Original Message-----
> From: dunlapg@gmail.com [mailto:dunlapg@gmail.com] On Behalf Of
> George Dunlap
> Sent: 29 August 2017 12:16
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: xen-devel <xen-devel@lists.xenproject.org>; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Jan Beulich <jbeulich@suse.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 03/12] x86/mm: add
> HYPERVISOR_memory_op to acquire guest resources
> 
> On Tue, Aug 22, 2017 at 3:50 PM, Paul Durrant <paul.durrant@citrix.com>
> wrote:
> > Certain memory resources associated with a guest are not necessarily
> > present in the guest P2M and so are not necessarily available to be
> > foreign-mapped by a tools domain unless they are inserted, which risks
> > shattering a super-page mapping.
> >
> > This patch adds a new memory op to allow such resourced to be priv-
> mapped
> > directly, by either a PV or HVM tools domain.
> >
> > NOTE: Whilst the new op is not intrinsicly specific to the x86 architecture,
> >       I have no means to test it on an ARM platform and so cannot verify
> >       that it functions correctly. Hence it is currently only implemented
> >       for x86.
> >
> > Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
> 
> p2m bits:
> Acked-by: George Dunlap <george.dunlap@citrix.com>
> 
> You can retain that ack if the p2m.[ch] parts of the patch remain
> substantially the same.

Ok, thanks :-)

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

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-25  9:46     ` Paul Durrant
  2017-08-25  9:53       ` Roger Pau Monne
@ 2017-08-29 11:36       ` George Dunlap
  2017-08-29 13:40       ` George Dunlap
  2 siblings, 0 replies; 56+ messages in thread
From: George Dunlap @ 2017-08-29 11:36 UTC (permalink / raw)
  To: Paul Durrant, Roger Pau Monne
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	Jan Beulich, Ian Jackson, xen-devel

On 08/25/2017 10:46 AM, Paul Durrant wrote:
>> -----Original Message-----
>> From: Roger Pau Monne
>> Sent: 25 August 2017 10:32
>> To: Paul Durrant <Paul.Durrant@citrix.com>
>> Cc: xen-devel@lists.xenproject.org; Stefano Stabellini
>> <sstabellini@kernel.org>; Wei Liu <wei.liu2@citrix.com>; George Dunlap
>> <George.Dunlap@citrix.com>; Andrew Cooper
>> <Andrew.Cooper3@citrix.com>; Ian Jackson <Ian.Jackson@citrix.com>; Tim
>> (Xen.org) <tim@xen.org>; Jan Beulich <jbeulich@suse.com>
>> Subject: Re: [Xen-devel] [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a
>> new mappable resource type...
>>
>> On Tue, Aug 22, 2017 at 03:51:06PM +0100, Paul Durrant wrote:
>>> ... XENMEM_resource_ioreq_server
>>>
>>> This patch adds support for a new resource type that can be mapped using
>>> the XENMEM_acquire_resource memory op.
>>>
>>> If an emulator makes use of this resource type then, instead of mapping
>>> gfns, the IOREQ server will allocate pages from the heap. These pages
>>> will never be present in the P2M of the guest at any point and so are
>>> not vulnerable to any direct attack by the guest. They are only ever
>>> accessible by Xen and any domain that has mapping privilege over the
>>> guest (which may or may not be limited to the domain running the
>> emulator).
>>>
>>> NOTE: Use of the new resource type is not compatible with use of
>>>       XEN_DMOP_get_ioreq_server_info unless the XEN_DMOP_no_gfns
>> flag is
>>>       set.
>>>
>>> Signed-off-by: Paul Durrant <paul.durrant@citrix.com>
>>> ---
>>> Cc: Jan Beulich <jbeulich@suse.com>
>>> Cc: Andrew Cooper <andrew.cooper3@citrix.com>
>>> Cc: George Dunlap <George.Dunlap@eu.citrix.com>
>>> Cc: Ian Jackson <ian.jackson@eu.citrix.com>
>>> Cc: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
>>> Cc: Stefano Stabellini <sstabellini@kernel.org>
>>> Cc: Tim Deegan <tim@xen.org>
>>> Cc: Wei Liu <wei.liu2@citrix.com>
>>> ---
>>>  xen/arch/x86/hvm/ioreq.c        | 136
>> ++++++++++++++++++++++++++++++++++++++++
>>>  xen/arch/x86/mm.c               |  27 ++++++++
>>>  xen/include/asm-x86/hvm/ioreq.h |   2 +
>>>  xen/include/public/hvm/dm_op.h  |   4 ++
>>>  xen/include/public/memory.h     |   3 +
>>>  5 files changed, 172 insertions(+)
>>>
>>> diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c
>>> index 795c198f95..9e6838dab6 100644
>>> --- a/xen/arch/x86/hvm/ioreq.c
>>> +++ b/xen/arch/x86/hvm/ioreq.c
>>> @@ -231,6 +231,15 @@ static int hvm_map_ioreq_gfn(struct
>> hvm_ioreq_server *s, bool buf)
>>>      struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
>>>      int rc;
>>>
>>> +    if ( iorp->page )
>>> +    {
>>> +        /* Make sure the page has not been allocated */
>>> +        if ( gfn_eq(iorp->gfn, INVALID_GFN) )
>>> +            return -EPERM;
>>> +
>>> +        return 0;
>>
>> EEXIST? (See comment below, which I think also applies here).
>>
>>> +    }
>>> +
>>>      if ( d->is_dying )
>>>          return -EINVAL;
>>>
>>> @@ -253,6 +262,60 @@ static int hvm_map_ioreq_gfn(struct
>> hvm_ioreq_server *s, bool buf)
>>>      return rc;
>>>  }
>>>
>>> +static int hvm_alloc_ioreq_mfn(struct hvm_ioreq_server *s, bool buf)
>>> +{
>>> +    struct domain *currd = current->domain;
>>> +    struct hvm_ioreq_page *iorp = buf ? &s->bufioreq : &s->ioreq;
>>> +
>>> +    if ( iorp->page )
>>> +    {
>>> +        /* Make sure the page has not been mapped */
>>> +        if ( !gfn_eq(iorp->gfn, INVALID_GFN) )
>>> +            return -EPERM;
>>> +
>>> +        return 0;
>>
>> Shouldn't this return EEXIST? Page has already been allocated by a
>> previous call AFAICT, and it seems like a possible error/misbehavior
>> to try to do it twice.
>>
> 
> The checks are there to prevent a caller from trying to mix the legacy and new methods of mapping ioreq server pages so EPERM (i.e. 'operation not permitted') seems like the correct error. I agree that it's not obvious, at this inner level, that I do think this is right. I'm open to debate about this though.

-EBUSY then?

 -George

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

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-25  9:46     ` Paul Durrant
  2017-08-25  9:53       ` Roger Pau Monne
  2017-08-29 11:36       ` George Dunlap
@ 2017-08-29 13:40       ` George Dunlap
  2017-08-29 14:10         ` Paul Durrant
  2 siblings, 1 reply; 56+ messages in thread
From: George Dunlap @ 2017-08-29 13:40 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	Jan Beulich, xen-devel, Ian Jackson, Roger Pau Monne

On Fri, Aug 25, 2017 at 10:46 AM, Paul Durrant <Paul.Durrant@citrix.com> wrote:
>> > +    /*
>> > +     * Allocated IOREQ server pages are assigned to the emulating
>> > +     * domain, not the target domain. This is because the emulator is
>> > +     * likely to be destroyed after the target domain has been torn
>> > +     * down, and we must use MEMF_no_refcount otherwise page
>> allocation
>> > +     * could fail if the emulating domain has already reached its
>> > +     * maximum allocation.
>> > +     */
>> > +    iorp->page = alloc_domheap_page(currd, MEMF_no_refcount);
>>
>> I don't really like the fact that the page is not accounted for any
>> domain, but I can see the point in doing it like that (which you
>> argument in the comment).
>>
>> IIRC there where talks about tightening the accounting of memory
>> pages, so that ideally everything would be accounted for in the memory
>> assigned to the domain.
>>
>> Just some random through, but could the toolstack set aside some
>> memory pages (ie: not map them into the domain p2m), that could then
>> be used by this? (not asking you to do this here)
>>
>> And how many pages are we expecting to use for each domain? I assume
>> the number will be quite low.
>>
>
> Yes, I agree the use on MEMF_no_refcount is not ideal and you do highlight an issue: I don't think there is currently an upper limit on the number of ioreq servers so an emulating domain could exhaust memory using the new scheme. I'll need to introduce a limit to avoid that.

I'm not terribly happy with allocating out-of-band pages either.  One
of the advantages of the way things are done now (with the page
allocated to the guest VM) is that it is more resilient to unexpected
events:  If the domain dies before the emulator is done, you have a
"zombie" domain until the process exits.  But once the process exits
for any reason -- whether crashing or whatever -- the ref is freed and
the domain can finish dying.

What happens in this case if the dm process in dom0 is killed /
segfaults before it can unmap the page?  Will the page be properly
freed, or will it just leak?

I don't immediately see an advantage to doing what you're doing here,
instaed of just calling hvm_alloc_ioreq_gfn().  The only reason you
give is that the domain is usually destroyed before the emulator
(meaning a short period of time where you have a 'zombie' domain), but
I don't see why that's an issue -- it doesn't seem like that's worth
the can of worms that it opens up.

 -George

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

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-29 13:40       ` George Dunlap
@ 2017-08-29 14:10         ` Paul Durrant
  2017-08-29 14:26           ` George Dunlap
  0 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-29 14:10 UTC (permalink / raw)
  To: George Dunlap
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	Jan Beulich, xen-devel, Ian Jackson, Roger Pau Monne

> -----Original Message-----
> From: George Dunlap
> Sent: 29 August 2017 14:40
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Roger Pau Monne <roger.pau@citrix.com>; Stefano Stabellini
> <sstabellini@kernel.org>; Wei Liu <wei.liu2@citrix.com>; Andrew Cooper
> <Andrew.Cooper3@citrix.com>; Tim (Xen.org) <tim@xen.org>; Jan Beulich
> <jbeulich@suse.com>; Ian Jackson <Ian.Jackson@citrix.com>; xen-
> devel@lists.xenproject.org
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a
> new mappable resource type...
> 
> On Fri, Aug 25, 2017 at 10:46 AM, Paul Durrant <Paul.Durrant@citrix.com>
> wrote:
> >> > +    /*
> >> > +     * Allocated IOREQ server pages are assigned to the emulating
> >> > +     * domain, not the target domain. This is because the emulator is
> >> > +     * likely to be destroyed after the target domain has been torn
> >> > +     * down, and we must use MEMF_no_refcount otherwise page
> >> allocation
> >> > +     * could fail if the emulating domain has already reached its
> >> > +     * maximum allocation.
> >> > +     */
> >> > +    iorp->page = alloc_domheap_page(currd, MEMF_no_refcount);
> >>
> >> I don't really like the fact that the page is not accounted for any
> >> domain, but I can see the point in doing it like that (which you
> >> argument in the comment).
> >>
> >> IIRC there where talks about tightening the accounting of memory
> >> pages, so that ideally everything would be accounted for in the memory
> >> assigned to the domain.
> >>
> >> Just some random through, but could the toolstack set aside some
> >> memory pages (ie: not map them into the domain p2m), that could then
> >> be used by this? (not asking you to do this here)
> >>
> >> And how many pages are we expecting to use for each domain? I assume
> >> the number will be quite low.
> >>
> >
> > Yes, I agree the use on MEMF_no_refcount is not ideal and you do
> highlight an issue: I don't think there is currently an upper limit on the
> number of ioreq servers so an emulating domain could exhaust memory
> using the new scheme. I'll need to introduce a limit to avoid that.
> 
> I'm not terribly happy with allocating out-of-band pages either.  One
> of the advantages of the way things are done now (with the page
> allocated to the guest VM) is that it is more resilient to unexpected
> events:  If the domain dies before the emulator is done, you have a
> "zombie" domain until the process exits.  But once the process exits
> for any reason -- whether crashing or whatever -- the ref is freed and
> the domain can finish dying.
> 
> What happens in this case if the dm process in dom0 is killed /
> segfaults before it can unmap the page?  Will the page be properly
> freed, or will it just leak?

The page is referenced by the ioreq server in the target domain, so it will be freed when the target domain is destroyed.

> 
> I don't immediately see an advantage to doing what you're doing here,
> instaed of just calling hvm_alloc_ioreq_gfn().  The only reason you
> give is that the domain is usually destroyed before the emulator
> (meaning a short period of time where you have a 'zombie' domain), but
> I don't see why that's an issue -- it doesn't seem like that's worth
> the can of worms that it opens up.
> 

The advantage is that the page is *never* in the guest P2M so it cannot be mapped by the guest. The use of guest pages for communication between Xen and an emulator is a well-known attack surface and IIRC has already been the subject of at least one XSA. Until we have better infrastructure to account hypervisor memory to guests then I think using alloc_domheap_page() with MEMF_no_refcount is the best way.

  Paul

>  -George
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-29 14:10         ` Paul Durrant
@ 2017-08-29 14:26           ` George Dunlap
  2017-08-29 14:31             ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: George Dunlap @ 2017-08-29 14:26 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	Jan Beulich, Ian Jackson, xen-devel, Roger Pau Monne

On Tue, Aug 29, 2017 at 3:10 PM, Paul Durrant <Paul.Durrant@citrix.com> wrote:
>> -----Original Message-----
>> From: George Dunlap
>> Sent: 29 August 2017 14:40
>> To: Paul Durrant <Paul.Durrant@citrix.com>
>> Cc: Roger Pau Monne <roger.pau@citrix.com>; Stefano Stabellini
>> <sstabellini@kernel.org>; Wei Liu <wei.liu2@citrix.com>; Andrew Cooper
>> <Andrew.Cooper3@citrix.com>; Tim (Xen.org) <tim@xen.org>; Jan Beulich
>> <jbeulich@suse.com>; Ian Jackson <Ian.Jackson@citrix.com>; xen-
>> devel@lists.xenproject.org
>> Subject: Re: [Xen-devel] [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a
>> new mappable resource type...
>>
>> On Fri, Aug 25, 2017 at 10:46 AM, Paul Durrant <Paul.Durrant@citrix.com>
>> wrote:

[snip]

>> I don't immediately see an advantage to doing what you're doing here,
>> instaed of just calling hvm_alloc_ioreq_gfn().  The only reason you
>> give is that the domain is usually destroyed before the emulator
>> (meaning a short period of time where you have a 'zombie' domain), but
>> I don't see why that's an issue -- it doesn't seem like that's worth
>> the can of worms that it opens up.
>>
>
> The advantage is that the page is *never* in the guest P2M so it cannot be mapped by the guest. The use of guest pages for communication between Xen and an emulator is a well-known attack surface and IIRC has already been the subject of at least one XSA. Until we have better infrastructure to account hypervisor memory to guests then I think using alloc_domheap_page() with MEMF_no_refcount is the best way.

...and hvm_alloc_ioreq_gfn() grabs pages which are in the guest's p2m
space but set aside for ioreq servers, so using those would make the
entire series pointless.  Sorry for missing that.

[snip]

>> >> > +    /*
>> >> > +     * Allocated IOREQ server pages are assigned to the emulating
>> >> > +     * domain, not the target domain. This is because the emulator is
>> >> > +     * likely to be destroyed after the target domain has been torn
>> >> > +     * down, and we must use MEMF_no_refcount otherwise page
>> >> allocation
>> >> > +     * could fail if the emulating domain has already reached its
>> >> > +     * maximum allocation.
>> >> > +     */
>> >> > +    iorp->page = alloc_domheap_page(currd, MEMF_no_refcount);
>> >>
>> >> I don't really like the fact that the page is not accounted for any
>> >> domain, but I can see the point in doing it like that (which you
>> >> argument in the comment).
>> >>
>> >> IIRC there where talks about tightening the accounting of memory
>> >> pages, so that ideally everything would be accounted for in the memory
>> >> assigned to the domain.
>> >>
>> >> Just some random through, but could the toolstack set aside some
>> >> memory pages (ie: not map them into the domain p2m), that could then
>> >> be used by this? (not asking you to do this here)
>> >>
>> >> And how many pages are we expecting to use for each domain? I assume
>> >> the number will be quite low.
>> >>
>> >
>> > Yes, I agree the use on MEMF_no_refcount is not ideal and you do
>> highlight an issue: I don't think there is currently an upper limit on the
>> number of ioreq servers so an emulating domain could exhaust memory
>> using the new scheme. I'll need to introduce a limit to avoid that.
>>
>> I'm not terribly happy with allocating out-of-band pages either.  One
>> of the advantages of the way things are done now (with the page
>> allocated to the guest VM) is that it is more resilient to unexpected
>> events:  If the domain dies before the emulator is done, you have a
>> "zombie" domain until the process exits.  But once the process exits
>> for any reason -- whether crashing or whatever -- the ref is freed and
>> the domain can finish dying.
>>
>> What happens in this case if the dm process in dom0 is killed /
>> segfaults before it can unmap the page?  Will the page be properly
>> freed, or will it just leak?
>
> The page is referenced by the ioreq server in the target domain, so it will be freed when the target domain is destroyed.

I don't understand how you're using the terms... I would have
interpreted 'target domain' to me means the guest VM to which emulated
devices are being provided, and 'ioreq server' means the process
(perhaps in dom0, perhaps in a stubdomain) which is providing the
emulated devices.

Did you mean that it's referenced by the ioreq_server struct in the
target domain, and so a put_page() will happen when the guest is
destroyed?

 -George

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

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-29 14:26           ` George Dunlap
@ 2017-08-29 14:31             ` Paul Durrant
  2017-08-29 14:38               ` George Dunlap
  0 siblings, 1 reply; 56+ messages in thread
From: Paul Durrant @ 2017-08-29 14:31 UTC (permalink / raw)
  To: George Dunlap
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	Jan Beulich, Ian Jackson, xen-devel, Roger Pau Monne

> -----Original Message-----
[snip]
> >> I'm not terribly happy with allocating out-of-band pages either.  One
> >> of the advantages of the way things are done now (with the page
> >> allocated to the guest VM) is that it is more resilient to unexpected
> >> events:  If the domain dies before the emulator is done, you have a
> >> "zombie" domain until the process exits.  But once the process exits
> >> for any reason -- whether crashing or whatever -- the ref is freed and
> >> the domain can finish dying.
> >>
> >> What happens in this case if the dm process in dom0 is killed /
> >> segfaults before it can unmap the page?  Will the page be properly
> >> freed, or will it just leak?
> >
> > The page is referenced by the ioreq server in the target domain, so it will
> be freed when the target domain is destroyed.
> 
> I don't understand how you're using the terms... I would have
> interpreted 'target domain' to me means the guest VM to which emulated
> devices are being provided, and 'ioreq server' means the process
> (perhaps in dom0, perhaps in a stubdomain) which is providing the
> emulated devices.
> 
> Did you mean that it's referenced by the ioreq_server struct in the
> target domain, and so a put_page() will happen when the guest is
> destroyed?

Terminology issues :-) By 'ioreq server' I mean the infrastructure in Xen, centred around struct ioreq_server. I refer to the dom0 process/stub domain/xengt module/whatever as the 'emulator'.
So, yes, the fact that the page is referenced in the ioreq server of the target domain means that a put_page() will happen when that domain is destroyed.

  Paul

> 
>  -George
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-29 14:31             ` Paul Durrant
@ 2017-08-29 14:38               ` George Dunlap
  2017-08-29 14:49                 ` Paul Durrant
  0 siblings, 1 reply; 56+ messages in thread
From: George Dunlap @ 2017-08-29 14:38 UTC (permalink / raw)
  To: Paul Durrant
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	Jan Beulich, xen-devel, Ian Jackson, Roger Pau Monne

On Tue, Aug 29, 2017 at 3:31 PM, Paul Durrant <Paul.Durrant@citrix.com> wrote:
>> -----Original Message-----
> [snip]
>> >> I'm not terribly happy with allocating out-of-band pages either.  One
>> >> of the advantages of the way things are done now (with the page
>> >> allocated to the guest VM) is that it is more resilient to unexpected
>> >> events:  If the domain dies before the emulator is done, you have a
>> >> "zombie" domain until the process exits.  But once the process exits
>> >> for any reason -- whether crashing or whatever -- the ref is freed and
>> >> the domain can finish dying.
>> >>
>> >> What happens in this case if the dm process in dom0 is killed /
>> >> segfaults before it can unmap the page?  Will the page be properly
>> >> freed, or will it just leak?
>> >
>> > The page is referenced by the ioreq server in the target domain, so it will
>> be freed when the target domain is destroyed.
>>
>> I don't understand how you're using the terms... I would have
>> interpreted 'target domain' to me means the guest VM to which emulated
>> devices are being provided, and 'ioreq server' means the process
>> (perhaps in dom0, perhaps in a stubdomain) which is providing the
>> emulated devices.
>>
>> Did you mean that it's referenced by the ioreq_server struct in the
>> target domain, and so a put_page() will happen when the guest is
>> destroyed?
>
> Terminology issues :-) By 'ioreq server' I mean the infrastructure in Xen, centred around struct ioreq_server. I refer to the dom0 process/stub domain/xengt module/whatever as the 'emulator'.
> So, yes, the fact that the page is referenced in the ioreq server of the target domain means that a put_page() will happen when that domain is destroyed.

OK; in that case:

Acked-by: George Dunlap <george.dunlap@citrix.com>

I think that's the only other Ack you need from me.  Thanks for doing this work.

 -George

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

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

* Re: [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type...
  2017-08-29 14:38               ` George Dunlap
@ 2017-08-29 14:49                 ` Paul Durrant
  0 siblings, 0 replies; 56+ messages in thread
From: Paul Durrant @ 2017-08-29 14:49 UTC (permalink / raw)
  To: George Dunlap
  Cc: Stefano Stabellini, Wei Liu, Andrew Cooper, Tim (Xen.org),
	Jan Beulich, xen-devel, Ian Jackson, Roger Pau Monne

> -----Original Message-----
> From: George Dunlap
> Sent: 29 August 2017 15:38
> To: Paul Durrant <Paul.Durrant@citrix.com>
> Cc: Stefano Stabellini <sstabellini@kernel.org>; Wei Liu
> <wei.liu2@citrix.com>; Andrew Cooper <Andrew.Cooper3@citrix.com>; Tim
> (Xen.org) <tim@xen.org>; Jan Beulich <jbeulich@suse.com>; Ian Jackson
> <Ian.Jackson@citrix.com>; xen-devel@lists.xenproject.org; Roger Pau
> Monne <roger.pau@citrix.com>
> Subject: Re: [Xen-devel] [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a
> new mappable resource type...
> 
> On Tue, Aug 29, 2017 at 3:31 PM, Paul Durrant <Paul.Durrant@citrix.com>
> wrote:
> >> -----Original Message-----
> > [snip]
> >> >> I'm not terribly happy with allocating out-of-band pages either.  One
> >> >> of the advantages of the way things are done now (with the page
> >> >> allocated to the guest VM) is that it is more resilient to unexpected
> >> >> events:  If the domain dies before the emulator is done, you have a
> >> >> "zombie" domain until the process exits.  But once the process exits
> >> >> for any reason -- whether crashing or whatever -- the ref is freed and
> >> >> the domain can finish dying.
> >> >>
> >> >> What happens in this case if the dm process in dom0 is killed /
> >> >> segfaults before it can unmap the page?  Will the page be properly
> >> >> freed, or will it just leak?
> >> >
> >> > The page is referenced by the ioreq server in the target domain, so it
> will
> >> be freed when the target domain is destroyed.
> >>
> >> I don't understand how you're using the terms... I would have
> >> interpreted 'target domain' to me means the guest VM to which
> emulated
> >> devices are being provided, and 'ioreq server' means the process
> >> (perhaps in dom0, perhaps in a stubdomain) which is providing the
> >> emulated devices.
> >>
> >> Did you mean that it's referenced by the ioreq_server struct in the
> >> target domain, and so a put_page() will happen when the guest is
> >> destroyed?
> >
> > Terminology issues :-) By 'ioreq server' I mean the infrastructure in Xen,
> centred around struct ioreq_server. I refer to the dom0 process/stub
> domain/xengt module/whatever as the 'emulator'.
> > So, yes, the fact that the page is referenced in the ioreq server of the
> target domain means that a put_page() will happen when that domain is
> destroyed.
> 
> OK; in that case:
> 
> Acked-by: George Dunlap <george.dunlap@citrix.com>
> 

Cool, thanks.

> I think that's the only other Ack you need from me.  Thanks for doing this
> work.
> 

No probs. Cheers,

  Paul

>  -George
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

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

end of thread, other threads:[~2017-08-29 14:49 UTC | newest]

Thread overview: 56+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-22 14:50 [PATCH v2 REPOST 00/12] x86: guest resource mapping Paul Durrant
2017-08-22 14:50 ` [PATCH v2 REPOST 01/12] [x86|arm]: remove code duplication Paul Durrant
2017-08-24 14:12   ` Jan Beulich
2017-08-24 14:16     ` Paul Durrant
2017-08-22 14:50 ` [PATCH v2 REPOST 02/12] x86/mm: allow a privileged PV domain to map guest mfns Paul Durrant
2017-08-24 16:33   ` Wei Liu
2017-08-25 10:05     ` Paul Durrant
2017-08-28 14:38       ` Wei Liu
2017-08-29  8:37         ` Paul Durrant
2017-08-22 14:50 ` [PATCH v2 REPOST 03/12] x86/mm: add HYPERVISOR_memory_op to acquire guest resources Paul Durrant
2017-08-28 15:01   ` Wei Liu
2017-08-29  8:32     ` Paul Durrant
2017-08-29  8:59       ` Jan Beulich
2017-08-29  9:13         ` Paul Durrant
2017-08-29  9:27           ` Jan Beulich
2017-08-29  9:31             ` Paul Durrant
2017-08-29  9:38               ` Jan Beulich
2017-08-29 11:16   ` George Dunlap
2017-08-29 11:19     ` Paul Durrant
2017-08-22 14:50 ` [PATCH v2 REPOST 04/12] tools/libxenforeignmemory: add support for resource mapping Paul Durrant
2017-08-24 15:52   ` Roger Pau Monné
2017-08-24 15:58     ` Paul Durrant
2017-08-22 14:50 ` [PATCH v2 REPOST 05/12] tools/libxenctrl: use new xenforeignmemory API to seed grant table Paul Durrant
2017-08-24 16:02   ` Roger Pau Monné
2017-08-24 16:09     ` Paul Durrant
2017-08-28 15:04       ` Wei Liu
2017-08-22 14:51 ` [PATCH v2 REPOST 06/12] x86/hvm/ioreq: rename .*pfn and .*gmfn to .*gfn Paul Durrant
2017-08-24 16:06   ` Roger Pau Monné
2017-08-28 15:01   ` Wei Liu
2017-08-22 14:51 ` [PATCH v2 REPOST 07/12] x86/hvm/ioreq: use bool rather than bool_t Paul Durrant
2017-08-24 16:11   ` Roger Pau Monné
2017-08-22 14:51 ` [PATCH v2 REPOST 08/12] x86/hvm/ioreq: move is_default into struct hvm_ioreq_server Paul Durrant
2017-08-24 16:21   ` Roger Pau Monné
2017-08-24 16:31     ` Paul Durrant
2017-08-22 14:51 ` [PATCH v2 REPOST 09/12] x86/hvm/ioreq: simplify code and use consistent naming Paul Durrant
2017-08-24 17:02   ` Roger Pau Monné
2017-08-25 10:18     ` Paul Durrant
2017-08-22 14:51 ` [PATCH v2 REPOST 10/12] x86/hvm/ioreq: use gfn_t in struct hvm_ioreq_page Paul Durrant
2017-08-24 17:05   ` Roger Pau Monné
2017-08-22 14:51 ` [PATCH v2 REPOST 11/12] x86/hvm/ioreq: defer mapping gfns until they are actually requsted Paul Durrant
2017-08-24 17:21   ` Roger Pau Monné
2017-08-25  9:52     ` Paul Durrant
2017-08-28 15:08   ` Wei Liu
2017-08-29  8:51     ` Paul Durrant
2017-08-22 14:51 ` [PATCH v2 REPOST 12/12] x86/hvm/ioreq: add a new mappable resource type Paul Durrant
2017-08-25  9:32   ` Roger Pau Monné
2017-08-25  9:46     ` Paul Durrant
2017-08-25  9:53       ` Roger Pau Monne
2017-08-25  9:58         ` Paul Durrant
2017-08-29 11:36       ` George Dunlap
2017-08-29 13:40       ` George Dunlap
2017-08-29 14:10         ` Paul Durrant
2017-08-29 14:26           ` George Dunlap
2017-08-29 14:31             ` Paul Durrant
2017-08-29 14:38               ` George Dunlap
2017-08-29 14:49                 ` Paul Durrant

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.