aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorEd Maste <emaste@FreeBSD.org>2023-08-18 03:39:08 +0000
committerEd Maste <emaste@FreeBSD.org>2023-08-29 17:25:30 +0000
commit0b029e9e85943d565c72aa58353538aeac68aa36 (patch)
tree9b052d44c466f94255b95953e79e2c08564f27fb /sys
parent09c45b089d2f90ec04153a1b4621dd6bec142959 (diff)
downloadsrc-0b029e9e85943d565c72aa58353538aeac68aa36.tar.gz
src-0b029e9e85943d565c72aa58353538aeac68aa36.zip
Diffstat (limited to 'sys')
-rw-r--r--sys/x86/x86/mp_x86.c23
1 files changed, 23 insertions, 0 deletions
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
index 76a1d14f371a..ddcb54b63d88 100644
--- a/sys/x86/x86/mp_x86.c
+++ b/sys/x86/x86/mp_x86.c
@@ -153,6 +153,11 @@ SYSCTL_INT(_machdep, OID_AUTO, hyperthreading_intr_allowed, CTLFLAG_RDTUN,
&hyperthreading_intr_allowed, 0,
"Allow interrupts on HTT logical CPUs");
+static int intr_apic_id_limit = -1;
+SYSCTL_INT(_machdep, OID_AUTO, intr_apic_id_limit, CTLFLAG_RDTUN,
+ &intr_apic_id_limit, 0,
+ "Maximum permitted APIC ID for interrupt delivery (-1 is unlimited)");
+
static struct topo_node topo_root;
static int pkg_id_shift;
@@ -258,6 +263,22 @@ topo_probe_amd(void)
if ((amd_feature2 & AMDID2_CMP) == 0)
return;
+ /*
+ * XXX Lack of an AMD IOMMU driver prevents use of APIC IDs above
+ * xAPIC_MAX_APIC_ID. This is a workaround so we boot and function on
+ * AMD systems with high thread counts, albeit with reduced interrupt
+ * performance.
+ *
+ * We should really set the limit to xAPIC_MAX_APIC_ID by default, and
+ * have the IOMMU driver increase it. That way if a driver is present
+ * but disabled, or is otherwise not able to route the interrupts, the
+ * system can fall back to a functional state. That will require a more
+ * substantial change though, including having the IOMMU initialize
+ * earlier.
+ */
+ if (intr_apic_id_limit == -1)
+ intr_apic_id_limit = xAPIC_MAX_APIC_ID;
+
/* For families 10h and newer. */
pkg_id_shift = (cpu_procinfo2 & AMDID_COREID_SIZE) >>
AMDID_COREID_SIZE_SHIFT;
@@ -1170,6 +1191,8 @@ set_interrupt_apic_ids(void)
continue;
if (cpu_info[apic_id].cpu_disabled)
continue;
+ if (intr_apic_id_limit >= 0 && apic_id > intr_apic_id_limit)
+ continue;
/* Don't let hyperthreads service interrupts. */
if (cpu_info[apic_id].cpu_hyperthread &&