direct-io.hg

view xen/common/kernel.c @ 10173:954f4dea9da6

[PAE] Allow pgdirs above 4GB for paravirt guests.
**NOTE**: This obviates the need for lowmem_emergency_pool.
Unpriv guests no longer need to be able to allocate memory
below 4GB for PAE PDPTs.
Signed-off-by: Keir Fraser <keir@xensource.com>
author kaf24@firebug.cl.cam.ac.uk
date Fri May 26 17:22:30 2006 +0100 (2006-05-26)
parents 4e1b8be54311
children 8aca850f66ad
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/compile.h>
12 #include <xen/sched.h>
13 #include <xen/shadow.h>
14 #include <xen/guest_access.h>
15 #include <asm/current.h>
16 #include <public/nmi.h>
17 #include <public/version.h>
19 int tainted;
21 void cmdline_parse(char *cmdline)
22 {
23 char opt[100], *optval, *p = cmdline, *q;
24 struct kernel_param *param;
26 if ( p == NULL )
27 return;
29 /* Skip whitespace and the image name. */
30 while ( *p == ' ' )
31 p++;
32 if ( (p = strchr(p, ' ')) == NULL )
33 return;
35 for ( ; ; )
36 {
37 /* Skip whitespace. */
38 while ( *p == ' ' )
39 p++;
40 if ( *p == '\0' )
41 break;
43 /* Grab the next whitespace-delimited option. */
44 q = opt;
45 while ( (*p != ' ') && (*p != '\0') )
46 {
47 if ( (q-opt) < (sizeof(opt)-1) ) /* avoid overflow */
48 *q++ = *p;
49 p++;
50 }
51 *q = '\0';
53 /* Search for value part of a key=value option. */
54 optval = strchr(opt, '=');
55 if ( optval != NULL )
56 *optval++ = '\0'; /* nul-terminate the option value */
57 else
58 optval = q; /* default option value is empty string */
60 for ( param = &__setup_start; param <= &__setup_end; param++ )
61 {
62 if ( strcmp(param->name, opt ) != 0 )
63 continue;
65 switch ( param->type )
66 {
67 case OPT_STR:
68 strncpy(param->var, optval, param->len);
69 ((char *)param->var)[param->len-1] = '\0';
70 break;
71 case OPT_UINT:
72 *(unsigned int *)param->var =
73 simple_strtol(optval, (char **)&optval, 0);
74 break;
75 case OPT_BOOL:
76 *(int *)param->var = 1;
77 break;
78 case OPT_CUSTOM:
79 ((void (*)(char *))param->var)(optval);
80 break;
81 }
82 }
83 }
84 }
86 /**
87 * print_tainted - return a string to represent the kernel taint state.
88 *
89 * 'S' - SMP with CPUs not designed for SMP.
90 * 'M' - Machine had a machine check experience.
91 * 'B' - System has hit bad_page.
92 *
93 * The string is overwritten by the next call to print_taint().
94 */
95 char *print_tainted(char *str)
96 {
97 if ( tainted )
98 {
99 snprintf(str, TAINT_STRING_MAX_LEN, "Tainted: %c%c%c",
100 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
101 tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
102 tainted & TAINT_BAD_PAGE ? 'B' : ' ');
103 }
104 else
105 {
106 snprintf(str, TAINT_STRING_MAX_LEN, "Not tainted");
107 }
109 return str;
110 }
112 void add_taint(unsigned flag)
113 {
114 tainted |= flag;
115 }
117 /*
118 * Simple hypercalls.
119 */
121 long do_xen_version(int cmd, XEN_GUEST_HANDLE(void) arg)
122 {
123 switch ( cmd )
124 {
125 case XENVER_version:
126 {
127 return (XEN_VERSION<<16) | (XEN_SUBVERSION);
128 }
130 case XENVER_extraversion:
131 {
132 xen_extraversion_t extraversion;
133 safe_strcpy(extraversion, XEN_EXTRAVERSION);
134 if ( copy_to_guest(arg, (char *)extraversion, sizeof(extraversion)) )
135 return -EFAULT;
136 return 0;
137 }
139 case XENVER_compile_info:
140 {
141 struct xen_compile_info info;
142 safe_strcpy(info.compiler, XEN_COMPILER);
143 safe_strcpy(info.compile_by, XEN_COMPILE_BY);
144 safe_strcpy(info.compile_domain, XEN_COMPILE_DOMAIN);
145 safe_strcpy(info.compile_date, XEN_COMPILE_DATE);
146 if ( copy_to_guest(arg, &info, 1) )
147 return -EFAULT;
148 return 0;
149 }
151 case XENVER_capabilities:
152 {
153 xen_capabilities_info_t info;
154 extern void arch_get_xen_caps(xen_capabilities_info_t info);
156 memset(info, 0, sizeof(info));
157 arch_get_xen_caps(info);
159 if ( copy_to_guest(arg, (char *)info, sizeof(info)) )
160 return -EFAULT;
161 return 0;
162 }
164 case XENVER_platform_parameters:
165 {
166 xen_platform_parameters_t params = {
167 .virt_start = HYPERVISOR_VIRT_START
168 };
169 if ( copy_to_guest(arg, &params, 1) )
170 return -EFAULT;
171 return 0;
173 }
175 case XENVER_changeset:
176 {
177 xen_changeset_info_t chgset;
178 safe_strcpy(chgset, XEN_CHANGESET);
179 if ( copy_to_guest(arg, (char *)chgset, sizeof(chgset)) )
180 return -EFAULT;
181 return 0;
182 }
184 case XENVER_get_features:
185 {
186 xen_feature_info_t fi;
188 if ( copy_from_guest(&fi, arg, 1) )
189 return -EFAULT;
191 switch ( fi.submap_idx )
192 {
193 case 0:
194 fi.submap = (1U << XENFEAT_pae_pgdir_above_4gb);
195 if ( shadow_mode_translate(current->domain) )
196 fi.submap |=
197 (1U << XENFEAT_writable_page_tables) |
198 (1U << XENFEAT_auto_translated_physmap);
199 if ( supervisor_mode_kernel )
200 fi.submap |= 1U << XENFEAT_supervisor_mode_kernel;
201 break;
202 default:
203 return -EINVAL;
204 }
206 if ( copy_to_guest(arg, &fi, 1) )
207 return -EFAULT;
208 return 0;
209 }
211 }
213 return -ENOSYS;
214 }
216 long register_guest_nmi_callback(unsigned long address)
217 {
218 struct vcpu *v = current;
219 struct domain *d = current->domain;
221 if ( (d->domain_id != 0) || (v->vcpu_id != 0) )
222 return -EINVAL;
224 v->nmi_addr = address;
225 #ifdef CONFIG_X86
226 /*
227 * If no handler was registered we can 'lose the NMI edge'. Re-assert it
228 * now.
229 */
230 if ( d->shared_info->arch.nmi_reason != 0 )
231 set_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
232 #endif
234 return 0;
235 }
237 long unregister_guest_nmi_callback(void)
238 {
239 struct vcpu *v = current;
241 v->nmi_addr = 0;
243 return 0;
244 }
246 long do_nmi_op(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
247 {
248 struct xennmi_callback cb;
249 long rc = 0;
251 switch ( cmd )
252 {
253 case XENNMI_register_callback:
254 rc = -EFAULT;
255 if ( copy_from_guest(&cb, arg, 1) )
256 break;
257 rc = register_guest_nmi_callback(cb.handler_address);
258 break;
259 case XENNMI_unregister_callback:
260 rc = unregister_guest_nmi_callback();
261 break;
262 default:
263 rc = -ENOSYS;
264 break;
265 }
267 return rc;
268 }
270 long do_vm_assist(unsigned int cmd, unsigned int type)
271 {
272 return vm_assist(current->domain, cmd, type);
273 }
275 long do_ni_hypercall(void)
276 {
277 /* No-op hypercall. */
278 return -ENOSYS;
279 }
281 /*
282 * Local variables:
283 * mode: C
284 * c-set-style: "BSD"
285 * c-basic-offset: 4
286 * tab-width: 4
287 * indent-tabs-mode: nil
288 * End:
289 */