6524928 domU console shouldn't drop when the domain reboots
6664507 virsh console command on Xen DomU system does not enforce console write exclusivity
6718462 need HVM serial support in virt-install
6718906 xVM console should be more verbose
1 Solaris dom0 support
2
3 diff --git a/src/xen_internal.c b/src/xen_internal.c
4 --- a/src/xen_internal.c
5 +++ b/src/xen_internal.c
6 @@ -70,7 +70,7 @@ typedef struct v1_hypercall_struct
7 #define XEN_V1_IOCTL_HYPERCALL_CMD \
8 _IOC(_IOC_NONE, 'P', 0, sizeof(v1_hypercall_t))
9 typedef v1_hypercall_t hypercall_t;
10 -#elif define(__sun__)
11 +#elif defined(__sun)
12 typedef privcmd_hypercall_t hypercall_t;
13 #else
14 #error "unsupported platform"
15 @@ -335,8 +335,10 @@ lock_pages(void *addr, size_t len)
16 {
17 #ifdef __linux__
18 return (mlock(addr, len));
19 -#elif define(__sun)
20 +#elif defined(__sun)
21 return (0);
22 +#else
23 +#error "unsupported platform"
24 #endif
25 }
26
27 @@ -345,8 +347,10 @@ unlock_pages(void *addr, size_t len)
28 {
29 #ifdef __linux__
30 return (munlock(addr, len));
31 -#elif define(__sun)
32 +#elif defined(__sun)
33 return (0);
34 +#else
35 +#error "unsupported platform"
36 #endif
37 }
38
39 @@ -661,7 +665,7 @@ typedef struct xen_op_v2_dom xen_op_v2_d
40 #define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
41 #define HYPERVISOR_CAPABILITIES "/sys/hypervisor/properties/capabilities"
42 #define CPUINFO "/proc/cpuinfo"
43 -#elif define(__sun__)
44 +#elif defined(__sun)
45 #define XEN_HYPERVISOR_SOCKET "/dev/xen/privcmd"
46 #define HYPERVISOR_CAPABILITIES ""
47 #define CPUINFO "/dev/cpu/self/cpuid"
48 @@ -2020,7 +2024,7 @@ xenHypervisorInit(void)
49 goto detect_v2;
50 }
51
52 -#ifndef __sun__
53 +#ifndef __sun
54 /*
55 * check if the old hypercall are actually working
56 */
57 @@ -2249,6 +2253,92 @@ xenHypervisorGetVersion(virConnectPtr co
58 return(0);
59 }
60
61 +#ifdef __linux__
62 +void
63 +loadCapabilities(FILE *cpuinfo, FILE *capabilities, char *hvm_type,
64 + int *host_pae, char *line, int LINE_SIZE)
65 +{
66 + regmatch_t subs[4];
67 +
68 + /* /proc/cpuinfo: flags: Intel calls HVM "vmx", AMD calls it "svm".
69 + * It's not clear if this will work on IA64, let alone other
70 + * architectures and non-Linux. (XXX)
71 + */
72 + if (cpuinfo) {
73 + while (fgets (line, LINE_SIZE, cpuinfo)) {
74 + if (regexec (&flags_hvm_rec, line,
75 + sizeof(subs)/sizeof(regmatch_t), subs, 0) == 0
76 + && subs[0].rm_so != -1) {
77 + strncpy (hvm_type,
78 + &line[subs[1].rm_so], subs[1].rm_eo-subs[1].rm_so+1);
79 + hvm_type[subs[1].rm_eo-subs[1].rm_so] = '\0';
80 + } else if (regexec (&flags_pae_rec, line, 0, NULL, 0) == 0)
81 + *host_pae = 1;
82 + }
83 + }
84 +
85 + /* Expecting one line in this file - ignore any more. */
86 + (void) fgets(line, LINE_SIZE, capabilities);
87 +}
88 +
89 +#else
90 +void
91 +loadCapabilities(FILE *cpuinfo, FILE *capabilities, char *hvm_type,
92 + int *host_pae, char *line, int LINE_SIZE)
93 +{
94 + struct {
95 + uint32_t r_eax, r_ebx, r_ecx, r_edx;
96 + } _r, *rp = &_r;
97 + int d, cmd;
98 + char *s;
99 + hypercall_t hc;
100 +
101 +
102 + if ((d = open(CPUINFO, O_RDONLY)) == -1) {
103 + goto cpuinfo_open_fail;
104 + }
105 +
106 + if (pread(d, rp, sizeof (*rp), 0) != sizeof (*rp)) {
107 + goto cpuinfo_pread_fail;
108 + }
109 +
110 + s = (char *)&rp->r_ebx;
111 + if (strncmp(s, "Auth" "cAMD" "enti", 12) == 0) {
112 + if (pread(d, rp, sizeof (*rp), 0x80000001) == sizeof (*rp)) {
113 + /* Read secure virtual machine bit (bit 2 of ECX feature ID) */
114 + if ((rp->r_ecx >> 2) & 1) {
115 + strcpy(hvm_type, "svm");
116 + }
117 + if ((rp->r_edx >> 6) & 1) {
118 + *host_pae = 1;
119 + }
120 + }
121 + } else if (strncmp(s, "Genu" "ntel" "ineI", 12) == 0) {
122 + if (pread(d, rp, sizeof (*rp), 0x00000001) == sizeof (*rp)) {
123 + /* Read VMXE feature bit (bit 5 of ECX feature ID) */
124 + if ((rp->r_ecx >> 5) & 1) {
125 + strcpy(hvm_type, "vmx");
126 + }
127 + if ((rp->r_edx >> 6) & 1) {
128 + *host_pae = 1;
129 + }
130 + }
131 + }
132 +cpuinfo_pread_fail:
133 + (void) close(d);
134 +cpuinfo_open_fail:
135 +
136 + d = open(XEN_HYPERVISOR_SOCKET, O_RDWR);
137 + hc.op = __HYPERVISOR_xen_version;
138 + hc.arg[0] = (unsigned long) XENVER_capabilities;
139 + hc.arg[1] = (unsigned long) line;
140 + cmd = IOCTL_PRIVCMD_HYPERCALL;
141 + (void) ioctl(d, cmd, (unsigned long) &hc);
142 + close(d);
143 +}
144 +
145 +#endif
146 +
147 /**
148 * xenHypervisorGetCapabilities:
149 * @conn: pointer to the connection block
150 @@ -2262,7 +2352,8 @@ xenHypervisorMakeCapabilitiesXML(virConn
151 const char *hostmachine,
152 FILE *cpuinfo, FILE *capabilities)
153 {
154 - char line[1024], *str, *token;
155 + const int LINE_SIZE = 1024;
156 + char line[LINE_SIZE], *str, *token;
157 regmatch_t subs[4];
158 char *saveptr = NULL;
159 int i, r, topology;
160 @@ -2287,24 +2378,12 @@ xenHypervisorMakeCapabilitiesXML(virConn
161
162 memset(guest_archs, 0, sizeof(guest_archs));
163
164 - /* /proc/cpuinfo: flags: Intel calls HVM "vmx", AMD calls it "svm".
165 - * It's not clear if this will work on IA64, let alone other
166 - * architectures and non-Linux. (XXX)
167 - */
168 - if (cpuinfo) {
169 - while (fgets (line, sizeof line, cpuinfo)) {
170 - if (regexec (&flags_hvm_rec, line, sizeof(subs)/sizeof(regmatch_t), subs, 0) == 0
171 - && subs[0].rm_so != -1) {
172 - strncpy (hvm_type,
173 - &line[subs[1].rm_so], subs[1].rm_eo-subs[1].rm_so+1);
174 - hvm_type[subs[1].rm_eo-subs[1].rm_so] = '\0';
175 - } else if (regexec (&flags_pae_rec, line, 0, NULL, 0) == 0)
176 - host_pae = 1;
177 - }
178 - }
179 -
180 - /* Most of the useful info is in /sys/hypervisor/properties/capabilities
181 - * which is documented in the code in xen-unstable.hg/xen/arch/.../setup.c.
182 + memset(line, 0, sizeof(line));
183 + loadCapabilities(cpuinfo, capabilities, hvm_type, &host_pae, line,
184 + LINE_SIZE);
185 +
186 + /* The capabilities line is documented in the code in
187 + * xen-unstable.hg/xen/arch/.../setup.c.
188 *
189 * It is a space-separated list of supported guest architectures.
190 *
191 @@ -2327,77 +2406,74 @@ xenHypervisorMakeCapabilitiesXML(virConn
192 * +--------------- "xen" or "hvm" for para or full virt respectively
193 */
194
195 - /* Expecting one line in this file - ignore any more. */
196 - if (fgets (line, sizeof line, capabilities)) {
197 - /* Split the line into tokens. strtok_r is OK here because we "own"
198 - * this buffer. Parse out the features from each token.
199 - */
200 - for (str = line, nr_guest_archs = 0;
201 - nr_guest_archs < sizeof guest_archs / sizeof guest_archs[0]
202 - && (token = strtok_r (str, " ", &saveptr)) != NULL;
203 - str = NULL) {
204 -
205 - if (regexec (&xen_cap_rec, token, sizeof subs / sizeof subs[0],
206 - subs, 0) == 0) {
207 - int hvm = strncmp (&token[subs[1].rm_so], "hvm", 3) == 0;
208 - const char *model;
209 - int bits, pae = 0, nonpae = 0, ia64_be = 0;
210 - if (strncmp (&token[subs[2].rm_so], "x86_32", 6) == 0) {
211 - model = "i686";
212 - bits = 32;
213 - if (strncmp (&token[subs[3].rm_so], "p", 1) == 0)
214 - pae = 1;
215 - else
216 - nonpae = 1;
217 + /* Split the line into tokens. strtok_r is OK here because we "own"
218 + * this buffer. Parse out the features from each token.
219 + */
220 + for (str = line, nr_guest_archs = 0;
221 + nr_guest_archs < sizeof guest_archs / sizeof guest_archs[0]
222 + && (token = strtok_r (str, " ", &saveptr)) != NULL;
223 + str = NULL) {
224 +
225 + if (regexec (&xen_cap_rec, token, sizeof subs / sizeof subs[0],
226 + subs, 0) == 0) {
227 + int hvm = strncmp (&token[subs[1].rm_so], "hvm", 3) == 0;
228 + const char *model;
229 + int bits, pae = 0, nonpae = 0, ia64_be = 0;
230 + if (strncmp (&token[subs[2].rm_so], "x86_32", 6) == 0) {
231 + model = "i686";
232 + bits = 32;
233 + if (strncmp (&token[subs[3].rm_so], "p", 1) == 0)
234 + pae = 1;
235 + else
236 + nonpae = 1;
237 + }
238 + else if (strncmp (&token[subs[2].rm_so], "x86_64", 6) == 0) {
239 + model = "x86_64";
240 + bits = 64;
241 + }
242 + else if (strncmp (&token[subs[2].rm_so], "ia64", 4) == 0) {
243 + model = "ia64";
244 + bits = 64;
245 + if (strncmp (&token[subs[3].rm_so], "be", 2) == 0)
246 + ia64_be = 1;
247 + }
248 + else if (strncmp (&token[subs[2].rm_so], "powerpc64", 4) == 0) {
249 + model = "ppc64";
250 + bits = 64;
251 + } else {
252 + /* XXX surely no other Xen archs exist */
253 + continue;
254 + }
255 +
256 + /* Search for existing matching (model,hvm) tuple */
257 + for (i = 0 ; i < nr_guest_archs ; i++) {
258 + if (!strcmp(guest_archs[i].model, model) &&
259 + guest_archs[i].hvm == hvm) {
260 + break;
261 }
262 - else if (strncmp (&token[subs[2].rm_so], "x86_64", 6) == 0) {
263 - model = "x86_64";
264 - bits = 64;
265 - }
266 - else if (strncmp (&token[subs[2].rm_so], "ia64", 4) == 0) {
267 - model = "ia64";
268 - bits = 64;
269 - if (strncmp (&token[subs[3].rm_so], "be", 2) == 0)
270 - ia64_be = 1;
271 - }
272 - else if (strncmp (&token[subs[2].rm_so], "powerpc64", 4) == 0) {
273 - model = "ppc64";
274 - bits = 64;
275 - } else {
276 - /* XXX surely no other Xen archs exist */
277 - continue;
278 - }
279 -
280 - /* Search for existing matching (model,hvm) tuple */
281 - for (i = 0 ; i < nr_guest_archs ; i++) {
282 - if (!strcmp(guest_archs[i].model, model) &&
283 - guest_archs[i].hvm == hvm) {
284 - break;
285 - }
286 - }
287 -
288 - /* Too many arch flavours - highly unlikely ! */
289 - if (i >= sizeof(guest_archs)/sizeof(guest_archs[0]))
290 - continue;
291 - /* Didn't find a match, so create a new one */
292 - if (i == nr_guest_archs)
293 - nr_guest_archs++;
294 -
295 - guest_archs[i].model = model;
296 - guest_archs[i].bits = bits;
297 - guest_archs[i].hvm = hvm;
298 -
299 - /* Careful not to overwrite a previous positive
300 - setting with a negative one here - some archs
301 - can do both pae & non-pae, but Xen reports
302 - separately capabilities so we're merging archs */
303 - if (pae)
304 - guest_archs[i].pae = pae;
305 - if (nonpae)
306 - guest_archs[i].nonpae = nonpae;
307 - if (ia64_be)
308 - guest_archs[i].ia64_be = ia64_be;
309 }
310 +
311 + /* Too many arch flavours - highly unlikely ! */
312 + if (i >= sizeof(guest_archs)/sizeof(guest_archs[0]))
313 + continue;
314 + /* Didn't find a match, so create a new one */
315 + if (i == nr_guest_archs)
316 + nr_guest_archs++;
317 +
318 + guest_archs[i].model = model;
319 + guest_archs[i].bits = bits;
320 + guest_archs[i].hvm = hvm;
321 +
322 + /* Careful not to overwrite a previous positive
323 + setting with a negative one here - some archs
324 + can do both pae & non-pae, but Xen reports
325 + separately capabilities so we're merging archs */
326 + if (pae)
327 + guest_archs[i].pae = pae;
328 + if (nonpae)
329 + guest_archs[i].nonpae = nonpae;
330 + if (ia64_be)
331 + guest_archs[i].ia64_be = ia64_be;
332 }
333 }
334
335 @@ -2543,29 +2619,33 @@ xenHypervisorGetCapabilities (virConnect
336 /* Really, this never fails - look at the man-page. */
337 uname (&utsname);
338
339 - cpuinfo = fopen ("/proc/cpuinfo", "r");
340 +#ifdef __linux__
341 + cpuinfo = fopen (CPUINFO, "r");
342 if (cpuinfo == NULL) {
343 if (errno != ENOENT) {
344 - virXenPerror (conn, "/proc/cpuinfo");
345 + virXenPerror (conn, CPUINFO);
346 return NULL;
347 }
348 }
349
350 - capabilities = fopen ("/sys/hypervisor/properties/capabilities", "r");
351 + capabilities = fopen (HYPERVISOR_CAPABILITIES, "r");
352 if (capabilities == NULL) {
353 if (errno != ENOENT) {
354 fclose(cpuinfo);
355 - virXenPerror (conn, "/sys/hypervisor/properties/capabilities");
356 + virXenPerror (conn, HYPERVISOR_CAPABILITIES);
357 return NULL;
358 }
359 }
360 +#endif
361
362 xml = xenHypervisorMakeCapabilitiesXML(conn, utsname.machine, cpuinfo, capabilities);
363
364 +#ifdef __linux__
365 if (cpuinfo)
366 fclose(cpuinfo);
367 if (capabilities)
368 fclose(capabilities);
369 +#endif
370
371 return xml;
372 }
373 diff --git a/src/xs_internal.c b/src/xs_internal.c
374 --- a/src/xs_internal.c
375 +++ b/src/xs_internal.c
376 @@ -33,7 +33,7 @@
377
378 #ifdef __linux__
379 #define XEN_HYPERVISOR_SOCKET "/proc/xen/privcmd"
380 -#elif define(__sun__)
381 +#elif defined(__sun)
382 #define XEN_HYPERVISOR_SOCKET "/dev/xen/privcmd"
383 #else
384 #error "unsupported platform"
--- EOF ---