Created
August 29, 2025 16:04
-
-
Save tihmstar/ea363e6ba3f4675eeedaa0e69152e4d0 to your computer and use it in GitHub Desktop.
Xen patch forward amd caching info cpuid(0x8000001d) to DomU guests
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| commit cc9f67f9190d8d873ea2d10d36a3ee442680d5b4 | |
| Author: tihmstar <[email protected]> | |
| Date: Fri Aug 29 17:51:12 2025 +0200 | |
| forward amd caching info cpuid(0x8000001d) to DomU guests | |
| diff --git a/xen/arch/x86/cpu-policy.c b/xen/arch/x86/cpu-policy.c | |
| index 42dccdce52..6bff44180d 100644 | |
| --- a/xen/arch/x86/cpu-policy.c | |
| +++ b/xen/arch/x86/cpu-policy.c | |
| @@ -282,6 +282,7 @@ static void recalculate_misc(struct cpu_policy *p) | |
| switch ( p->x86_vendor ) | |
| { | |
| case X86_VENDOR_INTEL: | |
| + memset(p->amdcache.raw, 0, sizeof(p->amdcache.raw)); | |
| p->basic.l2_nr_queries = 1; /* Fixed to 1 query. */ | |
| p->basic.raw[0x3] = EMPTY_LEAF; /* PSN - always hidden. */ | |
| p->basic.raw[0x9] = EMPTY_LEAF; /* DCA - always hidden. */ | |
| @@ -1046,6 +1047,21 @@ void recalculate_cpuid_policy(struct domain *d) | |
| } | |
| } | |
| + for ( i = 0; i < ARRAY_SIZE(p->amdcache.raw); ++i ) | |
| + { | |
| + if ( p->amdcache.raw[i].a ) | |
| + { | |
| + // | |
| + } | |
| + else | |
| + { | |
| + /* Subleaf is not valid. Zero the rest of the union. */ | |
| + zero_leaves(p->amdcache.raw, i, ARRAY_SIZE(p->amdcache.raw) - 1); | |
| + break; | |
| + } | |
| + } | |
| + | |
| + | |
| if ( vpmu_mode == XENPMU_MODE_OFF || | |
| ((vpmu_mode & XENPMU_MODE_ALL) && !is_hardware_domain(d)) ) | |
| p->basic.raw[0xa] = EMPTY_LEAF; | |
| diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c | |
| index b63a82dd38..9e7957838f 100644 | |
| --- a/xen/arch/x86/cpuid.c | |
| +++ b/xen/arch/x86/cpuid.c | |
| @@ -243,12 +243,19 @@ void guest_cpuid(const struct vcpu *v, uint32_t leaf, | |
| return cpuid_hypervisor_leaves(v, leaf, subleaf, res); | |
| case 0x80000000U ... 0x80000000U + CPUID_GUEST_NR_EXTD - 1: | |
| - ASSERT((p->extd.max_leaf & 0xffff) < ARRAY_SIZE(p->extd.raw)); | |
| - if ( (leaf & 0xffff) > min_t(uint32_t, p->extd.max_leaf & 0xffff, | |
| - ARRAY_SIZE(p->extd.raw) - 1) ) | |
| - return; | |
| + if (leaf == 0x8000001d){ | |
| + if ( subleaf >= ARRAY_SIZE(p->amdcache.raw) ) | |
| + return; | |
| - *res = array_access_nospec(p->extd.raw, leaf & 0xffff); | |
| + *res = array_access_nospec(p->amdcache.raw, subleaf); | |
| + }else{ | |
| + ASSERT((p->extd.max_leaf & 0xffff) < ARRAY_SIZE(p->extd.raw)); | |
| + if ( (leaf & 0xffff) > min_t(uint32_t, p->extd.max_leaf & 0xffff, | |
| + ARRAY_SIZE(p->extd.raw) - 1) ) | |
| + return; | |
| + | |
| + *res = array_access_nospec(p->extd.raw, leaf & 0xffff); | |
| + } | |
| break; | |
| default: | |
| diff --git a/xen/include/xen/lib/x86/cpu-policy.h b/xen/include/xen/lib/x86/cpu-policy.h | |
| index dd204a825b..b39453b331 100644 | |
| --- a/xen/include/xen/lib/x86/cpu-policy.h | |
| +++ b/xen/include/xen/lib/x86/cpu-policy.h | |
| @@ -337,6 +337,11 @@ struct cpu_policy | |
| }; | |
| } extd; | |
| + /* Structured amdcache leaf: 0x8000001d[xx] */ | |
| + union { | |
| + struct cpuid_leaf raw[CPUID_GUEST_NR_CACHE]; | |
| + } amdcache; | |
| + | |
| /* | |
| * 0x000000ce - MSR_INTEL_PLATFORM_INFO | |
| * | |
| diff --git a/xen/lib/x86/cpuid.c b/xen/lib/x86/cpuid.c | |
| index 6298d051f2..cf0d94efda 100644 | |
| --- a/xen/lib/x86/cpuid.c | |
| +++ b/xen/lib/x86/cpuid.c | |
| @@ -149,6 +149,20 @@ void x86_cpu_policy_fill_native(struct cpu_policy *p) | |
| p->cache.subleaf[i] = u.c; | |
| } | |
| + for ( i = 0; i < ARRAY_SIZE(p->amdcache.raw); ++i ) | |
| + { | |
| + union { | |
| + struct cpuid_leaf l; | |
| + } u; | |
| + | |
| + cpuid_count_leaf(0x8000001d, i, &u.l); | |
| + | |
| + if ( u.l.a == 0 ) | |
| + break; | |
| + | |
| + p->amdcache.raw[i] = u.l; | |
| + } | |
| + | |
| /* | |
| * The choice of CPUID_GUEST_NR_CACHE is arbitrary. It is expected | |
| * that it will eventually need increasing for future hardware. | |
| @@ -256,6 +270,17 @@ void x86_cpu_policy_clear_out_of_range_leaves(struct cpu_policy *p) | |
| zero_leaves(p->cache.raw, i, ARRAY_SIZE(p->cache.raw) - 1); | |
| } | |
| + if ( p->basic.max_leaf < 4 ) | |
| + memset(p->amdcache.raw, 0, sizeof(p->amdcache.raw)); | |
| + else | |
| + { | |
| + for ( i = 0; (i < ARRAY_SIZE(p->amdcache.raw) && | |
| + p->amdcache.raw[i].a); ++i ) | |
| + ; | |
| + | |
| + zero_leaves(p->amdcache.raw, i, ARRAY_SIZE(p->amdcache.raw) - 1); | |
| + } | |
| + | |
| if ( p->basic.max_leaf < 7 ) | |
| memset(p->feat.raw, 0, sizeof(p->feat.raw)); | |
| else |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment