aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc
diff options
context:
space:
mode:
authorNishanth Aravamudan <nacc@linux.vnet.ibm.com>2014-01-10 18:09:38 -0500
committerBenjamin Herrenschmidt <benh@kernel.crashing.org>2014-01-14 21:46:44 -0500
commitae69e1eddc646ff8dc1d5439005d1f82c33f9ae7 (patch)
tree9cf2ab2bc02f9fb432bd825cd65f26a5b5d2c3d8 /arch/powerpc
parentc141611fb1ee2cfc374cf9be5327e97f361c4bed (diff)
Revert "powerpc/pseries/iommu: remove default window before attempting DDW manipulation"
Ben rightfully pointed out that there is a race in the "newer" DDW code. Presuming we are running on recent enough firmware that supports the "reset" DDW manipulation call, we currently always remove the base 32-bit DMA window in order to maximize the resources for Phyp when creating the 64-bit window. However, this can be problematic for the case where multiple functions are in the same PE (partitionable endpoint), where some funtions might be 32-bit DMA only. All of a sudden, the only functional DMA window for such functions is gone. We will have serious errors in such situations. The best solution is simply to revert the extension to the DDW code where we ever remove the base DMA window. This reverts commit 25ebc45b93452d0bc60271f178237123c4b26808. Signed-off-by: Nishanth Aravamudan <nacc@linux.vnet.ibm.com> Signed-off-by: Benjamin Herrenschmidt <benh@kernel.crashing.org>
Diffstat (limited to 'arch/powerpc')
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c86
1 files changed, 17 insertions, 69 deletions
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index e0299183ae54..bb2e16c5ae27 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -721,21 +721,6 @@ static int __init disable_ddw_setup(char *str)
721 721
722early_param("disable_ddw", disable_ddw_setup); 722early_param("disable_ddw", disable_ddw_setup);
723 723
724static inline void __remove_ddw(struct device_node *np, const u32 *ddw_avail, u64 liobn)
725{
726 int ret;
727
728 ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn);
729 if (ret)
730 pr_warning("%s: failed to remove DMA window: rtas returned "
731 "%d to ibm,remove-pe-dma-window(%x) %llx\n",
732 np->full_name, ret, ddw_avail[2], liobn);
733 else
734 pr_debug("%s: successfully removed DMA window: rtas returned "
735 "%d to ibm,remove-pe-dma-window(%x) %llx\n",
736 np->full_name, ret, ddw_avail[2], liobn);
737}
738
739static void remove_ddw(struct device_node *np) 724static void remove_ddw(struct device_node *np)
740{ 725{
741 struct dynamic_dma_window_prop *dwp; 726 struct dynamic_dma_window_prop *dwp;
@@ -765,7 +750,15 @@ static void remove_ddw(struct device_node *np)
765 pr_debug("%s successfully cleared tces in window.\n", 750 pr_debug("%s successfully cleared tces in window.\n",
766 np->full_name); 751 np->full_name);
767 752
768 __remove_ddw(np, ddw_avail, liobn); 753 ret = rtas_call(ddw_avail[2], 1, 1, NULL, liobn);
754 if (ret)
755 pr_warning("%s: failed to remove direct window: rtas returned "
756 "%d to ibm,remove-pe-dma-window(%x) %llx\n",
757 np->full_name, ret, ddw_avail[2], liobn);
758 else
759 pr_debug("%s: successfully removed direct window: rtas returned "
760 "%d to ibm,remove-pe-dma-window(%x) %llx\n",
761 np->full_name, ret, ddw_avail[2], liobn);
769 762
770delprop: 763delprop:
771 ret = of_remove_property(np, win64); 764 ret = of_remove_property(np, win64);
@@ -925,12 +918,6 @@ static int create_ddw(struct pci_dev *dev, const u32 *ddw_avail,
925 return ret; 918 return ret;
926} 919}
927 920
928static void restore_default_window(struct pci_dev *dev,
929 u32 ddw_restore_token)
930{
931 __restore_default_window(pci_dev_to_eeh_dev(dev), ddw_restore_token);
932}
933
934struct failed_ddw_pdn { 921struct failed_ddw_pdn {
935 struct device_node *pdn; 922 struct device_node *pdn;
936 struct list_head list; 923 struct list_head list;
@@ -958,13 +945,9 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
958 u64 dma_addr, max_addr; 945 u64 dma_addr, max_addr;
959 struct device_node *dn; 946 struct device_node *dn;
960 const u32 *uninitialized_var(ddw_avail); 947 const u32 *uninitialized_var(ddw_avail);
961 const u32 *uninitialized_var(ddw_extensions);
962 u32 ddw_restore_token = 0;
963 struct direct_window *window; 948 struct direct_window *window;
964 struct property *win64; 949 struct property *win64;
965 struct dynamic_dma_window_prop *ddwprop; 950 struct dynamic_dma_window_prop *ddwprop;
966 const void *dma_window = NULL;
967 unsigned long liobn, offset, size;
968 struct failed_ddw_pdn *fpdn; 951 struct failed_ddw_pdn *fpdn;
969 952
970 mutex_lock(&direct_window_init_mutex); 953 mutex_lock(&direct_window_init_mutex);
@@ -995,42 +978,9 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
995 */ 978 */
996 ddw_avail = of_get_property(pdn, "ibm,ddw-applicable", &len); 979 ddw_avail = of_get_property(pdn, "ibm,ddw-applicable", &len);
997 if (!ddw_avail || len < 3 * sizeof(u32)) 980 if (!ddw_avail || len < 3 * sizeof(u32))
998 goto out_unlock; 981 goto out_failed;
999
1000 /*
1001 * the extensions property is only required to exist in certain
1002 * levels of firmware and later
1003 * the ibm,ddw-extensions property is a list with the first
1004 * element containing the number of extensions and each
1005 * subsequent entry is a value corresponding to that extension
1006 */
1007 ddw_extensions = of_get_property(pdn, "ibm,ddw-extensions", &len);
1008 if (ddw_extensions) {
1009 /*
1010 * each new defined extension length should be added to
1011 * the top of the switch so the "earlier" entries also
1012 * get picked up
1013 */
1014 switch (ddw_extensions[0]) {
1015 /* ibm,reset-pe-dma-windows */
1016 case 1:
1017 ddw_restore_token = ddw_extensions[1];
1018 break;
1019 }
1020 }
1021 982
1022 /* 983 /*
1023 * Only remove the existing DMA window if we can restore back to
1024 * the default state. Removing the existing window maximizes the
1025 * resources available to firmware for dynamic window creation.
1026 */
1027 if (ddw_restore_token) {
1028 dma_window = of_get_property(pdn, "ibm,dma-window", NULL);
1029 of_parse_dma_window(pdn, dma_window, &liobn, &offset, &size);
1030 __remove_ddw(pdn, ddw_avail, liobn);
1031 }
1032
1033 /*
1034 * Query if there is a second window of size to map the 984 * Query if there is a second window of size to map the
1035 * whole partition. Query returns number of windows, largest 985 * whole partition. Query returns number of windows, largest
1036 * block assigned to PE (partition endpoint), and two bitmasks 986 * block assigned to PE (partition endpoint), and two bitmasks
@@ -1039,7 +989,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
1039 dn = pci_device_to_OF_node(dev); 989 dn = pci_device_to_OF_node(dev);
1040 ret = query_ddw(dev, ddw_avail, &query); 990 ret = query_ddw(dev, ddw_avail, &query);
1041 if (ret != 0) 991 if (ret != 0)
1042 goto out_restore_window; 992 goto out_failed;
1043 993
1044 if (query.windows_available == 0) { 994 if (query.windows_available == 0) {
1045 /* 995 /*
@@ -1048,7 +998,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
1048 * trading in for a larger page size. 998 * trading in for a larger page size.
1049 */ 999 */
1050 dev_dbg(&dev->dev, "no free dynamic windows"); 1000 dev_dbg(&dev->dev, "no free dynamic windows");
1051 goto out_restore_window; 1001 goto out_failed;
1052 } 1002 }
1053 if (be32_to_cpu(query.page_size) & 4) { 1003 if (be32_to_cpu(query.page_size) & 4) {
1054 page_shift = 24; /* 16MB */ 1004 page_shift = 24; /* 16MB */
@@ -1059,7 +1009,7 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
1059 } else { 1009 } else {
1060 dev_dbg(&dev->dev, "no supported direct page size in mask %x", 1010 dev_dbg(&dev->dev, "no supported direct page size in mask %x",
1061 query.page_size); 1011 query.page_size);
1062 goto out_restore_window; 1012 goto out_failed;
1063 } 1013 }
1064 /* verify the window * number of ptes will map the partition */ 1014 /* verify the window * number of ptes will map the partition */
1065 /* check largest block * page size > max memory hotplug addr */ 1015 /* check largest block * page size > max memory hotplug addr */
@@ -1068,14 +1018,14 @@ static u64 enable_ddw(struct pci_dev *dev, struct device_node *pdn)
1068 dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u " 1018 dev_dbg(&dev->dev, "can't map partiton max 0x%llx with %u "
1069 "%llu-sized pages\n", max_addr, query.largest_available_block, 1019 "%llu-sized pages\n", max_addr, query.largest_available_block,
1070 1ULL << page_shift); 1020 1ULL << page_shift);
1071 goto out_restore_window; 1021 goto out_failed;
1072 } 1022 }
1073 len = order_base_2(max_addr); 1023 len = order_base_2(max_addr);
1074 win64 = kzalloc(sizeof(struct property), GFP_KERNEL); 1024 win64 = kzalloc(sizeof(struct property), GFP_KERNEL);
1075 if (!win64) { 1025 if (!win64) {
1076 dev_info(&dev->dev, 1026 dev_info(&dev->dev,
1077 "couldn't allocate property for 64bit dma window\n"); 1027 "couldn't allocate property for 64bit dma window\n");
1078 goto out_restore_window; 1028 goto out_failed;
1079 } 1029 }
1080 win64->name = kstrdup(DIRECT64_PROPNAME, GFP_KERNEL); 1030 win64->name = kstrdup(DIRECT64_PROPNAME, GFP_KERNEL);
1081 win64->value = ddwprop = kmalloc(sizeof(*ddwprop), GFP_KERNEL); 1031 win64->value = ddwprop = kmalloc(sizeof(*ddwprop), GFP_KERNEL);
@@ -1137,9 +1087,7 @@ out_free_prop:
1137 kfree(win64->value); 1087 kfree(win64->value);
1138 kfree(win64); 1088 kfree(win64);
1139 1089
1140out_restore_window: 1090out_failed:
1141 if (ddw_restore_token)
1142 restore_default_window(dev, ddw_restore_token);
1143 1091
1144 fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL); 1092 fpdn = kzalloc(sizeof(*fpdn), GFP_KERNEL);
1145 if (!fpdn) 1093 if (!fpdn)