[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 03/12] xen: add support for parameter scopes
In order to prepare support for domain-specific parameters similar to boot- and runtime-parameters of the hypervisor, add generic support for those to the parameter parsing framework. To each parameter definition a scope (global only for now) is added. Global parameters keep using pointers to the related variables in the struct kernel_param of their definitions, while those of narrower scope will use the offset in the structure (e.g. struct domain) for that purpose. This scheme requires passing the pointer to the structure instance to the parsing function and the parameter type specific subfunctions, of course. Signed-off-by: Juergen Gross <jgross@xxxxxxxx> --- xen/common/kernel.c | 38 ++++++++++++++++++++++++-------------- xen/include/xen/init.h | 32 ++++++++++++++++++++------------ 2 files changed, 44 insertions(+), 26 deletions(-) diff --git a/xen/common/kernel.c b/xen/common/kernel.c index a7e82453c2..f7f4e0dbff 100644 --- a/xen/common/kernel.c +++ b/xen/common/kernel.c @@ -19,6 +19,7 @@ #ifndef COMPAT struct parse_data { + enum param_scope scope; const struct kernel_param *start; const struct kernel_param *end; }; @@ -28,27 +29,28 @@ enum system_state system_state = SYS_STATE_early_boot; xen_commandline_t saved_cmdline; static const char __initconst opt_builtin_cmdline[] = CONFIG_CMDLINE; -static int assign_integer_param(const struct kernel_param *param, uint64_t val) +static int assign_integer_param(const struct kernel_param *param, + void *ptr, uint64_t val) { switch ( param->len ) { case sizeof(uint8_t): if ( val > UINT8_MAX && val < (uint64_t)INT8_MIN ) return -EOVERFLOW; - *(uint8_t *)param->par.var = val; + *(uint8_t *)ptr = val; break; case sizeof(uint16_t): if ( val > UINT16_MAX && val < (uint64_t)INT16_MIN ) return -EOVERFLOW; - *(uint16_t *)param->par.var = val; + *(uint16_t *)ptr = val; break; case sizeof(uint32_t): if ( val > UINT32_MAX && val < (uint64_t)INT32_MIN ) return -EOVERFLOW; - *(uint32_t *)param->par.var = val; + *(uint32_t *)ptr = val; break; case sizeof(uint64_t): - *(uint64_t *)param->par.var = val; + *(uint64_t *)ptr = val; break; default: BUG(); @@ -57,7 +59,8 @@ static int assign_integer_param(const struct kernel_param *param, uint64_t val) return 0; } -static int parse_params(const char *cmdline, const struct parse_data *data) +static int parse_params(const char *cmdline, const struct parse_data *data, + void *instance) { char opt[128], *optval, *optkey, *q; const char *p = cmdline, *key; @@ -108,6 +111,10 @@ static int parse_params(const char *cmdline, const struct parse_data *data) { int rctmp; const char *s; + void *ptr; + + if ( param->scope != data->scope ) + continue; if ( strcmp(param->name, optkey) ) { @@ -117,7 +124,7 @@ static int parse_params(const char *cmdline, const struct parse_data *data) { found = true; optval[-1] = '='; - rctmp = param->par.func(q); + rctmp = param->par.call(q, instance); optval[-1] = '\0'; if ( !rc ) rc = rctmp; @@ -127,14 +134,15 @@ static int parse_params(const char *cmdline, const struct parse_data *data) rctmp = 0; found = true; + ptr = (void *)((uint64_t)param->par.var + (uint64_t)instance); switch ( param->type ) { case OPT_STR: - strlcpy(param->par.var, optval, param->len); + strlcpy(ptr, optval, param->len); break; case OPT_UINT: rctmp = assign_integer_param( - param, + param, ptr, simple_strtoll(optval, &s, 0)); if ( *s ) rctmp = -EINVAL; @@ -146,11 +154,11 @@ static int parse_params(const char *cmdline, const struct parse_data *data) if ( !rctmp ) bool_assert = !bool_assert; rctmp = 0; - assign_integer_param(param, bool_assert); + assign_integer_param(param, ptr, bool_assert); break; case OPT_SIZE: rctmp = assign_integer_param( - param, + param, ptr, parse_size_and_unit(optval, &s)); if ( *s ) rctmp = -EINVAL; @@ -164,7 +172,7 @@ static int parse_params(const char *cmdline, const struct parse_data *data) safe_strcpy(opt, "no"); optval = opt; } - rctmp = param->par.func(optval); + rctmp = param->par.call(optval, instance); break; default: BUG(); @@ -192,23 +200,25 @@ static int parse_params(const char *cmdline, const struct parse_data *data) } static const struct parse_data boot_parse_data = { + .scope = SCOPE_GLOBAL, .start = __setup_start, .end = __setup_end, }; static const struct parse_data runtime_parse_data = { + .scope = SCOPE_GLOBAL, .start = __param_start, .end = __param_end, }; static void __init _cmdline_parse(const char *cmdline) { - parse_params(cmdline, &boot_parse_data); + parse_params(cmdline, &boot_parse_data, NULL); } int runtime_parse(const char *line) { - return parse_params(line, &runtime_parse_data); + return parse_params(line, &runtime_parse_data, NULL); } /** diff --git a/xen/include/xen/init.h b/xen/include/xen/init.h index d0b07b3d39..b04534c11a 100644 --- a/xen/include/xen/init.h +++ b/xen/include/xen/init.h @@ -73,6 +73,10 @@ void do_initcalls(void); /* * Used for kernel command line parameter setup */ +enum param_scope { + SCOPE_GLOBAL +}; + struct kernel_param { const char *name; enum { @@ -83,9 +87,11 @@ struct kernel_param { OPT_CUSTOM } type; unsigned int len; + enum param_scope scope; union { void *var; int (*func)(const char *); + int (*call)(const char *, void *); } par; }; @@ -101,54 +107,56 @@ extern const struct kernel_param __param_start[], __param_end[]; __attribute__((__aligned__(1))) char #define __kparam __param(__initsetup) -#define def_custom_param(_name, _func) \ +#define def_custom_param(_name, _scope, _func) \ { .name = _name, \ .type = OPT_CUSTOM, \ + .scope = _scope, \ .par.func = _func } -#define def_var_param(_name, _type, _var) \ +#define def_var_param(_name, _type, _scope, _var) \ { .name = _name, \ .type = _type, \ .len = sizeof(_var), \ + .scope = _scope, \ .par.var = &_var } #define custom_param(_name, _var) \ __setup_str __setup_str_##_var[] = _name; \ __kparam __setup_##_var = \ - def_custom_param(__setup_str_##_var, _var) + def_custom_param(__setup_str_##_var, SCOPE_GLOBAL, _var) #define boolean_param(_name, _var) \ __setup_str __setup_str_##_var[] = _name; \ __kparam __setup_##_var = \ - def_var_param(__setup_str_##_var, OPT_BOOL, _var) + def_var_param(__setup_str_##_var, OPT_BOOL, SCOPE_GLOBAL, _var) #define integer_param(_name, _var) \ __setup_str __setup_str_##_var[] = _name; \ __kparam __setup_##_var = \ - def_var_param(__setup_str_##_var, OPT_UINT, _var) + def_var_param(__setup_str_##_var, OPT_UINT, SCOPE_GLOBAL, _var) #define size_param(_name, _var) \ __setup_str __setup_str_##_var[] = _name; \ __kparam __setup_##_var = \ - def_var_param(__setup_str_##_var, OPT_SIZE, _var) + def_var_param(__setup_str_##_var, OPT_SIZE, SCOPE_GLOBAL, _var) #define string_param(_name, _var) \ __setup_str __setup_str_##_var[] = _name; \ __kparam __setup_##_var = \ - def_var_param(__setup_str_##_var, OPT_STR, _var) + def_var_param(__setup_str_##_var, OPT_STR, SCOPE_GLOBAL, _var) #define __rtparam __param(__dataparam) #define custom_runtime_only_param(_name, _var) \ __rtparam __rtpar_##_var = \ - def_custom_param(_name, _var) + def_custom_param(_name, SCOPE_GLOBAL, _var) #define boolean_runtime_only_param(_name, _var) \ __rtparam __rtpar_##_var = \ - def_var_param(_name, OPT_BOOL, _var) + def_var_param(_name, OPT_BOOL, SCOPE_GLOBAL, _var) #define integer_runtime_only_param(_name, _var) \ __rtparam __rtpar_##_var = \ - def_var_param(_name, OPT_UINT, _var) + def_var_param(_name, OPT_UINT, SCOPE_GLOBAL, _var) #define size_runtime_only_param(_name, _var) \ __rtparam __rtpar_##_var = \ - def_var_param(_name, OPT_SIZE, _var) + def_var_param(_name, OPT_SIZE, SCOPE_GLOBAL, _var) #define string_runtime_only_param(_name, _var) \ __rtparam __rtpar_##_var = \ - def_var_param(_name, OPT_STR, _var) + def_var_param(_name, OPT_STR, SCOPE_GLOBAL, _var) #define custom_runtime_param(_name, _var) \ custom_param(_name, _var); \ -- 2.16.4 _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |