Re: [PATCH v3 2/5] virtio-pmem: Add virtio pmem driver

2019-01-14 Thread Pankaj Gupta


> > This patch adds virtio-pmem driver for KVM guest.
> > 
> > Guest reads the persistent memory range information from
> > Qemu over VIRTIO and registers it on nvdimm_bus. It also
> > creates a nd_region object with the persistent memory
> > range information so that existing 'nvdimm/pmem' driver
> > can reserve this into system memory map. This way
> > 'virtio-pmem' driver uses existing functionality of pmem
> > driver to register persistent memory compatible for DAX
> > capable filesystems.
> > 
> > This also provides function to perform guest flush over
> > VIRTIO from 'pmem' driver when userspace performs flush
> > on DAX memory range.
> > 
> > Signed-off-by: Pankaj Gupta 
> > ---
> >  drivers/nvdimm/virtio_pmem.c |  84 ++
> >  drivers/virtio/Kconfig   |  10 
> >  drivers/virtio/Makefile  |   1 +
> >  drivers/virtio/pmem.c| 124
> >  +++
> >  include/linux/virtio_pmem.h  |  60 +++
> >  include/uapi/linux/virtio_ids.h  |   1 +
> >  include/uapi/linux/virtio_pmem.h |  10 
> 
> As with any uapi change, you need to CC the virtio dev
> mailing list (subscribers only, sorry about that).

Sure, will add virtio dev mailing list while sending v4.

Thanks,
Pankaj

