Message ID | 20231002214603.43881-1-gbatra@linux.vnet.ibm.com (mailing list archive) |
---|---|
State | Superseded, archived |
Headers | show |
Series | powerpc/pseries/iommu: enable_ddw incorrectly returns direct mapping for SR-IOV device. | expand |
Context | Check | Description |
---|---|---|
snowpatch_ozlabs/github-powerpc_ppctests | success | Successfully ran 8 jobs. |
snowpatch_ozlabs/github-powerpc_selftests | success | Successfully ran 8 jobs. |
snowpatch_ozlabs/github-powerpc_kernel_qemu | success | Successfully ran 23 jobs. |
snowpatch_ozlabs/github-powerpc_sparse | success | Successfully ran 4 jobs. |
snowpatch_ozlabs/github-powerpc_clang | success | Successfully ran 6 jobs. |
On 10/3/23 3:16 AM, Gaurav Batra wrote: > 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 capable of mapping 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. Just checked for patch submission and it is missing "Signed-off-by:" It is good to run once with checkpatch.pl before posting to mailing list maddy > --- > arch/powerpc/platforms/pseries/iommu.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c > index 16d93b580f61..d8b4adcef1ad 100644 > --- a/arch/powerpc/platforms/pseries/iommu.c > +++ b/arch/powerpc/platforms/pseries/iommu.c > @@ -914,7 +914,8 @@ static int remove_ddw(struct device_node *np, bool remove_prop, const char *win_ > return 0; > } > > -static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift) > +static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift, > + bool *direct_mapping) > { > struct dma_win *window; > 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 > dma64 = window->prop; > *dma_addr = be64_to_cpu(dma64->dma_base); > *window_shift = be32_to_cpu(dma64->window_shift); > + *direct_mapping = window->direct; > found = true; > break; > } > @@ -1270,8 +1272,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) > > mutex_lock(&dma_win_init_mutex); > > - if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len)) { > - direct_mapping = (len >= max_ram_len); > + if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len, &direct_mapping)) { > goto out_unlock; > } >
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 16d93b580f61..d8b4adcef1ad 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c @@ -914,7 +914,8 @@ static int remove_ddw(struct device_node *np, bool remove_prop, const char *win_ return 0; } -static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift) +static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift, + bool *direct_mapping) { struct dma_win *window; 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 dma64 = window->prop; *dma_addr = be64_to_cpu(dma64->dma_base); *window_shift = be32_to_cpu(dma64->window_shift); + *direct_mapping = window->direct; found = true; break; } @@ -1270,8 +1272,7 @@ static bool enable_ddw(struct pci_dev *dev, struct device_node *pdn) mutex_lock(&dma_win_init_mutex); - if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len)) { - direct_mapping = (len >= max_ram_len); + if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len, &direct_mapping)) { goto out_unlock; }