[PATCH 1/4] x86: extend update_intpte() to support atomic get-and-update
Kevin Lampis <[email protected]>
| Newsgroups | org.xenproject.lists.xen-devel |
|---|---|
| Message-ID | <[email protected]> |
The update_intpte() function now accepts a new use_cmpxchg flag and if set returns the old pte value through the new *old pointer. No functional change for existing callers. Signed-off-by: Kevin Lampis <[email protected]> --- xen/arch/x86/pv/mm.h | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/pv/mm.h b/xen/arch/x86/pv/mm.h index 4564cab9fc0f..8c42cf3b3f4d 100644 --- a/xen/arch/x86/pv/mm.h +++ b/xen/arch/x86/pv/mm.h @@ -66,13 +66,14 @@ static inline intpte_t paging_cmpxchg_guest_entry( * How to write an entry to the guest pagetables. * Returns false for failure (pointer not valid), true for success. */ -static inline bool update_intpte(intpte_t *p, intpte_t old, intpte_t new, - mfn_t mfn, struct vcpu *v, bool preserve_ad) +static inline bool update_intpte(intpte_t *p, intpte_t *old, intpte_t new, + mfn_t mfn, struct vcpu *v, bool preserve_ad, + bool use_cmpxchg) { bool rv = true; #ifndef PTE_UPDATE_WITH_CMPXCHG - if ( !preserve_ad ) + if ( !preserve_ad && !use_cmpxchg ) paging_write_guest_entry(v, p, new, mfn); else #endif @@ -82,30 +83,36 @@ static inline bool update_intpte(intpte_t *p, intpte_t old, intpte_t new, intpte_t _new = new, t; if ( preserve_ad ) - _new |= old & (_PAGE_ACCESSED | _PAGE_DIRTY); + _new |= *old & (_PAGE_ACCESSED | _PAGE_DIRTY); - t = paging_cmpxchg_guest_entry(v, p, old, _new, mfn); + t = paging_cmpxchg_guest_entry(v, p, *old, _new, mfn); - if ( t == old ) + if ( t == *old ) break; /* Allowed to change in Accessed/Dirty flags only. */ - BUG_ON((t ^ old) & ~(intpte_t)(_PAGE_ACCESSED|_PAGE_DIRTY)); + BUG_ON((t ^ *old) & ~(intpte_t)(_PAGE_ACCESSED|_PAGE_DIRTY)); - old = t; + *old = t; } } return rv; } +static inline bool _update_intpte(intpte_t *p, intpte_t old, intpte_t new, + mfn_t mfn, struct vcpu *v, bool preserve_ad) +{ + return update_intpte(p, &old, new, mfn, v, preserve_ad, false); +} + /* * Macro that wraps the appropriate type-changes around update_intpte(). * Arguments are: type, ptr, old, new, mfn, vcpu */ #define UPDATE_ENTRY(_t,_p,_o,_n,_m,_v,_ad) \ - update_intpte(&_t ## e_get_intpte(*(_p)), \ - _t ## e_get_intpte(_o), _t ## e_get_intpte(_n), \ - (_m), (_v), (_ad)) + _update_intpte(&_t ## e_get_intpte(*(_p)), \ + _t ## e_get_intpte(_o), _t ## e_get_intpte(_n), \ + (_m), (_v), (_ad)) static always_inline l1_pgentry_t adjust_guest_l1e(l1_pgentry_t l1e, const struct domain *d) -- 2.52.0