Merge tag 'ide-pull-request' of https://gitlab.com/jsnow/qemu into staging
[qemu.git] / target / i386 / monitor.c
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-target.h"
29 #include "monitor/hmp.h"
30 #include "qapi/qmp/qdict.h"
31 #include "sysemu/kvm.h"
32 #include "sysemu/sev.h"
33 #include "qapi/error.h"
34 #include "sev_i386.h"
35 #include "qapi/qapi-commands-misc-target.h"
36 #include "qapi/qapi-commands-misc.h"
37 #include "hw/i386/pc.h"
38
39 /* Perform linear address sign extension */
40 static hwaddr addr_canonical(CPUArchState *env, hwaddr addr)
41 {
42 #ifdef TARGET_X86_64
43 if (env->cr[4] & CR4_LA57_MASK) {
44 if (addr & (1ULL << 56)) {
45 addr |= (hwaddr)-(1LL << 57);
46 }
47 } else {
48 if (addr & (1ULL << 47)) {
49 addr |= (hwaddr)-(1LL << 48);
50 }
51 }
52 #endif
53 return addr;
54 }
55
56 static void print_pte(Monitor *mon, CPUArchState *env, hwaddr addr,
57 hwaddr pte, hwaddr mask)
58 {
59 addr = addr_canonical(env, addr);
60
61 monitor_printf(mon, TARGET_FMT_plx ": " TARGET_FMT_plx
62 " %c%c%c%c%c%c%c%c%c\n",
63 addr,
64 pte & mask,
65 pte & PG_NX_MASK ? 'X' : '-',
66 pte & PG_GLOBAL_MASK ? 'G' : '-',
67 pte & PG_PSE_MASK ? 'P' : '-',
68 pte & PG_DIRTY_MASK ? 'D' : '-',
69 pte & PG_ACCESSED_MASK ? 'A' : '-',
70 pte & PG_PCD_MASK ? 'C' : '-',
71 pte & PG_PWT_MASK ? 'T' : '-',
72 pte & PG_USER_MASK ? 'U' : '-',
73 pte & PG_RW_MASK ? 'W' : '-');
74 }
75
76 static void tlb_info_32(Monitor *mon, CPUArchState *env)
77 {
78 unsigned int l1, l2;
79 uint32_t pgd, pde, pte;
80
81 pgd = env->cr[3] & ~0xfff;
82 for(l1 = 0; l1 < 1024; l1++) {
83 cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
84 pde = le32_to_cpu(pde);
85 if (pde & PG_PRESENT_MASK) {
86 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
87 /* 4M pages */
88 print_pte(mon, env, (l1 << 22), pde, ~((1 << 21) - 1));
89 } else {
90 for(l2 = 0; l2 < 1024; l2++) {
91 cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
92 pte = le32_to_cpu(pte);
93 if (pte & PG_PRESENT_MASK) {
94 print_pte(mon, env, (l1 << 22) + (l2 << 12),
95 pte & ~PG_PSE_MASK,
96 ~0xfff);
97 }
98 }
99 }
100 }
101 }
102 }
103
104 static void tlb_info_pae32(Monitor *mon, CPUArchState *env)
105 {
106 unsigned int l1, l2, l3;
107 uint64_t pdpe, pde, pte;
108 uint64_t pdp_addr, pd_addr, pt_addr;
109
110 pdp_addr = env->cr[3] & ~0x1f;
111 for (l1 = 0; l1 < 4; l1++) {
112 cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
113 pdpe = le64_to_cpu(pdpe);
114 if (pdpe & PG_PRESENT_MASK) {
115 pd_addr = pdpe & 0x3fffffffff000ULL;
116 for (l2 = 0; l2 < 512; l2++) {
117 cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
118 pde = le64_to_cpu(pde);
119 if (pde & PG_PRESENT_MASK) {
120 if (pde & PG_PSE_MASK) {
121 /* 2M pages with PAE, CR4.PSE is ignored */
122 print_pte(mon, env, (l1 << 30) + (l2 << 21), pde,
123 ~((hwaddr)(1 << 20) - 1));
124 } else {
125 pt_addr = pde & 0x3fffffffff000ULL;
126 for (l3 = 0; l3 < 512; l3++) {
127 cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
128 pte = le64_to_cpu(pte);
129 if (pte & PG_PRESENT_MASK) {
130 print_pte(mon, env, (l1 << 30) + (l2 << 21)
131 + (l3 << 12),
132 pte & ~PG_PSE_MASK,
133 ~(hwaddr)0xfff);
134 }
135 }
136 }
137 }
138 }
139 }
140 }
141 }
142
143 #ifdef TARGET_X86_64
144 static void tlb_info_la48(Monitor *mon, CPUArchState *env,
145 uint64_t l0, uint64_t pml4_addr)
146 {
147 uint64_t l1, l2, l3, l4;
148 uint64_t pml4e, pdpe, pde, pte;
149 uint64_t pdp_addr, pd_addr, pt_addr;
150
151 for (l1 = 0; l1 < 512; l1++) {
152 cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
153 pml4e = le64_to_cpu(pml4e);
154 if (!(pml4e & PG_PRESENT_MASK)) {
155 continue;
156 }
157
158 pdp_addr = pml4e & 0x3fffffffff000ULL;
159 for (l2 = 0; l2 < 512; l2++) {
160 cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
161 pdpe = le64_to_cpu(pdpe);
162 if (!(pdpe & PG_PRESENT_MASK)) {
163 continue;
164 }
165
166 if (pdpe & PG_PSE_MASK) {
167 /* 1G pages, CR4.PSE is ignored */
168 print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30),
169 pdpe, 0x3ffffc0000000ULL);
170 continue;
171 }
172
173 pd_addr = pdpe & 0x3fffffffff000ULL;
174 for (l3 = 0; l3 < 512; l3++) {
175 cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
176 pde = le64_to_cpu(pde);
177 if (!(pde & PG_PRESENT_MASK)) {
178 continue;
179 }
180
181 if (pde & PG_PSE_MASK) {
182 /* 2M pages, CR4.PSE is ignored */
183 print_pte(mon, env, (l0 << 48) + (l1 << 39) + (l2 << 30) +
184 (l3 << 21), pde, 0x3ffffffe00000ULL);
185 continue;
186 }
187
188 pt_addr = pde & 0x3fffffffff000ULL;
189 for (l4 = 0; l4 < 512; l4++) {
190 cpu_physical_memory_read(pt_addr
191 + l4 * 8,
192 &pte, 8);
193 pte = le64_to_cpu(pte);
194 if (pte & PG_PRESENT_MASK) {
195 print_pte(mon, env, (l0 << 48) + (l1 << 39) +
196 (l2 << 30) + (l3 << 21) + (l4 << 12),
197 pte & ~PG_PSE_MASK, 0x3fffffffff000ULL);
198 }
199 }
200 }
201 }
202 }
203 }
204
205 static void tlb_info_la57(Monitor *mon, CPUArchState *env)
206 {
207 uint64_t l0;
208 uint64_t pml5e;
209 uint64_t pml5_addr;
210
211 pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
212 for (l0 = 0; l0 < 512; l0++) {
213 cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8);
214 pml5e = le64_to_cpu(pml5e);
215 if (pml5e & PG_PRESENT_MASK) {
216 tlb_info_la48(mon, env, l0, pml5e & 0x3fffffffff000ULL);
217 }
218 }
219 }
220 #endif /* TARGET_X86_64 */
221
222 void hmp_info_tlb(Monitor *mon, const QDict *qdict)
223 {
224 CPUArchState *env;
225
226 env = mon_get_cpu_env(mon);
227 if (!env) {
228 monitor_printf(mon, "No CPU available\n");
229 return;
230 }
231
232 if (!(env->cr[0] & CR0_PG_MASK)) {
233 monitor_printf(mon, "PG disabled\n");
234 return;
235 }
236 if (env->cr[4] & CR4_PAE_MASK) {
237 #ifdef TARGET_X86_64
238 if (env->hflags & HF_LMA_MASK) {
239 if (env->cr[4] & CR4_LA57_MASK) {
240 tlb_info_la57(mon, env);
241 } else {
242 tlb_info_la48(mon, env, 0, env->cr[3] & 0x3fffffffff000ULL);
243 }
244 } else
245 #endif
246 {
247 tlb_info_pae32(mon, env);
248 }
249 } else {
250 tlb_info_32(mon, env);
251 }
252 }
253
254 static void mem_print(Monitor *mon, CPUArchState *env,
255 hwaddr *pstart, int *plast_prot,
256 hwaddr end, int prot)
257 {
258 int prot1;
259 prot1 = *plast_prot;
260 if (prot != prot1) {
261 if (*pstart != -1) {
262 monitor_printf(mon, TARGET_FMT_plx "-" TARGET_FMT_plx " "
263 TARGET_FMT_plx " %c%c%c\n",
264 addr_canonical(env, *pstart),
265 addr_canonical(env, end),
266 addr_canonical(env, end - *pstart),
267 prot1 & PG_USER_MASK ? 'u' : '-',
268 'r',
269 prot1 & PG_RW_MASK ? 'w' : '-');
270 }
271 if (prot != 0)
272 *pstart = end;
273 else
274 *pstart = -1;
275 *plast_prot = prot;
276 }
277 }
278
279 static void mem_info_32(Monitor *mon, CPUArchState *env)
280 {
281 unsigned int l1, l2;
282 int prot, last_prot;
283 uint32_t pgd, pde, pte;
284 hwaddr start, end;
285
286 pgd = env->cr[3] & ~0xfff;
287 last_prot = 0;
288 start = -1;
289 for(l1 = 0; l1 < 1024; l1++) {
290 cpu_physical_memory_read(pgd + l1 * 4, &pde, 4);
291 pde = le32_to_cpu(pde);
292 end = l1 << 22;
293 if (pde & PG_PRESENT_MASK) {
294 if ((pde & PG_PSE_MASK) && (env->cr[4] & CR4_PSE_MASK)) {
295 prot = pde & (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
296 mem_print(mon, env, &start, &last_prot, end, prot);
297 } else {
298 for(l2 = 0; l2 < 1024; l2++) {
299 cpu_physical_memory_read((pde & ~0xfff) + l2 * 4, &pte, 4);
300 pte = le32_to_cpu(pte);
301 end = (l1 << 22) + (l2 << 12);
302 if (pte & PG_PRESENT_MASK) {
303 prot = pte & pde &
304 (PG_USER_MASK | PG_RW_MASK | PG_PRESENT_MASK);
305 } else {
306 prot = 0;
307 }
308 mem_print(mon, env, &start, &last_prot, end, prot);
309 }
310 }
311 } else {
312 prot = 0;
313 mem_print(mon, env, &start, &last_prot, end, prot);
314 }
315 }
316 /* Flush last range */
317 mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 32, 0);
318 }
319
320 static void mem_info_pae32(Monitor *mon, CPUArchState *env)
321 {
322 unsigned int l1, l2, l3;
323 int prot, last_prot;
324 uint64_t pdpe, pde, pte;
325 uint64_t pdp_addr, pd_addr, pt_addr;
326 hwaddr start, end;
327
328 pdp_addr = env->cr[3] & ~0x1f;
329 last_prot = 0;
330 start = -1;
331 for (l1 = 0; l1 < 4; l1++) {
332 cpu_physical_memory_read(pdp_addr + l1 * 8, &pdpe, 8);
333 pdpe = le64_to_cpu(pdpe);
334 end = l1 << 30;
335 if (pdpe & PG_PRESENT_MASK) {
336 pd_addr = pdpe & 0x3fffffffff000ULL;
337 for (l2 = 0; l2 < 512; l2++) {
338 cpu_physical_memory_read(pd_addr + l2 * 8, &pde, 8);
339 pde = le64_to_cpu(pde);
340 end = (l1 << 30) + (l2 << 21);
341 if (pde & PG_PRESENT_MASK) {
342 if (pde & PG_PSE_MASK) {
343 prot = pde & (PG_USER_MASK | PG_RW_MASK |
344 PG_PRESENT_MASK);
345 mem_print(mon, env, &start, &last_prot, end, prot);
346 } else {
347 pt_addr = pde & 0x3fffffffff000ULL;
348 for (l3 = 0; l3 < 512; l3++) {
349 cpu_physical_memory_read(pt_addr + l3 * 8, &pte, 8);
350 pte = le64_to_cpu(pte);
351 end = (l1 << 30) + (l2 << 21) + (l3 << 12);
352 if (pte & PG_PRESENT_MASK) {
353 prot = pte & pde & (PG_USER_MASK | PG_RW_MASK |
354 PG_PRESENT_MASK);
355 } else {
356 prot = 0;
357 }
358 mem_print(mon, env, &start, &last_prot, end, prot);
359 }
360 }
361 } else {
362 prot = 0;
363 mem_print(mon, env, &start, &last_prot, end, prot);
364 }
365 }
366 } else {
367 prot = 0;
368 mem_print(mon, env, &start, &last_prot, end, prot);
369 }
370 }
371 /* Flush last range */
372 mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 32, 0);
373 }
374
375
376 #ifdef TARGET_X86_64
377 static void mem_info_la48(Monitor *mon, CPUArchState *env)
378 {
379 int prot, last_prot;
380 uint64_t l1, l2, l3, l4;
381 uint64_t pml4e, pdpe, pde, pte;
382 uint64_t pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
383
384 pml4_addr = env->cr[3] & 0x3fffffffff000ULL;
385 last_prot = 0;
386 start = -1;
387 for (l1 = 0; l1 < 512; l1++) {
388 cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
389 pml4e = le64_to_cpu(pml4e);
390 end = l1 << 39;
391 if (pml4e & PG_PRESENT_MASK) {
392 pdp_addr = pml4e & 0x3fffffffff000ULL;
393 for (l2 = 0; l2 < 512; l2++) {
394 cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
395 pdpe = le64_to_cpu(pdpe);
396 end = (l1 << 39) + (l2 << 30);
397 if (pdpe & PG_PRESENT_MASK) {
398 if (pdpe & PG_PSE_MASK) {
399 prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
400 PG_PRESENT_MASK);
401 prot &= pml4e;
402 mem_print(mon, env, &start, &last_prot, end, prot);
403 } else {
404 pd_addr = pdpe & 0x3fffffffff000ULL;
405 for (l3 = 0; l3 < 512; l3++) {
406 cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
407 pde = le64_to_cpu(pde);
408 end = (l1 << 39) + (l2 << 30) + (l3 << 21);
409 if (pde & PG_PRESENT_MASK) {
410 if (pde & PG_PSE_MASK) {
411 prot = pde & (PG_USER_MASK | PG_RW_MASK |
412 PG_PRESENT_MASK);
413 prot &= pml4e & pdpe;
414 mem_print(mon, env, &start,
415 &last_prot, end, prot);
416 } else {
417 pt_addr = pde & 0x3fffffffff000ULL;
418 for (l4 = 0; l4 < 512; l4++) {
419 cpu_physical_memory_read(pt_addr
420 + l4 * 8,
421 &pte, 8);
422 pte = le64_to_cpu(pte);
423 end = (l1 << 39) + (l2 << 30) +
424 (l3 << 21) + (l4 << 12);
425 if (pte & PG_PRESENT_MASK) {
426 prot = pte & (PG_USER_MASK | PG_RW_MASK |
427 PG_PRESENT_MASK);
428 prot &= pml4e & pdpe & pde;
429 } else {
430 prot = 0;
431 }
432 mem_print(mon, env, &start,
433 &last_prot, end, prot);
434 }
435 }
436 } else {
437 prot = 0;
438 mem_print(mon, env, &start,
439 &last_prot, end, prot);
440 }
441 }
442 }
443 } else {
444 prot = 0;
445 mem_print(mon, env, &start, &last_prot, end, prot);
446 }
447 }
448 } else {
449 prot = 0;
450 mem_print(mon, env, &start, &last_prot, end, prot);
451 }
452 }
453 /* Flush last range */
454 mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 48, 0);
455 }
456
457 static void mem_info_la57(Monitor *mon, CPUArchState *env)
458 {
459 int prot, last_prot;
460 uint64_t l0, l1, l2, l3, l4;
461 uint64_t pml5e, pml4e, pdpe, pde, pte;
462 uint64_t pml5_addr, pml4_addr, pdp_addr, pd_addr, pt_addr, start, end;
463
464 pml5_addr = env->cr[3] & 0x3fffffffff000ULL;
465 last_prot = 0;
466 start = -1;
467 for (l0 = 0; l0 < 512; l0++) {
468 cpu_physical_memory_read(pml5_addr + l0 * 8, &pml5e, 8);
469 pml5e = le64_to_cpu(pml5e);
470 end = l0 << 48;
471 if (!(pml5e & PG_PRESENT_MASK)) {
472 prot = 0;
473 mem_print(mon, env, &start, &last_prot, end, prot);
474 continue;
475 }
476
477 pml4_addr = pml5e & 0x3fffffffff000ULL;
478 for (l1 = 0; l1 < 512; l1++) {
479 cpu_physical_memory_read(pml4_addr + l1 * 8, &pml4e, 8);
480 pml4e = le64_to_cpu(pml4e);
481 end = (l0 << 48) + (l1 << 39);
482 if (!(pml4e & PG_PRESENT_MASK)) {
483 prot = 0;
484 mem_print(mon, env, &start, &last_prot, end, prot);
485 continue;
486 }
487
488 pdp_addr = pml4e & 0x3fffffffff000ULL;
489 for (l2 = 0; l2 < 512; l2++) {
490 cpu_physical_memory_read(pdp_addr + l2 * 8, &pdpe, 8);
491 pdpe = le64_to_cpu(pdpe);
492 end = (l0 << 48) + (l1 << 39) + (l2 << 30);
493 if (pdpe & PG_PRESENT_MASK) {
494 prot = 0;
495 mem_print(mon, env, &start, &last_prot, end, prot);
496 continue;
497 }
498
499 if (pdpe & PG_PSE_MASK) {
500 prot = pdpe & (PG_USER_MASK | PG_RW_MASK |
501 PG_PRESENT_MASK);
502 prot &= pml5e & pml4e;
503 mem_print(mon, env, &start, &last_prot, end, prot);
504 continue;
505 }
506
507 pd_addr = pdpe & 0x3fffffffff000ULL;
508 for (l3 = 0; l3 < 512; l3++) {
509 cpu_physical_memory_read(pd_addr + l3 * 8, &pde, 8);
510 pde = le64_to_cpu(pde);
511 end = (l0 << 48) + (l1 << 39) + (l2 << 30) + (l3 << 21);
512 if (pde & PG_PRESENT_MASK) {
513 prot = 0;
514 mem_print(mon, env, &start, &last_prot, end, prot);
515 continue;
516 }
517
518 if (pde & PG_PSE_MASK) {
519 prot = pde & (PG_USER_MASK | PG_RW_MASK |
520 PG_PRESENT_MASK);
521 prot &= pml5e & pml4e & pdpe;
522 mem_print(mon, env, &start, &last_prot, end, prot);
523 continue;
524 }
525
526 pt_addr = pde & 0x3fffffffff000ULL;
527 for (l4 = 0; l4 < 512; l4++) {
528 cpu_physical_memory_read(pt_addr + l4 * 8, &pte, 8);
529 pte = le64_to_cpu(pte);
530 end = (l0 << 48) + (l1 << 39) + (l2 << 30) +
531 (l3 << 21) + (l4 << 12);
532 if (pte & PG_PRESENT_MASK) {
533 prot = pte & (PG_USER_MASK | PG_RW_MASK |
534 PG_PRESENT_MASK);
535 prot &= pml5e & pml4e & pdpe & pde;
536 } else {
537 prot = 0;
538 }
539 mem_print(mon, env, &start, &last_prot, end, prot);
540 }
541 }
542 }
543 }
544 }
545 /* Flush last range */
546 mem_print(mon, env, &start, &last_prot, (hwaddr)1 << 57, 0);
547 }
548 #endif /* TARGET_X86_64 */
549
550 void hmp_info_mem(Monitor *mon, const QDict *qdict)
551 {
552 CPUArchState *env;
553
554 env = mon_get_cpu_env(mon);
555 if (!env) {
556 monitor_printf(mon, "No CPU available\n");
557 return;
558 }
559
560 if (!(env->cr[0] & CR0_PG_MASK)) {
561 monitor_printf(mon, "PG disabled\n");
562 return;
563 }
564 if (env->cr[4] & CR4_PAE_MASK) {
565 #ifdef TARGET_X86_64
566 if (env->hflags & HF_LMA_MASK) {
567 if (env->cr[4] & CR4_LA57_MASK) {
568 mem_info_la57(mon, env);
569 } else {
570 mem_info_la48(mon, env);
571 }
572 } else
573 #endif
574 {
575 mem_info_pae32(mon, env);
576 }
577 } else {
578 mem_info_32(mon, env);
579 }
580 }
581
582 void hmp_mce(Monitor *mon, const QDict *qdict)
583 {
584 X86CPU *cpu;
585 CPUState *cs;
586 int cpu_index = qdict_get_int(qdict, "cpu_index");
587 int bank = qdict_get_int(qdict, "bank");
588 uint64_t status = qdict_get_int(qdict, "status");
589 uint64_t mcg_status = qdict_get_int(qdict, "mcg_status");
590 uint64_t addr = qdict_get_int(qdict, "addr");
591 uint64_t misc = qdict_get_int(qdict, "misc");
592 int flags = MCE_INJECT_UNCOND_AO;
593
594 if (qdict_get_try_bool(qdict, "broadcast", false)) {
595 flags |= MCE_INJECT_BROADCAST;
596 }
597 cs = qemu_get_cpu(cpu_index);
598 if (cs != NULL) {
599 cpu = X86_CPU(cs);
600 cpu_x86_inject_mce(mon, cpu, bank, status, mcg_status, addr, misc,
601 flags);
602 }
603 }
604
605 static target_long monitor_get_pc(Monitor *mon, const struct MonitorDef *md,
606 int val)
607 {
608 CPUArchState *env = mon_get_cpu_env(mon);
609 return env->eip + env->segs[R_CS].base;
610 }
611
612 const MonitorDef monitor_defs[] = {
613 #define SEG(name, seg) \
614 { name, offsetof(CPUX86State, segs[seg].selector), NULL, MD_I32 },\
615 { name ".base", offsetof(CPUX86State, segs[seg].base) },\
616 { name ".limit", offsetof(CPUX86State, segs[seg].limit), NULL, MD_I32 },
617
618 { "eax", offsetof(CPUX86State, regs[0]) },
619 { "ecx", offsetof(CPUX86State, regs[1]) },
620 { "edx", offsetof(CPUX86State, regs[2]) },
621 { "ebx", offsetof(CPUX86State, regs[3]) },
622 { "esp|sp", offsetof(CPUX86State, regs[4]) },
623 { "ebp|fp", offsetof(CPUX86State, regs[5]) },
624 { "esi", offsetof(CPUX86State, regs[6]) },
625 { "edi", offsetof(CPUX86State, regs[7]) },
626 #ifdef TARGET_X86_64
627 { "r8", offsetof(CPUX86State, regs[8]) },
628 { "r9", offsetof(CPUX86State, regs[9]) },
629 { "r10", offsetof(CPUX86State, regs[10]) },
630 { "r11", offsetof(CPUX86State, regs[11]) },
631 { "r12", offsetof(CPUX86State, regs[12]) },
632 { "r13", offsetof(CPUX86State, regs[13]) },
633 { "r14", offsetof(CPUX86State, regs[14]) },
634 { "r15", offsetof(CPUX86State, regs[15]) },
635 #endif
636 { "eflags", offsetof(CPUX86State, eflags) },
637 { "eip", offsetof(CPUX86State, eip) },
638 SEG("cs", R_CS)
639 SEG("ds", R_DS)
640 SEG("es", R_ES)
641 SEG("ss", R_SS)
642 SEG("fs", R_FS)
643 SEG("gs", R_GS)
644 { "pc", 0, monitor_get_pc, },
645 { NULL },
646 };
647
648 const MonitorDef *target_monitor_defs(void)
649 {
650 return monitor_defs;
651 }
652
653 void hmp_info_local_apic(Monitor *mon, const QDict *qdict)
654 {
655 CPUState *cs;
656
657 if (qdict_haskey(qdict, "apic-id")) {
658 int id = qdict_get_try_int(qdict, "apic-id", 0);
659 cs = cpu_by_arch_id(id);
660 } else {
661 cs = mon_get_cpu(mon);
662 }
663
664
665 if (!cs) {
666 monitor_printf(mon, "No CPU available\n");
667 return;
668 }
669 x86_cpu_dump_local_apic_state(cs, CPU_DUMP_FPU);
670 }
671
672 void hmp_info_io_apic(Monitor *mon, const QDict *qdict)
673 {
674 monitor_printf(mon, "This command is obsolete and will be "
675 "removed soon. Please use 'info pic' instead.\n");
676 }
677
678 SevInfo *qmp_query_sev(Error **errp)
679 {
680 SevInfo *info;
681
682 info = sev_get_info();
683 if (!info) {
684 error_setg(errp, "SEV feature is not available");
685 return NULL;
686 }
687
688 return info;
689 }
690
691 void hmp_info_sev(Monitor *mon, const QDict *qdict)
692 {
693 SevInfo *info = sev_get_info();
694
695 if (info && info->enabled) {
696 monitor_printf(mon, "handle: %d\n", info->handle);
697 monitor_printf(mon, "state: %s\n", SevState_str(info->state));
698 monitor_printf(mon, "build: %d\n", info->build_id);
699 monitor_printf(mon, "api version: %d.%d\n",
700 info->api_major, info->api_minor);
701 monitor_printf(mon, "debug: %s\n",
702 info->policy & SEV_POLICY_NODBG ? "off" : "on");
703 monitor_printf(mon, "key-sharing: %s\n",
704 info->policy & SEV_POLICY_NOKS ? "off" : "on");
705 } else {
706 monitor_printf(mon, "SEV is not enabled\n");
707 }
708
709 qapi_free_SevInfo(info);
710 }
711
712 SevLaunchMeasureInfo *qmp_query_sev_launch_measure(Error **errp)
713 {
714 char *data;
715 SevLaunchMeasureInfo *info;
716
717 data = sev_get_launch_measurement();
718 if (!data) {
719 error_setg(errp, "Measurement is not available");
720 return NULL;
721 }
722
723 info = g_malloc0(sizeof(*info));
724 info->data = data;
725
726 return info;
727 }
728
729 SevCapability *qmp_query_sev_capabilities(Error **errp)
730 {
731 return sev_get_capabilities(errp);
732 }
733
734 #define SEV_SECRET_GUID "4c2eb361-7d9b-4cc3-8081-127c90d3d294"
735 struct sev_secret_area {
736 uint32_t base;
737 uint32_t size;
738 };
739
740 void qmp_sev_inject_launch_secret(const char *packet_hdr,
741 const char *secret,
742 bool has_gpa, uint64_t gpa,
743 Error **errp)
744 {
745 if (!has_gpa) {
746 uint8_t *data;
747 struct sev_secret_area *area;
748
749 if (!pc_system_ovmf_table_find(SEV_SECRET_GUID, &data, NULL)) {
750 error_setg(errp, "SEV: no secret area found in OVMF,"
751 " gpa must be specified.");
752 return;
753 }
754 area = (struct sev_secret_area *)data;
755 gpa = area->base;
756 }
757
758 sev_inject_launch_secret(packet_hdr, secret, gpa, errp);
759 }
760
761 SevAttestationReport *
762 qmp_query_sev_attestation_report(const char *mnonce, Error **errp)
763 {
764 return sev_get_attestation_report(mnonce, errp);
765 }