diff options
author | Nishanth Aravamudan <nacc@linux.vnet.ibm.com> | 2014-01-10 18:10:41 -0500 |
---|---|---|
committer | Benjamin Herrenschmidt <benh@kernel.crashing.org> | 2014-01-14 21:46:45 -0500 |
commit | 97e7dc523acaa335d44517b06ef5609b3ee65c6a (patch) | |
tree | 927bb7eede2a0031a5bb34e88cbe6654e71c85d2 | |
parent | ae69e1eddc646ff8dc1d5439005d1f82c33f9ae7 (diff) |
Revert "pseries/iommu: Remove DDW on kexec"
After reverting 25ebc45b93452d0bc60271f178237123c4b26808
("powerpc/pseries/iommu: remove default window before attempting DDW
manipulation"), we no longer remove the base window in enable_ddw.
Therefore, we no longer need to reset the DMA window state in
find_existing_ddw_windows(). We can instead go back to what was done
before, which simply reuses the previous configuration, if any. Further,
this removes the final caller of the reset-pe-dma-windows call, so
remove those functions.
This fixes an EEH on kdump with the ipr driver. The EEH occurs, because
the initcall removes the DDW configuration (64-bit DMA window), but
doesn't ensure the ops are via the IOMMU -- a DMA operation occurs
during probe (still investigating this) and we EEH.
This reverts commit 14b6f00f8a4fdec5ccd45a0710284de301a61628.
Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com>
Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
-rw-r--r-- | arch/powerpc/platforms/pseries/iommu.c | 63 |
1 files changed, 14 insertions, 49 deletions
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index bb2e16c5ae27..33b552ffbe57 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -787,68 +787,33 @@ static u64 find_existing_ddw(struct device_node *pdn) | |||
787 | return dma_addr; | 787 | return dma_addr; |
788 | } | 788 | } |
789 | 789 | ||
790 | static void __restore_default_window(struct eeh_dev *edev, | ||
791 | u32 ddw_restore_token) | ||
792 | { | ||
793 | u32 cfg_addr; | ||
794 | u64 buid; | ||
795 | int ret; | ||
796 | |||
797 | /* | ||
798 | * Get the config address and phb buid of the PE window. | ||
799 | * Rely on eeh to retrieve this for us. | ||
800 | * Retrieve them from the pci device, not the node with the | ||
801 | * dma-window property | ||
802 | */ | ||
803 | cfg_addr = edev->config_addr; | ||
804 | if (edev->pe_config_addr) | ||
805 | cfg_addr = edev->pe_config_addr; | ||
806 | buid = edev->phb->buid; | ||
807 | |||
808 | do { | ||
809 | ret = rtas_call(ddw_restore_token, 3, 1, NULL, cfg_addr, | ||
810 | BUID_HI(buid), BUID_LO(buid)); | ||
811 | } while (rtas_busy_delay(ret)); | ||
812 | pr_info("ibm,reset-pe-dma-windows(%x) %x %x %x returned %d\n", | ||
813 | ddw_restore_token, cfg_addr, BUID_HI(buid), BUID_LO(buid), ret); | ||
814 | } | ||
815 | |||
816 | static int find_existing_ddw_windows(void) | 790 | static int find_existing_ddw_windows(void) |
817 | { | 791 | { |
792 | int len; | ||
818 | struct device_node *pdn; | 793 | struct device_node *pdn; |
794 | struct direct_window *window; | ||
819 | const struct dynamic_dma_window_prop *direct64; | 795 | const struct dynamic_dma_window_prop *direct64; |
820 | const u32 *ddw_extensions; | ||
821 | 796 | ||
822 | if (!firmware_has_feature(FW_FEATURE_LPAR)) | 797 | if (!firmware_has_feature(FW_FEATURE_LPAR)) |
823 | return 0; | 798 | return 0; |
824 | 799 | ||
825 | for_each_node_with_property(pdn, DIRECT64_PROPNAME) { | 800 | for_each_node_with_property(pdn, DIRECT64_PROPNAME) { |
826 | direct64 = of_get_property(pdn, DIRECT64_PROPNAME, NULL); | 801 | direct64 = of_get_property(pdn, DIRECT64_PROPNAME, &len); |
827 | if (!direct64) | 802 | if (!direct64) |
828 | continue; | 803 | continue; |
829 | 804 | ||
830 | /* | 805 | window = kzalloc(sizeof(*window), GFP_KERNEL); |
831 | * We need to ensure the IOMMU table is active when we | 806 | if (!window || len < sizeof(struct dynamic_dma_window_prop)) { |
832 | * return from the IOMMU setup so that the common code | 807 | kfree(window); |
833 | * can clear the table or find the holes. To that end, | 808 | remove_ddw(pdn); |
834 | * first, remove any existing DDW configuration. | 809 | continue; |
835 | */ | 810 | } |
836 | remove_ddw(pdn); | ||
837 | 811 | ||
838 | /* | 812 | window->device = pdn; |
839 | * Second, if we are running on a new enough level of | 813 | window->prop = direct64; |
840 | * firmware where the restore API is present, use it to | 814 | spin_lock(&direct_window_list_lock); |
841 | * restore the 32-bit window, which was removed in | 815 | list_add(&window->list, &direct_window_list); |
842 | * create_ddw. | 816 | spin_unlock(&direct_window_list_lock); |
843 | * If the API is not present, then create_ddw couldn't | ||
844 | * have removed the 32-bit window in the first place, so | ||
845 | * removing the DDW configuration should be sufficient. | ||
846 | */ | ||
847 | ddw_extensions = of_get_property(pdn, "ibm,ddw-extensions", | ||
848 | NULL); | ||
849 | if (ddw_extensions && ddw_extensions[0] > 0) | ||
850 | __restore_default_window(of_node_to_eeh_dev(pdn), | ||
851 | ddw_extensions[1]); | ||
852 | } | 817 | } |
853 | 818 | ||
854 | return 0; | 819 | return 0; |