Skip to content

Commit

Permalink
hwrng: geode - Revert managed API changes
Browse files Browse the repository at this point in the history
After commit e9afc74 ("hwrng: geode - Use linux/io.h instead of
asm/io.h") the geode-rng driver uses devres with pci_dev->dev to keep
track of resources, but does not actually register a PCI driver.  This
results in the following issues:

1.  The driver leaks memory because the driver does not attach to a
device.  The driver only uses the PCI device as a reference.   devm_*()
functions will release resources on driver detach, which the geode-rng
driver will never do.  As a result,

2.  The driver cannot be reloaded because there is always a use of the
ioport and region after the first load of the driver.

Revert the changes made by  e9afc74 ("hwrng: geode - Use linux/io.h
instead of asm/io.h").

Cc: <stable@vger.kernel.org>
Signed-off-by: Prarit Bhargava <prarit@redhat.com>
Fixes: 6e9b5e7 ("hwrng: geode - Migrate to managed API")
Cc: Matt Mackall <mpm@selenic.com>
Cc: Corentin LABBE <clabbe.montjoie@gmail.com>
Cc: PrasannaKumar Muralidharan <prasannatsmkumar@gmail.com>
Cc: Wei Yongjun <weiyongjun1@huawei.com>
Cc: linux-crypto@vger.kernel.org
Cc: linux-geode@lists.infradead.org
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
  • Loading branch information
Prarit Bhargava authored and Herbert Xu committed Mar 16, 2017
1 parent 69db700 commit 8c75704
Showing 1 changed file with 35 additions and 15 deletions.
50 changes: 35 additions & 15 deletions drivers/char/hw_random/geode-rng.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
#include <linux/module.h>
#include <linux/pci.h>


#define PFX KBUILD_MODNAME ": "

#define GEODE_RNG_DATA_REG 0x50
#define GEODE_RNG_STATUS_REG 0x54

Expand Down Expand Up @@ -82,34 +85,51 @@ static struct hwrng geode_rng = {

static int __init mod_init(void)
{
int err = -ENODEV;
struct pci_dev *pdev = NULL;
const struct pci_device_id *ent;
void __iomem *mem;
unsigned long rng_base;

for_each_pci_dev(pdev) {
ent = pci_match_id(pci_tbl, pdev);
if (ent) {
rng_base = pci_resource_start(pdev, 0);
if (rng_base == 0)
return -ENODEV;

mem = devm_ioremap(&pdev->dev, rng_base, 0x58);
if (!mem)
return -ENOMEM;
geode_rng.priv = (unsigned long)mem;

pr_info("AMD Geode RNG detected\n");
return devm_hwrng_register(&pdev->dev, &geode_rng);
}
if (ent)
goto found;
}

/* Device not found. */
return -ENODEV;
goto out;

found:
rng_base = pci_resource_start(pdev, 0);
if (rng_base == 0)
goto out;
err = -ENOMEM;
mem = ioremap(rng_base, 0x58);
if (!mem)
goto out;
geode_rng.priv = (unsigned long)mem;

pr_info("AMD Geode RNG detected\n");
err = hwrng_register(&geode_rng);
if (err) {
pr_err(PFX "RNG registering failed (%d)\n",
err);
goto err_unmap;
}
out:
return err;

err_unmap:
iounmap(mem);
goto out;
}

static void __exit mod_exit(void)
{
void __iomem *mem = (void __iomem *)geode_rng.priv;

hwrng_unregister(&geode_rng);
iounmap(mem);
}

module_init(mod_init);
Expand Down

0 comments on commit 8c75704

Please sign in to comment.