Skip to content

Commit 3bf983e

Browse files
Gaurav Batrampe
authored andcommitted
powerpc/pseries/iommu: enable_ddw incorrectly returns direct mapping for SR-IOV device
When a device is initialized, the driver invokes dma_supported() twice - first for streaming mappings followed by coherent mappings. For an SR-IOV device, default window is deleted and DDW created. With vPMEM enabled, TCE mappings are dynamically created for both vPMEM and SR-IOV device. There are no direct mappings. First time when dma_supported() is called with 64 bit mask, DDW is created and marked as dynamic window. The second time dma_supported() is called, enable_ddw() finds existing window for the device and incorrectly returns it as "direct mapping". This only happens when size of DDW is big enough to map max LPAR memory. This results in streaming TCEs to not get dynamically mapped, since code incorrently assumes these are already pre-mapped. The adapter initially comes up but goes down due to EEH. Fixes: 381ceda ("powerpc/pseries/iommu: Make use of DDW for indirect mapping") Cc: stable@vger.kernel.org # v5.15+ Signed-off-by: Gaurav Batra <gbatra@linux.vnet.ibm.com> Signed-off-by: Michael Ellerman <mpe@ellerman.id.au> Link: https://msgid.link/20231003030802.47914-1-gbatra@linux.vnet.ibm.com
1 parent efce842 commit 3bf983e

1 file changed

Lines changed: 4 additions & 4 deletions

File tree

  • arch/powerpc/platforms/pseries

arch/powerpc/platforms/pseries/iommu.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -914,7 +914,8 @@ static int remove_ddw(struct device_node *np, bool remove_prop, const char *win_
914914
return 0;
915915
}
916916

917-
static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift)
917+
static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift,
918+
bool *direct_mapping)
918919
{
919920
struct dma_win *window;
920921
const struct dynamic_dma_window_prop *dma64;
@@ -927,6 +928,7 @@ static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *windo
927928
dma64 = window->prop;
928929
*dma_addr = be64_to_cpu(dma64->dma_base);
929930
*window_shift = be32_to_cpu(dma64->window_shift);
931+
*direct_mapping = window->direct;
930932
found = true;
931933
break;
932934
}
@@ -1270,10 +1272,8 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn)
12701272

12711273
mutex_lock(&dma_win_init_mutex);
12721274

1273-
if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len)) {
1274-
direct_mapping = (len >= max_ram_len);
1275+
if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len, &direct_mapping))
12751276
goto out_unlock;
1276-
}
12771277

12781278
/*
12791279
* If we already went through this for a previous function of

0 commit comments

Comments
 (0)