diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2008-08-07 17:36:59 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2008-08-07 17:36:59 -0400 |
commit | 058ddee5625ade9e9e011b9ae155ac3b8d4eda3a (patch) | |
tree | 2821d666c06733da81f606624bf2a16bdf86ce73 /arch/arm/kernel/smp.c | |
parent | afd2fc02ab7bae6062671c5ca80dd34c34a63fb7 (diff) |
[ARM] Fix SMP booting with non-zero PHYS_OFFSET
The existing code tries to get the pmd for the temporary page table
by doing:
pgd = pgd_alloc(&init_mm);
pmd = pmd_offset(pgd, PHYS_OFFSET);
Since we have a two level page table, pmd_offset() is a no-op, so
this just has a casting effect from a pgd to a pmd - the address
argument is unused. So this can't work.
Normally, we'd do:
pgd = pgd_offset(&init_mm, PHYS_OFFSET);
...
pmd = pmd_offset(pgd, PHYS_OFFSET);
to get the pmd you want. However, pgd_offset() takes the mm_struct,
not the (unattached) pgd we just allocated. So, instead use:
pgd = pgd_alloc(&init_mm);
pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET);
Reported-by: Antti P Miettinen <ananaza@iki.fi>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/smp.c')
-rw-r--r-- | arch/arm/kernel/smp.c | 4 |
1 files changed, 2 insertions, 2 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 5a7c09564d13..e9842f6767f9 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -100,7 +100,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
100 | * a 1:1 mapping for the physical address of the kernel. | 100 | * a 1:1 mapping for the physical address of the kernel. |
101 | */ | 101 | */ |
102 | pgd = pgd_alloc(&init_mm); | 102 | pgd = pgd_alloc(&init_mm); |
103 | pmd = pmd_offset(pgd, PHYS_OFFSET); | 103 | pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET); |
104 | *pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) | | 104 | *pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) | |
105 | PMD_TYPE_SECT | PMD_SECT_AP_WRITE); | 105 | PMD_TYPE_SECT | PMD_SECT_AP_WRITE); |
106 | 106 | ||
@@ -139,7 +139,7 @@ int __cpuinit __cpu_up(unsigned int cpu) | |||
139 | secondary_data.stack = NULL; | 139 | secondary_data.stack = NULL; |
140 | secondary_data.pgdir = 0; | 140 | secondary_data.pgdir = 0; |
141 | 141 | ||
142 | *pmd_offset(pgd, PHYS_OFFSET) = __pmd(0); | 142 | *pmd = __pmd(0); |
143 | pgd_free(&init_mm, pgd); | 143 | pgd_free(&init_mm, pgd); |
144 | 144 | ||
145 | if (ret) { | 145 | if (ret) { |