summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
diff options
context:
space:
mode:
authorJinhui Guo <guojinhui.liam@bytedance.com>2025-09-30 15:42:37 +0800
committerCorey Minyard <corey@minyard.net>2025-10-14 15:52:58 -0500
commit936750fdba4c45e13bbd17f261bb140dd55f5e93 (patch)
tree14d5b85d6cfd44c8ecc6f354aee5042b78b36313 /drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c
parent9b332cece987ee1790b2ed4c989e28162fa47860 (diff)
ipmi: Fix the race between __scan_channels() and deliver_response()
The race window between __scan_channels() and deliver_response() causes the parameters of some channels to be set to 0. 1.[CPUA] __scan_channels() issues an IPMI request and waits with wait_event() until all channels have been scanned. wait_event() internally calls might_sleep(), which might yield the CPU. (Moreover, an interrupt can preempt wait_event() and force the task to yield the CPU.) 2.[CPUB] deliver_response() is invoked when the CPU receives the IPMI response. After processing a IPMI response, deliver_response() directly assigns intf->wchannels to intf->channel_list and sets intf->channels_ready to true. However, not all channels are actually ready for use. 3.[CPUA] Since intf->channels_ready is already true, wait_event() never enters __wait_event(). __scan_channels() immediately clears intf->null_user_handler and exits. 4.[CPUB] Once intf->null_user_handler is set to NULL, deliver_response() ignores further IPMI responses, leaving the remaining channels zero-initialized and unusable. CPUA CPUB ------------------------------- ----------------------------- __scan_channels() intf->null_user_handler = channel_handler; send_channel_info_cmd(intf, 0); wait_event(intf->waitq, intf->channels_ready); do { might_sleep(); deliver_response() channel_handler() intf->channel_list = intf->wchannels + set; intf->channels_ready = true; send_channel_info_cmd(intf, intf->curr_channel); if (condition) break; __wait_event(wq_head, condition); } while(0) intf->null_user_handler = NULL; deliver_response() if (!msg->user) if (intf->null_user_handler) rv = -EINVAL; return rv; ------------------------------- ----------------------------- Fix the race between __scan_channels() and deliver_response() by deferring both the assignment intf->channel_list = intf->wchannels and the flag intf->channels_ready = true until all channels have been successfully scanned or until the IPMI request has failed. Signed-off-by: Jinhui Guo <guojinhui.liam@bytedance.com> Message-ID: <20250930074239.2353-2-guojinhui.liam@bytedance.com> Signed-off-by: Corey Minyard <corey@minyard.net>
Diffstat (limited to 'drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c')
0 files changed, 0 insertions, 0 deletions