From: Andrew Cooper <andrew.cooper3@citrix.com>
To: Xen-devel <xen-devel@lists.xenproject.org>
Cc: "Sergey Dyasli" <sergey.dyasli@citrix.com>,
"Wei Liu" <wl@xen.org>,
"Andrew Cooper" <andrew.cooper3@citrix.com>,
"Ian Jackson" <Ian.Jackson@eu.citrix.com>,
"Jan Beulich" <JBeulich@suse.com>,
"Daniel De Graaf" <dgdegra@tycho.nsa.gov>,
"Roger Pau Monné" <roger.pau@citrix.com>
Subject: [Xen-devel] [PATCH v2 05/10] x86/domctl: Implement XEN_DOMCTL_set_cpumsr_policy
Date: Fri, 13 Sep 2019 20:27:54 +0100 [thread overview]
Message-ID: <20190913192759.10795-6-andrew.cooper3@citrix.com> (raw)
In-Reply-To: <20190913192759.10795-1-andrew.cooper3@citrix.com>
This hypercall allows the toolstack to present one combined CPUID and MSR
policy for a domain, which can be audited in one go by Xen, which is necessary
for correctness of the auditing.
Reuse the existing set_cpuid XSM access vector, as this is logically the same
operation.
As x86_cpu_policies_are_compatible() is still only a stub, retain the call to
recalculate_cpuid_policy() to discard unsafe toolstack settings.
Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
Signed-off-by: Sergey Dyasli <sergey.dyasli@citrix.com>
Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
Reviewed-by: Jan Beulich <jbeulich@suse.com>
---
CC: Jan Beulich <JBeulich@suse.com>
CC: Ian Jackson <Ian.Jackson@eu.citrix.com>
CC: Wei Liu <wl@xen.org>
CC: Roger Pau Monné <roger.pau@citrix.com>
CC: Daniel De Graaf <dgdegra@tycho.nsa.gov>
v2:
* Bump the DOMCTL interface version
* Proactively set the error pointers in xc_set_domain_cpu_policy()
* Adjust domctl API documentation to reflect that not all DOMCTL failures
will write the error pointers.
---
tools/libxc/include/xenctrl.h | 5 +++
tools/libxc/xc_cpuid_x86.c | 46 +++++++++++++++++++++
xen/arch/x86/domctl.c | 80 +++++++++++++++++++++++++++++++++++++
xen/include/public/domctl.h | 18 ++++++---
xen/xsm/flask/hooks.c | 1 +
xen/xsm/flask/policy/access_vectors | 1 +
6 files changed, 146 insertions(+), 5 deletions(-)
diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 7559e1bc69..0da437318e 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2530,6 +2530,11 @@ int xc_get_system_cpu_policy(xc_interface *xch, uint32_t index,
int xc_get_domain_cpu_policy(xc_interface *xch, uint32_t domid,
uint32_t *nr_leaves, xen_cpuid_leaf_t *leaves,
uint32_t *nr_msrs, xen_msr_entry_t *msrs);
+int xc_set_domain_cpu_policy(xc_interface *xch, uint32_t domid,
+ uint32_t nr_leaves, xen_cpuid_leaf_t *leaves,
+ uint32_t nr_msrs, xen_msr_entry_t *msrs,
+ uint32_t *err_leaf_p, uint32_t *err_subleaf_p,
+ uint32_t *err_msr_p);
uint32_t xc_get_cpu_featureset_size(void);
diff --git a/tools/libxc/xc_cpuid_x86.c b/tools/libxc/xc_cpuid_x86.c
index b829336082..0f07317b54 100644
--- a/tools/libxc/xc_cpuid_x86.c
+++ b/tools/libxc/xc_cpuid_x86.c
@@ -229,6 +229,52 @@ int xc_get_domain_cpu_policy(xc_interface *xch, uint32_t domid,
return ret;
}
+int xc_set_domain_cpu_policy(xc_interface *xch, uint32_t domid,
+ uint32_t nr_leaves, xen_cpuid_leaf_t *leaves,
+ uint32_t nr_msrs, xen_msr_entry_t *msrs,
+ uint32_t *err_leaf_p, uint32_t *err_subleaf_p,
+ uint32_t *err_msr_p)
+{
+ DECLARE_DOMCTL;
+ DECLARE_HYPERCALL_BOUNCE(leaves,
+ nr_leaves * sizeof(*leaves),
+ XC_HYPERCALL_BUFFER_BOUNCE_IN);
+ DECLARE_HYPERCALL_BOUNCE(msrs,
+ nr_msrs * sizeof(*msrs),
+ XC_HYPERCALL_BUFFER_BOUNCE_IN);
+ int ret;
+
+ if ( xc_hypercall_bounce_pre(xch, leaves) )
+ return -1;
+
+ if ( xc_hypercall_bounce_pre(xch, msrs) )
+ return -1;
+
+ domctl.cmd = XEN_DOMCTL_set_cpu_policy;
+ domctl.domain = domid;
+ domctl.u.cpu_policy.nr_leaves = nr_leaves;
+ set_xen_guest_handle(domctl.u.cpu_policy.cpuid_policy, leaves);
+ domctl.u.cpu_policy.nr_msrs = nr_msrs;
+ set_xen_guest_handle(domctl.u.cpu_policy.msr_policy, msrs);
+ domctl.u.cpu_policy.err_leaf = ~0;
+ domctl.u.cpu_policy.err_subleaf = ~0;
+ domctl.u.cpu_policy.err_msr = ~0;
+
+ ret = do_domctl(xch, &domctl);
+
+ xc_hypercall_bounce_post(xch, leaves);
+ xc_hypercall_bounce_post(xch, msrs);
+
+ if ( err_leaf_p )
+ *err_leaf_p = domctl.u.cpu_policy.err_leaf;
+ if ( err_subleaf_p )
+ *err_subleaf_p = domctl.u.cpu_policy.err_subleaf;
+ if ( err_msr_p )
+ *err_msr_p = domctl.u.cpu_policy.err_msr;
+
+ return ret;
+}
+
struct cpuid_domain_info
{
unsigned int vendor; /* X86_VENDOR_* */
diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c
index 48fccf2f7b..97ced32c21 100644
--- a/xen/arch/x86/domctl.c
+++ b/xen/arch/x86/domctl.c
@@ -294,6 +294,65 @@ static int update_domain_cpuid_info(struct domain *d,
return 0;
}
+static int update_domain_cpu_policy(struct domain *d,
+ xen_domctl_cpu_policy_t *xdpc)
+{
+ struct cpu_policy new = {};
+ const struct cpu_policy *sys = is_pv_domain(d)
+ ? &system_policies[XEN_SYSCTL_cpu_policy_pv_max]
+ : &system_policies[XEN_SYSCTL_cpu_policy_hvm_max];
+ struct cpu_policy_errors err = INIT_CPU_POLICY_ERRORS;
+ int ret = -ENOMEM;
+
+ /* Start by copying the domain's existing policies. */
+ if ( !(new.cpuid = xmemdup(d->arch.cpuid)) ||
+ !(new.msr = xmemdup(d->arch.msr)) )
+ goto out;
+
+ /* Merge the toolstack provided data. */
+ if ( (ret = x86_cpuid_copy_from_buffer(
+ new.cpuid, xdpc->cpuid_policy, xdpc->nr_leaves,
+ &err.leaf, &err.subleaf)) ||
+ (ret = x86_msr_copy_from_buffer(
+ new.msr, xdpc->msr_policy, xdpc->nr_msrs, &err.msr)) )
+ goto out;
+
+ /* Trim any newly-stale out-of-range leaves. */
+ x86_cpuid_policy_clear_out_of_range_leaves(new.cpuid);
+
+ /* Audit the combined dataset. */
+ ret = x86_cpu_policies_are_compatible(sys, &new, &err);
+ if ( ret )
+ goto out;
+
+ /*
+ * Audit was successful. Replace existing policies, leaving the old
+ * policies to be freed.
+ */
+ SWAP(new.cpuid, d->arch.cpuid);
+ SWAP(new.msr, d->arch.msr);
+
+ /* TODO: Drop when x86_cpu_policies_are_compatible() is completed. */
+ recalculate_cpuid_policy(d);
+
+ /* Recalculate relevant dom/vcpu state now the policy has changed. */
+ domain_cpu_policy_changed(d);
+
+ out:
+ /* Free whichever cpuid/msr structs are not installed in struct domain. */
+ xfree(new.cpuid);
+ xfree(new.msr);
+
+ if ( ret )
+ {
+ xdpc->err_leaf = err.leaf;
+ xdpc->err_subleaf = err.subleaf;
+ xdpc->err_msr = err.msr;
+ }
+
+ return ret;
+}
+
static int vcpu_set_vmce(struct vcpu *v,
const struct xen_domctl_ext_vcpucontext *evc)
{
@@ -1476,6 +1535,27 @@ long arch_do_domctl(
copyback = true;
break;
+ case XEN_DOMCTL_set_cpu_policy:
+ if ( d == currd ) /* No domain_pause() */
+ {
+ ret = -EINVAL;
+ break;
+ }
+
+ domain_pause(d);
+
+ if ( d->creation_finished )
+ ret = -EEXIST; /* No changing once the domain is running. */
+ else
+ {
+ ret = update_domain_cpu_policy(d, &domctl->u.cpu_policy);
+ if ( ret ) /* Copy domctl->u.cpu_policy.err_* to guest. */
+ copyback = true;
+ }
+
+ domain_unpause(d);
+ break;
+
default:
ret = iommu_do_domctl(domctl, d, u_domctl);
break;
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 77f546cbb8..bd7d26545d 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -38,7 +38,7 @@
#include "hvm/save.h"
#include "memory.h"
-#define XEN_DOMCTL_INTERFACE_VERSION 0x00000011
+#define XEN_DOMCTL_INTERFACE_VERSION 0x00000012
/*
* NB. xen_domctl.domain is an IN/OUT parameter for this operation.
@@ -658,17 +658,24 @@ struct xen_domctl_cpuid {
};
/*
- * XEN_DOMCTL_get_cpu_policy (x86 specific)
+ * XEN_DOMCTL_{get,set}_cpu_policy (x86 specific)
*
- * Query the CPUID and MSR policies for a specific domain.
+ * Query or set the CPUID and MSR policies for a specific domain.
*/
struct xen_domctl_cpu_policy {
uint32_t nr_leaves; /* IN/OUT: Number of leaves in/written to
* 'cpuid_policy'. */
uint32_t nr_msrs; /* IN/OUT: Number of MSRs in/written to
* 'msr_domain_policy' */
- XEN_GUEST_HANDLE_64(xen_cpuid_leaf_t) cpuid_policy; /* OUT */
- XEN_GUEST_HANDLE_64(xen_msr_entry_t) msr_policy; /* OUT */
+ XEN_GUEST_HANDLE_64(xen_cpuid_leaf_t) cpuid_policy; /* IN/OUT */
+ XEN_GUEST_HANDLE_64(xen_msr_entry_t) msr_policy; /* IN/OUT */
+
+ /*
+ * OUT, set_policy only. Written in some (but not all) error cases to
+ * identify problem the CPUID leaf/subleaf and/or MSR which auditing
+ * objects to.
+ */
+ uint32_t err_leaf, err_subleaf, err_msr;
};
typedef struct xen_domctl_cpu_policy xen_domctl_cpu_policy_t;
DEFINE_XEN_GUEST_HANDLE(xen_domctl_cpu_policy_t);
@@ -1193,6 +1200,7 @@ struct xen_domctl {
/* #define XEN_DOMCTL_set_gnttab_limits 80 - Moved into XEN_DOMCTL_createdomain */
#define XEN_DOMCTL_vuart_op 81
#define XEN_DOMCTL_get_cpu_policy 82
+#define XEN_DOMCTL_set_cpu_policy 83
#define XEN_DOMCTL_gdbsx_guestmemio 1000
#define XEN_DOMCTL_gdbsx_pausevcpu 1001
#define XEN_DOMCTL_gdbsx_unpausevcpu 1002
diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c
index 6800f2d9a0..b23772786a 100644
--- a/xen/xsm/flask/hooks.c
+++ b/xen/xsm/flask/hooks.c
@@ -715,6 +715,7 @@ static int flask_domctl(struct domain *d, int cmd)
case XEN_DOMCTL_set_virq_handler:
return current_has_perm(d, SECCLASS_DOMAIN, DOMAIN__SET_VIRQ_HANDLER);
+ case XEN_DOMCTL_set_cpu_policy:
case XEN_DOMCTL_set_cpuid:
return current_has_perm(d, SECCLASS_DOMAIN2, DOMAIN2__SET_CPUID);
diff --git a/xen/xsm/flask/policy/access_vectors b/xen/xsm/flask/policy/access_vectors
index 76f3d60ddd..6f3f9493f8 100644
--- a/xen/xsm/flask/policy/access_vectors
+++ b/xen/xsm/flask/policy/access_vectors
@@ -207,6 +207,7 @@ class domain2
# source = the domain making the hypercall
# target = the new target domain
set_as_target
+# XEN_DOMCTL_set_cpu_policy
# XEN_DOMCTL_set_cpuid
set_cpuid
# XEN_DOMCTL_gettscinfo
--
2.11.0
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xenproject.org
https://lists.xenproject.org/mailman/listinfo/xen-devel
next prev parent reply other threads:[~2019-09-13 19:29 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-09-13 19:27 [Xen-devel] [PATCH v2 00/10] x86/cpuid: Switch to using XEN_DOMCTL_set_cpumsr_policy Andrew Cooper
2019-09-13 19:27 ` [Xen-devel] [PATCH v2 01/10] x86/msr: Offer CPUID Faulting to PVH control domains Andrew Cooper
2019-09-16 10:53 ` Jan Beulich
2019-09-13 19:27 ` [Xen-devel] [PATCH v2 02/10] libx86: Proactively initialise error pointers Andrew Cooper
[not found] ` <527f33ad-3de1-15c7-eb4b-603eaf65f3c5@suse.com>
[not found] ` <65f18521-15c5-72a9-29f6-cd5d621e1283@citrix.com>
2019-09-16 15:46 ` Jan Beulich
2019-09-13 19:27 ` [Xen-devel] [PATCH v2 03/10] libx86: Introduce x86_cpu_policies_are_compatible() Andrew Cooper
2019-09-16 10:59 ` Jan Beulich
2019-09-16 15:31 ` Andrew Cooper
2019-09-13 19:27 ` [Xen-devel] [PATCH v2 04/10] x86/cpuid: Split update_domain_cpuid_info() in half Andrew Cooper
2019-09-13 19:27 ` Andrew Cooper [this message]
2019-09-16 11:04 ` [Xen-devel] [PATCH v2 05/10] x86/domctl: Implement XEN_DOMCTL_set_cpumsr_policy Jan Beulich
2019-09-16 15:40 ` Andrew Cooper
2019-09-13 19:27 ` [Xen-devel] [PATCH v2 06/10] tools/libxc: Pre-cleanup for xc_cpuid_{set, apply_policy}() Andrew Cooper
2019-09-16 11:09 ` Jan Beulich
2019-09-16 15:42 ` Andrew Cooper
2019-09-13 19:27 ` [Xen-devel] [PATCH v2 07/10] tools/libxc: Rework xc_cpuid_set() to use {get, set}_cpu_policy() Andrew Cooper
2019-09-13 19:27 ` [Xen-devel] [PATCH v2 08/10] tools/libxc: Rework xc_cpuid_apply_policy() " Andrew Cooper
2019-09-16 11:17 ` Jan Beulich
2019-09-16 13:41 ` Wei Liu
2019-09-16 15:49 ` Andrew Cooper
2019-09-16 16:05 ` Jan Beulich
2019-09-18 16:09 ` Jan Beulich
2019-09-19 8:48 ` Andrew Cooper
2019-09-25 18:11 ` [Xen-devel] [PATCH v3 " Andrew Cooper
2019-09-26 8:04 ` Jan Beulich
2019-09-26 12:25 ` Andrew Cooper
2019-09-13 19:27 ` [Xen-devel] [PATCH v2 09/10] x86/domctl: Drop XEN_DOMCTL_set_cpuid Andrew Cooper
2019-09-13 19:27 ` [Xen-devel] [PATCH v2 10/10] x86/cpuid: Enable CPUID Faulting for PV control domains by default Andrew Cooper
2019-09-16 11:22 ` Jan Beulich
2019-09-16 15:52 ` Andrew Cooper
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=20190913192759.10795-6-andrew.cooper3@citrix.com \
--to=andrew.cooper3@citrix.com \
--cc=Ian.Jackson@eu.citrix.com \
--cc=JBeulich@suse.com \
--cc=dgdegra@tycho.nsa.gov \
--cc=roger.pau@citrix.com \
--cc=sergey.dyasli@citrix.com \
--cc=wl@xen.org \
--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).