Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel...
[cascardo/linux.git] / arch / x86 / mm / init.c
index 07244aa..a97ee08 100644 (file)
 
 #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;
+}