x86/mm: refine epte_present test
authorTim Deegan <tim@xen.org>
Thu, 19 Jan 2012 13:09:23 +0000 (13:09 +0000)
committerTim Deegan <tim@xen.org>
Thu, 19 Jan 2012 13:09:23 +0000 (13:09 +0000)
The current test for a present ept entry checks for a permission bit
to be set.

While this is valid in contexts in which we want to know whether an entry
will fault, it is not correct when it comes to testing whether an entry is
valid. Specifically, in the ept_change_entry_type_page function which is
used to set entries to the log dirty type.

In combination with a p2m access type like n or n2rwx, log dirty will not be
set for ept entries for which it should.

Reported-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
Signed-off-by: Tim Deegan <tim@xen.org>
Acked-by: Andres Lagar-Cavilla <andres@lagarcavilla.org>
Committed-by: Tim Deegan <tim@xen.org>
xen/arch/x86/mm/p2m-ept.c

index f31558e45c9023c5534f233efc11e3462c922245..38903a62055828992ab5343ee12eb251ebb8798e 100644 (file)
 
 #define is_epte_present(ept_entry)      ((ept_entry)->epte & 0x7)
 #define is_epte_superpage(ept_entry)    ((ept_entry)->sp)
+static inline bool_t is_epte_valid(ept_entry_t *e)
+{
+    return (e->epte != 0 && e->sa_p2mt != p2m_invalid);
+}
 
 /* Non-ept "lock-and-check" wrapper */
 static int ept_pod_check_and_populate(struct p2m_domain *p2m, unsigned long gfn,
@@ -777,7 +781,7 @@ static void ept_change_entry_type_page(mfn_t ept_page_mfn, int ept_page_level,
 
     for ( int i = 0; i < EPT_PAGETABLE_ENTRIES; i++ )
     {
-        if ( !is_epte_present(epte + i) )
+        if ( !is_epte_valid(epte + i) )
             continue;
 
         if ( (ept_page_level > 0) && !is_epte_superpage(epte + i) )