From nobody Sun Dec 15 15:40:39 2024 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id 4YB6jM6l2vz5gyCn; Sun, 15 Dec 2024 15:40:39 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R10" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4YB6jM4MwNz40L8; Sun, 15 Dec 2024 15:40:39 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1734277239; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5Qulm8WlkRRS1IC98I7aHHIdJKYg63by4IAIwDCWBWU=; b=QmVpDQwpsENitG0tDgigOj9LaDb34ODf4X5kRLEwFCcpFrSu1UN1521A89T6srNnJIIlAa zOThARWlgCt9aRLlQPWrSUrgaEPFc0VucvOp8kbT2/p124udoFDeFVE47MBDyJnRw4E9nR 3rULwrcAjE9IKdO3VNmSeiKN13wvWzOqlcjMWQqt+fVmXXAochRe68Tw+M8vatXLmVaiiE iWUch19E9lmYZFr70NNi6qw5xZsNsBQvGgQfkxT/r1alzCv9uzs5WZrtapuDG+ySslWLSG bCh+GiG0TItwByxtEMHICFk2c5Xm/R/68r18uIEa5prmnqvVI1DPhcubsB2n8Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1734277239; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=5Qulm8WlkRRS1IC98I7aHHIdJKYg63by4IAIwDCWBWU=; b=GF3C2zV6Uglk98FTg2M/aP3b5kYQB8S8imnAt6ivU0cfTGWL0nTovrGJh4bWwxUs7SY3P8 z2LWBTEHHA9rA1WzUIcJhM/wIpQs9lEf2oT5aSHYY+UjQZbJuq7dMMlXnKzH2QP8YDdb3T 0VIXTTE5yGZ+sSwi/JmwmnitMWK1rcPcSWv8YZCbxAGS+cbRjVTHiU9Y5tZpTfGOykvyuV 6TQH/Y058xFNAvhVxxA7M+3r8EpkLJ7c2Dvw1yoIU9tbfPMPvxMPaO9d1JaA0SJJ3ymnl/ ZDZRWSVi1DObA//ei5KCdWzRyFoInP6BzB8+zMU+p1suzWTUq8CAYIUOycczvQ== ARC-Authentication-Results: i=1; mx1.freebsd.org; none ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1734277239; a=rsa-sha256; cv=none; b=iRBkUefJDhiy9F2BekIFDa0ug0vxx6Whbr6M2Vi5ikmaGj0sTZfmg2xZTC6a2rWTcyxRq9 spXBdz1GXKnJ6QJfnC58F0/UC93cHxGqjvtvuvNOSjkLmLMFQqOaLDP0iHXsEy6iFF2MkG Z0h7GyKui+3plelwFtLcaP/Lb2AWmeXpINhD9CnKfJLCh1VbioKZ7EfOjzV2zr4zIQNnuI dk8FcFOejeDH5gro6cCwazsVVVfkutuCsb7Zcy3GrcKzxbC46cmveom5+AX13lYJvZcd2x zdmG/V98j9XIYTSymZc/eUUbuWv763nyc0NtamB74BsyPSzD65snT1L8dYLRpw== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 4YB6jM3p72zDwB; Sun, 15 Dec 2024 15:40:39 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.18.1/8.18.1) with ESMTP id 4BFFedtI069518; Sun, 15 Dec 2024 15:40:39 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.18.1/8.18.1/Submit) id 4BFFedOk069515; Sun, 15 Dec 2024 15:40:39 GMT (envelope-from git) Date: Sun, 15 Dec 2024 15:40:39 GMT Message-Id: <202412151540.4BFFedOk069515@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Bojan =?utf-8?Q?Novkovi=C4=87?= Subject: git: 7bcaff05223e - main - x86: Add routines for querying XSAVE feature information List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: X-BeenThere: dev-commits-src-main@freebsd.org Sender: owner-dev-commits-src-main@FreeBSD.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: bnovkov X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 7bcaff05223eb81611372e341a120391925fa724 Auto-Submitted: auto-generated The branch main has been updated by bnovkov: URL: https://cgit.FreeBSD.org/src/commit/?id=7bcaff05223eb81611372e341a120391925fa724 commit 7bcaff05223eb81611372e341a120391925fa724 Author: Bojan Novković AuthorDate: 2024-12-15 14:04:58 +0000 Commit: Bojan Novković CommitDate: 2024-12-15 15:39:36 +0000 x86: Add routines for querying XSAVE feature information This patch adds several routines that track and expose information about various XSAVE-related features. More specifically, it adds the ability to check whether a given XFEATURE is supported and which XSAVE extensions are supported. Furthermore, it adds several routines for calculating the size and offsets within a save area given a XSAVE feature bitmap. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D47394 --- sys/amd64/amd64/fpu.c | 111 +++++++++++++++++++++++++++++++++++++++++++++++++- sys/x86/include/fpu.h | 6 +++ 2 files changed, 116 insertions(+), 1 deletion(-) diff --git a/sys/amd64/amd64/fpu.c b/sys/amd64/amd64/fpu.c index 58a135e827a8..591bd196ca7d 100644 --- a/sys/amd64/amd64/fpu.c +++ b/sys/amd64/amd64/fpu.c @@ -164,12 +164,14 @@ SYSCTL_INT(_hw, HW_FLOATINGPT, floatingpoint, CTLFLAG_RD, 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 @@ fpuinitstate(void *arg __unused) * 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 @@ fpuinitstate(void *arg __unused) 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 @@ fpu_save_area_reset(struct savefpu *fsa) 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 index cf2235e4d2bf..9d2e43f6386e 100644 --- a/sys/x86/include/fpu.h +++ b/sys/x86/include/fpu.h @@ -218,6 +218,12 @@ struct savefpu_ymm { */ #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_ */