Re: [SCSI] mvsas: Fix the kernel panic due to unaligned data access

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 2013-05-08 at 15:01 +0800, Paul Guo wrote:
> It's easy to find the address and symbol that causes the unalignd data
> access according to the stack dump information. The following small
> patch will fix it.

Do you have the panic log?  because it sounds like a bug in your
platform code.  All platforms have to support unaligned accesses because
some of the kernel parsers generate them as well.  You can see examples
of how to do this in e.g. arch/parisc/kernel/unaligned.c

> This change is harmless for platforms (like x86/x64) which support
> unaligned data access but is critical for platforms those do not support
> unaligned data access (like our platform: arch/tile).
> 
> I sent the patch but did not ping the status. I sync-up the workspace
> and re-generate the patch again. Feel free to give me any feedback. It's
> really annoying to maintain the change internally.

First off, you didn't compile this on x86, did you?

> @@ -39,6 +39,7 @@
>  #include <linux/irq.h>
>  #include <linux/slab.h>
>  #include <linux/vmalloc.h>
> +#include <linux/unaligned.h>
>  #include <scsi/libsas.h>
>  #include <scsi/scsi.h>
>  #include <scsi/scsi_tcq.h>

Causes

  CC [M]  drivers/scsi/scsi_sysfs.o
In file included from drivers/scsi/mvsas/mv_sas.c:26:0:
drivers/scsi/mvsas/mv_sas.h:41:29: fatal error: linux/unaligned.h: No
such file or directory

because it should be asm/unaligned.h.  If it actually compiles on your
platform, you've got a serious problem with the way include paths work.

Secondly, the reason we have get_unaligned() macros is to speed up
things by avoiding the trap when we know the data is unaligned, but it
is really inefficient on most platforms because it will unroll a u64
deref into 8 single byte loads.  In this case, the DMA buffer looks to
be a word file, so the below is probably how it should be done.  Notice
the efficient access in the fast path and the inefficient one in the
error path.

James

---

diff --git a/drivers/scsi/mvsas/mv_sas.c b/drivers/scsi/mvsas/mv_sas.c
index f14665a..6b1b4e9 100644
--- a/drivers/scsi/mvsas/mv_sas.c
+++ b/drivers/scsi/mvsas/mv_sas.c
@@ -1857,11 +1857,16 @@ int mvs_slot_complete(struct mvs_info *mvi, u32 rx_desc, u32 flags)
 		goto out;
 	}
 
-	/* error info record present */
-	if (unlikely((rx_desc & RXQ_ERR) && (*(u64 *) slot->response))) {
+	/*
+	 * error info record present; slot->response is 32 bit aligned but may
+	 * not be 64 bit aligned, so check for zero in two 32 bit reads
+	 */
+	if (unlikely((rx_desc & RXQ_ERR)
+		     && (*((u32 *)slot->response)
+			 || *(((u32 *)slot->response) + 1)))) {
 		mv_dprintk("port %d slot %d rx_desc %X has error info"
 			"%016llX.\n", slot->port->sas_port.id, slot_idx,
-			 rx_desc, (u64)(*(u64 *)slot->response));
+			 rx_desc, get_unaligned_le64(slot->response));
 		tstat->stat = mvs_slot_err(mvi, task, slot_idx);
 		tstat->resp = SAS_TASK_COMPLETE;
 		goto out;
diff --git a/drivers/scsi/mvsas/mv_sas.h b/drivers/scsi/mvsas/mv_sas.h
index 60e2fb7..d6b19dc 100644
--- a/drivers/scsi/mvsas/mv_sas.h
+++ b/drivers/scsi/mvsas/mv_sas.h
@@ -39,6 +39,7 @@
 #include <linux/irq.h>
 #include <linux/slab.h>
 #include <linux/vmalloc.h>
+#include <asm/unaligned.h>
 #include <scsi/libsas.h>
 #include <scsi/scsi.h>
 #include <scsi/scsi_tcq.h>


--
To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux