Commit cae66f1a authored by Corey Minyard's avatar Corey Minyard
Browse files

ipmi:si: Fix check for a misbehaving BMC



There is a race on checking the state in the sender, it needs to be
checked under a lock.  But you also need a check to avoid issues with
a misbehaving BMC for run to completion mode.  So leave the check at
the beginning for run to completion, and add a check under the lock
to avoid the race.

Reported-by: default avatarRafael J. Wysocki <rafael@kernel.org>
Fixes: bc3a9d21 ("ipmi:si: Gracefully handle if the BMC is non-functional")
Cc: stable@vger.kernel.org # 4.18
Signed-off-by: default avatarCorey Minyard <corey@minyard.net>
Reviewed-by: default avatarRafael J. Wysocki (Intel) <rafael@kernel.org>
parent 62cd1454
Loading
Loading
Loading
Loading
+13 −11
Original line number Diff line number Diff line
@@ -924,9 +924,14 @@ static int sender(void *send_info, struct ipmi_smi_msg *msg)
{
	struct smi_info   *smi_info = send_info;
	unsigned long     flags;
	int rv = IPMI_CC_NO_ERROR;

	debug_timestamp(smi_info, "Enqueue");

	/*
	 * Check here for run to completion mode.  A check under lock is
	 * later.
	 */
	if (smi_info->si_state == SI_HOSED)
		return IPMI_BUS_ERR;

@@ -940,18 +945,15 @@ static int sender(void *send_info, struct ipmi_smi_msg *msg)
	}

	spin_lock_irqsave(&smi_info->si_lock, flags);
	/*
	 * The following two lines don't need to be under the lock for
	 * the lock's sake, but they do need SMP memory barriers to
	 * avoid getting things out of order.  We are already claiming
	 * the lock, anyway, so just do it under the lock to avoid the
	 * ordering problem.
	 */
	if (smi_info->si_state == SI_HOSED) {
		rv = IPMI_BUS_ERR;
	} else {
		BUG_ON(smi_info->waiting_msg);
		smi_info->waiting_msg = msg;
		check_start_timer_thread(smi_info);
	}
	spin_unlock_irqrestore(&smi_info->si_lock, flags);
	return IPMI_CC_NO_ERROR;
	return rv;
}

static void set_run_to_completion(void *send_info, bool i_run_to_completion)