Add a new per-domain hypfs directory "abi-features" used to control
some feature availability. Changing the availability of a feature is
allowed only before the first activation of the domain.

The related leafs right now are "event-channel-upcall" and
"fifo-event-channels". For those bool elements are added to struct
domain, but for now without any further handling.

Signed-off-by: Juergen Gross <jgr...@suse.com>
---
 xen/common/hypfs_dom.c  | 39 +++++++++++++++++++++++++++++++++++++++
 xen/include/xen/sched.h |  4 ++++
 2 files changed, 43 insertions(+)

diff --git a/xen/common/hypfs_dom.c b/xen/common/hypfs_dom.c
index 241e379b24..b54e246ad6 100644
--- a/xen/common/hypfs_dom.c
+++ b/xen/common/hypfs_dom.c
@@ -10,6 +10,42 @@
 #include <xen/lib.h>
 #include <xen/sched.h>
 
+static int domain_abifeat_write(struct hypfs_entry_leaf *leaf,
+                                XEN_GUEST_HANDLE_PARAM(const_void) uaddr,
+                                unsigned int ulen)
+{
+    struct hypfs_dyndir_id *data;
+    struct domain *d;
+
+    data = hypfs_get_dyndata();
+    d = data->data;
+
+    if ( d->creation_finished )
+        return -EBUSY;
+
+    return hypfs_dyndir_id_write_bool(leaf, uaddr, ulen);
+}
+
+static const struct hypfs_funcs abifeat_funcs = {
+    .enter = hypfs_node_enter,
+    .exit = hypfs_node_exit,
+    .read = hypfs_dyndir_id_read_leaf,
+    .write = domain_abifeat_write,
+    .getsize = hypfs_getsize,
+    .findentry = hypfs_leaf_findentry,
+};
+
+static HYPFS_FIXEDSIZE_INIT(abifeat_evtupcall, XEN_HYPFS_TYPE_BOOL,
+                            "event-channel-upcall",
+                            HYPFS_STRUCT_ELEM(struct domain, abi_evt_upcall),
+                            &abifeat_funcs, 1);
+static HYPFS_FIXEDSIZE_INIT(abifeat_fifoevnt, XEN_HYPFS_TYPE_BOOL,
+                            "fifo-event-channels",
+                            HYPFS_STRUCT_ELEM(struct domain, abi_fifo_evt),
+                            &abifeat_funcs, 1);
+
+static HYPFS_DIR_INIT(domain_abifeatdir, "abi-features");
+
 static const struct hypfs_entry *domain_domdir_enter(
     const struct hypfs_entry *entry)
 {
@@ -131,6 +167,9 @@ static int __init domhypfs_init(void)
 {
     hypfs_add_dir(&hypfs_root, &domain_dir, true);
     hypfs_add_dyndir(&domain_dir, &domain_domdir);
+    hypfs_add_dir(&domain_domdir, &domain_abifeatdir, true);
+    hypfs_add_leaf(&domain_abifeatdir, &abifeat_evtupcall, true);
+    hypfs_add_leaf(&domain_abifeatdir, &abifeat_fifoevnt, true);
 
     return 0;
 }
diff --git a/xen/include/xen/sched.h b/xen/include/xen/sched.h
index 31abbe7a99..fb99249743 100644
--- a/xen/include/xen/sched.h
+++ b/xen/include/xen/sched.h
@@ -424,6 +424,10 @@ struct domain
      */
     bool             creation_finished;
 
+    /* ABI-features (can be set via hypfs before first unpause).*/
+    bool             abi_fifo_evt;
+    bool             abi_evt_upcall;
+
     /* Which guest this guest has privileges on */
     struct domain   *target;
 
-- 
2.26.2


Reply via email to