diff --git a/tools/libxc/include/xenctrl.h b/tools/libxc/include/xenctrl.h
index 43151cb415..e4d26967ba 100644
--- a/tools/libxc/include/xenctrl.h
+++ b/tools/libxc/include/xenctrl.h
@@ -2572,6 +2572,21 @@ int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout);
 int xc_domain_cacheflush(xc_interface *xch, uint32_t domid,
                          xen_pfn_t start_pfn, xen_pfn_t nr_pfns);
 
+/*
+ * Get the number of PMEM regions of the specified type.
+ *
+ * Parameters:
+ *  xch:  xc interface handle
+ *  type: the type of PMEM regions, must be one of PMEM_REGION_TYPE_*
+ *  nr:   the number of PMEM regions is returned via this parameter
+ *
+ * Return:
+ *  On success, return 0 and the number of PMEM regions is returned via @nr.
+ *  Otherwise, return a non-zero error code.
+ */
+int xc_nvdimm_pmem_get_regions_nr(xc_interface *xch,
+                                  uint8_t type, uint32_t *nr);
+
 /* Compat shims */
 #include "xenctrl_compat.h"
 
diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index 7e15e904e3..fa66410869 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -888,6 +888,30 @@ int xc_livepatch_replace(xc_interface *xch, char *name, uint32_t timeout)
     return _xc_livepatch_action(xch, name, LIVEPATCH_ACTION_REPLACE, timeout);
 }
 
+int xc_nvdimm_pmem_get_regions_nr(xc_interface *xch, uint8_t type, uint32_t *nr)
+{
+    DECLARE_SYSCTL;
+    xen_sysctl_nvdimm_op_t *nvdimm = &sysctl.u.nvdimm;
+    int rc;
+
+    if ( !nr || type != PMEM_REGION_TYPE_RAW )
+        return -EINVAL;
+
+    sysctl.cmd = XEN_SYSCTL_nvdimm_op;
+    nvdimm->cmd = XEN_SYSCTL_nvdimm_pmem_get_regions_nr;
+    nvdimm->pad = 0;
+    nvdimm->u.pmem_regions_nr.type = type;
+    nvdimm->err = 0;
+
+    rc = do_sysctl(xch, &sysctl);
+    if ( !rc )
+        *nr = nvdimm->u.pmem_regions_nr.num_regions;
+    else if ( nvdimm->err )
+        rc = nvdimm->err;
+
+    return rc;
+}
+
 /*
  * Local variables:
  * mode: C
diff --git a/xen/common/pmem.c b/xen/common/pmem.c
index d67f237cd5..995dfcb867 100644
--- a/xen/common/pmem.c
+++ b/xen/common/pmem.c
@@ -105,6 +105,23 @@ static int pmem_list_add(struct list_head *list,
     return rc;
 }
 
+static int pmem_get_regions_nr(xen_sysctl_nvdimm_pmem_regions_nr_t *regions_nr)
+{
+    int rc = 0;
+
+    switch ( regions_nr->type )
+    {
+    case PMEM_REGION_TYPE_RAW:
+        regions_nr->num_regions = nr_raw_regions;
+        break;
+
+    default:
+        rc = -EINVAL;
+    }
+
+    return rc;
+}
+
 /**
  * Register a pmem region to Xen.
  *
@@ -142,7 +159,17 @@ int pmem_register(unsigned long smfn, unsigned long emfn, unsigned int pxm)
  */
 int pmem_do_sysctl(struct xen_sysctl_nvdimm_op *nvdimm)
 {
-    int rc = -ENOSYS;
+    int rc;
+
+    switch ( nvdimm->cmd )
+    {
+    case XEN_SYSCTL_nvdimm_pmem_get_regions_nr:
+        rc = pmem_get_regions_nr(&nvdimm->u.pmem_regions_nr);
+        break;
+
+    default:
+        rc = -ENOSYS;
+    }
 
     nvdimm->err = -rc;
 
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index e8272ae968..cf308bbc45 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -1118,11 +1118,23 @@ DEFINE_XEN_GUEST_HANDLE(xen_sysctl_set_parameter_t);
  * Interface for NVDIMM management.
  */
 
+/* Types of PMEM regions */
+#define PMEM_REGION_TYPE_RAW        0 /* PMEM regions detected by Xen */
+
+/* XEN_SYSCTL_nvdimm_pmem_get_regions_nr */
+struct xen_sysctl_nvdimm_pmem_regions_nr {
+    uint8_t type;         /* IN: one of PMEM_REGION_TYPE_* */
+    uint32_t num_regions; /* OUT: the number of PMEM regions of type @type */
+};
+typedef struct xen_sysctl_nvdimm_pmem_regions_nr xen_sysctl_nvdimm_pmem_regions_nr_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_nvdimm_pmem_regions_nr_t);
+
 struct xen_sysctl_nvdimm_op {
-    uint32_t cmd; /* IN: XEN_SYSCTL_nvdimm_*; none is implemented yet. */
+    uint32_t cmd; /* IN: XEN_SYSCTL_nvdimm_*. */
+#define XEN_SYSCTL_nvdimm_pmem_get_regions_nr     0
     uint32_t pad; /* IN: Always zero. */
     union {
-        /* Parameters of XEN_SYSCTL_nvdimm_* will be added here. */
+        xen_sysctl_nvdimm_pmem_regions_nr_t pmem_regions_nr;
     } u;
     uint32_t err; /* OUT: error code */
 };
