forked from mirrors/linux
		
	powerpc/64s: Move hash MMU support code under CONFIG_PPC_64S_HASH_MMU
Compiling out hash support code when CONFIG_PPC_64S_HASH_MMU=n saves
128kB kernel image size (90kB text) on powernv_defconfig minus KVM,
350kB on pseries_defconfig minus KVM, 40kB on a tiny config.
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
[mpe: Fixup defined(ARCH_HAS_MEMREMAP_COMPAT_ALIGN), which needs CONFIG.
      Fix radix_enabled() use in setup_initial_memory_limit(). Add some
      stubs to reduce number of ifdefs.]
Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/20211201144153.2456614-18-npiggin@gmail.com
			
			
This commit is contained in:
		
							parent
							
								
									c28573744b
								
							
						
					
					
						commit
						387e220a2e
					
				
					 35 changed files with 172 additions and 57 deletions
				
			
		| 
						 | 
					@ -129,7 +129,7 @@ config PPC
 | 
				
			||||||
	select ARCH_HAS_KCOV
 | 
						select ARCH_HAS_KCOV
 | 
				
			||||||
	select ARCH_HAS_MEMBARRIER_CALLBACKS
 | 
						select ARCH_HAS_MEMBARRIER_CALLBACKS
 | 
				
			||||||
	select ARCH_HAS_MEMBARRIER_SYNC_CORE
 | 
						select ARCH_HAS_MEMBARRIER_SYNC_CORE
 | 
				
			||||||
	select ARCH_HAS_MEMREMAP_COMPAT_ALIGN	if PPC_BOOK3S_64
 | 
						select ARCH_HAS_MEMREMAP_COMPAT_ALIGN	if PPC_64S_HASH_MMU
 | 
				
			||||||
	select ARCH_HAS_MMIOWB			if PPC64
 | 
						select ARCH_HAS_MMIOWB			if PPC64
 | 
				
			||||||
	select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 | 
						select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE
 | 
				
			||||||
	select ARCH_HAS_PHYS_TO_DMA
 | 
						select ARCH_HAS_PHYS_TO_DMA
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -523,8 +523,14 @@ void slb_save_contents(struct slb_entry *slb_ptr);
 | 
				
			||||||
void slb_dump_contents(struct slb_entry *slb_ptr);
 | 
					void slb_dump_contents(struct slb_entry *slb_ptr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern void slb_vmalloc_update(void);
 | 
					extern void slb_vmalloc_update(void);
 | 
				
			||||||
extern void slb_set_size(u16 size);
 | 
					 | 
				
			||||||
void preload_new_slb_context(unsigned long start, unsigned long sp);
 | 
					void preload_new_slb_context(unsigned long start, unsigned long sp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
 | 
					void slb_set_size(u16 size);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static inline void slb_set_size(u16 size) { }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __ASSEMBLY__ */
 | 
					#endif /* __ASSEMBLY__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -105,7 +105,9 @@ typedef struct {
 | 
				
			||||||
		 * from EA and new context ids to build the new VAs.
 | 
							 * from EA and new context ids to build the new VAs.
 | 
				
			||||||
		 */
 | 
							 */
 | 
				
			||||||
		mm_context_id_t id;
 | 
							mm_context_id_t id;
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
		mm_context_id_t extended_id[TASK_SIZE_USER64/TASK_CONTEXT_SIZE];
 | 
							mm_context_id_t extended_id[TASK_SIZE_USER64/TASK_CONTEXT_SIZE];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	};
 | 
						};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Number of bits in the mm_cpumask */
 | 
						/* Number of bits in the mm_cpumask */
 | 
				
			||||||
| 
						 | 
					@ -117,7 +119,9 @@ typedef struct {
 | 
				
			||||||
	/* Number of user space windows opened in process mm_context */
 | 
						/* Number of user space windows opened in process mm_context */
 | 
				
			||||||
	atomic_t vas_windows;
 | 
						atomic_t vas_windows;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	struct hash_mm_context *hash_context;
 | 
						struct hash_mm_context *hash_context;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	void __user *vdso;
 | 
						void __user *vdso;
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -140,6 +144,7 @@ typedef struct {
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
} mm_context_t;
 | 
					} mm_context_t;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
static inline u16 mm_ctx_user_psize(mm_context_t *ctx)
 | 
					static inline u16 mm_ctx_user_psize(mm_context_t *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	return ctx->hash_context->user_psize;
 | 
						return ctx->hash_context->user_psize;
 | 
				
			||||||
| 
						 | 
					@ -200,8 +205,15 @@ static inline struct subpage_prot_table *mm_ctx_subpage_prot(mm_context_t *ctx)
 | 
				
			||||||
extern int mmu_linear_psize;
 | 
					extern int mmu_linear_psize;
 | 
				
			||||||
extern int mmu_virtual_psize;
 | 
					extern int mmu_virtual_psize;
 | 
				
			||||||
extern int mmu_vmalloc_psize;
 | 
					extern int mmu_vmalloc_psize;
 | 
				
			||||||
extern int mmu_vmemmap_psize;
 | 
					 | 
				
			||||||
extern int mmu_io_psize;
 | 
					extern int mmu_io_psize;
 | 
				
			||||||
 | 
					#else /* CONFIG_PPC_64S_HASH_MMU */
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64K_PAGES
 | 
				
			||||||
 | 
					#define mmu_virtual_psize MMU_PAGE_64K
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					#define mmu_virtual_psize MMU_PAGE_4K
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					extern int mmu_vmemmap_psize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* MMU initialization */
 | 
					/* MMU initialization */
 | 
				
			||||||
void mmu_early_init_devtree(void);
 | 
					void mmu_early_init_devtree(void);
 | 
				
			||||||
| 
						 | 
					@ -240,7 +252,8 @@ static inline void setup_initial_memory_limit(phys_addr_t first_memblock_base,
 | 
				
			||||||
	 * know which translations we will pick. Hence go with hash
 | 
						 * know which translations we will pick. Hence go with hash
 | 
				
			||||||
	 * restrictions.
 | 
						 * restrictions.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	return hash__setup_initial_memory_limit(first_memblock_base,
 | 
						if (!early_radix_enabled())
 | 
				
			||||||
 | 
							hash__setup_initial_memory_limit(first_memblock_base,
 | 
				
			||||||
						 first_memblock_size);
 | 
											 first_memblock_size);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -262,6 +275,7 @@ static inline void radix_init_pseries(void) { }
 | 
				
			||||||
void cleanup_cpu_mmu_context(void);
 | 
					void cleanup_cpu_mmu_context(void);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
static inline int get_user_context(mm_context_t *ctx, unsigned long ea)
 | 
					static inline int get_user_context(mm_context_t *ctx, unsigned long ea)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int index = ea >> MAX_EA_BITS_PER_CONTEXT;
 | 
						int index = ea >> MAX_EA_BITS_PER_CONTEXT;
 | 
				
			||||||
| 
						 | 
					@ -281,6 +295,7 @@ static inline unsigned long get_user_vsid(mm_context_t *ctx,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return get_vsid(context, ea, ssize);
 | 
						return get_vsid(context, ea, ssize);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __ASSEMBLY__ */
 | 
					#endif /* __ASSEMBLY__ */
 | 
				
			||||||
#endif /* _ASM_POWERPC_BOOK3S_64_MMU_H_ */
 | 
					#endif /* _ASM_POWERPC_BOOK3S_64_MMU_H_ */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,8 +112,14 @@ static inline void hash__flush_tlb_kernel_range(unsigned long start,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct mmu_gather;
 | 
					struct mmu_gather;
 | 
				
			||||||
extern void hash__tlb_flush(struct mmu_gather *tlb);
 | 
					extern void hash__tlb_flush(struct mmu_gather *tlb);
 | 
				
			||||||
 | 
					void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd, unsigned long addr);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
/* Private function for use by PCI IO mapping code */
 | 
					/* Private function for use by PCI IO mapping code */
 | 
				
			||||||
extern void __flush_hash_table_range(unsigned long start, unsigned long end);
 | 
					extern void __flush_hash_table_range(unsigned long start, unsigned long end);
 | 
				
			||||||
extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
 | 
					extern void flush_tlb_pmd_range(struct mm_struct *mm, pmd_t *pmd,
 | 
				
			||||||
				unsigned long addr);
 | 
									unsigned long addr);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static inline void __flush_hash_table_range(unsigned long start, unsigned long end) { }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#endif /*  _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */
 | 
					#endif /*  _ASM_POWERPC_BOOK3S_64_TLBFLUSH_HASH_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,6 +25,7 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 | 
				
			||||||
				     unsigned long size, pgprot_t vma_prot);
 | 
									     unsigned long size, pgprot_t vma_prot);
 | 
				
			||||||
