@@ -1006,6 +1006,57 @@ static int __init process_shm(struct domain *d,
return 0;
}
+
+int __init shm_init_late(void)
+{
+ unsigned long i = 0UL, shm_id;
+ int ret = 0;
+ struct domain *od, **bd = NULL;
+ unsigned long o_gfn, b_gfn, nr_gfns;
+
+ for ( shm_id = find_first_bit(shm_list_mask, NR_MEM_BANKS);
+ shm_id < NR_MEM_BANKS;
+ shm_id = find_next_bit(shm_list_mask, NR_MEM_BANKS, shm_id + 1) )
+
+ {
+ /* Acquire the only owner domain. */
+ od = get_domain_by_id(shm_list[shm_id].owner_dom);
+ if ( od == NULL )
+ return -ESRCH;
+ o_gfn = PFN_DOWN(shm_list[shm_id].owner_gbase);
+ nr_gfns = PFN_DOWN(shm_list[shm_id].size);
+
+ bd = xmalloc_array(struct domain *, shm_list[shm_id].nr_borrower);
+ if ( !bd )
+ return -ENOMEM;
+ /* Set up foreign memory map for all borrower domains. */
+ for ( i = 0; i < shm_list[shm_id].nr_borrower; i++ )
+ {
+ bd[i] = get_domain_by_id(shm_list[shm_id].borrower_dom[i]);
+ if ( bd[i] == NULL )
+ {
+ return -ESRCH;
+ goto fail;
+ }
+
+ b_gfn = PFN_DOWN(shm_list[shm_id].borrower_gbase[i]);
+ ret = guest_physmap_add_shm(od, bd[i], o_gfn, b_gfn, nr_gfns);
+ if ( ret )
+ {
+ ret = -EINVAL;
+ goto fail;
+ }
+ }
+
+ xfree(bd);
+ }
+ return ret;
+
+ fail:
+ xfree(bd);
+
+ return ret;
+}
#endif /* CONFIG_STATIC_SHM */
#else
static void __init allocate_static_memory(struct domain *d,
@@ -58,6 +58,7 @@ typedef struct {
} shm_info_t;
extern shm_info_t shm_list[NR_MEM_BANKS];
extern unsigned long shm_list_mask[BITS_TO_LONGS(NR_MEM_BANKS)];
+extern int shm_init_late(void);
#else
#define dom_shared NULL
#endif
@@ -1051,7 +1051,13 @@ void __init start_xen(unsigned long boot_phys_offset,
printk(XENLOG_INFO "Xen dom0less mode detected\n");
if ( acpi_disabled )
+ {
create_domUs();
+#ifdef CONFIG_STATIC_SHM
+ if ( shm_init_late() )
+ panic("Failed to set up deferred foreign memory mapping of static shared memory.\n");
+#endif
+ }
/*
* This needs to be called **before** heap_init_late() so modules