target-i386: Define structs for layout of xsave area

Add structs that define the layout of the xsave areas used by
Intel processors. Add some QEMU_BUILD_BUG_ON lines to ensure the
structs match the XSAVE_* macros in target-i386/kvm.c and the
offsets and sizes at target-i386/cpu.c:ext_save_areas.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
Eduardo Habkost 2015-11-19 16:52:33 -02:00
parent c915854761
commit b503717d28
2 changed files with 118 additions and 0 deletions

View file

@ -830,6 +830,101 @@ typedef struct {
#define NB_OPMASK_REGS 8
typedef union X86LegacyXSaveArea {
struct {
uint16_t fcw;
uint16_t fsw;
uint8_t ftw;
uint8_t reserved;
uint16_t fpop;
uint64_t fpip;
uint64_t fpdp;
uint32_t mxcsr;
uint32_t mxcsr_mask;
FPReg fpregs[8];
uint8_t xmm_regs[16][16];
};
uint8_t data[512];
} X86LegacyXSaveArea;
typedef struct X86XSaveHeader {
uint64_t xstate_bv;
uint64_t xcomp_bv;
uint8_t reserved[48];
} X86XSaveHeader;
/* Ext. save area 2: AVX State */
typedef struct XSaveAVX {
uint8_t ymmh[16][16];
} XSaveAVX;
/* Ext. save area 3: BNDREG */
typedef struct XSaveBNDREG {
BNDReg bnd_regs[4];
} XSaveBNDREG;
/* Ext. save area 4: BNDCSR */
typedef union XSaveBNDCSR {
BNDCSReg bndcsr;
uint8_t data[64];
} XSaveBNDCSR;
/* Ext. save area 5: Opmask */
typedef struct XSaveOpmask {
uint64_t opmask_regs[NB_OPMASK_REGS];
} XSaveOpmask;
/* Ext. save area 6: ZMM_Hi256 */
typedef struct XSaveZMM_Hi256 {
uint8_t zmm_hi256[16][32];
} XSaveZMM_Hi256;
/* Ext. save area 7: Hi16_ZMM */
typedef struct XSaveHi16_ZMM {
uint8_t hi16_zmm[16][64];
} XSaveHi16_ZMM;
/* Ext. save area 9: PKRU state */
typedef struct XSavePKRU {
uint32_t pkru;
uint32_t padding;
} XSavePKRU;
typedef struct X86XSaveArea {
X86LegacyXSaveArea legacy;
X86XSaveHeader header;
/* Extended save areas: */
/* AVX State: */
XSaveAVX avx_state;
uint8_t padding[960 - 576 - sizeof(XSaveAVX)];
/* MPX State: */
XSaveBNDREG bndreg_state;
XSaveBNDCSR bndcsr_state;
/* AVX-512 State: */
XSaveOpmask opmask_state;
XSaveZMM_Hi256 zmm_hi256_state;
XSaveHi16_ZMM hi16_zmm_state;
/* PKRU State: */
XSavePKRU pkru_state;
} X86XSaveArea;
QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, avx_state) != 0x240);
QEMU_BUILD_BUG_ON(sizeof(XSaveAVX) != 0x100);
QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndreg_state) != 0x3c0);
QEMU_BUILD_BUG_ON(sizeof(XSaveBNDREG) != 0x40);
QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, bndcsr_state) != 0x400);
QEMU_BUILD_BUG_ON(sizeof(XSaveBNDCSR) != 0x40);
QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, opmask_state) != 0x440);
QEMU_BUILD_BUG_ON(sizeof(XSaveOpmask) != 0x40);
QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, zmm_hi256_state) != 0x480);
QEMU_BUILD_BUG_ON(sizeof(XSaveZMM_Hi256) != 0x200);
QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, hi16_zmm_state) != 0x680);
QEMU_BUILD_BUG_ON(sizeof(XSaveHi16_ZMM) != 0x400);
QEMU_BUILD_BUG_ON(offsetof(X86XSaveArea, pkru_state) != 0xA80);
QEMU_BUILD_BUG_ON(sizeof(XSavePKRU) != 0x8);
typedef enum TPRAccess {
TPR_ACCESS_READ,
TPR_ACCESS_WRITE,

View file

@ -1307,6 +1307,29 @@ static int kvm_put_fpu(X86CPU *cpu)
#define XSAVE_Hi16_ZMM 416
#define XSAVE_PKRU 672
#define XSAVE_BYTE_OFFSET(word_offset) \
((word_offset) * sizeof(((struct kvm_xsave *)0)->region[0]))
#define ASSERT_OFFSET(word_offset, field) \
QEMU_BUILD_BUG_ON(XSAVE_BYTE_OFFSET(word_offset) != \
offsetof(X86XSaveArea, field))
ASSERT_OFFSET(XSAVE_FCW_FSW, legacy.fcw);
ASSERT_OFFSET(XSAVE_FTW_FOP, legacy.ftw);
ASSERT_OFFSET(XSAVE_CWD_RIP, legacy.fpip);
ASSERT_OFFSET(XSAVE_CWD_RDP, legacy.fpdp);
ASSERT_OFFSET(XSAVE_MXCSR, legacy.mxcsr);
ASSERT_OFFSET(XSAVE_ST_SPACE, legacy.fpregs);
ASSERT_OFFSET(XSAVE_XMM_SPACE, legacy.xmm_regs);
ASSERT_OFFSET(XSAVE_XSTATE_BV, header.xstate_bv);
ASSERT_OFFSET(XSAVE_YMMH_SPACE, avx_state);
ASSERT_OFFSET(XSAVE_BNDREGS, bndreg_state);
ASSERT_OFFSET(XSAVE_BNDCSR, bndcsr_state);
ASSERT_OFFSET(XSAVE_OPMASK, opmask_state);
ASSERT_OFFSET(XSAVE_ZMM_Hi256, zmm_hi256_state);
ASSERT_OFFSET(XSAVE_Hi16_ZMM, hi16_zmm_state);
ASSERT_OFFSET(XSAVE_PKRU, pkru_state);
static int kvm_put_xsave(X86CPU *cpu)
{
CPUX86State *env = &cpu->env;