aboutsummaryrefslogtreecommitdiffstats
path: root/debian/patches
diff options
context:
space:
mode:
authorChristian Ehrhardt <christian.ehrhardt@canonical.com>2016-06-15 20:29:06 +0200
committerChristian Ehrhardt <christian.ehrhardt@canonical.com>2016-06-15 20:37:12 +0200
commit199e427d5dea3051eec1726eb9c857aa3d5fdde2 (patch)
tree5477b3bd4868676a210bbd3ef67a469d34814e61 /debian/patches
parentb5cdd645c9fc62341d55aebbfc93a1b648415512 (diff)
Merge Ubuntu DPDK packaging as of 15th June 2016
As discussed this shall be our initial baseline. If history is needed for any sort of debugging or analysis it can be found at https://code.launchpad.net/~ubuntu-server/dpdk/+git/dpdk Change-Id: Ie95c7effbbea34d723df14f6451c1f782000cbc1 Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
Diffstat (limited to 'debian/patches')
-rw-r--r--debian/patches/series12
-rw-r--r--debian/patches/ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch141
-rw-r--r--debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch63
-rw-r--r--debian/patches/ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch52
-rw-r--r--debian/patches/ubuntu-backport-40-linking-fixes-stage-1-4.patch101
-rw-r--r--debian/patches/ubuntu-backport-40-linking-fixes-stage-2-4.patch556
-rw-r--r--debian/patches/ubuntu-backport-40-linking-fixes-stage-3-4.patch217
-rw-r--r--debian/patches/ubuntu-backport-40-linking-fixes-stage-4-4.patch149
-rw-r--r--debian/patches/ubuntu-backport-41-fix-install-tar-1.29.patch25
-rw-r--r--debian/patches/ubuntu-backport-42-increase-default-logging-level.patch81
-rw-r--r--debian/patches/ubuntu-backport-43-fix-level-type-retrieving.patch61
-rw-r--r--debian/patches/ubuntu-fix-vhost-user-socket-permission.patch372
-rw-r--r--debian/patches/ubuntu-fix-xenvirt-support-dynamic-page-size.patch32
13 files changed, 1862 insertions, 0 deletions
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 00000000..baab84f9
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,12 @@
+ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch
+ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch
+ubuntu-fix-vhost-user-socket-permission.patch
+ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch
+ubuntu-fix-xenvirt-support-dynamic-page-size.patch
+ubuntu-backport-40-linking-fixes-stage-1-4.patch
+ubuntu-backport-40-linking-fixes-stage-2-4.patch
+ubuntu-backport-40-linking-fixes-stage-3-4.patch
+ubuntu-backport-40-linking-fixes-stage-4-4.patch
+ubuntu-backport-41-fix-install-tar-1.29.patch
+ubuntu-backport-42-increase-default-logging-level.patch
+ubuntu-backport-43-fix-level-type-retrieving.patch
diff --git a/debian/patches/ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch b/debian/patches/ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch
new file mode 100644
index 00000000..ea1ff75b
--- /dev/null
+++ b/debian/patches/ubuntu-backport-33-vhost-user-add-error-handling-for-fd-1023.patch
@@ -0,0 +1,141 @@
+Description: backport of dpdk fix for LP: #1566874
+
+Forwarded: n/a (already discussed upstream)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-04-11
+
+Extended by Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Close fd on vserver->listenfd (Part of the upstream discussion)
+
+Original:
+From: Patrik Andersson <patrik.r.andersson@ericsson.com>
+
+Protect against DPDK crash when allocation of listen fd >= 1023.
+For events on fd:s >1023, the current implementation will trigger
+an abort due to access outside of allocated bit mask.
+
+Corrections would include:
+
+ * Match fdset_add() signature in fd_man.c to fd_man.h
+ * Handling of return codes from fdset_add()
+ * Addition of check of fd number in fdset_add_fd()
+
+The rationale behind the suggested code change is that,
+fdset_event_dispatch() could attempt access outside of the FD_SET
+bitmask if there is an event on a file descriptor that in turn
+looks up a virtio file descriptor with a value > 1023.
+Such an attempt will lead to an abort() and a restart of any
+vswitch using DPDK.
+
+A discussion topic exist in the ovs-discuss mailing list that can
+provide a little more background:
+
+http://openvswitch.org/pipermail/discuss/2016-February/020243.html
+
+Signed-off-by: Patrik Andersson <patrik.r.andersson@ericsson.com>
+---
+ fd_man.c | 11 ++++++-----
+ vhost-net-user.c | 23 +++++++++++++++++++++--
+ 2 files changed, 27 insertions(+), 7 deletions(-)
+
+Index: dpdk/lib/librte_vhost/vhost_user/fd_man.c
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/fd_man.c
++++ dpdk/lib/librte_vhost/vhost_user/fd_man.c
+@@ -71,20 +71,22 @@ fdset_find_free_slot(struct fdset *pfdse
+ return fdset_find_fd(pfdset, -1);
+ }
+
+-static void
++static int
+ fdset_add_fd(struct fdset *pfdset, int idx, int fd,
+ fd_cb rcb, fd_cb wcb, void *dat)
+ {
+ struct fdentry *pfdentry;
+
+- if (pfdset == NULL || idx >= MAX_FDS)
+- return;
++ if (pfdset == NULL || idx >= MAX_FDS || fd >= FD_SETSIZE)
++ return -1;
+
+ pfdentry = &pfdset->fd[idx];
+ pfdentry->fd = fd;
+ pfdentry->rcb = rcb;
+ pfdentry->wcb = wcb;
+ pfdentry->dat = dat;
++
++ return 0;
+ }
+
+ /**
+@@ -150,12 +152,11 @@ fdset_add(struct fdset *pfdset, int fd,
+
+ /* Find a free slot in the list. */
+ i = fdset_find_free_slot(pfdset);
+- if (i == -1) {
++ if (i == -1 || fdset_add_fd(pfdset, i, fd, rcb, wcb, dat) < 0) {
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+ return -2;
+ }
+
+- fdset_add_fd(pfdset, i, fd, rcb, wcb, dat);
+ pfdset->num++;
+
+ pthread_mutex_unlock(&pfdset->fd_mutex);
+Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.c
++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+@@ -288,6 +288,7 @@ vserver_new_vq_conn(int fd, void *dat, _
+ int fh;
+ struct vhost_device_ctx vdev_ctx = { (pid_t)0, 0 };
+ unsigned int size;
++ int ret;
+
+ conn_fd = accept(fd, NULL, NULL);
+ RTE_LOG(INFO, VHOST_CONFIG,
+@@ -317,8 +318,15 @@ vserver_new_vq_conn(int fd, void *dat, _
+
+ ctx->vserver = vserver;
+ ctx->fh = fh;
+- fdset_add(&g_vhost_server.fdset,
++ ret = fdset_add(&g_vhost_server.fdset,
+ conn_fd, vserver_message_handler, NULL, ctx);
++ if (ret < 0) {
++ free(ctx);
++ close(conn_fd);
++ RTE_LOG(ERR, VHOST_CONFIG,
++ "failed to add fd %d into vhost server fdset\n",
++ conn_fd);
++ }
+ }
+
+ /* callback when there is message on the connfd */
+@@ -453,6 +461,7 @@ int
+ rte_vhost_driver_register(const char *path)
+ {
+ struct vhost_server *vserver;
++ int ret;
+
+ pthread_mutex_lock(&g_vhost_server.server_mutex);
+
+@@ -478,8 +487,18 @@ rte_vhost_driver_register(const char *pa
+
+ vserver->path = strdup(path);
+
+- fdset_add(&g_vhost_server.fdset, vserver->listenfd,
++ ret = fdset_add(&g_vhost_server.fdset, vserver->listenfd,
+ vserver_new_vq_conn, NULL, vserver);
++ if (ret < 0) {
++ pthread_mutex_unlock(&g_vhost_server.server_mutex);
++ RTE_LOG(ERR, VHOST_CONFIG,
++ "failed to add listen fd %d to vhost server fdset\n",
++ vserver->listenfd);
++ close(vserver->listenfd);
++ free(vserver->path);
++ free(vserver);
++ return -1;
++ }
+
+ g_vhost_server.server[g_vhost_server.vserver_cnt++] = vserver;
+ pthread_mutex_unlock(&g_vhost_server.server_mutex);
diff --git a/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch b/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch
new file mode 100644
index 00000000..b756d8ff
--- /dev/null
+++ b/debian/patches/ubuntu-backport-38-dpdk-dev-Memory-leak-when-adding-removing-vhost_user-ports.patch
@@ -0,0 +1,63 @@
+Description: backport of dpdk 16.07 fix for LP: #1570466
+
+Backported from this discussion
+http://dpdk.org/dev/patchwork/patch/12103/
+Not accepted yet, but likely to be accepted in some form once tested and
+confirmed.
+
+Update 2016-05-17:
+Moving to 16.04 this now applies as-is without modifications, dropping the
+former backport changes.
+
+Also along the discussion vserver-fh is now initialized with -1 to avoid
+accidentially deleting the first connected port if we delete another not yet
+connected port.
+
+Forwarded: yes (based on an upstream discussion)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-05-17
+
+Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.c
++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+@@ -310,6 +310,7 @@ vserver_new_vq_conn(int fd, void *dat, _
+ }
+
+ vdev_ctx.fh = fh;
++ vserver->fh = fh;
+ size = strnlen(vserver->path, PATH_MAX);
+ vhost_set_ifname(vdev_ctx, vserver->path,
+ size);
+@@ -486,6 +487,7 @@ rte_vhost_driver_register(const char *pa
+ }
+
+ vserver->path = strdup(path);
++ vserver->fh = -1;
+
+ ret = fdset_add(&g_vhost_server.fdset, vserver->listenfd,
+ vserver_new_vq_conn, NULL, vserver);
+@@ -520,6 +522,11 @@ rte_vhost_driver_unregister(const char *
+
+ for (i = 0; i < g_vhost_server.vserver_cnt; i++) {
+ if (!strcmp(g_vhost_server.server[i]->path, path)) {
++ struct vhost_device_ctx ctx;
++
++ ctx.fh = g_vhost_server.server[i]->fh;
++ vhost_destroy_device(ctx);
++
+ fdset_del(&g_vhost_server.fdset,
+ g_vhost_server.server[i]->listenfd);
+
+Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.h
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.h
++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.h
+@@ -43,6 +43,7 @@
+ struct vhost_server {
+ char *path; /**< The path the uds is bind to. */
+ int listenfd; /**< The listener sockfd. */
++ uint32_t fh;
+ };
+
+ /* refer to hw/virtio/vhost-user.c */
diff --git a/debian/patches/ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch b/debian/patches/ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch
new file mode 100644
index 00000000..4224cad8
--- /dev/null
+++ b/debian/patches/ubuntu-backport-39-lpm-fix-freeing-in-compatibility-mode.patch
@@ -0,0 +1,52 @@
+Description: backport of dpdk 16.07 fix 7cc3f2c2
+
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Date: Tue Apr 12 15:49:27 2016 +0200
+
+ lpm: fix freeing in compatibility mode
+
+ Back then when we fixed the missing free lpm I was to quickly to say yes
+ if it applies not only to the lpm6 but also to all of the lpm code.
+
+ It turned out to not apply to all of them. In rte_lpm_create_v20 there
+ is an unexpected fused allocation:
+ mem_size = sizeof(*lpm) + (sizeof(lpm->rules_tbl[0]) * max_rules);
+ [...]
+ lpm = (struct rte_lpm_v20 *)rte_zmalloc_socket(mem_name,mem_size,
+ RTE_CACHE_LINE_SIZE, socket_id);
+
+ That causes lpm->rules_tbl not to have an own struct malloc_elem that
+ can be derived via RTE_PTR_SUB(data, MALLOC_ELEM_HEADER_LEN) in
+ malloc_elem_from_data.
+ Due to that the rte_lpm_free_v20 accidentially misderives the elem and
+ assumes it is ELEM_FREE triggering in malloc_elem_free
+ if (!malloc_elem_cookies_ok(elem) || elem->state !=
+ return -1;
+
+ While it seems counter-intuitive the way to properly remove rules_tbl in
+ the old fused allocation style of rte_lpm_free_v20 is to not remove it.
+
+ The newer rte_lpm_free_v1604 is safe because in rte_lpm_create_v1604
+ rules_tbl is a separate allocation.
+
+ Fixes: d4c18f0a1d5d ("lpm: fix missing free")
+
+ Signed-off-by: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+ Acked-by: Olivier Matz <olivier.matz@6wind.com>
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-05-17
+
+Index: dpdk/lib/librte_lpm/rte_lpm.c
+===================================================================
+--- dpdk.orig/lib/librte_lpm/rte_lpm.c
++++ dpdk/lib/librte_lpm/rte_lpm.c
+@@ -373,7 +373,6 @@ rte_lpm_free_v20(struct rte_lpm_v20 *lpm
+
+ rte_rwlock_write_unlock(RTE_EAL_TAILQ_RWLOCK);
+
+- rte_free(lpm->rules_tbl);
+ rte_free(lpm);
+ rte_free(te);
+ }
diff --git a/debian/patches/ubuntu-backport-40-linking-fixes-stage-1-4.patch b/debian/patches/ubuntu-backport-40-linking-fixes-stage-1-4.patch
new file mode 100644
index 00000000..5336cd49
--- /dev/null
+++ b/debian/patches/ubuntu-backport-40-linking-fixes-stage-1-4.patch
@@ -0,0 +1,101 @@
+Description: backport of dpdk 16.07 fix for library underlinking - stage 1/4
+
+This is a merge of related upstream fixes:
+- c6417ce6: mk: add build-time library directory to linker path
+- aace9d0b: mk: cleanup leftover references to malloc library
+- bf5a46fa: mk: generate internal library dependencies
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/drivers/net/cxgbe/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/cxgbe/Makefile
++++ dpdk/drivers/net/cxgbe/Makefile
+@@ -82,6 +82,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += t
+ # this lib depends upon:
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_mempool lib/librte_mbuf
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_net lib/librte_malloc
++DEPDIRS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += lib/librte_net
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/ena/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/ena/Makefile
++++ dpdk/drivers/net/ena/Makefile
+@@ -54,7 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += ena
+ # this lib depends upon:
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += lib/librte_mempool lib/librte_mbuf
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += lib/librte_net lib/librte_malloc
++DEPDIRS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += lib/librte_net
+
+ CFLAGS += $(INCLUDES)
+
+Index: dpdk/drivers/net/mpipe/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/mpipe/Makefile
++++ dpdk/drivers/net/mpipe/Makefile
+@@ -42,6 +42,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += m
+
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += lib/librte_mempool lib/librte_mbuf
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += lib/librte_net lib/librte_malloc
++DEPDIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += lib/librte_net
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/nfp/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/nfp/Makefile
++++ dpdk/drivers/net/nfp/Makefile
+@@ -53,6 +53,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp
+ # this lib depends upon:
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += lib/librte_mempool lib/librte_mbuf
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += lib/librte_net lib/librte_malloc
++DEPDIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += lib/librte_net
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/szedata2/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/szedata2/Makefile
++++ dpdk/drivers/net/szedata2/Makefile
+@@ -57,7 +57,6 @@ SYMLINK-y-include +=
+ # this lib depends upon:
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_ether
+-DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_malloc
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += lib/librte_kvargs
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/mk/rte.lib.mk
+===================================================================
+--- dpdk.orig/mk/rte.lib.mk
++++ dpdk/mk/rte.lib.mk
+@@ -77,6 +77,13 @@ else
+ _CPU_LDFLAGS := $(CPU_LDFLAGS)
+ endif
+
++# Translate DEPDIRS-y into LDLIBS
++# Ignore (sub)directory dependencies which do not provide an actual library
++_IGNORE_DIRS = lib/librte_eal/% lib/librte_net lib/librte_compat
++_DEPDIRS = $(filter-out $(_IGNORE_DIRS),$(DEPDIRS-y))
++_LDDIRS = $(subst librte_ether,libethdev,$(_DEPDIRS))
++LDLIBS += $(subst lib/lib,-l,$(_LDDIRS))
++
+ O_TO_A = $(AR) crDs $(LIB) $(OBJS-y)
+ O_TO_A_STR = $(subst ','\'',$(O_TO_A)) #'# fix syntax highlight
+ O_TO_A_DISP = $(if $(V),"$(O_TO_A_STR)"," AR $(@)")
+@@ -86,8 +93,8 @@ O_TO_A_DO = @set -e; \
+ $(O_TO_A) && \
+ echo $(O_TO_A_CMD) > $(call exe2cmd,$(@))
+
+-O_TO_S = $(LD) $(_CPU_LDFLAGS) $(EXTRA_LDFLAGS) -shared $(OBJS-y) $(LDLIBS) \
+- -Wl,-soname,$(LIB) -o $(LIB)
++O_TO_S = $(LD) -L$(RTE_OUTPUT)/lib $(_CPU_LDFLAGS) $(EXTRA_LDFLAGS) \
++ -shared $(OBJS-y) $(LDLIBS) -Wl,-soname,$(LIB) -o $(LIB)
+ O_TO_S_STR = $(subst ','\'',$(O_TO_S)) #'# fix syntax highlight
+ O_TO_S_DISP = $(if $(V),"$(O_TO_S_STR)"," LD $(@)")
+ O_TO_S_DO = @set -e; \
diff --git a/debian/patches/ubuntu-backport-40-linking-fixes-stage-2-4.patch b/debian/patches/ubuntu-backport-40-linking-fixes-stage-2-4.patch
new file mode 100644
index 00000000..30ca0d50
--- /dev/null
+++ b/debian/patches/ubuntu-backport-40-linking-fixes-stage-2-4.patch
@@ -0,0 +1,556 @@
+Description: backport of dpdk 16.07 fix for library underlinking - stage 2/4
+
+This is a merge of related upstream fixes:
+- a3f34a98 log: deprecate history dump
+- 3037e5e2 eal: remove useless includes of mempool and ring
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/app/test-pmd/cmdline.c
+===================================================================
+--- dpdk.orig/app/test-pmd/cmdline.c
++++ dpdk/app/test-pmd/cmdline.c
+@@ -7191,8 +7191,6 @@ static void cmd_dump_parsed(void *parsed
+ rte_dump_physmem_layout(stdout);
+ else if (!strcmp(res->dump, "dump_memzone"))
+ rte_memzone_dump(stdout);
+- else if (!strcmp(res->dump, "dump_log_history"))
+- rte_log_dump_history(stdout);
+ else if (!strcmp(res->dump, "dump_struct_sizes"))
+ dump_struct_sizes();
+ else if (!strcmp(res->dump, "dump_ring"))
+@@ -7207,7 +7205,6 @@ cmdline_parse_token_string_t cmd_dump_du
+ TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
+ "dump_physmem#"
+ "dump_memzone#"
+- "dump_log_history#"
+ "dump_struct_sizes#"
+ "dump_ring#"
+ "dump_mempool#"
+Index: dpdk/app/test/autotest_data.py
+===================================================================
+--- dpdk.orig/app/test/autotest_data.py
++++ dpdk/app/test/autotest_data.py
+@@ -88,12 +88,6 @@ parallel_test_group_list = [
+ "Report" : None,
+ },
+ {
+- "Name" : "Dump log history",
+- "Command" : "dump_log_history",
+- "Func" : dump_autotest,
+- "Report" : None,
+- },
+- {
+ "Name" : "Dump rings",
+ "Command" : "dump_ring",
+ "Func" : dump_autotest,
+Index: dpdk/app/test/autotest_test_funcs.py
+===================================================================
+--- dpdk.orig/app/test/autotest_test_funcs.py
++++ dpdk/app/test/autotest_test_funcs.py
+@@ -151,12 +151,6 @@ def logs_autotest(child, test_name):
+ "TESTAPP2: this is a info level message",
+ "TESTAPP2: this is a warning level message",
+ "TESTAPP1: this is a debug level message",
+- "TESTAPP1: this is a debug level message",
+- "TESTAPP1: this is a info level message",
+- "TESTAPP1: this is a warning level message",
+- "TESTAPP2: this is a info level message",
+- "TESTAPP2: this is a warning level message",
+- "TESTAPP1: this is a debug level message",
+ ]
+
+ for log_msg in log_list:
+Index: dpdk/app/test/commands.c
+===================================================================
+--- dpdk.orig/app/test/commands.c
++++ dpdk/app/test/commands.c
+@@ -150,8 +150,6 @@ static void cmd_dump_parsed(void *parsed
+ rte_dump_physmem_layout(stdout);
+ else if (!strcmp(res->dump, "dump_memzone"))
+ rte_memzone_dump(stdout);
+- else if (!strcmp(res->dump, "dump_log_history"))
+- rte_log_dump_history(stdout);
+ else if (!strcmp(res->dump, "dump_struct_sizes"))
+ dump_struct_sizes();
+ else if (!strcmp(res->dump, "dump_ring"))
+@@ -164,7 +162,7 @@ static void cmd_dump_parsed(void *parsed
+
+ cmdline_parse_token_string_t cmd_dump_dump =
+ TOKEN_STRING_INITIALIZER(struct cmd_dump_result, dump,
+- "dump_physmem#dump_memzone#dump_log_history#"
++ "dump_physmem#dump_memzone#"
+ "dump_struct_sizes#dump_ring#dump_mempool#"
+ "dump_devargs");
+
+Index: dpdk/app/test/test_logs.c
+===================================================================
+--- dpdk.orig/app/test/test_logs.c
++++ dpdk/app/test/test_logs.c
+@@ -85,8 +85,6 @@ test_logs(void)
+ RTE_LOG(DEBUG, TESTAPP1, "this is a debug level message\n");
+ RTE_LOG(DEBUG, TESTAPP2, "debug level message (not displayed)\n");
+
+- rte_log_dump_history(stdout);
+-
+ return 0;
+ }
+
+Index: dpdk/doc/guides/prog_guide/mempool_lib.rst
+===================================================================
+--- dpdk.orig/doc/guides/prog_guide/mempool_lib.rst
++++ dpdk/doc/guides/prog_guide/mempool_lib.rst
+@@ -38,9 +38,7 @@ In the DPDK, it is identified by name an
+ It provides some other optional services such as a per-core object cache and
+ an alignment helper to ensure that objects are padded to spread them equally on all DRAM or DDR3 channels.
+
+-This library is used by the
+-:ref:`Mbuf Library <Mbuf_Library>` and the
+-:ref:`Environment Abstraction Layer <Environment_Abstraction_Layer>` (for logging history).
++This library is used by the :ref:`Mbuf Library <Mbuf_Library>`.
+
+ Cookies
+ -------
+Index: dpdk/doc/guides/rel_notes/deprecation.rst
+===================================================================
+--- dpdk.orig/doc/guides/rel_notes/deprecation.rst
++++ dpdk/doc/guides/rel_notes/deprecation.rst
+@@ -8,6 +8,9 @@ API and ABI deprecation notices are to b
+ Deprecation Notices
+ -------------------
+
++* The log history is deprecated.
++ It is voided in 16.07 and will be removed in release 16.11.
++
+ * The ethdev hotplug API is going to be moved to EAL with a notification
+ mechanism added to crypto and ethdev libraries so that hotplug is now
+ available to both of them. This API will be stripped of the device arguments
+Index: dpdk/lib/librte_eal/bsdapp/eal/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_eal/bsdapp/eal/Makefile
++++ dpdk/lib/librte_eal/bsdapp/eal/Makefile
+@@ -40,8 +40,6 @@ VPATH += $(RTE_SDK)/lib/librte_eal/commo
+ CFLAGS += -I$(SRCDIR)/include
+ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
+-CFLAGS += -I$(RTE_SDK)/lib/librte_ring
+-CFLAGS += -I$(RTE_SDK)/lib/librte_mempool
+ CFLAGS += $(WERROR_FLAGS) -O3
+
+ LDLIBS += -lexecinfo
+Index: dpdk/lib/librte_eal/bsdapp/eal/eal_debug.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/bsdapp/eal/eal_debug.c
++++ dpdk/lib/librte_eal/bsdapp/eal/eal_debug.c
+@@ -77,9 +77,6 @@ void __rte_panic(const char *funcname, c
+ {
+ va_list ap;
+
+- /* disable history */
+- rte_log_set_history(0);
+-
+ rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
+ va_start(ap, format);
+ rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+@@ -98,9 +95,6 @@ rte_exit(int exit_code, const char *form
+ {
+ va_list ap;
+
+- /* disable history */
+- rte_log_set_history(0);
+-
+ if (exit_code != 0)
+ RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n"
+ " Cause: ", exit_code);
+Index: dpdk/lib/librte_eal/common/eal_common_log.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_log.c
++++ dpdk/lib/librte_eal/common/eal_common_log.c
+@@ -31,54 +31,16 @@
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+-#include <string.h>
+ #include <stdio.h>
+ #include <stdint.h>
+ #include <stdarg.h>
+-#include <sys/types.h>
+ #include <stdlib.h>
+-#include <unistd.h>
+-#include <inttypes.h>
+-#include <errno.h>
+-#include <sys/queue.h>
+
+ #include <rte_log.h>
+-#include <rte_memory.h>
+-#include <rte_memzone.h>
+-#include <rte_launch.h>
+-#include <rte_common.h>
+-#include <rte_cycles.h>
+-#include <rte_eal.h>
+ #include <rte_per_lcore.h>
+-#include <rte_lcore.h>
+-#include <rte_atomic.h>
+-#include <rte_debug.h>
+-#include <rte_spinlock.h>
+-#include <rte_branch_prediction.h>
+-#include <rte_ring.h>
+-#include <rte_mempool.h>
+
+ #include "eal_private.h"
+
+-#define LOG_ELT_SIZE 2048
+-
+-#define LOG_HISTORY_MP_NAME "log_history"
+-
+-STAILQ_HEAD(log_history_list, log_history);
+-
+-/**
+- * The structure of a message log in the log history.
+- */
+-struct log_history {
+- STAILQ_ENTRY(log_history) next;
+- unsigned size;
+- char buf[0];
+-};
+-
+-static struct rte_mempool *log_history_mp = NULL;
+-static unsigned log_history_size = 0;
+-static struct log_history_list log_history;
+-
+ /* global log structure */
+ struct rte_logs rte_logs = {
+ .type = ~0,
+@@ -86,10 +48,7 @@ struct rte_logs rte_logs = {
+ .file = NULL,
+ };
+
+-static rte_spinlock_t log_dump_lock = RTE_SPINLOCK_INITIALIZER;
+-static rte_spinlock_t log_list_lock = RTE_SPINLOCK_INITIALIZER;
+ static FILE *default_log_stream;
+-static int history_enabled = 1;
+
+ /**
+ * This global structure stores some informations about the message
+@@ -105,59 +64,16 @@ static struct log_cur_msg log_cur_msg[RT
+ /* default logs */
+
+ int
+-rte_log_add_in_history(const char *buf, size_t size)
++rte_log_add_in_history(const char *buf __rte_unused, size_t size __rte_unused)
+ {
+- struct log_history *hist_buf = NULL;
+- static const unsigned hist_buf_size = LOG_ELT_SIZE - sizeof(*hist_buf);
+- void *obj;
+-
+- if (history_enabled == 0)
+- return 0;
+-
+- rte_spinlock_lock(&log_list_lock);
+-
+- /* get a buffer for adding in history */
+- if (log_history_size > RTE_LOG_HISTORY) {
+- hist_buf = STAILQ_FIRST(&log_history);
+- if (hist_buf) {
+- STAILQ_REMOVE_HEAD(&log_history, next);
+- log_history_size--;
+- }
+- }
+- else {
+- if (rte_mempool_mc_get(log_history_mp, &obj) < 0)
+- obj = NULL;
+- hist_buf = obj;
+- }
+-
+- /* no buffer */
+- if (hist_buf == NULL) {
+- rte_spinlock_unlock(&log_list_lock);
+- return -ENOBUFS;
+- }
+-
+- /* not enough room for msg, buffer go back in mempool */
+- if (size >= hist_buf_size) {
+- rte_mempool_mp_put(log_history_mp, hist_buf);
+- rte_spinlock_unlock(&log_list_lock);
+- return -ENOBUFS;
+- }
+-
+- /* add in history */
+- memcpy(hist_buf->buf, buf, size);
+- hist_buf->buf[size] = hist_buf->buf[hist_buf_size-1] = '\0';
+- hist_buf->size = size;
+- STAILQ_INSERT_TAIL(&log_history, hist_buf, next);
+- log_history_size++;
+- rte_spinlock_unlock(&log_list_lock);
+-
+ return 0;
+ }
+
+ void
+ rte_log_set_history(int enable)
+ {
+- history_enabled = enable;
++ if (enable)
++ RTE_LOG(WARNING, EAL, "The log history is deprecated.\n");
+ }
+
+ /* Change the stream that will be used by logging system */
+@@ -224,44 +140,8 @@ int rte_log_cur_msg_logtype(void)
+
+ /* Dump log history to file */
+ void
+-rte_log_dump_history(FILE *out)
++rte_log_dump_history(FILE *out __rte_unused)
+ {
+- struct log_history_list tmp_log_history;
+- struct log_history *hist_buf;
+- unsigned i;
+-
+- /* only one dump at a time */
+- rte_spinlock_lock(&log_dump_lock);
+-
+- /* save list, and re-init to allow logging during dump */
+- rte_spinlock_lock(&log_list_lock);
+- tmp_log_history = log_history;
+- STAILQ_INIT(&log_history);
+- log_history_size = 0;
+- rte_spinlock_unlock(&log_list_lock);
+-
+- for (i=0; i<RTE_LOG_HISTORY; i++) {
+-
+- /* remove one message from history list */
+- hist_buf = STAILQ_FIRST(&tmp_log_history);
+-
+- if (hist_buf == NULL)
+- break;
+-
+- STAILQ_REMOVE_HEAD(&tmp_log_history, next);
+-
+- /* write on stdout */
+- if (fwrite(hist_buf->buf, hist_buf->size, 1, out) == 0) {
+- rte_mempool_mp_put(log_history_mp, hist_buf);
+- break;
+- }
+-
+- /* put back message structure in pool */
+- rte_mempool_mp_put(log_history_mp, hist_buf);
+- }
+- fflush(out);
+-
+- rte_spinlock_unlock(&log_dump_lock);
+ }
+
+ /*
+@@ -308,29 +188,11 @@ rte_log(uint32_t level, uint32_t logtype
+ }
+
+ /*
+- * called by environment-specific log init function to initialize log
+- * history
++ * called by environment-specific log init function
+ */
+ int
+ rte_eal_common_log_init(FILE *default_log)
+ {
+- STAILQ_INIT(&log_history);
+-
+- /* reserve RTE_LOG_HISTORY*2 elements, so we can dump and
+- * keep logging during this time */
+- log_history_mp = rte_mempool_create(LOG_HISTORY_MP_NAME, RTE_LOG_HISTORY*2,
+- LOG_ELT_SIZE, 0, 0,
+- NULL, NULL,
+- NULL, NULL,
+- SOCKET_ID_ANY, 0);
+-
+- if ((log_history_mp == NULL) &&
+- ((log_history_mp = rte_mempool_lookup(LOG_HISTORY_MP_NAME)) == NULL)){
+- RTE_LOG(ERR, EAL, "%s(): cannot create log_history mempool\n",
+- __func__);
+- return -1;
+- }
+-
+ default_log_stream = default_log;
+ rte_openlog_stream(default_log);
+ return 0;
+Index: dpdk/lib/librte_eal/common/eal_private.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_private.h
++++ dpdk/lib/librte_eal/common/eal_private.h
+@@ -49,9 +49,6 @@ int rte_eal_memzone_init(void);
+ /**
+ * Common log initialization function (private to eal).
+ *
+- * Called by environment-specific log initialization function to initialize
+- * log history.
+- *
+ * @param default_log
+ * The default log stream to be used.
+ * @return
+Index: dpdk/lib/librte_eal/common/include/rte_log.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/include/rte_log.h
++++ dpdk/lib/librte_eal/common/include/rte_log.h
+@@ -42,6 +42,8 @@
+ * This file provides a log API to RTE applications.
+ */
+
++#include "rte_common.h" /* for __rte_deprecated macro */
++
+ #ifdef __cplusplus
+ extern "C" {
+ #endif
+@@ -179,22 +181,27 @@ int rte_log_cur_msg_loglevel(void);
+ int rte_log_cur_msg_logtype(void);
+
+ /**
++ * @deprecated
+ * Enable or disable the history (enabled by default)
+ *
+ * @param enable
+ * true to enable, or 0 to disable history.
+ */
++__rte_deprecated
+ void rte_log_set_history(int enable);
+
+ /**
++ * @deprecated
+ * Dump the log history to a file
+ *
+ * @param f
+ * A pointer to a file for output
+ */
++__rte_deprecated
+ void rte_log_dump_history(FILE *f);
+
+ /**
++ * @deprecated
+ * Add a log message to the history.
+ *
+ * This function can be called from a user-defined log stream. It adds
+@@ -209,6 +216,7 @@ void rte_log_dump_history(FILE *f);
+ * - 0: Success.
+ * - (-ENOBUFS) if there is no room to store the message.
+ */
++__rte_deprecated
+ int rte_log_add_in_history(const char *buf, size_t size);
+
+ /**
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal_debug.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal_debug.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal_debug.c
+@@ -77,9 +77,6 @@ void __rte_panic(const char *funcname, c
+ {
+ va_list ap;
+
+- /* disable history */
+- rte_log_set_history(0);
+-
+ rte_log(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, "PANIC in %s():\n", funcname);
+ va_start(ap, format);
+ rte_vlog(RTE_LOG_CRIT, RTE_LOGTYPE_EAL, format, ap);
+@@ -98,9 +95,6 @@ rte_exit(int exit_code, const char *form
+ {
+ va_list ap;
+
+- /* disable history */
+- rte_log_set_history(0);
+-
+ if (exit_code != 0)
+ RTE_LOG(CRIT, EAL, "Error - exiting with code: %d\n"
+ " Cause: ", exit_code);
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal_log.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal_log.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal_log.c
+@@ -50,8 +50,7 @@
+ #include "eal_private.h"
+
+ /*
+- * default log function, used once mempool (hence log history) is
+- * available
++ * default log function
+ */
+ static ssize_t
+ console_log_write(__attribute__((unused)) void *c, const char *buf, size_t size)
+@@ -60,9 +59,6 @@ console_log_write(__attribute__((unused)
+ ssize_t ret;
+ uint32_t loglevel;
+
+- /* add this log in history */
+- rte_log_add_in_history(buf, size);
+-
+ /* write on stdout */
+ ret = fwrite(buf, 1, size, stdout);
+ fflush(stdout);
+@@ -110,8 +106,7 @@ rte_eal_log_init(const char *id, int fac
+ /* early logs */
+
+ /*
+- * early log function, used during boot when mempool (hence log
+- * history) is not available
++ * early log function, used before rte_eal_log_init
+ */
+ static ssize_t
+ early_log_write(__attribute__((unused)) void *c, const char *buf, size_t size)
+Index: dpdk/lib/librte_eal/linuxapp/eal/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/Makefile
++++ dpdk/lib/librte_eal/linuxapp/eal/Makefile
+@@ -44,9 +44,12 @@ VPATH += $(RTE_SDK)/lib/librte_eal/commo
+ CFLAGS += -I$(SRCDIR)/include
+ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common
+ CFLAGS += -I$(RTE_SDK)/lib/librte_eal/common/include
++ifeq ($(CONFIG_RTE_LIBRTE_IVSHMEM),y)
++# workaround for circular dependency eal -> ivshmem -> ring/mempool -> eal
+ CFLAGS += -I$(RTE_SDK)/lib/librte_ring
+ CFLAGS += -I$(RTE_SDK)/lib/librte_mempool
+ CFLAGS += -I$(RTE_SDK)/lib/librte_ivshmem
++endif
+ CFLAGS += $(WERROR_FLAGS) -O3
+
+ LDLIBS += -ldl
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal_interrupts.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal_interrupts.c
+@@ -57,10 +57,8 @@
+ #include <rte_lcore.h>
+ #include <rte_atomic.h>
+ #include <rte_branch_prediction.h>
+-#include <rte_ring.h>
+ #include <rte_debug.h>
+ #include <rte_log.h>
+-#include <rte_mempool.h>
+ #include <rte_pci.h>
+ #include <rte_malloc.h>
+ #include <rte_errno.h>
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal_ivshmem.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal_ivshmem.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal_ivshmem.c
+@@ -49,7 +49,6 @@
+ #include <rte_string_fns.h>
+ #include <rte_errno.h>
+ #include <rte_ring.h>
+-#include <rte_mempool.h>
+ #include <rte_malloc.h>
+ #include <rte_common.h>
+ #include <rte_ivshmem.h>
+Index: dpdk/lib/librte_ivshmem/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_ivshmem/Makefile
++++ dpdk/lib/librte_ivshmem/Makefile
+@@ -46,7 +46,9 @@ SRCS-$(CONFIG_RTE_LIBRTE_IVSHMEM) := rte
+ # install includes
+ SYMLINK-$(CONFIG_RTE_LIBRTE_IVSHMEM)-include := rte_ivshmem.h
+
+-# this lib needs eal
++# this lib needs EAL, ring and mempool
++DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_eal
++DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_ring
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += lib/librte_mempool
+
+ include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/debian/patches/ubuntu-backport-40-linking-fixes-stage-3-4.patch b/debian/patches/ubuntu-backport-40-linking-fixes-stage-3-4.patch
new file mode 100644
index 00000000..161832e6
--- /dev/null
+++ b/debian/patches/ubuntu-backport-40-linking-fixes-stage-3-4.patch
@@ -0,0 +1,217 @@
+Description: backport of dpdk 16.07 fix for library underlinking - stage 3/4
+
+This is a merge of related upstream fixes:
+- cb8e39da mk: sort drivers in static application link list
+- ea469893 mk: fix driver dependencies order for static application
+- 4e04fd45 mk: remove library grouping during application linking
+- 6248e442 mk: prevent overlinking in applications
+- ce18c527 mk: sort libraries in level order when linking
+- 95dc3c3c mk: reduce scope of whole-archive static linking
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/mk/rte.app.mk
+===================================================================
+--- dpdk.orig/mk/rte.app.mk
++++ dpdk/mk/rte.app.mk
+@@ -50,6 +50,9 @@ ifeq ($(NO_LDSCRIPT),)
+ LDSCRIPT = $(RTE_LDSCRIPT)
+ endif
+
++# Link only the libraries used in the application
++LDFLAGS += --as-needed
++
+ # default path for libs
+ _LDLIBS-y += -L$(RTE_SDK_BIN)/lib
+
+@@ -57,11 +60,6 @@ _LDLIBS-y += -L$(RTE_SDK_BIN)/lib
+ # Order is important: from higher level to lower level
+ #
+
+-_LDLIBS-y += --whole-archive
+-
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += -lrte_distributor
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder
+-
+ ifeq ($(CONFIG_RTE_EXEC_ENV_LINUXAPP),y)
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_KNI) += -lrte_kni
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_IVSHMEM) += -lrte_ivshmem
+@@ -70,51 +68,25 @@ endif
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PIPELINE) += -lrte_pipeline
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_TABLE) += -lrte_table
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PORT) += -lrte_port
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_HASH) += -lrte_hash
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += -lrte_jobstats
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_LPM) += -lrte_lpm
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += -lrte_acl
++
++_LDLIBS-$(CONFIG_RTE_LIBRTE_DISTRIBUTOR) += -lrte_distributor
++_LDLIBS-$(CONFIG_RTE_LIBRTE_REORDER) += -lrte_reorder
++_LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += -lrte_ip_frag
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_METER) += -lrte_meter
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lrte_sched
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lrte_vhost
++_LDLIBS-$(CONFIG_RTE_LIBRTE_LPM) += -lrte_lpm
++_LDLIBS-$(CONFIG_RTE_LIBRTE_ACL) += -lrte_acl
++_LDLIBS-$(CONFIG_RTE_LIBRTE_JOBSTATS) += -lrte_jobstats
++_LDLIBS-$(CONFIG_RTE_LIBRTE_POWER) += -lrte_power
+
+-# The static libraries do not know their dependencies.
+-# So linking with static library requires explicit dependencies.
+-ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lm
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lrt
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_METER) += -lm
+-ifeq ($(CONFIG_RTE_LIBRTE_VHOST_NUMA),y)
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lnuma
+-endif
+-ifeq ($(CONFIG_RTE_LIBRTE_VHOST_USER),n)
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lfuse
+-endif
+-_LDLIBS-$(CONFIG_RTE_PORT_PCAP) += -lpcap
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lpcap
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lz
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += -libverbs
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -libverbs
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += -lsze2
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lxenstore
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += -lgxio
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += -lm
+-# QAT / AESNI GCM PMDs are dependent on libcrypto (from openssl)
+-# for calculating HMAC precomputes
+-ifeq ($(CONFIG_RTE_LIBRTE_PMD_QAT),y)
+-_LDLIBS-y += -lcrypto
+-else ifeq ($(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM),y)
+-_LDLIBS-y += -lcrypto
+-endif
+-endif # !CONFIG_RTE_BUILD_SHARED_LIBS
++_LDLIBS-y += --whole-archive
+
+-_LDLIBS-y += --start-group
++_LDLIBS-$(CONFIG_RTE_LIBRTE_TIMER) += -lrte_timer
++_LDLIBS-$(CONFIG_RTE_LIBRTE_HASH) += -lrte_hash
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lrte_vhost
+
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_KVARGS) += -lrte_kvargs
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_MBUF) += -lrte_mbuf
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += -lrte_ip_frag
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_ETHER) += -lethdev
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_CRYPTODEV) += -lrte_cryptodev
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_MEMPOOL) += -lrte_mempool
+@@ -123,61 +95,65 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_EAL)
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_CMDLINE) += -lrte_cmdline
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_CFGFILE) += -lrte_cfgfile
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += -lrte_pmd_bond
+-
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lrte_pmd_xenvirt
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += -lrte_pmd_xenvirt -lxenstore
+
+ ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
+ # plugins (link only if static libraries)
+
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += -lrte_pmd_virtio
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += -lrte_pmd_af_packet
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_BNX2X_PMD) += -lrte_pmd_bnx2x
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_CXGBE_PMD) += -lrte_pmd_cxgbe
++_LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
++_LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_ENIC_PMD) += -lrte_pmd_enic
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += -lrte_pmd_fm10k
++_LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += -lrte_pmd_i40e
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += -lrte_pmd_ixgbe
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD) += -lrte_pmd_e1000
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD) += -lrte_pmd_ena
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += -lrte_pmd_mlx4
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -lrte_pmd_mlx5
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += -lrte_pmd_nfp
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += -lrte_pmd_szedata2
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += -lrte_pmd_mpipe
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING) += -lrte_pmd_ring
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lrte_pmd_pcap
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += -lrte_pmd_af_packet
++_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += -lrte_pmd_mlx4 -libverbs
++_LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += -lrte_pmd_mlx5 -libverbs
++_LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += -lrte_pmd_mpipe -lgxio
++_LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += -lrte_pmd_nfp -lm
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += -lrte_pmd_null
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += -lrte_pmd_pcap -lpcap
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING) += -lrte_pmd_ring
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2) += -lrte_pmd_szedata2 -lsze2
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += -lrte_pmd_virtio
++ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost
++endif # $(CONFIG_RTE_LIBRTE_VHOST)
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += -lrte_pmd_vmxnet3_uio
+
+ ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -lrte_pmd_aesni_mb
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -lrte_pmd_aesni_gcm
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM) += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += -lrte_pmd_null_crypto
+-
+-# AESNI MULTI BUFFER / GCM PMDs are dependent on the IPSec_MB library
+-ifeq ($(CONFIG_RTE_LIBRTE_PMD_AESNI_MB),y)
+-_LDLIBS-y += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+-else ifeq ($(CONFIG_RTE_LIBRTE_PMD_AESNI_GCM),y)
+-_LDLIBS-y += -L$(AESNI_MULTI_BUFFER_LIB_PATH) -lIPSec_MB
+-endif
+-
+-# SNOW3G PMD is dependent on the LIBSSO library
++_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_QAT) += -lrte_pmd_qat
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -lrte_pmd_snow3g
+ _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SNOW3G) += -L$(LIBSSO_PATH)/build -lsso
+ endif # CONFIG_RTE_LIBRTE_CRYPTODEV
+
+-ifeq ($(CONFIG_RTE_LIBRTE_VHOST),y)
+-
+-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += -lrte_pmd_vhost
++endif # !CONFIG_RTE_BUILD_SHARED_LIBS
+
+-endif # $(CONFIG_RTE_LIBRTE_VHOST)
++_LDLIBS-y += --no-whole-archive
+
+-endif # ! $(CONFIG_RTE_BUILD_SHARED_LIB)
++ifeq ($(CONFIG_RTE_BUILD_SHARED_LIB),n)
++# The static libraries do not know their dependencies.
++# So linking with static library requires explicit dependencies.
++_LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lm
++_LDLIBS-$(CONFIG_RTE_LIBRTE_SCHED) += -lrt
++_LDLIBS-$(CONFIG_RTE_LIBRTE_METER) += -lm
++ifeq ($(CONFIG_RTE_LIBRTE_VHOST_NUMA),y)
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lnuma
++endif
++ifeq ($(CONFIG_RTE_LIBRTE_VHOST_USER),n)
++_LDLIBS-$(CONFIG_RTE_LIBRTE_VHOST) += -lfuse
++endif
++_LDLIBS-$(CONFIG_RTE_PORT_PCAP) += -lpcap
++endif # !CONFIG_RTE_BUILD_SHARED_LIBS
+
+ _LDLIBS-y += $(EXECENV_LDLIBS)
+-_LDLIBS-y += --end-group
+-_LDLIBS-y += --no-whole-archive
+
+ LDLIBS += $(_LDLIBS-y) $(CPU_LDLIBS) $(EXTRA_LDLIBS)
+
+Index: dpdk/mk/exec-env/linuxapp/rte.vars.mk
+===================================================================
+--- dpdk.orig/mk/exec-env/linuxapp/rte.vars.mk
++++ dpdk/mk/exec-env/linuxapp/rte.vars.mk
+@@ -45,9 +45,6 @@ else
+ EXECENV_CFLAGS = -pthread
+ endif
+
+-# Workaround lack of DT_NEEDED entry
+-EXECENV_LDFLAGS = --no-as-needed
+-
+ EXECENV_LDLIBS =
+ EXECENV_ASFLAGS =
+
diff --git a/debian/patches/ubuntu-backport-40-linking-fixes-stage-4-4.patch b/debian/patches/ubuntu-backport-40-linking-fixes-stage-4-4.patch
new file mode 100644
index 00000000..188ee2bd
--- /dev/null
+++ b/debian/patches/ubuntu-backport-40-linking-fixes-stage-4-4.patch
@@ -0,0 +1,149 @@
+Description: backport of dpdk 16.07 fix for library underlinking - stage 4/4
+
+This is a merge of related upstream fixes:
+- 473b718f mk: fix vhost dependency to pthread
+- 6cbf4f75 mk: fix missing internal dependencies
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/drivers/net/vhost/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/vhost/Makefile
++++ dpdk/drivers/net/vhost/Makefile
+@@ -36,6 +36,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
+ #
+ LIB = librte_pmd_vhost.a
+
++LDLIBS += -lpthread
++
+ CFLAGS += -O3
+ CFLAGS += $(WERROR_FLAGS)
+
+@@ -54,6 +56,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += r
+ SYMLINK-y-include += rte_eth_vhost.h
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_VHOST) += lib/librte_kvargs
+Index: dpdk/drivers/crypto/null/Makefile
+===================================================================
+--- dpdk.orig/drivers/crypto/null/Makefile
++++ dpdk/drivers/crypto/null/Makefile
+@@ -55,5 +55,7 @@ SYMLINK-y-include +=
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_cryptodev
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_ring
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL_CRYPTO) += lib/librte_kvargs
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/af_packet/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/af_packet/Makefile
++++ dpdk/drivers/net/af_packet/Makefile
+@@ -51,6 +51,7 @@ CFLAGS += $(WERROR_FLAGS)
+ SRCS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += rte_eth_af_packet.c
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_AF_PACKET) += lib/librte_kvargs
+Index: dpdk/drivers/net/bonding/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/bonding/Makefile
++++ dpdk/drivers/net/bonding/Makefile
+@@ -64,5 +64,7 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) +=
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_kvargs
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_cmdline
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_mempool
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_BOND) += lib/librte_ring
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/fm10k/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/fm10k/Makefile
++++ dpdk/drivers/net/fm10k/Makefile
+@@ -99,5 +99,6 @@ SRCS-$(CONFIG_RTE_LIBRTE_FM10K_INC_VECTO
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += lib/librte_eal lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += lib/librte_mempool lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += lib/librte_net
++DEPDIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += lib/librte_kvargs
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/drivers/net/null/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/null/Makefile
++++ dpdk/drivers/net/null/Makefile
+@@ -54,6 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += rt
+ SYMLINK-y-include += rte_eth_null.h
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += lib/librte_kvargs
+Index: dpdk/drivers/net/pcap/Makefile
+===================================================================
+--- dpdk.orig/drivers/net/pcap/Makefile
++++ dpdk/drivers/net/pcap/Makefile
+@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += rt
+ SYMLINK-y-include +=
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += lib/librte_kvargs
+Index: dpdk/lib/librte_ip_frag/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_ip_frag/Makefile
++++ dpdk/lib/librte_ip_frag/Makefile
+@@ -54,6 +54,7 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_IP_FRAG)-inc
+
+
+ # this library depends on rte_ether
++DEPDIRS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_IP_FRAG) += lib/librte_mempool lib/librte_ether
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/lib/librte_pipeline/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_pipeline/Makefile
++++ dpdk/lib/librte_pipeline/Makefile
+@@ -52,6 +52,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_PIPELINE) := rt
+ SYMLINK-$(CONFIG_RTE_LIBRTE_PIPELINE)-include += rte_pipeline.h
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) := lib/librte_table
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PIPELINE) += lib/librte_port
+
+Index: dpdk/lib/librte_port/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_port/Makefile
++++ dpdk/lib/librte_port/Makefile
+@@ -75,5 +75,6 @@ DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib/librte_mempool
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib/librte_ether
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib/librte_ip_frag
++DEPDIRS-$(CONFIG_RTE_LIBRTE_PORT) += lib/librte_sched
+
+ include $(RTE_SDK)/mk/rte.lib.mk
+Index: dpdk/lib/librte_sched/Makefile
+===================================================================
+--- dpdk.orig/lib/librte_sched/Makefile
++++ dpdk/lib/librte_sched/Makefile
+@@ -59,6 +59,7 @@ SYMLINK-$(CONFIG_RTE_LIBRTE_SCHED)-inclu
+ SYMLINK-$(CONFIG_RTE_LIBRTE_SCHED)-include += rte_reciprocal.h
+
+ # this lib depends upon:
++DEPDIRS-$(CONFIG_RTE_LIBRTE_SCHED) += lib/librte_eal
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_SCHED) += lib/librte_mempool lib/librte_mbuf
+ DEPDIRS-$(CONFIG_RTE_LIBRTE_SCHED) += lib/librte_net lib/librte_timer
+
diff --git a/debian/patches/ubuntu-backport-41-fix-install-tar-1.29.patch b/debian/patches/ubuntu-backport-41-fix-install-tar-1.29.patch
new file mode 100644
index 00000000..e485e528
--- /dev/null
+++ b/debian/patches/ubuntu-backport-41-fix-install-tar-1.29.patch
@@ -0,0 +1,25 @@
+Description: backport of dpdk 16.07 fix for tar >=1.29
+
+This is a backport of:
+- dd9ae4c7 mk: fix install with tar 1.29
+
+Forwarded: yes (in DPDK 16.07)
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-06-14
+
+Index: dpdk/mk/rte.sdkinstall.mk
+===================================================================
+--- dpdk.orig/mk/rte.sdkinstall.mk
++++ dpdk/mk/rte.sdkinstall.mk
+@@ -116,9 +116,9 @@ install-runtime:
+ $(Q)$(call rte_mkdir, $(DESTDIR)$(libdir))
+ $(Q)cp -a $O/lib/* $(DESTDIR)$(libdir)
+ $(Q)$(call rte_mkdir, $(DESTDIR)$(bindir))
+- $(Q)tar -cf - -C $O app --exclude 'app/*.map' \
++ $(Q)tar -cf - -C $O --exclude 'app/*.map' \
+ --exclude 'app/cmdline*' --exclude app/test \
+- --exclude app/testacl --exclude app/testpipeline | \
++ --exclude app/testacl --exclude app/testpipeline app | \
+ tar -xf - -C $(DESTDIR)$(bindir) --strip-components=1 \
+ --keep-newer-files --warning=no-ignore-newer
+ $(Q)$(call rte_mkdir, $(DESTDIR)$(datadir))
diff --git a/debian/patches/ubuntu-backport-42-increase-default-logging-level.patch b/debian/patches/ubuntu-backport-42-increase-default-logging-level.patch
new file mode 100644
index 00000000..de641035
--- /dev/null
+++ b/debian/patches/ubuntu-backport-42-increase-default-logging-level.patch
@@ -0,0 +1,81 @@
+Index: dpdk/config/common_base
+===================================================================
+--- dpdk.orig/config/common_base
++++ dpdk/config/common_base
+@@ -88,7 +88,7 @@ CONFIG_RTE_MAX_NUMA_NODES=8
+ CONFIG_RTE_MAX_MEMSEG=256
+ CONFIG_RTE_MAX_MEMZONE=2560
+ CONFIG_RTE_MAX_TAILQ=32
+-CONFIG_RTE_LOG_LEVEL=8
++CONFIG_RTE_LOG_LEVEL=RTE_LOG_INFO
+ CONFIG_RTE_LOG_HISTORY=256
+ CONFIG_RTE_LIBEAL_USE_HPET=n
+ CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID=n
+Index: dpdk/doc/guides/faq/faq.rst
+===================================================================
+--- dpdk.orig/doc/guides/faq/faq.rst
++++ dpdk/doc/guides/faq/faq.rst
+@@ -88,9 +88,7 @@ the wrong socket, the application simply
+ On application startup, there is a lot of EAL information printed. Is there any way to reduce this?
+ ---------------------------------------------------------------------------------------------------
+
+-Yes, each EAL has a configuration file that is located in the /config directory. Within each configuration file, you will find CONFIG_RTE_LOG_LEVEL=8.
+-You can change this to a lower value, such as 6 to reduce this printout of debug information. The following is a list of LOG levels that can be found in the rte_log.h file.
+-You must remove, then rebuild, the EAL directory for the change to become effective as the configuration file creates the rte_config.h file in the EAL directory.
++Yes, the option ``--log-level=`` accepts one of these numbers:
+
+ .. code-block:: c
+
+@@ -103,6 +101,9 @@ You must remove, then rebuild, the EAL d
+ #define RTE_LOG_INFO 7U /* Informational. */
+ #define RTE_LOG_DEBUG 8U /* Debug-level messages. */
+
++It is also possible to change the maximum (and default level) at compile time
++with ``CONFIG_RTE_LOG_LEVEL``.
++
+
+ How can I tune my network application to achieve lower latency?
+ ---------------------------------------------------------------
+Index: dpdk/lib/librte_eal/common/eal_common_log.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_log.c
++++ dpdk/lib/librte_eal/common/eal_common_log.c
+@@ -195,5 +195,10 @@ rte_eal_common_log_init(FILE *default_lo
+ {
+ default_log_stream = default_log;
+ rte_openlog_stream(default_log);
++
++#if RTE_LOG_LEVEL >= RTE_LOG_DEBUG
++ RTE_LOG(NOTICE, EAL, "Debug logs available - lower performance\n");
++#endif
++
+ return 0;
+ }
+Index: dpdk/lib/librte_eal/common/eal_common_options.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_options.c
++++ dpdk/lib/librte_eal/common/eal_common_options.c
+@@ -141,7 +141,11 @@ eal_reset_internal_config(struct interna
+
+ internal_cfg->syslog_facility = LOG_DAEMON;
+ /* default value from build option */
++#if RTE_LOG_LEVEL >= RTE_LOG_DEBUG
++ internal_cfg->log_level = RTE_LOG_INFO;
++#else
+ internal_cfg->log_level = RTE_LOG_LEVEL;
++#endif
+
+ internal_cfg->xen_dom0_support = 0;
+
+Index: dpdk/scripts/test-build.sh
+===================================================================
+--- dpdk.orig/scripts/test-build.sh
++++ dpdk/scripts/test-build.sh
+@@ -138,6 +138,7 @@ config () # <directory> <target> <option
+ ! echo $3 | grep -q '+shared' || \
+ sed -ri 's,(SHARED_LIB=)n,\1y,' $1/.config
+ ! echo $3 | grep -q '+debug' || ( \
++ sed -ri 's,(RTE_LOG_LEVEL=).*,\1RTE_LOG_DEBUG,' $1/.config
+ sed -ri 's,(_DEBUG.*=)n,\1y,' $1/.config
+ sed -ri 's,(_STAT.*=)n,\1y,' $1/.config
+ sed -ri 's,(TEST_PMD_RECORD_.*=)n,\1y,' $1/.config )
diff --git a/debian/patches/ubuntu-backport-43-fix-level-type-retrieving.patch b/debian/patches/ubuntu-backport-43-fix-level-type-retrieving.patch
new file mode 100644
index 00000000..9a56223f
--- /dev/null
+++ b/debian/patches/ubuntu-backport-43-fix-level-type-retrieving.patch
@@ -0,0 +1,61 @@
+Index: dpdk/lib/librte_eal/common/eal_common_log.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_log.c
++++ dpdk/lib/librte_eal/common/eal_common_log.c
+@@ -57,9 +57,10 @@ static FILE *default_log_stream;
+ struct log_cur_msg {
+ uint32_t loglevel; /**< log level - see rte_log.h */
+ uint32_t logtype; /**< log type - see rte_log.h */
+-} __rte_cache_aligned;
+-static struct log_cur_msg log_cur_msg[RTE_MAX_LCORE]; /**< per core log */
++};
+
++ /* per core log */
++static RTE_DEFINE_PER_LCORE(struct log_cur_msg, log_cur_msg);
+
+ /* default logs */
+
+@@ -121,21 +122,13 @@ rte_get_log_type(void)
+ /* get the current loglevel for the message beeing processed */
+ int rte_log_cur_msg_loglevel(void)
+ {
+- unsigned lcore_id;
+- lcore_id = rte_lcore_id();
+- if (lcore_id >= RTE_MAX_LCORE)
+- return rte_get_log_level();
+- return log_cur_msg[lcore_id].loglevel;
++ return RTE_PER_LCORE(log_cur_msg).loglevel;
+ }
+
+ /* get the current logtype for the message beeing processed */
+ int rte_log_cur_msg_logtype(void)
+ {
+- unsigned lcore_id;
+- lcore_id = rte_lcore_id();
+- if (lcore_id >= RTE_MAX_LCORE)
+- return rte_get_log_type();
+- return log_cur_msg[lcore_id].logtype;
++ return RTE_PER_LCORE(log_cur_msg).logtype;
+ }
+
+ /* Dump log history to file */
+@@ -153,17 +146,13 @@ rte_vlog(uint32_t level, uint32_t logtyp
+ {
+ int ret;
+ FILE *f = rte_logs.file;
+- unsigned lcore_id;
+
+ if ((level > rte_logs.level) || !(logtype & rte_logs.type))
+ return 0;
+
+ /* save loglevel and logtype in a global per-lcore variable */
+- lcore_id = rte_lcore_id();
+- if (lcore_id < RTE_MAX_LCORE) {
+- log_cur_msg[lcore_id].loglevel = level;
+- log_cur_msg[lcore_id].logtype = logtype;
+- }
++ RTE_PER_LCORE(log_cur_msg).loglevel = level;
++ RTE_PER_LCORE(log_cur_msg).logtype = logtype;
+
+ ret = vfprintf(f, format, ap);
+ fflush(f);
diff --git a/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch b/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch
new file mode 100644
index 00000000..c2a9cdbf
--- /dev/null
+++ b/debian/patches/ubuntu-fix-vhost-user-socket-permission.patch
@@ -0,0 +1,372 @@
+Description: eal: provide option to set vhost_user socket owner/permissions
+
+The API doesn't hold a way to specify a owner/permission set for vhost_user
+created sockets.
+
+Projects consuming DPDK started to do 'their own workarounds' like openvswitch
+https://patchwork.ozlabs.org/patch/559043/
+https://patchwork.ozlabs.org/patch/559045/
+But for this specific example they are blocked/stalled behind a bigger
+rework (https://patchwork.ozlabs.org/patch/604898/).
+
+We need something now for existing code linking against DPDK. That implies to
+avoid changing API/ABI. So I created a DPDK EAL commandline option based ideas
+in the former patches.
+
+Fixes LP: #1546565
+
+*Update*
+ - with the split libs it now nees to be listed in
+ lib/librte_eal/linuxapp/eal/rte_eal_version.map to work on link steps
+ - please note that upstream gravitates towards not extending but creating a
+ new the API in DPDK as long term solution (will take a while)
+ - also as listed before most affected projects seem to create their own
+ workaround.
+ So over time we have to check when we can drop it at the price of a config
+ transition - likely OVS 2.6 won't need it anymore.
+
+Forwarded: yes
+Author: Christian Ehrhardt <christian.ehrhardt@canonical.com>
+Last-Update: 2016-05-18
+
+Index: dpdk/lib/librte_eal/common/eal_common_options.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_common_options.c
++++ dpdk/lib/librte_eal/common/eal_common_options.c
+@@ -95,6 +95,8 @@ eal_long_options[] = {
+ {OPT_VFIO_INTR, 1, NULL, OPT_VFIO_INTR_NUM },
+ {OPT_VMWARE_TSC_MAP, 0, NULL, OPT_VMWARE_TSC_MAP_NUM },
+ {OPT_XEN_DOM0, 0, NULL, OPT_XEN_DOM0_NUM },
++ {OPT_VHOST_OWNER, 1, NULL, OPT_VHOST_OWNER_NUM },
++ {OPT_VHOST_PERM, 1, NULL, OPT_VHOST_PERM_NUM },
+ {0, 0, NULL, 0 }
+ };
+
+@@ -153,6 +155,8 @@ eal_reset_internal_config(struct interna
+ #endif
+ internal_cfg->vmware_tsc_map = 0;
+ internal_cfg->create_uio_dev = 0;
++ internal_cfg->vhost_sock_owner = NULL;
++ internal_cfg->vhost_sock_perm = NULL;
+ }
+
+ static int
+Index: dpdk/lib/librte_eal/common/eal_internal_cfg.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_internal_cfg.h
++++ dpdk/lib/librte_eal/common/eal_internal_cfg.h
+@@ -83,6 +83,8 @@ struct internal_config {
+ volatile enum rte_intr_mode vfio_intr_mode;
+ const char *hugefile_prefix; /**< the base filename of hugetlbfs files */
+ const char *hugepage_dir; /**< specific hugetlbfs directory to use */
++ const char *vhost_sock_owner; /**< owner:group of vhost_user sockets */
++ const char *vhost_sock_perm; /**< permissions of vhost_user sockets */
+
+ unsigned num_hugepage_sizes; /**< how many sizes on this system */
+ struct hugepage_info hugepage_info[MAX_HUGEPAGE_SIZES];
+Index: dpdk/lib/librte_eal/common/eal_options.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/eal_options.h
++++ dpdk/lib/librte_eal/common/eal_options.h
+@@ -83,6 +83,10 @@ enum {
+ OPT_VMWARE_TSC_MAP_NUM,
+ #define OPT_XEN_DOM0 "xen-dom0"
+ OPT_XEN_DOM0_NUM,
++#define OPT_VHOST_OWNER "vhost-owner"
++ OPT_VHOST_OWNER_NUM,
++#define OPT_VHOST_PERM "vhost-perm"
++ OPT_VHOST_PERM_NUM,
+ OPT_LONG_MAX_NUM
+ };
+
+Index: dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+===================================================================
+--- dpdk.orig/lib/librte_vhost/vhost_user/vhost-net-user.c
++++ dpdk/lib/librte_vhost/vhost_user/vhost-net-user.c
+@@ -51,6 +51,8 @@
+ #include "vhost-net.h"
+ #include "virtio-net-user.h"
+
++#include <rte_eal.h>
++
+ #define MAX_VIRTIO_BACKLOG 128
+
+ static void vserver_new_vq_conn(int fd, void *data, int *remove);
+@@ -486,6 +488,8 @@ rte_vhost_driver_register(const char *pa
+ return -1;
+ }
+
++ rte_eal_set_socket_permissions(path);
++
+ vserver->path = strdup(path);
+ vserver->fh = -1;
+
+Index: dpdk/lib/librte_eal/linuxapp/eal/eal.c
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/eal.c
++++ dpdk/lib/librte_eal/linuxapp/eal/eal.c
+@@ -53,6 +53,9 @@
+ #if defined(RTE_ARCH_X86)
+ #include <sys/io.h>
+ #endif
++#include <sys/types.h>
++#include <pwd.h>
++#include <grp.h>
+
+ #include <rte_common.h>
+ #include <rte_debug.h>
+@@ -343,6 +346,8 @@ eal_usage(const char *prgname)
+ " --"OPT_CREATE_UIO_DEV" Create /dev/uioX (usually done by hotplug)\n"
+ " --"OPT_VFIO_INTR" Interrupt mode for VFIO (legacy|msi|msix)\n"
+ " --"OPT_XEN_DOM0" Support running on Xen dom0 without hugetlbfs\n"
++ " --"OPT_VHOST_OWNER" Create vhost-user sockets with this owner:group\n"
++ " --"OPT_VHOST_PERM" Create vhost-user sockets with these permissions\n"
+ "\n");
+ /* Allow the application to print its usage message too if hook is set */
+ if ( rte_application_usage_hook ) {
+@@ -618,6 +623,14 @@ eal_parse_args(int argc, char **argv)
+ internal_config.create_uio_dev = 1;
+ break;
+
++ case OPT_VHOST_OWNER_NUM:
++ internal_config.vhost_sock_owner = optarg;
++ break;
++
++ case OPT_VHOST_PERM_NUM:
++ internal_config.vhost_sock_perm = optarg;
++ break;
++
+ default:
+ if (opt < OPT_LONG_MIN_NUM && isprint(opt)) {
+ RTE_LOG(ERR, EAL, "Option %c is not supported "
+@@ -934,3 +947,172 @@ rte_eal_check_module(const char *module_
+ /* Module has been found */
+ return 1;
+ }
++
++/* Try to double the size of '*buf', return true
++ * if successful, and '*sizep' will be updated with
++ * the new size. Otherwise, return false. */
++static int
++enlarge_buffer(char **buf, size_t *sizep)
++{
++ size_t newsize = *sizep * 2;
++
++ if (newsize > *sizep) {
++ *buf = realloc(*buf, newsize);
++ *sizep = newsize;
++ return 1;
++ }
++
++ return 0;
++}
++
++static int
++get_owners_from_str(const char *user_spec, uid_t *uid, gid_t *gid)
++{
++ size_t bufsize = 4096;
++
++ char *pos = strchr(user_spec, ':');
++ user_spec += strspn(user_spec, " \t\r\n");
++ size_t len = pos ? (size_t)(pos - user_spec) : strlen(user_spec);
++
++ char *buf = NULL;
++ struct passwd pwd, *res;
++ int e;
++
++ buf = malloc(bufsize);
++ char *user_search = NULL;
++ if (len) {
++ user_search = malloc(len + 1);
++ memcpy(user_search, user_spec, len);
++ user_search[len] = '\0';
++ while ((e = getpwnam_r(user_search, &pwd, buf, bufsize, &res)) == ERANGE) {
++ if (!enlarge_buffer(&buf, &bufsize)) {
++ break;
++ }
++ }
++
++ if (e != 0) {
++ RTE_LOG(ERR, EAL,"Failed to retrive user %s's uid (%s), aborting.",
++ user_search, strerror(e));
++ goto release;
++ }
++ if (res == NULL) {
++ RTE_LOG(ERR, EAL,"user %s not found, aborting.",
++ user_search);
++ e = -1;
++ goto release;
++ }
++ } else {
++ /* User name is not specified, use current user. */
++ while ((e = getpwuid_r(getuid(), &pwd, buf, bufsize, &res)) == ERANGE) {
++ if (!enlarge_buffer(&buf, &bufsize)) {
++ break;
++ }
++ }
++
++ if (e != 0) {
++ RTE_LOG(ERR, EAL,"Failed to retrive current user's uid "
++ "(%s), aborting.", strerror(e));
++ goto release;
++ }
++ user_search = strdup(pwd.pw_name);
++ }
++
++ if (uid)
++ *uid = pwd.pw_uid;
++
++ free(buf);
++ buf = NULL;
++
++ if (pos) {
++ char *grpstr = pos + 1;
++ grpstr += strspn(grpstr, " \t\r\n");
++
++ if (*grpstr) {
++ struct group grp, *res;
++
++ bufsize = 4096;
++ buf = malloc(bufsize);
++ while ((e = getgrnam_r(grpstr, &grp, buf, bufsize, &res))
++ == ERANGE) {
++ if (!enlarge_buffer(&buf, &bufsize)) {
++ break;
++ }
++ }
++
++ if (e) {
++ RTE_LOG(ERR, EAL,"Failed to get group entry for %s, "
++ "(%s), aborting.", grpstr,
++ strerror(e));
++ goto release;
++ }
++ if (res == NULL) {
++ RTE_LOG(ERR, EAL,"Group %s not found, aborting.",
++ grpstr);
++ e = -1;
++ goto release;
++ }
++
++ if (gid)
++ *gid = grp.gr_gid;
++ }
++ }
++
++ release:
++ free(buf);
++ free(user_search);
++ return e;
++}
++
++static void
++vhost_set_permissions(const char *vhost_sock_location)
++{
++ unsigned long int mode = strtoul(internal_config.vhost_sock_perm, NULL, 0);
++ int err = chmod(vhost_sock_location, (mode_t)mode);
++ if (err) {
++ RTE_LOG(ERR, EAL,"vhost-user socket cannot set"
++ " permissions to %s (%s).\n",
++ internal_config.vhost_sock_perm, strerror(err));
++ return;
++ }
++ RTE_LOG(INFO, EAL,"Socket %s changed permissions"
++ " to %s\n", vhost_sock_location,
++ internal_config.vhost_sock_perm);
++}
++
++static void
++vhost_set_ownership(const char *vhost_sock_location)
++{
++ uid_t vhuid=0;
++ gid_t vhgid=0;
++
++ if (get_owners_from_str(internal_config.vhost_sock_owner, &vhuid, &vhgid)) {
++ RTE_LOG(ERR, EAL,"vhost-user socket unable to get"
++ " specified user/group: %s\n",
++ internal_config.vhost_sock_owner);
++ return;
++ }
++
++ int err = chown(vhost_sock_location, vhuid, vhgid);
++ if (err) {
++ RTE_LOG(ERR, EAL,"vhost-user socket unable to set"
++ " ownership to %s (%s).\n",
++ internal_config.vhost_sock_owner, strerror(err));
++ return;
++ }
++
++ RTE_LOG(INFO, EAL,"Socket %s changed ownership"
++ " to %s.\n", vhost_sock_location,
++ internal_config.vhost_sock_owner);
++}
++
++void
++rte_eal_set_socket_permissions(const char *path)
++{
++ if (internal_config.vhost_sock_perm) {
++ vhost_set_permissions(path);
++ }
++
++ if (internal_config.vhost_sock_owner) {
++ vhost_set_ownership(path);
++ }
++}
+Index: dpdk/lib/librte_eal/common/include/rte_eal.h
+===================================================================
+--- dpdk.orig/lib/librte_eal/common/include/rte_eal.h
++++ dpdk/lib/librte_eal/common/include/rte_eal.h
+@@ -252,6 +252,11 @@ static inline int rte_gettid(void)
+ return RTE_PER_LCORE(_thread_id);
+ }
+
++/**
++ * Set owner/permissions on sockets if requested on EAL commandline
++ */
++void rte_eal_set_socket_permissions(const char *);
++
+ #ifdef __cplusplus
+ }
+ #endif
+Index: dpdk/doc/guides/testpmd_app_ug/run_app.rst
+===================================================================
+--- dpdk.orig/doc/guides/testpmd_app_ug/run_app.rst
++++ dpdk/doc/guides/testpmd_app_ug/run_app.rst
+@@ -156,6 +156,25 @@ See the DPDK Getting Started Guides for
+
+ Use malloc instead of hugetlbfs.
+
++* ``--vhost-owner``
++
++ When creating vhost_user sockets change owner and group to the specified value.
++ This can be given as ``user:group``, but also only ``user`` or ``:group`` are supported.
++
++ Examples::
++
++ --vhost-owner 'libvirt-qemu:kvm'
++ --vhost-owner 'libvirt-qemu'
++ --vhost-owner ':kvm'
++
++* ``--vhost-perm``
++
++ When creating vhost_user sockets set them up with these permissions.
++
++ For example::
++
++ --vhost-perm '0664'
++
+
+ Testpmd Command-line Options
+ ----------------------------
+Index: dpdk/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+===================================================================
+--- dpdk.orig/lib/librte_eal/linuxapp/eal/rte_eal_version.map
++++ dpdk/lib/librte_eal/linuxapp/eal/rte_eal_version.map
+@@ -138,6 +138,7 @@ DPDK_2.2 {
+ rte_keepalive_mark_alive;
+ rte_keepalive_register_core;
+ rte_xen_dom0_supported;
++ rte_eal_set_socket_permissions;
+
+ } DPDK_2.1;
+
diff --git a/debian/patches/ubuntu-fix-xenvirt-support-dynamic-page-size.patch b/debian/patches/ubuntu-fix-xenvirt-support-dynamic-page-size.patch
new file mode 100644
index 00000000..ed6fb5d0
--- /dev/null
+++ b/debian/patches/ubuntu-fix-xenvirt-support-dynamic-page-size.patch
@@ -0,0 +1,32 @@
+Author: Ricardo Salveti <ricardo.salveti@linaro.org>
+Last-Update: 2016-04-17
+Fowarded: yes
+Description: xenvirt: support dynamic page size
+
+Fix build failure since PAGE_SIZE is not defined on ARM (multiple values
+are possible, so it needs to dynamically get the page size used).
+
+http://dpdk.org/ml/archives/dev/2016-April/037586.html
+
+Signed-off-by: Ricardo Salveti <ricardo.salveti@linaro.org>
+---
+ drivers/net/xenvirt/rte_eth_xenvirt.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
+index b9638d9..afc0193 100644
+--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
++++ b/drivers/net/xenvirt/rte_eth_xenvirt.c
+@@ -39,6 +39,9 @@
+ #include <sys/mman.h>
+ #include <errno.h>
+ #include <sys/user.h>
++#ifndef PAGE_SIZE
++#define PAGE_SIZE sysconf(_SC_PAGE_SIZE)
++#endif
+ #include <linux/binfmts.h>
+ #include <xen/xen-compat.h>
+ #if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
+--
+2.7.4
+