From patchwork Fri Nov 9 06:19:13 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [14/14] powerpc: Disable relocation on exceptions when kexecing Date: Thu, 08 Nov 2012 20:19:13 -0000 From: Michael Neuling X-Patchwork-Id: 197943 Message-Id: <1352441953-29096-16-git-send-email-mikey@neuling.org> To: Benjamin Herrenschmidt Cc: Michael Neuling , linuxppc-dev@lists.ozlabs.org, Ian Munsie , Matt Evans From: Ian Munsie Since we don't know if they new kernel we are kexecing into has been built to support relocation on exceptions, we disable them before we kexec. We do NOT disable them if we are execing a kdump kernel, because we want to change as little state as possible and it is likely that we are execing ourselves and will be able to handle them anyway. Signed-off-by: Ian Munsie Signed-off-by: Michael Neuling --- arch/powerpc/platforms/pseries/setup.c | 33 ++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 4c4adc0..47d2a7e 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -40,6 +40,7 @@ #include #include #include +#include #include #include @@ -397,6 +398,35 @@ static int __init pSeries_enable_reloc_on_exc(void) } } +#ifdef CONFIG_KEXEC +static long pSeries_disable_reloc_on_exc(void) +{ + long rc; + + while (1) { + rc = disable_reloc_on_exceptions(); + if (!H_IS_LONG_BUSY(rc)) + return rc; + mdelay(get_longbusy_msecs(rc)); + } +} + +static void pSeries_machine_kexec(struct kimage *image) +{ + long rc; + + if (firmware_has_feature(FW_FEATURE_SET_MODE) && + (image->type != KEXEC_TYPE_CRASH)) { + rc = pSeries_disable_reloc_on_exc(); + if (rc != H_SUCCESS) + pr_warning("Warning: Failed to disable relocation on " + "exceptions: %ld\n", rc); + } + + default_machine_kexec(image); +} +#endif + static void __init pSeries_setup_arch(void) { panic_timeout = 10; @@ -697,4 +727,7 @@ define_machine(pseries) { .progress = rtas_progress, .system_reset_exception = pSeries_system_reset_exception, .machine_check_exception = pSeries_machine_check_exception, +#ifdef CONFIG_KEXEC + .machine_kexec = pSeries_machine_kexec, +#endif };