@@ -799,6 +799,18 @@ that enabling this option cannot guarantee anything beyond what underlying
hardware guarantees (with, where available and known to Xen, respective
tweaks applied).
+### directmap (x86)
+> `= <boolean>`
+
+> Default: `true`
+
+Enable or disable the directmap region in Xen.
+
+By default, Xen creates the directmap region which maps physical memory
+in that region. Setting this to no will sparsely populate the directmap,
+blocking exploits that leak secrets via speculative memory access in the
+directmap.
+
### dma_bits
> `= <integer>`
@@ -28,6 +28,7 @@ config X86
select HAS_PCI_MSI
select HAS_PIRQ
select HAS_SCHED_GRANULARITY
+ select HAS_SECRET_HIDING
select HAS_UBSAN
select HAS_VPCI if HVM
select NEEDS_LIBELF
@@ -622,11 +622,17 @@ void write_32bit_pse_identmap(uint32_t *l2);
/*
* x86 maps part of physical memory via the directmap region.
* Return whether the range of MFN falls in the directmap region.
+ *
+ * When boot command line sets directmap=no, the directmap will mostly be empty
+ * so this will always return false.
*/
static inline bool arch_mfns_in_directmap(unsigned long mfn, unsigned long nr)
{
unsigned long eva = min(DIRECTMAP_VIRT_END, HYPERVISOR_VIRT_END);
+ if ( !has_directmap() )
+ return false;
+
return (mfn + nr) <= (virt_to_mfn(eva - 1) + 1);
}
@@ -1517,6 +1517,8 @@ void asmlinkage __init noreturn __start_xen(unsigned long mbi_p)
if ( highmem_start )
xenheap_max_mfn(PFN_DOWN(highmem_start - 1));
+ printk("Booting with directmap %s\n", has_directmap() ? "on" : "off");
+
/*
* Walk every RAM region and map it in its entirety (on x86/64, at least)
* and notify it to the boot allocator.
@@ -80,12 +80,29 @@ config HAS_PMAP
config HAS_SCHED_GRANULARITY
bool
+config HAS_SECRET_HIDING
+ bool
+
config HAS_UBSAN
bool
config MEM_ACCESS_ALWAYS_ON
bool
+config SECRET_HIDING
+ bool "Secret hiding"
+ depends on HAS_SECRET_HIDING
+ help
+ The directmap contains mapping for most of the RAM which makes domain
+ memory easily accessible. While making the performance better, it also makes
+ the hypervisor more vulnerable to speculation attacks.
+
+ Enabling this feature will allow the user to decide whether the memory
+ is always mapped at boot or mapped only on demand (see the command line
+ option "directmap").
+
+ If unsure, say N.
+
config MEM_ACCESS
def_bool MEM_ACCESS_ALWAYS_ON
prompt "Memory Access and VM events" if !MEM_ACCESS_ALWAYS_ON
@@ -174,6 +174,11 @@ paddr_t __ro_after_init mem_hotplug;
static char __initdata opt_badpage[100] = "";
string_param("badpage", opt_badpage);
+bool __ro_after_init opt_directmap = true;
+#ifdef CONFIG_HAS_SECRET_HIDING
+boolean_param("directmap", opt_directmap);
+#endif
+
/*
* no-bootscrub -> Free pages are not zeroed during boot.
*/
@@ -167,6 +167,13 @@ extern unsigned long max_page;
extern unsigned long total_pages;
extern paddr_t mem_hotplug;
+extern bool opt_directmap;
+
+static inline bool has_directmap(void)
+{
+ return opt_directmap;
+}
+
/*
* Extra fault info types which are used to further describe
* the source of an access violation.