mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 02:01:24 +01:00
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@suse.com> Reviewed-by: "Xu, Dongxiao" <dongxiao.xu@intel.com> Acked-by: Keir Fraser <keir@xen.org>
This commit is contained in:
1 parent
cadfd7bca9
commit
b99113b9d5
1 file changed
+31
-1
+31
-1
@@ -719,5 +719,35 @@ uint8_t epte_get_entry_emt(struct domain *d, unsigned long gfn, mfn_t mfn,
|
||||
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;
|
||||
}
|
||||