From d667edc01bedcd23988ef69f851e7cc26cc3c67f Mon Sep 17 00:00:00 2001 From: YueHaibing Date: Sat, 4 May 2019 18:24:27 +0800 Subject: powerpc/mm: Make some symbols static that can be Noticed by sparse. Signed-off-by: YueHaibing Signed-off-by: Michael Ellerman --- arch/powerpc/mm/book3s64/hash_native.c | 2 +- arch/powerpc/mm/book3s64/hash_utils.c | 2 +- arch/powerpc/mm/book3s64/radix_pgtable.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c index aaa28fd918fe..47caecdbbbac 100644 --- a/arch/powerpc/mm/book3s64/hash_native.c +++ b/arch/powerpc/mm/book3s64/hash_native.c @@ -45,7 +45,7 @@ #define HPTE_LOCK_BIT (56+3) #endif -DEFINE_RAW_SPINLOCK(native_tlbie_lock); +static DEFINE_RAW_SPINLOCK(native_tlbie_lock); static inline void tlbiel_hash_set_isa206(unsigned int set, unsigned int is) { diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index 919a861a8ec0..1ff451892d7f 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -985,7 +985,7 @@ void __init hash__early_init_devtree(void) htab_scan_page_sizes(); } -struct hash_mm_context init_hash_mm_context; +static struct hash_mm_context init_hash_mm_context; void __init hash__early_init_mmu(void) { #ifndef CONFIG_PPC_64K_PAGES diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index c9bcf428dd2b..c929d31f1043 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -323,7 +323,7 @@ static int __meminit create_physical_mapping(unsigned long start, return 0; } -void __init radix_init_pgtable(void) +static void __init radix_init_pgtable(void) { unsigned long rts_field; struct memblock_region *reg; -- cgit v1.2.3 From f8e0d0fddf87f26aed576983f752329de4c0900f Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 13 May 2019 10:00:14 +0000 Subject: powerpc/lib: fix redundant inclusion of quad.o quad.o is only for PPC64, and already included in obj64-y, so it doesn't have to be in obj-y Fixes: 31bfdb036f12 ("powerpc: Use instruction emulation infrastructure to handle alignment faults") Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/lib/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index c55f9c27bf79..17fce3738d48 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -49,7 +49,7 @@ obj64-$(CONFIG_KPROBES_SANITY_TEST) += test_emulate_step.o \ obj-y += checksum_$(BITS).o checksum_wrappers.o \ string_$(BITS).o -obj-y += sstep.o ldstfp.o quad.o +obj-y += sstep.o ldstfp.o obj64-y += quad.o obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o -- cgit v1.2.3 From 3e3ebed3fef4878e6f1680ff98088db1a9688831 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 13 May 2019 10:00:15 +0000 Subject: powerpc/lib: only build ldstfp.o when CONFIG_PPC_FPU is set The entire code in ldstfp.o is enclosed into #ifdef CONFIG_PPC_FPU, so there is no point in building it when this config is not selected. Fixes: cd64d1697cf0 ("powerpc: mtmsrd not defined") Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/lib/Makefile | 3 ++- arch/powerpc/lib/ldstfp.S | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile index 17fce3738d48..eebc782d89a5 100644 --- a/arch/powerpc/lib/Makefile +++ b/arch/powerpc/lib/Makefile @@ -49,7 +49,8 @@ obj64-$(CONFIG_KPROBES_SANITY_TEST) += test_emulate_step.o \ obj-y += checksum_$(BITS).o checksum_wrappers.o \ string_$(BITS).o -obj-y += sstep.o ldstfp.o +obj-y += sstep.o +obj-$(CONFIG_PPC_FPU) += ldstfp.o obj64-y += quad.o obj-$(CONFIG_PPC_LIB_RHEAP) += rheap.o diff --git a/arch/powerpc/lib/ldstfp.S b/arch/powerpc/lib/ldstfp.S index 32e91994b6b2..e388a3127cb6 100644 --- a/arch/powerpc/lib/ldstfp.S +++ b/arch/powerpc/lib/ldstfp.S @@ -18,8 +18,6 @@ #include #include -#ifdef CONFIG_PPC_FPU - #define STKFRM (PPC_MIN_STKFRM + 16) /* Get the contents of frN into *p; N is in r3 and p is in r4. */ @@ -241,5 +239,3 @@ _GLOBAL(conv_dp_to_sp) MTMSRD(r6) isync blr - -#endif /* CONFIG_PPC_FPU */ -- cgit v1.2.3 From efa9ace68e487ddd29c2b4d6dd23242158f1f607 Mon Sep 17 00:00:00 2001 From: Gen Zhang Date: Sun, 26 May 2019 10:42:40 +0800 Subject: powerpc/pseries/dlpar: Fix a missing check in dlpar_parse_cc_property() In dlpar_parse_cc_property(), 'prop->name' is allocated by kstrdup(). kstrdup() may return NULL, so it should be checked and handle error. And prop should be freed if 'prop->name' is NULL. Signed-off-by: Gen Zhang Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/dlpar.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index 17958043e7f7..c852024044bb 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -61,6 +61,10 @@ static struct property *dlpar_parse_cc_property(struct cc_workarea *ccwa) name = (char *)ccwa + be32_to_cpu(ccwa->name_offset); prop->name = kstrdup(name, GFP_KERNEL); + if (!prop->name) { + dlpar_free_cc_property(prop); + return NULL; + } prop->length = be32_to_cpu(ccwa->prop_length); value = (char *)ccwa + be32_to_cpu(ccwa->prop_offset); -- cgit v1.2.3 From 1549c42deff5f3ffff326ae295ae58165e5c5830 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Fri, 24 May 2019 15:09:56 +1000 Subject: powerpc/powernv: Update firmware archaeology around OPAL_HANDLE_HMI The first machines to ship with OPAL firmware all got firmware updates that have the new call, but just in case someone is foolish enough to believe the first 4 months of firmware is the best, we keep this code around. Comment is updated to not refer to late 2014 as recent or the future. Signed-off-by: Stewart Smith Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/opal.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/powernv/opal.c b/arch/powerpc/platforms/powernv/opal.c index f2b063b027f0..89b6ddc3ed38 100644 --- a/arch/powerpc/platforms/powernv/opal.c +++ b/arch/powerpc/platforms/powernv/opal.c @@ -206,16 +206,18 @@ static int __init opal_register_exception_handlers(void) glue = 0x7000; /* - * Check if we are running on newer firmware that exports - * OPAL_HANDLE_HMI token. If yes, then don't ask OPAL to patch - * the HMI interrupt and we catch it directly in Linux. + * Only ancient OPAL firmware requires this. + * Specifically, firmware from FW810.00 (released June 2014) + * through FW810.20 (Released October 2014). * - * For older firmware (i.e currently released POWER8 System Firmware - * as of today <= SV810_087), we fallback to old behavior and let OPAL - * patch the HMI vector and handle it inside OPAL firmware. + * Check if we are running on newer (post Oct 2014) firmware that + * exports the OPAL_HANDLE_HMI token. If yes, then don't ask OPAL to + * patch the HMI interrupt and we catch it directly in Linux. * - * For newer firmware (in development/yet to be released) we will - * start catching/handling HMI directly in Linux. + * For older firmware (i.e < FW810.20), we fallback to old behavior and + * let OPAL patch the HMI vector and handle it inside OPAL firmware. + * + * For newer firmware we catch/handle the HMI directly in Linux. */ if (!opal_check_token(OPAL_HANDLE_HMI)) { pr_info("Old firmware detected, OPAL handles HMIs.\n"); @@ -225,6 +227,11 @@ static int __init opal_register_exception_handlers(void) glue += 128; } + /* + * Only applicable to ancient firmware, all modern + * (post March 2015/skiboot 5.0) firmware will just return + * OPAL_UNSUPPORTED. + */ opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue); #endif -- cgit v1.2.3 From 89d87bcba2874d824affb7842bb3960cb6f5be05 Mon Sep 17 00:00:00 2001 From: Frederic Barrat Date: Thu, 23 May 2019 14:28:04 +0200 Subject: powerpc/powernv: Show checkstop reason for NPU2 HMIs If the kernel is notified of an HMI caused by the NPU2, it's currently not being recognized and it logs the default message: Unknown Malfunction Alert of type 3 The NPU on Power 9 has 3 Fault Isolation Registers, so that's a lot of possible causes, but we should at least log that it's an NPU problem and report which FIR and which bit were raised if opal gave us the information. Signed-off-by: Frederic Barrat Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/opal-api.h | 1 + arch/powerpc/platforms/powernv/opal-hmi.c | 40 +++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/opal-api.h b/arch/powerpc/include/asm/opal-api.h index e1577cfa7186..2492fe248e1e 100644 --- a/arch/powerpc/include/asm/opal-api.h +++ b/arch/powerpc/include/asm/opal-api.h @@ -568,6 +568,7 @@ enum OpalHMI_XstopType { CHECKSTOP_TYPE_UNKNOWN = 0, CHECKSTOP_TYPE_CORE = 1, CHECKSTOP_TYPE_NX = 2, + CHECKSTOP_TYPE_NPU = 3 }; enum OpalHMI_CoreXstopReason { diff --git a/arch/powerpc/platforms/powernv/opal-hmi.c b/arch/powerpc/platforms/powernv/opal-hmi.c index 5cae375525d0..3e1f064a18db 100644 --- a/arch/powerpc/platforms/powernv/opal-hmi.c +++ b/arch/powerpc/platforms/powernv/opal-hmi.c @@ -137,6 +137,43 @@ static void print_nx_checkstop_reason(const char *level, xstop_reason[i].description); } +static void print_npu_checkstop_reason(const char *level, + struct OpalHMIEvent *hmi_evt) +{ + uint8_t reason, reason_count, i; + + /* + * We may not have a checkstop reason on some combination of + * hardware and/or skiboot version + */ + if (!hmi_evt->u.xstop_error.xstop_reason) { + printk("%s NPU checkstop on chip %x\n", level, + be32_to_cpu(hmi_evt->u.xstop_error.u.chip_id)); + return; + } + + /* + * NPU2 has 3 FIRs. Reason encoded on a byte as: + * 2 bits for the FIR number + * 6 bits for the bit number + * It may be possible to find several reasons. + * + * We don't display a specific message per FIR bit as there + * are too many and most are meaningless without the workbook + * and/or hw team help anyway. + */ + reason_count = sizeof(hmi_evt->u.xstop_error.xstop_reason) / + sizeof(reason); + for (i = 0; i < reason_count; i++) { + reason = (hmi_evt->u.xstop_error.xstop_reason >> (8 * i)) & 0xFF; + if (reason) + printk("%s NPU checkstop on chip %x: FIR%d bit %d is set\n", + level, + be32_to_cpu(hmi_evt->u.xstop_error.u.chip_id), + reason >> 6, reason & 0x3F); + } +} + static void print_checkstop_reason(const char *level, struct OpalHMIEvent *hmi_evt) { @@ -148,6 +185,9 @@ static void print_checkstop_reason(const char *level, case CHECKSTOP_TYPE_NX: print_nx_checkstop_reason(level, hmi_evt); break; + case CHECKSTOP_TYPE_NPU: + print_npu_checkstop_reason(level, hmi_evt); + break; default: printk("%s Unknown Malfunction Alert of type %d\n", level, type); -- cgit v1.2.3 From c806a6fde1c29e7419afcf94d761827a19c5ffe7 Mon Sep 17 00:00:00 2001 From: Mathieu Malaterre Date: Thu, 23 May 2019 12:25:20 +0200 Subject: powerpc: Remove variable ‘path’ since not used MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit In commit eab00a208eb6 ("powerpc: Move `path` variable inside DEBUG_PROM") DEBUG_PROM sentinels were added to silence a warning (treated as error with W=1): arch/powerpc/kernel/prom_init.c:1388:8: error: variable ‘path’ set but not used [-Werror=unused-but-set-variable] Rework the original patch and simplify the code, by removing the variable ‘path’ completely. Fix line over 90 characters. Suggested-by: Michael Ellerman Signed-off-by: Mathieu Malaterre Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/prom_init.c | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index 00682b8df330..bab79c51ba4f 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -1566,9 +1566,6 @@ static void __init reserve_mem(u64 base, u64 size) static void __init prom_init_mem(void) { phandle node; -#ifdef DEBUG_PROM - char *path; -#endif char type[64]; unsigned int plen; cell_t *p, *endp; @@ -1590,9 +1587,6 @@ static void __init prom_init_mem(void) prom_debug("root_size_cells: %x\n", rsc); prom_debug("scanning memory:\n"); -#ifdef DEBUG_PROM - path = prom_scratch; -#endif for (node = 0; prom_next_node(&node); ) { type[0] = 0; @@ -1617,9 +1611,10 @@ static void __init prom_init_mem(void) endp = p + (plen / sizeof(cell_t)); #ifdef DEBUG_PROM - memset(path, 0, sizeof(prom_scratch)); - call_prom("package-to-path", 3, 1, node, path, sizeof(prom_scratch) - 1); - prom_debug(" node %s :\n", path); + memset(prom_scratch, 0, sizeof(prom_scratch)); + call_prom("package-to-path", 3, 1, node, prom_scratch, + sizeof(prom_scratch) - 1); + prom_debug(" node %s :\n", prom_scratch); #endif /* DEBUG_PROM */ while ((endp - p) >= (rac + rsc)) { -- cgit v1.2.3 From 02c5f5394918b9b47ff4357b1b18335768cd867d Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Fri, 19 Apr 2019 17:34:13 +0200 Subject: powerpc/powernv/npu: Fix reference leak Since 902bdc57451c, get_pci_dev() calls pci_get_domain_bus_and_slot(). This has the effect of incrementing the reference count of the PCI device, as explained in drivers/pci/search.c: * Given a PCI domain, bus, and slot/function number, the desired PCI * device is located in the list of PCI devices. If the device is * found, its reference count is increased and this function returns a * pointer to its data structure. The caller must decrement the * reference count by calling pci_dev_put(). If no device is found, * %NULL is returned. Nothing was done to call pci_dev_put() and the reference count of GPU and NPU PCI devices rockets up. A natural way to fix this would be to teach the callers about the change, so that they call pci_dev_put() when done with the pointer. This turns out to be quite intrusive, as it affects many paths in npu-dma.c, pci-ioda.c and vfio_pci_nvlink2.c. Also, the issue appeared in 4.16 and some affected code got moved around since then: it would be problematic to backport the fix to stable releases. All that code never cared for reference counting anyway. Call pci_dev_put() from get_pci_dev() to revert to the previous behavior. Fixes: 902bdc57451c ("powerpc/powernv/idoa: Remove unnecessary pcidev from pci_dn") Cc: stable@vger.kernel.org # v4.16 Signed-off-by: Greg Kurz Reviewed-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/npu-dma.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index 495550432f3d..dc1058efc24f 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c @@ -31,9 +31,22 @@ static DEFINE_SPINLOCK(npu_context_lock); static struct pci_dev *get_pci_dev(struct device_node *dn) { struct pci_dn *pdn = PCI_DN(dn); + struct pci_dev *pdev; - return pci_get_domain_bus_and_slot(pci_domain_nr(pdn->phb->bus), + pdev = pci_get_domain_bus_and_slot(pci_domain_nr(pdn->phb->bus), pdn->busno, pdn->devfn); + + /* + * pci_get_domain_bus_and_slot() increased the reference count of + * the PCI device, but callers don't need that actually as the PE + * already holds a reference to the device. Since callers aren't + * aware of the reference count change, call pci_dev_put() now to + * avoid leaks. + */ + if (pdev) + pci_dev_put(pdev); + + return pdev; } /* Given a NPU device get the associated PCI device. */ -- cgit v1.2.3 From a3bf9fbdad600b1e4335dd90979f8d6072e4f602 Mon Sep 17 00:00:00 2001 From: Greg Kurz Date: Wed, 15 May 2019 12:05:01 +0200 Subject: powerpc/pseries: Fix xive=off command line MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On POWER9, if the hypervisor supports XIVE exploitation mode, the guest OS will unconditionally requests for the XIVE interrupt mode even if XIVE was deactivated with the kernel command line xive=off. Later on, when the spapr XIVE init code handles xive=off, it disables XIVE and tries to fall back on the legacy mode XICS. This discrepency causes a kernel panic because the hypervisor is configured to provide the XIVE interrupt mode to the guest : kernel BUG at arch/powerpc/sysdev/xics/xics-common.c:135! ... NIP xics_smp_probe+0x38/0x98 LR xics_smp_probe+0x2c/0x98 Call Trace: xics_smp_probe+0x2c/0x98 (unreliable) pSeries_smp_probe+0x40/0xa0 smp_prepare_cpus+0x62c/0x6ec kernel_init_freeable+0x148/0x448 kernel_init+0x2c/0x148 ret_from_kernel_thread+0x5c/0x68 Look for xive=off during prom_init and don't ask for XIVE in this case. One exception though: if the host only supports XIVE, we still want to boot so we ignore xive=off. Similarly, have the spapr XIVE init code to looking at the interrupt mode negotiated during CAS, and ignore xive=off if the hypervisor only supports XIVE. Fixes: eac1e731b59e ("powerpc/xive: guest exploitation of the XIVE interrupt controller") Cc: stable@vger.kernel.org # v4.20 Reported-by: Pavithra R. Prakash Signed-off-by: Greg Kurz Reviewed-by: Cédric Le Goater Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/prom_init.c | 16 ++++++++++++- arch/powerpc/sysdev/xive/spapr.c | 52 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c index bab79c51ba4f..17f1ae7fae2c 100644 --- a/arch/powerpc/kernel/prom_init.c +++ b/arch/powerpc/kernel/prom_init.c @@ -172,6 +172,7 @@ static unsigned long __prombss prom_tce_alloc_end; #ifdef CONFIG_PPC_PSERIES static bool __prombss prom_radix_disable; +static bool __prombss prom_xive_disable; #endif struct platform_support { @@ -808,6 +809,12 @@ static void __init early_cmdline_parse(void) } if (prom_radix_disable) prom_debug("Radix disabled from cmdline\n"); + + opt = prom_strstr(prom_cmd_line, "xive=off"); + if (opt) { + prom_xive_disable = true; + prom_debug("XIVE disabled from cmdline\n"); + } #endif /* CONFIG_PPC_PSERIES */ } @@ -1216,10 +1223,17 @@ static void __init prom_parse_xive_model(u8 val, switch (val) { case OV5_FEAT(OV5_XIVE_EITHER): /* Either Available */ prom_debug("XIVE - either mode supported\n"); - support->xive = true; + support->xive = !prom_xive_disable; break; case OV5_FEAT(OV5_XIVE_EXPLOIT): /* Only Exploitation mode */ prom_debug("XIVE - exploitation mode supported\n"); + if (prom_xive_disable) { + /* + * If we __have__ to do XIVE, we're better off ignoring + * the command line rather than not booting. + */ + prom_printf("WARNING: Ignoring cmdline option xive=off\n"); + } support->xive = true; break; case OV5_FEAT(OV5_XIVE_LEGACY): /* Only Legacy mode */ diff --git a/arch/powerpc/sysdev/xive/spapr.c b/arch/powerpc/sysdev/xive/spapr.c index 575db3b06a6b..2e2d1b8f810f 100644 --- a/arch/powerpc/sysdev/xive/spapr.c +++ b/arch/powerpc/sysdev/xive/spapr.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -663,6 +664,55 @@ static bool xive_get_max_prio(u8 *max_prio) return true; } +static const u8 *get_vec5_feature(unsigned int index) +{ + unsigned long root, chosen; + int size; + const u8 *vec5; + + root = of_get_flat_dt_root(); + chosen = of_get_flat_dt_subnode_by_name(root, "chosen"); + if (chosen == -FDT_ERR_NOTFOUND) + return NULL; + + vec5 = of_get_flat_dt_prop(chosen, "ibm,architecture-vec-5", &size); + if (!vec5) + return NULL; + + if (size <= index) + return NULL; + + return vec5 + index; +} + +static bool xive_spapr_disabled(void) +{ + const u8 *vec5_xive; + + vec5_xive = get_vec5_feature(OV5_INDX(OV5_XIVE_SUPPORT)); + if (vec5_xive) { + u8 val; + + val = *vec5_xive & OV5_FEAT(OV5_XIVE_SUPPORT); + switch (val) { + case OV5_FEAT(OV5_XIVE_EITHER): + case OV5_FEAT(OV5_XIVE_LEGACY): + break; + case OV5_FEAT(OV5_XIVE_EXPLOIT): + /* Hypervisor only supports XIVE */ + if (xive_cmdline_disabled) + pr_warn("WARNING: Ignoring cmdline option xive=off\n"); + return false; + default: + pr_warn("%s: Unknown xive support option: 0x%x\n", + __func__, val); + break; + } + } + + return xive_cmdline_disabled; +} + bool __init xive_spapr_init(void) { struct device_node *np; @@ -675,7 +725,7 @@ bool __init xive_spapr_init(void) const __be32 *reg; int i; - if (xive_cmdline_disabled) + if (xive_spapr_disabled()) return false; pr_devel("%s()\n", __func__); -- cgit v1.2.3 From 934bda59f286d0221f1a3ebab7f5156a996cc37d Mon Sep 17 00:00:00 2001 From: Daniel Axtens Date: Mon, 3 Jun 2019 16:56:57 +1000 Subject: powerpc/pseries/hvconsole: Fix stack overread via udbg While developing KASAN for 64-bit book3s, I hit the following stack over-read. It occurs because the hypercall to put characters onto the terminal takes 2 longs (128 bits/16 bytes) of characters at a time, and so hvc_put_chars() would unconditionally copy 16 bytes from the argument buffer, regardless of supplied length. However, udbg_hvc_putc() can call hvc_put_chars() with a single-byte buffer, leading to the error. ================================================================== BUG: KASAN: stack-out-of-bounds in hvc_put_chars+0xdc/0x110 Read of size 8 at addr c0000000023e7a90 by task swapper/0 CPU: 0 PID: 0 Comm: swapper Not tainted 5.2.0-rc2-next-20190528-02824-g048a6ab4835b #113 Call Trace: dump_stack+0x104/0x154 (unreliable) print_address_description+0xa0/0x30c __kasan_report+0x20c/0x224 kasan_report+0x18/0x30 __asan_report_load8_noabort+0x24/0x40 hvc_put_chars+0xdc/0x110 hvterm_raw_put_chars+0x9c/0x110 udbg_hvc_putc+0x154/0x200 udbg_write+0xf0/0x240 console_unlock+0x868/0xd30 register_console+0x970/0xe90 register_early_udbg_console+0xf8/0x114 setup_arch+0x108/0x790 start_kernel+0x104/0x784 start_here_common+0x1c/0x534 Memory state around the buggy address: c0000000023e7980: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0000000023e7a00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 >c0000000023e7a80: f1 f1 01 f2 f2 f2 00 00 00 00 00 00 00 00 00 00 ^ c0000000023e7b00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 c0000000023e7b80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ================================================================== Document that a 16-byte buffer is requred, and provide it in udbg. Signed-off-by: Daniel Axtens Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/hvconsole.c | 2 +- drivers/tty/hvc/hvc_vio.c | 16 +++++++++++++++- 2 files changed, 16 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/hvconsole.c b/arch/powerpc/platforms/pseries/hvconsole.c index 74da18de853a..73ec15cd2708 100644 --- a/arch/powerpc/platforms/pseries/hvconsole.c +++ b/arch/powerpc/platforms/pseries/hvconsole.c @@ -62,7 +62,7 @@ EXPORT_SYMBOL(hvc_get_chars); * @vtermno: The vtermno or unit_address of the adapter from which the data * originated. * @buf: The character buffer that contains the character data to send to - * firmware. + * firmware. Must be at least 16 bytes, even if count is less than 16. * @count: Send this number of characters. */ int hvc_put_chars(uint32_t vtermno, const char *buf, int count) diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c index 6de6d4a1a221..7af54d6ed5b8 100644 --- a/drivers/tty/hvc/hvc_vio.c +++ b/drivers/tty/hvc/hvc_vio.c @@ -107,6 +107,14 @@ static int hvterm_raw_get_chars(uint32_t vtermno, char *buf, int count) return got; } +/** + * hvterm_raw_put_chars: send characters to firmware for given vterm adapter + * @vtermno: The virtual terminal number. + * @buf: The characters to send. Because of the underlying hypercall in + * hvc_put_chars(), this buffer must be at least 16 bytes long, even if + * you are sending fewer chars. + * @count: number of chars to send. + */ static int hvterm_raw_put_chars(uint32_t vtermno, const char *buf, int count) { struct hvterm_priv *pv = hvterm_privs[vtermno]; @@ -219,6 +227,7 @@ static const struct hv_ops hvterm_hvsi_ops = { static void udbg_hvc_putc(char c) { int count = -1; + unsigned char bounce_buffer[16]; if (!hvterm_privs[0]) return; @@ -229,7 +238,12 @@ static void udbg_hvc_putc(char c) do { switch(hvterm_privs[0]->proto) { case HV_PROTOCOL_RAW: - count = hvterm_raw_put_chars(0, &c, 1); + /* + * hvterm_raw_put_chars requires at least a 16-byte + * buffer, so go via the bounce buffer + */ + bounce_buffer[0] = c; + count = hvterm_raw_put_chars(0, bounce_buffer, 1); break; case HV_PROTOCOL_HVSI: count = hvterm_hvsi_put_chars(0, &c, 1); -- cgit v1.2.3 From 0aa82c482ab2ece530a6f44897b63b274bb43c8e Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 7 Jun 2019 00:04:07 -0500 Subject: powerpc/pseries: Fix oops in hotplug memory notifier During post-migration device tree updates, we can oops in pseries_update_drconf_memory() if the source device tree has an ibm,dynamic-memory-v2 property and the destination has a ibm,dynamic_memory (v1) property. The notifier processes an "update" for the ibm,dynamic-memory property but it's really an add in this scenario. So make sure the old property object is there before dereferencing it. Fixes: 2b31e3aec1db ("powerpc/drmem: Add support for ibm, dynamic-memory-v2 property") Cc: stable@vger.kernel.org # v4.16+ Signed-off-by: Nathan Lynch Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/hotplug-memory.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/hotplug-memory.c b/arch/powerpc/platforms/pseries/hotplug-memory.c index 47087832f8b2..e6bd172bcf30 100644 --- a/arch/powerpc/platforms/pseries/hotplug-memory.c +++ b/arch/powerpc/platforms/pseries/hotplug-memory.c @@ -980,6 +980,9 @@ static int pseries_update_drconf_memory(struct of_reconfig_data *pr) if (!memblock_size) return -EINVAL; + if (!pr->old_prop) + return 0; + p = (__be32 *) pr->old_prop->value; if (!p) return -EINVAL; -- cgit v1.2.3 From d4aa219a074a5abaf95a756b9f0d190b5c03a945 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Tue, 11 Jun 2019 23:45:04 -0500 Subject: powerpc/cacheinfo: add cacheinfo_teardown, cacheinfo_rebuild Allow external callers to force the cacheinfo code to release all its references to cache nodes, e.g. before processing device tree updates post-migration, and to rebuild the hierarchy afterward. CPU online/offline must be blocked by callers; enforce this. Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/cacheinfo.c | 21 +++++++++++++++++++++ arch/powerpc/kernel/cacheinfo.h | 4 ++++ 2 files changed, 25 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/cacheinfo.c b/arch/powerpc/kernel/cacheinfo.c index 862e2890bd3d..42c559efe060 100644 --- a/arch/powerpc/kernel/cacheinfo.c +++ b/arch/powerpc/kernel/cacheinfo.c @@ -896,4 +896,25 @@ void cacheinfo_cpu_offline(unsigned int cpu_id) if (cache) cache_cpu_clear(cache, cpu_id); } + +void cacheinfo_teardown(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_offline(cpu); +} + +void cacheinfo_rebuild(void) +{ + unsigned int cpu; + + lockdep_assert_cpus_held(); + + for_each_online_cpu(cpu) + cacheinfo_cpu_online(cpu); +} + #endif /* (CONFIG_PPC_PSERIES && CONFIG_SUSPEND) || CONFIG_HOTPLUG_CPU */ diff --git a/arch/powerpc/kernel/cacheinfo.h b/arch/powerpc/kernel/cacheinfo.h index 955f5e999f1b..52bd3fc6642d 100644 --- a/arch/powerpc/kernel/cacheinfo.h +++ b/arch/powerpc/kernel/cacheinfo.h @@ -6,4 +6,8 @@ extern void cacheinfo_cpu_online(unsigned int cpu_id); extern void cacheinfo_cpu_offline(unsigned int cpu_id); +/* Allow migration/suspend to tear down and rebuild the hierarchy. */ +extern void cacheinfo_teardown(void); +extern void cacheinfo_rebuild(void); + #endif /* _PPC_CACHEINFO_H */ -- cgit v1.2.3 From e59a175faa8df9d674247946f2a5a9c29c835725 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Tue, 11 Jun 2019 23:45:05 -0500 Subject: powerpc/pseries/mobility: prevent cpu hotplug during DT update CPU online/offline code paths are sensitive to parts of the device tree (various cpu node properties, cache nodes) that can be changed as a result of a migration. Prevent CPU hotplug while the device tree potentially is inconsistent. Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/mobility.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index 88925f8ca8a0..edc1ec408589 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -9,6 +9,7 @@ * 2 as published by the Free Software Foundation. */ +#include #include #include #include @@ -338,11 +339,19 @@ void post_mobility_fixup(void) if (rc) printk(KERN_ERR "Post-mobility activate-fw failed: %d\n", rc); + /* + * We don't want CPUs to go online/offline while the device + * tree is being updated. + */ + cpus_read_lock(); + rc = pseries_devicetree_update(MIGRATION_SCOPE); if (rc) printk(KERN_ERR "Post-mobility device tree update " "failed: %d\n", rc); + cpus_read_unlock(); + /* Possibly switch to a new RFI flush type */ pseries_setup_rfi_flush(); -- cgit v1.2.3 From e610a466d16a086e321f0bd421e2fc75cff28605 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Tue, 11 Jun 2019 23:45:06 -0500 Subject: powerpc/pseries/mobility: rebuild cacheinfo hierarchy post-migration It's common for the platform to replace the cache device nodes after a migration. Since the cacheinfo code is never informed about this, it never drops its references to the source system's cache nodes, causing it to wind up in an inconsistent state resulting in warnings and oopses as soon as CPU online/offline occurs after the migration, e.g. cache for /cpus/l3-cache@3113(Unified) refers to cache for /cpus/l2-cache@200d(Unified) WARNING: CPU: 15 PID: 86 at arch/powerpc/kernel/cacheinfo.c:176 release_cache+0x1bc/0x1d0 [...] NIP release_cache+0x1bc/0x1d0 LR release_cache+0x1b8/0x1d0 Call Trace: release_cache+0x1b8/0x1d0 (unreliable) cacheinfo_cpu_offline+0x1c4/0x2c0 unregister_cpu_online+0x1b8/0x260 cpuhp_invoke_callback+0x114/0xf40 cpuhp_thread_fun+0x270/0x310 smpboot_thread_fn+0x2c8/0x390 kthread+0x1b8/0x1c0 ret_from_kernel_thread+0x5c/0x68 Using device tree notifiers won't work since we want to rebuild the hierarchy only after all the removals and additions have occurred and the device tree is in a consistent state. Call cacheinfo_teardown() before processing device tree updates, and rebuild the hierarchy afterward. Fixes: 410bccf97881 ("powerpc/pseries: Partition migration in the kernel") Signed-off-by: Nathan Lynch Reviewed-by: Gautham R. Shenoy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/mobility.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c index edc1ec408589..b8c8096907d4 100644 --- a/arch/powerpc/platforms/pseries/mobility.c +++ b/arch/powerpc/platforms/pseries/mobility.c @@ -23,6 +23,7 @@ #include #include #include "pseries.h" +#include "../../kernel/cacheinfo.h" static struct kobject *mobility_kobj; @@ -345,11 +346,20 @@ void post_mobility_fixup(void) */ cpus_read_lock(); + /* + * It's common for the destination firmware to replace cache + * nodes. Release all of the cacheinfo hierarchy's references + * before updating the device tree. + */ + cacheinfo_teardown(); + rc = pseries_devicetree_update(MIGRATION_SCOPE); if (rc) printk(KERN_ERR "Post-mobility device tree update " "failed: %d\n", rc); + cacheinfo_rebuild(); + cpus_read_unlock(); /* Possibly switch to a new RFI flush type */ -- cgit v1.2.3 From 9c4e4c90ec24652921e31e9551fcaedc26eec86d Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 10 May 2019 06:31:28 +0000 Subject: powerpc/64: mark start_here_multiplatform as __ref Otherwise, the following warning is encountered: WARNING: vmlinux.o(.text+0x3dc6): Section mismatch in reference from the variable start_here_multiplatform to the function .init.text:.early_setup() The function start_here_multiplatform() references the function __init .early_setup(). This is often because start_here_multiplatform lacks a __init annotation or the annotation of .early_setup is wrong. Fixes: 56c46bba9bbf ("powerpc/64: Fix booting large kernels with STRICT_KERNEL_RWX") Cc: Russell Currey Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/head_64.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S index 5321a11c2835..259be7f6d551 100644 --- a/arch/powerpc/kernel/head_64.S +++ b/arch/powerpc/kernel/head_64.S @@ -904,6 +904,7 @@ p_toc: .8byte __toc_start + 0x8000 - 0b /* * This is where the main kernel code starts. */ +__REF start_here_multiplatform: /* set up the TOC */ bl relative_toc @@ -979,6 +980,7 @@ start_here_multiplatform: RFI b . /* prevent speculative execution */ + .previous /* This is where all platforms converge execution */ start_here_common: -- cgit v1.2.3 From 6ecb78ef56e08d2119d337ae23cb951a640dc52d Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Mon, 17 Jun 2019 21:42:14 +0000 Subject: powerpc/32s: fix suspend/resume when IBATs 4-7 are used Previously, only IBAT1 and IBAT2 were used to map kernel linear mem. Since commit 63b2bc619565 ("powerpc/mm/32s: Use BATs for STRICT_KERNEL_RWX"), we may have all 8 BATs used for mapping kernel text. But the suspend/restore functions only save/restore BATs 0 to 3, and clears BATs 4 to 7. Make suspend and restore functions respectively save and reload the 8 BATs on CPUs having MMU_FTR_USE_HIGH_BATS feature. Reported-by: Andreas Schwab Cc: stable@vger.kernel.org Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/swsusp_32.S | 73 +++++++++++++++++++++++++++++---- arch/powerpc/platforms/powermac/sleep.S | 68 +++++++++++++++++++++++++++--- 2 files changed, 128 insertions(+), 13 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/swsusp_32.S b/arch/powerpc/kernel/swsusp_32.S index 7a919e9a3400..cbdf86228eaa 100644 --- a/arch/powerpc/kernel/swsusp_32.S +++ b/arch/powerpc/kernel/swsusp_32.S @@ -25,11 +25,19 @@ #define SL_IBAT2 0x48 #define SL_DBAT3 0x50 #define SL_IBAT3 0x58 -#define SL_TB 0x60 -#define SL_R2 0x68 -#define SL_CR 0x6c -#define SL_LR 0x70 -#define SL_R12 0x74 /* r12 to r31 */ +#define SL_DBAT4 0x60 +#define SL_IBAT4 0x68 +#define SL_DBAT5 0x70 +#define SL_IBAT5 0x78 +#define SL_DBAT6 0x80 +#define SL_IBAT6 0x88 +#define SL_DBAT7 0x90 +#define SL_IBAT7 0x98 +#define SL_TB 0xa0 +#define SL_R2 0xa8 +#define SL_CR 0xac +#define SL_LR 0xb0 +#define SL_R12 0xb4 /* r12 to r31 */ #define SL_SIZE (SL_R12 + 80) .section .data @@ -114,6 +122,41 @@ _GLOBAL(swsusp_arch_suspend) mfibatl r4,3 stw r4,SL_IBAT3+4(r11) +BEGIN_MMU_FTR_SECTION + mfspr r4,SPRN_DBAT4U + stw r4,SL_DBAT4(r11) + mfspr r4,SPRN_DBAT4L + stw r4,SL_DBAT4+4(r11) + mfspr r4,SPRN_DBAT5U + stw r4,SL_DBAT5(r11) + mfspr r4,SPRN_DBAT5L + stw r4,SL_DBAT5+4(r11) + mfspr r4,SPRN_DBAT6U + stw r4,SL_DBAT6(r11) + mfspr r4,SPRN_DBAT6L + stw r4,SL_DBAT6+4(r11) + mfspr r4,SPRN_DBAT7U + stw r4,SL_DBAT7(r11) + mfspr r4,SPRN_DBAT7L + stw r4,SL_DBAT7+4(r11) + mfspr r4,SPRN_IBAT4U + stw r4,SL_IBAT4(r11) + mfspr r4,SPRN_IBAT4L + stw r4,SL_IBAT4+4(r11) + mfspr r4,SPRN_IBAT5U + stw r4,SL_IBAT5(r11) + mfspr r4,SPRN_IBAT5L + stw r4,SL_IBAT5+4(r11) + mfspr r4,SPRN_IBAT6U + stw r4,SL_IBAT6(r11) + mfspr r4,SPRN_IBAT6L + stw r4,SL_IBAT6+4(r11) + mfspr r4,SPRN_IBAT7U + stw r4,SL_IBAT7(r11) + mfspr r4,SPRN_IBAT7L + stw r4,SL_IBAT7+4(r11) +END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) + #if 0 /* Backup various CPU config stuffs */ bl __save_cpu_setup @@ -279,27 +322,41 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC) mtibatu 3,r4 lwz r4,SL_IBAT3+4(r11) mtibatl 3,r4 -#endif - BEGIN_MMU_FTR_SECTION - li r4,0 + lwz r4,SL_DBAT4(r11) mtspr SPRN_DBAT4U,r4 + lwz r4,SL_DBAT4+4(r11) mtspr SPRN_DBAT4L,r4 + lwz r4,SL_DBAT5(r11) mtspr SPRN_DBAT5U,r4 + lwz r4,SL_DBAT5+4(r11) mtspr SPRN_DBAT5L,r4 + lwz r4,SL_DBAT6(r11) mtspr SPRN_DBAT6U,r4 + lwz r4,SL_DBAT6+4(r11) mtspr SPRN_DBAT6L,r4 + lwz r4,SL_DBAT7(r11) mtspr SPRN_DBAT7U,r4 + lwz r4,SL_DBAT7+4(r11) mtspr SPRN_DBAT7L,r4 + lwz r4,SL_IBAT4(r11) mtspr SPRN_IBAT4U,r4 + lwz r4,SL_IBAT4+4(r11) mtspr SPRN_IBAT4L,r4 + lwz r4,SL_IBAT5(r11) mtspr SPRN_IBAT5U,r4 + lwz r4,SL_IBAT5+4(r11) mtspr SPRN_IBAT5L,r4 + lwz r4,SL_IBAT6(r11) mtspr SPRN_IBAT6U,r4 + lwz r4,SL_IBAT6+4(r11) mtspr SPRN_IBAT6L,r4 + lwz r4,SL_IBAT7(r11) mtspr SPRN_IBAT7U,r4 + lwz r4,SL_IBAT7+4(r11) mtspr SPRN_IBAT7L,r4 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) +#endif /* Flush all TLBs */ lis r4,0x1000 diff --git a/arch/powerpc/platforms/powermac/sleep.S b/arch/powerpc/platforms/powermac/sleep.S index fb64b09cad9d..eb583bd9a75d 100644 --- a/arch/powerpc/platforms/powermac/sleep.S +++ b/arch/powerpc/platforms/powermac/sleep.S @@ -38,10 +38,18 @@ #define SL_IBAT2 0x48 #define SL_DBAT3 0x50 #define SL_IBAT3 0x58 -#define SL_TB 0x60 -#define SL_R2 0x68 -#define SL_CR 0x6c -#define SL_R12 0x70 /* r12 to r31 */ +#define SL_DBAT4 0x60 +#define SL_IBAT4 0x68 +#define SL_DBAT5 0x70 +#define SL_IBAT5 0x78 +#define SL_DBAT6 0x80 +#define SL_IBAT6 0x88 +#define SL_DBAT7 0x90 +#define SL_IBAT7 0x98 +#define SL_TB 0xa0 +#define SL_R2 0xa8 +#define SL_CR 0xac +#define SL_R12 0xb0 /* r12 to r31 */ #define SL_SIZE (SL_R12 + 80) .section .text @@ -126,6 +134,41 @@ _GLOBAL(low_sleep_handler) mfibatl r4,3 stw r4,SL_IBAT3+4(r1) +BEGIN_MMU_FTR_SECTION + mfspr r4,SPRN_DBAT4U + stw r4,SL_DBAT4(r1) + mfspr r4,SPRN_DBAT4L + stw r4,SL_DBAT4+4(r1) + mfspr r4,SPRN_DBAT5U + stw r4,SL_DBAT5(r1) + mfspr r4,SPRN_DBAT5L + stw r4,SL_DBAT5+4(r1) + mfspr r4,SPRN_DBAT6U + stw r4,SL_DBAT6(r1) + mfspr r4,SPRN_DBAT6L + stw r4,SL_DBAT6+4(r1) + mfspr r4,SPRN_DBAT7U + stw r4,SL_DBAT7(r1) + mfspr r4,SPRN_DBAT7L + stw r4,SL_DBAT7+4(r1) + mfspr r4,SPRN_IBAT4U + stw r4,SL_IBAT4(r1) + mfspr r4,SPRN_IBAT4L + stw r4,SL_IBAT4+4(r1) + mfspr r4,SPRN_IBAT5U + stw r4,SL_IBAT5(r1) + mfspr r4,SPRN_IBAT5L + stw r4,SL_IBAT5+4(r1) + mfspr r4,SPRN_IBAT6U + stw r4,SL_IBAT6(r1) + mfspr r4,SPRN_IBAT6L + stw r4,SL_IBAT6+4(r1) + mfspr r4,SPRN_IBAT7U + stw r4,SL_IBAT7(r1) + mfspr r4,SPRN_IBAT7L + stw r4,SL_IBAT7+4(r1) +END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) + /* Backup various CPU config stuffs */ bl __save_cpu_setup @@ -326,22 +369,37 @@ grackle_wake_up: mtibatl 3,r4 BEGIN_MMU_FTR_SECTION - li r4,0 + lwz r4,SL_DBAT4(r1) mtspr SPRN_DBAT4U,r4 + lwz r4,SL_DBAT4+4(r1) mtspr SPRN_DBAT4L,r4 + lwz r4,SL_DBAT5(r1) mtspr SPRN_DBAT5U,r4 + lwz r4,SL_DBAT5+4(r1) mtspr SPRN_DBAT5L,r4 + lwz r4,SL_DBAT6(r1) mtspr SPRN_DBAT6U,r4 + lwz r4,SL_DBAT6+4(r1) mtspr SPRN_DBAT6L,r4 + lwz r4,SL_DBAT7(r1) mtspr SPRN_DBAT7U,r4 + lwz r4,SL_DBAT7+4(r1) mtspr SPRN_DBAT7L,r4 + lwz r4,SL_IBAT4(r1) mtspr SPRN_IBAT4U,r4 + lwz r4,SL_IBAT4+4(r1) mtspr SPRN_IBAT4L,r4 + lwz r4,SL_IBAT5(r1) mtspr SPRN_IBAT5U,r4 + lwz r4,SL_IBAT5+4(r1) mtspr SPRN_IBAT5L,r4 + lwz r4,SL_IBAT6(r1) mtspr SPRN_IBAT6U,r4 + lwz r4,SL_IBAT6+4(r1) mtspr SPRN_IBAT6L,r4 + lwz r4,SL_IBAT7(r1) mtspr SPRN_IBAT7U,r4 + lwz r4,SL_IBAT7+4(r1) mtspr SPRN_IBAT7L,r4 END_MMU_FTR_SECTION_IFSET(MMU_FTR_USE_HIGH_BATS) -- cgit v1.2.3 From 46c2478af610efb3212b8b08f74389d69899ef70 Mon Sep 17 00:00:00 2001 From: Andreas Schwab Date: Mon, 17 Jun 2019 23:22:20 +0200 Subject: powerpc/mm/32s: fix condition that is always true Move a misplaced paren that makes the condition always true. Fixes: 63b2bc619565 ("powerpc/mm/32s: Use BATs for STRICT_KERNEL_RWX") Cc: stable@vger.kernel.org # v5.1+ Signed-off-by: Andreas Schwab Reviewed-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/mm/pgtable_32.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c index 16ada373b32b..f3aab4398082 100644 --- a/arch/powerpc/mm/pgtable_32.c +++ b/arch/powerpc/mm/pgtable_32.c @@ -365,7 +365,7 @@ void mark_initmem_nx(void) unsigned long numpages = PFN_UP((unsigned long)_einittext) - PFN_DOWN((unsigned long)_sinittext); - if (v_block_mapped((unsigned long)_stext) + 1) + if (v_block_mapped((unsigned long)_stext + 1)) mmu_mark_initmem_nx(); else change_page_attr(page, numpages, PAGE_KERNEL); -- cgit v1.2.3 From 0b1be03f25bb4c92de6408da4de9361f4cb50ae3 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Mon, 17 Jun 2019 11:07:13 +0200 Subject: powerpc/ps3: Use [] to denote a flexible array member Flexible array members should be denoted using [] instead of [0], else gcc will not warn when they are no longer at the end of the structure. Signed-off-by: Geert Uytterhoeven Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/ps3stor.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/ps3stor.h b/arch/powerpc/include/asm/ps3stor.h index 6fcaf714fa50..d5767ba0670b 100644 --- a/arch/powerpc/include/asm/ps3stor.h +++ b/arch/powerpc/include/asm/ps3stor.h @@ -51,7 +51,7 @@ struct ps3_storage_device { unsigned int num_regions; unsigned long accessible_regions; unsigned int region_idx; /* first accessible region */ - struct ps3_storage_region regions[0]; /* Must be last */ + struct ps3_storage_region regions[]; /* Must be last */ }; static inline struct ps3_storage_device *to_ps3_storage_device(struct device *dev) -- cgit v1.2.3 From f474c28fbcbe42faca4eb415172c07d76adcb819 Mon Sep 17 00:00:00 2001 From: Ravi Bangoria Date: Thu, 13 Jun 2019 09:00:14 +0530 Subject: powerpc/watchpoint: Restore NV GPRs while returning from exception powerpc hardware triggers watchpoint before executing the instruction. To make trigger-after-execute behavior, kernel emulates the instruction. If the instruction is 'load something into non-volatile register', exception handler should restore emulated register state while returning back, otherwise there will be register state corruption. eg, adding a watchpoint on a list can corrput the list: # cat /proc/kallsyms | grep kthread_create_list c00000000121c8b8 d kthread_create_list Add watchpoint on kthread_create_list->prev: # perf record -e mem:0xc00000000121c8c0 Run some workload such that new kthread gets invoked. eg, I just logged out from console: list_add corruption. next->prev should be prev (c000000001214e00), \ but was c00000000121c8b8. (next=c00000000121c8b8). WARNING: CPU: 59 PID: 309 at lib/list_debug.c:25 __list_add_valid+0xb4/0xc0 CPU: 59 PID: 309 Comm: kworker/59:0 Kdump: loaded Not tainted 5.1.0-rc7+ #69 ... NIP __list_add_valid+0xb4/0xc0 LR __list_add_valid+0xb0/0xc0 Call Trace: __list_add_valid+0xb0/0xc0 (unreliable) __kthread_create_on_node+0xe0/0x260 kthread_create_on_node+0x34/0x50 create_worker+0xe8/0x260 worker_thread+0x444/0x560 kthread+0x160/0x1a0 ret_from_kernel_thread+0x5c/0x70 List corruption happened because it uses 'load into non-volatile register' instruction: Snippet from __kthread_create_on_node: c000000000136be8: addis r29,r2,-19 c000000000136bec: ld r29,31424(r29) if (!__list_add_valid(new, prev, next)) c000000000136bf0: mr r3,r30 c000000000136bf4: mr r5,r28 c000000000136bf8: mr r4,r29 c000000000136bfc: bl c00000000059a2f8 <__list_add_valid+0x8> Register state from WARN_ON(): GPR00: c00000000059a3a0 c000007ff23afb50 c000000001344e00 0000000000000075 GPR04: 0000000000000000 0000000000000000 0000001852af8bc1 0000000000000000 GPR08: 0000000000000001 0000000000000007 0000000000000006 00000000000004aa GPR12: 0000000000000000 c000007ffffeb080 c000000000137038 c000005ff62aaa00 GPR16: 0000000000000000 0000000000000000 c000007fffbe7600 c000007fffbe7370 GPR20: c000007fffbe7320 c000007fffbe7300 c000000001373a00 0000000000000000 GPR24: fffffffffffffef7 c00000000012e320 c000007ff23afcb0 c000000000cb8628 GPR28: c00000000121c8b8 c000000001214e00 c000007fef5b17e8 c000007fef5b17c0 Watchpoint hit at 0xc000000000136bec. addis r29,r2,-19 => r29 = 0xc000000001344e00 + (-19 << 16) => r29 = 0xc000000001214e00 ld r29,31424(r29) => r29 = *(0xc000000001214e00 + 31424) => r29 = *(0xc00000000121c8c0) 0xc00000000121c8c0 is where we placed a watchpoint and thus this instruction was emulated by emulate_step. But because handle_dabr_fault did not restore emulated register state, r29 still contains stale value in above register state. Fixes: 5aae8a5370802 ("powerpc, hw_breakpoints: Implement hw_breakpoints for 64-bit server processors") Signed-off-by: Ravi Bangoria Cc: stable@vger.kernel.org # 2.6.36+ Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 6b86055e5251..4d4fd2ad5b7d 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1746,7 +1746,7 @@ handle_page_fault: addi r3,r1,STACK_FRAME_OVERHEAD bl do_page_fault cmpdi r3,0 - beq+ 12f + beq+ ret_from_except_lite bl save_nvgprs mr r5,r3 addi r3,r1,STACK_FRAME_OVERHEAD @@ -1761,7 +1761,12 @@ handle_dabr_fault: ld r5,_DSISR(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_break -12: b ret_from_except_lite + /* + * do_break() may have changed the NV GPRS while handling a breakpoint. + * If so, we need to restore them with their updated values. Don't use + * ret_from_except_lite here. + */ + b ret_from_except #ifdef CONFIG_PPC_BOOK3S_64 -- cgit v1.2.3 From 348ea30f51fc63ce3c7fd7dba6043e8e3ee0ef34 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Tue, 28 May 2019 18:28:01 -0500 Subject: powerpc/pseries: avoid blocking in irq when queuing hotplug events A couple of bugs in queue_hotplug_event(): 1. Unchecked kmalloc result which could lead to an oops. 2. Use of GFP_KERNEL allocations in interrupt context (this code's only caller is ras_hotplug_interrupt()). Use kmemdup to avoid open-coding the allocation+copy and check for failure; use GFP_ATOMIC for both allocations. Ultimately it probably would be better to avoid or reduce allocations in this path if possible. Signed-off-by: Nathan Lynch Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/dlpar.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c index c852024044bb..4989c5762398 100644 --- a/arch/powerpc/platforms/pseries/dlpar.c +++ b/arch/powerpc/platforms/pseries/dlpar.c @@ -390,11 +390,11 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog) struct pseries_hp_work *work; struct pseries_hp_errorlog *hp_errlog_copy; - hp_errlog_copy = kmalloc(sizeof(struct pseries_hp_errorlog), - GFP_KERNEL); - memcpy(hp_errlog_copy, hp_errlog, sizeof(struct pseries_hp_errorlog)); + hp_errlog_copy = kmemdup(hp_errlog, sizeof(*hp_errlog), GFP_ATOMIC); + if (!hp_errlog_copy) + return; - work = kmalloc(sizeof(struct pseries_hp_work), GFP_KERNEL); + work = kmalloc(sizeof(struct pseries_hp_work), GFP_ATOMIC); if (work) { INIT_WORK((struct work_struct *)work, pseries_hp_work_fn); work->errlog = hp_errlog_copy; -- cgit v1.2.3 From 87997471c597d0594dc8c9346ecaafab83798cf3 Mon Sep 17 00:00:00 2001 From: Shaokun Zhang Date: Wed, 29 May 2019 17:21:51 +0800 Subject: powerpc/64s: Fix misleading SPR and timebase information pr_info shows SPR and timebase as a decimal value with a '0x' prefix, which is somewhat misleading. Fix it to print hexadecimal, as was intended. Fixes: 10d91611f426 ("powerpc/64s: Reimplement book3s idle code in C") Cc: Michael Ellerman Cc: Nicholas Piggin Signed-off-by: Shaokun Zhang Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/idle.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index c9133f7908ca..77f2e0a4ee37 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -1159,10 +1159,10 @@ static void __init pnv_power9_idle_init(void) pnv_deepest_stop_psscr_mask); } - pr_info("cpuidle-powernv: First stop level that may lose SPRs = 0x%lld\n", + pr_info("cpuidle-powernv: First stop level that may lose SPRs = 0x%llx\n", pnv_first_spr_loss_level); - pr_info("cpuidle-powernv: First stop level that may lose timebase = 0x%lld\n", + pr_info("cpuidle-powernv: First stop level that may lose timebase = 0x%llx\n", pnv_first_tb_loss_level); } -- cgit v1.2.3 From 9c9f8fb71feed144973a70455e0a4ee3da57ed2a Mon Sep 17 00:00:00 2001 From: Anju T Sudhakar Date: Mon, 10 Jun 2019 12:02:29 +0530 Subject: powerpc/perf: Use cpumask_last() to determine the designated cpu for nest/core units. Nest and core IMC (In-Memory Collection counters) assigns a particular cpu as the designated target for counter data collection. During system boot, the first online cpu in a chip gets assigned as the designated cpu for that chip(for nest-imc) and the first online cpu in a core gets assigned as the designated cpu for that core(for core-imc). If the designated cpu goes offline, the next online cpu from the same chip(for nest-imc)/core(for core-imc) is assigned as the next target, and the event context is migrated to the target cpu. Currently, cpumask_any_but() function is used to find the target cpu. Though this function is expected to return a `random` cpu, this always returns the next online cpu. If all cpus in a chip/core is offlined in a sequential manner, starting from the first cpu, the event migration has to happen for all the cpus which goes offline. Since the migration process involves a grace period, the total time taken to offline all the cpus will be significantly high. Example: In a system which has 2 sockets, with NUMA node0 CPU(s): 0-87 NUMA node8 CPU(s): 88-175 Time taken to offline cpu 88-175: real 2m56.099s user 0m0.191s sys 0m0.000s Use cpumask_last() to choose the target cpu, when the designated cpu goes online, so the migration will happen only when the last_cpu in the mask goes offline. This way the time taken to offline all cpus in a chip/core can be reduced. With the patch: Time taken to offline cpu 88-175: real 0m12.207s user 0m0.171s sys 0m0.000s Offlining all cpus in reverse order is also taken care because, cpumask_any_but() is used to find the designated cpu if the last cpu in the mask goes offline. Since cpumask_any_but() always return the first cpu in the mask, that becomes the designated cpu and migration will happen only when the first_cpu in the mask goes offline. Example: With the patch, Time taken to offline cpu from 175-88: real 0m9.330s user 0m0.110s sys 0m0.000s Signed-off-by: Anju T Sudhakar Reviewed-by: Madhavan Srinivasan Signed-off-by: Michael Ellerman --- arch/powerpc/perf/imc-pmu.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/perf/imc-pmu.c b/arch/powerpc/perf/imc-pmu.c index 3bdfc1e32096..dea243185ea4 100644 --- a/arch/powerpc/perf/imc-pmu.c +++ b/arch/powerpc/perf/imc-pmu.c @@ -362,7 +362,14 @@ static int ppc_nest_imc_cpu_offline(unsigned int cpu) */ nid = cpu_to_node(cpu); l_cpumask = cpumask_of_node(nid); - target = cpumask_any_but(l_cpumask, cpu); + target = cpumask_last(l_cpumask); + + /* + * If this(target) is the last cpu in the cpumask for this chip, + * check for any possible online cpu in the chip. + */ + if (unlikely(target == cpu)) + target = cpumask_any_but(l_cpumask, cpu); /* * Update the cpumask with the target cpu and @@ -667,7 +674,10 @@ static int ppc_core_imc_cpu_offline(unsigned int cpu) return 0; /* Find any online cpu in that core except the current "cpu" */ - ncpu = cpumask_any_but(cpu_sibling_mask(cpu), cpu); + ncpu = cpumask_last(cpu_sibling_mask(cpu)); + + if (unlikely(ncpu == cpu)) + ncpu = cpumask_any_but(cpu_sibling_mask(cpu), cpu); if (ncpu >= 0 && ncpu < nr_cpu_ids) { cpumask_set_cpu(ncpu, &core_imc_cpumask); -- cgit v1.2.3 From a72808a7ec5d340417a91a81e5cabdaa50650f2e Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 10 Jun 2019 13:08:16 +1000 Subject: powerpc/64: __ioremap_at clean up in the error case __ioremap_at error handling is wonky, it requires caller to clean up after it. Implement a helper that does the map and error cleanup and remove the requirement from the caller. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/mm/pgtable_64.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index d2d976ff8a0e..6bd3660388aa 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -108,14 +108,30 @@ unsigned long ioremap_bot; unsigned long ioremap_bot = IOREMAP_BASE; #endif +static int ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid) +{ + unsigned long i; + + for (i = 0; i < size; i += PAGE_SIZE) { + int err = map_kernel_page(ea + i, pa + i, prot); + if (err) { + if (slab_is_available()) + unmap_kernel_range(ea, size); + else + WARN_ON_ONCE(1); /* Should clean up */ + return err; + } + } + + return 0; +} + /** * __ioremap_at - Low level function to establish the page tables * for an IO mapping */ void __iomem *__ioremap_at(phys_addr_t pa, void *ea, unsigned long size, pgprot_t prot) { - unsigned long i; - /* We don't support the 4K PFN hack with ioremap */ if (pgprot_val(prot) & H_PAGE_4K_PFN) return NULL; @@ -129,9 +145,8 @@ void __iomem *__ioremap_at(phys_addr_t pa, void *ea, unsigned long size, pgprot_ WARN_ON(((unsigned long)ea) & ~PAGE_MASK); WARN_ON(size & ~PAGE_MASK); - for (i = 0; i < size; i += PAGE_SIZE) - if (map_kernel_page((unsigned long)ea + i, pa + i, prot)) - return NULL; + if (ioremap_range((unsigned long)ea, pa, size, prot, NUMA_NO_NODE)) + return NULL; return (void __iomem *)ea; } @@ -182,8 +197,6 @@ void __iomem * __ioremap_caller(phys_addr_t addr, unsigned long size, area->phys_addr = paligned; ret = __ioremap_at(paligned, area->addr, size, prot); - if (!ret) - vunmap(area->addr); } else { ret = __ioremap_at(paligned, (void *)ioremap_bot, size, prot); if (ret) -- cgit v1.2.3 From d38153f9ccc9b6b6a27a91559999292c27b72b8c Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 10 Jun 2019 13:08:17 +1000 Subject: powerpc/64s/radix: ioremap use ioremap_page_range Radix can use ioremap_page_range for ioremap, after slab is available. This makes it possible to enable huge ioremap mapping support. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/radix.h | 3 +++ arch/powerpc/mm/book3s64/pgtable.c | 21 +++++++++++++++++++++ arch/powerpc/mm/book3s64/radix_pgtable.c | 21 +++++++++++++++++++++ arch/powerpc/mm/pgtable_64.c | 2 +- 4 files changed, 46 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/book3s/64/radix.h b/arch/powerpc/include/asm/book3s/64/radix.h index 574eca33f893..e04a839cb5b9 100644 --- a/arch/powerpc/include/asm/book3s/64/radix.h +++ b/arch/powerpc/include/asm/book3s/64/radix.h @@ -266,6 +266,9 @@ extern void radix__vmemmap_remove_mapping(unsigned long start, extern int radix__map_kernel_page(unsigned long ea, unsigned long pa, pgprot_t flags, unsigned int psz); +extern int radix__ioremap_range(unsigned long ea, phys_addr_t pa, + unsigned long size, pgprot_t prot, int nid); + static inline unsigned long radix__get_tree_size(void) { unsigned long rts_field; diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c index 16bda049187a..ad3dd977c22d 100644 --- a/arch/powerpc/mm/book3s64/pgtable.c +++ b/arch/powerpc/mm/book3s64/pgtable.c @@ -447,3 +447,24 @@ int pmd_move_must_withdraw(struct spinlock *new_pmd_ptl, return true; } + +int ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid) +{ + unsigned long i; + + if (radix_enabled()) + return radix__ioremap_range(ea, pa, size, prot, nid); + + for (i = 0; i < size; i += PAGE_SIZE) { + int err = map_kernel_page(ea + i, pa + i, prot); + if (err) { + if (slab_is_available()) + unmap_kernel_range(ea, size); + else + WARN_ON_ONCE(1); /* Should clean up */ + return err; + } + } + + return 0; +} diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index c929d31f1043..06a5ff2ee626 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -11,6 +11,7 @@ #define pr_fmt(fmt) "radix-mmu: " fmt +#include #include #include #include @@ -1122,3 +1123,23 @@ void radix__ptep_modify_prot_commit(struct vm_area_struct *vma, set_pte_at(mm, addr, ptep, pte); } + +int radix__ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, + pgprot_t prot, int nid) +{ + if (likely(slab_is_available())) { + int err = ioremap_page_range(ea, ea + size, pa, prot); + if (err) + unmap_kernel_range(ea, size); + return err; + } else { + unsigned long i; + + for (i = 0; i < size; i += PAGE_SIZE) { + int err = map_kernel_page(ea + i, pa + i, prot); + if (WARN_ON_ONCE(err)) /* Should clean up */ + return err; + } + return 0; + } +} diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 6bd3660388aa..63cd81130643 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -108,7 +108,7 @@ unsigned long ioremap_bot; unsigned long ioremap_bot = IOREMAP_BASE; #endif -static int ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid) +int __weak ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid) { unsigned long i; -- cgit v1.2.3 From d909f9109c301f4e9e41678025c45d719ab8f7d7 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Mon, 10 Jun 2019 13:08:18 +1000 Subject: powerpc/64s/radix: Enable HAVE_ARCH_HUGE_VMAP This sets the HAVE_ARCH_HUGE_VMAP option, and defines the required page table functions. This enables huge (2MB and 1GB) ioremap mappings. I don't have a benchmark for this change, but huge vmap will be used by a later core kernel change to enable huge vmalloc memory mappings. This improves cached `git diff` performance by about 5% on a 2-node POWER9 with 32MB size dentry cache hash. Profiling git diff dTLB misses with a vanilla kernel: 81.75% git [kernel.vmlinux] [k] __d_lookup_rcu 7.21% git [kernel.vmlinux] [k] strncpy_from_user 1.77% git [kernel.vmlinux] [k] find_get_entry 1.59% git [kernel.vmlinux] [k] kmem_cache_free 40,168 dTLB-miss 0.100342754 seconds time elapsed With powerpc huge vmalloc: 2,987 dTLB-miss 0.095933138 seconds time elapsed Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- Documentation/admin-guide/kernel-parameters.txt | 2 +- arch/powerpc/Kconfig | 1 + arch/powerpc/include/asm/book3s/64/pgtable.h | 8 ++ arch/powerpc/mm/book3s64/radix_pgtable.c | 100 ++++++++++++++++++++++++ 4 files changed, 110 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt index 138f6664b2e2..a4c3538857e9 100644 --- a/Documentation/admin-guide/kernel-parameters.txt +++ b/Documentation/admin-guide/kernel-parameters.txt @@ -2927,7 +2927,7 @@ register save and restore. The kernel will only save legacy floating-point registers on task switch. - nohugeiomap [KNL,x86] Disable kernel huge I/O mappings. + nohugeiomap [KNL,x86,PPC] Disable kernel huge I/O mappings. nosmt [KNL,S390] Disable symmetric multithreading (SMT). Equivalent to smt=1. diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 8c1c636308c8..f0e5b38d52e8 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -167,6 +167,7 @@ config PPC select GENERIC_STRNLEN_USER select GENERIC_TIME_VSYSCALL select HAVE_ARCH_AUDITSYSCALL + select HAVE_ARCH_HUGE_VMAP if PPC_BOOK3S_64 && PPC_RADIX_MMU select HAVE_ARCH_JUMP_LABEL select HAVE_ARCH_KASAN if PPC32 select HAVE_ARCH_KGDB diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 7dede2e34b70..ac6eb9816b64 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -274,6 +274,14 @@ extern unsigned long __vmalloc_end; #define VMALLOC_START __vmalloc_start #define VMALLOC_END __vmalloc_end +static inline unsigned int ioremap_max_order(void) +{ + if (radix_enabled()) + return PUD_SHIFT; + return 7 + PAGE_SHIFT; /* default from linux/vmalloc.h */ +} +#define IOREMAP_MAX_ORDER ioremap_max_order() + extern unsigned long __kernel_virt_start; extern unsigned long __kernel_virt_size; extern unsigned long __kernel_io_start; diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index 06a5ff2ee626..8904aa1243d8 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -1124,6 +1124,106 @@ void radix__ptep_modify_prot_commit(struct vm_area_struct *vma, set_pte_at(mm, addr, ptep, pte); } +int __init arch_ioremap_pud_supported(void) +{ + /* HPT does not cope with large pages in the vmalloc area */ + return radix_enabled(); +} + +int __init arch_ioremap_pmd_supported(void) +{ + return radix_enabled(); +} + +int p4d_free_pud_page(p4d_t *p4d, unsigned long addr) +{ + return 0; +} + +int pud_set_huge(pud_t *pud, phys_addr_t addr, pgprot_t prot) +{ + pte_t *ptep = (pte_t *)pud; + pte_t new_pud = pfn_pte(__phys_to_pfn(addr), prot); + + if (!radix_enabled()) + return 0; + + set_pte_at(&init_mm, 0 /* radix unused */, ptep, new_pud); + + return 1; +} + +int pud_clear_huge(pud_t *pud) +{ + if (pud_huge(*pud)) { + pud_clear(pud); + return 1; + } + + return 0; +} + +int pud_free_pmd_page(pud_t *pud, unsigned long addr) +{ + pmd_t *pmd; + int i; + + pmd = (pmd_t *)pud_page_vaddr(*pud); + pud_clear(pud); + + flush_tlb_kernel_range(addr, addr + PUD_SIZE); + + for (i = 0; i < PTRS_PER_PMD; i++) { + if (!pmd_none(pmd[i])) { + pte_t *pte; + pte = (pte_t *)pmd_page_vaddr(pmd[i]); + + pte_free_kernel(&init_mm, pte); + } + } + + pmd_free(&init_mm, pmd); + + return 1; +} + +int pmd_set_huge(pmd_t *pmd, phys_addr_t addr, pgprot_t prot) +{ + pte_t *ptep = (pte_t *)pmd; + pte_t new_pmd = pfn_pte(__phys_to_pfn(addr), prot); + + if (!radix_enabled()) + return 0; + + set_pte_at(&init_mm, 0 /* radix unused */, ptep, new_pmd); + + return 1; +} + +int pmd_clear_huge(pmd_t *pmd) +{ + if (pmd_huge(*pmd)) { + pmd_clear(pmd); + return 1; + } + + return 0; +} + +int pmd_free_pte_page(pmd_t *pmd, unsigned long addr) +{ + pte_t *pte; + + pte = (pte_t *)pmd_page_vaddr(*pmd); + pmd_clear(pmd); + + flush_tlb_kernel_range(addr, addr + PMD_SIZE); + + pte_free_kernel(&init_mm, pte); + + return 1; +} + int radix__ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, pgprot_t prot, int nid) { -- cgit v1.2.3 From df5be5be8735ef2ae80d5ae1f2453cd81a035c4b Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 5 Jun 2019 13:38:14 +1000 Subject: powerpc/pci/of: Fix OF flags parsing for 64bit BARs When the firmware does PCI BAR resource allocation, it passes the assigned addresses and flags (prefetch/64bit/...) via the "reg" property of a PCI device device tree node so the kernel does not need to do resource allocation. The flags are stored in resource::flags - the lower byte stores PCI_BASE_ADDRESS_SPACE/etc bits and the other bytes are IORESOURCE_IO/etc. Some flags from PCI_BASE_ADDRESS_xxx and IORESOURCE_xxx are duplicated, such as PCI_BASE_ADDRESS_MEM_PREFETCH/PCI_BASE_ADDRESS_MEM_TYPE_64/etc. When parsing the "reg" property, we copy the prefetch flag but we skip on PCI_BASE_ADDRESS_MEM_TYPE_64 which leaves the flags out of sync. The missing IORESOURCE_MEM_64 flag comes into play under 2 conditions: 1. we remove PCI_PROBE_ONLY for pseries (by hacking pSeries_setup_arch() or by passing "/chosen/linux,pci-probe-only"); 2. we request resource alignment (by passing pci=resource_alignment= via the kernel cmd line to request PAGE_SIZE alignment or defining ppc_md.pcibios_default_alignment which returns anything but 0). Note that the alignment requests are ignored if PCI_PROBE_ONLY is enabled. With 1) and 2), the generic PCI code in the kernel unconditionally decides to: - reassign the BARs in pci_specified_resource_alignment() (works fine) - write new BARs to the device - this fails for 64bit BARs as the generic code looks at IORESOURCE_MEM_64 (not set) and writes only lower 32bits of the BAR and leaves the upper 32bit unmodified which breaks BAR mapping in the hypervisor. This fixes the issue by copying the flag. This is useful if we want to enforce certain BAR alignment per platform as handling subpage sized BARs is proven to cause problems with hotplug (SLOF already aligns BARs to 64k). Signed-off-by: Alexey Kardashevskiy Reviewed-by: Sam Bobroff Reviewed-by: Oliver O'Halloran Reviewed-by: Shawn Anastasio Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/pci_of_scan.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 24191ea2d9a7..64ad92016b63 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -45,6 +45,8 @@ unsigned int pci_parse_of_flags(u32 addr0, int bridge) if (addr0 & 0x02000000) { flags = IORESOURCE_MEM | PCI_BASE_ADDRESS_SPACE_MEMORY; flags |= (addr0 >> 22) & PCI_BASE_ADDRESS_MEM_TYPE_64; + if (flags & PCI_BASE_ADDRESS_MEM_TYPE_64) + flags |= IORESOURCE_MEM_64; flags |= (addr0 >> 28) & PCI_BASE_ADDRESS_MEM_TYPE_1M; if (addr0 & 0x40000000) flags |= IORESOURCE_PREFETCH -- cgit v1.2.3 From 869537709ebf1dc865e75c3fc97b23f8acf37c16 Mon Sep 17 00:00:00 2001 From: Suraj Jitindar Singh Date: Thu, 20 Jun 2019 11:46:50 +1000 Subject: KVM: PPC: Book3S HV: Signed extend decrementer value if not using large decrementer On POWER9 the decrementer can operate in large decrementer mode where the decrementer is 56 bits and signed extended to 64 bits. When not operating in this mode the decrementer behaves as a 32 bit decrementer which is NOT signed extended (as on POWER8). Currently when reading a guest decrementer value we don't take into account whether the large decrementer is enabled or not, and this means the value will be incorrect when the guest is not using the large decrementer. Fix this by sign extending the value read when the guest isn't using the large decrementer. Fixes: 95a6432ce903 ("KVM: PPC: Book3S HV: Streamlined guest entry/exit path on P9 for radix guests") Cc: stable@vger.kernel.org # v4.20+ Signed-off-by: Suraj Jitindar Singh Signed-off-by: Michael Ellerman --- arch/powerpc/kvm/book3s_hv.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index d5fc624e0655..ffd891ddaa2d 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -3607,6 +3607,8 @@ int kvmhv_p9_guest_entry(struct kvm_vcpu *vcpu, u64 time_limit, vcpu->arch.slb_max = 0; dec = mfspr(SPRN_DEC); + if (!(lpcr & LPCR_LD)) /* Sign extend if not using large decrementer */ + dec = (s32) dec; tb = mftb(); vcpu->arch.dec_expires = dec + tb; vcpu->cpu = -1; -- cgit v1.2.3 From 3c25ab35fbc8526ac0c9b298e8a78e7ad7a55479 Mon Sep 17 00:00:00 2001 From: Suraj Jitindar Singh Date: Thu, 20 Jun 2019 11:46:51 +1000 Subject: KVM: PPC: Book3S HV: Clear pending decrementer exceptions on nested guest entry If we enter an L1 guest with a pending decrementer exception then this is cleared on guest exit if the guest has writtien a positive value into the decrementer (indicating that it handled the decrementer exception) since there is no other way to detect that the guest has handled the pending exception and that it should be dequeued. In the event that the L1 guest tries to run a nested (L2) guest immediately after this and the L2 guest decrementer is negative (which is loaded by L1 before making the H_ENTER_NESTED hcall), then the pending decrementer exception isn't cleared and the L2 entry is blocked since L1 has a pending exception, even though L1 may have already handled the exception and written a positive value for it's decrementer. This results in a loop of L1 trying to enter the L2 guest and L0 blocking the entry since L1 has an interrupt pending with the outcome being that L2 never gets to run and hangs. Fix this by clearing any pending decrementer exceptions when L1 makes the H_ENTER_NESTED hcall since it won't do this if it's decrementer has gone negative, and anyway it's decrementer has been communicated to L0 in the hdec_expires field and L0 will return control to L1 when this goes negative by delivering an H_DECREMENTER exception. Fixes: 95a6432ce903 ("KVM: PPC: Book3S HV: Streamlined guest entry/exit path on P9 for radix guests") Cc: stable@vger.kernel.org # v4.20+ Signed-off-by: Suraj Jitindar Singh Signed-off-by: Michael Ellerman --- arch/powerpc/kvm/book3s_hv.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index ffd891ddaa2d..a104743291a9 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -4124,8 +4124,15 @@ int kvmhv_run_single_vcpu(struct kvm_run *kvm_run, preempt_enable(); - /* cancel pending decrementer exception if DEC is now positive */ - if (get_tb() < vcpu->arch.dec_expires && kvmppc_core_pending_dec(vcpu)) + /* + * cancel pending decrementer exception if DEC is now positive, or if + * entering a nested guest in which case the decrementer is now owned + * by L2 and the L1 decrementer is provided in hdec_expires + */ + if (kvmppc_core_pending_dec(vcpu) && + ((get_tb() < vcpu->arch.dec_expires) || + (trap == BOOK3S_INTERRUPT_SYSCALL && + kvmppc_get_gpr(vcpu, 3) == H_ENTER_NESTED))) kvmppc_core_dequeue_dec(vcpu); trace_kvm_guest_exit(vcpu); -- cgit v1.2.3 From 9fb603050ffd94f8127df99c699cca2f575eb6a0 Mon Sep 17 00:00:00 2001 From: Nathan Lynch Date: Fri, 21 Jun 2019 01:05:18 -0500 Subject: powerpc/rtas: retry when cpu offline races with suspend/migration The protocol for suspending or migrating an LPAR requires all present processor threads to enter H_JOIN. So if we have threads offline, we have to temporarily bring them up. This can race with administrator actions such as SMT state changes. As of dfd718a2ed1f ("powerpc/rtas: Fix a potential race between CPU-Offline & Migration"), rtas_ibm_suspend_me() accounts for this, but errors out with -EBUSY for what almost certainly is a transient condition in any reasonable scenario. Callers of rtas_ibm_suspend_me() already retry when -EAGAIN is returned, and it is typical during a migration for that to happen repeatedly for several minutes polling the H_VASI_STATE hcall result before proceeding to the next stage. So return -EAGAIN instead of -EBUSY when this race is encountered. Additionally: logging this event is still appropriate but use pr_info instead of pr_err; and remove use of unlikely() while here as this is not a hot path at all. Fixes: dfd718a2ed1f ("powerpc/rtas: Fix a potential race between CPU-Offline & Migration") Signed-off-by: Nathan Lynch Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/rtas.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c index fbc676160adf..9b4d2a2ffb4f 100644 --- a/arch/powerpc/kernel/rtas.c +++ b/arch/powerpc/kernel/rtas.c @@ -984,10 +984,9 @@ int rtas_ibm_suspend_me(u64 handle) cpu_hotplug_disable(); /* Check if we raced with a CPU-Offline Operation */ - if (unlikely(!cpumask_equal(cpu_present_mask, cpu_online_mask))) { - pr_err("%s: Raced against a concurrent CPU-Offline\n", - __func__); - atomic_set(&data.error, -EBUSY); + if (!cpumask_equal(cpu_present_mask, cpu_online_mask)) { + pr_info("%s: Raced against a concurrent CPU-Offline\n", __func__); + atomic_set(&data.error, -EAGAIN); goto out_hotplug_enable; } -- cgit v1.2.3 From f079bb3c5f2978b2c1a13098ab2a8c32e5d1ee3d Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 7 May 2019 13:31:38 +0000 Subject: powerpc/ftrace: Enable C Version of recordmcount Selects HAVE_C_RECORDMCOUNT to use the C version of the recordmcount intead of the old Perl Version of recordmcount. This should improve build time. It also seems like the old Perl Version misses some calls to _mcount that the C version finds. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index f0e5b38d52e8..3adff91bc856 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -176,6 +176,7 @@ config PPC select HAVE_ARCH_NVRAM_OPS select HAVE_ARCH_SECCOMP_FILTER select HAVE_ARCH_TRACEHOOK + select HAVE_C_RECORDMCOUNT select HAVE_CBPF_JIT if !PPC64 select HAVE_STACKPROTECTOR if PPC64 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r13) select HAVE_STACKPROTECTOR if PPC32 && $(cc-option,-mstack-protector-guard=tls -mstack-protector-guard-reg=r2) -- cgit v1.2.3 From 3becd11dffe5d4a7467ebd841172f3e091fbcbd0 Mon Sep 17 00:00:00 2001 From: Qian Cai Date: Wed, 5 Jun 2019 16:46:19 -0400 Subject: powerpc/eeh_cache: fix a W=1 kernel-doc warning The opening comment mark "/**" is reserved for kernel-doc comments, so it will generate a warning with "make W=1". arch/powerpc/kernel/eeh_cache.c:37: warning: cannot understand function prototype: 'struct pci_io_addr_range Since this is not a kernel-doc for the struct below, but rather an overview of this source eeh_cache.c, just use the free-form comments kernel-doc syntax instead. Signed-off-by: Qian Cai Acked-by: Russell Currey Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/eeh_cache.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/eeh_cache.c b/arch/powerpc/kernel/eeh_cache.c index 9c68f0837385..52c57d883e4a 100644 --- a/arch/powerpc/kernel/eeh_cache.c +++ b/arch/powerpc/kernel/eeh_cache.c @@ -31,6 +31,8 @@ /** + * DOC: Overview + * * The pci address cache subsystem. This subsystem places * PCI device address resources into a red-black tree, sorted * according to the address range, so that given only an i/o @@ -47,6 +49,7 @@ * than any hash algo I could think of for this problem, even * with the penalty of slow pointer chases for d-cache misses). */ + struct pci_io_addr_range { struct rb_node rb_node; resource_size_t addr_lo; -- cgit v1.2.3 From 04db3ede40ae4fc23a5c4237254c4a53bbe4c1f2 Mon Sep 17 00:00:00 2001 From: Qian Cai Date: Thu, 6 Jun 2019 09:58:13 -0400 Subject: powerpc/cacheflush: fix variable set but not used The powerpc's flush_cache_vmap() is defined as a macro and never use both of its arguments, so it will generate a compilation warning, lib/ioremap.c: In function 'ioremap_page_range': lib/ioremap.c:203:16: warning: variable 'start' set but not used [-Wunused-but-set-variable] Fix it by making it an inline function. Signed-off-by: Qian Cai Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/cacheflush.h | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index d5a8d7bf0759..b189f7aee222 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -32,9 +32,12 @@ * not expect this type of fault. flush_cache_vmap is not exactly the right * place to put this, but it seems to work well enough. */ -#define flush_cache_vmap(start, end) do { asm volatile("ptesync" ::: "memory"); } while (0) +static inline void flush_cache_vmap(unsigned long start, unsigned long end) +{ + asm volatile("ptesync" ::: "memory"); +} #else -#define flush_cache_vmap(start, end) do { } while (0) +static inline void flush_cache_vmap(unsigned long start, unsigned long end) { } #endif #define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 -- cgit v1.2.3 From aaf06665f7ea3ee9f9754e16c1a507a89f1de5b1 Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Thu, 27 Jun 2019 15:29:40 +0530 Subject: powerpc/xmon: Fix disabling tracing while in xmon Commit ed49f7fd6438d ("powerpc/xmon: Disable tracing when entering xmon") added code to disable recording trace entries while in xmon. The commit introduced a variable 'tracing_enabled' to record if tracing was enabled on xmon entry, and used this to conditionally enable tracing during exit from xmon. However, we are not checking the value of 'fromipi' variable in xmon_core() when setting 'tracing_enabled'. Due to this, when secondary cpus enter xmon, they will see tracing as being disabled already and tracing won't be re-enabled on exit. Fix the same. Fixes: ed49f7fd6438d ("powerpc/xmon: Disable tracing when entering xmon") Signed-off-by: Naveen N. Rao Signed-off-by: Michael Ellerman --- arch/powerpc/xmon/xmon.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index 1b0149b2bb6c..f1c4e1601b9d 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -469,8 +469,10 @@ static int xmon_core(struct pt_regs *regs, int fromipi) local_irq_save(flags); hard_irq_disable(); - tracing_enabled = tracing_is_on(); - tracing_off(); + if (!fromipi) { + tracing_enabled = tracing_is_on(); + tracing_off(); + } bp = in_breakpoint_table(regs->nip, &offset); if (bp != NULL) { -- cgit v1.2.3 From 63982618662e2a05e5c5c3e4247456d1d3467f32 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 25 Jun 2019 16:52:36 +0200 Subject: powerpc/powernv: remove the unused pnv_pci_set_p2p function This function has never been used anywhere in the kernel tree since it was added to the tree. We also now have proper PCIe P2P APIs in the core kernel, and any new P2P support should be using those. Signed-off-by: Christoph Hellwig Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/opal.h | 2 - arch/powerpc/include/asm/pnv-pci.h | 2 - arch/powerpc/platforms/powernv/opal-call.c | 1 - arch/powerpc/platforms/powernv/pci.c | 74 ------------------------------ arch/powerpc/platforms/powernv/pci.h | 5 -- 5 files changed, 84 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h index 4cc37e708bc7..15c488ce4225 100644 --- a/arch/powerpc/include/asm/opal.h +++ b/arch/powerpc/include/asm/opal.h @@ -287,8 +287,6 @@ int64_t opal_xive_set_queue_state(uint64_t vp, uint32_t prio, uint32_t qtoggle, uint32_t qindex); int64_t opal_xive_get_vp_state(uint64_t vp, __be64 *out_w01); -int64_t opal_pci_set_p2p(uint64_t phb_init, uint64_t phb_target, - uint64_t desc, uint16_t pe_number); int64_t opal_imc_counters_init(uint32_t type, uint64_t address, uint64_t cpu_pir); diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h index 630eb8b1b7ed..9fcb0bc462c6 100644 --- a/arch/powerpc/include/asm/pnv-pci.h +++ b/arch/powerpc/include/asm/pnv-pci.h @@ -26,8 +26,6 @@ extern int pnv_pci_get_presence_state(uint64_t id, uint8_t *state); extern int pnv_pci_get_power_state(uint64_t id, uint8_t *state); extern int pnv_pci_set_power_state(uint64_t id, uint8_t state, struct opal_msg *msg); -extern int pnv_pci_set_p2p(struct pci_dev *initiator, struct pci_dev *target, - u64 desc); extern int pnv_pci_enable_tunnel(struct pci_dev *dev, uint64_t *asnind); extern int pnv_pci_disable_tunnel(struct pci_dev *dev); diff --git a/arch/powerpc/platforms/powernv/opal-call.c b/arch/powerpc/platforms/powernv/opal-call.c index 36c8fa3647a2..29ca523c1c79 100644 --- a/arch/powerpc/platforms/powernv/opal-call.c +++ b/arch/powerpc/platforms/powernv/opal-call.c @@ -273,7 +273,6 @@ OPAL_CALL(opal_npu_map_lpar, OPAL_NPU_MAP_LPAR); OPAL_CALL(opal_imc_counters_init, OPAL_IMC_COUNTERS_INIT); OPAL_CALL(opal_imc_counters_start, OPAL_IMC_COUNTERS_START); OPAL_CALL(opal_imc_counters_stop, OPAL_IMC_COUNTERS_STOP); -OPAL_CALL(opal_pci_set_p2p, OPAL_PCI_SET_P2P); OPAL_CALL(opal_get_powercap, OPAL_GET_POWERCAP); OPAL_CALL(opal_set_powercap, OPAL_SET_POWERCAP); OPAL_CALL(opal_get_power_shift_ratio, OPAL_GET_POWER_SHIFT_RATIO); diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index ef9448a907c6..8d28f2932c3b 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -38,7 +38,6 @@ #include "powernv.h" #include "pci.h" -static DEFINE_MUTEX(p2p_mutex); static DEFINE_MUTEX(tunnel_mutex); int pnv_pci_get_slot_id(struct device_node *np, uint64_t *id) @@ -861,79 +860,6 @@ void pnv_pci_dma_bus_setup(struct pci_bus *bus) } } -int pnv_pci_set_p2p(struct pci_dev *initiator, struct pci_dev *target, u64 desc) -{ - struct pci_controller *hose; - struct pnv_phb *phb_init, *phb_target; - struct pnv_ioda_pe *pe_init; - int rc; - - if (!opal_check_token(OPAL_PCI_SET_P2P)) - return -ENXIO; - - hose = pci_bus_to_host(initiator->bus); - phb_init = hose->private_data; - - hose = pci_bus_to_host(target->bus); - phb_target = hose->private_data; - - pe_init = pnv_ioda_get_pe(initiator); - if (!pe_init) - return -ENODEV; - - /* - * Configuring the initiator's PHB requires to adjust its - * TVE#1 setting. Since the same device can be an initiator - * several times for different target devices, we need to keep - * a reference count to know when we can restore the default - * bypass setting on its TVE#1 when disabling. Opal is not - * tracking PE states, so we add a reference count on the PE - * in linux. - * - * For the target, the configuration is per PHB, so we keep a - * target reference count on the PHB. - */ - mutex_lock(&p2p_mutex); - - if (desc & OPAL_PCI_P2P_ENABLE) { - /* always go to opal to validate the configuration */ - rc = opal_pci_set_p2p(phb_init->opal_id, phb_target->opal_id, - desc, pe_init->pe_number); - - if (rc != OPAL_SUCCESS) { - rc = -EIO; - goto out; - } - - pe_init->p2p_initiator_count++; - phb_target->p2p_target_count++; - } else { - if (!pe_init->p2p_initiator_count || - !phb_target->p2p_target_count) { - rc = -EINVAL; - goto out; - } - - if (--pe_init->p2p_initiator_count == 0) - pnv_pci_ioda2_set_bypass(pe_init, true); - - if (--phb_target->p2p_target_count == 0) { - rc = opal_pci_set_p2p(phb_init->opal_id, - phb_target->opal_id, desc, - pe_init->pe_number); - if (rc != OPAL_SUCCESS) { - rc = -EIO; - goto out; - } - } - } - rc = 0; -out: - mutex_unlock(&p2p_mutex); - return rc; -} -EXPORT_SYMBOL_GPL(pnv_pci_set_p2p); - struct device_node *pnv_pci_get_phb_node(struct pci_dev *dev) { struct pci_controller *hose = pci_bus_to_host(dev->bus); diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index be26ab3d99e0..4f11c077af62 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -79,9 +79,6 @@ struct pnv_ioda_pe { struct pnv_ioda_pe *master; struct list_head slaves; - /* PCI peer-to-peer*/ - int p2p_initiator_count; - /* Link in list of PE#s */ struct list_head list; }; @@ -172,8 +169,6 @@ struct pnv_phb { /* PHB and hub diagnostics */ unsigned int diag_data_size; u8 *diag_data; - - int p2p_target_count; }; extern struct pci_ops pnv_pci_ops; -- cgit v1.2.3 From c498a4f9a79187029ed748ca0a7cacc35b74d28d Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 25 Jun 2019 16:52:37 +0200 Subject: powerpc/powernv: remove the unused tunneling exports These have been unused anywhere in the kernel tree ever since they've been added to the kernel. Signed-off-by: Christoph Hellwig Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pnv-pci.h | 4 -- arch/powerpc/platforms/powernv/pci-ioda.c | 4 +- arch/powerpc/platforms/powernv/pci.c | 71 ------------------------------- arch/powerpc/platforms/powernv/pci.h | 1 - 4 files changed, 3 insertions(+), 77 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/pnv-pci.h b/arch/powerpc/include/asm/pnv-pci.h index 9fcb0bc462c6..1ab4b0111abc 100644 --- a/arch/powerpc/include/asm/pnv-pci.h +++ b/arch/powerpc/include/asm/pnv-pci.h @@ -27,12 +27,8 @@ extern int pnv_pci_get_power_state(uint64_t id, uint8_t *state); extern int pnv_pci_set_power_state(uint64_t id, uint8_t state, struct opal_msg *msg); -extern int pnv_pci_enable_tunnel(struct pci_dev *dev, uint64_t *asnind); -extern int pnv_pci_disable_tunnel(struct pci_dev *dev); extern int pnv_pci_set_tunnel_bar(struct pci_dev *dev, uint64_t addr, int enable); -extern int pnv_pci_get_as_notify_info(struct task_struct *task, u32 *lpid, - u32 *pid, u32 *tid); int pnv_phb_to_cxl_mode(struct pci_dev *dev, uint64_t mode); int pnv_cxl_ioda_msi_setup(struct pci_dev *dev, unsigned int hwirq, unsigned int virq); diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 126602b4e399..6b0caa2d0425 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -54,6 +54,8 @@ static const char * const pnv_phb_names[] = { "IODA1", "IODA2", "NPU_NVLINK", "NPU_OCAPI" }; +static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable); + void pe_level_printk(const struct pnv_ioda_pe *pe, const char *level, const char *fmt, ...) { @@ -2360,7 +2362,7 @@ static long pnv_pci_ioda2_set_window(struct iommu_table_group *table_group, return 0; } -void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable) +static void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable) { uint16_t window_id = (pe->pe_number << 1 ) + 1; int64_t rc; diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c index 8d28f2932c3b..fc69f5611020 100644 --- a/arch/powerpc/platforms/powernv/pci.c +++ b/arch/powerpc/platforms/powernv/pci.c @@ -868,54 +868,6 @@ struct device_node *pnv_pci_get_phb_node(struct pci_dev *dev) } EXPORT_SYMBOL(pnv_pci_get_phb_node); -int pnv_pci_enable_tunnel(struct pci_dev *dev, u64 *asnind) -{ - struct device_node *np; - const __be32 *prop; - struct pnv_ioda_pe *pe; - uint16_t window_id; - int rc; - - if (!radix_enabled()) - return -ENXIO; - - if (!(np = pnv_pci_get_phb_node(dev))) - return -ENXIO; - - prop = of_get_property(np, "ibm,phb-indications", NULL); - of_node_put(np); - - if (!prop || !prop[1]) - return -ENXIO; - - *asnind = (u64)be32_to_cpu(prop[1]); - pe = pnv_ioda_get_pe(dev); - if (!pe) - return -ENODEV; - - /* Increase real window size to accept as_notify messages. */ - window_id = (pe->pe_number << 1 ) + 1; - rc = opal_pci_map_pe_dma_window_real(pe->phb->opal_id, pe->pe_number, - window_id, pe->tce_bypass_base, - (uint64_t)1 << 48); - return opal_error_code(rc); -} -EXPORT_SYMBOL_GPL(pnv_pci_enable_tunnel); - -int pnv_pci_disable_tunnel(struct pci_dev *dev) -{ - struct pnv_ioda_pe *pe; - - pe = pnv_ioda_get_pe(dev); - if (!pe) - return -ENODEV; - - /* Restore default real window size. */ - pnv_pci_ioda2_set_bypass(pe, true); - return 0; -} -EXPORT_SYMBOL_GPL(pnv_pci_disable_tunnel); - int pnv_pci_set_tunnel_bar(struct pci_dev *dev, u64 addr, int enable) { __be64 val; @@ -970,29 +922,6 @@ out: } EXPORT_SYMBOL_GPL(pnv_pci_set_tunnel_bar); -#ifdef CONFIG_PPC64 /* for thread.tidr */ -int pnv_pci_get_as_notify_info(struct task_struct *task, u32 *lpid, u32 *pid, - u32 *tid) -{ - struct mm_struct *mm = NULL; - - if (task == NULL) - return -EINVAL; - - mm = get_task_mm(task); - if (mm == NULL) - return -EINVAL; - - *pid = mm->context.id; - mmput(mm); - - *tid = task->thread.tidr; - *lpid = mfspr(SPRN_LPID); - return 0; -} -EXPORT_SYMBOL_GPL(pnv_pci_get_as_notify_info); -#endif - void pnv_pci_shutdown(void) { struct pci_controller *hose; diff --git a/arch/powerpc/platforms/powernv/pci.h b/arch/powerpc/platforms/powernv/pci.h index 4f11c077af62..469c24463247 100644 --- a/arch/powerpc/platforms/powernv/pci.h +++ b/arch/powerpc/platforms/powernv/pci.h @@ -195,7 +195,6 @@ extern int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type); extern void pnv_teardown_msi_irqs(struct pci_dev *pdev); extern struct pnv_ioda_pe *pnv_ioda_get_pe(struct pci_dev *dev); extern void pnv_set_msi_irq_chip(struct pnv_phb *phb, unsigned int virq); -extern void pnv_pci_ioda2_set_bypass(struct pnv_ioda_pe *pe, bool enable); extern unsigned long pnv_pci_ioda2_get_table_size(__u32 page_shift, __u64 window_size, __u32 levels); extern int pnv_eeh_post_init(void); -- cgit v1.2.3 From 7eb3cf761927b2687164e182efa675e6c09cfe44 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 25 Jun 2019 16:52:38 +0200 Subject: powerpc/powernv: remove unused NPU DMA code None of these routines were ever used anywhere in the kernel tree since they were added to the kernel. Signed-off-by: Christoph Hellwig Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/mmu.h | 2 - arch/powerpc/include/asm/powernv.h | 22 -- arch/powerpc/mm/book3s64/mmu_context.c | 1 - arch/powerpc/platforms/powernv/npu-dma.c | 556 ------------------------------- 4 files changed, 581 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/book3s/64/mmu.h b/arch/powerpc/include/asm/book3s/64/mmu.h index 74d24201fc4f..23b83d3593e2 100644 --- a/arch/powerpc/include/asm/book3s/64/mmu.h +++ b/arch/powerpc/include/asm/book3s/64/mmu.h @@ -116,8 +116,6 @@ typedef struct { /* Number of users of the external (Nest) MMU */ atomic_t copros; - /* NPU NMMU context */ - struct npu_context *npu_context; struct hash_mm_context *hash_context; unsigned long vdso_base; diff --git a/arch/powerpc/include/asm/powernv.h b/arch/powerpc/include/asm/powernv.h index 05b552418519..40f868c5e93c 100644 --- a/arch/powerpc/include/asm/powernv.h +++ b/arch/powerpc/include/asm/powernv.h @@ -11,35 +11,13 @@ #define _ASM_POWERNV_H #ifdef CONFIG_PPC_POWERNV -#define NPU2_WRITE 1 extern void powernv_set_nmmu_ptcr(unsigned long ptcr); -extern struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, - unsigned long flags, - void (*cb)(struct npu_context *, void *), - void *priv); -extern void pnv_npu2_destroy_context(struct npu_context *context, - struct pci_dev *gpdev); -extern int pnv_npu2_handle_fault(struct npu_context *context, uintptr_t *ea, - unsigned long *flags, unsigned long *status, - int count); void pnv_program_cpu_hotplug_lpcr(unsigned int cpu, u64 lpcr_val); void pnv_tm_init(void); #else static inline void powernv_set_nmmu_ptcr(unsigned long ptcr) { } -static inline struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, - unsigned long flags, - struct npu_context *(*cb)(struct npu_context *, void *), - void *priv) { return ERR_PTR(-ENODEV); } -static inline void pnv_npu2_destroy_context(struct npu_context *context, - struct pci_dev *gpdev) { } - -static inline int pnv_npu2_handle_fault(struct npu_context *context, - uintptr_t *ea, unsigned long *flags, - unsigned long *status, int count) { - return -ENODEV; -} static inline void pnv_tm_init(void) { } #endif diff --git a/arch/powerpc/mm/book3s64/mmu_context.c b/arch/powerpc/mm/book3s64/mmu_context.c index 6d8f06b04022..e2b78fb29fea 100644 --- a/arch/powerpc/mm/book3s64/mmu_context.c +++ b/arch/powerpc/mm/book3s64/mmu_context.c @@ -179,7 +179,6 @@ static int radix__init_new_context(struct mm_struct *mm) */ asm volatile("ptesync;isync" : : : "memory"); - mm->context.npu_context = NULL; mm->context.hash_context = NULL; return index; diff --git a/arch/powerpc/platforms/powernv/npu-dma.c b/arch/powerpc/platforms/powernv/npu-dma.c index dc1058efc24f..72b7441029ca 100644 --- a/arch/powerpc/platforms/powernv/npu-dma.c +++ b/arch/powerpc/platforms/powernv/npu-dma.c @@ -22,12 +22,6 @@ #include "pci.h" -/* - * spinlock to protect initialisation of an npu_context for a particular - * mm_struct. - */ -static DEFINE_SPINLOCK(npu_context_lock); - static struct pci_dev *get_pci_dev(struct device_node *dn) { struct pci_dn *pdn = PCI_DN(dn); @@ -375,15 +369,6 @@ struct npu_comp { /* An NPU descriptor, valid for POWER9 only */ struct npu { int index; - __be64 *mmio_atsd_regs[NV_NMMU_ATSD_REGS]; - unsigned int mmio_atsd_count; - - /* Bitmask for MMIO register usage */ - unsigned long mmio_atsd_usage; - - /* Do we need to explicitly flush the nest mmu? */ - bool nmmu_flush; - struct npu_comp npucomp; }; @@ -640,534 +625,8 @@ struct iommu_table_group *pnv_npu_compound_attach(struct pnv_ioda_pe *pe) } #endif /* CONFIG_IOMMU_API */ -/* Maximum number of nvlinks per npu */ -#define NV_MAX_LINKS 6 - -/* Maximum index of npu2 hosts in the system. Always < NV_MAX_NPUS */ -static int max_npu2_index; - -struct npu_context { - struct mm_struct *mm; - struct pci_dev *npdev[NV_MAX_NPUS][NV_MAX_LINKS]; - struct mmu_notifier mn; - struct kref kref; - bool nmmu_flush; - - /* Callback to stop translation requests on a given GPU */ - void (*release_cb)(struct npu_context *context, void *priv); - - /* - * Private pointer passed to the above callback for usage by - * device drivers. - */ - void *priv; -}; - -struct mmio_atsd_reg { - struct npu *npu; - int reg; -}; - -/* - * Find a free MMIO ATSD register and mark it in use. Return -ENOSPC - * if none are available. - */ -static int get_mmio_atsd_reg(struct npu *npu) -{ - int i; - - for (i = 0; i < npu->mmio_atsd_count; i++) { - if (!test_bit(i, &npu->mmio_atsd_usage)) - if (!test_and_set_bit_lock(i, &npu->mmio_atsd_usage)) - return i; - } - - return -ENOSPC; -} - -static void put_mmio_atsd_reg(struct npu *npu, int reg) -{ - clear_bit_unlock(reg, &npu->mmio_atsd_usage); -} - -/* MMIO ATSD register offsets */ -#define XTS_ATSD_LAUNCH 0 -#define XTS_ATSD_AVA 1 -#define XTS_ATSD_STAT 2 - -static unsigned long get_atsd_launch_val(unsigned long pid, unsigned long psize) -{ - unsigned long launch = 0; - - if (psize == MMU_PAGE_COUNT) { - /* IS set to invalidate entire matching PID */ - launch |= PPC_BIT(12); - } else { - /* AP set to invalidate region of psize */ - launch |= (u64)mmu_get_ap(psize) << PPC_BITLSHIFT(17); - } - - /* PRS set to process-scoped */ - launch |= PPC_BIT(13); - - /* PID */ - launch |= pid << PPC_BITLSHIFT(38); - - /* Leave "No flush" (bit 39) 0 so every ATSD performs a flush */ - - return launch; -} - -static void mmio_atsd_regs_write(struct mmio_atsd_reg - mmio_atsd_reg[NV_MAX_NPUS], unsigned long offset, - unsigned long val) -{ - struct npu *npu; - int i, reg; - - for (i = 0; i <= max_npu2_index; i++) { - reg = mmio_atsd_reg[i].reg; - if (reg < 0) - continue; - - npu = mmio_atsd_reg[i].npu; - __raw_writeq_be(val, npu->mmio_atsd_regs[reg] + offset); - } -} - -static void mmio_invalidate_pid(struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS], - unsigned long pid) -{ - unsigned long launch = get_atsd_launch_val(pid, MMU_PAGE_COUNT); - - /* Invalidating the entire process doesn't use a va */ - mmio_atsd_regs_write(mmio_atsd_reg, XTS_ATSD_LAUNCH, launch); -} - -static void mmio_invalidate_range(struct mmio_atsd_reg - mmio_atsd_reg[NV_MAX_NPUS], unsigned long pid, - unsigned long start, unsigned long psize) -{ - unsigned long launch = get_atsd_launch_val(pid, psize); - - /* Write all VAs first */ - mmio_atsd_regs_write(mmio_atsd_reg, XTS_ATSD_AVA, start); - - /* Issue one barrier for all address writes */ - eieio(); - - /* Launch */ - mmio_atsd_regs_write(mmio_atsd_reg, XTS_ATSD_LAUNCH, launch); -} - -#define mn_to_npu_context(x) container_of(x, struct npu_context, mn) - -static void mmio_invalidate_wait( - struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]) -{ - struct npu *npu; - int i, reg; - - /* Wait for all invalidations to complete */ - for (i = 0; i <= max_npu2_index; i++) { - if (mmio_atsd_reg[i].reg < 0) - continue; - - /* Wait for completion */ - npu = mmio_atsd_reg[i].npu; - reg = mmio_atsd_reg[i].reg; - while (__raw_readq(npu->mmio_atsd_regs[reg] + XTS_ATSD_STAT)) - cpu_relax(); - } -} - -/* - * Acquires all the address translation shootdown (ATSD) registers required to - * launch an ATSD on all links this npu_context is active on. - */ -static void acquire_atsd_reg(struct npu_context *npu_context, - struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]) -{ - int i, j; - struct npu *npu; - struct pci_dev *npdev; - - for (i = 0; i <= max_npu2_index; i++) { - mmio_atsd_reg[i].reg = -1; - for (j = 0; j < NV_MAX_LINKS; j++) { - /* - * There are no ordering requirements with respect to - * the setup of struct npu_context, but to ensure - * consistent behaviour we need to ensure npdev[][] is - * only read once. - */ - npdev = READ_ONCE(npu_context->npdev[i][j]); - if (!npdev) - continue; - - npu = pci_bus_to_host(npdev->bus)->npu; - if (!npu) - continue; - - mmio_atsd_reg[i].npu = npu; - mmio_atsd_reg[i].reg = get_mmio_atsd_reg(npu); - while (mmio_atsd_reg[i].reg < 0) { - mmio_atsd_reg[i].reg = get_mmio_atsd_reg(npu); - cpu_relax(); - } - break; - } - } -} - -/* - * Release previously acquired ATSD registers. To avoid deadlocks the registers - * must be released in the same order they were acquired above in - * acquire_atsd_reg. - */ -static void release_atsd_reg(struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]) -{ - int i; - - for (i = 0; i <= max_npu2_index; i++) { - /* - * We can't rely on npu_context->npdev[][] being the same here - * as when acquire_atsd_reg() was called, hence we use the - * values stored in mmio_atsd_reg during the acquire phase - * rather than re-reading npdev[][]. - */ - if (mmio_atsd_reg[i].reg < 0) - continue; - - put_mmio_atsd_reg(mmio_atsd_reg[i].npu, mmio_atsd_reg[i].reg); - } -} - -/* - * Invalidate a virtual address range - */ -static void mmio_invalidate(struct npu_context *npu_context, - unsigned long start, unsigned long size) -{ - struct mmio_atsd_reg mmio_atsd_reg[NV_MAX_NPUS]; - unsigned long pid = npu_context->mm->context.id; - unsigned long atsd_start = 0; - unsigned long end = start + size - 1; - int atsd_psize = MMU_PAGE_COUNT; - - /* - * Convert the input range into one of the supported sizes. If the range - * doesn't fit, use the next larger supported size. Invalidation latency - * is high, so over-invalidation is preferred to issuing multiple - * invalidates. - * - * A 4K page size isn't supported by NPU/GPU ATS, so that case is - * ignored. - */ - if (size == SZ_64K) { - atsd_start = start; - atsd_psize = MMU_PAGE_64K; - } else if (ALIGN_DOWN(start, SZ_2M) == ALIGN_DOWN(end, SZ_2M)) { - atsd_start = ALIGN_DOWN(start, SZ_2M); - atsd_psize = MMU_PAGE_2M; - } else if (ALIGN_DOWN(start, SZ_1G) == ALIGN_DOWN(end, SZ_1G)) { - atsd_start = ALIGN_DOWN(start, SZ_1G); - atsd_psize = MMU_PAGE_1G; - } - - if (npu_context->nmmu_flush) - /* - * Unfortunately the nest mmu does not support flushing specific - * addresses so we have to flush the whole mm once before - * shooting down the GPU translation. - */ - flush_all_mm(npu_context->mm); - - /* - * Loop over all the NPUs this process is active on and launch - * an invalidate. - */ - acquire_atsd_reg(npu_context, mmio_atsd_reg); - - if (atsd_psize == MMU_PAGE_COUNT) - mmio_invalidate_pid(mmio_atsd_reg, pid); - else - mmio_invalidate_range(mmio_atsd_reg, pid, atsd_start, - atsd_psize); - - mmio_invalidate_wait(mmio_atsd_reg); - - /* - * The GPU requires two flush ATSDs to ensure all entries have been - * flushed. We use PID 0 as it will never be used for a process on the - * GPU. - */ - mmio_invalidate_pid(mmio_atsd_reg, 0); - mmio_invalidate_wait(mmio_atsd_reg); - mmio_invalidate_pid(mmio_atsd_reg, 0); - mmio_invalidate_wait(mmio_atsd_reg); - - release_atsd_reg(mmio_atsd_reg); -} - -static void pnv_npu2_mn_release(struct mmu_notifier *mn, - struct mm_struct *mm) -{ - struct npu_context *npu_context = mn_to_npu_context(mn); - - /* Call into device driver to stop requests to the NMMU */ - if (npu_context->release_cb) - npu_context->release_cb(npu_context, npu_context->priv); - - /* - * There should be no more translation requests for this PID, but we - * need to ensure any entries for it are removed from the TLB. - */ - mmio_invalidate(npu_context, 0, ~0UL); -} - -static void pnv_npu2_mn_invalidate_range(struct mmu_notifier *mn, - struct mm_struct *mm, - unsigned long start, unsigned long end) -{ - struct npu_context *npu_context = mn_to_npu_context(mn); - mmio_invalidate(npu_context, start, end - start); -} - -static const struct mmu_notifier_ops nv_nmmu_notifier_ops = { - .release = pnv_npu2_mn_release, - .invalidate_range = pnv_npu2_mn_invalidate_range, -}; - -/* - * Call into OPAL to setup the nmmu context for the current task in - * the NPU. This must be called to setup the context tables before the - * GPU issues ATRs. pdev should be a pointed to PCIe GPU device. - * - * A release callback should be registered to allow a device driver to - * be notified that it should not launch any new translation requests - * as the final TLB invalidate is about to occur. - * - * Returns an error if there no contexts are currently available or a - * npu_context which should be passed to pnv_npu2_handle_fault(). - * - * mmap_sem must be held in write mode and must not be called from interrupt - * context. - */ -struct npu_context *pnv_npu2_init_context(struct pci_dev *gpdev, - unsigned long flags, - void (*cb)(struct npu_context *, void *), - void *priv) -{ - int rc; - u32 nvlink_index; - struct device_node *nvlink_dn; - struct mm_struct *mm = current->mm; - struct npu *npu; - struct npu_context *npu_context; - struct pci_controller *hose; - - /* - * At present we don't support GPUs connected to multiple NPUs and I'm - * not sure the hardware does either. - */ - struct pci_dev *npdev = pnv_pci_get_npu_dev(gpdev, 0); - - if (!npdev) - /* No nvlink associated with this GPU device */ - return ERR_PTR(-ENODEV); - - /* We only support DR/PR/HV in pnv_npu2_map_lpar_dev() */ - if (flags & ~(MSR_DR | MSR_PR | MSR_HV)) - return ERR_PTR(-EINVAL); - - nvlink_dn = of_parse_phandle(npdev->dev.of_node, "ibm,nvlink", 0); - if (WARN_ON(of_property_read_u32(nvlink_dn, "ibm,npu-link-index", - &nvlink_index))) - return ERR_PTR(-ENODEV); - - if (!mm || mm->context.id == 0) { - /* - * Kernel thread contexts are not supported and context id 0 is - * reserved on the GPU. - */ - return ERR_PTR(-EINVAL); - } - - hose = pci_bus_to_host(npdev->bus); - npu = hose->npu; - if (!npu) - return ERR_PTR(-ENODEV); - - /* - * We store the npu pci device so we can more easily get at the - * associated npus. - */ - spin_lock(&npu_context_lock); - npu_context = mm->context.npu_context; - if (npu_context) { - if (npu_context->release_cb != cb || - npu_context->priv != priv) { - spin_unlock(&npu_context_lock); - return ERR_PTR(-EINVAL); - } - - WARN_ON(!kref_get_unless_zero(&npu_context->kref)); - } - spin_unlock(&npu_context_lock); - - if (!npu_context) { - /* - * We can set up these fields without holding the - * npu_context_lock as the npu_context hasn't been returned to - * the caller meaning it can't be destroyed. Parallel allocation - * is protected against by mmap_sem. - */ - rc = -ENOMEM; - npu_context = kzalloc(sizeof(struct npu_context), GFP_KERNEL); - if (npu_context) { - kref_init(&npu_context->kref); - npu_context->mm = mm; - npu_context->mn.ops = &nv_nmmu_notifier_ops; - rc = __mmu_notifier_register(&npu_context->mn, mm); - } - - if (rc) { - kfree(npu_context); - return ERR_PTR(rc); - } - - mm->context.npu_context = npu_context; - } - - npu_context->release_cb = cb; - npu_context->priv = priv; - - /* - * npdev is a pci_dev pointer setup by the PCI code. We assign it to - * npdev[][] to indicate to the mmu notifiers that an invalidation - * should also be sent over this nvlink. The notifiers don't use any - * other fields in npu_context, so we just need to ensure that when they - * deference npu_context->npdev[][] it is either a valid pointer or - * NULL. - */ - WRITE_ONCE(npu_context->npdev[npu->index][nvlink_index], npdev); - - if (!npu->nmmu_flush) { - /* - * If we're not explicitly flushing ourselves we need to mark - * the thread for global flushes - */ - npu_context->nmmu_flush = false; - mm_context_add_copro(mm); - } else - npu_context->nmmu_flush = true; - - return npu_context; -} -EXPORT_SYMBOL(pnv_npu2_init_context); - -static void pnv_npu2_release_context(struct kref *kref) -{ - struct npu_context *npu_context = - container_of(kref, struct npu_context, kref); - - if (!npu_context->nmmu_flush) - mm_context_remove_copro(npu_context->mm); - - npu_context->mm->context.npu_context = NULL; -} - -/* - * Destroy a context on the given GPU. May free the npu_context if it is no - * longer active on any GPUs. Must not be called from interrupt context. - */ -void pnv_npu2_destroy_context(struct npu_context *npu_context, - struct pci_dev *gpdev) -{ - int removed; - struct npu *npu; - struct pci_dev *npdev = pnv_pci_get_npu_dev(gpdev, 0); - struct device_node *nvlink_dn; - u32 nvlink_index; - struct pci_controller *hose; - - if (WARN_ON(!npdev)) - return; - - hose = pci_bus_to_host(npdev->bus); - npu = hose->npu; - if (!npu) - return; - nvlink_dn = of_parse_phandle(npdev->dev.of_node, "ibm,nvlink", 0); - if (WARN_ON(of_property_read_u32(nvlink_dn, "ibm,npu-link-index", - &nvlink_index))) - return; - WRITE_ONCE(npu_context->npdev[npu->index][nvlink_index], NULL); - spin_lock(&npu_context_lock); - removed = kref_put(&npu_context->kref, pnv_npu2_release_context); - spin_unlock(&npu_context_lock); - - /* - * We need to do this outside of pnv_npu2_release_context so that it is - * outside the spinlock as mmu_notifier_destroy uses SRCU. - */ - if (removed) { - mmu_notifier_unregister(&npu_context->mn, - npu_context->mm); - - kfree(npu_context); - } - -} -EXPORT_SYMBOL(pnv_npu2_destroy_context); - -/* - * Assumes mmap_sem is held for the contexts associated mm. - */ -int pnv_npu2_handle_fault(struct npu_context *context, uintptr_t *ea, - unsigned long *flags, unsigned long *status, int count) -{ - u64 rc = 0, result = 0; - int i, is_write; - struct page *page[1]; - const char __user *u; - char c; - - /* mmap_sem should be held so the struct_mm must be present */ - struct mm_struct *mm = context->mm; - - WARN_ON(!rwsem_is_locked(&mm->mmap_sem)); - - for (i = 0; i < count; i++) { - is_write = flags[i] & NPU2_WRITE; - rc = get_user_pages_remote(NULL, mm, ea[i], 1, - is_write ? FOLL_WRITE : 0, - page, NULL, NULL); - - if (rc != 1) { - status[i] = rc; - result = -EFAULT; - continue; - } - - /* Make sure partition scoped tree gets a pte */ - u = page_address(page[0]); - if (__get_user(c, u)) - result = -EFAULT; - - status[i] = 0; - put_page(page[0]); - } - - return result; -} -EXPORT_SYMBOL(pnv_npu2_handle_fault); - int pnv_npu2_init(struct pci_controller *hose) { - unsigned int i; - u64 mmio_atsd; static int npu_index; struct npu *npu; int ret; @@ -1176,33 +635,18 @@ int pnv_npu2_init(struct pci_controller *hose) if (!npu) return -ENOMEM; - npu->nmmu_flush = of_property_read_bool(hose->dn, "ibm,nmmu-flush"); - - for (i = 0; i < ARRAY_SIZE(npu->mmio_atsd_regs) && - !of_property_read_u64_index(hose->dn, "ibm,mmio-atsd", - i, &mmio_atsd); i++) - npu->mmio_atsd_regs[i] = ioremap(mmio_atsd, 32); - - pr_info("NPU%d: Found %d MMIO ATSD registers", hose->global_number, i); - npu->mmio_atsd_count = i; - npu->mmio_atsd_usage = 0; npu_index++; if (WARN_ON(npu_index >= NV_MAX_NPUS)) { ret = -ENOSPC; goto fail_exit; } - max_npu2_index = npu_index; npu->index = npu_index; hose->npu = npu; return 0; fail_exit: - for (i = 0; i < npu->mmio_atsd_count; ++i) - iounmap(npu->mmio_atsd_regs[i]); - kfree(npu); - return ret; } -- cgit v1.2.3 From 452d23c0f6bd97f2fd8a9691fee79b76040a0feb Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Tue, 25 Jun 2019 16:52:39 +0200 Subject: powerpc/powernv: remove the unused vas_win_paste_addr and vas_win_id functions These two function have never been used anywhere in the kernel tree since they were added to the kernel. Signed-off-by: Christoph Hellwig Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/vas.h | 10 ---------- arch/powerpc/platforms/powernv/vas-window.c | 19 ------------------- arch/powerpc/platforms/powernv/vas.h | 20 -------------------- 3 files changed, 49 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/vas.h b/arch/powerpc/include/asm/vas.h index 771456227496..9b5b7261df7b 100644 --- a/arch/powerpc/include/asm/vas.h +++ b/arch/powerpc/include/asm/vas.h @@ -167,14 +167,4 @@ int vas_copy_crb(void *crb, int offset); */ int vas_paste_crb(struct vas_window *win, int offset, bool re); -/* - * Return a system-wide unique id for the VAS window @win. - */ -extern u32 vas_win_id(struct vas_window *win); - -/* - * Return the power bus paste address associated with @win so the caller - * can map that address into their address space. - */ -extern u64 vas_win_paste_addr(struct vas_window *win); #endif /* __ASM_POWERPC_VAS_H */ diff --git a/arch/powerpc/platforms/powernv/vas-window.c b/arch/powerpc/platforms/powernv/vas-window.c index e59e0e60e5b5..e48c44cb3a16 100644 --- a/arch/powerpc/platforms/powernv/vas-window.c +++ b/arch/powerpc/platforms/powernv/vas-window.c @@ -44,16 +44,6 @@ static void compute_paste_address(struct vas_window *window, u64 *addr, int *len pr_debug("Txwin #%d: Paste addr 0x%llx\n", winid, *addr); } -u64 vas_win_paste_addr(struct vas_window *win) -{ - u64 addr; - - compute_paste_address(win, &addr, NULL); - - return addr; -} -EXPORT_SYMBOL(vas_win_paste_addr); - static inline void get_hvwc_mmio_bar(struct vas_window *window, u64 *start, int *len) { @@ -1268,12 +1258,3 @@ int vas_win_close(struct vas_window *window) return 0; } EXPORT_SYMBOL_GPL(vas_win_close); - -/* - * Return a system-wide unique window id for the window @win. - */ -u32 vas_win_id(struct vas_window *win) -{ - return encode_pswid(win->vinst->vas_id, win->winid); -} -EXPORT_SYMBOL_GPL(vas_win_id); diff --git a/arch/powerpc/platforms/powernv/vas.h b/arch/powerpc/platforms/powernv/vas.h index f5493dbdd7ff..551affaddd59 100644 --- a/arch/powerpc/platforms/powernv/vas.h +++ b/arch/powerpc/platforms/powernv/vas.h @@ -448,26 +448,6 @@ static inline u64 read_hvwc_reg(struct vas_window *win, return in_be64(win->hvwc_map+reg); } -/* - * Encode/decode the Partition Send Window ID (PSWID) for a window in - * a way that we can uniquely identify any window in the system. i.e. - * we should be able to locate the 'struct vas_window' given the PSWID. - * - * Bits Usage - * 0:7 VAS id (8 bits) - * 8:15 Unused, 0 (3 bits) - * 16:31 Window id (16 bits) - */ -static inline u32 encode_pswid(int vasid, int winid) -{ - u32 pswid = 0; - - pswid |= vasid << (31 - 7); - pswid |= winid; - - return pswid; -} - static inline void decode_pswid(u32 pswid, int *vasid, int *winid) { if (vasid) -- cgit v1.2.3 From 4b1f5ccc7cdc89fe208e017f9d40d69cb9e160f4 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Wed, 12 Jun 2019 00:30:13 +1000 Subject: powerpc/64s/exception: fix line wrap and semicolon inconsistencies in macros By convention, all lines should be separated by a semicolons. Last line should have neither semicolon or line wrap. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 36 ++++++++--------- arch/powerpc/include/asm/head-64.h | 68 ++++++++++++++++---------------- 2 files changed, 52 insertions(+), 52 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index bef4e05a6823..b590765f6e45 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -189,11 +189,11 @@ */ #define LOAD_HANDLER(reg, label) \ ld reg,PACAKBASE(r13); /* get high part of &label */ \ - ori reg,reg,FIXED_SYMBOL_ABS_ADDR(label); + ori reg,reg,FIXED_SYMBOL_ABS_ADDR(label) #define __LOAD_HANDLER(reg, label) \ ld reg,PACAKBASE(r13); \ - ori reg,reg,(ABS_ADDR(label))@l; + ori reg,reg,(ABS_ADDR(label))@l /* * Branches from unrelocated code (e.g., interrupts) to labels outside @@ -202,7 +202,7 @@ #define __LOAD_FAR_HANDLER(reg, label) \ ld reg,PACAKBASE(r13); \ ori reg,reg,(ABS_ADDR(label))@l; \ - addis reg,reg,(ABS_ADDR(label))@h; + addis reg,reg,(ABS_ADDR(label))@h /* Exception register prefixes */ #define EXC_HV H @@ -277,7 +277,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \ INTERRUPT_TO_KERNEL; \ SAVE_CTR(r10, area); \ - mfcr r9; + mfcr r9 #define __EXCEPTION_PROLOG_1_POST(area) \ std r11,area+EX_R11(r13); \ @@ -294,7 +294,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define MASKABLE_EXCEPTION_PROLOG_1(area, extra, vec, bitmask) \ __EXCEPTION_PROLOG_1_PRE(area); \ extra(vec, bitmask); \ - __EXCEPTION_PROLOG_1_POST(area); + __EXCEPTION_PROLOG_1_POST(area) /* * This version of the EXCEPTION_PROLOG_1 is intended @@ -303,7 +303,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define _EXCEPTION_PROLOG_1(area, extra, vec) \ __EXCEPTION_PROLOG_1_PRE(area); \ extra(vec); \ - __EXCEPTION_PROLOG_1_POST(area); + __EXCEPTION_PROLOG_1_POST(area) #define EXCEPTION_PROLOG_1(area, extra, vec) \ _EXCEPTION_PROLOG_1(area, extra, vec) @@ -311,7 +311,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define __EXCEPTION_PROLOG_2(label, h) \ ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ - LOAD_HANDLER(r12,label) \ + LOAD_HANDLER(r12,label); \ mtspr SPRN_##h##SRR0,r12; \ mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ mtspr SPRN_##h##SRR1,r10; \ @@ -325,7 +325,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ xori r10,r10,MSR_RI; /* Clear MSR_RI */ \ mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ - LOAD_HANDLER(r12,label) \ + LOAD_HANDLER(r12,label); \ mtspr SPRN_##h##SRR0,r12; \ mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ mtspr SPRN_##h##SRR1,r10; \ @@ -339,7 +339,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2(label, h); + EXCEPTION_PROLOG_2(label, h) #define __KVMTEST(h, n) \ lbz r10,HSTATE_IN_GUEST(r13); \ @@ -413,7 +413,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define EXCEPTION_PROLOG_NORI(area, label, h, extra, vec) \ EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2_NORI(label, h); + EXCEPTION_PROLOG_2_NORI(label, h) #define __KVM_HANDLER(area, h, n) \ @@ -550,16 +550,16 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) /* Version of above for when we have to branch out-of-line */ #define __OOL_EXCEPTION(vec, label, hdlr) \ - SET_SCRATCH0(r13) \ - EXCEPTION_PROLOG_0(PACA_EXGEN) \ - b hdlr; + SET_SCRATCH0(r13); \ + EXCEPTION_PROLOG_0(PACA_EXGEN); \ + b hdlr #define STD_EXCEPTION_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \ EXCEPTION_PROLOG_2(label, EXC_STD) #define STD_EXCEPTION_HV(loc, vec, label) \ - EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec); + EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec) #define STD_EXCEPTION_HV_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ @@ -567,14 +567,14 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define STD_RELON_EXCEPTION(loc, vec, label) \ /* No guest interrupts come through here */ \ - EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_STD, NOTEST, vec); + EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_STD, NOTEST, vec) #define STD_RELON_EXCEPTION_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec); \ EXCEPTION_PROLOG_2_RELON(label, EXC_STD) #define STD_RELON_EXCEPTION_HV(loc, vec, label) \ - EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec); + EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec) #define STD_RELON_EXCEPTION_HV_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ @@ -619,7 +619,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \ - EXCEPTION_PROLOG_2(label, h); + EXCEPTION_PROLOG_2(label, h) #define MASKABLE_EXCEPTION(vec, label, bitmask) \ __MASKABLE_EXCEPTION(vec, label, EXC_STD, SOFTEN_TEST_PR, bitmask) @@ -646,7 +646,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define MASKABLE_RELON_EXCEPTION_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec, bitmask);\ - EXCEPTION_PROLOG_2(label, EXC_STD); + EXCEPTION_PROLOG_2(label, EXC_STD) #define MASKABLE_RELON_EXCEPTION_HV(vec, label, bitmask) \ __MASKABLE_RELON_EXCEPTION(vec, label, EXC_HV, SOFTEN_TEST_HV, bitmask) diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index a4f947888744..e34b3d06bf61 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -255,135 +255,135 @@ name: #define EXC_VIRT_NONE(start, size) \ FIXED_SECTION_ENTRY_BEGIN_LOCATION(virt_vectors, exc_virt_##start##_##unused, start, size); \ - FIXED_SECTION_ENTRY_END_LOCATION(virt_vectors, exc_virt_##start##_##unused, start, size); + FIXED_SECTION_ENTRY_END_LOCATION(virt_vectors, exc_virt_##start##_##unused, start, size) #define EXC_REAL(name, start, size) \ EXC_REAL_BEGIN(name, start, size); \ STD_EXCEPTION(start, name##_common); \ - EXC_REAL_END(name, start, size); + EXC_REAL_END(name, start, size) #define EXC_VIRT(name, start, size, realvec) \ EXC_VIRT_BEGIN(name, start, size); \ STD_RELON_EXCEPTION(start, realvec, name##_common); \ - EXC_VIRT_END(name, start, size); + EXC_VIRT_END(name, start, size) #define EXC_REAL_MASKABLE(name, start, size, bitmask) \ EXC_REAL_BEGIN(name, start, size); \ MASKABLE_EXCEPTION(start, name##_common, bitmask); \ - EXC_REAL_END(name, start, size); + EXC_REAL_END(name, start, size) #define EXC_VIRT_MASKABLE(name, start, size, realvec, bitmask) \ EXC_VIRT_BEGIN(name, start, size); \ MASKABLE_RELON_EXCEPTION(realvec, name##_common, bitmask); \ - EXC_VIRT_END(name, start, size); + EXC_VIRT_END(name, start, size) #define EXC_REAL_HV(name, start, size) \ EXC_REAL_BEGIN(name, start, size); \ STD_EXCEPTION_HV(start, start, name##_common); \ - EXC_REAL_END(name, start, size); + EXC_REAL_END(name, start, size) #define EXC_VIRT_HV(name, start, size, realvec) \ EXC_VIRT_BEGIN(name, start, size); \ STD_RELON_EXCEPTION_HV(start, realvec, name##_common); \ - EXC_VIRT_END(name, start, size); + EXC_VIRT_END(name, start, size) #define __EXC_REAL_OOL(name, start, size) \ EXC_REAL_BEGIN(name, start, size); \ __OOL_EXCEPTION(start, label, tramp_real_##name); \ - EXC_REAL_END(name, start, size); + EXC_REAL_END(name, start, size) #define __TRAMP_REAL_OOL(name, vec) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - STD_EXCEPTION_OOL(vec, name##_common); + STD_EXCEPTION_OOL(vec, name##_common) #define EXC_REAL_OOL(name, start, size) \ __EXC_REAL_OOL(name, start, size); \ - __TRAMP_REAL_OOL(name, start); + __TRAMP_REAL_OOL(name, start) #define __EXC_REAL_OOL_MASKABLE(name, start, size) \ - __EXC_REAL_OOL(name, start, size); + __EXC_REAL_OOL(name, start, size) #define __TRAMP_REAL_OOL_MASKABLE(name, vec, bitmask) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - MASKABLE_EXCEPTION_OOL(vec, name##_common, bitmask); + MASKABLE_EXCEPTION_OOL(vec, name##_common, bitmask) #define EXC_REAL_OOL_MASKABLE(name, start, size, bitmask) \ __EXC_REAL_OOL_MASKABLE(name, start, size); \ - __TRAMP_REAL_OOL_MASKABLE(name, start, bitmask); + __TRAMP_REAL_OOL_MASKABLE(name, start, bitmask) #define __EXC_REAL_OOL_HV_DIRECT(name, start, size, handler) \ EXC_REAL_BEGIN(name, start, size); \ __OOL_EXCEPTION(start, label, handler); \ - EXC_REAL_END(name, start, size); + EXC_REAL_END(name, start, size) #define __EXC_REAL_OOL_HV(name, start, size) \ - __EXC_REAL_OOL(name, start, size); + __EXC_REAL_OOL(name, start, size) #define __TRAMP_REAL_OOL_HV(name, vec) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - STD_EXCEPTION_HV_OOL(vec, name##_common); \ + STD_EXCEPTION_HV_OOL(vec, name##_common) #define EXC_REAL_OOL_HV(name, start, size) \ __EXC_REAL_OOL_HV(name, start, size); \ - __TRAMP_REAL_OOL_HV(name, start); + __TRAMP_REAL_OOL_HV(name, start) #define __EXC_REAL_OOL_MASKABLE_HV(name, start, size) \ - __EXC_REAL_OOL(name, start, size); + __EXC_REAL_OOL(name, start, size) #define __TRAMP_REAL_OOL_MASKABLE_HV(name, vec, bitmask) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - MASKABLE_EXCEPTION_HV_OOL(vec, name##_common, bitmask); \ + MASKABLE_EXCEPTION_HV_OOL(vec, name##_common, bitmask) #define EXC_REAL_OOL_MASKABLE_HV(name, start, size, bitmask) \ __EXC_REAL_OOL_MASKABLE_HV(name, start, size); \ - __TRAMP_REAL_OOL_MASKABLE_HV(name, start, bitmask); + __TRAMP_REAL_OOL_MASKABLE_HV(name, start, bitmask) #define __EXC_VIRT_OOL(name, start, size) \ EXC_VIRT_BEGIN(name, start, size); \ __OOL_EXCEPTION(start, label, tramp_virt_##name); \ - EXC_VIRT_END(name, start, size); + EXC_VIRT_END(name, start, size) #define __TRAMP_VIRT_OOL(name, realvec) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - STD_RELON_EXCEPTION_OOL(realvec, name##_common); + STD_RELON_EXCEPTION_OOL(realvec, name##_common) #define EXC_VIRT_OOL(name, start, size, realvec) \ __EXC_VIRT_OOL(name, start, size); \ - __TRAMP_VIRT_OOL(name, realvec); + __TRAMP_VIRT_OOL(name, realvec) #define __EXC_VIRT_OOL_MASKABLE(name, start, size) \ - __EXC_VIRT_OOL(name, start, size); + __EXC_VIRT_OOL(name, start, size) #define __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - MASKABLE_RELON_EXCEPTION_OOL(realvec, name##_common, bitmask); + MASKABLE_RELON_EXCEPTION_OOL(realvec, name##_common, bitmask) #define EXC_VIRT_OOL_MASKABLE(name, start, size, realvec, bitmask) \ __EXC_VIRT_OOL_MASKABLE(name, start, size); \ - __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask); + __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask) #define __EXC_VIRT_OOL_HV(name, start, size) \ - __EXC_VIRT_OOL(name, start, size); + __EXC_VIRT_OOL(name, start, size) #define __TRAMP_VIRT_OOL_HV(name, realvec) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - STD_RELON_EXCEPTION_HV_OOL(realvec, name##_common); \ + STD_RELON_EXCEPTION_HV_OOL(realvec, name##_common) #define EXC_VIRT_OOL_HV(name, start, size, realvec) \ __EXC_VIRT_OOL_HV(name, start, size); \ - __TRAMP_VIRT_OOL_HV(name, realvec); + __TRAMP_VIRT_OOL_HV(name, realvec) #define __EXC_VIRT_OOL_MASKABLE_HV(name, start, size) \ - __EXC_VIRT_OOL(name, start, size); + __EXC_VIRT_OOL(name, start, size) #define __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - MASKABLE_RELON_EXCEPTION_HV_OOL(realvec, name##_common, bitmask);\ + MASKABLE_RELON_EXCEPTION_HV_OOL(realvec, name##_common, bitmask) #define EXC_VIRT_OOL_MASKABLE_HV(name, start, size, realvec, bitmask) \ __EXC_VIRT_OOL_MASKABLE_HV(name, start, size); \ - __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask); + __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask) #define TRAMP_KVM(area, n) \ TRAMP_KVM_BEGIN(do_kvm_##n); \ @@ -406,11 +406,11 @@ name: #define EXC_COMMON(name, realvec, hdlr) \ EXC_COMMON_BEGIN(name); \ - STD_EXCEPTION_COMMON(realvec, name, hdlr); \ + STD_EXCEPTION_COMMON(realvec, name, hdlr) #define EXC_COMMON_ASYNC(name, realvec, hdlr) \ EXC_COMMON_BEGIN(name); \ - STD_EXCEPTION_COMMON_ASYNC(realvec, name, hdlr); \ + STD_EXCEPTION_COMMON_ASYNC(realvec, name, hdlr) #endif /* __ASSEMBLY__ */ -- cgit v1.2.3 From 1efd8caa9a9192e6820d267c780c110a9f54336f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Tue, 2 Jul 2019 18:20:52 +1000 Subject: powerpc/64s/exception: Remove unused SOFTEN_VALUE_0x980 Remove SOFTEN_VALUE_0x980, it's been unused since commit dabe859ec636 ("powerpc: Give hypervisor decrementer interrupts their own handler") (Sep 2012). Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index b590765f6e45..b4f8b745ba01 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -583,7 +583,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) /* This associate vector numbers with bits in paca->irq_happened */ #define SOFTEN_VALUE_0x500 PACA_IRQ_EE #define SOFTEN_VALUE_0x900 PACA_IRQ_DEC -#define SOFTEN_VALUE_0x980 PACA_IRQ_DEC #define SOFTEN_VALUE_0xa00 PACA_IRQ_DBELL #define SOFTEN_VALUE_0xe80 PACA_IRQ_DBELL #define SOFTEN_VALUE_0xe60 PACA_IRQ_HMI -- cgit v1.2.3 From 4508a74a63154fea5c2d36d8ad064273c5ea9608 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:11 +1000 Subject: powerpc/64s/exception: remove H concatenation for EXC_HV variants Replace all instances of this with gas macros that test the hsrr parameter and use the appropriate register names / labels. No generated code change. Signed-off-by: Nicholas Piggin [mpe: Remove extraneous 2nd check for 0xea0 in SOFTEN_TEST] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 332 ++++++++++++++++++------------- arch/powerpc/include/asm/head-64.h | 8 +- arch/powerpc/kernel/exceptions-64s.S | 97 +++++---- 3 files changed, 253 insertions(+), 184 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index b4f8b745ba01..eddd74cf36c3 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -67,6 +67,8 @@ */ #define EX_R3 EX_DAR +#ifdef __ASSEMBLY__ + #define STF_ENTRY_BARRIER_SLOT \ STF_ENTRY_BARRIER_FIXUP_SECTION; \ nop; \ @@ -148,38 +150,6 @@ hrfid; \ b hrfi_flush_fallback -#ifdef CONFIG_RELOCATABLE -#define __EXCEPTION_PROLOG_2_RELON(label, h) \ - mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ - LOAD_HANDLER(r12,label); \ - mtctr r12; \ - mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ - li r10,MSR_RI; \ - mtmsrd r10,1; /* Set RI (EE=0) */ \ - bctr; -#else -/* If not relocatable, we can jump directly -- and save messing with LR */ -#define __EXCEPTION_PROLOG_2_RELON(label, h) \ - mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ - mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ - li r10,MSR_RI; \ - mtmsrd r10,1; /* Set RI (EE=0) */ \ - b label; -#endif -#define EXCEPTION_PROLOG_2_RELON(label, h) \ - __EXCEPTION_PROLOG_2_RELON(label, h) - -/* - * As EXCEPTION_PROLOG(), except we've already got relocation on so no need to - * rfid. Save LR in case we're CONFIG_RELOCATABLE, in which case - * EXCEPTION_PROLOG_2_RELON will be using LR. - */ -#define EXCEPTION_RELON_PROLOG(area, label, h, extra, vec) \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0(area); \ - EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2_RELON(label, h) - /* * We're short on space and time in the exception prolog, so we can't * use the normal LOAD_REG_IMMEDIATE macro to load the address of label. @@ -204,9 +174,54 @@ ori reg,reg,(ABS_ADDR(label))@l; \ addis reg,reg,(ABS_ADDR(label))@h +#ifdef CONFIG_RELOCATABLE +.macro EXCEPTION_PROLOG_2_RELON label, hsrr + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + .endif + LOAD_HANDLER(r12, \label\()) + mtctr r12 + .if \hsrr + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + .else + mfspr r12,SPRN_SRR1 /* and HSRR1 */ + .endif + li r10,MSR_RI + mtmsrd r10,1 /* Set RI (EE=0) */ + bctr +.endm +#else +/* If not relocatable, we can jump directly -- and save messing with LR */ +.macro EXCEPTION_PROLOG_2_RELON label, hsrr + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + mfspr r12,SPRN_SRR1 /* and SRR1 */ + .endif + li r10,MSR_RI + mtmsrd r10,1 /* Set RI (EE=0) */ + b \label +.endm +#endif + +/* + * As EXCEPTION_PROLOG(), except we've already got relocation on so no need to + * rfid. Save LR in case we're CONFIG_RELOCATABLE, in which case + * EXCEPTION_PROLOG_2_RELON will be using LR. + */ +#define EXCEPTION_RELON_PROLOG(area, label, hsrr, extra, vec) \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0(area); \ + EXCEPTION_PROLOG_1(area, extra, vec); \ + EXCEPTION_PROLOG_2_RELON label, hsrr + /* Exception register prefixes */ -#define EXC_HV H -#define EXC_STD +#define EXC_HV 1 +#define EXC_STD 0 #if defined(CONFIG_RELOCATABLE) /* @@ -308,43 +323,57 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define EXCEPTION_PROLOG_1(area, extra, vec) \ _EXCEPTION_PROLOG_1(area, extra, vec) -#define __EXCEPTION_PROLOG_2(label, h) \ - ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ - mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ - LOAD_HANDLER(r12,label); \ - mtspr SPRN_##h##SRR0,r12; \ - mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ - mtspr SPRN_##h##SRR1,r10; \ - h##RFI_TO_KERNEL; \ +.macro EXCEPTION_PROLOG_2 label, hsrr + ld r10,PACAKMSR(r13) /* get MSR value for kernel */ + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + .endif + LOAD_HANDLER(r12,\label\()) + .if \hsrr + mtspr SPRN_HSRR0,r12 + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + mtspr SPRN_HSRR1,r10 + HRFI_TO_KERNEL + .else + mtspr SPRN_SRR0,r12 + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mtspr SPRN_SRR1,r10 + RFI_TO_KERNEL + .endif b . /* prevent speculative execution */ -#define EXCEPTION_PROLOG_2(label, h) \ - __EXCEPTION_PROLOG_2(label, h) +.endm /* _NORI variant keeps MSR_RI clear */ -#define __EXCEPTION_PROLOG_2_NORI(label, h) \ - ld r10,PACAKMSR(r13); /* get MSR value for kernel */ \ - xori r10,r10,MSR_RI; /* Clear MSR_RI */ \ - mfspr r11,SPRN_##h##SRR0; /* save SRR0 */ \ - LOAD_HANDLER(r12,label); \ - mtspr SPRN_##h##SRR0,r12; \ - mfspr r12,SPRN_##h##SRR1; /* and SRR1 */ \ - mtspr SPRN_##h##SRR1,r10; \ - h##RFI_TO_KERNEL; \ +.macro EXCEPTION_PROLOG_2_NORI label, hsrr + ld r10,PACAKMSR(r13) /* get MSR value for kernel */ + xori r10,r10,MSR_RI /* Clear MSR_RI */ + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + .endif + LOAD_HANDLER(r12,\label\()) + .if \hsrr + mtspr SPRN_HSRR0,r12 + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + mtspr SPRN_HSRR1,r10 + HRFI_TO_KERNEL + .else + mtspr SPRN_SRR0,r12 + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mtspr SPRN_SRR1,r10 + RFI_TO_KERNEL + .endif b . /* prevent speculative execution */ - -#define EXCEPTION_PROLOG_2_NORI(label, h) \ - __EXCEPTION_PROLOG_2_NORI(label, h) +.endm #define EXCEPTION_PROLOG(area, label, h, extra, vec) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2(label, h) - -#define __KVMTEST(h, n) \ - lbz r10,HSTATE_IN_GUEST(r13); \ - cmpwi r10,0; \ - bne do_kvm_##h##n + EXCEPTION_PROLOG_2 label, h #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* @@ -413,52 +442,66 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define EXCEPTION_PROLOG_NORI(area, label, h, extra, vec) \ EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2_NORI(label, h) - - -#define __KVM_HANDLER(area, h, n) \ - BEGIN_FTR_SECTION_NESTED(947) \ - ld r10,area+EX_CFAR(r13); \ - std r10,HSTATE_CFAR(r13); \ - END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947); \ - BEGIN_FTR_SECTION_NESTED(948) \ - ld r10,area+EX_PPR(r13); \ - std r10,HSTATE_PPR(r13); \ - END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \ - ld r10,area+EX_R10(r13); \ - std r12,HSTATE_SCRATCH0(r13); \ - sldi r12,r9,32; \ - ori r12,r12,(n); \ - /* This reloads r9 before branching to kvmppc_interrupt */ \ - __BRANCH_TO_KVM_EXIT(area, kvmppc_interrupt) - -#define __KVM_HANDLER_SKIP(area, h, n) \ - cmpwi r10,KVM_GUEST_MODE_SKIP; \ - beq 89f; \ - BEGIN_FTR_SECTION_NESTED(948) \ - ld r10,area+EX_PPR(r13); \ - std r10,HSTATE_PPR(r13); \ - END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948); \ - ld r10,area+EX_R10(r13); \ - std r12,HSTATE_SCRATCH0(r13); \ - sldi r12,r9,32; \ - ori r12,r12,(n); \ - /* This reloads r9 before branching to kvmppc_interrupt */ \ - __BRANCH_TO_KVM_EXIT(area, kvmppc_interrupt); \ -89: mtocrf 0x80,r9; \ - ld r9,area+EX_R9(r13); \ - ld r10,area+EX_R10(r13); \ - b kvmppc_skip_##h##interrupt + EXCEPTION_PROLOG_2_NORI label, h #ifdef CONFIG_KVM_BOOK3S_64_HANDLER -#define KVMTEST(h, n) __KVMTEST(h, n) -#define KVM_HANDLER(area, h, n) __KVM_HANDLER(area, h, n) -#define KVM_HANDLER_SKIP(area, h, n) __KVM_HANDLER_SKIP(area, h, n) +.macro KVMTEST hsrr, n + lbz r10,HSTATE_IN_GUEST(r13) + cmpwi r10,0 + .if \hsrr + bne do_kvm_H\n + .else + bne do_kvm_\n + .endif +.endm + +.macro KVM_HANDLER area, hsrr, n + BEGIN_FTR_SECTION_NESTED(947) + ld r10,\area+EX_CFAR(r13) + std r10,HSTATE_CFAR(r13) + END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947) + BEGIN_FTR_SECTION_NESTED(948) + ld r10,\area+EX_PPR(r13) + std r10,HSTATE_PPR(r13) + END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) + ld r10,\area+EX_R10(r13) + std r12,HSTATE_SCRATCH0(r13) + sldi r12,r9,32 + ori r12,r12,(\n) + /* This reloads r9 before branching to kvmppc_interrupt */ + __BRANCH_TO_KVM_EXIT(\area, kvmppc_interrupt) +.endm + +.macro KVM_HANDLER_SKIP area, hsrr, n + cmpwi r10,KVM_GUEST_MODE_SKIP + beq 89f + BEGIN_FTR_SECTION_NESTED(948) + ld r10,\area+EX_PPR(r13) + std r10,HSTATE_PPR(r13) + END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) + ld r10,\area+EX_R10(r13) + std r12,HSTATE_SCRATCH0(r13) + sldi r12,r9,32 + ori r12,r12,(\n) + /* This reloads r9 before branching to kvmppc_interrupt */ + __BRANCH_TO_KVM_EXIT(\area, kvmppc_interrupt) +89: mtocrf 0x80,r9 + ld r9,\area+EX_R9(r13) + ld r10,\area+EX_R10(r13) + .if \hsrr + b kvmppc_skip_Hinterrupt + .else + b kvmppc_skip_interrupt + .endif +.endm #else -#define KVMTEST(h, n) -#define KVM_HANDLER(area, h, n) -#define KVM_HANDLER_SKIP(area, h, n) +.macro KVMTEST hsrr, n +.endm +.macro KVM_HANDLER area, hsrr, n +.endm +.macro KVM_HANDLER_SKIP area, hsrr, n +.endm #endif #define NOTEST(n) @@ -556,14 +599,14 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define STD_EXCEPTION_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \ - EXCEPTION_PROLOG_2(label, EXC_STD) + EXCEPTION_PROLOG_2 label, EXC_STD #define STD_EXCEPTION_HV(loc, vec, label) \ EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec) #define STD_EXCEPTION_HV_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ - EXCEPTION_PROLOG_2(label, EXC_HV) + EXCEPTION_PROLOG_2 label, EXC_HV #define STD_RELON_EXCEPTION(loc, vec, label) \ /* No guest interrupts come through here */ \ @@ -571,88 +614,97 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define STD_RELON_EXCEPTION_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec); \ - EXCEPTION_PROLOG_2_RELON(label, EXC_STD) + EXCEPTION_PROLOG_2_RELON label, EXC_STD #define STD_RELON_EXCEPTION_HV(loc, vec, label) \ EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec) #define STD_RELON_EXCEPTION_HV_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ - EXCEPTION_PROLOG_2_RELON(label, EXC_HV) - -/* This associate vector numbers with bits in paca->irq_happened */ -#define SOFTEN_VALUE_0x500 PACA_IRQ_EE -#define SOFTEN_VALUE_0x900 PACA_IRQ_DEC -#define SOFTEN_VALUE_0xa00 PACA_IRQ_DBELL -#define SOFTEN_VALUE_0xe80 PACA_IRQ_DBELL -#define SOFTEN_VALUE_0xe60 PACA_IRQ_HMI -#define SOFTEN_VALUE_0xea0 PACA_IRQ_EE -#define SOFTEN_VALUE_0xf00 PACA_IRQ_PMI - -#define __SOFTEN_TEST(h, vec, bitmask) \ - lbz r10,PACAIRQSOFTMASK(r13); \ - andi. r10,r10,bitmask; \ - li r10,SOFTEN_VALUE_##vec; \ - bne masked_##h##interrupt - -#define _SOFTEN_TEST(h, vec, bitmask) __SOFTEN_TEST(h, vec, bitmask) + EXCEPTION_PROLOG_2_RELON label, EXC_HV + +.macro SOFTEN_TEST hsrr, vec, bitmask + lbz r10, PACAIRQSOFTMASK(r13) + andi. r10, r10, \bitmask + /* This associates vector numbers with bits in paca->irq_happened */ + .if \vec == 0x500 || \vec == 0xea0 + li r10, PACA_IRQ_EE + .elseif \vec == 0x900 + li r10, PACA_IRQ_DEC + .elseif \vec == 0xa00 || \vec == 0xe80 + li r10, PACA_IRQ_DBELL + .elseif \vec == 0xe60 + li r10, PACA_IRQ_HMI + .elseif \vec == 0xf00 + li r10, PACA_IRQ_PMI + .else + .abort "Bad maskable vector" + .endif + + + .if \hsrr + bne masked_Hinterrupt + .else + bne masked_interrupt + .endif +.endm #define SOFTEN_TEST_PR(vec, bitmask) \ - KVMTEST(EXC_STD, vec); \ - _SOFTEN_TEST(EXC_STD, vec, bitmask) + KVMTEST EXC_STD, vec ; \ + SOFTEN_TEST EXC_STD, vec, bitmask #define SOFTEN_TEST_HV(vec, bitmask) \ - KVMTEST(EXC_HV, vec); \ - _SOFTEN_TEST(EXC_HV, vec, bitmask) + KVMTEST EXC_HV, vec ; \ + SOFTEN_TEST EXC_HV, vec, bitmask #define KVMTEST_PR(vec) \ - KVMTEST(EXC_STD, vec) + KVMTEST EXC_STD, vec #define KVMTEST_HV(vec) \ - KVMTEST(EXC_HV, vec) + KVMTEST EXC_HV, vec -#define SOFTEN_NOTEST_PR(vec, bitmask) _SOFTEN_TEST(EXC_STD, vec, bitmask) -#define SOFTEN_NOTEST_HV(vec, bitmask) _SOFTEN_TEST(EXC_HV, vec, bitmask) +#define SOFTEN_NOTEST_PR(vec, bitmask) SOFTEN_TEST EXC_STD, vec, bitmask +#define SOFTEN_NOTEST_HV(vec, bitmask) SOFTEN_TEST EXC_HV, vec, bitmask #define __MASKABLE_EXCEPTION(vec, label, h, extra, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \ - EXCEPTION_PROLOG_2(label, h) + EXCEPTION_PROLOG_2 label, h #define MASKABLE_EXCEPTION(vec, label, bitmask) \ __MASKABLE_EXCEPTION(vec, label, EXC_STD, SOFTEN_TEST_PR, bitmask) #define MASKABLE_EXCEPTION_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec, bitmask);\ - EXCEPTION_PROLOG_2(label, EXC_STD) + EXCEPTION_PROLOG_2 label, EXC_STD #define MASKABLE_EXCEPTION_HV(vec, label, bitmask) \ __MASKABLE_EXCEPTION(vec, label, EXC_HV, SOFTEN_TEST_HV, bitmask) #define MASKABLE_EXCEPTION_HV_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\ - EXCEPTION_PROLOG_2(label, EXC_HV) + EXCEPTION_PROLOG_2 label, EXC_HV #define __MASKABLE_RELON_EXCEPTION(vec, label, h, extra, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \ - EXCEPTION_PROLOG_2_RELON(label, h) + EXCEPTION_PROLOG_2_RELON label, h #define MASKABLE_RELON_EXCEPTION(vec, label, bitmask) \ __MASKABLE_RELON_EXCEPTION(vec, label, EXC_STD, SOFTEN_NOTEST_PR, bitmask) #define MASKABLE_RELON_EXCEPTION_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec, bitmask);\ - EXCEPTION_PROLOG_2(label, EXC_STD) + EXCEPTION_PROLOG_2 label, EXC_STD #define MASKABLE_RELON_EXCEPTION_HV(vec, label, bitmask) \ __MASKABLE_RELON_EXCEPTION(vec, label, EXC_HV, SOFTEN_TEST_HV, bitmask) #define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\ - EXCEPTION_PROLOG_2_RELON(label, EXC_HV) + EXCEPTION_PROLOG_2_RELON label, EXC_HV /* * Our exception common code can be passed various "additions" @@ -731,4 +783,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define FINISH_NAP #endif +#endif /* __ASSEMBLY__ */ + #endif /* _ASM_POWERPC_EXCEPTION_H */ diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index e34b3d06bf61..4767d6c7b8fa 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -387,22 +387,22 @@ name: #define TRAMP_KVM(area, n) \ TRAMP_KVM_BEGIN(do_kvm_##n); \ - KVM_HANDLER(area, EXC_STD, n); \ + KVM_HANDLER area, EXC_STD, n #define TRAMP_KVM_SKIP(area, n) \ TRAMP_KVM_BEGIN(do_kvm_##n); \ - KVM_HANDLER_SKIP(area, EXC_STD, n); \ + KVM_HANDLER_SKIP area, EXC_STD, n /* * HV variant exceptions get the 0x2 bit added to their trap number. */ #define TRAMP_KVM_HV(area, n) \ TRAMP_KVM_BEGIN(do_kvm_H##n); \ - KVM_HANDLER(area, EXC_HV, n + 0x2); \ + KVM_HANDLER area, EXC_HV, n + 0x2 #define TRAMP_KVM_HV_SKIP(area, n) \ TRAMP_KVM_BEGIN(do_kvm_H##n); \ - KVM_HANDLER_SKIP(area, EXC_HV, n + 0x2); \ + KVM_HANDLER_SKIP area, EXC_HV, n + 0x2 #define EXC_COMMON(name, realvec, hdlr) \ EXC_COMMON_BEGIN(name); \ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 6c51aa845bce..13ae6b8d5e3e 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -356,7 +356,7 @@ machine_check_pSeries_0: * nested machine check corrupts it. machine_check_common enables * MSR_RI. */ - EXCEPTION_PROLOG_2_NORI(machine_check_common, EXC_STD) + EXCEPTION_PROLOG_2_NORI machine_check_common, EXC_STD TRAMP_KVM_SKIP(PACA_EXMC, 0x200) @@ -598,7 +598,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, 0x300) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2(data_access_common, EXC_STD) +EXCEPTION_PROLOG_2 data_access_common, EXC_STD EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) SET_SCRATCH0(r13) /* save r13 */ @@ -608,7 +608,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x300) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2_RELON(data_access_common, EXC_STD) +EXCEPTION_PROLOG_2_RELON data_access_common, EXC_STD EXC_VIRT_END(data_access, 0x4300, 0x80) TRAMP_KVM_SKIP(PACA_EXGEN, 0x300) @@ -645,7 +645,7 @@ TRAMP_REAL_BEGIN(tramp_real_data_access_slb) EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x380) mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) -EXCEPTION_PROLOG_2(data_access_slb_common, EXC_STD) +EXCEPTION_PROLOG_2 data_access_slb_common, EXC_STD EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) SET_SCRATCH0(r13) /* save r13 */ @@ -653,7 +653,7 @@ EXCEPTION_PROLOG_0(PACA_EXSLB) EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380) mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) -EXCEPTION_PROLOG_2_RELON(data_access_slb_common, EXC_STD) +EXCEPTION_PROLOG_2_RELON data_access_slb_common, EXC_STD EXC_VIRT_END(data_access_slb, 0x4380, 0x80) TRAMP_KVM_SKIP(PACA_EXSLB, 0x380) @@ -774,7 +774,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, 0x600) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2(alignment_common, EXC_STD) +EXCEPTION_PROLOG_2 alignment_common, EXC_STD EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) @@ -785,7 +785,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x600) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2_RELON(alignment_common, EXC_STD) +EXCEPTION_PROLOG_2_RELON alignment_common, EXC_STD EXC_VIRT_END(alignment, 0x4600, 0x100) TRAMP_KVM(PACA_EXGEN, 0x600) @@ -1053,7 +1053,7 @@ TRAMP_KVM_BEGIN(do_kvm_0xc00) SET_SCRATCH0(r10) std r9,PACA_EXGEN+EX_R9(r13) mfcr r9 - KVM_HANDLER(PACA_EXGEN, EXC_STD, 0xc00) + KVM_HANDLER PACA_EXGEN, EXC_STD, 0xc00 #endif @@ -1320,7 +1320,7 @@ EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) #endif KVMTEST_HV(0x1500) - EXCEPTION_PROLOG_2(denorm_common, EXC_HV) + EXCEPTION_PROLOG_2 denorm_common, EXC_HV EXC_REAL_END(denorm_exception_hv, 0x1500, 0x100) #ifdef CONFIG_PPC_DENORMALISATION @@ -1442,7 +1442,7 @@ EXC_VIRT_NONE(0x5800, 0x100) std r12,PACA_EXGEN+EX_R12(r13); \ GET_SCRATCH0(r10); \ std r10,PACA_EXGEN+EX_R13(r13); \ - EXCEPTION_PROLOG_2(soft_nmi_common, _H) + EXCEPTION_PROLOG_2 soft_nmi_common, _H /* * Branch to soft_nmi_interrupt using the emergency stack. The emergency @@ -1477,35 +1477,50 @@ EXC_COMMON_BEGIN(soft_nmi_common) * - Else it is one of PACA_IRQ_MUST_HARD_MASK, so hard disable and return. * This is called with r10 containing the value to OR to the paca field. */ -#define MASKED_INTERRUPT(_H) \ -masked_##_H##interrupt: \ - std r11,PACA_EXGEN+EX_R11(r13); \ - lbz r11,PACAIRQHAPPENED(r13); \ - or r11,r11,r10; \ - stb r11,PACAIRQHAPPENED(r13); \ - cmpwi r10,PACA_IRQ_DEC; \ - bne 1f; \ - lis r10,0x7fff; \ - ori r10,r10,0xffff; \ - mtspr SPRN_DEC,r10; \ - b MASKED_DEC_HANDLER_LABEL; \ -1: andi. r10,r10,PACA_IRQ_MUST_HARD_MASK; \ - beq 2f; \ - mfspr r10,SPRN_##_H##SRR1; \ - xori r10,r10,MSR_EE; /* clear MSR_EE */ \ - mtspr SPRN_##_H##SRR1,r10; \ - ori r11,r11,PACA_IRQ_HARD_DIS; \ - stb r11,PACAIRQHAPPENED(r13); \ -2: /* done */ \ - mtcrf 0x80,r9; \ - std r1,PACAR1(r13); \ - ld r9,PACA_EXGEN+EX_R9(r13); \ - ld r10,PACA_EXGEN+EX_R10(r13); \ - ld r11,PACA_EXGEN+EX_R11(r13); \ - /* returns to kernel where r13 must be set up, so don't restore it */ \ - ##_H##RFI_TO_KERNEL; \ - b .; \ - MASKED_DEC_HANDLER(_H) +.macro MASKED_INTERRUPT hsrr + .if \hsrr +masked_Hinterrupt: + .else +masked_interrupt: + .endif + std r11,PACA_EXGEN+EX_R11(r13) + lbz r11,PACAIRQHAPPENED(r13) + or r11,r11,r10 + stb r11,PACAIRQHAPPENED(r13) + cmpwi r10,PACA_IRQ_DEC + bne 1f + lis r10,0x7fff + ori r10,r10,0xffff + mtspr SPRN_DEC,r10 + b MASKED_DEC_HANDLER_LABEL +1: andi. r10,r10,PACA_IRQ_MUST_HARD_MASK + beq 2f + .if \hsrr + mfspr r10,SPRN_HSRR1 + xori r10,r10,MSR_EE /* clear MSR_EE */ + mtspr SPRN_HSRR1,r10 + .else + mfspr r10,SPRN_SRR1 + xori r10,r10,MSR_EE /* clear MSR_EE */ + mtspr SPRN_SRR1,r10 + .endif + ori r11,r11,PACA_IRQ_HARD_DIS + stb r11,PACAIRQHAPPENED(r13) +2: /* done */ + mtcrf 0x80,r9 + std r1,PACAR1(r13) + ld r9,PACA_EXGEN+EX_R9(r13) + ld r10,PACA_EXGEN+EX_R10(r13) + ld r11,PACA_EXGEN+EX_R11(r13) + /* returns to kernel where r13 must be set up, so don't restore it */ + .if \hsrr + HRFI_TO_KERNEL + .else + RFI_TO_KERNEL + .endif + b . + MASKED_DEC_HANDLER(\hsrr\()) +.endm TRAMP_REAL_BEGIN(stf_barrier_fallback) std r9,PACA_EXRFI+EX_R9(r13) @@ -1612,8 +1627,8 @@ TRAMP_REAL_BEGIN(hrfi_flush_fallback) * cannot reach these if they are put there. */ USE_FIXED_SECTION(virt_trampolines) - MASKED_INTERRUPT() - MASKED_INTERRUPT(H) + MASKED_INTERRUPT EXC_STD + MASKED_INTERRUPT EXC_HV #ifdef CONFIG_KVM_BOOK3S_64_HANDLER TRAMP_REAL_BEGIN(kvmppc_skip_interrupt) -- cgit v1.2.3 From bd7b6d1334c5fd92c1e1a9c8179154e115f427b0 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:12 +1000 Subject: powerpc/64s/exception: consolidate EXCEPTION_PROLOG_2 with _NORI variant Switch to a gas macro that conditionally expands the RI clearing instruction. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 43 ++++++++------------------------ arch/powerpc/kernel/exceptions-64s.S | 12 ++++----- 2 files changed, 17 insertions(+), 38 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index eddd74cf36c3..82a1c0576fbb 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -323,32 +323,11 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define EXCEPTION_PROLOG_1(area, extra, vec) \ _EXCEPTION_PROLOG_1(area, extra, vec) -.macro EXCEPTION_PROLOG_2 label, hsrr - ld r10,PACAKMSR(r13) /* get MSR value for kernel */ - .if \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - .endif - LOAD_HANDLER(r12,\label\()) - .if \hsrr - mtspr SPRN_HSRR0,r12 - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - mtspr SPRN_HSRR1,r10 - HRFI_TO_KERNEL - .else - mtspr SPRN_SRR0,r12 - mfspr r12,SPRN_SRR1 /* and SRR1 */ - mtspr SPRN_SRR1,r10 - RFI_TO_KERNEL - .endif - b . /* prevent speculative execution */ -.endm - -/* _NORI variant keeps MSR_RI clear */ -.macro EXCEPTION_PROLOG_2_NORI label, hsrr +.macro EXCEPTION_PROLOG_2 label, hsrr, set_ri ld r10,PACAKMSR(r13) /* get MSR value for kernel */ + .if ! \set_ri xori r10,r10,MSR_RI /* Clear MSR_RI */ + .endif .if \hsrr mfspr r11,SPRN_HSRR0 /* save HSRR0 */ .else @@ -373,7 +352,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2 label, h + EXCEPTION_PROLOG_2 label, h, 1 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* @@ -442,7 +421,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define EXCEPTION_PROLOG_NORI(area, label, h, extra, vec) \ EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2_NORI label, h + EXCEPTION_PROLOG_2 label, h, 0 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER .macro KVMTEST hsrr, n @@ -599,14 +578,14 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define STD_EXCEPTION_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \ - EXCEPTION_PROLOG_2 label, EXC_STD + EXCEPTION_PROLOG_2 label, EXC_STD, 1 #define STD_EXCEPTION_HV(loc, vec, label) \ EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec) #define STD_EXCEPTION_HV_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ - EXCEPTION_PROLOG_2 label, EXC_HV + EXCEPTION_PROLOG_2 label, EXC_HV, 1 #define STD_RELON_EXCEPTION(loc, vec, label) \ /* No guest interrupts come through here */ \ @@ -670,21 +649,21 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \ - EXCEPTION_PROLOG_2 label, h + EXCEPTION_PROLOG_2 label, h, 1 #define MASKABLE_EXCEPTION(vec, label, bitmask) \ __MASKABLE_EXCEPTION(vec, label, EXC_STD, SOFTEN_TEST_PR, bitmask) #define MASKABLE_EXCEPTION_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec, bitmask);\ - EXCEPTION_PROLOG_2 label, EXC_STD + EXCEPTION_PROLOG_2 label, EXC_STD, 1 #define MASKABLE_EXCEPTION_HV(vec, label, bitmask) \ __MASKABLE_EXCEPTION(vec, label, EXC_HV, SOFTEN_TEST_HV, bitmask) #define MASKABLE_EXCEPTION_HV_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\ - EXCEPTION_PROLOG_2 label, EXC_HV + EXCEPTION_PROLOG_2 label, EXC_HV, 1 #define __MASKABLE_RELON_EXCEPTION(vec, label, h, extra, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ @@ -697,7 +676,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define MASKABLE_RELON_EXCEPTION_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec, bitmask);\ - EXCEPTION_PROLOG_2 label, EXC_STD + EXCEPTION_PROLOG_2 label, EXC_STD, 1 #define MASKABLE_RELON_EXCEPTION_HV(vec, label, bitmask) \ __MASKABLE_RELON_EXCEPTION(vec, label, EXC_HV, SOFTEN_TEST_HV, bitmask) diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 13ae6b8d5e3e..f562b9a83b01 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -356,7 +356,7 @@ machine_check_pSeries_0: * nested machine check corrupts it. machine_check_common enables * MSR_RI. */ - EXCEPTION_PROLOG_2_NORI machine_check_common, EXC_STD + EXCEPTION_PROLOG_2 machine_check_common, EXC_STD, 0 TRAMP_KVM_SKIP(PACA_EXMC, 0x200) @@ -598,7 +598,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, 0x300) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2 data_access_common, EXC_STD +EXCEPTION_PROLOG_2 data_access_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) SET_SCRATCH0(r13) /* save r13 */ @@ -645,7 +645,7 @@ TRAMP_REAL_BEGIN(tramp_real_data_access_slb) EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x380) mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) -EXCEPTION_PROLOG_2 data_access_slb_common, EXC_STD +EXCEPTION_PROLOG_2 data_access_slb_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) SET_SCRATCH0(r13) /* save r13 */ @@ -774,7 +774,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, 0x600) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2 alignment_common, EXC_STD +EXCEPTION_PROLOG_2 alignment_common, EXC_STD, 1 EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) @@ -1320,7 +1320,7 @@ EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) #endif KVMTEST_HV(0x1500) - EXCEPTION_PROLOG_2 denorm_common, EXC_HV + EXCEPTION_PROLOG_2 denorm_common, EXC_HV, 1 EXC_REAL_END(denorm_exception_hv, 0x1500, 0x100) #ifdef CONFIG_PPC_DENORMALISATION @@ -1442,7 +1442,7 @@ EXC_VIRT_NONE(0x5800, 0x100) std r12,PACA_EXGEN+EX_R12(r13); \ GET_SCRATCH0(r10); \ std r10,PACA_EXGEN+EX_R13(r13); \ - EXCEPTION_PROLOG_2 soft_nmi_common, _H + EXCEPTION_PROLOG_2 soft_nmi_common, _H, 1 /* * Branch to soft_nmi_interrupt using the emergency stack. The emergency -- cgit v1.2.3 From 2d046308d0747848394a0c745d12af8122061792 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:13 +1000 Subject: powerpc/64s/exception: move and tidy EXCEPTION_PROLOG_2 variants - Re-name the macros to _REAL and _VIRT suffixes rather than no and _RELON suffix. - Move the macro definitions together in the file. - Move RELOCATABLE ifdef inside the _VIRT macro. Further consolidation between variants does not buy much here. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 87 +++++++++++++++----------------- arch/powerpc/kernel/exceptions-64s.S | 18 +++---- 2 files changed, 51 insertions(+), 54 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 82a1c0576fbb..3b0e736481fc 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -174,8 +174,33 @@ ori reg,reg,(ABS_ADDR(label))@l; \ addis reg,reg,(ABS_ADDR(label))@h +.macro EXCEPTION_PROLOG_2_REAL label, hsrr, set_ri + ld r10,PACAKMSR(r13) /* get MSR value for kernel */ + .if ! \set_ri + xori r10,r10,MSR_RI /* Clear MSR_RI */ + .endif + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + .endif + LOAD_HANDLER(r12, \label\()) + .if \hsrr + mtspr SPRN_HSRR0,r12 + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + mtspr SPRN_HSRR1,r10 + HRFI_TO_KERNEL + .else + mtspr SPRN_SRR0,r12 + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mtspr SPRN_SRR1,r10 + RFI_TO_KERNEL + .endif + b . /* prevent speculative execution */ +.endm + +.macro EXCEPTION_PROLOG_2_VIRT label, hsrr #ifdef CONFIG_RELOCATABLE -.macro EXCEPTION_PROLOG_2_RELON label, hsrr .if \hsrr mfspr r11,SPRN_HSRR0 /* save HSRR0 */ .else @@ -191,10 +216,7 @@ li r10,MSR_RI mtmsrd r10,1 /* Set RI (EE=0) */ bctr -.endm #else -/* If not relocatable, we can jump directly -- and save messing with LR */ -.macro EXCEPTION_PROLOG_2_RELON label, hsrr .if \hsrr mfspr r11,SPRN_HSRR0 /* save HSRR0 */ mfspr r12,SPRN_HSRR1 /* and HSRR1 */ @@ -205,19 +227,19 @@ li r10,MSR_RI mtmsrd r10,1 /* Set RI (EE=0) */ b \label -.endm #endif +.endm /* * As EXCEPTION_PROLOG(), except we've already got relocation on so no need to - * rfid. Save LR in case we're CONFIG_RELOCATABLE, in which case - * EXCEPTION_PROLOG_2_RELON will be using LR. + * rfid. Save CTR in case we're CONFIG_RELOCATABLE, in which case + * EXCEPTION_PROLOG_2_VIRT will be using CTR. */ #define EXCEPTION_RELON_PROLOG(area, label, hsrr, extra, vec) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2_RELON label, hsrr + EXCEPTION_PROLOG_2_VIRT label, hsrr /* Exception register prefixes */ #define EXC_HV 1 @@ -323,36 +345,11 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define EXCEPTION_PROLOG_1(area, extra, vec) \ _EXCEPTION_PROLOG_1(area, extra, vec) -.macro EXCEPTION_PROLOG_2 label, hsrr, set_ri - ld r10,PACAKMSR(r13) /* get MSR value for kernel */ - .if ! \set_ri - xori r10,r10,MSR_RI /* Clear MSR_RI */ - .endif - .if \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - .endif - LOAD_HANDLER(r12,\label\()) - .if \hsrr - mtspr SPRN_HSRR0,r12 - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - mtspr SPRN_HSRR1,r10 - HRFI_TO_KERNEL - .else - mtspr SPRN_SRR0,r12 - mfspr r12,SPRN_SRR1 /* and SRR1 */ - mtspr SPRN_SRR1,r10 - RFI_TO_KERNEL - .endif - b . /* prevent speculative execution */ -.endm - #define EXCEPTION_PROLOG(area, label, h, extra, vec) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2 label, h, 1 + EXCEPTION_PROLOG_2_REAL label, h, 1 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* @@ -421,7 +418,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define EXCEPTION_PROLOG_NORI(area, label, h, extra, vec) \ EXCEPTION_PROLOG_0(area); \ EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2 label, h, 0 + EXCEPTION_PROLOG_2_REAL label, h, 0 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER .macro KVMTEST hsrr, n @@ -578,14 +575,14 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define STD_EXCEPTION_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \ - EXCEPTION_PROLOG_2 label, EXC_STD, 1 + EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 #define STD_EXCEPTION_HV(loc, vec, label) \ EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec) #define STD_EXCEPTION_HV_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ - EXCEPTION_PROLOG_2 label, EXC_HV, 1 + EXCEPTION_PROLOG_2_REAL label, EXC_HV, 1 #define STD_RELON_EXCEPTION(loc, vec, label) \ /* No guest interrupts come through here */ \ @@ -593,14 +590,14 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define STD_RELON_EXCEPTION_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec); \ - EXCEPTION_PROLOG_2_RELON label, EXC_STD + EXCEPTION_PROLOG_2_VIRT label, EXC_STD #define STD_RELON_EXCEPTION_HV(loc, vec, label) \ EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec) #define STD_RELON_EXCEPTION_HV_OOL(vec, label) \ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ - EXCEPTION_PROLOG_2_RELON label, EXC_HV + EXCEPTION_PROLOG_2_VIRT label, EXC_HV .macro SOFTEN_TEST hsrr, vec, bitmask lbz r10, PACAIRQSOFTMASK(r13) @@ -649,41 +646,41 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \ - EXCEPTION_PROLOG_2 label, h, 1 + EXCEPTION_PROLOG_2_REAL label, h, 1 #define MASKABLE_EXCEPTION(vec, label, bitmask) \ __MASKABLE_EXCEPTION(vec, label, EXC_STD, SOFTEN_TEST_PR, bitmask) #define MASKABLE_EXCEPTION_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec, bitmask);\ - EXCEPTION_PROLOG_2 label, EXC_STD, 1 + EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 #define MASKABLE_EXCEPTION_HV(vec, label, bitmask) \ __MASKABLE_EXCEPTION(vec, label, EXC_HV, SOFTEN_TEST_HV, bitmask) #define MASKABLE_EXCEPTION_HV_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\ - EXCEPTION_PROLOG_2 label, EXC_HV, 1 + EXCEPTION_PROLOG_2_REAL label, EXC_HV, 1 #define __MASKABLE_RELON_EXCEPTION(vec, label, h, extra, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \ - EXCEPTION_PROLOG_2_RELON label, h + EXCEPTION_PROLOG_2_VIRT label, h #define MASKABLE_RELON_EXCEPTION(vec, label, bitmask) \ __MASKABLE_RELON_EXCEPTION(vec, label, EXC_STD, SOFTEN_NOTEST_PR, bitmask) #define MASKABLE_RELON_EXCEPTION_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec, bitmask);\ - EXCEPTION_PROLOG_2 label, EXC_STD, 1 + EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 #define MASKABLE_RELON_EXCEPTION_HV(vec, label, bitmask) \ __MASKABLE_RELON_EXCEPTION(vec, label, EXC_HV, SOFTEN_TEST_HV, bitmask) #define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label, bitmask) \ MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\ - EXCEPTION_PROLOG_2_RELON label, EXC_HV + EXCEPTION_PROLOG_2_VIRT label, EXC_HV /* * Our exception common code can be passed various "additions" diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index f562b9a83b01..38e21d671c3b 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -356,7 +356,7 @@ machine_check_pSeries_0: * nested machine check corrupts it. machine_check_common enables * MSR_RI. */ - EXCEPTION_PROLOG_2 machine_check_common, EXC_STD, 0 + EXCEPTION_PROLOG_2_REAL machine_check_common, EXC_STD, 0 TRAMP_KVM_SKIP(PACA_EXMC, 0x200) @@ -598,7 +598,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, 0x300) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2 data_access_common, EXC_STD, 1 +EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) SET_SCRATCH0(r13) /* save r13 */ @@ -608,7 +608,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x300) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2_RELON data_access_common, EXC_STD +EXCEPTION_PROLOG_2_VIRT data_access_common, EXC_STD EXC_VIRT_END(data_access, 0x4300, 0x80) TRAMP_KVM_SKIP(PACA_EXGEN, 0x300) @@ -645,7 +645,7 @@ TRAMP_REAL_BEGIN(tramp_real_data_access_slb) EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x380) mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) -EXCEPTION_PROLOG_2 data_access_slb_common, EXC_STD, 1 +EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) SET_SCRATCH0(r13) /* save r13 */ @@ -653,7 +653,7 @@ EXCEPTION_PROLOG_0(PACA_EXSLB) EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380) mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) -EXCEPTION_PROLOG_2_RELON data_access_slb_common, EXC_STD +EXCEPTION_PROLOG_2_VIRT data_access_slb_common, EXC_STD EXC_VIRT_END(data_access_slb, 0x4380, 0x80) TRAMP_KVM_SKIP(PACA_EXSLB, 0x380) @@ -774,7 +774,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, 0x600) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2 alignment_common, EXC_STD, 1 +EXCEPTION_PROLOG_2_REAL alignment_common, EXC_STD, 1 EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) @@ -785,7 +785,7 @@ EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x600) mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2_RELON alignment_common, EXC_STD +EXCEPTION_PROLOG_2_VIRT alignment_common, EXC_STD EXC_VIRT_END(alignment, 0x4600, 0x100) TRAMP_KVM(PACA_EXGEN, 0x600) @@ -1320,7 +1320,7 @@ EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) #endif KVMTEST_HV(0x1500) - EXCEPTION_PROLOG_2 denorm_common, EXC_HV, 1 + EXCEPTION_PROLOG_2_REAL denorm_common, EXC_HV, 1 EXC_REAL_END(denorm_exception_hv, 0x1500, 0x100) #ifdef CONFIG_PPC_DENORMALISATION @@ -1442,7 +1442,7 @@ EXC_VIRT_NONE(0x5800, 0x100) std r12,PACA_EXGEN+EX_R12(r13); \ GET_SCRATCH0(r10); \ std r10,PACA_EXGEN+EX_R13(r13); \ - EXCEPTION_PROLOG_2 soft_nmi_common, _H, 1 + EXCEPTION_PROLOG_2_REAL soft_nmi_common, _H, 1 /* * Branch to soft_nmi_interrupt using the emergency stack. The emergency -- cgit v1.2.3 From 8f528359efbbf05a7ce657ea31b3c80b7a742269 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:14 +1000 Subject: powerpc/64s/exception: fix sreset KVM test code The sreset handler KVM test theoretically should not depend on P7. In practice KVM now only supports P7 and up so no real bug fix, but this change is made now so the quirk is not propagated through cleanup patches. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 38e21d671c3b..08096d3fd5bb 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -126,10 +126,10 @@ EXC_VIRT_NONE(0x4000, 0x100) bltlr cr1 ; /* no state loss, return to idle caller */ \ BRANCH_TO_C000(r10, system_reset_idle_common) ; \ 1: \ - KVMTEST_PR(n) ; \ - END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) + END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) ; \ + KVMTEST_PR(n) #else -#define IDLETEST NOTEST +#define IDLETEST KVMTEST_PR #endif EXC_REAL_BEGIN(system_reset, 0x100, 0x100) -- cgit v1.2.3 From a7c1ca19c295962eb8e1f714416a930daa582a90 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:15 +1000 Subject: powerpc/64s/exception: remove the "extra" macro parameter Rather than pass in the soft-masking and KVM tests via macro that is passed to another macro to expand it, switch to usig gas macros and conditionally expand the soft-masking and KVM tests. The system reset with its idle test is open coded as it is a one-off. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 158 ++++++++++++++----------------- arch/powerpc/kernel/exceptions-64s.S | 78 ++++++++------- 2 files changed, 114 insertions(+), 122 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 3b0e736481fc..0a29bf2db198 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -235,10 +235,10 @@ * rfid. Save CTR in case we're CONFIG_RELOCATABLE, in which case * EXCEPTION_PROLOG_2_VIRT will be using CTR. */ -#define EXCEPTION_RELON_PROLOG(area, label, hsrr, extra, vec) \ +#define EXCEPTION_RELON_PROLOG(area, label, hsrr, kvm, vec) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(area); \ - EXCEPTION_PROLOG_1(area, extra, vec); \ + EXCEPTION_PROLOG_1 hsrr, area, kvm, vec ; \ EXCEPTION_PROLOG_2_VIRT label, hsrr /* Exception register prefixes */ @@ -325,31 +325,58 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) /* * This version of the EXCEPTION_PROLOG_1 will carry * addition parameter called "bitmask" to support - * checking of the interrupt maskable level in the SOFTEN_TEST. + * checking of the interrupt maskable level. * Intended to be used in MASKABLE_EXCPETION_* macros. */ -#define MASKABLE_EXCEPTION_PROLOG_1(area, extra, vec, bitmask) \ - __EXCEPTION_PROLOG_1_PRE(area); \ - extra(vec, bitmask); \ - __EXCEPTION_PROLOG_1_POST(area) +.macro MASKABLE_EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, bitmask + __EXCEPTION_PROLOG_1_PRE(\area\()) + .if \kvm + KVMTEST \hsrr \vec + .endif + + lbz r10,PACAIRQSOFTMASK(r13) + andi. r10,r10,\bitmask + /* This associates vector numbers with bits in paca->irq_happened */ + .if \vec == 0x500 || \vec == 0xea0 + li r10,PACA_IRQ_EE + .elseif \vec == 0x900 + li r10,PACA_IRQ_DEC + .elseif \vec == 0xa00 || \vec == 0xe80 + li r10,PACA_IRQ_DBELL + .elseif \vec == 0xe60 + li r10,PACA_IRQ_HMI + .elseif \vec == 0xf00 + li r10,PACA_IRQ_PMI + .else + .abort "Bad maskable vector" + .endif + + .if \hsrr + bne masked_Hinterrupt + .else + bne masked_interrupt + .endif + + __EXCEPTION_PROLOG_1_POST(\area\()) +.endm /* * This version of the EXCEPTION_PROLOG_1 is intended * to be used in STD_EXCEPTION* macros */ -#define _EXCEPTION_PROLOG_1(area, extra, vec) \ - __EXCEPTION_PROLOG_1_PRE(area); \ - extra(vec); \ - __EXCEPTION_PROLOG_1_POST(area) - -#define EXCEPTION_PROLOG_1(area, extra, vec) \ - _EXCEPTION_PROLOG_1(area, extra, vec) +.macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec + __EXCEPTION_PROLOG_1_PRE(\area\()) + .if \kvm + KVMTEST \hsrr \vec + .endif + __EXCEPTION_PROLOG_1_POST(\area\()) +.endm -#define EXCEPTION_PROLOG(area, label, h, extra, vec) \ +#define EXCEPTION_PROLOG(area, label, hsrr, kvm, vec) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(area); \ - EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2_REAL label, h, 1 + EXCEPTION_PROLOG_1 hsrr, area, kvm, vec ; \ + EXCEPTION_PROLOG_2_REAL label, hsrr, 1 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* @@ -415,10 +442,10 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #endif /* Do not enable RI */ -#define EXCEPTION_PROLOG_NORI(area, label, h, extra, vec) \ +#define EXCEPTION_PROLOG_NORI(area, label, hsrr, kvm, vec) \ EXCEPTION_PROLOG_0(area); \ - EXCEPTION_PROLOG_1(area, extra, vec); \ - EXCEPTION_PROLOG_2_REAL label, h, 0 + EXCEPTION_PROLOG_1 hsrr, area, kvm, vec ; \ + EXCEPTION_PROLOG_2_REAL label, hsrr, 0 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER .macro KVMTEST hsrr, n @@ -480,8 +507,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) .endm #endif -#define NOTEST(n) - #define EXCEPTION_PROLOG_COMMON_1() \ std r9,_CCR(r1); /* save CR in stackframe */ \ std r11,_NIP(r1); /* save SRR0 in stackframe */ \ @@ -565,7 +590,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) * Exception vectors. */ #define STD_EXCEPTION(vec, label) \ - EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_STD, KVMTEST_PR, vec); + EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_STD, 1, vec); /* Version of above for when we have to branch out-of-line */ #define __OOL_EXCEPTION(vec, label, hdlr) \ @@ -574,112 +599,69 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) b hdlr #define STD_EXCEPTION_OOL(vec, label) \ - EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, vec); \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec ; \ EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 #define STD_EXCEPTION_HV(loc, vec, label) \ - EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec) + EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_HV, 1, vec) #define STD_EXCEPTION_HV_OOL(vec, label) \ - EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec ; \ EXCEPTION_PROLOG_2_REAL label, EXC_HV, 1 #define STD_RELON_EXCEPTION(loc, vec, label) \ /* No guest interrupts come through here */ \ - EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_STD, NOTEST, vec) + EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_STD, 0, vec) #define STD_RELON_EXCEPTION_OOL(vec, label) \ - EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, vec); \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec ; \ EXCEPTION_PROLOG_2_VIRT label, EXC_STD -#define STD_RELON_EXCEPTION_HV(loc, vec, label) \ - EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_HV, KVMTEST_HV, vec) +#define STD_RELON_EXCEPTION_HV(loc, vec, label) \ + EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_HV, 1, vec) #define STD_RELON_EXCEPTION_HV_OOL(vec, label) \ - EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, vec); \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec; \ EXCEPTION_PROLOG_2_VIRT label, EXC_HV -.macro SOFTEN_TEST hsrr, vec, bitmask - lbz r10, PACAIRQSOFTMASK(r13) - andi. r10, r10, \bitmask - /* This associates vector numbers with bits in paca->irq_happened */ - .if \vec == 0x500 || \vec == 0xea0 - li r10, PACA_IRQ_EE - .elseif \vec == 0x900 - li r10, PACA_IRQ_DEC - .elseif \vec == 0xa00 || \vec == 0xe80 - li r10, PACA_IRQ_DBELL - .elseif \vec == 0xe60 - li r10, PACA_IRQ_HMI - .elseif \vec == 0xf00 - li r10, PACA_IRQ_PMI - .else - .abort "Bad maskable vector" - .endif - - - .if \hsrr - bne masked_Hinterrupt - .else - bne masked_interrupt - .endif -.endm - -#define SOFTEN_TEST_PR(vec, bitmask) \ - KVMTEST EXC_STD, vec ; \ - SOFTEN_TEST EXC_STD, vec, bitmask - -#define SOFTEN_TEST_HV(vec, bitmask) \ - KVMTEST EXC_HV, vec ; \ - SOFTEN_TEST EXC_HV, vec, bitmask - -#define KVMTEST_PR(vec) \ - KVMTEST EXC_STD, vec - -#define KVMTEST_HV(vec) \ - KVMTEST EXC_HV, vec - -#define SOFTEN_NOTEST_PR(vec, bitmask) SOFTEN_TEST EXC_STD, vec, bitmask -#define SOFTEN_NOTEST_HV(vec, bitmask) SOFTEN_TEST EXC_HV, vec, bitmask - -#define __MASKABLE_EXCEPTION(vec, label, h, extra, bitmask) \ +#define __MASKABLE_EXCEPTION(vec, label, hsrr, kvm, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ - MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \ - EXCEPTION_PROLOG_2_REAL label, h, 1 + MASKABLE_EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ + EXCEPTION_PROLOG_2_REAL label, hsrr, 1 #define MASKABLE_EXCEPTION(vec, label, bitmask) \ - __MASKABLE_EXCEPTION(vec, label, EXC_STD, SOFTEN_TEST_PR, bitmask) + __MASKABLE_EXCEPTION(vec, label, EXC_STD, 1, bitmask) #define MASKABLE_EXCEPTION_OOL(vec, label, bitmask) \ - MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_PR, vec, bitmask);\ + MASKABLE_EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, bitmask ; \ EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 #define MASKABLE_EXCEPTION_HV(vec, label, bitmask) \ - __MASKABLE_EXCEPTION(vec, label, EXC_HV, SOFTEN_TEST_HV, bitmask) + __MASKABLE_EXCEPTION(vec, label, EXC_HV, 1, bitmask) #define MASKABLE_EXCEPTION_HV_OOL(vec, label, bitmask) \ - MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\ + MASKABLE_EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ EXCEPTION_PROLOG_2_REAL label, EXC_HV, 1 -#define __MASKABLE_RELON_EXCEPTION(vec, label, h, extra, bitmask) \ +#define __MASKABLE_RELON_EXCEPTION(vec, label, hsrr, kvm, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ - MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, extra, vec, bitmask); \ - EXCEPTION_PROLOG_2_VIRT label, h + MASKABLE_EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ + EXCEPTION_PROLOG_2_VIRT label, hsrr #define MASKABLE_RELON_EXCEPTION(vec, label, bitmask) \ - __MASKABLE_RELON_EXCEPTION(vec, label, EXC_STD, SOFTEN_NOTEST_PR, bitmask) + __MASKABLE_RELON_EXCEPTION(vec, label, EXC_STD, 0, bitmask) #define MASKABLE_RELON_EXCEPTION_OOL(vec, label, bitmask) \ - MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_NOTEST_PR, vec, bitmask);\ + MASKABLE_EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, bitmask ; \ EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 #define MASKABLE_RELON_EXCEPTION_HV(vec, label, bitmask) \ - __MASKABLE_RELON_EXCEPTION(vec, label, EXC_HV, SOFTEN_TEST_HV, bitmask) + __MASKABLE_RELON_EXCEPTION(vec, label, EXC_HV, 1, bitmask) #define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label, bitmask) \ - MASKABLE_EXCEPTION_PROLOG_1(PACA_EXGEN, SOFTEN_TEST_HV, vec, bitmask);\ + MASKABLE_EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ EXCEPTION_PROLOG_2_VIRT label, EXC_HV /* diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 08096d3fd5bb..23f5c39063ed 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -107,6 +107,17 @@ __start_interrupts: EXC_VIRT_NONE(0x4000, 0x100) +EXC_REAL_BEGIN(system_reset, 0x100, 0x100) + SET_SCRATCH0(r13) + EXCEPTION_PROLOG_0(PACA_EXNMI) + + /* This is EXCEPTION_PROLOG_1 with the idle feature section added */ + OPT_SAVE_REG_TO_PACA(PACA_EXNMI+EX_PPR, r9, CPU_FTR_HAS_PPR) + OPT_SAVE_REG_TO_PACA(PACA_EXNMI+EX_CFAR, r10, CPU_FTR_CFAR) + INTERRUPT_TO_KERNEL + SAVE_CTR(r10, PACA_EXNMI) + mfcr r9 + #ifdef CONFIG_PPC_P7_NAP /* * If running native on arch 2.06 or later, check if we are waking up @@ -116,30 +127,29 @@ EXC_VIRT_NONE(0x4000, 0x100) * but we branch to the 0xc000... address so we can turn on relocation * with mtmsr. */ -#define IDLETEST(n) \ - BEGIN_FTR_SECTION ; \ - mfspr r10,SPRN_SRR1 ; \ - rlwinm. r10,r10,47-31,30,31 ; \ - beq- 1f ; \ - cmpwi cr1,r10,2 ; \ - mfspr r3,SPRN_SRR1 ; \ - bltlr cr1 ; /* no state loss, return to idle caller */ \ - BRANCH_TO_C000(r10, system_reset_idle_common) ; \ -1: \ - END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) ; \ - KVMTEST_PR(n) -#else -#define IDLETEST KVMTEST_PR + BEGIN_FTR_SECTION + mfspr r10,SPRN_SRR1 + rlwinm. r10,r10,47-31,30,31 + beq- 1f + cmpwi cr1,r10,2 + mfspr r3,SPRN_SRR1 + bltlr cr1 /* no state loss, return to idle caller */ + BRANCH_TO_C000(r10, system_reset_idle_common) +1: + END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) #endif -EXC_REAL_BEGIN(system_reset, 0x100, 0x100) - SET_SCRATCH0(r13) + KVMTEST EXC_STD 0x100 + std r11,PACA_EXNMI+EX_R11(r13) + std r12,PACA_EXNMI+EX_R12(r13) + GET_SCRATCH0(r10) + std r10,PACA_EXNMI+EX_R13(r13) + + EXCEPTION_PROLOG_2_REAL system_reset_common, EXC_STD, 0 /* * MSR_RI is not enabled, because PACA_EXNMI and nmi stack is * being used, so a nested NMI exception would corrupt it. */ - EXCEPTION_PROLOG_NORI(PACA_EXNMI, system_reset_common, EXC_STD, - IDLETEST, 0x100) EXC_REAL_END(system_reset, 0x100, 0x100) EXC_VIRT_NONE(0x4100, 0x100) @@ -246,7 +256,7 @@ TRAMP_REAL_BEGIN(system_reset_fwnmi) SET_SCRATCH0(r13) /* save r13 */ /* See comment at system_reset exception */ EXCEPTION_PROLOG_NORI(PACA_EXNMI, system_reset_common, EXC_STD, - NOTEST, 0x100) + 0, 0x100) #endif /* CONFIG_PPC_PSERIES */ @@ -265,7 +275,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) EXC_REAL_END(machine_check, 0x200, 0x100) EXC_VIRT_NONE(0x4200, 0x100) TRAMP_REAL_BEGIN(machine_check_common_early) - EXCEPTION_PROLOG_1(PACA_EXMC, NOTEST, 0x200) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200 /* * Register contents: * R13 = PACA @@ -350,7 +360,7 @@ BEGIN_FTR_SECTION b machine_check_common_early END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) machine_check_pSeries_0: - EXCEPTION_PROLOG_1(PACA_EXMC, KVMTEST_PR, 0x200) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200 /* * MSR_RI is not enabled, because PACA_EXMC is being used, so a * nested machine check corrupts it. machine_check_common enables @@ -588,7 +598,7 @@ EXCEPTION_PROLOG_0(PACA_EXGEN) EXC_REAL_END(data_access, 0x300, 0x80) TRAMP_REAL_BEGIN(tramp_real_data_access) -EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, 0x300) +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300 /* * DAR/DSISR must be read before setting MSR[RI], because * a d-side MCE will clobber those registers so is not @@ -603,7 +613,7 @@ EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0(PACA_EXGEN) -EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x300) +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) @@ -642,7 +652,7 @@ EXCEPTION_PROLOG_0(PACA_EXSLB) EXC_REAL_END(data_access_slb, 0x380, 0x80) TRAMP_REAL_BEGIN(tramp_real_data_access_slb) -EXCEPTION_PROLOG_1(PACA_EXSLB, KVMTEST_PR, 0x380) +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 1, 0x380 mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 @@ -650,7 +660,7 @@ EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0(PACA_EXSLB) -EXCEPTION_PROLOG_1(PACA_EXSLB, NOTEST, 0x380) +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380 mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) EXCEPTION_PROLOG_2_VIRT data_access_slb_common, EXC_STD @@ -705,11 +715,11 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) EXC_REAL_BEGIN(instruction_access_slb, 0x480, 0x80) -EXCEPTION_PROLOG(PACA_EXSLB, instruction_access_slb_common, EXC_STD, KVMTEST_PR, 0x480); +EXCEPTION_PROLOG(PACA_EXSLB, instruction_access_slb_common, EXC_STD, 1, 0x480); EXC_REAL_END(instruction_access_slb, 0x480, 0x80) EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80) -EXCEPTION_RELON_PROLOG(PACA_EXSLB, instruction_access_slb_common, EXC_STD, NOTEST, 0x480); +EXCEPTION_RELON_PROLOG(PACA_EXSLB, instruction_access_slb_common, EXC_STD, 0, 0x480); EXC_VIRT_END(instruction_access_slb, 0x4480, 0x80) TRAMP_KVM(PACA_EXSLB, 0x480) @@ -757,7 +767,7 @@ hardware_interrupt_relon_hv: IRQS_DISABLED) FTR_SECTION_ELSE __MASKABLE_RELON_EXCEPTION(0x500, hardware_interrupt_common, - EXC_STD, SOFTEN_TEST_PR, IRQS_DISABLED) + EXC_STD, 1, IRQS_DISABLED) ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100) @@ -769,7 +779,7 @@ EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ) EXC_REAL_BEGIN(alignment, 0x600, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0(PACA_EXGEN) -EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_PR, 0x600) +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) @@ -780,7 +790,7 @@ EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0(PACA_EXGEN) -EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x600) +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) @@ -946,7 +956,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception) GET_PACA(r13); \ std r10,PACA_EXGEN+EX_R10(r13); \ INTERRUPT_TO_KERNEL; \ - KVMTEST_PR(0xc00); /* uses r10, branch to do_kvm_0xc00_system_call */ \ + KVMTEST EXC_STD 0xc00 ; /* uses r10, branch to do_kvm_0xc00_system_call */ \ HMT_MEDIUM; \ mfctr r9; @@ -1109,7 +1119,7 @@ __TRAMP_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60, IRQS_DISABLED) EXC_VIRT_NONE(0x4e60, 0x20) TRAMP_KVM_HV(PACA_EXGEN, 0xe60) TRAMP_REAL_BEGIN(hmi_exception_early) - EXCEPTION_PROLOG_1(PACA_EXGEN, KVMTEST_HV, 0xe60) + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0xe60 mr r10,r1 /* Save r1 */ ld r1,PACAEMERGSP(r13) /* Use emergency stack for realmode */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ @@ -1311,7 +1321,7 @@ EXC_VIRT_NONE(0x5400, 0x100) EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) mtspr SPRN_SPRG_HSCRATCH0,r13 EXCEPTION_PROLOG_0(PACA_EXGEN) - EXCEPTION_PROLOG_1(PACA_EXGEN, NOTEST, 0x1500) + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500 #ifdef CONFIG_PPC_DENORMALISATION mfspr r10,SPRN_HSRR1 @@ -1319,7 +1329,7 @@ EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) bne+ denorm_assist #endif - KVMTEST_HV(0x1500) + KVMTEST EXC_HV 0x1500 EXCEPTION_PROLOG_2_REAL denorm_common, EXC_HV, 1 EXC_REAL_END(denorm_exception_hv, 0x1500, 0x100) -- cgit v1.2.3 From fa4cf6b703f4d63b9a422e24332266ef7efae7b6 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:16 +1000 Subject: powerpc/64s/exception: consolidate maskable and non-maskable prologs Conditionally expand the soft-masking test if a mask is passed in. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 112 +++++++++++++------------------ arch/powerpc/kernel/exceptions-64s.S | 20 +++--- 2 files changed, 55 insertions(+), 77 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 0a29bf2db198..4111888e04d7 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -238,7 +238,7 @@ #define EXCEPTION_RELON_PROLOG(area, label, hsrr, kvm, vec) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(area); \ - EXCEPTION_PROLOG_1 hsrr, area, kvm, vec ; \ + EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, 0 ; \ EXCEPTION_PROLOG_2_VIRT label, hsrr /* Exception register prefixes */ @@ -309,73 +309,51 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) std r10,area+EX_R10(r13); /* save r10 - r12 */ \ OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) -#define __EXCEPTION_PROLOG_1_PRE(area) \ - OPT_SAVE_REG_TO_PACA(area+EX_PPR, r9, CPU_FTR_HAS_PPR); \ - OPT_SAVE_REG_TO_PACA(area+EX_CFAR, r10, CPU_FTR_CFAR); \ - INTERRUPT_TO_KERNEL; \ - SAVE_CTR(r10, area); \ +.macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, bitmask + OPT_SAVE_REG_TO_PACA(\area\()+EX_PPR, r9, CPU_FTR_HAS_PPR) + OPT_SAVE_REG_TO_PACA(\area\()+EX_CFAR, r10, CPU_FTR_CFAR) + INTERRUPT_TO_KERNEL + SAVE_CTR(r10, \area\()) mfcr r9 - -#define __EXCEPTION_PROLOG_1_POST(area) \ - std r11,area+EX_R11(r13); \ - std r12,area+EX_R12(r13); \ - GET_SCRATCH0(r10); \ - std r10,area+EX_R13(r13) - -/* - * This version of the EXCEPTION_PROLOG_1 will carry - * addition parameter called "bitmask" to support - * checking of the interrupt maskable level. - * Intended to be used in MASKABLE_EXCPETION_* macros. - */ -.macro MASKABLE_EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, bitmask - __EXCEPTION_PROLOG_1_PRE(\area\()) .if \kvm KVMTEST \hsrr \vec .endif - lbz r10,PACAIRQSOFTMASK(r13) - andi. r10,r10,\bitmask - /* This associates vector numbers with bits in paca->irq_happened */ - .if \vec == 0x500 || \vec == 0xea0 - li r10,PACA_IRQ_EE - .elseif \vec == 0x900 - li r10,PACA_IRQ_DEC - .elseif \vec == 0xa00 || \vec == 0xe80 - li r10,PACA_IRQ_DBELL - .elseif \vec == 0xe60 - li r10,PACA_IRQ_HMI - .elseif \vec == 0xf00 - li r10,PACA_IRQ_PMI - .else - .abort "Bad maskable vector" - .endif - - .if \hsrr - bne masked_Hinterrupt - .else - bne masked_interrupt + .if \bitmask + lbz r10,PACAIRQSOFTMASK(r13) + andi. r10,r10,\bitmask + /* Associate vector numbers with bits in paca->irq_happened */ + .if \vec == 0x500 || \vec == 0xea0 + li r10,PACA_IRQ_EE + .elseif \vec == 0x900 + li r10,PACA_IRQ_DEC + .elseif \vec == 0xa00 || \vec == 0xe80 + li r10,PACA_IRQ_DBELL + .elseif \vec == 0xe60 + li r10,PACA_IRQ_HMI + .elseif \vec == 0xf00 + li r10,PACA_IRQ_PMI + .else + .abort "Bad maskable vector" + .endif + + .if \hsrr + bne masked_Hinterrupt + .else + bne masked_interrupt + .endif .endif - __EXCEPTION_PROLOG_1_POST(\area\()) -.endm - -/* - * This version of the EXCEPTION_PROLOG_1 is intended - * to be used in STD_EXCEPTION* macros - */ -.macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec - __EXCEPTION_PROLOG_1_PRE(\area\()) - .if \kvm - KVMTEST \hsrr \vec - .endif - __EXCEPTION_PROLOG_1_POST(\area\()) + std r11,\area\()+EX_R11(r13) + std r12,\area\()+EX_R12(r13) + GET_SCRATCH0(r10) + std r10,\area\()+EX_R13(r13) .endm #define EXCEPTION_PROLOG(area, label, hsrr, kvm, vec) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(area); \ - EXCEPTION_PROLOG_1 hsrr, area, kvm, vec ; \ + EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, 0 ; \ EXCEPTION_PROLOG_2_REAL label, hsrr, 1 #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE @@ -444,7 +422,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) /* Do not enable RI */ #define EXCEPTION_PROLOG_NORI(area, label, hsrr, kvm, vec) \ EXCEPTION_PROLOG_0(area); \ - EXCEPTION_PROLOG_1 hsrr, area, kvm, vec ; \ + EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, 0 ; \ EXCEPTION_PROLOG_2_REAL label, hsrr, 0 #ifdef CONFIG_KVM_BOOK3S_64_HANDLER @@ -599,14 +577,14 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) b hdlr #define STD_EXCEPTION_OOL(vec, label) \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0 ; \ EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 #define STD_EXCEPTION_HV(loc, vec, label) \ EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_HV, 1, vec) #define STD_EXCEPTION_HV_OOL(vec, label) \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec ; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0 ; \ EXCEPTION_PROLOG_2_REAL label, EXC_HV, 1 #define STD_RELON_EXCEPTION(loc, vec, label) \ @@ -614,54 +592,54 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_STD, 0, vec) #define STD_RELON_EXCEPTION_OOL(vec, label) \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, 0 ; \ EXCEPTION_PROLOG_2_VIRT label, EXC_STD #define STD_RELON_EXCEPTION_HV(loc, vec, label) \ EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_HV, 1, vec) #define STD_RELON_EXCEPTION_HV_OOL(vec, label) \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0 ; \ EXCEPTION_PROLOG_2_VIRT label, EXC_HV #define __MASKABLE_EXCEPTION(vec, label, hsrr, kvm, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ - MASKABLE_EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ + EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ EXCEPTION_PROLOG_2_REAL label, hsrr, 1 #define MASKABLE_EXCEPTION(vec, label, bitmask) \ __MASKABLE_EXCEPTION(vec, label, EXC_STD, 1, bitmask) #define MASKABLE_EXCEPTION_OOL(vec, label, bitmask) \ - MASKABLE_EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, bitmask ; \ EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 #define MASKABLE_EXCEPTION_HV(vec, label, bitmask) \ __MASKABLE_EXCEPTION(vec, label, EXC_HV, 1, bitmask) #define MASKABLE_EXCEPTION_HV_OOL(vec, label, bitmask) \ - MASKABLE_EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ EXCEPTION_PROLOG_2_REAL label, EXC_HV, 1 #define __MASKABLE_RELON_EXCEPTION(vec, label, hsrr, kvm, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0(PACA_EXGEN); \ - MASKABLE_EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ + EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ EXCEPTION_PROLOG_2_VIRT label, hsrr #define MASKABLE_RELON_EXCEPTION(vec, label, bitmask) \ __MASKABLE_RELON_EXCEPTION(vec, label, EXC_STD, 0, bitmask) #define MASKABLE_RELON_EXCEPTION_OOL(vec, label, bitmask) \ - MASKABLE_EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, bitmask ; \ EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 #define MASKABLE_RELON_EXCEPTION_HV(vec, label, bitmask) \ __MASKABLE_RELON_EXCEPTION(vec, label, EXC_HV, 1, bitmask) #define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label, bitmask) \ - MASKABLE_EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ EXCEPTION_PROLOG_2_VIRT label, EXC_HV /* diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 23f5c39063ed..cc356a31d5cc 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -275,7 +275,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) EXC_REAL_END(machine_check, 0x200, 0x100) EXC_VIRT_NONE(0x4200, 0x100) TRAMP_REAL_BEGIN(machine_check_common_early) - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200 + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 0 /* * Register contents: * R13 = PACA @@ -360,7 +360,7 @@ BEGIN_FTR_SECTION b machine_check_common_early END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) machine_check_pSeries_0: - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200 + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 0 /* * MSR_RI is not enabled, because PACA_EXMC is being used, so a * nested machine check corrupts it. machine_check_common enables @@ -598,7 +598,7 @@ EXCEPTION_PROLOG_0(PACA_EXGEN) EXC_REAL_END(data_access, 0x300, 0x80) TRAMP_REAL_BEGIN(tramp_real_data_access) -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300 +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300, 0 /* * DAR/DSISR must be read before setting MSR[RI], because * a d-side MCE will clobber those registers so is not @@ -613,7 +613,7 @@ EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0(PACA_EXGEN) -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300 +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300, 0 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) @@ -652,7 +652,7 @@ EXCEPTION_PROLOG_0(PACA_EXSLB) EXC_REAL_END(data_access_slb, 0x380, 0x80) TRAMP_REAL_BEGIN(tramp_real_data_access_slb) -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 1, 0x380 +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 1, 0x380, 0 mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 @@ -660,7 +660,7 @@ EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0(PACA_EXSLB) -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380 +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380, 0 mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) EXCEPTION_PROLOG_2_VIRT data_access_slb_common, EXC_STD @@ -779,7 +779,7 @@ EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ) EXC_REAL_BEGIN(alignment, 0x600, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0(PACA_EXGEN) -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600 +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600, 0 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) @@ -790,7 +790,7 @@ EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0(PACA_EXGEN) -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600 +EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600, 0 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) @@ -1119,7 +1119,7 @@ __TRAMP_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60, IRQS_DISABLED) EXC_VIRT_NONE(0x4e60, 0x20) TRAMP_KVM_HV(PACA_EXGEN, 0xe60) TRAMP_REAL_BEGIN(hmi_exception_early) - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0xe60 + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0xe60, 0 mr r10,r1 /* Save r1 */ ld r1,PACAEMERGSP(r13) /* Use emergency stack for realmode */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ @@ -1321,7 +1321,7 @@ EXC_VIRT_NONE(0x5400, 0x100) EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) mtspr SPRN_SPRG_HSCRATCH0,r13 EXCEPTION_PROLOG_0(PACA_EXGEN) - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500 + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500, 0 #ifdef CONFIG_PPC_DENORMALISATION mfspr r10,SPRN_HSRR1 -- cgit v1.2.3 From 17bdc064a1fe8638b526ec44e6593685dbfdc714 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:17 +1000 Subject: powerpc/64s/exception: merge KVM handler and skip variants Conditionally expand the skip case if it is specified. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 28 ++++++++++------------------ arch/powerpc/include/asm/head-64.h | 8 ++++---- arch/powerpc/kernel/exceptions-64s.S | 2 +- 3 files changed, 15 insertions(+), 23 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 4111888e04d7..d2a5bbeb727d 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -436,26 +436,17 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) .endif .endm -.macro KVM_HANDLER area, hsrr, n +.macro KVM_HANDLER area, hsrr, n, skip + .if \skip + cmpwi r10,KVM_GUEST_MODE_SKIP + beq 89f + .else BEGIN_FTR_SECTION_NESTED(947) ld r10,\area+EX_CFAR(r13) std r10,HSTATE_CFAR(r13) END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947) - BEGIN_FTR_SECTION_NESTED(948) - ld r10,\area+EX_PPR(r13) - std r10,HSTATE_PPR(r13) - END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) - ld r10,\area+EX_R10(r13) - std r12,HSTATE_SCRATCH0(r13) - sldi r12,r9,32 - ori r12,r12,(\n) - /* This reloads r9 before branching to kvmppc_interrupt */ - __BRANCH_TO_KVM_EXIT(\area, kvmppc_interrupt) -.endm + .endif -.macro KVM_HANDLER_SKIP area, hsrr, n - cmpwi r10,KVM_GUEST_MODE_SKIP - beq 89f BEGIN_FTR_SECTION_NESTED(948) ld r10,\area+EX_PPR(r13) std r10,HSTATE_PPR(r13) @@ -466,6 +457,8 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) ori r12,r12,(\n) /* This reloads r9 before branching to kvmppc_interrupt */ __BRANCH_TO_KVM_EXIT(\area, kvmppc_interrupt) + + .if \skip 89: mtocrf 0x80,r9 ld r9,\area+EX_R9(r13) ld r10,\area+EX_R10(r13) @@ -474,14 +467,13 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) .else b kvmppc_skip_interrupt .endif + .endif .endm #else .macro KVMTEST hsrr, n .endm -.macro KVM_HANDLER area, hsrr, n -.endm -.macro KVM_HANDLER_SKIP area, hsrr, n +.macro KVM_HANDLER area, hsrr, n, skip .endm #endif diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index 4767d6c7b8fa..518d9758b41e 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -387,22 +387,22 @@ name: #define TRAMP_KVM(area, n) \ TRAMP_KVM_BEGIN(do_kvm_##n); \ - KVM_HANDLER area, EXC_STD, n + KVM_HANDLER area, EXC_STD, n, 0 #define TRAMP_KVM_SKIP(area, n) \ TRAMP_KVM_BEGIN(do_kvm_##n); \ - KVM_HANDLER_SKIP area, EXC_STD, n + KVM_HANDLER area, EXC_STD, n, 1 /* * HV variant exceptions get the 0x2 bit added to their trap number. */ #define TRAMP_KVM_HV(area, n) \ TRAMP_KVM_BEGIN(do_kvm_H##n); \ - KVM_HANDLER area, EXC_HV, n + 0x2 + KVM_HANDLER area, EXC_HV, n + 0x2, 0 #define TRAMP_KVM_HV_SKIP(area, n) \ TRAMP_KVM_BEGIN(do_kvm_H##n); \ - KVM_HANDLER_SKIP area, EXC_HV, n + 0x2 + KVM_HANDLER area, EXC_HV, n + 0x2, 1 #define EXC_COMMON(name, realvec, hdlr) \ EXC_COMMON_BEGIN(name); \ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index cc356a31d5cc..d30f2b5fd206 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1063,7 +1063,7 @@ TRAMP_KVM_BEGIN(do_kvm_0xc00) SET_SCRATCH0(r10) std r9,PACA_EXGEN+EX_R9(r13) mfcr r9 - KVM_HANDLER PACA_EXGEN, EXC_STD, 0xc00 + KVM_HANDLER PACA_EXGEN, EXC_STD, 0xc00, 0 #endif -- cgit v1.2.3 From c0c6cd156c1239cd199a3bc083f1924518dd02a6 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:18 +1000 Subject: powerpc/64s/exception: KVM handler can set the HSRR trap bit Move the KVM trap HSRR bit into the KVM handler, which can be conditionally applied when hsrr parameter is set. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 5 +++++ arch/powerpc/include/asm/head-64.h | 7 ++----- 2 files changed, 7 insertions(+), 5 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index d2a5bbeb727d..a7b514574b80 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -454,7 +454,12 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) ld r10,\area+EX_R10(r13) std r12,HSTATE_SCRATCH0(r13) sldi r12,r9,32 + /* HSRR variants have the 0x2 bit added to their trap number */ + .if \hsrr + ori r12,r12,(\n + 0x2) + .else ori r12,r12,(\n) + .endif /* This reloads r9 before branching to kvmppc_interrupt */ __BRANCH_TO_KVM_EXIT(\area, kvmppc_interrupt) diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index 518d9758b41e..bdd67a26e959 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -393,16 +393,13 @@ name: TRAMP_KVM_BEGIN(do_kvm_##n); \ KVM_HANDLER area, EXC_STD, n, 1 -/* - * HV variant exceptions get the 0x2 bit added to their trap number. - */ #define TRAMP_KVM_HV(area, n) \ TRAMP_KVM_BEGIN(do_kvm_H##n); \ - KVM_HANDLER area, EXC_HV, n + 0x2, 0 + KVM_HANDLER area, EXC_HV, n, 0 #define TRAMP_KVM_HV_SKIP(area, n) \ TRAMP_KVM_BEGIN(do_kvm_H##n); \ - KVM_HANDLER area, EXC_HV, n + 0x2, 1 + KVM_HANDLER area, EXC_HV, n, 1 #define EXC_COMMON(name, realvec, hdlr) \ EXC_COMMON_BEGIN(name); \ -- cgit v1.2.3 From 5dba1d50ba4f44a82e7228d6fb83ccdfd1bda0fb Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:19 +1000 Subject: powerpc/64s/exception: Make EXCEPTION_PROLOG_0 a gas macro for consistency with others No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 25 +++++++++++++------------ arch/powerpc/kernel/exceptions-64s.S | 24 ++++++++++++------------ 2 files changed, 25 insertions(+), 24 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index a7b514574b80..663998e411e6 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -237,7 +237,7 @@ */ #define EXCEPTION_RELON_PROLOG(area, label, hsrr, kvm, vec) \ SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0(area); \ + EXCEPTION_PROLOG_0 area ; \ EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, 0 ; \ EXCEPTION_PROLOG_2_VIRT label, hsrr @@ -301,13 +301,14 @@ BEGIN_FTR_SECTION_NESTED(943) \ std ra,offset(r13); \ END_FTR_SECTION_NESTED(ftr,ftr,943) -#define EXCEPTION_PROLOG_0(area) \ - GET_PACA(r13); \ - std r9,area+EX_R9(r13); /* save r9 */ \ - OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR); \ - HMT_MEDIUM; \ - std r10,area+EX_R10(r13); /* save r10 - r12 */ \ +.macro EXCEPTION_PROLOG_0 area + GET_PACA(r13) + std r9,\area\()+EX_R9(r13) /* save r9 */ + OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR) + HMT_MEDIUM + std r10,\area\()+EX_R10(r13) /* save r10 - r12 */ OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) +.endm .macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, bitmask OPT_SAVE_REG_TO_PACA(\area\()+EX_PPR, r9, CPU_FTR_HAS_PPR) @@ -352,7 +353,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define EXCEPTION_PROLOG(area, label, hsrr, kvm, vec) \ SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0(area); \ + EXCEPTION_PROLOG_0 area ; \ EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, 0 ; \ EXCEPTION_PROLOG_2_REAL label, hsrr, 1 @@ -421,7 +422,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) /* Do not enable RI */ #define EXCEPTION_PROLOG_NORI(area, label, hsrr, kvm, vec) \ - EXCEPTION_PROLOG_0(area); \ + EXCEPTION_PROLOG_0 area ; \ EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, 0 ; \ EXCEPTION_PROLOG_2_REAL label, hsrr, 0 @@ -570,7 +571,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) /* Version of above for when we have to branch out-of-line */ #define __OOL_EXCEPTION(vec, label, hdlr) \ SET_SCRATCH0(r13); \ - EXCEPTION_PROLOG_0(PACA_EXGEN); \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ b hdlr #define STD_EXCEPTION_OOL(vec, label) \ @@ -601,7 +602,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define __MASKABLE_EXCEPTION(vec, label, hsrr, kvm, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0(PACA_EXGEN); \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ EXCEPTION_PROLOG_2_REAL label, hsrr, 1 @@ -621,7 +622,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #define __MASKABLE_RELON_EXCEPTION(vec, label, hsrr, kvm, bitmask) \ SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0(PACA_EXGEN); \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ EXCEPTION_PROLOG_2_VIRT label, hsrr diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index d30f2b5fd206..99541f7eabde 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -109,7 +109,7 @@ EXC_VIRT_NONE(0x4000, 0x100) EXC_REAL_BEGIN(system_reset, 0x100, 0x100) SET_SCRATCH0(r13) - EXCEPTION_PROLOG_0(PACA_EXNMI) + EXCEPTION_PROLOG_0 PACA_EXNMI /* This is EXCEPTION_PROLOG_1 with the idle feature section added */ OPT_SAVE_REG_TO_PACA(PACA_EXNMI+EX_PPR, r9, CPU_FTR_HAS_PPR) @@ -266,7 +266,7 @@ EXC_REAL_BEGIN(machine_check, 0x200, 0x100) * vector */ SET_SCRATCH0(r13) /* save r13 */ - EXCEPTION_PROLOG_0(PACA_EXMC) + EXCEPTION_PROLOG_0 PACA_EXMC BEGIN_FTR_SECTION b machine_check_common_early FTR_SECTION_ELSE @@ -355,7 +355,7 @@ TRAMP_REAL_BEGIN(machine_check_pSeries) .globl machine_check_fwnmi machine_check_fwnmi: SET_SCRATCH0(r13) /* save r13 */ - EXCEPTION_PROLOG_0(PACA_EXMC) + EXCEPTION_PROLOG_0 PACA_EXMC BEGIN_FTR_SECTION b machine_check_common_early END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) @@ -568,7 +568,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) /* Deliver the machine check to host kernel in V mode. */ MACHINE_CHECK_HANDLER_WINDUP SET_SCRATCH0(r13) /* save r13 */ - EXCEPTION_PROLOG_0(PACA_EXMC) + EXCEPTION_PROLOG_0 PACA_EXMC b machine_check_pSeries_0 EXC_COMMON_BEGIN(unrecover_mce) @@ -593,7 +593,7 @@ EXC_COMMON_BEGIN(mce_return) EXC_REAL_BEGIN(data_access, 0x300, 0x80) SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0(PACA_EXGEN) +EXCEPTION_PROLOG_0 PACA_EXGEN b tramp_real_data_access EXC_REAL_END(data_access, 0x300, 0x80) @@ -612,7 +612,7 @@ EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0(PACA_EXGEN) +EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300, 0 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR @@ -647,7 +647,7 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80) SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0(PACA_EXSLB) +EXCEPTION_PROLOG_0 PACA_EXSLB b tramp_real_data_access_slb EXC_REAL_END(data_access_slb, 0x380, 0x80) @@ -659,7 +659,7 @@ EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0(PACA_EXSLB) +EXCEPTION_PROLOG_0 PACA_EXSLB EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380, 0 mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) @@ -778,7 +778,7 @@ EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ) EXC_REAL_BEGIN(alignment, 0x600, 0x100) SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0(PACA_EXGEN) +EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600, 0 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR @@ -789,7 +789,7 @@ EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0(PACA_EXGEN) +EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600, 0 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR @@ -1167,7 +1167,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early) .globl hmi_exception_after_realmode hmi_exception_after_realmode: SET_SCRATCH0(r13) - EXCEPTION_PROLOG_0(PACA_EXGEN) + EXCEPTION_PROLOG_0 PACA_EXGEN b tramp_real_hmi_exception EXC_COMMON_BEGIN(hmi_exception_common) @@ -1320,7 +1320,7 @@ EXC_VIRT_NONE(0x5400, 0x100) EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) mtspr SPRN_SPRG_HSCRATCH0,r13 - EXCEPTION_PROLOG_0(PACA_EXGEN) + EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500, 0 #ifdef CONFIG_PPC_DENORMALISATION -- cgit v1.2.3 From c06075f3d3fc4d9be7f3f9d9832b4a387037cc26 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:20 +1000 Subject: powerpc/64s/exception: Move EXCEPTION_COMMON handler and return branches into callers The aim is to reduce the amount of indirection it takes to get through the exception handler macros, particularly where it provides little code sharing. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 26 +++++++++++++------------- arch/powerpc/kernel/exceptions-64s.S | 21 +++++++++++++-------- 2 files changed, 26 insertions(+), 21 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 663998e411e6..c98e274b5fba 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -663,31 +663,28 @@ BEGIN_FTR_SECTION \ beql ppc64_runlatch_on_trampoline; \ END_FTR_SECTION_IFSET(CPU_FTR_CTRL) -#define EXCEPTION_COMMON(area, trap, label, hdlr, ret, additions) \ +#define EXCEPTION_COMMON(area, trap, label, additions) \ EXCEPTION_PROLOG_COMMON(trap, area); \ /* Volatile regs are potentially clobbered here */ \ - additions; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b ret + additions /* * Exception where stack is already set in r1, r1 is saved in r10, and it * continues rather than returns. */ -#define EXCEPTION_COMMON_NORET_STACK(area, trap, label, hdlr, additions) \ +#define EXCEPTION_COMMON_NORET_STACK(area, trap, label, additions) \ EXCEPTION_PROLOG_COMMON_1(); \ kuap_save_amr_and_lock r9, r10, cr1; \ EXCEPTION_PROLOG_COMMON_2(area); \ EXCEPTION_PROLOG_COMMON_3(trap); \ /* Volatile regs are potentially clobbered here */ \ - additions; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr + additions #define STD_EXCEPTION_COMMON(trap, label, hdlr) \ - EXCEPTION_COMMON(PACA_EXGEN, trap, label, hdlr, \ - ret_from_except, ADD_NVGPRS;ADD_RECONCILE) + EXCEPTION_COMMON(PACA_EXGEN, trap, label, ADD_NVGPRS;ADD_RECONCILE); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b ret_from_except /* * Like STD_EXCEPTION_COMMON, but for exceptions that can occur @@ -695,8 +692,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_CTRL) * (finish nap and runlatch) */ #define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ - EXCEPTION_COMMON(PACA_EXGEN, trap, label, hdlr, \ - ret_from_except_lite, FINISH_NAP;ADD_RECONCILE;RUNLATCH_ON) + EXCEPTION_COMMON(PACA_EXGEN, trap, label, \ + FINISH_NAP;ADD_RECONCILE;RUNLATCH_ON); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b ret_from_except_lite /* * When the idle code in power4_idle puts the CPU into NAP mode, diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 99541f7eabde..7cf0e38875c3 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -195,9 +195,10 @@ EXC_COMMON_BEGIN(system_reset_common) mr r10,r1 ld r1,PACA_NMI_EMERG_SP(r13) subi r1,r1,INT_FRAME_SIZE - EXCEPTION_COMMON_NORET_STACK(PACA_EXNMI, 0x100, - system_reset, system_reset_exception, - ADD_NVGPRS;ADD_RECONCILE_NMI) + EXCEPTION_COMMON_NORET_STACK(PACA_EXNMI, 0x100, system_reset, + ADD_NVGPRS;ADD_RECONCILE_NMI) + addi r3,r1,STACK_FRAME_OVERHEAD + bl system_reset_exception /* This (and MCE) can be simplified with mtmsrd L=1 */ /* Clear MSR_RI before setting SRR0 and SRR1. */ @@ -1171,8 +1172,11 @@ hmi_exception_after_realmode: b tramp_real_hmi_exception EXC_COMMON_BEGIN(hmi_exception_common) -EXCEPTION_COMMON(PACA_EXGEN, 0xe60, hmi_exception_common, handle_hmi_exception, - ret_from_except, FINISH_NAP;ADD_NVGPRS;ADD_RECONCILE;RUNLATCH_ON) +EXCEPTION_COMMON(PACA_EXGEN, 0xe60, hmi_exception_common, + FINISH_NAP;ADD_NVGPRS;ADD_RECONCILE;RUNLATCH_ON) + addi r3,r1,STACK_FRAME_OVERHEAD + bl handle_hmi_exception + b ret_from_except EXC_REAL_OOL_MASKABLE_HV(h_doorbell, 0xe80, 0x20, IRQS_DISABLED) EXC_VIRT_OOL_MASKABLE_HV(h_doorbell, 0x4e80, 0x20, 0xe80, IRQS_DISABLED) @@ -1467,9 +1471,10 @@ EXC_COMMON_BEGIN(soft_nmi_common) mr r10,r1 ld r1,PACAEMERGSP(r13) subi r1,r1,INT_FRAME_SIZE - EXCEPTION_COMMON_NORET_STACK(PACA_EXGEN, 0x900, - system_reset, soft_nmi_interrupt, - ADD_NVGPRS;ADD_RECONCILE) + EXCEPTION_COMMON_NORET_STACK(PACA_EXGEN, 0x900, system_reset, + ADD_NVGPRS;ADD_RECONCILE) + addi r3,r1,STACK_FRAME_OVERHEAD + bl soft_nmi_interrupt b ret_from_except #else /* CONFIG_PPC_WATCHDOG */ -- cgit v1.2.3 From 47169fba3af465c995a936e6b9c67e0746f4c583 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:21 +1000 Subject: powerpc/64s/exception: Move EXCEPTION_COMMON additions into callers More cases of code insertion via macros that does not add a great deal. All the additions have to be specified in the macro arguments, so they can just as well go after the macro. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 42 +++++++++-------------------- arch/powerpc/include/asm/head-64.h | 4 +-- arch/powerpc/kernel/exceptions-64s.S | 45 +++++++++++++++++--------------- 3 files changed, 39 insertions(+), 52 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index c98e274b5fba..127ebd8d7746 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -640,21 +640,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ EXCEPTION_PROLOG_2_VIRT label, EXC_HV -/* - * Our exception common code can be passed various "additions" - * to specify the behaviour of interrupts, whether to kick the - * runlatch, etc... - */ - -/* - * This addition reconciles our actual IRQ state with the various software - * flags that track it. This may call C code. - */ -#define ADD_RECONCILE RECONCILE_IRQ_STATE(r10,r11) - -#define ADD_NVGPRS \ - bl save_nvgprs - #define RUNLATCH_ON \ BEGIN_FTR_SECTION \ ld r3, PACA_THREAD_INFO(r13); \ @@ -663,25 +648,22 @@ BEGIN_FTR_SECTION \ beql ppc64_runlatch_on_trampoline; \ END_FTR_SECTION_IFSET(CPU_FTR_CTRL) -#define EXCEPTION_COMMON(area, trap, label, additions) \ +#define EXCEPTION_COMMON(area, trap) \ EXCEPTION_PROLOG_COMMON(trap, area); \ - /* Volatile regs are potentially clobbered here */ \ - additions /* - * Exception where stack is already set in r1, r1 is saved in r10, and it - * continues rather than returns. + * Exception where stack is already set in r1, r1 is saved in r10 */ -#define EXCEPTION_COMMON_NORET_STACK(area, trap, label, additions) \ +#define EXCEPTION_COMMON_STACK(area, trap) \ EXCEPTION_PROLOG_COMMON_1(); \ kuap_save_amr_and_lock r9, r10, cr1; \ EXCEPTION_PROLOG_COMMON_2(area); \ - EXCEPTION_PROLOG_COMMON_3(trap); \ - /* Volatile regs are potentially clobbered here */ \ - additions + EXCEPTION_PROLOG_COMMON_3(trap) -#define STD_EXCEPTION_COMMON(trap, label, hdlr) \ - EXCEPTION_COMMON(PACA_EXGEN, trap, label, ADD_NVGPRS;ADD_RECONCILE); \ +#define STD_EXCEPTION_COMMON(trap, hdlr) \ + EXCEPTION_COMMON(PACA_EXGEN, trap); \ + bl save_nvgprs; \ + RECONCILE_IRQ_STATE(r10, r11); \ addi r3,r1,STACK_FRAME_OVERHEAD; \ bl hdlr; \ b ret_from_except @@ -691,9 +673,11 @@ END_FTR_SECTION_IFSET(CPU_FTR_CTRL) * in the idle task and therefore need the special idle handling * (finish nap and runlatch) */ -#define STD_EXCEPTION_COMMON_ASYNC(trap, label, hdlr) \ - EXCEPTION_COMMON(PACA_EXGEN, trap, label, \ - FINISH_NAP;ADD_RECONCILE;RUNLATCH_ON); \ +#define STD_EXCEPTION_COMMON_ASYNC(trap, hdlr) \ + EXCEPTION_COMMON(PACA_EXGEN, trap); \ + FINISH_NAP; \ + RECONCILE_IRQ_STATE(r10, r11); \ + RUNLATCH_ON; \ addi r3,r1,STACK_FRAME_OVERHEAD; \ bl hdlr; \ b ret_from_except_lite diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index bdd67a26e959..acd94fcf9f40 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -403,11 +403,11 @@ name: #define EXC_COMMON(name, realvec, hdlr) \ EXC_COMMON_BEGIN(name); \ - STD_EXCEPTION_COMMON(realvec, name, hdlr) + STD_EXCEPTION_COMMON(realvec, hdlr) #define EXC_COMMON_ASYNC(name, realvec, hdlr) \ EXC_COMMON_BEGIN(name); \ - STD_EXCEPTION_COMMON_ASYNC(realvec, name, hdlr) + STD_EXCEPTION_COMMON_ASYNC(realvec, hdlr) #endif /* __ASSEMBLY__ */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 7cf0e38875c3..2685c81e28f2 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -164,21 +164,6 @@ EXC_COMMON_BEGIN(system_reset_idle_common) b idle_return_gpr_loss #endif -/* - * Set IRQS_ALL_DISABLED unconditionally so arch_irqs_disabled does - * the right thing. We do not want to reconcile because that goes - * through irq tracing which we don't want in NMI. - * - * Save PACAIRQHAPPENED because some code will do a hard disable - * (e.g., xmon). So we want to restore this back to where it was - * when we return. DAR is unused in the stack, so save it there. - */ -#define ADD_RECONCILE_NMI \ - li r10,IRQS_ALL_DISABLED; \ - stb r10,PACAIRQSOFTMASK(r13); \ - lbz r10,PACAIRQHAPPENED(r13); \ - std r10,_DAR(r1) - EXC_COMMON_BEGIN(system_reset_common) /* * Increment paca->in_nmi then enable MSR_RI. SLB or MCE will be able @@ -195,8 +180,22 @@ EXC_COMMON_BEGIN(system_reset_common) mr r10,r1 ld r1,PACA_NMI_EMERG_SP(r13) subi r1,r1,INT_FRAME_SIZE - EXCEPTION_COMMON_NORET_STACK(PACA_EXNMI, 0x100, system_reset, - ADD_NVGPRS;ADD_RECONCILE_NMI) + EXCEPTION_COMMON_STACK(PACA_EXNMI, 0x100) + bl save_nvgprs + /* + * Set IRQS_ALL_DISABLED unconditionally so arch_irqs_disabled does + * the right thing. We do not want to reconcile because that goes + * through irq tracing which we don't want in NMI. + * + * Save PACAIRQHAPPENED because some code will do a hard disable + * (e.g., xmon). So we want to restore this back to where it was + * when we return. DAR is unused in the stack, so save it there. + */ + li r10,IRQS_ALL_DISABLED + stb r10,PACAIRQSOFTMASK(r13) + lbz r10,PACAIRQHAPPENED(r13) + std r10,_DAR(r1) + addi r3,r1,STACK_FRAME_OVERHEAD bl system_reset_exception @@ -1172,8 +1171,11 @@ hmi_exception_after_realmode: b tramp_real_hmi_exception EXC_COMMON_BEGIN(hmi_exception_common) -EXCEPTION_COMMON(PACA_EXGEN, 0xe60, hmi_exception_common, - FINISH_NAP;ADD_NVGPRS;ADD_RECONCILE;RUNLATCH_ON) + EXCEPTION_COMMON(PACA_EXGEN, 0xe60) + FINISH_NAP + bl save_nvgprs + RECONCILE_IRQ_STATE(r10, r11) + RUNLATCH_ON addi r3,r1,STACK_FRAME_OVERHEAD bl handle_hmi_exception b ret_from_except @@ -1471,8 +1473,9 @@ EXC_COMMON_BEGIN(soft_nmi_common) mr r10,r1 ld r1,PACAEMERGSP(r13) subi r1,r1,INT_FRAME_SIZE - EXCEPTION_COMMON_NORET_STACK(PACA_EXGEN, 0x900, system_reset, - ADD_NVGPRS;ADD_RECONCILE) + EXCEPTION_COMMON_STACK(PACA_EXGEN, 0x900) + bl save_nvgprs + RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD bl soft_nmi_interrupt b ret_from_except -- cgit v1.2.3 From fc557537f2ad546e5c6f217143d8a95382f2e1b5 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:22 +1000 Subject: powerpc/64s/exception: unwind exception-64s.h macros Many of these macros just specify 1-4 lines which are only called a few times each at most, and often just once. Remove this indirection. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 101 ------------------------------- arch/powerpc/include/asm/head-64.h | 76 +++++++++++++++++------ arch/powerpc/kernel/exceptions-64s.S | 44 ++++++++------ 3 files changed, 82 insertions(+), 139 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 127ebd8d7746..6efd182da254 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -230,17 +230,6 @@ #endif .endm -/* - * As EXCEPTION_PROLOG(), except we've already got relocation on so no need to - * rfid. Save CTR in case we're CONFIG_RELOCATABLE, in which case - * EXCEPTION_PROLOG_2_VIRT will be using CTR. - */ -#define EXCEPTION_RELON_PROLOG(area, label, hsrr, kvm, vec) \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 area ; \ - EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, 0 ; \ - EXCEPTION_PROLOG_2_VIRT label, hsrr - /* Exception register prefixes */ #define EXC_HV 1 #define EXC_STD 0 @@ -351,12 +340,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) std r10,\area\()+EX_R13(r13) .endm -#define EXCEPTION_PROLOG(area, label, hsrr, kvm, vec) \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 area ; \ - EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, 0 ; \ - EXCEPTION_PROLOG_2_REAL label, hsrr, 1 - #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* * If hv is possible, interrupts come into to the hv version @@ -420,12 +403,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #endif -/* Do not enable RI */ -#define EXCEPTION_PROLOG_NORI(area, label, hsrr, kvm, vec) \ - EXCEPTION_PROLOG_0 area ; \ - EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, 0 ; \ - EXCEPTION_PROLOG_2_REAL label, hsrr, 0 - #ifdef CONFIG_KVM_BOOK3S_64_HANDLER .macro KVMTEST hsrr, n lbz r10,HSTATE_IN_GUEST(r13) @@ -562,84 +539,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) std r10,RESULT(r1); /* clear regs->result */ \ std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ -/* - * Exception vectors. - */ -#define STD_EXCEPTION(vec, label) \ - EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_STD, 1, vec); - -/* Version of above for when we have to branch out-of-line */ -#define __OOL_EXCEPTION(vec, label, hdlr) \ - SET_SCRATCH0(r13); \ - EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - b hdlr - -#define STD_EXCEPTION_OOL(vec, label) \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0 ; \ - EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 - -#define STD_EXCEPTION_HV(loc, vec, label) \ - EXCEPTION_PROLOG(PACA_EXGEN, label, EXC_HV, 1, vec) - -#define STD_EXCEPTION_HV_OOL(vec, label) \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0 ; \ - EXCEPTION_PROLOG_2_REAL label, EXC_HV, 1 - -#define STD_RELON_EXCEPTION(loc, vec, label) \ - /* No guest interrupts come through here */ \ - EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_STD, 0, vec) - -#define STD_RELON_EXCEPTION_OOL(vec, label) \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, 0 ; \ - EXCEPTION_PROLOG_2_VIRT label, EXC_STD - -#define STD_RELON_EXCEPTION_HV(loc, vec, label) \ - EXCEPTION_RELON_PROLOG(PACA_EXGEN, label, EXC_HV, 1, vec) - -#define STD_RELON_EXCEPTION_HV_OOL(vec, label) \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0 ; \ - EXCEPTION_PROLOG_2_VIRT label, EXC_HV - -#define __MASKABLE_EXCEPTION(vec, label, hsrr, kvm, bitmask) \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ - EXCEPTION_PROLOG_2_REAL label, hsrr, 1 - -#define MASKABLE_EXCEPTION(vec, label, bitmask) \ - __MASKABLE_EXCEPTION(vec, label, EXC_STD, 1, bitmask) - -#define MASKABLE_EXCEPTION_OOL(vec, label, bitmask) \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, bitmask ; \ - EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 - -#define MASKABLE_EXCEPTION_HV(vec, label, bitmask) \ - __MASKABLE_EXCEPTION(vec, label, EXC_HV, 1, bitmask) - -#define MASKABLE_EXCEPTION_HV_OOL(vec, label, bitmask) \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ - EXCEPTION_PROLOG_2_REAL label, EXC_HV, 1 - -#define __MASKABLE_RELON_EXCEPTION(vec, label, hsrr, kvm, bitmask) \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - EXCEPTION_PROLOG_1 hsrr, PACA_EXGEN, kvm, vec, bitmask ; \ - EXCEPTION_PROLOG_2_VIRT label, hsrr - -#define MASKABLE_RELON_EXCEPTION(vec, label, bitmask) \ - __MASKABLE_RELON_EXCEPTION(vec, label, EXC_STD, 0, bitmask) - -#define MASKABLE_RELON_EXCEPTION_OOL(vec, label, bitmask) \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, bitmask ; \ - EXCEPTION_PROLOG_2_REAL label, EXC_STD, 1 - -#define MASKABLE_RELON_EXCEPTION_HV(vec, label, bitmask) \ - __MASKABLE_RELON_EXCEPTION(vec, label, EXC_HV, 1, bitmask) - -#define MASKABLE_RELON_EXCEPTION_HV_OOL(vec, label, bitmask) \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ - EXCEPTION_PROLOG_2_VIRT label, EXC_HV - #define RUNLATCH_ON \ BEGIN_FTR_SECTION \ ld r3, PACA_THREAD_INFO(r13); \ diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index acd94fcf9f40..54db05afb80f 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -258,44 +258,71 @@ name: FIXED_SECTION_ENTRY_END_LOCATION(virt_vectors, exc_virt_##start##_##unused, start, size) -#define EXC_REAL(name, start, size) \ +#define __EXC_REAL(name, start, size, area) \ EXC_REAL_BEGIN(name, start, size); \ - STD_EXCEPTION(start, name##_common); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 area ; \ + EXCEPTION_PROLOG_1 EXC_STD, area, 1, start, 0 ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ EXC_REAL_END(name, start, size) -#define EXC_VIRT(name, start, size, realvec) \ +#define EXC_REAL(name, start, size) \ + __EXC_REAL(name, start, size, PACA_EXGEN) + +#define __EXC_VIRT(name, start, size, realvec, area) \ EXC_VIRT_BEGIN(name, start, size); \ - STD_RELON_EXCEPTION(start, realvec, name##_common); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 area ; \ + EXCEPTION_PROLOG_1 EXC_STD, area, 0, realvec, 0; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ EXC_VIRT_END(name, start, size) +#define EXC_VIRT(name, start, size, realvec) \ + __EXC_VIRT(name, start, size, realvec, PACA_EXGEN) + #define EXC_REAL_MASKABLE(name, start, size, bitmask) \ EXC_REAL_BEGIN(name, start, size); \ - MASKABLE_EXCEPTION(start, name##_common, bitmask); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, start, bitmask ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ EXC_REAL_END(name, start, size) #define EXC_VIRT_MASKABLE(name, start, size, realvec, bitmask) \ EXC_VIRT_BEGIN(name, start, size); \ - MASKABLE_RELON_EXCEPTION(realvec, name##_common, bitmask); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ EXC_VIRT_END(name, start, size) #define EXC_REAL_HV(name, start, size) \ EXC_REAL_BEGIN(name, start, size); \ - STD_EXCEPTION_HV(start, start, name##_common); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 PACA_EXGEN; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, start, 0 ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 ; \ EXC_REAL_END(name, start, size) #define EXC_VIRT_HV(name, start, size, realvec) \ EXC_VIRT_BEGIN(name, start, size); \ - STD_RELON_EXCEPTION_HV(start, realvec, name##_common); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 PACA_EXGEN; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV ; \ EXC_VIRT_END(name, start, size) #define __EXC_REAL_OOL(name, start, size) \ EXC_REAL_BEGIN(name, start, size); \ - __OOL_EXCEPTION(start, label, tramp_real_##name); \ + SET_SCRATCH0(r13); \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + b tramp_real_##name ; \ EXC_REAL_END(name, start, size) #define __TRAMP_REAL_OOL(name, vec) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - STD_EXCEPTION_OOL(vec, name##_common) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0 ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 #define EXC_REAL_OOL(name, start, size) \ __EXC_REAL_OOL(name, start, size); \ @@ -306,7 +333,8 @@ name: #define __TRAMP_REAL_OOL_MASKABLE(name, vec, bitmask) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - MASKABLE_EXCEPTION_OOL(vec, name##_common, bitmask) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, bitmask ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 #define EXC_REAL_OOL_MASKABLE(name, start, size, bitmask) \ __EXC_REAL_OOL_MASKABLE(name, start, size); \ @@ -314,7 +342,9 @@ name: #define __EXC_REAL_OOL_HV_DIRECT(name, start, size, handler) \ EXC_REAL_BEGIN(name, start, size); \ - __OOL_EXCEPTION(start, label, handler); \ + SET_SCRATCH0(r13); \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + b handler; \ EXC_REAL_END(name, start, size) #define __EXC_REAL_OOL_HV(name, start, size) \ @@ -322,7 +352,8 @@ name: #define __TRAMP_REAL_OOL_HV(name, vec) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - STD_EXCEPTION_HV_OOL(vec, name##_common) + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0 ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 #define EXC_REAL_OOL_HV(name, start, size) \ __EXC_REAL_OOL_HV(name, start, size); \ @@ -333,7 +364,8 @@ name: #define __TRAMP_REAL_OOL_MASKABLE_HV(name, vec, bitmask) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - MASKABLE_EXCEPTION_HV_OOL(vec, name##_common, bitmask) + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 #define EXC_REAL_OOL_MASKABLE_HV(name, start, size, bitmask) \ __EXC_REAL_OOL_MASKABLE_HV(name, start, size); \ @@ -341,12 +373,15 @@ name: #define __EXC_VIRT_OOL(name, start, size) \ EXC_VIRT_BEGIN(name, start, size); \ - __OOL_EXCEPTION(start, label, tramp_virt_##name); \ + SET_SCRATCH0(r13); \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + b tramp_virt_##name; \ EXC_VIRT_END(name, start, size) #define __TRAMP_VIRT_OOL(name, realvec) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - STD_RELON_EXCEPTION_OOL(realvec, name##_common) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, 0 ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD #define EXC_VIRT_OOL(name, start, size, realvec) \ __EXC_VIRT_OOL(name, start, size); \ @@ -357,7 +392,8 @@ name: #define __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - MASKABLE_RELON_EXCEPTION_OOL(realvec, name##_common, bitmask) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 #define EXC_VIRT_OOL_MASKABLE(name, start, size, realvec, bitmask) \ __EXC_VIRT_OOL_MASKABLE(name, start, size); \ @@ -368,7 +404,8 @@ name: #define __TRAMP_VIRT_OOL_HV(name, realvec) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - STD_RELON_EXCEPTION_HV_OOL(realvec, name##_common) + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV #define EXC_VIRT_OOL_HV(name, start, size, realvec) \ __EXC_VIRT_OOL_HV(name, start, size); \ @@ -379,7 +416,8 @@ name: #define __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - MASKABLE_RELON_EXCEPTION_HV_OOL(realvec, name##_common, bitmask) + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, bitmask ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV #define EXC_VIRT_OOL_MASKABLE_HV(name, start, size, realvec, bitmask) \ __EXC_VIRT_OOL_MASKABLE_HV(name, start, size); \ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 2685c81e28f2..2774046e6cf4 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -254,9 +254,11 @@ EXC_COMMON_BEGIN(system_reset_common) */ TRAMP_REAL_BEGIN(system_reset_fwnmi) SET_SCRATCH0(r13) /* save r13 */ - /* See comment at system_reset exception */ - EXCEPTION_PROLOG_NORI(PACA_EXNMI, system_reset_common, EXC_STD, - 0, 0x100) + /* See comment at system_reset exception, don't turn on RI */ + EXCEPTION_PROLOG_0 PACA_EXNMI + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 0, 0x100, 0 + EXCEPTION_PROLOG_2_REAL system_reset_common, EXC_STD, 0 + #endif /* CONFIG_PPC_PSERIES */ @@ -714,14 +716,8 @@ MMU_FTR_SECTION_ELSE ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) -EXC_REAL_BEGIN(instruction_access_slb, 0x480, 0x80) -EXCEPTION_PROLOG(PACA_EXSLB, instruction_access_slb_common, EXC_STD, 1, 0x480); -EXC_REAL_END(instruction_access_slb, 0x480, 0x80) - -EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80) -EXCEPTION_RELON_PROLOG(PACA_EXSLB, instruction_access_slb_common, EXC_STD, 0, 0x480); -EXC_VIRT_END(instruction_access_slb, 0x4480, 0x80) - +__EXC_REAL(instruction_access_slb, 0x480, 0x80, PACA_EXSLB) +__EXC_VIRT(instruction_access_slb, 0x4480, 0x80, 0x480, PACA_EXSLB) TRAMP_KVM(PACA_EXSLB, 0x480) EXC_COMMON_BEGIN(instruction_access_slb_common) @@ -750,24 +746,34 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) EXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x100) - .globl hardware_interrupt_hv; + .globl hardware_interrupt_hv hardware_interrupt_hv: BEGIN_FTR_SECTION - MASKABLE_EXCEPTION_HV(0x500, hardware_interrupt_common, IRQS_DISABLED) + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_HV, 1 FTR_SECTION_ELSE - MASKABLE_EXCEPTION(0x500, hardware_interrupt_common, IRQS_DISABLED) + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_STD, 1 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) EXC_REAL_END(hardware_interrupt, 0x500, 0x100) EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100) - .globl hardware_interrupt_relon_hv; + .globl hardware_interrupt_relon_hv hardware_interrupt_relon_hv: BEGIN_FTR_SECTION - MASKABLE_RELON_EXCEPTION_HV(0x500, hardware_interrupt_common, - IRQS_DISABLED) + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_HV FTR_SECTION_ELSE - __MASKABLE_RELON_EXCEPTION(0x500, hardware_interrupt_common, - EXC_STD, 1, IRQS_DISABLED) + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_STD ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100) -- cgit v1.2.3 From 80bd9177def1ab92637e8cd27c2534b1224b12b5 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:23 +1000 Subject: powerpc/64s/exception: improve 0x500 handler code After the previous cleanup, it becomes possible to consolidate some common code outside the runtime alternate patching. Also remove unused labels. This results in some code change, but unchanged runtime instruction sequence. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 2774046e6cf4..6bf77070b1ba 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -746,32 +746,24 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) EXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x100) - .globl hardware_interrupt_hv -hardware_interrupt_hv: + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN BEGIN_FTR_SECTION - SET_SCRATCH0(r13) /* save r13 */ - EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_HV, 1 FTR_SECTION_ELSE - SET_SCRATCH0(r13) /* save r13 */ - EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_STD, 1 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) EXC_REAL_END(hardware_interrupt, 0x500, 0x100) EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100) - .globl hardware_interrupt_relon_hv -hardware_interrupt_relon_hv: + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN BEGIN_FTR_SECTION - SET_SCRATCH0(r13) /* save r13 */ - EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_HV FTR_SECTION_ELSE - SET_SCRATCH0(r13) /* save r13 */ - EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_STD ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) -- cgit v1.2.3 From f0ac44788e658e8afbe75644cd6d0c2d5993c933 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:24 +1000 Subject: powerpc/64s/exception: move EXCEPTION_PROLOG_2* to a more logical place No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 113 ++++++++++++++++--------------- 1 file changed, 57 insertions(+), 56 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 6efd182da254..f2552ea94090 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -174,62 +174,6 @@ ori reg,reg,(ABS_ADDR(label))@l; \ addis reg,reg,(ABS_ADDR(label))@h -.macro EXCEPTION_PROLOG_2_REAL label, hsrr, set_ri - ld r10,PACAKMSR(r13) /* get MSR value for kernel */ - .if ! \set_ri - xori r10,r10,MSR_RI /* Clear MSR_RI */ - .endif - .if \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - .endif - LOAD_HANDLER(r12, \label\()) - .if \hsrr - mtspr SPRN_HSRR0,r12 - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - mtspr SPRN_HSRR1,r10 - HRFI_TO_KERNEL - .else - mtspr SPRN_SRR0,r12 - mfspr r12,SPRN_SRR1 /* and SRR1 */ - mtspr SPRN_SRR1,r10 - RFI_TO_KERNEL - .endif - b . /* prevent speculative execution */ -.endm - -.macro EXCEPTION_PROLOG_2_VIRT label, hsrr -#ifdef CONFIG_RELOCATABLE - .if \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - .endif - LOAD_HANDLER(r12, \label\()) - mtctr r12 - .if \hsrr - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - .else - mfspr r12,SPRN_SRR1 /* and HSRR1 */ - .endif - li r10,MSR_RI - mtmsrd r10,1 /* Set RI (EE=0) */ - bctr -#else - .if \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - mfspr r12,SPRN_SRR1 /* and SRR1 */ - .endif - li r10,MSR_RI - mtmsrd r10,1 /* Set RI (EE=0) */ - b \label -#endif -.endm - /* Exception register prefixes */ #define EXC_HV 1 #define EXC_STD 0 @@ -340,6 +284,63 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) std r10,\area\()+EX_R13(r13) .endm +.macro EXCEPTION_PROLOG_2_REAL label, hsrr, set_ri + ld r10,PACAKMSR(r13) /* get MSR value for kernel */ + .if ! \set_ri + xori r10,r10,MSR_RI /* Clear MSR_RI */ + .endif + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + .endif + LOAD_HANDLER(r12, \label\()) + .if \hsrr + mtspr SPRN_HSRR0,r12 + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + mtspr SPRN_HSRR1,r10 + HRFI_TO_KERNEL + .else + mtspr SPRN_SRR0,r12 + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mtspr SPRN_SRR1,r10 + RFI_TO_KERNEL + .endif + b . /* prevent speculative execution */ +.endm + +.macro EXCEPTION_PROLOG_2_VIRT label, hsrr +#ifdef CONFIG_RELOCATABLE + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + .endif + LOAD_HANDLER(r12, \label\()) + mtctr r12 + .if \hsrr + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + .else + mfspr r12,SPRN_SRR1 /* and HSRR1 */ + .endif + li r10,MSR_RI + mtmsrd r10,1 /* Set RI (EE=0) */ + bctr +#else + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + mfspr r12,SPRN_SRR1 /* and SRR1 */ + .endif + li r10,MSR_RI + mtmsrd r10,1 /* Set RI (EE=0) */ + b \label +#endif +.endm + + #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* * If hv is possible, interrupts come into to the hv version -- cgit v1.2.3 From 6d18f29c33362bca2d28862d5b79f9b80e184ad3 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:25 +1000 Subject: powerpc/64s/exception: remove STD_EXCEPTION_COMMON variants These are only called in one place each. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 22 ---------------------- arch/powerpc/include/asm/head-64.h | 19 +++++++++++++++++-- 2 files changed, 17 insertions(+), 24 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index f2552ea94090..3117e9fe6b39 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -560,28 +560,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CTRL) EXCEPTION_PROLOG_COMMON_2(area); \ EXCEPTION_PROLOG_COMMON_3(trap) -#define STD_EXCEPTION_COMMON(trap, hdlr) \ - EXCEPTION_COMMON(PACA_EXGEN, trap); \ - bl save_nvgprs; \ - RECONCILE_IRQ_STATE(r10, r11); \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b ret_from_except - -/* - * Like STD_EXCEPTION_COMMON, but for exceptions that can occur - * in the idle task and therefore need the special idle handling - * (finish nap and runlatch) - */ -#define STD_EXCEPTION_COMMON_ASYNC(trap, hdlr) \ - EXCEPTION_COMMON(PACA_EXGEN, trap); \ - FINISH_NAP; \ - RECONCILE_IRQ_STATE(r10, r11); \ - RUNLATCH_ON; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b ret_from_except_lite - /* * When the idle code in power4_idle puts the CPU into NAP mode, * it has to do so in a loop, and relies on the external interrupt diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index 54db05afb80f..dc1940c94a86 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -441,11 +441,26 @@ name: #define EXC_COMMON(name, realvec, hdlr) \ EXC_COMMON_BEGIN(name); \ - STD_EXCEPTION_COMMON(realvec, hdlr) + EXCEPTION_COMMON(PACA_EXGEN, realvec); \ + bl save_nvgprs; \ + RECONCILE_IRQ_STATE(r10, r11); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b ret_from_except +/* + * Like EXC_COMMON, but for exceptions that can occur in the idle task and + * therefore need the special idle handling (finish nap and runlatch) + */ #define EXC_COMMON_ASYNC(name, realvec, hdlr) \ EXC_COMMON_BEGIN(name); \ - STD_EXCEPTION_COMMON_ASYNC(realvec, hdlr) + EXCEPTION_COMMON(PACA_EXGEN, realvec); \ + FINISH_NAP; \ + RECONCILE_IRQ_STATE(r10, r11); \ + RUNLATCH_ON; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b ret_from_except_lite #endif /* __ASSEMBLY__ */ -- cgit v1.2.3 From f1ff37e8f2d5e03a8ad60f23856a1b97ce4c6c2e Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:26 +1000 Subject: powerpc/64s/exception: move KVM related code together No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 40 +++++++++++++++++--------------- 1 file changed, 21 insertions(+), 19 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 3117e9fe6b39..a3b717e666d8 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -340,18 +340,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #endif .endm - -#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE -/* - * If hv is possible, interrupts come into to the hv version - * of the kvmppc_interrupt code, which then jumps to the PR handler, - * kvmppc_interrupt_pr, if the guest is a PR guest. - */ -#define kvmppc_interrupt kvmppc_interrupt_hv -#else -#define kvmppc_interrupt kvmppc_interrupt_pr -#endif - /* * Branch to label using its 0xC000 address. This results in instruction * address suitable for MSR[IR]=0 or 1, which allows relocation to be turned @@ -376,6 +364,17 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) mtctr r12; \ bctrl +#else +#define BRANCH_TO_COMMON(reg, label) \ + b label + +#define BRANCH_LINK_TO_FAR(label) \ + bl label +#endif + +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER + +#ifdef CONFIG_RELOCATABLE /* * KVM requires __LOAD_FAR_HANDLER. * @@ -392,19 +391,22 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) bctr #else -#define BRANCH_TO_COMMON(reg, label) \ - b label - -#define BRANCH_LINK_TO_FAR(label) \ - bl label - #define __BRANCH_TO_KVM_EXIT(area, label) \ ld r9,area+EX_R9(r13); \ b label +#endif +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +/* + * If hv is possible, interrupts come into to the hv version + * of the kvmppc_interrupt code, which then jumps to the PR handler, + * kvmppc_interrupt_pr, if the guest is a PR guest. + */ +#define kvmppc_interrupt kvmppc_interrupt_hv +#else +#define kvmppc_interrupt kvmppc_interrupt_pr #endif -#ifdef CONFIG_KVM_BOOK3S_64_HANDLER .macro KVMTEST hsrr, n lbz r10,HSTATE_IN_GUEST(r13) cmpwi r10,0 -- cgit v1.2.3 From 12a04809905913859106ffae93572cc312017dda Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:27 +1000 Subject: powerpc/64s/exception: move exception-64s.h code to exception-64s.S where it is used No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 431 ------------------------------- arch/powerpc/kernel/exceptions-64s.S | 431 +++++++++++++++++++++++++++++++ 2 files changed, 431 insertions(+), 431 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index a3b717e666d8..c28e2d2db926 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -150,437 +150,6 @@ hrfid; \ b hrfi_flush_fallback -/* - * We're short on space and time in the exception prolog, so we can't - * use the normal LOAD_REG_IMMEDIATE macro to load the address of label. - * Instead we get the base of the kernel from paca->kernelbase and or in the low - * part of label. This requires that the label be within 64KB of kernelbase, and - * that kernelbase be 64K aligned. - */ -#define LOAD_HANDLER(reg, label) \ - ld reg,PACAKBASE(r13); /* get high part of &label */ \ - ori reg,reg,FIXED_SYMBOL_ABS_ADDR(label) - -#define __LOAD_HANDLER(reg, label) \ - ld reg,PACAKBASE(r13); \ - ori reg,reg,(ABS_ADDR(label))@l - -/* - * Branches from unrelocated code (e.g., interrupts) to labels outside - * head-y require >64K offsets. - */ -#define __LOAD_FAR_HANDLER(reg, label) \ - ld reg,PACAKBASE(r13); \ - ori reg,reg,(ABS_ADDR(label))@l; \ - addis reg,reg,(ABS_ADDR(label))@h - -/* Exception register prefixes */ -#define EXC_HV 1 -#define EXC_STD 0 - -#if defined(CONFIG_RELOCATABLE) -/* - * If we support interrupts with relocation on AND we're a relocatable kernel, - * we need to use CTR to get to the 2nd level handler. So, save/restore it - * when required. - */ -#define SAVE_CTR(reg, area) mfctr reg ; std reg,area+EX_CTR(r13) -#define GET_CTR(reg, area) ld reg,area+EX_CTR(r13) -#define RESTORE_CTR(reg, area) ld reg,area+EX_CTR(r13) ; mtctr reg -#else -/* ...else CTR is unused and in register. */ -#define SAVE_CTR(reg, area) -#define GET_CTR(reg, area) mfctr reg -#define RESTORE_CTR(reg, area) -#endif - -/* - * PPR save/restore macros used in exceptions_64s.S - * Used for P7 or later processors - */ -#define SAVE_PPR(area, ra) \ -BEGIN_FTR_SECTION_NESTED(940) \ - ld ra,area+EX_PPR(r13); /* Read PPR from paca */ \ - std ra,_PPR(r1); \ -END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,940) - -#define RESTORE_PPR_PACA(area, ra) \ -BEGIN_FTR_SECTION_NESTED(941) \ - ld ra,area+EX_PPR(r13); \ - mtspr SPRN_PPR,ra; \ -END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941) - -/* - * Get an SPR into a register if the CPU has the given feature - */ -#define OPT_GET_SPR(ra, spr, ftr) \ -BEGIN_FTR_SECTION_NESTED(943) \ - mfspr ra,spr; \ -END_FTR_SECTION_NESTED(ftr,ftr,943) - -/* - * Set an SPR from a register if the CPU has the given feature - */ -#define OPT_SET_SPR(ra, spr, ftr) \ -BEGIN_FTR_SECTION_NESTED(943) \ - mtspr spr,ra; \ -END_FTR_SECTION_NESTED(ftr,ftr,943) - -/* - * Save a register to the PACA if the CPU has the given feature - */ -#define OPT_SAVE_REG_TO_PACA(offset, ra, ftr) \ -BEGIN_FTR_SECTION_NESTED(943) \ - std ra,offset(r13); \ -END_FTR_SECTION_NESTED(ftr,ftr,943) - -.macro EXCEPTION_PROLOG_0 area - GET_PACA(r13) - std r9,\area\()+EX_R9(r13) /* save r9 */ - OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR) - HMT_MEDIUM - std r10,\area\()+EX_R10(r13) /* save r10 - r12 */ - OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) -.endm - -.macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, bitmask - OPT_SAVE_REG_TO_PACA(\area\()+EX_PPR, r9, CPU_FTR_HAS_PPR) - OPT_SAVE_REG_TO_PACA(\area\()+EX_CFAR, r10, CPU_FTR_CFAR) - INTERRUPT_TO_KERNEL - SAVE_CTR(r10, \area\()) - mfcr r9 - .if \kvm - KVMTEST \hsrr \vec - .endif - - .if \bitmask - lbz r10,PACAIRQSOFTMASK(r13) - andi. r10,r10,\bitmask - /* Associate vector numbers with bits in paca->irq_happened */ - .if \vec == 0x500 || \vec == 0xea0 - li r10,PACA_IRQ_EE - .elseif \vec == 0x900 - li r10,PACA_IRQ_DEC - .elseif \vec == 0xa00 || \vec == 0xe80 - li r10,PACA_IRQ_DBELL - .elseif \vec == 0xe60 - li r10,PACA_IRQ_HMI - .elseif \vec == 0xf00 - li r10,PACA_IRQ_PMI - .else - .abort "Bad maskable vector" - .endif - - .if \hsrr - bne masked_Hinterrupt - .else - bne masked_interrupt - .endif - .endif - - std r11,\area\()+EX_R11(r13) - std r12,\area\()+EX_R12(r13) - GET_SCRATCH0(r10) - std r10,\area\()+EX_R13(r13) -.endm - -.macro EXCEPTION_PROLOG_2_REAL label, hsrr, set_ri - ld r10,PACAKMSR(r13) /* get MSR value for kernel */ - .if ! \set_ri - xori r10,r10,MSR_RI /* Clear MSR_RI */ - .endif - .if \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - .endif - LOAD_HANDLER(r12, \label\()) - .if \hsrr - mtspr SPRN_HSRR0,r12 - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - mtspr SPRN_HSRR1,r10 - HRFI_TO_KERNEL - .else - mtspr SPRN_SRR0,r12 - mfspr r12,SPRN_SRR1 /* and SRR1 */ - mtspr SPRN_SRR1,r10 - RFI_TO_KERNEL - .endif - b . /* prevent speculative execution */ -.endm - -.macro EXCEPTION_PROLOG_2_VIRT label, hsrr -#ifdef CONFIG_RELOCATABLE - .if \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - .endif - LOAD_HANDLER(r12, \label\()) - mtctr r12 - .if \hsrr - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - .else - mfspr r12,SPRN_SRR1 /* and HSRR1 */ - .endif - li r10,MSR_RI - mtmsrd r10,1 /* Set RI (EE=0) */ - bctr -#else - .if \hsrr - mfspr r11,SPRN_HSRR0 /* save HSRR0 */ - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - .else - mfspr r11,SPRN_SRR0 /* save SRR0 */ - mfspr r12,SPRN_SRR1 /* and SRR1 */ - .endif - li r10,MSR_RI - mtmsrd r10,1 /* Set RI (EE=0) */ - b \label -#endif -.endm - -/* - * Branch to label using its 0xC000 address. This results in instruction - * address suitable for MSR[IR]=0 or 1, which allows relocation to be turned - * on using mtmsr rather than rfid. - * - * This could set the 0xc bits for !RELOCATABLE as an immediate, rather than - * load KBASE for a slight optimisation. - */ -#define BRANCH_TO_C000(reg, label) \ - __LOAD_HANDLER(reg, label); \ - mtctr reg; \ - bctr - -#ifdef CONFIG_RELOCATABLE -#define BRANCH_TO_COMMON(reg, label) \ - __LOAD_HANDLER(reg, label); \ - mtctr reg; \ - bctr - -#define BRANCH_LINK_TO_FAR(label) \ - __LOAD_FAR_HANDLER(r12, label); \ - mtctr r12; \ - bctrl - -#else -#define BRANCH_TO_COMMON(reg, label) \ - b label - -#define BRANCH_LINK_TO_FAR(label) \ - bl label -#endif - -#ifdef CONFIG_KVM_BOOK3S_64_HANDLER - -#ifdef CONFIG_RELOCATABLE -/* - * KVM requires __LOAD_FAR_HANDLER. - * - * __BRANCH_TO_KVM_EXIT branches are also a special case because they - * explicitly use r9 then reload it from PACA before branching. Hence - * the double-underscore. - */ -#define __BRANCH_TO_KVM_EXIT(area, label) \ - mfctr r9; \ - std r9,HSTATE_SCRATCH1(r13); \ - __LOAD_FAR_HANDLER(r9, label); \ - mtctr r9; \ - ld r9,area+EX_R9(r13); \ - bctr - -#else -#define __BRANCH_TO_KVM_EXIT(area, label) \ - ld r9,area+EX_R9(r13); \ - b label -#endif - -#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE -/* - * If hv is possible, interrupts come into to the hv version - * of the kvmppc_interrupt code, which then jumps to the PR handler, - * kvmppc_interrupt_pr, if the guest is a PR guest. - */ -#define kvmppc_interrupt kvmppc_interrupt_hv -#else -#define kvmppc_interrupt kvmppc_interrupt_pr -#endif - -.macro KVMTEST hsrr, n - lbz r10,HSTATE_IN_GUEST(r13) - cmpwi r10,0 - .if \hsrr - bne do_kvm_H\n - .else - bne do_kvm_\n - .endif -.endm - -.macro KVM_HANDLER area, hsrr, n, skip - .if \skip - cmpwi r10,KVM_GUEST_MODE_SKIP - beq 89f - .else - BEGIN_FTR_SECTION_NESTED(947) - ld r10,\area+EX_CFAR(r13) - std r10,HSTATE_CFAR(r13) - END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947) - .endif - - BEGIN_FTR_SECTION_NESTED(948) - ld r10,\area+EX_PPR(r13) - std r10,HSTATE_PPR(r13) - END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) - ld r10,\area+EX_R10(r13) - std r12,HSTATE_SCRATCH0(r13) - sldi r12,r9,32 - /* HSRR variants have the 0x2 bit added to their trap number */ - .if \hsrr - ori r12,r12,(\n + 0x2) - .else - ori r12,r12,(\n) - .endif - /* This reloads r9 before branching to kvmppc_interrupt */ - __BRANCH_TO_KVM_EXIT(\area, kvmppc_interrupt) - - .if \skip -89: mtocrf 0x80,r9 - ld r9,\area+EX_R9(r13) - ld r10,\area+EX_R10(r13) - .if \hsrr - b kvmppc_skip_Hinterrupt - .else - b kvmppc_skip_interrupt - .endif - .endif -.endm - -#else -.macro KVMTEST hsrr, n -.endm -.macro KVM_HANDLER area, hsrr, n, skip -.endm -#endif - -#define EXCEPTION_PROLOG_COMMON_1() \ - std r9,_CCR(r1); /* save CR in stackframe */ \ - std r11,_NIP(r1); /* save SRR0 in stackframe */ \ - std r12,_MSR(r1); /* save SRR1 in stackframe */ \ - std r10,0(r1); /* make stack chain pointer */ \ - std r0,GPR0(r1); /* save r0 in stackframe */ \ - std r10,GPR1(r1); /* save r1 in stackframe */ \ - - -/* - * The common exception prolog is used for all except a few exceptions - * such as a segment miss on a kernel address. We have to be prepared - * to take another exception from the point where we first touch the - * kernel stack onwards. - * - * On entry r13 points to the paca, r9-r13 are saved in the paca, - * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and - * SRR1, and relocation is on. - */ -#define EXCEPTION_PROLOG_COMMON(n, area) \ - andi. r10,r12,MSR_PR; /* See if coming from user */ \ - mr r10,r1; /* Save r1 */ \ - subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ - beq- 1f; \ - ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ -1: cmpdi cr1,r1,-INT_FRAME_SIZE; /* check if r1 is in userspace */ \ - blt+ cr1,3f; /* abort if it is */ \ - li r1,(n); /* will be reloaded later */ \ - sth r1,PACA_TRAP_SAVE(r13); \ - std r3,area+EX_R3(r13); \ - addi r3,r13,area; /* r3 -> where regs are saved*/ \ - RESTORE_CTR(r1, area); \ - b bad_stack; \ -3: EXCEPTION_PROLOG_COMMON_1(); \ - kuap_save_amr_and_lock r9, r10, cr1, cr0; \ - beq 4f; /* if from kernel mode */ \ - ACCOUNT_CPU_USER_ENTRY(r13, r9, r10); \ - SAVE_PPR(area, r9); \ -4: EXCEPTION_PROLOG_COMMON_2(area) \ - EXCEPTION_PROLOG_COMMON_3(n) \ - ACCOUNT_STOLEN_TIME - -/* Save original regs values from save area to stack frame. */ -#define EXCEPTION_PROLOG_COMMON_2(area) \ - ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \ - ld r10,area+EX_R10(r13); \ - std r9,GPR9(r1); \ - std r10,GPR10(r1); \ - ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \ - ld r10,area+EX_R12(r13); \ - ld r11,area+EX_R13(r13); \ - std r9,GPR11(r1); \ - std r10,GPR12(r1); \ - std r11,GPR13(r1); \ - BEGIN_FTR_SECTION_NESTED(66); \ - ld r10,area+EX_CFAR(r13); \ - std r10,ORIG_GPR3(r1); \ - END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ - GET_CTR(r10, area); \ - std r10,_CTR(r1); - -#define EXCEPTION_PROLOG_COMMON_3(n) \ - std r2,GPR2(r1); /* save r2 in stackframe */ \ - SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ - SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ - mflr r9; /* Get LR, later save to stack */ \ - ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ - std r9,_LINK(r1); \ - lbz r10,PACAIRQSOFTMASK(r13); \ - mfspr r11,SPRN_XER; /* save XER in stackframe */ \ - std r10,SOFTE(r1); \ - std r11,_XER(r1); \ - li r9,(n)+1; \ - std r9,_TRAP(r1); /* set trap number */ \ - li r10,0; \ - ld r11,exception_marker@toc(r2); \ - std r10,RESULT(r1); /* clear regs->result */ \ - std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ - -#define RUNLATCH_ON \ -BEGIN_FTR_SECTION \ - ld r3, PACA_THREAD_INFO(r13); \ - ld r4,TI_LOCAL_FLAGS(r3); \ - andi. r0,r4,_TLF_RUNLATCH; \ - beql ppc64_runlatch_on_trampoline; \ -END_FTR_SECTION_IFSET(CPU_FTR_CTRL) - -#define EXCEPTION_COMMON(area, trap) \ - EXCEPTION_PROLOG_COMMON(trap, area); \ - -/* - * Exception where stack is already set in r1, r1 is saved in r10 - */ -#define EXCEPTION_COMMON_STACK(area, trap) \ - EXCEPTION_PROLOG_COMMON_1(); \ - kuap_save_amr_and_lock r9, r10, cr1; \ - EXCEPTION_PROLOG_COMMON_2(area); \ - EXCEPTION_PROLOG_COMMON_3(trap) - -/* - * When the idle code in power4_idle puts the CPU into NAP mode, - * it has to do so in a loop, and relies on the external interrupt - * and decrementer interrupt entry code to get it out of the loop. - * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags - * to signal that it is in the loop and needs help to get out. - */ -#ifdef CONFIG_PPC_970_NAP -#define FINISH_NAP \ -BEGIN_FTR_SECTION \ - ld r11, PACA_THREAD_INFO(r13); \ - ld r9,TI_LOCAL_FLAGS(r11); \ - andi. r10,r9,_TLF_NAPPING; \ - bnel power4_fixup_nap; \ -END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) -#else -#define FINISH_NAP -#endif - #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_EXCEPTION_H */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 6bf77070b1ba..785aaa3333a9 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -21,6 +21,437 @@ #include #include +/* + * We're short on space and time in the exception prolog, so we can't + * use the normal LOAD_REG_IMMEDIATE macro to load the address of label. + * Instead we get the base of the kernel from paca->kernelbase and or in the low + * part of label. This requires that the label be within 64KB of kernelbase, and + * that kernelbase be 64K aligned. + */ +#define LOAD_HANDLER(reg, label) \ + ld reg,PACAKBASE(r13); /* get high part of &label */ \ + ori reg,reg,FIXED_SYMBOL_ABS_ADDR(label) + +#define __LOAD_HANDLER(reg, label) \ + ld reg,PACAKBASE(r13); \ + ori reg,reg,(ABS_ADDR(label))@l + +/* + * Branches from unrelocated code (e.g., interrupts) to labels outside + * head-y require >64K offsets. + */ +#define __LOAD_FAR_HANDLER(reg, label) \ + ld reg,PACAKBASE(r13); \ + ori reg,reg,(ABS_ADDR(label))@l; \ + addis reg,reg,(ABS_ADDR(label))@h + +/* Exception register prefixes */ +#define EXC_HV 1 +#define EXC_STD 0 + +#if defined(CONFIG_RELOCATABLE) +/* + * If we support interrupts with relocation on AND we're a relocatable kernel, + * we need to use CTR to get to the 2nd level handler. So, save/restore it + * when required. + */ +#define SAVE_CTR(reg, area) mfctr reg ; std reg,area+EX_CTR(r13) +#define GET_CTR(reg, area) ld reg,area+EX_CTR(r13) +#define RESTORE_CTR(reg, area) ld reg,area+EX_CTR(r13) ; mtctr reg +#else +/* ...else CTR is unused and in register. */ +#define SAVE_CTR(reg, area) +#define GET_CTR(reg, area) mfctr reg +#define RESTORE_CTR(reg, area) +#endif + +/* + * PPR save/restore macros used in exceptions-64s.S + * Used for P7 or later processors + */ +#define SAVE_PPR(area, ra) \ +BEGIN_FTR_SECTION_NESTED(940) \ + ld ra,area+EX_PPR(r13); /* Read PPR from paca */ \ + std ra,_PPR(r1); \ +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,940) + +#define RESTORE_PPR_PACA(area, ra) \ +BEGIN_FTR_SECTION_NESTED(941) \ + ld ra,area+EX_PPR(r13); \ + mtspr SPRN_PPR,ra; \ +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,941) + +/* + * Get an SPR into a register if the CPU has the given feature + */ +#define OPT_GET_SPR(ra, spr, ftr) \ +BEGIN_FTR_SECTION_NESTED(943) \ + mfspr ra,spr; \ +END_FTR_SECTION_NESTED(ftr,ftr,943) + +/* + * Set an SPR from a register if the CPU has the given feature + */ +#define OPT_SET_SPR(ra, spr, ftr) \ +BEGIN_FTR_SECTION_NESTED(943) \ + mtspr spr,ra; \ +END_FTR_SECTION_NESTED(ftr,ftr,943) + +/* + * Save a register to the PACA if the CPU has the given feature + */ +#define OPT_SAVE_REG_TO_PACA(offset, ra, ftr) \ +BEGIN_FTR_SECTION_NESTED(943) \ + std ra,offset(r13); \ +END_FTR_SECTION_NESTED(ftr,ftr,943) + +.macro EXCEPTION_PROLOG_0 area + GET_PACA(r13) + std r9,\area\()+EX_R9(r13) /* save r9 */ + OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR) + HMT_MEDIUM + std r10,\area\()+EX_R10(r13) /* save r10 - r12 */ + OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) +.endm + +.macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, bitmask + OPT_SAVE_REG_TO_PACA(\area\()+EX_PPR, r9, CPU_FTR_HAS_PPR) + OPT_SAVE_REG_TO_PACA(\area\()+EX_CFAR, r10, CPU_FTR_CFAR) + INTERRUPT_TO_KERNEL + SAVE_CTR(r10, \area\()) + mfcr r9 + .if \kvm + KVMTEST \hsrr \vec + .endif + .if \bitmask + lbz r10,PACAIRQSOFTMASK(r13) + andi. r10,r10,\bitmask + /* Associate vector numbers with bits in paca->irq_happened */ + .if \vec == 0x500 || \vec == 0xea0 + li r10,PACA_IRQ_EE + .elseif \vec == 0x900 + li r10,PACA_IRQ_DEC + .elseif \vec == 0xa00 || \vec == 0xe80 + li r10,PACA_IRQ_DBELL + .elseif \vec == 0xe60 + li r10,PACA_IRQ_HMI + .elseif \vec == 0xf00 + li r10,PACA_IRQ_PMI + .else + .abort "Bad maskable vector" + .endif + + .if \hsrr + bne masked_Hinterrupt + .else + bne masked_interrupt + .endif + .endif + + std r11,\area\()+EX_R11(r13) + std r12,\area\()+EX_R12(r13) + GET_SCRATCH0(r10) + std r10,\area\()+EX_R13(r13) +.endm + +.macro EXCEPTION_PROLOG_2_REAL label, hsrr, set_ri + ld r10,PACAKMSR(r13) /* get MSR value for kernel */ + .if ! \set_ri + xori r10,r10,MSR_RI /* Clear MSR_RI */ + .endif + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + .endif + LOAD_HANDLER(r12, \label\()) + .if \hsrr + mtspr SPRN_HSRR0,r12 + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + mtspr SPRN_HSRR1,r10 + HRFI_TO_KERNEL + .else + mtspr SPRN_SRR0,r12 + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mtspr SPRN_SRR1,r10 + RFI_TO_KERNEL + .endif + b . /* prevent speculative execution */ +.endm + +.macro EXCEPTION_PROLOG_2_VIRT label, hsrr +#ifdef CONFIG_RELOCATABLE + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + .endif + LOAD_HANDLER(r12, \label\()) + mtctr r12 + .if \hsrr + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + .else + mfspr r12,SPRN_SRR1 /* and HSRR1 */ + .endif + li r10,MSR_RI + mtmsrd r10,1 /* Set RI (EE=0) */ + bctr +#else + .if \hsrr + mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + .else + mfspr r11,SPRN_SRR0 /* save SRR0 */ + mfspr r12,SPRN_SRR1 /* and SRR1 */ + .endif + li r10,MSR_RI + mtmsrd r10,1 /* Set RI (EE=0) */ + b \label +#endif +.endm + +/* + * Branch to label using its 0xC000 address. This results in instruction + * address suitable for MSR[IR]=0 or 1, which allows relocation to be turned + * on using mtmsr rather than rfid. + * + * This could set the 0xc bits for !RELOCATABLE as an immediate, rather than + * load KBASE for a slight optimisation. + */ +#define BRANCH_TO_C000(reg, label) \ + __LOAD_HANDLER(reg, label); \ + mtctr reg; \ + bctr + +#ifdef CONFIG_RELOCATABLE +#define BRANCH_TO_COMMON(reg, label) \ + __LOAD_HANDLER(reg, label); \ + mtctr reg; \ + bctr + +#define BRANCH_LINK_TO_FAR(label) \ + __LOAD_FAR_HANDLER(r12, label); \ + mtctr r12; \ + bctrl + +#else +#define BRANCH_TO_COMMON(reg, label) \ + b label + +#define BRANCH_LINK_TO_FAR(label) \ + bl label +#endif + +#ifdef CONFIG_KVM_BOOK3S_64_HANDLER + +#ifdef CONFIG_RELOCATABLE +/* + * KVM requires __LOAD_FAR_HANDLER. + * + * __BRANCH_TO_KVM_EXIT branches are also a special case because they + * explicitly use r9 then reload it from PACA before branching. Hence + * the double-underscore. + */ +#define __BRANCH_TO_KVM_EXIT(area, label) \ + mfctr r9; \ + std r9,HSTATE_SCRATCH1(r13); \ + __LOAD_FAR_HANDLER(r9, label); \ + mtctr r9; \ + ld r9,area+EX_R9(r13); \ + bctr + +#else +#define __BRANCH_TO_KVM_EXIT(area, label) \ + ld r9,area+EX_R9(r13); \ + b label +#endif + +#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE +/* + * If hv is possible, interrupts come into to the hv version + * of the kvmppc_interrupt code, which then jumps to the PR handler, + * kvmppc_interrupt_pr, if the guest is a PR guest. + */ +#define kvmppc_interrupt kvmppc_interrupt_hv +#else +#define kvmppc_interrupt kvmppc_interrupt_pr +#endif + +.macro KVMTEST hsrr, n + lbz r10,HSTATE_IN_GUEST(r13) + cmpwi r10,0 + .if \hsrr + bne do_kvm_H\n + .else + bne do_kvm_\n + .endif +.endm + +.macro KVM_HANDLER area, hsrr, n, skip + .if \skip + cmpwi r10,KVM_GUEST_MODE_SKIP + beq 89f + .else + BEGIN_FTR_SECTION_NESTED(947) + ld r10,\area+EX_CFAR(r13) + std r10,HSTATE_CFAR(r13) + END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947) + .endif + + BEGIN_FTR_SECTION_NESTED(948) + ld r10,\area+EX_PPR(r13) + std r10,HSTATE_PPR(r13) + END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) + ld r10,\area+EX_R10(r13) + std r12,HSTATE_SCRATCH0(r13) + sldi r12,r9,32 + /* HSRR variants have the 0x2 bit added to their trap number */ + .if \hsrr + ori r12,r12,(\n + 0x2) + .else + ori r12,r12,(\n) + .endif + /* This reloads r9 before branching to kvmppc_interrupt */ + __BRANCH_TO_KVM_EXIT(\area, kvmppc_interrupt) + + .if \skip +89: mtocrf 0x80,r9 + ld r9,\area+EX_R9(r13) + ld r10,\area+EX_R10(r13) + .if \hsrr + b kvmppc_skip_Hinterrupt + .else + b kvmppc_skip_interrupt + .endif + .endif +.endm + +#else +.macro KVMTEST hsrr, n +.endm +.macro KVM_HANDLER area, hsrr, n, skip +.endm +#endif + +#define EXCEPTION_PROLOG_COMMON_1() \ + std r9,_CCR(r1); /* save CR in stackframe */ \ + std r11,_NIP(r1); /* save SRR0 in stackframe */ \ + std r12,_MSR(r1); /* save SRR1 in stackframe */ \ + std r10,0(r1); /* make stack chain pointer */ \ + std r0,GPR0(r1); /* save r0 in stackframe */ \ + std r10,GPR1(r1); /* save r1 in stackframe */ \ + + +/* + * The common exception prolog is used for all except a few exceptions + * such as a segment miss on a kernel address. We have to be prepared + * to take another exception from the point where we first touch the + * kernel stack onwards. + * + * On entry r13 points to the paca, r9-r13 are saved in the paca, + * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and + * SRR1, and relocation is on. + */ +#define EXCEPTION_PROLOG_COMMON(n, area) \ + andi. r10,r12,MSR_PR; /* See if coming from user */ \ + mr r10,r1; /* Save r1 */ \ + subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ + beq- 1f; \ + ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ +1: cmpdi cr1,r1,-INT_FRAME_SIZE; /* check if r1 is in userspace */ \ + blt+ cr1,3f; /* abort if it is */ \ + li r1,(n); /* will be reloaded later */ \ + sth r1,PACA_TRAP_SAVE(r13); \ + std r3,area+EX_R3(r13); \ + addi r3,r13,area; /* r3 -> where regs are saved*/ \ + RESTORE_CTR(r1, area); \ + b bad_stack; \ +3: EXCEPTION_PROLOG_COMMON_1(); \ + kuap_save_amr_and_lock r9, r10, cr1, cr0; \ + beq 4f; /* if from kernel mode */ \ + ACCOUNT_CPU_USER_ENTRY(r13, r9, r10); \ + SAVE_PPR(area, r9); \ +4: EXCEPTION_PROLOG_COMMON_2(area) \ + EXCEPTION_PROLOG_COMMON_3(n) \ + ACCOUNT_STOLEN_TIME + +/* Save original regs values from save area to stack frame. */ +#define EXCEPTION_PROLOG_COMMON_2(area) \ + ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \ + ld r10,area+EX_R10(r13); \ + std r9,GPR9(r1); \ + std r10,GPR10(r1); \ + ld r9,area+EX_R11(r13); /* move r11 - r13 to stackframe */ \ + ld r10,area+EX_R12(r13); \ + ld r11,area+EX_R13(r13); \ + std r9,GPR11(r1); \ + std r10,GPR12(r1); \ + std r11,GPR13(r1); \ + BEGIN_FTR_SECTION_NESTED(66); \ + ld r10,area+EX_CFAR(r13); \ + std r10,ORIG_GPR3(r1); \ + END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ + GET_CTR(r10, area); \ + std r10,_CTR(r1); + +#define EXCEPTION_PROLOG_COMMON_3(n) \ + std r2,GPR2(r1); /* save r2 in stackframe */ \ + SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ + SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ + mflr r9; /* Get LR, later save to stack */ \ + ld r2,PACATOC(r13); /* get kernel TOC into r2 */ \ + std r9,_LINK(r1); \ + lbz r10,PACAIRQSOFTMASK(r13); \ + mfspr r11,SPRN_XER; /* save XER in stackframe */ \ + std r10,SOFTE(r1); \ + std r11,_XER(r1); \ + li r9,(n)+1; \ + std r9,_TRAP(r1); /* set trap number */ \ + li r10,0; \ + ld r11,exception_marker@toc(r2); \ + std r10,RESULT(r1); /* clear regs->result */ \ + std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ + +#define RUNLATCH_ON \ +BEGIN_FTR_SECTION \ + ld r3, PACA_THREAD_INFO(r13); \ + ld r4,TI_LOCAL_FLAGS(r3); \ + andi. r0,r4,_TLF_RUNLATCH; \ + beql ppc64_runlatch_on_trampoline; \ +END_FTR_SECTION_IFSET(CPU_FTR_CTRL) + +#define EXCEPTION_COMMON(area, trap) \ + EXCEPTION_PROLOG_COMMON(trap, area); \ + +/* + * Exception where stack is already set in r1, r1 is saved in r10 + */ +#define EXCEPTION_COMMON_STACK(area, trap) \ + EXCEPTION_PROLOG_COMMON_1(); \ + kuap_save_amr_and_lock r9, r10, cr1; \ + EXCEPTION_PROLOG_COMMON_2(area); \ + EXCEPTION_PROLOG_COMMON_3(trap) + +/* + * When the idle code in power4_idle puts the CPU into NAP mode, + * it has to do so in a loop, and relies on the external interrupt + * and decrementer interrupt entry code to get it out of the loop. + * It sets the _TLF_NAPPING bit in current_thread_info()->local_flags + * to signal that it is in the loop and needs help to get out. + */ +#ifdef CONFIG_PPC_970_NAP +#define FINISH_NAP \ +BEGIN_FTR_SECTION \ + ld r11, PACA_THREAD_INFO(r13); \ + ld r9,TI_LOCAL_FLAGS(r11); \ + andi. r10,r9,_TLF_NAPPING; \ + bnel power4_fixup_nap; \ +END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) +#else +#define FINISH_NAP +#endif + + /* * There are a few constraints to be concerned with. * - Real mode exceptions code/data must be located at their physical location. -- cgit v1.2.3 From a0502434bb02876d6c9b41d78a8db3a0b766f682 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:28 +1000 Subject: powerpc/64s/exception: move head-64.h code to exception-64s.S where it is used No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 1 - arch/powerpc/include/asm/head-64.h | 252 ------------------------------- arch/powerpc/kernel/exceptions-64s.S | 251 ++++++++++++++++++++++++++++++ 3 files changed, 251 insertions(+), 253 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index c28e2d2db926..3585e1d7e898 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -34,7 +34,6 @@ * exception handlers (including pSeries LPAR) and iSeries LPAR * implementations as possible. */ -#include #include /* PACA save area offsets (exgen, exmc, etc) */ diff --git a/arch/powerpc/include/asm/head-64.h b/arch/powerpc/include/asm/head-64.h index dc1940c94a86..a466765709a9 100644 --- a/arch/powerpc/include/asm/head-64.h +++ b/arch/powerpc/include/asm/head-64.h @@ -169,53 +169,6 @@ name: #define ABS_ADDR(label) (label - fs_label + fs_start) -/* - * Following are the BOOK3S exception handler helper macros. - * Handlers come in a number of types, and each type has a number of varieties. - * - * EXC_REAL_* - real, unrelocated exception vectors - * EXC_VIRT_* - virt (AIL), unrelocated exception vectors - * TRAMP_REAL_* - real, unrelocated helpers (virt can call these) - * TRAMP_VIRT_* - virt, unreloc helpers (in practice, real can use) - * TRAMP_KVM - KVM handlers that get put into real, unrelocated - * EXC_COMMON - virt, relocated common handlers - * - * The EXC handlers are given a name, and branch to name_common, or the - * appropriate KVM or masking function. Vector handler verieties are as - * follows: - * - * EXC_{REAL|VIRT}_BEGIN/END - used to open-code the exception - * - * EXC_{REAL|VIRT} - standard exception - * - * EXC_{REAL|VIRT}_suffix - * where _suffix is: - * - _MASKABLE - maskable exception - * - _OOL - out of line with trampoline to common handler - * - _HV - HV exception - * - * There can be combinations, e.g., EXC_VIRT_OOL_MASKABLE_HV - * - * The one unusual case is __EXC_REAL_OOL_HV_DIRECT, which is - * an OOL vector that branches to a specified handler rather than the usual - * trampoline that goes to common. It, and other underscore macros, should - * be used with care. - * - * KVM handlers come in the following verieties: - * TRAMP_KVM - * TRAMP_KVM_SKIP - * TRAMP_KVM_HV - * TRAMP_KVM_HV_SKIP - * - * COMMON handlers come in the following verieties: - * EXC_COMMON_BEGIN/END - used to open-code the handler - * EXC_COMMON - * EXC_COMMON_ASYNC - * - * TRAMP_REAL and TRAMP_VIRT can be used with BEGIN/END. KVM - * and OOL handlers are implemented as types of TRAMP and TRAMP_VIRT handlers. - */ - #define EXC_REAL_BEGIN(name, start, size) \ FIXED_SECTION_ENTRY_BEGIN_LOCATION(real_vectors, exc_real_##start##_##name, start, size) @@ -257,211 +210,6 @@ name: FIXED_SECTION_ENTRY_BEGIN_LOCATION(virt_vectors, exc_virt_##start##_##unused, start, size); \ FIXED_SECTION_ENTRY_END_LOCATION(virt_vectors, exc_virt_##start##_##unused, start, size) - -#define __EXC_REAL(name, start, size, area) \ - EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 area ; \ - EXCEPTION_PROLOG_1 EXC_STD, area, 1, start, 0 ; \ - EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ - EXC_REAL_END(name, start, size) - -#define EXC_REAL(name, start, size) \ - __EXC_REAL(name, start, size, PACA_EXGEN) - -#define __EXC_VIRT(name, start, size, realvec, area) \ - EXC_VIRT_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 area ; \ - EXCEPTION_PROLOG_1 EXC_STD, area, 0, realvec, 0; \ - EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ - EXC_VIRT_END(name, start, size) - -#define EXC_VIRT(name, start, size, realvec) \ - __EXC_VIRT(name, start, size, realvec, PACA_EXGEN) - -#define EXC_REAL_MASKABLE(name, start, size, bitmask) \ - EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, start, bitmask ; \ - EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ - EXC_REAL_END(name, start, size) - -#define EXC_VIRT_MASKABLE(name, start, size, realvec, bitmask) \ - EXC_VIRT_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ; \ - EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ - EXC_VIRT_END(name, start, size) - -#define EXC_REAL_HV(name, start, size) \ - EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 PACA_EXGEN; \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, start, 0 ; \ - EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 ; \ - EXC_REAL_END(name, start, size) - -#define EXC_VIRT_HV(name, start, size, realvec) \ - EXC_VIRT_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ - EXCEPTION_PROLOG_0 PACA_EXGEN; \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ; \ - EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV ; \ - EXC_VIRT_END(name, start, size) - -#define __EXC_REAL_OOL(name, start, size) \ - EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); \ - EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - b tramp_real_##name ; \ - EXC_REAL_END(name, start, size) - -#define __TRAMP_REAL_OOL(name, vec) \ - TRAMP_REAL_BEGIN(tramp_real_##name); \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0 ; \ - EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 - -#define EXC_REAL_OOL(name, start, size) \ - __EXC_REAL_OOL(name, start, size); \ - __TRAMP_REAL_OOL(name, start) - -#define __EXC_REAL_OOL_MASKABLE(name, start, size) \ - __EXC_REAL_OOL(name, start, size) - -#define __TRAMP_REAL_OOL_MASKABLE(name, vec, bitmask) \ - TRAMP_REAL_BEGIN(tramp_real_##name); \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, bitmask ; \ - EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 - -#define EXC_REAL_OOL_MASKABLE(name, start, size, bitmask) \ - __EXC_REAL_OOL_MASKABLE(name, start, size); \ - __TRAMP_REAL_OOL_MASKABLE(name, start, bitmask) - -#define __EXC_REAL_OOL_HV_DIRECT(name, start, size, handler) \ - EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); \ - EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - b handler; \ - EXC_REAL_END(name, start, size) - -#define __EXC_REAL_OOL_HV(name, start, size) \ - __EXC_REAL_OOL(name, start, size) - -#define __TRAMP_REAL_OOL_HV(name, vec) \ - TRAMP_REAL_BEGIN(tramp_real_##name); \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0 ; \ - EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 - -#define EXC_REAL_OOL_HV(name, start, size) \ - __EXC_REAL_OOL_HV(name, start, size); \ - __TRAMP_REAL_OOL_HV(name, start) - -#define __EXC_REAL_OOL_MASKABLE_HV(name, start, size) \ - __EXC_REAL_OOL(name, start, size) - -#define __TRAMP_REAL_OOL_MASKABLE_HV(name, vec, bitmask) \ - TRAMP_REAL_BEGIN(tramp_real_##name); \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ - EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 - -#define EXC_REAL_OOL_MASKABLE_HV(name, start, size, bitmask) \ - __EXC_REAL_OOL_MASKABLE_HV(name, start, size); \ - __TRAMP_REAL_OOL_MASKABLE_HV(name, start, bitmask) - -#define __EXC_VIRT_OOL(name, start, size) \ - EXC_VIRT_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); \ - EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - b tramp_virt_##name; \ - EXC_VIRT_END(name, start, size) - -#define __TRAMP_VIRT_OOL(name, realvec) \ - TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, 0 ; \ - EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD - -#define EXC_VIRT_OOL(name, start, size, realvec) \ - __EXC_VIRT_OOL(name, start, size); \ - __TRAMP_VIRT_OOL(name, realvec) - -#define __EXC_VIRT_OOL_MASKABLE(name, start, size) \ - __EXC_VIRT_OOL(name, start, size) - -#define __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask) \ - TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ; \ - EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 - -#define EXC_VIRT_OOL_MASKABLE(name, start, size, realvec, bitmask) \ - __EXC_VIRT_OOL_MASKABLE(name, start, size); \ - __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask) - -#define __EXC_VIRT_OOL_HV(name, start, size) \ - __EXC_VIRT_OOL(name, start, size) - -#define __TRAMP_VIRT_OOL_HV(name, realvec) \ - TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ; \ - EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV - -#define EXC_VIRT_OOL_HV(name, start, size, realvec) \ - __EXC_VIRT_OOL_HV(name, start, size); \ - __TRAMP_VIRT_OOL_HV(name, realvec) - -#define __EXC_VIRT_OOL_MASKABLE_HV(name, start, size) \ - __EXC_VIRT_OOL(name, start, size) - -#define __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask) \ - TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, bitmask ; \ - EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV - -#define EXC_VIRT_OOL_MASKABLE_HV(name, start, size, realvec, bitmask) \ - __EXC_VIRT_OOL_MASKABLE_HV(name, start, size); \ - __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask) - -#define TRAMP_KVM(area, n) \ - TRAMP_KVM_BEGIN(do_kvm_##n); \ - KVM_HANDLER area, EXC_STD, n, 0 - -#define TRAMP_KVM_SKIP(area, n) \ - TRAMP_KVM_BEGIN(do_kvm_##n); \ - KVM_HANDLER area, EXC_STD, n, 1 - -#define TRAMP_KVM_HV(area, n) \ - TRAMP_KVM_BEGIN(do_kvm_H##n); \ - KVM_HANDLER area, EXC_HV, n, 0 - -#define TRAMP_KVM_HV_SKIP(area, n) \ - TRAMP_KVM_BEGIN(do_kvm_H##n); \ - KVM_HANDLER area, EXC_HV, n, 1 - -#define EXC_COMMON(name, realvec, hdlr) \ - EXC_COMMON_BEGIN(name); \ - EXCEPTION_COMMON(PACA_EXGEN, realvec); \ - bl save_nvgprs; \ - RECONCILE_IRQ_STATE(r10, r11); \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b ret_from_except - -/* - * Like EXC_COMMON, but for exceptions that can occur in the idle task and - * therefore need the special idle handling (finish nap and runlatch) - */ -#define EXC_COMMON_ASYNC(name, realvec, hdlr) \ - EXC_COMMON_BEGIN(name); \ - EXCEPTION_COMMON(PACA_EXGEN, realvec); \ - FINISH_NAP; \ - RECONCILE_IRQ_STATE(r10, r11); \ - RUNLATCH_ON; \ - addi r3,r1,STACK_FRAME_OVERHEAD; \ - bl hdlr; \ - b ret_from_except_lite - #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_HEAD_64_H */ diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 785aaa3333a9..ba2ecbd06c72 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -451,6 +451,257 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define FINISH_NAP #endif +/* + * Following are the BOOK3S exception handler helper macros. + * Handlers come in a number of types, and each type has a number of varieties. + * + * EXC_REAL_* - real, unrelocated exception vectors + * EXC_VIRT_* - virt (AIL), unrelocated exception vectors + * TRAMP_REAL_* - real, unrelocated helpers (virt can call these) + * TRAMP_VIRT_* - virt, unreloc helpers (in practice, real can use) + * TRAMP_KVM - KVM handlers that get put into real, unrelocated + * EXC_COMMON - virt, relocated common handlers + * + * The EXC handlers are given a name, and branch to name_common, or the + * appropriate KVM or masking function. Vector handler verieties are as + * follows: + * + * EXC_{REAL|VIRT}_BEGIN/END - used to open-code the exception + * + * EXC_{REAL|VIRT} - standard exception + * + * EXC_{REAL|VIRT}_suffix + * where _suffix is: + * - _MASKABLE - maskable exception + * - _OOL - out of line with trampoline to common handler + * - _HV - HV exception + * + * There can be combinations, e.g., EXC_VIRT_OOL_MASKABLE_HV + * + * The one unusual case is __EXC_REAL_OOL_HV_DIRECT, which is + * an OOL vector that branches to a specified handler rather than the usual + * trampoline that goes to common. It, and other underscore macros, should + * be used with care. + * + * KVM handlers come in the following verieties: + * TRAMP_KVM + * TRAMP_KVM_SKIP + * TRAMP_KVM_HV + * TRAMP_KVM_HV_SKIP + * + * COMMON handlers come in the following verieties: + * EXC_COMMON_BEGIN/END - used to open-code the handler + * EXC_COMMON + * EXC_COMMON_ASYNC + * + * TRAMP_REAL and TRAMP_VIRT can be used with BEGIN/END. KVM + * and OOL handlers are implemented as types of TRAMP and TRAMP_VIRT handlers. + */ + +#define __EXC_REAL(name, start, size, area) \ + EXC_REAL_BEGIN(name, start, size); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 area ; \ + EXCEPTION_PROLOG_1 EXC_STD, area, 1, start, 0 ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ + EXC_REAL_END(name, start, size) + +#define EXC_REAL(name, start, size) \ + __EXC_REAL(name, start, size, PACA_EXGEN) + +#define __EXC_VIRT(name, start, size, realvec, area) \ + EXC_VIRT_BEGIN(name, start, size); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 area ; \ + EXCEPTION_PROLOG_1 EXC_STD, area, 0, realvec, 0; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ + EXC_VIRT_END(name, start, size) + +#define EXC_VIRT(name, start, size, realvec) \ + __EXC_VIRT(name, start, size, realvec, PACA_EXGEN) + +#define EXC_REAL_MASKABLE(name, start, size, bitmask) \ + EXC_REAL_BEGIN(name, start, size); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, start, bitmask ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ + EXC_REAL_END(name, start, size) + +#define EXC_VIRT_MASKABLE(name, start, size, realvec, bitmask) \ + EXC_VIRT_BEGIN(name, start, size); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ + EXC_VIRT_END(name, start, size) + +#define EXC_REAL_HV(name, start, size) \ + EXC_REAL_BEGIN(name, start, size); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 PACA_EXGEN; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, start, 0 ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 ; \ + EXC_REAL_END(name, start, size) + +#define EXC_VIRT_HV(name, start, size, realvec) \ + EXC_VIRT_BEGIN(name, start, size); \ + SET_SCRATCH0(r13); /* save r13 */ \ + EXCEPTION_PROLOG_0 PACA_EXGEN; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV ; \ + EXC_VIRT_END(name, start, size) + +#define __EXC_REAL_OOL(name, start, size) \ + EXC_REAL_BEGIN(name, start, size); \ + SET_SCRATCH0(r13); \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + b tramp_real_##name ; \ + EXC_REAL_END(name, start, size) + +#define __TRAMP_REAL_OOL(name, vec) \ + TRAMP_REAL_BEGIN(tramp_real_##name); \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0 ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 + +#define EXC_REAL_OOL(name, start, size) \ + __EXC_REAL_OOL(name, start, size); \ + __TRAMP_REAL_OOL(name, start) + +#define __EXC_REAL_OOL_MASKABLE(name, start, size) \ + __EXC_REAL_OOL(name, start, size) + +#define __TRAMP_REAL_OOL_MASKABLE(name, vec, bitmask) \ + TRAMP_REAL_BEGIN(tramp_real_##name); \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, bitmask ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 + +#define EXC_REAL_OOL_MASKABLE(name, start, size, bitmask) \ + __EXC_REAL_OOL_MASKABLE(name, start, size); \ + __TRAMP_REAL_OOL_MASKABLE(name, start, bitmask) + +#define __EXC_REAL_OOL_HV_DIRECT(name, start, size, handler) \ + EXC_REAL_BEGIN(name, start, size); \ + SET_SCRATCH0(r13); \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + b handler; \ + EXC_REAL_END(name, start, size) + +#define __EXC_REAL_OOL_HV(name, start, size) \ + __EXC_REAL_OOL(name, start, size) + +#define __TRAMP_REAL_OOL_HV(name, vec) \ + TRAMP_REAL_BEGIN(tramp_real_##name); \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0 ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 + +#define EXC_REAL_OOL_HV(name, start, size) \ + __EXC_REAL_OOL_HV(name, start, size); \ + __TRAMP_REAL_OOL_HV(name, start) + +#define __EXC_REAL_OOL_MASKABLE_HV(name, start, size) \ + __EXC_REAL_OOL(name, start, size) + +#define __TRAMP_REAL_OOL_MASKABLE_HV(name, vec, bitmask) \ + TRAMP_REAL_BEGIN(tramp_real_##name); \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 + +#define EXC_REAL_OOL_MASKABLE_HV(name, start, size, bitmask) \ + __EXC_REAL_OOL_MASKABLE_HV(name, start, size); \ + __TRAMP_REAL_OOL_MASKABLE_HV(name, start, bitmask) + +#define __EXC_VIRT_OOL(name, start, size) \ + EXC_VIRT_BEGIN(name, start, size); \ + SET_SCRATCH0(r13); \ + EXCEPTION_PROLOG_0 PACA_EXGEN ; \ + b tramp_virt_##name; \ + EXC_VIRT_END(name, start, size) + +#define __TRAMP_VIRT_OOL(name, realvec) \ + TRAMP_VIRT_BEGIN(tramp_virt_##name); \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, 0 ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD + +#define EXC_VIRT_OOL(name, start, size, realvec) \ + __EXC_VIRT_OOL(name, start, size); \ + __TRAMP_VIRT_OOL(name, realvec) + +#define __EXC_VIRT_OOL_MASKABLE(name, start, size) \ + __EXC_VIRT_OOL(name, start, size) + +#define __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask) \ + TRAMP_VIRT_BEGIN(tramp_virt_##name); \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ; \ + EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 + +#define EXC_VIRT_OOL_MASKABLE(name, start, size, realvec, bitmask) \ + __EXC_VIRT_OOL_MASKABLE(name, start, size); \ + __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask) + +#define __EXC_VIRT_OOL_HV(name, start, size) \ + __EXC_VIRT_OOL(name, start, size) + +#define __TRAMP_VIRT_OOL_HV(name, realvec) \ + TRAMP_VIRT_BEGIN(tramp_virt_##name); \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV + +#define EXC_VIRT_OOL_HV(name, start, size, realvec) \ + __EXC_VIRT_OOL_HV(name, start, size); \ + __TRAMP_VIRT_OOL_HV(name, realvec) + +#define __EXC_VIRT_OOL_MASKABLE_HV(name, start, size) \ + __EXC_VIRT_OOL(name, start, size) + +#define __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask) \ + TRAMP_VIRT_BEGIN(tramp_virt_##name); \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, bitmask ; \ + EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV + +#define EXC_VIRT_OOL_MASKABLE_HV(name, start, size, realvec, bitmask) \ + __EXC_VIRT_OOL_MASKABLE_HV(name, start, size); \ + __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask) + +#define TRAMP_KVM(area, n) \ + TRAMP_KVM_BEGIN(do_kvm_##n); \ + KVM_HANDLER area, EXC_STD, n, 0 + +#define TRAMP_KVM_SKIP(area, n) \ + TRAMP_KVM_BEGIN(do_kvm_##n); \ + KVM_HANDLER area, EXC_STD, n, 1 + +#define TRAMP_KVM_HV(area, n) \ + TRAMP_KVM_BEGIN(do_kvm_H##n); \ + KVM_HANDLER area, EXC_HV, n, 0 + +#define TRAMP_KVM_HV_SKIP(area, n) \ + TRAMP_KVM_BEGIN(do_kvm_H##n); \ + KVM_HANDLER area, EXC_HV, n, 1 + +#define EXC_COMMON(name, realvec, hdlr) \ + EXC_COMMON_BEGIN(name); \ + EXCEPTION_COMMON(PACA_EXGEN, realvec); \ + bl save_nvgprs; \ + RECONCILE_IRQ_STATE(r10, r11); \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b ret_from_except + +/* + * Like EXC_COMMON, but for exceptions that can occur in the idle task and + * therefore need the special idle handling (finish nap and runlatch) + */ +#define EXC_COMMON_ASYNC(name, realvec, hdlr) \ + EXC_COMMON_BEGIN(name); \ + EXCEPTION_COMMON(PACA_EXGEN, realvec); \ + FINISH_NAP; \ + RECONCILE_IRQ_STATE(r10, r11); \ + RUNLATCH_ON; \ + addi r3,r1,STACK_FRAME_OVERHEAD; \ + bl hdlr; \ + b ret_from_except_lite + /* * There are a few constraints to be concerned with. -- cgit v1.2.3 From 64e413515ce1e731b87f704cf0d8d9768f0bd8c8 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:29 +1000 Subject: powerpc/64s/exception: remove __BRANCH_TO_KVM No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 43 +++++++++++++++--------------------- 1 file changed, 18 insertions(+), 25 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index ba2ecbd06c72..c354bb9606b8 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -243,29 +243,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) #endif #ifdef CONFIG_KVM_BOOK3S_64_HANDLER - -#ifdef CONFIG_RELOCATABLE -/* - * KVM requires __LOAD_FAR_HANDLER. - * - * __BRANCH_TO_KVM_EXIT branches are also a special case because they - * explicitly use r9 then reload it from PACA before branching. Hence - * the double-underscore. - */ -#define __BRANCH_TO_KVM_EXIT(area, label) \ - mfctr r9; \ - std r9,HSTATE_SCRATCH1(r13); \ - __LOAD_FAR_HANDLER(r9, label); \ - mtctr r9; \ - ld r9,area+EX_R9(r13); \ - bctr - -#else -#define __BRANCH_TO_KVM_EXIT(area, label) \ - ld r9,area+EX_R9(r13); \ - b label -#endif - #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* * If hv is possible, interrupts come into to the hv version @@ -311,8 +288,24 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) .else ori r12,r12,(\n) .endif - /* This reloads r9 before branching to kvmppc_interrupt */ - __BRANCH_TO_KVM_EXIT(\area, kvmppc_interrupt) + +#ifdef CONFIG_RELOCATABLE + /* + * KVM requires __LOAD_FAR_HANDLER beause kvmppc_interrupt lives + * outside the head section. CONFIG_RELOCATABLE KVM expects CTR + * to be saved in HSTATE_SCRATCH1. + */ + mfctr r9 + std r9,HSTATE_SCRATCH1(r13) + __LOAD_FAR_HANDLER(r9, kvmppc_interrupt) + mtctr r9 + ld r9,\area+EX_R9(r13) + bctr +#else + ld r9,\area+EX_R9(r13) + b kvmppc_interrupt +#endif + .if \skip 89: mtocrf 0x80,r9 -- cgit v1.2.3 From f945478d5c689ccdab8bf3ee47f27085c2836690 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:30 +1000 Subject: powerpc/64s/exception: remove unused BRANCH_TO_COMMON Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 8 -------- 1 file changed, 8 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index c354bb9606b8..7d062d3f6f54 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -224,20 +224,12 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) bctr #ifdef CONFIG_RELOCATABLE -#define BRANCH_TO_COMMON(reg, label) \ - __LOAD_HANDLER(reg, label); \ - mtctr reg; \ - bctr - #define BRANCH_LINK_TO_FAR(label) \ __LOAD_FAR_HANDLER(r12, label); \ mtctr r12; \ bctrl #else -#define BRANCH_TO_COMMON(reg, label) \ - b label - #define BRANCH_LINK_TO_FAR(label) \ bl label #endif -- cgit v1.2.3 From 1b4d4a7933a7afc6ea8e973b7aba84abdfb2fd0b Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:31 +1000 Subject: powerpc/64s/exception: use a gas macro for system call handler code No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 127 +++++++++++++++-------------------- 1 file changed, 55 insertions(+), 72 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 7d062d3f6f54..73ba2e3f345b 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1607,6 +1607,7 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception) * without saving, though xer is not a good idea to use, as hardware may * interpret some bits so it may be costly to change them. */ +.macro SYSTEM_CALL virt #ifdef CONFIG_KVM_BOOK3S_64_HANDLER /* * There is a little bit of juggling to get syscall and hcall @@ -1616,95 +1617,77 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception) * Userspace syscalls have already saved the PPR, hcalls must save * it before setting HMT_MEDIUM. */ -#define SYSCALL_KVMTEST \ - mtctr r13; \ - GET_PACA(r13); \ - std r10,PACA_EXGEN+EX_R10(r13); \ - INTERRUPT_TO_KERNEL; \ - KVMTEST EXC_STD 0xc00 ; /* uses r10, branch to do_kvm_0xc00_system_call */ \ - HMT_MEDIUM; \ - mfctr r9; - + mtctr r13 + GET_PACA(r13) + std r10,PACA_EXGEN+EX_R10(r13) + INTERRUPT_TO_KERNEL + KVMTEST EXC_STD 0xc00 /* uses r10, branch to do_kvm_0xc00_system_call */ + HMT_MEDIUM + mfctr r9 #else -#define SYSCALL_KVMTEST \ - HMT_MEDIUM; \ - mr r9,r13; \ - GET_PACA(r13); \ - INTERRUPT_TO_KERNEL; + HMT_MEDIUM + mr r9,r13 + GET_PACA(r13) + INTERRUPT_TO_KERNEL #endif - -#define LOAD_SYSCALL_HANDLER(reg) \ - __LOAD_HANDLER(reg, system_call_common) - -/* - * After SYSCALL_KVMTEST, we reach here with PACA in r13, r13 in r9, - * and HMT_MEDIUM. - */ -#define SYSCALL_REAL \ - mfspr r11,SPRN_SRR0 ; \ - mfspr r12,SPRN_SRR1 ; \ - LOAD_SYSCALL_HANDLER(r10) ; \ - mtspr SPRN_SRR0,r10 ; \ - ld r10,PACAKMSR(r13) ; \ - mtspr SPRN_SRR1,r10 ; \ - RFI_TO_KERNEL ; \ - b . ; /* prevent speculative execution */ #ifdef CONFIG_PPC_FAST_ENDIAN_SWITCH -#define SYSCALL_FASTENDIAN_TEST \ -BEGIN_FTR_SECTION \ - cmpdi r0,0x1ebe ; \ - beq- 1f ; \ -END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) \ - -#define SYSCALL_FASTENDIAN \ - /* Fast LE/BE switch system call */ \ -1: mfspr r12,SPRN_SRR1 ; \ - xori r12,r12,MSR_LE ; \ - mtspr SPRN_SRR1,r12 ; \ - mr r13,r9 ; \ - RFI_TO_USER ; /* return to userspace */ \ - b . ; /* prevent speculative execution */ -#else -#define SYSCALL_FASTENDIAN_TEST -#define SYSCALL_FASTENDIAN -#endif /* CONFIG_PPC_FAST_ENDIAN_SWITCH */ +BEGIN_FTR_SECTION + cmpdi r0,0x1ebe + beq- 1f +END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) +#endif + /* We reach here with PACA in r13, r13 in r9, and HMT_MEDIUM. */ -#if defined(CONFIG_RELOCATABLE) + .if ! \virt + mfspr r11,SPRN_SRR0 + mfspr r12,SPRN_SRR1 + __LOAD_HANDLER(r10, system_call_common) + mtspr SPRN_SRR0,r10 + ld r10,PACAKMSR(r13) + mtspr SPRN_SRR1,r10 + RFI_TO_KERNEL + b . /* prevent speculative execution */ + .else +#ifdef CONFIG_RELOCATABLE /* * We can't branch directly so we do it via the CTR which * is volatile across system calls. */ -#define SYSCALL_VIRT \ - LOAD_SYSCALL_HANDLER(r10) ; \ - mtctr r10 ; \ - mfspr r11,SPRN_SRR0 ; \ - mfspr r12,SPRN_SRR1 ; \ - li r10,MSR_RI ; \ - mtmsrd r10,1 ; \ - bctr ; + __LOAD_HANDLER(r10, system_call_common) + mtctr r10 + mfspr r11,SPRN_SRR0 + mfspr r12,SPRN_SRR1 + li r10,MSR_RI + mtmsrd r10,1 + bctr #else /* We can branch directly */ -#define SYSCALL_VIRT \ - mfspr r11,SPRN_SRR0 ; \ - mfspr r12,SPRN_SRR1 ; \ - li r10,MSR_RI ; \ - mtmsrd r10,1 ; /* Set RI (EE=0) */ \ - b system_call_common ; + mfspr r11,SPRN_SRR0 + mfspr r12,SPRN_SRR1 + li r10,MSR_RI + mtmsrd r10,1 /* Set RI (EE=0) */ + b system_call_common +#endif + .endif + +#ifdef CONFIG_PPC_FAST_ENDIAN_SWITCH + /* Fast LE/BE switch system call */ +1: mfspr r12,SPRN_SRR1 + xori r12,r12,MSR_LE + mtspr SPRN_SRR1,r12 + mr r13,r9 + RFI_TO_USER /* return to userspace */ + b . /* prevent speculative execution */ #endif +.endm EXC_REAL_BEGIN(system_call, 0xc00, 0x100) - SYSCALL_KVMTEST /* loads PACA into r13, and saves r13 to r9 */ - SYSCALL_FASTENDIAN_TEST - SYSCALL_REAL - SYSCALL_FASTENDIAN + SYSTEM_CALL 0 EXC_REAL_END(system_call, 0xc00, 0x100) EXC_VIRT_BEGIN(system_call, 0x4c00, 0x100) - SYSCALL_KVMTEST /* loads PACA into r13, and saves r13 to r9 */ - SYSCALL_FASTENDIAN_TEST - SYSCALL_VIRT - SYSCALL_FASTENDIAN + SYSTEM_CALL 1 EXC_VIRT_END(system_call, 0x4c00, 0x100) #ifdef CONFIG_KVM_BOOK3S_64_HANDLER -- cgit v1.2.3 From bf66e3c4cf00bc00cdd2df90f63161eacf9c5714 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:32 +1000 Subject: powerpc/64s/exception: fix indenting irregularities Generally, macros that result in instructions being expanded are indented by a tab, and those that don't have no indent. Fix the obvious cases that go contrary to style. No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 92 ++++++++++++++++++------------------ 1 file changed, 46 insertions(+), 46 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 73ba2e3f345b..fcc88b5446c9 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -261,16 +261,16 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) cmpwi r10,KVM_GUEST_MODE_SKIP beq 89f .else - BEGIN_FTR_SECTION_NESTED(947) +BEGIN_FTR_SECTION_NESTED(947) ld r10,\area+EX_CFAR(r13) std r10,HSTATE_CFAR(r13) - END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947) +END_FTR_SECTION_NESTED(CPU_FTR_CFAR,CPU_FTR_CFAR,947) .endif - BEGIN_FTR_SECTION_NESTED(948) +BEGIN_FTR_SECTION_NESTED(948) ld r10,\area+EX_PPR(r13) std r10,HSTATE_PPR(r13) - END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) +END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) ld r10,\area+EX_R10(r13) std r12,HSTATE_SCRATCH0(r13) sldi r12,r9,32 @@ -372,10 +372,10 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) std r9,GPR11(r1); \ std r10,GPR12(r1); \ std r11,GPR13(r1); \ - BEGIN_FTR_SECTION_NESTED(66); \ +BEGIN_FTR_SECTION_NESTED(66); \ ld r10,area+EX_CFAR(r13); \ std r10,ORIG_GPR3(r1); \ - END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ +END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ GET_CTR(r10, area); \ std r10,_CTR(r1); @@ -794,7 +794,7 @@ EXC_REAL_BEGIN(system_reset, 0x100, 0x100) * but we branch to the 0xc000... address so we can turn on relocation * with mtmsr. */ - BEGIN_FTR_SECTION +BEGIN_FTR_SECTION mfspr r10,SPRN_SRR1 rlwinm. r10,r10,47-31,30,31 beq- 1f @@ -803,7 +803,7 @@ EXC_REAL_BEGIN(system_reset, 0x100, 0x100) bltlr cr1 /* no state loss, return to idle caller */ BRANCH_TO_C000(r10, system_reset_idle_common) 1: - END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) +END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) #endif KVMTEST EXC_STD 0x100 @@ -1151,10 +1151,10 @@ END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) * * Go back to nap/sleep/winkle mode again if (b) is true. */ - BEGIN_FTR_SECTION +BEGIN_FTR_SECTION rlwinm. r11,r12,47-31,30,31 bne machine_check_idle_common - END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) +END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) #endif /* @@ -1261,13 +1261,13 @@ EXC_COMMON_BEGIN(mce_return) b . EXC_REAL_BEGIN(data_access, 0x300, 0x80) -SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0 PACA_EXGEN + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN b tramp_real_data_access EXC_REAL_END(data_access, 0x300, 0x80) TRAMP_REAL_BEGIN(tramp_real_data_access) -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300, 0 + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300, 0 /* * DAR/DSISR must be read before setting MSR[RI], because * a d-side MCE will clobber those registers so is not @@ -1280,9 +1280,9 @@ EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300, 0 EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) -SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0 PACA_EXGEN -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300, 0 + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300, 0 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) @@ -1315,24 +1315,24 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80) -SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0 PACA_EXSLB + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXSLB b tramp_real_data_access_slb EXC_REAL_END(data_access_slb, 0x380, 0x80) TRAMP_REAL_BEGIN(tramp_real_data_access_slb) -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 1, 0x380, 0 + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 1, 0x380, 0 mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) -EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 + EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) -SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0 PACA_EXSLB -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380, 0 + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXSLB + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380, 0 mfspr r10,SPRN_DAR std r10,PACA_EXSLB+EX_DAR(r13) -EXCEPTION_PROLOG_2_VIRT data_access_slb_common, EXC_STD + EXCEPTION_PROLOG_2_VIRT data_access_slb_common, EXC_STD EXC_VIRT_END(data_access_slb, 0x4380, 0x80) TRAMP_KVM_SKIP(PACA_EXSLB, 0x380) @@ -1415,25 +1415,25 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) EXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN - BEGIN_FTR_SECTION - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED - EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_HV, 1 - FTR_SECTION_ELSE - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED - EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_STD, 1 - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) +BEGIN_FTR_SECTION + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_HV, 1 +FTR_SECTION_ELSE + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_STD, 1 +ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) EXC_REAL_END(hardware_interrupt, 0x500, 0x100) EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN - BEGIN_FTR_SECTION - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED - EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_HV - FTR_SECTION_ELSE - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED - EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_STD - ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) +BEGIN_FTR_SECTION + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_HV +FTR_SECTION_ELSE + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_STD +ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100) TRAMP_KVM(PACA_EXGEN, 0x500) @@ -1442,25 +1442,25 @@ EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ) EXC_REAL_BEGIN(alignment, 0x600, 0x100) -SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0 PACA_EXGEN -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600, 0 + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600, 0 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2_REAL alignment_common, EXC_STD, 1 + EXCEPTION_PROLOG_2_REAL alignment_common, EXC_STD, 1 EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) -SET_SCRATCH0(r13) /* save r13 */ -EXCEPTION_PROLOG_0 PACA_EXGEN -EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600, 0 + SET_SCRATCH0(r13) /* save r13 */ + EXCEPTION_PROLOG_0 PACA_EXGEN + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600, 0 mfspr r10,SPRN_DAR mfspr r11,SPRN_DSISR std r10,PACA_EXGEN+EX_DAR(r13) stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2_VIRT alignment_common, EXC_STD + EXCEPTION_PROLOG_2_VIRT alignment_common, EXC_STD EXC_VIRT_END(alignment, 0x4600, 0x100) TRAMP_KVM(PACA_EXGEN, 0x600) -- cgit v1.2.3 From f3c8b6c63e816e4770abf073ee004e63593b5260 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:33 +1000 Subject: powerpc/64s/exception: generate regs clear instructions using .rept No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index fcc88b5446c9..7de4b61bde37 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -2010,12 +2010,11 @@ BEGIN_FTR_SECTION mtmsrd r10 sync -#define FMR2(n) fmr (n), (n) ; fmr n+1, n+1 -#define FMR4(n) FMR2(n) ; FMR2(n+2) -#define FMR8(n) FMR4(n) ; FMR4(n+4) -#define FMR16(n) FMR8(n) ; FMR8(n+8) -#define FMR32(n) FMR16(n) ; FMR16(n+16) - FMR32(0) + .Lreg=0 + .rept 32 + fmr .Lreg,.Lreg + .Lreg=.Lreg+1 + .endr FTR_SECTION_ELSE /* @@ -2027,12 +2026,11 @@ FTR_SECTION_ELSE mtmsrd r10 sync -#define XVCPSGNDP2(n) XVCPSGNDP(n,n,n) ; XVCPSGNDP(n+1,n+1,n+1) -#define XVCPSGNDP4(n) XVCPSGNDP2(n) ; XVCPSGNDP2(n+2) -#define XVCPSGNDP8(n) XVCPSGNDP4(n) ; XVCPSGNDP4(n+4) -#define XVCPSGNDP16(n) XVCPSGNDP8(n) ; XVCPSGNDP8(n+8) -#define XVCPSGNDP32(n) XVCPSGNDP16(n) ; XVCPSGNDP16(n+16) - XVCPSGNDP32(0) + .Lreg=0 + .rept 32 + XVCPSGNDP(.Lreg,.Lreg,.Lreg) + .Lreg=.Lreg+1 + .endr ALT_FTR_SECTION_END_IFCLR(CPU_FTR_ARCH_206) @@ -2043,7 +2041,12 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S) * To denormalise we need to move a copy of the register to itself. * For POWER8 we need to do that for all 64 VSX registers */ - XVCPSGNDP32(32) + .Lreg=32 + .rept 32 + XVCPSGNDP(.Lreg,.Lreg,.Lreg) + .Lreg=.Lreg+1 + .endr + denorm_done: mfspr r11,SPRN_HSRR0 subi r11,r11,4 -- cgit v1.2.3 From d064151fd33b1b0ebeb732ae978cb3587e934ff9 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:34 +1000 Subject: powerpc/64s/exception: remove pointless EXCEPTION_PROLOG macro indirection No generated code change. Final vmlinux is changed only due to change in bug table line numbers. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 108 +++++++++++++++++------------------ 1 file changed, 51 insertions(+), 57 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 7de4b61bde37..9b60fa040aa6 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -326,40 +326,6 @@ END_FTR_SECTION_NESTED(CPU_FTR_HAS_PPR,CPU_FTR_HAS_PPR,948) std r0,GPR0(r1); /* save r0 in stackframe */ \ std r10,GPR1(r1); /* save r1 in stackframe */ \ - -/* - * The common exception prolog is used for all except a few exceptions - * such as a segment miss on a kernel address. We have to be prepared - * to take another exception from the point where we first touch the - * kernel stack onwards. - * - * On entry r13 points to the paca, r9-r13 are saved in the paca, - * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and - * SRR1, and relocation is on. - */ -#define EXCEPTION_PROLOG_COMMON(n, area) \ - andi. r10,r12,MSR_PR; /* See if coming from user */ \ - mr r10,r1; /* Save r1 */ \ - subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ - beq- 1f; \ - ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ -1: cmpdi cr1,r1,-INT_FRAME_SIZE; /* check if r1 is in userspace */ \ - blt+ cr1,3f; /* abort if it is */ \ - li r1,(n); /* will be reloaded later */ \ - sth r1,PACA_TRAP_SAVE(r13); \ - std r3,area+EX_R3(r13); \ - addi r3,r13,area; /* r3 -> where regs are saved*/ \ - RESTORE_CTR(r1, area); \ - b bad_stack; \ -3: EXCEPTION_PROLOG_COMMON_1(); \ - kuap_save_amr_and_lock r9, r10, cr1, cr0; \ - beq 4f; /* if from kernel mode */ \ - ACCOUNT_CPU_USER_ENTRY(r13, r9, r10); \ - SAVE_PPR(area, r9); \ -4: EXCEPTION_PROLOG_COMMON_2(area) \ - EXCEPTION_PROLOG_COMMON_3(n) \ - ACCOUNT_STOLEN_TIME - /* Save original regs values from save area to stack frame. */ #define EXCEPTION_PROLOG_COMMON_2(area) \ ld r9,area+EX_R9(r13); /* move r9, r10 to stackframe */ \ @@ -379,7 +345,7 @@ END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ GET_CTR(r10, area); \ std r10,_CTR(r1); -#define EXCEPTION_PROLOG_COMMON_3(n) \ +#define EXCEPTION_PROLOG_COMMON_3(trap) \ std r2,GPR2(r1); /* save r2 in stackframe */ \ SAVE_4GPRS(3, r1); /* save r3 - r6 in stackframe */ \ SAVE_2GPRS(7, r1); /* save r7, r8 in stackframe */ \ @@ -390,26 +356,45 @@ END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ mfspr r11,SPRN_XER; /* save XER in stackframe */ \ std r10,SOFTE(r1); \ std r11,_XER(r1); \ - li r9,(n)+1; \ + li r9,(trap)+1; \ std r9,_TRAP(r1); /* set trap number */ \ li r10,0; \ ld r11,exception_marker@toc(r2); \ std r10,RESULT(r1); /* clear regs->result */ \ std r11,STACK_FRAME_OVERHEAD-16(r1); /* mark the frame */ -#define RUNLATCH_ON \ -BEGIN_FTR_SECTION \ - ld r3, PACA_THREAD_INFO(r13); \ - ld r4,TI_LOCAL_FLAGS(r3); \ - andi. r0,r4,_TLF_RUNLATCH; \ - beql ppc64_runlatch_on_trampoline; \ -END_FTR_SECTION_IFSET(CPU_FTR_CTRL) +/* + * On entry r13 points to the paca, r9-r13 are saved in the paca, + * r9 contains the saved CR, r11 and r12 contain the saved SRR0 and + * SRR1, and relocation is on. + */ +#define EXCEPTION_COMMON(area, trap) \ + andi. r10,r12,MSR_PR; /* See if coming from user */ \ + mr r10,r1; /* Save r1 */ \ + subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ + beq- 1f; \ + ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ +1: cmpdi cr1,r1,-INT_FRAME_SIZE; /* check if r1 is in userspace */ \ + blt+ cr1,3f; /* abort if it is */ \ + li r1,(trap); /* will be reloaded later */ \ + sth r1,PACA_TRAP_SAVE(r13); \ + std r3,area+EX_R3(r13); \ + addi r3,r13,area; /* r3 -> where regs are saved*/ \ + RESTORE_CTR(r1, area); \ + b bad_stack; \ +3: EXCEPTION_PROLOG_COMMON_1(); \ + kuap_save_amr_and_lock r9, r10, cr1, cr0; \ + beq 4f; /* if from kernel mode */ \ + ACCOUNT_CPU_USER_ENTRY(r13, r9, r10); \ + SAVE_PPR(area, r9); \ +4: EXCEPTION_PROLOG_COMMON_2(area); \ + EXCEPTION_PROLOG_COMMON_3(trap); \ + ACCOUNT_STOLEN_TIME -#define EXCEPTION_COMMON(area, trap) \ - EXCEPTION_PROLOG_COMMON(trap, area); \ /* - * Exception where stack is already set in r1, r1 is saved in r10 + * Exception where stack is already set in r1, r1 is saved in r10. + * PPR save and CPU accounting is not done (for some reason). */ #define EXCEPTION_COMMON_STACK(area, trap) \ EXCEPTION_PROLOG_COMMON_1(); \ @@ -417,6 +402,15 @@ END_FTR_SECTION_IFSET(CPU_FTR_CTRL) EXCEPTION_PROLOG_COMMON_2(area); \ EXCEPTION_PROLOG_COMMON_3(trap) + +#define RUNLATCH_ON \ +BEGIN_FTR_SECTION \ + ld r3, PACA_THREAD_INFO(r13); \ + ld r4,TI_LOCAL_FLAGS(r3); \ + andi. r0,r4,_TLF_RUNLATCH; \ + beql ppc64_runlatch_on_trampoline; \ +END_FTR_SECTION_IFSET(CPU_FTR_CTRL) + /* * When the idle code in power4_idle puts the CPU into NAP mode, * it has to do so in a loop, and relies on the external interrupt @@ -1048,7 +1042,7 @@ EXC_COMMON_BEGIN(machine_check_common) std r10,PACA_EXMC+EX_DAR(r13) mfspr r10,SPRN_DSISR stw r10,PACA_EXMC+EX_DSISR(r13) - EXCEPTION_PROLOG_COMMON(0x200, PACA_EXMC) + EXCEPTION_COMMON(PACA_EXMC, 0x200) FINISH_NAP RECONCILE_IRQ_STATE(r10, r11) ld r3,PACA_EXMC+EX_DAR(r13) @@ -1299,7 +1293,7 @@ EXC_COMMON_BEGIN(data_access_common) * r9 - r13 are saved in paca->exgen. * EX_DAR and EX_DSISR have saved DAR/DSISR */ - EXCEPTION_PROLOG_COMMON(0x300, PACA_EXGEN) + EXCEPTION_COMMON(PACA_EXGEN, 0x300) RECONCILE_IRQ_STATE(r10, r11) ld r12,_MSR(r1) ld r3,PACA_EXGEN+EX_DAR(r13) @@ -1338,7 +1332,7 @@ EXC_VIRT_END(data_access_slb, 0x4380, 0x80) TRAMP_KVM_SKIP(PACA_EXSLB, 0x380) EXC_COMMON_BEGIN(data_access_slb_common) - EXCEPTION_PROLOG_COMMON(0x380, PACA_EXSLB) + EXCEPTION_COMMON(PACA_EXSLB, 0x380) ld r4,PACA_EXSLB+EX_DAR(r13) std r4,_DAR(r1) addi r3,r1,STACK_FRAME_OVERHEAD @@ -1368,7 +1362,7 @@ EXC_VIRT(instruction_access, 0x4400, 0x80, 0x400) TRAMP_KVM(PACA_EXGEN, 0x400) EXC_COMMON_BEGIN(instruction_access_common) - EXCEPTION_PROLOG_COMMON(0x400, PACA_EXGEN) + EXCEPTION_COMMON(PACA_EXGEN, 0x400) RECONCILE_IRQ_STATE(r10, r11) ld r12,_MSR(r1) ld r3,_NIP(r1) @@ -1388,7 +1382,7 @@ __EXC_VIRT(instruction_access_slb, 0x4480, 0x80, 0x480, PACA_EXSLB) TRAMP_KVM(PACA_EXSLB, 0x480) EXC_COMMON_BEGIN(instruction_access_slb_common) - EXCEPTION_PROLOG_COMMON(0x480, PACA_EXSLB) + EXCEPTION_COMMON(PACA_EXSLB, 0x480) ld r4,_NIP(r1) addi r3,r1,STACK_FRAME_OVERHEAD BEGIN_MMU_FTR_SECTION @@ -1465,7 +1459,7 @@ EXC_VIRT_END(alignment, 0x4600, 0x100) TRAMP_KVM(PACA_EXGEN, 0x600) EXC_COMMON_BEGIN(alignment_common) - EXCEPTION_PROLOG_COMMON(0x600, PACA_EXGEN) + EXCEPTION_COMMON(PACA_EXGEN, 0x600) ld r3,PACA_EXGEN+EX_DAR(r13) lwz r4,PACA_EXGEN+EX_DSISR(r13) std r3,_DAR(r1) @@ -1503,7 +1497,7 @@ EXC_COMMON_BEGIN(program_check_common) ld r1,PACAEMERGSP(r13) /* Use emergency stack */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ b 3f /* Jump into the macro !! */ -1: EXCEPTION_PROLOG_COMMON(0x700, PACA_EXGEN) +1: EXCEPTION_COMMON(PACA_EXGEN, 0x700) bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD @@ -1515,7 +1509,7 @@ EXC_REAL(fp_unavailable, 0x800, 0x100) EXC_VIRT(fp_unavailable, 0x4800, 0x100, 0x800) TRAMP_KVM(PACA_EXGEN, 0x800) EXC_COMMON_BEGIN(fp_unavailable_common) - EXCEPTION_PROLOG_COMMON(0x800, PACA_EXGEN) + EXCEPTION_COMMON(PACA_EXGEN, 0x800) bne 1f /* if from user, just load it up */ bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) @@ -1728,7 +1722,7 @@ EXC_COMMON_BEGIN(h_data_storage_common) std r10,PACA_EXGEN+EX_DAR(r13) mfspr r10,SPRN_HDSISR stw r10,PACA_EXGEN+EX_DSISR(r13) - EXCEPTION_PROLOG_COMMON(0xe00, PACA_EXGEN) + EXCEPTION_COMMON(PACA_EXGEN, 0xe00) bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD @@ -1860,7 +1854,7 @@ EXC_REAL_OOL(altivec_unavailable, 0xf20, 0x20) EXC_VIRT_OOL(altivec_unavailable, 0x4f20, 0x20, 0xf20) TRAMP_KVM(PACA_EXGEN, 0xf20) EXC_COMMON_BEGIN(altivec_unavailable_common) - EXCEPTION_PROLOG_COMMON(0xf20, PACA_EXGEN) + EXCEPTION_COMMON(PACA_EXGEN, 0xf20) #ifdef CONFIG_ALTIVEC BEGIN_FTR_SECTION beq 1f @@ -1897,7 +1891,7 @@ EXC_REAL_OOL(vsx_unavailable, 0xf40, 0x20) EXC_VIRT_OOL(vsx_unavailable, 0x4f40, 0x20, 0xf40) TRAMP_KVM(PACA_EXGEN, 0xf40) EXC_COMMON_BEGIN(vsx_unavailable_common) - EXCEPTION_PROLOG_COMMON(0xf40, PACA_EXGEN) + EXCEPTION_COMMON(PACA_EXGEN, 0xf40) #ifdef CONFIG_VSX BEGIN_FTR_SECTION beq 1f -- cgit v1.2.3 From 1582009113bc1336d4e54de1d94014ca3569c483 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sat, 22 Jun 2019 23:15:35 +1000 Subject: powerpc/64s/exception: move paca save area offsets into exception-64s.S No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 17 +++-------------- arch/powerpc/kernel/exceptions-64s.S | 22 ++++++++++++++++++++++ 2 files changed, 25 insertions(+), 14 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 3585e1d7e898..40d114e69cbe 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -36,22 +36,11 @@ */ #include -/* PACA save area offsets (exgen, exmc, etc) */ -#define EX_R9 0 -#define EX_R10 8 -#define EX_R11 16 -#define EX_R12 24 -#define EX_R13 32 -#define EX_DAR 40 -#define EX_DSISR 48 -#define EX_CCR 52 -#define EX_CFAR 56 -#define EX_PPR 64 +/* PACA save area size in u64 units (exgen, exmc, etc) */ #if defined(CONFIG_RELOCATABLE) -#define EX_CTR 72 -#define EX_SIZE 10 /* size in u64 units */ +#define EX_SIZE 10 #else -#define EX_SIZE 9 /* size in u64 units */ +#define EX_SIZE 9 #endif /* diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 9b60fa040aa6..4dfccc2efc95 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -21,6 +21,28 @@ #include #include +/* PACA save area offsets (exgen, exmc, etc) */ +#define EX_R9 0 +#define EX_R10 8 +#define EX_R11 16 +#define EX_R12 24 +#define EX_R13 32 +#define EX_DAR 40 +#define EX_DSISR 48 +#define EX_CCR 52 +#define EX_CFAR 56 +#define EX_PPR 64 +#if defined(CONFIG_RELOCATABLE) +#define EX_CTR 72 +.if EX_SIZE != 10 + .error "EX_SIZE is wrong" +.endif +#else +.if EX_SIZE != 9 + .error "EX_SIZE is wrong" +.endif +#endif + /* * We're short on space and time in the exception prolog, so we can't * use the normal LOAD_REG_IMMEDIATE macro to load the address of label. -- cgit v1.2.3 From b0b2a93da4c95ac808c4c43f24a1873ae3166a1a Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:20 +1000 Subject: powerpc/64s/exception: clean up system call entry syscall / hcall entry unnecessarily differs between KVM and non-KVM builds. Move the SMT priority instruction to the same location (after INTERRUPT_TO_KERNEL). Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 24 +++++++----------------- 1 file changed, 7 insertions(+), 17 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 4dfccc2efc95..564a77039701 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1638,10 +1638,8 @@ EXC_COMMON(trap_0b_common, 0xb00, unknown_exception) std r10,PACA_EXGEN+EX_R10(r13) INTERRUPT_TO_KERNEL KVMTEST EXC_STD 0xc00 /* uses r10, branch to do_kvm_0xc00_system_call */ - HMT_MEDIUM mfctr r9 #else - HMT_MEDIUM mr r9,r13 GET_PACA(r13) INTERRUPT_TO_KERNEL @@ -1653,11 +1651,14 @@ BEGIN_FTR_SECTION beq- 1f END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) #endif - /* We reach here with PACA in r13, r13 in r9, and HMT_MEDIUM. */ - .if ! \virt + /* We reach here with PACA in r13, r13 in r9. */ mfspr r11,SPRN_SRR0 mfspr r12,SPRN_SRR1 + + HMT_MEDIUM + + .if ! \virt __LOAD_HANDLER(r10, system_call_common) mtspr SPRN_SRR0,r10 ld r10,PACAKMSR(r13) @@ -1665,24 +1666,13 @@ END_FTR_SECTION_IFSET(CPU_FTR_REAL_LE) RFI_TO_KERNEL b . /* prevent speculative execution */ .else + li r10,MSR_RI + mtmsrd r10,1 /* Set RI (EE=0) */ #ifdef CONFIG_RELOCATABLE - /* - * We can't branch directly so we do it via the CTR which - * is volatile across system calls. - */ __LOAD_HANDLER(r10, system_call_common) mtctr r10 - mfspr r11,SPRN_SRR0 - mfspr r12,SPRN_SRR1 - li r10,MSR_RI - mtmsrd r10,1 bctr #else - /* We can branch directly */ - mfspr r11,SPRN_SRR0 - mfspr r12,SPRN_SRR1 - li r10,MSR_RI - mtmsrd r10,1 /* Set RI (EE=0) */ b system_call_common #endif .endif -- cgit v1.2.3 From 63d60d0c6946fd6874a099540e0ac9e26661f8dd Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:21 +1000 Subject: powerpc/64s/exception: avoid SPR RAW scoreboard stall in real mode entry Move SPR reads ahead of writes. Real mode entry that is not a KVM guest is rare these days, but bad practice propagates. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 564a77039701..3735b9d1bb65 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -183,19 +183,19 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) .endif .if \hsrr mfspr r11,SPRN_HSRR0 /* save HSRR0 */ + mfspr r12,SPRN_HSRR1 /* and HSRR1 */ + mtspr SPRN_HSRR1,r10 .else mfspr r11,SPRN_SRR0 /* save SRR0 */ + mfspr r12,SPRN_SRR1 /* and SRR1 */ + mtspr SPRN_SRR1,r10 .endif - LOAD_HANDLER(r12, \label\()) + LOAD_HANDLER(r10, \label\()) .if \hsrr - mtspr SPRN_HSRR0,r12 - mfspr r12,SPRN_HSRR1 /* and HSRR1 */ - mtspr SPRN_HSRR1,r10 + mtspr SPRN_HSRR0,r10 HRFI_TO_KERNEL .else - mtspr SPRN_SRR0,r12 - mfspr r12,SPRN_SRR1 /* and SRR1 */ - mtspr SPRN_SRR1,r10 + mtspr SPRN_SRR0,r10 RFI_TO_KERNEL .endif b . /* prevent speculative execution */ -- cgit v1.2.3 From fbc50063a2358f685deaa2f8370a55e3df5ef3ab Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:22 +1000 Subject: powerpc/64s/exception: mtmsrd L=1 cleanup All supported 64s CPUs support mtmsrd L=1 instruction, so a cleanup can be made in sreset and mce handlers. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 3735b9d1bb65..33c253fe8a68 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -882,11 +882,8 @@ EXC_COMMON_BEGIN(system_reset_common) addi r3,r1,STACK_FRAME_OVERHEAD bl system_reset_exception - /* This (and MCE) can be simplified with mtmsrd L=1 */ /* Clear MSR_RI before setting SRR0 and SRR1. */ - li r0,MSR_RI - mfmsr r9 - andc r9,r9,r0 + li r9,0 mtmsrd r9,1 /* @@ -1081,9 +1078,7 @@ EXC_COMMON_BEGIN(machine_check_common) #define MACHINE_CHECK_HANDLER_WINDUP \ /* Clear MSR_RI before setting SRR0 and SRR1. */\ - li r0,MSR_RI; \ - mfmsr r9; /* get MSR value */ \ - andc r9,r9,r0; \ + li r9,0; \ mtmsrd r9,1; /* Clear MSR_RI */ \ /* Move original SRR0 and SRR1 into the respective regs */ \ ld r9,_MSR(r1); \ -- cgit v1.2.3 From 9592b29a9cf14db596c752349e7d5b7a29d3bf90 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:23 +1000 Subject: powerpc/64s/exception: windup use r9 consistently to restore SPRs Trivial code change, r3->r9. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 33c253fe8a68..823e930b6e3e 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -909,8 +909,8 @@ EXC_COMMON_BEGIN(system_reset_common) /* Move original SRR0 and SRR1 into the respective regs */ ld r9,_MSR(r1) mtspr SPRN_SRR1,r9 - ld r3,_NIP(r1) - mtspr SPRN_SRR0,r3 + ld r9,_NIP(r1) + mtspr SPRN_SRR0,r9 ld r9,_CTR(r1) mtctr r9 ld r9,_XER(r1) @@ -1083,8 +1083,8 @@ EXC_COMMON_BEGIN(machine_check_common) /* Move original SRR0 and SRR1 into the respective regs */ \ ld r9,_MSR(r1); \ mtspr SPRN_SRR1,r9; \ - ld r3,_NIP(r1); \ - mtspr SPRN_SRR0,r3; \ + ld r9,_NIP(r1); \ + mtspr SPRN_SRR0,r9; \ ld r9,_CTR(r1); \ mtctr r9; \ ld r9,_XER(r1); \ @@ -1786,8 +1786,8 @@ TRAMP_REAL_BEGIN(hmi_exception_early) /* Move original HSRR0 and HSRR1 into the respective regs */ ld r9,_MSR(r1) mtspr SPRN_HSRR1,r9 - ld r3,_NIP(r1) - mtspr SPRN_HSRR0,r3 + ld r9,_NIP(r1) + mtspr SPRN_HSRR0,r9 ld r9,_CTR(r1) mtctr r9 ld r9,_XER(r1) -- cgit v1.2.3 From ad73d8d4f4a7994b234020fc6484c87672b0c404 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:24 +1000 Subject: powerpc/64s/exception: move machine check windup in_mce handling Move in_mce decrement earlier before registers are restored (but still after RI=0). This helps with later consolidation. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 823e930b6e3e..d8f1d70c675f 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1080,6 +1080,10 @@ EXC_COMMON_BEGIN(machine_check_common) /* Clear MSR_RI before setting SRR0 and SRR1. */\ li r9,0; \ mtmsrd r9,1; /* Clear MSR_RI */ \ + /* Decrement paca->in_mce now RI is clear. */ \ + lhz r12,PACA_IN_MCE(r13); \ + subi r12,r12,1; \ + sth r12,PACA_IN_MCE(r13); \ /* Move original SRR0 and SRR1 into the respective regs */ \ ld r9,_MSR(r1); \ mtspr SPRN_SRR1,r9; \ @@ -1096,10 +1100,6 @@ EXC_COMMON_BEGIN(machine_check_common) REST_GPR(10, r1); \ ld r11,_CCR(r1); \ mtcr r11; \ - /* Decrement paca->in_mce. */ \ - lhz r12,PACA_IN_MCE(r13); \ - subi r12,r12,1; \ - sth r12,PACA_IN_MCE(r13); \ REST_GPR(11, r1); \ REST_2GPRS(12, r1); \ /* restore original r1. */ \ -- cgit v1.2.3 From 67d4160a61a0dd63eef10392e4154433a0a64ac3 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:25 +1000 Subject: powerpc/64s/exception: simplify hmi windup code Duplicate the hmi windup code for both cases, rather than to put a special case branch in the middle of it. Remove unused label. This helps with later code consolidation. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index d8f1d70c675f..cbed1e42d85c 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1781,6 +1781,7 @@ TRAMP_REAL_BEGIN(hmi_exception_early) addi r3,r1,STACK_FRAME_OVERHEAD BRANCH_LINK_TO_FAR(DOTSYM(hmi_exception_realmode)) /* Function call ABI */ cmpdi cr0,r3,0 + bne 1f /* Windup the stack. */ /* Move original HSRR0 and HSRR1 into the respective regs */ @@ -1799,13 +1800,28 @@ TRAMP_REAL_BEGIN(hmi_exception_early) REST_GPR(10, r1) ld r11,_CCR(r1) REST_2GPRS(12, r1) - bne 1f mtcr r11 REST_GPR(11, r1) ld r1,GPR1(r1) HRFI_TO_USER_OR_KERNEL -1: mtcr r11 +1: + ld r9,_MSR(r1) + mtspr SPRN_HSRR1,r9 + ld r9,_NIP(r1) + mtspr SPRN_HSRR0,r9 + ld r9,_CTR(r1) + mtctr r9 + ld r9,_XER(r1) + mtxer r9 + ld r9,_LINK(r1) + mtlr r9 + REST_GPR(0, r1) + REST_8GPRS(2, r1) + REST_GPR(10, r1) + ld r11,_CCR(r1) + REST_2GPRS(12, r1) + mtcr r11 REST_GPR(11, r1) ld r1,GPR1(r1) @@ -1813,8 +1829,6 @@ TRAMP_REAL_BEGIN(hmi_exception_early) * Go to virtual mode and pull the HMI event information from * firmware. */ - .globl hmi_exception_after_realmode -hmi_exception_after_realmode: SET_SCRATCH0(r13) EXCEPTION_PROLOG_0 PACA_EXGEN b tramp_real_hmi_exception -- cgit v1.2.3 From b113c083414ed91c116483ebe74fb20c8b1ddcd3 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:26 +1000 Subject: powerpc/64s/exception: shuffle windup code around Restore all SPRs and CR up-front, these are longer latency instructions. Move register restore around to maximise pairs of adjacent loads (e.g., restore r0 next to r1). Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 40 +++++++++++++++--------------------- 1 file changed, 16 insertions(+), 24 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index cbed1e42d85c..b5060824303b 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -917,13 +917,11 @@ EXC_COMMON_BEGIN(system_reset_common) mtxer r9 ld r9,_LINK(r1) mtlr r9 - REST_GPR(0, r1) + ld r9,_CCR(r1) + mtcr r9 REST_8GPRS(2, r1) - REST_GPR(10, r1) - ld r11,_CCR(r1) - mtcr r11 - REST_GPR(11, r1) - REST_2GPRS(12, r1) + REST_4GPRS(10, r1) + REST_GPR(0, r1) /* restore original r1. */ ld r1,GPR1(r1) RFI_TO_USER_OR_KERNEL @@ -1095,13 +1093,11 @@ EXC_COMMON_BEGIN(machine_check_common) mtxer r9; \ ld r9,_LINK(r1); \ mtlr r9; \ - REST_GPR(0, r1); \ + ld r9,_CCR(r1); \ + mtcr r9; \ REST_8GPRS(2, r1); \ - REST_GPR(10, r1); \ - ld r11,_CCR(r1); \ - mtcr r11; \ - REST_GPR(11, r1); \ - REST_2GPRS(12, r1); \ + REST_4GPRS(10, r1); \ + REST_GPR(0, r1); \ /* restore original r1. */ \ ld r1,GPR1(r1) @@ -1795,13 +1791,11 @@ TRAMP_REAL_BEGIN(hmi_exception_early) mtxer r9 ld r9,_LINK(r1) mtlr r9 - REST_GPR(0, r1) + ld r9,_CCR(r1) + mtcr r9 REST_8GPRS(2, r1) - REST_GPR(10, r1) - ld r11,_CCR(r1) - REST_2GPRS(12, r1) - mtcr r11 - REST_GPR(11, r1) + REST_4GPRS(10, r1) + REST_GPR(0, r1) ld r1,GPR1(r1) HRFI_TO_USER_OR_KERNEL @@ -1816,13 +1810,11 @@ TRAMP_REAL_BEGIN(hmi_exception_early) mtxer r9 ld r9,_LINK(r1) mtlr r9 - REST_GPR(0, r1) + ld r9,_CCR(r1) + mtcr r9 REST_8GPRS(2, r1) - REST_GPR(10, r1) - ld r11,_CCR(r1) - REST_2GPRS(12, r1) - mtcr r11 - REST_GPR(11, r1) + REST_4GPRS(10, r1) + REST_GPR(0, r1) ld r1,GPR1(r1) /* -- cgit v1.2.3 From 391e941b891543f5d79c6be2f8f678cc15f7da5a Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:27 +1000 Subject: powerpc/64s/exception: use common macro for windup No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 112 +++++++++++------------------------ 1 file changed, 36 insertions(+), 76 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index b5060824303b..20e758ee704b 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -424,6 +424,38 @@ END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ EXCEPTION_PROLOG_COMMON_2(area); \ EXCEPTION_PROLOG_COMMON_3(trap) +/* + * Restore all registers including H/SRR0/1 saved in a stack frame of a + * standard exception. + */ +.macro EXCEPTION_RESTORE_REGS hsrr + /* Move original SRR0 and SRR1 into the respective regs */ + ld r9,_MSR(r1) + .if \hsrr + mtspr SPRN_HSRR1,r9 + .else + mtspr SPRN_SRR1,r9 + .endif + ld r9,_NIP(r1) + .if \hsrr + mtspr SPRN_HSRR0,r9 + .else + mtspr SPRN_SRR0,r9 + .endif + ld r9,_CTR(r1) + mtctr r9 + ld r9,_XER(r1) + mtxer r9 + ld r9,_LINK(r1) + mtlr r9 + ld r9,_CCR(r1) + mtcr r9 + REST_8GPRS(2, r1) + REST_4GPRS(10, r1) + REST_GPR(0, r1) + /* restore original r1. */ + ld r1,GPR1(r1) +.endm #define RUNLATCH_ON \ BEGIN_FTR_SECTION \ @@ -901,29 +933,7 @@ EXC_COMMON_BEGIN(system_reset_common) ld r10,SOFTE(r1) stb r10,PACAIRQSOFTMASK(r13) - /* - * Keep below code in synch with MACHINE_CHECK_HANDLER_WINDUP. - * Should share common bits... - */ - - /* Move original SRR0 and SRR1 into the respective regs */ - ld r9,_MSR(r1) - mtspr SPRN_SRR1,r9 - ld r9,_NIP(r1) - mtspr SPRN_SRR0,r9 - ld r9,_CTR(r1) - mtctr r9 - ld r9,_XER(r1) - mtxer r9 - ld r9,_LINK(r1) - mtlr r9 - ld r9,_CCR(r1) - mtcr r9 - REST_8GPRS(2, r1) - REST_4GPRS(10, r1) - REST_GPR(0, r1) - /* restore original r1. */ - ld r1,GPR1(r1) + EXCEPTION_RESTORE_REGS EXC_STD RFI_TO_USER_OR_KERNEL #ifdef CONFIG_PPC_PSERIES @@ -1082,24 +1092,7 @@ EXC_COMMON_BEGIN(machine_check_common) lhz r12,PACA_IN_MCE(r13); \ subi r12,r12,1; \ sth r12,PACA_IN_MCE(r13); \ - /* Move original SRR0 and SRR1 into the respective regs */ \ - ld r9,_MSR(r1); \ - mtspr SPRN_SRR1,r9; \ - ld r9,_NIP(r1); \ - mtspr SPRN_SRR0,r9; \ - ld r9,_CTR(r1); \ - mtctr r9; \ - ld r9,_XER(r1); \ - mtxer r9; \ - ld r9,_LINK(r1); \ - mtlr r9; \ - ld r9,_CCR(r1); \ - mtcr r9; \ - REST_8GPRS(2, r1); \ - REST_4GPRS(10, r1); \ - REST_GPR(0, r1); \ - /* restore original r1. */ \ - ld r1,GPR1(r1) + EXCEPTION_RESTORE_REGS EXC_STD #ifdef CONFIG_PPC_P7_NAP /* @@ -1779,48 +1772,15 @@ TRAMP_REAL_BEGIN(hmi_exception_early) cmpdi cr0,r3,0 bne 1f - /* Windup the stack. */ - /* Move original HSRR0 and HSRR1 into the respective regs */ - ld r9,_MSR(r1) - mtspr SPRN_HSRR1,r9 - ld r9,_NIP(r1) - mtspr SPRN_HSRR0,r9 - ld r9,_CTR(r1) - mtctr r9 - ld r9,_XER(r1) - mtxer r9 - ld r9,_LINK(r1) - mtlr r9 - ld r9,_CCR(r1) - mtcr r9 - REST_8GPRS(2, r1) - REST_4GPRS(10, r1) - REST_GPR(0, r1) - ld r1,GPR1(r1) + EXCEPTION_RESTORE_REGS EXC_HV HRFI_TO_USER_OR_KERNEL 1: - ld r9,_MSR(r1) - mtspr SPRN_HSRR1,r9 - ld r9,_NIP(r1) - mtspr SPRN_HSRR0,r9 - ld r9,_CTR(r1) - mtctr r9 - ld r9,_XER(r1) - mtxer r9 - ld r9,_LINK(r1) - mtlr r9 - ld r9,_CCR(r1) - mtcr r9 - REST_8GPRS(2, r1) - REST_4GPRS(10, r1) - REST_GPR(0, r1) - ld r1,GPR1(r1) - /* * Go to virtual mode and pull the HMI event information from * firmware. */ + EXCEPTION_RESTORE_REGS EXC_HV SET_SCRATCH0(r13) EXCEPTION_PROLOG_0 PACA_EXGEN b tramp_real_hmi_exception -- cgit v1.2.3 From 5312c4941e0d0185bb2c95d666d607292b7e3e57 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:28 +1000 Subject: powerpc/64s/exception: add dar and dsisr options to exception macro Some exception entry requires DAR and/or DSISR to be saved into the paca exception save area. Add options to the standard exception macros for these. Generated code changes slightly due to code structure. - 554: a6 02 72 7d mfdsisr r11 - 558: a8 00 4d f9 std r10,168(r13) - 55c: b0 00 6d 91 stw r11,176(r13) + 554: a8 00 4d f9 std r10,168(r13) + 558: a6 02 52 7d mfdsisr r10 + 55c: b0 00 4d 91 stw r10,176(r13) Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 101 ++++++++++++++++------------------- 1 file changed, 45 insertions(+), 56 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 20e758ee704b..aca162ed12e1 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -136,7 +136,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) OPT_GET_SPR(r10, SPRN_CFAR, CPU_FTR_CFAR) .endm -.macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, bitmask +.macro EXCEPTION_PROLOG_1 hsrr, area, kvm, vec, dar, dsisr, bitmask OPT_SAVE_REG_TO_PACA(\area\()+EX_PPR, r9, CPU_FTR_HAS_PPR) OPT_SAVE_REG_TO_PACA(\area\()+EX_CFAR, r10, CPU_FTR_CFAR) INTERRUPT_TO_KERNEL @@ -172,8 +172,22 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) std r11,\area\()+EX_R11(r13) std r12,\area\()+EX_R12(r13) + + /* + * DAR/DSISR, SCRATCH0 must be read before setting MSR[RI], + * because a d-side MCE will clobber those registers so is + * not recoverable if they are live. + */ GET_SCRATCH0(r10) std r10,\area\()+EX_R13(r13) + .if \dar + mfspr r10,SPRN_DAR + std r10,\area\()+EX_DAR(r13) + .endif + .if \dsisr + mfspr r10,SPRN_DSISR + stw r10,\area\()+EX_DSISR(r13) + .endif .endm .macro EXCEPTION_PROLOG_2_REAL label, hsrr, set_ri @@ -535,7 +549,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) EXC_REAL_BEGIN(name, start, size); \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 area ; \ - EXCEPTION_PROLOG_1 EXC_STD, area, 1, start, 0 ; \ + EXCEPTION_PROLOG_1 EXC_STD, area, 1, start, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ EXC_REAL_END(name, start, size) @@ -546,7 +560,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) EXC_VIRT_BEGIN(name, start, size); \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 area ; \ - EXCEPTION_PROLOG_1 EXC_STD, area, 0, realvec, 0; \ + EXCEPTION_PROLOG_1 EXC_STD, area, 0, realvec, 0, 0, 0; \ EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ EXC_VIRT_END(name, start, size) @@ -557,7 +571,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) EXC_REAL_BEGIN(name, start, size); \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, start, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, start, 0, 0, bitmask ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ EXC_REAL_END(name, start, size) @@ -565,7 +579,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) EXC_VIRT_BEGIN(name, start, size); \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, 0, 0, bitmask ; \ EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ EXC_VIRT_END(name, start, size) @@ -573,7 +587,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) EXC_REAL_BEGIN(name, start, size); \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 PACA_EXGEN; \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, start, 0 ; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, start, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 ; \ EXC_REAL_END(name, start, size) @@ -581,7 +595,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) EXC_VIRT_BEGIN(name, start, size); \ SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 PACA_EXGEN; \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV ; \ EXC_VIRT_END(name, start, size) @@ -594,7 +608,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __TRAMP_REAL_OOL(name, vec) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0 ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 #define EXC_REAL_OOL(name, start, size) \ @@ -606,7 +620,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __TRAMP_REAL_OOL_MASKABLE(name, vec, bitmask) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, vec, 0, 0, bitmask ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 #define EXC_REAL_OOL_MASKABLE(name, start, size, bitmask) \ @@ -625,7 +639,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __TRAMP_REAL_OOL_HV(name, vec) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0 ; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 #define EXC_REAL_OOL_HV(name, start, size) \ @@ -637,7 +651,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __TRAMP_REAL_OOL_MASKABLE_HV(name, vec, bitmask) \ TRAMP_REAL_BEGIN(tramp_real_##name); \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, vec, 0, 0, bitmask ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 #define EXC_REAL_OOL_MASKABLE_HV(name, start, size, bitmask) \ @@ -653,7 +667,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __TRAMP_VIRT_OOL(name, realvec) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, 0 ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, vec, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD #define EXC_VIRT_OOL(name, start, size, realvec) \ @@ -665,7 +679,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __TRAMP_VIRT_OOL_MASKABLE(name, realvec, bitmask) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, 0, 0, bitmask ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 #define EXC_VIRT_OOL_MASKABLE(name, start, size, realvec, bitmask) \ @@ -677,7 +691,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __TRAMP_VIRT_OOL_HV(name, realvec) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0 ; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV #define EXC_VIRT_OOL_HV(name, start, size, realvec) \ @@ -689,7 +703,7 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __TRAMP_VIRT_OOL_MASKABLE_HV(name, realvec, bitmask) \ TRAMP_VIRT_BEGIN(tramp_virt_##name); \ - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, bitmask ; \ + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0, 0, bitmask ; \ EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV #define EXC_VIRT_OOL_MASKABLE_HV(name, start, size, realvec, bitmask) \ @@ -944,7 +958,7 @@ TRAMP_REAL_BEGIN(system_reset_fwnmi) SET_SCRATCH0(r13) /* save r13 */ /* See comment at system_reset exception, don't turn on RI */ EXCEPTION_PROLOG_0 PACA_EXNMI - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 0, 0x100, 0 + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 0, 0x100, 0, 0, 0 EXCEPTION_PROLOG_2_REAL system_reset_common, EXC_STD, 0 #endif /* CONFIG_PPC_PSERIES */ @@ -965,7 +979,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) EXC_REAL_END(machine_check, 0x200, 0x100) EXC_VIRT_NONE(0x4200, 0x100) TRAMP_REAL_BEGIN(machine_check_common_early) - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 0 + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 0, 0x200, 0, 0, 0 /* * Register contents: * R13 = PACA @@ -1050,7 +1064,7 @@ BEGIN_FTR_SECTION b machine_check_common_early END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) machine_check_pSeries_0: - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 0 + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 0, 0, 0 /* * MSR_RI is not enabled, because PACA_EXMC is being used, so a * nested machine check corrupts it. machine_check_common enables @@ -1267,26 +1281,13 @@ EXC_REAL_BEGIN(data_access, 0x300, 0x80) EXC_REAL_END(data_access, 0x300, 0x80) TRAMP_REAL_BEGIN(tramp_real_data_access) - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300, 0 - /* - * DAR/DSISR must be read before setting MSR[RI], because - * a d-side MCE will clobber those registers so is not - * recoverable if they are live. - */ - mfspr r10,SPRN_DAR - mfspr r11,SPRN_DSISR - std r10,PACA_EXGEN+EX_DAR(r13) - stw r11,PACA_EXGEN+EX_DSISR(r13) -EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1 + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x300, 1, 1, 0 + EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300, 0 - mfspr r10,SPRN_DAR - mfspr r11,SPRN_DSISR - std r10,PACA_EXGEN+EX_DAR(r13) - stw r11,PACA_EXGEN+EX_DSISR(r13) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300, 1, 1, 0 EXCEPTION_PROLOG_2_VIRT data_access_common, EXC_STD EXC_VIRT_END(data_access, 0x4300, 0x80) @@ -1321,17 +1322,13 @@ EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80) EXC_REAL_END(data_access_slb, 0x380, 0x80) TRAMP_REAL_BEGIN(tramp_real_data_access_slb) - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 1, 0x380, 0 - mfspr r10,SPRN_DAR - std r10,PACA_EXSLB+EX_DAR(r13) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 1, 0x380, 1, 0, 0 EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXSLB - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380, 0 - mfspr r10,SPRN_DAR - std r10,PACA_EXSLB+EX_DAR(r13) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380, 1, 0, 0 EXCEPTION_PROLOG_2_VIRT data_access_slb_common, EXC_STD EXC_VIRT_END(data_access_slb, 0x4380, 0x80) @@ -1416,10 +1413,10 @@ EXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN BEGIN_FTR_SECTION - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_HV, 1 FTR_SECTION_ELSE - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED EXCEPTION_PROLOG_2_REAL hardware_interrupt_common, EXC_STD, 1 ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) EXC_REAL_END(hardware_interrupt, 0x500, 0x100) @@ -1428,10 +1425,10 @@ EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN BEGIN_FTR_SECTION - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_HV FTR_SECTION_ELSE - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, IRQS_DISABLED + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED EXCEPTION_PROLOG_2_VIRT hardware_interrupt_common, EXC_STD ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) EXC_VIRT_END(hardware_interrupt, 0x4500, 0x100) @@ -1444,22 +1441,14 @@ EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ) EXC_REAL_BEGIN(alignment, 0x600, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600, 0 - mfspr r10,SPRN_DAR - mfspr r11,SPRN_DSISR - std r10,PACA_EXGEN+EX_DAR(r13) - stw r11,PACA_EXGEN+EX_DSISR(r13) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600, 1, 1, 0 EXCEPTION_PROLOG_2_REAL alignment_common, EXC_STD, 1 EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600, 0 - mfspr r10,SPRN_DAR - mfspr r11,SPRN_DSISR - std r10,PACA_EXGEN+EX_DAR(r13) - stw r11,PACA_EXGEN+EX_DSISR(r13) + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600, 1, 1, 0 EXCEPTION_PROLOG_2_VIRT alignment_common, EXC_STD EXC_VIRT_END(alignment, 0x4600, 0x100) @@ -1757,7 +1746,7 @@ __TRAMP_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60, IRQS_DISABLED) EXC_VIRT_NONE(0x4e60, 0x20) TRAMP_KVM_HV(PACA_EXGEN, 0xe60) TRAMP_REAL_BEGIN(hmi_exception_early) - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0xe60, 0 + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0xe60, 0, 0, 0 mr r10,r1 /* Save r1 */ ld r1,PACAEMERGSP(r13) /* Use emergency stack for realmode */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ @@ -1942,7 +1931,7 @@ EXC_VIRT_NONE(0x5400, 0x100) EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) mtspr SPRN_SPRG_HSCRATCH0,r13 EXCEPTION_PROLOG_0 PACA_EXGEN - EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500, 0 + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500, 0, 0, 0 #ifdef CONFIG_PPC_DENORMALISATION mfspr r10,SPRN_HSRR1 -- cgit v1.2.3 From 02a1258154eec78783bd7e90d4ee1361c853db66 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:29 +1000 Subject: powerpc/64s/exception: machine check use standard macros to save dar/dsisr Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index aca162ed12e1..a39d5b47acbc 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1064,7 +1064,7 @@ BEGIN_FTR_SECTION b machine_check_common_early END_FTR_SECTION_IFCLR(CPU_FTR_HVMODE) machine_check_pSeries_0: - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 0, 0, 0 + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXMC, 1, 0x200, 1, 1, 0 /* * MSR_RI is not enabled, because PACA_EXMC is being used, so a * nested machine check corrupts it. machine_check_common enables @@ -1079,10 +1079,6 @@ EXC_COMMON_BEGIN(machine_check_common) * Machine check is different because we use a different * save area: PACA_EXMC instead of PACA_EXGEN. */ - mfspr r10,SPRN_DAR - std r10,PACA_EXMC+EX_DAR(r13) - mfspr r10,SPRN_DSISR - stw r10,PACA_EXMC+EX_DSISR(r13) EXCEPTION_COMMON(PACA_EXMC, 0x200) FINISH_NAP RECONCILE_IRQ_STATE(r10, r11) -- cgit v1.2.3 From 904f81f3f36d84a4d26c712a9c7741a397a4f348 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:30 +1000 Subject: powerpc/64s/exception: denorm handler use standard scratch save macro Although the 0x1500 interrupt only applies to bare metal, it is better to just use the standard macro for scratch save. Runtime code path remains unchanged (due to instruction patching). Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index a39d5b47acbc..836cf36df475 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -1925,7 +1925,7 @@ EXC_REAL_NONE(0x1400, 0x100) EXC_VIRT_NONE(0x5400, 0x100) EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) - mtspr SPRN_SPRG_HSCRATCH0,r13 + SET_SCRATCH0(r13) EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500, 0, 0, 0 -- cgit v1.2.3 From d7fb34c704719d3c91455297678aa75d9da95817 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:31 +1000 Subject: powerpc/64s/exception: move SET_SCRATCH0 into EXCEPTION_PROLOG_0 No generated code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 836cf36df475..b7c15a2df4a0 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -128,6 +128,7 @@ BEGIN_FTR_SECTION_NESTED(943) \ END_FTR_SECTION_NESTED(ftr,ftr,943) .macro EXCEPTION_PROLOG_0 area + SET_SCRATCH0(r13) /* save r13 */ GET_PACA(r13) std r9,\area\()+EX_R9(r13) /* save r9 */ OPT_GET_SPR(r9, SPRN_PPR, CPU_FTR_HAS_PPR) @@ -547,7 +548,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __EXC_REAL(name, start, size, area) \ EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 area ; \ EXCEPTION_PROLOG_1 EXC_STD, area, 1, start, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ @@ -558,7 +558,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __EXC_VIRT(name, start, size, realvec, area) \ EXC_VIRT_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 area ; \ EXCEPTION_PROLOG_1 EXC_STD, area, 0, realvec, 0, 0, 0; \ EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ @@ -569,7 +568,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define EXC_REAL_MASKABLE(name, start, size, bitmask) \ EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 PACA_EXGEN ; \ EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, start, 0, 0, bitmask ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_STD, 1 ; \ @@ -577,7 +575,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define EXC_VIRT_MASKABLE(name, start, size, realvec, bitmask) \ EXC_VIRT_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 PACA_EXGEN ; \ EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, realvec, 0, 0, bitmask ; \ EXCEPTION_PROLOG_2_VIRT name##_common, EXC_STD ; \ @@ -585,7 +582,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define EXC_REAL_HV(name, start, size) \ EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 PACA_EXGEN; \ EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, start, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_REAL name##_common, EXC_HV, 1 ; \ @@ -593,7 +589,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define EXC_VIRT_HV(name, start, size, realvec) \ EXC_VIRT_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); /* save r13 */ \ EXCEPTION_PROLOG_0 PACA_EXGEN; \ EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, realvec, 0, 0, 0 ; \ EXCEPTION_PROLOG_2_VIRT name##_common, EXC_HV ; \ @@ -601,7 +596,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __EXC_REAL_OOL(name, start, size) \ EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); \ EXCEPTION_PROLOG_0 PACA_EXGEN ; \ b tramp_real_##name ; \ EXC_REAL_END(name, start, size) @@ -629,7 +623,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __EXC_REAL_OOL_HV_DIRECT(name, start, size, handler) \ EXC_REAL_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); \ EXCEPTION_PROLOG_0 PACA_EXGEN ; \ b handler; \ EXC_REAL_END(name, start, size) @@ -660,7 +653,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) #define __EXC_VIRT_OOL(name, start, size) \ EXC_VIRT_BEGIN(name, start, size); \ - SET_SCRATCH0(r13); \ EXCEPTION_PROLOG_0 PACA_EXGEN ; \ b tramp_virt_##name; \ EXC_VIRT_END(name, start, size) @@ -837,7 +829,6 @@ EXC_VIRT_NONE(0x4000, 0x100) EXC_REAL_BEGIN(system_reset, 0x100, 0x100) - SET_SCRATCH0(r13) EXCEPTION_PROLOG_0 PACA_EXNMI /* This is EXCEPTION_PROLOG_1 with the idle feature section added */ @@ -955,7 +946,6 @@ EXC_COMMON_BEGIN(system_reset_common) * Vectors for the FWNMI option. Share common code. */ TRAMP_REAL_BEGIN(system_reset_fwnmi) - SET_SCRATCH0(r13) /* save r13 */ /* See comment at system_reset exception, don't turn on RI */ EXCEPTION_PROLOG_0 PACA_EXNMI EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 0, 0x100, 0, 0, 0 @@ -969,7 +959,6 @@ EXC_REAL_BEGIN(machine_check, 0x200, 0x100) * some code path might still want to branch into the original * vector */ - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXMC BEGIN_FTR_SECTION b machine_check_common_early @@ -1058,7 +1047,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_HVMODE) TRAMP_REAL_BEGIN(machine_check_pSeries) .globl machine_check_fwnmi machine_check_fwnmi: - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXMC BEGIN_FTR_SECTION b machine_check_common_early @@ -1246,7 +1234,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE) 9: /* Deliver the machine check to host kernel in V mode. */ MACHINE_CHECK_HANDLER_WINDUP - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXMC b machine_check_pSeries_0 @@ -1271,7 +1258,6 @@ EXC_COMMON_BEGIN(mce_return) b . EXC_REAL_BEGIN(data_access, 0x300, 0x80) - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN b tramp_real_data_access EXC_REAL_END(data_access, 0x300, 0x80) @@ -1281,7 +1267,6 @@ TRAMP_REAL_BEGIN(tramp_real_data_access) EXCEPTION_PROLOG_2_REAL data_access_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access, 0x4300, 0x80) - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x300, 1, 1, 0 EXCEPTION_PROLOG_2_VIRT data_access_common, EXC_STD @@ -1312,7 +1297,6 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) EXC_REAL_BEGIN(data_access_slb, 0x380, 0x80) - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXSLB b tramp_real_data_access_slb EXC_REAL_END(data_access_slb, 0x380, 0x80) @@ -1322,7 +1306,6 @@ TRAMP_REAL_BEGIN(tramp_real_data_access_slb) EXCEPTION_PROLOG_2_REAL data_access_slb_common, EXC_STD, 1 EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80) - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXSLB EXCEPTION_PROLOG_1 EXC_STD, PACA_EXSLB, 0, 0x380, 1, 0, 0 EXCEPTION_PROLOG_2_VIRT data_access_slb_common, EXC_STD @@ -1406,7 +1389,6 @@ ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX) EXC_REAL_BEGIN(hardware_interrupt, 0x500, 0x100) - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN BEGIN_FTR_SECTION EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED @@ -1418,7 +1400,6 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) EXC_REAL_END(hardware_interrupt, 0x500, 0x100) EXC_VIRT_BEGIN(hardware_interrupt, 0x4500, 0x100) - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN BEGIN_FTR_SECTION EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0x500, 0, 0, IRQS_DISABLED @@ -1435,14 +1416,12 @@ EXC_COMMON_ASYNC(hardware_interrupt_common, 0x500, do_IRQ) EXC_REAL_BEGIN(alignment, 0x600, 0x100) - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 1, 0x600, 1, 1, 0 EXCEPTION_PROLOG_2_REAL alignment_common, EXC_STD, 1 EXC_REAL_END(alignment, 0x600, 0x100) EXC_VIRT_BEGIN(alignment, 0x4600, 0x100) - SET_SCRATCH0(r13) /* save r13 */ EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_STD, PACA_EXGEN, 0, 0x600, 1, 1, 0 EXCEPTION_PROLOG_2_VIRT alignment_common, EXC_STD @@ -1766,7 +1745,6 @@ TRAMP_REAL_BEGIN(hmi_exception_early) * firmware. */ EXCEPTION_RESTORE_REGS EXC_HV - SET_SCRATCH0(r13) EXCEPTION_PROLOG_0 PACA_EXGEN b tramp_real_hmi_exception @@ -1925,7 +1903,6 @@ EXC_REAL_NONE(0x1400, 0x100) EXC_VIRT_NONE(0x5400, 0x100) EXC_REAL_BEGIN(denorm_exception_hv, 0x1500, 0x100) - SET_SCRATCH0(r13) EXCEPTION_PROLOG_0 PACA_EXGEN EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 0, 0x1500, 0, 0, 0 -- cgit v1.2.3 From f30a5e68f026f3214a9392391537adaa79996b24 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 15:33:32 +1000 Subject: powerpc/tm: update comment about interrupt re-entrancy Since the system reset interrupt began to use its own stack, and machine check interrupts have done so for some time, r1 can be changed without clearing MSR[RI], provided no other interrupts (including SLB misses) are taken. MSR[RI] does have to be cleared when using SCRATCH0, however. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/tm.S | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/tm.S b/arch/powerpc/kernel/tm.S index 9fabdce255cd..6ba0fdd1e7f8 100644 --- a/arch/powerpc/kernel/tm.S +++ b/arch/powerpc/kernel/tm.S @@ -148,7 +148,7 @@ _GLOBAL(tm_reclaim) /* Stash the stack pointer away for use after reclaim */ std r1, PACAR1(r13) - /* Clear MSR RI since we are about to change r1, EE is already off. */ + /* Clear MSR RI since we are about to use SCRATCH0, EE is already off */ li r5, 0 mtmsrd r5, 1 @@ -474,7 +474,7 @@ restore_gprs: REST_GPR(7, r7) - /* Clear MSR RI since we are about to change r1. EE is already off */ + /* Clear MSR RI since we are about to use SCRATCH0. EE is already off */ li r5, 0 mtmsrd r5, 1 -- cgit v1.2.3 From 0a882e28468f48ab3d9a36dde0a5723ea29ed1ed Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 16:33:18 +1000 Subject: powerpc/64s/exception: remove bad stack branch The bad stack test in interrupt handlers has a few problems. For performance it is taken in the common case, which is a fetch bubble and a waste of i-cache. For code development and maintainence, it requires yet another stack frame setup routine, and that constrains all exception handlers to follow the same register save pattern which inhibits future optimisation. Remove the test/branch and replace it with a trap. Teach the program check handler to use the emergency stack for this case. This does not result in quite so nice a message, however the SRR0 and SRR1 of the crashed interrupt can be seen in r11 and r12, as is the original r1 (adjusted by INT_FRAME_SIZE). These are the most important parts to debugging the issue. The original r9-12 and cr0 is lost, which is the main downside. kernel BUG at linux/arch/powerpc/kernel/exceptions-64s.S:847! Oops: Exception in kernel mode, sig: 5 [#1] BE SMP NR_CPUS=2048 NUMA PowerNV Modules linked in: CPU: 0 PID: 1 Comm: swapper/0 Not tainted NIP: c000000000009108 LR: c000000000cadbcc CTR: c0000000000090f0 REGS: c0000000fffcbd70 TRAP: 0700 Not tainted MSR: 9000000000021032 CR: 28222448 XER: 20040000 CFAR: c000000000009100 IRQMASK: 0 GPR00: 000000000000003d fffffffffffffd00 c0000000018cfb00 c0000000f02b3166 GPR04: fffffffffffffffd 0000000000000007 fffffffffffffffb 0000000000000030 GPR08: 0000000000000037 0000000028222448 0000000000000000 c000000000ca8de0 GPR12: 9000000002009032 c000000001ae0000 c000000000010a00 0000000000000000 GPR16: 0000000000000000 0000000000000000 0000000000000000 0000000000000000 GPR20: c0000000f00322c0 c000000000f85200 0000000000000004 ffffffffffffffff GPR24: fffffffffffffffe 0000000000000000 0000000000000000 000000000000000a GPR28: 0000000000000000 0000000000000000 c0000000f02b391c c0000000f02b3167 NIP [c000000000009108] decrementer_common+0x18/0x160 LR [c000000000cadbcc] .vsnprintf+0x3ec/0x4f0 Call Trace: Instruction dump: 996d098a 994d098b 38610070 480246ed 48005518 60000000 38200000 718a4000 7c2a0b78 3821fd00 41c20008 e82d0970 <0981fd00> f92101a0 f9610170 f9810178 Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/exception-64s.h | 7 --- arch/powerpc/include/asm/paca.h | 2 + arch/powerpc/kernel/asm-offsets.c | 2 + arch/powerpc/kernel/exceptions-64s.S | 96 ++++++-------------------------- arch/powerpc/xmon/xmon.c | 2 + 5 files changed, 22 insertions(+), 87 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/exception-64s.h b/arch/powerpc/include/asm/exception-64s.h index 40d114e69cbe..a77cdb07b152 100644 --- a/arch/powerpc/include/asm/exception-64s.h +++ b/arch/powerpc/include/asm/exception-64s.h @@ -48,13 +48,6 @@ */ #define MAX_MCE_DEPTH 4 -/* - * EX_R3 is only used by the bad_stack handler. bad_stack reloads and - * saves DAR from SPRN_DAR, and EX_DAR is not used. So EX_R3 can overlap - * with EX_DAR. - */ -#define EX_R3 EX_DAR - #ifdef __ASSEMBLY__ #define STF_ENTRY_BARRIER_SLOT \ diff --git a/arch/powerpc/include/asm/paca.h b/arch/powerpc/include/asm/paca.h index 62f27e0aef7c..a2f713034ed3 100644 --- a/arch/powerpc/include/asm/paca.h +++ b/arch/powerpc/include/asm/paca.h @@ -170,7 +170,9 @@ struct paca_struct { u64 kstack; /* Saved Kernel stack addr */ u64 saved_r1; /* r1 save for RTAS calls or PM or EE=0 */ u64 saved_msr; /* MSR saved here by enter_rtas */ +#ifdef CONFIG_PPC_BOOK3E u16 trap_save; /* Used when bad stack is encountered */ +#endif u8 irq_soft_mask; /* mask for irq soft masking */ u8 irq_happened; /* irq happened while soft-disabled */ u8 irq_work_pending; /* IRQ_WORK interrupt while soft-disable */ diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c index 8e02444e9d3d..524a7bba0ee5 100644 --- a/arch/powerpc/kernel/asm-offsets.c +++ b/arch/powerpc/kernel/asm-offsets.c @@ -270,7 +270,9 @@ int main(void) OFFSET(ACCOUNT_STARTTIME_USER, paca_struct, accounting.starttime_user); OFFSET(ACCOUNT_USER_TIME, paca_struct, accounting.utime); OFFSET(ACCOUNT_SYSTEM_TIME, paca_struct, accounting.stime); +#ifdef CONFIG_PPC_BOOK3E OFFSET(PACA_TRAP_SAVE, paca_struct, trap_save); +#endif OFFSET(PACA_SPRG_VDSO, paca_struct, sprg_vdso); #else /* CONFIG_PPC64 */ #ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index b7c15a2df4a0..c73e909470e3 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -411,14 +411,8 @@ END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ subi r1,r1,INT_FRAME_SIZE; /* alloc frame on kernel stack */ \ beq- 1f; \ ld r1,PACAKSAVE(r13); /* kernel stack to use */ \ -1: cmpdi cr1,r1,-INT_FRAME_SIZE; /* check if r1 is in userspace */ \ - blt+ cr1,3f; /* abort if it is */ \ - li r1,(trap); /* will be reloaded later */ \ - sth r1,PACA_TRAP_SAVE(r13); \ - std r3,area+EX_R3(r13); \ - addi r3,r13,area; /* r3 -> where regs are saved*/ \ - RESTORE_CTR(r1, area); \ - b bad_stack; \ +1: tdgei r1,-INT_FRAME_SIZE; /* trap if r1 is in userspace */ \ + EMIT_BUG_ENTRY 1b,__FILE__,__LINE__,0; \ 3: EXCEPTION_PROLOG_COMMON_1(); \ kuap_save_amr_and_lock r9, r10, cr1, cr0; \ beq 4f; /* if from kernel mode */ \ @@ -428,7 +422,6 @@ END_FTR_SECTION_NESTED(CPU_FTR_CFAR, CPU_FTR_CFAR, 66); \ EXCEPTION_PROLOG_COMMON_3(trap); \ ACCOUNT_STOLEN_TIME - /* * Exception where stack is already set in r1, r1 is saved in r10. * PPR save and CPU accounting is not done (for some reason). @@ -1453,21 +1446,25 @@ EXC_COMMON_BEGIN(program_check_common) * we switch to the emergency stack if we're taking a TM Bad Thing from * the kernel. */ - li r10,MSR_PR /* Build a mask of MSR_PR .. */ - oris r10,r10,0x200000@h /* .. and SRR1_PROGTM */ - and r10,r10,r12 /* Mask SRR1 with that. */ - srdi r10,r10,8 /* Shift it so we can compare */ - cmpldi r10,(0x200000 >> 8) /* .. with an immediate. */ - bne 1f /* If != go to normal path. */ - - /* SRR1 had PR=0 and SRR1_PROGTM=1, so use the emergency stack */ - andi. r10,r12,MSR_PR; /* Set CR0 correctly for label */ + + andi. r10,r12,MSR_PR + bne 2f /* If userspace, go normal path */ + + andis. r10,r12,(SRR1_PROGTM)@h + bne 1f /* If TM, emergency */ + + cmpdi r1,-INT_FRAME_SIZE /* check if r1 is in userspace */ + blt 2f /* normal path if not */ + + /* Use the emergency stack */ +1: andi. r10,r12,MSR_PR /* Set CR0 correctly for label */ /* 3 in EXCEPTION_PROLOG_COMMON */ mr r10,r1 /* Save r1 */ ld r1,PACAEMERGSP(r13) /* Use emergency stack */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ b 3f /* Jump into the macro !! */ -1: EXCEPTION_COMMON(PACA_EXGEN, 0x700) +2: + EXCEPTION_COMMON(PACA_EXGEN, 0x700) bl save_nvgprs RECONCILE_IRQ_STATE(r10, r11) addi r3,r1,STACK_FRAME_OVERHEAD @@ -2408,67 +2405,6 @@ handle_dabr_fault: bl bad_page_fault b ret_from_except -/* - * Here we have detected that the kernel stack pointer is bad. - * R9 contains the saved CR, r13 points to the paca, - * r10 contains the (bad) kernel stack pointer, - * r11 and r12 contain the saved SRR0 and SRR1. - * We switch to using an emergency stack, save the registers there, - * and call kernel_bad_stack(), which panics. - */ -bad_stack: - ld r1,PACAEMERGSP(r13) - subi r1,r1,64+INT_FRAME_SIZE - std r9,_CCR(r1) - std r10,GPR1(r1) - std r11,_NIP(r1) - std r12,_MSR(r1) - mfspr r11,SPRN_DAR - mfspr r12,SPRN_DSISR - std r11,_DAR(r1) - std r12,_DSISR(r1) - mflr r10 - mfctr r11 - mfxer r12 - std r10,_LINK(r1) - std r11,_CTR(r1) - std r12,_XER(r1) - SAVE_GPR(0,r1) - SAVE_GPR(2,r1) - ld r10,EX_R3(r3) - std r10,GPR3(r1) - SAVE_GPR(4,r1) - SAVE_4GPRS(5,r1) - ld r9,EX_R9(r3) - ld r10,EX_R10(r3) - SAVE_2GPRS(9,r1) - ld r9,EX_R11(r3) - ld r10,EX_R12(r3) - ld r11,EX_R13(r3) - std r9,GPR11(r1) - std r10,GPR12(r1) - std r11,GPR13(r1) -BEGIN_FTR_SECTION - ld r10,EX_CFAR(r3) - std r10,ORIG_GPR3(r1) -END_FTR_SECTION_IFSET(CPU_FTR_CFAR) - SAVE_8GPRS(14,r1) - SAVE_10GPRS(22,r1) - lhz r12,PACA_TRAP_SAVE(r13) - std r12,_TRAP(r1) - addi r11,r1,INT_FRAME_SIZE - std r11,0(r1) - li r12,0 - std r12,0(r11) - ld r2,PACATOC(r13) - ld r11,exception_marker@toc(r2) - std r12,RESULT(r1) - std r11,STACK_FRAME_OVERHEAD-16(r1) -1: addi r3,r1,STACK_FRAME_OVERHEAD - bl kernel_bad_stack - b 1b -_ASM_NOKPROBE_SYMBOL(bad_stack); - /* * When doorbell is triggered from system reset wakeup, the message is * not cleared, so it would fire again when EE is enabled. diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index f1c4e1601b9d..f879e9fe9733 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -2454,7 +2454,9 @@ static void dump_one_paca(int cpu) DUMP(p, canary, "%#-*lx"); #endif DUMP(p, saved_r1, "%#-*llx"); +#ifdef CONFIG_PPC_BOOK3E DUMP(p, trap_save, "%#-*x"); +#endif DUMP(p, irq_soft_mask, "%#-*x"); DUMP(p, irq_happened, "%#-*x"); #ifdef CONFIG_MMIOWB -- cgit v1.2.3 From 514caf23a70fd697fa2ece238b2cd8dcc73fb16f Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Wed, 26 Jun 2019 14:27:13 +0200 Subject: memremap: replace the altmap_valid field with a PGMAP_ALTMAP_VALID flag Add a flags field to struct dev_pagemap to replace the altmap_valid boolean to be a little more extensible. Also add a pgmap_altmap() helper to find the optional altmap and clean up the code using the altmap using it. Signed-off-by: Christoph Hellwig Reviewed-by: Ira Weiny Reviewed-by: Dan Williams Tested-by: Dan Williams Signed-off-by: Jason Gunthorpe --- arch/powerpc/mm/mem.c | 10 +--------- arch/x86/mm/init_64.c | 8 ++------ drivers/nvdimm/pfn_devs.c | 3 +-- drivers/nvdimm/pmem.c | 1 - include/linux/memremap.h | 12 +++++++++++- kernel/memremap.c | 26 ++++++++++---------------- mm/hmm.c | 1 - mm/memory_hotplug.c | 6 ++---- mm/page_alloc.c | 5 ++--- 9 files changed, 29 insertions(+), 43 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 2540d3b2588c..a2923c5c1982 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -131,17 +131,9 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size, { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - struct page *page; + struct page *page = pfn_to_page(start_pfn) + vmem_altmap_offset(altmap); int ret; - /* - * If we have an altmap then we need to skip over any reserved PFNs - * when querying the zone. - */ - page = pfn_to_page(start_pfn); - if (altmap) - page += vmem_altmap_offset(altmap); - __remove_pages(page_zone(page), start_pfn, nr_pages, altmap); /* Remove htab bolted mappings for this section of memory */ diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 0f01c7b1d217..08bbf648827b 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -1213,13 +1213,9 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size, { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; - struct page *page = pfn_to_page(start_pfn); - struct zone *zone; + struct page *page = pfn_to_page(start_pfn) + vmem_altmap_offset(altmap); + struct zone *zone = page_zone(page); - /* With altmap the first mapped page is offset from @start */ - if (altmap) - page += vmem_altmap_offset(altmap); - zone = page_zone(page); __remove_pages(zone, start_pfn, nr_pages, altmap); kernel_physical_mapping_remove(start, start + size); } diff --git a/drivers/nvdimm/pfn_devs.c b/drivers/nvdimm/pfn_devs.c index 0f81fc56bbfd..55fb6b7433ed 100644 --- a/drivers/nvdimm/pfn_devs.c +++ b/drivers/nvdimm/pfn_devs.c @@ -622,7 +622,6 @@ static int __nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap) if (offset < reserve) return -EINVAL; nd_pfn->npfns = le64_to_cpu(pfn_sb->npfns); - pgmap->altmap_valid = false; } else if (nd_pfn->mode == PFN_MODE_PMEM) { nd_pfn->npfns = PFN_SECTION_ALIGN_UP((resource_size(res) - offset) / PAGE_SIZE); @@ -634,7 +633,7 @@ static int __nvdimm_setup_pfn(struct nd_pfn *nd_pfn, struct dev_pagemap *pgmap) memcpy(altmap, &__altmap, sizeof(*altmap)); altmap->free = PHYS_PFN(offset - reserve); altmap->alloc = 0; - pgmap->altmap_valid = true; + pgmap->flags |= PGMAP_ALTMAP_VALID; } else return -ENXIO; diff --git a/drivers/nvdimm/pmem.c b/drivers/nvdimm/pmem.c index 093408ce40ad..e7d8cc9f41e8 100644 --- a/drivers/nvdimm/pmem.c +++ b/drivers/nvdimm/pmem.c @@ -412,7 +412,6 @@ static int pmem_attach_disk(struct device *dev, bb_res.start += pmem->data_offset; } else if (pmem_should_map_pages(dev)) { memcpy(&pmem->pgmap.res, &nsio->res, sizeof(pmem->pgmap.res)); - pmem->pgmap.altmap_valid = false; pmem->pgmap.type = MEMORY_DEVICE_FS_DAX; pmem->pgmap.ops = &fsdax_pagemap_ops; addr = devm_memremap_pages(dev, &pmem->pgmap); diff --git a/include/linux/memremap.h b/include/linux/memremap.h index 336eca601dad..e25685b878e9 100644 --- a/include/linux/memremap.h +++ b/include/linux/memremap.h @@ -88,6 +88,8 @@ struct dev_pagemap_ops { vm_fault_t (*migrate_to_ram)(struct vm_fault *vmf); }; +#define PGMAP_ALTMAP_VALID (1 << 0) + /** * struct dev_pagemap - metadata for ZONE_DEVICE mappings * @altmap: pre-allocated/reserved memory for vmemmap allocations @@ -96,19 +98,27 @@ struct dev_pagemap_ops { * @dev: host device of the mapping for debug * @data: private data pointer for page_free() * @type: memory type: see MEMORY_* in memory_hotplug.h + * @flags: PGMAP_* flags to specify defailed behavior * @ops: method table */ struct dev_pagemap { struct vmem_altmap altmap; - bool altmap_valid; struct resource res; struct percpu_ref *ref; struct device *dev; enum memory_type type; + unsigned int flags; u64 pci_p2pdma_bus_offset; const struct dev_pagemap_ops *ops; }; +static inline struct vmem_altmap *pgmap_altmap(struct dev_pagemap *pgmap) +{ + if (pgmap->flags & PGMAP_ALTMAP_VALID) + return &pgmap->altmap; + return NULL; +} + #ifdef CONFIG_ZONE_DEVICE void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap); void devm_memunmap_pages(struct device *dev, struct dev_pagemap *pgmap); diff --git a/kernel/memremap.c b/kernel/memremap.c index 6c3dbb692037..eee490e7d7e1 100644 --- a/kernel/memremap.c +++ b/kernel/memremap.c @@ -54,14 +54,8 @@ static void pgmap_array_delete(struct resource *res) static unsigned long pfn_first(struct dev_pagemap *pgmap) { - const struct resource *res = &pgmap->res; - struct vmem_altmap *altmap = &pgmap->altmap; - unsigned long pfn; - - pfn = res->start >> PAGE_SHIFT; - if (pgmap->altmap_valid) - pfn += vmem_altmap_offset(altmap); - return pfn; + return (pgmap->res.start >> PAGE_SHIFT) + + vmem_altmap_offset(pgmap_altmap(pgmap)); } static unsigned long pfn_end(struct dev_pagemap *pgmap) @@ -109,7 +103,7 @@ static void devm_memremap_pages_release(void *data) align_size >> PAGE_SHIFT, NULL); } else { arch_remove_memory(nid, align_start, align_size, - pgmap->altmap_valid ? &pgmap->altmap : NULL); + pgmap_altmap(pgmap)); kasan_remove_zero_shadow(__va(align_start), align_size); } mem_hotplug_done(); @@ -129,8 +123,8 @@ static void devm_memremap_pages_release(void *data) * 1/ At a minimum the res, ref and type and ops members of @pgmap must be * initialized by the caller before passing it to this function * - * 2/ The altmap field may optionally be initialized, in which case altmap_valid - * must be set to true + * 2/ The altmap field may optionally be initialized, in which case + * PGMAP_ALTMAP_VALID must be set in pgmap->flags. * * 3/ pgmap->ref must be 'live' on entry and will be killed and reaped * at devm_memremap_pages_release() time, or if this routine fails. @@ -142,15 +136,13 @@ static void devm_memremap_pages_release(void *data) void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) { resource_size_t align_start, align_size, align_end; - struct vmem_altmap *altmap = pgmap->altmap_valid ? - &pgmap->altmap : NULL; struct resource *res = &pgmap->res; struct dev_pagemap *conflict_pgmap; struct mhp_restrictions restrictions = { /* * We do not want any optional features only our own memmap */ - .altmap = altmap, + .altmap = pgmap_altmap(pgmap), }; pgprot_t pgprot = PAGE_KERNEL; int error, nid, is_ram; @@ -274,7 +266,7 @@ void *devm_memremap_pages(struct device *dev, struct dev_pagemap *pgmap) zone = &NODE_DATA(nid)->node_zones[ZONE_DEVICE]; move_pfn_range_to_zone(zone, align_start >> PAGE_SHIFT, - align_size >> PAGE_SHIFT, altmap); + align_size >> PAGE_SHIFT, pgmap_altmap(pgmap)); } mem_hotplug_done(); @@ -319,7 +311,9 @@ EXPORT_SYMBOL_GPL(devm_memunmap_pages); unsigned long vmem_altmap_offset(struct vmem_altmap *altmap) { /* number of pfns from base where pfn_to_page() is valid */ - return altmap->reserve + altmap->free; + if (altmap) + return altmap->reserve + altmap->free; + return 0; } void vmem_altmap_free(struct vmem_altmap *altmap, unsigned long nr_pfns) diff --git a/mm/hmm.c b/mm/hmm.c index 36e25cdbdac1..e4470462298f 100644 --- a/mm/hmm.c +++ b/mm/hmm.c @@ -1442,7 +1442,6 @@ struct hmm_devmem *hmm_devmem_add(const struct hmm_devmem_ops *ops, devmem->pagemap.type = MEMORY_DEVICE_PRIVATE; devmem->pagemap.res = *devmem->resource; devmem->pagemap.ops = &hmm_pagemap_ops; - devmem->pagemap.altmap_valid = false; devmem->pagemap.ref = &devmem->ref; result = devm_memremap_pages(devmem->device, &devmem->pagemap); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index e096c987d261..6166ba5a15f3 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -557,10 +557,8 @@ void __remove_pages(struct zone *zone, unsigned long phys_start_pfn, int sections_to_remove; /* In the ZONE_DEVICE case device driver owns the memory region */ - if (is_dev_zone(zone)) { - if (altmap) - map_offset = vmem_altmap_offset(altmap); - } + if (is_dev_zone(zone)) + map_offset = vmem_altmap_offset(altmap); clear_zone_contiguous(zone); diff --git a/mm/page_alloc.c b/mm/page_alloc.c index d66bc8abe0af..17a39d40a556 100644 --- a/mm/page_alloc.c +++ b/mm/page_alloc.c @@ -5853,6 +5853,7 @@ void __ref memmap_init_zone_device(struct zone *zone, { unsigned long pfn, end_pfn = start_pfn + size; struct pglist_data *pgdat = zone->zone_pgdat; + struct vmem_altmap *altmap = pgmap_altmap(pgmap); unsigned long zone_idx = zone_idx(zone); unsigned long start = jiffies; int nid = pgdat->node_id; @@ -5865,9 +5866,7 @@ void __ref memmap_init_zone_device(struct zone *zone, * of the pages reserved for the memmap, so we can just jump to * the end of that region and start processing the device pages. */ - if (pgmap->altmap_valid) { - struct vmem_altmap *altmap = &pgmap->altmap; - + if (altmap) { start_pfn = altmap->base_pfn + vmem_altmap_offset(altmap); size = end_pfn - start_pfn; } -- cgit v1.2.3 From 0e10be2bb9cf1f552f5d64bfe786926bba9d11d2 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 16:33:19 +1000 Subject: powerpc/64s/exception: optimise system_reset for idle, clean up non-idle case The idle wake up code in the system reset interrupt is not very optimal. There are two requirements: perform idle wake up quickly; and save everything including CFAR for non-idle interrupts, with no performance requirement. The problem with placing the idle test in the middle of the handler and using the normal handler code to save CFAR, is that it's quite costly (e.g., mfcfar is serialising, speculative workarounds get applied, SRR1 has to be reloaded, etc). It also prevents the standard interrupt handler boilerplate being used. This pain can be avoided by using a dedicated idle interrupt handler at the start of the interrupt handler, which restores all registers back to the way they were in case it was not an idle wake up. CFAR is preserved without saving it before the non-idle case by making that the fall-through, and idle is a taken branch. Performance seems to be in the noise, but possibly around 0.5% faster, the executed instructions certainly look better. The bigger benefit is being able to drop in standard interrupt handlers after the idle code, which helps with subsequent cleanup and consolidation. Signed-off-by: Nicholas Piggin [mpe: Fixup BE by using DOTSYM for idle_return_gpr_loss call] Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 69 ++++++++++++++++++++---------------- 1 file changed, 38 insertions(+), 31 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index c73e909470e3..e5660f3e8331 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -256,7 +256,7 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) * load KBASE for a slight optimisation. */ #define BRANCH_TO_C000(reg, label) \ - __LOAD_HANDLER(reg, label); \ + __LOAD_FAR_HANDLER(reg, label); \ mtctr reg; \ bctr @@ -822,15 +822,6 @@ EXC_VIRT_NONE(0x4000, 0x100) EXC_REAL_BEGIN(system_reset, 0x100, 0x100) - EXCEPTION_PROLOG_0 PACA_EXNMI - - /* This is EXCEPTION_PROLOG_1 with the idle feature section added */ - OPT_SAVE_REG_TO_PACA(PACA_EXNMI+EX_PPR, r9, CPU_FTR_HAS_PPR) - OPT_SAVE_REG_TO_PACA(PACA_EXNMI+EX_CFAR, r10, CPU_FTR_CFAR) - INTERRUPT_TO_KERNEL - SAVE_CTR(r10, PACA_EXNMI) - mfcr r9 - #ifdef CONFIG_PPC_P7_NAP /* * If running native on arch 2.06 or later, check if we are waking up @@ -838,43 +829,59 @@ EXC_REAL_BEGIN(system_reset, 0x100, 0x100) * bits 46:47. A non-0 value indicates that we are coming from a power * saving state. The idle wakeup handler initially runs in real mode, * but we branch to the 0xc000... address so we can turn on relocation - * with mtmsr. + * with mtmsrd later, after SPRs are restored. + * + * Careful to minimise cost for the fast path (idle wakeup) while + * also avoiding clobbering CFAR for the debug path (non-idle). + * + * For the idle wake case volatile registers can be clobbered, which + * is why we use those initially. If it turns out to not be an idle + * wake, carefully put everything back the way it was, so we can use + * common exception macros to handle it. */ BEGIN_FTR_SECTION - mfspr r10,SPRN_SRR1 - rlwinm. r10,r10,47-31,30,31 - beq- 1f - cmpwi cr1,r10,2 + SET_SCRATCH0(r13) + GET_PACA(r13) + std r3,PACA_EXNMI+0*8(r13) + std r4,PACA_EXNMI+1*8(r13) + std r5,PACA_EXNMI+2*8(r13) mfspr r3,SPRN_SRR1 - bltlr cr1 /* no state loss, return to idle caller */ - BRANCH_TO_C000(r10, system_reset_idle_common) -1: + mfocrf r4,0x80 + rlwinm. r5,r3,47-31,30,31 + bne+ system_reset_idle_wake + /* Not powersave wakeup. Restore regs for regular interrupt handler. */ + mtocrf 0x80,r4 + ld r3,PACA_EXNMI+0*8(r13) + ld r4,PACA_EXNMI+1*8(r13) + ld r5,PACA_EXNMI+2*8(r13) + GET_SCRATCH0(r13) END_FTR_SECTION_IFSET(CPU_FTR_HVMODE | CPU_FTR_ARCH_206) #endif - KVMTEST EXC_STD 0x100 - std r11,PACA_EXNMI+EX_R11(r13) - std r12,PACA_EXNMI+EX_R12(r13) - GET_SCRATCH0(r10) - std r10,PACA_EXNMI+EX_R13(r13) - + EXCEPTION_PROLOG_0 PACA_EXNMI + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 1, 0x100, 0, 0, 0 EXCEPTION_PROLOG_2_REAL system_reset_common, EXC_STD, 0 /* * MSR_RI is not enabled, because PACA_EXNMI and nmi stack is * being used, so a nested NMI exception would corrupt it. + * + * In theory, we should not enable relocation here if it was disabled + * in SRR1, because the MMU may not be configured to support it (e.g., + * SLB may have been cleared). In practice, there should only be a few + * small windows where that's the case, and sreset is considered to + * be dangerous anyway. */ - EXC_REAL_END(system_reset, 0x100, 0x100) + EXC_VIRT_NONE(0x4100, 0x100) TRAMP_KVM(PACA_EXNMI, 0x100) #ifdef CONFIG_PPC_P7_NAP -EXC_COMMON_BEGIN(system_reset_idle_common) - /* - * This must be a direct branch (without linker branch stub) because - * we can not use TOC at this point as r2 may not be restored yet. - */ - b idle_return_gpr_loss +TRAMP_REAL_BEGIN(system_reset_idle_wake) + /* We are waking up from idle, so may clobber any volatile register */ + cmpwi cr1,r5,2 + bltlr cr1 /* no state loss, return to idle caller with r3=SRR1 */ + BRANCH_TO_C000(r12, DOTSYM(idle_return_gpr_loss)) #endif EXC_COMMON_BEGIN(system_reset_common) -- cgit v1.2.3 From acc8da4492ef9b9d60bbdf5f857ead9e84031b5c Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 16:33:20 +1000 Subject: powerpc/64s/exception: sreset move trampoline ahead of common code Follow convention and move tramp ahead of common. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index e5660f3e8331..848d39ccf8c0 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -884,6 +884,18 @@ TRAMP_REAL_BEGIN(system_reset_idle_wake) BRANCH_TO_C000(r12, DOTSYM(idle_return_gpr_loss)) #endif +#ifdef CONFIG_PPC_PSERIES +/* + * Vectors for the FWNMI option. Share common code. + */ +TRAMP_REAL_BEGIN(system_reset_fwnmi) + /* See comment at system_reset exception, don't turn on RI */ + EXCEPTION_PROLOG_0 PACA_EXNMI + EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 0, 0x100, 0, 0, 0 + EXCEPTION_PROLOG_2_REAL system_reset_common, EXC_STD, 0 + +#endif /* CONFIG_PPC_PSERIES */ + EXC_COMMON_BEGIN(system_reset_common) /* * Increment paca->in_nmi then enable MSR_RI. SLB or MCE will be able @@ -941,18 +953,6 @@ EXC_COMMON_BEGIN(system_reset_common) EXCEPTION_RESTORE_REGS EXC_STD RFI_TO_USER_OR_KERNEL -#ifdef CONFIG_PPC_PSERIES -/* - * Vectors for the FWNMI option. Share common code. - */ -TRAMP_REAL_BEGIN(system_reset_fwnmi) - /* See comment at system_reset exception, don't turn on RI */ - EXCEPTION_PROLOG_0 PACA_EXNMI - EXCEPTION_PROLOG_1 EXC_STD, PACA_EXNMI, 0, 0x100, 0, 0, 0 - EXCEPTION_PROLOG_2_REAL system_reset_common, EXC_STD, 0 - -#endif /* CONFIG_PPC_PSERIES */ - EXC_REAL_BEGIN(machine_check, 0x200, 0x100) /* This is moved out of line as it can be patched by FW, but -- cgit v1.2.3 From f34c9675ca594bea6f813872a470e1b8b077d454 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 16:33:21 +1000 Subject: powerpc/64s/exception: hmi remove special case macro No code change. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index 848d39ccf8c0..c6e1d1a88701 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -519,11 +519,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) * * There can be combinations, e.g., EXC_VIRT_OOL_MASKABLE_HV * - * The one unusual case is __EXC_REAL_OOL_HV_DIRECT, which is - * an OOL vector that branches to a specified handler rather than the usual - * trampoline that goes to common. It, and other underscore macros, should - * be used with care. - * * KVM handlers come in the following verieties: * TRAMP_KVM * TRAMP_KVM_SKIP @@ -614,12 +609,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_CAN_NAP) __EXC_REAL_OOL_MASKABLE(name, start, size); \ __TRAMP_REAL_OOL_MASKABLE(name, start, bitmask) -#define __EXC_REAL_OOL_HV_DIRECT(name, start, size, handler) \ - EXC_REAL_BEGIN(name, start, size); \ - EXCEPTION_PROLOG_0 PACA_EXGEN ; \ - b handler; \ - EXC_REAL_END(name, start, size) - #define __EXC_REAL_OOL_HV(name, start, size) \ __EXC_REAL_OOL(name, start, size) @@ -1720,7 +1709,10 @@ EXC_COMMON(emulation_assist_common, 0xe40, emulation_assist_interrupt) * first, and then eventaully from there to the trampoline to get into virtual * mode. */ -__EXC_REAL_OOL_HV_DIRECT(hmi_exception, 0xe60, 0x20, hmi_exception_early) +EXC_REAL_BEGIN(hmi_exception, 0xe60, 0x20) + EXCEPTION_PROLOG_0 PACA_EXGEN + b hmi_exception_early +EXC_REAL_END(hmi_exception, 0xe60, 0x20) __TRAMP_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60, IRQS_DISABLED) EXC_VIRT_NONE(0x4e60, 0x20) TRAMP_KVM_HV(PACA_EXGEN, 0xe60) -- cgit v1.2.3 From 293c2e27b999e431ad5f9df3386bea37b18fce53 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Fri, 28 Jun 2019 16:33:22 +1000 Subject: powerpc/64s/exception: simplify hmi control flow Branch to the relocated 0xc000 address early (still in real mode), to simplify subsequent branches. Have the virt mode handler avoid just 'windup' and redo the exception from scratch, rather than branching back to the trampoline. Rearrange the stack setup instruction location to match the system reset handler (e.g., right before EXCEPTION_PROLOG_COMMON). Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/exceptions-64s.S | 26 ++++++++++---------------- 1 file changed, 10 insertions(+), 16 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/exceptions-64s.S b/arch/powerpc/kernel/exceptions-64s.S index c6e1d1a88701..eee5bef736c8 100644 --- a/arch/powerpc/kernel/exceptions-64s.S +++ b/arch/powerpc/kernel/exceptions-64s.S @@ -260,17 +260,6 @@ END_FTR_SECTION_NESTED(ftr,ftr,943) mtctr reg; \ bctr -#ifdef CONFIG_RELOCATABLE -#define BRANCH_LINK_TO_FAR(label) \ - __LOAD_FAR_HANDLER(r12, label); \ - mtctr r12; \ - bctrl - -#else -#define BRANCH_LINK_TO_FAR(label) \ - bl label -#endif - #ifdef CONFIG_KVM_BOOK3S_64_HANDLER #ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE /* @@ -1713,22 +1702,26 @@ EXC_REAL_BEGIN(hmi_exception, 0xe60, 0x20) EXCEPTION_PROLOG_0 PACA_EXGEN b hmi_exception_early EXC_REAL_END(hmi_exception, 0xe60, 0x20) -__TRAMP_REAL_OOL_MASKABLE_HV(hmi_exception, 0xe60, IRQS_DISABLED) EXC_VIRT_NONE(0x4e60, 0x20) TRAMP_KVM_HV(PACA_EXGEN, 0xe60) TRAMP_REAL_BEGIN(hmi_exception_early) EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0xe60, 0, 0, 0 + mfctr r10 /* save ctr, even for !RELOCATABLE */ + BRANCH_TO_C000(r11, hmi_exception_early_common) + +EXC_COMMON_BEGIN(hmi_exception_early_common) + mtctr r10 /* Restore ctr */ + mfspr r11,SPRN_HSRR0 /* Save HSRR0 */ + mfspr r12,SPRN_HSRR1 /* Save HSRR1 */ mr r10,r1 /* Save r1 */ ld r1,PACAEMERGSP(r13) /* Use emergency stack for realmode */ subi r1,r1,INT_FRAME_SIZE /* alloc stack frame */ - mfspr r11,SPRN_HSRR0 /* Save HSRR0 */ - mfspr r12,SPRN_HSRR1 /* Save HSRR1 */ EXCEPTION_PROLOG_COMMON_1() /* We don't touch AMR here, we never go to virtual mode */ EXCEPTION_PROLOG_COMMON_2(PACA_EXGEN) EXCEPTION_PROLOG_COMMON_3(0xe60) addi r3,r1,STACK_FRAME_OVERHEAD - BRANCH_LINK_TO_FAR(DOTSYM(hmi_exception_realmode)) /* Function call ABI */ + bl hmi_exception_realmode cmpdi cr0,r3,0 bne 1f @@ -1742,7 +1735,8 @@ TRAMP_REAL_BEGIN(hmi_exception_early) */ EXCEPTION_RESTORE_REGS EXC_HV EXCEPTION_PROLOG_0 PACA_EXGEN - b tramp_real_hmi_exception + EXCEPTION_PROLOG_1 EXC_HV, PACA_EXGEN, 1, 0xe60, 0, 0, IRQS_DISABLED + EXCEPTION_PROLOG_2_REAL hmi_exception_common, EXC_HV, 1 EXC_COMMON_BEGIN(hmi_exception_common) EXCEPTION_COMMON(PACA_EXGEN, 0xe60) -- cgit v1.2.3 From fe7946ce0808eb0e43711f5db7d2d1599b362d02 Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sun, 23 Jun 2019 20:41:51 +1000 Subject: powerpc/64s: Rename PPC_INVALIDATE_ERAT to PPC_ISA_3_0_INVALIDATE_ERAT This makes it clear to the caller that it can only be used on POWER9 and later CPUs. Signed-off-by: Nicholas Piggin [mpe: Use "ISA_3_0" rather than "ARCH_300"] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/ppc-opcode.h | 2 +- arch/powerpc/kernel/mce_power.c | 3 +-- arch/powerpc/kvm/book3s_hv_builtin.c | 2 +- arch/powerpc/mm/book3s64/hash_native.c | 2 +- arch/powerpc/mm/book3s64/radix_tlb.c | 8 ++++---- arch/powerpc/platforms/powernv/idle.c | 2 +- 6 files changed, 9 insertions(+), 10 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 23f7ed796f38..14f43b6cf7ec 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -591,7 +591,7 @@ #define PPC_SLBIA(IH) stringify_in_c(.long PPC_INST_SLBIA | \ ((IH & 0x7) << 21)) -#define PPC_INVALIDATE_ERAT PPC_SLBIA(7) +#define PPC_ISA_3_0_INVALIDATE_ERAT PPC_SLBIA(7) #define VCMPEQUD_RC(vrt, vra, vrb) stringify_in_c(.long PPC_INST_VCMPEQUD | \ ___PPC_RT(vrt) | ___PPC_RA(vra) | \ diff --git a/arch/powerpc/kernel/mce_power.c b/arch/powerpc/kernel/mce_power.c index b5e876efe864..451f3e90e958 100644 --- a/arch/powerpc/kernel/mce_power.c +++ b/arch/powerpc/kernel/mce_power.c @@ -95,8 +95,7 @@ static void flush_erat(void) return; } #endif - /* PPC_INVALIDATE_ERAT can only be used on ISA v3 and newer */ - asm volatile(PPC_INVALIDATE_ERAT : : :"memory"); + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); } #define MCE_FLUSH_SLB 1 diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index a46286f73eec..ca4f006abd77 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -833,7 +833,7 @@ static void flush_guest_tlb(struct kvm *kvm) } } asm volatile("ptesync": : :"memory"); - asm volatile(PPC_INVALIDATE_ERAT : : :"memory"); + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); } void kvmppc_check_need_tlb_flush(struct kvm *kvm, int pcpu, diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c index 47caecdbbbac..0b447d96b911 100644 --- a/arch/powerpc/mm/book3s64/hash_native.c +++ b/arch/powerpc/mm/book3s64/hash_native.c @@ -116,7 +116,7 @@ static void tlbiel_all_isa300(unsigned int num_sets, unsigned int is) asm volatile("ptesync": : :"memory"); - asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT "; isync" : : :"memory"); } void hash__tlbiel_all(unsigned int action) diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index 4d841369399f..7539c714438e 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -87,7 +87,7 @@ void radix__tlbiel_all(unsigned int action) else WARN(1, "%s called on pre-POWER9 CPU\n", __func__); - asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT "; isync" : : :"memory"); } static __always_inline void __tlbiel_pid(unsigned long pid, int set, @@ -262,7 +262,7 @@ static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) __tlbiel_pid(pid, set, RIC_FLUSH_TLB); asm volatile("ptesync": : :"memory"); - asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT "; isync" : : :"memory"); } static inline void _tlbie_pid(unsigned long pid, unsigned long ric) @@ -314,7 +314,7 @@ static inline void _tlbiel_lpid(unsigned long lpid, unsigned long ric) __tlbiel_lpid(lpid, set, RIC_FLUSH_TLB); asm volatile("ptesync": : :"memory"); - asm volatile(PPC_INVALIDATE_ERAT "; isync" : : :"memory"); + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT "; isync" : : :"memory"); } static inline void _tlbie_lpid(unsigned long lpid, unsigned long ric) @@ -366,7 +366,7 @@ static inline void _tlbiel_lpid_guest(unsigned long lpid, unsigned long ric) __tlbiel_lpid_guest(lpid, set, RIC_FLUSH_TLB); asm volatile("ptesync": : :"memory"); - asm volatile(PPC_INVALIDATE_ERAT : : :"memory"); + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); } diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index 77f2e0a4ee37..f9ab89510766 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -720,7 +720,7 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on) * to reload MMCR0 (see mmcr0 comment above). */ if (!cpu_has_feature(CPU_FTR_POWER9_DD2_1)) { - asm volatile(PPC_INVALIDATE_ERAT); + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT); mtspr(SPRN_MMCR0, mmcr0); } -- cgit v1.2.3 From 6c46fcce39f0eb4830078c5f1db289dd7196f84a Mon Sep 17 00:00:00 2001 From: Nicholas Piggin Date: Sun, 23 Jun 2019 20:41:52 +1000 Subject: powerpc/64s/radix: keep kernel ERAT over local process/guest invalidates ISA v3.0 radix modes provide SLBIA variants which can invalidate ERAT for effPID!=0 or for effLPID!=0, which allows user and guest invalidations to retain kernel/host ERAT entries. Signed-off-by: Nicholas Piggin Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/ppc-opcode.h | 9 +++++++++ arch/powerpc/kvm/book3s_hv_builtin.c | 6 ++++-- arch/powerpc/mm/book3s64/radix_tlb.c | 6 +++--- 3 files changed, 16 insertions(+), 5 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 14f43b6cf7ec..971bdf84f6fc 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -591,7 +591,16 @@ #define PPC_SLBIA(IH) stringify_in_c(.long PPC_INST_SLBIA | \ ((IH & 0x7) << 21)) + +/* + * These may only be used on ISA v3.0 or later (aka. CPU_FTR_ARCH_300, radix + * implies CPU_FTR_ARCH_300). USER/GUEST invalidates may only be used by radix + * mode (on HPT these would also invalidate various SLBEs which may not be + * desired). + */ #define PPC_ISA_3_0_INVALIDATE_ERAT PPC_SLBIA(7) +#define PPC_RADIX_INVALIDATE_ERAT_USER PPC_SLBIA(3) +#define PPC_RADIX_INVALIDATE_ERAT_GUEST PPC_SLBIA(6) #define VCMPEQUD_RC(vrt, vra, vrb) stringify_in_c(.long PPC_INST_VCMPEQUD | \ ___PPC_RT(vrt) | ___PPC_RA(vra) | \ diff --git a/arch/powerpc/kvm/book3s_hv_builtin.c b/arch/powerpc/kvm/book3s_hv_builtin.c index ca4f006abd77..8fa93114d630 100644 --- a/arch/powerpc/kvm/book3s_hv_builtin.c +++ b/arch/powerpc/kvm/book3s_hv_builtin.c @@ -823,6 +823,8 @@ static void flush_guest_tlb(struct kvm *kvm) : : "r" (rb), "i" (1), "i" (1), "i" (0), "r" (0) : "memory"); } + asm volatile("ptesync": : :"memory"); + asm volatile(PPC_RADIX_INVALIDATE_ERAT_GUEST : : :"memory"); } else { for (set = 0; set < kvm->arch.tlb_sets; ++set) { /* R=0 PRS=0 RIC=0 */ @@ -831,9 +833,9 @@ static void flush_guest_tlb(struct kvm *kvm) "r" (0) : "memory"); rb += PPC_BIT(51); /* increment set number */ } + asm volatile("ptesync": : :"memory"); + asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); } - asm volatile("ptesync": : :"memory"); - asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); } void kvmppc_check_need_tlb_flush(struct kvm *kvm, int pcpu, diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index 7539c714438e..edf39e9a4ec4 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -262,7 +262,7 @@ static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) __tlbiel_pid(pid, set, RIC_FLUSH_TLB); asm volatile("ptesync": : :"memory"); - asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT "; isync" : : :"memory"); + asm volatile(PPC_RADIX_INVALIDATE_ERAT_USER "; isync" : : :"memory"); } static inline void _tlbie_pid(unsigned long pid, unsigned long ric) @@ -314,7 +314,7 @@ static inline void _tlbiel_lpid(unsigned long lpid, unsigned long ric) __tlbiel_lpid(lpid, set, RIC_FLUSH_TLB); asm volatile("ptesync": : :"memory"); - asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT "; isync" : : :"memory"); + asm volatile(PPC_RADIX_INVALIDATE_ERAT_GUEST "; isync" : : :"memory"); } static inline void _tlbie_lpid(unsigned long lpid, unsigned long ric) @@ -366,7 +366,7 @@ static inline void _tlbiel_lpid_guest(unsigned long lpid, unsigned long ric) __tlbiel_lpid_guest(lpid, set, RIC_FLUSH_TLB); asm volatile("ptesync": : :"memory"); - asm volatile(PPC_ISA_3_0_INVALIDATE_ERAT : : :"memory"); + asm volatile(PPC_RADIX_INVALIDATE_ERAT_GUEST : : :"memory"); } -- cgit v1.2.3 From 548c54acba5bd1388d50727a9a126a42d0cd4ad0 Mon Sep 17 00:00:00 2001 From: Mathieu Malaterre Date: Tue, 4 Jun 2019 13:00:36 +1000 Subject: powerpc: silence a -Wcast-function-type warning in dawr_write_file_bool In commit c1fe190c0672 ("powerpc: Add force enable of DAWR on P9 option") the following piece of code was added: smp_call_function((smp_call_func_t)set_dawr, &null_brk, 0); Since GCC 8 this triggers the following warning about incompatible function types: arch/powerpc/kernel/hw_breakpoint.c:408:21: error: cast between incompatible function types from 'int (*)(struct arch_hw_breakpoint *)' to 'void (*)(void *)' [-Werror=cast-function-type] Since the warning is there for a reason, and should not be hidden behind a cast, provide an intermediate callback function to avoid the warning. Fixes: c1fe190c0672 ("powerpc: Add force enable of DAWR on P9 option") Suggested-by: Christoph Hellwig Signed-off-by: Mathieu Malaterre Signed-off-by: Michael Neuling Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/hw_breakpoint.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index da307dd93ee3..ca3a2358b768 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -384,6 +384,11 @@ void hw_breakpoint_pmu_read(struct perf_event *bp) bool dawr_force_enable; EXPORT_SYMBOL_GPL(dawr_force_enable); +static void set_dawr_cb(void *info) +{ + set_dawr(info); +} + static ssize_t dawr_write_file_bool(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) @@ -403,7 +408,7 @@ static ssize_t dawr_write_file_bool(struct file *file, /* If we are clearing, make sure all CPUs have the DAWR cleared */ if (!dawr_force_enable) - smp_call_function((smp_call_func_t)set_dawr, &null_brk, 0); + smp_call_function(set_dawr_cb, &null_brk, 0); return rc; } -- cgit v1.2.3 From a278e7ea608bea5fe6df9b6ae91fa134655c5d2c Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Tue, 4 Jun 2019 13:00:37 +1000 Subject: powerpc: Fix compile issue with force DAWR If you compile with KVM but without CONFIG_HAVE_HW_BREAKPOINT you fail at linking with: arch/powerpc/kvm/book3s_hv_rmhandlers.o:(.text+0x708): undefined reference to `dawr_force_enable' This was caused by commit c1fe190c0672 ("powerpc: Add force enable of DAWR on P9 option"). This moves a bunch of code around to fix this. It moves a lot of the DAWR code in a new file and creates a new CONFIG_PPC_DAWR to enable compiling it. Fixes: c1fe190c0672 ("powerpc: Add force enable of DAWR on P9 option") Signed-off-by: Michael Neuling [mpe: Minor formatting in set_dawr()] Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig | 4 ++ arch/powerpc/include/asm/hw_breakpoint.h | 21 ++++--- arch/powerpc/kernel/Makefile | 1 + arch/powerpc/kernel/dawr.c | 101 +++++++++++++++++++++++++++++++ arch/powerpc/kernel/hw_breakpoint.c | 61 ------------------- arch/powerpc/kernel/process.c | 28 --------- arch/powerpc/kvm/Kconfig | 1 + 7 files changed, 121 insertions(+), 96 deletions(-) create mode 100644 arch/powerpc/kernel/dawr.c (limited to 'arch/powerpc') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 3adff91bc856..876902661c04 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -236,6 +236,7 @@ config PPC select OLD_SIGSUSPEND select PCI_DOMAINS if PCI select PCI_SYSCALL if PCI + select PPC_DAWR if PPC64 select RTC_LIB select SPARSE_IRQ select SYSCTL_EXCEPTION_TRACE @@ -372,6 +373,9 @@ config PPC_ADV_DEBUG_DAC_RANGE depends on PPC_ADV_DEBUG_REGS && 44x default y +config PPC_DAWR + bool + config ZONE_DMA bool default y if PPC_BOOK3E_64 diff --git a/arch/powerpc/include/asm/hw_breakpoint.h b/arch/powerpc/include/asm/hw_breakpoint.h index 0fe8c1e46bbc..41abdae6d079 100644 --- a/arch/powerpc/include/asm/hw_breakpoint.h +++ b/arch/powerpc/include/asm/hw_breakpoint.h @@ -90,18 +90,25 @@ static inline void hw_breakpoint_disable(void) extern void thread_change_pc(struct task_struct *tsk, struct pt_regs *regs); int hw_breakpoint_handler(struct die_args *args); -extern int set_dawr(struct arch_hw_breakpoint *brk); +#else /* CONFIG_HAVE_HW_BREAKPOINT */ +static inline void hw_breakpoint_disable(void) { } +static inline void thread_change_pc(struct task_struct *tsk, + struct pt_regs *regs) { } + +#endif /* CONFIG_HAVE_HW_BREAKPOINT */ + + +#ifdef CONFIG_PPC_DAWR extern bool dawr_force_enable; static inline bool dawr_enabled(void) { return dawr_force_enable; } - -#else /* CONFIG_HAVE_HW_BREAKPOINT */ -static inline void hw_breakpoint_disable(void) { } -static inline void thread_change_pc(struct task_struct *tsk, - struct pt_regs *regs) { } +int set_dawr(struct arch_hw_breakpoint *brk); +#else static inline bool dawr_enabled(void) { return false; } -#endif /* CONFIG_HAVE_HW_BREAKPOINT */ +static inline int set_dawr(struct arch_hw_breakpoint *brk) { return -1; } +#endif + #endif /* __KERNEL__ */ #endif /* _PPC_BOOK3S_64_HW_BREAKPOINT_H */ diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile index 0ea6c4aa3a20..56dfa7a2a6f2 100644 --- a/arch/powerpc/kernel/Makefile +++ b/arch/powerpc/kernel/Makefile @@ -56,6 +56,7 @@ obj-$(CONFIG_PPC64) += setup_64.o sys_ppc32.o \ obj-$(CONFIG_VDSO32) += vdso32/ obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o +obj-$(CONFIG_PPC_DAWR) += dawr.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o diff --git a/arch/powerpc/kernel/dawr.c b/arch/powerpc/kernel/dawr.c new file mode 100644 index 000000000000..5f66b95b6858 --- /dev/null +++ b/arch/powerpc/kernel/dawr.c @@ -0,0 +1,101 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * DAWR infrastructure + * + * Copyright 2019, Michael Neuling, IBM Corporation. + */ + +#include +#include +#include +#include +#include +#include +#include + +bool dawr_force_enable; +EXPORT_SYMBOL_GPL(dawr_force_enable); + +int set_dawr(struct arch_hw_breakpoint *brk) +{ + unsigned long dawr, dawrx, mrd; + + dawr = brk->address; + + dawrx = (brk->type & (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE)) + << (63 - 58); + dawrx |= ((brk->type & (HW_BRK_TYPE_TRANSLATE)) >> 2) << (63 - 59); + dawrx |= (brk->type & (HW_BRK_TYPE_PRIV_ALL)) >> 3; + /* + * DAWR length is stored in field MDR bits 48:53. Matches range in + * doublewords (64 bits) baised by -1 eg. 0b000000=1DW and + * 0b111111=64DW. + * brk->len is in bytes. + * This aligns up to double word size, shifts and does the bias. + */ + mrd = ((brk->len + 7) >> 3) - 1; + dawrx |= (mrd & 0x3f) << (63 - 53); + + if (ppc_md.set_dawr) + return ppc_md.set_dawr(dawr, dawrx); + + mtspr(SPRN_DAWR, dawr); + mtspr(SPRN_DAWRX, dawrx); + + return 0; +} + +static void set_dawr_cb(void *info) +{ + set_dawr(info); +} + +static ssize_t dawr_write_file_bool(struct file *file, + const char __user *user_buf, + size_t count, loff_t *ppos) +{ + struct arch_hw_breakpoint null_brk = {0, 0, 0}; + size_t rc; + + /* Send error to user if they hypervisor won't allow us to write DAWR */ + if (!dawr_force_enable && + firmware_has_feature(FW_FEATURE_LPAR) && + set_dawr(&null_brk) != H_SUCCESS) + return -ENODEV; + + rc = debugfs_write_file_bool(file, user_buf, count, ppos); + if (rc) + return rc; + + /* If we are clearing, make sure all CPUs have the DAWR cleared */ + if (!dawr_force_enable) + smp_call_function(set_dawr_cb, &null_brk, 0); + + return rc; +} + +static const struct file_operations dawr_enable_fops = { + .read = debugfs_read_file_bool, + .write = dawr_write_file_bool, + .open = simple_open, + .llseek = default_llseek, +}; + +static int __init dawr_force_setup(void) +{ + if (cpu_has_feature(CPU_FTR_DAWR)) { + /* Don't setup sysfs file for user control on P8 */ + dawr_force_enable = true; + return 0; + } + + if (PVR_VER(mfspr(SPRN_PVR)) == PVR_POWER9) { + /* Turn DAWR off by default, but allow admin to turn it on */ + debugfs_create_file_unsafe("dawr_enable_dangerous", 0600, + powerpc_debugfs_root, + &dawr_force_enable, + &dawr_enable_fops); + } + return 0; +} +arch_initcall(dawr_force_setup); diff --git a/arch/powerpc/kernel/hw_breakpoint.c b/arch/powerpc/kernel/hw_breakpoint.c index ca3a2358b768..95605a9c9a1e 100644 --- a/arch/powerpc/kernel/hw_breakpoint.c +++ b/arch/powerpc/kernel/hw_breakpoint.c @@ -380,64 +380,3 @@ void hw_breakpoint_pmu_read(struct perf_event *bp) { /* TODO */ } - -bool dawr_force_enable; -EXPORT_SYMBOL_GPL(dawr_force_enable); - -static void set_dawr_cb(void *info) -{ - set_dawr(info); -} - -static ssize_t dawr_write_file_bool(struct file *file, - const char __user *user_buf, - size_t count, loff_t *ppos) -{ - struct arch_hw_breakpoint null_brk = {0, 0, 0}; - size_t rc; - - /* Send error to user if they hypervisor won't allow us to write DAWR */ - if ((!dawr_force_enable) && - (firmware_has_feature(FW_FEATURE_LPAR)) && - (set_dawr(&null_brk) != H_SUCCESS)) - return -1; - - rc = debugfs_write_file_bool(file, user_buf, count, ppos); - if (rc) - return rc; - - /* If we are clearing, make sure all CPUs have the DAWR cleared */ - if (!dawr_force_enable) - smp_call_function(set_dawr_cb, &null_brk, 0); - - return rc; -} - -static const struct file_operations dawr_enable_fops = { - .read = debugfs_read_file_bool, - .write = dawr_write_file_bool, - .open = simple_open, - .llseek = default_llseek, -}; - -static int __init dawr_force_setup(void) -{ - dawr_force_enable = false; - - if (cpu_has_feature(CPU_FTR_DAWR)) { - /* Don't setup sysfs file for user control on P8 */ - dawr_force_enable = true; - return 0; - } - - if (PVR_VER(mfspr(SPRN_PVR)) == PVR_POWER9) { - /* Turn DAWR off by default, but allow admin to turn it on */ - dawr_force_enable = false; - debugfs_create_file_unsafe("dawr_enable_dangerous", 0600, - powerpc_debugfs_root, - &dawr_force_enable, - &dawr_enable_fops); - } - return 0; -} -arch_initcall(dawr_force_setup); diff --git a/arch/powerpc/kernel/process.c b/arch/powerpc/kernel/process.c index 87da40129927..03a2da35ce61 100644 --- a/arch/powerpc/kernel/process.c +++ b/arch/powerpc/kernel/process.c @@ -797,34 +797,6 @@ static inline int set_dabr(struct arch_hw_breakpoint *brk) return __set_dabr(dabr, dabrx); } -int set_dawr(struct arch_hw_breakpoint *brk) -{ - unsigned long dawr, dawrx, mrd; - - dawr = brk->address; - - dawrx = (brk->type & (HW_BRK_TYPE_READ | HW_BRK_TYPE_WRITE)) \ - << (63 - 58); //* read/write bits */ - dawrx |= ((brk->type & (HW_BRK_TYPE_TRANSLATE)) >> 2) \ - << (63 - 59); //* translate */ - dawrx |= (brk->type & (HW_BRK_TYPE_PRIV_ALL)) \ - >> 3; //* PRIM bits */ - /* dawr length is stored in field MDR bits 48:53. Matches range in - doublewords (64 bits) baised by -1 eg. 0b000000=1DW and - 0b111111=64DW. - brk->len is in bytes. - This aligns up to double word size, shifts and does the bias. - */ - mrd = ((brk->len + 7) >> 3) - 1; - dawrx |= (mrd & 0x3f) << (63 - 53); - - if (ppc_md.set_dawr) - return ppc_md.set_dawr(dawr, dawrx); - mtspr(SPRN_DAWR, dawr); - mtspr(SPRN_DAWRX, dawrx); - return 0; -} - void __set_breakpoint(struct arch_hw_breakpoint *brk) { memcpy(this_cpu_ptr(¤t_brk), brk, sizeof(*brk)); diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index f53997a8ca62..b8e13d5a4a31 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -38,6 +38,7 @@ config KVM_BOOK3S_32_HANDLER config KVM_BOOK3S_64_HANDLER bool select KVM_BOOK3S_HANDLER + select PPC_DAWR_FORCE_ENABLE config KVM_BOOK3S_PR_POSSIBLE bool -- cgit v1.2.3 From 24911acd64cee411c9e626d3d0ca0733805b009b Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sat, 29 Jun 2019 10:03:59 +0200 Subject: powerpc: remove device_to_mask() Use the dma_get_mask() helper from dma-mapping.h instead, as they are functionally identical. Signed-off-by: Christoph Hellwig Reviewed-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/iommu.h | 8 -------- arch/powerpc/kernel/dma-iommu.c | 4 ++-- arch/powerpc/platforms/pseries/vio.c | 4 ++-- 3 files changed, 4 insertions(+), 12 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/iommu.h b/arch/powerpc/include/asm/iommu.h index 0ac52392ed99..f98f2864b66a 100644 --- a/arch/powerpc/include/asm/iommu.h +++ b/arch/powerpc/include/asm/iommu.h @@ -327,13 +327,5 @@ extern bool iommu_fixed_is_weak; extern const struct dma_map_ops dma_iommu_ops; -static inline unsigned long device_to_mask(struct device *dev) -{ - if (dev->dma_mask && *dev->dma_mask) - return *dev->dma_mask; - /* Assume devices without mask can take 32 bit addresses */ - return 0xfffffffful; -} - #endif /* __KERNEL__ */ #endif /* _ASM_IOMMU_H */ diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 09231ef06d01..168af3a5b4b1 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -71,7 +71,7 @@ static dma_addr_t dma_iommu_map_page(struct device *dev, struct page *page, return dma_direct_map_page(dev, page, offset, size, direction, attrs); return iommu_map_page(dev, get_iommu_table_base(dev), page, offset, - size, device_to_mask(dev), direction, attrs); + size, dma_get_mask(dev), direction, attrs); } @@ -92,7 +92,7 @@ static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, if (dma_iommu_map_bypass(dev, attrs)) return dma_direct_map_sg(dev, sglist, nelems, direction, attrs); return ppc_iommu_map_sg(dev, get_iommu_table_base(dev), sglist, nelems, - device_to_mask(dev), direction, attrs); + dma_get_mask(dev), direction, attrs); } static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist, diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c index 141795275ccb..97c0e3e5eae5 100644 --- a/arch/powerpc/platforms/pseries/vio.c +++ b/arch/powerpc/platforms/pseries/vio.c @@ -524,7 +524,7 @@ static dma_addr_t vio_dma_iommu_map_page(struct device *dev, struct page *page, if (vio_cmo_alloc(viodev, roundup(size, IOMMU_PAGE_SIZE(tbl)))) goto out_fail; - ret = iommu_map_page(dev, tbl, page, offset, size, device_to_mask(dev), + ret = iommu_map_page(dev, tbl, page, offset, size, dma_get_mask(dev), direction, attrs); if (unlikely(ret == DMA_MAPPING_ERROR)) goto out_deallocate; @@ -564,7 +564,7 @@ static int vio_dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist, if (vio_cmo_alloc(viodev, alloc_size)) goto out_fail; - ret = ppc_iommu_map_sg(dev, tbl, sglist, nelems, device_to_mask(dev), + ret = ppc_iommu_map_sg(dev, tbl, sglist, nelems, dma_get_mask(dev), direction, attrs); if (unlikely(!ret)) goto out_deallocate; -- cgit v1.2.3 From efd176a04bef41aab5b3087e977fea2b69915174 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Tue, 7 May 2019 16:25:58 +1000 Subject: powerpc/pseries/dma: Allow SWIOTLB The commit 8617a5c5bc00 ("powerpc/dma: handle iommu bypass in dma_iommu_ops") merged direct DMA ops into the IOMMU DMA ops allowing SWIOTLB as well but only for mapping; the unmapping and bouncing parts were left unmodified. This adds missing direct unmapping calls to .unmap_page() and .unmap_sg(). This adds missing sync callbacks and directs them to the direct DMA hooks. Fixes: 8617a5c5bc00 ("powerpc/dma: handle iommu bypass in dma_iommu_ops") Signed-off-by: Alexey Kardashevskiy Signed-off-by: Thiago Jung Bauermann Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/dma-iommu.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/dma-iommu.c b/arch/powerpc/kernel/dma-iommu.c index 168af3a5b4b1..a0879674a9c8 100644 --- a/arch/powerpc/kernel/dma-iommu.c +++ b/arch/powerpc/kernel/dma-iommu.c @@ -82,6 +82,8 @@ static void dma_iommu_unmap_page(struct device *dev, dma_addr_t dma_handle, if (!dma_iommu_map_bypass(dev, attrs)) iommu_unmap_page(get_iommu_table_base(dev), dma_handle, size, direction, attrs); + else + dma_direct_unmap_page(dev, dma_handle, size, direction, attrs); } @@ -102,6 +104,8 @@ static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist, if (!dma_iommu_map_bypass(dev, attrs)) ppc_iommu_unmap_sg(get_iommu_table_base(dev), sglist, nelems, direction, attrs); + else + dma_direct_unmap_sg(dev, sglist, nelems, direction, attrs); } static bool dma_iommu_bypass_supported(struct device *dev, u64 mask) @@ -163,6 +167,34 @@ u64 dma_iommu_get_required_mask(struct device *dev) return mask; } +static void dma_iommu_sync_for_cpu(struct device *dev, dma_addr_t addr, + size_t size, enum dma_data_direction dir) +{ + if (dma_iommu_alloc_bypass(dev)) + dma_direct_sync_single_for_cpu(dev, addr, size, dir); +} + +static void dma_iommu_sync_for_device(struct device *dev, dma_addr_t addr, + size_t sz, enum dma_data_direction dir) +{ + if (dma_iommu_alloc_bypass(dev)) + dma_direct_sync_single_for_device(dev, addr, sz, dir); +} + +extern void dma_iommu_sync_sg_for_cpu(struct device *dev, + struct scatterlist *sgl, int nents, enum dma_data_direction dir) +{ + if (dma_iommu_alloc_bypass(dev)) + dma_direct_sync_sg_for_cpu(dev, sgl, nents, dir); +} + +extern void dma_iommu_sync_sg_for_device(struct device *dev, + struct scatterlist *sgl, int nents, enum dma_data_direction dir) +{ + if (dma_iommu_alloc_bypass(dev)) + dma_direct_sync_sg_for_device(dev, sgl, nents, dir); +} + const struct dma_map_ops dma_iommu_ops = { .alloc = dma_iommu_alloc_coherent, .free = dma_iommu_free_coherent, @@ -172,4 +204,8 @@ const struct dma_map_ops dma_iommu_ops = { .map_page = dma_iommu_map_page, .unmap_page = dma_iommu_unmap_page, .get_required_mask = dma_iommu_get_required_mask, + .sync_single_for_cpu = dma_iommu_sync_for_cpu, + .sync_single_for_device = dma_iommu_sync_for_device, + .sync_sg_for_cpu = dma_iommu_sync_sg_for_cpu, + .sync_sg_for_device = dma_iommu_sync_sg_for_device, }; -- cgit v1.2.3 From 1a047cc7e53cb10e4706c09f6e92b2fa911a2bf2 Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Tue, 7 May 2019 16:25:59 +1000 Subject: powerpc/pseries/dma: Enable SWIOTLB So far the pseries platforms has always been using IOMMU making SWIOTLB unnecessary. Now we want secure guests which means devices can only access certain areas of guest physical memory; we are going to use SWIOTLB for this purpose. This allows SWIOTLB for pseries. By default there is no change in behavior. This enables SWIOTLB when the "swiotlb" kernel parameter is set to "force". With the SWIOTLB enabled, the kernel creates a directly mapped DMA window (using the usual DDW mechanism) and implements SWIOTLB on top of that. Signed-off-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/Kconfig | 1 + arch/powerpc/platforms/pseries/setup.c | 5 +++++ 2 files changed, 6 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index 9c6b3d860518..b9e8b608de01 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -23,6 +23,7 @@ config PPC_PSERIES select ARCH_RANDOM select PPC_DOORBELL select FORCE_SMP + select SWIOTLB default y config PPC_SPLPAR diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index e4f0dfd4ae33..30d72b587ac5 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -71,6 +72,7 @@ #include #include #include +#include #include "pseries.h" #include "../../../../drivers/pci/pci.h" @@ -797,6 +799,9 @@ static void __init pSeries_setup_arch(void) } ppc_md.pcibios_root_bridge_prepare = pseries_root_bridge_prepare; + + if (swiotlb_force == SWIOTLB_FORCE) + ppc_swiotlb_enable = 1; } static void pseries_panic(char *str) -- cgit v1.2.3 From dead1c845dbe97e0061dae2017eaf3bd8f8f06ee Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Wed, 26 Jun 2019 12:37:46 +1000 Subject: powerpc/pci/of: Parse unassigned resources The pseries platform uses the PCI_PROBE_DEVTREE method of PCI probing which reads "assigned-addresses" of every PCI device and initializes the device resources. However if the property is missing or zero sized, then there is no fallback of any kind and the PCI resources remain undiscovered, i.e. pdev->resource[] array remains empty. This adds a fallback which parses the "reg" property in pretty much same way except it marks resources as "unset" which later make Linux assign those resources proper addresses. This has an effect when: 1. a hypervisor failed to assign any resource for a device; 2. /chosen/linux,pci-probe-only=0 is in the DT so the system may try assigning a resource. Neither is likely to happen under PowerVM. Signed-off-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/pci_of_scan.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/pci_of_scan.c b/arch/powerpc/kernel/pci_of_scan.c index 64ad92016b63..bd78f325a636 100644 --- a/arch/powerpc/kernel/pci_of_scan.c +++ b/arch/powerpc/kernel/pci_of_scan.c @@ -82,10 +82,16 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) const __be32 *addrs; u32 i; int proplen; + bool mark_unset = false; addrs = of_get_property(node, "assigned-addresses", &proplen); - if (!addrs) - return; + if (!addrs || !proplen) { + addrs = of_get_property(node, "reg", &proplen); + if (!addrs || !proplen) + return; + mark_unset = true; + } + pr_debug(" parse addresses (%d bytes) @ %p\n", proplen, addrs); for (; proplen >= 20; proplen -= 20, addrs += 5) { flags = pci_parse_of_flags(of_read_number(addrs, 1), 0); @@ -110,6 +116,8 @@ static void of_pci_parse_addrs(struct device_node *node, struct pci_dev *dev) continue; } res->flags = flags; + if (mark_unset) + res->flags |= IORESOURCE_UNSET; res->name = pci_name(dev); region.start = base; region.end = base + size - 1; -- cgit v1.2.3 From 5636427d087a55842c1a199dfb839e6545d30e5d Mon Sep 17 00:00:00 2001 From: Alexey Kardashevskiy Date: Fri, 28 Jun 2019 16:53:00 +1000 Subject: powerpc/powernv: Fix stale iommu table base after VFIO The powernv platform uses @dma_iommu_ops for non-bypass DMA. These ops need an iommu_table pointer which is stored in dev->archdata.iommu_table_base. It is initialized during pcibios_setup_device() which handles boot time devices. However when a device is taken from the system in order to pass it through, the default IOMMU table is destroyed but the pointer in a device is not updated; also when a device is returned back to the system, a new table pointer is not stored in dev->archdata.iommu_table_base either. So when a just returned device tries using IOMMU, it crashes on accessing stale iommu_table or its members. This calls set_iommu_table_base() when the default window is created. Note it used to be there before but was wrongly removed (see "fixes"). It did not appear before as these days most devices simply use bypass. This adds set_iommu_table_base(NULL) when a device is taken from the system to make it clear that IOMMU DMA cannot be used past that point. Fixes: c4e9d3c1e65a ("powerpc/powernv/pseries: Rework device adding to IOMMU groups") Cc: stable@vger.kernel.org # v5.0+ Signed-off-by: Alexey Kardashevskiy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/pci-ioda.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c index 6b0caa2d0425..dc4a3c550446 100644 --- a/arch/powerpc/platforms/powernv/pci-ioda.c +++ b/arch/powerpc/platforms/powernv/pci-ioda.c @@ -2462,6 +2462,14 @@ static long pnv_pci_ioda2_setup_default_config(struct pnv_ioda_pe *pe) if (!pnv_iommu_bypass_disabled) pnv_pci_ioda2_set_bypass(pe, true); + /* + * Set table base for the case of IOMMU DMA use. Usually this is done + * from dma_dev_setup() which is not called when a device is returned + * from VFIO so do it here. + */ + if (pe->pdev) + set_iommu_table_base(&pe->pdev->dev, tbl); + return 0; } @@ -2549,6 +2557,8 @@ static void pnv_ioda2_take_ownership(struct iommu_table_group *table_group) pnv_pci_ioda2_unset_window(&pe->table_group, 0); if (pe->pbus) pnv_ioda_setup_bus_dma(pe, pe->pbus); + else if (pe->pdev) + set_iommu_table_base(&pe->pdev->dev, NULL); iommu_tce_table_put(tbl); } -- cgit v1.2.3 From 3fefd1cd95df04da67c83c1cb93b663f04b3324f Mon Sep 17 00:00:00 2001 From: Michael Neuling Date: Thu, 20 Jun 2019 16:00:40 +1000 Subject: KVM: PPC: Book3S HV: Fix CR0 setting in TM emulation When emulating tsr, treclaim and trechkpt, we incorrectly set CR0. The code currently sets: CR0 <- 00 || MSR[TS] but according to the ISA it should be: CR0 <- 0 || MSR[TS] || 0 This fixes the bit shift to put the bits in the correct location. This is a data integrity issue as CR0 is corrupted. Fixes: 4bb3c7a0208f ("KVM: PPC: Book3S HV: Work around transactional memory bugs in POWER9") Cc: stable@vger.kernel.org # v4.17+ Tested-by: Suraj Jitindar Singh Signed-off-by: Michael Neuling Signed-off-by: Michael Ellerman --- arch/powerpc/kvm/book3s_hv_tm.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kvm/book3s_hv_tm.c b/arch/powerpc/kvm/book3s_hv_tm.c index 888e2609e3f1..31cd0f327c8a 100644 --- a/arch/powerpc/kvm/book3s_hv_tm.c +++ b/arch/powerpc/kvm/book3s_hv_tm.c @@ -131,7 +131,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu) } /* Set CR0 to indicate previous transactional state */ vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) | - (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 28); + (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29); /* L=1 => tresume, L=0 => tsuspend */ if (instr & (1 << 21)) { if (MSR_TM_SUSPENDED(msr)) @@ -175,7 +175,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu) /* Set CR0 to indicate previous transactional state */ vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) | - (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 28); + (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29); vcpu->arch.shregs.msr &= ~MSR_TS_MASK; return RESUME_GUEST; @@ -205,7 +205,7 @@ int kvmhv_p9_tm_emulation(struct kvm_vcpu *vcpu) /* Set CR0 to indicate previous transactional state */ vcpu->arch.regs.ccr = (vcpu->arch.regs.ccr & 0x0fffffff) | - (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 28); + (((msr & MSR_TS_MASK) >> MSR_TS_S_LG) << 29); vcpu->arch.shregs.msr = msr | MSR_TS_S; return RESUME_GUEST; } -- cgit v1.2.3 From 6fbcdd59094ade30db63f32316e9502425d7b256 Mon Sep 17 00:00:00 2001 From: Suraj Jitindar Singh Date: Wed, 6 Mar 2019 12:10:38 +1100 Subject: powerpc: Add barrier_nospec to raw_copy_in_user() Commit ddf35cf3764b ("powerpc: Use barrier_nospec in copy_from_user()") Added barrier_nospec before loading from user-controlled pointers. The intention was to order the load from the potentially user-controlled pointer vs a previous branch based on an access_ok() check or similar. In order to achieve the same result, add a barrier_nospec to the raw_copy_in_user() function before loading from such a user-controlled pointer. Fixes: ddf35cf3764b ("powerpc: Use barrier_nospec in copy_from_user()") Signed-off-by: Suraj Jitindar Singh Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/uaccess.h | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/uaccess.h b/arch/powerpc/include/asm/uaccess.h index 76f34346b642..8b03eb44e876 100644 --- a/arch/powerpc/include/asm/uaccess.h +++ b/arch/powerpc/include/asm/uaccess.h @@ -312,6 +312,7 @@ raw_copy_in_user(void __user *to, const void __user *from, unsigned long n) { unsigned long ret; + barrier_nospec(); allow_user_access(to, from, n); ret = __copy_tofrom_user(to, from, n); prevent_user_access(to, from, n); -- cgit v1.2.3 From 3ab3a0689e74e6aa5b41360bc18861040ddef5b1 Mon Sep 17 00:00:00 2001 From: Christian Lamparter Date: Sat, 15 Jun 2019 17:23:13 +0200 Subject: powerpc/4xx/uic: clear pending interrupt after irq type/pol change When testing out gpio-keys with a button, a spurious interrupt (and therefore a key press or release event) gets triggered as soon as the driver enables the irq line for the first time. This patch clears any potential bogus generated interrupt that was caused by the switching of the associated irq's type and polarity. Signed-off-by: Christian Lamparter Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/4xx/uic.c | 1 + 1 file changed, 1 insertion(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/4xx/uic.c b/arch/powerpc/platforms/4xx/uic.c index 8b4dd0da0839..9e27cfe27026 100644 --- a/arch/powerpc/platforms/4xx/uic.c +++ b/arch/powerpc/platforms/4xx/uic.c @@ -158,6 +158,7 @@ static int uic_set_irq_type(struct irq_data *d, unsigned int flow_type) mtdcr(uic->dcrbase + UIC_PR, pr); mtdcr(uic->dcrbase + UIC_TR, tr); + mtdcr(uic->dcrbase + UIC_SR, ~mask); raw_spin_unlock_irqrestore(&uic->lock, flags); -- cgit v1.2.3 From 14b2f7d908c374df57792410bc0100dd71be4e5c Mon Sep 17 00:00:00 2001 From: Krzysztof Kozlowski Date: Tue, 4 Jun 2019 10:00:33 +0200 Subject: powerpc/configs: Remove useless UEVENT_HELPER_PATH Remove the CONFIG_UEVENT_HELPER_PATH because: 1. It is disabled since commit 1be01d4a5714 ("driver: base: Disable CONFIG_UEVENT_HELPER by default") as its dependency (UEVENT_HELPER) was made default to 'n', 2. It is not recommended (help message: "This should not be used today [...] creates a high system load") and was kept only for ancient userland, 3. Certain userland specifically requests it to be disabled (systemd README: "Legacy hotplug slows down the system and confuses udev"). Signed-off-by: Krzysztof Kozlowski Acked-by: Geert Uytterhoeven Signed-off-by: Michael Ellerman --- arch/powerpc/configs/40x/acadia_defconfig | 1 - arch/powerpc/configs/40x/ep405_defconfig | 1 - arch/powerpc/configs/40x/kilauea_defconfig | 1 - arch/powerpc/configs/40x/klondike_defconfig | 1 - arch/powerpc/configs/40x/makalu_defconfig | 1 - arch/powerpc/configs/40x/obs600_defconfig | 1 - arch/powerpc/configs/40x/virtex_defconfig | 1 - arch/powerpc/configs/40x/walnut_defconfig | 1 - arch/powerpc/configs/44x/akebono_defconfig | 1 - arch/powerpc/configs/44x/arches_defconfig | 1 - arch/powerpc/configs/44x/bamboo_defconfig | 1 - arch/powerpc/configs/44x/bluestone_defconfig | 1 - arch/powerpc/configs/44x/canyonlands_defconfig | 1 - arch/powerpc/configs/44x/currituck_defconfig | 1 - arch/powerpc/configs/44x/ebony_defconfig | 1 - arch/powerpc/configs/44x/eiger_defconfig | 1 - arch/powerpc/configs/44x/fsp2_defconfig | 1 - arch/powerpc/configs/44x/icon_defconfig | 1 - arch/powerpc/configs/44x/iss476-smp_defconfig | 1 - arch/powerpc/configs/44x/katmai_defconfig | 1 - arch/powerpc/configs/44x/rainier_defconfig | 1 - arch/powerpc/configs/44x/redwood_defconfig | 1 - arch/powerpc/configs/44x/sam440ep_defconfig | 1 - arch/powerpc/configs/44x/sequoia_defconfig | 1 - arch/powerpc/configs/44x/taishan_defconfig | 1 - arch/powerpc/configs/44x/virtex5_defconfig | 1 - arch/powerpc/configs/44x/warp_defconfig | 1 - arch/powerpc/configs/52xx/cm5200_defconfig | 1 - arch/powerpc/configs/52xx/lite5200b_defconfig | 1 - arch/powerpc/configs/52xx/motionpro_defconfig | 1 - arch/powerpc/configs/52xx/pcm030_defconfig | 1 - arch/powerpc/configs/52xx/tqm5200_defconfig | 1 - arch/powerpc/configs/83xx/asp8347_defconfig | 1 - arch/powerpc/configs/83xx/mpc8313_rdb_defconfig | 1 - arch/powerpc/configs/83xx/mpc8315_rdb_defconfig | 1 - arch/powerpc/configs/83xx/mpc832x_mds_defconfig | 1 - arch/powerpc/configs/83xx/mpc832x_rdb_defconfig | 1 - arch/powerpc/configs/83xx/mpc834x_itx_defconfig | 1 - arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig | 1 - arch/powerpc/configs/83xx/mpc834x_mds_defconfig | 1 - arch/powerpc/configs/83xx/mpc836x_mds_defconfig | 1 - arch/powerpc/configs/83xx/mpc836x_rdk_defconfig | 1 - arch/powerpc/configs/83xx/mpc837x_mds_defconfig | 1 - arch/powerpc/configs/83xx/mpc837x_rdb_defconfig | 1 - arch/powerpc/configs/85xx/ge_imp3a_defconfig | 1 - arch/powerpc/configs/85xx/ksi8560_defconfig | 1 - arch/powerpc/configs/85xx/mpc8540_ads_defconfig | 1 - arch/powerpc/configs/85xx/mpc8560_ads_defconfig | 1 - arch/powerpc/configs/85xx/mpc85xx_cds_defconfig | 1 - arch/powerpc/configs/85xx/sbc8548_defconfig | 1 - arch/powerpc/configs/85xx/stx_gp3_defconfig | 1 - arch/powerpc/configs/85xx/tqm8548_defconfig | 1 - arch/powerpc/configs/85xx/xes_mpc85xx_defconfig | 1 - arch/powerpc/configs/adder875_defconfig | 1 - arch/powerpc/configs/amigaone_defconfig | 1 - arch/powerpc/configs/cell_defconfig | 1 - arch/powerpc/configs/chrp32_defconfig | 1 - arch/powerpc/configs/ep8248e_defconfig | 1 - arch/powerpc/configs/ep88xc_defconfig | 1 - arch/powerpc/configs/fsl-emb-nonhw.config | 1 - arch/powerpc/configs/g5_defconfig | 1 - arch/powerpc/configs/gamecube_defconfig | 1 - arch/powerpc/configs/holly_defconfig | 1 - arch/powerpc/configs/linkstation_defconfig | 1 - arch/powerpc/configs/maple_defconfig | 1 - arch/powerpc/configs/mgcoge_defconfig | 1 - arch/powerpc/configs/mpc512x_defconfig | 1 - arch/powerpc/configs/mpc5200_defconfig | 1 - arch/powerpc/configs/mpc7448_hpc2_defconfig | 1 - arch/powerpc/configs/mpc8272_ads_defconfig | 1 - arch/powerpc/configs/mpc83xx_defconfig | 1 - arch/powerpc/configs/mpc885_ads_defconfig | 1 - arch/powerpc/configs/mvme5100_defconfig | 1 - arch/powerpc/configs/pasemi_defconfig | 1 - arch/powerpc/configs/pmac32_defconfig | 1 - arch/powerpc/configs/powernv_defconfig | 1 - arch/powerpc/configs/ppc40x_defconfig | 1 - arch/powerpc/configs/ppc44x_defconfig | 1 - arch/powerpc/configs/ppc64_defconfig | 1 - arch/powerpc/configs/ppc64e_defconfig | 1 - arch/powerpc/configs/ppc6xx_defconfig | 1 - arch/powerpc/configs/pq2fads_defconfig | 1 - arch/powerpc/configs/ps3_defconfig | 1 - arch/powerpc/configs/pseries_defconfig | 1 - arch/powerpc/configs/skiroot_defconfig | 1 - arch/powerpc/configs/storcenter_defconfig | 1 - arch/powerpc/configs/tqm8xx_defconfig | 1 - arch/powerpc/configs/wii_defconfig | 1 - 88 files changed, 88 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/configs/40x/acadia_defconfig b/arch/powerpc/configs/40x/acadia_defconfig index e57344c3b0d7..5a75e4f14273 100644 --- a/arch/powerpc/configs/40x/acadia_defconfig +++ b/arch/powerpc/configs/40x/acadia_defconfig @@ -22,7 +22,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/40x/ep405_defconfig b/arch/powerpc/configs/40x/ep405_defconfig index 0f66f8a87be8..e2691c5db766 100644 --- a/arch/powerpc/configs/40x/ep405_defconfig +++ b/arch/powerpc/configs/40x/ep405_defconfig @@ -21,7 +21,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/40x/kilauea_defconfig b/arch/powerpc/configs/40x/kilauea_defconfig index 3da091f651d6..949989ef2322 100644 --- a/arch/powerpc/configs/40x/kilauea_defconfig +++ b/arch/powerpc/configs/40x/kilauea_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/40x/klondike_defconfig b/arch/powerpc/configs/40x/klondike_defconfig index caab658d1da1..4347a87088dc 100644 --- a/arch/powerpc/configs/40x/klondike_defconfig +++ b/arch/powerpc/configs/40x/klondike_defconfig @@ -14,7 +14,6 @@ CONFIG_APM8018X=y # CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set CONFIG_MATH_EMULATION=y # CONFIG_SUSPEND is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=35000 CONFIG_SCSI=y diff --git a/arch/powerpc/configs/40x/makalu_defconfig b/arch/powerpc/configs/40x/makalu_defconfig index e0b1489b7c7b..90b759bbf426 100644 --- a/arch/powerpc/configs/40x/makalu_defconfig +++ b/arch/powerpc/configs/40x/makalu_defconfig @@ -21,7 +21,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/40x/obs600_defconfig b/arch/powerpc/configs/40x/obs600_defconfig index 38d3d7769a2f..881c300c011d 100644 --- a/arch/powerpc/configs/40x/obs600_defconfig +++ b/arch/powerpc/configs/40x/obs600_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/40x/virtex_defconfig b/arch/powerpc/configs/40x/virtex_defconfig index a2b2770eee8f..5e7c61d1d7d0 100644 --- a/arch/powerpc/configs/40x/virtex_defconfig +++ b/arch/powerpc/configs/40x/virtex_defconfig @@ -31,7 +31,6 @@ CONFIG_NETFILTER=y CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_MANGLE=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 diff --git a/arch/powerpc/configs/40x/walnut_defconfig b/arch/powerpc/configs/40x/walnut_defconfig index 6faa03cd661c..0ed46704b9fa 100644 --- a/arch/powerpc/configs/40x/walnut_defconfig +++ b/arch/powerpc/configs/40x/walnut_defconfig @@ -19,7 +19,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/akebono_defconfig b/arch/powerpc/configs/44x/akebono_defconfig index 9fcd361607e2..2fa553ebfdc9 100644 --- a/arch/powerpc/configs/44x/akebono_defconfig +++ b/arch/powerpc/configs/44x/akebono_defconfig @@ -33,7 +33,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_CONNECTOR=y diff --git a/arch/powerpc/configs/44x/arches_defconfig b/arch/powerpc/configs/44x/arches_defconfig index 6bba1a55b827..5a1b9ee18075 100644 --- a/arch/powerpc/configs/44x/arches_defconfig +++ b/arch/powerpc/configs/44x/arches_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/bamboo_defconfig b/arch/powerpc/configs/44x/bamboo_defconfig index 6f3a6ecc81e7..22e1ef5272ab 100644 --- a/arch/powerpc/configs/44x/bamboo_defconfig +++ b/arch/powerpc/configs/44x/bamboo_defconfig @@ -22,7 +22,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=35000 diff --git a/arch/powerpc/configs/44x/bluestone_defconfig b/arch/powerpc/configs/44x/bluestone_defconfig index 6b77aea79b6c..8006a5728afd 100644 --- a/arch/powerpc/configs/44x/bluestone_defconfig +++ b/arch/powerpc/configs/44x/bluestone_defconfig @@ -20,7 +20,6 @@ CONFIG_INET=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/canyonlands_defconfig b/arch/powerpc/configs/44x/canyonlands_defconfig index d427cee027a6..86f34ea4173a 100644 --- a/arch/powerpc/configs/44x/canyonlands_defconfig +++ b/arch/powerpc/configs/44x/canyonlands_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/currituck_defconfig b/arch/powerpc/configs/44x/currituck_defconfig index 5f1df5fe4453..ce3ec5a2cd15 100644 --- a/arch/powerpc/configs/44x/currituck_defconfig +++ b/arch/powerpc/configs/44x/currituck_defconfig @@ -31,7 +31,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_CONNECTOR=y diff --git a/arch/powerpc/configs/44x/ebony_defconfig b/arch/powerpc/configs/44x/ebony_defconfig index e2b6578993d5..f67447c92e6f 100644 --- a/arch/powerpc/configs/44x/ebony_defconfig +++ b/arch/powerpc/configs/44x/ebony_defconfig @@ -20,7 +20,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/44x/eiger_defconfig b/arch/powerpc/configs/44x/eiger_defconfig index f593258806ad..5dbd83a1c11b 100644 --- a/arch/powerpc/configs/44x/eiger_defconfig +++ b/arch/powerpc/configs/44x/eiger_defconfig @@ -25,7 +25,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/fsp2_defconfig b/arch/powerpc/configs/44x/fsp2_defconfig index bae6b26bcfba..e49114f0e526 100644 --- a/arch/powerpc/configs/44x/fsp2_defconfig +++ b/arch/powerpc/configs/44x/fsp2_defconfig @@ -44,7 +44,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set CONFIG_VLAN_8021Q=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_CONNECTOR=y diff --git a/arch/powerpc/configs/44x/icon_defconfig b/arch/powerpc/configs/44x/icon_defconfig index 4453a4590b1a..fa5378af44f9 100644 --- a/arch/powerpc/configs/44x/icon_defconfig +++ b/arch/powerpc/configs/44x/icon_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/iss476-smp_defconfig b/arch/powerpc/configs/44x/iss476-smp_defconfig index d24bfa6ecd62..aae879c21239 100644 --- a/arch/powerpc/configs/44x/iss476-smp_defconfig +++ b/arch/powerpc/configs/44x/iss476-smp_defconfig @@ -33,7 +33,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/44x/katmai_defconfig b/arch/powerpc/configs/44x/katmai_defconfig index 5d3f685a7af8..56eddca998c6 100644 --- a/arch/powerpc/configs/44x/katmai_defconfig +++ b/arch/powerpc/configs/44x/katmai_defconfig @@ -22,7 +22,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/rainier_defconfig b/arch/powerpc/configs/44x/rainier_defconfig index 7b8355a5698d..369bfd2e451d 100644 --- a/arch/powerpc/configs/44x/rainier_defconfig +++ b/arch/powerpc/configs/44x/rainier_defconfig @@ -23,7 +23,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/redwood_defconfig b/arch/powerpc/configs/44x/redwood_defconfig index 918cfb63f0c8..8be95f6fe3a7 100644 --- a/arch/powerpc/configs/44x/redwood_defconfig +++ b/arch/powerpc/configs/44x/redwood_defconfig @@ -25,7 +25,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/sam440ep_defconfig b/arch/powerpc/configs/44x/sam440ep_defconfig index 63302fbd184d..974a4f038cda 100644 --- a/arch/powerpc/configs/44x/sam440ep_defconfig +++ b/arch/powerpc/configs/44x/sam440ep_defconfig @@ -27,7 +27,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/44x/sequoia_defconfig b/arch/powerpc/configs/44x/sequoia_defconfig index f34fee9464e5..10e517b69fa4 100644 --- a/arch/powerpc/configs/44x/sequoia_defconfig +++ b/arch/powerpc/configs/44x/sequoia_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/taishan_defconfig b/arch/powerpc/configs/44x/taishan_defconfig index 42cc7b4ed95f..cd08f3ddd609 100644 --- a/arch/powerpc/configs/44x/taishan_defconfig +++ b/arch/powerpc/configs/44x/taishan_defconfig @@ -22,7 +22,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/44x/virtex5_defconfig b/arch/powerpc/configs/44x/virtex5_defconfig index 99cc3dc02df1..1f74079e1703 100644 --- a/arch/powerpc/configs/44x/virtex5_defconfig +++ b/arch/powerpc/configs/44x/virtex5_defconfig @@ -30,7 +30,6 @@ CONFIG_NETFILTER=y CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_FILTER=m CONFIG_IP_NF_MANGLE=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 diff --git a/arch/powerpc/configs/44x/warp_defconfig b/arch/powerpc/configs/44x/warp_defconfig index 6ae88d4879bf..af66c69c49fe 100644 --- a/arch/powerpc/configs/44x/warp_defconfig +++ b/arch/powerpc/configs/44x/warp_defconfig @@ -26,7 +26,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_VLAN_8021Q=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/52xx/cm5200_defconfig b/arch/powerpc/configs/52xx/cm5200_defconfig index 73948e88ac82..2412a6bf7ee6 100644 --- a/arch/powerpc/configs/52xx/cm5200_defconfig +++ b/arch/powerpc/configs/52xx/cm5200_defconfig @@ -23,7 +23,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/52xx/lite5200b_defconfig b/arch/powerpc/configs/52xx/lite5200b_defconfig index 6fc7f786c83c..63368e677506 100644 --- a/arch/powerpc/configs/52xx/lite5200b_defconfig +++ b/arch/powerpc/configs/52xx/lite5200b_defconfig @@ -26,7 +26,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/52xx/motionpro_defconfig b/arch/powerpc/configs/52xx/motionpro_defconfig index ae2a1f74103b..72762da94846 100644 --- a/arch/powerpc/configs/52xx/motionpro_defconfig +++ b/arch/powerpc/configs/52xx/motionpro_defconfig @@ -23,7 +23,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/52xx/pcm030_defconfig b/arch/powerpc/configs/52xx/pcm030_defconfig index 1554de6968ca..303600ff1fdb 100644 --- a/arch/powerpc/configs/52xx/pcm030_defconfig +++ b/arch/powerpc/configs/52xx/pcm030_defconfig @@ -36,7 +36,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/52xx/tqm5200_defconfig b/arch/powerpc/configs/52xx/tqm5200_defconfig index 0777e6efd22d..a3c8ca74032c 100644 --- a/arch/powerpc/configs/52xx/tqm5200_defconfig +++ b/arch/powerpc/configs/52xx/tqm5200_defconfig @@ -27,7 +27,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/83xx/asp8347_defconfig b/arch/powerpc/configs/83xx/asp8347_defconfig index dd884df32dfd..10192410b33c 100644 --- a/arch/powerpc/configs/83xx/asp8347_defconfig +++ b/arch/powerpc/configs/83xx/asp8347_defconfig @@ -27,7 +27,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_REDBOOT_PARTS=y diff --git a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig index 9dffb2e7f735..16a42e2267fb 100644 --- a/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc8313_rdb_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig index a42232732c6d..80d40ae668eb 100644 --- a/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc8315_rdb_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig index 4f914906ee4b..e94555452fb2 100644 --- a/arch/powerpc/configs/83xx/mpc832x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc832x_mds_defconfig @@ -26,7 +26,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig index a484eb8401e8..1715ff547442 100644 --- a/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc832x_rdb_defconfig @@ -27,7 +27,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig index 37f4d93b3f81..e65c0057147f 100644 --- a/arch/powerpc/configs/83xx/mpc834x_itx_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_itx_defconfig @@ -25,7 +25,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CFI=y diff --git a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig index 7adb6708a761..17714bf0ed40 100644 --- a/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_itxgp_defconfig @@ -25,7 +25,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CFI=y diff --git a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig index d7ce3551529d..e2ff684d8792 100644 --- a/arch/powerpc/configs/83xx/mpc834x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc834x_mds_defconfig @@ -26,7 +26,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig index 92134cee3f37..3eceb6db2982 100644 --- a/arch/powerpc/configs/83xx/mpc836x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc836x_mds_defconfig @@ -25,7 +25,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig index 97f7ea5f205f..093df33f9455 100644 --- a/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig +++ b/arch/powerpc/configs/83xx/mpc836x_rdk_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig index ee7510a33d06..3f5e5d10789f 100644 --- a/arch/powerpc/configs/83xx/mpc837x_mds_defconfig +++ b/arch/powerpc/configs/83xx/mpc837x_mds_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig index 8966a9af4230..dad53ef86b49 100644 --- a/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig +++ b/arch/powerpc/configs/83xx/mpc837x_rdb_defconfig @@ -26,7 +26,6 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/85xx/ge_imp3a_defconfig b/arch/powerpc/configs/85xx/ge_imp3a_defconfig index d70b60314dad..920f37316fdb 100644 --- a/arch/powerpc/configs/85xx/ge_imp3a_defconfig +++ b/arch/powerpc/configs/85xx/ge_imp3a_defconfig @@ -65,7 +65,6 @@ CONFIG_INET6_AH=m CONFIG_INET6_IPCOMP=m CONFIG_IPV6_TUNNEL=m CONFIG_NET_PKTGEN=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_BLOCK=y CONFIG_MTD_CFI=y diff --git a/arch/powerpc/configs/85xx/ksi8560_defconfig b/arch/powerpc/configs/85xx/ksi8560_defconfig index 9ce6f48cfb61..9cb211fb6d1e 100644 --- a/arch/powerpc/configs/85xx/ksi8560_defconfig +++ b/arch/powerpc/configs/85xx/ksi8560_defconfig @@ -23,7 +23,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig index 5fbc3f904046..618e03e0706d 100644 --- a/arch/powerpc/configs/85xx/mpc8540_ads_defconfig +++ b/arch/powerpc/configs/85xx/mpc8540_ads_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig index ff981d7905c7..9bc6283f2fb2 100644 --- a/arch/powerpc/configs/85xx/mpc8560_ads_defconfig +++ b/arch/powerpc/configs/85xx/mpc8560_ads_defconfig @@ -23,7 +23,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig index 974f0706d777..0683d8c292a8 100644 --- a/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig +++ b/arch/powerpc/configs/85xx/mpc85xx_cds_defconfig @@ -25,7 +25,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/85xx/sbc8548_defconfig b/arch/powerpc/configs/85xx/sbc8548_defconfig index 7e3e84a842e4..258881727119 100644 --- a/arch/powerpc/configs/85xx/sbc8548_defconfig +++ b/arch/powerpc/configs/85xx/sbc8548_defconfig @@ -22,7 +22,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/85xx/stx_gp3_defconfig b/arch/powerpc/configs/85xx/stx_gp3_defconfig index 5b9cc01b9098..ecbcc853307d 100644 --- a/arch/powerpc/configs/85xx/stx_gp3_defconfig +++ b/arch/powerpc/configs/85xx/stx_gp3_defconfig @@ -22,7 +22,6 @@ CONFIG_NETFILTER=y CONFIG_IP_NF_IPTABLES=m CONFIG_IP_NF_FILTER=m CONFIG_NET_PKTGEN=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_PARPORT=m CONFIG_PARPORT_PC=m diff --git a/arch/powerpc/configs/85xx/tqm8548_defconfig b/arch/powerpc/configs/85xx/tqm8548_defconfig index 1c63cbdc3211..afa1b9b633f8 100644 --- a/arch/powerpc/configs/85xx/tqm8548_defconfig +++ b/arch/powerpc/configs/85xx/tqm8548_defconfig @@ -29,7 +29,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CFI=y diff --git a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig index 78f5beb2928c..d50aca608736 100644 --- a/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig +++ b/arch/powerpc/configs/85xx/xes_mpc85xx_defconfig @@ -54,7 +54,6 @@ CONFIG_IP_PIMSM_V2=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_REDBOOT_PARTS=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/adder875_defconfig b/arch/powerpc/configs/adder875_defconfig index 935ea3ade7de..f7a803ab2285 100644 --- a/arch/powerpc/configs/adder875_defconfig +++ b/arch/powerpc/configs/adder875_defconfig @@ -26,7 +26,6 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/amigaone_defconfig b/arch/powerpc/configs/amigaone_defconfig index 12f397d403c6..cf94d28d0e31 100644 --- a/arch/powerpc/configs/amigaone_defconfig +++ b/arch/powerpc/configs/amigaone_defconfig @@ -37,7 +37,6 @@ CONFIG_NETFILTER=y # CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set # CONFIG_NETFILTER_XT_MATCH_STATE is not set # CONFIG_IP_NF_MANGLE is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set CONFIG_PARPORT=y CONFIG_PARPORT_PC=y diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig index 560a93a84efe..2dd1b58a18ae 100644 --- a/arch/powerpc/configs/cell_defconfig +++ b/arch/powerpc/configs/cell_defconfig @@ -102,7 +102,6 @@ CONFIG_IP_NF_RAW=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=131072 diff --git a/arch/powerpc/configs/chrp32_defconfig b/arch/powerpc/configs/chrp32_defconfig index a203b1cf67d3..9ff493dd8439 100644 --- a/arch/powerpc/configs/chrp32_defconfig +++ b/arch/powerpc/configs/chrp32_defconfig @@ -38,7 +38,6 @@ CONFIG_NETFILTER=y # CONFIG_NETFILTER_XT_MATCH_CONNTRACK is not set # CONFIG_NETFILTER_XT_MATCH_STATE is not set # CONFIG_IP_NF_MANGLE is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set CONFIG_BLK_DEV_FD=y CONFIG_BLK_DEV_LOOP=y diff --git a/arch/powerpc/configs/ep8248e_defconfig b/arch/powerpc/configs/ep8248e_defconfig index 2e6c8a45ae88..6e08d9502d89 100644 --- a/arch/powerpc/configs/ep8248e_defconfig +++ b/arch/powerpc/configs/ep8248e_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y CONFIG_NETFILTER=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/ep88xc_defconfig b/arch/powerpc/configs/ep88xc_defconfig index 7cb590e8f8fd..b20bd0cf3543 100644 --- a/arch/powerpc/configs/ep88xc_defconfig +++ b/arch/powerpc/configs/ep88xc_defconfig @@ -28,7 +28,6 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/fsl-emb-nonhw.config b/arch/powerpc/configs/fsl-emb-nonhw.config index d592ba27b122..3c7dad19a691 100644 --- a/arch/powerpc/configs/fsl-emb-nonhw.config +++ b/arch/powerpc/configs/fsl-emb-nonhw.config @@ -118,7 +118,6 @@ CONFIG_SYSVIPC=y CONFIG_TMPFS=y CONFIG_UBIFS_FS=y CONFIG_UDF_FS=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_UFS_FS=m CONFIG_UIO=y CONFIG_UNIX=y diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index ceb3c770786f..3f4c141b82b1 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -52,7 +52,6 @@ CONFIG_NF_CONNTRACK_IRC=m CONFIG_NF_CONNTRACK_TFTP=m CONFIG_NF_CT_NETLINK=m CONFIG_NF_CONNTRACK_IPV4=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_LOOP=y diff --git a/arch/powerpc/configs/gamecube_defconfig b/arch/powerpc/configs/gamecube_defconfig index 805b0f87653c..a39e32ea3035 100644 --- a/arch/powerpc/configs/gamecube_defconfig +++ b/arch/powerpc/configs/gamecube_defconfig @@ -35,7 +35,6 @@ CONFIG_IP_PNP_RARP=y # CONFIG_INET_DIAG is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y diff --git a/arch/powerpc/configs/holly_defconfig b/arch/powerpc/configs/holly_defconfig index 71d8d2430b6c..067f433c8f5e 100644 --- a/arch/powerpc/configs/holly_defconfig +++ b/arch/powerpc/configs/holly_defconfig @@ -27,7 +27,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig index 477794c41d50..ea59f3d146df 100644 --- a/arch/powerpc/configs/linkstation_defconfig +++ b/arch/powerpc/configs/linkstation_defconfig @@ -48,7 +48,6 @@ CONFIG_IP_NF_RAW=m CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index c5f2005005d3..7fab0a540452 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig @@ -36,7 +36,6 @@ CONFIG_IP_MULTICAST=y CONFIG_IP_PNP=y CONFIG_IP_PNP_DHCP=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=8192 # CONFIG_SCSI_PROC_FS is not set diff --git a/arch/powerpc/configs/mgcoge_defconfig b/arch/powerpc/configs/mgcoge_defconfig index 5d5f08e5b8d9..6ce4f206eac7 100644 --- a/arch/powerpc/configs/mgcoge_defconfig +++ b/arch/powerpc/configs/mgcoge_defconfig @@ -30,7 +30,6 @@ CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set CONFIG_NETFILTER=y CONFIG_TIPC=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/mpc512x_defconfig b/arch/powerpc/configs/mpc512x_defconfig index e4bf8aa87e60..6203c1093a3a 100644 --- a/arch/powerpc/configs/mpc512x_defconfig +++ b/arch/powerpc/configs/mpc512x_defconfig @@ -35,7 +35,6 @@ CONFIG_CAN_VCAN=y CONFIG_CAN_MSCAN=y CONFIG_CAN_DEBUG_DEVICES=y # CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_PREVENT_FIRMWARE_BUILD is not set diff --git a/arch/powerpc/configs/mpc5200_defconfig b/arch/powerpc/configs/mpc5200_defconfig index 7a2b2aa37def..6f87a5c74960 100644 --- a/arch/powerpc/configs/mpc5200_defconfig +++ b/arch/powerpc/configs/mpc5200_defconfig @@ -27,7 +27,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/mpc7448_hpc2_defconfig b/arch/powerpc/configs/mpc7448_hpc2_defconfig index 4b14c02b437c..19406a6c2648 100644 --- a/arch/powerpc/configs/mpc7448_hpc2_defconfig +++ b/arch/powerpc/configs/mpc7448_hpc2_defconfig @@ -25,7 +25,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y diff --git a/arch/powerpc/configs/mpc8272_ads_defconfig b/arch/powerpc/configs/mpc8272_ads_defconfig index b1e88b64536b..00a4d2bf43b2 100644 --- a/arch/powerpc/configs/mpc8272_ads_defconfig +++ b/arch/powerpc/configs/mpc8272_ads_defconfig @@ -23,7 +23,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y CONFIG_NETFILTER=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/mpc83xx_defconfig b/arch/powerpc/configs/mpc83xx_defconfig index 005d00020fb9..be125729635c 100644 --- a/arch/powerpc/configs/mpc83xx_defconfig +++ b/arch/powerpc/configs/mpc83xx_defconfig @@ -37,7 +37,6 @@ CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y CONFIG_INET_ESP=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y # CONFIG_FW_LOADER is not set diff --git a/arch/powerpc/configs/mpc885_ads_defconfig b/arch/powerpc/configs/mpc885_ads_defconfig index ec3fcc2bf737..285d506c5a76 100644 --- a/arch/powerpc/configs/mpc885_ads_defconfig +++ b/arch/powerpc/configs/mpc885_ads_defconfig @@ -27,7 +27,6 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/mvme5100_defconfig b/arch/powerpc/configs/mvme5100_defconfig index 63e38c7220f1..0a0d046fc445 100644 --- a/arch/powerpc/configs/mvme5100_defconfig +++ b/arch/powerpc/configs/mvme5100_defconfig @@ -58,7 +58,6 @@ CONFIG_IP_NF_ARPTABLES=m CONFIG_IP_NF_ARPFILTER=m CONFIG_IP_NF_ARP_MANGLE=m CONFIG_LAPB=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_COUNT=2 diff --git a/arch/powerpc/configs/pasemi_defconfig b/arch/powerpc/configs/pasemi_defconfig index c0423b2cf7c0..4b6d31d4474e 100644 --- a/arch/powerpc/configs/pasemi_defconfig +++ b/arch/powerpc/configs/pasemi_defconfig @@ -44,7 +44,6 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=y CONFIG_INET_ESP=y # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_MTD=y diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index 50b610b48914..ff7955dde23e 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig @@ -112,7 +112,6 @@ CONFIG_BT_HCIBFUSB=m CONFIG_CFG80211=m CONFIG_MAC80211=m CONFIG_MAC80211_LEDS=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set CONFIG_CONNECTOR=y CONFIG_MAC_FLOPPY=m diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig index ef2ef98d3f28..4b657d7f4552 100644 --- a/arch/powerpc/configs/powernv_defconfig +++ b/arch/powerpc/configs/powernv_defconfig @@ -98,7 +98,6 @@ CONFIG_NET_ACT_BPF=m CONFIG_DNS_RESOLVER=y CONFIG_BPF_JIT=y # CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_MTD=y diff --git a/arch/powerpc/configs/ppc40x_defconfig b/arch/powerpc/configs/ppc40x_defconfig index 689d7e276769..8f136b52198b 100644 --- a/arch/powerpc/configs/ppc40x_defconfig +++ b/arch/powerpc/configs/ppc40x_defconfig @@ -25,7 +25,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TRANSPORT is not set # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/ppc44x_defconfig b/arch/powerpc/configs/ppc44x_defconfig index db48039e0b11..67952819593e 100644 --- a/arch/powerpc/configs/ppc44x_defconfig +++ b/arch/powerpc/configs/ppc44x_defconfig @@ -36,7 +36,6 @@ CONFIG_IP_PNP_BOOTP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_BRIDGE=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_CONNECTOR=y CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 91fdb619b484..6b54c6b33c24 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -98,7 +98,6 @@ CONFIG_NET_CLS_BPF=m CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_BPF=m CONFIG_BPF_JIT=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_FD=y diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index 41d85cb3c9a2..a57bdc5291d7 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -50,7 +50,6 @@ CONFIG_INET_IPCOMP=m CONFIG_NETFILTER=y # CONFIG_NETFILTER_ADVANCED is not set CONFIG_BRIDGE=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_BLK_DEV_FD=y diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index 7c6baf6df139..bbc2521ef2ea 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -346,7 +346,6 @@ CONFIG_MAC80211_LEDS=y CONFIG_MAC80211_DEBUGFS=y CONFIG_NET_9P=m CONFIG_NET_9P_VIRTIO=m -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEBUG_DEVRES=y CONFIG_CONNECTOR=y CONFIG_PARPORT=m diff --git a/arch/powerpc/configs/pq2fads_defconfig b/arch/powerpc/configs/pq2fads_defconfig index 0ededa8c837d..9d8a76857c6f 100644 --- a/arch/powerpc/configs/pq2fads_defconfig +++ b/arch/powerpc/configs/pq2fads_defconfig @@ -24,7 +24,6 @@ CONFIG_IP_PNP_DHCP=y CONFIG_IP_PNP_BOOTP=y CONFIG_SYN_COOKIES=y CONFIG_NETFILTER=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig index cf8d55f67272..314c63939816 100644 --- a/arch/powerpc/configs/ps3_defconfig +++ b/arch/powerpc/configs/ps3_defconfig @@ -63,7 +63,6 @@ CONFIG_CFG80211=m CONFIG_CFG80211_WEXT=y CONFIG_MAC80211=m # CONFIG_MAC80211_RC_MINSTREL is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y CONFIG_BLK_DEV_RAM_SIZE=65535 diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 62e12f61a3b2..596a44b3d721 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -83,7 +83,6 @@ CONFIG_NET_CLS_BPF=m CONFIG_NET_CLS_ACT=y CONFIG_NET_ACT_BPF=m CONFIG_BPF_JIT=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_PARPORT=m diff --git a/arch/powerpc/configs/skiroot_defconfig b/arch/powerpc/configs/skiroot_defconfig index a887616e35a2..557b530b2f70 100644 --- a/arch/powerpc/configs/skiroot_defconfig +++ b/arch/powerpc/configs/skiroot_defconfig @@ -68,7 +68,6 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_BEET is not set CONFIG_DNS_RESOLVER=y # CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_DEVTMPFS=y CONFIG_DEVTMPFS_MOUNT=y CONFIG_MTD=m diff --git a/arch/powerpc/configs/storcenter_defconfig b/arch/powerpc/configs/storcenter_defconfig index 74bca2eccd0f..6c39c52b8e4a 100644 --- a/arch/powerpc/configs/storcenter_defconfig +++ b/arch/powerpc/configs/storcenter_defconfig @@ -26,7 +26,6 @@ CONFIG_IP_PNP_DHCP=y # CONFIG_INET_XFRM_MODE_TUNNEL is not set # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y CONFIG_MTD_BLOCK=y diff --git a/arch/powerpc/configs/tqm8xx_defconfig b/arch/powerpc/configs/tqm8xx_defconfig index cd72193fac0a..7493f36dd6e9 100644 --- a/arch/powerpc/configs/tqm8xx_defconfig +++ b/arch/powerpc/configs/tqm8xx_defconfig @@ -32,7 +32,6 @@ CONFIG_SYN_COOKIES=y # CONFIG_INET_XFRM_MODE_BEET is not set # CONFIG_IPV6 is not set # CONFIG_WIRELESS is not set -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_FW_LOADER is not set CONFIG_MTD=y CONFIG_MTD_CMDLINE_PARTS=y diff --git a/arch/powerpc/configs/wii_defconfig b/arch/powerpc/configs/wii_defconfig index f5c366b02828..437be0817e01 100644 --- a/arch/powerpc/configs/wii_defconfig +++ b/arch/powerpc/configs/wii_defconfig @@ -41,7 +41,6 @@ CONFIG_BT_BNEP_MC_FILTER=y CONFIG_BT_HIDP=y CONFIG_CFG80211=y CONFIG_MAC80211=y -CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug" # CONFIG_STANDALONE is not set CONFIG_BLK_DEV_LOOP=y CONFIG_BLK_DEV_RAM=y -- cgit v1.2.3 From 41732bdc9ccd26829cf647711c4b93384e03e529 Mon Sep 17 00:00:00 2001 From: Stewart Smith Date: Tue, 28 May 2019 13:29:25 +1000 Subject: powerpc/powernv-eeh: Consisely desribe what this file does If the previous comment made sense, continue debugging or call your doctor immediately. Signed-off-by: Stewart Smith Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/powernv/eeh-powernv.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/powernv/eeh-powernv.c b/arch/powerpc/platforms/powernv/eeh-powernv.c index f38078976c5d..bea6708be065 100644 --- a/arch/powerpc/platforms/powernv/eeh-powernv.c +++ b/arch/powerpc/platforms/powernv/eeh-powernv.c @@ -1,7 +1,5 @@ /* - * The file intends to implement the platform dependent EEH operations on - * powernv platform. Actually, the powernv was created in order to fully - * hypervisor support. + * PowerNV Platform dependent EEH operations * * Copyright Benjamin Herrenschmidt & Gavin Shan, IBM Corporation 2013. * -- cgit v1.2.3 From 2200bbec12c428d7b276fb450e5755cdfe435ae5 Mon Sep 17 00:00:00 2001 From: Nishad Kamdar Date: Tue, 16 Apr 2019 20:58:57 +0530 Subject: powerpc: Use the correct style for SPDX License Identifier This patch corrects the SPDX License Identifier style in the powerpc Hardware Architecture related files. Suggested-by: Joe Perches Signed-off-by: Nishad Kamdar Acked-by: Andrew Donnellan Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/pnv-ocxl.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/pnv-ocxl.h b/arch/powerpc/include/asm/pnv-ocxl.h index 208b5503f4ed..7de82647e761 100644 --- a/arch/powerpc/include/asm/pnv-ocxl.h +++ b/arch/powerpc/include/asm/pnv-ocxl.h @@ -1,4 +1,4 @@ -// SPDX-License-Identifier: GPL-2.0+ +/* SPDX-License-Identifier: GPL-2.0+ */ // Copyright 2017 IBM Corp. #ifndef _ASM_PNV_OCXL_H #define _ASM_PNV_OCXL_H -- cgit v1.2.3 From 6d3ca7e73642ce17398f4cd5df1780da4a1ccdaf Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Tue, 21 May 2019 22:13:24 +0900 Subject: powerpc/mm: mark more tlb functions as __always_inline With CONFIG_OPTIMIZE_INLINING enabled, Laura Abbott reported error with gcc 9.1.1: arch/powerpc/mm/book3s64/radix_tlb.c: In function '_tlbiel_pid': arch/powerpc/mm/book3s64/radix_tlb.c:104:2: warning: asm operand 3 probably doesn't match constraints 104 | asm volatile(PPC_TLBIEL(%0, %4, %3, %2, %1) | ^~~ arch/powerpc/mm/book3s64/radix_tlb.c:104:2: error: impossible constraint in 'asm' Fixing _tlbiel_pid() is enough to address the warning above, but I inlined more functions to fix all potential issues. To meet the "i" (immediate) constraint for the asm operands, functions propagating "ric" must be always inlined. Fixes: 9012d011660e ("compiler: allow all arches to enable CONFIG_OPTIMIZE_INLINING") Reported-by: Laura Abbott Signed-off-by: Masahiro Yamada Reviewed-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/mm/book3s64/hash_native.c | 2 +- arch/powerpc/mm/book3s64/radix_tlb.c | 32 ++++++++++++++++---------------- 2 files changed, 17 insertions(+), 17 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/book3s64/hash_native.c b/arch/powerpc/mm/book3s64/hash_native.c index 0b447d96b911..79e5c814675f 100644 --- a/arch/powerpc/mm/book3s64/hash_native.c +++ b/arch/powerpc/mm/book3s64/hash_native.c @@ -60,7 +60,7 @@ static inline void tlbiel_hash_set_isa206(unsigned int set, unsigned int is) * tlbiel instruction for hash, set invalidation * i.e., r=1 and is=01 or is=10 or is=11 */ -static inline void tlbiel_hash_set_isa300(unsigned int set, unsigned int is, +static __always_inline void tlbiel_hash_set_isa300(unsigned int set, unsigned int is, unsigned int pid, unsigned int ric, unsigned int prs) { diff --git a/arch/powerpc/mm/book3s64/radix_tlb.c b/arch/powerpc/mm/book3s64/radix_tlb.c index edf39e9a4ec4..8901f5c8ef8c 100644 --- a/arch/powerpc/mm/book3s64/radix_tlb.c +++ b/arch/powerpc/mm/book3s64/radix_tlb.c @@ -29,7 +29,7 @@ * tlbiel instruction for radix, set invalidation * i.e., r=1 and is=01 or is=10 or is=11 */ -static inline void tlbiel_radix_set_isa300(unsigned int set, unsigned int is, +static __always_inline void tlbiel_radix_set_isa300(unsigned int set, unsigned int is, unsigned int pid, unsigned int ric, unsigned int prs) { @@ -150,8 +150,8 @@ static __always_inline void __tlbie_lpid(unsigned long lpid, unsigned long ric) trace_tlbie(lpid, 0, rb, rs, ric, prs, r); } -static inline void __tlbiel_lpid_guest(unsigned long lpid, int set, - unsigned long ric) +static __always_inline void __tlbiel_lpid_guest(unsigned long lpid, int set, + unsigned long ric) { unsigned long rb,rs,prs,r; @@ -167,8 +167,8 @@ static inline void __tlbiel_lpid_guest(unsigned long lpid, int set, } -static inline void __tlbiel_va(unsigned long va, unsigned long pid, - unsigned long ap, unsigned long ric) +static __always_inline void __tlbiel_va(unsigned long va, unsigned long pid, + unsigned long ap, unsigned long ric) { unsigned long rb,rs,prs,r; @@ -183,8 +183,8 @@ static inline void __tlbiel_va(unsigned long va, unsigned long pid, trace_tlbie(0, 1, rb, rs, ric, prs, r); } -static inline void __tlbie_va(unsigned long va, unsigned long pid, - unsigned long ap, unsigned long ric) +static __always_inline void __tlbie_va(unsigned long va, unsigned long pid, + unsigned long ap, unsigned long ric) { unsigned long rb,rs,prs,r; @@ -199,8 +199,8 @@ static inline void __tlbie_va(unsigned long va, unsigned long pid, trace_tlbie(0, 0, rb, rs, ric, prs, r); } -static inline void __tlbie_lpid_va(unsigned long va, unsigned long lpid, - unsigned long ap, unsigned long ric) +static __always_inline void __tlbie_lpid_va(unsigned long va, unsigned long lpid, + unsigned long ap, unsigned long ric) { unsigned long rb,rs,prs,r; @@ -239,7 +239,7 @@ static inline void fixup_tlbie_lpid(unsigned long lpid) /* * We use 128 set in radix mode and 256 set in hpt mode. */ -static inline void _tlbiel_pid(unsigned long pid, unsigned long ric) +static __always_inline void _tlbiel_pid(unsigned long pid, unsigned long ric) { int set; @@ -341,7 +341,7 @@ static inline void _tlbie_lpid(unsigned long lpid, unsigned long ric) asm volatile("eieio; tlbsync; ptesync": : :"memory"); } -static inline void _tlbiel_lpid_guest(unsigned long lpid, unsigned long ric) +static __always_inline void _tlbiel_lpid_guest(unsigned long lpid, unsigned long ric) { int set; @@ -381,8 +381,8 @@ static inline void __tlbiel_va_range(unsigned long start, unsigned long end, __tlbiel_va(addr, pid, ap, RIC_FLUSH_TLB); } -static inline void _tlbiel_va(unsigned long va, unsigned long pid, - unsigned long psize, unsigned long ric) +static __always_inline void _tlbiel_va(unsigned long va, unsigned long pid, + unsigned long psize, unsigned long ric) { unsigned long ap = mmu_get_ap(psize); @@ -413,8 +413,8 @@ static inline void __tlbie_va_range(unsigned long start, unsigned long end, __tlbie_va(addr, pid, ap, RIC_FLUSH_TLB); } -static inline void _tlbie_va(unsigned long va, unsigned long pid, - unsigned long psize, unsigned long ric) +static __always_inline void _tlbie_va(unsigned long va, unsigned long pid, + unsigned long psize, unsigned long ric) { unsigned long ap = mmu_get_ap(psize); @@ -424,7 +424,7 @@ static inline void _tlbie_va(unsigned long va, unsigned long pid, asm volatile("eieio; tlbsync; ptesync": : :"memory"); } -static inline void _tlbie_lpid_va(unsigned long va, unsigned long lpid, +static __always_inline void _tlbie_lpid_va(unsigned long va, unsigned long lpid, unsigned long psize, unsigned long ric) { unsigned long ap = mmu_get_ap(psize); -- cgit v1.2.3 From 4f44e8aeaf1937d9148dfcc4c028cd8aff27902e Mon Sep 17 00:00:00 2001 From: "Enrico Weigelt, metux IT consult" Date: Wed, 3 Jul 2019 18:04:13 +0200 Subject: powerpc/Kconfig: Clean up formatting Formatting of Kconfig files doesn't look so pretty, so let the Great White Handkerchief come around and clean it up. Also convert "---help---" as requested. Signed-off-by: Enrico Weigelt, metux IT consult Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig | 40 +++++++++++++++++----------------- arch/powerpc/kvm/Kconfig | 6 ++--- arch/powerpc/platforms/40x/Kconfig | 7 +++--- arch/powerpc/platforms/44x/Kconfig | 10 ++++----- arch/powerpc/platforms/85xx/Kconfig | 8 +++---- arch/powerpc/platforms/86xx/Kconfig | 6 ++--- arch/powerpc/platforms/maple/Kconfig | 2 +- arch/powerpc/platforms/pseries/Kconfig | 18 +++++++-------- arch/powerpc/sysdev/xics/Kconfig | 13 +++++------ 9 files changed, 54 insertions(+), 56 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 876902661c04..537d93a4594b 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -48,7 +48,7 @@ config ARCH_MMAP_RND_COMPAT_BITS_MAX # Allow randomisation to consume up to 512MB of address space (2^29). default 11 if PPC_256K_PAGES # 11 = 29 (512MB) - 18 (256K) default 13 if PPC_64K_PAGES # 13 = 29 (512MB) - 16 (64K) - default 15 if PPC_16K_PAGES # 15 = 29 (512MB) - 14 (16K) + default 15 if PPC_16K_PAGES # 15 = 29 (512MB) - 14 (16K) default 17 # 17 = 29 (512MB) - 12 (4K) config ARCH_MMAP_RND_COMPAT_BITS_MIN @@ -247,9 +247,9 @@ config PPC # config PPC_BARRIER_NOSPEC - bool - default y - depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E + bool + default y + depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E config EARLY_PRINTK bool @@ -404,7 +404,7 @@ config HUGETLB_PAGE_SIZE_VARIABLE config MATH_EMULATION bool "Math emulation" depends on 4xx || PPC_8xx || PPC_MPC832x || BOOKE - ---help--- + help Some PowerPC chips designed for embedded applications do not have a floating-point unit and therefore do not implement the floating-point instructions in the PowerPC instruction set. If you @@ -423,27 +423,27 @@ choice config MATH_EMULATION_FULL bool "Emulate all the floating point instructions" - ---help--- + help Select this option will enable the kernel to support to emulate all the floating point instructions. If your SoC doesn't have a FPU, you should select this. config MATH_EMULATION_HW_UNIMPLEMENTED bool "Just emulate the FPU unimplemented instructions" - ---help--- + help Select this if you know there does have a hardware FPU on your SoC, but some floating point instructions are not implemented by that. endchoice config PPC_TRANSACTIONAL_MEM - bool "Transactional Memory support for POWERPC" - depends on PPC_BOOK3S_64 - depends on SMP - select ALTIVEC - select VSX - ---help--- - Support user-mode Transactional Memory on POWERPC. + bool "Transactional Memory support for POWERPC" + depends on PPC_BOOK3S_64 + depends on SMP + select ALTIVEC + select VSX + help + Support user-mode Transactional Memory on POWERPC. config LD_HEAD_STUB_CATCH bool "Reserve 256 bytes to cope with linker stubs in HEAD text" if EXPERT @@ -463,7 +463,7 @@ config HOTPLUG_CPU bool "Support for enabling/disabling CPUs" depends on SMP && (PPC_PSERIES || \ PPC_PMAC || PPC_POWERNV || FSL_SOC_BOOKE) - ---help--- + help Say Y here to be able to disable and re-enable individual CPUs at runtime on SMP machines. @@ -831,7 +831,7 @@ config PPC_DENORMALISATION bool "PowerPC denormalisation exception handling" depends on PPC_BOOK3S_64 default "y" if PPC_POWERNV - ---help--- + help Add support for handling denormalisation of single precision values. Useful for bare metal only. If unsure say Y here. @@ -944,7 +944,7 @@ config FSL_SOC bool config FSL_PCI - bool + bool select ARCH_HAS_DMA_SET_MASK select PPC_INDIRECT_PCI select PCI_QUIRKS @@ -992,7 +992,7 @@ config FSL_RIO bool "Freescale Embedded SRIO Controller support" depends on RAPIDIO = y && HAVE_RAPIDIO default "n" - ---help--- + help Include support for RapidIO controller on Freescale embedded processors (MPC8548, MPC8641, etc). @@ -1056,14 +1056,14 @@ config DYNAMIC_MEMSTART select NONSTATIC_KERNEL help This option enables the kernel to be loaded at any page aligned - physical address. The kernel creates a mapping from KERNELBASE to + physical address. The kernel creates a mapping from KERNELBASE to the address where the kernel is loaded. The page size here implies the TLB page size of the mapping for kernel on the particular platform. Please refer to the init code for finding the TLB page size. DYNAMIC_MEMSTART is an easy way of implementing pseudo-RELOCATABLE kernel image, where the only restriction is the page aligned kernel - load address. When this option is enabled, the compile time physical + load address. When this option is enabled, the compile time physical address CONFIG_PHYSICAL_START is ignored. This option is overridden by CONFIG_RELOCATABLE diff --git a/arch/powerpc/kvm/Kconfig b/arch/powerpc/kvm/Kconfig index b8e13d5a4a31..711fca9bc6f0 100644 --- a/arch/powerpc/kvm/Kconfig +++ b/arch/powerpc/kvm/Kconfig @@ -184,9 +184,9 @@ config KVM_MPIC select HAVE_KVM_MSI help Enable support for emulating MPIC devices inside the - host kernel, rather than relying on userspace to emulate. - Currently, support is limited to certain versions of - Freescale's MPIC implementation. + host kernel, rather than relying on userspace to emulate. + Currently, support is limited to certain versions of + Freescale's MPIC implementation. config KVM_XICS bool "KVM in-kernel XICS emulation" diff --git a/arch/powerpc/platforms/40x/Kconfig b/arch/powerpc/platforms/40x/Kconfig index ad2bb1408b4c..6da813b65b42 100644 --- a/arch/powerpc/platforms/40x/Kconfig +++ b/arch/powerpc/platforms/40x/Kconfig @@ -16,12 +16,12 @@ config EP405 This option enables support for the EP405/EP405PC boards. config HOTFOOT - bool "Hotfoot" + bool "Hotfoot" depends on 40x select PPC40x_SIMPLE select FORCE_PCI - help - This option enables support for the ESTEEM 195E Hotfoot board. + help + This option enables support for the ESTEEM 195E Hotfoot board. config KILAUEA bool "Kilauea" @@ -80,7 +80,6 @@ config OBS600 help This option enables support for PlatHome OpenBlockS 600 server - config PPC40x_SIMPLE bool "Simple PowerPC 40x board support" depends on 40x diff --git a/arch/powerpc/platforms/44x/Kconfig b/arch/powerpc/platforms/44x/Kconfig index 35be81fd2dc2..b369ed4e3675 100644 --- a/arch/powerpc/platforms/44x/Kconfig +++ b/arch/powerpc/platforms/44x/Kconfig @@ -40,12 +40,12 @@ config EBONY This option enables support for the IBM PPC440GP evaluation board. config SAM440EP - bool "Sam440ep" + bool "Sam440ep" depends on 44x - select 440EP - select FORCE_PCI - help - This option enables support for the ACube Sam440ep board. + select 440EP + select FORCE_PCI + help + This option enables support for the ACube Sam440ep board. config SEQUOIA bool "Sequoia" diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index d1af0ee2f8c8..fa3d29dcb57e 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig @@ -147,10 +147,10 @@ config SOCRATES This option enables support for the Socrates board. config KSI8560 - bool "Emerson KSI8560" - select DEFAULT_UIMAGE - help - This option enables support for the Emerson KSI8560 board + bool "Emerson KSI8560" + select DEFAULT_UIMAGE + help + This option enables support for the Emerson KSI8560 board config XES_MPC85xx bool "X-ES single-board computer" diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig index 0a610114bc38..07a9d60c618a 100644 --- a/arch/powerpc/platforms/86xx/Kconfig +++ b/arch/powerpc/platforms/86xx/Kconfig @@ -62,9 +62,9 @@ config GEF_SBC610 This option enables support for the GE SBC610. config MVME7100 - bool "Artesyn MVME7100" - help - This option enables support for the Emerson/Artesyn MVME7100 board. + bool "Artesyn MVME7100" + help + This option enables support for the Emerson/Artesyn MVME7100 board. endif diff --git a/arch/powerpc/platforms/maple/Kconfig b/arch/powerpc/platforms/maple/Kconfig index 08d530a2a8b1..86ae210bee9a 100644 --- a/arch/powerpc/platforms/maple/Kconfig +++ b/arch/powerpc/platforms/maple/Kconfig @@ -14,5 +14,5 @@ config PPC_MAPLE select MMIO_NVRAM select ATA_NONSTANDARD if ATA help - This option enables support for the Maple 970FX Evaluation Board. + This option enables support for the Maple 970FX Evaluation Board. For more information, refer to diff --git a/arch/powerpc/platforms/pseries/Kconfig b/arch/powerpc/platforms/pseries/Kconfig index b9e8b608de01..f7b484f55553 100644 --- a/arch/powerpc/platforms/pseries/Kconfig +++ b/arch/powerpc/platforms/pseries/Kconfig @@ -81,19 +81,19 @@ config LPARCFG bool "LPAR Configuration Data" depends on PPC_PSERIES help - Provide system capacity information via human readable - = pairs through a /proc/ppc64/lparcfg interface. + Provide system capacity information via human readable + = pairs through a /proc/ppc64/lparcfg interface. config PPC_PSERIES_DEBUG depends on PPC_PSERIES && PPC_EARLY_DEBUG bool "Enable extra debug logging in platforms/pseries" - help + default y + help Say Y here if you want the pseries core to produce a bunch of debug messages to the system log. Select this if you are having a problem with the pseries core and want to see more of what is going on. This does not enable debugging in lpar.c, which must be manually done due to its verbosity. - default y config PPC_SMLPAR bool "Support for shared-memory logical partitions" @@ -118,16 +118,16 @@ config CMM balance memory across many LPARs. config HV_PERF_CTRS - bool "Hypervisor supplied PMU events (24x7 & GPCI)" - default y - depends on PERF_EVENTS && PPC_PSERIES - help + bool "Hypervisor supplied PMU events (24x7 & GPCI)" + default y + depends on PERF_EVENTS && PPC_PSERIES + help Enable access to hypervisor supplied counters in perf. Currently, this enables code that uses the hcall GetPerfCounterInfo and 24x7 interfaces to retrieve counters. GPCI exists on Power 6 and later systems. 24x7 is available on Power 8 and later systems. - If unsure, select Y. + If unsure, select Y. config IBMVIO depends on PPC_PSERIES diff --git a/arch/powerpc/sysdev/xics/Kconfig b/arch/powerpc/sysdev/xics/Kconfig index 86fee428f5f1..304614c920aa 100644 --- a/arch/powerpc/sysdev/xics/Kconfig +++ b/arch/powerpc/sysdev/xics/Kconfig @@ -1,15 +1,14 @@ # SPDX-License-Identifier: GPL-2.0 config PPC_XICS - def_bool n - select PPC_SMP_MUXED_IPI - select HARDIRQS_SW_RESEND + def_bool n + select PPC_SMP_MUXED_IPI + select HARDIRQS_SW_RESEND config PPC_ICP_NATIVE - def_bool n + def_bool n config PPC_ICP_HV - def_bool n + def_bool n config PPC_ICS_RTAS - def_bool n - + def_bool n -- cgit v1.2.3 From 7505a13f85bdcb8713551a067dfc92ac3c7ba902 Mon Sep 17 00:00:00 2001 From: Anton Blanchard Date: Tue, 4 Jun 2019 15:42:57 +1000 Subject: powerpc/configs: Disable latencytop latencytop adds almost 4kB to each and every task struct and as such it doesn't deserve to be in our defconfigs. Signed-off-by: Anton Blanchard Signed-off-by: Michael Ellerman --- arch/powerpc/configs/g5_defconfig | 1 - arch/powerpc/configs/gamecube_defconfig | 1 - arch/powerpc/configs/maple_defconfig | 1 - arch/powerpc/configs/pmac32_defconfig | 1 - arch/powerpc/configs/powernv_defconfig | 1 - arch/powerpc/configs/ppc64_defconfig | 1 - arch/powerpc/configs/ppc64e_defconfig | 1 - arch/powerpc/configs/ppc6xx_defconfig | 1 - arch/powerpc/configs/pseries_defconfig | 1 - arch/powerpc/configs/wii_defconfig | 1 - 10 files changed, 10 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/configs/g5_defconfig b/arch/powerpc/configs/g5_defconfig index 3f4c141b82b1..fbfcc85e4dc0 100644 --- a/arch/powerpc/configs/g5_defconfig +++ b/arch/powerpc/configs/g5_defconfig @@ -243,7 +243,6 @@ CONFIG_CRC_T10DIF=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_MUTEXES=y -CONFIG_LATENCYTOP=y CONFIG_BOOTX_TEXT=y CONFIG_CRYPTO_TEST=m CONFIG_CRYPTO_PCBC=m diff --git a/arch/powerpc/configs/gamecube_defconfig b/arch/powerpc/configs/gamecube_defconfig index a39e32ea3035..85e73c3bd859 100644 --- a/arch/powerpc/configs/gamecube_defconfig +++ b/arch/powerpc/configs/gamecube_defconfig @@ -90,7 +90,6 @@ CONFIG_CRC_CCITT=y CONFIG_PRINTK_TIME=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y -CONFIG_LATENCYTOP=y CONFIG_SCHED_TRACER=y CONFIG_DMA_API_DEBUG=y CONFIG_PPC_EARLY_DEBUG=y diff --git a/arch/powerpc/configs/maple_defconfig b/arch/powerpc/configs/maple_defconfig index 7fab0a540452..2975e64629aa 100644 --- a/arch/powerpc/configs/maple_defconfig +++ b/arch/powerpc/configs/maple_defconfig @@ -103,7 +103,6 @@ CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_STACKOVERFLOW=y -CONFIG_LATENCYTOP=y CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_BOOTX_TEXT=y diff --git a/arch/powerpc/configs/pmac32_defconfig b/arch/powerpc/configs/pmac32_defconfig index ff7955dde23e..7e6654848531 100644 --- a/arch/powerpc/configs/pmac32_defconfig +++ b/arch/powerpc/configs/pmac32_defconfig @@ -292,7 +292,6 @@ CONFIG_CRC_T10DIF=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_KERNEL=y CONFIG_DETECT_HUNG_TASK=y -CONFIG_LATENCYTOP=y CONFIG_XMON=y CONFIG_XMON_DEFAULT=y CONFIG_BOOTX_TEXT=y diff --git a/arch/powerpc/configs/powernv_defconfig b/arch/powerpc/configs/powernv_defconfig index 4b657d7f4552..34219d555e8a 100644 --- a/arch/powerpc/configs/powernv_defconfig +++ b/arch/powerpc/configs/powernv_defconfig @@ -316,7 +316,6 @@ CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_HARDLOCKUP_DETECTOR=y -CONFIG_LATENCYTOP=y CONFIG_FUNCTION_TRACER=y CONFIG_SCHED_TRACER=y CONFIG_FTRACE_SYSCALLS=y diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index 6b54c6b33c24..cf5183c4a388 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -366,7 +366,6 @@ CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_HARDLOCKUP_DETECTOR=y CONFIG_DEBUG_MUTEXES=y -CONFIG_LATENCYTOP=y CONFIG_FUNCTION_TRACER=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y diff --git a/arch/powerpc/configs/ppc64e_defconfig b/arch/powerpc/configs/ppc64e_defconfig index a57bdc5291d7..0d746774c2bd 100644 --- a/arch/powerpc/configs/ppc64e_defconfig +++ b/arch/powerpc/configs/ppc64e_defconfig @@ -222,7 +222,6 @@ CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_DETECT_HUNG_TASK=y CONFIG_DEBUG_MUTEXES=y -CONFIG_LATENCYTOP=y CONFIG_IRQSOFF_TRACER=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y diff --git a/arch/powerpc/configs/ppc6xx_defconfig b/arch/powerpc/configs/ppc6xx_defconfig index bbc2521ef2ea..c9dc9253cb63 100644 --- a/arch/powerpc/configs/ppc6xx_defconfig +++ b/arch/powerpc/configs/ppc6xx_defconfig @@ -1147,7 +1147,6 @@ CONFIG_FAIL_MAKE_REQUEST=y CONFIG_FAIL_IO_TIMEOUT=y CONFIG_FAULT_INJECTION_DEBUG_FS=y CONFIG_FAULT_INJECTION_STACKTRACE_FILTER=y -CONFIG_LATENCYTOP=y CONFIG_SCHED_TRACER=y CONFIG_STACK_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig index 596a44b3d721..38abc9c1770a 100644 --- a/arch/powerpc/configs/pseries_defconfig +++ b/arch/powerpc/configs/pseries_defconfig @@ -289,7 +289,6 @@ CONFIG_DEBUG_STACK_USAGE=y CONFIG_DEBUG_STACKOVERFLOW=y CONFIG_SOFTLOCKUP_DETECTOR=y CONFIG_HARDLOCKUP_DETECTOR=y -CONFIG_LATENCYTOP=y CONFIG_FUNCTION_TRACER=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y diff --git a/arch/powerpc/configs/wii_defconfig b/arch/powerpc/configs/wii_defconfig index 437be0817e01..5a04448ad6b5 100644 --- a/arch/powerpc/configs/wii_defconfig +++ b/arch/powerpc/configs/wii_defconfig @@ -122,7 +122,6 @@ CONFIG_PRINTK_TIME=y CONFIG_MAGIC_SYSRQ=y CONFIG_DEBUG_SPINLOCK=y CONFIG_DEBUG_MUTEXES=y -CONFIG_LATENCYTOP=y CONFIG_SCHED_TRACER=y CONFIG_BLK_DEV_IO_TRACE=y CONFIG_DMA_API_DEBUG=y -- cgit v1.2.3 From c197922f0a8072d286dff8001f8ad0d4b95ec1dd Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Tue, 20 Dec 2016 22:02:17 +0800 Subject: powerpc/perf/24x7: use rb_entry To make the code clearer, use rb_entry() instead of container_of() to deal with rbtree. Signed-off-by: Geliang Tang Signed-off-by: Michael Ellerman --- arch/powerpc/perf/hv-24x7.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/perf/hv-24x7.c b/arch/powerpc/perf/hv-24x7.c index d2b8e6061933..bdeb41b1a6e5 100644 --- a/arch/powerpc/perf/hv-24x7.c +++ b/arch/powerpc/perf/hv-24x7.c @@ -571,7 +571,7 @@ static int event_uniq_add(struct rb_root *root, const char *name, int nl, struct event_uniq *it; int result; - it = container_of(*new, struct event_uniq, node); + it = rb_entry(*new, struct event_uniq, node); result = ev_uniq_ord(name, nl, domain, it->name, it->nl, it->domain); -- cgit v1.2.3 From 658829dfe75c49e879e0c4c9cbcd3bd1e4fbdcf5 Mon Sep 17 00:00:00 2001 From: Geliang Tang Date: Sat, 6 May 2017 23:37:20 +0800 Subject: powerpc/cell: set no_llseek in spufs_cntl_fops In spufs_cntl_fops, since we use nonseekable_open() to open, we should use no_llseek() to seek, not generic_file_llseek(). Signed-off-by: Geliang Tang Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/cell/spufs/file.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index bfb9ca99ac05..fd293e510621 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c @@ -459,7 +459,7 @@ static const struct file_operations spufs_cntl_fops = { .release = spufs_cntl_release, .read = simple_attr_read, .write = simple_attr_write, - .llseek = generic_file_llseek, + .llseek = no_llseek, .mmap = spufs_cntl_mmap, }; -- cgit v1.2.3 From 31afa05bf90ea5561307be83893c670555bd736d Mon Sep 17 00:00:00 2001 From: Satheesh Rajendran Date: Tue, 2 Jul 2019 21:17:45 +0530 Subject: powerpc: Enable CONFIG_IPV6 in ppc64_defconfig Enable CONFIG_IPV6 in ppc64_defconfig to enable certain network functionalities required for tests. Signed-off-by: Michael Ellerman Signed-off-by: Satheesh Rajendran Signed-off-by: Michael Ellerman --- arch/powerpc/configs/ppc64_defconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig index cf5183c4a388..dc83fefa04f7 100644 --- a/arch/powerpc/configs/ppc64_defconfig +++ b/arch/powerpc/configs/ppc64_defconfig @@ -89,7 +89,7 @@ CONFIG_SYN_COOKIES=y CONFIG_INET_AH=m CONFIG_INET_ESP=m CONFIG_INET_IPCOMP=m -# CONFIG_IPV6 is not set +CONFIG_IPV6=y CONFIG_NETFILTER=y # CONFIG_NETFILTER_ADVANCED is not set CONFIG_BRIDGE=m -- cgit v1.2.3 From 515bbc8ab488e4bc16fe26df097502c04d3649d4 Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Wed, 3 Jul 2019 22:33:54 +0530 Subject: powerpc/pseries: Use macros for referring to the DTL enable mask Introduce macros to encode the DTL enable mask fields and use those instead of hardcoding numbers. Acked-by: Nathan Lynch Signed-off-by: Naveen N. Rao Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/lppaca.h | 11 +++++++++++ arch/powerpc/platforms/pseries/dtl.c | 8 +------- arch/powerpc/platforms/pseries/lpar.c | 2 +- arch/powerpc/platforms/pseries/setup.c | 2 +- 4 files changed, 14 insertions(+), 9 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 7c23ce8a5a4c..2c7e31187726 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -154,6 +154,17 @@ struct dtl_entry { #define DISPATCH_LOG_BYTES 4096 /* bytes per cpu */ #define N_DISPATCH_LOG (DISPATCH_LOG_BYTES / sizeof(struct dtl_entry)) +/* + * Dispatch trace log event enable mask: + * 0x1: voluntary virtual processor waits + * 0x2: time-slice preempts + * 0x4: virtual partition memory page faults + */ +#define DTL_LOG_CEDE 0x1 +#define DTL_LOG_PREEMPT 0x2 +#define DTL_LOG_FAULT 0x4 +#define DTL_LOG_ALL (DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT) + extern struct kmem_cache *dtl_cache; /* diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index ef6595153642..051ea2de1e1a 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c @@ -40,13 +40,7 @@ struct dtl { }; static DEFINE_PER_CPU(struct dtl, cpu_dtl); -/* - * Dispatch trace log event mask: - * 0x7: 0x1: voluntary virtual processor waits - * 0x2: time-slice preempts - * 0x4: virtual partition memory page faults - */ -static u8 dtl_event_mask = 0x7; +static u8 dtl_event_mask = DTL_LOG_ALL; /* diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 1034ef1fe2b4..23f2ac6793b7 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -126,7 +126,7 @@ void vpa_init(int cpu) pr_err("WARNING: DTL registration of cpu %d (hw %d) " "failed with %ld\n", smp_processor_id(), hwcpu, ret); - lppaca_of(cpu).dtl_enable_mask = 2; + lppaca_of(cpu).dtl_enable_mask = DTL_LOG_PREEMPT; } } diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 30d72b587ac5..e2cb29e96fa4 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -318,7 +318,7 @@ static int alloc_dispatch_logs(void) pr_err("WARNING: DTL registration of cpu %d (hw %d) failed " "with %d\n", smp_processor_id(), hard_smp_processor_id(), ret); - get_paca()->lppaca_ptr->dtl_enable_mask = 2; + get_paca()->lppaca_ptr->dtl_enable_mask = DTL_LOG_PREEMPT; return 0; } -- cgit v1.2.3 From 5b3306f084590b298c1fe1b02aca5bac1abbbc34 Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Wed, 3 Jul 2019 22:33:55 +0530 Subject: powerpc/pseries: Do not save the previous DTL mask value When CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is enabled, we always initialize DTL enable mask to DTL_LOG_PREEMPT (0x2). There are no other places where the mask is changed. As such, when reading the DTL log buffer through debugfs, there is no need to save and restore the previous mask value. We don't need to save and restore the earlier mask value if CONFIG_VIRT_CPU_ACCOUNTING_NATIVE is not enabled. So, remove the field from the structure as well. Acked-by: Nathan Lynch Signed-off-by: Naveen N. Rao Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/dtl.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index 051ea2de1e1a..fb05804adb2f 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c @@ -55,7 +55,6 @@ struct dtl_ring { struct dtl_entry *write_ptr; struct dtl_entry *buf; struct dtl_entry *buf_end; - u8 saved_dtl_mask; }; static DEFINE_PER_CPU(struct dtl_ring, dtl_rings); @@ -105,7 +104,6 @@ static int dtl_start(struct dtl *dtl) dtlr->write_ptr = dtl->buf; /* enable event logging */ - dtlr->saved_dtl_mask = lppaca_of(dtl->cpu).dtl_enable_mask; lppaca_of(dtl->cpu).dtl_enable_mask |= dtl_event_mask; dtl_consumer = consume_dtle; @@ -123,7 +121,7 @@ static void dtl_stop(struct dtl *dtl) dtlr->buf = NULL; /* restore dtl_enable_mask */ - lppaca_of(dtl->cpu).dtl_enable_mask = dtlr->saved_dtl_mask; + lppaca_of(dtl->cpu).dtl_enable_mask = DTL_LOG_PREEMPT; if (atomic_dec_and_test(&dtl_count)) dtl_consumer = NULL; -- cgit v1.2.3 From 1c85a2a1945cbafcd2e7cebc6e23d0e206aeda3d Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Wed, 3 Jul 2019 22:33:56 +0530 Subject: powerpc/pseries: Factor out DTL buffer allocation and registration routines Introduce new helpers for DTL buffer allocation and registration and have the existing code use those. Signed-off-by: Naveen N. Rao [mpe: Don't split error messages across lines, for grepability] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/lppaca.h | 3 ++ arch/powerpc/platforms/pseries/lpar.c | 67 +++++++++++++++++++++++++--------- arch/powerpc/platforms/pseries/setup.c | 34 +---------------- 3 files changed, 54 insertions(+), 50 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index 2c7e31187726..a8ac2b8988d4 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -175,6 +175,9 @@ extern struct kmem_cache *dtl_cache; */ extern void (*dtl_consumer)(struct dtl_entry *entry, u64 index); +extern void register_dtl_buffer(int cpu); +extern void alloc_dtl_buffers(void); + #endif /* CONFIG_PPC_BOOK3S */ #endif /* __KERNEL__ */ #endif /* _ASM_POWERPC_LPPACA_H */ diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 23f2ac6793b7..da7e7c243864 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -65,13 +65,59 @@ EXPORT_SYMBOL(plpar_hcall); EXPORT_SYMBOL(plpar_hcall9); EXPORT_SYMBOL(plpar_hcall_norets); +void alloc_dtl_buffers(void) +{ + int cpu; + struct paca_struct *pp; + struct dtl_entry *dtl; + + for_each_possible_cpu(cpu) { + pp = paca_ptrs[cpu]; + dtl = kmem_cache_alloc(dtl_cache, GFP_KERNEL); + if (!dtl) { + pr_warn("Failed to allocate dispatch trace log for cpu %d\n", + cpu); + pr_warn("Stolen time statistics will be unreliable\n"); + break; + } + + pp->dtl_ridx = 0; + pp->dispatch_log = dtl; + pp->dispatch_log_end = dtl + N_DISPATCH_LOG; + pp->dtl_curr = dtl; + } +} + +void register_dtl_buffer(int cpu) +{ + long ret; + struct paca_struct *pp; + struct dtl_entry *dtl; + int hwcpu = get_hard_smp_processor_id(cpu); + + pp = paca_ptrs[cpu]; + dtl = pp->dispatch_log; + if (dtl) { + pp->dtl_ridx = 0; + pp->dtl_curr = dtl; + lppaca_of(cpu).dtl_idx = 0; + + /* hypervisor reads buffer length from this field */ + dtl->enqueue_to_dispatch_time = cpu_to_be32(DISPATCH_LOG_BYTES); + ret = register_dtl(hwcpu, __pa(dtl)); + if (ret) + pr_err("WARNING: DTL registration of cpu %d (hw %d) failed with %ld\n", + cpu, hwcpu, ret); + + lppaca_of(cpu).dtl_enable_mask = DTL_LOG_PREEMPT; + } +} + void vpa_init(int cpu) { int hwcpu = get_hard_smp_processor_id(cpu); unsigned long addr; long ret; - struct paca_struct *pp; - struct dtl_entry *dtl; /* * The spec says it "may be problematic" if CPU x registers the VPA of @@ -112,22 +158,7 @@ void vpa_init(int cpu) /* * Register dispatch trace log, if one has been allocated. */ - pp = paca_ptrs[cpu]; - dtl = pp->dispatch_log; - if (dtl) { - pp->dtl_ridx = 0; - pp->dtl_curr = dtl; - lppaca_of(cpu).dtl_idx = 0; - - /* hypervisor reads buffer length from this field */ - dtl->enqueue_to_dispatch_time = cpu_to_be32(DISPATCH_LOG_BYTES); - ret = register_dtl(hwcpu, __pa(dtl)); - if (ret) - pr_err("WARNING: DTL registration of cpu %d (hw %d) " - "failed with %ld\n", smp_processor_id(), - hwcpu, ret); - lppaca_of(cpu).dtl_enable_mask = DTL_LOG_PREEMPT; - } + register_dtl_buffer(cpu); } #ifdef CONFIG_PPC_BOOK3S_64 diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index e2cb29e96fa4..9d106494cc2d 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -279,46 +279,16 @@ struct kmem_cache *dtl_cache; */ static int alloc_dispatch_logs(void) { - int cpu, ret; - struct paca_struct *pp; - struct dtl_entry *dtl; - if (!firmware_has_feature(FW_FEATURE_SPLPAR)) return 0; if (!dtl_cache) return 0; - for_each_possible_cpu(cpu) { - pp = paca_ptrs[cpu]; - dtl = kmem_cache_alloc(dtl_cache, GFP_KERNEL); - if (!dtl) { - pr_warn("Failed to allocate dispatch trace log for cpu %d\n", - cpu); - pr_warn("Stolen time statistics will be unreliable\n"); - break; - } - - pp->dtl_ridx = 0; - pp->dispatch_log = dtl; - pp->dispatch_log_end = dtl + N_DISPATCH_LOG; - pp->dtl_curr = dtl; - } + alloc_dtl_buffers(); /* Register the DTL for the current (boot) cpu */ - dtl = get_paca()->dispatch_log; - get_paca()->dtl_ridx = 0; - get_paca()->dtl_curr = dtl; - get_paca()->lppaca_ptr->dtl_idx = 0; - - /* hypervisor reads buffer length from this field */ - dtl->enqueue_to_dispatch_time = cpu_to_be32(DISPATCH_LOG_BYTES); - ret = register_dtl(hard_smp_processor_id(), __pa(dtl)); - if (ret) - pr_err("WARNING: DTL registration of cpu %d (hw %d) failed " - "with %d\n", smp_processor_id(), - hard_smp_processor_id(), ret); - get_paca()->lppaca_ptr->dtl_enable_mask = DTL_LOG_PREEMPT; + register_dtl_buffer(smp_processor_id()); return 0; } -- cgit v1.2.3 From 06220d78f24a20549757be1014e57c382406cc92 Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Wed, 3 Jul 2019 22:33:57 +0530 Subject: powerpc/pseries: Introduce rwlock to gatekeep DTLB usage Since we would be introducing a new user of the DTL buffer in a subsequent patch, we need a way to gatekeep use of the DTL buffer. The current debugfs interface for DTL allows registering and opening cpu-specific DTL buffers. Cpu specific files are exposed under debugfs 'powerpc/dtl/' node, and changing 'dtl_event_mask' in the same directory enables controlling the event mask used when registering DTL buffer for a particular cpu. Subsequently, we will be introducing a user of the DTL buffers that registers access to the DTL buffers across all cpus with the same event mask. To ensure these two users do not step on each other, we introduce a rwlock to gatekeep DTL buffer access. This fits the requirement of the current debugfs interface wanting to allow multiple independent cpu-specific users (read lock), and the subsequent user wanting exclusive access (write lock). Suggested-by: Michael Ellerman Signed-off-by: Naveen N. Rao Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/lppaca.h | 2 ++ arch/powerpc/platforms/pseries/dtl.c | 11 ++++++++++- arch/powerpc/platforms/pseries/lpar.c | 4 ++++ 3 files changed, 16 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index a8ac2b8988d4..e45b7293414d 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -32,6 +32,7 @@ */ #include #include +#include #include #include #include @@ -166,6 +167,7 @@ struct dtl_entry { #define DTL_LOG_ALL (DTL_LOG_CEDE | DTL_LOG_PREEMPT | DTL_LOG_FAULT) extern struct kmem_cache *dtl_cache; +extern rwlock_t dtl_access_lock; /* * When CONFIG_VIRT_CPU_ACCOUNTING_NATIVE = y, the cpu accounting code controls diff --git a/arch/powerpc/platforms/pseries/dtl.c b/arch/powerpc/platforms/pseries/dtl.c index fb05804adb2f..ae4fb2a68758 100644 --- a/arch/powerpc/platforms/pseries/dtl.c +++ b/arch/powerpc/platforms/pseries/dtl.c @@ -193,11 +193,16 @@ static int dtl_enable(struct dtl *dtl) if (dtl->buf) return -EBUSY; + /* ensure there are no other conflicting dtl users */ + if (!read_trylock(&dtl_access_lock)) + return -EBUSY; + n_entries = dtl_buf_entries; buf = kmem_cache_alloc_node(dtl_cache, GFP_KERNEL, cpu_to_node(dtl->cpu)); if (!buf) { printk(KERN_WARNING "%s: buffer alloc failed for cpu %d\n", __func__, dtl->cpu); + read_unlock(&dtl_access_lock); return -ENOMEM; } @@ -214,8 +219,11 @@ static int dtl_enable(struct dtl *dtl) } spin_unlock(&dtl->lock); - if (rc) + if (rc) { + read_unlock(&dtl_access_lock); kmem_cache_free(dtl_cache, buf); + } + return rc; } @@ -227,6 +235,7 @@ static void dtl_disable(struct dtl *dtl) dtl->buf = NULL; dtl->buf_entries = 0; spin_unlock(&dtl->lock); + read_unlock(&dtl_access_lock); } /* file interface */ diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index da7e7c243864..7869121ab431 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -113,6 +113,10 @@ void register_dtl_buffer(int cpu) } } +#ifdef CONFIG_PPC_SPLPAR +DEFINE_RWLOCK(dtl_access_lock); +#endif /* CONFIG_PPC_SPLPAR */ + void vpa_init(int cpu) { int hwcpu = get_hard_smp_processor_id(cpu); -- cgit v1.2.3 From ef34e0efa22a867f8db16feb79fba9964cfbe253 Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Wed, 3 Jul 2019 22:33:58 +0530 Subject: powerpc/pseries: Generalize hcall_vphn() H_HOME_NODE_ASSOCIATIVITY hcall can take two different flags and return different associativity information in each case. Generalize the existing hcall_vphn() function to take flags as an argument and to return the result. Update the only existing user to pass the proper arguments. Signed-off-by: Naveen N. Rao Signed-off-by: Michael Ellerman --- arch/powerpc/mm/book3s64/vphn.h | 8 ++++++++ arch/powerpc/mm/numa.c | 27 +++++++++++++-------------- 2 files changed, 21 insertions(+), 14 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/book3s64/vphn.h b/arch/powerpc/mm/book3s64/vphn.h index f0b93c2dd578..f7ff1e0c3801 100644 --- a/arch/powerpc/mm/book3s64/vphn.h +++ b/arch/powerpc/mm/book3s64/vphn.h @@ -11,6 +11,14 @@ */ #define VPHN_ASSOC_BUFSIZE (VPHN_REGISTER_COUNT*sizeof(u64)/sizeof(u16) + 1) +/* + * The H_HOME_NODE_ASSOCIATIVITY hcall takes two values for flags: + * 1 for retrieving associativity information for a guest cpu + * 2 for retrieving associativity information for a host/hypervisor cpu + */ +#define VPHN_FLAG_VCPU 1 +#define VPHN_FLAG_PCPU 2 + extern int vphn_unpack_associativity(const long *packed, __be32 *unpacked); #endif diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 57e64273cb33..57f006b6214b 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1087,6 +1087,17 @@ static void reset_topology_timer(void); static int topology_timer_secs = 1; static int topology_inited; +static long hcall_vphn(unsigned long cpu, u64 flags, __be32 *associativity) +{ + long rc; + long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; + + rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, cpu); + vphn_unpack_associativity(retbuf, associativity); + + return rc; +} + /* * Change polling interval for associativity changes. */ @@ -1165,25 +1176,13 @@ static int update_cpu_associativity_changes_mask(void) * Retrieve the new associativity information for a virtual processor's * home node. */ -static long hcall_vphn(unsigned long cpu, __be32 *associativity) -{ - long rc; - long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; - u64 flags = 1; - int hwcpu = get_hard_smp_processor_id(cpu); - - rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, hwcpu); - vphn_unpack_associativity(retbuf, associativity); - - return rc; -} - static long vphn_get_associativity(unsigned long cpu, __be32 *associativity) { long rc; - rc = hcall_vphn(cpu, associativity); + rc = hcall_vphn(get_hard_smp_processor_id(cpu), + VPHN_FLAG_VCPU, associativity); switch (rc) { case H_FUNCTION: -- cgit v1.2.3 From 5a1ea4774ddc2c6bc3ba1415880091eccf1a901e Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Wed, 3 Jul 2019 22:33:59 +0530 Subject: powerpc/pseries: Move mm/book3s64/vphn.c under platforms/pseries/ hcall_vphn() is specific to pseries and will be used in a subsequent patch. So, move it to a more appropriate place under arch/powerpc/platforms/pseries. Also merge vphn.h into lppaca.h and update vphn selftest to use the new files. Signed-off-by: Naveen N. Rao Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/lppaca.h | 24 ++++++ arch/powerpc/mm/book3s64/Makefile | 1 - arch/powerpc/mm/book3s64/vphn.c | 73 ------------------- arch/powerpc/mm/book3s64/vphn.h | 24 ------ arch/powerpc/mm/numa.c | 14 ---- arch/powerpc/platforms/pseries/Makefile | 1 + arch/powerpc/platforms/pseries/vphn.c | 89 +++++++++++++++++++++++ tools/testing/selftests/powerpc/vphn/Makefile | 2 +- tools/testing/selftests/powerpc/vphn/asm/lppaca.h | 1 + tools/testing/selftests/powerpc/vphn/vphn.c | 2 +- tools/testing/selftests/powerpc/vphn/vphn.h | 1 - 11 files changed, 117 insertions(+), 115 deletions(-) delete mode 100644 arch/powerpc/mm/book3s64/vphn.c delete mode 100644 arch/powerpc/mm/book3s64/vphn.h create mode 100644 arch/powerpc/platforms/pseries/vphn.c create mode 120000 tools/testing/selftests/powerpc/vphn/asm/lppaca.h delete mode 120000 tools/testing/selftests/powerpc/vphn/vphn.h (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index e45b7293414d..f5195b4d9ffb 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -18,6 +18,29 @@ */ #ifndef _ASM_POWERPC_LPPACA_H #define _ASM_POWERPC_LPPACA_H + +/* + * The below VPHN macros are outside the __KERNEL__ check since these are + * used for compiling the vphn selftest in userspace + */ + +/* The H_HOME_NODE_ASSOCIATIVITY h_call returns 6 64-bit registers. */ +#define VPHN_REGISTER_COUNT 6 + +/* + * 6 64-bit registers unpacked into up to 24 be32 associativity values. To + * form the complete property we have to add the length in the first cell. + */ +#define VPHN_ASSOC_BUFSIZE (VPHN_REGISTER_COUNT*sizeof(u64)/sizeof(u16) + 1) + +/* + * The H_HOME_NODE_ASSOCIATIVITY hcall takes two values for flags: + * 1 for retrieving associativity information for a guest cpu + * 2 for retrieving associativity information for a host/hypervisor cpu + */ +#define VPHN_FLAG_VCPU 1 +#define VPHN_FLAG_PCPU 2 + #ifdef __KERNEL__ /* @@ -179,6 +202,7 @@ extern void (*dtl_consumer)(struct dtl_entry *entry, u64 index); extern void register_dtl_buffer(int cpu); extern void alloc_dtl_buffers(void); +extern long hcall_vphn(unsigned long cpu, u64 flags, __be32 *associativity); #endif /* CONFIG_PPC_BOOK3S */ #endif /* __KERNEL__ */ diff --git a/arch/powerpc/mm/book3s64/Makefile b/arch/powerpc/mm/book3s64/Makefile index 974b4fc19f4f..fd393b8be14f 100644 --- a/arch/powerpc/mm/book3s64/Makefile +++ b/arch/powerpc/mm/book3s64/Makefile @@ -10,7 +10,6 @@ obj-$(CONFIG_PPC_NATIVE) += hash_native.o obj-$(CONFIG_PPC_RADIX_MMU) += radix_pgtable.o radix_tlb.o obj-$(CONFIG_PPC_4K_PAGES) += hash_4k.o obj-$(CONFIG_PPC_64K_PAGES) += hash_64k.o -obj-$(CONFIG_PPC_SPLPAR) += vphn.o obj-$(CONFIG_HUGETLB_PAGE) += hash_hugetlbpage.o ifdef CONFIG_HUGETLB_PAGE obj-$(CONFIG_PPC_RADIX_MMU) += radix_hugetlbpage.o diff --git a/arch/powerpc/mm/book3s64/vphn.c b/arch/powerpc/mm/book3s64/vphn.c deleted file mode 100644 index 0ee7734afb50..000000000000 --- a/arch/powerpc/mm/book3s64/vphn.c +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -#include -#include "vphn.h" - -/* - * The associativity domain numbers are returned from the hypervisor as a - * stream of mixed 16-bit and 32-bit fields. The stream is terminated by the - * special value of "all ones" (aka. 0xffff) and its size may not exceed 48 - * bytes. - * - * --- 16-bit fields --> - * _________________________ - * | 0 | 1 | 2 | 3 | be_packed[0] - * ------+-----+-----+------ - * _________________________ - * | 4 | 5 | 6 | 7 | be_packed[1] - * ------------------------- - * ... - * _________________________ - * | 20 | 21 | 22 | 23 | be_packed[5] - * ------------------------- - * - * Convert to the sequence they would appear in the ibm,associativity property. - */ -int vphn_unpack_associativity(const long *packed, __be32 *unpacked) -{ - __be64 be_packed[VPHN_REGISTER_COUNT]; - int i, nr_assoc_doms = 0; - const __be16 *field = (const __be16 *) be_packed; - u16 last = 0; - bool is_32bit = false; - -#define VPHN_FIELD_UNUSED (0xffff) -#define VPHN_FIELD_MSB (0x8000) -#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB) - - /* Let's fix the values returned by plpar_hcall9() */ - for (i = 0; i < VPHN_REGISTER_COUNT; i++) - be_packed[i] = cpu_to_be64(packed[i]); - - for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) { - u16 new = be16_to_cpup(field++); - - if (is_32bit) { - /* - * Let's concatenate the 16 bits of this field to the - * 15 lower bits of the previous field - */ - unpacked[++nr_assoc_doms] = - cpu_to_be32(last << 16 | new); - is_32bit = false; - } else if (new == VPHN_FIELD_UNUSED) - /* This is the list terminator */ - break; - else if (new & VPHN_FIELD_MSB) { - /* Data is in the lower 15 bits of this field */ - unpacked[++nr_assoc_doms] = - cpu_to_be32(new & VPHN_FIELD_MASK); - } else { - /* - * Data is in the lower 15 bits of this field - * concatenated with the next 16 bit field - */ - last = new; - is_32bit = true; - } - } - - /* The first cell contains the length of the property */ - unpacked[0] = cpu_to_be32(nr_assoc_doms); - - return nr_assoc_doms; -} diff --git a/arch/powerpc/mm/book3s64/vphn.h b/arch/powerpc/mm/book3s64/vphn.h deleted file mode 100644 index f7ff1e0c3801..000000000000 --- a/arch/powerpc/mm/book3s64/vphn.h +++ /dev/null @@ -1,24 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef _ARCH_POWERPC_MM_VPHN_H_ -#define _ARCH_POWERPC_MM_VPHN_H_ - -/* The H_HOME_NODE_ASSOCIATIVITY h_call returns 6 64-bit registers. */ -#define VPHN_REGISTER_COUNT 6 - -/* - * 6 64-bit registers unpacked into up to 24 be32 associativity values. To - * form the complete property we have to add the length in the first cell. - */ -#define VPHN_ASSOC_BUFSIZE (VPHN_REGISTER_COUNT*sizeof(u64)/sizeof(u16) + 1) - -/* - * The H_HOME_NODE_ASSOCIATIVITY hcall takes two values for flags: - * 1 for retrieving associativity information for a guest cpu - * 2 for retrieving associativity information for a host/hypervisor cpu - */ -#define VPHN_FLAG_VCPU 1 -#define VPHN_FLAG_PCPU 2 - -extern int vphn_unpack_associativity(const long *packed, __be32 *unpacked); - -#endif diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 57f006b6214b..50fadc99897b 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -1067,9 +1067,6 @@ u64 memory_hotplug_max(void) /* Virtual Processor Home Node (VPHN) support */ #ifdef CONFIG_PPC_SPLPAR - -#include "book3s64/vphn.h" - struct topology_update_data { struct topology_update_data *next; unsigned int cpu; @@ -1087,17 +1084,6 @@ static void reset_topology_timer(void); static int topology_timer_secs = 1; static int topology_inited; -static long hcall_vphn(unsigned long cpu, u64 flags, __be32 *associativity) -{ - long rc; - long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; - - rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, cpu); - vphn_unpack_associativity(retbuf, associativity); - - return rc; -} - /* * Change polling interval for associativity changes. */ diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index a43ec843c8e2..ab3d59aeacca 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_LPARCFG) += lparcfg.o obj-$(CONFIG_IBMVIO) += vio.o obj-$(CONFIG_IBMEBUS) += ibmebus.o obj-$(CONFIG_PAPR_SCM) += papr_scm.o +obj-$(CONFIG_PPC_SPLPAR) += vphn.o ifdef CONFIG_PPC_PSERIES obj-$(CONFIG_SUSPEND) += suspend.o diff --git a/arch/powerpc/platforms/pseries/vphn.c b/arch/powerpc/platforms/pseries/vphn.c new file mode 100644 index 000000000000..3f07bf6c670e --- /dev/null +++ b/arch/powerpc/platforms/pseries/vphn.c @@ -0,0 +1,89 @@ +// SPDX-License-Identifier: GPL-2.0 +#include +#include + +/* + * The associativity domain numbers are returned from the hypervisor as a + * stream of mixed 16-bit and 32-bit fields. The stream is terminated by the + * special value of "all ones" (aka. 0xffff) and its size may not exceed 48 + * bytes. + * + * --- 16-bit fields --> + * _________________________ + * | 0 | 1 | 2 | 3 | be_packed[0] + * ------+-----+-----+------ + * _________________________ + * | 4 | 5 | 6 | 7 | be_packed[1] + * ------------------------- + * ... + * _________________________ + * | 20 | 21 | 22 | 23 | be_packed[5] + * ------------------------- + * + * Convert to the sequence they would appear in the ibm,associativity property. + */ +static int vphn_unpack_associativity(const long *packed, __be32 *unpacked) +{ + __be64 be_packed[VPHN_REGISTER_COUNT]; + int i, nr_assoc_doms = 0; + const __be16 *field = (const __be16 *) be_packed; + u16 last = 0; + bool is_32bit = false; + +#define VPHN_FIELD_UNUSED (0xffff) +#define VPHN_FIELD_MSB (0x8000) +#define VPHN_FIELD_MASK (~VPHN_FIELD_MSB) + + /* Let's fix the values returned by plpar_hcall9() */ + for (i = 0; i < VPHN_REGISTER_COUNT; i++) + be_packed[i] = cpu_to_be64(packed[i]); + + for (i = 1; i < VPHN_ASSOC_BUFSIZE; i++) { + u16 new = be16_to_cpup(field++); + + if (is_32bit) { + /* + * Let's concatenate the 16 bits of this field to the + * 15 lower bits of the previous field + */ + unpacked[++nr_assoc_doms] = + cpu_to_be32(last << 16 | new); + is_32bit = false; + } else if (new == VPHN_FIELD_UNUSED) + /* This is the list terminator */ + break; + else if (new & VPHN_FIELD_MSB) { + /* Data is in the lower 15 bits of this field */ + unpacked[++nr_assoc_doms] = + cpu_to_be32(new & VPHN_FIELD_MASK); + } else { + /* + * Data is in the lower 15 bits of this field + * concatenated with the next 16 bit field + */ + last = new; + is_32bit = true; + } + } + + /* The first cell contains the length of the property */ + unpacked[0] = cpu_to_be32(nr_assoc_doms); + + return nr_assoc_doms; +} + +/* NOTE: This file is included by a selftest and built in userspace. */ +#ifdef __KERNEL__ +#include + +long hcall_vphn(unsigned long cpu, u64 flags, __be32 *associativity) +{ + long rc; + long retbuf[PLPAR_HCALL9_BUFSIZE] = {0}; + + rc = plpar_hcall9(H_HOME_NODE_ASSOCIATIVITY, retbuf, flags, cpu); + vphn_unpack_associativity(retbuf, associativity); + + return rc; +} +#endif diff --git a/tools/testing/selftests/powerpc/vphn/Makefile b/tools/testing/selftests/powerpc/vphn/Makefile index 18b885da01bd..cf65cbf33085 100644 --- a/tools/testing/selftests/powerpc/vphn/Makefile +++ b/tools/testing/selftests/powerpc/vphn/Makefile @@ -1,7 +1,7 @@ # SPDX-License-Identifier: GPL-2.0-only TEST_GEN_PROGS := test-vphn -CFLAGS += -m64 +CFLAGS += -m64 -I$(CURDIR) top_srcdir = ../../../../.. include ../../lib.mk diff --git a/tools/testing/selftests/powerpc/vphn/asm/lppaca.h b/tools/testing/selftests/powerpc/vphn/asm/lppaca.h new file mode 120000 index 000000000000..942b1d00999c --- /dev/null +++ b/tools/testing/selftests/powerpc/vphn/asm/lppaca.h @@ -0,0 +1 @@ +../../../../../../arch/powerpc/include/asm/lppaca.h \ No newline at end of file diff --git a/tools/testing/selftests/powerpc/vphn/vphn.c b/tools/testing/selftests/powerpc/vphn/vphn.c index 1d1f5f2be3b2..5b5fbddccabd 120000 --- a/tools/testing/selftests/powerpc/vphn/vphn.c +++ b/tools/testing/selftests/powerpc/vphn/vphn.c @@ -1 +1 @@ -../../../../../arch/powerpc/mm/book3s64/vphn.c \ No newline at end of file +../../../../../arch/powerpc/platforms/pseries/vphn.c \ No newline at end of file diff --git a/tools/testing/selftests/powerpc/vphn/vphn.h b/tools/testing/selftests/powerpc/vphn/vphn.h deleted file mode 120000 index 45fe160f8288..000000000000 --- a/tools/testing/selftests/powerpc/vphn/vphn.h +++ /dev/null @@ -1 +0,0 @@ -../../../../../arch/powerpc/mm/book3s64/vphn.h \ No newline at end of file -- cgit v1.2.3 From d62c8deeb6e69cd7815c21171a218301822e4a06 Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Wed, 3 Jul 2019 22:34:00 +0530 Subject: powerpc/pseries: Provide vcpu dispatch statistics For Shared Processor LPARs, the POWER Hypervisor maintains a relatively static mapping of the LPAR processors (vcpus) to physical processor chips (representing the "home" node) and tries to always dispatch vcpus on their associated physical processor chip. However, under certain scenarios, vcpus may be dispatched on a different processor chip (away from its home node). The actual physical processor number on which a certain vcpu is dispatched is available to the guest in the 'processor_id' field of each DTL entry. The guest can discover the home node of each vcpu through the H_HOME_NODE_ASSOCIATIVITY(flags=1) hcall. The guest can also discover the associativity of physical processors, as represented in the DTL entry, through the H_HOME_NODE_ASSOCIATIVITY(flags=2) hcall. These can then be compared to determine if the vcpu was dispatched on its home node or not. If the vcpu was not dispatched on the home node, it is possible to determine if the vcpu was dispatched in a different chip, socket or drawer. Introduce a procfs file /proc/powerpc/vcpudispatch_stats that can be used to obtain these statistics. Writing '1' to this file enables collecting the statistics, while writing '0' disables the statistics. The statistics themselves are available by reading the procfs file. By default, the DTLB log for each vcpu is processed 50 times a second so as not to miss any entries. This processing frequency can be changed through /proc/powerpc/vcpudispatch_stats_freq. Signed-off-by: Naveen N. Rao Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/topology.h | 6 + arch/powerpc/mm/numa.c | 16 ++ arch/powerpc/platforms/pseries/lpar.c | 525 +++++++++++++++++++++++++++++++++- 3 files changed, 545 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h index f85e2b01c3df..2f7e1ea5089e 100644 --- a/arch/powerpc/include/asm/topology.h +++ b/arch/powerpc/include/asm/topology.h @@ -35,6 +35,7 @@ static inline int pcibus_to_node(struct pci_bus *bus) cpu_all_mask : \ cpumask_of_node(pcibus_to_node(bus))) +extern int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc); extern int __node_distance(int, int); #define node_distance(a, b) __node_distance(a, b) @@ -84,6 +85,11 @@ static inline int numa_update_cpu_topology(bool cpus_locked) static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node) {} +static inline int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc) +{ + return 0; +} + #endif /* CONFIG_NUMA */ #if defined(CONFIG_NUMA) && defined(CONFIG_PPC_SPLPAR) diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 50fadc99897b..26f479e6c8ed 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -167,6 +167,22 @@ static void unmap_cpu_from_node(unsigned long cpu) } #endif /* CONFIG_HOTPLUG_CPU || CONFIG_PPC_SPLPAR */ +int cpu_distance(__be32 *cpu1_assoc, __be32 *cpu2_assoc) +{ + int dist = 0; + + int i, index; + + for (i = 0; i < distance_ref_points_depth; i++) { + index = be32_to_cpu(distance_ref_points[i]); + if (cpu1_assoc[index] == cpu2_assoc[index]) + break; + dist++; + } + + return dist; +} + /* must hold reference to node during call */ static const __be32 *of_get_associativity(struct device_node *dev) { diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index 7869121ab431..ec5a7893f71b 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -30,6 +30,10 @@ #include #include #include +#include +#include +#include +#include #include #include #include @@ -65,6 +69,12 @@ EXPORT_SYMBOL(plpar_hcall); EXPORT_SYMBOL(plpar_hcall9); EXPORT_SYMBOL(plpar_hcall_norets); +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE +static u8 dtl_mask = DTL_LOG_PREEMPT; +#else +static u8 dtl_mask; +#endif + void alloc_dtl_buffers(void) { int cpu; @@ -73,11 +83,15 @@ void alloc_dtl_buffers(void) for_each_possible_cpu(cpu) { pp = paca_ptrs[cpu]; + if (pp->dispatch_log) + continue; dtl = kmem_cache_alloc(dtl_cache, GFP_KERNEL); if (!dtl) { pr_warn("Failed to allocate dispatch trace log for cpu %d\n", cpu); +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE pr_warn("Stolen time statistics will be unreliable\n"); +#endif break; } @@ -97,7 +111,7 @@ void register_dtl_buffer(int cpu) pp = paca_ptrs[cpu]; dtl = pp->dispatch_log; - if (dtl) { + if (dtl && dtl_mask) { pp->dtl_ridx = 0; pp->dtl_curr = dtl; lppaca_of(cpu).dtl_idx = 0; @@ -109,12 +123,519 @@ void register_dtl_buffer(int cpu) pr_err("WARNING: DTL registration of cpu %d (hw %d) failed with %ld\n", cpu, hwcpu, ret); - lppaca_of(cpu).dtl_enable_mask = DTL_LOG_PREEMPT; + lppaca_of(cpu).dtl_enable_mask = dtl_mask; } } #ifdef CONFIG_PPC_SPLPAR +struct dtl_worker { + struct delayed_work work; + int cpu; +}; + +struct vcpu_dispatch_data { + int last_disp_cpu; + + int total_disp; + + int same_cpu_disp; + int same_chip_disp; + int diff_chip_disp; + int far_chip_disp; + + int numa_home_disp; + int numa_remote_disp; + int numa_far_disp; +}; + +/* + * This represents the number of cpus in the hypervisor. Since there is no + * architected way to discover the number of processors in the host, we + * provision for dealing with NR_CPUS. This is currently 2048 by default, and + * is sufficient for our purposes. This will need to be tweaked if + * CONFIG_NR_CPUS is changed. + */ +#define NR_CPUS_H NR_CPUS + DEFINE_RWLOCK(dtl_access_lock); +static DEFINE_PER_CPU(struct vcpu_dispatch_data, vcpu_disp_data); +static DEFINE_PER_CPU(u64, dtl_entry_ridx); +static DEFINE_PER_CPU(struct dtl_worker, dtl_workers); +static enum cpuhp_state dtl_worker_state; +static DEFINE_MUTEX(dtl_enable_mutex); +static int vcpudispatch_stats_on __read_mostly; +static int vcpudispatch_stats_freq = 50; +static __be32 *vcpu_associativity, *pcpu_associativity; + + +static void free_dtl_buffers(void) +{ +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE + int cpu; + struct paca_struct *pp; + + for_each_possible_cpu(cpu) { + pp = paca_ptrs[cpu]; + if (!pp->dispatch_log) + continue; + kmem_cache_free(dtl_cache, pp->dispatch_log); + pp->dtl_ridx = 0; + pp->dispatch_log = 0; + pp->dispatch_log_end = 0; + pp->dtl_curr = 0; + } +#endif +} + +static int init_cpu_associativity(void) +{ + vcpu_associativity = kcalloc(num_possible_cpus() / threads_per_core, + VPHN_ASSOC_BUFSIZE * sizeof(__be32), GFP_KERNEL); + pcpu_associativity = kcalloc(NR_CPUS_H / threads_per_core, + VPHN_ASSOC_BUFSIZE * sizeof(__be32), GFP_KERNEL); + + if (!vcpu_associativity || !pcpu_associativity) { + pr_err("error allocating memory for associativity information\n"); + return -ENOMEM; + } + + return 0; +} + +static void destroy_cpu_associativity(void) +{ + kfree(vcpu_associativity); + kfree(pcpu_associativity); + vcpu_associativity = pcpu_associativity = 0; +} + +static __be32 *__get_cpu_associativity(int cpu, __be32 *cpu_assoc, int flag) +{ + __be32 *assoc; + int rc = 0; + + assoc = &cpu_assoc[(int)(cpu / threads_per_core) * VPHN_ASSOC_BUFSIZE]; + if (!assoc[0]) { + rc = hcall_vphn(cpu, flag, &assoc[0]); + if (rc) + return NULL; + } + + return assoc; +} + +static __be32 *get_pcpu_associativity(int cpu) +{ + return __get_cpu_associativity(cpu, pcpu_associativity, VPHN_FLAG_PCPU); +} + +static __be32 *get_vcpu_associativity(int cpu) +{ + return __get_cpu_associativity(cpu, vcpu_associativity, VPHN_FLAG_VCPU); +} + +static int cpu_relative_dispatch_distance(int last_disp_cpu, int cur_disp_cpu) +{ + __be32 *last_disp_cpu_assoc, *cur_disp_cpu_assoc; + + if (last_disp_cpu >= NR_CPUS_H || cur_disp_cpu >= NR_CPUS_H) + return -EINVAL; + + last_disp_cpu_assoc = get_pcpu_associativity(last_disp_cpu); + cur_disp_cpu_assoc = get_pcpu_associativity(cur_disp_cpu); + + if (!last_disp_cpu_assoc || !cur_disp_cpu_assoc) + return -EIO; + + return cpu_distance(last_disp_cpu_assoc, cur_disp_cpu_assoc); +} + +static int cpu_home_node_dispatch_distance(int disp_cpu) +{ + __be32 *disp_cpu_assoc, *vcpu_assoc; + int vcpu_id = smp_processor_id(); + + if (disp_cpu >= NR_CPUS_H) { + pr_debug_ratelimited("vcpu dispatch cpu %d > %d\n", + disp_cpu, NR_CPUS_H); + return -EINVAL; + } + + disp_cpu_assoc = get_pcpu_associativity(disp_cpu); + vcpu_assoc = get_vcpu_associativity(vcpu_id); + + if (!disp_cpu_assoc || !vcpu_assoc) + return -EIO; + + return cpu_distance(disp_cpu_assoc, vcpu_assoc); +} + +static void update_vcpu_disp_stat(int disp_cpu) +{ + struct vcpu_dispatch_data *disp; + int distance; + + disp = this_cpu_ptr(&vcpu_disp_data); + if (disp->last_disp_cpu == -1) { + disp->last_disp_cpu = disp_cpu; + return; + } + + disp->total_disp++; + + if (disp->last_disp_cpu == disp_cpu || + (cpu_first_thread_sibling(disp->last_disp_cpu) == + cpu_first_thread_sibling(disp_cpu))) + disp->same_cpu_disp++; + else { + distance = cpu_relative_dispatch_distance(disp->last_disp_cpu, + disp_cpu); + if (distance < 0) + pr_debug_ratelimited("vcpudispatch_stats: cpu %d: error determining associativity\n", + smp_processor_id()); + else { + switch (distance) { + case 0: + disp->same_chip_disp++; + break; + case 1: + disp->diff_chip_disp++; + break; + case 2: + disp->far_chip_disp++; + break; + default: + pr_debug_ratelimited("vcpudispatch_stats: cpu %d (%d -> %d): unexpected relative dispatch distance %d\n", + smp_processor_id(), + disp->last_disp_cpu, + disp_cpu, + distance); + } + } + } + + distance = cpu_home_node_dispatch_distance(disp_cpu); + if (distance < 0) + pr_debug_ratelimited("vcpudispatch_stats: cpu %d: error determining associativity\n", + smp_processor_id()); + else { + switch (distance) { + case 0: + disp->numa_home_disp++; + break; + case 1: + disp->numa_remote_disp++; + break; + case 2: + disp->numa_far_disp++; + break; + default: + pr_debug_ratelimited("vcpudispatch_stats: cpu %d on %d: unexpected numa dispatch distance %d\n", + smp_processor_id(), + disp_cpu, + distance); + } + } + + disp->last_disp_cpu = disp_cpu; +} + +static void process_dtl_buffer(struct work_struct *work) +{ + struct dtl_entry dtle; + u64 i = __this_cpu_read(dtl_entry_ridx); + struct dtl_entry *dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG); + struct dtl_entry *dtl_end = local_paca->dispatch_log_end; + struct lppaca *vpa = local_paca->lppaca_ptr; + struct dtl_worker *d = container_of(work, struct dtl_worker, work.work); + + if (!local_paca->dispatch_log) + return; + + /* if we have been migrated away, we cancel ourself */ + if (d->cpu != smp_processor_id()) { + pr_debug("vcpudispatch_stats: cpu %d worker migrated -- canceling worker\n", + smp_processor_id()); + return; + } + + if (i == be64_to_cpu(vpa->dtl_idx)) + goto out; + + while (i < be64_to_cpu(vpa->dtl_idx)) { + dtle = *dtl; + barrier(); + if (i + N_DISPATCH_LOG < be64_to_cpu(vpa->dtl_idx)) { + /* buffer has overflowed */ + pr_debug_ratelimited("vcpudispatch_stats: cpu %d lost %lld DTL samples\n", + d->cpu, + be64_to_cpu(vpa->dtl_idx) - N_DISPATCH_LOG - i); + i = be64_to_cpu(vpa->dtl_idx) - N_DISPATCH_LOG; + dtl = local_paca->dispatch_log + (i % N_DISPATCH_LOG); + continue; + } + update_vcpu_disp_stat(be16_to_cpu(dtle.processor_id)); + ++i; + ++dtl; + if (dtl == dtl_end) + dtl = local_paca->dispatch_log; + } + + __this_cpu_write(dtl_entry_ridx, i); + +out: + schedule_delayed_work_on(d->cpu, to_delayed_work(work), + HZ / vcpudispatch_stats_freq); +} + +static int dtl_worker_online(unsigned int cpu) +{ + struct dtl_worker *d = &per_cpu(dtl_workers, cpu); + + memset(d, 0, sizeof(*d)); + INIT_DELAYED_WORK(&d->work, process_dtl_buffer); + d->cpu = cpu; + +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE + per_cpu(dtl_entry_ridx, cpu) = 0; + register_dtl_buffer(cpu); +#else + per_cpu(dtl_entry_ridx, cpu) = be64_to_cpu(lppaca_of(cpu).dtl_idx); +#endif + + schedule_delayed_work_on(cpu, &d->work, HZ / vcpudispatch_stats_freq); + return 0; +} + +static int dtl_worker_offline(unsigned int cpu) +{ + struct dtl_worker *d = &per_cpu(dtl_workers, cpu); + + cancel_delayed_work_sync(&d->work); + +#ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE + unregister_dtl(get_hard_smp_processor_id(cpu)); +#endif + + return 0; +} + +static void set_global_dtl_mask(u8 mask) +{ + int cpu; + + dtl_mask = mask; + for_each_present_cpu(cpu) + lppaca_of(cpu).dtl_enable_mask = dtl_mask; +} + +static void reset_global_dtl_mask(void) +{ + int cpu; + +#ifdef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE + dtl_mask = DTL_LOG_PREEMPT; +#else + dtl_mask = 0; +#endif + for_each_present_cpu(cpu) + lppaca_of(cpu).dtl_enable_mask = dtl_mask; +} + +static int dtl_worker_enable(void) +{ + int rc = 0, state; + + if (!write_trylock(&dtl_access_lock)) { + rc = -EBUSY; + goto out; + } + + set_global_dtl_mask(DTL_LOG_ALL); + + /* Setup dtl buffers and register those */ + alloc_dtl_buffers(); + + state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powerpc/dtl:online", + dtl_worker_online, dtl_worker_offline); + if (state < 0) { + pr_err("vcpudispatch_stats: unable to setup workqueue for DTL processing\n"); + free_dtl_buffers(); + reset_global_dtl_mask(); + write_unlock(&dtl_access_lock); + rc = -EINVAL; + goto out; + } + dtl_worker_state = state; + +out: + return rc; +} + +static void dtl_worker_disable(void) +{ + cpuhp_remove_state(dtl_worker_state); + free_dtl_buffers(); + reset_global_dtl_mask(); + write_unlock(&dtl_access_lock); +} + +static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p, + size_t count, loff_t *ppos) +{ + struct vcpu_dispatch_data *disp; + int rc, cmd, cpu; + char buf[16]; + + if (count > 15) + return -EINVAL; + + if (copy_from_user(buf, p, count)) + return -EFAULT; + + buf[count] = 0; + rc = kstrtoint(buf, 0, &cmd); + if (rc || cmd < 0 || cmd > 1) { + pr_err("vcpudispatch_stats: please use 0 to disable or 1 to enable dispatch statistics\n"); + return rc ? rc : -EINVAL; + } + + mutex_lock(&dtl_enable_mutex); + + if ((cmd == 0 && !vcpudispatch_stats_on) || + (cmd == 1 && vcpudispatch_stats_on)) + goto out; + + if (cmd) { + rc = init_cpu_associativity(); + if (rc) + goto out; + + for_each_possible_cpu(cpu) { + disp = per_cpu_ptr(&vcpu_disp_data, cpu); + memset(disp, 0, sizeof(*disp)); + disp->last_disp_cpu = -1; + } + + rc = dtl_worker_enable(); + if (rc) { + destroy_cpu_associativity(); + goto out; + } + } else { + dtl_worker_disable(); + destroy_cpu_associativity(); + } + + vcpudispatch_stats_on = cmd; + +out: + mutex_unlock(&dtl_enable_mutex); + if (rc) + return rc; + return count; +} + +static int vcpudispatch_stats_display(struct seq_file *p, void *v) +{ + int cpu; + struct vcpu_dispatch_data *disp; + + if (!vcpudispatch_stats_on) { + seq_puts(p, "off\n"); + return 0; + } + + for_each_online_cpu(cpu) { + disp = per_cpu_ptr(&vcpu_disp_data, cpu); + seq_printf(p, "cpu%d", cpu); + seq_put_decimal_ull(p, " ", disp->total_disp); + seq_put_decimal_ull(p, " ", disp->same_cpu_disp); + seq_put_decimal_ull(p, " ", disp->same_chip_disp); + seq_put_decimal_ull(p, " ", disp->diff_chip_disp); + seq_put_decimal_ull(p, " ", disp->far_chip_disp); + seq_put_decimal_ull(p, " ", disp->numa_home_disp); + seq_put_decimal_ull(p, " ", disp->numa_remote_disp); + seq_put_decimal_ull(p, " ", disp->numa_far_disp); + seq_puts(p, "\n"); + } + + return 0; +} + +static int vcpudispatch_stats_open(struct inode *inode, struct file *file) +{ + return single_open(file, vcpudispatch_stats_display, NULL); +} + +static const struct file_operations vcpudispatch_stats_proc_ops = { + .open = vcpudispatch_stats_open, + .read = seq_read, + .write = vcpudispatch_stats_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static ssize_t vcpudispatch_stats_freq_write(struct file *file, + const char __user *p, size_t count, loff_t *ppos) +{ + int rc, freq; + char buf[16]; + + if (count > 15) + return -EINVAL; + + if (copy_from_user(buf, p, count)) + return -EFAULT; + + buf[count] = 0; + rc = kstrtoint(buf, 0, &freq); + if (rc || freq < 1 || freq > HZ) { + pr_err("vcpudispatch_stats_freq: please specify a frequency between 1 and %d\n", + HZ); + return rc ? rc : -EINVAL; + } + + vcpudispatch_stats_freq = freq; + + return count; +} + +static int vcpudispatch_stats_freq_display(struct seq_file *p, void *v) +{ + seq_printf(p, "%d\n", vcpudispatch_stats_freq); + return 0; +} + +static int vcpudispatch_stats_freq_open(struct inode *inode, struct file *file) +{ + return single_open(file, vcpudispatch_stats_freq_display, NULL); +} + +static const struct file_operations vcpudispatch_stats_freq_proc_ops = { + .open = vcpudispatch_stats_freq_open, + .read = seq_read, + .write = vcpudispatch_stats_freq_write, + .llseek = seq_lseek, + .release = single_release, +}; + +static int __init vcpudispatch_stats_procfs_init(void) +{ + if (!lppaca_shared_proc(get_lppaca())) + return 0; + + if (!proc_create("powerpc/vcpudispatch_stats", 0600, NULL, + &vcpudispatch_stats_proc_ops)) + pr_err("vcpudispatch_stats: error creating procfs file\n"); + else if (!proc_create("powerpc/vcpudispatch_stats_freq", 0600, NULL, + &vcpudispatch_stats_freq_proc_ops)) + pr_err("vcpudispatch_stats_freq: error creating procfs file\n"); + + return 0; +} + +machine_device_initcall(pseries, vcpudispatch_stats_procfs_init); #endif /* CONFIG_PPC_SPLPAR */ void vpa_init(int cpu) -- cgit v1.2.3 From 18a593c8b5426f6a08bcb353636d761a83f78d9e Mon Sep 17 00:00:00 2001 From: "Naveen N. Rao" Date: Wed, 3 Jul 2019 22:34:01 +0530 Subject: powerpc/pseries: Protect against hogging the cpu while setting up the stats When enabling or disabling the vcpu dispatch statistics, we do a lot of work including allocating/deallocating memory across all possible cpus for the DTL buffer. In order to guard against hogging the cpu for too long, track the time we're taking and yield the processor if necessary. Signed-off-by: Naveen N. Rao Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/lppaca.h | 2 +- arch/powerpc/platforms/pseries/lpar.c | 29 ++++++++++++++++++++--------- arch/powerpc/platforms/pseries/setup.c | 2 +- 3 files changed, 22 insertions(+), 11 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/lppaca.h b/arch/powerpc/include/asm/lppaca.h index f5195b4d9ffb..d7952665945a 100644 --- a/arch/powerpc/include/asm/lppaca.h +++ b/arch/powerpc/include/asm/lppaca.h @@ -201,7 +201,7 @@ extern rwlock_t dtl_access_lock; extern void (*dtl_consumer)(struct dtl_entry *entry, u64 index); extern void register_dtl_buffer(int cpu); -extern void alloc_dtl_buffers(void); +extern void alloc_dtl_buffers(unsigned long *time_limit); extern long hcall_vphn(unsigned long cpu, u64 flags, __be32 *associativity); #endif /* CONFIG_PPC_BOOK3S */ diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c index ec5a7893f71b..ae7040f59564 100644 --- a/arch/powerpc/platforms/pseries/lpar.c +++ b/arch/powerpc/platforms/pseries/lpar.c @@ -75,7 +75,7 @@ static u8 dtl_mask = DTL_LOG_PREEMPT; static u8 dtl_mask; #endif -void alloc_dtl_buffers(void) +void alloc_dtl_buffers(unsigned long *time_limit) { int cpu; struct paca_struct *pp; @@ -99,6 +99,11 @@ void alloc_dtl_buffers(void) pp->dispatch_log = dtl; pp->dispatch_log_end = dtl + N_DISPATCH_LOG; pp->dtl_curr = dtl; + + if (time_limit && time_after(jiffies, *time_limit)) { + cond_resched(); + *time_limit = jiffies + HZ; + } } } @@ -168,7 +173,7 @@ static int vcpudispatch_stats_freq = 50; static __be32 *vcpu_associativity, *pcpu_associativity; -static void free_dtl_buffers(void) +static void free_dtl_buffers(unsigned long *time_limit) { #ifndef CONFIG_VIRT_CPU_ACCOUNTING_NATIVE int cpu; @@ -183,6 +188,11 @@ static void free_dtl_buffers(void) pp->dispatch_log = 0; pp->dispatch_log_end = 0; pp->dtl_curr = 0; + + if (time_limit && time_after(jiffies, *time_limit)) { + cond_resched(); + *time_limit = jiffies + HZ; + } } #endif } @@ -442,7 +452,7 @@ static void reset_global_dtl_mask(void) lppaca_of(cpu).dtl_enable_mask = dtl_mask; } -static int dtl_worker_enable(void) +static int dtl_worker_enable(unsigned long *time_limit) { int rc = 0, state; @@ -454,13 +464,13 @@ static int dtl_worker_enable(void) set_global_dtl_mask(DTL_LOG_ALL); /* Setup dtl buffers and register those */ - alloc_dtl_buffers(); + alloc_dtl_buffers(time_limit); state = cpuhp_setup_state(CPUHP_AP_ONLINE_DYN, "powerpc/dtl:online", dtl_worker_online, dtl_worker_offline); if (state < 0) { pr_err("vcpudispatch_stats: unable to setup workqueue for DTL processing\n"); - free_dtl_buffers(); + free_dtl_buffers(time_limit); reset_global_dtl_mask(); write_unlock(&dtl_access_lock); rc = -EINVAL; @@ -472,10 +482,10 @@ out: return rc; } -static void dtl_worker_disable(void) +static void dtl_worker_disable(unsigned long *time_limit) { cpuhp_remove_state(dtl_worker_state); - free_dtl_buffers(); + free_dtl_buffers(time_limit); reset_global_dtl_mask(); write_unlock(&dtl_access_lock); } @@ -483,6 +493,7 @@ static void dtl_worker_disable(void) static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p, size_t count, loff_t *ppos) { + unsigned long time_limit = jiffies + HZ; struct vcpu_dispatch_data *disp; int rc, cmd, cpu; char buf[16]; @@ -517,13 +528,13 @@ static ssize_t vcpudispatch_stats_write(struct file *file, const char __user *p, disp->last_disp_cpu = -1; } - rc = dtl_worker_enable(); + rc = dtl_worker_enable(&time_limit); if (rc) { destroy_cpu_associativity(); goto out; } } else { - dtl_worker_disable(); + dtl_worker_disable(&time_limit); destroy_cpu_associativity(); } diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 9d106494cc2d..cb418d2bb1ac 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c @@ -285,7 +285,7 @@ static int alloc_dispatch_logs(void) if (!dtl_cache) return 0; - alloc_dtl_buffers(); + alloc_dtl_buffers(0); /* Register the DTL for the current (boot) cpu */ register_dtl_buffer(smp_processor_id()); -- cgit v1.2.3 From b8c8a524ccad1244916a203ae40292e2786e1b26 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 1 Jul 2019 20:07:00 +0530 Subject: powerpc/mm: Remove unused variable declaration Since commit 0034d395f89d ("powerpc/mm/hash64: Map all the kernel regions in the same 0xc range") __kernel_virt_size is not used anymore. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/pgtable.h | 1 - 1 file changed, 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 5faceeefd9f9..beabb099c040 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -283,7 +283,6 @@ static inline unsigned int ioremap_max_order(void) #define IOREMAP_MAX_ORDER ioremap_max_order() extern unsigned long __kernel_virt_start; -extern unsigned long __kernel_virt_size; extern unsigned long __kernel_io_start; extern unsigned long __kernel_io_end; #define KERN_VIRT_START __kernel_virt_start -- cgit v1.2.3 From 78c949888549a6318ae420802703408caae999f5 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 1 Jul 2019 20:04:41 +0530 Subject: powerpc/mm/hash/4k: Don't use 64K page size for vmemmap with 4K pagesize With hash translation and 4K PAGE_SIZE config, we need to make sure we don't use 64K page size for vmemmap. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/book3s64/hash_utils.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/book3s64/hash_utils.c b/arch/powerpc/mm/book3s64/hash_utils.c index 1ff451892d7f..25a2cf32d544 100644 --- a/arch/powerpc/mm/book3s64/hash_utils.c +++ b/arch/powerpc/mm/book3s64/hash_utils.c @@ -688,10 +688,8 @@ static void __init htab_init_page_sizes(void) if (mmu_psize_defs[MMU_PAGE_16M].shift && memblock_phys_mem_size() >= 0x40000000) mmu_vmemmap_psize = MMU_PAGE_16M; - else if (mmu_psize_defs[MMU_PAGE_64K].shift) - mmu_vmemmap_psize = MMU_PAGE_64K; else - mmu_vmemmap_psize = MMU_PAGE_4K; + mmu_vmemmap_psize = mmu_virtual_psize; #endif /* CONFIG_SPARSEMEM_VMEMMAP */ printk(KERN_DEBUG "Page orders: linear mapping = %d, " -- cgit v1.2.3 From 89a3496e0664577043666791ec07fb731d57c950 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 1 Jul 2019 20:04:42 +0530 Subject: powerpc/mm/radix: Use the right page size for vmemmap mapping We use mmu_vmemmap_psize to find the page size for mapping the vmmemap area. With radix translation, we are suboptimally setting this value to PAGE_SIZE. We do check for 2M page size support and update mmu_vmemap_psize to use hugepage size but we suboptimally reset the value to PAGE_SIZE in radix__early_init_mmu(). This resulted in always mapping vmemmap area with 64K page size. Fixes: 2bfd65e45e87 ("powerpc/mm/radix: Add radix callbacks for early init routines") Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/book3s64/radix_pgtable.c | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index 8904aa1243d8..b573fa024b32 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -520,14 +520,6 @@ void __init radix__early_init_devtree(void) mmu_psize_defs[MMU_PAGE_64K].shift = 16; mmu_psize_defs[MMU_PAGE_64K].ap = 0x5; found: -#ifdef CONFIG_SPARSEMEM_VMEMMAP - if (mmu_psize_defs[MMU_PAGE_2M].shift) { - /* - * map vmemmap using 2M if available - */ - mmu_vmemmap_psize = MMU_PAGE_2M; - } -#endif /* CONFIG_SPARSEMEM_VMEMMAP */ return; } @@ -592,7 +584,13 @@ void __init radix__early_init_mmu(void) #ifdef CONFIG_SPARSEMEM_VMEMMAP /* vmemmap mapping */ - mmu_vmemmap_psize = mmu_virtual_psize; + if (mmu_psize_defs[MMU_PAGE_2M].shift) { + /* + * map vmemmap using 2M if available + */ + mmu_vmemmap_psize = MMU_PAGE_2M; + } else + mmu_vmemmap_psize = mmu_virtual_psize; #endif /* * initialize page table size -- cgit v1.2.3 From ea9f5b702fe0215188fba2eda117419e4ae90a67 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 1 Jul 2019 20:06:24 +0530 Subject: powerpc/mm/drconf: Use NUMA_NO_NODE on failures instead of node 0 If we fail to parse the associativity array we should default to NUMA_NO_NODE instead of NODE 0. Rest of the code fallback to the right default if we find the numa node value NUMA_NO_NODE. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/numa.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index 26f479e6c8ed..b1ecfb850b5a 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -436,17 +436,19 @@ static int of_get_assoc_arrays(struct assoc_arrays *aa) static int of_drconf_to_nid_single(struct drmem_lmb *lmb) { struct assoc_arrays aa = { .arrays = NULL }; - int default_nid = 0; + int default_nid = NUMA_NO_NODE; int nid = default_nid; int rc, index; + if (min_common_depth < 0) + return default_nid; + rc = of_get_assoc_arrays(&aa); if (rc) return default_nid; - if (min_common_depth > 0 && min_common_depth <= aa.array_sz && - !(lmb->flags & DRCONF_MEM_AI_INVALID) && - lmb->aa_index < aa.n_arrays) { + if (min_common_depth <= aa.array_sz && + !(lmb->flags & DRCONF_MEM_AI_INVALID) && lmb->aa_index < aa.n_arrays) { index = lmb->aa_index * aa.array_sz + min_common_depth - 1; nid = of_read_number(&aa.arrays[index], 1); -- cgit v1.2.3 From f52741c410cfb76582df21f02e4c062ee732b882 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 1 Jul 2019 20:06:25 +0530 Subject: powerpc/mm: Fix node look up with numa=off boot If we boot with numa=off, we need to make sure we return NUMA_NO_NODE when looking up associativity details of resources. Without this, we hit crash like below BUG: Unable to handle kernel data access at 0x40000000008 Faulting instruction address: 0xc000000008f31704 cpu 0x1b: Vector: 380 (Data SLB Access) at [c00000000b9bb320] pc: c000000008f31704: _raw_spin_lock+0x14/0x100 lr: c0000000083f41fc: ____cache_alloc_node+0x5c/0x290 sp: c00000000b9bb5b0 msr: 800000010280b033 dar: 40000000008 current = 0xc00000000b9a2700 paca = 0xc00000000a740c00 irqmask: 0x03 irq_happened: 0x01 pid = 1, comm = swapper/27 Linux version 5.2.0-rc4-00925-g74e188c620b1 (root@linux-d8ip) (gcc version 7.4.1 20190424 [gcc-7-branch revision 270538] (SUSE Linux)) #34 SMP Sat Jun 29 00:41:02 EDT 2019 enter ? for help [link register ] c0000000083f41fc ____cache_alloc_node+0x5c/0x290 [c00000000b9bb5b0] 0000000000000dc0 (unreliable) [c00000000b9bb5f0] c0000000083f48c8 kmem_cache_alloc_node_trace+0x138/0x360 [c00000000b9bb670] c000000008aa789c devres_alloc_node+0x4c/0xa0 [c00000000b9bb6a0] c000000008337218 devm_memremap+0x58/0x130 [c00000000b9bb6f0] c000000008aed00c devm_nsio_enable+0xdc/0x170 [c00000000b9bb780] c000000008af3b6c nd_pmem_probe+0x4c/0x180 [c00000000b9bb7b0] c000000008ad84cc nvdimm_bus_probe+0xac/0x260 [c00000000b9bb840] c000000008aa0628 really_probe+0x148/0x500 [c00000000b9bb8d0] c000000008aa0d7c driver_probe_device+0x19c/0x1d0 [c00000000b9bb950] c000000008aa11bc device_driver_attach+0xcc/0x100 [c00000000b9bb990] c000000008aa12ec __driver_attach+0xfc/0x1e0 [c00000000b9bba10] c000000008a9d0a4 bus_for_each_dev+0xb4/0x130 [c00000000b9bba70] c000000008a9fc04 driver_attach+0x34/0x50 [c00000000b9bba90] c000000008a9f118 bus_add_driver+0x1d8/0x300 [c00000000b9bbb20] c000000008aa2358 driver_register+0x98/0x1a0 [c00000000b9bbb90] c000000008ad7e6c __nd_driver_register+0x5c/0x100 [c00000000b9bbbf0] c0000000093efbac nd_pmem_driver_init+0x34/0x48 [c00000000b9bbc10] c0000000080106c0 do_one_initcall+0x60/0x2d0 [c00000000b9bbce0] c00000000938463c kernel_init_freeable+0x384/0x48c [c00000000b9bbdb0] c000000008010a5c kernel_init+0x2c/0x160 [c00000000b9bbe20] c00000000800ba54 ret_from_kernel_thread+0x5c/0x68 Reported-and-debugged-by: Vaibhav Jain Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/numa.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index b1ecfb850b5a..a62bc9861e4e 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -232,7 +232,7 @@ static int associativity_to_nid(const __be32 *associativity) { int nid = NUMA_NO_NODE; - if (min_common_depth == -1) + if (min_common_depth == -1 || !numa_enabled) goto out; if (of_read_number(associativity, 1) >= min_common_depth) @@ -440,7 +440,7 @@ static int of_drconf_to_nid_single(struct drmem_lmb *lmb) int nid = default_nid; int rc, index; - if (min_common_depth < 0) + if ((min_common_depth < 0) || !numa_enabled) return default_nid; rc = of_get_assoc_arrays(&aa); @@ -830,7 +830,7 @@ static void __init find_possible_nodes(void) struct device_node *rtas; u32 numnodes, i; - if (min_common_depth <= 0) + if (min_common_depth <= 0 || !numa_enabled) return; rtas = of_find_node_by_path("/rtas"); -- cgit v1.2.3 From 495c2ff4c88108d1f7730dd0966d4f8b03f0046e Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 1 Jul 2019 20:06:26 +0530 Subject: powerpc/mm: Consolidate numa_enable check and min_common_depth check If we fail to parse min_common_depth from device tree we boot with numa disabled. Reflect the same by updating numa_enabled variable to false. Also, switch all min_common_depth failure check to if (!numa_enabled) check. This helps us to avoid checking for both in different code paths. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/numa.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c index a62bc9861e4e..9ff2987c13cf 100644 --- a/arch/powerpc/mm/numa.c +++ b/arch/powerpc/mm/numa.c @@ -232,7 +232,7 @@ static int associativity_to_nid(const __be32 *associativity) { int nid = NUMA_NO_NODE; - if (min_common_depth == -1 || !numa_enabled) + if (!numa_enabled) goto out; if (of_read_number(associativity, 1) >= min_common_depth) @@ -648,8 +648,14 @@ static int __init parse_numa_properties(void) min_common_depth = find_min_common_depth(); - if (min_common_depth < 0) + if (min_common_depth < 0) { + /* + * if we fail to parse min_common_depth from device tree + * mark the numa disabled, boot with numa disabled. + */ + numa_enabled = false; return min_common_depth; + } dbg("NUMA associativity depth for CPU/Memory: %d\n", min_common_depth); @@ -765,7 +771,7 @@ void __init dump_numa_cpu_topology(void) unsigned int node; unsigned int cpu, count; - if (min_common_depth == -1 || !numa_enabled) + if (!numa_enabled) return; for_each_online_node(node) { @@ -830,7 +836,7 @@ static void __init find_possible_nodes(void) struct device_node *rtas; u32 numnodes, i; - if (min_common_depth <= 0 || !numa_enabled) + if (!numa_enabled) return; rtas = of_find_node_by_path("/rtas"); @@ -1032,7 +1038,7 @@ int hot_add_scn_to_nid(unsigned long scn_addr) struct device_node *memory = NULL; int nid; - if (!numa_enabled || (min_common_depth < 0)) + if (!numa_enabled) return first_online_node; memory = of_find_node_by_path("/ibm,dynamic-reconfiguration-memory"); -- cgit v1.2.3 From c0b1b23b9c87569d5f90d06e86f26b31b544fa1e Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Mon, 1 Jul 2019 20:03:38 +0530 Subject: powerpc/mm/nvdimm: Add an informative message if we fail to allocate altmap block Allocation from altmap area can fail based on vmemmap page size used. Add kernel info message to indicate the failure. That allows the user to identify whether they are really using persistent memory reserved space for per-page metadata. The message looks like: [ 136.587212] altmap block allocation failed, falling back to system memory Signed-off-by: Aneesh Kumar K.V Reviewed-by: Oliver O'Halloran Signed-off-by: Michael Ellerman --- arch/powerpc/mm/init_64.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c index 45b02fa11cd8..b219160a5b1a 100644 --- a/arch/powerpc/mm/init_64.c +++ b/arch/powerpc/mm/init_64.c @@ -199,8 +199,11 @@ int __meminit vmemmap_populate(unsigned long start, unsigned long end, int node, * fail due to alignment issues when using 16MB hugepages, so * fall back to system memory if the altmap allocation fail. */ - if (altmap) + if (altmap) { p = altmap_alloc_block_buf(page_size, altmap); + if (!p) + pr_debug("altmap block allocation failed, falling back to system memory"); + } if (!p) p = vmemmap_alloc_block_buf(page_size, node); if (!p) -- cgit v1.2.3 From 2a0ffbd4789b25cd5a80bfd8f3d28fb629eae1a7 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 7 Jun 2019 12:14:07 +0530 Subject: powerpc/pseries/scm: Mark the region volatile if cache flush not required MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The device tree node is documented as below: “ibm,cache-flush-required”: property name indicates Cache Flush Required for this Persistent Memory Segment to persist memory prop-encoded-array: None, this is a name only property. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/papr_scm.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 96c53b23e58f..0176ce66673f 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -28,6 +28,7 @@ struct papr_scm_priv { uint64_t blocks; uint64_t block_size; int metadata_size; + bool is_volatile; uint64_t bound_addr; @@ -248,7 +249,10 @@ static int papr_scm_nvdimm_init(struct papr_scm_priv *p) ndr_desc.nd_set = &p->nd_set; set_bit(ND_REGION_PAGEMAP, &ndr_desc.flags); - p->region = nvdimm_pmem_region_create(p->bus, &ndr_desc); + if (p->is_volatile) + p->region = nvdimm_volatile_region_create(p->bus, &ndr_desc); + else + p->region = nvdimm_pmem_region_create(p->bus, &ndr_desc); if (!p->region) { dev_err(dev, "Error registering region %pR from %pOF\n", ndr_desc.res, p->dn); @@ -293,6 +297,7 @@ static int papr_scm_probe(struct platform_device *pdev) return -ENODEV; } + p = kzalloc(sizeof(*p), GFP_KERNEL); if (!p) return -ENOMEM; @@ -304,6 +309,7 @@ static int papr_scm_probe(struct platform_device *pdev) p->drc_index = drc_index; p->block_size = block_size; p->blocks = blocks; + p->is_volatile = !of_property_read_bool(dn, "ibm,cache-flush-required"); /* We just need to ensure that set cookies are unique across */ uuid_parse(uuid_str, (uuid_t *) uuid); -- cgit v1.2.3 From 53e80bd042773c8ddeed856bd1b68ca74c3b8b46 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 7 Jun 2019 12:15:11 +0530 Subject: powerpc/nvdimm: Add support for multibyte read/write for metadata SCM_READ/WRITE_MEATADATA hcall supports multibyte read/write. This patch updates the metadata read/write to use 1, 2, 4 or 8 byte read/write as mentioned in PAPR document. READ/WRITE_METADATA hcall supports the 1, 2, 4, or 8 bytes read/write. For other values hcall results H_P3. Hypervisor stores the metadata contents in big-endian format and in-order to enable read/write in different granularity, we need to switch the contents to big-endian before calling HCALL. Based on an patch from Oliver O'Halloran Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/papr_scm.c | 104 +++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 22 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 0176ce66673f..80fbab118ef1 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -97,42 +97,102 @@ static int drc_pmem_unbind(struct papr_scm_priv *p) } static int papr_scm_meta_get(struct papr_scm_priv *p, - struct nd_cmd_get_config_data_hdr *hdr) + struct nd_cmd_get_config_data_hdr *hdr) { unsigned long data[PLPAR_HCALL_BUFSIZE]; + unsigned long offset, data_offset; + int len, read; int64_t ret; - if (hdr->in_offset >= p->metadata_size || hdr->in_length != 1) + if ((hdr->in_offset + hdr->in_length) >= p->metadata_size) return -EINVAL; - ret = plpar_hcall(H_SCM_READ_METADATA, data, p->drc_index, - hdr->in_offset, 1); - - if (ret == H_PARAMETER) /* bad DRC index */ - return -ENODEV; - if (ret) - return -EINVAL; /* other invalid parameter */ - - hdr->out_buf[0] = data[0] & 0xff; - + for (len = hdr->in_length; len; len -= read) { + + data_offset = hdr->in_length - len; + offset = hdr->in_offset + data_offset; + + if (len >= 8) + read = 8; + else if (len >= 4) + read = 4; + else if (len >= 2) + read = 2; + else + read = 1; + + ret = plpar_hcall(H_SCM_READ_METADATA, data, p->drc_index, + offset, read); + + if (ret == H_PARAMETER) /* bad DRC index */ + return -ENODEV; + if (ret) + return -EINVAL; /* other invalid parameter */ + + switch (read) { + case 8: + *(uint64_t *)(hdr->out_buf + data_offset) = be64_to_cpu(data[0]); + break; + case 4: + *(uint32_t *)(hdr->out_buf + data_offset) = be32_to_cpu(data[0] & 0xffffffff); + break; + + case 2: + *(uint16_t *)(hdr->out_buf + data_offset) = be16_to_cpu(data[0] & 0xffff); + break; + + case 1: + *(uint8_t *)(hdr->out_buf + data_offset) = (data[0] & 0xff); + break; + } + } return 0; } static int papr_scm_meta_set(struct papr_scm_priv *p, - struct nd_cmd_set_config_hdr *hdr) + struct nd_cmd_set_config_hdr *hdr) { + unsigned long offset, data_offset; + int len, wrote; + unsigned long data; + __be64 data_be; int64_t ret; - if (hdr->in_offset >= p->metadata_size || hdr->in_length != 1) + if ((hdr->in_offset + hdr->in_length) >= p->metadata_size) return -EINVAL; - ret = plpar_hcall_norets(H_SCM_WRITE_METADATA, - p->drc_index, hdr->in_offset, hdr->in_buf[0], 1); - - if (ret == H_PARAMETER) /* bad DRC index */ - return -ENODEV; - if (ret) - return -EINVAL; /* other invalid parameter */ + for (len = hdr->in_length; len; len -= wrote) { + + data_offset = hdr->in_length - len; + offset = hdr->in_offset + data_offset; + + if (len >= 8) { + data = *(uint64_t *)(hdr->in_buf + data_offset); + data_be = cpu_to_be64(data); + wrote = 8; + } else if (len >= 4) { + data = *(uint32_t *)(hdr->in_buf + data_offset); + data &= 0xffffffff; + data_be = cpu_to_be32(data); + wrote = 4; + } else if (len >= 2) { + data = *(uint16_t *)(hdr->in_buf + data_offset); + data &= 0xffff; + data_be = cpu_to_be16(data); + wrote = 2; + } else { + data_be = *(uint8_t *)(hdr->in_buf + data_offset); + data_be &= 0xff; + wrote = 1; + } + + ret = plpar_hcall_norets(H_SCM_WRITE_METADATA, p->drc_index, + offset, data_be, wrote); + if (ret == H_PARAMETER) /* bad DRC index */ + return -ENODEV; + if (ret) + return -EINVAL; /* other invalid parameter */ + } return 0; } @@ -154,7 +214,7 @@ int papr_scm_ndctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm, get_size_hdr = buf; get_size_hdr->status = 0; - get_size_hdr->max_xfer = 1; + get_size_hdr->max_xfer = 8; get_size_hdr->config_size = p->metadata_size; *cmd_rc = 0; break; -- cgit v1.2.3 From 259a948c4ba1829ae4a3c31bb6e40ad458a21254 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Fri, 7 Jun 2019 12:17:05 +0530 Subject: powerpc/pseries/scm: Use a specific endian format for storing uuid from the device tree We used uuid_parse to convert uuid string from device tree to two u64 components. We want to make sure we look at the uuid read from device tree in an endian-neutral fashion. For now, I am picking little-endian to be format so that we don't end up doing an additional conversion. The reason to store in a specific endian format is to enable reading the namespace created with a little-endian kernel config on a big-endian kernel. We do store the device tree uuid string as a 64-bit little-endian cookie in the label area. When booting the kernel we also compare this cookie against what is read from the device tree. For this, to work we have to store and compare these values in a CPU endian config independent fashion. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/pseries/papr_scm.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/pseries/papr_scm.c b/arch/powerpc/platforms/pseries/papr_scm.c index 80fbab118ef1..c8ec670ee924 100644 --- a/arch/powerpc/platforms/pseries/papr_scm.c +++ b/arch/powerpc/platforms/pseries/papr_scm.c @@ -373,8 +373,15 @@ static int papr_scm_probe(struct platform_device *pdev) /* We just need to ensure that set cookies are unique across */ uuid_parse(uuid_str, (uuid_t *) uuid); - p->nd_set.cookie1 = uuid[0]; - p->nd_set.cookie2 = uuid[1]; + /* + * cookie1 and cookie2 are not really little endian + * we store a little endian representation of the + * uuid str so that we can compare this with the label + * area cookie irrespective of the endian config with which + * the kernel is built. + */ + p->nd_set.cookie1 = cpu_to_le64(uuid[0]); + p->nd_set.cookie2 = cpu_to_le64(uuid[1]); /* might be zero */ p->metadata_size = metadata_size; -- cgit v1.2.3 From d6eacedd1f0ebf00bdf1c77715d194f7c1036fd4 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 14 May 2019 11:33:00 +0530 Subject: powerpc/book3s: Use config independent helpers for page table walk Even when we have HugeTLB and THP disabled, kernel linear map can still be mapped with hugepages. This is only an issue with radix translation because hash MMU doesn't map kernel linear range in linux page table and other kernel map areas are not mapped using hugepage. Add config independent helpers and put WARN_ON() when we don't expect things to be mapped via hugepages. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/book3s/64/pgtable.h | 21 +++++++++++++++++++++ arch/powerpc/include/asm/pgtable.h | 24 ++++++++++++++++++++++++ arch/powerpc/include/asm/pte-walk.h | 28 ++++++++++++++++++++++++++-- arch/powerpc/kvm/book3s_64_mmu_radix.c | 12 +++--------- arch/powerpc/mm/book3s64/radix_pgtable.c | 10 +++++----- arch/powerpc/mm/pgtable.c | 16 ++++++++-------- arch/powerpc/mm/pgtable_64.c | 12 +++++++++--- arch/powerpc/mm/ptdump/ptdump.c | 6 +++--- arch/powerpc/xmon/xmon.c | 6 +++--- 9 files changed, 102 insertions(+), 33 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index beabb099c040..62e6ea0a7650 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -1350,5 +1350,26 @@ static inline bool is_pte_rw_upgrade(unsigned long old_val, unsigned long new_va return false; } +/* + * Like pmd_huge() and pmd_large(), but works regardless of config options + */ +#define pmd_is_leaf pmd_is_leaf +static inline bool pmd_is_leaf(pmd_t pmd) +{ + return !!(pmd_raw(pmd) & cpu_to_be64(_PAGE_PTE)); +} + +#define pud_is_leaf pud_is_leaf +static inline bool pud_is_leaf(pud_t pud) +{ + return !!(pud_raw(pud) & cpu_to_be64(_PAGE_PTE)); +} + +#define pgd_is_leaf pgd_is_leaf +static inline bool pgd_is_leaf(pgd_t pgd) +{ + return !!(pgd_raw(pgd) & cpu_to_be64(_PAGE_PTE)); +} + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_BOOK3S_64_PGTABLE_H_ */ diff --git a/arch/powerpc/include/asm/pgtable.h b/arch/powerpc/include/asm/pgtable.h index 3f53be60fb01..bf7d771f342e 100644 --- a/arch/powerpc/include/asm/pgtable.h +++ b/arch/powerpc/include/asm/pgtable.h @@ -140,6 +140,30 @@ static inline void pte_frag_set(mm_context_t *ctx, void *p) } #endif +#ifndef pmd_is_leaf +#define pmd_is_leaf pmd_is_leaf +static inline bool pmd_is_leaf(pmd_t pmd) +{ + return false; +} +#endif + +#ifndef pud_is_leaf +#define pud_is_leaf pud_is_leaf +static inline bool pud_is_leaf(pud_t pud) +{ + return false; +} +#endif + +#ifndef pgd_is_leaf +#define pgd_is_leaf pgd_is_leaf +static inline bool pgd_is_leaf(pgd_t pgd) +{ + return false; +} +#endif + #endif /* __ASSEMBLY__ */ #endif /* _ASM_POWERPC_PGTABLE_H */ diff --git a/arch/powerpc/include/asm/pte-walk.h b/arch/powerpc/include/asm/pte-walk.h index 2d633e9d686c..33fa5dd8ee6a 100644 --- a/arch/powerpc/include/asm/pte-walk.h +++ b/arch/powerpc/include/asm/pte-walk.h @@ -10,8 +10,20 @@ extern pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea, static inline pte_t *find_linux_pte(pgd_t *pgdir, unsigned long ea, bool *is_thp, unsigned *hshift) { + pte_t *pte; + VM_WARN(!arch_irqs_disabled(), "%s called with irq enabled\n", __func__); - return __find_linux_pte(pgdir, ea, is_thp, hshift); + pte = __find_linux_pte(pgdir, ea, is_thp, hshift); + +#if defined(CONFIG_DEBUG_VM) && \ + !(defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)) + /* + * We should not find huge page if these configs are not enabled. + */ + if (hshift) + WARN_ON(*hshift); +#endif + return pte; } static inline pte_t *find_init_mm_pte(unsigned long ea, unsigned *hshift) @@ -26,10 +38,22 @@ static inline pte_t *find_init_mm_pte(unsigned long ea, unsigned *hshift) static inline pte_t *find_current_mm_pte(pgd_t *pgdir, unsigned long ea, bool *is_thp, unsigned *hshift) { + pte_t *pte; + VM_WARN(!arch_irqs_disabled(), "%s called with irq enabled\n", __func__); VM_WARN(pgdir != current->mm->pgd, "%s lock less page table lookup called on wrong mm\n", __func__); - return __find_linux_pte(pgdir, ea, is_thp, hshift); + pte = __find_linux_pte(pgdir, ea, is_thp, hshift); + +#if defined(CONFIG_DEBUG_VM) && \ + !(defined(CONFIG_HUGETLB_PAGE) || defined(CONFIG_TRANSPARENT_HUGEPAGE)) + /* + * We should not find huge page if these configs are not enabled. + */ + if (hshift) + WARN_ON(*hshift); +#endif + return pte; } #endif /* _ASM_POWERPC_PTE_WALK_H */ diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index f55ef071883f..91efee7f0329 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -363,12 +363,6 @@ static void kvmppc_pte_free(pte_t *ptep) kmem_cache_free(kvm_pte_cache, ptep); } -/* Like pmd_huge() and pmd_large(), but works regardless of config options */ -static inline int pmd_is_leaf(pmd_t pmd) -{ - return !!(pmd_val(pmd) & _PAGE_PTE); -} - static pmd_t *kvmppc_pmd_alloc(void) { return kmem_cache_alloc(kvm_pmd_cache, GFP_KERNEL); @@ -489,7 +483,7 @@ static void kvmppc_unmap_free_pud(struct kvm *kvm, pud_t *pud, for (iu = 0; iu < PTRS_PER_PUD; ++iu, ++p) { if (!pud_present(*p)) continue; - if (pud_huge(*p)) { + if (pud_is_leaf(*p)) { pud_clear(p); } else { pmd_t *pmd; @@ -588,7 +582,7 @@ int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte, new_pud = pud_alloc_one(kvm->mm, gpa); pmd = NULL; - if (pud && pud_present(*pud) && !pud_huge(*pud)) + if (pud && pud_present(*pud) && !pud_is_leaf(*pud)) pmd = pmd_offset(pud, gpa); else if (level <= 1) new_pmd = kvmppc_pmd_alloc(); @@ -611,7 +605,7 @@ int kvmppc_create_pte(struct kvm *kvm, pgd_t *pgtable, pte_t pte, new_pud = NULL; } pud = pud_offset(pgd, gpa); - if (pud_huge(*pud)) { + if (pud_is_leaf(*pud)) { unsigned long hgpa = gpa & PUD_MASK; /* Check if we raced and someone else has set the same thing */ diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index b573fa024b32..e92c6472a20c 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -203,14 +203,14 @@ void radix__change_memory_range(unsigned long start, unsigned long end, pudp = pud_alloc(&init_mm, pgdp, idx); if (!pudp) continue; - if (pud_huge(*pudp)) { + if (pud_is_leaf(*pudp)) { ptep = (pte_t *)pudp; goto update_the_pte; } pmdp = pmd_alloc(&init_mm, pudp, idx); if (!pmdp) continue; - if (pmd_huge(*pmdp)) { + if (pmd_is_leaf(*pmdp)) { ptep = pmdp_ptep(pmdp); goto update_the_pte; } @@ -835,7 +835,7 @@ static void remove_pmd_table(pmd_t *pmd_start, unsigned long addr, if (!pmd_present(*pmd)) continue; - if (pmd_huge(*pmd)) { + if (pmd_is_leaf(*pmd)) { split_kernel_mapping(addr, end, PMD_SIZE, (pte_t *)pmd); continue; } @@ -860,7 +860,7 @@ static void remove_pud_table(pud_t *pud_start, unsigned long addr, if (!pud_present(*pud)) continue; - if (pud_huge(*pud)) { + if (pud_is_leaf(*pud)) { split_kernel_mapping(addr, end, PUD_SIZE, (pte_t *)pud); continue; } @@ -886,7 +886,7 @@ static void __meminit remove_pagetable(unsigned long start, unsigned long end) if (!pgd_present(*pgd)) continue; - if (pgd_huge(*pgd)) { + if (pgd_is_leaf(*pgd)) { split_kernel_mapping(addr, end, PGDIR_SIZE, (pte_t *)pgd); continue; } diff --git a/arch/powerpc/mm/pgtable.c b/arch/powerpc/mm/pgtable.c index 533fc6fa6726..2029e585e5c3 100644 --- a/arch/powerpc/mm/pgtable.c +++ b/arch/powerpc/mm/pgtable.c @@ -340,10 +340,11 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea, if (pgd_none(pgd)) return NULL; - if (pgd_huge(pgd)) { + if (pgd_is_leaf(pgd)) { ret_pte = (pte_t *)pgdp; goto out; } + if (is_hugepd(__hugepd(pgd_val(pgd)))) { hpdp = (hugepd_t *)&pgd; goto out_huge; @@ -361,14 +362,16 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea, if (pud_none(pud)) return NULL; - if (pud_huge(pud)) { + if (pud_is_leaf(pud)) { ret_pte = (pte_t *)pudp; goto out; } + if (is_hugepd(__hugepd(pud_val(pud)))) { hpdp = (hugepd_t *)&pud; goto out_huge; } + pdshift = PMD_SHIFT; pmdp = pmd_offset(&pud, ea); pmd = READ_ONCE(*pmdp); @@ -397,15 +400,12 @@ pte_t *__find_linux_pte(pgd_t *pgdir, unsigned long ea, ret_pte = (pte_t *)pmdp; goto out; } - /* - * pmd_large check below will handle the swap pmd pte - * we need to do both the check because they are config - * dependent. - */ - if (pmd_huge(pmd) || pmd_large(pmd)) { + + if (pmd_is_leaf(pmd)) { ret_pte = (pte_t *)pmdp; goto out; } + if (is_hugepd(__hugepd(pmd_val(pmd)))) { hpdp = (hugepd_t *)&pmd; goto out_huge; diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 63cd81130643..2892246a6fef 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -309,16 +309,20 @@ EXPORT_SYMBOL(__iounmap_at); /* 4 level page table */ struct page *pgd_page(pgd_t pgd) { - if (pgd_huge(pgd)) + if (pgd_is_leaf(pgd)) { + VM_WARN_ON(!pgd_huge(pgd)); return pte_page(pgd_pte(pgd)); + } return virt_to_page(pgd_page_vaddr(pgd)); } #endif struct page *pud_page(pud_t pud) { - if (pud_huge(pud)) + if (pud_is_leaf(pud)) { + VM_WARN_ON(!pud_huge(pud)); return pte_page(pud_pte(pud)); + } return virt_to_page(pud_page_vaddr(pud)); } @@ -328,8 +332,10 @@ struct page *pud_page(pud_t pud) */ struct page *pmd_page(pmd_t pmd) { - if (pmd_large(pmd) || pmd_huge(pmd) || pmd_devmap(pmd)) + if (pmd_is_leaf(pmd)) { + VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd) || pmd_devmap(pmd))); return pte_page(pmd_pte(pmd)); + } return virt_to_page(pmd_page_vaddr(pmd)); } diff --git a/arch/powerpc/mm/ptdump/ptdump.c b/arch/powerpc/mm/ptdump/ptdump.c index 646876d9da64..abe60d25b4e6 100644 --- a/arch/powerpc/mm/ptdump/ptdump.c +++ b/arch/powerpc/mm/ptdump/ptdump.c @@ -277,7 +277,7 @@ static void walk_pmd(struct pg_state *st, pud_t *pud, unsigned long start) for (i = 0; i < PTRS_PER_PMD; i++, pmd++) { addr = start + i * PMD_SIZE; - if (!pmd_none(*pmd) && !pmd_huge(*pmd)) + if (!pmd_none(*pmd) && !pmd_is_leaf(*pmd)) /* pmd exists */ walk_pte(st, pmd, addr); else @@ -293,7 +293,7 @@ static void walk_pud(struct pg_state *st, pgd_t *pgd, unsigned long start) for (i = 0; i < PTRS_PER_PUD; i++, pud++) { addr = start + i * PUD_SIZE; - if (!pud_none(*pud) && !pud_huge(*pud)) + if (!pud_none(*pud) && !pud_is_leaf(*pud)) /* pud exists */ walk_pmd(st, pud, addr); else @@ -314,7 +314,7 @@ static void walk_pagetables(struct pg_state *st) * the hash pagetable. */ for (i = 0; i < PTRS_PER_PGD; i++, pgd++, addr += PGDIR_SIZE) { - if (!pgd_none(*pgd) && !pgd_huge(*pgd)) + if (!pgd_none(*pgd) && !pgd_is_leaf(*pgd)) /* pgd exists */ walk_pud(st, pgd, addr); else diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c index f879e9fe9733..2ec20a5bb556 100644 --- a/arch/powerpc/xmon/xmon.c +++ b/arch/powerpc/xmon/xmon.c @@ -3098,7 +3098,7 @@ static void show_pte(unsigned long addr) printf("pgd @ 0x%px\n", pgdir); - if (pgd_huge(*pgdp)) { + if (pgd_is_leaf(*pgdp)) { format_pte(pgdp, pgd_val(*pgdp)); return; } @@ -3111,7 +3111,7 @@ static void show_pte(unsigned long addr) return; } - if (pud_huge(*pudp)) { + if (pud_is_leaf(*pudp)) { format_pte(pudp, pud_val(*pudp)); return; } @@ -3125,7 +3125,7 @@ static void show_pte(unsigned long addr) return; } - if (pmd_huge(*pmdp)) { + if (pmd_is_leaf(*pmdp)) { format_pte(pmdp, pmd_val(*pmdp)); return; } -- cgit v1.2.3 From 1ecf2cdc74fc7f79b4b45dd34f89c4a8e6ada96f Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 14 May 2019 11:33:01 +0530 Subject: powerpc/mm: pmd_devmap implies pmd_large(). large devmap usage is dependent on THP. Hence once check is sufficient. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/book3s64/pgtable.c | 2 +- arch/powerpc/mm/pgtable_64.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/book3s64/pgtable.c b/arch/powerpc/mm/book3s64/pgtable.c index 953850a602f7..85bc81abd286 100644 --- a/arch/powerpc/mm/book3s64/pgtable.c +++ b/arch/powerpc/mm/book3s64/pgtable.c @@ -76,7 +76,7 @@ void set_pmd_at(struct mm_struct *mm, unsigned long addr, WARN_ON(pte_hw_valid(pmd_pte(*pmdp)) && !pte_protnone(pmd_pte(*pmdp))); assert_spin_locked(pmd_lockptr(mm, pmdp)); - WARN_ON(!(pmd_large(pmd) || pmd_devmap(pmd))); + WARN_ON(!(pmd_large(pmd))); #endif trace_hugepage_set_pmd(addr, pmd_val(pmd)); return set_pte_at(mm, addr, pmdp_ptep(pmdp), pmd_pte(pmd)); diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c index 2892246a6fef..262adf1849e3 100644 --- a/arch/powerpc/mm/pgtable_64.c +++ b/arch/powerpc/mm/pgtable_64.c @@ -333,7 +333,7 @@ struct page *pud_page(pud_t pud) struct page *pmd_page(pmd_t pmd) { if (pmd_is_leaf(pmd)) { - VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd) || pmd_devmap(pmd))); + VM_WARN_ON(!(pmd_large(pmd) || pmd_huge(pmd))); return pte_page(pmd_pte(pmd)); } return virt_to_page(pmd_page_vaddr(pmd)); -- cgit v1.2.3 From 57caddae6ef43531a9f09a7f123c670db0789dad Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 14 May 2019 11:33:02 +0530 Subject: powerpc/mm: Remove radix dependency on HugeTLB page Now that we have switched the page table walk to use pmd_is_leaf we can now revert commit 8adddf349fda ("powerpc/mm/radix: Make Radix require HUGETLB_PAGE") Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/Kconfig.cputype | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/Kconfig.cputype b/arch/powerpc/platforms/Kconfig.cputype index 2794235e9d3e..56a7c814160d 100644 --- a/arch/powerpc/platforms/Kconfig.cputype +++ b/arch/powerpc/platforms/Kconfig.cputype @@ -330,7 +330,7 @@ config ARCH_ENABLE_SPLIT_PMD_PTLOCK config PPC_RADIX_MMU bool "Radix MMU Support" - depends on PPC_BOOK3S_64 && HUGETLB_PAGE + depends on PPC_BOOK3S_64 select ARCH_HAS_GIGANTIC_PAGE select PPC_HAVE_KUEP select PPC_HAVE_KUAP -- cgit v1.2.3 From 2230ebf6e6dd0b7751e2921b40f6cfe34f09bb16 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 28 May 2019 11:06:24 +0530 Subject: powerpc/mm: Handle page table allocation failures This fixes kernel crash that arises due to not handling page table allocation failures while allocating hugetlb page table. Fixes: e2b3d202d1db ("powerpc: Switch 16GB and 16MB explicit hugepages to a different page table format") Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/hugetlbpage.c | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index b5d92dc32844..1de0f43a68e5 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -130,6 +130,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz } else { pdshift = PUD_SHIFT; pu = pud_alloc(mm, pg, addr); + if (!pu) + return NULL; if (pshift == PUD_SHIFT) return (pte_t *)pu; else if (pshift > PMD_SHIFT) { @@ -138,6 +140,8 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz } else { pdshift = PMD_SHIFT; pm = pmd_alloc(mm, pu, addr); + if (!pm) + return NULL; if (pshift == PMD_SHIFT) /* 16MB hugepage */ return (pte_t *)pm; @@ -154,12 +158,16 @@ pte_t *huge_pte_alloc(struct mm_struct *mm, unsigned long addr, unsigned long sz } else { pdshift = PUD_SHIFT; pu = pud_alloc(mm, pg, addr); + if (!pu) + return NULL; if (pshift >= PUD_SHIFT) { ptl = pud_lockptr(mm, pu); hpdp = (hugepd_t *)pu; } else { pdshift = PMD_SHIFT; pm = pmd_alloc(mm, pu, addr); + if (!pm) + return NULL; ptl = pmd_lockptr(mm, pm); hpdp = (hugepd_t *)pm; } -- cgit v1.2.3 From 5d49275a27310233964fc3edc8dd097a094ce338 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 28 May 2019 11:06:25 +0530 Subject: powerpc/mm/hugetlb: Fix kernel crash if we fail to allocate page table caches We only check for hugetlb allocations, because with hugetlb we do conditional registration. For PGD/PUD/PMD levels we register them always in pgtable_cache_init. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/hugetlbpage.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index 1de0f43a68e5..f55dc110f2ad 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -61,12 +61,17 @@ static int __hugepte_alloc(struct mm_struct *mm, hugepd_t *hpdp, num_hugepd = 1; } + if (!cachep) { + WARN_ONCE(1, "No page table cache created for hugetlb tables"); + return -ENOMEM; + } + new = kmem_cache_alloc(cachep, pgtable_gfp_flags(mm, GFP_KERNEL)); BUG_ON(pshift > HUGEPD_SHIFT_MASK); BUG_ON((unsigned long)new & HUGEPD_SHIFT_MASK); - if (! new) + if (!new) return -ENOMEM; /* -- cgit v1.2.3 From ac25ba68fa4001c85395f0488b1c7a2421c5aada Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 28 May 2019 11:06:26 +0530 Subject: powerpc/mm/hugetlb: Don't enable HugeTLB if we don't have a page table cache This makes sure we don't enable HugeTLB if the cache is not configured. I am still not sure about this. IMHO hugetlb support should be a hardware support derivative and any cache allocation failure should be handled as I did in the earlier patch. But then if we were not able to create hugetlb page table cache, we can as well declare hugetlb support disabled thereby avoiding calling into allocation routines. Signed-off-by: Aneesh Kumar K.V Signed-off-by: Michael Ellerman --- arch/powerpc/mm/hugetlbpage.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.c index f55dc110f2ad..d34540479b1a 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -601,6 +601,7 @@ __setup("hugepagesz=", hugepage_setup_sz); static int __init hugetlbpage_init(void) { + bool configured = false; int psize; if (hugetlb_disabled) { @@ -651,10 +652,15 @@ static int __init hugetlbpage_init(void) pgtable_cache_add(pdshift - shift); else if (IS_ENABLED(CONFIG_PPC_FSL_BOOK3E) || IS_ENABLED(CONFIG_PPC_8xx)) pgtable_cache_add(PTE_T_ORDER); + + configured = true; } - if (IS_ENABLED(CONFIG_HUGETLB_PAGE_SIZE_VARIABLE)) - hugetlbpage_init_default(); + if (configured) { + if (IS_ENABLED(CONFIG_HUGETLB_PAGE_SIZE_VARIABLE)) + hugetlbpage_init_default(); + } else + pr_info("Failed to initialize. Disabling HugeTLB"); return 0; } -- cgit v1.2.3 From 6c5875843b87c3adea2beade9d1b8b3d4523900a Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 10 May 2019 09:24:48 +0000 Subject: powerpc: slightly improve cache helpers Cache instructions (dcbz, dcbi, dcbf and dcbst) take two registers that are summed to obtain the target address. Using 'Z' constraint and '%y0' argument gives GCC the opportunity to use both registers instead of only one with the second being forced to 0. Suggested-by: Segher Boessenkool Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/cache.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index 40ea5b3781c6..df8e4c407366 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -85,22 +85,22 @@ extern void _set_L3CR(unsigned long); static inline void dcbz(void *addr) { - __asm__ __volatile__ ("dcbz 0, %0" : : "r"(addr) : "memory"); + __asm__ __volatile__ ("dcbz %y0" : : "Z"(*(u8 *)addr) : "memory"); } static inline void dcbi(void *addr) { - __asm__ __volatile__ ("dcbi 0, %0" : : "r"(addr) : "memory"); + __asm__ __volatile__ ("dcbi %y0" : : "Z"(*(u8 *)addr) : "memory"); } static inline void dcbf(void *addr) { - __asm__ __volatile__ ("dcbf 0, %0" : : "r"(addr) : "memory"); + __asm__ __volatile__ ("dcbf %y0" : : "Z"(*(u8 *)addr) : "memory"); } static inline void dcbst(void *addr) { - __asm__ __volatile__ ("dcbst 0, %0" : : "r"(addr) : "memory"); + __asm__ __volatile__ ("dcbst %y0" : : "Z"(*(u8 *)addr) : "memory"); } #endif /* !__ASSEMBLY__ */ #endif /* __KERNEL__ */ -- cgit v1.2.3 From 1cfb725fb1899dc6fdc88f8b5354a65e8ad260c6 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 14 May 2019 09:05:13 +0000 Subject: powerpc/64: flush_inval_dcache_range() becomes flush_dcache_range() On most arches having function flush_dcache_range(), including PPC32, this function does a writeback and invalidation of the cache bloc. On PPC64, flush_dcache_range() only does a writeback while flush_inval_dcache_range() does the invalidation in addition. In addition it looks like within arch/powerpc/, there are no PPC64 platforms using flush_dcache_range() This patch drops the existing 64 bits version of flush_dcache_range() and renames flush_inval_dcache_range() into flush_dcache_range(). Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/cacheflush.h | 1 - arch/powerpc/kernel/misc_64.S | 27 ++------------------------- arch/powerpc/lib/pmem.c | 8 ++++---- arch/powerpc/mm/mem.c | 4 ++-- arch/powerpc/sysdev/dart_iommu.c | 2 +- drivers/macintosh/smu.c | 4 ++-- 6 files changed, 11 insertions(+), 35 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index b189f7aee222..69b6c3d78d6c 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -112,7 +112,6 @@ static inline void invalidate_dcache_range(unsigned long start, #endif /* CONFIG_PPC32 */ #ifdef CONFIG_PPC64 extern void flush_dcache_range(unsigned long start, unsigned long stop); -extern void flush_inval_dcache_range(unsigned long start, unsigned long stop); #endif #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index 262ba9481781..a4fd536efb44 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -121,31 +121,8 @@ EXPORT_SYMBOL(flush_icache_range) * * flush all bytes from start to stop-1 inclusive */ -_GLOBAL_TOC(flush_dcache_range) -/* - * Flush the data cache to memory - * - * Different systems have different cache line sizes - */ - ld r10,PPC64_CACHES@toc(r2) - lwz r7,DCACHEL1BLOCKSIZE(r10) /* Get dcache block size */ - addi r5,r7,-1 - andc r6,r3,r5 /* round low to line bdy */ - subf r8,r6,r4 /* compute length */ - add r8,r8,r5 /* ensure we get enough */ - lwz r9,DCACHEL1LOGBLOCKSIZE(r10) /* Get log-2 of dcache block size */ - srw. r8,r8,r9 /* compute line count */ - beqlr /* nothing to do? */ - mtctr r8 -0: dcbst 0,r6 - add r6,r6,r7 - bdnz 0b - sync - blr -EXPORT_SYMBOL(flush_dcache_range) - -_GLOBAL(flush_inval_dcache_range) +_GLOBAL_TOC(flush_dcache_range) ld r10,PPC64_CACHES@toc(r2) lwz r7,DCACHEL1BLOCKSIZE(r10) /* Get dcache block size */ addi r5,r7,-1 @@ -164,7 +141,7 @@ _GLOBAL(flush_inval_dcache_range) sync isync blr - +EXPORT_SYMBOL(flush_dcache_range) /* * Flush a particular page from the data cache to RAM. diff --git a/arch/powerpc/lib/pmem.c b/arch/powerpc/lib/pmem.c index 53c018762e1c..36e08bf850e0 100644 --- a/arch/powerpc/lib/pmem.c +++ b/arch/powerpc/lib/pmem.c @@ -23,14 +23,14 @@ void arch_wb_cache_pmem(void *addr, size_t size) { unsigned long start = (unsigned long) addr; - flush_inval_dcache_range(start, start + size); + flush_dcache_range(start, start + size); } EXPORT_SYMBOL(arch_wb_cache_pmem); void arch_invalidate_pmem(void *addr, size_t size) { unsigned long start = (unsigned long) addr; - flush_inval_dcache_range(start, start + size); + flush_dcache_range(start, start + size); } EXPORT_SYMBOL(arch_invalidate_pmem); @@ -43,7 +43,7 @@ long __copy_from_user_flushcache(void *dest, const void __user *src, unsigned long copied, start = (unsigned long) dest; copied = __copy_from_user(dest, src, size); - flush_inval_dcache_range(start, start + size); + flush_dcache_range(start, start + size); return copied; } @@ -53,7 +53,7 @@ void *memcpy_flushcache(void *dest, const void *src, size_t size) unsigned long start = (unsigned long) dest; memcpy(dest, src, size); - flush_inval_dcache_range(start, start + size); + flush_dcache_range(start, start + size); return dest; } diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 40bd4153ab09..096c87836e29 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -125,7 +125,7 @@ int __ref arch_add_memory(int nid, u64 start, u64 size, start, start + size, rc); return -EFAULT; } - flush_inval_dcache_range(start, start + size); + flush_dcache_range(start, start + size); return __add_pages(nid, start_pfn, nr_pages, restrictions); } @@ -151,7 +151,7 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size, /* Remove htab bolted mappings for this section of memory */ start = (unsigned long)__va(start); - flush_inval_dcache_range(start, start + size); + flush_dcache_range(start, start + size); ret = remove_section_mapping(start, start + size); WARN_ON_ONCE(ret); diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 2a751795ec1e..bc259a8d3f2d 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -158,7 +158,7 @@ static void dart_cache_sync(unsigned int *base, unsigned int count) unsigned int tmp; /* Perform a standard cache flush */ - flush_inval_dcache_range(start, end); + flush_dcache_range(start, end); /* * Perform the sequence described in the CPC925 manual to diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c index 6a844125cf2d..97758eed03f2 100644 --- a/drivers/macintosh/smu.c +++ b/drivers/macintosh/smu.c @@ -133,7 +133,7 @@ static void smu_start_cmd(void) /* Flush command and data to RAM */ faddr = (unsigned long)smu->cmd_buf; fend = faddr + smu->cmd_buf->length + 2; - flush_inval_dcache_range(faddr, fend); + flush_dcache_range(faddr, fend); /* We also disable NAP mode for the duration of the command @@ -195,7 +195,7 @@ static irqreturn_t smu_db_intr(int irq, void *arg) * reply length (it's only 2 cache lines anyway) */ faddr = (unsigned long)smu->cmd_buf; - flush_inval_dcache_range(faddr, faddr + 256); + flush_dcache_range(faddr, faddr + 256); /* Now check ack */ ack = (~cmd->cmd) & 0xff; -- cgit v1.2.3 From d98fc70fc139b72ae098d24fde42ad70c8ff2f81 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 14 May 2019 09:05:15 +0000 Subject: powerpc/32: define helpers to get L1 cache sizes. This patch defines C helpers to retrieve the size of cache blocks and uses them in the cacheflush functions. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/cache.h | 16 ++++++++++++++-- arch/powerpc/include/asm/cacheflush.h | 24 +++++++++++++++--------- 2 files changed, 29 insertions(+), 11 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index df8e4c407366..e84d1622eeb6 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -33,7 +33,8 @@ #define IFETCH_ALIGN_BYTES (1 << IFETCH_ALIGN_SHIFT) -#if defined(__powerpc64__) && !defined(__ASSEMBLY__) +#if !defined(__ASSEMBLY__) +#ifdef CONFIG_PPC64 struct ppc_cache_info { u32 size; @@ -53,7 +54,18 @@ struct ppc64_caches { }; extern struct ppc64_caches ppc64_caches; -#endif /* __powerpc64__ && ! __ASSEMBLY__ */ +#else +static inline u32 l1_cache_shift(void) +{ + return L1_CACHE_SHIFT; +} + +static inline u32 l1_cache_bytes(void) +{ + return L1_CACHE_BYTES; +} +#endif +#endif /* ! __ASSEMBLY__ */ #if defined(__ASSEMBLY__) /* diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 69b6c3d78d6c..217f183aa8c4 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -67,11 +67,13 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr) */ static inline void flush_dcache_range(unsigned long start, unsigned long stop) { - void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1)); - unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1); + unsigned long shift = l1_cache_shift(); + unsigned long bytes = l1_cache_bytes(); + void *addr = (void *)(start & ~(bytes - 1)); + unsigned long size = stop - (unsigned long)addr + (bytes - 1); unsigned long i; - for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES) + for (i = 0; i < size >> shift; i++, addr += bytes) dcbf(addr); mb(); /* sync */ } @@ -83,11 +85,13 @@ static inline void flush_dcache_range(unsigned long start, unsigned long stop) */ static inline void clean_dcache_range(unsigned long start, unsigned long stop) { - void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1)); - unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1); + unsigned long shift = l1_cache_shift(); + unsigned long bytes = l1_cache_bytes(); + void *addr = (void *)(start & ~(bytes - 1)); + unsigned long size = stop - (unsigned long)addr + (bytes - 1); unsigned long i; - for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES) + for (i = 0; i < size >> shift; i++, addr += bytes) dcbst(addr); mb(); /* sync */ } @@ -100,11 +104,13 @@ static inline void clean_dcache_range(unsigned long start, unsigned long stop) static inline void invalidate_dcache_range(unsigned long start, unsigned long stop) { - void *addr = (void *)(start & ~(L1_CACHE_BYTES - 1)); - unsigned long size = stop - (unsigned long)addr + (L1_CACHE_BYTES - 1); + unsigned long shift = l1_cache_shift(); + unsigned long bytes = l1_cache_bytes(); + void *addr = (void *)(start & ~(bytes - 1)); + unsigned long size = stop - (unsigned long)addr + (bytes - 1); unsigned long i; - for (i = 0; i < size >> L1_CACHE_SHIFT; i++, addr += L1_CACHE_BYTES) + for (i = 0; i < size >> shift; i++, addr += bytes) dcbi(addr); mb(); /* sync */ } -- cgit v1.2.3 From 22e9c88d486a0536d337d6e0973968be0a4cd4b2 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Tue, 14 May 2019 09:05:16 +0000 Subject: powerpc/64: reuse PPC32 static inline flush_dcache_range() This patch drops the assembly PPC64 version of flush_dcache_range() and re-uses the PPC32 static inline version. With GCC 8.1, the following code is generated: void flush_test(unsigned long start, unsigned long stop) { flush_dcache_range(start, stop); } 0000000000000130 <.flush_test>: 130: 3d 22 00 00 addis r9,r2,0 132: R_PPC64_TOC16_HA .data+0x8 134: 81 09 00 00 lwz r8,0(r9) 136: R_PPC64_TOC16_LO .data+0x8 138: 3d 22 00 00 addis r9,r2,0 13a: R_PPC64_TOC16_HA .data+0xc 13c: 80 e9 00 00 lwz r7,0(r9) 13e: R_PPC64_TOC16_LO .data+0xc 140: 7d 48 00 d0 neg r10,r8 144: 7d 43 18 38 and r3,r10,r3 148: 7c 00 04 ac hwsync 14c: 4c 00 01 2c isync 150: 39 28 ff ff addi r9,r8,-1 154: 7c 89 22 14 add r4,r9,r4 158: 7c 83 20 50 subf r4,r3,r4 15c: 7c 89 3c 37 srd. r9,r4,r7 160: 41 82 00 1c beq 17c <.flush_test+0x4c> 164: 7d 29 03 a6 mtctr r9 168: 60 00 00 00 nop 16c: 60 00 00 00 nop 170: 7c 00 18 ac dcbf 0,r3 174: 7c 63 42 14 add r3,r3,r8 178: 42 00 ff f8 bdnz 170 <.flush_test+0x40> 17c: 7c 00 04 ac hwsync 180: 4c 00 01 2c isync 184: 4e 80 00 20 blr 188: 60 00 00 00 nop 18c: 60 00 00 00 nop Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/cache.h | 10 ++++++++++ arch/powerpc/include/asm/cacheflush.h | 14 ++++++++------ arch/powerpc/kernel/misc_64.S | 29 ----------------------------- 3 files changed, 18 insertions(+), 35 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/cache.h b/arch/powerpc/include/asm/cache.h index e84d1622eeb6..b3388d95f451 100644 --- a/arch/powerpc/include/asm/cache.h +++ b/arch/powerpc/include/asm/cache.h @@ -54,6 +54,16 @@ struct ppc64_caches { }; extern struct ppc64_caches ppc64_caches; + +static inline u32 l1_cache_shift(void) +{ + return ppc64_caches.l1d.log_block_size; +} + +static inline u32 l1_cache_bytes(void) +{ + return ppc64_caches.l1d.block_size; +} #else static inline u32 l1_cache_shift(void) { diff --git a/arch/powerpc/include/asm/cacheflush.h b/arch/powerpc/include/asm/cacheflush.h index 217f183aa8c4..5c5a4538fc47 100644 --- a/arch/powerpc/include/asm/cacheflush.h +++ b/arch/powerpc/include/asm/cacheflush.h @@ -60,7 +60,6 @@ static inline void __flush_dcache_icache_phys(unsigned long physaddr) } #endif -#ifdef CONFIG_PPC32 /* * Write any modified data cache blocks out to memory and invalidate them. * Does not invalidate the corresponding instruction cache blocks. @@ -73,9 +72,17 @@ static inline void flush_dcache_range(unsigned long start, unsigned long stop) unsigned long size = stop - (unsigned long)addr + (bytes - 1); unsigned long i; + if (IS_ENABLED(CONFIG_PPC64)) { + mb(); /* sync */ + isync(); + } + for (i = 0; i < size >> shift; i++, addr += bytes) dcbf(addr); mb(); /* sync */ + + if (IS_ENABLED(CONFIG_PPC64)) + isync(); } /* @@ -115,11 +122,6 @@ static inline void invalidate_dcache_range(unsigned long start, mb(); /* sync */ } -#endif /* CONFIG_PPC32 */ -#ifdef CONFIG_PPC64 -extern void flush_dcache_range(unsigned long start, unsigned long stop); -#endif - #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ do { \ memcpy(dst, src, len); \ diff --git a/arch/powerpc/kernel/misc_64.S b/arch/powerpc/kernel/misc_64.S index a4fd536efb44..1b0a42c50ef1 100644 --- a/arch/powerpc/kernel/misc_64.S +++ b/arch/powerpc/kernel/misc_64.S @@ -114,35 +114,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_COHERENT_ICACHE) _ASM_NOKPROBE_SYMBOL(flush_icache_range) EXPORT_SYMBOL(flush_icache_range) -/* - * Like above, but only do the D-cache. - * - * flush_dcache_range(unsigned long start, unsigned long stop) - * - * flush all bytes from start to stop-1 inclusive - */ - -_GLOBAL_TOC(flush_dcache_range) - ld r10,PPC64_CACHES@toc(r2) - lwz r7,DCACHEL1BLOCKSIZE(r10) /* Get dcache block size */ - addi r5,r7,-1 - andc r6,r3,r5 /* round low to line bdy */ - subf r8,r6,r4 /* compute length */ - add r8,r8,r5 /* ensure we get enough */ - lwz r9,DCACHEL1LOGBLOCKSIZE(r10)/* Get log-2 of dcache block size */ - srw. r8,r8,r9 /* compute line count */ - beqlr /* nothing to do? */ - sync - isync - mtctr r8 -0: dcbf 0,r6 - add r6,r6,r7 - bdnz 0b - sync - isync - blr -EXPORT_SYMBOL(flush_dcache_range) - /* * Flush a particular page from the data cache to RAM. * Note: this is necessary because the instruction cache does *not* -- cgit v1.2.3 From 4128a89ac80d3714babde5b2811ffd058b09c229 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:38 +0000 Subject: powerpc/8xx: move CPM1 related files from sysdev/ to platforms/8xx Only 8xx selects CPM1 and related CONFIG options are already in platforms/8xx/Kconfig Move the related C files to platforms/8xx/. Signed-off-by: Christophe Leroy [mpe: Minor formatting fixes] Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/Makefile | 2 + arch/powerpc/platforms/8xx/cpm1.c | 790 ++++++++++++++++++++++++++++++++ arch/powerpc/platforms/8xx/micropatch.c | 750 ++++++++++++++++++++++++++++++ arch/powerpc/sysdev/Makefile | 2 - arch/powerpc/sysdev/cpm1.c | 788 ------------------------------- arch/powerpc/sysdev/micropatch.c | 749 ------------------------------ 6 files changed, 1542 insertions(+), 1539 deletions(-) create mode 100644 arch/powerpc/platforms/8xx/cpm1.c create mode 100644 arch/powerpc/platforms/8xx/micropatch.c delete mode 100644 arch/powerpc/sysdev/cpm1.c delete mode 100644 arch/powerpc/sysdev/micropatch.c (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/Makefile b/arch/powerpc/platforms/8xx/Makefile index 708ab099e886..27a7c6f828e0 100644 --- a/arch/powerpc/platforms/8xx/Makefile +++ b/arch/powerpc/platforms/8xx/Makefile @@ -3,6 +3,8 @@ # Makefile for the PowerPC 8xx linux kernel. # obj-y += m8xx_setup.o machine_check.o pic.o +obj-$(CONFIG_CPM1) += cpm1.o +obj-$(CONFIG_UCODE_PATCH) += micropatch.o obj-$(CONFIG_MPC885ADS) += mpc885ads_setup.o obj-$(CONFIG_MPC86XADS) += mpc86xads_setup.o obj-$(CONFIG_PPC_EP88XC) += ep88xc.o diff --git a/arch/powerpc/platforms/8xx/cpm1.c b/arch/powerpc/platforms/8xx/cpm1.c new file mode 100644 index 000000000000..0f65c51271db --- /dev/null +++ b/arch/powerpc/platforms/8xx/cpm1.c @@ -0,0 +1,790 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * General Purpose functions for the global management of the + * Communication Processor Module. + * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) + * + * In addition to the individual control of the communication + * channels, there are a few functions that globally affect the + * communication processor. + * + * Buffer descriptors must be allocated from the dual ported memory + * space. The allocator for that is here. When the communication + * process is reset, we reclaim the memory available. There is + * currently no deallocator for this memory. + * The amount of space available is platform dependent. On the + * MBX, the EPPC software loads additional microcode into the + * communication processor, and uses some of the DP ram for this + * purpose. Current, the first 512 bytes and the last 256 bytes of + * memory are used. Right now I am conservative and only use the + * memory that can never be used for microcode. If there are + * applications that require more DP ram, we can expand the boundaries + * but then we have to be careful of any downloaded microcode. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#ifdef CONFIG_8xx_GPIO +#include +#endif + +#define CPM_MAP_SIZE (0x4000) + +cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */ +immap_t __iomem *mpc8xx_immr; +static cpic8xx_t __iomem *cpic_reg; + +static struct irq_domain *cpm_pic_host; + +static void cpm_mask_irq(struct irq_data *d) +{ + unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d); + + clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec)); +} + +static void cpm_unmask_irq(struct irq_data *d) +{ + unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d); + + setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec)); +} + +static void cpm_end_irq(struct irq_data *d) +{ + unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d); + + out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec)); +} + +static struct irq_chip cpm_pic = { + .name = "CPM PIC", + .irq_mask = cpm_mask_irq, + .irq_unmask = cpm_unmask_irq, + .irq_eoi = cpm_end_irq, +}; + +int cpm_get_irq(void) +{ + int cpm_vec; + + /* + * Get the vector by setting the ACK bit and then reading + * the register. + */ + out_be16(&cpic_reg->cpic_civr, 1); + cpm_vec = in_be16(&cpic_reg->cpic_civr); + cpm_vec >>= 11; + + return irq_linear_revmap(cpm_pic_host, cpm_vec); +} + +static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq, + irq_hw_number_t hw) +{ + pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw); + + irq_set_status_flags(virq, IRQ_LEVEL); + irq_set_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq); + return 0; +} + +/* + * The CPM can generate the error interrupt when there is a race condition + * between generating and masking interrupts. All we have to do is ACK it + * and return. This is a no-op function so we don't need any special + * tests in the interrupt handler. + */ +static irqreturn_t cpm_error_interrupt(int irq, void *dev) +{ + return IRQ_HANDLED; +} + +static struct irqaction cpm_error_irqaction = { + .handler = cpm_error_interrupt, + .flags = IRQF_NO_THREAD, + .name = "error", +}; + +static const struct irq_domain_ops cpm_pic_host_ops = { + .map = cpm_pic_host_map, +}; + +unsigned int cpm_pic_init(void) +{ + struct device_node *np = NULL; + struct resource res; + unsigned int sirq = 0, hwirq, eirq; + int ret; + + pr_debug("cpm_pic_init\n"); + + np = of_find_compatible_node(NULL, NULL, "fsl,cpm1-pic"); + if (np == NULL) + np = of_find_compatible_node(NULL, "cpm-pic", "CPM"); + if (np == NULL) { + printk(KERN_ERR "CPM PIC init: can not find cpm-pic node\n"); + return sirq; + } + + ret = of_address_to_resource(np, 0, &res); + if (ret) + goto end; + + cpic_reg = ioremap(res.start, resource_size(&res)); + if (cpic_reg == NULL) + goto end; + + sirq = irq_of_parse_and_map(np, 0); + if (!sirq) + goto end; + + /* Initialize the CPM interrupt controller. */ + hwirq = (unsigned int)virq_to_hw(sirq); + out_be32(&cpic_reg->cpic_cicr, + (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) | + ((hwirq/2) << 13) | CICR_HP_MASK); + + out_be32(&cpic_reg->cpic_cimr, 0); + + cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL); + if (cpm_pic_host == NULL) { + printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); + sirq = 0; + goto end; + } + + /* Install our own error handler. */ + np = of_find_compatible_node(NULL, NULL, "fsl,cpm1"); + if (np == NULL) + np = of_find_node_by_type(NULL, "cpm"); + if (np == NULL) { + printk(KERN_ERR "CPM PIC init: can not find cpm node\n"); + goto end; + } + + eirq = irq_of_parse_and_map(np, 0); + if (!eirq) + goto end; + + if (setup_irq(eirq, &cpm_error_irqaction)) + printk(KERN_ERR "Could not allocate CPM error IRQ!"); + + setbits32(&cpic_reg->cpic_cicr, CICR_IEN); + +end: + of_node_put(np); + return sirq; +} + +void __init cpm_reset(void) +{ + sysconf8xx_t __iomem *siu_conf; + + mpc8xx_immr = ioremap(get_immrbase(), 0x4000); + if (!mpc8xx_immr) { + printk(KERN_CRIT "Could not map IMMR\n"); + return; + } + + cpmp = &mpc8xx_immr->im_cpm; + +#ifndef CONFIG_PPC_EARLY_DEBUG_CPM + /* Perform a reset. */ + out_be16(&cpmp->cp_cpcr, CPM_CR_RST | CPM_CR_FLG); + + /* Wait for it. */ + while (in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG); +#endif + +#ifdef CONFIG_UCODE_PATCH + cpm_load_patch(cpmp); +#endif + + /* + * Set SDMA Bus Request priority 5. + * On 860T, this also enables FEC priority 6. I am not sure + * this is what we really want for some applications, but the + * manual recommends it. + * Bit 25, FAM can also be set to use FEC aggressive mode (860T). + */ + siu_conf = immr_map(im_siu_conf); + if ((mfspr(SPRN_IMMR) & 0xffff) == 0x0900) /* MPC885 */ + out_be32(&siu_conf->sc_sdcr, 0x40); + else + out_be32(&siu_conf->sc_sdcr, 1); + immr_unmap(siu_conf); +} + +static DEFINE_SPINLOCK(cmd_lock); + +#define MAX_CR_CMD_LOOPS 10000 + +int cpm_command(u32 command, u8 opcode) +{ + int i, ret; + unsigned long flags; + + if (command & 0xffffff0f) + return -EINVAL; + + spin_lock_irqsave(&cmd_lock, flags); + + ret = 0; + out_be16(&cpmp->cp_cpcr, command | CPM_CR_FLG | (opcode << 8)); + for (i = 0; i < MAX_CR_CMD_LOOPS; i++) + if ((in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0) + goto out; + + printk(KERN_ERR "%s(): Not able to issue CPM command\n", __func__); + ret = -EIO; +out: + spin_unlock_irqrestore(&cmd_lock, flags); + return ret; +} +EXPORT_SYMBOL(cpm_command); + +/* + * Set a baud rate generator. This needs lots of work. There are + * four BRGs, any of which can be wired to any channel. + * The internal baud rate clock is the system clock divided by 16. + * This assumes the baudrate is 16x oversampled by the uart. + */ +#define BRG_INT_CLK (get_brgfreq()) +#define BRG_UART_CLK (BRG_INT_CLK/16) +#define BRG_UART_CLK_DIV16 (BRG_UART_CLK/16) + +void +cpm_setbrg(uint brg, uint rate) +{ + u32 __iomem *bp; + + /* This is good enough to get SMCs running..... */ + bp = &cpmp->cp_brgc1; + bp += brg; + /* + * The BRG has a 12-bit counter. For really slow baud rates (or + * really fast processors), we may have to further divide by 16. + */ + if (((BRG_UART_CLK / rate) - 1) < 4096) + out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN); + else + out_be32(bp, (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) | + CPM_BRG_EN | CPM_BRG_DIV16); +} + +struct cpm_ioport16 { + __be16 dir, par, odr_sor, dat, intr; + __be16 res[3]; +}; + +struct cpm_ioport32b { + __be32 dir, par, odr, dat; +}; + +struct cpm_ioport32e { + __be32 dir, par, sor, odr, dat; +}; + +static void cpm1_set_pin32(int port, int pin, int flags) +{ + struct cpm_ioport32e __iomem *iop; + pin = 1 << (31 - pin); + + if (port == CPM_PORTB) + iop = (struct cpm_ioport32e __iomem *) + &mpc8xx_immr->im_cpm.cp_pbdir; + else + iop = (struct cpm_ioport32e __iomem *) + &mpc8xx_immr->im_cpm.cp_pedir; + + if (flags & CPM_PIN_OUTPUT) + setbits32(&iop->dir, pin); + else + clrbits32(&iop->dir, pin); + + if (!(flags & CPM_PIN_GPIO)) + setbits32(&iop->par, pin); + else + clrbits32(&iop->par, pin); + + if (port == CPM_PORTB) { + if (flags & CPM_PIN_OPENDRAIN) + setbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin); + else + clrbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin); + } + + if (port == CPM_PORTE) { + if (flags & CPM_PIN_SECONDARY) + setbits32(&iop->sor, pin); + else + clrbits32(&iop->sor, pin); + + if (flags & CPM_PIN_OPENDRAIN) + setbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin); + else + clrbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin); + } +} + +static void cpm1_set_pin16(int port, int pin, int flags) +{ + struct cpm_ioport16 __iomem *iop = + (struct cpm_ioport16 __iomem *)&mpc8xx_immr->im_ioport; + + pin = 1 << (15 - pin); + + if (port != 0) + iop += port - 1; + + if (flags & CPM_PIN_OUTPUT) + setbits16(&iop->dir, pin); + else + clrbits16(&iop->dir, pin); + + if (!(flags & CPM_PIN_GPIO)) + setbits16(&iop->par, pin); + else + clrbits16(&iop->par, pin); + + if (port == CPM_PORTA) { + if (flags & CPM_PIN_OPENDRAIN) + setbits16(&iop->odr_sor, pin); + else + clrbits16(&iop->odr_sor, pin); + } + if (port == CPM_PORTC) { + if (flags & CPM_PIN_SECONDARY) + 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); + } +} + +void cpm1_set_pin(enum cpm_port port, int pin, int flags) +{ + if (port == CPM_PORTB || port == CPM_PORTE) + cpm1_set_pin32(port, pin, flags); + else + cpm1_set_pin16(port, pin, flags); +} + +int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode) +{ + int shift; + int i, bits = 0; + u32 __iomem *reg; + u32 mask = 7; + + u8 clk_map[][3] = { + {CPM_CLK_SCC1, CPM_BRG1, 0}, + {CPM_CLK_SCC1, CPM_BRG2, 1}, + {CPM_CLK_SCC1, CPM_BRG3, 2}, + {CPM_CLK_SCC1, CPM_BRG4, 3}, + {CPM_CLK_SCC1, CPM_CLK1, 4}, + {CPM_CLK_SCC1, CPM_CLK2, 5}, + {CPM_CLK_SCC1, CPM_CLK3, 6}, + {CPM_CLK_SCC1, CPM_CLK4, 7}, + + {CPM_CLK_SCC2, CPM_BRG1, 0}, + {CPM_CLK_SCC2, CPM_BRG2, 1}, + {CPM_CLK_SCC2, CPM_BRG3, 2}, + {CPM_CLK_SCC2, CPM_BRG4, 3}, + {CPM_CLK_SCC2, CPM_CLK1, 4}, + {CPM_CLK_SCC2, CPM_CLK2, 5}, + {CPM_CLK_SCC2, CPM_CLK3, 6}, + {CPM_CLK_SCC2, CPM_CLK4, 7}, + + {CPM_CLK_SCC3, CPM_BRG1, 0}, + {CPM_CLK_SCC3, CPM_BRG2, 1}, + {CPM_CLK_SCC3, CPM_BRG3, 2}, + {CPM_CLK_SCC3, CPM_BRG4, 3}, + {CPM_CLK_SCC3, CPM_CLK5, 4}, + {CPM_CLK_SCC3, CPM_CLK6, 5}, + {CPM_CLK_SCC3, CPM_CLK7, 6}, + {CPM_CLK_SCC3, CPM_CLK8, 7}, + + {CPM_CLK_SCC4, CPM_BRG1, 0}, + {CPM_CLK_SCC4, CPM_BRG2, 1}, + {CPM_CLK_SCC4, CPM_BRG3, 2}, + {CPM_CLK_SCC4, CPM_BRG4, 3}, + {CPM_CLK_SCC4, CPM_CLK5, 4}, + {CPM_CLK_SCC4, CPM_CLK6, 5}, + {CPM_CLK_SCC4, CPM_CLK7, 6}, + {CPM_CLK_SCC4, CPM_CLK8, 7}, + + {CPM_CLK_SMC1, CPM_BRG1, 0}, + {CPM_CLK_SMC1, CPM_BRG2, 1}, + {CPM_CLK_SMC1, CPM_BRG3, 2}, + {CPM_CLK_SMC1, CPM_BRG4, 3}, + {CPM_CLK_SMC1, CPM_CLK1, 4}, + {CPM_CLK_SMC1, CPM_CLK2, 5}, + {CPM_CLK_SMC1, CPM_CLK3, 6}, + {CPM_CLK_SMC1, CPM_CLK4, 7}, + + {CPM_CLK_SMC2, CPM_BRG1, 0}, + {CPM_CLK_SMC2, CPM_BRG2, 1}, + {CPM_CLK_SMC2, CPM_BRG3, 2}, + {CPM_CLK_SMC2, CPM_BRG4, 3}, + {CPM_CLK_SMC2, CPM_CLK5, 4}, + {CPM_CLK_SMC2, CPM_CLK6, 5}, + {CPM_CLK_SMC2, CPM_CLK7, 6}, + {CPM_CLK_SMC2, CPM_CLK8, 7}, + }; + + switch (target) { + case CPM_CLK_SCC1: + reg = &mpc8xx_immr->im_cpm.cp_sicr; + shift = 0; + break; + + case CPM_CLK_SCC2: + reg = &mpc8xx_immr->im_cpm.cp_sicr; + shift = 8; + break; + + case CPM_CLK_SCC3: + reg = &mpc8xx_immr->im_cpm.cp_sicr; + shift = 16; + break; + + case CPM_CLK_SCC4: + reg = &mpc8xx_immr->im_cpm.cp_sicr; + shift = 24; + break; + + case CPM_CLK_SMC1: + reg = &mpc8xx_immr->im_cpm.cp_simode; + shift = 12; + break; + + case CPM_CLK_SMC2: + reg = &mpc8xx_immr->im_cpm.cp_simode; + shift = 28; + break; + + default: + printk(KERN_ERR "cpm1_clock_setup: invalid clock target\n"); + return -EINVAL; + } + + for (i = 0; i < ARRAY_SIZE(clk_map); i++) { + if (clk_map[i][0] == target && clk_map[i][1] == clock) { + bits = clk_map[i][2]; + break; + } + } + + if (i == ARRAY_SIZE(clk_map)) { + printk(KERN_ERR "cpm1_clock_setup: invalid clock combination\n"); + return -EINVAL; + } + + bits <<= shift; + mask <<= shift; + + if (reg == &mpc8xx_immr->im_cpm.cp_sicr) { + if (mode == CPM_CLK_RTX) { + bits |= bits << 3; + mask |= mask << 3; + } else if (mode == CPM_CLK_RX) { + bits <<= 3; + mask <<= 3; + } + } + + out_be32(reg, (in_be32(reg) & ~mask) | bits); + + return 0; +} + +/* + * GPIO LIB API implementation + */ +#ifdef CONFIG_8xx_GPIO + +struct cpm1_gpio16_chip { + struct of_mm_gpio_chip mm_gc; + spinlock_t lock; + + /* 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) +{ + struct cpm1_gpio16_chip *cpm1_gc = + container_of(mm_gc, struct cpm1_gpio16_chip, mm_gc); + struct cpm_ioport16 __iomem *iop = mm_gc->regs; + + cpm1_gc->cpdata = in_be16(&iop->dat); +} + +static int cpm1_gpio16_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct cpm_ioport16 __iomem *iop = mm_gc->regs; + u16 pin_mask; + + pin_mask = 1 << (15 - gpio); + + return !!(in_be16(&iop->dat) & pin_mask); +} + +static void __cpm1_gpio16_set(struct of_mm_gpio_chip *mm_gc, u16 pin_mask, + int value) +{ + struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); + struct cpm_ioport16 __iomem *iop = mm_gc->regs; + + if (value) + cpm1_gc->cpdata |= pin_mask; + else + cpm1_gc->cpdata &= ~pin_mask; + + out_be16(&iop->dat, cpm1_gc->cpdata); +} + +static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value) +{ + 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); + unsigned long flags; + u16 pin_mask = 1 << (15 - gpio); + + spin_lock_irqsave(&cpm1_gc->lock, flags); + + __cpm1_gpio16_set(mm_gc, pin_mask, 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); + struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); + struct cpm_ioport16 __iomem *iop = mm_gc->regs; + unsigned long flags; + u16 pin_mask = 1 << (15 - gpio); + + spin_lock_irqsave(&cpm1_gc->lock, flags); + + setbits16(&iop->dir, pin_mask); + __cpm1_gpio16_set(mm_gc, pin_mask, val); + + spin_unlock_irqrestore(&cpm1_gc->lock, flags); + + return 0; +} + +static int cpm1_gpio16_dir_in(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); + struct cpm_ioport16 __iomem *iop = mm_gc->regs; + unsigned long flags; + u16 pin_mask = 1 << (15 - gpio); + + spin_lock_irqsave(&cpm1_gc->lock, flags); + + clrbits16(&iop->dir, pin_mask); + + spin_unlock_irqrestore(&cpm1_gc->lock, flags); + + return 0; +} + +int cpm1_gpiochip_add16(struct device *dev) +{ + struct device_node *np = dev->of_node; + 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) + return -ENOMEM; + + 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; + + mm_gc->save_regs = cpm1_gpio16_save_regs; + gc->ngpio = 16; + gc->direction_input = cpm1_gpio16_dir_in; + gc->direction_output = cpm1_gpio16_dir_out; + gc->get = cpm1_gpio16_get; + gc->set = cpm1_gpio16_set; + gc->to_irq = cpm1_gpio16_to_irq; + gc->parent = dev; + gc->owner = THIS_MODULE; + + return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc); +} + +struct cpm1_gpio32_chip { + struct of_mm_gpio_chip mm_gc; + spinlock_t lock; + + /* shadowed data register to clear/set bits safely */ + u32 cpdata; +}; + +static void cpm1_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc) +{ + struct cpm1_gpio32_chip *cpm1_gc = + container_of(mm_gc, struct cpm1_gpio32_chip, mm_gc); + struct cpm_ioport32b __iomem *iop = mm_gc->regs; + + cpm1_gc->cpdata = in_be32(&iop->dat); +} + +static int cpm1_gpio32_get(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct cpm_ioport32b __iomem *iop = mm_gc->regs; + u32 pin_mask; + + pin_mask = 1 << (31 - gpio); + + return !!(in_be32(&iop->dat) & pin_mask); +} + +static void __cpm1_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask, + int value) +{ + struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); + struct cpm_ioport32b __iomem *iop = mm_gc->regs; + + if (value) + cpm1_gc->cpdata |= pin_mask; + else + cpm1_gc->cpdata &= ~pin_mask; + + out_be32(&iop->dat, cpm1_gc->cpdata); +} + +static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); + unsigned long flags; + u32 pin_mask = 1 << (31 - gpio); + + spin_lock_irqsave(&cpm1_gc->lock, flags); + + __cpm1_gpio32_set(mm_gc, pin_mask, value); + + spin_unlock_irqrestore(&cpm1_gc->lock, flags); +} + +static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); + struct cpm_ioport32b __iomem *iop = mm_gc->regs; + unsigned long flags; + u32 pin_mask = 1 << (31 - gpio); + + spin_lock_irqsave(&cpm1_gc->lock, flags); + + setbits32(&iop->dir, pin_mask); + __cpm1_gpio32_set(mm_gc, pin_mask, val); + + spin_unlock_irqrestore(&cpm1_gc->lock, flags); + + return 0; +} + +static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio) +{ + struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); + struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); + struct cpm_ioport32b __iomem *iop = mm_gc->regs; + unsigned long flags; + u32 pin_mask = 1 << (31 - gpio); + + spin_lock_irqsave(&cpm1_gc->lock, flags); + + clrbits32(&iop->dir, pin_mask); + + spin_unlock_irqrestore(&cpm1_gc->lock, flags); + + return 0; +} + +int cpm1_gpiochip_add32(struct device *dev) +{ + struct device_node *np = dev->of_node; + struct cpm1_gpio32_chip *cpm1_gc; + struct of_mm_gpio_chip *mm_gc; + struct gpio_chip *gc; + + cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); + if (!cpm1_gc) + return -ENOMEM; + + spin_lock_init(&cpm1_gc->lock); + + mm_gc = &cpm1_gc->mm_gc; + gc = &mm_gc->gc; + + mm_gc->save_regs = cpm1_gpio32_save_regs; + gc->ngpio = 32; + gc->direction_input = cpm1_gpio32_dir_in; + gc->direction_output = cpm1_gpio32_dir_out; + gc->get = cpm1_gpio32_get; + gc->set = cpm1_gpio32_set; + gc->parent = dev; + gc->owner = THIS_MODULE; + + return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc); +} + +#endif /* CONFIG_8xx_GPIO */ diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c new file mode 100644 index 000000000000..83649a641dea --- /dev/null +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -0,0 +1,750 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Microcode patches for the CPM as supplied by Motorola. + * This is the one for IIC/SPI. There is a newer one that + * also relocates SMC2, but this would require additional changes + * to uart.c, so I am holding off on that for a moment. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * I2C/SPI relocation patch arrays. + */ + +#ifdef CONFIG_I2C_SPI_UCODE_PATCH + +static uint patch_2000[] __initdata = { + 0x7FFFEFD9, + 0x3FFD0000, + 0x7FFB49F7, + 0x7FF90000, + 0x5FEFADF7, + 0x5F89ADF7, + 0x5FEFAFF7, + 0x5F89AFF7, + 0x3A9CFBC8, + 0xE7C0EDF0, + 0x77C1E1BB, + 0xF4DC7F1D, + 0xABAD932F, + 0x4E08FDCF, + 0x6E0FAFF8, + 0x7CCF76CF, + 0xFD1FF9CF, + 0xABF88DC6, + 0xAB5679F7, + 0xB0937383, + 0xDFCE79F7, + 0xB091E6BB, + 0xE5BBE74F, + 0xB3FA6F0F, + 0x6FFB76CE, + 0xEE0DF9CF, + 0x2BFBEFEF, + 0xCFEEF9CF, + 0x76CEAD24, + 0x90B2DF9A, + 0x7FDDD0BF, + 0x4BF847FD, + 0x7CCF76CE, + 0xCFEF7E1F, + 0x7F1D7DFD, + 0xF0B6EF71, + 0x7FC177C1, + 0xFBC86079, + 0xE722FBC8, + 0x5FFFDFFF, + 0x5FB2FFFB, + 0xFBC8F3C8, + 0x94A67F01, + 0x7F1D5F39, + 0xAFE85F5E, + 0xFFDFDF96, + 0xCB9FAF7D, + 0x5FC1AFED, + 0x8C1C5FC1, + 0xAFDD5FC3, + 0xDF9A7EFD, + 0xB0B25FB2, + 0xFFFEABAD, + 0x5FB2FFFE, + 0x5FCE600B, + 0xE6BB600B, + 0x5FCEDFC6, + 0x27FBEFDF, + 0x5FC8CFDE, + 0x3A9CE7C0, + 0xEDF0F3C8, + 0x7F0154CD, + 0x7F1D2D3D, + 0x363A7570, + 0x7E0AF1CE, + 0x37EF2E68, + 0x7FEE10EC, + 0xADF8EFDE, + 0xCFEAE52F, + 0x7D0FE12B, + 0xF1CE5F65, + 0x7E0A4DF8, + 0xCFEA5F72, + 0x7D0BEFEE, + 0xCFEA5F74, + 0xE522EFDE, + 0x5F74CFDA, + 0x0B627385, + 0xDF627E0A, + 0x30D8145B, + 0xBFFFF3C8, + 0x5FFFDFFF, + 0xA7F85F5E, + 0xBFFE7F7D, + 0x10D31450, + 0x5F36BFFF, + 0xAF785F5E, + 0xBFFDA7F8, + 0x5F36BFFE, + 0x77FD30C0, + 0x4E08FDCF, + 0xE5FF6E0F, + 0xAFF87E1F, + 0x7E0FFD1F, + 0xF1CF5F1B, + 0xABF80D5E, + 0x5F5EFFEF, + 0x79F730A2, + 0xAFDD5F34, + 0x47F85F34, + 0xAFED7FDD, + 0x50B24978, + 0x47FD7F1D, + 0x7DFD70AD, + 0xEF717EC1, + 0x6BA47F01, + 0x2D267EFD, + 0x30DE5F5E, + 0xFFFD5F5E, + 0xFFEF5F5E, + 0xFFDF0CA0, + 0xAFED0A9E, + 0xAFDD0C3A, + 0x5F3AAFBD, + 0x7FBDB082, + 0x5F8247F8 +}; + +static uint patch_2f00[] __initdata = { + 0x3E303430, + 0x34343737, + 0xABF7BF9B, + 0x994B4FBD, + 0xBD599493, + 0x349FFF37, + 0xFB9B177D, + 0xD9936956, + 0xBBFDD697, + 0xBDD2FD11, + 0x31DB9BB3, + 0x63139637, + 0x93733693, + 0x193137F7, + 0x331737AF, + 0x7BB9B999, + 0xBB197957, + 0x7FDFD3D5, + 0x73B773F7, + 0x37933B99, + 0x1D115316, + 0x99315315, + 0x31694BF4, + 0xFBDBD359, + 0x31497353, + 0x76956D69, + 0x7B9D9693, + 0x13131979, + 0x79376935 +}; +#endif + +/* + * I2C/SPI/SMC1 relocation patch arrays. + */ + +#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH + +static uint patch_2000[] __initdata = { + 0x3fff0000, + 0x3ffd0000, + 0x3ffb0000, + 0x3ff90000, + 0x5f13eff8, + 0x5eb5eff8, + 0x5f88adf7, + 0x5fefadf7, + 0x3a9cfbc8, + 0x77cae1bb, + 0xf4de7fad, + 0xabae9330, + 0x4e08fdcf, + 0x6e0faff8, + 0x7ccf76cf, + 0xfdaff9cf, + 0xabf88dc8, + 0xab5879f7, + 0xb0925d8d, + 0xdfd079f7, + 0xb090e6bb, + 0xe5bbe74f, + 0x9e046f0f, + 0x6ffb76ce, + 0xee0cf9cf, + 0x2bfbefef, + 0xcfeef9cf, + 0x76cead23, + 0x90b3df99, + 0x7fddd0c1, + 0x4bf847fd, + 0x7ccf76ce, + 0xcfef77ca, + 0x7eaf7fad, + 0x7dfdf0b7, + 0xef7a7fca, + 0x77cafbc8, + 0x6079e722, + 0xfbc85fff, + 0xdfff5fb3, + 0xfffbfbc8, + 0xf3c894a5, + 0xe7c9edf9, + 0x7f9a7fad, + 0x5f36afe8, + 0x5f5bffdf, + 0xdf95cb9e, + 0xaf7d5fc3, + 0xafed8c1b, + 0x5fc3afdd, + 0x5fc5df99, + 0x7efdb0b3, + 0x5fb3fffe, + 0xabae5fb3, + 0xfffe5fd0, + 0x600be6bb, + 0x600b5fd0, + 0xdfc827fb, + 0xefdf5fca, + 0xcfde3a9c, + 0xe7c9edf9, + 0xf3c87f9e, + 0x54ca7fed, + 0x2d3a3637, + 0x756f7e9a, + 0xf1ce37ef, + 0x2e677fee, + 0x10ebadf8, + 0xefdecfea, + 0xe52f7d9f, + 0xe12bf1ce, + 0x5f647e9a, + 0x4df8cfea, + 0x5f717d9b, + 0xefeecfea, + 0x5f73e522, + 0xefde5f73, + 0xcfda0b61, + 0x5d8fdf61, + 0xe7c9edf9, + 0x7e9a30d5, + 0x1458bfff, + 0xf3c85fff, + 0xdfffa7f8, + 0x5f5bbffe, + 0x7f7d10d0, + 0x144d5f33, + 0xbfffaf78, + 0x5f5bbffd, + 0xa7f85f33, + 0xbffe77fd, + 0x30bd4e08, + 0xfdcfe5ff, + 0x6e0faff8, + 0x7eef7e9f, + 0xfdeff1cf, + 0x5f17abf8, + 0x0d5b5f5b, + 0xffef79f7, + 0x309eafdd, + 0x5f3147f8, + 0x5f31afed, + 0x7fdd50af, + 0x497847fd, + 0x7f9e7fed, + 0x7dfd70a9, + 0xef7e7ece, + 0x6ba07f9e, + 0x2d227efd, + 0x30db5f5b, + 0xfffd5f5b, + 0xffef5f5b, + 0xffdf0c9c, + 0xafed0a9a, + 0xafdd0c37, + 0x5f37afbd, + 0x7fbdb081, + 0x5f8147f8, + 0x3a11e710, + 0xedf0ccdd, + 0xf3186d0a, + 0x7f0e5f06, + 0x7fedbb38, + 0x3afe7468, + 0x7fedf4fc, + 0x8ffbb951, + 0xb85f77fd, + 0xb0df5ddd, + 0xdefe7fed, + 0x90e1e74d, + 0x6f0dcbf7, + 0xe7decfed, + 0xcb74cfed, + 0xcfeddf6d, + 0x91714f74, + 0x5dd2deef, + 0x9e04e7df, + 0xefbb6ffb, + 0xe7ef7f0e, + 0x9e097fed, + 0xebdbeffa, + 0xeb54affb, + 0x7fea90d7, + 0x7e0cf0c3, + 0xbffff318, + 0x5fffdfff, + 0xac59efea, + 0x7fce1ee5, + 0xe2ff5ee1, + 0xaffbe2ff, + 0x5ee3affb, + 0xf9cc7d0f, + 0xaef8770f, + 0x7d0fb0c6, + 0xeffbbfff, + 0xcfef5ede, + 0x7d0fbfff, + 0x5ede4cf8, + 0x7fddd0bf, + 0x49f847fd, + 0x7efdf0bb, + 0x7fedfffd, + 0x7dfdf0b7, + 0xef7e7e1e, + 0x5ede7f0e, + 0x3a11e710, + 0xedf0ccab, + 0xfb18ad2e, + 0x1ea9bbb8, + 0x74283b7e, + 0x73c2e4bb, + 0x2ada4fb8, + 0xdc21e4bb, + 0xb2a1ffbf, + 0x5e2c43f8, + 0xfc87e1bb, + 0xe74ffd91, + 0x6f0f4fe8, + 0xc7ba32e2, + 0xf396efeb, + 0x600b4f78, + 0xe5bb760b, + 0x53acaef8, + 0x4ef88b0e, + 0xcfef9e09, + 0xabf8751f, + 0xefef5bac, + 0x741f4fe8, + 0x751e760d, + 0x7fdbf081, + 0x741cafce, + 0xefcc7fce, + 0x751e70ac, + 0x741ce7bb, + 0x3372cfed, + 0xafdbefeb, + 0xe5bb760b, + 0x53f2aef8, + 0xafe8e7eb, + 0x4bf8771e, + 0x7e247fed, + 0x4fcbe2cc, + 0x7fbc30a9, + 0x7b0f7a0f, + 0x34d577fd, + 0x308b5db7, + 0xde553e5f, + 0xaf78741f, + 0x741f30f0, + 0xcfef5e2c, + 0x741f3eac, + 0xafb8771e, + 0x5e677fed, + 0x0bd3e2cc, + 0x741ccfec, + 0xe5ca53cd, + 0x6fcb4f74, + 0x5dadde4b, + 0x2ab63d38, + 0x4bb3de30, + 0x751f741c, + 0x6c42effa, + 0xefea7fce, + 0x6ffc30be, + 0xefec3fca, + 0x30b3de2e, + 0xadf85d9e, + 0xaf7daefd, + 0x5d9ede2e, + 0x5d9eafdd, + 0x761f10ac, + 0x1da07efd, + 0x30adfffe, + 0x4908fb18, + 0x5fffdfff, + 0xafbb709b, + 0x4ef85e67, + 0xadf814ad, + 0x7a0f70ad, + 0xcfef50ad, + 0x7a0fde30, + 0x5da0afed, + 0x3c12780f, + 0xefef780f, + 0xefef790f, + 0xa7f85e0f, + 0xffef790f, + 0xefef790f, + 0x14adde2e, + 0x5d9eadfd, + 0x5e2dfffb, + 0xe79addfd, + 0xeff96079, + 0x607ae79a, + 0xddfceff9, + 0x60795dff, + 0x607acfef, + 0xefefefdf, + 0xefbfef7f, + 0xeeffedff, + 0xebffe7ff, + 0xafefafdf, + 0xafbfaf7f, + 0xaeffadff, + 0xabffa7ff, + 0x6fef6fdf, + 0x6fbf6f7f, + 0x6eff6dff, + 0x6bff67ff, + 0x2fef2fdf, + 0x2fbf2f7f, + 0x2eff2dff, + 0x2bff27ff, + 0x4e08fd1f, + 0xe5ff6e0f, + 0xaff87eef, + 0x7e0ffdef, + 0xf11f6079, + 0xabf8f542, + 0x7e0af11c, + 0x37cfae3a, + 0x7fec90be, + 0xadf8efdc, + 0xcfeae52f, + 0x7d0fe12b, + 0xf11c6079, + 0x7e0a4df8, + 0xcfea5dc4, + 0x7d0befec, + 0xcfea5dc6, + 0xe522efdc, + 0x5dc6cfda, + 0x4e08fd1f, + 0x6e0faff8, + 0x7c1f761f, + 0xfdeff91f, + 0x6079abf8, + 0x761cee24, + 0xf91f2bfb, + 0xefefcfec, + 0xf91f6079, + 0x761c27fb, + 0xefdf5da7, + 0xcfdc7fdd, + 0xd09c4bf8, + 0x47fd7c1f, + 0x761ccfcf, + 0x7eef7fed, + 0x7dfdf093, + 0xef7e7f1e, + 0x771efb18, + 0x6079e722, + 0xe6bbe5bb, + 0xae0ae5bb, + 0x600bae85, + 0xe2bbe2bb, + 0xe2bbe2bb, + 0xaf02e2bb, + 0xe2bb2ff9, + 0x6079e2bb +}; + +static uint patch_2f00[] __initdata = { + 0x30303030, + 0x3e3e3434, + 0xabbf9b99, + 0x4b4fbdbd, + 0x59949334, + 0x9fff37fb, + 0x9b177dd9, + 0x936956bb, + 0xfbdd697b, + 0xdd2fd113, + 0x1db9f7bb, + 0x36313963, + 0x79373369, + 0x3193137f, + 0x7331737a, + 0xf7bb9b99, + 0x9bb19795, + 0x77fdfd3d, + 0x573b773f, + 0x737933f7, + 0xb991d115, + 0x31699315, + 0x31531694, + 0xbf4fbdbd, + 0x35931497, + 0x35376956, + 0xbd697b9d, + 0x96931313, + 0x19797937, + 0x6935af78, + 0xb9b3baa3, + 0xb8788683, + 0x368f78f7, + 0x87778733, + 0x3ffffb3b, + 0x8e8f78b8, + 0x1d118e13, + 0xf3ff3f8b, + 0x6bd8e173, + 0xd1366856, + 0x68d1687b, + 0x3daf78b8, + 0x3a3a3f87, + 0x8f81378f, + 0xf876f887, + 0x77fd8778, + 0x737de8d6, + 0xbbf8bfff, + 0xd8df87f7, + 0xfd876f7b, + 0x8bfff8bd, + 0x8683387d, + 0xb873d87b, + 0x3b8fd7f8, + 0xf7338883, + 0xbb8ee1f8, + 0xef837377, + 0x3337b836, + 0x817d11f8, + 0x7378b878, + 0xd3368b7d, + 0xed731b7d, + 0x833731f3, + 0xf22f3f23 +}; + +static uint patch_2e00[] __initdata = { + 0x27eeeeee, + 0xeeeeeeee, + 0xeeeeeeee, + 0xeeeeeeee, + 0xee4bf4fb, + 0xdbd259bb, + 0x1979577f, + 0xdfd2d573, + 0xb773f737, + 0x4b4fbdbd, + 0x25b9b177, + 0xd2d17376, + 0x956bbfdd, + 0x697bdd2f, + 0xff9f79ff, + 0xff9ff22f +}; +#endif + +/* + * USB SOF patch arrays. + */ + +#ifdef CONFIG_USB_SOF_UCODE_PATCH + +static uint patch_2000[] __initdata = { + 0x7fff0000, + 0x7ffd0000, + 0x7ffb0000, + 0x49f7ba5b, + 0xba383ffb, + 0xf9b8b46d, + 0xe5ab4e07, + 0xaf77bffe, + 0x3f7bbf79, + 0xba5bba38, + 0xe7676076, + 0x60750000 +}; + +static uint patch_2f00[] __initdata = { + 0x3030304c, + 0xcab9e441, + 0xa1aaf220 +}; +#endif + +void __init cpm_load_patch(cpm8xx_t *cp) +{ + volatile uint *dp; /* Dual-ported RAM. */ + volatile cpm8xx_t *commproc; +#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ + defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) + volatile iic_t *iip; + volatile struct spi_pram *spp; +#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH + volatile smc_uart_t *smp; +#endif +#endif + int i; + + commproc = cp; + +#ifdef CONFIG_USB_SOF_UCODE_PATCH + commproc->cp_rccr = 0; + + dp = (uint *)(commproc->cp_dpmem); + for (i=0; i<(sizeof(patch_2000)/4); i++) + *dp++ = patch_2000[i]; + + dp = (uint *)&(commproc->cp_dpmem[0x0f00]); + for (i=0; i<(sizeof(patch_2f00)/4); i++) + *dp++ = patch_2f00[i]; + + commproc->cp_rccr = 0x0009; + + printk("USB SOF microcode patch installed\n"); +#endif /* CONFIG_USB_SOF_UCODE_PATCH */ + +#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ + defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) + + commproc->cp_rccr = 0; + + dp = (uint *)(commproc->cp_dpmem); + for (i=0; i<(sizeof(patch_2000)/4); i++) + *dp++ = patch_2000[i]; + + dp = (uint *)&(commproc->cp_dpmem[0x0f00]); + for (i=0; i<(sizeof(patch_2f00)/4); i++) + *dp++ = patch_2f00[i]; + + iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC]; +# define RPBASE 0x0500 + iip->iic_rpbase = RPBASE; + + /* Put SPI above the IIC, also 32-byte aligned. + */ + i = (RPBASE + sizeof(iic_t) + 31) & ~31; + spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI]; + spp->rpbase = i; + +# if defined(CONFIG_I2C_SPI_UCODE_PATCH) + commproc->cp_cpmcr1 = 0x802a; + commproc->cp_cpmcr2 = 0x8028; + commproc->cp_cpmcr3 = 0x802e; + commproc->cp_cpmcr4 = 0x802c; + commproc->cp_rccr = 1; + + printk("I2C/SPI microcode patch installed.\n"); +# endif /* CONFIG_I2C_SPI_UCODE_PATCH */ + +# if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) + + dp = (uint *)&(commproc->cp_dpmem[0x0e00]); + for (i=0; i<(sizeof(patch_2e00)/4); i++) + *dp++ = patch_2e00[i]; + + commproc->cp_cpmcr1 = 0x8080; + commproc->cp_cpmcr2 = 0x808a; + commproc->cp_cpmcr3 = 0x8028; + commproc->cp_cpmcr4 = 0x802a; + commproc->cp_rccr = 3; + + smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1]; + smp->smc_rpbase = 0x1FC0; + + printk("I2C/SPI/SMC1 microcode patch installed.\n"); +# endif /* CONFIG_I2C_SPI_SMC1_UCODE_PATCH) */ + +#endif /* some variation of the I2C/SPI patch was selected */ +} + +/* + * Take this entire routine out, since no one calls it and its + * logic is suspect. + */ + +#if 0 +void +verify_patch(volatile immap_t *immr) +{ + volatile uint *dp; + volatile cpm8xx_t *commproc; + int i; + + commproc = (cpm8xx_t *)&immr->im_cpm; + + printk("cp_rccr %x\n", commproc->cp_rccr); + commproc->cp_rccr = 0; + + dp = (uint *)(commproc->cp_dpmem); + for (i=0; i<(sizeof(patch_2000)/4); i++) + if (*dp++ != patch_2000[i]) { + printk("patch_2000 bad at %d\n", i); + dp--; + printk("found 0x%X, wanted 0x%X\n", *dp, patch_2000[i]); + break; + } + + dp = (uint *)&(commproc->cp_dpmem[0x0f00]); + for (i=0; i<(sizeof(patch_2f00)/4); i++) + if (*dp++ != patch_2f00[i]) { + printk("patch_2f00 bad at %d\n", i); + dp--; + printk("found 0x%X, wanted 0x%X\n", *dp, patch_2f00[i]); + break; + } + + commproc->cp_rccr = 0x0009; +} +#endif diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile index aaf23283ba0c..9d73dfddf060 100644 --- a/arch/powerpc/sysdev/Makefile +++ b/arch/powerpc/sysdev/Makefile @@ -37,12 +37,10 @@ obj-$(CONFIG_XILINX_PCI) += xilinx_pci.o obj-$(CONFIG_OF_RTC) += of_rtc.o obj-$(CONFIG_CPM) += cpm_common.o -obj-$(CONFIG_CPM1) += cpm1.o obj-$(CONFIG_CPM2) += cpm2.o cpm2_pic.o cpm_gpio.o obj-$(CONFIG_8xx_GPIO) += cpm_gpio.o obj-$(CONFIG_QUICC_ENGINE) += cpm_common.o obj-$(CONFIG_PPC_DCR) += dcr.o -obj-$(CONFIG_UCODE_PATCH) += micropatch.o obj-$(CONFIG_PPC_MPC512x) += mpc5xxx_clocks.o obj-$(CONFIG_PPC_MPC52xx) += mpc5xxx_clocks.o diff --git a/arch/powerpc/sysdev/cpm1.c b/arch/powerpc/sysdev/cpm1.c deleted file mode 100644 index 4f8dcf124828..000000000000 --- a/arch/powerpc/sysdev/cpm1.c +++ /dev/null @@ -1,788 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 -/* - * General Purpose functions for the global management of the - * Communication Processor Module. - * Copyright (c) 1997 Dan error_act (dmalek@jlc.net) - * - * In addition to the individual control of the communication - * channels, there are a few functions that globally affect the - * communication processor. - * - * Buffer descriptors must be allocated from the dual ported memory - * space. The allocator for that is here. When the communication - * process is reset, we reclaim the memory available. There is - * currently no deallocator for this memory. - * The amount of space available is platform dependent. On the - * MBX, the EPPC software loads additional microcode into the - * communication processor, and uses some of the DP ram for this - * purpose. Current, the first 512 bytes and the last 256 bytes of - * memory are used. Right now I am conservative and only use the - * memory that can never be used for microcode. If there are - * applications that require more DP ram, we can expand the boundaries - * but then we have to be careful of any downloaded microcode. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#ifdef CONFIG_8xx_GPIO -#include -#endif - -#define CPM_MAP_SIZE (0x4000) - -cpm8xx_t __iomem *cpmp; /* Pointer to comm processor space */ -immap_t __iomem *mpc8xx_immr; -static cpic8xx_t __iomem *cpic_reg; - -static struct irq_domain *cpm_pic_host; - -static void cpm_mask_irq(struct irq_data *d) -{ - unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d); - - clrbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec)); -} - -static void cpm_unmask_irq(struct irq_data *d) -{ - unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d); - - setbits32(&cpic_reg->cpic_cimr, (1 << cpm_vec)); -} - -static void cpm_end_irq(struct irq_data *d) -{ - unsigned int cpm_vec = (unsigned int)irqd_to_hwirq(d); - - out_be32(&cpic_reg->cpic_cisr, (1 << cpm_vec)); -} - -static struct irq_chip cpm_pic = { - .name = "CPM PIC", - .irq_mask = cpm_mask_irq, - .irq_unmask = cpm_unmask_irq, - .irq_eoi = cpm_end_irq, -}; - -int cpm_get_irq(void) -{ - int cpm_vec; - - /* Get the vector by setting the ACK bit and then reading - * the register. - */ - out_be16(&cpic_reg->cpic_civr, 1); - cpm_vec = in_be16(&cpic_reg->cpic_civr); - cpm_vec >>= 11; - - return irq_linear_revmap(cpm_pic_host, cpm_vec); -} - -static int cpm_pic_host_map(struct irq_domain *h, unsigned int virq, - irq_hw_number_t hw) -{ - pr_debug("cpm_pic_host_map(%d, 0x%lx)\n", virq, hw); - - irq_set_status_flags(virq, IRQ_LEVEL); - irq_set_chip_and_handler(virq, &cpm_pic, handle_fasteoi_irq); - return 0; -} - -/* The CPM can generate the error interrupt when there is a race condition - * between generating and masking interrupts. All we have to do is ACK it - * and return. This is a no-op function so we don't need any special - * tests in the interrupt handler. - */ -static irqreturn_t cpm_error_interrupt(int irq, void *dev) -{ - return IRQ_HANDLED; -} - -static struct irqaction cpm_error_irqaction = { - .handler = cpm_error_interrupt, - .flags = IRQF_NO_THREAD, - .name = "error", -}; - -static const struct irq_domain_ops cpm_pic_host_ops = { - .map = cpm_pic_host_map, -}; - -unsigned int cpm_pic_init(void) -{ - struct device_node *np = NULL; - struct resource res; - unsigned int sirq = 0, hwirq, eirq; - int ret; - - pr_debug("cpm_pic_init\n"); - - np = of_find_compatible_node(NULL, NULL, "fsl,cpm1-pic"); - if (np == NULL) - np = of_find_compatible_node(NULL, "cpm-pic", "CPM"); - if (np == NULL) { - printk(KERN_ERR "CPM PIC init: can not find cpm-pic node\n"); - return sirq; - } - - ret = of_address_to_resource(np, 0, &res); - if (ret) - goto end; - - cpic_reg = ioremap(res.start, resource_size(&res)); - if (cpic_reg == NULL) - goto end; - - sirq = irq_of_parse_and_map(np, 0); - if (!sirq) - goto end; - - /* Initialize the CPM interrupt controller. */ - hwirq = (unsigned int)virq_to_hw(sirq); - out_be32(&cpic_reg->cpic_cicr, - (CICR_SCD_SCC4 | CICR_SCC_SCC3 | CICR_SCB_SCC2 | CICR_SCA_SCC1) | - ((hwirq/2) << 13) | CICR_HP_MASK); - - out_be32(&cpic_reg->cpic_cimr, 0); - - cpm_pic_host = irq_domain_add_linear(np, 64, &cpm_pic_host_ops, NULL); - if (cpm_pic_host == NULL) { - printk(KERN_ERR "CPM2 PIC: failed to allocate irq host!\n"); - sirq = 0; - goto end; - } - - /* Install our own error handler. */ - np = of_find_compatible_node(NULL, NULL, "fsl,cpm1"); - if (np == NULL) - np = of_find_node_by_type(NULL, "cpm"); - if (np == NULL) { - printk(KERN_ERR "CPM PIC init: can not find cpm node\n"); - goto end; - } - - eirq = irq_of_parse_and_map(np, 0); - if (!eirq) - goto end; - - if (setup_irq(eirq, &cpm_error_irqaction)) - printk(KERN_ERR "Could not allocate CPM error IRQ!"); - - setbits32(&cpic_reg->cpic_cicr, CICR_IEN); - -end: - of_node_put(np); - return sirq; -} - -void __init cpm_reset(void) -{ - sysconf8xx_t __iomem *siu_conf; - - mpc8xx_immr = ioremap(get_immrbase(), 0x4000); - if (!mpc8xx_immr) { - printk(KERN_CRIT "Could not map IMMR\n"); - return; - } - - cpmp = &mpc8xx_immr->im_cpm; - -#ifndef CONFIG_PPC_EARLY_DEBUG_CPM - /* Perform a reset. - */ - out_be16(&cpmp->cp_cpcr, CPM_CR_RST | CPM_CR_FLG); - - /* Wait for it. - */ - while (in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG); -#endif - -#ifdef CONFIG_UCODE_PATCH - cpm_load_patch(cpmp); -#endif - - /* Set SDMA Bus Request priority 5. - * On 860T, this also enables FEC priority 6. I am not sure - * this is what we really want for some applications, but the - * manual recommends it. - * Bit 25, FAM can also be set to use FEC aggressive mode (860T). - */ - siu_conf = immr_map(im_siu_conf); - if ((mfspr(SPRN_IMMR) & 0xffff) == 0x0900) /* MPC885 */ - out_be32(&siu_conf->sc_sdcr, 0x40); - else - out_be32(&siu_conf->sc_sdcr, 1); - immr_unmap(siu_conf); -} - -static DEFINE_SPINLOCK(cmd_lock); - -#define MAX_CR_CMD_LOOPS 10000 - -int cpm_command(u32 command, u8 opcode) -{ - int i, ret; - unsigned long flags; - - if (command & 0xffffff0f) - return -EINVAL; - - spin_lock_irqsave(&cmd_lock, flags); - - ret = 0; - out_be16(&cpmp->cp_cpcr, command | CPM_CR_FLG | (opcode << 8)); - for (i = 0; i < MAX_CR_CMD_LOOPS; i++) - if ((in_be16(&cpmp->cp_cpcr) & CPM_CR_FLG) == 0) - goto out; - - printk(KERN_ERR "%s(): Not able to issue CPM command\n", __func__); - ret = -EIO; -out: - spin_unlock_irqrestore(&cmd_lock, flags); - return ret; -} -EXPORT_SYMBOL(cpm_command); - -/* Set a baud rate generator. This needs lots of work. There are - * four BRGs, any of which can be wired to any channel. - * The internal baud rate clock is the system clock divided by 16. - * This assumes the baudrate is 16x oversampled by the uart. - */ -#define BRG_INT_CLK (get_brgfreq()) -#define BRG_UART_CLK (BRG_INT_CLK/16) -#define BRG_UART_CLK_DIV16 (BRG_UART_CLK/16) - -void -cpm_setbrg(uint brg, uint rate) -{ - u32 __iomem *bp; - - /* This is good enough to get SMCs running..... - */ - bp = &cpmp->cp_brgc1; - bp += brg; - /* The BRG has a 12-bit counter. For really slow baud rates (or - * really fast processors), we may have to further divide by 16. - */ - if (((BRG_UART_CLK / rate) - 1) < 4096) - out_be32(bp, (((BRG_UART_CLK / rate) - 1) << 1) | CPM_BRG_EN); - else - out_be32(bp, (((BRG_UART_CLK_DIV16 / rate) - 1) << 1) | - CPM_BRG_EN | CPM_BRG_DIV16); -} - -struct cpm_ioport16 { - __be16 dir, par, odr_sor, dat, intr; - __be16 res[3]; -}; - -struct cpm_ioport32b { - __be32 dir, par, odr, dat; -}; - -struct cpm_ioport32e { - __be32 dir, par, sor, odr, dat; -}; - -static void cpm1_set_pin32(int port, int pin, int flags) -{ - struct cpm_ioport32e __iomem *iop; - pin = 1 << (31 - pin); - - if (port == CPM_PORTB) - iop = (struct cpm_ioport32e __iomem *) - &mpc8xx_immr->im_cpm.cp_pbdir; - else - iop = (struct cpm_ioport32e __iomem *) - &mpc8xx_immr->im_cpm.cp_pedir; - - if (flags & CPM_PIN_OUTPUT) - setbits32(&iop->dir, pin); - else - clrbits32(&iop->dir, pin); - - if (!(flags & CPM_PIN_GPIO)) - setbits32(&iop->par, pin); - else - clrbits32(&iop->par, pin); - - if (port == CPM_PORTB) { - if (flags & CPM_PIN_OPENDRAIN) - setbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin); - else - clrbits16(&mpc8xx_immr->im_cpm.cp_pbodr, pin); - } - - if (port == CPM_PORTE) { - if (flags & CPM_PIN_SECONDARY) - setbits32(&iop->sor, pin); - else - clrbits32(&iop->sor, pin); - - if (flags & CPM_PIN_OPENDRAIN) - setbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin); - else - clrbits32(&mpc8xx_immr->im_cpm.cp_peodr, pin); - } -} - -static void cpm1_set_pin16(int port, int pin, int flags) -{ - struct cpm_ioport16 __iomem *iop = - (struct cpm_ioport16 __iomem *)&mpc8xx_immr->im_ioport; - - pin = 1 << (15 - pin); - - if (port != 0) - iop += port - 1; - - if (flags & CPM_PIN_OUTPUT) - setbits16(&iop->dir, pin); - else - clrbits16(&iop->dir, pin); - - if (!(flags & CPM_PIN_GPIO)) - setbits16(&iop->par, pin); - else - clrbits16(&iop->par, pin); - - if (port == CPM_PORTA) { - if (flags & CPM_PIN_OPENDRAIN) - setbits16(&iop->odr_sor, pin); - else - clrbits16(&iop->odr_sor, pin); - } - if (port == CPM_PORTC) { - if (flags & CPM_PIN_SECONDARY) - 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); - } -} - -void cpm1_set_pin(enum cpm_port port, int pin, int flags) -{ - if (port == CPM_PORTB || port == CPM_PORTE) - cpm1_set_pin32(port, pin, flags); - else - cpm1_set_pin16(port, pin, flags); -} - -int cpm1_clk_setup(enum cpm_clk_target target, int clock, int mode) -{ - int shift; - int i, bits = 0; - u32 __iomem *reg; - u32 mask = 7; - - u8 clk_map[][3] = { - {CPM_CLK_SCC1, CPM_BRG1, 0}, - {CPM_CLK_SCC1, CPM_BRG2, 1}, - {CPM_CLK_SCC1, CPM_BRG3, 2}, - {CPM_CLK_SCC1, CPM_BRG4, 3}, - {CPM_CLK_SCC1, CPM_CLK1, 4}, - {CPM_CLK_SCC1, CPM_CLK2, 5}, - {CPM_CLK_SCC1, CPM_CLK3, 6}, - {CPM_CLK_SCC1, CPM_CLK4, 7}, - - {CPM_CLK_SCC2, CPM_BRG1, 0}, - {CPM_CLK_SCC2, CPM_BRG2, 1}, - {CPM_CLK_SCC2, CPM_BRG3, 2}, - {CPM_CLK_SCC2, CPM_BRG4, 3}, - {CPM_CLK_SCC2, CPM_CLK1, 4}, - {CPM_CLK_SCC2, CPM_CLK2, 5}, - {CPM_CLK_SCC2, CPM_CLK3, 6}, - {CPM_CLK_SCC2, CPM_CLK4, 7}, - - {CPM_CLK_SCC3, CPM_BRG1, 0}, - {CPM_CLK_SCC3, CPM_BRG2, 1}, - {CPM_CLK_SCC3, CPM_BRG3, 2}, - {CPM_CLK_SCC3, CPM_BRG4, 3}, - {CPM_CLK_SCC3, CPM_CLK5, 4}, - {CPM_CLK_SCC3, CPM_CLK6, 5}, - {CPM_CLK_SCC3, CPM_CLK7, 6}, - {CPM_CLK_SCC3, CPM_CLK8, 7}, - - {CPM_CLK_SCC4, CPM_BRG1, 0}, - {CPM_CLK_SCC4, CPM_BRG2, 1}, - {CPM_CLK_SCC4, CPM_BRG3, 2}, - {CPM_CLK_SCC4, CPM_BRG4, 3}, - {CPM_CLK_SCC4, CPM_CLK5, 4}, - {CPM_CLK_SCC4, CPM_CLK6, 5}, - {CPM_CLK_SCC4, CPM_CLK7, 6}, - {CPM_CLK_SCC4, CPM_CLK8, 7}, - - {CPM_CLK_SMC1, CPM_BRG1, 0}, - {CPM_CLK_SMC1, CPM_BRG2, 1}, - {CPM_CLK_SMC1, CPM_BRG3, 2}, - {CPM_CLK_SMC1, CPM_BRG4, 3}, - {CPM_CLK_SMC1, CPM_CLK1, 4}, - {CPM_CLK_SMC1, CPM_CLK2, 5}, - {CPM_CLK_SMC1, CPM_CLK3, 6}, - {CPM_CLK_SMC1, CPM_CLK4, 7}, - - {CPM_CLK_SMC2, CPM_BRG1, 0}, - {CPM_CLK_SMC2, CPM_BRG2, 1}, - {CPM_CLK_SMC2, CPM_BRG3, 2}, - {CPM_CLK_SMC2, CPM_BRG4, 3}, - {CPM_CLK_SMC2, CPM_CLK5, 4}, - {CPM_CLK_SMC2, CPM_CLK6, 5}, - {CPM_CLK_SMC2, CPM_CLK7, 6}, - {CPM_CLK_SMC2, CPM_CLK8, 7}, - }; - - switch (target) { - case CPM_CLK_SCC1: - reg = &mpc8xx_immr->im_cpm.cp_sicr; - shift = 0; - break; - - case CPM_CLK_SCC2: - reg = &mpc8xx_immr->im_cpm.cp_sicr; - shift = 8; - break; - - case CPM_CLK_SCC3: - reg = &mpc8xx_immr->im_cpm.cp_sicr; - shift = 16; - break; - - case CPM_CLK_SCC4: - reg = &mpc8xx_immr->im_cpm.cp_sicr; - shift = 24; - break; - - case CPM_CLK_SMC1: - reg = &mpc8xx_immr->im_cpm.cp_simode; - shift = 12; - break; - - case CPM_CLK_SMC2: - reg = &mpc8xx_immr->im_cpm.cp_simode; - shift = 28; - break; - - default: - printk(KERN_ERR "cpm1_clock_setup: invalid clock target\n"); - return -EINVAL; - } - - for (i = 0; i < ARRAY_SIZE(clk_map); i++) { - if (clk_map[i][0] == target && clk_map[i][1] == clock) { - bits = clk_map[i][2]; - break; - } - } - - if (i == ARRAY_SIZE(clk_map)) { - printk(KERN_ERR "cpm1_clock_setup: invalid clock combination\n"); - return -EINVAL; - } - - bits <<= shift; - mask <<= shift; - - if (reg == &mpc8xx_immr->im_cpm.cp_sicr) { - if (mode == CPM_CLK_RTX) { - bits |= bits << 3; - mask |= mask << 3; - } else if (mode == CPM_CLK_RX) { - bits <<= 3; - mask <<= 3; - } - } - - out_be32(reg, (in_be32(reg) & ~mask) | bits); - - return 0; -} - -/* - * GPIO LIB API implementation - */ -#ifdef CONFIG_8xx_GPIO - -struct cpm1_gpio16_chip { - struct of_mm_gpio_chip mm_gc; - spinlock_t lock; - - /* 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) -{ - struct cpm1_gpio16_chip *cpm1_gc = - container_of(mm_gc, struct cpm1_gpio16_chip, mm_gc); - struct cpm_ioport16 __iomem *iop = mm_gc->regs; - - cpm1_gc->cpdata = in_be16(&iop->dat); -} - -static int cpm1_gpio16_get(struct gpio_chip *gc, unsigned int gpio) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm_ioport16 __iomem *iop = mm_gc->regs; - u16 pin_mask; - - pin_mask = 1 << (15 - gpio); - - return !!(in_be16(&iop->dat) & pin_mask); -} - -static void __cpm1_gpio16_set(struct of_mm_gpio_chip *mm_gc, u16 pin_mask, - int value) -{ - struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); - struct cpm_ioport16 __iomem *iop = mm_gc->regs; - - if (value) - cpm1_gc->cpdata |= pin_mask; - else - cpm1_gc->cpdata &= ~pin_mask; - - out_be16(&iop->dat, cpm1_gc->cpdata); -} - -static void cpm1_gpio16_set(struct gpio_chip *gc, unsigned int gpio, int value) -{ - 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); - unsigned long flags; - u16 pin_mask = 1 << (15 - gpio); - - spin_lock_irqsave(&cpm1_gc->lock, flags); - - __cpm1_gpio16_set(mm_gc, pin_mask, 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); - struct cpm1_gpio16_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); - struct cpm_ioport16 __iomem *iop = mm_gc->regs; - unsigned long flags; - u16 pin_mask = 1 << (15 - gpio); - - spin_lock_irqsave(&cpm1_gc->lock, flags); - - setbits16(&iop->dir, pin_mask); - __cpm1_gpio16_set(mm_gc, pin_mask, val); - - spin_unlock_irqrestore(&cpm1_gc->lock, flags); - - return 0; -} - -static int cpm1_gpio16_dir_in(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); - struct cpm_ioport16 __iomem *iop = mm_gc->regs; - unsigned long flags; - u16 pin_mask = 1 << (15 - gpio); - - spin_lock_irqsave(&cpm1_gc->lock, flags); - - clrbits16(&iop->dir, pin_mask); - - spin_unlock_irqrestore(&cpm1_gc->lock, flags); - - return 0; -} - -int cpm1_gpiochip_add16(struct device *dev) -{ - struct device_node *np = dev->of_node; - 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) - return -ENOMEM; - - 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; - - mm_gc->save_regs = cpm1_gpio16_save_regs; - gc->ngpio = 16; - gc->direction_input = cpm1_gpio16_dir_in; - gc->direction_output = cpm1_gpio16_dir_out; - gc->get = cpm1_gpio16_get; - gc->set = cpm1_gpio16_set; - gc->to_irq = cpm1_gpio16_to_irq; - gc->parent = dev; - gc->owner = THIS_MODULE; - - return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc); -} - -struct cpm1_gpio32_chip { - struct of_mm_gpio_chip mm_gc; - spinlock_t lock; - - /* shadowed data register to clear/set bits safely */ - u32 cpdata; -}; - -static void cpm1_gpio32_save_regs(struct of_mm_gpio_chip *mm_gc) -{ - struct cpm1_gpio32_chip *cpm1_gc = - container_of(mm_gc, struct cpm1_gpio32_chip, mm_gc); - struct cpm_ioport32b __iomem *iop = mm_gc->regs; - - cpm1_gc->cpdata = in_be32(&iop->dat); -} - -static int cpm1_gpio32_get(struct gpio_chip *gc, unsigned int gpio) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm_ioport32b __iomem *iop = mm_gc->regs; - u32 pin_mask; - - pin_mask = 1 << (31 - gpio); - - return !!(in_be32(&iop->dat) & pin_mask); -} - -static void __cpm1_gpio32_set(struct of_mm_gpio_chip *mm_gc, u32 pin_mask, - int value) -{ - struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); - struct cpm_ioport32b __iomem *iop = mm_gc->regs; - - if (value) - cpm1_gc->cpdata |= pin_mask; - else - cpm1_gc->cpdata &= ~pin_mask; - - out_be32(&iop->dat, cpm1_gc->cpdata); -} - -static void cpm1_gpio32_set(struct gpio_chip *gc, unsigned int gpio, int value) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); - unsigned long flags; - u32 pin_mask = 1 << (31 - gpio); - - spin_lock_irqsave(&cpm1_gc->lock, flags); - - __cpm1_gpio32_set(mm_gc, pin_mask, value); - - spin_unlock_irqrestore(&cpm1_gc->lock, flags); -} - -static int cpm1_gpio32_dir_out(struct gpio_chip *gc, unsigned int gpio, int val) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); - struct cpm_ioport32b __iomem *iop = mm_gc->regs; - unsigned long flags; - u32 pin_mask = 1 << (31 - gpio); - - spin_lock_irqsave(&cpm1_gc->lock, flags); - - setbits32(&iop->dir, pin_mask); - __cpm1_gpio32_set(mm_gc, pin_mask, val); - - spin_unlock_irqrestore(&cpm1_gc->lock, flags); - - return 0; -} - -static int cpm1_gpio32_dir_in(struct gpio_chip *gc, unsigned int gpio) -{ - struct of_mm_gpio_chip *mm_gc = to_of_mm_gpio_chip(gc); - struct cpm1_gpio32_chip *cpm1_gc = gpiochip_get_data(&mm_gc->gc); - struct cpm_ioport32b __iomem *iop = mm_gc->regs; - unsigned long flags; - u32 pin_mask = 1 << (31 - gpio); - - spin_lock_irqsave(&cpm1_gc->lock, flags); - - clrbits32(&iop->dir, pin_mask); - - spin_unlock_irqrestore(&cpm1_gc->lock, flags); - - return 0; -} - -int cpm1_gpiochip_add32(struct device *dev) -{ - struct device_node *np = dev->of_node; - struct cpm1_gpio32_chip *cpm1_gc; - struct of_mm_gpio_chip *mm_gc; - struct gpio_chip *gc; - - cpm1_gc = kzalloc(sizeof(*cpm1_gc), GFP_KERNEL); - if (!cpm1_gc) - return -ENOMEM; - - spin_lock_init(&cpm1_gc->lock); - - mm_gc = &cpm1_gc->mm_gc; - gc = &mm_gc->gc; - - mm_gc->save_regs = cpm1_gpio32_save_regs; - gc->ngpio = 32; - gc->direction_input = cpm1_gpio32_dir_in; - gc->direction_output = cpm1_gpio32_dir_out; - gc->get = cpm1_gpio32_get; - gc->set = cpm1_gpio32_set; - gc->parent = dev; - gc->owner = THIS_MODULE; - - return of_mm_gpiochip_add_data(np, mm_gc, cpm1_gc); -} - -#endif /* CONFIG_8xx_GPIO */ diff --git a/arch/powerpc/sysdev/micropatch.c b/arch/powerpc/sysdev/micropatch.c deleted file mode 100644 index 33a9042fca80..000000000000 --- a/arch/powerpc/sysdev/micropatch.c +++ /dev/null @@ -1,749 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0 - -/* Microcode patches for the CPM as supplied by Motorola. - * This is the one for IIC/SPI. There is a newer one that - * also relocates SMC2, but this would require additional changes - * to uart.c, so I am holding off on that for a moment. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * I2C/SPI relocation patch arrays. - */ - -#ifdef CONFIG_I2C_SPI_UCODE_PATCH - -static uint patch_2000[] __initdata = { - 0x7FFFEFD9, - 0x3FFD0000, - 0x7FFB49F7, - 0x7FF90000, - 0x5FEFADF7, - 0x5F89ADF7, - 0x5FEFAFF7, - 0x5F89AFF7, - 0x3A9CFBC8, - 0xE7C0EDF0, - 0x77C1E1BB, - 0xF4DC7F1D, - 0xABAD932F, - 0x4E08FDCF, - 0x6E0FAFF8, - 0x7CCF76CF, - 0xFD1FF9CF, - 0xABF88DC6, - 0xAB5679F7, - 0xB0937383, - 0xDFCE79F7, - 0xB091E6BB, - 0xE5BBE74F, - 0xB3FA6F0F, - 0x6FFB76CE, - 0xEE0DF9CF, - 0x2BFBEFEF, - 0xCFEEF9CF, - 0x76CEAD24, - 0x90B2DF9A, - 0x7FDDD0BF, - 0x4BF847FD, - 0x7CCF76CE, - 0xCFEF7E1F, - 0x7F1D7DFD, - 0xF0B6EF71, - 0x7FC177C1, - 0xFBC86079, - 0xE722FBC8, - 0x5FFFDFFF, - 0x5FB2FFFB, - 0xFBC8F3C8, - 0x94A67F01, - 0x7F1D5F39, - 0xAFE85F5E, - 0xFFDFDF96, - 0xCB9FAF7D, - 0x5FC1AFED, - 0x8C1C5FC1, - 0xAFDD5FC3, - 0xDF9A7EFD, - 0xB0B25FB2, - 0xFFFEABAD, - 0x5FB2FFFE, - 0x5FCE600B, - 0xE6BB600B, - 0x5FCEDFC6, - 0x27FBEFDF, - 0x5FC8CFDE, - 0x3A9CE7C0, - 0xEDF0F3C8, - 0x7F0154CD, - 0x7F1D2D3D, - 0x363A7570, - 0x7E0AF1CE, - 0x37EF2E68, - 0x7FEE10EC, - 0xADF8EFDE, - 0xCFEAE52F, - 0x7D0FE12B, - 0xF1CE5F65, - 0x7E0A4DF8, - 0xCFEA5F72, - 0x7D0BEFEE, - 0xCFEA5F74, - 0xE522EFDE, - 0x5F74CFDA, - 0x0B627385, - 0xDF627E0A, - 0x30D8145B, - 0xBFFFF3C8, - 0x5FFFDFFF, - 0xA7F85F5E, - 0xBFFE7F7D, - 0x10D31450, - 0x5F36BFFF, - 0xAF785F5E, - 0xBFFDA7F8, - 0x5F36BFFE, - 0x77FD30C0, - 0x4E08FDCF, - 0xE5FF6E0F, - 0xAFF87E1F, - 0x7E0FFD1F, - 0xF1CF5F1B, - 0xABF80D5E, - 0x5F5EFFEF, - 0x79F730A2, - 0xAFDD5F34, - 0x47F85F34, - 0xAFED7FDD, - 0x50B24978, - 0x47FD7F1D, - 0x7DFD70AD, - 0xEF717EC1, - 0x6BA47F01, - 0x2D267EFD, - 0x30DE5F5E, - 0xFFFD5F5E, - 0xFFEF5F5E, - 0xFFDF0CA0, - 0xAFED0A9E, - 0xAFDD0C3A, - 0x5F3AAFBD, - 0x7FBDB082, - 0x5F8247F8 -}; - -static uint patch_2f00[] __initdata = { - 0x3E303430, - 0x34343737, - 0xABF7BF9B, - 0x994B4FBD, - 0xBD599493, - 0x349FFF37, - 0xFB9B177D, - 0xD9936956, - 0xBBFDD697, - 0xBDD2FD11, - 0x31DB9BB3, - 0x63139637, - 0x93733693, - 0x193137F7, - 0x331737AF, - 0x7BB9B999, - 0xBB197957, - 0x7FDFD3D5, - 0x73B773F7, - 0x37933B99, - 0x1D115316, - 0x99315315, - 0x31694BF4, - 0xFBDBD359, - 0x31497353, - 0x76956D69, - 0x7B9D9693, - 0x13131979, - 0x79376935 -}; -#endif - -/* - * I2C/SPI/SMC1 relocation patch arrays. - */ - -#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH - -static uint patch_2000[] __initdata = { - 0x3fff0000, - 0x3ffd0000, - 0x3ffb0000, - 0x3ff90000, - 0x5f13eff8, - 0x5eb5eff8, - 0x5f88adf7, - 0x5fefadf7, - 0x3a9cfbc8, - 0x77cae1bb, - 0xf4de7fad, - 0xabae9330, - 0x4e08fdcf, - 0x6e0faff8, - 0x7ccf76cf, - 0xfdaff9cf, - 0xabf88dc8, - 0xab5879f7, - 0xb0925d8d, - 0xdfd079f7, - 0xb090e6bb, - 0xe5bbe74f, - 0x9e046f0f, - 0x6ffb76ce, - 0xee0cf9cf, - 0x2bfbefef, - 0xcfeef9cf, - 0x76cead23, - 0x90b3df99, - 0x7fddd0c1, - 0x4bf847fd, - 0x7ccf76ce, - 0xcfef77ca, - 0x7eaf7fad, - 0x7dfdf0b7, - 0xef7a7fca, - 0x77cafbc8, - 0x6079e722, - 0xfbc85fff, - 0xdfff5fb3, - 0xfffbfbc8, - 0xf3c894a5, - 0xe7c9edf9, - 0x7f9a7fad, - 0x5f36afe8, - 0x5f5bffdf, - 0xdf95cb9e, - 0xaf7d5fc3, - 0xafed8c1b, - 0x5fc3afdd, - 0x5fc5df99, - 0x7efdb0b3, - 0x5fb3fffe, - 0xabae5fb3, - 0xfffe5fd0, - 0x600be6bb, - 0x600b5fd0, - 0xdfc827fb, - 0xefdf5fca, - 0xcfde3a9c, - 0xe7c9edf9, - 0xf3c87f9e, - 0x54ca7fed, - 0x2d3a3637, - 0x756f7e9a, - 0xf1ce37ef, - 0x2e677fee, - 0x10ebadf8, - 0xefdecfea, - 0xe52f7d9f, - 0xe12bf1ce, - 0x5f647e9a, - 0x4df8cfea, - 0x5f717d9b, - 0xefeecfea, - 0x5f73e522, - 0xefde5f73, - 0xcfda0b61, - 0x5d8fdf61, - 0xe7c9edf9, - 0x7e9a30d5, - 0x1458bfff, - 0xf3c85fff, - 0xdfffa7f8, - 0x5f5bbffe, - 0x7f7d10d0, - 0x144d5f33, - 0xbfffaf78, - 0x5f5bbffd, - 0xa7f85f33, - 0xbffe77fd, - 0x30bd4e08, - 0xfdcfe5ff, - 0x6e0faff8, - 0x7eef7e9f, - 0xfdeff1cf, - 0x5f17abf8, - 0x0d5b5f5b, - 0xffef79f7, - 0x309eafdd, - 0x5f3147f8, - 0x5f31afed, - 0x7fdd50af, - 0x497847fd, - 0x7f9e7fed, - 0x7dfd70a9, - 0xef7e7ece, - 0x6ba07f9e, - 0x2d227efd, - 0x30db5f5b, - 0xfffd5f5b, - 0xffef5f5b, - 0xffdf0c9c, - 0xafed0a9a, - 0xafdd0c37, - 0x5f37afbd, - 0x7fbdb081, - 0x5f8147f8, - 0x3a11e710, - 0xedf0ccdd, - 0xf3186d0a, - 0x7f0e5f06, - 0x7fedbb38, - 0x3afe7468, - 0x7fedf4fc, - 0x8ffbb951, - 0xb85f77fd, - 0xb0df5ddd, - 0xdefe7fed, - 0x90e1e74d, - 0x6f0dcbf7, - 0xe7decfed, - 0xcb74cfed, - 0xcfeddf6d, - 0x91714f74, - 0x5dd2deef, - 0x9e04e7df, - 0xefbb6ffb, - 0xe7ef7f0e, - 0x9e097fed, - 0xebdbeffa, - 0xeb54affb, - 0x7fea90d7, - 0x7e0cf0c3, - 0xbffff318, - 0x5fffdfff, - 0xac59efea, - 0x7fce1ee5, - 0xe2ff5ee1, - 0xaffbe2ff, - 0x5ee3affb, - 0xf9cc7d0f, - 0xaef8770f, - 0x7d0fb0c6, - 0xeffbbfff, - 0xcfef5ede, - 0x7d0fbfff, - 0x5ede4cf8, - 0x7fddd0bf, - 0x49f847fd, - 0x7efdf0bb, - 0x7fedfffd, - 0x7dfdf0b7, - 0xef7e7e1e, - 0x5ede7f0e, - 0x3a11e710, - 0xedf0ccab, - 0xfb18ad2e, - 0x1ea9bbb8, - 0x74283b7e, - 0x73c2e4bb, - 0x2ada4fb8, - 0xdc21e4bb, - 0xb2a1ffbf, - 0x5e2c43f8, - 0xfc87e1bb, - 0xe74ffd91, - 0x6f0f4fe8, - 0xc7ba32e2, - 0xf396efeb, - 0x600b4f78, - 0xe5bb760b, - 0x53acaef8, - 0x4ef88b0e, - 0xcfef9e09, - 0xabf8751f, - 0xefef5bac, - 0x741f4fe8, - 0x751e760d, - 0x7fdbf081, - 0x741cafce, - 0xefcc7fce, - 0x751e70ac, - 0x741ce7bb, - 0x3372cfed, - 0xafdbefeb, - 0xe5bb760b, - 0x53f2aef8, - 0xafe8e7eb, - 0x4bf8771e, - 0x7e247fed, - 0x4fcbe2cc, - 0x7fbc30a9, - 0x7b0f7a0f, - 0x34d577fd, - 0x308b5db7, - 0xde553e5f, - 0xaf78741f, - 0x741f30f0, - 0xcfef5e2c, - 0x741f3eac, - 0xafb8771e, - 0x5e677fed, - 0x0bd3e2cc, - 0x741ccfec, - 0xe5ca53cd, - 0x6fcb4f74, - 0x5dadde4b, - 0x2ab63d38, - 0x4bb3de30, - 0x751f741c, - 0x6c42effa, - 0xefea7fce, - 0x6ffc30be, - 0xefec3fca, - 0x30b3de2e, - 0xadf85d9e, - 0xaf7daefd, - 0x5d9ede2e, - 0x5d9eafdd, - 0x761f10ac, - 0x1da07efd, - 0x30adfffe, - 0x4908fb18, - 0x5fffdfff, - 0xafbb709b, - 0x4ef85e67, - 0xadf814ad, - 0x7a0f70ad, - 0xcfef50ad, - 0x7a0fde30, - 0x5da0afed, - 0x3c12780f, - 0xefef780f, - 0xefef790f, - 0xa7f85e0f, - 0xffef790f, - 0xefef790f, - 0x14adde2e, - 0x5d9eadfd, - 0x5e2dfffb, - 0xe79addfd, - 0xeff96079, - 0x607ae79a, - 0xddfceff9, - 0x60795dff, - 0x607acfef, - 0xefefefdf, - 0xefbfef7f, - 0xeeffedff, - 0xebffe7ff, - 0xafefafdf, - 0xafbfaf7f, - 0xaeffadff, - 0xabffa7ff, - 0x6fef6fdf, - 0x6fbf6f7f, - 0x6eff6dff, - 0x6bff67ff, - 0x2fef2fdf, - 0x2fbf2f7f, - 0x2eff2dff, - 0x2bff27ff, - 0x4e08fd1f, - 0xe5ff6e0f, - 0xaff87eef, - 0x7e0ffdef, - 0xf11f6079, - 0xabf8f542, - 0x7e0af11c, - 0x37cfae3a, - 0x7fec90be, - 0xadf8efdc, - 0xcfeae52f, - 0x7d0fe12b, - 0xf11c6079, - 0x7e0a4df8, - 0xcfea5dc4, - 0x7d0befec, - 0xcfea5dc6, - 0xe522efdc, - 0x5dc6cfda, - 0x4e08fd1f, - 0x6e0faff8, - 0x7c1f761f, - 0xfdeff91f, - 0x6079abf8, - 0x761cee24, - 0xf91f2bfb, - 0xefefcfec, - 0xf91f6079, - 0x761c27fb, - 0xefdf5da7, - 0xcfdc7fdd, - 0xd09c4bf8, - 0x47fd7c1f, - 0x761ccfcf, - 0x7eef7fed, - 0x7dfdf093, - 0xef7e7f1e, - 0x771efb18, - 0x6079e722, - 0xe6bbe5bb, - 0xae0ae5bb, - 0x600bae85, - 0xe2bbe2bb, - 0xe2bbe2bb, - 0xaf02e2bb, - 0xe2bb2ff9, - 0x6079e2bb -}; - -static uint patch_2f00[] __initdata = { - 0x30303030, - 0x3e3e3434, - 0xabbf9b99, - 0x4b4fbdbd, - 0x59949334, - 0x9fff37fb, - 0x9b177dd9, - 0x936956bb, - 0xfbdd697b, - 0xdd2fd113, - 0x1db9f7bb, - 0x36313963, - 0x79373369, - 0x3193137f, - 0x7331737a, - 0xf7bb9b99, - 0x9bb19795, - 0x77fdfd3d, - 0x573b773f, - 0x737933f7, - 0xb991d115, - 0x31699315, - 0x31531694, - 0xbf4fbdbd, - 0x35931497, - 0x35376956, - 0xbd697b9d, - 0x96931313, - 0x19797937, - 0x6935af78, - 0xb9b3baa3, - 0xb8788683, - 0x368f78f7, - 0x87778733, - 0x3ffffb3b, - 0x8e8f78b8, - 0x1d118e13, - 0xf3ff3f8b, - 0x6bd8e173, - 0xd1366856, - 0x68d1687b, - 0x3daf78b8, - 0x3a3a3f87, - 0x8f81378f, - 0xf876f887, - 0x77fd8778, - 0x737de8d6, - 0xbbf8bfff, - 0xd8df87f7, - 0xfd876f7b, - 0x8bfff8bd, - 0x8683387d, - 0xb873d87b, - 0x3b8fd7f8, - 0xf7338883, - 0xbb8ee1f8, - 0xef837377, - 0x3337b836, - 0x817d11f8, - 0x7378b878, - 0xd3368b7d, - 0xed731b7d, - 0x833731f3, - 0xf22f3f23 -}; - -static uint patch_2e00[] __initdata = { - 0x27eeeeee, - 0xeeeeeeee, - 0xeeeeeeee, - 0xeeeeeeee, - 0xee4bf4fb, - 0xdbd259bb, - 0x1979577f, - 0xdfd2d573, - 0xb773f737, - 0x4b4fbdbd, - 0x25b9b177, - 0xd2d17376, - 0x956bbfdd, - 0x697bdd2f, - 0xff9f79ff, - 0xff9ff22f -}; -#endif - -/* - * USB SOF patch arrays. - */ - -#ifdef CONFIG_USB_SOF_UCODE_PATCH - -static uint patch_2000[] __initdata = { - 0x7fff0000, - 0x7ffd0000, - 0x7ffb0000, - 0x49f7ba5b, - 0xba383ffb, - 0xf9b8b46d, - 0xe5ab4e07, - 0xaf77bffe, - 0x3f7bbf79, - 0xba5bba38, - 0xe7676076, - 0x60750000 -}; - -static uint patch_2f00[] __initdata = { - 0x3030304c, - 0xcab9e441, - 0xa1aaf220 -}; -#endif - -void __init cpm_load_patch(cpm8xx_t *cp) -{ - volatile uint *dp; /* Dual-ported RAM. */ - volatile cpm8xx_t *commproc; -#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ - defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - volatile iic_t *iip; - volatile struct spi_pram *spp; -#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH - volatile smc_uart_t *smp; -#endif -#endif - int i; - - commproc = cp; - -#ifdef CONFIG_USB_SOF_UCODE_PATCH - commproc->cp_rccr = 0; - - dp = (uint *)(commproc->cp_dpmem); - for (i=0; i<(sizeof(patch_2000)/4); i++) - *dp++ = patch_2000[i]; - - dp = (uint *)&(commproc->cp_dpmem[0x0f00]); - for (i=0; i<(sizeof(patch_2f00)/4); i++) - *dp++ = patch_2f00[i]; - - commproc->cp_rccr = 0x0009; - - printk("USB SOF microcode patch installed\n"); -#endif /* CONFIG_USB_SOF_UCODE_PATCH */ - -#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ - defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - - commproc->cp_rccr = 0; - - dp = (uint *)(commproc->cp_dpmem); - for (i=0; i<(sizeof(patch_2000)/4); i++) - *dp++ = patch_2000[i]; - - dp = (uint *)&(commproc->cp_dpmem[0x0f00]); - for (i=0; i<(sizeof(patch_2f00)/4); i++) - *dp++ = patch_2f00[i]; - - iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC]; -# define RPBASE 0x0500 - iip->iic_rpbase = RPBASE; - - /* Put SPI above the IIC, also 32-byte aligned. - */ - i = (RPBASE + sizeof(iic_t) + 31) & ~31; - spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI]; - spp->rpbase = i; - -# if defined(CONFIG_I2C_SPI_UCODE_PATCH) - commproc->cp_cpmcr1 = 0x802a; - commproc->cp_cpmcr2 = 0x8028; - commproc->cp_cpmcr3 = 0x802e; - commproc->cp_cpmcr4 = 0x802c; - commproc->cp_rccr = 1; - - printk("I2C/SPI microcode patch installed.\n"); -# endif /* CONFIG_I2C_SPI_UCODE_PATCH */ - -# if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - - dp = (uint *)&(commproc->cp_dpmem[0x0e00]); - for (i=0; i<(sizeof(patch_2e00)/4); i++) - *dp++ = patch_2e00[i]; - - commproc->cp_cpmcr1 = 0x8080; - commproc->cp_cpmcr2 = 0x808a; - commproc->cp_cpmcr3 = 0x8028; - commproc->cp_cpmcr4 = 0x802a; - commproc->cp_rccr = 3; - - smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1]; - smp->smc_rpbase = 0x1FC0; - - printk("I2C/SPI/SMC1 microcode patch installed.\n"); -# endif /* CONFIG_I2C_SPI_SMC1_UCODE_PATCH) */ - -#endif /* some variation of the I2C/SPI patch was selected */ -} - -/* - * Take this entire routine out, since no one calls it and its - * logic is suspect. - */ - -#if 0 -void -verify_patch(volatile immap_t *immr) -{ - volatile uint *dp; - volatile cpm8xx_t *commproc; - int i; - - commproc = (cpm8xx_t *)&immr->im_cpm; - - printk("cp_rccr %x\n", commproc->cp_rccr); - commproc->cp_rccr = 0; - - dp = (uint *)(commproc->cp_dpmem); - for (i=0; i<(sizeof(patch_2000)/4); i++) - if (*dp++ != patch_2000[i]) { - printk("patch_2000 bad at %d\n", i); - dp--; - printk("found 0x%X, wanted 0x%X\n", *dp, patch_2000[i]); - break; - } - - dp = (uint *)&(commproc->cp_dpmem[0x0f00]); - for (i=0; i<(sizeof(patch_2f00)/4); i++) - if (*dp++ != patch_2f00[i]) { - printk("patch_2f00 bad at %d\n", i); - dp--; - printk("found 0x%X, wanted 0x%X\n", *dp, patch_2f00[i]); - break; - } - - commproc->cp_rccr = 0x0009; -} -#endif -- cgit v1.2.3 From 4d6d9c6db51275cba0f447ee04218bdf03d41453 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:39 +0000 Subject: powerpc/8xx: drop verify_patch() verify_patch() has been opted out since many years, and the comment suggests it doesn't work. So drop it. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/micropatch.c | 40 --------------------------------- 1 file changed, 40 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index 83649a641dea..0a310ef58f09 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -708,43 +708,3 @@ void __init cpm_load_patch(cpm8xx_t *cp) #endif /* some variation of the I2C/SPI patch was selected */ } - -/* - * Take this entire routine out, since no one calls it and its - * logic is suspect. - */ - -#if 0 -void -verify_patch(volatile immap_t *immr) -{ - volatile uint *dp; - volatile cpm8xx_t *commproc; - int i; - - commproc = (cpm8xx_t *)&immr->im_cpm; - - printk("cp_rccr %x\n", commproc->cp_rccr); - commproc->cp_rccr = 0; - - dp = (uint *)(commproc->cp_dpmem); - for (i=0; i<(sizeof(patch_2000)/4); i++) - if (*dp++ != patch_2000[i]) { - printk("patch_2000 bad at %d\n", i); - dp--; - printk("found 0x%X, wanted 0x%X\n", *dp, patch_2000[i]); - break; - } - - dp = (uint *)&(commproc->cp_dpmem[0x0f00]); - for (i=0; i<(sizeof(patch_2f00)/4); i++) - if (*dp++ != patch_2f00[i]) { - printk("patch_2f00 bad at %d\n", i); - dp--; - printk("found 0x%X, wanted 0x%X\n", *dp, patch_2f00[i]); - break; - } - - commproc->cp_rccr = 0x0009; -} -#endif -- cgit v1.2.3 From 9fb7e639f6ad4a67296c897bf22110b0d38e42a4 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:40 +0000 Subject: powerpc/8xx: compact microcode arrays Compact obscure microcode arrays by putting 4 values per line in order to reduce number of lines in the file to increase readability. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/micropatch.c | 699 +++++++------------------------- 1 file changed, 140 insertions(+), 559 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index 0a310ef58f09..a080a7d569a5 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -28,153 +28,45 @@ #ifdef CONFIG_I2C_SPI_UCODE_PATCH static uint patch_2000[] __initdata = { - 0x7FFFEFD9, - 0x3FFD0000, - 0x7FFB49F7, - 0x7FF90000, - 0x5FEFADF7, - 0x5F89ADF7, - 0x5FEFAFF7, - 0x5F89AFF7, - 0x3A9CFBC8, - 0xE7C0EDF0, - 0x77C1E1BB, - 0xF4DC7F1D, - 0xABAD932F, - 0x4E08FDCF, - 0x6E0FAFF8, - 0x7CCF76CF, - 0xFD1FF9CF, - 0xABF88DC6, - 0xAB5679F7, - 0xB0937383, - 0xDFCE79F7, - 0xB091E6BB, - 0xE5BBE74F, - 0xB3FA6F0F, - 0x6FFB76CE, - 0xEE0DF9CF, - 0x2BFBEFEF, - 0xCFEEF9CF, - 0x76CEAD24, - 0x90B2DF9A, - 0x7FDDD0BF, - 0x4BF847FD, - 0x7CCF76CE, - 0xCFEF7E1F, - 0x7F1D7DFD, - 0xF0B6EF71, - 0x7FC177C1, - 0xFBC86079, - 0xE722FBC8, - 0x5FFFDFFF, - 0x5FB2FFFB, - 0xFBC8F3C8, - 0x94A67F01, - 0x7F1D5F39, - 0xAFE85F5E, - 0xFFDFDF96, - 0xCB9FAF7D, - 0x5FC1AFED, - 0x8C1C5FC1, - 0xAFDD5FC3, - 0xDF9A7EFD, - 0xB0B25FB2, - 0xFFFEABAD, - 0x5FB2FFFE, - 0x5FCE600B, - 0xE6BB600B, - 0x5FCEDFC6, - 0x27FBEFDF, - 0x5FC8CFDE, - 0x3A9CE7C0, - 0xEDF0F3C8, - 0x7F0154CD, - 0x7F1D2D3D, - 0x363A7570, - 0x7E0AF1CE, - 0x37EF2E68, - 0x7FEE10EC, - 0xADF8EFDE, - 0xCFEAE52F, - 0x7D0FE12B, - 0xF1CE5F65, - 0x7E0A4DF8, - 0xCFEA5F72, - 0x7D0BEFEE, - 0xCFEA5F74, - 0xE522EFDE, - 0x5F74CFDA, - 0x0B627385, - 0xDF627E0A, - 0x30D8145B, - 0xBFFFF3C8, - 0x5FFFDFFF, - 0xA7F85F5E, - 0xBFFE7F7D, - 0x10D31450, - 0x5F36BFFF, - 0xAF785F5E, - 0xBFFDA7F8, - 0x5F36BFFE, - 0x77FD30C0, - 0x4E08FDCF, - 0xE5FF6E0F, - 0xAFF87E1F, - 0x7E0FFD1F, - 0xF1CF5F1B, - 0xABF80D5E, - 0x5F5EFFEF, - 0x79F730A2, - 0xAFDD5F34, - 0x47F85F34, - 0xAFED7FDD, - 0x50B24978, - 0x47FD7F1D, - 0x7DFD70AD, - 0xEF717EC1, - 0x6BA47F01, - 0x2D267EFD, - 0x30DE5F5E, - 0xFFFD5F5E, - 0xFFEF5F5E, - 0xFFDF0CA0, - 0xAFED0A9E, - 0xAFDD0C3A, - 0x5F3AAFBD, - 0x7FBDB082, - 0x5F8247F8 + 0x7FFFEFD9, 0x3FFD0000, 0x7FFB49F7, 0x7FF90000, + 0x5FEFADF7, 0x5F89ADF7, 0x5FEFAFF7, 0x5F89AFF7, + 0x3A9CFBC8, 0xE7C0EDF0, 0x77C1E1BB, 0xF4DC7F1D, + 0xABAD932F, 0x4E08FDCF, 0x6E0FAFF8, 0x7CCF76CF, + 0xFD1FF9CF, 0xABF88DC6, 0xAB5679F7, 0xB0937383, + 0xDFCE79F7, 0xB091E6BB, 0xE5BBE74F, 0xB3FA6F0F, + 0x6FFB76CE, 0xEE0DF9CF, 0x2BFBEFEF, 0xCFEEF9CF, + 0x76CEAD24, 0x90B2DF9A, 0x7FDDD0BF, 0x4BF847FD, + 0x7CCF76CE, 0xCFEF7E1F, 0x7F1D7DFD, 0xF0B6EF71, + 0x7FC177C1, 0xFBC86079, 0xE722FBC8, 0x5FFFDFFF, + 0x5FB2FFFB, 0xFBC8F3C8, 0x94A67F01, 0x7F1D5F39, + 0xAFE85F5E, 0xFFDFDF96, 0xCB9FAF7D, 0x5FC1AFED, + 0x8C1C5FC1, 0xAFDD5FC3, 0xDF9A7EFD, 0xB0B25FB2, + 0xFFFEABAD, 0x5FB2FFFE, 0x5FCE600B, 0xE6BB600B, + 0x5FCEDFC6, 0x27FBEFDF, 0x5FC8CFDE, 0x3A9CE7C0, + 0xEDF0F3C8, 0x7F0154CD, 0x7F1D2D3D, 0x363A7570, + 0x7E0AF1CE, 0x37EF2E68, 0x7FEE10EC, 0xADF8EFDE, + 0xCFEAE52F, 0x7D0FE12B, 0xF1CE5F65, 0x7E0A4DF8, + 0xCFEA5F72, 0x7D0BEFEE, 0xCFEA5F74, 0xE522EFDE, + 0x5F74CFDA, 0x0B627385, 0xDF627E0A, 0x30D8145B, + 0xBFFFF3C8, 0x5FFFDFFF, 0xA7F85F5E, 0xBFFE7F7D, + 0x10D31450, 0x5F36BFFF, 0xAF785F5E, 0xBFFDA7F8, + 0x5F36BFFE, 0x77FD30C0, 0x4E08FDCF, 0xE5FF6E0F, + 0xAFF87E1F, 0x7E0FFD1F, 0xF1CF5F1B, 0xABF80D5E, + 0x5F5EFFEF, 0x79F730A2, 0xAFDD5F34, 0x47F85F34, + 0xAFED7FDD, 0x50B24978, 0x47FD7F1D, 0x7DFD70AD, + 0xEF717EC1, 0x6BA47F01, 0x2D267EFD, 0x30DE5F5E, + 0xFFFD5F5E, 0xFFEF5F5E, 0xFFDF0CA0, 0xAFED0A9E, + 0xAFDD0C3A, 0x5F3AAFBD, 0x7FBDB082, 0x5F8247F8 }; static uint patch_2f00[] __initdata = { - 0x3E303430, - 0x34343737, - 0xABF7BF9B, - 0x994B4FBD, - 0xBD599493, - 0x349FFF37, - 0xFB9B177D, - 0xD9936956, - 0xBBFDD697, - 0xBDD2FD11, - 0x31DB9BB3, - 0x63139637, - 0x93733693, - 0x193137F7, - 0x331737AF, - 0x7BB9B999, - 0xBB197957, - 0x7FDFD3D5, - 0x73B773F7, - 0x37933B99, - 0x1D115316, - 0x99315315, - 0x31694BF4, - 0xFBDBD359, - 0x31497353, - 0x76956D69, - 0x7B9D9693, - 0x13131979, + 0x3E303430, 0x34343737, 0xABF7BF9B, 0x994B4FBD, + 0xBD599493, 0x349FFF37, 0xFB9B177D, 0xD9936956, + 0xBBFDD697, 0xBDD2FD11, 0x31DB9BB3, 0x63139637, + 0x93733693, 0x193137F7, 0x331737AF, 0x7BB9B999, + 0xBB197957, 0x7FDFD3D5, 0x73B773F7, 0x37933B99, + 0x1D115316, 0x99315315, 0x31694BF4, 0xFBDBD359, + 0x31497353, 0x76956D69, 0x7B9D9693, 0x13131979, 0x79376935 }; #endif @@ -186,412 +78,112 @@ static uint patch_2f00[] __initdata = { #ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH static uint patch_2000[] __initdata = { - 0x3fff0000, - 0x3ffd0000, - 0x3ffb0000, - 0x3ff90000, - 0x5f13eff8, - 0x5eb5eff8, - 0x5f88adf7, - 0x5fefadf7, - 0x3a9cfbc8, - 0x77cae1bb, - 0xf4de7fad, - 0xabae9330, - 0x4e08fdcf, - 0x6e0faff8, - 0x7ccf76cf, - 0xfdaff9cf, - 0xabf88dc8, - 0xab5879f7, - 0xb0925d8d, - 0xdfd079f7, - 0xb090e6bb, - 0xe5bbe74f, - 0x9e046f0f, - 0x6ffb76ce, - 0xee0cf9cf, - 0x2bfbefef, - 0xcfeef9cf, - 0x76cead23, - 0x90b3df99, - 0x7fddd0c1, - 0x4bf847fd, - 0x7ccf76ce, - 0xcfef77ca, - 0x7eaf7fad, - 0x7dfdf0b7, - 0xef7a7fca, - 0x77cafbc8, - 0x6079e722, - 0xfbc85fff, - 0xdfff5fb3, - 0xfffbfbc8, - 0xf3c894a5, - 0xe7c9edf9, - 0x7f9a7fad, - 0x5f36afe8, - 0x5f5bffdf, - 0xdf95cb9e, - 0xaf7d5fc3, - 0xafed8c1b, - 0x5fc3afdd, - 0x5fc5df99, - 0x7efdb0b3, - 0x5fb3fffe, - 0xabae5fb3, - 0xfffe5fd0, - 0x600be6bb, - 0x600b5fd0, - 0xdfc827fb, - 0xefdf5fca, - 0xcfde3a9c, - 0xe7c9edf9, - 0xf3c87f9e, - 0x54ca7fed, - 0x2d3a3637, - 0x756f7e9a, - 0xf1ce37ef, - 0x2e677fee, - 0x10ebadf8, - 0xefdecfea, - 0xe52f7d9f, - 0xe12bf1ce, - 0x5f647e9a, - 0x4df8cfea, - 0x5f717d9b, - 0xefeecfea, - 0x5f73e522, - 0xefde5f73, - 0xcfda0b61, - 0x5d8fdf61, - 0xe7c9edf9, - 0x7e9a30d5, - 0x1458bfff, - 0xf3c85fff, - 0xdfffa7f8, - 0x5f5bbffe, - 0x7f7d10d0, - 0x144d5f33, - 0xbfffaf78, - 0x5f5bbffd, - 0xa7f85f33, - 0xbffe77fd, - 0x30bd4e08, - 0xfdcfe5ff, - 0x6e0faff8, - 0x7eef7e9f, - 0xfdeff1cf, - 0x5f17abf8, - 0x0d5b5f5b, - 0xffef79f7, - 0x309eafdd, - 0x5f3147f8, - 0x5f31afed, - 0x7fdd50af, - 0x497847fd, - 0x7f9e7fed, - 0x7dfd70a9, - 0xef7e7ece, - 0x6ba07f9e, - 0x2d227efd, - 0x30db5f5b, - 0xfffd5f5b, - 0xffef5f5b, - 0xffdf0c9c, - 0xafed0a9a, - 0xafdd0c37, - 0x5f37afbd, - 0x7fbdb081, - 0x5f8147f8, - 0x3a11e710, - 0xedf0ccdd, - 0xf3186d0a, - 0x7f0e5f06, - 0x7fedbb38, - 0x3afe7468, - 0x7fedf4fc, - 0x8ffbb951, - 0xb85f77fd, - 0xb0df5ddd, - 0xdefe7fed, - 0x90e1e74d, - 0x6f0dcbf7, - 0xe7decfed, - 0xcb74cfed, - 0xcfeddf6d, - 0x91714f74, - 0x5dd2deef, - 0x9e04e7df, - 0xefbb6ffb, - 0xe7ef7f0e, - 0x9e097fed, - 0xebdbeffa, - 0xeb54affb, - 0x7fea90d7, - 0x7e0cf0c3, - 0xbffff318, - 0x5fffdfff, - 0xac59efea, - 0x7fce1ee5, - 0xe2ff5ee1, - 0xaffbe2ff, - 0x5ee3affb, - 0xf9cc7d0f, - 0xaef8770f, - 0x7d0fb0c6, - 0xeffbbfff, - 0xcfef5ede, - 0x7d0fbfff, - 0x5ede4cf8, - 0x7fddd0bf, - 0x49f847fd, - 0x7efdf0bb, - 0x7fedfffd, - 0x7dfdf0b7, - 0xef7e7e1e, - 0x5ede7f0e, - 0x3a11e710, - 0xedf0ccab, - 0xfb18ad2e, - 0x1ea9bbb8, - 0x74283b7e, - 0x73c2e4bb, - 0x2ada4fb8, - 0xdc21e4bb, - 0xb2a1ffbf, - 0x5e2c43f8, - 0xfc87e1bb, - 0xe74ffd91, - 0x6f0f4fe8, - 0xc7ba32e2, - 0xf396efeb, - 0x600b4f78, - 0xe5bb760b, - 0x53acaef8, - 0x4ef88b0e, - 0xcfef9e09, - 0xabf8751f, - 0xefef5bac, - 0x741f4fe8, - 0x751e760d, - 0x7fdbf081, - 0x741cafce, - 0xefcc7fce, - 0x751e70ac, - 0x741ce7bb, - 0x3372cfed, - 0xafdbefeb, - 0xe5bb760b, - 0x53f2aef8, - 0xafe8e7eb, - 0x4bf8771e, - 0x7e247fed, - 0x4fcbe2cc, - 0x7fbc30a9, - 0x7b0f7a0f, - 0x34d577fd, - 0x308b5db7, - 0xde553e5f, - 0xaf78741f, - 0x741f30f0, - 0xcfef5e2c, - 0x741f3eac, - 0xafb8771e, - 0x5e677fed, - 0x0bd3e2cc, - 0x741ccfec, - 0xe5ca53cd, - 0x6fcb4f74, - 0x5dadde4b, - 0x2ab63d38, - 0x4bb3de30, - 0x751f741c, - 0x6c42effa, - 0xefea7fce, - 0x6ffc30be, - 0xefec3fca, - 0x30b3de2e, - 0xadf85d9e, - 0xaf7daefd, - 0x5d9ede2e, - 0x5d9eafdd, - 0x761f10ac, - 0x1da07efd, - 0x30adfffe, - 0x4908fb18, - 0x5fffdfff, - 0xafbb709b, - 0x4ef85e67, - 0xadf814ad, - 0x7a0f70ad, - 0xcfef50ad, - 0x7a0fde30, - 0x5da0afed, - 0x3c12780f, - 0xefef780f, - 0xefef790f, - 0xa7f85e0f, - 0xffef790f, - 0xefef790f, - 0x14adde2e, - 0x5d9eadfd, - 0x5e2dfffb, - 0xe79addfd, - 0xeff96079, - 0x607ae79a, - 0xddfceff9, - 0x60795dff, - 0x607acfef, - 0xefefefdf, - 0xefbfef7f, - 0xeeffedff, - 0xebffe7ff, - 0xafefafdf, - 0xafbfaf7f, - 0xaeffadff, - 0xabffa7ff, - 0x6fef6fdf, - 0x6fbf6f7f, - 0x6eff6dff, - 0x6bff67ff, - 0x2fef2fdf, - 0x2fbf2f7f, - 0x2eff2dff, - 0x2bff27ff, - 0x4e08fd1f, - 0xe5ff6e0f, - 0xaff87eef, - 0x7e0ffdef, - 0xf11f6079, - 0xabf8f542, - 0x7e0af11c, - 0x37cfae3a, - 0x7fec90be, - 0xadf8efdc, - 0xcfeae52f, - 0x7d0fe12b, - 0xf11c6079, - 0x7e0a4df8, - 0xcfea5dc4, - 0x7d0befec, - 0xcfea5dc6, - 0xe522efdc, - 0x5dc6cfda, - 0x4e08fd1f, - 0x6e0faff8, - 0x7c1f761f, - 0xfdeff91f, - 0x6079abf8, - 0x761cee24, - 0xf91f2bfb, - 0xefefcfec, - 0xf91f6079, - 0x761c27fb, - 0xefdf5da7, - 0xcfdc7fdd, - 0xd09c4bf8, - 0x47fd7c1f, - 0x761ccfcf, - 0x7eef7fed, - 0x7dfdf093, - 0xef7e7f1e, - 0x771efb18, - 0x6079e722, - 0xe6bbe5bb, - 0xae0ae5bb, - 0x600bae85, - 0xe2bbe2bb, - 0xe2bbe2bb, - 0xaf02e2bb, - 0xe2bb2ff9, - 0x6079e2bb + 0x3fff0000, 0x3ffd0000, 0x3ffb0000, 0x3ff90000, + 0x5f13eff8, 0x5eb5eff8, 0x5f88adf7, 0x5fefadf7, + 0x3a9cfbc8, 0x77cae1bb, 0xf4de7fad, 0xabae9330, + 0x4e08fdcf, 0x6e0faff8, 0x7ccf76cf, 0xfdaff9cf, + 0xabf88dc8, 0xab5879f7, 0xb0925d8d, 0xdfd079f7, + 0xb090e6bb, 0xe5bbe74f, 0x9e046f0f, 0x6ffb76ce, + 0xee0cf9cf, 0x2bfbefef, 0xcfeef9cf, 0x76cead23, + 0x90b3df99, 0x7fddd0c1, 0x4bf847fd, 0x7ccf76ce, + 0xcfef77ca, 0x7eaf7fad, 0x7dfdf0b7, 0xef7a7fca, + 0x77cafbc8, 0x6079e722, 0xfbc85fff, 0xdfff5fb3, + 0xfffbfbc8, 0xf3c894a5, 0xe7c9edf9, 0x7f9a7fad, + 0x5f36afe8, 0x5f5bffdf, 0xdf95cb9e, 0xaf7d5fc3, + 0xafed8c1b, 0x5fc3afdd, 0x5fc5df99, 0x7efdb0b3, + 0x5fb3fffe, 0xabae5fb3, 0xfffe5fd0, 0x600be6bb, + 0x600b5fd0, 0xdfc827fb, 0xefdf5fca, 0xcfde3a9c, + 0xe7c9edf9, 0xf3c87f9e, 0x54ca7fed, 0x2d3a3637, + 0x756f7e9a, 0xf1ce37ef, 0x2e677fee, 0x10ebadf8, + 0xefdecfea, 0xe52f7d9f, 0xe12bf1ce, 0x5f647e9a, + 0x4df8cfea, 0x5f717d9b, 0xefeecfea, 0x5f73e522, + 0xefde5f73, 0xcfda0b61, 0x5d8fdf61, 0xe7c9edf9, + 0x7e9a30d5, 0x1458bfff, 0xf3c85fff, 0xdfffa7f8, + 0x5f5bbffe, 0x7f7d10d0, 0x144d5f33, 0xbfffaf78, + 0x5f5bbffd, 0xa7f85f33, 0xbffe77fd, 0x30bd4e08, + 0xfdcfe5ff, 0x6e0faff8, 0x7eef7e9f, 0xfdeff1cf, + 0x5f17abf8, 0x0d5b5f5b, 0xffef79f7, 0x309eafdd, + 0x5f3147f8, 0x5f31afed, 0x7fdd50af, 0x497847fd, + 0x7f9e7fed, 0x7dfd70a9, 0xef7e7ece, 0x6ba07f9e, + 0x2d227efd, 0x30db5f5b, 0xfffd5f5b, 0xffef5f5b, + 0xffdf0c9c, 0xafed0a9a, 0xafdd0c37, 0x5f37afbd, + 0x7fbdb081, 0x5f8147f8, 0x3a11e710, 0xedf0ccdd, + 0xf3186d0a, 0x7f0e5f06, 0x7fedbb38, 0x3afe7468, + 0x7fedf4fc, 0x8ffbb951, 0xb85f77fd, 0xb0df5ddd, + 0xdefe7fed, 0x90e1e74d, 0x6f0dcbf7, 0xe7decfed, + 0xcb74cfed, 0xcfeddf6d, 0x91714f74, 0x5dd2deef, + 0x9e04e7df, 0xefbb6ffb, 0xe7ef7f0e, 0x9e097fed, + 0xebdbeffa, 0xeb54affb, 0x7fea90d7, 0x7e0cf0c3, + 0xbffff318, 0x5fffdfff, 0xac59efea, 0x7fce1ee5, + 0xe2ff5ee1, 0xaffbe2ff, 0x5ee3affb, 0xf9cc7d0f, + 0xaef8770f, 0x7d0fb0c6, 0xeffbbfff, 0xcfef5ede, + 0x7d0fbfff, 0x5ede4cf8, 0x7fddd0bf, 0x49f847fd, + 0x7efdf0bb, 0x7fedfffd, 0x7dfdf0b7, 0xef7e7e1e, + 0x5ede7f0e, 0x3a11e710, 0xedf0ccab, 0xfb18ad2e, + 0x1ea9bbb8, 0x74283b7e, 0x73c2e4bb, 0x2ada4fb8, + 0xdc21e4bb, 0xb2a1ffbf, 0x5e2c43f8, 0xfc87e1bb, + 0xe74ffd91, 0x6f0f4fe8, 0xc7ba32e2, 0xf396efeb, + 0x600b4f78, 0xe5bb760b, 0x53acaef8, 0x4ef88b0e, + 0xcfef9e09, 0xabf8751f, 0xefef5bac, 0x741f4fe8, + 0x751e760d, 0x7fdbf081, 0x741cafce, 0xefcc7fce, + 0x751e70ac, 0x741ce7bb, 0x3372cfed, 0xafdbefeb, + 0xe5bb760b, 0x53f2aef8, 0xafe8e7eb, 0x4bf8771e, + 0x7e247fed, 0x4fcbe2cc, 0x7fbc30a9, 0x7b0f7a0f, + 0x34d577fd, 0x308b5db7, 0xde553e5f, 0xaf78741f, + 0x741f30f0, 0xcfef5e2c, 0x741f3eac, 0xafb8771e, + 0x5e677fed, 0x0bd3e2cc, 0x741ccfec, 0xe5ca53cd, + 0x6fcb4f74, 0x5dadde4b, 0x2ab63d38, 0x4bb3de30, + 0x751f741c, 0x6c42effa, 0xefea7fce, 0x6ffc30be, + 0xefec3fca, 0x30b3de2e, 0xadf85d9e, 0xaf7daefd, + 0x5d9ede2e, 0x5d9eafdd, 0x761f10ac, 0x1da07efd, + 0x30adfffe, 0x4908fb18, 0x5fffdfff, 0xafbb709b, + 0x4ef85e67, 0xadf814ad, 0x7a0f70ad, 0xcfef50ad, + 0x7a0fde30, 0x5da0afed, 0x3c12780f, 0xefef780f, + 0xefef790f, 0xa7f85e0f, 0xffef790f, 0xefef790f, + 0x14adde2e, 0x5d9eadfd, 0x5e2dfffb, 0xe79addfd, + 0xeff96079, 0x607ae79a, 0xddfceff9, 0x60795dff, + 0x607acfef, 0xefefefdf, 0xefbfef7f, 0xeeffedff, + 0xebffe7ff, 0xafefafdf, 0xafbfaf7f, 0xaeffadff, + 0xabffa7ff, 0x6fef6fdf, 0x6fbf6f7f, 0x6eff6dff, + 0x6bff67ff, 0x2fef2fdf, 0x2fbf2f7f, 0x2eff2dff, + 0x2bff27ff, 0x4e08fd1f, 0xe5ff6e0f, 0xaff87eef, + 0x7e0ffdef, 0xf11f6079, 0xabf8f542, 0x7e0af11c, + 0x37cfae3a, 0x7fec90be, 0xadf8efdc, 0xcfeae52f, + 0x7d0fe12b, 0xf11c6079, 0x7e0a4df8, 0xcfea5dc4, + 0x7d0befec, 0xcfea5dc6, 0xe522efdc, 0x5dc6cfda, + 0x4e08fd1f, 0x6e0faff8, 0x7c1f761f, 0xfdeff91f, + 0x6079abf8, 0x761cee24, 0xf91f2bfb, 0xefefcfec, + 0xf91f6079, 0x761c27fb, 0xefdf5da7, 0xcfdc7fdd, + 0xd09c4bf8, 0x47fd7c1f, 0x761ccfcf, 0x7eef7fed, + 0x7dfdf093, 0xef7e7f1e, 0x771efb18, 0x6079e722, + 0xe6bbe5bb, 0xae0ae5bb, 0x600bae85, 0xe2bbe2bb, + 0xe2bbe2bb, 0xaf02e2bb, 0xe2bb2ff9, 0x6079e2bb }; static uint patch_2f00[] __initdata = { - 0x30303030, - 0x3e3e3434, - 0xabbf9b99, - 0x4b4fbdbd, - 0x59949334, - 0x9fff37fb, - 0x9b177dd9, - 0x936956bb, - 0xfbdd697b, - 0xdd2fd113, - 0x1db9f7bb, - 0x36313963, - 0x79373369, - 0x3193137f, - 0x7331737a, - 0xf7bb9b99, - 0x9bb19795, - 0x77fdfd3d, - 0x573b773f, - 0x737933f7, - 0xb991d115, - 0x31699315, - 0x31531694, - 0xbf4fbdbd, - 0x35931497, - 0x35376956, - 0xbd697b9d, - 0x96931313, - 0x19797937, - 0x6935af78, - 0xb9b3baa3, - 0xb8788683, - 0x368f78f7, - 0x87778733, - 0x3ffffb3b, - 0x8e8f78b8, - 0x1d118e13, - 0xf3ff3f8b, - 0x6bd8e173, - 0xd1366856, - 0x68d1687b, - 0x3daf78b8, - 0x3a3a3f87, - 0x8f81378f, - 0xf876f887, - 0x77fd8778, - 0x737de8d6, - 0xbbf8bfff, - 0xd8df87f7, - 0xfd876f7b, - 0x8bfff8bd, - 0x8683387d, - 0xb873d87b, - 0x3b8fd7f8, - 0xf7338883, - 0xbb8ee1f8, - 0xef837377, - 0x3337b836, - 0x817d11f8, - 0x7378b878, - 0xd3368b7d, - 0xed731b7d, - 0x833731f3, - 0xf22f3f23 + 0x30303030, 0x3e3e3434, 0xabbf9b99, 0x4b4fbdbd, + 0x59949334, 0x9fff37fb, 0x9b177dd9, 0x936956bb, + 0xfbdd697b, 0xdd2fd113, 0x1db9f7bb, 0x36313963, + 0x79373369, 0x3193137f, 0x7331737a, 0xf7bb9b99, + 0x9bb19795, 0x77fdfd3d, 0x573b773f, 0x737933f7, + 0xb991d115, 0x31699315, 0x31531694, 0xbf4fbdbd, + 0x35931497, 0x35376956, 0xbd697b9d, 0x96931313, + 0x19797937, 0x6935af78, 0xb9b3baa3, 0xb8788683, + 0x368f78f7, 0x87778733, 0x3ffffb3b, 0x8e8f78b8, + 0x1d118e13, 0xf3ff3f8b, 0x6bd8e173, 0xd1366856, + 0x68d1687b, 0x3daf78b8, 0x3a3a3f87, 0x8f81378f, + 0xf876f887, 0x77fd8778, 0x737de8d6, 0xbbf8bfff, + 0xd8df87f7, 0xfd876f7b, 0x8bfff8bd, 0x8683387d, + 0xb873d87b, 0x3b8fd7f8, 0xf7338883, 0xbb8ee1f8, + 0xef837377, 0x3337b836, 0x817d11f8, 0x7378b878, + 0xd3368b7d, 0xed731b7d, 0x833731f3, 0xf22f3f23 }; static uint patch_2e00[] __initdata = { - 0x27eeeeee, - 0xeeeeeeee, - 0xeeeeeeee, - 0xeeeeeeee, - 0xee4bf4fb, - 0xdbd259bb, - 0x1979577f, - 0xdfd2d573, - 0xb773f737, - 0x4b4fbdbd, - 0x25b9b177, - 0xd2d17376, - 0x956bbfdd, - 0x697bdd2f, - 0xff9f79ff, - 0xff9ff22f + 0x27eeeeee, 0xeeeeeeee, 0xeeeeeeee, 0xeeeeeeee, + 0xee4bf4fb, 0xdbd259bb, 0x1979577f, 0xdfd2d573, + 0xb773f737, 0x4b4fbdbd, 0x25b9b177, 0xd2d17376, + 0x956bbfdd, 0x697bdd2f, 0xff9f79ff, 0xff9ff22f }; #endif @@ -602,24 +194,13 @@ static uint patch_2e00[] __initdata = { #ifdef CONFIG_USB_SOF_UCODE_PATCH static uint patch_2000[] __initdata = { - 0x7fff0000, - 0x7ffd0000, - 0x7ffb0000, - 0x49f7ba5b, - 0xba383ffb, - 0xf9b8b46d, - 0xe5ab4e07, - 0xaf77bffe, - 0x3f7bbf79, - 0xba5bba38, - 0xe7676076, - 0x60750000 + 0x7fff0000, 0x7ffd0000, 0x7ffb0000, 0x49f7ba5b, + 0xba383ffb, 0xf9b8b46d, 0xe5ab4e07, 0xaf77bffe, + 0x3f7bbf79, 0xba5bba38, 0xe7676076, 0x60750000 }; static uint patch_2f00[] __initdata = { - 0x3030304c, - 0xcab9e441, - 0xa1aaf220 + 0x3030304c, 0xcab9e441, 0xa1aaf220 }; #endif -- cgit v1.2.3 From 372fba9c76af11f1c7d162d22cff94e46f467bfb Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:41 +0000 Subject: powerpc/8xx: refactor writing of CPM microcode arrays Create a function to refactor the writing of CPM microcode arrays. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/micropatch.c | 35 ++++++++++++--------------------- 1 file changed, 13 insertions(+), 22 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index a080a7d569a5..04ef0b48ab21 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -204,9 +204,15 @@ static uint patch_2f00[] __initdata = { }; #endif +static void __init cpm_write_patch(cpm8xx_t *cp, int offset, uint *patch, int len) +{ + if (!len) + return; + memcpy_toio(cp->cp_dpmem + offset, patch, len); +} + void __init cpm_load_patch(cpm8xx_t *cp) { - volatile uint *dp; /* Dual-ported RAM. */ volatile cpm8xx_t *commproc; #if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) @@ -216,20 +222,13 @@ void __init cpm_load_patch(cpm8xx_t *cp) volatile smc_uart_t *smp; #endif #endif - int i; - commproc = cp; #ifdef CONFIG_USB_SOF_UCODE_PATCH commproc->cp_rccr = 0; - dp = (uint *)(commproc->cp_dpmem); - for (i=0; i<(sizeof(patch_2000)/4); i++) - *dp++ = patch_2000[i]; - - dp = (uint *)&(commproc->cp_dpmem[0x0f00]); - for (i=0; i<(sizeof(patch_2f00)/4); i++) - *dp++ = patch_2f00[i]; + cpm_write_patch(cp, 0, patch_2000, sizeof(patch_2000)); + cpm_write_patch(cp, 0xf00, patch_2f00, sizeof(patch_2f00)); commproc->cp_rccr = 0x0009; @@ -241,13 +240,8 @@ void __init cpm_load_patch(cpm8xx_t *cp) commproc->cp_rccr = 0; - dp = (uint *)(commproc->cp_dpmem); - for (i=0; i<(sizeof(patch_2000)/4); i++) - *dp++ = patch_2000[i]; - - dp = (uint *)&(commproc->cp_dpmem[0x0f00]); - for (i=0; i<(sizeof(patch_2f00)/4); i++) - *dp++ = patch_2f00[i]; + cpm_write_patch(cp, 0, patch_2000, sizeof(patch_2000)); + cpm_write_patch(cp, 0xf00, patch_2f00, sizeof(patch_2f00)); iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC]; # define RPBASE 0x0500 @@ -255,9 +249,8 @@ void __init cpm_load_patch(cpm8xx_t *cp) /* Put SPI above the IIC, also 32-byte aligned. */ - i = (RPBASE + sizeof(iic_t) + 31) & ~31; spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI]; - spp->rpbase = i; + spp->rpbase = (RPBASE + sizeof(iic_t) + 31) & ~31; # if defined(CONFIG_I2C_SPI_UCODE_PATCH) commproc->cp_cpmcr1 = 0x802a; @@ -271,9 +264,7 @@ void __init cpm_load_patch(cpm8xx_t *cp) # if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - dp = (uint *)&(commproc->cp_dpmem[0x0e00]); - for (i=0; i<(sizeof(patch_2e00)/4); i++) - *dp++ = patch_2e00[i]; + cpm_write_patch(cp, 0xe00, patch_2e00, sizeof(patch_2e00)); commproc->cp_cpmcr1 = 0x8080; commproc->cp_cpmcr2 = 0x808a; -- cgit v1.2.3 From 11597ff20b6b3cf039577e46e53bf1a94dda3098 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:42 +0000 Subject: powerpc/8xx: Refactor microcode write Add empty microcode tables so that all tables are defined all the time. Regroup the writing of the 3 tables regardless of the selected microcode. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/micropatch.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index 04ef0b48ab21..657fd35cf698 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -69,6 +69,8 @@ static uint patch_2f00[] __initdata = { 0x31497353, 0x76956D69, 0x7B9D9693, 0x13131979, 0x79376935 }; + +static uint patch_2e00[] __initdata = {}; #endif /* @@ -202,6 +204,8 @@ static uint patch_2000[] __initdata = { static uint patch_2f00[] __initdata = { 0x3030304c, 0xcab9e441, 0xa1aaf220 }; + +static uint patch_2e00[] __initdata = {}; #endif static void __init cpm_write_patch(cpm8xx_t *cp, int offset, uint *patch, int len) @@ -224,12 +228,13 @@ void __init cpm_load_patch(cpm8xx_t *cp) #endif commproc = cp; -#ifdef CONFIG_USB_SOF_UCODE_PATCH commproc->cp_rccr = 0; cpm_write_patch(cp, 0, patch_2000, sizeof(patch_2000)); cpm_write_patch(cp, 0xf00, patch_2f00, sizeof(patch_2f00)); + cpm_write_patch(cp, 0xe00, patch_2e00, sizeof(patch_2e00)); +#ifdef CONFIG_USB_SOF_UCODE_PATCH commproc->cp_rccr = 0x0009; printk("USB SOF microcode patch installed\n"); @@ -238,11 +243,6 @@ void __init cpm_load_patch(cpm8xx_t *cp) #if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - commproc->cp_rccr = 0; - - cpm_write_patch(cp, 0, patch_2000, sizeof(patch_2000)); - cpm_write_patch(cp, 0xf00, patch_2f00, sizeof(patch_2f00)); - iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC]; # define RPBASE 0x0500 iip->iic_rpbase = RPBASE; @@ -263,9 +263,6 @@ void __init cpm_load_patch(cpm8xx_t *cp) # endif /* CONFIG_I2C_SPI_UCODE_PATCH */ # if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - - cpm_write_patch(cp, 0xe00, patch_2e00, sizeof(patch_2e00)); - commproc->cp_cpmcr1 = 0x8080; commproc->cp_cpmcr2 = 0x808a; commproc->cp_cpmcr3 = 0x8028; -- cgit v1.2.3 From 5cfd5d8943fc9eb48030a7904e82c6e7d2056027 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:43 +0000 Subject: powerpc/8xx: refactor printing of microcode patch name. Define patch name together with the patch code, and refactor the associated printk() while replacing it by a pr_info() Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/micropatch.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index 657fd35cf698..9378f778af13 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -27,6 +27,8 @@ #ifdef CONFIG_I2C_SPI_UCODE_PATCH +static char patch_name[] __initdata = "I2C/SPI"; + static uint patch_2000[] __initdata = { 0x7FFFEFD9, 0x3FFD0000, 0x7FFB49F7, 0x7FF90000, 0x5FEFADF7, 0x5F89ADF7, 0x5FEFAFF7, 0x5F89AFF7, @@ -79,6 +81,8 @@ static uint patch_2e00[] __initdata = {}; #ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH +static char patch_name[] __initdata = "I2C/SPI/SMC1"; + static uint patch_2000[] __initdata = { 0x3fff0000, 0x3ffd0000, 0x3ffb0000, 0x3ff90000, 0x5f13eff8, 0x5eb5eff8, 0x5f88adf7, 0x5fefadf7, @@ -195,6 +199,8 @@ static uint patch_2e00[] __initdata = { #ifdef CONFIG_USB_SOF_UCODE_PATCH +static char patch_name[] __initdata = "USB SOF"; + static uint patch_2000[] __initdata = { 0x7fff0000, 0x7ffd0000, 0x7ffb0000, 0x49f7ba5b, 0xba383ffb, 0xf9b8b46d, 0xe5ab4e07, 0xaf77bffe, @@ -236,8 +242,6 @@ void __init cpm_load_patch(cpm8xx_t *cp) #ifdef CONFIG_USB_SOF_UCODE_PATCH commproc->cp_rccr = 0x0009; - - printk("USB SOF microcode patch installed\n"); #endif /* CONFIG_USB_SOF_UCODE_PATCH */ #if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ @@ -258,8 +262,6 @@ void __init cpm_load_patch(cpm8xx_t *cp) commproc->cp_cpmcr3 = 0x802e; commproc->cp_cpmcr4 = 0x802c; commproc->cp_rccr = 1; - - printk("I2C/SPI microcode patch installed.\n"); # endif /* CONFIG_I2C_SPI_UCODE_PATCH */ # if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) @@ -271,9 +273,9 @@ void __init cpm_load_patch(cpm8xx_t *cp) smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1]; smp->smc_rpbase = 0x1FC0; - - printk("I2C/SPI/SMC1 microcode patch installed.\n"); # endif /* CONFIG_I2C_SPI_SMC1_UCODE_PATCH) */ #endif /* some variation of the I2C/SPI patch was selected */ + + pr_info("%s microcode patch installed\n", patch_name); } -- cgit v1.2.3 From f5348c080e07bc7ce8f6a6c110bd2672f915c6b1 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:44 +0000 Subject: powerpc/8xx: refactor programming of microcode CPM params. The CPM registers RCCR and CPMCR1..4 registers has to be set in accordance with the microcode patch beeing programmed. Lets define them as part of the patch set and refactor their programming from that definition. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/micropatch.c | 45 ++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 18 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index 9378f778af13..2fdd8f935501 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -21,6 +21,14 @@ #include #include +struct patch_params { + ushort rccr; + ushort cpmcr1; + ushort cpmcr2; + ushort cpmcr3; + ushort cpmcr4; +}; + /* * I2C/SPI relocation patch arrays. */ @@ -29,6 +37,10 @@ static char patch_name[] __initdata = "I2C/SPI"; +static struct patch_params patch_params __initdata = { + 1, 0x802a, 0x8028, 0x802e, 0x802c, +}; + static uint patch_2000[] __initdata = { 0x7FFFEFD9, 0x3FFD0000, 0x7FFB49F7, 0x7FF90000, 0x5FEFADF7, 0x5F89ADF7, 0x5FEFAFF7, 0x5F89AFF7, @@ -83,6 +95,10 @@ static uint patch_2e00[] __initdata = {}; static char patch_name[] __initdata = "I2C/SPI/SMC1"; +static struct patch_params patch_params __initdata = { + 3, 0x8080, 0x808a, 0x8028, 0x802a, +}; + static uint patch_2000[] __initdata = { 0x3fff0000, 0x3ffd0000, 0x3ffb0000, 0x3ff90000, 0x5f13eff8, 0x5eb5eff8, 0x5f88adf7, 0x5fefadf7, @@ -201,6 +217,10 @@ static uint patch_2e00[] __initdata = { static char patch_name[] __initdata = "USB SOF"; +static struct patch_params patch_params __initdata = { + 9, +}; + static uint patch_2000[] __initdata = { 0x7fff0000, 0x7ffd0000, 0x7ffb0000, 0x49f7ba5b, 0xba383ffb, 0xf9b8b46d, 0xe5ab4e07, 0xaf77bffe, @@ -240,10 +260,6 @@ void __init cpm_load_patch(cpm8xx_t *cp) cpm_write_patch(cp, 0xf00, patch_2f00, sizeof(patch_2f00)); cpm_write_patch(cp, 0xe00, patch_2e00, sizeof(patch_2e00)); -#ifdef CONFIG_USB_SOF_UCODE_PATCH - commproc->cp_rccr = 0x0009; -#endif /* CONFIG_USB_SOF_UCODE_PATCH */ - #if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) @@ -256,26 +272,19 @@ void __init cpm_load_patch(cpm8xx_t *cp) spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI]; spp->rpbase = (RPBASE + sizeof(iic_t) + 31) & ~31; -# if defined(CONFIG_I2C_SPI_UCODE_PATCH) - commproc->cp_cpmcr1 = 0x802a; - commproc->cp_cpmcr2 = 0x8028; - commproc->cp_cpmcr3 = 0x802e; - commproc->cp_cpmcr4 = 0x802c; - commproc->cp_rccr = 1; -# endif /* CONFIG_I2C_SPI_UCODE_PATCH */ - # if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - commproc->cp_cpmcr1 = 0x8080; - commproc->cp_cpmcr2 = 0x808a; - commproc->cp_cpmcr3 = 0x8028; - commproc->cp_cpmcr4 = 0x802a; - commproc->cp_rccr = 3; - smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1]; smp->smc_rpbase = 0x1FC0; # endif /* CONFIG_I2C_SPI_SMC1_UCODE_PATCH) */ #endif /* some variation of the I2C/SPI patch was selected */ + commproc->cp_cpmcr1 = patch_params.cpmcr1; + commproc->cp_cpmcr2 = patch_params.cpmcr2; + commproc->cp_cpmcr3 = patch_params.cpmcr3; + commproc->cp_cpmcr4 = patch_params.cpmcr4; + + commproc->cp_rccr = patch_params.rccr; + pr_info("%s microcode patch installed\n", patch_name); } -- cgit v1.2.3 From 647d5ed0ae8a9942de8615f33790be7ac940056c Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:45 +0000 Subject: powerpc/8xx: replace #ifdefs by IS_ENABLED() in microcode.c Reduce #ifdef mess by using IS_ENABLED() instead. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/micropatch.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index 2fdd8f935501..0bb51531323e 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -244,14 +244,9 @@ static void __init cpm_write_patch(cpm8xx_t *cp, int offset, uint *patch, int le void __init cpm_load_patch(cpm8xx_t *cp) { volatile cpm8xx_t *commproc; -#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ - defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) volatile iic_t *iip; volatile struct spi_pram *spp; -#ifdef CONFIG_I2C_SPI_SMC1_UCODE_PATCH volatile smc_uart_t *smp; -#endif -#endif commproc = cp; commproc->cp_rccr = 0; @@ -260,24 +255,22 @@ void __init cpm_load_patch(cpm8xx_t *cp) cpm_write_patch(cp, 0xf00, patch_2f00, sizeof(patch_2f00)); cpm_write_patch(cp, 0xe00, patch_2e00, sizeof(patch_2e00)); -#if defined(CONFIG_I2C_SPI_UCODE_PATCH) || \ - defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - - iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC]; -# define RPBASE 0x0500 - iip->iic_rpbase = RPBASE; + if (IS_ENABLED(CONFIG_I2C_SPI_UCODE_PATCH) || + IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) { + u16 rpbase = 0x500; - /* Put SPI above the IIC, also 32-byte aligned. - */ - spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI]; - spp->rpbase = (RPBASE + sizeof(iic_t) + 31) & ~31; + iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC]; + iip->iic_rpbase = rpbase; -# if defined(CONFIG_I2C_SPI_SMC1_UCODE_PATCH) - smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1]; - smp->smc_rpbase = 0x1FC0; -# endif /* CONFIG_I2C_SPI_SMC1_UCODE_PATCH) */ + /* Put SPI above the IIC, also 32-byte aligned. */ + spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI]; + spp->rpbase = (rpbase + sizeof(iic_t) + 31) & ~31; -#endif /* some variation of the I2C/SPI patch was selected */ + if (IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) { + smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1]; + smp->smc_rpbase = 0x1FC0; + } + } commproc->cp_cpmcr1 = patch_params.cpmcr1; commproc->cp_cpmcr2 = patch_params.cpmcr2; -- cgit v1.2.3 From c3eec5d7da3f77c6e505b44241205ca0aff1df24 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:46 +0000 Subject: powerpc/8xx: Use IO accessors in microcode programming. Change microcode functions to use IO accessors and get rid of volatile attributes. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/micropatch.c | 34 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 18 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index 0bb51531323e..4ae846030ea7 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -243,13 +243,7 @@ static void __init cpm_write_patch(cpm8xx_t *cp, int offset, uint *patch, int le void __init cpm_load_patch(cpm8xx_t *cp) { - volatile cpm8xx_t *commproc; - volatile iic_t *iip; - volatile struct spi_pram *spp; - volatile smc_uart_t *smp; - commproc = cp; - - commproc->cp_rccr = 0; + out_be16(&cp->cp_rccr, 0); cpm_write_patch(cp, 0, patch_2000, sizeof(patch_2000)); cpm_write_patch(cp, 0xf00, patch_2f00, sizeof(patch_2f00)); @@ -258,26 +252,30 @@ void __init cpm_load_patch(cpm8xx_t *cp) if (IS_ENABLED(CONFIG_I2C_SPI_UCODE_PATCH) || IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) { u16 rpbase = 0x500; + iic_t *iip; + struct spi_pram *spp; - iip = (iic_t *)&commproc->cp_dparam[PROFF_IIC]; - iip->iic_rpbase = rpbase; + iip = (iic_t *)&cp->cp_dparam[PROFF_IIC]; + out_be16(&iip->iic_rpbase, rpbase); /* Put SPI above the IIC, also 32-byte aligned. */ - spp = (struct spi_pram *)&commproc->cp_dparam[PROFF_SPI]; - spp->rpbase = (rpbase + sizeof(iic_t) + 31) & ~31; + spp = (struct spi_pram *)&cp->cp_dparam[PROFF_SPI]; + out_be16(&spp->rpbase, (rpbase + sizeof(iic_t) + 31) & ~31); if (IS_ENABLED(CONFIG_I2C_SPI_SMC1_UCODE_PATCH)) { - smp = (smc_uart_t *)&commproc->cp_dparam[PROFF_SMC1]; - smp->smc_rpbase = 0x1FC0; + smc_uart_t *smp; + + smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1]; + out_be16(&smp->smc_rpbase, 0x1FC0); } } - commproc->cp_cpmcr1 = patch_params.cpmcr1; - commproc->cp_cpmcr2 = patch_params.cpmcr2; - commproc->cp_cpmcr3 = patch_params.cpmcr3; - commproc->cp_cpmcr4 = patch_params.cpmcr4; + out_be16(&cp->cp_cpmcr1, patch_params.cpmcr1); + out_be16(&cp->cp_cpmcr2, patch_params.cpmcr2); + out_be16(&cp->cp_cpmcr3, patch_params.cpmcr3); + out_be16(&cp->cp_cpmcr4, patch_params.cpmcr4); - commproc->cp_rccr = patch_params.rccr; + out_be16(&cp->cp_rccr, patch_params.rccr); pr_info("%s microcode patch installed\n", patch_name); } -- cgit v1.2.3 From 43db76f41824aea0a31f817e69ad304a95cf068a Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 06:41:47 +0000 Subject: powerpc/8xx: Add microcode patch to move SMC parameter RAM. Some SCC functions like the QMC requires an extended parameter RAM. On modern 8xx (ie 866 and 885), SPI area can already be relocated, allowing the use of those functions on SCC2. But SCC3 and SCC4 parameter RAM collide with SMC1 and SMC2 parameter RAMs. This patch adds microcode to allow the relocation of both SMC1 and SMC2, and relocate them at offsets 0x1ec0 and 0x1fc0. Those offsets are by default for the CPM1 DSP1 and DSP2, but there is no kernel driver using them at the moment so this area can be reused. This microcode is provided by Freescale/NXP in Engineering Bulletin EB662 ("MPC8xx I2C/SPI and SMC Relocation Microcode Packages") dated 2006. The binary code is public. The source is not available. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/platforms/8xx/Kconfig | 7 +++ arch/powerpc/platforms/8xx/micropatch.c | 97 +++++++++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/8xx/Kconfig b/arch/powerpc/platforms/8xx/Kconfig index d408162d5af4..e0fe670f06f6 100644 --- a/arch/powerpc/platforms/8xx/Kconfig +++ b/arch/powerpc/platforms/8xx/Kconfig @@ -157,6 +157,13 @@ config I2C_SPI_SMC1_UCODE_PATCH help Help not implemented yet, coming soon. +config SMC_UCODE_PATCH + bool "SMC relocation patch" + help + This microcode relocates SMC1 and SMC2 parameter RAMs at + offset 0x1ec0 and 0x1fc0 to allow extended parameter RAM + for SCC3 and SCC4. + endchoice config UCODE_PATCH diff --git a/arch/powerpc/platforms/8xx/micropatch.c b/arch/powerpc/platforms/8xx/micropatch.c index 4ae846030ea7..c80bd7afd6c5 100644 --- a/arch/powerpc/platforms/8xx/micropatch.c +++ b/arch/powerpc/platforms/8xx/micropatch.c @@ -234,6 +234,94 @@ static uint patch_2f00[] __initdata = { static uint patch_2e00[] __initdata = {}; #endif +/* + * SMC relocation patch arrays. + */ + +#ifdef CONFIG_SMC_UCODE_PATCH + +static char patch_name[] __initdata = "SMC"; + +static struct patch_params patch_params __initdata = { + 2, 0x8080, 0x8088, +}; + +static uint patch_2000[] __initdata = { + 0x3fff0000, 0x3ffd0000, 0x3ffb0000, 0x3ff90000, + 0x5fefeff8, 0x5f91eff8, 0x3ff30000, 0x3ff10000, + 0x3a11e710, 0xedf0ccb9, 0xf318ed66, 0x7f0e5fe2, + 0x7fedbb38, 0x3afe7468, 0x7fedf4d8, 0x8ffbb92d, + 0xb83b77fd, 0xb0bb5eb9, 0xdfda7fed, 0x90bde74d, + 0x6f0dcbd3, 0xe7decfed, 0xcb50cfed, 0xcfeddf6d, + 0x914d4f74, 0x5eaedfcb, 0x9ee0e7df, 0xefbb6ffb, + 0xe7ef7f0e, 0x9ee57fed, 0xebb7effa, 0xeb30affb, + 0x7fea90b3, 0x7e0cf09f, 0xbffff318, 0x5fffdfff, + 0xac35efea, 0x7fce1fc1, 0xe2ff5fbd, 0xaffbe2ff, + 0x5fbfaffb, 0xf9a87d0f, 0xaef8770f, 0x7d0fb0a2, + 0xeffbbfff, 0xcfef5fba, 0x7d0fbfff, 0x5fba4cf8, + 0x7fddd09b, 0x49f847fd, 0x7efdf097, 0x7fedfffd, + 0x7dfdf093, 0xef7e7e1e, 0x5fba7f0e, 0x3a11e710, + 0xedf0cc87, 0xfb18ad0a, 0x1f85bbb8, 0x74283b7e, + 0x7375e4bb, 0x2ab64fb8, 0x5c7de4bb, 0x32fdffbf, + 0x5f0843f8, 0x7ce3e1bb, 0xe74f7ded, 0x6f0f4fe8, + 0xc7ba32be, 0x73f2efeb, 0x600b4f78, 0xe5bb760b, + 0x5388aef8, 0x4ef80b6a, 0xcfef9ee5, 0xabf8751f, + 0xefef5b88, 0x741f4fe8, 0x751e760d, 0x7fdb70dd, + 0x741cafce, 0xefcc7fce, 0x751e7088, 0x741ce7bb, + 0x334ecfed, 0xafdbefeb, 0xe5bb760b, 0x53ceaef8, + 0xafe8e7eb, 0x4bf8771e, 0x7e007fed, 0x4fcbe2cc, + 0x7fbc3085, 0x7b0f7a0f, 0x34b177fd, 0xb0e75e93, + 0xdf313e3b, 0xaf78741f, 0x741f30cc, 0xcfef5f08, + 0x741f3e88, 0xafb8771e, 0x5f437fed, 0x0bafe2cc, + 0x741ccfec, 0xe5ca53a9, 0x6fcb4f74, 0x5e89df27, + 0x2a923d14, 0x4b8fdf0c, 0x751f741c, 0x6c1eeffa, + 0xefea7fce, 0x6ffc309a, 0xefec3fca, 0x308fdf0a, + 0xadf85e7a, 0xaf7daefd, 0x5e7adf0a, 0x5e7aafdd, + 0x761f1088, 0x1e7c7efd, 0x3089fffe, 0x4908fb18, + 0x5fffdfff, 0xafbbf0f7, 0x4ef85f43, 0xadf81489, + 0x7a0f7089, 0xcfef5089, 0x7a0fdf0c, 0x5e7cafed, + 0xbc6e780f, 0xefef780f, 0xefef790f, 0xa7f85eeb, + 0xffef790f, 0xefef790f, 0x1489df0a, 0x5e7aadfd, + 0x5f09fffb, 0xe79aded9, 0xeff96079, 0x607ae79a, + 0xded8eff9, 0x60795edb, 0x607acfef, 0xefefefdf, + 0xefbfef7f, 0xeeffedff, 0xebffe7ff, 0xafefafdf, + 0xafbfaf7f, 0xaeffadff, 0xabffa7ff, 0x6fef6fdf, + 0x6fbf6f7f, 0x6eff6dff, 0x6bff67ff, 0x2fef2fdf, + 0x2fbf2f7f, 0x2eff2dff, 0x2bff27ff, 0x4e08fd1f, + 0xe5ff6e0f, 0xaff87eef, 0x7e0ffdef, 0xf11f6079, + 0xabf8f51e, 0x7e0af11c, 0x37cfae16, 0x7fec909a, + 0xadf8efdc, 0xcfeae52f, 0x7d0fe12b, 0xf11c6079, + 0x7e0a4df8, 0xcfea5ea0, 0x7d0befec, 0xcfea5ea2, + 0xe522efdc, 0x5ea2cfda, 0x4e08fd1f, 0x6e0faff8, + 0x7c1f761f, 0xfdeff91f, 0x6079abf8, 0x761cee00, + 0xf91f2bfb, 0xefefcfec, 0xf91f6079, 0x761c27fb, + 0xefdf5e83, 0xcfdc7fdd, 0x50f84bf8, 0x47fd7c1f, + 0x761ccfcf, 0x7eef7fed, 0x7dfd70ef, 0xef7e7f1e, + 0x771efb18, 0x6079e722, 0xe6bbe5bb, 0x2e66e5bb, + 0x600b2ee1, 0xe2bbe2bb, 0xe2bbe2bb, 0x2f5ee2bb, + 0xe2bb2ff9, 0x6079e2bb, +}; + +static uint patch_2f00[] __initdata = { + 0x30303030, 0x3e3e3030, 0xaf79b9b3, 0xbaa3b979, + 0x9693369f, 0x79f79777, 0x97333fff, 0xfb3b9e9f, + 0x79b91d11, 0x9e13f3ff, 0x3f9b6bd9, 0xe173d136, + 0x695669d1, 0x697b3daf, 0x79b93a3a, 0x3f979f91, + 0x379ff976, 0xf99777fd, 0x9779737d, 0xe9d6bbf9, + 0xbfffd9df, 0x97f7fd97, 0x6f7b9bff, 0xf9bd9683, + 0x397db973, 0xd97b3b9f, 0xd7f9f733, 0x9993bb9e, + 0xe1f9ef93, 0x73773337, 0xb936917d, 0x11f87379, + 0xb979d336, 0x8b7ded73, 0x1b7d9337, 0x31f3f22f, + 0x3f2327ee, 0xeeeeeeee, 0xeeeeeeee, 0xeeeeeeee, + 0xeeeeee4b, 0xf4fbdbd2, 0x58bb1878, 0x577fdfd2, + 0xd573b773, 0xf7374b4f, 0xbdbd25b8, 0xb177d2d1, + 0x7376856b, 0xbfdd687b, 0xdd2fff8f, 0x78ffff8f, + 0xf22f0000, +}; + +static uint patch_2e00[] __initdata = {}; +#endif + static void __init cpm_write_patch(cpm8xx_t *cp, int offset, uint *patch, int len) { if (!len) @@ -270,6 +358,15 @@ void __init cpm_load_patch(cpm8xx_t *cp) } } + if (IS_ENABLED(CONFIG_SMC_UCODE_PATCH)) { + smc_uart_t *smp; + + smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC1]; + out_be16(&smp->smc_rpbase, 0x1ec0); + smp = (smc_uart_t *)&cp->cp_dparam[PROFF_SMC2]; + out_be16(&smp->smc_rpbase, 0x1fc0); + } + out_be16(&cp->cp_cpmcr1, patch_params.cpmcr1); out_be16(&cp->cp_cpmcr2, patch_params.cpmcr2); out_be16(&cp->cp_cpmcr3, patch_params.cpmcr3); -- cgit v1.2.3 From fbded57c962e7c42c932e1a46c8d801441726662 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 10:16:23 +0000 Subject: powerpc/boot: don't force gzipped uImage This patch modifies the generation of uImage by handing over the selected compression type instead of forcing gzip Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/boot/wrapper | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index f9141eaec6ff..4e9beecf2502 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -41,6 +41,7 @@ dts= cacheit= binary= compression=.gz +uboot_comp=gzip pie= format= @@ -131,6 +132,7 @@ while [ "$#" -gt 0 ]; do ;; -z) compression=.gz + uboot_comp=gzip ;; -Z) shift @@ -138,15 +140,21 @@ while [ "$#" -gt 0 ]; do [ "$1" != "gz" -o "$1" != "xz" -o "$1" != "none" ] || usage compression=".$1" + uboot_comp=$1 if [ $compression = ".none" ]; then compression= + uboot_comp=none fi + if [ $uboot_comp = "gz" ]; then + uboot_comp=gzip + fi ;; --no-gzip) # a "feature" of the the wrapper script is that it can be used outside # the kernel tree. So keeping this around for backwards compatibility. compression= + uboot_comp=none ;; -?) usage @@ -369,6 +377,7 @@ if [ -z "$cacheit" -o ! -f "$vmz$compression" -o "$vmz$compression" -ot "$kernel *) # drop the compression suffix so the stripped vmlinux is used compression= + uboot_comp=none ;; esac @@ -412,7 +421,7 @@ membase=`${CROSS}objdump -p "$kernel" | grep -m 1 LOAD | awk '{print $7}'` case "$platform" in uboot) rm -f "$ofile" - ${MKIMAGE} -A ppc -O linux -T kernel -C gzip -a $membase -e $membase \ + ${MKIMAGE} -A ppc -O linux -T kernel -C $uboot_comp -a $membase -e $membase \ $uboot_version -d "$vmz" "$ofile" if [ -z "$cacheit" ]; then rm -f "$vmz" -- cgit v1.2.3 From 1cc9a21b0bb36debdf96dbcc4b139d6639373018 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 10:16:24 +0000 Subject: powerpc/boot: Add lzma support for uImage This patch allows to generate lzma compressed uImage Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig | 1 + arch/powerpc/boot/Makefile | 2 ++ arch/powerpc/boot/wrapper | 5 ++++- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 537d93a4594b..016bd351e5fe 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -198,6 +198,7 @@ config PPC select HAVE_IOREMAP_PROT select HAVE_IRQ_EXIT_ON_IRQ_STACK select HAVE_KERNEL_GZIP + select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x select HAVE_KPROBES select HAVE_KPROBES_ON_FTRACE diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 73d1f3562978..9b7b11a22925 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -22,6 +22,7 @@ all: $(obj)/zImage compress-$(CONFIG_KERNEL_GZIP) := CONFIG_KERNEL_GZIP compress-$(CONFIG_KERNEL_XZ) := CONFIG_KERNEL_XZ +compress-$(CONFIG_KERNEL_LZMA) := CONFIG_KERNEL_LZMA ifdef CROSS32_COMPILE BOOTCC := $(CROSS32_COMPILE)gcc @@ -257,6 +258,7 @@ endif compressor-$(CONFIG_KERNEL_GZIP) := gz compressor-$(CONFIG_KERNEL_XZ) := xz +compressor-$(CONFIG_KERNEL_LZMA) := lzma # args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd quiet_cmd_wrap = WRAP $@ diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 4e9beecf2502..51dc42f5acbc 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -137,7 +137,7 @@ while [ "$#" -gt 0 ]; do -Z) shift [ "$#" -gt 0 ] || usage - [ "$1" != "gz" -o "$1" != "xz" -o "$1" != "none" ] || usage + [ "$1" != "gz" -o "$1" != "xz" -o "$1" != "lzma" -o "$1" != "none" ] || usage compression=".$1" uboot_comp=$1 @@ -374,6 +374,9 @@ if [ -z "$cacheit" -o ! -f "$vmz$compression" -o "$vmz$compression" -ot "$kernel .gz) gzip -n -f -9 "$vmz.$$" ;; + .lzma) + xz --format=lzma -f -6 "$vmz.$$" + ;; *) # drop the compression suffix so the stripped vmlinux is used compression= -- cgit v1.2.3 From 264bffad4d08f967ab3d6690bb15757a526b186a Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 14 Jun 2019 10:16:25 +0000 Subject: powerpc/boot: Add lzo support for uImage This patch allows to generate lzo compressed uImage Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/Kconfig | 1 + arch/powerpc/boot/Makefile | 2 ++ arch/powerpc/boot/wrapper | 5 ++++- 3 files changed, 7 insertions(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index 016bd351e5fe..12cee37f15c4 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -199,6 +199,7 @@ config PPC select HAVE_IRQ_EXIT_ON_IRQ_STACK select HAVE_KERNEL_GZIP select HAVE_KERNEL_LZMA if DEFAULT_UIMAGE + select HAVE_KERNEL_LZO if DEFAULT_UIMAGE select HAVE_KERNEL_XZ if PPC_BOOK3S || 44x select HAVE_KPROBES select HAVE_KPROBES_ON_FTRACE diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 9b7b11a22925..36fb51a9329f 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -23,6 +23,7 @@ all: $(obj)/zImage compress-$(CONFIG_KERNEL_GZIP) := CONFIG_KERNEL_GZIP compress-$(CONFIG_KERNEL_XZ) := CONFIG_KERNEL_XZ compress-$(CONFIG_KERNEL_LZMA) := CONFIG_KERNEL_LZMA +compress-$(CONFIG_KERNEL_LZO) := CONFIG_KERNEL_LZO ifdef CROSS32_COMPILE BOOTCC := $(CROSS32_COMPILE)gcc @@ -259,6 +260,7 @@ endif compressor-$(CONFIG_KERNEL_GZIP) := gz compressor-$(CONFIG_KERNEL_XZ) := xz compressor-$(CONFIG_KERNEL_LZMA) := lzma +compressor-$(CONFIG_KERNEL_LZO) := lzo # args (to if_changed): 1 = (this rule), 2 = platform, 3 = dts 4=dtb 5=initrd quiet_cmd_wrap = WRAP $@ diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper index 51dc42f5acbc..4ed18d63d892 100755 --- a/arch/powerpc/boot/wrapper +++ b/arch/powerpc/boot/wrapper @@ -137,7 +137,7 @@ while [ "$#" -gt 0 ]; do -Z) shift [ "$#" -gt 0 ] || usage - [ "$1" != "gz" -o "$1" != "xz" -o "$1" != "lzma" -o "$1" != "none" ] || usage + [ "$1" != "gz" -o "$1" != "xz" -o "$1" != "lzma" -o "$1" != "lzo" -o "$1" != "none" ] || usage compression=".$1" uboot_comp=$1 @@ -377,6 +377,9 @@ if [ -z "$cacheit" -o ! -f "$vmz$compression" -o "$vmz$compression" -ot "$kernel .lzma) xz --format=lzma -f -6 "$vmz.$$" ;; + .lzo) + lzop -f -9 "$vmz.$$" + ;; *) # drop the compression suffix so the stripped vmlinux is used compression= -- cgit v1.2.3 From 2fb0a2c989837c976b68233496bbaefb47cd3d6f Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Sat, 6 Jul 2019 00:18:53 +1000 Subject: powerpc/module64: Fix comment in R_PPC64_ENTRY handling The comment here is wrong, the addi reads from r2 not r12. The code is correct, 0x38420000 = addi r2,r2,0. Fixes: a61674bdfc7c ("powerpc/module: Handle R_PPC64_ENTRY relocations") Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/module_64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 8661eea78503..4bf81a111179 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -719,7 +719,7 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, /* * If found, replace it with: * addis r2, r12, (.TOC.-func)@ha - * addi r2, r12, (.TOC.-func)@l + * addi r2, r2, (.TOC.-func)@l */ ((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value); ((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value); -- cgit v1.2.3 From 7f9c929a7ff203eae60b4225bb6824c3eb31796c Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 3 May 2019 06:40:15 +0000 Subject: powerpc: Move PPC_HA() PPC_HI() and PPC_LO() to ppc-opcode.h PPC_HA() PPC_HI() and PPC_LO() macros are nice macros. Move them from module64.c to ppc-opcode.h in order to use them in other places. Signed-off-by: Christophe Leroy [mpe: Clean up formatting in new code, drop duplicates in ftrace.c] Signed-off-by: Michael Ellerman --- arch/powerpc/include/asm/ppc-opcode.h | 9 +++++++++ arch/powerpc/kernel/module_64.c | 7 ------- arch/powerpc/kernel/trace/ftrace.c | 4 ---- 3 files changed, 9 insertions(+), 11 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/ppc-opcode.h b/arch/powerpc/include/asm/ppc-opcode.h index 971bdf84f6fc..f544432aef82 100644 --- a/arch/powerpc/include/asm/ppc-opcode.h +++ b/arch/powerpc/include/asm/ppc-opcode.h @@ -412,6 +412,15 @@ #define __PPC_SPR(r) ((((r) & 0x1f) << 16) | ((((r) >> 5) & 0x1f) << 11)) #define __PPC_RC21 (0x1 << 10) +/* + * Both low and high 16 bits are added as SIGNED additions, so if low 16 bits + * has high bit set, high 16 bits must be adjusted. These macros do that (stolen + * from binutils). + */ +#define PPC_LO(v) ((v) & 0xffff) +#define PPC_HI(v) (((v) >> 16) & 0xffff) +#define PPC_HA(v) PPC_HI((v) + 0x8000) + /* * Only use the larx hint bit on 64bit CPUs. e500v1/v2 based CPUs will treat a * larx with EH set as an illegal instruction. diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 4bf81a111179..80ceb458e79c 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -400,13 +400,6 @@ static inline unsigned long my_r2(const Elf64_Shdr *sechdrs, struct module *me) return (sechdrs[me->arch.toc_section].sh_addr & ~0xfful) + 0x8000; } -/* Both low and high 16 bits are added as SIGNED additions, so if low - 16 bits has high bit set, high 16 bits must be adjusted. These - macros do that (stolen from binutils). */ -#define PPC_LO(v) ((v) & 0xffff) -#define PPC_HI(v) (((v) >> 16) & 0xffff) -#define PPC_HA(v) PPC_HI ((v) + 0x8000) - /* Patch stub to reference function and correct r2 value. */ static inline int create_stub(const Elf64_Shdr *sechdrs, struct ppc64_stub_entry *entry, diff --git a/arch/powerpc/kernel/trace/ftrace.c b/arch/powerpc/kernel/trace/ftrace.c index 517662a56bdc..be1ca98fce5c 100644 --- a/arch/powerpc/kernel/trace/ftrace.c +++ b/arch/powerpc/kernel/trace/ftrace.c @@ -866,10 +866,6 @@ void arch_ftrace_update_code(int command) #ifdef CONFIG_PPC64 #define PACATOC offsetof(struct paca_struct, kernel_toc) -#define PPC_LO(v) ((v) & 0xffff) -#define PPC_HI(v) (((v) >> 16) & 0xffff) -#define PPC_HA(v) PPC_HI ((v) + 0x8000) - extern unsigned int ftrace_tramp_text[], ftrace_tramp_init[]; int __init ftrace_dyn_arch_init(void) -- cgit v1.2.3 From 4eb4516eada3ae469cd9d97c6dbe730ad3cdf2b6 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 3 May 2019 06:40:16 +0000 Subject: powerpc/module32: Use symbolic instructions names. To increase readability/maintainability, replace hard coded instructions values by symbolic names. Signed-off-by: Christophe Leroy Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/module_32.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/module_32.c b/arch/powerpc/kernel/module_32.c index 88d83771f462..9cf201111d6c 100644 --- a/arch/powerpc/kernel/module_32.c +++ b/arch/powerpc/kernel/module_32.c @@ -172,10 +172,12 @@ int module_frob_arch_sections(Elf32_Ehdr *hdr, static inline int entry_matches(struct ppc_plt_entry *entry, Elf32_Addr val) { - if (entry->jump[0] == 0x3d800000 + ((val + 0x8000) >> 16) - && entry->jump[1] == 0x398c0000 + (val & 0xffff)) - return 1; - return 0; + if (entry->jump[0] != (PPC_INST_ADDIS | __PPC_RT(R12) | PPC_HA(val))) + return 0; + if (entry->jump[1] != (PPC_INST_ADDI | __PPC_RT(R12) | __PPC_RA(R12) | + PPC_LO(val))) + return 0; + return 1; } /* Set up a trampoline in the PLT to bounce us to the distant function */ @@ -200,10 +202,16 @@ static uint32_t do_plt_call(void *location, entry++; } - entry->jump[0] = 0x3d800000+((val+0x8000)>>16); /* lis r12,sym@ha */ - entry->jump[1] = 0x398c0000 + (val&0xffff); /* addi r12,r12,sym@l*/ - entry->jump[2] = 0x7d8903a6; /* mtctr r12 */ - entry->jump[3] = 0x4e800420; /* bctr */ + /* + * lis r12, sym@ha + * addi r12, r12, sym@l + * mtctr r12 + * bctr + */ + entry->jump[0] = PPC_INST_ADDIS | __PPC_RT(R12) | PPC_HA(val); + entry->jump[1] = PPC_INST_ADDI | __PPC_RT(R12) | __PPC_RA(R12) | PPC_LO(val); + entry->jump[2] = PPC_INST_MTCTR | __PPC_RS(R12); + entry->jump[3] = PPC_INST_BCTR; pr_debug("Initialized plt for 0x%x at %p\n", val, entry); return (uint32_t)entry; -- cgit v1.2.3 From a2b6f26c264e510f1d76ce347e34a21fbda9d8b2 Mon Sep 17 00:00:00 2001 From: Christophe Leroy Date: Fri, 3 May 2019 06:40:17 +0000 Subject: powerpc/module64: Use symbolic instructions names. To increase readability/maintainability, replace hard coded instructions values by symbolic names. Signed-off-by: Christophe Leroy [mpe: Fix R_PPC64_ENTRY case, the addi reads from r2 not r12] Signed-off-by: Michael Ellerman --- arch/powerpc/kernel/module_64.c | 53 +++++++++++++++++++++++++++-------------- 1 file changed, 35 insertions(+), 18 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/module_64.c b/arch/powerpc/kernel/module_64.c index 80ceb458e79c..ef75f590ad3e 100644 --- a/arch/powerpc/kernel/module_64.c +++ b/arch/powerpc/kernel/module_64.c @@ -133,20 +133,27 @@ struct ppc64_stub_entry * the stub, but it's significantly shorter to put these values at the * end of the stub code, and patch the stub address (32-bits relative * to the TOC ptr, r2) into the stub. + * + * addis r11,r2, + * addi r11,r11, + * std r2,R2_STACK_OFFSET(r1) + * ld r12,32(r11) + * ld r2,40(r11) + * mtctr r12 + * bctr */ - static u32 ppc64_stub_insns[] = { - 0x3d620000, /* addis r11,r2, */ - 0x396b0000, /* addi r11,r11, */ + PPC_INST_ADDIS | __PPC_RT(R11) | __PPC_RA(R2), + PPC_INST_ADDI | __PPC_RT(R11) | __PPC_RA(R11), /* Save current r2 value in magic place on the stack. */ - 0xf8410000|R2_STACK_OFFSET, /* std r2,R2_STACK_OFFSET(r1) */ - 0xe98b0020, /* ld r12,32(r11) */ + PPC_INST_STD | __PPC_RS(R2) | __PPC_RA(R1) | R2_STACK_OFFSET, + PPC_INST_LD | __PPC_RT(R12) | __PPC_RA(R11) | 32, #ifdef PPC64_ELF_ABI_v1 /* Set up new r2 from function descriptor */ - 0xe84b0028, /* ld r2,40(r11) */ + PPC_INST_LD | __PPC_RT(R2) | __PPC_RA(R11) | 40, #endif - 0x7d8903a6, /* mtctr r12 */ - 0x4e800420 /* bctr */ + PPC_INST_MTCTR | __PPC_RS(R12), + PPC_INST_BCTR, }; #ifdef CONFIG_DYNAMIC_FTRACE @@ -704,18 +711,21 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, * ld r2, ...(r12) * add r2, r2, r12 */ - if ((((uint32_t *)location)[0] & ~0xfffc) - != 0xe84c0000) + if ((((uint32_t *)location)[0] & ~0xfffc) != + (PPC_INST_LD | __PPC_RT(R2) | __PPC_RA(R12))) break; - if (((uint32_t *)location)[1] != 0x7c426214) + if (((uint32_t *)location)[1] != + (PPC_INST_ADD | __PPC_RT(R2) | __PPC_RA(R2) | __PPC_RB(R12))) break; /* * If found, replace it with: * addis r2, r12, (.TOC.-func)@ha * addi r2, r2, (.TOC.-func)@l */ - ((uint32_t *)location)[0] = 0x3c4c0000 + PPC_HA(value); - ((uint32_t *)location)[1] = 0x38420000 + PPC_LO(value); + ((uint32_t *)location)[0] = PPC_INST_ADDIS | __PPC_RT(R2) | + __PPC_RA(R12) | PPC_HA(value); + ((uint32_t *)location)[1] = PPC_INST_ADDI | __PPC_RT(R2) | + __PPC_RA(R2) | PPC_LO(value); break; case R_PPC64_REL16_HA: @@ -769,12 +779,19 @@ static unsigned long create_ftrace_stub(const Elf64_Shdr *sechdrs, { struct ppc64_stub_entry *entry; unsigned int i, num_stubs; + /* + * ld r12,PACATOC(r13) + * addis r12,r12, + * addi r12,r12, + * mtctr r12 + * bctr + */ static u32 stub_insns[] = { - 0xe98d0000 | PACATOC, /* ld r12,PACATOC(r13) */ - 0x3d8c0000, /* addis r12,r12, */ - 0x398c0000, /* addi r12,r12, */ - 0x7d8903a6, /* mtctr r12 */ - 0x4e800420, /* bctr */ + PPC_INST_LD | __PPC_RT(R12) | __PPC_RA(R13) | PACATOC, + PPC_INST_ADDIS | __PPC_RT(R12) | __PPC_RA(R12), + PPC_INST_ADDI | __PPC_RT(R12) | __PPC_RA(R12), + PPC_INST_MTCTR | __PPC_RS(R12), + PPC_INST_BCTR, }; long reladdr; -- cgit v1.2.3 From 0fc12c022ad25532b66bf6f6c818ee1c1d63e702 Mon Sep 17 00:00:00 2001 From: Michael Ellerman Date: Mon, 8 Jul 2019 16:02:19 +1000 Subject: powerpc/irq: Don't WARN continuously in arch_local_irq_restore() When CONFIG_PPC_IRQ_SOFT_MASK_DEBUG is enabled (uncommon), we have a series of WARN_ON's in arch_local_irq_restore(). These are "should never happen" conditions, but if they do happen they can flood the console and render the system unusable. So switch them to WARN_ON_ONCE(). Fixes: e2b36d591720 ("powerpc/64: Don't trace code that runs with the soft irq mask unreconciled") Fixes: 9b81c0211c24 ("powerpc/64s: make PACA_IRQ_HARD_DIS track MSR[EE] closely") Fixes: 7c0482e3d055 ("powerpc/irq: Fix another case of lazy IRQ state getting out of sync") Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190708061046.7075-1-mpe@ellerman.id.au --- arch/powerpc/kernel/irq.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c index ada901af4950..c9a6eac3075c 100644 --- a/arch/powerpc/kernel/irq.c +++ b/arch/powerpc/kernel/irq.c @@ -259,7 +259,7 @@ notrace void arch_local_irq_restore(unsigned long mask) irq_happened = get_irq_happened(); if (!irq_happened) { #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG - WARN_ON(!(mfmsr() & MSR_EE)); + WARN_ON_ONCE(!(mfmsr() & MSR_EE)); #endif return; } @@ -272,7 +272,7 @@ notrace void arch_local_irq_restore(unsigned long mask) */ if (!(irq_happened & PACA_IRQ_HARD_DIS)) { #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG - WARN_ON(!(mfmsr() & MSR_EE)); + WARN_ON_ONCE(!(mfmsr() & MSR_EE)); #endif __hard_irq_disable(); #ifdef CONFIG_PPC_IRQ_SOFT_MASK_DEBUG @@ -283,7 +283,7 @@ notrace void arch_local_irq_restore(unsigned long mask) * warn if we are wrong. Only do that when IRQ tracing * is enabled as mfmsr() can be costly. */ - if (WARN_ON(mfmsr() & MSR_EE)) + if (WARN_ON_ONCE(mfmsr() & MSR_EE)) __hard_irq_disable(); #endif } -- cgit v1.2.3 From 9e005b761e7ad153dcf40a6cba1d681fe0830ac6 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 5 Jul 2019 19:01:43 +0900 Subject: powerpc/boot: add {get, put}_unaligned_be32 to xz_config.h The next commit will make the way of passing CONFIG options more robust. Unfortunately, it would uncover another hidden issue; without this commit, skiroot_defconfig would be broken like this: | WRAP arch/powerpc/boot/zImage.pseries | arch/powerpc/boot/wrapper.a(decompress.o): In function `bcj_powerpc.isra.10': | decompress.c:(.text+0x720): undefined reference to `get_unaligned_be32' | decompress.c:(.text+0x7a8): undefined reference to `put_unaligned_be32' | make[1]: *** [arch/powerpc/boot/Makefile;383: arch/powerpc/boot/zImage.pseries] Error 1 | make: *** [arch/powerpc/Makefile;295: zImage] Error 2 skiroot_defconfig is the only defconfig that enables CONFIG_KERNEL_XZ for ppc, which has never been correctly built before. I figured out the root cause in lib/decompress_unxz.c: | #ifdef CONFIG_PPC | # define XZ_DEC_POWERPC | #endif CONFIG_PPC is undefined here in the ppc bootwrapper because autoconf.h is not included except by arch/powerpc/boot/serial.c XZ_DEC_POWERPC is not defined, therefore, bcj_powerpc() is not compiled for the bootwrapper. With the next commit passing CONFIG_PPC correctly, we would realize that {get,put}_unaligned_be32 was missing. Unlike the other decompressors, the ppc bootwrapper duplicates all the necessary helpers in arch/powerpc/boot/. The other architectures define __KERNEL__ and pull in helpers for building the decompressors. If ppc bootwrapper had defined __KERNEL__, lib/xz/xz_private.h would have included : | #ifdef __KERNEL__ | # include | # include | # include However, doing so would cause tons of definition conflicts since the bootwrapper has duplicated everything. I just added copies of {get,put}_unaligned_be32, following the bootwrapper coding convention. Signed-off-by: Masahiro Yamada Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190705100144.28785-1-yamada.masahiro@socionext.com --- arch/powerpc/boot/xz_config.h | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/boot/xz_config.h b/arch/powerpc/boot/xz_config.h index e22e5b3770dd..ebfadd39e192 100644 --- a/arch/powerpc/boot/xz_config.h +++ b/arch/powerpc/boot/xz_config.h @@ -20,10 +20,30 @@ static inline uint32_t swab32p(void *p) #ifdef __LITTLE_ENDIAN__ #define get_le32(p) (*((uint32_t *) (p))) +#define cpu_to_be32(x) swab32(x) +static inline u32 be32_to_cpup(const u32 *p) +{ + return swab32p((u32 *)p); +} #else #define get_le32(p) swab32p(p) +#define cpu_to_be32(x) (x) +static inline u32 be32_to_cpup(const u32 *p) +{ + return *p; +} #endif +static inline uint32_t get_unaligned_be32(const void *p) +{ + return be32_to_cpup(p); +} + +static inline void put_unaligned_be32(u32 val, void *p) +{ + *((u32 *)p) = cpu_to_be32(val); +} + #define memeq(a, b, size) (memcmp(a, b, size) == 0) #define memzero(buf, size) memset(buf, 0, size) -- cgit v1.2.3 From 4ba7f80f42563903b0e26d30175808db7d07e664 Mon Sep 17 00:00:00 2001 From: Masahiro Yamada Date: Fri, 5 Jul 2019 19:01:44 +0900 Subject: powerpc/boot: pass CONFIG options in a simpler and more robust way Commit 5e9dcb6188a4 ("powerpc/boot: Expose Kconfig symbols to wrapper") was wrong, but commit e41b93a6be57 ("powerpc/boot: Fix build failures with -j 1") was also wrong. The correct dependency is: $(obj)/serial.o: $(obj)/autoconf.h However, I do not see the reason why we need to copy autoconf.h to arch/power/boot/. Nor do I see consistency in the way of passing CONFIG options. decompress.c references CONFIG_KERNEL_GZIP and CONFIG_KERNEL_XZ, which are passed via the command line. serial.c includes autoconf.h to reference a couple of CONFIG options, but this is fragile because we often forget to include "autoconf.h" from source files. In fact, it is already broken. ppc_asm.h references CONFIG_PPC_8xx, but utils.S is not given any way to access CONFIG options. So, CONFIG_PPC_8xx is never defined here. Pass $(LINUXINCLUDE) to make sure CONFIG options are accessible from all .c and .S files in arch/powerpc/boot/. I also removed the -traditional flag to make include/linux/kconfig.h work. This flag makes the preprocessor imitate the behavior of the pre-standard C compiler, but I do not understand why it is necessary. Signed-off-by: Masahiro Yamada Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190705100144.28785-2-yamada.masahiro@socionext.com --- arch/powerpc/boot/.gitignore | 2 -- arch/powerpc/boot/Makefile | 16 +++------------- arch/powerpc/boot/serial.c | 1 - 3 files changed, 3 insertions(+), 16 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore index 32034a0cc554..6610665fcf5e 100644 --- a/arch/powerpc/boot/.gitignore +++ b/arch/powerpc/boot/.gitignore @@ -44,5 +44,3 @@ fdt_sw.c fdt_wip.c libfdt.h libfdt_internal.h -autoconf.h - diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile index 36fb51a9329f..6841bd52738b 100644 --- a/arch/powerpc/boot/Makefile +++ b/arch/powerpc/boot/Makefile @@ -20,11 +20,6 @@ all: $(obj)/zImage -compress-$(CONFIG_KERNEL_GZIP) := CONFIG_KERNEL_GZIP -compress-$(CONFIG_KERNEL_XZ) := CONFIG_KERNEL_XZ -compress-$(CONFIG_KERNEL_LZMA) := CONFIG_KERNEL_LZMA -compress-$(CONFIG_KERNEL_LZO) := CONFIG_KERNEL_LZO - ifdef CROSS32_COMPILE BOOTCC := $(CROSS32_COMPILE)gcc BOOTAR := $(CROSS32_COMPILE)ar @@ -36,7 +31,7 @@ endif BOOTCFLAGS := -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs \ -fno-strict-aliasing -O2 -msoft-float -mno-altivec -mno-vsx \ -pipe -fomit-frame-pointer -fno-builtin -fPIC -nostdinc \ - -D$(compress-y) + $(LINUXINCLUDE) ifdef CONFIG_PPC64_BOOT_WRAPPER BOOTCFLAGS += -m64 @@ -53,7 +48,7 @@ BOOTCFLAGS += -mlittle-endian BOOTCFLAGS += $(call cc-option,-mabi=elfv2) endif -BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -traditional -nostdinc +BOOTAFLAGS := -D__ASSEMBLY__ $(BOOTCFLAGS) -nostdinc BOOTARFLAGS := -cr$(KBUILD_ARFLAGS) @@ -204,14 +199,9 @@ $(obj)/empty.c: $(obj)/zImage.coff.lds $(obj)/zImage.ps3.lds : $(obj)/%: $(srctree)/$(src)/%.S $(Q)cp $< $@ -$(srctree)/$(src)/serial.c: $(obj)/autoconf.h - -$(obj)/autoconf.h: $(obj)/%: $(objtree)/include/generated/% - $(Q)cp $< $@ - clean-files := $(zlib-) $(zlibheader-) $(zliblinuxheader-) \ $(zlib-decomp-) $(libfdt) $(libfdtheader) \ - autoconf.h empty.c zImage.coff.lds zImage.ps3.lds zImage.lds + empty.c zImage.coff.lds zImage.ps3.lds zImage.lds quiet_cmd_bootcc = BOOTCC $@ cmd_bootcc = $(BOOTCC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c index b0491b8c0199..9457863147f9 100644 --- a/arch/powerpc/boot/serial.c +++ b/arch/powerpc/boot/serial.c @@ -18,7 +18,6 @@ #include "stdio.h" #include "io.h" #include "ops.h" -#include "autoconf.h" static int serial_open(void) { -- cgit v1.2.3 From 33439620680be5225c1b8806579a291e0d761ca0 Mon Sep 17 00:00:00 2001 From: Oliver O'Halloran Date: Thu, 11 Jul 2019 01:05:17 +1000 Subject: powerpc/eeh: Handle hugepages in ioremap space In commit 4a7b06c157a2 ("powerpc/eeh: Handle hugepages in ioremap space") support for using hugepages in the vmalloc and ioremap areas was enabled for radix. Unfortunately this broke EEH MMIO error checking. Detection works by inserting a hook which checks the results of the ioreadXX() set of functions. When a read returns a 0xFFs response we need to check for an error which we do by mapping the (virtual) MMIO address back to a physical address, then mapping physical address to a PCI device via an interval tree. When translating virt -> phys we currently assume the ioremap space is only populated by PAGE_SIZE mappings. If a hugepage mapping is found we emit a WARN_ON(), but otherwise handles the check as though a normal page was found. In pathalogical cases such as copying a buffer containing a lot of 0xFFs from BAR memory this can result in the system not booting because it's too busy printing WARN_ON()s. There's no real reason to assume huge pages can't be present and we're prefectly capable of handling them, so do that. Fixes: 4a7b06c157a2 ("powerpc/eeh: Handle hugepages in ioremap space") Reported-by: Sachin Sant Signed-off-by: Oliver O'Halloran Tested-by: Sachin Sant Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190710150517.27114-1-oohall@gmail.com --- arch/powerpc/kernel/eeh.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c index 289c0b37d845..0dc1865c84ce 100644 --- a/arch/powerpc/kernel/eeh.c +++ b/arch/powerpc/kernel/eeh.c @@ -367,10 +367,19 @@ static inline unsigned long eeh_token_to_phys(unsigned long token) ptep = find_init_mm_pte(token, &hugepage_shift); if (!ptep) return token; - WARN_ON(hugepage_shift); - pa = pte_pfn(*ptep) << PAGE_SHIFT; - return pa | (token & (PAGE_SIZE-1)); + pa = pte_pfn(*ptep); + + /* On radix we can do hugepage mappings for io, so handle that */ + if (hugepage_shift) { + pa <<= hugepage_shift; + pa |= token & ((1ul << hugepage_shift) - 1); + } else { + pa <<= PAGE_SHIFT; + pa |= token & (PAGE_SIZE - 1); + } + + return pa; } /* -- cgit v1.2.3 From f5a9e488d62360c91c5770bd55a0b40e419a71ce Mon Sep 17 00:00:00 2001 From: Athira Rajeev Date: Tue, 2 Jul 2019 16:28:36 +0530 Subject: powerpc/powernv/idle: Fix restore of SPRN_LDBAR for POWER9 stop state. commit 10d91611f426 ("powerpc/64s: Reimplement book3s idle code in C") reimplemented book3S code to pltform/powernv/idle.c. But when doing so missed to add the per-thread LDBAR update in the core_woken path of the power9_idle_stop(). Patch fixes the same. Fixes: 10d91611f426 ("powerpc/64s: Reimplement book3s idle code in C") Cc: stable@vger.kernel.org # v5.2+ Signed-off-by: Athira Rajeev Signed-off-by: Madhavan Srinivasan Reviewed-by: Nicholas Piggin Signed-off-by: Michael Ellerman Link: https://lore.kernel.org/r/20190702105836.26695-1-maddy@linux.vnet.ibm.com --- arch/powerpc/platforms/powernv/idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/powernv/idle.c b/arch/powerpc/platforms/powernv/idle.c index f9ab89510766..210fb73a5121 100644 --- a/arch/powerpc/platforms/powernv/idle.c +++ b/arch/powerpc/platforms/powernv/idle.c @@ -762,7 +762,6 @@ static unsigned long power9_idle_stop(unsigned long psscr, bool mmu_on) mtspr(SPRN_PTCR, sprs.ptcr); mtspr(SPRN_RPR, sprs.rpr); mtspr(SPRN_TSCR, sprs.tscr); - mtspr(SPRN_LDBAR, sprs.ldbar); if (pls >= pnv_first_tb_loss_level) { /* TB loss */ @@ -794,6 +793,7 @@ core_woken: mtspr(SPRN_MMCR0, sprs.mmcr0); mtspr(SPRN_MMCR1, sprs.mmcr1); mtspr(SPRN_MMCR2, sprs.mmcr2); + mtspr(SPRN_LDBAR, sprs.ldbar); mtspr(SPRN_SPRG3, local_paca->sprg_vdso); -- cgit v1.2.3 From 1a271a68e030f3e134de12087117574a883e20f0 Mon Sep 17 00:00:00 2001 From: Christian Brauner Date: Sun, 14 Jul 2019 21:22:04 +0200 Subject: arch: mark syscall number 435 reserved for clone3 A while ago Arnd made it possible to give new system calls the same syscall number on all architectures (except alpha). To not break this nice new feature let's mark 435 for clone3 as reserved on all architectures that do not yet implement it. Even if an architecture does not plan to implement it this ensures that new system calls coming after clone3 will have the same number on all architectures. Signed-off-by: Christian Brauner Cc: linux-arch@vger.kernel.org Cc: linux-alpha@vger.kernel.org Cc: linux-kernel@vger.kernel.org Cc: linux-ia64@vger.kernel.org Cc: linux-m68k@lists.linux-m68k.org Cc: linux-mips@vger.kernel.org Cc: linux-parisc@vger.kernel.org Cc: linuxppc-dev@lists.ozlabs.org Cc: linux-s390@vger.kernel.org Cc: linux-sh@vger.kernel.org Cc: sparclinux@vger.kernel.org Link: https://lore.kernel.org/r/20190714192205.27190-2-christian@brauner.io Reviewed-by: Arnd Bergmann Signed-off-by: Christian Brauner --- arch/alpha/kernel/syscalls/syscall.tbl | 1 + arch/ia64/kernel/syscalls/syscall.tbl | 1 + arch/m68k/kernel/syscalls/syscall.tbl | 1 + arch/mips/kernel/syscalls/syscall_n32.tbl | 1 + arch/mips/kernel/syscalls/syscall_n64.tbl | 1 + arch/mips/kernel/syscalls/syscall_o32.tbl | 1 + arch/parisc/kernel/syscalls/syscall.tbl | 1 + arch/powerpc/kernel/syscalls/syscall.tbl | 1 + arch/s390/kernel/syscalls/syscall.tbl | 1 + arch/sh/kernel/syscalls/syscall.tbl | 1 + arch/sparc/kernel/syscalls/syscall.tbl | 1 + 11 files changed, 11 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/alpha/kernel/syscalls/syscall.tbl b/arch/alpha/kernel/syscalls/syscall.tbl index 1db9bbcfb84e..728fe028c02c 100644 --- a/arch/alpha/kernel/syscalls/syscall.tbl +++ b/arch/alpha/kernel/syscalls/syscall.tbl @@ -474,3 +474,4 @@ 542 common fsmount sys_fsmount 543 common fspick sys_fspick 544 common pidfd_open sys_pidfd_open +# 545 reserved for clone3 diff --git a/arch/ia64/kernel/syscalls/syscall.tbl b/arch/ia64/kernel/syscalls/syscall.tbl index ecc44926737b..36d5faf4c86c 100644 --- a/arch/ia64/kernel/syscalls/syscall.tbl +++ b/arch/ia64/kernel/syscalls/syscall.tbl @@ -355,3 +355,4 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open +# 435 reserved for clone3 diff --git a/arch/m68k/kernel/syscalls/syscall.tbl b/arch/m68k/kernel/syscalls/syscall.tbl index 9a3eb2558568..a88a285a0e5f 100644 --- a/arch/m68k/kernel/syscalls/syscall.tbl +++ b/arch/m68k/kernel/syscalls/syscall.tbl @@ -434,3 +434,4 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open +# 435 reserved for clone3 diff --git a/arch/mips/kernel/syscalls/syscall_n32.tbl b/arch/mips/kernel/syscalls/syscall_n32.tbl index 97035e19ad03..c9c879ec9b6d 100644 --- a/arch/mips/kernel/syscalls/syscall_n32.tbl +++ b/arch/mips/kernel/syscalls/syscall_n32.tbl @@ -373,3 +373,4 @@ 432 n32 fsmount sys_fsmount 433 n32 fspick sys_fspick 434 n32 pidfd_open sys_pidfd_open +# 435 reserved for clone3 diff --git a/arch/mips/kernel/syscalls/syscall_n64.tbl b/arch/mips/kernel/syscalls/syscall_n64.tbl index d7292722d3b0..bbce9159caa1 100644 --- a/arch/mips/kernel/syscalls/syscall_n64.tbl +++ b/arch/mips/kernel/syscalls/syscall_n64.tbl @@ -349,3 +349,4 @@ 432 n64 fsmount sys_fsmount 433 n64 fspick sys_fspick 434 n64 pidfd_open sys_pidfd_open +# 435 reserved for clone3 diff --git a/arch/mips/kernel/syscalls/syscall_o32.tbl b/arch/mips/kernel/syscalls/syscall_o32.tbl index dba084c92f14..9653591428ec 100644 --- a/arch/mips/kernel/syscalls/syscall_o32.tbl +++ b/arch/mips/kernel/syscalls/syscall_o32.tbl @@ -422,3 +422,4 @@ 432 o32 fsmount sys_fsmount 433 o32 fspick sys_fspick 434 o32 pidfd_open sys_pidfd_open +# 435 reserved for clone3 diff --git a/arch/parisc/kernel/syscalls/syscall.tbl b/arch/parisc/kernel/syscalls/syscall.tbl index 5022b9e179c2..c7aadfef5386 100644 --- a/arch/parisc/kernel/syscalls/syscall.tbl +++ b/arch/parisc/kernel/syscalls/syscall.tbl @@ -431,3 +431,4 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open +# 435 reserved for clone3 diff --git a/arch/powerpc/kernel/syscalls/syscall.tbl b/arch/powerpc/kernel/syscalls/syscall.tbl index f2c3bda2d39f..3331749aab20 100644 --- a/arch/powerpc/kernel/syscalls/syscall.tbl +++ b/arch/powerpc/kernel/syscalls/syscall.tbl @@ -516,3 +516,4 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open +# 435 reserved for clone3 diff --git a/arch/s390/kernel/syscalls/syscall.tbl b/arch/s390/kernel/syscalls/syscall.tbl index 6ebacfeaf853..a90d3e945445 100644 --- a/arch/s390/kernel/syscalls/syscall.tbl +++ b/arch/s390/kernel/syscalls/syscall.tbl @@ -437,3 +437,4 @@ 432 common fsmount sys_fsmount sys_fsmount 433 common fspick sys_fspick sys_fspick 434 common pidfd_open sys_pidfd_open sys_pidfd_open +# 435 reserved for clone3 diff --git a/arch/sh/kernel/syscalls/syscall.tbl b/arch/sh/kernel/syscalls/syscall.tbl index 834c9c7d79fa..b5ed26c4c005 100644 --- a/arch/sh/kernel/syscalls/syscall.tbl +++ b/arch/sh/kernel/syscalls/syscall.tbl @@ -437,3 +437,4 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open +# 435 reserved for clone3 diff --git a/arch/sparc/kernel/syscalls/syscall.tbl b/arch/sparc/kernel/syscalls/syscall.tbl index c58e71f21129..8c8cc7537fb2 100644 --- a/arch/sparc/kernel/syscalls/syscall.tbl +++ b/arch/sparc/kernel/syscalls/syscall.tbl @@ -480,3 +480,4 @@ 432 common fsmount sys_fsmount 433 common fspick sys_fspick 434 common pidfd_open sys_pidfd_open +# 435 reserved for clone3 -- cgit v1.2.3 From 0f472d04f59ff89d15b2a1c4eafde7317ddd67a2 Mon Sep 17 00:00:00 2001 From: Anshuman Khandual Date: Tue, 16 Jul 2019 16:27:33 -0700 Subject: mm/ioremap: probe platform for p4d huge map support Finish up what commit c2febafc6773 ("mm: convert generic code to 5-level paging") started while levelling up P4D huge mapping support at par with PUD and PMD. A new arch call back arch_ioremap_p4d_supported() is added which just maintains status quo (P4D huge map not supported) on x86, arm64 and powerpc. When HAVE_ARCH_HUGE_VMAP is enabled its just a simple check from the arch about the support, hence runtime effects are minimal. Link: http://lkml.kernel.org/r/1561699231-20991-1-git-send-email-anshuman.khandual@arm.com Signed-off-by: Anshuman Khandual Acked-by: Thomas Gleixner Acked-by: Michael Ellerman (powerpc) Cc: Catalin Marinas Cc: Will Deacon Cc: Dave Hansen Cc: Andy Lutomirski Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Kirill A. Shutemov Cc: Michal Hocko Cc: Stephen Rothwell Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm64/mm/mmu.c | 5 +++++ arch/powerpc/mm/book3s64/radix_pgtable.c | 5 +++++ arch/x86/mm/ioremap.c | 5 +++++ include/linux/io.h | 1 + lib/ioremap.c | 2 ++ 5 files changed, 18 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index 1b49c08dfa2b..e661469cabdd 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -942,6 +942,11 @@ void *__init fixmap_remap_fdt(phys_addr_t dt_phys) return dt_virt; } +int __init arch_ioremap_p4d_supported(void) +{ + return 0; +} + int __init arch_ioremap_pud_supported(void) { /* diff --git a/arch/powerpc/mm/book3s64/radix_pgtable.c b/arch/powerpc/mm/book3s64/radix_pgtable.c index 65c2ba1e1783..b4ca9e95e678 100644 --- a/arch/powerpc/mm/book3s64/radix_pgtable.c +++ b/arch/powerpc/mm/book3s64/radix_pgtable.c @@ -1237,3 +1237,8 @@ int radix__ioremap_range(unsigned long ea, phys_addr_t pa, unsigned long size, return 0; } } + +int __init arch_ioremap_p4d_supported(void) +{ + return 0; +} diff --git a/arch/x86/mm/ioremap.c b/arch/x86/mm/ioremap.c index e500f1df1140..63e99f15d7cf 100644 --- a/arch/x86/mm/ioremap.c +++ b/arch/x86/mm/ioremap.c @@ -459,6 +459,11 @@ void iounmap(volatile void __iomem *addr) } EXPORT_SYMBOL(iounmap); +int __init arch_ioremap_p4d_supported(void) +{ + return 0; +} + int __init arch_ioremap_pud_supported(void) { #ifdef CONFIG_X86_64 diff --git a/include/linux/io.h b/include/linux/io.h index 9876e5801a9d..accac822336a 100644 --- a/include/linux/io.h +++ b/include/linux/io.h @@ -33,6 +33,7 @@ static inline int ioremap_page_range(unsigned long addr, unsigned long end, #ifdef CONFIG_HAVE_ARCH_HUGE_VMAP void __init ioremap_huge_init(void); +int arch_ioremap_p4d_supported(void); int arch_ioremap_pud_supported(void); int arch_ioremap_pmd_supported(void); #else diff --git a/lib/ioremap.c b/lib/ioremap.c index a95161d9c883..0a2ffadc6d71 100644 --- a/lib/ioremap.c +++ b/lib/ioremap.c @@ -30,6 +30,8 @@ early_param("nohugeiomap", set_nohugeiomap); void __init ioremap_huge_init(void) { if (!ioremap_huge_disabled) { + if (arch_ioremap_p4d_supported()) + ioremap_p4d_capable = 1; if (arch_ioremap_pud_supported()) ioremap_pud_capable = 1; if (arch_ioremap_pmd_supported()) -- cgit v1.2.3 From b98cca444d287a63dd96df04af7fb9793567599e Mon Sep 17 00:00:00 2001 From: Anshuman Khandual Date: Tue, 16 Jul 2019 16:28:00 -0700 Subject: mm, kprobes: generalize and rename notify_page_fault() as kprobe_page_fault() Architectures which support kprobes have very similar boilerplate around calling kprobe_fault_handler(). Use a helper function in kprobes.h to unify them, based on the x86 code. This changes the behaviour for other architectures when preemption is enabled. Previously, they would have disabled preemption while calling the kprobe handler. However, preemption would be disabled if this fault was due to a kprobe, so we know the fault was not due to a kprobe handler and can simply return failure. This behaviour was introduced in commit a980c0ef9f6d ("x86/kprobes: Refactor kprobes_fault() like kprobe_exceptions_notify()") [anshuman.khandual@arm.com: export kprobe_fault_handler()] Link: http://lkml.kernel.org/r/1561133358-8876-1-git-send-email-anshuman.khandual@arm.com Link: http://lkml.kernel.org/r/1560420444-25737-1-git-send-email-anshuman.khandual@arm.com Signed-off-by: Anshuman Khandual Reviewed-by: Dave Hansen Cc: Michal Hocko Cc: Matthew Wilcox Cc: Mark Rutland Cc: Christophe Leroy Cc: Stephen Rothwell Cc: Andrey Konovalov Cc: Michael Ellerman Cc: Paul Mackerras Cc: Russell King Cc: Catalin Marinas Cc: Will Deacon Cc: Tony Luck Cc: Fenghua Yu Cc: Martin Schwidefsky Cc: Heiko Carstens Cc: Yoshinori Sato Cc: "David S. Miller" Cc: Thomas Gleixner Cc: Peter Zijlstra Cc: Ingo Molnar Cc: Andy Lutomirski Cc: Vineet Gupta Cc: James Hogan Cc: Paul Burton Cc: Ralf Baechle Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm/mm/fault.c | 24 +----------------------- arch/arm64/mm/fault.c | 24 +----------------------- arch/ia64/mm/fault.c | 24 +----------------------- arch/mips/include/asm/kprobes.h | 1 + arch/mips/kernel/kprobes.c | 2 +- arch/powerpc/mm/fault.c | 23 ++--------------------- arch/s390/mm/fault.c | 16 +--------------- arch/sh/mm/fault.c | 18 ++---------------- arch/sparc/mm/fault_64.c | 16 +--------------- arch/x86/mm/fault.c | 21 ++------------------- include/linux/kprobes.h | 19 +++++++++++++++++++ 11 files changed, 32 insertions(+), 156 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c index 0e417233dad7..890eeaac3cbb 100644 --- a/arch/arm/mm/fault.c +++ b/arch/arm/mm/fault.c @@ -27,28 +27,6 @@ #ifdef CONFIG_MMU -#ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr) -{ - int ret = 0; - - if (!user_mode(regs)) { - /* kprobe_running() needs smp_processor_id() */ - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, fsr)) - ret = 1; - preempt_enable(); - } - - return ret; -} -#else -static inline int notify_page_fault(struct pt_regs *regs, unsigned int fsr) -{ - return 0; -} -#endif - /* * This is useful to dump out the page tables associated with * 'addr' in mm 'mm'. @@ -265,7 +243,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs) vm_fault_t fault; unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; - if (notify_page_fault(regs, fsr)) + if (kprobe_page_fault(regs, fsr)) return 0; tsk = current; diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index c8c61b1eb479..9568c116ac7f 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -59,28 +59,6 @@ static inline const struct fault_info *esr_to_debug_fault_info(unsigned int esr) return debug_fault_info + DBG_ESR_EVT(esr); } -#ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) -{ - int ret = 0; - - /* kprobe_running() needs smp_processor_id() */ - if (!user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, esr)) - ret = 1; - preempt_enable(); - } - - return ret; -} -#else -static inline int notify_page_fault(struct pt_regs *regs, unsigned int esr) -{ - return 0; -} -#endif - static void data_abort_decode(unsigned int esr) { pr_alert("Data abort info:\n"); @@ -434,7 +412,7 @@ static int __kprobes do_page_fault(unsigned long addr, unsigned int esr, unsigned long vm_flags = VM_READ | VM_WRITE; unsigned int mm_flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; - if (notify_page_fault(regs, esr)) + if (kprobe_page_fault(regs, esr)) return 0; /* diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c index 3c3a283d3172..c2f299fe9e04 100644 --- a/arch/ia64/mm/fault.c +++ b/arch/ia64/mm/fault.c @@ -21,28 +21,6 @@ extern int die(char *, struct pt_regs *, long); -#ifdef CONFIG_KPROBES -static inline int notify_page_fault(struct pt_regs *regs, int trap) -{ - int ret = 0; - - if (!user_mode(regs)) { - /* kprobe_running() needs smp_processor_id() */ - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, trap)) - ret = 1; - preempt_enable(); - } - - return ret; -} -#else -static inline int notify_page_fault(struct pt_regs *regs, int trap) -{ - return 0; -} -#endif - /* * Return TRUE if ADDRESS points at a page in the kernel's mapped segment * (inside region 5, on ia64) and that page is present. @@ -116,7 +94,7 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re /* * This is to handle the kprobes on user space access instructions */ - if (notify_page_fault(regs, TRAP_BRKPT)) + if (kprobe_page_fault(regs, TRAP_BRKPT)) return; if (user_mode(regs)) diff --git a/arch/mips/include/asm/kprobes.h b/arch/mips/include/asm/kprobes.h index 3cf8e4d5fa28..68b1e5d458cf 100644 --- a/arch/mips/include/asm/kprobes.h +++ b/arch/mips/include/asm/kprobes.h @@ -41,6 +41,7 @@ do { \ #define kretprobe_blacklist_size 0 void arch_remove_kprobe(struct kprobe *p); +int kprobe_fault_handler(struct pt_regs *regs, int trapnr); /* Architecture specific copy of original instruction*/ struct arch_specific_insn { diff --git a/arch/mips/kernel/kprobes.c b/arch/mips/kernel/kprobes.c index 81ba1d3c367c..6cfae2411c04 100644 --- a/arch/mips/kernel/kprobes.c +++ b/arch/mips/kernel/kprobes.c @@ -398,7 +398,7 @@ out: return 1; } -static inline int kprobe_fault_handler(struct pt_regs *regs, int trapnr) +int kprobe_fault_handler(struct pt_regs *regs, int trapnr) { struct kprobe *cur = kprobe_running(); struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c index d989592b6fc8..8432c281de92 100644 --- a/arch/powerpc/mm/fault.c +++ b/arch/powerpc/mm/fault.c @@ -42,26 +42,6 @@ #include #include -static inline bool notify_page_fault(struct pt_regs *regs) -{ - bool ret = false; - -#ifdef CONFIG_KPROBES - /* kprobe_running() needs smp_processor_id() */ - if (!user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, 11)) - ret = true; - preempt_enable(); - } -#endif /* CONFIG_KPROBES */ - - if (unlikely(debugger_fault_handler(regs))) - ret = true; - - return ret; -} - /* * Check whether the instruction inst is a store using * an update addressing form which will update r1. @@ -461,8 +441,9 @@ static int __do_page_fault(struct pt_regs *regs, unsigned long address, int is_write = page_fault_is_write(error_code); vm_fault_t fault, major = 0; bool must_retry = false; + bool kprobe_fault = kprobe_page_fault(regs, 11); - if (notify_page_fault(regs)) + if (unlikely(debugger_fault_handler(regs) || kprobe_fault)) return 0; if (unlikely(page_fault_is_bad(error_code))) { diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c index 0ba174f779da..63507662828f 100644 --- a/arch/s390/mm/fault.c +++ b/arch/s390/mm/fault.c @@ -67,20 +67,6 @@ static int __init fault_init(void) } early_initcall(fault_init); -static inline int notify_page_fault(struct pt_regs *regs) -{ - int ret = 0; - - /* kprobe_running() needs smp_processor_id() */ - if (kprobes_built_in() && !user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, 14)) - ret = 1; - preempt_enable(); - } - return ret; -} - /* * Find out which address space caused the exception. */ @@ -412,7 +398,7 @@ static inline vm_fault_t do_exception(struct pt_regs *regs, int access) */ clear_pt_regs_flag(regs, PIF_PER_TRAP); - if (notify_page_fault(regs)) + if (kprobe_page_fault(regs, 14)) return 0; mm = tsk->mm; diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c index 3093bc372138..5f51456f4fc7 100644 --- a/arch/sh/mm/fault.c +++ b/arch/sh/mm/fault.c @@ -24,20 +24,6 @@ #include #include -static inline int notify_page_fault(struct pt_regs *regs, int trap) -{ - int ret = 0; - - if (kprobes_built_in() && !user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, trap)) - ret = 1; - preempt_enable(); - } - - return ret; -} - static void force_sig_info_fault(int si_signo, int si_code, unsigned long address) { @@ -412,14 +398,14 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs, if (unlikely(fault_in_kernel_space(address))) { if (vmalloc_fault(address) >= 0) return; - if (notify_page_fault(regs, vec)) + if (kprobe_page_fault(regs, vec)) return; bad_area_nosemaphore(regs, error_code, address); return; } - if (unlikely(notify_page_fault(regs, vec))) + if (unlikely(kprobe_page_fault(regs, vec))) return; /* Only enable interrupts if they were on before the fault */ diff --git a/arch/sparc/mm/fault_64.c b/arch/sparc/mm/fault_64.c index 83fda4d9c3b2..2371fb6b97e4 100644 --- a/arch/sparc/mm/fault_64.c +++ b/arch/sparc/mm/fault_64.c @@ -38,20 +38,6 @@ int show_unhandled_signals = 1; -static inline __kprobes int notify_page_fault(struct pt_regs *regs) -{ - int ret = 0; - - /* kprobe_running() needs smp_processor_id() */ - if (kprobes_built_in() && !user_mode(regs)) { - preempt_disable(); - if (kprobe_running() && kprobe_fault_handler(regs, 0)) - ret = 1; - preempt_enable(); - } - return ret; -} - static void __kprobes unhandled_fault(unsigned long address, struct task_struct *tsk, struct pt_regs *regs) @@ -285,7 +271,7 @@ asmlinkage void __kprobes do_sparc64_fault(struct pt_regs *regs) fault_code = get_thread_fault_code(); - if (notify_page_fault(regs)) + if (kprobe_page_fault(regs, 0)) goto exit_exception; si_code = SEGV_MAPERR; diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index 794f364cb882..d1634c59ed56 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -46,23 +46,6 @@ kmmio_fault(struct pt_regs *regs, unsigned long addr) return 0; } -static nokprobe_inline int kprobes_fault(struct pt_regs *regs) -{ - if (!kprobes_built_in()) - return 0; - if (user_mode(regs)) - return 0; - /* - * To be potentially processing a kprobe fault and to be allowed to call - * kprobe_running(), we have to be non-preemptible. - */ - if (preemptible()) - return 0; - if (!kprobe_running()) - return 0; - return kprobe_fault_handler(regs, X86_TRAP_PF); -} - /* * Prefetch quirks: * @@ -1282,7 +1265,7 @@ do_kern_addr_fault(struct pt_regs *regs, unsigned long hw_error_code, return; /* kprobes don't want to hook the spurious faults: */ - if (kprobes_fault(regs)) + if (kprobe_page_fault(regs, X86_TRAP_PF)) return; /* @@ -1313,7 +1296,7 @@ void do_user_addr_fault(struct pt_regs *regs, mm = tsk->mm; /* kprobes don't want to hook the spurious faults: */ - if (unlikely(kprobes_fault(regs))) + if (unlikely(kprobe_page_fault(regs, X86_TRAP_PF))) return; /* diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h index 443d9800ca3f..04bdaf01112c 100644 --- a/include/linux/kprobes.h +++ b/include/linux/kprobes.h @@ -458,4 +458,23 @@ static inline bool is_kprobe_optinsn_slot(unsigned long addr) } #endif +/* Returns true if kprobes handled the fault */ +static nokprobe_inline bool kprobe_page_fault(struct pt_regs *regs, + unsigned int trap) +{ + if (!kprobes_built_in()) + return false; + if (user_mode(regs)) + return false; + /* + * To be potentially processing a kprobe fault and to be allowed + * to call kprobe_running(), we have to be non-preemptible. + */ + if (preemptible()) + return false; + if (!kprobe_running()) + return false; + return kprobe_fault_handler(regs, trap); +} + #endif /* _LINUX_KPROBES_H */ -- cgit v1.2.3 From f296f1df6e0e5b17654709c05b1821a1b58d329f Mon Sep 17 00:00:00 2001 From: "Dmitry V. Levin" Date: Tue, 16 Jul 2019 16:29:39 -0700 Subject: powerpc: define syscall_get_error() syscall_get_error() is required to be implemented on this architecture in addition to already implemented syscall_get_nr(), syscall_get_arguments(), syscall_get_return_value(), and syscall_get_arch() functions in order to extend the generic ptrace API with PTRACE_GET_SYSCALL_INFO request. Link: http://lkml.kernel.org/r/20190510152824.GE28558@altlinux.org Signed-off-by: Dmitry V. Levin Acked-by: Michael Ellerman Cc: Elvira Khabirova Cc: Eugene Syromyatnikov Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Oleg Nesterov Cc: Andy Lutomirski Cc: Greentime Hu Cc: Helge Deller [parisc] Cc: James E.J. Bottomley Cc: James Hogan Cc: kbuild test robot Cc: Kees Cook Cc: Paul Burton Cc: Ralf Baechle Cc: Richard Kuo Cc: Shuah Khan Cc: Vincent Chen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/include/asm/syscall.h | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/asm/syscall.h b/arch/powerpc/include/asm/syscall.h index 81abcf6a737b..38d62acfdce7 100644 --- a/arch/powerpc/include/asm/syscall.h +++ b/arch/powerpc/include/asm/syscall.h @@ -35,6 +35,16 @@ static inline void syscall_rollback(struct task_struct *task, regs->gpr[3] = regs->orig_gpr3; } +static inline long syscall_get_error(struct task_struct *task, + struct pt_regs *regs) +{ + /* + * If the system call failed, + * regs->gpr[3] contains a positive ERRORCODE. + */ + return (regs->ccr & 0x10000000UL) ? -regs->gpr[3] : 0; +} + static inline long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs) { -- cgit v1.2.3 From 8aa3c927ec10d1230c3ace8357f624479665f701 Mon Sep 17 00:00:00 2001 From: "Aneesh Kumar K.V" Date: Tue, 16 Jul 2019 16:30:41 -0700 Subject: mm/mmap: move common defines to mman-common.h Two architecture that use arch specific MMAP flags are powerpc and sparc. We still have few flag values common across them and other architectures. Consolidate this in mman-common.h. Also update the comment to indicate where to find HugeTLB specific reserved values Link: http://lkml.kernel.org/r/20190604090950.31417-1-aneesh.kumar@linux.ibm.com Signed-off-by: Aneesh Kumar K.V Reviewed-by: Andrew Morton Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/include/uapi/asm/mman.h | 6 +----- arch/sparc/include/uapi/asm/mman.h | 6 ------ include/uapi/asm-generic/mman-common.h | 6 +++++- include/uapi/asm-generic/mman.h | 9 ++++----- 4 files changed, 10 insertions(+), 17 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/include/uapi/asm/mman.h b/arch/powerpc/include/uapi/asm/mman.h index 65065ce32814..c0c737215b00 100644 --- a/arch/powerpc/include/uapi/asm/mman.h +++ b/arch/powerpc/include/uapi/asm/mman.h @@ -21,15 +21,11 @@ #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ + #define MCL_CURRENT 0x2000 /* lock all currently mapped pages */ #define MCL_FUTURE 0x4000 /* lock all additions to address space */ #define MCL_ONFAULT 0x8000 /* lock all pages that are faulted in */ -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ -#define MAP_HUGETLB 0x40000 /* create a huge page mapping */ - /* Override any generic PKEY permission defines */ #define PKEY_DISABLE_EXECUTE 0x4 #undef PKEY_ACCESS_MASK diff --git a/arch/sparc/include/uapi/asm/mman.h b/arch/sparc/include/uapi/asm/mman.h index f6f99ec65bb3..cec9f4109687 100644 --- a/arch/sparc/include/uapi/asm/mman.h +++ b/arch/sparc/include/uapi/asm/mman.h @@ -22,10 +22,4 @@ #define MCL_FUTURE 0x4000 /* lock all additions to address space */ #define MCL_ONFAULT 0x8000 /* lock all pages that are faulted in */ -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ -#define MAP_HUGETLB 0x40000 /* create a huge page mapping */ - - #endif /* _UAPI__SPARC_MMAN_H__ */ diff --git a/include/uapi/asm-generic/mman-common.h b/include/uapi/asm-generic/mman-common.h index 93a8b420ce1e..63b1f506ea67 100644 --- a/include/uapi/asm-generic/mman-common.h +++ b/include/uapi/asm-generic/mman-common.h @@ -20,7 +20,11 @@ #define MAP_FIXED 0x10 /* Interpret addr exactly */ #define MAP_ANONYMOUS 0x20 /* don't use a file */ -/* 0x0100 - 0x40000 flags are defined in asm-generic/mman.h */ +/* 0x0100 - 0x4000 flags are defined in asm-generic/mman.h */ +#define MAP_POPULATE 0x008000 /* populate (prefault) pagetables */ +#define MAP_NONBLOCK 0x010000 /* do not block on IO */ +#define MAP_STACK 0x020000 /* give out an address that is best suited for process/thread stacks */ +#define MAP_HUGETLB 0x040000 /* create a huge page mapping */ #define MAP_SYNC 0x080000 /* perform synchronous page faults for the mapping */ #define MAP_FIXED_NOREPLACE 0x100000 /* MAP_FIXED which doesn't unmap underlying mapping */ diff --git a/include/uapi/asm-generic/mman.h b/include/uapi/asm-generic/mman.h index 2dffcbf705b3..57e8195d0b53 100644 --- a/include/uapi/asm-generic/mman.h +++ b/include/uapi/asm-generic/mman.h @@ -9,12 +9,11 @@ #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ #define MAP_LOCKED 0x2000 /* pages are locked */ #define MAP_NORESERVE 0x4000 /* don't check for reservations */ -#define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ -#define MAP_NONBLOCK 0x10000 /* do not block on IO */ -#define MAP_STACK 0x20000 /* give out an address that is best suited for process/thread stacks */ -#define MAP_HUGETLB 0x40000 /* create a huge page mapping */ -/* Bits [26:31] are reserved, see mman-common.h for MAP_HUGETLB usage */ +/* + * Bits [26:31] are reserved, see asm-generic/hugetlb_encode.h + * for MAP_HUGETLB usage + */ #define MCL_CURRENT 1 /* lock all current mappings */ #define MCL_FUTURE 2 /* lock all future mappings */ -- cgit v1.2.3 From 175967318c3018d01931ac950c82adab5deb47ca Mon Sep 17 00:00:00 2001 From: Robin Murphy Date: Tue, 16 Jul 2019 16:30:47 -0700 Subject: mm: introduce ARCH_HAS_PTE_DEVMAP ARCH_HAS_ZONE_DEVICE is somewhat meaningless in itself, and combined with the long-out-of-date comment can lead to the impression than an architecture may just enable it (since __add_pages() now "comprehends device memory" for itself) and expect things to work. In practice, however, ZONE_DEVICE users have little chance of functioning correctly without __HAVE_ARCH_PTE_DEVMAP, so let's clean that up the same way as ARCH_HAS_PTE_SPECIAL and make it the proper dependency so the real situation is clearer. Link: http://lkml.kernel.org/r/87554aa78478a02a63f2c4cf60a847279ae3eb3b.1558547956.git.robin.murphy@arm.com Signed-off-by: Robin Murphy Acked-by: Dan Williams Reviewed-by: Ira Weiny Acked-by: Oliver O'Halloran Reviewed-by: Anshuman Khandual Cc: Michael Ellerman Cc: Catalin Marinas Cc: David Hildenbrand Cc: Jerome Glisse Cc: Michal Hocko Cc: Will Deacon Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/Kconfig | 2 +- arch/powerpc/include/asm/book3s/64/pgtable.h | 1 - arch/x86/Kconfig | 2 +- arch/x86/include/asm/pgtable.h | 4 ++-- arch/x86/include/asm/pgtable_types.h | 1 - include/linux/mm.h | 4 ++-- include/linux/pfn_t.h | 4 ++-- mm/Kconfig | 5 ++--- mm/gup.c | 2 +- 9 files changed, 11 insertions(+), 14 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig index f516796dd819..d8dcd8820369 100644 --- a/arch/powerpc/Kconfig +++ b/arch/powerpc/Kconfig @@ -129,6 +129,7 @@ config PPC select ARCH_HAS_MMIOWB if PPC64 select ARCH_HAS_PHYS_TO_DMA select ARCH_HAS_PMEM_API if PPC64 + select ARCH_HAS_PTE_DEVMAP if PPC_BOOK3S_64 select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_MEMBARRIER_CALLBACKS select ARCH_HAS_SCALED_CPUTIME if VIRT_CPU_ACCOUNTING_NATIVE && PPC64 @@ -136,7 +137,6 @@ config PPC select ARCH_HAS_TICK_BROADCAST if GENERIC_CLOCKEVENTS_BROADCAST select ARCH_HAS_UACCESS_FLUSHCACHE if PPC64 select ARCH_HAS_UBSAN_SANITIZE_ALL - select ARCH_HAS_ZONE_DEVICE if PPC_BOOK3S_64 select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_KEEP_MEMBLOCK select ARCH_MIGHT_HAVE_PC_PARPORT diff --git a/arch/powerpc/include/asm/book3s/64/pgtable.h b/arch/powerpc/include/asm/book3s/64/pgtable.h index 62e6ea0a7650..8308f32e9782 100644 --- a/arch/powerpc/include/asm/book3s/64/pgtable.h +++ b/arch/powerpc/include/asm/book3s/64/pgtable.h @@ -90,7 +90,6 @@ #define _PAGE_SOFT_DIRTY _RPAGE_SW3 /* software: software dirty tracking */ #define _PAGE_SPECIAL _RPAGE_SW2 /* software: special page */ #define _PAGE_DEVMAP _RPAGE_SW1 /* software: ZONE_DEVICE page */ -#define __HAVE_ARCH_PTE_DEVMAP /* * Drivers request for cache inhibited pte mapping using _PAGE_NO_CACHE diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 879741336771..4a55bd01e918 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig @@ -70,6 +70,7 @@ config X86 select ARCH_HAS_KCOV if X86_64 select ARCH_HAS_MEMBARRIER_SYNC_CORE select ARCH_HAS_PMEM_API if X86_64 + select ARCH_HAS_PTE_DEVMAP if X86_64 select ARCH_HAS_PTE_SPECIAL select ARCH_HAS_REFCOUNT select ARCH_HAS_UACCESS_FLUSHCACHE if X86_64 @@ -80,7 +81,6 @@ config X86 select ARCH_HAS_STRICT_MODULE_RWX select ARCH_HAS_SYNC_CORE_BEFORE_USERMODE select ARCH_HAS_UBSAN_SANITIZE_ALL - select ARCH_HAS_ZONE_DEVICE if X86_64 select ARCH_HAVE_NMI_SAFE_CMPXCHG select ARCH_MIGHT_HAVE_ACPI_PDC if ACPI select ARCH_MIGHT_HAVE_PC_PARPORT diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index 5e0509b41986..0bc530c4eb13 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -271,7 +271,7 @@ static inline int has_transparent_hugepage(void) return boot_cpu_has(X86_FEATURE_PSE); } -#ifdef __HAVE_ARCH_PTE_DEVMAP +#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP static inline int pmd_devmap(pmd_t pmd) { return !!(pmd_val(pmd) & _PAGE_DEVMAP); @@ -732,7 +732,7 @@ static inline int pte_present(pte_t a) return pte_flags(a) & (_PAGE_PRESENT | _PAGE_PROTNONE); } -#ifdef __HAVE_ARCH_PTE_DEVMAP +#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP static inline int pte_devmap(pte_t a) { return (pte_flags(a) & _PAGE_DEVMAP) == _PAGE_DEVMAP; diff --git a/arch/x86/include/asm/pgtable_types.h b/arch/x86/include/asm/pgtable_types.h index d6ff0bbdb394..b5e49e6bac63 100644 --- a/arch/x86/include/asm/pgtable_types.h +++ b/arch/x86/include/asm/pgtable_types.h @@ -103,7 +103,6 @@ #if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE) #define _PAGE_NX (_AT(pteval_t, 1) << _PAGE_BIT_NX) #define _PAGE_DEVMAP (_AT(u64, 1) << _PAGE_BIT_DEVMAP) -#define __HAVE_ARCH_PTE_DEVMAP #else #define _PAGE_NX (_AT(pteval_t, 0)) #define _PAGE_DEVMAP (_AT(pteval_t, 0)) diff --git a/include/linux/mm.h b/include/linux/mm.h index baa8b8761d8c..f43f4de4de68 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -547,7 +547,7 @@ static inline void vma_set_anonymous(struct vm_area_struct *vma) struct mmu_gather; struct inode; -#if !defined(__HAVE_ARCH_PTE_DEVMAP) || !defined(CONFIG_TRANSPARENT_HUGEPAGE) +#if !defined(CONFIG_ARCH_HAS_PTE_DEVMAP) || !defined(CONFIG_TRANSPARENT_HUGEPAGE) static inline int pmd_devmap(pmd_t pmd) { return 0; @@ -1750,7 +1750,7 @@ static inline void sync_mm_rss(struct mm_struct *mm) } #endif -#ifndef __HAVE_ARCH_PTE_DEVMAP +#ifndef CONFIG_ARCH_HAS_PTE_DEVMAP static inline int pte_devmap(pte_t pte) { return 0; diff --git a/include/linux/pfn_t.h b/include/linux/pfn_t.h index 01e8037023f7..2d9148221e9a 100644 --- a/include/linux/pfn_t.h +++ b/include/linux/pfn_t.h @@ -97,7 +97,7 @@ static inline pud_t pfn_t_pud(pfn_t pfn, pgprot_t pgprot) #endif #endif -#ifdef __HAVE_ARCH_PTE_DEVMAP +#ifdef CONFIG_ARCH_HAS_PTE_DEVMAP static inline bool pfn_t_devmap(pfn_t pfn) { const u64 flags = PFN_DEV|PFN_MAP; @@ -115,7 +115,7 @@ pmd_t pmd_mkdevmap(pmd_t pmd); defined(CONFIG_HAVE_ARCH_TRANSPARENT_HUGEPAGE_PUD) pud_t pud_mkdevmap(pud_t pud); #endif -#endif /* __HAVE_ARCH_PTE_DEVMAP */ +#endif /* CONFIG_ARCH_HAS_PTE_DEVMAP */ #ifdef CONFIG_ARCH_HAS_PTE_SPECIAL static inline bool pfn_t_special(pfn_t pfn) diff --git a/mm/Kconfig b/mm/Kconfig index 495d7368ced8..56cec636a1fc 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -649,8 +649,7 @@ config IDLE_PAGE_TRACKING See Documentation/admin-guide/mm/idle_page_tracking.rst for more details. -# arch_add_memory() comprehends device memory -config ARCH_HAS_ZONE_DEVICE +config ARCH_HAS_PTE_DEVMAP bool config ZONE_DEVICE @@ -658,7 +657,7 @@ config ZONE_DEVICE depends on MEMORY_HOTPLUG depends on MEMORY_HOTREMOVE depends on SPARSEMEM_VMEMMAP - depends on ARCH_HAS_ZONE_DEVICE + depends on ARCH_HAS_PTE_DEVMAP select XARRAY_MULTI help diff --git a/mm/gup.c b/mm/gup.c index 8bbaa5523116..98f13ab37bac 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1895,7 +1895,7 @@ static int gup_pte_range(pmd_t pmd, unsigned long addr, unsigned long end, } #endif /* CONFIG_ARCH_HAS_PTE_SPECIAL */ -#if defined(__HAVE_ARCH_PTE_DEVMAP) && defined(CONFIG_TRANSPARENT_HUGEPAGE) +#if defined(CONFIG_ARCH_HAS_PTE_DEVMAP) && defined(CONFIG_TRANSPARENT_HUGEPAGE) static int __gup_device_huge(unsigned long pfn, unsigned long addr, unsigned long end, struct page **pages, int *nr) { -- cgit v1.2.3 From 79eb597cba06c435b72f220e9d426ae413fc2579 Mon Sep 17 00:00:00 2001 From: Daniel Jordan Date: Tue, 16 Jul 2019 16:30:54 -0700 Subject: mm: add account_locked_vm utility function locked_vm accounting is done roughly the same way in five places, so unify them in a helper. Include the helper's caller in the debug print to distinguish between callsites. Error codes stay the same, so user-visible behavior does too. The one exception is that the -EPERM case in tce_account_locked_vm is removed because Alexey has never seen it triggered. [daniel.m.jordan@oracle.com: v3] Link: http://lkml.kernel.org/r/20190529205019.20927-1-daniel.m.jordan@oracle.com [sfr@canb.auug.org.au: fix mm/util.c] Link: http://lkml.kernel.org/r/20190524175045.26897-1-daniel.m.jordan@oracle.com Signed-off-by: Daniel Jordan Signed-off-by: Stephen Rothwell Tested-by: Alexey Kardashevskiy Acked-by: Alex Williamson Cc: Alan Tull Cc: Alex Williamson Cc: Benjamin Herrenschmidt Cc: Christoph Lameter Cc: Christophe Leroy Cc: Davidlohr Bueso Cc: Jason Gunthorpe Cc: Mark Rutland Cc: Michael Ellerman Cc: Moritz Fischer Cc: Paul Mackerras Cc: Steve Sistare Cc: Wu Hao Cc: Ira Weiny Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/kvm/book3s_64_vio.c | 44 ++------------------- arch/powerpc/mm/book3s64/iommu_api.c | 41 ++------------------ drivers/fpga/dfl-afu-dma-region.c | 53 ++----------------------- drivers/vfio/vfio_iommu_spapr_tce.c | 54 +++----------------------- drivers/vfio/vfio_iommu_type1.c | 17 +------- include/linux/mm.h | 4 ++ mm/util.c | 75 ++++++++++++++++++++++++++++++++++++ 7 files changed, 98 insertions(+), 190 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/kvm/book3s_64_vio.c b/arch/powerpc/kvm/book3s_64_vio.c index 5bf05cc774e2..e99a14798ab0 100644 --- a/arch/powerpc/kvm/book3s_64_vio.c +++ b/arch/powerpc/kvm/book3s_64_vio.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -45,43 +46,6 @@ static unsigned long kvmppc_stt_pages(unsigned long tce_pages) return tce_pages + ALIGN(stt_bytes, PAGE_SIZE) / PAGE_SIZE; } -static long kvmppc_account_memlimit(unsigned long stt_pages, bool inc) -{ - long ret = 0; - - if (!current || !current->mm) - return ret; /* process exited */ - - down_write(¤t->mm->mmap_sem); - - if (inc) { - unsigned long locked, lock_limit; - - locked = current->mm->locked_vm + stt_pages; - lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; - if (locked > lock_limit && !capable(CAP_IPC_LOCK)) - ret = -ENOMEM; - else - current->mm->locked_vm += stt_pages; - } else { - if (WARN_ON_ONCE(stt_pages > current->mm->locked_vm)) - stt_pages = current->mm->locked_vm; - - current->mm->locked_vm -= stt_pages; - } - - pr_debug("[%d] RLIMIT_MEMLOCK KVM %c%ld %ld/%ld%s\n", current->pid, - inc ? '+' : '-', - stt_pages << PAGE_SHIFT, - current->mm->locked_vm << PAGE_SHIFT, - rlimit(RLIMIT_MEMLOCK), - ret ? " - exceeded" : ""); - - up_write(¤t->mm->mmap_sem); - - return ret; -} - static void kvm_spapr_tce_iommu_table_free(struct rcu_head *head) { struct kvmppc_spapr_tce_iommu_table *stit = container_of(head, @@ -291,7 +255,7 @@ static int kvm_spapr_tce_release(struct inode *inode, struct file *filp) kvm_put_kvm(stt->kvm); - kvmppc_account_memlimit( + account_locked_vm(current->mm, kvmppc_stt_pages(kvmppc_tce_pages(stt->size)), false); call_rcu(&stt->rcu, release_spapr_tce_table); @@ -316,7 +280,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, return -EINVAL; npages = kvmppc_tce_pages(size); - ret = kvmppc_account_memlimit(kvmppc_stt_pages(npages), true); + ret = account_locked_vm(current->mm, kvmppc_stt_pages(npages), true); if (ret) return ret; @@ -362,7 +326,7 @@ long kvm_vm_ioctl_create_spapr_tce(struct kvm *kvm, kfree(stt); fail_acct: - kvmppc_account_memlimit(kvmppc_stt_pages(npages), false); + account_locked_vm(current->mm, kvmppc_stt_pages(npages), false); return ret; } diff --git a/arch/powerpc/mm/book3s64/iommu_api.c b/arch/powerpc/mm/book3s64/iommu_api.c index 90ee3a89722c..b056cae3388b 100644 --- a/arch/powerpc/mm/book3s64/iommu_api.c +++ b/arch/powerpc/mm/book3s64/iommu_api.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -46,40 +47,6 @@ struct mm_iommu_table_group_mem_t { u64 dev_hpa; /* Device memory base address */ }; -static long mm_iommu_adjust_locked_vm(struct mm_struct *mm, - unsigned long npages, bool incr) -{ - long ret = 0, locked, lock_limit; - - if (!npages) - return 0; - - down_write(&mm->mmap_sem); - - if (incr) { - locked = mm->locked_vm + npages; - lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; - if (locked > lock_limit && !capable(CAP_IPC_LOCK)) - ret = -ENOMEM; - else - mm->locked_vm += npages; - } else { - if (WARN_ON_ONCE(npages > mm->locked_vm)) - npages = mm->locked_vm; - mm->locked_vm -= npages; - } - - pr_debug("[%d] RLIMIT_MEMLOCK HASH64 %c%ld %ld/%ld\n", - current ? current->pid : 0, - incr ? '+' : '-', - npages << PAGE_SHIFT, - mm->locked_vm << PAGE_SHIFT, - rlimit(RLIMIT_MEMLOCK)); - up_write(&mm->mmap_sem); - - return ret; -} - bool mm_iommu_preregistered(struct mm_struct *mm) { return !list_empty(&mm->context.iommu_group_mem_list); @@ -96,7 +63,7 @@ static long mm_iommu_do_alloc(struct mm_struct *mm, unsigned long ua, unsigned long entry, chunk; if (dev_hpa == MM_IOMMU_TABLE_INVALID_HPA) { - ret = mm_iommu_adjust_locked_vm(mm, entries, true); + ret = account_locked_vm(mm, entries, true); if (ret) return ret; @@ -211,7 +178,7 @@ free_exit: kfree(mem); unlock_exit: - mm_iommu_adjust_locked_vm(mm, locked_entries, false); + account_locked_vm(mm, locked_entries, false); return ret; } @@ -311,7 +278,7 @@ long mm_iommu_put(struct mm_struct *mm, struct mm_iommu_table_group_mem_t *mem) unlock_exit: mutex_unlock(&mem_list_mutex); - mm_iommu_adjust_locked_vm(mm, unlock_entries, false); + account_locked_vm(mm, unlock_entries, false); return ret; } diff --git a/drivers/fpga/dfl-afu-dma-region.c b/drivers/fpga/dfl-afu-dma-region.c index dcd80b088c7b..62f924489db5 100644 --- a/drivers/fpga/dfl-afu-dma-region.c +++ b/drivers/fpga/dfl-afu-dma-region.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "dfl-afu.h" @@ -31,52 +32,6 @@ void afu_dma_region_init(struct dfl_feature_platform_data *pdata) afu->dma_regions = RB_ROOT; } -/** - * afu_dma_adjust_locked_vm - adjust locked memory - * @dev: port device - * @npages: number of pages - * @incr: increase or decrease locked memory - * - * Increase or decrease the locked memory size with npages input. - * - * Return 0 on success. - * Return -ENOMEM if locked memory size is over the limit and no CAP_IPC_LOCK. - */ -static int afu_dma_adjust_locked_vm(struct device *dev, long npages, bool incr) -{ - unsigned long locked, lock_limit; - int ret = 0; - - /* the task is exiting. */ - if (!current->mm) - return 0; - - down_write(¤t->mm->mmap_sem); - - if (incr) { - locked = current->mm->locked_vm + npages; - lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; - - if (locked > lock_limit && !capable(CAP_IPC_LOCK)) - ret = -ENOMEM; - else - current->mm->locked_vm += npages; - } else { - if (WARN_ON_ONCE(npages > current->mm->locked_vm)) - npages = current->mm->locked_vm; - current->mm->locked_vm -= npages; - } - - dev_dbg(dev, "[%d] RLIMIT_MEMLOCK %c%ld %ld/%ld%s\n", current->pid, - incr ? '+' : '-', npages << PAGE_SHIFT, - current->mm->locked_vm << PAGE_SHIFT, rlimit(RLIMIT_MEMLOCK), - ret ? "- exceeded" : ""); - - up_write(¤t->mm->mmap_sem); - - return ret; -} - /** * afu_dma_pin_pages - pin pages of given dma memory region * @pdata: feature device platform data @@ -92,7 +47,7 @@ static int afu_dma_pin_pages(struct dfl_feature_platform_data *pdata, struct device *dev = &pdata->dev->dev; int ret, pinned; - ret = afu_dma_adjust_locked_vm(dev, npages, true); + ret = account_locked_vm(current->mm, npages, true); if (ret) return ret; @@ -121,7 +76,7 @@ put_pages: free_pages: kfree(region->pages); unlock_vm: - afu_dma_adjust_locked_vm(dev, npages, false); + account_locked_vm(current->mm, npages, false); return ret; } @@ -141,7 +96,7 @@ static void afu_dma_unpin_pages(struct dfl_feature_platform_data *pdata, put_all_pages(region->pages, npages); kfree(region->pages); - afu_dma_adjust_locked_vm(dev, npages, false); + account_locked_vm(current->mm, npages, false); dev_dbg(dev, "%ld pages unpinned\n", npages); } diff --git a/drivers/vfio/vfio_iommu_spapr_tce.c b/drivers/vfio/vfio_iommu_spapr_tce.c index 7048c9198c21..8ce9ad21129f 100644 --- a/drivers/vfio/vfio_iommu_spapr_tce.c +++ b/drivers/vfio/vfio_iommu_spapr_tce.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include @@ -31,51 +32,6 @@ static void tce_iommu_detach_group(void *iommu_data, struct iommu_group *iommu_group); -static long try_increment_locked_vm(struct mm_struct *mm, long npages) -{ - long ret = 0, locked, lock_limit; - - if (WARN_ON_ONCE(!mm)) - return -EPERM; - - if (!npages) - return 0; - - down_write(&mm->mmap_sem); - locked = mm->locked_vm + npages; - lock_limit = rlimit(RLIMIT_MEMLOCK) >> PAGE_SHIFT; - if (locked > lock_limit && !capable(CAP_IPC_LOCK)) - ret = -ENOMEM; - else - mm->locked_vm += npages; - - pr_debug("[%d] RLIMIT_MEMLOCK +%ld %ld/%ld%s\n", current->pid, - npages << PAGE_SHIFT, - mm->locked_vm << PAGE_SHIFT, - rlimit(RLIMIT_MEMLOCK), - ret ? " - exceeded" : ""); - - up_write(&mm->mmap_sem); - - return ret; -} - -static void decrement_locked_vm(struct mm_struct *mm, long npages) -{ - if (!mm || !npages) - return; - - down_write(&mm->mmap_sem); - if (WARN_ON_ONCE(npages > mm->locked_vm)) - npages = mm->locked_vm; - mm->locked_vm -= npages; - pr_debug("[%d] RLIMIT_MEMLOCK -%ld %ld/%ld\n", current->pid, - npages << PAGE_SHIFT, - mm->locked_vm << PAGE_SHIFT, - rlimit(RLIMIT_MEMLOCK)); - up_write(&mm->mmap_sem); -} - /* * VFIO IOMMU fd for SPAPR_TCE IOMMU implementation * @@ -333,7 +289,7 @@ static int tce_iommu_enable(struct tce_container *container) return ret; locked = table_group->tce32_size >> PAGE_SHIFT; - ret = try_increment_locked_vm(container->mm, locked); + ret = account_locked_vm(container->mm, locked, true); if (ret) return ret; @@ -352,7 +308,7 @@ static void tce_iommu_disable(struct tce_container *container) container->enabled = false; BUG_ON(!container->mm); - decrement_locked_vm(container->mm, container->locked_pages); + account_locked_vm(container->mm, container->locked_pages, false); } static void *tce_iommu_open(unsigned long arg) @@ -656,7 +612,7 @@ static long tce_iommu_create_table(struct tce_container *container, if (!table_size) return -EINVAL; - ret = try_increment_locked_vm(container->mm, table_size >> PAGE_SHIFT); + ret = account_locked_vm(container->mm, table_size >> PAGE_SHIFT, true); if (ret) return ret; @@ -675,7 +631,7 @@ static void tce_iommu_free_table(struct tce_container *container, unsigned long pages = tbl->it_allocated_size >> PAGE_SHIFT; iommu_tce_table_put(tbl); - decrement_locked_vm(container->mm, pages); + account_locked_vm(container->mm, pages, false); } static long tce_iommu_create_window(struct tce_container *container, diff --git a/drivers/vfio/vfio_iommu_type1.c b/drivers/vfio/vfio_iommu_type1.c index add34adfadc7..054391f30fa8 100644 --- a/drivers/vfio/vfio_iommu_type1.c +++ b/drivers/vfio/vfio_iommu_type1.c @@ -272,21 +272,8 @@ static int vfio_lock_acct(struct vfio_dma *dma, long npage, bool async) ret = down_write_killable(&mm->mmap_sem); if (!ret) { - if (npage > 0) { - if (!dma->lock_cap) { - unsigned long limit; - - limit = task_rlimit(dma->task, - RLIMIT_MEMLOCK) >> PAGE_SHIFT; - - if (mm->locked_vm + npage > limit) - ret = -ENOMEM; - } - } - - if (!ret) - mm->locked_vm += npage; - + ret = __account_locked_vm(mm, abs(npage), npage > 0, dma->task, + dma->lock_cap); up_write(&mm->mmap_sem); } diff --git a/include/linux/mm.h b/include/linux/mm.h index f43f4de4de68..bd6512559bed 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -1543,6 +1543,10 @@ long get_user_pages_unlocked(unsigned long start, unsigned long nr_pages, int get_user_pages_fast(unsigned long start, int nr_pages, unsigned int gup_flags, struct page **pages); +int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc); +int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc, + struct task_struct *task, bool bypass_rlim); + /* Container for pinned pfns / pages */ struct frame_vector { unsigned int nr_allocated; /* Number of frames we have space for */ diff --git a/mm/util.c b/mm/util.c index 68575a315dc5..e6351a80f248 100644 --- a/mm/util.c +++ b/mm/util.c @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -300,6 +301,80 @@ void arch_pick_mmap_layout(struct mm_struct *mm, struct rlimit *rlim_stack) } #endif +/** + * __account_locked_vm - account locked pages to an mm's locked_vm + * @mm: mm to account against + * @pages: number of pages to account + * @inc: %true if @pages should be considered positive, %false if not + * @task: task used to check RLIMIT_MEMLOCK + * @bypass_rlim: %true if checking RLIMIT_MEMLOCK should be skipped + * + * Assumes @task and @mm are valid (i.e. at least one reference on each), and + * that mmap_sem is held as writer. + * + * Return: + * * 0 on success + * * -ENOMEM if RLIMIT_MEMLOCK would be exceeded. + */ +int __account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc, + struct task_struct *task, bool bypass_rlim) +{ + unsigned long locked_vm, limit; + int ret = 0; + + lockdep_assert_held_write(&mm->mmap_sem); + + locked_vm = mm->locked_vm; + if (inc) { + if (!bypass_rlim) { + limit = task_rlimit(task, RLIMIT_MEMLOCK) >> PAGE_SHIFT; + if (locked_vm + pages > limit) + ret = -ENOMEM; + } + if (!ret) + mm->locked_vm = locked_vm + pages; + } else { + WARN_ON_ONCE(pages > locked_vm); + mm->locked_vm = locked_vm - pages; + } + + pr_debug("%s: [%d] caller %ps %c%lu %lu/%lu%s\n", __func__, task->pid, + (void *)_RET_IP_, (inc) ? '+' : '-', pages << PAGE_SHIFT, + locked_vm << PAGE_SHIFT, task_rlimit(task, RLIMIT_MEMLOCK), + ret ? " - exceeded" : ""); + + return ret; +} +EXPORT_SYMBOL_GPL(__account_locked_vm); + +/** + * account_locked_vm - account locked pages to an mm's locked_vm + * @mm: mm to account against, may be NULL + * @pages: number of pages to account + * @inc: %true if @pages should be considered positive, %false if not + * + * Assumes a non-NULL @mm is valid (i.e. at least one reference on it). + * + * Return: + * * 0 on success, or if mm is NULL + * * -ENOMEM if RLIMIT_MEMLOCK would be exceeded. + */ +int account_locked_vm(struct mm_struct *mm, unsigned long pages, bool inc) +{ + int ret; + + if (pages == 0 || !mm) + return 0; + + down_write(&mm->mmap_sem); + ret = __account_locked_vm(mm, pages, inc, current, + capable(CAP_IPC_LOCK)); + up_write(&mm->mmap_sem); + + return ret; +} +EXPORT_SYMBOL_GPL(account_locked_vm); + unsigned long vm_mmap_pgoff(struct file *file, unsigned long addr, unsigned long len, unsigned long prot, unsigned long flag, unsigned long pgoff) -- cgit v1.2.3 From 80ec922dbd87fd38d15719c86a94457204648aeb Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Thu, 18 Jul 2019 15:56:51 -0700 Subject: mm/memory_hotplug: allow arch_remove_memory() without CONFIG_MEMORY_HOTREMOVE We want to improve error handling while adding memory by allowing to use arch_remove_memory() and __remove_pages() even if CONFIG_MEMORY_HOTREMOVE is not set to e.g., implement something like: arch_add_memory() rc = do_something(); if (rc) { arch_remove_memory(); } We won't get rid of CONFIG_MEMORY_HOTREMOVE for now, as it will require quite some dependencies for memory offlining. Link: http://lkml.kernel.org/r/20190527111152.16324-7-david@redhat.com Signed-off-by: David Hildenbrand Reviewed-by: Pavel Tatashin Cc: Tony Luck Cc: Fenghua Yu Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: Heiko Carstens Cc: Yoshinori Sato Cc: Rich Felker Cc: Dave Hansen Cc: Andy Lutomirski Cc: Peter Zijlstra Cc: Thomas Gleixner Cc: Borislav Petkov Cc: "H. Peter Anvin" Cc: Greg Kroah-Hartman Cc: "Rafael J. Wysocki" Cc: Michal Hocko Cc: David Hildenbrand Cc: Oscar Salvador Cc: "Kirill A. Shutemov" Cc: Alex Deucher Cc: "David S. Miller" Cc: Mark Brown Cc: Chris Wilson Cc: Christophe Leroy Cc: Nicholas Piggin Cc: Vasily Gorbik Cc: Rob Herring Cc: Masahiro Yamada Cc: "mike.travis@hpe.com" Cc: Andrew Banman Cc: Arun KS Cc: Qian Cai Cc: Mathieu Malaterre Cc: Baoquan He Cc: Logan Gunthorpe Cc: Anshuman Khandual Cc: Ard Biesheuvel Cc: Catalin Marinas Cc: Chintan Pandya Cc: Dan Williams Cc: Ingo Molnar Cc: Jonathan Cameron Cc: Joonsoo Kim Cc: Jun Yao Cc: Mark Rutland Cc: Mike Rapoport Cc: Oscar Salvador Cc: Robin Murphy Cc: Wei Yang Cc: Will Deacon Cc: Yu Zhao Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/arm64/mm/mmu.c | 2 -- arch/ia64/mm/init.c | 2 -- arch/powerpc/mm/mem.c | 2 -- arch/s390/mm/init.c | 2 -- arch/sh/mm/init.c | 2 -- arch/x86/mm/init_32.c | 2 -- arch/x86/mm/init_64.c | 2 -- drivers/base/memory.c | 2 -- include/linux/memory.h | 2 -- include/linux/memory_hotplug.h | 2 -- mm/memory_hotplug.c | 2 -- mm/sparse.c | 6 ------ 12 files changed, 28 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/arm64/mm/mmu.c b/arch/arm64/mm/mmu.c index a21fa7e1167d..750a69dde39b 100644 --- a/arch/arm64/mm/mmu.c +++ b/arch/arm64/mm/mmu.c @@ -1074,7 +1074,6 @@ int arch_add_memory(int nid, u64 start, u64 size, return __add_pages(nid, start >> PAGE_SHIFT, size >> PAGE_SHIFT, restrictions); } -#ifdef CONFIG_MEMORY_HOTREMOVE void arch_remove_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap) { @@ -1093,4 +1092,3 @@ void arch_remove_memory(int nid, u64 start, u64 size, __remove_pages(zone, start_pfn, nr_pages, altmap); } #endif -#endif diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c index d28e29103bdb..aae75fd7b810 100644 --- a/arch/ia64/mm/init.c +++ b/arch/ia64/mm/init.c @@ -681,7 +681,6 @@ int arch_add_memory(int nid, u64 start, u64 size, return ret; } -#ifdef CONFIG_MEMORY_HOTREMOVE void arch_remove_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap) { @@ -693,4 +692,3 @@ void arch_remove_memory(int nid, u64 start, u64 size, __remove_pages(zone, start_pfn, nr_pages, altmap); } #endif -#endif diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c index 26a8da3723bb..9259337d7374 100644 --- a/arch/powerpc/mm/mem.c +++ b/arch/powerpc/mm/mem.c @@ -125,7 +125,6 @@ int __ref arch_add_memory(int nid, u64 start, u64 size, return __add_pages(nid, start_pfn, nr_pages, restrictions); } -#ifdef CONFIG_MEMORY_HOTREMOVE void __ref arch_remove_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap) { @@ -151,7 +150,6 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size, pr_warn("Hash collision while resizing HPT\n"); } #endif -#endif /* CONFIG_MEMORY_HOTPLUG */ #ifndef CONFIG_NEED_MULTIPLE_NODES void __init mem_topology_setup(void) diff --git a/arch/s390/mm/init.c b/arch/s390/mm/init.c index 5b1ec2f532e0..4e5bbe328594 100644 --- a/arch/s390/mm/init.c +++ b/arch/s390/mm/init.c @@ -286,7 +286,6 @@ int arch_add_memory(int nid, u64 start, u64 size, return rc; } -#ifdef CONFIG_MEMORY_HOTREMOVE void arch_remove_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap) { @@ -298,5 +297,4 @@ void arch_remove_memory(int nid, u64 start, u64 size, __remove_pages(zone, start_pfn, nr_pages, altmap); vmem_remove_mapping(start, size); } -#endif #endif /* CONFIG_MEMORY_HOTPLUG */ diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c index 13c6a6bb5fd9..dfdbaa50946e 100644 --- a/arch/sh/mm/init.c +++ b/arch/sh/mm/init.c @@ -429,7 +429,6 @@ int memory_add_physaddr_to_nid(u64 addr) EXPORT_SYMBOL_GPL(memory_add_physaddr_to_nid); #endif -#ifdef CONFIG_MEMORY_HOTREMOVE void arch_remove_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap) { @@ -440,5 +439,4 @@ void arch_remove_memory(int nid, u64 start, u64 size, zone = page_zone(pfn_to_page(start_pfn)); __remove_pages(zone, start_pfn, nr_pages, altmap); } -#endif #endif /* CONFIG_MEMORY_HOTPLUG */ diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c index f265a4316179..4068abb9427f 100644 --- a/arch/x86/mm/init_32.c +++ b/arch/x86/mm/init_32.c @@ -860,7 +860,6 @@ int arch_add_memory(int nid, u64 start, u64 size, return __add_pages(nid, start_pfn, nr_pages, restrictions); } -#ifdef CONFIG_MEMORY_HOTREMOVE void arch_remove_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap) { @@ -872,7 +871,6 @@ void arch_remove_memory(int nid, u64 start, u64 size, __remove_pages(zone, start_pfn, nr_pages, altmap); } #endif -#endif int kernel_set_to_readonly __read_mostly; diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 08bbf648827b..5a289a2ab108 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -1198,7 +1198,6 @@ void __ref vmemmap_free(unsigned long start, unsigned long end, remove_pagetable(start, end, false, altmap); } -#ifdef CONFIG_MEMORY_HOTREMOVE static void __meminit kernel_physical_mapping_remove(unsigned long start, unsigned long end) { @@ -1219,7 +1218,6 @@ void __ref arch_remove_memory(int nid, u64 start, u64 size, __remove_pages(zone, start_pfn, nr_pages, altmap); kernel_physical_mapping_remove(start, start + size); } -#endif #endif /* CONFIG_MEMORY_HOTPLUG */ static struct kcore_list kcore_vsyscall; diff --git a/drivers/base/memory.c b/drivers/base/memory.c index e0aa7f9abb36..92459d6f12be 100644 --- a/drivers/base/memory.c +++ b/drivers/base/memory.c @@ -723,7 +723,6 @@ out: return ret; } -#ifdef CONFIG_MEMORY_HOTREMOVE static void unregister_memory(struct memory_block *memory) { @@ -762,7 +761,6 @@ void unregister_memory_section(struct mem_section *section) out_unlock: mutex_unlock(&mem_sysfs_mutex); } -#endif /* CONFIG_MEMORY_HOTREMOVE */ /* return true if the memory block is offlined, otherwise, return false */ bool is_memblock_offlined(struct memory_block *mem) diff --git a/include/linux/memory.h b/include/linux/memory.h index e1dc1bb2b787..474c7c60c8f2 100644 --- a/include/linux/memory.h +++ b/include/linux/memory.h @@ -112,9 +112,7 @@ extern void unregister_memory_notifier(struct notifier_block *nb); extern int register_memory_isolate_notifier(struct notifier_block *nb); extern void unregister_memory_isolate_notifier(struct notifier_block *nb); int hotplug_memory_register(int nid, struct mem_section *section); -#ifdef CONFIG_MEMORY_HOTREMOVE extern void unregister_memory_section(struct mem_section *); -#endif extern int memory_dev_init(void); extern int memory_notify(unsigned long val, void *v); extern int memory_isolate_notify(unsigned long val, void *v); diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 988fde33cd7f..87bf9c4a889e 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -123,12 +123,10 @@ static inline bool movable_node_is_enabled(void) return movable_node_enabled; } -#ifdef CONFIG_MEMORY_HOTREMOVE extern void arch_remove_memory(int nid, u64 start, u64 size, struct vmem_altmap *altmap); extern void __remove_pages(struct zone *zone, unsigned long start_pfn, unsigned long nr_pages, struct vmem_altmap *altmap); -#endif /* CONFIG_MEMORY_HOTREMOVE */ /* * Do we want sysfs memblock files created. This will allow userspace to online diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index a8c25fd85ee3..bc11888d5d7e 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -318,7 +318,6 @@ out: return err; } -#ifdef CONFIG_MEMORY_HOTREMOVE /* find the smallest valid pfn in the range [start_pfn, end_pfn) */ static unsigned long find_smallest_section_pfn(int nid, struct zone *zone, unsigned long start_pfn, @@ -580,7 +579,6 @@ void __remove_pages(struct zone *zone, unsigned long phys_start_pfn, set_zone_contiguous(zone); } -#endif /* CONFIG_MEMORY_HOTREMOVE */ int set_online_page_callback(online_page_callback_t callback) { diff --git a/mm/sparse.c b/mm/sparse.c index fd13166949b5..d1d5e05f5b8d 100644 --- a/mm/sparse.c +++ b/mm/sparse.c @@ -604,7 +604,6 @@ static void __kfree_section_memmap(struct page *memmap, vmemmap_free(start, end, altmap); } -#ifdef CONFIG_MEMORY_HOTREMOVE static void free_map_bootmem(struct page *memmap) { unsigned long start = (unsigned long)memmap; @@ -612,7 +611,6 @@ static void free_map_bootmem(struct page *memmap) vmemmap_free(start, end, NULL); } -#endif /* CONFIG_MEMORY_HOTREMOVE */ #else static struct page *__kmalloc_section_memmap(void) { @@ -651,7 +649,6 @@ static void __kfree_section_memmap(struct page *memmap, get_order(sizeof(struct page) * PAGES_PER_SECTION)); } -#ifdef CONFIG_MEMORY_HOTREMOVE static void free_map_bootmem(struct page *memmap) { unsigned long maps_section_nr, removing_section_nr, i; @@ -681,7 +678,6 @@ static void free_map_bootmem(struct page *memmap) put_page_bootmem(page); } } -#endif /* CONFIG_MEMORY_HOTREMOVE */ #endif /* CONFIG_SPARSEMEM_VMEMMAP */ /** @@ -746,7 +742,6 @@ out: return ret; } -#ifdef CONFIG_MEMORY_HOTREMOVE #ifdef CONFIG_MEMORY_FAILURE static void clear_hwpoisoned_pages(struct page *memmap, int nr_pages) { @@ -823,5 +818,4 @@ void sparse_remove_one_section(struct zone *zone, struct mem_section *ms, PAGES_PER_SECTION - map_offset); free_section_usemap(memmap, usemap, altmap); } -#endif /* CONFIG_MEMORY_HOTREMOVE */ #endif /* CONFIG_MEMORY_HOTPLUG */ -- cgit v1.2.3 From fbcf73ce65827c3d8935f38b832a43153a0c78d1 Mon Sep 17 00:00:00 2001 From: David Hildenbrand Date: Thu, 18 Jul 2019 15:57:46 -0700 Subject: mm/memory_hotplug: rename walk_memory_range() and pass start+size instead of pfns walk_memory_range() was once used to iterate over sections. Now, it iterates over memory blocks. Rename the function, fixup the documentation. Also, pass start+size instead of PFNs, which is what most callers already have at hand. (we'll rework link_mem_sections() most probably soon) Follow-up patches will rework, simplify, and move walk_memory_blocks() to drivers/base/memory.c. Note: walk_memory_blocks() only works correctly right now if the start_pfn is aligned to a section start. This is the case right now, but we'll generalize the function in a follow up patch so the semantics match the documentation. [akpm@linux-foundation.org: remove unused variable] Link: http://lkml.kernel.org/r/20190614100114.311-5-david@redhat.com Signed-off-by: David Hildenbrand Reviewed-by: Andrew Morton Cc: Benjamin Herrenschmidt Cc: Paul Mackerras Cc: Michael Ellerman Cc: "Rafael J. Wysocki" Cc: Len Brown Cc: Greg Kroah-Hartman Cc: David Hildenbrand Cc: Rashmica Gupta Cc: Pavel Tatashin Cc: Anshuman Khandual Cc: Michael Neuling Cc: Thomas Gleixner Cc: Oscar Salvador Cc: Michal Hocko Cc: Wei Yang Cc: Juergen Gross Cc: Qian Cai Cc: Arun KS Cc: Nick Desaulniers Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- arch/powerpc/platforms/powernv/memtrace.c | 23 +++++++++++------------ drivers/acpi/acpi_memhotplug.c | 19 ++++--------------- drivers/base/node.c | 5 +++-- include/linux/memory_hotplug.h | 2 +- mm/memory_hotplug.c | 24 +++++++++++++----------- 5 files changed, 32 insertions(+), 41 deletions(-) (limited to 'arch/powerpc') diff --git a/arch/powerpc/platforms/powernv/memtrace.c b/arch/powerpc/platforms/powernv/memtrace.c index 5e53c1392d3b..eb2e75dac369 100644 --- a/arch/powerpc/platforms/powernv/memtrace.c +++ b/arch/powerpc/platforms/powernv/memtrace.c @@ -70,23 +70,23 @@ static int change_memblock_state(struct memory_block *mem, void *arg) /* called with device_hotplug_lock held */ static bool memtrace_offline_pages(u32 nid, u64 start_pfn, u64 nr_pages) { - u64 end_pfn = start_pfn + nr_pages - 1; + const unsigned long start = PFN_PHYS(start_pfn); + const unsigned long size = PFN_PHYS(nr_pages); - if (walk_memory_range(start_pfn, end_pfn, NULL, - check_memblock_online)) + if (walk_memory_blocks(start, size, NULL, check_memblock_online)) return false; - walk_memory_range(start_pfn, end_pfn, (void *)MEM_GOING_OFFLINE, - change_memblock_state); + walk_memory_blocks(start, size, (void *)MEM_GOING_OFFLINE, + change_memblock_state); if (offline_pages(start_pfn, nr_pages)) { - walk_memory_range(start_pfn, end_pfn, (void *)MEM_ONLINE, - change_memblock_state); + walk_memory_blocks(start, size, (void *)MEM_ONLINE, + change_memblock_state); return false; } - walk_memory_range(start_pfn, end_pfn, (void *)MEM_OFFLINE, - change_memblock_state); + walk_memory_blocks(start, size, (void *)MEM_OFFLINE, + change_memblock_state); return true; @@ -242,9 +242,8 @@ static int memtrace_online(void) */ if (!memhp_auto_online) { lock_device_hotplug(); - walk_memory_range(PFN_DOWN(ent->start), - PFN_UP(ent->start + ent->size - 1), - NULL, online_mem_block); + walk_memory_blocks(ent->start, ent->size, NULL, + online_mem_block); unlock_device_hotplug(); } diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index db013dc21c02..e294f44a7850 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c @@ -155,16 +155,6 @@ static int acpi_memory_check_device(struct acpi_memory_device *mem_device) return 0; } -static unsigned long acpi_meminfo_start_pfn(struct acpi_memory_info *info) -{ - return PFN_DOWN(info->start_addr); -} - -static unsigned long acpi_meminfo_end_pfn(struct acpi_memory_info *info) -{ - return PFN_UP(info->start_addr + info->length-1); -} - static int acpi_bind_memblk(struct memory_block *mem, void *arg) { return acpi_bind_one(&mem->dev, arg); @@ -173,9 +163,8 @@ static int acpi_bind_memblk(struct memory_block *mem, void *arg) static int acpi_bind_memory_blocks(struct acpi_memory_info *info, struct acpi_device *adev) { - return walk_memory_range(acpi_meminfo_start_pfn(info), - acpi_meminfo_end_pfn(info), adev, - acpi_bind_memblk); + return walk_memory_blocks(info->start_addr, info->length, adev, + acpi_bind_memblk); } static int acpi_unbind_memblk(struct memory_block *mem, void *arg) @@ -186,8 +175,8 @@ static int acpi_unbind_memblk(struct memory_block *mem, void *arg) static void acpi_unbind_memory_blocks(struct acpi_memory_info *info) { - walk_memory_range(acpi_meminfo_start_pfn(info), - acpi_meminfo_end_pfn(info), NULL, acpi_unbind_memblk); + walk_memory_blocks(info->start_addr, info->length, NULL, + acpi_unbind_memblk); } static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) diff --git a/drivers/base/node.c b/drivers/base/node.c index 27391f1e8f60..75b7e6f6535b 100644 --- a/drivers/base/node.c +++ b/drivers/base/node.c @@ -834,8 +834,9 @@ void unregister_memory_block_under_nodes(struct memory_block *mem_blk) int link_mem_sections(int nid, unsigned long start_pfn, unsigned long end_pfn) { - return walk_memory_range(start_pfn, end_pfn, (void *)&nid, - register_mem_sect_under_node); + return walk_memory_blocks(PFN_PHYS(start_pfn), + PFN_PHYS(end_pfn - start_pfn), (void *)&nid, + register_mem_sect_under_node); } #ifdef CONFIG_HUGETLBFS diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h index 79e0add6a597..d9fffc34949f 100644 --- a/include/linux/memory_hotplug.h +++ b/include/linux/memory_hotplug.h @@ -340,7 +340,7 @@ static inline void __remove_memory(int nid, u64 start, u64 size) {} #endif /* CONFIG_MEMORY_HOTREMOVE */ extern void __ref free_area_init_core_hotplug(int nid); -extern int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, +extern int walk_memory_blocks(unsigned long start, unsigned long size, void *arg, int (*func)(struct memory_block *, void *)); extern int __add_memory(int nid, u64 start, u64 size); extern int add_memory(int nid, u64 start, u64 size); diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c index d1d0ceaaca88..b3ef84e408fa 100644 --- a/mm/memory_hotplug.c +++ b/mm/memory_hotplug.c @@ -1124,8 +1124,7 @@ int __ref add_memory_resource(int nid, struct resource *res) /* online pages if requested */ if (memhp_auto_online) - walk_memory_range(PFN_DOWN(start), PFN_UP(start + size - 1), - NULL, online_memory_block); + walk_memory_blocks(start, size, NULL, online_memory_block); return ret; error: @@ -1663,20 +1662,24 @@ int offline_pages(unsigned long start_pfn, unsigned long nr_pages) #endif /* CONFIG_MEMORY_HOTREMOVE */ /** - * walk_memory_range - walks through all mem sections in [start_pfn, end_pfn) - * @start_pfn: start pfn of the memory range - * @end_pfn: end pfn of the memory range + * walk_memory_blocks - walk through all present memory blocks overlapped + * by the range [start, start + size) + * + * @start: start address of the memory range + * @size: size of the memory range * @arg: argument passed to func - * @func: callback for each memory section walked + * @func: callback for each memory block walked * - * This function walks through all present mem sections in range - * [start_pfn, end_pfn) and call func on each mem section. + * This function walks through all present memory blocks overlapped by the + * range [start, start + size), calling func on each memory block. * * Returns the return value of func. */ -int walk_memory_range(unsigned long start_pfn, unsigned long end_pfn, +int walk_memory_blocks(unsigned long start, unsigned long size, void *arg, int (*func)(struct memory_block *, void *)) { + const unsigned long start_pfn = PFN_DOWN(start); + const unsigned long end_pfn = PFN_UP(start + size - 1); struct memory_block *mem = NULL; struct mem_section *section; unsigned long pfn, section_nr; @@ -1822,8 +1825,7 @@ static int __ref try_remove_memory(int nid, u64 start, u64 size) * whether all memory blocks in question are offline and return error * if this is not the case. */ - rc = walk_memory_range(PFN_DOWN(start), PFN_UP(start + size - 1), NULL, - check_memblock_offlined_cb); + rc = walk_memory_blocks(start, size, NULL, check_memblock_offlined_cb); if (rc) goto done; -- cgit v1.2.3