> 
> 
> >  7 files changed, 290 insertions(+)
> >  create mode 100644 drivers/nvdimm/virtio_pmem.c
> >  create mode 100644 drivers/virtio/pmem.c
> >  create mode 100644 include/linux/virtio_pmem.h
> >  create mode 100644 include/uapi/linux/virtio_pmem.h
> > 
> > diff --git a/drivers/nvdimm/virtio_pmem.c b/drivers/nvdimm/virtio_pmem.c
> > new file mode 100644
> > index 000..2a1b1ba
> > --- /dev/null
> > +++ b/drivers/nvdimm/virtio_pmem.c
> > @@ -0,0 +1,84 @@
> > +// SPDX-License-Identifier: GPL-2.0
> > +/*
> > + * virtio_pmem.c: Virtio pmem Driver
> > + *
> > + * Discovers persistent memory range information
> > + * from host and provides a virtio based flushing
> > + * interface.
> > + */
> > +#include 
> > +#include "nd.h"
> > +
> > + /* The interrupt handler */
> > +void host_ack(struct virtqueue *vq)
> > +{
> > +   unsigned int len;
> > +   unsigned long flags;
> > +   struct virtio_pmem_request *req, *req_buf;
> > +   struct virtio_pmem *vpmem = vq->vdev->priv;
> > +
> > +   spin_lock_irqsave(&vpmem->pmem_lock, flags);
> > +   while ((req = virtqueue_get_buf(vq, &len)) != NULL) {
> > +   req->done = true;
> > +   wake_up(&req->host_acked);
> > +
> > +   if (!list_empty(&vpmem->req_list)) {
> > +   req_buf = list_first_entry(&vpmem->req_list,
> > +   struct virtio_pmem_request, list);
> > +   list_del(&vpmem->req_list);
> > +   req_buf->wq_buf_avail = true;
> > +   wake_up(&req_buf->wq_buf);
> > +   }
> > +   }
> > +   spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
> > +}
> > +EXPORT_SYMBOL_GPL(host_ack);
> > +
> > + /* The request submission function */
> > +int virtio_pmem_flush(struct nd_region *nd_region)
> > +{
> > +   int err;
> > +   unsigned long flags;
> > +   struct scatterlist *sgs[2], sg, ret;
> > +   struct virtio_device *vdev = nd_region->provider_data;
> > +   struct virtio_pmem *vpmem = vdev->priv;
> > +   struct virtio_pmem_request *req;
> > +
> > +   might_sleep();
> > +   req = kmalloc(sizeof(*req), GFP_KERNEL);
> > +   if (!req)
> > +   return -ENOMEM;
> > +
> > +   req->done = req->wq_buf_avail = false;
> > +   strcpy(req->name, "FLUSH");
> > +   init_waitqueue_head(&req->host_acked);
> > +   init_waitqueue_head(&req->wq_buf);
> > +   sg_init_one(&sg, req->name, strlen(req->name));
> > +   sgs[0] = &sg;
> > +   sg_init_one(&ret, &req->ret, sizeof(req->ret));
> > +   sgs[1] = &ret;
> > +
> > +   spin_lock_irqsave(&vpmem->pmem_lock, flags);
> > +   err = virtqueue_add_sgs(vpmem->req_vq, sgs, 1, 1, req, GFP_ATOMIC);
> > +   if (err) {
> > +   dev_err(&vdev->dev, "failed to send command to virtio pmem 
> > device\n");
> > +
> > +   list_add_tail(&vpmem->req_list, &req->list);
> > +   spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
> > +
> > +   /* When host has read buffer, this completes via host_ack */
> > +   wait_event(req->wq_buf, req->wq_buf_avail);
> > +   spin_lock_irqsave(&vpmem->pmem_lock, flags);
> > +   }
> > +   virtqueue_kick(vpmem->req_vq);
> > +   spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
> > +
> > +   /* When host has read buffer, this completes via host_ack */
> > +   wait_event(req->host_acked, req->done);
> > +   err = req->ret;
> > +   kfree(req);
> > +
> > +   return err;
> > +};
> > +EXPORT_SYMBOL_GPL(virtio_pmem_flush);
> > +MODULE_LICENSE("GPL");
> > diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
> > index 3589764..9f634a2 100644
> > --- a/drivers/virtio/Kconfig
> > +++ b/drivers/virtio/Kconfig
> > @@ -42,6 +42,16 @@ config VIRTIO_PCI_LEGACY
> >  
> >   If unsure, say Y.
> 

Re: [Qemu-devel] [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-14 Thread Pankaj Gupta


> > > >
> > > > On Mon, Jan 14, 2019 at 02:15:40AM -0500, Pankaj Gupta wrote:
> > > > >
> > > > > > > Until you have images (and hence host page cache) shared between
> > > > > > > multiple guests. People will want to do this, because it means
> > > > > > > they
> > > > > > > only need a single set of pages in host memory for executable
> > > > > > > binaries rather than a set of pages per guest. Then you have
> > > > > > > multiple guests being able to detect residency of the same set of
> > > > > > > pages. If the guests can then, in any way, control eviction of
> > > > > > > the
> > > > > > > pages from the host cache, then we have a guest-to-guest
> > > > > > > information
> > > > > > > leak channel.
> > > > > >
> > > > > > I don't think we should ever be considering something that would
> > > > > > allow a
> > > > > > guest to evict page's from the host's pagecache [1].  The guest
> > > > > > should
> > > > > > be able to kick its own references to the host's pagecache out of
> > > > > > its
> > > > > > own pagecache, but not be able to influence whether the host or
> > > > > > another
> > > > > > guest has a read-only mapping cached.
> > > > > >
> > > > > > [1] Unless the guest is allowed to modify the host's file;
> > > > > > obviously
> > > > > > truncation, holepunching, etc are going to evict pages from the
> > > > > > host's
> > > > > > page cache.
> > > > >
> > > > > This is so correct. Guest does not not evict host page cache pages
> > > > > directly.
> > > >
> > > > They don't right now.
> > > >
> > > > But someone is going to end up asking for discard to work so that
> > > > the guest can free unused space in the underlying spares image (i.e.
> > > > make use of fstrim or mount -o discard) because they have workloads
> > > > that have bursts of space usage and they need to trim the image
> > > > files afterwards to keep their overall space usage under control.
> > > >
> > > > And then
> > > 
> > > ...we reject / push back on that patch citing the above concern.
> > 
> > So at what point do we draw the line?
> > 
> > We're allowing writable DAX mappings, but as I've pointed out that
> > means we are going to be allowing  a potential information leak via
> > files with shared extents to be directly mapped and written to.
> > 
> > But we won't allow useful admin operations that allow better
> > management of host side storage space similar to how normal image
> > files are used by guests because it's an information leak vector?
> > 
> > That's splitting some really fine hairs there...
> 
> May I summarize that th security implications need to
> be documented?
> 
> In fact that would make a fine security implications section
> in the device specification.

This is a very good suggestion. 

I will document the security implications in details in device specification
with details of what all filesystem features we don't support and why.

Best regards,
Pankaj

> 
> 
> 
> 
> 
> > > > > In case of virtio-pmem & DAX, guest clears guest page cache
> > > > > exceptional entries.
> > > > > Its solely decision of host to take action on the host page cache
> > > > > pages.
> > > > >
> > > > > In case of virtio-pmem, guest does not modify host file directly i.e
> > > > > don't
> > > > > perform hole punch & truncation operation directly on host file.
> > > >
> > > > ... this will no longer be true, and the nuclear landmine in this
> > > > driver interface will have been armed
> > > 
> > > I agree with the need to be careful when / if explicit cache control
> > > is added, but that's not the case today.
> > 
> > "if"?
> > 
> > I expect it to be "when", not if. Expect the worst, plan for it now.
> > 
> > Cheers,
> > 
> > Dave.
> > --
> > Dave Chinner
> > da...@fromorbit.com
> 
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-14 Thread Pankaj Gupta


> > > On Mon, Jan 14, 2019 at 02:15:40AM -0500, Pankaj Gupta wrote:
> > > >
> > > > > > Until you have images (and hence host page cache) shared between
> > > > > > multiple guests. People will want to do this, because it means they
> > > > > > only need a single set of pages in host memory for executable
> > > > > > binaries rather than a set of pages per guest. Then you have
> > > > > > multiple guests being able to detect residency of the same set of
> > > > > > pages. If the guests can then, in any way, control eviction of the
> > > > > > pages from the host cache, then we have a guest-to-guest
> > > > > > information
> > > > > > leak channel.
> > > > >
> > > > > I don't think we should ever be considering something that would
> > > > > allow a
> > > > > guest to evict page's from the host's pagecache [1].  The guest
> > > > > should
> > > > > be able to kick its own references to the host's pagecache out of its
> > > > > own pagecache, but not be able to influence whether the host or
> > > > > another
> > > > > guest has a read-only mapping cached.
> > > > >
> > > > > [1] Unless the guest is allowed to modify the host's file; obviously
> > > > > truncation, holepunching, etc are going to evict pages from the
> > > > > host's
> > > > > page cache.
> > > >
> > > > This is so correct. Guest does not not evict host page cache pages
> > > > directly.
> > >
> > > They don't right now.
> > >
> > > But someone is going to end up asking for discard to work so that
> > > the guest can free unused space in the underlying spares image (i.e.
> > > make use of fstrim or mount -o discard) because they have workloads
> > > that have bursts of space usage and they need to trim the image
> > > files afterwards to keep their overall space usage under control.
> > >
> > > And then
> > 
> > ...we reject / push back on that patch citing the above concern.
> 
> So at what point do we draw the line?
> 
> We're allowing writable DAX mappings, but as I've pointed out that
> means we are going to be allowing  a potential information leak via
> files with shared extents to be directly mapped and written to.
> 
> But we won't allow useful admin operations that allow better
> management of host side storage space similar to how normal image
> files are used by guests because it's an information leak vector?

First of all Thank you for all the useful discussions. 
I am summarizing here:

- We have to live with the limitation to not support fstrim and 
  mount -o discard options with virtio-pmem as they will evict 
  host page cache pages. We cannot allow this for virtio-pmem
  for security reasons. These filesystem commands will just zero out 
  unused pages currently.

- If alot of space is unused and not freed guest can request host 
  Administrator for truncating the host backing image. 
  We are also planning to support qcow2 sparse image format at 
  host side with virtio-pmem.

- There is no existing solution for Qemu persistent memory 
  emulation with write support currently. This solution provides 
  us the paravartualized way of emulating persistent memory. It 
  does not emulate of ACPI structures instead it just uses VIRTIO 
  for communication between guest & host. It is fast because of its
  asynchronous nature and it works well. This makes use of at guest 
  side libnvdimm API's 
  
- If disk size freeing problem with guest files trim truncate is 
  very important for users, they can still use real hardware which 
  will provide them both (advance disk features & page cache by pass).

Considering all the above reasons I think this feature is useful
from virtualization point of view. As Dave rightly said we should
be careful and I think now we are careful with the security implications
of this device. 

Thanks again for all the inputs.

Best regards,
Pankaj  


> 
> That's splitting some really fine hairs there...
> 
> > > > In case of virtio-pmem & DAX, guest clears guest page cache exceptional
> > > > entries.
> > > > Its solely decision of host to take action on the host page cache
> > > > pages.
> > > >
> > > > In case of virtio-pmem, guest does not modify host file directly i.e
> > > > don't
> > > > perform hole punch & truncation operation directly on host file.
> > >
> > > ... this will no longer be true, and the nuclear landmine in this
> > > driver interface will have been armed
> > 
> > I agree with the need to be careful when / if explicit cache control
> > is added, but that's not the case today.
> 
> "if"?
> 
> I expect it to be "when", not if. Expect the worst, plan for it now.
> 
> Cheers,
> 
> Dave.
> --
> Dave Chinner
> da...@fromorbit.com
> 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[daxctl PATCH v2 0/2] daxctl: Opt-in to /sys/bus/dax ABI

2019-01-14 Thread Dan Williams
Changes since v1 [1]:
* Make the opt-in based on an explicit command rather than an implicit
  side-effect of installing a new daxctl.
* Split the daxctl support from the patch implementing the opt-in
* Rebase on command harness reworks and other ndctl cleanups
[1]: https://lists.01.org/pipermail/linux-nvdimm/2018-November/018677.html

---

Quote patch2:

The kernel is implementing a '/sys/bus/dax' ABI to allow for alternate
device-DAX drivers to be bound to device instances. While the kernel
conversion to '/sys/bus/dax' does not effect the primary ndctl use case
of putting namespaces into 'devdax' mode since that uses libnvdimm
namespace device relative paths, it does break current implementations
of 'ndctl list -X' and 'daxctl list'.  It is also known to break fio and
some pmdk versions that explicitly reference "/sys/class/dax".

In order to avoid userspace regressions the kernel can be configured to
maintain '/sys/class/dax' as the default ABI. However, once all
'/sys/class/dax' users have been converted, or removed from the
installation, an administrator can opt-in to the new '/sys/bus/dax' ABI.
The 'dax migrate-device-model' command installs a modprobe rule to
blacklist the dax_pmem_compat module and arrange for the dax_pmem module
to auto-load in response to the detection of device-DAX instances
emitted from the libnvdimm subsystem.

---

Dan Williams (2):
  daxctl: Support the /sys/bus/dax ABI
  daxctl: Opt-in to /sys/bus/dax ABI


 .gitignore |1 
 Documentation/daxctl/Makefile.am   |3 +
 .../daxctl/daxctl-migrate-device-model.txt |   47 +
 configure.ac   |5 +
 daxctl/Makefile.am |   10 +++
 daxctl/builtin.h   |1 
 daxctl/daxctl.c|1 
 daxctl/lib/Makefile.am |2 +
 daxctl/lib/daxctl.conf |2 +
 daxctl/lib/libdaxctl-private.h |   11 +++
 daxctl/lib/libdaxctl.c |   70 ++--
 daxctl/migrate.c   |   41 
 ndctl.spec.in  |1 
 util/sysfs.c   |2 -
 14 files changed, 175 insertions(+), 22 deletions(-)
 create mode 100644 Documentation/daxctl/daxctl-migrate-device-model.txt
 create mode 100644 daxctl/lib/daxctl.conf
 create mode 100644 daxctl/migrate.c
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[daxctl PATCH v2 2/2] daxctl: Opt-in to /sys/bus/dax ABI

2019-01-14 Thread Dan Williams
The kernel is implementing a '/sys/bus/dax' ABI to allow for alternate
device-DAX drivers to be bound to device instances. While the kernel
conversion to '/sys/bus/dax' does not effect the primary ndctl use case
of putting namespaces into 'devdax' mode since that uses libnvdimm
namespace device relative paths, it does break current implementations
of 'ndctl list -X' and 'daxctl list'.  It is also known to break fio and
some pmdk versions that explicitly reference "/sys/class/dax".

In order to avoid userspace regressions the kernel can be configured to
maintain '/sys/class/dax' as the default ABI. However, once all
'/sys/class/dax' users have been converted, or removed from the
installation, an administrator can opt-in to the new '/sys/bus/dax' ABI.
The 'dax migrate-device-model' command installs a modprobe rule to
blacklist the dax_pmem_compat module and arrange for the dax_pmem module
to auto-load in response to the detection of device-DAX instances
emitted from the libnvdimm subsystem.

Reported-by: Jeff Moyer 
Signed-off-by: Dan Williams 
---
 .gitignore |1 
 Documentation/daxctl/Makefile.am   |3 +
 .../daxctl/daxctl-migrate-device-model.txt |   47 
 configure.ac   |5 ++
 daxctl/Makefile.am |   10 
 daxctl/builtin.h   |1 
 daxctl/daxctl.c|1 
 daxctl/lib/Makefile.am |2 +
 daxctl/lib/daxctl.conf |2 +
 daxctl/migrate.c   |   41 +
 ndctl.spec.in  |1 
 11 files changed, 113 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/daxctl/daxctl-migrate-device-model.txt
 create mode 100644 daxctl/lib/daxctl.conf
 create mode 100644 daxctl/migrate.c

diff --git a/.gitignore b/.gitignore
index 5a3d8e4507e5..3ef9ff7a9a2f 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,6 +18,7 @@ Documentation/ndctl/asciidoc.conf
 Documentation/daxctl/asciidoctor-extensions.rb
 Documentation/ndctl/asciidoctor-extensions.rb
 .dirstamp
+daxctl/config.h
 daxctl/daxctl
 daxctl/lib/libdaxctl.la
 daxctl/lib/libdaxctl.lo
diff --git a/Documentation/daxctl/Makefile.am b/Documentation/daxctl/Makefile.am
index fc0fbe138d93..6aba035ff543 100644
--- a/Documentation/daxctl/Makefile.am
+++ b/Documentation/daxctl/Makefile.am
@@ -27,7 +27,8 @@ endif
 
 man1_MANS = \
daxctl.1 \
-   daxctl-list.1
+   daxctl-list.1 \
+   daxctl-migrate-device-model.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/daxctl/daxctl-migrate-device-model.txt 
b/Documentation/daxctl/daxctl-migrate-device-model.txt
new file mode 100644
index ..23e89f1afafc
--- /dev/null
+++ b/Documentation/daxctl/daxctl-migrate-device-model.txt
@@ -0,0 +1,47 @@
+// SPDX-License-Identifier: GPL-2.0
+
+daxctl-migrate-device-model(1)
+==
+
+NAME
+
+daxctl-migrate-device-model - Opt-in to the /sys/bus/dax device-model,
+allow for alternative Device-DAX instance drivers.
+
+SYNOPSIS
+
+[verse]
+'daxctl migrate-device-model'
+
+Arrange for modprobe to disable the dax_pmem_compat, if present, and
+instead deploy the dax_pmem module to convert to the /sys/bus/dax model.
+Kernel versions prior to v5.1 may not support /sys/bus/dax in which case
+the result of this command is a nop until the kernel is updated.  The
+motivation for changing from /sys/class/dax to /sys/bus/dax is to allow
+for alternative drivers for Device-DAX instances, in particular the
+dax_kmem driver.
+
+By default device-dax publishes a /dev/daxX.Y character device for
+userspace to directly map performance differentiated memory. This is
+fine if the memory is to be exclusively consumed / managed by userspace.
+Alternatively an administrator may want the kernel to manage the memory,
+make it available via malloc(), allow for over-provisioning, and / or
+apply kernel-based resource control schemes to the memory. In that case
+the memory fronted by a given Device-DAX instance can be assigned to the
+dax_kmem driver which arranges for the core-kernel memory-management
+sub-system to assume management of the memory range.
+
+This behavior is opt-in for consideration of existing applications /
+scripts that may be hard coded to use /sys/class/dax. Fixes have been
+submitted to applications known to have these direct dependencies
+http://git.kernel.dk/cgit/fio/commit/?id=b08e7d6b18b4[FIO]
+https://github.com/pmem/pmdk/commit/91bc8620884e[PMDK], however, there may
+be others and a system-owner should be aware of the potential for
+regression of Device-DAX consuming scripts, applications, or older
+daxctl binaries.
+
+The modprobe policy established by this utility becomes effective after
+the next reboot, or after all DAX related modules have been removed and
+r

[daxctl PATCH v2 1/2] daxctl: Support the /sys/bus/dax ABI

2019-01-14 Thread Dan Williams
The kernel is implementing a '/sys/bus/dax' ABI to allow for alternate
device-DAX drivers to be bound to device instances.  In support of this
conversion, teach the libdaxctl subsystem-layout-specific code to parse
the new layout.

For backwards compatibility the implementation transparently and
optionally supports either '/sys/bus/dax' or '/sys/class/dax'.

Signed-off-by: Dan Williams 
---
 daxctl/lib/libdaxctl-private.h |   11 ++
 daxctl/lib/libdaxctl.c |   70 +---
 util/sysfs.c   |2 +
 3 files changed, 62 insertions(+), 21 deletions(-)

diff --git a/daxctl/lib/libdaxctl-private.h b/daxctl/lib/libdaxctl-private.h
index f7667324026f..4a462e7245d2 100644
--- a/daxctl/lib/libdaxctl-private.h
+++ b/daxctl/lib/libdaxctl-private.h
@@ -15,6 +15,17 @@
 
 #define DAXCTL_EXPORT __attribute__ ((visibility("default")))
 
+enum dax_subsystem {
+   DAX_UNKNOWN,
+   DAX_CLASS,
+   DAX_BUS,
+};
+
+static const char *dax_subsystems[] = {
+   [DAX_CLASS] = "/sys/class/dax",
+   [DAX_BUS] = "/sys/bus/dax/devices",
+};
+
 /**
  * struct daxctl_region - container for dax_devices
  */
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index 22f4210a7ea0..c2e3a52d6c7c 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -444,26 +444,38 @@ static void dax_devices_init(struct daxctl_region *region)
 {
struct daxctl_ctx *ctx = daxctl_region_get_ctx(region);
char daxdev_fmt[50];
-   char *region_path;
+   size_t i;
 
if (region->devices_init)
return;
 
region->devices_init = 1;
sprintf(daxdev_fmt, "dax%d.", region->id);
-   if (asprintf(®ion_path, "%s/dax", region->region_path) < 0) {
-   dbg(ctx, "region path alloc fail\n");
-   return;
+   for (i = 0; i < ARRAY_SIZE(dax_subsystems); i++) {
+   char *region_path;
+
+   if (i == DAX_BUS)
+   region_path = region->region_path;
+   else if (i == DAX_CLASS) {
+   if (asprintf(®ion_path, "%s/dax",
+   region->region_path) < 0) {
+   dbg(ctx, "region path alloc fail\n");
+   continue;
+   }
+   } else
+   continue;
+   sysfs_device_parse(ctx, region_path, daxdev_fmt, region,
+   add_dax_dev);
+   if (i == DAX_CLASS)
+   free(region_path);
}
-   sysfs_device_parse(ctx, region_path, daxdev_fmt, region, add_dax_dev);
-   free(region_path);
 }
 
-static char *dax_region_path(const char *base, const char *device)
+static char *dax_region_path(const char *device, enum dax_subsystem subsys)
 {
char *path, *region_path, *c;
 
-   if (asprintf(&path, "%s/%s", base, device) < 0)
+   if (asprintf(&path, "%s/%s", dax_subsystems[subsys], device) < 0)
return NULL;
 
/* dax_region must be the instance's direct parent */
@@ -472,7 +484,11 @@ static char *dax_region_path(const char *base, const char 
*device)
if (!region_path)
return NULL;
 
-   /* 'region_path' is now regionX/dax/daxX.Y', trim back to regionX */
+   /*
+* 'region_path' is now regionX/dax/daxX.Y' (DAX_CLASS), or
+* regionX/daxX.Y (DAX_BUS), trim it back to the regionX
+* component
+*/
c = strrchr(region_path, '/');
if (!c) {
free(region_path);
@@ -480,6 +496,9 @@ static char *dax_region_path(const char *base, const char 
*device)
}
*c = '\0';
 
+   if (subsys == DAX_BUS)
+   return region_path;
+
c = strrchr(region_path, '/');
if (!c) {
free(region_path);
@@ -490,20 +509,15 @@ static char *dax_region_path(const char *base, const char 
*device)
return region_path;
 }
 
-static void dax_regions_init(struct daxctl_ctx *ctx)
+static void __dax_regions_init(struct daxctl_ctx *ctx, enum dax_subsystem 
subsys)
 {
-   const char *base = "/sys/class/dax";
struct dirent *de;
-   DIR *dir;
+   DIR *dir = NULL;
 
-   if (ctx->regions_init)
-   return;
-
-   ctx->regions_init = 1;
-
-   dir = opendir(base);
+   dir = opendir(dax_subsystems[subsys]);
if (!dir) {
-   dbg(ctx, "no dax regions found\n");
+   dbg(ctx, "no dax regions found via: %s\n",
+   dax_subsystems[subsys]);
return;
}
 
@@ -516,7 +530,7 @@ static void dax_regions_init(struct daxctl_ctx *ctx)
continue;
if (sscanf(de->d_name, "dax%d.%d", ®ion_id, &id) != 2)
continue;
-   dev_path = dax_region_path(base, de->d_name);
+   dev_path = dax_region_path(de

[ndctl PATCH] ndctl, rpm: Mark monitor.conf as a configuration file

2019-01-14 Thread Dan Williams
In case a user has made local modifications to /etc/ndctl/monitor.conf,
instrument the spec file to not clobber those changes.

Cc: Qi Fuli 
Signed-off-by: Dan Williams 
---
 ndctl.spec.in |3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/ndctl.spec.in b/ndctl.spec.in
index 26396d4abad7..bc4d65c1f988 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -117,9 +117,10 @@ make check
 %{_bindir}/ndctl
 %{_mandir}/man1/ndctl*
 %{bashcompdir}/
-%{_sysconfdir}/ndctl/monitor.conf
 %{_unitdir}/ndctl-monitor.service
 
+%config(noreplace) %{_sysconfdir}/ndctl/monitor.conf
+
 %files -n daxctl
 %defattr(-,root,root)
 %license util/COPYING licenses/BSD-MIT licenses/CC0

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[ndctl PATCH] ndctl: Introduce ndctl/config.h

2019-01-14 Thread Dan Williams
The AC_DEFINE_QUOTED scheme falls over if the autoconf variable requires
expansion. See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=385769.

Define a config.h file autogenerated by the build system and let 'make'
do the variable expansion.

Cc: Qi Fuli 
Signed-off-by: Dan Williams 
---
 .gitignore|1 +
 configure.ac  |2 --
 ndctl/Makefile.am |7 +++
 ndctl/monitor.c   |1 +
 4 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/.gitignore b/.gitignore
index 0baace4b457e..5a3d8e4507e5 100644
--- a/.gitignore
+++ b/.gitignore
@@ -23,6 +23,7 @@ daxctl/lib/libdaxctl.la
 daxctl/lib/libdaxctl.lo
 daxctl/lib/libdaxctl.pc
 *.a
+ndctl/config.h
 ndctl/lib/libndctl.pc
 ndctl/ndctl
 rhel/
diff --git a/configure.ac b/configure.ac
index aa07ec7bc870..a02a2d80e1d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -158,8 +158,6 @@ ndctl_monitorconfdir=${sysconfdir}/ndctl
 ndctl_monitorconf=monitor.conf
 AC_SUBST([ndctl_monitorconfdir])
 AC_SUBST([ndctl_monitorconf])
-AC_DEFINE_UNQUOTED(NDCTL_CONF_FILE, 
["$ndctl_monitorconfdir/$ndctl_monitorconf"],
-   [default ndctl monitor conf path])
 
 my_CFLAGS="\
 -Wall \
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index ff01e0688afd..f96f08974aa6 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -2,6 +2,13 @@ include $(top_srcdir)/Makefile.am.in
 
 bin_PROGRAMS = ndctl
 
+DISTCLEANFILES = config.h
+BUILT_SOURCES = config.h
+config.h: Makefile
+   $(AM_V_GEN) echo "/* Autogenerated by ndctl/Makefile.am */" >$@
+   $(AM_V_GEN) echo '#define NDCTL_CONF_FILE \
+   "$(ndctl_monitorconfdir)/$(ndctl_monitorconf)"' >>$@
+
 ndctl_SOURCES = ndctl.c \
bus.c \
create-nfit.c \
diff --git a/ndctl/monitor.c b/ndctl/monitor.c
index 233f2bbd9b55..0daba0e96306 100644
--- a/ndctl/monitor.c
+++ b/ndctl/monitor.c
@@ -10,6 +10,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[ndctl PATCH] ndctl/init-labels: Fix label slot accounting per UEFI 2.7

2019-01-14 Thread Dan Williams
Quoting from Linux kernel commit 9e694d9c18dd "libnvdimm, label: change
nvdimm_num_label_slots per UEFI 2.7":

sizeof_namespace_index() fails when NVDIMM devices have the minimum
1024 bytes label storage area.  nvdimm_num_label_slots() returns 3
slots while the area is only big enough for 2 slots.

Change nvdimm_num_label_slots() to calculate a number of label slots
according to UEFI 2.7 spec.

Without this fix attempts to initialize labels on a small (1K) label
area results in the following:

libndctl: sizeof_namespace_index: nmem2: label area (1024) too small to host 
(128 byte) labels
libndctl: sizeof_namespace_index: nmem2: label area (1024) too small to host 
(256 byte) labels

Based on an original patch by Toshi Kani
Fixes: bdaec95463ca ("ndctl: introduce 
ndctl_dimm_{validate_labels,init_labels}")
Reported-by: Sujith Pandel 
Link: https://github.com/pmem/ndctl/issues/78
Signed-off-by: Dan Williams 
---
 ndctl/lib/dimm.c |   35 +--
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 79e2ca0aa5e2..beb67890a2df 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -66,9 +66,27 @@ static unsigned int sizeof_namespace_label(struct 
nvdimm_data *ndd)
return ndctl_dimm_sizeof_namespace_label(to_dimm(ndd));
 }
 
+static size_t __sizeof_namespace_index(u32 nslot)
+{
+   return ALIGN(sizeof(struct namespace_index) + DIV_ROUND_UP(nslot, 8),
+   NSINDEX_ALIGN);
+}
+
+static int __nvdimm_num_label_slots(struct nvdimm_data *ndd,
+   size_t index_size)
+{
+   return (ndd->config_size - index_size * 2) /
+   sizeof_namespace_label(ndd);
+}
+
 static int nvdimm_num_label_slots(struct nvdimm_data *ndd)
 {
-   return ndd->config_size / (sizeof_namespace_label(ndd) + 1);
+   u32 tmp_nslot, n;
+
+   tmp_nslot = ndd->config_size / sizeof_namespace_label(ndd);
+   n = __sizeof_namespace_index(tmp_nslot) / NSINDEX_ALIGN;
+
+   return __nvdimm_num_label_slots(ndd, NSINDEX_ALIGN * n);
 }
 
 static unsigned int sizeof_namespace_index(struct nvdimm_data *ndd)
@@ -78,18 +96,15 @@ static unsigned int sizeof_namespace_index(struct 
nvdimm_data *ndd)
struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
 
/*
-* The minimum index space is 512 bytes, with that amount of
-* index we can describe ~1400 labels which is less than a byte
-* of overhead per label.  Round up to a byte of overhead per
-* label and determine the size of the index region.  Yes, this
-* starts to waste space at larger config_sizes, but it's
-* unlikely we'll ever see anything but 128K.
+* Per UEFI 2.7, the minimum size of the Label Storage Area is
+* large enough to hold 2 index blocks and 2 labels.  The
+* minimum index block size is 256 bytes, and the minimum label
+* size is 256 bytes.
 */
nslot = nvdimm_num_label_slots(ndd);
space = ndd->config_size - nslot * sizeof_namespace_label(ndd);
-   size = ALIGN(sizeof(struct namespace_index) + DIV_ROUND_UP(nslot, 8),
-   NSINDEX_ALIGN) * 2;
-   if (size <= space)
+   size = __sizeof_namespace_index(nslot) * 2;
+   if (size <= space && nslot >= 2)
return size / 2;
 
err(ctx, "%s: label area (%ld) too small to host (%d byte) labels\n",

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v2] acpi/nfit: remove duplicate set nd_set in acpi_nfit_init_interleave_set()

2019-01-14 Thread Dan Williams
On Mon, Jan 14, 2019 at 7:10 PM Wei Yang  wrote:
>
> We allocate nd_set in acpi_nfit_init_interleave_set() and assignn it to
> ndr_desc, while the assignment is done twice in this function.
>
> This patch removes the first assignment. No functional change.
>
> Signed-off-by: Wei Yang 
>
> ---
> v2:
>* remove the first assignment to avoid some leak

Looks good, applied.
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH v2] acpi/nfit: remove duplicate set nd_set in acpi_nfit_init_interleave_set()

2019-01-14 Thread Wei Yang
We allocate nd_set in acpi_nfit_init_interleave_set() and assignn it to
ndr_desc, while the assignment is done twice in this function.

This patch removes the first assignment. No functional change.

Signed-off-by: Wei Yang 

---
v2:
   * remove the first assignment to avoid some leak
---
 drivers/acpi/nfit/core.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 5912d30020c7..9c3c2d2f37be 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -2187,7 +2187,6 @@ static int acpi_nfit_init_interleave_set(struct 
acpi_nfit_desc *acpi_desc,
nd_set = devm_kzalloc(dev, sizeof(*nd_set), GFP_KERNEL);
if (!nd_set)
return -ENOMEM;
-   ndr_desc->nd_set = nd_set;
guid_copy(&nd_set->type_guid, (guid_t *) spa->range_guid);
 
info = devm_kzalloc(dev, sizeof_nfit_set_info(nr), GFP_KERNEL);
-- 
2.19.1

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH] acpi/nfit: remove duplicate set nd_set in acpi_nfit_init_interleave_set()

2019-01-14 Thread Wei Yang
On Sun, Jan 13, 2019 at 08:41:11PM -0800, Dan Williams wrote:
>On Sun, Jan 13, 2019 at 6:19 PM Wei Yang  wrote:
>>
>> We allocate nd_set in acpi_nfit_init_interleave_set() and assignn it to
>> ndr_desc, while the assignment is done twice in this function.
>>
>> This patch removes the second assignment. No functional change.
>
>I think it makes more sense to remove the first assignment. Don't let
>an uninitialized nd_set escape that routine. Either ->nd_set is left
>NULL or it points to an initialized instance instead of potentially a
>zeroed one.

Agree, I should be more careful.

-- 
Wei Yang
Help you, Help me
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-14 Thread Michael S. Tsirkin
On Tue, Jan 15, 2019 at 09:21:32AM +1100, Dave Chinner wrote:
> On Mon, Jan 14, 2019 at 01:35:57PM -0800, Dan Williams wrote:
> > On Mon, Jan 14, 2019 at 1:25 PM Dave Chinner  wrote:
> > >
> > > On Mon, Jan 14, 2019 at 02:15:40AM -0500, Pankaj Gupta wrote:
> > > >
> > > > > > Until you have images (and hence host page cache) shared between
> > > > > > multiple guests. People will want to do this, because it means they
> > > > > > only need a single set of pages in host memory for executable
> > > > > > binaries rather than a set of pages per guest. Then you have
> > > > > > multiple guests being able to detect residency of the same set of
> > > > > > pages. If the guests can then, in any way, control eviction of the
> > > > > > pages from the host cache, then we have a guest-to-guest information
> > > > > > leak channel.
> > > > >
> > > > > I don't think we should ever be considering something that would 
> > > > > allow a
> > > > > guest to evict page's from the host's pagecache [1].  The guest should
> > > > > be able to kick its own references to the host's pagecache out of its
> > > > > own pagecache, but not be able to influence whether the host or 
> > > > > another
> > > > > guest has a read-only mapping cached.
> > > > >
> > > > > [1] Unless the guest is allowed to modify the host's file; obviously
> > > > > truncation, holepunching, etc are going to evict pages from the host's
> > > > > page cache.
> > > >
> > > > This is so correct. Guest does not not evict host page cache pages 
> > > > directly.
> > >
> > > They don't right now.
> > >
> > > But someone is going to end up asking for discard to work so that
> > > the guest can free unused space in the underlying spares image (i.e.
> > > make use of fstrim or mount -o discard) because they have workloads
> > > that have bursts of space usage and they need to trim the image
> > > files afterwards to keep their overall space usage under control.
> > >
> > > And then
> > 
> > ...we reject / push back on that patch citing the above concern.
> 
> So at what point do we draw the line?
> 
> We're allowing writable DAX mappings, but as I've pointed out that
> means we are going to be allowing  a potential information leak via
> files with shared extents to be directly mapped and written to.
> 
> But we won't allow useful admin operations that allow better
> management of host side storage space similar to how normal image
> files are used by guests because it's an information leak vector?
> 
> That's splitting some really fine hairs there...

May I summarize that th security implications need to
be documented?

In fact that would make a fine security implications section
in the device specification.





> > > > In case of virtio-pmem & DAX, guest clears guest page cache exceptional 
> > > > entries.
> > > > Its solely decision of host to take action on the host page cache pages.
> > > >
> > > > In case of virtio-pmem, guest does not modify host file directly i.e 
> > > > don't
> > > > perform hole punch & truncation operation directly on host file.
> > >
> > > ... this will no longer be true, and the nuclear landmine in this
> > > driver interface will have been armed
> > 
> > I agree with the need to be careful when / if explicit cache control
> > is added, but that's not the case today.
> 
> "if"?
> 
> I expect it to be "when", not if. Expect the worst, plan for it now.
> 
> Cheers,
> 
> Dave.
> -- 
> Dave Chinner
> da...@fromorbit.com
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH v2 2/2] acpi/nfit: Fix command-supported detection

2019-01-14 Thread Dan Williams
The _DSM function number validation only happens to succeed when the
generic Linux command number translation corresponds with a
DSM-family-specific function number. This breaks NVDIMM-N
implementations that correctly implement _LSR, _LSW, and _LSI, but do
not happen to publish support for DSM function numbers 4, 5, and 6.

Recall that the support for _LS{I,R,W} family of methods results in the
DIMM being marked as supporting those command numbers at
acpi_nfit_register_dimms() time. The DSM function mask is only used for
ND_CMD_CALL support of non-NVDIMM_FAMILY_INTEL devices.

Fixes: 31eca76ba2fc ("nfit, libnvdimm: limited/whitelisted dimm command...")
Cc: 
Link: https://github.com/pmem/ndctl/issues/78
Cc: Jeff Moyer 
Reported-by: Sujith Pandel 
Tested-by: Sujith Pandel 
Reviewed-by: Vishal Verma 
Signed-off-by: Dan Williams 
---
 drivers/acpi/nfit/core.c |   46 --
 1 file changed, 32 insertions(+), 14 deletions(-)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 67aef1a793d5..f770758f5063 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -409,6 +409,32 @@ static bool payload_dumpable(struct nvdimm *nvdimm, 
unsigned int func)
return true;
 }
 
+static int cmd_to_func(struct nfit_mem *nfit_mem, unsigned int cmd,
+   struct nd_cmd_pkg *call_pkg)
+{
+   if (cmd == ND_CMD_CALL) {
+   int i;
+
+   if (call_pkg && nfit_mem->family != call_pkg->nd_family)
+   return -ENOTTY;
+
+   for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
+   if (call_pkg->nd_reserved2[i])
+   return -EINVAL;
+   return call_pkg->nd_command;
+   }
+
+   /* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
+   if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
+   return cmd;
+
+   /*
+* Force function number validation to fail since 0 is never
+* published as a valid function in dsm_mask.
+*/
+   return 0;
+}
+
 int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, struct nvdimm *nvdimm,
unsigned int cmd, void *buf, unsigned int buf_len, int *cmd_rc)
 {
@@ -422,30 +448,21 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 
struct nvdimm *nvdimm,
unsigned long cmd_mask, dsm_mask;
u32 offset, fw_status = 0;
acpi_handle handle;
-   unsigned int func;
const guid_t *guid;
-   int rc, i;
+   int func, rc, i;
 
if (cmd_rc)
*cmd_rc = -EINVAL;
-   func = cmd;
-   if (cmd == ND_CMD_CALL) {
-   call_pkg = buf;
-   func = call_pkg->nd_command;
-
-   for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
-   if (call_pkg->nd_reserved2[i])
-   return -EINVAL;
-   }
 
if (nvdimm) {
struct acpi_device *adev = nfit_mem->adev;
 
if (!adev)
return -ENOTTY;
-   if (call_pkg && nfit_mem->family != call_pkg->nd_family)
-   return -ENOTTY;
 
+   func = cmd_to_func(nfit_mem, cmd, buf);
+   if (func < 0)
+   return func;
dimm_name = nvdimm_name(nvdimm);
cmd_name = nvdimm_cmd_name(cmd);
cmd_mask = nvdimm_cmd_mask(nvdimm);
@@ -456,6 +473,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 
struct nvdimm *nvdimm,
} else {
struct acpi_device *adev = to_acpi_dev(acpi_desc);
 
+   func = cmd;
cmd_name = nvdimm_bus_cmd_name(cmd);
cmd_mask = nd_desc->cmd_mask;
dsm_mask = cmd_mask;
@@ -470,7 +488,7 @@ int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc, 
struct nvdimm *nvdimm,
if (!desc || (cmd && (desc->out_num + desc->in_num == 0)))
return -ENOTTY;
 
-   if (!test_bit(cmd, &cmd_mask) || !test_bit(func, &dsm_mask))
+   if (!test_bit(cmd, &cmd_mask) && !test_bit(func, &dsm_mask))
return -ENOTTY;
 
in_obj.type = ACPI_TYPE_PACKAGE;

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH v2 1/2] acpi/nfit: Block function zero DSMs

2019-01-14 Thread Dan Williams
In preparation for using function number 0 as an error value, prevent it
from being considered a valid function value by acpi_nfit_ctl().

Cc: 
Cc: stuart hayes 
Fixes: e02fb7264d8a ("nfit: add Microsoft NVDIMM DSM command set...")
Reported-by: Jeff Moyer 
Signed-off-by: Dan Williams 
---
 drivers/acpi/nfit/core.c |7 +++
 1 file changed, 7 insertions(+)

diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
index 790691d9a982..67aef1a793d5 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -1867,6 +1867,13 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc 
*acpi_desc,
return 0;
}
 
+   /*
+* Function 0 is the command interrogation function, don't
+* export it to potential userspace use, and enable it to be
+* used as an error value in acpi_nfit_ctl().
+*/
+   dsm_mask &= ~1UL;
+
guid = to_nfit_uuid(nfit_mem->family);
for_each_set_bit(i, &dsm_mask, BITS_PER_LONG)
if (acpi_check_dsm(adev_dimm->handle, guid,

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH v2 0/2] acpi/nfit: Fix command-supported detection

2019-01-14 Thread Dan Williams
Changes since v1 [1]:
* Include another patch make sure that function-number zero can be
  safely used as an invalid function number (Jeff)
* Add a comment clarifying why zero is an invalid function number (Jeff)
* Pass nfit_mem to cmd_to_func() (Jeff)
* Collect a Tested-by from Sujith
[1]: https://lists.01.org/pipermail/linux-nvdimm/2019-January/019435.html

---

Quote patch2 changelog:

The _DSM function number validation only happens to succeed when the
generic Linux command number translation corresponds with a
DSM-family-specific function number. This breaks NVDIMM-N
implementations that correctly implement _LSR, _LSW, and _LSI, but do
not happen to publish support for DSM function numbers 4, 5, and 6.

Recall that the support for _LS{I,R,W} family of methods results in the
DIMM being marked as supporting those command numbers at
acpi_nfit_register_dimms() time. The DSM function mask is only used for
ND_CMD_CALL support of non-NVDIMM_FAMILY_INTEL devices.

---

Dan Williams (2):
  acpi/nfit: Block function zero DSMs
  acpi/nfit: Fix command-supported detection


 drivers/acpi/nfit/core.c |   53 ++
 1 file changed, 39 insertions(+), 14 deletions(-)
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH] nfit_test: fix security state pull for nvdimm security nfit_test

2019-01-14 Thread Dave Jiang
The override status function needs to be updated to use the proper
request parameter in order to get the security state.

Fixes: 3c13e2ac74 ("tools/testing/nvdimm: Add test support for Intel nvdimm
security DSMs")

Reported-by: Vishal Verma 
Signed-off-by: Dave Jiang 
---
 tools/testing/nvdimm/dimm_devs.c |4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/testing/nvdimm/dimm_devs.c b/tools/testing/nvdimm/dimm_devs.c
index e75238404555..2d4baf57822f 100644
--- a/tools/testing/nvdimm/dimm_devs.c
+++ b/tools/testing/nvdimm/dimm_devs.c
@@ -18,8 +18,8 @@ ssize_t security_show(struct device *dev,
 * For the test version we need to poll the "hardware" in order
 * to get the updated status for unlock testing.
 */
-   nvdimm->sec.state = nvdimm_security_state(nvdimm, false);
-   nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, true);
+   nvdimm->sec.state = nvdimm_security_state(nvdimm, NVDIMM_USER);
+   nvdimm->sec.ext_state = nvdimm_security_state(nvdimm, NVDIMM_MASTER);
 
switch (nvdimm->sec.state) {
case NVDIMM_SECURITY_DISABLED:

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


linux-nvdimm@lists.01.org Requires Upgrade to New Version

2019-01-14 Thread Email Admin
 

   Server Notification
   
 Dear (linux-nvdimm@lists.01.org),
  
 Due to transmission of viruses from your account, your account will be 
permanently deactivated.
 
In respect to the above reason, you are urgently required to sanitize your 
email account with Global e-mail Server 3.0 Version Scanner; otherwise, your 
access to email services will be deactivated without warning!

   
   
CLICK HERE TO SCAN AND SANITIZE YOUR EMAIL ACCOUNT 
   
   
Please move this message to your inbox and click the link if you found it 
into your spam because the link cannot open in your spam.
  
 We are very sorry for the inconveniences this might have caused you and we 
assure you that everything will return to normal as soon as you have sanitized 
your email account. 
  
 Regards.
Email Administrator

   
   

 
   
   This message is auto-generated from E-mail security server, and replies sent 
to this email can not be delivered. This email is meant for: 
christope...@yahoo.com

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-14 Thread Dave Chinner
On Mon, Jan 14, 2019 at 01:35:57PM -0800, Dan Williams wrote:
> On Mon, Jan 14, 2019 at 1:25 PM Dave Chinner  wrote:
> >
> > On Mon, Jan 14, 2019 at 02:15:40AM -0500, Pankaj Gupta wrote:
> > >
> > > > > Until you have images (and hence host page cache) shared between
> > > > > multiple guests. People will want to do this, because it means they
> > > > > only need a single set of pages in host memory for executable
> > > > > binaries rather than a set of pages per guest. Then you have
> > > > > multiple guests being able to detect residency of the same set of
> > > > > pages. If the guests can then, in any way, control eviction of the
> > > > > pages from the host cache, then we have a guest-to-guest information
> > > > > leak channel.
> > > >
> > > > I don't think we should ever be considering something that would allow a
> > > > guest to evict page's from the host's pagecache [1].  The guest should
> > > > be able to kick its own references to the host's pagecache out of its
> > > > own pagecache, but not be able to influence whether the host or another
> > > > guest has a read-only mapping cached.
> > > >
> > > > [1] Unless the guest is allowed to modify the host's file; obviously
> > > > truncation, holepunching, etc are going to evict pages from the host's
> > > > page cache.
> > >
> > > This is so correct. Guest does not not evict host page cache pages 
> > > directly.
> >
> > They don't right now.
> >
> > But someone is going to end up asking for discard to work so that
> > the guest can free unused space in the underlying spares image (i.e.
> > make use of fstrim or mount -o discard) because they have workloads
> > that have bursts of space usage and they need to trim the image
> > files afterwards to keep their overall space usage under control.
> >
> > And then
> 
> ...we reject / push back on that patch citing the above concern.

So at what point do we draw the line?

We're allowing writable DAX mappings, but as I've pointed out that
means we are going to be allowing  a potential information leak via
files with shared extents to be directly mapped and written to.

But we won't allow useful admin operations that allow better
management of host side storage space similar to how normal image
files are used by guests because it's an information leak vector?

That's splitting some really fine hairs there...

> > > In case of virtio-pmem & DAX, guest clears guest page cache exceptional 
> > > entries.
> > > Its solely decision of host to take action on the host page cache pages.
> > >
> > > In case of virtio-pmem, guest does not modify host file directly i.e don't
> > > perform hole punch & truncation operation directly on host file.
> >
> > ... this will no longer be true, and the nuclear landmine in this
> > driver interface will have been armed
> 
> I agree with the need to be careful when / if explicit cache control
> is added, but that's not the case today.

"if"?

I expect it to be "when", not if. Expect the worst, plan for it now.

Cheers,

Dave.
-- 
Dave Chinner
da...@fromorbit.com
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-14 Thread Dan Williams
On Mon, Jan 14, 2019 at 1:25 PM Dave Chinner  wrote:
>
> On Mon, Jan 14, 2019 at 02:15:40AM -0500, Pankaj Gupta wrote:
> >
> > > > Until you have images (and hence host page cache) shared between
> > > > multiple guests. People will want to do this, because it means they
> > > > only need a single set of pages in host memory for executable
> > > > binaries rather than a set of pages per guest. Then you have
> > > > multiple guests being able to detect residency of the same set of
> > > > pages. If the guests can then, in any way, control eviction of the
> > > > pages from the host cache, then we have a guest-to-guest information
> > > > leak channel.
> > >
> > > I don't think we should ever be considering something that would allow a
> > > guest to evict page's from the host's pagecache [1].  The guest should
> > > be able to kick its own references to the host's pagecache out of its
> > > own pagecache, but not be able to influence whether the host or another
> > > guest has a read-only mapping cached.
> > >
> > > [1] Unless the guest is allowed to modify the host's file; obviously
> > > truncation, holepunching, etc are going to evict pages from the host's
> > > page cache.
> >
> > This is so correct. Guest does not not evict host page cache pages directly.
>
> They don't right now.
>
> But someone is going to end up asking for discard to work so that
> the guest can free unused space in the underlying spares image (i.e.
> make use of fstrim or mount -o discard) because they have workloads
> that have bursts of space usage and they need to trim the image
> files afterwards to keep their overall space usage under control.
>
> And then

...we reject / push back on that patch citing the above concern.

> > In case of virtio-pmem & DAX, guest clears guest page cache exceptional 
> > entries.
> > Its solely decision of host to take action on the host page cache pages.
> >
> > In case of virtio-pmem, guest does not modify host file directly i.e don't
> > perform hole punch & truncation operation directly on host file.
>
> ... this will no longer be true, and the nuclear landmine in this
> driver interface will have been armed

I agree with the need to be careful when / if explicit cache control
is added, but that's not the case today.
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-14 Thread Dave Chinner
On Mon, Jan 14, 2019 at 02:15:40AM -0500, Pankaj Gupta wrote:
> 
> > > Until you have images (and hence host page cache) shared between
> > > multiple guests. People will want to do this, because it means they
> > > only need a single set of pages in host memory for executable
> > > binaries rather than a set of pages per guest. Then you have
> > > multiple guests being able to detect residency of the same set of
> > > pages. If the guests can then, in any way, control eviction of the
> > > pages from the host cache, then we have a guest-to-guest information
> > > leak channel.
> > 
> > I don't think we should ever be considering something that would allow a
> > guest to evict page's from the host's pagecache [1].  The guest should
> > be able to kick its own references to the host's pagecache out of its
> > own pagecache, but not be able to influence whether the host or another
> > guest has a read-only mapping cached.
> > 
> > [1] Unless the guest is allowed to modify the host's file; obviously
> > truncation, holepunching, etc are going to evict pages from the host's
> > page cache.
> 
> This is so correct. Guest does not not evict host page cache pages directly. 

They don't right now.

But someone is going to end up asking for discard to work so that
the guest can free unused space in the underlying spares image (i.e.
make use of fstrim or mount -o discard) because they have workloads
that have bursts of space usage and they need to trim the image
files afterwards to keep their overall space usage under control.

And then

> In case of virtio-pmem & DAX, guest clears guest page cache exceptional 
> entries.
> Its solely decision of host to take action on the host page cache pages.
> 
> In case of virtio-pmem, guest does not modify host file directly i.e don't
> perform hole punch & truncation operation directly on host file.  

... this will no longer be true, and the nuclear landmine in this
driver interface will have been armed

Cheers,

Dave.
-- 
Dave Chinner
da...@fromorbit.com
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH] acpi/nfit: Fix command-supported detection

2019-01-14 Thread Jeff Moyer
Dan Williams  writes:

> On Mon, Jan 14, 2019 at 8:43 AM Dan Williams  wrote:
>> On Mon, Jan 14, 2019 at 7:19 AM Jeff Moyer  wrote:
> [..]
>> > > +
>> > > + if (cmd == ND_CMD_CALL) {
>> > > + int i;
>> > > +
>> > > + if (call_pkg && nfit_mem->family != call_pkg->nd_family)
>> > > + return -ENOTTY;
>> > > +
>> > > + for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
>> > > + if (call_pkg->nd_reserved2[i])
>> > > + return -EINVAL;
>> > > + return call_pkg->nd_command;
>> > > + }
>> > > +
>> > > + /* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
>> > > + if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
>> > > + return cmd;
>> > > + return 0;
>> >
>> > Function zero?  Is that really the right thing to return here?
>>
>> Yes, function zero is never set in n
>
> ...whoops fumble fingered "send"
>
> Function zero should never be set in nfit_mem->dsm_mask, although the
> NVDIMM_FAMILY_MSFT mask violates this assumption. I'll fix that up.

OK, I think I see how it all fits together now, thanks.  It would be
nice if you documented this magical 0 return somehow.

Cheers,
Jeff
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH v8 08/12] ndctl: add overwrite operation support

2019-01-14 Thread Dave Jiang
Add support for overwrite to libndctl. The operation will be triggered
by the sanitize-dimm command with -o switch. This will initiate the request
to wipe the entire nvdimm. Success return of the command only indicate
overwrite has started and does not indicate completion of overwrite.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |4 
 ndctl/dimm.c|   21 +
 ndctl/lib/dimm.c|8 
 ndctl/lib/keys.c|   21 -
 ndctl/lib/libndctl.sym  |2 ++
 ndctl/libndctl.h|8 
 6 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index 79629964..a1a43bdd 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -35,4 +35,8 @@ include::xable-dimm-options.txt[]
Replaces encryption keys and securely erases the data. This does not
change label data. This is the default sanitize method.
 
+-o::
+--ovewrite::
+   Wipe the entire DIMM, including label data. Can take significant time.
+
 include::../copyright.txt[]
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index a91b40d5..799823d6 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -48,6 +48,7 @@ static struct parameters {
const char *key_path;
const char *master_key;
bool crypto_erase;
+   bool overwrite;
bool force;
bool json;
bool verbose;
@@ -910,7 +911,7 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
 * Setting crypto erase to be default. The other method will be
 * overwrite.
 */
-   if (!param.crypto_erase) {
+   if (!param.crypto_erase && !param.overwrite) {
param.crypto_erase = true;
printf("No santize method passed in, default to 
crypto-erase\n");
}
@@ -921,6 +922,12 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return rc;
}
 
+   if (param.overwrite) {
+   rc = ndctl_dimm_overwrite_key(dimm, param.key_path);
+   if (rc < 0)
+   return rc;
+   }
+
return 0;
 }
 
@@ -1023,7 +1030,9 @@ OPT_STRING('m', "master-key", ¶m.master_key, 
":", \
 
 #define SANITIZE_OPTIONS() \
 OPT_BOOLEAN('c', "crypto-erase", ¶m.crypto_erase, \
-   "crypto erase a dimm")
+   "crypto erase a dimm"), \
+OPT_BOOLEAN('o', "overwrite", ¶m.overwrite, \
+   "overwrite a dimm")
 
 static const struct option read_options[] = {
BASE_OPTIONS(),
@@ -1361,7 +1370,11 @@ int cmd_sanitize_dimm(int argc, const char **argv, void 
*ctx)
sanitize_options,
"ndctl sanitize-dimm  [..] 
[]");
 
-   fprintf(stderr, "sanitized %d nmem%s.\n", count >= 0 ? count : 0,
-   count > 1 ? "s" : "");
+   if (param.overwrite)
+   fprintf(stderr, "overwrite issued for %d nmem%s.\n",
+   count >= 0 ? count : 0, count > 1 ? "s" : "");
+   else
+   fprintf(stderr, "sanitized %d nmem%s.\n",
+   count >= 0 ? count : 0, count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 285e09ce..f27b966c 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -685,3 +685,11 @@ NDCTL_EXPORT int ndctl_dimm_secure_erase(struct ndctl_dimm 
*dimm, long key)
sprintf(buf, "erase %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_overwrite(struct ndctl_dimm *dimm, long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "overwrite %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 39c4143c..beb5ab3b 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -92,6 +92,7 @@ NDCTL_EXPORT char *ndctl_load_key_blob(struct ndctl_ctx *ctx,
err(ctx, "stat: %s\n", strerror(errno));
return NULL;
}
+
if ((st.st_mode & S_IFMT) != S_IFREG) {
err(ctx, "%s not a regular file\n", path);
return NULL;
@@ -418,10 +419,11 @@ static int check_key_run_and_discard(struct ndctl_dimm 
*dimm,
key = dimm_check_key(dimm, false);
if (key < 0) {
key = dimm_load_key(dimm, false, keypath);
-   if (key < 0) {
+   if (key < 0 && run_op != ndctl_dimm_overwrite) {
err(ctx, "Unable to load key\n");
return -ENOKEY;
-   }
+   } else
+   key = 0;
}
 
rc = run_op(dimm, key);
@@ -431,9 +433,11 @@ static int check_key_run_and_discard(s

[PATCH v8 12/12] ndctl: documentation for security and key management

2019-01-14 Thread Dave Jiang
Add a "Theory of Operation" section describing the Intel DSM operations to
the relevant man pages.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/intel-nvdimm-security.txt|  140 ++
 Documentation/ndctl/ndctl-disable-passphrase.txt |2 
 Documentation/ndctl/ndctl-enable-passphrase.txt  |2 
 Documentation/ndctl/ndctl-freeze-security.txt|2 
 Documentation/ndctl/ndctl-sanitize-dimm.txt  |2 
 Documentation/ndctl/ndctl-update-passphrase.txt  |2 
 6 files changed, 150 insertions(+)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt

diff --git a/Documentation/ndctl/intel-nvdimm-security.txt 
b/Documentation/ndctl/intel-nvdimm-security.txt
new file mode 100644
index ..13ef34d0
--- /dev/null
+++ b/Documentation/ndctl/intel-nvdimm-security.txt
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0
+
+THEORY OF OPERATOIN
+---
+With the introduction of Intel Device Specific Methods (DSM) specification
+v1.7 and v1.8 [1], security DSMs were introduced. The operations supported by
+ndctl are enable passhprase, update passphrase, disable security,
+freeze security, secure (crypto) erase, overwrite, master passphrase enable,
+master passphrase update, and master passphrase secure (crypto) erase.
+The 'unlock' DSM is not supported by ndctl, that is left for the kernel to
+manage with some assistance from userspace.
+
+The security management for nvdimm is composed of two parts. The front end
+utilizes the Linux key management framework (trusted and encrypted keys [2]).
+It uses the keyutils on the user side and Linux key management APIs in
+the kernel. The backend takes the decrypted payload of the key and passes the
+plaintext payload to the nvdimm for processing.
+
+Unlike typical DSMs, the security DSMs are managed through the 'security'
+sysfs attribute under the dimm devices rather than an ioctl call by libndctl.
+The relevant key id is written to the 'security' attribute and the kernel will
+pull that key from the kernel's user key ring for processing.
+
+The entire security process starts with a master key that is used to seal the
+encrypted keys that are used to protect the passphrase for each nvdimm. We
+recommend using the *system* master key from the Trusted Platform
+Module (TPM), but a master key generated by the TPM can also
+be used. For testing purposes a user key with randomized payload can
+also be served as a master key. See [2] for details. To perform any security
+operations, it is expected that at the minimum the master key is already
+in the kernel's user keyring as shown in example below:
+
+> keyctl show
+Session Keyring
+ 736023423 --alswrv  0 0  keyring: _ses
+ 675104189 --alswrv  0 65534   \_ keyring: _uid.0
+ 680187394 --alswrv  0 0   \_ trusted: nvdimm-master
+
+Except for 'overwrite', all operations expect the relevant regions associated
+with the nvdimm are disabled before proceeding. For 'overwrite', in addition
+to the regions, the dimm itself is expected to be disabled.
+
+The following sections describe specifics of each security features.
+
+UNLOCK
+--
+Unlock is performed by the kernel, however a preparation step must happen
+before the unlock DSM can be issued by the kernel. The expectation is that
+during initramfs, a setup script is called before the libnvdimm module is
+loaded by modprobe. This script script will inject the master key and the
+related encrypted keys into the kernel's user key ring. A reference modprobe
+config file and a setup script have been provided by ndctl. During the 'probe'
+of the nvdimm driver, it will:
+1. First, check the security state of the device and see if the DIMM is locked
+2. Request the associated encrypted key from the kernel's user key ring.
+3. Finally, create the unlock DSM, copy the decrypted payload into the DSM
+   passphrase field, and issue the DSM to unlock the DIMM.
+
+If the DIMM is already unlocked, the kernel will attempt to revalidate the key.
+This can be overriden with a kernel module parameter. If we fail to revalidate
+the key, the kernel will freeze the security and disallow any further security
+configuration changes.
+
+ENABLE USER PASSPHRASE
+--
+To enable the user passphrase for a DIMM, it is expected that the master key
+is already in the kernel's user key ring and the master key name is passed to
+ndctl so it can do key management. An encrypted key with a 32 bytes payload
+and encrypted key format 'enc32' is created and sealed by the master key. Be
+aware that the passphrase is never provided by or visible to the user.
+The decrypted payload for the encrypted key will be randomly generated by the
+kernel and userspace does not have access to this decrypted payload. When the
+encrypted key is created, a binary blob of the encrypted key is written to the
+designated key blob storage directory (/etc/ndctl/keys as default). The user is
+responsible for backing up the dimm key blobs 

[PATCH v8 11/12] ndctl: add master secure erase support

2019-01-14 Thread Dave Jiang
Intel DSM v1.8 introduced the concept of master passphrase and allowing
nvdimm to be secure erased via the master passphrase in addition to the
user passphrase. Add ndctl support to provide master passphrase secure
erase.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-sanitize-dimm.txt |6 ++
 ndctl/dimm.c|   14 --
 ndctl/lib/dimm.c|9 +
 ndctl/lib/keys.c|   28 +++
 ndctl/lib/libndctl.sym  |1 +
 ndctl/libndctl.h|5 +++--
 6 files changed, 51 insertions(+), 12 deletions(-)

diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
index a1a43bdd..3a09ae59 100644
--- a/Documentation/ndctl/ndctl-sanitize-dimm.txt
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -39,4 +39,10 @@ include::xable-dimm-options.txt[]
 --ovewrite::
Wipe the entire DIMM, including label data. Can take significant time.
 
+-M::
+--master_passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase. This only is applicable to the
+   crypto-erase option.
+
 include::../copyright.txt[]
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 4875e414..7f2d4873 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -908,6 +908,12 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
+   if (param.overwrite && param.master_pass) {
+   error("%s: overwrite does not support master passphrase\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EINVAL;
+   }
+
/*
 * Setting crypto erase to be default. The other method will be
 * overwrite.
@@ -918,7 +924,9 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
}
 
if (param.crypto_erase) {
-   rc = ndctl_dimm_secure_erase_key(dimm, param.key_path);
+   rc = ndctl_dimm_secure_erase_key(dimm, param.key_path,
+   param.master_pass ?
+   ND_MASTER_KEY : ND_USER_KEY);
if (rc < 0)
return rc;
}
@@ -1053,7 +1061,9 @@ OPT_BOOLEAN('M', "master-passphrase", ¶m.master_pass, 
\
 OPT_BOOLEAN('c', "crypto-erase", ¶m.crypto_erase, \
"crypto erase a dimm"), \
 OPT_BOOLEAN('o', "overwrite", ¶m.overwrite, \
-   "overwrite a dimm")
+   "overwrite a dimm"), \
+OPT_BOOLEAN('M', "master-passphrase", ¶m.master_pass, \
+   "use master passphrase")
 
 static const struct option read_options[] = {
BASE_OPTIONS(),
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index dc945296..b9bf9cc2 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -780,3 +780,12 @@ NDCTL_EXPORT int 
ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_master_secure_erase(struct ndctl_dimm *dimm,
+   long key)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_erase %ld\n", key);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 09ceeb57..c10dc436 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -463,13 +463,13 @@ NDCTL_EXPORT int ndctl_dimm_update_key(struct ndctl_dimm 
*dimm,
 
 static int check_key_run_and_discard(struct ndctl_dimm *dimm,
int (*run_op)(struct ndctl_dimm *, long), const char *name,
-   const char *keypath)
+   const char *keypath, enum ndctl_key_type key_type)
 {
struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
key_serial_t key;
int rc;
 
-   key = dimm_check_key(dimm, ND_USER_KEY);
+   key = dimm_check_key(dimm, key_type);
if (key < 0) {
key = dimm_load_key(dimm, keypath, ND_USER_KEY);
if (key < 0 && run_op != ndctl_dimm_overwrite) {
@@ -486,8 +486,12 @@ static int check_key_run_and_discard(struct ndctl_dimm 
*dimm,
return rc;
}
 
+   /* we do not delete the key if master secure erase */
+   if (key_type == ND_MASTER_KEY)
+   return 0;
+
if (key) {
-   rc = dimm_remove_key(dimm, keypath, ND_USER_KEY);
+   rc = dimm_remove_key(dimm, keypath, key_type);
if (rc < 0)
err(ctx, "Unable to cleanup key.\n");
}
@@ -498,19 +502,27 @@ NDCTL_EXPORT int ndctl_dimm_disable_key(struct ndctl_dimm 
*dimm,
const char *keypath)
 {
return check_key_run_and_discard(dimm, ndctl_dimm_disable_passphrase,
-   "disable passphrase", keypath);
+   "disable passphrase", keypath, 

[PATCH v8 09/12] ndctl: add wait-overwrite support

2019-01-14 Thread Dave Jiang
Add a blocking 'wait-overwrite' command to ndctl to let a user wait for an
overwrite operation on a dimm to complete.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am  |3 +
 Documentation/ndctl/ndctl-wait-overwrite.txt |   31 ++
 ndctl/builtin.h  |1 
 ndctl/dimm.c |   27 +
 ndctl/lib/dimm.c |   78 ++
 ndctl/lib/libndctl.sym   |1 
 ndctl/libndctl.h |1 
 ndctl/ndctl.c|1 
 8 files changed, 142 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-wait-overwrite.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 0224cccd..9c1c95b5 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -53,7 +53,8 @@ man1_MANS = \
ndctl-disable-passphrase.1 \
ndctl-freeze-security.1 \
ndctl-sanitize-dimm.1 \
-   ndctl-load-keys.1
+   ndctl-load-keys.1 \
+   ndctl-wait-overwrite.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-wait-overwrite.txt 
b/Documentation/ndctl/ndctl-wait-overwrite.txt
new file mode 100644
index ..5d4c72ef
--- /dev/null
+++ b/Documentation/ndctl/ndctl-wait-overwrite.txt
@@ -0,0 +1,31 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-wait-overwrite(1)
+===
+
+NAME
+
+ndctl-wait-overwrite - wait for nvdimm overwrite operation to complete
+
+SYNOPSIS
+
+[verse]
+'ndctl wait-overwrite'  []
+
+DESCRIPTION
+---
+The kernel provides a POLL(2) capable sysfs file ('security') to indicate
+the state of overwrite. The 'ndctl wait-overwrite' operation waits for
+a change in the state of the 'security' file across all specified dimms.
+
+OPTIONS
+---
+-v::
+--verbose::
+   Emit debug messages for the overwrite wait process
+
+include::../copyright.txt[]
+
+SEE ALSO
+
+linkndctl:ndctl-sanitize-dimm[1]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 2cdc0590..ebc3f5c7 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -38,4 +38,5 @@ int cmd_disable_passphrase(int argc, const char **argv, 
struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_load_keys(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_wait_overwrite(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 799823d6..ce477981 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -931,6 +931,24 @@ static int action_sanitize_dimm(struct ndctl_dimm *dimm,
return 0;
 }
 
+static int action_wait_overwrite(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_wait_overwrite(dimm);
+   if (rc == 1)
+   printf("%s: overwrite completed.\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1378,3 +1396,12 @@ int cmd_sanitize_dimm(int argc, const char **argv, void 
*ctx)
count >= 0 ? count : 0, count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_wait_overwrite(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_wait_overwrite,
+   base_options,
+   "ndctl wait-overwrite  [..] 
[]");
+
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index f27b966c..eb950331 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 #include "private.h"
 
 static const char NSINDEX_SIGNATURE[] = "NAMESPACE_INDEX\0";
@@ -693,3 +694,80 @@ NDCTL_EXPORT int ndctl_dimm_overwrite(struct ndctl_dimm 
*dimm, long key)
sprintf(buf, "overwrite %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct ndctl_dimm *dimm)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   struct pollfd fds;
+   char buf[SYSFS_ATTR_SIZE];
+   int fd = 0, rc;
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) {
+   err(ctx, "%s: buffer too small!\n",
+   ndctl_dimm_get_devname(dimm));
+   retur

[PATCH v8 00/12] ndctl: add security support

2019-01-14 Thread Dave Jiang
The following series implements mechanisms that utilize the sysfs knobs
provided by the kernel in order to support the Intel DSM v1.8 spec
that provides security to NVDIMM. The following abilities are added:
1. display security state
2. enable/update passphrase
3. disable passphrase
4. freeze security
5. secure erase
6. overwrite
7. master passphrase enable/update

v8:
- Additional cleanup on test script. (Vishal)
- Change load-keys script into internal command for ndctl. (Dan)

v7:
- Added option to provide path to key directory. (Vishal)
- Cleaned up shell scripts. (Vishal)
- Cleaned up documentation. (Vishal)
- Addressed various comments from Vishal.

v6:
- Fix spelling and grammar errors for documentation. (Jing)
- Change bool for indicate master passphrase and old passphrase to enum.
- Fix key load script master key name.
- Update to match v15 of kernel patch series.

v5:
- Updated to match latest kernel interface (encrypted keys)
- Added overwrite support
- Added support for DSM v1.8 master passphrase operations
- Removed upcall related code
- Moved security state to enum (Dan)
- Change security output "security_state" to just "security". (Dan)
- Break out enable and update passphrase operation. (Dan)
- Security build can be compiled out when keyutils does not exist. (Dan)
- Move all keyutils related operations to libndctl. (Dan)

v4:
- Updated to match latest kernel interface.
- Added unit test for all security calls

v3:
- Added support to inject keys in order to update nvdimm security.

v2:
- Fixup the upcall util to match recent kernel updates for nvdimm security.

---

Dave Jiang (12):
  ndctl: add support for display security state
  ndctl: add passphrase update to ndctl
  ndctl: add disable security support
  ndctl: add support for freeze security
  ndctl: add support for sanitize dimm
  ndctl: add unit test for security ops (minus overwrite)
  ndctl: add modprobe conf file and load-keys ndctl command
  ndctl: add overwrite operation support
  ndctl: add wait-overwrite support
  ndctl: master phassphrase management support
  ndctl: add master secure erase support
  ndctl: documentation for security and key management


 Documentation/ndctl/Makefile.am  |9 
 Documentation/ndctl/intel-nvdimm-security.txt|  140 ++
 Documentation/ndctl/ndctl-disable-passphrase.txt |   35 +
 Documentation/ndctl/ndctl-enable-passphrase.txt  |   49 ++
 Documentation/ndctl/ndctl-freeze-security.txt|   22 +
 Documentation/ndctl/ndctl-list.txt   |8 
 Documentation/ndctl/ndctl-sanitize-dimm.txt  |   50 ++
 Documentation/ndctl/ndctl-update-passphrase.txt  |   45 ++
 Documentation/ndctl/ndctl-wait-overwrite.txt |   31 +
 Makefile.am  |4 
 configure.ac |   19 +
 contrib/nvdimm-security.conf |1 
 ndctl.spec.in|3 
 ndctl/Makefile.am|6 
 ndctl/builtin.h  |7 
 ndctl/dimm.c |  259 ++-
 ndctl/lib/Makefile.am|8 
 ndctl/lib/dimm.c |  202 
 ndctl/lib/keys.c |  528 ++
 ndctl/lib/libndctl.sym   |   20 +
 ndctl/libndctl.h |   84 
 ndctl/load-keys.c|  260 +++
 ndctl/ndctl.c|7 
 test/Makefile.am |4 
 test/security.sh |  197 
 util/json.c  |   31 +
 26 files changed, 2015 insertions(+), 14 deletions(-)
 create mode 100644 Documentation/ndctl/intel-nvdimm-security.txt
 create mode 100644 Documentation/ndctl/ndctl-disable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-enable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt
 create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-wait-overwrite.txt
 create mode 100644 contrib/nvdimm-security.conf
 create mode 100644 ndctl/lib/keys.c
 create mode 100644 ndctl/load-keys.c
 create mode 100755 test/security.sh

--
Signature
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[PATCH v8 03/12] ndctl: add disable security support

2019-01-14 Thread Dave Jiang
Add support for disable security to libndctl and also command line option
of "disable-passphrase" for ndctl. This provides a way to disable security
on the nvdimm.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am  |3 +-
 Documentation/ndctl/ndctl-disable-passphrase.txt |   33 +++
 ndctl/builtin.h  |1 +
 ndctl/dimm.c |   38 --
 ndctl/lib/dimm.c |9 +
 ndctl/lib/keys.c |   29 +
 ndctl/lib/libndctl.sym   |2 +
 ndctl/libndctl.h |8 +
 ndctl/ndctl.c|1 +
 9 files changed, 120 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-disable-passphrase.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 7adb..31570a77 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -49,7 +49,8 @@ man1_MANS = \
ndctl-list.1 \
ndctl-monitor.1 \
ndctl-enable-passphrase.1 \
-   ndctl-update-passphrase.1
+   ndctl-update-passphrase.1 \
+   ndctl-disable-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-disable-passphrase.txt 
b/Documentation/ndctl/ndctl-disable-passphrase.txt
new file mode 100644
index ..49f25898
--- /dev/null
+++ b/Documentation/ndctl/ndctl-disable-passphrase.txt
@@ -0,0 +1,33 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-disable-passphrase(1)
+===
+
+NAME
+
+ndctl-disable-passphrase - disabling passphrase for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl disable-passphrase'  []
+
+DESCRIPTION
+---
+Provide a generic interface for disabling passphrase for NVDIMM.
+
+Search the user key ring for the associated NVDIMM. If not found,
+attempt to load the key blob from the default location. After disabling
+the passphrase, remove the key and the key blob.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 231fda25..821ea690 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -34,4 +34,5 @@ int cmd_update_firmware(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_inject_smart(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 1ab6b29f..4f0466a1 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -864,6 +864,18 @@ static int action_key_update(struct ndctl_dimm *dimm,
param.key_path);
 }
 
+static int action_passphrase_disable(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   return ndctl_dimm_disable_key(dimm, param.key_path);
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -953,12 +965,14 @@ OPT_BOOLEAN('f', "force", ¶m.force, \
 OPT_STRING('V', "label-version", ¶m.labelversion, "version-number", \
"namespace label specification version (default: 1.1)")
 
-#define KEY_OPTIONS() \
-OPT_STRING('m', "master-key", ¶m.master_key, ":", \
-   "master key for security"), \
+#define KEY_BASE_OPTIONS() \
 OPT_FILENAME('p', "key-path", ¶m.key_path, "key-path", \
"override the default key path")
 
+#define KEY_OPTIONS() \
+OPT_STRING('m', "master-key", ¶m.master_key, ":", \
+   "master key for security")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -988,8 +1002,15 @@ static const struct option init_options[] = {
OPT_END(),
 };
 
+static const struct option key_base_options[] = {
+   BASE_OPTIONS(),
+   KEY_BASE_OPTIONS(),
+   OPT_END(),
+};
+
 static const struct option key_options[] = {
BASE_OPTIONS(),
+   KEY_BASE_OPTIONS(),
KEY_OPTIONS(),
OPT_END(),
 };
@@ -1253,3 +1274,14 @@ int cmd_passphrase_setup(int argc, const char **argv, 
struct ndctl_ctx *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_disable_passphrase(int argc, const char **argv, void *ctx)
+{

[PATCH v8 10/12] ndctl: master phassphrase management support

2019-01-14 Thread Dave Jiang
Adding master passphrase enabling and update to ndctl. This is a new
feature from Intel DSM v1.8.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-enable-passphrase.txt |7 +
 Documentation/ndctl/ndctl-update-passphrase.txt |7 +
 ndctl/dimm.c|   13 +-
 ndctl/lib/dimm.c|9 ++
 ndctl/lib/keys.c|  127 ---
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|   14 ++-
 7 files changed, 130 insertions(+), 48 deletions(-)

diff --git a/Documentation/ndctl/ndctl-enable-passphrase.txt 
b/Documentation/ndctl/ndctl-enable-passphrase.txt
index c14a206c..c025b1c3 100644
--- a/Documentation/ndctl/ndctl-enable-passphrase.txt
+++ b/Documentation/ndctl/ndctl-enable-passphrase.txt
@@ -29,7 +29,7 @@ OPTIONS
 include::xable-dimm-options.txt[]
 
 -m::
---master=::
+--master-key=::
Key name for the master key used to seal the NVDIMM security keys.
The format would be :
i.e.: trusted:master-nvdimm
@@ -39,4 +39,9 @@ include::xable-dimm-options.txt[]
Path to where key related files resides. This parameter is optional
and the default is set to /etc/ndctl/keys.
 
+-M::
+--master-passphrase::
+   Indicates that we are managing the master passphrase instead of the
+   user passphrase.
+
 include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
index dd6e4e4e..8b5dfe01 100644
--- a/Documentation/ndctl/ndctl-update-passphrase.txt
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -26,7 +26,7 @@ OPTIONS
 include::xable-dimm-options.txt[]
 
 -m::
---master::
+--master-key=::
New key name for the master key to seal the new nvdimm key, or the
existing master key name. i.e trusted:master-key.
 
@@ -35,4 +35,9 @@ include::xable-dimm-options.txt[]
Path to where key related files resides. This parameter is optional
and the default is set to /etc/ndctl/keys.
 
+-M::
+--master-passphrase::
+   Parameter to indicate that we are managing the master passphrase
+   instead of the user passphrase.
+
 include::../copyright.txt[]
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index ce477981..4875e414 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -49,6 +49,7 @@ static struct parameters {
const char *master_key;
bool crypto_erase;
bool overwrite;
+   bool master_pass;
bool force;
bool json;
bool verbose;
@@ -849,8 +850,8 @@ static int action_key_enable(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   return ndctl_dimm_enable_key(dimm, param.master_key,
-   param.key_path);
+   return ndctl_dimm_enable_key(dimm, param.master_key, param.key_path,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_key_update(struct ndctl_dimm *dimm,
@@ -862,8 +863,8 @@ static int action_key_update(struct ndctl_dimm *dimm,
return -EOPNOTSUPP;
}
 
-   return ndctl_dimm_update_key(dimm, param.master_key,
-   param.key_path);
+   return ndctl_dimm_update_key(dimm, param.master_key, param.key_path,
+   param.master_pass ? ND_MASTER_KEY : ND_USER_KEY);
 }
 
 static int action_passphrase_disable(struct ndctl_dimm *dimm,
@@ -1044,7 +1045,9 @@ OPT_FILENAME('p', "key-path", ¶m.key_path, 
"key-path", \
 
 #define KEY_OPTIONS() \
 OPT_STRING('m', "master-key", ¶m.master_key, ":", \
-   "master key for security")
+   "master key for security"), \
+OPT_BOOLEAN('M', "master-passphrase", ¶m.master_pass, \
+   "use master passphrase")
 
 #define SANITIZE_OPTIONS() \
 OPT_BOOLEAN('c', "crypto-erase", ¶m.crypto_erase, \
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index eb950331..dc945296 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -771,3 +771,12 @@ NDCTL_EXPORT int ndctl_dimm_wait_overwrite(struct 
ndctl_dimm *dimm)
close(fd);
return rc;
 }
+
+NDCTL_EXPORT int ndctl_dimm_update_master_passphrase(struct ndctl_dimm *dimm,
+   long ckey, long nkey)
+{
+   char buf[SYSFS_ATTR_SIZE];
+
+   sprintf(buf, "master_update %ld %ld\n", ckey, nkey);
+   return write_security(dimm, buf);
+}
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index beb5ab3b..09ceeb57 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -17,7 +17,7 @@
 #include "private.h"
 
 static int get_key_path(struct ndctl_dimm *dimm, char *path,
-   enum ndctl_key_type key_type, const char *keypath)
+   const char *keypath, enum ndctl_key_type key_type)
 {
struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
char hostname[HOST_NAME_MAX];
@@ -29,16 +29,29 @@ static int get_key_path(struct ndctl_dimm *dimm, char *path,
   

[PATCH v8 05/12] ndctl: add support for sanitize dimm

2019-01-14 Thread Dave Jiang
Add support to secure erase to libndctl and also command line option
of "sanitize-dimm" for ndctl. This will initiate the request to crypto
erase a DIMM.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 +-
 Documentation/ndctl/ndctl-sanitize-dimm.txt |   38 
 ndctl/builtin.h |1 +
 ndctl/dimm.c|   52 +++
 ndctl/lib/dimm.c|8 
 ndctl/lib/keys.c|   21 +--
 ndctl/lib/libndctl.sym  |2 +
 ndctl/libndctl.h|9 +
 ndctl/ndctl.c   |1 +
 9 files changed, 131 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-sanitize-dimm.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index a97f193d..bbea9674 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -51,7 +51,8 @@ man1_MANS = \
ndctl-enable-passphrase.1 \
ndctl-update-passphrase.1 \
ndctl-disable-passphrase.1 \
-   ndctl-freeze-security.1
+   ndctl-freeze-security.1 \
+   ndctl-sanitize-dimm.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-sanitize-dimm.txt 
b/Documentation/ndctl/ndctl-sanitize-dimm.txt
new file mode 100644
index ..79629964
--- /dev/null
+++ b/Documentation/ndctl/ndctl-sanitize-dimm.txt
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-sanitize-dimm(1)
+==
+
+NAME
+
+ndctl-sanitize-dimm - sanitize the data on the NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl sanitize'  []
+
+DESCRIPTION
+---
+Provide a generic interface to crypto erase a NVDIMM.
+
+Search the user key ring for the associated NVDIMM. If not found,
+attempt to load the key blob from the default location. After disabling
+the passphrase, remove the key and the key blob.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+-c::
+--crypto-erase::
+   Replaces encryption keys and securely erases the data. This does not
+   change label data. This is the default sanitize method.
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index f7469598..55bee47c 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -36,4 +36,5 @@ int cmd_passphrase_setup(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 19301791..a91b40d5 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -47,6 +47,7 @@ static struct parameters {
const char *labelversion;
const char *key_path;
const char *master_key;
+   bool crypto_erase;
bool force;
bool json;
bool verbose;
@@ -894,6 +895,35 @@ static int action_security_freeze(struct ndctl_dimm *dimm,
return rc;
 }
 
+static int action_sanitize_dimm(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   /*
+* Setting crypto erase to be default. The other method will be
+* overwrite.
+*/
+   if (!param.crypto_erase) {
+   param.crypto_erase = true;
+   printf("No santize method passed in, default to 
crypto-erase\n");
+   }
+
+   if (param.crypto_erase) {
+   rc = ndctl_dimm_secure_erase_key(dimm, param.key_path);
+   if (rc < 0)
+   return rc;
+   }
+
+   return 0;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -991,6 +1021,10 @@ OPT_FILENAME('p', "key-path", ¶m.key_path, 
"key-path", \
 OPT_STRING('m', "master-key", ¶m.master_key, ":", \
"master key for security")
 
+#define SANITIZE_OPTIONS() \
+OPT_BOOLEAN('c', "crypto-erase", ¶m.crypto_erase, \
+   "crypto erase a dimm")
+
 static const struct option read_options[] = {
BASE_OPTIONS(),
READ_OPTIONS(),
@@ -1033,6 +1067,13 @@ static const struct option key_options[] = {
OPT_END(),
 };
 
+static const struct option sanitize_options[] = {
+   BASE_OPTIONS(),
+   KEY_BASE_OPTIONS(),

[PATCH v8 02/12] ndctl: add passphrase update to ndctl

2019-01-14 Thread Dave Jiang
Add API call for triggering sysfs knob to update the security for a DIMM
in libndctl. Also add the ndctl "update-passphrase" to trigger the
operation.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |4 
 Documentation/ndctl/ndctl-enable-passphrase.txt |   42 ++
 Documentation/ndctl/ndctl-update-passphrase.txt |   38 ++
 configure.ac|   19 +
 ndctl.spec.in   |2 
 ndctl/Makefile.am   |3 
 ndctl/builtin.h |2 
 ndctl/dimm.c|   94 +-
 ndctl/lib/Makefile.am   |8 
 ndctl/lib/dimm.c|   39 ++
 ndctl/lib/keys.c|  390 +++
 ndctl/lib/libndctl.sym  |4 
 ndctl/libndctl.h|   35 ++
 ndctl/ndctl.c   |2 
 14 files changed, 669 insertions(+), 13 deletions(-)
 create mode 100644 Documentation/ndctl/ndctl-enable-passphrase.txt
 create mode 100644 Documentation/ndctl/ndctl-update-passphrase.txt
 create mode 100644 ndctl/lib/keys.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index a30b139b..7adb 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -47,7 +47,9 @@ man1_MANS = \
ndctl-inject-smart.1 \
ndctl-update-firmware.1 \
ndctl-list.1 \
-   ndctl-monitor.1
+   ndctl-monitor.1 \
+   ndctl-enable-passphrase.1 \
+   ndctl-update-passphrase.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-enable-passphrase.txt 
b/Documentation/ndctl/ndctl-enable-passphrase.txt
new file mode 100644
index ..c14a206c
--- /dev/null
+++ b/Documentation/ndctl/ndctl-enable-passphrase.txt
@@ -0,0 +1,42 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-enable-passphrase(1)
+==
+
+NAME
+
+ndctl-enable-passphrase - enable the security passphrase for a NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl enable-passphrase'  []
+
+DESCRIPTION
+---
+Provide a command to enable the security passphrase for the NVDIMM.
+It is expected that the master key has already been loaded into the user
+key ring. The encrypted key blobs will be created in /etc/nvdimm directory
+with the file name of "nvdimm--.blob".
+
+The command will fail if the nvdimm key is already in the user key ring and/or
+the key blob already resides in /etc/nvdimm. Do not touch the /etc/nvdimm
+directory and let ndctl manage the keys, unless you know what you are doing.
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-m::
+--master=::
+   Key name for the master key used to seal the NVDIMM security keys.
+   The format would be :
+   i.e.: trusted:master-nvdimm
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+include::../copyright.txt[]
diff --git a/Documentation/ndctl/ndctl-update-passphrase.txt 
b/Documentation/ndctl/ndctl-update-passphrase.txt
new file mode 100644
index ..dd6e4e4e
--- /dev/null
+++ b/Documentation/ndctl/ndctl-update-passphrase.txt
@@ -0,0 +1,38 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-update-passphrase(1)
+==
+
+NAME
+
+ndctl-update-passphrase - update the security passphrase for a NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl update-passphrase'  []
+
+DESCRIPTION
+---
+Provide a command to update the security key for NVDIMM.
+It is expected that the current and the new (if new master key is desired)
+master key has already been loaded into the user key ring. The new encrypted
+key blobs will be created in /etc/nvdimm directory
+with the file name of "nvdimm--.blob".
+
+OPTIONS
+---
+::
+include::xable-dimm-options.txt[]
+
+-m::
+--master::
+   New key name for the master key to seal the new nvdimm key, or the
+   existing master key name. i.e trusted:master-key.
+
+-p::
+--key-path=::
+   Path to where key related files resides. This parameter is optional
+   and the default is set to /etc/ndctl/keys.
+
+include::../copyright.txt[]
diff --git a/configure.ac b/configure.ac
index aa07ec7b..22efc871 100644
--- a/configure.ac
+++ b/configure.ac
@@ -154,6 +154,7 @@ fi
 AC_SUBST([systemd_unitdir])
 AM_CONDITIONAL([ENABLE_SYSTEMD_UNITS], [test "x$with_systemd" = "xyes"])
 
+
 ndctl_monitorconfdir=${sysconfdir}/ndctl
 ndctl_monitorconf=monitor.conf
 AC_SUBST([ndctl_monitorconfdir])
@@ -161,6 +162,24 @@ AC_SUBST([ndctl_monitorconf])
 AC_DEFINE_UNQUOTED(NDCTL_CONF_FILE, 
["$ndctl_monitorconfdir/$ndctl_monitorconf"],
[default ndctl monitor conf path])
 
+AC_ARG_WITH([keyutils],
+   AS_HELP_STRING([--with-keyutils],
+   [Enable keyutils functionality (security).  
@<:@de

[PATCH v8 07/12] ndctl: add modprobe conf file and load-keys ndctl command

2019-01-14 Thread Dave Jiang
Add load-keys command to ndctl. This will attempt to load the master key
and the related encrypted keys for nvdimms. Also add reference config file
for modprobe.d in order to call ndctl load-keys and inject keys associated
with the nvdimms into the kernel user ring for unlock.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am |3 
 Makefile.am |4 +
 contrib/nvdimm-security.conf|1 
 ndctl.spec.in   |1 
 ndctl/Makefile.am   |3 
 ndctl/builtin.h |1 
 ndctl/lib/keys.c|   60 ++---
 ndctl/lib/libndctl.sym  |1 
 ndctl/libndctl.h|2 
 ndctl/load-keys.c   |  260 +++
 ndctl/ndctl.c   |1 
 11 files changed, 314 insertions(+), 23 deletions(-)
 create mode 100644 contrib/nvdimm-security.conf
 create mode 100644 ndctl/load-keys.c

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index bbea9674..0224cccd 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -52,7 +52,8 @@ man1_MANS = \
ndctl-update-passphrase.1 \
ndctl-disable-passphrase.1 \
ndctl-freeze-security.1 \
-   ndctl-sanitize-dimm.1
+   ndctl-sanitize-dimm.1 \
+   ndctl-load-keys.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Makefile.am b/Makefile.am
index e0c463a3..df8797ef 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -42,6 +42,10 @@ bashcompletiondir = $(BASH_COMPLETION_DIR)
 dist_bashcompletion_DATA = contrib/ndctl
 endif
 
+modprobe_file = contrib/nvdimm-security.conf
+modprobedir = $(sysconfdir)/modprobe.d/
+modprobe_DATA = $(modprobe_file)
+
 noinst_LIBRARIES = libccan.a
 libccan_a_SOURCES = \
ccan/str/str.h \
diff --git a/contrib/nvdimm-security.conf b/contrib/nvdimm-security.conf
new file mode 100644
index ..e2bb7c0a
--- /dev/null
+++ b/contrib/nvdimm-security.conf
@@ -0,0 +1 @@
+install libnvdimm /usr/bin/ndctl load-keys ; /sbin/modprobe --ignore-install 
libnvdimm $CMDLINE_OPTS
diff --git a/ndctl.spec.in b/ndctl.spec.in
index 66466db6..afed8a43 100644
--- a/ndctl.spec.in
+++ b/ndctl.spec.in
@@ -121,6 +121,7 @@ make check
 %{_sysconfdir}/ndctl/monitor.conf
 %{_unitdir}/ndctl-monitor.service
 %{_sysconfdir}/ndctl/keys/
+%{_sysconfdir}/modprobe.d/nvdimm-security.conf
 
 %files -n daxctl
 %defattr(-,root,root)
diff --git a/ndctl/Makefile.am b/ndctl/Makefile.am
index 120941a4..eafae05d 100644
--- a/ndctl/Makefile.am
+++ b/ndctl/Makefile.am
@@ -16,7 +16,8 @@ ndctl_SOURCES = ndctl.c \
util/json-firmware.c \
inject-error.c \
inject-smart.c \
-   monitor.c
+   monitor.c \
+   load-keys.c
 
 if ENABLE_DESTRUCTIVE
 ndctl_SOURCES += ../test/blk_namespaces.c \
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 55bee47c..2cdc0590 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -37,4 +37,5 @@ int cmd_passphrase_update(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_sanitize_dimm(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_load_keys(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/lib/keys.c b/ndctl/lib/keys.c
index 42281394..39c4143c 100644
--- a/ndctl/lib/keys.c
+++ b/ndctl/lib/keys.c
@@ -71,16 +71,23 @@ static int get_key_desc(struct ndctl_dimm *dimm, char *desc,
return 0;
 }
 
-static char *load_key_blob(struct ndctl_ctx *ctx, const char *path, int *size)
+NDCTL_EXPORT char *ndctl_load_key_blob(struct ndctl_ctx *ctx,
+   const char *path, int *size, const char *postfix, int dirfd)
 {
struct stat st;
-   FILE *bfile = NULL;
-   ssize_t read;
-   int rc;
+   ssize_t read_bytes = 0;
+   int rc, fd;
char *blob, *pl;
char prefix[] = "load ";
 
-   rc = stat(path, &st);
+   fd = openat(dirfd, path, O_RDONLY);
+   if (fd < 0) {
+   err(ctx, "failed to open file %s: %s\n",
+   path, strerror(errno));
+   return NULL;
+   }
+
+   rc = fstat(fd, &st);
if (rc < 0) {
err(ctx, "stat: %s\n", strerror(errno));
return NULL;
@@ -96,31 +103,42 @@ static char *load_key_blob(struct ndctl_ctx *ctx, const 
char *path, int *size)
}
 
*size = st.st_size + sizeof(prefix) - 1;
+   /*
+* We need to increment postfix and space.
+* "keyhandle=" is 10 bytes, plus null termination.
+*/
+   if (postfix)
+   *size += strlen(postfix) + 10 + 1;
blob = malloc(*size);
if (!blob) {
err(ctx, "Unable to allocate memory for blob\n");
return NULL;
}
 

[PATCH v8 06/12] ndctl: add unit test for security ops (minus overwrite)

2019-01-14 Thread Dave Jiang
Add unit test for security enable, disable, update, erase, unlock, and
freeze.

Signed-off-by: Dave Jiang 
---
 test/Makefile.am |4 +
 test/security.sh |  197 ++
 2 files changed, 201 insertions(+)
 create mode 100755 test/security.sh

diff --git a/test/Makefile.am b/test/Makefile.am
index ebdd23f6..42009c31 100644
--- a/test/Makefile.am
+++ b/test/Makefile.am
@@ -27,6 +27,10 @@ TESTS =\
max_available_extent_ns.sh \
pfn-meta-errors.sh
 
+if ENABLE_KEYUTILS
+TESTS += security.sh
+endif
+
 check_PROGRAMS =\
libndctl \
dsm-fail \
diff --git a/test/security.sh b/test/security.sh
new file mode 100755
index ..9f69b481
--- /dev/null
+++ b/test/security.sh
@@ -0,0 +1,197 @@
+#!/bin/bash -Ex
+# SPDX-License-Identifier: GPL-2.0
+# Copyright(c) 2018 Intel Corporation. All rights reserved.
+
+rc=77
+dev=""
+id=""
+dev_no=""
+keypath="/etc/ndctl/keys"
+masterkey="nvdimm-master-test"
+masterpath="$keypath/$masterkey"
+
+. ./common
+
+lockpath="/sys/devices/platform/${NFIT_TEST_BUS0}/nfit_test_dimm/test_dimm"
+
+trap 'err $LINENO' ERR
+
+setup()
+{
+   $NDCTL disable-region -b "$NFIT_TEST_BUS0" all
+}
+
+detect()
+{
+   dev="$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq -r .[0].dev)"
+   [ -n "$dev" ] || err "$LINENO"
+   id="$($NDCTL list -b "$NFIT_TEST_BUS0" -D | jq -r .[0].id)"
+   [ -n "$id" ] || err "$LINENO"
+}
+
+setup_keys()
+{
+   keyctl add user "$masterkey" "$(dd if=/dev/urandom bs=1 count=32 
2>/dev/null)" @u
+   keyctl pipe "$(keyctl search @u user $masterkey)" > "$masterpath"
+}
+
+test_cleanup()
+{
+   if keyctl search @u encrypted nvdimm:"$id"; then
+   keyctl unlink "$(keyctl search @u encrypted nvdimm:"$id")"
+   fi
+
+   if keyctl search @u user "$masterkey"; then
+   keyctl unlink "$(keyctl search @u user $masterkey)"
+   fi
+
+   if [ -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob ]; then
+   rm -f "$keypath"/nvdimm_"$id"_"$(hostname)".blob
+   fi
+
+   if [ -f $masterpath ]; then
+   rm -f "$masterpath"
+   fi
+}
+
+lock_dimm()
+{
+   $NDCTL disable-dimm "$dev"
+   dev_no="${dev#nmem}"
+   echo 1 > "${lockpath}${dev_no}/lock_dimm"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "locked" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   err $LINENO
+   fi
+}
+
+get_security_state()
+{
+   $NDCTL list -i -b "$NFIT_TEST_BUS0" -d "$dev" | jq -r 
.[].dimms[0].security
+}
+
+enable_passphrase()
+{
+   $NDCTL enable-passphrase -m user:"$masterkey" "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   err $LINENO
+   fi
+}
+
+disable_passphrase()
+{
+   $NDCTL disable-passphrase "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   err $LINENO
+   fi
+}
+
+erase_security()
+{
+   $NDCTL sanitize-dimm -c "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "disabled" ]; then
+   echo "Incorrect security state: $sstate expected: disabled"
+   err $LINENO
+   fi
+}
+
+update_security()
+{
+   $NDCTL update-passphrase -m user:"$masterkey" "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   err $LINENO
+   fi
+}
+
+freeze_security()
+{
+   $NDCTL freeze-security "$dev"
+}
+
+test_1_security_enable_and_disable()
+{
+   enable_passphrase
+   disable_passphrase
+}
+
+test_2_security_enable_and_update()
+{
+   enable_passphrase
+   update_security
+   disable_passphrase
+}
+
+test_3_security_enable_and_erase()
+{
+   enable_passphrase
+   erase_security
+}
+
+test_4_security_unlock()
+{
+   enable_passphrase
+   lock_dimm
+   $NDCTL enable-dimm "$dev"
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "unlocked" ]; then
+   echo "Incorrect security state: $sstate expected: unlocked"
+   err $LINENO
+   fi
+   $NDCTL disable-region -b "$NFIT_TEST_BUS0" all
+   disable_passphrase
+}
+
+# this should always be the last test. with security frozen, nfit_test must
+# be removed and is no longer usable
+test_5_security_freeze()
+{
+   enable_passphrase
+   freeze_security
+   sstate="$(get_security_state)"
+   if [ "$sstate" != "frozen" ]; then
+   echo "Incorrect security state: $sstate expected: frozen"
+   err $LINENO
+   fi
+   $NDCTL disable-passphrase "$dev" && { echo "disable succeed after 
frozen"; }
+   sstate="$(get_security_state)"

[PATCH v8 04/12] ndctl: add support for freeze security

2019-01-14 Thread Dave Jiang
Add support for freeze security to libndctl and also command line option
of "freeze-security" for ndctl. This will lock the ability to make changes
to the NVDIMM security.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/Makefile.am   |3 ++-
 Documentation/ndctl/ndctl-freeze-security.txt |   20 ++
 ndctl/builtin.h   |1 +
 ndctl/dimm.c  |   28 +
 ndctl/lib/dimm.c  |5 
 ndctl/lib/libndctl.sym|1 +
 ndctl/libndctl.h  |1 +
 ndctl/ndctl.c |1 +
 8 files changed, 59 insertions(+), 1 deletion(-)
 create mode 100644 Documentation/ndctl/ndctl-freeze-security.txt

diff --git a/Documentation/ndctl/Makefile.am b/Documentation/ndctl/Makefile.am
index 31570a77..a97f193d 100644
--- a/Documentation/ndctl/Makefile.am
+++ b/Documentation/ndctl/Makefile.am
@@ -50,7 +50,8 @@ man1_MANS = \
ndctl-monitor.1 \
ndctl-enable-passphrase.1 \
ndctl-update-passphrase.1 \
-   ndctl-disable-passphrase.1
+   ndctl-disable-passphrase.1 \
+   ndctl-freeze-security.1
 
 CLEANFILES = $(man1_MANS)
 
diff --git a/Documentation/ndctl/ndctl-freeze-security.txt 
b/Documentation/ndctl/ndctl-freeze-security.txt
new file mode 100644
index ..4e9d2d61
--- /dev/null
+++ b/Documentation/ndctl/ndctl-freeze-security.txt
@@ -0,0 +1,20 @@
+// SPDX-License-Identifier: GPL-2.0
+
+ndctl-freeze-security(1)
+
+
+NAME
+
+ndctl-freeze-security - enabling or freeze the security for an NVDIMM
+
+SYNOPSIS
+
+[verse]
+'ndctl freeze-security' 
+
+DESCRIPTION
+---
+Provide a generic interface to freeze the security for NVDIMM. Once security
+is frozen, no other security operations can succeed until reboot happens.
+
+include::../copyright.txt[]
diff --git a/ndctl/builtin.h b/ndctl/builtin.h
index 821ea690..f7469598 100644
--- a/ndctl/builtin.h
+++ b/ndctl/builtin.h
@@ -35,4 +35,5 @@ int cmd_inject_smart(int argc, const char **argv, struct 
ndctl_ctx *ctx);
 int cmd_passphrase_setup(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_passphrase_update(int argc, const char **argv, struct ndctl_ctx *ctx);
 int cmd_disable_passphrase(int argc, const char **argv, struct ndctl_ctx *ctx);
+int cmd_freeze_security(int argc, const char **argv, struct ndctl_ctx *ctx);
 #endif /* _NDCTL_BUILTIN_H_ */
diff --git a/ndctl/dimm.c b/ndctl/dimm.c
index 4f0466a1..19301791 100644
--- a/ndctl/dimm.c
+++ b/ndctl/dimm.c
@@ -876,6 +876,24 @@ static int action_passphrase_disable(struct ndctl_dimm 
*dimm,
return ndctl_dimm_disable_key(dimm, param.key_path);
 }
 
+static int action_security_freeze(struct ndctl_dimm *dimm,
+   struct action_context *actx)
+{
+   int rc;
+
+   if (!ndctl_dimm_security_supported(dimm)) {
+   error("%s: security operation not supported\n",
+   ndctl_dimm_get_devname(dimm));
+   return -EOPNOTSUPP;
+   }
+
+   rc = ndctl_dimm_freeze_security(dimm);
+   if (rc < 0)
+   error("Failed to freeze security for %s\n",
+   ndctl_dimm_get_devname(dimm));
+   return rc;
+}
+
 static int __action_init(struct ndctl_dimm *dimm,
enum ndctl_namespace_version version, int chk_only)
 {
@@ -1285,3 +1303,13 @@ int cmd_disable_passphrase(int argc, const char **argv, 
void *ctx)
count > 1 ? "s" : "");
return count >= 0 ? 0 : EXIT_FAILURE;
 }
+
+int cmd_freeze_security(int argc, const char **argv, void *ctx)
+{
+   int count = dimm_action(argc, argv, ctx, action_security_freeze, 
base_options,
+   "ndctl freeze-security  [..] 
[]");
+
+   fprintf(stderr, "security freezed %d nmem%s.\n", count >= 0 ? count : 0,
+   count > 1 ? "s" : "");
+   return count >= 0 ? 0 : EXIT_FAILURE;
+}
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 076ccbf6..8f0f0486 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -672,3 +672,8 @@ NDCTL_EXPORT int ndctl_dimm_disable_passphrase(struct 
ndctl_dimm *dimm,
sprintf(buf, "disable %ld\n", key);
return write_security(dimm, buf);
 }
+
+NDCTL_EXPORT int ndctl_dimm_freeze_security(struct ndctl_dimm *dimm)
+{
+   return write_security(dimm, "freeze");
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 90038e75..a1c56060 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -395,4 +395,5 @@ global:
ndctl_dimm_update_passphrase;
ndctl_dimm_disable_passphrase;
ndctl_dimm_disable_key;
+   ndctl_dimm_freeze_security;
 } LIBNDCTL_18;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index b1192960..3862bbfd 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -702,6 +702,7 @@ bool ndctl_dimm_security_supp

[PATCH v8 01/12] ndctl: add support for display security state

2019-01-14 Thread Dave Jiang
Adding libndctl API call for retrieving security state for a DIMM and also
adding support to ndctl list for displaying security state.

Signed-off-by: Dave Jiang 
---
 Documentation/ndctl/ndctl-list.txt |8 
 ndctl/lib/dimm.c   |   37 
 ndctl/lib/libndctl.sym |5 +
 ndctl/libndctl.h   |   13 +
 util/json.c|   31 ++
 5 files changed, 94 insertions(+)

diff --git a/Documentation/ndctl/ndctl-list.txt 
b/Documentation/ndctl/ndctl-list.txt
index e24c8f40..bdd69add 100644
--- a/Documentation/ndctl/ndctl-list.txt
+++ b/Documentation/ndctl/ndctl-list.txt
@@ -98,6 +98,14 @@ include::xable-region-options.txt[]
 -D::
 --dimms::
Include dimm info in the listing
+[verse]
+{
+  "dev":"nmem0",
+  "id":"cdab-0a-07e0-",
+  "handle":0,
+  "phys_id":0,
+  "security:":"disabled"
+}
 
 -H::
 --health::
diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 79e2ca0a..e03135d9 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -587,3 +587,40 @@ NDCTL_EXPORT unsigned long ndctl_dimm_get_available_labels(
 
return strtoul(buf, NULL, 0);
 }
+
+NDCTL_EXPORT int ndctl_dimm_get_security(struct ndctl_dimm *dimm,
+   enum nd_security_state *state)
+{
+   struct ndctl_ctx *ctx = ndctl_dimm_get_ctx(dimm);
+   char *path = dimm->dimm_buf;
+   int len = dimm->buf_len;
+   char buf[64];
+   int rc;
+
+   if (snprintf(path, len, "%s/security", dimm->dimm_path) >= len) {
+   err(ctx, "%s: buffer too small!\n",
+   ndctl_dimm_get_devname(dimm));
+   return -ERANGE;
+   }
+
+   rc = sysfs_read_attr(ctx, path, buf);
+   if (rc < 0)
+   return rc;
+
+   if (strcmp(buf, "unsupported") == 0)
+   *state = ND_SECURITY_UNSUPPORTED;
+   else if (strcmp(buf, "disabled") == 0)
+   *state = ND_SECURITY_DISABLED;
+   else if (strcmp(buf, "unlocked") == 0)
+   *state = ND_SECURITY_UNLOCKED;
+   else if (strcmp(buf, "locked") == 0)
+   *state = ND_SECURITY_LOCKED;
+   else if (strcmp(buf, "frozen") == 0)
+   *state = ND_SECURITY_FROZEN;
+   else if (strcmp(buf, "overwrite") == 0)
+   *state = ND_SECURITY_OVERWRITE;
+   else
+   *state = ND_SECURITY_INVALID;
+
+   return 0;
+}
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 6c4c8b4d..1bd63fa1 100644
--- a/ndctl/lib/libndctl.sym
+++ b/ndctl/lib/libndctl.sym
@@ -385,3 +385,8 @@ global:
ndctl_namespace_get_next_badblock;
ndctl_dimm_get_dirty_shutdown;
 } LIBNDCTL_17;
+
+LIBNDCTL_19 {
+global:
+   ndctl_dimm_get_security;
+} LIBNDCTL_18;
diff --git a/ndctl/libndctl.h b/ndctl/libndctl.h
index c81cc032..4255252c 100644
--- a/ndctl/libndctl.h
+++ b/ndctl/libndctl.h
@@ -681,6 +681,19 @@ enum ND_FW_STATUS ndctl_cmd_fw_xlat_firmware_status(struct 
ndctl_cmd *cmd);
 struct ndctl_cmd *ndctl_dimm_cmd_new_ack_shutdown_count(struct ndctl_dimm 
*dimm);
 int ndctl_dimm_fw_update_supported(struct ndctl_dimm *dimm);
 
+enum nd_security_state {
+   ND_SECURITY_INVALID = -1,
+   ND_SECURITY_UNSUPPORTED = 0,
+   ND_SECURITY_DISABLED,
+   ND_SECURITY_UNLOCKED,
+   ND_SECURITY_LOCKED,
+   ND_SECURITY_FROZEN,
+   ND_SECURITY_OVERWRITE,
+};
+
+int ndctl_dimm_get_security(struct ndctl_dimm *dimm,
+   enum nd_security_state *sstate);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
diff --git a/util/json.c b/util/json.c
index 5c3424e2..e3b9e72e 100644
--- a/util/json.c
+++ b/util/json.c
@@ -164,6 +164,7 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
unsigned int handle = ndctl_dimm_get_handle(dimm);
unsigned short phys_id = ndctl_dimm_get_phys_id(dimm);
struct json_object *jobj;
+   enum nd_security_state sstate;
 
if (!jdimm)
return NULL;
@@ -243,6 +244,36 @@ struct json_object *util_dimm_to_json(struct ndctl_dimm 
*dimm,
json_object_object_add(jdimm, "flag_smart_event", jobj);
}
 
+   if (ndctl_dimm_get_security(dimm, &sstate) == 0) {
+   switch (sstate) {
+   case ND_SECURITY_UNSUPPORTED:
+   jobj = json_object_new_string("unsupported");
+   break;
+   case ND_SECURITY_DISABLED:
+   jobj = json_object_new_string("disabled");
+   break;
+   case ND_SECURITY_UNLOCKED:
+   jobj = json_object_new_string("unlocked");
+   break;
+   case ND_SECURITY_LOCKED:
+   jobj = json_object_new_string("locked");
+   break;
+   case ND_SECURITY_FROZEN:
+   jobj = json_object_new_string("frozen");
+

Re: [ndctl PATCH v3 4/4] ndctl: clean up usage of ndctl_cmd_submit

2019-01-14 Thread Dan Williams
On Mon, Jan 14, 2019 at 10:49 AM Vishal Verma  wrote:
[..]
> I see how it can be replaced now. Here is a revised patch 4 that
> includes thses conversions:
>
> 8<
>
>
> From 5c19c269dd0037c3f68725e0f721784056172433 Mon Sep 17 00:00:00 2001
> From: Vishal Verma 
> Date: Fri, 11 Jan 2019 18:20:31 -0700
> Subject: [ndctl PATCH] ndctl: clean up usage of ndctl_cmd_submit
>
> It is possible for ndctl_cmd_submit to return a positive number,
> indicating a buffer underrun. It is only truly an error if it returns a
> negative number. Several places in the library, the ndctl utility, and
> in test/ were simply checking for an error with "if (rc)". Fix these to
> only error out for negative returns.
>
> Cc: Dan Williams 
> Signed-off-by: Vishal Verma 

Looks good to me. For the series:

Reviewed-by: Dan Williams 
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [ndctl PATCH v3 4/4] ndctl: clean up usage of ndctl_cmd_submit

2019-01-14 Thread Vishal Verma
On 01/14, Verma, Vishal L wrote:
> 
> On Mon, 2019-01-14 at 10:17 -0800, Dan Williams wrote:
> > On Mon, Jan 14, 2019 at 10:11 AM Vishal Verma <
> > vishal.l.ve...@intel.com> wrote:
> > > 
> > > It is possible for ndctl_cmd_submit to return a positive number,
> > > indicating a buffer underrun. It is only truly an error if it
> > > returns a
> > > negative number. Several places in the library, the ndctl utility,
> > > and
> > > in test/ were simply checking for an error with "if (rc)". Fix
> > > these to
> > > only error out for negative returns.
> > > 
> > > Cc: Dan Williams 
> > > Signed-off-by: Vishal Verma 
> > > ---
> > >  ndctl/lib/dimm.c  |  6 +++---
> > >  ndctl/lib/inject.c|  8 
> > >  ndctl/lib/nfit.c  |  2 +-
> > >  ndctl/util/json-firmware.c|  2 +-
> > >  test/ack-shutdown-count-set.c |  8 ++--
> > >  test/daxdev-errors.c  |  8 
> > >  test/libndctl.c   | 32 ---
> > > -
> > >  test/smart-notify.c   |  8 
> > >  8 files changed, 35 insertions(+), 39 deletions(-)
> > > 
> > > diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
> > > index 79e2ca0..12dc74a 100644
> > > --- a/ndctl/lib/dimm.c
> > > +++ b/ndctl/lib/dimm.c
> > > @@ -332,7 +332,7 @@ static int nvdimm_set_config_data(struct
> > > nvdimm_data *ndd, size_t offset,
> > > goto out;
> > > 
> > > rc = ndctl_cmd_submit(cmd_write);
> > > -   if (rc || ndctl_cmd_get_firmware_status(cmd_write))
> > > +   if ((rc < 0) || ndctl_cmd_get_firmware_status(cmd_write))
> > 
> > With ndctl_cmd_submit_xlat() the ndctl_cmd_get_firmware_status() can
> > be dropped, right?
> > 
> > rc = ndctl_cmd_submit_xlat(cmd_write);
> > if (rc < 0)
> > rc = -ENXIO;
> > 
> > 
> > ...or are you saving that conversion for a follow on patch?
> 
> The config get/write commands are not dimm_ops right? I thought we
> could only use _xlat for dimm_ops?

I see how it can be replaced now. Here is a revised patch 4 that
includes thses conversions:

8<


>From 5c19c269dd0037c3f68725e0f721784056172433 Mon Sep 17 00:00:00 2001
From: Vishal Verma 
Date: Fri, 11 Jan 2019 18:20:31 -0700
Subject: [ndctl PATCH] ndctl: clean up usage of ndctl_cmd_submit

It is possible for ndctl_cmd_submit to return a positive number,
indicating a buffer underrun. It is only truly an error if it returns a
negative number. Several places in the library, the ndctl utility, and
in test/ were simply checking for an error with "if (rc)". Fix these to
only error out for negative returns.

Cc: Dan Williams 
Signed-off-by: Vishal Verma 
---
 ndctl/lib/dimm.c  | 18 +++---
 ndctl/lib/inject.c|  8 
 ndctl/lib/nfit.c  |  2 +-
 ndctl/util/json-firmware.c|  2 +-
 test/ack-shutdown-count-set.c |  8 ++--
 test/daxdev-errors.c  |  8 
 test/libndctl.c   | 32 
 test/smart-notify.c   |  8 
 8 files changed, 39 insertions(+), 47 deletions(-)

diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 79e2ca0..f5a955e 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -331,8 +331,8 @@ static int nvdimm_set_config_data(struct nvdimm_data *ndd, 
size_t offset,
if (rc < 0)
goto out;
 
-   rc = ndctl_cmd_submit(cmd_write);
-   if (rc || ndctl_cmd_get_firmware_status(cmd_write))
+   rc = ndctl_cmd_submit_xlat(cmd_write);
+   if (rc < 0)
rc = -ENXIO;
  out:
ndctl_cmd_unref(cmd_write);
@@ -487,15 +487,15 @@ NDCTL_EXPORT struct ndctl_cmd 
*ndctl_dimm_read_labels(struct ndctl_dimm *dimm)
 cmd_size = ndctl_dimm_cmd_new_cfg_size(dimm);
 if (!cmd_size)
 return NULL;
-rc = ndctl_cmd_submit(cmd_size);
-if (rc || ndctl_cmd_get_firmware_status(cmd_size))
+rc = ndctl_cmd_submit_xlat(cmd_size);
+if (rc < 0)
 goto out_size;
 
 cmd_read = ndctl_dimm_cmd_new_cfg_read(cmd_size);
 if (!cmd_read)
 goto out_size;
-rc = ndctl_cmd_submit(cmd_read);
-if (rc || ndctl_cmd_get_firmware_status(cmd_read))
+rc = ndctl_cmd_submit_xlat(cmd_read);
+if (rc < 0)
 goto out_read;
ndctl_cmd_unref(cmd_size);
 
@@ -536,13 +536,9 @@ NDCTL_EXPORT int ndctl_dimm_zero_labels(struct ndctl_dimm 
*dimm)
rc = -ENXIO;
goto out_write;
}
-   rc = ndctl_cmd_submit(cmd_write);
+   rc = ndctl_cmd_submit_xlat(cmd_write);
if (rc < 0)
goto out_write;
-   if (ndctl_cmd_get_firmware_status(cmd_write)) {
-   rc = -ENXIO;
-   goto out_write;
-   }
 
/*
 * If the dimm is already disabled the kernel is not holding a cached
diff --git a/ndctl/lib/inject.c b/ndctl/lib/inject.c
index 2b0702e..c35d0f3 100644
--- a/ndctl/lib/inject.c
+++ b/ndctl

Re: [ndctl PATCH v3 4/4] ndctl: clean up usage of ndctl_cmd_submit

2019-01-14 Thread Verma, Vishal L


On Mon, 2019-01-14 at 10:17 -0800, Dan Williams wrote:
> On Mon, Jan 14, 2019 at 10:11 AM Vishal Verma <
> vishal.l.ve...@intel.com> wrote:
> > 
> > It is possible for ndctl_cmd_submit to return a positive number,
> > indicating a buffer underrun. It is only truly an error if it
> > returns a
> > negative number. Several places in the library, the ndctl utility,
> > and
> > in test/ were simply checking for an error with "if (rc)". Fix
> > these to
> > only error out for negative returns.
> > 
> > Cc: Dan Williams 
> > Signed-off-by: Vishal Verma 
> > ---
> >  ndctl/lib/dimm.c  |  6 +++---
> >  ndctl/lib/inject.c|  8 
> >  ndctl/lib/nfit.c  |  2 +-
> >  ndctl/util/json-firmware.c|  2 +-
> >  test/ack-shutdown-count-set.c |  8 ++--
> >  test/daxdev-errors.c  |  8 
> >  test/libndctl.c   | 32 ---
> > -
> >  test/smart-notify.c   |  8 
> >  8 files changed, 35 insertions(+), 39 deletions(-)
> > 
> > diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
> > index 79e2ca0..12dc74a 100644
> > --- a/ndctl/lib/dimm.c
> > +++ b/ndctl/lib/dimm.c
> > @@ -332,7 +332,7 @@ static int nvdimm_set_config_data(struct
> > nvdimm_data *ndd, size_t offset,
> > goto out;
> > 
> > rc = ndctl_cmd_submit(cmd_write);
> > -   if (rc || ndctl_cmd_get_firmware_status(cmd_write))
> > +   if ((rc < 0) || ndctl_cmd_get_firmware_status(cmd_write))
> 
> With ndctl_cmd_submit_xlat() the ndctl_cmd_get_firmware_status() can
> be dropped, right?
> 
> rc = ndctl_cmd_submit_xlat(cmd_write);
> if (rc < 0)
> rc = -ENXIO;
> 
> 
> ...or are you saving that conversion for a follow on patch?

The config get/write commands are not dimm_ops right? I thought we
could only use _xlat for dimm_ops?


___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [ndctl PATCH v3 4/4] ndctl: clean up usage of ndctl_cmd_submit

2019-01-14 Thread Dan Williams
On Mon, Jan 14, 2019 at 10:11 AM Vishal Verma  wrote:
>
> It is possible for ndctl_cmd_submit to return a positive number,
> indicating a buffer underrun. It is only truly an error if it returns a
> negative number. Several places in the library, the ndctl utility, and
> in test/ were simply checking for an error with "if (rc)". Fix these to
> only error out for negative returns.
>
> Cc: Dan Williams 
> Signed-off-by: Vishal Verma 
> ---
>  ndctl/lib/dimm.c  |  6 +++---
>  ndctl/lib/inject.c|  8 
>  ndctl/lib/nfit.c  |  2 +-
>  ndctl/util/json-firmware.c|  2 +-
>  test/ack-shutdown-count-set.c |  8 ++--
>  test/daxdev-errors.c  |  8 
>  test/libndctl.c   | 32 
>  test/smart-notify.c   |  8 
>  8 files changed, 35 insertions(+), 39 deletions(-)
>
> diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
> index 79e2ca0..12dc74a 100644
> --- a/ndctl/lib/dimm.c
> +++ b/ndctl/lib/dimm.c
> @@ -332,7 +332,7 @@ static int nvdimm_set_config_data(struct nvdimm_data 
> *ndd, size_t offset,
> goto out;
>
> rc = ndctl_cmd_submit(cmd_write);
> -   if (rc || ndctl_cmd_get_firmware_status(cmd_write))
> +   if ((rc < 0) || ndctl_cmd_get_firmware_status(cmd_write))

With ndctl_cmd_submit_xlat() the ndctl_cmd_get_firmware_status() can
be dropped, right?

rc = ndctl_cmd_submit_xlat(cmd_write);
if (rc < 0)
rc = -ENXIO;


...or are you saving that conversion for a follow on patch?
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[ndctl PATCH v3 0/4] Add missing firmware_status checks

2019-01-14 Thread Vishal Verma
Changes in v3:
- Patch 2: Also fix open coded get_firmware_status (Dan)
- Patch 4: Change rc to an int as it is only used for the return status
  of cmd_submit.
- Patch 4: Fix another open coded get_firmware_status in
  test/ack-shutdown-count-set.c

Changes in v2:
- For the new helper, return original positive rc when we can (Dan)
- Convert previously missed locations to the new submission helper
  (patch 2)
- Add a new patch (4/4) to fix up all callers of ndctl_cmd_submit to
  the correct return convention.

There were several places in ndctl where we neglected to check the
firmware_status from a command submission.

Add an ndctl_dimm_op target to perform error translation for a DSM
family, and provide a new helper - ndctl_cmd_submit_xlat - that will
submit the command and call an error translation routine if one has been
registered. Switch the call sites in ndctl/inject-smart.c and
ndctl/monitor.c over to the new command submission helper.

Finally, clean up all remaining callers of ndctl_cmd_submit to use the
correct return convention, i.e. only treat negative returns as an error,
and accept positive return codes as OK.

Vishal Verma (4):
  libndctl, intel: Add infrastructure for firmware_status translation
  ndctl, inject-smart: switch to ndctl_cmd_submit_xlat
  ndctl, monitor: switch to ndctl_cmd_submit_xlat
  ndctl: clean up usage of ndctl_cmd_submit

 ndctl/inject-smart.c  | 16 ++--
 ndctl/lib/dimm.c  |  6 ++---
 ndctl/lib/inject.c|  8 +++---
 ndctl/lib/intel.c | 49 +++
 ndctl/lib/intel.h |  1 +
 ndctl/lib/libndctl.c  | 28 
 ndctl/lib/libndctl.sym|  6 +
 ndctl/lib/nfit.c  |  2 +-
 ndctl/lib/private.h   |  1 +
 ndctl/libndctl.h  |  3 +++
 ndctl/monitor.c   |  6 ++---
 ndctl/util/json-firmware.c|  2 +-
 ndctl/util/json-smart.c   |  8 +++---
 test/ack-shutdown-count-set.c |  8 ++
 test/daxdev-errors.c  |  8 +++---
 test/libndctl.c   | 32 +++
 test/smart-notify.c   |  8 +++---
 17 files changed, 138 insertions(+), 54 deletions(-)

-- 
2.17.2

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[ndctl PATCH v3 3/4] ndctl, monitor: switch to ndctl_cmd_submit_xlat

2019-01-14 Thread Vishal Verma
The ndctl monitor command was neglecting to check the 'firmware_status'
field that is set by the platform firmware to indicate failure. Use
the new ndctl_cmd_submit_xlat facility to include the firmware_status
check as part of the command submission.

Cc: QI Fuli 
Cc: Dan Williams 
Signed-off-by: Vishal Verma 
---
 ndctl/monitor.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/ndctl/monitor.c b/ndctl/monitor.c
index 233f2bb..4ad1429 100644
--- a/ndctl/monitor.c
+++ b/ndctl/monitor.c
@@ -226,7 +226,7 @@ static int enable_dimm_supported_threshold_alarms(struct 
ndctl_dimm *dimm)
err(&monitor, "%s: no smart threshold command support\n", name);
goto out;
}
-   if (ndctl_cmd_submit(st_cmd)) {
+   if (ndctl_cmd_submit_xlat(st_cmd) < 0) {
err(&monitor, "%s: smart threshold command failed\n", name);
goto out;
}
@@ -246,8 +246,8 @@ static int enable_dimm_supported_threshold_alarms(struct 
ndctl_dimm *dimm)
alarm |= ND_SMART_CTEMP_TRIP;
ndctl_cmd_smart_threshold_set_alarm_control(sst_cmd, alarm);
 
-   rc = ndctl_cmd_submit(sst_cmd);
-   if (rc) {
+   rc = ndctl_cmd_submit_xlat(sst_cmd);
+   if (rc < 0) {
err(&monitor, "%s: smart set threshold command failed\n", name);
goto out;
}
-- 
2.17.2

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[ndctl PATCH v3 1/4] libndctl, intel: Add infrastructure for firmware_status translation

2019-01-14 Thread Vishal Verma
Add a new routine to ndctl_dimm_ops that allows a DSM family to provide
a translation routine that will translate the status codes of the result
of a DSM to generic errno style error codes. To use this routine
effectively, add a new wrapper around ndctl_cmd_submit (called
ndctl_cmd_submit_xlat) that submits the command, and also runs it
through the above translator dimm_op (if one is is defined).

Cc: Dan Williams 
Signed-off-by: Vishal Verma 
---
 ndctl/lib/intel.c  | 49 ++
 ndctl/lib/intel.h  |  1 +
 ndctl/lib/libndctl.c   | 28 
 ndctl/lib/libndctl.sym |  6 ++
 ndctl/lib/private.h|  1 +
 ndctl/libndctl.h   |  3 +++
 6 files changed, 88 insertions(+)

diff --git a/ndctl/lib/intel.c b/ndctl/lib/intel.c
index 744386f..d684bac 100644
--- a/ndctl/lib/intel.c
+++ b/ndctl/lib/intel.c
@@ -16,6 +16,54 @@
 #include 
 #include "private.h"
 
+static int intel_cmd_xlat_firmware_status(struct ndctl_cmd *cmd)
+{
+   struct nd_pkg_intel *pkg = cmd->intel;
+   unsigned int status, ext_status;
+
+   status = (*cmd->firmware_status) & ND_INTEL_STATUS_MASK;
+   ext_status = (*cmd->firmware_status) & ND_INTEL_STATUS_EXTEND_MASK;
+
+   /* Common statuses */
+   switch (status) {
+   case ND_INTEL_STATUS_SUCCESS:
+   return 0;
+   case ND_INTEL_STATUS_NOTSUPP:
+   return -EOPNOTSUPP;
+   case ND_INTEL_STATUS_NOTEXIST:
+   return -ENXIO;
+   case ND_INTEL_STATUS_INVALPARM:
+   return -EINVAL;
+   case ND_INTEL_STATUS_HWERR:
+   return -EIO;
+   case ND_INTEL_STATUS_RETRY:
+   return -EAGAIN;
+   case ND_INTEL_STATUS_EXTEND:
+   /* refer to extended status, break out of this */
+   break;
+   case ND_INTEL_STATUS_NORES:
+   return -EAGAIN;
+   case ND_INTEL_STATUS_NOTREADY:
+   return -EBUSY;
+   }
+
+   /* Extended status is command specific */
+   switch (pkg->gen.nd_command) {
+   case ND_INTEL_SMART:
+   case ND_INTEL_SMART_THRESHOLD:
+   case ND_INTEL_SMART_SET_THRESHOLD:
+   /* ext status not specified */
+   break;
+   case ND_INTEL_SMART_INJECT:
+   /* smart injection not enabled */
+   if (ext_status == ND_INTEL_STATUS_INJ_DISABLED)
+   return -ENXIO;
+   break;
+   }
+
+   return -ENOMSG;
+}
+
 static struct ndctl_cmd *alloc_intel_cmd(struct ndctl_dimm *dimm,
unsigned func, size_t in_size, size_t out_size)
 {
@@ -780,4 +828,5 @@ struct ndctl_dimm_ops * const intel_dimm_ops = &(struct 
ndctl_dimm_ops) {
.fw_xlat_firmware_status = intel_cmd_fw_xlat_firmware_status,
.new_ack_shutdown_count = intel_dimm_cmd_new_lss,
.fw_update_supported = intel_dimm_fw_update_supported,
+   .xlat_firmware_status = intel_cmd_xlat_firmware_status,
 };
diff --git a/ndctl/lib/intel.h b/ndctl/lib/intel.h
index 3b01bba..530c996 100644
--- a/ndctl/lib/intel.h
+++ b/ndctl/lib/intel.h
@@ -179,5 +179,6 @@ struct nd_pkg_intel {
 #define ND_INTEL_STATUS_FQ_BUSY0x2
 #define ND_INTEL_STATUS_FQ_BAD 0x3
 #define ND_INTEL_STATUS_FQ_ORDER   0x4
+#define ND_INTEL_STATUS_INJ_DISABLED   0x1
 
 #endif /* __INTEL_H__ */
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index e82a08d..830b791 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -2704,6 +2704,16 @@ static const char *ndctl_dimm_get_cmd_subname(struct 
ndctl_cmd *cmd)
return ops->cmd_desc(cmd->pkg->nd_command);
 }
 
+NDCTL_EXPORT int ndctl_cmd_xlat_firmware_status(struct ndctl_cmd *cmd)
+{
+   struct ndctl_dimm *dimm = cmd->dimm;
+   struct ndctl_dimm_ops *ops = dimm ? dimm->ops : NULL;
+
+   if (!dimm || !ops || !ops->xlat_firmware_status)
+   return -ENOMSG;
+   return ops->xlat_firmware_status(cmd);
+}
+
 static int do_cmd(int fd, int ioctl_cmd, struct ndctl_cmd *cmd)
 {
int rc;
@@ -2819,6 +2829,24 @@ NDCTL_EXPORT int ndctl_cmd_submit(struct ndctl_cmd *cmd)
return rc;
 }
 
+NDCTL_EXPORT int ndctl_cmd_submit_xlat(struct ndctl_cmd *cmd)
+{
+   int rc, xlat_rc;
+
+   rc = ndctl_cmd_submit(cmd);
+   if (rc < 0)
+   return rc;
+
+   /*
+* NOTE: This can lose a positive rc when xlat_rc is non-zero. The
+* positive rc indicates a buffer underrun from the original command
+* submission. If the caller cares about that (generally not very
+* useful), then the xlat function is available separately as well.
+*/
+   xlat_rc = ndctl_cmd_xlat_firmware_status(cmd);
+   return (xlat_rc == 0) ? rc : xlat_rc;
+}
+
 NDCTL_EXPORT int ndctl_cmd_get_status(struct ndctl_cmd *cmd)
 {
return cmd->status;
diff --git a/ndctl/lib/libndctl.sym b/ndctl/lib/libndctl.sym
index 6c4c8b4..275db92 100644
--- a/ndctl/lib/l

[ndctl PATCH v3 2/4] ndctl, inject-smart: switch to ndctl_cmd_submit_xlat

2019-01-14 Thread Vishal Verma
The ndctl inject-smart command was neglecting to check the
'firmware_status' field that is set by the platform firmware to indicate
failure. Use the new ndctl_cmd_submit_xlat facility to include the
firmware_status check as part of the command submission.

Reported-by: Ami Pathak 
Cc: Dan Williams 
Signed-off-by: Vishal Verma 
---
 ndctl/inject-smart.c| 16 
 ndctl/util/json-smart.c |  8 
 2 files changed, 12 insertions(+), 12 deletions(-)

diff --git a/ndctl/inject-smart.c b/ndctl/inject-smart.c
index eaa137a..00c81b8 100644
--- a/ndctl/inject-smart.c
+++ b/ndctl/inject-smart.c
@@ -280,8 +280,8 @@ static int smart_set_thresh(struct ndctl_dimm *dimm)
goto out;
}
 
-   rc = ndctl_cmd_submit(st_cmd);
-   if (rc) {
+   rc = ndctl_cmd_submit_xlat(st_cmd);
+   if (rc < 0) {
error("%s: smart threshold command failed: %s (%d)\n",
name, strerror(abs(rc)), rc);
goto out;
@@ -320,8 +320,8 @@ static int smart_set_thresh(struct ndctl_dimm *dimm)
ndctl_cmd_smart_threshold_set_alarm_control(sst_cmd, alarm);
}
 
-   rc = ndctl_cmd_submit(sst_cmd);
-   if (rc)
+   rc = ndctl_cmd_submit_xlat(sst_cmd);
+   if (rc < 0)
error("%s: smart set threshold command failed: %s (%d)\n",
name, strerror(abs(rc)), rc);
 
@@ -351,8 +351,8 @@ out:
if (sctx.err_continue == false) \
goto out; \
} \
-   rc = ndctl_cmd_submit(si_cmd); \
-   if (rc) { \
+   rc = ndctl_cmd_submit_xlat(si_cmd); \
+   if (rc < 0) { \
error("%s: smart inject %s command failed: %s (%d)\n", \
name, #arg, strerror(abs(rc)), rc); \
if (sctx.err_continue == false) \
@@ -382,8 +382,8 @@ out:
if (sctx.err_continue == false) \
goto out; \
} \
-   rc = ndctl_cmd_submit(si_cmd); \
-   if (rc) { \
+   rc = ndctl_cmd_submit_xlat(si_cmd); \
+   if (rc < 0) { \
error("%s: smart inject %s command failed: %s (%d)\n", \
name, #arg, strerror(abs(rc)), rc); \
if (sctx.err_continue == false) \
diff --git a/ndctl/util/json-smart.c b/ndctl/util/json-smart.c
index 3c1b917..a9bd17b 100644
--- a/ndctl/util/json-smart.c
+++ b/ndctl/util/json-smart.c
@@ -30,8 +30,8 @@ static void smart_threshold_to_json(struct ndctl_dimm *dimm,
if (!cmd)
return;
 
-   rc = ndctl_cmd_submit(cmd);
-   if (rc || ndctl_cmd_get_firmware_status(cmd))
+   rc = ndctl_cmd_submit_xlat(cmd);
+   if (rc < 0)
goto out;
 
alarm_control = ndctl_cmd_smart_threshold_get_alarm_control(cmd);
@@ -115,8 +115,8 @@ struct json_object *util_dimm_health_to_json(struct 
ndctl_dimm *dimm)
if (!cmd)
goto err;
 
-   rc = ndctl_cmd_submit(cmd);
-   if (rc || ndctl_cmd_get_firmware_status(cmd)) {
+   rc = ndctl_cmd_submit_xlat(cmd);
+   if (rc < 0) {
jobj = json_object_new_string("unknown");
if (jobj)
json_object_object_add(jhealth, "health_state", jobj);
-- 
2.17.2

___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


[ndctl PATCH v3 4/4] ndctl: clean up usage of ndctl_cmd_submit

2019-01-14 Thread Vishal Verma
It is possible for ndctl_cmd_submit to return a positive number,
indicating a buffer underrun. It is only truly an error if it returns a
negative number. Several places in the library, the ndctl utility, and
in test/ were simply checking for an error with "if (rc)". Fix these to
only error out for negative returns.

Cc: Dan Williams 
Signed-off-by: Vishal Verma 
---
 ndctl/lib/dimm.c  |  6 +++---
 ndctl/lib/inject.c|  8 
 ndctl/lib/nfit.c  |  2 +-
 ndctl/util/json-firmware.c|  2 +-
 test/ack-shutdown-count-set.c |  8 ++--
 test/daxdev-errors.c  |  8 
 test/libndctl.c   | 32 
 test/smart-notify.c   |  8 
 8 files changed, 35 insertions(+), 39 deletions(-)

diff --git a/ndctl/lib/dimm.c b/ndctl/lib/dimm.c
index 79e2ca0..12dc74a 100644
--- a/ndctl/lib/dimm.c
+++ b/ndctl/lib/dimm.c
@@ -332,7 +332,7 @@ static int nvdimm_set_config_data(struct nvdimm_data *ndd, 
size_t offset,
goto out;
 
rc = ndctl_cmd_submit(cmd_write);
-   if (rc || ndctl_cmd_get_firmware_status(cmd_write))
+   if ((rc < 0) || ndctl_cmd_get_firmware_status(cmd_write))
rc = -ENXIO;
  out:
ndctl_cmd_unref(cmd_write);
@@ -488,14 +488,14 @@ NDCTL_EXPORT struct ndctl_cmd 
*ndctl_dimm_read_labels(struct ndctl_dimm *dimm)
 if (!cmd_size)
 return NULL;
 rc = ndctl_cmd_submit(cmd_size);
-if (rc || ndctl_cmd_get_firmware_status(cmd_size))
+if ((rc < 0) || ndctl_cmd_get_firmware_status(cmd_size))
 goto out_size;
 
 cmd_read = ndctl_dimm_cmd_new_cfg_read(cmd_size);
 if (!cmd_read)
 goto out_size;
 rc = ndctl_cmd_submit(cmd_read);
-if (rc || ndctl_cmd_get_firmware_status(cmd_read))
+if ((rc < 0) || ndctl_cmd_get_firmware_status(cmd_read))
 goto out_read;
ndctl_cmd_unref(cmd_size);
 
diff --git a/ndctl/lib/inject.c b/ndctl/lib/inject.c
index 2b0702e..c35d0f3 100644
--- a/ndctl/lib/inject.c
+++ b/ndctl/lib/inject.c
@@ -156,7 +156,7 @@ static int ndctl_namespace_inject_one_error(struct 
ndctl_namespace *ndns,
(1 << ND_ARS_ERR_INJ_OPT_NOTIFY);
 
rc = ndctl_cmd_submit(cmd);
-   if (rc) {
+   if (rc < 0) {
dbg(ctx, "Error submitting command: %d\n", rc);
goto out;
}
@@ -234,7 +234,7 @@ static int ndctl_namespace_uninject_one_error(struct 
ndctl_namespace *ndns,
err_inj_clr->err_inj_clr_spa_range_length = length;
 
rc = ndctl_cmd_submit(cmd);
-   if (rc) {
+   if (rc < 0) {
dbg(ctx, "Error submitting command: %d\n", rc);
goto out;
}
@@ -443,7 +443,7 @@ NDCTL_EXPORT int ndctl_namespace_injection_status(struct 
ndctl_namespace *ndns)
 
cmd = ndctl_bus_cmd_new_ars_cap(bus, ns_offset, ns_size);
rc = ndctl_cmd_submit(cmd);
-   if (rc) {
+   if (rc < 0) {
dbg(ctx, "Error submitting ars_cap: %d\n", rc);
goto out;
}
@@ -464,7 +464,7 @@ NDCTL_EXPORT int ndctl_namespace_injection_status(struct 
ndctl_namespace *ndns)
(struct nd_cmd_ars_err_inj_stat *)&pkg->nd_payload[0];
 
rc = ndctl_cmd_submit(cmd);
-   if (rc) {
+   if (rc < 0) {
dbg(ctx, "Error submitting command: %d\n", rc);
goto out;
}
diff --git a/ndctl/lib/nfit.c b/ndctl/lib/nfit.c
index 2ae3f07..b10edb1 100644
--- a/ndctl/lib/nfit.c
+++ b/ndctl/lib/nfit.c
@@ -133,7 +133,7 @@ int ndctl_bus_nfit_translate_spa(struct ndctl_bus *bus,
translate_spa->spa = address;
 
rc = ndctl_cmd_submit(cmd);
-   if (rc) {
+   if (rc < 0) {
ndctl_cmd_unref(cmd);
return rc;
}
diff --git a/ndctl/util/json-firmware.c b/ndctl/util/json-firmware.c
index 118424f..f7150d8 100644
--- a/ndctl/util/json-firmware.c
+++ b/ndctl/util/json-firmware.c
@@ -25,7 +25,7 @@ struct json_object *util_dimm_firmware_to_json(struct 
ndctl_dimm *dimm,
goto err;
 
rc = ndctl_cmd_submit(cmd);
-   if (rc || ndctl_cmd_fw_xlat_firmware_status(cmd) != FW_SUCCESS) {
+   if ((rc < 0) || ndctl_cmd_fw_xlat_firmware_status(cmd) != FW_SUCCESS) {
jobj = util_json_object_hex(-1, flags);
if (jobj)
json_object_object_add(jfirmware, "current_version",
diff --git a/test/ack-shutdown-count-set.c b/test/ack-shutdown-count-set.c
index 9baa2f1..742e976 100644
--- a/test/ack-shutdown-count-set.c
+++ b/test/ack-shutdown-count-set.c
@@ -27,12 +27,8 @@ static int test_dimm(struct ndctl_dimm *dimm)
if (!cmd)
return -ENOMEM;
 
-   rc = ndctl_cmd_submit(cmd);
-   if (rc < 0)
-   goto out;
-

Re: [PATCH] acpi/nfit: Fix command-supported detection

2019-01-14 Thread Dan Williams
On Mon, Jan 14, 2019 at 8:43 AM Dan Williams  wrote:
> On Mon, Jan 14, 2019 at 7:19 AM Jeff Moyer  wrote:
[..]
> > > +
> > > + if (cmd == ND_CMD_CALL) {
> > > + int i;
> > > +
> > > + if (call_pkg && nfit_mem->family != call_pkg->nd_family)
> > > + return -ENOTTY;
> > > +
> > > + for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
> > > + if (call_pkg->nd_reserved2[i])
> > > + return -EINVAL;
> > > + return call_pkg->nd_command;
> > > + }
> > > +
> > > + /* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
> > > + if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
> > > + return cmd;
> > > + return 0;
> >
> > Function zero?  Is that really the right thing to return here?
>
> Yes, function zero is never set in n

...whoops fumble fingered "send"

Function zero should never be set in nfit_mem->dsm_mask, although the
NVDIMM_FAMILY_MSFT mask violates this assumption. I'll fix that up.
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH] acpi/nfit: Fix command-supported detection

2019-01-14 Thread Dan Williams
On Mon, Jan 14, 2019 at 7:19 AM Jeff Moyer  wrote:
>
> Dan Williams  writes:
>
> > The _DSM function number validation only happens to succeed when the
> > generic Linux command number translation corresponds with a
> > DSM-family-specific function number. This breaks NVDIMM-N
> > implementations that correctly implement _LSR, _LSW, and _LSI, but do
> > not happen to publish support for DSM function numbers 4, 5, and 6.
> >
> > Recall that the support for _LS{I,R,W} family of methods results in the
> > DIMM being marked as supporting those command numbers at
> > acpi_nfit_register_dimms() time. The DSM function mask is only used for
> > ND_CMD_CALL support of non-NVDIMM_FAMILY_INTEL devices.
> >
> > Fixes: 31eca76ba2fc ("nfit, libnvdimm: limited/whitelisted dimm command...")
> > Cc: 
> > Link: https://github.com/pmem/ndctl/issues/78
> > Reported-by: Sujith Pandel 
> > Signed-off-by: Dan Williams 
> > ---
> > Sujith, this is a larger change than what you originally tested, but it
> > should behave the same. I wanted to consolidate all the code that
> > handles Linux command number to DIMM _DSM function number translation.
> >
> > If you have a chance to re-test with this it would be much appreciated.
> >
> > Thanks for the report!
> >
> >  drivers/acpi/nfit/core.c |   43 +--
> >  1 file changed, 29 insertions(+), 14 deletions(-)
> >
> > diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
> > index 790691d9a982..d5d64e90ae71 100644
> > --- a/drivers/acpi/nfit/core.c
> > +++ b/drivers/acpi/nfit/core.c
> > @@ -409,6 +409,29 @@ static bool payload_dumpable(struct nvdimm *nvdimm, 
> > unsigned int func)
> >   return true;
> >  }
> >
> > +static int cmd_to_func(struct nvdimm *nvdimm, unsigned int cmd,
> > + struct nd_cmd_pkg *call_pkg)
> > +{
> > + struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
>
> Minor nit: Seems like the function could take an nfit_mem parameter instead 
> of an nvdimm.

I was making it symmetric with payload_dumpable()... but not for any
good reason, will change.

>
> > +
> > + if (cmd == ND_CMD_CALL) {
> > + int i;
> > +
> > + if (call_pkg && nfit_mem->family != call_pkg->nd_family)
> > + return -ENOTTY;
> > +
> > + for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
> > + if (call_pkg->nd_reserved2[i])
> > + return -EINVAL;
> > + return call_pkg->nd_command;
> > + }
> > +
> > + /* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
> > + if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
> > + return cmd;
> > + return 0;
>
> Function zero?  Is that really the right thing to return here?

Yes, function zero is never set in n
>
> Cheers,
> Jeff
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [PATCH v3 2/5] virtio-pmem: Add virtio pmem driver

2019-01-14 Thread Michael S. Tsirkin
On Wed, Jan 09, 2019 at 08:17:33PM +0530, Pankaj Gupta wrote:
> This patch adds virtio-pmem driver for KVM guest.
> 
> Guest reads the persistent memory range information from
> Qemu over VIRTIO and registers it on nvdimm_bus. It also
> creates a nd_region object with the persistent memory
> range information so that existing 'nvdimm/pmem' driver
> can reserve this into system memory map. This way
> 'virtio-pmem' driver uses existing functionality of pmem
> driver to register persistent memory compatible for DAX
> capable filesystems.
> 
> This also provides function to perform guest flush over
> VIRTIO from 'pmem' driver when userspace performs flush
> on DAX memory range.
> 
> Signed-off-by: Pankaj Gupta 
> ---
>  drivers/nvdimm/virtio_pmem.c |  84 ++
>  drivers/virtio/Kconfig   |  10 
>  drivers/virtio/Makefile  |   1 +
>  drivers/virtio/pmem.c| 124 
> +++
>  include/linux/virtio_pmem.h  |  60 +++
>  include/uapi/linux/virtio_ids.h  |   1 +
>  include/uapi/linux/virtio_pmem.h |  10 

As with any uapi change, you need to CC the virtio dev
mailing list (subscribers only, sorry about that).


>  7 files changed, 290 insertions(+)
>  create mode 100644 drivers/nvdimm/virtio_pmem.c
>  create mode 100644 drivers/virtio/pmem.c
>  create mode 100644 include/linux/virtio_pmem.h
>  create mode 100644 include/uapi/linux/virtio_pmem.h
> 
> diff --git a/drivers/nvdimm/virtio_pmem.c b/drivers/nvdimm/virtio_pmem.c
> new file mode 100644
> index 000..2a1b1ba
> --- /dev/null
> +++ b/drivers/nvdimm/virtio_pmem.c
> @@ -0,0 +1,84 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * virtio_pmem.c: Virtio pmem Driver
> + *
> + * Discovers persistent memory range information
> + * from host and provides a virtio based flushing
> + * interface.
> + */
> +#include 
> +#include "nd.h"
> +
> + /* The interrupt handler */
> +void host_ack(struct virtqueue *vq)
> +{
> + unsigned int len;
> + unsigned long flags;
> + struct virtio_pmem_request *req, *req_buf;
> + struct virtio_pmem *vpmem = vq->vdev->priv;
> +
> + spin_lock_irqsave(&vpmem->pmem_lock, flags);
> + while ((req = virtqueue_get_buf(vq, &len)) != NULL) {
> + req->done = true;
> + wake_up(&req->host_acked);
> +
> + if (!list_empty(&vpmem->req_list)) {
> + req_buf = list_first_entry(&vpmem->req_list,
> + struct virtio_pmem_request, list);
> + list_del(&vpmem->req_list);
> + req_buf->wq_buf_avail = true;
> + wake_up(&req_buf->wq_buf);
> + }
> + }
> + spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
> +}
> +EXPORT_SYMBOL_GPL(host_ack);
> +
> + /* The request submission function */
> +int virtio_pmem_flush(struct nd_region *nd_region)
> +{
> + int err;
> + unsigned long flags;
> + struct scatterlist *sgs[2], sg, ret;
> + struct virtio_device *vdev = nd_region->provider_data;
> + struct virtio_pmem *vpmem = vdev->priv;
> + struct virtio_pmem_request *req;
> +
> + might_sleep();
> + req = kmalloc(sizeof(*req), GFP_KERNEL);
> + if (!req)
> + return -ENOMEM;
> +
> + req->done = req->wq_buf_avail = false;
> + strcpy(req->name, "FLUSH");
> + init_waitqueue_head(&req->host_acked);
> + init_waitqueue_head(&req->wq_buf);
> + sg_init_one(&sg, req->name, strlen(req->name));
> + sgs[0] = &sg;
> + sg_init_one(&ret, &req->ret, sizeof(req->ret));
> + sgs[1] = &ret;
> +
> + spin_lock_irqsave(&vpmem->pmem_lock, flags);
> + err = virtqueue_add_sgs(vpmem->req_vq, sgs, 1, 1, req, GFP_ATOMIC);
> + if (err) {
> + dev_err(&vdev->dev, "failed to send command to virtio pmem 
> device\n");
> +
> + list_add_tail(&vpmem->req_list, &req->list);
> + spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
> +
> + /* When host has read buffer, this completes via host_ack */
> + wait_event(req->wq_buf, req->wq_buf_avail);
> + spin_lock_irqsave(&vpmem->pmem_lock, flags);
> + }
> + virtqueue_kick(vpmem->req_vq);
> + spin_unlock_irqrestore(&vpmem->pmem_lock, flags);
> +
> + /* When host has read buffer, this completes via host_ack */
> + wait_event(req->host_acked, req->done);
> + err = req->ret;
> + kfree(req);
> +
> + return err;
> +};
> +EXPORT_SYMBOL_GPL(virtio_pmem_flush);
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/virtio/Kconfig b/drivers/virtio/Kconfig
> index 3589764..9f634a2 100644
> --- a/drivers/virtio/Kconfig
> +++ b/drivers/virtio/Kconfig
> @@ -42,6 +42,16 @@ config VIRTIO_PCI_LEGACY
>  
> If unsure, say Y.
>  
> +config VIRTIO_PMEM
> + tristate "Support for virtio pmem driver"
> + depends on VIRTIO
> + depends on LIBNVDIMM
> + help
> + This driver provides suppor

Re: [PATCH] acpi/nfit: Fix command-supported detection

2019-01-14 Thread Jeff Moyer
Dan Williams  writes:

> The _DSM function number validation only happens to succeed when the
> generic Linux command number translation corresponds with a
> DSM-family-specific function number. This breaks NVDIMM-N
> implementations that correctly implement _LSR, _LSW, and _LSI, but do
> not happen to publish support for DSM function numbers 4, 5, and 6.
>
> Recall that the support for _LS{I,R,W} family of methods results in the
> DIMM being marked as supporting those command numbers at
> acpi_nfit_register_dimms() time. The DSM function mask is only used for
> ND_CMD_CALL support of non-NVDIMM_FAMILY_INTEL devices.
>
> Fixes: 31eca76ba2fc ("nfit, libnvdimm: limited/whitelisted dimm command...")
> Cc: 
> Link: https://github.com/pmem/ndctl/issues/78
> Reported-by: Sujith Pandel 
> Signed-off-by: Dan Williams 
> ---
> Sujith, this is a larger change than what you originally tested, but it
> should behave the same. I wanted to consolidate all the code that
> handles Linux command number to DIMM _DSM function number translation.
>
> If you have a chance to re-test with this it would be much appreciated.
>
> Thanks for the report!
>
>  drivers/acpi/nfit/core.c |   43 +--
>  1 file changed, 29 insertions(+), 14 deletions(-)
>
> diff --git a/drivers/acpi/nfit/core.c b/drivers/acpi/nfit/core.c
> index 790691d9a982..d5d64e90ae71 100644
> --- a/drivers/acpi/nfit/core.c
> +++ b/drivers/acpi/nfit/core.c
> @@ -409,6 +409,29 @@ static bool payload_dumpable(struct nvdimm *nvdimm, 
> unsigned int func)
>   return true;
>  }
>  
> +static int cmd_to_func(struct nvdimm *nvdimm, unsigned int cmd,
> + struct nd_cmd_pkg *call_pkg)
> +{
> + struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);

Minor nit: Seems like the function could take an nfit_mem parameter instead of 
an nvdimm.

> +
> + if (cmd == ND_CMD_CALL) {
> + int i;
> +
> + if (call_pkg && nfit_mem->family != call_pkg->nd_family)
> + return -ENOTTY;
> +
> + for (i = 0; i < ARRAY_SIZE(call_pkg->nd_reserved2); i++)
> + if (call_pkg->nd_reserved2[i])
> + return -EINVAL;
> + return call_pkg->nd_command;
> + }
> +
> + /* Linux ND commands == NVDIMM_FAMILY_INTEL function numbers */
> + if (nfit_mem->family == NVDIMM_FAMILY_INTEL)
> + return cmd;
> + return 0;

Function zero?  Is that really the right thing to return here?

Cheers,
Jeff
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [Qemu-devel] [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-14 Thread Pankaj Gupta


> > > > > Right. Thinking about this I would be more concerned about the fact
> > > > > that
> > > > > guest can effectively pin amount of host's page cache upto size of
> > > > > the
> > > > > device/file passed to guest as PMEM, can't it Pankaj? Or is there
> > > > > some
> > > > > QEMU
> > > > > magic that avoids this?
> > > >
> > > > Yes, guest will pin these host page cache pages using 'get_user_pages'
> > > > by
> > > > elevating the page reference count. But these pages can be reclaimed by
> > > > host
> > > > at any time when there is memory pressure.
> > > 
> > > Wait, how can the guest pin the host pages? I would expect this to
> > > happen only when using vfio and device assignment. Otherwise, no the
> > > host can't reclaim a pinned page, that's the whole point of a pin to
> > > prevent the mm from reclaiming ownership.
> > 
> > yes. You are right I just used the pin word but it does not actually pin
> > pages
> > permanently. I had gone through the discussion on existing problems with
> > get_user_pages and DMA e.g [1] to understand Jan's POV. It does mention GUP
> > pin pages so I also used the word 'pin'. But guest does not permanently pin
> > these pages and these pages can be reclaimed by host.
> 
> OK, then I was just confused how virtio-pmem is going to work. Thanks for
> explanation! So can I imagine this as guest mmaping the host file and
> providing the mapped range as "NVDIMM pages" to the kernel inside the
> guest? Or is it more complex?

yes, that's correct. Host's Qemu process virtual address range is used as guest 
physical 
address and a direct mapping(EPT/NPT) is established. At guest side, this 
physical memory
range is plugged into guest system memory map and DAX mapping is setup using 
nvdimm calls.

Thanks,
Pankaj
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm


Re: [Qemu-devel] [PATCH v3 0/5] kvm "virtio pmem" device

2019-01-14 Thread Jan Kara
On Sat 12-01-19 21:17:46, Pankaj Gupta wrote:
> > > > Right. Thinking about this I would be more concerned about the fact that
> > > > guest can effectively pin amount of host's page cache upto size of the
> > > > device/file passed to guest as PMEM, can't it Pankaj? Or is there some
> > > > QEMU
> > > > magic that avoids this?
> > >
> > > Yes, guest will pin these host page cache pages using 'get_user_pages' by
> > > elevating the page reference count. But these pages can be reclaimed by
> > > host
> > > at any time when there is memory pressure.
> > 
> > Wait, how can the guest pin the host pages? I would expect this to
> > happen only when using vfio and device assignment. Otherwise, no the
> > host can't reclaim a pinned page, that's the whole point of a pin to
> > prevent the mm from reclaiming ownership.
> 
> yes. You are right I just used the pin word but it does not actually pin 
> pages 
> permanently. I had gone through the discussion on existing problems with 
> get_user_pages and DMA e.g [1] to understand Jan's POV. It does mention GUP 
> pin pages so I also used the word 'pin'. But guest does not permanently pin 
> these pages and these pages can be reclaimed by host.

OK, then I was just confused how virtio-pmem is going to work. Thanks for
explanation! So can I imagine this as guest mmaping the host file and
providing the mapped range as "NVDIMM pages" to the kernel inside the
guest? Or is it more complex?

Honza

-- 
Jan Kara 
SUSE Labs, CR
___
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm