From: Vasilis Liaskovitis <vliaskovitis@suse.com>
To: xen-devel@lists.xenproject.org
Cc: jgross@suse.com, sstabellini@kernel.org, wei.liu2@citrix.com,
jbeulich@suse.com, George.Dunlap@eu.citrix.com,
andrew.cooper3@citrix.com, ian.jackson@eu.citrix.com,
tim@xen.org, vliaskovitis@suse.com, dgdegra@tycho.nsa.gov
Subject: [PATCH v2 1/4] xen: add hypercall for getting parameters at runtime
Date: Fri, 22 Mar 2019 20:28:06 +0100 [thread overview]
Message-ID: <20190322192809.3002-2-vliaskovitis@suse.com> (raw)
In-Reply-To: <20190322192809.3002-1-vliaskovitis@suse.com>
Add a sysctl hypercall to support getting hypervisor parameters
at runtime.
Limitations:
- Custom runtime parameters (OPT_CUSTOM) are not supported yet.
- For integer parameters (OPT_UINT), only unsigned parameters are printed
correctly.
Signed-off-by: Vasilis Liaskovitis <vliaskovitis@suse.com>
---
tools/flask/policy/modules/dom0.te | 2 +-
xen/common/kernel.c | 110 ++++++++++++++++++++++++++++
xen/common/sysctl.c | 55 +++++++++++++-
xen/include/public/sysctl.h | 18 +++++
xen/include/xen/lib.h | 1 +
xen/xsm/flask/hooks.c | 3 +
xen/xsm/flask/policy/access_vectors | 2 +
7 files changed, 188 insertions(+), 3 deletions(-)
diff --git a/tools/flask/policy/modules/dom0.te b/tools/flask/policy/modules/dom0.te
index a347d664f8..681d1a101b 100644
--- a/tools/flask/policy/modules/dom0.te
+++ b/tools/flask/policy/modules/dom0.te
@@ -16,7 +16,7 @@ allow dom0_t xen_t:xen {
allow dom0_t xen_t:xen2 {
resource_op psr_cmt_op psr_alloc pmu_ctrl get_symbol
get_cpu_levelling_caps get_cpu_featureset livepatch_op
- coverage_op set_parameter
+ coverage_op set_parameter get_parameter
};
# Allow dom0 to use all XENVER_ subops that have checks.
diff --git a/xen/common/kernel.c b/xen/common/kernel.c
index 612575430f..2d12a5bcf6 100644
--- a/xen/common/kernel.c
+++ b/xen/common/kernel.c
@@ -12,6 +12,7 @@
#include <xen/paging.h>
#include <xen/guest_access.h>
#include <xen/hypercall.h>
+#include <xen/ctype.h>
#include <xsm/xsm.h>
#include <asm/current.h>
#include <public/version.h>
@@ -52,6 +53,115 @@ static int assign_integer_param(const struct kernel_param *param, uint64_t val)
return 0;
}
+static int get_integer_param(const struct kernel_param *param, uint64_t *val)
+{
+ switch ( param->len )
+ {
+ case sizeof(uint8_t):
+ *val = *(uint8_t *)param->par.var;
+ break;
+ case sizeof(uint16_t):
+ *val = *(uint16_t *)param->par.var;
+ break;
+ case sizeof(uint32_t):
+ *val = *(uint32_t *)param->par.var;
+ break;
+ case sizeof(uint64_t):
+ *val = *(uint64_t *)param->par.var;
+ break;
+ default:
+ BUG();
+ }
+
+ return 0;
+}
+
+int runtime_get_params(const char *cmdline, char *values,
+ size_t maxlen)
+{
+ char opt[128], *optkey, *q, *val = values;
+ const char *p = cmdline;
+ const struct kernel_param *param;
+ int rc = 0, len = 0;
+ size_t bufpos = 0;
+ uint64_t param_int;
+
+ if (!values)
+ return -EFAULT;
+
+ for ( ; ; )
+ {
+ /* Skip whitespace. */
+ while ( isspace(*p) )
+ p++;
+ if ( *p == '\0' )
+ break;
+
+ /* Grab the next whitespace-delimited option. */
+ q = optkey = opt;
+ while ( (*p != ' ') && (*p != '\0') )
+ {
+ if ( (q - opt) < (sizeof(opt)-1) ) /* avoid overflow */
+ *q++ = *p;
+ p++;
+ }
+ *q = '\0';
+
+ for ( param = __param_start; param < __param_end; param++ )
+ {
+ if ( strcmp(param->name, optkey) )
+ continue;
+
+ switch ( param->type )
+ {
+ case OPT_STR:
+ len = snprintf(val + bufpos, maxlen - bufpos, "%s ",
+ (char*)param->par.var);
+ break;
+ case OPT_UINT:
+ case OPT_SIZE:
+ get_integer_param(param, ¶m_int);
+ len = snprintf(val + bufpos, maxlen - bufpos,
+ "%"PRIu64" ", param_int);
+ break;
+ case OPT_BOOL:
+ get_integer_param(param, ¶m_int);
+ len = snprintf(val + bufpos, maxlen - bufpos, "%s ",
+ param_int ? "true" : "false");
+ break;
+ case OPT_CUSTOM:
+ /* Custom parameters are not supported yet. */
+ rc = -EINVAL;
+ break;
+ default:
+ BUG();
+ break;
+ }
+
+ if (len < 0)
+ rc = len;
+ else if (len < maxlen - bufpos)
+ /* if output was not truncated update buffer position */
+ bufpos += (size_t) len;
+ else if (len > 0)
+ rc = -ENOMEM;
+
+ break;
+ }
+
+ /* no parameter was matched */
+ if ( param >= __param_end )
+ {
+ rc = -EINVAL;
+ }
+
+ if (rc)
+ break;
+ }
+
+ return rc;
+}
+
static int parse_params(const char *cmdline, const struct kernel_param *start,
const struct kernel_param *end)
{
diff --git a/xen/common/sysctl.c b/xen/common/sysctl.c
index c0aa6bde4e..1b65bd617e 100644
--- a/xen/common/sysctl.c
+++ b/xen/common/sysctl.c
@@ -466,9 +466,9 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
copyback = 1;
break;
+#define XEN_PARAMETER_MAX_SIZE 1023
case XEN_SYSCTL_set_parameter:
{
-#define XEN_SET_PARAMETER_MAX_SIZE 1023
char *params;
if ( op->u.set_parameter.pad[0] || op->u.set_parameter.pad[1] ||
@@ -477,7 +477,7 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
ret = -EINVAL;
break;
}
- if ( op->u.set_parameter.size > XEN_SET_PARAMETER_MAX_SIZE )
+ if ( op->u.set_parameter.size > XEN_PARAMETER_MAX_SIZE )
{
ret = -E2BIG;
break;
@@ -501,6 +501,57 @@ long do_sysctl(XEN_GUEST_HANDLE_PARAM(xen_sysctl_t) u_sysctl)
break;
}
+ case XEN_SYSCTL_get_parameter:
+ {
+ char *params;
+ char *values;
+
+ if ( op->u.get_parameter.pad[0] || op->u.get_parameter.pad[1] ||
+ op->u.get_parameter.pad[2] )
+ {
+ ret = -EINVAL;
+ break;
+ }
+ if ( op->u.get_parameter.size > XEN_PARAMETER_MAX_SIZE )
+ {
+ ret = -E2BIG;
+ break;
+ }
+ params = xmalloc_bytes(op->u.get_parameter.size + 1);
+ if ( !params )
+ {
+ ret = -ENOMEM;
+ break;
+ }
+
+ values = xmalloc_bytes(XEN_PARAMETER_MAX_SIZE);
+ if ( !values )
+ {
+ xfree(params);
+ ret = -ENOMEM;
+ break;
+ }
+
+ else if ( copy_from_guest(params, op->u.get_parameter.params,
+ op->u.get_parameter.size) )
+ ret = -EFAULT;
+ else
+ {
+ params[op->u.set_parameter.size] = 0;
+ ret = runtime_get_params(params, values, XEN_PARAMETER_MAX_SIZE);
+
+ if ( !ret && copy_to_guest(op->u.get_parameter.values, values,
+ strlen(values)) )
+ {
+ ret = -EFAULT;
+ }
+ }
+
+ xfree(params);
+ xfree(values);
+
+ break;
+ }
default:
ret = arch_do_sysctl(op, u_sysctl);
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index c49b4dcc99..7d77d57115 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -1100,6 +1100,22 @@ typedef struct xen_sysctl_cpu_policy xen_sysctl_cpu_policy_t;
DEFINE_XEN_GUEST_HANDLE(xen_sysctl_cpu_policy_t);
#endif
+/*
+ * XEN_SYSCTL_get_parameter
+ *
+ * Read hypervisor parameters at runtime.
+ * Parameters are a single string terminated by a NUL byte of max. size
+ * characters. Multiple settings can be specified by separating them
+ * with blanks.
+ */
+
+struct xen_sysctl_get_parameter {
+ XEN_GUEST_HANDLE_64(char) params; /* IN: pointer to parameters. */
+ XEN_GUEST_HANDLE_64(char) values; /* OUT: pointer to output values. */
+ uint16_t size; /* IN: size of parameters. */
+ uint16_t pad[3]; /* IN: MUST be zero. */
+};
+
struct xen_sysctl {
uint32_t cmd;
#define XEN_SYSCTL_readconsole 1
@@ -1130,6 +1146,7 @@ struct xen_sysctl {
#define XEN_SYSCTL_livepatch_op 27
#define XEN_SYSCTL_set_parameter 28
#define XEN_SYSCTL_get_cpu_policy 29
+#define XEN_SYSCTL_get_parameter 30
uint32_t interface_version; /* XEN_SYSCTL_INTERFACE_VERSION */
union {
struct xen_sysctl_readconsole readconsole;
@@ -1162,6 +1179,7 @@ struct xen_sysctl {
#if defined(__i386__) || defined(__x86_64__)
struct xen_sysctl_cpu_policy cpu_policy;
#endif
+ struct xen_sysctl_get_parameter get_parameter;
uint8_t pad[128];
} u;
};
diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h
index 89939f43c8..96440a6041 100644
--- a/xen/include/xen/lib.h
+++ b/xen/include/xen/lib.h
@@ -71,6 +71,7 @@ struct domain;
void cmdline_parse(const char *cmdline);
int runtime_parse(const char *line);
int parse_bool(const char *s, const char *e);
+int runtime_get_params(const char *cmdline, char *values, size_t maxlen);
/**
* Given a specific name, parses a string of the form:
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 3d00c747f6..1b832e9a4c 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -830,6 +830,9 @@ static int flask_sysctl(int cmd)
case XEN_SYSCTL_set_parameter:
return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN2,
XEN2__SET_PARAMETER, NULL);
+ case XEN_SYSCTL_get_parameter:
+ return avc_current_has_perm(SECINITSID_XEN, SECCLASS_XEN2,
+ XEN2__GET_PARAMETER, NULL);
default:
return avc_unknown_permission("sysctl", cmd);
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index e00448b776..c5ee21d852 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -103,6 +103,8 @@ class xen2
coverage_op
# XEN_SYSCTL_set_parameter
set_parameter
+# XEN_SYSCTL_get_parameter
+ get_parameter
}
# Classes domain and domain2 consist of operations that a domain performs on
--
2.20.1
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2019-03-22 19:28 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-22 19:28 [PATCH v2 0/4] Support for reading hypervisor parameters at runtime Vasilis Liaskovitis
2019-03-22 19:28 ` Vasilis Liaskovitis [this message]
2019-04-05 15:01 ` [PATCH v2 1/4] xen: add hypercall for getting " Jan Beulich
2019-04-05 15:01 ` [Xen-devel] " Jan Beulich
[not found] ` <5CA76DE50200007800224E9C@suse.com>
2019-04-30 19:05 ` Vasilis Liaskovitis
2019-04-30 19:05 ` [Xen-devel] " Vasilis Liaskovitis
2019-05-02 7:36 ` Jan Beulich
2019-05-02 7:36 ` [Xen-devel] " Jan Beulich
2019-03-22 19:28 ` [PATCH v2 2/4] libxc: add function to get hypervisor parameters Vasilis Liaskovitis
2019-03-22 19:28 ` [PATCH v2 3/4] libxl: add libxl_get_parameters() function Vasilis Liaskovitis
2019-03-22 19:28 ` [PATCH v2 4/4] xl: add new xl command get-parameters Vasilis Liaskovitis
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20190322192809.3002-2-vliaskovitis@suse.com \
--to=vliaskovitis@suse.com \
--cc=George.Dunlap@eu.citrix.com \
--cc=andrew.cooper3@citrix.com \
--cc=dgdegra@tycho.nsa.gov \
--cc=ian.jackson@eu.citrix.com \
--cc=jbeulich@suse.com \
--cc=jgross@suse.com \
--cc=sstabellini@kernel.org \
--cc=tim@xen.org \
--cc=wei.liu2@citrix.com \
--cc=xen-devel@lists.xenproject.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).