Commit 4093261b authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[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.
parent e7d1d6cd
...@@ -32,18 +32,20 @@ typedef struct { ...@@ -32,18 +32,20 @@ typedef struct {
/* N.B.: For SSE we only save %xmm0-%xmm7 even for x86-64, since /* 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 */ the code doesn't know about the additional x86-64 registers */
typedef struct { typedef struct {
unsigned int sarea[8*4]; unsigned int sarea[8*4+2];
unsigned int cr0; unsigned long cr0;
} raid6_sse_save_t __attribute__((aligned(16))); } raid6_sse_save_t __attribute__((aligned(16)));
/* This is for x86-64-specific code which uses all 16 XMM registers */ /* This is for x86-64-specific code which uses all 16 XMM registers */
typedef struct { typedef struct {
unsigned int sarea[16*4]; unsigned int sarea[16*4+2];
unsigned long cr0; unsigned long cr0;
} raid6_sse16_save_t __attribute__((aligned(16))); } raid6_sse16_save_t __attribute__((aligned(16)));
/* On x86-64 the stack is 16-byte aligned */ /* On x86-64 the stack *SHOULD* be 16-byte aligned, but currently this
#define SAREA(x) (x->sarea) 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__ */ #else /* __i386__ */
...@@ -60,6 +62,7 @@ typedef struct { ...@@ -60,6 +62,7 @@ typedef struct {
unsigned long cr0; unsigned long cr0;
} raid6_sse_save_t; } raid6_sse_save_t;
/* Find the 16-byte aligned save area */
#define SAREA(x) ((unsigned int *)((((unsigned long)&(x)->sarea)+15) & ~15)) #define SAREA(x) ((unsigned int *)((((unsigned long)&(x)->sarea)+15) & ~15))
#endif #endif
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment