diff options
author | Keith Mannthey <kmannth@us.ibm.com> | 2005-07-29 00:15:38 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-29 00:46:00 -0400 |
commit | b684664fd495fd640353c0f786751763db77dcfb (patch) | |
tree | 348f3d452f9d1a78ec1a3684ef53380d41ec9db8 /arch/x86_64/mm/numa.c | |
parent | 17158d17aa726142255050b407ad701a6f191aba (diff) |
[PATCH] x86_64: Fix overflow in NUMA hash function setup
Signed-off-by: Andi Kleen <ak@suse.de>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'arch/x86_64/mm/numa.c')
-rw-r--r-- | arch/x86_64/mm/numa.c | 50 |
1 files changed, 26 insertions, 24 deletions
diff --git a/arch/x86_64/mm/numa.c b/arch/x86_64/mm/numa.c index ac61c186eb02..70cb2904a90f 100644 --- a/arch/x86_64/mm/numa.c +++ b/arch/x86_64/mm/numa.c | |||
@@ -36,34 +36,36 @@ int numa_off __initdata; | |||
36 | int __init compute_hash_shift(struct node *nodes, int numnodes) | 36 | int __init compute_hash_shift(struct node *nodes, int numnodes) |
37 | { | 37 | { |
38 | int i; | 38 | int i; |
39 | int shift = 24; | 39 | int shift = 20; |
40 | u64 addr; | 40 | unsigned long addr,maxend=0; |
41 | 41 | ||
42 | /* When in doubt use brute force. */ | 42 | for (i = 0; i < numnodes; i++) |
43 | while (shift < 48) { | 43 | if ((nodes[i].start != nodes[i].end) && (nodes[i].end > maxend)) |
44 | memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); | 44 | maxend = nodes[i].end; |
45 | for (i = 0; i < numnodes; i++) { | 45 | |
46 | if (nodes[i].start == nodes[i].end) | 46 | while ((1UL << shift) < (maxend / NODEMAPSIZE)) |
47 | continue; | 47 | shift++; |
48 | for (addr = nodes[i].start; | 48 | |
49 | addr < nodes[i].end; | 49 | printk (KERN_DEBUG"Using %d for the hash shift. Max adder is %lx \n", |
50 | addr += (1UL << shift)) { | 50 | shift,maxend); |
51 | if (memnodemap[addr >> shift] != 0xff && | 51 | memset(memnodemap,0xff,sizeof(*memnodemap) * NODEMAPSIZE); |
52 | memnodemap[addr >> shift] != i) { | 52 | for (i = 0; i < numnodes; i++) { |
53 | printk(KERN_INFO | 53 | if (nodes[i].start == nodes[i].end) |
54 | "node %d shift %d addr %Lx conflict %d\n", | 54 | continue; |
55 | i, shift, addr, memnodemap[addr>>shift]); | 55 | for (addr = nodes[i].start; |
56 | goto next; | 56 | addr < nodes[i].end; |
57 | } | 57 | addr += (1UL << shift)) { |
58 | memnodemap[addr >> shift] = i; | 58 | if (memnodemap[addr >> shift] != 0xff) { |
59 | printk(KERN_INFO | ||
60 | "Your memory is not aligned you need to rebuild your kernel " | ||
61 | "with a bigger NODEMAPSIZE shift=%d adder=%lu\n", | ||
62 | shift,addr); | ||
63 | return -1; | ||
59 | } | 64 | } |
65 | memnodemap[addr >> shift] = i; | ||
60 | } | 66 | } |
61 | return shift; | ||
62 | next: | ||
63 | shift++; | ||
64 | } | 67 | } |
65 | memset(memnodemap,0,sizeof(*memnodemap) * NODEMAPSIZE); | 68 | return shift; |
66 | return -1; | ||
67 | } | 69 | } |
68 | 70 | ||
69 | #ifdef CONFIG_SPARSEMEM | 71 | #ifdef CONFIG_SPARSEMEM |