}
}
-/**************************************************************************/
-
-/* Reset the up-pointers of every L3 shadow to 0.
- * This is called when l3 shadows stop being pinnable, to clear out all
- * the list-head bits so the up-pointer field is properly inititalised. */
-static int cf_check sh_clear_up_pointer(
- struct vcpu *v, mfn_t smfn, mfn_t unused)
-{
- mfn_to_page(smfn)->up = 0;
- return 0;
-}
-
-void sh_reset_l3_up_pointers(struct vcpu *v)
-{
- static const hash_vcpu_callback_t callbacks[SH_type_unused] = {
- [SH_type_l3_64_shadow] = sh_clear_up_pointer,
- };
-
- HASH_CALLBACKS_CHECK(SHF_L3_64);
- hash_vcpu_foreach(v, SHF_L3_64, callbacks, INVALID_MFN);
-}
-
-
/**************************************************************************/
static void sh_update_paging_modes(struct vcpu *v)
*/
int sh_remove_all_mappings(struct domain *d, mfn_t gmfn, gfn_t gfn);
-/* Reset the up-pointers of every L3 shadow to 0.
- * This is called when l3 shadows stop being pinnable, to clear out all
- * the list-head bits so the up-pointer field is properly inititalised. */
-void sh_reset_l3_up_pointers(struct vcpu *v);
-
/******************************************************************************
* Flags used in the return value of the shadow_set_lXe() functions...
*/
{
struct page_list_head tmp_list, *pin_list;
struct page_info *sp, *next;
- unsigned int i, head_type;
+ unsigned int i, head_type, sz;
ASSERT(mfn_valid(smfn));
sp = mfn_to_page(smfn);
return;
sp->u.sh.pinned = 0;
- /* Cut the sub-list out of the list of pinned shadows,
- * stitching it back into a list fragment of its own. */
+ sz = shadow_size(head_type);
+
+ /*
+ * Cut the sub-list out of the list of pinned shadows, stitching
+ * multi-page shadows back into a list fragment of their own.
+ */
pin_list = &d->arch.paging.shadow.pinned_shadows;
INIT_PAGE_LIST_HEAD(&tmp_list);
- for ( i = 0; i < shadow_size(head_type); i++ )
+ for ( i = 0; i < sz; i++ )
{
ASSERT(sp->u.sh.type == head_type);
ASSERT(!i || !sp->u.sh.head);
next = page_list_next(sp, pin_list);
page_list_del(sp, pin_list);
- page_list_add_tail(sp, &tmp_list);
+ if ( sz > 1 )
+ page_list_add_tail(sp, &tmp_list);
+ else if ( head_type == SH_type_l3_64_shadow )
+ sp->up = 0;
sp = next;
}
- sh_terminate_list(&tmp_list);
+
+ if ( sz > 1 )
+ sh_terminate_list(&tmp_list);
sh_put_ref(d, smfn, 0);
}