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