[PATCH 2/4] x86: extend mod_l1_entry() to optionally return the old PTE value
Kevin Lampis <[email protected]>
| Newsgroups | org.xenproject.lists.xen-devel |
|---|---|
| Message-ID | <[email protected]> |
Calling mod_l1_entry() with a valid ol1e_out pointer will do an atomic xchg to set the new pte value and return the old pte value through the ol1e_out pointer. If the ol1e_out pointer is NULL then old behavior is preserved. Signed-off-by: Kevin Lampis <[email protected]> --- xen/arch/x86/mm.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-) diff --git a/xen/arch/x86/mm.c b/xen/arch/x86/mm.c index bb4ba0afe2d4..500549c8e036 100644 --- a/xen/arch/x86/mm.c +++ b/xen/arch/x86/mm.c @@ -2151,7 +2151,8 @@ static void l3t_unlock(struct page_info *page) /* Update the L1 entry at pl1e to new value nl1e. */ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e, mfn_t gl1mfn, unsigned int cmd, - struct vcpu *pt_vcpu, struct domain *pg_dom) + struct vcpu *pt_vcpu, struct domain *pg_dom, + l1_pgentry_t *ol1e_out) { bool preserve_ad = (cmd == MMU_PT_UPDATE_PRESERVE_AD); l1_pgentry_t ol1e = l1e_read(pl1e); @@ -2213,8 +2214,8 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e, /* Fast path for sufficiently-similar mappings. */ if ( !l1e_has_changed(ol1e, nl1e, ~FASTPATH_FLAG_WHITELIST) ) { - rc = UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, - preserve_ad); + rc = update_intpte(&pl1e->l1, &ol1e.l1, nl1e.l1, gl1mfn, pt_vcpu, + preserve_ad, !!ol1e_out); if ( page ) put_page(page); return rc ? 0 : -EBUSY; @@ -2237,8 +2238,8 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e, if ( page ) put_page(page); - if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, - preserve_ad)) ) + if ( unlikely(!update_intpte(&pl1e->l1, &ol1e.l1, nl1e.l1, gl1mfn, + pt_vcpu, preserve_ad, !!ol1e_out)) ) { ol1e = nl1e; rc = -EBUSY; @@ -2246,13 +2247,17 @@ static int mod_l1_entry(l1_pgentry_t *pl1e, l1_pgentry_t nl1e, } else if ( pv_l1tf_check_l1e(pt_dom, nl1e) ) return -ERESTART; - else if ( unlikely(!UPDATE_ENTRY(l1, pl1e, ol1e, nl1e, gl1mfn, pt_vcpu, - preserve_ad)) ) + else if ( unlikely(!update_intpte(&pl1e->l1, &ol1e.l1, nl1e.l1, gl1mfn, + pt_vcpu, preserve_ad, !!ol1e_out)) ) { return -EBUSY; } put_page_from_l1e(ol1e, pt_dom); + + if ( !rc && ol1e_out ) + *ol1e_out = ol1e; + return rc; } @@ -4140,7 +4145,7 @@ long do_mmu_update( { case PGT_l1_page_table: rc = mod_l1_entry(va, l1e_from_intpte(req.val), mfn, - cmd, v, pg_owner); + cmd, v, pg_owner, NULL); break; case PGT_l2_page_table: @@ -4505,7 +4510,8 @@ static int __do_update_va_mapping( goto out; } - rc = mod_l1_entry(pl1e, val, gl1mfn, MMU_NORMAL_PT_UPDATE, v, pg_owner); + rc = mod_l1_entry(pl1e, val, gl1mfn, MMU_NORMAL_PT_UPDATE, v, pg_owner, + NULL); page_unlock(gl1pg); put_page(gl1pg); -- 2.52.0