master
c 600 lines 22 KB
Raw
1 /*
2 * QEMU monitor
3 *
4 * Copyright (c) 2003-2004 Fabrice Bellard
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a copy
7 * of this software and associated documentation files (the "Software"), to deal
8 * in the Software without restriction, including without limitation the rights
9 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 * copies of the Software, and to permit persons to whom the Software is
11 * furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 * THE SOFTWARE.
23 */
24
25 #include "qemu/osdep.h"
26 #include "cpu.h"
27 #include "monitor/monitor.h"
28 #include "monitor/hmp.h"
29 #include "qobject/qdict.h"
30 #include "qapi/error.h"
31 #include "qapi/qapi-commands-misc.h"
32 #include "system/memory.h"
33
34 #ifdef CONFIG_HMP
35
36 /* Perform linear address sign extension */
37 static hwaddr addr_canonical(CPUArchState *env, hwaddr addr)
38 {
39 #ifdef TARGET_X86_64
40 if (env->cr[4] & CR4_LA57_MASK) {
41 if (addr & (1ULL << 56)) {
42 addr |= (hwaddr)-(1LL << 57);
43 }
44 } else {
45 if (addr & (1ULL << 47)) {
46 addr |= (hwaddr)-(1LL << 48);
47 }
48 }
49 #endif
50 return addr;
51 }
52
53 static void print_pte(MonitorHMP *hmp, CPUArchState *env, hwaddr addr,
54 hwaddr pte, hwaddr mask)
55 {
56 addr = addr_canonical(env, addr);
57
58 monitor_hmp_printf(hmp, HWADDR_FMT_plx ": " HWADDR_FMT_plx
59 " %c%c%c%c%c%c%c%c%c\n",
60 addr,
61 pte & mask,
62 pte & PG_NX_MASK ? 'X' : '-',
63 pte & PG_GLOBAL_MASK ? 'G' : '-',
64 pte & PG_PSE_MASK ? 'P' : '-',
65 pte & PG_DIRTY_MASK ? 'D' : '-',
66 pte & PG_ACCESSED_MASK ? 'A' : '-',
67 pte & PG_PCD_MASK ? 'C' : '-',
68 pte & PG_PWT_MASK ? 'T' : '-',
69 pte & PG_USER_MASK ? 'U' : '-',
70 pte & PG_RW_MASK ? 'W' : '-');
71 }
72
73 static void tlb_info_32(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
74 {
75 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
76 unsigned int l1, l2;
77 uint32_t pgd, pde, pte;
78
79 pgd = env->cr[3] & ~0xfff;
80 for(l1 = 0; l1 < 1024; l1++) {
81 pde = address_space_ldl_le(as, pgd + l1 * 4, attrs, NULL);
82 if (pde & PG_PRESENT_MASK) {
83 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
84 /* 4M pages */
85 print_pte(hmp, env, (l1 << 22), pde, ~((1 << 21) - 1));
86 } else {
87 for(l2 = 0; l2 < 1024; l2++) {
88 pte = address_space_ldl_le(as, (pde & ~0xfff) + l2 * 4,
89 attrs, NULL);
90 if (pte & PG_PRESENT_MASK) {
91 print_pte(hmp, env, (l1 << 22) + (l2 << 12),
92 pte & ~PG_PSE_MASK,
93 ~0xfff);
94 }
95 }
96 }
97 }
98 }
99 }
100
101 static void tlb_info_pae32(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
102 {
103 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
104 unsigned int l1, l2, l3;
105 uint64_t pdpe, pde, pte;
106 uint64_t pdp_addr, pd_addr, pt_addr;
107
108 pdp_addr = env->cr[3] & ~0x1f;
109 for (l1 = 0; l1 < 4; l1++) {
110 pdpe = address_space_ldq_le(as, pdp_addr + l1 * 8, attrs, NULL);
111 if (pdpe & PG_PRESENT_MASK) {
112 pd_addr = pdpe & 0x3fffffffff000ULL;
113 for (l2 = 0; l2 < 512; l2++) {
114 pde = address_space_ldq_le(as, pd_addr + l2 * 8, attrs, NULL);
115 if (pde & PG_PRESENT_MASK) {
116 if (pde & PG_PSE_MASK) {
117 /* 2M pages with PAE, CR4.PSE is ignored */
118 print_pte(hmp, env, (l1 << 30) + (l2 << 21), pde,
119 ~((hwaddr)(1 << 20) - 1));
120 } else {
121 pt_addr = pde & 0x3fffffffff000ULL;
122 for (l3 = 0; l3 < 512; l3++) {
123 pte = address_space_ldq_le(as, pt_addr + l3 * 8,
124 attrs, NULL);
125 if (pte & PG_PRESENT_MASK) {
126 print_pte(hmp, env, (l1 << 30) + (l2 << 21)
127 + (l3 << 12),
128 pte & ~PG_PSE_MASK,
129 ~(hwaddr)0xfff);
130 }
131 }
132 }
133 }
134 }
135 }
136 }
137 }
138
139 #ifdef TARGET_X86_64
140 static void tlb_info_la48(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as,
141 uint64_t l0, uint64_t pml4_addr)
142 {
143 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
144 uint64_t l1, l2, l3, l4;
145 uint64_t pml4e, pdpe, pde, pte;
146 uint64_t pdp_addr, pd_addr, pt_addr;
147
148 for (l1 = 0; l1 < 512; l1++) {
149 pml4e = address_space_ldq_le(as, pml4_addr + l1 * 8, attrs, NULL);
150 if (!(pml4e & PG_PRESENT_MASK)) {
151 continue;
152 }
153
154 pdp_addr = pml4e & 0x3fffffffff000ULL;
155 for (l2 = 0; l2 < 512; l2++) {
156 pdpe = address_space_ldq_le(as, pdp_addr + l2 * 8, attrs, NULL);
157 if (!(pdpe & PG_PRESENT_MASK)) {
158 continue;
159 }
160
161 if (pdpe & PG_PSE_MASK) {
162 /* 1G pages, CR4.PSE is ignored */
163 print_pte(hmp, env, (l0 << 48) + (l1 << 39) + (l2 << 30),
164 pdpe, 0x3ffffc0000000ULL);
165 continue;
166 }
167
168 pd_addr = pdpe & 0x3fffffffff000ULL;
169 for (l3 = 0; l3 < 512; l3++) {
170 pde = address_space_ldq_le(as, pd_addr + l3 * 8, attrs, NULL);
171 if (!(pde & PG_PRESENT_MASK)) {
172 continue;
173 }
174
175 if (pde & PG_PSE_MASK) {
176 /* 2M pages, CR4.PSE is ignored */
177 print_pte(hmp, env, (l0 << 48) + (l1 << 39) + (l2 << 30) +
178 (l3 << 21), pde, 0x3ffffffe00000ULL);
179 continue;
180 }
181
182 pt_addr = pde & 0x3fffffffff000ULL;
183 for (l4 = 0; l4 < 512; l4++) {
184 pte = address_space_ldq_le(as, pt_addr + l4 * 8,
185 attrs, NULL);
186 if (pte & PG_PRESENT_MASK) {
187 print_pte(hmp, env, (l0 << 48) + (l1 << 39) +
188 (l2 << 30) + (l3 << 21) + (l4 << 12),
189 pte & ~PG_PSE_MASK, 0x3fffffffff000ULL);
190 }
191 }
192 }
193 }
194 }
195 }
196
197 static void tlb_info_la57(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
198 {
199 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
200 uint64_t l0;
201 uint64_t pml5e;
202 uint64_t pml5_addr;
203
204 pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
205 for (l0 = 0; l0 < 512; l0++) {
206 pml5e = address_space_ldq_le(as, pml5_addr + l0 * 8, attrs, NULL);
207 if (pml5e & PG_PRESENT_MASK) {
208 tlb_info_la48(hmp, env, as, l0, pml5e & 0x3fffffffff000ULL);
209 }
210 }
211 }
212 #endif /* TARGET_X86_64 */
213
214 void hmp_info_tlb(MonitorHMP *hmp, const QDict *qdict)
215 {
216 CPUArchState *env;
217 AddressSpace *as;
218
219 env = monitor_hmp_get_cpu_env(hmp);
220 if (!env) {
221 monitor_hmp_printf(hmp, "No CPU available\n");
222 return;
223 }
224
225 if (!(env->cr[0] & CR0_PG_MASK)) {
226 monitor_hmp_printf(hmp, "PG disabled\n");
227 return;
228 }
229 as = cpu_get_address_space(env_cpu(env), X86ASIdx_MEM);
230 if (env->cr[4] & CR4_PAE_MASK) {
231 #ifdef TARGET_X86_64
232 if (env->hflags & HF_LMA_MASK) {
233 if (env->cr[4] & CR4_LA57_MASK) {
234 tlb_info_la57(hmp, env, as);
235 } else {
236 tlb_info_la48(hmp, env, as, 0, env->cr[3] & 0x3fffffffff000ULL);
237 }
238 } else
239 #endif
240 {
241 tlb_info_pae32(hmp, env, as);
242 }
243 } else {
244 tlb_info_32(hmp, env, as);
245 }
246 }
247
248 static void mem_print(MonitorHMP *hmp, CPUArchState *env,
249 hwaddr *pstart, int *plast_prot,
250 hwaddr end, int prot)
251 {
252 int prot1;
253 prot1 = *plast_prot;
254 if (prot != prot1) {
255 if (*pstart != -1) {
256 monitor_hmp_printf(hmp, HWADDR_FMT_plx "-" HWADDR_FMT_plx " "
257 HWADDR_FMT_plx " %c%c%c\n",
258 addr_canonical(env, *pstart),
259 addr_canonical(env, end),
260 addr_canonical(env, end - *pstart),
261 prot1 & PG_USER_MASK ? 'u' : '-',
262 'r',
263 prot1 & PG_RW_MASK ? 'w' : '-');
264 }
265 if (prot != 0)
266 *pstart = end;
267 else
268 *pstart = -1;
269 *plast_prot = prot;
270 }
271 }
272
273 static void mem_info_32(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
274 {
275 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
276 unsigned int l1, l2;
277 int prot, last_prot;
278 uint32_t pgd, pde, pte;
279 hwaddr start, end;
280
281 pgd = env->cr[3] & ~0xfff;
282 last_prot = 0;
283 start = -1;
284 for(l1 = 0; l1 < 1024; l1++) {
285 pde = address_space_ldl_le(as, pgd + l1 * 4, attrs, NULL);
286 end = l1 << 22;
287 if (pde & PG_PRESENT_MASK) {
288 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
289 prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
290 mem_print(hmp, env, &start, &last_prot, end, prot);
291 } else {
292 for(l2 = 0; l2 < 1024; l2++) {
293 pte = address_space_ldl_le(as, (pde & ~0xfff) + l2 * 4,
294 attrs, NULL);
295 end = (l1 << 22) + (l2 << 12);
296 if (pte & PG_PRESENT_MASK) {
297 prot = pte & pde &
298 (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
299 } else {
300 prot = 0;
301 }
302 mem_print(hmp, env, &start, &last_prot, end, prot);
303 }
304 }
305 } else {
306 prot = 0;
307 mem_print(hmp, env, &start, &last_prot, end, prot);
308 }
309 }
310 /* Flush last range */
311 mem_print(hmp, env, &start, &last_prot, (hwaddr)1 << 32, 0);
312 }
313
314 static void mem_info_pae32(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
315 {
316 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
317 unsigned int l1, l2, l3;
318 int prot, last_prot;
319 uint64_t pdpe, pde, pte;
320 uint64_t pdp_addr, pd_addr, pt_addr;
321 hwaddr start, end;
322
323 pdp_addr = env->cr[3] & ~0x1f;
324 last_prot = 0;
325 start = -1;
326 for (l1 = 0; l1 < 4; l1++) {
327 pdpe = address_space_ldq_le(as, pdp_addr + l1 * 8, attrs, NULL);
328 end = l1 << 30;
329 if (pdpe & PG_PRESENT_MASK) {
330 pd_addr = pdpe & 0x3fffffffff000ULL;
331 for (l2 = 0; l2 < 512; l2++) {
332 pde = address_space_ldq_le(as, pd_addr + l2 * 8, attrs, NULL);
333 end = (l1 << 30) + (l2 << 21);
334 if (pde & PG_PRESENT_MASK) {
335 if (pde & PG_PSE_MASK) {
336 prot = pde & (PG_USER_MASK | PG_RW_MASK |
337 PG_PRESENT_MASK);
338 mem_print(hmp, env, &start, &last_prot, end, prot);
339 } else {
340 pt_addr = pde & 0x3fffffffff000ULL;
341 for (l3 = 0; l3 < 512; l3++) {
342 pte = address_space_ldq_le(as, pt_addr + l3 * 8,
343 attrs, NULL);
344 end = (l1 << 30) + (l2 << 21) + (l3 << 12);
345 if (pte & PG_PRESENT_MASK) {
346 prot = pte & pde & (PG_USER_MASK | PG_RW_MASK |
347 PG_PRESENT_MASK);
348 } else {
349 prot = 0;
350 }
351 mem_print(hmp, env, &start, &last_prot, end, prot);
352 }
353 }
354 } else {
355 prot = 0;
356 mem_print(hmp, env, &start, &last_prot, end, prot);
357 }
358 }
359 } else {
360 prot = 0;
361 mem_print(hmp, env, &start, &last_prot, end, prot);
362 }
363 }
364 /* Flush last range */
365 mem_print(hmp, env, &start, &last_prot, (hwaddr)1 << 32, 0);
366 }
367
368
369 #ifdef TARGET_X86_64
370 static void mem_info_la48(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
371 {
372 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
373 int prot, last_prot;
374 uint64_t l1, l2, l3, l4;
375 uint64_t pml4e, pdpe, pde, pte;
376 uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
377
378 pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
379 last_prot = 0;
380 start = -1;
381 for (l1 = 0; l1 < 512; l1++) {
382 pml4e = address_space_ldq_le(as, pml4_addr + l1 * 8, attrs, NULL);
383 end = l1 << 39;
384 if (pml4e & PG_PRESENT_MASK) {
385 pdp_addr = pml4e & 0x3fffffffff000ULL;
386 for (l2 = 0; l2 < 512; l2++) {
387 pdpe = address_space_ldq_le(as, pdp_addr + l2 * 8, attrs, NULL);
388 end = (l1 << 39) + (l2 << 30);
389 if (pdpe & PG_PRESENT_MASK) {
390 if (pdpe & PG_PSE_MASK) {
391 prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
392 PG_PRESENT_MASK);
393 prot &= pml4e;
394 mem_print(hmp, env, &start, &last_prot, end, prot);
395 } else {
396 pd_addr = pdpe & 0x3fffffffff000ULL;
397 for (l3 = 0; l3 < 512; l3++) {
398 pde = address_space_ldq_le(as, pd_addr + l3 * 8,
399 attrs, NULL);
400 end = (l1 << 39) + (l2 << 30) + (l3 << 21);
401 if (pde & PG_PRESENT_MASK) {
402 if (pde & PG_PSE_MASK) {
403 prot = pde & (PG_USER_MASK | PG_RW_MASK |
404 PG_PRESENT_MASK);
405 prot &= pml4e & pdpe;
406 mem_print(hmp, env, &start,
407 &last_prot, end, prot);
408 } else {
409 pt_addr = pde & 0x3fffffffff000ULL;
410 for (l4 = 0; l4 < 512; l4++) {
411 pte = address_space_ldq_le(as,
412 pt_addr
413 + l4 * 8,
414 attrs, NULL);
415 end = (l1 << 39) + (l2 << 30) +
416 (l3 << 21) + (l4 << 12);
417 if (pte & PG_PRESENT_MASK) {
418 prot = pte & (PG_USER_MASK | PG_RW_MASK |
419 PG_PRESENT_MASK);
420 prot &= pml4e & pdpe & pde;
421 } else {
422 prot = 0;
423 }
424 mem_print(hmp, env, &start,
425 &last_prot, end, prot);
426 }
427 }
428 } else {
429 prot = 0;
430 mem_print(hmp, env, &start,
431 &last_prot, end, prot);
432 }
433 }
434 }
435 } else {
436 prot = 0;
437 mem_print(hmp, env, &start, &last_prot, end, prot);
438 }
439 }
440 } else {
441 prot = 0;
442 mem_print(hmp, env, &start, &last_prot, end, prot);
443 }
444 }
445 /* Flush last range */
446 mem_print(hmp, env, &start, &last_prot, (hwaddr)1 << 48, 0);
447 }
448
449 static void mem_info_la57(MonitorHMP *hmp, CPUArchState *env, AddressSpace *as)
450 {
451 const MemTxAttrs attrs = MEMTXATTRS_UNSPECIFIED;
452 int prot, last_prot;
453 uint64_t l0, l1, l2, l3, l4;
454 uint64_t pml5e, pml4e, pdpe, pde, pte;
455 uint64_t pml5_addr, pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
456
457 pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
458 last_prot = 0;
459 start = -1;
460 for (l0 = 0; l0 < 512; l0++) {
461 pml5e = address_space_ldq_le(as, pml5_addr + l0 * 8, attrs, NULL);
462 end = l0 << 48;
463 if (!(pml5e & PG_PRESENT_MASK)) {
464 prot = 0;
465 mem_print(hmp, env, &start, &last_prot, end, prot);
466 continue;
467 }
468
469 pml4_addr = pml5e & 0x3fffffffff000ULL;
470 for (l1 = 0; l1 < 512; l1++) {
471 pml4e = address_space_ldq_le(as, pml4_addr + l1 * 8, attrs, NULL);
472 end = (l0 << 48) + (l1 << 39);
473 if (!(pml4e & PG_PRESENT_MASK)) {
474 prot = 0;
475 mem_print(hmp, env, &start, &last_prot, end, prot);
476 continue;
477 }
478
479 pdp_addr = pml4e & 0x3fffffffff000ULL;
480 for (l2 = 0; l2 < 512; l2++) {
481 pdpe = address_space_ldq_le(as, pdp_addr + l2 * 8, attrs, NULL);
482 end = (l0 << 48) + (l1 << 39) + (l2 << 30);
483 if (pdpe & PG_PRESENT_MASK) {
484 prot = 0;
485 mem_print(hmp, env, &start, &last_prot, end, prot);
486 continue;
487 }
488
489 if (pdpe & PG_PSE_MASK) {
490 prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
491 PG_PRESENT_MASK);
492 prot &= pml5e & pml4e;
493 mem_print(hmp, env, &start, &last_prot, end, prot);
494 continue;
495 }
496
497 pd_addr = pdpe & 0x3fffffffff000ULL;
498 for (l3 = 0; l3 < 512; l3++) {
499 pde = address_space_ldq_le(as, pd_addr + l3 * 8,
500 attrs, NULL);
501 end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21);
502 if (pde & PG_PRESENT_MASK) {
503 prot = 0;
504 mem_print(hmp, env, &start, &last_prot, end, prot);
505 continue;
506 }
507
508 if (pde & PG_PSE_MASK) {
509 prot = pde & (PG_USER_MASK | PG_RW_MASK |
510 PG_PRESENT_MASK);
511 prot &= pml5e & pml4e & pdpe;
512 mem_print(hmp, env, &start, &last_prot, end, prot);
513 continue;
514 }
515
516 pt_addr = pde & 0x3fffffffff000ULL;
517 for (l4 = 0; l4 < 512; l4++) {
518 pte = address_space_ldq_le(as, pt_addr + l4 * 8,
519 attrs, NULL);
520 end = (l0 << 48) + (l1 << 39) + (l2 << 30) +
521 (l3 << 21) + (l4 << 12);
522 if (pte & PG_PRESENT_MASK) {
523 prot = pte & (PG_USER_MASK | PG_RW_MASK |
524 PG_PRESENT_MASK);
525 prot &= pml5e & pml4e & pdpe & pde;
526 } else {
527 prot = 0;
528 }
529 mem_print(hmp, env, &start, &last_prot, end, prot);
530 }
531 }
532 }
533 }
534 }
535 /* Flush last range */
536 mem_print(hmp, env, &start, &last_prot, (hwaddr)1 << 57, 0);
537 }
538 #endif /* TARGET_X86_64 */
539
540 void hmp_info_mem(MonitorHMP *hmp, const QDict *qdict)
541 {
542 CPUArchState *env;
543 AddressSpace *as;
544
545 env = monitor_hmp_get_cpu_env(hmp);
546 if (!env) {
547 monitor_hmp_printf(hmp, "No CPU available\n");
548 return;
549 }
550
551 if (!(env->cr[0] & CR0_PG_MASK)) {
552 monitor_hmp_printf(hmp, "PG disabled\n");
553 return;
554 }
555 as = cpu_get_address_space(env_cpu(env), X86ASIdx_MEM);
556 if (env->cr[4] & CR4_PAE_MASK) {
557 #ifdef TARGET_X86_64
558 if (env->hflags & HF_LMA_MASK) {
559 if (env->cr[4] & CR4_LA57_MASK) {
560 mem_info_la57(hmp, env, as);
561 } else {
562 mem_info_la48(hmp, env, as);
563 }
564 } else
565 #endif
566 {
567 mem_info_pae32(hmp, env, as);
568 }
569 } else {
570 mem_info_32(hmp, env, as);
571 }
572 }
573
574 void hmp_mce(MonitorHMP *hmp, const QDict *qdict)
575 {
576 X86CPU *cpu;
577 CPUState *cs;
578 int cpu_index = qdict_get_int(qdict, "cpu_index");
579 int bank = qdict_get_int(qdict, "bank");
580 uint64_t status = qdict_get_int(qdict, "status");
581 uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
582 uint64_t addr = qdict_get_int(qdict, "addr");
583 uint64_t misc = qdict_get_int(qdict, "misc");
584 int flags = MCE_INJECT_UNCOND_AO;
585 Error *err = NULL;
586
587 if (qdict_get_try_bool(qdict, "broadcast", false)) {
588 flags |= MCE_INJECT_BROADCAST;
589 }
590 cs = qemu_get_cpu(cpu_index);
591 if (cs) {
592 cpu = X86_CPU(cs);
593 cpu_x86_inject_mce(cpu, bank, status, mcg_status, addr, misc,
594 flags, &err);
595 } else {
596 error_setg(&err, "Invalid CPU %d", cpu_index);
597 }
598 hmp_handle_error(hmp, err);
599 }
600 #endif