forked from Minki/linux
atm: idt77252: avoid accessing the data mapped to streaming DMA
In queue_skb(), skb->data is mapped to streaming DMA on line 850: dma_map_single(..., skb->data, ...); Then skb->data is accessed on lines 862 and 863: tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) | (skb->data[2] << 8) | (skb->data[3] << 0); and on lines 893 and 894: tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) | (skb->data[2] << 8) | (skb->data[3] << 0); These accesses may cause data inconsistency between CPU cache and hardware. To fix this problem, the calculation result of skb->data is stored in a local variable before DMA mapping, and then the driver accesses this local variable instead of skb->data. Signed-off-by: Jia-Ju Bai <baijiaju@tsinghua.edu.cn> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
a45a9e8a76
commit
cbbb64f62a
@ -835,6 +835,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
|
||||
unsigned long flags;
|
||||
int error;
|
||||
int aal;
|
||||
u32 word4;
|
||||
|
||||
if (skb->len == 0) {
|
||||
printk("%s: invalid skb->len (%d)\n", card->name, skb->len);
|
||||
@ -846,6 +847,8 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
|
||||
|
||||
tbd = &IDT77252_PRV_TBD(skb);
|
||||
vcc = ATM_SKB(skb)->vcc;
|
||||
word4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
|
||||
(skb->data[2] << 8) | (skb->data[3] << 0);
|
||||
|
||||
IDT77252_PRV_PADDR(skb) = dma_map_single(&card->pcidev->dev, skb->data,
|
||||
skb->len, DMA_TO_DEVICE);
|
||||
@ -859,8 +862,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
|
||||
tbd->word_1 = SAR_TBD_OAM | ATM_CELL_PAYLOAD | SAR_TBD_EPDU;
|
||||
tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
|
||||
tbd->word_3 = 0x00000000;
|
||||
tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
|
||||
(skb->data[2] << 8) | (skb->data[3] << 0);
|
||||
tbd->word_4 = word4;
|
||||
|
||||
if (test_bit(VCF_RSV, &vc->flags))
|
||||
vc = card->vcs[0];
|
||||
@ -890,8 +892,7 @@ queue_skb(struct idt77252_dev *card, struct vc_map *vc,
|
||||
|
||||
tbd->word_2 = IDT77252_PRV_PADDR(skb) + 4;
|
||||
tbd->word_3 = 0x00000000;
|
||||
tbd->word_4 = (skb->data[0] << 24) | (skb->data[1] << 16) |
|
||||
(skb->data[2] << 8) | (skb->data[3] << 0);
|
||||
tbd->word_4 = word4;
|
||||
break;
|
||||
|
||||
case ATM_AAL5:
|
||||
|
Loading…
Reference in New Issue
Block a user