/* SPDX-License-Identifier: GPL-2.0 */ #ifndef __KVM_X86_VMX_VMCS12_H #define __KVM_X86_VMX_VMCS12_H #include <linux/build_bug.h> #include "vmcs.h" /* * struct vmcs12 describes the state that our guest hypervisor (L1) keeps for a * single nested guest (L2), hence the name vmcs12. Any VMX implementation has * a VMCS structure, and vmcs12 is our emulated VMX's VMCS. This structure is * stored in guest memory specified by VMPTRLD, but is opaque to the guest, * which must access it using VMREAD/VMWRITE/VMCLEAR instructions. * More than one of these structures may exist, if L1 runs multiple L2 guests. * nested_vmx_run() will use the data here to build the vmcs02: a VMCS for the * underlying hardware which will be used to run L2. * This structure is packed to ensure that its layout is identical across * machines (necessary for live migration). * * IMPORTANT: Changing the layout of existing fields in this structure * will break save/restore compatibility with older kvm releases. When * adding new fields, either use space in the reserved padding* arrays * or add the new fields to the end of the structure. */ natural_width; struct __packed vmcs12 { … }; /* * VMCS12_REVISION is KVM's arbitrary ID for the layout of struct vmcs12. KVM * enumerates this value to L1 via MSR_IA32_VMX_BASIC, and checks the revision * ID during nested VMPTRLD to verify that L1 is loading a VMCS that adhere's * to KVM's virtual CPU definition. * * DO NOT change this value, as it will break save/restore compatibility with * older KVM releases. */ #define VMCS12_REVISION … /* * VMCS12_SIZE is the number of bytes L1 should allocate for the VMXON region * and any VMCS region. Although only sizeof(struct vmcs12) are used by the * current implementation, 4K are reserved to avoid future complications and * to preserve userspace ABI. */ #define VMCS12_SIZE … /* * For save/restore compatibility, the vmcs12 field offsets must not change, * although appending fields and/or filling gaps is obviously allowed. */ #define CHECK_OFFSET(field, loc) … static inline void vmx_check_vmcs12_offsets(void) { … } extern const unsigned short vmcs12_field_offsets[]; extern const unsigned int nr_vmcs12_fields; static inline short get_vmcs12_field_offset(unsigned long field) { … } static inline u64 vmcs12_read_any(struct vmcs12 *vmcs12, unsigned long field, u16 offset) { … } static inline void vmcs12_write_any(struct vmcs12 *vmcs12, unsigned long field, u16 offset, u64 field_value) { … } #endif /* __KVM_X86_VMX_VMCS12_H */