Paul Gofman : wineboot: Initialize XState features in user_shared_data.
Alexandre Julliard
julliard at winehq.org
Thu Aug 20 16:03:36 CDT 2020
Module: wine
Branch: master
Commit: 97b5ad7597bf2add39251d7379fc607bf1578478
URL: https://source.winehq.org/git/wine.git/?a=commit;h=97b5ad7597bf2add39251d7379fc607bf1578478
Author: Paul Gofman <pgofman at codeweavers.com>
Date: Thu Aug 20 00:22:59 2020 +0300
wineboot: Initialize XState features in user_shared_data.
Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/ntdll/tests/virtual.c | 67 ++++++++++++++++++++++++++++++++++++++++++++
programs/wineboot/wineboot.c | 59 ++++++++++++++++++++++++++++++++++++++
2 files changed, 126 insertions(+)
diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c
index beab744178..4a0a4a6b8e 100644
--- a/dlls/ntdll/tests/virtual.c
+++ b/dlls/ntdll/tests/virtual.c
@@ -516,9 +516,34 @@ static void test_NtMapViewOfSection(void)
CloseHandle(process);
}
+#define SUPPORTED_XSTATE_FEATURES ((1 << XSTATE_LEGACY_FLOATING_POINT) | (1 << XSTATE_LEGACY_SSE) | (1 << XSTATE_AVX))
+
static void test_user_shared_data(void)
{
+ struct old_xstate_configuration
+ {
+ ULONG64 EnabledFeatures;
+ ULONG Size;
+ ULONG OptimizedSave:1;
+ ULONG CompactionEnabled:1;
+ XSTATE_FEATURE Features[MAXIMUM_XSTATE_FEATURES];
+ };
+
+ static const ULONG feature_offsets[] =
+ {
+ 0,
+ 160, /*offsetof(XMM_SAVE_AREA32, XmmRegisters)*/
+ 512 /* sizeof(XMM_SAVE_AREA32) */ + offsetof(XSTATE, YmmContext),
+ };
+ static const ULONG feature_sizes[] =
+ {
+ 160,
+ 256, /*sizeof(M128A) * 16 */
+ sizeof(YMMCONTEXT),
+ };
const KSHARED_USER_DATA *user_shared_data = (void *)0x7ffe0000;
+ XSTATE_CONFIGURATION xstate = user_shared_data->XState;
+ unsigned int i;
ok(user_shared_data->NumberOfPhysicalPages == sbi.MmNumberOfPhysicalPages,
"Got number of physical pages %#x, expected %#x.\n",
@@ -534,6 +559,48 @@ static void test_user_shared_data(void)
ok(user_shared_data->ActiveGroupCount == 1
|| broken(!user_shared_data->ActiveGroupCount) /* before Win7 */,
"Got unexpected ActiveGroupCount %u.\n", user_shared_data->ActiveGroupCount);
+
+ if (!xstate.EnabledFeatures)
+ {
+ struct old_xstate_configuration *xs_old
+ = (struct old_xstate_configuration *)((char *)user_shared_data + 0x3e0);
+
+ if (!xs_old->EnabledFeatures)
+ {
+ skip("XState features are not supported.\n");
+ return;
+ }
+
+ memset(&xstate, 0, sizeof(xstate));
+ xstate.EnabledFeatures = xstate.EnabledVolatileFeatures = xs_old->EnabledFeatures;
+ memcpy(&xstate.Size, &xs_old->Size, sizeof(*xs_old) - offsetof(struct old_xstate_configuration, Size));
+ for (i = 0; i < 3; ++i)
+ xstate.AllFeatures[i] = xs_old->Features[i].Size;
+ xstate.AllFeatureSize = 512 + sizeof(XSTATE);
+ }
+
+ trace("XState EnabledFeatures %s.\n", wine_dbgstr_longlong(xstate.EnabledFeatures));
+ ok((xstate.EnabledFeatures & SUPPORTED_XSTATE_FEATURES) == SUPPORTED_XSTATE_FEATURES,
+ "Got unexpected EnabledFeatures %s.\n", wine_dbgstr_longlong(xstate.EnabledFeatures));
+ ok((xstate.EnabledVolatileFeatures & SUPPORTED_XSTATE_FEATURES) == xstate.EnabledFeatures,
+ "Got unexpected EnabledVolatileFeatures %s.\n", wine_dbgstr_longlong(xstate.EnabledVolatileFeatures));
+ ok(xstate.Size >= 512 + sizeof(XSTATE), "Got unexpected Size %u.\n", xstate.Size);
+ if (xstate.CompactionEnabled)
+ ok(xstate.OptimizedSave, "Got zero OptimizedSave with compaction enabled.\n");
+ ok(!xstate.AlignedFeatures, "Got unexpected AlignedFeatures %s.\n",
+ wine_dbgstr_longlong(xstate.AlignedFeatures));
+ ok(xstate.AllFeatureSize >= 512 + sizeof(XSTATE), "Got unexpected AllFeatureSize %u.\n",
+ xstate.AllFeatureSize);
+
+ for (i = 0; i < ARRAY_SIZE(feature_sizes); ++i)
+ {
+ ok(xstate.AllFeatures[i] == feature_sizes[i], "Got unexpected AllFeatures[%u] %u, expected %u.\n", i,
+ xstate.AllFeatures[i], feature_sizes[i]);
+ ok(xstate.Features[i].Size == feature_sizes[i], "Got unexpected Features[%u].Size %u, expected %u.\n", i,
+ xstate.Features[i].Size, feature_sizes[i]);
+ ok(xstate.Features[i].Offset == feature_offsets[i], "Got unexpected Features[%u].Offset %u, expected %u.\n",
+ i, xstate.Features[i].Offset, feature_offsets[i]);
+ }
}
START_TEST(virtual)
diff --git a/programs/wineboot/wineboot.c b/programs/wineboot/wineboot.c
index 902f6af042..2f8b7169cf 100644
--- a/programs/wineboot/wineboot.c
+++ b/programs/wineboot/wineboot.c
@@ -191,6 +191,63 @@ static DWORD set_reg_value_dword( HKEY hkey, const WCHAR *name, DWORD value )
return RegSetValueExW( hkey, name, 0, REG_DWORD, (const BYTE *)&value, sizeof(value) );
}
+#if defined(__i386__) || defined(__x86_64__)
+
+static void initialize_xstate_features(struct _KUSER_SHARED_DATA *data)
+{
+ XSTATE_CONFIGURATION *xstate = &data->XState;
+ unsigned int i;
+ int regs[4];
+
+ if (!data->ProcessorFeatures[PF_AVX_INSTRUCTIONS_AVAILABLE])
+ return;
+
+ __cpuidex(regs, 0, 0);
+
+ TRACE("Max cpuid level %#x.\n", regs[0]);
+ if (regs[0] < 0xd)
+ return;
+
+ __cpuidex(regs, 1, 0);
+ TRACE("CPU features %#x, %#x, %#x, %#x.\n", regs[0], regs[1], regs[2], regs[3]);
+ if (!(regs[2] & (0x1 << 27))) /* xsave OS enabled */
+ return;
+
+ __cpuidex(regs, 0xd, 0);
+ TRACE("XSAVE details %#x, %#x, %#x, %#x.\n", regs[0], regs[1], regs[2], regs[3]);
+ if (!(regs[0] & XSTATE_AVX))
+ return;
+
+ xstate->EnabledFeatures = (1 << XSTATE_LEGACY_FLOATING_POINT) | (1 << XSTATE_LEGACY_SSE) | (1 << XSTATE_AVX);
+ xstate->EnabledVolatileFeatures = xstate->EnabledFeatures;
+ xstate->Size = sizeof(XSAVE_FORMAT) + sizeof(XSTATE);
+ xstate->AllFeatureSize = regs[1];
+ xstate->AllFeatures[0] = offsetof(XSAVE_FORMAT, XmmRegisters);
+ xstate->AllFeatures[1] = sizeof(M128A) * 16;
+ xstate->AllFeatures[2] = sizeof(YMMCONTEXT);
+
+ for (i = 0; i < 3; ++i)
+ xstate->Features[i].Size = xstate->AllFeatures[i];
+
+ xstate->Features[1].Offset = xstate->Features[0].Size;
+ xstate->Features[2].Offset = sizeof(XSAVE_FORMAT) + offsetof(XSTATE, YmmContext);
+
+ __cpuidex(regs, 0xd, 1);
+ xstate->OptimizedSave = regs[0] & 1;
+ xstate->CompactionEnabled = !!(regs[0] & 2);
+
+ __cpuidex(regs, 0xd, 2);
+ TRACE("XSAVE feature 2 %#x, %#x, %#x, %#x.\n", regs[0], regs[1], regs[2], regs[3]);
+}
+
+#else
+
+static void initialize_xstate_features(struct _KUSER_SHARED_DATA *data)
+{
+}
+
+#endif
+
static void create_user_shared_data(void)
{
struct _KUSER_SHARED_DATA *data;
@@ -276,6 +333,8 @@ static void create_user_shared_data(void)
data->ActiveProcessorCount = NtCurrentTeb()->Peb->NumberOfProcessors;
data->ActiveGroupCount = 1;
+ initialize_xstate_features( data );
+
UnmapViewOfFile( data );
}
More information about the wine-cvs
mailing list