1 #ifndef _XEN_PARAM_H
2 #define _XEN_PARAM_H
3
4 #include <xen/bug.h>
5 #include <xen/hypfs.h>
6 #include <xen/init.h>
7 #include <xen/lib.h>
8 #include <xen/stdbool.h>
9
10 /*
11 * Used for kernel command line parameter setup
12 */
13 struct kernel_param {
14 const char *name;
15 enum {
16 OPT_STR,
17 OPT_UINT,
18 OPT_BOOL,
19 OPT_SIZE,
20 OPT_CUSTOM,
21 OPT_IGNORE,
22 } type;
23 unsigned int len;
24 union {
25 void *var;
26 int (*func)(const char *s);
27 } par;
28 };
29
30 /* Maximum length of a single parameter string. */
31 #define MAX_PARAM_SIZE 128
32
33 extern const struct kernel_param __setup_start[], __setup_end[];
34
35 #define __param(att) static const att \
36 __attribute__((__aligned__(sizeof(void *)))) struct kernel_param
37
38 #define __setup_str static const __initconst \
39 __attribute__((__aligned__(1))) char
40 #define __kparam __param(__initsetup)
41
42 /* Only for use with .init data, to avoid creating livepatch problems. */
43 #define __TEMP_NAME(base, line) base ## _ ## line
44 #define _TEMP_NAME(base, line) __TEMP_NAME(base, line)
45 #define TEMP_NAME(base) _TEMP_NAME(base, __LINE__)
46
47 #define custom_param(_name, _var) \
48 __setup_str __setup_str_##_var[] = (_name); \
49 __kparam __setup_##_var = \
50 { .name = __setup_str_##_var, \
51 .type = OPT_CUSTOM, \
52 .par.func = (_var) }
53 #define boolean_param(_name, _var) \
54 __setup_str __setup_str_##_var[] = (_name); \
55 __kparam __setup_##_var = \
56 { .name = __setup_str_##_var, \
57 .type = OPT_BOOL, \
58 .len = sizeof(_var) + \
59 BUILD_BUG_ON_ZERO(sizeof(_var) != sizeof(bool)), \
60 .par.var = &(_var) }
61 #define integer_param(_name, _var) \
62 __setup_str __setup_str_##_var[] = (_name); \
63 __kparam __setup_##_var = \
64 { .name = __setup_str_##_var, \
65 .type = OPT_UINT, \
66 .len = sizeof(_var), \
67 .par.var = &(_var) }
68 #define size_param(_name, _var) \
69 __setup_str __setup_str_##_var[] = (_name); \
70 __kparam __setup_##_var = \
71 { .name = __setup_str_##_var, \
72 .type = OPT_SIZE, \
73 .len = sizeof(_var), \
74 .par.var = &(_var) }
75 #define string_param(_name, _var) \
76 __setup_str __setup_str_##_var[] = (_name); \
77 __kparam __setup_##_var = \
78 { .name = __setup_str_##_var, \
79 .type = OPT_STR, \
80 .len = sizeof(_var), \
81 .par.var = &(_var) }
82 #define ignore_param(_name) \
83 __setup_str TEMP_NAME(__setup_str_ign)[] = (_name); \
84 __kparam TEMP_NAME(__setup_ign) = \
85 { .name = TEMP_NAME(__setup_str_ign), \
86 .type = OPT_IGNORE }
87
88 #ifdef CONFIG_HYPFS
89
90 struct param_hypfs {
91 struct hypfs_entry_leaf hypfs;
92 void (*init_leaf)(struct param_hypfs *par);
93 int (*func)(const char *);
94 };
95
96 extern struct param_hypfs __paramhypfs_start[], __paramhypfs_end[];
97
98 #define __paramhypfs __used_section(".data.paramhypfs")
99
100 #define __paramfs static __paramhypfs \
101 __attribute__((__aligned__(sizeof(void *)))) struct param_hypfs
102
103 #define custom_runtime_set_var_sz(parfs, var, sz) \
104 { \
105 (parfs)->hypfs.u.content = var; \
106 (parfs)->hypfs.e.max_size = sz; \
107 (parfs)->hypfs.e.size = strlen(var) + 1; \
108 }
109 #define custom_runtime_set_var(parfs, var) \
110 custom_runtime_set_var_sz(parfs, var, sizeof(var))
111
112 #define param_2_parfs(par) &__parfs_##par
113
114 /* initfunc needs to set size and content, e.g. via custom_runtime_set_var(). */
115 #define custom_runtime_only_param(nam, variable, initfunc) \
116 __paramfs __parfs_##variable = \
117 { .hypfs.e.type = XEN_HYPFS_TYPE_STRING, \
118 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
119 .hypfs.e.name = (nam), \
120 .hypfs.e.funcs = &hypfs_custom_wr_funcs, \
121 .init_leaf = (initfunc), \
122 .func = (variable) }
123 #define boolean_runtime_only_param(nam, variable) \
124 __paramfs __parfs_##variable = \
125 { .hypfs.e.type = XEN_HYPFS_TYPE_BOOL, \
126 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
127 .hypfs.e.name = (nam), \
128 .hypfs.e.size = sizeof(variable), \
129 .hypfs.e.max_size = sizeof(variable), \
130 .hypfs.e.funcs = &hypfs_bool_wr_funcs, \
131 .hypfs.u.content = &(variable) }
132 #define integer_runtime_only_param(nam, variable) \
133 __paramfs __parfs_##variable = \
134 { .hypfs.e.type = XEN_HYPFS_TYPE_UINT, \
135 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
136 .hypfs.e.name = (nam), \
137 .hypfs.e.size = sizeof(variable), \
138 .hypfs.e.max_size = sizeof(variable), \
139 .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
140 .hypfs.u.content = &(variable) }
141 #define size_runtime_only_param(nam, variable) \
142 __paramfs __parfs_##variable = \
143 { .hypfs.e.type = XEN_HYPFS_TYPE_UINT, \
144 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
145 .hypfs.e.name = (nam), \
146 .hypfs.e.size = sizeof(variable), \
147 .hypfs.e.max_size = sizeof(variable), \
148 .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
149 .hypfs.u.content = &(variable) }
150 #define string_runtime_only_param(nam, variable) \
151 __paramfs __parfs_##variable = \
152 { .hypfs.e.type = XEN_HYPFS_TYPE_STRING, \
153 .hypfs.e.encoding = XEN_HYPFS_ENC_PLAIN, \
154 .hypfs.e.name = (nam), \
155 .hypfs.e.size = 0, \
156 .hypfs.e.max_size = sizeof(variable), \
157 .hypfs.e.funcs = &hypfs_leaf_wr_funcs, \
158 .hypfs.u.content = &(variable) }
159
160 #else
161
162 #define custom_runtime_only_param(nam, var, initfunc)
163 #define boolean_runtime_only_param(nam, var)
164 #define integer_runtime_only_param(nam, var)
165 #define size_runtime_only_param(nam, var)
166 #define string_runtime_only_param(nam, var)
167
168 #define custom_runtime_set_var(parfs, var)
169
170 #endif
171
172 #define custom_runtime_param(_name, _var, initfunc) \
173 custom_param(_name, _var); \
174 custom_runtime_only_param(_name, _var, initfunc)
175 #define boolean_runtime_param(_name, _var) \
176 boolean_param(_name, _var); \
177 boolean_runtime_only_param(_name, _var)
178 #define integer_runtime_param(_name, _var) \
179 integer_param(_name, _var); \
180 integer_runtime_only_param(_name, _var)
181 #define size_runtime_param(_name, _var) \
182 size_param(_name, _var); \
183 size_runtime_only_param(_name, _var)
184 #define string_runtime_param(_name, _var) \
185 string_param(_name, _var); \
186 string_runtime_only_param(_name, _var)
187
188 extern bool opt_dit;
189
no_config_param(const char * cfg,const char * param,const char * s,const char * e)190 static inline void no_config_param(const char *cfg, const char *param,
191 const char *s, const char *e)
192 {
193 int len = e ? ({ ASSERT(e >= s); e - s; }) : strlen(s);
194
195 printk(XENLOG_INFO "CONFIG_%s disabled - ignoring '%s=%.*s' setting\n",
196 cfg, param, len, s);
197 }
198
199 #endif /* _XEN_PARAM_H */
200