diff mbox series

[RFC,9/9] x86/nested, xsm: add nested_schedop_shutdown hypercall

Message ID 20190620003053.21993-10-christopher.w.clark@gmail.com (mailing list archive)
State New, archived
Headers show
Series The Xen Blanket: hypervisor interface for PV drivers on nested Xen | expand

Commit Message

Christopher Clark June 20, 2019, 12:30 a.m. UTC
Provides proxying to the host hypervisor for SCHEDOP_shutdown op.

Signed-off-by: Christopher Clark <christopher.clark@starlab.io>
---
 tools/flask/policy/modules/dom0.te  |  1 +
 xen/arch/x86/guest/hypercall_page.S |  1 +
 xen/arch/x86/guest/xen-nested.c     | 25 +++++++++++++++++++++++++
 xen/arch/x86/hypercall.c            |  1 +
 xen/arch/x86/pv/hypercall.c         |  1 +
 xen/include/public/xen.h            |  1 +
 xen/include/xen/hypercall.h         |  4 ++++
 xen/include/xsm/dummy.h             |  7 +++++++
 xen/include/xsm/xsm.h               |  7 +++++++
 xen/xsm/dummy.c                     |  1 +
 xen/xsm/flask/hooks.c               |  6 ++++++
 11 files changed, 55 insertions(+)
diff mbox series

Patch

diff --git a/tools/flask/policy/modules/dom0.te b/tools/flask/policy/modules/dom0.te
index ba3c5ad63d..23911aef4d 100644
--- a/tools/flask/policy/modules/dom0.te
+++ b/tools/flask/policy/modules/dom0.te
@@ -51,6 +51,7 @@  allow dom0_t nestedxen_t:grant query;
 allow dom0_t nestedxen_t:nested_event {
     alloc_unbound bind_vcpu close send unmask
 };
+allow dom0_t nestedxen_t:domain { shutdown };
 
 # These permissions allow using the FLASK security server to compute access
 # checks locally, which could be used by a domain or service (such as xenstore)
diff --git a/xen/arch/x86/guest/hypercall_page.S b/xen/arch/x86/guest/hypercall_page.S
index 64f1885629..28a631e850 100644
--- a/xen/arch/x86/guest/hypercall_page.S
+++ b/xen/arch/x86/guest/hypercall_page.S
@@ -65,6 +65,7 @@  DECLARE_HYPERCALL(nested_memory_op)
 DECLARE_HYPERCALL(nested_hvm_op)
 DECLARE_HYPERCALL(nested_grant_table_op)
 DECLARE_HYPERCALL(nested_event_channel_op)
+DECLARE_HYPERCALL(nested_sched_op)
 
 DECLARE_HYPERCALL(arch_0)
 DECLARE_HYPERCALL(arch_1)
diff --git a/xen/arch/x86/guest/xen-nested.c b/xen/arch/x86/guest/xen-nested.c
index babf4bf783..4f33d5d9be 100644
--- a/xen/arch/x86/guest/xen-nested.c
+++ b/xen/arch/x86/guest/xen-nested.c
@@ -26,6 +26,7 @@ 
 #include <public/grant_table.h>
 #include <public/hvm/hvm_op.h>
 #include <public/memory.h>
+#include <public/sched.h>
 #include <public/version.h>
 #include <public/xen.h>
 
@@ -323,3 +324,27 @@  long do_nested_event_channel_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
 
     return ret;
 }
+
+long do_nested_sched_op(int cmd, XEN_GUEST_HANDLE_PARAM(void) arg)
+{
+    struct sched_shutdown sched_shutdown;
+    long ret;
+
+    if ( !xen_nested )
+        return -ENOSYS;
+
+    if ( cmd != SCHEDOP_shutdown )
+    {
+        gprintk(XENLOG_ERR, "Nested: sched op %d not supported.\n", cmd);
+        return -EOPNOTSUPP;
+    }
+
+    ret = xsm_nested_schedop_shutdown(XSM_PRIV, current->domain);
+    if ( ret )
+        return ret;
+
+    if ( copy_from_guest(&sched_shutdown, arg, 1) )
+        return -EFAULT;
+
+    return xen_hypercall_sched_op(cmd, &sched_shutdown);
+}
diff --git a/xen/arch/x86/hypercall.c b/xen/arch/x86/hypercall.c
index 752955ac81..8bf1d74f14 100644
--- a/xen/arch/x86/hypercall.c
+++ b/xen/arch/x86/hypercall.c
@@ -79,6 +79,7 @@  const hypercall_args_t hypercall_args_table[NR_hypercalls] =
     ARGS(nested_hvm_op, 2),
     ARGS(nested_grant_table_op, 3),
     ARGS(nested_event_channel_op, 2),
+    ARGS(nested_sched_op, 2),
 #endif
     ARGS(mca, 1),
     ARGS(arch_1, 1),
