* [PATCH v3 1/6] powerpc/fsl: Disable the speculation barrier from the command line
From: Diana Craciun @ 2018-07-13 13:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mpe, oss, leoyang.li, bharat.bhushan, Diana Craciun
In-Reply-To: <1531489935-17473-1-git-send-email-diana.craciun@nxp.com>
The speculation barrier can be disabled from the command line
with the parameter: "nospectre_v1".
Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
---
History:
v2-->v3
- no changes
arch/powerpc/kernel/security.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
index a8b2773..2ebfc5b 100644
--- a/arch/powerpc/kernel/security.c
+++ b/arch/powerpc/kernel/security.c
@@ -16,6 +16,7 @@
unsigned long powerpc_security_features __read_mostly = SEC_FTR_DEFAULT;
bool barrier_nospec_enabled;
+static bool no_nospec;
static void enable_barrier_nospec(bool enable)
{
@@ -42,9 +43,18 @@ void setup_barrier_nospec(void)
enable = security_ftr_enabled(SEC_FTR_FAVOUR_SECURITY) &&
security_ftr_enabled(SEC_FTR_BNDS_CHK_SPEC_BAR);
- enable_barrier_nospec(enable);
+ if (!no_nospec)
+ enable_barrier_nospec(enable);
}
+static int __init handle_nospectre_v1(char *p)
+{
+ no_nospec = true;
+
+ return 0;
+}
+early_param("nospectre_v1", handle_nospectre_v1);
+
#ifdef CONFIG_DEBUG_FS
static int barrier_nospec_set(void *data, u64 val)
{
--
2.5.5
^ permalink raw reply related
* [PATCH v3 0/6] powerpc/fsl: Speculation barrier for NXP PowerPC Book3E
From: Diana Craciun @ 2018-07-13 13:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mpe, oss, leoyang.li, bharat.bhushan, Diana Craciun
Implement barrier_nospec for NXP PowerPC Book3E processors.
Diana Craciun (6):
Disable the speculation barrier from the command line
Document nospectre_v1 kernel parameter.
Make stf barrier PPC_BOOK3S_64 specific.
Enable cpu vulnerabilities reporting for NXP PPC BOOK3E
Add barrier_nospec implementation for NXP PowerPC Book3E
powerpc/fsl: Sanitize the syscall table for NXP PowerPC 32 bit
platforms
Documentation/admin-guide/kernel-parameters.txt | 4 +++
arch/powerpc/Kconfig | 7 ++++-
arch/powerpc/include/asm/barrier.h | 12 ++++++---
arch/powerpc/include/asm/setup.h | 6 ++++-
arch/powerpc/kernel/Makefile | 3 ++-
arch/powerpc/kernel/entry_32.S | 10 +++++++
arch/powerpc/kernel/module.c | 4 ++-
arch/powerpc/kernel/security.c | 17 +++++++++++-
arch/powerpc/kernel/setup-common.c | 2 ++
arch/powerpc/kernel/vmlinux.lds.S | 4 ++-
arch/powerpc/lib/feature-fixups.c | 35 ++++++++++++++++++++++++-
arch/powerpc/platforms/powernv/setup.c | 1 -
arch/powerpc/platforms/pseries/setup.c | 1 -
13 files changed, 94 insertions(+), 12 deletions(-)
--
History:
v2 --> v3
- addressed review comments
- included the 32bit sanitization in the same patch series
v1 --> v2
- added implementation for cpu_show_spectre_x functions
- the mitigation is no longer enabled through device tree options
2.5.5
^ permalink raw reply
* [PATCH v3 2/6] powerpc/fsl: Document nospectre_v1 kernel parameter.
From: Diana Craciun @ 2018-07-13 13:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mpe, oss, leoyang.li, bharat.bhushan, Diana Craciun
In-Reply-To: <1531489935-17473-1-git-send-email-diana.craciun@nxp.com>
Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
---
History:
v2-->v3
- new
Documentation/admin-guide/kernel-parameters.txt | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index efc7aa7..b346cc7 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2687,6 +2687,10 @@
nosmt [KNL,S390] Disable symmetric multithreading (SMT).
Equivalent to smt=1.
+ nospectre_v1 [PPC] Disable mitigations for Spectre Variant 1
+ (bounds check bypass). With this option data leaks are
+ possible in the system.
+
nospectre_v2 [X86] Disable all mitigations for the Spectre variant 2
(indirect branch prediction) vulnerability. System may
allow data leaks with this option, which is equivalent
--
2.5.5
^ permalink raw reply related
* [PATCH v3 3/6] powerpc/fsl: Make stf barrier PPC_BOOK3S_64 specific.
From: Diana Craciun @ 2018-07-13 13:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mpe, oss, leoyang.li, bharat.bhushan, Diana Craciun
In-Reply-To: <1531489935-17473-1-git-send-email-diana.craciun@nxp.com>
NXP Book3E platforms are not vulnerable to speculative store
bypass, so make the mitigations PPC_BOOK3S_64 specific.
Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
---
History:
v2-->v3
- new
arch/powerpc/kernel/security.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
index 2ebfc5b..3a4e5c3 100644
--- a/arch/powerpc/kernel/security.c
+++ b/arch/powerpc/kernel/security.c
@@ -169,6 +169,7 @@ ssize_t cpu_show_spectre_v2(struct device *dev, struct device_attribute *attr, c
return s.len;
}
+#ifdef CONFIG_PPC_BOOK3S_64
/*
* Store-forwarding barrier support.
*/
@@ -316,3 +317,5 @@ static __init int stf_barrier_debugfs_init(void)
}
device_initcall(stf_barrier_debugfs_init);
#endif /* CONFIG_DEBUG_FS */
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
--
2.5.5
^ permalink raw reply related
* [PATCH v3 4/6] powerpc/fsl: Enable cpu vulnerabilities reporting for NXP PPC BOOK3E
From: Diana Craciun @ 2018-07-13 13:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mpe, oss, leoyang.li, bharat.bhushan, Diana Craciun
In-Reply-To: <1531489935-17473-1-git-send-email-diana.craciun@nxp.com>
The NXP PPC Book3E platforms are not vulnerable to meltdown, so make it
PPC_BOOK3S_64 specific.
Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
---
History:
v2-->v3
- used the existing functions for spectre v1/v2
arch/powerpc/Kconfig | 7 ++++++-
arch/powerpc/kernel/security.c | 2 ++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9f2b75f..116c953 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -165,7 +165,7 @@ config PPC
select GENERIC_CLOCKEVENTS_BROADCAST if SMP
select GENERIC_CMOS_UPDATE
select GENERIC_CPU_AUTOPROBE
- select GENERIC_CPU_VULNERABILITIES if PPC_BOOK3S_64
+ select GENERIC_CPU_VULNERABILITIES if PPC_NOSPEC
select GENERIC_IRQ_SHOW
select GENERIC_IRQ_SHOW_LEVEL
select GENERIC_SMP_IDLE_THREAD
@@ -240,6 +240,11 @@ config PPC
# Please keep this list sorted alphabetically.
#
+config PPC_NOSPEC
+ bool
+ default y
+ depends on PPC_BOOK3S_64 || PPC_FSL_BOOK3E
+
config GENERIC_CSUM
def_bool n
diff --git a/arch/powerpc/kernel/security.c b/arch/powerpc/kernel/security.c
index 3a4e5c3..539c744 100644
--- a/arch/powerpc/kernel/security.c
+++ b/arch/powerpc/kernel/security.c
@@ -92,6 +92,7 @@ static __init int barrier_nospec_debugfs_init(void)
device_initcall(barrier_nospec_debugfs_init);
#endif /* CONFIG_DEBUG_FS */
+#ifdef CONFIG_PPC_BOOK3S_64
ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, char *buf)
{
bool thread_priv;
@@ -124,6 +125,7 @@ ssize_t cpu_show_meltdown(struct device *dev, struct device_attribute *attr, cha
return sprintf(buf, "Vulnerable\n");
}
+#endif
ssize_t cpu_show_spectre_v1(struct device *dev, struct device_attribute *attr, char *buf)
{
--
2.5.5
^ permalink raw reply related
* [PATCH v3 5/6] powerpc/fsl: Add barrier_nospec implementation for NXP PowerPC Book3E
From: Diana Craciun @ 2018-07-13 13:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mpe, oss, leoyang.li, bharat.bhushan, Diana Craciun
In-Reply-To: <1531489935-17473-1-git-send-email-diana.craciun@nxp.com>
Implement the barrier_nospec as a isync;sync instruction sequence.
The implementation uses the infrastructure built for BOOK3S 64.
Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
---
History:
v2-->v3
- added PPC_NOSPEC Kconfig
- addressed the review comments
It was a discussion at the previous review cycle about the place in the code
where to call setup_barrier_nospec. I have chosen to call the function in the
common code in order to be re-used on multiple platforms. However, I am not sure
that changes concerning powernv/pseries are correct, I need some input here.
arch/powerpc/include/asm/barrier.h | 12 +++++++++---
arch/powerpc/include/asm/setup.h | 6 +++++-
arch/powerpc/kernel/Makefile | 3 ++-
arch/powerpc/kernel/module.c | 4 +++-
arch/powerpc/kernel/setup-common.c | 2 ++
arch/powerpc/kernel/vmlinux.lds.S | 4 +++-
arch/powerpc/lib/feature-fixups.c | 35 +++++++++++++++++++++++++++++++++-
arch/powerpc/platforms/powernv/setup.c | 1 -
arch/powerpc/platforms/pseries/setup.c | 1 -
9 files changed, 58 insertions(+), 10 deletions(-)
diff --git a/arch/powerpc/include/asm/barrier.h b/arch/powerpc/include/asm/barrier.h
index f67b3f6..0bdfa81 100644
--- a/arch/powerpc/include/asm/barrier.h
+++ b/arch/powerpc/include/asm/barrier.h
@@ -77,19 +77,25 @@ do { \
})
#ifdef CONFIG_PPC_BOOK3S_64
+#define NOSPEC_BARRIER_SLOT nop
+#elif defined(CONFIG_PPC_FSL_BOOK3E)
+#define NOSPEC_BARRIER_SLOT nop; nop
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
+#ifdef CONFIG_PPC_NOSPEC
/*
* Prevent execution of subsequent instructions until preceding branches have
* been fully resolved and are no longer executing speculatively.
*/
-#define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; nop
+#define barrier_nospec_asm NOSPEC_BARRIER_FIXUP_SECTION; NOSPEC_BARRIER_SLOT
// This also acts as a compiler barrier due to the memory clobber.
#define barrier_nospec() asm (stringify_in_c(barrier_nospec_asm) ::: "memory")
-#else /* !CONFIG_PPC_BOOK3S_64 */
+#else /* !CONFIG_PPC_NOSPEC */
#define barrier_nospec_asm
#define barrier_nospec()
-#endif
+#endif /* CONFIG_PPC_NOSPEC */
#include <asm-generic/barrier.h>
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 8721fd0..1abe152 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -52,11 +52,15 @@ enum l1d_flush_type {
void setup_rfi_flush(enum l1d_flush_type, bool enable);
void do_rfi_flush_fixups(enum l1d_flush_type types);
+#ifdef CONFIG_PPC_NOSPEC
void setup_barrier_nospec(void);
+#else
+void setup_barrier_nospec(void) { };
+#endif
void do_barrier_nospec_fixups(bool enable);
extern bool barrier_nospec_enabled;
-#ifdef CONFIG_PPC_BOOK3S_64
+#ifdef CONFIG_PPC_NOSPEC
void do_barrier_nospec_fixups_range(bool enable, void *start, void *end);
#else
static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { };
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2b4c40b2..cd0eb38 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -42,9 +42,10 @@ obj-$(CONFIG_VDSO32) += vdso32/
obj-$(CONFIG_PPC_WATCHDOG) += watchdog.o
obj-$(CONFIG_HAVE_HW_BREAKPOINT) += hw_breakpoint.o
obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_ppc970.o cpu_setup_pa6t.o
-obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o security.o
+obj-$(CONFIG_PPC_BOOK3S_64) += cpu_setup_power.o
obj-$(CONFIG_PPC_BOOK3S_64) += mce.o mce_power.o
obj-$(CONFIG_PPC_BOOK3E_64) += exceptions-64e.o idle_book3e.o
+obj-$(CONFIG_PPC_NOSPEC) += security.o
obj-$(CONFIG_PPC64) += vdso64/
obj-$(CONFIG_ALTIVEC) += vecemu.o
obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
diff --git a/arch/powerpc/kernel/module.c b/arch/powerpc/kernel/module.c
index 1b3c683..a0c4967 100644
--- a/arch/powerpc/kernel/module.c
+++ b/arch/powerpc/kernel/module.c
@@ -72,13 +72,15 @@ int module_finalize(const Elf_Ehdr *hdr,
do_feature_fixups(powerpc_firmware_features,
(void *)sect->sh_addr,
(void *)sect->sh_addr + sect->sh_size);
+#endif /* CONFIG_PPC64 */
+#if defined(CONFIG_PPC64) || defined(CONFIG_PPC_FSL_BOOK3E)
sect = find_section(hdr, sechdrs, "__spec_barrier_fixup");
if (sect != NULL)
do_barrier_nospec_fixups_range(barrier_nospec_enabled,
(void *)sect->sh_addr,
(void *)sect->sh_addr + sect->sh_size);
-#endif
+#endif /* CONFIG_PPC64 || CONFIG_PPC_FSL_BOOK3E */
sect = find_section(hdr, sechdrs, "__lwsync_fixup");
if (sect != NULL)
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 40b44bb..93fa0c9 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -972,6 +972,8 @@ void __init setup_arch(char **cmdline_p)
if (ppc_md.setup_arch)
ppc_md.setup_arch();
+ setup_barrier_nospec();
+
paging_init();
/* Initialize the MMU context management stuff. */
diff --git a/arch/powerpc/kernel/vmlinux.lds.S b/arch/powerpc/kernel/vmlinux.lds.S
index 5baac79..6087b02 100644
--- a/arch/powerpc/kernel/vmlinux.lds.S
+++ b/arch/powerpc/kernel/vmlinux.lds.S
@@ -153,14 +153,16 @@ SECTIONS
*(__rfi_flush_fixup)
__stop___rfi_flush_fixup = .;
}
+#endif /* CONFIG_PPC64 */
+#if defined(CONFIG_PPC64) || defined(CONFIG_PPC_FSL_BOOK3E)
. = ALIGN(8);
__spec_barrier_fixup : AT(ADDR(__spec_barrier_fixup) - LOAD_OFFSET) {
__start___barrier_nospec_fixup = .;
*(__barrier_nospec_fixup)
__stop___barrier_nospec_fixup = .;
}
-#endif
+#endif /* CONFIG_PPC64 || CONFIG_PPC_FSL_BOOK3E */
EXCEPTION_TABLE(0)
diff --git a/arch/powerpc/lib/feature-fixups.c b/arch/powerpc/lib/feature-fixups.c
index 8b69f86..41f372e 100644
--- a/arch/powerpc/lib/feature-fixups.c
+++ b/arch/powerpc/lib/feature-fixups.c
@@ -304,6 +304,9 @@ void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_
printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
}
+#endif /* CONFIG_PPC_BOOK3S_64 */
+
+#ifdef CONFIG_PPC_NOSPEC
void do_barrier_nospec_fixups(bool enable)
{
void *start, *end;
@@ -313,8 +316,38 @@ void do_barrier_nospec_fixups(bool enable)
do_barrier_nospec_fixups_range(enable, start, end);
}
+#endif /* CONFIG_PPC_NOSPEC */
-#endif /* CONFIG_PPC_BOOK3S_64 */
+#ifdef CONFIG_PPC_FSL_BOOK3E
+void do_barrier_nospec_fixups_range(bool enable, void *fixup_start, void *fixup_end)
+{
+ unsigned int instr[2], *dest;
+ long *start, *end;
+ int i;
+
+ start = fixup_start;
+ end = fixup_end;
+
+ instr[0] = PPC_INST_NOP;
+ instr[1] = PPC_INST_NOP;
+
+ if (enable) {
+ pr_info("barrier-nospec: using isync; sync as speculation barrier\n");
+ instr[0] = PPC_INST_ISYNC;
+ instr[1] = PPC_INST_SYNC;
+ }
+
+ for (i = 0; start < end; start++, i++) {
+ dest = (void *)start + *start;
+
+ pr_devel("patching dest %lx\n", (unsigned long)dest);
+ patch_instruction(dest, instr[0]);
+ patch_instruction(dest + 1, instr[1]);
+ }
+
+ printk(KERN_DEBUG "barrier-nospec: patched %d locations\n", i);
+}
+#endif /* CONFIG_PPC_FSL_BOOK3E */
void do_lwsync_fixups(unsigned long value, void *fixup_start, void *fixup_end)
{
diff --git a/arch/powerpc/platforms/powernv/setup.c b/arch/powerpc/platforms/powernv/setup.c
index f96df0a..1ab6dc7 100644
--- a/arch/powerpc/platforms/powernv/setup.c
+++ b/arch/powerpc/platforms/powernv/setup.c
@@ -124,7 +124,6 @@ static void pnv_setup_rfi_flush(void)
security_ftr_enabled(SEC_FTR_L1D_FLUSH_HV));
setup_rfi_flush(type, enable);
- setup_barrier_nospec();
}
static void __init pnv_setup_arch(void)
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 139f0af..fdb32e0 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -534,7 +534,6 @@ void pseries_setup_rfi_flush(void)
security_ftr_enabled(SEC_FTR_L1D_FLUSH_PR);
setup_rfi_flush(types, enable);
- setup_barrier_nospec();
}
#ifdef CONFIG_PCI_IOV
--
2.5.5
^ permalink raw reply related
* [PATCH v3 6/6] powerpc/fsl: Sanitize the syscall table for NXP PowerPC 32 bit platforms
From: Diana Craciun @ 2018-07-13 13:52 UTC (permalink / raw)
To: linuxppc-dev; +Cc: mpe, oss, leoyang.li, bharat.bhushan, Diana Craciun
In-Reply-To: <1531489935-17473-1-git-send-email-diana.craciun@nxp.com>
Used barrier_nospec to sanitize the syscall table.
Signed-off-by: Diana Craciun <diana.craciun@nxp.com>
---
History:
v2-->v3
- included in the series
arch/powerpc/kernel/entry_32.S | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/arch/powerpc/kernel/entry_32.S b/arch/powerpc/kernel/entry_32.S
index 973577f..8f05280 100644
--- a/arch/powerpc/kernel/entry_32.S
+++ b/arch/powerpc/kernel/entry_32.S
@@ -33,6 +33,7 @@
#include <asm/unistd.h>
#include <asm/ptrace.h>
#include <asm/export.h>
+#include <asm/barrier.h>
/*
* MSR_KERNEL is > 0x10000 on 4xx/Book-E since it include MSR_CE.
@@ -358,6 +359,15 @@ syscall_dotrace_cont:
ori r10,r10,sys_call_table@l
slwi r0,r0,2
bge- 66f
+
+ barrier_nospec_asm
+ /*
+ * Prevent the load of the handler below (based on the user-passed
+ * system call number) being speculatively executed until the test
+ * against NR_syscalls and branch to .66f above has
+ * committed.
+ */
+
lwzx r10,r10,r0 /* Fetch system call handler [ptr] */
mtlr r10
addi r9,r1,STACK_FRAME_OVERHEAD
--
2.5.5
^ permalink raw reply related
* [PATCH 0/2] powerpc/pseries: Improve serialization of PRRN events
From: John Allen @ 2018-07-13 14:22 UTC (permalink / raw)
To: linuxppc-dev; +Cc: nfont
Stress testing has uncovered issues with handling continuously queued PRRN
events. Running PRRN events in this way can seriously load the system given
the sheer volume of dlpar being handled. This patchset ensures that PRRN
events are handled more synchronously, only allowing the PRRN handler to
queue a single dlpar event at any given time. Additionally, it ensures
that rtas polling continues normally when multiple PRRN events are queued
simultaneously.
John Allen (2):
pseries/prrn: Avoid blocking rtas polling handling multiple PRRN
events
pseries/prrn: Wait for completion of hotplug events during PRRN
handling
arch/powerpc/kernel/rtasd.c | 11 ++++++++---
arch/powerpc/platforms/pseries/mobility.c | 5 ++++-
2 files changed, 12 insertions(+), 4 deletions(-)
--
2.17.1
^ permalink raw reply
* [PATCH 1/2] powerpc/pseries: Avoid blocking rtas polling handling multiple PRRN events
From: John Allen @ 2018-07-13 14:22 UTC (permalink / raw)
To: linuxppc-dev; +Cc: nfont, John Allen
In-Reply-To: <20180713142224.4516-1-jallen@linux.ibm.com>
When a PRRN event is being handled and another PRRN event comes in, the
second event will block rtas polling waiting on the first to complete,
preventing any further rtas events from being handled. This can be
especially problematic in case that PRRN events are continuously being
queued in which case rtas polling gets indefinitely blocked completely.
This patch introduces a mutex that prevents any subsequent PRRN events from
running while there is a prrn event being handled, allowing rtas polling to
continue normally.
Signed-off-by: John Allen <jallen@linux.ibm.com>
---
arch/powerpc/kernel/rtasd.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 44d66c33d59d..8a72a53d62c0 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -35,6 +35,8 @@
static DEFINE_SPINLOCK(rtasd_log_lock);
+static DEFINE_MUTEX(prrn_lock);
+
static DECLARE_WAIT_QUEUE_HEAD(rtas_log_wait);
static char *rtas_log_buf;
@@ -290,9 +292,12 @@ static DECLARE_WORK(prrn_work, prrn_work_fn);
static void prrn_schedule_update(u32 scope)
{
- flush_work(&prrn_work);
- prrn_update_scope = scope;
- schedule_work(&prrn_work);
+ if (mutex_trylock(&prrn_lock)) {
+ flush_work(&prrn_work);
+ prrn_update_scope = scope;
+ schedule_work(&prrn_work);
+ mutex_unlock(&prrn_lock);
+ }
}
static void handle_rtas_event(const struct rtas_error_log *log)
--
2.17.1
^ permalink raw reply related
* [PATCH 2/2] powerpc/pseries: Wait for completion of hotplug events during PRRN handling
From: John Allen @ 2018-07-13 14:22 UTC (permalink / raw)
To: linuxppc-dev; +Cc: nfont, John Allen
In-Reply-To: <20180713142224.4516-1-jallen@linux.ibm.com>
While handling PRRN events, the time to handle the actual hotplug events
dwarfs the time it takes to perform the device tree updates and queue the
hotplug events. In the case that PRRN events are being queued continuously,
hotplug events have been observed to be queued faster than the kernel can
actually handle them. This patch avoids the problem by waiting for a
hotplug request to complete before queueing more hotplug events.
Signed-off-by: John Allen <jallen@linux.ibm.com>
---
arch/powerpc/platforms/pseries/mobility.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index 8a8033a249c7..49930848fa78 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -242,6 +242,7 @@ static int add_dt_node(__be32 parent_phandle, __be32 drc_index)
static void prrn_update_node(__be32 phandle)
{
struct pseries_hp_errorlog *hp_elog;
+ struct completion hotplug_done;
struct device_node *dn;
/*
@@ -263,7 +264,9 @@ static void prrn_update_node(__be32 phandle)
hp_elog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
hp_elog->_drc_u.drc_index = phandle;
- queue_hotplug_event(hp_elog, NULL, NULL);
+ init_completion(&hotplug_done);
+ queue_hotplug_event(hp_elog, &hotplug_done, NULL);
+ wait_for_completion(&hotplug_done);
kfree(hp_elog);
}
--
2.17.1
^ permalink raw reply related
* Re: [PATCH v06 1/9] hotplug/cpu: Conditionally acquire/release DRC index
From: Michael Bringmann @ 2018-07-13 15:54 UTC (permalink / raw)
To: Naveen N. Rao, linuxppc-dev
Cc: John Allen, Thomas Falcon, Tyrel Datwyler, Nathan Fontenot
In-Reply-To: <1531324062.imrh0yfelc.naveen@linux.ibm.com>
See below. Code cleanups accepted for next revision.
On 07/11/2018 11:00 AM, Naveen N. Rao wrote:
> Michael Bringmann wrote:
>> powerpc/cpu: Modify dlpar_cpu_add and dlpar_cpu_remove to allow the
>> skipping of DRC index acquire or release operations during the CPU
>> add or remove operations. This is intended to support subsequent
>> changes to provide a 'CPU readd' operation.
>>
>> Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
>> ---
>> Changes in patch:
>> -- Move new validity check added to pseries_smp_notifier
>> to another patch
>> ---
>> arch/powerpc/platforms/pseries/hotplug-cpu.c | 68 +++++++++++++++-----------
>> 1 file changed, 39 insertions(+), 29 deletions(-)
>>
>> diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
>> index 6ef77ca..3632db2 100644
>> --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
>> +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
>> @@ -432,7 +432,7 @@ static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index)
>> return found;
>> }
>>
>> -static ssize_t dlpar_cpu_add(u32 drc_index)
>> +static ssize_t dlpar_cpu_add(u32 drc_index, bool acquire_drc)
>> {
>> struct device_node *dn, *parent;
>> int rc, saved_rc;
>> @@ -457,19 +457,22 @@ static ssize_t dlpar_cpu_add(u32 drc_index)
>> return -EINVAL;
>> }
>>
>> - rc = dlpar_acquire_drc(drc_index);
>> - if (rc) {
>> - pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n",
>> - rc, drc_index);
>> - of_node_put(parent);
>> - return -EINVAL;
>> + if (acquire_drc) {
>> + rc = dlpar_acquire_drc(drc_index);
>> + if (rc) {
>> + pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n",
>> + rc, drc_index);
>> + of_node_put(parent);
>> + return -EINVAL;
>> + }
>> }
>>
>> dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
>> if (!dn) {
>> pr_warn("Failed call to configure-connector, drc index: %x\n",
>> drc_index);
>> - dlpar_release_drc(drc_index);
>> + if (acquire_drc)
>> + dlpar_release_drc(drc_index);
>> of_node_put(parent);
>> return -EINVAL;
>> }
>> @@ -484,8 +487,9 @@ static ssize_t dlpar_cpu_add(u32 drc_index)
>> pr_warn("Failed to attach node %s, rc: %d, drc index: %x\n",
>> dn->name, rc, drc_index);
>>
>> - rc = dlpar_release_drc(drc_index);
>> - if (!rc)
>> + if (acquire_drc)
>> + rc = dlpar_release_drc(drc_index);
>> + if (!rc || acquire_drc)
>> dlpar_free_cc_nodes(dn);
>
> (!rc) can only be true if acquire_drc is true, so we seem to be only invoking dlpar_free_cc_nodes() if acquire_drc is true. Would it be better to frame that condition in this manner:
>
> if (acquire_drc) {
> rc = dlpar_release_drc(drc_index):
> if (!rc)
> dlpar_free_cc_nodes(dn);
> }
>
Okay.
>>
>> return saved_rc;
>> @@ -498,7 +502,7 @@ static ssize_t dlpar_cpu_add(u32 drc_index)
>> dn->name, rc, drc_index);
>>
>> rc = dlpar_detach_node(dn);
>> - if (!rc)
>> + if (!rc && acquire_drc)
>> dlpar_release_drc(drc_index);
>>
>> return saved_rc;
>> @@ -566,7 +570,8 @@ static int dlpar_offline_cpu(struct device_node *dn)
>>
>> }
>>
>> -static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
>> +static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index,
>> + bool release_drc)
>> {
>> int rc;
>>
>> @@ -579,12 +584,14 @@ static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
>> return -EINVAL;
>> }
>>
>> - rc = dlpar_release_drc(drc_index);
>> - if (rc) {
>> - pr_warn("Failed to release drc (%x) for CPU %s, rc: %d\n",
>> - drc_index, dn->name, rc);
>> - dlpar_online_cpu(dn);
>> - return rc;
>> + if (release_drc) {
>> + rc = dlpar_release_drc(drc_index);
>> + if (rc) {
>> + pr_warn("Failed to release drc (%x) for CPU %s, rc: %d\n",
>> + drc_index, dn->name, rc);
>> + dlpar_online_cpu(dn);
>> + return rc;
>> + }
>> }
>>
>> rc = dlpar_detach_node(dn);
>> @@ -593,7 +600,10 @@ static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
>>
>> pr_warn("Failed to detach CPU %s, rc: %d", dn->name, rc);
>>
>> - rc = dlpar_acquire_drc(drc_index);
>> + if (release_drc)
>> + rc = dlpar_acquire_drc(drc_index);
>> + else
>> + rc = 0;
>> if (!rc)
>> dlpar_online_cpu(dn);
>
> Here, we seem to want to invoke dlpar_online_cpu() unconditionally if release_drc is false. So, to make that explicit, would it be better to frame that as:
> if (release_drc)
> rc = dlpar_acquire_drc(drc_index);
> if (!release_drc || !rc)
> dlpar_online_cpu(dn);
>
> - Naveen
Okay.
>
>>
>> @@ -622,7 +632,7 @@ static struct device_node *cpu_drc_index_to_dn(u32 drc_index)
>> return dn;
>> }
>>
>> -static int dlpar_cpu_remove_by_index(u32 drc_index)
>> +static int dlpar_cpu_remove_by_index(u32 drc_index, bool release_drc)
>> {
>> struct device_node *dn;
>> int rc;
>> @@ -634,7 +644,7 @@ static int dlpar_cpu_remove_by_index(u32 drc_index)
>> return -ENODEV;
>> }
>>
>> - rc = dlpar_cpu_remove(dn, drc_index);
>> + rc = dlpar_cpu_remove(dn, drc_index, release_drc);
>> of_node_put(dn);
>> return rc;
>> }
>> @@ -699,7 +709,7 @@ static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
>> }
>>
>> for (i = 0; i < cpus_to_remove; i++) {
>> - rc = dlpar_cpu_remove_by_index(cpu_drcs[i]);
>> + rc = dlpar_cpu_remove_by_index(cpu_drcs[i], true);
>> if (rc)
>> break;
>>
>> @@ -710,7 +720,7 @@ static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
>> pr_warn("CPU hot-remove failed, adding back removed CPUs\n");
>>
>> for (i = 0; i < cpus_removed; i++)
>> - dlpar_cpu_add(cpu_drcs[i]);
>> + dlpar_cpu_add(cpu_drcs[i], true);
>>
>> rc = -EINVAL;
>> } else {
>> @@ -780,7 +790,7 @@ static int dlpar_cpu_add_by_count(u32 cpus_to_add)
>> }
>>
>> for (i = 0; i < cpus_to_add; i++) {
>> - rc = dlpar_cpu_add(cpu_drcs[i]);
>> + rc = dlpar_cpu_add(cpu_drcs[i], true);
>> if (rc)
>> break;
>>
>> @@ -791,7 +801,7 @@ static int dlpar_cpu_add_by_count(u32 cpus_to_add)
>> pr_warn("CPU hot-add failed, removing any added CPUs\n");
>>
>> for (i = 0; i < cpus_added; i++)
>> - dlpar_cpu_remove_by_index(cpu_drcs[i]);
>> + dlpar_cpu_remove_by_index(cpu_drcs[i], true);
>>
>> rc = -EINVAL;
>> } else {
>> @@ -817,7 +827,7 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
>> if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
>> rc = dlpar_cpu_remove_by_count(count);
>> else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
>> - rc = dlpar_cpu_remove_by_index(drc_index);
>> + rc = dlpar_cpu_remove_by_index(drc_index, true);
>> else
>> rc = -EINVAL;
>> break;
>> @@ -825,7 +835,7 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
>> if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
>> rc = dlpar_cpu_add_by_count(count);
>> else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
>> - rc = dlpar_cpu_add(drc_index);
>> + rc = dlpar_cpu_add(drc_index, true);
>> else
>> rc = -EINVAL;
>> break;
>> @@ -850,7 +860,7 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
>> if (rc)
>> return -EINVAL;
>>
>> - rc = dlpar_cpu_add(drc_index);
>> + rc = dlpar_cpu_add(drc_index, true);
>>
>> return rc ? rc : count;
>> }
>> @@ -871,7 +881,7 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
>> return -EINVAL;
>> }
>>
>> - rc = dlpar_cpu_remove(dn, drc_index);
>> + rc = dlpar_cpu_remove(dn, drc_index, true);
>> of_node_put(dn);
>>
>> return rc ? rc : count;
>>
>>
>
>
--
Michael W. Bringmann
Linux Technology Center
IBM Corporation
Tie-Line 363-5196
External: (512) 286-5196
Cell: (512) 466-0650
mwb@linux.vnet.ibm.com
^ permalink raw reply
* [RFC PATCH v1 0/4] KASAN for nohash PPC32
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin,
aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
This serie adds support to nohash PPC32
Tested on MPC8xx
Christophe Leroy (4):
powerpc/mm: prepare kernel for KAsan on PPC32
powerpc: add missing header in pgtable-types.h
powerpc/32: Move early_init() in a separate file
powerpc/nohash32: Add KASAN support
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/kasan.h | 21 ++++++++
arch/powerpc/include/asm/nohash/32/pgtable.h | 2 +
arch/powerpc/include/asm/pgtable-types.h | 2 +
arch/powerpc/include/asm/ppc_asm.h | 5 ++
arch/powerpc/include/asm/setup.h | 5 ++
arch/powerpc/include/asm/string.h | 14 ++++++
arch/powerpc/kernel/Makefile | 5 +-
arch/powerpc/kernel/cputable.c | 4 +-
arch/powerpc/kernel/early_32.c | 35 +++++++++++++
arch/powerpc/kernel/setup-common.c | 2 +
arch/powerpc/kernel/setup_32.c | 33 ++-----------
arch/powerpc/lib/Makefile | 2 +
arch/powerpc/lib/copy_32.S | 9 ++--
arch/powerpc/mm/Makefile | 3 ++
arch/powerpc/mm/dump_linuxpagetables.c | 8 +++
arch/powerpc/mm/kasan_init.c | 73 ++++++++++++++++++++++++++++
arch/powerpc/mm/mem.c | 4 ++
18 files changed, 193 insertions(+), 35 deletions(-)
create mode 100644 arch/powerpc/include/asm/kasan.h
create mode 100644 arch/powerpc/kernel/early_32.c
create mode 100644 arch/powerpc/mm/kasan_init.c
--
2.13.3
^ permalink raw reply
* [RFC PATCH v1 1/4] powerpc/mm: prepare kernel for KAsan on PPC32
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin,
aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
In-Reply-To: <cover.1531498345.git.christophe.leroy@c-s.fr>
In kernel/cputable.c, explicitly use memcpy() in order
to allow GCC to replace it with __memcpy() when KASAN is
selected.
Since commit 400c47d81ca38 ("powerpc32: memset: only use dcbz once cache is
enabled"), memset() can be used before activation of the cache,
so no need to use memset_io() for zeroing the BSS.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/kernel/cputable.c | 4 ++--
arch/powerpc/kernel/setup_32.c | 6 ++----
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index c8fc9691f8c7..60ee5900bf12 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -2183,7 +2183,7 @@ void __init set_cur_cpu_spec(struct cpu_spec *s)
struct cpu_spec *t = &the_cpu_spec;
t = PTRRELOC(t);
- *t = *s;
+ memcpy(t, s, sizeof(*t));
*PTRRELOC(&cur_cpu_spec) = &the_cpu_spec;
}
@@ -2198,7 +2198,7 @@ static struct cpu_spec * __init setup_cpu_spec(unsigned long offset,
old = *t;
/* Copy everything, then do fixups */
- *t = *s;
+ memcpy(t, s, sizeof(*t));
/*
* If we are overriding a previous value derived from the real
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 74457485574b..6a394b9e109e 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -70,10 +70,8 @@ notrace unsigned long __init early_init(unsigned long dt_ptr)
{
unsigned long offset = reloc_offset();
- /* First zero the BSS -- use memset_io, some platforms don't have
- * caches on yet */
- memset_io((void __iomem *)PTRRELOC(&__bss_start), 0,
- __bss_stop - __bss_start);
+ /* First zero the BSS */
+ memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
/*
* Identify the CPU type and fix up code sections
--
2.13.3
^ permalink raw reply related
* [RFC PATCH v1 2/4] powerpc: add missing header in pgtable-types.h
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin,
aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
In-Reply-To: <cover.1531498345.git.christophe.leroy@c-s.fr>
pte_basic_t is defined in page.h
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/include/asm/pgtable-types.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/powerpc/include/asm/pgtable-types.h b/arch/powerpc/include/asm/pgtable-types.h
index eccb30b38b47..3d8f68aebea3 100644
--- a/arch/powerpc/include/asm/pgtable-types.h
+++ b/arch/powerpc/include/asm/pgtable-types.h
@@ -2,6 +2,8 @@
#ifndef _ASM_POWERPC_PGTABLE_TYPES_H
#define _ASM_POWERPC_PGTABLE_TYPES_H
+#include <asm/page.h>
+
/* PTE level */
typedef struct { pte_basic_t pte; } pte_t;
#define __pte(x) ((pte_t) { (x) })
--
2.13.3
^ permalink raw reply related
* [RFC PATCH v1 3/4] powerpc/32: Move early_init() in a separate file
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin,
aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
In-Reply-To: <cover.1531498345.git.christophe.leroy@c-s.fr>
In preparation of KASAN, move early_init() into a separate
file in order to allow deactivation of KASAN for that function.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/kernel/Makefile | 2 +-
arch/powerpc/kernel/early_32.c | 35 +++++++++++++++++++++++++++++++++++
arch/powerpc/kernel/setup_32.c | 26 --------------------------
3 files changed, 36 insertions(+), 27 deletions(-)
create mode 100644 arch/powerpc/kernel/early_32.c
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 2b4c40b255e4..70e9dbdc55f5 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -89,7 +89,7 @@ extra-y += vmlinux.lds
obj-$(CONFIG_RELOCATABLE) += reloc_$(BITS).o
-obj-$(CONFIG_PPC32) += entry_32.o setup_32.o
+obj-$(CONFIG_PPC32) += entry_32.o setup_32.o early_32.o
obj-$(CONFIG_PPC64) += dma-iommu.o iommu.o
obj-$(CONFIG_KGDB) += kgdb.o
obj-$(CONFIG_BOOTX_TEXT) += btext.o
diff --git a/arch/powerpc/kernel/early_32.c b/arch/powerpc/kernel/early_32.c
new file mode 100644
index 000000000000..b3e40d6d651c
--- /dev/null
+++ b/arch/powerpc/kernel/early_32.c
@@ -0,0 +1,35 @@
+// SPDX-License-Identifier: GPL-2.0
+
+/*
+ * Early init before relocation
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <asm/setup.h>
+#include <asm/sections.h>
+
+/*
+ * We're called here very early in the boot.
+ *
+ * Note that the kernel may be running at an address which is different
+ * from the address that it was linked at, so we must use RELOC/PTRRELOC
+ * to access static data (including strings). -- paulus
+ */
+notrace unsigned long __init early_init(unsigned long dt_ptr)
+{
+ unsigned long offset = reloc_offset();
+
+ /* First zero the BSS */
+ memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
+
+ /*
+ * Identify the CPU type and fix up code sections
+ * that depend on which cpu we have.
+ */
+ identify_cpu(offset, mfspr(SPRN_PVR));
+
+ apply_feature_fixups();
+
+ return KERNELBASE + offset;
+}
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 6a394b9e109e..1c62f81cb257 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -60,32 +60,6 @@ EXPORT_SYMBOL(DMA_MODE_READ);
EXPORT_SYMBOL(DMA_MODE_WRITE);
/*
- * We're called here very early in the boot.
- *
- * Note that the kernel may be running at an address which is different
- * from the address that it was linked at, so we must use RELOC/PTRRELOC
- * to access static data (including strings). -- paulus
- */
-notrace unsigned long __init early_init(unsigned long dt_ptr)
-{
- unsigned long offset = reloc_offset();
-
- /* First zero the BSS */
- memset(PTRRELOC(&__bss_start), 0, __bss_stop - __bss_start);
-
- /*
- * Identify the CPU type and fix up code sections
- * that depend on which cpu we have.
- */
- identify_cpu(offset, mfspr(SPRN_PVR));
-
- apply_feature_fixups();
-
- return KERNELBASE + offset;
-}
-
-
-/*
* This is run before start_kernel(), the kernel has been relocated
* and we are running with enough of the MMU enabled to have our
* proper kernel virtual addresses
--
2.13.3
^ permalink raw reply related
* [RFC PATCH v1 4/4] powerpc/nohash32: Add KASAN support
From: Christophe Leroy @ 2018-07-13 16:23 UTC (permalink / raw)
To: Benjamin Herrenschmidt, Paul Mackerras, Michael Ellerman, npiggin,
aneesh.kumar
Cc: linux-kernel, linuxppc-dev, linux-mm
In-Reply-To: <cover.1531498345.git.christophe.leroy@c-s.fr>
This patch adds KASAN support for nohash PPC32.
Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
arch/powerpc/Kconfig | 1 +
arch/powerpc/include/asm/kasan.h | 21 ++++++++
arch/powerpc/include/asm/nohash/32/pgtable.h | 2 +
arch/powerpc/include/asm/ppc_asm.h | 5 ++
arch/powerpc/include/asm/setup.h | 5 ++
arch/powerpc/include/asm/string.h | 14 ++++++
arch/powerpc/kernel/Makefile | 3 ++
arch/powerpc/kernel/setup-common.c | 2 +
arch/powerpc/kernel/setup_32.c | 5 +-
arch/powerpc/lib/Makefile | 2 +
arch/powerpc/lib/copy_32.S | 9 ++--
arch/powerpc/mm/Makefile | 3 ++
arch/powerpc/mm/dump_linuxpagetables.c | 8 +++
arch/powerpc/mm/kasan_init.c | 73 ++++++++++++++++++++++++++++
arch/powerpc/mm/mem.c | 4 ++
15 files changed, 153 insertions(+), 4 deletions(-)
create mode 100644 arch/powerpc/include/asm/kasan.h
create mode 100644 arch/powerpc/mm/kasan_init.c
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 9f2b75fe2c2d..7519ec67fdea 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -174,6 +174,7 @@ config PPC
select GENERIC_TIME_VSYSCALL
select HAVE_ARCH_AUDITSYSCALL
select HAVE_ARCH_JUMP_LABEL
+ select HAVE_ARCH_KASAN if PPC32 && PPC_MMU_NOHASH
select HAVE_ARCH_KGDB
select HAVE_ARCH_MMAP_RND_BITS
select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT
diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
new file mode 100644
index 000000000000..419366bcd5f4
--- /dev/null
+++ b/arch/powerpc/include/asm/kasan.h
@@ -0,0 +1,21 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_KASAN_H
+#define __ASM_KASAN_H
+
+#ifndef __ASSEMBLY__
+
+#include <asm/pgtable-types.h>
+#include <asm/fixmap.h>
+
+#define KASAN_SHADOW_SCALE_SHIFT 3
+#define KASAN_SHADOW_SIZE ((~0UL - PAGE_OFFSET + 1) >> KASAN_SHADOW_SCALE_SHIFT)
+
+#define KASAN_SHADOW_START (ALIGN_DOWN(FIXADDR_START - KASAN_SHADOW_SIZE, PGDIR_SIZE))
+#define KASAN_SHADOW_END (KASAN_SHADOW_START + KASAN_SHADOW_SIZE)
+#define KASAN_SHADOW_OFFSET (KASAN_SHADOW_START - (PAGE_OFFSET >> KASAN_SHADOW_SCALE_SHIFT))
+
+void kasan_early_init(void);
+void kasan_init(void);
+
+#endif
+#endif
diff --git a/arch/powerpc/include/asm/nohash/32/pgtable.h b/arch/powerpc/include/asm/nohash/32/pgtable.h
index 7c46a98cc7f4..0f1205a74212 100644
--- a/arch/powerpc/include/asm/nohash/32/pgtable.h
+++ b/arch/powerpc/include/asm/nohash/32/pgtable.h
@@ -70,6 +70,8 @@ extern int icache_44x_need_flush;
*/
#ifdef CONFIG_HIGHMEM
#define KVIRT_TOP PKMAP_BASE
+#elif defined(CONFIG_KASAN)
+#define KVIRT_TOP KASAN_SHADOW_START
#else
#define KVIRT_TOP (0xfe000000UL) /* for now, could be FIXMAP_BASE ? */
#endif
diff --git a/arch/powerpc/include/asm/ppc_asm.h b/arch/powerpc/include/asm/ppc_asm.h
index 75ece56dcd62..947d945293fa 100644
--- a/arch/powerpc/include/asm/ppc_asm.h
+++ b/arch/powerpc/include/asm/ppc_asm.h
@@ -250,6 +250,11 @@ GLUE(.,name):
#define _GLOBAL_TOC(name) _GLOBAL(name)
+#define KASAN_OVERRIDE(x, y) \
+ .weak x; \
+ .set x, y
+
+
#endif
/*
diff --git a/arch/powerpc/include/asm/setup.h b/arch/powerpc/include/asm/setup.h
index 8721fd004291..2da38c990278 100644
--- a/arch/powerpc/include/asm/setup.h
+++ b/arch/powerpc/include/asm/setup.h
@@ -62,6 +62,11 @@ void do_barrier_nospec_fixups_range(bool enable, void *start, void *end);
static inline void do_barrier_nospec_fixups_range(bool enable, void *start, void *end) { };
#endif
+#ifndef CONFIG_KASAN
+static inline void kasan_early_init(void) { }
+static inline void kasan_init(void) { }
+#endif
+
#endif /* !__ASSEMBLY__ */
#endif /* _ASM_POWERPC_SETUP_H */
diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h
index 9b8cedf618f4..93be88bfe439 100644
--- a/arch/powerpc/include/asm/string.h
+++ b/arch/powerpc/include/asm/string.h
@@ -27,6 +27,20 @@ extern int memcmp(const void *,const void *,__kernel_size_t);
extern void * memchr(const void *,int,__kernel_size_t);
extern void * memcpy_flushcache(void *,const void *,__kernel_size_t);
+void * __memset(void *, int, __kernel_size_t);
+void * __memcpy(void *, const void *, __kernel_size_t);
+void * __memmove(void *, const void *, __kernel_size_t);
+
+#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+/*
+ * For files that are not instrumented (e.g. mm/slub.c) we
+ * should use not instrumented version of mem* functions.
+ */
+#define memcpy(dst, src, len) __memcpy(dst, src, len)
+#define memmove(dst, src, len) __memmove(dst, src, len)
+#define memset(s, c, n) __memset(s, c, n)
+#endif
+
#ifdef CONFIG_PPC64
#define __HAVE_ARCH_MEMSET32
#define __HAVE_ARCH_MEMSET64
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 70e9dbdc55f5..b08072f19349 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -28,6 +28,9 @@ CFLAGS_REMOVE_btext.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_prom.o = -mno-sched-epilog $(CC_FLAGS_FTRACE)
endif
+KASAN_SANITIZE_early_32.o := n
+KASAN_SANITIZE_cputable.o := n
+
obj-y := cputable.o ptrace.o syscalls.o \
irq.o align.o signal_32.o pmc.o vdso.o \
process.o systbl.o idle.o \
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 40b44bb53a4e..a030a373fbb3 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -974,6 +974,8 @@ void __init setup_arch(char **cmdline_p)
paging_init();
+ kasan_init();
+
/* Initialize the MMU context management stuff. */
mmu_context_init();
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index 1c62f81cb257..c581f1c6adcd 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -17,6 +17,7 @@
#include <linux/console.h>
#include <linux/memblock.h>
#include <linux/export.h>
+#include <linux/kasan.h>
#include <asm/io.h>
#include <asm/prom.h>
@@ -74,13 +75,15 @@ notrace void __init machine_init(u64 dt_ptr)
unsigned int *addr = &memset_nocache_branch;
unsigned long insn;
+ kasan_early_init();
+
/* Configure static keys first, now that we're relocated. */
setup_feature_keys();
/* Enable early debugging if any specified (see udbg.h) */
udbg_early_init();
- patch_instruction((unsigned int *)&memcpy, PPC_INST_NOP);
+ patch_instruction((unsigned int *)&__memcpy, PPC_INST_NOP);
insn = create_cond_branch(addr, branch_target(addr), 0x820000);
patch_instruction(addr, insn); /* replace b by bne cr0 */
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index d0ca13ad8231..4a378d10fd83 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -10,6 +10,8 @@ ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE)
CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE)
+KASAN_SANITIZE_feature-fixups.o := n
+
obj-y += string.o alloc.o code-patching.o feature-fixups.o
obj-$(CONFIG_PPC32) += div64.o copy_32.o crtsavres.o
diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index da425bb6b369..76b4d86c0c8f 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -90,7 +90,8 @@ EXPORT_SYMBOL(memset16)
* We therefore skip the optimised bloc that uses dcbz. This jump is
* replaced by a nop once cache is active. This is done in machine_init()
*/
-_GLOBAL(memset)
+_GLOBAL(__memset)
+KASAN_OVERRIDE(memset, __memset)
cmplwi 0,r5,4
blt 7f
@@ -162,12 +163,14 @@ EXPORT_SYMBOL(memset)
* We therefore jump to generic_memcpy which doesn't use dcbz. This jump is
* replaced by a nop once cache is active. This is done in machine_init()
*/
-_GLOBAL(memmove)
+_GLOBAL(__memmove)
+KASAN_OVERRIDE(memmove, __memmove)
cmplw 0,r3,r4
bgt backwards_memcpy
/* fall through */
-_GLOBAL(memcpy)
+_GLOBAL(__memcpy)
+KASAN_OVERRIDE(memcpy, __memcpy)
b generic_memcpy
add r7,r3,r5 /* test if the src & dst overlap */
add r8,r4,r5
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index f06f3577d8d1..8b755143204b 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -7,6 +7,8 @@ subdir-ccflags-$(CONFIG_PPC_WERROR) := -Werror
ccflags-$(CONFIG_PPC64) := $(NO_MINIMAL_TOC)
+KASAN_SANITIZE_kasan_init.o := n
+
obj-y := fault.o mem.o pgtable.o mmap.o \
init_$(BITS).o pgtable_$(BITS).o \
init-common.o mmu_context.o drmem.o
@@ -45,3 +47,4 @@ obj-$(CONFIG_SPAPR_TCE_IOMMU) += mmu_context_iommu.o
obj-$(CONFIG_PPC_PTDUMP) += dump_linuxpagetables.o
obj-$(CONFIG_PPC_HTDUMP) += dump_hashpagetable.o
obj-$(CONFIG_PPC_MEM_KEYS) += pkeys.o
+obj-$(CONFIG_KASAN) += kasan_init.o
diff --git a/arch/powerpc/mm/dump_linuxpagetables.c b/arch/powerpc/mm/dump_linuxpagetables.c
index 876e2a3c79f2..8e0c8a0f06ba 100644
--- a/arch/powerpc/mm/dump_linuxpagetables.c
+++ b/arch/powerpc/mm/dump_linuxpagetables.c
@@ -91,6 +91,10 @@ static struct addr_marker address_markers[] = {
{ 0, "Consistent mem start" },
{ 0, "Consistent mem end" },
#endif
+#ifdef CONFIG_KASAN
+ { 0, "kasan shadow mem start" },
+ { 0, "kasan shadow mem end" },
+#endif
#ifdef CONFIG_HIGHMEM
{ 0, "Highmem PTEs start" },
{ 0, "Highmem PTEs end" },
@@ -459,6 +463,10 @@ static void populate_markers(void)
address_markers[i++].start_address = IOREMAP_TOP +
CONFIG_CONSISTENT_SIZE;
#endif
+#ifdef CONFIG_KASAN
+ address_markers[i++].start_address = KASAN_SHADOW_START;
+ address_markers[i++].start_address = KASAN_SHADOW_END;
+#endif
#ifdef CONFIG_HIGHMEM
address_markers[i++].start_address = PKMAP_BASE;
address_markers[i++].start_address = PKMAP_ADDR(LAST_PKMAP);
diff --git a/arch/powerpc/mm/kasan_init.c b/arch/powerpc/mm/kasan_init.c
new file mode 100644
index 000000000000..3331239edcbb
--- /dev/null
+++ b/arch/powerpc/mm/kasan_init.c
@@ -0,0 +1,73 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/kasan.h>
+#include <linux/printk.h>
+#include <linux/memblock.h>
+#include <linux/bootmem.h>
+#include <asm/pgalloc.h>
+
+void __init kasan_early_init(void)
+{
+ unsigned long addr = KASAN_SHADOW_START & PGDIR_MASK;
+ unsigned long end = KASAN_SHADOW_END;
+ unsigned long next;
+ pmd_t *pmd = pmd_offset(pud_offset(pgd_offset_k(addr), addr), addr);
+ int i;
+ phys_addr_t pa = __pa(kasan_zero_page);
+
+ for (i = 0; i < PTRS_PER_PTE; i++)
+ kasan_zero_pte[i] = pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL_RO);
+
+ do {
+ next = pgd_addr_end(addr, end);
+ pmd_populate_kernel(&init_mm, pmd, kasan_zero_pte);
+ } while (pmd++, addr = next, addr != end);
+
+ pr_info("KASAN early init done\n");
+}
+
+static void __init kasan_init_region(struct memblock_region *reg)
+{
+ void *start = __va(reg->base);
+ void *end = __va(reg->base + reg->size);
+ unsigned long k_start, k_end, k_cur, k_next;
+ pmd_t *pmd;
+
+ if (start >= end)
+ return;
+
+ k_start = (unsigned long)kasan_mem_to_shadow(start);
+ k_end = (unsigned long)kasan_mem_to_shadow(end);
+ pmd = pmd_offset(pud_offset(pgd_offset_k(k_start), k_start), k_start);
+
+ for (k_cur = k_start; k_cur != k_end; k_cur = k_next, pmd++) {
+ k_next = pgd_addr_end(k_cur, k_end);
+ if ((void*)pmd_page_vaddr(*pmd) == kasan_zero_pte) {
+ pte_t *new = pte_alloc_one_kernel(&init_mm, k_cur);
+
+ if (!new)
+ panic("kasan: pte_alloc_one_kernel() failed");
+ memcpy(new, kasan_zero_pte, PTE_TABLE_SIZE);
+ pmd_populate_kernel(&init_mm, pmd, new);
+ }
+ };
+
+ for (k_cur = k_start; k_cur < k_end; k_cur += PAGE_SIZE) {
+ phys_addr_t pa = memblock_alloc(PAGE_SIZE, PAGE_SIZE);
+ pte_t pte = pfn_pte(pa >> PAGE_SHIFT, PAGE_KERNEL);
+
+ pmd = pmd_offset(pud_offset(pgd_offset_k(k_cur), k_cur), k_cur);
+ pte_update(pte_offset_kernel(pmd, k_cur), ~0, pte_val(pte));
+ }
+ flush_tlb_kernel_range(k_start, k_end);
+}
+
+void __init kasan_init(void)
+{
+ struct memblock_region *reg;
+
+ for_each_memblock(memory, reg)
+ kasan_init_region(reg);
+
+ pr_info("KASAN init done\n");
+}
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 5c8530d0c611..b5f6c2c2ac45 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -381,6 +381,10 @@ void __init mem_init(void)
pr_info(" * 0x%08lx..0x%08lx : highmem PTEs\n",
PKMAP_BASE, PKMAP_ADDR(LAST_PKMAP));
#endif /* CONFIG_HIGHMEM */
+#ifdef CONFIG_KASAN
+ pr_info(" * 0x%08lx..0x%08lx : kasan shadow mem\n",
+ KASAN_SHADOW_START, KASAN_SHADOW_END);
+#endif
#ifdef CONFIG_NOT_COHERENT_CACHE
pr_info(" * 0x%08lx..0x%08lx : consistent mem\n",
IOREMAP_TOP, IOREMAP_TOP + CONFIG_CONSISTENT_SIZE);
--
2.13.3
^ permalink raw reply related
* [PATCH v07 0/9] powerpc/hotplug: Update affinity for migrated CPUs
From: Michael Bringmann @ 2018-07-13 20:16 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Bringmann, Nathan Fontenot, John Allen, Tyrel Datwyler,
Thomas Falcon
The migration of LPARs across Power systems affects many attributes
including that of the associativity of CPUs. The patches in this
set execute when a system is coming up fresh upon a migration target.
They are intended to,
* Recognize changes to the associativity of CPUs recorded in internal
data structures when compared to the latest copies in the device tree.
* Generate calls to other code layers to reset the data structures
related to associativity of the CPUs.
* Re-register the 'changed' entities into the target system.
Re-registration of CPUs mostly entails acting as if they have been
newly hot-added into the target system.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
Michael Bringmann (9):
hotplug/cpu: Conditionally acquire/release DRC index
hotplug/cpu: Add operation queuing function
hotplug/cpu: Provide CPU readd operation
mobility/numa: Ensure numa update does not overlap
numa: Disable/enable arch_update_cpu_topology
pmt/numa: Disable arch_update_cpu_topology during CPU readd
powerpc/rtas: Allow disabling rtas_event_scan
hotplug/rtas: No rtas_event_scan during PMT update
hotplug/pmt: Update topology after PMT
---
Changes in patch:
-- Restructure and rearrange content of patches to co-locate
similar or related modifications
-- Rename pseries_update_drconf_cpu to pseries_update_processor
-- Simplify code to update CPU nodes during mobility checks.
Remove functions to generate extra HP_ELOG messages in favor
of direct function calls to dlpar_cpu_readd_by_index.
-- Revise code order in dlpar_cpu_readd_by_index() to present
more appropriate error codes from underlying layers of the
implementation.
-- Add hotplug device lock around all property updates
-- Add call to rebuild_sched_domains in case of changes
-- Various code cleanups and compaction
-- Rebase to 4.18-rc1 kernel
-- Change operation to run CPU readd after end of migration store.
-- Improve descriptive text
-- Cleanup patch reference to outdated function
-- Code cleanup a 'acquire_drc' check in dlpar_cpu_add.
-- Code cleanup a 'release_drc' check in dlpar_cpu_remove.
^ permalink raw reply
* [PATCH v07 1/9] hotplug/cpu: Conditionally acquire/release DRC index
From: Michael Bringmann @ 2018-07-13 20:17 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Bringmann, Nathan Fontenot, John Allen, Tyrel Datwyler,
Thomas Falcon
In-Reply-To: <458ff569-f611-f506-afa1-138146551dde@linux.vnet.ibm.com>
powerpc/cpu: Modify dlpar_cpu_add and dlpar_cpu_remove to allow the
skipping of DRC index acquire or release operations during the CPU
add or remove operations. This is intended to support subsequent
changes to provide a 'CPU readd' operation.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in patch:
-- Move new validity check added to pseries_smp_notifier
to another patch
-- Revise one of checks for 'acquire_drc' in dlpar_cpu_add.
-- Revise one of checks for 'release_drc' in dlpar_cpu_remove.
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 71 +++++++++++++++-----------
1 file changed, 40 insertions(+), 31 deletions(-)
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 6ef77ca..7ede3b0 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -432,7 +432,7 @@ static bool valid_cpu_drc_index(struct device_node *parent, u32 drc_index)
return found;
}
-static ssize_t dlpar_cpu_add(u32 drc_index)
+static ssize_t dlpar_cpu_add(u32 drc_index, bool acquire_drc)
{
struct device_node *dn, *parent;
int rc, saved_rc;
@@ -457,19 +457,22 @@ static ssize_t dlpar_cpu_add(u32 drc_index)
return -EINVAL;
}
- rc = dlpar_acquire_drc(drc_index);
- if (rc) {
- pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n",
- rc, drc_index);
- of_node_put(parent);
- return -EINVAL;
+ if (acquire_drc) {
+ rc = dlpar_acquire_drc(drc_index);
+ if (rc) {
+ pr_warn("Failed to acquire DRC, rc: %d, drc index: %x\n",
+ rc, drc_index);
+ of_node_put(parent);
+ return -EINVAL;
+ }
}
dn = dlpar_configure_connector(cpu_to_be32(drc_index), parent);
if (!dn) {
pr_warn("Failed call to configure-connector, drc index: %x\n",
drc_index);
- dlpar_release_drc(drc_index);
+ if (acquire_drc)
+ dlpar_release_drc(drc_index);
of_node_put(parent);
return -EINVAL;
}
@@ -484,9 +487,11 @@ static ssize_t dlpar_cpu_add(u32 drc_index)
pr_warn("Failed to attach node %s, rc: %d, drc index: %x\n",
dn->name, rc, drc_index);
- rc = dlpar_release_drc(drc_index);
- if (!rc)
- dlpar_free_cc_nodes(dn);
+ if (acquire_drc) {
+ rc = dlpar_release_drc(drc_index);
+ if (!rc)
+ dlpar_free_cc_nodes(dn);
+ }
return saved_rc;
}
@@ -498,7 +503,7 @@ static ssize_t dlpar_cpu_add(u32 drc_index)
dn->name, rc, drc_index);
rc = dlpar_detach_node(dn);
- if (!rc)
+ if (!rc && acquire_drc)
dlpar_release_drc(drc_index);
return saved_rc;
@@ -566,7 +571,8 @@ static int dlpar_offline_cpu(struct device_node *dn)
}
-static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
+static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index,
+ bool release_drc)
{
int rc;
@@ -579,12 +585,14 @@ static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
return -EINVAL;
}
- rc = dlpar_release_drc(drc_index);
- if (rc) {
- pr_warn("Failed to release drc (%x) for CPU %s, rc: %d\n",
- drc_index, dn->name, rc);
- dlpar_online_cpu(dn);
- return rc;
+ if (release_drc) {
+ rc = dlpar_release_drc(drc_index);
+ if (rc) {
+ pr_warn("Failed to release drc (%x) for CPU %s, rc: %d\n",
+ drc_index, dn->name, rc);
+ dlpar_online_cpu(dn);
+ return rc;
+ }
}
rc = dlpar_detach_node(dn);
@@ -593,8 +601,9 @@ static ssize_t dlpar_cpu_remove(struct device_node *dn, u32 drc_index)
pr_warn("Failed to detach CPU %s, rc: %d", dn->name, rc);
- rc = dlpar_acquire_drc(drc_index);
- if (!rc)
+ if (release_drc)
+ rc = dlpar_acquire_drc(drc_index);
+ if (!release_drc || !rc)
dlpar_online_cpu(dn);
return saved_rc;
@@ -622,7 +631,7 @@ static struct device_node *cpu_drc_index_to_dn(u32 drc_index)
return dn;
}
-static int dlpar_cpu_remove_by_index(u32 drc_index)
+static int dlpar_cpu_remove_by_index(u32 drc_index, bool release_drc)
{
struct device_node *dn;
int rc;
@@ -634,7 +643,7 @@ static int dlpar_cpu_remove_by_index(u32 drc_index)
return -ENODEV;
}
- rc = dlpar_cpu_remove(dn, drc_index);
+ rc = dlpar_cpu_remove(dn, drc_index, release_drc);
of_node_put(dn);
return rc;
}
@@ -699,7 +708,7 @@ static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
}
for (i = 0; i < cpus_to_remove; i++) {
- rc = dlpar_cpu_remove_by_index(cpu_drcs[i]);
+ rc = dlpar_cpu_remove_by_index(cpu_drcs[i], true);
if (rc)
break;
@@ -710,7 +719,7 @@ static int dlpar_cpu_remove_by_count(u32 cpus_to_remove)
pr_warn("CPU hot-remove failed, adding back removed CPUs\n");
for (i = 0; i < cpus_removed; i++)
- dlpar_cpu_add(cpu_drcs[i]);
+ dlpar_cpu_add(cpu_drcs[i], true);
rc = -EINVAL;
} else {
@@ -780,7 +789,7 @@ static int dlpar_cpu_add_by_count(u32 cpus_to_add)
}
for (i = 0; i < cpus_to_add; i++) {
- rc = dlpar_cpu_add(cpu_drcs[i]);
+ rc = dlpar_cpu_add(cpu_drcs[i], true);
if (rc)
break;
@@ -791,7 +800,7 @@ static int dlpar_cpu_add_by_count(u32 cpus_to_add)
pr_warn("CPU hot-add failed, removing any added CPUs\n");
for (i = 0; i < cpus_added; i++)
- dlpar_cpu_remove_by_index(cpu_drcs[i]);
+ dlpar_cpu_remove_by_index(cpu_drcs[i], true);
rc = -EINVAL;
} else {
@@ -817,7 +826,7 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
rc = dlpar_cpu_remove_by_count(count);
else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
- rc = dlpar_cpu_remove_by_index(drc_index);
+ rc = dlpar_cpu_remove_by_index(drc_index, true);
else
rc = -EINVAL;
break;
@@ -825,7 +834,7 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_COUNT)
rc = dlpar_cpu_add_by_count(count);
else if (hp_elog->id_type == PSERIES_HP_ELOG_ID_DRC_INDEX)
- rc = dlpar_cpu_add(drc_index);
+ rc = dlpar_cpu_add(drc_index, true);
else
rc = -EINVAL;
break;
@@ -850,7 +859,7 @@ static ssize_t dlpar_cpu_probe(const char *buf, size_t count)
if (rc)
return -EINVAL;
- rc = dlpar_cpu_add(drc_index);
+ rc = dlpar_cpu_add(drc_index, true);
return rc ? rc : count;
}
@@ -871,7 +880,7 @@ static ssize_t dlpar_cpu_release(const char *buf, size_t count)
return -EINVAL;
}
- rc = dlpar_cpu_remove(dn, drc_index);
+ rc = dlpar_cpu_remove(dn, drc_index, true);
of_node_put(dn);
return rc ? rc : count;
^ permalink raw reply related
* [PATCH v07 2/9] hotplug/cpu: Add operation queuing function
From: Michael Bringmann @ 2018-07-13 20:18 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Bringmann, Nathan Fontenot, John Allen, Tyrel Datwyler,
Thomas Falcon
In-Reply-To: <458ff569-f611-f506-afa1-138146551dde@linux.vnet.ibm.com>
migration/dlpar: This patch adds function dlpar_queue_action()
which will queued up information about a CPU/Memory 'readd'
operation according to resource type, action code, and DRC index.
At a subsequent point, the list of operations can be run/played
in series. Examples of such oprations include 'readd' of CPU
and Memory blocks identified as having changed their associativity
during an LPAR migration event.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in patch:
-- Correct drc_index before adding to pseries_hp_errorlog struct
-- Correct text of notice
-- Revise queuing model to save up all of the DLPAR actions for
later execution.
-- Restore list init statement missing from patch
-- Move call to apply queued operations into 'mobility.c'
-- Compress some code
-- Rename some of queueing function APIs
-- Revise implementation to push execution of queued operations
to a workqueue task.
-- Cleanup reference to outdated queuing operation.
---
arch/powerpc/include/asm/rtas.h | 2 +
arch/powerpc/platforms/pseries/dlpar.c | 61 +++++++++++++++++++++++++++++
arch/powerpc/platforms/pseries/mobility.c | 4 ++
arch/powerpc/platforms/pseries/pseries.h | 2 +
4 files changed, 69 insertions(+)
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 71e393c..4f601c7 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -310,12 +310,14 @@ struct pseries_hp_errorlog {
struct { __be32 count, index; } ic;
char drc_name[1];
} _drc_u;
+ struct list_head list;
};
#define PSERIES_HP_ELOG_RESOURCE_CPU 1
#define PSERIES_HP_ELOG_RESOURCE_MEM 2
#define PSERIES_HP_ELOG_RESOURCE_SLOT 3
#define PSERIES_HP_ELOG_RESOURCE_PHB 4
+#define PSERIES_HP_ELOG_RESOURCE_PMT 5
#define PSERIES_HP_ELOG_ACTION_ADD 1
#define PSERIES_HP_ELOG_ACTION_REMOVE 2
diff --git a/arch/powerpc/platforms/pseries/dlpar.c b/arch/powerpc/platforms/pseries/dlpar.c
index a0b20c0..7264b8e 100644
--- a/arch/powerpc/platforms/pseries/dlpar.c
+++ b/arch/powerpc/platforms/pseries/dlpar.c
@@ -25,6 +25,7 @@
#include <asm/prom.h>
#include <asm/machdep.h>
#include <linux/uaccess.h>
+#include <linux/delay.h>
#include <asm/rtas.h>
static struct workqueue_struct *pseries_hp_wq;
@@ -329,6 +330,8 @@ int dlpar_release_drc(u32 drc_index)
return 0;
}
+static int dlpar_pmt(struct pseries_hp_errorlog *work);
+
static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
{
int rc;
@@ -357,6 +360,9 @@ static int handle_dlpar_errorlog(struct pseries_hp_errorlog *hp_elog)
case PSERIES_HP_ELOG_RESOURCE_CPU:
rc = dlpar_cpu(hp_elog);
break;
+ case PSERIES_HP_ELOG_RESOURCE_PMT:
+ rc = dlpar_pmt(hp_elog);
+ break;
default:
pr_warn_ratelimited("Invalid resource (%d) specified\n",
hp_elog->resource);
@@ -407,6 +413,61 @@ void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog,
}
}
+LIST_HEAD(dlpar_delayed_list);
+
+int dlpar_queue_action(int resource, int action, u32 drc_index)
+{
+ struct pseries_hp_errorlog *hp_errlog;
+
+ hp_errlog = kmalloc(sizeof(struct pseries_hp_errorlog), GFP_KERNEL);
+ if (!hp_errlog)
+ return -ENOMEM;
+
+ hp_errlog->resource = resource;
+ hp_errlog->action = action;
+ hp_errlog->id_type = PSERIES_HP_ELOG_ID_DRC_INDEX;
+ hp_errlog->_drc_u.drc_index = cpu_to_be32(drc_index);
+
+ list_add_tail(&hp_errlog->list, &dlpar_delayed_list);
+
+ return 0;
+}
+
+static int dlpar_pmt(struct pseries_hp_errorlog *work)
+{
+ struct list_head *pos, *q;
+
+ ssleep(15);
+
+ list_for_each_safe(pos, q, &dlpar_delayed_list) {
+ struct pseries_hp_errorlog *tmp;
+
+ tmp = list_entry(pos, struct pseries_hp_errorlog, list);
+ handle_dlpar_errorlog(tmp);
+
+ list_del(pos);
+ kfree(tmp);
+
+ ssleep(10);
+ }
+
+ return 0;
+}
+
+int dlpar_queued_actions_run(void)
+{
+ if (!list_empty(&dlpar_delayed_list)) {
+ struct pseries_hp_errorlog hp_errlog;
+
+ hp_errlog.resource = PSERIES_HP_ELOG_RESOURCE_PMT;
+ hp_errlog.action = 0;
+ hp_errlog.id_type = 0;
+
+ queue_hotplug_event(&hp_errlog, 0, 0);
+ }
+ return 0;
+}
+
static int dlpar_parse_resource(char **cmd, struct pseries_hp_errorlog *hp_elog)
{
char *arg;
diff --git a/arch/powerpc/platforms/pseries/mobility.c b/arch/powerpc/platforms/pseries/mobility.c
index f6364d9..d0d1cae 100644
--- a/arch/powerpc/platforms/pseries/mobility.c
+++ b/arch/powerpc/platforms/pseries/mobility.c
@@ -378,6 +378,10 @@ static ssize_t migration_store(struct class *class,
return rc;
post_mobility_fixup();
+
+ /* Apply any necessary changes identified during fixup */
+ dlpar_queued_actions_run();
+
return count;
}
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index 60db2ee..72ca996 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -61,6 +61,8 @@ extern struct device_node *dlpar_configure_connector(__be32,
void queue_hotplug_event(struct pseries_hp_errorlog *hp_errlog,
struct completion *hotplug_done, int *rc);
+int dlpar_queue_action(int resource, int action, u32 drc_index);
+int dlpar_queued_actions_run(void);
#ifdef CONFIG_MEMORY_HOTPLUG
int dlpar_memory(struct pseries_hp_errorlog *hp_elog);
#else
^ permalink raw reply related
* [PATCH v07 3/9] hotplug/cpu: Provide CPU readd operation
From: Michael Bringmann @ 2018-07-13 20:18 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Bringmann, Nathan Fontenot, John Allen, Tyrel Datwyler,
Thomas Falcon
In-Reply-To: <458ff569-f611-f506-afa1-138146551dde@linux.vnet.ibm.com>
powerpc/dlpar: Provide hotplug CPU 'readd by index' operation to
support LPAR Post Migration state updates. When such changes are
invoked by the PowerPC 'mobility' code, they will be queued up so
that modifications to CPU properties will take place after the new
property value is written to the device-tree.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
Changes in patch:
-- Add CPU validity check to pseries_smp_notifier
-- Improve check on 'ibm,associativity' property
-- Add check for cpu type to new update property entry
-- Cleanup reference to outdated queuing function.
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 58 ++++++++++++++++++++++++++
1 file changed, 58 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 7ede3b0..1906ee57 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -305,6 +305,36 @@ static int pseries_add_processor(struct device_node *np)
return err;
}
+static int pseries_update_processor(struct of_reconfig_data *pr)
+{
+ int old_entries, new_entries, rc = 0;
+ __be32 *old_assoc, *new_assoc;
+
+ /* We only handle changes due to 'ibm,associativity' property
+ */
+ old_assoc = pr->old_prop->value;
+ old_entries = be32_to_cpu(*old_assoc++);
+
+ new_assoc = pr->prop->value;
+ new_entries = be32_to_cpu(*new_assoc++);
+
+ if (old_entries == new_entries) {
+ int sz = old_entries * sizeof(int);
+
+ if (memcmp(old_assoc, new_assoc, sz))
+ rc = dlpar_queue_action(
+ PSERIES_HP_ELOG_RESOURCE_CPU,
+ PSERIES_HP_ELOG_ACTION_READD,
+ pr->dn->phandle);
+ } else {
+ rc = dlpar_queue_action(PSERIES_HP_ELOG_RESOURCE_CPU,
+ PSERIES_HP_ELOG_ACTION_READD,
+ pr->dn->phandle);
+ }
+
+ return rc;
+}
+
/*
* Update the present map for a cpu node which is going away, and set
* the hard id in the paca(s) to -1 to be consistent with boot time
@@ -648,6 +678,26 @@ static int dlpar_cpu_remove_by_index(u32 drc_index, bool release_drc)
return rc;
}
+static int dlpar_cpu_readd_by_index(u32 drc_index)
+{
+ int rc = 0;
+
+ pr_info("Attempting to re-add CPU, drc index %x\n", drc_index);
+
+ rc = dlpar_cpu_remove_by_index(drc_index, false);
+ if (!rc)
+ rc = dlpar_cpu_add(drc_index, false);
+
+ if (rc)
+ pr_info("Failed to update cpu at drc_index %lx\n",
+ (unsigned long int)drc_index);
+ else
+ pr_info("CPU at drc_index %lx was updated\n",
+ (unsigned long int)drc_index);
+
+ return rc;
+}
+
static int find_dlpar_cpus_to_remove(u32 *cpu_drcs, int cpus_to_remove)
{
struct device_node *dn;
@@ -838,6 +888,9 @@ int dlpar_cpu(struct pseries_hp_errorlog *hp_elog)
else
rc = -EINVAL;
break;
+ case PSERIES_HP_ELOG_ACTION_READD:
+ rc = dlpar_cpu_readd_by_index(drc_index);
+ break;
default:
pr_err("Invalid action (%d) specified\n", hp_elog->action);
rc = -EINVAL;
@@ -901,6 +954,11 @@ static int pseries_smp_notifier(struct notifier_block *nb,
case OF_RECONFIG_DETACH_NODE:
pseries_remove_processor(rd->dn);
break;
+ case OF_RECONFIG_UPDATE_PROPERTY:
+ if (!strcmp(rd->dn->type, "cpu") &&
+ !strcmp(rd->prop->name, "ibm,associativity"))
+ pseries_update_processor(rd);
+ break;
}
return notifier_from_errno(err);
}
^ permalink raw reply related
* [PATCH v07 4/9] mobility/numa: Ensure numa update does not overlap
From: Michael Bringmann @ 2018-07-13 20:18 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Bringmann, Nathan Fontenot, John Allen, Tyrel Datwyler,
Thomas Falcon
In-Reply-To: <458ff569-f611-f506-afa1-138146551dde@linux.vnet.ibm.com>
mobility/numa: Ensure that numa_update_cpu_topology() can not be
entered multiple times concurrently. It may be accessed through
many different paths / concurrent work functions, and the lock
ordering may be difficult to ensure otherwise.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
arch/powerpc/mm/numa.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index a789d57..b22e27a 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1079,6 +1079,7 @@ struct topology_update_data {
static int topology_timer_secs = 1;
static int topology_inited;
static int topology_update_needed;
+static struct mutex topology_update_lock;
/*
* Change polling interval for associativity changes.
@@ -1320,6 +1321,11 @@ int numa_update_cpu_topology(bool cpus_locked)
if (!updates)
return 0;
+ if (!mutex_trylock(&topology_update_lock)) {
+ kfree(updates);
+ return 0;
+ }
+
cpumask_clear(&updated_cpus);
for_each_cpu(cpu, &cpu_associativity_changes_mask) {
@@ -1424,6 +1430,7 @@ int numa_update_cpu_topology(bool cpus_locked)
out:
kfree(updates);
topology_update_needed = 0;
+ mutex_unlock(&topology_update_lock);
return changed;
}
@@ -1598,6 +1605,8 @@ static ssize_t topology_write(struct file *file, const char __user *buf,
static int topology_update_init(void)
{
+ mutex_init(&topology_update_lock);
+
/* Do not poll for changes if disabled at boot */
if (topology_updates_enabled)
start_topology_update();
^ permalink raw reply related
* [PATCH v07 5/9] numa: Disable/enable arch_update_cpu_topology
From: Michael Bringmann @ 2018-07-13 20:18 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Bringmann, Nathan Fontenot, John Allen, Tyrel Datwyler,
Thomas Falcon
In-Reply-To: <458ff569-f611-f506-afa1-138146551dde@linux.vnet.ibm.com>
numa: Provide mechanism to disable/enable operation of
arch_update_cpu_topology/numa_update_cpu_topology. This is
a simple tool to eliminate some avenues for thread deadlock
observed during system execution.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/topology.h | 10 ++++++++++
arch/powerpc/mm/numa.c | 14 ++++++++++++++
2 files changed, 24 insertions(+)
diff --git a/arch/powerpc/include/asm/topology.h b/arch/powerpc/include/asm/topology.h
index 16b0778..d9ceba6 100644
--- a/arch/powerpc/include/asm/topology.h
+++ b/arch/powerpc/include/asm/topology.h
@@ -43,6 +43,8 @@ static inline int pcibus_to_node(struct pci_bus *bus)
extern int sysfs_add_device_to_node(struct device *dev, int nid);
extern void sysfs_remove_device_from_node(struct device *dev, int nid);
extern int numa_update_cpu_topology(bool cpus_locked);
+extern void arch_update_cpu_topology_suspend(void);
+extern void arch_update_cpu_topology_resume(void);
static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node)
{
@@ -82,6 +84,14 @@ static inline int numa_update_cpu_topology(bool cpus_locked)
return 0;
}
+static inline void arch_update_cpu_topology_suspend(void)
+{
+}
+
+static inline void arch_update_cpu_topology_resume(void)
+{
+}
+
static inline void update_numa_cpu_lookup_table(unsigned int cpu, int node) {}
#endif /* CONFIG_NUMA */
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index b22e27a..2352489 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1079,6 +1079,7 @@ struct topology_update_data {
static int topology_timer_secs = 1;
static int topology_inited;
static int topology_update_needed;
+static int topology_update_enabled = 1;
static struct mutex topology_update_lock;
/*
@@ -1313,6 +1314,9 @@ int numa_update_cpu_topology(bool cpus_locked)
return 0;
}
+ if (!topology_update_enabled)
+ return 0;
+
weight = cpumask_weight(&cpu_associativity_changes_mask);
if (!weight)
return 0;
@@ -1439,6 +1443,16 @@ int arch_update_cpu_topology(void)
return numa_update_cpu_topology(true);
}
+void arch_update_cpu_topology_suspend(void)
+{
+ topology_update_enabled = 0;
+}
+
+void arch_update_cpu_topology_resume(void)
+{
+ topology_update_enabled = 1;
+}
+
static void topology_work_fn(struct work_struct *work)
{
rebuild_sched_domains();
^ permalink raw reply related
* [PATCH v07 6/9] pmt/numa: Disable arch_update_cpu_topology during CPU readd
From: Michael Bringmann @ 2018-07-13 20:18 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Bringmann, Nathan Fontenot, John Allen, Tyrel Datwyler,
Thomas Falcon
In-Reply-To: <458ff569-f611-f506-afa1-138146551dde@linux.vnet.ibm.com>
pmt/numa: Disable arch_update_cpu_topology during post migration
CPU readd updates when evaluating device-tree changes after LPM
to avoid thread deadlocks trying to update node assignments.
System timing between all of the threads and timers restarted in
a migrated system overlapped frequently allowing tasks to start
acquiring resources (get_online_cpus) needed by rebuild_sched_domains.
Defer the operation of that function until after the CPU readd has
completed.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 1906ee57..df1791b 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -26,6 +26,7 @@
#include <linux/sched.h> /* for idle_task_exit */
#include <linux/sched/hotplug.h>
#include <linux/cpu.h>
+#include <linux/cpuset.h>
#include <linux/of.h>
#include <linux/slab.h>
#include <asm/prom.h>
@@ -684,9 +685,15 @@ static int dlpar_cpu_readd_by_index(u32 drc_index)
pr_info("Attempting to re-add CPU, drc index %x\n", drc_index);
+ arch_update_cpu_topology_suspend();
rc = dlpar_cpu_remove_by_index(drc_index, false);
- if (!rc)
+ arch_update_cpu_topology_resume();
+
+ if (!rc) {
+ arch_update_cpu_topology_suspend();
rc = dlpar_cpu_add(drc_index, false);
+ arch_update_cpu_topology_resume();
+ }
if (rc)
pr_info("Failed to update cpu at drc_index %lx\n",
^ permalink raw reply related
* [PATCH v07 7/9] powerpc/rtas: Allow disabling rtas_event_scan
From: Michael Bringmann @ 2018-07-13 20:18 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Bringmann, Nathan Fontenot, John Allen, Tyrel Datwyler,
Thomas Falcon
In-Reply-To: <458ff569-f611-f506-afa1-138146551dde@linux.vnet.ibm.com>
powerpc/rtas: Provide mechanism by which the rtas_event_scan can
be disabled/re-enabled by other portions of the powerpc code.
Among other things, this simplifies the usage of locking mechanisms
for shared kernel resources.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
arch/powerpc/include/asm/rtas.h | 4 ++++
arch/powerpc/kernel/rtasd.c | 14 ++++++++++++++
2 files changed, 18 insertions(+)
diff --git a/arch/powerpc/include/asm/rtas.h b/arch/powerpc/include/asm/rtas.h
index 4f601c7..4ab605a 100644
--- a/arch/powerpc/include/asm/rtas.h
+++ b/arch/powerpc/include/asm/rtas.h
@@ -386,8 +386,12 @@ extern int early_init_dt_scan_rtas(unsigned long node,
#ifdef CONFIG_PPC_RTAS_DAEMON
extern void rtas_cancel_event_scan(void);
+extern void rtas_event_scan_disable(void);
+extern void rtas_event_scan_enable(void);
#else
static inline void rtas_cancel_event_scan(void) { }
+static inline void rtas_event_scan_disable(void) { }
+static inline void rtas_event_scan_enable(void) { }
#endif
/* Error types logged. */
diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 44d66c33d..af69e44 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -455,11 +455,25 @@ static void do_event_scan(void)
*/
static unsigned long event_scan_delay = 1*HZ;
static int first_pass = 1;
+static int res_enable = 1;
+
+void rtas_event_scan_disable(void)
+{
+ res_enable = 0;
+}
+
+void rtas_event_scan_enable(void)
+{
+ res_enable = 1;
+}
static void rtas_event_scan(struct work_struct *w)
{
unsigned int cpu;
+ if (!res_enable)
+ return;
+
do_event_scan();
get_online_cpus();
^ permalink raw reply related
* [PATCH v07 8/9] hotplug/rtas: No rtas_event_scan during PMT update
From: Michael Bringmann @ 2018-07-13 20:18 UTC (permalink / raw)
To: linuxppc-dev
Cc: Michael Bringmann, Nathan Fontenot, John Allen, Tyrel Datwyler,
Thomas Falcon
In-Reply-To: <458ff569-f611-f506-afa1-138146551dde@linux.vnet.ibm.com>
hotplug/rtas: Disable rtas_event_scan during device-tree property
updates after migration to reduce conflicts with changes propagated
to other parts of the kernel configuration, such as CPUs or memory.
Signed-off-by: Michael Bringmann <mwb@linux.vnet.ibm.com>
---
arch/powerpc/platforms/pseries/hotplug-cpu.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index df1791b..09633de 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -685,14 +685,18 @@ static int dlpar_cpu_readd_by_index(u32 drc_index)
pr_info("Attempting to re-add CPU, drc index %x\n", drc_index);
+ rtas_event_scan_disable();
arch_update_cpu_topology_suspend();
rc = dlpar_cpu_remove_by_index(drc_index, false);
arch_update_cpu_topology_resume();
+ rtas_event_scan_enable();
if (!rc) {
+ rtas_event_scan_disable();
arch_update_cpu_topology_suspend();
rc = dlpar_cpu_add(drc_index, false);
arch_update_cpu_topology_resume();
+ rtas_event_scan_enable();
}
if (rc)
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox