[PATCH] dax: Use non-exclusive wait in wait_entry_unlocked()
by Dan Williams
get_unlocked_entry() uses an exclusive wait because it is guaranteed to
eventually obtain the lock and follow on with an unlock+wakeup cycle.
The wait_entry_unlocked() path does not have the same guarantee. Rather
than open-code an extra wakeup, just switch to a non-exclusive wait.
Cc: Jan Kara <jack(a)suse.cz>
Cc: Matthew Wilcox <willy(a)infradead.org>
Reported-by: Linus Torvalds <torvalds(a)linux-foundation.org>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
fs/dax.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
diff --git a/fs/dax.c b/fs/dax.c
index 48132eca3761..042d3b31b413 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -246,18 +246,16 @@ static void wait_entry_unlocked(struct xa_state *xas, void *entry)
ewait.wait.func = wake_exceptional_entry_func;
wq = dax_entry_waitqueue(xas, entry, &ewait.key);
- prepare_to_wait_exclusive(wq, &ewait.wait, TASK_UNINTERRUPTIBLE);
+ /*
+ * Unlike get_unlocked_entry() there is no guarantee that this
+ * path ever successfully retrieves an unlocked entry before an
+ * inode dies. Perform a non-exclusive wait in case this path
+ * never successfully performs its own wake up.
+ */
+ prepare_to_wait(wq, &ewait.wait, TASK_UNINTERRUPTIBLE);
xas_unlock_irq(xas);
schedule();
finish_wait(wq, &ewait.wait);
-
- /*
- * Entry lock waits are exclusive. Wake up the next waiter since
- * we aren't sure we will acquire the entry lock and thus wake
- * the next waiter up on unlock.
- */
- if (waitqueue_active(wq))
- __wake_up(wq, TASK_NORMAL, 1, &ewait.key);
}
static void put_unlocked_entry(struct xa_state *xas, void *entry)
2 years
[GIT PULL] dax fix for 4.21
by Williams, Dan J
Hi Linus, please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm tags/dax-fix-4.21
...to receive a single fix for an issue you identified on the last dax
fix pull request. While I feel a bit silly sending a single-commit
pull-request there is nothing else queued up for dax this cycle. This
change has shipped in -next for multiple releases.
---
The following changes since commit 7566ec393f4161572ba6f11ad5171fd5d59b0fbd:
Linux 4.20-rc7 (2018-12-16 15:46:55 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm tags/dax-fix-4.21
for you to fetch changes up to d8a706414af4827fc0b4b1c0c631c607351938b9:
dax: Use non-exclusive wait in wait_entry_unlocked() (2018-12-21 11:35:53 -0800)
----------------------------------------------------------------
dax fix 4.21
* Clean up unnecessary usage of prepare_to_wait_exclusive()
----------------------------------------------------------------
Dan Williams (1):
dax: Use non-exclusive wait in wait_entry_unlocked()
fs/dax.c | 16 +++++++---------
1 file changed, 7 insertions(+), 9 deletions(-)
2 years
[GIT PULL] libnvdimm for 4.21
by Williams, Dan J
Hi Linus, please pull from:
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm tags/libnvdimm-for-4.21
...to receive the libnvdimm update for 4.21.
The vast bulk of this update is the new support for the security
capabilities of some nvdimms. It was rebased at the end of last week to
remove randconfig breakage detected in -next. It has since appeared in
subsequent -next releases with no reported issues. The userspace
tooling for this capability is still a work in progress, but the
changes survive the existing libnvdimm unit tests. The changes also
pass manual checkout on hardware and the new nfit_test emulation of the
security capability.
The touches of the security/keys/ files have received the necessary
acks from Mimi and David. Those changes were necessary to allow for a
new generic encrypted-key type, and allow the nvdimm sub-system to
lookup key material referenced by the libnvdimm-sysfs interface.
---
The following changes since commit 40e020c129cfc991e8ab4736d2665351ffd1468d:
Linux 4.20-rc6 (2018-12-09 15:31:00 -0800)
are available in the Git repository at:
git://git.kernel.org/pub/scm/linux/kernel/git/nvdimm/nvdimm tags/libnvdimm-for-4.21
for you to fetch changes up to 4b5f747e82b12b6d8ab815fc259827a615c7f2c3:
Merge miscellaneous libnvdimm updates for 4.21 (2018-12-27 19:54:10 -0800)
----------------------------------------------------------------
libnvdimm for 4.21
* Add support for the security features of nvdimm devices that
implement a security model similar to ATA hard drive security. The
security model supports locking access to the media at
device-power-loss, to be unlocked with a passphrase, and secure-erase
(crypto-scramble).
Unlike the ATA security case where the kernel expects device
security to be managed in a pre-OS environment, the libnvdimm security
implementation allows key provisioning and key-operations at OS
runtime. Keys are managed with the kernel's encrypted-keys facility to
provide data-at-rest security for the libnvdimm key material. The
usage model mirrors fscrypt key management, but is driven via
libnvdimm sysfs.
* Miscellaneous updates for api usage and comment fixes.
----------------------------------------------------------------
Andy Shevchenko (2):
libnvdimm, label: Switch to bitmap_zalloc()
libnvdimm, namespace: Replace kmemdup() with kstrndup()
Dan Williams (2):
libnvdimm/security: Quiet security operations
Merge miscellaneous libnvdimm updates for 4.21
Dave Jiang (16):
acpi/nfit: Add support for Intel DSM 1.8 commands
acpi/nfit, libnvdimm: Store dimm id as a member to struct nvdimm
keys: Export lookup_user_key to external users
keys-encrypted: add nvdimm key format type to encrypted keys
acpi/nfit, libnvdimm: Introduce nvdimm_security_ops
acpi/nfit, libnvdimm: Add freeze security support to Intel nvdimm
acpi/nfit, libnvdimm: Add unlock of nvdimm support for Intel DIMMs
acpi/nfit, libnvdimm: Add disable passphrase support to Intel nvdimm.
acpi/nfit, libnvdimm: Add enable/update passphrase support for Intel nvdimms
acpi/nfit, libnvdimm: Add support for issue secure erase DSM to Intel nvdimm
acpi/nfit, libnvdimm/security: Add security DSM overwrite support
acpi/nfit, libnvdimm/security: add Intel DSM 1.8 master passphrase support
tools/testing/nvdimm: Add test support for Intel nvdimm security DSMs
tools/testing/nvdimm: Add overwrite support for nfit_test
tools/testing/nvdimm: add Intel DSM 1.8 support for nfit_test
libnvdimm/security: Add documentation for nvdimm security support
Ocean He (2):
libnvdimm, bus: Check id immediately following ida_simple_get
ACPI/nfit: Adjust annotation for why return 0 if fail to find NFIT at start
Documentation/nvdimm/security.txt | 141 +++++++
Documentation/security/keys/trusted-encrypted.rst | 6 +-
drivers/acpi/nfit/Kconfig | 11 +
drivers/acpi/nfit/Makefile | 1 +
drivers/acpi/nfit/core.c | 103 ++++-
drivers/acpi/nfit/intel.c | 388 ++++++++++++++++++
drivers/acpi/nfit/intel.h | 76 ++++
drivers/acpi/nfit/nfit.h | 24 +-
drivers/nvdimm/Kconfig | 5 +
drivers/nvdimm/Makefile | 1 +
drivers/nvdimm/bus.c | 33 +-
drivers/nvdimm/dimm.c | 16 +-
drivers/nvdimm/dimm_devs.c | 210 +++++++++-
drivers/nvdimm/label.c | 7 +-
drivers/nvdimm/namespace_devs.c | 3 +-
drivers/nvdimm/nd-core.h | 57 +++
drivers/nvdimm/nd.h | 8 +
drivers/nvdimm/region_devs.c | 5 +
drivers/nvdimm/security.c | 454 ++++++++++++++++++++++
include/linux/key.h | 3 +
include/linux/libnvdimm.h | 76 +++-
security/keys/encrypted-keys/encrypted.c | 29 +-
security/keys/internal.h | 2 -
security/keys/process_keys.c | 1 +
tools/testing/nvdimm/Kbuild | 3 +
tools/testing/nvdimm/dimm_devs.c | 41 ++
tools/testing/nvdimm/test/nfit.c | 321 +++++++++++++++
27 files changed, 1971 insertions(+), 54 deletions(-)
create mode 100644 Documentation/nvdimm/security.txt
create mode 100644 drivers/acpi/nfit/intel.c
create mode 100644 drivers/nvdimm/security.c
create mode 100644 tools/testing/nvdimm/dimm_devs.c
2 years
Re: [ndctl PATCH] ndctl/monitor: Drop 'struct ndctl_ctx *' casts
by Dan Williams
On Wed, Dec 26, 2018 at 4:03 PM Verma, Vishal L
<vishal.l.verma(a)intel.com> wrote:
>
> On Sun, 2018-12-23 at 10:56 -0800, Dan Williams wrote:
> > Functions that take a 'struct ndctl_ctx *' are fine to take the 'void *'
> > argument representing a library context that is passed to all commands.
> > However, the shared logging macros need a defined type to dereference
> > and retrieve the log_ctx. Introduce _gen_ctx to generically represent
> > 'struct ndctl_ctx *' and 'struct daxctl_ctx *' to the log helpers, and
> > drop the remaining casts in ndctl/monitor.c. Add a couple BUILD_BUG_ON()
> > statements to backup the log_ctx expectations.
> >
> > Cc: QI Fuli <qi.fuli(a)jp.fujitsu.com>
> > Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
> > ---
> > daxctl/lib/libdaxctl.c | 4 ++++
> > ndctl/lib/libndctl.c | 4 ++++
> > ndctl/monitor.c | 22 +++++++++++-----------
> > util/log.h | 16 ++++++++++++----
> > 4 files changed, 31 insertions(+), 15 deletions(-)
> >
>
> <..>
>
> > diff --git a/util/log.h b/util/log.h
> > index 495e0d33c7f5..881971522690 100644
> > --- a/util/log.h
> > +++ b/util/log.h
> > @@ -56,10 +56,18 @@ do { \
> > # define log_notice(ctx, arg...) log_null(ctx, ## arg)
> > #endif
> >
> > -#define dbg(x, arg...) log_dbg(&(x)->ctx, ## arg)
> > -#define info(x, arg...) log_info(&(x)->ctx, ## arg)
> > -#define err(x, arg...) log_err(&(x)->ctx, ## arg)
> > -#define notice(x, arg...) log_notice(&(x)->ctx, ## arg)
> > +struct _gen_ctx {
> > + /*
> > + * Requires ndctl_ctx and daxctl_ctx keep their log_ctx as their
> > + * first element
> > + */
> > + struct log_ctx ctx;
> > +};
> > +
> > +#define dbg(x, arg...) log_dbg(&((struct _gen_ctx *)(x))->ctx, ## arg)
> > +#define info(x, arg...) log_info(&((struct _gen_ctx *)(x))->ctx, ## arg)
> > +#define err(x, arg...) log_err(&((struct _gen_ctx *)(x))->ctx, ## arg)
> > +#define notice(x, arg...) log_notice(&((struct _gen_ctx *)(x))->ctx, ## arg)
>
> Looks like this breaks ndctl/check.c's (ab)use of log_ctx directly,
> causing a segfault when this is called.
Whoops.
> I'm guessing this should be
> fixed by passing the actual ndctl_ctx to the check function, and letting
> the logging helpers dereference it correctly.
>
> It is also fixed if I move log_ctx to be the first member of btt_chk.
>
> Any thoughts on whether we should allow the embedding of log_ctx like
> this?
Yeah, I think we should, it's useful.
I'll just cook up a patch to convert the command harness to be
typesafe and drop this "offset-0" trickery.
> Other than that the patch looks good to me.
Good catch.
2 years
长期日光浴的结果
by lzio
Message sent using Winmail Mail Server
2 years
[PATCH -next] acpi, nfit: Remove duplicated include from core.c
by YueHaibing
Remove duplicated include.
Signed-off-by: YueHaibing <yuehaibing(a)huawei.com>
---
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 011d3db..328e464 100644
--- a/drivers/acpi/nfit/core.c
+++ b/drivers/acpi/nfit/core.c
@@ -26,7 +26,6 @@
#include <acpi/nfit.h>
#include "intel.h"
#include "nfit.h"
-#include "intel.h"
/*
* For readq() and writeq() on 32-bit builds, the hi-lo, lo-hi order is
2 years, 1 month
[ndctl PATCH] ndctl/monitor: Drop 'struct ndctl_ctx *' casts
by Dan Williams
Functions that take a 'struct ndctl_ctx *' are fine to take the 'void *'
argument representing a library context that is passed to all commands.
However, the shared logging macros need a defined type to dereference
and retrieve the log_ctx. Introduce _gen_ctx to generically represent
'struct ndctl_ctx *' and 'struct daxctl_ctx *' to the log helpers, and
drop the remaining casts in ndctl/monitor.c. Add a couple BUILD_BUG_ON()
statements to backup the log_ctx expectations.
Cc: QI Fuli <qi.fuli(a)jp.fujitsu.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
daxctl/lib/libdaxctl.c | 4 ++++
ndctl/lib/libndctl.c | 4 ++++
ndctl/monitor.c | 22 +++++++++++-----------
util/log.h | 16 ++++++++++++----
4 files changed, 31 insertions(+), 15 deletions(-)
diff --git a/daxctl/lib/libdaxctl.c b/daxctl/lib/libdaxctl.c
index 22f4210a7ea0..7b233b8d43f1 100644
--- a/daxctl/lib/libdaxctl.c
+++ b/daxctl/lib/libdaxctl.c
@@ -23,6 +23,7 @@
#include <ccan/array_size/array_size.h>
#include <util/log.h>
+#include <util/util.h>
#include <util/sysfs.h>
#include <daxctl/libdaxctl.h>
#include "libdaxctl-private.h"
@@ -86,6 +87,9 @@ DAXCTL_EXPORT int daxctl_new(struct daxctl_ctx **ctx)
{
struct daxctl_ctx *c;
+ /* Sanity check for the expectations of the shared log functions */
+ BUILD_BUG_ON(offsetof(struct daxctl_ctx, ctx) != 0);
+
c = calloc(1, sizeof(struct daxctl_ctx));
if (!c)
return -ENOMEM;
diff --git a/ndctl/lib/libndctl.c b/ndctl/lib/libndctl.c
index 0c3a35e5bcc9..77b29454a253 100644
--- a/ndctl/lib/libndctl.c
+++ b/ndctl/lib/libndctl.c
@@ -31,6 +31,7 @@
#include <ccan/build_assert/build_assert.h>
#include <ndctl.h>
+#include <util/util.h>
#include <util/sysfs.h>
#include <ndctl/libndctl.h>
#include <ndctl/namespace.h>
@@ -287,6 +288,9 @@ NDCTL_EXPORT int ndctl_new(struct ndctl_ctx **ctx)
const char *env;
int rc = 0;
+ /* Sanity check for the expectations of the shared log functions */
+ BUILD_BUG_ON(offsetof(struct ndctl_ctx, ctx) != 0);
+
udev = udev_new();
if (check_udev(udev) != 0)
return -ENXIO;
diff --git a/ndctl/monitor.c b/ndctl/monitor.c
index b92a133b7b94..73d75286e90b 100644
--- a/ndctl/monitor.c
+++ b/ndctl/monitor.c
@@ -623,14 +623,14 @@ int cmd_monitor(int argc, const char **argv, void *ctx)
usage_with_options(u, options);
/* default to log_standard */
- ndctl_set_log_fn((struct ndctl_ctx *)ctx, log_standard);
+ ndctl_set_log_fn(ctx, log_standard);
if (monitor.verbose)
- ndctl_set_log_priority((struct ndctl_ctx *)ctx, LOG_DEBUG);
+ ndctl_set_log_priority(ctx, LOG_DEBUG);
else
- ndctl_set_log_priority((struct ndctl_ctx *)ctx, LOG_INFO);
+ ndctl_set_log_priority(ctx, LOG_INFO);
- rc = read_config_file((struct ndctl_ctx *)ctx, &monitor, ¶m);
+ rc = read_config_file(ctx, &monitor, ¶m);
if (rc)
goto out;
@@ -638,7 +638,7 @@ int cmd_monitor(int argc, const char **argv, void *ctx)
if (strncmp(monitor.log, "./", 2) != 0)
fix_filename(prefix, (const char **)&monitor.log);
if (strncmp(monitor.log, "./syslog", 8) == 0)
- ndctl_set_log_fn((struct ndctl_ctx *)ctx, log_syslog);
+ ndctl_set_log_fn(ctx, log_syslog);
else if (strncmp(monitor.log, "./standard", 10) == 0)
; /*default, already set */
else {
@@ -649,21 +649,21 @@ int cmd_monitor(int argc, const char **argv, void *ctx)
goto out;
}
fclose(f);
- ndctl_set_log_fn((struct ndctl_ctx *)ctx, log_file);
+ ndctl_set_log_fn(ctx, log_file);
}
}
if (monitor.daemon) {
if (!monitor.log || strncmp(monitor.log, "./", 2) == 0)
- ndctl_set_log_fn((struct ndctl_ctx *)ctx, log_syslog);
+ ndctl_set_log_fn(ctx, log_syslog);
if (daemon(0, 0) != 0) {
- err((struct ndctl_ctx *)ctx, "daemon start failed\n");
+ err(ctx, "daemon start failed\n");
goto out;
}
- info((struct ndctl_ctx *)ctx, "ndctl monitor daemon started\n");
+ info(ctx, "ndctl monitor daemon started\n");
}
- if (parse_monitor_event(&monitor, (struct ndctl_ctx *)ctx))
+ if (parse_monitor_event(&monitor, ctx))
goto out;
fctx.filter_bus = filter_bus;
@@ -681,7 +681,7 @@ int cmd_monitor(int argc, const char **argv, void *ctx)
goto out;
if (!mfa.num_dimm) {
- dbg((struct ndctl_ctx *)ctx, "no dimms to monitor\n");
+ dbg(ctx, "no dimms to monitor\n");
if (!monitor.daemon)
rc = -ENXIO;
goto out;
diff --git a/util/log.h b/util/log.h
index 495e0d33c7f5..881971522690 100644
--- a/util/log.h
+++ b/util/log.h
@@ -56,10 +56,18 @@ do { \
# define log_notice(ctx, arg...) log_null(ctx, ## arg)
#endif
-#define dbg(x, arg...) log_dbg(&(x)->ctx, ## arg)
-#define info(x, arg...) log_info(&(x)->ctx, ## arg)
-#define err(x, arg...) log_err(&(x)->ctx, ## arg)
-#define notice(x, arg...) log_notice(&(x)->ctx, ## arg)
+struct _gen_ctx {
+ /*
+ * Requires ndctl_ctx and daxctl_ctx keep their log_ctx as their
+ * first element
+ */
+ struct log_ctx ctx;
+};
+
+#define dbg(x, arg...) log_dbg(&((struct _gen_ctx *)(x))->ctx, ## arg)
+#define info(x, arg...) log_info(&((struct _gen_ctx *)(x))->ctx, ## arg)
+#define err(x, arg...) log_err(&((struct _gen_ctx *)(x))->ctx, ## arg)
+#define notice(x, arg...) log_notice(&((struct _gen_ctx *)(x))->ctx, ## arg)
#ifndef HAVE_SECURE_GETENV
# ifdef HAVE___SECURE_GETENV
2 years, 1 month
[PATCH] libnvdimm/security: Quiet security operations
by Dan Williams
The security implementation is too chatty. For example, the common case
is that security is not enabled / setup, and booting a qemu
configuration currently yields:
nvdimm nmem0: request_key() found no key
nvdimm nmem0: failed to unlock dimm: -126
nvdimm nmem1: request_key() found no key
nvdimm nmem1: failed to unlock dimm: -126
Convert all security related log messages to debug level.
Cc: Dave Jiang <dave.jiang(a)intel.com>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
drivers/nvdimm/dimm.c | 2 +-
drivers/nvdimm/security.c | 30 +++++++++++++++---------------
2 files changed, 16 insertions(+), 16 deletions(-)
diff --git a/drivers/nvdimm/dimm.c b/drivers/nvdimm/dimm.c
index 1b3d9e7b2ffe..0cf58cabc9ed 100644
--- a/drivers/nvdimm/dimm.c
+++ b/drivers/nvdimm/dimm.c
@@ -62,7 +62,7 @@ static int nvdimm_probe(struct device *dev)
*/
rc = nvdimm_security_unlock(dev);
if (rc < 0)
- dev_err(dev, "failed to unlock dimm: %d\n", rc);
+ dev_dbg(dev, "failed to unlock dimm: %d\n", rc);
/*
diff --git a/drivers/nvdimm/security.c b/drivers/nvdimm/security.c
index d9a39dc251e9..f8bb746a549f 100644
--- a/drivers/nvdimm/security.c
+++ b/drivers/nvdimm/security.c
@@ -56,9 +56,9 @@ static struct key *nvdimm_request_key(struct nvdimm *nvdimm)
key = request_key(&key_type_encrypted, desc, "");
if (IS_ERR(key)) {
if (PTR_ERR(key) == -ENOKEY)
- dev_warn(dev, "request_key() found no key\n");
+ dev_dbg(dev, "request_key() found no key\n");
else
- dev_warn(dev, "request_key() upcall failed\n");
+ dev_dbg(dev, "request_key() upcall failed\n");
key = NULL;
} else {
struct encrypted_key_payload *epayload;
@@ -145,7 +145,7 @@ static int __nvdimm_security_unlock(struct nvdimm *nvdimm)
return -EIO;
if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
- dev_warn(dev, "Security operation in progress.\n");
+ dev_dbg(dev, "Security operation in progress.\n");
return -EBUSY;
}
@@ -204,13 +204,13 @@ int nvdimm_security_disable(struct nvdimm *nvdimm, unsigned int keyid)
return -EOPNOTSUPP;
if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
- dev_warn(dev, "Incorrect security state: %d\n",
+ dev_dbg(dev, "Incorrect security state: %d\n",
nvdimm->sec.state);
return -EIO;
}
if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
- dev_warn(dev, "Security operation in progress.\n");
+ dev_dbg(dev, "Security operation in progress.\n");
return -EBUSY;
}
@@ -244,7 +244,7 @@ int nvdimm_security_update(struct nvdimm *nvdimm, unsigned int keyid,
return -EOPNOTSUPP;
if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
- dev_warn(dev, "Incorrect security state: %d\n",
+ dev_dbg(dev, "Incorrect security state: %d\n",
nvdimm->sec.state);
return -EIO;
}
@@ -297,24 +297,24 @@ int nvdimm_security_erase(struct nvdimm *nvdimm, unsigned int keyid,
return -EOPNOTSUPP;
if (atomic_read(&nvdimm->busy)) {
- dev_warn(dev, "Unable to secure erase while DIMM active.\n");
+ dev_dbg(dev, "Unable to secure erase while DIMM active.\n");
return -EBUSY;
}
if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
- dev_warn(dev, "Incorrect security state: %d\n",
+ dev_dbg(dev, "Incorrect security state: %d\n",
nvdimm->sec.state);
return -EIO;
}
if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
- dev_warn(dev, "Security operation in progress.\n");
+ dev_dbg(dev, "Security operation in progress.\n");
return -EBUSY;
}
if (nvdimm->sec.ext_state != NVDIMM_SECURITY_UNLOCKED
&& pass_type == NVDIMM_MASTER) {
- dev_warn(dev,
+ dev_dbg(dev,
"Attempt to secure erase in wrong master state.\n");
return -EOPNOTSUPP;
}
@@ -348,23 +348,23 @@ int nvdimm_security_overwrite(struct nvdimm *nvdimm, unsigned int keyid)
return -EOPNOTSUPP;
if (atomic_read(&nvdimm->busy)) {
- dev_warn(dev, "Unable to overwrite while DIMM active.\n");
+ dev_dbg(dev, "Unable to overwrite while DIMM active.\n");
return -EBUSY;
}
if (dev->driver == NULL) {
- dev_warn(dev, "Unable to overwrite while DIMM active.\n");
+ dev_dbg(dev, "Unable to overwrite while DIMM active.\n");
return -EINVAL;
}
if (nvdimm->sec.state >= NVDIMM_SECURITY_FROZEN) {
- dev_warn(dev, "Incorrect security state: %d\n",
+ dev_dbg(dev, "Incorrect security state: %d\n",
nvdimm->sec.state);
return -EIO;
}
if (test_bit(NDD_SECURITY_OVERWRITE, &nvdimm->flags)) {
- dev_warn(dev, "Security operation in progress.\n");
+ dev_dbg(dev, "Security operation in progress.\n");
return -EBUSY;
}
@@ -429,7 +429,7 @@ void __nvdimm_security_overwrite_query(struct nvdimm *nvdimm)
}
if (rc < 0)
- dev_warn(&nvdimm->dev, "overwrite failed\n");
+ dev_dbg(&nvdimm->dev, "overwrite failed\n");
else
dev_dbg(&nvdimm->dev, "overwrite completed\n");
2 years, 1 month
Re: FAILED: patch "[PATCH] dax: Don't access a freed inode" failed to apply to 4.19-stable tree
by Matthew Wilcox
On Tue, Dec 11, 2018 at 03:00:09PM +0100, gregkh(a)linuxfoundation.org wrote:
>
> The patch below does not apply to the 4.19-stable tree.
> If someone wants it applied there, or to any other stable or longterm
> tree, then please email the backport, including the original git commit
> id to <stable(a)vger.kernel.org>.
I have only compile-tested this backport. Dan, do you want to run it
through some tests before Greg applies it?
>From e01d37913b5577acaa2e8e35200081eae2795087 Mon Sep 17 00:00:00 2001
From: Matthew Wilcox <willy(a)infradead.org>
Date: Tue, 11 Dec 2018 10:16:45 -0500
Subject: [PATCH 2/2] dax: Don't access a freed inode
commit 55e56f06ed71d9441f3abd5b1d3c1a870812b3fe upstream.
After we drop the i_pages lock, the inode can be freed at any time.
The get_unlocked_entry() code has no choice but to reacquire the lock,
so it can't be used here. Create a new wait_entry_unlocked() which takes
care not to acquire the lock or dereference the address_space in any way.
Fixes: c2a7d2a11552 ("filesystem-dax: Introduce dax_lock_mapping_entry()")
Cc: <stable(a)vger.kernel.org>
Signed-off-by: Matthew Wilcox <willy(a)infradead.org>
Reviewed-by: Jan Kara <jack(a)suse.cz>
Signed-off-by: Dan Williams <dan.j.williams(a)intel.com>
---
fs/dax.c | 69 ++++++++++++++++++++++++++------------------------------
1 file changed, 32 insertions(+), 37 deletions(-)
diff --git a/fs/dax.c b/fs/dax.c
index 3a2682a6c832..415605fafaeb 100644
--- a/fs/dax.c
+++ b/fs/dax.c
@@ -229,8 +229,8 @@ static void put_unlocked_mapping_entry(struct address_space *mapping,
*
* Must be called with the i_pages lock held.
*/
-static void *__get_unlocked_mapping_entry(struct address_space *mapping,
- pgoff_t index, void ***slotp, bool (*wait_fn)(void))
+static void *get_unlocked_mapping_entry(struct address_space *mapping,
+ pgoff_t index, void ***slotp)
{
void *entry, **slot;
struct wait_exceptional_entry_queue ewait;
@@ -240,8 +240,6 @@ static void *__get_unlocked_mapping_entry(struct address_space *mapping,
ewait.wait.func = wake_exceptional_entry_func;
for (;;) {
- bool revalidate;
-
entry = __radix_tree_lookup(&mapping->i_pages, index, NULL,
&slot);
if (!entry ||
@@ -256,30 +254,39 @@ static void *__get_unlocked_mapping_entry(struct address_space *mapping,
prepare_to_wait_exclusive(wq, &ewait.wait,
TASK_UNINTERRUPTIBLE);
xa_unlock_irq(&mapping->i_pages);
- revalidate = wait_fn();
+ schedule();
finish_wait(wq, &ewait.wait);
xa_lock_irq(&mapping->i_pages);
- if (revalidate) {
- put_unlocked_mapping_entry(mapping, index, entry);
- return ERR_PTR(-EAGAIN);
- }
}
}
-static bool entry_wait(void)
+/*
+ * The only thing keeping the address space around is the i_pages lock
+ * (it's cycled in clear_inode() after removing the entries from i_pages)
+ * After we call xas_unlock_irq(), we cannot touch xas->xa.
+ */
+static void wait_entry_unlocked(struct address_space *mapping, pgoff_t index,
+ void ***slotp, void *entry)
{
+ struct wait_exceptional_entry_queue ewait;
+ wait_queue_head_t *wq;
+
+ init_wait(&ewait.wait);
+ ewait.wait.func = wake_exceptional_entry_func;
+
+ wq = dax_entry_waitqueue(mapping, index, entry, &ewait.key);
+ prepare_to_wait_exclusive(wq, &ewait.wait, TASK_UNINTERRUPTIBLE);
+ xa_unlock_irq(&mapping->i_pages);
schedule();
+ finish_wait(wq, &ewait.wait);
+
/*
- * Never return an ERR_PTR() from
- * __get_unlocked_mapping_entry(), just keep looping.
+ * Entry lock waits are exclusive. Wake up the next waiter since
+ * we aren't sure we will acquire the entry lock and thus wake
+ * the next waiter up on unlock.
*/
- return false;
-}
-
-static void *get_unlocked_mapping_entry(struct address_space *mapping,
- pgoff_t index, void ***slotp)
-{
- return __get_unlocked_mapping_entry(mapping, index, slotp, entry_wait);
+ if (waitqueue_active(wq))
+ __wake_up(wq, TASK_NORMAL, 1, &ewait.key);
}
static void unlock_mapping_entry(struct address_space *mapping, pgoff_t index)
@@ -398,19 +405,6 @@ static struct page *dax_busy_page(void *entry)
return NULL;
}
-static bool entry_wait_revalidate(void)
-{
- rcu_read_unlock();
- schedule();
- rcu_read_lock();
-
- /*
- * Tell __get_unlocked_mapping_entry() to take a break, we need
- * to revalidate page->mapping after dropping locks
- */
- return true;
-}
-
bool dax_lock_mapping_entry(struct page *page)
{
pgoff_t index;
@@ -446,14 +440,15 @@ bool dax_lock_mapping_entry(struct page *page)
}
index = page->index;
- entry = __get_unlocked_mapping_entry(mapping, index, &slot,
- entry_wait_revalidate);
+ entry = __radix_tree_lookup(&mapping->i_pages, index,
+ NULL, &slot);
if (!entry) {
xa_unlock_irq(&mapping->i_pages);
break;
- } else if (IS_ERR(entry)) {
- xa_unlock_irq(&mapping->i_pages);
- WARN_ON_ONCE(PTR_ERR(entry) != -EAGAIN);
+ } else if (slot_locked(mapping, slot)) {
+ rcu_read_unlock();
+ wait_entry_unlocked(mapping, index, &slot, entry);
+ rcu_read_lock();
continue;
}
lock_slot(mapping, slot);
--
2.19.1
2 years, 1 month
Re: linux-next: Tree for Dec 21 (nvdimm/security.o)
by Randy Dunlap
On 12/21/18 12:32 AM, Stephen Rothwell wrote:
> Hi all,
>
> News: there will be no linux-next release until Jan 2. Have a good break.
>
> Changes since 20181220:
>
on x86_64:
ld: drivers/nvdimm/security.o: in function `nvdimm_request_key':
security.c:(.text+0xbe): undefined reference to `key_type_encrypted'
ld: drivers/nvdimm/security.o: in function `nvdimm_lookup_user_key.isra.1':
security.c:(.text+0x1ea): undefined reference to `key_type_encrypted'
Full randconfig file is attached.
--
~Randy
2 years, 1 month