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

Commit 6626a707 authored by Russell King's avatar Russell King Committed by Russell King
Browse files

[ARM] Control v6 'global' bit via Linux PTE entries



Unfortunately, we can't use the "user" bit in the page tables to
control whether a page table entry is "global" or "asid" specific,
since the vector page is mapped as "user" accessible but is not
process specific.

Therefore, give direct control of the ARMv6 "nG" (not global)
bit to the mm layers.

Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 1b9749e7
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -383,6 +383,7 @@ static void __init build_mem_type_table(void)
{
	struct cachepolicy *cp;
	unsigned int cr = get_cr();
	unsigned int user_pgprot;
	int cpu_arch = cpu_architecture();
	int i;

@@ -408,6 +409,9 @@ static void __init build_mem_type_table(void)
		}
	}

	cp = &cache_policies[cachepolicy];
	user_pgprot = cp->pte;

	/*
	 * ARMv6 and above have extended page tables.
	 */
@@ -426,11 +430,18 @@ static void __init build_mem_type_table(void)
		mem_types[MT_MINICLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;
		mem_types[MT_CACHECLEAN].prot_sect |= PMD_SECT_APX|PMD_SECT_AP_WRITE;

		/*
		 * Mark the device area as "shared device"
		 */
		mem_types[MT_DEVICE].prot_pte |= L_PTE_BUFFERABLE;
		mem_types[MT_DEVICE].prot_sect |= PMD_SECT_BUFFERED;
	}

	cp = &cache_policies[cachepolicy];
		/*
		 * User pages need to be mapped with the ASID
		 * (iow, non-global)
		 */
		user_pgprot |= L_PTE_ASID;
	}

	if (cpu_arch >= CPU_ARCH_ARMv5) {
		mem_types[MT_LOW_VECTORS].prot_pte |= cp->pte & PTE_CACHEABLE;
@@ -448,7 +459,7 @@ static void __init build_mem_type_table(void)

	for (i = 0; i < 16; i++) {
		unsigned long v = pgprot_val(protection_map[i]);
		v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | cp->pte;
		v &= (~(PTE_BUFFERABLE|PTE_CACHEABLE)) | user_pgprot;
		protection_map[i] = __pgprot(v);
	}

+2 −2
Original line number Diff line number Diff line
@@ -133,7 +133,7 @@ ENTRY(cpu_v6_switch_mm)
ENTRY(cpu_v6_set_pte)
	str	r1, [r0], #-2048		@ linux version

	bic	r2, r1, #0x00000ff0
	bic	r2, r1, #0x000007f0
	bic	r2, r2, #0x00000003
	orr	r2, r2, #PTE_EXT_AP0 | 2

@@ -142,7 +142,7 @@ ENTRY(cpu_v6_set_pte)
	orreq	r2, r2, #PTE_EXT_APX

	tst	r1, #L_PTE_USER
	orrne	r2, r2, #PTE_EXT_AP1 | PTE_EXT_NG
	orrne	r2, r2, #PTE_EXT_AP1
	tstne	r2, #PTE_EXT_APX
	bicne	r2, r2, #PTE_EXT_APX | PTE_EXT_AP0

+2 −0
Original line number Diff line number Diff line
@@ -230,6 +230,8 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
#define L_PTE_WRITE		(1 << 5)
#define L_PTE_EXEC		(1 << 6)
#define L_PTE_DIRTY		(1 << 7)
#define L_PTE_SHARED		(1 << 10)	/* shared between CPUs (v6) */
#define L_PTE_ASID		(1 << 11)	/* non-global (use ASID, v6) */

#ifndef __ASSEMBLY__