From fd615f69a18a9d4aa5ef02a1dc83f319f75da8e7 Mon Sep 17 00:00:00 2001 From: LiuHailong Date: Tue, 7 Feb 2017 10:35:52 +0800 Subject: [PATCH 1/9] powerpc/64e: Fix hang when debugging programs with relocated kernel Debug interrupts can be taken during interrupt entry, since interrupt entry does not automatically turn them off. The kernel will check whether the faulting instruction is between [interrupt_base_book3e, __end_interrupts], and if so clear MSR[DE] and return. However, when the kernel is built with CONFIG_RELOCATABLE, it can't use LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) and LOAD_REG_IMMEDIATE(r15,__end_interrupts), as they ignore relocation. Thus, if the kernel is actually running at a different address than it was built at, the address comparison will fail, and the exception entry code will hang at kernel_dbg_exc. r2(toc) is also not usable here, as r2 still holds data from the interrupted context, so LOAD_REG_ADDR() doesn't work either. So we use the *name@got* to get the EV of two labels directly. Test programs test.c shows as follows: int main(int argc, char *argv[]) { if (access("/proc/sys/kernel/perf_event_paranoid", F_OK) == -1) printf("Kernel doesn't have perf_event support\n"); } Steps to reproduce the bug, for example: 1) ./gdb ./test 2) (gdb) b access 3) (gdb) r 4) (gdb) s Signed-off-by: Liu Hailong Signed-off-by: Jiang Xuexin Reviewed-by: Jiang Biao Reviewed-by: Liu Song Reviewed-by: Huang Jian [scottwood: cleaned up commit message, and specified bad behavior as a hang rather than an oops to correspond to mainline kernel behavior] Fixes: 1cb6e0649248 ("powerpc/book3e: support CONFIG_RELOCATABLE") Cc: # 4.4.x- Signed-off-by: Scott Wood --- arch/powerpc/kernel/exceptions-64e.S | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/arch/powerpc/kernel/exceptions-64e.S b/arch/powerpc/kernel/exceptions-64e.S index 45b453e4d0c8..acd8ca76233e 100644 --- a/arch/powerpc/kernel/exceptions-64e.S +++ b/arch/powerpc/kernel/exceptions-64e.S @@ -735,8 +735,14 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) andis. r15,r14,(DBSR_IC|DBSR_BT)@h beq+ 1f +#ifdef CONFIG_RELOCATABLE + ld r15,PACATOC(r13) + ld r14,interrupt_base_book3e@got(r15) + ld r15,__end_interrupts@got(r15) +#else LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) LOAD_REG_IMMEDIATE(r15,__end_interrupts) +#endif cmpld cr0,r10,r14 cmpld cr1,r10,r15 blt+ cr0,1f @@ -799,8 +805,14 @@ kernel_dbg_exc: andis. r15,r14,(DBSR_IC|DBSR_BT)@h beq+ 1f +#ifdef CONFIG_RELOCATABLE + ld r15,PACATOC(r13) + ld r14,interrupt_base_book3e@got(r15) + ld r15,__end_interrupts@got(r15) +#else LOAD_REG_IMMEDIATE(r14,interrupt_base_book3e) LOAD_REG_IMMEDIATE(r15,__end_interrupts) +#endif cmpld cr0,r10,r14 cmpld cr1,r10,r15 blt+ cr0,1f From 8b8642af15ed14b9a7a34d3401afbcc274533e13 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 7 Feb 2017 10:05:09 +0100 Subject: [PATCH 2/9] net: ethernet: ucc_geth: fix MEM_PART_MURAM mode Since commit 5093bb965a163 ("powerpc/QE: switch to the cpm_muram implementation"), muram area is not part of immrbar mapping anymore so immrbar_virt_to_phys() is not usable anymore. Fixes: 5093bb965a163 ("powerpc/QE: switch to the cpm_muram implementation") Signed-off-by: Christophe Leroy Acked-by: David S. Miller Acked-by: Li Yang Signed-off-by: Scott Wood --- drivers/net/ethernet/freescale/ucc_geth.c | 8 +++----- include/soc/fsl/qe/qe.h | 1 + 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/drivers/net/ethernet/freescale/ucc_geth.c b/drivers/net/ethernet/freescale/ucc_geth.c index 3f7ae9f64cd8..f77ba9fa257b 100644 --- a/drivers/net/ethernet/freescale/ucc_geth.c +++ b/drivers/net/ethernet/freescale/ucc_geth.c @@ -2594,11 +2594,10 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } else if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_MURAM) { out_be32(&ugeth->p_send_q_mem_reg->sqqd[i].bd_ring_base, - (u32) immrbar_virt_to_phys(ugeth-> - p_tx_bd_ring[i])); + (u32)qe_muram_dma(ugeth->p_tx_bd_ring[i])); out_be32(&ugeth->p_send_q_mem_reg->sqqd[i]. last_bd_completed_address, - (u32) immrbar_virt_to_phys(endOfRing)); + (u32)qe_muram_dma(endOfRing)); } } @@ -2844,8 +2843,7 @@ static int ucc_geth_startup(struct ucc_geth_private *ugeth) } else if (ugeth->ug_info->uf_info.bd_mem_part == MEM_PART_MURAM) { out_be32(&ugeth->p_rx_bd_qs_tbl[i].externalbdbaseptr, - (u32) immrbar_virt_to_phys(ugeth-> - p_rx_bd_ring[i])); + (u32)qe_muram_dma(ugeth->p_rx_bd_ring[i])); } /* rest of fields handled by QE */ } diff --git a/include/soc/fsl/qe/qe.h b/include/soc/fsl/qe/qe.h index 70339d7958c0..0cd4c11479b1 100644 --- a/include/soc/fsl/qe/qe.h +++ b/include/soc/fsl/qe/qe.h @@ -243,6 +243,7 @@ static inline int qe_alive_during_sleep(void) #define qe_muram_free cpm_muram_free #define qe_muram_addr cpm_muram_addr #define qe_muram_offset cpm_muram_offset +#define qe_muram_dma cpm_muram_dma #define qe_setbits32(_addr, _v) iowrite32be(ioread32be(_addr) | (_v), (_addr)) #define qe_clrbits32(_addr, _v) iowrite32be(ioread32be(_addr) & ~(_v), (_addr)) From b54ea82f01282253c85eb7e2fd2b6c96f7a027d8 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 7 Feb 2017 10:05:11 +0100 Subject: [PATCH 3/9] soc/fsl/qe: get rid of immrbar_virt_to_phys() immrbar_virt_to_phys() is not used anymore Signed-off-by: Christophe Leroy Acked-by: Li Yang Signed-off-by: Scott Wood --- drivers/soc/fsl/qe/qe.c | 4 +--- include/soc/fsl/qe/immap_qe.h | 19 ------------------- 2 files changed, 1 insertion(+), 22 deletions(-) diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index ade168f5328e..d9c04f588f7f 100644 --- a/drivers/soc/fsl/qe/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -66,7 +66,7 @@ static unsigned int qe_num_of_snum; static phys_addr_t qebase = -1; -phys_addr_t get_qe_base(void) +static phys_addr_t get_qe_base(void) { struct device_node *qe; int ret; @@ -90,8 +90,6 @@ phys_addr_t get_qe_base(void) return qebase; } -EXPORT_SYMBOL(get_qe_base); - void qe_reset(void) { if (qe_immr == NULL) diff --git a/include/soc/fsl/qe/immap_qe.h b/include/soc/fsl/qe/immap_qe.h index c76ef30b05ba..7baaabd5ec2c 100644 --- a/include/soc/fsl/qe/immap_qe.h +++ b/include/soc/fsl/qe/immap_qe.h @@ -464,25 +464,6 @@ struct qe_immap { } __attribute__ ((packed)); extern struct qe_immap __iomem *qe_immr; -extern phys_addr_t get_qe_base(void); - -/* - * Returns the offset within the QE address space of the given pointer. - * - * Note that the QE does not support 36-bit physical addresses, so if - * get_qe_base() returns a number above 4GB, the caller will probably fail. - */ -static inline phys_addr_t immrbar_virt_to_phys(void *address) -{ - void *q = (void *)qe_immr; - - /* Is it a MURAM address? */ - if ((address >= q) && (address < (q + QE_IMMAP_SIZE))) - return get_qe_base() + (address - q); - - /* It's an address returned by kmalloc */ - return virt_to_phys(address); -} #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_IMMAP_QE_H */ From 2ccf80b7566cc035d903dd0ac5d7ebd25c2c1060 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 17 Feb 2017 11:29:45 +0100 Subject: [PATCH 4/9] soc/fsl/qe: round brg_freq to 1kHz granularity Because of integer computation rounding in u-boot (that sets the QE brg-frequency DTS prop), the clk value is 99999999 Hz even though it is 100 MHz. When setting brg clks that are exact divisors of 100 MHz, this small differnce plays a role and can result in lower clks to be output (for instance 20 MHz - divide by 5 - results in 16.666 MHz - divide by 6). This patch fixes that by "forcing" the brg_clk to the nearest kHz when the difference is below 2 integer rounding errors (i.e. 4). Signed-off-by: Valentin Longchamp Signed-off-by: Scott Wood --- drivers/soc/fsl/qe/qe.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index d9c04f588f7f..31a094573a9d 100644 --- a/drivers/soc/fsl/qe/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -161,11 +161,15 @@ EXPORT_SYMBOL(qe_issue_cmd); */ static unsigned int brg_clk = 0; +#define CLK_GRAN (1000) +#define CLK_GRAN_LIMIT (5) + unsigned int qe_get_brg_clk(void) { struct device_node *qe; int size; const u32 *prop; + unsigned int mod; if (brg_clk) return brg_clk; @@ -183,6 +187,15 @@ unsigned int qe_get_brg_clk(void) of_node_put(qe); + /* round this if near to a multiple of CLK_GRAN */ + mod = brg_clk % CLK_GRAN; + if (mod) { + if (mod < CLK_GRAN_LIMIT) + brg_clk -= mod; + else if (mod > (CLK_GRAN - CLK_GRAN_LIMIT)) + brg_clk += CLK_GRAN - mod; + } + return brg_clk; } EXPORT_SYMBOL(qe_get_brg_clk); From e5c5c8d23fef2a976afe724f30e34da31be09769 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 17 Feb 2017 11:29:46 +0100 Subject: [PATCH 5/9] soc/fsl/qe: only apply QE_General4 workaround on affected SoCs The QE_General4 workaround is only valid for the MPC832x and MPC836x SoCs. The other SoCs that embed a QUICC engine are not affected by this hardware bug and thus can use the computed divisors (this was successfully tested on the T1040). Similalry to what was done in commit 8ce795cb0c6b ("i2c: mpc: assign the correct prescaler from SVR") in order to avoid changes in the device tree nodes of the QE (with maybe a variant of the compatible property), the PVR reg is read out to find out if the workaround must be applied or not. Signed-off-by: Valentin Longchamp Signed-off-by: Scott Wood --- drivers/soc/fsl/qe/qe.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/soc/fsl/qe/qe.c b/drivers/soc/fsl/qe/qe.c index 31a094573a9d..2ef6fc6487c1 100644 --- a/drivers/soc/fsl/qe/qe.c +++ b/drivers/soc/fsl/qe/qe.c @@ -200,6 +200,9 @@ unsigned int qe_get_brg_clk(void) } EXPORT_SYMBOL(qe_get_brg_clk); +#define PVR_VER_836x 0x8083 +#define PVR_VER_832x 0x8084 + /* Program the BRG to the given sampling rate and multiplier * * @brg: the BRG, QE_BRG1 - QE_BRG16 @@ -226,8 +229,9 @@ int qe_setbrg(enum qe_clock brg, unsigned int rate, unsigned int multiplier) /* Errata QE_General4, which affects some MPC832x and MPC836x SOCs, says that the BRG divisor must be even if you're not using divide-by-16 mode. */ - if (!div16 && (divisor & 1) && (divisor > 3)) - divisor++; + if (pvr_version_is(PVR_VER_836x) || pvr_version_is(PVR_VER_832x)) + if (!div16 && (divisor & 1) && (divisor > 3)) + divisor++; tempval = ((divisor - 1) << QE_BRGC_DIVISOR_SHIFT) | QE_BRGC_ENABLE | div16; From 4ba251626ff1ac3447f9a05ecfcec7f85b6c8a91 Mon Sep 17 00:00:00 2001 From: Valentin Longchamp Date: Fri, 17 Feb 2017 11:29:47 +0100 Subject: [PATCH 6/9] soc/fsl/qe: add EXPORT_SYMBOL for the 2 qe_tdm functions This allows to build the fsl_ucc_hdlc driver as a module. Signed-off-by: Valentin Longchamp Signed-off-by: Scott Wood --- drivers/soc/fsl/qe/qe_tdm.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/soc/fsl/qe/qe_tdm.c b/drivers/soc/fsl/qe/qe_tdm.c index a1048b44e6b9..f744c214f680 100644 --- a/drivers/soc/fsl/qe/qe_tdm.c +++ b/drivers/soc/fsl/qe/qe_tdm.c @@ -177,6 +177,7 @@ err_miss_siram_property: devm_iounmap(&pdev->dev, utdm->si_regs); return ret; } +EXPORT_SYMBOL(ucc_of_parse_tdm); void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info) { @@ -274,3 +275,4 @@ void ucc_tdm_init(struct ucc_tdm *utdm, struct ucc_tdm_info *ut_info) break; } } +EXPORT_SYMBOL(ucc_tdm_init); From e21c7316d8ddcf1fd679591d1427e937999a7cf5 Mon Sep 17 00:00:00 2001 From: Roy Pledge Date: Mon, 17 Apr 2017 16:55:19 -0400 Subject: [PATCH 7/9] soc/fsl/qbman: Disable IRQs for deferred QBMan work Work for Congestion State Notifications (CSCN) and Message Ring (MR) handling is handled via the workqueue mechanism. This requires the driver to disable those IRQs before scheduling the work and re-enabling it once the work is completed so that the interrupt doesn't continually fire. Signed-off-by: Roy Pledge Signed-off-by: Scott Wood --- drivers/soc/fsl/qbman/qman.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/drivers/soc/fsl/qbman/qman.c b/drivers/soc/fsl/qbman/qman.c index 6f509f68085e..2827a65aa25a 100644 --- a/drivers/soc/fsl/qbman/qman.c +++ b/drivers/soc/fsl/qbman/qman.c @@ -1344,6 +1344,7 @@ static void qm_congestion_task(struct work_struct *work) if (!qm_mc_result_timeout(&p->p, &mcr)) { spin_unlock(&p->cgr_lock); dev_crit(p->config->dev, "QUERYCONGESTION timeout\n"); + qman_p_irqsource_add(p, QM_PIRQ_CSCI); return; } /* mask out the ones I'm not interested in */ @@ -1358,6 +1359,7 @@ static void qm_congestion_task(struct work_struct *work) if (cgr->cb && qman_cgrs_get(&c, cgr->cgrid)) cgr->cb(p, cgr, qman_cgrs_get(&rr, cgr->cgrid)); spin_unlock(&p->cgr_lock); + qman_p_irqsource_add(p, QM_PIRQ_CSCI); } static void qm_mr_process_task(struct work_struct *work) @@ -1417,12 +1419,14 @@ static void qm_mr_process_task(struct work_struct *work) } qm_mr_cci_consume(&p->p, num); + qman_p_irqsource_add(p, QM_PIRQ_MRI); preempt_enable(); } static u32 __poll_portal_slow(struct qman_portal *p, u32 is) { if (is & QM_PIRQ_CSCI) { + qman_p_irqsource_remove(p, QM_PIRQ_CSCI); queue_work_on(smp_processor_id(), qm_portal_wq, &p->congestion_work); } @@ -1434,6 +1438,7 @@ static u32 __poll_portal_slow(struct qman_portal *p, u32 is) } if (is & QM_PIRQ_MRI) { + qman_p_irqsource_remove(p, QM_PIRQ_MRI); queue_work_on(smp_processor_id(), qm_portal_wq, &p->mr_work); } From 726bd223105c04f7bf5eacdc2540819c301061f7 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 1 May 2017 09:38:13 +0200 Subject: [PATCH 8/9] powerpc/8xx: Adding support of IRQ in MPC8xx GPIO This patch allows the use of IRQ to notify the change of GPIO status on MPC8xx CPM IO ports. This then allows to associate IRQs to GPIOs in the Device Tree. Ex: CPM1_PIO_C: gpio-controller@960 { #gpio-cells = <2>; compatible = "fsl,cpm1-pario-bank-c"; reg = <0x960 0x10>; fsl,cpm1-gpio-irq-mask = <0x0fff>; interrupts = <1 2 6 9 10 11 14 15 23 24 26 31>; interrupt-parent = <&CPM_PIC>; gpio-controller; }; The property 'fsl,cpm1-gpio-irq-mask' defines which of the 16 GPIOs have the associated interrupts defined in the 'interrupts' property. Signed-off-by: Christophe Leroy Signed-off-by: Scott Wood --- .../bindings/soc/fsl/cpm_qe/gpio.txt | 21 +++++++++++++++- arch/powerpc/include/asm/cpm1.h | 2 ++ arch/powerpc/sysdev/cpm1.c | 25 +++++++++++++++++++ 3 files changed, 47 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/gpio.txt b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/gpio.txt index 349f79fd7076..626e1afa64a6 100644 --- a/Documentation/devicetree/bindings/soc/fsl/cpm_qe/gpio.txt +++ b/Documentation/devicetree/bindings/soc/fsl/cpm_qe/gpio.txt @@ -13,8 +13,17 @@ Required properties: - #gpio-cells : Should be two. The first cell is the pin number and the second cell is used to specify optional parameters (currently unused). - gpio-controller : Marks the port as GPIO controller. +Optional properties: +- fsl,cpm1-gpio-irq-mask : For banks having interrupt capability (like port C + on CPM1), this item tells which ports have an associated interrupt (ports are + listed in the same order as in PCINT register) +- interrupts : This property provides the list of interrupt for each GPIO having + one as described by the fsl,cpm1-gpio-irq-mask property. There should be as + many interrupts as number of ones in the mask property. The first interrupt in + the list corresponds to the most significant bit of the mask. +- interrupt-parent : Parent for the above interrupt property. -Example of three SOC GPIO banks defined as gpio-controller nodes: +Example of four SOC GPIO banks defined as gpio-controller nodes: CPM1_PIO_A: gpio-controller@950 { #gpio-cells = <2>; @@ -30,6 +39,16 @@ Example of three SOC GPIO banks defined as gpio-controller nodes: gpio-controller; }; + CPM1_PIO_C: gpio-controller@960 { + #gpio-cells = <2>; + compatible = "fsl,cpm1-pario-bank-c"; + reg = <0x960 0x10>; + fsl,cpm1-gpio-irq-mask = <0x0fff>; + interrupts = <1 2 6 9 10 11 14 15 23 24 26 31>; + interrupt-parent = <&CPM_PIC>; + gpio-controller; + }; + CPM1_PIO_E: gpio-controller@ac8 { #gpio-cells = <2>; compatible = "fsl,cpm1-pario-bank-e"; diff --git a/arch/powerpc/include/asm/cpm1.h b/arch/powerpc/include/asm/cpm1.h index 8ee4211ca0c6..14ad37865000 100644 --- a/arch/powerpc/include/asm/cpm1.h +++ b/arch/powerpc/include/asm/cpm1.h @@ -560,6 +560,8 @@ typedef struct risc_timer_pram { #define CPM_PIN_SECONDARY 2 #define CPM_PIN_GPIO 4 #define CPM_PIN_OPENDRAIN 8 +#define CPM_PIN_FALLEDGE 16 +#define CPM_PIN_ANYEDGE 0 enum cpm_port { CPM_PORTA, diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c index 986cd111d4df..c651e668996b 100644 --- a/arch/powerpc/sysdev/cpm1.c +++ b/arch/powerpc/sysdev/cpm1.c @@ -377,6 +377,10 @@ static void cpm1_set_pin16(int port, int pin, int flags) setbits16(&iop->odr_sor, pin); else clrbits16(&iop->odr_sor, pin); + if (flags & CPM_PIN_FALLEDGE) + setbits16(&iop->intr, pin); + else + clrbits16(&iop->intr, pin); } } @@ -528,6 +532,9 @@ struct cpm1_gpio16_chip { /* shadowed data register to clear/set bits safely */ u16 cpdata; + + /* IRQ associated with Pins when relevant */ + int irq[16]; }; static void cpm1_gpio16_save_regs(struct of_mm_gpio_chip *mm_gc) @@ -578,6 +585,14 @@ static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value) spin_unlock_irqrestore(&cpm1_gc->lock, flags); } +static int cpm1_gpio16_to_irq(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); + + return cpm1_gc->irq[gpio] ? : -ENXIO; +} + static int cpm1_gpio16_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) { struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); @@ -618,6 +633,7 @@ int cpm1_gpiochip_add16(struct device_node *np) struct cpm1_gpio16_chip *cpm1_gc; struct of_mm_gpio_chip *mm_gc; struct gpio_chip *gc; + u16 mask; cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); if (!cpm1_gc) @@ -625,6 +641,14 @@ int cpm1_gpiochip_add16(struct device_node *np) spin_lock_init(&cpm1_gc->lock); + if (!of_property_read_u16(np, "fsl,cpm1-gpio-irq-mask", &mask)) { + int i, j; + + for (i = 0, j = 0; i < 16; i++) + if (mask & (1 << (15 - i))) + cpm1_gc->irq[i] = irq_of_parse_and_map(np, j++); + } + mm_gc = &cpm1_gc->mm_gc; gc = &mm_gc->gc; @@ -634,6 +658,7 @@ int cpm1_gpiochip_add16(struct device_node *np) gc->direction_output = cpm1_gpio16_dir_out; gc->get = cpm1_gpio16_get; gc->set = cpm1_gpio16_set; + gc->to_irq = cpm1_gpio16_to_irq; return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc); } From 61baf15555129f69720334f232b153890895ef71 Mon Sep 17 00:00:00 2001 From: Scott Wood Date: Fri, 5 May 2017 01:22:06 -0500 Subject: [PATCH 9/9] powerpc/64e: Don't place the stack beyond TASK_SIZE Commit f4ea6dcb08ea ("powerpc/mm: Enable mappings above 128TB") increased the task size on book3s, and introduced a mechanism to dynamically control whether a task uses these larger addresses. While the change to the task size itself was ifdef-protected to only apply on book3s, the change to STACK_TOP_USER64 was not. On book3e, this had the effect of trying to use addresses up to 128TiB for the stack despite a 64TiB task size limit -- which broke 64-bit userspace producing the following errors: Starting init: /sbin/init exists but couldn't execute it (error -14) Starting init: /bin/sh exists but couldn't execute it (error -14) Kernel panic - not syncing: No working init found. Try passing init= option to kernel. See Linux Documentation/admin-guide/init.rst for guidance. Fixes: f4ea6dcb08ea ("powerpc/mm: Enable mappings above 128TB") Cc: Aneesh Kumar K.V Signed-off-by: Scott Wood --- arch/powerpc/include/asm/processor.h | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/arch/powerpc/include/asm/processor.h b/arch/powerpc/include/asm/processor.h index a4b1d8d6b793..a2123f291ab0 100644 --- a/arch/powerpc/include/asm/processor.h +++ b/arch/powerpc/include/asm/processor.h @@ -151,8 +151,13 @@ void release_thread(struct task_struct *); #ifdef __powerpc64__ +#ifdef CONFIG_PPC_BOOK3S_64 /* Limit stack to 128TB */ #define STACK_TOP_USER64 TASK_SIZE_128TB +#else +#define STACK_TOP_USER64 TASK_SIZE_USER64 +#endif + #define STACK_TOP_USER32 TASK_SIZE_USER32 #define STACK_TOP (is_32bit_task() ? \