certain you don't plan on having PV guests which use this feature,
turning it off can reduce the attack surface.
+### pv-l1tf (x86)
+> `= List of [ <bool>, dom0=<bool>, domu=<bool> ]`
+
+> Default: `false` on believed-unaffected hardware.
+> `domu` on believed-affected hardware.
+
+Mitigations for L1TF / XSA-273 / CVE-2018-3620 for PV guests.
+
+For backwards compatibility, we may not alter an architecturally-legitimate
+pagetable entry a PV guest chooses to write. We can however force such a
+guest into shadow mode so that Xen controls the PTEs which are reachable by
+the CPU pagewalk.
+
+Shadowing is performed at the point where a PV guest first tries to write an
+L1TF-vulnerable PTE. Therefore, a PV guest kernel which has been updated with
+its own L1TF mitigations will not trigger shadow mode if it is well behaved.
+
+If CONFIG\_SHADOW\_PAGING is not compiled in, this mitigation instead crashes
+the guest when an L1TF-vulnerable PTE is written, which still allows updated,
+well-behaved PV guests to run, despite Shadow being compiled out.
+
### reboot
> `= t[riple] | k[bd] | a[cpi] | p[ci] | P[ower] | e[fi] | n[o] [, [w]arm | [c]old]`
}
custom_param("spec-ctrl", parse_spec_ctrl);
+int8_t __read_mostly opt_pv_l1tf = -1;
+
+static __init int parse_pv_l1tf(char *s)
+{
+ char *ss;
+ int val, rc = 0;
+
+ /* Inhibit the defaults as an explicit choice has been given. */
+ if ( opt_pv_l1tf == -1 )
+ opt_pv_l1tf = 0;
+
+ /* Interpret 'pv-l1tf' alone in its positive boolean form. */
+ if ( *s == '\0' )
+ opt_xpti = OPT_PV_L1TF_DOM0 | OPT_PV_L1TF_DOMU;
+
+ do {
+ ss = strchr(s, ',');
+ if ( ss )
+ *ss = '\0';
+
+ switch ( parse_bool(s) )
+ {
+ case 0:
+ opt_pv_l1tf = 0;
+ break;
+
+ case 1:
+ opt_pv_l1tf = OPT_PV_L1TF_DOM0 | OPT_PV_L1TF_DOMU;
+ break;
+
+ default:
+ if ( (val = parse_boolean("dom0", s, ss)) >= 0 )
+ opt_pv_l1tf = ((opt_pv_l1tf & ~OPT_PV_L1TF_DOM0) |
+ (val ? OPT_PV_L1TF_DOM0 : 0));
+ else if ( (val = parse_boolean("domu", s, ss)) >= 0 )
+ opt_pv_l1tf = ((opt_pv_l1tf & ~OPT_PV_L1TF_DOMU) |
+ (val ? OPT_PV_L1TF_DOMU : 0));
+ else
+ rc = -EINVAL;
+ break;
+ }
+
+ s = ss + 1;
+ } while ( ss );
+
+ return rc;
+}
+custom_param("pv-l1tf", parse_pv_l1tf);
+
static void __init print_details(enum ind_thunk thunk, uint64_t caps)
{
unsigned int _7d0 = 0, e8b = 0, tmp;
(caps & ARCH_CAPS_RSBA) ? " RSBA" : "",
(caps & ARCH_CAPS_SSB_NO) ? " SSB_NO" : "");
- /* Compiled-in support which pertains to BTI mitigations. */
+#if defined(CONFIG_INDIRECT_THUNK) || defined(CONFIG_SHADOW_PAGING)
+ /* Compiled-in support which pertains to mitigations. */
+ printk(" Compiled-in support:"
#ifdef CONFIG_INDIRECT_THUNK
- printk(XENLOG_DEBUG " Compiled-in support: INDIRECT_THUNK\n");
+ " INDIRECT_THUNK"
+#endif
+#ifdef CONFIG_SHADOW_PAGING
+ " SHADOW_PAGING"
+#endif
+ "\n");
#endif
/* Settings for Xen's protection, irrespective of guests. */
(default_xen_spec_ctrl & SPEC_CTRL_SSBD) ? " SSBD+" : " SSBD-",
opt_ibpb ? " IBPB" : "");
+ /* L1TF diagnostics, printed if vulnerable or PV shadowing is in use. */
+ if ( cpu_has_bug_l1tf || opt_pv_l1tf )
+ printk(" L1TF: believed%s vulnerable, maxphysaddr L1D %u, CPUID %u"
+ ", Safe address %"PRIx64"\n",
+ cpu_has_bug_l1tf ? "" : " not",
+ l1d_maxphysaddr, paddr_bits, l1tf_safe_maddr);
+
/*
* Alternatives blocks for protecting against and/or virtualising
* mitigation support for guests.
printk(" XPTI (64-bit PV only): Dom0 %s, DomU %s\n",
opt_xpti & OPT_XPTI_DOM0 ? "enabled" : "disabled",
opt_xpti & OPT_XPTI_DOMU ? "enabled" : "disabled");
+
+ printk(" PV L1TF shadowing: Dom0 %s, DomU %s\n",
+ opt_pv_l1tf & OPT_PV_L1TF_DOM0 ? "enabled" : "disabled",
+ opt_pv_l1tf & OPT_PV_L1TF_DOMU ? "enabled" : "disabled");
}
/* Calculate whether Retpoline is known-safe on this CPU. */
l1tf_calculations(caps);
+ /*
+ * By default, enable PV domU L1TF mitigations on all L1TF-vulnerable
+ * hardware.
+ */
+ if ( opt_pv_l1tf == -1 )
+ {
+ if ( !cpu_has_bug_l1tf )
+ opt_pv_l1tf = 0;
+ else
+ opt_pv_l1tf = OPT_PV_L1TF_DOMU;
+ }
+
print_details(thunk, caps);
/*