Skip to contentSkip to conversation

Allow setting up shared memory areas between VMs from xl config files

PATCH In review Zhongze Liu 5 participants 45 messages Jan 30, 2018 – Feb 26, 2018

lore
Share & tools
lore
#0 lore raw

v4 cover Allow setting up shared memory areas between VMs from xl config files

Hi,

This series implements the new xl config entry proposed in [1]. Users can use the new config entry to statically setup shared memory areas among VMs that don't have grant table support so that they could communicate with each other through the static shared memory areas.

After several rounds of reviews, the current design is somewhat different from what was described in the original proposal. So please refer to the documentation in [patch 7/7] for the current design.

[1] Proposal to allow setting up shared memory areas between VMs from xl config file:
https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

v3:
* Added the docs
* Changed the order of patches to reflect their internal dependencies
* Fixed the error handling when memory mapping are done but the xs trasaction fails
* Changed the xsm hooks to lookup the current domain themselves instead of getting it as a parameter
v4:
* Place the sshm info, which should not be readable by guests, under the /libxl/static_shm xs path.
* Add a new subop to xenmem_add_to_physmap() to support the memory sharing, instead of modifying an old one.

Cheers,

Zhongze Liu (7):
libxc: add xc_domain_remove_from_physmap to wrap
XENMEM_remove_from_physmap
xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing
libxl: introduce a new structure to represent static shared memory
regions
libxl: support mapping static shared memory areas during domain
creation
libxl: support unmapping static shared memory areas during domain
destruction
libxl:xl: add parsing code to parse "libxl_static_sshm" from xl config
files
docs: documentation about static shared memory regions

 docs/man/xl-static-shm-configuration.pod.5 | 257 +++++++++++++++
 docs/man/xl.cfg.pod.5.in                   |   8 +
 docs/misc/xenstore-paths.markdown          |  47 +++
 tools/flask/policy/modules/xen.if          |   2 +
 tools/libxc/include/xenctrl.h              |   4 +
 tools/libxc/xc_domain.c                    |  11 +
 tools/libxl/Makefile                       |   4 +-
 tools/libxl/libxl.h                        |   4 +
 tools/libxl/libxl_arch.h                   |   6 +
 tools/libxl/libxl_arm.c                    |  15 +
 tools/libxl/libxl_create.c                 |  27 ++
 tools/libxl/libxl_domain.c                 |   5 +
 tools/libxl/libxl_internal.h               |  16 +
 tools/libxl/libxl_sshm.c                   | 503 +++++++++++++++++++++++++++++
 tools/libxl/libxl_types.idl                |  32 +-
 tools/libxl/libxl_x86.c                    |  19 ++
 tools/libxl/libxlu_sshm.c                  | 210 ++++++++++++
 tools/libxl/libxlutil.h                    |   6 +
 tools/xl/xl_parse.c                        |  24 +-
 xen/arch/arm/mm.c                          |   8 +-
 xen/arch/x86/mm.c                          |   4 +
 xen/include/public/memory.h                |   4 +
 xen/include/xsm/dummy.h                    |   6 +
 xen/include/xsm/xsm.h                      |   6 +
 xen/xsm/dummy.c                            |   1 +
 xen/xsm/flask/hooks.c                      |   7 +
 xen/xsm/flask/policy/access_vectors        |   5 +
 27 files changed, 1235 insertions(+), 6 deletions(-)
 create mode 100644 docs/man/xl-static-shm-configuration.pod.5
 create mode 100644 tools/libxl/libxl_sshm.c
 create mode 100644 tools/libxl/libxlu_sshm.c
Signature · 7 lines
2.16.1


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#1 lore raw

PATCH v4 1/7 libxc: add xc_domain_remove_from_physmap to wrap XENMEM_remove_from_physmap

This is for the proposal "Allow setting up shared memory areas between VMs from xl config file". See:

https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Then plan is to use XENMEM_add_to_physmap_batch to map the shared pages from one domU to another and use XENMEM_remove_from_physmap to cancel the sharing. A wrapper to XENMEM_add_to_physmap_batch was added in the following commit:

commit 20e725e9364cff4a29945f66986ecd88cca8743d

Now add the wrapper to XENMEM_remove_from_physmap.

Cc Ian Jackson <[email protected]>
Cc Wei Liu <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>
---
 tools/libxc/include/xenctrl.h |  4 ++++
 tools/libxc/xc_domain.c       | 11 +++++++++++
 2 files changed, 15 insertions(+)
tools/libxc/include/xenctrl.h +4 -0
index 235b8bb847..543abfcb34 100644
@@ -1416,6 +1416,10 @@ int xc_domain_add_to_physmap_batch(xc_interface *xch,
                                    xen_pfn_t *gfpns,
                                    int *errs);
 
+int xc_domain_remove_from_physmap(xc_interface *xch,
+                                  uint32_t domid,
+                                  xen_pfn_t gpfn);
+
 int xc_domain_populate_physmap(xc_interface *xch,
                                uint32_t domid,
                                unsigned long nr_extents,
tools/libxc/xc_domain.c +11 -0
index da0aa2f6a8..ea3df1ef31 100644
@@ -1090,6 +1090,17 @@ out:
     return rc;
 }
 
+int xc_domain_remove_from_physmap(xc_interface *xch,
+                                  uint32_t domid,
+                                  xen_pfn_t gpfn)
+{
+    struct xen_remove_from_physmap xrfp = {
+        .domid = domid,
+        .gpfn = gpfn,
+    };
+    return do_memory_op(xch, XENMEM_remove_from_physmap, &xrfp, sizeof(xrfp));
+}
+
 int xc_domain_claim_pages(xc_interface *xch,
                                uint32_t domid,
                                unsigned long nr_pages)
Signature · 7 lines
2.16.1


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#2 lore raw

PATCH v4 2/7 xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

In reply to Zhongze Liu

The existing XENMAPSPACE_gmfn_foreign subop of XENMEM_add_to_physmap forbids a Dom0 to map memory pages from one DomU to another, which restricts some useful yet not dangerous use cases -- such as sharing pages among DomU's so that they can do shm-based communication.

This patch introduces XENMAPSPACE_gmfn_share to address this inconvenience, which is mostly the same as XENMAPSPACE_gmfn_foreign but has its own xsm check.

Specifically, the patch:

* Introduces a new av permission MMU__SHARE_MEM to denote if two domains can share memory by using the new subop;
* Introduces xsm_map_gmfn_share() to check if (current) has proper permission over (t) AND MMU__SHARE_MEM is allowed between (d) and (t);
* Modify the default xen.te to allow MMU__SHARE_MEM for normal domains that allow grant mapping/event channels.

The new subop is marked unsupported for x86 because calling p2m_add_foregin on two DomU's is currently not supported on x86.

This is for the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]).

[1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Cc Daniel De Graaf <[email protected]>
Cc Ian Jackson <[email protected]>
Cc Wei Liu <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>

---
V3:
* Change several if statements to the GCC '... = a ?: b' extention.
* Lookup the current domain in the hooks instead of passing it as an arg.

V4:
* Eliminate the duplicated (c) over (d) check.
* Added a new subop instead of modifying the old subop.

---
 tools/flask/policy/modules/xen.if   | 2 ++
 xen/arch/arm/mm.c                   | 8 +++++++-
 xen/arch/x86/mm.c                   | 4 ++++
 xen/include/public/memory.h         | 4 ++++
 xen/include/xsm/dummy.h             | 6 ++++++
 xen/include/xsm/xsm.h               | 6 ++++++
 xen/xsm/dummy.c                     | 1 +
 xen/xsm/flask/hooks.c               | 7 +++++++
 xen/xsm/flask/policy/access_vectors | 5 +++++
 9 files changed, 42 insertions(+), 1 deletion(-)
tools/flask/policy/modules/xen.if +2 -0
index 459880bb01..f02d49114f 100644
@@ -127,6 +127,8 @@ define(`domain_comms', `
 	domain_event_comms($1, $2)
 	allow $1 $2:grant { map_read map_write copy unmap };
 	allow $2 $1:grant { map_read map_write copy unmap };
+	allow $1 $2:mmu share_mem;
+	allow $2 $1:mmu share_mem;
 ')
 
 # domain_self_comms(domain)
xen/arch/arm/mm.c +7 -1
index 3c328e2df5..8e385d62a8 100644
@@ -1251,6 +1251,7 @@ int xenmem_add_to_physmap_one(
 
         break;
     case XENMAPSPACE_gmfn_foreign:
+    case XENMAPSPACE_gmfn_share:
     {
         struct domain *od;
         p2m_type_t p2mt;
@@ -1265,7 +1266,12 @@ int xenmem_add_to_physmap_one(
             return -EINVAL;
         }
 
-        rc = xsm_map_gmfn_foreign(XSM_TARGET, d, od);
+        if ( space == XENMAPSPACE_gmfn_foreign ) {
+            rc = xsm_map_gmfn_foreign(XSM_TARGET, d, od);
+        } else {
+            rc = xsm_map_gmfn_share(XSM_TARGET, d, od);
+        }
+
         if ( rc )
         {
             rcu_unlock_domain(od);
xen/arch/x86/mm.c +4 -0
index c732734ac1..684403f737 100644
@@ -4126,6 +4126,10 @@ int xenmem_add_to_physmap_one(
         }
         case XENMAPSPACE_gmfn_foreign:
             return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
+        case XENMAPSPACE_gmfn_share:
+            gdprintk(XENLOG_WARNING,
+                     "XENMAPSPACE_gmfn_share is currently not supported on x86\n");
+            break;
         default:
             break;
     }
xen/include/public/memory.h +4 -0
index 29386df98b..ce70788660 100644
@@ -227,6 +227,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
                                       Stage-2 using the Normal Memory
                                       Inner/Outer Write-Back Cacheable
                                       memory attribute. */
+#define XENMAPSPACE_gmfn_share   6 /* Same as *_gmfn_foreign, but this is
+                                      for a privileged dom to share pages
+                                      between two doms. */
+
 /* ` } */
 
 /*
xen/include/xsm/dummy.h +6 -0
index d6ddadcafd..cda87dea12 100644
@@ -521,6 +521,12 @@ static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str
     return xsm_default_action(action, d, t);
 }
 
+static XSM_INLINE int xsm_map_gmfn_share(XSM_DEFAULT_ARG struct domain *d, struct domain *t)
+{
+    XSM_ASSERT_ACTION(XSM_TARGET);
+    return xsm_default_action(action, current->domain, t);
+}
+
 static XSM_INLINE int xsm_hvm_param(XSM_DEFAULT_ARG struct domain *d, unsigned long op)
 {
     XSM_ASSERT_ACTION(XSM_TARGET);
xen/include/xsm/xsm.h +6 -0
index e3912bcc9d..1305b16973 100644
@@ -86,6 +86,7 @@ struct xsm_operations {
     int (*add_to_physmap) (struct domain *d1, struct domain *d2);
     int (*remove_from_physmap) (struct domain *d1, struct domain *d2);
     int (*map_gmfn_foreign) (struct domain *d, struct domain *t);
+    int (*map_gmfn_share) (struct domain *d, struct domain *t);
     int (*claim_pages) (struct domain *d);
 
     int (*console_io) (struct domain *d, int cmd);
@@ -375,6 +376,11 @@ static inline int xsm_map_gmfn_foreign (xsm_default_t def, struct domain *d, str
     return xsm_ops->map_gmfn_foreign(d, t);
 }
 
+static inline int xsm_map_gmfn_share (xsm_default_t def, struct domain *d, struct domain *t)
+{
+    return xsm_ops->map_gmfn_share(d, t);
+}
+
 static inline int xsm_claim_pages(xsm_default_t def, struct domain *d)
 {
     return xsm_ops->claim_pages(d);
xen/xsm/dummy.c +1 -0
index 479b103614..3017dfc9a6 100644
@@ -124,6 +124,7 @@ void __init xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, add_to_physmap);
     set_to_dummy_if_null(ops, remove_from_physmap);
     set_to_dummy_if_null(ops, map_gmfn_foreign);
+    set_to_dummy_if_null(ops, map_gmfn_share);
 
     set_to_dummy_if_null(ops, vm_event_control);
 
xen/xsm/flask/hooks.c +7 -0
index 1802d8dfe6..d4a8153301 100644
@@ -1196,6 +1196,12 @@ static int flask_map_gmfn_foreign(struct domain *d, struct domain *t)
     return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
 }
 
+static int flask_map_gmfn_share(struct domain *d, struct domain *t)
+{
+    return current_has_perm(t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE) ?:
+        domain_has_perm(d, t, SECCLASS_MMU, MMU__SHARE_MEM);
+}
+
 static int flask_hvm_param(struct domain *d, unsigned long op)
 {
     u32 perm;
@@ -1815,6 +1821,7 @@ static struct xsm_operations flask_ops = {
     .add_to_physmap = flask_add_to_physmap,
     .remove_from_physmap = flask_remove_from_physmap,
     .map_gmfn_foreign = flask_map_gmfn_foreign,
+    .map_gmfn_share = flask_map_gmfn_share,
 
 #if defined(CONFIG_HAS_PASSTHROUGH) && defined(CONFIG_HAS_PCI)
     .get_device_group = flask_get_device_group,
xen/xsm/flask/policy/access_vectors +5 -0
index 89b99966bb..e249a68728 100644
@@ -383,6 +383,11 @@ class mmu
 # Allow a privileged domain to install a map of a page it does not own.  Used
 # for stub domain device models with the PV framebuffer.
     target_hack
+# Checked when using XENMEM_add_to_physmap with XENMAPSPACE_gmfn_share
+# to share memory between two domains:
+#  source = domain whose memory is being shared
+#  target = client domain
+    share_mem
 }
 
 # control of the paging_domctl split by subop
Signature · 7 lines
2.16.1


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#3 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

xen/arch/x86/mm.c int xenmem_add_to_physmap_one( · line 4132

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 30.01.18 at 18:50, <[email protected]> wrote:
xen/arch/x86/mm.c +4 -0
@@ -4126,6 +4126,10 @@ int xenmem_add_to_physmap_one(
         }
         case XENMAPSPACE_gmfn_foreign:
             return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
+        case XENMAPSPACE_gmfn_share:
+            gdprintk(XENLOG_WARNING,
+                     "XENMAPSPACE_gmfn_share is currently not supported on x86\n");
+            break;

Please don't - a hypervisor log message isn't really useful here. It should be the tool stack to disallow respective options on x86 until that's implemented.

xen/include/public/memory.h DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t); · line 233

Quoted 10 lines
xen/include/public/memory.h +4 -0
@@ -227,6 +227,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
                                       Stage-2 using the Normal Memory
                                       Inner/Outer Write-Back Cacheable
                                       memory attribute. */
+#define XENMAPSPACE_gmfn_share   6 /* Same as *_gmfn_foreign, but this is
+                                      for a privileged dom to share pages
+                                      between two doms. */
+

The comment doesn't make clear why XENMAPSPACE_gmfn_foreign then can't be used. In particular it is left open how _both_ domains would be specified.

Also XENMAPSPACE_gmfn_foreign is restricted to XENMEM_add_to_physmap_batch (a comment says so) - how about this new one? According to the actual code changes you do, there's no meaningful difference, in which case the restriction should be named here as well.

xen/include/xsm/dummy.h static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str · line 524

Quoted 7 lines
xen/include/xsm/dummy.h +1 -0
@@ -521,6 +521,12 @@ static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str
     return xsm_default_action(action, d, t);
 }
 
+static XSM_INLINE int xsm_map_gmfn_share(XSM_DEFAULT_ARG struct domain *d, struct domain *t)

Line length.

xen/include/xsm/dummy.h static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str · line 527

Quoted 3 lines
xen/include/xsm/dummy.h +3 -0
+{
+    XSM_ASSERT_ACTION(XSM_TARGET);
+    return xsm_default_action(action, current->domain, t);

How does this represent a proper default equivalent of ...

xen/xsm/flask/hooks.c +4 -0
@@ -1196,6 +1196,12 @@ static int flask_map_gmfn_foreign(struct domain *d, struct domain *t)
     return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
 }
 
+static int flask_map_gmfn_share(struct domain *d, struct domain *t)
+{
+    return current_has_perm(t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE) ?:
+        domain_has_perm(d, t, SECCLASS_MMU, MMU__SHARE_MEM);
 

... this?

Jan

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#4 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Hi Jan,

2018-02-01 18:23 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line · On 30.01.18 at 18:50, <[email protected]> wrote:

[...]

Quoted 27 lines

xen/include/xsm/dummy.h static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str · line 524

Quoted 7 lines
xen/include/xsm/dummy.h +1 -0
@@ -521,6 +521,12 @@ static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str
     return xsm_default_action(action, d, t);
 }
 
+static XSM_INLINE int xsm_map_gmfn_share(XSM_DEFAULT_ARG struct domain *d, struct domain *t)

Line length.

xen/include/xsm/dummy.h static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str · line 527

Quoted 3 lines
xen/include/xsm/dummy.h +3 -0
+{
+    XSM_ASSERT_ACTION(XSM_TARGET);
+    return xsm_default_action(action, current->domain, t);

How does this represent a proper default equivalent of ...

xen/xsm/flask/hooks.c +4 -0
@@ -1196,6 +1196,12 @@ static int flask_map_gmfn_foreign(struct domain *d, struct domain *t)
     return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
 }
 
+static int flask_map_gmfn_share(struct domain *d, struct domain *t)
+{
+    return current_has_perm(t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE) ?:
+        domain_has_perm(d, t, SECCLASS_MMU, MMU__SHARE_MEM);
 
Quoted 1 line

... this?

The full flask check tries to guarantee that:
1) (c) over (d), which will always be checked somewhere higher in

      the call stack for these kinds of calls;

2) (c) over (t), namely, MMU__MAP_READ/WRITE;
3) (d) over (t), namely, MMU__SHARE_MEM

In my default builtin actions, checks 1) and 2) are done by the xsm_default_action
function, but I can't think of a way to do check 3), because we don't have the proper
equivalence of MMU__SHARE_MEM (xsm_default_action is definitely not a choice). Want to hear your and other maintainers' suggestions about how to do this properly.

Quoted 3 lines

Jan

Cheers,

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#5 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Quoted 27 lines
Quoted 1 line
Quoted 1 line · On 01.02.18 at 19:11, <[email protected]> wrote:

2018-02-01 18:23 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 25 lines

xen/include/xsm/dummy.h static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str · line 527

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 30.01.18 at 18:50, <[email protected]> wrote:
xen/include/xsm/dummy.h +4 -0
@@ -521,6 +521,12 @@ static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str
     return xsm_default_action(action, d, t);
 }
 
+static XSM_INLINE int xsm_map_gmfn_share(XSM_DEFAULT_ARG struct domain *d, struct domain *t)
+{
+    XSM_ASSERT_ACTION(XSM_TARGET);
+    return xsm_default_action(action, current->domain, t);

How does this represent a proper default equivalent of ...

xen/xsm/flask/hooks.c +4 -0
@@ -1196,6 +1196,12 @@ static int flask_map_gmfn_foreign(struct domain *d, struct domain *t)
     return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
 }
 
+static int flask_map_gmfn_share(struct domain *d, struct domain *t)
+{
+    return current_has_perm(t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE) ?:
+        domain_has_perm(d, t, SECCLASS_MMU, MMU__SHARE_MEM);
 
Quoted 5 lines
Quoted 1 line

... this?

The full flask check tries to guarantee that:
1) (c) over (d), which will always be checked somewhere higher in

      the call stack for these kinds of calls;

This is in no way apparent here. At the very least a comment to that effect should be added, but perhaps even better would be if you had an explicit xsm_default_action(..., current->domain, d) call there. Whether one or the other is preferable I'd leave to Daniel.

Quoted 11 lines

2) (c) over (t), namely, MMU__MAP_READ/WRITE;
3) (d) over (t), namely, MMU__SHARE_MEM

In my default builtin actions, checks 1) and 2) are done by the xsm_default_action
function, but I can't think of a way to do check 3), because we don't have the proper
equivalence of MMU__SHARE_MEM (xsm_default_action is definitely not a choice).
Want to hear your and other maintainers' suggestions about how to do this properly.

