int sh_remove_all_mappings(struct vcpu *v, mfn_t gmfn)
{
struct page_info *page = mfn_to_page(gmfn);
- int expected_count;
/* Dispatch table for getting per-type functions */
static const hash_callback_t callbacks[SH_type_unused] = {
;
perfc_incr(shadow_mappings);
- if ( (page->count_info & PGC_count_mask) == 0 )
+ if ( sh_check_page_has_no_refs(page) )
return 0;
/* Although this is an externally visible function, we do not know
hash_foreach(v, callback_mask, callbacks, gmfn);
/* If that didn't catch the mapping, something is very wrong */
- expected_count = (page->count_info & PGC_allocated) ? 1 : 0;
- if ( (page->count_info & PGC_count_mask) != expected_count )
+ if ( !sh_check_page_has_no_refs(page) )
{
/* Don't complain if we're in HVM and there are some extra mappings:
* The qemu helper process has an untyped mapping of this dom's RAM
{
(void) shadow_set_l1e(v, sl1e, shadow_l1e_empty(),
p2m_invalid, sl1mfn);
- if ( (mfn_to_page(target_mfn)->count_info & PGC_count_mask) == 0 )
+ if ( sh_check_page_has_no_refs(mfn_to_page(target_mfn)) )
/* This breaks us cleanly out of the FOREACH macro */
done = 1;
}
#include <xen/domain_page.h>
#include <asm/x86_emulate.h>
#include <asm/hvm/support.h>
+#include <asm/atomic.h>
#include "../mm-locks.h"
}
#endif /* (SHADOW_OPTIMIZATIONS & SHOPT_VIRTUAL_TLB) */
+static inline int sh_check_page_has_no_refs(struct page_info *page)
+{
+ unsigned long count = read_atomic(&page->count_info);
+ return ( (count & PGC_count_mask) ==
+ ((count & PGC_allocated) ? 1 : 0) );
+}
#endif /* _XEN_SHADOW_PRIVATE_H */