|
|
|
|
|
|
|
|
|
|
xen-changelog
[Xen-changelog] [xen-unstable] [NET] back: Loopback must copy foreign ma
# 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
|
<Prev in Thread] |
Current Thread |
[Next in Thread> |
- [Xen-changelog] [xen-unstable] [NET] back: Loopback must copy foreign mappings.,
Xen patchbot-unstable <=
|
|
|
|
|