"(d) over (t)" would suggest xsm_default_action(action, d, t), which I don't think is appropriate here. In fact aiui d and t are unrelated to one another in terms of mutual privilege. I don't think 3) needs expressing in the dummy version; it's really the apparent lack of 1) which I've been commenting on. But again, I'll leave it to Daniel to tell you otherwise. What is imperative in any event is that you extend the description to also reason about the dummy logic, at least as long as it isn't a clear equivalent of the flask variant.

Jan

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#6 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Hi Jan,

(Sorry for the late reply.)

2018-02-02 16:32 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 33 lines
Quoted 27 lines
Quoted 1 line
Quoted 1 line · On 01.02.18 at 19:11, <[email protected]> wrote:

2018-02-01 18:23 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 25 lines

xen/include/xsm/dummy.h static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str · line 527

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 30.01.18 at 18:50, <[email protected]> wrote:
xen/include/xsm/dummy.h +4 -0
@@ -521,6 +521,12 @@ static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str
     return xsm_default_action(action, d, t);
 }
 
+static XSM_INLINE int xsm_map_gmfn_share(XSM_DEFAULT_ARG struct domain *d, struct domain *t)
+{
+    XSM_ASSERT_ACTION(XSM_TARGET);
+    return xsm_default_action(action, current->domain, t);

How does this represent a proper default equivalent of ...

xen/xsm/flask/hooks.c +4 -0
@@ -1196,6 +1196,12 @@ static int flask_map_gmfn_foreign(struct domain *d, struct domain *t)
     return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
 }
 
+static int flask_map_gmfn_share(struct domain *d, struct domain *t)
+{
+    return current_has_perm(t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE) ?:
+        domain_has_perm(d, t, SECCLASS_MMU, MMU__SHARE_MEM);
 
Quoted 5 lines
Quoted 1 line

... this?

The full flask check tries to guarantee that:
1) (c) over (d), which will always be checked somewhere higher in

      the call stack for these kinds of calls;
Quoted 6 lines

This is in no way apparent here. At the very least a comment to that effect should be added, but perhaps even better would be if you had an explicit xsm_default_action(..., current->domain, d) call there. Whether one or the other is preferable I'd leave to Daniel.

During our discussion on v3 of the patch set, Daniel has already expressed his preference not to duplicate the (c)-over-(d) check here, and that's why I've eliminated the check in this version. But I do agree with you on adding a comment here ...

Quoted 12 lines
Quoted 11 lines

2) (c) over (t), namely, MMU__MAP_READ/WRITE;
3) (d) over (t), namely, MMU__SHARE_MEM

In my default builtin actions, checks 1) and 2) are done by the xsm_default_action
function, but I can't think of a way to do check 3), because we don't have the proper
equivalence of MMU__SHARE_MEM (xsm_default_action is definitely not a choice).
Want to hear your and other maintainers' suggestions about how to do this properly.

Quoted 9 lines

"(d) over (t)" would suggest xsm_default_action(action, d, t), which I don't think is appropriate here. In fact aiui d and t are unrelated to one another in terms of mutual privilege. I don't think 3) needs expressing in the dummy version; it's really the apparent lack of 1)k which I've been commenting on. But again, I'll leave it to Daniel to tell you otherwise. What is imperative in any event is that you extend the description to also reason about the dummy logic, at least as long as it isn't a clear equivalent of the flask variant.

... and here.

Cheers,

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#7 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

In reply to Jan Beulich

Hi Jan,

I've updated the comments according to your previous suggestions, do they look good to you?

2018-02-01 18:23 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 16 lines

xen/arch/x86/mm.c int xenmem_add_to_physmap_one( · line 4132

Quoted 11 lines
Quoted 1 line
Quoted 1 line · On 30.01.18 at 18:50, <[email protected]> wrote:
xen/arch/x86/mm.c +4 -0
@@ -4126,6 +4126,10 @@ int xenmem_add_to_physmap_one(
         }
         case XENMAPSPACE_gmfn_foreign:
             return p2m_add_foreign(d, idx, gfn_x(gpfn), extra.foreign_domid);
+        case XENMAPSPACE_gmfn_share:
+            gdprintk(XENLOG_WARNING,
+                     "XENMAPSPACE_gmfn_share is currently not supported on x86\n");
+            break;

Please don't - a hypervisor log message isn't really useful here. It should be the tool stack to disallow respective options on x86 until that's implemented.

Quoted 6 lines

xen/include/public/memory.h DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t); · line 229

Quoted 6 lines
xen/include/public/memory.h +0 -0
@@ -227,6 +227,10 @@ DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t);
                                       Stage-2 using the Normal Memory
                                       Inner/Outer Write-Back Cacheable
                                       memory attribute. */

/*
* GMFN from another dom, but with different privilege requirements. *
* Suppose that (c), the current domain, is trying to map pages from (t) into
* (d). gmfn_share dosen't require that (d) has privilege over (t). This
* enables some usecases such as dom0 trying to share memory pages between
* two unprivileged guests, which will otherwise be impossible using
* gmfn_foreign. This is XENMEM_add_to_physmap_batch only, and currently ARM
* only.
*
* The exact XSM privilege requirements are as follows:
*
* ================== ============== ===================== =====================
* (c) over (d) (c) over (t) (d) over (t)
* ================== ============== ===================== =====================

 * _foreign (dummy)   XSM_TARGET     NO                    XSM_TARGET
 * _share (dummy)     XSM_TARGET     XSM_TARGET            NO
 * _foreign (flask)   MMU__PHYSMAP   NO                    MMU__MAP_READ/WRITE
 * _share (flask)     MMU__PHYSMAP   MMU__MAP_READ/WRITE   MMU__SHARE

* ================== ============== ===================== ===================== */

Quoted 21 lines

xen/include/public/memory.h DEFINE_XEN_GUEST_HANDLE(xen_machphys_mapping_t); · line 233

Quoted 4 lines
xen/include/public/memory.h +4 -0
+#define XENMAPSPACE_gmfn_share   6 /* Same as *_gmfn_foreign, but this is
+                                      for a privileged dom to share pages
+                                      between two doms. */
+

The comment doesn't make clear why XENMAPSPACE_gmfn_foreign then can't be used. In particular it is left open how _both_ domains would be specified.

Also XENMAPSPACE_gmfn_foreign is restricted to XENMEM_add_to_physmap_batch (a comment says so) - how about this new one? According to the actual code changes you do, there's no meaningful difference, in which case the restriction should be named here as well.

Quoted 6 lines
xen/include/xsm/dummy.h +0 -0
@@ -521,6 +521,12 @@ static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str
     return xsm_default_action(action, d, t);
 }
 
Quoted 5 lines

xen/include/xsm/dummy.h static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str · line 524

Quoted 1 line
xen/include/xsm/dummy.h +1 -0
+static XSM_INLINE int xsm_map_gmfn_share(XSM_DEFAULT_ARG struct domain *d, struct domain *t)

Line length.

Quoted 1 line
xen/include/xsm/dummy.h +1 -0
+{

/*
* This action also requires that @current targets @d, but it has already been
* checked somewhere higher in the call stack.
*
* Be aware that this is not an exact default equivalence of its flask variant
* which also checks if @d and @t "are allowed to share memory pages", for we
* don't have a proper default equivalence of such a check.
*/

xen/xsm/flask/hooks.c static int flask_map_gmfn_foreign(struct domain *d, struct domain *t) · line 1200

Quoted 13 lines

xen/include/xsm/dummy.h static XSM_INLINE int xsm_map_gmfn_foreign(XSM_DEFAULT_ARG struct domain *d, str · line 527

Quoted 2 lines
xen/include/xsm/dummy.h +2 -0
+    XSM_ASSERT_ACTION(XSM_TARGET);
+    return xsm_default_action(action, current->domain, t);

How does this represent a proper default equivalent of ...

xen/xsm/flask/hooks.c +2 -0
@@ -1196,6 +1196,12 @@ static int flask_map_gmfn_foreign(struct domain *d, struct domain *t)
     return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE);
 }
 
