diff mbox series

[v4,3/6] xen: extend XEN_DOMCTL_memory_mapping to handle memory policy

Message ID 20190807002311.9906-3-sstabellini@kernel.org (mailing list archive)
State New, archived
Headers show
Series [v4,1/6] xen/arm: introduce p2m_is_mmio | expand

Commit Message

Stefano Stabellini Aug. 7, 2019, 12:23 a.m. UTC
Reuse the existing padding field to pass memory policy information. On
Arm, the caller can specify whether the memory should be mapped as
Device-nGnRE (Device Memory on Armv7) at stage-2, which is the default
and the only possibility today, or cacheable memory write-back. The
resulting memory attributes will be a combination of stage-2 and stage-1
memory attributes: it will actually be the strongest between the 2
stages attributes.

On x86, the only option is uncachable. The current behavior becomes the
default (numerically '0'). Also explicitely set the memory_policy field
to 0 in libxc.

On Arm, map Device-nGnRE as p2m_mmio_direct_dev (as it is already done
today) and WB cacheable memory as p2m_mmio_direct_c.

On x86, there is just one policy which is the default.

Signed-off-by: Stefano Stabellini <stefanos@xilinx.com>
CC: JBeulich@suse.com
CC: andrew.cooper3@citrix.com

---

Changes in v4:
- return -EINVAL on XEN_DOMCTL_memory_mapping on default label
- use MEMORY_POLICY_DEFAULT instead of 0
- uint32_t memory_policy -> unsigned int memory_policy
- cache= -> policy=
- MEMORY_POLICY_X86_UC_MINUS -> MEMORY_POLICY_DEFAULT
- ARM -> Arm

Changes in v3:
- error handling in default label of the switch
- set memory_policy to 0 in libxc
- improve commit message
- improve comments
- s/Device-nGRE/Device-nGnRE/g
- add in-code comment
- s/MEMORY_POLICY_X86_UC/MEMORY_POLICY_X86_UC_MINUS/g
- #ifdef hypercall defines according to arch

Changes in v2:
- rebase
- use p2m_mmio_direct_c
- use EOPNOTSUPP
- rename cache_policy to memory policy
- rename MEMORY_POLICY_DEVMEM to MEMORY_POLICY_ARM_DEV_nGRE
- rename MEMORY_POLICY_MEMORY to MEMORY_POLICY_ARM_MEM_WB
- add MEMORY_POLICY_X86_UC
- add MEMORY_POLICY_DEFAULT and use it
---
 tools/libxc/xc_domain.c     |  1 +
 xen/common/domctl.c         | 25 +++++++++++++++++++++++--
 xen/include/public/domctl.h | 20 +++++++++++++++++++-
 3 files changed, 43 insertions(+), 3 deletions(-)

Comments

Jan Beulich Aug. 9, 2019, 11:25 a.m. UTC | #1
On 07.08.2019 02:23, Stefano Stabellini wrote:
> @@ -950,9 +951,29 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>           if ( add )
>           {
>               printk(XENLOG_G_DEBUG
> -                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
> -                   d->domain_id, gfn, mfn, nr_mfns);
> +                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx policy=%u\n",
> +                   d->domain_id, gfn, mfn, nr_mfns, memory_policy);
>   
> +            switch ( memory_policy )
> +            {
> +#ifdef CONFIG_ARM
> +                case MEMORY_POLICY_ARM_MEM_WB:
> +                    p2mt = p2m_mmio_direct_c;
> +                    break;
> +                case MEMORY_POLICY_ARM_DEV_nGnRE:
> +                    p2mt = p2m_mmio_direct_dev;
> +                    break;
> +#endif
> +#ifdef CONFIG_X86
> +                case MEMORY_POLICY_DEFAULT:
> +                    p2mt = p2m_mmio_direct;
> +                    break;
> +#endif
> +                default:
> +                    domctl_lock_release();
> +                    ret = -EINVAL;
> +                    goto domctl_out_unlock_domonly;
> +            }

Indentation is wrong here: The case labels ought to align with their
switch(). Also please have blank lines between case blocks. For the
Arm part it would be nice if the case being MEMORY_POLICY_DEFAULT
would gain a respective comment, perhaps in the form of a commented
out case label.

