aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/mm/init.c
diff options
context:
space:
mode:
authorAndi Kleen <ak@linux.intel.com>2018-06-13 15:48:28 -0700
committerThomas Gleixner <tglx@linutronix.de>2018-06-20 19:10:01 +0200
commit377eeaa8e11fe815b1d07c81c4a0e2843a8c15eb (patch)
tree05848bf81eb28216c7a95870d8658d6f0151cccf /arch/x86/mm/init.c
parentx86/speculation/l1tf: Disallow non privileged high MMIO PROT_NONE mappings (diff)
downloadlinux-dev-377eeaa8e11fe815b1d07c81c4a0e2843a8c15eb.tar.xz
linux-dev-377eeaa8e11fe815b1d07c81c4a0e2843a8c15eb.zip
x86/speculation/l1tf: Limit swap file size to MAX_PA/2
For the L1TF workaround its necessary to limit the swap file size to below MAX_PA/2, so that the higher bits of the swap offset inverted never point to valid memory. Add a mechanism for the architecture to override the swap file size check in swapfile.c and add a x86 specific max swapfile check function that enforces that limit. The check is only enabled if the CPU is vulnerable to L1TF. In VMs with 42bit MAX_PA the typical limit is 2TB now, on a native system with 46bit PA it is 32TB. The limit is only per individual swap file, so it's always possible to exceed these limits with multiple swap files or partitions. Signed-off-by: Andi Kleen <ak@linux.intel.com> Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Josh Poimboeuf <jpoimboe@redhat.com> Acked-by: Michal Hocko <mhocko@suse.com> Acked-by: Dave Hansen <dave.hansen@intel.com>
Diffstat (limited to 'arch/x86/mm/init.c')
-rw-r--r--arch/x86/mm/init.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c
index cee58a972cb2..1b530197d114 100644
--- a/arch/x86/mm/init.c
+++ b/arch/x86/mm/init.c
@@ -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>
@@ -880,3 +882,16 @@ 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 */
+ pages = min_t(unsigned long, l1tf_pfn_limit() + 1, pages);
+ }
+ return pages;
+}