aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristof Schmitt <christof.schmitt@de.ibm.com>2007-05-07 10:35:04 -0400
committerJames Bottomley <jejb@mulgrave.il.steeleye.com>2007-05-08 12:19:50 -0400
commitb03670e5277224d1166cb5e4f610fc388186b065 (patch)
treea89c29683450afec0035acbabd4e6aaeadc02349
parent2135be5f24ee6620ea6f2a594087d51b6a67ce7e (diff)
[SCSI] zfcp: Stop system after memory corruption
For each request that is sent to the FCP adapter, zfcp allocates memory. Status information and data that is being read from the device is written to this memory by the hardware. After that, the hardware signals this via the response queue and zfcp continues processing. Now, if zfcp detects that there is a signal for an incoming response from the hardware, but there is no outstanding request for that request id, then some memory that can be in use anywhere in the system has just been overwritten. This should never happen, but if it does, stop the system with a panic. Signed-off-by: Christof Schmitt <christof.schmitt@de.ibm.com> Signed-off-by: Swen Schillig <swen@vnet.ibm.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c34
1 files changed, 6 insertions, 28 deletions
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 1e12a78e8edd..e50e6ad4e6cb 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -285,8 +285,8 @@ zfcp_qdio_request_handler(struct ccw_device *ccw_device,
285/** 285/**
286 * zfcp_qdio_reqid_check - checks for valid reqids or unsolicited status 286 * zfcp_qdio_reqid_check - checks for valid reqids or unsolicited status
287 */ 287 */
288static int zfcp_qdio_reqid_check(struct zfcp_adapter *adapter, 288static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
289 unsigned long req_id) 289 unsigned long req_id)
290{ 290{
291 struct zfcp_fsf_req *fsf_req; 291 struct zfcp_fsf_req *fsf_req;
292 unsigned long flags; 292 unsigned long flags;
@@ -298,9 +298,7 @@ static int zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
298 298
299 if (!fsf_req) { 299 if (!fsf_req) {
300 spin_unlock_irqrestore(&adapter->req_list_lock, flags); 300 spin_unlock_irqrestore(&adapter->req_list_lock, flags);
301 ZFCP_LOG_NORMAL("error: unknown request id (%ld).\n", req_id); 301 panic("error: unknown request id (%ld).\n", req_id);
302 zfcp_erp_adapter_reopen(adapter, 0);
303 return -EINVAL;
304 } 302 }
305 303
306 zfcp_reqlist_remove(adapter, req_id); 304 zfcp_reqlist_remove(adapter, req_id);
@@ -309,8 +307,6 @@ static int zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
309 307
310 /* finish the FSF request */ 308 /* finish the FSF request */
311 zfcp_fsf_req_complete(fsf_req); 309 zfcp_fsf_req_complete(fsf_req);
312
313 return 0;
314} 310}
315 311
316/* 312/*
@@ -374,27 +370,9 @@ zfcp_qdio_response_handler(struct ccw_device *ccw_device,
374 370
375 /* look for QDIO request identifiers in SB */ 371 /* look for QDIO request identifiers in SB */
376 buffere = &buffer->element[buffere_index]; 372 buffere = &buffer->element[buffere_index];
377 retval = zfcp_qdio_reqid_check(adapter, 373 zfcp_qdio_reqid_check(adapter,
378 (unsigned long) buffere->addr); 374 (unsigned long) buffere->addr);
379 375
380 if (retval) {
381 ZFCP_LOG_NORMAL("bug: unexpected inbound "
382 "packet on adapter %s "
383 "(reqid=0x%lx, "
384 "first_element=%d, "
385 "elements_processed=%d)\n",
386 zfcp_get_busid_by_adapter(adapter),
387 (unsigned long) buffere->addr,
388 first_element,
389 elements_processed);
390 ZFCP_LOG_NORMAL("hex dump of inbound buffer "
391 "at address %p "
392 "(buffer_index=%d, "
393 "buffere_index=%d)\n", buffer,
394 buffer_index, buffere_index);
395 ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
396 (char *) buffer, SBAL_SIZE);
397 }
398 /* 376 /*
399 * A single used SBALE per inbound SBALE has been 377 * A single used SBALE per inbound SBALE has been
400 * implemented by QDIO so far. Hope they will 378 * implemented by QDIO so far. Hope they will