All of lore.kernel.org
 help / color / mirror / Atom feed
* [RFC 0/3] x86: Add a hvmop for setting the #VE suppress bit
@ 2017-04-05 13:38 Adrian Pop
  2017-04-05 13:38 ` [RFC 1/3] x86/mm: Change default value for suppress #VE in set_mem_access() Adrian Pop
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Adrian Pop @ 2017-04-05 13:38 UTC (permalink / raw)
  To: xen-devel
  Cc: Tamas K Lengyel, Wei Liu, Razvan Cojocaru, Adrian Pop,
	George Dunlap, Andrew Cooper, Ian Jackson, Jan Beulich

After DomU has enabled #VE using HVMOP_altp2m_vcpu_enable_notify, all
its pages have the #VE suppress bit cleared, generating #VEs for any EPT
violation.  There is currently no way to change the value of the #VE
suppress bit for a page from a domain; it can only be done in Xen
internally using ept_set_entry().

Following the discussion from
https://lists.xen.org/archives/html/xen-devel/2017-03/msg01312.html this
patch introduces a new hvmop to set this bit.

I'm not quite sure where it would be best to define
p2m_set_suppress_ve().  It is currently in mem_access.c, but this file
contains common functions for x86 (vmx & svm), while this function is
Intel-specific.

Adrian Pop (2):
  x86/altp2m: Add a hvmop for setting the suppress #VE bit
  libxc: Add support for the altp2m suppress #VE hvmop

Vlad Ioan Topan (1):
  x86/mm: Change default value for suppress #VE in set_mem_access()

 tools/libxc/include/xenctrl.h   |  2 ++
 tools/libxc/xc_altp2m.c         | 24 +++++++++++++++++++
 xen/arch/x86/hvm/hvm.c          | 14 +++++++++++
 xen/arch/x86/mm/mem_access.c    | 51 +++++++++++++++++++++++++++++++++++++++--
 xen/include/public/hvm/hvm_op.h | 15 ++++++++++++
 xen/include/xen/mem_access.h    |  3 +++
 6 files changed, 107 insertions(+), 2 deletions(-)

-- 
2.12.1


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

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

* [RFC 1/3] x86/mm: Change default value for suppress #VE in set_mem_access()
  2017-04-05 13:38 [RFC 0/3] x86: Add a hvmop for setting the #VE suppress bit Adrian Pop
@ 2017-04-05 13:38 ` Adrian Pop
  2017-04-05 13:38 ` [RFC 2/3] x86/altp2m: Add a hvmop for setting the suppress #VE bit Adrian Pop
  2017-04-05 13:38 ` [RFC 3/3] libxc: Add support for the altp2m suppress #VE hvmop Adrian Pop
  2 siblings, 0 replies; 4+ messages in thread
From: Adrian Pop @ 2017-04-05 13:38 UTC (permalink / raw)
  To: xen-devel
  Cc: Tamas K Lengyel, Wei Liu, Razvan Cojocaru, George Dunlap,
	Andrew Cooper, Ian Jackson, Jan Beulich, Vlad Ioan Topan

From: Vlad Ioan Topan <itopan@bitdefender.com>

The default value for the "suppress #VE" bit set by set_mem_access()
currently depends on whether the call is made from the same domain (the
bit is set when called from another domain and cleared if called from
the same domain). This patch changes that behavior to inherit the old
suppress #VE bit value if it is already set and to set it to 1
otherwise, which is safer and more reliable.

Signed-off-by: Vlad Ioan Topan <itopan@bitdefender.com>
---
 xen/arch/x86/mm/mem_access.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c
index 5adaf6df90..d0b0767855 100644
--- a/xen/arch/x86/mm/mem_access.c
+++ b/xen/arch/x86/mm/mem_access.c
@@ -273,8 +273,7 @@ int p2m_set_altp2m_mem_access(struct domain *d, struct p2m_domain *hp2m,
         }
     }
 
