direct-io.hg

view xen/common/kernel.c @ 10734:9b7e1ea4c4d2

[HVM] Sync p2m table across all vcpus on x86_32p xen.
We found VGA acceleration can not work on SMP VMX guests on x86_32p
xen, this is caused by the way we construct p2m table today: only the 1st
l2 page table slot that maps p2m table pages is copied to none-vcpu0 vcpu
monitor page table when VMX is created. But VGA acceleration will
create some p2m table entries beyond the 1st l2 page table slot after HVM is
created, so only vcpu0 can get these p2m entries, and other vcpu can
not do VGA acceleration.

Signed-off-by: Xin Li <xin.b.li@intel.com>
author kfraser@localhost.localdomain
date Wed Jul 26 11:34:12 2006 +0100 (2006-07-26)
parents ab63f44d948e
children b786bfb058eb
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%c",
100 tainted & TAINT_UNSAFE_SMP ? 'S' : ' ',
101 tainted & TAINT_MACHINE_CHECK ? 'M' : ' ',
102 tainted & TAINT_BAD_PAGE ? 'B' : ' ',
103 tainted & TAINT_SYNC_CONSOLE ? 'C' : ' ');
104 }
105 else
106 {
107 snprintf(str, TAINT_STRING_MAX_LEN, "Not tainted");
108 }
110 return str;
111 }
113 void add_taint(unsigned flag)
114 {
115 tainted |= flag;
116 }
118 /*
119 * Simple hypercalls.
120 */
122 long do_xen_version(int cmd, XEN_GUEST_HANDLE(void) arg)
123 {
124 switch ( cmd )
125 {
126 case XENVER_version:
127 {
128 return (XEN_VERSION<<16) | (XEN_SUBVERSION);
129 }
131 case XENVER_extraversion:
132 {
133 xen_extraversion_t extraversion;
134 safe_strcpy(extraversion, XEN_EXTRAVERSION);
135 if ( copy_to_guest(arg, (char *)extraversion, sizeof(extraversion)) )
136 return -EFAULT;
137 return 0;
138 }
140 case XENVER_compile_info:
141 {
142 struct xen_compile_info info;
143 safe_strcpy(info.compiler, XEN_COMPILER);
144 safe_strcpy(info.compile_by, XEN_COMPILE_BY);
145 safe_strcpy(info.compile_domain, XEN_COMPILE_DOMAIN);
146 safe_strcpy(info.compile_date, XEN_COMPILE_DATE);
147 if ( copy_to_guest(arg, &info, 1) )
148 return -EFAULT;
149 return 0;
150 }
152 case XENVER_capabilities:
153 {
154 xen_capabilities_info_t info;
155 extern void arch_get_xen_caps(xen_capabilities_info_t info);
157 memset(info, 0, sizeof(info));
158 arch_get_xen_caps(info);
160 if ( copy_to_guest(arg, (char *)info, sizeof(info)) )
161 return -EFAULT;
162 return 0;
163 }
165 case XENVER_platform_parameters:
166 {
167 xen_platform_parameters_t params = {
168 .virt_start = HYPERVISOR_VIRT_START
169 };
170 if ( copy_to_guest(arg, &params, 1) )
171 return -EFAULT;
172 return 0;
174 }
176 case XENVER_changeset:
177 {
178 xen_changeset_info_t chgset;
179 safe_strcpy(chgset, XEN_CHANGESET);
180 if ( copy_to_guest(arg, (char *)chgset, sizeof(chgset)) )
181 return -EFAULT;
182 return 0;
183 }
185 case XENVER_get_features:
186 {
187 xen_feature_info_t fi;
188 struct domain *d = current->domain;
190 if ( copy_from_guest(&fi, arg, 1) )
191 return -EFAULT;
193 switch ( fi.submap_idx )
194 {
195 case 0:
196 fi.submap = 0;
197 if ( VM_ASSIST(d, VMASST_TYPE_pae_extended_cr3) )
198 fi.submap |= (1U << XENFEAT_pae_pgdir_above_4gb);
199 if ( shadow_mode_translate(current->domain) )
200 fi.submap |=
201 (1U << XENFEAT_writable_page_tables) |
202 (1U << XENFEAT_auto_translated_physmap);
203 if ( supervisor_mode_kernel )
204 fi.submap |= 1U << XENFEAT_supervisor_mode_kernel;
205 break;
206 default:
207 return -EINVAL;
208 }
210 if ( copy_to_guest(arg, &fi, 1) )
211 return -EFAULT;
212 return 0;
213 }
215 case XENVER_pagesize:
216 {
217 return (!guest_handle_is_null(arg) ? -EINVAL : PAGE_SIZE);
218 }
220 }
222 return -ENOSYS;
223 }
225 long register_guest_nmi_callback(unsigned long address)
226 {
227 struct vcpu *v = current;
228 struct domain *d = current->domain;
230 if ( (d->domain_id != 0) || (v->vcpu_id != 0) )
231 return -EINVAL;
233 v->nmi_addr = address;
234 #ifdef CONFIG_X86
235 /*
236 * If no handler was registered we can 'lose the NMI edge'. Re-assert it
237 * now.
238 */
239 if ( d->shared_info->arch.nmi_reason != 0 )
240 set_bit(_VCPUF_nmi_pending, &v->vcpu_flags);
241 #endif
243 return 0;
244 }
246 long unregister_guest_nmi_callback(void)
247 {
248 struct vcpu *v = current;
250 v->nmi_addr = 0;
252 return 0;
253 }
255 long do_nmi_op(unsigned int cmd, XEN_GUEST_HANDLE(void) arg)
256 {
257 struct xennmi_callback cb;
258 long rc = 0;
260 switch ( cmd )
261 {
262 case XENNMI_register_callback:
263 rc = -EFAULT;
264 if ( copy_from_guest(&cb, arg, 1) )
265 break;
266 rc = register_guest_nmi_callback(cb.handler_address);
267 break;
268 case XENNMI_unregister_callback:
269 rc = unregister_guest_nmi_callback();
270 break;
271 default:
272 rc = -ENOSYS;
273 break;
274 }
276 return rc;
277 }
279 long do_vm_assist(unsigned int cmd, unsigned int type)
280 {
281 return vm_assist(current->domain, cmd, type);
282 }
284 long do_ni_hypercall(void)
285 {
286 /* No-op hypercall. */
287 return -ENOSYS;
288 }
290 /*
291 * Local variables:
292 * mode: C
293 * c-set-style: "BSD"
294 * c-basic-offset: 4
295 * tab-width: 4
296 * indent-tabs-mode: nil
297 * End:
298 */