Changeset View
Changeset View
Standalone View
Standalone View
sys/amd64/vmm/x86.c
Context not available. | |||||
SYSCTL_ULONG(_hw_vmm, OID_AUTO, bhyve_xcpuids, CTLFLAG_RW, &bhyve_xcpuids, 0, | SYSCTL_ULONG(_hw_vmm, OID_AUTO, bhyve_xcpuids, CTLFLAG_RW, &bhyve_xcpuids, 0, | ||||
"Number of times an unknown cpuid leaf was accessed"); | "Number of times an unknown cpuid leaf was accessed"); | ||||
/* | #if __FreeBSD_version < 1200060 /* Remove after 11 EOL helps MFCing */ | ||||
* The default CPU topology is a single thread per package. | extern u_int threads_per_core; | ||||
grehan: I think this can be deleted. There weren't large numbers of users of this due to it being… | |||||
Done Inline ActionsI am leaving this here for now to simplify merging to stable/11. rgrimes: I am leaving this here for now to simplify merging to stable/11.
I'll write another… | |||||
*/ | |||||
static u_int threads_per_core = 1; | |||||
SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, threads_per_core, CTLFLAG_RDTUN, | SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, threads_per_core, CTLFLAG_RDTUN, | ||||
&threads_per_core, 0, NULL); | &threads_per_core, 0, NULL); | ||||
static u_int cores_per_package = 1; | extern u_int cores_per_package; | ||||
SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, cores_per_package, CTLFLAG_RDTUN, | SYSCTL_UINT(_hw_vmm_topology, OID_AUTO, cores_per_package, CTLFLAG_RDTUN, | ||||
&cores_per_package, 0, NULL); | &cores_per_package, 0, NULL); | ||||
#endif | |||||
static int cpuid_leaf_b = 1; | static int cpuid_leaf_b = 1; | ||||
SYSCTL_INT(_hw_vmm_topology, OID_AUTO, cpuid_leaf_b, CTLFLAG_RDTUN, | SYSCTL_INT(_hw_vmm_topology, OID_AUTO, cpuid_leaf_b, CTLFLAG_RDTUN, | ||||
Context not available. | |||||
int error, enable_invpcid, level, width, x2apic_id; | int error, enable_invpcid, level, width, x2apic_id; | ||||
Done Inline Actionscores/cpus/sockets/threads should be uint16_t grehan: cores/cpus/sockets/threads should be uint16_t | |||||
unsigned int func, regs[4], logical_cpus; | unsigned int func, regs[4], logical_cpus; | ||||
enum x2apic_state x2apic_state; | enum x2apic_state x2apic_state; | ||||
uint16_t cores, maxcpus, sockets, threads; | |||||
VCPU_CTR2(vm, vcpu_id, "cpuid %#x,%#x", *eax, *ecx); | VCPU_CTR2(vm, vcpu_id, "cpuid %#x,%#x", *eax, *ecx); | ||||
Context not available. | |||||
* | * | ||||
* However this matches the logical cpus as | * However this matches the logical cpus as | ||||
* advertised by leaf 0x1 and will work even | * advertised by leaf 0x1 and will work even | ||||
* if the 'threads_per_core' tunable is set | * if threads is set incorrectly on an AMD host. | ||||
* incorrectly on an AMD host. | |||||
*/ | */ | ||||
logical_cpus = threads_per_core * | vm_get_topology(vm, &sockets, &cores, &threads, | ||||
cores_per_package; | &maxcpus); | ||||
logical_cpus = threads * cores; | |||||
regs[2] = logical_cpus - 1; | regs[2] = logical_cpus - 1; | ||||
} | } | ||||
break; | break; | ||||
Context not available. | |||||
*/ | */ | ||||
regs[3] |= (CPUID_MCA | CPUID_MCE | CPUID_MTRR); | regs[3] |= (CPUID_MCA | CPUID_MCE | CPUID_MTRR); | ||||
logical_cpus = threads_per_core * cores_per_package; | vm_get_topology(vm, &sockets, &cores, &threads, | ||||
&maxcpus); | |||||
logical_cpus = threads * cores; | |||||
regs[1] &= ~CPUID_HTT_CORES; | regs[1] &= ~CPUID_HTT_CORES; | ||||
regs[1] |= (logical_cpus & 0xff) << 16; | regs[1] |= (logical_cpus & 0xff) << 16; | ||||
regs[3] |= CPUID_HTT; | regs[3] |= CPUID_HTT; | ||||
Context not available. | |||||
cpuid_count(*eax, *ecx, regs); | cpuid_count(*eax, *ecx, regs); | ||||
if (regs[0] || regs[1] || regs[2] || regs[3]) { | if (regs[0] || regs[1] || regs[2] || regs[3]) { | ||||
vm_get_topology(vm, &sockets, &cores, &threads, | |||||
&maxcpus); | |||||
regs[0] &= 0x3ff; | regs[0] &= 0x3ff; | ||||
regs[0] |= (cores_per_package - 1) << 26; | regs[0] |= (cores - 1) << 26; | ||||
/* | /* | ||||
* Cache topology: | * Cache topology: | ||||
* - L1 and L2 are shared only by the logical | * - L1 and L2 are shared only by the logical | ||||
Context not available. | |||||
* - L3 and above are shared by all logical | * - L3 and above are shared by all logical | ||||
* processors in the package. | * processors in the package. | ||||
*/ | */ | ||||
logical_cpus = threads_per_core; | logical_cpus = threads; | ||||
level = (regs[0] >> 5) & 0x7; | level = (regs[0] >> 5) & 0x7; | ||||
if (level >= 3) | if (level >= 3) | ||||
logical_cpus *= cores_per_package; | logical_cpus *= cores; | ||||
regs[0] |= (logical_cpus - 1) << 14; | regs[0] |= (logical_cpus - 1) << 14; | ||||
} | } | ||||
break; | break; | ||||
Context not available. | |||||
/* | /* | ||||
* Processor topology enumeration | * Processor topology enumeration | ||||
*/ | */ | ||||
vm_get_topology(vm, &sockets, &cores, &threads, | |||||
&maxcpus); | |||||
if (*ecx == 0) { | if (*ecx == 0) { | ||||
logical_cpus = threads_per_core; | logical_cpus = threads; | ||||
width = log2(logical_cpus); | width = log2(logical_cpus); | ||||
Done Inline ActionsThis call needs to be moved before the if, otherwise sockets, cores and threads are used unitialized in the other cases of *ecx. rgrimes: This call needs to be moved before the if, otherwise sockets, cores and threads are used… | |||||
level = CPUID_TYPE_SMT; | level = CPUID_TYPE_SMT; | ||||
x2apic_id = vcpu_id; | x2apic_id = vcpu_id; | ||||
Context not available. | |||||
} | } | ||||
if (*ecx == 1) { | if (*ecx == 1) { | ||||
logical_cpus = threads_per_core * | logical_cpus = threads * cores; | ||||
cores_per_package; | |||||
width = log2(logical_cpus); | width = log2(logical_cpus); | ||||
level = CPUID_TYPE_CORE; | level = CPUID_TYPE_CORE; | ||||
x2apic_id = vcpu_id; | x2apic_id = vcpu_id; | ||||
Context not available. |
I think this can be deleted. There weren't large numbers of users of this due to it being global, and the bhyve parameters are much better to use.