Skip to content

Commit

Permalink
gnttab: allow setting max version per-domain
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
royger authored and ijackson-citrix committed Nov 8, 2021
1 parent b36c23e commit 7379f9e
Show file tree
Hide file tree
Showing 19 changed files with 110 additions and 6 deletions.
5 changes: 5 additions & 0 deletions docs/man/xl.cfg.5.pod.in
Original file line number Diff line number Diff line change
Expand Up @@ -580,6 +580,11 @@ to have. This value controls how many pages of foreign domains can be accessed
via the grant mechanism by this domain. The default value is settable via
L<xl.conf(5)>.

=item B<max_grant_version=NUMBER>

Specify the maximum grant table version the domain is allowed to use. The
default value is settable via L<xl.conf(5)>.

=item B<nomigrate=BOOLEAN>

Disable migration of this domain. This enables certain other features
Expand Down
6 changes: 6 additions & 0 deletions docs/man/xl.conf.5.pod.in
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ Sets the default value for the C<max_maptrack_frames> domain config value.
Default: value of Xen command line B<gnttab_max_maptrack_frames>
parameter (or its default value if unspecified).

=item B<max_grant_version=NUMBER>

Sets the default value for the C<max_grant_version> domain config value.

Default: maximum grant version supported by the hypervisor.

=item B<vif.default.script="PATH">

Configures the default hotplug script used by virtual network devices.
Expand Down
2 changes: 2 additions & 0 deletions tools/helpers/init-xenstore-domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,11 @@ static int build(xc_interface *xch)
* 1 grant frame is enough: we don't need many grants.
* Mini-OS doesn't like less than 4, though, so use 4.
* 128 maptrack frames: 256 entries per frame, enough for 32768 domains.
* Currently Mini-OS only supports grant v1.
*/
.max_grant_frames = 4,
.max_maptrack_frames = 128,
.grant_opts = 1,
};

xs_fd = open("/dev/xen/xenbus_backend", O_RDWR);
Expand Down
7 changes: 7 additions & 0 deletions tools/include/libxl.h
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,13 @@
*/
#define LIBXL_HAVE_PHYSINFO_CAP_GNTTAB 1

/*
* LIBXL_HAVE_MAX_GRANT_VERSION indicates libxl_domain_build_info has a
* max_grant_version field for setting the max grant table version per
* domain.
*/
#define LIBXL_HAVE_MAX_GRANT_VERSION 1

/*
* libxl ABI compatibility
*
Expand Down
23 changes: 23 additions & 0 deletions tools/libs/light/libxl_create.c
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,28 @@ int libxl__domain_build_info_setdefault(libxl__gc *gc,
libxl_defbool_setdefault(&b_info->nested_hvm, false);
}

if (b_info->max_grant_version == LIBXL_MAX_GRANT_DEFAULT) {
libxl_physinfo info;

rc = libxl_get_physinfo(CTX, &info);
if (rc) {
LOG(ERROR, "failed to get hypervisor info");
return rc;
}

if (info.cap_gnttab_v2)
b_info->max_grant_version = 2;
else if (info.cap_gnttab_v1)
b_info->max_grant_version = 1;
else
/* No grant table support reported */
b_info->max_grant_version = 0;
} else if (b_info->max_grant_version & ~XEN_DOMCTL_GRANT_version_mask) {
LOG(ERROR, "max grant version %d out of range",
b_info->max_grant_version);
return -ERROR_INVAL;
}

return 0;
}

Expand Down Expand Up @@ -607,6 +629,7 @@ int libxl__domain_make(libxl__gc *gc, libxl_domain_config *d_config,
.max_evtchn_port = b_info->event_channels,
.max_grant_frames = b_info->max_grant_frames,
.max_maptrack_frames = b_info->max_maptrack_frames,
.grant_opts = b_info->max_grant_version,
.vmtrace_size = ROUNDUP(b_info->vmtrace_buf_kb << 10, XC_PAGE_SHIFT),
};

Expand Down
1 change: 1 addition & 0 deletions tools/libs/light/libxl_dm.c
Original file line number Diff line number Diff line change
Expand Up @@ -2320,6 +2320,7 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss)

dm_config->b_info.max_grant_frames = guest_config->b_info.max_grant_frames;
dm_config->b_info.max_maptrack_frames = guest_config->b_info.max_maptrack_frames;
dm_config->b_info.max_grant_version = guest_config->b_info.max_grant_version;

dm_config->b_info.u.pv.features = "";

