From nobody Sun Apr 12 22:43:28 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=reject dis=none) header.from=citrix.com ARC-Seal: i=1; a=rsa-sha256; t=1775666187; cv=none; d=zohomail.com; s=zohoarc; b=mrOghmKwDTZ2hY+08aosM1Yi0/gFlSPXOL4PaKOovriWhBgOhTIhPIFLTIS77chxf5Mx92Kvrx6zdonLdZMfT9yOWQ0XT5kJ0V9X/CNP3o+nIyCFJvidQEZ6DLkRqi/ipplub0c2gd+mD8oxsyCvdhws7t2xJ4+WhNkiF/NBx/g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1775666187; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=UN00C5w8mxxKS6BZsJBcm/d7Q6sznRAtUQSRYmu6l/8=; b=drjFX5C683lRBm98AKU+BPmnjYKL3JDaHlCrrcyBuY6LS7xQ/7FQdoNSWAl8ju4Uey4Z/RtSSlypjrwkUbMul2CSfr0OcPzKJdinG4lIB27MdnveSAUY5Xj9OtIaAFlrc177L+5g9XU+AwZdzDVfdEfCeDUbfU68OuNvsT9SeCQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 177566618754819.006918244492795; Wed, 8 Apr 2026 09:36:27 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1276336.1561844 (Exim 4.92) (envelope-from ) id 1wAVsh-0004UR-QE; Wed, 08 Apr 2026 16:35:55 +0000 Received: by outflank-mailman (output) from mailman id 1276336.1561844; Wed, 08 Apr 2026 16:35:55 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wAVsh-0004UK-Mg; Wed, 08 Apr 2026 16:35:55 +0000 Received: by outflank-mailman (input) for mailman id 1276336; Wed, 08 Apr 2026 16:35:54 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wAVsf-0004UE-Un for xen-devel@lists.xenproject.org; Wed, 08 Apr 2026 16:35:54 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wAVsd-006NwQ-BB for xen-devel@lists.xenproject.org; Wed, 08 Apr 2026 18:35:52 +0200 Received: from [10.42.69.1] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 69d683b6-2eae-0a2a0a5409dd-0a2a4501ddc8-34 for ; Wed, 08 Apr 2026 18:35:52 +0200 Received: from [209.85.128.67] (helo=mail-wm1-f67.google.com) by tlsNG-d62444.mxtls.expurgate.net with ESMTPS (eXpurgate 4.56.0) (envelope-from ) id 69d683e8-6fc9-0a2a45010019-d1558043d0db-3 for ; Wed, 08 Apr 2026 18:35:52 +0200 Received: by mail-wm1-f67.google.com with SMTP id 5b1f17b1804b1-4889e045bc6so113215e9.2 for ; Wed, 08 Apr 2026 09:35:52 -0700 (PDT) Received: from localhost.localdomain (host-78-146-242-105.as13285.net. [78.146.242.105]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-43d1e4d2738sm61201338f8f.24.2026.04.08.09.35.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 08 Apr 2026 09:35:51 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=google header.d=citrix.com header.i="@citrix.com" header.h="Content-Transfer-Encoding:MIME-Version:Message-Id:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=citrix.com; s=google; t=1775666152; x=1776270952; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=UN00C5w8mxxKS6BZsJBcm/d7Q6sznRAtUQSRYmu6l/8=; b=Bp8npXhrI4YjYq1Bj6SQMBRI4jk4GhUQ/bT87MLgs9i1kSXieNxUyGYxxlprzGGm4z UXLIYHkMDsY7VqmBc7QvxApxBCYHp5odkIKzi/5R8sk9M87PAtn1ld9NeqXvLmIYfSdp F0BjBiT/T+9zDv57DP8vlz1rhpZnuMz+XIXCM= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1775666152; x=1776270952; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=UN00C5w8mxxKS6BZsJBcm/d7Q6sznRAtUQSRYmu6l/8=; b=ZR+aRKt+bdcJtGJKdU8FoyrGJvge1UK650N65Uk0Yv5X69y/9NLFEfZISYnGf/uTEc sTeeUstHwqi6dLHT9JVWjjrF2AzT/PvrbkPKDo9tYzCEbDydVDcv3gXZvO35EMbMi1ye 0YXY/tV8n+Br+mINsB/VdibXN/9qGTG51lqU9IAbjydZhKF7uO2RjW0zV3T7h1ifO31E ZTB8aAnERxilWyP8N5dvjnvrlQbuIp3SHS/E959C/lNtiaWAKiUkHWrC7svdfwwhENrR NAGG3erFGL6Rsf/3PmE+BObNsdNDRLmMVGQkk/HJioSmP4Hsdpgqb9MNNFbPc9cfV/rn fiRw== X-Gm-Message-State: AOJu0YwIbcE/GLeP8PghA9WGlammfBxP/8wKJWDeh9xr/d1aHgwcFs8l /r6a9nZS2wYhN5EWllAC7nKN/34I20CBCDcDM6kuCOlzTSow+DBKyuqs49oQipeKVvyLjoEmgUJ V3+vKbJFs6hf4 X-Gm-Gg: AeBDievE6OBve+oCRS7tpDatpaX1F+8sEkuEA6lc6BmrV/jeGI7c7j99ZL8EYukw0Nk 4Qdoptyx6PMLUvXK5Wj5P61EW7n3L9Qe50cnRWpy3U/ewPSnobw8N78JQ9N70gHbdJ18ioonXjV dBaz7Eb+wwKlCsU8qvdKzphTGtNlAN1Rm6HXzfTCJVDkCYy5NN0tnIrZ4G4NR2+tm/+8hT9wcxU Zhwi+YcsmxfNviDW7DhDyBzAhMBRLZdQMrYZa3E3KVEb8Gypon4xoipDzEjwhz6Qa8y5HjKJ+Ef UTD4z9MB5U8HdY/Y8pzdkB82OHcsbE98WRFq45f1BrjVXxZpx3rogBOzrdh2nhitfOEy8ZpAfxP iLs6U7bddZcIGk1NrfAQKGagiSXaoVdvFbOpUo1236XCAvS7CPJi8GobkdzCtiVZxAMGC9F130K 8nGJmHVF+C7gv/BbGvlqi8XFHfwV6fBXdnk4xDTVF3Gb+CXDkIlLGdDCvk39bi6ZGReiCVCYk5i L/v X-Received: by 2002:a05:600c:858c:b0:488:9439:880d with SMTP id 5b1f17b1804b1-488cd087322mr5197785e9.29.1775666151565; Wed, 08 Apr 2026 09:35:51 -0700 (PDT) From: Andrew Cooper To: Xen-devel Cc: Andrew Cooper , Jan Beulich , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie Subject: [PATCH] x86/gen-cpuid: Split deep_features by vendor Date: Wed, 8 Apr 2026 17:35:49 +0100 Message-Id: <20260408163549.135245-1-andrew.cooper3@citrix.com> X-Mailer: git-send-email 2.39.5 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-d62444/1775666152-150E0185-2BB1BED4/0/0 X-purgate-type: clean X-purgate-size: 8689 X-ZohoMail-DKIM: pass (identity @citrix.com) X-ZM-MESSAGEID: 1775666188281158500 AMD CPUs need LKGS depend on NSCB, but this dependency cannot be unconditio= nal as it will break FRED on Intel CPUs which don't need to enumerate the absen= ce of a bug. The deep dependecy logic is formed of two parts; a deep_features bitmap indicating which features have dependencies, and deep_deps; the mapping of feature to dependent features. Given that NSCB is an unconnected root of a dependency, we can have the row in deep_deps and conditionally exclude it t= he deep_features level. Rename INIT_DEEP_FEATURES to INIT_ALL_DEEP_FEATURES and add AMD and INTEL forms too. In both xc_cpuid_apply_policy() and sanitise_featureset(), choo= se the appropriate {amd,intel}_deep_features based on vendor. Introduce the NSCB <-> LKGS dependency and exclude the NSCB row from intel_deep_features. Signed-off-by: Andrew Cooper --- CC: Jan Beulich CC: Roger Pau Monn=C3=A9 CC: Teddy Astie Only compile tested so far. --- tools/libs/guest/xg_cpuid_x86.c | 14 +++++++++++++- xen/arch/x86/cpu-policy.c | 16 ++++++++++++++-- xen/arch/x86/lib/cpu-policy/cpuid.c | 2 +- xen/include/public/arch-x86/cpufeatureset.h | 2 +- xen/tools/gen-cpuid.py | 20 +++++++++++++++++--- 5 files changed, 46 insertions(+), 8 deletions(-) diff --git a/tools/libs/guest/xg_cpuid_x86.c b/tools/libs/guest/xg_cpuid_x8= 6.c index 0db6d77cd801..0b00672c4762 100644 --- a/tools/libs/guest/xg_cpuid_x86.c +++ b/tools/libs/guest/xg_cpuid_x86.c @@ -650,9 +650,12 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t = domid, bool restore, =20 if ( featureset ) { + static const uint32_t amd_deep_features[] =3D INIT_AMD_DEEP_FEATU= RES; + static const uint32_t intel_deep_features[] =3D INIT_INTEL_DEEP_F= EATURES; + + const uint32_t *deep_features; uint32_t disabled_features[FEATURESET_NR_ENTRIES], feat[FEATURESET_NR_ENTRIES] =3D {}; - static const uint32_t deep_features[] =3D INIT_DEEP_FEATURES; unsigned int i, b; =20 /* @@ -670,6 +673,15 @@ int xc_cpuid_apply_policy(xc_interface *xch, uint32_t = domid, bool restore, =20 memcpy(feat, featureset, sizeof(*featureset) * user_len); =20 + /* + * At the time of writing, amd_deep_features contains one extra + * dependency over intel for a "hardware no longer has this bug" b= it. + */ + if ( p->policy.x86_vendor & (X86_VENDOR_AMD|X86_VENDOR_HYGON) ) + deep_features =3D amd_deep_features; + else + deep_features =3D intel_deep_features; + /* Disable deep dependencies of disabled features. */ for ( i =3D 0; i < ARRAY_SIZE(disabled_features); ++i ) disabled_features[i] =3D ~feat[i] & deep_features[i]; diff --git a/xen/arch/x86/cpu-policy.c b/xen/arch/x86/cpu-policy.c index 5273fe0ae435..2228c52ffc79 100644 --- a/xen/arch/x86/cpu-policy.c +++ b/xen/arch/x86/cpu-policy.c @@ -39,7 +39,8 @@ static const uint32_t __initconst hvm_shadow_def_featurem= ask[] =3D INIT_HVM_SHADOW_DEF_FEATURES; static const uint32_t __initconst hvm_hap_def_featuremask[] =3D INIT_HVM_HAP_DEF_FEATURES; -static const uint32_t deep_features[] =3D INIT_DEEP_FEATURES; +static const uint32_t amd_deep_features[] =3D INIT_AMD_DEEP_FEATURES; +static const uint32_t intel_deep_features[] =3D INIT_INTEL_DEEP_FEATURES; =20 static const struct feature_name { const char *name; @@ -158,11 +159,21 @@ static void zero_leaves(struct cpuid_leaf *l, =20 static void sanitise_featureset(uint32_t *fs) { + const uint32_t *deep_features; /* bitmap_for_each() uses unsigned longs. Extend with zeroes. */ uint32_t disabled_features[ ROUNDUP(FSCAPINTS, sizeof(unsigned long)/sizeof(uint32_t))] =3D {}; unsigned int i; =20 + /* + * At the time of writing, amd_deep_features contains one extra depend= ency + * over intel for a "hardware no longer has this bug" bit. + */ + if ( boot_cpu_data.vendor & (X86_VENDOR_AMD|X86_VENDOR_HYGON) ) + deep_features =3D amd_deep_features; + else + deep_features =3D intel_deep_features; + for ( i =3D 0; i < FSCAPINTS; ++i ) { /* Clamp to known mask. */ @@ -1110,7 +1121,8 @@ static void __init __maybe_unused build_assertions(vo= id) BUILD_BUG_ON(ARRAY_SIZE(pv_max_featuremask) !=3D FSCAPINTS); BUILD_BUG_ON(ARRAY_SIZE(hvm_shadow_max_featuremask) !=3D FSCAPINTS); BUILD_BUG_ON(ARRAY_SIZE(hvm_hap_max_featuremask) !=3D FSCAPINTS); - BUILD_BUG_ON(ARRAY_SIZE(deep_features) !=3D FSCAPINTS); + BUILD_BUG_ON(ARRAY_SIZE(amd_deep_features) !=3D FSCAPINTS); + BUILD_BUG_ON(ARRAY_SIZE(intel_deep_features) !=3D FSCAPINTS); =20 /* Find some more clever allocation scheme if this trips. */ BUILD_BUG_ON(sizeof(struct cpu_policy) > PAGE_SIZE); diff --git a/xen/arch/x86/lib/cpu-policy/cpuid.c b/xen/arch/x86/lib/cpu-pol= icy/cpuid.c index 3162e795bc21..73ea68690b4a 100644 --- a/xen/arch/x86/lib/cpu-policy/cpuid.c +++ b/xen/arch/x86/lib/cpu-policy/cpuid.c @@ -293,7 +293,7 @@ void x86_cpu_policy_clear_out_of_range_leaves(struct cp= u_policy *p) =20 const uint32_t *x86_cpu_policy_lookup_deep_deps(uint32_t feature) { - static const uint32_t deep_features[] =3D INIT_DEEP_FEATURES; + static const uint32_t deep_features[] =3D INIT_ALL_DEEP_FEATURES; static const struct { uint32_t feature; uint32_t fs[FEATURESET_NR_ENTRIES]; diff --git a/xen/include/public/arch-x86/cpufeatureset.h b/xen/include/publ= ic/arch-x86/cpufeatureset.h index c4d3276f2f89..acee5a0544a0 100644 --- a/xen/include/public/arch-x86/cpufeatureset.h +++ b/xen/include/public/arch-x86/cpufeatureset.h @@ -326,7 +326,7 @@ XEN_CPUFEATURE(NO_NEST_BP, 11*32+ 0) /*A No Ne= sted Data Breakpoints */ XEN_CPUFEATURE(FS_GS_NS, 11*32+ 1) /*S| FS/GS base MSRs non-seri= alising */ XEN_CPUFEATURE(LFENCE_DISPATCH, 11*32+ 2) /*A LFENCE always serializin= g */ XEN_CPUFEATURE(VERW_CLEAR, 11*32+ 5) /*!A| VERW clears microarchit= ectural buffers */ -XEN_CPUFEATURE(NSCB, 11*32+ 6) /*A Null Selector Clears Bas= e (and limit too) */ +XEN_CPUFEATURE(NSCB, 11*32+ 6) /*!A Null Selector Clears Bas= e (and limit too) */ XEN_CPUFEATURE(AUTO_IBRS, 11*32+ 8) /*S Automatic IBRS */ XEN_CPUFEATURE(AMD_FSRS, 11*32+10) /*A Fast Short REP STOSB */ XEN_CPUFEATURE(AMD_FSRC, 11*32+11) /*A Fast Short REP CMPSB */ diff --git a/xen/tools/gen-cpuid.py b/xen/tools/gen-cpuid.py index 13d85a43482a..a0fff6c45676 100755 --- a/xen/tools/gen-cpuid.py +++ b/xen/tools/gen-cpuid.py @@ -344,6 +344,12 @@ def crunch_numbers(state): # The ARCH_CAPS CPUID bit enumerates the availability of the whole= register. ARCH_CAPS: feat_range(RDCL_NO, RDCL_NO + 63), =20 + # AMD-only special case. NullSelectorClearsBase is really a "hard= ware + # doesn't have this bug any more" bit. All FRED-capable hardware = has + # NSCB properties, so disallow configurations which would cause LG= KS + # to behave unexpectedly. + NSCB: [LKGS], + # The behaviour described by RRSBA depend on eIBRS being active. EIBRS: [RRSBA], =20 @@ -383,9 +389,13 @@ def crunch_numbers(state): =20 state.deep_deps[feat] =3D seen =20 - state.deep_features =3D deps.keys() state.nr_deep_deps =3D len(state.deep_deps.keys()) =20 + # deep_features is split per vendor to exlcude certain rows from + # processing. + state.all_deep_features =3D set(deps.keys()) + state.intel_deep_features =3D state.all_deep_features - set((NSCB, )) + # Calculate the bitfield name declarations. Leave 4 placeholders on t= he end for word in range(state.nr_entries + 4): =20 @@ -447,7 +457,10 @@ def write_results(state): =20 #define NR_DEEP_DEPS %sU =20 -#define INIT_DEEP_FEATURES { \\\n%s\n} +#define INIT_ALL_DEEP_FEATURES { \\\n%s\n} + +#define INIT_AMD_DEEP_FEATURES INIT_ALL_DEEP_FEATURES +#define INIT_INTEL_DEEP_FEATURES { \\\n%s\n} =20 #define INIT_DEEP_DEPS { \\ """ % (state.nr_entries, @@ -462,7 +475,8 @@ def write_results(state): format_uint32s(state, state.hvm_hap_def, 4), format_uint32s(state, state.hvm_hap_max, 4), state.nr_deep_deps, - format_uint32s(state, state.deep_features, 4), + format_uint32s(state, state.all_deep_features, 4), + format_uint32s(state, state.intel_deep_features, 4), )) =20 for dep in sorted(state.deep_deps.keys()): --=20 2.39.5