Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 516295e5 authored by Russell King's avatar Russell King
Browse files

ARM: pgtable: add pud-level code



Add pud_offset() et.al. between the pgd and pmd code in preparation of
using pgtable-nopud.h rather than 4level-fixup.h.

This incorporates a fix from Jamie Iles <jamie@jamieiles.com> for
uaccess_with_memcpy.c.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent f60892d3
Loading
Loading
Loading
Loading
+1 −0
Original line number Original line Diff line number Diff line
@@ -301,6 +301,7 @@ extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
#define pgd_present(pgd)	(1)
#define pgd_present(pgd)	(1)
#define pgd_clear(pgdp)		do { } while (0)
#define pgd_clear(pgdp)		do { } while (0)
#define set_pgd(pgd,pgdp)	do { } while (0)
#define set_pgd(pgd,pgdp)	do { } while (0)
#define set_pud(pud,pudp)	do { } while (0)




/* Find an entry in the second-level page table.. */
/* Find an entry in the second-level page table.. */
+6 −1
Original line number Original line Diff line number Diff line
@@ -27,13 +27,18 @@ pin_page_for_write(const void __user *_addr, pte_t **ptep, spinlock_t **ptlp)
	pgd_t *pgd;
	pgd_t *pgd;
	pmd_t *pmd;
	pmd_t *pmd;
	pte_t *pte;
	pte_t *pte;
	pud_t *pud;
	spinlock_t *ptl;
	spinlock_t *ptl;


	pgd = pgd_offset(current->mm, addr);
	pgd = pgd_offset(current->mm, addr);
	if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd)))
	if (unlikely(pgd_none(*pgd) || pgd_bad(*pgd)))
		return 0;
		return 0;


	pmd = pmd_offset(pgd, addr);
	pud = pud_offset(pgd, addr);
	if (unlikely(pud_none(*pud) || pud_bad(*pud)))
		return 0;

	pmd = pmd_offset(pud, addr);
	if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd)))
	if (unlikely(pmd_none(*pmd) || pmd_bad(*pmd)))
		return 0;
		return 0;


+10 −1
Original line number Original line Diff line number Diff line
@@ -148,6 +148,7 @@ static int __init consistent_init(void)
{
{
	int ret = 0;
	int ret = 0;
	pgd_t *pgd;
	pgd_t *pgd;
	pud_t *pud;
	pmd_t *pmd;
	pmd_t *pmd;
	pte_t *pte;
	pte_t *pte;
	int i = 0;
	int i = 0;
@@ -155,7 +156,15 @@ static int __init consistent_init(void)


	do {
	do {
		pgd = pgd_offset(&init_mm, base);
		pgd = pgd_offset(&init_mm, base);
		pmd = pmd_alloc(&init_mm, pgd, base);

		pud = pud_alloc(&init_mm, pgd, base);
		if (!pud) {
			printk(KERN_ERR "%s: no pud tables\n", __func__);
			ret = -ENOMEM;
			break;
		}

		pmd = pmd_alloc(&init_mm, pud, base);
		if (!pmd) {
		if (!pmd) {
			printk(KERN_ERR "%s: no pmd tables\n", __func__);
			printk(KERN_ERR "%s: no pmd tables\n", __func__);
			ret = -ENOMEM;
			ret = -ENOMEM;
+6 −1
Original line number Original line Diff line number Diff line
@@ -95,6 +95,7 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
{
{
	spinlock_t *ptl;
	spinlock_t *ptl;
	pgd_t *pgd;
	pgd_t *pgd;
	pud_t *pud;
	pmd_t *pmd;
	pmd_t *pmd;
	pte_t *pte;
	pte_t *pte;
	int ret;
	int ret;
@@ -103,7 +104,11 @@ static int adjust_pte(struct vm_area_struct *vma, unsigned long address,
	if (pgd_none_or_clear_bad(pgd))
	if (pgd_none_or_clear_bad(pgd))
		return 0;
		return 0;


	pmd = pmd_offset(pgd, address);
	pud = pud_offset(pgd, address);
	if (pud_none_or_clear_bad(pud))
		return 0;

	pmd = pmd_offset(pud, address);
	if (pmd_none_or_clear_bad(pmd))
	if (pmd_none_or_clear_bad(pmd))
		return 0;
		return 0;


+25 −4
Original line number Original line Diff line number Diff line
@@ -80,6 +80,7 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
			addr, (long long)pgd_val(*pgd));
			addr, (long long)pgd_val(*pgd));


	do {
	do {
		pud_t *pud;
		pmd_t *pmd;
		pmd_t *pmd;
		pte_t *pte;
		pte_t *pte;


@@ -91,7 +92,19 @@ void show_pte(struct mm_struct *mm, unsigned long addr)
			break;
			break;
		}
		}


		pmd = pmd_offset(pgd, addr);
		pud = pud_offset(pgd, addr);
		if (PTRS_PER_PUD != 1)
			printk(", *pud=%08lx", pud_val(*pud));

		if (pud_none(*pud))
			break;

		if (pud_bad(*pud)) {
			printk("(bad)");
			break;
		}

		pmd = pmd_offset(pud, addr);
		if (PTRS_PER_PMD != 1)
		if (PTRS_PER_PMD != 1)
			printk(", *pmd=%08llx", (long long)pmd_val(*pmd));
			printk(", *pmd=%08llx", (long long)pmd_val(*pmd));


@@ -390,6 +403,7 @@ do_translation_fault(unsigned long addr, unsigned int fsr,
{
{
	unsigned int index;
	unsigned int index;
	pgd_t *pgd, *pgd_k;
	pgd_t *pgd, *pgd_k;
	pud_t *pud, *pud_k;
	pmd_t *pmd, *pmd_k;
	pmd_t *pmd, *pmd_k;


	if (addr < TASK_SIZE)
	if (addr < TASK_SIZE)
@@ -408,12 +422,19 @@ do_translation_fault(unsigned long addr, unsigned int fsr,


	if (pgd_none(*pgd_k))
	if (pgd_none(*pgd_k))
		goto bad_area;
		goto bad_area;

	if (!pgd_present(*pgd))
	if (!pgd_present(*pgd))
		set_pgd(pgd, *pgd_k);
		set_pgd(pgd, *pgd_k);


	pmd_k = pmd_offset(pgd_k, addr);
	pud = pud_offset(pgd, addr);
	pmd   = pmd_offset(pgd, addr);
	pud_k = pud_offset(pgd_k, addr);

	if (pud_none(*pud_k))
		goto bad_area;
	if (!pud_present(*pud))
		set_pud(pud, *pud_k);

	pmd = pmd_offset(pud, addr);
	pmd_k = pmd_offset(pud_k, addr);


	/*
	/*
	 * On ARM one Linux PGD entry contains two hardware entries (see page
	 * On ARM one Linux PGD entry contains two hardware entries (see page
Loading