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