aboutsummaryrefslogtreecommitdiffstats
path: root/xen
diff options
context:
space:
mode:
authorTim Deegan <tim@xen.org>2012-01-19 13:09:23 +0000
committerTim Deegan <tim@xen.org>2012-01-19 13:09:23 +0000
commit2d94bc491a586d28d00575b52ea60cc08c71f7b6 (patch)
treed60ac8698f72c6d905a204e3671586f10ecaf698 /xen
parentcd00a203a562caad39fa774e414a02fbdd99333c (diff)
downloadxen-2d94bc491a586d28d00575b52ea60cc08c71f7b6.tar.gz
xen-2d94bc491a586d28d00575b52ea60cc08c71f7b6.tar.bz2
xen-2d94bc491a586d28d00575b52ea60cc08c71f7b6.zip
x86/mm: refine epte_present test
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>
Diffstat (limited to 'xen')
-rw-r--r--xen/arch/x86/mm/p2m-ept.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/xen/arch/x86/mm/p2m-ept.c b/xen/arch/x86/mm/p2m-ept.c
index f31558e45c..38903a6205 100644
--- a/xen/arch/x86/mm/p2m-ept.c
+++ b/xen/arch/x86/mm/p2m-ept.c
@@ -41,6 +41,10 @@
#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) )