@@ -6357,8 +6357,44 @@ unsigned long get_upper_mfn_bound(void)
static void __init __maybe_unused build_assertions(void)
{
+ /* A bunch of static assertions to check that the XEN_MSR_PAT is valid
+ * and consistent with the _PAGE_* macros */
BUILD_BUG_ON(XEN_MSR_PAT != 0x050100070406ULL &&
"wrong XEN_MSR_PAT breaks PV guests");
+ BUILD_BUG_ON(_PAGE_WB && "Linux requires _PAGE_WB to be 0");
+#define PAT_VALUE(v) (0xFF & (XEN_MSR_PAT >> (8 * (v))))
+#define BAD_VALUE(v) ((v) < 0 || (v) > 7 || \
+ (v) == X86_MT_RESERVED_1 || (v) == X86_MT_RESERVED_2)
+#define BAD_PAT_VALUE(v) BUILD_BUG_ON(BAD_VALUE(PAT_VALUE(v)))
+ BAD_PAT_VALUE(0);
+ BAD_PAT_VALUE(1);
+ BAD_PAT_VALUE(2);
+ BAD_PAT_VALUE(3);
+ BAD_PAT_VALUE(4);
+ BAD_PAT_VALUE(5);
+ BAD_PAT_VALUE(6);
+ BAD_PAT_VALUE(7);
+#undef BAD_PAT_VALUE
+#undef BAD_VALUE
+#define PAT_SHIFT(page_value) (((page_value) & _PAGE_PAT) >> 5 | \
+ ((page_value) & (_PAGE_PCD | _PAGE_PWT)) >> 3)
+#define CHECK_PAGE_VALUE(page_value) do { \
+ /* Check that the _PAGE_* macros only use bits from PAGE_CACHE_ATTRS */ \
+ BUILD_BUG_ON(((_PAGE_##page_value) & PAGE_CACHE_ATTRS) != \
+ (_PAGE_##page_value)); \
+ /* Check that the _PAGE_* are consistent with XEN_MSR_PAT */ \
+ BUILD_BUG_ON(PAT_VALUE(PAT_SHIFT(_PAGE_##page_value)) != \
+ (X86_MT_##page_value)); \
+} while (0)
+ CHECK_PAGE_VALUE(WT);
+ CHECK_PAGE_VALUE(WB);
+ CHECK_PAGE_VALUE(WC);
+ CHECK_PAGE_VALUE(UC);
+ CHECK_PAGE_VALUE(UCM);
+ CHECK_PAGE_VALUE(WP);
+#undef CHECK_PAGE_VALUE
+#undef PAT_SHIFT
+#undef PAT_VALUE
}
/*
It may be desirable to change Xen's PAT for various reasons. This requires changes to several _PAGE_* macros as well. Add static assertions to check that XEN_MSR_PAT is consistent with the _PAGE_* macros, and that _PAGE_WB is 0 as required by Linux. Signed-off-by: Demi Marie Obenour <demi@invisiblethingslab.com> --- xen/arch/x86/mm.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)