]> git.ipfire.org Git - thirdparty/kernel/linux.git/blobdiff - arch/x86/mm/init.c
x86/speculation/l1tf: Extend 64bit swap file size limit
[thirdparty/kernel/linux.git] / arch / x86 / mm / init.c
index fec82b577c183f516b4c3c416d94127f9ccd26ad..c0870df32b2d362465938bc7b774bea4c3c1faa9 100644 (file)
@@ -4,6 +4,8 @@
 #include <linux/swap.h>
 #include <linux/memblock.h>
 #include <linux/bootmem.h>     /* for max_low_pfn */
+#include <linux/swapfile.h>
+#include <linux/swapops.h>
 
 #include <asm/set_memory.h>
 #include <asm/e820/api.h>
@@ -706,7 +708,9 @@ void __init init_mem_mapping(void)
  */
 int devmem_is_allowed(unsigned long pagenr)
 {
-       if (page_is_ram(pagenr)) {
+       if (region_intersects(PFN_PHYS(pagenr), PAGE_SIZE,
+                               IORESOURCE_SYSTEM_RAM, IORES_DESC_NONE)
+                       != REGION_DISJOINT) {
                /*
                 * For disallowed memory regions in the low 1MB range,
                 * request that the page be shown as all zeros.
@@ -878,3 +882,24 @@ void update_cache_mode_entry(unsigned entry, enum page_cache_mode cache)
        __cachemode2pte_tbl[cache] = __cm_idx2pte(entry);
        __pte2cachemode_tbl[entry] = cache;
 }
+
+unsigned long max_swapfile_size(void)
+{
+       unsigned long pages;
+
+       pages = generic_max_swapfile_size();
+
+       if (boot_cpu_has_bug(X86_BUG_L1TF)) {
+               /* Limit the swap file size to MAX_PA/2 for L1TF workaround */
+               unsigned long l1tf_limit = l1tf_pfn_limit() + 1;
+               /*
+                * We encode swap offsets also with 3 bits below those for pfn
+                * which makes the usable limit higher.
+                */
+#ifdef CONFIG_X86_64
+               l1tf_limit <<= PAGE_SHIFT - SWP_OFFSET_FIRST_BIT;
+#endif
+               pages = min_t(unsigned long, l1tf_limit, pages);
+       }
+       return pages;
+}