From nobody Tue Feb 10 02:49:59 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=intel.com ARC-Seal: i=1; a=rsa-sha256; t=1645003910; cv=none; d=zohomail.com; s=zohoarc; b=idj6Tn2qGrU4n/HMJ+WyTO68bbWqFkKC4KtQTbvfIGjcCIRUHe5P+aS/hSEPSQMg9gI3Pvcn4TdBBC+JZHDHVlU/7q9DhiJUpwCUy0JEaQU2IrSG3tr8ofIt8/eVqeGQQNhohdYlh0/desiG1Ryresy8wnu39dtffXEX0pRDuJw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1645003910; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=UBuYYFTrscBhvUPpWQbs6V/zsDIcxCUmSXgt8Q1vhgc=; b=fNuJ0/LLsVMXVZe/CVlDAVNVrz21LkklmB3hd/uJdMsKJoTHwwtazd2P613VVRdhd5xla61CJEi4KgrSHCYi1CetAuwgOgMtloQ/xayciKI7mrrJTORRbQ7Xb8DjJAtjTIwZBHqss1Ao+S8UeK2hIDmxGZq51ZefrUGirnbQuzA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=@intel.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1645003910314515.2125371641524; Wed, 16 Feb 2022 01:31:50 -0800 (PST) Received: from localhost ([::1]:35096 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nKGf6-0008KM-Vl for importer@patchew.org; Wed, 16 Feb 2022 04:31:49 -0500 Received: from eggs.gnu.org ([209.51.188.92]:51358) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nKG6K-0006aI-Pt for qemu-devel@nongnu.org; Wed, 16 Feb 2022 03:55:52 -0500 Received: from mga14.intel.com ([192.55.52.115]:10622) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nKG6G-0002mh-95 for qemu-devel@nongnu.org; Wed, 16 Feb 2022 03:55:52 -0500 Received: from fmsmga002.fm.intel.com ([10.253.24.26]) by fmsmga103.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2022 00:54:53 -0800 Received: from embargo.jf.intel.com ([10.165.9.183]) by fmsmga002-auth.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 16 Feb 2022 00:54:06 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=intel.com; i=@intel.com; q=dns/txt; s=Intel; t=1645001749; x=1676537749; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=vpU+dDwGdr/y/YFn6PEOCs1NoiHA7z2R+29wt+qBHQY=; b=YowYcU+ChDY+bQlMBJWq7ETDJ7t0X2jgZtmPyQDUa7GEKzIi1j/qjk5L xOuIpS/yGwioPjv7LFqQLL/mf1WREKDync89fgCkhQyPiE6kiFqi8rue2 WHFGLrzXqgCUrGmip26riXNvunJCmIEcItaOU5NbReptJcHGSQyvxQE7m 15HZ3RuOm7KTllypgULzOhfiNi4G+GHOfmcZQ6WlXjG8eMKfaNQiPmgtP L306IZ0AdZ/u2l3kTOdnGsRZOov2C+OszBX9SauY0P65lRNM3nr59DRTY nzEHFGdcB/p3qqRqJwG5jbil1/so9Nr6ccQ1qudEqpyMSFgV6y1CcHvNE A==; X-IronPort-AV: E=McAfee;i="6200,9189,10259"; a="250756907" X-IronPort-AV: E=Sophos;i="5.88,373,1635231600"; d="scan'208";a="250756907" X-IronPort-AV: E=Sophos;i="5.88,373,1635231600"; d="scan'208";a="633418280" From: Yang Weijiang To: pbonzini@redhat.com, ehabkost@redhat.com, mtosatti@redhat.com, seanjc@google.com, richard.henderson@linaro.org, like.xu.linux@gmail.com, wei.w.wang@intel.com, qemu-devel@nongnu.org, kvm@vger.kernel.org Subject: [PATCH 4/8] target/i386: Enable support for XSAVES based features Date: Tue, 15 Feb 2022 14:52:54 -0500 Message-Id: <20220215195258.29149-5-weijiang.yang@intel.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20220215195258.29149-1-weijiang.yang@intel.com> References: <20220215195258.29149-1-weijiang.yang@intel.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=192.55.52.115; envelope-from=weijiang.yang@intel.com; helo=mga14.intel.com X-Spam_score_int: -60 X-Spam_score: -6.1 X-Spam_bar: ------ X-Spam_report: (-6.1 / 5.0 requ) BAYES_00=-1.9, DATE_IN_PAST_12_24=1.049, DKIMWL_WL_HIGH=-0.083, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_HI=-5, SPF_HELO_NONE=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Yang Weijiang Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: pass (identity @intel.com) X-ZM-MESSAGEID: 1645003911704100001 Content-Type: text/plain; charset="utf-8" There're some new features, including Arch LBR, depending on XSAVES/XRSTORS support, the new instructions will save/restore data based on feature bits enabled in XCR0 | XSS. This patch adds the basic support for related CPUID enumeration and meanwhile changes the name from FEAT_XSAVE_COMP_{LO|HI} to FEAT_XSAVE_XCR0_{LO|HI} to differentiate clearly the feature bits in XCR0 and those in XSS. Signed-off-by: Yang Weijiang --- target/i386/cpu.c | 104 +++++++++++++++++++++++++++++++++++----------- target/i386/cpu.h | 13 +++++- 2 files changed, 91 insertions(+), 26 deletions(-) diff --git a/target/i386/cpu.c b/target/i386/cpu.c index a037bba387..496e906233 100644 --- a/target/i386/cpu.c +++ b/target/i386/cpu.c @@ -940,6 +940,34 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] =3D { }, .tcg_features =3D TCG_XSAVE_FEATURES, }, + [FEAT_XSAVE_XSS_LO] =3D { + .type =3D CPUID_FEATURE_WORD, + .feat_names =3D { + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + }, + .cpuid =3D { + .eax =3D 0xD, + .needs_ecx =3D true, + .ecx =3D 1, + .reg =3D R_ECX, + }, + }, + [FEAT_XSAVE_XSS_HI] =3D { + .type =3D CPUID_FEATURE_WORD, + .cpuid =3D { + .eax =3D 0xD, + .needs_ecx =3D true, + .ecx =3D 1, + .reg =3D R_EDX + }, + }, [FEAT_6_EAX] =3D { .type =3D CPUID_FEATURE_WORD, .feat_names =3D { @@ -955,7 +983,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] =3D { .cpuid =3D { .eax =3D 6, .reg =3D R_EAX, }, .tcg_features =3D TCG_6_EAX_FEATURES, }, - [FEAT_XSAVE_COMP_LO] =3D { + [FEAT_XSAVE_XCR0_LO] =3D { .type =3D CPUID_FEATURE_WORD, .cpuid =3D { .eax =3D 0xD, @@ -968,7 +996,7 @@ FeatureWordInfo feature_word_info[FEATURE_WORDS] =3D { XSTATE_OPMASK_MASK | XSTATE_ZMM_Hi256_MASK | XSTATE_Hi16_ZMM_M= ASK | XSTATE_PKRU_MASK, }, - [FEAT_XSAVE_COMP_HI] =3D { + [FEAT_XSAVE_XCR0_HI] =3D { .type =3D CPUID_FEATURE_WORD, .cpuid =3D { .eax =3D 0xD, @@ -1385,6 +1413,9 @@ static const X86RegisterInfo32 x86_reg_info_32[CPU_NB= _REGS32] =3D { }; #undef REGISTER =20 +/* CPUID feature bits available in XSS */ +#define CPUID_XSTATE_XSS_MASK (0) + ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COUNT] =3D { [XSTATE_FP_BIT] =3D { /* x87 FP state component is always enabled if XSAVE is supported = */ @@ -1427,15 +1458,18 @@ ExtSaveArea x86_ext_save_areas[XSAVE_STATE_AREA_COU= NT] =3D { }, }; =20 -static uint32_t xsave_area_size(uint64_t mask) +static uint32_t xsave_area_size(uint64_t mask, bool compacted) { + uint64_t ret =3D x86_ext_save_areas[0].size; + const ExtSaveArea *esa; + uint32_t offset =3D 0; int i; - uint64_t ret =3D 0; =20 - for (i =3D 0; i < ARRAY_SIZE(x86_ext_save_areas); i++) { - const ExtSaveArea *esa =3D &x86_ext_save_areas[i]; + for (i =3D 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) { + esa =3D &x86_ext_save_areas[i]; if ((mask >> i) & 1) { - ret =3D MAX(ret, esa->offset + esa->size); + offset =3D compacted ? ret : esa->offset; + ret =3D MAX(ret, offset + esa->size); } } return ret; @@ -1446,10 +1480,10 @@ static inline bool accel_uses_host_cpuid(void) return kvm_enabled() || hvf_enabled(); } =20 -static inline uint64_t x86_cpu_xsave_components(X86CPU *cpu) +static inline uint64_t x86_cpu_xsave_xcr0_components(X86CPU *cpu) { - return ((uint64_t)cpu->env.features[FEAT_XSAVE_COMP_HI]) << 32 | - cpu->env.features[FEAT_XSAVE_COMP_LO]; + return ((uint64_t)cpu->env.features[FEAT_XSAVE_XCR0_HI]) << 32 | + cpu->env.features[FEAT_XSAVE_XCR0_LO]; } =20 /* Return name of 32-bit register, from a R_* constant */ @@ -1461,6 +1495,12 @@ static const char *get_register_name_32(unsigned int= reg) return x86_reg_info_32[reg].name; } =20 +static inline uint64_t x86_cpu_xsave_xss_components(X86CPU *cpu) +{ + return ((uint64_t)cpu->env.features[FEAT_XSAVE_XSS_HI]) << 32 | + cpu->env.features[FEAT_XSAVE_XSS_LO]; +} + /* * Returns the set of feature flags that are supported and migratable by * QEMU, for a given FeatureWord. @@ -4628,8 +4668,8 @@ static const char *x86_cpu_feature_name(FeatureWord w= , int bitnr) /* XSAVE components are automatically enabled by other features, * so return the original feature name instead */ - if (w =3D=3D FEAT_XSAVE_COMP_LO || w =3D=3D FEAT_XSAVE_COMP_HI) { - int comp =3D (w =3D=3D FEAT_XSAVE_COMP_HI) ? bitnr + 32 : bitnr; + if (w =3D=3D FEAT_XSAVE_XCR0_LO || w =3D=3D FEAT_XSAVE_XCR0_HI) { + int comp =3D (w =3D=3D FEAT_XSAVE_XCR0_HI) ? bitnr + 32 : bitnr; =20 if (comp < ARRAY_SIZE(x86_ext_save_areas) && x86_ext_save_areas[comp].bits) { @@ -5494,25 +5534,36 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index= , uint32_t count, } =20 if (count =3D=3D 0) { - *ecx =3D xsave_area_size(x86_cpu_xsave_components(cpu)); - *eax =3D env->features[FEAT_XSAVE_COMP_LO]; - *edx =3D env->features[FEAT_XSAVE_COMP_HI]; + *ecx =3D xsave_area_size(x86_cpu_xsave_xcr0_components(cpu), f= alse); + *eax =3D env->features[FEAT_XSAVE_XCR0_LO]; + *edx =3D env->features[FEAT_XSAVE_XCR0_HI]; /* * The initial value of xcr0 and ebx =3D=3D 0, On host without= kvm * commit 412a3c41(e.g., CentOS 6), the ebx's value always =3D= =3D 0 * even through guest update xcr0, this will crash some legacy= guest * (e.g., CentOS 6), So set ebx =3D=3D ecx to workaroud it. */ - *ebx =3D kvm_enabled() ? *ecx : xsave_area_size(env->xcr0); + *ebx =3D kvm_enabled() ? *ecx : xsave_area_size(env->xcr0, fal= se); } else if (count =3D=3D 1) { + uint64_t xstate =3D x86_cpu_xsave_xcr0_components(cpu) | + x86_cpu_xsave_xss_components(cpu); + *eax =3D env->features[FEAT_XSAVE]; + *ebx =3D xsave_area_size(xstate, true); + *ecx =3D env->features[FEAT_XSAVE_XSS_LO]; + *edx =3D env->features[FEAT_XSAVE_XSS_HI]; } else if (count < ARRAY_SIZE(x86_ext_save_areas)) { - if ((x86_cpu_xsave_components(cpu) >> count) & 1) { - const ExtSaveArea *esa =3D &x86_ext_save_areas[count]; + const ExtSaveArea *esa =3D &x86_ext_save_areas[count]; + + if ((x86_cpu_xsave_xcr0_components(cpu) >> count) & 1) { *eax =3D esa->size; *ebx =3D esa->offset; *ecx =3D (esa->ecx & ESA_FEATURE_ALIGN64_MASK) | (esa->ecx & ESA_FEATURE_XFD_MASK); + } else if ((x86_cpu_xsave_xss_components(cpu) >> count) & 1) { + *eax =3D esa->size; + *ebx =3D 0; + *ecx =3D 1; } } break; @@ -5563,8 +5614,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, = uint32_t count, } else { *eax &=3D env->features[FEAT_SGX_12_1_EAX]; *ebx &=3D 0; /* ebx reserve */ - *ecx &=3D env->features[FEAT_XSAVE_COMP_LO]; - *edx &=3D env->features[FEAT_XSAVE_COMP_HI]; + *ecx &=3D env->features[FEAT_XSAVE_XSS_LO]; + *edx &=3D env->features[FEAT_XSAVE_XSS_HI]; =20 /* FP and SSE are always allowed regardless of XSAVE/XCR0. */ *ecx |=3D XSTATE_FP_MASK | XSTATE_SSE_MASK; @@ -5947,6 +5998,9 @@ static void x86_cpu_reset(DeviceState *dev) } for (i =3D 2; i < ARRAY_SIZE(x86_ext_save_areas); i++) { const ExtSaveArea *esa =3D &x86_ext_save_areas[i]; + if (!((1 << i) & CPUID_XSTATE_XCR0_MASK)) { + continue; + } if (env->features[esa->feature] & esa->bits) { xcr0 |=3D 1ull << i; } @@ -6083,8 +6137,8 @@ static void x86_cpu_enable_xsave_components(X86CPU *c= pu) uint64_t mask; =20 if (!(env->features[FEAT_1_ECX] & CPUID_EXT_XSAVE)) { - env->features[FEAT_XSAVE_COMP_LO] =3D 0; - env->features[FEAT_XSAVE_COMP_HI] =3D 0; + env->features[FEAT_XSAVE_XCR0_LO] =3D 0; + env->features[FEAT_XSAVE_XCR0_HI] =3D 0; return; } =20 @@ -6102,8 +6156,10 @@ static void x86_cpu_enable_xsave_components(X86CPU *= cpu) request_perm =3D true; } =20 - env->features[FEAT_XSAVE_COMP_LO] =3D mask; - env->features[FEAT_XSAVE_COMP_HI] =3D mask >> 32; + env->features[FEAT_XSAVE_XCR0_LO] =3D mask & CPUID_XSTATE_XCR0_MASK; + env->features[FEAT_XSAVE_XCR0_HI] =3D mask >> 32; + env->features[FEAT_XSAVE_XSS_LO] =3D mask & CPUID_XSTATE_XSS_MASK; + env->features[FEAT_XSAVE_XSS_HI] =3D mask >> 32; } =20 /***** Steps involved on loading and filtering CPUID data diff --git a/target/i386/cpu.h b/target/i386/cpu.h index 852afabe0b..1d17196a0b 100644 --- a/target/i386/cpu.h +++ b/target/i386/cpu.h @@ -568,6 +568,13 @@ typedef enum X86Seg { #define ESA_FEATURE_XFD_MASK (1U << ESA_FEATURE_XFD_BIT) =20 =20 +/* CPUID feature bits available in XCR0 */ +#define CPUID_XSTATE_XCR0_MASK (XSTATE_FP_MASK | XSTATE_SSE_MASK | \ + XSTATE_YMM_MASK | XSTATE_BNDREGS_MASK | \ + XSTATE_BNDCSR_MASK | XSTATE_OPMASK_MASK |= \ + XSTATE_ZMM_Hi256_MASK | \ + XSTATE_Hi16_ZMM_MASK | XSTATE_PKRU_MASK) + /* CPUID feature words */ typedef enum FeatureWord { FEAT_1_EDX, /* CPUID[1].EDX */ @@ -586,8 +593,8 @@ typedef enum FeatureWord { FEAT_SVM, /* CPUID[8000_000A].EDX */ FEAT_XSAVE, /* CPUID[EAX=3D0xd,ECX=3D1].EAX */ FEAT_6_EAX, /* CPUID[6].EAX */ - FEAT_XSAVE_COMP_LO, /* CPUID[EAX=3D0xd,ECX=3D0].EAX */ - FEAT_XSAVE_COMP_HI, /* CPUID[EAX=3D0xd,ECX=3D0].EDX */ + FEAT_XSAVE_XCR0_LO, /* CPUID[EAX=3D0xd,ECX=3D0].EAX */ + FEAT_XSAVE_XCR0_HI, /* CPUID[EAX=3D0xd,ECX=3D0].EDX */ FEAT_ARCH_CAPABILITIES, FEAT_CORE_CAPABILITY, FEAT_PERF_CAPABILITIES, @@ -604,6 +611,8 @@ typedef enum FeatureWord { FEAT_SGX_12_0_EAX, /* CPUID[EAX=3D0x12,ECX=3D0].EAX (SGX) */ FEAT_SGX_12_0_EBX, /* CPUID[EAX=3D0x12,ECX=3D0].EBX (SGX MISCSELECT[3= 1:0]) */ FEAT_SGX_12_1_EAX, /* CPUID[EAX=3D0x12,ECX=3D1].EAX (SGX ATTRIBUTES[3= 1:0]) */ + FEAT_XSAVE_XSS_LO, /* CPUID[EAX=3D0xd,ECX=3D1].ECX */ + FEAT_XSAVE_XSS_HI, /* CPUID[EAX=3D0xd,ECX=3D1].EDX */ FEATURE_WORDS, } FeatureWord; =20 --=20 2.27.0