@@ -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"
@@ -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
@@ -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;
@@ -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 */
};
XEN_SYSCTL_nvdimm_pmem_get_rgions_nr, which is a command of hypercall XEN_SYSCTL_nvdimm_op, is to get the number of PMEM regions of the specified type (see PMEM_REGION_TYPE_*). 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/include/xenctrl.h | 15 +++++++++++++++ tools/libxc/xc_misc.c | 24 ++++++++++++++++++++++++ xen/common/pmem.c | 29 ++++++++++++++++++++++++++++- xen/include/public/sysctl.h | 16 ++++++++++++++-- 4 files changed, 81 insertions(+), 3 deletions(-)