diff options
Diffstat (limited to 'sys/x86')
| -rw-r--r-- | sys/x86/acpica/acpi_apm.c | 1 | ||||
| -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 | 
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++) | 
