Commit b96536e7 authored by Daniel Verkamp's avatar Daniel Verkamp
Browse files

nvme: check request allocation when submitting AER



Previously, if nvme_allocate_request() failed in
nvme_ctrlr_construct_and_submit_aer(), there was no error checking, so a
NULL pointer would be dereferenced.

Add a return value to nvme_ctrlr_construct_and_submit_aer() so we can
signal failure to the caller.  This can only really be reasonably
handled during initialization; when resubmitting a completed AER later,
there is nowhere to report failure, so the AER will just remain
unsubmitted.

Change-Id: I413eb6c21be01cd9a61e67f62f2d0b7170eabaa3
Signed-off-by: default avatarDaniel Verkamp <daniel.verkamp@intel.com>
parent a0ba9ce2
Loading
Loading
Loading
Loading
+18 −4
Original line number Diff line number Diff line
@@ -38,7 +38,7 @@
 *
 */

static void nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
static int nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
		struct nvme_async_event_request *aer);

static int
@@ -520,10 +520,16 @@ nvme_ctrlr_async_event_cb(void *arg, const struct nvme_completion *cpl)
	 * Repost another asynchronous event request to replace the one
	 *  that just completed.
	 */
	nvme_ctrlr_construct_and_submit_aer(aer->ctrlr, aer);
	if (nvme_ctrlr_construct_and_submit_aer(ctrlr, aer)) {
		/*
		 * We can't do anything to recover from a failure here,
		 * so just print a warning message and leave the AER unsubmitted.
		 */
		nvme_printf(ctrlr, "resubmitting AER failed!\n");
	}
}

static void
static int
nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
				    struct nvme_async_event_request *aer)
{
@@ -532,6 +538,9 @@ nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
	aer->ctrlr = ctrlr;
	req = nvme_allocate_request(NULL, 0, nvme_ctrlr_async_event_cb, aer);
	aer->req = req;
	if (req == NULL) {
		return -1;
	}

	/*
	 * Disable timeout here, since asynchronous event requests should by
@@ -540,6 +549,8 @@ nvme_ctrlr_construct_and_submit_aer(struct nvme_controller *ctrlr,
	req->timeout = false;
	req->cmd.opc = NVME_OPC_ASYNC_EVENT_REQUEST;
	nvme_ctrlr_submit_admin_request(ctrlr, req);

	return 0;
}

static int
@@ -569,7 +580,10 @@ nvme_ctrlr_configure_aer(struct nvme_controller *ctrlr)

	for (i = 0; i < ctrlr->num_aers; i++) {
		aer = &ctrlr->aer[i];
		nvme_ctrlr_construct_and_submit_aer(ctrlr, aer);
		if (nvme_ctrlr_construct_and_submit_aer(ctrlr, aer)) {
			nvme_printf(ctrlr, "nvme_ctrlr_construct_and_submit_aer failed!\n");
			return -1;
		}
	}

	return 0;