aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTerry Loftin <terry.loftin@hp.com>2007-07-12 19:23:22 -0400
committerTony Luck <tony.luck@intel.com>2007-07-13 12:16:50 -0400
commit51b58e3e26ebfb8cd56825c4b396ed251f51dec9 (patch)
tree13e04ced4a61562a7c4a0ade7b453fa4e24a6753
parent773208946a132fb733ba273ee8562814f828cc28 (diff)
[IA64] use machvec=dig on hpzx1 platforms
On HP zx1 machines, the 'machvec=dig' parameter is needed for the kdump kernel to avoid problems with the HP sba iommu. The problem is that during the boot of the kdump kernel, the iommu is re-initialized, so in-flight DMA from improperly shutdown drivers causes an IOTLB miss which leads to an MCA. With kdump, the idea is to get into the kdump kernel with as little code as we can, so shutting down drivers properly is not an option. The workaround is to add 'machvec=dig' to the kdump kernel boot parameters. This makes the kdump kernel avoid using the sba iommu altogether, leaving the IOTLB intact. Any ongoing DMA falls harmlessly outside the kdump kernel. After the kdump kernel reboots, all devices will have been shutdown properly and DMA stopped. This patch pushes that functionality into the sba iommu initialization code, so that users won't have to find the obscure documentation telling them about 'machvec=dig'. This patch only affects HP platforms. It still includes one extern declaration in the file, because no applicable header file exists. Signed-off-by: Terry Loftin <terry.loftin@hp.com> Signed-off-by: Alex Williamson <alex.williamson@hp.com> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--arch/ia64/hp/common/sba_iommu.c20
1 files changed, 18 insertions, 2 deletions
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index c1dca226b479..cd4adf52f174 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -34,6 +34,7 @@
34#include <linux/efi.h> 34#include <linux/efi.h>
35#include <linux/nodemask.h> 35#include <linux/nodemask.h>
36#include <linux/bitops.h> /* hweight64() */ 36#include <linux/bitops.h> /* hweight64() */
37#include <linux/crash_dump.h>
37 38
38#include <asm/delay.h> /* ia64_get_itc() */ 39#include <asm/delay.h> /* ia64_get_itc() */
39#include <asm/io.h> 40#include <asm/io.h>
@@ -43,6 +44,8 @@
43 44
44#include <asm/acpi-ext.h> 45#include <asm/acpi-ext.h>
45 46
47extern int swiotlb_late_init_with_default_size (size_t size);
48
46#define PFX "IOC: " 49#define PFX "IOC: "
47 50
48/* 51/*
@@ -2026,11 +2029,24 @@ sba_init(void)
2026 if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb")) 2029 if (!ia64_platform_is("hpzx1") && !ia64_platform_is("hpzx1_swiotlb"))
2027 return 0; 2030 return 0;
2028 2031
2032#if defined(CONFIG_IA64_GENERIC) && defined(CONFIG_CRASH_DUMP)
2033 /* If we are booting a kdump kernel, the sba_iommu will
2034 * cause devices that were not shutdown properly to MCA
2035 * as soon as they are turned back on. Our only option for
2036 * a successful kdump kernel boot is to use the swiotlb.
2037 */
2038 if (elfcorehdr_addr < ELFCORE_ADDR_MAX) {
2039 if (swiotlb_late_init_with_default_size(64 * (1<<20)) != 0)
2040 panic("Unable to initialize software I/O TLB:"
2041 " Try machvec=dig boot option");
2042 machvec_init("dig");
2043 return 0;
2044 }
2045#endif
2046
2029 acpi_bus_register_driver(&acpi_sba_ioc_driver); 2047 acpi_bus_register_driver(&acpi_sba_ioc_driver);
2030 if (!ioc_list) { 2048 if (!ioc_list) {
2031#ifdef CONFIG_IA64_GENERIC 2049#ifdef CONFIG_IA64_GENERIC
2032 extern int swiotlb_late_init_with_default_size (size_t size);
2033
2034 /* 2050 /*
2035 * If we didn't find something sba_iommu can claim, we 2051 * If we didn't find something sba_iommu can claim, we
2036 * need to setup the swiotlb and switch to the dig machvec. 2052 * need to setup the swiotlb and switch to the dig machvec.