Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/contrib/xen/arch-x86/hvm/save.h
48378 views
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
663