Messages in this thread | | | Date | Mon, 1 May 2006 12:07:37 +0900 | From | "Magnus Damm" <> | Subject | Re: i386 and PAE: pud_present() |
| |
On 4/30/06, Dave McCracken <dmccr@us.ibm.com> wrote: > > --On Friday, April 28, 2006 10:27:21 +0200 Andi Kleen <ak@suse.de> wrote: > > >> Take a look a little further down the page for the comment. > >> > >> In i386 + PAE, pud is always present. > > > > I think his problem is that the PGD is always present too (in > > pgtables-nopud.h) Indeed looks strange. > > The PGD is always fully populated on i386 if PAE is enabled. All three of > the pmd pages are allocated at page table creation time and persist till > the page table is deleted.
The following code snippet is from some kexec patch of mine. The function is used to build a new set of page tables which are used when jumping to the new kernel.
The code should be pretty archtecture independent - the same code works on x86 and x86_64. And x86/PAE with a workaround.
#ifdef CONFIG_X86_PAE #undef pud_present #define pud_present(pud) (pud_val(pud) & _PAGE_PRESENT) #endif
#define pa_page(page) __pa(page_address(page))
static int create_mapping(struct page *root, struct page **pages, unsigned long va, unsigned long pa) { pgd_t *pgd; pud_t *pud; pmd_t *pmd; pte_t *pte; int k = 0;
pgd = (pgd_t *)page_address(root) + pgd_index(va); if (!pgd_present(*pgd)) set_pgd(pgd, __pgd(pa_page(pages[k++]) | _KERNPG_TABLE));
pud = pud_offset(pgd, va); if (!pud_present(*pud)) set_pud(pud, __pud(pa_page(pages[k++]) | _KERNPG_TABLE));
pmd = pmd_offset(pud, va); if (!pmd_present(*pmd)) set_pmd(pmd, __pmd(pa_page(pages[k++]) | _KERNPG_TABLE));
pte = (pte_t *)page_address(pmd_page(*pmd)) + pte_index(va); set_pte(pte, __pte(pa | _PAGE_KERNEL_EXEC));
return k; }
Any comments?
/ magnus - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |