[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH] AMD Processor Topology Information
From: |
Philippe Mathieu-Daudé |
Subject: |
Re: [Qemu-devel] [PATCH] AMD Processor Topology Information |
Date: |
Wed, 8 Nov 2017 09:44:36 -0300 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:52.0) Gecko/20100101 Thunderbird/52.4.0 |
Hi Stanislav,
This does not seem so trivial ;)
Cc'ing more reviewers.
On 11/03/2017 02:30 PM, Stanislav Lanci wrote:
> V2:
> Adds information about cache size and topology on leaf 0x8000001D for family
> 17h
> Without the added cache topology guest with SMT suffers latency problems
>
> Add CPUID 0x8000001E for describing AMD Processor Topology Information
> Disables warning about smt for 17h family of AMD CPUs
>
> Signed-off-by: Stanislav Lanci <address@hidden>
> ---
> target/i386/cpu.c | 93
> ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
> target/i386/kvm.c | 28 +++++++++++++++--
> 2 files changed, 117 insertions(+), 4 deletions(-)
>
> diff --git a/target/i386/cpu.c b/target/i386/cpu.c
> index ddc45abd70..1545e3fe31 100644
> --- a/target/i386/cpu.c
> +++ b/target/i386/cpu.c
> @@ -113,7 +113,9 @@
> /* L1 instruction cache: */
> #define L1I_LINE_SIZE 64
> #define L1I_ASSOCIATIVITY 8
> +#define L1I_ASSOC_AMD_ZEN 4
> #define L1I_SETS 64
> +#define L1I_SETS_AMD_ZEN 256
> #define L1I_PARTITIONS 1
> /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 32KiB */
> #define L1I_DESCRIPTOR CPUID_2_L1I_32KB_8WAY_64B
> @@ -125,7 +127,9 @@
> /* Level 2 unified cache: */
> #define L2_LINE_SIZE 64
> #define L2_ASSOCIATIVITY 16
> +#define L2_ASSOC_AMD_ZEN 8
> #define L2_SETS 4096
> +#define L2_SETS_AMD_ZEN 1024
> #define L2_PARTITIONS 1
> /* Size = LINE_SIZE*ASSOCIATIVITY*SETS*PARTITIONS = 4MiB */
> /*FIXME: CPUID leaf 2 descriptor is inconsistent with CPUID leaf 4 */
> @@ -142,6 +146,7 @@
> #define L3_N_LINE_SIZE 64
> #define L3_N_ASSOCIATIVITY 16
> #define L3_N_SETS 16384
> +#define L3_N_SETS_AMD_ZEN 4096
> #define L3_N_PARTITIONS 1
> #define L3_N_DESCRIPTOR CPUID_2_L3_16MB_16WAY_64B
> #define L3_N_LINES_PER_TAG 1
> @@ -3072,6 +3077,91 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index,
> uint32_t count,
> *edx = 0;
> }
> break;
> + case 0x8000001D: /* AMD TOPOEXT cache info for ZEN */
> + if (cpu->cache_info_passthrough) {
> + host_cpuid(index, count, eax, ebx, ecx, edx);
> + break;
> + } else if ((env->cpuid_version & 0xFF00F00) == 0x800F00) {
> + *eax = 0;
> + switch (count) {
> + case 0: /* L1 dcache info */
> + *eax |= CPUID_4_TYPE_DCACHE | \
> + CPUID_4_LEVEL(1) | \
> + CPUID_4_SELF_INIT_LEVEL | \
> + ((cs->nr_threads - 1) << 14);
> + *ebx = (L1D_LINE_SIZE - 1) | \
> + ((L1D_PARTITIONS - 1) << 12) | \
> + ((L1D_ASSOCIATIVITY - 1) << 22);
> + *ecx = L1D_SETS - 1;
> + *edx = 0;
> + break;
> + case 1: /* L1 icache info */
> + *eax |= CPUID_4_TYPE_ICACHE | \
> + CPUID_4_LEVEL(1) | \
> + CPUID_4_SELF_INIT_LEVEL | \
> + ((cs->nr_threads - 1) << 14);
> + *ebx = (L1I_LINE_SIZE - 1) | \
> + ((L1I_PARTITIONS - 1) << 12) | \
> + ((L1I_ASSOC_AMD_ZEN - 1) << 22);
> + *ecx = L1I_SETS_AMD_ZEN - 1;
> + *edx = 0;
> + break;
> + case 2: /* L2 cache info */
> + *eax |= CPUID_4_TYPE_UNIFIED | \
> + CPUID_4_LEVEL(2) | \
> + CPUID_4_SELF_INIT_LEVEL | \
> + ((cs->nr_threads - 1) << 14);
> + *ebx = (L2_LINE_SIZE - 1) | \
> + ((L2_PARTITIONS - 1) << 12) | \
> + ((L2_ASSOC_AMD_ZEN - 1) << 22);
> + *ecx = L2_SETS_AMD_ZEN - 1;
> + *edx = CPUID_4_INCLUSIVE;
> + break;
> + case 3: /* L3 cache info */
> + if (!cpu->enable_l3_cache) {
> + *eax = 0;
> + *ebx = 0;
> + *ecx = 0;
> + *edx = 0;
> + break;
> + }
> + *eax |= CPUID_4_TYPE_UNIFIED | \
> + CPUID_4_LEVEL(3) | \
> + CPUID_4_SELF_INIT_LEVEL | \
> + ((cs->nr_cores * cs->nr_threads - 1) << 14);
> + *ebx = (L3_N_LINE_SIZE - 1) | \
> + ((L3_N_PARTITIONS - 1) << 12) | \
> + ((L3_N_ASSOCIATIVITY - 1) << 22);
> + *ecx = L3_N_SETS_AMD_ZEN - 1;
> + *edx = CPUID_4_NO_INVD_SHARING;
> + break;
> + default: /* end of info */
> + *eax = 0;
> + *ebx = 0;
> + *ecx = 0;
> + *edx = 0;
> + break;
> + }
> + } else {
> + *eax = 0;
> + *ebx = 0;
> + *ecx = 0;
> + *edx = 0;
> + }
> + break;
> + case 0x8000001E: /* AMD TOPOEXT cpu topology info for ZEN */
> + if ((env->cpuid_version & 0xFF00F00) == 0x800F00) {
> + *eax = cpu->apic_id;
> + *ebx = (cs->nr_threads - 1) << 8 | cpu->core_id;
> + *ecx = cpu->socket_id;
> + *edx = 0;
> + } else {
> + *eax = 0;
> + *ebx = 0;
> + *ecx = 0;
> + *edx = 0;
> + }
> + break;
> case 0xC0000000:
> *eax = env->cpuid_xlevel2;
> *ebx = 0;
> @@ -3742,7 +3832,8 @@ static void x86_cpu_realizefn(DeviceState *dev, Error
> **errp)
> * NOTE: the following code has to follow qemu_init_vcpu(). Otherwise
> * cs->nr_threads hasn't be populated yet and the checking is incorrect.
> */
> - if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned) {
> + if (!IS_INTEL_CPU(env) && cs->nr_threads > 1 && !ht_warned && \
> + (env->cpuid_version & 0xFF00F00) != 0x800F00) {
> error_report("AMD CPU doesn't support hyperthreading. Please
> configure"
> " -smp options properly.");
> ht_warned = true;
> diff --git a/target/i386/kvm.c b/target/i386/kvm.c
> index 6db7783edc..d6b4e1ae74 100644
> --- a/target/i386/kvm.c
> +++ b/target/i386/kvm.c
> @@ -869,9 +869,31 @@ int kvm_arch_init_vcpu(CPUState *cs)
> }
> c = &cpuid_data.entries[cpuid_i++];
>
> - c->function = i;
> - c->flags = 0;
> - cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
> + switch (i) {
> + case 0x8000001d:
> + 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->eax == 0) {
> + break;
> + }
> + if (cpuid_i == KVM_MAX_CPUID_ENTRIES) {
> + fprintf(stderr, "cpuid_data is full, no space for "
> + "cpuid(eax:0x%x,ecx:0x%x)\n", i, j);
> + abort();
> + }
> + c = &cpuid_data.entries[cpuid_i++];
> + }
> + break;
> + default:
> + c->function = i;
> + c->flags = 0;
> + cpu_x86_cpuid(env, i, 0, &c->eax, &c->ebx, &c->ecx, &c->edx);
> + break;
> + }
> }
>
> /* Call Centaur's CPUID instructions they are supported. */
>