diff mbox series

powerpc/pseries/iommu: enable_ddw incorrectly returns direct mapping for SR-IOV device.

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

Checks

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.

Commit Message

Gaurav Batra Oct. 2, 2023, 9:46 p.m. UTC
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.
---
 arch/powerpc/platforms/pseries/iommu.c | 7 ++++---
 1 file changed, 4 insertions(+), 3 deletions(-)

Comments

Madhavan Srinivasan Oct. 3, 2023, 2:22 a.m. UTC | #1
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 mbox series

Patch

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;
 	}