ia64/xen-unstable

view xen/common/kernel.c @ 18594:5e4e234d58be

x86: Define __per_cpu_shift label to help kdump/crashdump.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Wed Oct 08 13:11:06 2008 +0100 (2008-10-08)
parents 847bc9b19c48
children 33d6ed9fd3c5
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 void cmdline_parse(char *cmdline)
28 {
29 char opt[100], *optval, *optkey, *q;
30 const char *p = cmdline;
31 struct kernel_param *param;
32 int bool_assert;
34 if ( p == NULL )
35 return;
37 for ( ; ; )
38 {
39 /* Skip whitespace. */
40 while ( *p == ' ' )
41 p++;
42 if ( *p == '\0' )
43 break;
45 /* Grab the next whitespace-delimited option. */
46 q = optkey = opt;
47 while ( (*p != ' ') && (*p != '\0') )
48 {
49 if ( (q-opt) < (sizeof(opt)-1) ) /* avoid overflow */
50 *q++ = *p;
51 p++;
52 }
53 *q = '\0';
55 /* Search for value part of a key=value option. */
56 optval = strchr(opt, '=');
57 if ( optval != NULL )
58 *optval++ = '\0'; /* nul-terminate the option value */
59 else
60 optval = q; /* default option value is empty string */
62 /* Boolean parameters can be inverted with 'no-' prefix. */
63 bool_assert = !!strncmp("no-", optkey, 3);
64 if ( !bool_assert )
65 optkey += 3;
67 for ( param = &__setup_start; param <= &__setup_end; param++ )
68 {
69 if ( strcmp(param->name, optkey) )
70 continue;
72 switch ( param->type )
73 {
74 case OPT_STR:
75 strlcpy(param->var, optval, param->len);
76 break;
77 case OPT_UINT:
78 *(unsigned int *)param->var =
79 simple_strtol(optval, (const char **)&optval, 0);
80 break;
81 case OPT_BOOL:
82 case OPT_INVBOOL:
83 if ( !strcmp("no", optval) ||
84 !strcmp("off", optval) ||
85 !strcmp("false", optval) ||
86 !strcmp("0", optval) )
87 bool_assert = !bool_assert;
88 if ( param->type == OPT_INVBOOL )
89 bool_assert = !bool_assert;
90 *(int *)param->var = bool_assert;
91 break;
92 case OPT_CUSTOM:
93 ((void (*)(const char *))param->var)(optval);
94 break;
95 }
96 }
97 }
98 }
100 /**
101 * print_tainted - return a string to represent the kernel taint state.
102 *
103 * 'S' - SMP with CPUs not designed for SMP.
104 * 'M' - Machine had a machine check experience.
105 * 'B' - System has hit bad_page.
106 *
107 * The string is overwritten by the next call to print_taint().
108 */
109 char *print_tainted(char *str)
110 {
111 if ( tainted )
112 {
113 snprintf(str, TAINT_STRING_MAX_LEN, "Tainted: %c%c%c%c",
114 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
115 tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
116 tainted & TAINT_BAD_PAGE ? 'B' : ' ',
117 tainted & TAINT_SYNC_CONSOLE ? 'C' : ' ');
118 }
119 else
120 {
121 snprintf(str, TAINT_STRING_MAX_LEN, "Not tainted");
122 }
124 return str;
125 }
127 void add_taint(unsigned flag)
128 {
129 tainted |= flag;
130 }
132 # define DO(fn) long do_##fn
134 #endif
136 /*
137 * Simple hypercalls.
138 */
140 DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg)
141 {
142 switch ( cmd )
143 {
144 case XENVER_version:
145 {
146 return (xen_major_version() << 16) | xen_minor_version();
147 }
149 case XENVER_extraversion:
150 {
151 xen_extraversion_t extraversion;
152 safe_strcpy(extraversion, xen_extra_version());
153 if ( copy_to_guest(arg, extraversion, ARRAY_SIZE(extraversion)) )
154 return -EFAULT;
155 return 0;
156 }
158 case XENVER_compile_info:
159 {
160 struct xen_compile_info info;
161 safe_strcpy(info.compiler, xen_compiler());
162 safe_strcpy(info.compile_by, xen_compile_by());
163 safe_strcpy(info.compile_domain, xen_compile_domain());
164 safe_strcpy(info.compile_date, xen_compile_date());
165 if ( copy_to_guest(arg, &info, 1) )
166 return -EFAULT;
167 return 0;
168 }
170 case XENVER_capabilities:
171 {
172 xen_capabilities_info_t info;
173 extern void arch_get_xen_caps(xen_capabilities_info_t *info);
175 memset(info, 0, sizeof(info));
176 arch_get_xen_caps(&info);
178 if ( copy_to_guest(arg, info, ARRAY_SIZE(info)) )
179 return -EFAULT;
180 return 0;
181 }
183 case XENVER_platform_parameters:
184 {
185 xen_platform_parameters_t params = {
186 .virt_start = HYPERVISOR_VIRT_START
187 };
188 if ( copy_to_guest(arg, &params, 1) )
189 return -EFAULT;
190 return 0;
192 }
194 case XENVER_changeset:
195 {
196 xen_changeset_info_t chgset;
197 safe_strcpy(chgset, xen_changeset());
198 if ( copy_to_guest(arg, chgset, ARRAY_SIZE(chgset)) )
199 return -EFAULT;
200 return 0;
201 }
203 case XENVER_get_features:
204 {
205 xen_feature_info_t fi;
206 struct domain *d = current->domain;
208 if ( copy_from_guest(&fi, arg, 1) )
209 return -EFAULT;
211 switch ( fi.submap_idx )
212 {
213 case 0:
214 fi.submap = 0;
215 if ( VM_ASSIST(d, VMASST_TYPE_pae_extended_cr3) )
216 fi.submap |= (1U << XENFEAT_pae_pgdir_above_4gb);
217 if ( paging_mode_translate(current->domain) )
218 fi.submap |=
219 (1U << XENFEAT_writable_page_tables) |
220 (1U << XENFEAT_auto_translated_physmap);
221 if ( supervisor_mode_kernel )
222 fi.submap |= 1U << XENFEAT_supervisor_mode_kernel;
223 #ifdef CONFIG_X86
224 if ( !is_hvm_vcpu(current) )
225 fi.submap |= 1U << XENFEAT_mmu_pt_update_preserve_ad;
226 #endif
227 break;
228 default:
229 return -EINVAL;
230 }
232 if ( copy_to_guest(arg, &fi, 1) )
233 return -EFAULT;
234 return 0;
235 }
237 case XENVER_pagesize:
238 {
239 return (!guest_handle_is_null(arg) ? -EINVAL : PAGE_SIZE);
240 }
242 case XENVER_guest_handle:
243 {
244 if ( copy_to_guest(arg, current->domain->handle,
245 ARRAY_SIZE(current->domain->handle)) )
246 return -EFAULT;
247 return 0;
248 }
249 }
251 return -ENOSYS;
252 }
254 DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
255 {
256 struct xennmi_callback cb;
257 long rc = 0;
259 switch ( cmd )
260 {
261 case XENNMI_register_callback:
262 rc = -EFAULT;
263 if ( copy_from_guest(&cb, arg, 1) )
264 break;
265 rc = register_guest_nmi_callback(cb.handler_address);
266 break;
267 case XENNMI_unregister_callback:
268 rc = unregister_guest_nmi_callback();
269 break;
270 default:
271 rc = -ENOSYS;
272 break;
273 }
275 return rc;
276 }
278 DO(vm_assist)(unsigned int cmd, unsigned int type)
279 {
280 return vm_assist(current->domain, cmd, type);
281 }
283 DO(ni_hypercall)(void)
284 {
285 /* No-op hypercall. */
286 return -ENOSYS;
287 }
289 /*
290 * Local variables:
291 * mode: C
292 * c-set-style: "BSD"
293 * c-basic-offset: 4
294 * tab-width: 4
295 * indent-tabs-mode: nil
296 * End:
297 */