diff --git a/docs/misc/xen-command-line.pandoc b/docs/misc/xen-command-line.pandoc index a03c0b4bdf..ab853bda12 100644 --- a/docs/misc/xen-command-line.pandoc +++ b/docs/misc/xen-command-line.pandoc @@ -1172,7 +1172,7 @@ detection of systems known to misbehave upon accesses to that port. ### iommu = List of [ , verbose, debug, force, required, - sharept, intremap, intpost, + sharept, intremap, intpost, crash-disable, snoop, qinval, igfx, workaround_bios_bug, amd-iommu-perdev-intremap, dom0-{passthrough,strict} ] @@ -1235,6 +1235,12 @@ boolean (e.g. `iommu=no`) can override this and leave the IOMMUs disabled. This option depends on `intremap`, and is disabled by default due to some corner cases in the implementation which have yet to be resolved. +* The `crash-disable` boolean controls disabling IOMMU functionality (DMAR/IR/QI) + before switching to a crash kernel. This option is inactive by default and + is for compatibility with older kdump kernels only. Modern kernels copy + all the necessary tables from the previous one following kexec which makes + the transition transparent for them with IOMMU functions still on. + The following options are specific to Intel VT-d hardware: * The `snoop` boolean controls the Snoop Control sub-feature, and is active diff --git a/xen/arch/x86/crash.c b/xen/arch/x86/crash.c index 60c98b6175..01e48a1133 100644 --- a/xen/arch/x86/crash.c +++ b/xen/arch/x86/crash.c @@ -162,8 +162,11 @@ static void nmi_shootdown_cpus(void) printk("Failed to shoot down CPUs {%*pbl}\n", nr_cpu_ids, cpumask_bits(&waiting_to_crash)); - /* Crash shutdown any IOMMU functionality as the crashdump kernel is not - * happy when booting if interrupt/dma remapping is still enabled */ + /* + * Try to crash shutdown IOMMU functionality as some old crashdump + * kernels are not happy when booting if interrupt/dma remapping + * is still enabled. + */ iommu_crash_shutdown(); __stop_this_cpu(); diff --git a/xen/drivers/passthrough/iommu.c b/xen/drivers/passthrough/iommu.c index 5ecaa10bb4..611e857259 100644 --- a/xen/drivers/passthrough/iommu.c +++ b/xen/drivers/passthrough/iommu.c @@ -35,6 +35,7 @@ bool_t __read_mostly iommu_igfx = 1; bool_t __read_mostly iommu_snoop = 1; bool_t __read_mostly iommu_qinval = 1; bool_t __read_mostly iommu_intremap = 1; +bool_t __read_mostly iommu_crash_disable; static bool __hwdom_initdata iommu_hwdom_none; bool __hwdom_initdata iommu_hwdom_strict; @@ -88,6 +89,10 @@ static int __init parse_iommu_param(const char *s) iommu_intremap = val; else if ( (val = parse_boolean("intpost", s, ss)) >= 0 ) iommu_intpost = val; +#ifdef CONFIG_KEXEC + else if ( (val = parse_boolean("crash-disable", s, ss)) >= 0 ) + iommu_crash_disable = val; +#endif else if ( (val = parse_boolean("debug", s, ss)) >= 0 ) { iommu_debug = val; @@ -579,6 +584,9 @@ void iommu_share_p2m_table(struct domain* d) void iommu_crash_shutdown(void) { + if ( !iommu_crash_disable ) + return; + if ( iommu_enabled ) iommu_get_ops()->crash_shutdown(); iommu_enabled = iommu_intremap = iommu_intpost = 0;