return rc;
}
-#define adjust_guest_l1e(pl1e, d) \
- do { \
- if ( likely(l1e_get_flags((pl1e)) & _PAGE_PRESENT) && \
- likely(!is_pv_32bit_domain(d)) ) \
- { \
- /* _PAGE_GUEST_KERNEL page cannot have the Global bit set. */ \
- if ( (l1e_get_flags((pl1e)) & (_PAGE_GUEST_KERNEL|_PAGE_GLOBAL)) \
- == (_PAGE_GUEST_KERNEL|_PAGE_GLOBAL) ) \
- gdprintk(XENLOG_WARNING, \
- "Global bit is set to kernel page %lx\n", \
- l1e_get_pfn((pl1e))); \
- if ( !(l1e_get_flags((pl1e)) & _PAGE_USER) ) \
- l1e_add_flags((pl1e), (_PAGE_GUEST_KERNEL|_PAGE_USER)); \
- if ( !(l1e_get_flags((pl1e)) & _PAGE_GUEST_KERNEL) ) \
- l1e_add_flags((pl1e), (_PAGE_GLOBAL|_PAGE_USER)); \
- } \
- } while ( 0 )
-
-#define adjust_guest_l2e(pl2e, d) \
- do { \
- if ( likely(l2e_get_flags((pl2e)) & _PAGE_PRESENT) && \
- likely(!is_pv_32bit_domain(d)) ) \
- l2e_add_flags((pl2e), _PAGE_USER); \
- } while ( 0 )
-
-#define adjust_guest_l3e(pl3e, d) \
- do { \
- if ( likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \
- l3e_add_flags((pl3e), likely(!is_pv_32bit_domain(d)) ? \
- _PAGE_USER : \
- _PAGE_USER|_PAGE_RW); \
- } while ( 0 )
-
-#define adjust_guest_l4e(pl4e, d) \
- do { \
- if ( likely(l4e_get_flags((pl4e)) & _PAGE_PRESENT) && \
- likely(!is_pv_32bit_domain(d)) ) \
- l4e_add_flags((pl4e), _PAGE_USER); \
- } while ( 0 )
-
-#define unadjust_guest_l3e(pl3e, d) \
- do { \
- if ( unlikely(is_pv_32bit_domain(d)) && \
- likely(l3e_get_flags((pl3e)) & _PAGE_PRESENT) ) \
- l3e_remove_flags((pl3e), _PAGE_USER|_PAGE_RW|_PAGE_ACCESSED); \
- } while ( 0 )
+static l1_pgentry_t adjust_guest_l1e(l1_pgentry_t l1e, const struct domain *d)
+{
+ if ( likely(l1e_get_flags(l1e) & _PAGE_PRESENT) &&
+ likely(!is_pv_32bit_domain(d)) )
+ {
+ /* _PAGE_GUEST_KERNEL page cannot have the Global bit set. */
+ if ( (l1e_get_flags(l1e) & (_PAGE_GUEST_KERNEL | _PAGE_GLOBAL)) ==
+ (_PAGE_GUEST_KERNEL | _PAGE_GLOBAL) )
+ gdprintk(XENLOG_WARNING, "Global bit is set in kernel page %lx\n",
+ l1e_get_pfn(l1e));
+
+ if ( !(l1e_get_flags(l1e) & _PAGE_USER) )
+ l1e_add_flags(l1e, (_PAGE_GUEST_KERNEL | _PAGE_USER));
+
+ if ( !(l1e_get_flags(l1e) & _PAGE_GUEST_KERNEL) )
+ l1e_add_flags(l1e, (_PAGE_GLOBAL | _PAGE_USER));
+ }
+
+ return l1e;
+}
+
+static l2_pgentry_t adjust_guest_l2e(l2_pgentry_t l2e, const struct domain *d)
+{
+ if ( likely(l2e_get_flags(l2e) & _PAGE_PRESENT) &&
+ likely(!is_pv_32bit_domain(d)) )
+ l2e_add_flags(l2e, _PAGE_USER);
+
+ return l2e;
+}
+
+static l3_pgentry_t adjust_guest_l3e(l3_pgentry_t l3e, const struct domain *d)
+{
+ if ( likely(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+ l3e_add_flags(l3e, (likely(!is_pv_32bit_domain(d))
+ ? _PAGE_USER : _PAGE_USER | _PAGE_RW));
+
+ return l3e;
+}
+
+static l3_pgentry_t unadjust_guest_l3e(l3_pgentry_t l3e, const struct domain *d)
+{
+ if ( unlikely(is_pv_32bit_domain(d)) &&
+ likely(l3e_get_flags(l3e) & _PAGE_PRESENT) )
+ l3e_remove_flags(l3e, _PAGE_USER | _PAGE_RW | _PAGE_ACCESSED);
+
+ return l3e;
+}
+
+static l4_pgentry_t adjust_guest_l4e(l4_pgentry_t l4e, const struct domain *d)
+{
+ if ( likely(l4e_get_flags(l4e) & _PAGE_PRESENT) &&
+ likely(!is_pv_32bit_domain(d)) )
+ l4e_add_flags(l4e, _PAGE_USER);
+
+ return l4e;
+}
void put_page_from_l1e(l1_pgentry_t l1e, struct domain *l1e_owner)
{
break;
}
- adjust_guest_l1e(pl1e[i], d);
+ pl1e[i] = adjust_guest_l1e(pl1e[i], d);
}
unmap_domain_page(pl1e);
break;
}
- adjust_guest_l2e(pl2e[i], d);
+ pl2e[i] = adjust_guest_l2e(pl2e[i], d);
}
if ( rc >= 0 && (type & PGT_pae_xen_l2) )
if ( rc < 0 )
break;
- adjust_guest_l3e(pl3e[i], d);
+ pl3e[i] = adjust_guest_l3e(pl3e[i], d);
}
if ( rc >= 0 && !create_pae_xen_mappings(d, pl3e) )
current->arch.old_guest_table = page;
}
while ( i-- > 0 )
- unadjust_guest_l3e(pl3e[i], d);
+ pl3e[i] = unadjust_guest_l3e(pl3e[i], d);
}
unmap_domain_page(pl3e);
return rc;
}
- adjust_guest_l4e(pl4e[i], d);
+ pl4e[i] = adjust_guest_l4e(pl4e[i], d);
}
if ( rc >= 0 )
partial = 0;
if ( rc > 0 )
continue;
- unadjust_guest_l3e(pl3e[i], d);
+ pl3e[i] = unadjust_guest_l3e(pl3e[i], d);
} while ( i-- );
unmap_domain_page(pl3e);
/* Fast path for sufficiently-similar mappings. */
if ( !l1e_has_changed(ol1e, nl1e, ~FASTPATH_FLAG_WHITELIST) )
{
- adjust_guest_l1e(nl1e, pt_dom);
+ nl1e = adjust_guest_l1e(nl1e, pt_dom);
rc = UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu,
preserve_ad);
if ( page )
if ( page )
put_page(page);
- adjust_guest_l1e(nl1e, pt_dom);
+ nl1e = adjust_guest_l1e(nl1e, pt_dom);
if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu,
preserve_ad)) )
{
/* Fast path for sufficiently-similar mappings. */
if ( !l2e_has_changed(ol2e, nl2e, ~FASTPATH_FLAG_WHITELIST) )
{
- adjust_guest_l2e(nl2e, d);
+ nl2e = adjust_guest_l2e(nl2e, d);
if ( UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu, preserve_ad) )
return 0;
return -EBUSY;
if ( unlikely((rc = get_page_from_l2e(nl2e, pfn, d)) < 0) )
return rc;
- adjust_guest_l2e(nl2e, d);
+ nl2e = adjust_guest_l2e(nl2e, d);
if ( unlikely(!UPDATE_ENTRY(l2, pl2e, ol2e, nl2e, pfn, vcpu,
preserve_ad)) )
{
/* Fast path for sufficiently-similar mappings. */
if ( !l3e_has_changed(ol3e, nl3e, ~FASTPATH_FLAG_WHITELIST) )
{
- adjust_guest_l3e(nl3e, d);
+ nl3e = adjust_guest_l3e(nl3e, d);
rc = UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, vcpu, preserve_ad);
return rc ? 0 : -EFAULT;
}
return rc;
rc = 0;
- adjust_guest_l3e(nl3e, d);
+ nl3e = adjust_guest_l3e(nl3e, d);
if ( unlikely(!UPDATE_ENTRY(l3, pl3e, ol3e, nl3e, pfn, vcpu,
preserve_ad)) )
{
/* Fast path for sufficiently-similar mappings. */
if ( !l4e_has_changed(ol4e, nl4e, ~FASTPATH_FLAG_WHITELIST) )
{
- adjust_guest_l4e(nl4e, d);
+ nl4e = adjust_guest_l4e(nl4e, d);
rc = UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, vcpu, preserve_ad);
return rc ? 0 : -EFAULT;
}
return rc;
rc = 0;
- adjust_guest_l4e(nl4e, d);
+ nl4e = adjust_guest_l4e(nl4e, d);
if ( unlikely(!UPDATE_ENTRY(l4, pl4e, ol4e, nl4e, pfn, vcpu,
preserve_ad)) )
{
if ( !IS_ALIGNED(pte_addr, sizeof(nl1e)) )
return GNTST_general_error;
- adjust_guest_l1e(nl1e, d);
+ nl1e = adjust_guest_l1e(nl1e, d);
gmfn = pte_addr >> PAGE_SHIFT;
page = get_page_from_gfn(d, gmfn, NULL, P2M_ALLOC);
struct page_info *l1pg;
int okay;
- adjust_guest_l1e(nl1e, d);
+ nl1e = adjust_guest_l1e(nl1e, d);
pl1e = guest_map_l1e(va, &gl1mfn);
if ( !pl1e )
break;
}
- adjust_guest_l1e(nl1e, d);
+ nl1e = adjust_guest_l1e(nl1e, d);
/* Checked successfully: do the update (write or cmpxchg). */
pl1e = map_domain_page(_mfn(mfn));