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

Commit 3fbd55ec authored by Russell King's avatar Russell King
Browse files

Merge branch 'for-rmk/lpae' of...

Merge branch 'for-rmk/lpae' of git://git.kernel.org/pub/scm/linux/kernel/git/will/linux into devel-stable

Conflicts:
	arch/arm/kernel/smp.c

Please pull these miscellaneous LPAE fixes I've been collecting for a while
now for 3.11. They've been tested and reviewed by quite a few people, and most
of the patches are pretty trivial. -- Will Deacon.
parents b3f288de a469abd0
Loading
Loading
Loading
Loading
+17 −1
Original line number Diff line number Diff line
@@ -18,6 +18,8 @@
#include <linux/types.h>
#include <linux/sizes.h>

#include <asm/cache.h>

#ifdef CONFIG_NEED_MACH_MEMORY_H
#include <mach/memory.h>
#endif
@@ -141,6 +143,20 @@
#define page_to_phys(page)	(__pfn_to_phys(page_to_pfn(page)))
#define phys_to_page(phys)	(pfn_to_page(__phys_to_pfn(phys)))

/*
 * Minimum guaranted alignment in pgd_alloc().  The page table pointers passed
 * around in head.S and proc-*.S are shifted by this amount, in order to
 * leave spare high bits for systems with physical address extension.  This
 * does not fully accomodate the 40-bit addressing capability of ARM LPAE, but
 * gives us about 38-bits or so.
 */
#ifdef CONFIG_ARM_LPAE
#define ARCH_PGD_SHIFT		L1_CACHE_SHIFT
#else
#define ARCH_PGD_SHIFT		0
#endif
#define ARCH_PGD_MASK		((1 << ARCH_PGD_SHIFT) - 1)

#ifndef __ASSEMBLY__

/*
@@ -207,7 +223,7 @@ static inline unsigned long __phys_to_virt(unsigned long x)
 * direct-mapped view.  We assume this is the first page
 * of RAM in the mem_map as well.
 */
#define PHYS_PFN_OFFSET	(PHYS_OFFSET >> PAGE_SHIFT)
#define PHYS_PFN_OFFSET	((unsigned long)(PHYS_OFFSET >> PAGE_SHIFT))

/*
 * These are *only* valid on the kernel direct mapped RAM memory.
+1 −1
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@
/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT		12
#define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
#define PAGE_MASK		(~(PAGE_SIZE-1))
#define PAGE_MASK		(~((1 << PAGE_SHIFT) - 1))

#ifndef __ASSEMBLY__

+20 −0
Original line number Diff line number Diff line
@@ -83,4 +83,24 @@
#define PHYS_MASK_SHIFT		(40)
#define PHYS_MASK		((1ULL << PHYS_MASK_SHIFT) - 1)

/*
 * TTBR0/TTBR1 split (PAGE_OFFSET):
 *   0x40000000: T0SZ = 2, T1SZ = 0 (not used)
 *   0x80000000: T0SZ = 0, T1SZ = 1
 *   0xc0000000: T0SZ = 0, T1SZ = 2
 *
 * Only use this feature if PHYS_OFFSET <= PAGE_OFFSET, otherwise
 * booting secondary CPUs would end up using TTBR1 for the identity
 * mapping set up in TTBR0.
 */
#if defined CONFIG_VMSPLIT_2G
#define TTBR1_OFFSET	16			/* skip two L1 entries */
#elif defined CONFIG_VMSPLIT_3G
#define TTBR1_OFFSET	(4096 * (1 + 3))	/* only L2, skip pgd + 3*pmd */
#else
#define TTBR1_OFFSET	0
#endif

#define TTBR1_SIZE	(((PAGE_OFFSET >> 30) - 1) << 16)

#endif
+4 −4
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@
#define PTRS_PER_PMD		512
#define PTRS_PER_PGD		4

#define PTE_HWTABLE_PTRS	(PTRS_PER_PTE)
#define PTE_HWTABLE_PTRS	(0)
#define PTE_HWTABLE_OFF		(0)
#define PTE_HWTABLE_SIZE	(PTRS_PER_PTE * sizeof(u64))

@@ -48,16 +48,16 @@
#define PMD_SHIFT		21

#define PMD_SIZE		(1UL << PMD_SHIFT)
#define PMD_MASK		(~(PMD_SIZE-1))
#define PMD_MASK		(~((1 << PMD_SHIFT) - 1))
#define PGDIR_SIZE		(1UL << PGDIR_SHIFT)
#define PGDIR_MASK		(~(PGDIR_SIZE-1))
#define PGDIR_MASK		(~((1 << PGDIR_SHIFT) - 1))

/*
 * section address mask and size definitions.
 */
#define SECTION_SHIFT		21
#define SECTION_SIZE		(1UL << SECTION_SHIFT)
#define SECTION_MASK		(~(SECTION_SIZE-1))
#define SECTION_MASK		(~((1 << SECTION_SHIFT) - 1))

#define USER_PTRS_PER_PGD	(PAGE_OFFSET / PGDIR_SIZE)

+19 −7
Original line number Diff line number Diff line
@@ -60,7 +60,7 @@ extern struct processor {
	/*
	 * Set the page table
	 */
	void (*switch_mm)(unsigned long pgd_phys, struct mm_struct *mm);
	void (*switch_mm)(phys_addr_t pgd_phys, struct mm_struct *mm);
	/*
	 * Set a possibly extended PTE.  Non-extended PTEs should
	 * ignore 'ext'.
@@ -82,7 +82,7 @@ extern void cpu_proc_init(void);
extern void cpu_proc_fin(void);
extern int cpu_do_idle(void);
extern void cpu_dcache_clean_area(void *, int);
extern void cpu_do_switch_mm(unsigned long pgd_phys, struct mm_struct *mm);
extern void cpu_do_switch_mm(phys_addr_t pgd_phys, struct mm_struct *mm);
#ifdef CONFIG_ARM_LPAE
extern void cpu_set_pte_ext(pte_t *ptep, pte_t pte);
#else
@@ -116,13 +116,25 @@ extern void cpu_resume(void);
#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)

#ifdef CONFIG_ARM_LPAE

#define cpu_get_ttbr(nr)					\
	({							\
		u64 ttbr;					\
		__asm__("mrrc	p15, " #nr ", %Q0, %R0, c2"	\
			: "=r" (ttbr));				\
		ttbr;						\
	})

#define cpu_set_ttbr(nr, val)					\
	do {							\
		u64 ttbr = val;					\
		__asm__("mcrr	p15, " #nr ", %Q0, %R0, c2"	\
			: : "r" (ttbr));			\
	} while (0)

#define cpu_get_pgd()	\
	({						\
		unsigned long pg, pg2;			\
		__asm__("mrrc	p15, 0, %0, %1, c2"	\
			: "=r" (pg), "=r" (pg2)		\
			:				\
			: "cc");			\
		u64 pg = cpu_get_ttbr(0);		\
		pg &= ~(PTRS_PER_PGD*sizeof(pgd_t)-1);	\
		(pgd_t *)phys_to_virt(pg);		\
	})
Loading