sh_hash_audit_bucket(d, key);
}
-void shadow_hash_delete(struct domain *d, unsigned long n, unsigned int t,
+bool shadow_hash_delete(struct domain *d, unsigned long n, unsigned int t,
mfn_t smfn)
/* Excise the mapping (n,t)->smfn from the hash table */
{
{
/* Need to search for the one we want */
x = d->arch.paging.shadow.hash_table[key];
- while ( 1 )
+ while ( x )
{
- ASSERT(x); /* We can't have hit the end, since our target is
- * still in the chain somehwere... */
if ( next_shadow(x) == sp )
{
x->next_shadow = sp->next_shadow;
}
x = next_shadow(x);
}
+ if ( !x )
+ return false;
}
set_next_shadow(sp, NULL);
sh_hash_audit_bucket(d, key);
+
+ return true;
}
typedef int (*hash_vcpu_callback_t)(struct vcpu *v, mfn_t smfn, mfn_t other_mfn);
SHADOW_PRINTK("gfn=%"SH_PRI_gfn", type=%08x, smfn=%"PRI_mfn"\n",
gfn_x(gfn), SH_type_fl1_shadow, mfn_x(smfn));
ASSERT(mfn_to_page(smfn)->u.sh.head);
- shadow_hash_delete(d, gfn_x(gfn), SH_type_fl1_shadow, smfn);
+ if ( !shadow_hash_delete(d, gfn_x(gfn), SH_type_fl1_shadow, smfn) )
+ {
+ printk(XENLOG_G_ERR
+ "%pd: %"PRI_gfn":FL1 hash entry not found for %"PRI_mfn"\n",
+ d, gfn_x(gfn), mfn_x(smfn));
+ domain_crash(d);
+ }
}
mfn_t shadow_hash_lookup(struct domain *d, unsigned long n, unsigned int t);
void shadow_hash_insert(struct domain *d,
unsigned long n, unsigned int t, mfn_t smfn);
-void shadow_hash_delete(struct domain *d,
+bool shadow_hash_delete(struct domain *d,
unsigned long n, unsigned int t, mfn_t smfn);
/* shadow promotion */
set_shadow_status(struct domain *d, mfn_t gmfn, u32 shadow_type, mfn_t smfn)
/* Put a shadow into the hash table */
{
- int res;
-
SHADOW_PRINTK("d%d gmfn=%lx, type=%08x, smfn=%lx\n",
d->domain_id, mfn_x(gmfn), shadow_type, mfn_x(smfn));
ASSERT(mfn_to_page(smfn)->u.sh.head);
/* 32-bit PV guests don't own their l4 pages so can't get_page them */
- if ( !is_pv_32bit_domain(d) || shadow_type != SH_type_l4_64_shadow )
+ if ( (shadow_type != SH_type_l4_64_shadow || !is_pv_32bit_domain(d)) &&
+ !get_page(mfn_to_page(gmfn), d) )
{
- res = get_page(mfn_to_page(gmfn), d);
- ASSERT(res == 1);
+ printk(XENLOG_G_ERR "%pd: cannot get page for MFN %" PRI_mfn "\n",
+ d, mfn_x(gmfn));
+ domain_crash(d);
+ return;
}
shadow_hash_insert(d, mfn_x(gmfn), shadow_type, smfn);
SHADOW_PRINTK("d%d gmfn=%"PRI_mfn", type=%08x, smfn=%"PRI_mfn"\n",
d->domain_id, mfn_x(gmfn), shadow_type, mfn_x(smfn));
ASSERT(mfn_to_page(smfn)->u.sh.head);
- shadow_hash_delete(d, mfn_x(gmfn), shadow_type, smfn);
- /* 32-bit PV guests don't own their l4 pages; see set_shadow_status */
- if ( !is_pv_32bit_domain(d) || shadow_type != SH_type_l4_64_shadow )
+ if ( shadow_hash_delete(d, mfn_x(gmfn), shadow_type, smfn) &&
+ /* 32-bit PV guests don't own their l4 pages; see set_shadow_status */
+ (shadow_type != SH_type_l4_64_shadow || !is_pv_32bit_domain(d)) )
put_page(mfn_to_page(gmfn));
}