arch/powerpc/include/asm/book3s/64/hash-64k.h

Source file repositories/reference/linux-study-clean/arch/powerpc/include/asm/book3s/64/hash-64k.h

File Facts

System
Linux kernel
Corpus path
arch/powerpc/include/asm/book3s/64/hash-64k.h
Extension
.h
Size
10129 bytes
Lines
287
Domain
Architecture Layer
Bucket
arch/powerpc
Inferred role
Architecture Layer: implementation source
Status
source implementation candidate

Why This File Exists

CPU and platform-specific kernel glue: boot entry, traps, syscall entry, interrupts, page tables, context switch, and low-level barriers.

Dependency Surface

Detected Declarations

Annotated Snippet

#ifndef _ASM_POWERPC_BOOK3S_64_HASH_64K_H
#define _ASM_POWERPC_BOOK3S_64_HASH_64K_H

#define H_PTE_INDEX_SIZE   8  // size: 8B <<  8 = 2KB, maps 2^8  x 64KB = 16MB
#define H_PMD_INDEX_SIZE  10  // size: 8B << 10 = 8KB, maps 2^10 x 16MB = 16GB
#define H_PUD_INDEX_SIZE  10  // size: 8B << 10 = 8KB, maps 2^10 x 16GB = 16TB
#define H_PGD_INDEX_SIZE   8  // size: 8B <<  8 = 2KB, maps 2^8  x 16TB =  4PB

/*
 * If we store section details in page->flags we can't increase the MAX_PHYSMEM_BITS
 * if we increase SECTIONS_WIDTH we will not store node details in page->flags and
 * page_to_nid does a page->section->node lookup
 * Hence only increase for VMEMMAP. Further depending on SPARSEMEM_EXTREME reduce
 * memory requirements with large number of sections.
 * 51 bits is the max physical real address on POWER9
 */
#if defined(CONFIG_SPARSEMEM_VMEMMAP) && defined(CONFIG_SPARSEMEM_EXTREME)
#define H_MAX_PHYSMEM_BITS	51
#else
#define H_MAX_PHYSMEM_BITS	46
#endif

/*
 * Each context is 512TB size. SLB miss for first context/default context
 * is handled in the hotpath.
 */
#define MAX_EA_BITS_PER_CONTEXT		49
#define REGION_SHIFT		MAX_EA_BITS_PER_CONTEXT

/*
 * We use one context for each MAP area.
 */
#define H_KERN_MAP_SIZE		(1UL << MAX_EA_BITS_PER_CONTEXT)

/*
 * Define the address range of the kernel non-linear virtual area
 * 2PB
 */
#define H_KERN_VIRT_START	ASM_CONST(0xc008000000000000)

/*
 * 64k aligned address free up few of the lower bits of RPN for us
 * We steal that here. For more deatils look at pte_pfn/pfn_pte()
 */
#define H_PAGE_COMBO	_RPAGE_RPN0 /* this is a combo 4k page */
#define H_PAGE_4K_PFN	_RPAGE_RPN1 /* PFN is for a single 4k page */
#define H_PAGE_BUSY	_RPAGE_RSV1     /* software: PTE & hash are busy */
#define H_PAGE_HASHPTE	_RPAGE_RPN43	/* PTE has associated HPTE */

/* memory key bits. */
#define H_PTE_PKEY_BIT4		_RPAGE_PKEY_BIT4
#define H_PTE_PKEY_BIT3		_RPAGE_PKEY_BIT3
#define H_PTE_PKEY_BIT2		_RPAGE_PKEY_BIT2
#define H_PTE_PKEY_BIT1		_RPAGE_PKEY_BIT1
#define H_PTE_PKEY_BIT0		_RPAGE_PKEY_BIT0

/*
 * We need to differentiate between explicit huge page and THP huge
 * page, since THP huge page also need to track real subpage details
 */
#define H_PAGE_THP_HUGE  H_PAGE_4K_PFN

/* PTE flags to conserve for HPTE identification */
#define _PAGE_HPTEFLAGS (H_PAGE_BUSY | H_PAGE_HASHPTE | H_PAGE_COMBO)
/*
 * We use a 2K PTE page fragment and another 2K for storing
 * real_pte_t hash index
 * 8 bytes per each pte entry and another 8 bytes for storing
 * slot details.
 */
#define H_PTE_FRAG_SIZE_SHIFT  (H_PTE_INDEX_SIZE + 3 + 1)
#define H_PTE_FRAG_NR	(PAGE_SIZE >> H_PTE_FRAG_SIZE_SHIFT)

#if defined(CONFIG_TRANSPARENT_HUGEPAGE) || defined(CONFIG_HUGETLB_PAGE)
#define H_PMD_FRAG_SIZE_SHIFT  (H_PMD_INDEX_SIZE + 3 + 1)
#else
#define H_PMD_FRAG_SIZE_SHIFT  (H_PMD_INDEX_SIZE + 3)
#endif
#define H_PMD_FRAG_NR	(PAGE_SIZE >> H_PMD_FRAG_SIZE_SHIFT)

#ifndef __ASSEMBLER__
#include <asm/errno.h>

/*
 * With 64K pages on hash table, we have a special PTE format that
 * uses a second "half" of the page table to encode sub-page information
 * in order to deal with 64K made of 4K HW pages. Thus we override the
 * generic accessors and iterators here
 */
#define __real_pte __real_pte

Annotation

Implementation Notes