Path: blob/main/sys/contrib/xen/arch-x86/hvm/save.h
48378 views
/*1* Structure definitions for HVM state that is held by Xen and must2* be saved along with the domain's memory and device-model state.3*4* Copyright (c) 2007 XenSource Ltd.5*6* Permission is hereby granted, free of charge, to any person obtaining a copy7* of this software and associated documentation files (the "Software"), to8* deal in the Software without restriction, including without limitation the9* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or10* sell copies of the Software, and to permit persons to whom the Software is11* furnished to do so, subject to the following conditions:12*13* The above copyright notice and this permission notice shall be included in14* all copies or substantial portions of the Software.15*16* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR17* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,18* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE19* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER20* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING21* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER22* DEALINGS IN THE SOFTWARE.23*/2425#ifndef __XEN_PUBLIC_HVM_SAVE_X86_H__26#define __XEN_PUBLIC_HVM_SAVE_X86_H__2728#include "../../xen.h"2930/*31* Save/restore header: general info about the save file.32*/3334#define HVM_FILE_MAGIC 0x5438128635#define HVM_FILE_VERSION 0x000000013637struct hvm_save_header {38uint32_t magic; /* Must be HVM_FILE_MAGIC */39uint32_t version; /* File format version */40uint64_t changeset; /* Version of Xen that saved this file */41uint32_t cpuid; /* CPUID[0x01][%eax] on the saving machine */42uint32_t gtsc_khz; /* Guest's TSC frequency in kHz */43};4445DECLARE_HVM_SAVE_TYPE(HEADER, 1, struct hvm_save_header);464748/*49* Processor50*51* Compat:52* - Pre-3.4 didn't have msr_tsc_aux53* - Pre-4.7 didn't have fpu_initialised54*/5556struct hvm_hw_cpu {57uint8_t fpu_regs[512];5859uint64_t rax;60uint64_t rbx;61uint64_t rcx;62uint64_t rdx;63uint64_t rbp;64uint64_t rsi;65uint64_t rdi;66uint64_t rsp;67uint64_t r8;68uint64_t r9;69uint64_t r10;70uint64_t r11;71uint64_t r12;72uint64_t r13;73uint64_t r14;74uint64_t r15;7576uint64_t rip;77uint64_t rflags;7879uint64_t cr0;80uint64_t cr2;81uint64_t cr3;82uint64_t cr4;8384uint64_t dr0;85uint64_t dr1;86uint64_t dr2;87uint64_t dr3;88uint64_t dr6;89uint64_t dr7;9091uint32_t cs_sel;92uint32_t ds_sel;93uint32_t es_sel;94uint32_t fs_sel;95uint32_t gs_sel;96uint32_t ss_sel;97uint32_t tr_sel;98uint32_t ldtr_sel;99100uint32_t cs_limit;101uint32_t ds_limit;102uint32_t es_limit;103uint32_t fs_limit;104uint32_t gs_limit;105uint32_t ss_limit;106uint32_t tr_limit;107uint32_t ldtr_limit;108uint32_t idtr_limit;109uint32_t gdtr_limit;110111uint64_t cs_base;112uint64_t ds_base;113uint64_t es_base;114uint64_t fs_base;115uint64_t gs_base;116uint64_t ss_base;117uint64_t tr_base;118uint64_t ldtr_base;119uint64_t idtr_base;120uint64_t gdtr_base;121122uint32_t cs_arbytes;123uint32_t ds_arbytes;124uint32_t es_arbytes;125uint32_t fs_arbytes;126uint32_t gs_arbytes;127uint32_t ss_arbytes;128uint32_t tr_arbytes;129uint32_t ldtr_arbytes;130131uint64_t sysenter_cs;132uint64_t sysenter_esp;133uint64_t sysenter_eip;134135/* msr for em64t */136uint64_t shadow_gs;137138/* msr content saved/restored. */139uint64_t msr_flags; /* Obsolete, ignored. */140uint64_t msr_lstar;141uint64_t msr_star;142uint64_t msr_cstar;143uint64_t msr_syscall_mask;144uint64_t msr_efer;145uint64_t msr_tsc_aux;146147/* guest's idea of what rdtsc() would return */148uint64_t tsc;149150/* pending event, if any */151union {152uint32_t pending_event;153struct {154uint8_t pending_vector:8;155uint8_t pending_type:3;156uint8_t pending_error_valid:1;157uint32_t pending_reserved:19;158uint8_t pending_valid:1;159};160};161/* error code for pending event */162uint32_t error_code;163164#define _XEN_X86_FPU_INITIALISED 0165#define XEN_X86_FPU_INITIALISED (1U<<_XEN_X86_FPU_INITIALISED)166uint32_t flags;167uint32_t pad0;168};169170struct hvm_hw_cpu_compat {171uint8_t fpu_regs[512];172173uint64_t rax;174uint64_t rbx;175uint64_t rcx;176uint64_t rdx;177uint64_t rbp;178uint64_t rsi;179uint64_t rdi;180uint64_t rsp;181uint64_t r8;182uint64_t r9;183uint64_t r10;184uint64_t r11;185uint64_t r12;186uint64_t r13;187uint64_t r14;188uint64_t r15;189190uint64_t rip;191uint64_t rflags;192193uint64_t cr0;194uint64_t cr2;195uint64_t cr3;196uint64_t cr4;197198uint64_t dr0;199uint64_t dr1;200uint64_t dr2;201uint64_t dr3;202uint64_t dr6;203uint64_t dr7;204205uint32_t cs_sel;206uint32_t ds_sel;207uint32_t es_sel;208uint32_t fs_sel;209uint32_t gs_sel;210uint32_t ss_sel;211uint32_t tr_sel;212uint32_t ldtr_sel;213214uint32_t cs_limit;215uint32_t ds_limit;216uint32_t es_limit;217uint32_t fs_limit;218uint32_t gs_limit;219uint32_t ss_limit;220uint32_t tr_limit;221uint32_t ldtr_limit;222uint32_t idtr_limit;223uint32_t gdtr_limit;224225uint64_t cs_base;226uint64_t ds_base;227uint64_t es_base;228uint64_t fs_base;229uint64_t gs_base;230uint64_t ss_base;231uint64_t tr_base;232uint64_t ldtr_base;233uint64_t idtr_base;234uint64_t gdtr_base;235236uint32_t cs_arbytes;237uint32_t ds_arbytes;238uint32_t es_arbytes;239uint32_t fs_arbytes;240uint32_t gs_arbytes;241uint32_t ss_arbytes;242uint32_t tr_arbytes;243uint32_t ldtr_arbytes;244245uint64_t sysenter_cs;246uint64_t sysenter_esp;247uint64_t sysenter_eip;248249/* msr for em64t */250uint64_t shadow_gs;251252/* msr content saved/restored. */253uint64_t msr_flags; /* Obsolete, ignored. */254uint64_t msr_lstar;255uint64_t msr_star;256uint64_t msr_cstar;257uint64_t msr_syscall_mask;258uint64_t msr_efer;259/*uint64_t msr_tsc_aux; COMPAT */260261/* guest's idea of what rdtsc() would return */262uint64_t tsc;263264/* pending event, if any */265union {266uint32_t pending_event;267struct {268uint8_t pending_vector:8;269uint8_t pending_type:3;270uint8_t pending_error_valid:1;271uint32_t pending_reserved:19;272uint8_t pending_valid:1;273};274};275/* error code for pending event */276uint32_t error_code;277};278279static inline int _hvm_hw_fix_cpu(void *h, uint32_t size) {280281union hvm_hw_cpu_union {282struct hvm_hw_cpu nat;283struct hvm_hw_cpu_compat cmp;284} *ucpu = (union hvm_hw_cpu_union *)h;285286if ( size == sizeof(struct hvm_hw_cpu_compat) )287{288/*289* If we copy from the end backwards, we should290* be able to do the modification in-place.291*/292ucpu->nat.error_code = ucpu->cmp.error_code;293ucpu->nat.pending_event = ucpu->cmp.pending_event;294ucpu->nat.tsc = ucpu->cmp.tsc;295ucpu->nat.msr_tsc_aux = 0;296}297/* Mimic the old behaviour by unconditionally setting fpu_initialised. */298ucpu->nat.flags = XEN_X86_FPU_INITIALISED;299300return 0;301}302303DECLARE_HVM_SAVE_TYPE_COMPAT(CPU, 2, struct hvm_hw_cpu, \304struct hvm_hw_cpu_compat, _hvm_hw_fix_cpu);305306/*307* PIC308*/309310struct hvm_hw_vpic {311/* IR line bitmasks. */312uint8_t irr;313uint8_t imr;314uint8_t isr;315316/* Line IRx maps to IRQ irq_base+x */317uint8_t irq_base;318319/*320* Where are we in ICW2-4 initialisation (0 means no init in progress)?321* Bits 0-1 (=x): Next write at A=1 sets ICW(x+1).322* Bit 2: ICW1.IC4 (1 == ICW4 included in init sequence)323* Bit 3: ICW1.SNGL (0 == ICW3 included in init sequence)324*/325uint8_t init_state:4;326327/* IR line with highest priority. */328uint8_t priority_add:4;329330/* Reads from A=0 obtain ISR or IRR? */331uint8_t readsel_isr:1;332333/* Reads perform a polling read? */334uint8_t poll:1;335336/* Automatically clear IRQs from the ISR during INTA? */337uint8_t auto_eoi:1;338339/* Automatically rotate IRQ priorities during AEOI? */340uint8_t rotate_on_auto_eoi:1;341342/* Exclude slave inputs when considering in-service IRQs? */343uint8_t special_fully_nested_mode:1;344345/* Special mask mode excludes masked IRs from AEOI and priority checks. */346uint8_t special_mask_mode:1;347348/* Is this a master PIC or slave PIC? (NB. This is not programmable.) */349uint8_t is_master:1;350351/* Edge/trigger selection. */352uint8_t elcr;353354/* Virtual INT output. */355uint8_t int_output;356};357358DECLARE_HVM_SAVE_TYPE(PIC, 3, struct hvm_hw_vpic);359360361/*362* IO-APIC363*/364365union vioapic_redir_entry366{367uint64_t bits;368struct {369uint8_t vector;370uint8_t delivery_mode:3;371uint8_t dest_mode:1;372uint8_t delivery_status:1;373uint8_t polarity:1;374uint8_t remote_irr:1;375uint8_t trig_mode:1;376uint8_t mask:1;377uint8_t reserve:7;378uint8_t reserved[4];379uint8_t dest_id;380} fields;381};382383#define VIOAPIC_NUM_PINS 48 /* 16 ISA IRQs, 32 non-legacy PCI IRQS. */384385#define XEN_HVM_VIOAPIC(name, cnt) \386struct name { \387uint64_t base_address; \388uint32_t ioregsel; \389uint32_t id; \390union vioapic_redir_entry redirtbl[cnt]; \391}392393XEN_HVM_VIOAPIC(hvm_hw_vioapic, VIOAPIC_NUM_PINS);394395#ifndef __XEN__396#undef XEN_HVM_VIOAPIC397#else398#undef VIOAPIC_NUM_PINS399#endif400401DECLARE_HVM_SAVE_TYPE(IOAPIC, 4, struct hvm_hw_vioapic);402403404/*405* LAPIC406*/407408struct hvm_hw_lapic {409uint64_t apic_base_msr;410uint32_t disabled; /* VLAPIC_xx_DISABLED */411uint32_t timer_divisor;412uint64_t tdt_msr;413};414415DECLARE_HVM_SAVE_TYPE(LAPIC, 5, struct hvm_hw_lapic);416417struct hvm_hw_lapic_regs {418uint8_t data[1024];419};420421DECLARE_HVM_SAVE_TYPE(LAPIC_REGS, 6, struct hvm_hw_lapic_regs);422423424/*425* IRQs426*/427428struct hvm_hw_pci_irqs {429/*430* Virtual interrupt wires for a single PCI bus.431* Indexed by: device*4 + INTx#.432*/433union {434unsigned long i[16 / sizeof (unsigned long)]; /* DECLARE_BITMAP(i, 32*4); */435uint64_t pad[2];436};437};438439DECLARE_HVM_SAVE_TYPE(PCI_IRQ, 7, struct hvm_hw_pci_irqs);440441struct hvm_hw_isa_irqs {442/*443* Virtual interrupt wires for ISA devices.444* Indexed by ISA IRQ (assumes no ISA-device IRQ sharing).445*/446union {447unsigned long i[1]; /* DECLARE_BITMAP(i, 16); */448uint64_t pad[1];449};450};451452DECLARE_HVM_SAVE_TYPE(ISA_IRQ, 8, struct hvm_hw_isa_irqs);453454struct hvm_hw_pci_link {455/*456* PCI-ISA interrupt router.457* Each PCI <device:INTx#> is 'wire-ORed' into one of four links using458* the traditional 'barber's pole' mapping ((device + INTx#) & 3).459* The router provides a programmable mapping from each link to a GSI.460*/461uint8_t route[4];462uint8_t pad0[4];463};464465DECLARE_HVM_SAVE_TYPE(PCI_LINK, 9, struct hvm_hw_pci_link);466467/*468* PIT469*/470471struct hvm_hw_pit {472struct hvm_hw_pit_channel {473uint32_t count; /* can be 65536 */474uint16_t latched_count;475uint8_t count_latched;476uint8_t status_latched;477uint8_t status;478uint8_t read_state;479uint8_t write_state;480uint8_t write_latch;481uint8_t rw_mode;482uint8_t mode;483uint8_t bcd; /* not supported */484uint8_t gate; /* timer start */485} channels[3]; /* 3 x 16 bytes */486uint32_t speaker_data_on;487uint32_t pad0;488};489490DECLARE_HVM_SAVE_TYPE(PIT, 10, struct hvm_hw_pit);491492493/*494* RTC495*/496497#define RTC_CMOS_SIZE 14498struct hvm_hw_rtc {499/* CMOS bytes */500uint8_t cmos_data[RTC_CMOS_SIZE];501/* Index register for 2-part operations */502uint8_t cmos_index;503uint8_t pad0;504/* RTC offset from host time */505int64_t rtc_offset;506};507508DECLARE_HVM_SAVE_TYPE(RTC, 11, struct hvm_hw_rtc);509510511/*512* HPET513*/514515#define HPET_TIMER_NUM 3 /* 3 timers supported now */516struct hvm_hw_hpet {517/* Memory-mapped, software visible registers */518uint64_t capability; /* capabilities */519uint64_t res0; /* reserved */520uint64_t config; /* configuration */521uint64_t res1; /* reserved */522uint64_t isr; /* interrupt status reg */523uint64_t res2[25]; /* reserved */524uint64_t mc64; /* main counter */525uint64_t res3; /* reserved */526struct { /* timers */527uint64_t config; /* configuration/cap */528uint64_t cmp; /* comparator */529uint64_t fsb; /* FSB route, not supported now */530uint64_t res4; /* reserved */531} timers[HPET_TIMER_NUM];532uint64_t res5[4*(24-HPET_TIMER_NUM)]; /* reserved, up to 0x3ff */533534/* Hidden register state */535uint64_t period[HPET_TIMER_NUM]; /* Last value written to comparator */536};537538DECLARE_HVM_SAVE_TYPE(HPET, 12, struct hvm_hw_hpet);539540541/*542* PM timer543*/544545struct hvm_hw_pmtimer {546uint32_t tmr_val; /* PM_TMR_BLK.TMR_VAL: 32bit free-running counter */547uint16_t pm1a_sts; /* PM1a_EVT_BLK.PM1a_STS: status register */548uint16_t pm1a_en; /* PM1a_EVT_BLK.PM1a_EN: enable register */549};550551DECLARE_HVM_SAVE_TYPE(PMTIMER, 13, struct hvm_hw_pmtimer);552553/*554* MTRR MSRs555*/556557struct hvm_hw_mtrr {558#define MTRR_VCNT 8559#define NUM_FIXED_MSR 11560uint64_t msr_pat_cr;561/* mtrr physbase & physmask msr pair*/562uint64_t msr_mtrr_var[MTRR_VCNT*2];563uint64_t msr_mtrr_fixed[NUM_FIXED_MSR];564uint64_t msr_mtrr_cap;565uint64_t msr_mtrr_def_type;566};567568DECLARE_HVM_SAVE_TYPE(MTRR, 14, struct hvm_hw_mtrr);569570/*571* The save area of XSAVE/XRSTOR.572*/573574struct hvm_hw_cpu_xsave {575uint64_t xfeature_mask; /* Ignored */576uint64_t xcr0; /* Updated by XSETBV */577uint64_t xcr0_accum; /* Updated by XSETBV */578struct {579struct { char x[512]; } fpu_sse;580581struct hvm_hw_cpu_xsave_hdr {582uint64_t xstate_bv; /* Updated by XRSTOR */583uint64_t xcomp_bv; /* Updated by XRSTOR{C,S} */584uint64_t reserved[6];585} xsave_hdr; /* The 64-byte header */586} save_area;587};588589#define CPU_XSAVE_CODE 16590591/*592* Viridian hypervisor context.593*/594595struct hvm_viridian_domain_context {596uint64_t hypercall_gpa;597uint64_t guest_os_id;598uint64_t time_ref_count;599uint64_t reference_tsc;600};601602DECLARE_HVM_SAVE_TYPE(VIRIDIAN_DOMAIN, 15, struct hvm_viridian_domain_context);603604struct hvm_viridian_vcpu_context {605uint64_t vp_assist_msr;606uint8_t apic_assist_pending;607uint8_t _pad[7];608uint64_t simp_msr;609uint64_t sint_msr[16];610uint64_t stimer_config_msr[4];611uint64_t stimer_count_msr[4];612};613614DECLARE_HVM_SAVE_TYPE(VIRIDIAN_VCPU, 17, struct hvm_viridian_vcpu_context);615616struct hvm_vmce_vcpu {617uint64_t caps;618uint64_t mci_ctl2_bank0;619uint64_t mci_ctl2_bank1;620uint64_t mcg_ext_ctl;621};622623DECLARE_HVM_SAVE_TYPE(VMCE_VCPU, 18, struct hvm_vmce_vcpu);624625struct hvm_tsc_adjust {626uint64_t tsc_adjust;627};628629DECLARE_HVM_SAVE_TYPE(TSC_ADJUST, 19, struct hvm_tsc_adjust);630631632struct hvm_msr {633uint32_t count;634struct hvm_one_msr {635uint32_t index;636uint32_t _rsvd;637uint64_t val;638} msr[XEN_FLEX_ARRAY_DIM];639};640641#define CPU_MSR_CODE 20642643/* Range 22 - 34 (inclusive) reserved for Amazon */644645/*646* Largest type-code in use647*/648#define HVM_SAVE_CODE_MAX 20649650#endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */651652/*653* Local variables:654* mode: C655* c-file-style: "BSD"656* c-basic-offset: 4657* tab-width: 4658* indent-tabs-mode: nil659* End:660*/661662663