[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [NET] back: Copy tx_ring data before verification
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID dcee7eca71afd3525543388d4aa22ec95564cdc1 # Parent af1aa35265eb0d2566e14ed530e4e7e442a9f132 [NET] back: Copy tx_ring data before verification We need to make a copy of data from tx_ring before verifying them as otherwise what we end up using may be different from what was verified. Signed-off-by: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx> --- linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 55 ++++++++++----------- 1 files changed, 28 insertions(+), 27 deletions(-) diff -r af1aa35265eb -r dcee7eca71af linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Oct 12 14:28:59 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Thu Oct 12 16:09:15 2006 +0100 @@ -883,20 +883,28 @@ static void netbk_tx_err(netif_t *netif, netif_put(netif); } -static int netbk_count_requests(netif_t *netif, netif_tx_request_t *txp, - int work_to_do) -{ - netif_tx_request_t *first = txp; +static int netbk_count_requests(netif_t *netif, netif_tx_request_t *first, + netif_tx_request_t *txp, int work_to_do) +{ RING_IDX cons = netif->tx.req_cons; int frags = 0; - while (txp->flags & NETTXF_more_data) { + if (!(first->flags & NETTXF_more_data)) + return 0; + + do { if (frags >= work_to_do) { DPRINTK("Need more frags\n"); return -frags; } - txp = RING_GET_REQUEST(&netif->tx, cons + frags); + if (unlikely(frags >= MAX_SKB_FRAGS)) { + DPRINTK("Too many frags\n"); + return -frags; + } + + memcpy(txp, RING_GET_REQUEST(&netif->tx, cons + frags), + sizeof(*txp)); if (txp->size > first->size) { DPRINTK("Frags galore\n"); return -frags; @@ -910,27 +918,25 @@ static int netbk_count_requests(netif_t txp->offset, txp->size); return -frags; } - } + } while ((txp++)->flags & NETTXF_more_data); return frags; } static gnttab_map_grant_ref_t *netbk_get_requests(netif_t *netif, struct sk_buff *skb, + netif_tx_request_t *txp, gnttab_map_grant_ref_t *mop) { struct skb_shared_info *shinfo = skb_shinfo(skb); skb_frag_t *frags = shinfo->frags; - netif_tx_request_t *txp; unsigned long pending_idx = *((u16 *)skb->data); - RING_IDX cons = netif->tx.req_cons; int i, start; /* Skip first skb fragment if it is on same page as header fragment. */ start = ((unsigned long)shinfo->frags[0].page == pending_idx); - for (i = start; i < shinfo->nr_frags; i++) { - txp = RING_GET_REQUEST(&netif->tx, cons++); + for (i = start; i < shinfo->nr_frags; i++, txp++) { pending_idx = pending_ring[MASK_PEND_IDX(pending_cons++)]; gnttab_set_map_op(mop++, idx_to_kaddr(pending_idx), @@ -1044,7 +1050,7 @@ int netbk_get_extras(netif_t *netif, str int netbk_get_extras(netif_t *netif, struct netif_extra_info *extras, int work_to_do) { - struct netif_extra_info *extra; + struct netif_extra_info extra; RING_IDX cons = netif->tx.req_cons; do { @@ -1053,18 +1059,18 @@ int netbk_get_extras(netif_t *netif, str return -EBADR; } - extra = (struct netif_extra_info *) - RING_GET_REQUEST(&netif->tx, cons); - if (unlikely(!extra->type || - extra->type >= XEN_NETIF_EXTRA_TYPE_MAX)) { + memcpy(&extra, RING_GET_REQUEST(&netif->tx, cons), + sizeof(extra)); + if (unlikely(!extra.type || + extra.type >= XEN_NETIF_EXTRA_TYPE_MAX)) { netif->tx.req_cons = ++cons; - DPRINTK("Invalid extra type: %d\n", extra->type); + DPRINTK("Invalid extra type: %d\n", extra.type); return -EINVAL; } - memcpy(&extras[extra->type - 1], extra, sizeof(*extra)); + memcpy(&extras[extra.type - 1], &extra, sizeof(extra)); netif->tx.req_cons = ++cons; - } while (extra->flags & XEN_NETIF_EXTRA_FLAG_MORE); + } while (extra.flags & XEN_NETIF_EXTRA_FLAG_MORE); return work_to_do; } @@ -1099,6 +1105,7 @@ static void net_tx_action(unsigned long struct sk_buff *skb; netif_t *netif; netif_tx_request_t txreq; + netif_tx_request_t txfrags[MAX_SKB_FRAGS]; struct netif_extra_info extras[XEN_NETIF_EXTRA_TYPE_MAX - 1]; u16 pending_idx; RING_IDX i; @@ -1175,18 +1182,12 @@ static void net_tx_action(unsigned long } } - ret = netbk_count_requests(netif, &txreq, work_to_do); + ret = netbk_count_requests(netif, &txreq, txfrags, work_to_do); if (unlikely(ret < 0)) { netbk_tx_err(netif, &txreq, i - ret); continue; } i += ret; - - if (unlikely(ret > MAX_SKB_FRAGS)) { - DPRINTK("Too many frags\n"); - netbk_tx_err(netif, &txreq, i); - continue; - } if (unlikely(txreq.size < ETH_HLEN)) { DPRINTK("Bad packet size: %d\n", txreq.size); @@ -1256,7 +1257,7 @@ static void net_tx_action(unsigned long pending_cons++; - mop = netbk_get_requests(netif, skb, mop); + mop = netbk_get_requests(netif, skb, txfrags, mop); netif->tx.req_cons = i; netif_schedule_work(netif); _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |