[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] [NET] back: Loopback must copy foreign mappings.
# HG changeset patch # User kfraser@xxxxxxxxxxxxxxxxxxxxx # Node ID 9977b878557066527ccdf37bf388d8efbba3eaa1 # Parent 593b5623a0d2ac66576baeb275a3b93cad606c9f [NET] back: Loopback must copy foreign mappings. Signed-off-by: Keir Fraser <keir@xxxxxxxxxxxxx> --- linux-2.6-xen-sparse/drivers/xen/netback/loopback.c | 50 ++++++++++++++++++++ linux-2.6-xen-sparse/drivers/xen/netback/netback.c | 2 2 files changed, 51 insertions(+), 1 deletion(-) diff -r 593b5623a0d2 -r 9977b8785570 linux-2.6-xen-sparse/drivers/xen/netback/loopback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Fri Sep 29 15:40:35 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/loopback.c Fri Sep 29 19:12:15 2006 +0100 @@ -79,9 +79,59 @@ static int loopback_close(struct net_dev return 0; } +#ifdef CONFIG_X86 +static int is_foreign(unsigned long pfn) +{ + /* NB. Play it safe for auto-translation mode. */ + return (xen_feature(XENFEAT_auto_translated_physmap) || + (phys_to_machine_mapping[pfn] & FOREIGN_FRAME_BIT)); +} +#else +/* How to detect a foreign mapping? Play it safe. */ +#define is_foreign(pfn) (1) +#endif + +static int skb_remove_foreign_references(struct sk_buff *skb) +{ + struct page *page; + unsigned long pfn; + int i, off; + char *vaddr; + + BUG_ON(skb_shinfo(skb)->frag_list); + + for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) { + pfn = page_to_pfn(skb_shinfo(skb)->frags[i].page); + if (!is_foreign(pfn)) + continue; + + page = alloc_page(GFP_ATOMIC | __GFP_NOWARN); + if (unlikely(!page)) + return 0; + + vaddr = kmap_skb_frag(&skb_shinfo(skb)->frags[i]); + off = skb_shinfo(skb)->frags[i].page_offset; + memcpy(page_address(page) + off, + vaddr + off, + skb_shinfo(skb)->frags[i].size); + kunmap_skb_frag(vaddr); + + put_page(skb_shinfo(skb)->frags[i].page); + skb_shinfo(skb)->frags[i].page = page; + } + + return 1; +} + static int loopback_start_xmit(struct sk_buff *skb, struct net_device *dev) { struct net_private *np = netdev_priv(dev); + + if (!skb_remove_foreign_references(skb)) { + np->stats.tx_dropped++; + dev_kfree_skb(skb); + return 0; + } dst_release(skb->dst); skb->dst = NULL; diff -r 593b5623a0d2 -r 9977b8785570 linux-2.6-xen-sparse/drivers/xen/netback/netback.c --- a/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri Sep 29 15:40:35 2006 +0100 +++ b/linux-2.6-xen-sparse/drivers/xen/netback/netback.c Fri Sep 29 19:12:15 2006 +0100 @@ -217,7 +217,7 @@ static struct sk_buff *netbk_copy_skb(st copy = len >= PAGE_SIZE ? PAGE_SIZE : len; zero = len >= PAGE_SIZE ? 0 : __GFP_ZERO; - page = alloc_page(GFP_ATOMIC | zero); + page = alloc_page(GFP_ATOMIC | __GFP_NOWARN | zero); if (unlikely(!page)) goto err_free; _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |