All of lore.kernel.org
 help / color / mirror / Atom feed
From: Haozhong Zhang <haozhong.zhang@intel.com>
To: xen-devel@lists.xen.org
Cc: Konrad Rzeszutek Wilk <konrad@darnok.org>,
	Dan Williams <dan.j.williams@intel.com>,
	Ian Jackson <ian.jackson@eu.citrix.com>,
	Wei Liu <wei.liu2@citrix.com>,
	Haozhong Zhang <haozhong.zhang@intel.com>
Subject: [RFC XEN PATCH v2 13/15] tools/libxl: add support to map host pmem device to guests
Date: Mon, 20 Mar 2017 08:09:47 +0800	[thread overview]
Message-ID: <20170320000949.24675-14-haozhong.zhang@intel.com> (raw)
In-Reply-To: <20170320000949.24675-1-haozhong.zhang@intel.com>

We can map host pmem devices or files on pmem devices to guests. This
patch adds support to map pmem devices. The implementation relies on
the Linux pmem driver (CONFIG_ACPI_NFIT, CONFIG_LIBNVDIMM, CONFIG_BLK_DEV_PMEM),
so it functions only when libxl is compiled for Linux right now.

Signed-off-by: Haozhong Zhang <haozhong.zhang@intel.com>
---
Cc: Ian Jackson <ian.jackson@eu.citrix.com>
Cc: Wei Liu <wei.liu2@citrix.com>
---
 tools/libxl/Makefile       |   4 +
 tools/libxl/libxl_nvdimm.c | 182 +++++++++++++++++++++++++++++++++++++++++++++
 tools/libxl/libxl_nvdimm.h |  42 +++++++++++
 3 files changed, 228 insertions(+)
 create mode 100644 tools/libxl/libxl_nvdimm.c
 create mode 100644 tools/libxl/libxl_nvdimm.h

diff --git a/tools/libxl/Makefile b/tools/libxl/Makefile
index a3e5e9909f..6bfc78972f 100644
--- a/tools/libxl/Makefile
+++ b/tools/libxl/Makefile
@@ -115,6 +115,10 @@ endif
 endif
 endif
 
