diff options
Diffstat (limited to 'arch/x86/mm/init.c')
| -rw-r--r-- | arch/x86/mm/init.c | 37 | 
1 files changed, 37 insertions, 0 deletions
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index 66dba36f2343..82b41d56bb98 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -27,6 +27,35 @@  #include "mm_internal.h" +/* + * Tables translating between page_cache_type_t and pte encoding. + * Minimal supported modes are defined statically, modified if more supported + * cache modes are available. + * Index into __cachemode2pte_tbl is the cachemode. + * Index into __pte2cachemode_tbl are the caching attribute bits of the pte + * (_PAGE_PWT, _PAGE_PCD, _PAGE_PAT) at index bit positions 0, 1, 2. + */ +uint16_t __cachemode2pte_tbl[_PAGE_CACHE_MODE_NUM] = { +	[_PAGE_CACHE_MODE_WB]		= 0, +	[_PAGE_CACHE_MODE_WC]		= _PAGE_PWT, +	[_PAGE_CACHE_MODE_UC_MINUS]	= _PAGE_PCD, +	[_PAGE_CACHE_MODE_UC]		= _PAGE_PCD | _PAGE_PWT, +	[_PAGE_CACHE_MODE_WT]		= _PAGE_PCD, +	[_PAGE_CACHE_MODE_WP]		= _PAGE_PCD, +}; +EXPORT_SYMBOL_GPL(__cachemode2pte_tbl); +uint8_t __pte2cachemode_tbl[8] = { +	[__pte2cm_idx(0)] = _PAGE_CACHE_MODE_WB, +	[__pte2cm_idx(_PAGE_PWT)] = _PAGE_CACHE_MODE_WC, +	[__pte2cm_idx(_PAGE_PCD)] = _PAGE_CACHE_MODE_UC_MINUS, +	[__pte2cm_idx(_PAGE_PWT | _PAGE_PCD)] = _PAGE_CACHE_MODE_UC, +	[__pte2cm_idx(_PAGE_PAT)] = _PAGE_CACHE_MODE_WB, +	[__pte2cm_idx(_PAGE_PWT | _PAGE_PAT)] = _PAGE_CACHE_MODE_WC, +	[__pte2cm_idx(_PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC_MINUS, +	[__pte2cm_idx(_PAGE_PWT | _PAGE_PCD | _PAGE_PAT)] = _PAGE_CACHE_MODE_UC, +}; +EXPORT_SYMBOL_GPL(__pte2cachemode_tbl); +  static unsigned long __initdata pgt_buf_start;  static unsigned long __initdata pgt_buf_end;  static unsigned long __initdata pgt_buf_top; @@ -687,3 +716,11 @@ void __init zone_sizes_init(void)  	free_area_init_nodes(max_zone_pfns);  } +void update_cache_mode_entry(unsigned entry, enum page_cache_mode cache) +{ +	/* entry 0 MUST be WB (hardwired to speed up translations) */ +	BUG_ON(!entry && cache != _PAGE_CACHE_MODE_WB); + +	__cachemode2pte_tbl[cache] = __cm_idx2pte(entry); +	__pte2cachemode_tbl[entry] = cache; +}  | 
