All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v7 0/7] nvdimm: Add an IOCTL pass thru for DSM calls
@ 2016-03-15 21:32 Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 1/7] ACPI / util: Fix acpi_evaluate_dsm() argument type Jerry Hoemann
                   ` (6 more replies)
  0 siblings, 7 replies; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-15 21:32 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm


The NVDIMM code in the kernel supports an IOCTL interface to user
space based upon the Intel Example DSM:

	http://pmem.io/documents/NVDIMM_DSM_Interface_Example.pdf

This interface cannot be used by other NVDIMM DSMs that support
incompatible functions.

An alternative DSM specification for Type N DSM being developed
by Hewlett Packard Enterprise can be found at:

	https://github.com/HewlettPackard/hpe-nvm/tree/master/Documentation

To accommodate multiple and conflicting DSM specifications, this patch
set adds a generic "passthru" IOCTL interface which is not tied to
a particular DSM.

A new _IOC_NR ND_CMD_CALL == "10" is added for the pass thru call.

The new data structure nd_cmd_pkg serves as a wrapper for the
passthru calls.  This wrapper supplies the data that the kernel
needs to make the _DSM call.

Unlike the definitions of the _DSM functions themselves, the nd_cmd_pkg
provides the calling information (input/output sizes) in an uniform
manner making the kernel marshaling of the arguments straight
forward.

This shifts the marshaling burden from the kernel to the user
space application while still permitting the kernel to internally
call _DSM functions.

The kernel functions __nd_ioctl and acpi_nfit_ctl were modified
to accommodate ND_CMD_CALL.

Changes in version 7:
--------------------
0. change name ND_CMD_CALL_DSM to ND_CMD_CALL
    - part of abstracting out DSM missed in version 6.

1. change name in struct nd_call_dsm
    a) "ncp_" -> "nd_"
    b) ncp_pot_size -> nd_fw_size
    c) ncp_type -> nd_family
    o) cascade name changes to other patches

2. Expanded comment around data structure nd_cmd_pkg

3. At Dan's request, hard coding "root" UUID.
    a) retract extension of dsm_uuid to nvdimm_bus_descriptor.
    b) reverted nfit.c/acpi_nfit_init_dsms() with the exception of
	allowing function 0 in mask.

4. At Dan's request, removed "rev" from nd_cmd_pkg.  Hard-coding
    use of rev "1" in acpi_nfit_ctl.


Changes in version 6:
---------------------
Built against
git://git.kernel.org/pub/scm/linux/kernel/git/djbw/nvdimm.git
libnvdimm-pending

0. Patches "Clean-up access mode check" and "Fix security issue with DSM IOCTL"
   already in above libnvdimm-pending.  So omitted here.

1. Incorporated changes from Dan's RFC patch set
   https://lists.01.org/pipermail/linux-nvdimm/2016-January/004049.html

2. Dan asked me to abstract out the DSM aspects from the ndm_cmd_dsmcall_pkg.
   This became nd_cmd_pkg.  UUIDs are no longer passed in from
   user applications.

3. To accommodate multiple UUIDS, added table cmd_type_tbl which is used
   to determine UUID for the acpi object by calling function 0 for
   each UUID in table until success.

   This table also provides a MASK field that the kernel can use
   to exclude functions being called.

   This table can be thought of a list of "acceptable" DSMs.

4. The cmd_type_tbl is also used by acpi_nfit_ctl to map the
   external handle of calls to internal handle, UUID.

   Note, code only validates that the requested type of call is one in
   cmd_type_tbl, but it might not necessarily be the same found during
   acpi_nfit_add_dimm.  The ACPI SPEC appears to allow and firmware
   does implement multiple UUID per object.

   In the case where type is in table, but the UUID isn't supported
   by the underlying firmware, firmware shall return an error when
   called.

   This allows for use of a secondary DSM on an object.  This could
   be considered a feature or a defect.  This can be tightened
   up if needed.



Changes in version 5:
---------------------
0. Fixed submit comment for drivers/acpi/utils.c.


Changes in version 4:
---------------------
0. Added patch to correct parameter type passed to acpi_evaluate_dsm
   ACPI defines arguments rev and fun as 64 bit quantities and the ioctl
   exports to user face rev and func. We want those to match the ACPI spec.

   Also modified acpi_evaluate_dsm_typed and acpi_check dsm which had
   similar issue.

1. nd_cmd_dsmcall_pkg rearrange a reserve and rounded up total size
   to 16 byte boundary.

2. Created stand alone patch for the pre-existing security issue related
   to "read only" IOCTL calls.

3. Added patch for increasing envelope size of IOCTL.  Needed to
   be able to read in the wrapper to know remaining size to copy in.

   Note: in_env, out_env are statics sized based upon this change.

4. Moved copyin code to table driven nd_cmd_desc 

  Note, the last 40 lines or so of acpi_nfit_ctl will not return _DSM
  data unless the size allocated in user space buffer equals
  out_obj->buffer.length.

  The semantic we want in the pass thru case is to return as much
  of the _DSM data as the user space buffer would accommodate.

  Hence, in acpi_nfit_ctl I have retained the line:

		memcpy(pkg->dsm_buf + pkg->h.dsm_in,
			out_obj->buffer.pointer,
			min(pkg->h.dsm_size, pkg->h.dsm_out));

  and the early return from the function.




Changes in version 3:
---------------------
1. Changed name ND_CMD_PASSTHRU to ND_CMD_CALL_DSM.

2. Value of ND_CMD_CALL_DSM is 10, not 100.

3. Changed name of nd_passthru_pkg to nd_cmd_dsmcall_pkg.

4. Removed separate functions for handling ND_CMD_CALL_DSM.
   Moved functionality to __nd_ioctl and acpi_nfit_ctl proper.
   The resultant code looks very different from prior versions.

5. BUGFIX: __nd_ioctl: Change the if read_only switch to use
	 _IOC_NR cmd (not ioctl_cmd) for better protection.

	Do we want to make a stand alone patch for this issue?


Changes in version 2:
---------------------
1. Cleanup access mode check in nd_ioctl and nvdimm_ioctl.
2. Change name of ndn_pkg to nd_passthru_pkg
3. Adjust sizes in nd_passthru_pkg. DSM integers are 64 bit.
4. No new ioctl type, instead tunnel into the existing number space.
5. Push down one function level where determine ioctl cmd type.
6. re-work diagnostic print/dump message in pass-thru functions.

Jerry Hoemann (7):
  ACPI / util: Fix acpi_evaluate_dsm() argument type
  nvdimm: Add wrapper for IOCTL pass thru
  nvdimm: Increase max envelope size for IOCTL
  nvdimm: Add UUIDs
  libnvdimm: advertise 'call_dsm' support
  nvdimm: Add IOCTL pass thru functions
  tools/testing/nvdimm: 'call_dsm' support

 drivers/acpi/nfit.c              | 142 ++++++++++++++++++++++++++++++++++-----
 drivers/acpi/nfit.h              |   5 ++
 drivers/acpi/utils.c             |   4 +-
 drivers/nvdimm/bus.c             |  45 ++++++++++++-
 drivers/nvdimm/core.c            |   3 +
 drivers/nvdimm/dimm_devs.c       |   8 ++-
 include/acpi/acpi_bus.h          |   6 +-
 include/linux/libnvdimm.h        |   3 +-
 include/uapi/linux/ndctl.h       |  53 +++++++++++++++
 tools/testing/nvdimm/test/nfit.c |  13 +++-
 10 files changed, 254 insertions(+), 28 deletions(-)

-- 
1.7.11.3

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

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH v7 1/7] ACPI / util: Fix acpi_evaluate_dsm() argument type
  2016-03-15 21:32 [PATCH v7 0/7] nvdimm: Add an IOCTL pass thru for DSM calls Jerry Hoemann
@ 2016-03-15 21:32 ` Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 2/7] nvdimm: Add wrapper for IOCTL pass thru Jerry Hoemann
                   ` (5 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-15 21:32 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm

The ACPI spec speicifies that arguments "Revision ID" and
"Function Index" to a _DSM are type "Integer."  Type Integers
are 64 bit quantities.

The function evaluate_dsm specifies these types as simple "int"
which are 32 bits.  Correct type passed to acpi_evaluate_dsm
and its callers and derived callers to pass correct type.

acpi_check_dsm and acpi_evaluate_dsm_typed had similar issue
and were corrected as well.

Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
---
 drivers/acpi/utils.c    | 4 ++--
 include/acpi/acpi_bus.h | 6 +++---
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index f2f9873..87bd54d 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -629,7 +629,7 @@ acpi_status acpi_evaluate_lck(acpi_handle handle, int lock)
  * some old BIOSes do expect a buffer or an integer etc.
  */
 union acpi_object *
-acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, int rev, int func,
+acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 func,
 		  union acpi_object *argv4)
 {
 	acpi_status ret;
@@ -678,7 +678,7 @@ EXPORT_SYMBOL(acpi_evaluate_dsm);
  * functions. Currently only support 64 functions at maximum, should be
  * enough for now.
  */
-bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs)
+bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 funcs)
 {
 	int i;
 	u64 mask = 0;
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 14362a8..f092cc6 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -61,12 +61,12 @@ bool acpi_ata_match(acpi_handle handle);
 bool acpi_bay_match(acpi_handle handle);
 bool acpi_dock_match(acpi_handle handle);
 
-bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, int rev, u64 funcs);
+bool acpi_check_dsm(acpi_handle handle, const u8 *uuid, u64 rev, u64 funcs);
 union acpi_object *acpi_evaluate_dsm(acpi_handle handle, const u8 *uuid,
-			int rev, int func, union acpi_object *argv4);
+			u64 rev, u64 func, union acpi_object *argv4);
 
 static inline union acpi_object *
-acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, int rev, int func,
+acpi_evaluate_dsm_typed(acpi_handle handle, const u8 *uuid, u64 rev, u64 func,
 			union acpi_object *argv4, acpi_object_type type)
 {
 	union acpi_object *obj;
-- 
1.7.11.3

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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 2/7] nvdimm: Add wrapper for IOCTL pass thru
  2016-03-15 21:32 [PATCH v7 0/7] nvdimm: Add an IOCTL pass thru for DSM calls Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 1/7] ACPI / util: Fix acpi_evaluate_dsm() argument type Jerry Hoemann
@ 2016-03-15 21:32 ` Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 3/7] nvdimm: Increase max envelope size for IOCTL Jerry Hoemann
                   ` (4 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-15 21:32 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm

Add struct nd_cmd_pkg which serves as a warapper for
the data being passed via a pass thru to a NVDIMM DSM.
This wrapper specifies the extra information in a uniform
manner allowing the kenrel to call a DSM without knowing
specifics of the DSM.

Add dsm_call command to nvdimm_bus_cmd_name and nvdimm_cmd_name.

Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
---
 include/uapi/linux/ndctl.h | 53 ++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 53 insertions(+)

diff --git a/include/uapi/linux/ndctl.h b/include/uapi/linux/ndctl.h
index 7cc28ab..c043cd1 100644
--- a/include/uapi/linux/ndctl.h
+++ b/include/uapi/linux/ndctl.h
@@ -114,6 +114,7 @@ enum {
 	ND_CMD_ARS_START = 2,
 	ND_CMD_ARS_STATUS = 3,
 	ND_CMD_CLEAR_ERROR = 4,
+	/* 10 reserved for ND_CMD_CALL below */
 
 	/* per-dimm commands */
 	ND_CMD_SMART = 1,
@@ -125,6 +126,7 @@ enum {
 	ND_CMD_VENDOR_EFFECT_LOG_SIZE = 7,
 	ND_CMD_VENDOR_EFFECT_LOG = 8,
 	ND_CMD_VENDOR = 9,
+	ND_CMD_CALL = 10,
 };
 
 enum {
@@ -139,6 +141,7 @@ static inline const char *nvdimm_bus_cmd_name(unsigned cmd)
 		[ND_CMD_ARS_START] = "ars_start",
 		[ND_CMD_ARS_STATUS] = "ars_status",
 		[ND_CMD_CLEAR_ERROR] = "clear_error",
+		[ND_CMD_CALL] = "cmd_call",
 	};
 
 	if (cmd < ARRAY_SIZE(names) && names[cmd])
@@ -158,6 +161,7 @@ static inline const char *nvdimm_cmd_name(unsigned cmd)
 		[ND_CMD_VENDOR_EFFECT_LOG_SIZE] = "effect_size",
 		[ND_CMD_VENDOR_EFFECT_LOG] = "effect_log",
 		[ND_CMD_VENDOR] = "vendor",
+		[ND_CMD_CALL] = "cmd_call",
 	};
 
 	if (cmd < ARRAY_SIZE(names) && names[cmd])
@@ -224,4 +228,53 @@ enum ars_masks {
 	ARS_STATUS_MASK = 0x0000FFFF,
 	ARS_EXT_STATUS_SHIFT = 16,
 };
+
+
+/*
+ * struct nd_cmd_pkg
+ *
+ * is a wrapper to a quasi pass thru interface for invoking firmware
+ * associated with nvdimms.
+ *
+ * INPUT PARAMETERS
+ *
+ * nd_family corresponds to the firmware (e.g. DSM) interface.
+ *
+ * nd_command are the function index advertised by the firmware.
+ *
+ * nd_size_in is the size of the input parameters being passed to firmware
+ *
+ * OUTPUT PARAMETERS
+ *
+ * nd_fw_size is the size of the data firmware wants to return for
+ * the call.  If nd_fw_size is greater than size of nd_size_out, only
+ * the first nd_size_out bytes are returned.
+ */
+
+struct nd_cmd_pkg {
+	__u64   nd_family;		/* family of commands, eg ND_TYPE_BUS */
+	__u64   nd_command;
+	__u32   nd_size_in;		/* INPUT: size of input args */
+	__u32   nd_size_out;		/* INPUT: size of payload */
+	__u32   nd_reserved2[9];	/* reserved must be zero */
+	__u32   nd_fw_size;		/* OUTPUT: size fw wants to return */
+	unsigned char nd_payload[];	/* Contents of call      */
+};
+
+/*
+ * the list nd_family of commands.  The mapping to firmware handles
+ * is definied in the nfit_cmd_family_tbl
+ *
+ */
+#define ND_TYPE_BUS			1
+#define ND_TYPE_DIMM_INTEL1		2
+#define ND_TYPE_DIMM_N_HPE1		3
+#define ND_TYPE_DIMM_N_HPE2		4
+
+
+#define ND_IOCTL_CALL			_IOWR(ND_IOCTL, ND_CMD_CALL,\
+					struct nd_cmd_pkg)
+
+
+
 #endif /* __NDCTL_H__ */
-- 
1.7.11.3

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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 3/7] nvdimm: Increase max envelope size for IOCTL
  2016-03-15 21:32 [PATCH v7 0/7] nvdimm: Add an IOCTL pass thru for DSM calls Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 1/7] ACPI / util: Fix acpi_evaluate_dsm() argument type Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 2/7] nvdimm: Add wrapper for IOCTL pass thru Jerry Hoemann
@ 2016-03-15 21:32 ` Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 4/7] nvdimm: Add UUIDs Jerry Hoemann
                   ` (3 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-15 21:32 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm

In __nd_ioctl must first read in the fixed sized portion of an ioctl
so that it can then determine the size of the variable part.

Prepare for ND_CMD_CALL_DSM calls which have larger fixed portion
wrapper.

Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
---
 include/linux/libnvdimm.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index 833867b..af31d1c 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -27,7 +27,7 @@ enum {
 	/* need to set a limit somewhere, but yes, this is likely overkill */
 	ND_IOCTL_MAX_BUFLEN = SZ_4M,
 	ND_CMD_MAX_ELEM = 5,
-	ND_CMD_MAX_ENVELOPE = 16,
+	ND_CMD_MAX_ENVELOPE = 256,
 	ND_MAX_MAPPINGS = 32,
 
 	/* region flag indicating to direct-map persistent memory by default */
-- 
1.7.11.3

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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 4/7] nvdimm: Add UUIDs
  2016-03-15 21:32 [PATCH v7 0/7] nvdimm: Add an IOCTL pass thru for DSM calls Jerry Hoemann
                   ` (2 preceding siblings ...)
  2016-03-15 21:32 ` [PATCH v7 3/7] nvdimm: Increase max envelope size for IOCTL Jerry Hoemann
@ 2016-03-15 21:32 ` Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support Jerry Hoemann
                   ` (2 subsequent siblings)
  6 siblings, 0 replies; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-15 21:32 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm

Add UUID associated with HPE Type N NVDIMM.

Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
---
 drivers/acpi/nfit.h | 5 +++++
 1 file changed, 5 insertions(+)

diff --git a/drivers/acpi/nfit.h b/drivers/acpi/nfit.h
index c75576b..10dd0d3 100644
--- a/drivers/acpi/nfit.h
+++ b/drivers/acpi/nfit.h
@@ -23,6 +23,8 @@
 
 #define UUID_NFIT_BUS "2f10e7a4-9e91-11e4-89d3-123b93f75cba"
 #define UUID_NFIT_DIMM "4309ac30-0d11-11e4-9191-0800200c9a66"
+#define UUID_NFIT_DIMM_N_HPE1 "9002c334-acf3-4c0e-9642-a235f0d53bc6"
+#define UUID_NFIT_DIMM_N_HPE2 "5008664B-B758-41A0-A03C-27C2F2D04F7E"
 #define ACPI_NFIT_MEM_FAILED_MASK (ACPI_NFIT_MEM_SAVE_FAILED \
 		| ACPI_NFIT_MEM_RESTORE_FAILED | ACPI_NFIT_MEM_FLUSH_FAILED \
 		| ACPI_NFIT_MEM_NOT_ARMED)
@@ -38,6 +40,8 @@ enum nfit_uuids {
 	NFIT_SPA_PCD,
 	NFIT_DEV_BUS,
 	NFIT_DEV_DIMM,
+	NFIT_DEV_DIMM_N_HPE1,
+	NFIT_DEV_DIMM_N_HPE2,
 	NFIT_UUID_MAX,
 };
 
@@ -110,6 +114,7 @@ struct nfit_mem {
 	struct list_head list;
 	struct acpi_device *adev;
 	unsigned long dsm_mask;
+	const u8 *dsm_uuid;
 };
 
 struct acpi_nfit_desc {
-- 
1.7.11.3

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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support
  2016-03-15 21:32 [PATCH v7 0/7] nvdimm: Add an IOCTL pass thru for DSM calls Jerry Hoemann
                   ` (3 preceding siblings ...)
  2016-03-15 21:32 ` [PATCH v7 4/7] nvdimm: Add UUIDs Jerry Hoemann
@ 2016-03-15 21:32 ` Jerry Hoemann
  2016-03-15 22:08   ` Dan Williams
  2016-03-15 21:32 ` [PATCH v7 6/7] nvdimm: Add IOCTL pass thru functions Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 7/7] tools/testing/nvdimm: 'call_dsm' support Jerry Hoemann
  6 siblings, 1 reply; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-15 21:32 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm

Indicate to userspace that the generic 'dsm_call' capability is
available for the given control device.  Over time we want to deprecate
the per-dsm function ioctl commands and direct everything through the
generic envelope.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
---
 drivers/nvdimm/core.c      | 3 +++
 drivers/nvdimm/dimm_devs.c | 8 +++++++-
 include/linux/libnvdimm.h  | 1 +
 3 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c
index 79646d0..9b395e5 100644
--- a/drivers/nvdimm/core.c
+++ b/drivers/nvdimm/core.c
@@ -253,6 +253,9 @@ static ssize_t commands_show(struct device *dev,
 
 	for_each_set_bit(cmd, &nd_desc->dsm_mask, BITS_PER_LONG)
 		len += sprintf(buf + len, "%s ", nvdimm_bus_cmd_name(cmd));
+	if (nd_desc->call_dsm)
+		len += sprintf(buf + len, "%s ",
+				nvdimm_bus_cmd_name(ND_CMD_CALL));
 	len += sprintf(buf + len, "\n");
 	return len;
 }
diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
index c56f882..89086d6 100644
--- a/drivers/nvdimm/dimm_devs.c
+++ b/drivers/nvdimm/dimm_devs.c
@@ -274,14 +274,20 @@ EXPORT_SYMBOL_GPL(nvdimm_provider_data);
 static ssize_t commands_show(struct device *dev,
 		struct device_attribute *attr, char *buf)
 {
+	struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
 	struct nvdimm *nvdimm = to_nvdimm(dev);
+	struct nvdimm_bus_descriptor *nd_desc;
 	int cmd, len = 0;
 
-	if (!nvdimm->dsm_mask)
+	if (!nvdimm->dsm_mask || !nvdimm_bus)
 		return sprintf(buf, "\n");
 
 	for_each_set_bit(cmd, nvdimm->dsm_mask, BITS_PER_LONG)
 		len += sprintf(buf + len, "%s ", nvdimm_cmd_name(cmd));
+	nd_desc = nvdimm_bus->nd_desc;
+	if (nd_desc->call_dsm)
+		len += sprintf(buf + len, "%s ",
+				nvdimm_cmd_name(ND_CMD_CALL));
 	len += sprintf(buf + len, "\n");
 	return len;
 }
diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
index af31d1c..458db57 100644
--- a/include/linux/libnvdimm.h
+++ b/include/linux/libnvdimm.h
@@ -68,6 +68,7 @@ struct nd_mapping {
 
 struct nvdimm_bus_descriptor {
 	const struct attribute_group **attr_groups;
+	unsigned int call_dsm:1;
 	unsigned long dsm_mask;
 	char *provider_name;
 	ndctl_fn ndctl;
-- 
1.7.11.3

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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 6/7] nvdimm: Add IOCTL pass thru functions
  2016-03-15 21:32 [PATCH v7 0/7] nvdimm: Add an IOCTL pass thru for DSM calls Jerry Hoemann
                   ` (4 preceding siblings ...)
  2016-03-15 21:32 ` [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support Jerry Hoemann
@ 2016-03-15 21:32 ` Jerry Hoemann
  2016-03-15 21:32 ` [PATCH v7 7/7] tools/testing/nvdimm: 'call_dsm' support Jerry Hoemann
  6 siblings, 0 replies; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-15 21:32 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm

Add ioctl command ND_CMD_CALL_DSM to acpi_nfit_ctl and __nd_ioctl which
allow kernel to call a nvdimm's _DSM as a passthru without using the
marshaling code of the nd_cmd_desc.

Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
---
 drivers/acpi/nfit.c  | 142 ++++++++++++++++++++++++++++++++++++++++++++-------
 drivers/nvdimm/bus.c |  45 +++++++++++++++-
 2 files changed, 168 insertions(+), 19 deletions(-)

diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index d0f35e6..2ff777a 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -56,6 +56,21 @@ struct nfit_table_prev {
 	struct list_head flushes;
 };
 
+struct cmd_family_tbl {
+	enum nfit_uuids	key_uuid;	/* Internal handle		*/
+	int		key_type;	/* Exported handle		*/
+	int		rev;		/* _DSM rev			*/
+	u64		mask;		/* 0 bit excludes underlying func.*/
+};
+
+struct cmd_family_tbl nfit_cmd_family_tbl[] = {
+	{ NFIT_DEV_BUS,		ND_TYPE_BUS,		1, ~0UL},
+	{ NFIT_DEV_DIMM,	ND_TYPE_DIMM_INTEL1,	1, ~0UL},
+	{ NFIT_DEV_DIMM_N_HPE1, ND_TYPE_DIMM_N_HPE1,	1, ~0UL},
+	{ NFIT_DEV_DIMM_N_HPE2, ND_TYPE_DIMM_N_HPE2,	1, ~0UL},
+	{ -1, -1, -1, 0},
+};
+
 static u8 nfit_uuid[NFIT_UUID_MAX][16];
 
 const u8 *to_nfit_uuid(enum nfit_uuids id)
@@ -64,6 +79,18 @@ const u8 *to_nfit_uuid(enum nfit_uuids id)
 }
 EXPORT_SYMBOL(to_nfit_uuid);
 
+static int
+known_nvdimm_type(u32 type, struct cmd_family_tbl *tbl)
+{
+	int i;
+
+	for (i = 0;  tbl[i].key_type >= 0 ; i++) {
+		if (tbl[i].key_type == type)
+			return 1;
+	}
+	return 0;
+}
+
 static struct acpi_nfit_desc *to_acpi_nfit_desc(
 		struct nvdimm_bus_descriptor *nd_desc)
 {
@@ -171,8 +198,9 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 		unsigned int buf_len, int *cmd_rc)
 {
 	struct acpi_nfit_desc *acpi_desc = to_acpi_nfit_desc(nd_desc);
-	const struct nd_cmd_desc *desc = NULL;
 	union acpi_object in_obj, in_buf, *out_obj;
+	struct nd_cmd_pkg *call_dsm = NULL;
+	const struct nd_cmd_desc *desc = NULL;
 	struct device *dev = acpi_desc->dev;
 	const char *cmd_name, *dimm_name;
 	unsigned long dsm_mask;
@@ -180,6 +208,12 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 	const u8 *uuid;
 	u32 offset;
 	int rc, i;
+	__u64 rev = 1, func = cmd;
+
+	if (cmd == ND_CMD_CALL) {
+		call_dsm = buf;
+		func = call_dsm->nd_command;
+	}
 
 	if (nvdimm) {
 		struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
@@ -191,7 +225,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 		cmd_name = nvdimm_cmd_name(cmd);
 		dsm_mask = nfit_mem->dsm_mask;
 		desc = nd_cmd_dimm_desc(cmd);
-		uuid = to_nfit_uuid(NFIT_DEV_DIMM);
+		uuid = nfit_mem->dsm_uuid;
 		handle = adev->handle;
 	} else {
 		struct acpi_device *adev = to_acpi_dev(acpi_desc);
@@ -207,7 +241,7 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 	if (!desc || (cmd && (desc->out_num + desc->in_num == 0)))
 		return -ENOTTY;
 
-	if (!test_bit(cmd, &dsm_mask))
+	if (!test_bit(func, &dsm_mask))
 		return -ENOTTY;
 
 	in_obj.type = ACPI_TYPE_PACKAGE;
@@ -218,25 +252,48 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 	in_buf.buffer.length = 0;
 
 	/* libnvdimm has already validated the input envelope */
-	for (i = 0; i < desc->in_num; i++)
+	for (i = 0; i < desc->in_num; i++) {
 		in_buf.buffer.length += nd_cmd_in_size(nvdimm, cmd, desc,
 				i, buf);
+	}
+
+	if (call_dsm) {
+		/* must skip over package wrapper */
+		in_buf.buffer.pointer = (void *) &call_dsm->nd_payload;
+		in_buf.buffer.length = call_dsm->nd_size_in;
+		if (!known_nvdimm_type(call_dsm->nd_family, nfit_cmd_family_tbl)) {
+			dev_dbg(dev, "%s:%s unsupported uuid\n", dimm_name,
+					cmd_name);
+			return -EINVAL;
+		}
+	}
 
 	if (IS_ENABLED(CONFIG_ACPI_NFIT_DEBUG)) {
-		dev_dbg(dev, "%s:%s cmd: %s input length: %d\n", __func__,
-				dimm_name, cmd_name, in_buf.buffer.length);
-		print_hex_dump_debug(cmd_name, DUMP_PREFIX_OFFSET, 4,
-				4, in_buf.buffer.pointer, min_t(u32, 128,
-					in_buf.buffer.length), true);
+		dev_dbg(dev, "%s:%s cmd: %d: %llu input length: %d\n", __func__,
+				dimm_name, cmd, func, in_buf.buffer.length);
+		print_hex_dump_debug("nvdimm in  ", DUMP_PREFIX_OFFSET, 4, 4,
+			in_buf.buffer.pointer,
+			min_t(u32, 256, in_buf.buffer.length), true);
+
 	}
 
-	out_obj = acpi_evaluate_dsm(handle, uuid, 1, cmd, &in_obj);
+	out_obj = acpi_evaluate_dsm(handle, uuid, rev, func, &in_obj);
 	if (!out_obj) {
-		dev_dbg(dev, "%s:%s _DSM failed cmd: %s\n", __func__, dimm_name,
-				cmd_name);
+		dev_dbg(dev, "%s:%s unexpected output object type cmd: %s %llu, type: %d\n",
+			__func__, dimm_name, cmd_name, func, out_obj->type);
 		return -EINVAL;
 	}
 
+	if (call_dsm) {
+		call_dsm->nd_fw_size = out_obj->buffer.length;
+		memcpy(call_dsm->nd_payload + call_dsm->nd_size_in,
+			out_obj->buffer.pointer,
+			min(call_dsm->nd_fw_size, call_dsm->nd_size_out));
+
+		ACPI_FREE(out_obj);
+		return 0;
+	}
+
 	if (out_obj->package.type != ACPI_TYPE_BUFFER) {
 		dev_dbg(dev, "%s:%s unexpected output object type cmd: %s type: %d\n",
 				__func__, dimm_name, cmd_name, out_obj->type);
@@ -918,13 +975,60 @@ static struct nvdimm *acpi_nfit_dimm_by_handle(struct acpi_nfit_desc *acpi_desc,
 	return NULL;
 }
 
+
+/*
+ * determine if the _DSM specified by UUID is supported and return
+ * mask of supported functions in nd_cmd_mask.
+ */
+
+static int acpi_nfit_sup_func(acpi_handle handle, const u8 *uuid,
+		int rev, unsigned long *nd_cmd_mask)
+{
+	int i;
+	u64 mask = 0;
+	union acpi_object *obj;
+
+	obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
+	if (!obj)
+		return 0;
+	/* For compatibility, old BIOSes may return an integer */
+	if (obj->type == ACPI_TYPE_INTEGER)
+		mask = obj->integer.value;
+	else if (obj->type == ACPI_TYPE_BUFFER)
+		for (i = 0; i < obj->buffer.length && i < 8; i++)
+			mask |= (((u8)obj->buffer.pointer[i]) << (i * 8));
+	ACPI_FREE(obj);
+
+	*nd_cmd_mask = mask;
+
+	return !!mask;
+}
+
+
+static inline void
+to_nfit_uuid_msk(acpi_handle handle, struct cmd_family_tbl *tbl,
+		u8 const **cmd_uuid, unsigned long *cmd_mask)
+{
+	unsigned long mask = 0;
+	int i;
+
+	for (i = 0;  tbl[i].key_uuid >= 0 ; i++) {
+		const u8 *uuid = to_nfit_uuid(tbl[i].key_uuid);
+		int rev = tbl[i].rev;
+
+		if (acpi_nfit_sup_func(handle, uuid, rev, &mask)) {
+			*cmd_mask = mask & tbl[i].mask;
+			*cmd_uuid = uuid;
+			break;
+		}
+	}
+}
+
 static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
 		struct nfit_mem *nfit_mem, u32 device_handle)
 {
 	struct acpi_device *adev, *adev_dimm;
 	struct device *dev = acpi_desc->dev;
-	const u8 *uuid = to_nfit_uuid(NFIT_DEV_DIMM);
-	int i;
 
 	nfit_mem->dsm_mask = acpi_desc->dimm_dsm_force_en;
 	adev = to_acpi_dev(acpi_desc);
@@ -939,9 +1043,8 @@ static int acpi_nfit_add_dimm(struct acpi_nfit_desc *acpi_desc,
 		return force_enable_dimms ? 0 : -ENODEV;
 	}
 
-	for (i = ND_CMD_SMART; i <= ND_CMD_VENDOR; i++)
-		if (acpi_check_dsm(adev_dimm->handle, uuid, 1, 1ULL << i))
-			set_bit(i, &nfit_mem->dsm_mask);
+	to_nfit_uuid_msk(adev_dimm->handle, nfit_cmd_family_tbl,
+			&nfit_mem->dsm_uuid, &nfit_mem->dsm_mask);
 
 	return 0;
 }
@@ -1012,7 +1115,8 @@ static void acpi_nfit_init_dsms(struct acpi_nfit_desc *acpi_desc)
 	if (!adev)
 		return;
 
-	for (i = ND_CMD_ARS_CAP; i <= ND_CMD_CLEAR_ERROR; i++)
+	nd_desc->call_dsm = 1;
+	for (i = 0; i <= ND_CMD_CLEAR_ERROR; i++)
 		if (acpi_check_dsm(adev->handle, uuid, 1, 1ULL << i))
 			set_bit(i, &nd_desc->dsm_mask);
 }
@@ -2463,6 +2567,8 @@ static __init int nfit_init(void)
 	acpi_str_to_uuid(UUID_PERSISTENT_VIRTUAL_CD, nfit_uuid[NFIT_SPA_PCD]);
 	acpi_str_to_uuid(UUID_NFIT_BUS, nfit_uuid[NFIT_DEV_BUS]);
 	acpi_str_to_uuid(UUID_NFIT_DIMM, nfit_uuid[NFIT_DEV_DIMM]);
+	acpi_str_to_uuid(UUID_NFIT_DIMM_N_HPE1, nfit_uuid[NFIT_DEV_DIMM_N_HPE1]);
+	acpi_str_to_uuid(UUID_NFIT_DIMM_N_HPE2, nfit_uuid[NFIT_DEV_DIMM_N_HPE2]);
 
 	nfit_wq = create_singlethread_workqueue("nfit");
 	if (!nfit_wq)
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index 3355748..4ff5787 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -439,6 +439,12 @@ static const struct nd_cmd_desc __nd_cmd_dimm_descs[] = {
 		.out_num = 3,
 		.out_sizes = { 4, 4, UINT_MAX, },
 	},
+	[ND_CMD_CALL] = {
+		.in_num = 2,
+		.in_sizes = {sizeof(struct nd_cmd_pkg), UINT_MAX, },
+		.out_num = 1,
+		.out_sizes = { UINT_MAX, },
+	},
 };
 
 const struct nd_cmd_desc *nd_cmd_dimm_desc(int cmd)
@@ -473,6 +479,12 @@ static const struct nd_cmd_desc __nd_cmd_bus_descs[] = {
 		.out_num = 3,
 		.out_sizes = { 4, 4, 8, },
 	},
+	[ND_CMD_CALL] = {
+		.in_num = 2,
+		.in_sizes = {sizeof(struct nd_cmd_pkg), UINT_MAX, },
+		.out_num = 1,
+		.out_sizes = { UINT_MAX, },
+	},
 };
 
 const struct nd_cmd_desc *nd_cmd_bus_desc(int cmd)
@@ -500,6 +512,10 @@ u32 nd_cmd_in_size(struct nvdimm *nvdimm, int cmd,
 		struct nd_cmd_vendor_hdr *hdr = buf;
 
 		return hdr->in_length;
+	} else if (cmd == ND_CMD_CALL) {
+		struct nd_cmd_pkg *pkg = buf;
+
+		return pkg->nd_size_in;
 	}
 
 	return UINT_MAX;
@@ -522,6 +538,12 @@ u32 nd_cmd_out_size(struct nvdimm *nvdimm, int cmd,
 		return out_field[1];
 	else if (!nvdimm && cmd == ND_CMD_ARS_STATUS && idx == 2)
 		return out_field[1] - 8;
+	else if (cmd == ND_CMD_CALL) {
+		struct nd_cmd_pkg *pkg =
+				(struct nd_cmd_pkg *) in_field;
+		return pkg->nd_size_out;
+	}
+
 
 	return UINT_MAX;
 }
@@ -588,7 +610,9 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 	unsigned int cmd = _IOC_NR(ioctl_cmd);
 	void __user *p = (void __user *) arg;
 	struct device *dev = &nvdimm_bus->dev;
+	struct nd_cmd_pkg call_dsm;
 	const char *cmd_name, *dimm_name;
+	unsigned int func = cmd;
 	unsigned long dsm_mask;
 	void *buf;
 	int rc, i;
@@ -605,8 +629,16 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 		dimm_name = "bus";
 	}
 
+	if (cmd == ND_CMD_CALL) {
+		if (!nd_desc->call_dsm)
+			return -ENOTTY;
+		if (copy_from_user(&call_dsm, p, sizeof(call_dsm)))
+			return -EFAULT;
+		func = call_dsm.nd_command;
+	}
+
 	if (!desc || (desc->out_num + desc->in_num == 0) ||
-			!test_bit(cmd, &dsm_mask))
+			!test_bit(func, &dsm_mask))
 		return -ENOTTY;
 
 	/* fail write commands (when read-only) */
@@ -616,6 +648,7 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 		case ND_CMD_SET_CONFIG_DATA:
 		case ND_CMD_ARS_START:
 		case ND_CMD_CLEAR_ERROR:
+		case ND_CMD_CALL:
 			dev_dbg(&nvdimm_bus->dev, "'%s' command while read-only.\n",
 					nvdimm ? nvdimm_cmd_name(cmd)
 					: nvdimm_bus_cmd_name(cmd));
@@ -643,6 +676,16 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 		in_len += in_size;
 	}
 
+	if (cmd == ND_CMD_CALL) {
+		dev_dbg(dev, "%s:%s, idx: %llu, in: %zu, out: %zu, len %zu\n",
+				__func__, dimm_name, call_dsm.nd_command,
+				in_len, out_len, buf_len);
+
+		for (i = 0; i < ARRAY_SIZE(call_dsm.nd_reserved2); i++)
+			if (call_dsm.nd_reserved2[i])
+				return -EINVAL;
+	}
+
 	/* process an output envelope */
 	for (i = 0; i < desc->out_num; i++) {
 		u32 out_size = nd_cmd_out_size(nvdimm, cmd, desc, i,
-- 
1.7.11.3

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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH v7 7/7] tools/testing/nvdimm: 'call_dsm' support
  2016-03-15 21:32 [PATCH v7 0/7] nvdimm: Add an IOCTL pass thru for DSM calls Jerry Hoemann
                   ` (5 preceding siblings ...)
  2016-03-15 21:32 ` [PATCH v7 6/7] nvdimm: Add IOCTL pass thru functions Jerry Hoemann
@ 2016-03-15 21:32 ` Jerry Hoemann
  6 siblings, 0 replies; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-15 21:32 UTC (permalink / raw)
  To: dan.j.williams; +Cc: linux-nvdimm

Enable nfit_test to use the generic 'call_dsm' envelope.

Signed-off-by: Dan Williams <dan.j.williams@intel.com>
---
 tools/testing/nvdimm/test/nfit.c | 13 +++++++++++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/tools/testing/nvdimm/test/nfit.c b/tools/testing/nvdimm/test/nfit.c
index 3187322..9cdce4b 100644
--- a/tools/testing/nvdimm/test/nfit.c
+++ b/tools/testing/nvdimm/test/nfit.c
@@ -336,12 +336,21 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
 {
 	struct acpi_nfit_desc *acpi_desc = to_acpi_desc(nd_desc);
 	struct nfit_test *t = container_of(acpi_desc, typeof(*t), acpi_desc);
+	unsigned int func = cmd;
 	int i, rc = 0, __cmd_rc;
 
 	if (!cmd_rc)
 		cmd_rc = &__cmd_rc;
 	*cmd_rc = 0;
 
+	if (cmd == ND_CMD_CALL) {
+		struct nd_cmd_pkg *call_dsm = buf;
+
+		buf_len = call_dsm->nd_size_in + call_dsm->nd_size_out;
+		buf = (void *) call_dsm->nd_payload;
+		func = call_dsm->nd_command;
+	}
+
 	if (nvdimm) {
 		struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
 
@@ -356,7 +365,7 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
 		if (i >= ARRAY_SIZE(handle))
 			return -ENXIO;
 
-		switch (cmd) {
+		switch (func) {
 		case ND_CMD_GET_CONFIG_SIZE:
 			rc = nfit_test_cmd_get_config_size(buf, buf_len);
 			break;
@@ -377,7 +386,7 @@ static int nfit_test_ctl(struct nvdimm_bus_descriptor *nd_desc,
 		if (!nd_desc || !test_bit(cmd, &nd_desc->dsm_mask))
 			return -ENOTTY;
 
-		switch (cmd) {
+		switch (func) {
 		case ND_CMD_ARS_CAP:
 			rc = nfit_test_cmd_ars_cap(buf, buf_len);
 			break;
-- 
1.7.11.3

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

^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support
  2016-03-15 21:32 ` [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support Jerry Hoemann
@ 2016-03-15 22:08   ` Dan Williams
  2016-03-16 20:21     ` Jerry Hoemann
  0 siblings, 1 reply; 14+ messages in thread
From: Dan Williams @ 2016-03-15 22:08 UTC (permalink / raw)
  To: Jerry Hoemann; +Cc: linux-nvdimm@lists.01.org

On Tue, Mar 15, 2016 at 2:32 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> Indicate to userspace that the generic 'dsm_call' capability is
> available for the given control device.  Over time we want to deprecate
> the per-dsm function ioctl commands and direct everything through the
> generic envelope.
>
> Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
> ---
>  drivers/nvdimm/core.c      | 3 +++
>  drivers/nvdimm/dimm_devs.c | 8 +++++++-
>  include/linux/libnvdimm.h  | 1 +
>  3 files changed, 11 insertions(+), 1 deletion(-)
>
> diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c
> index 79646d0..9b395e5 100644
> --- a/drivers/nvdimm/core.c
> +++ b/drivers/nvdimm/core.c
> @@ -253,6 +253,9 @@ static ssize_t commands_show(struct device *dev,
>
>         for_each_set_bit(cmd, &nd_desc->dsm_mask, BITS_PER_LONG)
>                 len += sprintf(buf + len, "%s ", nvdimm_bus_cmd_name(cmd));
> +       if (nd_desc->call_dsm)
> +               len += sprintf(buf + len, "%s ",
> +                               nvdimm_bus_cmd_name(ND_CMD_CALL));
>         len += sprintf(buf + len, "\n");
>         return len;
>  }
> diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
> index c56f882..89086d6 100644
> --- a/drivers/nvdimm/dimm_devs.c
> +++ b/drivers/nvdimm/dimm_devs.c
> @@ -274,14 +274,20 @@ EXPORT_SYMBOL_GPL(nvdimm_provider_data);
>  static ssize_t commands_show(struct device *dev,
>                 struct device_attribute *attr, char *buf)
>  {
> +       struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
>         struct nvdimm *nvdimm = to_nvdimm(dev);
> +       struct nvdimm_bus_descriptor *nd_desc;
>         int cmd, len = 0;
>
> -       if (!nvdimm->dsm_mask)
> +       if (!nvdimm->dsm_mask || !nvdimm_bus)
>                 return sprintf(buf, "\n");
>
>         for_each_set_bit(cmd, nvdimm->dsm_mask, BITS_PER_LONG)
>                 len += sprintf(buf + len, "%s ", nvdimm_cmd_name(cmd));
> +       nd_desc = nvdimm_bus->nd_desc;
> +       if (nd_desc->call_dsm)
> +               len += sprintf(buf + len, "%s ",
> +                               nvdimm_cmd_name(ND_CMD_CALL));
>         len += sprintf(buf + len, "\n");
>         return len;
>  }
> diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
> index af31d1c..458db57 100644
> --- a/include/linux/libnvdimm.h
> +++ b/include/linux/libnvdimm.h
> @@ -68,6 +68,7 @@ struct nd_mapping {
>
>  struct nvdimm_bus_descriptor {
>         const struct attribute_group **attr_groups;
> +       unsigned int call_dsm:1;

We don't need this at the bus level, only at the dimm level.  I.e
replace dsm_mask with cmd_mask as all it refers to is the ioctls that
the dimm interface supports where command 10 is the generic
nd_cmd_call interface.

If you want to tell userspace which functions a dimm supports that can
be a true "dsm_mask" exported in sysfs under the nfit/ sub-directory.

For example:

    /sys/bus/nd/devices/nmem0/commands

...shows the base/generic nd commands supported in text format, while new

    /sys/bus/nd/devices/nmem0/nfit/dsm_mask
    /sys/bus/nd/devices/nmem0/nfit/family

...shares the raw bit mask of ACPI _DSM command codes.  I'd like to
pretend that a dimm will not support multiple families even though the
spec technically allows that.  If we're forced to cross that bridge
down the road we can add a series of alt_familyX/ sub-directories to
detail the other supported families per-dimm.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support
  2016-03-15 22:08   ` Dan Williams
@ 2016-03-16 20:21     ` Jerry Hoemann
  2016-03-16 20:47       ` Dan Williams
  0 siblings, 1 reply; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-16 20:21 UTC (permalink / raw)
  To: Dan Williams; +Cc: linux-nvdimm@lists.01.org

On Tue, Mar 15, 2016 at 03:08:14PM -0700, Dan Williams wrote:
> On Tue, Mar 15, 2016 at 2:32 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> > Indicate to userspace that the generic 'dsm_call' capability is
> > available for the given control device.  Over time we want to deprecate
> > the per-dsm function ioctl commands and direct everything through the
> > generic envelope.
> >
> > Signed-off-by: Dan Williams <dan.j.williams@intel.com>
> > Signed-off-by: Jerry Hoemann <jerry.hoemann@hpe.com>
> > ---
> >  drivers/nvdimm/core.c      | 3 +++
> >  drivers/nvdimm/dimm_devs.c | 8 +++++++-
> >  include/linux/libnvdimm.h  | 1 +
> >  3 files changed, 11 insertions(+), 1 deletion(-)
> >
> > diff --git a/drivers/nvdimm/core.c b/drivers/nvdimm/core.c
> > index 79646d0..9b395e5 100644
> > --- a/drivers/nvdimm/core.c
> > +++ b/drivers/nvdimm/core.c
> > @@ -253,6 +253,9 @@ static ssize_t commands_show(struct device *dev,
> >
> >         for_each_set_bit(cmd, &nd_desc->dsm_mask, BITS_PER_LONG)
> >                 len += sprintf(buf + len, "%s ", nvdimm_bus_cmd_name(cmd));
> > +       if (nd_desc->call_dsm)
> > +               len += sprintf(buf + len, "%s ",
> > +                               nvdimm_bus_cmd_name(ND_CMD_CALL));
> >         len += sprintf(buf + len, "\n");
> >         return len;
> >  }
> > diff --git a/drivers/nvdimm/dimm_devs.c b/drivers/nvdimm/dimm_devs.c
> > index c56f882..89086d6 100644
> > --- a/drivers/nvdimm/dimm_devs.c
> > +++ b/drivers/nvdimm/dimm_devs.c
> > @@ -274,14 +274,20 @@ EXPORT_SYMBOL_GPL(nvdimm_provider_data);
> >  static ssize_t commands_show(struct device *dev,
> >                 struct device_attribute *attr, char *buf)
> >  {
> > +       struct nvdimm_bus *nvdimm_bus = walk_to_nvdimm_bus(dev);
> >         struct nvdimm *nvdimm = to_nvdimm(dev);
> > +       struct nvdimm_bus_descriptor *nd_desc;
> >         int cmd, len = 0;
> >
> > -       if (!nvdimm->dsm_mask)
> > +       if (!nvdimm->dsm_mask || !nvdimm_bus)
> >                 return sprintf(buf, "\n");
> >
> >         for_each_set_bit(cmd, nvdimm->dsm_mask, BITS_PER_LONG)
> >                 len += sprintf(buf + len, "%s ", nvdimm_cmd_name(cmd));
> > +       nd_desc = nvdimm_bus->nd_desc;
> > +       if (nd_desc->call_dsm)
> > +               len += sprintf(buf + len, "%s ",
> > +                               nvdimm_cmd_name(ND_CMD_CALL));
> >         len += sprintf(buf + len, "\n");
> >         return len;
> >  }
> > diff --git a/include/linux/libnvdimm.h b/include/linux/libnvdimm.h
> > index af31d1c..458db57 100644
> > --- a/include/linux/libnvdimm.h
> > +++ b/include/linux/libnvdimm.h
> > @@ -68,6 +68,7 @@ struct nd_mapping {
> >
> >  struct nvdimm_bus_descriptor {
> >         const struct attribute_group **attr_groups;
> > +       unsigned int call_dsm:1;
> 
> We don't need this at the bus level, only at the dimm level.  I.e
> replace dsm_mask with cmd_mask as all it refers to is the ioctls that
> the dimm interface supports where command 10 is the generic
> nd_cmd_call interface.
> 
> If you want to tell userspace which functions a dimm supports that can
> be a true "dsm_mask" exported in sysfs under the nfit/ sub-directory.
> 
> For example:
> 
>     /sys/bus/nd/devices/nmem0/commands
> 
> ...shows the base/generic nd commands supported in text format, while new
> 
>     /sys/bus/nd/devices/nmem0/nfit/dsm_mask
>     /sys/bus/nd/devices/nmem0/nfit/family
> 
> ...shares the raw bit mask of ACPI _DSM command codes.  I'd like to
> pretend that a dimm will not support multiple families even though the
> spec technically allows that.  If we're forced to cross that bridge
> down the road we can add a series of alt_familyX/ sub-directories to
> detail the other supported families per-dimm.


The above touches upon multiple things, and I'm not sure I understand
all your comments.


1. nvdimm_bus_descriptor.dsm_mask has been around for quite a while.

   I think you simply want me to rename this to cmd_mask and leave
   it in nvdimm_bus_descriptor.

   however, it is still a mask of acceptable dsm functions.  we test
   the pass thru nd_command against it.

2. nvdimm_bus_descriptor.call_dsm:1;

   This was introduced in:
	https://lists.01.org/pipermail/linux-nvdimm/2016-January/004052.html

   This flag didn't really change the system behavior.  So, I don't
   think the sense of the tests on call_dsm in core.c/commands_show() and
   dimm_devs.c/commands_show() is what you intended.

   In the respective commands_show function, I think we only want to
   call nvdimm_bus_cmd_name or nvdimm_cmd_name if and only if the underlying
   DSM matches the intel example dsm. (i.e. nvdimm_bus_cmd_name and nvdimm_cmd_name
   describes function names from the intel example dsm, not hpe's example.)

   For root commands, there is currently no divergence, so we could leave
   it as proposed, or drop it as you suggest above.

   For the non-root commands, if we're using the intel dsm, we want to call
   nvdimm_cmd_name.  But if not, then the only command available is the pass
   thru "call_dsm".

   So, I'll move a flag to the nvdimm struct and set it only if we're
   using NFIT_DEV_DIMM, not for NFIT_DEV_DIMM_N_HPE[1|2].


3.  sysfs extensions

   I had planned to do some type of extension for sysfs for passthru
   after getting basic features agreed upon.  But, i hadn't thought
   it through deeply.  As for:

	/sys/bus/nd/devices/nmem0/nfit/dsm_mask
	/sys/bus/nd/devices/nmem0/nfit/family

   Don't we want:

	/sys/bus/nd/devices/nmem0/dsm_mask
	/sys/bus/nd/devices/nmem0/family

   As the mask/family is associated with the dimm.

   Do you consider this sysfs change as a requirement for accepting the
   rest of the patch set?


   Jerry

-- 

-----------------------------------------------------------------------------
Jerry Hoemann                  Software Engineer   Hewlett Packard Enterprise
-----------------------------------------------------------------------------
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support
  2016-03-16 20:21     ` Jerry Hoemann
@ 2016-03-16 20:47       ` Dan Williams
  2016-03-16 23:31         ` Jerry Hoemann
  2016-03-18 23:27         ` Jerry Hoemann
  0 siblings, 2 replies; 14+ messages in thread
From: Dan Williams @ 2016-03-16 20:47 UTC (permalink / raw)
  To: Jerry Hoemann; +Cc: linux-nvdimm@lists.01.org

On Wed, Mar 16, 2016 at 1:21 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> On Tue, Mar 15, 2016 at 03:08:14PM -0700, Dan Williams wrote:
[..]
> The above touches upon multiple things, and I'm not sure I understand
> all your comments.
>
>
> 1. nvdimm_bus_descriptor.dsm_mask has been around for quite a while.
>
>    I think you simply want me to rename this to cmd_mask and leave
>    it in nvdimm_bus_descriptor.
>
>    however, it is still a mask of acceptable dsm functions.  we test
>    the pass thru nd_command against it.
>
> 2. nvdimm_bus_descriptor.call_dsm:1;
>
>    This was introduced in:
>         https://lists.01.org/pipermail/linux-nvdimm/2016-January/004052.html
>
>    This flag didn't really change the system behavior.  So, I don't
>    think the sense of the tests on call_dsm in core.c/commands_show() and
>    dimm_devs.c/commands_show() is what you intended.
>
>    In the respective commands_show function, I think we only want to
>    call nvdimm_bus_cmd_name or nvdimm_cmd_name if and only if the underlying
>    DSM matches the intel example dsm. (i.e. nvdimm_bus_cmd_name and nvdimm_cmd_name
>    describes function names from the intel example dsm, not hpe's example.)
>
>    For root commands, there is currently no divergence, so we could leave
>    it as proposed, or drop it as you suggest above.
>
>    For the non-root commands, if we're using the intel dsm, we want to call
>    nvdimm_cmd_name.  But if not, then the only command available is the pass
>    thru "call_dsm".

This is where I think we diverge.  There's nothing stopping the kernel
from translating a

ND_IOCTL_SET_CONFIG_DATA into an "Intel - Set Namespace Label Data" or
"HP - NVDIMM-N Set OS data".  In all cases the kernel will want to
intercept that command whether it comes in as the generic
ND_IOCTL_SET_CONFIG_DATA or via the ND_IOCTL_CALL interface.

>    So, I'll move a flag to the nvdimm struct and set it only if we're
>    using NFIT_DEV_DIMM, not for NFIT_DEV_DIMM_N_HPE[1|2].

NFIT_DEV_DIMM_N_HPE* can support more than just ND_IOCTL_CALL.  Having
the kernel do ND_IOCTL_<GENERIC> conversion to the family specific
command allows old ndctl binaries to run against new kernels.

> 3.  sysfs extensions
>
>    I had planned to do some type of extension for sysfs for passthru
>    after getting basic features agreed upon.  But, i hadn't thought
>    it through deeply.  As for:
>
>         /sys/bus/nd/devices/nmem0/nfit/dsm_mask
>         /sys/bus/nd/devices/nmem0/nfit/family
>
>    Don't we want:
>
>         /sys/bus/nd/devices/nmem0/dsm_mask
>         /sys/bus/nd/devices/nmem0/family
>
>    As the mask/family is associated with the dimm.

Hmm, I think more like this:

         /sys/bus/nd/devices/nmem0/nfit/dsm_mask
         /sys/bus/nd/devices/nmem0/family

The mask is associated with the dimm, but it is ACPI specific.
However, you're right that the family id is truly generic and should
be at the dimm level because the family type could span across
non-ACPI architectures.

>    Do you consider this sysfs change as a requirement for accepting the
>    rest of the patch set?

You can defer it to me.  I need the family information for ndctl to
start converting from the old-style to the new-style ioctl interface.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support
  2016-03-16 20:47       ` Dan Williams
@ 2016-03-16 23:31         ` Jerry Hoemann
  2016-03-17  0:28           ` Dan Williams
  2016-03-18 23:27         ` Jerry Hoemann
  1 sibling, 1 reply; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-16 23:31 UTC (permalink / raw)
  To: Dan Williams; +Cc: linux-nvdimm@lists.01.org

On Wed, Mar 16, 2016 at 01:47:43PM -0700, Dan Williams wrote:
> On Wed, Mar 16, 2016 at 1:21 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> > On Tue, Mar 15, 2016 at 03:08:14PM -0700, Dan Williams wrote:
> [..]
> > The above touches upon multiple things, and I'm not sure I understand
> > all your comments.
> >
> >
> > 1. nvdimm_bus_descriptor.dsm_mask has been around for quite a while.
> >
> >    I think you simply want me to rename this to cmd_mask and leave
> >    it in nvdimm_bus_descriptor.
> >
> >    however, it is still a mask of acceptable dsm functions.  we test
> >    the pass thru nd_command against it.
> >
> > 2. nvdimm_bus_descriptor.call_dsm:1;
> >
> >    This was introduced in:
> >         https://lists.01.org/pipermail/linux-nvdimm/2016-January/004052.html
> >
> >    This flag didn't really change the system behavior.  So, I don't
> >    think the sense of the tests on call_dsm in core.c/commands_show() and
> >    dimm_devs.c/commands_show() is what you intended.
> >
> >    In the respective commands_show function, I think we only want to
> >    call nvdimm_bus_cmd_name or nvdimm_cmd_name if and only if the underlying
> >    DSM matches the intel example dsm. (i.e. nvdimm_bus_cmd_name and nvdimm_cmd_name
> >    describes function names from the intel example dsm, not hpe's example.)
> >
> >    For root commands, there is currently no divergence, so we could leave
> >    it as proposed, or drop it as you suggest above.
> >
> >    For the non-root commands, if we're using the intel dsm, we want to call
> >    nvdimm_cmd_name.  But if not, then the only command available is the pass
> >    thru "call_dsm".


  The above deals with what sysfs displays.  This needs to be based
  upon the type of NVDIMM/DSM it is.  The dimms know what type it is 
  and displays the correct info.  So, are we okay with above?


> 
> This is where I think we diverge.  There's nothing stopping the kernel
> from translating a
> 
> ND_IOCTL_SET_CONFIG_DATA into an "Intel - Set Namespace Label Data" or
> "HP - NVDIMM-N Set OS data".  In all cases the kernel will want to
> intercept that command whether it comes in as the generic
> ND_IOCTL_SET_CONFIG_DATA or via the ND_IOCTL_CALL interface.

  I will get back to this point in a bit.

  The IOCTL interface is different (and i have a bug.)

  For the IOCTL interface the user app *thinks* it knows the type of
  NVDIMM it is, but the user could be wrong.

  In general, the system needs to explicitly prevent an application thinking
  its running on one type of NVDIMM/DSM from calling a function on a different
  type of NVDIMM/DSM.  And this is because function "7" might be defined
  by both DSMs but have different semantics.

  The way I was achieving this was by having UUID default to either:

                uuid = type_to_nvdimm_uuid(type);
                uuid = type_to_bus_uuid(type);

  And replacing uuid only if doing the pass thru (which required the
  user app specifying the uuid.)

  Since the different firmwares use different UUIDs, firmware will
  return error on such a mis-match and the kernel would pass error
  back to the user app.

  I messed this up in my patch set last week.  I switched to using
  the actual UUID on the dimm as default and not switching the one
  passed in.  This is bad and I will fix.

  nfit.c/known_nvdimm_type() needs to do more than validate the type,
  it needs to return the uuid.  I'll change this to something like
  family_to_uuid.


> 
> >    So, I'll move a flag to the nvdimm struct and set it only if we're
> >    using NFIT_DEV_DIMM, not for NFIT_DEV_DIMM_N_HPE[1|2].
> 
> NFIT_DEV_DIMM_N_HPE* can support more than just ND_IOCTL_CALL.  Having
> the kernel do ND_IOCTL_<GENERIC> conversion to the family specific
> command allows old ndctl binaries to run against new kernels.


  I think you're making the same mistake I made when I first
  started on this.  While the 0.84 NVDIMM-N spec looks like
  a super-set of the Intel Example DSM, it is not.

  There are some frustratingly small differences in the semantics
  of the calls.  So, in general we can't assume the existing ND_IOCTL_*
  calls will do what you expect if called on NVDIMM-N.
  Some will, some won't.  This is unfortunate.

  Now for HP - NVDIMM-N Set OS data, I think the semantics are
  the same, but the current implmentation of config data is very
  limited in size (much smaller than ND_LABEL_MIN_SIZE.)  So, the
  kernel isn't using it.   But in general there is a potential need
  to intercept calls, but my changes don't address that at this time.


> 
> > 3.  sysfs extensions
> >
> >    I had planned to do some type of extension for sysfs for passthru
> >    after getting basic features agreed upon.  But, i hadn't thought
> >    it through deeply.  As for:
> >
> >         /sys/bus/nd/devices/nmem0/nfit/dsm_mask
> >         /sys/bus/nd/devices/nmem0/nfit/family
> >
> >    Don't we want:
> >
> >         /sys/bus/nd/devices/nmem0/dsm_mask
> >         /sys/bus/nd/devices/nmem0/family
> >
> >    As the mask/family is associated with the dimm.
> 
> Hmm, I think more like this:
> 
>          /sys/bus/nd/devices/nmem0/nfit/dsm_mask
>          /sys/bus/nd/devices/nmem0/family
> 
> The mask is associated with the dimm, but it is ACPI specific.
> However, you're right that the family id is truly generic and should
> be at the dimm level because the family type could span across
> non-ACPI architectures.
> 
> >    Do you consider this sysfs change as a requirement for accepting the
> >    rest of the patch set?
> 
> You can defer it to me.  I need the family information for ndctl to
> start converting from the old-style to the new-style ioctl interface.

-- 

-----------------------------------------------------------------------------
Jerry Hoemann                  Software Engineer   Hewlett Packard Enterprise
-----------------------------------------------------------------------------
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support
  2016-03-16 23:31         ` Jerry Hoemann
@ 2016-03-17  0:28           ` Dan Williams
  0 siblings, 0 replies; 14+ messages in thread
From: Dan Williams @ 2016-03-17  0:28 UTC (permalink / raw)
  To: Jerry Hoemann; +Cc: linux-nvdimm@lists.01.org

On Wed, Mar 16, 2016 at 4:31 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> On Wed, Mar 16, 2016 at 01:47:43PM -0700, Dan Williams wrote:
>> On Wed, Mar 16, 2016 at 1:21 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
>> > On Tue, Mar 15, 2016 at 03:08:14PM -0700, Dan Williams wrote:
>> [..]
>> > The above touches upon multiple things, and I'm not sure I understand
>> > all your comments.
>> >
>> >
>> > 1. nvdimm_bus_descriptor.dsm_mask has been around for quite a while.
>> >
>> >    I think you simply want me to rename this to cmd_mask and leave
>> >    it in nvdimm_bus_descriptor.
>> >
>> >    however, it is still a mask of acceptable dsm functions.  we test
>> >    the pass thru nd_command against it.
>> >
>> > 2. nvdimm_bus_descriptor.call_dsm:1;
>> >
>> >    This was introduced in:
>> >         https://lists.01.org/pipermail/linux-nvdimm/2016-January/004052.html
>> >
>> >    This flag didn't really change the system behavior.  So, I don't
>> >    think the sense of the tests on call_dsm in core.c/commands_show() and
>> >    dimm_devs.c/commands_show() is what you intended.
>> >
>> >    In the respective commands_show function, I think we only want to
>> >    call nvdimm_bus_cmd_name or nvdimm_cmd_name if and only if the underlying
>> >    DSM matches the intel example dsm. (i.e. nvdimm_bus_cmd_name and nvdimm_cmd_name
>> >    describes function names from the intel example dsm, not hpe's example.)
>> >
>> >    For root commands, there is currently no divergence, so we could leave
>> >    it as proposed, or drop it as you suggest above.
>> >
>> >    For the non-root commands, if we're using the intel dsm, we want to call
>> >    nvdimm_cmd_name.  But if not, then the only command available is the pass
>> >    thru "call_dsm".
>
>
>   The above deals with what sysfs displays.  This needs to be based
>   upon the type of NVDIMM/DSM it is.  The dimms know what type it is
>   and displays the correct info.  So, are we okay with above?
>
>
>>
>> This is where I think we diverge.  There's nothing stopping the kernel
>> from translating a
>>
>> ND_IOCTL_SET_CONFIG_DATA into an "Intel - Set Namespace Label Data" or
>> "HP - NVDIMM-N Set OS data".  In all cases the kernel will want to
>> intercept that command whether it comes in as the generic
>> ND_IOCTL_SET_CONFIG_DATA or via the ND_IOCTL_CALL interface.
>
>   I will get back to this point in a bit.
>
>   The IOCTL interface is different (and i have a bug.)
>
>   For the IOCTL interface the user app *thinks* it knows the type of
>   NVDIMM it is, but the user could be wrong.
>
>   In general, the system needs to explicitly prevent an application thinking
>   its running on one type of NVDIMM/DSM from calling a function on a different
>   type of NVDIMM/DSM.  And this is because function "7" might be defined
>   by both DSMs but have different semantics.
>
>   The way I was achieving this was by having UUID default to either:
>
>                 uuid = type_to_nvdimm_uuid(type);
>                 uuid = type_to_bus_uuid(type);
>
>   And replacing uuid only if doing the pass thru (which required the
>   user app specifying the uuid.)
>
>   Since the different firmwares use different UUIDs, firmware will
>   return error on such a mis-match and the kernel would pass error
>   back to the user app.
>
>   I messed this up in my patch set last week.  I switched to using
>   the actual UUID on the dimm as default and not switching the one
>   passed in.  This is bad and I will fix.
>
>   nfit.c/known_nvdimm_type() needs to do more than validate the type,
>   it needs to return the uuid.  I'll change this to something like
>   family_to_uuid.
>
>
>>
>> >    So, I'll move a flag to the nvdimm struct and set it only if we're
>> >    using NFIT_DEV_DIMM, not for NFIT_DEV_DIMM_N_HPE[1|2].
>>
>> NFIT_DEV_DIMM_N_HPE* can support more than just ND_IOCTL_CALL.  Having
>> the kernel do ND_IOCTL_<GENERIC> conversion to the family specific
>> command allows old ndctl binaries to run against new kernels.
>
>
>   I think you're making the same mistake I made when I first
>   started on this.  While the 0.84 NVDIMM-N spec looks like
>   a super-set of the Intel Example DSM, it is not.
>
>   There are some frustratingly small differences in the semantics
>   of the calls.  So, in general we can't assume the existing ND_IOCTL_*
>   calls will do what you expect if called on NVDIMM-N.
>   Some will, some won't.  This is unfortunate.
>
>   Now for HP - NVDIMM-N Set OS data, I think the semantics are
>   the same, but the current implmentation of config data is very
>   limited in size (much smaller than ND_LABEL_MIN_SIZE.)  So, the

I could look to reduce that minimum, it was just expedient to pick
128K for the time being.

>   kernel isn't using it.   But in general there is a potential need
>   to intercept calls, but my changes don't address that at this time.
>

If there are subtle differences between similar commands, like "HP -
NVDIMM-N Set OS data" and "Intel - Set Namespace data", my proposal is
that the kernel internally handles that subtlety.  Well, at least
after crying a little on the inside at the fact that different vendors
have yet to come together on a standard for commands that are
frustratingly similar, but for some reason not identical.

The ND_IOCTL_* commands *can* be generic, but for this initial
implementation of ND_IOCTL_CALL it is fine that ND_IOCTL_CALL is the
only command that the HPE family devices support.

Later, when we go to add kernel filtering of ND_IOCTL_CALL commands,
the subtlety handling code will fall out of that effort naturally as
far as I can see.
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 14+ messages in thread

* Re: [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support
  2016-03-16 20:47       ` Dan Williams
  2016-03-16 23:31         ` Jerry Hoemann
@ 2016-03-18 23:27         ` Jerry Hoemann
  1 sibling, 0 replies; 14+ messages in thread
From: Jerry Hoemann @ 2016-03-18 23:27 UTC (permalink / raw)
  To: Dan Williams; +Cc: linux-nvdimm@lists.01.org

On Wed, Mar 16, 2016 at 01:47:43PM -0700, Dan Williams wrote:
> On Wed, Mar 16, 2016 at 1:21 PM, Jerry Hoemann <jerry.hoemann@hpe.com> wrote:
> > On Tue, Mar 15, 2016 at 03:08:14PM -0700, Dan Williams wrote:

[..]

> > 3.  sysfs extensions
> >
> >    I had planned to do some type of extension for sysfs for passthru
> >    after getting basic features agreed upon.  But, i hadn't thought
> >    it through deeply.  As for:
> >
> >         /sys/bus/nd/devices/nmem0/nfit/dsm_mask
> >         /sys/bus/nd/devices/nmem0/nfit/family
> >
> >    Don't we want:
> >
> >         /sys/bus/nd/devices/nmem0/dsm_mask
> >         /sys/bus/nd/devices/nmem0/family
> >
> >    As the mask/family is associated with the dimm.
> 
> Hmm, I think more like this:
> 
>          /sys/bus/nd/devices/nmem0/nfit/dsm_mask
>          /sys/bus/nd/devices/nmem0/family
> 
> The mask is associated with the dimm, but it is ACPI specific.
> However, you're right that the family id is truly generic and should
> be at the dimm level because the family type could span across
> non-ACPI architectures.

  We could abstract it to "cmd_mask" and put it off nmem0 like
  family.  Same reasoning should apply.  Just something to think
  about.


-- 

-----------------------------------------------------------------------------
Jerry Hoemann                  Software Engineer   Hewlett Packard Enterprise
-----------------------------------------------------------------------------
_______________________________________________
Linux-nvdimm mailing list
Linux-nvdimm@lists.01.org
https://lists.01.org/mailman/listinfo/linux-nvdimm

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2016-03-18 23:27 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-03-15 21:32 [PATCH v7 0/7] nvdimm: Add an IOCTL pass thru for DSM calls Jerry Hoemann
2016-03-15 21:32 ` [PATCH v7 1/7] ACPI / util: Fix acpi_evaluate_dsm() argument type Jerry Hoemann
2016-03-15 21:32 ` [PATCH v7 2/7] nvdimm: Add wrapper for IOCTL pass thru Jerry Hoemann
2016-03-15 21:32 ` [PATCH v7 3/7] nvdimm: Increase max envelope size for IOCTL Jerry Hoemann
2016-03-15 21:32 ` [PATCH v7 4/7] nvdimm: Add UUIDs Jerry Hoemann
2016-03-15 21:32 ` [PATCH v7 5/7] libnvdimm: advertise 'call_dsm' support Jerry Hoemann
2016-03-15 22:08   ` Dan Williams
2016-03-16 20:21     ` Jerry Hoemann
2016-03-16 20:47       ` Dan Williams
2016-03-16 23:31         ` Jerry Hoemann
2016-03-17  0:28           ` Dan Williams
2016-03-18 23:27         ` Jerry Hoemann
2016-03-15 21:32 ` [PATCH v7 6/7] nvdimm: Add IOCTL pass thru functions Jerry Hoemann
2016-03-15 21:32 ` [PATCH v7 7/7] tools/testing/nvdimm: 'call_dsm' support Jerry Hoemann

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.