> --- a/xen/include/public/domctl.h
> +++ b/xen/include/public/domctl.h
> @@ -571,12 +571,30 @@ struct xen_domctl_bind_pt_irq {
>   */
>   #define DPCI_ADD_MAPPING         1
>   #define DPCI_REMOVE_MAPPING      0
> +/*
> + * Default memory policy. Corresponds to:
> + * Arm: MEMORY_POLICY_ARM_DEV_nGnRE
> + * x86: Memory type UNCACHABLE
> + */

I continue to be unhappy about the imprecise "uncachable" here
for x86: In shadow mode and on AMD/NPT we produce UC- mappings,
while the way EPT works it further depends on host and guest
MTRR settings.  Andrew - do you have any thoughts how to best
describe this here without growing the text too large, but also
without producing an overly imprecise description?

> +#define MEMORY_POLICY_DEFAULT         0
> +#if defined(__arm__) || defined (__aarch64__)
> +/* Arm only. Outer Shareable, Device-nGnRE memory (Device Memory on Armv7) */
> +# define MEMORY_POLICY_ARM_DEV_nGnRE      0
> +/* Arm only. Outer Shareable, Outer/Inner Write-Back Cacheable memory */
> +# define MEMORY_POLICY_ARM_MEM_WB         1
> +/*
> + * On Arm, MEMORY_POLICY selects the stage-2 memory attributes, but note
> + * that the resulting memory attributes will be a combination of stage-2
> + * and stage-1 memory attributes: it will be the strongest between the 2
> + * stages attributes.
> + */
> +#endif
>   struct xen_domctl_memory_mapping {
>       uint64_aligned_t first_gfn; /* first page (hvm guest phys page) in range */
>       uint64_aligned_t first_mfn; /* first page (machine page) in range */
>       uint64_aligned_t nr_mfns;   /* number of pages in range (>0) */
>       uint32_t add_mapping;       /* add or remove mapping */
> -    uint32_t padding;           /* padding for 64-bit aligned structure */
> +    uint32_t memory_policy;      /* cacheability of the memory mapping */

The comment looks to start one column too far to the right.

Jan
Julien Grall Aug. 9, 2019, 5:25 p.m. UTC | #2
Hi,

On 07/08/2019 01:23, Stefano Stabellini wrote:
> diff --git a/xen/common/domctl.c b/xen/common/domctl.c
> index 2674caa005..063523c7f7 100644
> --- a/xen/common/domctl.c
> +++ b/xen/common/domctl.c
> @@ -920,6 +920,7 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>           unsigned long mfn_end = mfn + nr_mfns - 1;
>           int add = op->u.memory_mapping.add_mapping;
>           p2m_type_t p2mt;
> +        unsigned int memory_policy = op->u.memory_mapping.memory_policy;
>   
>           ret = -EINVAL;
>           if ( mfn_end < mfn || /* wrap? */
> @@ -950,9 +951,29 @@ long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
>           if ( add )
>           {
>               printk(XENLOG_G_DEBUG
> -                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
> -                   d->domain_id, gfn, mfn, nr_mfns);
> +                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx policy=%u\n",
> +                   d->domain_id, gfn, mfn, nr_mfns, memory_policy);
>   
> +            switch ( memory_policy )
> +            {
> +#ifdef CONFIG_ARM
> +                case MEMORY_POLICY_ARM_MEM_WB:
> +                    p2mt = p2m_mmio_direct_c;
> +                    break;
> +                case MEMORY_POLICY_ARM_DEV_nGnRE:
> +                    p2mt = p2m_mmio_direct_dev;
> +                    break;
> +#endif
> +#ifdef CONFIG_X86
> +                case MEMORY_POLICY_DEFAULT:
> +                    p2mt = p2m_mmio_direct;
> +                    break;
> +#endif

I would prefer if the arch specific bits are done in arch code and not in common 
code. This could be done in a separate patch if you don't plan to respin it.

The rest looks good to me.

Cheers,
diff mbox series

Patch

diff --git a/tools/libxc/xc_domain.c b/tools/libxc/xc_domain.c
index 05d771f2ce..075ffb9ed1 100644
--- a/tools/libxc/xc_domain.c
+++ b/tools/libxc/xc_domain.c
@@ -2070,6 +2070,7 @@  int xc_domain_memory_mapping(
     domctl.cmd = XEN_DOMCTL_memory_mapping;
     domctl.domain = domid;
     domctl.u.memory_mapping.add_mapping = add_mapping;
+    domctl.u.memory_mapping.memory_policy = MEMORY_POLICY_DEFAULT;
     max_batch_sz = nr_mfns;
     do
     {
diff --git a/xen/common/domctl.c b/xen/common/domctl.c
index 2674caa005..063523c7f7 100644
--- a/xen/common/domctl.c
+++ b/xen/common/domctl.c
@@ -920,6 +920,7 @@  long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
         unsigned long mfn_end = mfn + nr_mfns - 1;
         int add = op->u.memory_mapping.add_mapping;
         p2m_type_t p2mt;
+        unsigned int memory_policy = op->u.memory_mapping.memory_policy;
 
         ret = -EINVAL;
         if ( mfn_end < mfn || /* wrap? */
@@ -950,9 +951,29 @@  long do_domctl(XEN_GUEST_HANDLE_PARAM(xen_domctl_t) u_domctl)
         if ( add )
         {
             printk(XENLOG_G_DEBUG
-                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx\n",
-                   d->domain_id, gfn, mfn, nr_mfns);
+                   "memory_map:add: dom%d gfn=%lx mfn=%lx nr=%lx policy=%u\n",
+                   d->domain_id, gfn, mfn, nr_mfns, memory_policy);
 
+            switch ( memory_policy )
+            {
+#ifdef CONFIG_ARM
+                case MEMORY_POLICY_ARM_MEM_WB:
+                    p2mt = p2m_mmio_direct_c;
+                    break;
+                case MEMORY_POLICY_ARM_DEV_nGnRE:
+                    p2mt = p2m_mmio_direct_dev;
+                    break;
+#endif
+#ifdef CONFIG_X86
+                case MEMORY_POLICY_DEFAULT:
+                    p2mt = p2m_mmio_direct;
+                    break;
+#endif
+                default:
+                    domctl_lock_release();
+                    ret = -EINVAL;
+                    goto domctl_out_unlock_domonly;
+            }
             ret = map_mmio_regions(d, _gfn(gfn), nr_mfns, _mfn(mfn), p2mt);
             if ( ret < 0 )
                 printk(XENLOG_G_WARNING
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 19486d5e32..b9078400fa 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -571,12 +571,30 @@  struct xen_domctl_bind_pt_irq {
 */
 #define DPCI_ADD_MAPPING         1
 #define DPCI_REMOVE_MAPPING      0
+/*
+ * Default memory policy. Corresponds to:
+ * Arm: MEMORY_POLICY_ARM_DEV_nGnRE
+ * x86: Memory type UNCACHABLE
+ */
+#define MEMORY_POLICY_DEFAULT         0
+#if defined(__arm__) || defined (__aarch64__)
+/* Arm only. Outer Shareable, Device-nGnRE memory (Device Memory on Armv7) */
+# define MEMORY_POLICY_ARM_DEV_nGnRE      0
+/* Arm only. Outer Shareable, Outer/Inner Write-Back Cacheable memory */
+# define MEMORY_POLICY_ARM_MEM_WB         1
+/*
+ * On Arm, MEMORY_POLICY selects the stage-2 memory attributes, but note
+ * that the resulting memory attributes will be a combination of stage-2
+ * and stage-1 memory attributes: it will be the strongest between the 2
+ * stages attributes.
+ */
+#endif
 struct xen_domctl_memory_mapping {
     uint64_aligned_t first_gfn; /* first page (hvm guest phys page) in range */
     uint64_aligned_t first_mfn; /* first page (machine page) in range */
     uint64_aligned_t nr_mfns;   /* number of pages in range (>0) */
     uint32_t add_mapping;       /* add or remove mapping */
-    uint32_t padding;           /* padding for 64-bit aligned structure */
+    uint32_t memory_policy;      /* cacheability of the memory mapping */
 };