Skip to content

Commit

Permalink
crypto: nx - prevent nx 842 load if no hw driver
Browse files Browse the repository at this point in the history
Change the nx-842 common driver to wait for loading of both platform
drivers, and fail loading if the platform driver pointer is not set.
Add an independent platform driver pointer, that the platform drivers
set if they find they are able to load (i.e. if they find their platform
devicetree node(s)).

The problem is currently, the main nx-842 driver will stay loaded even
if there is no platform driver and thus no possible way it can do any
compression or decompression.  This allows the crypto 842-nx driver
to load even if it won't actually work.  For crypto compression users
(e.g. zswap) that expect an available crypto compression driver to
actually work, this is bad.  This patch fixes that, so the 842-nx crypto
compression driver won't load if it doesn't have the driver and hardware
available to perform the compression.

Signed-off-by: Dan Streetman <[email protected]>
Signed-off-by: Herbert Xu <[email protected]>
  • Loading branch information
ddstreet authored and herbertx committed Jun 3, 2015
1 parent f614e54 commit 3e648cb
Show file tree
Hide file tree
Showing 6 changed files with 148 additions and 135 deletions.
3 changes: 2 additions & 1 deletion drivers/crypto/nx/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ nx-crypto-objs := nx.o \
nx-sha256.o \
nx-sha512.o

obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS) += nx-compress.o
obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS) += nx-compress.o nx-compress-platform.o
obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_PSERIES) += nx-compress-pseries.o
obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_POWERNV) += nx-compress-powernv.o
obj-$(CONFIG_CRYPTO_DEV_NX_COMPRESS_CRYPTO) += nx-compress-crypto.o
nx-compress-objs := nx-842.o
nx-compress-platform-objs := nx-842-platform.o
nx-compress-pseries-objs := nx-842-pseries.o
nx-compress-powernv-objs := nx-842-powernv.o
nx-compress-crypto-objs := nx-842-crypto.o
84 changes: 84 additions & 0 deletions drivers/crypto/nx/nx-842-platform.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@

#include "nx-842.h"

/* this is needed, separate from the main nx-842.c driver, because that main
* driver loads the platform drivers during its init(), and it expects one
* (or none) of the platform drivers to set this pointer to its driver.
* That means this pointer can't be in the main nx-842 driver, because it
* wouldn't be accessible until after the main driver loaded, which wouldn't
* be possible as it's waiting for the platform driver to load. So place it
* here.
*/
static struct nx842_driver *driver;
static DEFINE_SPINLOCK(driver_lock);

struct nx842_driver *nx842_platform_driver(void)
{
return driver;
}
EXPORT_SYMBOL_GPL(nx842_platform_driver);

bool nx842_platform_driver_set(struct nx842_driver *_driver)
{
bool ret = false;

spin_lock(&driver_lock);

if (!driver) {
driver = _driver;
ret = true;
} else
WARN(1, "can't set platform driver, already set to %s\n",
driver->name);

spin_unlock(&driver_lock);
return ret;
}
EXPORT_SYMBOL_GPL(nx842_platform_driver_set);

/* only call this from the platform driver exit function */
void nx842_platform_driver_unset(struct nx842_driver *_driver)
{
spin_lock(&driver_lock);

if (driver == _driver)
driver = NULL;
else if (driver)
WARN(1, "can't unset platform driver %s, currently set to %s\n",
_driver->name, driver->name);
else
WARN(1, "can't unset platform driver, already unset\n");

spin_unlock(&driver_lock);
}
EXPORT_SYMBOL_GPL(nx842_platform_driver_unset);

bool nx842_platform_driver_get(void)
{
bool ret = false;

spin_lock(&driver_lock);

if (driver)
ret = try_module_get(driver->owner);

spin_unlock(&driver_lock);

return ret;
}
EXPORT_SYMBOL_GPL(nx842_platform_driver_get);

void nx842_platform_driver_put(void)
{
spin_lock(&driver_lock);

if (driver)
module_put(driver->owner);

spin_unlock(&driver_lock);
}
EXPORT_SYMBOL_GPL(nx842_platform_driver_put);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dan Streetman <[email protected]>");
MODULE_DESCRIPTION("842 H/W Compression platform driver");
17 changes: 13 additions & 4 deletions drivers/crypto/nx/nx-842-powernv.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include <asm/prom.h>
#include <asm/icswx.h>

#define MODULE_NAME NX842_POWERNV_MODULE_NAME
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dan Streetman <[email protected]>");
MODULE_DESCRIPTION("842 H/W Compression driver for IBM PowerNV processors");
Expand Down Expand Up @@ -571,6 +570,7 @@ static struct nx842_constraints nx842_powernv_constraints = {
};

static struct nx842_driver nx842_powernv_driver = {
.name = KBUILD_MODNAME,
.owner = THIS_MODULE,
.constraints = &nx842_powernv_constraints,
.compress = nx842_powernv_compress,
Expand All @@ -593,15 +593,24 @@ static __init int nx842_powernv_init(void)

pr_info("loading\n");

for_each_compatible_node(dn, NULL, NX842_POWERNV_COMPAT_NAME)
for_each_compatible_node(dn, NULL, "ibm,power-nx")
nx842_powernv_probe(dn);

if (!nx842_ct) {
pr_err("no coprocessors found\n");
return -ENODEV;
}

nx842_register_driver(&nx842_powernv_driver);
if (!nx842_platform_driver_set(&nx842_powernv_driver)) {
struct nx842_coproc *coproc, *n;

list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) {
list_del(&coproc->list);
kfree(coproc);
}

return -EEXIST;
}

pr_info("loaded\n");

Expand All @@ -613,7 +622,7 @@ static void __exit nx842_powernv_exit(void)
{
struct nx842_coproc *coproc, *n;

nx842_unregister_driver(&nx842_powernv_driver);
nx842_platform_driver_unset(&nx842_powernv_driver);

list_for_each_entry_safe(coproc, n, &nx842_coprocs, list) {
list_del(&coproc->list);
Expand Down
33 changes: 24 additions & 9 deletions drivers/crypto/nx/nx-842-pseries.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#include "nx-842.h"
#include "nx_csbcpb.h" /* struct nx_csbcpb */

#define MODULE_NAME NX842_PSERIES_MODULE_NAME
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Robert Jennings <[email protected]>");
MODULE_DESCRIPTION("842 H/W Compression driver for IBM Power processors");
Expand Down Expand Up @@ -965,6 +964,7 @@ static struct attribute_group nx842_attribute_group = {
};

static struct nx842_driver nx842_pseries_driver = {
.name = KBUILD_MODNAME,
.owner = THIS_MODULE,
.constraints = &nx842_pseries_constraints,
.compress = nx842_pseries_compress,
Expand Down Expand Up @@ -1033,8 +1033,6 @@ static int __init nx842_probe(struct vio_dev *viodev,
goto error;
}

nx842_register_driver(&nx842_pseries_driver);

return 0;

error_unlock:
Expand Down Expand Up @@ -1066,18 +1064,16 @@ static int __exit nx842_remove(struct vio_dev *viodev)
kfree(old_devdata->counters);
kfree(old_devdata);

nx842_unregister_driver(&nx842_pseries_driver);

return 0;
}

static struct vio_device_id nx842_vio_driver_ids[] = {
{NX842_PSERIES_COMPAT_NAME "-v1", NX842_PSERIES_COMPAT_NAME},
{"ibm,compression-v1", "ibm,compression"},
{"", ""},
};

static struct vio_driver nx842_vio_driver = {
.name = MODULE_NAME,
.name = KBUILD_MODNAME,
.probe = nx842_probe,
.remove = __exit_p(nx842_remove),
.get_desired_dma = nx842_get_desired_dma,
Expand All @@ -1087,10 +1083,15 @@ static struct vio_driver nx842_vio_driver = {
static int __init nx842_init(void)
{
struct nx842_devdata *new_devdata;
int ret;

pr_info("Registering IBM Power 842 compression driver\n");

BUILD_BUG_ON(sizeof(struct nx842_workmem) > NX842_MEM_COMPRESS);

if (!of_find_compatible_node(NULL, NULL, "ibm,compression"))
return -ENODEV;

RCU_INIT_POINTER(devdata, NULL);
new_devdata = kzalloc(sizeof(*new_devdata), GFP_KERNEL);
if (!new_devdata) {
Expand All @@ -1100,7 +1101,21 @@ static int __init nx842_init(void)
new_devdata->status = UNAVAILABLE;
RCU_INIT_POINTER(devdata, new_devdata);

return vio_register_driver(&nx842_vio_driver);
ret = vio_register_driver(&nx842_vio_driver);
if (ret) {
pr_err("Could not register VIO driver %d\n", ret);

kfree(new_devdata);
return ret;
}

if (!nx842_platform_driver_set(&nx842_pseries_driver)) {
vio_unregister_driver(&nx842_vio_driver);
kfree(new_devdata);
return -EEXIST;
}

return 0;
}

module_init(nx842_init);
Expand All @@ -1111,6 +1126,7 @@ static void __exit nx842_exit(void)
unsigned long flags;

pr_info("Exiting IBM Power 842 compression driver\n");
nx842_platform_driver_unset(&nx842_pseries_driver);
spin_lock_irqsave(&devdata_mutex, flags);
old_devdata = rcu_dereference_check(devdata,
lockdep_is_held(&devdata_mutex));
Expand All @@ -1120,7 +1136,6 @@ static void __exit nx842_exit(void)
if (old_devdata && old_devdata->dev)
dev_set_drvdata(old_devdata->dev, NULL);
kfree(old_devdata);
nx842_unregister_driver(&nx842_pseries_driver);
vio_unregister_driver(&nx842_vio_driver);
}

Expand Down
Loading

0 comments on commit 3e648cb

Please sign in to comment.