aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomoya MORINAGA <tomoya.rohm@gmail.com>2011-11-10 20:12:17 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-04-22 19:21:42 -0400
commita1fdbba66d5a3a7ec0cc78ac8c1f19d99d37454e (patch)
tree66ca5a7a5fa87a6ba9e3da101dfd8c05d96fa1d5
parent7657523f93d637688488eb91a3ea86be12073827 (diff)
pch_phub: Improve ADE(Address Decode Enable) control
commit 9914a0de7a27ef2cb5d9aacfe50ae97ebb532f28 upstream. 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 <tomoya.rohm@gmail.com> Cc: Masayuki Ohtak <masa-korg@dsn.okisemi.com> Cc: Alexander Stein <alexander.stein@systec-electronic.com> Cc: Denis Turischev <denis@compulab.co.il> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--drivers/misc/pch_phub.c51
1 files changed, 34 insertions, 17 deletions
diff --git a/drivers/misc/pch_phub.c b/drivers/misc/pch_phub.c
index bac3eb24b61..f51c81e1884 100644
--- a/drivers/misc/pch_phub.c
+++ b/drivers/misc/pch_phub.c
@@ -118,6 +118,7 @@
118 * @pch_mac_start_address: MAC address area start address 118 * @pch_mac_start_address: MAC address area start address
119 * @pch_opt_rom_start_address: Option ROM start address 119 * @pch_opt_rom_start_address: Option ROM start address
120 * @ioh_type: Save IOH type 120 * @ioh_type: Save IOH type
121 * @pdev: pointer to pci device struct
121 */ 122 */
122struct pch_phub_reg { 123struct pch_phub_reg {
123 u32 phub_id_reg; 124 u32 phub_id_reg;
@@ -139,6 +140,7 @@ struct pch_phub_reg {
139 u32 pch_mac_start_address; 140 u32 pch_mac_start_address;
140 u32 pch_opt_rom_start_address; 141 u32 pch_opt_rom_start_address;
141 int ioh_type; 142 int ioh_type;
143 struct pci_dev *pdev;
142}; 144};
143 145
144/* SROM SPEC for MAC address assignment offset */ 146/* SROM SPEC for MAC address assignment offset */
@@ -501,6 +503,7 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
501 unsigned int orom_size; 503 unsigned int orom_size;
502 int ret; 504 int ret;
503 int err; 505 int err;
506 ssize_t rom_size;
504 507
505 struct pch_phub_reg *chip = 508 struct pch_phub_reg *chip =
506 dev_get_drvdata(container_of(kobj, struct device, kobj)); 509 dev_get_drvdata(container_of(kobj, struct device, kobj));
@@ -512,6 +515,10 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
512 } 515 }
513 516
514 /* Get Rom signature */ 517 /* Get Rom signature */
518 chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
519 if (!chip->pch_phub_extrom_base_address)
520 goto exrom_map_err;
521
515 pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address, 522 pch_phub_read_serial_rom(chip, chip->pch_opt_rom_start_address,
516 (unsigned char *)&rom_signature); 523 (unsigned char *)&rom_signature);
517 rom_signature &= 0xff; 524 rom_signature &= 0xff;
@@ -542,10 +549,13 @@ static ssize_t pch_phub_bin_read(struct file *filp, struct kobject *kobj,
542 goto return_err; 549 goto return_err;
543 } 550 }
544return_ok: 551return_ok:
552 pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
545 mutex_unlock(&pch_phub_mutex); 553 mutex_unlock(&pch_phub_mutex);
546 return addr_offset; 554 return addr_offset;
547 555
548return_err: 556return_err:
557 pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
558exrom_map_err:
549 mutex_unlock(&pch_phub_mutex); 559 mutex_unlock(&pch_phub_mutex);
550return_err_nomutex: 560return_err_nomutex:
551 return err; 561 return err;
@@ -558,6 +568,7 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
558 int err; 568 int err;
559 unsigned int addr_offset; 569 unsigned int addr_offset;
560 int ret; 570 int ret;
571 ssize_t rom_size;
561 struct pch_phub_reg *chip = 572 struct pch_phub_reg *chip =
562 dev_get_drvdata(container_of(kobj, struct device, kobj)); 573 dev_get_drvdata(container_of(kobj, struct device, kobj));
563 574
@@ -574,6 +585,12 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
574 goto return_ok; 585 goto return_ok;
575 } 586 }
576 587
588 chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
589 if (!chip->pch_phub_extrom_base_address) {
590 err = -ENOMEM;
591 goto exrom_map_err;
592 }
593
577 for (addr_offset = 0; addr_offset < count; addr_offset++) { 594 for (addr_offset = 0; addr_offset < count; addr_offset++) {
578 if (PCH_PHUB_OROM_SIZE < off + addr_offset) 595 if (PCH_PHUB_OROM_SIZE < off + addr_offset)
579 goto return_ok; 596 goto return_ok;
@@ -588,10 +605,14 @@ static ssize_t pch_phub_bin_write(struct file *filp, struct kobject *kobj,
588 } 605 }
589 606
590return_ok: 607return_ok:
608 pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
591 mutex_unlock(&pch_phub_mutex); 609 mutex_unlock(&pch_phub_mutex);
592 return addr_offset; 610 return addr_offset;
593 611
594return_err: 612return_err:
613 pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
614
615exrom_map_err:
595 mutex_unlock(&pch_phub_mutex); 616 mutex_unlock(&pch_phub_mutex);
596 return err; 617 return err;
597} 618}
@@ -601,8 +622,14 @@ static ssize_t show_pch_mac(struct device *dev, struct device_attribute *attr,
601{ 622{
602 u8 mac[8]; 623 u8 mac[8];
603 struct pch_phub_reg *chip = dev_get_drvdata(dev); 624 struct pch_phub_reg *chip = dev_get_drvdata(dev);
625 ssize_t rom_size;
626
627 chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
628 if (!chip->pch_phub_extrom_base_address)
629 return -ENOMEM;
604 630
605 pch_phub_read_gbe_mac_addr(chip, mac); 631 pch_phub_read_gbe_mac_addr(chip, mac);
632 pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
606 633
607 return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n", 634 return sprintf(buf, "%02x:%02x:%02x:%02x:%02x:%02x\n",
608 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]); 635 mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
@@ -612,6 +639,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
612 const char *buf, size_t count) 639 const char *buf, size_t count)
613{ 640{
614 u8 mac[6]; 641 u8 mac[6];
642 ssize_t rom_size;
615 struct pch_phub_reg *chip = dev_get_drvdata(dev); 643 struct pch_phub_reg *chip = dev_get_drvdata(dev);
616 644
617 if (count != 18) 645 if (count != 18)
@@ -621,7 +649,12 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
621 (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3], 649 (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
622 (u32 *)&mac[4], (u32 *)&mac[5]); 650 (u32 *)&mac[4], (u32 *)&mac[5]);
623 651
652 chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
653 if (!chip->pch_phub_extrom_base_address)
654 return -ENOMEM;
655
624 pch_phub_write_gbe_mac_addr(chip, mac); 656 pch_phub_write_gbe_mac_addr(chip, mac);
657 pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
625 658
626 return count; 659 return count;
627} 660}
@@ -644,7 +677,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
644 int retval; 677 int retval;
645 678
646 int ret; 679 int ret;
647 ssize_t rom_size;
648 struct pch_phub_reg *chip; 680 struct pch_phub_reg *chip;
649 681
650 chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); 682 chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
@@ -681,19 +713,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
681 "in pch_phub_base_address variable is %p\n", __func__, 713 "in pch_phub_base_address variable is %p\n", __func__,
682 chip->pch_phub_base_address); 714 chip->pch_phub_base_address);
683 715
684 if (id->driver_data != 3) { 716 chip->pdev = pdev; /* Save pci device struct */
685 chip->pch_phub_extrom_base_address =\
686 pci_map_rom(pdev, &rom_size);
687 if (chip->pch_phub_extrom_base_address == 0) {
688 dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__);
689 ret = -ENOMEM;
690 goto err_pci_map;
691 }
692 dev_dbg(&pdev->dev, "%s : "
693 "pci_map_rom SUCCESS and value in "
694 "pch_phub_extrom_base_address variable is %p\n",
695 __func__, chip->pch_phub_extrom_base_address);
696 }
697 717
698 if (id->driver_data == 1) { /* EG20T PCH */ 718 if (id->driver_data == 1) { /* EG20T PCH */
699 retval = sysfs_create_file(&pdev->dev.kobj, 719 retval = sysfs_create_file(&pdev->dev.kobj,
@@ -790,8 +810,6 @@ exit_bin_attr:
790 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); 810 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
791 811
792err_sysfs_create: 812err_sysfs_create:
793 pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
794err_pci_map:
795 pci_iounmap(pdev, chip->pch_phub_base_address); 813 pci_iounmap(pdev, chip->pch_phub_base_address);
796err_pci_iomap: 814err_pci_iomap:
797 pci_release_regions(pdev); 815 pci_release_regions(pdev);
@@ -809,7 +827,6 @@ static void __devexit pch_phub_remove(struct pci_dev *pdev)
809 827
810 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); 828 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
811 sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr); 829 sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
812 pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
813 pci_iounmap(pdev, chip->pch_phub_base_address); 830 pci_iounmap(pdev, chip->pch_phub_base_address);
814 pci_release_regions(pdev); 831 pci_release_regions(pdev);
815 pci_disable_device(pdev); 832 pci_disable_device(pdev);