Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F106092103
D47394.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
4 KB
Referenced Files
None
Subscribers
None
D47394.diff
View Options
diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c
--- a/sys/amd64/amd64/fpu.c
+++ b/sys/amd64/amd64/fpu.c
@@ -164,12 +164,14 @@
int use_xsave; /* non-static for cpu_switch.S */
uint64_t xsave_mask; /* the same */
+static uint64_t xsave_extensions;
static uma_zone_t fpu_save_area_zone;
static struct savefpu *fpu_initialstate;
static struct xsave_area_elm_descr {
u_int offset;
u_int size;
+ u_int flags;
} *xsave_area_desc;
static void
@@ -452,6 +454,9 @@
* Region of an XSAVE Area" for the source of offsets/sizes.
*/
if (use_xsave) {
+ cpuid_count(0xd, 1, cp);
+ xsave_extensions = cp[0];
+
xstate_bv = (uint64_t *)((char *)(fpu_initialstate + 1) +
offsetof(struct xstate_hdr, xstate_bv));
*xstate_bv = XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE;
@@ -465,8 +470,9 @@
for (i = 2; i < max_ext_n; i++) {
cpuid_count(0xd, i, cp);
- xsave_area_desc[i].offset = cp[1];
xsave_area_desc[i].size = cp[0];
+ xsave_area_desc[i].offset = cp[1];
+ xsave_area_desc[i].flags = cp[2];
}
}
@@ -1285,3 +1291,106 @@
bcopy(fpu_initialstate, fsa, cpu_max_ext_state_size);
}
+
+static __inline void
+xsave_extfeature_check(uint64_t feature)
+{
+
+ KASSERT((feature & (feature - 1)) == 0,
+ ("%s: invalid XFEATURE 0x%lx", __func__, feature));
+ KASSERT(feature < flsl(xsave_mask),
+ ("%s: unsupported XFEATURE 0x%lx", __func__, feature));
+}
+
+static __inline void
+xsave_extstate_bv_check(uint64_t xstate_bv)
+{
+ KASSERT(xstate_bv != 0 && ilog2(xstate_bv) < flsl(xsave_mask),
+ ("%s: invalid XSTATE_BV 0x%lx", __func__, xstate_bv));
+}
+
+/*
+ * Returns whether the XFEATURE 'feature' is supported as a user state
+ * or supervisor state component.
+ */
+bool
+xsave_extfeature_supported(uint64_t feature, bool supervisor)
+{
+ int idx;
+
+ KASSERT(use_xsave, ("%s: XSAVE not supported", __func__));
+ xsave_extfeature_check(feature);
+
+ if ((xsave_mask & feature) == 0)
+ return (false);
+ idx = ilog2(feature);
+ return (((xsave_area_desc[idx].flags & CPUID_EXTSTATE_SUPERVISOR) != 0) ==
+ supervisor);
+}
+
+/*
+ * Returns whether the given XSAVE extension is supported.
+ */
+bool
+xsave_extension_supported(uint64_t extension)
+{
+ KASSERT(use_xsave, ("%s: XSAVE not supported", __func__));
+
+ return ((xsave_extensions & extension) != 0);
+}
+
+/*
+ * Returns offset for XFEATURE 'feature' given the requested feature bitmap
+ * 'xstate_bv', and extended region format ('compact').
+ */
+size_t
+xsave_area_offset(uint64_t xstate_bv, uint64_t feature,
+ bool compact)
+{
+ int i, idx;
+ size_t offs;
+ struct xsave_area_elm_descr *xep;
+
+ KASSERT(use_xsave, ("%s: XSAVE not supported", __func__));
+ xsave_extstate_bv_check(xstate_bv);
+ xsave_extfeature_check(feature);
+
+ idx = ilog2(feature);
+ if (!compact)
+ return (xsave_area_desc[idx].offset);
+ offs = sizeof(struct savefpu) + sizeof(struct xstate_hdr);
+ xstate_bv &= ~(XFEATURE_ENABLED_X87 | XFEATURE_ENABLED_SSE);
+ while ((i = ffs(xstate_bv) - 1) > 0 && i < idx) {
+ xep = &xsave_area_desc[i];
+ if ((xep->flags & CPUID_EXTSTATE_ALIGNED) != 0)
+ offs = roundup2(offs, 64);
+ offs += xep->size;
+ xstate_bv &= ~((uint64_t)1 << i);
+ }
+
+ return (offs);
+}
+
+/*
+ * Returns the XSAVE area size for the requested feature bitmap
+ * 'xstate_bv' and extended region format ('compact').
+ */
+size_t
+xsave_area_size(uint64_t xstate_bv, bool compact)
+{
+ int last_idx;
+
+ KASSERT(use_xsave, ("%s: XSAVE not supported", __func__));
+ xsave_extstate_bv_check(xstate_bv);
+
+ last_idx = ilog2(xstate_bv);
+
+ return (xsave_area_offset(xstate_bv, (uint64_t)1 << last_idx, compact) +
+ xsave_area_desc[last_idx].size);
+}
+
+size_t
+xsave_area_hdr_offset(void)
+{
+ return (sizeof(struct savefpu));
+}
diff --git a/sys/x86/include/fpu.h b/sys/x86/include/fpu.h
--- a/sys/x86/include/fpu.h
+++ b/sys/x86/include/fpu.h
@@ -218,6 +218,12 @@
*/
#define fpu_enable() clts()
#define fpu_disable() load_cr0(rcr0() | CR0_TS)
+
+bool xsave_extfeature_supported(uint64_t feature, bool supervisor);
+bool xsave_extension_supported(uint64_t extension);
+size_t xsave_area_hdr_offset(void);
+size_t xsave_area_offset(uint64_t xstate_bv, uint64_t feature, bool compact);
+size_t xsave_area_size(uint64_t xstate_bv, bool compact);
#endif
#endif /* !_X86_FPU_H_ */
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Dec 26, 6:41 AM (11 h, 43 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15602168
Default Alt Text
D47394.diff (4 KB)
Attached To
Mode
D47394: x86: Add routines for querying XSAVE feature information
Attached
Detach File
Event Timeline
Log In to Comment