Page MenuHomeFreeBSD

D35899.id133336.diff
No OneTemporary

D35899.id133336.diff

diff --git a/sys/arm/arm/gic_acpi.c b/sys/arm/arm/gic_acpi.c
--- a/sys/arm/arm/gic_acpi.c
+++ b/sys/arm/arm/gic_acpi.c
@@ -232,6 +232,14 @@
intr_pic_deregister(dev, xref);
goto cleanup;
}
+
+#ifdef SMP
+ if (intr_ipi_pic_register(dev, 0) != 0) {
+ device_printf(dev, "could not register for IPIs\n");
+ goto cleanup;
+ }
+#endif
+
/* If we have children probe and attach them */
if (arm_gic_add_children(dev)) {
bus_generic_probe(dev);
diff --git a/sys/arm/arm/gic_fdt.c b/sys/arm/arm/gic_fdt.c
--- a/sys/arm/arm/gic_fdt.c
+++ b/sys/arm/arm/gic_fdt.c
@@ -158,6 +158,13 @@
intr_pic_deregister(dev, xref);
goto cleanup;
}
+
+#ifdef SMP
+ if (intr_ipi_pic_register(dev, 0) != 0) {
+ device_printf(dev, "could not register for IPIs\n");
+ goto cleanup;
+ }
+#endif
} else {
if (sc->base.gic_res[2] == NULL) {
device_printf(dev,
diff --git a/sys/arm/broadcom/bcm2835/bcm2836.c b/sys/arm/broadcom/bcm2835/bcm2836.c
--- a/sys/arm/broadcom/bcm2835/bcm2836.c
+++ b/sys/arm/broadcom/bcm2835/bcm2836.c
@@ -646,7 +646,17 @@
if (pic == NULL)
return (ENXIO);
- return (intr_pic_claim_root(sc->bls_dev, xref, bcm_lintc_intr, sc));
+ error = intr_pic_claim_root(sc->bls_dev, xref, bcm_lintc_intr, sc);
+ if (error != 0)
+ return (error);
+
+#ifdef SMP
+ error = intr_ipi_pic_register(sc->bls_dev, 0);
+ if (error != 0)
+ return (error);
+#endif
+
+ return (0);
}
static int
diff --git a/sys/arm64/arm64/gic_v3_acpi.c b/sys/arm64/arm64/gic_v3_acpi.c
--- a/sys/arm64/arm64/gic_v3_acpi.c
+++ b/sys/arm64/arm64/gic_v3_acpi.c
@@ -351,6 +351,14 @@
goto error;
}
+#ifdef SMP
+ err = intr_ipi_pic_register(dev, 0);
+ if (err != 0) {
+ device_printf(dev, "could not register for IPIs\n");
+ goto error;
+ }
+#endif
+
/*
* Try to register the ITS driver to this GIC. The GIC will act as
* a bus in that case. Failure here will not affect the main GIC
diff --git a/sys/arm64/arm64/gic_v3_fdt.c b/sys/arm64/arm64/gic_v3_fdt.c
--- a/sys/arm64/arm64/gic_v3_fdt.c
+++ b/sys/arm64/arm64/gic_v3_fdt.c
@@ -166,6 +166,14 @@
goto error;
}
+#ifdef SMP
+ err = intr_ipi_pic_register(dev, 0);
+ if (err != 0) {
+ device_printf(dev, "could not register for IPIs\n");
+ goto error;
+ }
+#endif
+
/*
* Try to register ITS to this GIC.
* GIC will act as a bus in that case.
diff --git a/sys/kern/subr_intr.c b/sys/kern/subr_intr.c
--- a/sys/kern/subr_intr.c
+++ b/sys/kern/subr_intr.c
@@ -139,6 +139,10 @@
char ii_name[INTR_IPI_NAMELEN];
u_long *ii_count;
};
+
+static device_t intr_ipi_dev;
+static u_int intr_ipi_dev_priority;
+static bool intr_ipi_dev_frozen;
#endif
static struct mtx pic_list_lock;
@@ -380,7 +384,8 @@
KASSERT(isrc != NULL, ("%s: no source", __func__));
- isrc_increment_count(isrc);
+ if ((isrc->isrc_flags & INTR_ISRCF_IPI) == 0)
+ isrc_increment_count(isrc);
#ifdef INTR_SOLO
if (isrc->isrc_filter != NULL) {
@@ -396,7 +401,8 @@
return (0);
}
- isrc_increment_straycount(isrc);
+ if ((isrc->isrc_flags & INTR_ISRCF_IPI) == 0)
+ isrc_increment_straycount(isrc);
return (EINVAL);
}
@@ -1815,6 +1821,20 @@
return (&ipi_sources[ipi]);
}
+int
+intr_ipi_pic_register(device_t dev, u_int priority)
+{
+ if (intr_ipi_dev_frozen) {
+ device_printf(dev, "IPI device already frozen");
+ return (EBUSY);
+ }
+
+ if (intr_ipi_dev == NULL || priority > intr_ipi_dev_priority)
+ intr_ipi_dev = dev;
+
+ return (0);
+}
+
/*
* Setup IPI handler on interrupt controller.
*
@@ -1828,10 +1848,17 @@
struct intr_ipi *ii;
int error;
- KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__));
+ if (!intr_ipi_dev_frozen) {
+ if (intr_ipi_dev == NULL)
+ panic("%s: no IPI PIC attached", __func__);
+
+ intr_ipi_dev_frozen = true;
+ device_printf(intr_ipi_dev, "using for IPIs\n");
+ }
+
KASSERT(hand != NULL, ("%s: ipi %u no handler", __func__, ipi));
- error = PIC_IPI_SETUP(intr_irq_root_dev, ipi, &isrc);
+ error = PIC_IPI_SETUP(intr_ipi_dev, ipi, &isrc);
if (error != 0)
return;
@@ -1846,7 +1873,7 @@
strlcpy(ii->ii_name, name, INTR_IPI_NAMELEN);
ii->ii_count = intr_ipi_setup_counters(name);
- PIC_ENABLE_INTR(intr_irq_root_dev, isrc);
+ PIC_ENABLE_INTR(intr_ipi_dev, isrc);
}
void
@@ -1854,7 +1881,8 @@
{
struct intr_ipi *ii;
- KASSERT(intr_irq_root_dev != NULL, ("%s: no root attached", __func__));
+ KASSERT(intr_ipi_dev_frozen,
+ ("%s: IPI device not yet frozen", __func__));
ii = intr_ipi_lookup(ipi);
if (ii->ii_count == NULL)
@@ -1873,7 +1901,7 @@
dsb(ishst);
#endif
- PIC_IPI_SEND(intr_irq_root_dev, ii->ii_isrc, cpus, ipi);
+ PIC_IPI_SEND(intr_ipi_dev, ii->ii_isrc, cpus, ipi);
}
/*
diff --git a/sys/sys/intr.h b/sys/sys/intr.h
--- a/sys/sys/intr.h
+++ b/sys/sys/intr.h
@@ -156,6 +156,7 @@
#ifdef SMP
typedef void intr_ipi_handler_t(void *);
+int intr_ipi_pic_register(device_t dev, u_int priority);
void intr_ipi_setup(u_int ipi, const char *name, intr_ipi_handler_t *hand,
void *arg);
void intr_ipi_send(cpuset_t cpus, u_int ipi);

File Metadata

Mime Type
text/plain
Expires
Sun, Apr 19, 8:44 AM (16 h, 59 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31751955
Default Alt Text
D35899.id133336.diff (4 KB)

Event Timeline