diff --git a/xen/arch/x86/pv/hypercall.c b/xen/arch/x86/pv/hypercall.c
index 6b1ae74d64..4874e701e0 100644
--- a/xen/arch/x86/pv/hypercall.c
+++ b/xen/arch/x86/pv/hypercall.c
@@ -90,6 +90,7 @@  const hypercall_table_t pv_hypercall_table[] = {
     HYPERCALL(nested_hvm_op),
     HYPERCALL(nested_grant_table_op),
     HYPERCALL(nested_event_channel_op),
+    HYPERCALL(nested_sched_op),
 #endif
     HYPERCALL(mca),
     HYPERCALL(arch_1),
diff --git a/xen/include/public/xen.h b/xen/include/public/xen.h
index 5fb322e882..62a23310e7 100644
--- a/xen/include/public/xen.h
+++ b/xen/include/public/xen.h
@@ -126,6 +126,7 @@  DEFINE_XEN_GUEST_HANDLE(xen_ulong_t);
 #define __HYPERVISOR_nested_hvm_op        44
 #define __HYPERVISOR_nested_grant_table_op 45
 #define __HYPERVISOR_nested_event_channel_op 46
+#define __HYPERVISOR_nested_sched_op      47
 
 /* Architecture-specific hypercall definitions. */
 #define __HYPERVISOR_arch_0               48
diff --git a/xen/include/xen/hypercall.h b/xen/include/xen/hypercall.h
index bd739c2dc7..96d6ba2cd2 100644
--- a/xen/include/xen/hypercall.h
+++ b/xen/include/xen/hypercall.h
@@ -171,6 +171,10 @@  extern long do_nested_grant_table_op(
 extern long do_nested_event_channel_op(
     int cmd,
     XEN_GUEST_HANDLE_PARAM(void) arg);
+
+extern long do_nested_sched_op(
+    int cmd,
+    XEN_GUEST_HANDLE_PARAM(void) arg);
 #endif
 
 #ifdef CONFIG_COMPAT
diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h
index f8162f3308..200f097d50 100644
--- a/xen/include/xsm/dummy.h
+++ b/xen/include/xsm/dummy.h
@@ -776,6 +776,13 @@  static XSM_INLINE int xsm_nested_event_channel_op(XSM_DEFAULT_ARG
     XSM_ASSERT_ACTION(XSM_PRIV);
     return xsm_default_action(action, d, NULL);
 }
+
+static XSM_INLINE int xsm_nested_schedop_shutdown(XSM_DEFAULT_ARG
+                                                  const struct domain *d)
+{
+    XSM_ASSERT_ACTION(XSM_PRIV);
+    return xsm_default_action(action, d, NULL);
+}
 #endif
 
 #include <public/version.h>
diff --git a/xen/include/xsm/xsm.h b/xen/include/xsm/xsm.h
index 81cb67b89b..1cb70d427b 100644
--- a/xen/include/xsm/xsm.h
+++ b/xen/include/xsm/xsm.h
@@ -193,6 +193,7 @@  struct xsm_operations {
     int (*nested_hvm_op) (const struct domain *d, unsigned int cmd);
     int (*nested_grant_query_size) (const struct domain *d);
     int (*nested_event_channel_op) (const struct domain *d, unsigned int cmd);
+    int (*nested_schedop_shutdown) (const struct domain *d);
 #endif
 };
 
@@ -763,6 +764,12 @@  static inline int xsm_nested_event_channel_op(xsm_default_t def,
     return xsm_ops->nested_event_channel_op(d, cmd);
 }
 
+static inline int xsm_nested_schedop_shutdown(xsm_default_t def,
+                                              const struct domain *d)
+{
+    return xsm_ops->nested_schedop_shutdown(d);
+}
+
 #endif /* CONFIG_XEN_NESTED */
 
 #endif /* XSM_NO_WRAPPERS */
diff --git a/xen/xsm/dummy.c b/xen/xsm/dummy.c
index 91db264ddc..ac6e5fdd49 100644
--- a/xen/xsm/dummy.c
+++ b/xen/xsm/dummy.c
@@ -163,5 +163,6 @@  void __init xsm_fixup_ops (struct xsm_operations *ops)
     set_to_dummy_if_null(ops, nested_hvm_op);
     set_to_dummy_if_null(ops, nested_grant_query_size);
     set_to_dummy_if_null(ops, nested_event_channel_op);
+    set_to_dummy_if_null(ops, nested_schedop_shutdown);
 #endif
 }
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 27bfa01559..385ae1458c 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -1828,6 +1828,11 @@  static int flask_nested_event_channel_op(const struct domain *d,
     return domain_has_nested_perm(d, SECCLASS_NESTED_EVENT, perm);
 }
 
+static int flask_nested_schedop_shutdown(const struct domain *d)
+{
+    return domain_has_nested_perm(d, SECCLASS_DOMAIN, DOMAIN__SHUTDOWN);
+}
+
 #endif
 
 long do_flask_op(XEN_GUEST_HANDLE_PARAM(xsm_op_t) u_flask_op);
@@ -1975,6 +1980,7 @@  static struct xsm_operations flask_ops = {
     .nested_hvm_op = flask_nested_hvm_op,
     .nested_grant_query_size = flask_nested_grant_query_size,
     .nested_event_channel_op = flask_nested_event_channel_op,
+    .nested_schedop_shutdown = flask_nested_schedop_shutdown,
 #endif
 };