qemu/target
Babu Moger b776569a53 target/i386: Fix CPUID encoding of Fn8000001E_ECX
Observed the following failure while booting the SEV-SNP guest and the
guest fails to boot with the smp parameters:
"-smp 192,sockets=1,dies=12,cores=8,threads=2".

qemu-system-x86_64: sev_snp_launch_update: SNP_LAUNCH_UPDATE ret=-5 fw_error=22 'Invalid parameter'
qemu-system-x86_64: SEV-SNP: CPUID validation failed for function 0x8000001e, index: 0x0.
provided: eax:0x00000000, ebx: 0x00000100, ecx: 0x00000b00, edx: 0x00000000
expected: eax:0x00000000, ebx: 0x00000100, ecx: 0x00000300, edx: 0x00000000
qemu-system-x86_64: SEV-SNP: failed update CPUID page

Reason for the failure is due to overflowing of bits used for "Node per
processor" in CPUID Fn8000001E_ECX. This field's width is 3 bits wide and
can hold maximum value 0x7. With dies=12 (0xB), it overflows and spills
over into the reserved bits. In the case of SEV-SNP, this causes CPUID
enforcement failure and guest fails to boot.

The PPR documentation for CPUID_Fn8000001E_ECX [Node Identifiers]
=================================================================
Bits    Description
31:11   Reserved.

10:8    NodesPerProcessor: Node per processor. Read-only.
        ValidValues:
        Value   Description
        0h      1 node per processor.
        7h-1h   Reserved.

7:0     NodeId: Node ID. Read-only. Reset: Fixed,XXh.
=================================================================

As in the spec, the valid value for "node per processor" is 0 and rest
are reserved.

Looking back at the history of decoding of CPUID_Fn8000001E_ECX, noticed
that there were cases where "node per processor" can be more than 1. It
is valid only for pre-F17h (pre-EPYC) architectures. For EPYC or later
CPUs, the linux kernel does not use this information to build the L3
topology.

Also noted that the CPUID Function 0x8000001E_ECX is available only when
TOPOEXT feature is enabled. This feature is enabled only for EPYC(F17h)
or later processors. So, previous generation of processors do not not
enumerate 0x8000001E_ECX leaf.

There could be some corner cases where the older guests could enable the
TOPOEXT feature by running with -cpu host, in which case legacy guests
might notice the topology change. To address those cases introduced a
new CPU property "legacy-multi-node". It will be true for older machine
types to maintain compatibility. By default, it will be false, so new
decoding will be used going forward.

The documentation is taken from Preliminary Processor Programming
Reference (PPR) for AMD Family 19h Model 11h, Revision B1 Processors 55901
Rev 0.25 - Oct 6, 2022.

Cc: qemu-stable@nongnu.org
Fixes: 31ada106d8 ("Simplify CPUID_8000_001E for AMD")
Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537
Reviewed-by: Zhao Liu <zhao1.liu@intel.com>
Signed-off-by: Babu Moger <babu.moger@amd.com>
Message-ID: <0ee4b0a8293188a53970a2b0e4f4ef713425055e.1714757834.git.babu.moger@amd.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
2024-05-07 08:50:38 +02:00
..
alpha exec/cpu: Extract page-protection definitions to page-protection.h 2024-05-06 11:17:15 +02:00
arm Accelerator patches 2024-05-06 10:19:10 -07:00
avr accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
cris exec/cpu: Extract page-protection definitions to page-protection.h 2024-05-06 11:17:15 +02:00
hexagon Accelerator patches 2024-05-06 10:19:10 -07:00
hppa accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
i386 target/i386: Fix CPUID encoding of Fn8000001E_ECX 2024-05-07 08:50:38 +02:00
loongarch accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
m68k exec/cpu: Extract page-protection definitions to page-protection.h 2024-05-06 11:17:15 +02:00
microblaze accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
mips accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
openrisc accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
ppc Accelerator patches 2024-05-06 10:19:10 -07:00
riscv accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
rx accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
s390x exec/cpu: Extract page-protection definitions to page-protection.h 2024-05-06 11:17:15 +02:00
sh4 accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
sparc qemu-sparc queue 2024-05-06 10:19:56 -07:00
tricore accel/tcg: Access tcg_cflags with getter / setter 2024-05-06 11:21:05 +02:00
xtensa exec/cpu: Extract page-protection definitions to page-protection.h 2024-05-06 11:17:15 +02:00
Kconfig meson: make target endianneess available to Kconfig 2024-05-03 15:47:47 +02:00
meson.build exec: Expose 'target_page.h' API to user emulation 2024-04-26 15:28:11 +02:00