Implement CPUID leaf 0x80000026 (AMD Extended CPU Topology). It presents the
complete topology information to guests via a single CPUID with multiple
subleafs, each describing a specific hierarchy level, viz. core, complex,
die, socket.
Note that complex/CCX level relates to "die" in QEMU, and die/CCD level is
not supported in QEMU yet. Hence, use CCX at CCD level until diegroups are
implemented.
Signed-off-by: Shivansh Dhiman <shivansh.dhiman@amd.com>
---
target/i386/cpu.c | 76 +++++++++++++++++++++++++++++++++++++++++++
target/i386/kvm/kvm.c | 17 ++++++++++
2 files changed, 93 insertions(+)
diff --git a/target/i386/cpu.c b/target/i386/cpu.c
index 641777578637..b7827e448aa5 100644
--- a/target/i386/cpu.c
+++ b/target/i386/cpu.c
@@ -495,6 +495,78 @@ static void encode_topo_cpuid1f(CPUX86State *env, uint32_t count,
assert(!(*eax & ~0x1f));
}
+/*
+ * CPUID_Fn80000026: Extended CPU Topology
+ *
+ * EAX Bits Description
+ * 31:5 Reserved
+ * 4:0 Number of bits to shift Extended APIC ID right to get a unique
+ * topology ID of the current hierarchy level.
+ *
+ * EBX Bits Description
+ * 31:16 Reserved
+ * 15:0 Number of logical processors at the current hierarchy level.
+ *
+ * ECX Bits Description
+ * 31:16 Reserved
+ * 15:8 Level Type. Values:
+ * Value Description
+ * 0h Reserved
+ * 1h Core
+ * 2h Complex
+ * 3h Die
+ * 4h Socket
+ * FFh-05h Reserved
+ * 7:0 Input ECX
+ *
+ * EDX Bits Description
+ * 31:0 Extended APIC ID of the logical processor
+ */
+static void encode_topo_cpuid80000026(CPUX86State *env, uint32_t count,
+ X86CPUTopoInfo *topo_info,
+ uint32_t *eax, uint32_t *ebx,
+ uint32_t *ecx, uint32_t *edx)
+{
+ X86CPU *cpu = env_archcpu(env);
+ uint32_t shift, nr_logproc, lvl_type;
+
+ switch (count) {
+ case 0:
+ shift = apicid_core_offset(topo_info);
+ nr_logproc = num_threads_by_topo_level(topo_info, CPU_TOPOLOGY_LEVEL_CORE);
+ lvl_type = 1;
+ break;
+
+ case 1:
+ shift = apicid_die_offset(topo_info);
+ nr_logproc = num_threads_by_topo_level(topo_info, CPU_TOPOLOGY_LEVEL_DIE);
+ lvl_type = 2;
+ break;
+
+ case 2:
+ shift = apicid_die_offset(topo_info);
+ nr_logproc = num_threads_by_topo_level(topo_info, CPU_TOPOLOGY_LEVEL_DIE);
+ lvl_type = 3;
+ break;
+
+ case 3:
+ shift = apicid_pkg_offset(topo_info);
+ nr_logproc = num_threads_by_topo_level(topo_info, CPU_TOPOLOGY_LEVEL_SOCKET);
+ lvl_type = 4;
+ break;
+
+ default:
+ shift = 0;
+ nr_logproc = 0;
+ lvl_type = 0;
+ }
+
+ *eax = shift & 0x1F;
+ *ebx = nr_logproc;
+ *ecx = ((lvl_type & 0xFF) << 8) | (count & 0xFF);
+ *edx = cpu->apic_id;
+}
+
/* Encode cache info for CPUID[0x80000005].ECX or CPUID[0x80000005].EDX */
static uint32_t encode_cache_cpuid80000005(CPUCacheInfo *cache)
{
@@ -8554,6 +8626,10 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
R_EBX) & 0xf;
}
break;
+ case 0x80000026:
+ /* AMD Extended CPU Topology */
+ encode_topo_cpuid80000026(env, count, topo_info, eax, ebx, ecx, edx);
+ break;
case 0xC0000000:
*eax = env->cpuid_xlevel2;
*ebx = 0;
diff --git a/target/i386/kvm/kvm.c b/target/i386/kvm/kvm.c
index 60c798113823..ed3d40bf073e 100644
--- a/target/i386/kvm/kvm.c
+++ b/target/i386/kvm/kvm.c
@@ -2037,6 +2037,23 @@ uint32_t kvm_x86_build_cpuid(CPUX86State *env, struct kvm_cpuid_entry2 *entries,
c = &entries[cpuid_i++];
}
break;
+ case 0x80000026:
+ /* Query for all AMD extended topology information leaves */
+ for (j = 0; ; j++) {
+ c->function = i;
+ c->flags = KVM_CPUID_FLAG_SIGNIFCANT_INDEX;
+ c->index = j;
+ cpu_x86_cpuid(env, i, j, &c->eax, &c->ebx, &c->ecx, &c->edx);
+
+ if (((c->ecx >> 8) & 0xFF) == 0) {
+ break;
+ }
+ if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
+ goto full;
+ }
+ c = &entries[cpuid_i++];
+ }
+ break;
default:
c->function = i;
c->flags = 0;
--
2.43.0
Hi Shivansh,
Sorry for late reply.
On Fri, Nov 21, 2025 at 08:34:48AM +0000, Shivansh Dhiman wrote:
> Date: Fri, 21 Nov 2025 08:34:48 +0000
> From: Shivansh Dhiman <shivansh.dhiman@amd.com>
> Subject: [PATCH 1/5] i386: Implement CPUID 0x80000026
> X-Mailer: git-send-email 2.43.0
>
> Implement CPUID leaf 0x80000026 (AMD Extended CPU Topology). It presents the
> complete topology information to guests via a single CPUID with multiple
> subleafs, each describing a specific hierarchy level, viz. core, complex,
> die, socket.
>
> Note that complex/CCX level relates to "die" in QEMU, and die/CCD level is
> not supported in QEMU yet. Hence, use CCX at CCD level until diegroups are
> implemented.
I'm trying to understand AMD's topology hierarchy by comparing it to the
kernel's arch/x86/kernel/cpu/topology_ext.c file:
static const unsigned int topo_domain_map_0b_1f[MAX_TYPE_1F] = {
[SMT_TYPE] = TOPO_SMT_DOMAIN,
[CORE_TYPE] = TOPO_CORE_DOMAIN,
[MODULE_TYPE] = TOPO_MODULE_DOMAIN,
[TILE_TYPE] = TOPO_TILE_DOMAIN,
[DIE_TYPE] = TOPO_DIE_DOMAIN,
[DIEGRP_TYPE] = TOPO_DIEGRP_DOMAIN,
};
static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
[SMT_TYPE] = TOPO_SMT_DOMAIN,
[CORE_TYPE] = TOPO_CORE_DOMAIN,
[AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
[AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
};
What particularly puzzles me is that "complex" isn't listed here, yet it
should be positioned between "core" and CCD. Does this mean complex
actually corresponds to kernel's module domain?
Back to QEMU, now CCX is mapped as QEMU's die level, and AMD socket is mapped
to socket level. Should we revisit QEMU's topology level mapping for AMD, to
align with the above topology domain mapping?
If we want to go further: supporting CCD configuration would be quite
tricky. I feel that adding another new parameter between the smp.dies
and smp.sockets would create significant confusion.
> Signed-off-by: Shivansh Dhiman <shivansh.dhiman@amd.com>
> ---
> target/i386/cpu.c | 76 +++++++++++++++++++++++++++++++++++++++++++
> target/i386/kvm/kvm.c | 17 ++++++++++
> 2 files changed, 93 insertions(+)
>
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index 641777578637..b7827e448aa5 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -495,6 +495,78 @@ static void encode_topo_cpuid1f(CPUX86State *env, uint32_t count,
> assert(!(*eax & ~0x1f));
> }
>
> +/*
> + * CPUID_Fn80000026: Extended CPU Topology
> + *
> + * EAX Bits Description
> + * 31:5 Reserved
> + * 4:0 Number of bits to shift Extended APIC ID right to get a unique
> + * topology ID of the current hierarchy level.
> + *
> + * EBX Bits Description
> + * 31:16 Reserved
> + * 15:0 Number of logical processors at the current hierarchy level.
> + *
> + * ECX Bits Description
> + * 31:16 Reserved
> + * 15:8 Level Type. Values:
> + * Value Description
> + * 0h Reserved
> + * 1h Core
> + * 2h Complex
> + * 3h Die
> + * 4h Socket
> + * FFh-05h Reserved
> + * 7:0 Input ECX
> + *
> + * EDX Bits Description
> + * 31:0 Extended APIC ID of the logical processor
> + */
I feel this long comment is not necessary, since people could check APM for
details. Or this description could be included in commit message.
> +static void encode_topo_cpuid80000026(CPUX86State *env, uint32_t count,
> + X86CPUTopoInfo *topo_info,
> + uint32_t *eax, uint32_t *ebx,
> + uint32_t *ecx, uint32_t *edx)
Regards,
Zhao
Hi Zhao,
On 07-01-2026 12:55, Zhao Liu wrote:
> Hi Shivansh,
>
> Sorry for late reply.
>
> On Fri, Nov 21, 2025 at 08:34:48AM +0000, Shivansh Dhiman wrote:
>> Date: Fri, 21 Nov 2025 08:34:48 +0000
>> From: Shivansh Dhiman <shivansh.dhiman@amd.com>
>> Subject: [PATCH 1/5] i386: Implement CPUID 0x80000026
>> X-Mailer: git-send-email 2.43.0
>>
>> Implement CPUID leaf 0x80000026 (AMD Extended CPU Topology). It presents the
>> complete topology information to guests via a single CPUID with multiple
>> subleafs, each describing a specific hierarchy level, viz. core, complex,
>> die, socket.
>>
>> Note that complex/CCX level relates to "die" in QEMU, and die/CCD level is
>> not supported in QEMU yet. Hence, use CCX at CCD level until diegroups are
>> implemented.
>
> I'm trying to understand AMD's topology hierarchy by comparing it to the
> kernel's arch/x86/kernel/cpu/topology_ext.c file:
>
> static const unsigned int topo_domain_map_0b_1f[MAX_TYPE_1F] = {
> [SMT_TYPE] = TOPO_SMT_DOMAIN,
> [CORE_TYPE] = TOPO_CORE_DOMAIN,
> [MODULE_TYPE] = TOPO_MODULE_DOMAIN,
> [TILE_TYPE] = TOPO_TILE_DOMAIN,
> [DIE_TYPE] = TOPO_DIE_DOMAIN,
> [DIEGRP_TYPE] = TOPO_DIEGRP_DOMAIN,
> };
>
> static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
> [SMT_TYPE] = TOPO_SMT_DOMAIN,
> [CORE_TYPE] = TOPO_CORE_DOMAIN,
> [AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
> [AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
> };
These mappings reuse some original names (SMT_TYPE and CORE_TYPE) along with the
new ones (AMD_CCD_TYPE and AMD_SOCKET_TYPE). I think to avoid defining more AMD
specific types the original names are used. So, essentially you can read them
like this:
static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
[AMD_CORE_TYPE] = TOPO_SMT_DOMAIN,
[AMD_CCX_TYPE] = TOPO_CORE_DOMAIN,
[AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
[AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
};
>
> What particularly puzzles me is that "complex" isn't listed here, yet it
> should be positioned between "core" and CCD. Does this mean complex
> actually corresponds to kernel's module domain?
There is a nuance with CPUID 80000026h related to the shifting of x2APIC ID.
According to APM, EAX[4:0] tells us the number of bits to shift x2APIC ID right
to get unique topology ID of the next instance of the current level type.
So, all logical processors with the same next level ID share current level. This
results in mapping the Nth level type to (N-1)th domain. This is unlike Intel's
CPUID 0xb which maps Nth level type to Nth domain.
Back to your question, the complex is same as tile since both represent a L3
cache boundary.
>
> Back to QEMU, now CCX is mapped as QEMU's die level, and AMD socket is mapped
> to socket level. Should we revisit QEMU's topology level mapping for AMD, to
> align with the above topology domain mapping?
>
> If we want to go further: supporting CCD configuration would be quite
> tricky. I feel that adding another new parameter between the smp.dies
> and smp.sockets would create significant confusion.
The current kernel doesn't have sensitivity to a level between L3 boundary and
socket. Also, most production systems in current AMD CPU landscape have CCD=CCX.
Only a handful of models feature CCD=2CCX, so this isn't an immediate pressing need.
In QEMU's terminology, socket represents an actual socket and die represents the
L3 cache boundary. There is no intermediate level between them. Looking ahead,
when more granular topology information (like CCD) becomes necessary for VMs,
introducing a "diegroup" level would be the logical approach. This level would
fit naturally between die and socket, as its role cannot be fulfilled by
existing topology levels.
Also, I was looking at Intel's SDM Vol. 2A "Instruction Set Reference, A-Z"
Table 3-8. "Information Returned by CPUID Instruction". The presence of a
"diegrp" level between die and socket suggests Intel has already recognized the
need for this intermediate topology level. If this maps to a similar concept as
AMD's CCD, it would indeed strengthen the case for introducing a new level in QEMU.
>
>> Signed-off-by: Shivansh Dhiman <shivansh.dhiman@amd.com>
>> ---
>> target/i386/cpu.c | 76 +++++++++++++++++++++++++++++++++++++++++++
>> target/i386/kvm/kvm.c | 17 ++++++++++
>> 2 files changed, 93 insertions(+)
>>
>> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
>> index 641777578637..b7827e448aa5 100644
>> --- a/target/i386/cpu.c
>> +++ b/target/i386/cpu.c
>> @@ -495,6 +495,78 @@ static void encode_topo_cpuid1f(CPUX86State *env, uint32_t count,
>> assert(!(*eax & ~0x1f));
>> }
>>
>> +/*
>> + * CPUID_Fn80000026: Extended CPU Topology
>> + *
>> + * EAX Bits Description
>> + * 31:5 Reserved
>> + * 4:0 Number of bits to shift Extended APIC ID right to get a unique
>> + * topology ID of the current hierarchy level.
>> + *
>> + * EBX Bits Description
>> + * 31:16 Reserved
>> + * 15:0 Number of logical processors at the current hierarchy level.
>> + *
>> + * ECX Bits Description
>> + * 31:16 Reserved
>> + * 15:8 Level Type. Values:
>> + * Value Description
>> + * 0h Reserved
>> + * 1h Core
>> + * 2h Complex
>> + * 3h Die
>> + * 4h Socket
>> + * FFh-05h Reserved
>> + * 7:0 Input ECX
>> + *
>> + * EDX Bits Description
>> + * 31:0 Extended APIC ID of the logical processor
>> + */
>
> I feel this long comment is not necessary, since people could check APM for
> details. Or this description could be included in commit message.
Sure. Will do. Thanks.
>
>> +static void encode_topo_cpuid80000026(CPUX86State *env, uint32_t count,
>> + X86CPUTopoInfo *topo_info,
>> + uint32_t *eax, uint32_t *ebx,
>> + uint32_t *ecx, uint32_t *edx)
>
> Regards,
> Zhao
>
On Thu, Jan 08, 2026 at 04:03:12PM +0530, Shivansh Dhiman wrote:
> Date: Thu, 8 Jan 2026 16:03:12 +0530
> From: Shivansh Dhiman <shivansh.dhiman@amd.com>
> Subject: Re: [PATCH 1/5] i386: Implement CPUID 0x80000026
>
> Hi Zhao,
>
> On 07-01-2026 12:55, Zhao Liu wrote:
> > Hi Shivansh,
> >
> > Sorry for late reply.
> >
> > On Fri, Nov 21, 2025 at 08:34:48AM +0000, Shivansh Dhiman wrote:
> >> Date: Fri, 21 Nov 2025 08:34:48 +0000
> >> From: Shivansh Dhiman <shivansh.dhiman@amd.com>
> >> Subject: [PATCH 1/5] i386: Implement CPUID 0x80000026
> >> X-Mailer: git-send-email 2.43.0
> >>
> >> Implement CPUID leaf 0x80000026 (AMD Extended CPU Topology). It presents the
> >> complete topology information to guests via a single CPUID with multiple
> >> subleafs, each describing a specific hierarchy level, viz. core, complex,
> >> die, socket.
> >>
> >> Note that complex/CCX level relates to "die" in QEMU, and die/CCD level is
> >> not supported in QEMU yet. Hence, use CCX at CCD level until diegroups are
> >> implemented.
> >
> > I'm trying to understand AMD's topology hierarchy by comparing it to the
> > kernel's arch/x86/kernel/cpu/topology_ext.c file:
> >
> > static const unsigned int topo_domain_map_0b_1f[MAX_TYPE_1F] = {
> > [SMT_TYPE] = TOPO_SMT_DOMAIN,
> > [CORE_TYPE] = TOPO_CORE_DOMAIN,
> > [MODULE_TYPE] = TOPO_MODULE_DOMAIN,
> > [TILE_TYPE] = TOPO_TILE_DOMAIN,
> > [DIE_TYPE] = TOPO_DIE_DOMAIN,
> > [DIEGRP_TYPE] = TOPO_DIEGRP_DOMAIN,
> > };
> >
> > static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
> > [SMT_TYPE] = TOPO_SMT_DOMAIN,
> > [CORE_TYPE] = TOPO_CORE_DOMAIN,
> > [AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
> > [AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
> > };
>
> These mappings reuse some original names (SMT_TYPE and CORE_TYPE) along with the
> new ones (AMD_CCD_TYPE and AMD_SOCKET_TYPE). I think to avoid defining more AMD
> specific types the original names are used. So, essentially you can read them
> like this:
>
> static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
> [AMD_CORE_TYPE] = TOPO_SMT_DOMAIN,
> [AMD_CCX_TYPE] = TOPO_CORE_DOMAIN,
> [AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
> [AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
> };
Thank you! It's clear and I see the difference.
> > What particularly puzzles me is that "complex" isn't listed here, yet it
> > should be positioned between "core" and CCD. Does this mean complex
> > actually corresponds to kernel's module domain?
>
> There is a nuance with CPUID 80000026h related to the shifting of x2APIC ID.
> According to APM, EAX[4:0] tells us the number of bits to shift x2APIC ID right
> to get unique topology ID of the next instance of the current level type.
>
> So, all logical processors with the same next level ID share current level. This
> results in mapping the Nth level type to (N-1)th domain. This is unlike Intel's
> CPUID 0xb which maps Nth level type to Nth domain.
Yes, it's the core difference. I think it's better to have a helper
clearly define the mapping between QEMU general topo level v.s. AMD topo
types, similar to cpuid1f_topo_type().
> Back to your question, the complex is same as tile since both represent a L3
> cache boundary.
Yeah, this makes sense. CCD->die, and CCX->tile.
> > Back to QEMU, now CCX is mapped as QEMU's die level, and AMD socket is mapped
> > to socket level. Should we revisit QEMU's topology level mapping for AMD, to
> > align with the above topology domain mapping?
> >
> > If we want to go further: supporting CCD configuration would be quite
> > tricky. I feel that adding another new parameter between the smp.dies
> > and smp.sockets would create significant confusion.
>
> The current kernel doesn't have sensitivity to a level between L3 boundary and
> socket. Also, most production systems in current AMD CPU landscape have CCD=CCX.
> Only a handful of models feature CCD=2CCX, so this isn't an immediate pressing need.
>
> In QEMU's terminology, socket represents an actual socket and die represents the
> L3 cache boundary. There is no intermediate level between them. Looking ahead,
> when more granular topology information (like CCD) becomes necessary for VMs,
> introducing a "diegroup" level would be the logical approach. This level would
> fit naturally between die and socket, as its role cannot be fulfilled by
> existing topology levels.
With your nice clarification, I think this problem has become a bit easier.
In fact, we can consider that CCD=CCX=die is currently the default
assumption in QEMU. When future implementations require distinguishing between
these CCD/CCX concepts, we can simply introduce an additional "smp.tiles" and
map CCX to it. This may need a documentation or a compatibility option, but I
believe these extra efforts are worthwhile.
And "smp.tiles" means "how many tiles in a die", so I feel it's perfect
to describe CCX.
> Also, I was looking at Intel's SDM Vol. 2A "Instruction Set Reference, A-Z"
> Table 3-8. "Information Returned by CPUID Instruction". The presence of a
> "diegrp" level between die and socket suggests Intel has already recognized the
> need for this intermediate topology level. If this maps to a similar concept as
> AMD's CCD, it would indeed strengthen the case for introducing a new level in QEMU.
SDM has "diedrp" but currently no product is using it. So it's hard for me
to say what this layer will look like in the future, especially with
topology-aware features/MSRs. Therefore, I prefer to add the "tile" if
needed, as it aligns better with the existing hierarchy definition. Anyway,
this is the future topic (though it is related with the last statement in your
commit message). At least for now, how to map the AMD hierarchy is fairly
clear.
Thanks,
Zhao
On 09-01-2026 14:33, Zhao Liu wrote:
> On Thu, Jan 08, 2026 at 04:03:12PM +0530, Shivansh Dhiman wrote:
>> Date: Thu, 8 Jan 2026 16:03:12 +0530
>> From: Shivansh Dhiman <shivansh.dhiman@amd.com>
>> Subject: Re: [PATCH 1/5] i386: Implement CPUID 0x80000026
>>
>> Hi Zhao,
>>
>> On 07-01-2026 12:55, Zhao Liu wrote:
>>> Hi Shivansh,
>>>
>>> Sorry for late reply.
>>>
>>> On Fri, Nov 21, 2025 at 08:34:48AM +0000, Shivansh Dhiman wrote:
>>>> Date: Fri, 21 Nov 2025 08:34:48 +0000
>>>> From: Shivansh Dhiman <shivansh.dhiman@amd.com>
>>>> Subject: [PATCH 1/5] i386: Implement CPUID 0x80000026
>>>> X-Mailer: git-send-email 2.43.0
>>>>
>>>> Implement CPUID leaf 0x80000026 (AMD Extended CPU Topology). It presents the
>>>> complete topology information to guests via a single CPUID with multiple
>>>> subleafs, each describing a specific hierarchy level, viz. core, complex,
>>>> die, socket.
>>>>
>>>> Note that complex/CCX level relates to "die" in QEMU, and die/CCD level is
>>>> not supported in QEMU yet. Hence, use CCX at CCD level until diegroups are
>>>> implemented.
>>>
>>> I'm trying to understand AMD's topology hierarchy by comparing it to the
>>> kernel's arch/x86/kernel/cpu/topology_ext.c file:
>>>
>>> static const unsigned int topo_domain_map_0b_1f[MAX_TYPE_1F] = {
>>> [SMT_TYPE] = TOPO_SMT_DOMAIN,
>>> [CORE_TYPE] = TOPO_CORE_DOMAIN,
>>> [MODULE_TYPE] = TOPO_MODULE_DOMAIN,
>>> [TILE_TYPE] = TOPO_TILE_DOMAIN,
>>> [DIE_TYPE] = TOPO_DIE_DOMAIN,
>>> [DIEGRP_TYPE] = TOPO_DIEGRP_DOMAIN,
>>> };
>>>
>>> static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
>>> [SMT_TYPE] = TOPO_SMT_DOMAIN,
>>> [CORE_TYPE] = TOPO_CORE_DOMAIN,
>>> [AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
>>> [AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
>>> };
>>
>> These mappings reuse some original names (SMT_TYPE and CORE_TYPE) along with the
>> new ones (AMD_CCD_TYPE and AMD_SOCKET_TYPE). I think to avoid defining more AMD
>> specific types the original names are used. So, essentially you can read them
>> like this:
>>
>> static const unsigned int topo_domain_map_80000026[MAX_TYPE_80000026] = {
>> [AMD_CORE_TYPE] = TOPO_SMT_DOMAIN,
>> [AMD_CCX_TYPE] = TOPO_CORE_DOMAIN,
>> [AMD_CCD_TYPE] = TOPO_TILE_DOMAIN,
>> [AMD_SOCKET_TYPE] = TOPO_DIE_DOMAIN,
>> };
>
> Thank you! It's clear and I see the difference.
>
>>> What particularly puzzles me is that "complex" isn't listed here, yet it
>>> should be positioned between "core" and CCD. Does this mean complex
>>> actually corresponds to kernel's module domain?
>>
>> There is a nuance with CPUID 80000026h related to the shifting of x2APIC ID.
>> According to APM, EAX[4:0] tells us the number of bits to shift x2APIC ID right
>> to get unique topology ID of the next instance of the current level type.
>>
>> So, all logical processors with the same next level ID share current level. This
>> results in mapping the Nth level type to (N-1)th domain. This is unlike Intel's
>> CPUID 0xb which maps Nth level type to Nth domain.
>
> Yes, it's the core difference. I think it's better to have a helper
> clearly define the mapping between QEMU general topo level v.s. AMD topo
> types, similar to cpuid1f_topo_type().
Yeah. That can be done.
>
>> Back to your question, the complex is same as tile since both represent a L3
>> cache boundary.
>
> Yeah, this makes sense. CCD->die, and CCX->tile.
>
>>> Back to QEMU, now CCX is mapped as QEMU's die level, and AMD socket is mapped
>>> to socket level. Should we revisit QEMU's topology level mapping for AMD, to
>>> align with the above topology domain mapping?
>>>
>>> If we want to go further: supporting CCD configuration would be quite
>>> tricky. I feel that adding another new parameter between the smp.dies
>>> and smp.sockets would create significant confusion.
>>
>> The current kernel doesn't have sensitivity to a level between L3 boundary and
>> socket. Also, most production systems in current AMD CPU landscape have CCD=CCX.
>> Only a handful of models feature CCD=2CCX, so this isn't an immediate pressing need.
>>
>> In QEMU's terminology, socket represents an actual socket and die represents the
>> L3 cache boundary. There is no intermediate level between them. Looking ahead,
>> when more granular topology information (like CCD) becomes necessary for VMs,
>> introducing a "diegroup" level would be the logical approach. This level would
>> fit naturally between die and socket, as its role cannot be fulfilled by
>> existing topology levels.
>
> With your nice clarification, I think this problem has become a bit easier.
>
> In fact, we can consider that CCD=CCX=die is currently the default
> assumption in QEMU. When future implementations require distinguishing between
> these CCD/CCX concepts, we can simply introduce an additional "smp.tiles" and
> map CCX to it. This may need a documentation or a compatibility option, but I
> believe these extra efforts are worthwhile.
>
> And "smp.tiles" means "how many tiles in a die", so I feel it's perfect
> to describe CCX.
That indeed looks like a cleaner solution. However, I'm concerned about
retaining compatibility with existing "dies". But yeah, that's a task for a
later time.
>
>> Also, I was looking at Intel's SDM Vol. 2A "Instruction Set Reference, A-Z"
>> Table 3-8. "Information Returned by CPUID Instruction". The presence of a
>> "diegrp" level between die and socket suggests Intel has already recognized the
>> need for this intermediate topology level. If this maps to a similar concept as
>> AMD's CCD, it would indeed strengthen the case for introducing a new level in QEMU.
>
> SDM has "diedrp" but currently no product is using it. So it's hard for me
> to say what this layer will look like in the future, especially with
> topology-aware features/MSRs. Therefore, I prefer to add the "tile" if
> needed, as it aligns better with the existing hierarchy definition. Anyway,
> this is the future topic (though it is related with the last statement in your
> commit message). At least for now, how to map the AMD hierarchy is fairly
> clear.
Ack.
>
> Thanks,
> Zhao
>
> >> The current kernel doesn't have sensitivity to a level between L3 boundary and > >> socket. Also, most production systems in current AMD CPU landscape have CCD=CCX. > >> Only a handful of models feature CCD=2CCX, so this isn't an immediate pressing need. > >> > >> In QEMU's terminology, socket represents an actual socket and die represents the > >> L3 cache boundary. There is no intermediate level between them. Looking ahead, > >> when more granular topology information (like CCD) becomes necessary for VMs, > >> introducing a "diegroup" level would be the logical approach. This level would > >> fit naturally between die and socket, as its role cannot be fulfilled by > >> existing topology levels. > > > > With your nice clarification, I think this problem has become a bit easier. > > > > In fact, we can consider that CCD=CCX=die is currently the default > > assumption in QEMU. When future implementations require distinguishing between > > these CCD/CCX concepts, we can simply introduce an additional "smp.tiles" and > > map CCX to it. This may need a documentation or a compatibility option, but I > > believe these extra efforts are worthwhile. > > > > And "smp.tiles" means "how many tiles in a die", so I feel it's perfect > > to describe CCX. > > That indeed looks like a cleaner solution. However, I'm concerned about > retaining compatibility with existing "dies". But yeah, that's a task for a > later time. Yes, it may be necessary to address some compatibility issues. But I think this way could align with the topology mapping of the Linux kernel as much as possible. Thanks, Zhao
On 12-01-2026 13:31, Zhao Liu wrote: >>>> The current kernel doesn't have sensitivity to a level between L3 boundary and >>>> socket. Also, most production systems in current AMD CPU landscape have CCD=CCX. >>>> Only a handful of models feature CCD=2CCX, so this isn't an immediate pressing need. >>>> >>>> In QEMU's terminology, socket represents an actual socket and die represents the >>>> L3 cache boundary. There is no intermediate level between them. Looking ahead, >>>> when more granular topology information (like CCD) becomes necessary for VMs, >>>> introducing a "diegroup" level would be the logical approach. This level would >>>> fit naturally between die and socket, as its role cannot be fulfilled by >>>> existing topology levels. >>> >>> With your nice clarification, I think this problem has become a bit easier. >>> >>> In fact, we can consider that CCD=CCX=die is currently the default >>> assumption in QEMU. When future implementations require distinguishing between >>> these CCD/CCX concepts, we can simply introduce an additional "smp.tiles" and >>> map CCX to it. This may need a documentation or a compatibility option, but I >>> believe these extra efforts are worthwhile. >>> >>> And "smp.tiles" means "how many tiles in a die", so I feel it's perfect >>> to describe CCX. >> >> That indeed looks like a cleaner solution. However, I'm concerned about >> retaining compatibility with existing "dies". But yeah, that's a task for a >> later time. > > Yes, it may be necessary to address some compatibility issues. But I think > this way could align with the topology mapping of the Linux kernel as much > as possible. This sounds like a good idea. Thanks. > > Thanks, > Zhao
© 2016 - 2026 Red Hat, Inc.