Skip to content

Commit

Permalink
[ARM] Fix SMP booting with non-zero PHYS_OFFSET
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Russell King authored and Russell King committed Aug 7, 2008
1 parent afd2fc0 commit 058ddee
Showing 1 changed file with 2 additions and 2 deletions.
4 changes: 2 additions & 2 deletions arch/arm/kernel/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
* a 1:1 mapping for the physical address of the kernel.
*/
pgd = pgd_alloc(&init_mm);
pmd = pmd_offset(pgd, PHYS_OFFSET);
pmd = pmd_offset(pgd + pgd_index(PHYS_OFFSET), PHYS_OFFSET);
*pmd = __pmd((PHYS_OFFSET & PGDIR_MASK) |
PMD_TYPE_SECT | PMD_SECT_AP_WRITE);

Expand Down Expand Up @@ -139,7 +139,7 @@ int __cpuinit __cpu_up(unsigned int cpu)
secondary_data.stack = NULL;
secondary_data.pgdir = 0;

*pmd_offset(pgd, PHYS_OFFSET) = __pmd(0);
*pmd = __pmd(0);
pgd_free(&init_mm, pgd);

if (ret) {
Expand Down

0 comments on commit 058ddee

Please sign in to comment.