diff --git a/tools/libxl/libxl_domain.c b/tools/libxl/libxl_domain.c
index 08eccd082b..73ac856fb4 100644
--- a/tools/libxl/libxl_domain.c
+++ b/tools/libxl/libxl_domain.c
@@ -1028,6 +1028,11 @@ void libxl__destroy_domid(libxl__egc *egc, libxl__destroy_domid_state *dis)
         goto out;
     }
 
+    rc = libxl__sshm_del(gc, domid);
+    if (rc) {
+        LOGD(ERROR, domid, "Deleting static shm failed.");
+    }
+
     if (libxl__device_pci_destroy_all(gc, domid) < 0)
         LOGD(ERROR, domid, "Pci shutdown failed");
     rc = xc_domain_pause(ctx->xch, domid);
diff --git a/tools/libxl/libxl_internal.h b/tools/libxl/libxl_internal.h
index 74bc0acb21..648eaee8c2 100644
--- a/tools/libxl/libxl_internal.h
+++ b/tools/libxl/libxl_internal.h
@@ -4361,6 +4361,8 @@ static inline bool libxl__acpi_defbool_val(const libxl_domain_build_info *b_info
 _hidden int libxl__sshm_add(libxl__gc *gc, uint32_t domid,
                             libxl_static_shm *sshm, int len);
 
+_hidden int libxl__sshm_del(libxl__gc *gc, uint32_t domid);
+
 _hidden int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
                                       libxl_static_shm *sshms, int len);
 _hidden int libxl__sshm_setdefault(libxl__gc *gc, uint32_t domid,
diff --git a/tools/libxl/libxl_sshm.c b/tools/libxl/libxl_sshm.c
index e16c24ccb9..417a4cd0a4 100644
--- a/tools/libxl/libxl_sshm.c
+++ b/tools/libxl/libxl_sshm.c
@@ -79,6 +79,131 @@ int libxl__sshm_check_overlap(libxl__gc *gc, uint32_t domid,
     return 0;
 }
 
+/* Delete sshm master infomation from xenstore. If there are still living
+ * slaves, mark the master as in zombie state, but do not delete it,
+ * and it will be totally deleted later after all slaves are gone */
+static void libxl__sshm_del_master(libxl__gc *gc, xs_transaction_t xt,
+                                   uint32_t domid, const char *id)
+{
+    char *sshm_path;
+
+    sshm_path = libxl__xs_get_sshmpath(gc, id);
+
+    /* we know that domid can't be both a master and a slave for one id
+     * (enforced in the *_add_master() and *_add_slave() code),
+     * so the number of slaves won't change during iteration. Simply check
+     * sshm_path/slaves to tell if there are still living slaves. */
+    if (libxl__xs_read(gc, xt, GCSPRINTF("%s/slaves", sshm_path))) {
+        SSHM_ERROR(domid, id,
+                   "there are living slaves, won't be totally destroyed");
+
+        libxl__xs_write_checked(gc, xt,
+                                GCSPRINTF("%s/status", sshm_path),
+                                "zombie");
+    } else {
+        libxl__xs_path_cleanup(gc, xt, sshm_path);
+    }
+
+    return;
+}
+
+static void libxl__sshm_do_unmap(libxl__gc *gc, uint32_t domid, const char *id,
+                                 uint64_t begin, uint64_t end)
+{
+    begin >>= 12;
+    end >>= 12;
+    for (; begin < end; ++begin) {
+        if (xc_domain_remove_from_physmap(CTX->xch, domid, begin)) {
+            SSHM_ERROR(domid, id,
+                       "unable to unmap shared page at 0x%"PRIx64".",
+                       begin);
+        }
+    }
+}
+
+static void libxl__sshm_del_slave(libxl__gc *gc, xs_transaction_t xt,
+                                  uint32_t domid, const char *id, bool isretry)
+{
+    char *sshm_path, *slave_path;
+    char *master_stat, *mdomid_str, *begin_str, *end_str;
+    uint64_t begin, end;
+    uint32_t master_domid;
+
+    sshm_path = libxl__xs_get_sshmpath(gc, id);
+    slave_path = GCSPRINTF("%s/slaves/%"PRIu32, sshm_path, domid);
+
+    begin_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/begin", slave_path));
+    end_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/end", slave_path));
+    begin = strtoull(begin_str, NULL, 16);
+    end = strtoull(end_str, NULL, 16);
+
+    /* Avoid calling do_unmap many times in case of xs transaction retry */
+    if (!isretry)
+        libxl__sshm_do_unmap(gc, domid, id, begin, end);
+
+    libxl__xs_path_cleanup(gc, xt, slave_path);
+
+    /* check if master is in zombie state and has no slaves now,
+     * if yes, now it's the time to destroy it */
+    master_stat = libxl__xs_read(gc, xt, GCSPRINTF("%s/status", sshm_path));
+    if (!strncmp(master_stat, "zombie", 6) &&
+        !libxl__xs_read(gc, xt, GCSPRINTF("%s/slaves", sshm_path)))
+    {
+        mdomid_str = libxl__xs_read(gc, xt, GCSPRINTF("%s/master", sshm_path));
+        master_domid = strtoul(mdomid_str, NULL, 10);
+        libxl__sshm_del_master(gc, xt, master_domid, id);
+    }
+}
+
+/* Delete static_shm entries in the xensotre. */
+int libxl__sshm_del(libxl__gc *gc,  uint32_t domid)
+{
+    int rc, i;
+    bool isretry;
+    xs_transaction_t xt = XBT_NULL;
+    char *dom_path, *dom_sshm_path;
+    const char *role;
+    char **sshm_ents;
+    unsigned int sshm_num;
+
+    dom_path = libxl__xs_get_dompath(gc, domid);
+    dom_sshm_path = GCSPRINTF("%s/static_shm", dom_path);
+
+    isretry = false;
+    for (;;) {
+        rc = libxl__xs_transaction_start(gc, &xt);
+        if (rc) goto out;
+
+        if (libxl__xs_read(gc, xt, dom_sshm_path)) {
+            sshm_ents = libxl__xs_directory(gc, xt, dom_sshm_path, &sshm_num);
+            if (!sshm_ents) continue;
+
+            for (i = 0; i < sshm_num; ++i) {
+                role = libxl__xs_read(gc, xt,
+                                      GCSPRINTF("%s/%s/role",
+                                                dom_sshm_path,
+                                                sshm_ents[i]));
+                assert(role);
+                if (!strncmp(role, "slave", 5)) {
+                    libxl__sshm_del_slave(gc, xt, domid, sshm_ents[i], isretry);
+                } else {
+                    libxl__sshm_del_master(gc, xt, domid, sshm_ents[i]);
+                }
+            }
+        }
+
+        rc = libxl__xs_transaction_commit(gc, &xt);
+        if (!rc) break;
+        if (rc < 0) goto out;
+	 isretry = true;
+    }
+
+    rc = 0;
+out:
+    libxl__xs_transaction_abort(gc, &xt);
+    return rc;
+}
+
 /* The caller have to guarentee that sshm->begin < sshm->end */
 static int libxl__sshm_do_map(libxl__gc *gc, uint32_t mid, uint32_t sid,
                               libxl_static_shm *sshm,
