]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blob
c1ba99656829aa142eac760657cea7c241f4c568
[thirdparty/kernel/stable-queue.git] /
1 From 3bf983e4e93ce8e6d69e9d63f52a66ec0856672e Mon Sep 17 00:00:00 2001
2 From: Gaurav Batra <gbatra@linux.vnet.ibm.com>
3 Date: Mon, 2 Oct 2023 22:08:02 -0500
4 Subject: powerpc/pseries/iommu: enable_ddw incorrectly returns direct mapping for SR-IOV device
5
6 From: Gaurav Batra <gbatra@linux.vnet.ibm.com>
7
8 commit 3bf983e4e93ce8e6d69e9d63f52a66ec0856672e upstream.
9
10 When a device is initialized, the driver invokes dma_supported() twice -
11 first for streaming mappings followed by coherent mappings. For an
12 SR-IOV device, default window is deleted and DDW created. With vPMEM
13 enabled, TCE mappings are dynamically created for both vPMEM and SR-IOV
14 device. There are no direct mappings.
15
16 First time when dma_supported() is called with 64 bit mask, DDW is created
17 and marked as dynamic window. The second time dma_supported() is called,
18 enable_ddw() finds existing window for the device and incorrectly returns
19 it as "direct mapping".
20
21 This only happens when size of DDW is big enough to map max LPAR memory.
22
23 This results in streaming TCEs to not get dynamically mapped, since code
24 incorrently assumes these are already pre-mapped. The adapter initially
25 comes up but goes down due to EEH.
26
27 Fixes: 381ceda88c4c ("powerpc/pseries/iommu: Make use of DDW for indirect mapping")
28 Cc: stable@vger.kernel.org # v5.15+
29 Signed-off-by: Gaurav Batra <gbatra@linux.vnet.ibm.com>
30 Signed-off-by: Michael Ellerman <mpe@ellerman.id.au>
31 Link: https://msgid.link/20231003030802.47914-1-gbatra@linux.vnet.ibm.com
32 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
33 ---
34 arch/powerpc/platforms/pseries/iommu.c | 8 ++++----
35 1 file changed, 4 insertions(+), 4 deletions(-)
36
37 --- a/arch/powerpc/platforms/pseries/iommu.c
38 +++ b/arch/powerpc/platforms/pseries/iommu.c
39 @@ -914,7 +914,8 @@ static int remove_ddw(struct device_node
40 return 0;
41 }
42
43 -static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift)
44 +static bool find_existing_ddw(struct device_node *pdn, u64 *dma_addr, int *window_shift,
45 + bool *direct_mapping)
46 {
47 struct dma_win *window;
48 const struct dynamic_dma_window_prop *dma64;
49 @@ -927,6 +928,7 @@ static bool find_existing_ddw(struct dev
50 dma64 = window->prop;
51 *dma_addr = be64_to_cpu(dma64->dma_base);
52 *window_shift = be32_to_cpu(dma64->window_shift);
53 + *direct_mapping = window->direct;
54 found = true;
55 break;
56 }
57 @@ -1270,10 +1272,8 @@ static bool enable_ddw(struct pci_dev *d
58
59 mutex_lock(&dma_win_init_mutex);
60
61 - if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len)) {
62 - direct_mapping = (len >= max_ram_len);
63 + if (find_existing_ddw(pdn, &dev->dev.archdata.dma_offset, &len, &direct_mapping))
64 goto out_unlock;
65 - }
66
67 /*
68 * If we already went through this for a previous function of