+static int flask_map_gmfn_share(struct domain *d, struct domain *t)
+{

/*
* This action also requires that @current has MMU__MAP_READ/WRITE over @d,
* but that has already been checked somewhere higher in the call stack (for
* example, by flask_add_to_physmap()).
*/

Quoted 4 lines
xen/xsm/flask/hooks.c +2 -0
+    return current_has_perm(t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WRITE) ?:
+        domain_has_perm(d, t, SECCLASS_MMU, MMU__SHARE_MEM);
 

... this?

Cheers,

Zhongze Liu.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#8 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Quoted 3 lines
Quoted 1 line
Quoted 1 line · On 13.02.18 at 16:15, <[email protected]> wrote:

I've updated the comments according to your previous suggestions, do they look good to you?

The one in the public header is way too verbose. I specifically don't see why you would need to spell out XSM privilege requirements there. Please make new comments match existing ones in style and verbosity if at all possible, while still conveying all necessary / relevant information.

Jan

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#9 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Hi Jan,

2018-02-13 23:26 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 10 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line · On 13.02.18 at 16:15, <[email protected]> wrote:

I've updated the comments according to your previous suggestions, do they look good to you?

The one in the public header is way too verbose. I specifically don't see why you would need to spell out XSM privilege requirements there. Please make new comments match existing ones in style and verbosity if at all possible, while still conveying all necessary / relevant information.

I shortened it a little bit, and now it looks like:

#define XENMAPSPACE_gmfn_share 6 /* GMFN from another dom. Unlike
gmfn_foreign,
if (c) tries to map pages from (t) into (d), this doesn't require that (d) itself has the privilege to map the pages, but instead requires that (c) has the privilege to do so, as long as (d) and (t) are allowed to share memory pages. This is XENMEM_add_to_physmap_batch only, and currently ARM only. */

Cheers,

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#10 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Quoted 17 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 08:15, <[email protected]> wrote:

Hi Jan,

2018-02-13 23:26 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 10 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line · On 13.02.18 at 16:15, <[email protected]> wrote:

I've updated the comments according to your previous suggestions, do they look good to you?

The one in the public header is way too verbose. I specifically don't see why you would need to spell out XSM privilege requirements there. Please make new comments match existing ones in style and verbosity if at all possible, while still conveying all necessary / relevant information.

I shortened it a little bit, and now it looks like:

Quoted 10 lines

#define XENMAPSPACE_gmfn_share 6 /* GMFN from another dom. Unlike
gmfn_foreign,
if (c) tries to map pages from (t) into (d), this doesn't require that (d) itself has the privilege to map the pages, but instead requires that (c) has the privilege to do so, as long as (d) and (t) are allowed to share memory pages. This is XENMEM_add_to_physmap_batch only, and currently ARM only. */

Which leaves unclear what (c), (d), and (t) are. How about

"GMFN from another dom, XENMEM_add_to_physmap_batch (and currently ARM) only. Other than XENMAPSPACE_gmfn_foreign this <explain here what the difference is with a few simple words>."

(You can and should go into further detail in the commit message.) Without this _properly_ explained, I'll continue to ask why you can't simply make XENMAPSPACE_gmfn_foreign do what you want (as it already takes two domid_t-s as input), by suitably adjusting its XSM check(s).

You'd also need to adjust the comment on the foreign_domid structure field, as it saying "gmfn_foreign" would otherwise become stale with your change.

I don't, btw, like the ARM only part here - there's nothing inherently wrong with the same operation being sensible on x86.

Jan

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#11 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Hi Jan,

2018-02-14 16:37 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 34 lines
Quoted 17 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 08:15, <[email protected]> wrote:

Hi Jan,

2018-02-13 23:26 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 10 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line · On 13.02.18 at 16:15, <[email protected]> wrote:

I've updated the comments according to your previous suggestions, do they look good to you?

The one in the public header is way too verbose. I specifically don't see why you would need to spell out XSM privilege requirements there. Please make new comments match existing ones in style and verbosity if at all possible, while still conveying all necessary / relevant information.

I shortened it a little bit, and now it looks like:

Quoted 10 lines

#define XENMAPSPACE_gmfn_share 6 /* GMFN from another dom. Unlike
gmfn_foreign,
if (c) tries to map pages from (t) into (d), this doesn't require that (d) itself has the privilege to map the pages, but instead requires that (c) has the privilege to do so, as long as (d) and (t) are allowed to share memory pages. This is XENMEM_add_to_physmap_batch only, and currently ARM only. */

Which leaves unclear what (c), (d), and (t) are. How about

"GMFN from another dom, XENMEM_add_to_physmap_batch (and currently ARM) only. Other than XENMAPSPACE_gmfn_foreign this <explain here what the difference is with a few simple words>."

Quoted 5 lines

(You can and should go into further detail in the commit message.) Without this _properly_ explained, I'll continue to ask why you can't simply make XENMAPSPACE_gmfn_foreign do what you want (as it already takes two domid_t-s as input), by suitably adjusting its XSM check(s).

I'm sorry that I failed to see the reason why you say "which leaves unclear what (c), (d), and (t) are". I think "if (c) tries to map pages from (t) into (d)" has already included the necessary information about this: (c) is the caller of the hypercall (current), (d) is the dest domain, and (t) the source domain.
I think I still need more of your explanation here.

Quoted 4 lines

You'd also need to adjust the comment on the foreign_domid structure field, as it saying "gmfn_foreign" would otherwise become stale with your change.

Thanks for pointing out that. I've already updated it.

Quoted 4 lines

I don't, btw, like the ARM only part here - there's nothing inherently wrong with the same operation being sensible on x86.

I agree that we should make this also available to x86 guests, but we have to fix the FIXME in x86/mm/p2m.c: p2m_add_foreign() first. And that, I think, should be done in another patch set. And "currently" here also means that it's planned to be fixed. I just don't want to disappoint the users who are eager to try this new subop out but end up getting weired errors.

Cheers,

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#12 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Quoted 40 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 18:02, <[email protected]> wrote:

2018-02-14 16:37 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 32 lines
Quoted 15 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 08:15, <[email protected]> wrote:

2018-02-13 23:26 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 10 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line · On 13.02.18 at 16:15, <[email protected]> wrote:

I've updated the comments according to your previous suggestions, do they look good to you?

The one in the public header is way too verbose. I specifically don't see why you would need to spell out XSM privilege requirements there. Please make new comments match existing ones in style and verbosity if at all possible, while still conveying all necessary / relevant information.

I shortened it a little bit, and now it looks like:

Quoted 10 lines

#define XENMAPSPACE_gmfn_share 6 /* GMFN from another dom. Unlike
gmfn_foreign,
if (c) tries to map pages from (t) into (d), this doesn't require that (d) itself has the privilege to map the pages, but instead requires that (c) has the privilege to do so, as long as (d) and (t) are allowed to share memory pages. This is XENMEM_add_to_physmap_batch only, and currently ARM only. */

Which leaves unclear what (c), (d), and (t) are. How about

"GMFN from another dom, XENMEM_add_to_physmap_batch (and currently ARM) only. Other than XENMAPSPACE_gmfn_foreign this <explain here what the difference is with a few simple words>."

Quoted 5 lines

(You can and should go into further detail in the commit message.) Without this _properly_ explained, I'll continue to ask why you can't simply make XENMAPSPACE_gmfn_foreign do what you want (as it already takes two domid_t-s as input), by suitably adjusting its XSM check(s).

Quoted 6 lines

I'm sorry that I failed to see the reason why you say "which leaves unclear what (c), (d), and (t) are". I think "if (c) tries to map pages from (t) into (d)" has already included the necessary information about this: (c) is the caller of the hypercall (current), (d) is the dest domain, and (t) the source domain.
I think I still need more of your explanation here.

Someone coming across _just_ this comment (while reading the public header) will not necessarily know what (c), (d), and (t) stand for, and (s)he shouldn't be forced to dig into git history to find the patch description. But anyway - all this should go away from the header anyway, as explained before. All that's needed here is a terse but understandable explanation of what's different from XENMAPSPACE_gmfn_foreign.

Jan

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#13 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Hi Jan,

(Last week was the Chinese Spring Festival, so I failed to follow up timely. Sorry for that.)

2018-02-15 16:58 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 47 lines
Quoted 40 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 18:02, <[email protected]> wrote:

2018-02-14 16:37 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 32 lines
Quoted 15 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 08:15, <[email protected]> wrote:

2018-02-13 23:26 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 10 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line · On 13.02.18 at 16:15, <[email protected]> wrote:

I've updated the comments according to your previous suggestions, do they look good to you?

The one in the public header is way too verbose. I specifically don't see why you would need to spell out XSM privilege requirements there. Please make new comments match existing ones in style and verbosity if at all possible, while still conveying all necessary / relevant information.

I shortened it a little bit, and now it looks like:

Quoted 10 lines

#define XENMAPSPACE_gmfn_share 6 /* GMFN from another dom. Unlike
gmfn_foreign,
if (c) tries to map pages from (t) into (d), this doesn't require that (d) itself has the privilege to map the pages, but instead requires that (c) has the privilege to do so, as long as (d) and (t) are allowed to share memory pages. This is XENMEM_add_to_physmap_batch only, and currently ARM only. */

Which leaves unclear what (c), (d), and (t) are. How about

"GMFN from another dom, XENMEM_add_to_physmap_batch (and currently ARM) only. Other than XENMAPSPACE_gmfn_foreign this <explain here what the difference is with a few simple words>."

Quoted 5 lines

(You can and should go into further detail in the commit message.) Without this _properly_ explained, I'll continue to ask why you can't simply make XENMAPSPACE_gmfn_foreign do what you want (as it already takes two domid_t-s as input), by suitably adjusting its XSM check(s).

Quoted 6 lines

I'm sorry that I failed to see the reason why you say "which leaves unclear what (c), (d), and (t) are". I think "if (c) tries to map pages from (t) into (d)" has already included the necessary information about this: (c) is the caller of the hypercall (current), (d) is the dest domain, and (t) the source domain.
I think I still need more of your explanation here.

Quoted 8 lines

Someone coming across _just_ this comment (while reading the public header) will not necessarily know what (c), (d), and (t) stand for, and (s)he shouldn't be forced to dig into git history to find the patch description. But anyway - all this should go away from the header anyway, as explained before. All that's needed here is a terse but understandable explanation of what's different from XENMAPSPACE_gmfn_foreign.

I think before we can reach a consensus on how the final comment should look like, we need to reach an agreement on what should be included in the <differences> part. And according to our previous discussion, below is what I think is necessary so far:

1. Different privilege requirements

2. Why we can't just modify the original hypercall to meet our needs.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#14 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

... Sorry for the incomplete mail. I somehow hit the "send" button before I finish composing the previous mail. And now it continues...

2018-02-24 10:50 GMT+08:00 Zhongze Liu <[email protected]>:

Quoted 62 lines

Hi Jan,

(Last week was the Chinese Spring Festival, so I failed to follow up timely. Sorry for that.)

2018-02-15 16:58 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 47 lines
Quoted 40 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 18:02, <[email protected]> wrote:

2018-02-14 16:37 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 32 lines
Quoted 15 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 08:15, <[email protected]> wrote:

2018-02-13 23:26 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 10 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line · On 13.02.18 at 16:15, <[email protected]> wrote:

I've updated the comments according to your previous suggestions, do they look good to you?

The one in the public header is way too verbose. I specifically don't see why you would need to spell out XSM privilege requirements there. Please make new comments match existing ones in style and verbosity if at all possible, while still conveying all necessary / relevant information.

I shortened it a little bit, and now it looks like:

Quoted 10 lines

#define XENMAPSPACE_gmfn_share 6 /* GMFN from another dom. Unlike
gmfn_foreign,
if (c) tries to map pages from (t) into (d), this doesn't require that (d) itself has the privilege to map the pages, but instead requires that (c) has the privilege to do so, as long as (d) and (t) are allowed to share memory pages. This is XENMEM_add_to_physmap_batch only, and currently ARM only. */

Which leaves unclear what (c), (d), and (t) are. How about

"GMFN from another dom, XENMEM_add_to_physmap_batch (and currently ARM) only. Other than XENMAPSPACE_gmfn_foreign this <explain here what the difference is with a few simple words>."

Quoted 5 lines

(You can and should go into further detail in the commit message.) Without this _properly_ explained, I'll continue to ask why you can't simply make XENMAPSPACE_gmfn_foreign do what you want (as it already takes two domid_t-s as input), by suitably adjusting its XSM check(s).

Quoted 6 lines

I'm sorry that I failed to see the reason why you say "which leaves unclear what (c), (d), and (t) are". I think "if (c) tries to map pages from (t) into (d)" has already included the necessary information about this: (c) is the caller of the hypercall (current), (d) is the dest domain, and (t) the source domain.
I think I still need more of your explanation here.

Quoted 8 lines

Someone coming across _just_ this comment (while reading the public header) will not necessarily know what (c), (d), and (t) stand for, and (s)he shouldn't be forced to dig into git history to find the patch description. But anyway - all this should go away from the header anyway, as explained before. All that's needed here is a terse but understandable explanation of what's different from XENMAPSPACE_gmfn_foreign.

Quoted 7 lines

I think before we can reach a consensus on how the final comment should look like, we need to reach an agreement on what should be included in the <differences> part. And according to our previous discussion, below is what I think is necessary so far:

1. Different privilege requirements

This is what I've been trying to convey in the comment. But it seems that I failed to make it "terse yet understandable". Now my question is: Am I *not* supposed to spell out the detail of the exact difference between their privilege requirements? If so, do you have a rough picture of how it should look like? Are we going to give an example of a use case where the old subop is not applicable?

Quoted 2 lines

2. Why we can't just modify the original hypercall to meet our needs.

According to our discussion on the previous versions of this patch, we can't fit the checks needed by both subop into one because doing so will either regress the original one or permit something that shouldn't be allowed in the new use cases. Should we clarify this in the comment, too?

Cheers,
and Best Wishes.

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#15 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

Quoted 88 lines
Quoted 1 line
Quoted 1 line · On 24.02.18 at 06:37, <[email protected]> wrote:

... Sorry for the incomplete mail. I somehow hit the "send" button before I finish composing the previous mail. And now it continues...

2018-02-24 10:50 GMT+08:00 Zhongze Liu <[email protected]>:

Quoted 26 lines

Hi Jan,

(Last week was the Chinese Spring Festival, so I failed to follow up timely. Sorry for that.)

2018-02-15 16:58 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 20 lines
Quoted 20 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 18:02, <[email protected]> wrote:

2018-02-14 16:37 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 18 lines
Quoted 18 lines
Quoted 1 line
Quoted 1 line · On 14.02.18 at 08:15, <[email protected]> wrote:

2018-02-13 23:26 GMT+08:00 Jan Beulich <[email protected]>:

Quoted 10 lines
Quoted 3 lines
Quoted 1 line
Quoted 1 line · On 13.02.18 at 16:15, <[email protected]> wrote:

I've updated the comments according to your previous suggestions, do they look good to you?

The one in the public header is way too verbose. I specifically don't see why you would need to spell out XSM privilege requirements there. Please make new comments match existing ones in style and verbosity if at all possible, while still conveying all necessary / relevant information.

I shortened it a little bit, and now it looks like:

#define XENMAPSPACE_gmfn_share 6 /* GMFN from another dom. Unlike
gmfn_foreign,
if (c) tries to map pages from (t)

into

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

(d), this doesn't require that (d)

itself

Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

has the privilege to map the pages,

but

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

instead requires that (c) has the privilege to do so, as long as (d) and

(t)

Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines
Quoted 2 lines

are allowed to share memory pages. This is XENMEM_add_to_physmap_batch

only,

Quoted 30 lines
Quoted 21 lines
Quoted 14 lines
Quoted 8 lines
Quoted 1 line

and currently ARM only. */

Which leaves unclear what (c), (d), and (t) are. How about

"GMFN from another dom, XENMEM_add_to_physmap_batch (and currently ARM) only. Other than XENMAPSPACE_gmfn_foreign this <explain here what the difference is with a few simple words>."

Quoted 5 lines

(You can and should go into further detail in the commit message.) Without this _properly_ explained, I'll continue to ask why you can't simply make XENMAPSPACE_gmfn_foreign do what you want (as it already takes two domid_t-s as input), by suitably adjusting its XSM check(s).

Quoted 6 lines

I'm sorry that I failed to see the reason why you say "which leaves unclear what (c), (d), and (t) are". I think "if (c) tries to map pages from (t) into (d)" has already included the necessary information about this: (c) is the caller of the hypercall (current), (d) is the dest domain, and (t) the source domain.
I think I still need more of your explanation here.

Quoted 8 lines

Someone coming across _just_ this comment (while reading the public header) will not necessarily know what (c), (d), and (t) stand for, and (s)he shouldn't be forced to dig into git history to find the patch description. But anyway - all this should go away from the header anyway, as explained before. All that's needed here is a terse but understandable explanation of what's different from XENMAPSPACE_gmfn_foreign.

Quoted 7 lines

I think before we can reach a consensus on how the final comment should look like, we need to reach an agreement on what should be included in the <differences> part. And according to our previous discussion, below is what I think is necessary so far:

1. Different privilege requirements

This is what I've been trying to convey in the comment. But it seems that I failed to make it "terse yet understandable". Now my question is: Am I *not* supposed to spell out the detail of the exact difference between their privilege requirements? If so, do you have a rough picture of how it should look like? Are we going to give an example of a use case where the old subop is not applicable?

Quoted 1 line
Quoted 6 lines
Quoted 1 line

2. Why we can't just modify the original hypercall to meet our needs.

According to our discussion on the previous versions of this patch, we can't fit the checks needed by both subop into one because doing so will either regress the original one or permit something that shouldn't be allowed in the new use cases. Should we clarify this in the comment, too?

My view on this is: The comment ought to describe the behavior, nothing else. The commit message ought to explain the difference to the existing sub-op, to help understand / explain the reason why the existing one can't be suitably extended.

Jan

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#16 lore raw

Re: [PATCH v4 2/7] xen: xsm: flask: introduce XENMAPSPACE_gmfn_share for memory sharing

In reply to Zhongze Liu

Hi,

Quoted 13 lines · Zhongze Liu
xen/arch/arm/mm.c +1 -0
index 3c328e2df5..8e385d62a8 100644
@@ -1251,6 +1251,7 @@ int xenmem_add_to_physmap_one(
 
          break;
      case XENMAPSPACE_gmfn_foreign:
+    case XENMAPSPACE_gmfn_share:
      {
          struct domain *od;
          p2m_type_t p2mt;

xen/arch/arm/mm.c int xenmem_add_to_physmap_one( · line 1273

Quoted 9 lines
xen/arch/arm/mm.c +5 -1
@@ -1265,7 +1266,12 @@ int xenmem_add_to_physmap_one(
              return -EINVAL;
          }
 
-        rc = xsm_map_gmfn_foreign(XSM_TARGET, d, od);
+        if ( space == XENMAPSPACE_gmfn_foreign ) {
+            rc = xsm_map_gmfn_foreign(XSM_TARGET, d, od);
+        } else {
+            rc = xsm_map_gmfn_share(XSM_TARGET, d, od);
+        }

Coding style:

if ( .... )
{
}
else
{
}

But in that case, there braces are not necessary. So you could do if ( ... )
...
else
...

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#17 lore raw

PATCH v4 3/7 libxl: introduce a new structure to represent static shared memory regions

In reply to Zhongze Liu

Add a new structure to the IDL familiy to represent static shared memory regions as proposed in the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]).

And deleted some trailing white spaces.

[1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Cc Wei Liu <[email protected]>
Cc Ian Jackson <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>
---
 tools/libxl/libxl.h         |  4 ++++
 tools/libxl/libxl_types.idl | 32 ++++++++++++++++++++++++++++++--
 2 files changed, 34 insertions(+), 2 deletions(-)
tools/libxl/libxl.h +4 -0
index eca0ea2c50..372ad3cd32 100644
@@ -2365,6 +2365,10 @@ int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock);
 int libxl_qemu_monitor_command(libxl_ctx *ctx, uint32_t domid,
                                const char *command_line, char **output);
 
+/* Constants for libxl_static_shm */
+#define LIBXL_SSHM_RANGE_UNKNOWN UINT64_MAX
+#define LIBXL_SSHM_ID_MAXLEN    128
+
 #include <libxl_event.h>
 
 #endif /* LIBXL_H */
tools/libxl/libxl_types.idl +30 -2
index 35038120ca..4e9accf168 100644
@@ -559,10 +559,10 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                        ("keymap",           string),
                                        ("sdl",              libxl_sdl_info),
                                        ("spice",            libxl_spice_info),
-                                       
+
                                        ("gfx_passthru",     libxl_defbool),
                                        ("gfx_passthru_kind", libxl_gfx_passthru_kind),
-                                       
+
                                        ("serial",           string),
                                        ("boot",             string),
                                        ("usb",              libxl_defbool),
@@ -816,6 +816,33 @@ libxl_device_vdispl = Struct("device_vdispl", [
     ("connectors", Array(libxl_connector_param, "num_connectors"))
     ])
 
+libxl_sshm_cachepolicy = Enumeration("sshm_cachepolicy", [
+    (-1, "UNKNOWN"),
+    (0,  "ARM_NORMAL"),  # ARM policies should be < 32
+    (32,  "X86_NORMAL"), # X86 policies should be >= 32
+    ], init_val = "LIBXL_SSHM_CHCHE_POLICY_UNKNOWN")
+
+libxl_sshm_prot = Enumeration("sshm_prot", [
+    (-1, "UNKNOWN"),
+    (3,  "RW"),
+    ], init_val = "LIBXL_SSHM_PROT_UNKNOWN")
+
+libxl_sshm_role = Enumeration("sshm_role", [
+    (-1, "UNKNOWN"),
+    (0,  "MASTER"),
+    (1,  "SLAVE"),
+    ], init_val = "LIBXL_SSHM_ROLE_UNKNOWN")
+
+libxl_static_shm = Struct("static_shm", [
+    ("id", string),
+    ("offset", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("begin", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("end", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("prot", libxl_sshm_prot, {'init_val': 'LIBXL_SSHM_PROT_UNKNOWN'}),
+    ("cache_policy", libxl_sshm_cachepolicy, {'init_val': 'LIBXL_SSHM_CACHEPOLICY_UNKNOWN'}),
+    ("role", libxl_sshm_role, {'init_val': 'LIBXL_SSHM_ROLE_UNKNOWN'}),
+])
+
 libxl_domain_config = Struct("domain_config", [
     ("c_info", libxl_domain_create_info),
     ("b_info", libxl_domain_build_info),
@@ -835,6 +862,7 @@ libxl_domain_config = Struct("domain_config", [
     ("channels", Array(libxl_device_channel, "num_channels")),
     ("usbctrls", Array(libxl_device_usbctrl, "num_usbctrls")),
     ("usbdevs", Array(libxl_device_usbdev, "num_usbdevs")),
+    ("sshms", Array(libxl_static_shm, "num_sshms")),
 
     ("on_poweroff", libxl_action_on_shutdown),
     ("on_reboot", libxl_action_on_shutdown),
Signature · 7 lines
2.16.1


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#18 lore raw

Re: [PATCH v4 3/7] libxl: introduce a new structure to represent static shared memory regions

Hi,

Quoted 1 line · Zhongze Liu

Add a new structure to the IDL familiy to represent static shared memory regions

s/familiy/family/

Quoted 26 lines

as proposed in the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]).

And deleted some trailing white spaces.

[1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Cc Wei Liu <[email protected]>
Cc Ian Jackson <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>
---
  tools/libxl/libxl.h         |  4 ++++
  tools/libxl/libxl_types.idl | 32 ++++++++++++++++++++++++++++++--
  2 files changed, 34 insertions(+), 2 deletions(-)
tools/libxl/libxl.h +0 -0
index eca0ea2c50..372ad3cd32 100644

tools/libxl/libxl.h int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock); · line 2371

Quoted 7 lines
tools/libxl/libxl.h +4 -0
@@ -2365,6 +2365,10 @@ int libxl_fd_set_nonblock(libxl_ctx *ctx, int fd, int nonblock);
  int libxl_qemu_monitor_command(libxl_ctx *ctx, uint32_t domid,
                                 const char *command_line, char **output);
 
+/* Constants for libxl_static_shm */
+#define LIBXL_SSHM_RANGE_UNKNOWN UINT64_MAX
+#define LIBXL_SSHM_ID_MAXLEN    128
+

You need to add LIBXL_HAVE_* in libxl.h to tell shared memory regions are available. I wasn't able to find anything within this series.

Quoted 36 lines
tools/libxl/libxl.h +0 -0
  #include <libxl_event.h>
 
  #endif /* LIBXL_H */
tools/libxl/libxl_types.idl +14 -2
index 35038120ca..4e9accf168 100644
@@ -559,10 +559,10 @@ libxl_domain_build_info = Struct("domain_build_info",[
                                         ("keymap",           string),
                                         ("sdl",              libxl_sdl_info),
                                         ("spice",            libxl_spice_info),
-
+
                                         ("gfx_passthru",     libxl_defbool),
                                         ("gfx_passthru_kind", libxl_gfx_passthru_kind),
-
+
                                         ("serial",           string),
                                         ("boot",             string),
                                         ("usb",              libxl_defbool),
@@ -816,6 +816,33 @@ libxl_device_vdispl = Struct("device_vdispl", [
      ("connectors", Array(libxl_connector_param, "num_connectors"))
      ])
 
+libxl_sshm_cachepolicy = Enumeration("sshm_cachepolicy", [
+    (-1, "UNKNOWN"),
+    (0,  "ARM_NORMAL"),  # ARM policies should be < 32
+    (32,  "X86_NORMAL"), # X86 policies should be >= 32
+    ], init_val = "LIBXL_SSHM_CHCHE_POLICY_UNKNOWN")
+
+libxl_sshm_prot = Enumeration("sshm_prot", [
+    (-1, "UNKNOWN"),
+    (3,  "RW"),
+    ], init_val = "LIBXL_SSHM_PROT_UNKNOWN")
+
+libxl_sshm_role = Enumeration("sshm_role", [

tools/libxl/libxl_types.idl libxl_device_vdispl = Struct("device_vdispl", [ · line 840

Quoted 10 lines
tools/libxl/libxl_types.idl +10 -0
+    (-1, "UNKNOWN"),
+    (0,  "MASTER"),
+    (1,  "SLAVE"),
+    ], init_val = "LIBXL_SSHM_ROLE_UNKNOWN")
+
+libxl_static_shm = Struct("static_shm", [
+    ("id", string),
+    ("offset", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("begin", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("end", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),

We might want to store the size rather than the end. This would allow us to cover region up to the address 2^64-1.

Also, this would make clearer whether end is included in the region or not.

Quoted 10 lines
tools/libxl/libxl_types.idl +5 -0
+    ("prot", libxl_sshm_prot, {'init_val': 'LIBXL_SSHM_PROT_UNKNOWN'}),
+    ("cache_policy", libxl_sshm_cachepolicy, {'init_val': 'LIBXL_SSHM_CACHEPOLICY_UNKNOWN'}),
+    ("role", libxl_sshm_role, {'init_val': 'LIBXL_SSHM_ROLE_UNKNOWN'}),
+])
+
  libxl_domain_config = Struct("domain_config", [
      ("c_info", libxl_domain_create_info),
      ("b_info", libxl_domain_build_info),

tools/libxl/libxl_types.idl libxl_domain_config = Struct("domain_config", [ · line 868

Quoted 7 lines
tools/libxl/libxl_types.idl +1 -0
@@ -835,6 +862,7 @@ libxl_domain_config = Struct("domain_config", [
      ("channels", Array(libxl_device_channel, "num_channels")),
      ("usbctrls", Array(libxl_device_usbctrl, "num_usbctrls")),
      ("usbdevs", Array(libxl_device_usbdev, "num_usbdevs")),
+    ("sshms", Array(libxl_static_shm, "num_sshms")),
 
      ("on_poweroff", libxl_action_on_shutdown),
      ("on_reboot", libxl_action_on_shutdown),

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#19 lore raw

Re: [PATCH v4 3/7] libxl: introduce a new structure to represent static shared memory regions

Hi Julien,

Thanks for reviewing.

2018-02-06 19:27 GMT+08:00 Julien Grall <[email protected]>:

Quoted 6 lines

Hi,

Quoted 3 lines · Zhongze Liu

Add a new structure to the IDL familiy to represent static shared memory regions

[...]

Quoted 7 lines

tools/libxl/libxl_types.idl libxl_device_vdispl = Struct("device_vdispl", [ · line 840

Quoted 5 lines
tools/libxl/libxl_types.idl +5 -0
+libxl_static_shm = Struct("static_shm", [
+    ("id", string),
+    ("offset", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("begin", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("end", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
Quoted 5 lines

We might want to store the size rather than the end. This would allow us to cover region up to the address 2^64-1.

Also, this would make clearer whether end is included in the region or not.

I think making the range inclusive and documenting it would have the same effect.
But I'm not sure which syntax is more friendly to the users. What do you think?

Zhongze Liu

Cheers.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#20 lore raw

Re: [PATCH v4 3/7] libxl: introduce a new structure to represent static shared memory regions

Hi,

Quoted 22 lines · Zhongze Liu

Thanks for reviewing.

2018-02-06 19:27 GMT+08:00 Julien Grall <[email protected]>:

Quoted 6 lines

Hi,

Quoted 3 lines · Zhongze Liu

Add a new structure to the IDL familiy to represent static shared memory regions

[...]

Quoted 10 lines

tools/libxl/libxl_types.idl libxl_device_vdispl = Struct("device_vdispl", [ · line 840

Quoted 5 lines
tools/libxl/libxl_types.idl +5 -0
+libxl_static_shm = Struct("static_shm", [
+    ("id", string),
+    ("offset", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("begin", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("end", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),

We might want to store the size rather than the end. This would allow us to cover region up to the address 2^64-1.

Quoted 6 lines
Quoted 2 lines

Also, this would make clearer whether end is included in the region or not.

I think making the range inclusive and documenting it would have the same effect.
But I'm not sure which syntax is more friendly to the users. What do you think?

You would still run into some problem. Indeed LIBX_SSHM_RANGE_UNKNOWN is defined as UINT64_MAX. So how would you differentiate them?

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#21 lore raw

Re: [PATCH v4 3/7] libxl: introduce a new structure to represent static shared memory regions

Hi,

2018-02-06 23:46 GMT+08:00 Julien Grall <[email protected]>:

Quoted 35 lines

Hi,

Quoted 32 lines · Zhongze Liu

Thanks for reviewing.

2018-02-06 19:27 GMT+08:00 Julien Grall <[email protected]>:

Quoted 8 lines

Hi,

Quoted 4 lines · Zhongze Liu

Add a new structure to the IDL familiy to represent static shared memory regions

[...]

Quoted 15 lines

tools/libxl/libxl_types.idl libxl_device_vdispl = Struct("device_vdispl", [ · line 840

Quoted 5 lines
tools/libxl/libxl_types.idl +5 -0
+libxl_static_shm = Struct("static_shm", [
+    ("id", string),
+    ("offset", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("begin", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("end", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),

We might want to store the size rather than the end. This would allow us to
cover region up to the address 2^64-1.

Also, this would make clearer whether end is included in the region or not.

Quoted 8 lines
Quoted 4 lines

I think making the range inclusive and documenting it would have the same effect.
But I'm not sure which syntax is more friendly to the users. What do you think?

You would still run into some problem. Indeed LIBX_SSHM_RANGE_UNKNOWN is defined as UINT64_MAX. So how would you differentiate them?

But saying inclusive, I was actually trying to say "including the page that begins at @end", so
the only possibility when LIBXL_SSHM_RANGE_UNKNOWN would be a valid value for @end is when the page granularity is 1byte, which, I think, is not very likely to happen.

But soon I find this might lead to more confusion. Now I agree with you that we should use
the begin/size syntax instead of the current one.

Cheers,

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#22 lore raw

Re: [PATCH v4 3/7] libxl: introduce a new structure to represent static shared memory regions

Quoted 1 line · Zhongze Liu

Hi,

Hi,

Quoted 42 lines

2018-02-06 23:46 GMT+08:00 Julien Grall <[email protected]>:

Quoted 41 lines

Hi,

Quoted 36 lines · Zhongze Liu

Thanks for reviewing.

2018-02-06 19:27 GMT+08:00 Julien Grall <[email protected]>:

Quoted 8 lines

Hi,

Quoted 4 lines · Zhongze Liu

Add a new structure to the IDL familiy to represent static shared memory regions

[...]

Quoted 8 lines

tools/libxl/libxl_types.idl libxl_device_vdispl = Struct("device_vdispl", [ · line 840

Quoted 5 lines
tools/libxl/libxl_types.idl +5 -0
+libxl_static_shm = Struct("static_shm", [
+    ("id", string),
+    ("offset", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("begin", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
+    ("end", uint64, {'init_val': 'LIBXL_SSHM_RANGE_UNKNOWN'}),
Quoted 7 lines

We might want to store the size rather than the end. This would allow us to
cover region up to the address 2^64-1.

Also, this would make clearer whether end is included in the region or not.

I think making the range inclusive and documenting it would have the same effect.
But I'm not sure which syntax is more friendly to the users. What do you think?

Quoted 5 lines
Quoted 2 lines

You would still run into some problem. Indeed LIBX_SSHM_RANGE_UNKNOWN is defined as UINT64_MAX. So how would you differentiate them?

But saying inclusive, I was actually trying to say "including the page that begins at @end", so

Which is quite confusing. Usually when I see a range, I assume that the end will be the actual end. Not PAGE_ALIGN(end).

Quoted 7 lines

the only possibility when LIBXL_SSHM_RANGE_UNKNOWN would be a valid value for @end is when the page granularity is 1byte, which, I think, is not very likely to happen.

But soon I find this might lead to more confusion. Now I agree with you that we should use
the begin/size syntax instead of the current one.

Yes, begin/size is straightforward. There are no way to lead to map one less (or extra) page by confusion.

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#23 lore raw

PATCH v4 4/7 libxl: support mapping static shared memory areas during domain creation

In reply to Zhongze Liu

Add libxl__sshm_add to map shared pages from one DomU to another, The mapping process involves the follwing steps:

* Set defaults and check for further errors in the static_shm configs:
overlapping areas, invalid ranges, duplicated master domain, not page aligned, no master domain etc.
* Use xc_domain_add_to_physmap_batch to do the page sharing.
* When some of the pages can't be successfully mapped, roll back any successfully mapped pages so that the system stays in a consistent state.
* Write infomation about static shared memory areas into the appropriate xenstore paths and set the refcount of the shared region accordingly.

Temporarily mark this as unsupported on x86 because calling p2m_add_foreign on two domU's is currently not allowd on x86 (see the comments in x86/mm/p2m.c:p2m_add_foreign for more details).

This is for the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]).

[1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Cc Wei Liu <[email protected]>
Cc Ian Jackson <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>

---
V3:
* Unmap the successfully mapped pages whenever rc != 0.

V4:
* Use XENMAPSPACE_gmfn_share instead of *_gmfn_foreign.

---
 tools/libxl/Makefile         |   2 +-
 tools/libxl/libxl_arch.h     |   6 +
 tools/libxl/libxl_arm.c      |  15 ++
 tools/libxl/libxl_create.c   |  27 +++
 tools/libxl/libxl_internal.h |  14 ++
 tools/libxl/libxl_sshm.c     | 397 +++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_x86.c      |  19 +++
 7 files changed, 479 insertions(+), 1 deletion(-)
 create mode 100644 tools/libxl/libxl_sshm.c
tools/libxl/Makefile +1 -1
index 917ceb0e72..e2834d84dc 100644
@@ -139,7 +139,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
 			libxl_dom_suspend.o libxl_dom_save.o libxl_usb.o \
 			libxl_vtpm.o libxl_nic.o libxl_disk.o libxl_console.o \
 			libxl_cpupool.o libxl_mem.o libxl_sched.o libxl_tmem.o \
-			libxl_9pfs.o libxl_domain.o libxl_vdispl.o \
+			libxl_9pfs.o libxl_domain.o libxl_vdispl.o libxl_sshm.o \
                         $(LIBXL_OBJS-y)
 LIBXL_OBJS += libxl_genid.o
 LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
tools/libxl/libxl_arch.h +6 -0
index 784ec7f609..11433fe466 100644
@@ -78,6 +78,12 @@ int libxl__arch_extra_memory(libxl__gc *gc,
                              const libxl_domain_build_info *info,
                              uint64_t *out);
 
+_hidden
+bool libxl__arch_domain_support_sshm(const libxl_domain_build_info *b_info);
+
+_hidden
+int libxl__arch_domain_sshm_cachepolicy_setdefault(libxl_static_shm *sshm);
+
 #if defined(__i386__) || defined(__x86_64__)
 
 #define LAPIC_BASE_ADDRESS  0xfee00000
tools/libxl/libxl_arm.c +15 -0
index 3e46554301..e14879ec08 100644
@@ -1154,6 +1154,21 @@ void libxl__arch_domain_build_info_acpi_setdefault(
     libxl_defbool_setdefault(&b_info->acpi, false);
 }
 
+bool libxl__arch_domain_support_sshm(const libxl_domain_build_info *b_info)
+{
+    return true;
+}
+
+int libxl__arch_domain_sshm_cachepolicy_setdefault(libxl_static_shm *sshm)
+{
+    if (sshm->cache_policy == LIBXL_SSHM_CACHEPOLICY_UNKNOWN)
+        sshm->cache_policy = LIBXL_SSHM_CACHEPOLICY_ARM_NORMAL;
+    if (sshm->cache_policy >= LIBXL_SSHM_CACHEPOLICY_X86_NORMAL)
+        return ERROR_INVAL;
+
+    return 0;
+}
+
 /*
  * Local variables:
  * mode: C
tools/libxl/libxl_create.c +27 -0
index c498135246..98c16867bf 100644
@@ -532,6 +532,14 @@ int libxl__domain_build(libxl__gc *gc,
         ret = ERROR_INVAL;
         goto out;
     }
+
+    /* the p2m has been setup, we could map the static shared memory now. */
+    ret = libxl__sshm_add(gc, domid, d_config->sshms, d_config->num_sshms);
+    if (ret != 0) {
+        LOG(ERROR, "failed to map static shared memory");
+        goto out;
+    }
+
     ret = libxl__build_post(gc, domid, info, state, vments, localents);
 out:
     return ret;
@@ -957,6 +965,25 @@ static void initiate_domain_create(libxl__egc *egc,
         goto error_out;
     }
 
+    if (d_config->num_sshms != 0 &&
+        !libxl__arch_domain_support_sshm(&d_config->b_info)) {
+        LOGD(ERROR, domid, "static_shm is not supported by this domain type.");
+        ret = ERROR_INVAL;
+        goto error_out;
+    }
+
+    for (i = 0; i < d_config->num_sshms; ++i) {
+        ret = libxl__sshm_setdefault(gc, domid, &d_config->sshms[i]);
+        if (ret) {
+            LOGD(ERROR, domid, "Unable to set defaults for static shm");
+            goto error_out;
+        }
+    }
+
+    ret = libxl__sshm_check_overlap(gc, domid,
+                                    d_config->sshms, d_config->num_sshms);
+    if (ret) goto error_out;
+
     ret = libxl__domain_make(gc, d_config, &domid, &state->config);
     if (ret) {
         LOGD(ERROR, domid, "cannot make domain: %d", ret);
tools/libxl/libxl_internal.h +14 -0
index 506687fbe9..2cfe4c08a7 100644
@@ -4415,6 +4415,20 @@ static inline bool libxl__string_is_default(char **s)
 }
 #endif
 
+/*
+ * Set up static shared ram pages for HVM domains to communicate
+ *
+ * This function should only be called after the memory map is constructed
+ * and before any further memory access.
+ */
+_hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
+                            libxl_static_shm *sshm, int len);
+
+_hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
+                                      libxl_static_shm *sshms, int len);
+_hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
+                                   libxl_static_shm *sshm);
+
 /*
  * Local variables:
  * mode: C
tools/libxl/libxl_sshm.c new file +397 -0

397 lines not on this page · raw message

tools/libxl/libxl_x86.c +19 -0
index 5f91fe4f92..8ec5044eb2 100644
@@ -596,6 +596,25 @@ void libxl__arch_domain_build_info_acpi_setdefault(
     libxl_defbool_setdefault(&b_info->acpi, true);
 }
 
+bool libxl__arch_domain_support_sshm(const libxl_domain_build_info *b_info)
+{
+    /* FIXME: Mark this as unsupported for calling p2m_add_foreign on two
+     * DomU's is currently not allowd on x86, see the comments in
+     * x86/mm/p2m.c: p2m_add_foreign.
+     */
+     return false;
+}
+
+int libxl__arch_domain_sshm_cachepolicy_setdefault(libxl_static_shm *sshm)
+{
+    if (sshm->cache_policy == LIBXL_SSHM_CACHEPOLICY_UNKNOWN)
+        sshm->cache_policy = LIBXL_SSHM_CACHEPOLICY_X86_NORMAL;
+    if (sshm->cache_policy < LIBXL_SSHM_CACHEPOLICY_X86_NORMAL)
+        return ERROR_INVAL;
+
+    return 0;
+}
+
 /*
  * Local variables:
  * mode: C
Signature · 7 lines
2.16.1


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#24 lore raw

Re: [PATCH v4 4/7] libxl: support mapping static shared memory areas during domain creation

Hi,

Quoted 2 lines · Zhongze Liu

Add libxl__sshm_add to map shared pages from one DomU to another, The mapping process involves the follwing steps:

s/follwing/following/

Quoted 8 lines

* Set defaults and check for further errors in the static_shm configs:
overlapping areas, invalid ranges, duplicated master domain, not page aligned, no master domain etc.
* Use xc_domain_add_to_physmap_batch to do the page sharing.
* When some of the pages can't be successfully mapped, roll back any successfully mapped pages so that the system stays in a consistent state.
* Write infomation about static shared memory areas into the appropriate

s/infomation/information/

Quoted 96 lines

xenstore paths and set the refcount of the shared region accordingly.

Temporarily mark this as unsupported on x86 because calling p2m_add_foreign on two domU's is currently not allowd on x86 (see the comments in x86/mm/p2m.c:p2m_add_foreign for more details).

This is for the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]).

[1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Cc Wei Liu <[email protected]>
Cc Ian Jackson <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>

---
V3:
* Unmap the successfully mapped pages whenever rc != 0.

V4:
* Use XENMAPSPACE_gmfn_share instead of *_gmfn_foreign.

---
  tools/libxl/Makefile         |   2 +-
  tools/libxl/libxl_arch.h     |   6 +
  tools/libxl/libxl_arm.c      |  15 ++
  tools/libxl/libxl_create.c   |  27 +++
  tools/libxl/libxl_internal.h |  14 ++
  tools/libxl/libxl_sshm.c     | 397 +++++++++++++++++++++++++++++++++++++++++++
  tools/libxl/libxl_x86.c      |  19 +++
  7 files changed, 479 insertions(+), 1 deletion(-)

create mode 100644 tools/libxl/libxl_sshm.c

tools/libxl/Makefile +1 -1
index 917ceb0e72..e2834d84dc 100644
@@ -139,7 +139,7 @@ LIBXL_OBJS = flexarray.o libxl.o libxl_create.o libxl_dm.o libxl_pci.o \
  			libxl_dom_suspend.o libxl_dom_save.o libxl_usb.o \
  			libxl_vtpm.o libxl_nic.o libxl_disk.o libxl_console.o \
  			libxl_cpupool.o libxl_mem.o libxl_sched.o libxl_tmem.o \
-			libxl_9pfs.o libxl_domain.o libxl_vdispl.o \
+			libxl_9pfs.o libxl_domain.o libxl_vdispl.o libxl_sshm.o \
                          $(LIBXL_OBJS-y)
  LIBXL_OBJS += libxl_genid.o
  LIBXL_OBJS += _libxl_types.o libxl_flask.o _libxl_types_internal.o
tools/libxl/libxl_arch.h +6 -0
index 784ec7f609..11433fe466 100644
@@ -78,6 +78,12 @@ int libxl__arch_extra_memory(libxl__gc *gc,
                               const libxl_domain_build_info *info,
                               uint64_t *out);
 
+_hidden
+bool libxl__arch_domain_support_sshm(const libxl_domain_build_info *b_info);
+
+_hidden
+int libxl__arch_domain_sshm_cachepolicy_setdefault(libxl_static_shm *sshm);
+
  #if defined(__i386__) || defined(__x86_64__)
 
  #define LAPIC_BASE_ADDRESS  0xfee00000
tools/libxl/libxl_arm.c +15 -0
index 3e46554301..e14879ec08 100644
@@ -1154,6 +1154,21 @@ void libxl__arch_domain_build_info_acpi_setdefault(
      libxl_defbool_setdefault(&b_info->acpi, false);
  }
 
+bool libxl__arch_domain_support_sshm(const libxl_domain_build_info *b_info)
+{
+    return true;
+}
+
+int libxl__arch_domain_sshm_cachepolicy_setdefault(libxl_static_shm *sshm)
+{
+    if (sshm->cache_policy == LIBXL_SSHM_CACHEPOLICY_UNKNOWN)
+        sshm->cache_policy = LIBXL_SSHM_CACHEPOLICY_ARM_NORMAL;
+    if (sshm->cache_policy >= LIBXL_SSHM_CACHEPOLICY_X86_NORMAL)
+        return ERROR_INVAL;
+
+    return 0;
+}
+
  /*
   * Local variables:
   * mode: C
tools/libxl/libxl_create.c +0 -0
index c498135246..98c16867bf 100644

tools/libxl/libxl_create.c int libxl__domain_build(libxl__gc *gc, · line 536

Quoted 5 lines
tools/libxl/libxl_create.c +2 -0
@@ -532,6 +532,14 @@ int libxl__domain_build(libxl__gc *gc,
          ret = ERROR_INVAL;
          goto out;
      }
+
+    /* the p2m has been setup, we could map the static shared memory now. */

s/the/The/

Quoted 76 lines
tools/libxl/libxl_create.c +25 -0
+    ret = libxl__sshm_add(gc, domid, d_config->sshms, d_config->num_sshms);
+    if (ret != 0) {
+        LOG(ERROR, "failed to map static shared memory");
+        goto out;
+    }
+
      ret = libxl__build_post(gc, domid, info, state, vments, localents);
  out:
      return ret;
@@ -957,6 +965,25 @@ static void initiate_domain_create(libxl__egc *egc,
          goto error_out;
      }
 
+    if (d_config->num_sshms != 0 &&
+        !libxl__arch_domain_support_sshm(&d_config->b_info)) {
+        LOGD(ERROR, domid, "static_shm is not supported by this domain type.");
+        ret = ERROR_INVAL;
+        goto error_out;
+    }
+
+    for (i = 0; i < d_config->num_sshms; ++i) {
+        ret = libxl__sshm_setdefault(gc, domid, &d_config->sshms[i]);
+        if (ret) {
+            LOGD(ERROR, domid, "Unable to set defaults for static shm");
+            goto error_out;
+        }
+    }
+
+    ret = libxl__sshm_check_overlap(gc, domid,
+                                    d_config->sshms, d_config->num_sshms);
+    if (ret) goto error_out;
+
      ret = libxl__domain_make(gc, d_config, &domid, &state->config);
      if (ret) {
          LOGD(ERROR, domid, "cannot make domain: %d", ret);
tools/libxl/libxl_internal.h +14 -0
index 506687fbe9..2cfe4c08a7 100644
@@ -4415,6 +4415,20 @@ static inline bool libxl__string_is_default(char **s)
  }
  #endif
 
+/*
+ * Set up static shared ram pages for HVM domains to communicate
+ *
+ * This function should only be called after the memory map is constructed
+ * and before any further memory access.
+ */
+_hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
+                            libxl_static_shm *sshm, int len);
+
+_hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
+                                      libxl_static_shm *sshms, int len);
+_hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
+                                   libxl_static_shm *sshm);
+
  /*
   * Local variables:
   * mode: C
tools/libxl/libxl_sshm.c new file +10 -0
new file mode 100644
index 0000000000..562f46f299
@@ -0,0 +1,397 @@
+#include "libxl_osdeps.h"
+#include "libxl_internal.h"
+#include "libxl_arch.h"
+
+#define SSHM_PATH(id) GCSPRINTF("/libxl/static_shm/%s", id)
+
+#define SSHM_ERROR(domid, sshmid, f, ...)                               \
+    LOGD(ERROR, domid, "static_shm id = %s: " f, sshmid, ##__VA_ARGS__)
+
+

tools/libxl/libxl_sshm.c line 20

Quoted 10 lines
tools/libxl/libxl_sshm.c new file +10 -0
+/* Set default values for libxl_static_shm */
+int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
+                           libxl_static_shm *sshm)
+{
+    int rc;
+
+    if (sshm->role == LIBXL_SSHM_ROLE_UNKNOWN)
+        sshm->role = LIBXL_SSHM_ROLE_SLAVE;
+    if (sshm->prot == LIBXL_SSHM_PROT_UNKNOWN)
+        sshm->prot = LIBXL_SSHM_PROT_RW;

What is the purpose of {ROLE,PROT}_UNKNOWN if you default it resp. to ROLE_SLAVE and PROT_RW. Would not it be easier to just drop them?

Quoted 30 lines
tools/libxl/libxl_sshm.c new file +30 -0
+
+    /* role-specific checks */
+    if (sshm->role == LIBXL_SSHM_ROLE_SLAVE) {
+        if (sshm->offset == LIBXL_SSHM_RANGE_UNKNOWN)
+            sshm->offset = 0;
+        if (sshm->cache_policy != LIBXL_SSHM_CACHEPOLICY_UNKNOWN) {
+            SSHM_ERROR(domid, sshm->id,
+                       "cache_policy is only applicable to master domains");
+            rc = ERROR_INVAL;
+            goto out;
+        }
+    } else {
+        if (sshm->offset != LIBXL_SSHM_RANGE_UNKNOWN) {
+            SSHM_ERROR(domid, sshm->id,
+                       "offset is only applicable to slave domains");
+            rc = ERROR_INVAL;
+            goto out;
+        }
+
+        rc = libxl__arch_domain_sshm_cachepolicy_setdefault(sshm);
+        if (rc) {
+            SSHM_ERROR(domid, sshm->id,
+                       "cache policy not supported on this platform");
+            goto out;
+        }
+    }
+
+    rc = 0;
+out:
+    return rc;

tools/libxl/libxl_sshm.c line 60

Quoted 10 lines
tools/libxl/libxl_sshm.c new file +10 -0
+}
+
+/* Comparator for sorting sshm ranges by sshm->begin */
+static int sshm_range_cmp(const void *a, const void *b)
+{
+    libxl_static_shm *const *sshma = a, *const *sshmb = b;
+    return (*sshma)->begin > (*sshmb)->begin ? 1 : -1;
+}
+
+/* check if the sshm slave configs in @sshm overlap */

s/check/Check/

Quoted 29 lines
tools/libxl/libxl_sshm.c new file +29 -0
+int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
+                                     libxl_static_shm *sshms, int len)
+{
+
+    const libxl_static_shm **slave_sshms = NULL;
+    int num_slaves;
+    int i;
+
+    if (!len) return 0;
+
+    slave_sshms = libxl__calloc(gc, len, sizeof(slave_sshms[0]));
+    num_slaves = 0;
+    for (i = 0; i < len; ++i) {
+        if (sshms[i].role == LIBXL_SSHM_ROLE_SLAVE)
+            slave_sshms[num_slaves++] = sshms + i;
+    }
+    qsort(slave_sshms, num_slaves, sizeof(slave_sshms[0]), sshm_range_cmp);
+
+    for (i = 0; i < num_slaves - 1; ++i) {
+        if (slave_sshms[i+1]->begin < slave_sshms[i]->end) {
+            SSHM_ERROR(domid, slave_sshms[i+1]->id, "slave ranges overlap.");
+            return ERROR_INVAL;
+        }
+    }
+
+    return 0;
+}
+
+/*   libxl__sshm_do_map -- map pages into slave's physmap

tools/libxl/libxl_sshm.c line 99

Quoted 10 lines
tools/libxl/libxl_sshm.c new file +10 -0
+ *
+ *   This functions maps
+ *     master gfn: [@msshm->begin + @sshm->offset, @msshm->end + @sshm->offset)
+ *   into
+ *     slave gfn: [@sshm->begin, @sshm->end)
+ *
+ *   The gfns of the pages that are successfully mapped will be stored
+ *   in @mapped, and the number of the gfns will be stored in @nmapped.
+ *
+ *   The caller have to guarentee that sshm->begin < sshm->end and all the

s/have to/has to/ I think.
s/guarentee/guarantee/

tools/libxl/libxl_sshm.c line 100

Quoted 1 line
tools/libxl/libxl_sshm.c new file +1 -0
+ *   values are page-aligned.

Hmmm, I don't see the alignement check in libxl. So do you rely on the toolstack to do it?

tools/libxl/libxl_sshm.c line 108

Quoted 8 lines
tools/libxl/libxl_sshm.c new file +8 -0
+ */
+static int libxl__sshm_do_map(libxl__gc *gc, uint32_t mid, uint32_t sid,
+                              libxl_static_shm *sshm, libxl_static_shm *msshm,
+                              xen_pfn_t *mapped, unsigned int *nmapped)
+{
+    int rc;
+    int i;
+    unsigned int num_mpages, num_spages, num_success, offset;

A frame number may not fit into a 32-bit value. You would need to use xen_pfn_t (64-bit) here.

Quoted 6 lines
tools/libxl/libxl_sshm.c new file +6 -0
+    int *errs;
+    xen_ulong_t *idxs;
+    xen_pfn_t *gpfns;
+
+    num_mpages = (msshm->end - msshm->begin) >> XC_PAGE_SHIFT;
+    num_spages = (sshm->end - sshm->begin) >> XC_PAGE_SHIFT;

tools/libxl/libxl_sshm.c line 124

Quoted 10 lines
tools/libxl/libxl_sshm.c new file +10 -0
+    offset = sshm->offset >> XC_PAGE_SHIFT;
+
+    /* Check range. Test offset < mpages first to avoid overflow */
+    if ((offset >= num_mpages) || (num_mpages - offset < num_spages)) {
+        SSHM_ERROR(sid, sshm->id, "exceeds master's address space.");
+        rc = ERROR_INVAL;
+        goto out;
+    }
+
+    /* fill out the pfn's and do the mapping */

I think you mean gfn here and not pfn.

Quoted 36 lines
tools/libxl/libxl_sshm.c new file +36 -0
+    errs = libxl__calloc(gc, num_spages, sizeof(int));
+    idxs = libxl__calloc(gc, num_spages, sizeof(xen_ulong_t));
+    gpfns = libxl__calloc(gc, num_spages, sizeof(xen_pfn_t));
+    for (i = 0; i < num_spages; i++) {
+        idxs[i] = (msshm->begin >> XC_PAGE_SHIFT) + offset + i;
+        gpfns[i]= (sshm->begin >> XC_PAGE_SHIFT) + i;
+    }
+    rc = xc_domain_add_to_physmap_batch(CTX->xch,
+                                        sid, mid,
+                                        XENMAPSPACE_gmfn_share,
+                                        num_spages,
+                                        idxs, gpfns, errs);
+
+    num_success = 0;
+    for (i = 0; i < num_spages; i++) {
+        if (errs[i]) {
+            SSHM_ERROR(sid, sshm->id,
+                       "can't map at address 0x%"PRIx64".",
+                       gpfns[i] << XC_PAGE_SHIFT);
+            rc = ERROR_FAIL;
+        } else {
+            mapped[num_success++] = gpfns[i];
+        }
+    }
+    *nmapped = num_success;
+    if (rc) goto out;
+
+    rc = 0;
+out:
+    return rc;
+}
+
+static int libxl__sshm_incref(libxl__gc *gc, xs_transaction_t xt,
+                              const char *sshm_path)
+{
+    int rc, count;

tools/libxl/libxl_sshm.c line 170

Quoted 10 lines
tools/libxl/libxl_sshm.c new file +10 -0
+    const char *count_path, *count_string;
+
+    count_path = GCSPRINTF("%s/usercnt", sshm_path);
+    rc = libxl__xs_read_checked(gc, xt, count_path, &count_string);
+    if (rc) goto out;
+    count = atoi(count_string);
+
+    count_string = GCSPRINTF("%d", count+1);
+    rc = libxl__xs_write_checked(gc, xt, count_path, count_string);
+    if (rc) goto out;

I was a about to say the update does not look safe, but then noticed it was called within a same transation. You might want to add a comment on top of this function to avoid misunderstanding.

Quoted 248 lines
tools/libxl/libxl_sshm.c new file +227 -0
+
+    rc = 0;
+out:
+    return rc;
+}
+
+static int libxl__sshm_add_slave(libxl__gc *gc, uint32_t domid,
+                                 libxl_static_shm *sshm)
+{
+    int rc, i;
+    const char *sshm_path, *slave_path;
+    const char *dom_path, *dom_sshm_path, *dom_role_path;
+    const char *xs_value;
+    char *ents[9];
+    libxl_static_shm master_sshm;
+    uint32_t master_domid;
+    xen_pfn_t *mapped;
+    unsigned int nmapped = 0;
+    xs_transaction_t xt = XBT_NULL;
+    bool isretry;
+
+    sshm_path = SSHM_PATH(sshm->id);
+    slave_path = GCSPRINTF("%s/slaves/%"PRIu32, sshm_path, domid);
+    dom_path = libxl__xs_get_dompath(gc, domid);
+    /* the domain should be in xenstore by now */
+    assert(dom_path);
+    dom_sshm_path = GCSPRINTF("%s/static_shm/%s", dom_path, sshm->id);
+    dom_role_path = GCSPRINTF("%s/role", dom_sshm_path);
+
+    /* prepare the slave xenstore entries */
+    ents[0] = "begin";
+    ents[1] = GCSPRINTF("0x%"PRIx64, sshm->begin);
+    ents[2] = "end";
+    ents[3] = GCSPRINTF("0x%"PRIx64, sshm->end);
+    ents[4] = "offset";
+    ents[5] = GCSPRINTF("0x%"PRIx64, sshm->offset);
+    ents[6] = "prot";
+    ents[7] = libxl__strdup(gc, libxl_sshm_prot_to_string(sshm->prot));
+    ents[8] = NULL;
+
+    mapped = libxl__calloc(gc, (sshm->end - sshm->begin) >> XC_PAGE_SHIFT,
+                           sizeof(xen_pfn_t));
+
+    isretry = false;
+    for (;;) {
+        rc = libxl__xs_transaction_start(gc, &xt);
+        if (rc) goto out;
+
+        if (!libxl__xs_read(gc, xt, sshm_path)) {
+            SSHM_ERROR(domid, sshm->id, "no master found.");
+            rc = ERROR_FAIL;
+            goto out;
+        }
+
+        /* every ID can appear in each domain at most once */
+        if (libxl__xs_read(gc, xt, dom_sshm_path)) {
+            SSHM_ERROR(domid, sshm->id,
+                       "domain tried to map the same ID twice.");
+            rc = ERROR_FAIL;
+            goto out;
+        }
+
+        /* look at the master info and see if we could do the mapping */
+        rc = libxl__xs_read_checked(gc, xt,
+                                    GCSPRINTF("%s/prot", sshm_path),
+                                    &xs_value);
+        if (rc) goto out;
+        libxl_sshm_prot_from_string(xs_value, &master_sshm.prot);
+
+        rc = libxl__xs_read_checked(gc, xt,
+                                    GCSPRINTF("%s/begin", sshm_path),
+                                    &xs_value);
+        if (rc) goto out;
+        master_sshm.begin = strtoull(xs_value, NULL, 16);
+
+        rc = libxl__xs_read_checked(gc, xt,
+                                    GCSPRINTF("%s/end", sshm_path),
+                                    &xs_value);
+        if (rc) goto out;
+        master_sshm.end = strtoull(xs_value, NULL, 16);
+
+        rc = libxl__xs_read_checked(gc, xt,
+                                    GCSPRINTF("%s/master", sshm_path),
+                                    &xs_value);
+        if (rc) goto out;
+        master_domid = strtoull(xs_value, NULL, 16);
+
+        if (sshm->prot == LIBXL_SSHM_PROT_UNKNOWN)
+            sshm->prot = master_sshm.prot;
+
+        /* check if the slave is asking too much permission */
+        if (master_sshm.prot < sshm->prot) {
+            SSHM_ERROR(domid, sshm->id, "slave is asking too much permission.");
+            rc = ERROR_INVAL;
+            goto out;
+        }
+
+        /* all checks passed, do the job */
+        if (!isretry) {
+            rc = libxl__sshm_do_map(gc, master_domid, domid,
+                                    sshm, &master_sshm,
+                                    mapped, &nmapped);
+            if (rc) goto out;
+        }
+
+        /* write the result to xenstore and commit */
+        rc = libxl__xs_write_checked(gc, xt, dom_role_path, "slave");
+        if (rc) goto out;
+        rc = libxl__xs_writev(gc, xt, slave_path, ents);
+        if (rc) goto out;
+        rc = libxl__sshm_incref(gc, xt, sshm_path);
+        if (rc) goto out;
+
+        rc = libxl__xs_transaction_commit(gc, &xt);
+        if (!rc) break;
+        if (rc < 0) goto out;
+        isretry = true;
+    }
+
+    rc = 0;
+out:
+    if (rc) {
+        /* roll back successfully mapped pages */
+        SSHM_ERROR(domid, sshm->id, "failed to map some pages, cancelling.");
+        for (i = 0; i < nmapped; i++) {
+            xc_domain_remove_from_physmap(CTX->xch, domid, mapped[i]);
+        }
+    }
+
+    libxl__xs_transaction_abort(gc, &xt);
+
+    return rc;
+}
+
+static int libxl__sshm_add_master(libxl__gc *gc, uint32_t domid,
+                                  libxl_static_shm *sshm)
+{
+    int rc;
+    const char *sshm_path, *dom_path, *dom_role_path;
+    char *ents[13];
+    struct xs_permissions noperm;
+    xs_transaction_t xt = XBT_NULL;
+
+    sshm_path = SSHM_PATH(sshm->id);
+    dom_path = libxl__xs_get_dompath(gc, domid);
+    /* the domain should be in xenstore by now */
+    assert(dom_path);
+    dom_role_path = GCSPRINTF("%s/static_shm/%s/role", dom_path, sshm->id);
+
+    /* prepare the xenstore entries */
+    ents[0] = "master";
+    ents[1] = GCSPRINTF("%"PRIu32, domid);
+    ents[2] = "begin";
+    ents[3] = GCSPRINTF("0x%"PRIx64, sshm->begin);
+    ents[4] = "end";
+    ents[5] = GCSPRINTF("0x%"PRIx64, sshm->end);
+    ents[6] = "prot";
+    ents[7] = libxl__strdup(gc, libxl_sshm_prot_to_string(sshm->prot));
+    ents[8] = "cache_policy";
+    ents[9] = libxl__strdup(gc,
+                            libxl_sshm_cachepolicy_to_string(sshm->cache_policy));
+    ents[10] = "usercnt";
+    ents[11] = "1";
+    ents[12] = NULL;
+
+    /* could only be accessed by Dom0 */
+    noperm.id = 0;
+    noperm.perms = XS_PERM_NONE;
+
+    for (;;) {
+        rc = libxl__xs_transaction_start(gc, &xt);
+        if (rc) goto out;
+
+        if (!libxl__xs_read(gc, xt, sshm_path)) {
+            /* every ID can appear in each domain at most once */
+            if (libxl__xs_read(gc, xt, dom_role_path)) {
+                SSHM_ERROR(domid, sshm->id,
+                           "domain tried to map the same ID twice.");
+                rc = ERROR_FAIL;
+                goto out;
+            }
+            rc = libxl__xs_write_checked(gc, xt, dom_role_path, "master");
+            if (rc) goto out;;
+
+            libxl__xs_mknod(gc, xt, sshm_path, &noperm, 1);
+            libxl__xs_writev(gc, xt, sshm_path, ents);
+        } else {
+            SSHM_ERROR(domid, sshm->id, "can only have one master.");
+            rc = ERROR_FAIL;
+            goto out;
+        }
+
+        rc = libxl__xs_transaction_commit(gc, &xt);
+        if (!rc) break;
+        if (rc < 0) goto out;
+    }
+
+    rc = 0;
+out:
+    libxl__xs_transaction_abort(gc, &xt);
+    return rc;
+}
+
+int libxl__sshm_add(libxl__gc *gc,  uint32_t domid,
+                    libxl_static_shm *sshms, int len)
+{
+    int rc, i;
+
+    for (i = 0; i < len; ++i) {
+        if (sshms[i].role == LIBXL_SSHM_ROLE_SLAVE) {
+            rc = libxl__sshm_add_slave(gc, domid, sshms+i);
+        } else {
+            rc = libxl__sshm_add_master(gc, domid, sshms+i);
+        }
+        if (rc)  return rc;
+    }
+
+    return 0;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
tools/libxl/libxl_x86.c +12 -0
index 5f91fe4f92..8ec5044eb2 100644
@@ -596,6 +596,25 @@ void libxl__arch_domain_build_info_acpi_setdefault(
      libxl_defbool_setdefault(&b_info->acpi, true);
  }
 
+bool libxl__arch_domain_support_sshm(const libxl_domain_build_info *b_info)
+{
+    /* FIXME: Mark this as unsupported for calling p2m_add_foreign on two
+     * DomU's is currently not allowd on x86, see the comments in
+     * x86/mm/p2m.c: p2m_add_foreign.
+     */
+     return false;
+}
+
+int libxl__arch_domain_sshm_cachepolicy_setdefault(libxl_static_shm *sshm)
+{
+    if (sshm->cache_policy == LIBXL_SSHM_CACHEPOLICY_UNKNOWN)

tools/libxl/libxl_x86.c void libxl__arch_domain_build_info_acpi_setdefault( · line 620

Quoted 10 lines
tools/libxl/libxl_x86.c +7 -0
+        sshm->cache_policy = LIBXL_SSHM_CACHEPOLICY_X86_NORMAL;
+    if (sshm->cache_policy < LIBXL_SSHM_CACHEPOLICY_X86_NORMAL)
+        return ERROR_INVAL;
+
+    return 0;
+}
+
  /*
   * Local variables:
   * mode: C

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#25 lore raw

Re: [PATCH v4 4/7] libxl: support mapping static shared memory areas during domain creation

Hi Julien,

2018-02-06 21:07 GMT+08:00 Julien Grall <[email protected]>:

Quoted 7 lines

Hi,

Quoted 4 lines · Zhongze Liu

Add libxl__sshm_add to map shared pages from one DomU to another, The mapping
process involves the follwing steps:

[...]

Quoted 7 lines
Quoted 7 lines
tools/libxl/libxl_sshm.c new file +7 -0
+
+/* Set default values for libxl_static_shm */
+int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
+                           libxl_static_shm *sshm)
+{
+    int rc;
+
Quoted 8 lines

tools/libxl/libxl_sshm.c line 20

Quoted 4 lines
tools/libxl/libxl_sshm.c new file +4 -0
+    if (sshm->role == LIBXL_SSHM_ROLE_UNKNOWN)
+        sshm->role = LIBXL_SSHM_ROLE_SLAVE;
+    if (sshm->prot == LIBXL_SSHM_PROT_UNKNOWN)
+        sshm->prot = LIBXL_SSHM_PROT_RW;

What is the purpose of {ROLE,PROT}_UNKNOWN if you default it resp. to ROLE_SLAVE and PROT_RW. Would not it be easier to just drop them?

The *_UNKNOWN values are used by the libxlu code to check whether a specific option was set more than once. Without the default *_UNKNOWN value, I will not be able to judge if, say, role is set to 'slave' by the user or not, and therefore, if I
see the user setting role to 'master', I won't be able to tell if role is specified twice
or not.

I think treating re-specification of options as errors will be good for the users.

[...]

Quoted 19 lines
Quoted 6 lines
tools/libxl/libxl_sshm.c new file +5 -0
+
+/*   libxl__sshm_do_map -- map pages into slave's physmap
+ *
+ *   This functions maps
+ *     master gfn: [@msshm->begin + @sshm->offset, @msshm->end +

@sshm->offset)

Quoted 8 lines

+ * into
+ * slave gfn: [@sshm->begin, @sshm->end)
+ *
+ * The gfns of the pages that are successfully mapped will be stored
+ * in @mapped, and the number of the gfns will be stored in @nmapped.
+ *
+ * The caller have to guarentee that sshm->begin < sshm->end and all
the

s/have to/has to/ I think.
s/guarentee/guarantee/

Quoted 5 lines
Quoted 1 line

+ * values are page-aligned.

Hmmm, I don't see the alignement check in libxl. So do you rely on the toolstack to do it?

Yes, This was done in libxlu_sshm.c.

Cheers,

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#26 lore raw

Re: [PATCH v4 4/7] libxl: support mapping static shared memory areas during domain creation

Quoted 1 line · Zhongze Liu

Hi Julien,

Hi,

Quoted 27 lines

2018-02-06 21:07 GMT+08:00 Julien Grall <[email protected]>:

Quoted 7 lines

Hi,

Quoted 4 lines · Zhongze Liu

Add libxl__sshm_add to map shared pages from one DomU to another, The mapping
process involves the follwing steps:

[...]

Quoted 7 lines
Quoted 7 lines
tools/libxl/libxl_sshm.c new file +7 -0
+
+/* Set default values for libxl_static_shm */
+int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
+                           libxl_static_shm *sshm)
+{
+    int rc;
+
Quoted 8 lines

tools/libxl/libxl_sshm.c line 20

Quoted 4 lines
tools/libxl/libxl_sshm.c new file +4 -0
+    if (sshm->role == LIBXL_SSHM_ROLE_UNKNOWN)
+        sshm->role = LIBXL_SSHM_ROLE_SLAVE;
+    if (sshm->prot == LIBXL_SSHM_PROT_UNKNOWN)
+        sshm->prot = LIBXL_SSHM_PROT_RW;

What is the purpose of {ROLE,PROT}_UNKNOWN if you default it resp. to ROLE_SLAVE and PROT_RW. Would not it be easier to just drop them?

Quoted 2 lines

The *_UNKNOWN values are used by the libxlu code to check whether a specific option was set more than once.

AFAIK, a toolstack is free to not use libxlu. Someone may implement their own toolstack on top of libxl and may use ROLE_UNKNOWN by mistake.

Quoted 9 lines

Without the default *_UNKNOWN value, I will not
be able to judge if, say, role is set to 'slave' by the user or not, and therefore, if I
see the user setting role to 'master', I won't be able to tell if role is specified twice
or not.

I think treating re-specification of options as errors will be good for the users.

In that case, you should treat that as an error for everyone and not only xl. This would avoid confusion on other toolstack.

Quoted 22 lines

[...]

Quoted 19 lines
Quoted 6 lines
tools/libxl/libxl_sshm.c new file +5 -0
+
+/*   libxl__sshm_do_map -- map pages into slave's physmap
+ *
+ *   This functions maps
+ *     master gfn: [@msshm->begin + @sshm->offset, @msshm->end +

@sshm->offset)

Quoted 8 lines

+ * into
+ * slave gfn: [@sshm->begin, @sshm->end)
+ *
+ * The gfns of the pages that are successfully mapped will be stored
+ * in @mapped, and the number of the gfns will be stored in @nmapped.
+ *
+ * The caller have to guarentee that sshm->begin < sshm->end and all
the

s/have to/has to/ I think.
s/guarentee/guarantee/

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

+ * values are page-aligned.

Hmmm, I don't see the alignement check in libxl. So do you rely on the toolstack to do it?

Yes, This was done in libxlu_sshm.c.

Same remark as above regarding libxlu. Note that I am maintaining the tools. Ian and Wei may have a different opinion here.

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#27 lore raw

Re: [PATCH v4 4/7] libxl: support mapping static shared memory areas during domain creation

Quoted 35 lines · Julien Grall
Quoted 1 line · Zhongze Liu

Hi Julien,

Hi,

Quoted 27 lines

2018-02-06 21:07 GMT+08:00 Julien Grall <[email protected]>:

Quoted 7 lines

Hi,

Quoted 4 lines · Zhongze Liu

Add libxl__sshm_add to map shared pages from one DomU to another, The mapping
process involves the follwing steps:

[...]

Quoted 15 lines

tools/libxl/libxl_sshm.c line 20

Quoted 11 lines
tools/libxl/libxl_sshm.c new file +11 -0
+
+/* Set default values for libxl_static_shm */
+int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
+                           libxl_static_shm *sshm)
+{
+    int rc;
+
+    if (sshm->role == LIBXL_SSHM_ROLE_UNKNOWN)
+        sshm->role = LIBXL_SSHM_ROLE_SLAVE;
+    if (sshm->prot == LIBXL_SSHM_PROT_UNKNOWN)
+        sshm->prot = LIBXL_SSHM_PROT_RW;

What is the purpose of {ROLE,PROT}_UNKNOWN if you default it resp. to ROLE_SLAVE and PROT_RW. Would not it be easier to just drop them?

Quoted 5 lines
Quoted 2 lines

The *_UNKNOWN values are used by the libxlu code to check whether a specific option was set more than once.

AFAIK, a toolstack is free to not use libxlu. Someone may implement their own toolstack on top of libxl and may use ROLE_UNKNOWN by mistake.

Yes.

Quoted 39 lines
Quoted 10 lines

Without the default *_UNKNOWN value, I will not
be able to judge if, say, role is set to 'slave' by the user or not, and therefore, if I
see the user setting role to 'master', I won't be able to tell if role is specified twice
or not.

I think treating re-specification of options as errors will be good for the users.

In that case, you should treat that as an error for everyone and not only xl. This would avoid confusion on other toolstack.

Quoted 25 lines

[...]

Quoted 22 lines
Quoted 6 lines
tools/libxl/libxl_sshm.c new file +5 -0
+
+/*   libxl__sshm_do_map -- map pages into slave's physmap
+ *
+ *   This functions maps
+ *     master gfn: [@msshm->begin + @sshm->offset, @msshm->end +

@sshm->offset)

Quoted 8 lines

+ * into
+ * slave gfn: [@sshm->begin, @sshm->end)
+ *
+ * The gfns of the pages that are successfully mapped will be stored
+ * in @mapped, and the number of the gfns will be stored in @nmapped.
+ *
+ * The caller have to guarentee that sshm->begin < sshm->end and all
the

s/have to/has to/ I think.
s/guarentee/guarantee/

Quoted 1 line

+ * values are page-aligned.

Quoted 8 lines
Quoted 4 lines
Quoted 2 lines

Hmmm, I don't see the alignement check in libxl. So do you rely on the toolstack to do it?

Yes, This was done in libxlu_sshm.c.

Same remark as above regarding libxlu. Note that I am maintaining the tools. Ian and Wei may have a different opinion here.

Please move the check to libxl.

Wei.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#28 lore raw

Re: [PATCH v4 4/7] libxl: support mapping static shared memory areas during domain creation

Hi Wei and Julien,

2018-02-07 1:47 GMT+08:00 Wei Liu <[email protected]>:

Quoted 86 lines · Julien Grall
Quoted 35 lines · Zhongze Liu
Quoted 1 line

Hi Julien,

Hi,

Quoted 27 lines

2018-02-06 21:07 GMT+08:00 Julien Grall <[email protected]>:

Quoted 7 lines

Hi,

Quoted 4 lines · Zhongze Liu

Add libxl__sshm_add to map shared pages from one DomU to another, The mapping
process involves the follwing steps:

[...]

Quoted 15 lines

tools/libxl/libxl_sshm.c line 20

Quoted 11 lines
tools/libxl/libxl_sshm.c new file +11 -0
+
+/* Set default values for libxl_static_shm */
+int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
+                           libxl_static_shm *sshm)
+{
+    int rc;
+
+    if (sshm->role == LIBXL_SSHM_ROLE_UNKNOWN)
+        sshm->role = LIBXL_SSHM_ROLE_SLAVE;
+    if (sshm->prot == LIBXL_SSHM_PROT_UNKNOWN)
+        sshm->prot = LIBXL_SSHM_PROT_RW;

What is the purpose of {ROLE,PROT}_UNKNOWN if you default it resp. to ROLE_SLAVE and PROT_RW. Would not it be easier to just drop them?

Quoted 5 lines
Quoted 2 lines

The *_UNKNOWN values are used by the libxlu code to check whether a specific option was set more than once.

AFAIK, a toolstack is free to not use libxlu. Someone may implement their own toolstack on top of libxl and may use ROLE_UNKNOWN by mistake.

Yes.

Quoted 42 lines
Quoted 10 lines

Without the default *_UNKNOWN value, I will not
be able to judge if, say, role is set to 'slave' by the user or not, and therefore, if I
see the user setting role to 'master', I won't be able to tell if role is specified twice
or not.

I think treating re-specification of options as errors will be good for the users.

In that case, you should treat that as an error for everyone and not only xl. This would avoid confusion on other toolstack.

Quoted 28 lines

[...]

Quoted 24 lines
Quoted 6 lines
tools/libxl/libxl_sshm.c new file +5 -0
+
+/*   libxl__sshm_do_map -- map pages into slave's physmap
+ *
+ *   This functions maps
+ *     master gfn: [@msshm->begin + @sshm->offset, @msshm->end +

@sshm->offset)

Quoted 8 lines

+ * into
+ * slave gfn: [@sshm->begin, @sshm->end)
+ *
+ * The gfns of the pages that are successfully mapped will be stored
+ * in @mapped, and the number of the gfns will be stored in @nmapped.
+ *
+ * The caller have to guarentee that sshm->begin < sshm->end and all
the

s/have to/has to/ I think.
s/guarentee/guarantee/

Quoted 1 line

+ * values are page-aligned.

Hmmm, I don't see the alignement check in libxl. So do you rely on the toolstack to do it?

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

Yes, This was done in libxlu_sshm.c.

Same remark as above regarding libxlu. Note that I am maintaining the tools. Ian and Wei may have a different opinion here.

Please move the check to libxl.

I agree that we should move the alignment check to libxl.

But I still think that re-specification checks could only be done in libxlu, because
this could only be spotted in the parsing phase -- it shouldn't be libxl's job. For
libxl, an *_UNKNOWN values just indicates that the user of libxl didn't explicitly
assign a value to the option upon calling the constructor of the sshm struct, and the code in libxl will set the option to its default value. However, I do think
I failed to handle the possibilities where an option value is not not *_UNKNOWN and
not any valid values, which might occur if the user of libxl didn't use the constructor
to initialize the sshm struct.

Cheers,

Zhongze Liu.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#29 lore raw

Re: [PATCH v4 4/7] libxl: support mapping static shared memory areas during domain creation

Quoted 37 lines · Zhongze Liu
Quoted 27 lines
Quoted 27 lines
Quoted 27 lines

[...]

Quoted 24 lines
Quoted 6 lines
tools/libxl/libxl_sshm.c new file +5 -0
+
+/*   libxl__sshm_do_map -- map pages into slave's physmap
+ *
+ *   This functions maps
+ *     master gfn: [@msshm->begin + @sshm->offset, @msshm->end +

@sshm->offset)

Quoted 8 lines

+ * into
+ * slave gfn: [@sshm->begin, @sshm->end)
+ *
+ * The gfns of the pages that are successfully mapped will be stored
+ * in @mapped, and the number of the gfns will be stored in @nmapped.
+ *
+ * The caller have to guarentee that sshm->begin < sshm->end and all
the

s/have to/has to/ I think.
s/guarentee/guarantee/

Quoted 1 line

+ * values are page-aligned.

Hmmm, I don't see the alignement check in libxl. So do you rely on the toolstack to do it?

Quoted 7 lines
Quoted 5 lines
Quoted 1 line

Yes, This was done in libxlu_sshm.c.

Same remark as above regarding libxlu. Note that I am maintaining the tools. Ian and Wei may have a different opinion here.

Please move the check to libxl.

I agree that we should move the alignment check to libxl.

Quoted 14 lines

But I still think that re-specification checks could only be done in libxlu, because
this could only be spotted in the parsing phase -- it shouldn't be libxl's job. For
libxl, an *_UNKNOWN values just indicates that the user of libxl didn't explicitly
assign a value to the option upon calling the constructor of the sshm struct, and the code in libxl will set the option to its default value. However, I do think
I failed to handle the possibilities where an option value is not not *_UNKNOWN and
not any valid values, which might occur if the user of libxl didn't use the constructor
to initialize the sshm struct.

So there are two problems under discussion. One is parsing, which should be done in the parser library (libxlu); the other is checking the validity of the value in the struct, which should be done in libxl. I don't think we fundamentally disagree with each other. Sorry for my terse reply earlier.

Wei.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#30 lore raw

PATCH v4 5/7 libxl: support unmapping static shared memory areas during domain destruction

In reply to Zhongze Liu

Add libxl__sshm_del to unmap static shared memory areas mapped by libxl__sshm_add during domain creation. The unmapping process is:

* For a master: decrease the refcount of the sshm region, if the refcount reaches 0, cleanup the whole sshm path.
* For a slave: 1) unmap the shared pages, and cleanup related xs entries. If the system works normally, all the shared pages will be unmapped, so there won't be page leaks. In case of errors, the unmapping process will go on and unmap all the other pages that can be unmapped, so the other pages won't be leaked, either. 2) Decrease the refcount of the sshm region, if the refcount reaches 0, cleanup the whole sshm path.

This is for the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]).

[1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Cc Ian Jackson <[email protected]>
Cc Wei Liu <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>
---
 tools/libxl/libxl_domain.c   |   5 ++
 tools/libxl/libxl_internal.h |   2 +
 tools/libxl/libxl_sshm.c     | 106 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 113 insertions(+)
tools/libxl/libxl_domain.c +5 -0
index 13b1c73d40..37f001554b 100644
@@ -1026,6 +1026,11 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
         goto out;
     }
 
+    rc = libxl__sshm_del(gc, domid);
+    if (rc) {
+        LOGD(ERROR, domid, "Deleting static shm failed.");
+    }
+
     if (libxl__device_pci_destroy_all(gc, domid) < 0)
         LOGD(ERROR, domid, "Pci shutdown failed");
     rc = xc_domain_pause(ctx->xch, domid);
tools/libxl/libxl_internal.h +2 -0
index 2cfe4c08a7..c398b6a6b8 100644
@@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char **s)
 _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
                             libxl_static_shm *sshm, int len);
 
+_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid);
+
 _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
                                       libxl_static_shm *sshms, int len);
 _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
tools/libxl/libxl_sshm.c +106 -0

112 lines not on this page · raw message

Signature · 7 lines
2.16.1


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#31 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Hi,

Quoted 11 lines · Zhongze Liu

Add libxl__sshm_del to unmap static shared memory areas mapped by libxl__sshm_add during domain creation. The unmapping process is:

* For a master: decrease the refcount of the sshm region, if the refcount reaches 0, cleanup the whole sshm path.
* For a slave: 1) unmap the shared pages, and cleanup related xs entries. If the system works normally, all the shared pages will be unmapped, so there won't be page leaks. In case of errors, the unmapping process will go on and unmap all the other pages that can be unmapped, so the other pages won't be leaked, either. 2) Decrease the refcount of the sshm region, if the refcount reaches 0, cleanup the whole sshm path.

May I ask to add a newline line 1) and 2). This would make clearer the 2 steps.

Quoted 53 lines

This is for the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]).

[1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Cc Ian Jackson <[email protected]>
Cc Wei Liu <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>
---
  tools/libxl/libxl_domain.c   |   5 ++
  tools/libxl/libxl_internal.h |   2 +
  tools/libxl/libxl_sshm.c     | 106 +++++++++++++++++++++++++++++++++++++++++++
  3 files changed, 113 insertions(+)
tools/libxl/libxl_domain.c +5 -0
index 13b1c73d40..37f001554b 100644
@@ -1026,6 +1026,11 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
          goto out;
      }
 
+    rc = libxl__sshm_del(gc, domid);
+    if (rc) {
+        LOGD(ERROR, domid, "Deleting static shm failed.");
+    }
+
      if (libxl__device_pci_destroy_all(gc, domid) < 0)
          LOGD(ERROR, domid, "Pci shutdown failed");
      rc = xc_domain_pause(ctx->xch, domid);
tools/libxl/libxl_internal.h +2 -0
index 2cfe4c08a7..c398b6a6b8 100644
@@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char **s)
  _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
                              libxl_static_shm *sshm, int len);
 
+_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid);
+
  _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
                                        libxl_static_shm *sshms, int len);
  _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
tools/libxl/libxl_sshm.c +0 -0
index 562f46f299..1bf4d4c2dc 100644

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 89

Quoted 4 lines
tools/libxl/libxl_sshm.c +1 -0
@@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
      return 0;
  }
 
+/* Decrease the refcount of an sshm. When refcount reaches 0,

NIT: Libxl coding style regarding the comment seems to be uncleared (Ian, Wei?). But I feel keep /* and */ in separate line is nicer.

Quoted 10 lines
tools/libxl/libxl_sshm.c +10 -0
+ * clean up the whole sshm path.
+ */
+static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt,
+                               const char *sshm_path)
+{
+    int count;
+    const char *count_path, *count_string;
+
+    count_path = GCSPRINTF("%s/usercnt", sshm_path);
+    if (libxl__xs_read_checked(gc, xt, count_path, &count_string))

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 109

Quoted 10 lines
tools/libxl/libxl_sshm.c +10 -0
+        return;
+    count = atoi(count_string);
+
+    if (--count == 0) {
+        libxl__xs_path_cleanup(gc, xt, sshm_path);
+        return;
+    }
+
+    count_string = GCSPRINTF("%d", count);
+    libxl__xs_write_checked(gc, xt, count_path, count_string);

See my comment about incref in a patch #4.

Quoted 24 lines
tools/libxl/libxl_sshm.c +24 -0
+
+    return;
+}
+
+static void libxl__sshm_do_unmap(libxl__gc *gc, uint32_t domid, const char *id,
+                                 uint64_t begin, uint64_t end)
+{
+    begin >>= XC_PAGE_SHIFT;
+    end >>= XC_PAGE_SHIFT;
+    for (; begin < end; ++begin) {
+        if (xc_domain_remove_from_physmap(CTX->xch, domid, begin)) {
+            SSHM_ERROR(domid, id,
+                       "unable to unmap shared page at 0x%"PRIx64".",
+                       begin);
+        }
+    }
+}
+
+static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt,
+                                  uint32_t domid, const char *id, bool isretry)
+{
+    const char *slave_path, *begin_str, *end_str;
+    uint64_t begin, end;
+

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 143

Quoted 10 lines
tools/libxl/libxl_sshm.c +10 -0
+    slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid);
+
+    begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", slave_path));
+    end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path));
+    begin = strtoull(begin_str, NULL, 16);
+    end = strtoull(end_str, NULL, 16);
+
+    /* Avoid calling do_unmap many times in case of xs transaction retry */
+    if (!isretry)
+        libxl__sshm_do_unmap(gc, domid, id, begin, end);

IHMO, by unmapping the regions in middle of the transaction, you increase the potential failure of it. I would move that out of the transaction path.

I would be interested to hear the opinion of the tools maintainers here.

Quoted 17 lines
tools/libxl/libxl_sshm.c +17 -0
+
+    libxl__xs_path_cleanup(gc, xt, slave_path);
+}
+
+/* Delete static_shm entries in the xensotre. */
+int libxl__sshm_del(libxl__gc *gc,  uint32_t domid)
+{
+    int rc, i;
+    bool isretry;
+    xs_transaction_t xt = XBT_NULL;
+    const char *dom_path, *dom_sshm_path, *role;
+    char **sshm_ents;
+    unsigned int sshm_num;
+
+    dom_path = libxl__xs_get_dompath(gc, domid);
+    dom_sshm_path = GCSPRINTF("%s/static_shm", dom_path);
+

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 170

Quoted 10 lines
tools/libxl/libxl_sshm.c +10 -0
+    isretry = false;
+    for (;;) {
+        rc = libxl__xs_transaction_start(gc, &xt);
+        if (rc) goto out;
+
+        if (libxl__xs_read(gc, xt, dom_sshm_path)) {
+            sshm_ents = libxl__xs_directory(gc, xt, dom_sshm_path, &sshm_num);
+            if (!sshm_ents) continue;
+
+            for (i = 0; i < sshm_num; ++i) {

Similar comment here. You increase the chance of the transaction failing by trying to del multiple shared memory regions at the same time. I am mostly thinking on the libxl__sshm_decref bit.

Quoted 18 lines
tools/libxl/libxl_sshm.c +17 -0
+                role = libxl__xs_read(gc, xt,
+                                      GCSPRINTF("%s/%s/role",
+                                                dom_sshm_path,
+                                                sshm_ents[i]));
+                assert(role);
+                if (!strncmp(role, "slave", 5))
+                    libxl__sshm_del_slave(gc, xt, domid, sshm_ents[i], isretry);
+
+                libxl__sshm_decref(gc, xt, SSHM_PATH(sshm_ents[i]));
+            }
+        }
+
+        rc = libxl__xs_transaction_commit(gc, &xt);
+        if (!rc) break;
+        if (rc < 0) goto out;
+        isretry = true;
+    }

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 197

Quoted 10 lines
tools/libxl/libxl_sshm.c +7 -0
+
+    rc = 0;
+out:
+    libxl__xs_transaction_abort(gc, &xt);
+    return rc;
+}
+
  /*   libxl__sshm_do_map -- map pages into slave's physmap
   *
   *   This functions maps

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#32 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Quoted 18 lines · Julien Grall
Quoted 18 lines
      if (libxl__device_pci_destroy_all(gc, domid) < 0)
          LOGD(ERROR, domid, "Pci shutdown failed");
      rc = xc_domain_pause(ctx->xch, domid);
tools/libxl/libxl_internal.h +2 -0
index 2cfe4c08a7..c398b6a6b8 100644
@@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char **s)
  _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
                              libxl_static_shm *sshm, int len);
+_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid);
+
  _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
                                        libxl_static_shm *sshms, int len);
  _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
tools/libxl/libxl_sshm.c +0 -1
index 562f46f299..1bf4d4c2dc 100644
--- a/tools/libxl/libxl_sshm.c
Quoted 8 lines

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 88

Quoted 5 lines

+++ b/tools/libxl/libxl_sshm.c

tools/libxl/libxl_sshm.c +1 -0
@@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
      return 0;
  }
+/* Decrease the refcount of an sshm. When refcount reaches 0,

NIT: Libxl coding style regarding the comment seems to be uncleared (Ian, Wei?). But I feel keep /* and */ in separate line is nicer.

I don't have an opinion here.

Quoted 25 lines
Quoted 11 lines
tools/libxl/libxl_sshm.c +10 -0
+ * clean up the whole sshm path.
+ */
+static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt,
+                               const char *sshm_path)
+static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt,
+                                  uint32_t domid, const char *id, bool isretry)
+{
+    const char *slave_path, *begin_str, *end_str;
+    uint64_t begin, end;
+

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 143

Quoted 10 lines
tools/libxl/libxl_sshm.c +10 -0
+    slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid);
+
+    begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", slave_path));
+    end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path));
+    begin = strtoull(begin_str, NULL, 16);
+    end = strtoull(end_str, NULL, 16);
+
+    /* Avoid calling do_unmap many times in case of xs transaction retry */
+    if (!isretry)
+        libxl__sshm_do_unmap(gc, domid, id, begin, end);

IHMO, by unmapping the regions in middle of the transaction, you increase the potential failure of it. I would move that out of the transaction path.

Quoted 2 lines

I would be interested to hear the opinion of the tools maintainers here.

If you move the unmap after the loop you create a window in which the pages are still mapped but the toolstack thinks they are unmapped.

While the code as-is now makes sure (assuming no error in unmap) the pages are unmapped no later than the transaction is committed. I think this can be done by moving unmap before the transaction.

Zhongze, do you think the unmap must be done inside the loop? What kind of invariants do you have in mind?

Then there is the question of "what do we do if unmap fails". Honestly I don't have an answer. It seems rather screwed up in that case and I doubt there is much libxl can do to rectify things.

Wei.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#33 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Hi Wei and Julien,

2018-02-07 2:06 GMT+08:00 Wei Liu <[email protected]>:

Quoted 65 lines · Julien Grall
Quoted 18 lines
Quoted 18 lines
      if (libxl__device_pci_destroy_all(gc, domid) < 0)
          LOGD(ERROR, domid, "Pci shutdown failed");
      rc = xc_domain_pause(ctx->xch, domid);
tools/libxl/libxl_internal.h +2 -0
index 2cfe4c08a7..c398b6a6b8 100644
@@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char **s)
  _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
                              libxl_static_shm *sshm, int len);
+_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid);
+
  _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
                                        libxl_static_shm *sshms, int len);
  _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
tools/libxl/libxl_sshm.c +0 -1
index 562f46f299..1bf4d4c2dc 100644
--- a/tools/libxl/libxl_sshm.c
Quoted 8 lines

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 88

Quoted 5 lines

+++ b/tools/libxl/libxl_sshm.c

tools/libxl/libxl_sshm.c +1 -0
@@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
      return 0;
  }
+/* Decrease the refcount of an sshm. When refcount reaches 0,

NIT: Libxl coding style regarding the comment seems to be uncleared (Ian, Wei?). But I feel keep /* and */ in separate line is nicer.

I don't have an opinion here.

Quoted 25 lines
Quoted 11 lines
tools/libxl/libxl_sshm.c +10 -0
+ * clean up the whole sshm path.
+ */
+static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt,
+                               const char *sshm_path)
+static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt,
+                                  uint32_t domid, const char *id, bool isretry)
+{
+    const char *slave_path, *begin_str, *end_str;
+    uint64_t begin, end;
+

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 143

Quoted 10 lines
tools/libxl/libxl_sshm.c +10 -0
+    slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid);
+
+    begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", slave_path));
+    end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path));
+    begin = strtoull(begin_str, NULL, 16);
+    end = strtoull(end_str, NULL, 16);
+
+    /* Avoid calling do_unmap many times in case of xs transaction retry */
+    if (!isretry)
+        libxl__sshm_do_unmap(gc, domid, id, begin, end);

IHMO, by unmapping the regions in middle of the transaction, you increase the potential failure of it. I would move that out of the transaction path.

Quoted 2 lines

I would be interested to hear the opinion of the tools maintainers here.

If you move the unmap after the loop you create a window in which the pages are still mapped but the toolstack thinks they are unmapped.

While the code as-is now makes sure (assuming no error in unmap) the pages are unmapped no later than the transaction is committed. I think this can be done by moving unmap before the transaction.

Quoted 7 lines

Zhongze, do you think the unmap must be done inside the loop? What kind of invariants do you have in mind?

Then there is the question of "what do we do if unmap fails". Honestly I don't have an answer. It seems rather screwed up in that case and I doubt there is much libxl can do to rectify things.

I put the unmap inside the transaction because I want to make the whole read_mapping_info->unmap->update_mapping_info process atomic. If I put unmap outside the transaction: after I read out the information that I need to do the unmap, and before I do the unmap and decrease the refcnt, there could be another instance of this code trying to do the same thing, which might lead to race condition.

And yes, I don't think we can do much in case of something go wrong, so what I'm doing here is just to do as best as I can -- unmapping all that pages that can be unmapped and cleanup the xs entries.

Cheers,

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#34 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Quoted 1 line · Zhongze Liu

Hi Wei and Julien,

Hi,

Quoted 74 lines

2018-02-07 2:06 GMT+08:00 Wei Liu <[email protected]>:

Quoted 65 lines · Julien Grall
Quoted 18 lines
Quoted 18 lines
       if (libxl__device_pci_destroy_all(gc, domid) < 0)
           LOGD(ERROR, domid, "Pci shutdown failed");
       rc = xc_domain_pause(ctx->xch, domid);
tools/libxl/libxl_internal.h +2 -0
index 2cfe4c08a7..c398b6a6b8 100644
@@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char **s)
   _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
                               libxl_static_shm *sshm, int len);
+_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid);
+
   _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
                                         libxl_static_shm *sshms, int len);
   _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
tools/libxl/libxl_sshm.c +0 -1
index 562f46f299..1bf4d4c2dc 100644
--- a/tools/libxl/libxl_sshm.c
Quoted 8 lines

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 88

Quoted 5 lines

+++ b/tools/libxl/libxl_sshm.c

tools/libxl/libxl_sshm.c +1 -0
@@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
       return 0;
   }
+/* Decrease the refcount of an sshm. When refcount reaches 0,

NIT: Libxl coding style regarding the comment seems to be uncleared (Ian, Wei?). But I feel keep /* and */ in separate line is nicer.

I don't have an opinion here.

Quoted 25 lines
Quoted 11 lines
tools/libxl/libxl_sshm.c +10 -0
+ * clean up the whole sshm path.
+ */
+static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt,
+                               const char *sshm_path)
+static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt,
+                                  uint32_t domid, const char *id, bool isretry)
+{
+    const char *slave_path, *begin_str, *end_str;
+    uint64_t begin, end;
+

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 143

Quoted 10 lines
tools/libxl/libxl_sshm.c +10 -0
+    slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid);
+
+    begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", slave_path));
+    end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path));
+    begin = strtoull(begin_str, NULL, 16);
+    end = strtoull(end_str, NULL, 16);
+
+    /* Avoid calling do_unmap many times in case of xs transaction retry */
+    if (!isretry)
+        libxl__sshm_do_unmap(gc, domid, id, begin, end);

IHMO, by unmapping the regions in middle of the transaction, you increase the potential failure of it. I would move that out of the transaction path.

Quoted 2 lines

I would be interested to hear the opinion of the tools maintainers here.

If you move the unmap after the loop you create a window in which the pages are still mapped but the toolstack thinks they are unmapped.

While the code as-is now makes sure (assuming no error in unmap) the pages are unmapped no later than the transaction is committed. I think this can be done by moving unmap before the transaction.

Quoted 7 lines

Zhongze, do you think the unmap must be done inside the loop? What kind of invariants do you have in mind?

Then there is the question of "what do we do if unmap fails". Honestly I don't have an answer. It seems rather screwed up in that case and I doubt there is much libxl can do to rectify things.

Quoted 6 lines

I put the unmap inside the transaction because I want to make the whole read_mapping_info->unmap->update_mapping_info process atomic. If I put unmap outside the transaction: after I read out the information that I need to do the unmap, and before I do the unmap and decrease the refcnt, there could be another instance of this code trying to do the same thing, which might lead to race condition.

AFAIU, the transaction is not a "global" lock. You will just not see the the change from the others during the transactions. Your changes will be only be visible at the end. So two transaction can be happily started concurrently, and try to do the unmap together. Not even your code will protect against that.

So can you give a bit more details here?

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#35 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Hi Julien an Wei,

2018-02-08 0:54 GMT+08:00 Julien Grall <[email protected]>:

Quoted 105 lines · Zhongze Liu
Quoted 2 lines

Hi Wei and Julien,

Hi,

Quoted 89 lines

2018-02-07 2:06 GMT+08:00 Wei Liu <[email protected]>:

Quoted 80 lines · Julien Grall
Quoted 25 lines
Quoted 25 lines
       if (libxl__device_pci_destroy_all(gc, domid) < 0)
           LOGD(ERROR, domid, "Pci shutdown failed");
       rc = xc_domain_pause(ctx->xch, domid);
tools/libxl/libxl_internal.h +2 -0
index 2cfe4c08a7..c398b6a6b8 100644
@@ -4424,6 +4424,8 @@ static inline bool libxl__string_is_default(char
 **s)
   _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
                               libxl_static_shm *sshm, int len);
+_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid);
+
   _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
                                         libxl_static_shm *sshms, int
 len);

_hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,

tools/libxl/libxl_sshm.c +0 -0
index 562f46f299..1bf4d4c2dc 100644
@@ -86,6 +86,112 @@ int libxl__sshm_check_overlap(libxl__gc *gc,
 uint32_t domid,
Quoted 8 lines

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 89

Quoted 3 lines
tools/libxl/libxl_sshm.c +1 -0
       return 0;
   }
+/* Decrease the refcount of an sshm. When refcount reaches 0,

NIT: Libxl coding style regarding the comment seems to be uncleared (Ian,
Wei?). But I feel keep /* and */ in separate line is nicer.

I don't have an opinion here.

Quoted 31 lines
Quoted 22 lines
tools/libxl/libxl_sshm.c +18 -0
+ * clean up the whole sshm path.
+ */
+static void libxl__sshm_decref(libxl__gc *gc, xs_transaction_t xt,
+                               const char *sshm_path)
+static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt,
+                                  uint32_t domid, const char *id, bool
 isretry)
+{
+    const char *slave_path, *begin_str, *end_str;
+    uint64_t begin, end;
+
+    slave_path = GCSPRINTF("%s/slaves/%"PRIu32, SSHM_PATH(id), domid);
+
+    begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin",
 slave_path));
+    end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path));
+    begin = strtoull(begin_str, NULL, 16);
+    end = strtoull(end_str, NULL, 16);
+
+    /* Avoid calling do_unmap many times in case of xs transaction

retry */

tools/libxl/libxl_sshm.c int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid, · line 143

Quoted 2 lines
tools/libxl/libxl_sshm.c +2 -0
+    if (!isretry)
+        libxl__sshm_do_unmap(gc, domid, id, begin, end);

IHMO, by unmapping the regions in middle of the transaction, you increase
the potential failure of it. I would move that out of the transaction path.

Quoted 2 lines

I would be interested to hear the opinion of the tools maintainers here.

If you move the unmap after the loop you create a window in which the pages are still mapped but the toolstack thinks they are unmapped.

While the code as-is now makes sure (assuming no error in unmap) the pages are unmapped no later than the transaction is committed. I think this can be done by moving unmap before the transaction.

Quoted 7 lines

Zhongze, do you think the unmap must be done inside the loop? What kind of invariants do you have in mind?

Then there is the question of "what do we do if unmap fails". Honestly I don't have an answer. It seems rather screwed up in that case and I doubt there is much libxl can do to rectify things.

Quoted 6 lines

I put the unmap inside the transaction because I want to make the whole read_mapping_info->unmap->update_mapping_info process atomic. If I put unmap outside the transaction: after I read out the information that I need to do the unmap, and before I do the unmap and decrease the refcnt, there could be another instance of this code trying to do the same thing, which might lead to race condition.

Quoted 8 lines

AFAIU, the transaction is not a "global" lock. You will just not see the the change from the others during the transactions. Your changes will be only be visible at the end. So two transaction can be happily started concurrently, and try to do the unmap together. Not even your code will protect against that.

So can you give a bit more details here?

It seems that I mistakenly use transaction as a global lock. Now I don't have any reasons not putting the unmap out of the transaction, but this will break the original transaction into two, and I do think that we need some explicit locking here.

@Wei. Do you have any suggestions here?

Cheers,

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#36 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Hi,

Quoted 6 lines · Zhongze Liu

2018-02-08 0:54 GMT+08:00 Julien Grall <[email protected]>:

Quoted 1 line · Zhongze Liu

It seems that I mistakenly use transaction as a global lock. Now I don't have any reasons not putting the unmap out of the transaction, but this will break the original transaction into two, and I do think that we need some explicit locking here.

Can you explain why you need specific locking here? What are you trying to protect? Are you trying to protect against two process doing the unmap?

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#37 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Hi Julien,

2018-02-12 23:09 GMT+08:00 Julien Grall <[email protected]>:

Quoted 17 lines

Hi,

Quoted 5 lines · Zhongze Liu

2018-02-08 0:54 GMT+08:00 Julien Grall <[email protected]>:

Quoted 2 lines · Zhongze Liu
Quoted 7 lines

It seems that I mistakenly use transaction as a global lock. Now I don't have
any reasons not putting the unmap out of the transaction, but this will break
the original transaction into two, and I do think that we need some explicit
locking here.

Quoted 3 lines

Can you explain why you need specific locking here? What are you trying to protect? Are you trying to protect against two process doing the unmap?

Yes.

Cheers,

Zhongze Liu

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#38 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Quoted 1 line · Zhongze Liu

Hi Julien,

Hi,

Quoted 19 lines

2018-02-12 23:09 GMT+08:00 Julien Grall <[email protected]>:

Quoted 17 lines

Hi,

Quoted 12 lines · Zhongze Liu

2018-02-08 0:54 GMT+08:00 Julien Grall <[email protected]>:

Quoted 2 lines · Zhongze Liu

It seems that I mistakenly use transaction as a global lock. Now I don't have
any reasons not putting the unmap out of the transaction, but this will break
the original transaction into two, and I do think that we need some explicit
locking here.

Quoted 5 lines
Quoted 3 lines

Can you explain why you need specific locking here? What are you trying to protect? Are you trying to protect against two process doing the unmap?

Yes.

I don't think you have to worry about the locking here. With the current interface, the regions cannot be modified after the guest has booted. So the addresses will always stay valid.

This code path should never be called concurrently, as a lot of code in libxl, so I think someone else will take care about that for you (I will let Wei confirm here).

In any case, the worst that could happen is the unmap is called twice on the same region. So you would get spurious error message. Not that bad.

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#39 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Quoted 32 lines · Julien Grall
Quoted 1 line · Zhongze Liu

Hi Julien,

Hi,

Quoted 19 lines

2018-02-12 23:09 GMT+08:00 Julien Grall <[email protected]>:

Quoted 17 lines

Hi,

Quoted 12 lines · Zhongze Liu

2018-02-08 0:54 GMT+08:00 Julien Grall <[email protected]>:

Quoted 2 lines · Zhongze Liu

It seems that I mistakenly use transaction as a global lock. Now I don't have
any reasons not putting the unmap out of the transaction, but this will break
the original transaction into two, and I do think that we need some explicit
locking here.

Quoted 5 lines
Quoted 3 lines

Can you explain why you need specific locking here? What are you trying to protect? Are you trying to protect against two process doing the unmap?

Yes.

Quoted 7 lines

I don't think you have to worry about the locking here. With the current interface, the regions cannot be modified after the guest has booted. So the addresses will always stay valid.

This code path should never be called concurrently, as a lot of code in libxl, so I think someone else will take care about that for you (I will let Wei confirm here).

I think you mean "can be called concurrently but locking is taken care of".

If two processes / threads with different libxl ctx (not just xl. xl has a global lock) try to manipulate the same domain, libxl APIs use file locks. For the same same process, multiple threads but sharing one libxl_ctx there is pthread mutex in libxl_ctx.

In a way, "someone else" (in libxl code) has already taken care of the locking.

Fundamentally We need to assume the code can be called concurrently. It would be good thing if this is taken into consideration if new code is added.

Wei.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#40 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

In reply to Julien Grall
Quoted 36 lines · Julien Grall
Quoted 1 line · Zhongze Liu

Hi Julien,

Hi,

Quoted 19 lines

2018-02-12 23:09 GMT+08:00 Julien Grall <[email protected]>:

Quoted 17 lines

Hi,

Quoted 12 lines · Zhongze Liu

2018-02-08 0:54 GMT+08:00 Julien Grall <[email protected]>:

Quoted 2 lines · Zhongze Liu

It seems that I mistakenly use transaction as a global lock. Now I don't have
any reasons not putting the unmap out of the transaction, but this will break
the original transaction into two, and I do think that we need some explicit
locking here.

Quoted 5 lines
Quoted 3 lines

Can you explain why you need specific locking here? What are you trying to protect? Are you trying to protect against two process doing the unmap?

Yes.

I don't think you have to worry about the locking here. With the current interface, the regions cannot be modified after the guest has booted. So the addresses will always stay valid.

Quoted 6 lines

This code path should never be called concurrently, as a lot of code in libxl, so I think someone else will take care about that for you (I will let Wei confirm here).

In any case, the worst that could happen is the unmap is called twice on the same region. So you would get spurious error message. Not that bad.

Yeah, not that bad. Not going to be a security issue, not going to leak resources in the end.

To avoid spurious unmap, can we maybe unmap the pages after the xenstore transaction is committed? In that case, only the successful one gets to unmap, the ones that aren't committed will bail.

(Just tossing around ideas)

Wei.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#41 lore raw

Re: [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction

Wei Liu writes ("Re: [Xen-devel] [PATCH v4 5/7] libxl: support unmapping static shared memory areas during domain destruction"):

Quoted 12 lines · Julien Grall
Quoted 2 lines

In any case, the worst that could happen is the unmap is called twice on the same region. So you would get spurious error message. Not that bad.

Yeah, not that bad. Not going to be a security issue, not going to leak resources in the end.

To avoid spurious unmap, can we maybe unmap the pages after the xenstore transaction is committed? In that case, only the successful one gets to unmap, the ones that aren't committed will bail.

(Just tossing around ideas)

It should be the other way around. Because, your way, if your process crashes for some reason between the xenstore commit and the unmap, the memory is leaked.

Instead, do the unmap first. Check the error code to see if it means "this was already unmapped" and if so report that only via a debug log message.

Ian.

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel

#42 lore raw

PATCH v4 6/7 libxl:xl: add parsing code to parse "libxl_static_sshm" from xl config files

In reply to Zhongze Liu

Add the parsing utils for the newly introduced libxl_static_sshm struct to the libxl/libxlu_* family. And add realated parsing code in xl to parse the struct from xl config files. This is for the proposal "Allow setting up shared memory areas between VMs from xl config file" (see [1]).

[1] https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Cc Wei Liu <[email protected]>
Cc Ian Jackson <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>
---
 tools/libxl/Makefile      |   2 +-
 tools/libxl/libxlu_sshm.c | 210 ++++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxlutil.h   |   6 ++
 tools/xl/xl_parse.c       |  24 +++++-
 4 files changed, 240 insertions(+), 2 deletions(-)
 create mode 100644 tools/libxl/libxlu_sshm.c
tools/libxl/Makefile +1 -1
index e2834d84dc..dfd68bc2df 100644
@@ -176,7 +176,7 @@ AUTOINCS= libxlu_cfg_y.h libxlu_cfg_l.h _libxl_list.h _paths.h \
 AUTOSRCS= libxlu_cfg_y.c libxlu_cfg_l.c
 AUTOSRCS += _libxl_save_msgs_callout.c _libxl_save_msgs_helper.c
 LIBXLU_OBJS = libxlu_cfg_y.o libxlu_cfg_l.o libxlu_cfg.o \
-	libxlu_disk_l.o libxlu_disk.o libxlu_vif.o libxlu_pci.o
+	libxlu_disk_l.o libxlu_disk.o libxlu_vif.o libxlu_pci.o libxlu_sshm.o
 $(LIBXLU_OBJS): CFLAGS += $(CFLAGS_libxenctrl) # For xentoollog.h
 
 $(TEST_PROG_OBJS) _libxl.api-for-check: CFLAGS += $(CFLAGS_libxentoollog) $(CFLAGS_libxentoolcore)
tools/libxl/libxlu_sshm.c new file +210 -0

210 lines not on this page · raw message

tools/libxl/libxlutil.h +6 -0
index e81b644c01..ee39cb5bdc 100644
@@ -118,6 +118,12 @@ int xlu_rdm_parse(XLU_Config *cfg, libxl_rdm_reserve *rdm, const char *str);
 int xlu_vif_parse_rate(XLU_Config *cfg, const char *rate,
                        libxl_device_nic *nic);
 
+/*
+ * static shared memory specification parsing
+ */
+int xlu_sshm_parse(XLU_Config *cfg, const char *spec,
+                   libxl_static_shm *sshm);
+
 #endif /* LIBXLUTIL_H */
 
 /*
tools/xl/xl_parse.c +23 -1
index f6842540ca..3221401dac 100644
@@ -860,7 +860,7 @@ void parse_config_data(const char *config_source,
     long l, vcpus = 0;
     XLU_Config *config;
     XLU_ConfigList *cpus, *vbds, *nics, *pcis, *cvfbs, *cpuids, *vtpms,
-                   *usbctrls, *usbdevs, *p9devs, *vdispls;
+                   *usbctrls, *usbdevs, *p9devs, *vdispls, *sshms;
     XLU_ConfigList *channels, *ioports, *irqs, *iomem, *viridian, *dtdevs,
                    *mca_caps;
     int num_ioports, num_irqs, num_iomem, num_cpus, num_viridian, num_mca_caps;
@@ -1566,6 +1566,28 @@ void parse_config_data(const char *config_source,
         }
     }
 
+    if (!xlu_cfg_get_list (config, "static_shm", &sshms, 0, 0)) {
+        d_config->num_sshms = 0;
+        d_config->sshms = NULL;
+        while ((buf = xlu_cfg_get_listitem (sshms, d_config->num_sshms)) != NULL) {
+            libxl_static_shm *sshm;
+            char *buf2 = strdup(buf);
+            int ret;
+
+            sshm = ARRAY_EXTEND_INIT_NODEVID(d_config->sshms,
+                                             d_config->num_sshms,
+                                             libxl_static_shm_init);
+            ret = xlu_sshm_parse(config, buf2, sshm);
+            if (ret) {
+                fprintf(stderr,
+                        "xl: Invalid argument for static_shm: %s", buf2);
+                exit(EXIT_FAILURE);
+            }
+
+            free(buf2);
+        }
+    }
+
     if (!xlu_cfg_get_list(config, "p9", &p9devs, 0, 0)) {
         libxl_device_p9 *p9;
         char *security_model = NULL;
Signature · 7 lines
2.16.1


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#43 lore raw

PATCH v4 7/7 docs: documentation about static shared memory regions

In reply to Zhongze Liu

Add docs to document the motivation, usage, use cases and other relevant information about the static shared memory feature.

This is for the proposal "Allow setting up shared memory areas between VMs from xl config file". See:

https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html

Cc Ian Jackson <[email protected]>
Cc Wei Liu <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>
---
 docs/man/xl-static-shm-configuration.pod.5 | 257 +++++++++++++++++++++++++++++
 docs/man/xl.cfg.pod.5.in                   |   8 +
 docs/misc/xenstore-paths.markdown          |  47 ++++++
 3 files changed, 312 insertions(+)
 create mode 100644 docs/man/xl-static-shm-configuration.pod.5
docs/man/xl-static-shm-configuration.pod.5 new file +257 -0
new file mode 100644
index 0000000000..d68ed0ebf7
@@ -0,0 +1,257 @@
+=head1 NAME
+
+xl-static-shm-configuration - XL Static Shared Memeory Configuration Syntax
+
+
+(B<NOTE>: This is currently only available to ARM guests.)
+
+=head1 DESCRIPTION
+
+The static_shm option allows users to statically setup shared memory regions
+among a group of VMs, enabling guests without grant table support to do
+shm-based communication.
+
+Every shared region is:
+
+=over 4
+
+* Uniquely identified by a string that is no longer than 128 characters, which
+is called an B<identifier> in this document.
+
+* Backed by exactely one domain, which is called a B<master> domain, and all
+the other domains who are also sharing this region are called B<slave>s.
+
+=back
+
+=head1 SYNTAX
+
+This document specifies syntax of the static shared memory configuration in
+the xl config file. It has the following form:
+
+    static_shm = [ "SSHM_SPEC", "SSHM_SPEC", ... ]
+
+where each C<SSHM_SPEC> is in this form:
+
+    [<key>=<value>,]*
+
+Valid examples of C<SSHM_SPEC> are:
+
+    id=ID1, begin=0x100000, end=0x200000, role=master, cache_policy=x86_normal
+    id=ID1, offset = 0, begin=0x500000, end=0x600000, role=slave, prot=rw
+    id=ID2, begin=0x300000, end=0x400000, role=master
+    id=ID2, offset = 0x10000, begin=0x690000, end=0x800000, role=slave
+    id=ID2, offset = 0x10000, begin=0x690000, end=0x800000, role=slave
+
+These might be specified in the domain config file like this:
+
+    static_shm = ["id=ID2, offset = 0x10000, begin=0x690000, end=0x800000,
+role=slave"]
+
+
+More formally, the string is a series of comma-separated keyword/value
+pairs. Each parameter may be specified at most once. Default values apply if
+the parameter is not specified.
+
+=head1 Parameters
+
+=over 4
+
+=item B<id>
+
+=over 4
+
+=item Description
+
+The unique identifier of the shared memory region.
+
+Every identifier could appear only once in each xl config file.
+
+=item Supported values
+
+A string that contains alphanumerics and "_"s, and is no longer than 128
+characters.
+
+=item Default value
+
+None, this parameter is mandatory.
+
+=back
+
+=item B<begin>/B<end>
+
+=over 4
+
+=item Description
+
+The boundaries of the shared memory area.
+
+=item Supported values
+
+Same with B<offset>.
+
+=item Default Value
+
+None, this parameter is mandatory.
+
+=back
+
+=item B<offset>
+
+=over 4
+
+=item Description
+
+Can only appear when B<role> = slave. If set, the address mapping will not
+start from the beginning the backing memory region, but from the middle
+(B<offet> bytes away from the beginning) of it. See the graph below:
+
+With B<offset> = 0, the mapping will look like:
+
+  backing memory region:  #########################################
+                          |                       |
+                          |                       |
+                          |                       |
+                          V                       V
+  slave's shared region:  #########################
+
+With B<offset> > 0:
+
+  backing memory region:   #########################################
+                           |<-- offset -->||                       |
+                                           |                       |
+                                           |                       |
+                                           V                       V
+  slave's memory region:                   #########################
+
+=item Supported values
+
+Decimals or hexadecimals with a prefix "0x", and should be the multiple of the
+hypervisor page granularity (currently 4K on both ARM and x86).
+
+=item Default value
+
+0x0
+
+=back
+
+=item B<role>
+
+=over 4
+
+=item Description
+
+The backing area would be taken from one domain, which we will mark
+as the "master domain", and this domain should be created prior to any
+other slave domains that depend on it.
+
+This arugment specifies the role of this domain.
+
+=item Supported values
+
+master, slave
+
+=item Default value
+
+slave
+
+=back
+
+=item B<prot>
+
+=over 4
+
+=item Description
+
+When B<role> = master, this means the largest set of stage-2 permission flags
+that can be granted to the slave domains. When B<role> = slave, this means the
+stage-2 permission flags of the shared memory area.
+
+=item Supported values
+
+Currently only 'rw' is supported.
+
+=item Default value
+
+rw
+
+=back
+
+=item B<cache_policy>
+
+=over 4
+
+=item Description
+
+The stage-2 cacheability/shareability attributes of the shared memory area.
+This can only appear when B<role> = master.
+
+=item Supported values
+
+Currently, only the following policy is supported:
+
+=over 4
+
+=item B<ARM_normal>
+
+Only applicable to ARM guests. This would mean Inner and Outer Write-Back
+Cacheable, and Inner Shareable.
+
+=back
+
+=item Default value
+
+ARM_normal
+
+=back
+
+=back
+
+=head1 TYPICAL USAGE
+
+A typical procedure of setting up a shared mem region among several VMs is:
+
+=over 4
+
+1. Add a static_shm option to the master domain's xl config file, assign an
+B<ID> to it and mark it's B<role> as master, and set up the boundaries, prot
+flag, and B<cache_policy> appropriately.
+
+2. Add a static_shm option to every slave domain's xl config file, set
+their B<ID> to the same value as the master's, and set up the B<offset>,
+boundaries and prot flag appropriately.
+
+3. Create the master domain.
+
+4. Create the slaves.
+
+=back
+
+Remember that the master domain must be created before any slave domains could
+be created, for the slaves depend on the memory pages backed by their master.
+
+=head1 Example
+
+Suppose that we have 3 domains: vm1~vm3. And we want to setup two shared
+regions, say, ID1 and ID2, among the three domains, with the following address
+mapping:
+
+   ID1: (vm1 : 0x100000~0x200000) <=====> (vm2 : 0x500000~0x600000)
+   ID2: (vm1 : 0x310000~0x400000) <=====> (vm3 : 0x690000~0x800000)
+
+According to the syntax defined above, the xl config files of the three domains
+should contains the following content:
+
+In xl config file of vm1:
+  static_shm = [ "id=ID1, begin=0x100000, end=0x200000, role=master,
+cache_policy=x86_normal, prot=rw",
+"id=ID2, begin=0x300000, end=0x400000, role=master" ]
+
+In xl config file of vm2:
+  static_shm = [ "id=ID1, offset=0, begin=0x500000, end=0x600000,
+role=slave, prot=rw" ]
+
+In xl config file of vm3:
+  static_shm = [ "id=ID2, offset=0x10000, begin=0x690000,
+end=0x800000, role=slave" ]
+
+After that, just create vm1 first, and then create vm2 and vm3 in any order.
docs/man/xl.cfg.pod.5.in +8 -0
index a699367779..c4d8d5e8ff 100644
@@ -277,6 +277,14 @@ memory=8096 will report significantly less memory available for use
 than a system with maxmem=8096 memory=8096 due to the memory overhead
 of having to track the unused pages.
 
+=item B<static_shm=[ "SSHM_SPEC", "SSHM_SPEC", ... ]>
+
+Specifies the static shared memory regions of this guest. Static shared
+memory regions enables guests to communicate with each other through
+one or more shared memory regions, even without grant table support.
+Currently, this only works on ARM guests.
+See L<xl-static-shm-configuration(5)> for more details.
+
 =back
 
 =head3 Guest Virtual NUMA Configuration
docs/misc/xenstore-paths.markdown +47 -0

59 lines not on this page · raw message

Signature · 7 lines
2.16.1


_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel
#44 lore raw

Re: [PATCH v4 7/7] docs: documentation about static shared memory regions

Hi,

Quoted 28 lines · Zhongze Liu

Add docs to document the motivation, usage, use cases and other relevant information about the static shared memory feature.

This is for the proposal "Allow setting up shared memory areas between VMs from xl config file". See:

   https://lists.xen.org/archives/html/xen-devel/2017-08/msg03242.html
Cc Ian Jackson <[email protected]>
Cc Wei Liu <[email protected]>
Cc Stefano Stabellini <[email protected]>
Cc Julien Grall <[email protected]>
---
  docs/man/xl-static-shm-configuration.pod.5 | 257 +++++++++++++++++++++++++++++
  docs/man/xl.cfg.pod.5.in                   |   8 +
  docs/misc/xenstore-paths.markdown          |  47 ++++++
  3 files changed, 312 insertions(+)

create mode 100644 docs/man/xl-static-shm-configuration.pod.5

docs/man/xl-static-shm-configuration.pod.5 new file +0 -0
new file mode 100644
index 0000000000..d68ed0ebf7

docs/man/xl-static-shm-configuration.pod.5 line 3

Quoted 3 lines
docs/man/xl-static-shm-configuration.pod.5 new file +3 -0
@@ -0,0 +1,257 @@
+=head1 NAME
+
+xl-static-shm-configuration - XL Static Shared Memeory Configuration Syntax

s/Memeory/memory/

Quoted 8 lines
docs/man/xl-static-shm-configuration.pod.5 new file +8 -0
+
+
+(B<NOTE>: This is currently only available to ARM guests.)
+
+=head1 DESCRIPTION
+
+The static_shm option allows users to statically setup shared memory regions
+among a group of VMs, enabling guests without grant table support to do

docs/man/xl-static-shm-configuration.pod.5 line 21

Quoted 10 lines
docs/man/xl-static-shm-configuration.pod.5 new file +10 -0
+shm-based communication.
+
+Every shared region is:
+
+=over 4
+
+* Uniquely identified by a string that is no longer than 128 characters, which
+is called an B<identifier> in this document.
+
+* Backed by exactely one domain, which is called a B<master> domain, and all

s/exactely/exactly/

Quoted 75 lines
docs/man/xl-static-shm-configuration.pod.5 new file +75 -0
+the other domains who are also sharing this region are called B<slave>s.
+
+=back
+
+=head1 SYNTAX
+
+This document specifies syntax of the static shared memory configuration in
+the xl config file. It has the following form:
+
+    static_shm = [ "SSHM_SPEC", "SSHM_SPEC", ... ]
+
+where each C<SSHM_SPEC> is in this form:
+
+    [<key>=<value>,]*
+
+Valid examples of C<SSHM_SPEC> are:
+
+    id=ID1, begin=0x100000, end=0x200000, role=master, cache_policy=x86_normal
+    id=ID1, offset = 0, begin=0x500000, end=0x600000, role=slave, prot=rw
+    id=ID2, begin=0x300000, end=0x400000, role=master
+    id=ID2, offset = 0x10000, begin=0x690000, end=0x800000, role=slave
+    id=ID2, offset = 0x10000, begin=0x690000, end=0x800000, role=slave
+
+These might be specified in the domain config file like this:
+
+    static_shm = ["id=ID2, offset = 0x10000, begin=0x690000, end=0x800000,
+role=slave"]
+
+
+More formally, the string is a series of comma-separated keyword/value
+pairs. Each parameter may be specified at most once. Default values apply if
+the parameter is not specified.
+
+=head1 Parameters
+
+=over 4
+
+=item B<id>
+
+=over 4
+
+=item Description
+
+The unique identifier of the shared memory region.
+
+Every identifier could appear only once in each xl config file.
+
+=item Supported values
+
+A string that contains alphanumerics and "_"s, and is no longer than 128
+characters.
+
+=item Default value
+
+None, this parameter is mandatory.
+
+=back
+
+=item B<begin>/B<end>
+
+=over 4
+
+=item Description
+
+The boundaries of the shared memory area.
+
+=item Supported values
+
+Same with B<offset>.
+
+=item Default Value
+
+None, this parameter is mandatory.
+
+=back

docs/man/xl-static-shm-configuration.pod.5 line 106

Quoted 10 lines
docs/man/xl-static-shm-configuration.pod.5 new file +10 -0
+
+=item B<offset>
+
+=over 4
+
+=item Description
+
+Can only appear when B<role> = slave. If set, the address mapping will not
+start from the beginning the backing memory region, but from the middle
+(B<offet> bytes away from the beginning) of it. See the graph below:

s/offet/offset/

Quoted 31 lines
docs/man/xl-static-shm-configuration.pod.5 new file +31 -0
+
+With B<offset> = 0, the mapping will look like:
+
+  backing memory region:  #########################################
+                          |                       |
+                          |                       |
+                          |                       |
+                          V                       V
+  slave's shared region:  #########################
+
+With B<offset> > 0:
+
+  backing memory region:   #########################################
+                           |<-- offset -->||                       |
+                                           |                       |
+                                           |                       |
+                                           V                       V
+  slave's memory region:                   #########################
+
+=item Supported values
+
+Decimals or hexadecimals with a prefix "0x", and should be the multiple of the
+hypervisor page granularity (currently 4K on both ARM and x86).
+
+=item Default value
+
+0x0
+
+=back
+
+=item B<role>

docs/man/xl-static-shm-configuration.pod.5 line 147

Quoted 10 lines
docs/man/xl-static-shm-configuration.pod.5 new file +10 -0
+
+=over 4
+
+=item Description
+
+The backing area would be taken from one domain, which we will mark
+as the "master domain", and this domain should be created prior to any
+other slave domains that depend on it.
+
+This arugment specifies the role of this domain.

s/arugment/argument/

Quoted 185 lines
docs/man/xl-static-shm-configuration.pod.5 new file +110 -0
+
+=item Supported values
+
+master, slave
+
+=item Default value
+
+slave
+
+=back
+
+=item B<prot>
+
+=over 4
+
+=item Description
+
+When B<role> = master, this means the largest set of stage-2 permission flags
+that can be granted to the slave domains. When B<role> = slave, this means the
+stage-2 permission flags of the shared memory area.
+
+=item Supported values
+
+Currently only 'rw' is supported.
+
+=item Default value
+
+rw
+
+=back
+
+=item B<cache_policy>
+
+=over 4
+
+=item Description
+
+The stage-2 cacheability/shareability attributes of the shared memory area.
+This can only appear when B<role> = master.
+
+=item Supported values
+
+Currently, only the following policy is supported:
+
+=over 4
+
+=item B<ARM_normal>
+
+Only applicable to ARM guests. This would mean Inner and Outer Write-Back
+Cacheable, and Inner Shareable.
+
+=back
+
+=item Default value
+
+ARM_normal
+
+=back
+
+=back
+
+=head1 TYPICAL USAGE
+
+A typical procedure of setting up a shared mem region among several VMs is:
+
+=over 4
+
+1. Add a static_shm option to the master domain's xl config file, assign an
+B<ID> to it and mark it's B<role> as master, and set up the boundaries, prot
+flag, and B<cache_policy> appropriately.
+
+2. Add a static_shm option to every slave domain's xl config file, set
+their B<ID> to the same value as the master's, and set up the B<offset>,
+boundaries and prot flag appropriately.
+
+3. Create the master domain.
+
+4. Create the slaves.
+
+=back
+
+Remember that the master domain must be created before any slave domains could
+be created, for the slaves depend on the memory pages backed by their master.
+
+=head1 Example
+
+Suppose that we have 3 domains: vm1~vm3. And we want to setup two shared
+regions, say, ID1 and ID2, among the three domains, with the following address
+mapping:
+
+   ID1: (vm1 : 0x100000~0x200000) <=====> (vm2 : 0x500000~0x600000)
+   ID2: (vm1 : 0x310000~0x400000) <=====> (vm3 : 0x690000~0x800000)
+
+According to the syntax defined above, the xl config files of the three domains
+should contains the following content:
+
+In xl config file of vm1:
+  static_shm = [ "id=ID1, begin=0x100000, end=0x200000, role=master,
+cache_policy=x86_normal, prot=rw",
+"id=ID2, begin=0x300000, end=0x400000, role=master" ]
+
+In xl config file of vm2:
+  static_shm = [ "id=ID1, offset=0, begin=0x500000, end=0x600000,
+role=slave, prot=rw" ]
+
+In xl config file of vm3:
+  static_shm = [ "id=ID2, offset=0x10000, begin=0x690000,
+end=0x800000, role=slave" ]
+
+After that, just create vm1 first, and then create vm2 and vm3 in any order.
docs/man/xl.cfg.pod.5.in +8 -0
index a699367779..c4d8d5e8ff 100644
@@ -277,6 +277,14 @@ memory=8096 will report significantly less memory available for use
  than a system with maxmem=8096 memory=8096 due to the memory overhead
  of having to track the unused pages.
 
+=item B<static_shm=[ "SSHM_SPEC", "SSHM_SPEC", ... ]>
+
+Specifies the static shared memory regions of this guest. Static shared
+memory regions enables guests to communicate with each other through
+one or more shared memory regions, even without grant table support.
+Currently, this only works on ARM guests.
+See L<xl-static-shm-configuration(5)> for more details.
+
  =back
 
  =head3 Guest Virtual NUMA Configuration
docs/misc/xenstore-paths.markdown +40 -0
index 7be2592c74..33ad123839 100644
@@ -174,6 +174,14 @@ than this amount of RAM.
 
  The size of the video RAM this domain is configured with.
 
+#### ~/static_shm/[_a-zA-Z0-9]+/role = ("master"|"slave") []
+
+(Note: Currently, this will only appear on ARM guests.)
+
+The role of this domain in the static shared memory region whose id matches
+the `[_a-zA-Z0-9]+` part in the path. (Described in the manpage
+**xl-static-shm-configuration(5)**).
+
  #### ~/device/suspend/event-channel = ""|EVTCHN [w]
 
  The domain's suspend event channel. The toolstack will create this
@@ -539,6 +547,45 @@ type. The name of each backend directory is the same as the backend type
 
  Contains the PIDs of the device models running on the domain.
 
+#### /libxl/static_shm/[_a-zA-Z0-9]+/* []
+
+(Note: Currently, this will only appear on ARM guests.)
+
+The following paths contain backing memory parameters of a static shared memory
+whose id matches the `[_a-zA-Z0-9]+` part in the path. Their formats and
+meanings are the same as those in an xl config file, described in the manpage
+**xl-static-shm-configuration(5)**.
+
+* begin/end: the boundary of the backing memory region.
+* prot: the largest set of stage-2 permission flags that can be granted to
+  the slave domains.
+* cache_policy: the stage-2 cacheability/shareability attributes of the backing
+  memory region.
+
+The following paths contain run-time information about the static shared memory
+region.
+
+* master: the domid of the backing domain.
+* slaves: information about the slaves that are sharing the region, see
+  ** /libxl/static_shm/[_a-zA-Z0-9]+/slaves/$DOMID/* ** below.
+* usercnt: An integer. This is the reference count of the backing memory region,
+  including the master domain itself. When this value reachies 0, the backing
+  memory region will be freed.
+
+#### /libxl/staitc_shm/[_a-zA-Z0-9]+/slaves/$DOMID/* []
+
+(Note: Currently, this will only appear on ARM guests.)
+
+The following paths contain static shared memory region parameters of a slave
+domain. Their formats and meanings are the same as those in xl config files,
+described in the manpage **xl-static-shm-configuration(5)**.

docs/misc/xenstore-paths.markdown type. The name of each backend directory is the same as the backend type · line 591

Quoted 10 lines
docs/misc/xenstore-paths.markdown +7 -0
+
+* begin/end: the boundary of the shared memory region.
+* prot: the stage-2 permission flags of the shared memory area.
+* offset: when mapping the backing memory region to the slave's memory space,
+  the mapping will start from offset bytes after the beginning of the backing
+  memory region.
+
  ## Virtual Machine Paths
 
  The /vm/$UUID namespace is used by toolstacks to store various

Cheers,

Signature · 6 lines
Julien Grall

_______________________________________________
Xen-devel mailing list
[email protected]
https://lists.xenproject.org/mailman/listinfo/xen-devel