Skip to contentSkip to conversation

arm: dma-mapping: Fix mapping size value

PATCH New Ritesh Harjani 2 participants 3 messages Apr 21, 2014 Arm (32-bit)

lore
Share & tools
lore

Ritesh Harjani

author Acked-by Laurent Pinchart
#0 lore raw

Fixed the commit message. Please find the new patch below:

68efd7d2fb("arm: dma-mapping: remove order parameter from arm_iommu_create_mapping()") is causing kernel panic because it wrongly sets the mapping->size value.

Unable to handle kernel NULL pointer dereference at virtual

address 000000a0
pgd = e7a84000
[000000a0] *pgd=00000000
...
PC is at bitmap_clear+0x48/0xd0
LR is at __iommu_remove_mapping+0x130/
0x164

Fix it by correcting the mapping->size value.

---
 arch/arm/mm/dma-mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/dma-mapping.c +0 -0
index f62aa06..6b00be1 100644
@@ -1963,8 +1963,8 @@ arm_iommu_create_mapping(struct bus_type *bus,

dma_addr_t base, size_t size)

        mapping->nr_bitmaps = 1;
        mapping->extensions = extensions;
        mapping->base = base;
-       mapping->size = bitmap_size << PAGE_SHIFT;
        mapping->bits = BITS_PER_BYTE * bitmap_size;

+ mapping->size = mapping->bits << PAGE_SHIFT;

        spin_lock_init(&mapping->lock);

--
1.8.1.3

Quoted 137 lines · Laurent Pinchart

Hi Ritesh,

Quoted 3 lines · On Saturday 19 April 2014 16:55:30 Ritesh Harjani wrote:

In explaining the issue below, made a mistake of taking PAGE_SIZE instead of PAGE_SHIFT (mistake mentioned inline). Although numerical values and patch is correct.

I was about to send the same patch, so, provided you fix the commit message,

Quoted 118 lines

On Sat, Apr 19, 2014 at 4:49 PM, Ritesh Harjani

Quoted 68 lines · <[email protected]> wrote:

I am finding an oops after following commit. I am on 3.10.30 kernel but applied all the latest patches from arch/arm/mm/dma-mapping.c

I added some debug logs to see what is the error, on which I found that we are incorrectly setting mapping->size value.
Please take a look at this and correct me if I am wrong here.

FAULTY COMMIT:
commit 68efd7d2fb32c2606f1da318b6a851
d933813f27

Author: Marek Szyprowski <[email protected]>
Date:   Tue Feb 25 13:01:09 2014 +0100

arm: dma-mapping: remove order parameter from
arm_iommu_create_mapping()

OOPS LOGS:

[26.898145] __alloc_iova#LINE: 1097 start = 0x3500
[26.898159] __alloc_iova#LINE:1136 iova = 0x53500000
[26.898170] __alloc_iova#LINE:1138 mapping->base= 0x50000000
[26.898181] __alloc_iova#LINE:1140 mapping->size = 0x1000000, i = 0
[26.924442] __free_iova, bitmap_index = 3

[Ritesh]: bitmap_index should be 0 for address 0x53500000. see in alloc_iova above.

[26.924454] __free_iova,addr = 0x53500000
[26.924463] __free_iova,mapping->base = 0x50000000
[26.924472] __free_iova,mapping->size = 0x1000000
[26.924482] __free_iova,bitmap_base = 0x53000000
[26.924490] __free_iova, start = 0x500

[Ritesh]: start should be 0x3500 for address 0x53500000. see in alloc_iova above.

[26.924533] Unable to handle kernel NULL pointer dereference at virtual
address 000000a0
[26.924543] pgd = e7a84000
[26.924558] [000000a0] *pgd=00000000
[26.924572] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[26.924598] Modules linked in:
[26.924613] CPU: 1 PID: 2263 Comm: BufferLiberator Not tainted 3.10.30+
#144
[26.924624] task: e7370a40 ti: e6e06000 task.ti: e6e06000
[26.924644] PC is at bitmap_clear+0x48/0xd0
[26.924659] LR is at __iommu_remove_mapping+0x130/0x164
[26.924673] pc : [<c02d0814>]    lr : [<c001bd30>]    psr: 20000093
[26.924673] sp : e6e07e20  ip : ffffffff  fp : e6e07e3c
[26.924682] r10: 00000500  r9 : c1333ea8  r8 : 80000013
[26.924692] r7 : ffffffff  r6 : 00000321  r5 : 000000a0  r4 : 00000028
[26.924707] r3 : 00000000  r2 : 00000341  r1 : 00000500  r0 : 00000000
[26.924730] Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment
user
[26.924742] Control: 10c5387d  Table: 77a8406a  DAC: 00000015

See below on how this is wrong:

here iova_base = 0x50000000
iova_size = 0x20000000
=> bits needed to map = 131072.

        => bitmap_size = 0x4000
        since bitmap_size > PAGE_SIZE
        => bitmap_size = PAGE_SIZE,  extensions = 4;

Now, mapping->size is currently set as bitmap_size << PAGE_SHIFT.

Quoted 8 lines
        =>mapping->size = 0x1000000.

mapping->size is the IOVA size, which one bitmap can address.

Now mapping->size * extensions should be size (0x20000000). which is not true, => our bitmap_size is set wrong.

it should be (mapping->bits << PAGE_SIZE) or say

It should be PAGE_SHIFT here.

Quoted 1 line

(BITS_PER_BYTE * bitmap_size << PAGE_SIZE)

It should be PAGE_SHIFT here.

Quoted 32 lines
        => (8 * 0x1000) << 12) = 0x8000000

With this IOVA_SIZE = extensions * mapping->size = 0x20000000

PATCH:

Currently mapping->size is wrongly set resulting
in OOPS (atleast we see OOPS with extension 4).

Fix this.

---

 arch/arm/mm/dma-mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/dma-mapping.c +1 -1
index f62aa06..d1701a2 100644
@@ -1963,8 +1963,8 @@ arm_iommu_create_mapping(struct bus_type *bus,
 dma_addr_t base, size_t size)
        mapping->nr_bitmaps = 1;
        mapping->extensions = extensions;
        mapping->base = base;
-       mapping->size = bitmap_size << PAGE_SHIFT;
        mapping->bits = BITS_PER_BYTE * bitmap_size;
+       mapping->size = mapping->bits << PAGE_SHIFT;
 
Quoted 2 lines

arch/arm/mm/dma-mapping.c arm_iommu_create_mapping(struct bus_type *bus, · line 1970

Quoted 2 lines
arch/arm/mm/dma-mapping.c +0 -0
        spin_lock_init(&mapping->lock);

--
Regards,

Laurent Pinchart

#1 lore raw

PATCH 1/1 arm: dma-mapping: Fix mapping size value

Hi Ritesh,

Quoted 1 line · On Monday 21 April 2014 09:31:38 Ritesh Harjani wrote:

Fixed the commit message. Please find the new patch below:

Thank you. Your mail has wrapped lines and converted tabs to whitespaces. Could you please fix that and resubmit the patch on a mail of its own (use git send-email to avoid white space issues), with the subject set to "[PATCH v2]
arm: dma-mapping: Fix mapping size value" ?

Quoted 182 lines

68efd7d2fb("arm: dma-mapping: remove order parameter from arm_iommu_create_mapping()") is causing kernel panic because it wrongly sets the mapping->size value.

Unable to handle kernel NULL pointer dereference at virtual

address 000000a0
pgd = e7a84000
[000000a0] *pgd=00000000
...
PC is at bitmap_clear+0x48/0xd0
LR is at __iommu_remove_mapping+0x130/
0x164

Fix it by correcting the mapping->size value.

---
 arch/arm/mm/dma-mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/dma-mapping.c +1 -2
index f62aa06..6b00be1 100644
@@ -1963,8 +1963,8 @@ arm_iommu_create_mapping(struct bus_type *bus,
 dma_addr_t base, size_t size)
        mapping->nr_bitmaps = 1;
        mapping->extensions = extensions;
        mapping->base = base;
-       mapping->size = bitmap_size << PAGE_SHIFT;
        mapping->bits = BITS_PER_BYTE * bitmap_size;
+       mapping->size = mapping->bits << PAGE_SHIFT;
 
        spin_lock_init(&mapping->lock);
 
 
--

1.8.1.3

On Mon, Apr 21, 2014 at 4:06 AM, Laurent Pinchart

Quoted 138 lines · <[email protected]> wrote:

Hi Ritesh,

Quoted 3 lines · On Saturday 19 April 2014 16:55:30 Ritesh Harjani wrote:

In explaining the issue below, made a mistake of taking PAGE_SIZE instead of PAGE_SHIFT (mistake mentioned inline). Although numerical values and patch is correct.

I was about to send the same patch, so, provided you fix the commit message,

Quoted 126 lines

On Sat, Apr 19, 2014 at 4:49 PM, Ritesh Harjani

Quoted 71 lines · <[email protected]> wrote:

I am finding an oops after following commit. I am on 3.10.30 kernel but applied all the latest patches from arch/arm/mm/dma-mapping.c

I added some debug logs to see what is the error, on which I found that we
are incorrectly setting mapping->size value.
Please take a look at this and correct me if I am wrong here.

FAULTY COMMIT:
commit 68efd7d2fb32c2606f1da318b6a851
d933813f27

Author: Marek Szyprowski <[email protected]>
Date:   Tue Feb 25 13:01:09 2014 +0100

arm: dma-mapping: remove order parameter from
arm_iommu_create_mapping()

OOPS LOGS:

[26.898145] __alloc_iova#LINE: 1097 start = 0x3500
[26.898159] __alloc_iova#LINE:1136 iova = 0x53500000
[26.898170] __alloc_iova#LINE:1138 mapping->base= 0x50000000
[26.898181] __alloc_iova#LINE:1140 mapping->size = 0x1000000, i = 0
[26.924442] __free_iova, bitmap_index = 3

[Ritesh]: bitmap_index should be 0 for address 0x53500000. see in alloc_iova above.

[26.924454] __free_iova,addr = 0x53500000
[26.924463] __free_iova,mapping->base = 0x50000000
[26.924472] __free_iova,mapping->size = 0x1000000
[26.924482] __free_iova,bitmap_base = 0x53000000
[26.924490] __free_iova, start = 0x500

[Ritesh]: start should be 0x3500 for address 0x53500000. see in alloc_iova
above.

[26.924533] Unable to handle kernel NULL pointer dereference at virtual
address 000000a0
[26.924543] pgd = e7a84000
[26.924558] [000000a0] *pgd=00000000
[26.924572] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[26.924598] Modules linked in:
[26.924613] CPU: 1 PID: 2263 Comm: BufferLiberator Not tainted 3.10.30+
#144
[26.924624] task: e7370a40 ti: e6e06000 task.ti: e6e06000
[26.924644] PC is at bitmap_clear+0x48/0xd0
[26.924659] LR is at __iommu_remove_mapping+0x130/0x164
[26.924673] pc : [<c02d0814>]    lr : [<c001bd30>]    psr: 20000093
[26.924673] sp : e6e07e20  ip : ffffffff  fp : e6e07e3c
[26.924682] r10: 00000500  r9 : c1333ea8  r8 : 80000013
[26.924692] r7 : ffffffff  r6 : 00000321  r5 : 000000a0  r4 : 00000028
[26.924707] r3 : 00000000  r2 : 00000341  r1 : 00000500  r0 : 00000000
[26.924730] Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM 
Segment
user
[26.924742] Control: 10c5387d  Table: 77a8406a  DAC: 00000015

See below on how this is wrong:

here iova_base = 0x50000000
iova_size = 0x20000000
=> bits needed to map = 131072.

        => bitmap_size = 0x4000
        since bitmap_size > PAGE_SIZE
        => bitmap_size = PAGE_SIZE,  extensions = 4;

Now, mapping->size is currently set as bitmap_size << PAGE_SHIFT.

Quoted 8 lines
        =>mapping->size = 0x1000000.

mapping->size is the IOVA size, which one bitmap can address.

Now mapping->size * extensions should be size (0x20000000). which is not true, => our bitmap_size is set wrong.

it should be (mapping->bits << PAGE_SIZE) or say

It should be PAGE_SHIFT here.

Quoted 1 line

(BITS_PER_BYTE * bitmap_size << PAGE_SIZE)

It should be PAGE_SHIFT here.

Quoted 37 lines
        => (8 * 0x1000) << 12) = 0x8000000

With this IOVA_SIZE = extensions * mapping->size = 0x20000000

PATCH:

Currently mapping->size is wrongly set resulting
in OOPS (atleast we see OOPS with extension 4).

Fix this.

---

 arch/arm/mm/dma-mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/dma-mapping.c +1 -1
index f62aa06..d1701a2 100644
@@ -1963,8 +1963,8 @@ arm_iommu_create_mapping(struct bus_type *bus,
 dma_addr_t base, size_t size)
 
        mapping->nr_bitmaps = 1;
        mapping->extensions = extensions;
        mapping->base = base;
 
-       mapping->size = bitmap_size << PAGE_SHIFT;
 
        mapping->bits = BITS_PER_BYTE * bitmap_size;
 
+       mapping->size = mapping->bits << PAGE_SHIFT;
 
        spin_lock_init(&mapping->lock);
Signature · 3 lines
Regards,

Laurent Pinchart
#2 lore raw

PATCH 1/1 arm: dma-mapping: Fix mapping size value

Quoted 8 lines · On Monday 21 April 2014 11:53:12 Laurent Pinchart wrote:

Hi Ritesh,

Quoted 1 line · On Monday 21 April 2014 09:31:38 Ritesh Harjani wrote:

Fixed the commit message. Please find the new patch below:

Thank you. Your mail has wrapped lines and converted tabs to whitespaces. Could you please fix that and resubmit the patch on a mail of its own (use git send-email to avoid white space issues), with the subject set to "[PATCH v2] arm: dma-mapping: Fix mapping size value" ?

Please ignore this, I had missed that you have already resent the patch.

Quoted 193 lines
Quoted 193 lines

68efd7d2fb("arm: dma-mapping: remove order parameter from arm_iommu_create_mapping()") is causing kernel panic because it wrongly sets the mapping->size value.

Unable to handle kernel NULL pointer dereference at virtual

address 000000a0
pgd = e7a84000
[000000a0] *pgd=00000000
...
PC is at bitmap_clear+0x48/0xd0
LR is at __iommu_remove_mapping+0x130/
0x164

Fix it by correcting the mapping->size value.

---

 arch/arm/mm/dma-mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/dma-mapping.c +1 -2
index f62aa06..6b00be1 100644
@@ -1963,8 +1963,8 @@ arm_iommu_create_mapping(struct bus_type *bus,
 dma_addr_t base, size_t size)
 
        mapping->nr_bitmaps = 1;
        mapping->extensions = extensions;
        mapping->base = base;
 
-       mapping->size = bitmap_size << PAGE_SHIFT;
 
        mapping->bits = BITS_PER_BYTE * bitmap_size;
 
+       mapping->size = mapping->bits << PAGE_SHIFT;
 
        spin_lock_init(&mapping->lock);
 
--

1.8.1.3

On Mon, Apr 21, 2014 at 4:06 AM, Laurent Pinchart

Quoted 144 lines · <[email protected]> wrote:

Hi Ritesh,

Quoted 3 lines · On Saturday 19 April 2014 16:55:30 Ritesh Harjani wrote:

In explaining the issue below, made a mistake of taking PAGE_SIZE instead of PAGE_SHIFT (mistake mentioned inline). Although numerical values and patch is correct.

I was about to send the same patch, so, provided you fix the commit message,

Quoted 132 lines

On Sat, Apr 19, 2014 at 4:49 PM, Ritesh Harjani

Quoted 77 lines · <[email protected]> wrote:

I am finding an oops after following commit. I am on 3.10.30 kernel but
applied all the latest patches from arch/arm/mm/dma-mapping.c

I added some debug logs to see what is the error, on which I found that
we
are incorrectly setting mapping->size value.
Please take a look at this and correct me if I am wrong here.

FAULTY COMMIT:
commit 68efd7d2fb32c2606f1da318b6a851
d933813f27

Author: Marek Szyprowski <[email protected]>
Date:   Tue Feb 25 13:01:09 2014 +0100

arm: dma-mapping: remove order parameter from arm_iommu_create_mapping()

OOPS LOGS:

[26.898145] __alloc_iova#LINE: 1097 start = 0x3500
[26.898159] __alloc_iova#LINE:1136 iova = 0x53500000
[26.898170] __alloc_iova#LINE:1138 mapping->base= 0x50000000
[26.898181] __alloc_iova#LINE:1140 mapping->size = 0x1000000, i = 0
[26.924442] __free_iova, bitmap_index = 3

[Ritesh]: bitmap_index should be 0 for address 0x53500000. see in alloc_iova above.

[26.924454] __free_iova,addr = 0x53500000
[26.924463] __free_iova,mapping->base = 0x50000000
[26.924472] __free_iova,mapping->size = 0x1000000
[26.924482] __free_iova,bitmap_base = 0x53000000
[26.924490] __free_iova, start = 0x500

[Ritesh]: start should be 0x3500 for address 0x53500000. see in alloc_iova
above.

[26.924533] Unable to handle kernel NULL pointer dereference at
virtual
address 000000a0
[26.924543] pgd = e7a84000
[26.924558] [000000a0] *pgd=00000000
[26.924572] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
[26.924598] Modules linked in:
[26.924613] CPU: 1 PID: 2263 Comm: BufferLiberator Not tainted
3.10.30+
#144
[26.924624] task: e7370a40 ti: e6e06000 task.ti: e6e06000
[26.924644] PC is at bitmap_clear+0x48/0xd0
[26.924659] LR is at __iommu_remove_mapping+0x130/0x164
[26.924673] pc : [<c02d0814>]    lr : [<c001bd30>]    psr: 20000093
[26.924673] sp : e6e07e20  ip : ffffffff  fp : e6e07e3c
[26.924682] r10: 00000500  r9 : c1333ea8  r8 : 80000013
[26.924692] r7 : ffffffff  r6 : 00000321  r5 : 000000a0  r4 :
00000028
[26.924707] r3 : 00000000  r2 : 00000341  r1 : 00000500  r0 :
00000000
[26.924730] Flags: nzCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM
Segment
user
[26.924742] Control: 10c5387d  Table: 77a8406a  DAC: 00000015

See below on how this is wrong:

here iova_base = 0x50000000
iova_size = 0x20000000
=> bits needed to map = 131072.

        => bitmap_size = 0x4000
        since bitmap_size > PAGE_SIZE
        => bitmap_size = PAGE_SIZE,  extensions = 4;

Now, mapping->size is currently set as bitmap_size << PAGE_SHIFT.

Quoted 8 lines
        =>mapping->size = 0x1000000.

mapping->size is the IOVA size, which one bitmap can address.

Now mapping->size * extensions should be size (0x20000000). which is not true, => our bitmap_size is set wrong.

it should be (mapping->bits << PAGE_SIZE) or say

It should be PAGE_SHIFT here.

Quoted 1 line

(BITS_PER_BYTE * bitmap_size << PAGE_SIZE)

It should be PAGE_SHIFT here.

Quoted 37 lines
        => (8 * 0x1000) << 12) = 0x8000000

With this IOVA_SIZE = extensions * mapping->size = 0x20000000

PATCH:

Currently mapping->size is wrongly set resulting in OOPS (atleast we see OOPS with extension 4).

Fix this.

---

 arch/arm/mm/dma-mapping.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm/mm/dma-mapping.c +1 -1
index f62aa06..d1701a2 100644
@@ -1963,8 +1963,8 @@ arm_iommu_create_mapping(struct bus_type *bus,
 dma_addr_t base, size_t size)
 
        mapping->nr_bitmaps = 1;
        mapping->extensions = extensions;
        mapping->base = base;
 
-       mapping->size = bitmap_size << PAGE_SHIFT;
 
        mapping->bits = BITS_PER_BYTE * bitmap_size;
 
+       mapping->size = mapping->bits << PAGE_SHIFT;
 
        spin_lock_init(&mapping->lock);
Signature · 3 lines
Regards,

Laurent Pinchart