diff --git a/drivers/acpi/nfit.c b/drivers/acpi/nfit.c
index 9ba5a9a4b943..00aa20adde7c 100644
--- a/drivers/acpi/nfit.c
+++ b/drivers/acpi/nfit.c
@@ -76,8 +76,9 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 		unsigned int buf_len)
 {
 	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_dsmcall_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;
@@ -87,8 +88,10 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 	int rc, i;
 	__u64 rev = 1, func = cmd;
 
-	struct nd_cmd_dsmcall_pkg *pkg = buf;
-	int dsm_call = (cmd == ND_CMD_CALL_DSM);
+	if (cmd == ND_CMD_CALL_DSM) {
+		call_dsm = buf;
+		func = call_dsm->dsm_fun_idx;
+	}
 
 	if (nvdimm) {
 		struct nfit_mem *nfit_mem = nvdimm_provider_data(nvdimm);
@@ -112,13 +115,11 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 		handle = adev->handle;
 		dimm_name = "bus";
 	}
-	if (dsm_call)
-		dsm_mask = ~0UL;
 
 	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;
@@ -133,14 +134,16 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 		in_buf.buffer.length += nd_cmd_in_size(nvdimm, cmd, desc,
 				i, buf);
 
-	if (dsm_call) {
+	if (call_dsm) {
 		/* must skip over package wrapper */
-		in_buf.buffer.pointer = (void *) &pkg->dsm_buf;
-		in_buf.buffer.length = pkg->dsm_in;
-		/* for pass thru must use value sent in from user space. */
-		uuid = pkg->dsm_uuid;
-		rev  = pkg->dsm_rev;
-		func = pkg->dsm_fun_idx;
+		in_buf.buffer.pointer = (void *) &call_dsm->dsm_buf;
+		in_buf.buffer.length = call_dsm->dsm_in;
+		if (memcmp(call_dsm->dsm_uuid, uuid, 16) != 0) {
+			dev_dbg(dev, "%s:%s unsupported uuid\n", dimm_name,
+					cmd_name);
+			return -EINVAL;
+		}
+		rev  = call_dsm->dsm_rev;
 	}
 
 	if (IS_ENABLED(CONFIG_ACPI_NFIT_DEBUG)) {
@@ -173,10 +176,12 @@ static int acpi_nfit_ctl(struct nvdimm_bus_descriptor *nd_desc,
 			min_t(u32, 256, out_obj->buffer.length), true);
 	}
 
-	if (dsm_call) {
-		pkg->dsm_size = out_obj->buffer.length;
-		memcpy(pkg->dsm_buf + pkg->dsm_in, out_obj->buffer.pointer,
-				min(pkg->dsm_size, pkg->dsm_out));
+	if (call_dsm) {
+		call_dsm->dsm_size = out_obj->buffer.length;
+		memcpy(call_dsm->dsm_buf + call_dsm->dsm_in,
+				out_obj->buffer.pointer,
+				min(call_dsm->dsm_size, call_dsm->dsm_out));
+
 		ACPI_FREE(out_obj);
 		return 0;
 	}
diff --git a/drivers/nvdimm/bus.c b/drivers/nvdimm/bus.c
index 6e9787ad1fe1..b86d5eda78ed 100644
--- a/drivers/nvdimm/bus.c
+++ b/drivers/nvdimm/bus.c
@@ -512,35 +512,38 @@ 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_dsmcall_pkg call_dsm;
 	const char *cmd_name, *dimm_name;
-	unsigned long dsm_mask = ~0UL;
+	unsigned int func = cmd;
+	unsigned long dsm_mask;
 	void *buf;
 	int rc, i;
 
-	struct nd_cmd_dsmcall_pkg *pkg;
-	int dsm_call = (cmd == ND_CMD_CALL_DSM);
-
 	if (nvdimm) {
 		desc = nd_cmd_dimm_desc(cmd);
 		cmd_name = nvdimm_cmd_name(cmd);
-		if (!dsm_call)
-			dsm_mask = nvdimm->dsm_mask ? *(nvdimm->dsm_mask) : 0;
+		dsm_mask = nvdimm->dsm_mask ? *(nvdimm->dsm_mask) : 0;
 		dimm_name = dev_name(&nvdimm->dev);
 	} else {
 		desc = nd_cmd_bus_desc(cmd);
 		cmd_name = nvdimm_bus_cmd_name(cmd);
-		if (!dsm_call)
-			dsm_mask = nd_desc->dsm_mask;
+		dsm_mask = nd_desc->dsm_mask;
 		dimm_name = "bus";
 	}
 
+	if (cmd == ND_CMD_CALL_DSM) {
+		if (copy_from_user(&call_dsm, p, sizeof(cmd)))
+			return -EFAULT;
+		func = call_dsm.dsm_fun_idx;
+	}
+
 	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) */
 	if (read_only)
-		switch (cmd) {
+		switch (func) {
 		case ND_CMD_VENDOR:
 		case ND_CMD_SET_CONFIG_DATA:
 		case ND_CMD_ARS_START:
@@ -572,15 +575,13 @@ static int __nd_ioctl(struct nvdimm_bus *nvdimm_bus, struct nvdimm *nvdimm,
 		in_len += in_size;
 	}
 
-	if (dsm_call) {
-		pkg = (struct nd_cmd_dsmcall_pkg *) in_env;
-
+	if (cmd == ND_CMD_CALL_DSM) {
 		dev_dbg(dev, "%s:%s rev: %llu, idx: %llu, in: %zu, out: %zu, len %zu\n",
-				__func__, dimm_name, pkg->dsm_rev,
-				pkg->dsm_fun_idx, in_len, out_len, buf_len);
+				__func__, dimm_name, call_dsm.dsm_rev,
+				call_dsm.dsm_fun_idx, in_len, out_len, buf_len);
 
-		for (i = 0; i < ARRAY_SIZE(pkg->reserved2); i++)
-			if (pkg->reserved2[i])
+		for (i = 0; i < ARRAY_SIZE(call_dsm.reserved2); i++)
+			if (call_dsm.reserved2[i])
 				return -EINVAL;
 	}
 
