* PTE is invalid or holds a reserved entry (PTE<1:0> == x0)) or if the PTE
* maps a memory block at level 3 (PTE<1:0> == 01).
*/
- if ( !lpae_is_mapping(pte, level) )
+ if ( !lpae_is_valid(pte) || !lpae_is_mapping(pte, level) )
return -EFAULT;
/* Make sure that the lower bits of the PTE's base address are zero. */
for(; addr < addr_end; addr += PAGE_SIZE, mfn = mfn_add(mfn, 1))
{
entry = &xen_second[second_linear_offset(addr)];
- if ( !lpae_is_table(*entry, 2) )
+ if ( !lpae_is_valid(*entry) || !lpae_is_table(*entry, 2) )
{
rc = create_xen_table(entry);
if ( rc < 0 ) {
return radix_tree_ptr_to_int(ptr);
}
+/*
+ * lpae_is_* helpers don't check whether the valid bit is set in the
+ * PTE. Provide our own overlay to check the valid bit.
+ */
+static inline bool p2m_is_mapping(lpae_t pte, unsigned int level)
+{
+ return lpae_is_valid(pte) && lpae_is_mapping(pte, level);
+}
+
+static inline bool p2m_is_superpage(lpae_t pte, unsigned int level)
+{
+ return lpae_is_valid(pte) && lpae_is_superpage(pte, level);
+}
+
#define GUEST_TABLE_MAP_FAILED 0
#define GUEST_TABLE_SUPER_PAGE 1
#define GUEST_TABLE_NORMAL_PAGE 2
/* The function p2m_next_level is never called at the 3rd level */
ASSERT(level < 3);
- if ( lpae_is_mapping(*entry, level) )
+ if ( p2m_is_mapping(*entry, level) )
return GUEST_TABLE_SUPER_PAGE;
mfn = lpae_get_mfn(*entry);
return;
/* Nothing to do but updating the stats if the entry is a super-page. */
- if ( lpae_is_superpage(entry, level) )
+ if ( p2m_is_superpage(entry, level) )
{
p2m->stats.mappings[level]--;
return;
* a superpage.
*/
ASSERT(level < target);
- ASSERT(lpae_is_superpage(*entry, level));
+ ASSERT(p2m_is_superpage(*entry, level));
page = alloc_domheap_page(NULL, 0);
if ( !page )
/* We need to split the original page. */
lpae_t split_pte = *entry;
- ASSERT(lpae_is_superpage(*entry, level));
+ ASSERT(p2m_is_superpage(*entry, level));
if ( !p2m_split_superpage(p2m, &split_pte, level, target, offsets) )
{
return pte.walk.valid;
}
+/*
+ * lpae_is_* don't check the valid bit. This gives an opportunity for the
+ * callers to operate on the entry even if they are not valid. For
+ * instance to store information in advance.
+ */
static inline bool lpae_is_table(lpae_t pte, unsigned int level)
{
- return (level < 3) && lpae_is_valid(pte) && pte.walk.table;
+ return (level < 3) && pte.walk.table;
}
static inline bool lpae_is_mapping(lpae_t pte, unsigned int level)
{
- if ( !lpae_is_valid(pte) )
- return false;
- else if ( level == 3 )
+ if ( level == 3 )
return pte.walk.table;
else
return !pte.walk.table;