summaryrefslogtreecommitdiff
path: root/xen
diff options
context:
space:
mode:
authorRoger Pau Monne <roger.pau@citrix.com>2021-11-04 11:48:34 +0100
committerIan Jackson <iwj@xenproject.org>2021-11-08 15:10:05 +0000
commit7379f9e10a3b13ec8bcea756384b2ace8af7064d (patch)
treee3a290f2f7c7a6970131006d6402ab702f146ccb /xen
parentb36c23eada769f647e5352d5691f793be06afd62 (diff)
gnttab: allow setting max version per-domain
Introduce a new domain create field so that toolstack can specify the maximum grant table version usable by the domain. This is plumbed into xl and settable by the user as max_grant_version. Previously this was only settable on a per host basis using the gnttab command line option. Note the version is specified using 4 bits, which leaves room to specify up to grant table version 15. Given that we only have 2 grant table versions right now, and a new version is unlikely in the near future using 4 bits seems more than enough. xenstored stubdomains are limited to grant table v1 because the current MiniOS code used to build them only has support for grants v1. There are existing limits set for xenstored stubdomains at creation time that already match the defaults in MiniOS. Signed-off-by: Roger Pau Monné <roger.pau@citrix.com> Acked-by: Christian Lindig <christian.lindig@citrix.com> Reviewed-by: Ian Jackson <iwj@xenproject.org> Reviewed-by: Andrew Cooper <andrew.cooper3@citrix.com> Release-Acked-by: Ian Jackson <iwj@xenproject.org>
Diffstat (limited to 'xen')
-rw-r--r--xen/arch/arm/domain_build.c2
-rw-r--r--xen/arch/x86/setup.c1
-rw-r--r--xen/common/domain.c9
-rw-r--r--xen/common/grant_table.c21
-rw-r--r--xen/include/public/domctl.h5
-rw-r--r--xen/include/xen/grant_table.h8
6 files changed, 41 insertions, 5 deletions
diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c
index 0167731ab0..9e92b640cd 100644
--- a/xen/arch/arm/domain_build.c
+++ b/xen/arch/arm/domain_build.c
@@ -2967,6 +2967,7 @@ void __init create_domUs(void)
.max_evtchn_port = -1,
.max_grant_frames = -1,
.max_maptrack_frames = -1,
+ .grant_opts = opt_gnttab_max_version,
};
if ( !dt_device_is_compatible(node, "xen,domain") )
@@ -3074,6 +3075,7 @@ void __init create_dom0(void)
.max_evtchn_port = -1,
.max_grant_frames = gnttab_dom0_frames(),
.max_maptrack_frames = -1,
+ .grant_opts = opt_gnttab_max_version,
};
/* The vGIC for DOM0 is exactly emulating the hardware GIC */
diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c
index fea86530f9..ec6e686fac 100644
--- a/xen/arch/x86/setup.c
+++ b/xen/arch/x86/setup.c
@@ -755,6 +755,7 @@ static struct domain *__init create_dom0(const module_t *image,
.max_evtchn_port = -1,
.max_grant_frames = -1,
.max_maptrack_frames = -1,
+ .grant_opts = opt_gnttab_max_version,
.max_vcpus = dom0_max_vcpus(),
.arch = {
.misc_flags = opt_dom0_msr_relaxed ? XEN_X86_MSR_RELAXED : 0,
diff --git a/xen/common/domain.c b/xen/common/domain.c
index d71fcab88c..56d47dd664 100644
--- a/xen/common/domain.c
+++ b/xen/common/domain.c
@@ -492,6 +492,12 @@ static int sanitise_domain_config(struct xen_domctl_createdomain *config)
return -EINVAL;
}
+ if ( config->grant_opts & ~XEN_DOMCTL_GRANT_version_mask )
+ {
+ dprintk(XENLOG_INFO, "Unknown grant options %#x\n", config->grant_opts);
+ return -EINVAL;
+ }
+
if ( config->max_vcpus < 1 )
{
dprintk(XENLOG_INFO, "No vCPUS\n");
@@ -678,7 +684,8 @@ struct domain *domain_create(domid_t domid,
init_status |= INIT_evtchn;
if ( (err = grant_table_init(d, config->max_grant_frames,
- config->max_maptrack_frames)) != 0 )
+ config->max_maptrack_frames,
+ config->grant_opts)) != 0 )
goto fail;
init_status |= INIT_gnttab;
diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c
index a20319b22a..8b322b51c0 100644
--- a/xen/common/grant_table.c
+++ b/xen/common/grant_table.c
@@ -53,6 +53,7 @@ struct grant_table {
percpu_rwlock_t lock;
/* Lock protecting the maptrack limit */
spinlock_t maptrack_lock;
+ unsigned int max_version;
/*
* Defaults to v1. May be changed with GNTTABOP_set_version. All other
* values are invalid.
@@ -1917,11 +1918,26 @@ active_alloc_failed:
}
int grant_table_init(struct domain *d, int max_grant_frames,
- int max_maptrack_frames)
+ int max_maptrack_frames, unsigned int options)
{
struct grant_table *gt;
+ unsigned int max_grant_version = options & XEN_DOMCTL_GRANT_version_mask;
int ret = -ENOMEM;
+ if ( !max_grant_version )
+ {
+ dprintk(XENLOG_INFO, "%pd: invalid grant table version 0 requested\n",
+ d);
+ return -EINVAL;
+ }
+ if ( max_grant_version > opt_gnttab_max_version )
+ {
+ dprintk(XENLOG_INFO,
+ "%pd: requested grant version (%u) greater than supported (%u)\n",
+ d, max_grant_version, opt_gnttab_max_version);
+ return -EINVAL;
+ }
+
/* Default to maximum value if no value was specified */
if ( max_grant_frames < 0 )
max_grant_frames = opt_max_grant_frames;
@@ -1947,6 +1963,7 @@ int grant_table_init(struct domain *d, int max_grant_frames,
gt->gt_version = 1;
gt->max_grant_frames = max_grant_frames;
gt->max_maptrack_frames = max_maptrack_frames;
+ gt->max_version = max_grant_version;
/* Install the structure early to simplify the error path. */
gt->domain = d;
@@ -3076,7 +3093,7 @@ gnttab_set_version(XEN_GUEST_HANDLE_PARAM(gnttab_set_version_t) uop)
goto out;
res = -ENOSYS;
- if ( op.version == 2 && opt_gnttab_max_version == 1 )
+ if ( op.version == 2 && gt->max_version == 1 )
goto out; /* Behave as before set_version was introduced. */
res = 0;
diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h
index 51017b47bc..1c21d4dc75 100644
--- a/xen/include/public/domctl.h
+++ b/xen/include/public/domctl.h
@@ -97,6 +97,11 @@ struct xen_domctl_createdomain {
int32_t max_grant_frames;
int32_t max_maptrack_frames;
+/* Grant version, use low 4 bits. */
+#define XEN_DOMCTL_GRANT_version_mask 0xf
+
+ uint32_t grant_opts;
+
/* Per-vCPU buffer size in bytes. 0 to disable. */
uint32_t vmtrace_size;
diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h
index 9ee830cfd0..85fe6b7b5e 100644
--- a/xen/include/xen/grant_table.h
+++ b/xen/include/xen/grant_table.h
@@ -37,7 +37,7 @@ extern unsigned int opt_max_grant_frames;
/* Create/destroy per-domain grant table context. */
int grant_table_init(struct domain *d, int max_grant_frames,
- int max_maptrack_frames);
+ int max_maptrack_frames, unsigned int options);
void grant_table_destroy(
struct domain *d);
void grant_table_init_vcpu(struct vcpu *v);
@@ -69,8 +69,12 @@ int gnttab_acquire_resource(
static inline int grant_table_init(struct domain *d,
int max_grant_frames,
- int max_maptrack_frames)
+ int max_maptrack_frames,
+ unsigned int options)
{
+ if ( options )
+ return -EINVAL;
+
return 0;
}