#ifdef CONFIG_NUMA /* * To workaround broken NUMA config. Read the comment in * srat_detect_node().
*/ staticint nearby_node(int apicid)
{ int i, node;
for (i = apicid - 1; i >= 0; i--) {
node = __apicid_to_node[i]; if (node != NUMA_NO_NODE && node_online(node)) return node;
} for (i = apicid + 1; i < MAX_LOCAL_APIC; i++) {
node = __apicid_to_node[i]; if (node != NUMA_NO_NODE && node_online(node)) return node;
} return first_node(node_online_map); /* Shouldn't happen */
} #endif
staticvoid srat_detect_node(struct cpuinfo_x86 *c)
{ #ifdef CONFIG_NUMA int cpu = smp_processor_id(); int node; unsignedint apicid = c->topo.apicid;
node = numa_cpu_node(cpu); if (node == NUMA_NO_NODE)
node = c->topo.llc_id;
/* * On multi-fabric platform (e.g. Numascale NumaChip) a * platform-specific handler needs to be called to fixup some * IDs of the CPU.
*/ if (x86_cpuinit.fixup_cpu_id)
x86_cpuinit.fixup_cpu_id(c, node);
if (!node_online(node)) { /* * Two possibilities here: * * - The CPU is missing memory and no node was created. In * that case try picking one from a nearby CPU. * * - The APIC IDs differ from the HyperTransport node IDs. * Assume they are all increased by a constant offset, but * in the same order as the HT nodeids. If that doesn't * result in a usable node fall back to the path for the * previous case. * * This workaround operates directly on the mapping between * APIC ID and NUMA node, assuming certain relationship * between APIC ID, HT node ID and NUMA topology. As going * through CPU mapping may alter the outcome, directly * access __apicid_to_node[].
*/ int ht_nodeid = c->topo.initial_apicid;
if (__apicid_to_node[ht_nodeid] != NUMA_NO_NODE)
node = __apicid_to_node[ht_nodeid]; /* Pick a nearby node */ if (!node_online(node))
node = nearby_node(apicid);
}
numa_set_node(cpu, node); #endif
}
rdmsrq(MSR_K7_HWCR, val); if (!(val & BIT(24)))
pr_warn(FW_BUG "TSC doesn't count with P0 frequency!\n");
}
if (cpu_has(c, X86_FEATURE_MWAITX))
use_mwaitx_delay();
if (!boot_cpu_has(X86_FEATURE_AMD_SSBD) &&
!boot_cpu_has(X86_FEATURE_VIRT_SSBD)) { /* * Try to cache the base value so further operations can * avoid RMW. If that faults, do not enable SSBD.
*/ if (!rdmsrq_safe(MSR_AMD64_LS_CFG, &x86_amd_ls_cfg_base)) {
setup_force_cpu_cap(X86_FEATURE_LS_CFG_SSBD);
setup_force_cpu_cap(X86_FEATURE_SSBD);
x86_amd_ls_cfg_ssbd_mask = 1ULL << 10;
}
}
/* * c->x86_power is 8000_0007 edx. Bit 8 is TSC runs at constant rate * with P/T states and does not stop in deep C-states
*/ if (c->x86_power & (1 << 8)) {
set_cpu_cap(c, X86_FEATURE_CONSTANT_TSC);
set_cpu_cap(c, X86_FEATURE_NONSTOP_TSC);
}
/* Bit 12 of 8000_0007 edx is accumulated power mechanism. */ if (c->x86_power & BIT(12))
set_cpu_cap(c, X86_FEATURE_ACC_POWER);
/* Bit 14 indicates the Runtime Average Power Limit interface. */ if (c->x86_power & BIT(14))
set_cpu_cap(c, X86_FEATURE_RAPL);
#ifdefined(CONFIG_X86_LOCAL_APIC) && defined(CONFIG_PCI) /* * ApicID can always be treated as an 8-bit value for Hygon APIC So, we * can safely set X86_FEATURE_EXTD_APICID unconditionally.
*/ if (boot_cpu_has(X86_FEATURE_APIC))
set_cpu_cap(c, X86_FEATURE_EXTD_APICID); #endif
/* * This is only needed to tell the kernel whether to use VMCALL * and VMMCALL. VMMCALL is never executed except under virt, so * we can set it unconditionally.
*/
set_cpu_cap(c, X86_FEATURE_VMMCALL);
}
if (cpu_has(c, X86_FEATURE_SVM)) {
rdmsrq(MSR_VM_CR, vm_cr); if (vm_cr & SVM_VM_CR_SVM_DIS_MASK) {
pr_notice_once("SVM disabled (by BIOS) in MSR_VM_CR\n");
clear_cpu_cap(c, X86_FEATURE_SVM);
}
}
if (cpu_has(c, X86_FEATURE_XMM2)) { /* * Use LFENCE for execution serialization. On families which * don't have that MSR, LFENCE is already serializing. * msr_set_bit() uses the safe accessors, too, even if the MSR * is not present.
*/
msr_set_bit(MSR_AMD64_DE_CFG,
MSR_AMD64_DE_CFG_LFENCE_SERIALIZE_BIT);
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.