diff options
author | Denis V. Lunev <den@openvz.org> | 2009-06-05 15:13:08 +0400 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2009-06-18 07:31:44 +0000 |
commit | de8cd9a3067e25a860c225f794e6b249b73aa6b1 (patch) | |
tree | 48dd6f028d03fd4595ee3551e57eae35f73cc671 /drivers/watchdog | |
parent | e73a780272a46e897bd94a4870fd6b6a8655d2d4 (diff) | |
download | op-kernel-dev-de8cd9a3067e25a860c225f794e6b249b73aa6b1.zip op-kernel-dev-de8cd9a3067e25a860c225f794e6b249b73aa6b1.tar.gz |
[WATCHDOG] iTCO_wdt: fix memory corruption when RCBA is disabled by hardware
According to 9.1.33 on p.343 of ICH8.pdf RCBA can be disabled by
hardware if bit 0 of RCBA register is not set.
Perform correct check for this to prevent memory corruption under
some virtual machines where this feature is disabled.
Signed-off-by: Denis V. Lunev <den@openvz.org>
CC: Vasily Averin <vvs@openvz.org>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/iTCO_wdt.c | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c index 6284961..6a51edd 100644 --- a/drivers/watchdog/iTCO_wdt.c +++ b/drivers/watchdog/iTCO_wdt.c @@ -666,6 +666,11 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, GCS = RCBA + ICH6_GCS(0x3410). */ if (iTCO_wdt_private.iTCO_version == 2) { pci_read_config_dword(pdev, 0xf0, &base_address); + if ((base_address & 1) == 0) { + printk(KERN_ERR PFX "RCBA is disabled by harddware\n"); + ret = -ENODEV; + goto out; + } RCBA = base_address & 0xffffc000; iTCO_wdt_private.gcs = ioremap((RCBA + 0x3410), 4); } @@ -675,7 +680,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, printk(KERN_ERR PFX "failed to reset NO_REBOOT flag, " "reboot disabled by hardware\n"); ret = -ENODEV; /* Cannot reset NO_REBOOT bit */ - goto out; + goto out_unmap; } /* Set the NO_REBOOT bit to prevent later reboots, just for sure */ @@ -686,7 +691,7 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev, printk(KERN_ERR PFX "I/O address 0x%04lx already in use\n", SMI_EN); ret = -EIO; - goto out; + goto out_unmap; } /* Bit 13: TCO_EN -> 0 = Disables TCO logic generating an SMI# */ val32 = inl(SMI_EN); @@ -742,9 +747,10 @@ unreg_region: release_region(TCOBASE, 0x20); unreg_smi_en: release_region(SMI_EN, 4); -out: +out_unmap: if (iTCO_wdt_private.iTCO_version == 2) iounmap(iTCO_wdt_private.gcs); +out: pci_dev_put(iTCO_wdt_private.pdev); iTCO_wdt_private.ACPIBASE = 0; return ret; |