diff options
Diffstat (limited to 'sys/x86')
| -rw-r--r-- | sys/x86/conf/NOTES | 1 | ||||
| -rw-r--r-- | sys/x86/include/apicvar.h | 3 | ||||
| -rw-r--r-- | sys/x86/include/intr_machdep.h | 1 | ||||
| -rw-r--r-- | sys/x86/include/x86_smp.h | 2 | ||||
| -rw-r--r-- | sys/x86/iommu/amd_intrmap.c | 9 | ||||
| -rw-r--r-- | sys/x86/x86/intr_machdep.c | 20 | ||||
| -rw-r--r-- | sys/x86/x86/local_apic.c | 9 | ||||
| -rw-r--r-- | sys/x86/x86/mp_x86.c | 22 | ||||
| -rw-r--r-- | sys/x86/x86/msi.c | 8 |
9 files changed, 65 insertions, 10 deletions
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++) |