+ifeq ($(CONFIG_Linux), y)
+LIBXL_OBJS-y += libxl_nvdimm.o
+endif
+
 ifeq ($(FLEX),)
 %.c %.h:: %.l
 	$(warning Flex is needed to rebuild some libxl parsers and \
diff --git a/tools/libxl/libxl_nvdimm.c b/tools/libxl/libxl_nvdimm.c
new file mode 100644
index 0000000000..1b3c83f2ca
--- /dev/null
+++ b/tools/libxl/libxl_nvdimm.c
@@ -0,0 +1,182 @@
+/*
+ * tools/libxl/libxl_nvdimm.c
+ *
+ * Copyright (C) 2017,  Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "libxl_internal.h"
+#include "libxl_arch.h"
+#include "libxl_nvdimm.h"
+
+#include <xenctrl.h>
+
+#define BLK_DEVICE_ROOT "/sys/dev/block"
+
+static int nvdimm_sysfs_read(libxl__gc *gc,
+                             unsigned int major, unsigned int minor,
+                             const char *name, void **data_r)
+{
+    char *path = libxl__sprintf(gc, BLK_DEVICE_ROOT"/%u:%u/device/%s",
+                                major, minor, name);
+    return libxl__read_sysfs_file_contents(gc, path, data_r, NULL);
+}
+
+static int nvdimm_get_spa(libxl__gc *gc, unsigned int major, unsigned int minor,
+                          uint64_t *spa_r)
+{
+    void *data;
+    int ret = nvdimm_sysfs_read(gc, major, minor, "resource", &data);
+
+    if ( ret )
+        return ret;
+
+    *spa_r = strtoll(data, NULL, 0);
+    return 0;
+}
+
+static int nvdimm_get_size(libxl__gc *gc, unsigned int major, unsigned int minor,
+                           uint64_t *size_r)
+{
+    void *data;
+    int ret = nvdimm_sysfs_read(gc, major, minor, "size", &data);
+
+    if ( ret )
+        return ret;
+
+    *size_r = strtoll(data, NULL, 0);
+
+    return 0;
+}
+
+static int add_pages(libxl__gc *gc, uint32_t domid,
+                     xen_pfn_t mfn, xen_pfn_t gpfn, unsigned long nr_mfns)
+{
+    unsigned int nr;
+    int ret = 0;
+
+    while ( nr_mfns )
+    {
+        nr = min(nr_mfns, (unsigned long) UINT_MAX);
+
+        ret = xc_domain_populate_pmemmap(CTX->xch, domid, mfn, gpfn, nr);
+        if ( ret )
+        {
+            LOG(ERROR, "failed to map pmem pages, "
+                "mfn 0x%" PRIx64", gpfn 0x%" PRIx64 ", nr_mfns %u, err %d",
+                mfn, gpfn, nr, ret);
+            break;
+        }
+
+        nr_mfns -= nr;
+        mfn += nr;
+        gpfn += nr;
+    }
+
+    return ret;
+}
+
+int libxl_nvdimm_add_device(libxl__gc *gc,
+                            uint32_t domid, const char *path,
+                            uint64_t guest_spa, uint64_t guest_size)
+{
+    int fd;
+    struct stat st;
+    unsigned int major, minor;
+    uint64_t host_spa, host_size;
+    xen_pfn_t mfn, gpfn;
+    unsigned long nr_gpfns;
+    int ret;
+
+    if ( (guest_spa & ~XC_PAGE_MASK) || (guest_size & ~XC_PAGE_MASK) )
+        return -EINVAL;
+
+    fd = open(path, O_RDONLY);
+    if ( fd < 0 )
+    {
+        LOG(ERROR, "failed to open file %s (err: %d)", path, errno);
+        return -EIO;
+    }
+
+    ret = fstat(fd, &st);
+    if ( ret )
+    {
+        LOG(ERROR, "failed to get status of file %s (err: %d)",
+            path, errno);
+        goto out;
+    }
+
+    switch ( st.st_mode & S_IFMT )
+    {
+    case S_IFBLK:
+        major = major(st.st_rdev);
+        minor = minor(st.st_rdev);
+        break;
+
+    default:
+        LOG(ERROR, "only support block device now");
+        ret = -EINVAL;
+        goto out;
+    }
+
+    ret = nvdimm_get_spa(gc, major, minor, &host_spa);
+    if ( ret )
+    {
+        LOG(ERROR, "failed to get SPA of device %u:%u", major, minor);
+        goto out;
+    }
+    else if ( host_spa & ~XC_PAGE_MASK )
+    {
+        ret = -EINVAL;
+        goto out;
+    }
+
+    ret = nvdimm_get_size(gc, major, minor, &host_size);
+    if ( ret )
+    {
+        LOG(ERROR, "failed to get size of device %u:%u", major, minor);
+        goto out;
+    }
+    else if ( guest_size > host_size )
+    {
+        LOG(ERROR, "vNVDIMM size %" PRIu64 " expires NVDIMM size %" PRIu64,
+            guest_size, host_size);
+        ret = -EINVAL;
+        goto out;
+    }
+
+    mfn = host_spa >> XC_PAGE_SHIFT;
+    gpfn = guest_spa >> XC_PAGE_SHIFT;
+    nr_gpfns = guest_size >> XC_PAGE_SHIFT;
+    ret = add_pages(gc, domid, mfn, gpfn, nr_gpfns);
+
+ out:
+    close(fd);
+    return ret;
+}
+
+/*
+ * Local variables:
+ * mode: C
+ * c-basic-offset: 4
+ * indent-tabs-mode: nil
+ * End:
+ */
diff --git a/tools/libxl/libxl_nvdimm.h b/tools/libxl/libxl_nvdimm.h
new file mode 100644
index 0000000000..e95be99c67
--- /dev/null
+++ b/tools/libxl/libxl_nvdimm.h
@@ -0,0 +1,42 @@
+/*
+ * tools/libxl/libxl_nvdimm.h
+ *
+ * Copyright (C) 2017,  Intel Corporation
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License, version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef LIBXL_NVDIMM_H
+#define LIBXL_NVDIMM_H
+
+#include <stdint.h>
+#include "libxl_internal.h"
+
+#if defined(__linux__)
+
+int libxl_nvdimm_add_device(libxl__gc *gc,
+                            uint32_t domid, const char *path,
+                            uint64_t spa, uint64_t length);
+
+#else
+
+static inline int libxl_nvdimm_add_device(libxl__gc *gc,
+                                          uint32_t domid, const char *path,
+                                          uint64_t spa, uint64_t length)
+{
+    return -ENOSYS;
+}
+
+#endif /* __linux__ */
+
+#endif /* !LIBXL_NVDIMM_H */
-- 
2.12.0


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

  parent reply	other threads:[~2017-03-20  0:09 UTC|newest]

Thread overview: 32+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-20  0:09 [RFC XEN PATCH v2 00/15] Add vNVDIMM support to HVM domains Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 01/15] xen/common: add Kconfig item for pmem support Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 02/15] xen: probe pmem regions via ACPI NFIT Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 03/15] xen/x86: allow customizing locations of extended frametable & M2P Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 04/15] xen/x86: add XEN_SYSCTL_nvdimm_pmem_setup to setup host pmem Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 05/15] xen/x86: add XENMEM_populate_pmem_map to map host pmem pages to HVM domain Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 06/15] tools: reserve guest memory for ACPI from device model Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 07/15] tools/libacpi: expose the minimum alignment used by mem_ops.alloc Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 08/15] tools/libacpi: add callback acpi_ctxt.p2v to get a pointer from physical address Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 09/15] tools/libacpi: add callbacks to access XenStore Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 10/15] tools/libacpi: add a simple AML builder Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 11/15] tools/libacpi: load ACPI built by the device model Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 12/15] tools/libxl: build qemu options from xl vNVDIMM configs Haozhong Zhang
2017-03-20  0:09 ` Haozhong Zhang [this message]
2017-03-20  0:09 ` [RFC XEN PATCH v2 14/15] tools/libxl: initiate pmem mapping via qmp callback Haozhong Zhang
2017-03-20  0:09 ` [RFC XEN PATCH v2 15/15] tools/misc: add xen-ndctl Haozhong Zhang
2017-03-30  4:11   ` Dan Williams
2017-03-30  7:58     ` Haozhong Zhang
2017-04-01 11:55       ` Konrad Rzeszutek Wilk
2017-03-30  4:20 ` [RFC XEN PATCH v2 00/15] Add vNVDIMM support to HVM domains Dan Williams
2017-03-30  8:21   ` Haozhong Zhang
2017-03-30 16:01     ` Dan Williams
2017-04-01 11:54       ` Konrad Rzeszutek Wilk
2017-04-01 15:45         ` Dan Williams
2017-04-04 17:00           ` Konrad Rzeszutek Wilk
2017-04-04 17:16             ` Dan Williams
2017-04-04 17:34               ` Konrad Rzeszutek Wilk
2017-04-04 17:59                 ` Dan Williams
2017-04-04 18:05                   ` Konrad Rzeszutek Wilk
2017-04-04 18:59                     ` Dan Williams
2017-04-11 17:48                       ` Konrad Rzeszutek Wilk
2017-04-01 12:24 ` Konrad Rzeszutek Wilk

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20170320000949.24675-14-haozhong.zhang@intel.com \
    --to=haozhong.zhang@intel.com \
    --cc=dan.j.williams@intel.com \
    --cc=ian.jackson@eu.citrix.com \
    --cc=konrad@darnok.org \
    --cc=wei.liu2@citrix.com \
    --cc=xen-devel@lists.xen.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.