[PATCH v1] target/i386: Reserve 0x8000001D and 0x8000001E if !CPUID_EXT3_TOPOEXT

Wei Wang posted 1 patch 3 weeks, 3 days ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/SI2PR01MB4393C152E5D8E3E964AA9E02DC87A@SI2PR01MB4393.apcprd01.prod.exchangelabs.com
Maintainers: Paolo Bonzini <pbonzini@redhat.com>, Zhao Liu <zhao1.liu@intel.com>, Marcelo Tosatti <mtosatti@redhat.com>
target/i386/cpu.c     | 7 ++++++-
target/i386/kvm/kvm.c | 1 +
2 files changed, 7 insertions(+), 1 deletion(-)
[PATCH v1] target/i386: Reserve 0x8000001D and 0x8000001E if !CPUID_EXT3_TOPOEXT
Posted by Wei Wang 3 weeks, 3 days ago
The AMD APM states that if CPUID 0x80000001.ECX[TopologyExtensions] = 0,
then CPUID 0x8000001D and 0x8000001E are reserved. To comply with this,
ensure that EAX, EBX, ECX, and EDX for the two leaves return zero when
CPUID_EXT3_TOPOEXT is not enabled.

To test, launch a VM with CPUID_EXT3_TOPOEXT disabled using "-cpu host" or
"-cpu EPYC-Genoa,-topoext" on a Zen-based machine.

Signed-off-by: Wei Wang <wei.w.wang@hotmail.com>
---
 target/i386/cpu.c     | 7 ++++++-
 target/i386/kvm/kvm.c | 1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 6417775786..437da88b4a 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -8489,6 +8489,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         break;
     case 0x8000001D:
         *eax = 0;
+        /* 0x8000001D leaf is reserved if CPUID_EXT3_TOPOEXT is not set */
+        if (!(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT)) {
+            break;
+        }
         if (cpu->cache_info_passthrough) {
             x86_cpu_get_cache_cpuid(index, count, eax, ebx, ecx, edx);
             break;
@@ -8519,7 +8523,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         }
         break;
     case 0x8000001E:
-        if (cpu->core_id <= 255) {
+        if ((env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
+            cpu->core_id <= 255) {
             encode_topo_cpuid8000001e(cpu, topo_info, eax, ebx, ecx, edx);
         } else {
             *eax = 0;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 60c7981138..c988358548 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2029,6 +2029,7 @@ uint32_t kvm_x86_build_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *entries,
                 cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->edx);
 
                 if (c->eax == 0) {
+                    cpuid_i--;
                     break;
                 }
                 if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
-- 
2.51.0
Re: [PATCH v1] target/i386: Reserve 0x8000001D and 0x8000001E if !CPUID_EXT3_TOPOEXT
Posted by Wei Wang 2 weeks, 6 days ago
On 1/6/26 3:19 AM, Wei Wang wrote:
> The AMD APM states that if CPUID 0x80000001.ECX[TopologyExtensions] = 0,
> then CPUID 0x8000001D and 0x8000001E are reserved. To comply with this,
> ensure that EAX, EBX, ECX, and EDX for the two leaves return zero when
> CPUID_EXT3_TOPOEXT is not enabled.
> 
> To test, launch a VM with CPUID_EXT3_TOPOEXT disabled using "-cpu host" or
> "-cpu EPYC-Genoa,-topoext" on a Zen-based machine.
> 
> Signed-off-by: Wei Wang <wei.w.wang@hotmail.com>
> ---
>   target/i386/cpu.c     | 7 ++++++-
>   target/i386/kvm/kvm.c | 1 +
>   2 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 6417775786..437da88b4a 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -8489,6 +8489,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
>           break;
>       case 0x8000001D:
>           *eax = 0;
> +        /* 0x8000001D leaf is reserved if CPUID_EXT3_TOPOEXT is not set */
> +        if (!(env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT)) {
> +            break;
> +        }
>           if (cpu->cache_info_passthrough) {
>               x86_cpu_get_cache_cpuid(index, count, eax, ebx, ecx, edx);
>               break;
> @@ -8519,7 +8523,8 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
>           }
>           break;
>       case 0x8000001E:
> -        if (cpu->core_id <= 255) {
> +        if ((env->features[FEAT_8000_0001_ECX] & CPUID_EXT3_TOPOEXT) &&
> +            cpu->core_id <= 255) {
>               encode_topo_cpuid8000001e(cpu, topo_info, eax, ebx, ecx, edx);
>           } else {
>               *eax = 0;
> diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
> index 60c7981138..c988358548 100644
> --- a/target/i386/kvm/kvm.c
> +++ b/target/i386/kvm/kvm.c
> @@ -2029,6 +2029,7 @@ uint32_t kvm_x86_build_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *entries,
>                   cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->edx);
>   
>                   if (c->eax == 0) {
> +                    cpuid_i--;
>                       break;
>                   }
>                   if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {

Gentle ping — any thoughts on this patch?