#define __HAVE_PHYS_MEM_ACCESS_PROT
 | 
					#define __HAVE_PHYS_MEM_ACCESS_PROT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if defined(CONFIG_PPC32) || defined(CONFIG_PPC_64S_HASH_MMU)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * This gets called at the end of handling a page fault, when
 | 
					 * This gets called at the end of handling a page fault, when
 | 
				
			||||||
 * the kernel has put a new PTE into the page table for the process.
 | 
					 * the kernel has put a new PTE into the page table for the process.
 | 
				
			||||||
| 
						 | 
					@ -35,6 +36,9 @@ extern pgprot_t phys_mem_access_prot(struct file *file, unsigned long pfn,
 | 
				
			||||||
 * waiting for the inevitable extra hash-table miss exception.
 | 
					 * waiting for the inevitable extra hash-table miss exception.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep);
 | 
					void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static inline void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t *ptep) {}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* __ASSEMBLY__ */
 | 
					#endif /* __ASSEMBLY__ */
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,6 +75,7 @@ extern void hash__reserve_context_id(int id);
 | 
				
			||||||
extern void __destroy_context(int context_id);
 | 
					extern void __destroy_context(int context_id);
 | 
				
			||||||
static inline void mmu_context_init(void) { }
 | 
					static inline void mmu_context_init(void) { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
static inline int alloc_extended_context(struct mm_struct *mm,
 | 
					static inline int alloc_extended_context(struct mm_struct *mm,
 | 
				
			||||||
					 unsigned long ea)
 | 
										 unsigned long ea)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -100,6 +101,7 @@ static inline bool need_extra_context(struct mm_struct *mm, unsigned long ea)
 | 
				
			||||||
		return true;
 | 
							return true;
 | 
				
			||||||
	return false;
 | 
						return false;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
extern void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next,
 | 
					extern void switch_mmu_context(struct mm_struct *prev, struct mm_struct *next,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -97,7 +97,9 @@ struct paca_struct {
 | 
				
			||||||
					/* this becomes non-zero. */
 | 
										/* this becomes non-zero. */
 | 
				
			||||||
	u8 kexec_state;		/* set when kexec down has irqs off */
 | 
						u8 kexec_state;		/* set when kexec down has irqs off */
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_BOOK3S_64
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	struct slb_shadow *slb_shadow_ptr;
 | 
						struct slb_shadow *slb_shadow_ptr;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	struct dtl_entry *dispatch_log;
 | 
						struct dtl_entry *dispatch_log;
 | 
				
			||||||
	struct dtl_entry *dispatch_log_end;
 | 
						struct dtl_entry *dispatch_log_end;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -110,6 +112,7 @@ struct paca_struct {
 | 
				
			||||||
	/* used for most interrupts/exceptions */
 | 
						/* used for most interrupts/exceptions */
 | 
				
			||||||
	u64 exgen[EX_SIZE] __attribute__((aligned(0x80)));
 | 
						u64 exgen[EX_SIZE] __attribute__((aligned(0x80)));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	/* SLB related definitions */
 | 
						/* SLB related definitions */
 | 
				
			||||||
	u16 vmalloc_sllp;
 | 
						u16 vmalloc_sllp;
 | 
				
			||||||
	u8 slb_cache_ptr;
 | 
						u8 slb_cache_ptr;
 | 
				
			||||||
| 
						 | 
					@ -120,6 +123,7 @@ struct paca_struct {
 | 
				
			||||||
	u32 slb_used_bitmap;		/* Bitmaps for first 32 SLB entries. */
 | 
						u32 slb_used_bitmap;		/* Bitmaps for first 32 SLB entries. */
 | 
				
			||||||
	u32 slb_kern_bitmap;
 | 
						u32 slb_kern_bitmap;
 | 
				
			||||||
	u32 slb_cache[SLB_CACHE_ENTRIES];
 | 
						u32 slb_cache[SLB_CACHE_ENTRIES];
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#endif /* CONFIG_PPC_BOOK3S_64 */
 | 
					#endif /* CONFIG_PPC_BOOK3S_64 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3E
 | 
					#ifdef CONFIG_PPC_BOOK3E
 | 
				
			||||||
| 
						 | 
					@ -149,6 +153,7 @@ struct paca_struct {
 | 
				
			||||||
#endif /* CONFIG_PPC_BOOK3E */
 | 
					#endif /* CONFIG_PPC_BOOK3E */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S
 | 
					#ifdef CONFIG_PPC_BOOK3S
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
#ifdef CONFIG_PPC_MM_SLICES
 | 
					#ifdef CONFIG_PPC_MM_SLICES
 | 
				
			||||||
	unsigned char mm_ctx_low_slices_psize[BITS_PER_LONG / BITS_PER_BYTE];
 | 
						unsigned char mm_ctx_low_slices_psize[BITS_PER_LONG / BITS_PER_BYTE];
 | 
				
			||||||
	unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE];
 | 
						unsigned char mm_ctx_high_slices_psize[SLICE_ARRAY_SIZE];
 | 
				
			||||||
| 
						 | 
					@ -156,6 +161,7 @@ struct paca_struct {
 | 
				
			||||||
	u16 mm_ctx_user_psize;
 | 
						u16 mm_ctx_user_psize;
 | 
				
			||||||
	u16 mm_ctx_sllp;
 | 
						u16 mm_ctx_sllp;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
| 
						 | 
					@ -268,9 +274,11 @@ struct paca_struct {
 | 
				
			||||||
#endif /* CONFIG_PPC_PSERIES */
 | 
					#endif /* CONFIG_PPC_PSERIES */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_BOOK3S_64
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	/* Capture SLB related old contents in MCE handler. */
 | 
						/* Capture SLB related old contents in MCE handler. */
 | 
				
			||||||
	struct slb_entry *mce_faulty_slbs;
 | 
						struct slb_entry *mce_faulty_slbs;
 | 
				
			||||||
	u16 slb_save_cache_ptr;
 | 
						u16 slb_save_cache_ptr;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#endif /* CONFIG_PPC_BOOK3S_64 */
 | 
					#endif /* CONFIG_PPC_BOOK3S_64 */
 | 
				
			||||||
#ifdef CONFIG_STACKPROTECTOR
 | 
					#ifdef CONFIG_STACKPROTECTOR
 | 
				
			||||||
	unsigned long canary;
 | 
						unsigned long canary;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -218,10 +218,12 @@ int main(void)
 | 
				
			||||||
	OFFSET(PACA_EXGEN, paca_struct, exgen);
 | 
						OFFSET(PACA_EXGEN, paca_struct, exgen);
 | 
				
			||||||
	OFFSET(PACA_EXMC, paca_struct, exmc);
 | 
						OFFSET(PACA_EXMC, paca_struct, exmc);
 | 
				
			||||||
	OFFSET(PACA_EXNMI, paca_struct, exnmi);
 | 
						OFFSET(PACA_EXNMI, paca_struct, exnmi);
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	OFFSET(PACA_SLBSHADOWPTR, paca_struct, slb_shadow_ptr);
 | 
						OFFSET(PACA_SLBSHADOWPTR, paca_struct, slb_shadow_ptr);
 | 
				
			||||||
	OFFSET(SLBSHADOW_STACKVSID, slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid);
 | 
						OFFSET(SLBSHADOW_STACKVSID, slb_shadow, save_area[SLB_NUM_BOLTED - 1].vsid);
 | 
				
			||||||
	OFFSET(SLBSHADOW_STACKESID, slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid);
 | 
						OFFSET(SLBSHADOW_STACKESID, slb_shadow, save_area[SLB_NUM_BOLTED - 1].esid);
 | 
				
			||||||
	OFFSET(SLBSHADOW_SAVEAREA, slb_shadow, save_area);
 | 
						OFFSET(SLBSHADOW_SAVEAREA, slb_shadow, save_area);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	OFFSET(LPPACA_PMCINUSE, lppaca, pmcregs_in_use);
 | 
						OFFSET(LPPACA_PMCINUSE, lppaca, pmcregs_in_use);
 | 
				
			||||||
#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 | 
					#ifdef CONFIG_KVM_BOOK3S_HV_POSSIBLE
 | 
				
			||||||
	OFFSET(PACA_PMCINUSE, paca_struct, pmcregs_in_use);
 | 
						OFFSET(PACA_PMCINUSE, paca_struct, pmcregs_in_use);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -180,7 +180,7 @@ _GLOBAL(_switch)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ld	r8,KSP(r4)	/* new stack pointer */
 | 
						ld	r8,KSP(r4)	/* new stack pointer */
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
BEGIN_MMU_FTR_SECTION
 | 
					BEGIN_MMU_FTR_SECTION
 | 
				
			||||||
	b	2f
 | 
						b	2f
 | 
				
			||||||
END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
 | 
					END_MMU_FTR_SECTION_IFSET(MMU_FTR_TYPE_RADIX)
 | 
				
			||||||
| 
						 | 
					@ -232,7 +232,7 @@ END_FTR_SECTION_IFCLR(CPU_FTR_ARCH_207S)
 | 
				
			||||||
	slbmte	r7,r0
 | 
						slbmte	r7,r0
 | 
				
			||||||
	isync
 | 
						isync
 | 
				
			||||||
2:
 | 
					2:
 | 
				
			||||||
#endif /* CONFIG_PPC_BOOK3S_64 */
 | 
					#endif /* CONFIG_PPC_64S_HASH_MMU */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	clrrdi	r7, r8, THREAD_SHIFT	/* base of new stack */
 | 
						clrrdi	r7, r8, THREAD_SHIFT	/* base of new stack */
 | 
				
			||||||
	/* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
 | 
						/* Note: this uses SWITCH_FRAME_SIZE rather than INT_FRAME_SIZE
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1367,11 +1367,15 @@ EXC_COMMON_BEGIN(data_access_common)
 | 
				
			||||||
	addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
						addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
				
			||||||
	andis.	r0,r4,DSISR_DABRMATCH@h
 | 
						andis.	r0,r4,DSISR_DABRMATCH@h
 | 
				
			||||||
	bne-	1f
 | 
						bne-	1f
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
BEGIN_MMU_FTR_SECTION
 | 
					BEGIN_MMU_FTR_SECTION
 | 
				
			||||||
	bl	do_hash_fault
 | 
						bl	do_hash_fault
 | 
				
			||||||
MMU_FTR_SECTION_ELSE
 | 
					MMU_FTR_SECTION_ELSE
 | 
				
			||||||
	bl	do_page_fault
 | 
						bl	do_page_fault
 | 
				
			||||||
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
 | 
					ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						bl	do_page_fault
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	b	interrupt_return_srr
 | 
						b	interrupt_return_srr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
1:	bl	do_break
 | 
					1:	bl	do_break
 | 
				
			||||||
| 
						 | 
					@ -1414,6 +1418,7 @@ EXC_VIRT_BEGIN(data_access_slb, 0x4380, 0x80)
 | 
				
			||||||
EXC_VIRT_END(data_access_slb, 0x4380, 0x80)
 | 
					EXC_VIRT_END(data_access_slb, 0x4380, 0x80)
 | 
				
			||||||
EXC_COMMON_BEGIN(data_access_slb_common)
 | 
					EXC_COMMON_BEGIN(data_access_slb_common)
 | 
				
			||||||
	GEN_COMMON data_access_slb
 | 
						GEN_COMMON data_access_slb
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
BEGIN_MMU_FTR_SECTION
 | 
					BEGIN_MMU_FTR_SECTION
 | 
				
			||||||
	/* HPT case, do SLB fault */
 | 
						/* HPT case, do SLB fault */
 | 
				
			||||||
	addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
						addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
				
			||||||
| 
						 | 
					@ -1426,6 +1431,9 @@ MMU_FTR_SECTION_ELSE
 | 
				
			||||||
	/* Radix case, access is outside page table range */
 | 
						/* Radix case, access is outside page table range */
 | 
				
			||||||
	li	r3,-EFAULT
 | 
						li	r3,-EFAULT
 | 
				
			||||||
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
 | 
					ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						li	r3,-EFAULT
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	std	r3,RESULT(r1)
 | 
						std	r3,RESULT(r1)
 | 
				
			||||||
	addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
						addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
				
			||||||
	bl	do_bad_segment_interrupt
 | 
						bl	do_bad_segment_interrupt
 | 
				
			||||||
| 
						 | 
					@ -1460,11 +1468,15 @@ EXC_VIRT_END(instruction_access, 0x4400, 0x80)
 | 
				
			||||||
EXC_COMMON_BEGIN(instruction_access_common)
 | 
					EXC_COMMON_BEGIN(instruction_access_common)
 | 
				
			||||||
	GEN_COMMON instruction_access
 | 
						GEN_COMMON instruction_access
 | 
				
			||||||
	addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
						addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
BEGIN_MMU_FTR_SECTION
 | 
					BEGIN_MMU_FTR_SECTION
 | 
				
			||||||
	bl	do_hash_fault
 | 
						bl	do_hash_fault
 | 
				
			||||||
MMU_FTR_SECTION_ELSE
 | 
					MMU_FTR_SECTION_ELSE
 | 
				
			||||||
	bl	do_page_fault
 | 
						bl	do_page_fault
 | 
				
			||||||
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
 | 
					ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						bl	do_page_fault
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	b	interrupt_return_srr
 | 
						b	interrupt_return_srr
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1494,6 +1506,7 @@ EXC_VIRT_BEGIN(instruction_access_slb, 0x4480, 0x80)
 | 
				
			||||||
EXC_VIRT_END(instruction_access_slb, 0x4480, 0x80)
 | 
					EXC_VIRT_END(instruction_access_slb, 0x4480, 0x80)
 | 
				
			||||||
EXC_COMMON_BEGIN(instruction_access_slb_common)
 | 
					EXC_COMMON_BEGIN(instruction_access_slb_common)
 | 
				
			||||||
	GEN_COMMON instruction_access_slb
 | 
						GEN_COMMON instruction_access_slb
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
BEGIN_MMU_FTR_SECTION
 | 
					BEGIN_MMU_FTR_SECTION
 | 
				
			||||||
	/* HPT case, do SLB fault */
 | 
						/* HPT case, do SLB fault */
 | 
				
			||||||
	addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
						addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
				
			||||||
| 
						 | 
					@ -1506,6 +1519,9 @@ MMU_FTR_SECTION_ELSE
 | 
				
			||||||
	/* Radix case, access is outside page table range */
 | 
						/* Radix case, access is outside page table range */
 | 
				
			||||||
	li	r3,-EFAULT
 | 
						li	r3,-EFAULT
 | 
				
			||||||
ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
 | 
					ALT_MMU_FTR_SECTION_END_IFCLR(MMU_FTR_TYPE_RADIX)
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						li	r3,-EFAULT
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
	std	r3,RESULT(r1)
 | 
						std	r3,RESULT(r1)
 | 
				
			||||||
	addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
						addi	r3,r1,STACK_FRAME_OVERHEAD
 | 
				
			||||||
	bl	do_bad_segment_interrupt
 | 
						bl	do_bad_segment_interrupt
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -586,7 +586,7 @@ void machine_check_print_event_info(struct machine_check_event *evt,
 | 
				
			||||||
		mc_error_class[evt->error_class] : "Unknown";
 | 
							mc_error_class[evt->error_class] : "Unknown";
 | 
				
			||||||
	printk("%sMCE: CPU%d: %s\n", level, evt->cpu, subtype);
 | 
						printk("%sMCE: CPU%d: %s\n", level, evt->cpu, subtype);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	/* Display faulty slb contents for SLB errors. */
 | 
						/* Display faulty slb contents for SLB errors. */
 | 
				
			||||||
	if (evt->error_type == MCE_ERROR_TYPE_SLB && !in_guest)
 | 
						if (evt->error_type == MCE_ERROR_TYPE_SLB && !in_guest)
 | 
				
			||||||
		slb_dump_contents(local_paca->mce_faulty_slbs);
 | 
							slb_dump_contents(local_paca->mce_faulty_slbs);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -77,7 +77,7 @@ static bool mce_in_guest(void)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* flush SLBs and reload */
 | 
					/* flush SLBs and reload */
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
void flush_and_reload_slb(void)
 | 
					void flush_and_reload_slb(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	if (early_radix_enabled())
 | 
						if (early_radix_enabled())
 | 
				
			||||||
| 
						 | 
					@ -99,7 +99,7 @@ void flush_and_reload_slb(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void flush_erat(void)
 | 
					void flush_erat(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
 | 
						if (!early_cpu_has_feature(CPU_FTR_ARCH_300)) {
 | 
				
			||||||
		flush_and_reload_slb();
 | 
							flush_and_reload_slb();
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
| 
						 | 
					@ -114,7 +114,7 @@ void flush_erat(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int mce_flush(int what)
 | 
					static int mce_flush(int what)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	if (what == MCE_FLUSH_SLB) {
 | 
						if (what == MCE_FLUSH_SLB) {
 | 
				
			||||||
		flush_and_reload_slb();
 | 
							flush_and_reload_slb();
 | 
				
			||||||
		return 1;
 | 
							return 1;
 | 
				
			||||||
| 
						 | 
					@ -499,8 +499,10 @@ static int mce_handle_ierror(struct pt_regs *regs, unsigned long srr1,
 | 
				
			||||||
			/* attempt to correct the error */
 | 
								/* attempt to correct the error */
 | 
				
			||||||
			switch (table[i].error_type) {
 | 
								switch (table[i].error_type) {
 | 
				
			||||||
			case MCE_ERROR_TYPE_SLB:
 | 
								case MCE_ERROR_TYPE_SLB:
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
				if (local_paca->in_mce == 1)
 | 
									if (local_paca->in_mce == 1)
 | 
				
			||||||
					slb_save_contents(local_paca->mce_faulty_slbs);
 | 
										slb_save_contents(local_paca->mce_faulty_slbs);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
				handled = mce_flush(MCE_FLUSH_SLB);
 | 
									handled = mce_flush(MCE_FLUSH_SLB);
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
			case MCE_ERROR_TYPE_ERAT:
 | 
								case MCE_ERROR_TYPE_ERAT:
 | 
				
			||||||
| 
						 | 
					@ -588,8 +590,10 @@ static int mce_handle_derror(struct pt_regs *regs,
 | 
				
			||||||
			/* attempt to correct the error */
 | 
								/* attempt to correct the error */
 | 
				
			||||||
			switch (table[i].error_type) {
 | 
								switch (table[i].error_type) {
 | 
				
			||||||
			case MCE_ERROR_TYPE_SLB:
 | 
								case MCE_ERROR_TYPE_SLB:
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
				if (local_paca->in_mce == 1)
 | 
									if (local_paca->in_mce == 1)
 | 
				
			||||||
					slb_save_contents(local_paca->mce_faulty_slbs);
 | 
										slb_save_contents(local_paca->mce_faulty_slbs);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
				if (mce_flush(MCE_FLUSH_SLB))
 | 
									if (mce_flush(MCE_FLUSH_SLB))
 | 
				
			||||||
					handled = 1;
 | 
										handled = 1;
 | 
				
			||||||
				break;
 | 
									break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -139,8 +139,7 @@ static struct lppaca * __init new_lppaca(int cpu, unsigned long limit)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif /* CONFIG_PPC_PSERIES */
 | 
					#endif /* CONFIG_PPC_PSERIES */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * 3 persistent SLBs are allocated here.  The buffer will be zero
 | 
					 * 3 persistent SLBs are allocated here.  The buffer will be zero
 | 
				
			||||||
 * initially, hence will all be invaild until we actually write them.
 | 
					 * initially, hence will all be invaild until we actually write them.
 | 
				
			||||||
| 
						 | 
					@ -169,8 +168,7 @@ static struct slb_shadow * __init new_slb_shadow(int cpu, unsigned long limit)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return s;
 | 
						return s;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif /* CONFIG_PPC_64S_HASH_MMU */
 | 
				
			||||||
#endif /* CONFIG_PPC_BOOK3S_64 */
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_PSERIES
 | 
					#ifdef CONFIG_PPC_PSERIES
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
| 
						 | 
					@ -226,7 +224,7 @@ void __init initialise_paca(struct paca_struct *new_paca, int cpu)
 | 
				
			||||||
	new_paca->kexec_state = KEXEC_STATE_NONE;
 | 
						new_paca->kexec_state = KEXEC_STATE_NONE;
 | 
				
			||||||
	new_paca->__current = &init_task;
 | 
						new_paca->__current = &init_task;
 | 
				
			||||||
	new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL;
 | 
						new_paca->data_offset = 0xfeeeeeeeeeeeeeeeULL;
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	new_paca->slb_shadow_ptr = NULL;
 | 
						new_paca->slb_shadow_ptr = NULL;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -307,7 +305,7 @@ void __init allocate_paca(int cpu)
 | 
				
			||||||
#ifdef CONFIG_PPC_PSERIES
 | 
					#ifdef CONFIG_PPC_PSERIES
 | 
				
			||||||
	paca->lppaca_ptr = new_lppaca(cpu, limit);
 | 
						paca->lppaca_ptr = new_lppaca(cpu, limit);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	paca->slb_shadow_ptr = new_slb_shadow(cpu, limit);
 | 
						paca->slb_shadow_ptr = new_slb_shadow(cpu, limit);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef CONFIG_PPC_PSERIES
 | 
					#ifdef CONFIG_PPC_PSERIES
 | 
				
			||||||
| 
						 | 
					@ -328,7 +326,7 @@ void __init free_unused_pacas(void)
 | 
				
			||||||
	paca_nr_cpu_ids = nr_cpu_ids;
 | 
						paca_nr_cpu_ids = nr_cpu_ids;
 | 
				
			||||||
	paca_ptrs_size = new_ptrs_size;
 | 
						paca_ptrs_size = new_ptrs_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	if (early_radix_enabled()) {
 | 
						if (early_radix_enabled()) {
 | 
				
			||||||
		/* Ugly fixup, see new_slb_shadow() */
 | 
							/* Ugly fixup, see new_slb_shadow() */
 | 
				
			||||||
		memblock_phys_free(__pa(paca_ptrs[boot_cpuid]->slb_shadow_ptr),
 | 
							memblock_phys_free(__pa(paca_ptrs[boot_cpuid]->slb_shadow_ptr),
 | 
				
			||||||
| 
						 | 
					@ -341,9 +339,9 @@ void __init free_unused_pacas(void)
 | 
				
			||||||
			paca_ptrs_size + paca_struct_size, nr_cpu_ids);
 | 
								paca_ptrs_size + paca_struct_size, nr_cpu_ids);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
void copy_mm_to_paca(struct mm_struct *mm)
 | 
					void copy_mm_to_paca(struct mm_struct *mm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S
 | 
					 | 
				
			||||||
	mm_context_t *context = &mm->context;
 | 
						mm_context_t *context = &mm->context;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_MM_SLICES
 | 
					#ifdef CONFIG_PPC_MM_SLICES
 | 
				
			||||||
| 
						 | 
					@ -356,7 +354,5 @@ void copy_mm_to_paca(struct mm_struct *mm)
 | 
				
			||||||
	get_paca()->mm_ctx_user_psize = context->user_psize;
 | 
						get_paca()->mm_ctx_user_psize = context->user_psize;
 | 
				
			||||||
	get_paca()->mm_ctx_sllp = context->sllp;
 | 
						get_paca()->mm_ctx_sllp = context->sllp;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#else /* !CONFIG_PPC_BOOK3S */
 | 
					 | 
				
			||||||
	return;
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif /* CONFIG_PPC_64S_HASH_MMU */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1240,7 +1240,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct thread_struct *new_thread, *old_thread;
 | 
						struct thread_struct *new_thread, *old_thread;
 | 
				
			||||||
	struct task_struct *last;
 | 
						struct task_struct *last;
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	struct ppc64_tlb_batch *batch;
 | 
						struct ppc64_tlb_batch *batch;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1249,7 +1249,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	WARN_ON(!irqs_disabled());
 | 
						WARN_ON(!irqs_disabled());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	batch = this_cpu_ptr(&ppc64_tlb_batch);
 | 
						batch = this_cpu_ptr(&ppc64_tlb_batch);
 | 
				
			||||||
	if (batch->active) {
 | 
						if (batch->active) {
 | 
				
			||||||
		current_thread_info()->local_flags |= _TLF_LAZY_MMU;
 | 
							current_thread_info()->local_flags |= _TLF_LAZY_MMU;
 | 
				
			||||||
| 
						 | 
					@ -1328,6 +1328,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_BOOK3S_64
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * This applies to a process that was context switched while inside
 | 
						 * This applies to a process that was context switched while inside
 | 
				
			||||||
	 * arch_enter_lazy_mmu_mode(), to re-activate the batch that was
 | 
						 * arch_enter_lazy_mmu_mode(), to re-activate the batch that was
 | 
				
			||||||
| 
						 | 
					@ -1339,6 +1340,7 @@ struct task_struct *__switch_to(struct task_struct *prev,
 | 
				
			||||||
		batch = this_cpu_ptr(&ppc64_tlb_batch);
 | 
							batch = this_cpu_ptr(&ppc64_tlb_batch);
 | 
				
			||||||
		batch->active = 1;
 | 
							batch->active = 1;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Math facilities are masked out of the child MSR in copy_thread.
 | 
						 * Math facilities are masked out of the child MSR in copy_thread.
 | 
				
			||||||
| 
						 | 
					@ -1689,7 +1691,7 @@ int arch_dup_task_struct(struct task_struct *dst, struct task_struct *src)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void setup_ksp_vsid(struct task_struct *p, unsigned long sp)
 | 
					static void setup_ksp_vsid(struct task_struct *p, unsigned long sp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	unsigned long sp_vsid;
 | 
						unsigned long sp_vsid;
 | 
				
			||||||
	unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
 | 
						unsigned long llp = mmu_psize_defs[mmu_linear_psize].sllp;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2333,10 +2335,9 @@ unsigned long arch_randomize_brk(struct mm_struct *mm)
 | 
				
			||||||
	 * the heap, we can put it above 1TB so it is backed by a 1TB
 | 
						 * the heap, we can put it above 1TB so it is backed by a 1TB
 | 
				
			||||||
	 * segment. Otherwise the heap will be in the bottom 1TB
 | 
						 * segment. Otherwise the heap will be in the bottom 1TB
 | 
				
			||||||
	 * which always uses 256MB segments and this may result in a
 | 
						 * which always uses 256MB segments and this may result in a
 | 
				
			||||||
	 * performance penalty. We don't need to worry about radix. For
 | 
						 * performance penalty.
 | 
				
			||||||
	 * radix, mmu_highuser_ssize remains unchanged from 256MB.
 | 
					 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (!is_32bit_task() && (mmu_highuser_ssize == MMU_SEGSIZE_1T))
 | 
						if (!radix_enabled() && !is_32bit_task() && (mmu_highuser_ssize == MMU_SEGSIZE_1T))
 | 
				
			||||||
		base = max_t(unsigned long, mm->brk, 1UL << SID_SHIFT_1T);
 | 
							base = max_t(unsigned long, mm->brk, 1UL << SID_SHIFT_1T);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -231,7 +231,7 @@ static void __init check_cpu_pa_features(unsigned long node)
 | 
				
			||||||
		      ibm_pa_features, ARRAY_SIZE(ibm_pa_features));
 | 
							      ibm_pa_features, ARRAY_SIZE(ibm_pa_features));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
static void __init init_mmu_slb_size(unsigned long node)
 | 
					static void __init init_mmu_slb_size(unsigned long node)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	const __be32 *slb_size_ptr;
 | 
						const __be32 *slb_size_ptr;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -886,7 +886,7 @@ void __init setup_per_cpu_areas(void)
 | 
				
			||||||
		atom_size = SZ_1M;
 | 
							atom_size = SZ_1M;
 | 
				
			||||||
	} else if (radix_enabled()) {
 | 
						} else if (radix_enabled()) {
 | 
				
			||||||
		atom_size = PAGE_SIZE;
 | 
							atom_size = PAGE_SIZE;
 | 
				
			||||||
	} else {
 | 
						} else if (IS_ENABLED(CONFIG_PPC_64S_HASH_MMU)) {
 | 
				
			||||||
		/*
 | 
							/*
 | 
				
			||||||
		 * Linear mapping is one of 4K, 1M and 16M.  For 4K, no need
 | 
							 * Linear mapping is one of 4K, 1M and 16M.  For 4K, no need
 | 
				
			||||||
		 * to group units.  For larger mappings, use 1M atom which
 | 
							 * to group units.  For larger mappings, use 1M atom which
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -378,7 +378,7 @@ void default_machine_kexec(struct kimage *image)
 | 
				
			||||||
	/* NOTREACHED */
 | 
						/* NOTREACHED */
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
/* Values we need to export to the second kernel via the device tree. */
 | 
					/* Values we need to export to the second kernel via the device tree. */
 | 
				
			||||||
static unsigned long htab_base;
 | 
					static unsigned long htab_base;
 | 
				
			||||||
static unsigned long htab_size;
 | 
					static unsigned long htab_size;
 | 
				
			||||||
| 
						 | 
					@ -420,4 +420,4 @@ static int __init export_htab_values(void)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
late_initcall(export_htab_values);
 | 
					late_initcall(export_htab_values);
 | 
				
			||||||
#endif /* CONFIG_PPC_BOOK3S_64 */
 | 
					#endif /* CONFIG_PPC_64S_HASH_MMU */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -296,7 +296,7 @@ int add_initrd_mem_range(struct crash_mem **mem_ranges)
 | 
				
			||||||
	return ret;
 | 
						return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
/**
 | 
					/**
 | 
				
			||||||
 * add_htab_mem_range - Adds htab range to the given memory ranges list,
 | 
					 * add_htab_mem_range - Adds htab range to the given memory ranges list,
 | 
				
			||||||
 *                      if it exists
 | 
					 *                      if it exists
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,20 +2,23 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ccflags-y	:= $(NO_MINIMAL_TOC)
 | 
					ccflags-y	:= $(NO_MINIMAL_TOC)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					obj-y				+= mmu_context.o pgtable.o trace.o
 | 
				
			||||||
 | 
					ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
CFLAGS_REMOVE_slb.o = $(CC_FLAGS_FTRACE)
 | 
					CFLAGS_REMOVE_slb.o = $(CC_FLAGS_FTRACE)
 | 
				
			||||||
 | 
					obj-y				+= hash_pgtable.o hash_utils.o hash_tlb.o slb.o
 | 
				
			||||||
obj-y				+= hash_pgtable.o hash_utils.o slb.o \
 | 
					 | 
				
			||||||
				   mmu_context.o pgtable.o hash_tlb.o trace.o
 | 
					 | 
				
			||||||
obj-$(CONFIG_PPC_HASH_MMU_NATIVE)	+= hash_native.o
 | 
					obj-$(CONFIG_PPC_HASH_MMU_NATIVE)	+= hash_native.o
 | 
				
			||||||
obj-$(CONFIG_PPC_RADIX_MMU)	+= radix_pgtable.o radix_tlb.o
 | 
					 | 
				
			||||||
obj-$(CONFIG_PPC_4K_PAGES)	+= hash_4k.o
 | 
					obj-$(CONFIG_PPC_4K_PAGES)	+= hash_4k.o
 | 
				
			||||||
obj-$(CONFIG_PPC_64K_PAGES)	+= hash_64k.o
 | 
					obj-$(CONFIG_PPC_64K_PAGES)	+= hash_64k.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += hash_hugepage.o
 | 
				
			||||||
 | 
					obj-$(CONFIG_PPC_SUBPAGE_PROT)	+= subpage_prot.o
 | 
				
			||||||
 | 
					endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 | 
					obj-$(CONFIG_HUGETLB_PAGE)	+= hugetlbpage.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					obj-$(CONFIG_PPC_RADIX_MMU)	+= radix_pgtable.o radix_tlb.o
 | 
				
			||||||
ifdef CONFIG_HUGETLB_PAGE
 | 
					ifdef CONFIG_HUGETLB_PAGE
 | 
				
			||||||
obj-$(CONFIG_PPC_RADIX_MMU)	+= radix_hugetlbpage.o
 | 
					obj-$(CONFIG_PPC_RADIX_MMU)	+= radix_hugetlbpage.o
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
obj-$(CONFIG_TRANSPARENT_HUGEPAGE) += hash_hugepage.o
 | 
					 | 
				
			||||||
obj-$(CONFIG_PPC_SUBPAGE_PROT)	+= subpage_prot.o
 | 
					 | 
				
			||||||
obj-$(CONFIG_SPAPR_TCE_IOMMU)	+= iommu_api.o
 | 
					obj-$(CONFIG_SPAPR_TCE_IOMMU)	+= iommu_api.o
 | 
				
			||||||
obj-$(CONFIG_PPC_PKEY)	+= pkeys.o
 | 
					obj-$(CONFIG_PPC_PKEY)	+= pkeys.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@
 | 
				
			||||||
unsigned int hpage_shift;
 | 
					unsigned int hpage_shift;
 | 
				
			||||||
EXPORT_SYMBOL(hpage_shift);
 | 
					EXPORT_SYMBOL(hpage_shift);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
 | 
					int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
 | 
				
			||||||
		     pte_t *ptep, unsigned long trap, unsigned long flags,
 | 
							     pte_t *ptep, unsigned long trap, unsigned long flags,
 | 
				
			||||||
		     int ssize, unsigned int shift, unsigned int mmu_psize)
 | 
							     int ssize, unsigned int shift, unsigned int mmu_psize)
 | 
				
			||||||
| 
						 | 
					@ -122,6 +123,7 @@ int __hash_page_huge(unsigned long ea, unsigned long access, unsigned long vsid,
 | 
				
			||||||
	*ptep = __pte(new_pte & ~H_PAGE_BUSY);
 | 
						*ptep = __pte(new_pte & ~H_PAGE_BUSY);
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
 | 
					pte_t huge_ptep_modify_prot_start(struct vm_area_struct *vma,
 | 
				
			||||||
				  unsigned long addr, pte_t *ptep)
 | 
									  unsigned long addr, pte_t *ptep)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -31,6 +31,7 @@ static int alloc_context_id(int min_id, int max_id)
 | 
				
			||||||
	return ida_alloc_range(&mmu_context_ida, min_id, max_id, GFP_KERNEL);
 | 
						return ida_alloc_range(&mmu_context_ida, min_id, max_id, GFP_KERNEL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
void hash__reserve_context_id(int id)
 | 
					void hash__reserve_context_id(int id)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int result = ida_alloc_range(&mmu_context_ida, id, id, GFP_KERNEL);
 | 
						int result = ida_alloc_range(&mmu_context_ida, id, id, GFP_KERNEL);
 | 
				
			||||||
| 
						 | 
					@ -50,7 +51,9 @@ int hash__alloc_context_id(void)
 | 
				
			||||||
	return alloc_context_id(MIN_USER_CONTEXT, max);
 | 
						return alloc_context_id(MIN_USER_CONTEXT, max);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(hash__alloc_context_id);
 | 
					EXPORT_SYMBOL_GPL(hash__alloc_context_id);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
static int realloc_context_ids(mm_context_t *ctx)
 | 
					static int realloc_context_ids(mm_context_t *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i, id;
 | 
						int i, id;
 | 
				
			||||||
| 
						 | 
					@ -150,6 +153,13 @@ void hash__setup_new_exec(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	slb_setup_new_exec();
 | 
						slb_setup_new_exec();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static inline int hash__init_new_context(struct mm_struct *mm)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						BUILD_BUG();
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int radix__init_new_context(struct mm_struct *mm)
 | 
					static int radix__init_new_context(struct mm_struct *mm)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -175,7 +185,9 @@ static int radix__init_new_context(struct mm_struct *mm)
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	asm volatile("ptesync;isync" : : : "memory");
 | 
						asm volatile("ptesync;isync" : : : "memory");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	mm->context.hash_context = NULL;
 | 
						mm->context.hash_context = NULL;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return index;
 | 
						return index;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -213,6 +225,10 @@ EXPORT_SYMBOL_GPL(__destroy_context);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void destroy_contexts(mm_context_t *ctx)
 | 
					static void destroy_contexts(mm_context_t *ctx)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
						if (radix_enabled()) {
 | 
				
			||||||
 | 
							ida_free(&mmu_context_ida, ctx->id);
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
		int index, context_id;
 | 
							int index, context_id;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		for (index = 0; index < ARRAY_SIZE(ctx->extended_id); index++) {
 | 
							for (index = 0; index < ARRAY_SIZE(ctx->extended_id); index++) {
 | 
				
			||||||
| 
						 | 
					@ -221,6 +237,10 @@ static void destroy_contexts(mm_context_t *ctx)
 | 
				
			||||||
				ida_free(&mmu_context_ida, context_id);
 | 
									ida_free(&mmu_context_ida, context_id);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		kfree(ctx->hash_context);
 | 
							kfree(ctx->hash_context);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
							BUILD_BUG(); // radix_enabled() should be constant true
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void pmd_frag_destroy(void *pmd_frag)
 | 
					static void pmd_frag_destroy(void *pmd_frag)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -529,7 +529,7 @@ static int __init pgtable_debugfs_setup(void)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
arch_initcall(pgtable_debugfs_setup);
 | 
					arch_initcall(pgtable_debugfs_setup);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_ZONE_DEVICE
 | 
					#if defined(CONFIG_ZONE_DEVICE) && defined(CONFIG_ARCH_HAS_MEMREMAP_COMPAT_ALIGN)
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Override the generic version in mm/memremap.c.
 | 
					 * Override the generic version in mm/memremap.c.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -334,7 +334,7 @@ static void __init radix_init_pgtable(void)
 | 
				
			||||||
	u64 i;
 | 
						u64 i;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* We don't support slb for radix */
 | 
						/* We don't support slb for radix */
 | 
				
			||||||
	mmu_slb_size = 0;
 | 
						slb_set_size(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Create the linear mapping
 | 
						 * Create the linear mapping
 | 
				
			||||||
| 
						 | 
					@ -565,6 +565,7 @@ void __init radix__early_init_mmu(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long lpcr;
 | 
						unsigned long lpcr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
#ifdef CONFIG_PPC_64K_PAGES
 | 
					#ifdef CONFIG_PPC_64K_PAGES
 | 
				
			||||||
	/* PAGE_SIZE mappings */
 | 
						/* PAGE_SIZE mappings */
 | 
				
			||||||
	mmu_virtual_psize = MMU_PAGE_64K;
 | 
						mmu_virtual_psize = MMU_PAGE_64K;
 | 
				
			||||||
| 
						 | 
					@ -581,6 +582,7 @@ void __init radix__early_init_mmu(void)
 | 
				
			||||||
		mmu_vmemmap_psize = MMU_PAGE_2M;
 | 
							mmu_vmemmap_psize = MMU_PAGE_2M;
 | 
				
			||||||
	} else
 | 
						} else
 | 
				
			||||||
		mmu_vmemmap_psize = mmu_virtual_psize;
 | 
							mmu_vmemmap_psize = mmu_virtual_psize;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * initialize page table size
 | 
						 * initialize page table size
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,6 +82,7 @@ int copro_handle_mm_fault(struct mm_struct *mm, unsigned long ea,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(copro_handle_mm_fault);
 | 
					EXPORT_SYMBOL_GPL(copro_handle_mm_fault);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
 | 
					int copro_calculate_slb(struct mm_struct *mm, u64 ea, struct copro_slb *slb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	u64 vsid, vsidkey;
 | 
						u64 vsid, vsidkey;
 | 
				
			||||||
| 
						 | 
					@ -146,3 +147,4 @@ void copro_flush_all_slbs(struct mm_struct *mm)
 | 
				
			||||||
	cxl_slbia(mm);
 | 
						cxl_slbia(mm);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
EXPORT_SYMBOL_GPL(copro_flush_all_slbs);
 | 
					EXPORT_SYMBOL_GPL(copro_flush_all_slbs);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,5 +10,5 @@ obj-$(CONFIG_PPC_BOOK3S_64)	+= book3s64.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ifdef CONFIG_PTDUMP_DEBUGFS
 | 
					ifdef CONFIG_PTDUMP_DEBUGFS
 | 
				
			||||||
obj-$(CONFIG_PPC_BOOK3S_32)	+= bats.o segment_regs.o
 | 
					obj-$(CONFIG_PPC_BOOK3S_32)	+= bats.o segment_regs.o
 | 
				
			||||||
obj-$(CONFIG_PPC_BOOK3S_64)	+= hashpagetable.o
 | 
					obj-$(CONFIG_PPC_64S_HASH_MMU)	+= hashpagetable.o
 | 
				
			||||||
endif
 | 
					endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -491,12 +491,14 @@ static unsigned long power7_idle_insn(unsigned long type)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	mtspr(SPRN_SPRG3,	local_paca->sprg_vdso);
 | 
						mtspr(SPRN_SPRG3,	local_paca->sprg_vdso);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * The SLB has to be restored here, but it sometimes still
 | 
						 * The SLB has to be restored here, but it sometimes still
 | 
				
			||||||
	 * contains entries, so the __ variant must be used to prevent
 | 
						 * contains entries, so the __ variant must be used to prevent
 | 
				
			||||||
	 * multi hits.
 | 
						 * multi hits.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	__slb_restore_bolted_realmode();
 | 
						__slb_restore_bolted_realmode();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return srr1;
 | 
						return srr1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -211,6 +211,7 @@ static void __init pnv_init(void)
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
		add_preferred_console("hvc", 0, NULL);
 | 
							add_preferred_console("hvc", 0, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	if (!radix_enabled()) {
 | 
						if (!radix_enabled()) {
 | 
				
			||||||
		size_t size = sizeof(struct slb_entry) * mmu_slb_size;
 | 
							size_t size = sizeof(struct slb_entry) * mmu_slb_size;
 | 
				
			||||||
		int i;
 | 
							int i;
 | 
				
			||||||
| 
						 | 
					@ -223,6 +224,7 @@ static void __init pnv_init(void)
 | 
				
			||||||
						cpu_to_node(i));
 | 
											cpu_to_node(i));
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void __init pnv_init_IRQ(void)
 | 
					static void __init pnv_init_IRQ(void)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -58,6 +58,7 @@ EXPORT_SYMBOL(plpar_hcall);
 | 
				
			||||||
EXPORT_SYMBOL(plpar_hcall9);
 | 
					EXPORT_SYMBOL(plpar_hcall9);
 | 
				
			||||||
EXPORT_SYMBOL(plpar_hcall_norets);
 | 
					EXPORT_SYMBOL(plpar_hcall_norets);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * H_BLOCK_REMOVE supported block size for this page size in segment who's base
 | 
					 * H_BLOCK_REMOVE supported block size for this page size in segment who's base
 | 
				
			||||||
 * page size is that page size.
 | 
					 * page size is that page size.
 | 
				
			||||||
| 
						 | 
					@ -66,6 +67,7 @@ EXPORT_SYMBOL(plpar_hcall_norets);
 | 
				
			||||||
 * page size.
 | 
					 * page size.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static int hblkrm_size[MMU_PAGE_COUNT][MMU_PAGE_COUNT] __ro_after_init;
 | 
					static int hblkrm_size[MMU_PAGE_COUNT][MMU_PAGE_COUNT] __ro_after_init;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Due to the involved complexity, and that the current hypervisor is only
 | 
					 * Due to the involved complexity, and that the current hypervisor is only
 | 
				
			||||||
| 
						 | 
					@ -689,7 +691,7 @@ void vpa_init(int cpu)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * PAPR says this feature is SLB-Buffer but firmware never
 | 
						 * PAPR says this feature is SLB-Buffer but firmware never
 | 
				
			||||||
	 * reports that.  All SPLPAR support SLB shadow buffer.
 | 
						 * reports that.  All SPLPAR support SLB shadow buffer.
 | 
				
			||||||
| 
						 | 
					@ -702,7 +704,7 @@ void vpa_init(int cpu)
 | 
				
			||||||
			       "cpu %d (hw %d) of area %lx failed with %ld\n",
 | 
								       "cpu %d (hw %d) of area %lx failed with %ld\n",
 | 
				
			||||||
			       cpu, hwcpu, addr, ret);
 | 
								       cpu, hwcpu, addr, ret);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
#endif /* CONFIG_PPC_BOOK3S_64 */
 | 
					#endif /* CONFIG_PPC_64S_HASH_MMU */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * Register dispatch trace log, if one has been allocated.
 | 
						 * Register dispatch trace log, if one has been allocated.
 | 
				
			||||||
| 
						 | 
					@ -740,6 +742,8 @@ static int pseries_lpar_register_process_table(unsigned long base,
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
 | 
					static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
 | 
				
			||||||
				     unsigned long vpn, unsigned long pa,
 | 
									     unsigned long vpn, unsigned long pa,
 | 
				
			||||||
				     unsigned long rflags, unsigned long vflags,
 | 
									     unsigned long rflags, unsigned long vflags,
 | 
				
			||||||
| 
						 | 
					@ -1730,6 +1734,7 @@ void __init hpte_init_pseries(void)
 | 
				
			||||||
	if (cpu_has_feature(CPU_FTR_ARCH_300))
 | 
						if (cpu_has_feature(CPU_FTR_ARCH_300))
 | 
				
			||||||
		pseries_lpar_register_process_table(0, 0, 0);
 | 
							pseries_lpar_register_process_table(0, 0, 0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					#endif /* CONFIG_PPC_64S_HASH_MMU */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_RADIX_MMU
 | 
					#ifdef CONFIG_PPC_RADIX_MMU
 | 
				
			||||||
void radix_init_pseries(void)
 | 
					void radix_init_pseries(void)
 | 
				
			||||||
| 
						 | 
					@ -1932,6 +1937,7 @@ int h_get_mpp_x(struct hvcall_mpp_x_data *mpp_x_data)
 | 
				
			||||||
	return rc;
 | 
						return rc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
static unsigned long vsid_unscramble(unsigned long vsid, int ssize)
 | 
					static unsigned long vsid_unscramble(unsigned long vsid, int ssize)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	unsigned long protovsid;
 | 
						unsigned long protovsid;
 | 
				
			||||||
| 
						 | 
					@ -1992,6 +1998,7 @@ static int __init reserve_vrma_context_id(void)
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
machine_device_initcall(pseries, reserve_vrma_context_id);
 | 
					machine_device_initcall(pseries, reserve_vrma_context_id);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_DEBUG_FS
 | 
					#ifdef CONFIG_DEBUG_FS
 | 
				
			||||||
/* debugfs file interface for vpa data */
 | 
					/* debugfs file interface for vpa data */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -531,7 +531,7 @@ static int pseries_lparcfg_data(struct seq_file *m, void *v)
 | 
				
			||||||
	seq_printf(m, "shared_processor_mode=%d\n",
 | 
						seq_printf(m, "shared_processor_mode=%d\n",
 | 
				
			||||||
		   lppaca_shared_proc(get_lppaca()));
 | 
							   lppaca_shared_proc(get_lppaca()));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	if (!radix_enabled())
 | 
						if (!radix_enabled())
 | 
				
			||||||
		seq_printf(m, "slb_size=%d\n", mmu_slb_size);
 | 
							seq_printf(m, "slb_size=%d\n", mmu_slb_size);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -451,11 +451,15 @@ static void prod_others(void)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static u16 clamp_slb_size(void)
 | 
					static u16 clamp_slb_size(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	u16 prev = mmu_slb_size;
 | 
						u16 prev = mmu_slb_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	slb_set_size(SLB_MIN_SIZE);
 | 
						slb_set_size(SLB_MIN_SIZE);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return prev;
 | 
						return prev;
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
						return 0;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int do_suspend(void)
 | 
					static int do_suspend(void)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -113,6 +113,11 @@ int dlpar_workqueue_init(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
extern u32 pseries_security_flavor;
 | 
					extern u32 pseries_security_flavor;
 | 
				
			||||||
void pseries_setup_security_mitigations(void);
 | 
					void pseries_setup_security_mitigations(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
void pseries_lpar_read_hblkrm_characteristics(void);
 | 
					void pseries_lpar_read_hblkrm_characteristics(void);
 | 
				
			||||||
 | 
					#else
 | 
				
			||||||
 | 
					static inline void pseries_lpar_read_hblkrm_characteristics(void) { }
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* _PSERIES_PSERIES_H */
 | 
					#endif /* _PSERIES_PSERIES_H */
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -526,6 +526,7 @@ static int mce_handle_err_realmode(int disposition, u8 error_type)
 | 
				
			||||||
			disposition = RTAS_DISP_FULLY_RECOVERED;
 | 
								disposition = RTAS_DISP_FULLY_RECOVERED;
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		case	MC_ERROR_TYPE_SLB:
 | 
							case	MC_ERROR_TYPE_SLB:
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
			/*
 | 
								/*
 | 
				
			||||||
			 * Store the old slb content in paca before flushing.
 | 
								 * Store the old slb content in paca before flushing.
 | 
				
			||||||
			 * Print this when we go to virtual mode.
 | 
								 * Print this when we go to virtual mode.
 | 
				
			||||||
| 
						 | 
					@ -538,6 +539,7 @@ static int mce_handle_err_realmode(int disposition, u8 error_type)
 | 
				
			||||||
				slb_save_contents(local_paca->mce_faulty_slbs);
 | 
									slb_save_contents(local_paca->mce_faulty_slbs);
 | 
				
			||||||
			flush_and_reload_slb();
 | 
								flush_and_reload_slb();
 | 
				
			||||||
			disposition = RTAS_DISP_FULLY_RECOVERED;
 | 
								disposition = RTAS_DISP_FULLY_RECOVERED;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
		default:
 | 
							default:
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -112,7 +112,7 @@ static void __init fwnmi_init(void)
 | 
				
			||||||
	u8 *mce_data_buf;
 | 
						u8 *mce_data_buf;
 | 
				
			||||||
	unsigned int i;
 | 
						unsigned int i;
 | 
				
			||||||
	int nr_cpus = num_possible_cpus();
 | 
						int nr_cpus = num_possible_cpus();
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	struct slb_entry *slb_ptr;
 | 
						struct slb_entry *slb_ptr;
 | 
				
			||||||
	size_t size;
 | 
						size_t size;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -152,7 +152,7 @@ static void __init fwnmi_init(void)
 | 
				
			||||||
						(RTAS_ERROR_LOG_MAX * i);
 | 
											(RTAS_ERROR_LOG_MAX * i);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	if (!radix_enabled()) {
 | 
						if (!radix_enabled()) {
 | 
				
			||||||
		/* Allocate per cpu area to save old slb contents during MCE */
 | 
							/* Allocate per cpu area to save old slb contents during MCE */
 | 
				
			||||||
		size = sizeof(struct slb_entry) * mmu_slb_size * nr_cpus;
 | 
							size = sizeof(struct slb_entry) * mmu_slb_size * nr_cpus;
 | 
				
			||||||
| 
						 | 
					@ -801,7 +801,9 @@ static void __init pSeries_setup_arch(void)
 | 
				
			||||||
	fwnmi_init();
 | 
						fwnmi_init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pseries_setup_security_mitigations();
 | 
						pseries_setup_security_mitigations();
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	pseries_lpar_read_hblkrm_characteristics();
 | 
						pseries_lpar_read_hblkrm_characteristics();
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* By default, only probe PCI (can be overridden by rtas_pci) */
 | 
						/* By default, only probe PCI (can be overridden by rtas_pci) */
 | 
				
			||||||
	pci_add_flags(PCI_PROBE_ONLY);
 | 
						pci_add_flags(PCI_PROBE_ONLY);
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1159,7 +1159,7 @@ cmds(struct pt_regs *excp)
 | 
				
			||||||
		case 'P':
 | 
							case 'P':
 | 
				
			||||||
			show_tasks();
 | 
								show_tasks();
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S
 | 
					#if defined(CONFIG_PPC_BOOK3S_32) || defined(CONFIG_PPC_64S_HASH_MMU)
 | 
				
			||||||
		case 'u':
 | 
							case 'u':
 | 
				
			||||||
			dump_segments();
 | 
								dump_segments();
 | 
				
			||||||
			break;
 | 
								break;
 | 
				
			||||||
| 
						 | 
					@ -2614,7 +2614,7 @@ static void dump_tracing(void)
 | 
				
			||||||
static void dump_one_paca(int cpu)
 | 
					static void dump_one_paca(int cpu)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct paca_struct *p;
 | 
						struct paca_struct *p;
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	int i = 0;
 | 
						int i = 0;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2656,6 +2656,7 @@ static void dump_one_paca(int cpu)
 | 
				
			||||||
	DUMP(p, cpu_start, "%#-*x");
 | 
						DUMP(p, cpu_start, "%#-*x");
 | 
				
			||||||
	DUMP(p, kexec_state, "%#-*x");
 | 
						DUMP(p, kexec_state, "%#-*x");
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_BOOK3S_64
 | 
				
			||||||
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	if (!early_radix_enabled()) {
 | 
						if (!early_radix_enabled()) {
 | 
				
			||||||
		for (i = 0; i < SLB_NUM_BOLTED; i++) {
 | 
							for (i = 0; i < SLB_NUM_BOLTED; i++) {
 | 
				
			||||||
			u64 esid, vsid;
 | 
								u64 esid, vsid;
 | 
				
			||||||
| 
						 | 
					@ -2683,6 +2684,7 @@ static void dump_one_paca(int cpu)
 | 
				
			||||||
				       22, "slb_cache", i, p->slb_cache[i]);
 | 
									       22, "slb_cache", i, p->slb_cache[i]);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	DUMP(p, rfi_flush_fallback_area, "%-*px");
 | 
						DUMP(p, rfi_flush_fallback_area, "%-*px");
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
						 | 
					@ -3746,7 +3748,7 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
 | 
				
			||||||
	printf("%s", after);
 | 
						printf("%s", after);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
void dump_segments(void)
 | 
					void dump_segments(void)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int i;
 | 
						int i;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -182,7 +182,7 @@ static const struct crashtype crashtypes[] = {
 | 
				
			||||||
	CRASHTYPE(FORTIFIED_SUBOBJECT),
 | 
						CRASHTYPE(FORTIFIED_SUBOBJECT),
 | 
				
			||||||
	CRASHTYPE(FORTIFIED_STRSCPY),
 | 
						CRASHTYPE(FORTIFIED_STRSCPY),
 | 
				
			||||||
	CRASHTYPE(DOUBLE_FAULT),
 | 
						CRASHTYPE(DOUBLE_FAULT),
 | 
				
			||||||
#ifdef CONFIG_PPC_BOOK3S_64
 | 
					#ifdef CONFIG_PPC_64S_HASH_MMU
 | 
				
			||||||
	CRASHTYPE(PPC_SLB_MULTIHIT),
 | 
						CRASHTYPE(PPC_SLB_MULTIHIT),
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue