debuggers.hg

view xen/common/kernel.c @ 22906:700ac6445812

Now add KDB to the non-kdb tree
author Mukesh Rathor
date Thu Feb 03 15:42:41 2011 -0800 (2011-02-03)
parents e8acb9753ff1
children
line source
1 /******************************************************************************
2 * kernel.c
3 *
4 * Copyright (c) 2002-2005 K A Fraser
5 */
7 #include <xen/config.h>
8 #include <xen/init.h>
9 #include <xen/lib.h>
10 #include <xen/errno.h>
11 #include <xen/version.h>
12 #include <xen/sched.h>
13 #include <xen/paging.h>
14 #include <xen/nmi.h>
15 #include <xen/guest_access.h>
16 #include <asm/current.h>
17 #include <public/nmi.h>
18 #include <public/version.h>
19 #ifdef CONFIG_X86
20 #include <asm/shared.h>
21 #endif
23 #ifndef COMPAT
25 int tainted;
27 xen_commandline_t saved_cmdline;
29 static void __init assign_integer_param(
30 struct kernel_param *param, uint64_t val)
31 {
32 switch ( param->len )
33 {
34 case sizeof(uint8_t):
35 *(uint8_t *)param->var = val;
36 break;
37 case sizeof(uint16_t):
38 *(uint16_t *)param->var = val;
39 break;
40 case sizeof(uint32_t):
41 *(uint32_t *)param->var = val;
42 break;
43 case sizeof(uint64_t):
44 *(uint64_t *)param->var = val;
45 break;
46 default:
47 BUG();
48 }
49 }
51 void __init cmdline_parse(char *cmdline)
52 {
53 char opt[100], *optval, *optkey, *q;
54 const char *p = cmdline;
55 struct kernel_param *param;
56 int bool_assert;
58 safe_strcpy(saved_cmdline, cmdline);
60 if ( p == NULL )
61 return;
63 for ( ; ; )
64 {
65 /* Skip whitespace. */
66 while ( *p == ' ' )
67 p++;
68 if ( *p == '\0' )
69 break;
71 /* Grab the next whitespace-delimited option. */
72 q = optkey = opt;
73 while ( (*p != ' ') && (*p != '\0') )
74 {
75 if ( (q-opt) < (sizeof(opt)-1) ) /* avoid overflow */
76 *q++ = *p;
77 p++;
78 }
79 *q = '\0';
81 /* Search for value part of a key=value option. */
82 optval = strchr(opt, '=');
83 if ( optval != NULL )
84 *optval++ = '\0'; /* nul-terminate the option value */
85 else
86 optval = q; /* default option value is empty string */
88 /* Boolean parameters can be inverted with 'no-' prefix. */
89 bool_assert = !!strncmp("no-", optkey, 3);
90 if ( !bool_assert )
91 optkey += 3;
93 for ( param = &__setup_start; param <= &__setup_end; param++ )
94 {
95 if ( strcmp(param->name, optkey) )
96 continue;
98 switch ( param->type )
99 {
100 case OPT_STR:
101 strlcpy(param->var, optval, param->len);
102 break;
103 case OPT_UINT:
104 assign_integer_param(
105 param,
106 simple_strtoll(optval, NULL, 0));
107 break;
108 case OPT_BOOL:
109 case OPT_INVBOOL:
110 if ( !parse_bool(optval) )
111 bool_assert = !bool_assert;
112 assign_integer_param(
113 param,
114 (param->type == OPT_BOOL) == bool_assert);
115 break;
116 case OPT_SIZE:
117 assign_integer_param(
118 param,
119 parse_size_and_unit(optval, NULL));
120 break;
121 case OPT_CUSTOM:
122 ((void (*)(const char *))param->var)(optval);
123 break;
124 default:
125 BUG();
126 break;
127 }
128 }
129 }
130 }
132 int __init parse_bool(const char *s)
133 {
134 if ( !strcmp("no", s) ||
135 !strcmp("off", s) ||
136 !strcmp("false", s) ||
137 !strcmp("disable", s) ||
138 !strcmp("0", s) )
139 return 0;
141 if ( !strcmp("yes", s) ||
142 !strcmp("on", s) ||
143 !strcmp("true", s) ||
144 !strcmp("enable", s) ||
145 !strcmp("1", s) )
146 return 1;
148 return -1;
149 }
151 /**
152 * print_tainted - return a string to represent the kernel taint state.
153 *
154 * 'S' - SMP with CPUs not designed for SMP.
155 * 'M' - Machine had a machine check experience.
156 * 'B' - System has hit bad_page.
157 *
158 * The string is overwritten by the next call to print_taint().
159 */
160 char *print_tainted(char *str)
161 {
162 if ( tainted )
163 {
164 snprintf(str, TAINT_STRING_MAX_LEN, "Tainted: %c%c%c%c",
165 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
166 tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
167 tainted & TAINT_BAD_PAGE ? 'B' : ' ',
168 tainted & TAINT_SYNC_CONSOLE ? 'C' : ' ');
169 }
170 else
171 {
172 snprintf(str, TAINT_STRING_MAX_LEN, "Not tainted");
173 }
175 return str;
176 }
178 void add_taint(unsigned flag)
179 {
180 tainted |= flag;
181 }
183 extern initcall_t __initcall_start, __presmp_initcall_end, __initcall_end;
185 void __init do_presmp_initcalls(void)
186 {
187 initcall_t *call;
188 for ( call = &__initcall_start; call < &__presmp_initcall_end; call++ )
189 (*call)();
190 }
192 void __init do_initcalls(void)
193 {
194 initcall_t *call;
195 for ( call = &__presmp_initcall_end; call < &__initcall_end; call++ )
196 (*call)();
197 }
199 # define DO(fn) long do_##fn
201 #endif
203 /*
204 * Simple hypercalls.
205 */
207 DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg)
208 {
209 switch ( cmd )
210 {
211 case XENVER_version:
212 {
213 return (xen_major_version() << 16) | xen_minor_version();
214 }
216 case XENVER_extraversion:
217 {
218 xen_extraversion_t extraversion;
219 safe_strcpy(extraversion, xen_extra_version());
220 if ( copy_to_guest(arg, extraversion, ARRAY_SIZE(extraversion)) )
221 return -EFAULT;
222 return 0;
223 }
225 case XENVER_compile_info:
226 {
227 struct xen_compile_info info;
228 safe_strcpy(info.compiler, xen_compiler());
229 safe_strcpy(info.compile_by, xen_compile_by());
230 safe_strcpy(info.compile_domain, xen_compile_domain());
231 safe_strcpy(info.compile_date, xen_compile_date());
232 if ( copy_to_guest(arg, &info, 1) )
233 return -EFAULT;
234 return 0;
235 }
237 case XENVER_capabilities:
238 {
239 xen_capabilities_info_t info;
240 extern void arch_get_xen_caps(xen_capabilities_info_t *info);
242 memset(info, 0, sizeof(info));
243 arch_get_xen_caps(&info);
245 if ( copy_to_guest(arg, info, ARRAY_SIZE(info)) )
246 return -EFAULT;
247 return 0;
248 }
250 case XENVER_platform_parameters:
251 {
252 xen_platform_parameters_t params = {
253 .virt_start = HYPERVISOR_VIRT_START
254 };
255 if ( copy_to_guest(arg, &params, 1) )
256 return -EFAULT;
257 return 0;
259 }
261 case XENVER_changeset:
262 {
263 xen_changeset_info_t chgset;
264 safe_strcpy(chgset, xen_changeset());
265 if ( copy_to_guest(arg, chgset, ARRAY_SIZE(chgset)) )
266 return -EFAULT;
267 return 0;
268 }
270 case XENVER_get_features:
271 {
272 xen_feature_info_t fi;
273 struct domain *d = current->domain;
275 if ( copy_from_guest(&fi, arg, 1) )
276 return -EFAULT;
278 switch ( fi.submap_idx )
279 {
280 case 0:
281 fi.submap = 0;
282 if ( VM_ASSIST(d, VMASST_TYPE_pae_extended_cr3) )
283 fi.submap |= (1U << XENFEAT_pae_pgdir_above_4gb);
284 if ( paging_mode_translate(current->domain) )
285 fi.submap |=
286 (1U << XENFEAT_writable_page_tables) |
287 (1U << XENFEAT_auto_translated_physmap);
288 if ( supervisor_mode_kernel )
289 fi.submap |= 1U << XENFEAT_supervisor_mode_kernel;
290 #ifdef CONFIG_X86
291 if ( !is_hvm_vcpu(current) )
292 fi.submap |= (1U << XENFEAT_mmu_pt_update_preserve_ad) |
293 (1U << XENFEAT_highmem_assist) |
294 (1U << XENFEAT_gnttab_map_avail_bits);
295 else
296 fi.submap |= (1U << XENFEAT_hvm_safe_pvclock) |
297 (1U << XENFEAT_hvm_callback_vector) |
298 (1U << XENFEAT_hvm_pirqs);
299 #endif
300 break;
301 default:
302 return -EINVAL;
303 }
305 if ( copy_to_guest(arg, &fi, 1) )
306 return -EFAULT;
307 return 0;
308 }
310 case XENVER_pagesize:
311 {
312 return (!guest_handle_is_null(arg) ? -EINVAL : PAGE_SIZE);
313 }
315 case XENVER_guest_handle:
316 {
317 if ( copy_to_guest(arg, current->domain->handle,
318 ARRAY_SIZE(current->domain->handle)) )
319 return -EFAULT;
320 return 0;
321 }
323 case XENVER_commandline:
324 {
325 if ( copy_to_guest(arg, saved_cmdline, ARRAY_SIZE(saved_cmdline)) )
326 return -EFAULT;
327 return 0;
328 }
329 }
331 return -ENOSYS;
332 }
334 DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
335 {
336 struct xennmi_callback cb;
337 long rc = 0;
339 switch ( cmd )
340 {
341 case XENNMI_register_callback:
342 rc = -EFAULT;
343 if ( copy_from_guest(&cb, arg, 1) )
344 break;
345 rc = register_guest_nmi_callback(cb.handler_address);
346 break;
347 case XENNMI_unregister_callback:
348 rc = unregister_guest_nmi_callback();
349 break;
350 default:
351 rc = -ENOSYS;
352 break;
353 }
355 return rc;
356 }
358 DO(vm_assist)(unsigned int cmd, unsigned int type)
359 {
360 return vm_assist(current->domain, cmd, type);
361 }
363 DO(ni_hypercall)(void)
364 {
365 /* No-op hypercall. */
366 return -ENOSYS;
367 }
369 /*
370 * Local variables:
371 * mode: C
372 * c-set-style: "BSD"
373 * c-basic-offset: 4
374 * tab-width: 4
375 * indent-tabs-mode: nil
376 * End:
377 */