Commit 4ee7084e authored by Becky Bruce's avatar Becky Bruce Committed by Kumar Gala
Browse files

POWERPC: Allow 32-bit hashed pgtable code to support 36-bit physical



This rearranges a bit of code, and adds support for
36-bit physical addressing for configs that use a
hashed page table.  The 36b physical support is not
enabled by default on any config - it must be
explicitly enabled via the config system.

This patch *only* expands the page table code to accomodate
large physical addresses on 32-bit systems and enables the
PHYS_64BIT config option for 86xx.  It does *not*
allow you to boot a board with more than about 3.5GB of
RAM - for that, SWIOTLB support is also required (and
coming soon).

Signed-off-by: default avatarBecky Bruce <becky.bruce@freescale.com>
Signed-off-by: default avatarKumar Gala <galak@kernel.crashing.org>
parent 9a62c051
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -711,7 +711,7 @@ static inline void * phys_to_virt(unsigned long address)
/*
 * Change "struct page" to physical address.
 */
#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
#define page_to_phys(page)	((phys_addr_t)page_to_pfn(page) << PAGE_SHIFT)

/* We do NOT want virtual merging, it would put too much pressure on
 * our iommu allocator. Instead, we want drivers to be smart enough
+7 −1
Original line number Diff line number Diff line
@@ -13,10 +13,16 @@
#define ARCH_KMALLOC_MINALIGN	L1_CACHE_BYTES
#endif

#ifdef CONFIG_PTE_64BIT
#define PTE_FLAGS_OFFSET	4	/* offset of PTE flags, in bytes */
#else
#define PTE_FLAGS_OFFSET	0
#endif

#ifndef __ASSEMBLY__
/*
 * The basic type of a PTE - 64 bits for those CPUs with > 32 bit
 * physical addressing.  For now this just the IBM PPC440.
 * physical addressing.
 */
#ifdef CONFIG_PTE_64BIT
typedef unsigned long long pte_basic_t;
+15 −2
Original line number Diff line number Diff line
@@ -369,7 +369,12 @@ extern int icache_44x_need_flush;
#define _PAGE_RW	0x400	/* software: user write access allowed */
#define _PAGE_SPECIAL	0x800	/* software: Special page */

#ifdef CONFIG_PTE_64BIT
/* We never clear the high word of the pte */
#define _PTE_NONE_MASK	(0xffffffff00000000ULL | _PAGE_HASHPTE)
#else
#define _PTE_NONE_MASK	_PAGE_HASHPTE
#endif

#define _PMD_PRESENT	0
#define _PMD_PRESENT_MASK (PAGE_MASK)
@@ -587,6 +592,10 @@ extern int flush_hash_pages(unsigned context, unsigned long va,
extern void add_hash_page(unsigned context, unsigned long va,
			  unsigned long pmdval);

/* Flush an entry from the TLB/hash table */
extern void flush_hash_entry(struct mm_struct *mm, pte_t *ptep,
			     unsigned long address);

/*
 * Atomic PTE updates.
 *
@@ -665,9 +674,13 @@ static inline unsigned long long pte_update(pte_t *p,
static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
			      pte_t *ptep, pte_t pte)
{
#if _PAGE_HASHPTE != 0
#if (_PAGE_HASHPTE != 0) && defined(CONFIG_SMP) && !defined(CONFIG_PTE_64BIT)
	pte_update(ptep, ~_PAGE_HASHPTE, pte_val(pte) & ~_PAGE_HASHPTE);
#elif defined(CONFIG_PTE_64BIT) && defined(CONFIG_SMP)
#if _PAGE_HASHPTE != 0
	if (pte_val(*ptep) & _PAGE_HASHPTE)
		flush_hash_entry(mm, ptep, addr);
#endif
	__asm__ __volatile__("\
		stw%U0%X0 %2,%0\n\
		eieio\n\
@@ -675,7 +688,7 @@ static inline void __set_pte_at(struct mm_struct *mm, unsigned long addr,
	: "=m" (*ptep), "=m" (*((unsigned char *)ptep+4))
	: "r" (pte) : "memory");
#else
	*ptep = pte;
	*ptep = (*ptep & _PAGE_HASHPTE) | (pte & ~_PAGE_HASHPTE);
#endif
}

+1 −0
Original line number Diff line number Diff line
@@ -352,6 +352,7 @@ int main(void)
#endif

	DEFINE(PGD_TABLE_SIZE, PGD_TABLE_SIZE);
	DEFINE(PTE_SIZE, sizeof(pte_t));

#ifdef CONFIG_KVM
	DEFINE(TLBE_BYTES, sizeof(struct tlbe));
+2 −2
Original line number Diff line number Diff line
@@ -369,13 +369,13 @@ i##n: \
DataAccess:
	EXCEPTION_PROLOG
	mfspr	r10,SPRN_DSISR
	stw	r10,_DSISR(r11)
	andis.	r0,r10,0xa470		/* weird error? */
	bne	1f			/* if not, try to put a PTE */
	mfspr	r4,SPRN_DAR		/* into the hash table */
	rlwinm	r3,r10,32-15,21,21	/* DSISR_STORE -> _PAGE_RW */
	bl	hash_page
1:	stw	r10,_DSISR(r11)
	mr	r5,r10
1:	lwz	r5,_DSISR(r11)		/* get DSISR value */
	mfspr	r4,SPRN_DAR
	EXC_XFER_EE_LITE(0x300, handle_page_fault)

Loading