diff --git a/docs/man/xl.conf.5.pod b/docs/man/xl.conf.5.pod index 37262a7ef8..398b6cdf41 100644 --- a/docs/man/xl.conf.5.pod +++ b/docs/man/xl.conf.5.pod @@ -81,13 +81,15 @@ Default: C Sets the default value for the C domain config value. -Default: C<32> on hosts up to 16TB of memory, C<64> on hosts larger than 16TB +Default: value of Xen command line B parameter (or its +default value if unspecified). =item B Sets the default value for the C domain config value. -Default: C<1024> +Default: value of Xen command line B +parameter (or its default value if unspecified). =item B diff --git a/tools/libxl/libxl.h b/tools/libxl/libxl.h index a38e5cdba2..29208ec8ee 100644 --- a/tools/libxl/libxl.h +++ b/tools/libxl/libxl.h @@ -341,8 +341,17 @@ */ #define LIBXL_HAVE_BUILDINFO_GRANT_LIMITS 1 -#define LIBXL_MAX_GRANT_FRAMES_DEFAULT 32 -#define LIBXL_MAX_MAPTRACK_FRAMES_DEFAULT 1024 +#define LIBXL_MAX_GRANT_DEFAULT (~(uint32_t)0) +#define LIBXL_MAX_GRANT_FRAMES_DEFAULT 32 /* deprecated */ +#define LIBXL_MAX_MAPTRACK_FRAMES_DEFAULT 1024 /* deprecated */ +/* + * LIBXL_HAVE_BUILDINFO_GRANT_DEFAULT indicates that the default + * values of max_grant_frames and max_maptrack_frames fields in + * libxl_domain_build_info are the special sentinel value + * LIBXL_MAX_GRANT_DEFAULT rather than the fixed values above. + * This means to use the hypervisor's default. + */ +#define LIBXL_HAVE_BUILDINFO_GRANT_DEFAULT 1 /* * LIBXL_HAVE_BUILDINFO_* indicates that libxl_domain_build_info has diff --git a/tools/libxl/libxl_types.idl b/tools/libxl/libxl_types.idl index b685ac47ac..3599320605 100644 --- a/tools/libxl/libxl_types.idl +++ b/tools/libxl/libxl_types.idl @@ -493,8 +493,8 @@ libxl_domain_build_info = Struct("domain_build_info",[ ("vnuma_nodes", Array(libxl_vnode_info, "num_vnuma_nodes")), - ("max_grant_frames", uint32, {'init_val': 'LIBXL_MAX_GRANT_FRAMES_DEFAULT'}), - ("max_maptrack_frames", uint32, {'init_val': 'LIBXL_MAX_MAPTRACK_FRAMES_DEFAULT'}), + ("max_grant_frames", uint32, {'init_val': 'LIBXL_MAX_GRANT_DEFAULT'}), + ("max_maptrack_frames", uint32, {'init_val': 'LIBXL_MAX_GRANT_DEFAULT'}), ("device_model_version", libxl_device_model_version), ("device_model_stubdomain", libxl_defbool), diff --git a/tools/libxl/libxlu_cfg.c b/tools/libxl/libxlu_cfg.c index 5838f6885e..239ca1f26b 100644 --- a/tools/libxl/libxlu_cfg.c +++ b/tools/libxl/libxlu_cfg.c @@ -268,8 +268,9 @@ int xlu_cfg_replace_string(const XLU_Config *cfg, const char *n, return 0; } -int xlu_cfg_get_long(const XLU_Config *cfg, const char *n, - long *value_r, int dont_warn) { +int xlu_cfg_get_bounded_long(const XLU_Config *cfg, const char *n, + long min, long max, long *value_r, + int dont_warn) { long l; XLU_ConfigSetting *set; int e; @@ -295,10 +296,31 @@ int xlu_cfg_get_long(const XLU_Config *cfg, const char *n, cfg->config_source, set->lineno, n); return EINVAL; } + if (l < min) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: value `%ld' is smaller than minimum bound '%ld'\n", + cfg->config_source, set->lineno, l, min); + return EINVAL; + } + if (l > max) { + if (!dont_warn) + fprintf(cfg->report, + "%s:%d: warning: value `%ld' is greater than maximum bound '%ld'\n", + cfg->config_source, set->lineno, l, max); + return EINVAL; + } + *value_r= l; return 0; } +int xlu_cfg_get_long(const XLU_Config *cfg, const char *n, + long *value_r, int dont_warn) { + return xlu_cfg_get_bounded_long(cfg, n, LONG_MIN, LONG_MAX, value_r, + dont_warn); +} + int xlu_cfg_get_defbool(const XLU_Config *cfg, const char *n, libxl_defbool *b, int dont_warn) { diff --git a/tools/libxl/libxlutil.h b/tools/libxl/libxlutil.h index e81b644c01..2d066bf515 100644 --- a/tools/libxl/libxlutil.h +++ b/tools/libxl/libxlutil.h @@ -58,6 +58,8 @@ int xlu_cfg_replace_string(const XLU_Config *cfg, const char *n, char **value_r, int dont_warn); int xlu_cfg_get_long(const XLU_Config*, const char *n, long *value_r, int dont_warn); +int xlu_cfg_get_bounded_long(const XLU_Config*, const char *n, long min, + long max, long *value_r, int dont_warn); int xlu_cfg_get_defbool(const XLU_Config*, const char *n, libxl_defbool *b, int dont_warn); diff --git a/tools/python/xen/lowlevel/xc/xc.c b/tools/python/xen/lowlevel/xc/xc.c index cc8175a11e..2dd25f5498 100644 --- a/tools/python/xen/lowlevel/xc/xc.c +++ b/tools/python/xen/lowlevel/xc/xc.c @@ -127,8 +127,8 @@ static PyObject *pyxc_domain_create(XcObject *self, }, .max_vcpus = 1, .max_evtchn_port = -1, /* No limit. */ - .max_grant_frames = 32, - .max_maptrack_frames = 1024, + .max_grant_frames = -1, + .max_maptrack_frames = -1, }; static char *kwd_list[] = { "domid", "ssidref", "handle", "flags", diff --git a/tools/xl/xl.c b/tools/xl/xl.c index ddd29b3f1b..3d4390a46d 100644 --- a/tools/xl/xl.c +++ b/tools/xl/xl.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -96,7 +97,6 @@ static void parse_global_config(const char *configfile, XLU_Config *config; int e; const char *buf; - libxl_physinfo physinfo; config = xlu_cfg_init(stderr, configfile); if (!config) { @@ -197,17 +197,19 @@ static void parse_global_config(const char *configfile, xlu_cfg_replace_string (config, "colo.default.proxyscript", &default_colo_proxy_script, 0); - if (!xlu_cfg_get_long (config, "max_grant_frames", &l, 0)) + e = xlu_cfg_get_bounded_long (config, "max_grant_frames", 0, INT_MAX, + &l, 1); + if (!e) max_grant_frames = l; - else { - libxl_physinfo_init(&physinfo); - max_grant_frames = (libxl_get_physinfo(ctx, &physinfo) != 0 || - !(physinfo.max_possible_mfn >> 32)) - ? 32 : 64; - libxl_physinfo_dispose(&physinfo); - } - if (!xlu_cfg_get_long (config, "max_maptrack_frames", &l, 0)) + else if (e != ESRCH) + exit(1); + + e = xlu_cfg_get_bounded_long (config, "max_maptrack_frames", 0, + INT_MAX, &l, 1); + if (!e) max_maptrack_frames = 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); diff --git a/tools/xl/xl_parse.c b/tools/xl/xl_parse.c index 352cd214dd..a03992067b 100644 --- a/tools/xl/xl_parse.c +++ b/tools/xl/xl_parse.c @@ -1401,14 +1401,23 @@ void parse_config_data(const char *config_source, !xlu_cfg_get_string (config, "cpus_soft", &buf, 0)) parse_vcpu_affinity(b_info, cpus, buf, num_cpus, false); - if (!xlu_cfg_get_long (config, "max_grant_frames", &l, 0)) + e = xlu_cfg_get_bounded_long (config, "max_grant_frames", 0, INT_MAX, + &l, 1); + if (e == ESRCH) /* not specified */ + b_info->max_grant_frames = max_grant_frames; + else if (!e) b_info->max_grant_frames = l; else - b_info->max_grant_frames = max_grant_frames; - if (!xlu_cfg_get_long (config, "max_maptrack_frames", &l, 0)) - b_info->max_maptrack_frames = l; - else if (max_maptrack_frames != -1) + exit(1); + + e = xlu_cfg_get_bounded_long (config, "max_maptrack_frames", 0, + INT_MAX, &l, 1); + if (e == ESRCH) /* not specified */ b_info->max_maptrack_frames = max_maptrack_frames; + else if (!e) + b_info->max_maptrack_frames = l; + else + exit(1); libxl_defbool_set(&b_info->claim_mode, claim_mode); diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 7fe02120a7..d986f84f8d 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -741,7 +741,7 @@ void __init start_xen(unsigned long boot_phys_offset, .flags = XEN_DOMCTL_CDF_hvm_guest | XEN_DOMCTL_CDF_hap, .max_evtchn_port = -1, .max_grant_frames = gnttab_dom0_frames(), - .max_maptrack_frames = opt_max_maptrack_frames, + .max_maptrack_frames = -1, }; dcache_line_bytes = read_dcache_line_bytes(); diff --git a/xen/arch/x86/setup.c b/xen/arch/x86/setup.c index c1c7c44000..5ab53e3d85 100644 --- a/xen/arch/x86/setup.c +++ b/xen/arch/x86/setup.c @@ -689,8 +689,8 @@ void __init noreturn __start_xen(unsigned long mbi_p) struct xen_domctl_createdomain dom0_cfg = { .flags = XEN_DOMCTL_CDF_s3_integrity, .max_evtchn_port = -1, - .max_grant_frames = opt_max_grant_frames, - .max_maptrack_frames = opt_max_maptrack_frames, + .max_grant_frames = -1, + .max_maptrack_frames = -1, }; /* Critical region without IDT or TSS. Any fault is deadly! */ diff --git a/xen/common/grant_table.c b/xen/common/grant_table.c index e9ce0ac473..daac9924fc 100644 --- a/xen/common/grant_table.c +++ b/xen/common/grant_table.c @@ -83,11 +83,42 @@ struct grant_table { struct grant_table_arch arch; }; -unsigned int __read_mostly opt_max_grant_frames = 64; -integer_runtime_param("gnttab_max_frames", opt_max_grant_frames); +static int parse_gnttab_limit(const char *param, const char *arg, + unsigned int *valp) +{ + const char *e; + unsigned long val; -unsigned int __read_mostly opt_max_maptrack_frames = 1024; -integer_runtime_param("gnttab_max_maptrack_frames", opt_max_maptrack_frames); + val = simple_strtoul(arg, &e, 0); + if ( *e ) + return -EINVAL; + + if ( val > INT_MAX ) + return -ERANGE; + + *valp = val; + + return 0; +} + +unsigned int __read_mostly opt_max_grant_frames = 64; + +static int parse_gnttab_max_frames(const char *arg) +{ + return parse_gnttab_limit("gnttab_max_frames", arg, + &opt_max_grant_frames); +} +custom_runtime_param("gnttab_max_frames", parse_gnttab_max_frames); + +static unsigned int __read_mostly opt_max_maptrack_frames = 1024; + +static int parse_gnttab_max_maptrack_frames(const char *arg) +{ + return parse_gnttab_limit("gnttab_max_maptrack_frames", arg, + &opt_max_maptrack_frames); +} +custom_runtime_param("gnttab_max_maptrack_frames", + parse_gnttab_max_maptrack_frames); #ifndef GNTTAB_MAX_VERSION #define GNTTAB_MAX_VERSION 2 @@ -1802,12 +1833,18 @@ active_alloc_failed: return -ENOMEM; } -int grant_table_init(struct domain *d, unsigned int max_grant_frames, - unsigned int max_maptrack_frames) +int grant_table_init(struct domain *d, int max_grant_frames, + int max_maptrack_frames) { struct grant_table *gt; int ret = -ENOMEM; + /* Default to maximum value if no value was specified */ + if ( max_grant_frames < 0 ) + max_grant_frames = opt_max_grant_frames; + if ( max_maptrack_frames < 0 ) + max_maptrack_frames = opt_max_maptrack_frames; + if ( max_grant_frames < INITIAL_NR_GRANT_FRAMES || max_grant_frames > opt_max_grant_frames || max_maptrack_frames > opt_max_maptrack_frames ) diff --git a/xen/include/public/domctl.h b/xen/include/public/domctl.h index 6f9be8166e..01f142289e 100644 --- a/xen/include/public/domctl.h +++ b/xen/include/public/domctl.h @@ -67,13 +67,15 @@ struct xen_domctl_createdomain { uint32_t flags; /* - * Various domain limits, which impact the quantity of resources (global - * mapping space, xenheap, etc) a guest may consume. + * Various domain limits, which impact the quantity of resources + * (global mapping space, xenheap, etc) a guest may consume. For + * max_grant_frames and max_maptrack_frames, < 0 means "use the + * default maximum value in the hypervisor". */ uint32_t max_vcpus; uint32_t max_evtchn_port; - uint32_t max_grant_frames; - uint32_t max_maptrack_frames; + int32_t max_grant_frames; + int32_t max_maptrack_frames; struct xen_arch_domainconfig arch; }; diff --git a/xen/include/xen/grant_table.h b/xen/include/xen/grant_table.h index 12e8a4b80b..119b8f7e2b 100644 --- a/xen/include/xen/grant_table.h +++ b/xen/include/xen/grant_table.h @@ -32,11 +32,10 @@ struct grant_table; extern unsigned int opt_max_grant_frames; -extern unsigned int opt_max_maptrack_frames; /* Create/destroy per-domain grant table context. */ -int grant_table_init(struct domain *d, unsigned int max_grant_frames, - unsigned int max_maptrack_frames); +int grant_table_init(struct domain *d, int max_grant_frames, + int max_maptrack_frames); void grant_table_destroy( struct domain *d); void grant_table_init_vcpu(struct vcpu *v);