target-i386: xsave: Add FP and SSE bits to x86_ext_save_areas

Instead of treating the FP and SSE bits as special cases, add
them to the x86_ext_save_areas array. This will simplify the code
that calculates the supported xsave components and the size of
the xsave area.

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
This commit is contained in:
Eduardo Habkost 2016-09-30 15:49:42 -03:00
parent 16d2fcaa50
commit e3c9022b4e

View File

@ -535,6 +535,20 @@ typedef struct ExtSaveArea {
} ExtSaveArea; } ExtSaveArea;
static const ExtSaveArea x86_ext_save_areas[] = { static const ExtSaveArea x86_ext_save_areas[] = {
[XSTATE_FP_BIT] = {
/* x87 FP state component is always enabled if XSAVE is supported */
.feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
/* x87 state is in the legacy region of the XSAVE area */
.offset = 0,
.size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
},
[XSTATE_SSE_BIT] = {
/* SSE state component is always enabled if XSAVE is supported */
.feature = FEAT_1_ECX, .bits = CPUID_EXT_XSAVE,
/* SSE state is in the legacy region of the XSAVE area */
.offset = 0,
.size = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader),
},
[XSTATE_YMM_BIT] = [XSTATE_YMM_BIT] =
{ .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX, { .feature = FEAT_1_ECX, .bits = CPUID_EXT_AVX,
.offset = offsetof(X86XSaveArea, avx_state), .offset = offsetof(X86XSaveArea, avx_state),
@ -568,9 +582,9 @@ static const ExtSaveArea x86_ext_save_areas[] = {
static uint32_t xsave_area_size(uint64_t mask) static uint32_t xsave_area_size(uint64_t mask)
{ {
int i; int i;
uint64_t ret = sizeof(X86LegacyXSaveArea) + sizeof(X86XSaveHeader); uint64_t ret = 0;
for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) { for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
const ExtSaveArea *esa = &x86_ext_save_areas[i]; const ExtSaveArea *esa = &x86_ext_save_areas[i];
if ((mask >> i) & 1) { if ((mask >> i) & 1) {
ret = MAX(ret, esa->offset + esa->size); ret = MAX(ret, esa->offset + esa->size);
@ -2961,8 +2975,8 @@ static void x86_cpu_enable_xsave_components(X86CPU *cpu)
return; return;
} }
mask = (XSTATE_FP_MASK | XSTATE_SSE_MASK); mask = 0;
for (i = 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) { for (i = 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) {
const ExtSaveArea *esa = &x86_ext_save_areas[i]; const ExtSaveArea *esa = &x86_ext_save_areas[i];
if (env->features[esa->feature] & esa->bits) { if (env->features[esa->feature] & esa->bits) {
mask |= (1ULL << i); mask |= (1ULL << i);