Commit bfe51886 authored by Geoff Levand's avatar Geoff Levand Committed by Michael Ellerman

powerpc: Fix PS3 allmodconfig warning

The struct ps3_notification_device in the ps3_probe_thread routine
is too large to be on the stack, causing a warning for an
allmodconfig build with clang.

Change the struct ps3_notification_device from a variable on the stack
to a dynamically allocated variable.
Reported-by: default avatarArnd Bergmann <arnd@kernel.org>
Signed-off-by: default avatarGeoff Levand <geoff@infradead.org>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://msgid.link/d64f06f4-81ae-4ec5-ab3b-d7f7f091e0ac@infradead.org
parent 608d4a5c
...@@ -770,49 +770,51 @@ static struct task_struct *probe_task; ...@@ -770,49 +770,51 @@ static struct task_struct *probe_task;
static int ps3_probe_thread(void *data) static int ps3_probe_thread(void *data)
{ {
struct {
struct ps3_notification_device dev; struct ps3_notification_device dev;
u8 buf[512];
} *local;
struct ps3_notify_cmd *notify_cmd;
struct ps3_notify_event *notify_event;
int res; int res;
unsigned int irq; unsigned int irq;
u64 lpar; u64 lpar;
void *buf;
struct ps3_notify_cmd *notify_cmd;
struct ps3_notify_event *notify_event;
pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__); pr_debug(" -> %s:%u: kthread started\n", __func__, __LINE__);
buf = kzalloc(512, GFP_KERNEL); local = kzalloc(sizeof(*local), GFP_KERNEL);
if (!buf) if (!local)
return -ENOMEM; return -ENOMEM;
lpar = ps3_mm_phys_to_lpar(__pa(buf)); lpar = ps3_mm_phys_to_lpar(__pa(&local->buf));
notify_cmd = buf; notify_cmd = (struct ps3_notify_cmd *)&local->buf;
notify_event = buf; notify_event = (struct ps3_notify_event *)&local->buf;
/* dummy system bus device */ /* dummy system bus device */
dev.sbd.bus_id = (u64)data; local->dev.sbd.bus_id = (u64)data;
dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID; local->dev.sbd.dev_id = PS3_NOTIFICATION_DEV_ID;
dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID; local->dev.sbd.interrupt_id = PS3_NOTIFICATION_INTERRUPT_ID;
res = lv1_open_device(dev.sbd.bus_id, dev.sbd.dev_id, 0); res = lv1_open_device(local->dev.sbd.bus_id, local->dev.sbd.dev_id, 0);
if (res) { if (res) {
pr_err("%s:%u: lv1_open_device failed %s\n", __func__, pr_err("%s:%u: lv1_open_device failed %s\n", __func__,
__LINE__, ps3_result(res)); __LINE__, ps3_result(res));
goto fail_free; goto fail_free;
} }
res = ps3_sb_event_receive_port_setup(&dev.sbd, PS3_BINDING_CPU_ANY, res = ps3_sb_event_receive_port_setup(&local->dev.sbd,
&irq); PS3_BINDING_CPU_ANY, &irq);
if (res) { if (res) {
pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n", pr_err("%s:%u: ps3_sb_event_receive_port_setup failed %d\n",
__func__, __LINE__, res); __func__, __LINE__, res);
goto fail_close_device; goto fail_close_device;
} }
spin_lock_init(&dev.lock); spin_lock_init(&local->dev.lock);
rcuwait_init(&dev.wait); rcuwait_init(&local->dev.wait);
res = request_irq(irq, ps3_notification_interrupt, 0, res = request_irq(irq, ps3_notification_interrupt, 0,
"ps3_notification", &dev); "ps3_notification", &local->dev);
if (res) { if (res) {
pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__, pr_err("%s:%u: request_irq failed %d\n", __func__, __LINE__,
res); res);
...@@ -823,7 +825,7 @@ static int ps3_probe_thread(void *data) ...@@ -823,7 +825,7 @@ static int ps3_probe_thread(void *data)
notify_cmd->operation_code = 0; /* must be zero */ notify_cmd->operation_code = 0; /* must be zero */
notify_cmd->event_mask = 1UL << notify_region_probe; notify_cmd->event_mask = 1UL << notify_region_probe;
res = ps3_notification_read_write(&dev, lpar, 1); res = ps3_notification_read_write(&local->dev, lpar, 1);
if (res) if (res)
goto fail_free_irq; goto fail_free_irq;
...@@ -834,7 +836,7 @@ static int ps3_probe_thread(void *data) ...@@ -834,7 +836,7 @@ static int ps3_probe_thread(void *data)
memset(notify_event, 0, sizeof(*notify_event)); memset(notify_event, 0, sizeof(*notify_event));
res = ps3_notification_read_write(&dev, lpar, 0); res = ps3_notification_read_write(&local->dev, lpar, 0);
if (res) if (res)
break; break;
...@@ -845,25 +847,26 @@ static int ps3_probe_thread(void *data) ...@@ -845,25 +847,26 @@ static int ps3_probe_thread(void *data)
notify_event->dev_port); notify_event->dev_port);
if (notify_event->event_type != notify_region_probe || if (notify_event->event_type != notify_region_probe ||
notify_event->bus_id != dev.sbd.bus_id) { notify_event->bus_id != local->dev.sbd.bus_id) {
pr_warn("%s:%u: bad notify_event: event %llu, dev_id %llu, dev_type %llu\n", pr_warn("%s:%u: bad notify_event: event %llu, dev_id %llu, dev_type %llu\n",
__func__, __LINE__, notify_event->event_type, __func__, __LINE__, notify_event->event_type,
notify_event->dev_id, notify_event->dev_type); notify_event->dev_id, notify_event->dev_type);
continue; continue;
} }
ps3_find_and_add_device(dev.sbd.bus_id, notify_event->dev_id); ps3_find_and_add_device(local->dev.sbd.bus_id,
notify_event->dev_id);
} while (!kthread_should_stop()); } while (!kthread_should_stop());
fail_free_irq: fail_free_irq:
free_irq(irq, &dev); free_irq(irq, &local->dev);
fail_sb_event_receive_port_destroy: fail_sb_event_receive_port_destroy:
ps3_sb_event_receive_port_destroy(&dev.sbd, irq); ps3_sb_event_receive_port_destroy(&local->dev.sbd, irq);
fail_close_device: fail_close_device:
lv1_close_device(dev.sbd.bus_id, dev.sbd.dev_id); lv1_close_device(local->dev.sbd.bus_id, local->dev.sbd.dev_id);
fail_free: fail_free:
kfree(buf); kfree(local);
probe_task = NULL; probe_task = NULL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment