summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Morton <akpm@osdl.org>2004-01-30 18:06:29 -0800
committerLinus Torvalds <torvalds@home.osdl.org>2004-01-30 18:06:29 -0800
commit4093261b82b7dbe3be34d38e106a3de9ffffa771 (patch)
treeb2fd96abbbd2758ab38baaeac62526bb64840d0a
parente7d1d6cd8e12e123bb9e70e731f662fbbbe51f53 (diff)
[PATCH] RAID-6: x86-64 crash workaround
From: "H. Peter Anvin" <hpa@zytor.com> Apparently, on x86-64, the stack isn't always aligned properly (16 bytes) in the kernel at the moment. This causes the RAID-6 code to crash the system. This patch is a workaround for that; the right thing is to muck with the assembly entrypoints to enforce proper stack alignment. However, that's not anything I feel comfortable doing in an evening, especially since I don't have a machine on which I can test the resulting kernels.
-rw-r--r--drivers/md/raid6x86.h13
1 files changed, 8 insertions, 5 deletions
diff --git a/drivers/md/raid6x86.h b/drivers/md/raid6x86.h
index 0579c764dd09..41867a6903d6 100644
--- a/drivers/md/raid6x86.h
+++ b/drivers/md/raid6x86.h
@@ -32,18 +32,20 @@ typedef struct {
/* N.B.: For SSE we only save %xmm0-%xmm7 even for x86-64, since
the code doesn't know about the additional x86-64 registers */
typedef struct {
- unsigned int sarea[8*4];
- unsigned int cr0;
+ unsigned int sarea[8*4+2];
+ unsigned long cr0;
} raid6_sse_save_t __attribute__((aligned(16)));
/* This is for x86-64-specific code which uses all 16 XMM registers */
typedef struct {
- unsigned int sarea[16*4];
+ unsigned int sarea[16*4+2];
unsigned long cr0;
} raid6_sse16_save_t __attribute__((aligned(16)));
-/* On x86-64 the stack is 16-byte aligned */
-#define SAREA(x) (x->sarea)
+/* On x86-64 the stack *SHOULD* be 16-byte aligned, but currently this
+ is buggy in the kernel and it's only 8-byte aligned in places, so
+ we need to do this anyway. Sigh. */
+#define SAREA(x) ((unsigned int *)((((unsigned long)&(x)->sarea)+15) & ~15))
#else /* __i386__ */
@@ -60,6 +62,7 @@ typedef struct {
unsigned long cr0;
} raid6_sse_save_t;
+/* Find the 16-byte aligned save area */
#define SAREA(x) ((unsigned int *)((((unsigned long)&(x)->sarea)+15) & ~15))
#endif