Skip to content

Commit

Permalink
[WATCHDOG] iTCO_wdt: fix memory corruption when RCBA is disabled by h…
Browse files Browse the repository at this point in the history
…ardware

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>
  • Loading branch information
Denis V. Lunev authored and Wim Van Sebroeck committed Jun 18, 2009
1 parent e73a780 commit de8cd9a
Showing 1 changed file with 9 additions and 3 deletions.
12 changes: 9 additions & 3 deletions drivers/watchdog/iTCO_wdt.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand All @@ -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 */
Expand All @@ -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);
Expand Down Expand Up @@ -742,9 +747,10 @@ static int __devinit iTCO_wdt_init(struct pci_dev *pdev,
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;
Expand Down

0 comments on commit de8cd9a

Please sign in to comment.