* [for-2.6 PATCH 0/3] target-i386: Use C struct for xsave area layout, offsets & sizes
@ 2015-11-28 19:56 ` Eduardo Habkost
0 siblings, 0 replies; 27+ messages in thread
From: Eduardo Habkost @ 2015-11-28 19:56 UTC (permalink / raw)
To: qemu-devel; +Cc: Paolo Bonzini, kvm, Huaitong Han
target-i386/cpu.c:ext_save_area uses magic numbers for the xsave
area offets and sizes, and target-i386/kvm.c:kvm_{put,get}_xsave()
uses offset macros and bit manipulation to access the xsave area.
This series changes both to use C structs for the same
operations.
I still need to figure out a way to write unit tests for the new
code. Maybe I will just copy and paste the new and old functions,
and test them locally (checking if they give the same results
when translating blobs of random bytes).
Eduardo Habkost (3):
target-i386: Define structs for layout of xsave area
target-i386: Use xsave structs for ext_save_area
target-i386: kvm: Use X86XSaveArea struct for xsave save/load
target-i386/cpu.c | 18 +++++---
target-i386/cpu.h | 85 ++++++++++++++++++++++++++++++++++++++
target-i386/kvm.c | 121 +++++++++++++++++++++++-------------------------------
3 files changed, 149 insertions(+), 75 deletions(-)
--
2.1.0
^ permalink raw reply [flat|nested] 27+ messages in thread* [Qemu-devel] [for-2.6 PATCH 0/3] target-i386: Use C struct for xsave area layout, offsets & sizes @ 2015-11-28 19:56 ` Eduardo Habkost 0 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-28 19:56 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, kvm, Huaitong Han target-i386/cpu.c:ext_save_area uses magic numbers for the xsave area offets and sizes, and target-i386/kvm.c:kvm_{put,get}_xsave() uses offset macros and bit manipulation to access the xsave area. This series changes both to use C structs for the same operations. I still need to figure out a way to write unit tests for the new code. Maybe I will just copy and paste the new and old functions, and test them locally (checking if they give the same results when translating blobs of random bytes). Eduardo Habkost (3): target-i386: Define structs for layout of xsave area target-i386: Use xsave structs for ext_save_area target-i386: kvm: Use X86XSaveArea struct for xsave save/load target-i386/cpu.c | 18 +++++--- target-i386/cpu.h | 85 ++++++++++++++++++++++++++++++++++++++ target-i386/kvm.c | 121 +++++++++++++++++++++++------------------------------- 3 files changed, 149 insertions(+), 75 deletions(-) -- 2.1.0 ^ permalink raw reply [flat|nested] 27+ messages in thread
* [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area 2015-11-28 19:56 ` [Qemu-devel] " Eduardo Habkost @ 2015-11-28 19:56 ` Eduardo Habkost -1 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-28 19:56 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, kvm, Huaitong Han 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> --- target-i386/cpu.h | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ target-i386/kvm.c | 23 +++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 84edfd0..3d1d01e 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -806,6 +806,91 @@ 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]; + uint64_t xmm_regs[16][2]; + }; + 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 { + uint64_t ymmh[16][2]; +} 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 { + uint64_t zmm_hi256[16][4]; +} XSaveZMM_Hi256; + +/* Ext. save area 7: Hi16_ZMM */ +typedef struct XSaveHi16_ZMM { + XMMReg hi16_zmm[16]; +} XSaveHi16_ZMM; + +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; +} 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); + typedef enum TPRAccess { TPR_ACCESS_READ, TPR_ACCESS_WRITE, diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 6dc9846..ee6c213 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1218,6 +1218,29 @@ static int kvm_put_fpu(X86CPU *cpu) #define XSAVE_ZMM_Hi256 288 #define XSAVE_Hi16_ZMM 416 +#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); + + static int kvm_put_xsave(X86CPU *cpu) { CPUX86State *env = &cpu->env; -- 2.1.0 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area @ 2015-11-28 19:56 ` Eduardo Habkost 0 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-28 19:56 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, kvm, Huaitong Han 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> --- target-i386/cpu.h | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ target-i386/kvm.c | 23 +++++++++++++++ 2 files changed, 108 insertions(+) diff --git a/target-i386/cpu.h b/target-i386/cpu.h index 84edfd0..3d1d01e 100644 --- a/target-i386/cpu.h +++ b/target-i386/cpu.h @@ -806,6 +806,91 @@ 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]; + uint64_t xmm_regs[16][2]; + }; + 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 { + uint64_t ymmh[16][2]; +} 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 { + uint64_t zmm_hi256[16][4]; +} XSaveZMM_Hi256; + +/* Ext. save area 7: Hi16_ZMM */ +typedef struct XSaveHi16_ZMM { + XMMReg hi16_zmm[16]; +} XSaveHi16_ZMM; + +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; +} 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); + typedef enum TPRAccess { TPR_ACCESS_READ, TPR_ACCESS_WRITE, diff --git a/target-i386/kvm.c b/target-i386/kvm.c index 6dc9846..ee6c213 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1218,6 +1218,29 @@ static int kvm_put_fpu(X86CPU *cpu) #define XSAVE_ZMM_Hi256 288 #define XSAVE_Hi16_ZMM 416 +#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); + + static int kvm_put_xsave(X86CPU *cpu) { CPUX86State *env = &cpu->env; -- 2.1.0 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area 2015-11-28 19:56 ` [Qemu-devel] " Eduardo Habkost @ 2015-11-30 11:18 ` Paolo Bonzini -1 siblings, 0 replies; 27+ messages in thread From: Paolo Bonzini @ 2015-11-30 11:18 UTC (permalink / raw) To: Eduardo Habkost, qemu-devel; +Cc: kvm, Huaitong Han On 28/11/2015 20:56, Eduardo Habkost wrote: > +/* Ext. save area 2: AVX State */ > +typedef struct XSaveAVX { > + uint64_t ymmh[16][2]; > +} XSaveAVX; > + Because this is always little endian, I would write it as uint8_t[16][16]. > +/* Ext. save area 6: ZMM_Hi256 */ > +typedef struct XSaveZMM_Hi256 { > + uint64_t zmm_hi256[16][4]; > +} XSaveZMM_Hi256; Same here (uint8_t[16][32]). > +/* Ext. save area 7: Hi16_ZMM */ > +typedef struct XSaveHi16_ZMM { > + XMMReg hi16_zmm[16]; > +} XSaveHi16_ZMM; This is uint8_t[16][64] or uint64_t[16][8]. Paolo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area @ 2015-11-30 11:18 ` Paolo Bonzini 0 siblings, 0 replies; 27+ messages in thread From: Paolo Bonzini @ 2015-11-30 11:18 UTC (permalink / raw) To: Eduardo Habkost, qemu-devel; +Cc: Huaitong Han, kvm On 28/11/2015 20:56, Eduardo Habkost wrote: > +/* Ext. save area 2: AVX State */ > +typedef struct XSaveAVX { > + uint64_t ymmh[16][2]; > +} XSaveAVX; > + Because this is always little endian, I would write it as uint8_t[16][16]. > +/* Ext. save area 6: ZMM_Hi256 */ > +typedef struct XSaveZMM_Hi256 { > + uint64_t zmm_hi256[16][4]; > +} XSaveZMM_Hi256; Same here (uint8_t[16][32]). > +/* Ext. save area 7: Hi16_ZMM */ > +typedef struct XSaveHi16_ZMM { > + XMMReg hi16_zmm[16]; > +} XSaveHi16_ZMM; This is uint8_t[16][64] or uint64_t[16][8]. Paolo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area 2015-11-30 11:18 ` [Qemu-devel] " Paolo Bonzini @ 2015-11-30 14:48 ` Eduardo Habkost -1 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-30 14:48 UTC (permalink / raw) To: Paolo Bonzini; +Cc: qemu-devel, kvm, Huaitong Han On Mon, Nov 30, 2015 at 12:18:33PM +0100, Paolo Bonzini wrote: > On 28/11/2015 20:56, Eduardo Habkost wrote: > > +/* Ext. save area 2: AVX State */ > > +typedef struct XSaveAVX { > > + uint64_t ymmh[16][2]; > > +} XSaveAVX; > > + > > Because this is always little endian, I would write it as uint8_t[16][16]. The main reason I used uint64_t was to allow the put/save code to simply use field[0], field[1], field[2] instead of field, field+8, field+16. But I think your suggestion makes sense: the fact that we load/save the register data in 8-byte chunks in kvm_{get,put}_xsave() has nothing to do with the layout of the data itself (so it doesn't need to be encoded in the struct definition). > > > +/* Ext. save area 6: ZMM_Hi256 */ > > +typedef struct XSaveZMM_Hi256 { > > + uint64_t zmm_hi256[16][4]; > > +} XSaveZMM_Hi256; > > Same here (uint8_t[16][32]). > > > +/* Ext. save area 7: Hi16_ZMM */ > > +typedef struct XSaveHi16_ZMM { > > + XMMReg hi16_zmm[16]; > > +} XSaveHi16_ZMM; > > This is uint8_t[16][64] or uint64_t[16][8]. While writing this series, I had a version that redefined the XMMReg, YMMReg, ZMMReg structs with the correct sizes, and reused them for ymmh, zmm_hi256, and hi16_zmm. I still planned to propose that later. You don't think it would make sense? -- Eduardo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area @ 2015-11-30 14:48 ` Eduardo Habkost 0 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-30 14:48 UTC (permalink / raw) To: Paolo Bonzini; +Cc: Huaitong Han, qemu-devel, kvm On Mon, Nov 30, 2015 at 12:18:33PM +0100, Paolo Bonzini wrote: > On 28/11/2015 20:56, Eduardo Habkost wrote: > > +/* Ext. save area 2: AVX State */ > > +typedef struct XSaveAVX { > > + uint64_t ymmh[16][2]; > > +} XSaveAVX; > > + > > Because this is always little endian, I would write it as uint8_t[16][16]. The main reason I used uint64_t was to allow the put/save code to simply use field[0], field[1], field[2] instead of field, field+8, field+16. But I think your suggestion makes sense: the fact that we load/save the register data in 8-byte chunks in kvm_{get,put}_xsave() has nothing to do with the layout of the data itself (so it doesn't need to be encoded in the struct definition). > > > +/* Ext. save area 6: ZMM_Hi256 */ > > +typedef struct XSaveZMM_Hi256 { > > + uint64_t zmm_hi256[16][4]; > > +} XSaveZMM_Hi256; > > Same here (uint8_t[16][32]). > > > +/* Ext. save area 7: Hi16_ZMM */ > > +typedef struct XSaveHi16_ZMM { > > + XMMReg hi16_zmm[16]; > > +} XSaveHi16_ZMM; > > This is uint8_t[16][64] or uint64_t[16][8]. While writing this series, I had a version that redefined the XMMReg, YMMReg, ZMMReg structs with the correct sizes, and reused them for ymmh, zmm_hi256, and hi16_zmm. I still planned to propose that later. You don't think it would make sense? -- Eduardo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area 2015-11-30 11:18 ` [Qemu-devel] " Paolo Bonzini (?) (?) @ 2015-12-01 17:09 ` Richard Henderson 2015-12-01 17:15 ` Eduardo Habkost -1 siblings, 1 reply; 27+ messages in thread From: Richard Henderson @ 2015-12-01 17:09 UTC (permalink / raw) To: Paolo Bonzini, Eduardo Habkost, qemu-devel; +Cc: Huaitong Han, kvm On 11/30/2015 03:18 AM, Paolo Bonzini wrote: > Because this is always little endian, I would write it as uint8_t[16][16]. Maybe. That isn't altogether handy for TCG, since we'll be wanting to bswap these buffers (probably in uint64_t chunks). r~ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area 2015-12-01 17:09 ` Richard Henderson @ 2015-12-01 17:15 ` Eduardo Habkost 0 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-12-01 17:15 UTC (permalink / raw) To: Richard Henderson; +Cc: Paolo Bonzini, qemu-devel, Huaitong Han, kvm On Tue, Dec 01, 2015 at 09:09:47AM -0800, Richard Henderson wrote: > On 11/30/2015 03:18 AM, Paolo Bonzini wrote: > >Because this is always little endian, I would write it as uint8_t[16][16]. > > Maybe. That isn't altogether handy for TCG, since we'll be wanting to bswap > these buffers (probably in uint64_t chunks). X86XSaveArea will be used only when loading/saving state using xsave, not for executing regular instructions. In X86CPU, the data is already stored as XMMReg unions (the one with the XMM_[BWDQ] helpers). -- Eduardo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area @ 2015-12-01 17:15 ` Eduardo Habkost 0 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-12-01 17:15 UTC (permalink / raw) To: Richard Henderson; +Cc: Paolo Bonzini, qemu-devel, kvm, Huaitong Han On Tue, Dec 01, 2015 at 09:09:47AM -0800, Richard Henderson wrote: > On 11/30/2015 03:18 AM, Paolo Bonzini wrote: > >Because this is always little endian, I would write it as uint8_t[16][16]. > > Maybe. That isn't altogether handy for TCG, since we'll be wanting to bswap > these buffers (probably in uint64_t chunks). X86XSaveArea will be used only when loading/saving state using xsave, not for executing regular instructions. In X86CPU, the data is already stored as XMMReg unions (the one with the XMM_[BWDQ] helpers). -- Eduardo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area 2015-12-01 17:15 ` Eduardo Habkost @ 2015-12-01 17:20 ` Richard Henderson -1 siblings, 0 replies; 27+ messages in thread From: Richard Henderson @ 2015-12-01 17:20 UTC (permalink / raw) To: Eduardo Habkost; +Cc: Paolo Bonzini, qemu-devel, Huaitong Han, kvm On 12/01/2015 09:15 AM, Eduardo Habkost wrote: > On Tue, Dec 01, 2015 at 09:09:47AM -0800, Richard Henderson wrote: >> On 11/30/2015 03:18 AM, Paolo Bonzini wrote: >>> Because this is always little endian, I would write it as uint8_t[16][16]. >> >> Maybe. That isn't altogether handy for TCG, since we'll be wanting to bswap >> these buffers (probably in uint64_t chunks). > > X86XSaveArea will be used only when loading/saving state using > xsave, not for executing regular instructions. ... like the regular instruction xsave? https://patchwork.ozlabs.org/patch/493318/ > In X86CPU, the > data is already stored as XMMReg unions (the one with the > XMM_[BWDQ] helpers). Of course. But those unions are arranged to be in big-endian format on big-endian hosts. So we need to swap the data back to little-endian format for storage into guest memory. r~ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area @ 2015-12-01 17:20 ` Richard Henderson 0 siblings, 0 replies; 27+ messages in thread From: Richard Henderson @ 2015-12-01 17:20 UTC (permalink / raw) To: Eduardo Habkost; +Cc: Paolo Bonzini, qemu-devel, kvm, Huaitong Han On 12/01/2015 09:15 AM, Eduardo Habkost wrote: > On Tue, Dec 01, 2015 at 09:09:47AM -0800, Richard Henderson wrote: >> On 11/30/2015 03:18 AM, Paolo Bonzini wrote: >>> Because this is always little endian, I would write it as uint8_t[16][16]. >> >> Maybe. That isn't altogether handy for TCG, since we'll be wanting to bswap >> these buffers (probably in uint64_t chunks). > > X86XSaveArea will be used only when loading/saving state using > xsave, not for executing regular instructions. ... like the regular instruction xsave? https://patchwork.ozlabs.org/patch/493318/ > In X86CPU, the > data is already stored as XMMReg unions (the one with the > XMM_[BWDQ] helpers). Of course. But those unions are arranged to be in big-endian format on big-endian hosts. So we need to swap the data back to little-endian format for storage into guest memory. r~ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area 2015-12-01 17:20 ` Richard Henderson @ 2015-12-01 17:27 ` Paolo Bonzini -1 siblings, 0 replies; 27+ messages in thread From: Paolo Bonzini @ 2015-12-01 17:27 UTC (permalink / raw) To: Richard Henderson, Eduardo Habkost; +Cc: qemu-devel, Huaitong Han, kvm On 01/12/2015 18:20, Richard Henderson wrote: >> >> X86XSaveArea will be used only when loading/saving state using >> xsave, not for executing regular instructions. > > ... like the regular instruction xsave? > > https://patchwork.ozlabs.org/patch/493318/ Right, but that's a helper anyway. >> In X86CPU, the >> data is already stored as XMMReg unions (the one with the >> XMM_[BWDQ] helpers). > > Of course. But those unions are arranged to be in big-endian format on > big-endian hosts. So we need to swap the data back to little-endian > format for storage into guest memory. Yes, you can use byte moves with XMM_B (more obvious), or stq_le_p with XMM_Q (faster I guess---though the compiler might optimize the former on little-endian hosts). Either works with an uint8_t[] destination. Paolo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area @ 2015-12-01 17:27 ` Paolo Bonzini 0 siblings, 0 replies; 27+ messages in thread From: Paolo Bonzini @ 2015-12-01 17:27 UTC (permalink / raw) To: Richard Henderson, Eduardo Habkost; +Cc: Huaitong Han, qemu-devel, kvm On 01/12/2015 18:20, Richard Henderson wrote: >> >> X86XSaveArea will be used only when loading/saving state using >> xsave, not for executing regular instructions. > > ... like the regular instruction xsave? > > https://patchwork.ozlabs.org/patch/493318/ Right, but that's a helper anyway. >> In X86CPU, the >> data is already stored as XMMReg unions (the one with the >> XMM_[BWDQ] helpers). > > Of course. But those unions are arranged to be in big-endian format on > big-endian hosts. So we need to swap the data back to little-endian > format for storage into guest memory. Yes, you can use byte moves with XMM_B (more obvious), or stq_le_p with XMM_Q (faster I guess---though the compiler might optimize the former on little-endian hosts). Either works with an uint8_t[] destination. Paolo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area 2015-12-01 17:27 ` Paolo Bonzini @ 2015-12-01 18:34 ` Eduardo Habkost -1 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-12-01 18:34 UTC (permalink / raw) To: Paolo Bonzini; +Cc: Richard Henderson, qemu-devel, Huaitong Han, kvm On Tue, Dec 01, 2015 at 06:27:17PM +0100, Paolo Bonzini wrote: > On 01/12/2015 18:20, Richard Henderson wrote: > >> > >> X86XSaveArea will be used only when loading/saving state using > >> xsave, not for executing regular instructions. > > > > ... like the regular instruction xsave? > > > > https://patchwork.ozlabs.org/patch/493318/ > > Right, but that's a helper anyway. > > >> In X86CPU, the > >> data is already stored as XMMReg unions (the one with the > >> XMM_[BWDQ] helpers). > > > > Of course. But those unions are arranged to be in big-endian format on > > big-endian hosts. So we need to swap the data back to little-endian > > format for storage into guest memory. > > Yes, you can use byte moves with XMM_B (more obvious), or stq_le_p with > XMM_Q (faster I guess---though the compiler might optimize the former on > little-endian hosts). Either works with an uint8_t[] destination. stq_le_p() (more exactly, stq_p()) is exactly what is already done by kvm_{get,put}_xsave(), using uint8_t pointers. BTW, if we are going to implement xsave in TCG, the X86CPU<->xsave translation logic in kvm_{get,put}_xsave() could be moved to generic code and reused by TCG instead of being reimplemented. -- Eduardo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area @ 2015-12-01 18:34 ` Eduardo Habkost 0 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-12-01 18:34 UTC (permalink / raw) To: Paolo Bonzini; +Cc: Huaitong Han, qemu-devel, kvm, Richard Henderson On Tue, Dec 01, 2015 at 06:27:17PM +0100, Paolo Bonzini wrote: > On 01/12/2015 18:20, Richard Henderson wrote: > >> > >> X86XSaveArea will be used only when loading/saving state using > >> xsave, not for executing regular instructions. > > > > ... like the regular instruction xsave? > > > > https://patchwork.ozlabs.org/patch/493318/ > > Right, but that's a helper anyway. > > >> In X86CPU, the > >> data is already stored as XMMReg unions (the one with the > >> XMM_[BWDQ] helpers). > > > > Of course. But those unions are arranged to be in big-endian format on > > big-endian hosts. So we need to swap the data back to little-endian > > format for storage into guest memory. > > Yes, you can use byte moves with XMM_B (more obvious), or stq_le_p with > XMM_Q (faster I guess---though the compiler might optimize the former on > little-endian hosts). Either works with an uint8_t[] destination. stq_le_p() (more exactly, stq_p()) is exactly what is already done by kvm_{get,put}_xsave(), using uint8_t pointers. BTW, if we are going to implement xsave in TCG, the X86CPU<->xsave translation logic in kvm_{get,put}_xsave() could be moved to generic code and reused by TCG instead of being reimplemented. -- Eduardo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area 2015-12-01 18:34 ` Eduardo Habkost @ 2015-12-01 18:42 ` Richard Henderson -1 siblings, 0 replies; 27+ messages in thread From: Richard Henderson @ 2015-12-01 18:42 UTC (permalink / raw) To: Eduardo Habkost, Paolo Bonzini; +Cc: qemu-devel, Huaitong Han, kvm On 12/01/2015 10:34 AM, Eduardo Habkost wrote: > BTW, if we are going to implement xsave in TCG, the > X86CPU<->xsave translation logic in kvm_{get,put}_xsave() could > be moved to generic code and reused by TCG instead of being > reimplemented. That's not trivial. In particular, stq_p isn't what the tcg helper needs to use, but rather cpu_stq_data_ra. Given the differing parameters, we'd have to resort to some sort of macro-ization. It's probably easiest to simply keep the two implementations separate. r~ ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area @ 2015-12-01 18:42 ` Richard Henderson 0 siblings, 0 replies; 27+ messages in thread From: Richard Henderson @ 2015-12-01 18:42 UTC (permalink / raw) To: Eduardo Habkost, Paolo Bonzini; +Cc: Huaitong Han, qemu-devel, kvm On 12/01/2015 10:34 AM, Eduardo Habkost wrote: > BTW, if we are going to implement xsave in TCG, the > X86CPU<->xsave translation logic in kvm_{get,put}_xsave() could > be moved to generic code and reused by TCG instead of being > reimplemented. That's not trivial. In particular, stq_p isn't what the tcg helper needs to use, but rather cpu_stq_data_ra. Given the differing parameters, we'd have to resort to some sort of macro-ization. It's probably easiest to simply keep the two implementations separate. r~ ^ permalink raw reply [flat|nested] 27+ messages in thread
* [for-2.6 PATCH 2/3] target-i386: Use xsave structs for ext_save_area 2015-11-28 19:56 ` [Qemu-devel] " Eduardo Habkost @ 2015-11-28 19:56 ` Eduardo Habkost -1 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-28 19:56 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, kvm, Huaitong Han This doesn't introduce any change in the code, as the offsets and struct sizes match what was present in the table. This can be validated by the QEMU_BUILD_BUG_ON lines on target-i386/cpu.h, which ensures the struct sizes and offsets match the existing values in ext_save_area. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- target-i386/cpu.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 11e5e39..bc95437 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -458,17 +458,23 @@ typedef struct ExtSaveArea { static const ExtSaveArea ext_save_areas[] = { [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX, - .offset = 0x240, .size = 0x100 }, + .offset = offsetof(X86XSaveArea, avx_state), + .size = sizeof(XSaveAVX) }, [3] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, - .offset = 0x3c0, .size = 0x40 }, + .offset = offsetof(X86XSaveArea, bndreg_state), + .size = sizeof(XSaveBNDREG) }, [4] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, - .offset = 0x400, .size = 0x40 }, + .offset = offsetof(X86XSaveArea, bndcsr_state), + .size = sizeof(XSaveBNDCSR) }, [5] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, - .offset = 0x440, .size = 0x40 }, + .offset = offsetof(X86XSaveArea, opmask_state), + .size = sizeof(XSaveOpmask) }, [6] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, - .offset = 0x480, .size = 0x200 }, + .offset = offsetof(X86XSaveArea, zmm_hi256_state), + .size = sizeof(XSaveZMM_Hi256) }, [7] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, - .offset = 0x680, .size = 0x400 }, + .offset = offsetof(X86XSaveArea, hi16_zmm_state), + .size = sizeof(XSaveHi16_ZMM) }, }; const char *get_register_name_32(unsigned int reg) -- 2.1.0 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [for-2.6 PATCH 2/3] target-i386: Use xsave structs for ext_save_area @ 2015-11-28 19:56 ` Eduardo Habkost 0 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-28 19:56 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, kvm, Huaitong Han This doesn't introduce any change in the code, as the offsets and struct sizes match what was present in the table. This can be validated by the QEMU_BUILD_BUG_ON lines on target-i386/cpu.h, which ensures the struct sizes and offsets match the existing values in ext_save_area. Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- target-i386/cpu.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/target-i386/cpu.c b/target-i386/cpu.c index 11e5e39..bc95437 100644 --- a/target-i386/cpu.c +++ b/target-i386/cpu.c @@ -458,17 +458,23 @@ typedef struct ExtSaveArea { static const ExtSaveArea ext_save_areas[] = { [2] = { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX, - .offset = 0x240, .size = 0x100 }, + .offset = offsetof(X86XSaveArea, avx_state), + .size = sizeof(XSaveAVX) }, [3] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, - .offset = 0x3c0, .size = 0x40 }, + .offset = offsetof(X86XSaveArea, bndreg_state), + .size = sizeof(XSaveBNDREG) }, [4] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_MPX, - .offset = 0x400, .size = 0x40 }, + .offset = offsetof(X86XSaveArea, bndcsr_state), + .size = sizeof(XSaveBNDCSR) }, [5] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, - .offset = 0x440, .size = 0x40 }, + .offset = offsetof(X86XSaveArea, opmask_state), + .size = sizeof(XSaveOpmask) }, [6] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, - .offset = 0x480, .size = 0x200 }, + .offset = offsetof(X86XSaveArea, zmm_hi256_state), + .size = sizeof(XSaveZMM_Hi256) }, [7] = { .feature = FEAT_7_0_EBX, .bits = CPUID_7_0_EBX_AVX512F, - .offset = 0x680, .size = 0x400 }, + .offset = offsetof(X86XSaveArea, hi16_zmm_state), + .size = sizeof(XSaveHi16_ZMM) }, }; const char *get_register_name_32(unsigned int reg) -- 2.1.0 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [for-2.6 PATCH 3/3] target-i386: kvm: Use X86XSaveArea struct for xsave save/load 2015-11-28 19:56 ` [Qemu-devel] " Eduardo Habkost @ 2015-11-28 19:56 ` Eduardo Habkost -1 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-28 19:56 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, kvm, Huaitong Han Instead of using offset macros and bit operations in a uint32_t array, use the X86XSaveArea struct to perform the loading/saving operations in kvm_put_xsave() and kvm_get_xsave(). Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- target-i386/kvm.c | 144 ++++++++++++++++++++---------------------------------- 1 file changed, 52 insertions(+), 92 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ee6c213..5e7ec70 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1203,50 +1203,11 @@ static int kvm_put_fpu(X86CPU *cpu) return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_FPU, &fpu); } -#define XSAVE_FCW_FSW 0 -#define XSAVE_FTW_FOP 1 -#define XSAVE_CWD_RIP 2 -#define XSAVE_CWD_RDP 4 -#define XSAVE_MXCSR 6 -#define XSAVE_ST_SPACE 8 -#define XSAVE_XMM_SPACE 40 -#define XSAVE_XSTATE_BV 128 -#define XSAVE_YMMH_SPACE 144 -#define XSAVE_BNDREGS 240 -#define XSAVE_BNDCSR 256 -#define XSAVE_OPMASK 272 -#define XSAVE_ZMM_Hi256 288 -#define XSAVE_Hi16_ZMM 416 - -#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); - - static int kvm_put_xsave(X86CPU *cpu) { CPUX86State *env = &cpu->env; - struct kvm_xsave* xsave = env->kvm_xsave_buf; + X86XSaveArea *xsave = env->kvm_xsave_buf; uint16_t cwd, swd, twd; - uint8_t *xmm, *ymmh, *zmmh; int i, r; if (!has_xsave) { @@ -1261,37 +1222,38 @@ static int kvm_put_xsave(X86CPU *cpu) for (i = 0; i < 8; ++i) { twd |= (!env->fptags[i]) << i; } - xsave->region[XSAVE_FCW_FSW] = (uint32_t)(swd << 16) + cwd; - xsave->region[XSAVE_FTW_FOP] = (uint32_t)(env->fpop << 16) + twd; - memcpy(&xsave->region[XSAVE_CWD_RIP], &env->fpip, sizeof(env->fpip)); - memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp)); - memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs, + xsave->legacy.fcw = cwd; + xsave->legacy.fsw = swd; + xsave->legacy.ftw = twd; + xsave->legacy.fpop = env->fpop; + xsave->legacy.fpip = env->fpip; + xsave->legacy.fpdp = env->fpdp; + memcpy(&xsave->legacy.fpregs, env->fpregs, sizeof env->fpregs); - xsave->region[XSAVE_MXCSR] = env->mxcsr; - *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv; - memcpy(&xsave->region[XSAVE_BNDREGS], env->bnd_regs, + xsave->legacy.mxcsr = env->mxcsr; + xsave->header.xstate_bv = env->xstate_bv; + memcpy(&xsave->bndreg_state.bnd_regs, env->bnd_regs, sizeof env->bnd_regs); - memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs, - sizeof(env->bndcs_regs)); - memcpy(&xsave->region[XSAVE_OPMASK], env->opmask_regs, + xsave->bndcsr_state.bndcsr = env->bndcs_regs; + memcpy(&xsave->opmask_state.opmask_regs, env->opmask_regs, sizeof env->opmask_regs); - xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; - ymmh = (uint8_t *)&xsave->region[XSAVE_YMMH_SPACE]; - zmmh = (uint8_t *)&xsave->region[XSAVE_ZMM_Hi256]; - for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) { - stq_p(xmm, env->xmm_regs[i].XMM_Q(0)); - stq_p(xmm+8, env->xmm_regs[i].XMM_Q(1)); - stq_p(ymmh, env->xmm_regs[i].XMM_Q(2)); - stq_p(ymmh+8, env->xmm_regs[i].XMM_Q(3)); - stq_p(zmmh, env->xmm_regs[i].XMM_Q(4)); - stq_p(zmmh+8, env->xmm_regs[i].XMM_Q(5)); - stq_p(zmmh+16, env->xmm_regs[i].XMM_Q(6)); - stq_p(zmmh+24, env->xmm_regs[i].XMM_Q(7)); + for (i = 0; i < CPU_NB_REGS; i++) { + X86LegacyXSaveArea *legacy = &xsave->legacy; + XSaveAVX *avx = &xsave->avx_state; + XSaveZMM_Hi256 *zmm_hi256 = &xsave->zmm_hi256_state; + stq_p(&legacy->xmm_regs[i][0], env->xmm_regs[i].XMM_Q(0)); + stq_p(&legacy->xmm_regs[i][1], env->xmm_regs[i].XMM_Q(1)); + stq_p(&avx->ymmh[i][0], env->xmm_regs[i].XMM_Q(2)); + stq_p(&avx->ymmh[i][1], env->xmm_regs[i].XMM_Q(3)); + stq_p(&zmm_hi256->zmm_hi256[i][0], env->xmm_regs[i].XMM_Q(4)); + stq_p(&zmm_hi256->zmm_hi256[i][1], env->xmm_regs[i].XMM_Q(5)); + stq_p(&zmm_hi256->zmm_hi256[i][2], env->xmm_regs[i].XMM_Q(6)); + stq_p(&zmm_hi256->zmm_hi256[i][3], env->xmm_regs[i].XMM_Q(7)); } #ifdef TARGET_X86_64 - memcpy(&xsave->region[XSAVE_Hi16_ZMM], &env->xmm_regs[16], + memcpy(&xsave->hi16_zmm_state.hi16_zmm, &env->xmm_regs[16], 16 * sizeof env->xmm_regs[16]); #endif r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave); @@ -1627,9 +1589,8 @@ static int kvm_get_fpu(X86CPU *cpu) static int kvm_get_xsave(X86CPU *cpu) { CPUX86State *env = &cpu->env; - struct kvm_xsave* xsave = env->kvm_xsave_buf; + X86XSaveArea *xsave = env->kvm_xsave_buf; int ret, i; - const uint8_t *xmm, *ymmh, *zmmh; uint16_t cwd, swd, twd; if (!has_xsave) { @@ -1641,45 +1602,44 @@ static int kvm_get_xsave(X86CPU *cpu) return ret; } - cwd = (uint16_t)xsave->region[XSAVE_FCW_FSW]; - swd = (uint16_t)(xsave->region[XSAVE_FCW_FSW] >> 16); - twd = (uint16_t)xsave->region[XSAVE_FTW_FOP]; - env->fpop = (uint16_t)(xsave->region[XSAVE_FTW_FOP] >> 16); + cwd = xsave->legacy.fcw; + swd = xsave->legacy.fsw; + twd = xsave->legacy.ftw; + env->fpop = xsave->legacy.fpop; env->fpstt = (swd >> 11) & 7; env->fpus = swd; env->fpuc = cwd; for (i = 0; i < 8; ++i) { env->fptags[i] = !((twd >> i) & 1); } - memcpy(&env->fpip, &xsave->region[XSAVE_CWD_RIP], sizeof(env->fpip)); - memcpy(&env->fpdp, &xsave->region[XSAVE_CWD_RDP], sizeof(env->fpdp)); - env->mxcsr = xsave->region[XSAVE_MXCSR]; - memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE], + env->fpip = xsave->legacy.fpip; + env->fpdp = xsave->legacy.fpdp; + env->mxcsr = xsave->legacy.mxcsr; + memcpy(env->fpregs, &xsave->legacy.fpregs, sizeof env->fpregs); - env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV]; - memcpy(env->bnd_regs, &xsave->region[XSAVE_BNDREGS], + env->xstate_bv = xsave->header.xstate_bv; + memcpy(env->bnd_regs, &xsave->bndreg_state.bnd_regs, sizeof env->bnd_regs); - memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR], - sizeof(env->bndcs_regs)); - memcpy(env->opmask_regs, &xsave->region[XSAVE_OPMASK], + env->bndcs_regs = xsave->bndcsr_state.bndcsr; + memcpy(env->opmask_regs, &xsave->opmask_state.opmask_regs, sizeof env->opmask_regs); - xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; - ymmh = (const uint8_t *)&xsave->region[XSAVE_YMMH_SPACE]; - zmmh = (const uint8_t *)&xsave->region[XSAVE_ZMM_Hi256]; - for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) { - env->xmm_regs[i].XMM_Q(0) = ldq_p(xmm); - env->xmm_regs[i].XMM_Q(1) = ldq_p(xmm+8); - env->xmm_regs[i].XMM_Q(2) = ldq_p(ymmh); - env->xmm_regs[i].XMM_Q(3) = ldq_p(ymmh+8); - env->xmm_regs[i].XMM_Q(4) = ldq_p(zmmh); - env->xmm_regs[i].XMM_Q(5) = ldq_p(zmmh+8); - env->xmm_regs[i].XMM_Q(6) = ldq_p(zmmh+16); - env->xmm_regs[i].XMM_Q(7) = ldq_p(zmmh+24); + for (i = 0; i < CPU_NB_REGS; i++) { + X86LegacyXSaveArea *legacy = &xsave->legacy; + XSaveAVX *avx = &xsave->avx_state; + XSaveZMM_Hi256 *zmm_hi256 = &xsave->zmm_hi256_state; + env->xmm_regs[i].XMM_Q(0) = ldq_p(&legacy->xmm_regs[i][0]); + env->xmm_regs[i].XMM_Q(1) = ldq_p(&legacy->xmm_regs[i][1]); + env->xmm_regs[i].XMM_Q(2) = ldq_p(&avx->ymmh[i][0]); + env->xmm_regs[i].XMM_Q(3) = ldq_p(&avx->ymmh[i][1]); + env->xmm_regs[i].XMM_Q(4) = ldq_p(&zmm_hi256->zmm_hi256[i][0]); + env->xmm_regs[i].XMM_Q(5) = ldq_p(&zmm_hi256->zmm_hi256[i][1]); + env->xmm_regs[i].XMM_Q(6) = ldq_p(&zmm_hi256->zmm_hi256[i][2]); + env->xmm_regs[i].XMM_Q(7) = ldq_p(&zmm_hi256->zmm_hi256[i][3]); } #ifdef TARGET_X86_64 - memcpy(&env->xmm_regs[16], &xsave->region[XSAVE_Hi16_ZMM], + memcpy(&env->xmm_regs[16], &xsave->hi16_zmm_state.hi16_zmm, 16 * sizeof env->xmm_regs[16]); #endif return 0; -- 2.1.0 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* [Qemu-devel] [for-2.6 PATCH 3/3] target-i386: kvm: Use X86XSaveArea struct for xsave save/load @ 2015-11-28 19:56 ` Eduardo Habkost 0 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-28 19:56 UTC (permalink / raw) To: qemu-devel; +Cc: Paolo Bonzini, kvm, Huaitong Han Instead of using offset macros and bit operations in a uint32_t array, use the X86XSaveArea struct to perform the loading/saving operations in kvm_put_xsave() and kvm_get_xsave(). Signed-off-by: Eduardo Habkost <ehabkost@redhat.com> --- target-i386/kvm.c | 144 ++++++++++++++++++++---------------------------------- 1 file changed, 52 insertions(+), 92 deletions(-) diff --git a/target-i386/kvm.c b/target-i386/kvm.c index ee6c213..5e7ec70 100644 --- a/target-i386/kvm.c +++ b/target-i386/kvm.c @@ -1203,50 +1203,11 @@ static int kvm_put_fpu(X86CPU *cpu) return kvm_vcpu_ioctl(CPU(cpu), KVM_SET_FPU, &fpu); } -#define XSAVE_FCW_FSW 0 -#define XSAVE_FTW_FOP 1 -#define XSAVE_CWD_RIP 2 -#define XSAVE_CWD_RDP 4 -#define XSAVE_MXCSR 6 -#define XSAVE_ST_SPACE 8 -#define XSAVE_XMM_SPACE 40 -#define XSAVE_XSTATE_BV 128 -#define XSAVE_YMMH_SPACE 144 -#define XSAVE_BNDREGS 240 -#define XSAVE_BNDCSR 256 -#define XSAVE_OPMASK 272 -#define XSAVE_ZMM_Hi256 288 -#define XSAVE_Hi16_ZMM 416 - -#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); - - static int kvm_put_xsave(X86CPU *cpu) { CPUX86State *env = &cpu->env; - struct kvm_xsave* xsave = env->kvm_xsave_buf; + X86XSaveArea *xsave = env->kvm_xsave_buf; uint16_t cwd, swd, twd; - uint8_t *xmm, *ymmh, *zmmh; int i, r; if (!has_xsave) { @@ -1261,37 +1222,38 @@ static int kvm_put_xsave(X86CPU *cpu) for (i = 0; i < 8; ++i) { twd |= (!env->fptags[i]) << i; } - xsave->region[XSAVE_FCW_FSW] = (uint32_t)(swd << 16) + cwd; - xsave->region[XSAVE_FTW_FOP] = (uint32_t)(env->fpop << 16) + twd; - memcpy(&xsave->region[XSAVE_CWD_RIP], &env->fpip, sizeof(env->fpip)); - memcpy(&xsave->region[XSAVE_CWD_RDP], &env->fpdp, sizeof(env->fpdp)); - memcpy(&xsave->region[XSAVE_ST_SPACE], env->fpregs, + xsave->legacy.fcw = cwd; + xsave->legacy.fsw = swd; + xsave->legacy.ftw = twd; + xsave->legacy.fpop = env->fpop; + xsave->legacy.fpip = env->fpip; + xsave->legacy.fpdp = env->fpdp; + memcpy(&xsave->legacy.fpregs, env->fpregs, sizeof env->fpregs); - xsave->region[XSAVE_MXCSR] = env->mxcsr; - *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv; - memcpy(&xsave->region[XSAVE_BNDREGS], env->bnd_regs, + xsave->legacy.mxcsr = env->mxcsr; + xsave->header.xstate_bv = env->xstate_bv; + memcpy(&xsave->bndreg_state.bnd_regs, env->bnd_regs, sizeof env->bnd_regs); - memcpy(&xsave->region[XSAVE_BNDCSR], &env->bndcs_regs, - sizeof(env->bndcs_regs)); - memcpy(&xsave->region[XSAVE_OPMASK], env->opmask_regs, + xsave->bndcsr_state.bndcsr = env->bndcs_regs; + memcpy(&xsave->opmask_state.opmask_regs, env->opmask_regs, sizeof env->opmask_regs); - xmm = (uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; - ymmh = (uint8_t *)&xsave->region[XSAVE_YMMH_SPACE]; - zmmh = (uint8_t *)&xsave->region[XSAVE_ZMM_Hi256]; - for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) { - stq_p(xmm, env->xmm_regs[i].XMM_Q(0)); - stq_p(xmm+8, env->xmm_regs[i].XMM_Q(1)); - stq_p(ymmh, env->xmm_regs[i].XMM_Q(2)); - stq_p(ymmh+8, env->xmm_regs[i].XMM_Q(3)); - stq_p(zmmh, env->xmm_regs[i].XMM_Q(4)); - stq_p(zmmh+8, env->xmm_regs[i].XMM_Q(5)); - stq_p(zmmh+16, env->xmm_regs[i].XMM_Q(6)); - stq_p(zmmh+24, env->xmm_regs[i].XMM_Q(7)); + for (i = 0; i < CPU_NB_REGS; i++) { + X86LegacyXSaveArea *legacy = &xsave->legacy; + XSaveAVX *avx = &xsave->avx_state; + XSaveZMM_Hi256 *zmm_hi256 = &xsave->zmm_hi256_state; + stq_p(&legacy->xmm_regs[i][0], env->xmm_regs[i].XMM_Q(0)); + stq_p(&legacy->xmm_regs[i][1], env->xmm_regs[i].XMM_Q(1)); + stq_p(&avx->ymmh[i][0], env->xmm_regs[i].XMM_Q(2)); + stq_p(&avx->ymmh[i][1], env->xmm_regs[i].XMM_Q(3)); + stq_p(&zmm_hi256->zmm_hi256[i][0], env->xmm_regs[i].XMM_Q(4)); + stq_p(&zmm_hi256->zmm_hi256[i][1], env->xmm_regs[i].XMM_Q(5)); + stq_p(&zmm_hi256->zmm_hi256[i][2], env->xmm_regs[i].XMM_Q(6)); + stq_p(&zmm_hi256->zmm_hi256[i][3], env->xmm_regs[i].XMM_Q(7)); } #ifdef TARGET_X86_64 - memcpy(&xsave->region[XSAVE_Hi16_ZMM], &env->xmm_regs[16], + memcpy(&xsave->hi16_zmm_state.hi16_zmm, &env->xmm_regs[16], 16 * sizeof env->xmm_regs[16]); #endif r = kvm_vcpu_ioctl(CPU(cpu), KVM_SET_XSAVE, xsave); @@ -1627,9 +1589,8 @@ static int kvm_get_fpu(X86CPU *cpu) static int kvm_get_xsave(X86CPU *cpu) { CPUX86State *env = &cpu->env; - struct kvm_xsave* xsave = env->kvm_xsave_buf; + X86XSaveArea *xsave = env->kvm_xsave_buf; int ret, i; - const uint8_t *xmm, *ymmh, *zmmh; uint16_t cwd, swd, twd; if (!has_xsave) { @@ -1641,45 +1602,44 @@ static int kvm_get_xsave(X86CPU *cpu) return ret; } - cwd = (uint16_t)xsave->region[XSAVE_FCW_FSW]; - swd = (uint16_t)(xsave->region[XSAVE_FCW_FSW] >> 16); - twd = (uint16_t)xsave->region[XSAVE_FTW_FOP]; - env->fpop = (uint16_t)(xsave->region[XSAVE_FTW_FOP] >> 16); + cwd = xsave->legacy.fcw; + swd = xsave->legacy.fsw; + twd = xsave->legacy.ftw; + env->fpop = xsave->legacy.fpop; env->fpstt = (swd >> 11) & 7; env->fpus = swd; env->fpuc = cwd; for (i = 0; i < 8; ++i) { env->fptags[i] = !((twd >> i) & 1); } - memcpy(&env->fpip, &xsave->region[XSAVE_CWD_RIP], sizeof(env->fpip)); - memcpy(&env->fpdp, &xsave->region[XSAVE_CWD_RDP], sizeof(env->fpdp)); - env->mxcsr = xsave->region[XSAVE_MXCSR]; - memcpy(env->fpregs, &xsave->region[XSAVE_ST_SPACE], + env->fpip = xsave->legacy.fpip; + env->fpdp = xsave->legacy.fpdp; + env->mxcsr = xsave->legacy.mxcsr; + memcpy(env->fpregs, &xsave->legacy.fpregs, sizeof env->fpregs); - env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV]; - memcpy(env->bnd_regs, &xsave->region[XSAVE_BNDREGS], + env->xstate_bv = xsave->header.xstate_bv; + memcpy(env->bnd_regs, &xsave->bndreg_state.bnd_regs, sizeof env->bnd_regs); - memcpy(&env->bndcs_regs, &xsave->region[XSAVE_BNDCSR], - sizeof(env->bndcs_regs)); - memcpy(env->opmask_regs, &xsave->region[XSAVE_OPMASK], + env->bndcs_regs = xsave->bndcsr_state.bndcsr; + memcpy(env->opmask_regs, &xsave->opmask_state.opmask_regs, sizeof env->opmask_regs); - xmm = (const uint8_t *)&xsave->region[XSAVE_XMM_SPACE]; - ymmh = (const uint8_t *)&xsave->region[XSAVE_YMMH_SPACE]; - zmmh = (const uint8_t *)&xsave->region[XSAVE_ZMM_Hi256]; - for (i = 0; i < CPU_NB_REGS; i++, xmm += 16, ymmh += 16, zmmh += 32) { - env->xmm_regs[i].XMM_Q(0) = ldq_p(xmm); - env->xmm_regs[i].XMM_Q(1) = ldq_p(xmm+8); - env->xmm_regs[i].XMM_Q(2) = ldq_p(ymmh); - env->xmm_regs[i].XMM_Q(3) = ldq_p(ymmh+8); - env->xmm_regs[i].XMM_Q(4) = ldq_p(zmmh); - env->xmm_regs[i].XMM_Q(5) = ldq_p(zmmh+8); - env->xmm_regs[i].XMM_Q(6) = ldq_p(zmmh+16); - env->xmm_regs[i].XMM_Q(7) = ldq_p(zmmh+24); + for (i = 0; i < CPU_NB_REGS; i++) { + X86LegacyXSaveArea *legacy = &xsave->legacy; + XSaveAVX *avx = &xsave->avx_state; + XSaveZMM_Hi256 *zmm_hi256 = &xsave->zmm_hi256_state; + env->xmm_regs[i].XMM_Q(0) = ldq_p(&legacy->xmm_regs[i][0]); + env->xmm_regs[i].XMM_Q(1) = ldq_p(&legacy->xmm_regs[i][1]); + env->xmm_regs[i].XMM_Q(2) = ldq_p(&avx->ymmh[i][0]); + env->xmm_regs[i].XMM_Q(3) = ldq_p(&avx->ymmh[i][1]); + env->xmm_regs[i].XMM_Q(4) = ldq_p(&zmm_hi256->zmm_hi256[i][0]); + env->xmm_regs[i].XMM_Q(5) = ldq_p(&zmm_hi256->zmm_hi256[i][1]); + env->xmm_regs[i].XMM_Q(6) = ldq_p(&zmm_hi256->zmm_hi256[i][2]); + env->xmm_regs[i].XMM_Q(7) = ldq_p(&zmm_hi256->zmm_hi256[i][3]); } #ifdef TARGET_X86_64 - memcpy(&env->xmm_regs[16], &xsave->region[XSAVE_Hi16_ZMM], + memcpy(&env->xmm_regs[16], &xsave->hi16_zmm_state.hi16_zmm, 16 * sizeof env->xmm_regs[16]); #endif return 0; -- 2.1.0 ^ permalink raw reply related [flat|nested] 27+ messages in thread
* Re: [for-2.6 PATCH 0/3] target-i386: Use C struct for xsave area layout, offsets & sizes 2015-11-28 19:56 ` [Qemu-devel] " Eduardo Habkost @ 2015-11-30 11:21 ` Paolo Bonzini -1 siblings, 0 replies; 27+ messages in thread From: Paolo Bonzini @ 2015-11-30 11:21 UTC (permalink / raw) To: Eduardo Habkost, qemu-devel; +Cc: kvm, Huaitong Han On 28/11/2015 20:56, Eduardo Habkost wrote: > I still need to figure out a way to write unit tests for the new > code. Maybe I will just copy and paste the new and old functions, > and test them locally (checking if they give the same results > when translating blobs of random bytes). Aren't the QEMU_BUILD_BUG_ON enough? No need to delete them in patch 3, though perhaps you can remove the #defines. Paolo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 0/3] target-i386: Use C struct for xsave area layout, offsets & sizes @ 2015-11-30 11:21 ` Paolo Bonzini 0 siblings, 0 replies; 27+ messages in thread From: Paolo Bonzini @ 2015-11-30 11:21 UTC (permalink / raw) To: Eduardo Habkost, qemu-devel; +Cc: Huaitong Han, kvm On 28/11/2015 20:56, Eduardo Habkost wrote: > I still need to figure out a way to write unit tests for the new > code. Maybe I will just copy and paste the new and old functions, > and test them locally (checking if they give the same results > when translating blobs of random bytes). Aren't the QEMU_BUILD_BUG_ON enough? No need to delete them in patch 3, though perhaps you can remove the #defines. Paolo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [for-2.6 PATCH 0/3] target-i386: Use C struct for xsave area layout, offsets & sizes 2015-11-30 11:21 ` [Qemu-devel] " Paolo Bonzini @ 2015-11-30 14:14 ` Eduardo Habkost -1 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-30 14:14 UTC (permalink / raw) To: Paolo Bonzini; +Cc: qemu-devel, kvm, Huaitong Han On Mon, Nov 30, 2015 at 12:21:23PM +0100, Paolo Bonzini wrote: > > > On 28/11/2015 20:56, Eduardo Habkost wrote: > > I still need to figure out a way to write unit tests for the new > > code. Maybe I will just copy and paste the new and old functions, > > and test them locally (checking if they give the same results > > when translating blobs of random bytes). > > Aren't the QEMU_BUILD_BUG_ON enough? No need to delete them in patch 3, > though perhaps you can remove the #defines. Just wanted to be 100% sure. Even if the offets are all correct, I might have made other mistakes when translating the get/save code. About the QEMU_BUILD_BUG_ON lines, we can keep them if you like. We could translate the uint32_t offsets to byte offsets after ptach 3/3, to make them easier to compare to the Intel docs. -- Eduardo ^ permalink raw reply [flat|nested] 27+ messages in thread
* Re: [Qemu-devel] [for-2.6 PATCH 0/3] target-i386: Use C struct for xsave area layout, offsets & sizes @ 2015-11-30 14:14 ` Eduardo Habkost 0 siblings, 0 replies; 27+ messages in thread From: Eduardo Habkost @ 2015-11-30 14:14 UTC (permalink / raw) To: Paolo Bonzini; +Cc: Huaitong Han, qemu-devel, kvm On Mon, Nov 30, 2015 at 12:21:23PM +0100, Paolo Bonzini wrote: > > > On 28/11/2015 20:56, Eduardo Habkost wrote: > > I still need to figure out a way to write unit tests for the new > > code. Maybe I will just copy and paste the new and old functions, > > and test them locally (checking if they give the same results > > when translating blobs of random bytes). > > Aren't the QEMU_BUILD_BUG_ON enough? No need to delete them in patch 3, > though perhaps you can remove the #defines. Just wanted to be 100% sure. Even if the offets are all correct, I might have made other mistakes when translating the get/save code. About the QEMU_BUILD_BUG_ON lines, we can keep them if you like. We could translate the uint32_t offsets to byte offsets after ptach 3/3, to make them easier to compare to the Intel docs. -- Eduardo ^ permalink raw reply [flat|nested] 27+ messages in thread
end of thread, other threads:[~2015-12-01 18:43 UTC | newest] Thread overview: 27+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2015-11-28 19:56 [for-2.6 PATCH 0/3] target-i386: Use C struct for xsave area layout, offsets & sizes Eduardo Habkost 2015-11-28 19:56 ` [Qemu-devel] " Eduardo Habkost 2015-11-28 19:56 ` [for-2.6 PATCH 1/3] target-i386: Define structs for layout of xsave area Eduardo Habkost 2015-11-28 19:56 ` [Qemu-devel] " Eduardo Habkost 2015-11-30 11:18 ` Paolo Bonzini 2015-11-30 11:18 ` [Qemu-devel] " Paolo Bonzini 2015-11-30 14:48 ` Eduardo Habkost 2015-11-30 14:48 ` [Qemu-devel] " Eduardo Habkost 2015-12-01 17:09 ` Richard Henderson 2015-12-01 17:15 ` Eduardo Habkost 2015-12-01 17:15 ` Eduardo Habkost 2015-12-01 17:20 ` Richard Henderson 2015-12-01 17:20 ` Richard Henderson 2015-12-01 17:27 ` Paolo Bonzini 2015-12-01 17:27 ` Paolo Bonzini 2015-12-01 18:34 ` Eduardo Habkost 2015-12-01 18:34 ` Eduardo Habkost 2015-12-01 18:42 ` Richard Henderson 2015-12-01 18:42 ` Richard Henderson 2015-11-28 19:56 ` [for-2.6 PATCH 2/3] target-i386: Use xsave structs for ext_save_area Eduardo Habkost 2015-11-28 19:56 ` [Qemu-devel] " Eduardo Habkost 2015-11-28 19:56 ` [for-2.6 PATCH 3/3] target-i386: kvm: Use X86XSaveArea struct for xsave save/load Eduardo Habkost 2015-11-28 19:56 ` [Qemu-devel] " Eduardo Habkost 2015-11-30 11:21 ` [for-2.6 PATCH 0/3] target-i386: Use C struct for xsave area layout, offsets & sizes Paolo Bonzini 2015-11-30 11:21 ` [Qemu-devel] " Paolo Bonzini 2015-11-30 14:14 ` Eduardo Habkost 2015-11-30 14:14 ` [Qemu-devel] " Eduardo Habkost
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.