aboutsummaryrefslogtreecommitdiff
path: root/sys/x86
diff options
context:
space:
mode:
Diffstat (limited to 'sys/x86')
-rw-r--r--sys/x86/acpica/acpi_apm.c1
-rw-r--r--sys/x86/conf/NOTES1
-rw-r--r--sys/x86/include/apicvar.h3
-rw-r--r--sys/x86/include/intr_machdep.h1
-rw-r--r--sys/x86/include/x86_smp.h2
-rw-r--r--sys/x86/iommu/amd_intrmap.c9
-rw-r--r--sys/x86/x86/intr_machdep.c20
-rw-r--r--sys/x86/x86/local_apic.c9
-rw-r--r--sys/x86/x86/mp_x86.c22
-rw-r--r--sys/x86/x86/msi.c8
10 files changed, 66 insertions, 10 deletions
diff --git a/sys/x86/acpica/acpi_apm.c b/sys/x86/acpica/acpi_apm.c
index 8e5785cf0ed6..919f76949dd4 100644
--- a/sys/x86/acpica/acpi_apm.c
+++ b/sys/x86/acpica/acpi_apm.c
@@ -64,6 +64,7 @@ static const struct filterops apm_readfiltops = {
.f_isfd = 1,
.f_detach = apmreadfiltdetach,
.f_event = apmreadfilt,
+ .f_copy = knote_triv_copy,
};
static struct cdevsw apm_cdevsw = {
diff --git a/sys/x86/conf/NOTES b/sys/x86/conf/NOTES
index 3b3439b519d7..fadaf90d508f 100644
--- a/sys/x86/conf/NOTES
+++ b/sys/x86/conf/NOTES
@@ -541,7 +541,6 @@ device smbios
device vpd
device asmc
device tpm
-device padlock_rng # VIA Padlock RNG
device rdrand_rng # Intel Bull Mountain RNG
device aesni # AES-NI OpenCrypto module
device ossl # OpenSSL OpenCrypto module
diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h
index c537d0ee0cdd..551f5527ac00 100644
--- a/sys/x86/include/apicvar.h
+++ b/sys/x86/include/apicvar.h
@@ -134,7 +134,8 @@
#define IPI_STOP (APIC_IPI_INTS + 6) /* Stop CPU until restarted. */
#define IPI_SUSPEND (APIC_IPI_INTS + 7) /* Suspend CPU until restarted. */
#define IPI_SWI (APIC_IPI_INTS + 8) /* Run clk_intr_event. */
-#define IPI_DYN_FIRST (APIC_IPI_INTS + 9)
+#define IPI_OFF (APIC_IPI_INTS + 9) /* Stop CPU forever */
+#define IPI_DYN_FIRST (APIC_IPI_INTS + 10)
#define IPI_DYN_LAST (254) /* IPIs allocated at runtime */
/*
diff --git a/sys/x86/include/intr_machdep.h b/sys/x86/include/intr_machdep.h
index 9e913440c712..497c89b0a7eb 100644
--- a/sys/x86/include/intr_machdep.h
+++ b/sys/x86/include/intr_machdep.h
@@ -142,6 +142,7 @@ int intr_add_handler(struct intsrc *isrc, const char *name,
int intr_config_intr(struct intsrc *isrc, enum intr_trigger trig,
enum intr_polarity pol);
int intr_describe(struct intsrc *isrc, void *ih, const char *descr);
+void intr_disable_all(void);
void intr_execute_handlers(struct intsrc *isrc, struct trapframe *frame);
u_int intr_next_cpu(int domain);
struct intsrc *intr_lookup_source(int vector);
diff --git a/sys/x86/include/x86_smp.h b/sys/x86/include/x86_smp.h
index 8b9eb2ec9b66..f5015e9d8a24 100644
--- a/sys/x86/include/x86_smp.h
+++ b/sys/x86/include/x86_smp.h
@@ -77,6 +77,7 @@ extern u_long *ipi_rendezvous_counts[MAXCPU];
inthand_t
IDTVEC(ipi_intr_bitmap_handler), /* Bitmap based IPIs */
IDTVEC(ipi_swi), /* Runs delayed SWI */
+ IDTVEC(cpuoff), /* CPU goes offline until hard reset */
IDTVEC(cpustop), /* CPU stops & waits to be restarted */
IDTVEC(cpususpend), /* CPU suspends & waits to be resumed */
IDTVEC(rendezvous); /* handle CPU rendezvous */
@@ -93,6 +94,7 @@ void assign_cpu_ids(void);
void cpu_add(u_int apic_id, char boot_cpu);
void cpustop_handler(void);
void cpususpend_handler(void);
+void cpuoff_handler(void);
void init_secondary_tail(void);
void init_secondary(void);
void ipi_startup(int apic_id, int vector);
diff --git a/sys/x86/iommu/amd_intrmap.c b/sys/x86/iommu/amd_intrmap.c
index f8900fe0561f..cce4f57ca323 100644
--- a/sys/x86/iommu/amd_intrmap.c
+++ b/sys/x86/iommu/amd_intrmap.c
@@ -223,9 +223,9 @@ static struct amdiommu_ctx *
amdiommu_ir_find(device_t src, uint16_t *ridp, bool *is_iommu)
{
devclass_t src_class;
- device_t requester;
struct amdiommu_unit *unit;
struct amdiommu_ctx *ctx;
+ struct iommu_ctx *ioctx;
uint32_t edte;
uint16_t rid;
uint8_t dte;
@@ -255,10 +255,9 @@ amdiommu_ir_find(device_t src, uint16_t *ridp, bool *is_iommu)
error = amdiommu_find_unit(src, &unit, &rid, &dte, &edte,
bootverbose);
if (error == 0) {
- error = iommu_get_requester(src, &requester, &rid);
- MPASS(error == 0);
- ctx = amdiommu_get_ctx_for_dev(unit, src,
- rid, 0, false /* XXXKIB */, false, dte, edte);
+ ioctx = iommu_instantiate_ctx(AMD2IOMMU(unit), src, false);
+ if (ioctx != NULL)
+ ctx = IOCTX2CTX(ioctx);
}
}
if (ridp != NULL)
diff --git a/sys/x86/x86/intr_machdep.c b/sys/x86/x86/intr_machdep.c
index 023c3df22580..a16d2ced8dba 100644
--- a/sys/x86/x86/intr_machdep.c
+++ b/sys/x86/x86/intr_machdep.c
@@ -245,6 +245,26 @@ intr_register_source(struct intsrc *isrc)
return (0);
}
+void
+intr_disable_all(void)
+{
+ /*
+ * Disable all external interrupts. This is used by kexec_reboot() to
+ * prevent problems on the other side when APs are brought up.
+ */
+ for (int v = 0; v < num_io_irqs; v++) {
+ struct intsrc *is;
+
+ is = interrupt_sources[v];
+ if (is == NULL)
+ continue;
+ if (is->is_pic->pic_disable_intr != NULL) {
+ is->is_pic->pic_disable_source(is, PIC_EOI);
+ is->is_pic->pic_disable_intr(is);
+ }
+ }
+}
+
struct intsrc *
intr_lookup_source(int vector)
{
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index db9a1eb757de..c1c9029531f5 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -372,9 +372,12 @@ lvt_mode_impl(struct lapic *la, struct lvt *lvt, u_int pin, uint32_t value)
case APIC_LVT_DM_SMI:
case APIC_LVT_DM_INIT:
case APIC_LVT_DM_EXTINT:
- if (!lvt->lvt_edgetrigger && bootverbose) {
- printf("lapic%u: Forcing LINT%u to edge trigger\n",
- la->la_id, pin);
+ if (!lvt->lvt_edgetrigger) {
+ if (bootverbose) {
+ printf(
+ "lapic%u: Forcing LINT%u to edge trigger\n",
+ la->la_id, pin);
+ }
value &= ~APIC_LVT_TM;
}
/* Use a vector of 0. */
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
index c0da41a4d222..6b1715853763 100644
--- a/sys/x86/x86/mp_x86.c
+++ b/sys/x86/x86/mp_x86.c
@@ -1696,6 +1696,28 @@ cpususpend_handler(void)
CPU_CLR_ATOMIC(cpu, &toresume_cpus);
}
+void
+cpuoff_handler(void)
+{
+ u_int cpu;
+
+ cpu = PCPU_GET(cpuid);
+
+ /* Time to go catatonic. A reset will be required to leave. */
+ disable_intr();
+ lapic_disable();
+ CPU_SET_ATOMIC(cpu, &suspended_cpus);
+
+ /*
+ * There technically should be no need for the `while` here, since it
+ * cannot be interrupted (interrupts are disabled). Be safe anyway.
+ * Any interrupt at this point will likely be fatal, as the page tables
+ * are likely going away shortly.
+ */
+ while (1)
+ halt();
+}
+
/*
* Handle an IPI_SWI by waking delayed SWI thread.
*/
diff --git a/sys/x86/x86/msi.c b/sys/x86/x86/msi.c
index 9d5a51f9753c..b38247bf6e45 100644
--- a/sys/x86/x86/msi.c
+++ b/sys/x86/x86/msi.c
@@ -219,6 +219,14 @@ msi_disable_intr(struct intsrc *isrc)
struct msi_intsrc *msi = (struct msi_intsrc *)isrc;
msi = msi->msi_first;
+
+ /*
+ * Interrupt sources are always registered, but never unregistered.
+ * Handle the case where MSIs have all been unregistered.
+ */
+ if (msi == NULL)
+ return;
+
msi->msi_enabled--;
if (msi->msi_enabled == 0) {
for (u_int i = 0; i < msi->msi_count; i++)