|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH 2/5] x86/HVM: fix memory type merging in epte_get_entry_emt()
Using the minimum numeric value of guest and host specified memory
types is too simplistic - it works only correctly for a subset of
types. It is in particular the WT/WP combination that needs conversion
to UC if the two types conflict.
Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
--- a/xen/arch/x86/hvm/mtrr.c
+++ b/xen/arch/x86/hvm/mtrr.c
@@ -719,5 +719,35 @@ uint8_t epte_get_entry_emt(struct domain
MTRR_TYPE_WRBACK;
hmtrr_mtype = get_mtrr_type(&mtrr_state, (mfn_x(mfn) << PAGE_SHIFT));
- return ((gmtrr_mtype <= hmtrr_mtype) ? gmtrr_mtype : hmtrr_mtype);
+
+ /* If both types match we're fine. */
+ if ( likely(gmtrr_mtype == hmtrr_mtype) )
+ return hmtrr_mtype;
+
+ /* If either type is UC, we have to go with that one. */
+ if ( gmtrr_mtype == MTRR_TYPE_UNCACHABLE ||
+ hmtrr_mtype == MTRR_TYPE_UNCACHABLE )
+ return MTRR_TYPE_UNCACHABLE;
+
+ /* If either type is WB, we have to go with the other one. */
+ if ( gmtrr_mtype == MTRR_TYPE_WRBACK )
+ return hmtrr_mtype;
+ if ( hmtrr_mtype == MTRR_TYPE_WRBACK )
+ return gmtrr_mtype;
+
+ /*
+ * At this point we have disagreeing WC, WT, or WP types. The only
+ * combination that can be cleanly resolved is WT:WP. The ones involving
+ * WC need to be converted to UC, both due to the memory ordering
+ * differences and because WC disallows reads to be cached (WT and WP
+ * permit this), while WT and WP require writes to go straight to memory
+ * (WC can buffer them).
+ */
+ if ( (gmtrr_mtype == MTRR_TYPE_WRTHROUGH &&
+ hmtrr_mtype == MTRR_TYPE_WRPROT) ||
+ (gmtrr_mtype == MTRR_TYPE_WRPROT &&
+ hmtrr_mtype == MTRR_TYPE_WRTHROUGH) )
+ return MTRR_TYPE_WRPROT;
+
+ return MTRR_TYPE_UNCACHABLE;
}
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
http://lists.xen.org/xen-devel
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |