aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTomoya MORINAGA <tomoya.rohm@gmail.com>2011-11-10 20:12:17 -0500
committerGreg Kroah-Hartman <gregkh@suse.de>2011-11-15 14:01:49 -0500
commit9914a0de7a27ef2cb5d9aacfe50ae97ebb532f28 (patch)
treec165181386be5e577ca6dbc1c4fc136a8fb16437
parent7f2732c8d7c06f97cc1d530177b7635cb8890b35 (diff)
pch_phub: Improve ADE(Address Decode Enable) control
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 e7c59950a2a5..0e2c1819a944 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, "%pM\n", mac); 634 return sprintf(buf, "%pM\n", mac);
608} 635}
@@ -611,6 +638,7 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
611 const char *buf, size_t count) 638 const char *buf, size_t count)
612{ 639{
613 u8 mac[6]; 640 u8 mac[6];
641 ssize_t rom_size;
614 struct pch_phub_reg *chip = dev_get_drvdata(dev); 642 struct pch_phub_reg *chip = dev_get_drvdata(dev);
615 643
616 if (count != 18) 644 if (count != 18)
@@ -620,7 +648,12 @@ static ssize_t store_pch_mac(struct device *dev, struct device_attribute *attr,
620 (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3], 648 (u32 *)&mac[0], (u32 *)&mac[1], (u32 *)&mac[2], (u32 *)&mac[3],
621 (u32 *)&mac[4], (u32 *)&mac[5]); 649 (u32 *)&mac[4], (u32 *)&mac[5]);
622 650
651 chip->pch_phub_extrom_base_address = pci_map_rom(chip->pdev, &rom_size);
652 if (!chip->pch_phub_extrom_base_address)
653 return -ENOMEM;
654
623 pch_phub_write_gbe_mac_addr(chip, mac); 655 pch_phub_write_gbe_mac_addr(chip, mac);
656 pci_unmap_rom(chip->pdev, chip->pch_phub_extrom_base_address);
624 657
625 return count; 658 return count;
626} 659}
@@ -643,7 +676,6 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
643 int retval; 676 int retval;
644 677
645 int ret; 678 int ret;
646 ssize_t rom_size;
647 struct pch_phub_reg *chip; 679 struct pch_phub_reg *chip;
648 680
649 chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL); 681 chip = kzalloc(sizeof(struct pch_phub_reg), GFP_KERNEL);
@@ -680,19 +712,7 @@ static int __devinit pch_phub_probe(struct pci_dev *pdev,
680 "in pch_phub_base_address variable is %p\n", __func__, 712 "in pch_phub_base_address variable is %p\n", __func__,
681 chip->pch_phub_base_address); 713 chip->pch_phub_base_address);
682 714
683 if (id->driver_data != 3) { 715 chip->pdev = pdev; /* Save pci device struct */
684 chip->pch_phub_extrom_base_address =\
685 pci_map_rom(pdev, &rom_size);
686 if (chip->pch_phub_extrom_base_address == 0) {
687 dev_err(&pdev->dev, "%s: pci_map_rom FAILED", __func__);
688 ret = -ENOMEM;
689 goto err_pci_map;
690 }
691 dev_dbg(&pdev->dev, "%s : "
692 "pci_map_rom SUCCESS and value in "
693 "pch_phub_extrom_base_address variable is %p\n",
694 __func__, chip->pch_phub_extrom_base_address);
695 }
696 716
697 if (id->driver_data == 1) { /* EG20T PCH */ 717 if (id->driver_data == 1) { /* EG20T PCH */
698 const char *board_name; 718 const char *board_name;
@@ -792,8 +812,6 @@ exit_bin_attr:
792 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); 812 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
793 813
794err_sysfs_create: 814err_sysfs_create:
795 pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
796err_pci_map:
797 pci_iounmap(pdev, chip->pch_phub_base_address); 815 pci_iounmap(pdev, chip->pch_phub_base_address);
798err_pci_iomap: 816err_pci_iomap:
799 pci_release_regions(pdev); 817 pci_release_regions(pdev);
@@ -811,7 +829,6 @@ static void __devexit pch_phub_remove(struct pci_dev *pdev)
811 829
812 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr); 830 sysfs_remove_file(&pdev->dev.kobj, &dev_attr_pch_mac.attr);
813 sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr); 831 sysfs_remove_bin_file(&pdev->dev.kobj, &pch_bin_attr);
814 pci_unmap_rom(pdev, chip->pch_phub_extrom_base_address);
815 pci_iounmap(pdev, chip->pch_phub_base_address); 832 pci_iounmap(pdev, chip->pch_phub_base_address);
816 pci_release_regions(pdev); 833 pci_release_regions(pdev);
817 pci_disable_device(pdev); 834 pci_disable_device(pdev);