Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

AMD CPUs have incorrect package topology in XNU #112

Open
vit9696 opened this issue May 5, 2021 · 1 comment
Open

AMD CPUs have incorrect package topology in XNU #112

vit9696 opened this issue May 5, 2021 · 1 comment
Labels
bug Something isn't working

Comments

@vit9696
Copy link

vit9696 commented May 5, 2021

Describe the bug
macOS builds a CPU topology, i.e. the CPU structure, comprised of lcores, cores, dies, and packages:

  • a logical core is essentially a thread or a virtual core.
  • a core is a physical core, it generally has 1 or 2 logical cores (depending on Hyper Threading support).
  • a die is a CPU die or chiplet where one or more cores are placed.
  • a package is physical CPU installed into the socket, it has one or more dies.

Let's take AMD Ryzen 9 5900X 12-Core Processor. This CPU has 12 cores with the support for Hyper Threading, so it is supposed to have a list with 24 virtual cores and a list with 12 physical cores, each physical core linking to a list of 2 physical cores. Since AMD follows chiplet design, and each die is believed to have 6 cores, we also expect 2 dies pointing to a set of 6 physical and 12 virtual cores. Since this CPU is produced as a single socket and can only be installed into single socket motherboards, there can only be 1 package.

For some reason this is not what I see, and the current patches provide an inadequate CPU topology in XNU as shown in acidanthera/bugtracker#1625 (comment).

To Reproduce

Let's take this simple code and execute it in the kernel:

		pmKextRegister(PM_DISPATCH_VERSION, NULL, &pmCallbacks);
		uint32_t cc = 0, pp = 0;
		auto pkg = pmCallbacks.GetPkgRoot();
		while (pkg != nullptr) {
			auto core = pkg->cores;
			while (core != nullptr) {
				cc++;
				core = core->next_in_pkg;
			}
			DBGLOG("rev", "calculated %u cores in pkg %u", cc, pp);
			pp++;
			pkg = pkg->next;
		}

Expected behavior

What we expect it print is:

calculated 12 cores in pkg 0

Actual behavior

Yet what does print is:

calculated 2 cores in pkg 0
calculated 12 cores in pkg 1

I.e. we have 2 packages, one package with 2 cores and another 10. In XNU terms that means we installed 2 physical AMD Ryzen 9 5900X 12-Core Processor CPUs on one board, but one has just the 2 cores working and another one has 10 cores working. This is plain wrong and makes no sense.

If applicable, add screenshots to help explain your problem.

System Version (please complete the following information):

  • macOS: 11.3

System Information (please complete the following information):

  • AMD Ryzen 9 5900X 12-Core Processor
  • ASUS ROG STRIX X570-E GAMING
  • OpenCore 0.6.9

Additional context

This is particularly terrific, because genuine configurations with multiple physical CPUs are indistinguishable, and in RestrictEvents I actually had to hardcode AMD CPUID checks to assume that only single CPU configurations are allowed, counting multiple packages as parts of single CPUs.

The issue was discovered with @simonintense, who can provide more information about his system if necessary. There are both OpenCore log and configuration in acidanthera/bugtracker#1625 (comment).

@vit9696 vit9696 added the bug Something isn't working label May 5, 2021
@trulyspinach
Copy link

trulyspinach commented Jul 29, 2021

I’ve noticed this a while ago when writing the power management kext. If I remembered correct, XNU use APIC ID to generate the topology map. However, according to AMD’s documents and some of my experimentations they have non-continuous APIC ID unlike Intel’s, resulting in the incorrect map generated by XNU.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

2 participants