aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/platforms/pseries/dlpar.c
diff options
context:
space:
mode:
authorNathan Lynch <nathanl@linux.ibm.com>2019-05-28 18:28:01 -0500
committerMichael Ellerman <mpe@ellerman.id.au>2019-06-19 20:05:08 +1000
commit348ea30f51fc63ce3c7fd7dba6043e8e3ee0ef34 (patch)
treead391ce2c50619edb86e197d51b62c5234e3b50f /arch/powerpc/platforms/pseries/dlpar.c
parentpowerpc/watchpoint: Restore NV GPRs while returning from exception (diff)
downloadlinux-dev-348ea30f51fc63ce3c7fd7dba6043e8e3ee0ef34.tar.xz
linux-dev-348ea30f51fc63ce3c7fd7dba6043e8e3ee0ef34.zip
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 <nathanl@linux.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Diffstat (limited to 'arch/powerpc/platforms/pseries/dlpar.c')
-rw-r--r--arch/powerpc/platforms/pseries/dlpar.c8
1 files changed, 4 insertions, 4 deletions
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;