ia64/xen-unstable

view xen/common/kernel.c @ 15896:42d4313b5fdd

[IA64] update .hgignore for xenitp

Signed-off-by: Alex Williamson <alex.williamson@hp.com>
author Alex Williamson <alex.williamson@hp.com>
date Mon Sep 24 14:21:02 2007 -0600 (2007-09-24)
parents 2eb38cefdcd9
children b032af6ad976
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) || !strcmp("off", optval) )
84 bool_assert = !bool_assert;
85 if ( param->type == OPT_INVBOOL )
86 bool_assert = !bool_assert;
87 *(int *)param->var = bool_assert;
88 break;
89 case OPT_CUSTOM:
90 ((void (*)(const char *))param->var)(optval);
91 break;
92 }
93 }
94 }
95 }
97 /**
98 * print_tainted - return a string to represent the kernel taint state.
99 *
100 * 'S' - SMP with CPUs not designed for SMP.
101 * 'M' - Machine had a machine check experience.
102 * 'B' - System has hit bad_page.
103 *
104 * The string is overwritten by the next call to print_taint().
105 */
106 char *print_tainted(char *str)
107 {
108 if ( tainted )
109 {
110 snprintf(str, TAINT_STRING_MAX_LEN, "Tainted: %c%c%c%c",
111 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
112 tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
113 tainted & TAINT_BAD_PAGE ? 'B' : ' ',
114 tainted & TAINT_SYNC_CONSOLE ? 'C' : ' ');
115 }
116 else
117 {
118 snprintf(str, TAINT_STRING_MAX_LEN, "Not tainted");
119 }
121 return str;
122 }
124 void add_taint(unsigned flag)
125 {
126 tainted |= flag;
127 }
129 # define DO(fn) long do_##fn
131 #endif
133 /*
134 * Simple hypercalls.
135 */
137 DO(xen_version)(int cmd, XEN_GUEST_HANDLE(void) arg)
138 {
139 switch ( cmd )
140 {
141 case XENVER_version:
142 {
143 return (xen_major_version() << 16) | xen_minor_version();
144 }
146 case XENVER_extraversion:
147 {
148 xen_extraversion_t extraversion;
149 safe_strcpy(extraversion, xen_extra_version());
150 if ( copy_to_guest(arg, extraversion, ARRAY_SIZE(extraversion)) )
151 return -EFAULT;
152 return 0;
153 }
155 case XENVER_compile_info:
156 {
157 struct xen_compile_info info;
158 safe_strcpy(info.compiler, xen_compiler());
159 safe_strcpy(info.compile_by, xen_compile_by());
160 safe_strcpy(info.compile_domain, xen_compile_domain());
161 safe_strcpy(info.compile_date, xen_compile_date());
162 if ( copy_to_guest(arg, &info, 1) )
163 return -EFAULT;
164 return 0;
165 }
167 case XENVER_capabilities:
168 {
169 xen_capabilities_info_t info;
170 extern void arch_get_xen_caps(xen_capabilities_info_t *info);
172 memset(info, 0, sizeof(info));
173 arch_get_xen_caps(&info);
175 if ( copy_to_guest(arg, info, ARRAY_SIZE(info)) )
176 return -EFAULT;
177 return 0;
178 }
180 case XENVER_platform_parameters:
181 {
182 xen_platform_parameters_t params = {
183 .virt_start = HYPERVISOR_VIRT_START
184 };
185 if ( copy_to_guest(arg, &params, 1) )
186 return -EFAULT;
187 return 0;
189 }
191 case XENVER_changeset:
192 {
193 xen_changeset_info_t chgset;
194 safe_strcpy(chgset, xen_changeset());
195 if ( copy_to_guest(arg, chgset, ARRAY_SIZE(chgset)) )
196 return -EFAULT;
197 return 0;
198 }
200 case XENVER_get_features:
201 {
202 xen_feature_info_t fi;
203 struct domain *d = current->domain;
205 if ( copy_from_guest(&fi, arg, 1) )
206 return -EFAULT;
208 switch ( fi.submap_idx )
209 {
210 case 0:
211 fi.submap = 0;
212 if ( VM_ASSIST(d, VMASST_TYPE_pae_extended_cr3) )
213 fi.submap |= (1U << XENFEAT_pae_pgdir_above_4gb);
214 if ( paging_mode_translate(current->domain) )
215 fi.submap |=
216 (1U << XENFEAT_writable_page_tables) |
217 (1U << XENFEAT_auto_translated_physmap);
218 if ( supervisor_mode_kernel )
219 fi.submap |= 1U << XENFEAT_supervisor_mode_kernel;
220 break;
221 default:
222 return -EINVAL;
223 }
225 if ( copy_to_guest(arg, &fi, 1) )
226 return -EFAULT;
227 return 0;
228 }
230 case XENVER_pagesize:
231 {
232 return (!guest_handle_is_null(arg) ? -EINVAL : PAGE_SIZE);
233 }
235 case XENVER_guest_handle:
236 {
237 if ( copy_to_guest(arg, current->domain->handle,
238 ARRAY_SIZE(current->domain->handle)) )
239 return -EFAULT;
240 return 0;
241 }
242 }
244 return -ENOSYS;
245 }
247 #ifndef COMPAT
249 long register_guest_nmi_callback(unsigned long address)
250 {
251 struct vcpu *v = current;
252 struct domain *d = current->domain;
254 if ( (d->domain_id != 0) || (v->vcpu_id != 0) )
255 return -EINVAL;
257 v->nmi_addr = address;
258 #ifdef CONFIG_X86
259 /*
260 * If no handler was registered we can 'lose the NMI edge'. Re-assert it
261 * now.
262 */
263 if ( arch_get_nmi_reason(d) != 0 )
264 v->nmi_pending = 1;
265 #endif
267 return 0;
268 }
270 long unregister_guest_nmi_callback(void)
271 {
272 struct vcpu *v = current;
274 v->nmi_addr = 0;
276 return 0;
277 }
279 #endif
281 DO(nmi_op)(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
282 {
283 struct xennmi_callback cb;
284 long rc = 0;
286 switch ( cmd )
287 {
288 case XENNMI_register_callback:
289 rc = -EFAULT;
290 if ( copy_from_guest(&cb, arg, 1) )
291 break;
292 rc = register_guest_nmi_callback(cb.handler_address);
293 break;
294 case XENNMI_unregister_callback:
295 rc = unregister_guest_nmi_callback();
296 break;
297 default:
298 rc = -ENOSYS;
299 break;
300 }
302 return rc;
303 }
305 DO(vm_assist)(unsigned int cmd, unsigned int type)
306 {
307 return vm_assist(current->domain, cmd, type);
308 }
310 DO(ni_hypercall)(void)
311 {
312 /* No-op hypercall. */
313 return -ENOSYS;
314 }
316 /*
317 * Local variables:
318 * mode: C
319 * c-set-style: "BSD"
320 * c-basic-offset: 4
321 * tab-width: 4
322 * indent-tabs-mode: nil
323 * End:
324 */