mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-26 05:34:13 +08:00
[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>
This commit is contained in:
parent
e73a780272
commit
de8cd9a306
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user