xref: /freebsd/sys/contrib/xen/arch-x86/hvm/save.h (revision 094517119c62c23369d545a7475ae982d86330a3)
1 /*
2  * Structure definitions for HVM state that is held by Xen and must
3  * be saved along with the domain's memory and device-model state.
4  *
5  * Copyright (c) 2007 XenSource Ltd.
6  *
7  * Permission is hereby granted, free of charge, to any person obtaining a copy
8  * of this software and associated documentation files (the "Software"), to
9  * deal in the Software without restriction, including without limitation the
10  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
11  * sell copies of the Software, and to permit persons to whom the Software is
12  * furnished to do so, subject to the following conditions:
13  *
14  * The above copyright notice and this permission notice shall be included in
15  * all copies or substantial portions of the Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23  * DEALINGS IN THE SOFTWARE.
24  */
25 
26 #ifndef __XEN_PUBLIC_HVM_SAVE_X86_H__
27 #define __XEN_PUBLIC_HVM_SAVE_X86_H__
28 
29 #include "../../xen.h"
30 
31 /*
32  * Save/restore header: general info about the save file.
33  */
34 
35 #define HVM_FILE_MAGIC   0x54381286
36 #define HVM_FILE_VERSION 0x00000001
37 
38 struct hvm_save_header {
39     uint32_t magic;             /* Must be HVM_FILE_MAGIC */
40     uint32_t version;           /* File format version */
41     uint64_t changeset;         /* Version of Xen that saved this file */
42     uint32_t cpuid;             /* CPUID[0x01][%eax] on the saving machine */
43     uint32_t gtsc_khz;        /* Guest's TSC frequency in kHz */
44 };
45 
46 DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);
47 
48 
49 /*
50  * Processor
51  *
52  * Compat:
53  *     - Pre-3.4 didn't have msr_tsc_aux
54  *     - Pre-4.7 didn't have fpu_initialised
55  */
56 
57 struct hvm_hw_cpu {
58     uint8_t  fpu_regs[512];
59 
60     uint64_t rax;
61     uint64_t rbx;
62     uint64_t rcx;
63     uint64_t rdx;
64     uint64_t rbp;
65     uint64_t rsi;
66     uint64_t rdi;
67     uint64_t rsp;
68     uint64_t r8;
69     uint64_t r9;
70     uint64_t r10;
71     uint64_t r11;
72     uint64_t r12;
73     uint64_t r13;
74     uint64_t r14;
75     uint64_t r15;
76 
77     uint64_t rip;
78     uint64_t rflags;
79 
80     uint64_t cr0;
81     uint64_t cr2;
82     uint64_t cr3;
83     uint64_t cr4;
84 
85     uint64_t dr0;
86     uint64_t dr1;
87     uint64_t dr2;
88     uint64_t dr3;
89     uint64_t dr6;
90     uint64_t dr7;
91 
92     uint32_t cs_sel;
93     uint32_t ds_sel;
94     uint32_t es_sel;
95     uint32_t fs_sel;
96     uint32_t gs_sel;
97     uint32_t ss_sel;
98     uint32_t tr_sel;
99     uint32_t ldtr_sel;
100 
101     uint32_t cs_limit;
102     uint32_t ds_limit;
103     uint32_t es_limit;
104     uint32_t fs_limit;
105     uint32_t gs_limit;
106     uint32_t ss_limit;
107     uint32_t tr_limit;
108     uint32_t ldtr_limit;
109     uint32_t idtr_limit;
110     uint32_t gdtr_limit;
111 
112     uint64_t cs_base;
113     uint64_t ds_base;
114     uint64_t es_base;
115     uint64_t fs_base;
116     uint64_t gs_base;
117     uint64_t ss_base;
118     uint64_t tr_base;
119     uint64_t ldtr_base;
120     uint64_t idtr_base;
121     uint64_t gdtr_base;
122 
123     uint32_t cs_arbytes;
124     uint32_t ds_arbytes;
125     uint32_t es_arbytes;
126     uint32_t fs_arbytes;
127     uint32_t gs_arbytes;
128     uint32_t ss_arbytes;
129     uint32_t tr_arbytes;
130     uint32_t ldtr_arbytes;
131 
132     uint64_t sysenter_cs;
133     uint64_t sysenter_esp;
134     uint64_t sysenter_eip;
135 
136     /* msr for em64t */
137     uint64_t shadow_gs;
138 
139     /* msr content saved/restored. */
140     uint64_t msr_flags; /* Obsolete, ignored. */
141     uint64_t msr_lstar;
142     uint64_t msr_star;
143     uint64_t msr_cstar;
144     uint64_t msr_syscall_mask;
145     uint64_t msr_efer;
146     uint64_t msr_tsc_aux;
147 
148     /* guest's idea of what rdtsc() would return */
149     uint64_t tsc;
150 
151     /* pending event, if any */
152     union {
153         uint32_t pending_event;
154         struct {
155             uint8_t  pending_vector:8;
156             uint8_t  pending_type:3;
157             uint8_t  pending_error_valid:1;
158             uint32_t pending_reserved:19;
159             uint8_t  pending_valid:1;
160         };
161     };
162     /* error code for pending event */
163     uint32_t error_code;
164 
165 #define _XEN_X86_FPU_INITIALISED        0
166 #define XEN_X86_FPU_INITIALISED         (1U<<_XEN_X86_FPU_INITIALISED)
167     uint32_t flags;
168     uint32_t pad0;
169 };
170 
171 struct hvm_hw_cpu_compat {
172     uint8_t  fpu_regs[512];
173 
174     uint64_t rax;
175     uint64_t rbx;
176     uint64_t rcx;
177     uint64_t rdx;
178     uint64_t rbp;
179     uint64_t rsi;
180     uint64_t rdi;
181     uint64_t rsp;
182     uint64_t r8;
183     uint64_t r9;
184     uint64_t r10;
185     uint64_t r11;
186     uint64_t r12;
187     uint64_t r13;
188     uint64_t r14;
189     uint64_t r15;
190 
191     uint64_t rip;
192     uint64_t rflags;
193 
194     uint64_t cr0;
195     uint64_t cr2;
196     uint64_t cr3;
197     uint64_t cr4;
198 
199     uint64_t dr0;
200     uint64_t dr1;
201     uint64_t dr2;
202     uint64_t dr3;
203     uint64_t dr6;
204     uint64_t dr7;
205 
206     uint32_t cs_sel;
207     uint32_t ds_sel;
208     uint32_t es_sel;
209     uint32_t fs_sel;
210     uint32_t gs_sel;
211     uint32_t ss_sel;
212     uint32_t tr_sel;
213     uint32_t ldtr_sel;
214 
215     uint32_t cs_limit;
216     uint32_t ds_limit;
217     uint32_t es_limit;
218     uint32_t fs_limit;
219     uint32_t gs_limit;
220     uint32_t ss_limit;
221     uint32_t tr_limit;
222     uint32_t ldtr_limit;
223     uint32_t idtr_limit;
224     uint32_t gdtr_limit;
225 
226     uint64_t cs_base;
227     uint64_t ds_base;
228     uint64_t es_base;
229     uint64_t fs_base;
230     uint64_t gs_base;
231     uint64_t ss_base;
232     uint64_t tr_base;
233     uint64_t ldtr_base;
234     uint64_t idtr_base;
235     uint64_t gdtr_base;
236 
237     uint32_t cs_arbytes;
238     uint32_t ds_arbytes;
239     uint32_t es_arbytes;
240     uint32_t fs_arbytes;
241     uint32_t gs_arbytes;
242     uint32_t ss_arbytes;
243     uint32_t tr_arbytes;
244     uint32_t ldtr_arbytes;
245 
246     uint64_t sysenter_cs;
247     uint64_t sysenter_esp;
248     uint64_t sysenter_eip;
249 
250     /* msr for em64t */
251     uint64_t shadow_gs;
252 
253     /* msr content saved/restored. */
254     uint64_t msr_flags; /* Obsolete, ignored. */
255     uint64_t msr_lstar;
256     uint64_t msr_star;
257     uint64_t msr_cstar;
258     uint64_t msr_syscall_mask;
259     uint64_t msr_efer;
260     /*uint64_t msr_tsc_aux; COMPAT */
261 
262     /* guest's idea of what rdtsc() would return */
263     uint64_t tsc;
264 
265     /* pending event, if any */
266     union {
267         uint32_t pending_event;
268         struct {
269             uint8_t  pending_vector:8;
270             uint8_t  pending_type:3;
271             uint8_t  pending_error_valid:1;
272             uint32_t pending_reserved:19;
273             uint8_t  pending_valid:1;
274         };
275     };
276     /* error code for pending event */
277     uint32_t error_code;
278 };
279 
280 static inline int _hvm_hw_fix_cpu(void *h, uint32_t size) {
281 
282     union hvm_hw_cpu_union {
283         struct hvm_hw_cpu nat;
284         struct hvm_hw_cpu_compat cmp;
285     } *ucpu = (union hvm_hw_cpu_union *)h;
286 
287     if ( size == sizeof(struct hvm_hw_cpu_compat) )
288     {
289         /*
290          * If we copy from the end backwards, we should
291          * be able to do the modification in-place.
292          */
293         ucpu->nat.error_code = ucpu->cmp.error_code;
294         ucpu->nat.pending_event = ucpu->cmp.pending_event;
295         ucpu->nat.tsc = ucpu->cmp.tsc;
296         ucpu->nat.msr_tsc_aux = 0;
297     }
298     /* Mimic the old behaviour by unconditionally setting fpu_initialised. */
299     ucpu->nat.flags = XEN_X86_FPU_INITIALISED;
300 
301     return 0;
302 }
303 
304 DECLARE_HVM_SAVE_TYPE_COMPAT(CPU, 2, struct hvm_hw_cpu, \
305                              struct hvm_hw_cpu_compat, _hvm_hw_fix_cpu);
306 
307 /*
308  * PIC
309  */
310 
311 struct hvm_hw_vpic {
312     /* IR line bitmasks. */
313     uint8_t irr;
314     uint8_t imr;
315     uint8_t isr;
316 
317     /* Line IRx maps to IRQ irq_base+x */
318     uint8_t irq_base;
319 
320     /*
321      * Where are we in ICW2-4 initialisation (0 means no init in progress)?
322      * Bits 0-1 (=x): Next write at A=1 sets ICW(x+1).
323      * Bit 2: ICW1.IC4  (1 == ICW4 included in init sequence)
324      * Bit 3: ICW1.SNGL (0 == ICW3 included in init sequence)
325      */
326     uint8_t init_state:4;
327 
328     /* IR line with highest priority. */
329     uint8_t priority_add:4;
330 
331     /* Reads from A=0 obtain ISR or IRR? */
332     uint8_t readsel_isr:1;
333 
334     /* Reads perform a polling read? */
335     uint8_t poll:1;
336 
337     /* Automatically clear IRQs from the ISR during INTA? */
338     uint8_t auto_eoi:1;
339 
340     /* Automatically rotate IRQ priorities during AEOI? */
341     uint8_t rotate_on_auto_eoi:1;
342 
343     /* Exclude slave inputs when considering in-service IRQs? */
344     uint8_t special_fully_nested_mode:1;
345 
346     /* Special mask mode excludes masked IRs from AEOI and priority checks. */
347     uint8_t special_mask_mode:1;
348 
349     /* Is this a master PIC or slave PIC? (NB. This is not programmable.) */
350     uint8_t is_master:1;
351 
352     /* Edge/trigger selection. */
353     uint8_t elcr;
354 
355     /* Virtual INT output. */
356     uint8_t int_output;
357 };
358 
359 DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);
360 
361 
362 /*
363  * IO-APIC
364  */
365 
366 union vioapic_redir_entry
367 {
368     uint64_t bits;
369     struct {
370         uint8_t vector;
371         uint8_t delivery_mode:3;
372         uint8_t dest_mode:1;
373         uint8_t delivery_status:1;
374         uint8_t polarity:1;
375         uint8_t remote_irr:1;
376         uint8_t trig_mode:1;
377         uint8_t mask:1;
378         uint8_t reserve:7;
379         uint8_t reserved[4];
380         uint8_t dest_id;
381     } fields;
382 };
383 
384 #define VIOAPIC_NUM_PINS  48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */
385 
386 #define XEN_HVM_VIOAPIC(name, cnt)                      \
387     struct name {                                       \
388         uint64_t base_address;                          \
389         uint32_t ioregsel;                              \
390         uint32_t id;                                    \
391         union vioapic_redir_entry redirtbl[cnt];        \
392     }
393 
394 XEN_HVM_VIOAPIC(hvm_hw_vioapic, VIOAPIC_NUM_PINS);
395 
396 #ifndef __XEN__
397 #undef XEN_HVM_VIOAPIC
398 #else
399 #undef VIOAPIC_NUM_PINS
400 #endif
401 
402 DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);
403 
404 
405 /*
406  * LAPIC
407  */
408 
409 struct hvm_hw_lapic {
410     uint64_t             apic_base_msr;
411     uint32_t             disabled; /* VLAPIC_xx_DISABLED */
412     uint32_t             timer_divisor;
413     uint64_t             tdt_msr;
414 };
415 
416 DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic);
417 
418 struct hvm_hw_lapic_regs {
419     uint8_t data[1024];
420 };
421 
422 DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs);
423 
424 
425 /*
426  * IRQs
427  */
428 
429 struct hvm_hw_pci_irqs {
430     /*
431      * Virtual interrupt wires for a single PCI bus.
432      * Indexed by: device*4 + INTx#.
433      */
434     union {
435         unsigned long i[16 / sizeof (unsigned long)]; /* DECLARE_BITMAP(i, 32*4); */
436         uint64_t pad[2];
437     };
438 };
439 
440 DECLARE_HVM_SAVE_TYPE(PCI_IRQ, 7, struct hvm_hw_pci_irqs);
441 
442 struct hvm_hw_isa_irqs {
443     /*
444      * Virtual interrupt wires for ISA devices.
445      * Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).
446      */
447     union {
448         unsigned long i[1];  /* DECLARE_BITMAP(i, 16); */
449         uint64_t pad[1];
450     };
451 };
452 
453 DECLARE_HVM_SAVE_TYPE(ISA_IRQ, 8, struct hvm_hw_isa_irqs);
454 
455 struct hvm_hw_pci_link {
456     /*
457      * PCI-ISA interrupt router.
458      * Each PCI <device:INTx#> is 'wire-ORed' into one of four links using
459      * the traditional 'barber's pole' mapping ((device + INTx#) & 3).
460      * The router provides a programmable mapping from each link to a GSI.
461      */
462     uint8_t route[4];
463     uint8_t pad0[4];
464 };
465 
466 DECLARE_HVM_SAVE_TYPE(PCI_LINK, 9, struct hvm_hw_pci_link);
467 
468 /*
469  *  PIT
470  */
471 
472 struct hvm_hw_pit {
473     struct hvm_hw_pit_channel {
474         uint32_t count; /* can be 65536 */
475         uint16_t latched_count;
476         uint8_t count_latched;
477         uint8_t status_latched;
478         uint8_t status;
479         uint8_t read_state;
480         uint8_t write_state;
481         uint8_t write_latch;
482         uint8_t rw_mode;
483         uint8_t mode;
484         uint8_t bcd; /* not supported */
485         uint8_t gate; /* timer start */
486     } channels[3];  /* 3 x 16 bytes */
487     uint32_t speaker_data_on;
488     uint32_t pad0;
489 };
490 
491 DECLARE_HVM_SAVE_TYPE(PIT, 10, struct hvm_hw_pit);
492 
493 
494 /*
495  * RTC
496  */
497 
498 #define RTC_CMOS_SIZE 14
499 struct hvm_hw_rtc {
500     /* CMOS bytes */
501     uint8_t cmos_data[RTC_CMOS_SIZE];
502     /* Index register for 2-part operations */
503     uint8_t cmos_index;
504     uint8_t pad0;
505     /* RTC offset from host time */
506     int64_t rtc_offset;
507 };
508 
509 DECLARE_HVM_SAVE_TYPE(RTC, 11, struct hvm_hw_rtc);
510 
511 
512 /*
513  * HPET
514  */
515 
516 #define HPET_TIMER_NUM     3    /* 3 timers supported now */
517 struct hvm_hw_hpet {
518     /* Memory-mapped, software visible registers */
519     uint64_t capability;        /* capabilities */
520     uint64_t res0;              /* reserved */
521     uint64_t config;            /* configuration */
522     uint64_t res1;              /* reserved */
523     uint64_t isr;               /* interrupt status reg */
524     uint64_t res2[25];          /* reserved */
525     uint64_t mc64;              /* main counter */
526     uint64_t res3;              /* reserved */
527     struct {                    /* timers */
528         uint64_t config;        /* configuration/cap */
529         uint64_t cmp;           /* comparator */
530         uint64_t fsb;           /* FSB route, not supported now */
531         uint64_t res4;          /* reserved */
532     } timers[HPET_TIMER_NUM];
533     uint64_t res5[4*(24-HPET_TIMER_NUM)];  /* reserved, up to 0x3ff */
534 
535     /* Hidden register state */
536     uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */
537 };
538 
539 DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);
540 
541 
542 /*
543  * PM timer
544  */
545 
546 struct hvm_hw_pmtimer {
547     uint32_t tmr_val;   /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */
548     uint16_t pm1a_sts;  /* PM1a_EVT_BLK.PM1a_STS: status register */
549     uint16_t pm1a_en;   /* PM1a_EVT_BLK.PM1a_EN: enable register */
550 };
551 
552 DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);
553 
554 /*
555  * MTRR MSRs
556  */
557 
558 struct hvm_hw_mtrr {
559 #define MTRR_VCNT 8
560 #define NUM_FIXED_MSR 11
561     uint64_t msr_pat_cr;
562     /* mtrr physbase & physmask msr pair*/
563     uint64_t msr_mtrr_var[MTRR_VCNT*2];
564     uint64_t msr_mtrr_fixed[NUM_FIXED_MSR];
565     uint64_t msr_mtrr_cap;
566     uint64_t msr_mtrr_def_type;
567 };
568 
569 DECLARE_HVM_SAVE_TYPE(MTRR, 14, struct hvm_hw_mtrr);
570 
571 /*
572  * The save area of XSAVE/XRSTOR.
573  */
574 
575 struct hvm_hw_cpu_xsave {
576     uint64_t xfeature_mask;        /* Ignored */
577     uint64_t xcr0;                 /* Updated by XSETBV */
578     uint64_t xcr0_accum;           /* Updated by XSETBV */
579     struct {
580         struct { char x[512]; } fpu_sse;
581 
582         struct hvm_hw_cpu_xsave_hdr {
583             uint64_t xstate_bv;         /* Updated by XRSTOR */
584             uint64_t xcomp_bv;          /* Updated by XRSTOR{C,S} */
585             uint64_t reserved[6];
586         } xsave_hdr;                    /* The 64-byte header */
587     } save_area;
588 };
589 
590 #define CPU_XSAVE_CODE  16
591 
592 /*
593  * Viridian hypervisor context.
594  */
595 
596 struct hvm_viridian_domain_context {
597     uint64_t hypercall_gpa;
598     uint64_t guest_os_id;
599     uint64_t time_ref_count;
600     uint64_t reference_tsc;
601 };
602 
603 DECLARE_HVM_SAVE_TYPE(VIRIDIAN_DOMAIN, 15, struct hvm_viridian_domain_context);
604 
605 struct hvm_viridian_vcpu_context {
606     uint64_t vp_assist_msr;
607     uint8_t  apic_assist_pending;
608     uint8_t  _pad[7];
609     uint64_t simp_msr;
610     uint64_t sint_msr[16];
611     uint64_t stimer_config_msr[4];
612     uint64_t stimer_count_msr[4];
613 };
614 
615 DECLARE_HVM_SAVE_TYPE(VIRIDIAN_VCPU, 17, struct hvm_viridian_vcpu_context);
616 
617 struct hvm_vmce_vcpu {
618     uint64_t caps;
619     uint64_t mci_ctl2_bank0;
620     uint64_t mci_ctl2_bank1;
621     uint64_t mcg_ext_ctl;
622 };
623 
624 DECLARE_HVM_SAVE_TYPE(VMCE_VCPU, 18, struct hvm_vmce_vcpu);
625 
626 struct hvm_tsc_adjust {
627     uint64_t tsc_adjust;
628 };
629 
630 DECLARE_HVM_SAVE_TYPE(TSC_ADJUST, 19, struct hvm_tsc_adjust);
631 
632 
633 struct hvm_msr {
634     uint32_t count;
635     struct hvm_one_msr {
636         uint32_t index;
637         uint32_t _rsvd;
638         uint64_t val;
639     } msr[XEN_FLEX_ARRAY_DIM];
640 };
641 
642 #define CPU_MSR_CODE  20
643 
644 /* Range 22 - 34 (inclusive) reserved for Amazon */
645 
646 /*
647  * Largest type-code in use
648  */
649 #define HVM_SAVE_CODE_MAX 20
650 
651 #endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */
652 
653 /*
654  * Local variables:
655  * mode: C
656  * c-file-style: "BSD"
657  * c-basic-offset: 4
658  * tab-width: 4
659  * indent-tabs-mode: nil
660  * End:
661  */
662