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