mirror of
https://github.com/xen-project/xen.git
synced 2026-10-28 10:11:27 +01:00
Make map_domain_page_global fail
When the global mapping cache runs out, make map_domain_page_global return NULL on failure rather than fire an assertion failure. This also updates the callers to handle the error gracefully. The only exception to this is the shadow pagetable code, which uses map_domain_page_global to create a mapping for v->arch.paging.shadow.guest_vtable; it's not clear this needs to be a global mapping anyway. Signed-off-by: Jeremy Fitzhardinge <jeremy@xensource.com>
This commit is contained in:
1 parent
fab51b46ae
commit
8a981e0bf2
3 files changed
+25
-5
No files matched your search
@@ -918,12 +918,19 @@ int vlapic_init(struct vcpu *v)
|
||||
vlapic->regs_page = alloc_domheap_page(NULL);
|
||||
if ( vlapic->regs_page == NULL )
|
||||
{
|
||||
dprintk(XENLOG_ERR, "malloc vlapic regs error for vcpu %x\n",
|
||||
dprintk(XENLOG_ERR, "malloc vlapic regs_page error for vcpu %x\n",
|
||||
v->vcpu_id);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
vlapic->regs = map_domain_page_global(page_to_mfn(vlapic->regs_page));
|
||||
if ( vlapic->regs == NULL )
|
||||
{
|
||||
dprintk(XENLOG_ERR, "malloc vlapic regs error for vcpu %x\n",
|
||||
v->vcpu_id);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
memset(vlapic->regs, 0, PAGE_SIZE);
|
||||
|
||||
vlapic_reset(vlapic);
|
||||
|
||||
@@ -3485,6 +3485,8 @@ sh_update_cr3(struct vcpu *v, int do_locking)
|
||||
if ( v->arch.paging.shadow.guest_vtable )
|
||||
sh_unmap_domain_page_global(v->arch.paging.shadow.guest_vtable);
|
||||
v->arch.paging.shadow.guest_vtable = sh_map_domain_page_global(gmfn);
|
||||
/* PAGING_LEVELS==4 implies 64-bit, which means that
|
||||
* map_domain_page_global can't fail */
|
||||
}
|
||||
else
|
||||
v->arch.paging.shadow.guest_vtable = __linear_l4_table;
|
||||
@@ -3515,6 +3517,9 @@ sh_update_cr3(struct vcpu *v, int do_locking)
|
||||
if ( v->arch.paging.shadow.guest_vtable )
|
||||
sh_unmap_domain_page_global(v->arch.paging.shadow.guest_vtable);
|
||||
v->arch.paging.shadow.guest_vtable = sh_map_domain_page_global(gmfn);
|
||||
/* Does this really need map_domain_page_global? Handle the
|
||||
* error properly if so. */
|
||||
ASSERT( v->arch.paging.shadow.guest_vtable );
|
||||
}
|
||||
else
|
||||
v->arch.paging.shadow.guest_vtable = __linear_l2_table;
|
||||
|
||||
@@ -218,17 +218,25 @@ void *map_domain_page_global(unsigned long mfn)
|
||||
|
||||
idx = find_first_zero_bit(inuse, GLOBALMAP_BITS);
|
||||
va = IOREMAP_VIRT_START + (idx << PAGE_SHIFT);
|
||||
ASSERT(va < FIXADDR_START);
|
||||
if ( va >= FIXADDR_START )
|
||||
{
|
||||
va = 0;
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
set_bit(idx, inuse);
|
||||
inuse_cursor = idx + 1;
|
||||
|
||||
fail:
|
||||
spin_unlock(&globalmap_lock);
|
||||
|
||||
pl2e = virt_to_xen_l2e(va);
|
||||
pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(va);
|
||||
l1e_write(pl1e, l1e_from_pfn(mfn, __PAGE_HYPERVISOR));
|
||||
if ( likely(va != 0) )
|
||||
{
|
||||
pl2e = virt_to_xen_l2e(va);
|
||||
pl1e = l2e_to_l1e(*pl2e) + l1_table_offset(va);
|
||||
l1e_write(pl1e, l1e_from_pfn(mfn, __PAGE_HYPERVISOR));
|
||||
}
|
||||
|
||||
return (void *)va;
|
||||
}
|
||||
|
||||