diff --git a/docs/misc/xenstore-paths.markdown b/docs/misc/xenstore-paths.markdown
index 197bb0f..208b64b 100644
--- a/docs/misc/xenstore-paths.markdown
+++ b/docs/misc/xenstore-paths.markdown
@@ -505,6 +505,11 @@ The guest's virtual time offset from UTC in seconds.
 
 The device model version for a domain.
 
+#### ~/libxl/$DOMID/dm-emuidmap = INTEGER
+
+Which emulator IDs are serving a domain.  This is a bitmask of
+`1u<<EMUID_*` values (see `libxl_internal.h`).
+
 #### /libxl/$DOMID/remus/netbuf/$DEVID/ifb = STRING [n,INTERNAL]
 
 ifb device used by Remus to buffer network output from the associated vif.
diff --git a/tools/libxl/libxl_create.c b/tools/libxl/libxl_create.c
index 41ece5a..71893c5 100644
--- a/tools/libxl/libxl_create.c
+++ b/tools/libxl/libxl_create.c
@@ -410,6 +410,8 @@ int libxl__domain_build(libxl__gc *gc,
     struct timeval start_time;
     int i, ret;
 
+    state->emuidmap = 0;
+
     ret = libxl__build_pre(gc, domid, d_config, state);
     if (ret)
         goto out;
diff --git a/tools/libxl/libxl_dm.c b/tools/libxl/libxl_dm.c
index 916d12c..2bd1eb0 100644
--- a/tools/libxl/libxl_dm.c
+++ b/tools/libxl/libxl_dm.c
@@ -1459,6 +1459,9 @@ void libxl__spawn_stub_dm(libxl__egc *egc, libxl__stub_dm_spawn_state *sdss,
         goto out;
     }
 
+    ret = libxl__dm_emuidmap_add(gc, guest_domid, d_state, emuid);
+    if (ret) goto out;
+
     sdss->pvqemu.guest_domid = 0;
 
     libxl_domain_create_info_init(&dm_config->c_info);
@@ -1801,6 +1804,9 @@ void libxl__spawn_local_dm(libxl__egc *egc, libxl__dm_spawn_state *dmss,
         abort();
     }
 
+    rc = libxl__dm_emuidmap_add(gc, domid, state, emuid);
+    if (rc) goto out;
+
     dm = libxl__domain_device_model(gc, b_info);
     if (!dm) {
         rc = ERROR_FAIL;
@@ -2417,6 +2423,61 @@ static void dm_support_check_done(libxl__egc *egc,
     ch->callback(egc, ch, rc);
 }
 
+/* emuid recording */
+
+static const char *emuidmap_path(libxl__gc *gc, int domid)
+{
+    return GCSPRINTF("libxl/%d/dm-emuidmap", domid);
+}
+
+int libxl__dm_emuidmap_add(libxl__gc *gc, int domid,
+                           libxl__domain_build_state *bstate, int emuid)
+{
+    unsigned newflag = 1u << emuid;
+
+    assert(!(bstate->emuidmap & newflag));
+    bstate->emuidmap |= newflag;
+    return libxl__xs_printf(gc, XBT_NULL, emuidmap_path(gc, domid),
+                            "%u", bstate->emuidmap);
+}
+
+int libxl__dm_emuidmap_get(libxl__gc *gc, int domid,
+                           unsigned *emuidmap_r)
+{
+    const char *s;
+    int rc;
+
+    rc = libxl__xs_read_checked(gc, XBT_NULL, emuidmap_path(gc, domid), &s);
+    if (rc) goto out;
+
+    if (!s) {
+        *emuidmap_r = 0;
+        return 0;
+    }
+
+    *emuidmap_r = atoi(s);
+    return 0;
+
+ out:
+    return rc;
+}
+
+void libxl__dm_emuidmap_get_bodgeerrors(libxl__gc *gc, int domid,
+                                        unsigned *emuidmap_r)
+{
+    int rc;
+
+    rc = libxl__dm_emuidmap_get(gc, domid, emuidmap_r);
+    if (rc) {
+        *emuidmap_r =
+            (1u << EMUID_DM) |
+            (1u << EMUID_PV);
+        LOG(ERROR,
+"Failed libxl_dm_emuidmap_get (rc=%d), using %#x (probably a wrong answer)",
+            rc, *emuidmap_r);
+    }
+}   
+
 /*
  * Local variables:
  * mode: C
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 71c1e17..0194823 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -1097,6 +1097,8 @@ typedef struct {
 
     char *saved_state;
 
+    unsigned emuidmap;
+
     libxl__file_reference pv_kernel;
     libxl__file_reference pv_ramdisk;
     const char * pv_cmdline;
@@ -1962,6 +1964,18 @@ enum {
     /* NB stubdom and its PV service domain not recorded here */
 };
 
+_hidden int libxl__dm_emuidmap_add(libxl__gc*, int domid,
+                                   libxl__domain_build_state*, int emuid);
+
+_hidden int libxl__dm_emuidmap_get(libxl__gc*, int domid,
+                                   unsigned *emuidmap_r);
+
+_hidden void libxl__dm_emuidmap_get_bodgeerrors(libxl__gc*, int domid,
+                                             unsigned *emuidmap_r);
+    /* *emuidmap_r is set to a default (but unreliable) value even
+     * if we get an error, which is logged.  Try to avoid calling
+     * this if you can! */
+
 _hidden char *libxl__device_model_xs_path(libxl__gc *gc,
         uint32_t dm_domid,
         uint32_t domid, int emuid,