-    return ap2m->set_entry(ap2m, gfn_l, mfn, PAGE_ORDER_4K, t, a,
-                         (current->domain != d));
+    return ap2m->set_entry(ap2m, gfn_l, mfn, PAGE_ORDER_4K, t, a, -1);
 }
 
 static int set_mem_access(struct domain *d, struct p2m_domain *p2m,
-- 
2.12.1


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

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

* [RFC 2/3] x86/altp2m: Add a hvmop for setting the suppress #VE bit
  2017-04-05 13:38 [RFC 0/3] x86: Add a hvmop for setting the #VE suppress bit Adrian Pop
  2017-04-05 13:38 ` [RFC 1/3] x86/mm: Change default value for suppress #VE in set_mem_access() Adrian Pop
@ 2017-04-05 13:38 ` Adrian Pop
  2017-04-05 13:38 ` [RFC 3/3] libxc: Add support for the altp2m suppress #VE hvmop Adrian Pop
  2 siblings, 0 replies; 4+ messages in thread
From: Adrian Pop @ 2017-04-05 13:38 UTC (permalink / raw)
  To: xen-devel
  Cc: Tamas K Lengyel, Wei Liu, Razvan Cojocaru, Adrian Pop,
	George Dunlap, Andrew Cooper, Ian Jackson, Jan Beulich

Introduce a new hvmop, HVMOP_altp2m_set_suppress_ve, which allows a
domain to change the value of the #VE suppress bit for a page.

Signed-off-by: Adrian Pop <apop@bitdefender.com>
---
 xen/arch/x86/hvm/hvm.c          | 14 ++++++++++++
 xen/arch/x86/mm/mem_access.c    | 48 +++++++++++++++++++++++++++++++++++++++++
 xen/include/public/hvm/hvm_op.h | 15 +++++++++++++
 xen/include/xen/mem_access.h    |  3 +++
 4 files changed, 80 insertions(+)

diff --git a/xen/arch/x86/hvm/hvm.c b/xen/arch/x86/hvm/hvm.c
index 2e76c2345b..eb01527c5b 100644
--- a/xen/arch/x86/hvm/hvm.c
+++ b/xen/arch/x86/hvm/hvm.c
@@ -4356,6 +4356,7 @@ static int do_altp2m_op(
     case HVMOP_altp2m_destroy_p2m:
     case HVMOP_altp2m_switch_p2m:
     case HVMOP_altp2m_set_mem_access:
+    case HVMOP_altp2m_set_suppress_ve:
     case HVMOP_altp2m_change_gfn:
         break;
     default:
@@ -4472,6 +4473,19 @@ static int do_altp2m_op(
                                     a.u.set_mem_access.view);
         break;
 
+    case HVMOP_altp2m_set_suppress_ve:
+        if ( a.u.set_suppress_ve.pad1 || a.u.set_suppress_ve.pad2 )
+            rc = -EINVAL;
+        else
+        {
+            gfn_t gfn = _gfn(a.u.set_mem_access.gfn);
+            unsigned int altp2m_idx = a.u.set_mem_access.view;
+            uint8_t suppress_ve = a.u.set_suppress_ve.suppress_ve;
+
+            rc = p2m_set_suppress_ve(d, gfn, suppress_ve, altp2m_idx);
+        }
+        break;
+
     case HVMOP_altp2m_change_gfn:
         if ( a.u.change_gfn.pad1 || a.u.change_gfn.pad2 )
             rc = -EINVAL;
diff --git a/xen/arch/x86/mm/mem_access.c b/xen/arch/x86/mm/mem_access.c
index d0b0767855..b9e611d3db 100644
--- a/xen/arch/x86/mm/mem_access.c
+++ b/xen/arch/x86/mm/mem_access.c
@@ -466,6 +466,54 @@ int p2m_get_mem_access(struct domain *d, gfn_t gfn, xenmem_access_t *access)
 }
 
 /*
+ * Set/clear the #VE suppress bit for a page.  Only available on VMX.
+ */
+int p2m_set_suppress_ve(struct domain *d, gfn_t gfn, uint8_t suppress_ve,
+                        unsigned int altp2m_idx)
+{
+    struct p2m_domain *host_p2m = p2m_get_hostp2m(d);
+    struct p2m_domain *ap2m = NULL;
+    struct p2m_domain *p2m = NULL;
+    mfn_t mfn;
+    p2m_access_t a;
+    p2m_type_t t;
+    unsigned long gfn_l;
+    int rc = 0;
+
+    if ( !cpu_has_vmx )
+        return -EOPNOTSUPP;
+
+    if ( altp2m_idx > 0 )
+    {
+        if ( altp2m_idx >= MAX_ALTP2M ||
+                d->arch.altp2m_eptp[altp2m_idx] == mfn_x(INVALID_MFN) )
+            return -EINVAL;
+
+        p2m = ap2m = d->arch.altp2m_p2m[altp2m_idx];
+    }
+    else
+    {
+        p2m = host_p2m;
+    }
+
+    p2m_lock(host_p2m);
+    if ( ap2m )
+        p2m_lock(ap2m);
+
+    gfn_l = gfn_x(gfn);
+    mfn = p2m->get_entry(p2m, gfn_l, &t, &a, 0, NULL, NULL);
+    if ( !mfn_valid(mfn) )
+        return -ESRCH;
+    rc = p2m->set_entry(p2m, gfn_l, mfn, PAGE_ORDER_4K, t, a,
+                        suppress_ve);
+    if ( ap2m )
+        p2m_unlock(ap2m);
+    p2m_unlock(host_p2m);
+
+    return rc;
+}
+
+/*
  * Local variables:
  * mode: C
  * c-file-style: "BSD"
diff --git a/xen/include/public/hvm/hvm_op.h b/xen/include/public/hvm/hvm_op.h
index bc00ef0e65..9736092f58 100644
--- a/xen/include/public/hvm/hvm_op.h
+++ b/xen/include/public/hvm/hvm_op.h
@@ -231,6 +231,18 @@ struct xen_hvm_altp2m_set_mem_access {
 typedef struct xen_hvm_altp2m_set_mem_access xen_hvm_altp2m_set_mem_access_t;
 DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_mem_access_t);
 
+struct xen_hvm_altp2m_set_suppress_ve {
+    /* view */
+    uint16_t view;
+    uint8_t suppress_ve;
+    uint8_t pad1;
+    uint32_t pad2;
+    /* gfn */
+    uint64_t gfn;
+};
+typedef struct xen_hvm_altp2m_set_suppress_ve xen_hvm_altp2m_set_suppress_ve_t;
+DEFINE_XEN_GUEST_HANDLE(xen_hvm_altp2m_set_suppress_ve_t);
+
 struct xen_hvm_altp2m_change_gfn {
     /* view */
     uint16_t view;
@@ -262,6 +274,8 @@ struct xen_hvm_altp2m_op {
 #define HVMOP_altp2m_set_mem_access       7
 /* Change a p2m entry to have a different gfn->mfn mapping */
 #define HVMOP_altp2m_change_gfn           8
+/* Set the "Suppress #VE" bit on a page */
+#define HVMOP_altp2m_set_suppress_ve      9
     domid_t domain;
     uint16_t pad1;
     uint32_t pad2;
@@ -270,6 +284,7 @@ struct xen_hvm_altp2m_op {
         struct xen_hvm_altp2m_vcpu_enable_notify enable_notify;
         struct xen_hvm_altp2m_view               view;
         struct xen_hvm_altp2m_set_mem_access     set_mem_access;
+        struct xen_hvm_altp2m_set_suppress_ve    set_suppress_ve;
         struct xen_hvm_altp2m_change_gfn         change_gfn;
         uint8_t pad[64];
     } u;
diff --git a/xen/include/xen/mem_access.h b/xen/include/xen/mem_access.h
index 5ab34c1553..b6e6a7650a 100644
--- a/xen/include/xen/mem_access.h
+++ b/xen/include/xen/mem_access.h
@@ -78,6 +78,9 @@ long p2m_set_mem_access_multi(struct domain *d,
  */
 int p2m_get_mem_access(struct domain *d, gfn_t gfn, xenmem_access_t *access);
 
+int p2m_set_suppress_ve(struct domain *d, gfn_t gfn, uint8_t suppress_ve,
+                        unsigned int altp2m_idx);
+
 #ifdef CONFIG_HAS_MEM_ACCESS
 int mem_access_memop(unsigned long cmd,
                      XEN_GUEST_HANDLE_PARAM(xen_mem_access_op_t) arg);
-- 
2.12.1


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

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

* [RFC 3/3] libxc: Add support for the altp2m suppress #VE hvmop
  2017-04-05 13:38 [RFC 0/3] x86: Add a hvmop for setting the #VE suppress bit Adrian Pop
  2017-04-05 13:38 ` [RFC 1/3] x86/mm: Change default value for suppress #VE in set_mem_access() Adrian Pop
  2017-04-05 13:38 ` [RFC 2/3] x86/altp2m: Add a hvmop for setting the suppress #VE bit Adrian Pop
@ 2017-04-05 13:38 ` Adrian Pop
  2 siblings, 0 replies; 4+ messages in thread
From: Adrian Pop @ 2017-04-05 13:38 UTC (permalink / raw)
  To: xen-devel
  Cc: Tamas K Lengyel, Wei Liu, Razvan Cojocaru, Adrian Pop,
	George Dunlap, Andrew Cooper, Ian Jackson, Jan Beulich

This adds a wrapper for issuing HVMOP_altp2m_set_suppress_ve from a
domain.

Signed-off-by: Adrian Pop <apop@bitdefender.com>
---
 tools/libxc/include/xenctrl.h |  2 ++
 tools/libxc/xc_altp2m.c       | 24 ++++++++++++++++++++++++
 2 files changed, 26 insertions(+)

diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 2d97d36c38..5e1e4cfa81 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -1923,6 +1923,8 @@ int xc_altp2m_destroy_view(xc_interface *handle, domid_t domid,
 /* Switch all vCPUs of the domain to the specified altp2m view */
 int xc_altp2m_switch_to_view(xc_interface *handle, domid_t domid,
                              uint16_t view_id);
+int xc_altp2m_set_suppress_ve(xc_interface *handle, domid_t domid,
+                              uint16_t view_id, xen_pfn_t gfn, uint8_t sve);
 int xc_altp2m_set_mem_access(xc_interface *handle, domid_t domid,
                              uint16_t view_id, xen_pfn_t gfn,
                              xenmem_access_t access);
diff --git a/tools/libxc/xc_altp2m.c b/tools/libxc/xc_altp2m.c
index 0639632477..b0f3e344af 100644
--- a/tools/libxc/xc_altp2m.c
+++ b/tools/libxc/xc_altp2m.c
@@ -163,6 +163,30 @@ int xc_altp2m_switch_to_view(xc_interface *handle, domid_t domid,
     return rc;
 }
 
+int xc_altp2m_set_suppress_ve(xc_interface *handle, domid_t domid,
+                              uint16_t view_id, xen_pfn_t gfn, uint8_t sve)
+{
+    int rc;
+    DECLARE_HYPERCALL_BUFFER(xen_hvm_altp2m_op_t, arg);
+
+    arg = xc_hypercall_buffer_alloc(handle, arg, sizeof(*arg));
+    if ( arg == NULL )
+        return -1;
+
+    arg->version = HVMOP_ALTP2M_INTERFACE_VERSION;
+    arg->cmd = HVMOP_altp2m_set_suppress_ve;
+    arg->domain = domid;
+    arg->u.set_suppress_ve.view = view_id;
+    arg->u.set_suppress_ve.gfn = gfn;
+    arg->u.set_suppress_ve.suppress_ve = sve;
+
+    rc = xencall2(handle->xcall, __HYPERVISOR_hvm_op, HVMOP_altp2m,
+		  HYPERCALL_BUFFER_AS_ARG(arg));
+
+    xc_hypercall_buffer_free(handle, arg);
+    return rc;
+}
+
 int xc_altp2m_set_mem_access(xc_interface *handle, domid_t domid,
                              uint16_t view_id, xen_pfn_t gfn,
                              xenmem_access_t access)
-- 
2.12.1


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

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

end of thread, other threads:[~2017-04-05 13:38 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-04-05 13:38 [RFC 0/3] x86: Add a hvmop for setting the #VE suppress bit Adrian Pop
2017-04-05 13:38 ` [RFC 1/3] x86/mm: Change default value for suppress #VE in set_mem_access() Adrian Pop
2017-04-05 13:38 ` [RFC 2/3] x86/altp2m: Add a hvmop for setting the suppress #VE bit Adrian Pop
2017-04-05 13:38 ` [RFC 3/3] libxc: Add support for the altp2m suppress #VE hvmop Adrian Pop

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.