Skip to content

Commit

Permalink
pch_phub: Improve ADE(Address Decode Enable) control
Browse files Browse the repository at this point in the history
Currently, external ROM access is enabled/disabled in probe()/remove().
So, when a buggy software access unanticipated memory area,
in case of enabling this ADE bit,
external ROM memory area can be broken.

This patch enables the ADE bit only accessing external ROM area.

Signed-off-by: Tomoya MORINAGA <[email protected]>
Cc: Masayuki Ohtak <[email protected]>
Cc: Alexander Stein <[email protected]>
Cc: Denis Turischev <[email protected]>
Signed-off-by: Andrew Morton <[email protected]>
Signed-off-by: Greg Kroah-Hartman <[email protected]>
  • Loading branch information
Tomoya MORINAGA authored and gregkh committed Nov 15, 2011
1 parent 7f2732c commit 9914a0d
Showing 1 changed file with 34 additions and 17 deletions.
51 changes: 34 additions & 17 deletions drivers/misc/pch_phub.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,7 @@
* @pch_mac_start_address: MAC address area start address
* @pch_opt_rom_start_address: Option ROM start address
* @ioh_type: Save IOH type
* @pdev: pointer to pci device struct
*/
struct pch_phub_reg {
u32 phub_id_reg;
Expand All @@ -139,6 +140,7 @@ struct pch_phub_reg {
u32 pch_mac_start_address;
u32 pch_opt_rom_start_address;
int ioh_type;
struct pci_dev *pdev;
};

/* SROM SPEC for MAC address assignment offset */
Expand Down Expand Up @@ -501,6 +503,7 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
unsigned int orom_size;
int ret;
int err;
ssize_t rom_size;

struct pch_phub_reg *chip =
dev_get_drvdata(container_of(kobj, struct device, kobj));
Expand All @@ -512,6 +515,10 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
}

/* Get Rom signature */
chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
if (!chip->pch_phub_extrom_base_address)
goto exrom_map_err;

pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
(unsigned char *)&rom_signature);
rom_signature &= 0xff;
Expand Down Expand Up @@ -542,10 +549,13 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
goto return_err;
}
return_ok:
pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
mutex_unlock(&pch_phub_mutex);
return addr_offset;

return_err:
pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
exrom_map_err:
mutex_unlock(&pch_phub_mutex);
return_err_nomutex:
return err;
Expand All @@ -558,6 +568,7 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
int err;
unsigned int addr_offset;
int ret;
ssize_t rom_size;
struct pch_phub_reg *chip =
dev_get_drvdata(container_of(kobj, struct device, kobj));

Expand All @@ -574,6 +585,12 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
goto return_ok;
}

chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
if (!chip->pch_phub_extrom_base_address) {
err = -ENOMEM;
goto exrom_map_err;
}

for (addr_offset = 0; addr_offset < count; addr_offset++) {
if (PCH_PHUB_OROM_SIZE < off + addr_offset)
goto return_ok;
Expand All @@ -588,10 +605,14 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
}

return_ok:
pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
mutex_unlock(&pch_phub_mutex);
return addr_offset;

return_err:
pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);

exrom_map_err:
mutex_unlock(&pch_phub_mutex);
return err;
}
Expand All @@ -601,8 +622,14 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
{
u8 mac[8];
struct pch_phub_reg *chip = dev_get_drvdata(dev);
ssize_t rom_size;

chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
if (!chip->pch_phub_extrom_base_address)
return -ENOMEM;

pch_phub_read_gbe_mac_addr(chip, mac);
pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);

return sprintf(buf, "%pM\n", mac);
}
Expand All @@ -611,6 +638,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
u8 mac[6];
ssize_t rom_size;
struct pch_phub_reg *chip = dev_get_drvdata(dev);

if (count != 18)
Expand All @@ -620,7 +648,12 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
(u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
(u32 *)&mac[4], (u32 *)&mac[5]);

chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
if (!chip->pch_phub_extrom_base_address)
return -ENOMEM;

pch_phub_write_gbe_mac_addr(chip, mac);
pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);

return count;
}
Expand All @@ -643,7 +676,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
int retval;

int ret;
ssize_t rom_size;
struct pch_phub_reg *chip;

chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
Expand Down Expand Up @@ -680,19 +712,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
"in pch_phub_base_address variable is %p\n", __func__,
chip->pch_phub_base_address);

if (id->driver_data != 3) {
chip->pch_phub_extrom_base_address =\
pci_map_rom(pdev, &rom_size);
if (chip->pch_phub_extrom_base_address == 0) {
dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__);
ret = -ENOMEM;
goto err_pci_map;
}
dev_dbg(&pdev->dev, "%s : "
"pci_map_rom SUCCESS and value in "
"pch_phub_extrom_base_address variable is %p\n",
__func__, chip->pch_phub_extrom_base_address);
}
chip->pdev = pdev; /* Save pci device struct */

if (id->driver_data == 1) { /* EG20T PCH */
const char *board_name;
Expand Down Expand Up @@ -792,8 +812,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);

err_sysfs_create:
pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
err_pci_map:
pci_iounmap(pdev, chip->pch_phub_base_address);
err_pci_iomap:
pci_release_regions(pdev);
Expand All @@ -811,7 +829,6 @@ static void __devexit pch_phub_remove(struct pci_dev *pdev)

sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
pci_iounmap(pdev, chip->pch_phub_base_address);
pci_release_regions(pdev);
pci_disable_device(pdev);
Expand Down

0 comments on commit 9914a0d

Please sign in to comment.