* [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support
@ 2015-10-07 3:48 Scott Wood
2015-10-07 3:48 ` [PATCH v2 01/18] powerpc/fsl-booke-64: Allow booting from the secondary thread Scott Wood
` (17 more replies)
0 siblings, 18 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
This patchset adds support for kexec and kdump to e5500 and e6500 based
systems running 64-bit kernels. It depends on the kexec-tools patch
http://patchwork.ozlabs.org/patch/527050/ ("ppc64: Add a flag to tell the
kernel it's booting from kexec").
Scott Wood (12):
powerpc/fsl-booke-64: Allow booting from the secondary thread
powerpc/fsl-corenet: Disable coreint if kexec is enabled
powerpc/85xx: Don't use generic timebase sync on 64-bit
powerpc/fsl_pci: Don't set up inbound windows in kdump crash kernel
powerpc/85xx: Load all early TLB entries at once
powerpc/fsl-booke-64: Don't limit ppc64_rma_size to one TLB entry
powerpc/e6500: kexec: Handle hardware threads
powerpc/book3e/kdump: Enable crash_kexec_wait_realmode
powerpc/book3e-64: Don't limit paca to 256 MiB
powerpc/book3e-64/kexec: Enable SMP release
powerpc/booke: Only use VIRT_PHYS_OFFSET on booke32
powerpc/book3e-64/kexec: Set "r4 = 0" when entering spinloop
Tiejun Chen (6):
powerpc/85xx: Implement 64-bit kexec support
powerpc/book3e-64: rename interrupt_end_book3e with __end_interrupts
powerpc/booke64: Fix args to copy_and_flush
powerpc/book3e: support CONFIG_RELOCATABLE
powerpc/book3e-64/kexec: create an identity TLB mapping
powerpc/book3e-64: Enable kexec
Documentation/devicetree/bindings/chosen.txt | 8 +++
arch/powerpc/Kconfig | 2 +-
arch/powerpc/include/asm/exception-64e.h | 4 +-
arch/powerpc/include/asm/page.h | 7 ++-
arch/powerpc/kernel/crash.c | 6 +-
arch/powerpc/kernel/exceptions-64e.S | 17 ++++--
arch/powerpc/kernel/head_64.S | 43 ++++++++++++--
arch/powerpc/kernel/machine_kexec_64.c | 18 ++++++
arch/powerpc/kernel/misc_64.S | 60 ++++++++++++++++++-
arch/powerpc/kernel/paca.c | 6 +-
arch/powerpc/kernel/setup_64.c | 25 +++++++-
arch/powerpc/mm/fsl_booke_mmu.c | 35 ++++++++---
arch/powerpc/mm/mmu_decl.h | 4 +-
arch/powerpc/mm/tlb_nohash.c | 41 ++++++++++---
arch/powerpc/mm/tlb_nohash_low.S | 63 ++++++++++++++++++++
arch/powerpc/platforms/85xx/corenet_generic.c | 4 ++
arch/powerpc/platforms/85xx/smp.c | 86 ++++++++++++++++++++++++---
arch/powerpc/sysdev/fsl_pci.c | 84 +++++++++++++++++++-------
18 files changed, 443 insertions(+), 70 deletions(-)
--
2.1.4
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v2 01/18] powerpc/fsl-booke-64: Allow booting from the secondary thread
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 02/18] powerpc/fsl-corenet: Disable coreint if kexec is enabled Scott Wood
` (16 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
This allows SMP kernels to work as kdump crash kernels. While crash
kernels don't really need to be SMP, this prevents things from breaking
if a user does it anyway (which is not something you want to only find
out once the main kernel has crashed in the field, especially if
whether it works or not depends on which cpu crashed).
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/platforms/85xx/smp.c | 27 ++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index b8b8216..c2ded03 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -173,15 +173,22 @@ static inline u32 read_spin_table_addr_l(void *spin_table)
static void wake_hw_thread(void *info)
{
void fsl_secondary_thread_init(void);
- unsigned long imsr1, inia1;
+ unsigned long imsr, inia;
int nr = *(const int *)info;
- imsr1 = MSR_KERNEL;
- inia1 = *(unsigned long *)fsl_secondary_thread_init;
-
- mttmr(TMRN_IMSR1, imsr1);
- mttmr(TMRN_INIA1, inia1);
- mtspr(SPRN_TENS, TEN_THREAD(1));
+ imsr = MSR_KERNEL;
+ inia = *(unsigned long *)fsl_secondary_thread_init;
+
+ if (cpu_thread_in_core(nr) == 0) {
+ /* For when we boot on a secondary thread with kdump */
+ mttmr(TMRN_IMSR0, imsr);
+ mttmr(TMRN_INIA0, inia);
+ mtspr(SPRN_TENS, TEN_THREAD(0));
+ } else {
+ mttmr(TMRN_IMSR1, imsr);
+ mttmr(TMRN_INIA1, inia);
+ mtspr(SPRN_TENS, TEN_THREAD(1));
+ }
smp_generic_kick_cpu(nr);
}
@@ -224,6 +231,12 @@ static int smp_85xx_kick_cpu(int nr)
smp_call_function_single(primary, wake_hw_thread, &nr, 0);
return 0;
+ } else if (cpu_thread_in_core(boot_cpuid) != 0 &&
+ cpu_first_thread_sibling(boot_cpuid) == nr) {
+ if (WARN_ON_ONCE(!cpu_has_feature(CPU_FTR_SMT)))
+ return -ENOENT;
+
+ smp_call_function_single(boot_cpuid, wake_hw_thread, &nr, 0);
}
#endif
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 02/18] powerpc/fsl-corenet: Disable coreint if kexec is enabled
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
2015-10-07 3:48 ` [PATCH v2 01/18] powerpc/fsl-booke-64: Allow booting from the secondary thread Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 03/18] powerpc/85xx: Don't use generic timebase sync on 64-bit Scott Wood
` (15 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
Problems have been observed in coreint (EPR) mode if interrupts are
left pending (due to the lack of device quiescence with kdump) after
having tried to deliver to a CPU but unable to deliver due to MSR[EE]
-- interrupts no longer get reliably delivered in the new kernel. I
tried various ways of fixing it up inside the crash kernel itself, and
none worked (including resetting the entire mpic). Masking all
interrupts and issuing EOIs in the crashing kernel did help a lot of
the time, but the behavior was not consistent.
Thus, stick to standard IACK mode when kdump is a possibility.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
Previously I discussed the possibility of removing coreint entirely,
but I think we want to keep it for virtualized guests.
---
arch/powerpc/platforms/85xx/corenet_generic.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/powerpc/platforms/85xx/corenet_generic.c b/arch/powerpc/platforms/85xx/corenet_generic.c
index b395571..04ffbcb 100644
--- a/arch/powerpc/platforms/85xx/corenet_generic.c
+++ b/arch/powerpc/platforms/85xx/corenet_generic.c
@@ -214,7 +214,11 @@ define_machine(corenet_generic) {
.pcibios_fixup_bus = fsl_pcibios_fixup_bus,
.pcibios_fixup_phb = fsl_pcibios_fixup_phb,
#endif
+#ifdef CONFIG_KEXEC
+ .get_irq = mpic_get_irq,
+#else
.get_irq = mpic_get_coreint_irq,
+#endif
.restart = fsl_rstcr_restart,
.calibrate_decr = generic_calibrate_decr,
.progress = udbg_progress,
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 03/18] powerpc/85xx: Don't use generic timebase sync on 64-bit
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
2015-10-07 3:48 ` [PATCH v2 01/18] powerpc/fsl-booke-64: Allow booting from the secondary thread Scott Wood
2015-10-07 3:48 ` [PATCH v2 02/18] powerpc/fsl-corenet: Disable coreint if kexec is enabled Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 04/18] powerpc/fsl_pci: Don't set up inbound windows in kdump crash kernel Scott Wood
` (14 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
85xx currently uses the generic timebase sync mechanism when
CONFIG_KEXEC is enabled, because 32-bit 85xx kexec support does a hard
reset of each core. 64-bit 85xx kexec does not do this, so we neither
need nor want this (nor is the generic timebase sync code built on
ppc64).
FWIW, I don't like the fact that the hard reset is done on 32-bit
kexec, and I especially don't like the timebase sync being triggered
only on the presence of CONFIG_KEXEC rather than actually booting in
that environment, but that's beyond the scope of this patch...
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/platforms/85xx/smp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index c2ded03..a0763be 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -344,7 +344,7 @@ struct smp_ops_t smp_85xx_ops = {
.cpu_disable = generic_cpu_disable,
.cpu_die = generic_cpu_die,
#endif
-#ifdef CONFIG_KEXEC
+#if defined(CONFIG_KEXEC) && !defined(CONFIG_PPC64)
.give_timebase = smp_generic_give_timebase,
.take_timebase = smp_generic_take_timebase,
#endif
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 04/18] powerpc/fsl_pci: Don't set up inbound windows in kdump crash kernel
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (2 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 03/18] powerpc/85xx: Don't use generic timebase sync on 64-bit Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 05/18] powerpc/85xx: Load all early TLB entries at once Scott Wood
` (13 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood, Mingkai Hu
Otherwise, because the top end of the crash kernel is treated as the
absolute top of memory rather than the beginning of a reserved region,
in-flight DMA from the previous kernel that targets areas above the
crash kernel can trigger a storm of PCI errors. We only do this for
kdump, not normal kexec, in case kexec is being used to upgrade to a
kernel that wants a different inbound memory map.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Cc: Mingkai Hu <Mingkai.hu@freescale.com>
---
v2: new patch
arch/powerpc/sysdev/fsl_pci.c | 84 +++++++++++++++++++++++++++++++------------
1 file changed, 61 insertions(+), 23 deletions(-)
diff --git a/arch/powerpc/sysdev/fsl_pci.c b/arch/powerpc/sysdev/fsl_pci.c
index ebc1f412..98d671c 100644
--- a/arch/powerpc/sysdev/fsl_pci.c
+++ b/arch/powerpc/sysdev/fsl_pci.c
@@ -179,6 +179,19 @@ static int setup_one_atmu(struct ccsr_pci __iomem *pci,
return i;
}
+static bool is_kdump(void)
+{
+ struct device_node *node;
+
+ node = of_find_node_by_type(NULL, "memory");
+ if (!node) {
+ WARN_ON_ONCE(1);
+ return false;
+ }
+
+ return of_property_read_bool(node, "linux,usable-memory");
+}
+
/* atmu setup for fsl pci/pcie controller */
static void setup_pci_atmu(struct pci_controller *hose)
{
@@ -192,6 +205,16 @@ static void setup_pci_atmu(struct pci_controller *hose)
const char *name = hose->dn->full_name;
const u64 *reg;
int len;
+ bool setup_inbound;
+
+ /*
+ * If this is kdump, we don't want to trigger a bunch of PCI
+ * errors by closing the window on in-flight DMA.
+ *
+ * We still run most of the function's logic so that things like
+ * hose->dma_window_size still get set.
+ */
+ setup_inbound = !is_kdump();
if (early_find_capability(hose, 0, 0, PCI_CAP_ID_EXP)) {
if (in_be32(&pci->block_rev1) >= PCIE_IP_REV_2_2) {
@@ -204,8 +227,11 @@ static void setup_pci_atmu(struct pci_controller *hose)
/* Disable all windows (except powar0 since it's ignored) */
for(i = 1; i < 5; i++)
out_be32(&pci->pow[i].powar, 0);
- for (i = start_idx; i < end_idx; i++)
- out_be32(&pci->piw[i].piwar, 0);
+
+ if (setup_inbound) {
+ for (i = start_idx; i < end_idx; i++)
+ out_be32(&pci->piw[i].piwar, 0);
+ }
/* Setup outbound MEM window */
for(i = 0, j = 1; i < 3; i++) {
@@ -278,6 +304,7 @@ static void setup_pci_atmu(struct pci_controller *hose)
/* Setup inbound mem window */
mem = memblock_end_of_DRAM();
+ pr_info("%s: end of DRAM %llx\n", __func__, mem);
/*
* The msi-address-64 property, if it exists, indicates the physical
@@ -320,12 +347,14 @@ static void setup_pci_atmu(struct pci_controller *hose)
piwar |= ((mem_log - 1) & PIWAR_SZ_MASK);
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwar, piwar);
- win_idx--;
+ if (setup_inbound) {
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwbar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+ }
+ win_idx--;
hose->dma_window_base_cur = 0x00000000;
hose->dma_window_size = (resource_size_t)sz;
@@ -343,13 +372,15 @@ static void setup_pci_atmu(struct pci_controller *hose)
piwar = (piwar & ~PIWAR_SZ_MASK) | (mem_log - 1);
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, 0x00000000);
- out_be32(&pci->piw[win_idx].piwbear,
- pci64_dma_offset >> 44);
- out_be32(&pci->piw[win_idx].piwbar,
- pci64_dma_offset >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
+ if (setup_inbound) {
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, 0x00000000);
+ out_be32(&pci->piw[win_idx].piwbear,
+ pci64_dma_offset >> 44);
+ out_be32(&pci->piw[win_idx].piwbar,
+ pci64_dma_offset >> 12);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+ }
/*
* install our own dma_set_mask handler to fixup dma_ops
@@ -362,12 +393,15 @@ static void setup_pci_atmu(struct pci_controller *hose)
} else {
u64 paddr = 0;
- /* Setup inbound memory window */
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, (piwar | (mem_log - 1)));
- win_idx--;
+ if (setup_inbound) {
+ /* Setup inbound memory window */
+ out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwar,
+ (piwar | (mem_log - 1)));
+ }
+ win_idx--;
paddr += 1ull << mem_log;
sz -= 1ull << mem_log;
@@ -375,11 +409,15 @@ static void setup_pci_atmu(struct pci_controller *hose)
mem_log = ilog2(sz);
piwar |= (mem_log - 1);
- out_be32(&pci->piw[win_idx].pitar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwbar, paddr >> 12);
- out_be32(&pci->piw[win_idx].piwar, piwar);
- win_idx--;
+ if (setup_inbound) {
+ out_be32(&pci->piw[win_idx].pitar,
+ paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwbar,
+ paddr >> 12);
+ out_be32(&pci->piw[win_idx].piwar, piwar);
+ }
+ win_idx--;
paddr += 1ull << mem_log;
}
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 05/18] powerpc/85xx: Load all early TLB entries at once
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (3 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 04/18] powerpc/fsl_pci: Don't set up inbound windows in kdump crash kernel Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 14:00 ` Laurentiu Tudor
2015-10-07 3:48 ` [PATCH v2 06/18] powerpc/fsl-booke-64: Don't limit ppc64_rma_size to one TLB entry Scott Wood
` (12 subsequent siblings)
17 siblings, 1 reply; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
Use an AS=1 trampoline TLB entry to allow all normal TLB1 entries to
be loaded at once. This avoids the need to keep the translation that
code is executing from in the same TLB entry in the final TLB
configuration as during early boot, which in turn is helpful for
relocatable kernels (e.g. kdump) where the kernel is not running from
what would be the first TLB entry.
On e6500, we limit map_mem_in_cams() to the primary hwthread of a
core (the boot cpu is always considered primary, as a kdump kernel
can be entered on any cpu). Each TLB only needs to be set up once,
and when we do, we don't want another thread to be running when we
create a temporary trampoline TLB1 entry.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/kernel/setup_64.c | 8 +++++
arch/powerpc/mm/fsl_booke_mmu.c | 15 ++++++++--
arch/powerpc/mm/mmu_decl.h | 1 +
arch/powerpc/mm/tlb_nohash.c | 19 +++++++++++-
arch/powerpc/mm/tlb_nohash_low.S | 63 ++++++++++++++++++++++++++++++++++++++++
5 files changed, 102 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index bdcbb71..505ec2c 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -108,6 +108,14 @@ static void setup_tlb_core_data(void)
for_each_possible_cpu(cpu) {
int first = cpu_first_thread_sibling(cpu);
+ /*
+ * If we boot via kdump on a non-primary thread,
+ * make sure we point at the thread that actually
+ * set up this TLB.
+ */
+ if (cpu_first_thread_sibling(boot_cpuid) == first)
+ first = boot_cpuid;
+
paca[cpu].tcd_ptr = &paca[first].tcd;
/*
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 354ba3c..36d3c55 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -105,8 +105,9 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
* an unsigned long (for example, 32-bit implementations cannot support a 4GB
* size).
*/
-static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
- unsigned long size, unsigned long flags, unsigned int pid)
+static void preptlbcam(int index, unsigned long virt, phys_addr_t phys,
+ unsigned long size, unsigned long flags,
+ unsigned int pid)
{
unsigned int tsize;
@@ -141,7 +142,13 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
tlbcam_addrs[index].start = virt;
tlbcam_addrs[index].limit = virt + size - 1;
tlbcam_addrs[index].phys = phys;
+}
+void settlbcam(int index, unsigned long virt, phys_addr_t phys,
+ unsigned long size, unsigned long flags,
+ unsigned int pid)
+{
+ preptlbcam(index, virt, phys, size, flags, pid);
loadcam_entry(index);
}
@@ -181,13 +188,15 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
unsigned long cam_sz;
cam_sz = calc_cam_sz(ram, virt, phys);
- settlbcam(i, virt, phys, cam_sz, pgprot_val(PAGE_KERNEL_X), 0);
+ preptlbcam(i, virt, phys, cam_sz, pgprot_val(PAGE_KERNEL_X), 0);
ram -= cam_sz;
amount_mapped += cam_sz;
virt += cam_sz;
phys += cam_sz;
}
+
+ loadcam_multi(0, i, max_cam_idx);
tlbcam_index = i;
#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 085b66b..27c3a2d 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -152,6 +152,7 @@ extern int switch_to_as1(void);
extern void restore_to_as0(int esel, int offset, void *dt_ptr, int bootcpu);
#endif
extern void loadcam_entry(unsigned int index);
+extern void loadcam_multi(int first_idx, int num, int tmp_idx);
struct tlbcam {
u32 MAS0;
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index 723a099..a7381fb 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -42,6 +42,7 @@
#include <asm/tlbflush.h>
#include <asm/tlb.h>
#include <asm/code-patching.h>
+#include <asm/cputhreads.h>
#include <asm/hugetlb.h>
#include <asm/paca.h>
@@ -628,10 +629,26 @@ static void early_init_this_mmu(void)
#ifdef CONFIG_PPC_FSL_BOOK3E
if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
unsigned int num_cams;
+ int __maybe_unused cpu = smp_processor_id();
+ bool map = true;
/* use a quarter of the TLBCAM for bolted linear map */
num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
- linear_map_top = map_mem_in_cams(linear_map_top, num_cams);
+
+ /*
+ * Only do the mapping once per core, or else the
+ * transient mapping would cause problems.
+ */
+#ifdef CONFIG_SMP
+ if (cpu != boot_cpuid &&
+ (cpu != cpu_first_thread_sibling(cpu) ||
+ cpu == cpu_first_thread_sibling(boot_cpuid)))
+ map = false;
+#endif
+
+ if (map)
+ linear_map_top = map_mem_in_cams(linear_map_top,
+ num_cams);
}
#endif
diff --git a/arch/powerpc/mm/tlb_nohash_low.S b/arch/powerpc/mm/tlb_nohash_low.S
index 43ff3c7..68c4775 100644
--- a/arch/powerpc/mm/tlb_nohash_low.S
+++ b/arch/powerpc/mm/tlb_nohash_low.S
@@ -400,6 +400,7 @@ _GLOBAL(set_context)
* extern void loadcam_entry(unsigned int index)
*
* Load TLBCAM[index] entry in to the L2 CAM MMU
+ * Must preserve r7, r8, r9, and r10
*/
_GLOBAL(loadcam_entry)
mflr r5
@@ -423,4 +424,66 @@ END_MMU_FTR_SECTION_IFSET(MMU_FTR_BIG_PHYS)
tlbwe
isync
blr
+
+/*
+ * Load multiple TLB entries at once, using an alternate-space
+ * trampoline so that we don't have to care about whether the same
+ * TLB entry maps us before and after.
+ *
+ * r3 = first entry to write
+ * r4 = number of entries to write
+ * r5 = temporary tlb entry
+ */
+_GLOBAL(loadcam_multi)
+ mflr r8
+
+ /*
+ * Set up temporary TLB entry that is the same as what we're
+ * running from, but in AS=1.
+ */
+ bl 1f
+1: mflr r6
+ tlbsx 0,r8
+ mfspr r6,SPRN_MAS1
+ ori r6,r6,MAS1_TS
+ mtspr SPRN_MAS1,r6
+ mfspr r6,SPRN_MAS0
+ rlwimi r6,r5,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK
+ mr r7,r5
+ mtspr SPRN_MAS0,r6
+ isync
+ tlbwe
+ isync
+
+ /* Switch to AS=1 */
+ mfmsr r6
+ ori r6,r6,MSR_IS|MSR_DS
+ mtmsr r6
+ isync
+
+ mr r9,r3
+ add r10,r3,r4
+2: bl loadcam_entry
+ addi r9,r9,1
+ cmpw r9,r10
+ mr r3,r9
+ blt 2b
+
+ /* Return to AS=0 and clear the temporary entry */
+ mfmsr r6
+ rlwinm. r6,r6,0,~(MSR_IS|MSR_DS)
+ mtmsr r6
+ isync
+
+ li r6,0
+ mtspr SPRN_MAS1,r6
+ rlwinm r6,r7,MAS0_ESEL_SHIFT,MAS0_ESEL_MASK
+ oris r6,r6,MAS0_TLBSEL(1)@h
+ mtspr SPRN_MAS0,r6
+ isync
+ tlbwe
+ isync
+
+ mtlr r8
+ blr
#endif
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 06/18] powerpc/fsl-booke-64: Don't limit ppc64_rma_size to one TLB entry
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (4 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 05/18] powerpc/85xx: Load all early TLB entries at once Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 07/18] powerpc/85xx: Implement 64-bit kexec support Scott Wood
` (11 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
This is required for kdump to work when loaded at at an address that
does not fall within the first TLB entry -- which can easily happen
because while the lower limit is enforced via reserved memory, which
doesn't affect how much is mapped, the upper limit is enforced via a
different mechanism that does. Thus, more TLB entries are needed than
would normally be used, as the total memory to be mapped might not be a
power of two.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/mm/fsl_booke_mmu.c | 22 +++++++++++++++-------
arch/powerpc/mm/mmu_decl.h | 3 ++-
arch/powerpc/mm/tlb_nohash.c | 24 +++++++++++++++++-------
3 files changed, 34 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
index 36d3c55..5eef7d7 100644
--- a/arch/powerpc/mm/fsl_booke_mmu.c
+++ b/arch/powerpc/mm/fsl_booke_mmu.c
@@ -178,7 +178,8 @@ unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
}
static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
- unsigned long ram, int max_cam_idx)
+ unsigned long ram, int max_cam_idx,
+ bool dryrun)
{
int i;
unsigned long amount_mapped = 0;
@@ -188,7 +189,9 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
unsigned long cam_sz;
cam_sz = calc_cam_sz(ram, virt, phys);
- preptlbcam(i, virt, phys, cam_sz, pgprot_val(PAGE_KERNEL_X), 0);
+ if (!dryrun)
+ preptlbcam(i, virt, phys, cam_sz,
+ pgprot_val(PAGE_KERNEL_X), 0);
ram -= cam_sz;
amount_mapped += cam_sz;
@@ -196,6 +199,9 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
phys += cam_sz;
}
+ if (dryrun)
+ return amount_mapped;
+
loadcam_multi(0, i, max_cam_idx);
tlbcam_index = i;
@@ -208,12 +214,12 @@ static unsigned long map_mem_in_cams_addr(phys_addr_t phys, unsigned long virt,
return amount_mapped;
}
-unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx)
+unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx, bool dryrun)
{
unsigned long virt = PAGE_OFFSET;
phys_addr_t phys = memstart_addr;
- return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx);
+ return map_mem_in_cams_addr(phys, virt, ram, max_cam_idx, dryrun);
}
#ifdef CONFIG_PPC32
@@ -244,7 +250,7 @@ void __init adjust_total_lowmem(void)
ram = min((phys_addr_t)__max_low_memory, (phys_addr_t)total_lowmem);
i = switch_to_as1();
- __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM);
+ __max_low_memory = map_mem_in_cams(ram, CONFIG_LOWMEM_CAM_NUM, false);
restore_to_as0(i, 0, 0, 1);
pr_info("Memory CAM mapping: ");
@@ -312,10 +318,12 @@ notrace void __init relocate_init(u64 dt_ptr, phys_addr_t start)
n = switch_to_as1();
/* map a 64M area for the second relocation */
if (memstart_addr > start)
- map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM);
+ map_mem_in_cams(0x4000000, CONFIG_LOWMEM_CAM_NUM,
+ false);
else
map_mem_in_cams_addr(start, PAGE_OFFSET + offset,
- 0x4000000, CONFIG_LOWMEM_CAM_NUM);
+ 0x4000000, CONFIG_LOWMEM_CAM_NUM,
+ false);
restore_to_as0(n, offset, __va(dt_ptr), 1);
/* We should never reach here */
panic("Relocation error");
diff --git a/arch/powerpc/mm/mmu_decl.h b/arch/powerpc/mm/mmu_decl.h
index 27c3a2d..9f58ff4 100644
--- a/arch/powerpc/mm/mmu_decl.h
+++ b/arch/powerpc/mm/mmu_decl.h
@@ -141,7 +141,8 @@ extern void MMU_init_hw(void);
extern unsigned long mmu_mapin_ram(unsigned long top);
#elif defined(CONFIG_PPC_FSL_BOOK3E)
-extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx);
+extern unsigned long map_mem_in_cams(unsigned long ram, int max_cam_idx,
+ bool dryrun);
extern unsigned long calc_cam_sz(unsigned long ram, unsigned long virt,
phys_addr_t phys);
#ifdef CONFIG_PPC32
diff --git a/arch/powerpc/mm/tlb_nohash.c b/arch/powerpc/mm/tlb_nohash.c
index a7381fb..bb04e4d 100644
--- a/arch/powerpc/mm/tlb_nohash.c
+++ b/arch/powerpc/mm/tlb_nohash.c
@@ -648,7 +648,7 @@ static void early_init_this_mmu(void)
if (map)
linear_map_top = map_mem_in_cams(linear_map_top,
- num_cams);
+ num_cams, false);
}
#endif
@@ -746,10 +746,14 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
* entries are supported though that may eventually
* change.
*
- * on FSL Embedded 64-bit, we adjust the RMA size to match the
- * first bolted TLB entry size. We still limit max to 1G even if
- * the TLB could cover more. This is due to what the early init
- * code is setup to do.
+ * on FSL Embedded 64-bit, usually all RAM is bolted, but with
+ * unusual memory sizes it's possible for some RAM to not be mapped
+ * (such RAM is not used at all by Linux, since we don't support
+ * highmem on 64-bit). We limit ppc64_rma_size to what would be
+ * mappable if this memblock is the only one. Additional memblocks
+ * can only increase, not decrease, the amount that ends up getting
+ * mapped. We still limit max to 1G even if we'll eventually map
+ * more. This is due to what the early init code is set up to do.
*
* We crop it to the size of the first MEMBLOCK to
* avoid going over total available memory just in case...
@@ -757,8 +761,14 @@ void setup_initial_memory_limit(phys_addr_t first_memblock_base,
#ifdef CONFIG_PPC_FSL_BOOK3E
if (mmu_has_feature(MMU_FTR_TYPE_FSL_E)) {
unsigned long linear_sz;
- linear_sz = calc_cam_sz(first_memblock_size, PAGE_OFFSET,
- first_memblock_base);
+ unsigned int num_cams;
+
+ /* use a quarter of the TLBCAM for bolted linear map */
+ num_cams = (mfspr(SPRN_TLB1CFG) & TLBnCFG_N_ENTRY) / 4;
+
+ linear_sz = map_mem_in_cams(first_memblock_size, num_cams,
+ true);
+
ppc64_rma_size = min_t(u64, linear_sz, 0x40000000);
} else
#endif
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 07/18] powerpc/85xx: Implement 64-bit kexec support
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (5 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 06/18] powerpc/fsl-booke-64: Don't limit ppc64_rma_size to one TLB entry Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 08/18] powerpc/e6500: kexec: Handle hardware threads Scott Wood
` (10 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev
Cc: Tiejun Chen, Michael Ellerman, kexec, Tiejun Chen, Scott Wood
From: Tiejun Chen <tiejun.chen@windriver.com>
Unlike 32-bit 85xx kexec, we don't do a core reset.
Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
[scottwood: edit changelog, and cleanup]
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/platforms/85xx/smp.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index a0763be..2e46684 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -351,6 +351,7 @@ struct smp_ops_t smp_85xx_ops = {
};
#ifdef CONFIG_KEXEC
+#ifdef CONFIG_PPC32
atomic_t kexec_down_cpus = ATOMIC_INIT(0);
void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
@@ -370,9 +371,18 @@ static void mpc85xx_smp_kexec_down(void *arg)
if (ppc_md.kexec_cpu_down)
ppc_md.kexec_cpu_down(0,1);
}
+#else
+void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
+{
+ local_irq_disable();
+ hard_irq_disable();
+ mpic_teardown_this_cpu(secondary);
+}
+#endif
static void mpc85xx_smp_machine_kexec(struct kimage *image)
{
+#ifdef CONFIG_PPC32
int timeout = INT_MAX;
int i, num_cpus = num_present_cpus();
@@ -393,6 +403,7 @@ static void mpc85xx_smp_machine_kexec(struct kimage *image)
if ( i == smp_processor_id() ) continue;
mpic_reset_core(i);
}
+#endif
default_machine_kexec(image);
}
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 08/18] powerpc/e6500: kexec: Handle hardware threads
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (6 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 07/18] powerpc/85xx: Implement 64-bit kexec support Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 09/18] powerpc/book3e-64: rename interrupt_end_book3e with __end_interrupts Scott Wood
` (9 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
The new kernel will be expecting secondary threads to be disabled,
not spinning.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
v2: minor cleanup
arch/powerpc/kernel/head_64.S | 16 ++++++++++++++
arch/powerpc/platforms/85xx/smp.c | 46 +++++++++++++++++++++++++++++++++++++++
2 files changed, 62 insertions(+)
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index d48125d..8b2bf0d 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -182,6 +182,8 @@ exception_marker:
#ifdef CONFIG_PPC_BOOK3E
_GLOBAL(fsl_secondary_thread_init)
+ mfspr r4,SPRN_BUCSR
+
/* Enable branch prediction */
lis r3,BUCSR_INIT@h
ori r3,r3,BUCSR_INIT@l
@@ -196,10 +198,24 @@ _GLOBAL(fsl_secondary_thread_init)
* number. There are two threads per core, so shift everything
* but the low bit right by two bits so that the cpu numbering is
* continuous.
+ *
+ * If the old value of BUCSR is non-zero, this thread has run
+ * before. Thus, we assume we are coming from kexec or a similar
+ * scenario, and PIR is already set to the correct value. This
+ * is a bit of a hack, but there are limited opportunities for
+ * getting information into the thread and the alternatives
+ * seemed like they'd be overkill. We can't tell just by looking
+ * at the old PIR value which state it's in, since the same value
+ * could be valid for one thread out of reset and for a different
+ * thread in Linux.
*/
+
mfspr r3, SPRN_PIR
+ cmpwi r4,0
+ bne 1f
rlwimi r3, r3, 30, 2, 30
mtspr SPRN_PIR, r3
+1:
#endif
_GLOBAL(generic_secondary_thread_init)
diff --git a/arch/powerpc/platforms/85xx/smp.c b/arch/powerpc/platforms/85xx/smp.c
index 2e46684..712764f 100644
--- a/arch/powerpc/platforms/85xx/smp.c
+++ b/arch/powerpc/platforms/85xx/smp.c
@@ -374,9 +374,55 @@ static void mpc85xx_smp_kexec_down(void *arg)
#else
void mpc85xx_smp_kexec_cpu_down(int crash_shutdown, int secondary)
{
+ int cpu = smp_processor_id();
+ int sibling = cpu_last_thread_sibling(cpu);
+ bool notified = false;
+ int disable_cpu;
+ int disable_threadbit = 0;
+ long start = mftb();
+ long now;
+
local_irq_disable();
hard_irq_disable();
mpic_teardown_this_cpu(secondary);
+
+ if (cpu == crashing_cpu && cpu_thread_in_core(cpu) != 0) {
+ /*
+ * We enter the crash kernel on whatever cpu crashed,
+ * even if it's a secondary thread. If that's the case,
+ * disable the corresponding primary thread.
+ */
+ disable_threadbit = 1;
+ disable_cpu = cpu_first_thread_sibling(cpu);
+ } else if (sibling != crashing_cpu &&
+ cpu_thread_in_core(cpu) == 0 &&
+ cpu_thread_in_core(sibling) != 0) {
+ disable_threadbit = 2;
+ disable_cpu = sibling;
+ }
+
+ if (disable_threadbit) {
+ while (paca[disable_cpu].kexec_state < KEXEC_STATE_REAL_MODE) {
+ barrier();
+ now = mftb();
+ if (!notified && now - start > 1000000) {
+ pr_info("%s/%d: waiting for cpu %d to enter KEXEC_STATE_REAL_MODE (%d)\n",
+ __func__, smp_processor_id(),
+ disable_cpu,
+ paca[disable_cpu].kexec_state);
+ notified = true;
+ }
+ }
+
+ if (notified) {
+ pr_info("%s: cpu %d done waiting\n",
+ __func__, disable_cpu);
+ }
+
+ mtspr(SPRN_TENC, disable_threadbit);
+ while (mfspr(SPRN_TENSR) & disable_threadbit)
+ cpu_relax();
+ }
}
#endif
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 09/18] powerpc/book3e-64: rename interrupt_end_book3e with __end_interrupts
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (7 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 08/18] powerpc/e6500: kexec: Handle hardware threads Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 10/18] powerpc/booke64: Fix args to copy_and_flush Scott Wood
` (8 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev
Cc: Tiejun Chen, Michael Ellerman, kexec, Tiejun Chen, Scott Wood
From: Tiejun Chen <tiejun.chen@windriver.com>
Rename 'interrupt_end_book3e' to '__end_interrupts' so that the symbol
can be used by both book3s and book3e.
Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
[scottwood: edit changelog]
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/kernel/exceptions-64e.S | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index f3bd5e7..9d4a006 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -542,8 +542,8 @@ interrupt_base_book3e: /* fake trap */
EXCEPTION_STUB(0x320, ehpriv)
EXCEPTION_STUB(0x340, lrat_error)
- .globl interrupt_end_book3e
-interrupt_end_book3e:
+ .globl __end_interrupts
+__end_interrupts:
/* Critical Input Interrupt */
START_EXCEPTION(critical_input);
@@ -736,7 +736,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
beq+ 1f
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
- LOAD_REG_IMMEDIATE(r15,interrupt_end_book3e)
+ LOAD_REG_IMMEDIATE(r15,__end_interrupts)
cmpld cr0,r10,r14
cmpld cr1,r10,r15
blt+ cr0,1f
@@ -800,7 +800,7 @@ kernel_dbg_exc:
beq+ 1f
LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e)
- LOAD_REG_IMMEDIATE(r15,interrupt_end_book3e)
+ LOAD_REG_IMMEDIATE(r15,__end_interrupts)
cmpld cr0,r10,r14
cmpld cr1,r10,r15
blt+ cr0,1f
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 10/18] powerpc/booke64: Fix args to copy_and_flush
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (8 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 09/18] powerpc/book3e-64: rename interrupt_end_book3e with __end_interrupts Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 11/18] powerpc/book3e: support CONFIG_RELOCATABLE Scott Wood
` (7 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev
Cc: Tiejun Chen, Michael Ellerman, kexec, Tiejun Chen, Scott Wood
From: Tiejun Chen <tiejun.chen@windriver.com>
Convert r4/r5, not r6, to a virtual address when calling
copy_and_flush. Otherwise, r3 is already virtual, and copy_to_flush
tries to access r3+r6, PAGE_OFFSET gets added twice.
This isn't normally seen because on book3e we normally enter with
the kernel at zero and thus skip copy_to_flush -- but it will be
needed for kexec support.
Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
[scottwood: split patch and rewrote changelog]
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/kernel/head_64.S | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index 8b2bf0d..a1e85ca 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -474,15 +474,15 @@ __after_prom_start:
*/
li r3,0 /* target addr */
#ifdef CONFIG_PPC_BOOK3E
- tovirt(r3,r3) /* on booke, we already run at PAGE_OFFSET */
+ tovirt(r3,r3) /* on booke, we already run at PAGE_OFFSET */
#endif
mr. r4,r26 /* In some cases the loader may */
+#if defined(CONFIG_PPC_BOOK3E)
+ tovirt(r4,r4)
+#endif
beq 9f /* have already put us at zero */
li r6,0x100 /* Start offset, the first 0x100 */
/* bytes were copied earlier. */
-#ifdef CONFIG_PPC_BOOK3E
- tovirt(r6,r6) /* on booke, we already run at PAGE_OFFSET */
-#endif
#ifdef CONFIG_RELOCATABLE
/*
@@ -514,6 +514,9 @@ __after_prom_start:
p_end: .llong _end - _stext
4: /* Now copy the rest of the kernel up to _end */
+#if defined(CONFIG_PPC_BOOK3E)
+ tovirt(r26,r26)
+#endif
addis r5,r26,(p_end - _stext)@ha
ld r5,(p_end - _stext)@l(r5) /* get _end */
5: bl copy_and_flush /* copy the rest */
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 11/18] powerpc/book3e: support CONFIG_RELOCATABLE
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (9 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 10/18] powerpc/booke64: Fix args to copy_and_flush Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 12/18] powerpc/book3e/kdump: Enable crash_kexec_wait_realmode Scott Wood
` (6 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev
Cc: Tiejun Chen, Michael Ellerman, kexec, Tiejun Chen, Scott Wood
From: Tiejun Chen <tiejun.chen@windriver.com>
book3e is different with book3s since 3s includes the exception
vectors code in head_64.S as it relies on absolute addressing
which is only possible within this compilation unit. So we have
to get that label address with got.
And when boot a relocated kernel, we should reset ipvr properly again
after .relocate.
Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
[scottwood: cleanup and ifdef removal]
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/include/asm/exception-64e.h | 4 ++--
arch/powerpc/kernel/exceptions-64e.S | 9 +++++++--
arch/powerpc/kernel/head_64.S | 22 +++++++++++++++++++---
3 files changed, 28 insertions(+), 7 deletions(-)
diff --git a/arch/powerpc/include/asm/exception-64e.h b/arch/powerpc/include/asm/exception-64e.h
index a8b52b6..344fc43 100644
--- a/arch/powerpc/include/asm/exception-64e.h
+++ b/arch/powerpc/include/asm/exception-64e.h
@@ -204,8 +204,8 @@ exc_##label##_book3e:
#endif
#define SET_IVOR(vector_number, vector_offset) \
- li r3,vector_offset@l; \
- ori r3,r3,interrupt_base_book3e@l; \
+ LOAD_REG_ADDR(r3,interrupt_base_book3e);\
+ ori r3,r3,vector_offset@l; \
mtspr SPRN_IVOR##vector_number,r3;
#endif /* _ASM_POWERPC_EXCEPTION_64E_H */
diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S
index 9d4a006..488e631 100644
--- a/arch/powerpc/kernel/exceptions-64e.S
+++ b/arch/powerpc/kernel/exceptions-64e.S
@@ -1351,7 +1351,10 @@ skpinv: addi r6,r6,1 /* Increment */
* r4 = MAS0 w/TLBSEL & ESEL for the temp mapping
*/
/* Now we branch the new virtual address mapped by this entry */
- LOAD_REG_IMMEDIATE(r6,2f)
+ bl 1f /* Find our address */
+1: mflr r6
+ addi r6,r6,(2f - 1b)
+ tovirt(r6,r6)
lis r7,MSR_KERNEL@h
ori r7,r7,MSR_KERNEL@l
mtspr SPRN_SRR0,r6
@@ -1583,9 +1586,11 @@ _GLOBAL(book3e_secondary_thread_init)
mflr r28
b 3b
+ .globl init_core_book3e
init_core_book3e:
/* Establish the interrupt vector base */
- LOAD_REG_IMMEDIATE(r3, interrupt_base_book3e)
+ tovirt(r2,r2)
+ LOAD_REG_ADDR(r3, interrupt_base_book3e)
mtspr SPRN_IVPR,r3
sync
blr
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index a1e85ca..1b77956 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -457,12 +457,22 @@ __after_prom_start:
/* process relocations for the final address of the kernel */
lis r25,PAGE_OFFSET@highest /* compute virtual base of kernel */
sldi r25,r25,32
+#if defined(CONFIG_PPC_BOOK3E)
+ tovirt(r26,r26) /* on booke, we already run at PAGE_OFFSET */
+#endif
lwz r7,__run_at_load-_stext(r26)
+#if defined(CONFIG_PPC_BOOK3E)
+ tophys(r26,r26)
+#endif
cmplwi cr0,r7,1 /* flagged to stay where we are ? */
bne 1f
add r25,r25,r26
1: mr r3,r25
bl relocate
+#if defined(CONFIG_PPC_BOOK3E)
+ /* IVPR needs to be set after relocation. */
+ bl init_core_book3e
+#endif
#endif
/*
@@ -490,12 +500,21 @@ __after_prom_start:
* variable __run_at_load, if it is set the kernel is treated as relocatable
* kernel, otherwise it will be moved to PHYSICAL_START
*/
+#if defined(CONFIG_PPC_BOOK3E)
+ tovirt(r26,r26) /* on booke, we already run at PAGE_OFFSET */
+#endif
lwz r7,__run_at_load-_stext(r26)
cmplwi cr0,r7,1
bne 3f
+#ifdef CONFIG_PPC_BOOK3E
+ LOAD_REG_ADDR(r5, __end_interrupts)
+ LOAD_REG_ADDR(r11, _stext)
+ sub r5,r5,r11
+#else
/* just copy interrupts */
LOAD_REG_IMMEDIATE(r5, __end_interrupts - _stext)
+#endif
b 5f
3:
#endif
@@ -514,9 +533,6 @@ __after_prom_start:
p_end: .llong _end - _stext
4: /* Now copy the rest of the kernel up to _end */
-#if defined(CONFIG_PPC_BOOK3E)
- tovirt(r26,r26)
-#endif
addis r5,r26,(p_end - _stext)@ha
ld r5,(p_end - _stext)@l(r5) /* get _end */
5: bl copy_and_flush /* copy the rest */
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 12/18] powerpc/book3e/kdump: Enable crash_kexec_wait_realmode
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (10 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 11/18] powerpc/book3e: support CONFIG_RELOCATABLE Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 13/18] powerpc/book3e-64: Don't limit paca to 256 MiB Scott Wood
` (5 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
While book3e doesn't have "real mode", we still want to wait for
all the non-crash cpus to complete their shutdown.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/kernel/crash.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 51dbace..2bb252c 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -221,8 +221,8 @@ void crash_kexec_secondary(struct pt_regs *regs)
#endif /* CONFIG_SMP */
/* wait for all the CPUs to hit real mode but timeout if they don't come in */
-#if defined(CONFIG_SMP) && defined(CONFIG_PPC_STD_MMU_64)
-static void crash_kexec_wait_realmode(int cpu)
+#if defined(CONFIG_SMP) && defined(CONFIG_PPC64)
+static void __maybe_unused crash_kexec_wait_realmode(int cpu)
{
unsigned int msecs;
int i;
@@ -244,7 +244,7 @@ static void crash_kexec_wait_realmode(int cpu)
}
#else
static inline void crash_kexec_wait_realmode(int cpu) {}
-#endif /* CONFIG_SMP && CONFIG_PPC_STD_MMU_64 */
+#endif /* CONFIG_SMP && CONFIG_PPC64 */
/*
* Register a function to be called on shutdown. Only use this if you
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 13/18] powerpc/book3e-64: Don't limit paca to 256 MiB
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (11 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 12/18] powerpc/book3e/kdump: Enable crash_kexec_wait_realmode Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-19 22:10 ` [PATCH v3 13/17] " Scott Wood
2015-10-07 3:48 ` [PATCH v2 14/18] powerpc/book3e-64/kexec: create an identity TLB mapping Scott Wood
` (4 subsequent siblings)
17 siblings, 1 reply; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
This limit only makes sense on book3s, and on book3e it can cause
problems with kdump if we don't have any memory under 256 MiB.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/kernel/paca.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 5a23b69..7fdff63 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -206,12 +206,16 @@ void __init allocate_pacas(void)
{
int cpu, limit;
+ limit = ppc64_rma_size;
+
+#ifdef CONFIG_PPC_BOOK3S_64
/*
* We can't take SLB misses on the paca, and we want to access them
* in real mode, so allocate them within the RMA and also within
* the first segment.
*/
- limit = min(0x10000000ULL, ppc64_rma_size);
+ limit = min(0x10000000ULL, limit);
+#endif
paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids);
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 14/18] powerpc/book3e-64/kexec: create an identity TLB mapping
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (12 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 13/18] powerpc/book3e-64: Don't limit paca to 256 MiB Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 15/18] powerpc/book3e-64/kexec: Enable SMP release Scott Wood
` (3 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev
Cc: Tiejun Chen, Michael Ellerman, kexec, Tiejun Chen, Scott Wood
From: Tiejun Chen <tiejun.chen@windriver.com>
book3e has no real MMU mode so we have to create an identity TLB
mapping to make sure we can access the real physical address.
Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
[scottwood: cleanup, and split off some changes]
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/kernel/misc_64.S | 52 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 51 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 6e4168c..246ad8c 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -26,6 +26,7 @@
#include <asm/thread_info.h>
#include <asm/kexec.h>
#include <asm/ptrace.h>
+#include <asm/mmu.h>
.text
@@ -496,6 +497,51 @@ kexec_flag:
#ifdef CONFIG_KEXEC
+#ifdef CONFIG_PPC_BOOK3E
+/*
+ * BOOK3E has no real MMU mode, so we have to setup the initial TLB
+ * for a core to identity map v:0 to p:0. This current implementation
+ * assumes that 1G is enough for kexec.
+ */
+kexec_create_tlb:
+ /*
+ * Invalidate all non-IPROT TLB entries to avoid any TLB conflict.
+ * IPROT TLB entries should be >= PAGE_OFFSET and thus not conflict.
+ */
+ PPC_TLBILX_ALL(0,R0)
+ sync
+ isync
+
+ mfspr r10,SPRN_TLB1CFG
+ andi. r10,r10,TLBnCFG_N_ENTRY /* Extract # entries */
+ subi r10,r10,1 /* Last entry: no conflict with kernel text */
+ lis r9,MAS0_TLBSEL(1)@h
+ rlwimi r9,r10,16,4,15 /* Setup MAS0 = TLBSEL | ESEL(r9) */
+
+/* Set up a temp identity mapping v:0 to p:0 and return to it. */
+#if defined(CONFIG_SMP) || defined(CONFIG_PPC_E500MC)
+#define M_IF_NEEDED MAS2_M
+#else
+#define M_IF_NEEDED 0
+#endif
+ mtspr SPRN_MAS0,r9
+
+ lis r9,(MAS1_VALID|MAS1_IPROT)@h
+ ori r9,r9,(MAS1_TSIZE(BOOK3E_PAGESZ_1GB))@l
+ mtspr SPRN_MAS1,r9
+
+ LOAD_REG_IMMEDIATE(r9, 0x0 | M_IF_NEEDED)
+ mtspr SPRN_MAS2,r9
+
+ LOAD_REG_IMMEDIATE(r9, 0x0 | MAS3_SR | MAS3_SW | MAS3_SX)
+ mtspr SPRN_MAS3,r9
+ li r9,0
+ mtspr SPRN_MAS7,r9
+
+ tlbwe
+ isync
+ blr
+#endif
/* kexec_smp_wait(void)
*
@@ -525,6 +571,10 @@ _GLOBAL(kexec_smp_wait)
* don't overwrite r3 here, it is live for kexec_wait above.
*/
real_mode: /* assume normal blr return */
+#ifdef CONFIG_PPC_BOOK3E
+ /* Create an identity mapping. */
+ b kexec_create_tlb
+#else
1: li r9,MSR_RI
li r10,MSR_DR|MSR_IR
mflr r11 /* return address to SRR0 */
@@ -536,7 +586,7 @@ real_mode: /* assume normal blr return */
mtspr SPRN_SRR1,r10
mtspr SPRN_SRR0,r11
rfid
-
+#endif
/*
* kexec_sequence(newstack, start, image, control, clear_all())
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 15/18] powerpc/book3e-64/kexec: Enable SMP release
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (13 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 14/18] powerpc/book3e-64/kexec: create an identity TLB mapping Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 16/18] powerpc/booke: Only use VIRT_PHYS_OFFSET on booke32 Scott Wood
` (2 subsequent siblings)
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood, devicetree
The SMP release mechanism for FSL book3e is different from when booting
with normal hardware. In theory we could simulate the normal spin
table mechanism, but not at the addresses U-Boot put in the device tree
-- so there'd need to be even more communication between the kernel and
kexec to set that up. Instead, kexec-tools will set a boolean property
linux,booted-from-kexec in the /chosen node.
Signed-off-by: Scott Wood <scottwood@freescale.com>
Cc: devicetree@vger.kernel.org
---
v2: Use a device tree property instead of a flag in the kernel image
This depends on the kexec-tools patch v2 "ppc64: Add a flag to tell the
kernel it's booting from kexec":
http://patchwork.ozlabs.org/patch/527050/
---
Documentation/devicetree/bindings/chosen.txt | 8 ++++++++
arch/powerpc/kernel/setup_64.c | 17 ++++++++++++++++-
2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/Documentation/devicetree/bindings/chosen.txt b/Documentation/devicetree/bindings/chosen.txt
index ed838f4..6ae9d82 100644
--- a/Documentation/devicetree/bindings/chosen.txt
+++ b/Documentation/devicetree/bindings/chosen.txt
@@ -44,3 +44,11 @@ Implementation note: Linux will look for the property "linux,stdout-path" or
on PowerPC "stdout" if "stdout-path" is not found. However, the
"linux,stdout-path" and "stdout" properties are deprecated. New platforms
should only use the "stdout-path" property.
+
+linux,booted-from-kexec
+-----------------------
+
+This property is set (currently only on PowerPC, and only needed on
+book3e) by some versions of kexec-tools to tell the new kernel that it
+is being booted by kexec, as the booting environment may differ (e.g.
+a different secondary CPU release mechanism)
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 505ec2c..5c03a6a 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -340,11 +340,26 @@ void early_setup_secondary(void)
#endif /* CONFIG_SMP */
#if defined(CONFIG_SMP) || defined(CONFIG_KEXEC)
+static bool use_spinloop(void)
+{
+ if (!IS_ENABLED(CONFIG_PPC_BOOK3E))
+ return true;
+
+ /*
+ * When book3e boots from kexec, the ePAPR spin table does
+ * not get used.
+ */
+ return of_property_read_bool(of_chosen, "linux,booted-from-kexec");
+}
+
void smp_release_cpus(void)
{
unsigned long *ptr;
int i;
+ if (!use_spinloop())
+ return;
+
DBG(" -> smp_release_cpus()\n");
/* All secondary cpus are spinning on a common spinloop, release them
@@ -524,7 +539,7 @@ void __init setup_system(void)
* Freescale Book3e parts spin in a loop provided by firmware,
* so smp_release_cpus() does nothing for them
*/
-#if defined(CONFIG_SMP) && !defined(CONFIG_PPC_FSL_BOOK3E)
+#if defined(CONFIG_SMP)
/* Release secondary cpus out of their spinloops at 0x60 now that
* we can map physical -> logical CPU ids
*/
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 16/18] powerpc/booke: Only use VIRT_PHYS_OFFSET on booke32
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (14 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 15/18] powerpc/book3e-64/kexec: Enable SMP release Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 17/18] powerpc/book3e-64/kexec: Set "r4 = 0" when entering spinloop Scott Wood
2015-10-07 3:48 ` [PATCH v2 18/18] powerpc/book3e-64: Enable kexec Scott Wood
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
The way VIRT_PHYS_OFFSET is not correct on book3e-64, because
it does not account for CONFIG_RELOCATABLE other than via the
32-bit-only virt_phys_offset.
book3e-64 can (and if the comment about a GCC miscompilation is still
relevant, should) use the normal ppc64 __va/__pa.
At this point, only booke-32 will use VIRT_PHYS_OFFSET, so given the
issues with its calculation, restrict its definition to booke-32.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/include/asm/page.h | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/include/asm/page.h b/arch/powerpc/include/asm/page.h
index 168ca67..6b67239 100644
--- a/arch/powerpc/include/asm/page.h
+++ b/arch/powerpc/include/asm/page.h
@@ -107,12 +107,13 @@ extern long long virt_phys_offset;
#endif
/* See Description below for VIRT_PHYS_OFFSET */
-#ifdef CONFIG_RELOCATABLE_PPC32
+#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
+#ifdef CONFIG_RELOCATABLE
#define VIRT_PHYS_OFFSET virt_phys_offset
#else
#define VIRT_PHYS_OFFSET (KERNELBASE - PHYSICAL_START)
#endif
-
+#endif
#ifdef CONFIG_PPC64
#define MEMORY_START 0UL
@@ -205,7 +206,7 @@ extern long long virt_phys_offset;
* On non-Book-E PPC64 PAGE_OFFSET and MEMORY_START are constants so use
* the other definitions for __va & __pa.
*/
-#ifdef CONFIG_BOOKE
+#if defined(CONFIG_PPC32) && defined(CONFIG_BOOKE)
#define __va(x) ((void *)(unsigned long)((phys_addr_t)(x) + VIRT_PHYS_OFFSET))
#define __pa(x) ((unsigned long)(x) - VIRT_PHYS_OFFSET)
#else
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 17/18] powerpc/book3e-64/kexec: Set "r4 = 0" when entering spinloop
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (15 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 16/18] powerpc/booke: Only use VIRT_PHYS_OFFSET on booke32 Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 18/18] powerpc/book3e-64: Enable kexec Scott Wood
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Tiejun Chen, Michael Ellerman, kexec, Scott Wood
book3e_secondary_core_init will only create a TLB entry if r4 = 0,
so do so.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/kernel/misc_64.S | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index 246ad8c..ddbc535 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -485,6 +485,8 @@ _GLOBAL(kexec_wait)
mtsrr1 r11
rfid
#else
+ /* Create TLB entry in book3e_secondary_core_init */
+ li r4,0
ba 0x60
#endif
#endif
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* [PATCH v2 18/18] powerpc/book3e-64: Enable kexec
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
` (16 preceding siblings ...)
2015-10-07 3:48 ` [PATCH v2 17/18] powerpc/book3e-64/kexec: Set "r4 = 0" when entering spinloop Scott Wood
@ 2015-10-07 3:48 ` Scott Wood
17 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 3:48 UTC (permalink / raw)
To: linuxppc-dev
Cc: Tiejun Chen, Michael Ellerman, kexec, Tiejun Chen, Scott Wood
From: Tiejun Chen <tiejun.chen@windriver.com>
Allow KEXEC for book3e, and bypass or convert non-book3e stuff
in kexec code.
Signed-off-by: Tiejun Chen <tiejun.chen@windriver.com>
[scottwood@freescale.com: move code to minimize diff, and cleanup]
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
arch/powerpc/Kconfig | 2 +-
arch/powerpc/kernel/machine_kexec_64.c | 18 ++++++++++++++++++
arch/powerpc/kernel/misc_64.S | 6 ++++++
3 files changed, 25 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9a7057e..db49e0d 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -419,7 +419,7 @@ config PPC64_SUPPORTS_MEMORY_FAILURE
config KEXEC
bool "kexec system call"
- depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP))
+ depends on (PPC_BOOK3S || FSL_BOOKE || (44x && !SMP)) || PPC_BOOK3E
select KEXEC_CORE
help
kexec is a system call that implements the ability to shutdown your
diff --git a/arch/powerpc/kernel/machine_kexec_64.c b/arch/powerpc/kernel/machine_kexec_64.c
index 1a74446..0fbd75d 100644
--- a/arch/powerpc/kernel/machine_kexec_64.c
+++ b/arch/powerpc/kernel/machine_kexec_64.c
@@ -30,6 +30,21 @@
#include <asm/smp.h>
#include <asm/hw_breakpoint.h>
+#ifdef CONFIG_PPC_BOOK3E
+int default_machine_kexec_prepare(struct kimage *image)
+{
+ int i;
+ /*
+ * Since we use the kernel fault handlers and paging code to
+ * handle the virtual mode, we must make sure no destination
+ * overlaps kernel static data or bss.
+ */
+ for (i = 0; i < image->nr_segments; i++)
+ if (image->segment[i].mem < __pa(_end))
+ return -ETXTBSY;
+ return 0;
+}
+#else
int default_machine_kexec_prepare(struct kimage *image)
{
int i;
@@ -95,6 +110,7 @@ int default_machine_kexec_prepare(struct kimage *image)
return 0;
}
+#endif /* !CONFIG_PPC_BOOK3E */
static void copy_segments(unsigned long ind)
{
@@ -365,6 +381,7 @@ void default_machine_kexec(struct kimage *image)
/* NOTREACHED */
}
+#ifndef CONFIG_PPC_BOOK3E
/* Values we need to export to the second kernel via the device tree. */
static unsigned long htab_base;
static unsigned long htab_size;
@@ -411,3 +428,4 @@ static int __init export_htab_values(void)
return 0;
}
late_initcall(export_htab_values);
+#endif /* !CONFIG_PPC_BOOK3E */
diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S
index ddbc535..db475d4 100644
--- a/arch/powerpc/kernel/misc_64.S
+++ b/arch/powerpc/kernel/misc_64.S
@@ -631,9 +631,13 @@ _GLOBAL(kexec_sequence)
lhz r25,PACAHWCPUID(r13) /* get our phys cpu from paca */
/* disable interrupts, we are overwriting kernel data next */
+#ifdef CONFIG_PPC_BOOK3E
+ wrteei 0
+#else
mfmsr r3
rlwinm r3,r3,0,17,15
mtmsrd r3,1
+#endif
/* copy dest pages, flush whole dest image */
mr r3,r29
@@ -655,6 +659,7 @@ _GLOBAL(kexec_sequence)
li r6,1
stw r6,kexec_flag-1b(5)
+#ifndef CONFIG_PPC_BOOK3E
/* clear out hardware hash page table and tlb */
#if !defined(_CALL_ELF) || _CALL_ELF != 2
ld r12,0(r27) /* deref function descriptor */
@@ -663,6 +668,7 @@ _GLOBAL(kexec_sequence)
#endif
mtctr r12
bctrl /* ppc_md.hpte_clear_all(void); */
+#endif /* !CONFIG_PPC_BOOK3E */
/*
* kexec image calling is:
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
* Re: [PATCH v2 05/18] powerpc/85xx: Load all early TLB entries at once
2015-10-07 3:48 ` [PATCH v2 05/18] powerpc/85xx: Load all early TLB entries at once Scott Wood
@ 2015-10-07 14:00 ` Laurentiu Tudor
2015-10-07 19:57 ` Scott Wood
0 siblings, 1 reply; 22+ messages in thread
From: Laurentiu Tudor @ 2015-10-07 14:00 UTC (permalink / raw)
To: Scott Wood, linuxppc-dev; +Cc: Tiejun Chen, kexec
On 10/07/2015 06:48 AM, Scott Wood wrote:
> Use an AS=1 trampoline TLB entry to allow all normal TLB1 entries to
> be loaded at once. This avoids the need to keep the translation that
> code is executing from in the same TLB entry in the final TLB
> configuration as during early boot, which in turn is helpful for
> relocatable kernels (e.g. kdump) where the kernel is not running from
> what would be the first TLB entry.
>
> On e6500, we limit map_mem_in_cams() to the primary hwthread of a
> core (the boot cpu is always considered primary, as a kdump kernel
> can be entered on any cpu). Each TLB only needs to be set up once,
> and when we do, we don't want another thread to be running when we
> create a temporary trampoline TLB1 entry.
>
> Signed-off-by: Scott Wood <scottwood@freescale.com>
> ---
> arch/powerpc/kernel/setup_64.c | 8 +++++
> arch/powerpc/mm/fsl_booke_mmu.c | 15 ++++++++--
> arch/powerpc/mm/mmu_decl.h | 1 +
> arch/powerpc/mm/tlb_nohash.c | 19 +++++++++++-
> arch/powerpc/mm/tlb_nohash_low.S | 63 ++++++++++++++++++++++++++++++++++++++++
> 5 files changed, 102 insertions(+), 4 deletions(-)
>
> diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
> index bdcbb71..505ec2c 100644
> --- a/arch/powerpc/kernel/setup_64.c
> +++ b/arch/powerpc/kernel/setup_64.c
> @@ -108,6 +108,14 @@ static void setup_tlb_core_data(void)
> for_each_possible_cpu(cpu) {
> int first = cpu_first_thread_sibling(cpu);
>
> + /*
> + * If we boot via kdump on a non-primary thread,
> + * make sure we point at the thread that actually
> + * set up this TLB.
> + */
> + if (cpu_first_thread_sibling(boot_cpuid) == first)
> + first = boot_cpuid;
> +
> paca[cpu].tcd_ptr = &paca[first].tcd;
>
> /*
> diff --git a/arch/powerpc/mm/fsl_booke_mmu.c b/arch/powerpc/mm/fsl_booke_mmu.c
> index 354ba3c..36d3c55 100644
> --- a/arch/powerpc/mm/fsl_booke_mmu.c
> +++ b/arch/powerpc/mm/fsl_booke_mmu.c
> @@ -105,8 +105,9 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
> * an unsigned long (for example, 32-bit implementations cannot support a 4GB
> * size).
> */
> -static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
> - unsigned long size, unsigned long flags, unsigned int pid)
> +static void preptlbcam(int index, unsigned long virt, phys_addr_t phys,
> + unsigned long size, unsigned long flags,
> + unsigned int pid)
> {
> unsigned int tsize;
>
> @@ -141,7 +142,13 @@ static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
> tlbcam_addrs[index].start = virt;
> tlbcam_addrs[index].limit = virt + size - 1;
> tlbcam_addrs[index].phys = phys;
> +}
>
> +void settlbcam(int index, unsigned long virt, phys_addr_t phys,
Nit: shouldn't this be left static? Also, now with this bulk TLB1 loading is it still used? Maybe it can be dropped.
---
Best Regards, Laurentiu
^ permalink raw reply [flat|nested] 22+ messages in thread
* Re: [PATCH v2 05/18] powerpc/85xx: Load all early TLB entries at once
2015-10-07 14:00 ` Laurentiu Tudor
@ 2015-10-07 19:57 ` Scott Wood
0 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-07 19:57 UTC (permalink / raw)
To: Laurentiu Tudor; +Cc: linuxppc-dev, Tiejun Chen, kexec
On Wed, 2015-10-07 at 17:00 +0300, Laurentiu Tudor wrote:
> On 10/07/2015 06:48 AM, Scott Wood wrote:
> > Use an AS=1 trampoline TLB entry to allow all normal TLB1 entries to
> > be loaded at once. This avoids the need to keep the translation that
> > code is executing from in the same TLB entry in the final TLB
> > configuration as during early boot, which in turn is helpful for
> > relocatable kernels (e.g. kdump) where the kernel is not running from
> > what would be the first TLB entry.
> >
> > On e6500, we limit map_mem_in_cams() to the primary hwthread of a
> > core (the boot cpu is always considered primary, as a kdump kernel
> > can be entered on any cpu). Each TLB only needs to be set up once,
> > and when we do, we don't want another thread to be running when we
> > create a temporary trampoline TLB1 entry.
> >
> > Signed-off-by: Scott Wood <scottwood@freescale.com>
> > ---
> > arch/powerpc/kernel/setup_64.c | 8 +++++
> > arch/powerpc/mm/fsl_booke_mmu.c | 15 ++++++++--
> > arch/powerpc/mm/mmu_decl.h | 1 +
> > arch/powerpc/mm/tlb_nohash.c | 19 +++++++++++-
> > arch/powerpc/mm/tlb_nohash_low.S | 63
> > ++++++++++++++++++++++++++++++++++++++++
> > 5 files changed, 102 insertions(+), 4 deletions(-)
> >
> > diff --git a/arch/powerpc/kernel/setup_64.c
> > b/arch/powerpc/kernel/setup_64.c
> > index bdcbb71..505ec2c 100644
> > --- a/arch/powerpc/kernel/setup_64.c
> > +++ b/arch/powerpc/kernel/setup_64.c
> > @@ -108,6 +108,14 @@ static void setup_tlb_core_data(void)
> > for_each_possible_cpu(cpu) {
> > int first = cpu_first_thread_sibling(cpu);
> >
> > + /*
> > + * If we boot via kdump on a non-primary thread,
> > + * make sure we point at the thread that actually
> > + * set up this TLB.
> > + */
> > + if (cpu_first_thread_sibling(boot_cpuid) == first)
> > + first = boot_cpuid;
> > +
> > paca[cpu].tcd_ptr = &paca[first].tcd;
> >
> > /*
> > diff --git a/arch/powerpc/mm/fsl_booke_mmu.c
> > b/arch/powerpc/mm/fsl_booke_mmu.c
> > index 354ba3c..36d3c55 100644
> > --- a/arch/powerpc/mm/fsl_booke_mmu.c
> > +++ b/arch/powerpc/mm/fsl_booke_mmu.c
> > @@ -105,8 +105,9 @@ unsigned long p_mapped_by_tlbcam(phys_addr_t pa)
> > * an unsigned long (for example, 32-bit implementations cannot support a
> > 4GB
> > * size).
> > */
> > -static void settlbcam(int index, unsigned long virt, phys_addr_t phys,
> > - unsigned long size, unsigned long flags, unsigned int pid)
> > +static void preptlbcam(int index, unsigned long virt, phys_addr_t phys,
> > + unsigned long size, unsigned long flags,
> > + unsigned int pid)
> > {
> > unsigned int tsize;
> >
> > @@ -141,7 +142,13 @@ static void settlbcam(int index, unsigned long virt,
> > phys_addr_t phys,
> > tlbcam_addrs[index].start = virt;
> > tlbcam_addrs[index].limit = virt + size - 1;
> > tlbcam_addrs[index].phys = phys;
> > +}
> >
> > +void settlbcam(int index, unsigned long virt, phys_addr_t phys,
>
>
> Nit: shouldn't this be left static? Also, now with this bulk TLB1 loading
> is it still used? Maybe it can be dropped.
You're right, it's an unneeded leftover. We might as well
s/preptlbcam/settlbcam/ as well to reduce churn.
-Scott
^ permalink raw reply [flat|nested] 22+ messages in thread
* [PATCH v3 13/17] powerpc/book3e-64: Don't limit paca to 256 MiB
2015-10-07 3:48 ` [PATCH v2 13/18] powerpc/book3e-64: Don't limit paca to 256 MiB Scott Wood
@ 2015-10-19 22:10 ` Scott Wood
0 siblings, 0 replies; 22+ messages in thread
From: Scott Wood @ 2015-10-19 22:10 UTC (permalink / raw)
To: linuxppc-dev; +Cc: kexec, Scott Wood
This limit only makes sense on book3s, and on book3e it can cause
problems with kdump if we don't have any memory under 256 MiB.
Signed-off-by: Scott Wood <scottwood@freescale.com>
---
v3: Fix book3s build error
arch/powerpc/kernel/paca.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/paca.c b/arch/powerpc/kernel/paca.c
index 5a23b69..01ea0ed 100644
--- a/arch/powerpc/kernel/paca.c
+++ b/arch/powerpc/kernel/paca.c
@@ -204,14 +204,19 @@ static int __initdata paca_size;
void __init allocate_pacas(void)
{
- int cpu, limit;
+ u64 limit;
+ int cpu;
+ limit = ppc64_rma_size;
+
+#ifdef CONFIG_PPC_BOOK3S_64
/*
* We can't take SLB misses on the paca, and we want to access them
* in real mode, so allocate them within the RMA and also within
* the first segment.
*/
- limit = min(0x10000000ULL, ppc64_rma_size);
+ limit = min(0x10000000ULL, limit);
+#endif
paca_size = PAGE_ALIGN(sizeof(struct paca_struct) * nr_cpu_ids);
--
2.1.4
^ permalink raw reply related [flat|nested] 22+ messages in thread
end of thread, other threads:[~2015-10-19 22:10 UTC | newest]
Thread overview: 22+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-10-07 3:48 [PATCH v2 00/18] powerpc/fsl-book3e-64: kexec/kdump support Scott Wood
2015-10-07 3:48 ` [PATCH v2 01/18] powerpc/fsl-booke-64: Allow booting from the secondary thread Scott Wood
2015-10-07 3:48 ` [PATCH v2 02/18] powerpc/fsl-corenet: Disable coreint if kexec is enabled Scott Wood
2015-10-07 3:48 ` [PATCH v2 03/18] powerpc/85xx: Don't use generic timebase sync on 64-bit Scott Wood
2015-10-07 3:48 ` [PATCH v2 04/18] powerpc/fsl_pci: Don't set up inbound windows in kdump crash kernel Scott Wood
2015-10-07 3:48 ` [PATCH v2 05/18] powerpc/85xx: Load all early TLB entries at once Scott Wood
2015-10-07 14:00 ` Laurentiu Tudor
2015-10-07 19:57 ` Scott Wood
2015-10-07 3:48 ` [PATCH v2 06/18] powerpc/fsl-booke-64: Don't limit ppc64_rma_size to one TLB entry Scott Wood
2015-10-07 3:48 ` [PATCH v2 07/18] powerpc/85xx: Implement 64-bit kexec support Scott Wood
2015-10-07 3:48 ` [PATCH v2 08/18] powerpc/e6500: kexec: Handle hardware threads Scott Wood
2015-10-07 3:48 ` [PATCH v2 09/18] powerpc/book3e-64: rename interrupt_end_book3e with __end_interrupts Scott Wood
2015-10-07 3:48 ` [PATCH v2 10/18] powerpc/booke64: Fix args to copy_and_flush Scott Wood
2015-10-07 3:48 ` [PATCH v2 11/18] powerpc/book3e: support CONFIG_RELOCATABLE Scott Wood
2015-10-07 3:48 ` [PATCH v2 12/18] powerpc/book3e/kdump: Enable crash_kexec_wait_realmode Scott Wood
2015-10-07 3:48 ` [PATCH v2 13/18] powerpc/book3e-64: Don't limit paca to 256 MiB Scott Wood
2015-10-19 22:10 ` [PATCH v3 13/17] " Scott Wood
2015-10-07 3:48 ` [PATCH v2 14/18] powerpc/book3e-64/kexec: create an identity TLB mapping Scott Wood
2015-10-07 3:48 ` [PATCH v2 15/18] powerpc/book3e-64/kexec: Enable SMP release Scott Wood
2015-10-07 3:48 ` [PATCH v2 16/18] powerpc/booke: Only use VIRT_PHYS_OFFSET on booke32 Scott Wood
2015-10-07 3:48 ` [PATCH v2 17/18] powerpc/book3e-64/kexec: Set "r4 = 0" when entering spinloop Scott Wood
2015-10-07 3:48 ` [PATCH v2 18/18] powerpc/book3e-64: Enable kexec Scott Wood
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).