diff mbox

[RFC,XEN,v3,24/39] xen/pmem: support PMEM_REGION_TYPE_DATA for XEN_SYSCTL_nvdimm_pmem_get_regions

Message ID 20170911043820.14617-25-haozhong.zhang@intel.com (mailing list archive)
State New, archived
Headers show

Commit Message

Haozhong Zhang Sept. 11, 2017, 4:38 a.m. UTC
Allow XEN_SYSCTL_nvdimm_pmem_get_regions to return a list of data PMEM
regions.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
Cc: Andrew Cooper <andrew.cooper3@citrix.com>
Cc: Jan Beulich <jbeulich@suse.com>
---
 tools/libxc/xc_misc.c       |  8 ++++++++
 xen/common/pmem.c           | 46 +++++++++++++++++++++++++++++++++++++++++++++
 xen/include/public/sysctl.h | 12 ++++++++++++
 3 files changed, 66 insertions(+)
diff mbox

Patch

diff --git a/tools/libxc/xc_misc.c b/tools/libxc/xc_misc.c
index db74df853a..93a1f8fdc5 100644
--- a/tools/libxc/xc_misc.c
+++ b/tools/libxc/xc_misc.c
@@ -944,6 +944,10 @@  int xc_nvdimm_pmem_get_regions(xc_interface *xch, uint8_t type,
         size = sizeof(xen_sysctl_nvdimm_pmem_mgmt_region_t) * max;
         break;
 
+    case PMEM_REGION_TYPE_DATA:
+        size = sizeof(xen_sysctl_nvdimm_pmem_data_region_t) * max;
+        break;
+
     default:
         return -EINVAL;
     }
@@ -969,6 +973,10 @@  int xc_nvdimm_pmem_get_regions(xc_interface *xch, uint8_t type,
         set_xen_guest_handle(regions->u_buffer.mgmt_regions, buffer);
         break;
 
+    case PMEM_REGION_TYPE_DATA:
+        set_xen_guest_handle(regions->u_buffer.data_regions, buffer);
+        break;
+
     default:
         rc = -EINVAL;
         goto out;
diff --git a/xen/common/pmem.c b/xen/common/pmem.c
index cbe557c220..ed4a014c30 100644
--- a/xen/common/pmem.c
+++ b/xen/common/pmem.c
@@ -251,6 +251,48 @@  static int pmem_get_mgmt_regions(
     return rc;
 }
 
+static int pmem_get_data_regions(
+    XEN_GUEST_HANDLE_64(xen_sysctl_nvdimm_pmem_data_region_t) regions,
+    unsigned int *num_regions)
+{
+    struct list_head *cur;
+    unsigned int nr = 0, max = *num_regions;
+    xen_sysctl_nvdimm_pmem_data_region_t region;
+    int rc = 0;
+
+    if ( !guest_handle_okay(regions, max * sizeof(region)) )
+        return -EINVAL;
+
+    spin_lock(&pmem_data_lock);
+
+    list_for_each(cur, &pmem_data_regions)
+    {
+        struct pmem *pmem = list_entry(cur, struct pmem, link);
+
+        if ( nr >= max )
+            break;
+
+        region.smfn = pmem->smfn;
+        region.emfn = pmem->emfn;
+        region.mgmt_smfn = pmem->u.data.mgmt_smfn;
+        region.mgmt_emfn = pmem->u.data.mgmt_emfn;
+
+        if ( copy_to_guest_offset(regions, nr, &region, 1) )
+        {
+            rc = -EFAULT;
+            break;
+        }
+
+        nr++;
+    }
+
+    spin_unlock(&pmem_data_lock);
+
+    *num_regions = nr;
+
+    return rc;
+}
+
 static int pmem_get_regions(xen_sysctl_nvdimm_pmem_regions_t *regions)
 {
     unsigned int type = regions->type, max = regions->num_regions;
@@ -269,6 +311,10 @@  static int pmem_get_regions(xen_sysctl_nvdimm_pmem_regions_t *regions)
         rc = pmem_get_mgmt_regions(regions->u_buffer.mgmt_regions, &max);
         break;
 
+    case PMEM_REGION_TYPE_DATA:
+        rc = pmem_get_data_regions(regions->u_buffer.data_regions, &max);
+        break;
+
     default:
         rc = -EINVAL;
     }
diff --git a/xen/include/public/sysctl.h b/xen/include/public/sysctl.h
index d7c12f23fb..8595ea438a 100644
--- a/xen/include/public/sysctl.h
+++ b/xen/include/public/sysctl.h
@@ -1141,6 +1141,16 @@  struct xen_sysctl_nvdimm_pmem_mgmt_region {
 typedef struct xen_sysctl_nvdimm_pmem_mgmt_region xen_sysctl_nvdimm_pmem_mgmt_region_t;
 DEFINE_XEN_GUEST_HANDLE(xen_sysctl_nvdimm_pmem_mgmt_region_t);
 
+/* PMEM_REGION_TYPE_DATA */
+struct xen_sysctl_nvdimm_pmem_data_region {
+    uint64_t smfn;
+    uint64_t emfn;
+    uint64_t mgmt_smfn;
+    uint64_t mgmt_emfn;
+};
+typedef struct xen_sysctl_nvdimm_pmem_data_region xen_sysctl_nvdimm_pmem_data_region_t;
+DEFINE_XEN_GUEST_HANDLE(xen_sysctl_nvdimm_pmem_data_region_t);
+
 /* XEN_SYSCTL_nvdimm_pmem_get_regions_nr */
 struct xen_sysctl_nvdimm_pmem_regions_nr {
     uint8_t type;         /* IN: one of PMEM_REGION_TYPE_* */
@@ -1161,6 +1171,8 @@  struct xen_sysctl_nvdimm_pmem_regions {
         XEN_GUEST_HANDLE_64(xen_sysctl_nvdimm_pmem_raw_region_t) raw_regions;
         /* if type == PMEM_REGION_TYPE_MGMT */
         XEN_GUEST_HANDLE_64(xen_sysctl_nvdimm_pmem_mgmt_region_t) mgmt_regions;
+        /* if type == PMEM_REGION_TYPE_DATA */
+        XEN_GUEST_HANDLE_64(xen_sysctl_nvdimm_pmem_data_region_t) data_regions;
     } u_buffer;           /* IN: the guest handler where the entries of PMEM
                                  regions of the type @type are returned */
 };