Expand Down
1 change: 1 addition & 0 deletions tools/libs/light/libxl_types.idl
Original file line number Diff line number Diff line change
Expand Up @@ -519,6 +519,7 @@ libxl_domain_build_info = Struct("domain_build_info",[

("max_grant_frames", uint32, {'init_val': 'LIBXL_MAX_GRANT_DEFAULT'}),
("max_maptrack_frames", uint32, {'init_val': 'LIBXL_MAX_GRANT_DEFAULT'}),
("max_grant_version", integer, {'init_val': 'LIBXL_MAX_GRANT_DEFAULT'}),

("device_model_version", libxl_device_model_version),
("device_model_stubdomain", libxl_defbool),
Expand Down
1 change: 1 addition & 0 deletions tools/ocaml/libs/xc/xenctrl.ml
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ type domctl_create_config =
max_evtchn_port: int;
max_grant_frames: int;
max_maptrack_frames: int;
max_grant_version: int;
arch: arch_domainconfig;
}

Expand Down
1 change: 1 addition & 0 deletions tools/ocaml/libs/xc/xenctrl.mli
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ type domctl_create_config = {
max_evtchn_port: int;
max_grant_frames: int;
max_maptrack_frames: int;
max_grant_version: int;
arch: arch_domainconfig;
}

Expand Down
5 changes: 4 additions & 1 deletion tools/ocaml/libs/xc/xenctrl_stubs.c
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,8 @@ CAMLprim value stub_xc_domain_create(value xch, value wanted_domid, value config
#define VAL_MAX_EVTCHN_PORT Field(config, 5)
#define VAL_MAX_GRANT_FRAMES Field(config, 6)
#define VAL_MAX_MAPTRACK_FRAMES Field(config, 7)
#define VAL_ARCH Field(config, 8)
#define VAL_MAX_GRANT_VERSION Field(config, 8)
#define VAL_ARCH Field(config, 9)

uint32_t domid = Int_val(wanted_domid);
int result;
Expand All @@ -198,6 +199,7 @@ CAMLprim value stub_xc_domain_create(value xch, value wanted_domid, value config
.max_evtchn_port = Int_val(VAL_MAX_EVTCHN_PORT),
.max_grant_frames = Int_val(VAL_MAX_GRANT_FRAMES),
.max_maptrack_frames = Int_val(VAL_MAX_MAPTRACK_FRAMES),
.grant_opts = Int_val(VAL_MAX_GRANT_VERSION),
};

domain_handle_of_uuid_string(cfg.handle, String_val(VAL_HANDLE));
Expand Down Expand Up @@ -251,6 +253,7 @@ CAMLprim value stub_xc_domain_create(value xch, value wanted_domid, value config
}

#undef VAL_ARCH
#undef VAL_MAX_GRANT_VERSION
#undef VAL_MAX_MAPTRACK_FRAMES
#undef VAL_MAX_GRANT_FRAMES
#undef VAL_MAX_EVTCHN_PORT
Expand Down
8 changes: 8 additions & 0 deletions tools/xl/xl.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ bool progress_use_cr = 0;
bool timestamps = 0;
int max_grant_frames = -1;
int max_maptrack_frames = -1;
int max_grant_version = LIBXL_MAX_GRANT_DEFAULT;
libxl_domid domid_policy = INVALID_DOMID;

xentoollog_level minmsglevel = minmsglevel_default;
Expand Down Expand Up @@ -219,6 +220,13 @@ static void parse_global_config(const char *configfile,
else if (e != ESRCH)
exit(1);

e = xlu_cfg_get_bounded_long (config, "max_grant_version", 0,
INT_MAX, &l, 1);
if (!e)
max_grant_version = l;
else if (e != ESRCH)
exit(1);

libxl_cpu_bitmap_alloc(ctx, &global_vm_affinity_mask, 0);
libxl_cpu_bitmap_alloc(ctx, &global_hvm_affinity_mask, 0);
libxl_cpu_bitmap_alloc(ctx, &global_pv_affinity_mask, 0);
Expand Down
1 change: 1 addition & 0 deletions tools/xl/xl.h
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ extern char *default_colo_proxy_script;
extern char *blkdev_start;
extern int max_grant_frames;
extern int max_maptrack_frames;
extern int max_grant_version;
extern libxl_bitmap global_vm_affinity_mask;
extern libxl_bitmap global_hvm_affinity_mask;
extern libxl_bitmap global_pv_affinity_mask;
Expand Down
9 changes: 9 additions & 0 deletions tools/xl/xl_parse.c
Original file line number Diff line number Diff line change
Expand Up @@ -1431,6 +1431,15 @@ void parse_config_data(const char *config_source,
else
exit(1);

e = xlu_cfg_get_bounded_long (config, "max_grant_version", 0,
INT_MAX, &l, 1);
if (e == ESRCH) /* not specified */
b_info->max_grant_version = max_grant_version;
else if (!e)
b_info->max_grant_version = l;
else
exit(1);

libxl_defbool_set(&b_info->claim_mode, claim_mode);

if (xlu_cfg_get_string (config, "on_poweroff", &buf, 0))
Expand Down
2 changes: 2 additions & 0 deletions xen/arch/arm/domain_build.c
Original file line number Diff line number Diff line change
Expand Up @@ -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") )
Expand Down Expand Up @@ -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 */
Expand Down
1 change: 1 addition & 0 deletions xen/arch/x86/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
9 changes: 8 additions & 1 deletion xen/common/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down Expand Up @@ -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;

Expand Down
21 changes: 19 additions & 2 deletions xen/common/grant_table.c
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -1917,11 +1918,26 @@ gnttab_grow_table(struct domain *d, unsigned int req_nr_frames)
}

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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions xen/include/public/domctl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
8 changes: 6 additions & 2 deletions xen/include/xen/grant_table.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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;
}

Expand Down

0 comments on commit 7379f9e

Please sign in to comment.