* GUEST_TABLE_SUPER_PAGE: The next entry points to a superpage.
*/
static int p2m_next_level(struct p2m_domain *p2m, bool read_only,
- lpae_t **table, unsigned int offset)
+ unsigned int level, lpae_t **table,
+ unsigned int offset)
{
lpae_t *entry;
int ret;
}
/* The function p2m_next_level is never called at the 3rd level */
- if ( lpae_mapping(*entry) )
+ ASSERT(level < 3);
+ if ( lpae_is_mapping(*entry, level) )
return GUEST_TABLE_SUPER_PAGE;
mfn = _mfn(entry->p2m.base);
for ( level = P2M_ROOT_LEVEL; level < 3; level++ )
{
- rc = p2m_next_level(p2m, true, &table, offsets[level]);
+ rc = p2m_next_level(p2m, true, level, &table, offsets[level]);
if ( rc == GUEST_TABLE_MAP_FAILED )
goto out_unmap;
else if ( rc != GUEST_TABLE_NORMAL_PAGE )
* is about to be removed (i.e mfn == INVALID_MFN).
*/
rc = p2m_next_level(p2m, mfn_eq(smfn, INVALID_MFN),
- &table, offsets[level]);
+ level, &table, offsets[level]);
if ( rc == GUEST_TABLE_MAP_FAILED )
{
/*
/* then move to the level we want to make real changes */
for ( ; level < target; level++ )
{
- rc = p2m_next_level(p2m, true, &table, offsets[level]);
+ rc = p2m_next_level(p2m, true, level, &table, offsets[level]);
/*
* The entry should be found and either be a table
}
/*
- * These two can only be used on L0..L2 ptes because L3 mappings set
+ * This one can only be used on L0..L2 ptes because L3 mappings set
* the table bit and therefore these would return the opposite to what
* you would expect.
*/
return lpae_valid(pte) && pte.walk.table;
}
-static inline bool lpae_mapping(lpae_t pte)
+static inline bool lpae_is_mapping(lpae_t pte, unsigned int level)
{
- return lpae_valid(pte) && !pte.walk.table;
+ if ( !lpae_valid(pte) )
+ return false;
+ else if ( level == 3 )
+ return pte.walk.table;
+ else
+ return !pte.walk.table;
}
static inline bool lpae_is_superpage(lpae_t pte, unsigned int level)
{
- return (level < 3) && lpae_mapping(pte);
+ return (level < 3) && lpae_is_mapping(pte, level);
}
static inline bool lpae_is_page(lpae_t pte, unsigned int level)