[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 7/8] x86/mm: make code robust to future PAT changes
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. Additionally, Xen has two unused entries in the PAT. Currently these are UC, but this will change if the hardware ever supports additional memory types. To avoid future problems, this adds a check in debug builds that injects #GP into a guest that tries to use one of these entries, along with returning -EINVAL from the hypercall. Future versions of Xen will refuse to use these entries even in release builds. Signed-off-by: Demi Marie Obenour <demi@xxxxxxxxxxxxxxxxxxxxxx> --- xen/arch/x86/mm.c | 58 +++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 54 insertions(+), 4 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index 5d05399c3a841bf03991a3bed63df9a815c1e891..517fccee699b2a673ba537e47933aefc80017aa5 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -849,6 +849,45 @@ static int cf_check print_mmio_emul_range( } #endif +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 */ +#define PAT_VALUE(v) (0xFF & (XEN_MSR_PAT >> (8 * (v)))) +#define BAD_VALUE(v) ((v) < 0 || (v) > 7 || \ + (v) == MSR_PAT_RESERVED_1 || (v) == MSR_PAT_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)) != \ + (MSR_PAT_##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 +} + /* * get_page_from_l1e returns: * 0 => success (page not present also counts as such) @@ -961,13 +1000,24 @@ get_page_from_l1e( switch ( l1f & PAGE_CACHE_ATTRS ) { - case _PAGE_WB: + default: +#ifndef NDEBUG + printk(XENLOG_G_WARNING + "d%d: Guest tried to use bad cachability attribute %u for MFN %lx\n", + l1e_owner->domain_id, l1f & PAGE_CACHE_ATTRS, mfn); + pv_inject_hw_exception(TRAP_gp_fault, 0); + return -EINVAL; +#endif case _PAGE_WT: case _PAGE_WP: - flip |= (l1f & PAGE_CACHE_ATTRS) ^ _PAGE_UC; + case _PAGE_WB: + /* Force this to be uncachable */ + return flip | ( (l1f & PAGE_CACHE_ATTRS) ^ _PAGE_UC ); + case _PAGE_WC: + case _PAGE_UC: + case _PAGE_UCM: + return flip; } - - return flip; } if ( unlikely((real_pg_owner != pg_owner) && -- Sincerely, Demi Marie Obenour (she/her/hers) Invisible Things Lab
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |