All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/6] remove xen dom0 support in DPDK
@ 2017-08-30 18:10 Jianfeng Tan
  2017-08-30 18:10 ` [PATCH 1/6] example/vhost_xen: remove Jianfeng Tan
                   ` (10 more replies)
  0 siblings, 11 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
	shahafs, Jianfeng Tan

Following the calls on the mailing list:
    http://dpdk.org/ml/archives/dev/2017-June/068151.html
The Technical Board decided to drop Xen dom0 support from EAL:
    http://dpdk.org/ml/archives/dev/2017-June/068615.html

This series remove xen dom0 support in DPDK, as well as xenvirt PMD and
vhost_xen example.

What are effected?

After these patches, users cannot run DPDK applications inside xen dom0.

What are not effected?

Users can still run DPDK applications inside xen domU on pass-throughed
physical devices and virtio devices; on the host, users still can run
DPDK applications same as before.

Jianfeng Tan (6):
  example/vhost_xen: remove
  net/xenvirt: remove
  xen: remove xen dependency in app, examples, test
  xen: remove xen dependency in drivers, ether, mempool
  eal: remove xen dom0 support
  eal: remove API rte_mem_phy2mch

 MAINTAINERS                                        |   10 -
 app/test-pmd/Makefile                              |    4 -
 app/test-pmd/testpmd.c                             |   14 +-
 config/common_base                                 |   10 -
 config/defconfig_arm-armv7a-linuxapp-gcc           |    1 -
 doc/guides/index.rst                               |    1 -
 doc/guides/linux_gsg/build_sample_apps.rst         |    5 +-
 doc/guides/linux_gsg/sys_reqs.rst                  |   53 -
 doc/guides/nics/features/xenvirt.ini               |    6 -
 doc/guides/prog_guide/source_org.rst               |    1 -
 doc/guides/rel_notes/deprecation.rst               |    3 -
 doc/guides/rel_notes/release_17_11.rst             |   14 +
 doc/guides/testpmd_app_ug/run_app.rst              |    4 -
 doc/guides/xen/img/dpdk_xen_pkt_switch.png         |  Bin 163842 -> 0 bytes
 doc/guides/xen/img/grant_refs.png                  |  Bin 6405 -> 0 bytes
 doc/guides/xen/img/grant_table.png                 |  Bin 96762 -> 0 bytes
 doc/guides/xen/index.rst                           |   38 -
 doc/guides/xen/pkt_switch.rst                      |  470 ------
 drivers/crypto/qat/qat_qp.c                        |    7 +-
 drivers/net/Makefile                               |    2 -
 drivers/net/e1000/em_rxtx.c                        |    4 +-
 drivers/net/e1000/igb_rxtx.c                       |    4 +-
 drivers/net/fm10k/fm10k_ethdev.c                   |    4 +-
 drivers/net/i40e/i40e_ethdev.c                     |    2 +-
 drivers/net/i40e/i40e_fdir.c                       |    2 +-
 drivers/net/i40e/i40e_rxtx.c                       |   16 +-
 drivers/net/ixgbe/ixgbe_rxtx.c                     |    4 +-
 drivers/net/sfc/sfc.c                              |    2 +-
 drivers/net/xenvirt/Makefile                       |   57 -
 drivers/net/xenvirt/rte_eth_xenvirt.c              |  766 ----------
 drivers/net/xenvirt/rte_eth_xenvirt.h              |   61 -
 drivers/net/xenvirt/rte_eth_xenvirt_version.map    |    7 -
 drivers/net/xenvirt/rte_mempool_gntalloc.c         |  295 ----
 drivers/net/xenvirt/rte_xen_lib.c                  |  454 ------
 drivers/net/xenvirt/rte_xen_lib.h                  |  116 --
 drivers/net/xenvirt/virtio_logs.h                  |   70 -
 drivers/net/xenvirt/virtqueue.h                    |  273 ----
 examples/Makefile                                  |    1 -
 examples/ip_pipeline/app.h                         |    4 -
 examples/ip_pipeline/config_parse.c                |   19 -
 examples/ip_pipeline/init.c                        |    5 -
 examples/kni/main.c                                |    3 -
 examples/vhost_xen/Makefile                        |   52 -
 examples/vhost_xen/main.c                          | 1522 --------------------
 examples/vhost_xen/main.h                          |   66 -
 examples/vhost_xen/vhost_monitor.c                 |  595 --------
 examples/vhost_xen/virtio-net.h                    |  113 --
 examples/vhost_xen/xen_vhost.h                     |  148 --
 examples/vhost_xen/xenstore_parse.c                |  775 ----------
 .../bsdapp/eal/include/exec-env/rte_dom0_common.h  |  107 --
 lib/librte_eal/common/eal_common_options.c         |    3 -
 lib/librte_eal/common/eal_internal_cfg.h           |    1 -
 lib/librte_eal/common/eal_options.h                |    2 -
 lib/librte_eal/common/include/rte_memory.h         |   71 -
 lib/librte_eal/linuxapp/Makefile                   |    2 -
 lib/librte_eal/linuxapp/eal/Makefile               |    5 +-
 lib/librte_eal/linuxapp/eal/eal.c                  |   24 -
 lib/librte_eal/linuxapp/eal/eal_memory.c           |   56 -
 lib/librte_eal/linuxapp/eal/eal_xen_memory.c       |  381 -----
 .../eal/include/exec-env/rte_dom0_common.h         |  108 --
 lib/librte_eal/linuxapp/igb_uio/igb_uio.c          |   54 -
 lib/librte_eal/linuxapp/xen_dom0/Makefile          |   53 -
 lib/librte_eal/linuxapp/xen_dom0/compat.h          |   15 -
 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h     |  107 --
 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c    |  780 ----------
 lib/librte_ether/rte_ethdev.c                      |    7 +-
 lib/librte_mempool/rte_mempool.c                   |   11 +-
 mk/rte.app.mk                                      |    1 -
 pkg/dpdk.spec                                      |    6 -
 test/test/process.h                                |   10 -
 test/test/test.c                                   |    4 -
 test/test/test_eal_flags.c                         |   81 --
 72 files changed, 38 insertions(+), 7934 deletions(-)
 delete mode 100644 doc/guides/nics/features/xenvirt.ini
 delete mode 100644 doc/guides/xen/img/dpdk_xen_pkt_switch.png
 delete mode 100644 doc/guides/xen/img/grant_refs.png
 delete mode 100644 doc/guides/xen/img/grant_table.png
 delete mode 100644 doc/guides/xen/index.rst
 delete mode 100644 doc/guides/xen/pkt_switch.rst
 delete mode 100644 drivers/net/xenvirt/Makefile
 delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
 delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
 delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
 delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
 delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
 delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
 delete mode 100644 drivers/net/xenvirt/virtio_logs.h
 delete mode 100644 drivers/net/xenvirt/virtqueue.h
 delete mode 100644 examples/vhost_xen/Makefile
 delete mode 100644 examples/vhost_xen/main.c
 delete mode 100644 examples/vhost_xen/main.h
 delete mode 100644 examples/vhost_xen/vhost_monitor.c
 delete mode 100644 examples/vhost_xen/virtio-net.h
 delete mode 100644 examples/vhost_xen/xen_vhost.h
 delete mode 100644 examples/vhost_xen/xenstore_parse.c
 delete mode 100644 lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_xen_memory.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
 delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/Makefile
 delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/compat.h
 delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h
 delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c

-- 
2.7.4

^ permalink raw reply	[flat|nested] 38+ messages in thread

* [PATCH 1/6] example/vhost_xen: remove
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
  2017-08-30 18:10 ` [PATCH 1/6] example/vhost_xen: remove Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-09-04 14:14   ` [dpdk-dev] " Bruce Richardson
  2017-09-04 14:14   ` Bruce Richardson
  2017-08-30 18:10 ` [PATCH 2/6] net/xenvirt: remove Jianfeng Tan
                   ` (8 subsequent siblings)
  10 siblings, 2 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
	shahafs, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 MAINTAINERS                         |    1 -
 examples/Makefile                   |    1 -
 examples/vhost_xen/Makefile         |   52 --
 examples/vhost_xen/main.c           | 1522 -----------------------------------
 examples/vhost_xen/main.h           |   66 --
 examples/vhost_xen/vhost_monitor.c  |  595 --------------
 examples/vhost_xen/virtio-net.h     |  113 ---
 examples/vhost_xen/xen_vhost.h      |  148 ----
 examples/vhost_xen/xenstore_parse.c |  775 ------------------
 9 files changed, 3273 deletions(-)
 delete mode 100644 examples/vhost_xen/Makefile
 delete mode 100644 examples/vhost_xen/main.c
 delete mode 100644 examples/vhost_xen/main.h
 delete mode 100644 examples/vhost_xen/vhost_monitor.c
 delete mode 100644 examples/vhost_xen/virtio-net.h
 delete mode 100644 examples/vhost_xen/xen_vhost.h
 delete mode 100644 examples/vhost_xen/xenstore_parse.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a0cd75e..fe6c6db 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -196,7 +196,6 @@ F: lib/librte_eal/linuxapp/eal/*xen*
 F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
 F: drivers/net/xenvirt/
 F: doc/guides/xen/
-F: examples/vhost_xen/
 F: doc/guides/nics/features/xenvirt.ini
 
 FreeBSD EAL (with overlaps)
diff --git a/examples/Makefile b/examples/Makefile
index 28354ff..d27eddd 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -89,7 +89,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += tep_termination
 endif
 DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += timer
 DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += vhost vhost_scsi
-DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += vhost_xen
 DIRS-y += vmdq
 DIRS-y += vmdq_dcb
 ifeq ($(CONFIG_RTE_LIBRTE_POWER), y)
diff --git a/examples/vhost_xen/Makefile b/examples/vhost_xen/Makefile
deleted file mode 100644
index ad2466a..0000000
--- a/examples/vhost_xen/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-ifeq ($(RTE_SDK),)
-$(error "Please define RTE_SDK environment variable")
-endif
-
-# Default target, can be overridden by command line or environment
-RTE_TARGET ?= x86_64-native-linuxapp-gcc
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-# binary name
-APP = vhost-switch
-
-# all source are stored in SRCS-y
-SRCS-y := main.c vhost_monitor.c xenstore_parse.c
-
-CFLAGS += -O2 -I/usr/local/include -D_FILE_OFFSET_BITS=64 -Wno-unused-parameter
-CFLAGS += $(WERROR_FLAGS)
-CFLAGS += -D_GNU_SOURCE
-LDFLAGS += -lxenstore
-
-include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/vhost_xen/main.c b/examples/vhost_xen/main.c
deleted file mode 100644
index eba4d35..0000000
--- a/examples/vhost_xen/main.c
+++ /dev/null
@@ -1,1522 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <arpa/inet.h>
-#include <getopt.h>
-#include <linux/if_ether.h>
-#include <linux/if_vlan.h>
-#include <linux/virtio_net.h>
-#include <linux/virtio_ring.h>
-#include <signal.h>
-#include <stdint.h>
-#include <sys/eventfd.h>
-#include <sys/param.h>
-#include <unistd.h>
-
-#include <rte_atomic.h>
-#include <rte_cycles.h>
-#include <rte_ethdev.h>
-#include <rte_log.h>
-#include <rte_string_fns.h>
-#include <rte_pause.h>
-
-#include "main.h"
-#include "virtio-net.h"
-#include "xen_vhost.h"
-
-#define MAX_QUEUES 128
-
-/* the maximum number of external ports supported */
-#define MAX_SUP_PORTS 1
-
-/*
- * Calculate the number of buffers needed per port
- */
-#define NUM_MBUFS_PER_PORT ((MAX_QUEUES*RTE_TEST_RX_DESC_DEFAULT) +		\
-							(num_switching_cores*MAX_PKT_BURST) +  			\
-							(num_switching_cores*RTE_TEST_TX_DESC_DEFAULT) +\
-							(num_switching_cores*MBUF_CACHE_SIZE))
-
-#define MBUF_CACHE_SIZE 64
-
-/*
- * RX and TX Prefetch, Host, and Write-back threshold values should be
- * carefully set for optimal performance. Consult the network
- * controller's datasheet and supporting DPDK documentation for guidance
- * on how these parameters should be set.
- */
-#define RX_PTHRESH 8 /* Default values of RX prefetch threshold reg. */
-#define RX_HTHRESH 8 /* Default values of RX host threshold reg. */
-#define RX_WTHRESH 4 /* Default values of RX write-back threshold reg. */
-
-/*
- * These default values are optimized for use with the Intel(R) 82599 10 GbE
- * Controller and the DPDK ixgbe PMD. Consider using other values for other
- * network controllers and/or network drivers.
- */
-#define TX_PTHRESH 36 /* Default values of TX prefetch threshold reg. */
-#define TX_HTHRESH 0  /* Default values of TX host threshold reg. */
-#define TX_WTHRESH 0  /* Default values of TX write-back threshold reg. */
-
-#define MAX_PKT_BURST 32		/* Max burst size for RX/TX */
-#define MAX_MRG_PKT_BURST 16	/* Max burst for merge buffers. Set to 1 due to performance issue. */
-#define BURST_TX_DRAIN_US 100	/* TX drain every ~100us */
-
-/* State of virtio device. */
-#define DEVICE_NOT_READY     0
-#define DEVICE_READY         1
-#define DEVICE_SAFE_REMOVE   2
-
-/* Config_core_flag status definitions. */
-#define REQUEST_DEV_REMOVAL 1
-#define ACK_DEV_REMOVAL 0
-
-/* Configurable number of RX/TX ring descriptors */
-#define RTE_TEST_RX_DESC_DEFAULT 128
-#define RTE_TEST_TX_DESC_DEFAULT 512
-
-#define INVALID_PORT_ID 0xFF
-
-/* Max number of devices. Limited by vmdq. */
-#define MAX_DEVICES 64
-
-/* Size of buffers used for snprintfs. */
-#define MAX_PRINT_BUFF 6072
-
-
-/* Maximum long option length for option parsing. */
-#define MAX_LONG_OPT_SZ 64
-
-/* Used to compare MAC addresses. */
-#define MAC_ADDR_CMP 0xFFFFFFFFFFFF
-
-/* mask of enabled ports */
-static uint32_t enabled_port_mask = 0;
-
-/*Number of switching cores enabled*/
-static uint32_t num_switching_cores = 0;
-
-/* number of devices/queues to support*/
-static uint32_t num_queues = 0;
-uint32_t num_devices = 0;
-
-/* Enable VM2VM communications. If this is disabled then the MAC address compare is skipped. */
-static uint32_t enable_vm2vm = 1;
-/* Enable stats. */
-static uint32_t enable_stats = 0;
-
-/* empty vmdq configuration structure. Filled in programatically */
-static const struct rte_eth_conf vmdq_conf_default = {
-	.rxmode = {
-		.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
-		.split_hdr_size = 0,
-		.header_split   = 0, /**< Header Split disabled */
-		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
-		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
-		/*
-		 * It is necessary for 1G NIC such as I350,
-		 * this fixes bug of ipv4 forwarding in guest can't
-		 * forward pakets from one virtio dev to another virtio dev.
-		 */
-		.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
-		.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
-		.hw_strip_crc   = 1, /**< CRC stripped by hardware */
-	},
-
-	.txmode = {
-		.mq_mode = ETH_MQ_TX_NONE,
-	},
-	.rx_adv_conf = {
-		/*
-		 * should be overridden separately in code with
-		 * appropriate values
-		 */
-		.vmdq_rx_conf = {
-			.nb_queue_pools = ETH_8_POOLS,
-			.enable_default_pool = 0,
-			.default_pool = 0,
-			.nb_pool_maps = 0,
-			.pool_map = {{0, 0},},
-		},
-	},
-};
-
-static unsigned lcore_ids[RTE_MAX_LCORE];
-static uint8_t ports[RTE_MAX_ETHPORTS];
-static unsigned num_ports = 0; /**< The number of ports specified in command line */
-
-const uint16_t vlan_tags[] = {
-	1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007,
-	1008, 1009, 1010, 1011,	1012, 1013, 1014, 1015,
-	1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
-	1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031,
-	1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
-	1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047,
-	1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055,
-	1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
-};
-
-/* ethernet addresses of ports */
-static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS];
-
-/* heads for the main used and free linked lists for the data path. */
-static struct virtio_net_data_ll *ll_root_used = NULL;
-static struct virtio_net_data_ll *ll_root_free = NULL;
-
-/* Array of data core structures containing information on individual core linked lists. */
-static struct lcore_info lcore_info[RTE_MAX_LCORE];
-
-/* Used for queueing bursts of TX packets. */
-struct mbuf_table {
-	unsigned len;
-	unsigned txq_id;
-	struct rte_mbuf *m_table[MAX_PKT_BURST];
-};
-
-/* TX queue for each data core. */
-struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
-
-/* Vlan header struct used to insert vlan tags on TX. */
-struct vlan_ethhdr {
-	unsigned char   h_dest[ETH_ALEN];
-	unsigned char   h_source[ETH_ALEN];
-	__be16          h_vlan_proto;
-	__be16          h_vlan_TCI;
-	__be16          h_vlan_encapsulated_proto;
-};
-
-/* Header lengths. */
-#define VLAN_HLEN       4
-#define VLAN_ETH_HLEN   18
-
-/* Per-device statistics struct */
-struct device_statistics {
-	uint64_t tx_total;
-	rte_atomic64_t rx_total;
-	uint64_t tx;
-	rte_atomic64_t rx;
-} __rte_cache_aligned;
-struct device_statistics dev_statistics[MAX_DEVICES];
-
-/*
- * Builds up the correct configuration for VMDQ VLAN pool map
- * according to the pool & queue limits.
- */
-static inline int
-get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_devices)
-{
-	struct rte_eth_vmdq_rx_conf conf;
-	unsigned i;
-
-	memset(&conf, 0, sizeof(conf));
-	conf.nb_queue_pools = (enum rte_eth_nb_pools)num_devices;
-	conf.nb_pool_maps = num_devices;
-
-	for (i = 0; i < conf.nb_pool_maps; i++) {
-		conf.pool_map[i].vlan_id = vlan_tags[ i ];
-		conf.pool_map[i].pools = (1UL << i);
-	}
-
-	(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
-	(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,
-		   sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
-	return 0;
-}
-
-/*
- * Validate the device number according to the max pool number gotten form dev_info
- * If the device number is invalid, give the error message and return -1.
- * Each device must have its own pool.
- */
-static inline int
-validate_num_devices(uint32_t max_nb_devices)
-{
-	if (num_devices > max_nb_devices) {
-		RTE_LOG(ERR, VHOST_PORT, "invalid number of devices\n");
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * Initialises a given port using global settings and with the rx buffers
- * coming from the mbuf_pool passed as parameter
- */
-static inline int
-port_init(uint8_t port, struct rte_mempool *mbuf_pool)
-{
-	struct rte_eth_dev_info dev_info;
-	struct rte_eth_rxconf *rxconf;
-	struct rte_eth_conf port_conf;
-	uint16_t rx_rings, tx_rings = (uint16_t)rte_lcore_count();
-	uint16_t rx_ring_size = RTE_TEST_RX_DESC_DEFAULT;
-	uint16_t tx_ring_size = RTE_TEST_TX_DESC_DEFAULT;
-	int retval;
-	uint16_t q;
-
-	/* The max pool number from dev_info will be used to validate the pool number specified in cmd line */
-	rte_eth_dev_info_get (port, &dev_info);
-
-	/*configure the number of supported virtio devices based on VMDQ limits */
-	num_devices = dev_info.max_vmdq_pools;
-	num_queues = dev_info.max_rx_queues;
-
-	retval = validate_num_devices(MAX_DEVICES);
-	if (retval < 0)
-		return retval;
-
-	/* Get port configuration. */
-	retval = get_eth_conf(&port_conf, num_devices);
-	if (retval < 0)
-		return retval;
-
-	if (port >= rte_eth_dev_count()) return -1;
-
-	rx_rings = (uint16_t)num_queues,
-	/* Configure ethernet device. */
-	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
-	if (retval != 0)
-		return retval;
-
-	retval = rte_eth_dev_adjust_nb_rx_tx_desc(port, &rx_ring_size,
-		&tx_ring_size);
-	if (retval != 0)
-		return retval;
-	if (rx_ring_size > RTE_TEST_RX_DESC_DEFAULT ||
-		tx_ring_size > RTE_TEST_TX_DESC_DEFAULT) {
-		RTE_LOG(ERR, VHOST_PORT, "Mbuf pool has an insufficient size for "
-			"port %u.\n", port);
-		return -1;
-	}
-
-	rte_eth_dev_info_get(port, &dev_info);
-	rxconf = &dev_info.default_rxconf;
-	rxconf->rx_drop_en = 1;
-	/* Setup the queues. */
-	for (q = 0; q < rx_rings; q ++) {
-		retval = rte_eth_rx_queue_setup(port, q, rx_ring_size,
-						rte_eth_dev_socket_id(port), rxconf,
-						mbuf_pool);
-		if (retval < 0)
-			return retval;
-	}
-	for (q = 0; q < tx_rings; q ++) {
-		retval = rte_eth_tx_queue_setup(port, q, tx_ring_size,
-						rte_eth_dev_socket_id(port),
-						NULL);
-		if (retval < 0)
-			return retval;
-	}
-
-	/* Start the device. */
-	retval  = rte_eth_dev_start(port);
-	if (retval < 0)
-		return retval;
-
-	rte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]);
-	RTE_LOG(INFO, VHOST_PORT, "Max virtio devices supported: %u\n", num_devices);
-	RTE_LOG(INFO, VHOST_PORT, "Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
-			" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
-			(unsigned)port,
-			vmdq_ports_eth_addr[port].addr_bytes[0],
-			vmdq_ports_eth_addr[port].addr_bytes[1],
-			vmdq_ports_eth_addr[port].addr_bytes[2],
-			vmdq_ports_eth_addr[port].addr_bytes[3],
-			vmdq_ports_eth_addr[port].addr_bytes[4],
-			vmdq_ports_eth_addr[port].addr_bytes[5]);
-
-	return 0;
-}
-
-/*
- * Parse the portmask provided at run time.
- */
-static int
-parse_portmask(const char *portmask)
-{
-	char *end = NULL;
-	unsigned long pm;
-
-	errno = 0;
-
-	/* parse hexadecimal string */
-	pm = strtoul(portmask, &end, 16);
-	if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0') || (errno != 0))
-		return -1;
-
-	if (pm == 0)
-		return -1;
-
-	return pm;
-
-}
-
-/*
- * Parse num options at run time.
- */
-static int
-parse_num_opt(const char *q_arg, uint32_t max_valid_value)
-{
-	char *end = NULL;
-	unsigned long num;
-
-	errno = 0;
-
-	/* parse unsigned int string */
-	num = strtoul(q_arg, &end, 10);
-	if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0') || (errno != 0))
-		return -1;
-
-	if (num > max_valid_value)
-		return -1;
-
-	return num;
-
-}
-
-/*
- * Display usage
- */
-static void
-us_vhost_usage(const char *prgname)
-{
-	RTE_LOG(INFO, VHOST_CONFIG, "%s [EAL options] -- -p PORTMASK --vm2vm [0|1] --stats [0-N] --nb-devices ND\n"
-	"		-p PORTMASK: Set mask for ports to be used by application\n"
-	"		--vm2vm [0|1]: disable/enable(default) vm2vm comms\n"
-	"		--stats [0-N]: 0: Disable stats, N: Time in seconds to print stats\n",
-	       prgname);
-}
-
-/*
- * Parse the arguments given in the command line of the application.
- */
-static int
-us_vhost_parse_args(int argc, char **argv)
-{
-	int opt, ret;
-	int option_index;
-	unsigned i;
-	const char *prgname = argv[0];
-	static struct option long_option[] = {
-		{"vm2vm", required_argument, NULL, 0},
-		{"stats", required_argument, NULL, 0},
-		{NULL, 0, 0, 0}
-	};
-
-	/* Parse command line */
-	while ((opt = getopt_long(argc, argv, "p:",long_option, &option_index)) != EOF) {
-		switch (opt) {
-		/* Portmask */
-		case 'p':
-			enabled_port_mask = parse_portmask(optarg);
-			if (enabled_port_mask == 0) {
-				RTE_LOG(INFO, VHOST_CONFIG, "Invalid portmask\n");
-				us_vhost_usage(prgname);
-				return -1;
-			}
-			break;
-
-		case 0:
-			/* Enable/disable vm2vm comms. */
-			if (!strncmp(long_option[option_index].name, "vm2vm", MAX_LONG_OPT_SZ)) {
-				ret = parse_num_opt(optarg, 1);
-				if (ret == -1) {
-					RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for vm2vm [0|1]\n");
-					us_vhost_usage(prgname);
-					return -1;
-				} else {
-					enable_vm2vm = ret;
-				}
-			}
-
-			/* Enable/disable stats. */
-			if (!strncmp(long_option[option_index].name, "stats", MAX_LONG_OPT_SZ)) {
-				ret = parse_num_opt(optarg, INT32_MAX);
-				if (ret == -1) {
-					RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for stats [0..N]\n");
-					us_vhost_usage(prgname);
-					return -1;
-				} else {
-					enable_stats = ret;
-				}
-			}
-			break;
-
-			/* Invalid option - print options. */
-		default:
-			us_vhost_usage(prgname);
-			return -1;
-		}
-	}
-
-	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-		if (enabled_port_mask & (1 << i))
-			ports[num_ports++] = (uint8_t)i;
-	}
-
-	if ((num_ports ==  0) || (num_ports > MAX_SUP_PORTS)) {
-		RTE_LOG(INFO, VHOST_PORT, "Current enabled port number is %u,"
-			"but only %u port can be enabled\n",num_ports, MAX_SUP_PORTS);
-		return -1;
-	}
-
-	return 0;
-}
-
-/*
- * Update the global var NUM_PORTS and array PORTS according to system ports number
- * and return valid ports number
- */
-static unsigned check_ports_num(unsigned nb_ports)
-{
-	unsigned valid_num_ports = num_ports;
-	unsigned portid;
-
-	if (num_ports > nb_ports) {
-		RTE_LOG(INFO, VHOST_PORT, "\nSpecified port number(%u) exceeds total system port number(%u)\n",
-			num_ports, nb_ports);
-		num_ports = nb_ports;
-	}
-
-	for (portid = 0; portid < num_ports; portid ++) {
-		if (ports[portid] >= nb_ports) {
-			RTE_LOG(INFO, VHOST_PORT, "\nSpecified port ID(%u) exceeds max system port ID(%u)\n",
-				ports[portid], (nb_ports - 1));
-			ports[portid] = INVALID_PORT_ID;
-			valid_num_ports--;
-		}
-	}
-	return valid_num_ports;
-}
-
-/*
- * Function to convert guest physical addresses to vhost virtual addresses. This
- * is used to convert virtio buffer addresses.
- */
-static __rte_always_inline uint64_t
-gpa_to_vva(struct virtio_net *dev, uint64_t guest_pa)
-{
-	struct virtio_memory_regions *region;
-	uint32_t regionidx;
-	uint64_t vhost_va = 0;
-
-	for (regionidx = 0; regionidx < dev->mem->nregions; regionidx++) {
-		region = &dev->mem->regions[regionidx];
-		if ((guest_pa >= region->guest_phys_address) &&
-			(guest_pa <= region->guest_phys_address_end)) {
-			vhost_va = region->address_offset + guest_pa;
-			break;
-		}
-	}
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") GPA %p| VVA %p\n",
-		dev->device_fh, (void*)(uintptr_t)guest_pa, (void*)(uintptr_t)vhost_va);
-
-	return vhost_va;
-}
-
-/*
- * This function adds buffers to the virtio devices RX virtqueue. Buffers can
- * be received from the physical port or from another virtio device. A packet
- * count is returned to indicate the number of packets that were successfully
- * added to the RX queue.
- */
-static __rte_always_inline uint32_t
-virtio_dev_rx(struct virtio_net *dev, struct rte_mbuf **pkts, uint32_t count)
-{
-	struct vhost_virtqueue *vq;
-	struct vring_desc *desc;
-	struct rte_mbuf *buff;
-	/* The virtio_hdr is initialised to 0. */
-	struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0,0,0,0,0,0},0};
-	uint64_t buff_addr = 0;
-	uint64_t buff_hdr_addr = 0;
-	uint32_t head[MAX_PKT_BURST], packet_len = 0;
-	uint32_t head_idx, packet_success = 0;
-	uint16_t avail_idx, res_cur_idx;
-	uint16_t res_base_idx, res_end_idx;
-	uint16_t free_entries;
-	uint8_t success = 0;
-	void *userdata;
-
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") virtio_dev_rx()\n", dev->device_fh);
-	vq = dev->virtqueue_rx;
-	count = (count > MAX_PKT_BURST) ? MAX_PKT_BURST : count;
-	/* As many data cores may want access to available buffers, they need to be reserved. */
-	do {
-
-		res_base_idx = vq->last_used_idx_res;
-
-		avail_idx = *((volatile uint16_t *)&vq->avail->idx);
-
-		free_entries = (avail_idx - res_base_idx);
-
-		/*check that we have enough buffers*/
-		if (unlikely(count > free_entries))
-			count = free_entries;
-
-		if (count == 0)
-			return 0;
-
-		res_end_idx = res_base_idx + count;
-		/* vq->last_used_idx_res is atomically updated. */
-		success = rte_atomic16_cmpset(&vq->last_used_idx_res, res_base_idx,
-									res_end_idx);
-	} while (unlikely(success == 0));
-	res_cur_idx = res_base_idx;
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") Current Index %d| End Index %d\n",
-		dev->device_fh, res_cur_idx, res_end_idx);
-
-	/* Prefetch available ring to retrieve indexes. */
-	rte_prefetch0(&vq->avail->ring[res_cur_idx & (vq->size - 1)]);
-
-	/* Retrieve all of the head indexes first to avoid caching issues. */
-	for (head_idx = 0; head_idx < count; head_idx++)
-		head[head_idx] = vq->avail->ring[(res_cur_idx + head_idx) & (vq->size - 1)];
-
-	/*Prefetch descriptor index. */
-	rte_prefetch0(&vq->desc[head[packet_success]]);
-
-	while (res_cur_idx != res_end_idx) {
-		/* Get descriptor from available ring */
-		desc = &vq->desc[head[packet_success]];
-		/* Prefetch descriptor address. */
-		rte_prefetch0(desc);
-
-		buff = pkts[packet_success];
-
-		/* Convert from gpa to vva (guest physical addr -> vhost virtual addr) */
-		buff_addr = gpa_to_vva(dev, desc->addr);
-		/* Prefetch buffer address. */
-		rte_prefetch0((void*)(uintptr_t)buff_addr);
-
-		{
-			/* Copy virtio_hdr to packet and increment buffer address */
-			buff_hdr_addr = buff_addr;
-			packet_len = rte_pktmbuf_data_len(buff) + vq->vhost_hlen;
-
-			/*
-			 * If the descriptors are chained the header and data are placed in
-			 * separate buffers.
-			 */
-			if (desc->flags & VRING_DESC_F_NEXT) {
-				desc->len = vq->vhost_hlen;
-				desc = &vq->desc[desc->next];
-				/* Buffer address translation. */
-				buff_addr = gpa_to_vva(dev, desc->addr);
-				desc->len = rte_pktmbuf_data_len(buff);
-			} else {
-				buff_addr += vq->vhost_hlen;
-				desc->len = packet_len;
-			}
-		}
-
-		/* Update used ring with desc information */
-		vq->used->ring[res_cur_idx & (vq->size - 1)].id = head[packet_success];
-		vq->used->ring[res_cur_idx & (vq->size - 1)].len = packet_len;
-
-		/* Copy mbuf data to buffer */
-		userdata = rte_pktmbuf_mtod(buff, void *);
-		rte_memcpy((void *)(uintptr_t)buff_addr, userdata, rte_pktmbuf_data_len(buff));
-
-		res_cur_idx++;
-		packet_success++;
-
-		/* mergeable is disabled then a header is required per buffer. */
-		rte_memcpy((void *)(uintptr_t)buff_hdr_addr, (const void *)&virtio_hdr, vq->vhost_hlen);
-		if (res_cur_idx < res_end_idx) {
-			/* Prefetch descriptor index. */
-			rte_prefetch0(&vq->desc[head[packet_success]]);
-		}
-	}
-
-	rte_compiler_barrier();
-
-	/* Wait until it's our turn to add our buffer to the used ring. */
-	while (unlikely(vq->last_used_idx != res_base_idx))
-		rte_pause();
-
-	*(volatile uint16_t *)&vq->used->idx += count;
-
-	vq->last_used_idx = res_end_idx;
-
-	return count;
-}
-
-/*
- * Compares a packet destination MAC address to a device MAC address.
- */
-static __rte_always_inline int
-ether_addr_cmp(struct ether_addr *ea, struct ether_addr *eb)
-{
-	return ((*(uint64_t *)ea ^ *(uint64_t *)eb) & MAC_ADDR_CMP) == 0;
-}
-
-/*
- * This function registers mac along with a
- * vlan tag to a VMDQ.
- */
-static int
-link_vmdq(struct virtio_net *dev)
-{
-	int ret;
-	struct virtio_net_data_ll *dev_ll;
-
-	dev_ll = ll_root_used;
-
-	while (dev_ll != NULL) {
-		if ((dev != dev_ll->dev) && ether_addr_cmp(&dev->mac_address, &dev_ll->dev->mac_address)) {
-			RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") WARNING: This device is using an existing MAC address and has not been registered.\n", dev->device_fh);
-			return -1;
-		}
-		dev_ll = dev_ll->next;
-	}
-
-	/* vlan_tag currently uses the device_id. */
-	dev->vlan_tag = vlan_tags[dev->device_fh];
-	dev->vmdq_rx_q = dev->device_fh * (num_queues/num_devices);
-
-	/* Print out VMDQ registration info. */
-	RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") MAC_ADDRESS %02x:%02x:%02x:%02x:%02x:%02x and VLAN_TAG %d registered\n",
-		dev->device_fh,
-		dev->mac_address.addr_bytes[0], dev->mac_address.addr_bytes[1],
-		dev->mac_address.addr_bytes[2], dev->mac_address.addr_bytes[3],
-		dev->mac_address.addr_bytes[4], dev->mac_address.addr_bytes[5],
-		dev->vlan_tag);
-
-	/* Register the MAC address. */
-	ret = rte_eth_dev_mac_addr_add(ports[0], &dev->mac_address, (uint32_t)dev->device_fh);
-	if (ret) {
-		RTE_LOG(ERR, VHOST_DATA, "(%"PRIu64") Failed to add device MAC address to VMDQ\n",
-										dev->device_fh);
-		return -1;
-	}
-
-	/* Enable stripping of the vlan tag as we handle routing. */
-	rte_eth_dev_set_vlan_strip_on_queue(ports[0], dev->vmdq_rx_q, 1);
-
-	rte_compiler_barrier();
-	/* Set device as ready for RX. */
-	dev->ready = DEVICE_READY;
-
-	return 0;
-}
-
-/*
- * Removes MAC address and vlan tag from VMDQ. Ensures that nothing is adding buffers to the RX
- * queue before disabling RX on the device.
- */
-static inline void
-unlink_vmdq(struct virtio_net *dev)
-{
-	unsigned i = 0;
-	unsigned rx_count;
-	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
-
-	if (dev->ready == DEVICE_READY) {
-		/*clear MAC and VLAN settings*/
-		rte_eth_dev_mac_addr_remove(ports[0], &dev->mac_address);
-		for (i = 0; i < 6; i++)
-			dev->mac_address.addr_bytes[i] = 0;
-
-		dev->vlan_tag = 0;
-
-		/*Clear out the receive buffers*/
-		rx_count = rte_eth_rx_burst(ports[0],
-					(uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
-
-		while (rx_count) {
-			for (i = 0; i < rx_count; i++)
-				rte_pktmbuf_free(pkts_burst[i]);
-
-			rx_count = rte_eth_rx_burst(ports[0],
-					(uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
-		}
-
-		dev->ready = DEVICE_NOT_READY;
-	}
-}
-
-/*
- * Check if the packet destination MAC address is for a local device. If so then put
- * the packet on that devices RX queue. If not then return.
- */
-static __rte_always_inline unsigned
-virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m)
-{
-	struct virtio_net_data_ll *dev_ll;
-	struct ether_hdr *pkt_hdr;
-	uint64_t ret = 0;
-
-	pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
-
-	/*get the used devices list*/
-	dev_ll = ll_root_used;
-
-	while (dev_ll != NULL) {
-		if (likely(dev_ll->dev->ready == DEVICE_READY) && ether_addr_cmp(&(pkt_hdr->d_addr),
-				          &dev_ll->dev->mac_address)) {
-
-			/* Drop the packet if the TX packet is destined for the TX device. */
-			if (dev_ll->dev->device_fh == dev->device_fh) {
-				RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: "
-					"Source and destination MAC addresses are the same. "
-					"Dropping packet.\n",
-					dev_ll->dev->device_fh);
-				return 0;
-			}
-
-
-			RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: "
-				"MAC address is local\n", dev_ll->dev->device_fh);
-
-			if (dev_ll->dev->remove) {
-				/*drop the packet if the device is marked for removal*/
-				RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") "
-					"Device is marked for removal\n",
-					dev_ll->dev->device_fh);
-			} else {
-				/*send the packet to the local virtio device*/
-				ret = virtio_dev_rx(dev_ll->dev, &m, 1);
-				if (enable_stats) {
-					rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, 1);
-					rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret);
-					dev_statistics[dev->device_fh].tx_total++;
-					dev_statistics[dev->device_fh].tx += ret;
-				}
-			}
-
-			return 0;
-		}
-		dev_ll = dev_ll->next;
-	}
-
-	return -1;
-}
-
-/*
- * This function routes the TX packet to the correct interface. This may be a local device
- * or the physical port.
- */
-static __rte_always_inline void
-virtio_tx_route(struct virtio_net* dev, struct rte_mbuf *m, struct rte_mempool *mbuf_pool, uint16_t vlan_tag)
-{
-	struct mbuf_table *tx_q;
-	struct vlan_ethhdr *vlan_hdr;
-	struct rte_mbuf **m_table;
-	struct rte_mbuf *mbuf;
-	unsigned len, ret;
-	const uint16_t lcore_id = rte_lcore_id();
-
-	/*check if destination is local VM*/
-	if (enable_vm2vm && (virtio_tx_local(dev, m) == 0)) {
-		return;
-	}
-
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: "
-		"MAC address is external\n", dev->device_fh);
-
-	/*Add packet to the port tx queue*/
-	tx_q = &lcore_tx_queue[lcore_id];
-	len = tx_q->len;
-
-	/* Allocate an mbuf and populate the structure. */
-	mbuf = rte_pktmbuf_alloc(mbuf_pool);
-	if(!mbuf)
-		return;
-
-	mbuf->data_len = m->data_len + VLAN_HLEN;
-	mbuf->pkt_len = mbuf->data_len;
-
-	/* Copy ethernet header to mbuf. */
-	rte_memcpy(rte_pktmbuf_mtod(mbuf, void*),
-			rte_pktmbuf_mtod(m, const void*), ETH_HLEN);
-
-
-	/* Setup vlan header. Bytes need to be re-ordered for network with htons()*/
-	vlan_hdr = rte_pktmbuf_mtod(mbuf, struct vlan_ethhdr *);
-	vlan_hdr->h_vlan_encapsulated_proto = vlan_hdr->h_vlan_proto;
-	vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
-	vlan_hdr->h_vlan_TCI = htons(vlan_tag);
-
-	/* Copy the remaining packet contents to the mbuf. */
-	rte_memcpy(rte_pktmbuf_mtod_offset(mbuf, void *, VLAN_ETH_HLEN),
-		rte_pktmbuf_mtod_offset(m, const void *, ETH_HLEN),
-		(m->data_len - ETH_HLEN));
-	tx_q->m_table[len] = mbuf;
-	len++;
-	if (enable_stats) {
-		dev_statistics[dev->device_fh].tx_total++;
-		dev_statistics[dev->device_fh].tx++;
-	}
-
-	if (unlikely(len == MAX_PKT_BURST)) {
-		m_table = (struct rte_mbuf **)tx_q->m_table;
-		ret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id, m_table, (uint16_t) len);
-		/* Free any buffers not handled by TX and update the port stats. */
-		if (unlikely(ret < len)) {
-			do {
-				rte_pktmbuf_free(m_table[ret]);
-			} while (++ret < len);
-		}
-
-		len = 0;
-	}
-
-	tx_q->len = len;
-	return;
-}
-
-static __rte_always_inline void
-virtio_dev_tx(struct virtio_net* dev, struct rte_mempool *mbuf_pool)
-{
-	struct rte_mbuf m;
-	struct vhost_virtqueue *vq;
-	struct vring_desc *desc;
-	uint64_t buff_addr = 0;
-	uint32_t head[MAX_PKT_BURST];
-	uint32_t used_idx;
-	uint32_t i;
-	uint16_t free_entries, packet_success = 0;
-	uint16_t avail_idx;
-
-	vq = dev->virtqueue_tx;
-	avail_idx = *((volatile uint16_t *)&vq->avail->idx);
-
-	/* If there are no available buffers then return. */
-	if (vq->last_used_idx == avail_idx)
-		return;
-
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") virtio_dev_tx()\n",
-		dev->device_fh);
-
-	/* Prefetch available ring to retrieve head indexes. */
-	rte_prefetch0(&vq->avail->ring[vq->last_used_idx & (vq->size - 1)]);
-
-	/*get the number of free entries in the ring*/
-	free_entries = avail_idx - vq->last_used_idx;
-	free_entries = unlikely(free_entries < MAX_PKT_BURST) ? free_entries : MAX_PKT_BURST;
-
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") Buffers available %d\n",
-		dev->device_fh, free_entries);
-	/* Retrieve all of the head indexes first to avoid caching issues. */
-	for (i = 0; i < free_entries; i++)
-		head[i] = vq->avail->ring[(vq->last_used_idx + i) & (vq->size - 1)];
-
-	/* Prefetch descriptor index. */
-	rte_prefetch0(&vq->desc[head[packet_success]]);
-
-	while (packet_success < free_entries) {
-		desc = &vq->desc[head[packet_success]];
-		/* Prefetch descriptor address. */
-		rte_prefetch0(desc);
-
-		if (packet_success < (free_entries - 1)) {
-			/* Prefetch descriptor index. */
-			rte_prefetch0(&vq->desc[head[packet_success+1]]);
-		}
-
-		/* Update used index buffer information. */
-		used_idx = vq->last_used_idx & (vq->size - 1);
-		vq->used->ring[used_idx].id = head[packet_success];
-		vq->used->ring[used_idx].len = 0;
-
-		/* Discard first buffer as it is the virtio header */
-		desc = &vq->desc[desc->next];
-
-		/* Buffer address translation. */
-		buff_addr = gpa_to_vva(dev, desc->addr);
-		/* Prefetch buffer address. */
-		rte_prefetch0((void*)(uintptr_t)buff_addr);
-
-		/* Setup dummy mbuf. This is copied to a real mbuf if transmitted out the physical port. */
-		m.data_len = desc->len;
-		m.data_off = 0;
-		m.nb_segs = 1;
-
-		virtio_tx_route(dev, &m, mbuf_pool, 0);
-
-		vq->last_used_idx++;
-		packet_success++;
-	}
-
-	rte_compiler_barrier();
-	vq->used->idx += packet_success;
-	/* Kick guest if required. */
-}
-
-/*
- * This function is called by each data core. It handles all RX/TX registered with the
- * core. For TX the specific lcore linked list is used. For RX, MAC addresses are compared
- * with all devices in the main linked list.
- */
-static int
-switch_worker(__attribute__((unused)) void *arg)
-{
-	struct rte_mempool *mbuf_pool = arg;
-	struct virtio_net *dev = NULL;
-	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
-	struct virtio_net_data_ll *dev_ll;
-	struct mbuf_table *tx_q;
-	volatile struct lcore_ll_info *lcore_ll;
-	const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
-	uint64_t prev_tsc, diff_tsc, cur_tsc, ret_count = 0;
-	unsigned ret, i;
-	const uint16_t lcore_id = rte_lcore_id();
-	const uint16_t num_cores = (uint16_t)rte_lcore_count();
-	uint16_t rx_count = 0;
-
-	RTE_LOG(INFO, VHOST_DATA, "Procesing on Core %u started \n", lcore_id);
-	lcore_ll = lcore_info[lcore_id].lcore_ll;
-	prev_tsc = 0;
-
-	tx_q = &lcore_tx_queue[lcore_id];
-	for (i = 0; i < num_cores; i ++) {
-		if (lcore_ids[i] == lcore_id) {
-			tx_q->txq_id = i;
-			break;
-		}
-	}
-
-	while(1) {
-		cur_tsc = rte_rdtsc();
-		/*
-		 * TX burst queue drain
-		 */
-		diff_tsc = cur_tsc - prev_tsc;
-		if (unlikely(diff_tsc > drain_tsc)) {
-
-			if (tx_q->len) {
-				RTE_LOG_DP(DEBUG, VHOST_DATA,
-					"TX queue drained after timeout with burst size %u\n",
-					tx_q->len);
-
-				/*Tx any packets in the queue*/
-				ret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id,
-									   (struct rte_mbuf **)tx_q->m_table,
-									   (uint16_t)tx_q->len);
-				if (unlikely(ret < tx_q->len)) {
-					do {
-						rte_pktmbuf_free(tx_q->m_table[ret]);
-					} while (++ret < tx_q->len);
-				}
-
-				tx_q->len = 0;
-			}
-
-			prev_tsc = cur_tsc;
-
-		}
-
-		/*
-		 * Inform the configuration core that we have exited the linked list and that no devices are
-		 * in use if requested.
-		 */
-		if (lcore_ll->dev_removal_flag == REQUEST_DEV_REMOVAL)
-			lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;
-
-		/*
-		 * Process devices
-	 	 */
-		dev_ll = lcore_ll->ll_root_used;
-
-		while (dev_ll != NULL) {
-			/*get virtio device ID*/
-			dev = dev_ll->dev;
-
-			if (unlikely(dev->remove)) {
-				dev_ll = dev_ll->next;
-				unlink_vmdq(dev);
-				dev->ready = DEVICE_SAFE_REMOVE;
-				continue;
-			}
-			if (likely(dev->ready == DEVICE_READY)) {
-				/*Handle guest RX*/
-				rx_count = rte_eth_rx_burst(ports[0],
-					(uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
-
-				if (rx_count) {
-					ret_count = virtio_dev_rx(dev, pkts_burst, rx_count);
-					if (enable_stats) {
-						rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, rx_count);
-						rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret_count);
-					}
-					while (likely(rx_count)) {
-						rx_count--;
-						rte_pktmbuf_free_seg(pkts_burst[rx_count]);
-					}
-
-				}
-			}
-
-			if (likely(!dev->remove))
-				/*Handle guest TX*/
-				virtio_dev_tx(dev, mbuf_pool);
-
-			/*move to the next device in the list*/
-			dev_ll = dev_ll->next;
-		}
-	}
-
-	return 0;
-}
-
-/*
- * Add an entry to a used linked list. A free entry must first be found in the free linked list
- * using get_data_ll_free_entry();
- */
-static void
-add_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)
-{
-	struct virtio_net_data_ll *ll = *ll_root_addr;
-
-	/* Set next as NULL and use a compiler barrier to avoid reordering. */
-	ll_dev->next = NULL;
-	rte_compiler_barrier();
-
-	/* If ll == NULL then this is the first device. */
-	if (ll) {
-		/* Increment to the tail of the linked list. */
-		while ((ll->next != NULL) )
-			ll = ll->next;
-
-		ll->next = ll_dev;
-	} else {
-		*ll_root_addr = ll_dev;
-	}
-}
-
-/*
- * Remove an entry from a used linked list. The entry must then be added to the free linked list
- * using put_data_ll_free_entry().
- */
-static void
-rm_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev, struct virtio_net_data_ll *ll_dev_last)
-{
-	struct virtio_net_data_ll *ll = *ll_root_addr;
-
-	if (ll_dev == ll)
-		*ll_root_addr = ll_dev->next;
-	else
-		ll_dev_last->next = ll_dev->next;
-}
-
-/*
- * Find and return an entry from the free linked list.
- */
-static struct virtio_net_data_ll *
-get_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr)
-{
-	struct virtio_net_data_ll *ll_free = *ll_root_addr;
-	struct virtio_net_data_ll *ll_dev;
-
-	if (ll_free == NULL)
-		return NULL;
-
-	ll_dev = ll_free;
-	*ll_root_addr = ll_free->next;
-
-	return ll_dev;
-}
-
-/*
- * Place an entry back on to the free linked list.
- */
-static void
-put_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)
-{
-	struct virtio_net_data_ll *ll_free = *ll_root_addr;
-
-	ll_dev->next = ll_free;
-	*ll_root_addr = ll_dev;
-}
-
-/*
- * Creates a linked list of a given size.
- */
-static struct virtio_net_data_ll *
-alloc_data_ll(uint32_t size)
-{
-	struct virtio_net_data_ll *ll_new;
-	uint32_t i;
-
-	/* Malloc and then chain the linked list. */
-	ll_new = malloc(size * sizeof(struct virtio_net_data_ll));
-	if (ll_new == NULL) {
-		RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for ll_new.\n");
-		return NULL;
-	}
-
-	for (i = 0; i < size - 1; i++) {
-		ll_new[i].dev = NULL;
-		ll_new[i].next = &ll_new[i+1];
-	}
-	ll_new[i].next = NULL;
-
-	return ll_new;
-}
-
-/*
- * Create the main linked list along with each individual cores linked list. A used and a free list
- * are created to manage entries.
- */
-static int
-init_data_ll (void)
-{
-	int lcore;
-
-	RTE_LCORE_FOREACH_SLAVE(lcore) {
-		lcore_info[lcore].lcore_ll = malloc(sizeof(struct lcore_ll_info));
-		if (lcore_info[lcore].lcore_ll == NULL) {
-			RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for lcore_ll.\n");
-			return -1;
-		}
-
-		lcore_info[lcore].lcore_ll->device_num = 0;
-		lcore_info[lcore].lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;
-		lcore_info[lcore].lcore_ll->ll_root_used = NULL;
-		if (num_devices % num_switching_cores)
-			lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll((num_devices / num_switching_cores) + 1);
-		else
-			lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll(num_devices / num_switching_cores);
-	}
-
-	/* Allocate devices up to a maximum of MAX_DEVICES. */
-	ll_root_free = alloc_data_ll(MIN((num_devices), MAX_DEVICES));
-
-	return 0;
-}
-/*
- * Remove a device from the specific data core linked list and from the main linked list. The
- * rx/tx thread must be set the flag to indicate that it is safe to remove the device.
- * used.
- */
-static void
-destroy_device (volatile struct virtio_net *dev)
-{
-	struct virtio_net_data_ll *ll_lcore_dev_cur;
-	struct virtio_net_data_ll *ll_main_dev_cur;
-	struct virtio_net_data_ll *ll_lcore_dev_last = NULL;
-	struct virtio_net_data_ll *ll_main_dev_last = NULL;
-	int lcore;
-
-	dev->flags &= ~VIRTIO_DEV_RUNNING;
-
-	/*set the remove flag. */
-	dev->remove = 1;
-
-	while(dev->ready != DEVICE_SAFE_REMOVE) {
-		rte_pause();
-	}
-
-	/* Search for entry to be removed from lcore ll */
-	ll_lcore_dev_cur = lcore_info[dev->coreid].lcore_ll->ll_root_used;
-	while (ll_lcore_dev_cur != NULL) {
-		if (ll_lcore_dev_cur->dev == dev) {
-			break;
-		} else {
-			ll_lcore_dev_last = ll_lcore_dev_cur;
-			ll_lcore_dev_cur = ll_lcore_dev_cur->next;
-		}
-	}
-
-	/* Search for entry to be removed from main ll */
-	ll_main_dev_cur = ll_root_used;
-	ll_main_dev_last = NULL;
-	while (ll_main_dev_cur != NULL) {
-		if (ll_main_dev_cur->dev == dev) {
-			break;
-		} else {
-			ll_main_dev_last = ll_main_dev_cur;
-			ll_main_dev_cur = ll_main_dev_cur->next;
-		}
-	}
-
-	if (ll_lcore_dev_cur == NULL || ll_main_dev_cur == NULL) {
-		RTE_LOG(ERR, XENHOST, "%s: could find device in per_cpu list or main_list\n", __func__);
-		return;
-	}
-
-	/* Remove entries from the lcore and main ll. */
-	rm_data_ll_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_used, ll_lcore_dev_cur, ll_lcore_dev_last);
-	rm_data_ll_entry(&ll_root_used, ll_main_dev_cur, ll_main_dev_last);
-
-	/* Set the dev_removal_flag on each lcore. */
-	RTE_LCORE_FOREACH_SLAVE(lcore) {
-		lcore_info[lcore].lcore_ll->dev_removal_flag = REQUEST_DEV_REMOVAL;
-	}
-
-	/*
-	 * Once each core has set the dev_removal_flag to ACK_DEV_REMOVAL we can be sure that
-	 * they can no longer access the device removed from the linked lists and that the devices
-	 * are no longer in use.
-	 */
-	RTE_LCORE_FOREACH_SLAVE(lcore) {
-		while (lcore_info[lcore].lcore_ll->dev_removal_flag != ACK_DEV_REMOVAL) {
-			rte_pause();
-		}
-	}
-
-	/* Add the entries back to the lcore and main free ll.*/
-	put_data_ll_free_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_free, ll_lcore_dev_cur);
-	put_data_ll_free_entry(&ll_root_free, ll_main_dev_cur);
-
-	/* Decrement number of device on the lcore. */
-	lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->device_num--;
-
-	RTE_LOG(INFO, VHOST_DATA, "  #####(%"PRIu64") Device has been removed from data core\n", dev->device_fh);
-}
-
-/*
- * A new device is added to a data core. First the device is added to the main linked list
- * and the allocated to a specific data core.
- */
-static int
-new_device (struct virtio_net *dev)
-{
-	struct virtio_net_data_ll *ll_dev;
-	int lcore, core_add = 0;
-	uint32_t device_num_min = num_devices;
-
-	/* Add device to main ll */
-	ll_dev = get_data_ll_free_entry(&ll_root_free);
-	if (ll_dev == NULL) {
-		RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") No free entry found in linked list. Device limit "
-			"of %d devices per core has been reached\n",
-			dev->device_fh, num_devices);
-		return -1;
-	}
-	ll_dev->dev = dev;
-	add_data_ll_entry(&ll_root_used, ll_dev);
-
-	/*reset ready flag*/
-	dev->ready = DEVICE_NOT_READY;
-	dev->remove = 0;
-
-	/* Find a suitable lcore to add the device. */
-	RTE_LCORE_FOREACH_SLAVE(lcore) {
-		if (lcore_info[lcore].lcore_ll->device_num < device_num_min) {
-			device_num_min = lcore_info[lcore].lcore_ll->device_num;
-			core_add = lcore;
-		}
-	}
-	/* Add device to lcore ll */
-	ll_dev->dev->coreid = core_add;
-	ll_dev = get_data_ll_free_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_free);
-	if (ll_dev == NULL) {
-		RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Failed to add device to data core\n", dev->device_fh);
-		destroy_device(dev);
-		return -1;
-	}
-	ll_dev->dev = dev;
-	add_data_ll_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_used, ll_dev);
-
-	/* Initialize device stats */
-	memset(&dev_statistics[dev->device_fh], 0, sizeof(struct device_statistics));
-
-	lcore_info[ll_dev->dev->coreid].lcore_ll->device_num++;
-	dev->flags |= VIRTIO_DEV_RUNNING;
-
-	RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Device has been added to data core %d\n", dev->device_fh, dev->coreid);
-
-	link_vmdq(dev);
-
-	return 0;
-}
-
-/*
- * These callback allow devices to be added to the data core when configuration
- * has been fully complete.
- */
-static const struct virtio_net_device_ops virtio_net_device_ops =
-{
-	.new_device =  new_device,
-	.destroy_device = destroy_device,
-};
-
-/*
- * This is a thread will wake up after a period to print stats if the user has
- * enabled them.
- */
-static void
-print_stats(void)
-{
-	struct virtio_net_data_ll *dev_ll;
-	uint64_t tx_dropped, rx_dropped;
-	uint64_t tx, tx_total, rx, rx_total;
-	uint32_t device_fh;
-	const char clr[] = { 27, '[', '2', 'J', '\0' };
-	const char top_left[] = { 27, '[', '1', ';', '1', 'H','\0' };
-
-	while(1) {
-		sleep(enable_stats);
-
-		/* Clear screen and move to top left */
-		printf("%s%s", clr, top_left);
-
-		printf("\nDevice statistics ====================================");
-
-		dev_ll = ll_root_used;
-		while (dev_ll != NULL) {
-			device_fh = (uint32_t)dev_ll->dev->device_fh;
-			tx_total = dev_statistics[device_fh].tx_total;
-			tx = dev_statistics[device_fh].tx;
-			tx_dropped = tx_total - tx;
-			rx_total = rte_atomic64_read(&dev_statistics[device_fh].rx_total);
-			rx = rte_atomic64_read(&dev_statistics[device_fh].rx);
-			rx_dropped = rx_total - rx;
-
-			printf("\nStatistics for device %"PRIu32" ------------------------------"
-					"\nTX total: 		%"PRIu64""
-					"\nTX dropped: 		%"PRIu64""
-					"\nTX successful: 		%"PRIu64""
-					"\nRX total: 		%"PRIu64""
-					"\nRX dropped: 		%"PRIu64""
-					"\nRX successful: 		%"PRIu64"",
-					device_fh,
-					tx_total,
-					tx_dropped,
-					tx,
-					rx_total,
-					rx_dropped,
-					rx);
-
-			dev_ll = dev_ll->next;
-		}
-		printf("\n======================================================\n");
-	}
-}
-
-
-int init_virtio_net(struct virtio_net_device_ops const * const ops);
-
-/*
- * Main function, does initialisation and calls the per-lcore functions.
- */
-int
-main(int argc, char *argv[])
-{
-	struct rte_mempool *mbuf_pool;
-	unsigned lcore_id, core_id = 0;
-	unsigned nb_ports, valid_num_ports;
-	int ret;
-	uint8_t portid;
-	static pthread_t tid;
-	char thread_name[RTE_MAX_THREAD_NAME_LEN];
-
-	/* init EAL */
-	ret = rte_eal_init(argc, argv);
-	if (ret < 0)
-		rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
-	argc -= ret;
-	argv += ret;
-
-	/* parse app arguments */
-	ret = us_vhost_parse_args(argc, argv);
-	if (ret < 0)
-		rte_exit(EXIT_FAILURE, "Invalid argument\n");
-
-	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++)
-		if (rte_lcore_is_enabled(lcore_id))
-			lcore_ids[core_id ++] = lcore_id;
-
-	if (rte_lcore_count() > RTE_MAX_LCORE)
-		rte_exit(EXIT_FAILURE,"Not enough cores\n");
-
-	/*set the number of swithcing cores available*/
-	num_switching_cores = rte_lcore_count()-1;
-
-	/* Get the number of physical ports. */
-	nb_ports = rte_eth_dev_count();
-
-	/*
-	 * Update the global var NUM_PORTS and global array PORTS
-	 * and get value of var VALID_NUM_PORTS according to system ports number
-	 */
-	valid_num_ports = check_ports_num(nb_ports);
-
-	if ((valid_num_ports ==  0) || (valid_num_ports > MAX_SUP_PORTS)) {
-		RTE_LOG(INFO, VHOST_PORT, "Current enabled port number is %u,"
-			"but only %u port can be enabled\n",num_ports, MAX_SUP_PORTS);
-		return -1;
-	}
-
-	/* Create the mbuf pool. */
-	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
-		NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE, 0,
-		RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
-	if (mbuf_pool == NULL)
-		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
-
-	/* initialize all ports */
-	for (portid = 0; portid < nb_ports; portid++) {
-		/* skip ports that are not enabled */
-		if ((enabled_port_mask & (1 << portid)) == 0) {
-			RTE_LOG(INFO, VHOST_PORT, "Skipping disabled port %d\n", portid);
-			continue;
-		}
-		if (port_init(portid, mbuf_pool) != 0)
-			rte_exit(EXIT_FAILURE, "Cannot initialize network ports\n");
-	}
-
-	/* Initialise all linked lists. */
-	if (init_data_ll() == -1)
-		rte_exit(EXIT_FAILURE, "Failed to initialize linked list\n");
-
-	/* Initialize device stats */
-	memset(&dev_statistics, 0, sizeof(dev_statistics));
-
-	/* Enable stats if the user option is set. */
-	if (enable_stats) {
-		ret = pthread_create(&tid, NULL, (void *)print_stats, NULL);
-		if (ret != 0)
-			rte_exit(EXIT_FAILURE,
-				"Cannot create print-stats thread\n");
-
-		/* Set thread_name for aid in debugging. */
-		snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "print-xen-stats");
-		ret = rte_thread_setname(tid, thread_name);
-		if (ret != 0)
-			RTE_LOG(DEBUG, VHOST_CONFIG,
-				"Cannot set print-stats name\n");
-	}
-
-	/* Launch all data cores. */
-	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
-		rte_eal_remote_launch(switch_worker, mbuf_pool, lcore_id);
-	}
-
-	init_virtio_xen(&virtio_net_device_ops);
-
-	virtio_monitor_loop();
-	return 0;
-}
diff --git a/examples/vhost_xen/main.h b/examples/vhost_xen/main.h
deleted file mode 100644
index 5ff48fd..0000000
--- a/examples/vhost_xen/main.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-/* Macros for printing using RTE_LOG */
-#define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
-#define RTE_LOGTYPE_VHOST_DATA   RTE_LOGTYPE_USER2
-#define RTE_LOGTYPE_VHOST_PORT   RTE_LOGTYPE_USER3
-
-/*
- * Device linked list structure for data path.
- */
-struct virtio_net_data_ll
-{
-	struct virtio_net          *dev;   /* Pointer to device created by configuration core. */
-	struct virtio_net_data_ll  *next;  /* Pointer to next device in linked list. */
-};
-
-/*
- * Structure containing data core specific information.
- */
-struct lcore_ll_info
-{
-	struct virtio_net_data_ll    *ll_root_free; 	/* Pointer to head in free linked list. */
-	struct virtio_net_data_ll    *ll_root_used;	    /* Pointer to head of used linked list. */
-	uint32_t                      device_num;       /* Number of devices on lcore. */
-	volatile  uint8_t             dev_removal_flag; /* Flag to synchronize device removal. */
-};
-
-struct lcore_info
-{
-	struct lcore_ll_info	*lcore_ll;	/* Pointer to data core specific lcore_ll_info struct */
-};
-#endif /* _MAIN_H_ */
diff --git a/examples/vhost_xen/vhost_monitor.c b/examples/vhost_xen/vhost_monitor.c
deleted file mode 100644
index fb9606b..0000000
--- a/examples/vhost_xen/vhost_monitor.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <sys/eventfd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-#include <linux/virtio_ring.h>
-#include <linux/virtio_pci.h>
-#include <linux/virtio_net.h>
-
-#include <rte_ethdev.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-
-#include "virtio-net.h"
-#include "xen_vhost.h"
-
-struct virtio_watch {
-	struct xs_handle *xs;
-	int watch_fd;
-};
-
-
-/* device ops to add/remove device to/from data core. */
-static struct virtio_net_device_ops const *notify_ops;
-
-/* root address of the linked list in the configuration core. */
-static struct virtio_net_config_ll *ll_root = NULL;
-
-/* root address of VM. */
-static struct xen_guestlist guest_root;
-
-static struct virtio_watch watch;
-
-static void
-vq_vring_init(struct vhost_virtqueue *vq, unsigned int num, uint8_t *p,
-	unsigned long align)
-{
-	vq->size = num;
-	vq->desc = (struct vring_desc *) p;
-	vq->avail = (struct vring_avail *) (p +
-		num * sizeof(struct vring_desc));
-	vq->used = (void *)
-		RTE_ALIGN_CEIL( (uintptr_t)(&vq->avail->ring[num]), align);
-
-}
-
-static int
-init_watch(void)
-{
-	struct xs_handle *xs;
-	int ret;
-	int fd;
-
-	/* get a connection to the daemon */
-	xs = xs_daemon_open();
-	if (xs == NULL) {
-		RTE_LOG(ERR, XENHOST, "xs_daemon_open failed\n");
-		return -1;
-	}
-
-	ret = xs_watch(xs, "/local/domain", "mytoken");
-	if (ret == 0) {
-		RTE_LOG(ERR, XENHOST, "%s: xs_watch failed\n", __func__);
-		xs_daemon_close(xs);
-		return -1;
-	}
-
-	/* We are notified of read availability on the watch via the file descriptor. */
-	fd = xs_fileno(xs);
-	watch.xs = xs;
-	watch.watch_fd = fd;
-
-	TAILQ_INIT(&guest_root);
-	return 0;
-}
-
-static struct xen_guest *
-get_xen_guest(int dom_id)
-{
-	struct xen_guest *guest = NULL;
-
-	TAILQ_FOREACH(guest, &guest_root, next) {
-		if(guest->dom_id == dom_id)
-			return guest;
-	}
-
-	return NULL;
-}
-
-
-static struct xen_guest *
-add_xen_guest(int32_t dom_id)
-{
-	struct xen_guest *guest = NULL;
-
-	if ((guest = get_xen_guest(dom_id)) != NULL)
-		return guest;
-
-	guest = calloc(1, sizeof(struct xen_guest));
-	if (guest) {
-		RTE_LOG(ERR, XENHOST, "  %s: return newly created guest with %d rings\n", __func__, guest->vring_num);
-		TAILQ_INSERT_TAIL(&guest_root, guest, next);
-		guest->dom_id = dom_id;
-	}
-
-	return guest;
-}
-
-static void
-cleanup_device(struct virtio_net_config_ll *ll_dev)
-{
-	if (ll_dev == NULL)
-		return;
-	if (ll_dev->dev.virtqueue_rx) {
-		rte_free(ll_dev->dev.virtqueue_rx);
-		ll_dev->dev.virtqueue_rx = NULL;
-	}
-	if (ll_dev->dev.virtqueue_tx) {
-		rte_free(ll_dev->dev.virtqueue_tx);
-		ll_dev->dev.virtqueue_tx = NULL;
-	}
-	free(ll_dev);
-}
-
-/*
- * Add entry containing a device to the device configuration linked list.
- */
-static void
-add_config_ll_entry(struct virtio_net_config_ll *new_ll_dev)
-{
-	struct virtio_net_config_ll *ll_dev = ll_root;
-
-	/* If ll_dev == NULL then this is the first device so go to else */
-	if (ll_dev) {
-		/* If the 1st device_id != 0 then we insert our device here. */
-		if (ll_dev->dev.device_fh != 0)	{
-			new_ll_dev->dev.device_fh = 0;
-			new_ll_dev->next = ll_dev;
-			ll_root = new_ll_dev;
-		} else {
-			/* increment through the ll until we find un unused device_id,
-			 * insert the device at that entry
-			 */
-			while ((ll_dev->next != NULL) && (ll_dev->dev.device_fh == (ll_dev->next->dev.device_fh - 1)))
-				ll_dev = ll_dev->next;
-
-			new_ll_dev->dev.device_fh = ll_dev->dev.device_fh + 1;
-			new_ll_dev->next = ll_dev->next;
-			ll_dev->next = new_ll_dev;
-		}
-	} else {
-		ll_root = new_ll_dev;
-		ll_root->dev.device_fh = 0;
-	}
-}
-
-
-/*
- * Remove an entry from the device configuration linked list.
- */
-static struct virtio_net_config_ll *
-rm_config_ll_entry(struct virtio_net_config_ll *ll_dev, struct virtio_net_config_ll *ll_dev_last)
-{
-	/* First remove the device and then clean it up. */
-	if (ll_dev == ll_root) {
-		ll_root = ll_dev->next;
-		cleanup_device(ll_dev);
-		return ll_root;
-	} else {
-		ll_dev_last->next = ll_dev->next;
-		cleanup_device(ll_dev);
-		return ll_dev_last->next;
-	}
-}
-
-/*
- * Retrieves an entry from the devices configuration linked list.
- */
-static struct virtio_net_config_ll *
-get_config_ll_entry(unsigned int virtio_idx, unsigned int dom_id)
-{
-	struct virtio_net_config_ll *ll_dev = ll_root;
-
-	/* Loop through linked list until the dom_id is found. */
-	while (ll_dev != NULL) {
-		if (ll_dev->dev.dom_id == dom_id && ll_dev->dev.virtio_idx == virtio_idx)
-			return ll_dev;
-		ll_dev = ll_dev->next;
-	}
-
-	return NULL;
-}
-
-/*
- * Initialise all variables in device structure.
- */
-static void
-init_dev(struct virtio_net *dev)
-{
-	RTE_SET_USED(dev);
-}
-
-
-static struct
-virtio_net_config_ll *new_device(unsigned int virtio_idx, struct xen_guest *guest)
-{
-	struct virtio_net_config_ll *new_ll_dev;
-	struct vhost_virtqueue *virtqueue_rx, *virtqueue_tx;
-	size_t size, vq_ring_size, vq_size = VQ_DESC_NUM;
-	void *vq_ring_virt_mem;
-	uint64_t gpa;
-	uint32_t i;
-
-	/* Setup device and virtqueues. */
-	new_ll_dev   = calloc(1, sizeof(struct virtio_net_config_ll));
-	virtqueue_rx = rte_zmalloc(NULL, sizeof(struct vhost_virtqueue), RTE_CACHE_LINE_SIZE);
-	virtqueue_tx = rte_zmalloc(NULL, sizeof(struct vhost_virtqueue), RTE_CACHE_LINE_SIZE);
-	if (new_ll_dev == NULL || virtqueue_rx == NULL || virtqueue_tx == NULL)
-		goto err;
-
-	new_ll_dev->dev.virtqueue_rx = virtqueue_rx;
-	new_ll_dev->dev.virtqueue_tx = virtqueue_tx;
-	new_ll_dev->dev.dom_id       = guest->dom_id;
-	new_ll_dev->dev.virtio_idx   = virtio_idx;
-	/* Initialise device and virtqueues. */
-	init_dev(&new_ll_dev->dev);
-
-	size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN);
-	vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
-	(void)vq_ring_size;
-
-	vq_ring_virt_mem = guest->vring[virtio_idx].rxvring_addr;
-	vq_vring_init(virtqueue_rx, vq_size, vq_ring_virt_mem, VIRTIO_PCI_VRING_ALIGN);
-	virtqueue_rx->size = vq_size;
-	virtqueue_rx->vhost_hlen = sizeof(struct virtio_net_hdr);
-
-	vq_ring_virt_mem = guest->vring[virtio_idx].txvring_addr;
-	vq_vring_init(virtqueue_tx, vq_size, vq_ring_virt_mem, VIRTIO_PCI_VRING_ALIGN);
-	virtqueue_tx->size = vq_size;
-	memcpy(&new_ll_dev->dev.mac_address, &guest->vring[virtio_idx].addr, sizeof(struct ether_addr));
-
-	/* virtio_memory has to be one per domid */
-	new_ll_dev->dev.mem = malloc(sizeof(struct virtio_memory) + sizeof(struct virtio_memory_regions) * MAX_XENVIRT_MEMPOOL);
-	new_ll_dev->dev.mem->nregions = guest->pool_num;
-	for (i = 0; i < guest->pool_num; i++) {
-		gpa = new_ll_dev->dev.mem->regions[i].guest_phys_address =
-				(uint64_t)((uintptr_t)guest->mempool[i].gva);
-		new_ll_dev->dev.mem->regions[i].guest_phys_address_end =
-				gpa + guest->mempool[i].mempfn_num * getpagesize();
-		new_ll_dev->dev.mem->regions[i].address_offset =
-				(uint64_t)((uintptr_t)guest->mempool[i].hva -
-					(uintptr_t)gpa);
-	}
-
-	new_ll_dev->next = NULL;
-
-	/* Add entry to device configuration linked list. */
-	add_config_ll_entry(new_ll_dev);
-	return new_ll_dev;
-err:
-	free(new_ll_dev);
-	rte_free(virtqueue_rx);
-	rte_free(virtqueue_tx);
-
-	return NULL;
-}
-
-static void
-destroy_guest(struct xen_guest *guest)
-{
-	uint32_t i;
-
-	for (i = 0; i < guest->vring_num; i++)
-		cleanup_vring(&guest->vring[i]);
-	/* clean mempool */
-	for (i = 0; i < guest->pool_num; i++)
-		cleanup_mempool(&guest->mempool[i]);
-	free(guest);
-
-	return;
-}
-
-/*
- * This function will cleanup the device and remove it from device configuration linked list.
- */
-static void
-destroy_device(unsigned int virtio_idx, unsigned int dom_id)
-{
-	struct virtio_net_config_ll *ll_dev_cur_ctx, *ll_dev_last = NULL;
-	struct virtio_net_config_ll *ll_dev_cur = ll_root;
-
-	/* clean virtio device */
-	struct xen_guest *guest = NULL;
-	guest = get_xen_guest(dom_id);
-	if (guest == NULL)
-		return;
-
-	/* Find the linked list entry for the device to be removed. */
-	ll_dev_cur_ctx = get_config_ll_entry(virtio_idx, dom_id);
-	while (ll_dev_cur != NULL) {
-		/* If the device is found or a device that doesn't exist is found then it is removed. */
-		if  (ll_dev_cur == ll_dev_cur_ctx) {
-			if ((ll_dev_cur->dev.flags & VIRTIO_DEV_RUNNING))
-				notify_ops->destroy_device(&(ll_dev_cur->dev));
-			ll_dev_cur = rm_config_ll_entry(ll_dev_cur, ll_dev_last);
-		} else {
-			ll_dev_last = ll_dev_cur;
-			ll_dev_cur = ll_dev_cur->next;
-		}
-	}
-	RTE_LOG(INFO, XENHOST, "  %s guest:%p vring:%p rxvring:%p txvring:%p flag:%p\n",
-		__func__, guest, &guest->vring[virtio_idx], guest->vring[virtio_idx].rxvring_addr, guest->vring[virtio_idx].txvring_addr, guest->vring[virtio_idx].flag);
-	cleanup_vring(&guest->vring[virtio_idx]);
-	guest->vring[virtio_idx].removed = 1;
-	guest->vring_num -= 1;
-}
-
-
-
-
-static void
-watch_unmap_event(void)
-{
-	int i;
-	struct xen_guest *guest  = NULL;
-	bool remove_request;
-
-	TAILQ_FOREACH(guest, &guest_root, next) {
-		for (i = 0; i < MAX_VIRTIO; i++) {
-			if (guest->vring[i].dom_id && guest->vring[i].removed == 0 && *guest->vring[i].flag == 0) {
-				RTE_LOG(INFO, XENHOST, "\n\n");
-				RTE_LOG(INFO, XENHOST, "  #####%s:  (%d, %d) to be removed\n",
-					__func__,
-					guest->vring[i].dom_id,
-					i);
-				destroy_device(i, guest->dom_id);
-				RTE_LOG(INFO, XENHOST, "  %s: DOM %u, vring num: %d\n",
-					__func__,
-					guest->dom_id,
-					guest->vring_num);
-			}
-		}
-	}
-
-_find_next_remove:
-	guest = NULL;
-	remove_request = false;
-	TAILQ_FOREACH(guest, &guest_root, next) {
-		if (guest->vring_num == 0) {
-			remove_request = true;
-			break;
-		}
-	}
-	if (remove_request == true) {
-		TAILQ_REMOVE(&guest_root, guest, next);
-		RTE_LOG(INFO, XENHOST, "  #####%s: destroy guest (%d)\n", __func__, guest->dom_id);
-		destroy_guest(guest);
-		goto _find_next_remove;
-	}
-	return;
-}
-
-/*
- * OK, if the guest starts first, it is ok.
- * if host starts first, it is ok.
- * if guest starts, and has run for sometime, and host stops and restarts,
- * then last_used_idx  0? how to solve this. */
-
-static void virtio_init(void)
-{
-	uint32_t len, e_num;
-	uint32_t i,j;
-	char **dom;
-	char *status;
-	int dom_id;
-	char path[PATH_MAX];
-	char node[PATH_MAX];
-	xs_transaction_t th;
-	struct xen_guest *guest;
-	struct virtio_net_config_ll *net_config;
-	char *end;
-	int val;
-
-	/* init env for watch the node */
-	if (init_watch() < 0)
-		return;
-
-	dom = xs_directory(watch.xs, XBT_NULL, "/local/domain", &e_num);
-
-	for (i = 0; i < e_num; i++) {
-		errno = 0;
-		dom_id = strtol(dom[i], &end, 0);
-		if (errno != 0 || end == NULL || dom_id == 0)
-			continue;
-
-		for (j = 0; j < RTE_MAX_ETHPORTS; j++) {
-			snprintf(node, PATH_MAX, "%s%d", VIRTIO_START, j);
-			snprintf(path, PATH_MAX, XEN_VM_NODE_FMT,
-					dom_id, node);
-
-			th = xs_transaction_start(watch.xs);
-			status = xs_read(watch.xs, th, path, &len);
-			xs_transaction_end(watch.xs, th, false);
-
-			if (status == NULL)
-				break;
-
-			/* if there's any valid virtio device */
-			errno = 0;
-			val = strtol(status, &end, 0);
-			if (errno != 0 || end == NULL || dom_id == 0)
-				val = 0;
-			if (val == 1) {
-				guest = add_xen_guest(dom_id);
-				if (guest == NULL)
-					continue;
-				RTE_LOG(INFO, XENHOST, "  there's a new virtio existed, new a virtio device\n\n");
-
-				RTE_LOG(INFO, XENHOST, "  parse_vringnode dom_id %d virtioidx %d\n",dom_id,j);
-				if (parse_vringnode(guest, j)) {
-					RTE_LOG(ERR, XENHOST, "  there is invalid information in xenstore\n");
-					TAILQ_REMOVE(&guest_root, guest, next);
-					destroy_guest(guest);
-
-					continue;
-				}
-
-				/*if pool_num > 0, then mempool has already been parsed*/
-				if (guest->pool_num == 0 && parse_mempoolnode(guest)) {
-					RTE_LOG(ERR, XENHOST, "  there is error information in xenstore\n");
-					TAILQ_REMOVE(&guest_root, guest, next);
-					destroy_guest(guest);
-					continue;
-				}
-
-				net_config = new_device(j, guest);
-				/* every thing is ready now, added into data core */
-				notify_ops->new_device(&net_config->dev);
-			}
-		}
-	}
-
-	free(dom);
-	return;
-}
-
-void
-virtio_monitor_loop(void)
-{
-	char **vec;
-	xs_transaction_t th;
-	char *buf;
-	unsigned int len;
-	unsigned int dom_id;
-	uint32_t virtio_idx;
-	struct xen_guest *guest;
-	struct virtio_net_config_ll *net_config;
-	enum fieldnames {
-		FLD_NULL = 0,
-		FLD_LOCAL,
-		FLD_DOMAIN,
-		FLD_ID,
-		FLD_CONTROL,
-		FLD_DPDK,
-		FLD_NODE,
-		_NUM_FLD
-	};
-	char *str_fld[_NUM_FLD];
-	char *str;
-	char *end;
-
-	virtio_init();
-	while (1) {
-		watch_unmap_event();
-
-		usleep(50);
-		vec = xs_check_watch(watch.xs);
-
-		if (vec == NULL)
-			continue;
-
-		th = xs_transaction_start(watch.xs);
-
-		buf = xs_read(watch.xs, th, vec[XS_WATCH_PATH],&len);
-		xs_transaction_end(watch.xs, th, false);
-
-		if (buf) {
-			/* theres' some node for vhost existed */
-			if (rte_strsplit(vec[XS_WATCH_PATH], strnlen(vec[XS_WATCH_PATH], PATH_MAX),
-						str_fld, _NUM_FLD, '/') == _NUM_FLD) {
-				if (strstr(str_fld[FLD_NODE], VIRTIO_START)) {
-					errno = 0;
-					str = str_fld[FLD_ID];
-					dom_id = strtoul(str, &end, 0);
-					if (errno != 0 || end == NULL || end == str ) {
-						RTE_LOG(INFO, XENHOST, "invalid domain id\n");
-						continue;
-					}
-
-					errno = 0;
-					str = str_fld[FLD_NODE] + sizeof(VIRTIO_START) - 1;
-					virtio_idx = strtoul(str, &end, 0);
-					if (errno != 0 || end == NULL || end == str
-							|| virtio_idx > MAX_VIRTIO) {
-						RTE_LOG(INFO, XENHOST, "invalid virtio idx\n");
-						continue;
-					}
-					RTE_LOG(INFO, XENHOST, "  #####virtio dev (%d, %d) is started\n", dom_id, virtio_idx);
-
-					guest = add_xen_guest(dom_id);
-					if (guest == NULL)
-						continue;
-					guest->dom_id = dom_id;
-					if (parse_vringnode(guest, virtio_idx)) {
-						RTE_LOG(ERR, XENHOST, "  there is invalid information in xenstore\n");
-						/*guest newly created? guest existed ?*/
-						TAILQ_REMOVE(&guest_root, guest, next);
-						destroy_guest(guest);
-						continue;
-					}
-					/*if pool_num > 0, then mempool has already been parsed*/
-					if (guest->pool_num == 0 && parse_mempoolnode(guest)) {
-						RTE_LOG(ERR, XENHOST, "  there is error information in xenstore\n");
-						TAILQ_REMOVE(&guest_root, guest, next);
-						destroy_guest(guest);
-						continue;
-					}
-
-
-					net_config = new_device(virtio_idx, guest);
-					RTE_LOG(INFO, XENHOST, "  Add to dataplane core\n");
-					notify_ops->new_device(&net_config->dev);
-
-				}
-			}
-		}
-
-		free(vec);
-	}
-	return;
-}
-
-/*
- * Register ops so that we can add/remove device to data core.
- */
-int
-init_virtio_xen(struct virtio_net_device_ops const *const ops)
-{
-	notify_ops = ops;
-	if (xenhost_init())
-		return -1;
-	return 0;
-}
diff --git a/examples/vhost_xen/virtio-net.h b/examples/vhost_xen/virtio-net.h
deleted file mode 100644
index ab69726..0000000
--- a/examples/vhost_xen/virtio-net.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VIRTIO_NET_H_
-#define _VIRTIO_NET_H_
-
-#include <stdint.h>
-
-#define VQ_DESC_NUM 256
-/* Used to indicate that the device is running on a data core */
-#define VIRTIO_DEV_RUNNING 1
-
-/*
- * Structure contains variables relevant to TX/RX virtqueues.
- */
-struct vhost_virtqueue
-{
-	struct vring_desc  *desc;             /* Virtqueue descriptor ring. */
-	struct vring_avail *avail;            /* Virtqueue available ring. */
-	struct vring_used  *used;             /* Virtqueue used ring. */
-	uint32_t           size;              /* Size of descriptor ring. */
-	uint32_t           vhost_hlen;        /* Vhost header length (varies depending on RX merge buffers. */
-	volatile uint16_t  last_used_idx;     /* Last index used on the available ring */
-	volatile uint16_t  last_used_idx_res; /* Used for multiple devices reserving buffers. */
-} __rte_cache_aligned;
-
-/*
- * Device structure contains all configuration information relating to the device.
- */
-struct virtio_net
-{
-	struct vhost_virtqueue	*virtqueue_tx;	/* Contains all TX virtqueue information. */
-	struct vhost_virtqueue	*virtqueue_rx;	/* Contains all RX virtqueue information. */
-	struct virtio_memory    *mem;           /* QEMU memory and memory region information. */
-	struct ether_addr       mac_address;    /* Device MAC address (Obtained on first TX packet). */
-	uint32_t                flags;          /* Device flags. Only used to check if device is running on data core. */
-	uint32_t                vlan_tag;       /* Vlan tag for device. Currently set to device_id (0-63). */
-	uint32_t                vmdq_rx_q;
-	uint64_t                device_fh;      /* device identifier. */
-	uint16_t                coreid;
-	volatile uint8_t        ready;          /* A device is set as ready if the MAC address has been set. */
-	volatile uint8_t        remove;         /* Device is marked for removal from the data core. */
-	uint32_t                virtio_idx;     /* Index of virtio device */
-	uint32_t                dom_id;         /* Domain id of xen guest */
-} ___rte_cache_aligned;
-
-/*
- * Device linked list structure for configuration.
- */
-struct virtio_net_config_ll
-{
-	struct virtio_net		dev;	/* Virtio device. */
-	struct virtio_net_config_ll	*next; /* Next entry on linked list. */
-};
-
-/*
- * Information relating to memory regions including offsets to addresses in QEMUs memory file.
- */
-struct virtio_memory_regions {
-	uint64_t	guest_phys_address;     /* Base guest physical address of region. */
-	uint64_t	guest_phys_address_end;	/* End guest physical address of region. */
-	uint64_t	memory_size;		/* Size of region. */
-	uint64_t	userspace_address;      /* Base userspace address of region. */
-	uint64_t	address_offset;         /* Offset of region for address translation. */
-};
-
-/*
- * Memory structure includes region and mapping information.
- */
-struct virtio_memory {
-	uint32_t			nregions;	/* Number of memory regions. */
-	struct virtio_memory_regions 	regions[0];	/* Memory region information. */
-};
-
-/*
- * Device operations to add/remove device.
- */
-struct virtio_net_device_ops {
-	int (* new_device)(struct virtio_net *);	/* Add device. */
-	void (* destroy_device)	(volatile struct virtio_net *);	/* Remove device. */
-};
-
-#endif
diff --git a/examples/vhost_xen/xen_vhost.h b/examples/vhost_xen/xen_vhost.h
deleted file mode 100644
index 2fc304c..0000000
--- a/examples/vhost_xen/xen_vhost.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _XEN_VHOST_H_
-#define _XEN_VHOST_H_
-
-#include <stdint.h>
-
-#include <rte_ether.h>
-
-#include "virtio-net.h"
-
-#define RTE_LOGTYPE_XENHOST RTE_LOGTYPE_USER1
-
-#define XEN_VM_ROOTNODE_FMT  "/local/domain/%d/control/dpdk"
-#define XEN_VM_NODE_FMT      "/local/domain/%d/control/dpdk/%s"
-#define XEN_MEMPOOL_SUFFIX   "mempool_gref"
-#define XEN_RXVRING_SUFFIX   "rx_vring_gref"
-#define XEN_TXVRING_SUFFIX   "tx_vring_gref"
-#define XEN_GVA_SUFFIX       "mempool_va"
-#define XEN_VRINGFLAG_SUFFIX "vring_flag"
-#define XEN_ADDR_SUFFIX      "ether_addr"
-#define VIRTIO_START         "event_type_start_"
-
-#define XEN_GREF_SPLITTOKEN  ','
-
-#define MAX_XENVIRT_MEMPOOL 16
-#define MAX_VIRTIO  32
-#define MAX_GREF_PER_NODE 64  /* 128 MB memory */
-
-#define PAGE_SIZE   4096
-#define PAGE_PFNNUM (PAGE_SIZE / sizeof(uint32_t))
-
-#define XEN_GNTDEV_FNAME "/dev/xen/gntdev"
-
-/* xen grant reference info in one grant node */
-struct xen_gnt {
-	uint32_t gref;	/* grant reference for this node */
-	union {
-		int gref;		/* grant reference */
-		uint32_t pfn_num;	/* guest pfn number of grant reference */
-	} gref_pfn[PAGE_PFNNUM];
-}__attribute__((__packed__));
-
-
-/* structure for mempool or vring node list */
-struct xen_gntnode {
-	uint32_t gnt_num;           /* grant reference number */
-	struct xen_gnt *gnt_info;   /* grant reference info */
-};
-
-
-struct xen_vring {
-	uint32_t dom_id;
-	uint32_t virtio_idx;    /* index of virtio device */
-	void *rxvring_addr;     /* mapped virtual address of rxvring */
-	void *txvring_addr;     /* mapped virtual address of txvring */
-	uint32_t rxpfn_num;     /* number of gpfn for rxvring */
-	uint32_t txpfn_num;	/* number of gpfn for txvring */
-	uint32_t *rxpfn_tbl;    /* array of rxvring gpfn */
-	uint32_t *txpfn_tbl;	/* array of txvring gpfn */
-	uint64_t *rx_pindex;    /* index used to release rx grefs */
-	uint64_t *tx_pindex;    /* index used to release tx grefs */
-	uint64_t  flag_index;
-	uint8_t  *flag; 	/* cleared to zero on guest unmap */
-	struct ether_addr addr; /* ethernet address of virtio device */
-	uint8_t   removed;
-
-};
-
-struct xen_mempool {
-	uint32_t dom_id;      /* guest domain id */
-	uint32_t pool_idx;    /* index of memory pool */
-	void *gva;            /* guest virtual address of mbuf pool */
-	void *hva;            /* host virtual address of mbuf pool */
-	uint32_t mempfn_num;  /* number of gpfn for mbuf pool */
-	uint32_t *mempfn_tbl; /* array of mbuf pool gpfn */
-	uint64_t *pindex;     /* index used to release grefs */
-};
-
-struct xen_guest {
-	TAILQ_ENTRY(xen_guest) next;
-	int32_t dom_id;       /* guest domain id */
-	uint32_t pool_num;    /* number of mbuf pool of the guest */
-	uint32_t vring_num;   /* number of virtio ports of the guest */
-	/* array contain the guest mbuf pool info */
-	struct xen_mempool mempool[MAX_XENVIRT_MEMPOOL];
-	/* array contain the guest rx/tx vring info */
-	struct xen_vring vring[MAX_VIRTIO];
-};
-
-TAILQ_HEAD(xen_guestlist, xen_guest);
-
-int
-parse_mempoolnode(struct xen_guest *guest);
-
-int
-xenhost_init(void);
-
-int
-parse_vringnode(struct xen_guest *guest, uint32_t virtio_idx);
-
-int
-parse_mempoolnode(struct xen_guest *guest);
-
-void
-cleanup_mempool(struct xen_mempool *mempool);
-
-void
-cleanup_vring(struct xen_vring *vring);
-
-void
-virtio_monitor_loop(void);
-
-int
-init_virtio_xen(struct virtio_net_device_ops const * const);
-
-#endif
diff --git a/examples/vhost_xen/xenstore_parse.c b/examples/vhost_xen/xenstore_parse.c
deleted file mode 100644
index ab089f1..0000000
--- a/examples/vhost_xen/xenstore_parse.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <xen/sys/gntalloc.h>
-#include <xen/sys/gntdev.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-
-#include <rte_common.h>
-#include <rte_memory.h>
-#include <rte_eal.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_log.h>
-#include <rte_debug.h>
-
-#include "xen_vhost.h"
-
-/* xenstore handle */
-static struct xs_handle *xs = NULL;
-
-/* gntdev file descriptor to map grant pages */
-static int d_fd = -1;
-
-/*
- *  The grant node format in xenstore for vring/mpool is like:
- *  idx#_rx_vring_gref = "gref1#, gref2#, gref3#"
- *  idx#_mempool_gref  = "gref1#, gref2#, gref3#"
- *  each gref# is the grant reference for a shared page.
- *  In each shared page, we store the grant_node_item items.
- */
-struct grant_node_item {
-	uint32_t gref;
-	uint32_t pfn;
-} __attribute__((packed));
-
-int cmdline_parse_etheraddr(void *tk, const char *srcbuf,
-	void *res, unsigned ressize);
-
-/* Map grant ref refid at addr_ori*/
-static void *
-xen_grant_mmap(void *addr_ori, int domid, int refid, uint64_t *pindex)
-{
-	struct ioctl_gntdev_map_grant_ref arg;
-	void *addr = NULL;
-	int pg_sz = getpagesize();
-
-	arg.count = 1;
-	arg.refs[0].domid = domid;
-	arg.refs[0].ref = refid;
-
-	int rv = ioctl(d_fd, IOCTL_GNTDEV_MAP_GRANT_REF, &arg);
-	if (rv) {
-		RTE_LOG(ERR, XENHOST, "  %s: (%d,%d) %s (ioctl failed)\n", __func__,
-				domid, refid, strerror(errno));
-		return NULL;
-	}
-
-	if (addr_ori == NULL)
-		addr = mmap(addr_ori, pg_sz, PROT_READ|PROT_WRITE, MAP_SHARED,
-				d_fd, arg.index);
-	else
-		addr = mmap(addr_ori, pg_sz, PROT_READ|PROT_WRITE, MAP_SHARED | MAP_FIXED,
-				d_fd, arg.index);
-
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, XENHOST, "  %s: (%d, %d) %s (map failed)\n", __func__,
-				domid, refid, strerror(errno));
-		return NULL;
-	}
-
-	if (pindex)
-		*pindex = arg.index;
-
-	return addr;
-}
-
-/* Unmap one grant ref, and munmap must be called before this */
-static int
-xen_unmap_grant_ref(uint64_t index)
-{
-	struct ioctl_gntdev_unmap_grant_ref arg;
-	int rv;
-
-	arg.count = 1;
-	arg.index = index;
-	rv = ioctl(d_fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &arg);
-	if (rv) {
-		RTE_LOG(ERR, XENHOST, "  %s: index 0x%" PRIx64 "unmap failed\n", __func__, index);
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * Reserve a virtual address space.
- * On success, returns the pointer. On failure, returns NULL.
- */
-static void *
-get_xen_virtual(size_t size, size_t page_sz)
-{
-	void *addr;
-	uintptr_t aligned_addr;
-
-	addr = mmap(NULL, size + page_sz, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, XENHOST, "failed get a virtual area\n");
-		return NULL;
-	}
-
-	aligned_addr = RTE_ALIGN_CEIL((uintptr_t)addr, page_sz);
-	munmap(addr, aligned_addr - (uintptr_t)addr);
-	munmap((void *)(aligned_addr + size), page_sz + (uintptr_t)addr - aligned_addr);
-	addr = (void *)(aligned_addr);
-
-	return addr;
-}
-
-static void
-free_xen_virtual(void *addr, size_t size, size_t page_sz __rte_unused)
-{
-	if (addr)
-		munmap(addr, size);
-}
-
-/*
- * Returns val str in xenstore.
- * @param path
- *  Full path string for key
- * @return
- *  Pointer to Val str, NULL on failure
- */
-static char *
-xen_read_node(char *path, uint32_t *len)
-{
-	char *buf;
-
-	buf = xs_read(xs, XBT_NULL, path, len);
-	return buf;
-}
-
-static int
-cal_pagenum(struct xen_gnt *gnt)
-{
-	unsigned int i;
-	/*
-	 * the items in the page are in the format of
-	 * gref#,pfn#,...,gref#,pfn#
-	 * FIXME, 0 is reserved by system, use it as terminator.
-	 */
-	for (i = 0; i < (PAGE_PFNNUM) / 2; i++) {
-		if (gnt->gref_pfn[i * 2].gref <= 0)
-			break;
-	}
-
-	return i;
-}
-
-/* Frees memory allocated to a grant node */
-static void
-xen_free_gntnode(struct xen_gntnode *gntnode)
-{
-	if (gntnode == NULL)
-		return;
-	free(gntnode->gnt_info);
-	free(gntnode);
-}
-
-/*
- * Parse a grant node.
- * @param domid
- *  Guest domain id.
- * @param path
- *  Full path string for a grant node, like for the following (key, val) pair
- *  idx#_mempool_gref = "gref#, gref#, gref#"
- *  path = 'local/domain/domid/control/dpdk/idx#_mempool_gref'
- *  gref# is a shared page contain packed (gref,pfn) entries
- * @return
- *  Returns the pointer to xen_gntnode
- */
-static struct xen_gntnode *
-parse_gntnode(int dom_id, char *path)
-{
-	char **gref_list = NULL;
-	uint32_t i, len, gref_num;
-	void *addr = NULL;
-	char *buf = NULL;
-	struct xen_gntnode *gntnode = NULL;
-	struct xen_gnt *gnt = NULL;
-	int pg_sz = getpagesize();
-	char *end;
-	uint64_t index;
-
-	if ((buf = xen_read_node(path, &len)) == NULL)
-		goto err;
-
-	gref_list = malloc(MAX_GREF_PER_NODE * sizeof(char *));
-	if (gref_list == NULL)
-		goto err;
-
-	gref_num = rte_strsplit(buf, len, gref_list, MAX_GREF_PER_NODE,
-			XEN_GREF_SPLITTOKEN);
-	if (gref_num == 0) {
-		RTE_LOG(ERR, XENHOST, "  %s: invalid grant node format\n", __func__);
-		goto err;
-	}
-
-	gntnode = calloc(1, sizeof(struct xen_gntnode));
-	gnt = calloc(gref_num, sizeof(struct xen_gnt));
-	if (gnt == NULL || gntnode == NULL)
-		goto err;
-
-	for (i = 0; i < gref_num; i++) {
-		errno = 0;
-		gnt[i].gref = strtol(gref_list[i], &end, 0);
-		if (errno != 0 || end == NULL || end == gref_list[i] ||
-			(*end != '\0' &&  *end != XEN_GREF_SPLITTOKEN)) {
-			RTE_LOG(ERR, XENHOST, "  %s: parse grant node item failed\n", __func__);
-			goto err;
-		}
-		addr = xen_grant_mmap(NULL, dom_id, gnt[i].gref, &index);
-		if (addr == NULL) {
-			RTE_LOG(ERR, XENHOST, "  %s: map gref %u failed\n", __func__, gnt[i].gref);
-			goto err;
-		}
-		RTE_LOG(INFO, XENHOST, "      %s: map gref %u to %p\n", __func__, gnt[i].gref, addr);
-		memcpy(gnt[i].gref_pfn, addr, pg_sz);
-		if (munmap(addr, pg_sz)) {
-			RTE_LOG(INFO, XENHOST, "  %s: unmap gref %u failed\n", __func__, gnt[i].gref);
-			goto err;
-		}
-		if (xen_unmap_grant_ref(index)) {
-			RTE_LOG(INFO, XENHOST, "  %s: release gref %u failed\n", __func__, gnt[i].gref);
-			goto err;
-		}
-
-	}
-
-	gntnode->gnt_num  = gref_num;
-	gntnode->gnt_info = gnt;
-
-	free(buf);
-	free(gref_list);
-	return gntnode;
-
-err:
-	free(gnt);
-	free(gntnode);
-	free(gref_list);
-	free(buf);
-	return NULL;
-}
-
-/*
- * This function maps grant node of vring or mbuf pool to a continuous virtual address space,
- * and returns mapped address, pfn array, index array
- * @param gntnode
- *  Pointer to grant node
- * @param domid
- *  Guest domain id
- * @param ppfn
- *  Pointer to pfn array, caller should free this array
- * @param pgs
- *  Pointer to number of pages
- * @param ppindex
- *  Pointer to index array, used to release grefs when to free this node
- * @return
- *  Pointer to mapped virtual address, NULL on failure
- */
-static void *
-map_gntnode(struct xen_gntnode *gntnode, int domid, uint32_t **ppfn, uint32_t *pgs, uint64_t **ppindex)
-{
-	struct xen_gnt *gnt;
-	uint32_t i, j;
-	size_t total_pages = 0;
-	void *addr;
-	uint32_t *pfn;
-	uint64_t *pindex;
-	uint32_t pfn_num = 0;
-	int pg_sz;
-
-	if (gntnode == NULL)
-		return NULL;
-
-	pg_sz = getpagesize();
-	for (i = 0; i < gntnode->gnt_num; i++) {
-		gnt = gntnode->gnt_info + i;
-		total_pages += cal_pagenum(gnt);
-	}
-	if ((addr = get_xen_virtual(total_pages * pg_sz, pg_sz)) == NULL) {
-		RTE_LOG(ERR, XENHOST, "  %s: failed get_xen_virtual\n", __func__);
-		return NULL;
-	}
-	pfn = calloc(total_pages, (size_t)sizeof(uint32_t));
-	pindex = calloc(total_pages, (size_t)sizeof(uint64_t));
-	if (pfn == NULL || pindex == NULL) {
-		free_xen_virtual(addr, total_pages * pg_sz, pg_sz);
-		free(pfn);
-		free(pindex);
-		return NULL;
-	}
-
-	RTE_LOG(INFO, XENHOST, "    %s: total pages:%zu, map to [%p, %p]\n", __func__, total_pages, addr, RTE_PTR_ADD(addr, total_pages * pg_sz - 1));
-	for (i = 0; i < gntnode->gnt_num; i++) {
-		gnt = gntnode->gnt_info + i;
-		for (j = 0; j < (PAGE_PFNNUM) / 2; j++) {
-			if ((gnt->gref_pfn[j * 2].gref) <= 0)
-				goto _end;
-			/*alternative: batch map, or through libxc*/
-			if (xen_grant_mmap(RTE_PTR_ADD(addr, pfn_num * pg_sz),
-					domid,
-					gnt->gref_pfn[j * 2].gref,
-					&pindex[pfn_num]) == NULL) {
-				goto mmap_failed;
-			}
-			pfn[pfn_num] = gnt->gref_pfn[j * 2 + 1].pfn_num;
-			pfn_num++;
-		}
-	}
-
-mmap_failed:
-	if (pfn_num)
-		munmap(addr, pfn_num * pg_sz);
-	for (i = 0; i < pfn_num; i++) {
-		xen_unmap_grant_ref(pindex[i]);
-	}
-	free(pindex);
-	free(pfn);
-	return NULL;
-
-_end:
-	if (ppindex)
-		*ppindex = pindex;
-	else
-		free(pindex);
-	if (ppfn)
-		*ppfn = pfn;
-	else
-		free(pfn);
-	if (pgs)
-		*pgs = total_pages;
-
-	return addr;
-}
-
-static int
-parse_mpool_va(struct xen_mempool *mempool)
-{
-	char path[PATH_MAX] = {0};
-	char *buf;
-	uint32_t len;
-	char *end;
-	int ret = -1;
-
-	errno = 0;
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_GVA_SUFFIX,
-		mempool->dom_id, mempool->pool_idx);
-
-	if((buf = xen_read_node(path, &len)) == NULL)
-		goto out;
-	mempool->gva = (void *)strtoul(buf, &end, 16);
-	if (errno != 0 || end == NULL || end == buf || *end != '\0') {
-		mempool->gva = NULL;
-		goto out;
-	}
-	ret = 0;
-out:
-	free(buf);
-	return ret;
-}
-
-/*
- * map mbuf pool
- */
-static int
-map_mempoolnode(struct xen_gntnode *gntnode,
-			struct xen_mempool *mempool)
-{
-	if (gntnode == NULL || mempool == NULL)
-		return -1;
-
-	mempool->hva =
-		map_gntnode(gntnode, mempool->dom_id, &mempool->mempfn_tbl, &mempool->mempfn_num, &mempool->pindex);
-
-	RTE_LOG(INFO, XENHOST, "  %s: map mempool at %p\n", __func__, (void *)mempool->hva);
-	if (mempool->hva)
-		return 0;
-	else {
-		return -1;
-	}
-}
-
-void
-cleanup_mempool(struct xen_mempool *mempool)
-{
-	int pg_sz = getpagesize();
-	uint32_t i;
-
-	if (mempool->hva)
-		munmap(mempool->hva, mempool->mempfn_num * pg_sz);
-	mempool->hva = NULL;
-
-	if (mempool->pindex) {
-		RTE_LOG(INFO, XENHOST, "  %s: unmap dom %02u mempool%02u %u grefs\n",
-			__func__,
-			mempool->dom_id,
-			mempool->pool_idx,
-			mempool->mempfn_num);
-		for (i = 0; i < mempool->mempfn_num; i ++) {
-			xen_unmap_grant_ref(mempool->pindex[i]);
-		}
-	}
-	mempool->pindex = NULL;
-
-	free(mempool->mempfn_tbl);
-	mempool->mempfn_tbl = NULL;
-}
-
-/*
- * process mempool node idx#_mempool_gref, idx = 0, 1, 2...
- * until we encounter a node that doesn't exist.
- */
-int
-parse_mempoolnode(struct xen_guest *guest)
-{
-	uint32_t i, len;
-	char path[PATH_MAX] = {0};
-	struct xen_gntnode *gntnode = NULL;
-	struct xen_mempool *mempool = NULL;
-	char *buf;
-
-	bzero(&guest->mempool, MAX_XENVIRT_MEMPOOL * sizeof(guest->mempool[0]));
-	guest->pool_num = 0;
-
-	while (1) {
-		/* check if null terminated */
-		snprintf(path, sizeof(path),
-			XEN_VM_ROOTNODE_FMT"/%d_"XEN_MEMPOOL_SUFFIX,
-			guest->dom_id,
-			guest->pool_num);
-
-		if ((buf = xen_read_node(path, &len)) != NULL) {
-			/* this node exists */
-			free(buf);
-		} else {
-			if (guest->pool_num == 0) {
-				RTE_LOG(ERR, PMD, "no mempool found\n");
-				return -1;
-			}
-			break;
-		}
-
-		mempool = &guest->mempool[guest->pool_num];
-		mempool->dom_id = guest->dom_id;
-		mempool->pool_idx = guest->pool_num;
-
-		RTE_LOG(INFO, XENHOST, "  %s: mempool %u parse gntnode %s\n", __func__, guest->pool_num, path);
-		gntnode = parse_gntnode(guest->dom_id, path);
-		if (gntnode == NULL)
-			goto err;
-
-		if (parse_mpool_va(mempool))
-			goto err;
-
-		RTE_LOG(INFO, XENHOST, "  %s: mempool %u map gntnode %s\n", __func__, guest->pool_num, path);
-		if (map_mempoolnode(gntnode, mempool))
-			goto err;
-
-		xen_free_gntnode(gntnode);
-		guest->pool_num++;
-	}
-
-	return 0;
-err:
-	if (gntnode)
-		xen_free_gntnode(gntnode);
-	for (i = 0; i <  MAX_XENVIRT_MEMPOOL ; i++) {
-		cleanup_mempool(&guest->mempool[i]);
-	}
-	/* reinitialise mempool */
-	bzero(&guest->mempool, MAX_XENVIRT_MEMPOOL * sizeof(guest->mempool[0]));
-	return -1;
-}
-
-static int
-xen_map_vringflag(struct xen_vring *vring)
-{
-	char path[PATH_MAX] = {0};
-	char *buf;
-	uint32_t len,gref;
-	int pg_sz = getpagesize();
-	char *end;
-
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_VRINGFLAG_SUFFIX,
-		vring->dom_id, vring->virtio_idx);
-
-	if((buf = xen_read_node(path, &len)) == NULL)
-		goto err;
-
-	errno = 0;
-	gref = strtol(buf, &end, 0);
-	if (errno != 0 || end == NULL || end == buf) {
-		goto err;
-	}
-	vring->flag = xen_grant_mmap(0, vring->dom_id, gref, &vring->flag_index);
-	if (vring->flag == NULL || *vring->flag == 0)
-		goto err;
-
-	free(buf);
-	return 0;
-err:
-	free(buf);
-	if (vring->flag) {
-		munmap(vring->flag, pg_sz);
-		vring->flag = NULL;
-		xen_unmap_grant_ref(vring->flag_index);
-	}
-	return -1;
-}
-
-
-static int
-xen_map_rxvringnode(struct xen_gntnode *gntnode,
-				struct xen_vring *vring)
-{
-	vring->rxvring_addr =
-		map_gntnode(gntnode, vring->dom_id, &vring->rxpfn_tbl, &vring->rxpfn_num, &vring->rx_pindex);
-	RTE_LOG(INFO, XENHOST, "  %s: map rx vring at %p\n", __func__, (void *)vring->rxvring_addr);
-	if (vring->rxvring_addr)
-		return 0;
-	else
-		return -1;
-}
-
-static int
-xen_map_txvringnode(struct xen_gntnode *gntnode,
-				struct xen_vring *vring)
-{
-	vring->txvring_addr =
-		map_gntnode(gntnode, vring->dom_id, &vring->txpfn_tbl, &vring->txpfn_num, &vring->tx_pindex);
-	RTE_LOG(INFO, XENHOST, "  %s: map tx vring at %p\n", __func__, (void *)vring->txvring_addr);
-	if (vring->txvring_addr)
-		return 0;
-	else
-		return -1;
-}
-
-void
-cleanup_vring(struct xen_vring *vring)
-{
-	int pg_sz = getpagesize();
-	uint32_t i;
-
-	RTE_LOG(INFO, XENHOST, "  %s: cleanup dom %u vring %u\n", __func__, vring->dom_id, vring->virtio_idx);
-	if (vring->rxvring_addr) {
-		munmap(vring->rxvring_addr, vring->rxpfn_num * pg_sz);
-		RTE_LOG(INFO, XENHOST, "  %s: unmap rx vring [%p, %p]\n",
-			__func__,
-			vring->rxvring_addr,
-			RTE_PTR_ADD(vring->rxvring_addr,
-			vring->rxpfn_num * pg_sz - 1));
-	}
-	vring->rxvring_addr = NULL;
-
-
-	if (vring->rx_pindex) {
-		RTE_LOG(INFO, XENHOST, "  %s: unmap rx vring %u grefs\n", __func__, vring->rxpfn_num);
-		for (i = 0; i < vring->rxpfn_num; i++) {
-			xen_unmap_grant_ref(vring->rx_pindex[i]);
-		}
-	}
-	vring->rx_pindex = NULL;
-
-	free(vring->rxpfn_tbl);
-	vring->rxpfn_tbl = NULL;
-
-	if (vring->txvring_addr) {
-		munmap(vring->txvring_addr, vring->txpfn_num * pg_sz);
-		RTE_LOG(INFO, XENHOST, "  %s: unmap tx vring [%p, %p]\n",
-			__func__,
-			vring->txvring_addr,
-			RTE_PTR_ADD(vring->txvring_addr,
-			vring->txpfn_num * pg_sz - 1));
-	}
-	vring->txvring_addr = NULL;
-
-	if (vring->tx_pindex) {
-		RTE_LOG(INFO, XENHOST, "  %s: unmap tx vring %u grefs\n", __func__, vring->txpfn_num);
-		for (i = 0; i < vring->txpfn_num; i++) {
-			xen_unmap_grant_ref(vring->tx_pindex[i]);
-		}
-	}
-	vring->tx_pindex = NULL;
-
-	free(vring->txpfn_tbl);
-	vring->txpfn_tbl = NULL;
-
-	if (vring->flag) {
-		if (!munmap((void *)vring->flag, pg_sz))
-			RTE_LOG(INFO, XENHOST, "  %s: unmap flag page at %p\n", __func__, vring->flag);
-		if (!xen_unmap_grant_ref(vring->flag_index))
-			RTE_LOG(INFO, XENHOST, "  %s: release flag ref index 0x%" PRIx64 "\n", __func__, vring->flag_index);
-	}
-	vring->flag = NULL;
-	return;
-}
-
-
-
-static int
-xen_parse_etheraddr(struct xen_vring *vring)
-{
-	char path[PATH_MAX] = {0};
-	char *buf;
-	uint32_t len;
-	int ret = -1;
-
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_ADDR_SUFFIX,
-		vring->dom_id, vring->virtio_idx);
-
-	if ((buf = xen_read_node(path, &len)) == NULL)
-		goto out;
-
-	if (cmdline_parse_etheraddr(NULL, buf, &vring->addr,
-			sizeof(vring->addr)) < 0)
-		goto out;
-	ret = 0;
-out:
-	free(buf);
-	return ret;
-}
-
-
-int
-parse_vringnode(struct xen_guest *guest, uint32_t virtio_idx)
-{
-	char path[PATH_MAX] = {0};
-	struct xen_gntnode *rx_gntnode = NULL;
-	struct xen_gntnode *tx_gntnode = NULL;
-	struct xen_vring *vring = NULL;
-
-	/*check if null terminated */
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_RXVRING_SUFFIX,
-		guest->dom_id,
-		virtio_idx);
-
-	RTE_LOG(INFO, XENHOST, "  %s: virtio %u parse rx gntnode %s\n", __func__, virtio_idx, path);
-	rx_gntnode = parse_gntnode(guest->dom_id, path);
-	if (rx_gntnode == NULL)
-		goto err;
-
-	/*check if null terminated */
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_TXVRING_SUFFIX,
-		guest->dom_id,
-		virtio_idx);
-
-	RTE_LOG(INFO, XENHOST, "  %s: virtio %u parse tx gntnode %s\n", __func__, virtio_idx, path);
-	tx_gntnode = parse_gntnode(guest->dom_id, path);
-	if (tx_gntnode == NULL)
-		goto err;
-
-	vring = &guest->vring[virtio_idx];
-	bzero(vring, sizeof(*vring));
-	vring->dom_id = guest->dom_id;
-	vring->virtio_idx = virtio_idx;
-
-	if (xen_parse_etheraddr(vring) != 0)
-		goto err;
-
-	RTE_LOG(INFO, XENHOST, "  %s: virtio %u map rx gntnode %s\n", __func__, virtio_idx, path);
-	if (xen_map_rxvringnode(rx_gntnode, vring) != 0)
-		goto err;
-
-	RTE_LOG(INFO, XENHOST, "  %s: virtio %u map tx gntnode %s\n", __func__, virtio_idx, path);
-	if (xen_map_txvringnode(tx_gntnode, vring) != 0)
-		goto err;
-
-	if (xen_map_vringflag(vring) != 0)
-		goto err;
-
-	guest->vring_num++;
-
-	xen_free_gntnode(rx_gntnode);
-	xen_free_gntnode(tx_gntnode);
-
-	return 0;
-
-err:
-	if (rx_gntnode)
-		xen_free_gntnode(rx_gntnode);
-	if (tx_gntnode)
-		xen_free_gntnode(tx_gntnode);
-	if (vring) {
-		cleanup_vring(vring);
-		bzero(vring, sizeof(*vring));
-	}
-	return -1;
-}
-
-/*
- * Open xen grant dev driver
- * @return
- *  0 on success, -1 on failure.
- */
-static int
-xen_grant_init(void)
-{
-	d_fd = open(XEN_GNTDEV_FNAME, O_RDWR);
-
-	return d_fd == -1? (-1): (0);
-}
-
-/*
- * Initialise xenstore handle and open grant dev driver.
- * @return
- *  0 on success, -1 on failure.
- */
-int
-xenhost_init(void)
-{
-	xs = xs_daemon_open();
-	if (xs == NULL) {
-		rte_panic("failed initialize xen daemon handler");
-		return -1;
-	}
-	if (xen_grant_init())
-		return -1;
-	return 0;
-}
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 1/6] example/vhost_xen: remove
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-08-30 18:10 ` Jianfeng Tan
                   ` (9 subsequent siblings)
  10 siblings, 0 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: jerin.jacob, shahafs, john.mcnamara, Jianfeng Tan, oao.m.martins,
	thomas, xen-devel

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 MAINTAINERS                         |    1 -
 examples/Makefile                   |    1 -
 examples/vhost_xen/Makefile         |   52 --
 examples/vhost_xen/main.c           | 1522 -----------------------------------
 examples/vhost_xen/main.h           |   66 --
 examples/vhost_xen/vhost_monitor.c  |  595 --------------
 examples/vhost_xen/virtio-net.h     |  113 ---
 examples/vhost_xen/xen_vhost.h      |  148 ----
 examples/vhost_xen/xenstore_parse.c |  775 ------------------
 9 files changed, 3273 deletions(-)
 delete mode 100644 examples/vhost_xen/Makefile
 delete mode 100644 examples/vhost_xen/main.c
 delete mode 100644 examples/vhost_xen/main.h
 delete mode 100644 examples/vhost_xen/vhost_monitor.c
 delete mode 100644 examples/vhost_xen/virtio-net.h
 delete mode 100644 examples/vhost_xen/xen_vhost.h
 delete mode 100644 examples/vhost_xen/xenstore_parse.c

diff --git a/MAINTAINERS b/MAINTAINERS
index a0cd75e..fe6c6db 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -196,7 +196,6 @@ F: lib/librte_eal/linuxapp/eal/*xen*
 F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
 F: drivers/net/xenvirt/
 F: doc/guides/xen/
-F: examples/vhost_xen/
 F: doc/guides/nics/features/xenvirt.ini
 
 FreeBSD EAL (with overlaps)
diff --git a/examples/Makefile b/examples/Makefile
index 28354ff..d27eddd 100644
--- a/examples/Makefile
+++ b/examples/Makefile
@@ -89,7 +89,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += tep_termination
 endif
 DIRS-$(CONFIG_RTE_LIBRTE_TIMER) += timer
 DIRS-$(CONFIG_RTE_LIBRTE_VHOST) += vhost vhost_scsi
-DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += vhost_xen
 DIRS-y += vmdq
 DIRS-y += vmdq_dcb
 ifeq ($(CONFIG_RTE_LIBRTE_POWER), y)
diff --git a/examples/vhost_xen/Makefile b/examples/vhost_xen/Makefile
deleted file mode 100644
index ad2466a..0000000
--- a/examples/vhost_xen/Makefile
+++ /dev/null
@@ -1,52 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-ifeq ($(RTE_SDK),)
-$(error "Please define RTE_SDK environment variable")
-endif
-
-# Default target, can be overridden by command line or environment
-RTE_TARGET ?= x86_64-native-linuxapp-gcc
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-# binary name
-APP = vhost-switch
-
-# all source are stored in SRCS-y
-SRCS-y := main.c vhost_monitor.c xenstore_parse.c
-
-CFLAGS += -O2 -I/usr/local/include -D_FILE_OFFSET_BITS=64 -Wno-unused-parameter
-CFLAGS += $(WERROR_FLAGS)
-CFLAGS += -D_GNU_SOURCE
-LDFLAGS += -lxenstore
-
-include $(RTE_SDK)/mk/rte.extapp.mk
diff --git a/examples/vhost_xen/main.c b/examples/vhost_xen/main.c
deleted file mode 100644
index eba4d35..0000000
--- a/examples/vhost_xen/main.c
+++ /dev/null
@@ -1,1522 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <arpa/inet.h>
-#include <getopt.h>
-#include <linux/if_ether.h>
-#include <linux/if_vlan.h>
-#include <linux/virtio_net.h>
-#include <linux/virtio_ring.h>
-#include <signal.h>
-#include <stdint.h>
-#include <sys/eventfd.h>
-#include <sys/param.h>
-#include <unistd.h>
-
-#include <rte_atomic.h>
-#include <rte_cycles.h>
-#include <rte_ethdev.h>
-#include <rte_log.h>
-#include <rte_string_fns.h>
-#include <rte_pause.h>
-
-#include "main.h"
-#include "virtio-net.h"
-#include "xen_vhost.h"
-
-#define MAX_QUEUES 128
-
-/* the maximum number of external ports supported */
-#define MAX_SUP_PORTS 1
-
-/*
- * Calculate the number of buffers needed per port
- */
-#define NUM_MBUFS_PER_PORT ((MAX_QUEUES*RTE_TEST_RX_DESC_DEFAULT) +		\
-							(num_switching_cores*MAX_PKT_BURST) +  			\
-							(num_switching_cores*RTE_TEST_TX_DESC_DEFAULT) +\
-							(num_switching_cores*MBUF_CACHE_SIZE))
-
-#define MBUF_CACHE_SIZE 64
-
-/*
- * RX and TX Prefetch, Host, and Write-back threshold values should be
- * carefully set for optimal performance. Consult the network
- * controller's datasheet and supporting DPDK documentation for guidance
- * on how these parameters should be set.
- */
-#define RX_PTHRESH 8 /* Default values of RX prefetch threshold reg. */
-#define RX_HTHRESH 8 /* Default values of RX host threshold reg. */
-#define RX_WTHRESH 4 /* Default values of RX write-back threshold reg. */
-
-/*
- * These default values are optimized for use with the Intel(R) 82599 10 GbE
- * Controller and the DPDK ixgbe PMD. Consider using other values for other
- * network controllers and/or network drivers.
- */
-#define TX_PTHRESH 36 /* Default values of TX prefetch threshold reg. */
-#define TX_HTHRESH 0  /* Default values of TX host threshold reg. */
-#define TX_WTHRESH 0  /* Default values of TX write-back threshold reg. */
-
-#define MAX_PKT_BURST 32		/* Max burst size for RX/TX */
-#define MAX_MRG_PKT_BURST 16	/* Max burst for merge buffers. Set to 1 due to performance issue. */
-#define BURST_TX_DRAIN_US 100	/* TX drain every ~100us */
-
-/* State of virtio device. */
-#define DEVICE_NOT_READY     0
-#define DEVICE_READY         1
-#define DEVICE_SAFE_REMOVE   2
-
-/* Config_core_flag status definitions. */
-#define REQUEST_DEV_REMOVAL 1
-#define ACK_DEV_REMOVAL 0
-
-/* Configurable number of RX/TX ring descriptors */
-#define RTE_TEST_RX_DESC_DEFAULT 128
-#define RTE_TEST_TX_DESC_DEFAULT 512
-
-#define INVALID_PORT_ID 0xFF
-
-/* Max number of devices. Limited by vmdq. */
-#define MAX_DEVICES 64
-
-/* Size of buffers used for snprintfs. */
-#define MAX_PRINT_BUFF 6072
-
-
-/* Maximum long option length for option parsing. */
-#define MAX_LONG_OPT_SZ 64
-
-/* Used to compare MAC addresses. */
-#define MAC_ADDR_CMP 0xFFFFFFFFFFFF
-
-/* mask of enabled ports */
-static uint32_t enabled_port_mask = 0;
-
-/*Number of switching cores enabled*/
-static uint32_t num_switching_cores = 0;
-
-/* number of devices/queues to support*/
-static uint32_t num_queues = 0;
-uint32_t num_devices = 0;
-
-/* Enable VM2VM communications. If this is disabled then the MAC address compare is skipped. */
-static uint32_t enable_vm2vm = 1;
-/* Enable stats. */
-static uint32_t enable_stats = 0;
-
-/* empty vmdq configuration structure. Filled in programatically */
-static const struct rte_eth_conf vmdq_conf_default = {
-	.rxmode = {
-		.mq_mode        = ETH_MQ_RX_VMDQ_ONLY,
-		.split_hdr_size = 0,
-		.header_split   = 0, /**< Header Split disabled */
-		.hw_ip_checksum = 0, /**< IP checksum offload disabled */
-		.hw_vlan_filter = 0, /**< VLAN filtering disabled */
-		/*
-		 * It is necessary for 1G NIC such as I350,
-		 * this fixes bug of ipv4 forwarding in guest can't
-		 * forward pakets from one virtio dev to another virtio dev.
-		 */
-		.hw_vlan_strip  = 1, /**< VLAN strip enabled. */
-		.jumbo_frame    = 0, /**< Jumbo Frame Support disabled */
-		.hw_strip_crc   = 1, /**< CRC stripped by hardware */
-	},
-
-	.txmode = {
-		.mq_mode = ETH_MQ_TX_NONE,
-	},
-	.rx_adv_conf = {
-		/*
-		 * should be overridden separately in code with
-		 * appropriate values
-		 */
-		.vmdq_rx_conf = {
-			.nb_queue_pools = ETH_8_POOLS,
-			.enable_default_pool = 0,
-			.default_pool = 0,
-			.nb_pool_maps = 0,
-			.pool_map = {{0, 0},},
-		},
-	},
-};
-
-static unsigned lcore_ids[RTE_MAX_LCORE];
-static uint8_t ports[RTE_MAX_ETHPORTS];
-static unsigned num_ports = 0; /**< The number of ports specified in command line */
-
-const uint16_t vlan_tags[] = {
-	1000, 1001, 1002, 1003, 1004, 1005, 1006, 1007,
-	1008, 1009, 1010, 1011,	1012, 1013, 1014, 1015,
-	1016, 1017, 1018, 1019, 1020, 1021, 1022, 1023,
-	1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031,
-	1032, 1033, 1034, 1035, 1036, 1037, 1038, 1039,
-	1040, 1041, 1042, 1043, 1044, 1045, 1046, 1047,
-	1048, 1049, 1050, 1051, 1052, 1053, 1054, 1055,
-	1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063,
-};
-
-/* ethernet addresses of ports */
-static struct ether_addr vmdq_ports_eth_addr[RTE_MAX_ETHPORTS];
-
-/* heads for the main used and free linked lists for the data path. */
-static struct virtio_net_data_ll *ll_root_used = NULL;
-static struct virtio_net_data_ll *ll_root_free = NULL;
-
-/* Array of data core structures containing information on individual core linked lists. */
-static struct lcore_info lcore_info[RTE_MAX_LCORE];
-
-/* Used for queueing bursts of TX packets. */
-struct mbuf_table {
-	unsigned len;
-	unsigned txq_id;
-	struct rte_mbuf *m_table[MAX_PKT_BURST];
-};
-
-/* TX queue for each data core. */
-struct mbuf_table lcore_tx_queue[RTE_MAX_LCORE];
-
-/* Vlan header struct used to insert vlan tags on TX. */
-struct vlan_ethhdr {
-	unsigned char   h_dest[ETH_ALEN];
-	unsigned char   h_source[ETH_ALEN];
-	__be16          h_vlan_proto;
-	__be16          h_vlan_TCI;
-	__be16          h_vlan_encapsulated_proto;
-};
-
-/* Header lengths. */
-#define VLAN_HLEN       4
-#define VLAN_ETH_HLEN   18
-
-/* Per-device statistics struct */
-struct device_statistics {
-	uint64_t tx_total;
-	rte_atomic64_t rx_total;
-	uint64_t tx;
-	rte_atomic64_t rx;
-} __rte_cache_aligned;
-struct device_statistics dev_statistics[MAX_DEVICES];
-
-/*
- * Builds up the correct configuration for VMDQ VLAN pool map
- * according to the pool & queue limits.
- */
-static inline int
-get_eth_conf(struct rte_eth_conf *eth_conf, uint32_t num_devices)
-{
-	struct rte_eth_vmdq_rx_conf conf;
-	unsigned i;
-
-	memset(&conf, 0, sizeof(conf));
-	conf.nb_queue_pools = (enum rte_eth_nb_pools)num_devices;
-	conf.nb_pool_maps = num_devices;
-
-	for (i = 0; i < conf.nb_pool_maps; i++) {
-		conf.pool_map[i].vlan_id = vlan_tags[ i ];
-		conf.pool_map[i].pools = (1UL << i);
-	}
-
-	(void)(rte_memcpy(eth_conf, &vmdq_conf_default, sizeof(*eth_conf)));
-	(void)(rte_memcpy(&eth_conf->rx_adv_conf.vmdq_rx_conf, &conf,
-		   sizeof(eth_conf->rx_adv_conf.vmdq_rx_conf)));
-	return 0;
-}
-
-/*
- * Validate the device number according to the max pool number gotten form dev_info
- * If the device number is invalid, give the error message and return -1.
- * Each device must have its own pool.
- */
-static inline int
-validate_num_devices(uint32_t max_nb_devices)
-{
-	if (num_devices > max_nb_devices) {
-		RTE_LOG(ERR, VHOST_PORT, "invalid number of devices\n");
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * Initialises a given port using global settings and with the rx buffers
- * coming from the mbuf_pool passed as parameter
- */
-static inline int
-port_init(uint8_t port, struct rte_mempool *mbuf_pool)
-{
-	struct rte_eth_dev_info dev_info;
-	struct rte_eth_rxconf *rxconf;
-	struct rte_eth_conf port_conf;
-	uint16_t rx_rings, tx_rings = (uint16_t)rte_lcore_count();
-	uint16_t rx_ring_size = RTE_TEST_RX_DESC_DEFAULT;
-	uint16_t tx_ring_size = RTE_TEST_TX_DESC_DEFAULT;
-	int retval;
-	uint16_t q;
-
-	/* The max pool number from dev_info will be used to validate the pool number specified in cmd line */
-	rte_eth_dev_info_get (port, &dev_info);
-
-	/*configure the number of supported virtio devices based on VMDQ limits */
-	num_devices = dev_info.max_vmdq_pools;
-	num_queues = dev_info.max_rx_queues;
-
-	retval = validate_num_devices(MAX_DEVICES);
-	if (retval < 0)
-		return retval;
-
-	/* Get port configuration. */
-	retval = get_eth_conf(&port_conf, num_devices);
-	if (retval < 0)
-		return retval;
-
-	if (port >= rte_eth_dev_count()) return -1;
-
-	rx_rings = (uint16_t)num_queues,
-	/* Configure ethernet device. */
-	retval = rte_eth_dev_configure(port, rx_rings, tx_rings, &port_conf);
-	if (retval != 0)
-		return retval;
-
-	retval = rte_eth_dev_adjust_nb_rx_tx_desc(port, &rx_ring_size,
-		&tx_ring_size);
-	if (retval != 0)
-		return retval;
-	if (rx_ring_size > RTE_TEST_RX_DESC_DEFAULT ||
-		tx_ring_size > RTE_TEST_TX_DESC_DEFAULT) {
-		RTE_LOG(ERR, VHOST_PORT, "Mbuf pool has an insufficient size for "
-			"port %u.\n", port);
-		return -1;
-	}
-
-	rte_eth_dev_info_get(port, &dev_info);
-	rxconf = &dev_info.default_rxconf;
-	rxconf->rx_drop_en = 1;
-	/* Setup the queues. */
-	for (q = 0; q < rx_rings; q ++) {
-		retval = rte_eth_rx_queue_setup(port, q, rx_ring_size,
-						rte_eth_dev_socket_id(port), rxconf,
-						mbuf_pool);
-		if (retval < 0)
-			return retval;
-	}
-	for (q = 0; q < tx_rings; q ++) {
-		retval = rte_eth_tx_queue_setup(port, q, tx_ring_size,
-						rte_eth_dev_socket_id(port),
-						NULL);
-		if (retval < 0)
-			return retval;
-	}
-
-	/* Start the device. */
-	retval  = rte_eth_dev_start(port);
-	if (retval < 0)
-		return retval;
-
-	rte_eth_macaddr_get(port, &vmdq_ports_eth_addr[port]);
-	RTE_LOG(INFO, VHOST_PORT, "Max virtio devices supported: %u\n", num_devices);
-	RTE_LOG(INFO, VHOST_PORT, "Port %u MAC: %02"PRIx8" %02"PRIx8" %02"PRIx8
-			" %02"PRIx8" %02"PRIx8" %02"PRIx8"\n",
-			(unsigned)port,
-			vmdq_ports_eth_addr[port].addr_bytes[0],
-			vmdq_ports_eth_addr[port].addr_bytes[1],
-			vmdq_ports_eth_addr[port].addr_bytes[2],
-			vmdq_ports_eth_addr[port].addr_bytes[3],
-			vmdq_ports_eth_addr[port].addr_bytes[4],
-			vmdq_ports_eth_addr[port].addr_bytes[5]);
-
-	return 0;
-}
-
-/*
- * Parse the portmask provided at run time.
- */
-static int
-parse_portmask(const char *portmask)
-{
-	char *end = NULL;
-	unsigned long pm;
-
-	errno = 0;
-
-	/* parse hexadecimal string */
-	pm = strtoul(portmask, &end, 16);
-	if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0') || (errno != 0))
-		return -1;
-
-	if (pm == 0)
-		return -1;
-
-	return pm;
-
-}
-
-/*
- * Parse num options at run time.
- */
-static int
-parse_num_opt(const char *q_arg, uint32_t max_valid_value)
-{
-	char *end = NULL;
-	unsigned long num;
-
-	errno = 0;
-
-	/* parse unsigned int string */
-	num = strtoul(q_arg, &end, 10);
-	if ((q_arg[0] == '\0') || (end == NULL) || (*end != '\0') || (errno != 0))
-		return -1;
-
-	if (num > max_valid_value)
-		return -1;
-
-	return num;
-
-}
-
-/*
- * Display usage
- */
-static void
-us_vhost_usage(const char *prgname)
-{
-	RTE_LOG(INFO, VHOST_CONFIG, "%s [EAL options] -- -p PORTMASK --vm2vm [0|1] --stats [0-N] --nb-devices ND\n"
-	"		-p PORTMASK: Set mask for ports to be used by application\n"
-	"		--vm2vm [0|1]: disable/enable(default) vm2vm comms\n"
-	"		--stats [0-N]: 0: Disable stats, N: Time in seconds to print stats\n",
-	       prgname);
-}
-
-/*
- * Parse the arguments given in the command line of the application.
- */
-static int
-us_vhost_parse_args(int argc, char **argv)
-{
-	int opt, ret;
-	int option_index;
-	unsigned i;
-	const char *prgname = argv[0];
-	static struct option long_option[] = {
-		{"vm2vm", required_argument, NULL, 0},
-		{"stats", required_argument, NULL, 0},
-		{NULL, 0, 0, 0}
-	};
-
-	/* Parse command line */
-	while ((opt = getopt_long(argc, argv, "p:",long_option, &option_index)) != EOF) {
-		switch (opt) {
-		/* Portmask */
-		case 'p':
-			enabled_port_mask = parse_portmask(optarg);
-			if (enabled_port_mask == 0) {
-				RTE_LOG(INFO, VHOST_CONFIG, "Invalid portmask\n");
-				us_vhost_usage(prgname);
-				return -1;
-			}
-			break;
-
-		case 0:
-			/* Enable/disable vm2vm comms. */
-			if (!strncmp(long_option[option_index].name, "vm2vm", MAX_LONG_OPT_SZ)) {
-				ret = parse_num_opt(optarg, 1);
-				if (ret == -1) {
-					RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for vm2vm [0|1]\n");
-					us_vhost_usage(prgname);
-					return -1;
-				} else {
-					enable_vm2vm = ret;
-				}
-			}
-
-			/* Enable/disable stats. */
-			if (!strncmp(long_option[option_index].name, "stats", MAX_LONG_OPT_SZ)) {
-				ret = parse_num_opt(optarg, INT32_MAX);
-				if (ret == -1) {
-					RTE_LOG(INFO, VHOST_CONFIG, "Invalid argument for stats [0..N]\n");
-					us_vhost_usage(prgname);
-					return -1;
-				} else {
-					enable_stats = ret;
-				}
-			}
-			break;
-
-			/* Invalid option - print options. */
-		default:
-			us_vhost_usage(prgname);
-			return -1;
-		}
-	}
-
-	for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
-		if (enabled_port_mask & (1 << i))
-			ports[num_ports++] = (uint8_t)i;
-	}
-
-	if ((num_ports ==  0) || (num_ports > MAX_SUP_PORTS)) {
-		RTE_LOG(INFO, VHOST_PORT, "Current enabled port number is %u,"
-			"but only %u port can be enabled\n",num_ports, MAX_SUP_PORTS);
-		return -1;
-	}
-
-	return 0;
-}
-
-/*
- * Update the global var NUM_PORTS and array PORTS according to system ports number
- * and return valid ports number
- */
-static unsigned check_ports_num(unsigned nb_ports)
-{
-	unsigned valid_num_ports = num_ports;
-	unsigned portid;
-
-	if (num_ports > nb_ports) {
-		RTE_LOG(INFO, VHOST_PORT, "\nSpecified port number(%u) exceeds total system port number(%u)\n",
-			num_ports, nb_ports);
-		num_ports = nb_ports;
-	}
-
-	for (portid = 0; portid < num_ports; portid ++) {
-		if (ports[portid] >= nb_ports) {
-			RTE_LOG(INFO, VHOST_PORT, "\nSpecified port ID(%u) exceeds max system port ID(%u)\n",
-				ports[portid], (nb_ports - 1));
-			ports[portid] = INVALID_PORT_ID;
-			valid_num_ports--;
-		}
-	}
-	return valid_num_ports;
-}
-
-/*
- * Function to convert guest physical addresses to vhost virtual addresses. This
- * is used to convert virtio buffer addresses.
- */
-static __rte_always_inline uint64_t
-gpa_to_vva(struct virtio_net *dev, uint64_t guest_pa)
-{
-	struct virtio_memory_regions *region;
-	uint32_t regionidx;
-	uint64_t vhost_va = 0;
-
-	for (regionidx = 0; regionidx < dev->mem->nregions; regionidx++) {
-		region = &dev->mem->regions[regionidx];
-		if ((guest_pa >= region->guest_phys_address) &&
-			(guest_pa <= region->guest_phys_address_end)) {
-			vhost_va = region->address_offset + guest_pa;
-			break;
-		}
-	}
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") GPA %p| VVA %p\n",
-		dev->device_fh, (void*)(uintptr_t)guest_pa, (void*)(uintptr_t)vhost_va);
-
-	return vhost_va;
-}
-
-/*
- * This function adds buffers to the virtio devices RX virtqueue. Buffers can
- * be received from the physical port or from another virtio device. A packet
- * count is returned to indicate the number of packets that were successfully
- * added to the RX queue.
- */
-static __rte_always_inline uint32_t
-virtio_dev_rx(struct virtio_net *dev, struct rte_mbuf **pkts, uint32_t count)
-{
-	struct vhost_virtqueue *vq;
-	struct vring_desc *desc;
-	struct rte_mbuf *buff;
-	/* The virtio_hdr is initialised to 0. */
-	struct virtio_net_hdr_mrg_rxbuf virtio_hdr = {{0,0,0,0,0,0},0};
-	uint64_t buff_addr = 0;
-	uint64_t buff_hdr_addr = 0;
-	uint32_t head[MAX_PKT_BURST], packet_len = 0;
-	uint32_t head_idx, packet_success = 0;
-	uint16_t avail_idx, res_cur_idx;
-	uint16_t res_base_idx, res_end_idx;
-	uint16_t free_entries;
-	uint8_t success = 0;
-	void *userdata;
-
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") virtio_dev_rx()\n", dev->device_fh);
-	vq = dev->virtqueue_rx;
-	count = (count > MAX_PKT_BURST) ? MAX_PKT_BURST : count;
-	/* As many data cores may want access to available buffers, they need to be reserved. */
-	do {
-
-		res_base_idx = vq->last_used_idx_res;
-
-		avail_idx = *((volatile uint16_t *)&vq->avail->idx);
-
-		free_entries = (avail_idx - res_base_idx);
-
-		/*check that we have enough buffers*/
-		if (unlikely(count > free_entries))
-			count = free_entries;
-
-		if (count == 0)
-			return 0;
-
-		res_end_idx = res_base_idx + count;
-		/* vq->last_used_idx_res is atomically updated. */
-		success = rte_atomic16_cmpset(&vq->last_used_idx_res, res_base_idx,
-									res_end_idx);
-	} while (unlikely(success == 0));
-	res_cur_idx = res_base_idx;
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") Current Index %d| End Index %d\n",
-		dev->device_fh, res_cur_idx, res_end_idx);
-
-	/* Prefetch available ring to retrieve indexes. */
-	rte_prefetch0(&vq->avail->ring[res_cur_idx & (vq->size - 1)]);
-
-	/* Retrieve all of the head indexes first to avoid caching issues. */
-	for (head_idx = 0; head_idx < count; head_idx++)
-		head[head_idx] = vq->avail->ring[(res_cur_idx + head_idx) & (vq->size - 1)];
-
-	/*Prefetch descriptor index. */
-	rte_prefetch0(&vq->desc[head[packet_success]]);
-
-	while (res_cur_idx != res_end_idx) {
-		/* Get descriptor from available ring */
-		desc = &vq->desc[head[packet_success]];
-		/* Prefetch descriptor address. */
-		rte_prefetch0(desc);
-
-		buff = pkts[packet_success];
-
-		/* Convert from gpa to vva (guest physical addr -> vhost virtual addr) */
-		buff_addr = gpa_to_vva(dev, desc->addr);
-		/* Prefetch buffer address. */
-		rte_prefetch0((void*)(uintptr_t)buff_addr);
-
-		{
-			/* Copy virtio_hdr to packet and increment buffer address */
-			buff_hdr_addr = buff_addr;
-			packet_len = rte_pktmbuf_data_len(buff) + vq->vhost_hlen;
-
-			/*
-			 * If the descriptors are chained the header and data are placed in
-			 * separate buffers.
-			 */
-			if (desc->flags & VRING_DESC_F_NEXT) {
-				desc->len = vq->vhost_hlen;
-				desc = &vq->desc[desc->next];
-				/* Buffer address translation. */
-				buff_addr = gpa_to_vva(dev, desc->addr);
-				desc->len = rte_pktmbuf_data_len(buff);
-			} else {
-				buff_addr += vq->vhost_hlen;
-				desc->len = packet_len;
-			}
-		}
-
-		/* Update used ring with desc information */
-		vq->used->ring[res_cur_idx & (vq->size - 1)].id = head[packet_success];
-		vq->used->ring[res_cur_idx & (vq->size - 1)].len = packet_len;
-
-		/* Copy mbuf data to buffer */
-		userdata = rte_pktmbuf_mtod(buff, void *);
-		rte_memcpy((void *)(uintptr_t)buff_addr, userdata, rte_pktmbuf_data_len(buff));
-
-		res_cur_idx++;
-		packet_success++;
-
-		/* mergeable is disabled then a header is required per buffer. */
-		rte_memcpy((void *)(uintptr_t)buff_hdr_addr, (const void *)&virtio_hdr, vq->vhost_hlen);
-		if (res_cur_idx < res_end_idx) {
-			/* Prefetch descriptor index. */
-			rte_prefetch0(&vq->desc[head[packet_success]]);
-		}
-	}
-
-	rte_compiler_barrier();
-
-	/* Wait until it's our turn to add our buffer to the used ring. */
-	while (unlikely(vq->last_used_idx != res_base_idx))
-		rte_pause();
-
-	*(volatile uint16_t *)&vq->used->idx += count;
-
-	vq->last_used_idx = res_end_idx;
-
-	return count;
-}
-
-/*
- * Compares a packet destination MAC address to a device MAC address.
- */
-static __rte_always_inline int
-ether_addr_cmp(struct ether_addr *ea, struct ether_addr *eb)
-{
-	return ((*(uint64_t *)ea ^ *(uint64_t *)eb) & MAC_ADDR_CMP) == 0;
-}
-
-/*
- * This function registers mac along with a
- * vlan tag to a VMDQ.
- */
-static int
-link_vmdq(struct virtio_net *dev)
-{
-	int ret;
-	struct virtio_net_data_ll *dev_ll;
-
-	dev_ll = ll_root_used;
-
-	while (dev_ll != NULL) {
-		if ((dev != dev_ll->dev) && ether_addr_cmp(&dev->mac_address, &dev_ll->dev->mac_address)) {
-			RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") WARNING: This device is using an existing MAC address and has not been registered.\n", dev->device_fh);
-			return -1;
-		}
-		dev_ll = dev_ll->next;
-	}
-
-	/* vlan_tag currently uses the device_id. */
-	dev->vlan_tag = vlan_tags[dev->device_fh];
-	dev->vmdq_rx_q = dev->device_fh * (num_queues/num_devices);
-
-	/* Print out VMDQ registration info. */
-	RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") MAC_ADDRESS %02x:%02x:%02x:%02x:%02x:%02x and VLAN_TAG %d registered\n",
-		dev->device_fh,
-		dev->mac_address.addr_bytes[0], dev->mac_address.addr_bytes[1],
-		dev->mac_address.addr_bytes[2], dev->mac_address.addr_bytes[3],
-		dev->mac_address.addr_bytes[4], dev->mac_address.addr_bytes[5],
-		dev->vlan_tag);
-
-	/* Register the MAC address. */
-	ret = rte_eth_dev_mac_addr_add(ports[0], &dev->mac_address, (uint32_t)dev->device_fh);
-	if (ret) {
-		RTE_LOG(ERR, VHOST_DATA, "(%"PRIu64") Failed to add device MAC address to VMDQ\n",
-										dev->device_fh);
-		return -1;
-	}
-
-	/* Enable stripping of the vlan tag as we handle routing. */
-	rte_eth_dev_set_vlan_strip_on_queue(ports[0], dev->vmdq_rx_q, 1);
-
-	rte_compiler_barrier();
-	/* Set device as ready for RX. */
-	dev->ready = DEVICE_READY;
-
-	return 0;
-}
-
-/*
- * Removes MAC address and vlan tag from VMDQ. Ensures that nothing is adding buffers to the RX
- * queue before disabling RX on the device.
- */
-static inline void
-unlink_vmdq(struct virtio_net *dev)
-{
-	unsigned i = 0;
-	unsigned rx_count;
-	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
-
-	if (dev->ready == DEVICE_READY) {
-		/*clear MAC and VLAN settings*/
-		rte_eth_dev_mac_addr_remove(ports[0], &dev->mac_address);
-		for (i = 0; i < 6; i++)
-			dev->mac_address.addr_bytes[i] = 0;
-
-		dev->vlan_tag = 0;
-
-		/*Clear out the receive buffers*/
-		rx_count = rte_eth_rx_burst(ports[0],
-					(uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
-
-		while (rx_count) {
-			for (i = 0; i < rx_count; i++)
-				rte_pktmbuf_free(pkts_burst[i]);
-
-			rx_count = rte_eth_rx_burst(ports[0],
-					(uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
-		}
-
-		dev->ready = DEVICE_NOT_READY;
-	}
-}
-
-/*
- * Check if the packet destination MAC address is for a local device. If so then put
- * the packet on that devices RX queue. If not then return.
- */
-static __rte_always_inline unsigned
-virtio_tx_local(struct virtio_net *dev, struct rte_mbuf *m)
-{
-	struct virtio_net_data_ll *dev_ll;
-	struct ether_hdr *pkt_hdr;
-	uint64_t ret = 0;
-
-	pkt_hdr = rte_pktmbuf_mtod(m, struct ether_hdr *);
-
-	/*get the used devices list*/
-	dev_ll = ll_root_used;
-
-	while (dev_ll != NULL) {
-		if (likely(dev_ll->dev->ready == DEVICE_READY) && ether_addr_cmp(&(pkt_hdr->d_addr),
-				          &dev_ll->dev->mac_address)) {
-
-			/* Drop the packet if the TX packet is destined for the TX device. */
-			if (dev_ll->dev->device_fh == dev->device_fh) {
-				RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: "
-					"Source and destination MAC addresses are the same. "
-					"Dropping packet.\n",
-					dev_ll->dev->device_fh);
-				return 0;
-			}
-
-
-			RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: "
-				"MAC address is local\n", dev_ll->dev->device_fh);
-
-			if (dev_ll->dev->remove) {
-				/*drop the packet if the device is marked for removal*/
-				RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") "
-					"Device is marked for removal\n",
-					dev_ll->dev->device_fh);
-			} else {
-				/*send the packet to the local virtio device*/
-				ret = virtio_dev_rx(dev_ll->dev, &m, 1);
-				if (enable_stats) {
-					rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, 1);
-					rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret);
-					dev_statistics[dev->device_fh].tx_total++;
-					dev_statistics[dev->device_fh].tx += ret;
-				}
-			}
-
-			return 0;
-		}
-		dev_ll = dev_ll->next;
-	}
-
-	return -1;
-}
-
-/*
- * This function routes the TX packet to the correct interface. This may be a local device
- * or the physical port.
- */
-static __rte_always_inline void
-virtio_tx_route(struct virtio_net* dev, struct rte_mbuf *m, struct rte_mempool *mbuf_pool, uint16_t vlan_tag)
-{
-	struct mbuf_table *tx_q;
-	struct vlan_ethhdr *vlan_hdr;
-	struct rte_mbuf **m_table;
-	struct rte_mbuf *mbuf;
-	unsigned len, ret;
-	const uint16_t lcore_id = rte_lcore_id();
-
-	/*check if destination is local VM*/
-	if (enable_vm2vm && (virtio_tx_local(dev, m) == 0)) {
-		return;
-	}
-
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") TX: "
-		"MAC address is external\n", dev->device_fh);
-
-	/*Add packet to the port tx queue*/
-	tx_q = &lcore_tx_queue[lcore_id];
-	len = tx_q->len;
-
-	/* Allocate an mbuf and populate the structure. */
-	mbuf = rte_pktmbuf_alloc(mbuf_pool);
-	if(!mbuf)
-		return;
-
-	mbuf->data_len = m->data_len + VLAN_HLEN;
-	mbuf->pkt_len = mbuf->data_len;
-
-	/* Copy ethernet header to mbuf. */
-	rte_memcpy(rte_pktmbuf_mtod(mbuf, void*),
-			rte_pktmbuf_mtod(m, const void*), ETH_HLEN);
-
-
-	/* Setup vlan header. Bytes need to be re-ordered for network with htons()*/
-	vlan_hdr = rte_pktmbuf_mtod(mbuf, struct vlan_ethhdr *);
-	vlan_hdr->h_vlan_encapsulated_proto = vlan_hdr->h_vlan_proto;
-	vlan_hdr->h_vlan_proto = htons(ETH_P_8021Q);
-	vlan_hdr->h_vlan_TCI = htons(vlan_tag);
-
-	/* Copy the remaining packet contents to the mbuf. */
-	rte_memcpy(rte_pktmbuf_mtod_offset(mbuf, void *, VLAN_ETH_HLEN),
-		rte_pktmbuf_mtod_offset(m, const void *, ETH_HLEN),
-		(m->data_len - ETH_HLEN));
-	tx_q->m_table[len] = mbuf;
-	len++;
-	if (enable_stats) {
-		dev_statistics[dev->device_fh].tx_total++;
-		dev_statistics[dev->device_fh].tx++;
-	}
-
-	if (unlikely(len == MAX_PKT_BURST)) {
-		m_table = (struct rte_mbuf **)tx_q->m_table;
-		ret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id, m_table, (uint16_t) len);
-		/* Free any buffers not handled by TX and update the port stats. */
-		if (unlikely(ret < len)) {
-			do {
-				rte_pktmbuf_free(m_table[ret]);
-			} while (++ret < len);
-		}
-
-		len = 0;
-	}
-
-	tx_q->len = len;
-	return;
-}
-
-static __rte_always_inline void
-virtio_dev_tx(struct virtio_net* dev, struct rte_mempool *mbuf_pool)
-{
-	struct rte_mbuf m;
-	struct vhost_virtqueue *vq;
-	struct vring_desc *desc;
-	uint64_t buff_addr = 0;
-	uint32_t head[MAX_PKT_BURST];
-	uint32_t used_idx;
-	uint32_t i;
-	uint16_t free_entries, packet_success = 0;
-	uint16_t avail_idx;
-
-	vq = dev->virtqueue_tx;
-	avail_idx = *((volatile uint16_t *)&vq->avail->idx);
-
-	/* If there are no available buffers then return. */
-	if (vq->last_used_idx == avail_idx)
-		return;
-
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") virtio_dev_tx()\n",
-		dev->device_fh);
-
-	/* Prefetch available ring to retrieve head indexes. */
-	rte_prefetch0(&vq->avail->ring[vq->last_used_idx & (vq->size - 1)]);
-
-	/*get the number of free entries in the ring*/
-	free_entries = avail_idx - vq->last_used_idx;
-	free_entries = unlikely(free_entries < MAX_PKT_BURST) ? free_entries : MAX_PKT_BURST;
-
-	RTE_LOG_DP(DEBUG, VHOST_DATA, "(%" PRIu64 ") Buffers available %d\n",
-		dev->device_fh, free_entries);
-	/* Retrieve all of the head indexes first to avoid caching issues. */
-	for (i = 0; i < free_entries; i++)
-		head[i] = vq->avail->ring[(vq->last_used_idx + i) & (vq->size - 1)];
-
-	/* Prefetch descriptor index. */
-	rte_prefetch0(&vq->desc[head[packet_success]]);
-
-	while (packet_success < free_entries) {
-		desc = &vq->desc[head[packet_success]];
-		/* Prefetch descriptor address. */
-		rte_prefetch0(desc);
-
-		if (packet_success < (free_entries - 1)) {
-			/* Prefetch descriptor index. */
-			rte_prefetch0(&vq->desc[head[packet_success+1]]);
-		}
-
-		/* Update used index buffer information. */
-		used_idx = vq->last_used_idx & (vq->size - 1);
-		vq->used->ring[used_idx].id = head[packet_success];
-		vq->used->ring[used_idx].len = 0;
-
-		/* Discard first buffer as it is the virtio header */
-		desc = &vq->desc[desc->next];
-
-		/* Buffer address translation. */
-		buff_addr = gpa_to_vva(dev, desc->addr);
-		/* Prefetch buffer address. */
-		rte_prefetch0((void*)(uintptr_t)buff_addr);
-
-		/* Setup dummy mbuf. This is copied to a real mbuf if transmitted out the physical port. */
-		m.data_len = desc->len;
-		m.data_off = 0;
-		m.nb_segs = 1;
-
-		virtio_tx_route(dev, &m, mbuf_pool, 0);
-
-		vq->last_used_idx++;
-		packet_success++;
-	}
-
-	rte_compiler_barrier();
-	vq->used->idx += packet_success;
-	/* Kick guest if required. */
-}
-
-/*
- * This function is called by each data core. It handles all RX/TX registered with the
- * core. For TX the specific lcore linked list is used. For RX, MAC addresses are compared
- * with all devices in the main linked list.
- */
-static int
-switch_worker(__attribute__((unused)) void *arg)
-{
-	struct rte_mempool *mbuf_pool = arg;
-	struct virtio_net *dev = NULL;
-	struct rte_mbuf *pkts_burst[MAX_PKT_BURST];
-	struct virtio_net_data_ll *dev_ll;
-	struct mbuf_table *tx_q;
-	volatile struct lcore_ll_info *lcore_ll;
-	const uint64_t drain_tsc = (rte_get_tsc_hz() + US_PER_S - 1) / US_PER_S * BURST_TX_DRAIN_US;
-	uint64_t prev_tsc, diff_tsc, cur_tsc, ret_count = 0;
-	unsigned ret, i;
-	const uint16_t lcore_id = rte_lcore_id();
-	const uint16_t num_cores = (uint16_t)rte_lcore_count();
-	uint16_t rx_count = 0;
-
-	RTE_LOG(INFO, VHOST_DATA, "Procesing on Core %u started \n", lcore_id);
-	lcore_ll = lcore_info[lcore_id].lcore_ll;
-	prev_tsc = 0;
-
-	tx_q = &lcore_tx_queue[lcore_id];
-	for (i = 0; i < num_cores; i ++) {
-		if (lcore_ids[i] == lcore_id) {
-			tx_q->txq_id = i;
-			break;
-		}
-	}
-
-	while(1) {
-		cur_tsc = rte_rdtsc();
-		/*
-		 * TX burst queue drain
-		 */
-		diff_tsc = cur_tsc - prev_tsc;
-		if (unlikely(diff_tsc > drain_tsc)) {
-
-			if (tx_q->len) {
-				RTE_LOG_DP(DEBUG, VHOST_DATA,
-					"TX queue drained after timeout with burst size %u\n",
-					tx_q->len);
-
-				/*Tx any packets in the queue*/
-				ret = rte_eth_tx_burst(ports[0], (uint16_t)tx_q->txq_id,
-									   (struct rte_mbuf **)tx_q->m_table,
-									   (uint16_t)tx_q->len);
-				if (unlikely(ret < tx_q->len)) {
-					do {
-						rte_pktmbuf_free(tx_q->m_table[ret]);
-					} while (++ret < tx_q->len);
-				}
-
-				tx_q->len = 0;
-			}
-
-			prev_tsc = cur_tsc;
-
-		}
-
-		/*
-		 * Inform the configuration core that we have exited the linked list and that no devices are
-		 * in use if requested.
-		 */
-		if (lcore_ll->dev_removal_flag == REQUEST_DEV_REMOVAL)
-			lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;
-
-		/*
-		 * Process devices
-	 	 */
-		dev_ll = lcore_ll->ll_root_used;
-
-		while (dev_ll != NULL) {
-			/*get virtio device ID*/
-			dev = dev_ll->dev;
-
-			if (unlikely(dev->remove)) {
-				dev_ll = dev_ll->next;
-				unlink_vmdq(dev);
-				dev->ready = DEVICE_SAFE_REMOVE;
-				continue;
-			}
-			if (likely(dev->ready == DEVICE_READY)) {
-				/*Handle guest RX*/
-				rx_count = rte_eth_rx_burst(ports[0],
-					(uint16_t)dev->vmdq_rx_q, pkts_burst, MAX_PKT_BURST);
-
-				if (rx_count) {
-					ret_count = virtio_dev_rx(dev, pkts_burst, rx_count);
-					if (enable_stats) {
-						rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx_total, rx_count);
-						rte_atomic64_add(&dev_statistics[dev_ll->dev->device_fh].rx, ret_count);
-					}
-					while (likely(rx_count)) {
-						rx_count--;
-						rte_pktmbuf_free_seg(pkts_burst[rx_count]);
-					}
-
-				}
-			}
-
-			if (likely(!dev->remove))
-				/*Handle guest TX*/
-				virtio_dev_tx(dev, mbuf_pool);
-
-			/*move to the next device in the list*/
-			dev_ll = dev_ll->next;
-		}
-	}
-
-	return 0;
-}
-
-/*
- * Add an entry to a used linked list. A free entry must first be found in the free linked list
- * using get_data_ll_free_entry();
- */
-static void
-add_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)
-{
-	struct virtio_net_data_ll *ll = *ll_root_addr;
-
-	/* Set next as NULL and use a compiler barrier to avoid reordering. */
-	ll_dev->next = NULL;
-	rte_compiler_barrier();
-
-	/* If ll == NULL then this is the first device. */
-	if (ll) {
-		/* Increment to the tail of the linked list. */
-		while ((ll->next != NULL) )
-			ll = ll->next;
-
-		ll->next = ll_dev;
-	} else {
-		*ll_root_addr = ll_dev;
-	}
-}
-
-/*
- * Remove an entry from a used linked list. The entry must then be added to the free linked list
- * using put_data_ll_free_entry().
- */
-static void
-rm_data_ll_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev, struct virtio_net_data_ll *ll_dev_last)
-{
-	struct virtio_net_data_ll *ll = *ll_root_addr;
-
-	if (ll_dev == ll)
-		*ll_root_addr = ll_dev->next;
-	else
-		ll_dev_last->next = ll_dev->next;
-}
-
-/*
- * Find and return an entry from the free linked list.
- */
-static struct virtio_net_data_ll *
-get_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr)
-{
-	struct virtio_net_data_ll *ll_free = *ll_root_addr;
-	struct virtio_net_data_ll *ll_dev;
-
-	if (ll_free == NULL)
-		return NULL;
-
-	ll_dev = ll_free;
-	*ll_root_addr = ll_free->next;
-
-	return ll_dev;
-}
-
-/*
- * Place an entry back on to the free linked list.
- */
-static void
-put_data_ll_free_entry(struct virtio_net_data_ll **ll_root_addr, struct virtio_net_data_ll *ll_dev)
-{
-	struct virtio_net_data_ll *ll_free = *ll_root_addr;
-
-	ll_dev->next = ll_free;
-	*ll_root_addr = ll_dev;
-}
-
-/*
- * Creates a linked list of a given size.
- */
-static struct virtio_net_data_ll *
-alloc_data_ll(uint32_t size)
-{
-	struct virtio_net_data_ll *ll_new;
-	uint32_t i;
-
-	/* Malloc and then chain the linked list. */
-	ll_new = malloc(size * sizeof(struct virtio_net_data_ll));
-	if (ll_new == NULL) {
-		RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for ll_new.\n");
-		return NULL;
-	}
-
-	for (i = 0; i < size - 1; i++) {
-		ll_new[i].dev = NULL;
-		ll_new[i].next = &ll_new[i+1];
-	}
-	ll_new[i].next = NULL;
-
-	return ll_new;
-}
-
-/*
- * Create the main linked list along with each individual cores linked list. A used and a free list
- * are created to manage entries.
- */
-static int
-init_data_ll (void)
-{
-	int lcore;
-
-	RTE_LCORE_FOREACH_SLAVE(lcore) {
-		lcore_info[lcore].lcore_ll = malloc(sizeof(struct lcore_ll_info));
-		if (lcore_info[lcore].lcore_ll == NULL) {
-			RTE_LOG(ERR, VHOST_CONFIG, "Failed to allocate memory for lcore_ll.\n");
-			return -1;
-		}
-
-		lcore_info[lcore].lcore_ll->device_num = 0;
-		lcore_info[lcore].lcore_ll->dev_removal_flag = ACK_DEV_REMOVAL;
-		lcore_info[lcore].lcore_ll->ll_root_used = NULL;
-		if (num_devices % num_switching_cores)
-			lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll((num_devices / num_switching_cores) + 1);
-		else
-			lcore_info[lcore].lcore_ll->ll_root_free = alloc_data_ll(num_devices / num_switching_cores);
-	}
-
-	/* Allocate devices up to a maximum of MAX_DEVICES. */
-	ll_root_free = alloc_data_ll(MIN((num_devices), MAX_DEVICES));
-
-	return 0;
-}
-/*
- * Remove a device from the specific data core linked list and from the main linked list. The
- * rx/tx thread must be set the flag to indicate that it is safe to remove the device.
- * used.
- */
-static void
-destroy_device (volatile struct virtio_net *dev)
-{
-	struct virtio_net_data_ll *ll_lcore_dev_cur;
-	struct virtio_net_data_ll *ll_main_dev_cur;
-	struct virtio_net_data_ll *ll_lcore_dev_last = NULL;
-	struct virtio_net_data_ll *ll_main_dev_last = NULL;
-	int lcore;
-
-	dev->flags &= ~VIRTIO_DEV_RUNNING;
-
-	/*set the remove flag. */
-	dev->remove = 1;
-
-	while(dev->ready != DEVICE_SAFE_REMOVE) {
-		rte_pause();
-	}
-
-	/* Search for entry to be removed from lcore ll */
-	ll_lcore_dev_cur = lcore_info[dev->coreid].lcore_ll->ll_root_used;
-	while (ll_lcore_dev_cur != NULL) {
-		if (ll_lcore_dev_cur->dev == dev) {
-			break;
-		} else {
-			ll_lcore_dev_last = ll_lcore_dev_cur;
-			ll_lcore_dev_cur = ll_lcore_dev_cur->next;
-		}
-	}
-
-	/* Search for entry to be removed from main ll */
-	ll_main_dev_cur = ll_root_used;
-	ll_main_dev_last = NULL;
-	while (ll_main_dev_cur != NULL) {
-		if (ll_main_dev_cur->dev == dev) {
-			break;
-		} else {
-			ll_main_dev_last = ll_main_dev_cur;
-			ll_main_dev_cur = ll_main_dev_cur->next;
-		}
-	}
-
-	if (ll_lcore_dev_cur == NULL || ll_main_dev_cur == NULL) {
-		RTE_LOG(ERR, XENHOST, "%s: could find device in per_cpu list or main_list\n", __func__);
-		return;
-	}
-
-	/* Remove entries from the lcore and main ll. */
-	rm_data_ll_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_used, ll_lcore_dev_cur, ll_lcore_dev_last);
-	rm_data_ll_entry(&ll_root_used, ll_main_dev_cur, ll_main_dev_last);
-
-	/* Set the dev_removal_flag on each lcore. */
-	RTE_LCORE_FOREACH_SLAVE(lcore) {
-		lcore_info[lcore].lcore_ll->dev_removal_flag = REQUEST_DEV_REMOVAL;
-	}
-
-	/*
-	 * Once each core has set the dev_removal_flag to ACK_DEV_REMOVAL we can be sure that
-	 * they can no longer access the device removed from the linked lists and that the devices
-	 * are no longer in use.
-	 */
-	RTE_LCORE_FOREACH_SLAVE(lcore) {
-		while (lcore_info[lcore].lcore_ll->dev_removal_flag != ACK_DEV_REMOVAL) {
-			rte_pause();
-		}
-	}
-
-	/* Add the entries back to the lcore and main free ll.*/
-	put_data_ll_free_entry(&lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->ll_root_free, ll_lcore_dev_cur);
-	put_data_ll_free_entry(&ll_root_free, ll_main_dev_cur);
-
-	/* Decrement number of device on the lcore. */
-	lcore_info[ll_lcore_dev_cur->dev->coreid].lcore_ll->device_num--;
-
-	RTE_LOG(INFO, VHOST_DATA, "  #####(%"PRIu64") Device has been removed from data core\n", dev->device_fh);
-}
-
-/*
- * A new device is added to a data core. First the device is added to the main linked list
- * and the allocated to a specific data core.
- */
-static int
-new_device (struct virtio_net *dev)
-{
-	struct virtio_net_data_ll *ll_dev;
-	int lcore, core_add = 0;
-	uint32_t device_num_min = num_devices;
-
-	/* Add device to main ll */
-	ll_dev = get_data_ll_free_entry(&ll_root_free);
-	if (ll_dev == NULL) {
-		RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") No free entry found in linked list. Device limit "
-			"of %d devices per core has been reached\n",
-			dev->device_fh, num_devices);
-		return -1;
-	}
-	ll_dev->dev = dev;
-	add_data_ll_entry(&ll_root_used, ll_dev);
-
-	/*reset ready flag*/
-	dev->ready = DEVICE_NOT_READY;
-	dev->remove = 0;
-
-	/* Find a suitable lcore to add the device. */
-	RTE_LCORE_FOREACH_SLAVE(lcore) {
-		if (lcore_info[lcore].lcore_ll->device_num < device_num_min) {
-			device_num_min = lcore_info[lcore].lcore_ll->device_num;
-			core_add = lcore;
-		}
-	}
-	/* Add device to lcore ll */
-	ll_dev->dev->coreid = core_add;
-	ll_dev = get_data_ll_free_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_free);
-	if (ll_dev == NULL) {
-		RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Failed to add device to data core\n", dev->device_fh);
-		destroy_device(dev);
-		return -1;
-	}
-	ll_dev->dev = dev;
-	add_data_ll_entry(&lcore_info[ll_dev->dev->coreid].lcore_ll->ll_root_used, ll_dev);
-
-	/* Initialize device stats */
-	memset(&dev_statistics[dev->device_fh], 0, sizeof(struct device_statistics));
-
-	lcore_info[ll_dev->dev->coreid].lcore_ll->device_num++;
-	dev->flags |= VIRTIO_DEV_RUNNING;
-
-	RTE_LOG(INFO, VHOST_DATA, "(%"PRIu64") Device has been added to data core %d\n", dev->device_fh, dev->coreid);
-
-	link_vmdq(dev);
-
-	return 0;
-}
-
-/*
- * These callback allow devices to be added to the data core when configuration
- * has been fully complete.
- */
-static const struct virtio_net_device_ops virtio_net_device_ops =
-{
-	.new_device =  new_device,
-	.destroy_device = destroy_device,
-};
-
-/*
- * This is a thread will wake up after a period to print stats if the user has
- * enabled them.
- */
-static void
-print_stats(void)
-{
-	struct virtio_net_data_ll *dev_ll;
-	uint64_t tx_dropped, rx_dropped;
-	uint64_t tx, tx_total, rx, rx_total;
-	uint32_t device_fh;
-	const char clr[] = { 27, '[', '2', 'J', '\0' };
-	const char top_left[] = { 27, '[', '1', ';', '1', 'H','\0' };
-
-	while(1) {
-		sleep(enable_stats);
-
-		/* Clear screen and move to top left */
-		printf("%s%s", clr, top_left);
-
-		printf("\nDevice statistics ====================================");
-
-		dev_ll = ll_root_used;
-		while (dev_ll != NULL) {
-			device_fh = (uint32_t)dev_ll->dev->device_fh;
-			tx_total = dev_statistics[device_fh].tx_total;
-			tx = dev_statistics[device_fh].tx;
-			tx_dropped = tx_total - tx;
-			rx_total = rte_atomic64_read(&dev_statistics[device_fh].rx_total);
-			rx = rte_atomic64_read(&dev_statistics[device_fh].rx);
-			rx_dropped = rx_total - rx;
-
-			printf("\nStatistics for device %"PRIu32" ------------------------------"
-					"\nTX total: 		%"PRIu64""
-					"\nTX dropped: 		%"PRIu64""
-					"\nTX successful: 		%"PRIu64""
-					"\nRX total: 		%"PRIu64""
-					"\nRX dropped: 		%"PRIu64""
-					"\nRX successful: 		%"PRIu64"",
-					device_fh,
-					tx_total,
-					tx_dropped,
-					tx,
-					rx_total,
-					rx_dropped,
-					rx);
-
-			dev_ll = dev_ll->next;
-		}
-		printf("\n======================================================\n");
-	}
-}
-
-
-int init_virtio_net(struct virtio_net_device_ops const * const ops);
-
-/*
- * Main function, does initialisation and calls the per-lcore functions.
- */
-int
-main(int argc, char *argv[])
-{
-	struct rte_mempool *mbuf_pool;
-	unsigned lcore_id, core_id = 0;
-	unsigned nb_ports, valid_num_ports;
-	int ret;
-	uint8_t portid;
-	static pthread_t tid;
-	char thread_name[RTE_MAX_THREAD_NAME_LEN];
-
-	/* init EAL */
-	ret = rte_eal_init(argc, argv);
-	if (ret < 0)
-		rte_exit(EXIT_FAILURE, "Error with EAL initialization\n");
-	argc -= ret;
-	argv += ret;
-
-	/* parse app arguments */
-	ret = us_vhost_parse_args(argc, argv);
-	if (ret < 0)
-		rte_exit(EXIT_FAILURE, "Invalid argument\n");
-
-	for (lcore_id = 0; lcore_id < RTE_MAX_LCORE; lcore_id ++)
-		if (rte_lcore_is_enabled(lcore_id))
-			lcore_ids[core_id ++] = lcore_id;
-
-	if (rte_lcore_count() > RTE_MAX_LCORE)
-		rte_exit(EXIT_FAILURE,"Not enough cores\n");
-
-	/*set the number of swithcing cores available*/
-	num_switching_cores = rte_lcore_count()-1;
-
-	/* Get the number of physical ports. */
-	nb_ports = rte_eth_dev_count();
-
-	/*
-	 * Update the global var NUM_PORTS and global array PORTS
-	 * and get value of var VALID_NUM_PORTS according to system ports number
-	 */
-	valid_num_ports = check_ports_num(nb_ports);
-
-	if ((valid_num_ports ==  0) || (valid_num_ports > MAX_SUP_PORTS)) {
-		RTE_LOG(INFO, VHOST_PORT, "Current enabled port number is %u,"
-			"but only %u port can be enabled\n",num_ports, MAX_SUP_PORTS);
-		return -1;
-	}
-
-	/* Create the mbuf pool. */
-	mbuf_pool = rte_pktmbuf_pool_create("MBUF_POOL",
-		NUM_MBUFS_PER_PORT * valid_num_ports, MBUF_CACHE_SIZE, 0,
-		RTE_MBUF_DEFAULT_BUF_SIZE, rte_socket_id());
-	if (mbuf_pool == NULL)
-		rte_exit(EXIT_FAILURE, "Cannot create mbuf pool\n");
-
-	/* initialize all ports */
-	for (portid = 0; portid < nb_ports; portid++) {
-		/* skip ports that are not enabled */
-		if ((enabled_port_mask & (1 << portid)) == 0) {
-			RTE_LOG(INFO, VHOST_PORT, "Skipping disabled port %d\n", portid);
-			continue;
-		}
-		if (port_init(portid, mbuf_pool) != 0)
-			rte_exit(EXIT_FAILURE, "Cannot initialize network ports\n");
-	}
-
-	/* Initialise all linked lists. */
-	if (init_data_ll() == -1)
-		rte_exit(EXIT_FAILURE, "Failed to initialize linked list\n");
-
-	/* Initialize device stats */
-	memset(&dev_statistics, 0, sizeof(dev_statistics));
-
-	/* Enable stats if the user option is set. */
-	if (enable_stats) {
-		ret = pthread_create(&tid, NULL, (void *)print_stats, NULL);
-		if (ret != 0)
-			rte_exit(EXIT_FAILURE,
-				"Cannot create print-stats thread\n");
-
-		/* Set thread_name for aid in debugging. */
-		snprintf(thread_name, RTE_MAX_THREAD_NAME_LEN, "print-xen-stats");
-		ret = rte_thread_setname(tid, thread_name);
-		if (ret != 0)
-			RTE_LOG(DEBUG, VHOST_CONFIG,
-				"Cannot set print-stats name\n");
-	}
-
-	/* Launch all data cores. */
-	RTE_LCORE_FOREACH_SLAVE(lcore_id) {
-		rte_eal_remote_launch(switch_worker, mbuf_pool, lcore_id);
-	}
-
-	init_virtio_xen(&virtio_net_device_ops);
-
-	virtio_monitor_loop();
-	return 0;
-}
diff --git a/examples/vhost_xen/main.h b/examples/vhost_xen/main.h
deleted file mode 100644
index 5ff48fd..0000000
--- a/examples/vhost_xen/main.h
+++ /dev/null
@@ -1,66 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _MAIN_H_
-#define _MAIN_H_
-
-/* Macros for printing using RTE_LOG */
-#define RTE_LOGTYPE_VHOST_CONFIG RTE_LOGTYPE_USER1
-#define RTE_LOGTYPE_VHOST_DATA   RTE_LOGTYPE_USER2
-#define RTE_LOGTYPE_VHOST_PORT   RTE_LOGTYPE_USER3
-
-/*
- * Device linked list structure for data path.
- */
-struct virtio_net_data_ll
-{
-	struct virtio_net          *dev;   /* Pointer to device created by configuration core. */
-	struct virtio_net_data_ll  *next;  /* Pointer to next device in linked list. */
-};
-
-/*
- * Structure containing data core specific information.
- */
-struct lcore_ll_info
-{
-	struct virtio_net_data_ll    *ll_root_free; 	/* Pointer to head in free linked list. */
-	struct virtio_net_data_ll    *ll_root_used;	    /* Pointer to head of used linked list. */
-	uint32_t                      device_num;       /* Number of devices on lcore. */
-	volatile  uint8_t             dev_removal_flag; /* Flag to synchronize device removal. */
-};
-
-struct lcore_info
-{
-	struct lcore_ll_info	*lcore_ll;	/* Pointer to data core specific lcore_ll_info struct */
-};
-#endif /* _MAIN_H_ */
diff --git a/examples/vhost_xen/vhost_monitor.c b/examples/vhost_xen/vhost_monitor.c
deleted file mode 100644
index fb9606b..0000000
--- a/examples/vhost_xen/vhost_monitor.c
+++ /dev/null
@@ -1,595 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdlib.h>
-#include <stdio.h>
-#include <dirent.h>
-#include <unistd.h>
-#include <sys/eventfd.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-#include <linux/virtio_ring.h>
-#include <linux/virtio_pci.h>
-#include <linux/virtio_net.h>
-
-#include <rte_ethdev.h>
-#include <rte_log.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-
-#include "virtio-net.h"
-#include "xen_vhost.h"
-
-struct virtio_watch {
-	struct xs_handle *xs;
-	int watch_fd;
-};
-
-
-/* device ops to add/remove device to/from data core. */
-static struct virtio_net_device_ops const *notify_ops;
-
-/* root address of the linked list in the configuration core. */
-static struct virtio_net_config_ll *ll_root = NULL;
-
-/* root address of VM. */
-static struct xen_guestlist guest_root;
-
-static struct virtio_watch watch;
-
-static void
-vq_vring_init(struct vhost_virtqueue *vq, unsigned int num, uint8_t *p,
-	unsigned long align)
-{
-	vq->size = num;
-	vq->desc = (struct vring_desc *) p;
-	vq->avail = (struct vring_avail *) (p +
-		num * sizeof(struct vring_desc));
-	vq->used = (void *)
-		RTE_ALIGN_CEIL( (uintptr_t)(&vq->avail->ring[num]), align);
-
-}
-
-static int
-init_watch(void)
-{
-	struct xs_handle *xs;
-	int ret;
-	int fd;
-
-	/* get a connection to the daemon */
-	xs = xs_daemon_open();
-	if (xs == NULL) {
-		RTE_LOG(ERR, XENHOST, "xs_daemon_open failed\n");
-		return -1;
-	}
-
-	ret = xs_watch(xs, "/local/domain", "mytoken");
-	if (ret == 0) {
-		RTE_LOG(ERR, XENHOST, "%s: xs_watch failed\n", __func__);
-		xs_daemon_close(xs);
-		return -1;
-	}
-
-	/* We are notified of read availability on the watch via the file descriptor. */
-	fd = xs_fileno(xs);
-	watch.xs = xs;
-	watch.watch_fd = fd;
-
-	TAILQ_INIT(&guest_root);
-	return 0;
-}
-
-static struct xen_guest *
-get_xen_guest(int dom_id)
-{
-	struct xen_guest *guest = NULL;
-
-	TAILQ_FOREACH(guest, &guest_root, next) {
-		if(guest->dom_id == dom_id)
-			return guest;
-	}
-
-	return NULL;
-}
-
-
-static struct xen_guest *
-add_xen_guest(int32_t dom_id)
-{
-	struct xen_guest *guest = NULL;
-
-	if ((guest = get_xen_guest(dom_id)) != NULL)
-		return guest;
-
-	guest = calloc(1, sizeof(struct xen_guest));
-	if (guest) {
-		RTE_LOG(ERR, XENHOST, "  %s: return newly created guest with %d rings\n", __func__, guest->vring_num);
-		TAILQ_INSERT_TAIL(&guest_root, guest, next);
-		guest->dom_id = dom_id;
-	}
-
-	return guest;
-}
-
-static void
-cleanup_device(struct virtio_net_config_ll *ll_dev)
-{
-	if (ll_dev == NULL)
-		return;
-	if (ll_dev->dev.virtqueue_rx) {
-		rte_free(ll_dev->dev.virtqueue_rx);
-		ll_dev->dev.virtqueue_rx = NULL;
-	}
-	if (ll_dev->dev.virtqueue_tx) {
-		rte_free(ll_dev->dev.virtqueue_tx);
-		ll_dev->dev.virtqueue_tx = NULL;
-	}
-	free(ll_dev);
-}
-
-/*
- * Add entry containing a device to the device configuration linked list.
- */
-static void
-add_config_ll_entry(struct virtio_net_config_ll *new_ll_dev)
-{
-	struct virtio_net_config_ll *ll_dev = ll_root;
-
-	/* If ll_dev == NULL then this is the first device so go to else */
-	if (ll_dev) {
-		/* If the 1st device_id != 0 then we insert our device here. */
-		if (ll_dev->dev.device_fh != 0)	{
-			new_ll_dev->dev.device_fh = 0;
-			new_ll_dev->next = ll_dev;
-			ll_root = new_ll_dev;
-		} else {
-			/* increment through the ll until we find un unused device_id,
-			 * insert the device at that entry
-			 */
-			while ((ll_dev->next != NULL) && (ll_dev->dev.device_fh == (ll_dev->next->dev.device_fh - 1)))
-				ll_dev = ll_dev->next;
-
-			new_ll_dev->dev.device_fh = ll_dev->dev.device_fh + 1;
-			new_ll_dev->next = ll_dev->next;
-			ll_dev->next = new_ll_dev;
-		}
-	} else {
-		ll_root = new_ll_dev;
-		ll_root->dev.device_fh = 0;
-	}
-}
-
-
-/*
- * Remove an entry from the device configuration linked list.
- */
-static struct virtio_net_config_ll *
-rm_config_ll_entry(struct virtio_net_config_ll *ll_dev, struct virtio_net_config_ll *ll_dev_last)
-{
-	/* First remove the device and then clean it up. */
-	if (ll_dev == ll_root) {
-		ll_root = ll_dev->next;
-		cleanup_device(ll_dev);
-		return ll_root;
-	} else {
-		ll_dev_last->next = ll_dev->next;
-		cleanup_device(ll_dev);
-		return ll_dev_last->next;
-	}
-}
-
-/*
- * Retrieves an entry from the devices configuration linked list.
- */
-static struct virtio_net_config_ll *
-get_config_ll_entry(unsigned int virtio_idx, unsigned int dom_id)
-{
-	struct virtio_net_config_ll *ll_dev = ll_root;
-
-	/* Loop through linked list until the dom_id is found. */
-	while (ll_dev != NULL) {
-		if (ll_dev->dev.dom_id == dom_id && ll_dev->dev.virtio_idx == virtio_idx)
-			return ll_dev;
-		ll_dev = ll_dev->next;
-	}
-
-	return NULL;
-}
-
-/*
- * Initialise all variables in device structure.
- */
-static void
-init_dev(struct virtio_net *dev)
-{
-	RTE_SET_USED(dev);
-}
-
-
-static struct
-virtio_net_config_ll *new_device(unsigned int virtio_idx, struct xen_guest *guest)
-{
-	struct virtio_net_config_ll *new_ll_dev;
-	struct vhost_virtqueue *virtqueue_rx, *virtqueue_tx;
-	size_t size, vq_ring_size, vq_size = VQ_DESC_NUM;
-	void *vq_ring_virt_mem;
-	uint64_t gpa;
-	uint32_t i;
-
-	/* Setup device and virtqueues. */
-	new_ll_dev   = calloc(1, sizeof(struct virtio_net_config_ll));
-	virtqueue_rx = rte_zmalloc(NULL, sizeof(struct vhost_virtqueue), RTE_CACHE_LINE_SIZE);
-	virtqueue_tx = rte_zmalloc(NULL, sizeof(struct vhost_virtqueue), RTE_CACHE_LINE_SIZE);
-	if (new_ll_dev == NULL || virtqueue_rx == NULL || virtqueue_tx == NULL)
-		goto err;
-
-	new_ll_dev->dev.virtqueue_rx = virtqueue_rx;
-	new_ll_dev->dev.virtqueue_tx = virtqueue_tx;
-	new_ll_dev->dev.dom_id       = guest->dom_id;
-	new_ll_dev->dev.virtio_idx   = virtio_idx;
-	/* Initialise device and virtqueues. */
-	init_dev(&new_ll_dev->dev);
-
-	size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN);
-	vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
-	(void)vq_ring_size;
-
-	vq_ring_virt_mem = guest->vring[virtio_idx].rxvring_addr;
-	vq_vring_init(virtqueue_rx, vq_size, vq_ring_virt_mem, VIRTIO_PCI_VRING_ALIGN);
-	virtqueue_rx->size = vq_size;
-	virtqueue_rx->vhost_hlen = sizeof(struct virtio_net_hdr);
-
-	vq_ring_virt_mem = guest->vring[virtio_idx].txvring_addr;
-	vq_vring_init(virtqueue_tx, vq_size, vq_ring_virt_mem, VIRTIO_PCI_VRING_ALIGN);
-	virtqueue_tx->size = vq_size;
-	memcpy(&new_ll_dev->dev.mac_address, &guest->vring[virtio_idx].addr, sizeof(struct ether_addr));
-
-	/* virtio_memory has to be one per domid */
-	new_ll_dev->dev.mem = malloc(sizeof(struct virtio_memory) + sizeof(struct virtio_memory_regions) * MAX_XENVIRT_MEMPOOL);
-	new_ll_dev->dev.mem->nregions = guest->pool_num;
-	for (i = 0; i < guest->pool_num; i++) {
-		gpa = new_ll_dev->dev.mem->regions[i].guest_phys_address =
-				(uint64_t)((uintptr_t)guest->mempool[i].gva);
-		new_ll_dev->dev.mem->regions[i].guest_phys_address_end =
-				gpa + guest->mempool[i].mempfn_num * getpagesize();
-		new_ll_dev->dev.mem->regions[i].address_offset =
-				(uint64_t)((uintptr_t)guest->mempool[i].hva -
-					(uintptr_t)gpa);
-	}
-
-	new_ll_dev->next = NULL;
-
-	/* Add entry to device configuration linked list. */
-	add_config_ll_entry(new_ll_dev);
-	return new_ll_dev;
-err:
-	free(new_ll_dev);
-	rte_free(virtqueue_rx);
-	rte_free(virtqueue_tx);
-
-	return NULL;
-}
-
-static void
-destroy_guest(struct xen_guest *guest)
-{
-	uint32_t i;
-
-	for (i = 0; i < guest->vring_num; i++)
-		cleanup_vring(&guest->vring[i]);
-	/* clean mempool */
-	for (i = 0; i < guest->pool_num; i++)
-		cleanup_mempool(&guest->mempool[i]);
-	free(guest);
-
-	return;
-}
-
-/*
- * This function will cleanup the device and remove it from device configuration linked list.
- */
-static void
-destroy_device(unsigned int virtio_idx, unsigned int dom_id)
-{
-	struct virtio_net_config_ll *ll_dev_cur_ctx, *ll_dev_last = NULL;
-	struct virtio_net_config_ll *ll_dev_cur = ll_root;
-
-	/* clean virtio device */
-	struct xen_guest *guest = NULL;
-	guest = get_xen_guest(dom_id);
-	if (guest == NULL)
-		return;
-
-	/* Find the linked list entry for the device to be removed. */
-	ll_dev_cur_ctx = get_config_ll_entry(virtio_idx, dom_id);
-	while (ll_dev_cur != NULL) {
-		/* If the device is found or a device that doesn't exist is found then it is removed. */
-		if  (ll_dev_cur == ll_dev_cur_ctx) {
-			if ((ll_dev_cur->dev.flags & VIRTIO_DEV_RUNNING))
-				notify_ops->destroy_device(&(ll_dev_cur->dev));
-			ll_dev_cur = rm_config_ll_entry(ll_dev_cur, ll_dev_last);
-		} else {
-			ll_dev_last = ll_dev_cur;
-			ll_dev_cur = ll_dev_cur->next;
-		}
-	}
-	RTE_LOG(INFO, XENHOST, "  %s guest:%p vring:%p rxvring:%p txvring:%p flag:%p\n",
-		__func__, guest, &guest->vring[virtio_idx], guest->vring[virtio_idx].rxvring_addr, guest->vring[virtio_idx].txvring_addr, guest->vring[virtio_idx].flag);
-	cleanup_vring(&guest->vring[virtio_idx]);
-	guest->vring[virtio_idx].removed = 1;
-	guest->vring_num -= 1;
-}
-
-
-
-
-static void
-watch_unmap_event(void)
-{
-	int i;
-	struct xen_guest *guest  = NULL;
-	bool remove_request;
-
-	TAILQ_FOREACH(guest, &guest_root, next) {
-		for (i = 0; i < MAX_VIRTIO; i++) {
-			if (guest->vring[i].dom_id && guest->vring[i].removed == 0 && *guest->vring[i].flag == 0) {
-				RTE_LOG(INFO, XENHOST, "\n\n");
-				RTE_LOG(INFO, XENHOST, "  #####%s:  (%d, %d) to be removed\n",
-					__func__,
-					guest->vring[i].dom_id,
-					i);
-				destroy_device(i, guest->dom_id);
-				RTE_LOG(INFO, XENHOST, "  %s: DOM %u, vring num: %d\n",
-					__func__,
-					guest->dom_id,
-					guest->vring_num);
-			}
-		}
-	}
-
-_find_next_remove:
-	guest = NULL;
-	remove_request = false;
-	TAILQ_FOREACH(guest, &guest_root, next) {
-		if (guest->vring_num == 0) {
-			remove_request = true;
-			break;
-		}
-	}
-	if (remove_request == true) {
-		TAILQ_REMOVE(&guest_root, guest, next);
-		RTE_LOG(INFO, XENHOST, "  #####%s: destroy guest (%d)\n", __func__, guest->dom_id);
-		destroy_guest(guest);
-		goto _find_next_remove;
-	}
-	return;
-}
-
-/*
- * OK, if the guest starts first, it is ok.
- * if host starts first, it is ok.
- * if guest starts, and has run for sometime, and host stops and restarts,
- * then last_used_idx  0? how to solve this. */
-
-static void virtio_init(void)
-{
-	uint32_t len, e_num;
-	uint32_t i,j;
-	char **dom;
-	char *status;
-	int dom_id;
-	char path[PATH_MAX];
-	char node[PATH_MAX];
-	xs_transaction_t th;
-	struct xen_guest *guest;
-	struct virtio_net_config_ll *net_config;
-	char *end;
-	int val;
-
-	/* init env for watch the node */
-	if (init_watch() < 0)
-		return;
-
-	dom = xs_directory(watch.xs, XBT_NULL, "/local/domain", &e_num);
-
-	for (i = 0; i < e_num; i++) {
-		errno = 0;
-		dom_id = strtol(dom[i], &end, 0);
-		if (errno != 0 || end == NULL || dom_id == 0)
-			continue;
-
-		for (j = 0; j < RTE_MAX_ETHPORTS; j++) {
-			snprintf(node, PATH_MAX, "%s%d", VIRTIO_START, j);
-			snprintf(path, PATH_MAX, XEN_VM_NODE_FMT,
-					dom_id, node);
-
-			th = xs_transaction_start(watch.xs);
-			status = xs_read(watch.xs, th, path, &len);
-			xs_transaction_end(watch.xs, th, false);
-
-			if (status == NULL)
-				break;
-
-			/* if there's any valid virtio device */
-			errno = 0;
-			val = strtol(status, &end, 0);
-			if (errno != 0 || end == NULL || dom_id == 0)
-				val = 0;
-			if (val == 1) {
-				guest = add_xen_guest(dom_id);
-				if (guest == NULL)
-					continue;
-				RTE_LOG(INFO, XENHOST, "  there's a new virtio existed, new a virtio device\n\n");
-
-				RTE_LOG(INFO, XENHOST, "  parse_vringnode dom_id %d virtioidx %d\n",dom_id,j);
-				if (parse_vringnode(guest, j)) {
-					RTE_LOG(ERR, XENHOST, "  there is invalid information in xenstore\n");
-					TAILQ_REMOVE(&guest_root, guest, next);
-					destroy_guest(guest);
-
-					continue;
-				}
-
-				/*if pool_num > 0, then mempool has already been parsed*/
-				if (guest->pool_num == 0 && parse_mempoolnode(guest)) {
-					RTE_LOG(ERR, XENHOST, "  there is error information in xenstore\n");
-					TAILQ_REMOVE(&guest_root, guest, next);
-					destroy_guest(guest);
-					continue;
-				}
-
-				net_config = new_device(j, guest);
-				/* every thing is ready now, added into data core */
-				notify_ops->new_device(&net_config->dev);
-			}
-		}
-	}
-
-	free(dom);
-	return;
-}
-
-void
-virtio_monitor_loop(void)
-{
-	char **vec;
-	xs_transaction_t th;
-	char *buf;
-	unsigned int len;
-	unsigned int dom_id;
-	uint32_t virtio_idx;
-	struct xen_guest *guest;
-	struct virtio_net_config_ll *net_config;
-	enum fieldnames {
-		FLD_NULL = 0,
-		FLD_LOCAL,
-		FLD_DOMAIN,
-		FLD_ID,
-		FLD_CONTROL,
-		FLD_DPDK,
-		FLD_NODE,
-		_NUM_FLD
-	};
-	char *str_fld[_NUM_FLD];
-	char *str;
-	char *end;
-
-	virtio_init();
-	while (1) {
-		watch_unmap_event();
-
-		usleep(50);
-		vec = xs_check_watch(watch.xs);
-
-		if (vec == NULL)
-			continue;
-
-		th = xs_transaction_start(watch.xs);
-
-		buf = xs_read(watch.xs, th, vec[XS_WATCH_PATH],&len);
-		xs_transaction_end(watch.xs, th, false);
-
-		if (buf) {
-			/* theres' some node for vhost existed */
-			if (rte_strsplit(vec[XS_WATCH_PATH], strnlen(vec[XS_WATCH_PATH], PATH_MAX),
-						str_fld, _NUM_FLD, '/') == _NUM_FLD) {
-				if (strstr(str_fld[FLD_NODE], VIRTIO_START)) {
-					errno = 0;
-					str = str_fld[FLD_ID];
-					dom_id = strtoul(str, &end, 0);
-					if (errno != 0 || end == NULL || end == str ) {
-						RTE_LOG(INFO, XENHOST, "invalid domain id\n");
-						continue;
-					}
-
-					errno = 0;
-					str = str_fld[FLD_NODE] + sizeof(VIRTIO_START) - 1;
-					virtio_idx = strtoul(str, &end, 0);
-					if (errno != 0 || end == NULL || end == str
-							|| virtio_idx > MAX_VIRTIO) {
-						RTE_LOG(INFO, XENHOST, "invalid virtio idx\n");
-						continue;
-					}
-					RTE_LOG(INFO, XENHOST, "  #####virtio dev (%d, %d) is started\n", dom_id, virtio_idx);
-
-					guest = add_xen_guest(dom_id);
-					if (guest == NULL)
-						continue;
-					guest->dom_id = dom_id;
-					if (parse_vringnode(guest, virtio_idx)) {
-						RTE_LOG(ERR, XENHOST, "  there is invalid information in xenstore\n");
-						/*guest newly created? guest existed ?*/
-						TAILQ_REMOVE(&guest_root, guest, next);
-						destroy_guest(guest);
-						continue;
-					}
-					/*if pool_num > 0, then mempool has already been parsed*/
-					if (guest->pool_num == 0 && parse_mempoolnode(guest)) {
-						RTE_LOG(ERR, XENHOST, "  there is error information in xenstore\n");
-						TAILQ_REMOVE(&guest_root, guest, next);
-						destroy_guest(guest);
-						continue;
-					}
-
-
-					net_config = new_device(virtio_idx, guest);
-					RTE_LOG(INFO, XENHOST, "  Add to dataplane core\n");
-					notify_ops->new_device(&net_config->dev);
-
-				}
-			}
-		}
-
-		free(vec);
-	}
-	return;
-}
-
-/*
- * Register ops so that we can add/remove device to data core.
- */
-int
-init_virtio_xen(struct virtio_net_device_ops const *const ops)
-{
-	notify_ops = ops;
-	if (xenhost_init())
-		return -1;
-	return 0;
-}
diff --git a/examples/vhost_xen/virtio-net.h b/examples/vhost_xen/virtio-net.h
deleted file mode 100644
index ab69726..0000000
--- a/examples/vhost_xen/virtio-net.h
+++ /dev/null
@@ -1,113 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VIRTIO_NET_H_
-#define _VIRTIO_NET_H_
-
-#include <stdint.h>
-
-#define VQ_DESC_NUM 256
-/* Used to indicate that the device is running on a data core */
-#define VIRTIO_DEV_RUNNING 1
-
-/*
- * Structure contains variables relevant to TX/RX virtqueues.
- */
-struct vhost_virtqueue
-{
-	struct vring_desc  *desc;             /* Virtqueue descriptor ring. */
-	struct vring_avail *avail;            /* Virtqueue available ring. */
-	struct vring_used  *used;             /* Virtqueue used ring. */
-	uint32_t           size;              /* Size of descriptor ring. */
-	uint32_t           vhost_hlen;        /* Vhost header length (varies depending on RX merge buffers. */
-	volatile uint16_t  last_used_idx;     /* Last index used on the available ring */
-	volatile uint16_t  last_used_idx_res; /* Used for multiple devices reserving buffers. */
-} __rte_cache_aligned;
-
-/*
- * Device structure contains all configuration information relating to the device.
- */
-struct virtio_net
-{
-	struct vhost_virtqueue	*virtqueue_tx;	/* Contains all TX virtqueue information. */
-	struct vhost_virtqueue	*virtqueue_rx;	/* Contains all RX virtqueue information. */
-	struct virtio_memory    *mem;           /* QEMU memory and memory region information. */
-	struct ether_addr       mac_address;    /* Device MAC address (Obtained on first TX packet). */
-	uint32_t                flags;          /* Device flags. Only used to check if device is running on data core. */
-	uint32_t                vlan_tag;       /* Vlan tag for device. Currently set to device_id (0-63). */
-	uint32_t                vmdq_rx_q;
-	uint64_t                device_fh;      /* device identifier. */
-	uint16_t                coreid;
-	volatile uint8_t        ready;          /* A device is set as ready if the MAC address has been set. */
-	volatile uint8_t        remove;         /* Device is marked for removal from the data core. */
-	uint32_t                virtio_idx;     /* Index of virtio device */
-	uint32_t                dom_id;         /* Domain id of xen guest */
-} ___rte_cache_aligned;
-
-/*
- * Device linked list structure for configuration.
- */
-struct virtio_net_config_ll
-{
-	struct virtio_net		dev;	/* Virtio device. */
-	struct virtio_net_config_ll	*next; /* Next entry on linked list. */
-};
-
-/*
- * Information relating to memory regions including offsets to addresses in QEMUs memory file.
- */
-struct virtio_memory_regions {
-	uint64_t	guest_phys_address;     /* Base guest physical address of region. */
-	uint64_t	guest_phys_address_end;	/* End guest physical address of region. */
-	uint64_t	memory_size;		/* Size of region. */
-	uint64_t	userspace_address;      /* Base userspace address of region. */
-	uint64_t	address_offset;         /* Offset of region for address translation. */
-};
-
-/*
- * Memory structure includes region and mapping information.
- */
-struct virtio_memory {
-	uint32_t			nregions;	/* Number of memory regions. */
-	struct virtio_memory_regions 	regions[0];	/* Memory region information. */
-};
-
-/*
- * Device operations to add/remove device.
- */
-struct virtio_net_device_ops {
-	int (* new_device)(struct virtio_net *);	/* Add device. */
-	void (* destroy_device)	(volatile struct virtio_net *);	/* Remove device. */
-};
-
-#endif
diff --git a/examples/vhost_xen/xen_vhost.h b/examples/vhost_xen/xen_vhost.h
deleted file mode 100644
index 2fc304c..0000000
--- a/examples/vhost_xen/xen_vhost.h
+++ /dev/null
@@ -1,148 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _XEN_VHOST_H_
-#define _XEN_VHOST_H_
-
-#include <stdint.h>
-
-#include <rte_ether.h>
-
-#include "virtio-net.h"
-
-#define RTE_LOGTYPE_XENHOST RTE_LOGTYPE_USER1
-
-#define XEN_VM_ROOTNODE_FMT  "/local/domain/%d/control/dpdk"
-#define XEN_VM_NODE_FMT      "/local/domain/%d/control/dpdk/%s"
-#define XEN_MEMPOOL_SUFFIX   "mempool_gref"
-#define XEN_RXVRING_SUFFIX   "rx_vring_gref"
-#define XEN_TXVRING_SUFFIX   "tx_vring_gref"
-#define XEN_GVA_SUFFIX       "mempool_va"
-#define XEN_VRINGFLAG_SUFFIX "vring_flag"
-#define XEN_ADDR_SUFFIX      "ether_addr"
-#define VIRTIO_START         "event_type_start_"
-
-#define XEN_GREF_SPLITTOKEN  ','
-
-#define MAX_XENVIRT_MEMPOOL 16
-#define MAX_VIRTIO  32
-#define MAX_GREF_PER_NODE 64  /* 128 MB memory */
-
-#define PAGE_SIZE   4096
-#define PAGE_PFNNUM (PAGE_SIZE / sizeof(uint32_t))
-
-#define XEN_GNTDEV_FNAME "/dev/xen/gntdev"
-
-/* xen grant reference info in one grant node */
-struct xen_gnt {
-	uint32_t gref;	/* grant reference for this node */
-	union {
-		int gref;		/* grant reference */
-		uint32_t pfn_num;	/* guest pfn number of grant reference */
-	} gref_pfn[PAGE_PFNNUM];
-}__attribute__((__packed__));
-
-
-/* structure for mempool or vring node list */
-struct xen_gntnode {
-	uint32_t gnt_num;           /* grant reference number */
-	struct xen_gnt *gnt_info;   /* grant reference info */
-};
-
-
-struct xen_vring {
-	uint32_t dom_id;
-	uint32_t virtio_idx;    /* index of virtio device */
-	void *rxvring_addr;     /* mapped virtual address of rxvring */
-	void *txvring_addr;     /* mapped virtual address of txvring */
-	uint32_t rxpfn_num;     /* number of gpfn for rxvring */
-	uint32_t txpfn_num;	/* number of gpfn for txvring */
-	uint32_t *rxpfn_tbl;    /* array of rxvring gpfn */
-	uint32_t *txpfn_tbl;	/* array of txvring gpfn */
-	uint64_t *rx_pindex;    /* index used to release rx grefs */
-	uint64_t *tx_pindex;    /* index used to release tx grefs */
-	uint64_t  flag_index;
-	uint8_t  *flag; 	/* cleared to zero on guest unmap */
-	struct ether_addr addr; /* ethernet address of virtio device */
-	uint8_t   removed;
-
-};
-
-struct xen_mempool {
-	uint32_t dom_id;      /* guest domain id */
-	uint32_t pool_idx;    /* index of memory pool */
-	void *gva;            /* guest virtual address of mbuf pool */
-	void *hva;            /* host virtual address of mbuf pool */
-	uint32_t mempfn_num;  /* number of gpfn for mbuf pool */
-	uint32_t *mempfn_tbl; /* array of mbuf pool gpfn */
-	uint64_t *pindex;     /* index used to release grefs */
-};
-
-struct xen_guest {
-	TAILQ_ENTRY(xen_guest) next;
-	int32_t dom_id;       /* guest domain id */
-	uint32_t pool_num;    /* number of mbuf pool of the guest */
-	uint32_t vring_num;   /* number of virtio ports of the guest */
-	/* array contain the guest mbuf pool info */
-	struct xen_mempool mempool[MAX_XENVIRT_MEMPOOL];
-	/* array contain the guest rx/tx vring info */
-	struct xen_vring vring[MAX_VIRTIO];
-};
-
-TAILQ_HEAD(xen_guestlist, xen_guest);
-
-int
-parse_mempoolnode(struct xen_guest *guest);
-
-int
-xenhost_init(void);
-
-int
-parse_vringnode(struct xen_guest *guest, uint32_t virtio_idx);
-
-int
-parse_mempoolnode(struct xen_guest *guest);
-
-void
-cleanup_mempool(struct xen_mempool *mempool);
-
-void
-cleanup_vring(struct xen_vring *vring);
-
-void
-virtio_monitor_loop(void);
-
-int
-init_virtio_xen(struct virtio_net_device_ops const * const);
-
-#endif
diff --git a/examples/vhost_xen/xenstore_parse.c b/examples/vhost_xen/xenstore_parse.c
deleted file mode 100644
index ab089f1..0000000
--- a/examples/vhost_xen/xenstore_parse.c
+++ /dev/null
@@ -1,775 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <inttypes.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <sys/mman.h>
-#include <xen/sys/gntalloc.h>
-#include <xen/sys/gntdev.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-
-#include <rte_common.h>
-#include <rte_memory.h>
-#include <rte_eal.h>
-#include <rte_malloc.h>
-#include <rte_string_fns.h>
-#include <rte_log.h>
-#include <rte_debug.h>
-
-#include "xen_vhost.h"
-
-/* xenstore handle */
-static struct xs_handle *xs = NULL;
-
-/* gntdev file descriptor to map grant pages */
-static int d_fd = -1;
-
-/*
- *  The grant node format in xenstore for vring/mpool is like:
- *  idx#_rx_vring_gref = "gref1#, gref2#, gref3#"
- *  idx#_mempool_gref  = "gref1#, gref2#, gref3#"
- *  each gref# is the grant reference for a shared page.
- *  In each shared page, we store the grant_node_item items.
- */
-struct grant_node_item {
-	uint32_t gref;
-	uint32_t pfn;
-} __attribute__((packed));
-
-int cmdline_parse_etheraddr(void *tk, const char *srcbuf,
-	void *res, unsigned ressize);
-
-/* Map grant ref refid at addr_ori*/
-static void *
-xen_grant_mmap(void *addr_ori, int domid, int refid, uint64_t *pindex)
-{
-	struct ioctl_gntdev_map_grant_ref arg;
-	void *addr = NULL;
-	int pg_sz = getpagesize();
-
-	arg.count = 1;
-	arg.refs[0].domid = domid;
-	arg.refs[0].ref = refid;
-
-	int rv = ioctl(d_fd, IOCTL_GNTDEV_MAP_GRANT_REF, &arg);
-	if (rv) {
-		RTE_LOG(ERR, XENHOST, "  %s: (%d,%d) %s (ioctl failed)\n", __func__,
-				domid, refid, strerror(errno));
-		return NULL;
-	}
-
-	if (addr_ori == NULL)
-		addr = mmap(addr_ori, pg_sz, PROT_READ|PROT_WRITE, MAP_SHARED,
-				d_fd, arg.index);
-	else
-		addr = mmap(addr_ori, pg_sz, PROT_READ|PROT_WRITE, MAP_SHARED | MAP_FIXED,
-				d_fd, arg.index);
-
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, XENHOST, "  %s: (%d, %d) %s (map failed)\n", __func__,
-				domid, refid, strerror(errno));
-		return NULL;
-	}
-
-	if (pindex)
-		*pindex = arg.index;
-
-	return addr;
-}
-
-/* Unmap one grant ref, and munmap must be called before this */
-static int
-xen_unmap_grant_ref(uint64_t index)
-{
-	struct ioctl_gntdev_unmap_grant_ref arg;
-	int rv;
-
-	arg.count = 1;
-	arg.index = index;
-	rv = ioctl(d_fd, IOCTL_GNTDEV_UNMAP_GRANT_REF, &arg);
-	if (rv) {
-		RTE_LOG(ERR, XENHOST, "  %s: index 0x%" PRIx64 "unmap failed\n", __func__, index);
-		return -1;
-	}
-	return 0;
-}
-
-/*
- * Reserve a virtual address space.
- * On success, returns the pointer. On failure, returns NULL.
- */
-static void *
-get_xen_virtual(size_t size, size_t page_sz)
-{
-	void *addr;
-	uintptr_t aligned_addr;
-
-	addr = mmap(NULL, size + page_sz, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, XENHOST, "failed get a virtual area\n");
-		return NULL;
-	}
-
-	aligned_addr = RTE_ALIGN_CEIL((uintptr_t)addr, page_sz);
-	munmap(addr, aligned_addr - (uintptr_t)addr);
-	munmap((void *)(aligned_addr + size), page_sz + (uintptr_t)addr - aligned_addr);
-	addr = (void *)(aligned_addr);
-
-	return addr;
-}
-
-static void
-free_xen_virtual(void *addr, size_t size, size_t page_sz __rte_unused)
-{
-	if (addr)
-		munmap(addr, size);
-}
-
-/*
- * Returns val str in xenstore.
- * @param path
- *  Full path string for key
- * @return
- *  Pointer to Val str, NULL on failure
- */
-static char *
-xen_read_node(char *path, uint32_t *len)
-{
-	char *buf;
-
-	buf = xs_read(xs, XBT_NULL, path, len);
-	return buf;
-}
-
-static int
-cal_pagenum(struct xen_gnt *gnt)
-{
-	unsigned int i;
-	/*
-	 * the items in the page are in the format of
-	 * gref#,pfn#,...,gref#,pfn#
-	 * FIXME, 0 is reserved by system, use it as terminator.
-	 */
-	for (i = 0; i < (PAGE_PFNNUM) / 2; i++) {
-		if (gnt->gref_pfn[i * 2].gref <= 0)
-			break;
-	}
-
-	return i;
-}
-
-/* Frees memory allocated to a grant node */
-static void
-xen_free_gntnode(struct xen_gntnode *gntnode)
-{
-	if (gntnode == NULL)
-		return;
-	free(gntnode->gnt_info);
-	free(gntnode);
-}
-
-/*
- * Parse a grant node.
- * @param domid
- *  Guest domain id.
- * @param path
- *  Full path string for a grant node, like for the following (key, val) pair
- *  idx#_mempool_gref = "gref#, gref#, gref#"
- *  path = 'local/domain/domid/control/dpdk/idx#_mempool_gref'
- *  gref# is a shared page contain packed (gref,pfn) entries
- * @return
- *  Returns the pointer to xen_gntnode
- */
-static struct xen_gntnode *
-parse_gntnode(int dom_id, char *path)
-{
-	char **gref_list = NULL;
-	uint32_t i, len, gref_num;
-	void *addr = NULL;
-	char *buf = NULL;
-	struct xen_gntnode *gntnode = NULL;
-	struct xen_gnt *gnt = NULL;
-	int pg_sz = getpagesize();
-	char *end;
-	uint64_t index;
-
-	if ((buf = xen_read_node(path, &len)) == NULL)
-		goto err;
-
-	gref_list = malloc(MAX_GREF_PER_NODE * sizeof(char *));
-	if (gref_list == NULL)
-		goto err;
-
-	gref_num = rte_strsplit(buf, len, gref_list, MAX_GREF_PER_NODE,
-			XEN_GREF_SPLITTOKEN);
-	if (gref_num == 0) {
-		RTE_LOG(ERR, XENHOST, "  %s: invalid grant node format\n", __func__);
-		goto err;
-	}
-
-	gntnode = calloc(1, sizeof(struct xen_gntnode));
-	gnt = calloc(gref_num, sizeof(struct xen_gnt));
-	if (gnt == NULL || gntnode == NULL)
-		goto err;
-
-	for (i = 0; i < gref_num; i++) {
-		errno = 0;
-		gnt[i].gref = strtol(gref_list[i], &end, 0);
-		if (errno != 0 || end == NULL || end == gref_list[i] ||
-			(*end != '\0' &&  *end != XEN_GREF_SPLITTOKEN)) {
-			RTE_LOG(ERR, XENHOST, "  %s: parse grant node item failed\n", __func__);
-			goto err;
-		}
-		addr = xen_grant_mmap(NULL, dom_id, gnt[i].gref, &index);
-		if (addr == NULL) {
-			RTE_LOG(ERR, XENHOST, "  %s: map gref %u failed\n", __func__, gnt[i].gref);
-			goto err;
-		}
-		RTE_LOG(INFO, XENHOST, "      %s: map gref %u to %p\n", __func__, gnt[i].gref, addr);
-		memcpy(gnt[i].gref_pfn, addr, pg_sz);
-		if (munmap(addr, pg_sz)) {
-			RTE_LOG(INFO, XENHOST, "  %s: unmap gref %u failed\n", __func__, gnt[i].gref);
-			goto err;
-		}
-		if (xen_unmap_grant_ref(index)) {
-			RTE_LOG(INFO, XENHOST, "  %s: release gref %u failed\n", __func__, gnt[i].gref);
-			goto err;
-		}
-
-	}
-
-	gntnode->gnt_num  = gref_num;
-	gntnode->gnt_info = gnt;
-
-	free(buf);
-	free(gref_list);
-	return gntnode;
-
-err:
-	free(gnt);
-	free(gntnode);
-	free(gref_list);
-	free(buf);
-	return NULL;
-}
-
-/*
- * This function maps grant node of vring or mbuf pool to a continuous virtual address space,
- * and returns mapped address, pfn array, index array
- * @param gntnode
- *  Pointer to grant node
- * @param domid
- *  Guest domain id
- * @param ppfn
- *  Pointer to pfn array, caller should free this array
- * @param pgs
- *  Pointer to number of pages
- * @param ppindex
- *  Pointer to index array, used to release grefs when to free this node
- * @return
- *  Pointer to mapped virtual address, NULL on failure
- */
-static void *
-map_gntnode(struct xen_gntnode *gntnode, int domid, uint32_t **ppfn, uint32_t *pgs, uint64_t **ppindex)
-{
-	struct xen_gnt *gnt;
-	uint32_t i, j;
-	size_t total_pages = 0;
-	void *addr;
-	uint32_t *pfn;
-	uint64_t *pindex;
-	uint32_t pfn_num = 0;
-	int pg_sz;
-
-	if (gntnode == NULL)
-		return NULL;
-
-	pg_sz = getpagesize();
-	for (i = 0; i < gntnode->gnt_num; i++) {
-		gnt = gntnode->gnt_info + i;
-		total_pages += cal_pagenum(gnt);
-	}
-	if ((addr = get_xen_virtual(total_pages * pg_sz, pg_sz)) == NULL) {
-		RTE_LOG(ERR, XENHOST, "  %s: failed get_xen_virtual\n", __func__);
-		return NULL;
-	}
-	pfn = calloc(total_pages, (size_t)sizeof(uint32_t));
-	pindex = calloc(total_pages, (size_t)sizeof(uint64_t));
-	if (pfn == NULL || pindex == NULL) {
-		free_xen_virtual(addr, total_pages * pg_sz, pg_sz);
-		free(pfn);
-		free(pindex);
-		return NULL;
-	}
-
-	RTE_LOG(INFO, XENHOST, "    %s: total pages:%zu, map to [%p, %p]\n", __func__, total_pages, addr, RTE_PTR_ADD(addr, total_pages * pg_sz - 1));
-	for (i = 0; i < gntnode->gnt_num; i++) {
-		gnt = gntnode->gnt_info + i;
-		for (j = 0; j < (PAGE_PFNNUM) / 2; j++) {
-			if ((gnt->gref_pfn[j * 2].gref) <= 0)
-				goto _end;
-			/*alternative: batch map, or through libxc*/
-			if (xen_grant_mmap(RTE_PTR_ADD(addr, pfn_num * pg_sz),
-					domid,
-					gnt->gref_pfn[j * 2].gref,
-					&pindex[pfn_num]) == NULL) {
-				goto mmap_failed;
-			}
-			pfn[pfn_num] = gnt->gref_pfn[j * 2 + 1].pfn_num;
-			pfn_num++;
-		}
-	}
-
-mmap_failed:
-	if (pfn_num)
-		munmap(addr, pfn_num * pg_sz);
-	for (i = 0; i < pfn_num; i++) {
-		xen_unmap_grant_ref(pindex[i]);
-	}
-	free(pindex);
-	free(pfn);
-	return NULL;
-
-_end:
-	if (ppindex)
-		*ppindex = pindex;
-	else
-		free(pindex);
-	if (ppfn)
-		*ppfn = pfn;
-	else
-		free(pfn);
-	if (pgs)
-		*pgs = total_pages;
-
-	return addr;
-}
-
-static int
-parse_mpool_va(struct xen_mempool *mempool)
-{
-	char path[PATH_MAX] = {0};
-	char *buf;
-	uint32_t len;
-	char *end;
-	int ret = -1;
-
-	errno = 0;
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_GVA_SUFFIX,
-		mempool->dom_id, mempool->pool_idx);
-
-	if((buf = xen_read_node(path, &len)) == NULL)
-		goto out;
-	mempool->gva = (void *)strtoul(buf, &end, 16);
-	if (errno != 0 || end == NULL || end == buf || *end != '\0') {
-		mempool->gva = NULL;
-		goto out;
-	}
-	ret = 0;
-out:
-	free(buf);
-	return ret;
-}
-
-/*
- * map mbuf pool
- */
-static int
-map_mempoolnode(struct xen_gntnode *gntnode,
-			struct xen_mempool *mempool)
-{
-	if (gntnode == NULL || mempool == NULL)
-		return -1;
-
-	mempool->hva =
-		map_gntnode(gntnode, mempool->dom_id, &mempool->mempfn_tbl, &mempool->mempfn_num, &mempool->pindex);
-
-	RTE_LOG(INFO, XENHOST, "  %s: map mempool at %p\n", __func__, (void *)mempool->hva);
-	if (mempool->hva)
-		return 0;
-	else {
-		return -1;
-	}
-}
-
-void
-cleanup_mempool(struct xen_mempool *mempool)
-{
-	int pg_sz = getpagesize();
-	uint32_t i;
-
-	if (mempool->hva)
-		munmap(mempool->hva, mempool->mempfn_num * pg_sz);
-	mempool->hva = NULL;
-
-	if (mempool->pindex) {
-		RTE_LOG(INFO, XENHOST, "  %s: unmap dom %02u mempool%02u %u grefs\n",
-			__func__,
-			mempool->dom_id,
-			mempool->pool_idx,
-			mempool->mempfn_num);
-		for (i = 0; i < mempool->mempfn_num; i ++) {
-			xen_unmap_grant_ref(mempool->pindex[i]);
-		}
-	}
-	mempool->pindex = NULL;
-
-	free(mempool->mempfn_tbl);
-	mempool->mempfn_tbl = NULL;
-}
-
-/*
- * process mempool node idx#_mempool_gref, idx = 0, 1, 2...
- * until we encounter a node that doesn't exist.
- */
-int
-parse_mempoolnode(struct xen_guest *guest)
-{
-	uint32_t i, len;
-	char path[PATH_MAX] = {0};
-	struct xen_gntnode *gntnode = NULL;
-	struct xen_mempool *mempool = NULL;
-	char *buf;
-
-	bzero(&guest->mempool, MAX_XENVIRT_MEMPOOL * sizeof(guest->mempool[0]));
-	guest->pool_num = 0;
-
-	while (1) {
-		/* check if null terminated */
-		snprintf(path, sizeof(path),
-			XEN_VM_ROOTNODE_FMT"/%d_"XEN_MEMPOOL_SUFFIX,
-			guest->dom_id,
-			guest->pool_num);
-
-		if ((buf = xen_read_node(path, &len)) != NULL) {
-			/* this node exists */
-			free(buf);
-		} else {
-			if (guest->pool_num == 0) {
-				RTE_LOG(ERR, PMD, "no mempool found\n");
-				return -1;
-			}
-			break;
-		}
-
-		mempool = &guest->mempool[guest->pool_num];
-		mempool->dom_id = guest->dom_id;
-		mempool->pool_idx = guest->pool_num;
-
-		RTE_LOG(INFO, XENHOST, "  %s: mempool %u parse gntnode %s\n", __func__, guest->pool_num, path);
-		gntnode = parse_gntnode(guest->dom_id, path);
-		if (gntnode == NULL)
-			goto err;
-
-		if (parse_mpool_va(mempool))
-			goto err;
-
-		RTE_LOG(INFO, XENHOST, "  %s: mempool %u map gntnode %s\n", __func__, guest->pool_num, path);
-		if (map_mempoolnode(gntnode, mempool))
-			goto err;
-
-		xen_free_gntnode(gntnode);
-		guest->pool_num++;
-	}
-
-	return 0;
-err:
-	if (gntnode)
-		xen_free_gntnode(gntnode);
-	for (i = 0; i <  MAX_XENVIRT_MEMPOOL ; i++) {
-		cleanup_mempool(&guest->mempool[i]);
-	}
-	/* reinitialise mempool */
-	bzero(&guest->mempool, MAX_XENVIRT_MEMPOOL * sizeof(guest->mempool[0]));
-	return -1;
-}
-
-static int
-xen_map_vringflag(struct xen_vring *vring)
-{
-	char path[PATH_MAX] = {0};
-	char *buf;
-	uint32_t len,gref;
-	int pg_sz = getpagesize();
-	char *end;
-
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_VRINGFLAG_SUFFIX,
-		vring->dom_id, vring->virtio_idx);
-
-	if((buf = xen_read_node(path, &len)) == NULL)
-		goto err;
-
-	errno = 0;
-	gref = strtol(buf, &end, 0);
-	if (errno != 0 || end == NULL || end == buf) {
-		goto err;
-	}
-	vring->flag = xen_grant_mmap(0, vring->dom_id, gref, &vring->flag_index);
-	if (vring->flag == NULL || *vring->flag == 0)
-		goto err;
-
-	free(buf);
-	return 0;
-err:
-	free(buf);
-	if (vring->flag) {
-		munmap(vring->flag, pg_sz);
-		vring->flag = NULL;
-		xen_unmap_grant_ref(vring->flag_index);
-	}
-	return -1;
-}
-
-
-static int
-xen_map_rxvringnode(struct xen_gntnode *gntnode,
-				struct xen_vring *vring)
-{
-	vring->rxvring_addr =
-		map_gntnode(gntnode, vring->dom_id, &vring->rxpfn_tbl, &vring->rxpfn_num, &vring->rx_pindex);
-	RTE_LOG(INFO, XENHOST, "  %s: map rx vring at %p\n", __func__, (void *)vring->rxvring_addr);
-	if (vring->rxvring_addr)
-		return 0;
-	else
-		return -1;
-}
-
-static int
-xen_map_txvringnode(struct xen_gntnode *gntnode,
-				struct xen_vring *vring)
-{
-	vring->txvring_addr =
-		map_gntnode(gntnode, vring->dom_id, &vring->txpfn_tbl, &vring->txpfn_num, &vring->tx_pindex);
-	RTE_LOG(INFO, XENHOST, "  %s: map tx vring at %p\n", __func__, (void *)vring->txvring_addr);
-	if (vring->txvring_addr)
-		return 0;
-	else
-		return -1;
-}
-
-void
-cleanup_vring(struct xen_vring *vring)
-{
-	int pg_sz = getpagesize();
-	uint32_t i;
-
-	RTE_LOG(INFO, XENHOST, "  %s: cleanup dom %u vring %u\n", __func__, vring->dom_id, vring->virtio_idx);
-	if (vring->rxvring_addr) {
-		munmap(vring->rxvring_addr, vring->rxpfn_num * pg_sz);
-		RTE_LOG(INFO, XENHOST, "  %s: unmap rx vring [%p, %p]\n",
-			__func__,
-			vring->rxvring_addr,
-			RTE_PTR_ADD(vring->rxvring_addr,
-			vring->rxpfn_num * pg_sz - 1));
-	}
-	vring->rxvring_addr = NULL;
-
-
-	if (vring->rx_pindex) {
-		RTE_LOG(INFO, XENHOST, "  %s: unmap rx vring %u grefs\n", __func__, vring->rxpfn_num);
-		for (i = 0; i < vring->rxpfn_num; i++) {
-			xen_unmap_grant_ref(vring->rx_pindex[i]);
-		}
-	}
-	vring->rx_pindex = NULL;
-
-	free(vring->rxpfn_tbl);
-	vring->rxpfn_tbl = NULL;
-
-	if (vring->txvring_addr) {
-		munmap(vring->txvring_addr, vring->txpfn_num * pg_sz);
-		RTE_LOG(INFO, XENHOST, "  %s: unmap tx vring [%p, %p]\n",
-			__func__,
-			vring->txvring_addr,
-			RTE_PTR_ADD(vring->txvring_addr,
-			vring->txpfn_num * pg_sz - 1));
-	}
-	vring->txvring_addr = NULL;
-
-	if (vring->tx_pindex) {
-		RTE_LOG(INFO, XENHOST, "  %s: unmap tx vring %u grefs\n", __func__, vring->txpfn_num);
-		for (i = 0; i < vring->txpfn_num; i++) {
-			xen_unmap_grant_ref(vring->tx_pindex[i]);
-		}
-	}
-	vring->tx_pindex = NULL;
-
-	free(vring->txpfn_tbl);
-	vring->txpfn_tbl = NULL;
-
-	if (vring->flag) {
-		if (!munmap((void *)vring->flag, pg_sz))
-			RTE_LOG(INFO, XENHOST, "  %s: unmap flag page at %p\n", __func__, vring->flag);
-		if (!xen_unmap_grant_ref(vring->flag_index))
-			RTE_LOG(INFO, XENHOST, "  %s: release flag ref index 0x%" PRIx64 "\n", __func__, vring->flag_index);
-	}
-	vring->flag = NULL;
-	return;
-}
-
-
-
-static int
-xen_parse_etheraddr(struct xen_vring *vring)
-{
-	char path[PATH_MAX] = {0};
-	char *buf;
-	uint32_t len;
-	int ret = -1;
-
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_ADDR_SUFFIX,
-		vring->dom_id, vring->virtio_idx);
-
-	if ((buf = xen_read_node(path, &len)) == NULL)
-		goto out;
-
-	if (cmdline_parse_etheraddr(NULL, buf, &vring->addr,
-			sizeof(vring->addr)) < 0)
-		goto out;
-	ret = 0;
-out:
-	free(buf);
-	return ret;
-}
-
-
-int
-parse_vringnode(struct xen_guest *guest, uint32_t virtio_idx)
-{
-	char path[PATH_MAX] = {0};
-	struct xen_gntnode *rx_gntnode = NULL;
-	struct xen_gntnode *tx_gntnode = NULL;
-	struct xen_vring *vring = NULL;
-
-	/*check if null terminated */
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_RXVRING_SUFFIX,
-		guest->dom_id,
-		virtio_idx);
-
-	RTE_LOG(INFO, XENHOST, "  %s: virtio %u parse rx gntnode %s\n", __func__, virtio_idx, path);
-	rx_gntnode = parse_gntnode(guest->dom_id, path);
-	if (rx_gntnode == NULL)
-		goto err;
-
-	/*check if null terminated */
-	snprintf(path, sizeof(path),
-		XEN_VM_ROOTNODE_FMT"/%d_"XEN_TXVRING_SUFFIX,
-		guest->dom_id,
-		virtio_idx);
-
-	RTE_LOG(INFO, XENHOST, "  %s: virtio %u parse tx gntnode %s\n", __func__, virtio_idx, path);
-	tx_gntnode = parse_gntnode(guest->dom_id, path);
-	if (tx_gntnode == NULL)
-		goto err;
-
-	vring = &guest->vring[virtio_idx];
-	bzero(vring, sizeof(*vring));
-	vring->dom_id = guest->dom_id;
-	vring->virtio_idx = virtio_idx;
-
-	if (xen_parse_etheraddr(vring) != 0)
-		goto err;
-
-	RTE_LOG(INFO, XENHOST, "  %s: virtio %u map rx gntnode %s\n", __func__, virtio_idx, path);
-	if (xen_map_rxvringnode(rx_gntnode, vring) != 0)
-		goto err;
-
-	RTE_LOG(INFO, XENHOST, "  %s: virtio %u map tx gntnode %s\n", __func__, virtio_idx, path);
-	if (xen_map_txvringnode(tx_gntnode, vring) != 0)
-		goto err;
-
-	if (xen_map_vringflag(vring) != 0)
-		goto err;
-
-	guest->vring_num++;
-
-	xen_free_gntnode(rx_gntnode);
-	xen_free_gntnode(tx_gntnode);
-
-	return 0;
-
-err:
-	if (rx_gntnode)
-		xen_free_gntnode(rx_gntnode);
-	if (tx_gntnode)
-		xen_free_gntnode(tx_gntnode);
-	if (vring) {
-		cleanup_vring(vring);
-		bzero(vring, sizeof(*vring));
-	}
-	return -1;
-}
-
-/*
- * Open xen grant dev driver
- * @return
- *  0 on success, -1 on failure.
- */
-static int
-xen_grant_init(void)
-{
-	d_fd = open(XEN_GNTDEV_FNAME, O_RDWR);
-
-	return d_fd == -1? (-1): (0);
-}
-
-/*
- * Initialise xenstore handle and open grant dev driver.
- * @return
- *  0 on success, -1 on failure.
- */
-int
-xenhost_init(void)
-{
-	xs = xs_daemon_open();
-	if (xs == NULL) {
-		rte_panic("failed initialize xen daemon handler");
-		return -1;
-	}
-	if (xen_grant_init())
-		return -1;
-	return 0;
-}
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 2/6] net/xenvirt: remove
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
                   ` (2 preceding siblings ...)
  2017-08-30 18:10 ` [PATCH 2/6] net/xenvirt: remove Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-09-04 14:25   ` Bruce Richardson
  2017-09-04 14:25   ` Bruce Richardson
  2017-08-30 18:10 ` [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
                   ` (6 subsequent siblings)
  10 siblings, 2 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
	shahafs, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 MAINTAINERS                                     |   2 -
 app/test-pmd/Makefile                           |   4 -
 app/test-pmd/testpmd.c                          |  12 -
 config/common_base                              |   5 -
 config/defconfig_arm-armv7a-linuxapp-gcc        |   1 -
 doc/guides/nics/features/xenvirt.ini            |   6 -
 drivers/net/Makefile                            |   2 -
 drivers/net/xenvirt/Makefile                    |  57 --
 drivers/net/xenvirt/rte_eth_xenvirt.c           | 766 ------------------------
 drivers/net/xenvirt/rte_eth_xenvirt.h           |  61 --
 drivers/net/xenvirt/rte_eth_xenvirt_version.map |   7 -
 drivers/net/xenvirt/rte_mempool_gntalloc.c      | 295 ---------
 drivers/net/xenvirt/rte_xen_lib.c               | 454 --------------
 drivers/net/xenvirt/rte_xen_lib.h               | 116 ----
 drivers/net/xenvirt/virtio_logs.h               |  70 ---
 drivers/net/xenvirt/virtqueue.h                 | 273 ---------
 mk/rte.app.mk                                   |   1 -
 pkg/dpdk.spec                                   |   3 -
 18 files changed, 2135 deletions(-)
 delete mode 100644 doc/guides/nics/features/xenvirt.ini
 delete mode 100644 drivers/net/xenvirt/Makefile
 delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
 delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
 delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
 delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
 delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
 delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
 delete mode 100644 drivers/net/xenvirt/virtio_logs.h
 delete mode 100644 drivers/net/xenvirt/virtqueue.h

diff --git a/MAINTAINERS b/MAINTAINERS
index fe6c6db..003e72e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -194,9 +194,7 @@ M: Jianfeng Tan <jianfeng.tan@intel.com>
 F: lib/librte_eal/linuxapp/xen_dom0/
 F: lib/librte_eal/linuxapp/eal/*xen*
 F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
-F: drivers/net/xenvirt/
 F: doc/guides/xen/
-F: doc/guides/nics/features/xenvirt.ini
 
 FreeBSD EAL (with overlaps)
 M: Bruce Richardson <bruce.richardson@intel.com>
diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index c36be19..b6e80dd 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -77,10 +77,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
 LDLIBS += -lrte_pmd_bnxt
 endif
 
-ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
-LDLIBS += -lrte_pmd_xenvirt
-endif
-
 endif
 
 CFLAGS_cmdline.o := -D_GNU_SOURCE
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 7d40139..f8d02ae 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -76,9 +76,6 @@
 #ifdef RTE_LIBRTE_IXGBE_PMD
 #include <rte_pmd_ixgbe.h>
 #endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-#include <rte_eth_xenvirt.h>
-#endif
 #ifdef RTE_LIBRTE_PDUMP
 #include <rte_pdump.h>
 #endif
@@ -497,15 +494,6 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
 
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
-		(unsigned) mb_mempool_cache,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL,
-		socket_id, 0);
-#endif
-
 	/* if the former XEN allocation failed fall back to normal allocation */
 	if (rte_mp == NULL) {
 		if (mp_anon != 0) {
diff --git a/config/common_base b/config/common_base
index 5e97a08..93928b6 100644
--- a/config/common_base
+++ b/config/common_base
@@ -411,11 +411,6 @@ CONFIG_RTE_LIBRTE_AVP_DEBUG_BUFFERS=n
 CONFIG_RTE_LIBRTE_PMD_TAP=n
 
 #
-# Compile Xen PMD
-#
-CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
-
-#
 # Compile null PMD
 #
 CONFIG_RTE_LIBRTE_PMD_NULL=y
diff --git a/config/defconfig_arm-armv7a-linuxapp-gcc b/config/defconfig_arm-armv7a-linuxapp-gcc
index 00bc2ab..6628567 100644
--- a/config/defconfig_arm-armv7a-linuxapp-gcc
+++ b/config/defconfig_arm-armv7a-linuxapp-gcc
@@ -76,7 +76,6 @@ CONFIG_RTE_LIBRTE_I40E_PMD=n
 CONFIG_RTE_LIBRTE_IXGBE_PMD=n
 CONFIG_RTE_LIBRTE_MLX4_PMD=n
 CONFIG_RTE_LIBRTE_VMXNET3_PMD=n
-CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
 CONFIG_RTE_LIBRTE_PMD_BNX2X=n
 CONFIG_RTE_LIBRTE_QEDE_PMD=n
 CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
diff --git a/doc/guides/nics/features/xenvirt.ini b/doc/guides/nics/features/xenvirt.ini
deleted file mode 100644
index 8ab5f46..0000000
--- a/doc/guides/nics/features/xenvirt.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-;
-; Supported features of the 'xenvirt' network poll mode driver.
-;
-; Refer to default.ini for the full list of available PMD features.
-;
-[Features]
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index d33c959..0e00cd1 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -97,8 +97,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
 DEPDIRS-virtio = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
 DEPDIRS-vmxnet3 = $(core-libs)
-DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
-DEPDIRS-xenvirt = $(core-libs) librte_cmdline
 
 ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_KNI) += kni
diff --git a/drivers/net/xenvirt/Makefile b/drivers/net/xenvirt/Makefile
deleted file mode 100644
index 8b4b8f0..0000000
--- a/drivers/net/xenvirt/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-#
-# library name
-#
-LIB = librte_pmd_xenvirt.a
-
-CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS)
-LDLIBS += -lxenstore
-
-EXPORT_MAP := rte_eth_xenvirt_version.map
-
-LIBABIVER := 1
-
-#
-# all source are stored in SRCS-y
-#
-SRCS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += rte_eth_xenvirt.c rte_mempool_gntalloc.c rte_xen_lib.c
-
-#
-# Export include files
-#
-SYMLINK-y-include += rte_eth_xenvirt.h
-
-include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
deleted file mode 100644
index e404b77..0000000
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ /dev/null
@@ -1,766 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#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
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-#include <linux/virtio_ring.h>
-
-#include <rte_mbuf.h>
-#include <rte_ethdev.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-#include <rte_string_fns.h>
-#include <rte_vdev.h>
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
-#include "rte_xen_lib.h"
-#include "virtqueue.h"
-#include "rte_eth_xenvirt.h"
-
-#define VQ_DESC_NUM 256
-#define VIRTIO_MBUF_BURST_SZ 64
-
-/* virtio_idx is increased after new device is created.*/
-static int virtio_idx = 0;
-
-static struct rte_eth_link pmd_link = {
-		.link_speed = ETH_SPEED_NUM_10G,
-		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = ETH_LINK_DOWN,
-		.link_autoneg = ETH_LINK_SPEED_FIXED
-};
-
-static void
-eth_xenvirt_free_queues(struct rte_eth_dev *dev);
-
-static uint16_t
-eth_xenvirt_rx(void *q, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
-{
-	struct virtqueue *rxvq = q;
-	struct rte_mbuf *rxm, *new_mbuf;
-	uint16_t nb_used, num;
-	uint32_t len[VIRTIO_MBUF_BURST_SZ];
-	uint32_t i;
-	struct pmd_internals *pi = rxvq->internals;
-
-	nb_used = VIRTQUEUE_NUSED(rxvq);
-
-	rte_smp_rmb();
-	num = (uint16_t)(likely(nb_used <= nb_pkts) ? nb_used : nb_pkts);
-	num = (uint16_t)(likely(num <= VIRTIO_MBUF_BURST_SZ) ? num : VIRTIO_MBUF_BURST_SZ);
-	if (unlikely(num == 0)) return 0;
-
-	num = virtqueue_dequeue_burst(rxvq, rx_pkts, len, num);
-	PMD_RX_LOG(DEBUG, "used:%d dequeue:%d\n", nb_used, num);
-	for (i = 0; i < num ; i ++) {
-		rxm = rx_pkts[i];
-		PMD_RX_LOG(DEBUG, "packet len:%d\n", len[i]);
-		rxm->next = NULL;
-		rxm->data_off = RTE_PKTMBUF_HEADROOM;
-		rxm->data_len = (uint16_t)(len[i] - sizeof(struct virtio_net_hdr));
-		rxm->nb_segs = 1;
-		rxm->port = pi->port_id;
-		rxm->pkt_len  = (uint32_t)(len[i] - sizeof(struct virtio_net_hdr));
-	}
-	/* allocate new mbuf for the used descriptor */
-	while (likely(!virtqueue_full(rxvq))) {
-		new_mbuf = rte_mbuf_raw_alloc(rxvq->mpool);
-		if (unlikely(new_mbuf == NULL)) {
-			break;
-		}
-		if (unlikely(virtqueue_enqueue_recv_refill(rxvq, new_mbuf))) {
-			rte_pktmbuf_free_seg(new_mbuf);
-			break;
-		}
-	}
-	pi->eth_stats.ipackets += num;
-	return num;
-}
-
-static uint16_t
-eth_xenvirt_tx(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
-	struct virtqueue *txvq = tx_queue;
-	struct rte_mbuf *txm;
-	uint16_t nb_used, nb_tx, num, i;
-	int error;
-	uint32_t len[VIRTIO_MBUF_BURST_SZ];
-	struct rte_mbuf *snd_pkts[VIRTIO_MBUF_BURST_SZ];
-	struct pmd_internals *pi = txvq->internals;
-
-	nb_tx = 0;
-
-	if (unlikely(nb_pkts == 0))
-		return 0;
-
-	PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts);
-	nb_used = VIRTQUEUE_NUSED(txvq);
-
-	rte_smp_rmb();
-
-	num = (uint16_t)(likely(nb_used <= VIRTIO_MBUF_BURST_SZ) ? nb_used : VIRTIO_MBUF_BURST_SZ);
-	num = virtqueue_dequeue_burst(txvq, snd_pkts, len, num);
-
-	for (i = 0; i < num ; i ++) {
-		/* mergable not supported, one segment only */
-		rte_pktmbuf_free_seg(snd_pkts[i]);
-	}
-
-	while (nb_tx < nb_pkts) {
-		if (likely(!virtqueue_full(txvq))) {
-		/* TODO drop tx_pkts if it contains multiple segments */
-			txm = tx_pkts[nb_tx];
-			error = virtqueue_enqueue_xmit(txvq, txm);
-			if (unlikely(error)) {
-				if (error == ENOSPC)
-					PMD_TX_LOG(ERR, "virtqueue_enqueue Free count = 0\n");
-				else if (error == EMSGSIZE)
-					PMD_TX_LOG(ERR, "virtqueue_enqueue Free count < 1\n");
-				else
-					PMD_TX_LOG(ERR, "virtqueue_enqueue error: %d\n", error);
-				break;
-			}
-			nb_tx++;
-		} else {
-			PMD_TX_LOG(ERR, "No free tx descriptors to transmit\n");
-			/* virtqueue_notify not needed in our para-virt solution */
-			break;
-		}
-	}
-	pi->eth_stats.opackets += nb_tx;
-	return nb_tx;
-}
-
-static int
-eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
-{
-	RTE_LOG(ERR, PMD, "%s\n", __func__);
-	return 0;
-}
-
-/*
- * Create a shared page between guest and host.
- * Host monitors this page if it is cleared on unmap, and then
- * do necessary clean up.
- */
-static void
-gntalloc_vring_flag(int vtidx)
-{
-	char key_str[PATH_MAX];
-	char val_str[PATH_MAX];
-	uint32_t gref_tmp;
-	void *ptr;
-
-	if (grefwatch_from_alloc(&gref_tmp, &ptr)) {
-		RTE_LOG(ERR, PMD, "grefwatch_from_alloc error\n");
-		exit(0);
-	}
-
-	*(uint8_t *)ptr = MAP_FLAG;
-	snprintf(val_str, sizeof(val_str), "%u", gref_tmp);
-	snprintf(key_str, sizeof(key_str),
-		DPDK_XENSTORE_PATH"%d"VRING_FLAG_STR, vtidx);
-	xenstore_write(key_str, val_str);
-}
-
-/*
- * Notify host this virtio device is started.
- * Host could start polling this device.
- */
-static void
-dev_start_notify(int vtidx)
-{
-	char key_str[PATH_MAX];
-	char val_str[PATH_MAX];
-
-	RTE_LOG(INFO, PMD, "%s: virtio %d is started\n", __func__, vtidx);
-	gntalloc_vring_flag(vtidx);
-
-	snprintf(key_str, sizeof(key_str), "%s%s%d",
-		DPDK_XENSTORE_PATH, EVENT_TYPE_START_STR,
-			vtidx);
-	snprintf(val_str, sizeof(val_str), "1");
-	xenstore_write(key_str, val_str);
-}
-
-/*
- * Notify host this virtio device is stopped.
- * Host could stop polling this device.
- */
-static void
-dev_stop_notify(int vtidx)
-{
-	RTE_SET_USED(vtidx);
-}
-
-
-static int
-update_mac_address(struct ether_addr *mac_addrs, int vtidx)
-{
-	char key_str[PATH_MAX];
-	char val_str[PATH_MAX];
-	int rv;
-
-	if (mac_addrs == NULL) {
-		RTE_LOG(ERR, PMD, "%s: NULL pointer mac specified\n", __func__);
-		return -1;
-	}
-	rv = snprintf(key_str, sizeof(key_str),
-			DPDK_XENSTORE_PATH"%d_ether_addr", vtidx);
-	if (rv == -1)
-		return rv;
-	rv = snprintf(val_str, sizeof(val_str), "%02x:%02x:%02x:%02x:%02x:%02x",
-			mac_addrs->addr_bytes[0],
-			mac_addrs->addr_bytes[1],
-			mac_addrs->addr_bytes[2],
-			mac_addrs->addr_bytes[3],
-			mac_addrs->addr_bytes[4],
-			mac_addrs->addr_bytes[5]);
-	if (rv == -1)
-		return rv;
-	if (xenstore_write(key_str, val_str))
-		return rv;
-	return 0;
-}
-
-
-static int
-eth_dev_start(struct rte_eth_dev *dev)
-{
-	struct virtqueue *rxvq = dev->data->rx_queues[0];
-	struct virtqueue *txvq = dev->data->tx_queues[0];
-	struct rte_mbuf *m;
-	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
-	int rv;
-
-	dev->data->dev_link.link_status = ETH_LINK_UP;
-	while (!virtqueue_full(rxvq)) {
-		m = rte_mbuf_raw_alloc(rxvq->mpool);
-		if (m == NULL)
-			break;
-		/* Enqueue allocated buffers. */
-		if (virtqueue_enqueue_recv_refill(rxvq, m)) {
-			rte_pktmbuf_free_seg(m);
-			break;
-		}
-	}
-
-	rxvq->internals = pi;
-	txvq->internals = pi;
-
-	rv = update_mac_address(dev->data->mac_addrs, pi->virtio_idx);
-	if (rv)
-		return -1;
-	dev_start_notify(pi->virtio_idx);
-
-	return 0;
-}
-
-static void
-eth_dev_stop(struct rte_eth_dev *dev)
-{
-	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
-
-	dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	dev_stop_notify(pi->virtio_idx);
-}
-
-/*
- * Notify host this virtio device is closed.
- * Host could do necessary clean up to this device.
- */
-static void
-eth_dev_close(struct rte_eth_dev *dev)
-{
-	eth_xenvirt_free_queues(dev);
-}
-
-static void
-eth_dev_info(struct rte_eth_dev *dev,
-		struct rte_eth_dev_info *dev_info)
-{
-	struct pmd_internals *internals = dev->data->dev_private;
-
-	RTE_SET_USED(internals);
-	dev_info->max_mac_addrs = 1;
-	dev_info->max_rx_pktlen = (uint32_t)2048;
-	dev_info->max_rx_queues = (uint16_t)1;
-	dev_info->max_tx_queues = (uint16_t)1;
-	dev_info->min_rx_bufsize = 0;
-}
-
-static void
-eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
-{
-	struct pmd_internals *internals = dev->data->dev_private;
-	if(stats)
-		rte_memcpy(stats, &internals->eth_stats, sizeof(*stats));
-}
-
-static void
-eth_stats_reset(struct rte_eth_dev *dev)
-{
-	struct pmd_internals *internals = dev->data->dev_private;
-	/* Reset software totals */
-	memset(&internals->eth_stats, 0, sizeof(internals->eth_stats));
-}
-
-static void
-eth_queue_release(void *q)
-{
-	rte_free(q);
-}
-
-static int
-eth_link_update(struct rte_eth_dev *dev __rte_unused,
-		int wait_to_complete __rte_unused)
-{
-	return 0;
-}
-
-/*
- * Create shared vring between guest and host.
- * Memory is allocated through grant alloc driver, so it is not physical continuous.
- */
-static void *
-gntalloc_vring_create(int queue_type, uint32_t size, int vtidx)
-{
-	char key_str[PATH_MAX] = {0};
-	char val_str[PATH_MAX] = {0};
-	void *va = NULL;
-	int pg_size;
-	uint32_t pg_num;
-	uint32_t *gref_arr = NULL;
-	phys_addr_t *pa_arr = NULL;
-	uint64_t start_index;
-	int rv;
-
-	pg_size = getpagesize();
-	size    = RTE_ALIGN_CEIL(size, pg_size);
-	pg_num  = size / pg_size;
-
-	gref_arr = calloc(pg_num, sizeof(gref_arr[0]));
-	pa_arr  = calloc(pg_num, sizeof(pa_arr[0]));
-
-	if (gref_arr == NULL || pa_arr == NULL) {
-		RTE_LOG(ERR, PMD, "%s: calloc failed\n", __func__);
-		goto out;
-	}
-
-	va  = gntalloc(size, gref_arr, &start_index);
-	if (va == NULL) {
-		RTE_LOG(ERR, PMD, "%s: gntalloc failed\n", __func__);
-		goto out;
-	}
-
-	if (get_phys_map(va, pa_arr, pg_num, pg_size))
-		goto out;
-
-	/* write in xenstore gref and pfn for each page of vring */
-	if (grant_node_create(pg_num, gref_arr, pa_arr, val_str, sizeof(val_str))) {
-		gntfree(va, size, start_index);
-		va = NULL;
-		goto out;
-	}
-
-	if (queue_type == VTNET_RQ)
-		rv = snprintf(key_str, sizeof(key_str), DPDK_XENSTORE_PATH"%d"RXVRING_XENSTORE_STR, vtidx);
-	else
-		rv = snprintf(key_str, sizeof(key_str), DPDK_XENSTORE_PATH"%d"TXVRING_XENSTORE_STR, vtidx);
-	if (rv == -1 || xenstore_write(key_str, val_str) == -1) {
-		gntfree(va, size, start_index);
-		va = NULL;
-	}
-out:
-	free(pa_arr);
-	free(gref_arr);
-
-	return va;
-}
-
-
-
-static struct virtqueue *
-virtio_queue_setup(struct rte_eth_dev *dev, int queue_type)
-{
-	struct virtqueue *vq = NULL;
-	uint16_t vq_size = VQ_DESC_NUM;
-	int i = 0;
-	char vq_name[VIRTQUEUE_MAX_NAME_SZ];
-	size_t size;
-	struct vring *vr;
-
-	/* Allocate memory for virtqueue. */
-	if (queue_type == VTNET_RQ) {
-		snprintf(vq_name, sizeof(vq_name), "port%d_rvq",
-				dev->data->port_id);
-		vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) +
-			vq_size * sizeof(struct vq_desc_extra), RTE_CACHE_LINE_SIZE);
-		if (vq == NULL) {
-			RTE_LOG(ERR, PMD, "%s: unabled to allocate virtqueue\n", __func__);
-			return NULL;
-		}
-		memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
-	} else if(queue_type == VTNET_TQ) {
-		snprintf(vq_name, sizeof(vq_name), "port%d_tvq",
-			dev->data->port_id);
-		vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) +
-			vq_size * sizeof(struct vq_desc_extra), RTE_CACHE_LINE_SIZE);
-		if (vq == NULL) {
-			RTE_LOG(ERR, PMD, "%s: unabled to allocate virtqueue\n", __func__);
-			return NULL;
-		}
-		memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
-	}
-
-	memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
-
-	vq->vq_alignment = VIRTIO_PCI_VRING_ALIGN;
-	vq->vq_nentries = vq_size;
-	vq->vq_free_cnt = vq_size;
-	/* Calcuate vring size according to virtio spec */
-	size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN);
-	vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
-	/* Allocate memory for virtio vring through gntalloc driver*/
-	vq->vq_ring_virt_mem = gntalloc_vring_create(queue_type, vq->vq_ring_size,
-		((struct pmd_internals *)dev->data->dev_private)->virtio_idx);
-	memset(vq->vq_ring_virt_mem, 0, vq->vq_ring_size);
-	vr = &vq->vq_ring;
-	vring_init(vr, vq_size, vq->vq_ring_virt_mem, vq->vq_alignment);
-	/*
-	 * Locally maintained last consumed index, this idex trails
-	 * vq_ring.used->idx.
-	 */
-	vq->vq_used_cons_idx = 0;
-	vq->vq_desc_head_idx = 0;
-	vq->vq_free_cnt = vq->vq_nentries;
-	memset(vq->vq_descx, 0, sizeof(struct vq_desc_extra) * vq->vq_nentries);
-
-	/* Chain all the descriptors in the ring with an END */
-	for (i = 0; i < vq_size - 1; i++)
-		vr->desc[i].next = (uint16_t)(i + 1);
-	vr->desc[i].next = VQ_RING_DESC_CHAIN_END;
-
-	return vq;
-}
-
-static int
-eth_rx_queue_setup(struct rte_eth_dev *dev,uint16_t rx_queue_id,
-				uint16_t nb_rx_desc __rte_unused,
-				unsigned int socket_id __rte_unused,
-				const struct rte_eth_rxconf *rx_conf __rte_unused,
-				struct rte_mempool *mb_pool)
-{
-	struct virtqueue *vq;
-	vq = dev->data->rx_queues[rx_queue_id] = virtio_queue_setup(dev, VTNET_RQ);
-	vq->mpool = mb_pool;
-	return 0;
-}
-
-static int
-eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
-				uint16_t nb_tx_desc __rte_unused,
-				unsigned int socket_id __rte_unused,
-				const struct rte_eth_txconf *tx_conf __rte_unused)
-{
-	dev->data->tx_queues[tx_queue_id] = virtio_queue_setup(dev, VTNET_TQ);
-	return 0;
-}
-
-static void
-eth_xenvirt_free_queues(struct rte_eth_dev *dev)
-{
-	int i;
-
-	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		eth_queue_release(dev->data->rx_queues[i]);
-		dev->data->rx_queues[i] = NULL;
-	}
-	dev->data->nb_rx_queues = 0;
-
-	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		eth_queue_release(dev->data->tx_queues[i]);
-		dev->data->tx_queues[i] = NULL;
-	}
-	dev->data->nb_tx_queues = 0;
-}
-
-static const struct eth_dev_ops ops = {
-	.dev_start = eth_dev_start,
-	.dev_stop = eth_dev_stop,
-	.dev_close = eth_dev_close,
-	.dev_configure = eth_dev_configure,
-	.dev_infos_get = eth_dev_info,
-	.rx_queue_setup = eth_rx_queue_setup,
-	.tx_queue_setup = eth_tx_queue_setup,
-	.rx_queue_release = eth_queue_release,
-	.tx_queue_release = eth_queue_release,
-	.link_update = eth_link_update,
-	.stats_get = eth_stats_get,
-	.stats_reset = eth_stats_reset,
-};
-
-
-static int
-rte_eth_xenvirt_parse_args(struct xenvirt_dict *dict,
-			const char *name, const char *params)
-{
-	int i;
-	char *pairs[RTE_ETH_XENVIRT_MAX_ARGS];
-	int num_of_pairs;
-	char *pair[2];
-	char *args;
-	int ret = -1;
-
-	if (params == NULL)
-		return 0;
-
-	args = rte_zmalloc(NULL, strlen(params) + 1, RTE_CACHE_LINE_SIZE);
-	if (args == NULL) {
-		RTE_LOG(ERR, PMD, "Couldn't parse %s device \n", name);
-		return -1;
-	}
-	rte_memcpy(args, params, strlen(params));
-
-	num_of_pairs = rte_strsplit(args, strnlen(args, MAX_ARG_STRLEN),
-					pairs,
-					RTE_ETH_XENVIRT_MAX_ARGS ,
-					RTE_ETH_XENVIRT_PAIRS_DELIM);
-
-	for (i = 0; i < num_of_pairs; i++) {
-		pair[0] = NULL;
-		pair[1] = NULL;
-		rte_strsplit(pairs[i], strnlen(pairs[i], MAX_ARG_STRLEN),
-					pair, 2,
-					RTE_ETH_XENVIRT_KEY_VALUE_DELIM);
-
-		if (pair[0] == NULL || pair[1] == NULL || pair[0][0] == 0
-			|| pair[1][0] == 0) {
-			RTE_LOG(ERR, PMD,
-				"Couldn't parse %s device,"
-				"wrong key or value \n", name);
-			goto err;
-		}
-
-		if (!strncmp(pair[0], RTE_ETH_XENVIRT_MAC_PARAM,
-				sizeof(RTE_ETH_XENVIRT_MAC_PARAM))) {
-			if (cmdline_parse_etheraddr(NULL,
-						    pair[1],
-						    &dict->addr,
-						    sizeof(dict->addr)) < 0) {
-				RTE_LOG(ERR, PMD,
-					"Invalid %s device ether address\n",
-					name);
-				goto err;
-			}
-
-			dict->addr_valid = 1;
-		}
-	}
-
-	ret = 0;
-err:
-	rte_free(args);
-	return ret;
-}
-
-enum dev_action {
-	DEV_CREATE,
-	DEV_ATTACH
-};
-
-static struct rte_vdev_driver pmd_xenvirt_drv;
-
-static int
-eth_dev_xenvirt_create(const char *name, const char *params,
-		const unsigned numa_node,
-                enum dev_action action)
-{
-	struct rte_eth_dev_data *data = NULL;
-	struct pmd_internals *internals = NULL;
-	struct rte_eth_dev *eth_dev = NULL;
-	struct xenvirt_dict dict;
-
-	memset(&dict, 0, sizeof(struct xenvirt_dict));
-
-	RTE_LOG(INFO, PMD, "Creating virtio rings backed ethdev on numa socket %u\n",
-			numa_node);
-	RTE_SET_USED(action);
-
-	if (rte_eth_xenvirt_parse_args(&dict, name, params) < 0) {
-		RTE_LOG(ERR, PMD, "%s: Failed to parse ethdev parameters\n", __func__);
-		return -1;
-	}
-
-	/* now do all data allocation - for eth_dev structure, dummy pci driver
-	 * and internal (private) data
-	 */
-	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
-	if (data == NULL)
-		goto err;
-
-	internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node);
-	if (internals == NULL)
-		goto err;
-
-	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate(name);
-	if (eth_dev == NULL)
-		goto err;
-
-	data->dev_private = internals;
-	data->port_id = eth_dev->data->port_id;
-	data->nb_rx_queues = (uint16_t)1;
-	data->nb_tx_queues = (uint16_t)1;
-	data->dev_link = pmd_link;
-	data->mac_addrs = rte_zmalloc("xen_virtio", ETHER_ADDR_LEN, 0);
-
-	if(dict.addr_valid)
-		memcpy(&data->mac_addrs->addr_bytes, &dict.addr, sizeof(struct ether_addr));
-	else
-		eth_random_addr(&data->mac_addrs->addr_bytes[0]);
-
-	eth_dev->data = data;
-	eth_dev->dev_ops = &ops;
-
-	eth_dev->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
-	eth_dev->data->kdrv = RTE_KDRV_NONE;
-	eth_dev->data->numa_node = numa_node;
-
-	eth_dev->rx_pkt_burst = eth_xenvirt_rx;
-	eth_dev->tx_pkt_burst = eth_xenvirt_tx;
-
-	internals->virtio_idx = virtio_idx++;
-	internals->port_id = eth_dev->data->port_id;
-
-	return 0;
-
-err:
-	rte_free(data);
-	rte_free(internals);
-
-	return -1;
-}
-
-
-static int
-eth_dev_xenvirt_free(const char *name, const unsigned numa_node)
-{
-	struct rte_eth_dev *eth_dev = NULL;
-
-	RTE_LOG(DEBUG, PMD,
-		"Free virtio rings backed ethdev on numa socket %u\n",
-		numa_node);
-
-	/* find an ethdev entry */
-	eth_dev = rte_eth_dev_allocated(name);
-	if (eth_dev == NULL)
-		return -1;
-
-	if (eth_dev->data->dev_started == 1) {
-		eth_dev_stop(eth_dev);
-		eth_dev_close(eth_dev);
-	}
-
-	eth_dev->rx_pkt_burst = NULL;
-	eth_dev->tx_pkt_burst = NULL;
-	eth_dev->dev_ops = NULL;
-
-	rte_free(eth_dev->data);
-	rte_free(eth_dev->data->dev_private);
-	rte_free(eth_dev->data->mac_addrs);
-
-	virtio_idx--;
-
-	return 0;
-}
-
-/*TODO: Support multiple process model */
-static int
-rte_pmd_xenvirt_probe(struct rte_vdev_device *dev)
-{
-	if (virtio_idx == 0) {
-		if (xenstore_init() != 0) {
-			RTE_LOG(ERR, PMD, "%s: xenstore init failed\n", __func__);
-			return -1;
-		}
-		if (gntalloc_open() != 0) {
-			RTE_LOG(ERR, PMD, "%s: grant init failed\n", __func__);
-			return -1;
-		}
-	}
-	eth_dev_xenvirt_create(rte_vdev_device_name(dev),
-		rte_vdev_device_args(dev), rte_socket_id(), DEV_CREATE);
-	return 0;
-}
-
-static int
-rte_pmd_xenvirt_remove(struct rte_vdev_device *dev)
-{
-	eth_dev_xenvirt_free(rte_vdev_device_name(dev), rte_socket_id());
-
-	if (virtio_idx == 0) {
-		if (xenstore_uninit() != 0)
-			RTE_LOG(ERR, PMD, "%s: xenstore uninit failed\n", __func__);
-
-		gntalloc_close();
-	}
-	return 0;
-}
-
-static struct rte_vdev_driver pmd_xenvirt_drv = {
-	.probe = rte_pmd_xenvirt_probe,
-	.remove = rte_pmd_xenvirt_remove,
-};
-
-RTE_PMD_REGISTER_VDEV(net_xenvirt, pmd_xenvirt_drv);
-RTE_PMD_REGISTER_ALIAS(net_xenvirt, eth_xenvirt);
-RTE_PMD_REGISTER_PARAM_STRING(net_xenvirt,
-	"mac=<mac addr>");
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.h b/drivers/net/xenvirt/rte_eth_xenvirt.h
deleted file mode 100644
index 598adc6..0000000
--- a/drivers/net/xenvirt/rte_eth_xenvirt.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_ETH_XENVIRT_H_
-#define _RTE_ETH_XENVIRT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <rte_mempool.h>
-
-/**
- * Creates mempool for xen virtio PMD.
- * This function uses memzone_reserve to allocate memory for meta data,
- * and uses grant alloc driver to allocate memory for data area.
- * The input parameters are exactly the same as rte_mempool_create.
- */
-struct rte_mempool *
-rte_mempool_gntalloc_create(const char *name, unsigned elt_num, unsigned elt_size,
-		   unsigned cache_size, unsigned private_data_size,
-		   rte_mempool_ctor_t *mp_init, void *mp_init_arg,
-		   rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
-		   int socket_id, unsigned flags);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt_version.map b/drivers/net/xenvirt/rte_eth_xenvirt_version.map
deleted file mode 100644
index dd636f7..0000000
--- a/drivers/net/xenvirt/rte_eth_xenvirt_version.map
+++ /dev/null
@@ -1,7 +0,0 @@
-DPDK_2.0 {
-	global:
-
-	rte_mempool_gntalloc_create;
-
-	local: *;
-};
diff --git a/drivers/net/xenvirt/rte_mempool_gntalloc.c b/drivers/net/xenvirt/rte_mempool_gntalloc.c
deleted file mode 100644
index 73e82f8..0000000
--- a/drivers/net/xenvirt/rte_mempool_gntalloc.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <xen/sys/gntalloc.h>
-
-#include <rte_common.h>
-#include <rte_mempool.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-#include "rte_xen_lib.h"
-#include "rte_eth_xenvirt.h"
-
-struct _gntarr {
-	uint32_t gref;
-	phys_addr_t pa;
-	uint64_t index;
-	void *va;
-};
-
-struct _mempool_gntalloc_info {
-	struct rte_mempool *mp;
-	uint32_t pg_num;
-	uint32_t *gref_arr;
-	phys_addr_t *pa_arr;
-	void *va;
-	uint32_t mempool_idx;
-	uint64_t start_index;
-};
-
-
-static rte_atomic32_t global_xenvirt_mempool_idx = RTE_ATOMIC32_INIT(-1);
-
-static int
-compare(const void *p1, const void *p2)
-{
-	return ((const struct _gntarr *)p1)->pa  - ((const struct _gntarr *)p2)->pa;
-}
-
-
-static struct _mempool_gntalloc_info
-_create_mempool(const char *name, unsigned elt_num, unsigned elt_size,
-		   unsigned cache_size, unsigned private_data_size,
-		   rte_mempool_ctor_t *mp_init, void *mp_init_arg,
-		   rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
-		   int socket_id, unsigned flags)
-{
-	struct _mempool_gntalloc_info mgi;
-	struct rte_mempool *mp = NULL;
-	struct rte_mempool_objsz  objsz;
-	uint32_t pg_num, rpg_num, pg_shift, pg_sz;
-	char *va, *orig_va, *uv; /* uv: from which, the pages could be freed */
-	ssize_t sz, usz; /* usz: unused size */
-	/*
-	 * for each page allocated through xen_gntalloc driver,
-	 * gref_arr:stores grant references,
-	 * pa_arr: stores physical address,
-	 * gnt_arr: stores all meta dat
-	 */
-	uint32_t *gref_arr = NULL;
-	phys_addr_t *pa_arr = NULL;
-	struct _gntarr *gnt_arr = NULL;
-	/* start index of the grant referances, used for dealloc*/
-	uint64_t start_index;
-	uint32_t i, j;
-	int rv = 0;
-	struct ioctl_gntalloc_dealloc_gref arg;
-
-	mgi.mp = NULL;
-	va = orig_va = uv = NULL;
-	pg_num = rpg_num = 0;
-	sz = 0;
-
-	pg_sz = getpagesize();
-	if (rte_is_power_of_2(pg_sz) == 0) {
-		goto out;
-	}
-	pg_shift = rte_bsf32(pg_sz);
-
-	rte_mempool_calc_obj_size(elt_size, flags, &objsz);
-	sz = rte_mempool_xmem_size(elt_num, objsz.total_size, pg_shift);
-	pg_num = sz >> pg_shift;
-
-	pa_arr = calloc(pg_num, sizeof(pa_arr[0]));
-	gref_arr = calloc(pg_num, sizeof(gref_arr[0]));
-	gnt_arr  = calloc(pg_num, sizeof(gnt_arr[0]));
-	if ((gnt_arr == NULL) || (gref_arr == NULL) || (pa_arr == NULL))
-		goto out;
-
-	/* grant index is continuous in ascending order */
-	orig_va = gntalloc(sz, gref_arr, &start_index);
-	if (orig_va == NULL)
-		goto out;
-
-	get_phys_map(orig_va, pa_arr, pg_num, pg_sz);
-	for (i = 0; i < pg_num; i++) {
-		gnt_arr[i].index = start_index + i * pg_sz;
-		gnt_arr[i].gref = gref_arr[i];
-		gnt_arr[i].pa = pa_arr[i];
-		gnt_arr[i].va  = RTE_PTR_ADD(orig_va, i * pg_sz);
-	}
-	qsort(gnt_arr, pg_num, sizeof(struct _gntarr), compare);
-
-	va = get_xen_virtual(sz, pg_sz);
-	if (va == NULL) {
-		goto out;
-	}
-
-	/*
-	 * map one by one, as index isn't continuous now.
-	 * pg_num VMAs, doesn't linux has a limitation on this?
-	 */
-	for (i = 0; i < pg_num; i++) {
-	/* update gref_arr and pa_arr after sort */
-		gref_arr[i] = gnt_arr[i].gref;
-		pa_arr[i]   = gnt_arr[i].pa;
-		gnt_arr[i].va = mmap(va + i * pg_sz, pg_sz, PROT_READ | PROT_WRITE,
-			MAP_SHARED | MAP_FIXED, gntalloc_fd, gnt_arr[i].index);
-		if ((gnt_arr[i].va == MAP_FAILED) || (gnt_arr[i].va != (va + i * pg_sz))) {
-			RTE_LOG(ERR, PMD, "failed to map %d pages\n", i);
-			goto mmap_failed;
-		}
-	}
-
-	/*
-	 * Check that allocated size is big enough to hold elt_num
-	 * objects and a calcualte how many bytes are actually required.
-	 */
-	usz = rte_mempool_xmem_usage(va, elt_num, objsz.total_size, pa_arr, pg_num, pg_shift);
-	if (usz < 0) {
-		mp = NULL;
-		i = pg_num;
-		goto mmap_failed;
-	} else {
-		/* unmap unused pages if any */
-		uv = RTE_PTR_ADD(va, usz);
-		if ((usz = va + sz - uv) > 0) {
-
-			RTE_LOG(ERR, PMD,
-				"%s(%s): unmap unused %zu of %zu "
-				"mmaped bytes @%p orig:%p\n",
-				__func__, name, usz, sz, uv, va);
-			munmap(uv, usz);
-			i = (sz - usz) / pg_sz;
-			for (; i < pg_num; i++) {
-				arg.count = 1;
-				arg.index = gnt_arr[i].index;
-				rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg);
-				if (rv) {
-					/* shouldn't fail here */
-					RTE_LOG(ERR, PMD, "va=%p pa=%"PRIu64"x index=%"PRIu64" %s\n",
-						gnt_arr[i].va,
-						gnt_arr[i].pa,
-						arg.index, strerror(errno));
-					rte_panic("gntdealloc failed when freeing pages\n");
-				}
-			}
-
-			rpg_num = (sz - usz) >> pg_shift;
-		} else
-			rpg_num = pg_num;
-
-		mp = rte_mempool_xmem_create(name, elt_num, elt_size,
-				cache_size, private_data_size,
-				mp_init, mp_init_arg,
-				obj_init, obj_init_arg,
-				socket_id, flags, va, pa_arr, rpg_num, pg_shift);
-
-		RTE_ASSERT(elt_num == mp->size);
-	}
-	mgi.mp = mp;
-	mgi.pg_num = rpg_num;
-	mgi.gref_arr = gref_arr;
-	mgi.pa_arr = pa_arr;
-	if (mp)
-		mgi.mempool_idx = rte_atomic32_add_return(&global_xenvirt_mempool_idx, 1);
-	mgi.start_index = start_index;
-	mgi.va = va;
-
-	if (mp == NULL) {
-		i = pg_num;
-		goto mmap_failed;
-	}
-
-/*
- * unmap only, without deallocate grant reference.
- * unused pages have already been unmaped,
- * unmap twice will fail, but it is safe.
- */
-mmap_failed:
-	for (j = 0; j < i; j++) {
-		if (gnt_arr[i].va)
-			munmap(gnt_arr[i].va, pg_sz);
-	}
-out:
-	free(gnt_arr);
-	if (orig_va)
-		munmap(orig_va, sz);
-	if (mp == NULL) {
-		free(gref_arr);
-		free(pa_arr);
-
-		/* some gref has already been de-allocated from the list in the driver,
-		 * so dealloc one by one, and it is safe to deallocate twice
-		 */
-		if (orig_va) {
-			for (i = 0; i < pg_num; i++) {
-				arg.index = start_index + i * pg_sz;
-				rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, arg);
-			}
-		}
-	}
-	return mgi;
-}
-
-struct rte_mempool *
-rte_mempool_gntalloc_create(const char *name, unsigned elt_num, unsigned elt_size,
-		   unsigned cache_size, unsigned private_data_size,
-		   rte_mempool_ctor_t *mp_init, void *mp_init_arg,
-		   rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
-		   int socket_id, unsigned flags)
-{
-	int rv;
-	uint32_t i;
-	struct _mempool_gntalloc_info mgi;
-	struct ioctl_gntalloc_dealloc_gref arg;
-	int pg_sz = getpagesize();
-
-	mgi = _create_mempool(name, elt_num, elt_size,
-			cache_size, private_data_size,
-			mp_init, mp_init_arg,
-			obj_init, obj_init_arg,
-			socket_id, flags);
-	if (mgi.mp) {
-		rv = grant_gntalloc_mbuf_pool(mgi.mp,
-			mgi.pg_num,
-			mgi.gref_arr,
-			mgi.pa_arr,
-			mgi.mempool_idx);
-		free(mgi.gref_arr);
-		free(mgi.pa_arr);
-		if (rv == 0)
-			return mgi.mp;
-		/*
-		 * in _create_mempool, unused pages have already been unmapped, deallocagted
-		 * unmap and dealloc the remained ones here.
-		 */
-		munmap(mgi.va, pg_sz * mgi.pg_num);
-		for (i = 0; i < mgi.pg_num; i++) {
-			arg.index = mgi.start_index + i * pg_sz;
-			rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, arg);
-		}
-		return NULL;
-	}
-	return NULL;
-
-
-
-}
diff --git a/drivers/net/xenvirt/rte_xen_lib.c b/drivers/net/xenvirt/rte_xen_lib.c
deleted file mode 100644
index 6c9a1d4..0000000
--- a/drivers/net/xenvirt/rte_xen_lib.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-#include <xen/sys/gntalloc.h>
-
-#include <rte_common.h>
-#include <rte_string_fns.h>
-#include <rte_malloc.h>
-
-#include "rte_xen_lib.h"
-
-/*
- * The grant node format in xenstore for vring/mpool is:
- * 0_rx_vring_gref = "gref1#, gref2#, gref3#"
- * 0_mempool_gref  = "gref1#, gref2#, gref3#"
- * each gref# is a grant reference for a shared page.
- * In each shared page, we store the grant_node_item items.
- */
-struct grant_node_item {
-	uint32_t gref;
-	uint32_t pfn;
-} __attribute__((packed));
-
-/* fd for xen_gntalloc driver, used to allocate grant pages*/
-int gntalloc_fd = -1;
-
-/* xenstore path for local domain, now it is '/local/domain/domid/' */
-static char *dompath = NULL;
-/* handle to xenstore read/write operations */
-static struct xs_handle *xs = NULL;
-/* flag to indicate if xenstore cleanup is required */
-static bool is_xenstore_cleaned_up;
-
-/*
- * Reserve a virtual address space.
- * On success, returns the pointer. On failure, returns NULL.
- */
-void *
-get_xen_virtual(size_t size, size_t page_sz)
-{
-	void *addr;
-	uintptr_t aligned_addr;
-
-	addr = mmap(NULL, size + page_sz, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, PMD, "failed get a virtual area\n");
-		return NULL;
-	}
-
-	aligned_addr = RTE_ALIGN_CEIL((uintptr_t)addr, page_sz);
-	addr = (void *)(aligned_addr);
-
-	return addr;
-}
-
-/*
- * Get the physical address for virtual memory starting at va.
- */
-int
-get_phys_map(void *va, phys_addr_t pa[], uint32_t pg_num, uint32_t pg_sz)
-{
-	int32_t fd, rc = 0;
-	uint32_t i, nb;
-	off_t ofs;
-
-	ofs = (uintptr_t)va / pg_sz * sizeof(*pa);
-	nb = pg_num * sizeof(*pa);
-
-	if ((fd = open(PAGEMAP_FNAME, O_RDONLY)) < 0 ||
-			(rc = pread(fd, pa, nb, ofs)) < 0 ||
-			(rc -= nb) != 0) {
-		RTE_LOG(ERR, PMD, "%s: failed read of %u bytes from \'%s\' "
-			"at offset %lu, error code: %d\n",
-			__func__, nb, PAGEMAP_FNAME, (unsigned long)ofs, errno);
-		rc = ENOENT;
-	}
-
-	close(fd);
-	for (i = 0; i != pg_num; i++)
-		pa[i] = (pa[i] & PAGEMAP_PFN_MASK) * pg_sz;
-
-	return rc;
-}
-
-int
-gntalloc_open(void)
-{
-	gntalloc_fd = open(XEN_GNTALLOC_FNAME, O_RDWR);
-	return (gntalloc_fd != -1) ? 0 : -1;
-}
-
-void
-gntalloc_close(void)
-{
-	if (gntalloc_fd != -1)
-		close(gntalloc_fd);
-	gntalloc_fd = -1;
-}
-
-void *
-gntalloc(size_t size, uint32_t *gref, uint64_t *start_index)
-{
-	int page_size = getpagesize();
-	uint32_t i, pg_num;
-	void *va;
-	int rv;
-	struct ioctl_gntalloc_alloc_gref *arg;
-	struct ioctl_gntalloc_dealloc_gref arg_d;
-
-	if (size % page_size) {
-		RTE_LOG(ERR, PMD, "%s: %zu isn't multiple of page size\n",
-			__func__, size);
-		return NULL;
-	}
-
-	pg_num = size / page_size;
-	arg = malloc(sizeof(*arg) + (pg_num - 1) * sizeof(uint32_t));
-	if (arg == NULL)
-		return NULL;
-	arg->domid = DOM0_DOMID;
-	arg->flags = GNTALLOC_FLAG_WRITABLE;
-	arg->count = pg_num;
-
-	rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_ALLOC_GREF, arg);
-	if (rv) {
-		RTE_LOG(ERR, PMD, "%s: ioctl error\n", __func__);
-		free(arg);
-		return NULL;
-	}
-
-	va = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, gntalloc_fd, arg->index);
-	if (va == MAP_FAILED) {
-		RTE_LOG(ERR, PMD, "%s: mmap failed\n", __func__);
-		arg_d.count = pg_num;
-		arg_d.index = arg->index;
-		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, arg_d);
-		free(arg);
-		return NULL;
-	}
-
-	if (gref) {
-		for (i = 0; i < pg_num; i++) {
-			gref[i] = arg->gref_ids[i];
-		}
-	}
-	if (start_index)
-		*start_index = arg->index;
-
-	free(arg);
-
-	return va;
-}
-
-int
-grefwatch_from_alloc(uint32_t *gref, void **pptr)
-{
-	int rv;
-	void *ptr;
-	int pg_size = getpagesize();
-	struct ioctl_gntalloc_alloc_gref arg = {
-		.domid = DOM0_DOMID,
-		.flags = GNTALLOC_FLAG_WRITABLE,
-		.count = 1
-	};
-	struct ioctl_gntalloc_dealloc_gref arg_d;
-	struct ioctl_gntalloc_unmap_notify notify = {
-		.action = UNMAP_NOTIFY_CLEAR_BYTE
-	};
-
-	rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_ALLOC_GREF, &arg);
-	if (rv) {
-		RTE_LOG(ERR, PMD, "%s: ioctl error\n", __func__);
-		return -1;
-	}
-
-	ptr = (void *)mmap(NULL, pg_size, PROT_READ|PROT_WRITE, MAP_SHARED, gntalloc_fd, arg.index);
-	arg_d.index = arg.index;
-	arg_d.count = 1;
-	if (ptr == MAP_FAILED) {
-		RTE_LOG(ERR, PMD, "%s: mmap failed\n", __func__);
-		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
-		return -1;
-	}
-	if (pptr)
-		*pptr = ptr;
-	if (gref)
-		*gref = arg.gref_ids[0];
-
-	notify.index = arg.index;
-	rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, &notify);
-	if (rv) {
-		RTE_LOG(ERR, PMD, "%s: unmap notify failed\n", __func__);
-		munmap(ptr, pg_size);
-		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
-		return -1;
-	}
-
-	return 0;
-}
-
-void
-gntfree(void *va, size_t sz, uint64_t start_index)
-{
-	struct ioctl_gntalloc_dealloc_gref arg_d;
-
-	if (va && sz) {
-		munmap(va, sz);
-		arg_d.count = sz / getpagesize();
-		arg_d.index = start_index;
-		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
-	}
-}
-
-static int
-xenstore_cleanup(void)
-{
-	char store_path[PATH_MAX] = {0};
-
-	if (snprintf(store_path, sizeof(store_path),
-		"%s%s", dompath, DPDK_XENSTORE_NODE) == -1)
-		return -1;
-
-	if (xs_rm(xs, XBT_NULL, store_path) == false) {
-		RTE_LOG(ERR, PMD, "%s: failed cleanup node\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-int
-xenstore_init(void)
-{
-	unsigned int len, domid;
-	char *buf;
-	char *end;
-
-	xs = xs_domain_open();
-	if (xs == NULL) {
-		RTE_LOG(ERR, PMD,"%s: xs_domain_open failed\n", __func__);
-		return -1;
-	}
-	buf = xs_read(xs, XBT_NULL, "domid", &len);
-	if (buf == NULL) {
-		RTE_LOG(ERR, PMD, "%s: failed read domid\n", __func__);
-		return -1;
-	}
-	errno = 0;
-	domid = strtoul(buf, &end, 0);
-	if (errno != 0 || end == NULL || end == buf ||  domid == 0)
-		return -1;
-
-	RTE_LOG(INFO, PMD, "retrieved dom ID = %d\n", domid);
-
-	dompath = xs_get_domain_path(xs, domid);
-	if (dompath == NULL)
-		return -1;
-
-	xs_transaction_start(xs); /* When to stop transaction */
-
-	if (is_xenstore_cleaned_up == 0) {
-		if (xenstore_cleanup())
-			return -1;
-		is_xenstore_cleaned_up = 1;
-	}
-
-	return 0;
-}
-
-int
-xenstore_uninit(void)
-{
-	xs_close(xs);
-
-	if (is_xenstore_cleaned_up == 0) {
-		if (xenstore_cleanup())
-			return -1;
-		is_xenstore_cleaned_up = 1;
-	}
-	free(dompath);
-	dompath = NULL;
-
-	return 0;
-}
-
-int
-xenstore_write(const char *key_str, const char *val_str)
-{
-	char grant_path[PATH_MAX];
-	int rv, len;
-
-	if (xs == NULL) {
-		RTE_LOG(ERR, PMD, "%s: xenstore init failed\n", __func__);
-		return -1;
-	}
-	rv = snprintf(grant_path, sizeof(grant_path), "%s%s", dompath, key_str);
-	if (rv == -1) {
-		RTE_LOG(ERR, PMD, "%s: snprintf %s %s failed\n",
-			__func__, dompath, key_str);
-		return -1;
-	}
-	len = strnlen(val_str, PATH_MAX);
-
-	if (xs_write(xs, XBT_NULL, grant_path, val_str, len) == false) {
-		RTE_LOG(ERR, PMD, "%s: xs_write failed\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-int
-grant_node_create(uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, char *val_str, size_t str_size)
-{
-	uint64_t start_index;
-	int pg_size;
-	uint32_t pg_shift;
-	void *ptr = NULL;
-	uint32_t count, entries_per_pg;
-	uint32_t i, j = 0, k = 0;
-	uint32_t *gref_tmp;
-	int first = 1;
-	char tmp_str[PATH_MAX] = {0};
-	int rv = -1;
-
-	pg_size = getpagesize();
-	if (rte_is_power_of_2(pg_size) == 0) {
-		return -1;
-	}
-	pg_shift = rte_bsf32(pg_size);
-	if (pg_size % sizeof(struct grant_node_item)) {
-		RTE_LOG(ERR, PMD, "pg_size isn't a multiple of grant node item\n");
-		return -1;
-	}
-
-	entries_per_pg = pg_size / sizeof(struct grant_node_item);
-	count  = (pg_num +  entries_per_pg - 1 ) / entries_per_pg;
-	gref_tmp = malloc(count * sizeof(uint32_t));
-	if (gref_tmp == NULL)
-		return -1;
-	ptr = gntalloc(pg_size * count, gref_tmp, &start_index);
-	if (ptr == NULL) {
-		RTE_LOG(ERR, PMD, "%s: gntalloc error of %d pages\n", __func__, count);
-		free(gref_tmp);
-		return -1;
-	}
-
-	while (j < pg_num) {
-		if (first) {
-			rv = snprintf(val_str, str_size, "%u", gref_tmp[k]);
-			first = 0;
-		} else {
-			snprintf(tmp_str, PATH_MAX, "%s", val_str);
-			rv = snprintf(val_str, str_size, "%s,%u", tmp_str, gref_tmp[k]);
-		}
-		k++;
-		if (rv == -1)
-			break;
-
-		for (i = 0; i < entries_per_pg && j < pg_num ; i++) {
-			((struct grant_node_item *)ptr)->gref = gref_arr[j];
-			((struct grant_node_item *)ptr)->pfn =  pa_arr[j] >> pg_shift;
-			ptr = RTE_PTR_ADD(ptr, sizeof(struct grant_node_item));
-			j++;
-		}
-	}
-	if (rv == -1) {
-		gntfree(ptr, pg_size * count, start_index);
-	} else
-		rv = 0;
-	free(gref_tmp);
-	return rv;
-}
-
-
-int
-grant_gntalloc_mbuf_pool(struct rte_mempool *mpool, uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, int mempool_idx)
-{
-	char key_str[PATH_MAX] = {0};
-	char val_str[PATH_MAX] = {0};
-	void *mempool_obj_va;
-
-	if (grant_node_create(pg_num, gref_arr, pa_arr, val_str, sizeof(val_str))) {
-		return -1;
-	}
-
-	if (snprintf(key_str, sizeof(key_str),
-		DPDK_XENSTORE_PATH"%d"MEMPOOL_XENSTORE_STR, mempool_idx) == -1)
-		return -1;
-	if (xenstore_write(key_str, val_str) == -1)
-		return -1;
-
-	if (snprintf(key_str, sizeof(key_str),
-		DPDK_XENSTORE_PATH"%d"MEMPOOL_VA_XENSTORE_STR, mempool_idx) == -1)
-		return -1;
-	if (mpool->nb_mem_chunks != 1) {
-		RTE_LOG(ERR, PMD,
-			"mempool with more than 1 chunk is not supported\n");
-		return -1;
-	}
-	mempool_obj_va = STAILQ_FIRST(&mpool->mem_list)->addr;
-	if (snprintf(val_str, sizeof(val_str), "%"PRIxPTR,
-			(uintptr_t)mempool_obj_va) == -1)
-		return -1;
-	if (xenstore_write(key_str, val_str) == -1)
-		return -1;
-
-	return 0;
-}
diff --git a/drivers/net/xenvirt/rte_xen_lib.h b/drivers/net/xenvirt/rte_xen_lib.h
deleted file mode 100644
index d973eac..0000000
--- a/drivers/net/xenvirt/rte_xen_lib.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_XEN_DUMMY_PMD_H
-#define _RTE_XEN_DUMMY_PMD_H
-
-#include <stdint.h>
-
-#include <rte_common.h>
-#include <rte_mempool.h>
-#include <rte_ether.h>
-
-#define	PAGEMAP_FNAME           "/proc/self/pagemap"
-#define XEN_GNTALLOC_FNAME      "/dev/xen/gntalloc"
-#define DPDK_XENSTORE_PATH      "/control/dpdk/"
-#define DPDK_XENSTORE_NODE      "/control/dpdk"
-/*format 0_mempool_gref = "1537,1524,1533" */
-#define MEMPOOL_XENSTORE_STR    "_mempool_gref"
-/*format 0_mempool_va = 0x80340000 */
-#define MEMPOOL_VA_XENSTORE_STR "_mempool_va"
-/*format 0_rx_vring_gref  = "1537,1524,1533" */
-#define RXVRING_XENSTORE_STR    "_rx_vring_gref"
-/*format 0_tx_vring_gref  = "1537,1524,1533" */
-#define TXVRING_XENSTORE_STR    "_tx_vring_gref"
-#define VRING_FLAG_STR          "_vring_flag"
-/*format: event_type_start_0 = 1*/
-#define EVENT_TYPE_START_STR    "event_type_start_"
-
-#define DOM0_DOMID 0
-/*
- * the pfn (page frame number) are bits 0-54 (see pagemap.txt in linux
- * Documentation).
- */
-#define PAGEMAP_PFN_BITS	54
-#define PAGEMAP_PFN_MASK	RTE_LEN2MASK(PAGEMAP_PFN_BITS, phys_addr_t)
-
-#define MAP_FLAG	0xA5
-
-#define RTE_ETH_XENVIRT_PAIRS_DELIM ';'
-#define RTE_ETH_XENVIRT_KEY_VALUE_DELIM '='
-#define RTE_ETH_XENVIRT_MAX_ARGS 1
-#define RTE_ETH_XENVIRT_MAC_PARAM "mac"
-struct xenvirt_dict {
-	uint8_t addr_valid;
-	struct ether_addr addr;
-};
-
-extern int gntalloc_fd;
-
-int
-gntalloc_open(void);
-
-void
-gntalloc_close(void);
-
-void *
-gntalloc(size_t sz, uint32_t *gref, uint64_t *start_index);
-
-void
-gntfree(void *va, size_t sz, uint64_t start_index);
-
-int
-xenstore_init(void);
-
-int
-xenstore_uninit(void);
-
-int
-xenstore_write(const char *key_str, const char *val_str);
-
-int
-get_phys_map(void *va, phys_addr_t pa[], uint32_t pg_num, uint32_t pg_sz);
-
-void *
-get_xen_virtual(size_t size, size_t page_sz);
-
-int
-grefwatch_from_alloc(uint32_t *gref, void **pptr);
-
-
-int grant_node_create(uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, char *val_str, size_t str_size);
-
-int
-grant_gntalloc_mbuf_pool(struct rte_mempool *mpool, uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, int mempool_idx);
-
-#endif
diff --git a/drivers/net/xenvirt/virtio_logs.h b/drivers/net/xenvirt/virtio_logs.h
deleted file mode 100644
index d6c33f7..0000000
--- a/drivers/net/xenvirt/virtio_logs.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VIRTIO_LOGS_H_
-#define _VIRTIO_LOGS_H_
-
-#include <rte_log.h>
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_INIT
-#define PMD_INIT_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
-#else
-#define PMD_INIT_LOG(level, fmt, args...) do { } while(0)
-#define PMD_INIT_FUNC_TRACE() do { } while(0)
-#endif
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_RX
-#define PMD_RX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s() rx: " fmt , __func__, ## args)
-#else
-#define PMD_RX_LOG(level, fmt, args...) do { } while(0)
-#endif
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_TX
-#define PMD_TX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s() tx: " fmt , __func__, ## args)
-#else
-#define PMD_TX_LOG(level, fmt, args...) do { } while(0)
-#endif
-
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_DRIVER
-#define PMD_DRV_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt , __func__, ## args)
-#else
-#define PMD_DRV_LOG(level, fmt, args...) do { } while(0)
-#endif
-
-#endif /* _VIRTIO_LOGS_H_ */
diff --git a/drivers/net/xenvirt/virtqueue.h b/drivers/net/xenvirt/virtqueue.h
deleted file mode 100644
index 1bb6877..0000000
--- a/drivers/net/xenvirt/virtqueue.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VIRTQUEUE_H_
-#define _VIRTQUEUE_H_
-
-#include <stdint.h>
-#include <linux/virtio_ring.h>
-#include <linux/virtio_net.h>
-
-#include <rte_atomic.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_mempool.h>
-
-#include "virtio_logs.h"
-
-struct rte_mbuf;
-
-/* The alignment to use between consumer and producer parts of vring. */
-#define VIRTIO_PCI_VRING_ALIGN 4096
-
-enum { VTNET_RQ = 0, VTNET_TQ = 1, VTNET_CQ = 2 };
-
-/**
- * The maximum virtqueue size is 2^15. Use that value as the end of
- * descriptor chain terminator since it will never be a valid index
- * in the descriptor table. This is used to verify we are correctly
- * handling vq_free_cnt.
- */
-#define VQ_RING_DESC_CHAIN_END 32768
-
-#define VIRTQUEUE_MAX_NAME_SZ  32
-
-struct pmd_internals {
-	struct rte_eth_stats eth_stats;
-	int port_id;
-	int virtio_idx;
-};
-
-
-struct virtqueue {
-	char vq_name[VIRTQUEUE_MAX_NAME_SZ];
-	struct rte_mempool       *mpool;  /**< mempool for mbuf allocation */
-	uint16_t    queue_id;             /**< DPDK queue index. */
-	uint16_t    vq_queue_index;       /**< PCI queue index */
-	uint8_t     port_id;              /**< Device port identifier. */
-
-	void        *vq_ring_virt_mem;    /**< virtual address of vring*/
-	int         vq_alignment;
-	int         vq_ring_size;
-
-	struct vring vq_ring;    /**< vring keeping desc, used and avail */
-	struct pmd_internals *internals;  /**< virtio device internal info. */
-	uint16_t    vq_nentries; /**< vring desc numbers */
-	uint16_t    vq_desc_head_idx;
-	uint16_t    vq_free_cnt; /**< num of desc available */
-	uint16_t vq_used_cons_idx; /**< Last consumed desc in used table, trails vq_ring.used->idx*/
-
-	struct vq_desc_extra {
-		void              *cookie;
-		uint16_t          ndescs;
-	} vq_descx[0] __rte_cache_aligned;
-};
-
-
-#ifdef  RTE_LIBRTE_XENVIRT_DEBUG_DUMP
-#define VIRTQUEUE_DUMP(vq) do { \
-	uint16_t used_idx, nused; \
-	used_idx = (vq)->vq_ring.used->idx; \
-	nused = (uint16_t)(used_idx - (vq)->vq_used_cons_idx); \
-	PMD_INIT_LOG(DEBUG, \
-	  "VQ: %s - size=%d; free=%d; used=%d; desc_head_idx=%d;" \
-	  " avail.idx=%d; used_cons_idx=%d; used.idx=%d;" \
-	  " avail.flags=0x%x; used.flags=0x%x\n", \
-	  (vq)->vq_name, (vq)->vq_nentries, (vq)->vq_free_cnt, nused, \
-	  (vq)->vq_desc_head_idx, (vq)->vq_ring.avail->idx, \
-	  (vq)->vq_used_cons_idx, (vq)->vq_ring.used->idx, \
-	  (vq)->vq_ring.avail->flags, (vq)->vq_ring.used->flags); \
-} while (0)
-#else
-#define VIRTQUEUE_DUMP(vq) do { } while (0)
-#endif
-
-
-/**
- *  Dump virtqueue internal structures, for debug purpose only.
- */
-void virtqueue_dump(struct virtqueue *vq);
-
-/**
- *  Get all mbufs to be freed.
- */
-struct rte_mbuf * virtqueue_detatch_unused(struct virtqueue *vq);
-
-static __rte_always_inline int
-virtqueue_full(const struct virtqueue *vq)
-{
-	return vq->vq_free_cnt == 0;
-}
-
-#define VIRTQUEUE_NUSED(vq) ((uint16_t)((vq)->vq_ring.used->idx - (vq)->vq_used_cons_idx))
-
-static __rte_always_inline void
-vq_ring_update_avail(struct virtqueue *vq, uint16_t desc_idx)
-{
-	uint16_t avail_idx;
-	/*
-	 * Place the head of the descriptor chain into the next slot and make
-	 * it usable to the host. The chain is made available now rather than
-	 * deferring to virtqueue_notify() in the hopes that if the host is
-	 * currently running on another CPU, we can keep it processing the new
-	 * descriptor.
-	 */
-	avail_idx = (uint16_t)(vq->vq_ring.avail->idx & (vq->vq_nentries - 1));
-	vq->vq_ring.avail->ring[avail_idx] = desc_idx;
-	rte_smp_wmb();
-	vq->vq_ring.avail->idx++;
-}
-
-static __rte_always_inline void
-vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
-{
-	struct vring_desc *dp;
-	struct vq_desc_extra *dxp;
-
-	dp  = &vq->vq_ring.desc[desc_idx];
-	dxp = &vq->vq_descx[desc_idx];
-	vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt + dxp->ndescs);
-	while (dp->flags & VRING_DESC_F_NEXT) {
-		dp = &vq->vq_ring.desc[dp->next];
-	}
-	dxp->ndescs = 0;
-
-	/*
-	 * We must append the existing free chain, if any, to the end of
-	 * newly freed chain. If the virtqueue was completely used, then
-	 * head would be VQ_RING_DESC_CHAIN_END (ASSERTed above).
-	 */
-	dp->next = vq->vq_desc_head_idx;
-	vq->vq_desc_head_idx = desc_idx;
-}
-
-static __rte_always_inline int
-virtqueue_enqueue_recv_refill(struct virtqueue *rxvq, struct rte_mbuf *cookie)
-{
-	const uint16_t needed = 1;
-	const uint16_t head_idx = rxvq->vq_desc_head_idx;
-	struct vring_desc *start_dp = rxvq->vq_ring.desc;
-	struct vq_desc_extra *dxp;
-
-	if (unlikely(rxvq->vq_free_cnt == 0))
-		return -ENOSPC;
-	if (unlikely(rxvq->vq_free_cnt < needed))
-		return -EMSGSIZE;
-	if (unlikely(head_idx >= rxvq->vq_nentries))
-		return -EFAULT;
-
-	dxp = &rxvq->vq_descx[head_idx];
-	dxp->cookie = (void *)cookie;
-	dxp->ndescs = needed;
-
-	start_dp[head_idx].addr  =
-		(uint64_t) ((uintptr_t)cookie->buf_addr + RTE_PKTMBUF_HEADROOM - sizeof(struct virtio_net_hdr));
-	start_dp[head_idx].len   = cookie->buf_len - RTE_PKTMBUF_HEADROOM + sizeof(struct virtio_net_hdr);
-	start_dp[head_idx].flags = VRING_DESC_F_WRITE;
-	rxvq->vq_desc_head_idx   = start_dp[head_idx].next;
-	rxvq->vq_free_cnt        = (uint16_t)(rxvq->vq_free_cnt - needed);
-	vq_ring_update_avail(rxvq, head_idx);
-
-	return 0;
-}
-
-static __rte_always_inline int
-virtqueue_enqueue_xmit(struct virtqueue *txvq, struct rte_mbuf *cookie)
-{
-
-	const uint16_t needed = 2;
-	struct vring_desc *start_dp =  txvq->vq_ring.desc;
-	uint16_t head_idx = txvq->vq_desc_head_idx;
-	uint16_t idx      = head_idx;
-	struct vq_desc_extra *dxp;
-
-	if (unlikely(txvq->vq_free_cnt == 0))
-		return -ENOSPC;
-	if (unlikely(txvq->vq_free_cnt < needed))
-		return -EMSGSIZE;
-	if (unlikely(head_idx >= txvq->vq_nentries))
-		return -EFAULT;
-
-	dxp = &txvq->vq_descx[idx];
-	dxp->cookie = (void *)cookie;
-	dxp->ndescs = needed;
-
-	start_dp = txvq->vq_ring.desc;
-	start_dp[idx].addr  = 0;
-/*
- * TODO: save one desc here?
- */
-	start_dp[idx].len   = sizeof(struct virtio_net_hdr);
-	start_dp[idx].flags = VRING_DESC_F_NEXT;
-	start_dp[idx].addr  = (uintptr_t)NULL;
-	idx = start_dp[idx].next;
-	start_dp[idx].addr  = (uint64_t)rte_pktmbuf_mtod(cookie, uintptr_t);
-	start_dp[idx].len   = cookie->data_len;
-	start_dp[idx].flags = 0;
-	idx = start_dp[idx].next;
-	txvq->vq_desc_head_idx = idx;
-	txvq->vq_free_cnt = (uint16_t)(txvq->vq_free_cnt - needed);
-	vq_ring_update_avail(txvq, head_idx);
-
-	return 0;
-}
-
-static __rte_always_inline uint16_t
-virtqueue_dequeue_burst(struct virtqueue *vq, struct rte_mbuf **rx_pkts, uint32_t *len, uint16_t num)
-{
-	struct vring_used_elem *uep;
-	struct rte_mbuf *cookie;
-	uint16_t used_idx, desc_idx;
-	uint16_t i;
-	/*  Caller does the check */
-	for (i = 0; i < num ; i ++) {
-		used_idx = (uint16_t)(vq->vq_used_cons_idx & (vq->vq_nentries - 1));
-		uep = &vq->vq_ring.used->ring[used_idx];
-		desc_idx = (uint16_t) uep->id;
-		cookie = (struct rte_mbuf *)vq->vq_descx[desc_idx].cookie;
-		if (unlikely(cookie == NULL)) {
-			PMD_DRV_LOG(ERR, "vring descriptor with no mbuf cookie at %u\n",
-				vq->vq_used_cons_idx);
-			RTE_LOG(ERR, PMD, "%s: inconsistent (%u, %u)\n", __func__, used_idx , desc_idx);
-			break;
-		}
-		len[i] = uep->len;
-		rx_pkts[i]  = cookie;
-		vq->vq_used_cons_idx++;
-		vq_ring_free_chain(vq, desc_idx);
-		vq->vq_descx[desc_idx].cookie = NULL;
-	}
-	return i;
-}
-
-#endif /* _VIRTQUEUE_H_ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..fb6be12 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -144,7 +144,6 @@ 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
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT)    += -lrte_pmd_xenvirt -lxenstore
 
 ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)    += -lrte_pmd_aesni_mb
diff --git a/pkg/dpdk.spec b/pkg/dpdk.spec
index 5ba3431..95c3335 100644
--- a/pkg/dpdk.spec
+++ b/pkg/dpdk.spec
@@ -90,9 +90,6 @@ sed -ri 's,(RTE_BUILD_SHARED_LIB=).*,\1y,' %{target}/.config
 sed -ri 's,(RTE_NEXT_ABI=).*,\1n,'         %{target}/.config
 sed -ri 's,(LIBRTE_VHOST=).*,\1y,'         %{target}/.config
 sed -ri 's,(LIBRTE_PMD_PCAP=).*,\1y,'      %{target}/.config
-%ifarch i686 x86_64
-sed -ri 's,(LIBRTE_PMD_XENVIRT=).*,\1y,'   %{target}/.config
-%endif
 make O=%{target} %{?_smp_mflags}
 make O=%{target} doc
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 2/6] net/xenvirt: remove
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
  2017-08-30 18:10 ` [PATCH 1/6] example/vhost_xen: remove Jianfeng Tan
  2017-08-30 18:10 ` Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-08-30 18:10 ` Jianfeng Tan
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: jerin.jacob, shahafs, john.mcnamara, Jianfeng Tan, oao.m.martins,
	thomas, xen-devel

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 MAINTAINERS                                     |   2 -
 app/test-pmd/Makefile                           |   4 -
 app/test-pmd/testpmd.c                          |  12 -
 config/common_base                              |   5 -
 config/defconfig_arm-armv7a-linuxapp-gcc        |   1 -
 doc/guides/nics/features/xenvirt.ini            |   6 -
 drivers/net/Makefile                            |   2 -
 drivers/net/xenvirt/Makefile                    |  57 --
 drivers/net/xenvirt/rte_eth_xenvirt.c           | 766 ------------------------
 drivers/net/xenvirt/rte_eth_xenvirt.h           |  61 --
 drivers/net/xenvirt/rte_eth_xenvirt_version.map |   7 -
 drivers/net/xenvirt/rte_mempool_gntalloc.c      | 295 ---------
 drivers/net/xenvirt/rte_xen_lib.c               | 454 --------------
 drivers/net/xenvirt/rte_xen_lib.h               | 116 ----
 drivers/net/xenvirt/virtio_logs.h               |  70 ---
 drivers/net/xenvirt/virtqueue.h                 | 273 ---------
 mk/rte.app.mk                                   |   1 -
 pkg/dpdk.spec                                   |   3 -
 18 files changed, 2135 deletions(-)
 delete mode 100644 doc/guides/nics/features/xenvirt.ini
 delete mode 100644 drivers/net/xenvirt/Makefile
 delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
 delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
 delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
 delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
 delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
 delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
 delete mode 100644 drivers/net/xenvirt/virtio_logs.h
 delete mode 100644 drivers/net/xenvirt/virtqueue.h

diff --git a/MAINTAINERS b/MAINTAINERS
index fe6c6db..003e72e 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -194,9 +194,7 @@ M: Jianfeng Tan <jianfeng.tan@intel.com>
 F: lib/librte_eal/linuxapp/xen_dom0/
 F: lib/librte_eal/linuxapp/eal/*xen*
 F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
-F: drivers/net/xenvirt/
 F: doc/guides/xen/
-F: doc/guides/nics/features/xenvirt.ini
 
 FreeBSD EAL (with overlaps)
 M: Bruce Richardson <bruce.richardson@intel.com>
diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index c36be19..b6e80dd 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -77,10 +77,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
 LDLIBS += -lrte_pmd_bnxt
 endif
 
-ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
-LDLIBS += -lrte_pmd_xenvirt
-endif
-
 endif
 
 CFLAGS_cmdline.o := -D_GNU_SOURCE
diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index 7d40139..f8d02ae 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -76,9 +76,6 @@
 #ifdef RTE_LIBRTE_IXGBE_PMD
 #include <rte_pmd_ixgbe.h>
 #endif
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-#include <rte_eth_xenvirt.h>
-#endif
 #ifdef RTE_LIBRTE_PDUMP
 #include <rte_pdump.h>
 #endif
@@ -497,15 +494,6 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
 
-#ifdef RTE_LIBRTE_PMD_XENVIRT
-	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
-		(unsigned) mb_mempool_cache,
-		sizeof(struct rte_pktmbuf_pool_private),
-		rte_pktmbuf_pool_init, NULL,
-		rte_pktmbuf_init, NULL,
-		socket_id, 0);
-#endif
-
 	/* if the former XEN allocation failed fall back to normal allocation */
 	if (rte_mp == NULL) {
 		if (mp_anon != 0) {
diff --git a/config/common_base b/config/common_base
index 5e97a08..93928b6 100644
--- a/config/common_base
+++ b/config/common_base
@@ -411,11 +411,6 @@ CONFIG_RTE_LIBRTE_AVP_DEBUG_BUFFERS=n
 CONFIG_RTE_LIBRTE_PMD_TAP=n
 
 #
-# Compile Xen PMD
-#
-CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
-
-#
 # Compile null PMD
 #
 CONFIG_RTE_LIBRTE_PMD_NULL=y
diff --git a/config/defconfig_arm-armv7a-linuxapp-gcc b/config/defconfig_arm-armv7a-linuxapp-gcc
index 00bc2ab..6628567 100644
--- a/config/defconfig_arm-armv7a-linuxapp-gcc
+++ b/config/defconfig_arm-armv7a-linuxapp-gcc
@@ -76,7 +76,6 @@ CONFIG_RTE_LIBRTE_I40E_PMD=n
 CONFIG_RTE_LIBRTE_IXGBE_PMD=n
 CONFIG_RTE_LIBRTE_MLX4_PMD=n
 CONFIG_RTE_LIBRTE_VMXNET3_PMD=n
-CONFIG_RTE_LIBRTE_PMD_XENVIRT=n
 CONFIG_RTE_LIBRTE_PMD_BNX2X=n
 CONFIG_RTE_LIBRTE_QEDE_PMD=n
 CONFIG_RTE_LIBRTE_SFC_EFX_PMD=n
diff --git a/doc/guides/nics/features/xenvirt.ini b/doc/guides/nics/features/xenvirt.ini
deleted file mode 100644
index 8ab5f46..0000000
--- a/doc/guides/nics/features/xenvirt.ini
+++ /dev/null
@@ -1,6 +0,0 @@
-;
-; Supported features of the 'xenvirt' network poll mode driver.
-;
-; Refer to default.ini for the full list of available PMD features.
-;
-[Features]
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index d33c959..0e00cd1 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -97,8 +97,6 @@ DIRS-$(CONFIG_RTE_LIBRTE_VIRTIO_PMD) += virtio
 DEPDIRS-virtio = $(core-libs)
 DIRS-$(CONFIG_RTE_LIBRTE_VMXNET3_PMD) += vmxnet3
 DEPDIRS-vmxnet3 = $(core-libs)
-DIRS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += xenvirt
-DEPDIRS-xenvirt = $(core-libs) librte_cmdline
 
 ifeq ($(CONFIG_RTE_LIBRTE_KNI),y)
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_KNI) += kni
diff --git a/drivers/net/xenvirt/Makefile b/drivers/net/xenvirt/Makefile
deleted file mode 100644
index 8b4b8f0..0000000
--- a/drivers/net/xenvirt/Makefile
+++ /dev/null
@@ -1,57 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-#
-# library name
-#
-LIB = librte_pmd_xenvirt.a
-
-CFLAGS += -O3
-CFLAGS += $(WERROR_FLAGS)
-LDLIBS += -lxenstore
-
-EXPORT_MAP := rte_eth_xenvirt_version.map
-
-LIBABIVER := 1
-
-#
-# all source are stored in SRCS-y
-#
-SRCS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT) += rte_eth_xenvirt.c rte_mempool_gntalloc.c rte_xen_lib.c
-
-#
-# Export include files
-#
-SYMLINK-y-include += rte_eth_xenvirt.h
-
-include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.c b/drivers/net/xenvirt/rte_eth_xenvirt.c
deleted file mode 100644
index e404b77..0000000
--- a/drivers/net/xenvirt/rte_eth_xenvirt.c
+++ /dev/null
@@ -1,766 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/types.h>
-#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
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-#include <linux/virtio_ring.h>
-
-#include <rte_mbuf.h>
-#include <rte_ethdev.h>
-#include <rte_malloc.h>
-#include <rte_memcpy.h>
-#include <rte_string_fns.h>
-#include <rte_vdev.h>
-#include <cmdline_parse.h>
-#include <cmdline_parse_etheraddr.h>
-
-#include "rte_xen_lib.h"
-#include "virtqueue.h"
-#include "rte_eth_xenvirt.h"
-
-#define VQ_DESC_NUM 256
-#define VIRTIO_MBUF_BURST_SZ 64
-
-/* virtio_idx is increased after new device is created.*/
-static int virtio_idx = 0;
-
-static struct rte_eth_link pmd_link = {
-		.link_speed = ETH_SPEED_NUM_10G,
-		.link_duplex = ETH_LINK_FULL_DUPLEX,
-		.link_status = ETH_LINK_DOWN,
-		.link_autoneg = ETH_LINK_SPEED_FIXED
-};
-
-static void
-eth_xenvirt_free_queues(struct rte_eth_dev *dev);
-
-static uint16_t
-eth_xenvirt_rx(void *q, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
-{
-	struct virtqueue *rxvq = q;
-	struct rte_mbuf *rxm, *new_mbuf;
-	uint16_t nb_used, num;
-	uint32_t len[VIRTIO_MBUF_BURST_SZ];
-	uint32_t i;
-	struct pmd_internals *pi = rxvq->internals;
-
-	nb_used = VIRTQUEUE_NUSED(rxvq);
-
-	rte_smp_rmb();
-	num = (uint16_t)(likely(nb_used <= nb_pkts) ? nb_used : nb_pkts);
-	num = (uint16_t)(likely(num <= VIRTIO_MBUF_BURST_SZ) ? num : VIRTIO_MBUF_BURST_SZ);
-	if (unlikely(num == 0)) return 0;
-
-	num = virtqueue_dequeue_burst(rxvq, rx_pkts, len, num);
-	PMD_RX_LOG(DEBUG, "used:%d dequeue:%d\n", nb_used, num);
-	for (i = 0; i < num ; i ++) {
-		rxm = rx_pkts[i];
-		PMD_RX_LOG(DEBUG, "packet len:%d\n", len[i]);
-		rxm->next = NULL;
-		rxm->data_off = RTE_PKTMBUF_HEADROOM;
-		rxm->data_len = (uint16_t)(len[i] - sizeof(struct virtio_net_hdr));
-		rxm->nb_segs = 1;
-		rxm->port = pi->port_id;
-		rxm->pkt_len  = (uint32_t)(len[i] - sizeof(struct virtio_net_hdr));
-	}
-	/* allocate new mbuf for the used descriptor */
-	while (likely(!virtqueue_full(rxvq))) {
-		new_mbuf = rte_mbuf_raw_alloc(rxvq->mpool);
-		if (unlikely(new_mbuf == NULL)) {
-			break;
-		}
-		if (unlikely(virtqueue_enqueue_recv_refill(rxvq, new_mbuf))) {
-			rte_pktmbuf_free_seg(new_mbuf);
-			break;
-		}
-	}
-	pi->eth_stats.ipackets += num;
-	return num;
-}
-
-static uint16_t
-eth_xenvirt_tx(void *tx_queue, struct rte_mbuf **tx_pkts, uint16_t nb_pkts)
-{
-	struct virtqueue *txvq = tx_queue;
-	struct rte_mbuf *txm;
-	uint16_t nb_used, nb_tx, num, i;
-	int error;
-	uint32_t len[VIRTIO_MBUF_BURST_SZ];
-	struct rte_mbuf *snd_pkts[VIRTIO_MBUF_BURST_SZ];
-	struct pmd_internals *pi = txvq->internals;
-
-	nb_tx = 0;
-
-	if (unlikely(nb_pkts == 0))
-		return 0;
-
-	PMD_TX_LOG(DEBUG, "%d packets to xmit", nb_pkts);
-	nb_used = VIRTQUEUE_NUSED(txvq);
-
-	rte_smp_rmb();
-
-	num = (uint16_t)(likely(nb_used <= VIRTIO_MBUF_BURST_SZ) ? nb_used : VIRTIO_MBUF_BURST_SZ);
-	num = virtqueue_dequeue_burst(txvq, snd_pkts, len, num);
-
-	for (i = 0; i < num ; i ++) {
-		/* mergable not supported, one segment only */
-		rte_pktmbuf_free_seg(snd_pkts[i]);
-	}
-
-	while (nb_tx < nb_pkts) {
-		if (likely(!virtqueue_full(txvq))) {
-		/* TODO drop tx_pkts if it contains multiple segments */
-			txm = tx_pkts[nb_tx];
-			error = virtqueue_enqueue_xmit(txvq, txm);
-			if (unlikely(error)) {
-				if (error == ENOSPC)
-					PMD_TX_LOG(ERR, "virtqueue_enqueue Free count = 0\n");
-				else if (error == EMSGSIZE)
-					PMD_TX_LOG(ERR, "virtqueue_enqueue Free count < 1\n");
-				else
-					PMD_TX_LOG(ERR, "virtqueue_enqueue error: %d\n", error);
-				break;
-			}
-			nb_tx++;
-		} else {
-			PMD_TX_LOG(ERR, "No free tx descriptors to transmit\n");
-			/* virtqueue_notify not needed in our para-virt solution */
-			break;
-		}
-	}
-	pi->eth_stats.opackets += nb_tx;
-	return nb_tx;
-}
-
-static int
-eth_dev_configure(struct rte_eth_dev *dev __rte_unused)
-{
-	RTE_LOG(ERR, PMD, "%s\n", __func__);
-	return 0;
-}
-
-/*
- * Create a shared page between guest and host.
- * Host monitors this page if it is cleared on unmap, and then
- * do necessary clean up.
- */
-static void
-gntalloc_vring_flag(int vtidx)
-{
-	char key_str[PATH_MAX];
-	char val_str[PATH_MAX];
-	uint32_t gref_tmp;
-	void *ptr;
-
-	if (grefwatch_from_alloc(&gref_tmp, &ptr)) {
-		RTE_LOG(ERR, PMD, "grefwatch_from_alloc error\n");
-		exit(0);
-	}
-
-	*(uint8_t *)ptr = MAP_FLAG;
-	snprintf(val_str, sizeof(val_str), "%u", gref_tmp);
-	snprintf(key_str, sizeof(key_str),
-		DPDK_XENSTORE_PATH"%d"VRING_FLAG_STR, vtidx);
-	xenstore_write(key_str, val_str);
-}
-
-/*
- * Notify host this virtio device is started.
- * Host could start polling this device.
- */
-static void
-dev_start_notify(int vtidx)
-{
-	char key_str[PATH_MAX];
-	char val_str[PATH_MAX];
-
-	RTE_LOG(INFO, PMD, "%s: virtio %d is started\n", __func__, vtidx);
-	gntalloc_vring_flag(vtidx);
-
-	snprintf(key_str, sizeof(key_str), "%s%s%d",
-		DPDK_XENSTORE_PATH, EVENT_TYPE_START_STR,
-			vtidx);
-	snprintf(val_str, sizeof(val_str), "1");
-	xenstore_write(key_str, val_str);
-}
-
-/*
- * Notify host this virtio device is stopped.
- * Host could stop polling this device.
- */
-static void
-dev_stop_notify(int vtidx)
-{
-	RTE_SET_USED(vtidx);
-}
-
-
-static int
-update_mac_address(struct ether_addr *mac_addrs, int vtidx)
-{
-	char key_str[PATH_MAX];
-	char val_str[PATH_MAX];
-	int rv;
-
-	if (mac_addrs == NULL) {
-		RTE_LOG(ERR, PMD, "%s: NULL pointer mac specified\n", __func__);
-		return -1;
-	}
-	rv = snprintf(key_str, sizeof(key_str),
-			DPDK_XENSTORE_PATH"%d_ether_addr", vtidx);
-	if (rv == -1)
-		return rv;
-	rv = snprintf(val_str, sizeof(val_str), "%02x:%02x:%02x:%02x:%02x:%02x",
-			mac_addrs->addr_bytes[0],
-			mac_addrs->addr_bytes[1],
-			mac_addrs->addr_bytes[2],
-			mac_addrs->addr_bytes[3],
-			mac_addrs->addr_bytes[4],
-			mac_addrs->addr_bytes[5]);
-	if (rv == -1)
-		return rv;
-	if (xenstore_write(key_str, val_str))
-		return rv;
-	return 0;
-}
-
-
-static int
-eth_dev_start(struct rte_eth_dev *dev)
-{
-	struct virtqueue *rxvq = dev->data->rx_queues[0];
-	struct virtqueue *txvq = dev->data->tx_queues[0];
-	struct rte_mbuf *m;
-	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
-	int rv;
-
-	dev->data->dev_link.link_status = ETH_LINK_UP;
-	while (!virtqueue_full(rxvq)) {
-		m = rte_mbuf_raw_alloc(rxvq->mpool);
-		if (m == NULL)
-			break;
-		/* Enqueue allocated buffers. */
-		if (virtqueue_enqueue_recv_refill(rxvq, m)) {
-			rte_pktmbuf_free_seg(m);
-			break;
-		}
-	}
-
-	rxvq->internals = pi;
-	txvq->internals = pi;
-
-	rv = update_mac_address(dev->data->mac_addrs, pi->virtio_idx);
-	if (rv)
-		return -1;
-	dev_start_notify(pi->virtio_idx);
-
-	return 0;
-}
-
-static void
-eth_dev_stop(struct rte_eth_dev *dev)
-{
-	struct pmd_internals *pi = (struct pmd_internals *)dev->data->dev_private;
-
-	dev->data->dev_link.link_status = ETH_LINK_DOWN;
-	dev_stop_notify(pi->virtio_idx);
-}
-
-/*
- * Notify host this virtio device is closed.
- * Host could do necessary clean up to this device.
- */
-static void
-eth_dev_close(struct rte_eth_dev *dev)
-{
-	eth_xenvirt_free_queues(dev);
-}
-
-static void
-eth_dev_info(struct rte_eth_dev *dev,
-		struct rte_eth_dev_info *dev_info)
-{
-	struct pmd_internals *internals = dev->data->dev_private;
-
-	RTE_SET_USED(internals);
-	dev_info->max_mac_addrs = 1;
-	dev_info->max_rx_pktlen = (uint32_t)2048;
-	dev_info->max_rx_queues = (uint16_t)1;
-	dev_info->max_tx_queues = (uint16_t)1;
-	dev_info->min_rx_bufsize = 0;
-}
-
-static void
-eth_stats_get(struct rte_eth_dev *dev, struct rte_eth_stats *stats)
-{
-	struct pmd_internals *internals = dev->data->dev_private;
-	if(stats)
-		rte_memcpy(stats, &internals->eth_stats, sizeof(*stats));
-}
-
-static void
-eth_stats_reset(struct rte_eth_dev *dev)
-{
-	struct pmd_internals *internals = dev->data->dev_private;
-	/* Reset software totals */
-	memset(&internals->eth_stats, 0, sizeof(internals->eth_stats));
-}
-
-static void
-eth_queue_release(void *q)
-{
-	rte_free(q);
-}
-
-static int
-eth_link_update(struct rte_eth_dev *dev __rte_unused,
-		int wait_to_complete __rte_unused)
-{
-	return 0;
-}
-
-/*
- * Create shared vring between guest and host.
- * Memory is allocated through grant alloc driver, so it is not physical continuous.
- */
-static void *
-gntalloc_vring_create(int queue_type, uint32_t size, int vtidx)
-{
-	char key_str[PATH_MAX] = {0};
-	char val_str[PATH_MAX] = {0};
-	void *va = NULL;
-	int pg_size;
-	uint32_t pg_num;
-	uint32_t *gref_arr = NULL;
-	phys_addr_t *pa_arr = NULL;
-	uint64_t start_index;
-	int rv;
-
-	pg_size = getpagesize();
-	size    = RTE_ALIGN_CEIL(size, pg_size);
-	pg_num  = size / pg_size;
-
-	gref_arr = calloc(pg_num, sizeof(gref_arr[0]));
-	pa_arr  = calloc(pg_num, sizeof(pa_arr[0]));
-
-	if (gref_arr == NULL || pa_arr == NULL) {
-		RTE_LOG(ERR, PMD, "%s: calloc failed\n", __func__);
-		goto out;
-	}
-
-	va  = gntalloc(size, gref_arr, &start_index);
-	if (va == NULL) {
-		RTE_LOG(ERR, PMD, "%s: gntalloc failed\n", __func__);
-		goto out;
-	}
-
-	if (get_phys_map(va, pa_arr, pg_num, pg_size))
-		goto out;
-
-	/* write in xenstore gref and pfn for each page of vring */
-	if (grant_node_create(pg_num, gref_arr, pa_arr, val_str, sizeof(val_str))) {
-		gntfree(va, size, start_index);
-		va = NULL;
-		goto out;
-	}
-
-	if (queue_type == VTNET_RQ)
-		rv = snprintf(key_str, sizeof(key_str), DPDK_XENSTORE_PATH"%d"RXVRING_XENSTORE_STR, vtidx);
-	else
-		rv = snprintf(key_str, sizeof(key_str), DPDK_XENSTORE_PATH"%d"TXVRING_XENSTORE_STR, vtidx);
-	if (rv == -1 || xenstore_write(key_str, val_str) == -1) {
-		gntfree(va, size, start_index);
-		va = NULL;
-	}
-out:
-	free(pa_arr);
-	free(gref_arr);
-
-	return va;
-}
-
-
-
-static struct virtqueue *
-virtio_queue_setup(struct rte_eth_dev *dev, int queue_type)
-{
-	struct virtqueue *vq = NULL;
-	uint16_t vq_size = VQ_DESC_NUM;
-	int i = 0;
-	char vq_name[VIRTQUEUE_MAX_NAME_SZ];
-	size_t size;
-	struct vring *vr;
-
-	/* Allocate memory for virtqueue. */
-	if (queue_type == VTNET_RQ) {
-		snprintf(vq_name, sizeof(vq_name), "port%d_rvq",
-				dev->data->port_id);
-		vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) +
-			vq_size * sizeof(struct vq_desc_extra), RTE_CACHE_LINE_SIZE);
-		if (vq == NULL) {
-			RTE_LOG(ERR, PMD, "%s: unabled to allocate virtqueue\n", __func__);
-			return NULL;
-		}
-		memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
-	} else if(queue_type == VTNET_TQ) {
-		snprintf(vq_name, sizeof(vq_name), "port%d_tvq",
-			dev->data->port_id);
-		vq = rte_zmalloc(vq_name, sizeof(struct virtqueue) +
-			vq_size * sizeof(struct vq_desc_extra), RTE_CACHE_LINE_SIZE);
-		if (vq == NULL) {
-			RTE_LOG(ERR, PMD, "%s: unabled to allocate virtqueue\n", __func__);
-			return NULL;
-		}
-		memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
-	}
-
-	memcpy(vq->vq_name, vq_name, sizeof(vq->vq_name));
-
-	vq->vq_alignment = VIRTIO_PCI_VRING_ALIGN;
-	vq->vq_nentries = vq_size;
-	vq->vq_free_cnt = vq_size;
-	/* Calcuate vring size according to virtio spec */
-	size = vring_size(vq_size, VIRTIO_PCI_VRING_ALIGN);
-	vq->vq_ring_size = RTE_ALIGN_CEIL(size, VIRTIO_PCI_VRING_ALIGN);
-	/* Allocate memory for virtio vring through gntalloc driver*/
-	vq->vq_ring_virt_mem = gntalloc_vring_create(queue_type, vq->vq_ring_size,
-		((struct pmd_internals *)dev->data->dev_private)->virtio_idx);
-	memset(vq->vq_ring_virt_mem, 0, vq->vq_ring_size);
-	vr = &vq->vq_ring;
-	vring_init(vr, vq_size, vq->vq_ring_virt_mem, vq->vq_alignment);
-	/*
-	 * Locally maintained last consumed index, this idex trails
-	 * vq_ring.used->idx.
-	 */
-	vq->vq_used_cons_idx = 0;
-	vq->vq_desc_head_idx = 0;
-	vq->vq_free_cnt = vq->vq_nentries;
-	memset(vq->vq_descx, 0, sizeof(struct vq_desc_extra) * vq->vq_nentries);
-
-	/* Chain all the descriptors in the ring with an END */
-	for (i = 0; i < vq_size - 1; i++)
-		vr->desc[i].next = (uint16_t)(i + 1);
-	vr->desc[i].next = VQ_RING_DESC_CHAIN_END;
-
-	return vq;
-}
-
-static int
-eth_rx_queue_setup(struct rte_eth_dev *dev,uint16_t rx_queue_id,
-				uint16_t nb_rx_desc __rte_unused,
-				unsigned int socket_id __rte_unused,
-				const struct rte_eth_rxconf *rx_conf __rte_unused,
-				struct rte_mempool *mb_pool)
-{
-	struct virtqueue *vq;
-	vq = dev->data->rx_queues[rx_queue_id] = virtio_queue_setup(dev, VTNET_RQ);
-	vq->mpool = mb_pool;
-	return 0;
-}
-
-static int
-eth_tx_queue_setup(struct rte_eth_dev *dev, uint16_t tx_queue_id,
-				uint16_t nb_tx_desc __rte_unused,
-				unsigned int socket_id __rte_unused,
-				const struct rte_eth_txconf *tx_conf __rte_unused)
-{
-	dev->data->tx_queues[tx_queue_id] = virtio_queue_setup(dev, VTNET_TQ);
-	return 0;
-}
-
-static void
-eth_xenvirt_free_queues(struct rte_eth_dev *dev)
-{
-	int i;
-
-	for (i = 0; i < dev->data->nb_rx_queues; i++) {
-		eth_queue_release(dev->data->rx_queues[i]);
-		dev->data->rx_queues[i] = NULL;
-	}
-	dev->data->nb_rx_queues = 0;
-
-	for (i = 0; i < dev->data->nb_tx_queues; i++) {
-		eth_queue_release(dev->data->tx_queues[i]);
-		dev->data->tx_queues[i] = NULL;
-	}
-	dev->data->nb_tx_queues = 0;
-}
-
-static const struct eth_dev_ops ops = {
-	.dev_start = eth_dev_start,
-	.dev_stop = eth_dev_stop,
-	.dev_close = eth_dev_close,
-	.dev_configure = eth_dev_configure,
-	.dev_infos_get = eth_dev_info,
-	.rx_queue_setup = eth_rx_queue_setup,
-	.tx_queue_setup = eth_tx_queue_setup,
-	.rx_queue_release = eth_queue_release,
-	.tx_queue_release = eth_queue_release,
-	.link_update = eth_link_update,
-	.stats_get = eth_stats_get,
-	.stats_reset = eth_stats_reset,
-};
-
-
-static int
-rte_eth_xenvirt_parse_args(struct xenvirt_dict *dict,
-			const char *name, const char *params)
-{
-	int i;
-	char *pairs[RTE_ETH_XENVIRT_MAX_ARGS];
-	int num_of_pairs;
-	char *pair[2];
-	char *args;
-	int ret = -1;
-
-	if (params == NULL)
-		return 0;
-
-	args = rte_zmalloc(NULL, strlen(params) + 1, RTE_CACHE_LINE_SIZE);
-	if (args == NULL) {
-		RTE_LOG(ERR, PMD, "Couldn't parse %s device \n", name);
-		return -1;
-	}
-	rte_memcpy(args, params, strlen(params));
-
-	num_of_pairs = rte_strsplit(args, strnlen(args, MAX_ARG_STRLEN),
-					pairs,
-					RTE_ETH_XENVIRT_MAX_ARGS ,
-					RTE_ETH_XENVIRT_PAIRS_DELIM);
-
-	for (i = 0; i < num_of_pairs; i++) {
-		pair[0] = NULL;
-		pair[1] = NULL;
-		rte_strsplit(pairs[i], strnlen(pairs[i], MAX_ARG_STRLEN),
-					pair, 2,
-					RTE_ETH_XENVIRT_KEY_VALUE_DELIM);
-
-		if (pair[0] == NULL || pair[1] == NULL || pair[0][0] == 0
-			|| pair[1][0] == 0) {
-			RTE_LOG(ERR, PMD,
-				"Couldn't parse %s device,"
-				"wrong key or value \n", name);
-			goto err;
-		}
-
-		if (!strncmp(pair[0], RTE_ETH_XENVIRT_MAC_PARAM,
-				sizeof(RTE_ETH_XENVIRT_MAC_PARAM))) {
-			if (cmdline_parse_etheraddr(NULL,
-						    pair[1],
-						    &dict->addr,
-						    sizeof(dict->addr)) < 0) {
-				RTE_LOG(ERR, PMD,
-					"Invalid %s device ether address\n",
-					name);
-				goto err;
-			}
-
-			dict->addr_valid = 1;
-		}
-	}
-
-	ret = 0;
-err:
-	rte_free(args);
-	return ret;
-}
-
-enum dev_action {
-	DEV_CREATE,
-	DEV_ATTACH
-};
-
-static struct rte_vdev_driver pmd_xenvirt_drv;
-
-static int
-eth_dev_xenvirt_create(const char *name, const char *params,
-		const unsigned numa_node,
-                enum dev_action action)
-{
-	struct rte_eth_dev_data *data = NULL;
-	struct pmd_internals *internals = NULL;
-	struct rte_eth_dev *eth_dev = NULL;
-	struct xenvirt_dict dict;
-
-	memset(&dict, 0, sizeof(struct xenvirt_dict));
-
-	RTE_LOG(INFO, PMD, "Creating virtio rings backed ethdev on numa socket %u\n",
-			numa_node);
-	RTE_SET_USED(action);
-
-	if (rte_eth_xenvirt_parse_args(&dict, name, params) < 0) {
-		RTE_LOG(ERR, PMD, "%s: Failed to parse ethdev parameters\n", __func__);
-		return -1;
-	}
-
-	/* now do all data allocation - for eth_dev structure, dummy pci driver
-	 * and internal (private) data
-	 */
-	data = rte_zmalloc_socket(name, sizeof(*data), 0, numa_node);
-	if (data == NULL)
-		goto err;
-
-	internals = rte_zmalloc_socket(name, sizeof(*internals), 0, numa_node);
-	if (internals == NULL)
-		goto err;
-
-	/* reserve an ethdev entry */
-	eth_dev = rte_eth_dev_allocate(name);
-	if (eth_dev == NULL)
-		goto err;
-
-	data->dev_private = internals;
-	data->port_id = eth_dev->data->port_id;
-	data->nb_rx_queues = (uint16_t)1;
-	data->nb_tx_queues = (uint16_t)1;
-	data->dev_link = pmd_link;
-	data->mac_addrs = rte_zmalloc("xen_virtio", ETHER_ADDR_LEN, 0);
-
-	if(dict.addr_valid)
-		memcpy(&data->mac_addrs->addr_bytes, &dict.addr, sizeof(struct ether_addr));
-	else
-		eth_random_addr(&data->mac_addrs->addr_bytes[0]);
-
-	eth_dev->data = data;
-	eth_dev->dev_ops = &ops;
-
-	eth_dev->data->dev_flags = RTE_ETH_DEV_DETACHABLE;
-	eth_dev->data->kdrv = RTE_KDRV_NONE;
-	eth_dev->data->numa_node = numa_node;
-
-	eth_dev->rx_pkt_burst = eth_xenvirt_rx;
-	eth_dev->tx_pkt_burst = eth_xenvirt_tx;
-
-	internals->virtio_idx = virtio_idx++;
-	internals->port_id = eth_dev->data->port_id;
-
-	return 0;
-
-err:
-	rte_free(data);
-	rte_free(internals);
-
-	return -1;
-}
-
-
-static int
-eth_dev_xenvirt_free(const char *name, const unsigned numa_node)
-{
-	struct rte_eth_dev *eth_dev = NULL;
-
-	RTE_LOG(DEBUG, PMD,
-		"Free virtio rings backed ethdev on numa socket %u\n",
-		numa_node);
-
-	/* find an ethdev entry */
-	eth_dev = rte_eth_dev_allocated(name);
-	if (eth_dev == NULL)
-		return -1;
-
-	if (eth_dev->data->dev_started == 1) {
-		eth_dev_stop(eth_dev);
-		eth_dev_close(eth_dev);
-	}
-
-	eth_dev->rx_pkt_burst = NULL;
-	eth_dev->tx_pkt_burst = NULL;
-	eth_dev->dev_ops = NULL;
-
-	rte_free(eth_dev->data);
-	rte_free(eth_dev->data->dev_private);
-	rte_free(eth_dev->data->mac_addrs);
-
-	virtio_idx--;
-
-	return 0;
-}
-
-/*TODO: Support multiple process model */
-static int
-rte_pmd_xenvirt_probe(struct rte_vdev_device *dev)
-{
-	if (virtio_idx == 0) {
-		if (xenstore_init() != 0) {
-			RTE_LOG(ERR, PMD, "%s: xenstore init failed\n", __func__);
-			return -1;
-		}
-		if (gntalloc_open() != 0) {
-			RTE_LOG(ERR, PMD, "%s: grant init failed\n", __func__);
-			return -1;
-		}
-	}
-	eth_dev_xenvirt_create(rte_vdev_device_name(dev),
-		rte_vdev_device_args(dev), rte_socket_id(), DEV_CREATE);
-	return 0;
-}
-
-static int
-rte_pmd_xenvirt_remove(struct rte_vdev_device *dev)
-{
-	eth_dev_xenvirt_free(rte_vdev_device_name(dev), rte_socket_id());
-
-	if (virtio_idx == 0) {
-		if (xenstore_uninit() != 0)
-			RTE_LOG(ERR, PMD, "%s: xenstore uninit failed\n", __func__);
-
-		gntalloc_close();
-	}
-	return 0;
-}
-
-static struct rte_vdev_driver pmd_xenvirt_drv = {
-	.probe = rte_pmd_xenvirt_probe,
-	.remove = rte_pmd_xenvirt_remove,
-};
-
-RTE_PMD_REGISTER_VDEV(net_xenvirt, pmd_xenvirt_drv);
-RTE_PMD_REGISTER_ALIAS(net_xenvirt, eth_xenvirt);
-RTE_PMD_REGISTER_PARAM_STRING(net_xenvirt,
-	"mac=<mac addr>");
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt.h b/drivers/net/xenvirt/rte_eth_xenvirt.h
deleted file mode 100644
index 598adc6..0000000
--- a/drivers/net/xenvirt/rte_eth_xenvirt.h
+++ /dev/null
@@ -1,61 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_ETH_XENVIRT_H_
-#define _RTE_ETH_XENVIRT_H_
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#include <rte_mempool.h>
-
-/**
- * Creates mempool for xen virtio PMD.
- * This function uses memzone_reserve to allocate memory for meta data,
- * and uses grant alloc driver to allocate memory for data area.
- * The input parameters are exactly the same as rte_mempool_create.
- */
-struct rte_mempool *
-rte_mempool_gntalloc_create(const char *name, unsigned elt_num, unsigned elt_size,
-		   unsigned cache_size, unsigned private_data_size,
-		   rte_mempool_ctor_t *mp_init, void *mp_init_arg,
-		   rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
-		   int socket_id, unsigned flags);
-
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif
diff --git a/drivers/net/xenvirt/rte_eth_xenvirt_version.map b/drivers/net/xenvirt/rte_eth_xenvirt_version.map
deleted file mode 100644
index dd636f7..0000000
--- a/drivers/net/xenvirt/rte_eth_xenvirt_version.map
+++ /dev/null
@@ -1,7 +0,0 @@
-DPDK_2.0 {
-	global:
-
-	rte_mempool_gntalloc_create;
-
-	local: *;
-};
diff --git a/drivers/net/xenvirt/rte_mempool_gntalloc.c b/drivers/net/xenvirt/rte_mempool_gntalloc.c
deleted file mode 100644
index 73e82f8..0000000
--- a/drivers/net/xenvirt/rte_mempool_gntalloc.c
+++ /dev/null
@@ -1,295 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <string.h>
-#include <xen/sys/gntalloc.h>
-
-#include <rte_common.h>
-#include <rte_mempool.h>
-#include <rte_memory.h>
-#include <rte_errno.h>
-
-#include "rte_xen_lib.h"
-#include "rte_eth_xenvirt.h"
-
-struct _gntarr {
-	uint32_t gref;
-	phys_addr_t pa;
-	uint64_t index;
-	void *va;
-};
-
-struct _mempool_gntalloc_info {
-	struct rte_mempool *mp;
-	uint32_t pg_num;
-	uint32_t *gref_arr;
-	phys_addr_t *pa_arr;
-	void *va;
-	uint32_t mempool_idx;
-	uint64_t start_index;
-};
-
-
-static rte_atomic32_t global_xenvirt_mempool_idx = RTE_ATOMIC32_INIT(-1);
-
-static int
-compare(const void *p1, const void *p2)
-{
-	return ((const struct _gntarr *)p1)->pa  - ((const struct _gntarr *)p2)->pa;
-}
-
-
-static struct _mempool_gntalloc_info
-_create_mempool(const char *name, unsigned elt_num, unsigned elt_size,
-		   unsigned cache_size, unsigned private_data_size,
-		   rte_mempool_ctor_t *mp_init, void *mp_init_arg,
-		   rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
-		   int socket_id, unsigned flags)
-{
-	struct _mempool_gntalloc_info mgi;
-	struct rte_mempool *mp = NULL;
-	struct rte_mempool_objsz  objsz;
-	uint32_t pg_num, rpg_num, pg_shift, pg_sz;
-	char *va, *orig_va, *uv; /* uv: from which, the pages could be freed */
-	ssize_t sz, usz; /* usz: unused size */
-	/*
-	 * for each page allocated through xen_gntalloc driver,
-	 * gref_arr:stores grant references,
-	 * pa_arr: stores physical address,
-	 * gnt_arr: stores all meta dat
-	 */
-	uint32_t *gref_arr = NULL;
-	phys_addr_t *pa_arr = NULL;
-	struct _gntarr *gnt_arr = NULL;
-	/* start index of the grant referances, used for dealloc*/
-	uint64_t start_index;
-	uint32_t i, j;
-	int rv = 0;
-	struct ioctl_gntalloc_dealloc_gref arg;
-
-	mgi.mp = NULL;
-	va = orig_va = uv = NULL;
-	pg_num = rpg_num = 0;
-	sz = 0;
-
-	pg_sz = getpagesize();
-	if (rte_is_power_of_2(pg_sz) == 0) {
-		goto out;
-	}
-	pg_shift = rte_bsf32(pg_sz);
-
-	rte_mempool_calc_obj_size(elt_size, flags, &objsz);
-	sz = rte_mempool_xmem_size(elt_num, objsz.total_size, pg_shift);
-	pg_num = sz >> pg_shift;
-
-	pa_arr = calloc(pg_num, sizeof(pa_arr[0]));
-	gref_arr = calloc(pg_num, sizeof(gref_arr[0]));
-	gnt_arr  = calloc(pg_num, sizeof(gnt_arr[0]));
-	if ((gnt_arr == NULL) || (gref_arr == NULL) || (pa_arr == NULL))
-		goto out;
-
-	/* grant index is continuous in ascending order */
-	orig_va = gntalloc(sz, gref_arr, &start_index);
-	if (orig_va == NULL)
-		goto out;
-
-	get_phys_map(orig_va, pa_arr, pg_num, pg_sz);
-	for (i = 0; i < pg_num; i++) {
-		gnt_arr[i].index = start_index + i * pg_sz;
-		gnt_arr[i].gref = gref_arr[i];
-		gnt_arr[i].pa = pa_arr[i];
-		gnt_arr[i].va  = RTE_PTR_ADD(orig_va, i * pg_sz);
-	}
-	qsort(gnt_arr, pg_num, sizeof(struct _gntarr), compare);
-
-	va = get_xen_virtual(sz, pg_sz);
-	if (va == NULL) {
-		goto out;
-	}
-
-	/*
-	 * map one by one, as index isn't continuous now.
-	 * pg_num VMAs, doesn't linux has a limitation on this?
-	 */
-	for (i = 0; i < pg_num; i++) {
-	/* update gref_arr and pa_arr after sort */
-		gref_arr[i] = gnt_arr[i].gref;
-		pa_arr[i]   = gnt_arr[i].pa;
-		gnt_arr[i].va = mmap(va + i * pg_sz, pg_sz, PROT_READ | PROT_WRITE,
-			MAP_SHARED | MAP_FIXED, gntalloc_fd, gnt_arr[i].index);
-		if ((gnt_arr[i].va == MAP_FAILED) || (gnt_arr[i].va != (va + i * pg_sz))) {
-			RTE_LOG(ERR, PMD, "failed to map %d pages\n", i);
-			goto mmap_failed;
-		}
-	}
-
-	/*
-	 * Check that allocated size is big enough to hold elt_num
-	 * objects and a calcualte how many bytes are actually required.
-	 */
-	usz = rte_mempool_xmem_usage(va, elt_num, objsz.total_size, pa_arr, pg_num, pg_shift);
-	if (usz < 0) {
-		mp = NULL;
-		i = pg_num;
-		goto mmap_failed;
-	} else {
-		/* unmap unused pages if any */
-		uv = RTE_PTR_ADD(va, usz);
-		if ((usz = va + sz - uv) > 0) {
-
-			RTE_LOG(ERR, PMD,
-				"%s(%s): unmap unused %zu of %zu "
-				"mmaped bytes @%p orig:%p\n",
-				__func__, name, usz, sz, uv, va);
-			munmap(uv, usz);
-			i = (sz - usz) / pg_sz;
-			for (; i < pg_num; i++) {
-				arg.count = 1;
-				arg.index = gnt_arr[i].index;
-				rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg);
-				if (rv) {
-					/* shouldn't fail here */
-					RTE_LOG(ERR, PMD, "va=%p pa=%"PRIu64"x index=%"PRIu64" %s\n",
-						gnt_arr[i].va,
-						gnt_arr[i].pa,
-						arg.index, strerror(errno));
-					rte_panic("gntdealloc failed when freeing pages\n");
-				}
-			}
-
-			rpg_num = (sz - usz) >> pg_shift;
-		} else
-			rpg_num = pg_num;
-
-		mp = rte_mempool_xmem_create(name, elt_num, elt_size,
-				cache_size, private_data_size,
-				mp_init, mp_init_arg,
-				obj_init, obj_init_arg,
-				socket_id, flags, va, pa_arr, rpg_num, pg_shift);
-
-		RTE_ASSERT(elt_num == mp->size);
-	}
-	mgi.mp = mp;
-	mgi.pg_num = rpg_num;
-	mgi.gref_arr = gref_arr;
-	mgi.pa_arr = pa_arr;
-	if (mp)
-		mgi.mempool_idx = rte_atomic32_add_return(&global_xenvirt_mempool_idx, 1);
-	mgi.start_index = start_index;
-	mgi.va = va;
-
-	if (mp == NULL) {
-		i = pg_num;
-		goto mmap_failed;
-	}
-
-/*
- * unmap only, without deallocate grant reference.
- * unused pages have already been unmaped,
- * unmap twice will fail, but it is safe.
- */
-mmap_failed:
-	for (j = 0; j < i; j++) {
-		if (gnt_arr[i].va)
-			munmap(gnt_arr[i].va, pg_sz);
-	}
-out:
-	free(gnt_arr);
-	if (orig_va)
-		munmap(orig_va, sz);
-	if (mp == NULL) {
-		free(gref_arr);
-		free(pa_arr);
-
-		/* some gref has already been de-allocated from the list in the driver,
-		 * so dealloc one by one, and it is safe to deallocate twice
-		 */
-		if (orig_va) {
-			for (i = 0; i < pg_num; i++) {
-				arg.index = start_index + i * pg_sz;
-				rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, arg);
-			}
-		}
-	}
-	return mgi;
-}
-
-struct rte_mempool *
-rte_mempool_gntalloc_create(const char *name, unsigned elt_num, unsigned elt_size,
-		   unsigned cache_size, unsigned private_data_size,
-		   rte_mempool_ctor_t *mp_init, void *mp_init_arg,
-		   rte_mempool_obj_cb_t *obj_init, void *obj_init_arg,
-		   int socket_id, unsigned flags)
-{
-	int rv;
-	uint32_t i;
-	struct _mempool_gntalloc_info mgi;
-	struct ioctl_gntalloc_dealloc_gref arg;
-	int pg_sz = getpagesize();
-
-	mgi = _create_mempool(name, elt_num, elt_size,
-			cache_size, private_data_size,
-			mp_init, mp_init_arg,
-			obj_init, obj_init_arg,
-			socket_id, flags);
-	if (mgi.mp) {
-		rv = grant_gntalloc_mbuf_pool(mgi.mp,
-			mgi.pg_num,
-			mgi.gref_arr,
-			mgi.pa_arr,
-			mgi.mempool_idx);
-		free(mgi.gref_arr);
-		free(mgi.pa_arr);
-		if (rv == 0)
-			return mgi.mp;
-		/*
-		 * in _create_mempool, unused pages have already been unmapped, deallocagted
-		 * unmap and dealloc the remained ones here.
-		 */
-		munmap(mgi.va, pg_sz * mgi.pg_num);
-		for (i = 0; i < mgi.pg_num; i++) {
-			arg.index = mgi.start_index + i * pg_sz;
-			rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, arg);
-		}
-		return NULL;
-	}
-	return NULL;
-
-
-
-}
diff --git a/drivers/net/xenvirt/rte_xen_lib.c b/drivers/net/xenvirt/rte_xen_lib.c
deleted file mode 100644
index 6c9a1d4..0000000
--- a/drivers/net/xenvirt/rte_xen_lib.c
+++ /dev/null
@@ -1,454 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <sys/types.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/ioctl.h>
-#include <xen/xen-compat.h>
-#if __XEN_LATEST_INTERFACE_VERSION__ < 0x00040200
-#include <xs.h>
-#else
-#include <xenstore.h>
-#endif
-#include <xen/sys/gntalloc.h>
-
-#include <rte_common.h>
-#include <rte_string_fns.h>
-#include <rte_malloc.h>
-
-#include "rte_xen_lib.h"
-
-/*
- * The grant node format in xenstore for vring/mpool is:
- * 0_rx_vring_gref = "gref1#, gref2#, gref3#"
- * 0_mempool_gref  = "gref1#, gref2#, gref3#"
- * each gref# is a grant reference for a shared page.
- * In each shared page, we store the grant_node_item items.
- */
-struct grant_node_item {
-	uint32_t gref;
-	uint32_t pfn;
-} __attribute__((packed));
-
-/* fd for xen_gntalloc driver, used to allocate grant pages*/
-int gntalloc_fd = -1;
-
-/* xenstore path for local domain, now it is '/local/domain/domid/' */
-static char *dompath = NULL;
-/* handle to xenstore read/write operations */
-static struct xs_handle *xs = NULL;
-/* flag to indicate if xenstore cleanup is required */
-static bool is_xenstore_cleaned_up;
-
-/*
- * Reserve a virtual address space.
- * On success, returns the pointer. On failure, returns NULL.
- */
-void *
-get_xen_virtual(size_t size, size_t page_sz)
-{
-	void *addr;
-	uintptr_t aligned_addr;
-
-	addr = mmap(NULL, size + page_sz, PROT_READ, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
-	if (addr == MAP_FAILED) {
-		RTE_LOG(ERR, PMD, "failed get a virtual area\n");
-		return NULL;
-	}
-
-	aligned_addr = RTE_ALIGN_CEIL((uintptr_t)addr, page_sz);
-	addr = (void *)(aligned_addr);
-
-	return addr;
-}
-
-/*
- * Get the physical address for virtual memory starting at va.
- */
-int
-get_phys_map(void *va, phys_addr_t pa[], uint32_t pg_num, uint32_t pg_sz)
-{
-	int32_t fd, rc = 0;
-	uint32_t i, nb;
-	off_t ofs;
-
-	ofs = (uintptr_t)va / pg_sz * sizeof(*pa);
-	nb = pg_num * sizeof(*pa);
-
-	if ((fd = open(PAGEMAP_FNAME, O_RDONLY)) < 0 ||
-			(rc = pread(fd, pa, nb, ofs)) < 0 ||
-			(rc -= nb) != 0) {
-		RTE_LOG(ERR, PMD, "%s: failed read of %u bytes from \'%s\' "
-			"at offset %lu, error code: %d\n",
-			__func__, nb, PAGEMAP_FNAME, (unsigned long)ofs, errno);
-		rc = ENOENT;
-	}
-
-	close(fd);
-	for (i = 0; i != pg_num; i++)
-		pa[i] = (pa[i] & PAGEMAP_PFN_MASK) * pg_sz;
-
-	return rc;
-}
-
-int
-gntalloc_open(void)
-{
-	gntalloc_fd = open(XEN_GNTALLOC_FNAME, O_RDWR);
-	return (gntalloc_fd != -1) ? 0 : -1;
-}
-
-void
-gntalloc_close(void)
-{
-	if (gntalloc_fd != -1)
-		close(gntalloc_fd);
-	gntalloc_fd = -1;
-}
-
-void *
-gntalloc(size_t size, uint32_t *gref, uint64_t *start_index)
-{
-	int page_size = getpagesize();
-	uint32_t i, pg_num;
-	void *va;
-	int rv;
-	struct ioctl_gntalloc_alloc_gref *arg;
-	struct ioctl_gntalloc_dealloc_gref arg_d;
-
-	if (size % page_size) {
-		RTE_LOG(ERR, PMD, "%s: %zu isn't multiple of page size\n",
-			__func__, size);
-		return NULL;
-	}
-
-	pg_num = size / page_size;
-	arg = malloc(sizeof(*arg) + (pg_num - 1) * sizeof(uint32_t));
-	if (arg == NULL)
-		return NULL;
-	arg->domid = DOM0_DOMID;
-	arg->flags = GNTALLOC_FLAG_WRITABLE;
-	arg->count = pg_num;
-
-	rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_ALLOC_GREF, arg);
-	if (rv) {
-		RTE_LOG(ERR, PMD, "%s: ioctl error\n", __func__);
-		free(arg);
-		return NULL;
-	}
-
-	va = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, gntalloc_fd, arg->index);
-	if (va == MAP_FAILED) {
-		RTE_LOG(ERR, PMD, "%s: mmap failed\n", __func__);
-		arg_d.count = pg_num;
-		arg_d.index = arg->index;
-		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, arg_d);
-		free(arg);
-		return NULL;
-	}
-
-	if (gref) {
-		for (i = 0; i < pg_num; i++) {
-			gref[i] = arg->gref_ids[i];
-		}
-	}
-	if (start_index)
-		*start_index = arg->index;
-
-	free(arg);
-
-	return va;
-}
-
-int
-grefwatch_from_alloc(uint32_t *gref, void **pptr)
-{
-	int rv;
-	void *ptr;
-	int pg_size = getpagesize();
-	struct ioctl_gntalloc_alloc_gref arg = {
-		.domid = DOM0_DOMID,
-		.flags = GNTALLOC_FLAG_WRITABLE,
-		.count = 1
-	};
-	struct ioctl_gntalloc_dealloc_gref arg_d;
-	struct ioctl_gntalloc_unmap_notify notify = {
-		.action = UNMAP_NOTIFY_CLEAR_BYTE
-	};
-
-	rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_ALLOC_GREF, &arg);
-	if (rv) {
-		RTE_LOG(ERR, PMD, "%s: ioctl error\n", __func__);
-		return -1;
-	}
-
-	ptr = (void *)mmap(NULL, pg_size, PROT_READ|PROT_WRITE, MAP_SHARED, gntalloc_fd, arg.index);
-	arg_d.index = arg.index;
-	arg_d.count = 1;
-	if (ptr == MAP_FAILED) {
-		RTE_LOG(ERR, PMD, "%s: mmap failed\n", __func__);
-		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
-		return -1;
-	}
-	if (pptr)
-		*pptr = ptr;
-	if (gref)
-		*gref = arg.gref_ids[0];
-
-	notify.index = arg.index;
-	rv = ioctl(gntalloc_fd, IOCTL_GNTALLOC_SET_UNMAP_NOTIFY, &notify);
-	if (rv) {
-		RTE_LOG(ERR, PMD, "%s: unmap notify failed\n", __func__);
-		munmap(ptr, pg_size);
-		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
-		return -1;
-	}
-
-	return 0;
-}
-
-void
-gntfree(void *va, size_t sz, uint64_t start_index)
-{
-	struct ioctl_gntalloc_dealloc_gref arg_d;
-
-	if (va && sz) {
-		munmap(va, sz);
-		arg_d.count = sz / getpagesize();
-		arg_d.index = start_index;
-		ioctl(gntalloc_fd, IOCTL_GNTALLOC_DEALLOC_GREF, &arg_d);
-	}
-}
-
-static int
-xenstore_cleanup(void)
-{
-	char store_path[PATH_MAX] = {0};
-
-	if (snprintf(store_path, sizeof(store_path),
-		"%s%s", dompath, DPDK_XENSTORE_NODE) == -1)
-		return -1;
-
-	if (xs_rm(xs, XBT_NULL, store_path) == false) {
-		RTE_LOG(ERR, PMD, "%s: failed cleanup node\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-int
-xenstore_init(void)
-{
-	unsigned int len, domid;
-	char *buf;
-	char *end;
-
-	xs = xs_domain_open();
-	if (xs == NULL) {
-		RTE_LOG(ERR, PMD,"%s: xs_domain_open failed\n", __func__);
-		return -1;
-	}
-	buf = xs_read(xs, XBT_NULL, "domid", &len);
-	if (buf == NULL) {
-		RTE_LOG(ERR, PMD, "%s: failed read domid\n", __func__);
-		return -1;
-	}
-	errno = 0;
-	domid = strtoul(buf, &end, 0);
-	if (errno != 0 || end == NULL || end == buf ||  domid == 0)
-		return -1;
-
-	RTE_LOG(INFO, PMD, "retrieved dom ID = %d\n", domid);
-
-	dompath = xs_get_domain_path(xs, domid);
-	if (dompath == NULL)
-		return -1;
-
-	xs_transaction_start(xs); /* When to stop transaction */
-
-	if (is_xenstore_cleaned_up == 0) {
-		if (xenstore_cleanup())
-			return -1;
-		is_xenstore_cleaned_up = 1;
-	}
-
-	return 0;
-}
-
-int
-xenstore_uninit(void)
-{
-	xs_close(xs);
-
-	if (is_xenstore_cleaned_up == 0) {
-		if (xenstore_cleanup())
-			return -1;
-		is_xenstore_cleaned_up = 1;
-	}
-	free(dompath);
-	dompath = NULL;
-
-	return 0;
-}
-
-int
-xenstore_write(const char *key_str, const char *val_str)
-{
-	char grant_path[PATH_MAX];
-	int rv, len;
-
-	if (xs == NULL) {
-		RTE_LOG(ERR, PMD, "%s: xenstore init failed\n", __func__);
-		return -1;
-	}
-	rv = snprintf(grant_path, sizeof(grant_path), "%s%s", dompath, key_str);
-	if (rv == -1) {
-		RTE_LOG(ERR, PMD, "%s: snprintf %s %s failed\n",
-			__func__, dompath, key_str);
-		return -1;
-	}
-	len = strnlen(val_str, PATH_MAX);
-
-	if (xs_write(xs, XBT_NULL, grant_path, val_str, len) == false) {
-		RTE_LOG(ERR, PMD, "%s: xs_write failed\n", __func__);
-		return -1;
-	}
-
-	return 0;
-}
-
-int
-grant_node_create(uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, char *val_str, size_t str_size)
-{
-	uint64_t start_index;
-	int pg_size;
-	uint32_t pg_shift;
-	void *ptr = NULL;
-	uint32_t count, entries_per_pg;
-	uint32_t i, j = 0, k = 0;
-	uint32_t *gref_tmp;
-	int first = 1;
-	char tmp_str[PATH_MAX] = {0};
-	int rv = -1;
-
-	pg_size = getpagesize();
-	if (rte_is_power_of_2(pg_size) == 0) {
-		return -1;
-	}
-	pg_shift = rte_bsf32(pg_size);
-	if (pg_size % sizeof(struct grant_node_item)) {
-		RTE_LOG(ERR, PMD, "pg_size isn't a multiple of grant node item\n");
-		return -1;
-	}
-
-	entries_per_pg = pg_size / sizeof(struct grant_node_item);
-	count  = (pg_num +  entries_per_pg - 1 ) / entries_per_pg;
-	gref_tmp = malloc(count * sizeof(uint32_t));
-	if (gref_tmp == NULL)
-		return -1;
-	ptr = gntalloc(pg_size * count, gref_tmp, &start_index);
-	if (ptr == NULL) {
-		RTE_LOG(ERR, PMD, "%s: gntalloc error of %d pages\n", __func__, count);
-		free(gref_tmp);
-		return -1;
-	}
-
-	while (j < pg_num) {
-		if (first) {
-			rv = snprintf(val_str, str_size, "%u", gref_tmp[k]);
-			first = 0;
-		} else {
-			snprintf(tmp_str, PATH_MAX, "%s", val_str);
-			rv = snprintf(val_str, str_size, "%s,%u", tmp_str, gref_tmp[k]);
-		}
-		k++;
-		if (rv == -1)
-			break;
-
-		for (i = 0; i < entries_per_pg && j < pg_num ; i++) {
-			((struct grant_node_item *)ptr)->gref = gref_arr[j];
-			((struct grant_node_item *)ptr)->pfn =  pa_arr[j] >> pg_shift;
-			ptr = RTE_PTR_ADD(ptr, sizeof(struct grant_node_item));
-			j++;
-		}
-	}
-	if (rv == -1) {
-		gntfree(ptr, pg_size * count, start_index);
-	} else
-		rv = 0;
-	free(gref_tmp);
-	return rv;
-}
-
-
-int
-grant_gntalloc_mbuf_pool(struct rte_mempool *mpool, uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, int mempool_idx)
-{
-	char key_str[PATH_MAX] = {0};
-	char val_str[PATH_MAX] = {0};
-	void *mempool_obj_va;
-
-	if (grant_node_create(pg_num, gref_arr, pa_arr, val_str, sizeof(val_str))) {
-		return -1;
-	}
-
-	if (snprintf(key_str, sizeof(key_str),
-		DPDK_XENSTORE_PATH"%d"MEMPOOL_XENSTORE_STR, mempool_idx) == -1)
-		return -1;
-	if (xenstore_write(key_str, val_str) == -1)
-		return -1;
-
-	if (snprintf(key_str, sizeof(key_str),
-		DPDK_XENSTORE_PATH"%d"MEMPOOL_VA_XENSTORE_STR, mempool_idx) == -1)
-		return -1;
-	if (mpool->nb_mem_chunks != 1) {
-		RTE_LOG(ERR, PMD,
-			"mempool with more than 1 chunk is not supported\n");
-		return -1;
-	}
-	mempool_obj_va = STAILQ_FIRST(&mpool->mem_list)->addr;
-	if (snprintf(val_str, sizeof(val_str), "%"PRIxPTR,
-			(uintptr_t)mempool_obj_va) == -1)
-		return -1;
-	if (xenstore_write(key_str, val_str) == -1)
-		return -1;
-
-	return 0;
-}
diff --git a/drivers/net/xenvirt/rte_xen_lib.h b/drivers/net/xenvirt/rte_xen_lib.h
deleted file mode 100644
index d973eac..0000000
--- a/drivers/net/xenvirt/rte_xen_lib.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2015 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _RTE_XEN_DUMMY_PMD_H
-#define _RTE_XEN_DUMMY_PMD_H
-
-#include <stdint.h>
-
-#include <rte_common.h>
-#include <rte_mempool.h>
-#include <rte_ether.h>
-
-#define	PAGEMAP_FNAME           "/proc/self/pagemap"
-#define XEN_GNTALLOC_FNAME      "/dev/xen/gntalloc"
-#define DPDK_XENSTORE_PATH      "/control/dpdk/"
-#define DPDK_XENSTORE_NODE      "/control/dpdk"
-/*format 0_mempool_gref = "1537,1524,1533" */
-#define MEMPOOL_XENSTORE_STR    "_mempool_gref"
-/*format 0_mempool_va = 0x80340000 */
-#define MEMPOOL_VA_XENSTORE_STR "_mempool_va"
-/*format 0_rx_vring_gref  = "1537,1524,1533" */
-#define RXVRING_XENSTORE_STR    "_rx_vring_gref"
-/*format 0_tx_vring_gref  = "1537,1524,1533" */
-#define TXVRING_XENSTORE_STR    "_tx_vring_gref"
-#define VRING_FLAG_STR          "_vring_flag"
-/*format: event_type_start_0 = 1*/
-#define EVENT_TYPE_START_STR    "event_type_start_"
-
-#define DOM0_DOMID 0
-/*
- * the pfn (page frame number) are bits 0-54 (see pagemap.txt in linux
- * Documentation).
- */
-#define PAGEMAP_PFN_BITS	54
-#define PAGEMAP_PFN_MASK	RTE_LEN2MASK(PAGEMAP_PFN_BITS, phys_addr_t)
-
-#define MAP_FLAG	0xA5
-
-#define RTE_ETH_XENVIRT_PAIRS_DELIM ';'
-#define RTE_ETH_XENVIRT_KEY_VALUE_DELIM '='
-#define RTE_ETH_XENVIRT_MAX_ARGS 1
-#define RTE_ETH_XENVIRT_MAC_PARAM "mac"
-struct xenvirt_dict {
-	uint8_t addr_valid;
-	struct ether_addr addr;
-};
-
-extern int gntalloc_fd;
-
-int
-gntalloc_open(void);
-
-void
-gntalloc_close(void);
-
-void *
-gntalloc(size_t sz, uint32_t *gref, uint64_t *start_index);
-
-void
-gntfree(void *va, size_t sz, uint64_t start_index);
-
-int
-xenstore_init(void);
-
-int
-xenstore_uninit(void);
-
-int
-xenstore_write(const char *key_str, const char *val_str);
-
-int
-get_phys_map(void *va, phys_addr_t pa[], uint32_t pg_num, uint32_t pg_sz);
-
-void *
-get_xen_virtual(size_t size, size_t page_sz);
-
-int
-grefwatch_from_alloc(uint32_t *gref, void **pptr);
-
-
-int grant_node_create(uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, char *val_str, size_t str_size);
-
-int
-grant_gntalloc_mbuf_pool(struct rte_mempool *mpool, uint32_t pg_num, uint32_t *gref_arr, phys_addr_t *pa_arr, int mempool_idx);
-
-#endif
diff --git a/drivers/net/xenvirt/virtio_logs.h b/drivers/net/xenvirt/virtio_logs.h
deleted file mode 100644
index d6c33f7..0000000
--- a/drivers/net/xenvirt/virtio_logs.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VIRTIO_LOGS_H_
-#define _VIRTIO_LOGS_H_
-
-#include <rte_log.h>
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_INIT
-#define PMD_INIT_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt "\n", __func__, ## args)
-#define PMD_INIT_FUNC_TRACE() PMD_INIT_LOG(DEBUG, " >>")
-#else
-#define PMD_INIT_LOG(level, fmt, args...) do { } while(0)
-#define PMD_INIT_FUNC_TRACE() do { } while(0)
-#endif
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_RX
-#define PMD_RX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s() rx: " fmt , __func__, ## args)
-#else
-#define PMD_RX_LOG(level, fmt, args...) do { } while(0)
-#endif
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_TX
-#define PMD_TX_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s() tx: " fmt , __func__, ## args)
-#else
-#define PMD_TX_LOG(level, fmt, args...) do { } while(0)
-#endif
-
-
-#ifdef RTE_LIBRTE_VIRTIO_DEBUG_DRIVER
-#define PMD_DRV_LOG(level, fmt, args...) \
-	RTE_LOG(level, PMD, "%s(): " fmt , __func__, ## args)
-#else
-#define PMD_DRV_LOG(level, fmt, args...) do { } while(0)
-#endif
-
-#endif /* _VIRTIO_LOGS_H_ */
diff --git a/drivers/net/xenvirt/virtqueue.h b/drivers/net/xenvirt/virtqueue.h
deleted file mode 100644
index 1bb6877..0000000
--- a/drivers/net/xenvirt/virtqueue.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _VIRTQUEUE_H_
-#define _VIRTQUEUE_H_
-
-#include <stdint.h>
-#include <linux/virtio_ring.h>
-#include <linux/virtio_net.h>
-
-#include <rte_atomic.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_mempool.h>
-
-#include "virtio_logs.h"
-
-struct rte_mbuf;
-
-/* The alignment to use between consumer and producer parts of vring. */
-#define VIRTIO_PCI_VRING_ALIGN 4096
-
-enum { VTNET_RQ = 0, VTNET_TQ = 1, VTNET_CQ = 2 };
-
-/**
- * The maximum virtqueue size is 2^15. Use that value as the end of
- * descriptor chain terminator since it will never be a valid index
- * in the descriptor table. This is used to verify we are correctly
- * handling vq_free_cnt.
- */
-#define VQ_RING_DESC_CHAIN_END 32768
-
-#define VIRTQUEUE_MAX_NAME_SZ  32
-
-struct pmd_internals {
-	struct rte_eth_stats eth_stats;
-	int port_id;
-	int virtio_idx;
-};
-
-
-struct virtqueue {
-	char vq_name[VIRTQUEUE_MAX_NAME_SZ];
-	struct rte_mempool       *mpool;  /**< mempool for mbuf allocation */
-	uint16_t    queue_id;             /**< DPDK queue index. */
-	uint16_t    vq_queue_index;       /**< PCI queue index */
-	uint8_t     port_id;              /**< Device port identifier. */
-
-	void        *vq_ring_virt_mem;    /**< virtual address of vring*/
-	int         vq_alignment;
-	int         vq_ring_size;
-
-	struct vring vq_ring;    /**< vring keeping desc, used and avail */
-	struct pmd_internals *internals;  /**< virtio device internal info. */
-	uint16_t    vq_nentries; /**< vring desc numbers */
-	uint16_t    vq_desc_head_idx;
-	uint16_t    vq_free_cnt; /**< num of desc available */
-	uint16_t vq_used_cons_idx; /**< Last consumed desc in used table, trails vq_ring.used->idx*/
-
-	struct vq_desc_extra {
-		void              *cookie;
-		uint16_t          ndescs;
-	} vq_descx[0] __rte_cache_aligned;
-};
-
-
-#ifdef  RTE_LIBRTE_XENVIRT_DEBUG_DUMP
-#define VIRTQUEUE_DUMP(vq) do { \
-	uint16_t used_idx, nused; \
-	used_idx = (vq)->vq_ring.used->idx; \
-	nused = (uint16_t)(used_idx - (vq)->vq_used_cons_idx); \
-	PMD_INIT_LOG(DEBUG, \
-	  "VQ: %s - size=%d; free=%d; used=%d; desc_head_idx=%d;" \
-	  " avail.idx=%d; used_cons_idx=%d; used.idx=%d;" \
-	  " avail.flags=0x%x; used.flags=0x%x\n", \
-	  (vq)->vq_name, (vq)->vq_nentries, (vq)->vq_free_cnt, nused, \
-	  (vq)->vq_desc_head_idx, (vq)->vq_ring.avail->idx, \
-	  (vq)->vq_used_cons_idx, (vq)->vq_ring.used->idx, \
-	  (vq)->vq_ring.avail->flags, (vq)->vq_ring.used->flags); \
-} while (0)
-#else
-#define VIRTQUEUE_DUMP(vq) do { } while (0)
-#endif
-
-
-/**
- *  Dump virtqueue internal structures, for debug purpose only.
- */
-void virtqueue_dump(struct virtqueue *vq);
-
-/**
- *  Get all mbufs to be freed.
- */
-struct rte_mbuf * virtqueue_detatch_unused(struct virtqueue *vq);
-
-static __rte_always_inline int
-virtqueue_full(const struct virtqueue *vq)
-{
-	return vq->vq_free_cnt == 0;
-}
-
-#define VIRTQUEUE_NUSED(vq) ((uint16_t)((vq)->vq_ring.used->idx - (vq)->vq_used_cons_idx))
-
-static __rte_always_inline void
-vq_ring_update_avail(struct virtqueue *vq, uint16_t desc_idx)
-{
-	uint16_t avail_idx;
-	/*
-	 * Place the head of the descriptor chain into the next slot and make
-	 * it usable to the host. The chain is made available now rather than
-	 * deferring to virtqueue_notify() in the hopes that if the host is
-	 * currently running on another CPU, we can keep it processing the new
-	 * descriptor.
-	 */
-	avail_idx = (uint16_t)(vq->vq_ring.avail->idx & (vq->vq_nentries - 1));
-	vq->vq_ring.avail->ring[avail_idx] = desc_idx;
-	rte_smp_wmb();
-	vq->vq_ring.avail->idx++;
-}
-
-static __rte_always_inline void
-vq_ring_free_chain(struct virtqueue *vq, uint16_t desc_idx)
-{
-	struct vring_desc *dp;
-	struct vq_desc_extra *dxp;
-
-	dp  = &vq->vq_ring.desc[desc_idx];
-	dxp = &vq->vq_descx[desc_idx];
-	vq->vq_free_cnt = (uint16_t)(vq->vq_free_cnt + dxp->ndescs);
-	while (dp->flags & VRING_DESC_F_NEXT) {
-		dp = &vq->vq_ring.desc[dp->next];
-	}
-	dxp->ndescs = 0;
-
-	/*
-	 * We must append the existing free chain, if any, to the end of
-	 * newly freed chain. If the virtqueue was completely used, then
-	 * head would be VQ_RING_DESC_CHAIN_END (ASSERTed above).
-	 */
-	dp->next = vq->vq_desc_head_idx;
-	vq->vq_desc_head_idx = desc_idx;
-}
-
-static __rte_always_inline int
-virtqueue_enqueue_recv_refill(struct virtqueue *rxvq, struct rte_mbuf *cookie)
-{
-	const uint16_t needed = 1;
-	const uint16_t head_idx = rxvq->vq_desc_head_idx;
-	struct vring_desc *start_dp = rxvq->vq_ring.desc;
-	struct vq_desc_extra *dxp;
-
-	if (unlikely(rxvq->vq_free_cnt == 0))
-		return -ENOSPC;
-	if (unlikely(rxvq->vq_free_cnt < needed))
-		return -EMSGSIZE;
-	if (unlikely(head_idx >= rxvq->vq_nentries))
-		return -EFAULT;
-
-	dxp = &rxvq->vq_descx[head_idx];
-	dxp->cookie = (void *)cookie;
-	dxp->ndescs = needed;
-
-	start_dp[head_idx].addr  =
-		(uint64_t) ((uintptr_t)cookie->buf_addr + RTE_PKTMBUF_HEADROOM - sizeof(struct virtio_net_hdr));
-	start_dp[head_idx].len   = cookie->buf_len - RTE_PKTMBUF_HEADROOM + sizeof(struct virtio_net_hdr);
-	start_dp[head_idx].flags = VRING_DESC_F_WRITE;
-	rxvq->vq_desc_head_idx   = start_dp[head_idx].next;
-	rxvq->vq_free_cnt        = (uint16_t)(rxvq->vq_free_cnt - needed);
-	vq_ring_update_avail(rxvq, head_idx);
-
-	return 0;
-}
-
-static __rte_always_inline int
-virtqueue_enqueue_xmit(struct virtqueue *txvq, struct rte_mbuf *cookie)
-{
-
-	const uint16_t needed = 2;
-	struct vring_desc *start_dp =  txvq->vq_ring.desc;
-	uint16_t head_idx = txvq->vq_desc_head_idx;
-	uint16_t idx      = head_idx;
-	struct vq_desc_extra *dxp;
-
-	if (unlikely(txvq->vq_free_cnt == 0))
-		return -ENOSPC;
-	if (unlikely(txvq->vq_free_cnt < needed))
-		return -EMSGSIZE;
-	if (unlikely(head_idx >= txvq->vq_nentries))
-		return -EFAULT;
-
-	dxp = &txvq->vq_descx[idx];
-	dxp->cookie = (void *)cookie;
-	dxp->ndescs = needed;
-
-	start_dp = txvq->vq_ring.desc;
-	start_dp[idx].addr  = 0;
-/*
- * TODO: save one desc here?
- */
-	start_dp[idx].len   = sizeof(struct virtio_net_hdr);
-	start_dp[idx].flags = VRING_DESC_F_NEXT;
-	start_dp[idx].addr  = (uintptr_t)NULL;
-	idx = start_dp[idx].next;
-	start_dp[idx].addr  = (uint64_t)rte_pktmbuf_mtod(cookie, uintptr_t);
-	start_dp[idx].len   = cookie->data_len;
-	start_dp[idx].flags = 0;
-	idx = start_dp[idx].next;
-	txvq->vq_desc_head_idx = idx;
-	txvq->vq_free_cnt = (uint16_t)(txvq->vq_free_cnt - needed);
-	vq_ring_update_avail(txvq, head_idx);
-
-	return 0;
-}
-
-static __rte_always_inline uint16_t
-virtqueue_dequeue_burst(struct virtqueue *vq, struct rte_mbuf **rx_pkts, uint32_t *len, uint16_t num)
-{
-	struct vring_used_elem *uep;
-	struct rte_mbuf *cookie;
-	uint16_t used_idx, desc_idx;
-	uint16_t i;
-	/*  Caller does the check */
-	for (i = 0; i < num ; i ++) {
-		used_idx = (uint16_t)(vq->vq_used_cons_idx & (vq->vq_nentries - 1));
-		uep = &vq->vq_ring.used->ring[used_idx];
-		desc_idx = (uint16_t) uep->id;
-		cookie = (struct rte_mbuf *)vq->vq_descx[desc_idx].cookie;
-		if (unlikely(cookie == NULL)) {
-			PMD_DRV_LOG(ERR, "vring descriptor with no mbuf cookie at %u\n",
-				vq->vq_used_cons_idx);
-			RTE_LOG(ERR, PMD, "%s: inconsistent (%u, %u)\n", __func__, used_idx , desc_idx);
-			break;
-		}
-		len[i] = uep->len;
-		rx_pkts[i]  = cookie;
-		vq->vq_used_cons_idx++;
-		vq_ring_free_chain(vq, desc_idx);
-		vq->vq_descx[desc_idx].cookie = NULL;
-	}
-	return i;
-}
-
-#endif /* _VIRTQUEUE_H_ */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c25fdd9..fb6be12 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -144,7 +144,6 @@ 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
-_LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_XENVIRT)    += -lrte_pmd_xenvirt -lxenstore
 
 ifeq ($(CONFIG_RTE_LIBRTE_CRYPTODEV),y)
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_AESNI_MB)    += -lrte_pmd_aesni_mb
diff --git a/pkg/dpdk.spec b/pkg/dpdk.spec
index 5ba3431..95c3335 100644
--- a/pkg/dpdk.spec
+++ b/pkg/dpdk.spec
@@ -90,9 +90,6 @@ sed -ri 's,(RTE_BUILD_SHARED_LIB=).*,\1y,' %{target}/.config
 sed -ri 's,(RTE_NEXT_ABI=).*,\1n,'         %{target}/.config
 sed -ri 's,(LIBRTE_VHOST=).*,\1y,'         %{target}/.config
 sed -ri 's,(LIBRTE_PMD_PCAP=).*,\1y,'      %{target}/.config
-%ifarch i686 x86_64
-sed -ri 's,(LIBRTE_PMD_XENVIRT=).*,\1y,'   %{target}/.config
-%endif
 make O=%{target} %{?_smp_mflags}
 make O=%{target} doc
 
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 3/6] xen: remove xen dependency in app, examples, test
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
                   ` (3 preceding siblings ...)
  2017-08-30 18:10 ` Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-09-04 14:24   ` [dpdk-dev] " Bruce Richardson
                     ` (3 more replies)
  2017-08-30 18:10 ` Jianfeng Tan
                   ` (5 subsequent siblings)
  10 siblings, 4 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
	shahafs, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 app/test-pmd/testpmd.c              |  2 +-
 examples/ip_pipeline/app.h          |  4 --
 examples/ip_pipeline/config_parse.c | 19 ---------
 examples/ip_pipeline/init.c         |  5 ---
 examples/kni/main.c                 |  3 --
 test/test/process.h                 | 10 -----
 test/test/test.c                    |  4 --
 test/test/test_eal_flags.c          | 81 -------------------------------------
 8 files changed, 1 insertion(+), 127 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index f8d02ae..d9c785c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -494,7 +494,7 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
 
-	/* if the former XEN allocation failed fall back to normal allocation */
+	/* if the former allocation failed fall back to normal allocation */
 	if (rte_mp == NULL) {
 		if (mp_anon != 0) {
 			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index e41290e..94e7a6d 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -428,10 +428,6 @@ struct app_eal_params {
 	/* Interrupt mode for VFIO (legacy|msi|msix) */
 	char *vfio_intr;
 
-	/* Support running on Xen dom0 without hugetlbfs */
-	uint32_t xen_dom0_present;
-	int xen_dom0;
-
 	uint32_t parsed;
 };
 
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 0b76134..3211c6a 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -809,21 +809,6 @@ parse_eal(struct app_params *app,
 			continue;
 		}
 
-		/* xen_dom0 */
-		if (strcmp(entry->name, "xen_dom0") == 0) {
-			int val;
-
-			PARSE_ERROR_DUPLICATE((p->xen_dom0_present == 0),
-				section_name,
-				entry->name);
-			p->xen_dom0_present = 1;
-
-			val = parser_read_arg_bool(entry->value);
-			PARSE_ERROR((val >= 0), section_name, entry->name);
-			p->xen_dom0 = val;
-			continue;
-		}
-
 		/* unrecognized */
 		PARSE_ERROR_INVALID(0, section_name, entry->name);
 	}
@@ -2643,10 +2628,6 @@ save_eal_params(struct app_params *app, FILE *f)
 	if (p->vfio_intr)
 		fprintf(f, "%s = %s\n", "vfio_intr", p->vfio_intr);
 
-	if (p->xen_dom0_present)
-		fprintf(f, "%s = %s\n", "xen_dom0",
-			(p->xen_dom0) ? "yes" : "no");
-
 	fputc('\n', f);
 }
 
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 7cde49a..034c238 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -296,11 +296,6 @@ app_init_eal(struct app_params *app)
 		app->eal_argv[n_args++] = strdup(buffer);
 	}
 
-	if ((p->xen_dom0_present) && (p->xen_dom0)) {
-		snprintf(buffer, sizeof(buffer), "--xen-dom0");
-		app->eal_argv[n_args++] = strdup(buffer);
-	}
-
 	snprintf(buffer, sizeof(buffer), "--");
 	app->eal_argv[n_args++] = strdup(buffer);
 
diff --git a/examples/kni/main.c b/examples/kni/main.c
index e3bc2fb..9f9d227 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -919,9 +919,6 @@ main(int argc, char** argv)
 			continue;
 		kni_free_kni(port);
 	}
-#ifdef RTE_LIBRTE_XEN_DOM0
-	rte_kni_close();
-#endif
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
 		if (kni_port_params_array[i]) {
 			rte_free(kni_port_params_array[i]);
diff --git a/test/test/process.h b/test/test/process.h
index 4f8d121..51ced12 100644
--- a/test/test/process.h
+++ b/test/test/process.h
@@ -52,11 +52,7 @@ static inline int
 process_dup(const char *const argv[], int numargs, const char *env_value)
 {
 	int num;
-#ifdef RTE_LIBRTE_XEN_DOM0
-	char *argv_cpy[numargs + 2];
-#else
 	char *argv_cpy[numargs + 1];
-#endif
 	int i, fd, status;
 	char path[32];
 
@@ -67,14 +63,8 @@ process_dup(const char *const argv[], int numargs, const char *env_value)
 		/* make a copy of the arguments to be passed to exec */
 		for (i = 0; i < numargs; i++)
 			argv_cpy[i] = strdup(argv[i]);
-#ifdef RTE_LIBRTE_XEN_DOM0
-		argv_cpy[i] = strdup("--xen-dom0");
-		argv_cpy[i + 1] = NULL;
-		num = numargs + 1;
-#else
 		argv_cpy[i] = NULL;
 		num = numargs;
-#endif
 
 		/* close all open file descriptors, check /proc/self/fd to only
 		 * call close on open fds. Exclude fds 0, 1 and 2*/
diff --git a/test/test/test.c b/test/test/test.c
index c561eb5..9accbd1 100644
--- a/test/test/test.c
+++ b/test/test/test.c
@@ -87,11 +87,7 @@ do_recursive_call(void)
 			{ "test_invalid_b_flag", no_action },
 			{ "test_invalid_vdev_flag", no_action },
 			{ "test_invalid_r_flag", no_action },
-#ifdef RTE_LIBRTE_XEN_DOM0
-			{ "test_dom0_misc_flags", no_action },
-#else
 			{ "test_misc_flags", no_action },
-#endif
 			{ "test_memory_flags", no_action },
 			{ "test_file_prefix", no_action },
 			{ "test_no_huge_flag", no_action },
diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
index 594d79d..310109e 100644
--- a/test/test/test_eal_flags.c
+++ b/test/test/test_eal_flags.c
@@ -51,11 +51,7 @@
 
 #include "process.h"
 
-#ifdef RTE_LIBRTE_XEN_DOM0
-#define DEFAULT_MEM_SIZE "30"
-#else
 #define DEFAULT_MEM_SIZE "18"
-#endif
 #define mp_flag "--proc-type=secondary"
 #define no_hpet "--no-hpet"
 #define no_huge "--no-huge"
@@ -809,72 +805,6 @@ test_no_huge_flag(void)
 	return 0;
 }
 
-#ifdef RTE_LIBRTE_XEN_DOM0
-static int
-test_dom0_misc_flags(void)
-{
-	char prefix[PATH_MAX], tmp[PATH_MAX];
-
-	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
-		printf("Error - unable to get current prefix!\n");
-		return -1;
-	}
-	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
-
-	/* check that some general flags don't prevent things from working.
-	 * All cases, apart from the first, app should run.
-	 * No further testing of output done.
-	 */
-	/* sanity check - failure with invalid option */
-	const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"};
-
-	/* With --no-pci */
-	const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"};
-	/* With -v */
-	const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"};
-	/* With valid --syslog */
-	const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1",
-			"--syslog", "syslog"};
-	/* With empty --syslog (should fail) */
-	const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"};
-	/* With invalid --syslog */
-	const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
-	/* With no-sh-conf */
-	const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", "20",
-			"--no-shconf", "--file-prefix=noshconf" };
-
-	if (launch_proc(argv0) == 0) {
-		printf("Error - process ran ok with invalid flag\n");
-		return -1;
-	}
-	if (launch_proc(argv1) != 0) {
-		printf("Error - process did not run ok with --no-pci flag\n");
-		return -1;
-	}
-	if (launch_proc(argv2) != 0) {
-		printf("Error - process did not run ok with -v flag\n");
-		return -1;
-	}
-	if (launch_proc(argv3) != 0) {
-		printf("Error - process did not run ok with --syslog flag\n");
-		return -1;
-	}
-	if (launch_proc(argv4) == 0) {
-		printf("Error - process run ok with empty --syslog flag\n");
-		return -1;
-	}
-	if (launch_proc(argv5) == 0) {
-		printf("Error - process run ok with invalid --syslog flag\n");
-		return -1;
-	}
-	if (launch_proc(argv6) != 0) {
-		printf("Error - process did not run ok with --no-shconf flag\n");
-		return -1;
-	}
-
-	return 0;
-}
-#else
 static int
 test_misc_flags(void)
 {
@@ -1061,7 +991,6 @@ test_misc_flags(void)
 	}
 	return 0;
 }
-#endif
 
 static int
 test_file_prefix(void)
@@ -1098,9 +1027,6 @@ test_file_prefix(void)
 		printf("Error - unable to get current prefix!\n");
 		return -1;
 	}
-#ifdef RTE_LIBRTE_XEN_DOM0
-	return 0;
-#endif
 
 	/* check if files for current prefix are present */
 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
@@ -1299,9 +1225,6 @@ test_memory_flags(void)
 		printf("Error - process failed with valid -m flag!\n");
 		return -1;
 	}
-#ifdef RTE_LIBRTE_XEN_DOM0
-	return 0;
-#endif
 	if (launch_proc(argv2) == 0) {
 		printf("Error - process run ok with invalid (zero) --socket-mem!\n");
 		return -1;
@@ -1427,11 +1350,7 @@ test_eal_flags(void)
 		return ret;
 	}
 
-#ifdef RTE_LIBRTE_XEN_DOM0
-	ret = test_dom0_misc_flags();
-#else
 	ret = test_misc_flags();
-#endif
 	if (ret < 0) {
 		printf("Error in test_misc_flags()");
 		return ret;
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 3/6] xen: remove xen dependency in app, examples, test
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
                   ` (4 preceding siblings ...)
  2017-08-30 18:10 ` [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-08-30 18:10 ` [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool Jianfeng Tan
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: jerin.jacob, shahafs, john.mcnamara, Jianfeng Tan, oao.m.martins,
	thomas, xen-devel

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 app/test-pmd/testpmd.c              |  2 +-
 examples/ip_pipeline/app.h          |  4 --
 examples/ip_pipeline/config_parse.c | 19 ---------
 examples/ip_pipeline/init.c         |  5 ---
 examples/kni/main.c                 |  3 --
 test/test/process.h                 | 10 -----
 test/test/test.c                    |  4 --
 test/test/test_eal_flags.c          | 81 -------------------------------------
 8 files changed, 1 insertion(+), 127 deletions(-)

diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
index f8d02ae..d9c785c 100644
--- a/app/test-pmd/testpmd.c
+++ b/app/test-pmd/testpmd.c
@@ -494,7 +494,7 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
 		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
 		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
 
-	/* if the former XEN allocation failed fall back to normal allocation */
+	/* if the former allocation failed fall back to normal allocation */
 	if (rte_mp == NULL) {
 		if (mp_anon != 0) {
 			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,
diff --git a/examples/ip_pipeline/app.h b/examples/ip_pipeline/app.h
index e41290e..94e7a6d 100644
--- a/examples/ip_pipeline/app.h
+++ b/examples/ip_pipeline/app.h
@@ -428,10 +428,6 @@ struct app_eal_params {
 	/* Interrupt mode for VFIO (legacy|msi|msix) */
 	char *vfio_intr;
 
-	/* Support running on Xen dom0 without hugetlbfs */
-	uint32_t xen_dom0_present;
-	int xen_dom0;
-
 	uint32_t parsed;
 };
 
diff --git a/examples/ip_pipeline/config_parse.c b/examples/ip_pipeline/config_parse.c
index 0b76134..3211c6a 100644
--- a/examples/ip_pipeline/config_parse.c
+++ b/examples/ip_pipeline/config_parse.c
@@ -809,21 +809,6 @@ parse_eal(struct app_params *app,
 			continue;
 		}
 
-		/* xen_dom0 */
-		if (strcmp(entry->name, "xen_dom0") == 0) {
-			int val;
-
-			PARSE_ERROR_DUPLICATE((p->xen_dom0_present == 0),
-				section_name,
-				entry->name);
-			p->xen_dom0_present = 1;
-
-			val = parser_read_arg_bool(entry->value);
-			PARSE_ERROR((val >= 0), section_name, entry->name);
-			p->xen_dom0 = val;
-			continue;
-		}
-
 		/* unrecognized */
 		PARSE_ERROR_INVALID(0, section_name, entry->name);
 	}
@@ -2643,10 +2628,6 @@ save_eal_params(struct app_params *app, FILE *f)
 	if (p->vfio_intr)
 		fprintf(f, "%s = %s\n", "vfio_intr", p->vfio_intr);
 
-	if (p->xen_dom0_present)
-		fprintf(f, "%s = %s\n", "xen_dom0",
-			(p->xen_dom0) ? "yes" : "no");
-
 	fputc('\n', f);
 }
 
diff --git a/examples/ip_pipeline/init.c b/examples/ip_pipeline/init.c
index 7cde49a..034c238 100644
--- a/examples/ip_pipeline/init.c
+++ b/examples/ip_pipeline/init.c
@@ -296,11 +296,6 @@ app_init_eal(struct app_params *app)
 		app->eal_argv[n_args++] = strdup(buffer);
 	}
 
-	if ((p->xen_dom0_present) && (p->xen_dom0)) {
-		snprintf(buffer, sizeof(buffer), "--xen-dom0");
-		app->eal_argv[n_args++] = strdup(buffer);
-	}
-
 	snprintf(buffer, sizeof(buffer), "--");
 	app->eal_argv[n_args++] = strdup(buffer);
 
diff --git a/examples/kni/main.c b/examples/kni/main.c
index e3bc2fb..9f9d227 100644
--- a/examples/kni/main.c
+++ b/examples/kni/main.c
@@ -919,9 +919,6 @@ main(int argc, char** argv)
 			continue;
 		kni_free_kni(port);
 	}
-#ifdef RTE_LIBRTE_XEN_DOM0
-	rte_kni_close();
-#endif
 	for (i = 0; i < RTE_MAX_ETHPORTS; i++)
 		if (kni_port_params_array[i]) {
 			rte_free(kni_port_params_array[i]);
diff --git a/test/test/process.h b/test/test/process.h
index 4f8d121..51ced12 100644
--- a/test/test/process.h
+++ b/test/test/process.h
@@ -52,11 +52,7 @@ static inline int
 process_dup(const char *const argv[], int numargs, const char *env_value)
 {
 	int num;
-#ifdef RTE_LIBRTE_XEN_DOM0
-	char *argv_cpy[numargs + 2];
-#else
 	char *argv_cpy[numargs + 1];
-#endif
 	int i, fd, status;
 	char path[32];
 
@@ -67,14 +63,8 @@ process_dup(const char *const argv[], int numargs, const char *env_value)
 		/* make a copy of the arguments to be passed to exec */
 		for (i = 0; i < numargs; i++)
 			argv_cpy[i] = strdup(argv[i]);
-#ifdef RTE_LIBRTE_XEN_DOM0
-		argv_cpy[i] = strdup("--xen-dom0");
-		argv_cpy[i + 1] = NULL;
-		num = numargs + 1;
-#else
 		argv_cpy[i] = NULL;
 		num = numargs;
-#endif
 
 		/* close all open file descriptors, check /proc/self/fd to only
 		 * call close on open fds. Exclude fds 0, 1 and 2*/
diff --git a/test/test/test.c b/test/test/test.c
index c561eb5..9accbd1 100644
--- a/test/test/test.c
+++ b/test/test/test.c
@@ -87,11 +87,7 @@ do_recursive_call(void)
 			{ "test_invalid_b_flag", no_action },
 			{ "test_invalid_vdev_flag", no_action },
 			{ "test_invalid_r_flag", no_action },
-#ifdef RTE_LIBRTE_XEN_DOM0
-			{ "test_dom0_misc_flags", no_action },
-#else
 			{ "test_misc_flags", no_action },
-#endif
 			{ "test_memory_flags", no_action },
 			{ "test_file_prefix", no_action },
 			{ "test_no_huge_flag", no_action },
diff --git a/test/test/test_eal_flags.c b/test/test/test_eal_flags.c
index 594d79d..310109e 100644
--- a/test/test/test_eal_flags.c
+++ b/test/test/test_eal_flags.c
@@ -51,11 +51,7 @@
 
 #include "process.h"
 
-#ifdef RTE_LIBRTE_XEN_DOM0
-#define DEFAULT_MEM_SIZE "30"
-#else
 #define DEFAULT_MEM_SIZE "18"
-#endif
 #define mp_flag "--proc-type=secondary"
 #define no_hpet "--no-hpet"
 #define no_huge "--no-huge"
@@ -809,72 +805,6 @@ test_no_huge_flag(void)
 	return 0;
 }
 
-#ifdef RTE_LIBRTE_XEN_DOM0
-static int
-test_dom0_misc_flags(void)
-{
-	char prefix[PATH_MAX], tmp[PATH_MAX];
-
-	if (get_current_prefix(tmp, sizeof(tmp)) == NULL) {
-		printf("Error - unable to get current prefix!\n");
-		return -1;
-	}
-	snprintf(prefix, sizeof(prefix), "--file-prefix=%s", tmp);
-
-	/* check that some general flags don't prevent things from working.
-	 * All cases, apart from the first, app should run.
-	 * No further testing of output done.
-	 */
-	/* sanity check - failure with invalid option */
-	const char *argv0[] = {prgname, prefix, mp_flag, "-c", "1", "--invalid-opt"};
-
-	/* With --no-pci */
-	const char *argv1[] = {prgname, prefix, mp_flag, "-c", "1", "--no-pci"};
-	/* With -v */
-	const char *argv2[] = {prgname, prefix, mp_flag, "-c", "1", "-v"};
-	/* With valid --syslog */
-	const char *argv3[] = {prgname, prefix, mp_flag, "-c", "1",
-			"--syslog", "syslog"};
-	/* With empty --syslog (should fail) */
-	const char *argv4[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog"};
-	/* With invalid --syslog */
-	const char *argv5[] = {prgname, prefix, mp_flag, "-c", "1", "--syslog", "error"};
-	/* With no-sh-conf */
-	const char *argv6[] = {prgname, "-c", "1", "-n", "2", "-m", "20",
-			"--no-shconf", "--file-prefix=noshconf" };
-
-	if (launch_proc(argv0) == 0) {
-		printf("Error - process ran ok with invalid flag\n");
-		return -1;
-	}
-	if (launch_proc(argv1) != 0) {
-		printf("Error - process did not run ok with --no-pci flag\n");
-		return -1;
-	}
-	if (launch_proc(argv2) != 0) {
-		printf("Error - process did not run ok with -v flag\n");
-		return -1;
-	}
-	if (launch_proc(argv3) != 0) {
-		printf("Error - process did not run ok with --syslog flag\n");
-		return -1;
-	}
-	if (launch_proc(argv4) == 0) {
-		printf("Error - process run ok with empty --syslog flag\n");
-		return -1;
-	}
-	if (launch_proc(argv5) == 0) {
-		printf("Error - process run ok with invalid --syslog flag\n");
-		return -1;
-	}
-	if (launch_proc(argv6) != 0) {
-		printf("Error - process did not run ok with --no-shconf flag\n");
-		return -1;
-	}
-
-	return 0;
-}
-#else
 static int
 test_misc_flags(void)
 {
@@ -1061,7 +991,6 @@ test_misc_flags(void)
 	}
 	return 0;
 }
-#endif
 
 static int
 test_file_prefix(void)
@@ -1098,9 +1027,6 @@ test_file_prefix(void)
 		printf("Error - unable to get current prefix!\n");
 		return -1;
 	}
-#ifdef RTE_LIBRTE_XEN_DOM0
-	return 0;
-#endif
 
 	/* check if files for current prefix are present */
 	if (process_hugefiles(prefix, HUGEPAGE_CHECK_EXISTS) != 1) {
@@ -1299,9 +1225,6 @@ test_memory_flags(void)
 		printf("Error - process failed with valid -m flag!\n");
 		return -1;
 	}
-#ifdef RTE_LIBRTE_XEN_DOM0
-	return 0;
-#endif
 	if (launch_proc(argv2) == 0) {
 		printf("Error - process run ok with invalid (zero) --socket-mem!\n");
 		return -1;
@@ -1427,11 +1350,7 @@ test_eal_flags(void)
 		return ret;
 	}
 
-#ifdef RTE_LIBRTE_XEN_DOM0
-	ret = test_dom0_misc_flags();
-#else
 	ret = test_misc_flags();
-#endif
 	if (ret < 0) {
 		printf("Error in test_misc_flags()");
 		return ret;
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
                   ` (5 preceding siblings ...)
  2017-08-30 18:10 ` Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-09-04 14:51   ` [dpdk-dev] " Bruce Richardson
  2017-09-04 14:51   ` Bruce Richardson
  2017-08-30 18:10 ` Jianfeng Tan
                   ` (3 subsequent siblings)
  10 siblings, 2 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: xen-devel, thomas, john.mcnamara, oao.m.martins, jerin.jacob,
	shahafs, Jianfeng Tan

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/crypto/qat/qat_qp.c      | 7 +------
 drivers/net/i40e/i40e_rxtx.c     | 8 ++------
 lib/librte_ether/rte_ethdev.c    | 7 +------
 lib/librte_mempool/rte_mempool.c | 8 ++------
 4 files changed, 6 insertions(+), 24 deletions(-)

diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 5048d21..34f75ca 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -122,14 +122,9 @@ queue_dma_zone_reserve(const char *queue_name, uint32_t queue_size,
 	break;
 	default:
 		memzone_flags = RTE_MEMZONE_SIZE_HINT_ONLY;
-}
-#ifdef RTE_LIBRTE_XEN_DOM0
-	return rte_memzone_reserve_bounded(queue_name, queue_size,
-		socket_id, 0, RTE_CACHE_LINE_SIZE, RTE_PGSIZE_2M);
-#else
+	}
 	return rte_memzone_reserve_aligned(queue_name, queue_size, socket_id,
 		memzone_flags, queue_size);
-#endif
 }
 
 int qat_crypto_sym_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index d42c23c..f571e79 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2221,12 +2221,8 @@ i40e_memzone_reserve(const char *name, uint32_t len, int socket_id)
 	if (mz)
 		return mz;
 
-	if (rte_xen_dom0_supported())
-		mz = rte_memzone_reserve_bounded(name, len,
-				socket_id, 0, I40E_RING_BASE_ALIGN, RTE_PGSIZE_2M);
-	else
-		mz = rte_memzone_reserve_aligned(name, len,
-				socket_id, 0, I40E_RING_BASE_ALIGN);
+	mz = rte_memzone_reserve_aligned(name, len,
+					 socket_id, 0, I40E_RING_BASE_ALIGN);
 	return mz;
 }
 
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0597641..cb0bde7 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2818,12 +2818,7 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 	if (mz)
 		return mz;
 
-	if (rte_xen_dom0_supported())
-		return rte_memzone_reserve_bounded(z_name, size, socket_id,
-						   0, align, RTE_PGSIZE_2M);
-	else
-		return rte_memzone_reserve_aligned(z_name, size, socket_id,
-						   0, align);
+	return rte_memzone_reserve_aligned(z_name, size, socket_id, 0, align);
 }
 
 int
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 6fc3c9c..6d726ae 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -527,11 +527,7 @@ rte_mempool_populate_default(struct rte_mempool *mp)
 	if (mp->nb_mem_chunks != 0)
 		return -EEXIST;
 
-	if (rte_xen_dom0_supported()) {
-		pg_sz = RTE_PGSIZE_2M;
-		pg_shift = rte_bsf32(pg_sz);
-		align = pg_sz;
-	} else if (rte_eal_has_hugepages()) {
+	if (rte_eal_has_hugepages()) {
 		pg_shift = 0; /* not needed, zone is physically contiguous */
 		pg_sz = 0;
 		align = RTE_CACHE_LINE_SIZE;
@@ -568,7 +564,7 @@ rte_mempool_populate_default(struct rte_mempool *mp)
 		else
 			paddr = mz->phys_addr;
 
-		if (rte_eal_has_hugepages() && !rte_xen_dom0_supported())
+		if (rte_eal_has_hugepages())
 			ret = rte_mempool_populate_phys(mp, mz->addr,
 				paddr, mz->len,
 				rte_mempool_memchunk_mz_free,
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
                   ` (6 preceding siblings ...)
  2017-08-30 18:10 ` [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-08-30 18:10 ` [PATCH 5/6] eal: remove xen dom0 support Jianfeng Tan
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: jerin.jacob, shahafs, john.mcnamara, Jianfeng Tan, oao.m.martins,
	thomas, xen-devel

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 drivers/crypto/qat/qat_qp.c      | 7 +------
 drivers/net/i40e/i40e_rxtx.c     | 8 ++------
 lib/librte_ether/rte_ethdev.c    | 7 +------
 lib/librte_mempool/rte_mempool.c | 8 ++------
 4 files changed, 6 insertions(+), 24 deletions(-)

diff --git a/drivers/crypto/qat/qat_qp.c b/drivers/crypto/qat/qat_qp.c
index 5048d21..34f75ca 100644
--- a/drivers/crypto/qat/qat_qp.c
+++ b/drivers/crypto/qat/qat_qp.c
@@ -122,14 +122,9 @@ queue_dma_zone_reserve(const char *queue_name, uint32_t queue_size,
 	break;
 	default:
 		memzone_flags = RTE_MEMZONE_SIZE_HINT_ONLY;
-}
-#ifdef RTE_LIBRTE_XEN_DOM0
-	return rte_memzone_reserve_bounded(queue_name, queue_size,
-		socket_id, 0, RTE_CACHE_LINE_SIZE, RTE_PGSIZE_2M);
-#else
+	}
 	return rte_memzone_reserve_aligned(queue_name, queue_size, socket_id,
 		memzone_flags, queue_size);
-#endif
 }
 
 int qat_crypto_sym_qp_setup(struct rte_cryptodev *dev, uint16_t queue_pair_id,
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index d42c23c..f571e79 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -2221,12 +2221,8 @@ i40e_memzone_reserve(const char *name, uint32_t len, int socket_id)
 	if (mz)
 		return mz;
 
-	if (rte_xen_dom0_supported())
-		mz = rte_memzone_reserve_bounded(name, len,
-				socket_id, 0, I40E_RING_BASE_ALIGN, RTE_PGSIZE_2M);
-	else
-		mz = rte_memzone_reserve_aligned(name, len,
-				socket_id, 0, I40E_RING_BASE_ALIGN);
+	mz = rte_memzone_reserve_aligned(name, len,
+					 socket_id, 0, I40E_RING_BASE_ALIGN);
 	return mz;
 }
 
diff --git a/lib/librte_ether/rte_ethdev.c b/lib/librte_ether/rte_ethdev.c
index 0597641..cb0bde7 100644
--- a/lib/librte_ether/rte_ethdev.c
+++ b/lib/librte_ether/rte_ethdev.c
@@ -2818,12 +2818,7 @@ rte_eth_dma_zone_reserve(const struct rte_eth_dev *dev, const char *ring_name,
 	if (mz)
 		return mz;
 
-	if (rte_xen_dom0_supported())
-		return rte_memzone_reserve_bounded(z_name, size, socket_id,
-						   0, align, RTE_PGSIZE_2M);
-	else
-		return rte_memzone_reserve_aligned(z_name, size, socket_id,
-						   0, align);
+	return rte_memzone_reserve_aligned(z_name, size, socket_id, 0, align);
 }
 
 int
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 6fc3c9c..6d726ae 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -527,11 +527,7 @@ rte_mempool_populate_default(struct rte_mempool *mp)
 	if (mp->nb_mem_chunks != 0)
 		return -EEXIST;
 
-	if (rte_xen_dom0_supported()) {
-		pg_sz = RTE_PGSIZE_2M;
-		pg_shift = rte_bsf32(pg_sz);
-		align = pg_sz;
-	} else if (rte_eal_has_hugepages()) {
+	if (rte_eal_has_hugepages()) {
 		pg_shift = 0; /* not needed, zone is physically contiguous */
 		pg_sz = 0;
 		align = RTE_CACHE_LINE_SIZE;
@@ -568,7 +564,7 @@ rte_mempool_populate_default(struct rte_mempool *mp)
 		else
 			paddr = mz->phys_addr;
 
-		if (rte_eal_has_hugepages() && !rte_xen_dom0_supported())
+		if (rte_eal_has_hugepages())
 			ret = rte_mempool_populate_phys(mp, mz->addr,
 				paddr, mz->len,
 				rte_mempool_memchunk_mz_free,
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 5/6] eal: remove xen dom0 support
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
                   ` (7 preceding siblings ...)
  2017-08-30 18:10 ` Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-09-04 14:43   ` [dpdk-dev] " Bruce Richardson
  2017-09-04 14:43   ` Bruce Richardson
  2017-08-30 18:10 ` [PATCH 6/6] eal: remove API rte_mem_phy2mch Jianfeng Tan
  2017-08-31  8:44 ` [PATCH 0/6] remove xen dom0 support in DPDK Wei Liu
  10 siblings, 2 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: jerin.jacob, shahafs, john.mcnamara, Jianfeng Tan, oao.m.martins,
	thomas, xen-devel

We remove xen-specific code in EAL, including the option --xen-dom0,
memory initialization code, compiling dependency, etc.

Besides, related documents are removed or updated.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 MAINTAINERS                                        |   7 -
 config/common_base                                 |   5 -
 doc/guides/index.rst                               |   1 -
 doc/guides/linux_gsg/build_sample_apps.rst         |   5 +-
 doc/guides/linux_gsg/sys_reqs.rst                  |  53 --
 doc/guides/prog_guide/source_org.rst               |   1 -
 doc/guides/rel_notes/deprecation.rst               |   3 -
 doc/guides/rel_notes/release_17_11.rst             |  12 +
 doc/guides/testpmd_app_ug/run_app.rst              |   4 -
 doc/guides/xen/img/dpdk_xen_pkt_switch.png         | Bin 163842 -> 0 bytes
 doc/guides/xen/img/grant_refs.png                  | Bin 6405 -> 0 bytes
 doc/guides/xen/img/grant_table.png                 | Bin 96762 -> 0 bytes
 doc/guides/xen/index.rst                           |  38 -
 doc/guides/xen/pkt_switch.rst                      | 470 -------------
 .../bsdapp/eal/include/exec-env/rte_dom0_common.h  | 107 ---
 lib/librte_eal/common/eal_common_options.c         |   3 -
 lib/librte_eal/common/eal_internal_cfg.h           |   1 -
 lib/librte_eal/common/eal_options.h                |   2 -
 lib/librte_eal/common/include/rte_memory.h         |  66 --
 lib/librte_eal/linuxapp/Makefile                   |   2 -
 lib/librte_eal/linuxapp/eal/Makefile               |   5 +-
 lib/librte_eal/linuxapp/eal/eal.c                  |  24 -
 lib/librte_eal/linuxapp/eal/eal_memory.c           |  56 --
 lib/librte_eal/linuxapp/eal/eal_xen_memory.c       | 381 ----------
 .../eal/include/exec-env/rte_dom0_common.h         | 108 ---
 lib/librte_eal/linuxapp/igb_uio/igb_uio.c          |  54 --
 lib/librte_eal/linuxapp/xen_dom0/Makefile          |  53 --
 lib/librte_eal/linuxapp/xen_dom0/compat.h          |  15 -
 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h     | 107 ---
 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c    | 780 ---------------------
 pkg/dpdk.spec                                      |   3 -
 31 files changed, 14 insertions(+), 2352 deletions(-)
 delete mode 100644 doc/guides/xen/img/dpdk_xen_pkt_switch.png
 delete mode 100644 doc/guides/xen/img/grant_refs.png
 delete mode 100644 doc/guides/xen/img/grant_table.png
 delete mode 100644 doc/guides/xen/index.rst
 delete mode 100644 doc/guides/xen/pkt_switch.rst
 delete mode 100644 lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
 delete mode 100644 lib/librte_eal/linuxapp/eal/eal_xen_memory.c
 delete mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
 delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/Makefile
 delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/compat.h
 delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h
 delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c

diff --git a/MAINTAINERS b/MAINTAINERS
index 003e72e..2af32ff 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -189,13 +189,6 @@ Linux VFIO
 M: Anatoly Burakov <anatoly.burakov@intel.com>
 F: lib/librte_eal/linuxapp/eal/*vfio*
 
-Linux Xen
-M: Jianfeng Tan <jianfeng.tan@intel.com>
-F: lib/librte_eal/linuxapp/xen_dom0/
-F: lib/librte_eal/linuxapp/eal/*xen*
-F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
-F: doc/guides/xen/
-
 FreeBSD EAL (with overlaps)
 M: Bruce Richardson <bruce.richardson@intel.com>
 M: Sergio Gonzalez Monroy <sergio.gonzalez.monroy@intel.com>
diff --git a/config/common_base b/config/common_base
index 93928b6..17d3dae 100644
--- a/config/common_base
+++ b/config/common_base
@@ -719,11 +719,6 @@ CONFIG_RTE_LIBRTE_VHOST_DEBUG=n
 CONFIG_RTE_LIBRTE_PMD_VHOST=n
 
 #
-#Compile Xen domain0 support
-#
-CONFIG_RTE_LIBRTE_XEN_DOM0=n
-
-#
 # Compile the test application
 #
 CONFIG_RTE_APP_TEST=y
diff --git a/doc/guides/index.rst b/doc/guides/index.rst
index 63716b0..5b6eb7e 100644
--- a/doc/guides/index.rst
+++ b/doc/guides/index.rst
@@ -44,7 +44,6 @@ DPDK documentation
    nics/index
    cryptodevs/index
    eventdevs/index
-   xen/index
    contributing/index
    rel_notes/index
    faq/index
diff --git a/doc/guides/linux_gsg/build_sample_apps.rst b/doc/guides/linux_gsg/build_sample_apps.rst
index 0cc5fd1..582984d 100644
--- a/doc/guides/linux_gsg/build_sample_apps.rst
+++ b/doc/guides/linux_gsg/build_sample_apps.rst
@@ -116,7 +116,7 @@ The following is the list of options that can be given to the EAL:
 
     ./rte-app [-c COREMASK | -l CORELIST] [-n NUM] [-b <domain:bus:devid.func>] \
               [--socket-mem=MB,...] [-d LIB.so|DIR] [-m MB] [-r NUM] [-v] [--file-prefix] \
-	      [--proc-type <primary|secondary|auto>] [-- xen-dom0]
+	      [--proc-type <primary|secondary|auto>]
 
 The EAL options are as follows:
 
@@ -163,9 +163,6 @@ The EAL options are as follows:
 * ``--proc-type``:
   The type of process instance.
 
-* ``--xen-dom0``:
-  Support application running on Xen Domain0 without hugetlbfs.
-
 * ``--vmware-tsc-map``:
   Use VMware TSC map instead of native RDTSC.
 
diff --git a/doc/guides/linux_gsg/sys_reqs.rst b/doc/guides/linux_gsg/sys_reqs.rst
index eb8442c..3e7fe63 100644
--- a/doc/guides/linux_gsg/sys_reqs.rst
+++ b/doc/guides/linux_gsg/sys_reqs.rst
@@ -228,56 +228,3 @@ The mount point can be made permanent across reboots, by adding the following li
 For 1GB pages, the page size must be specified as a mount option::
 
     nodev /mnt/huge_1GB hugetlbfs pagesize=1GB 0 0
-
-Xen Domain0 Support in the Linux Environment
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-The existing memory management implementation is based on the Linux kernel hugepage mechanism.
-On the Xen hypervisor, hugepage support for DomainU (DomU) Guests means that DPDK applications work as normal for guests.
-
-However, Domain0 (Dom0) does not support hugepages.
-To work around this limitation, a new kernel module rte_dom0_mm is added to facilitate the allocation and mapping of memory via
-**IOCTL** (allocation) and **MMAP** (mapping).
-
-Enabling Xen Dom0 Mode in the DPDK
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-By default, Xen Dom0 mode is disabled in the DPDK build configuration files.
-To support Xen Dom0, the CONFIG_RTE_LIBRTE_XEN_DOM0 setting should be changed to “y”, which enables the Xen Dom0 mode at compile time.
-
-Furthermore, the CONFIG_RTE_EAL_ALLOW_INV_SOCKET_ID setting should also be changed to “y” in the case of the wrong socket ID being received.
-
-Loading the DPDK rte_dom0_mm Module
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-To run any DPDK application on Xen Dom0, the ``rte_dom0_mm`` module must be loaded into the running kernel with rsv_memsize option.
-The module is found in the kmod sub-directory of the DPDK target directory.
-This module should be loaded using the insmod command as shown below (assuming that the current directory is the DPDK target directory)::
-
-    sudo insmod kmod/rte_dom0_mm.ko rsv_memsize=X
-
-The value X cannot be greater than 4096(MB).
-
-Configuring Memory for DPDK Use
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-After the rte_dom0_mm.ko kernel module has been loaded, the user must configure the memory size for DPDK usage.
-This is done by echoing the memory size to a memsize file in the /sys/devices/ directory.
-Use the following command (assuming that 2048 MB is required)::
-
-    echo 2048 > /sys/kernel/mm/dom0-mm/memsize-mB/memsize
-
-The user can also check how much memory has already been used::
-
-    cat /sys/kernel/mm/dom0-mm/memsize-mB/memsize_rsvd
-
-Xen Domain0 does not support NUMA configuration, as a result the ``--socket-mem`` command line option is invalid for Xen Domain0.
-
-.. note::
-
-    The memsize value cannot be greater than the rsv_memsize value.
-
-Running the DPDK Application on Xen Domain0
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-To run the DPDK application on Xen Domain0, an extra command line option ``--xen-dom0`` is required.
diff --git a/doc/guides/prog_guide/source_org.rst b/doc/guides/prog_guide/source_org.rst
index d5d01f3..7aab4b4 100644
--- a/doc/guides/prog_guide/source_org.rst
+++ b/doc/guides/prog_guide/source_org.rst
@@ -108,7 +108,6 @@ The drivers directory has a *net* subdirectory which contains::
     +-- szedata2           # SZEDATA2 poll mode driver
     +-- virtio             # Virtio poll mode driver
     +-- vmxnet3            # VMXNET3 poll mode driver
-    +-- xenvirt            # Xen virtio poll mode driver
 
 .. note::
 
diff --git a/doc/guides/rel_notes/deprecation.rst b/doc/guides/rel_notes/deprecation.rst
index 3362f33..7a2d2f2 100644
--- a/doc/guides/rel_notes/deprecation.rst
+++ b/doc/guides/rel_notes/deprecation.rst
@@ -29,9 +29,6 @@ Deprecation Notices
   - ``rte_eal_devargs_type_count``
   - ``rte_eal_parse_devargs_str``, replaced by ``rte_eal_devargs_parse``
 
-* eal: the support of Xen dom0 will be removed from EAL in 17.11; and with
-  that, drivers/net/xenvirt and examples/vhost_xen will also be removed.
-
 * eal: An ABI change is planned for 17.11 to make DPDK aware of IOVA address
   translation scheme.
   Reference to phys address in EAL data-structure or functions may change to
diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index 170f4f9..d211084 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -124,7 +124,19 @@ ABI Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+Removed Items
+-------------
 
+.. This section should contain removed items in this release. Sample format:
+
+   * Add a short 1-2 sentence description of the removed item in the past
+     tense.
+
+   This section is a comment. do not overwrite or remove it.
+   Also, make sure to start the actual text at the margin.
+   =========================================================
+
+   * Xen dom0 in EAL was removed, as well as xenvirt PMD and vhost_xen.
 
 Shared Library Versions
 -----------------------
diff --git a/doc/guides/testpmd_app_ug/run_app.rst b/doc/guides/testpmd_app_ug/run_app.rst
index e8303f3..bd5ebe6 100644
--- a/doc/guides/testpmd_app_ug/run_app.rst
+++ b/doc/guides/testpmd_app_ug/run_app.rst
@@ -94,10 +94,6 @@ See the DPDK Getting Started Guides for more information on these options.
 
     Display the version information on startup.
 
-*   ``--xen-dom0``
-
-    Support application running on Xen Domain0 without hugetlbfs.
-
 *   ``--syslog``
 
     Set the syslog facility.
diff --git a/doc/guides/xen/img/dpdk_xen_pkt_switch.png b/doc/guides/xen/img/dpdk_xen_pkt_switch.png
deleted file mode 100644
index 32a6d1618820e930b17231f8fe38aab5d5c5d370..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 163842
zcmV)2K+M01P)<h;3K|Lk000e1NJLTq00HO#00AQi1^@s6`G1mo00001b5ch_0Itp)
z=>Px#32;bRa{vGi!~g&e!~vBn4jTXf02y>eSaefwW^{L9a%BKbX=8G4b8lvJAWvpy
zX=7!7?KN=#0RNClL_t(|UhI7ZfE>q__FLu^qs6ji%K}TbC4<b&kT`}Umt2wy$6>hO
zUGOdpm;b^!$8j7m#uUfQAls59Sqv7lR?7_k_q|uu(=*ev)3dvh<-{YecXp<`y6V+q
zs=}{+^{aCJc^CEEc;oM-tFudb@_HmMKVS0l^2EP-dV2INKgq-QZ@k`sz#9;F0|J>L
zKpyeW$0vGv@&k~NS7wI50f0@2U-yQYo|k9C-URpW{YtK+JMP8V9_nOFe!svofRl+a
z-+{WM2Qs&-t4oUTo0!wx-6;hH1yaZdeDTX)l36on%2CJ6mbUhG2w?!d8&Jx_#eTgW
zXovjzU&{&h3$q4lud|Hv27C?@p#O;<^Ln6z1Zx|pjmndPG=3Q=5Hs=AFxcW=gL`^%
zAnCZ5zCLy^!_IN?aThvJo8QlIbjlFCR8G1fsEdp9WzX(CCZLOo3g!JDc)uKV<Pp-v
z54ue@!=M(*X=gyIru4erxPAihjoaUVz#9<w$AEx(0|$C35zH})Uq(JR?qo7B;JCNP
zW#G!|@#7t)VI_c{g}+l+rYH)j_k|s=eypf#_#MPgusNBY&r2f5@$gACDEp%P=tCTm
zq$*6IIi_8c%Y6>Ud`v#xQ$WLTmLmM@+goP>Iv=03w6s7VcT00yr-Oc;w6(RvqV8}4
zIv)Z$FDGqnpz;47W4zv-U;h|ud}9@FK;Y1ZK;}qYTv3-UDZ^pGTvs30^&B~_izvjK
zc{~%#8)KQ|k~dNZI^s#8+nX%yO)h#XG*{Rk?CZlJ<G|Rb!y1-wKBRO-d6|@z7D^Lj
zvI=O`L<$gh#!okdG$ghL7P|07x6sY)x9NcBod+8}hrsjVk<uYB(Kn{>1_a)KKqLgx
zY1n%j!<WYwy#3?}6l`JFZbr+GCYzgKrfa;A%-}IiHBtv0K|-L2QYTVB3;!KY{TT2W
z=QLm{{OoV!e(4_eK<>hO4cB!i-kX5dFCmOg1+j-gk~8U{hpLndT&wodqYj8e<mHgf
zQO2RTIsGKNe!@AK5)Xa&0OyE{{ap1Mx4!{_Y!Jv~`NbEgsZWSDUZQY0Ixd};8Sldh
zU{P8Cd3fsMQy&~PkzTIRuTmIB)V%3cjZ3ej?KrQzm?9?0Vm^drK=w7O`K-d3au_LM
z5V@AmpaMD%LYU@t68zF&$!i##jtAuIlNy*S6lvU)xU~MbnFeM?*+wBcA6ys)E|rk-
zoNbl|>-#XjAs;egKe+HYSZn>Kc}^}_OEH1ccflF`0FIaBO3gvg7>Y*VXiP~JT?vyu
zo_|Dm*bMSHGW6IVDpEF|>0x1zsz8bRig{%eXd|-JO%%C{0~ru^E{D=}5XrQj1FeV}
zif(`t&|r&!0!Cr(Fd~ntOjwmV#Dudh!k2(4f!QkJYH9~#i@d_%8B7n9oP(!C7}h5C
zlU|XSL~;;-LpXT1jy>+sncG2F{u_^Y4I#i%QsW<qNof2th0*)3lY}H`iWxmAukP-6
zre7rerzi|cw{CntC$$(OV3r!U%@wSf<`axV#n~|t&LtTZ2Y_bzJZ_Cs*!j$E8ix)5
z`knGMH<R!lhDw5!qj*`Cvd;=%FWU$Bnw-bxJl%R#G`sbYSDOW`6E*Qhywgnxb^%tY
zyE)g5KhW2ku<=aZx#|<DM$E^@v1sF5;~tly#E@uHg>=k`4aj8y!@&}CF3c&&`IW=^
zdmB3qHl`(-TSwn2^~W?sa$dz7Hw-)kA{D*^z_SN>=3OcfL(<rDNRR4)bo6u`ngRKv
z^2CIIpjF(HmngGJFn`CRLNMu$QbbcML@jmooZ5Y7VMrTDr|AV*KY^31SJ?O(XbK6)
z9>hPXl%zSdbMlrL#3SiD^aX`fz;T>Hps-H4k)t7V%6;zcATJ3i5rKdXZ=V;)?z4fu
z#_x~9G38lNp9M?Ty(MCSN8?8RQvt05h87j@O8Ug9xv+7G-?V-rL*H*tPz*Pw06zMX
z;$kT*EY!4gowHkCVs}H>;0YuwYqCj#@IB#)hZ#_oF{tqPQZ)+5&W;Xg#}A1jW^aL*
zAPX%FfM8~RG2w#}I?lmr+xsB=Qr4GN_K-?(QOr3Lj6wpLZ@ZBl(bm=`9i6BoNP78)
z43MG_6Qci!mkqoJC1P_Gv9l3Zj?nF^=O--5=v~7&YyeSOT%<HoP!Lk^b5Sfpj5oL~
zObc<wisCP!`&jDA7xQ+zKpPz$?f9{(np6RnA8EWt?LoST)T{J=CL9QtqGG_Ns7QIM
z>IorQ4Ww*}%t(^H86<I53g)vS&?hpY;NU~P)&(H7qvEKu1H6OEl1Vi;B`Qzput?P{
zqI8YET%(XoRVE^~BIz2pK(99Ts9PjIk;TmpVhYm`U;~%2_ci25Q~kX>2%4*f1ziHl
zLIK_l9aJtIK-h%~7s|?2D`nTNT|nXvwGH{b&N~(PlLU00pic|dkMRoHq^E;H`67j?
zX05Z~fV4oc6*|OhM~t9QiV!H!#5n~U^<exXWjLvo-%Uj(u@jydvgu1jMY)WhFhNc@
z;RKm{_yno1Z%1icn?s|B^0l1Y76s65v7YWW%&bQS53Yt1AoA?O=VZm|C9<z(k94$k
zOJQCy>g>3}?A#*{u;>CPy7O8AjV}Bv!`dP6yW0Vm9%+ZthMa%Q--Kyik0}DuO^Wtm
z1`-DGjC(?5FBwbewj#XPL8q#!O2&>IBPX7Cio&O%sY6;@o9uq>iE5SH7mkGj{aoOa
zOK2u1i=e+4-naV?ija+*S|)~{dU3RHj+%FDaL1DO<nHX`K#dgipvdF!y}JuaeW45<
zRw<3mo$}n%Ps)aMt7XsLJ-CFD1{exXpHJ7f6A~&X@Sa%S1>{DrCn->2RUqw<o&|;A
zIbE$l%~I(A{uksoOMXWwt_FWlqXC%PNnX(@J-Al$ZM#Yw&6sC0iJ5zW$7z%PXffkC
zm6cU8k-TI6e3>+1wAAfylvW7qyu2dJ%gr~IVvO}^G7>ldf7BwT2dm3ESAmBN1@CBX
z>Xa9re_Gb9T_wAA?+$pHw|@iovuX;ApOWk5OA$cdRoDz(3|MqS0m^TaPC6Aj`MyY-
zUlD#?<hgi$9^j|~8{>50<~-b!*FjzezUY9H1|z>GfK4ZOGPlm)Gf_@H@kE($*a&HC
zYL({JR_qqmSWt*@F}uDhczq+$zTc&?j%i~20nd&a$qQ-jxpysicS_%%+>bj+6hQKl
zk|HTBES9_P{kz=r*L!5mrY+La+75)!_9{vfUCPkoP&1H$0!SL97<YDe5tHy6R7BAu
zMG(pqxD*U|Z3?Oa2oh1GfG~1GLU{mU^+w2?LGrV`dz-&$?GO3GU2?*_+49!6T_ckw
zPLRgBCUZUKlx&d>%Z`pVsj9>rv8a3RdqDpB*9T<Ps~e=PvmWz>wC*ke11bSAfe`%d
zQA!MX8$K__I@`hQdh%OLK=)K)j-^u2*#a)pA#EUL5?emTQ%x0cD<nf9h?F_<OQM;@
z`UoS6<M2yeRG2RXHJJllXv6<>pPVv(o?Lz1TV%q-(bCXZuZ)vp{<FOXUJz%3U>tgh
zzBiihWmf<X)LsVRB)23LCcv+<(o!v7`QxAOl!yNQpz@CPPT(h)cenBnTGHwE9UDh5
zffjN@n@Fe-0?u}l@e7q#&_hodghd%Htdruda{OH+9eEJSxV{wcyYarG0D>ID7j~8#
zErjWiz=*K$SQFa`L0kk+80llg&9}<wC!HYIU3aw%9X?EI>*^)HkjlL&_*r)m7j&rt
z<9MV~q<eZgrM$e9x{Ta%+dXpsJrBs*Et_Ekb*l1A{-laagkn$Fkj5c;p}b=r1>|S2
zz@fBsLU{pmg#lEI`GJ>$9~8mTRai)o6!t)w!QXlLozhl_YoW}PNEJ9e1bE7`(!paw
zEFVf2SDudx{`ALN<>V9Q$u(DBC8NfSl)A=7lq*50Qb+h}gp+X}>o?DZUd)nqG3WzD
zEd3qV6C1U@(vo~>ZEKb<{QKwS@n>F;Bab{rX3jfXO3MeUc1G7RH>$IcqB9#*AWWd;
zb(2t_%@sokcR@f?2ozIbbhSx)0rh4IHGWRF2_>=p_H=Ao8ME6>k)g$z`sBb1Kq80h
zwhkKm-yVBG?z#VA`SO=OD;Jz|mNeEksphZoe~ib{1syjw06V0zybzjWgM9NF-<Btz
zS}GHdm?N`JI7iAVAe0$D5;CYl>7dXIkRimylxj^nQz^*@9T$N3I|Z6L;~_m92XKRM
z?!spR?VYg6R}BS(0y^pH>QI+qmuCA@xp6TojHj?pYqA@5FG2+aGicbeQ|^28dAa|A
zhvieB`<PsK!P(MK-=IuZl_k&2vTbpaCJ-Nzu|fV1bm75M1P(ON7^5YQFrkR}Vit56
zgwMWxb@Ju^{F*FVzFH1Ha=IL|;6lkO1@E9z2?3<u9MX2Gf~}q((hPpn!c#%sr8TN-
z?OBiq%a~R{0fbE+yh|PU9>P?uUtCixpcjr0{zVlvzXNom@oE=o)n}T>Oct?V&fqr%
zcou~ue`<E`lE2*ZnB4#O$K;D&`Mex|+_CV&HR}A$N0sG8feap}^vx%7UEn+P?(N-I
zD_{MOugT(NYvrgJbLHrhFOq_iGAVTN!{`J!HQ`io;h41cwb=&Nti}#j4>cdpC;{K$
zMJ-aqIe-VT$3}h^6@Cm+2!31C428cKAS{6uu6BL$VgjCJA5$h2^pFp6ufeC#qPk|+
zPPy%#N92Kr9+S_1>2tE+q<K<TSF8Lfp3#;KfCun<HA1OyxLtIbZ=?l%0H@K1p|O!B
zx#WwV{i3|Ie4SkS=667qt(Jz?9;w3~u>)E`K7=V2)vYmzY}u3`Eg*kudy4=kAaw9Q
zygFK2q(t4Wt<nO*DT3C`&F^B&n8K$N2&6tPnu$PiAY}oCpIX_ZFCt;`63zNE?Ys*X
z`QQ;_;mW;OwryA?pZLU=B>xBhjl)V#lg8S5B{378e8(|4c2=@OTR3X01@fgYeN7g=
zyjm`N)7znVR7qodr|d^JIKqw!h)zze+H8aj_!U6u0r4v_6qjS2UDDAG*Ha;w6Ex!j
z#z%?=<98w8(+W$y1<DeX0LI8%u1ub~{AqcR2~p88?cKjL>BVX1rt1{Rpb_Kcgt22~
z$E$$Pr@tuqh@qc<=4mRV8Gta@nAPxF*5tpILT%umJ+KN)F7wNZi`j5B<$I$W@C@P=
zXqh<}tu3wcu}^$PcGfh?MQ?f=+|4DjzY(fuD?}y)pQle_k;yaa1`T#WK`$Vahk#ZL
zgdpw$uP7|6gkp-Y5!Be$hB`Rc;8~+p4vVm`w9?$vZF|+@me*B<&-1}wIF9#X*|QQ^
z)Tz*bCyGK3)+VjM>e1D5;@GLOVdcwm{YO75Kl|Sw%G{Yp!DSBxUoFWL-V?z)C`45T
zXg>?svFIsDFXZPw{RP<pCFYX1yiGc~i@`g<4-xunZKWrGe9ajqDbMHtueGpQ9*i3B
z!_E>Z0(=_V>R|Z~ky3gnAf%hI=KMlD6N0n=a3FlT+p$k=9T495tQ>A|Dh`YTXw)nN
zW_asDjTjhNSPZ>z^jZuaccd&Bf4Hn$u~<HI{U_x&KmW1Jojn5`xnQx!j-}*?a07UG
zK!qx-Rj-J4aSz}#`#lu*fg0Z9k3KDrJ^rFxdfmGa!x$v{5yNd`{Wc4_A;4*&ac3z=
z7!m31#cvDX@0v7fh}1OKN@EB8R_!u+NF^+5oG4OUf|2rMS8a<XR*kGIlFEt-*;Z#R
z6FPLd-~v{GNB1^tO0yPSDS&&p*NF*uZGa9$>VW`j0OB8Z_$=AEZHN5d4S$f+Pd^#N
z4l5pUbSy^i_A7|PI!j8+<e8_Qmxmu&D3@OIZg>%@!GPMO9dosDplw1cr9jJ9YdRf1
ze2)KA6&);m?1({#N3}>31bqRl|6zbn8)DK$B_)zi;a>-V-PtTdtBR$pYNYJmU*|H#
zsZg2QiLfEONO-BrhL#a<g8>`9=k?%kQj7f<Ic0{7-M&?R^~)RNtWy_22>~(E-KHYn
z;@l36`;BAa0df&81Nvao@KT1%gvW8PVqj;NX|&f4UQshL+)&HVVM=*fnf&=LcgTuW
zYvrnUydSh)0Gx(Z3mhv1?@&up)0kZkg%n>ZEnV8a1;Ag}eR@^_R8qt`hsl2MheqU)
z6hI)48&NK;@F-Oj7b4NIUiLR2Gy|bAa%i!XmJO91dm)HaKkb0HHBT8|#Q99Z2x6X5
zZ_P5LMcxDAV6bh<%;RL+wk>kQ4ZoM;fB4^Q0*M&7&wb9a@3dg`TC53UlCS;su6toQ
zuaqm_{vK)SfF}+@nKY@MG39Zz6{uJwP*i7)&kEpaWClCGFVwg)!)zks#{oY3nh{gR
zjsS*-4IeI@ogGq9+5`AENiE{URPINPfMHcsAvFz6@Pe|TCF70+R5I?H5|e-xg;xi8
zFn+p}r{!bb2)zLq(`L_??VC5r4gdFhnfv4K(&v%gC^<OflJP03K&UI$uiWtCkhGw^
zTUZeo!nXsMeG}p@lV{A4((2)|vlbQ`tTXFyMs1Yhlw|<6eoOS~<pm(Lx3$X2#~v+Z
z)kX5No9>e#m8J5ox11->KK-K1oI6zxpEOp!@q<6hzS=r@>sv3CBd1K3Z~p8K*|le%
zloTSygruo1BvupxL78Ad4bwl@(>RgH;;d96NakQ0FfV)H4r^@bk{QRHEKl6~7kT`N
zr{#jPPlc6O3k#iAE@Qeb*)0XN!m#lxBr4zVhd;`+8OKV+;L%VlTEQ%6<Woq}1x3n&
zFjb+JA_!=00C04nG0x=Y-idI+nJ1nG<tR^nd&9j_1#iMT-h8?|wfGe|_PFUXarhAV
z;g4>Sn#O%{_1mtHY1603_kMhbY~Q<I3QG`kqC1cT3%6FDdJz~>Fr*8ddO=2_Y3M9{
zA)GqF*qYk9<e0f9%folwERQ_$q+EF38D>T65ES{U_M{PV)UL-DB2hwe;3+q=QzV`}
z85R6Uwfs2iNTVT!M<&yXBWHI2bcN{s%3dC*R)_ni$)cEBQ)83da_j9fd)~>26PHK}
zcu5P~&_(bNQQcGW(qt*4&ooXBI)uoPLc~#Ntuc1ojWI4d>m(#!HpriDeFQ>gh`jUa
zbLD}@mda%p%~JvR!=K!Y7<aq8=dD-Dph3gr+dsM!mM(-dJa85YGr(#0Mp8rs9JN}7
zbJXi?hsk4FU|bwCe}O#r$lbDV@nSh{&TQ#`z|%da>pf~PM=4tWt?qv?|H1;mr$uhL
z<qkRK*c0Hbs+6V%RGGkKUkIK>-l1diU)b8fd%~&!9s@wdCE3xrMi;H+@mzE1`Lbr!
zEAqg7%VgsCYPs&(3*~{oKO@&%brRg^d*nwyy&ZAyGWpPZE|w-(-9P&I-CAa%c|qiV
zDLgz}9_sOsj`|)Z7La{VOMwTj17kF{bjq;{&X8vxxI-2#dRdN{bBr1qhxUt#QzFE|
zeSBS5&;_uZwr<-lE7z}*c_*I*#*ITgxP6R`(2b=iYZ_b+gf?9`UJzv55E^(u)Fn$_
zk+)uZfs7t8R3?nBlxldi*RI(FVxBC6Dhg%xwDGcLBQ#cIP8Kss4Ug=?=I5aVA+H?n
zZXja^EXV@(Fz0!m6pCI;AlWIurw!@IQ58U3$Lw%qLsyjHnZrlQgAYF{7oLAQC8|!D
zS%*FzoDHd1O0{*{R#^j=`K)>806uNf3dT@~&#8$r$($}N;{$XJGlMfUDv_HR;2IaR
zyliUqMR47{{L)ME_UkT|vBL(*gi(W~3NTr}a-}SoKU+o*FO}(250edrEiz^D2sj`b
zr4(@JY(~rp`%qX|3SwpGpiMPwW_oriBTT%!xDLElO8A&7_Li_LsTd?fMvVh}9+z{^
zIURe>Fag)XtD=*}G7IClk|geR={pl&5y-Zyy?@WWN_|Di-T3qA`<f$Xnn?+W5FF8S
zjFeU}fX4VHJvI0Zg|ob>LKeNeOt$XaBd5+e1)04_Kk8tKCSBD|rAc~}uRaLlDBB%V
zY9RX>$)Z$ZJ0aj-TJ(xsbiqkdRaPuBj+~%w?v1am1MM6mBSsEGR`Do=gkVXI9wYTo
z5{faeHVDzY5?F`j6%f))GBbf{uk<xDIg{fCS2*6*4h3P*u#r+&UL}t_`nVi-?6Jmd
zVklo!{H@1|88jQ#y(*ixZkGk;UIte%gmWjAWGF8P<0S>d-1ID&mBNFwLb+N&F~VE$
zut8WCG4ux-ZG-Fj<riO;(@&i(k3X^;^P3^HySK~kty`p`=tQZQI7%jt87_l|l*`Z&
zMbfgZN%yP+$0z19R|R1SHBVHT@TzAb!N>9d=#}d<G0r*RJ=GbWBhiV!%PWUSaphon
z=+P%--n`?bsR!1)y6G*fcJP`-#X#E>46toHge~YWAep4VKz|o9k&6+hXz6IiMldxH
z2^!oI*L=e?E;?ia((4s6c@SXhx9^ntmRdP{%1D_!Zn&)5v{Uxf*QvW`_4;ixdGbia
zojatqVL!4q;h2KIVf476QVb;D(g<P$G8W?8PCC9iF^_^!rg4}TsaW##XE<jXA}%Ve
ztd?C!&}e{5IuFW-CX_gLZ&Y<qDq<BE6~ooMk5Mow#tA5`$mXVI+=E0nqIrRqJ<)nK
zO*q=UjaVIotGc%7+G1@v#@)1YH?+|fIpPQ~oWn-Sx(!>UuAxB_YSz5EUnWi-CMD(F
zmMw`GJsb<TcD#m=cJ6M%o`HZ6ccMm}mZlNnN5R{G2^i7QbyZP0NOl80Er?Z-IVvHN
z5op4T*-Y7A{j-eY3%UrQJ;1V0S!)bNoE;{iD+V||mvMRr+5`uz>4nkQv$D7zsR8e3
zr)7e;b8EXb>QQWTZtys8B6vCqpl0JoDHk==E7xz93kuJWDTj}i!>1i4%T}(2V%#Rp
zEzPoVQ>#p#GEVnt&py%%5>ZRKW%|)m;Qrn#+xAf)K|lvgA`=cP(P|Zisra<AOrd5n
zTxInTc=YxotP48B*Jh0;tmrg6351i;4e4o5O%3P>v2zI8E(mAMm2u^)sj%_Zx%bLb
z3F@ZD58*TFFr?RRByRP9=2x%VBIloTtV}s#l)~t_XI80oTi1Y)S#7gSpFSDoQG--@
zYHy{Vpi?TU$_2TuvL8GrpFE6JB=jUIUscn=!Hfo(=_G1vyCgnp939*&8cN{rWf*@u
z#&2sk@1R+wnLP|~aN&Smql!p~pE)8rBwgG|K)^0A`?&xJ#AFF(4wE@^bC^Z#1r7xs
ztuzYgLUrl({_3H72O93eWgF!D)8=5z4!QI07qo5;_4%@7#YQ>mh)HtB;q&B$7Z%GY
zb7sKu?UK_@KNb~Ot#ac%&%@Qtnnxy#u|x<~V>rG`1d0?NmTAgZ3uDfOSXT>TC#}$m
z%b+=O9+qnseRt}rs0FvRqTUe1RZviZxU<1WlO_WJMgpKfW3o%A%*qYM%M^i?2rTJ?
zx_bu%>x)Yl%Yp@f4{E6Iyz5cO?jk9I)v#pQ3Yh|-J!$edd2!JqnK^43tnNJ2GndHR
z<L3gFkAe7`Fcvaf3sHIkzh0r1co-K^E63PL(vs+I?}QN6kcGyWkgNu{wjkN9j3uN#
zPNP}3afGusEaF|84Q~eG`vDiQIZY}a91g@BqsEM~Wcu}NSYWEaQU3*vH-k0`OF*Z<
z+n#pIbI2p(CmqDVA5~gGOkG6?)sRl802Fo0elU+07cZBKFF0OGimK$k2cE(sijluk
zBrhynDo4$nfzL%2y|_q@J$?pwN{5UXRUtEH9u3-f0)iV!X0#NktY;7!Jru;60A&t%
z!iudcsK9I76&|XtP96&ko?%T00!)a6HAS3Ccp3pz#Pikqg_VJCpa$SQdp{Iwu`>BU
z1Y#-waGnN?)d{7f2n+3m^^3w(@G~TyVf?zrX7pg#ELU8*Ksu3x_R8utQdU-tr2sxl
zH^{tWW??@%Wyz8iGH2>|JiSRyJ!PJ3S-VbZUai4AN|mQ-XqL&PKIcT|WS&N!HLiUT
z$VaGHV4ry+qbf9jUkmD?TY&>=`G+*ee&JXS^cL4rSLGpO$9dLxND62VOkbDCSY}~f
zB@#Qpq4Ue^a1TXDBAaQKTAPTULKRM#<5k>Wy%Q>5LD3Ld{PL^v)^iug_C0%L)#@GS
zzBO2?%gd33hFC^TvrHH}RMxEDEf=443M|25sjq96W1$faA6yQX5V8+dDKJ5z!dmB)
zaOHY2>kTQ+RTCj-T|yb4M~NB96hf*2D>0g8m?_`d6Ldl&WHEj@2n-1q@GhuU31Mup
zXA(ICF5SagtZkXqAxhTgs_%h9Q%_N$Z-OqpPI>92)pGSkr^?1{b+UTxF4U7&!mU?@
z8q9XtTeMe33?3zGSM8Nk7n~s7a3PLAd<d*|WXE?PBOVO0n<Xd6AkRm-d=IRAeYUE;
zWRzyr`w1Dp1bkRR!M7B`tTzSGQ~QR~JP_xuKSK_ra^NqGBKmmZ(Dr?xU-1p?*t3i^
z#ax(QF4tyzxY7mHcra<!57VnfCQY1X@}cE|nRU%DSWuTwLp6bh_88AzNRPO&tAL7g
znO1Em@6U(({H0BD&BajQ7jBTvuhz?mF~g)9O*8iFY(kF%@Pg8I*|E7+Mw~NDn(FtX
zN~8fa!E!<i`B+I9UP|z0E&CVWvJnRj4=wJZU{qmF@?=vW3LMg^YXIUrbG^cd_nJna
z=tgd(3IM#6S_wl76w0x69JEy1B+O7(vKd9nn+ZeAs{p{w>!iU^XmMzG?>gHH<%JhF
z%hjjPmRs*%BsKfnWa7|5sYW9d@{##7rb}H-t?b#}E`yFPlo?Zp$@D3MW%6)jUBkQZ
z>ZWZ{Qi^0$jcIFh1x$uo7yqN+W}_1JVzA5~CcvuN5cDl|9tRB<x~5WY?G}4HIIp<<
z*)^}mThSrHJtPHm*cG93)g&ee9GJE}i2rDF3&v)E9Gwt6bg7y)%mR1fpNY8Smlw@u
zxiMBuw{CM=4-jafx^BCWyj4_OD$g$7s)<$&OE=28oqMIGsX*?1Vl|Kv^?XQv+OV@h
zs;bekrg5j1BT)!aP+K=Pb4CS8#ts>59YlCb1W<)ST{bA8U@Tp08I52y`GLYUE*|k(
z-^Wv}1G=0nW&^sRyv2JElH#nn$-*ziTh%)GND>|2(`!+LQnq}#{r(qZ&wjKSL~N?0
zuuPs>xKg(6Zj{|fnA@<eLuy*`<+111Nh_KY6hKSfva?YNimRlf5lLORhaH@>Apw<{
zATi9~p{h)1LPq#V;saq7!y}+`!roKyU_OWu8(YE{aD1|jUr#i{_j?~&bzIomL(*Rn
zpQX;lCYXL<<fDTGzQm()5}T3Fi5emO>9KW#_!2(?U<c<TT2tMyDpAm+LPkp>*<-*<
zTx=%Y;F_o6g$#v?3T)?<AwUA4Ff$nx&aPK3iH8b#F_h0bRFd5C*Tu4R>t2My%2nBZ
z>{)a+#OKevxB~RkiR|PydGN`X!6qtD?uATl#AnOPE2T!uDoqILj-+fAKT|%yS!sEq
z_1t7&uL}lBhie?7)*=&6mF|1T82>D#caDcPU!)`UFX#btXh()S4Hw3NHN<4pnKVc5
zv(!L=4#XN{>j+5hMLv=TK~0a`F7Sw(A6zD{EZ+(}qEwooz(4xTa%pPnmcKvxva~m&
z?*S6$o?g5O33Oe6<4&17XO>hi-;0rUs<+h2%$y>lywn>%lml#}gzy86E#-IYM#lUk
z6W|PkDz8-!1q~p_pCi~o0y}eI3~_Ke?s(qCZ7jp~=n&1~=CZ>bxM(HkLxb(;X?1Po
zOdzwTZVQvHoO_wB6?MM^b<pX+2|nSNWbe?>9(Zo8(rOW!dQgLW{Mof|NzrZ7A*;6T
z(VpM;Jhlv)dA>aHbd9=~is2T@gL|45qJfgF_X06tZ}e}M%w)J_E;9Vq^bhTE&JH|e
z0Cc&Th3LxyJaI&!LBeI@EN*6(YIh<sB)ZOMIY5!YJQ*u0VyvEl=uB=sotImHS|X@<
z;Qi<zcHa~0bqd85m4ec95Z4l21Lv@A+h*<8`@qvH^_oo(=0vqZX!-2rt80R{fF2L$
zcrtkDqg-oLeXe6J?pGe>&15<fUI7GjH(caa%jl}1u?LZkk^`U}M`cKRH(NFmjf(k4
zGE%R>Wg9T#_o=w<-JRLRd|bI3!y_ER`#vuu_Km4<ROOg;{%mf*21DvCBBc@ciTake
zph_~p<?)dUzj~6*g{3rN$)1)_sntcOEMUf^Rq`7hp&DB50xeL{FGPlE16;)SJ_5lE
z;k|ADUKL=>q1o`j3z~>JX8aUcx^lbhL#xg_#%+Tv=>)&i(RC}q8T7$yretfP^~-j{
z{EnT<^3jvP(mFZq?ECDeuFnO3(7I!-1BY`OYokR<!Y)9}++gF9s(6ihEEAqV4}0@o
zda9&akN0ew4F7l&LU=ddwGi=lxc*VjRol=hx4{@H248q_#ZFx(^JQLrdav@<4clLq
zO}o2g)0XXkA@-1apjNu^CR?Fr5a7Xh+eYge`2}ozQh-FT0(M{X#sGV*bHDW(3VY)@
zzQu4lqB$lV8v|op7*{@XT`7BbNDJunr7MLwAX}y;Rn}ryXJ{d!h?@^VKtv1DmL1<u
z)X*9B>&IBV6}Uq%17S2ag&%5uz!iNJ7cuB*>Fz~LoYM4vBOnt(CVUlvRHOAwG1EpX
zCgWzto<SVGxd7cW`b@juTVnA@&a_w)%CzR`?xqII+D(o~7Z3>%C1K1u*A*m>oQRVc
z<I>iFWN_5iHQSW)GhwPkg*IbUj#O}IT$znx%(I~ctBqXfs`jVvFpfut<agD)2n0q#
z_z})<Pg3z>{Wh5g;@$*4XiFKDdKh&2K0z!t_NSp!HftjW>BYJvwOmB^R~5+A-R0le
zb0;!AG(90GeV;Q<xR;Pn_@3C7b}YzbzNkNYV^*EdGFB8*`sB-JAnP7Dnq`+gjYq5U
z>hmxxiA=j=0p-*U?Cwv@n%*Gt3+8vgDu+VagSe@tGU<C$xas>TswjgOu1g+#{3Rn*
z&^`sU3VY9wQoupXW`d^*Q7(ye4Z5SdmznD74pW5zO_cDtTCXvLw8silbL}sdvU=sj
zs8ZW|1vu&pQ!Gct#I)xb^we4G)M(N3M@#I&tjigeWPT76RcTbQjFOGlthBR-&0S#V
za16E<eSXn$Sli$`rOZ8Hi&3sCF<TENHb2UTd$0_`nPp+x<3VRZYufmDH|2riw(*vP
zQk_!Ck_7vBTsLLA2H;QUc~$f^nZut$(#4&5wVolHqooWgR6EL*3h72AqG6Nh`l01$
zm|_@{B%mFNsS89y8WbdU9fgIrBDKR635icq7m2;6_C;;aT*anO2ie;YX1cxlKQE-i
z8&08v=q_-#0f`-KZAV6sUu0Sxi|+MyGL@XS+zUKX3thk+QjQGsZo&t1Erh$xgs;W5
z5&&`<yTZW1*SLemmx$<=jOXG&_^KG=(keEik8q)KU~wsa##ojYynOG#Yans(cVzDV
z_M2r&7V>PQnQ<-77jqyXTa~$w&J+I8gcOHK<qX=GH^hIo$Bodyx}M}+k3XJ6x1@Q-
z70`WGauio%2!)v78@S7KP6_-V9{GG0FTe{x!~Bd&YZq}1e_L3|hnYBpS<y-4;v`UD
z(Yda9D)6ZhgPB++GoP6#=b->(f+dv&y4RCDgsE_JTau4>HCsPg+feg2@sufg{dibS
z8?4|iB&IQQnax0y__BDAlyf>J<plu;x6qTtaZ5nos7BLRIfZhOR(Kds3+8RLTGnVN
zLD;s3p=<M0k#`?~KT_dmOJCJ5&=5*v#^jrXJrtWVtVgYPjg6Ck`A&?sJpbb3i!_VP
z63DbW8A5X12thXMX@N|*MSEh+53=w;VD&p*HE;+w5F@#L3HX{V_H`tn8E5flRY4O&
zi<*_o79z=D3p^Z*O`{BlyPlFHU`!;C)yc@@GJ>5XQ1^~ulO>mUHAcIYskBg^lM@aJ
z>(8g~Cn2gwCX-_BKK!P;dB|{?G4D*(TB!td@-T~#fYfM&3O1)k^}7FVK5$d97qDsC
zw0+xU#nR_w&yHQ@5g-g`EvTRksK`cEPeKxq^fODkanpCiZ>~Q>cGH?2Z1htXwNgdE
z2-yCQ>(%XK0yg}zW$O(l-~pdf)Ob#tdphFT73SrFr4V#!1JhLPl0@7qTn6sT%r5Ed
z&rplWgD~}SGd<iZT_uZBK>}qb;?e%Q#5IXMNS%X!ETNc^Hkffyks@D}GKV|vPLfrW
zYd<@*a=RkR#htLAZLF|hp%9>eEP>V5(XdrkEP9g34v@oOgUkWZiQ6hIaKyNC@R9D7
z!qEw78yweCfT?>N`0w94!DZey3tg$L?GKXid?DC~&~DpJ%5v1}q<I(g^09ofQ^ro4
zB@<^KD`gO%MX3HL(r}NReid>;rvuY%AWxSws<eC#zkiH97a$>X%d0D7+nS};-$B>w
zCKI6mXfq-=b&q3SN$^U$K1|o)E;Nlv^HTT;d7uhVjs4N{V1|xnaq}L{uW@coH*-}M
zX!-L8f|(6VSn@UV__L&Z$Vki^Ax9`U<Vi{M$PL8~{?!U1<A+@O>q9^*VsTT=rJM%@
zYesGIzAdZdJs*4z>fI`^v4~IOIurq!tJQNx#~!Vo&MaR~SYZyIumH_nt#Hy(25708
zA!q=jac)|j!I4QCR<|9BA5(Y*b$7PM-Yvw>|K}IKku94x$gE>eb=I<-VVZa)9KZ2|
z5D}PeDgMy?oR192U9xTCO8K`BykCY48mw&sxhQJd+6&k*R%HST8^_EYbD(QT-FF&)
zvJPV^7@hVR+^>tX+DRM2X{xIA^9HwVO5DcC{8&n0j%g4=bhXj#|C?XmC_A@olp}|Y
zRz_(DuQ>~WKF1&#FCKKFsVod{e?@u%o$-UdKgZzZ;bu(6EEj&xq#Tcu#G!!2C2&SX
zoz0anPiwLey2X2Xtd(P;D;)P%U4Cp_qoEj&!^Y6nigEkyX~G49LOj)p{Qwm9w;mw~
zD=9Ir{wq#V3Q^Q<MeS=Cf?f=95q6-2y;$C~V)+u8G<uL+b=9>f;bU1J@hnAoRi%;M
zEk%4s=gu9hGRD)4;V5hL2|pXl?Jwzz`^``Fv^;YytEY~#$MF_Rj`Xx+z9K!QQk4qM
zqYwuMRmz%`%jMQP{w|Y`o~wy#aOfH{_k1n@ic_3IK(gJoIs1}I#VhCHCjRvxZoF>!
zV!8Ut^JUtRN9Y;L{us{GQl)?isz5Oz&e3@`vl<DSfo<#6!$#QgQSp%1>c>h4cGiL=
z>DhW1KH#B67Ftu`t@y9Es6wfwW@xd>$`pD9SzU7bZMVtlRZHdg1?Q?4l_%`^M3sT|
z^bGWP9(D=N?{GB=$q&iT!Urv2r#hhdvK(s8>^Tt7RcOD51}1vK663}`eqv0Y*kAzl
z49*c(Af!k<OfKM=u`Cw|cbXwVavVivWpXB17^6xsPwS=1ae2SFzAYwe_o)!aKf1?9
z48I*EV{E-ig@YC-86*Xe!$4*y`tdSshG+6hY{Yk3mYR@e2+lLEtI7zUV`NY@>JL$;
z$V3x14dFb4b8kb;KOs1Hfw|Rm9ZFQDX=~ixF((RJKAVTh6V7DRovf==g~b??3IJwM
zk|ij-IUX}d8DHYwI4xQ4$wRGkfsFj?-DuX&Q*fBr!5=TYJTPnx0msb&VZ9Qc@s@rF
z<FN4biVR(piZiO505;nG)Wz!^JiRv}D6sRM8aG+rozB8B35FGTI6Tv3vm9DIrWdI)
z#68h+HOA~12-1vY3IG!{hL<L=y`WXtIL*PI_T&{P(g<@eJRPW9(f;(jB}_Nz5bh6C
zi@hy@B&V?P9xoTBGD_4)LI;u#$BvsO#~gPm&Spnhpmx*adC7W_2~W@rl}gnKy*1~S
zWr8KF?C7OVAUXOXjEVP{JTr+|6`?{$_nps42vJ{-V{vjLYI?y`^wVFC-z8|bOAEaa
zCpNLwF^|0Dxzt^lJ0iSk08iwW*jEV~z=X8k;b>Arcp6(nIT=u9+Kl66#*A60Aw~;P
zr}g;pj2{rmK-HL!w&-;dR22^=uN5C$Zi-fhr~+WTLV1HzaFlKw4r|Da!kX8G_;c8R
z@=BOR_!+vxK_X~M^1^eA&}w)K#&)Hz^d>6ZVM^){O{jVO!NnZdP5eup(r&PO-Nm32
zE>2_l_=orc`#pE?AQwQttCNWathEIqbTvauCNY?$Xad7F-7`mOYZRmu$O;h0q`V-t
zPYj_<h&s9rF-_GJy|8k`=$WD?xZo5OHwSpvw9A*JSXm<iG6sDfHDwiQ)CvvDvmuhX
z^vJXs&t_Q?h*<wwCM!?uX)i`O8U!{=)08wF^Yw8#ufPNZLx#>~1<EI&sj^0rZYU#j
zOH@$;GdG}GQLHtEaORoUns~$O)T;Ke6{j4ja^s1Q!+BS_?NL60U)|kksfZ*Ra|+t=
zp{nsa`bvUHj0C4>7#fp`^UAgdeheS#2pA(C!Q(fJ5o;q1+03C32{4)*<2*X5@2K%%
z@HK13ltoQgWb+!lI&n%HQG)KkZU|W>!Vq>mW>x2hFL_=%l}l9~`H#%ojiX~B+m03y
z_mBHz`wqOoy!@Ogq;-DymJBlJz@%0-l6P<)pU2;(w3+qomAJ&&!Eqp)%ryNSse;Ah
zVfGQtQuB1<C^%A)BP=`661Szf1&uzCwM-7~6lL-aJ)c~aWb4uGtw#?R&V{x4e%%)N
zq2g&CtU!Tw_)j-Cj;}E|t3V>yOn`ggW8Mfa{8a14w`3UHO)9L&T5dxZGKBXS-)2Zl
zaCl7*Po!`!KUS}>(na|3ZQjO1n8%}(i?a%F7!ewb@JI1d`4KO%P?avj&0X6rJE3CA
zjfqfC|Em0fH(T`4yo=ftg}BBX9EbbHpRL5xypkTC3~#!7ozS+ioLGlJQ-mH19Xz?u
zIJv^42e2`vm-I&C%?yWL={ZAgODa60a5Ou9X1>BWrYUEp?-;XtUAVYSskH<Ko3;^-
zy<?WKwjKbHAt@jqmUJPq_jtW}#1n#9jSst9wMP<j2N8?eg_>NJ0E{OvP2hr78T?I6
zTakmAm=?WL!~(<YWHu=29Ih9Bp;n?pUYjh1G3N~e(|K48wXKYpLji4@s9V*G3<)Ed
zj-^CKYt<2(qNe@hGsqwqA?_&vlVD7jy|FcJZ$QylID~-D&gRjWY9S~S;k^tQC1T9l
zZcyEZ=+smMj|P+uq+m-MkD`Q|npT51M`$%Lqnj>7t>e@_zvjYHtIY}WJbDy#9hQ*h
zJ1H?{W*Oj^sPh1LEz?o10WHHT%{9l7vYOJp4w?3)C)n_~WoWd}j5E4x@KaS)X$dlD
zpy3&uLImBEl-cpDajGF|nE|7bP*e!v-q291aH>EUrwf9#4enU>r{}r}H!BgcIAAL}
z((&`k%1Z5Ptow`aO3?y#f6ab<Up=T=m9-9daQr+pcY}(U;<+(nRTM}?E}TPp(zP)s
zhx<+erXdMq+EmWe!gt;lT~x{|F3cmZi>psL`UxJb1fTjL<q_PYg*erUKj`vhou_H>
zkr<eRg1?Y%T&PyEDU}w+v1$Z@f^buG)mm%PgC$^E#K7|%m4<;rtBSjZqbwBQ6?yCJ
zKqZv)U<xo>^K=Wk@Ufx-)5wP<%|6pq>O0Xztec(0s2D2;bRi&z+fg`gleIZ}axyZ|
zG70xX>43yc90A!;fQBRZQ4l&|Sp<bK2wj<!R?m<LRD-&%LwU3xmbk^w=(=`mR^@|=
zAPgmBVVmN^#!XZfxqgmo9-wx_-Gi|;Zp|Dd8X%SU9B|b3zij7%+IMY;WaoBMym>xh
z_j~T28*N8j9T%5lKgoMzQ&9DFA)vWP6F|<2b1_JsW!95V?H51!tr~$XhM*}ct<qC$
zD!`}+$QGOjO3jwXNRlb>BrBo>t&nyIrJ+NI;?$-JFvA8kA8C-0BS&csbZu>|3>rLG
zI}_E^?9=!tTgMF^G(?)AdAH!GITg4XKXI{ZGAlfbwbQJXZdX^WS(^b8(*^DbgI08)
z7?|qhkddx1Z?$IGW@SLETecXq9ehES18Yee@PPrTfGk7?c@gRo(SQVNW!EFtD>q=x
z-C){fXwss!<$#x-K!tUY@eT$Is;hARHm+-KZkFN0he1%_j90v`s;*EganGJT3ZE`$
zz-4f)vp;YHj*z1;p_0%AIFq5NC6DPA<5)f(fysTbG+Ff{8ewWXK|1$Xn!%D4S4&RV
zD1))MR<9aN2xMVm8gRmL&j}bUvsMAS>OocV?6c3v&wlz7*|vFuTyn*m<UQ~CH~Hl+
zeudVlr^qR%oFa>H($1ZC{#E|%-~LU0cjIqy^3ID8tle_#+&S|3FMM8}dHNao{`bGH
z7T#w*`x)82d$-(i`|T=#+kjWq)q~`-`22_?4wrlGxmRww=_bInNaoHxPOiJ|I-H_3
zNcZ=?`|gup{Nm>duMdCZ!*c1Rm&(hFUzYEE?|X91wb#n|=U<?>{_Su7w~QY@9`kvx
zTJC?m`H#T+8u{P{Kd7s`^_E+8zs^4UEL{6-dFMO-Rp!q>UKTEVK^}bYL9FjRIOn(2
z>QG%2H8z9Fa$&rE^RZ47puOE=WjauB=<;{oVa~c7N4K`2l`oNW2;j#yy6i_^1n)yR
z@S5HSb^GF43KQb@h!Hrr0<^vheV@y4LQ^#k>8R)V0f5!eA>b9bz7~y1cnuY&3eZv=
zPRZ+_LQGEt;H5qAL8DZvNP|V-A8l+P(v3qNVEwVr0uR5*!?Cz|Q05AGAPvi~s7Sle
zSeUo>4lnb3=rsx_8U}X0y~~l)F?r^@HBGX(FO|$j^xfwXo+UVPwjQU;aUAkTu7kXe
z>oB2@5F6H6RaK?<yBGXn<jCR5bNAQo*V<^}C;0{&5V6@wX&Fna3edC!AqOg-P>u*M
zQx0sCm={CEm9VqUgjD*WY~gFDuYe)jywW(Z9usyHuoupT6TQPGU6~tbYdIE8XiUdU
z&)30A#i>r%{!!r3N+nXmN`R{;AHNHEfCggFRV7vG{i#G!1%+`*DNbE+NVOkl7MGQw
zB^?l|xur?1<LZ)fspseD*;|1OYqkreH8*nbaJ81}(2#!E;GtRzT{5azYH+Z5YkecG
zFM|LdszlWe%cvMVs$0?ivlz%*QBkTQWXslFmIbNSDAu6eK&j=yl0^L?HF?%x79b`@
z?cENwpb#<*JBZD=UGlD;uy9fbFu9DzdDx!}UIleM(o(1PX>s#>)<@&{LvRXCPivP9
zM$66)%)JDszR>+yQd*279UJi*?FB(V4Isv5SZq~LZ0h&z1q@4N(1_tmgyn!m<=`Re
zCal|EBg3nQDoo4JFuSIv9t^1tr*)Oe5D0fNG#;i=42zNinrB~^;n~!n*_41pXI2~g
zaMLnGc!I~>VX``ZG7B!p#r#wqVq9ApNA_1d=AM0=@D(m?#Vis3e=~_7K+EOcd+w6&
zedoJ4X74R>Gz2jFG}CQ(-#vHZ_`UH`QGTlI+O-pc^)3k0Yvj>K9+VSLm?x*5dJ0Zq
z8X_x~FPG1L`jhgJk6tgMaUv20#1V%dE|*_^rTp*z{uDi(XUe6QT!?YX)iPiF(jwWm
zWsAJ;eeaV;AA4M$c<fR6<u89B3!i^ZzVlz-k`H|7Ln;8i`Hin>RzLF+{&pvhM8vV8
zmt1_2yz<I2x#8zOm5Z)?i(G&GM^u3P?zg{2H>llm<(saMBd1N4C5soSC*;(VPn5s>
z@ei_Q#Vc~(-~J|z4Rtt5@Ne=jZ+|<KW3=K`Ww0NwsGB1!@~9^mf8dsw(~#P)7Z`q@
zES}A_!0=M={9;X7;&nK)9o_3Huzww`EmDTgf(-SP55*x4<)x|=Q86z;zj=BJ_U+%V
zC6<is*ML5T4y%CRA`fW97{v;!#>V|>Jq{mHt@#6Nz_EQt4dC7>!-wJE9SC9?1yqO_
zQeel#QYbl9RfA;bo}Cb82-mSMHJXPMbfMKKLlzLwXa}xmyXR{QP|JDA_ELAc8n%{1
ztIjr-f~g09BGvK~6o%U9h5W*0RAcb!(rWNk#KO@Pj5_k5(hB9Pq-zRpibT$x^v(m0
zhzkrM(9<(w<VYy!d`J&?W;L0h;{PCcbn;;|Q~<tpbxpDpN)G#J4;?m4mHHO&=t_8x
zc;ql=UV&ywJfLXfrtJ{y;QNk8Xx{|DsE3VeD4(^&jny$&vxXl`X^V+Q$)JqDNAJtc
z2J_h8yZzAXy+Q$4y)Fba39U<$h3Mu{F6i7KblviE5*hU+#H1l8TiaV?$ne2x6_jGL
zE2=Bemak5keFct7p*yLexk;)9LDOxlgP7=qmJ4C6S|6-RAV4F&r|>F83%{n;MybNT
z0$3;Qovm=WAl`v~(-jb0g^cf_Oll;aw{!PSJa?G7xEgT}nQ|L7UTtV%E<<fY+RdXF
zG4DcX5pW?DqWxbH`&H9b3?a?+m>ZnhUb+ZMcxO$7Tb$b(l+YbaBFm?{Si@?_YFFg7
z#Dfk9%BE&`2}TbCeD>qO_Hxu67lJtI(D@4oc2p>tNdu0?s~%hhI5c3bglVhRYnOmo
z6d;aD*s`NqIgZ_IXs(w^5SkGOdktH>n~G6B#w>sfYACF|8n{_$S<+3mZ{I#x8&!Hr
z8S#-qlzZFB<`6xls>i@#4yI-bOd;b(goSoXb8yLGCB-I=951wpI5m1pXt7<e#4C;8
z!Q%Qkgy>aQT_Nv!_j_<I?izR+z?5(;kMXqbYDS5K1>JPTfN3Lebjzkqa>9udr4;)@
zE9K>v7s;iUUm<gkJswI;h0L3OlKlPtzss3toDJcB71|^2Giw6VIr8u$Va2{%-u^G|
zkSi{`RBpfZ&+;Oy+e<FKSl;*E_psblHgDc6H~#K-@;)dHlc!FXojbPTz=D_Mu}2?~
z(Gw@D1zv($+x!1^p9~#7T&5mARc`(BpXAH`@p&o5cT~<g;T}H%=cDtKrEh)Xt8&^I
zXJT#?X4dywlO)w`o+DuW<<3>wm%EAgyxr0g>G*Z-PR2IX+r^|W>wd*Hxcni_dDm4v
zgyon~Be5@e@WO#kh7X01Xq2{=dbJdX52=!Rc%K-fE{8%(Z&?RVv1)FFM+&Wi0fP<z
zdjCGq7WfV=Kzfs^s*9nR!efV%m3V$Um4Q+y^c|q9ks}9zCUN>3XmjXLyoa!BY`_V1
zu<*OIpqkTTKXJ4Z1&uS=vWqp)bf>#Bsu^F+rif}t4^S!54q_H2p%BZ5k)W<-<vYY_
zE3dL7XtT2Ec5i5^lVKx=Kq0TyDGdRCXacTxVNE4~R|$9}&t0xSbCRYeDBFNb3yufo
zi;6ottTn>3*#gg7IXsqa?eKhJZ0*^vrKSw2fajudNeN)ZQw4_~Ho|xXXn`$KYik>%
zJdag7JZk_U0Pszg#CBsN3$Ur(`K*10mrxTkO(C(D?Qzz~R^o;L{i4x09Z9pnzju5#
z4}qJd^KMw*_}9hDqO@Vxrdic=fzrvLHFV7S1@gD!$TwgKkOf*Dw6DBo5*sXD5L5?<
zh3=DT5YJv%&6)siK#{-v4<ec{VWJ`r5r8qky?gg+*5qJViIXNxk^Rt?>H4LnI1Jhy
zk%jK@%4!Ii+HN3GjSPh~-PF_s4HEGij5&1p2(?y7Xd0U)f@ma|NgcF!xg*>H#-Z62
z2(B8kdJv%^m+n{`E@!auD5JwNK}g{PLS`2quG9tLo8g+TtnSvimO_K48=IB^HDT5v
zlTlDnsi~=>S55C5H*OrRfvXPIF|F}kyY~VH<$%Qy9LqTs*VZa5ckSG-t}6-?y1a%A
z83osDC*ZT+;M3ZS=eDXfQd-7jF~*(UIw@t;7$6k9gNJJ%wCJ*TFjGRKBGL~|o&(m$
ziHULvw0?>pXj{RQ_U+w=GL<9c`RAUOPkrn|GHT2?`N{wOuYS*DE_nE%pn$<}&D1+^
z|Bjuzq_ljnOq#Mw&N=^l`R)JxPX6%6o8+^f{FI!u;57N}4}J{THEXT_-G&Wlo#@?^
zRQRYcwV>ZIJw!u?4ukt}pTc?=@Q?-w)x=@LhU?LtjlkuJlP1Z8$&=;Rzxg$+z81LM
z7bp$T%AjRW%Zf=$_uhMteD-snH7^WljqYIxqObhtf69OS$A99u(?+R;J5!HJbtN{j
z&^CuXh<&NUrBu(8-S2WeoFYZ*lcI<RF1V;E_&!p(psdsSZ3C{hwN|JVNFGr#xD0OH
zM(iQ1V+iZkX2kIUpK_e*K4~IaS=Q`T4^drRy@rrV;SwJ)ax8cb4wl(lqi|Ke06J)H
z-mcm3<?t}=*|S@D6VHdQ-CwWID}nV{Py!mp{*lMA`(S%FJW-mfV3wd+!rWCe5yJ^$
z;r9XTXh8--ib-4)j1=q&8vW6jF0LV5Xoa$|l2I9O3;eVP3U)iZ3-q|P0*AQHa-45X
z?-`YiL9qNAfI~b%im~c3qsAz%?%useuiFc{paM5!$S|2aaf-sK9{5B4Qvse$e#`qS
zE6bpypd<H=-7;h-ym0V7(JR-`&<wi4^AK8Sf&#!8yk+%}vs!phQ>!$e1r<H&#<#M!
zNSMS%tOI|cy59}d`Xb+ZeF$hpMyKU^LZcgvLWtTV6TF;2(-<n;M_bXLgN&r1sZHu(
z?XnbT7hKbfE%Q}`<KkMusCbMb&ura~Q>sXWw3-$5aVSI=+|Ju}>{FK=k<2vCJe)CF
zqnlj{m-w#TwGiI5I&K5BN4jEIcA&BEZ97?a@1SjoX{Pb=6f7R+#{RnOoWqm27{kVs
z>AC05SZ+$zmyfksCa}vYcY93zi}ipCBf?OvJrEWYhOImHXn*V7><f(V+TrqU--B2*
z`(9(LA~63pcq8)R&f2{f@iW2)$_?A`>Cu|S=*tbwc@tgu7@!5rie)5(VM{yV+@-GG
z?K|sbFV1tO63~E#_#B&>GZ)y@3OMpK9<_w2R8Uc2;s_GW2mqWO#?mkqe%fo?vXfOn
z5Ik{omkbc>pSBw{s3mvNm0t}7W!CIja?79oB47LZm*vAB|CIdZm%juPM)(DuhL_+f
zzWBm3aE$3fFr_m6oNmEuuDMn&z4$^L)z=~0x9tEUDwj`x=F_U+J^92_P%@j<-Pa5T
z*~xuif}b*0=29S53Rm;qecR;Or(cpat5?gr5fd&!_~u@?q0hVMVhzze_~65G{Ji-H
zVU$9FZI!dmI#;g$=ttyjZ+)wVHC|cviY!~UT-L5#E5{ytthy{2KYa4ZCp0cvUx!0w
z0QbFMmSe_GlJ~s-gYs!85EG_MRl%igVm-spioFAWf#!m^Iau~T@yZdBCgNDLBLYr8
zO=2tf4E$q1)@H=oBincHbBSDVR|8)=K<CAP9Th8<I`Q9T9P&T`)dD4_07;lU`n3>w
zFne(Bb3N#Y$z{ZOeIowjIC(f&rWOZjbk;OTZ9NrbW+1~-N0vPSScEWln;r&1A!^yp
z-LQ65p;LD#N29gN(mDK~Q=l#<q!~rwxMq7Oy;*NQHEx20TRcbaH|5vo{g_~*V%8%&
zcI;JnKu46uru}+v8@!6zAq}4scUdV=P*e_q3IX1@TVd7##ih9&UINfN&oJ1seV@Ab
zTY<~oo74y|g?g88&EEaZs?@jhxJZD6e3h*~StiPR?L;t51vdVPS$ER=h#%|vNZ25A
zn;trb{=AxT05!)bc=siKt;&R(@9RQ9tMGA%<4M{tz;K=d5t{&lq99_+Ov|i>Fk&JG
zksJu!+Q!lqTXJ)Y^=T#IwF7y2kfcCj%}3i%%e1sjZbg}r5r`eI&P-Zgiqh8HDYZ?t
z${_O~=v(o(zI@q$)(2CY(+^Fs5Rpv^V|2RTfJDsTRKZPjV?u}{4sS*GB4msg`p7&H
z(cDtj70Eb|@+VCivn+D0F$8nb(hoK;;n#?_H32@_Zj{Oe1UA1{_c<=<2GJ?95w?1)
z6g6-NB*<C{rF;-o8%m_uC?9ehuOivs*pAbDaE`7L9fgo(f#=f=#aJ^0yuq2?4`Vn*
zdUBOzg=#Dv<0uglK9*Fj8nH9AGeG9G_&AY)P0zt+Klge0;rG8MpZwInt8zDU)+`9;
z!4QTYlOO!x2lA$?-=TQ*`7e9{7Q!%@0Qd4;cik%wKm4SO9($Nvef2f+tKa+**3~Xu
z%!jW3n1)*@$d5Q;nhb##he{BwW}cTmdFoUor9CH~{N(2mv&@%IefD#5;(`S-1=sF?
z_41()e?;kE>eMOn{ttXmmM?z=0(OENgM_kk&pA)dJo7Bsx_yVbV4r&GX_<e*iSpg=
zeh*4QiG2O*-^ADpWz^`g@I19bIV+LrN6*mYr>m~HMwTpnMb@u>)o??pF_v!G?@dZ)
zi00BHt1y1y9Z=!KAR>_3hkBf2m%4L}$(!xSR+Ky!*@S7Q;xw*f>=&PPqkORiyhDW;
z;?;VjB?NK@V8L8~9$ZiS)*b=4iYHhxX^C0J46SJy9N~kB?u0i=Ennbx8)$?3W95=)
zVGMb#z4h6rnr<cPtD%1TdVrAjhH&<+S2Vm*AEmsil1}MtB3P|w4(!&-&;9L$iTM}I
z`XpdE^A0VA!ajp<X!0gq@6;`nuZXk&7x{<+%)5<z6+DIaQF&)eRoaAFx(6Q8)M&|e
z)>z7kCBDaJo3=yvgQpjQFV#ZmYnlK<D40hpP9W5L6y<SLV6bPJyTTn;&C2mS@>$me
zN<9T;U>RQYL%Yubb8~tQao3OS=J&b~&`DaMZXbJEyJRuC6*Y^GE)||<%9sr|8H=SL
z(sCfJqBV<~drA%4b-JOuP-{zxUHGn3ldE(KZL<+eqn7FklxA)xH=5-n-X)>Jm)e_U
z8*AO4mYcXf(mGcYLe!>dE%Vf7<~K7_l88mcLK8Uf9iwR8nV*UaY0OWpb==P{$Ov?k
zjZIp1CkUTepZMY0=<c?;n^R9+qb`G#y>PuNNS)?NjAm_Ud`J}$Um9YyuUbov`z#yV
zFw6+S69LC@GL;Mw*IS*mZUi?;_tRXp^gb{P)DGX^CA6g7POHmD%ZlilROaH@N$(Vs
z6OqIqK7*0Nk-%Iu*r>pSyKch7iSolA|3sd7_E{CsM<0E(x<5}s2KSE<GFb#GdKQHC
z#EFwM7vKwD`cDlx0G-vc7>7i%k9_2MSh8!75H?FDPdQxOs{{&#EvpXrH_Nf;9z5rq
z^W~U1$10Pb0wGMxmw6Xd3cmU6@5-~!Jgu3q3*g2k&QG3txP0p05m$zl{*|wOL!UYA
zs8)P`nku2^oOdA@EW9B#jmYZ$fM#=3LEwwoyx;oo?`X+ZeM6&s3>Nf0cuB}WwXd}*
zsC{REecvyW&iZ7<EyF>p-L)xkyNtGs#x#858fR$v5K*0Yt)T~_XEOf+mKU)%wF)yf
zzhLQ*Wh|@J&eM_{y;!F#=krrMcEK$rUc+XM`D#71xypFPGfBvoTbbBKDG|<9Ry60i
z0GLj<D%LE!VyT<Oj*aNebKzb4kuW4(>h;dGO`)ov@jm64$`{EeEfi}?r@_>56<wFX
zK@AqJnK5L*#u_*opzSPfyH@*DXio}*r}dBE{Ve6Q{s{VXhcdP=#xwa|TbOFU3L9Td
z3XD<0z2mi95_<qC>*n+LEIb3p1a_jrhpunmn@!;ok8Q-@1Ot1C;*vAUeEZ`=T0k3d
znaiq^wRS{yZUz}Vi3S8z1qM@r1OhwQ0hzL{UpMbFLQF8zK<EWTjPH>UW6yCuWrtvj
zo=*5F_Gnv16OUomqaG)Ryw>c%2`0rj8{0E0A}E{mck`G^2rJc3-GLOU$?{4jH}D=J
zZiJXl(gKxG$VYf03@vYaS^S#C`N+J43$+rNmhCJZ!5W$4?dv#=m`#8N!qu%?SEcbS
z+XFim-6h~?W~@P>o7tWuTK}198UA~xxHxz#83qYb0a%>Sr!vJx{eTfH6CNMO_!kf5
z@LbheSlY{o)s&0_{fcCEP7`;tad0v?=EL3D1ffag=Y$haRwhgrKf@=rwT&_ul>+BN
z08$XvBK}6JV)WRt*04cwhItE}h!IbbDM-?yrCbkT%d>j9+~Fwe(LKS&x#|;*0S`j_
zjxQ#SwYDJnkuG=S8x%s&9yjj<{jLdl1iY^lIRX`x)jFqgB<nGDT!w_dib{j0S#c(S
zii*o+%-D)RDWT#y0-5EUS1XhbT1O-GZ`UutG5dksm$*V(^9W5sD^Jjd9?HQ@5HYrF
z9ywGPBgQ+Zs#L$zQ;*b2HAS<B)~Y*x&E%>H5>q@qZ*cgn9KfC%D2@8w_=<Y1oCNYh
z$oPcsso?HY!Opo`c0~a<mwSwPQAm}RAxRUwPAympp#oPg9ZDqa4Nm-yB}$g(VV(oa
z9ES%?85w76*(~J<cT@o%id+Xr?Q1~x>nu^_jZW$D_+r1A2x~ZGJi`h2Ae-LSZ9LKA
zT7u6w5vxj%wQJ^_T%EQKWju=`7tz?E7Z3PXUdDq@+@1ku`N;L4L1KqxxbjVH0%T#b
zOl%{rn>sE&#;1WqMoj|04&f|r4*>pVDn3=Db|l{v6qPB`(`svIY>^c!R!a$lbP<>a
zV|7ZJDlm*_f^ifjxWk4t+IWFNOeuzp(Onw|SbpX$Zv(RmM~7PB`RRA~VP<8r^mg~@
z;5IJ?fEsF%q&1Az2x2pBbuw~j83+eT2D=ccaAmTX5pAmY3CA?}o{YR28N$V^F@_M%
z)A$&ZmEdYd!qAEpYf*Pu4q?F978#6b!wMfKm=nlm+NrM5wJTLZbCj5@nD~Yb?o-DU
zJp(dW+aCDe>OxE!#KVQe?5t)8wY@cMGNhW>nK*H`6&d0~kU0()x_Kb5Hnn(+Q6|aB
z_|$M<uk;KGuFn?u|I}vEb(<2#W+O-husNuu0MCz>k!TkXyB7Pz?AScI2^E%x)BLSo
z9=kbM2Zg2KzbT{^S9DfAEk9)9Q}Htk!rYPC5iS(w&>PK9=w7A}(1PUW&e>_Wu63xk
zCR$O<zU9j(=Cym7;sVBo$<fQgTIOyDpl;wlLrP4tVxn6S=w;`&E%M6JMaZAvS}gxT
z>xZ}w)nZK<53A&XVybWq@fQVpLUHvFpl8eYkU__AmcNbCyuk4;@nB1JuZ&CaNXM>x
z#J-^@ZC<w?l_9iRfm_XW5Tv7nZiuM_ktRean=!8UZ*(EYWC)U6^8lM};Avq&8N4eL
zhJ~_j-D-@BHbgFVZnW!mS80#*Z$SYHcU_<36M??(@YMv4hd~H8I9?J%FmHs%K+i9{
zk)yEl0-DbT&b7nnX#;PlL|N<3?Rya383bNIK@BCfxkCnx8v}ULfI|tE&LNE7sd!3y
zG8zrPqHj4shJjAcDK7YRNLtWgAw<{6FqAqBf+bkDZ;uQaI~+*~Jt&<T!X8%gnU8%M
z7K>#cYwfJYFKrXTo8hfRCo7c!TE?FPh<lqP5{(~*_@GmtmDIwB#%omPP1{@>-ZNJ+
zN_2%9eV80`>Ll>VcGMSdk&|Z4Q=}pW(S6GpwZ_sjk7&vQ#-#-`dgKUL$;Bvt0DLBl
z(B=x2Xr@wFTqU3VII?f)x@KG&NUQzC63cM&PC-h?O#IwE%q%g*6Iud^l7YdyT=J4}
zw-B(*<rRK;ZPqJ46dYwEC(2Q$O~f!QvVZS3Ibr%-Xvef1=zcT7pjvf5q;r2Y;2_4C
ziVKQ(9<3<Y9DeylQ%4JF@Sbt2!r@kCXlbkTpE;jn3O*(v>Bmukn`{XI-w9@uDWN@Z
z$Q{LNBKTOK^oH=qZ-IY)0GEip=`YNqi7NyHzNKeX*9qYQg?`NFkx~iwbQ3%fMMzrA
zV{#D~`*>s!KYH&i^6=lE!VT7nRl`|kUaGK7H?tC!mnk}auRX95bQFBzJx2T>_}VEk
z&NZ$36;{PP|Dpk*iBGh`=~)9ExAe%&1?Q-1xVCPej6IA8$~dK4=iQ3{QUy0)bjmZw
zj2ez39+B{cUIs;|$S6co;jmHT<vZW{o|a$Qv~0t@m(KuXPc;lO#Up^1(y51ydlN9y
zB!-~MYeFe;k4g|wf?EWx3wJ%iPp<|QS(eIxfJzXrKK;t~n~sTux=tibP8@p@*6A#0
z$1}6x(QEa+c_p0j<dpnFQb6lgI|8R=FchT-r=NJd{N=$#a@NGz)=wA=`n0ppm*$gB
zg&oRsM(L`dn+jH<tKH+yCwPyQh$!Q82$Vo&yUGMmh+9#Ew)E(<JxkBd)4ai892?sq
zv1_nlNRI0&2B9u;glyfi0lmcc%1QH&gY}D;6A=x?_k5o9*NWnt$x~q+<}kzr7o0R-
zZhiPgIc4%p+|O8izRWxAJeheM5EL4w6>zaB0f)D)W^S^{BGY~DPNcK7>t_x!?t8z!
zRKNr=YyXA2*MU8FraoPTQnJXPl2cp(Mu9T8&D++&CA(MV&6@{$V<Q*4R<q<8BIs2c
zKEPxa2;mfEE#Olg7x;a$RhhuMu)1Q_tc~XP-A78@THMExEI0*6&5INbg9K}}@1w2W
z^qbv^k_Pocmt*pKTG@$$zXQ7m(e6kStaRCTAVF!|*fB_GJ4#j~DQ?~wlcWuai=D{8
z8Z>geoPYIuVL8&1VEGj05;v<*^O#Bh8k414oHUcznq>M9A%mAkDtJOSIR2s^>&Aq?
z<A+YEC9Wj4-{RriBk(nHui}nE88T{utlhW{%0`DAH+MGH!1k{J!Sw=kJXd46<}svK
zVa$kOa@?$$^1_N0GWX1*r5>S~BW52j<EI>{)@(qx6mEKMv!9-=!J5)I#XVptT#G#;
z!NUBa5_Dl>hdHzfU)5WTIeER*4aFo|1)!beh3xfq^pfZ-2F&2msV;=4wQ_=n5qE7{
z3op-pnLB3&_8S!@sM8K`)f-F)7CmzsJpn3D<R+*OIRWk6)5<th<H^_dn*WNDk-t6j
ziY$5Q8993P32?n2=3HEXn$K!10{^rQ6pLfBMzEdSVpCg9^qR|0lN<DNPb7vIW?Jfl
zgZHY)DD9Y|OEWp0CYC@g8`GMo5Wy0}r$d3rRk#?wL(^lOeXBhF$h~sq1?PZ)O!xhJ
zlqeW`C1yIbkKAaRB9X3JYYyM@?sv(<PcM<xi(iy!IN_@kWl#A?ASy>4ayL)WAtcy4
zSnIA6M51g}|8vCP2*x~pZXKMzVvuEW>NhFOC(Ljx0mOqbtn>sF?8UtivfD8om+?_F
zDQN3%l9!)+SS~vEESWKLhKVi<mIq8BLNsP^VdX?K!Ns{-exd#MF4K^-3^NLkcc$K%
z%QNA%v2hZ3=E&ILS=QC4LTF+?;Q8w3vk$x|GA^7Vki*FB9;8?3|5CqHqOlmPDo?ie
z1Nn-(2NnikPL*}#;vos|d*A!z!yo>PY+SWW4m<oPtz76twsb-DIPE^D=Pc{0JRFSg
zn7TnLP18~x?(stJs!ps>%gX{<@{2d&ZV*$(qku^m0`4<+h4<=t=;k9yjC0e3D|n8I
zA*4|OtoaB_o_buaebc4r-*6c2w#;ek4(51J#0FR?s^1(c>j;a$9(d=w-XqU^<V&({
z<uaKx?I?s+P^&-qFw7lEYQ!IJVDK-;8XePcP;)%QuhoTD6kP%VjB8ZEHtg}<7@sVr
zGt)2J_g?Ua?<W-9^O;;*h=kxGG<xbrFZFyVD`lNXv}1jA({6e8vA@Z+S6w0#Cy!Nw
zEiEKD&<HvJ$nIg{hazkaIRTyImUcVVf+F=1X!P)3U;mQ4<t^_(azLxhm~#RM4GBt2
zkWzU@4UcgNL(+s|X0aY0M^Y34B5R`~MI?tZ_Js;#FAUTYC!(m<X+*2NXBA;h<MnP|
z<9G=dw-Jhwy`6!|qJLP2)Z|)s$en-ql^ij3lDzG0Z__b~ka5VEAWKzf>#_jLm|;{*
z#B^56T0}iDl$9YUf%*D3zKmMhcftsV=6EdN19u+#1@pzS2gbv!M^J*nst8c6)ctl4
z31XNYTPURYG{AxGH9JF?^3|V6V~z0j#2AH-QJU?8%T`T-PlDL}Ik{v6#YMQUZ4cmc
zgUmQ$lDzfp|Dp*o1;r#X#%&G8UJcV-ix7TcdP(<oguhLGADljx^l`eh3O9K3-)i=5
z@JcXg`zQqS2>F(9aXJp=?y<UE-tKS8EcwFgG?2KMv@$#Ah76v~3#=iG<zS?*F%?Ql
zvN?spasG;FiUirm@?*ypyy;3ohCOszgesE2r$*FzA9dtWs3-rpeE5SOlheA-m#O%>
zsf*p}%txgmF~1%aa?bj5k1z_f%wtpF!#ipU6fwLL7AD`LWry+`EoTIO(qt*}B=@WY
zc$`oQEyV=6;fv`S<TvCUXq19}w@r1s<?cWHpPYKy@pAd4msuPb$zpmKg=ZPb=#~U1
zy7(<i%$j;MqKtGrl$K9_?&EU(hd+tqCeD<@kDMWmJXOvUFo#YsR7}cBPzeWTj4N*l
zUTzNzUIr|dWYK^sVtZpAX^F2isg{R+a5SAeTQ*Y&!{_ecWxo@=)K5uQf!c5KjC^=b
zivatg5>!w$ZI!>>^lLfsq`7j*rB`ZK1uf6goEn>>O({N(X27(VAIHnda2(yu&%3z~
zK?^!+)y!_KtFM>i=gvY4#qY}xfAULt^uF6=#Mp^af^I$R>f=ir$m|2qhj^MIixZmO
z@-(?*S&R0yxk1<^i47zu#9Mge8eHoB=shhFaIHH%nOaPd2@g(aDL&a}UR&n<?Qli0
zLs{LHwQ|C-vtaf9t5l#IhP9@4SUfSuY3eTFBsFFm1s`rM8`mE*dxre<r{9;K{N$(d
z$o+T8h*9H^-8&c~`_rYo9gsYVDKs8fo<W43tnN1>6CM*+g2ozb-N$=cc~l=5Q9F{H
zm_=!&S<YSOtTJ;OdLr}BwhU6Pn92)#O%u+0k!R4bb%V@5ZkD{`9dAPeheF*8#>=$#
zx~do<CvA$Lh%1bv1w(wIJ$MRuE^~?!-j2~bsgQtAW<lQ@=ZP;+(?{vgy^(kyX(bx{
z_?!mfBKz#0aq6k^o$vp*{PtJBMZ41ts_>VvJ*ndhhW@zMotBn(p5q%%Xa=7<-r?mb
zS!oxn@?!R*$LV3j?GDgJ3z`D3w}M%oCXmfJ<vn|$mH9E<M{HTCErFSY)zN~6K|7>z
z#}+yJoRj6+w_T$ph-JlWsALC9WPdr&R@ip}0au4ox%nrbAm9A&ugb3pAGps)qRfw-
z(9D9TD&wm)3{D<ifwwU9{K&b$bH`o@R5Z#fxGs7|k@%~M00b=D(rhZCX<}}yB%b8m
zJ^}ln;tD~|oCE3#XurH`C*ZSdi=2D*>1cy{wU)5*d<Es%UaQIuqyfGnE}eOWEO9+?
z=8&?WGZ8TNi_RwYD!u?N;p66?Aou_MA$k6pg|ZI^S+IQ`HC59M!`d(jArrhQOtp_?
zpb_&;A?gjA5u17B>8C+ptuk%;3>;E0O>0zDkZCi4MAXi-L}xL&+-v_#uW{2dW=R;&
zs6J})I63hx*CRG^40`#ZPdHlqp~W>>iV~u}b93f;;*g!53dJ7enBxU-37>$N?ce_X
zusrwNLfN}(pK7m~B}&kwx-#vFAq&m^w!=1@koLsKL=4QgeqW<J@cgsVg?QEUIdimS
zUndk9^FUjS*xX{?+%Q+G^OGlUh*}9f(v0V^h2P=hN6D#Ie^lnonGI%_hcYqrE!Qkj
z4DK>dg4~*zxZhvF5OsgdM-MQu+i>yM<M+U!d5AQUF{^K@$vBU`4Hv*F{`%6vt9V8?
zy9#f^YtkPpKrX%HVwrdRe0k{c$7J!s=W#F$+D`gbe@e$;Mb*LDs39{YdfEVf7K6TP
z>ucqK7oKOaugp4Tj*J~U9t~aWh*7mkwI>4^nzzyu3UR6oVeUu|vPD^AU52uunNtsw
z6W@BJ9DUR@DaGIAXc=p1vGJ@lv&Vg7Afs=7#!3*b@%)P}1aCc29(w3uS+WT5Y1o5W
zcy_F_(m!>f2h7bYLIh1>!_78H=UQa7r9~w$wD!rPFD=xPyjio4LlWP32x^|T$8o5D
zv#cz%56ZI)Tf=BY3%-lz3~)xcz8Ek%`f$MKy34iaKnW7uN&z2#QdulUdO)Z(0u~WW
zJ*co#`gT@67JkSG=-!Bu6Q;MBoq8H@s6#cZw|883rCfLQ71(h0c5c&Fa&~yUWx|=j
zOE5GKlZ4Q-FT+BRaVu(CU;o;F%Ev$SZV1uY^5g&a3wg`6Z<g6;Dxn9vyCVAp`5N&C
zHlh-_|JLTfp1VwTW2;5>oAsV`9zMV<725FHx-oI1#(LujXFiE@Vp$a%P&CxxC^sC)
zK-gT3!y0PQ$*U29o5vVhhqRQ0C3W4WW2Pg&q%X9)5?tor{?^y!`uDv9iogl-y&wON
zyy-1C%wf*lK#4J5n<po)bPz_4DS7zlB|hF~XTO%A8HS#2h3Bv)nu-D$tUjA?jti6n
zLTs<EL2X~d$uYSI_ukjqA0ZkZd7#D##`HR&|A4}pSOz+4tVf@C9FO`=oE~<~TduJl
z(CFK*M?E^G=)Gvc?W(^g1a!bhQml74@lf`(M}F|_Z^@Vb{Sz{F%xJmc_kWOoefQgC
z?6?VNKg?F2=CRYd=w85^9Oh$F6y#-~kxUu9Z4~evql9f$+1ST<^wa~F@=AxTc?+#v
z&S;eDWyp%2G4|T7MyC7Q-*%n6<(jJ@psh!?9U&R!lmw{f5Ux{K7Sbq&h1`y^u<!oY
z*W?TT{xR+C|LfoUPTuy8Yh>coBedlwdw;WJuM2MPB$s(;?4)oOLz?`KO-s<-jt6S+
zZ+cwWD2nSMpjnpa!ry%&;DN@`Xz!aDF-hyg--nEV?j3T*+<m8>4xCoihSQ?hoTCz(
zQil3Hc3|S}Xyu@05;!4gft-ZF;NNRJG@+L<4oiVaH_7ss7Ry_3X6~6d`tJ*$|FSGw
zyhP4F>vXiHWB)z26m{_^H)%`jXMEPu`NJ>oLgPJ}DM|uE%!pbaYY&+eWi2d2l1IBO
z7%{6%%;Ha_W=lf#youSF4G0M^>#`Iv@8W9Kj+-l4G1hCm3L39kB+VLYOf=!=RU}8A
zalL2P4q35ysk{l+$SEhzm(P7}r@XQV@Hz7=X@rKX9>Y{7>5@~7DJ1s7mc>ua($mgL
zcnfC;K4W(x*HTdjHI+qw6jZz?!RE5TC>~`dl)8A=AK0t<yCzLK8DL+0f5z+2y-|>k
z952$<>$;nf`SW<x+I`v#rvllUWknU5OlBb*-;5}Q=2Wjt(F{XyB^vW&t4*~#Wy6Y<
z@@ceX<q@G@|H?OI!>V;M_n70+v!U4~f6{=ku2>mgN+YC9HhwYXRP#U7_;B6-T-~{2
z5YD<xVLoXOuxI)#dsP-Fq*X~KYqQp|4LGTe&nbmBu@pTNtZSMLmYB6yTH<NU#c=zt
ztJx{bR<4qdef*<(?)bld`D?Oj%^I0|!pZ0(&ocp7O2%2S=Rp#C4)JgMLj4dtQ`iYL
zYrkxsJMA3DXoZVANAb{Ha4}x^AO~I$g`-NVruWbbY&~)gkOiHbtdfp2xd6v6n;l^o
z!{IT8N=n*>52X}1B!Ci*absiJDOOe_!E#i_Fi3fRemo|z3)=2s^2ININ$$M!4%x7N
zt<0HwJlyIR<J{t1GHmEjZIHrvXebJ*-HAAg6+|Szyq%s8cP)ucTlDdn<O#f#h@=ff
z4AFgDJma(@@PO_!YxQXgf?1mmLD`uMpYx+a6?BP2Hhq>}n<|)ixQ26ux#!W6rIk<k
zeEQ!%hrZEw%c_+tW#;VJa^3|OXdmaHIHAVK-)ZMbb7fE7WcYaXh{<1^2D8j{F7#$I
z!Nz-NHHpW^wLN3t)`givZ;T>UW5}fR#A7x&kYemh`$7|GxYk!;93d<+&*!y)QLgaO
z9Vbq?H%cBlb+)W!|9JL@H#<%7Oi>SSTzz49mEOhL+h(#K{gf$F<lXQ6fZU8jQico~
zieBia$lT*kkR7{fw3!fzlil)6!S7`>$DC<DF{GwzcYDk8o2|vL@r;Dho1lxt$h`~f
z;NC#db#zN*nEe=BKB@BCv=$HUd5SyPae_x~9*N|$4}RpMa>GqG%XoMdPQ{U_$IU+(
z=VR{$e0V-Q<J>T0&{QWFGIi*bzg4}5BB6?gerL&VOpZ0<!;XPXePy3<Y|`!Z!bnd^
z1f80ql$ez&*9Xdi&O}VP5?OfVi82PpfL$9*zfi?1a&^n`h~o!k;lCYPk$4Jw>y|(O
zPoH(P{QbfEWFIu`(TIr-8$I0m#lrIC!31=L6M?<!i)9#mI0aB58NuH9|J(P@rIcj7
z+h>7>?yTB?v?6FM6^>?An#)OJZoz1#Hn`k16MiYoI1^8&%PeG{D)O_7S1Bm<sF~B`
z?+@Iir_+o>Ont=Y5z0WIE~(b4Wo5WNDcnuhx;rY*Lp)d-_b;^Bv}Bx79Y9d8u>XQ<
z4;GOP45^0LW?u!V8zMFx#f%5U9xnnA{kb<2T>CdBFvR6fXdSb!%Sm~dSyjGh(DRIN
zAFI#}*$h)$iU<~5ti^I9YOa^QvJ@TUT4mgnNm7mTojbvl*oT0Jk9Fx;&{+hu5wg``
z2d-q}Z`u=|Uu&OhzPMgqn-0x%G;_HiNmOLd(jnb%g+F<cBQPC0ZG59d3m`a2o<hYo
zBgX|fBrM}uhz~DY^nx_wEXlE>N6W}zL$zlEt#`tQJc4{A^%W&zwH>RP%6@Xz(ah%U
z_^O^UoosAGE+-v)iBI}LuQ5=^J;(M_(~uNarjxx+T-+h(@nCY(d)<ctnyQ5zRhASD
zdn+|C(dtl1-Ka<?0daN0g;anT=r$b7Scu=naNn{65pogqw?173i$@*PB*OyG5Z%z;
z$9xhf>t_{4y~KNmV@Xr*jd3NkuLL~o=0yIqkxG<UOV->BL(CPf?ICrYhB+)f<2kua
zZA~~ox=_!5M!F<=;iAPTnGoKa%g_NRSOGuC&}l7ggZz%zyvzv~+V0n@WR6C}f9g;B
zCyXON=UQlbI?Ko)owDaxVHV^HbBQosC-78-F3`ILbkT~8>pYYbH8nM$K?eF~BR<L)
zFNL!P>$IjQJL}d6q?eN3!=}Bx6A6=!b43WyXtZ)-AW4+EBFH4g*NfeF$mw};X5PXp
z;6%jfcP;4eP4<GEfc^WV1Rs_nXNFB;dJvi`V6O(>eJ%9xbZEJ7SDI2_8yj$CDmltS
zUaMDJW|hD(bC{SsIiLc1Ac-&0f-hOH1sQ`_kM&|ooT}vHQ-H(azqOv%`L1*W@po}C
z&OY9`M?U}A&&z@ZC(D&rTp|DV{*TD*x89DDsCP(ngSn_#?Wh|bSn$+f*?Gt}n=qHL
zHNJA<*<py+?(BEw%?oS9+2E+NAyV3;f~?0trm29nmv6-we3yYypyX0tcB%?*L@5L^
zBMF}`fB8S<WRzvR>B_6*J@5ID+;Pk8@_`S$4-BahadjSAf*UB`DOw$aVIL%aLQ5hB
z?$#eH)-f(uyX{tEa}R3PdndGLSiN>6nr-iTTTNf@4elFYuGH80WW%)qWu1-&40n|r
zdU=JF>t1&v<;&DTdo)35{n~Z%{cnFquDbeaIqtaQ<x`*dtW2MIj9hr}CDPc5oEeP5
zaG3R<&d#`1Dc0~#h=7%bDdFOck-92|s{HK3t4Lar{-FdM@$%1gzXNYz@4Lve#5cUU
zQNH%IZ^*URyjhMrex7{vqo0!L$2=+*qh7hWx!Jm=F(FOEaM|Hwz3T(c=I*h-14G2Y
z$}IiY;uU8dwhYz5LYE&n3tHtxIzT*u=N@!72CLSbbN#66))S!5N>a_z3o5r6>9l0q
zr#Cyz&-~)h;PMeWs+Ni4Crb+sQ{Rb$*egmaWpEYTFen9J$1<d2D-gXMAGqF`+@Ns~
zF5V%Dqb)-ik3WedCtX$2{@FV7SrU~KE)h1V4Hik%_N-9O97bhnnLZ}5M}7{D=JMzg
z3OaEF7h~-OfW=^$1o$-7HOs~gTW}K6Ai!*x9?X%4h5<a9lRw_=WbtT=i+AZnLMu!2
z%en9I%N-=-fEEwQa{}1`xVXOpY+$C88|Gws=Ap5c-XW4%84D;*Y22tP`DHW_g;%Mc
zc{gt6xv0eh)-!7OC>cL?g4E-j=UqGZp<<&-s?h1M9p^{qBk7VBWDod<#+3sPU~g-r
zmh4JF-CX@)5y^~$N_l2}8-9Y7PkQ(y*6PD`!7yMP-Y!nuABLotCcWjO+nu&gMN*B^
z)<zw6nAFtP;f(U#QjWNM1^7uTs!zJ<Y1A;8okAT)Kx=<;KRKN*0c^9j&yDw}#~}>^
zGSNvoPDJ5Z?lLSJbz5T_=0K2V`(r0_vY=ILsH9IUBCRYzRROp7lo*)Z7oXXt8h1Ks
z5F2sjJ0V)sGlFf3Nl6&V)~G`ow_)l^peq-@I^o*h^y(^k^JVADfBeT+<mMZHhGPLQ
zkr61Yf8m*D<b)GWU~ZQUu9LHMCXPkJSI+ySayk_)6j?m{_=mel2MPX{qi{9=cxA=b
zZg7rPk_>4blsqsJ*rRjg9#T6scavsT;<m1?HrcU#lU#Q3c__8|mfUsQALNX4FO!iY
zhR9P-KZUZZ`Ec{OGiG%Rcl4Y~Obbf4LbMUhWWzBv$3_E~C#LG6aY>jTUFRJa@8aQR
z_^NDzEJ*&#;?nGm38a0OLRW@^9;orw5C&S*v-w$HnNT*EWMfrP-^U%(JZe6>&_;?B
z!;xTeS?|uX7I2D`z4OUsn(u+!lme7b)+466XWOfC>17wmH^2UMY5vvE<chakhq!9D
ztX;EOrX6{t_5cr3fn3jnqzR_T409SKyN`{gmC8e4N<S4U!A(-28Sw689v-aKv!aMi
zu<0cO&e&k;#NB7))$~-tGHz{dkiFYC%bPE~NPhT(@5&9o{JC6w#hcN-v`3aNSu97-
zoQ+jk0~5<t$s|A%6H6Eo_L-R|Av$of$fg&UF0wyYVH-iuy(a!ez%$cF9NWU9xt3W)
z%so8OctjKzP{}Bk%_VG$bz^6Egu&D=!XrA$c?by9>DBJ7kr&Zq;HoPwlOO-^JM!~i
z{7k-q_M$a=>*VQ$i)7yXW7Q3#bJ2Q4M=k^?cE?(d+B{NuXsV^`_t#G~SDQI~bHhm;
zakRi*_Cb?uycTP|0@f9_w6w@Vz~_upPL$hjxfz+<_sFT|oF@(NE-YO5lC+@demUyA
zHTgz61Q?9H>)$Ia*>N?(wuvB!++daq-t|61e~3W#b=VcDbP<nEqVKiw;y$_W*Togi
zxvVAbZ2C85bUZYA_oD!5j4}L5XS`-rn_JRoWBc}PvU&YVdGqBLBhj==o_g|W`Sho*
zmxU-v+`es-Og&;Ul1y=f=Fs?z;}nRbOfq?&ZB7ZCPt4JCvUu=~!yCfS35}Ww?;<2q
zA}1N}L6P|0-8*Ids#g#;yig_{He7yt!wvG054;yAay7`y%ht*<vyQ<DtZbO#vwBkJ
z8TIhqXqubT8${ysgZTIuHD)|wHGyn!HvvsLXAj66UU7*wham_2(kLw^8I_|SNzk&R
z&culmW%A@nnvFbc*a$h|h^f*&Rb=(X%^DxcN79G()mCbWzscdJrg;Vin&YO77azfT
z-wqyaIby^JJwb=BY10mud2^=g`%SODsx{rjEG;L~Px*iUlk6(&&zypL`v(3#<6K|n
zJkY{9>}l!qLi%`PU)JBpM;-FFg&h{;2TY7S{P4*#Vcb}mhyyIvjv6Y{4<Cm_(?WUV
ziG`p7JL{W8KZ(TB-j{i>;C&#Tqg5PQonou)MpD?gaih_7a2y&Z)x+yHR8Bg62F?-a
zl=ZJ}L8mu#YNYWK+tNKSC=$(z<1w1(d*cac6({ss1<SJgauU!{AQ{Nb9muhg1fsK=
zdj&J#QHoAI%a<>gKcj8tHXP=@e*Jp+^Pm5M<fm5IQ`@LXQdY@pu5=rgqq0U<(J(gF
z9H_PWjn<ht7gOv>^?D(?838`qwrrK({r-<gcIlR-OO_(z9c}vHO?Y+9I<!$d(c)~5
zFm1SGsP}c<eZ6lW*52P|_xFCkhQv7W7{)-*>p;yt(>@&N@x$~m5V#QD3u}sDmJfNu
zvrj!GT`djr0@{eKUbRYYzw@uMZu1T)LLLiCh*;aNy(cxnB00i)FyL^YU=fXH`ZVuE
zlM<AmJ+o{HdPua$s~b0<-}idC<+eMd2Ho8D?QK96NU=0)w>82hUbV-;g4sagO>cDI
zMT)neX#n<1K)>Dq6eK@pfD$d}v17+-2KTC!E98Y27RvF*ABO`W+U2pQo>$AcOXJ)b
zTvRc4^7RHcle0JivaLggqHgg-bP%Ji+tk>k@5!Tf@2S<+FWqR^;1j=-!Qqse7#eaS
zK`b#snjWejq^GgO+=6~x7T&*XUZvM^uV2e&_Y1%gH}}z5H6YW-1V{1%i%0YP=`L+l
zG9Tvz)Ya~nT6E(&asE818oXZCZrJ8LZnPwcxD-P1Evq<-c&+w2Q%5x8k!C^DE@YeJ
zacFY1V8H?;&y~osr7r_k$D?<7qdfTVbFiQxoN0AqvD%S1&D}q+@QMS|T(9Zh9wg(0
z4`uW!pcBr?^r`l5G6!zFAU{n>AbnFkp+^_?qn;NBHV~2a?AZ;iuT;jMr!G%fq6XN-
z_IfxYHIGS8t}%*XQaJ9F8IcAWX3?5!$f4g?*Ey9CrvRH4Y%vkKsfy5~|1e}?_Q0h#
zWbk0XXN*px6bFCM%~zCHn#6pxtc&;Ogza{9Z}8INMGv5W?(NzA70RA@C4nR)fg+(5
zcx#+1te1?G{@_`z_xkI5OC0s<j2b(>;Em@s$aVgyXc_nZuy>00uykt3kRhtz4;wZN
zLa0LD@55OE8#e7mpL|Q0w5qA>Ysu#Q3ePh>Z86!?o}GQ25xg@aKS^JY&0mA6?v*c<
z71c5hykpCjO(;t%(?%ub<?u`*My*5hNJ^X;VCOeyXBbg*n0;L~Zrtm#&m!9u+4tH;
zaMw9Hw>GSOba5ZN#bsN3FW>tOjtL)L&VH^NHf)fGAAStK*UC=x<$mPhM{wFoo7B|o
zLn0Z35bQ+ud`+Y=g*BfTSk;duy{5MUTd1V$*|P^-#Qu&GxbkG_(j_ut<S;!=jIb(%
zo6oYxLofB)IIAJ%UL+^-MXx&cP<;T}Yl`1lQ0O(CTLxIBGRgxp$GAJ*cN)xf-hSP5
zbr-;g{mSB%GIrz$S@QA{*|KqyJoEJPvUu4_RDKjI@90FlRr_^eDOL-e`K3x+A8<GO
zE#?8tp4B`6ihhU_6rw}py0shR(Z`;W70Z{%jvYJY;fEf@QI~Bvl%omR+ZI0L`2lf5
zg>m;Q?sZ9mGCLq+UXi|wQS<TM13#!okDOiHxh*#48V33@x4N7hNw}CvP)rhI6OJl0
ziGT9RC*@?gWZLn0-Te>g_XQ9_$+Q(u6F3-fJ7CYyGBliLjrG&TeJTzSVWXFN)H5zX
zzhS!iHgDafCwAc=8g*%z1@5aWZG&@Rod;|!S#a%OJU62SPU|WQl=^GEXA=s!l47>`
z7#ifV^SREz;Z`4?(cii8ezpkaiE>9wJ3@{-_Bh$Tb+gp$+b74*J61~Jk$ZmeYIhI}
z6HHl#nBKEL)2dV1d;jL^%6CE!%RFBH_AKEgGK_9Vt@C7r08Tz>zIJ1L@r4(_M;6F_
z#GrTXeMosow{}U(t~w-ySpVjj4s-7_&W?le_aWXKIUfJ%fhg*+wEJ=r(Ak(r_GP7C
z5r3iaMo%5jH{!{9H{ih|8#iy>48i;qEa>%WEk5zY6KWyW?87mRX!qHnaVK}khPK1x
z$eA~Gpx2kWj)5LO7%xrnL#H*KcZ=BCV~;(qXIQUVy+R&){4q@u+rD!*&aExdT153~
z_aPtCKl?!7*+2`XsPX!<7yVgtf1Z0F1ZaQfla*Ez96BeZFFfu*&XLC(^01!OIGO3O
zCm)rSt5(X6o!jNfCmxek>o=pbG){SALK#n-i;AtKEO;R2HqdyQ&VLkxGH#hU&`{xw
zZ1xSWu9Jr!eN;BATO<4S?FJutRGLttS&uWc3sC0Tp*@t8d8EAt9wyOq?xUU;8)dUz
z7@ig;laqkXI{544f=mt`o{G}i+KPJLHfd~Zly)>0Xu)~0O-(IUV#OvL?27Lifh3lz
zXo#N!pR^P|hBQ!{;bK;d_=3qW*@G=T%Rq1~?8&WXP4}pE&2yXqBs*W1ns7YjQ71a^
z1UOLZKS<-`0ILHfXb#d!`}CNo`iLly#kYZyr{VE0jz=JTrzVLhKj@KW&;w6=YerL!
z=9VVVN~`jblByy*4GMIUdQ@$$!078d6FN;F5iQ4w2K0=_>7F1Y*4o~x`8;(E`=zY|
zumPOv8*rp1)OzKuNHDcdkvTrB50}4|f;gJjkzu-|I$ghcAyq(YK-y7&9(~Aji<$V~
zF5)p@mg~d%))=Kk0f3_*Z6}W8`ii<IDv=^GF)ZbICQcJ6a0ak$5LCMyjnh^xzx)ze
zwtNya;T7`cH@_K()g`yxevh=^OxMC<oIMSfmLJ29V<V(5j7giRuJ#x?A{oKs4O{=D
zK7g`U&<Eq`dC=}@+PFkic^NzAFnQ~>SD~#~JK}1Ea^;n8((#&ax&=(BQOfa|Ll&(j
zNkr?THDmvb#Qx@JONO(Il3K<k=B^Wr$_{kx*K`m2f|MzcG+b~HOnqK&&+o@3_IKJj
zLOY|a6ofT{lZ8^zEWI<C(oo#BM{JS5SBLOnEzPRV{t7=g%rK+xO>;B{58%D+P})0@
z+;sB%6Xl}wF4T6O)KM?G_)?iXZG$}a%!|rfy7b_8gviK4BNiUOFa(p-mY}*{%2UE~
zir&RkWj;4Nx9)*qhjY4Mv3Pds78(^8f3>4AEsJ~B%$aiKWtYgfu_I(7`X*d+^|eyl
z(2V0JZ$+g{3ob9Q+}pIa#o6~WxFW<{6Z0j^67aJ5M(uPo?u6GD2e-nrjYMz93d3V*
zTPMts-WXO2k&L>)Kvh6@L+fK!9c%R}D=B~!kE8$xnisSdyPN!)VhHFA@Qk$n;-_(@
zkLonnFyh3ecg8zxkJ#y|TZ$1F>27b6O`A5sP4zSq8dk}+?OWuLM;?(T^wMo;XpoV^
zhl3cc!K4Xj!i4T_H?@e}3u}^Tc#(Qvsv;3FUK-KG=5X1OJa9291908|#-HhG0X`I=
z6H;w$z5MNO4@e2JxtA?@MMjPs4cAl;l0J6GnaE<L0%OVw-FbE}eQzw&pS6`>wgF_b
zOxX8R&y{47hfS<GF6Kl{i}yyiR?WBwFULbFOzO3nglF=WJBFQu)~C^~@bgu3kN5H|
zWs`8(N!mn*J%S@@U(%nFME;pLq00vLn31T|NZjC6qqv#9wqu!Jy^yr+wF4kwSzJ^s
z)yUd@`MGCh(U_64c+pbXxM{0AyYNL>^2!Q$l}cprph41x9I+nssqg0b=b`7@vmDp<
zQ_=;|s&b4bRWn!K<1P-AztDPu{WXD?w85!kMUHJB28Zk5Pfct~+Cp|OOyASQ9uQ98
ztvD#773V!KS@^0v{`51l0>^Rg*s)6<dgx)PYoy1r1@IXnEjR{R6%w`?_OGao$iz2;
zbtEW<`=q=qT>I&+OYKOV)aft;6WwcnPsCRBN;y%mCH*OE-JO^lSg20103Vi>l}J@Z
zv9vUmnSiGD^4ts0N+XKwTbiNCz#qe&%IzIJNQ~l*7(nH+(}J@B$Sop`h#gYtf<p)t
zE#b01#Pa~X(oB5kCJ5oKhk?gshu2+UfJ2xR!D~>5<Ii|1&9tdgqz&$u!PSG%9q4da
zj-7}vt(WIOfb6^5sVA=Z#qf9N=*!UN>%1a}A#hWL<`lj(z)eq_{!86eH(-+Hnr@v$
zDh&#v1hS=F<M%|tnB32}5XZnZHP%T7+;&G#KT?&tjjyheNs}fjQ7wFNkt}-g1vF(S
zHy?}Z!)=FUq*6r0ri9m+O<XwU71Ut%%Dgf>D`Ibw1Y&mdOVDLHkLs0XjXYx9l;M(C
z_hy+vAYgLTZ^D8tRmcT&sA!r#aFlB=u72qiMzzO0o<=d+NSK*IlFTpM-=v9@addxD
z={N<Rz6P3u79gy%W%GJXpge5cIFxCQLn+Z_bQBv0uTqOV_3R6>82lAnMj5dQ<3yIW
zk##h@Jd9J((T$?BG9@=z$x0##?_F?s7YnuBd=f&$ct@ChgyEEmZoHP(Ab%IY_}RC6
zi&R!s%2ae|tlwWFRh8AsTkBy#FIl=m7B75Gy7C=-a!8^}Lvt0x2_!K1d7jyeWKLa-
zF5JdadJ6z*Z+hjU$(v(S4C7^lOwjS+nPq>8veFVMMF?@vo?RxOKlH&5$bI+Shq8dD
z-8i@!3uR-9Cd6a)&;*AHS?E5?*OBT(pN9-1bwZ;xxMmVQ{=0<cX9Ul4NcZpEE0<h+
zA?g>$z+$cg5)DH0fyr6|@c(}HbA?Z7d8MA`+NBNM`5bOPg_&uKfvon9hLG$I7E17j
zHZ77t@cS&xGm2>Y49s3`<a2mTUPJ9ZnKNgOOgmx<>J__CE-_jrOqi&5HsP><U;g}m
z^>iApr`w-2qmwjY@3rw>y}!C<JAo(+f~3Da?f7d_7`EQm8xzlPpJ~uB1gD3U)5>!&
zUNb^DV+`Koat6{#;YT@dzY4q<7Ib(T;k`(LmQxxt#c@;b%Skr~PFG7TG3x#tb}wgG
z1>24{8Vck=GK3x0y}xF!eDs6wmQkZdDgPKc6gAPP^DTsM`o+(FA&Z}1C<W*!#wHwA
z44pF5C?rxOj<X^Pl6cUJo9hudT1=(O!z59LmM69QcF9$5z8voDv9f2^E*Umt7?gXo
zREEa#gYW-HUVdqj6roO<#*eBS@s<;@hhC)#e--sv4%;8T{Qxmto`T5Sog&~%bybC(
z>;-|X0{W`AT%|uzuU7TTxVW(*V-5@J?b7fDL@l~k4jm?y5W%X#lM{<|f&;#O^r);u
z<M#jkfB#SZ@Q0ga+tw|zapOk$!%a6y1CpYqA9Vx}={ukUx~P07F{idT;)n|xU3xYI
zbR030py3cno-NXRXv{bQDw7lpdxOjugJcCLB~8t(@;fxS|JAR4jlWU%iPnAX9c@Zf
zrNu>Z^UXIR6CRCRaIJag5>nEl5$^9O4N@26;1ZMB=*~weV}7hKoO8jk-tG%;a%de%
zFmpUOX^%1~5z37mXd)2EMR5||&J28AL7R$Gy&+^s;(A>&6G{4^BL!mWGu%bNRyy)b
z9osFtPy8ei=84OTq5zSN0F(Jj>XQ=5TBMD9S+j1v{ORVKptyF(i!UyeHEYo7^R~ap
z+O_NDsyAIOZ+g?4wHm}q5Pf_%F>0jX)G5Z{D$#2hXay$jcwTArg0=vP%q}#3`t5Ii
zB{zYeZpOI=>)?_6^G$z}y*2yMac#c5`v7S`mcPC4l6JUhb#MDAPt&j>4hZ9-(t)~;
z{1QY=0bPWQcK^zn#a&vG^^yZM<%2#hHJ77~I#MpX>{7I%TPmwiE^+ZC7a?1@1w{9<
zx*q<SU)`m}GI`PjIq9Sm)uJvfEtD&+xKcd_ciedo`so%)2?X^UuQwp@&jx{N<nA1M
z?6Gpuh3CV=hPq#5EMIi-WwLVRawz_FdRiWT{#jqumE|&X<_x*$f(uat{Spq>*(8@<
zda2ax-wzk}QpE8K^yiING6YomK7h_pH{bjRSU)A&D^|4_{8+oOkkvy=S|z;=lF3!c
z@A`91Z)0al)D6!o&L-;;R9kcISG;dUylC3AX|i?eT-l8S#p~<qktnuZV=4Fl?S8rQ
zj=SOOMHZ&EndHed3A4-&QXkmYYp3`HtwyXZA>H_NaU)S~!uWA=<dH`x1KJ1ecRS$2
zcpMuK+<o_bIBv2+p+cb@KAXniO*5ar9h@S)B)Py50~{h2w5}+V391O~)*NL@=88K5
z4##+S8+T`N!P~fF#<L{jt)stJC7cg7dsc5Wp`7Z}(@s-*sHv$z`C&5>p|(o{c*qU^
zcZ1w;!;KKo@Gd!ojpygf1(K-<*xyz5{eH3xFGtMXEjYodL5@5ASmmeWtqll?Z3lds
zVEo*2+bweI9k*yLxyqd=Pf~a~!3M;~p17-t8v=+sUYzTE#ydkMY+~blEXqSwK!4{u
z-<4~xyG~1tT3g$#*K{gCl*iCTlPl8nHbrCpX$(7zYmrPmh1of#pKJY`^~5!VU=mba
zT|ExSctKXISfNQCP0dZRX7yU_AU1mR7!crDTCdlsHE9Vrm?tV;c}JWL3ttmFB~_^P
z2BRo}kV!y9j+02lv7wL%1NgKyH*2EY(pO&5godqKx5CS?O1mVnhxxz$>m^czBs-1I
zxp4_wPfzi1$1Sv1A@29zYl<oO(BJj<1^-g{V<x=)ClJtK@MpvK_$+oH`A)W3#rU3h
zjZh9>h2ROBH*Zn5_UhGZKo{Fk?NA5av0B!nb@0qtvvH`*Nm`DTJ+>7|{aGdyABr(n
z*6&MFW6%tb?cKLmmLep!a^*_dxcOBL8?FHFsBfr8hq0-0_St8nHX3Q%jO$0v;9#xs
zwZJpW;?DQ+EO6Xn;MDHDXfI7zl$Djssi&N#mJxcoYb_dkPUy?Y&&U{8zqj(h4bU5Z
z=XaW`5qdlUv3p;=bVAr%e%Zyc4l$)AOBSOJ`YoEs@YlQVl{3ybMQ`#&0I8u86ZbKU
z#1wfFB|CFrat8{EVdIqWX+R9R74?i)pq7y@9zS`}MfSeEy+;<DatZ{sWnzYtJi_A~
zsJXr|?i&y|SP<}h!}Af+#;P?NW%Q^K5Hx3jF3@ohO8xn8=Wc-#`^xf_a>^+S(33mS
zW%?h<*`3O3ef@{0dy0~6JN8I1l=q7-yg*)AF<I8GTPK%YaVg^RopR@0_X0jADSTq_
ziV)*X)ptD(Wa9r}zS`S02NIW*--nq#9g88mgo%X30OGEF2#xUCZfGs7=$eH_H?SIc
zT%a{3p__sUKy+a;5!Wi2LgfK|P;bbDpcUW6Z3#tu^{LN<yDw)KH{H}!KHQoZoM)2Q
zM$|zsTd@+yO}-*~_U(}uknqt8m~7v^6Y-K(t?liE8^WwX4`s{ZW<7Q9?pud}e)r>g
z2NXE&rm%w7Uo4DzzEVh-1yS0f4w_xo(1>Ik>KC7R?s>qj2iC%BS+;DMPHyYA9a39|
z&SEV%%?h_`zu}-%Av|6-5^-?tO~V=}Dm)b6p9JryjSd6Cv9Fw5+^H&KHu(3Bob);+
zXxjkj!#f)K$>{QlVx^w;lgH5+x`AwLP+N#O#OE#PVK^H*ncw8Xe@OD-?qTGI6g>Ou
z8`PULal&{UBC`ywK6j!O?iyM4%5qJ9s%dJIX7E@Z$m0t@dQSkgN#>R$nh<Z{Jqhno
zI&4#6ZLmp(f8uXHmhszY0`iGo{7u<WTvDXvRO{Dmkmca5gwHON5WTcy5qNGR62)p{
zKRSxFwOhKP7B+>@Uf+ggi~GZuKc%iU6({4Y--mNez9s6r`vS+T&*%F5bKKI@8-vf7
zaL6RF9^`(t!h>r9+IRn<neG10g9+W)iB^}em>6U6?wkSjaA$C4coxx@-*MgC%1pef
z$CP#m*ACS7^1uhS_hjdv4!B&{J*&C7T~ppW(D0qsA+7A>GsPi{=;Bt*?zM1{^aWB`
z?ny}r?}UIR0d;}du(q=ZS?}#=?9z%DQV-(zUC@Nt8Z{p=`gXu7%#P!hfCMx8M}c83
z+mcHhIxc*288gOQ;|>>hdL{^BJUA?=VqShgFY^Y8dq@w;Fk8{WvJL!!9kV)7+0cO;
z4blTY?*!9mLpQ>1G+$^(>8fV;#94Q2;2g-+Mp*`l=Oyj6(+`vlx&@N2(x_<#Y&yXs
zT5&QUbA7ttVQ59qjn)==<p3vquUYPpMRAw?TEvSF6r@c-K+G9@HlHUBnWka_nqGek
zOjEveJK4h<%nH(ib7yTH0GT?lYmS5Xs<rqIV9p;4&7}pzG<N)9GXJ>aWGK!$e)5S&
z)%8yWW)Etlsj%b~6zhpr{LHjW_k%M`g{}M!c>u)(cK}Cw!#>*`@TLq#x3F{0JVQTY
z<C1yv=Ii@4C@1O0dD%T^P@?!k$n+U!Vs2v0rMxaK%W26mFOGRxT=>KuF7}1FP)iPj
z#$8ZfuX9sj%ur8Zg3?NzefrTeWd_<=?%A_b>d-S__N<voFHfM=CtH8A_iZ8DCdXY$
z-0S+fj-2kxFqzbkN%N$AEk&hOXe^Pg?1_`6;Iywf=#o_`FE4sg7M!#Ig1Jk!@48Jr
zwOu%GK0h`8sh2tC+BZF?<sR&d(P571|1g16B5Rft;1{EY>X5>c0R&sBrJE-uh^fAc
z^#8}7cv4>7^eS9dYvh549)MPi)2z_qvIyU^ttG8Ut)&PjiVawS_y8_(z=pDH{*vNS
zbw}O*&?D$5)*|=adoSW`)kthFQrCAOTKci8m^N&QWg-mN1m76w4G0`m2!w@00eC?%
z&Pspbxur6wx<a0PZlOH;{0n+q?S{=;p|_Xftn?zao=tr9y<PG_U1Z9``eL!Fo168$
z=#Q}B)s6DxQ%}p1#fxR};-&Hs+9)?Px8d-NMtI(eBp)$WGZp_qypVm`tYmo`LqPZG
zDX+Vmy3k|0x@wS|d+zzNd)E%R`A@eZlY6K9&rg3L*I$3VoN@NKaBW-TcWuPsR``#q
zzNBto7Zei`+1Y2EtG#r8`qLk4-`Ex3{I*>Gk&nqa=U<59CQJ0_Nq^W%F0Rhk9m2dZ
z;eTofBpQ_<0~glc*s<f}l+(^c5C1jt*Sqe6KrWR3`u6waLm&O9Or3T#+}&_-ySQV_
zRH%N#w=V*<-w$;Igr7~<_K;!2<n%MoMF0Lpa^p>ZkSetO{MLVcSFZoWXXKo7&$Gjs
zAk6=flIQvl%YV}2CJk^dU=l(o_SBs{>uCAZZ*GuD6Q;;rx8El3e9s5vuD?AZ-~RU3
z;O1`9+st*7Zh`lILk{f`xa6r*C(D0-^IPctbFzH@yWf!aU;k<O(_e0t8*cnHlIYOK
z9oBPK;NJRY)`So3y?kSK0|NmHA_^c@G|ZTJjC}cvUqM&Kx5}qK`60RL+IPtvf4yIR
z^y9P9Gk~WxnRR#|l=|0F7-xf|Cejs`$l>TQ@#QamQLef6t@5c)TrY3?*Z0Z&4?HN}
zJ?|{pySEv_8Sek!D57kmzSiF#h+Rxy(?6{R9VKHKS8i(N*`!6XZ`W?w3=6uUzF9hY
z_P~YPfD)oIw6;VdRGJI-;B3}wjgovm-Tg-%HC<jpz4+r#E|it4*CDoaxNP3KSDTb*
zbf1UQYt!L3UT;9)9}@yT#_DT+8H;9H<moeJ$)cB+%A-##M2Xc78F|<w*|EC`U9t)_
zzlYTi8UjiY(}%KvP3&MgpUV`<3i?|)M$6v)Ey!s)>gZXr@P$P<)oP)vTfb4}FBmV|
zch*Tc4%z8Kq8Q`)rotTR%KgFN`Tw*6S~WGr0}p6J4A%L6`m>*t4}IYM^81_qh=i~r
zxM4nx8tMHq9G91&-DMAw85l=07p}YipTM6>__QOb<NY7}kbGv{r*Oc^gNWN#$ooI^
z5ya>l^{7c^ceDKB;Gpk6Ci8z|Rfj$V!ZBz)?GJe=#l?B@$xnS$KK{{9%H8+gFOw!u
zk@vm-1G0P1UKurF1deN^<IVa_zjgvSt`j+)FwV4&<bLS}p8_P<UjMO=%fEl-({k^<
z56GBt<K^w|cqgpq{W5A~5sv&VLJ1n;^x6QXZye-c!PS(k<X69v)*wsl+$<}>vLBbl
zeW1x9u~~<*R%BWmt?06{GQ^{+m5?fN<YYxfC9LOiDbX%jC?WC!Nb6A@BE?S4JkZcS
zP~#IeEVIIT0i)8AQYl75hC;Zm=+Yhy22=uNrU#karnV@?#m`thP}6>6+&3W5PYA?g
z`b>uEmbTUoDDkDrE7(<!?(d;Phv}(Sqz&tp5LZa{bK()V$6HHuj%R=JV9k*3k#=;d
zEJb51o(fn9fy~VIVZ%qDya+9n?M&m>P<hD#-mZ&W_>Q!)@EnFyDdIBT!?zu93)*V~
z%Crxm%-)~?-9tlNPdrVe2<`dSOHJK=sUB2~W8`YIckGNAM}xRJL1bMx{}tlL)sDLs
z3r^$v$8qa2UBlMq%E(+}7oP3Pn($V*`k5TljymWfoROW6R-iqoBd2?tXGI5f^EyUQ
zaGnFozH#Xr5IFb{h%3O-XGZ>k;{l84g=^J%Xx2e9_F6>6l|3e)#52!@eH30BUT8h_
zUz?YC4cOGB87+f5U@3RN8%Ovs3*OF+XNeKZULD(cZ6@01rv}Yk`e^+}J@|kN=-1Yr
z(+jLq(y)m<6h4IQ7r*oc88LjAyyt!IMx6B-`Q^|47unqZqr}zT+2$(Mh(sQfUMr;U
zGcIMnF-e=V!Utw&cS897@CV;V*RWdj-hQV%i+IwVx85or`N)R>Iy5D4=eZv8A*AdO
zc;kxKAq4s^U|rNRrkR*3=-8vby}en!`<?GdS$V0Pcfon`)vy1T+=EiYe|g8hNGF7~
zatm$Zb8sx^bXbsz<2^gJuQMjR3ZcYz00!Uv?sws7D@NPo)8*NxpOuFmd{C~r?yb^=
zW+gNUbk6A^`q-G*pZ(ADkSL`lB8@<MMGW-w2Sh-J!>_)12eqQo(lTh21&BS^(laGK
z`;L%FOx?@8)Ow~c=484?ALhUvb&XTf!k1}N4gBzQ%`bfZv+|Rl{6xO>jjv+Po$~g#
zz7?^NPN^DHDg|(ThhLG19M%B)GDkk(K(5~}APPoq?!KF(&V$M=NgK4yI9fw}ogOPW
z9bN_guHC;+sw#_NNt+T3US(}z-F*SPQuUeM_BI<yh82j^akA}yZ|nEp^#*?*B8zh2
zySW6n$JO03+!wgMLMR=!Fj9w4inN6AJPeZ5C3;-bDMTQ2QoBj_z|@qBs0a^w)&wv8
zK4r3LZoO=@?f2YWmvP%u)}XhAKI^sBr<-Fic9No+87ax*dV0#xy0S)w4;v*jj-C!W
z=#hFfEUBtMcc@CV!1Yc1Q{XTl=o`XCB{TjVny!a+Y{8q2{z6EU+KyD&m)|4uRlFyB
z^7G2128U*h96nrTA(<`@22su4JyKB$&q6sYY2Je$c)k04Qeptw-grxYc&mde=cum`
zK<V{nLz;FZ3-Yu-hCFy$Vvn}*%)$srt9nVI^)>&>Q9zrkl0w**3*=*_`J4okANVzZ
zURhBlElo|ba>a7lv1=FF+#&W73j7Bde!$pFXP3mqkG@=Iph`ZG%0rvq4Tfu*Zrktu
z*Ei*gx4Z*gf%eNCcie$k(qL$RaPiVgWalvN{&hRWCLMiEZs^N84%9tiBoE^i_nc=y
zA2WNl{P2fAly_cxwXEB`4d+9jB!BwjUm&C__0%i6|9zM(fxo%1h7dQ8A~Z+z2WtJ<
z#|0$vojVQyVk^UNvZ2Ax{%>U?*<SvDIp0GFovEyz&*eLiD-=kVc4%V^ld()PK2JS#
z5MmB_oqC@s$($2H4@`Y@2`%hQ#9C87S33?A^|>lZ`8hRdH*eB7-qJ0b&qv~S7jRxX
z#W_hHW;y(bW7`RF)|0!ych)1*b@%dqo4d<XNFBt3D(&-h+RALLa4l}22u7Nd^6Mdz
zG9Tq(;j!_)q%2?N95-Kn{mWm=Dx8S7d*@!MuC9_l{NXQBiSv+o9JKnP*cLeGWN7oW
zBYquANuW>KI&{sEYg2$GUc4+c$E1W-Z$x|4O#PdqL|x;b8+yJzA|#B1?F)V84Y0D3
ze3?7<So!s@e<SPGtdT8f;&S#`XUm^&{xjfHp`k;1>4JUbdQ#_TL}fpj1g*a&3XZ+N
zHW;(Fv32`M7|c1~Jbc?$d<O4GSy_opo;VT5@{ZBI>y0>Is1q_W5A8esS!SBeuYe*w
zk@hW|Xf$C<^GZsN0y=~M4n8a}SJ?|@QCtQ$1}6D`zx$K??cN6wyWJxNw4xDbQ1jnV
zF~CAjO^=-jwS)_vkcq&e2s&3HBrOnVA&d@s$0AXI?y8FNL2}9^?~}dFdGhlc?*OpD
z3>BEl0@a<H+!2VR$Cjv$Ib=c}zpma8r8fi{i1i0l<lcl~9Y)UZJRCyt%+g|X3>$U$
zv9cA~@2IJB<?csc&^;x5tW3iGCB0PA$8oO_OR0JGHc9&~pBzZh$pIy{ndH}<a$idS
zaa(f4HTs-{Ib@NJ#Kwf%*z{27d7KFEdD0&H`dGs&5^%RttMzv`iedXdqanS9zsVfJ
za3b7P2%B&<9Jljj{ZcrFzsJU5g9v^P{N~x{dLsp@DX_Y090%*5yyYhfcYVIWQ9UKR
z$7ZF9LLSa0%I{`rk-5*P1o$y^HGz;y$B8t-tDude=(v4Ng00`{(06fZQ<*WBl;Bx@
z!BO3=$QyX<>gcJ*$}Z%t3?4UK?)dvNnzKRvVdB{ln8GeG5#v8`i958G*U4KuIKz@l
zM;|d)w$$vCp%adlzdroDmSmFW5?i&IOR9S&a*bhF4HOVkcvgmC4R@W1ssfs_0UQDS
z#oN(gu^3+0(PKx+zx>N}a@JX=;4Ey!++91^0+$2e>%EPxNe_;eIIa`?q=TFUw4Gi;
zj*(ah0ZRqF7@9*3+&Q27_b<wd)mvryoRj3lV@^SLDU>CtDsI|2vl^LPq{(Akl*+RM
z0qov3jSR<Wu@RRs(TRsYFw2lVVpa6QqGs}w#;Um#)npy_^bAm;bFkMkP{^5m94#jS
zTnYdSV>mcK1F<9Se-S(jgd5?N&m_9Yct%VC9g`V*q|QF`fxm*!_DLbeYaMMQy(e;0
z@P%-~^ZGE)_cRcYm8UTioQ7V03=^Ox<igMN1a2@^IU9WM2Ig}DtD8f5MTiK^dD^(t
z-q{n_PN$;93>Pgu1#aA=x#%4p>uo-?k_`+L=1xG9`RdecE(LlCm{VlZQbKk1ur-C)
zuhD)V2ue#u+a%BjGl+WQc|o2gnsxz*onY81c0mse4-rlj*0i1nI$0~qn=sJN=<j$Q
zw#?Y3RoBjgn0VS16n=UoX~eM~ckJg-p&ZCpn1*{9m$YBt`#h-U14=LU)}KVx+T17`
zUtK33|Mzdnb#FdTKJkf<;#-#HI<Ff|Z$)0i;6TwO9eEz$e&-~hO*kjdTpLmVP-PVb
z^7*g+uROnKxm^8@_e*y{1x|8-%Z(3$L}PglPl{rhTQ@awcL0aY<3NyF?>k54Mf*Mc
zbZT!DJY8_fQ`jJopbU*#P9FNiYMW15h}tvOBS&Hd#;_0mS_TqFdmGD|GZe$a3U=AX
zOjPK8aHH~gQs^$Kc;(|{pTPX};LzV>u+Hl2)q<fEv1C1cd4vu9ZNew>B^ho@!?cK@
zgXQ-&MP<4wc&wJ*dkn&ss%gk(ZAN2+7s4jUc$MN>a4?Nox85sbrF|q|3Q$@b_Pqhf
zS!S4%J=YFoaO9r=Aud&2*@HH)?rBx4{i1+XrJ08o(1Pa-beaA+Je|lC4<Cm!N4uYo
zo_(it;2u%1o8#Wc*7&!#7@!8IrEaezI3;a>jhFs90JP?$ND^+OJ|+Tjw7o681Ymdt
z<i!dFmSvhtzZ)6LJR#6r+hNZ~I*RMv?wN_>4jqjAvy-l|=Y_s9#X!AT>9Ea&_u*w`
zyf5`3_UPUpLR81#>TLy_n$hftIZEB&9ptx-Eygz(Ce6<)GMNz!X@7*N$mVIZ!G$Kd
z*xkLE=r?M*$<ueGUMWjTzD6a2TE3isS19O7F2+JjDhA2S6Hb-kX#e_)U;j#`9d(pk
zars3El{RQ-)ZF-~YmCO_+yr#Uat?;WXBAat^4Gf`l7}96R4#e*HNr~RR%A39v!QUd
zl=@EeyH@r<xGM3JZ#za50(3Hh+Cp;iV)FXbxJdYKd(Y=4yUhyCSFeds{NB6o13BXm
zjEPXmh3a;nGF11V-ku*IpWCEd))vQ$n{EAldA^S6g%Q9;ZP9mAqTprRS>eaCvQ?1l
z#UbIq#ik&?U%w{?{X6wOxBp4kD7XWT9>64o<EiK#c})sqN%E`(3^E!2)M~dWn$RNi
zaqPpGkhlIUW@>^j`Q<H6Z?W1n@GPltG;wEw-Gp7Yp6~<Dg(4m^@t`Cr@wB^v8D^rg
zRAh>8fKdG2$Axur4(DxuOwi&-y{|?ODv<e|GEieaY9!!0y^Kp%;S7(7w|?EdoCE2(
z+c6-1?V@W=SeTGjWy8}+*a(VZ{z_UQL@`pcSHkpge}~|lNeVd>(<`H{@tftJ!}+FK
z`5vzWTDOZ;8PV7z1(5MQx-`vKXClUwF^<VW>|v>AFLPa9AO#@yOAaAZFnw-gLL&=k
zBOUWn5HaUJorB)ZA^iL>I2FX<YZQitW27H?UG=@X6<|T5xe+aC?~S!|B}Zgw)Z-_u
zNSXZ7`;t*1b&E4?djc(-2g<|S{Z1Xn!Zr4?ZG?9b7qy`Lv?mWo?lv~a@WT$1^Dezo
ze)NO?ky$fm$zg|$(z4X9JSc0Lq+|5w={$8ih<CXOXq!%GU?X%+_0PB7CX<giN~#Bs
zl6su+NunyG<&58LI5(JwEhHZ$M$OV$1sqiwUE<|w(tnovx6Z^tE%llNuzR^i0fR#M
z0KilhxH?Y6;zfR|7{^mhjo%@b;P%7KSE<8Io=h?YLHaPq-qsceMzPj!yJ+iAnPUKy
z@Wb4DG8~N)sUUXuf}wb3t$M9$?!=8S4<s>~6_k;`Drymyrkm<IGB5)#BvY?RrCI;H
z)Ny(pJ3L3--jM6bW~J5=UHJhJ=#hcoDu5-x14Go4Kz^<6EEiXDJVo)Ij2bX(X=#&k
zgog?tfX#BCM<O4zgFoO7wZtm}bXPl0{mDbNtDYLhX%H7tR}1$=dq=aBl?+zKuL9Kp
zkW7Of4z7XorH$Q#4^=qhIcn#FVdNKJKQT@l&Oa|KV$Mhjo)3%9(*pOM-ZBL+_n2!k
z81VUp$bjPczNDF=k_r{|2zWSJA+As>H@dRPQH`hT+-NZE<q<%?;2$9d5yhBO2N;NJ
zq8N*Njst`H%XlI`Bi<uVQWX^@g@xyC`72a-Ji*!TV5(sQ$Sb*lCfb{*aWoayFr5Ju
zroaS<Qpf6T>;MRMyJvpEzJym0-n8(2#t(SbvAN>yhd4x>B1{M~jg={lxO;UyDbEiU
zVbHcYMO|Z`Mfng?KTH1G?`1Mf!q+Ho!`F(<p=sFMS#H;<AwSl_PdRd?yt3qF7_fKC
zXVIU1KLj+d@tI5+o%D|H<RqZIrl77~hmJ+4t=WxC?Oi*z%aj@Oai%hvNwLMpK;Yf5
zntM7?YNep!Q^WBkvp78{l4vr7`eE9ObB!m9-tY5vPY7)ta<~YZ`+^^O*Q`eb`yG&1
zKw$}Rr_M9Zya(!<c<WD)u7^O>^Ap^|uF}wpCkU?FtzGF(|4zU)Jf3Oz$z0PLdcpHO
z*9+C>q_U2%&%=-AKMT`Jruz~zNRV7_>(_CTr>#j<dh!m#Aqd-$x$q2ZEvX>kGD(5L
zkM3v)KJPi8JU50!pF@{st}Zxjo-BEJiL})>%8<cBWe?6&Pyr9&T#SKvcLxu0hv_l*
zn4_f$2`6i}?9<IFC`3|9d%lbuHC(10IY$;gyBxw23_t}jGPpS>{Fvj4xT&rmSN6yN
z4`6^bP#x+-?60gChsDe}RyJ<jCj0g^ND+<~RmB?Lt9?!LN4JsVz>kZ+yP#y`!vbOw
z%-rLTR!_>3Wv`<5bh)0BOg)8g;Qp&O4flg9*cj>~j~Pb{*K8#yGfd*I{d-kHluDdc
zMR<ASaq51QyDZzxldR(qGU{99<TgT>zI30$1R8osCapI~zIwv;zz#h(Ag-9#INo5i
zlo&_3DrhB=S9*St`mAJTkqvUWf3L|Up?OBEmDFXS8>gQ;#-o)?YIK68I$8BlC~f#X
zX2K*{vwA&Z?$+drMyug{m}7;es+N!aotuE>gbWi55Ag>D^v+#4pd4jYg9Z;lhZu5$
zVim}Y$8@!`c?GUVVn7;=kzu86Pwp`7(;cdv#mNj+{VwehUULcy8O?(IM}MUVs{j$g
zpQlP*!Xzk5ivb{KX@{?jY!;9*R9_XG7&A(`M0FG}mUbjm6lq)$0!*#X78OdRWu^Lk
z7jhNyQFfRQ+;2yBDKgR$oEuCb){1MZP*Yzuh(~mG%alo@<>b>&mY@IOLA{p(u$kGP
zu$c4E@4UUERZc!(j%?kwMP6LC7TLm85CXJ9Q6+(6J}WEmOj^nmei)CXjoS6Dq)hUP
z_?_iew6`^5&ah_C(TO<&dFY=mC;_3h&iL3FXUvwr-`_6#_S7L?qz$1d2x18D;$nCQ
z(4w)ECOPKTi8@bO+{G{xHU0{2TTuq90klplsjCZ}=Frrqm07K@`16a)X)^_ii@MIK
zyhL?;NZSx1SE2;We;tKpx$b40>%II7uBGrx)!LLRI{H^eXG}J6Fosh`0+|`94o6H!
zAC`Ef(x0(od->m9Sq_huBz)Z$sakBDYj|s>`;vG-Xiib{$p(0TkJmlaTNNHN3J}=_
z&HjCy407`Md}^8mg`ZZ~Tf$J1A}73Q!0%y0N6Ov}%h5p%T^FGccY;`grBH|S+o5A6
z=Mv;3pe-qcql6585Lz3EPy^rUHe;~gVoln+nNuNf)#}h+p&d3vkBh3=!JESso`|yC
zq8`^I!E3Wk05~!G*K930EIaO{@zCFVDakL-P@+bNxznjJzYLR(Ia=H$>vfTeKnjOu
zsD|gIlpvuc9~NXsOCyMIkeqYr8ES1l{?tMoy;&pE4#z29+iO6Wt#a6?F>qy<$>vQP
zL8JvTdFtWP+|n$|7Oj)~jvkqR%#m{Bgkdu4s7bP9$qE?(!F|s8XG=bW^WUF*S+;N9
zh2$fgiUfkc`0NF87!pt(fBGrev7<@a8eml~-+*ztWb)Y2$n|KGIkRTqgrIzR_^Fp<
zZ(Wm~Wj+>`_Sp+gk(xdGWaZk;(C~|7$KE<Ph|09VLJ{5I5WI!m2uZcp$?)N0<cteW
zgy1cdr=EFU)@`YkvdW>-3D@13C(V;76Gq633zz6w$9rpPW%H|hG&YUe2aM4nC!aV&
zjyz(#Jon-&vV7HMDJ-oHXh}2717YPUDvHC0xK}E!9S8(S!4@^-BKj_;BNY<@-Takb
zSi)T*xy>vleqvef*(fX|b;ANKqYyQPAb1hHDHe6woFhm#nLB5gW`_Hc#*a`cvaLAs
z{;>24D<Dd&9yi?Y3<^S0?RanZsX~>VUC<-sfvv`_KG)^l`0*k8I_W_JjUgt5_wa-v
ztG^f(FnoxM<~x_anW?GU%&~J4(1u`^@}S7)gsml}SZu4Hv<Ox-OEi!aM*G+`bYRRb
z$iz!3!x;EfhU_5r;LUFFnt(Qf(&f6j(}f@GWsvX@&NYlPi<sBMA<$Ip4>X8)NUT?d
zkTV`r;yo!|h`=3}JRu8jWQVsgwK$%Q46q9mwC<PTse#bPbEz|u^Qy|~7^%HiH<iCm
zzw!!40ytV~$0RAn;UTO>qk+xkmz)ACvR;b8%&)!jbh+cs`{c}%kC25gt(S$*zbt28
zd9qBHG**7}{a0l8;6ZZXIrHT4C!Upa&z>ju-Se;vMw5$5Sd^ox%Vb1#iM-{~)6roG
z@nt;rx;LFBf4-?kIvZ+a-t5V;YV&R!PEsHvE;~tn^V`44*x?m&{`n`$&;R#kJo99@
zya%I6#%`H3W~dCVI#GW2m;0m=&%FBb1yaz~D1(Yd$f+mIl9!inl-urkR9)FcaL46A
z0m$cp1xWB5URfe<d-Lh2Tjc=|E%KJj&yYLrdrH=>-ys*CyFlj6JzVx|-zt}%cRWfg
zE96(d`HL(#egYU$h1_=QYB~SHGtf<ItRCBX<;4roSD-{*ShNYxGM1xJNgobz`w*5V
zf!CHOrhDqF($Ka?m*d3XurbNbUuGkQ@HvvU5?)2SlnE_i!u6x^OEQ%Zy+sKc#l_J5
zQOnA*)FcWFUz<(Pg_oPU)-a!lDIimMOGd%k>m0qjN#;{&V<&H#eI0TcCvAQBc~M)H
z0Z-Iw=GvWL_WNm40v~E9hz2QgNEm8Tj~L~j<)YZO@_&hk`l+Z?2`<V}K>G#-bff9e
zbW<^=tc?t8!d*Pgh=j*E`m|3@+i91!resDPxT*#OiQFKOMC5>~dmXLMrK$_&!tlW4
z#&9iMoVWZv!MWca=6)LPF+P7I*(Gim5EYh6$OR`zf&`GzyuFgdIXPJqW&=rMyDyTS
zpYmB4B0BvPCgP2rWEu$P6nLa{h#Epc8!w8Z*i#eCIl%l3<k9=b!5YGEoCTya^#WV>
z(dHWt@wpt^#M<3-!sw*9gZsO1BTJr!j~*pQP9H13zu{R~zkZucn|`>|G<3)g1eB*A
zF-|rwds!xq9E!tN%4F2w!E(gm!=%2kR`%|Lm0DdSP3<l6!m8C$SUE(VM$?xIFFi?$
zDhJ8;fAJTXwdm`7))_Kl@Dv<<S|(d}*U7JLdQ654E0@oH_%b>C@F}q7djwr*VG*~<
zprK{5ZRbAu?TwGi_%Va!)9<}VCXXH>)8-s44UP43!*3qJX-g&Y$q!s0L#m3U0~)?E
z5Gd7!bU7EoJq;2*{q#9-ofpdg`{g~-*j6W3UU`9BeEtHt|F3t;f_YQr|899o)-78n
zr=L7UF23ws=|uS*^a^Rh%@Zb%lw*&dDmVP@Z?bybRypmAlci$F7_4O{ZEHPPB@fL^
zv?Qz>8R-t!lCZ<=U%<E`$TgaV<0*HsYi*T2lOG<)B~ROi!A^lsrNF4aqj(Qs;&SNp
z4*xzAAM^C7MDCsujx9T&hQCrS7B&%y#v$Sh^wltlMNc(xMJiM9<E7q5Ity!ExjZAZ
z#3Wu3@r*R?;ORSrT&eulhbxnY3pUxq*8O&j(X&P~SuJVIchNK9Y~_&j9wWG<c^7bu
z<1;3BTJj_ne3hB3(x6Cj=5IJopOXb`a}ImSY1T72#@c-{DW#KLkaQ}JNe8M%vgnHv
zSdlU_<|agKOwwoJaXd#zyU7dVlrK`|kV>!#?b=-X`bxVeG^Qh@)EHV?Of4)q{D7%g
zl)}jTQ?icDo$PInVZsmIdx{RNB~|7oFxM_}LQv~>BMj(NW@n&_;tJ`T6)Eqd_S7ZI
z*i;j12(Ld-NW#x1ai@%D*U^26PFaZk_H>rXx^+9{?t7k+%Pv1hHRTm+Hp!}2_sJ_O
zw#jAZPLpG1OqG3mx5%b_wK8-16d5;hm@Hbm1)e6r1lN;%+j*i7n);MN2#*~-NH(B_
zY6l3n7&#ty-}{)9w)M#QXHA2fdAGE86-zTRMd_(3h1<NTwn=(eXN!0@leM;PtC4mj
zYPNJ0AdcOJ_OyjEV#H8cvvwn{DMKA<59Yi}s$qF|BU_vKA=-cjv0}Qq*<5Jc__4Ba
z(+<Sh8LuvqmFsrM)QLl7+LZBdX}8JdoptDaFj%&1-7Wi@A>2z5pGLg89h*F1!Z?kw
z@7z@@gNBThXJ1@}Id@3~lnxCKFy2j`#29!4j3c%XI(<YPbd<gqg*)-k$<b{#i4=ow
zq81P)fB!y}{!;k{zmLWLoD@nKHw>QOeHh>l_NlVS+Zb7v;mAA06Wl{Gf;%;Im2qvM
zFM`P>Ruc%=NS^3sojOFskV&^^nsn+OxaDdpm=mgg+th3g6c*0cC5t*p1#WHSa8x9%
zr+~>zUZ1X9<|LrQ8|Dk7n9Ul*UbW>JR^US{kpvWH+xv4(F4Wkc=ft}=7fn6hhzIAY
zIP+FWM<9OKJs!{`-t->I8>oHDY^8@G7iWE$AnnPCHQx*=l|z6nUbJ3TEL$OS=1!OM
z&OZqPv{W8?<ar3+*)nVH90=BJva@cFoH2if!featrO3i&-7-r|U{%7BWw{cMD(pt6
zs0?EYT+Uq(rbiwzQS#Bufe9yU>_CH;$!T!3>;0M?&Ot4EP2KM-X`w>Y3D<RdCw^Mm
zr3$Akb#|~+3+J38#?8hVRIKyxyh0|Jbz)^0yc?f2wII0*C&zRlIjyG$C0s?YebKUa
ze*;b(!hNMhxCZX>B3Ss0bu;0N-2%Iz6trNjs<dND6y`&RRLQsrqoEY+*7!I((edox
zLd=b|)^T3ZNrDG{uj9<^U|tigyarOkDH-@hSrIX@RGRJY+@s^%(TqPn&86c+{Cjg)
zQ6J?~LYYrIOFvW1#;g#vhPA_({iwVoi89oy<&i#-&}aU8O(1zvxeI7&4NmiNiUD{6
z<v$7gHOtA)VOMg$^nf5o?$gNmj{eL$if_gpF9UfdOY<n^;XMm+GBrpK5xm{%c9UQ6
zL_mD-YJcr+xP}W+$K0`B4xc&|vDk}{{rs4$T)tC|J{qxTlq}Wa)UO@8>g3|n50?j?
zS}c1Tx@F>ZV`SyZ?fASFjSJ9FpQTKoorcCX88%|L9C6fSS^V-EIrse2<hWyw5;Sa+
zD=t1u9{SsJDr{+G>poBjLttu~uYw|2xyaULr9=U0m~ot+cC})EV<egN<dw^!#cSo#
zi%*ulJ0Td0x?t5GCNHhnrQs$`Zqkx0t_cY(n9s{gUzJNQJxk_q*(G)Ld*z(7j>kFa
z+hys>tup)gM#Q1#%PTLfk~0<@0bxzS3>E}oT~bsftJl0FXP$bToO$MaS%NtCITxG+
z#iLDDtVE(1EO<6Fp%OqpZhvqp?!EDM_8?suCl`a%l4@~!ArLjq2um+2<7wbw7DZjr
z6gTkC?)!dOtLb<WI#ns+>Szu7q-R?#Llmxgll^5OU?|_(+0S>?po~;G>2nk~2d7P`
zTs14)&n$NVodOe!zk@h=T8+zY(~XF?_P#^-0NojhL{az_wZ53vz=4>0e~>@+nh(Up
zLt_r~S*pEFw}0>gapfZg5+-U{$q3o7VZS{7+zOdHZyE>^F79=k<f&&@OGU*<d2z``
zjX`bSQ!fqe#d7~6ugJEoHIR!%(h9foQ!lKC5H65cx75p$l^bQoF;nHfdmo0ddtQz^
z{zxV4haX!cFE3k<CO~CU3qhU_mo>XdE?l%q_SUvYTXVa-uw)%RE0z_jHpuoJbyA4t
zCmo>2=NGM!=GHFRv2}+$@Zj@u)U=5>#HL<0Zr_I*P4<=ta=WDCPORs}C7Y!Y4aiol
z-z>!yOJw#jQ(zcRfp-9FTDTnZE|I(Ldq!p*J4<HInuzRe9177eTwQf5VIg-Fwdox1
zxO<_@KVh1jbIuUiy|-STd}fKJp0H+G`<+0MP(~G3dx|O4;-YA#{f~=-{lTA@5gcRi
zsr)u0V~x~S)0NdIp&u7${kTpYxN-M7_H+6!WbDoeOFiP*=^@R~otle8dFP7kbV$ae
zE!k8>wRQpwJu8Usnrv2q@0=iZcjDDY0c{UflN}Q&LF@{2r}dHrcsLs^_*8Ne)&ssX
zvA0mSAs0<F?p*th8?j1xGR~VDm}+5W0C6PLBP`5*EG4IXh`P96j4tNWjlc#D2Q9n<
z*Oe<RWI5r}3zy1s3z=wzPC^~s$nC0xkSvBE+#|1U+#p3|C^3R%dpCq+L4G;<^;SuJ
zbDP}rz#`Nt!}5i|{^M;=ODW>oCB>Bxl<VY$rRzaD4AvG%S=AtUV&O8)3N1zKx2LCF
z?tSoC+&4(uuHN_XGlDPV5tLQoBz7EqSdEkA+VT0L$jq*iv(GsdmhxU4eRw}C?@l>p
z*446af1}YUtZ+Vt*7}1_yofTe3MsA{2I0O=UVLdCtYVampys<9^B#%Pt257>CHMaw
zC0-l1%UNe0B~y<+0x{-pc^+1JPeGYf4ITl7W0$N&!;^fR7v6!yv0@~q(c;%KYIVoc
zVs{Cb1E|gS7oVc<k6`2nL(maSsW{%x=f<V=*oSY#<d=a9I3~@;yR7dtoe7Mw@?Y3o
z%S+Wj2%Gh+ElbsF&Crz#KY?}%ksqRAC$*l<1`l5DPc?K^LYqaM+i6x#(mU_Ej?K($
z)^?2^Jz7dIf#$|K8B#sex+Q5ZS|q^e*~y4G#e?_&TorfI;$D}c(hR^1a}!kYm_sCd
zBe5`tb@zF#QO^j~3HEv1>^Ej&u&Eipx!_~^m^}H32U74@NTfVN%`K^@K<=0w*;tCE
z9^EJ}WF}`Ggi-<A#;gw}0a8#)cNwyt+d+(I>52B7-T8QrYm3WF8>cI~2o^Atsi<7=
z00Fw4^GgQl`0M~i*I8ld5RRz#6ci59``BufF)uwg2h5<f3gfqy$tEP1U2yJn8GG1K
zQd*ubJ8JgA>Rzo)Rag?qKH%_ugNa}~^!sKXhT?L#&DmSK2Mt-!kfamO-rvw7O|5Nm
z-F25s{XTR*8(Jg}J-%2PVWpSgh*rAm+mKjRz?x@i(>as?2HHhTV{~5RSRyHVjHh=K
zOW&Q?Wq$*xh$VB-WZcUIf3jn3^cA^1V}R*8f_G#NUBy@-EyUQ$MfzI$<=Jo^<nSyr
z&m|7j)gNH7Ud1;%P)RdE^w>;#ldTC)DXJnGk$W;?_z;vDBB8U@`r{``cl@lPpW8<Z
z+6Gml8O^~*j~oGa+_Cb~E3e3D<0nCAvy%|m1QJdN2nBBJ&55zu?viNBI08}Qz&!qA
zGhP`}nT&1BS!r540ewLDQtC=$?qM{m=pO@#Puv5rk+Fs_LBkVUec2(sN18CHIM2cg
zds!l-skV&s_E3mIuv^&|3EFBN^bi5OkRPrB+qLty_Nw|q$FHCx8`De>gSJue9^V09
z^ne;AH<mDQ{8Dv^Z``t7Zv4}B8HG4EPnp}de-|u$x|}N^RNbK)E-p-l<28MDLCc5Y
z(aEvlChNpx?!NDN)L{>iN+g}_t=lhqaJFwr*+@N@o`*zmzMYr{`;l{Y3<c;hmmZy6
zshb@V5``BL3_2$6#U`#;dwlRNio);s6cb|jp(#g=8CTH7UU}s9Wte&F1x4hM#J)FT
z<|KoZk28scSQfNWozZz9pxHePrn9xUhB}S+g`k(N&PG|gW|@5GU00)ZZ-LaI+5+0N
zyN|Q*KhY4+NkFGB%Eg^Ap=+<YQtr9;14u&IE<?vmk@_Z3KYIv6D<?xJVCVRl$v;t3
zJ=7R<)KcPW`7zO78GC;)Gv0Heh?a~#^%Zv}QOK_=iPT`C6p)B{M-1Apm{tacA8(DW
znTaDaiz68=Sh)nha2BFUOZ&{^5)TQmEN3O|d>n0R{w%dF^(<x$NSR`*SNW}=0M#S;
zXdj#AuB93}x@qpt_ojc*l7_b(E^s7&!QyVjVH<U?*5X!{R3U?$*0SEsas3!pfNQ5N
z!3%)jS_XpouqCNxp5vg4U3>P+)(&_F%5g9N>bJYPI3BaPp?EltnRn*dAvsiJXf6AO
zBYX}I6p7gXc-tQjxevvwB3judrs?6)f2*P&>^4IJW+r7S`SZ-euOFKcTR}^IhRrT{
zj=qaUUuVP<t8_|A$DlSXWwuHS_77m|-@!wwW$APGLuj|kr5BwC4|Ag`uzDgLdu%G5
z50rooCX>EN%{ZWX&M~v(UGILU{N~0#%jxG|DI*S>B5mm9%ghjJ-IjTpxHqy6Itg0g
zZMKZKSg+V-Y^>2TT;%G%Q@)K#CW!l#NDVrNwInhU!vr1^W;#j2J8^vvYGicF-2(J|
zE<7WAvyL1spd*!<XbB$|lxf#R!Zrgw#j!BV-X&~!w4!wgqU)J%XX~<Or(LPbOV3>9
zdk8sLl5~6XBq!@o#`d@n(71+%aW@2KmnvoEwzeY*d5j_P&0N+=O>><3W}OM_j2y<s
zN&NY^wg{SfD-W#DN1+8Lx_ss5S89xmZgss58Ub{D-Dp2|J^oG;xSWV}jTG#pF1WkV
z$D6{vs07w`VLQYw8ZS_AV+^PSwr-_&J2zLu0eWsYL4zLQfdWAO7Ev4@vC}M8d2L>*
zBBeb#poI`&@c2YKYL%Be1&fMSn1&)pv+ENtr!++@I1_$G^T%{TimGymf@@T}m)_&^
z(TY~;+WWeP22u}GV@#1%90v(c{86pslYZ|M*U^Nh0K{BUSt-kxyd+B(KQI6FrBBG9
z%5rHz%U{iuR6<B_k=|gElLc)9S%#W#8$bdBnQKPs$3OZZG$W{#-~H}pbTk?zlhKQ~
z8V6{U!K`m*(|s}|0+7r=%R0EY^cH@);1oF%k39WV38Gg7QKC^B$5<L-dxfau<Y69~
zZXYz_=dROU@CU<rdx!^$qx=L~ktP5XFcAPu2MpJa(ezqS%DlsL7sgb-BO&@RhGvMT
z%g;p^Dl>2o^WDX`(iEV1m!h>{r4@#nS|&S@v2smp<PL_;by3c+=PVN)41~SJkX^|F
zYjl-xC~O?{s7F?pWJ!g-dzV9{DBhQ>D@4J~!7s2@Q!qT8k;KEE@OH&vBx+j*s768L
ziH;3~2rreoK{<yu+1LH?jRLrQJ2KLu&lIK<lis2=dNb=<Bh8L1?0yq}VQbneSvD5w
zt(2!~X}FC4!{^-%W)0JkPF&V%4@VaP(b+r_Na!GqkE}U^FA=H7xLs1Ds9SGyMPeH3
zu+_)FHor<5WHT;Chv!n6RH3ankuC}jhSw+>@uGG;Lhv|2p^$Lr80&f3<cr$u1w4g`
z{!9vD4vrJiwqDx{#TA#jtI*fKd2FZU9kjzEp?knn!?@eQGo$Ai1+%y|P1J}{YE$NY
zF}$-bi;jPhw^B0D?aL!c(Nu?KCTW6~koW45tVxWXik*c+yl01gmjZOS>joXQce7sr
za2`scVH0sW2Bl{5(nJ9$h81Emh5sV~+4D(5s5ZoT&rMQ;u+N&6%h21tL%#pbugE#4
zpDYb^wHD@~;ln*uxx*XHv+R#`)$o`q_$q00?ZxeZk&qrt*k-J`6^SEU+lSuw4!Pj$
z)8wY#-z4|kcR!Ay+=X7gZR++SvTFM?E#P)2pzgX<Y1A9k!`G%rah;xLl8G@CXH<w-
zIG>3zUFbKgT_ymawl-J*Iwvw7BM5^$AP$bCNpEB_WS$UYII+N<f?C)ProPgOg7w3e
zr%CwchY2>+<7347lnFaf_}?*b&n}_5<Vh-3q9x#^1g6Lj>q(D6#G24pg7K1KG@EE^
zZ3Jv^auOUL9mqV?^VGwpLd3ij%|LX8h;tIg%KR~O2kT<Jo0t8aNx30wBKFdHy)a6P
ziNcRKRGiz40w{-wJZUx#R<S)lsiYM~?KC`!T6e_!y}b7L$1!!jp)V5LCOZHEtx>s0
zf=qOLKVh#3M+~O|$J2nDR1Aigabo@1){JFaQLs&U5E-iWSGH@tSEIayAq5Cnl%n<E
zR6lLrqSqLWm=NO~<TKzmn#oSSL_wa1dU9UVjIY>JqDs5Ff#o}xg{;RkfMf_C#YB_r
z8}Iiz3gBj7`FJdi08{KCu+R&D)jdp@>IVN;Udi`*JuLvDW4J?{gBQFr-QdIY?6AhZ
zClBY0!#mZ|hGa`T4Sn~N*O+P-0|^xEV(e>7KqwjcYrUYQy3B;giei~Mb+Wwu%FE?V
zZ@v<4?jcfN+n@>t`JpLmCS$@g3i7nvcoy8su@`sL{K<eifr#|GGo!n%u2aTO950{w
z+^6M=E3c5<dv>Bpfo7w?<=rWb$O7eo)-KG3Sw=cjVuC95GAubDJRih&^x?FvDrC|v
ze`T56_UAuJMRk?D^&S5zLxzu*))v&4LbJ8gNgXjciK*Hv1X&@<WZJu$<o4VDB&%1f
zl=CmXOinrF44lym>w&IH3d&6KF-n(6ntlvK%Lo<To847N^dR87P@<DpXqIvT5{=lk
z>W<s~C@(F1R_32LUoO1lO%TxSKq@LO#u${x_*P(^$?{_iS&Rb^UO~U<dvCu@MvNUV
z*S`H7Qo<t=nR}q#7K5p2hat?&B!t4)+uJn}@CXzNKVO}C1abD0dD*GX$?PH0{n#Hf
zCc}RBD!W7X^akokS`K{}jmBYG4dI*OgQq=B3rk@?HgMderMOBB73V&``jLRC-XOL#
zcAf_&2Mxj@C(k_ju-tX$-7<aVY<ct5*Wr6hqBVQaymEAj(rZwF+INN*_?`)M1;`U<
ztJ^2H|M|C4Q(rHayyczfvwk>)8oJ4`HEL3$?$lLh%J1kibRutz;!qU61f>ZSRxzkw
zK}vaO5>7e%%`bi?n>MVIYyRb3GXLZ=q#l-}c86BjQ9<#Z1mcewJKYrG7^tkITwZ$i
zX}R^LU&&F&%$2vl`(rBFdeC97P;(?03d+v+!tBH^ELvd4gO}&FUZ`>%Tt+GQ=y05B
zH)YZUnK*GAWJZUsm$7EzwBdCxjK>>kp=tEN#htteeK4hd$OYQi*n}2<`8Yt}NE`q^
z(>!!$$*a4K-fjwYo{OsoPo%u!5@;lo@mj5S&5|fI1}-==w@99T>N&ab|DKT_{rLN`
zWy=<M;Gsw5dq4UgO@r^CKvAC`M>b1bU2wb~f{aS@eson@{KDgM+?-?3HZf1G!65=I
zIP;orm<)U=eVPN!v~|95Bn}A(fMAmicrF<0EP-P6jjw(~Mh>f%+wb_Z{N#UrAvHU<
z%EvzSL1}8XOygj0Nr>b+%5A+-+=GT3#qyIM?~rTWdbMoXv_<A&&u7k=jWdI>zp$RI
zz{nDyVrjhb=)}fK2}Jo&L0DMYnY_vH=?{+S^xSj9=o>Yrj~b^6)i5Nyz7yWX-i2_S
zz0QCVk+>IcykPH>_9udEXNb=PF47R6iZY<%%_b9)<Z^fV+@pn1)U#aJ3=1eLFP2;W
ze2eVgy<L9)yI;$_e|u0iuU#ph{le!Vpn0A)y;Y2MFz0}nh+;Ix{+W{ifyBInD$vl=
zk3A`y*Ud&bU5RGNUwhR>dcT&cIsqNEIt6Dg%Z^Q7*)Q}$#{{&wxQk%*Ha9iMe}3hQ
za^VGM$%!X?PJaEX8)f80m&(;|Iv)m2yD9yY9pUgIRTy^0W3m<AS5{QYtIJ=Ke|yir
z;NY2BIql^6G6sF#yE~h4EGk{*u(ab?&=Je%PeQMUxA8?g51n4fl49Ll7^>}vH#eGm
zV|Tw$o<(o_6y^iEq4=-g0@@0*-Eot2aWcIe@!3weXS%vt;rd1|U)8V7xYup;Ov11=
z{nZZvmfW4l##bc*nk#HzS+{D1Y+AooD$zKB{ft+vSdK1BTV%vA)Qcj<tZ@^k$yoL(
zy)x7i@fQvt=!XBd1Bc$T7xAX;yJXMq{Zd&~Zq}w+?|q|`ILS%9l1nO6^nxqM#v|;V
zE>A59Q{`T@wRFl$FFb>@f2-9BXlU3kOP9PX4fW{73>Q@ZfIxr0C%ht_m{QB-Y+vbe
zDn>V}I<=PDamMkko!ewe!xS9!01cP5@Oo-X!VQ+4?BiVFSZNx#sX3U2o)CC^pK_s6
znHxi`zbMw6JdXqc5t}V8o1_RNU2a!vjzegCdyE^&P07f>kM8aZ{<iDwQj=`4l?y+9
za3|**wmL)Og}8&`ooSnpNKi9ooOs#a{yvL;8-och<DY&Dynt5kOzK$4Fzpo+()OOj
z&O72-)=|oZ<4OK23~A^8hE^M(p5=Mu<3z5<9)3XTYWK)g941nN#xsvS`jEWuL+_Iz
zm1r2l<H5LxPC&D+oV=n3R<yc*b;`(bL5Qgf=W!RnBeiqeW~r^IlX5V9GI&3Sq`mj^
zP*C@c?_`8;X#FA7OSwF1?+`ad-TUqxTjc4-AC?ba{{cDbh{;m3caJQ3@dcccb`mUL
z3TW3KLqm!j$CPMR3XoSbw~~G6JK+`|iryMKcI}t#=!RE4csLs8;Cs~C=b-|kuj?jD
z3P6^+R!?e1diDxm6Ao+X_wXX)!qyh!huz4-VBB4kF?Ec@-t?Nw6R{cn7SQ431uv-W
zIp(?u60^7r5~OZ`U7^A>A{G>7RcAz`v@eVq8>o!&D#HLC)FKw}FaP=u*#o!x%{SkK
z0}Z<5BiCOqgNF{qXEituuu{*ohB$T`gZE@;0YjlOZ1Dp<{RcbH0S%YRh?cg|6%~J?
z$yfIIMmJ0pvr-_3A47O687PCGrdN#4Rlokf-^eFF@j<!q_c!8T1;FH^pMa3vEyISP
zOBIAHAxOeeR7@JrJSRNG$jS!-r~^KLBFhcv;&wNgFdINd5`jCKI1+k9BC9qT+(t8w
zk$XX={5^Ri6q7V@#S~F`ewZL=ifKY9@tFxG>TsRH*(DKmX}G|-0GR{=T+tk9jm6<+
zj-`K-!2Q^qUn1GhmtCnpg4ZbH_6o8ZB#Cf@#`_JANq0Io7q0N0Ho6kICQaDUIa&Fb
zCO6@Ig0DCL1sQ(acT@269)%Cbu;xUXI2Yl5PFF%X;dB>e6w{4LP>RN+^iQKm%bpP-
z$Rj>Vn~z^R*9urQw>HZ+|LdFbl`nikZoKh#@-h_MkALQq(pZnO8o;xJiYosR2Q;Og
zr<l<>>$Bwz1=NgDoI(aZ%HZhQ?qXtL2z8TSIDn*-%C@4tB@xWc2`Kx<7-b_$Y$r^d
zDBu3xcjfmt{zf)!TrU%*Ou#X!SD<0eb{T@hQ}jyWh{_06@9;l6-HFnfFktEmW6vG%
zP<C|@*GPY`(7|e$+^X*NKJt?kHkQ7yRM>|9b{;u((Yt-~Uu$zB2m{@3X9b4`kF8w0
zoBA!F!w(Ov78QzyR>~$ErE^m(L)8;}v{dR3-l?S?XgeeZLw-XYXm?0v8a`qKj?zQp
zerT$LhYZ89d6jU>;G9mqk&#-XQX7ZG=e(EXM1EosRWduh3ctHt@ZY>p{h56P0Sw?r
zMhN^LlTd7J%s3r71ZNcw8I0b|-BLAZh?GL>FGZWm0>DJqsmz@jm`(r$b0U1H33EK|
zGzEsiik+i0AD$hxywDq9&_oZHf>X-y;ypOZh$hac5Oi>0a**dq8iQ0p=m8rN%-({>
zbkr))CL}f&J(UWb_vo3?FdQo(=*HyO98;Ni!sEp8z2<Eqo7-X6Qduw;s3{BfnO7t@
zIPpK^<qFs#8=+X@rsA+F2liYlA^c4RL~Ea!w4_P{Ju1vJW@1l*u60N)AJLEP&j?jD
z9ln{g()7=xb};(x^iR1@Y4^u}beht}?bb0JP7sE}h7XsqW5*)jrd|2Th>>IT&=S%C
zEob9{R<=gEKm^+0M4IAw+$a2KeLCP=Sb`33jvtY>d=*Lv)v|JiNUV=b3vo@2Bskh1
zTq}=09S<R0hL*NXEv+(g%vh<Ys>ZjhA2I0=C>{y}J6oOafMq(4rMy^N+B|Ul@kcZ|
z9vx?%%D+P33K(Hl5N5c*lxFS^w}>*wE09*2=(5o9ov&hv^Q0)098dwBGzqU6v!oz!
z2{?COz_7W%Oq3F5NfFmjyHUUyv*F9<`+3El=jayl)E;zkXahl&f*4rasR<pP$tbdT
z;S?6w#(tFK^%)M;T=~p^ucwb-$b6e`Y{7+E_IC%46r?p(T#6DA<_Lg4S5#GjF~d3r
ztc>}aMU|`p8aF0%`~hkTd(9N5ur?SPbK<tdOX!HZ<apY10uPeMji%C6rl#u+G59i^
zzf8|bE0_)iqgk3J6qTJg%aKWw#VEPS2cv4i(Tx<k^eT|~7PDV>I}-JrAl9r`T<^!=
zcNB_L3M{NZW@T<pPc3SF5EBC>!NN#>jM7pZEeX$#S-55$Cj_kvN%{T+n7d{i+kgo{
zjqgiH7x-Ps`4D5&Yt*5icfrl*?<0P6vc)H^qZJ)}wrDD?XWE-|42ZHkyjLgr>If59
zw=j8UjiJWlJ((0i@28`<=|EdHT6*Qx<;u93AXy24RHR-cdaMkt24&+<)(nQHBDpzh
z*vXV<{f?dqdZu)mP7!o_o{G!Kp^IK9DBhCelAyaT3`@SZ(mo~!)0!;CiES<LR<c&U
ztgPJP%y9dA1y|9Idqi|l>(qHInJYs#wq~B;x4yTeG?w>ipZXZ<iKm|DvSgDB;n*^#
zXuIf(KfTC~z{d=a(s`2CgmCr13FwIWMnkeNxK!oO1u|K$4cM+~xctkGv{UqU+P$f+
z=GJ4KZ#NkV>lht?RQ6IJh3+HOD3Q?`(K-9H2#+K54EPeQtkZnWE=WK-pa@-y{g}0<
z1V)&!%FJi?DPUFAO?nZ;)DpFshJNRWRblO2-tMNzt&aFGCQ5iuM|NQLof&Hk+2IN;
z(Zw&lBsDerWeQ3uCQO*1IAr-2=tWJTh2IoVt#ErTUc5+M*)wL$kiGl%$=EStAlRFw
z9$C60M~zbJmFF)LWM#;SShj4L3fP%5XCRRV<u-r=KkvZ!9T3`9Q<|^d9zK&lv}P$3
z+aVx`=d{de<v#oLQ*z8P#~^{PQUz);=BC!WQ!cgMnpQo2v!qTNhaz^!T7MskqH?ii
z(?(S$+Hg*F7slnh#~n6WUU>0E88vdWOqw*w6c99M;QbU#>UHs^erR*jd1(Ug()Tb>
zMeM5xoQN9=vyqaY-e0!kNg)yPF)PYCxLMdhl~c!GRPcaMI15_P{^hC<m9)B9n#Fxp
z*LP^aq$M>R?6Xu*=ooQnCPJX~3l{od%TVXbTZ{qSVB%UmqFZ2I9^yUFMR6`Y{lhQB
zsr`=E>h0>84WWZ-{V}LNoo!{msh2CveXSc}GC>84c?Ha(HgAaTRZQS|Lm-T%e9nOr
z&;iqTGj@{=1hlQs3A=v5E9GX73?6B{24g#^jTXpo2?=Ib(y}0*Qr|3{FGLz6Bs-MA
ztVZpP%=m&X$8~q|$fHO~A@4S8AeR$+tQe}KV!1~euGbKY<Yk@%(+c@k2~A^?cD*rx
zbZSr=85adEE5cR<ngt6KW7TzG&b`!EWae{3>0Q)yagpDq&5chy-H(@`A7iK~ml@7r
zfhF*=tXRHW{&3UHI70DkRqPrY>Sg^p#MdCGD=I5w&FWPuaF06bC?p@gB7eQ}4w*E0
zl5F0*Ni$p5uC7F`!yXwoZX5*LL<s8^73eqLe6!4)H4|q^uaw5d2C2Y78KXyyRblz^
zqUACQLXkgO#<(B7uQ5gi4(B-Ru)`4F+o(MV4nKUV_8Zu`b*t9-KXCv3G6BzNN0KJ3
z{*`Oj$OwdX_CZm2_~A$7+H0>-LB4n2UYRsyvI_P+yLQQt!GolssY$BfL1ALgc8s?N
zzqg^{f%z6EpLn9oJZg$O`Pic}a>Pi<JN*n91NSA9L06#{Ki9_QL_M015fdj<kRobd
zqr4>n<Ih4PQ9L}ZK+80=u1t}~lz$bH{0PdKifXlxDUIM&Fw@YC07n-l&W&&A{rJ2S
z9=skVs`@sPq(6FSbP|bGq(YT{N3AD1mLK88>Q||&`T%Ur{O95r1uPw-KvkY-Y6}%t
zYhL2jc*k?yJ=U~`u;h8`Y)HcHbokMFHTJA<KhDTj0U1L=M}@9pv(=~zy@+wL#P-J7
z&v+Q)&|JIiSUeg~g+{M7zU)Oyjsn_A)zG9>kOA=2<e9DO1zI8Mo~co5cPR@kgn9})
zjgZW*UyzEp*%OLGTI<N-5CU(Is4SJ0h_Aw3!cbZ{I-ixJ4I9d%fe382k$|agtn;?;
zBp!xjJG%yJ&38T;lN6QYD`T#zEJen0U^@=<isFqI#f754qtu+BcT+fuk(G{mXuLxL
zs+0j9JbRe${Yw+SBQ}e)GYGINDJy~{)d9G|&4*?ul^CPK!Ib?NbpIo~J+YZ*6rM+X
z76}Ibq5JJ`Q@W?ci{zb7x+oz4**Jm6rLuIw_@Z-VY27QkZ}rH?k;q$s5dF=sf2H@(
zs+~4%8cIoiCGY>h2W7_e>1y#7A>W~xv1V9BZ@Km@^1%;(R3?m{An$zVJEXZ8RwpJx
z3;X3Ii&6QYf5<9S6;KGDe%fiWefxH)*<YhV^}X+XFNE}H`R||pMEly86qm`l=bk5f
zAv|A!VBE272Cm;G+qUhL$&)9`Fys{6dB-g>X(A7=>6HEZYa#p_RnRYAwnSFUJX#)o
z^kF$>&RiKYb`0uP%jAwbZkLl#2mhPj{6;?Xp%2RAk3SBpxf>^79fp#Z3e34#GxNO?
zvvA=;RR~VQT-UBy3zue_Jn%p*k_<nl`3o8w@0CFrgY|J)6LyyIZ~YNa=?c7LKYzN4
zwF?vPAoo(dwVm|a8%BrlXOW?hesXOW`OxQc>&QPCRwydKsobD}%5u^`g&>s!6Xa=L
zmJr6;=R})F@<CY5SVwgw#z47NAzZg~b64R0>gqvKg%i%03*d9^_}t*-c~u75PrBCK
z6m8JOWFC?HL^nbOF$I&7I_RgYyg(`k4brxkMF^E)7iCaY1r$p(MIv8;w?OyUnVjb0
zHhf_N7bcxz>+wTg-L4^)va(8)qm`io2hY=^(Ht*}$01`~6{Q@e8V5=E=BL5LKPpoi
z^6Cctw^@iuPrXyML#=Kb%W&JjEI8#c**4Yw&aso2*N!Y$?_InArprX-G>S_t=CBit
zV#O;fWZRCNDBZ!iv-FpSFvh0G|2v85|Mau=h?q)!VO$Dd<Ae_9=+e0`G=YO(NK|4r
zWD!pGDMc5sCmz2~D$w<(vAIY7{>T&Z>YfH5Of#BmF$T?}_c)j(i=m%~PO+1z{ZKlZ
z!92Gh-M<W2vS!_@@`pd&0=E<d6Z<RE%bkFFG6H4eBK=)|DzZkwO_dcx5KRlB`wcBj
z85>={W{V6fDwSQEH_FYo-zwE8?<hn|y&&pobQs1f{eb<WNpO!p`Ls+KKMaCkpWOGr
zqq1!6CMoDd=@p*U#%y0Ao7?VyXY1d@B?qcr_(YU^wh%`0O`d0ksnM?RnhASiTTHzG
zezxH#ubVi2oE$xKx(tT(SdYwGD)1c;+KeH012$SF#^+#v>znIkJIcuR?%j>=i{#5+
z{(}7Y$3Ky!OP9!n7hNouUw)aoq^ZO;z#3k?a=Ct9j+37_gCdN{11E}0df+y0Q@8ls
zIdkN~3(u3sAA17A?o?RAN653!J}Vnu-5{qdSOCG;gn89LF&K%l+vNQp{E$5J)bp}>
z^=g?iWr{xM`GwEP(4m9nb7&CM*48DT_~gf61((Ucz4zVn^{;(X=FUA<`)G5G=bm?t
zoN?x<vV8dxxTM<vhhivX)oN+;xy>yN^6Ya@LGdh?W;PaTg)%{mA@kvZ7=#9J=bG!T
z(S*xi{qk1|;WN%WLmF2#%D$Q!2>tP3P}FYi6st(ar;Lh8ggj0YPoPo+#>-AoJX@z4
z44!9JFJ8J-Hom$UO&{vj9d9RQIc?9;eXzxu=r4>Ax|`lB6v&9=Xj{NrRC1);o&2Yk
zmVyRecxkcBnlVvo_HCED?z&H&S@<##smb+Nr{aO8KAqNg9lvz-gljh}!_u-sS@rTW
z(t)E13yP~S)>6c5|A<Cn^{N2U2r}cx@&}S$`gyV%;w|c6>W<BN<woz1%Uh#(i-UU?
z6xsr|umnA|qc3}b_reu`mu%Z5yLWAoGVsn-uWph*{qfIG7Mm~{yDmD*NAJbl0Te1L
zJ``C%F9Ia=!o>?^&h+u{^z4*-;1zoI1)QJWRfmuY%Rk9*Q>=!FtqR1QTW=69NY>(9
z7{RfMu=0~Org;f18O-ttcsbqn!$3!qP^&%ts3T=KyNES5gO_k^Oq{jkF_SI^e^X49
zKpcmn*TH#2@H<BfIvr1G0a)F07Y>!L#Cfr`@{6DUR33lgIn)cIj0YLPJY&`e&kZKY
zrc^GnD-5d?_&Nb%0@{I$(HsDPjXB^d>7u2Wr*+VCkDdx<E3$6odf8IbDXoq55Flhk
z6wv0dB{&Pg%vrkA0WDBFkfS?J>;5KbY3-3+yKCj~r(c3)(t_))-a8Y{r|KJFoF9nw
zhv_ZT*a<<!C>SgEc=j-ofUtLsyX&NJN|)^3*CfxqunaYbjX3lOJwLrPbxbx5S6vd|
z_6^%)*wAXgv{M$nvRYPc-UZ&YSI;o&U_u^7D)KR-6ktTHzgLdvzBB?&nGs!!smvJ3
zCf<Rhhg#^t79<e#h)2uUZp4c#235&BuDx2`bj4-p76;;otC2!L%VD$`0ZuoD3whjO
z<IuwIDs)HMC@;RaNbbJ-ZWTnMMvZ|$tcGQa)7x4*wK4wG$y4NF2;O_{y-zm46@B)(
z=fW-CD1U$8VYRNN9dWpnL12>UKJ)Bz(g3S^%ov=lUS2K*upGw2`mIMS`ndV?Wi*~k
z7}9Wf_|eBubK9s^^nGAj6r4jL%<=)}d;WGmT+gFr)abDgo<rqHH0BvUaWe3=L#^c@
zLx!Uh-fgn<mE|%M-I;E=^)@+d!r^lM`KQV3*|X*Q-~Eof`OR;VKmO@v`N~(m0)hR!
zwr$nSZa}u3iIm_Pq^m_QFUEL7WcrMwp_uJQW1D6<>Ex5}+~Mk3P@Ggt*jc@)o9f(p
zWX|3)Ce0O5fq|ud^B-@MKm7Stz^oZ(Uss|61BY}F57onAyBt=?!n`Gw-ZJrx@ECf3
z8Zz>My<;Qy4{Z@-%jVrO<%kLB#oQ)~m#vkam776F4VWw72O~iZ81&et<%p^wJ#*V!
z<2c6~5`OoVS7iF6Vd_a)jou8+xTvjZe~{>>oKppx;dn0c)$@d)>L5Yc=}V3|HplFu
zL8L#VbJlmW%_r6J5}bp)U#j!lWLQhPY~EQTk3F{-ispVSg6E%m&SIs9X7urdCzfSW
ziKcy3EU#|bDbps7k=n*qdFka9sJz*X+UR|_8SSIV(^CX=!c}a0rug9u!%R34mc>z9
zon%4l#TI*3ybcLy^&%iwqXRsp5-ydi-h72zb=Bok1lnoiv2r>A-fM|&X^biY&2kjb
zUTY041B>SY3sr-vWy{W8@~(e<m$U#0k3H#388&j15+1c^<;_m>^9ckxO7F^P@01bs
zEt#)NSzs)KZWo}AX3yrs)l^o@zSFR9V8P^r(5HeqO+Ioi8U(aJ7z1%|Z>N@0Ss{cr
zw!y2Dox-?QC?HFpeh@A^xLbyglUc`~0u70aK>TQ+*OL3{v)n=LOasDN%AlFou%IcZ
zUbwejipmE|)zHy$^qiAWyGaGb9d_XMDXFf{aR`>^SHeB|*aP?CejJQaQ77Y%o+Bg2
zO_uyFbo{}dx1)_Ay%NZ0O`BhoWfecRNX0K1=#g=0C}{pr2D;BQCZ--Bi<NhDw#xQx
zTji_Y`o6rl@J0FNcfKW^EwFr;%)%x-xTgaIHh$bhx#Eg9p@~bQCQDs$<(0A$Enm-p
ztGOD&xgNr|t{xfjP+F(J3Z`{AZo*_a4RP9fbk{rXxa07wZh7R<N9Bnpo{%G9<<c@b
z^Q^OF?b@|6b=py|f``JbTO{XSa3QSgVp+6kF*5|fn0QzVt@%7y@B8Jfv(J^u6Q{sE
zzC>f;M;(2nx<(g1zfj7N81{CwupI{Pz~;?cWY+9s(R^kp?$4L;6DG+SXPpDDRtx^_
z0Ry>OX3d(7ICHZcapZLQ=*K@HM@>IUm4hi$r@^X5CNc!0Dl353puttJW*X(nE8iq*
z5Z9)4cjg&q$~L&ymo8nVO)63aa;97X&FWW1m5A3C;xmRwKK+@`sdwvy)6SN;6Q`nN
zsmyspZNJTe4vXh7YK4Sq2F*CroJ?_ZXcdz|(ekHTyA2JD3QGq|N!4(fHsd&{8a4_N
z3?~=?*E;Y$hc519UxAQ-=A(dLENfh|tXc}%cB7gk4+jm6lNra(*H)jF17pDe=iMK0
z&d~P(k(j8lW+WTJy|4KvSYbh7sq8_slI^P>lftqp88Y%PnKkcpO`fFNTfKOiu5K2v
zuFb{3^n5jZ$CB7KTu+#mmJgF7XC0586=Ok<NT3uN59Cn^x21W@o#YQ`FUbz&Y%5J?
z;_3M>=E^s2W)`$tgzhbb3C^I{Cja%LU&`|@JTE`|!FN!?%Bl}4{pLwA4~I!<#^ucu
zU||A_)EgS+B%sZum>ibp<nxgL(*Z{Fz3=`|YU|tN!mF>vF?1EufVdtNXw7UTfrk<v
z0s@H&lw^ZpZ{G(3T2*b`^ltXahRcL;k4m_<>tN+ovCa^e)Hk=w{>C;K#;sE9;zZPJ
z?Zh1t4{-=$NL{%okEv@$GY`6CiqYt#M{3Zv4#o*CV)kl(CVmj^B_WY~l!)w9p)M{E
z2-QJt9Sd*i=mAWqo${2ch@f%GH0iBqhLr~}uz?}Qfi;fuibBA(6G>3Ta9?)7_d^gd
zzLxfiP+6nF81X4#p7P3^IOZQ@1Z`+%r*%<z8#8%^oPAlP+;#gOWX}9~^49CFl-m9E
z5YiTdrUg25=m;4(dX&1HyHJZZefkV!O3%?!J>vMV;Ul%DJMm@sa9j%^-iEC0S-6H{
zFp;XNx<V~gW<Qr9&e#MPjYE>z<f&63ym7{qW@mTEkYOWqeivObPMI?k!T9-c^XAD}
zXPlwQSoP@kcIs)T!@Y|6;W>O=_tv+mi<@xhhD&?q%%N&=UVO<Ur9aN~q?1ln_QEV~
zVnh@6n@urFVUeGF%Bf(At#aZ?bgehb;nR+EohorH4vJwS6En3ZPnjyyjyy`A!`Su&
z2>z*4kI=-nmL@XKEM})(VJ=EztgMdch5|51{&LHm8Ya2mimPSVn2Aykk3?si)uYog
z*AlZR!K)C6m(>zG!7w9PT6Vubm9LZn8hn8ziXAWv_5%hT#W+BytIZg$n^rNd;mSMJ
z`D03A9y*GZf$sKWKdb4Tz!(kK>%CC+m^mNrB4#Cz*<qV$+WomVa!l+)0Tc}W>wuR)
zD>_(~hf^~4Hz4~TTh)fOw8Mz0Y3$NG6?!REL1rRV$Zg?koC(uHmiQHRN;7y#C-Aoe
zaH|JQdrDZ&#>0M8u&6u=zao=PbKuL-$8ko%+j~o$o7?fqV(nN3`X7IkoO|gYdE)LH
z<##vUB=3abT3fph-egRM-hmLVst3U>A~99_BqsrFut=UPiKP-9xc>B)JLRb-pO;In
zej9{YF&K))eR<4e7h_TSa>6}PY)mXoBxZ$&P9?w$ny?NVTAdHLt0qMYTGbW0Dw&xK
zL5r!7>FPbs#imUMz@$4|T!HnwOmHXQOjF_k6BaiilOS`~2KKbBDC#_+^2CxP?K^}&
z={t~{k1FQ+17uBoo|~8Iw_KN63e?!_s6*9W83&>kr!GW0hB6Iv!s9wHb~D7mcBo`F
zfL1%0G-1+>#EwoJGSUGCM5RX+XAhs0eGBhn6g@>HYV=@F66auN<fMuR0pnI_z(f>h
zJ(ELV>3jCo%kaUY<g{}ymY@9OXEJZzama#3SrpH3<=yb>QZTiH18a>k7!U=nC3_ju
z%u^+ecn4h&b)P)znSgGA^5^T2DIl4BJ%0Rnb(t6N%x3&<(G%a`vjC1UYrF+x`*Fh^
zyRNw6O5L}8Xah;5vjOg3%f4d`GVm1P7B-(zW!Nd1`FKVfVqwm{Kubvo4dAb~B2+l=
zL^JFY%f)a%>vp+LKED|XhgJx&AqwElXK<IBxh9OMhtp%d{5!uD2dro;&0Mf?gh@9Q
zd=*kiEJF7A`gI!+)Bk^R#(5XZ&=KRMt_ipVS0>BIm@DDyPYvD?nBtO-GUBbVAxqeC
zC=*4RNniSauE$xu(WSRJrI+)vvN;#4$K1$fl$X%+=HLPd>RwT_XiE$I96W^bMg@@_
zZL4LD_@)!WPotfzgJ&#LP3Y8h+uz{?*KF%g<(o-=I~YY?6Q*0PLC-@cJ<*7<{0{P2
z@^uPUtMLb{@V<-3^YVM8KSg6zaIEH=%!Ey!^ptYlTgGm+$q%1^zd2SL0HsZkd>LB`
z+50@H@W)}6<3EoQx%!=sn>uK3N}tIz$_rNc(3Q>IAU_#gHB3%D?=tz-uYM=T&pT0$
zJYtIWC?_ph$k+BwZD*fDkn;H41az=t=F(6XAs$BJyydn#WZLYxh@Dj;o6{N?wBr~@
zLq9ISiB1&^p<VWV;Z(R}`#S|u{M7V0A^at>c()MeLFY9!bxkBw#zv-UnRhxd3kn(b
z@TIOLV>YVg>pd*RV)FsMw`42cVjwpL9lZLojtpx{L!2DP=H+yuB(zS?qzn%EAU3+6
zRDf$;xG@QPrLeKkv-y_pYo60eSaKZCEzCW~1d2qsAPGKEYfW2dXg}O{9Mj^KDU8-l
zH*(g>18jY^B;Q2GETKBMeMcTPNs3=tDtF%bSNZIxuGfYnrsI*xuwe)Lmp9|udKrYc
zuXWY35DsCa@>vm%53?+73iNWsl_}6`_Ux8QoT63)SFk1ju$!3GH>=PLA+HG`QwBZE
z+G#=J9yZ!BCdKLDeoUhUZuyqxTFeV^Ox(zFD<-0K>ivwPJAv%1H@cYfnT_R-MpQ6!
z0cKg7wdLHaPB5t4a8@e2qggVoxvKRmr=Tb_vRQh{pn0R=9plb_z3W~iNtL2C<PlN}
zPZz4o^*GpW^l#?a+S^6xG!x>a;Axtqa`!2Xdt`C<B*myg<Ag~j2{+ySj$X(cRApCY
z%bWZ>6^tn__r1GL#Xb266@O%=7HLMM(V%rQv^K)}6Pm8Q_Y+j)bI<W}ONEDSOh2wM
zjPoxY%Hg|@tLnGhC&EKBv;7$dwichnYv)}PYlx6WGp5`T_eh%tOEWoHVL^GrkQ6>+
z&apl_1XwTRLLl)*mQE=QH`1!R*DLwfI3^i1UL=IC2^R16*;Ap$rMYfLD^#9`4gde-
z{Re=ZXL;ri-_v{3Xw-Y}#j@lgS#me-#u%_MrU#M`NU{k@Hk)MgWwX1<ZVDuu1_43`
zV}m;`a+h3WOSY`udv8-Uef0gV`+47U&di+AoRMTq{69v_%sKCQ%k$j5T=z&T#PEOc
z!AI<W{MjEdvw)fxH%KCF5gyz3IRLUG$wap|AO#)YNHUBBQ_+ia5ZvaI^i$5BGzSYJ
z6b_uxJYffdkMk$dswHSciyo6)PvSlIzug#c<r1rx;MKVhlVawYp@=LD#R%BVk#de0
zB3k80285iY3Ryy1fF2<9ONa9)pBt_g`u!4HeC`kNE`BpGNARKpV@C#u6m*Pu<c5Zf
zkXVRBhx&bWe?ECYdbwayl)=|Hd0beh*gU&{YvZR1vt+x;zUUGuBE;`m!lEbdg~v%g
zqb&DkVvps6huW5H+kLv3zN@H-x7m@GFQ<C{FoQuJf8sG)aPh@VK^tt-rcUv&vMP)V
z$Q3ILE00e(<UDE>G~MmQ$rIjs_RvE=Bk%iRDx}LioUMFwGfGt5h^55=R76T!-lRU4
zf>jHYZc|m`Tj;f}tF5z(=3mS+;nkvCmHQktsFXhK{a%3f=}&&nJ&(f&_uDW+@)8Jz
zREvw><nb#Pred}NMgqE5N@!9@dfG~P_^RwqV&sSQ@$R7R^5eXzH0Wj(1&OtYxN$EV
zw`{Y)BdGw7>PPf^orKkMd}>W{56^mWmn*R}j*m>Cy~MBQa!fdNY&-?(i)BoZEA9h2
zUBx^Uj0)$CNcqIYOhG>fTy^oA(iN`UBL^VHWJpW9-DqDYN_p-CS0n^(%98bbZy?8X
z=eQ6<)cr<^DKJ$q@FNE%q|}1E3<^8!V*=E~TkE3l`RS8}PAsEBueA)=aGvnALCz;$
z-3&s}OE_ncb*V>&=j|Coi6cMZTdBt+Wkj#*IbTHU9z_8XIsgK1B$7OI=omY&d!MJt
z6fskDBzVuUzR+LE0^^j88kmAkeo+q}Zb~7p<0p<G*kE#USl%+B5U1ZnyqRGUlhLPe
zd;a$Yl-c2G;b8;Q1lYB3wfK{0`J&BB74NZg8JJ1;78I}-7J0R@-V6)taF+7kr0_i?
z9EkK+{gqgo*m~^dHAG~asEo|ufr5MN9;k<h{GTjf4bO<8EN*FLZj5y^ilYVXwq21d
zl2@Cmoc;G6;lJQ*1tUZUhhuu~Qv3!APZP44WnIr~Ugera-z`8m2E6eudjiG0_U+Yn
z0wp;?03V#{fpzb=;+s#E^jeCs<hfpb)m66qnHTKv(PQLx^X=(pp0;~Gc8@hMA9m%6
z72Z3nzTqQ)jwp}4f8Snv{<-JLEsu1dlV_iM*85<uT(*qKNY698<gm@4T3QBxX3XxS
z6Jh1b*SzO>_UxIAJA4x4vbP*=v#c!N-hO+7{n?-Yv3>S)pR?J_Ctm){Gn}sqkd<rk
z=8J6G_AQPEHV(Yx3F9Z)E3d317u{@^T(XG2CwO==)dLQ@*K6U<i`?Zs=ZJS$*IWdb
za^AI|td&%aAiNpasg3DQp(P~)T1?!{K#tAi5z;?*YP2~KZO|&YCl<?zAnd&dT3_%Y
zq2MX%xq_UD-sU|=g+q{^ah?h*9+7*Hp((c;%TOorUZ3_{gLG?hF2{7giy$jwBPHCN
z(~6!^_m3RN_7oFGdMi~V38X^&zQcNj2MFmy2ZV})a4xq)S4|w*@iJgH0D@Fc|4Mn^
z^-T8;8(ll`PIPE|Z{0*hq@WTM&_iLlxasy@yjww65bL7W1S9<jI+B97JXP~6DjOMa
zT7-bn9;FxcGg7ZQ(||qbKvp4W9ZX3TZcrq{h1B1vyn*LaTpGp`juZk5n;6?ZQ7|~6
zq<bpszM@a5Yms_P{QcOb3U*yw#VxBV*m@3JqWg;HkS6kzA?y%dL9xdS<QAcm0=_c&
zp)>R?cDPHC=lLRqUwkQ?QzB88vgy9ziNBNN)bqW*p3PYzqL56ENq4=}?*)eHsW3wV
zz(DTNbNV?_!<Byhq%|5pMM&rKU7uzpFCZ6T3*-r-IaNI$z7t?m1O9LzKxfS~Yvjb4
z!g0yp#kpY}eJ+E}qe77$ufA1C*jqned{9F2g^QvlJpUz-jTQ=Y0wV?MURAbly#A{9
z9$$3PJX;PLm!|ZbB69Td%P-p(zVLZ_=9wqG_-p(2?Y5l?XSEAmgF+PG$Rzre$D<6_
zz5TYMbFEyt(rHDCfAQi=?8zsdaAi4u>=^q2Q^gi9Ug8L3Kl;J<ZRgINcHhVEqjm8m
z`k2c-wEY$>UKd@oz+QUcIoq&)Eu%uqP{cEA&FZy2kxhS(=Uyg&SoRZIrY^sHiM{^%
z>lgvg*oQyzAw2FXn~P#!zWiA`L<RN+z)qH83_SkWWA^1Qf0^~@UeFhoEVBZvG!{^=
zee%7KVpbi8$ITTkXJj8WD}{n9<sI+4rsd81o?V^<xsxt58F(axT6*wXCVZ3bn3!M^
zMq|w4k?M4H6B+GZ>)`T4Vl|R6fmplA@C1#<MzUxQIU?CY48tQRIf`gd_dpMX6KpRv
z6!A%do}>GUk9)UeOOlUtBOxUssUP!Lz~R>#=$Rx7c$P@<guRSps*IV)s7_Wx2Q4F+
zB3a}}%zQtWO8zYBo3hT(>KC(qij4A$r}B18b?IbEB!j{s$<>XDse7NNkMs80n21H<
z2$WBFgl^@ub_r6qK%g_Bpg0ssO1=d8k2GpGUKx;rjtM2U5B(~-0fjL5HQ*8m)Ss3k
zskBI0#ns;lLW@EH;ZC$c(K4lxu00*RUJjo#X7c+UHgN?kb*Z8fNQXY`E?1}_kl<Lj
zD!Oom8i+t1U$BTn5ZDXA;z9&(2k}x4T4@^GAQ8fiJgnx^^f~4fM+>Y4mok!-6z6YU
z%|}GoU7-x*+2UP0+w-UHY#_OyfwVlK2q6UI6QrPl=R9{7?Po!_gr4ufNXfiVyiZ}j
zLs&9wZSatlzi!ch@-xi7rMRetLWpuU!kgA)MamoV(?|E?H>7-$Yxg8^Mhu+Lo2d_!
zVB+Xa-AWp0vb2ttb6pVbF-C4gdcHp0e^=Weq6H7er$D)oQI0elfSLm~h>-T8g^O(E
ztFL(Yxs6KQu_)D9vu4p>{4@7Xg@LU(<268GUUu1BTk}={ZB#&Q4yge~vk|ZON_z<f
zt@@4o?h~q5o7L6T*`fs(*`VrbJ55#eT%bP-2}3{e#N#%CYVbMy{VHB=vw#l};DY-U
z{atd&CA4C#=K9ke>-(Lx8$5(o0D8<2`jM-E-E63DAS6D|z4s$Wj(VQ^jn`iH$X6}6
z;sQV!F=8ZeqciDyUKRFNI~(QH;sweyeG_P}Z&N9;tsK~)!ZW8L(LzWeIgL7^oAAe@
zGkMM~oHxk>;Tqlljwrv!<ul=%bjLWUM(sdxAy2IQLd9>$C5947H71JYBP0ezk|bYZ
zIucgD^Py;0MPxyEi^gP()Do2$G!)D&`u3Xu{ApM29fjmIGG3G#crMgk1f{RF3s?``
zcjsJWOX`-zDyzSB^I}U$THT}XM&ty!at-%-#+gp*!h5t_3Xw0UfY?pbgR%E6b0dj`
z3~dLCp}m=ro$8*UUF}ru5gS@u5s_nZq+{^?LLpsG{tvBNu@RLNDCr6eV=uNF>GmY!
z{{Bu7q^_xF48}-!FhyErkVb~4NA-eQ4lS%PvHM$o-vd(6>UZn(6Dr3NZG;Pa(U5Fj
ztUeK;68i3Qrt)b}PSIMXtU=OxNiN?x{uT>+c~=m*Ha%NCxb$U<2{ZvE8^Dn;1%h|@
zy-h6}4wN88rErXTrfDak^4PzxVg$bJz7<5W>g8u_>E-k6`fIPmqk6;MSn;GSzWy!>
zfFM4;lMTX67ESbOy9z)W@~}hcec0PL-*S%6*vHqpDYfViSIMkJY~4C@WC6cwO+=;1
zlj^C?6o&q9?%fNXymd)!GVG;_fUx}3isZB;2IHslC;?ro(@H=b+qLcuYk_$#U;Giv
zD=fC3KK!U%H@M0Q%7=JOLJkH}Cw+iw(>WtJRXl?%{?@fr^(k*#-m4d|$+Gr)?(s^a
zdDG1jPrp3z*;HYAwsjYtm7*?D1%r47noxmT2dzj8FTTuv_P~#*%KSF@;1crBLwyKE
zwHH|#UhgtO%WvbIHrQ2HU1Lu^`IP<7|MmAa4-_x8Q$7Fk3L83{5cbSj0Nku}kv<v}
zGljaRO`C52K|98@sZ(jgnn!EK_Z;5v+H0=^G~~zj)vtZkv9Ct}6?zg-kWut0Z^cuW
zF>vkmH_%)CTxjE}tn_s(2AWg!{2B^(2JK+q`1-%QXLidix1hkYZ2y6S4w@qP#EQxq
z=$1hl<ln1nhI$Q2#HlIHMW*Vx@Ad6jH0HZ321EHs%xA;1GJ>;-;y7l$8;cUU!Qjq7
z<!8=Rv2B<lqMS5((1-hmsz&DGjxZ>e4yq?~J4ijj7XcX-BA|D-lL9YQ^!r`=bD&IE
zTUB^>WjFA={4D^a$Y>Vkz`osE?7+^=_L-0VCZI_T_P_t?|5?T0u{LDF9QF<LEue`5
z&xuFzCS_O)Br2HHv~8Wo>O{tG_r=RhE<3M+5#g<@*~Q3B@v(G*?ka%V<kQ+J149Z(
zGo2M-5SU38-|3RP?J8t#ke6y{MDA#X^Yc3G&6UrS0;#vFu3hG%a36Z~0lVqLpF_sf
z5UJI50=|LddKhFB3?Er+A!5hcL{Ya;6Oj7q{d`XKnLTztbQUXJ-Am-?xL%aYs0d{U
z&nr*wk)tTOkf`5@GIFBD0V(LzyGoEl^guDPN+yhS9;9^kg^?Z+BjG{h>CrTho<&jI
zUl`F@^d#oP@C9&F8`Zh3Al&2uSdtI%3)3?P0tuid0a{O7r^@7f@{k1(RB3)GrSj8k
z&#ry;`pVZG)@klVa|z(UrVycKBX`hK?BxttNm3w5>{ac4+<vadc-L0J*T{1_B2w=e
zjXYlEZFrts2s>9yMWiDic)o0<D7so`X=(6T#af>{DQ6j7V1cyroe&w}{)Lmv+6p--
zmo+Km8bbzE+dk;v$k7vajDI8X<f_2kJwpLhn4XN<V?AWtb-F8!u)=#6(*~Hk)U_Ch
zAimIR7#lOm^M)|LkhD5{D8$`&-vhc+omBxsqI{vtbOd!Pk%MJdUCnTei9Y>lEP32}
z?zz{8QH+i9ylS0Vx@4JSHW!iSUb18fUU)n0R_%8E4cFUV-~o%tSIL{*vSpJaa%uVU
z8PRveva4;zj2XU`trVaMmUGvx9X{Dg=dT3OOA1&(Ck=SnDn7gKQ=jr4b<HW>hBB`L
zpL;M7fRlJ?AN$zH?ckw<0IXDiMPKIM6}0I`050*~?=)UVrrNLH>h0)6o|cNDY%vYE
z84%=KSlftCx&_@by^*sVm#U1<CX?OY#e);5i(2g*Qj<`n_#;P(SZN$&i~6AR;HxGg
zY@HO@737_vFpo|aWR8SV7bu49@`5pL{h5&k`N9!~--<cUxDi!$V)!5osujL}V<(al
z8I7@&Loc*DJfsq%)S-LoEM7jwfJViJww?2Mr3*WyVXbstXQy}oYs$e#P(p=ZVrUQZ
z)P4mX_kp^TwsViBsR1^EEXk(uF^6aFP%)%ZRLCYr;O0HaX~_jeAT+#X`iwcYYUMHN
zG2Ud*%t4INOE4w}fkVL>%8(}gAqr8Kf<npOX^{xG$8|3kMB|>*;`UxbdCI|ijy>e?
zi@U8UIwASZb5_vjbjQDhFLg*MBb>Srm<74==m8RGJZ4QTb?_M$6`z$*dH&|A*RjM(
z?4m2DS^aS)_29+8Qy|vhQI-JN7==Z1@v>`=Y`1-c1GCy&VU2d%ylJDo`Nj&HO!3X>
zrW1B_{i_g-dZb&({Z$bL9Yw`%4f!;A22Mhe{E3Mr(_G#;E*Jv9TW}C2QX*$iwBkWk
zX_uf`JAk4)dFlw^MTL|Y_yIn7YiFZ9^zg$rV)8}S(s0Ten(Mf@V!f<a)eum^N@<&u
zP=OIZ-a2(`Kf(yeJz2X5tK7mI`@jF^e=<Cz%;qdw!tjQj0G_ClxyULRNK!dyu(g1q
zq=J!-4(^ZdD1Yy*B~f@TRCmgV32A`~^-Aj?q&<0$YetGf{g*P*TG;>L7#{?WLCaGb
zgS8|cE|^9MoF)vu@sp<b+G{*xC14{pL+GVOF;`X9SasA&C8fL+g{wgpZAe{bTFy0b
z$_x)rH>2RE&Y0z%+9`0Y@45FAgt+H;7)+JUMGRF?7<%f|8UCIW|41sIbsueNt5Wqh
z73ft})mFv2>%D2yI5%r8<3Y5bHm^yOr~3C*aqhU|oU@GFwZ=!r#z%j9kf}26?>rak
z^JFQ|+0W=YDUIyzsf2{L7vk(8m8T&M#TppWe%cyNz(XBW#iMMC>GjP)89xIL6%QQ`
zfLMbaX*}h8rM0ZA7zHn&T-p_7!;iu#IC1Q-HIsfg!=98AXe%knv!6Zk5X!9F7A?L3
zgLfawdV?#xit<V;2jx$54o*|FC|FnF#b?9Mo{~ruc3zm3%!FsOe4TjnD*nnx*0ePq
zrzYd1*A3))6snExh2yqs+YXz1>5X=9_a^H=Ugl$P<kOB@41eSlms>MSoC^eVmgLgm
zJ;<I0KcCjLJipj}_{|?!4Uwmd7f-Q$TQ)cbqI&(yN-M3J^iLk^+l;LB)<cDlosFXn
zjy&rNvnm5SOHjGzF2_V~?=J-{qJWv??UV@`5q#~nuRU*v_H2a5P}C4W78{t4;%*^#
zTwa-NYuCI%UhtH)bF6!NgrUYv1tDs|H9ke>%~zj=*=j*f8V{sp1<I(>CXV}%>{%-y
zjHphW7Epj3sDn`UadLxiyu1YgyNEF4M3@N++5te~ob<VGSjOZb-7F*Bb2>tB6Ko#U
z$ru|)cdTcc(JCsHQIG{{v%wpH<nsXQA36q4tfJBm?%K?dgu@<wYH#VX1|DJNT&jB~
zPq!0CkJ{?jU$kKrc~&{3+*1g$K4#CJYSX7Mb`i)+MqAlw7^XNMR%$zG+rezkDk!sy
zF1g-ARap`){8S-{d-`!YBnlm7{G1sdnCY4;G^xl#WFUCH58>hSmMPZ3s&560T|g}D
zL=SQi)ItMmN5KhRQ$j;{)WH}A$b^<9Cg%AFN_91Ka-6*9EcRg*#$9Ns3YNa3h^cnN
zD>?(_wpyO@Ng2$cI$TQKK{~XTibQZefr!MGw*Y~<INtAHATxX-Pg^2F&mbl4;Z~31
zDH;OZ0$Ab&Nl_#~-&J1Sfmqy_=w36C@p8YH2WIFng$O|gH>!0Ye0+xeQEPG$x&0Fd
zcH3KoU)!6Gu|};R=Lyob!-|CHM&3BLlmQ>BR@$lKhv7efDcs8}x2bcM*i2wo+gloK
z)r#k=6xyg6rb%M*{#vOa7;3lNc00yy6^a*S-qK{*z!Gb-PVL`jTPft5y<jN@^H6K@
zNl8LUl*mdJTxRe@86J|!;>dOpzjWA!)vs7R#g7`WQcQi0Ca4L_XB5$(ywQ`an7QUB
z5ATF1Pg*wXRabl3S}@S3EnI9vN6i8sV2^ED^@0rrNp9r0;W$^sKzX<kmtJHG7tCik
zQHAeAD~3@U12<HEad7Ku+r1&n<}SIKXhnGd2_ec6z;Z(DC9|i<a7j`QOAC_I>on=E
z9!$uPH}C(t?=J=I0*ow%1Qhw=*PeaEj_%)%BB^jMW%Be%g!@Kexza*|msnC-W!v|k
z@S3tJ1`FgMkTfl5J;atnaYlir9TlIk|Nei!M)ho!hpM!$VSoa}qRBdfc5`Kj-~<?6
zMOV+g^oITQ|M`Cq6;p!nJ~4PbALw@7g-LSszq2W%=>nI3hxTo^4X-V?CFFF5Fma^>
zrWr#RwT%L=1_U#)RFn;<P<72-z@>4TDqh*OYnQ$F+>=(E-2~q9di&rVw-f695FP<x
zYK5!4s7K5}TMUe;=gk4XS%p<y7$}WE-2Khpe$8H8@r*6G`c@!dQACPnu#P?n&8x>%
zK%vLd3ipmMWX2E~EX!FA3A-CHRTO&H4<T$hx|1^&8AUu*{oBfj#dYh}5qg_%tKVGh
zEmAYdFKcLqb0D;_i%Rce!qEyt%d_3EVLiRc!|-kgxnm{}648>vlzttBPWj$TjC!0r
zd9oL9$)lCR3~Qw5h-xbW$caZtcs~^Gg?sPr)dr(OFA38afy+lh>biVC^}E49QHmyf
zp8EQg^On<vX46$Qoex<^h{}oPM?N9h#@d6n>iI{h$ZcZURxxx?XqQa8#HW%q5bbCN
zO)U$rZ~M-@0LGMI#F6Sjk+uR0{3i7(#e}_29wA&ib*z2)cfU+32*tx^>VKBe5AYtI
zG2Jj7jILCFI*x@vku<ye{s$kn@BH9lyYhxRNOc!^rF&3C8A$rG(R~_sIg>MrJ_=cr
zb#GF<cx)fW#RsgMb*LyW2j+GdU_K3aws^y&29KRO?diWf>RU=MY*p{@)`pGL@E{Ye
zDYbW2JZ<;fc{5P8A7>4Gwpqwmx(`W&iW^djK*0+|G4qg5t#}Uq__cqv*Irs~mt1$d
zI}3`S2D;VC1SsIpuJ&%J>b@7&uPEJc9+txUOhHT313ZtZTX$qXKn>fhW+<plC|YEk
zjb$*#%sDfeUAu|u)@in5$381>0Asm&G+yIQ6mlNcEV#^Avb(pujn$WBfA**Ujbfld
z<PuN0;8c}zHph7xkt-NL9W*{I>T^^f$hB8rW{*7fbEeyDvbh=&r~)$i=U!15=b`&2
zn7))!rh+nfQxfPQ9J_<w*YOjEfuTI!j@K~_iLmuhtnt<Y=GICe<K1oByx9g-GMtu4
zGAF1c)hNk}W>2xBd$!tZ&p&RHrp~gD-*cCjrl_JlDCppggmRTonVKafjHjtw_0XX;
z_Nh<bYrp;be*!e+amy~Ma^Q(LOB8$2*(#>fM4Onh&quJH<9B1h6f3e&<P-KvYuHGn
zr3lZU7$yAlQ%@3>EVkEPS>aXHrKCriF?OnGg*wF?=fPlepE`NW8jva*H?3o6#T>$x
zhw!$k)YZap^3t+04}o{#d1>H=6k~mTt-Zvo=0SK9qeqS)L=Bv1Y|QY}(Y_RSP#ccl
zu#{@|2lfD;%c<ZtixwQyIX=*<Y{M%?FY|7Us4GM7XG&-1xYRC0y+$I)v2cH`aFW-K
z0X_6lZ++Z951sqHMQfvCEabe<@$!)?I}dDU@X1k(vB9L#D16K=vZ>Q%lG3WMT|2fr
zjO)uQU!lcqlu!9PeDJVGU`on}qOgx!)~*EXrrbXL@jtLZ%r>sAt>t+EqS12`_I6p~
z1*>3C^B3_N{-)-D8kf61e49P<^m2w!>;gNUl!f4Az358(mx)S^iQ;@$C0ZL@xvkNT
z@7ZEkTrtN6l^0t*`1OO4c|%8zv97}hZ7{rE&-{X}qsJ+7tRgCqi}x(0O?vU7`HWP>
zX~1(HKDd-AYPSMPL#l|`2r8h9+dRXlM#n0oUIRHrXkU$Zm85#^zV|MBVbz~-&XYtI
zh6h+_CyP*N6=HPna!N6i<#g5yeCxN@YrFJ*RLz}ozW0}cb~;t1F8!2E%#I}|oR?ds
zz91Hd>Pi@`uC9S1nUhTQ8Ae{ZnNV*&026bpf%cP5Ds|;fmy&}%ab&k|?uZdX>@*=M
zsvEpmBZt<PPAoxJD(ri}=8iC!+sUaySQ=6=VnnqaTDv{8KzQ(6OYPmAnQW&YGY|n8
zti<@0{4ID}{LPv)qC5sMvsw42b;=Q16H(BnCXOk_<5fEv`J<ZZGL&@@U>rwLq$mNZ
zen*ZNZ_hvdk}X>{(!nxn8xbsOx{nlCqL?S{g(L(U(4R1th*k_9rj{RuLy%giEUToj
zL#RU9uTXs%I<R6>^W7J`XWazvGYdz!qK+y-Pt)@8(u*(H2`1G{r|Npw_O0ILwD#?_
zc)L@4hVe!~OMdX({~+R0Y2!$X6w-Ee_{b?{;r`e@bk~QxH@c27d}~Op$O9K}$UB-y
zMK1CRdX<loLfF1@hwa(3(@Kg8+{h8qmfw)Z)QKuHh>vv>0+CWae%b&4|MW>jK~#3@
zYgJR}>{lVI{T}arH`4I6){JU?$oOu6mc6ytJ3{nkw$;`(k<Q4X=Azj~vcJvLAB-M7
zg5t@ccI;rSI(R(<UM3VeXlDq8e3f{aZAv?+5}aZ$*DKz31m6f<jgWUIQM@qvmTWH3
z6-8o346Cu@Ow?25vPz{w3wh>V^o5K>c@Zk%YG!I$1$8D)JBsXZUs{XP!kSmjiqbO3
z$uT2`Vf5GeK&4KK!Sa|tUkP09CPs5k7&qHn6zglrUsK8LZDp#`mf5euJVod<ltZZ{
zRjz6TDrtub3Lgt7q7;^WnTEf(!55IrTvI0^D!+WHie+M8zuw9>mC)Rlj>7V({P@07
z&~bmD7NnwjFd<wfY61Q~h++h__-x0*-LrQGm4L+nLp%xb6rn^)>;Qle1&pCo0Y?rf
zPzR45vBAKz6_sS$<4?Y5U;6Du5S}I*$-<RF31Qiw5~W>234I=o^tk|99HRJR^=d+y
zW2bwb)gv_-8n~Hg?{rL-0CYf$zwY!&k4WL?EE_gt1mWuKHs_*+czY;g2z)CA97T-x
zbAtwJy@EN#Dnx2wq+$tqRZVB<gy}YI+iBD0EwWA9cd>>CY}~{#D0~fU2ue7Zt-(@_
zXS%8uKwe%2>4AqHe#~kKNzJBMN&^6b(JyZynJ>!Z+28eJ5-mo_D|sI)_p4zDYDL@4
zY-eF>FJ$V~WtUyz&pu<ube|8cTy-&C^-VY3WY0XioV-|zS59AX#S**b$}8*}|Nd=<
z1{G+Dg!Cr*rB9wXLB;MEMn%5rdF$W$(r?+{ef6t8WWz(-E@+YlOeTg~Z0hu0uilh$
z0ZH@1Y)|CzUzn4f=UJd_dBCd2P%GWAkz;N9y48eR8H<Ubs?^mRufOIaIZKF)Jh5XZ
zbqNJ_{3!WnRomkLxKTyK<mAD6(rg!dFZ-*j*4S+yyv4GZV5K^iJPdyiRil9NWW3V$
z*ugq<K##f9%!sBoZ{B7bw(qv-7hT~)CmbBgyDeg`vHP>8RmK-^vqgsm6nT|Z4zZ1!
zx7#(>Ot2CZuiE!EGH<*X54R45%ye&@o?<U}Y@(~61l}nssq#Mjz59>YMHH28-?`D&
zZQM>R%Oa+s$$?N?mhjhcaohlr%ust8QihLmsdFhV&$H!EJZ+6k$Qne;V>`7#?xBWe
z>PR`q1*hk(pflmOzNjpzn1h0jBSJmzCRWbzc|sKFJld?zlkDG>uS-|RV{IalDxw)b
z?IO>Q<mNVDWkD>pRAOV9)g5L3Byn>ffb14qi?>`#K2`+=b%ZcaoNBP8w7tmUefZ&L
z2v^OqIrC?r%%xDgDF6#Dpauni^DvA(iyUpkkyiWqx4w_^%Cj+iuemKMS5S+U|BDs;
zyRrn)Np&xw$j8I*vTCuwHSc%%!>jF;SKp-9b|#EXwJy(4+gKOcwYk4S6!P9Z2mSlG
zjO1(}%CLUJX4`%ExZV7rkJ#(azi9vOpTBOu^&6jq=~R#*D>tCD#RyNK<xXp?DONeQ
ze&Y`N_pg7?hL4@eISF%l@{F~VRqP(P7%H?ML?smO=Hg_0?qJ{qFGULZnde`y7hib6
zhEx%X)}3O2c)^?cWJLjxh4N&D99vG?lZT)sOjw6D3c8L_`;f=_s?v2OVbDA7xWi5!
zKY<W0K-teHJl?^uh(~Sz!9zat*=bZ>il+@i-9zZ{%uLFrJ1kw=Hsb|3&jZu-LAxB4
z;EDuN+Dp8LH?5uZ@v|7@&2%vgA2rp6jhbeM_mVyvTu$g&aHJ=#g~e{D(_T|JN)>Vz
z^(ZHf9iSD8`WIBxks~Lp?M$&vnRgvt^)CA-dg&{udzlQ#jRRLG1)&f(#=abYZ1T_!
zcqF!f7kBO6Yya@Ie<L(J$OaFeh{p&8;&im*y~;}sX^(gJ)w?Evm|#wcjh}gmy}JB<
z8%&k?*fFEMf?IvwP4y~H)o=#-o^ggw;rT1wm=DsRa?;CRc+qkSS%djYZ68BqzQ*(Y
z_V1R{GRO>a(YpgpDdnZ2#=r*x5OQQftfgJ+_S-l9?Yp!zPIb)tHs2^0D9$HZM@KMo
zZ#pxcxsWRulx`BRD{*dD)Ir+CGS5wm#CyrxeSdk-JaDIvOQ942FYuyEmf0W*HP)?u
ziLlC1Cl2A4$f6TH3l_n9?sA%~*73u$trXCPWjEf8GMVmuzKfP++28!l|E5yA0n3l@
zigKi~SOHTA3R=sqYpTGk9mU*b6Q(S(Yp%N!i%uv&A`&Se0hlPfojD_&S2!vvzzzM&
z{Gs*`Ld!SZb{B;iPgB(N8X?qtLU#(;D~zOqBc%tFa})F+9s_q?kAX3$W~^Ox%f~2w
zskY0mz0KZv{W<&OC+;EFFNjx7V`42*!bwUoD0HVWhrkygc=BxaCD+)PDVO3Es_zl0
zqiaPmh>&{`C`GE}+y6Q_HhKoHfmy(TY23h&(2Uqf)y?WdK6-c`bFQ1nJ5G0@s=no^
z%tcl^)ASiLy?Rw%wgif1DR(l3X&3+_WhE7O6~Kft<U+8HBAgX3uXIfAH^IbydBq!c
zC4JPFU4DiA;ulZT0yWul*v+a0kBpZvIV#g<mh;j3*mSFUp=Eo<>n(wlh%P19J#48<
ztAz5-V4I^uGR-&kyj~wyh>U(2U@C?bpw5zOZ?!FNzHB?Ttg+*Vs7iLoSw+!waEXVU
zrJz;xrOu8l3du%N|FY!9TP(kHgpHY2fe`AjKlsD1SZ-&t6;baYdeP`c{S#cSz)Z5U
zsN+CktDveCu%!vp7TIN2-$M9Ud?MqxH58XcfENRiE&Z)$CbCD5+kn?Pm@4h7Z@JS}
zKfl~w07E{{r&zHMj=fFy0ryVJh^NHViY6IM_qUCkwZP_Iwakv4K4X_$eY0(UYlZ#R
zZ~hua2&qRR4#H^<WfKAqQlvl;gP^#ZF?idvD{1Mx)<#d9YZ^iBFwXL@onOL0ibO4U
zhO(l+b%{UkUpl!2aTyVQCeIxF{8Zl5T_$UC0{?{1-&YD+YoJ0UA0N&pwE(Ml^5h|$
zwH9(9Ov|Cbt3xHmcs6o?JD`+2_i{9O3!dRS?Rbn0M-SMj;geAI1-5U`c81Z{U>VM5
z*Z|BIg>%JF$yJv(4#Y{<X>v>_7;MmJ$0$;(9zGch7eWzAj*xbw#~oGd?5|9iqvsid
zoQtTyEq-mVJg=Z=oNyuR)8v)UP^mtcuyY~izl;iD9ZT7Hi5KBKp^ACwmq1#mO6{br
zq2<(3o_{DItCO?~owSLQ$Jk&}2l5U>@moZYk=j)bN#R-L<Bk);tvh<q+D8Kiim;+f
z*DEoz73vm>SQLfuNn=>sosRaFnIh_MEtB`vKTEm)?rRsVS>)Mi{Zt${oR*RM?)wz?
z4Gf{?+Nw92F!cP37I|^k2*RJf)-1LrVJ%#ASul$^;{*m^sNY!C-}-zWaG^>8D7rBk
za1$M`KF(ny#@eNeukgO)R%lUG@iMaX@_e}NEyJa`(26(RT4$_`qx<i64wqZOO!IYj
z_^?Q<`ZER|3s0TlL%X+>;VXlM^ujfPVDO*N_j2*dPEinej2`7I6+u!|ie%w}82v)Y
z6AGH<Yb#fZLQ-h_48>(l)Eyk%x7)@~9||g6z134|FbOb{VbxTEOZm95FWC?f7(Gm@
zie$d4BG2P=R@5~y747&TE5cK4>!4*+%3O5lD12$?JI#`%qlt5oH}UR3&d7r%A`0qO
z$fJ*bbQBC@0+|!7I!IK7%?e`3@EZy`*W1w=P97oRc)|)sR9GD{qW17^3e7aEW{}f*
zSJc%YYyion&~cz~Hl!CyDEy_MOa*h*!zLoU$$`rW!Z<$DCFm&Su$i&$MqsL}&X6|x
zIV{sPi?8eyEE<ph1%^(Dr=+(XcU=V3!~V6!g?XM|+F5c%2za>2H>xR@+m5YkZ0u-=
zhX0fkDWVOatp(*Rfk>NBD+2aR7ZuIqkOawh8Ze4CDg7^|@Sp?b(_DYhzW&eufHE5F
zZ7{yBTI3!II(W%#<W`F8{`()XuYUF0cJ-~*7>=McMIt5)GLI^b`dE=nH~wr38Y`JR
z?!N;CEGtfhU8j!kw`ZSv)Na1<S}M7xxyUOiD|XD^4h<!M0enCKCurwi0R)tfr~A(4
zEsQbzxm|x}mA(GbGj{z|v+ei(=qp&pDt?gw4eJte&>_4fo#I&5{8Ux)?|%9BZQZJ8
zZQhl)u>KUmh~Xlk>)`oXmM9XHdC5!fRY<Qe`d7{|r?@ikuyPb`=T8^X{Od$n3RNv1
z4@r4+0l(-u)X%J!Lq9rgNYMz<P69f-7xpzEQh5h}7w-Wqg3{JNdvyl5GL8hT^3VPa
zkHAECHxNDbE^ypHlySPt_oi)Mtgv?CtH52|zM3#PFZA<dpq!ne*=u2+s}@75v$L(<
zRxJM+k&$|bUhT3f>Q$;$L53`$#SmU9BsC;MRvi#(ftE4f2+hCw{8KiF)Q6N=IYSfv
z?(hGVs2nQGd6b$E7suLUIT-<EPdp@VQtyB5t6#UDKmL?0yB$bf4{OW74Rn>c0dwvP
znQs4!Fd(+Sv(|QPTx)lK<ikYifcRA}bP;Kt({v}avuZ3tD^7uXwNkL;)a4Ycc;RJR
zNh|CP_kO`%c=0J4RgrBseek0`YP1r>up+u5PJ?c!ytPKHs@owRawMcN^+VtP(}(Tt
zH(szyueu#CS~=@jA&c+g2DA&$IGON5(tFpM$Hr#7Q_(#+9R>s3-*H9=pXrnLoq`t9
zPZ67W^5`ClnKpxc4D(=_o^EWnix@^Qjb7-jTX)#7!8Hsp*zWL@H57zxr3gxGR7GV4
zHjE0)O>5uq7MkDv{r>`j&kzuCD2VcWq)(7`A)EU0VtyE^nd;`7Z@vzKQwZ#Bn|1M0
zm|91wbs`RA^k%0Ep_qF}HdhdF|E%tK!^ZWrna!{%GbTgyjr3_&Qaw4rM<ur4Dd$m5
zx^u@aE3GI;AW`*wqLwg2p3Pwp#Gylb?73h3)TT|GY+v}b-{AXvhn!r<^&|-}keTu>
z`YnX4OG+y3%fI(U`{O_Pb1=K>C`zlrIUskY@Ry7i6@Q2%<q`Nh=kv-`8K=KSXvqlY
z@DO*@Uo5Xzu$r2_)WR@}LI6q>L6&||HK|&#9B|4#=x}Zo+o_1hbF9&M<PCUkSvs6!
zbNRdrPb}2-s~sw=T?kuhQQQTHZYh4Y^IM_wS>0dCclF5UNd*_|K3RX?BN}m4Ou23A
zDm=HNHWbWq?ORSxsm-6ggqoK^+p}}GrzW0S{<Mu4H`*an4}y7KkW)xK3&vO_7z?j2
zr?{!m{^<AroRk|z^D#h9WEfKr)kRo5&P)3JyTMFY7d|e*!2aYXK4z;{zh#GZZMBh;
zRo@b31#olGNXP!4`a;SX(W+Vi_wC$jOBP>hRYVw1)-&(}9R7(D$Jw#NN9g;mq{gM5
zmQz~8=#6d!aOY&>NuE8=7B5|7M^7BE)hnL{Dz)9NSaKEp;@NhZs9Qy47I*?x4$w1m
z)<g>Awy-w244|Pho_uu+9XBO__*`@K5{#A?@y4m;sGv}cXsJ>QA(k4tXFNdX>BVz<
zrBlY4uVYZmft5ovO+4*vohUT-8}z-8T?0R!uf6XSw3MhsY$Gsx%68_-jP-md!vKhD
z3)sFD@Qh+WM2t49B2av0&zWWW4jtuvP1lj9U1^7b@vE*HY~x0cBaBIy*S#NMdP~tJ
zOXd@~1QjF@zE(Ip7q4^Z&?-B${-6_zSA9oTQKFsb{Pf7#Db1sD5-O^q4i}Q~P|vL0
zNz-Vvf)G>z8uThH9C&U5TFCV_EA!Cx88FHljw`<wP^pFwud$b2ecQ$`yrG0Pv{O`Y
zOKJJM6`vmFCkqN&MIBM^wTQ9>CL6~0OYs&?Qyo62cq|rm2>UBt6v$S?19Ut3>+Fk@
zWSC6zjhQlLV5VS3MM~Nk3#?_@&R%_E6>TA<wqVY5dxNo#hndl=3hnvx=ll2SnMl=4
zSXu>T@4WMlEnK(|r5>iF$;<ZYcJ@O>VH%L}>Z>b#*hN)@qb(p483ef)N?OBKD#ATP
z7Y%FZ-b$D0Go9OUnRp22cIMP?rP=FPIY+YW{I79-XGr*99)8aCXi$ej-RzNL0Av+<
zB&ma*WXTzM!&yW`$|!UiNxI_bv3fR;kT?7&l&uq_+(u9=Ik=|U(;Av2r|NJOglV*?
z@ah8vDgq<2ihw#m$to!=vf<U`<ZLNIbKoN>c2Y$iw#n={FXX<89y_4XHlmJ$!HV#f
zK<}dmYnzCix*qf(l0iac96frh9mMEA(s0s^o&w}SMLCn+4jr)(gDVJa7ouP#Ka@IZ
zr60P92oq5#0Yo8VN=gcC^r+Eb4AgpisB-m#X|u{DbgtP7C4|Ra{*bzii%mmB?EK;|
znJeSI_8?Z$!FW$@RZ`A*`YQe)GW>P6_nm^)0%+hvdHG=SMOdv2A}B2`b8v`l+cz>}
zcOyUn753yWwiEU(aP*lS+jn|@s<+b+I;tmBRSNcPHU&VdLC(4dTx9p`ls|UC;X&C*
zj|8j73&t=23b<Aq7T`PU8BQ>GV#G)Rd?Qrpy_=djNgyK70O1(zI?SZegNF|sv7Chq
zP{?F~K`?q}{U%o^f-)4Nmmox1P%_G`D#VmW9zKsq!k#@xfZ&^9J86rkqm7~h5RDcF
zkOx5#n<??L>0wp860TjvvFq2rVaHFk+Dx#@+nAmuD=LKIQ@p}%#G9GG$>gYv8LUTw
zE_Pmp@|8!jt(I|(Z>?Eni!YvM&(T6PdCC-5xEnzS(+ubx^e=CtxB1hb{xo4uylsTg
zBac4pp7hN(-|RwNO8mtapC@W@+6P-m;J*zN>fytO?53M<^n$%de)1?-#rZy;StBde
zx~1uH?-u1;NTGeU{YYEIEgFdGIzlyfhMFdmjlUqrg!+xxbQ@GNf_hIyJrw=Wl)N+c
z$}2B{oJZ#feaf4+thapl<rqq*1;C9WaQ|g_s=h$rKto3ovBFE-MW@8#MdR%>^%zoS
z3Ii*T>|Rt9T|rklALXLwicwz20S?-{bH7cRyTlcigCm8RSr_C<`#VW*K4KsUGE(iO
z2M->#F{8#>F@{DhM!2v6%4l;vdKe=g*;<5wdywvg24U0#$dku<w9rF+@Bl4_)2|>Z
zu#p^lGlt7>YA=BEgy!WbYvDI-+T_DuB%jsdC^;pWr8U{Tbr&E%7(W$*NIOX}i=I5J
z&`mM>h~aa5Wh_53KEF1$`=03?FLKj=!O!v6`%Xctin|pdr#7qUGcP7o{fcD|%BLWT
z-d=_`v@~`Ca$oC(AI-TGD?#X|>W?^NUoM3n^#GY1Ida@Czv>n%WlGZze)4li!<s*D
zE=ny7ckt;k-Vh(cklp~mc~ljC4Cv4Ye)gy}Hf7t~MRTeCRu!{|MG9UT=<GS@ZhM?*
zm5+O#;ZEY0`z9W44JuH>9A?d$ZLdAK!CrlF6(bL+IL;GJH^Ui#S=0A@@)sUo)1gMk
zy)8m$oMLj*+BeqNzN0O+@cIwi)_2y}U;XXh*r)HihYERto~RWh6qxz7q8zGx0975!
zli&ExTlSCt{4E<jX_4i@oTpXEi5C(mQY07^2Kneo?ztacN-|7lDl227h<o>QCkk%(
zrnjg;I{+cfg9f&4UPq7n8p3a77<wf>UQ)_g6QhO^!qe<!J+msa72Xs!yZ(OS@yG2G
z_uXr60SWrR{Xeyj-FvTX0_yPi(PMs&=`*L<6Tf)E^Ov2t2d}JL#k8v{yr|3-bPB>(
z#&RIdfxir8oO#R7+4rxPvd%DXd_L>b^SipkPzS&;2ymcBjF<pg*c=q_PV&iv=xhMS
z6K{|56VhlW9qdPy{95Na@DvJB+QLFONY5|XX`8<AT5C9U+`jhzzG-cr@3bisM!6jE
zf_o_zXfIn~ZRAC}T8%LB6xQ0cyVkz-od+zdc&Jql8&3@lMOcblsir}xn6uAOO?j-$
zcqS92q<!upGC37|gw?M<MV`2b7PRs7ok<e4Q5e_c2EK~_vdI~rATOVX3{^X8ZF4OX
z0bjG+;?XvG+Qqb})!XyWy=03ny_nQn1<@nH%?6L$Ws@S8iV7mzHR81kWS4C_j@gP=
z*3jm)nDa2?MR{&H(W;H{f)*8tg<O756DE`AyD)SV;vosw#iJdriId`5GA}A7^&?ZZ
z=>4alLoKow8Z5m08i%b^FZAA{`+dZs6l+dbkyml6TG%Uxjp74&C}&ETKs3~@zxht9
z9!Z~YZV8|Ox%Myr^bb}GQ;A5tr&#$!DV4|&3c68M+=Qs;@tZn*p<M;$G=6vpC9AVu
z3R-LLNT2%U+^ybT#FkE~=rU0#KIBq6i7HgtwKv_)oYfcYmDk>IFngZ??Jh!irZC4<
z|4;8C7O8rCYer9@z3O(9>j;~_u+Vm`ebRp8H-62!7*m_Y$UL=sC?p#gL4zDf1$di9
z2#;%^#GFMp*pTsytdUD~kZa3Pzo%MB9PlN;p9auSk>rK%Tg*gByTg*g9A4|i|Ec&(
zZD^yI7*$QN;Mc$L4L~ODL`jztvOGc5p#&JlyXaj$0d!|61$a~JnP;BC&^uzE{p{y_
zAAb7NpE~0;Qi(fz&TK#(u11N!;bSAGQQ>{vb=TSb58Mx!LoI@?0K~RsHWbK26~=hF
zBAT9cVT8teb(YMOL+`sgcV0Q)Ck;lYcnRJn@>58)@HIDlnAXjwZ3~9y;kHwJh(;ox
zta-*hMitjr6PA?15$a$r-s4cBPfKpP1$_QtDE5)A^#A;S{C7gc$BFcj+5j~yN7cuw
zdiG)}(i<|)$f>G`uoFnp3DXzbq9xZ`3q8^v+6HYb&q048Cm^GT&2$g?KTbT=LLPkh
zgeergwb^S#hK?<N2~U>7M=X{+$yOh^i)?gDhkHedQt5-DE(Ek?zFl(F^;S<W^_<JD
zw7qMe$B=zA44IL$kZ2)GeK3X4Wi%NT<5f0e!L>Gg9P`#m0d(dfQxNQ`YF7okn&R9i
z<v!FR{h#smzEjXrMk4-DkcGG>tVkj{C{{eTGgw~A_edp#0;SMLsCEVQGUt&WbPN+L
z*ACuqpqMJ3_cWVVVJZjVh!k@yHev-WBG9l52~$~rqLWbN9R5q_<P4Q_rVeyE!VAjA
z|36`@`J^x9LMetD13-e%i*%pfHs~SzK+rN-^c*>w*UVz%W6?UAxJG$unL-TCt#(al
zl7iLD5TzD;kcdz3;azg7@&Fa$@|UVAwbl;H6<NjnRA?{uTmwqm09s{!30&s`DcrWx
zh{tL6<L`afzVb)^)%G#HN6#k6MR_#Jp>5u>g#i~snLAQsqZudp^z!9iw=j0xINt}+
zqsBsNx|G_qa)n04a>(l{0QyigTaPy}id@^aZQFqUJjN{OWu#5Qn8?&9#V_H}`@KZp
z9{GP#iP+<bgTWS8;s?N(c6!_0&?oHbJ-w14j+zHXzlsGhdR-35_>}x{nH2cJ`3Ct=
z5VZ`Qq}}QagMCPBbDcsyS2v0HEaCy22*syL2Mu@H2zct@y}*khEZWWO>UY;J+yRbX
zz*@+VEG3myHIx(pb9?nn>Zr-VfN-!E<Y_x=L}m>!3xp}Fqq+_m^Sb{I>Vmph*W&V0
zt74?4hJyrIp(P6;HRZAuxD-Fh@hPgP^3*`^IHTOXdeB|=Yf0jQPsx`H_sp4}DahXt
zuMRg5vVQS?C2z{NwZ}caFN?(T2>VD0t3Pkm%g@>d!089!^$Z(6jv|eGyd4U3fRZ~6
z5>H-Uu~#r>XVKEa_p-5qg;)L5V?QCp-3X!OGs|?H{kK2<Q{Wk=23S49o$*RWbzjla
zi}JEK?`iwlPai@sKWvv?^C1lD;?Qoy;=5i8W<lnAoaV^%;h7XKL%#|hF9NEN5S3SU
zoXYlfjLG{r;pt^pUYQX1?rA%t$CihbZ?@&BhZ~{t(yBM?M?d_r&A<Euw(0FRm|b|-
zZn^b#LcCxK<1uPxwu+;~qy<2wszpfW%0YQ)oZ@kivlPA>)zD;97F<Ou8-h$$u$Vhq
z4>t>>w-s%OjiCNkslQlw{QZoVTMHMbE}|TkM;{bVP@6|97~C`Lum0-)kn^gv(FlrL
zZmDz+TZMC_Lrd+_%NAqM6@e0VC;8(Vd;Qf{L6Z_v*g}e18d31meWIGI`de<k)yGfj
zRaR1FS1!HMe)hAU*{p@L?eWK-@DTTe2@^4bR6rCSW+0)t3mwkB(B}&RD?He{aqj-e
zCzH=(@7cRBC|+u7ueVp8c>t{bz0_7f|CJM&bzUlH1=<y*sF<__uc^SvBT~Za=6m%N
zTt4%_kL=pp@1)}RsJ-&+FHmRzn2a1xB&Niw=_--_K78o7k7iUJwnIQ2+@y+5TLA=F
zv+^bK&`oyH((9dmWCBn^<vbMHkIwBi5SmK8f}XF09Q&S)Ypnjj7W;$W`yCrUc^Zxl
zT?z7{T|v{M9kpEgfE@N)&!wRjKYQ@!bh|uc7hnHDduzpVFc*&54cFa3e!0vGCxy-3
zNXJBDBS?^hwFMR=c@k=Cz(prD_ssJeRCCg1FTC1LtMJsLfuV|9=x<t=&<FkA82w(@
z=|mLtvb$=Lp&eK3`%iaXqNGlWD1YC1&?<H+Bo9=3d>;^%s~Gf6KOJGI#)dY#c;S2y
zpvKuwig|_*%HFnRH&vD=fX=JJTiJ=m$af6yY;d_Zy#5kB!X@^5zxTTo>s&?Xk*aX@
zuHr?zMeO*nE;7SEl!XYgxT46u_}jl`+jdbfv}KjeT(Au5P@5BKg9D*t#!SJY%2>N3
zc}KSss30NK_4nGfZ&R#vy?x?S_k#ai>*v-X0ii0gHkDUW?<WLPpq4d+%ct-8Fdzb3
z?MDxO->Og~A7(6ERw0<X<lf3DJR3ZS;xn*^XVY)K6|XP9s0?GMoV7iUmyyMqkK{dY
z%~3kzr(A^MW{tg3nh|3{Tk<xmAZ&8tikx$kHRt)Q$UupAHd;boOE#kep^}evKY#v3
zE*#3sD=73*9zNvqRfWBD>9WM%?ReEUg2}CU(K23C$t}TCU0v;eYn)^}oI)PMq)AgK
z6uZSe^ILAYm7MoHZ|!QO1upiS`|_ZFRTbQMZpeH7b%nO&Au6}5!lq4IUbTbAsW})v
z0_8*TU{;AOn7@S4lX-Sv{~;R*53G27B_3~;^ZC(3$9(>L&5%mVV$9^m*Pmuc52%FY
zxi&~cW1tQ23vKb`SKFGkZ`r&B3+=$ZgI;VnhI8%Ra{w>>j8!lfpm21F?b*EA#!m%h
zZp37aV!o@io%4BSGUa?0w5K9hq_UGiLOZs+V}J37ziwAwak(8kS#NEMBoLB!+y__C
z@@h4O3R#0u+eN2~==yhl`}4MM_wU%7FFtN<bw})`Td$|+jJeLNNdZ{fLns(CI|@Gc
z9LBV6U=Q*!Zb#a|{Rh3HW;BJoH(YhGJ@CkK8#iUP6_gADzd-|!)G-lYK0}$+d!wAY
zt@Sy|^7oyBR`^tqm5mf6Flq%j$|~P10nZnfm)Vfvqip4h6*hb3bQJhH_OHvvP8ef*
zDCnVEz|mXE@rHIE0HKCq22&?a^3j1UgkU^$u3{ZofQk5Xq(Bwg7Ah8bp+X=uCo*pC
z<<~d6#iS5eh{7mL9EztzwCP{TLaTu*=MXxHBj}#HBup)|FNNTmX!@TtWt_E=2W@K+
zD24#~L&)EA<bI1v&Z|`cg#`3zGdZ*(s=cR8pJFEue8WaBxP&3{c*$6^DpEO(qN;BI
z(53mb&%bSJBeaF*Je(1eCr=#rh(jAwpa#<(l23fAk;0Km!eDB3^Fi}0gFI<xAvYA1
zd`R{ppG}|y%Q%CVw^^i^rG2fuTd*<~blw0E;$t3#mgYh_V2{hHS7^Hfbg?krPKHis
zYHVT<LLv~sJDQ%B=#7RBIt1+Pz0g`SQZ7mfh^F}OG)j9a9{SYjGyFR$4(kv&gN!@B
zMxc#Mm2tY`GWC|yUn4d~qXmqYKVI560OJwK-s_#VirbHjy$UT|l%DcvQ{;B&bP2S&
z{`NaFn&@i{d##W52l`RQDw}jfQ~hylab$sbi@c|TIKzjGBB#n+<P+;{!NQB+hf_A3
z;U`thf<JoXSlDCkzXId^D7gP>N2+GHLkI77QCM|KIPDCTIDBZoEnTw6_JcUq(stU$
zjUDA!?M<~r^LT6@bBe@nq1U)`7;m7kIu%M*uf0dh(m#8Dd!D)${T<tF^?CLdqGIY;
z7&B%JqbBPJQ>$=HA#T!MzI}Mpqz<))%FU~&tP>e2#KxMzl{RDYSbO=6Cv5`L1&aYq
zY8B`YIsNvQCa~#wPS&9qFTIQ0wWMen-8cn+ymU5Vv{Jo2WKbo1*~Pxp6CGtuDNbXz
zqNNC)cDhv=&~x@ja(#ZT;;#_l_P8ATohvXS-Bs)hIBjd4!d?3Dl0*8ZDPZS(?O(w!
z1_eXDLv2=-)n1h?MMOG~GXGq><V`?u?gNZ{5Jf!C!Ep>WqgbH}q9`VWavE2+fbh}@
zdZ0_`fzB(fw6z<z+O4-u^Soe8$O$1Cv~JWs73S*}!f?tbZrQZcDh7{WW8xfi05x><
zA60dqWm5;Pn0uehRh*Pxq&#v_E*gQjaou{m4NPFIiDt<Pj9$vZf%&BveZH*9RFuD$
z{Ym~FYj*YejW&4fWIzTOBZm^!q%ie<wqb45<KgAwS+Co&4WO3_hG>*hy)GEUVxT+e
z-{kKD%-(Koqum1V0gV9_#&8h9N;2u%D(;ANTV_IbV8Mk9&*@tlmyyS4;em@B6-=um
zgU7cpL?FWd#pf4?h5bnAFaJAYz=Yo7Z~agE6CJIeZ4oM2a!12)euhj9lIY6=J^n02
z8J{sBNc@eSIymvS46gpYmXIQfl0GSUy0BXDLo19C-&y}gR;Ij@@!I(QC}Kw5lOE>^
zU^cTm)w|pUAQIRC+~$j<(n={5EG#UyUp)S-RacNN?#Mxz7BYl~DsGk{7mx7}oe)Dt
zOr(>ffnvc{E3H;nhz4wgR?kXWL!W!*W%m>-%fTXmhpGThYGs&>>P3XW*G`3U3C9VA
zu1mP@>XVkmKS0_@x7Qi3N%UnYkb)8bdvF3aZ{B26NZGX2f}@RtL_A5pkLQCOUtDdK
zyzhfA=pE0;i8&3}$UEyc+eC`RP951!H_b_8a}5~VDvHy{O40;8_gcCgis+h9tCbq5
zI(gOtTG>jNW4~?J0hD(R1!Lu&9#f%SF!1#Xl}5iRugJVjZ!jd-DaG2ALjP5{`3rR)
zYIkbILM;PvX8MAqwsG}~Ry|0g;h3PpjNL;jy{BqWnAqBI34-NJrYS~=<Pw%SNjt=G
z!oN$dxs3tf)%MTd{JuBMUo?MS@SuWZPV<6|G1%%r68rIwerEfRH{0dcUW^h85c?|p
z5OH>RGCFBK4U{R)zD_Ah$Q5&FbCUNgCYdv5fxYnj<5=?lPL=sG?nBeLWZubZQD0^7
zUgVi}sKT8}QWbeT`TZB|*_YPXmA8G$Hm-Tio_y>PTgvQW^?Wzr9eb6yKsYo2L(2XP
zg)g4>rs#=h-mwc5vgcRYq*+&44vM_(3~gOhTnaNc<n{#S;`6Y)uqO0_UdYz~lyg6q
z4My69y}Jwfr2U;MQ}4Ua^JGxqc;44Yd+}Jj_4kAq_;Zbm6(12cZKq#(+}JsG1Z8^c
z@FvTmNGTTtti1>799KOXV>Vxfelp;Q9PQh>6COY)P!MzQNF82rq0PGVHli%Y?D;1i
z#+$68cRJ4_Nqe?zh7~k`Cl~~R9$x;;^MrgkE1%bcJ#g@7gN>VWxmD8YB@i2>gM6O4
zM_`h#fy$J0$7ga58LS0`WhmIW_Ag(jZH%be%()kl9t((o`GUiR#{)mhi&kZ*Ot(C%
z$I$=L4}M?=YjbQq!->|v{Fpua<a2iE<%^jFH^_@9yN;=r2yA|N<H%kW`tIGgKfna@
z`>x&l?4=i8u_@Cpr(moagf~)VYRkfi@rVnR<Qi$~)#C%R<}WZ24d8S=M9ce1L5qb$
zK9xEqEZhZ)uK}qh&t6~txE<7>b+@L330oe1S7_IrAB9!4iG@}%Y^+`Vfe%{E*m)dT
zXfrR#v48*OSIKD~b(lx5IF?Z#<#!WHFCv5>+p%mX&01uOZ@2@Cn*uQndy==vm%La)
zUaf;p2p;mnD2@;^NeZwyq@r-Ws}tplkTR8nYHZ0>chJuBGy8{s_&ZdgU<O6YGH)YD
zJUnW(6m_Y>nEUL+z!)@ohFx;g$C;Hq!Y)}-WxL*b#D4Jof29RWI-U@)BpBE4j0R+Q
zuvgzz#U)j&l?bv+ulk@38h@!Za&zr4POc{1$UJb5-M<hFgb?o;07YN8L$!q6_9QOa
z@JocS(}mfw%<lQ!QFQ699eW)8-B)kpH0?e9G8d`8TOQ!&y~FT|@F;y1KrjlkOYN%b
zK4fcFJ!tQMEJwb`Y1bQ}r4+P8^!^4x6nSvjg*KRpOE=u{Q7axa%1UUTyXy9Ad*`KJ
z*ugy;eVC7U^o%Oa+<@0t6=9-)Q0RmdT$NM}v-wxtVq<4t4iu)kPN)Ru*2LGU-3a)J
z1CO%wT%Li*B=Ks?>1-P_f!<{zlz;no{{#*IwK^J7!FtHJ&+4KNT3qdIrsT|Z&%g(F
zkk6kn?+ROV^*vUH62ExK2W{`_=k3v-{tUR}V+!wim3%-X46-fMf`sMP%9hlOvWu5~
z5CA1=LdaWF5a95tn$U+U#P^gEiZB`mNCy|{@SXwoP#P3X+KP;QFAekmMXkFj7k^(V
z=tzuu53c6!wlJ6V)TvW8ifKWE@Z6+`J2eKb6UFI$yI5#4>X-|y2~NU+?If<-48qMB
z@+1Oe?_##}8OEgn+u=n*VhFv2EEO0+7|elq&Tz64ildaDY{#0+rYG9DTAxRR6_ja8
z2rt@<m@zUD%ITOWR%s!J5iz;+u3%1OR7k~ekEaP62?1%`xJiVmL-<{JBf;i{Ds$a0
zQ@?mT?}KikACZ2;_O@DjIERoPY9&0^U{%$_9gn(=KFCm684C#I>814nZt-z(!Z2na
zhYG>e?<uDBK^ZE(Nh&<uf5_s-A*%OANrycRQEQh6Q9dXbau<qid!HwheIMx6-;Hx-
zb`NJ;sMrA0B4>8CcjKr`*T$nmk`d|-QDrhtZX-G1CTcFG&YWcx&~_&VxctH(Z}If-
z5WW40`VEa^)wtDGW<fVMlS*@)O{kjiZWl7As+wXmO_@`{7sX_`iaN<N77Ke9ggkQ!
zU+I`o@p2ov*&MLFJ<28YKQvw#uh@IdGp$z`h*Ivg7xIXy^*P;COAfh+Vz@y}pVfP;
zm3X~_FuvDwD9kNoE9FFZJCYe~Z4HFG!O(6##rm8ie9t`SA%k6ssi@MYSOv=&xg~7!
z2veKq&LM)Q;Tt~TN`rws_3VknAe;S1XuHaEhI;0-mWeQk<Zvd3#us+BNHWIzPC=`<
zN%cC}<dffg=}DVCb(DSfFaDfXh6*Pn;l|S08<c@!(jua4+N@v}O_VuG3&cNv{a<a<
znwPvH^SPh@gj`1+xu+UOxEVD{Ei%UNh(k^=nsC)b(Uqza#ZVfczH`%BJFs(~U3Jsl
zmRnRw&Q%Kzq47iBriv)utyffn5EM+L@I23jHG1UmPTTh8Q}%@~eA*T-S>m6zfs-8%
ztML9oj@8<9pl~&!GY2<#)tWc$U%&mYHt*t_?47q(SqZR)x7~gZc;=Pl`pdjXL;xIW
zLsE}#3)ZYxyd%w|jB9Ia?OA|3hEQxbW5JEq3{Xs$02n;#5T<AO<Q|AqXlCJ+0aa&k
zh@Yy*au389O1Do5;hyRB<0ta8Loiy-_KJ(a&V@#jbrN9>`#V=`jAU}HboZV9{CzJ>
zoOW@rpE#9~b~(DgnJToBvMk+o(!7^$z5CjNUSE&Ku;R^13Dh#(?(J8ew0l1KLA&Yt
z8*v245i5lxdN;g9@tqrZD$bN*SKoA}ZQr%e{{A2T&AI?KX>B@TE1zSs71#>-rBybR
z7OT<78u8D*eFv!FD7OZRuTE1Km6wmS5`F>aSp6bHIQAc)&FTXf1u76x(IQIEEy?aT
ze!juEv?Q8x()emcg&=yZd(GNU?6AN5|NWVbpEMI76#=va1)VKW6+f8&(;CUk<>W2Y
z20i}B&+MsZe`*V^z1!Y=`4KC~s<m4`bO%MYr9cT+QoB;(#iw=D{}j@`d77zKUIZM4
ztQ#rFeD2v7n9^5gGZtL~1`5~>?kIRkmU=>5VW%r59f$-@OU+Slb~nE1b<(p4h<<J$
z{`h^Tpv6u_$~V(Wm3yYae(%40ncm#NR<B7IFj#(WG4`zpT3{uz>>zXpq~|9}dd7?)
z_B+4%>-Jy2@+bE8ws&aRqA;X-kQeV9V}9u+ix)X=^6YstJU1dp$60e{*!CTJAtaE7
z^3MSLUIu0?)3mm|ZIj7^x44HYg$GZ;y{g{qiEMK=p*<iAH>w77KShR$SBr-{)w*?W
z+Z{J9wYxra8>m;OeUN%_k%~A37NB;g5O&TcADxdUAX_w__da;rO-!R%PcQWMX(t(E
z*M8)K6sOP^d>X7Y7^kwl7z3xxW=xq3P{(E~sQ{4;2HUfDKWo}yV@K53wbxv1PdxSv
zbEGfFXaQJXEUU1ghrVR<s(M=9hJ%J?sGu{`kUftIo<%IvlAnf3?4*6rmyk;qc4ea0
zB6A~B&Y37?Z$Z<p^`pppo-6fu^=2z?*S|p!d$irpre}<&p@q?y>BHdZ?lpuWd+$xG
z%=NPubg7(;xHBR)E_DjGAbLlf`dr5}f-n6t_CY&6zApvnku;zu3n+TrxZ`b`vtX=!
z@>8F%#*-8=3H?hEBX~$<qT;0vrEes_y-12CDni%Gt{7#_4ae+jfA`ncNmzVHRRM*S
zDoiyyMZWd231e;3y0`3x>lXuIxf^7x2AeW!B9r&FSt~qLM19BTVO6$o^BSARY=Gin
zQ!othDn+u&v-Ws}XYRcinaUEs|FgZ=7azsRv+UZo+5Ym6zhsv#RGU>Zlkiv*AW+?K
zP!3<MVBAYi7bASt8;yruUY3oV{jBZUwA$WY@i>*~N9_Y2yn!_?wN`NIOA2zR&}J~m
zu~wTpe-7)g)ry#wRn2gk{rmR0VLytYK36TJ&FazRHg?K93dx4DCgh=sXapJJ@Ji7t
zWL7Me>H4Hynm$M>4s!?k*EchhTRQUnr=VE`g}564mLJBPR#jJ?0=&JGFq4Nul;_04
zJ424d!`uqBN-0Qa;91w<?P-);8LdPIz<MpI0<Kex#`hIosjXGmyq>m#@ov>N5vr;g
z0tPc>|8;eHv8WY_F^W9MgDdYHwTHM>ot9<#=7NC|ODZ6I5U_;Dc*ZbcM&a#d8#`ta
z0s_WrR&kaPeIR9d^d5!}*(^ozb9LY3m*we{F&us3m~nRe;C|pP$5;WOI02K0&`twN
zl7p+zN<zArN=s)z{;Qx0KKsC7w`JS7kHL(fE1=}Hg|@6>LhH#^DhV?w%#a3%)pO5P
z8R%N{P&eI}A}O#_mGeMs>a)wP_|sSs#me?<3OCggjg@L&&)lElj&pWW(r%nZ%GMFl
zdT6V@yy93X$De!N%-g+sc(y&xr)#BG`O>waT`YK;q3tAuFT;w3b}QG$y<ds8#<Q<|
ze`}N3&Lxj>`@joB1w_ku#fDlYD$Q|3zAmb|yJ$u9Xq;M$d}JiE)s<TE2Z9qcum=Hh
z`V4JTOmkA}Tq{E}DykWRg5jP+8myT%#s<8@6JRY=(kGvtyO;Wo4hqsnJD$4+tEj+A
z(3g4qY~~(H)FK@5jqdBhQ*ZB;>Pe6KTl_2_o>9X`TVpMqE)-~a8W5uaSHu^>T_M&{
zz5YgczP+uP^jDWv7gpFr5DizXeZfYL9ExLw$Luqma{!EDSPz9{ZKM@Tz#GsSs$i^w
z0<y!P>$Oq1+u7bi0dN@#AD|?PRg25$J=2;bTJnPT9Lnx8SBgEK{QPLD`*q!B@hDmx
z%66)c!=1@XM|}0ZQqb;q5hqpEawSuMc5d9rW*)U+Lq=Nzic|}cEoDruIXf4{EA%im
z_*2y2twj*cpy~=+{pM@54mDZL_%U|m&_1u`_8}RxVjVto5CxoT8`iJ)#T*J+R2?&p
z3#ryD%9pjxhA58>mlo5KA$27qK-;7cZeZTNMA$&ZN2(wZ2?k<_jRA$V<pD_J${?;{
zG~0#^Z`mEUe}G&$RjC*l@{^sp-HTPeNCHy|Gl$3MAiPFwf%B|oNW{oV(=c}G2~Uxa
z&M#LP26-Qt1Evye<tApf3cgQ+BwFzbii-*mNUh9?EoGY3P9h1#40A7Yi(0}>A#O2a
zR#Zf%g0TSW=dRPaFUA1Ad9KWtNq#R@jJ_w4*Vxys#U5qoT@TiNCf7(kUo1ew4C|x^
zq`$R?eRUux9GmW?_rp1ZKuPXRsvJq}+wXtj9hD7Q5vYqB41IP*^nb2%-MjwJoXS^$
zKO{H0NMDsQglGGvz0fWtT!pl8wz4+LU3mn65I0brxe*knQ!t7uk7+v<gNp5~$JYU6
zIY`z%9y0Tc=^O!9%MF#iJ88=#&;0Cjukxi_B6sB|p>_t+P`^PfjS%OW8GGB2TV%ym
zLw(&eR3n5J(#w<cF={jUu4+h%nSRF@5dd7)+VrWnTkG*AqLcwkAO~ECEQPqEwo+mL
zyF&mVR0$|y4b4rqZu<@!H+7z!Jh+a&=c6d#;TZkFQD{PjWFc$U(PmXhuHWfK-Vzas
zT*l#+loZ*%?fY;<^6A3CInW$vui%Y9TQtJc&(vF%{4!`KJ)NZs@uVEt<Ky?0g4Q+&
zl%oa9s%F#}+rMY1{mGyFseSR+f8EA0Wknz&XRvTPyGp#JK_0O}&e_?(eX3Lg1+jef
zEB3cv`$ro+ah?rh7WAX{f7_1k-%T+`wdYrNZQtTvsfYHspmNV|ytcx@@oCuuj;_OY
zZ#%+(iCH#b8Z8GHgt@Yqu<F#?r?7hHGVZ<;=@=s8T&b-56dn~phEb2fa&*syYtNs*
zh*pLlQvLZ=yMtU$0Y-%vaNq?5qK-Ty7)tm?suFEv1l+&=%Om#Wb8GCH+dfO>>dW@P
zkA7q~UVDwVHng4ydE|W7K@kNhg1X~JyzMHVS==fLS^e5Ow*2`wZQ8|*Tm&hosjHsc
znoMiu?1DnpdgwPn1ImbbH(%$%oRWc3C?)h?syXa57Q8_H-RO%v!`SoH$`>I}3+buX
z_f%Y{f)_y*3bIhYOF_l^8!KfE&Je<wlvsc>%skAkYv%)`5tMVZ{~l5c23PDo$6l-U
zNv%5Wxu;p|Smvw$R`(i;b3({6wlDSUf{@iqo}ure4oOrSc0aN1FE(2IUO8BvRN{3O
zH}G8c>_X7c8LVng6Vbabnw~Lz5nUmV*kAtHpV__l-siO~@(=^Azm^D-H^P(8R-qK{
zohB9bvxk3f|M8s%>1MbUo&xssq5G|ZK^aw*MQ#@F*tiyDq=*)VvGCndLeD+(6wxL|
z*m9D(6DMrn;X0eL=xVB$M>^I*wuW;M+3Pdva3L1pEa%Yv<>Tngn01N$^FRKpwGjol
z_|nC8Mpiu$fLw1|k<lU}N5yW?JduX3GkLcE#7_I>*Z<uPp31RHZ~lO-d#TeN`sw3#
zHSM33HAEyS)Ri0&Z-{o|=*!WA`<%|Dh}Z1cfI;(`O`m%;-g71EOxjL)XAGra^sCKE
zvMuunLpnK}j`q?UFg-ab<!|?z`ylX0cDwv=rcW;VubhI8@6Fo=Qf@RJ$JL+nsW7$#
zW-A(N+QnDct1moi|NXE3!N!0fCdJsr#&uGWt#&B|UmO$K)e-+s4tm#~J%E%9w=vT%
zMrRe;#aG^DTVH$1jx`7&N(EKndr6N7BJc$cg--f82<1F~DR7vCY&tw-6M`(RmSt_r
zqm4Gjzrxqk1B*o-aR!VQo+o<wuR<&fbE`E3z6*=J6cB(J7hhvPd-Mf+eZvlfi$>wG
zUQWc3*Xpeazzldl1Y!Ed7G`K4vsss+T+2t=%!OCkYoICp{MnbuH8U(-xpk!ggqG&v
z%kVHh-O4>L(gF-vA2x2bjRlaPMN@bj$Uu4c5Z(#f?C}o=A@KL4SE9%1D~ISk)2@(o
zeR&c>cnhOH6?gP8fht0ag{Q947n4Mvc~Oa*3ZZw?`!_wbD`c-`TlLyYU@4!nspJ6#
z)hUf6&<gdzO8H8e>7E3udf)&sjhreUB{vd?!r6@b+`w$x3J~oC5$ax~4{-_J<kJY`
z1@kYqp+kqz_ge4s%Jov3LE%9?r+Uk!D0E$YU+0#>*I2`ycwvf~3?ZuHC~YeA!vm3!
zd-25=Z3^?NM~@jz{lRhDMUBRU2@}8#=X|Qx=Nzh2h`ST?w^AZ2R<5uG3l@-~7#zA7
zKu^<}$RJZe&aOSXeXU228S880h6n|kx)1mAqKH5~fA8D3*Nv1TM4>97omv1pE(5!~
zlj10UMH?Q|L@ca)2l*^HQ8Cbpr%ANO@t%sF94a;j1qz;Rg1ox%M-)~}xo)a-jOowK
zT%7~7D$FVn!%A)H!lm}?%a7Xn9e+bklznutAKf*3<X8gn>~2*TgPuo0)XtrUY{Jxw
ztc+2S`K>iJXYqBm4-D%=;Iro_swdv@is&%x$8A(nP}z8sXH;;7*Ete{f69W(xep;L
zXgG&<LUkO0K2ybiT)~`_r;#{y4>Mkf=w~_$E#|@K*svb)21V=2k5*`6`1qN2>cnCD
z>NkFDW1oKmfHMg-$rbIH>L3)Qlz~U24c_l041O4F^3%XCFTDB=Z+xAGTv<hk{1-2-
zA-Y%Obn8+<2BdnMqu=95lf=wPdc%i~oo!>L(Gn{(LYF7nuORor9qULH=*m3sp4T9c
zqet+HdGEqeJTQ*lbzh&%lyQ$WO%Pqu+XyK<k4FXijfgB6QH_OOB#Zg{Jy+09FRr9Q
z4$^PkX(;mkJpY@bsGMMe5Kq!or0sl(C7?C6sS{|)3R`-^$E^0`Ny5+!4%dc>rv;(r
zSlYpQ5929$9}oE=_4EOP--<WbiLe<nakh;l-&|i;n`mo@!*YqVn7*rPQfQV#f1iNw
zMOe)YCyzZCF>Mg^L6JD|=w2cX-IHe`>I@s%!^i1KFtK5fAdyJ2C0Y)g5D2T`-4C5O
z!>%7Ug(~!eQAK+)2NL|)up%CQRxWvPkzI4?XoPVA-~x?!zU6ksZJz;x@GyW2wJNQP
z+8M&t!#+xAhQXDpl%GZ3sD$FOCZABFf;qLViC6<c3M56ZWZ|5IT=dup85{i)da?Zf
zJb0y%mMEAwdmUOj!uh;VO3K=yM5FrlR6{1QVDT@iBv(HwZ8F?v7mP0Ol{3uB%P-Ei
zEubYmO6BPtw|$UG+hRM$yk8BIA3t6L56bMFx8L%KR#O?QQqB;O<r~+NqiX_J`zAmq
zp0Y#a@Hdin`RGSKiok^iDOA|DZM!}E&_i~^jUTWTFTG&Rw6M*aH{ZrG32WD`T@1ND
zXj7+5^P)R>P3zaa<Mdq)tm>dagY3ldW1uLNvKRFzz}+4S{n>**v4s~ew0U5LzXfuf
zl*nsDc?2c7=#oX?q?b|Xcz~2gIX@3N7tEM3-Jw}`?AYnbe#VR$7#(f)^2;yU%vm!*
zirS12K526>GEP%jyG6x-tbx4nQd$c&j&=RI4K^O7Uo(6d=RM5mO>&B~^_5Uu)r`R2
zw`->p%c@nc+obUmZ2ytN3~ga}ismWDia<0Jc@mz=bef9oM}g-=+pqo6UP~E551r6}
zclQO=7KE@9WE@54vDv9gshfg|MSFC7B$K=snsYajnkfaU_NqHS&#dnw4Bk<GI8eT$
z_C<=#1u^f_vTXUFfi0dv#EG_`dUC5utj%0-g^iyvpUUJ0H;`g^7cBQk-r<4f;7O~E
zv9Pq1eXfLODMD+LH!AeMcy%OKx?^z%iI`v>S4hq?sfCcyBZfAu?yp#Zr7HM@9Ey2J
z3Ws}W08w!AqU&ws%**V=v7`Px(FFt7x!e;!s?AkVyIdPLyvzm<9qtBw8!cwJI75qW
zz1O|w7UW8|E#cN;*y4m@MS)MPsIf9+bqh#_Vf~pC?FR_oLf6I9=1))K@xD(egr{|k
z)>WAu&D(ao_1Hs->8sa@^je_|jtEX$=umNCA4oIh>0DmA5R_b$;T?`}isHw6uAozE
zKir#jg{2!M{7g|qK&Ohf%kMw(K2vuvg_<-bF$`GeA6i!%JG6S3jTkZ_Fp!7zV&xvR
zKu{`yp(WIn=TM=OI8U^ems`$k-fAZTy%LqHF%L&pg#y^}o&a({jlbj($&$}kJ~}LQ
z%BF~b0z;%K+VqZHq|9Bx#u6+Ld*Zx)-+HcSq+@(fdbh_(yEHtVD1l}`j~gerKz&aX
z8EeBp6&`LT9T1p`!We-r@IQs~)pwXpamz?xOml`3Y7=I6La4-qrF228>g6GJ(tg%y
z#V|z=@z*Djr`}SmkRv*dh?jk$cEAl{-5&os3Ds*3xWcBPKU9aZC%)%BS-#IpCqHmf
z3<5qDpm8ym_W4`i`j*dge&v-{Y|_Mu_MQLu5Bt*Z{EjQ=Idf)G$-mo9o;+qZ-LTAx
zXc_s+SN_2M>`(u@4ab|VtE(eN&$J%KnQq^)!xkf`PovB?Zrb2V|ArfGu;q-ZETDyL
z&6?E=ZTWqa>}x3B2kiFSZnrnyc!iY3d{FCtWY=-5iW{X|$B!S!Fo6SBJ87al`sgFJ
zefu_7wkMfet$Kjndv<Yeb6kOL-@cW)flagyj>OnF>>mFq@RU_0`<H+Dm!xgTo#O3p
zShtqzz2VpbyLN8#FuW!V?c`jF3e-^V@%;14y-ny;-ATK1!iVg|=byzxA8Swk;z_&w
zvdi$CTWl*e3X>*Jv}(o@764#V2t9RaVw%Ur1AC?0r=YT;V*=;+Ki^*`6rofRg<ziq
zCgd_iJLdGC<iYTJ{9aOECN|v9*PTuh#sMGs@COVl8Tc~x#||Is1*t)Dh*;vtOQatn
zf)({irnI*zb_X_sIv4OfON*+3@~m;Csap-9^dPKtN=FLwdxEYdm-tQ&9Vcq%4AF!*
zJ)kf5s3S;Su7tGEFEM^Y^qkSPx-Ct_Pl=^YVHMw>lw~}l{%{Z&r4!4kO0O!diJl{c
z=M)w2NR)0GdB8Q5N>=@fjw(R0I-g+(53L?eVGsWzSsPzENTo;y`ZlrFtVajRy_9ri
zNH2-+llvF$Kyr|x;9QijB6q&DO6w6d(&%C3(>z@nP$F}EJ(AbyOG;#tqfZqi;rK{C
zW*~avL*9D@9o<PnX)4?Y0T%&**F+Wcu_K4@4(dV(B4VCcNTz+xNYTcjH6Qh;jgqoe
zI8^^}jEE(Kkpg=q_Qe0zCqa=q`$gt(Y-mb}CkQoh6AHsA{HJrpBhkX|y<a+icdIr1
zh6^4v;<QvblcZX|&Cuu9<9vEFzjo^Ng@mS%lOB!xbww5lv-q6uk+1@4-H<X?uAZk2
zIqhIT`S+AfS9n&x#eyYTw=fD%Hz4aYtbsFVipAfP0lTeH|NP;CS!*Lk&BOX03<6vw
zMS1ONX~WBKpV_k{vCDl93Ob?>(Ty;E^(@M>D>|d;Iu(E_{MSGJUHiMg`xg}5X1nVn
zA7O;#&8~bkc2J5;;QvG^Jzrf;SXTvgngLyaa&E(DsTn%V7NNi{z4TI7$oJlRuea_!
z`|NVZe_y<0u`APhz%fRS9AU%pPMc2GGrVLfqxzorb$Ij5Re0QEt!hvO#WF>Vw!GLb
zy67VN8J_uXe(^VK*sx)E>RavhJ8pNQ;RN|i83O`=xRzRiu?#wR6(ggep@D+Rp*E6h
zC_-=ok6DKD+i$HVYH*v4B0T<YU<8O({a!|aOAQTZ=!~k5|M>U+tJP6NC?jstgz@ev
zH)DWoSVw`Ojwf_403Vmm(Uhnlx01puZ7oJb51|b!QirZ56#8$aV3Ga{^j>4_3B1|^
zJ`_gu8Vcirw&{J|<TX=iuP498Q9UPx=)i=(!2XFJd`_`Xp_Mod$~BG(2DuZx5iE)T
z{VRnMJxy!?238F@erJ2a1)VPUq7+nA_u}94V^bAYBD9ovoH#n?Z@AtGDWJq!$ZHFX
z+Kv5!answYPIsiDUzq%!=1I)3PRDa@fdpCQ^3*#D{7R8=B3YqxgrEI$tG=ls#&Dlu
zEyJs)_=tLSG)UUdT|}RC4FgW9Du+5MTdUT^9T(x6C-qE^MLCB*gRTi{oFa?em<an3
z-VJx0xPSjV{QH$q(Bb~2^r$vf=nqA=Y4w|U0z1ill~YPzNzqL~qF5lzR}MMOp1YCd
zL>&}mwiqVfz?d*uEm`fZpd;c;-O$*Acfqd3jfH~<E3$M0fv1v$9zdI~>P3AmvXo>H
zr0pL~qk$5Sl5$>pjZ>>}ds0Z^`Ms?mwx(0aH8qhI-Lgk1Jj^5{uVn5jN!+pE65cJ0
z$MFt^AmY|jyOpUZ1s12KGRd6rbL-O-i(Y>@!cXv2d{0y{)02hLEkzpc>}BZq27~@a
zb$%0y<*iq?;gyv!7gkul)eQ6yWND58bmm@FFRsmi-TbklA|~||s}O1=vz%|Z{s!BJ
zx4CA`8ocNqcrJL{xN%;*5)AOjd*dEe@Uw5<QF{VU@{j)Tk8I`2*L-ZDUYA^Q3BsZT
zMR*Di^hE$)iu|9#Z)0d{JD5w04I$KvE?VIEZJl@6h~c&z<^9>ue$IQ&ufF;kW^F%j
zv+;_HiWyGAeb&=fxSD%Y*!`i09;RJqtnYzx+A8W2?<mJ7ffS0_7+%1=>pl)0I&9Zo
zcb)hBOZn=UVZ%n)iWMsXr77oJ<7~sm4S3Y6Q1~CTqjX6OA2AG%`ZPsQ-*H1>@#U9u
zKeO$--}w)_a@jI_ebp+PNQ9w;QLaY`YX^Hbq(B1Bb!;TZUT<=9V)95(j_W_AKm>QG
zK749Nn0oZ)>u)eA?SzdUG03WU?n2fgcJ`u8NfCkiHDm*O@l*!%7~hNbI#kAoym7Z;
ztw@W;p;a9g91Af<;F&OVCGd>bY$UE7$q&E7Kr50ji9B=6%c<Pt-<4)hd8|kdC1jQ4
zmrt%sezCjZk}A{EFk$Lj(V>!~j(6?*5)@CIk_^imJ&PY7;>UrPlh=wBSP&xte%WD)
z^*GU*^o+F1I2V7rgC$w+wH%@ApjQeIV?*OY+elBeQ&&-UV!yqy@f{TO5Sz7VDZIsq
zOD@m}A18vIDTHyhx|Lo8l=?k?o}{vs(HLrC(!UZ#VksZLrwTfirZjTUl{1_D^g|EW
zpsHf~wa?y*K&qyHHqU!+CD=mFAe}`V6K3eSORB3t_#qz}F#((CHOpR9l3Wcha$=L6
z9io(uh)zI$BBD4~llY2LW6(|BC8=C$ocNEFbF91KO?CqEwu9uxxdrZc)<IasQ<DUq
zqN0%mpCxWJ=1}K~pg`qKhO-7D6@jPntWF;huZ~mUk%zb?AW{qtUn5nny1Ass;e47v
z85JgZF_^BzGAX<l##9Ez(78OQ<e{cu*~V4HeqQ$k5<Kg_hY)*GVCeVMQJgV@_B4+@
zm+x+is`k&=NqW<tc^WL=pM2e}yX`|(GjgJx_O6T2@)4e<pH~l=6yK_pp2liQ`P_Ba
zhf#p_p8vi3?z=raed(ou^($OWj=mmaL2J=MNcZAJ3tiDQlOwz9u8-K1$y03z`O6>w
z=*Kn+<R}RZ&CR}zko9T4d-vTRM_HEIqD7bUeyJTsneExLmmDvZ!aQm&JTR2J-6uZv
zX;ALQ*zf+{S1@3!@t7|mN6ml%?ord(nh`?B$d9T3YXdoN&7i*fqxU#ElMI6CjI<0e
zk%WX%z?yqLW%^7CzV_R__uXgT``-6$0<)>daE&{;@4<wyH;`Xe6l(;Y@WxG>?bqpy
z_>b>=7Z3b;?td|g`WSiXZFtIK$V-D04Gip;f9Jp0P`vkrtWRZCh0i{gF(Y13aoa3%
z>OzW=vQ=SU(%a~{Pm1US(uoWBMBoJ!Begc3u;(6qz~;=IZlC@5uUQqj`Fz6XS_h?a
z1{R8Rp^%11A~_MUU5Hpkd=?!a=v)dg+-Pj5>8A&0c~ATz=fa0a`1?V*IGc*EQk1mI
zlt`{bIz3^?cn&q;Ii`yHXgXaKc8_IB(&>=$)U8MNF8*}KC@A*$ew<D9zT|_9aJ>-)
z6%+Rx@wsM7`s6a*hUzt3ChCqOX%t00T;4{CId-m+9<vNJ!uLLCCyeLqONj*wAncK(
zxWjlxN>C9YeeQgls^Il(lB-dNLmN@7<BakA;g24)hko=;`@o0qV~9^x@a|JBf#@o!
zIwB^Hv}AHN@e+tPBR?T&5WLq#Vu`gD!NAmP@Ea>%22!)wKL2Z<BDbY}TBapIBwq1L
zkwG`XA9g7z^t}MdgV-*Vlbf6fpeM8gvK!eRHrG!P;X<c|O>}zSe6B5qP&-Ai*n-vU
zOz1tvp<t<tR*V49E@c%nUUUstys@>d{?BkL!6*nyO212hDKw{>XP9HKMk8kN{g1SU
zpFff%dS<U^Mp4K3ys6mOvBm1P8zt9X=^j<r>NvOJ<8^dS6u^QCEc^le`BgBbgWTI8
zcO&mw-l;4db|(@t!C(k0A3zGkDK2;wVTcuYk8SHo*UA$mUeWV*%YEtlI<EuiyKiB`
zpp|<+ej7!4E%wriC+*r>K1Sbq4Mz&;Nt~fVl61m1c`2{HO|ifemN|Q(kenbGtEC9>
zYCBk$(SR&WAlKWfb}RlaC10zswkoovm{pu5150qQm3Z}y08Uf`?|9`kSEFc$5ngNc
zeEFm)Q$uAxw<0fnaB->c$%Khhm=6tfBIj)3*iu@07B5-mVb2zTVkS+UMjKx{q5UCV
z<z0*-*K$>GEh+F0di<6xyV|cW8qz%}yq7T4oZe(<nN6QL+x7!2vwqW7TfFp2Lhr-5
zPPUC0J>GNI3opIQ_r9T_&MsbfDMe#DF#wigOk76cU@>D9N81?i-31-n+{&~v_+>JN
zfZDV4?5c8i&(TAh?oJX>VVzhz0Wt>fp}WBx?~HS_YpkRtr!*Mfw$-n`Xcx_$W*`07
zhf&Hzd{{r7TLz7XX=CZyO-|^{QW?Ds#soE_7>#kHD(p~rCA`GgFm+9=`wwkyevETM
zz?>INv?ITCiqLi>noNd~gR|f_ok+)tr*%YX#Lx?1-BV1;9yjWJGF`Z8d~Ls$KYx%}
zIS$s8lt;ei&ikRzE>@7?6j295w+Lil=`bNLsvY149c_*03(8)GxMW@I%?A16_ZUUr
zsJe`ltkxiSzxu30$b#%~XN2pY<ji!xaV7D8Ead&hB-MFE%Ft!1zY)o6|4R`-v#}#<
z>`TA(83rMJ&(^&3gk65)2RXP1n(ywj4%om;d#f(o6T5SEDHQZT{2=eC2OX>$g-B4&
z<dOF8*-jPTA^W}G{UU;}#OJ0K7lVOIv6!kf1JOiEGf9g{xhvrsS!_W~tI9BJSi*|*
zXLp-6v6u16g$lsP0*e%CE(DrSs9A+yu6R?-shChz!mkjnl%Fdz38EOT(Jvnmxukd%
zhVd&%G4i|enF?QuK*flve3d{JXL?(hIwN_0FC>Z1>$iZ?(KW=Zl3OYwkvBA`Qo{WV
z-W)kb5q`o$jg%*aR00GERg4m5dgS1>=i#AAU_0|?hn5H_b1}EV#EzdVbtsQo#*#CV
zL%oDGb*m#bI@AUt4<>Mn!1MjQ3DS#5(1|gAH&w($@1+oHbn@tU9UG=}>3-TU<TTpv
z^PjmF*uVyG*q6g}_cGd23L$QxNXI>Ae=kPV(vx=(B2(L(!q!@gX7xe?9^udIhLnzy
z@f8dbeeS=pc5NW8iGG?11<#loU}B|IwSxLgf;S+4NlAy6s&>ZbWo0!x&Bg5{8pEeH
zCecz8J?hGPwu9Lm(`D$-=Q?=P67OyFlj`MB8lB$%&*LoNcMeznuo&axmfP-dTzO$2
zd+Qj_*iPY>R$Be=${ptt#k%nWH+xRJv;wdil>cceljV7|(@qr7#sWns?;bx-OcyG!
zN&u!ftpzm}zY^P>vMqkw@iDFtB`<Pp^IL1Iv^dW`e&5G<uZ{e6vm*xvdJ>;Syry&Y
zBs>|AiMoyM^cOCj`kt61DOO#8^1m1gRffKQBT5<R^G+3XMINCJ7dEwjPfE=H={q5u
z>*FG&Y~p7oucTt7E({R02E{$>Qs6BZS&9xs)~}~6G`K_20-yZkS}DM^>iV(Q7<f>j
zXr->A)E4(q1;U?@%JfeKUoKNr5$}d|@UTUfK8rbue#q$b{HU%e`%VsmKa<uVpci_m
z*gacnihL(n4`@dQTNp1ZOzp7qGB|bJIGvXlh5b`VAnmVx_1mY|QT{z&>j>w;;Xh^I
zQiGwi>2H4N^Y)kj<Nw&kH&-&b@H&jkR0SC>dqI?Re-G2g=kKY4j`_fw(ea?Su3u|Q
zmMp@%7-S9Plgbbj3VmsWn0f-;=#1rdDi3vI<~X;MWcpyJMt?hFM7FR_8+oD<xT<DV
zpXRY+$DAM?yo76?7U~s3IRHpV>4kHNys{A#?QTs<G*jg)=7MlN9}<~xB3y;>I;m1r
zShEvPTlbI)!qB8C6F}9`q?;ByNbA$MaigfN-R^&j;qw^!-lZNe7yLSBz*p9}CE#<J
zKRasVaN2S9`Y?|n6ym7QRr$wbgdLs1_~$cJh1A9U<tZ9~@GJxMt7=e{hisKw)LB~z
z$L^sQyp1aEP+t=jyhW9(o`cpXN;uFN*4I^&WP<145eXW3M>0a<YHleoZzJgS()ZKZ
zl-=J;^<IJ-5-fQy-qKpKKOJp&n)DCfb=RHtr+@zUcJkO^E2<uY0@DU$!XZHw#I)j!
z9SLSvDhOhM)##cMa{g=_67pYhKX&jG^irNzhNXKzDLJxs3Y)?+$a|3y6H)=%C#`KT
zinQ+XzSRR849es5jw)wdgc3R<<;Gduh~v9@U*}Y{c5};V8#ye1S?J~K6ovPkcHIyS
z@2f4W5n-ji=pl?j6u62EM^`=`Dh)69z#=cG1us=q>7vn~tbzxo{|op9!TSndOkMh<
zhaA*$Fcva;xxpM1wQQl*mIm9uce{Q1qqkEeh$`dx@(JH-LR7b{?u)$qy74`xA&!(#
zXE%sbH_}7l=>+Nyj*?1fz!-Kg4Yd|}0i1H4qLbjA2Avs-FGUN&;@4XFUPGIqk2$Qd
zWJep34~Z<*eYo-L6PvoIPsp=r(<bw?z+pifiR26)KAdRAHX<on7tIw22BDN-JE;bx
zMP%6f({i37#zJbJ_ftcm;y}@}x@9Uz4IDWFz!3jwecfn?=vF^voJyw108+L77{04>
zo}}u3@BTwh2f@=1%0Hy-6misjQ$NJPt)!xq3KR&7`sFz&I5Hlk3v;(+RJz(uafF;c
zQnx6vr&`|(>BmnH8B&Vbpl_t4%PI@(u8-bj|M<19+qBt4YjX*8JB=kn=f7+P9YXej
zE8bfLEv3dnC|sp}!1m4-+As*IVfE)hr~*6ah?G;%&MB-M^lX}!!acDvPIpYKT%C4&
zAv_!oGgYGCRA8gLr7SKHTrt(GVq@hOy(&~Wq)2IbOBJ4E5wLZgs_vyCP<e6*xB?WX
zgk0=_6>Ay`R;n0S%3gT1W5$oQa>A0TtPKJXW>G5=>ry}qN^uc=ll9D-jXbCl;OrCv
zRs2r(k{cmUDd(ta%Hb6AoB|Z&)X4^Nq+)_lg{^@Wr-hv@#V*er!LKP(MP&&4l0qL7
z2ZAsIG4^9Dl!nM3>t0MAQ97grv(ocB{4N19nBgJi48+*6W0y0oJbdL~)gLRM3n^|v
z^ZC8Td?7TS1b{=2ZA)l@z(c7XReWS`5gJ+L2(5NFTQ*!y7RC&i;5C(l$$bu`AZf2n
zVoe+#@El%ldbna0kO<0_zXk6op(;;6&nW8AKC1v!LN-PK({~h&P%D*F9RDX8ap9?R
z@_PYvqt+Sk*T&$HV35+2%u<V!-WQlmD<Ni`=LbJ{%&xq08IzAj(vy4&<x0U<BuMu&
z$i9-k<{eu%04%fLKJ%GRTOHs!GHwMmDOOjsMZ!}1qma2KyB*$hkc!r7d;HOd?Y{dy
zK?J5Ec+niE2NM0Z`##EZjQ};=n2=`|3UlIW{bYNSA_-cpuxkkc=e!mdXNCf?o|aQj
zxttWv5}4upTC1kxr>vBa_NWm<F?<7lb2h#DPO$MwqT>@oI8tfAWkmW)<?f^s8y)f}
zV;K~F4jwev>fkrwY^!im3?leRg^|N#w;)4eWVjeQwU~WZTBH-+QL0D^F&O?tO)xSA
zkt;rHgs(l_B*T!pl?f9jx>vl1S^?2kKKq{w`j}Etq7Tu6qHp>vt}RfXy7o^6gifm+
z%^qFR`Kzd-P#d0#qXf~bdzIW#A)%roVSO01ixDSYR=tGoy_)Afd7{?Abn;{vx(AZw
zjz)+KDdiKj$#TC#YO36k*uCd~tOPe)3kr(E=vx>^bd$q%+b}3Yj4p*PB10*Tc*Y-v
zh^P#h{uT5Y9|k0&H$?m#nU(z#uXex(qlXTqJ*))0j1yKt=v(X6|5?vLpq#^3-dhFj
zBop$QEeLm6UFBfAs`<Eps!|Dm6-sFjvem*A6)Gg2vs(pGFsl+pB)xe*WqD#oiv!`o
zVv^tuNI-IFRD@DsgDa~DJ5vBe@lOoZC;*A^<Q^LcrD_aXDZmdRv^{(FISN#<3VaS7
zvEu+gNWc#pF#;kN17+C`(4N!}Szb2S1~Y_x6F9RP)hJ?7sM|q1fV-?Lt8yhcV)#%8
ztk9TCc{Dnwt~G?hom#+CYEO}a#QIeTt(+XF7);tqMnhemT60FZl`JW+8`P)K0Pw3o
zXD`3!78h6@AoB$%ol^dtL69E+5lD)7%$QMDq(U1M{7J^SX*h-|aW(p_yrPJLqcU1*
z8c9Rcd5^flSG9ya)nYV>++!omCo5e{7gkxCw>y|ZFM5r%a5|$na%7WV@uD~xKoRJG
zhgQ`C8$A4BL}B&;P?M7*FH*E2QtyxL0@H_A@Q8yk#(R!{)NVhbu%xN}v|V%E)wXf-
zMmMgOEMDTYv3|pPN7#~)BBiwSilz4QikBI%a?&PEnnaP<6kEOeEkC=^xt@9EX`hun
zlexkhH*au-yL9PN6l$(ld(W9Y+g^R`RjQ&dv$ceCw{P1*WU1EPe)Da+?)vNOO)9DP
z?%l)pXV}wEKkfH7YxXQ#&HJ5%y)U6iOor3TFTa4|sIb|y=h#zEJ?W7a6}##C-~8q`
z?AO2W>$E2wwI6=}dp2X*RJ)ui?B`y1j!4o8im&F92cMqscwE6oVe#M|hkv0RF(_*x
zTt%6Uu#~An)PIkxYu}D2cPW<i&*IO+SK|?=0gxo*l;s_&l}hO^DMTr{f-=o`59u;_
zNAYFi)K)KAOYx|Bf0imLV(JaTCn)JC{Oc*7Py^A0k}JjF9YislfLo3c#ma+!lw&`{
z^t(ya6P#dxkJesAuX;&dOa$a67n<3BU_YQU$HC(+LWb0!a0{)zsnzx#IN}OaJYEdo
z%i4F|apO)AznUQcB8juOrz+}pbnf_i6DLk^n$%d_;SBRBrzP+N{7~Q20pN)$+?goF
zcZShY*C^CFWKRo@(J(ynJnpXz8KtRxLYtFer`~uO>~a8x3<)$YN8}hlH==p<ybESo
zX|FxIfJP?$F}S9h&VZv<L;GJ5GO-T%ptY-^4nwPX9EB+U9Win=vaF7EI_lTzHc6{5
z580!Lk*q%J28xChrErc8g<zgOP$!CX%o%h}sqfwCCW=3K27(cR_R<7a`ngoMkArQI
zOuNP(x<lCQ$k^LVH5$Va@2P?g>?n_yRtXgzDeS`nNsKFR5vsMZK%@S_UVD{z%6KJ{
zZnZyZC|QhHKDpYi#C^j;s5n46@|))oC1fPjwSlt6Ll5j=T12)3>|Qf?h+B|Fw8PYQ
zH89y`jE9oTu)qd0W-=e_+=KLPAAuPZI?|c<?AzlO?#!7p>46Pc%#M1*&<J@kd4$PB
zt}<+>yc4gD#Pch|qa6eaS00wK=ZDBo=27fXzyuk2xw<#?;~qS8fROG<n61g%j%vUT
zA2xW94H;Z%hhY4{gNM4{DB}7D5C$zxEqEWJxc8%W6vj}m>?oLXB>&WRTM2`0-LloK
zX|?>+*VEF}ews?(ZG_cEU{SZ*;e&@kmYSxr5EM95y_nF`N|BI+$F5y_+*9=byeK9V
z%p~M*f(cTHRkGgqA?%O8;yv!^WkdbKQSTCjp9)_jyOkSvHy<U9u_4@F?Xs7MWDp8V
zz!E0zRl-=CLd1dzT+c0k0b{D(KKhY6?Wt#;r60M;Zn*9md+hPYP{MV#5Tz?*Fd1ou
z2<PXPKgD|O@@nt<@4p`pqY#>IbJ)#JqD9-bZDKa}7wkK<CsjdHLJb>^HNSZA<+c~a
zUyCvJ(8G^-#6;G86(Pp?po|?qdfXoP>HR3@y&h_O`l+XE3>D@IcgiqO0oufglbMzK
zG@i~$uioChb2lO3Jw!?N(i{CHMgry%1|Mb@alVNt59OAZUU7xJ{>lnFw0|Flq(a_9
z>CJu`tmT>BUmkCTLcXdm2>TNmyNUgY>O`E!x=XlZg>Rs9&mj13@kYx_4no(xoG2X?
zz;jfgt0+v!R|afwK|v|k8!P-M=NwfThIeBlyqiQki>Veuv<X7hJ-RWNe7Rb79+in0
z;A!1x5hn<^1A4Dv?e?(VBS(&mqD&azM7`7tet6$uuWmnCTIcd$2fWfmbS)QX;8ys1
z=k`5B!-m>0jPiYik0pbo1Y3R1x>94bUn-j6bgFt1l4}ZwvnGQ{S)HUpxez5Ql(P=_
zQAWE!W`vB`g`6!TYIpeXG3e+d^svt(hpO(EY^&n;lPKXTrqL<&r6|C*9ozl7`8XL(
zrw`lC9ea=$)i!?IXrg9=DIDb9aWFP++yvz7C>uelP_pX;;qN{B4k6$1${Sjs#S;#$
zbDG|G6@v{%M%5#)TJh))V65b^7IKifDX&y}t%m{cayz1-R8bMAE8amUhk+gXyAz`7
z^sW=hjWA+Zx%M;2;WJs>6TnA7i8~~n8|MMC_#9u#)kn%WHv4^QpYAQHb<&w7pF)>H
z_lNO3|2bazf_zOxt#F&i``r|kH60YTa+m?$BCv26A=YE55?qrI9Vz#v^CZ8MWU;X0
zv90c^Lky|^F|fH4<=mxN(S#_61KM7V6?ha#$098B2Byk1Q@Aq*Yf*XLmJV`ogxeb1
z0CwL~Yi)#uMvtkqGo%=EA%I-vI@AlyW{es(9LA|-hBA=?6n6_DZhg0mah3vvP>4H^
zaF_6S3-N5nP8b6;<RNS48QKs^TXt-<iFoakXG{g>`5kN94;Ta<ZFV6;4^$*1VwLl)
zJeR9N{-52|*t$kwAl3e(q9s*zbP_TZl2ZX|tl6t7@Hm8pd;sBn2~dz72z1YxbDU;p
z%1}`ayNYle7npPBir9tUtaGpqC+bgG8!&w;U}@EG1@0jTPVIxNNVUp@T}bF$7k)i;
zaB_cQMoVSB6w&GXE2c|SeM@M%>!durA}@sB7|0=yDw9_LKG8je3RN$q;&fi1$A41D
zgR%Z6OdM@3kF{WRm$E05Jjx(7Fb)(iA$m=sMd=g<niOaW*139@_47>-!8ATlj4x!h
z5eRQ7R-uWh()qH>m$;!M<u?H+%pd*uNAC4L{p8bj+wHe`yVe-mvy|T0dtjeK$yP9-
zY|gy7E@(?p-~u2Sf|8#!X|lb!`VAs3CmbMU0nncs4XB95XwD(PihTB}u&{*OEl5yY
zQ_6n*JEa(Ghu!;<av6d#ru=&7QiymZmCI6;@P*CQbyw~hUFaovZWlyei3`tAd9To^
zYz8;SBhc=oROo5t^%UpH2l7JD=+F3hVn-sp9rA;oV|ChtFGzE#m~;&5rHGkwo2AOp
ztK|-U8;in{7wxpJ5w&=#TX$`9(3&=AtyK`1;xXib6k9(0Kd5Gq?FX8*L(u@9OFUjk
zI!gZ<@OX8uY;x~i%s;NKsj%u{gOL{p8Dj|;4l-&ZLw$s3H-Y0f5~Ujh$jqdv6M(DT
z4i9rq?nC)rR}89|5UzV3GMD!oFgE2W%LwX#-`n}85V@$Jjlxn*3*5GIJ2gVZjwGju
zp!11v=#}>_kul%l-n{InV5YOKL^|@>z<T6{l)q?9#z7aUIB%Eo!a8}k-Nbm18L4y@
zeH@nwBr=*QB$EuTN&#~pQiMLITPIV^lUr0SfYctFqx^kr5N0AQ25?Mp0uw|PNx;}N
zjVzETeUj90;bGoW1s!rT%Ks_{Qi#%OL+Md?gtg~NS_NWJWn_Sf>#m^Fh9LZTqrjFQ
zp1Nz{_aNj0lgBwRg-hC~LLE+VO&Q@p<x@qtZQxhuGvZC3<pPy?;#e(U6{E2tchhb|
zKix5AxR!wjo84rcgpZU1m0t2ua9$|Z<%Jy@^?2yWQ5cu}4uVz%9J@G&dQFwf(&)!}
zAyDDjsxa;}Kb0p@HK>H=AUt^Gl$9gbn7R_eP4$4qw_|a;SFIeQz&X4wNP`M;u~-QM
z7F7^Vufi~(`d5{%>UPmMJI*0k%+oN}Fg-KET|!5r-u53lN=SW#O`!cpq4$$8tioBj
z1*{pKRwIhOW>}F8rzcjHxSp+uAp&Rc3gKn$Lsh7SJbUO__i2V+BojPc-^LKF3_Q_;
z;ZpZ3^>ZB-|E-}Tq5UfeWv`6o_ncs*c<#O+ubg{Ov0uRAPJN|QCOwhYLYOod6>4W%
zxbPBt@W(&1zxv<*!mx}<^aF3SfBeUPA{0HB5Zx(mgw#Z3jpy?etr$6KETAG!+c&=P
zO;1s%AWs$AL-241gV!Fc^DMjR=37A~+vG)O>UnNruclDxJqWtE_L^($;h#TblfmPz
zt!r?PD;w`fz1Ig2$U^^;=P?0=ykf-)yqd9uDT#0hJOw2`ciu&A(5cmGI0~czx{~lz
z6@Lk-8S&g3AeW7yNKkqFV&1#z>X{A!T1WBIIR17+IR(kDKiQPp>CoS?nSCyes2UBK
ziJk!?WmIe@p|y7EK62>*QRK}F^&*45$7TnvPa&p0BP#C6M3J0?v`94;-2d`(Ntuox
zH-U5tH36p>{s3Pq<)uk^&G2&@`&ow<TZLzO4ER=sjt9XzT4Rl4Z9%q(u5>joDC9ee
zyv&+D&2z*JoUb6i$$3wFFN1yZ#7QW&)5xPX5EiLVK_;~Gdn?Fw`S4&<6N6Ler7uE0
zNQS6>p@#YPVz}B`WEwQ;XnV*qF7F6hXVj&FOgKndZrr#sE32TgoBP&1o}sWyT_07F
zafICUw+c#qHZ_J~?Wrb=z*<@it0;J#K^VN)BSEDYq&lxAbZJ(6C16w4H6v{QL1ZAG
z6-$Y?o#gga6e9-=1*tZ$h@VsUFNpEv9`q#>x_u|rdGlc;>OT)S6>|LquHrZV+@HD-
zJ34Z$G(U8}#FvWO5i_Odv<7Oh_`8u~F#aX~BAq60I=qo+&yBzEo+{`NNeVYxOenXQ
z!hy|z9gIdfcsaguSuP-Bw(DtCXU5*?@=!WcTwtTK<iX(k_a3z4g~y|ls&MTzIlp=@
z<Tye&SCf1M{C^Z8lOoMWS?$@m2ce7=2(z{!Id<;f<HkjnMy^S9@C<tn?&05F@1<>1
z4<IjvglbRLagAm#u8?=4oOUarVljrSPciEbsx?)~D+8v1Ye*nVX|`}r4G3&`bq%$r
zuw2{i2>B`x_d<j_ckT0VnF@wf*x{0mfBPsVQh|^>wmPn-s&WZ_83=kcp!8Mfu?LS@
zc`N;{Yf50$V)f=x8=#!|j-9(ax7`>S6$KQwbYdW=7){{yKBU5nSjB+B0!~_y(GolD
zcHh&?b~LuALoUw)eeyuKfb!4E^(l-$>oO3rFdD+p_JLf76M1em5)7=VB0V)siTd=X
zKVuE2sGc1;3{2~Jo^w~Y(hI=&!dL{ho=No!@|yNDAmffZKZxNs-05v9`FZWDa>MSG
zQxtaj;-z@v)BH)4w^W*-k^v)s@~4099@+F6vz=as3>of*P8F#H<qYRQBPUS|5_oEj
z8pgyn)fXsNsDTAnUVW_}Hy)v`#n-@%88hd4I;ou&o<ffM_$NN$?NFCpcBy-z*IoYs
zuNEFp6hL{wa)h<KecwlyBJag3ZV?Lj0ICC%A+)ic94#T#xid6XETqU1H3Ztev(Z*h
zDWCFKVcT6(1p4YmIw1uk=VBWvATQQL@yZ)KK^j7XNW{x3syc&AkwJCvu=tW^fJQcN
z+s1r!_zHd%kMG-!T##`o+Lgh^?@Fb4#|AtnBi{i_P~fU-X<*`$a_>PYw|Lv0;AExe
zMPEk`9dn~EAMEL)hmU)4YZ1JuYaFMh01;*_`xunNz3d_CqHw&@Gj*I-a%Ly_W6f&r
z(o{0!pYBh?CJHIQbJ@dUXlP2Y3dcC6L4~h8n`&z+$}6a9Kjv$pc0fH#0miCw-#S(X
z)DhBw8jj)xT3Cc9kb&9RGBOo~3iSx-Dznc~OgK+Dys=~ePK&p9DKSBqQ<2TQJY?ne
z1MqR1O#@r~w6t|Bp3ZX7%;eTtq)rMe`6I`4CbCQ6v-eg(yJZei7ylGO8B9*}_1E9D
zYpz~K@3C%KLNDB~m;LvU4Qa(i8abSPF{K@%kcY0J@C~g+f{s)LqPGi>*J-3>MFK&&
zm@KTuQs53xo<bq24_P`0;yg|fkTbI0P?%nxzq~nDK-m;#h<l=tJ04yhxl!+{CQsT-
z)u#UG9#xFgLQYz(TbgOD-{T(G(+V$hFWzH`o7zf9IrJjt5_Lc!vXdR;H@g^17rK9_
zY-OOcyyn(MgoQj{MJBLjW&NIvW;T0qHiPKvu&(tjZ+TM+hPA2JbE&6MMN(W#Lf;EB
zcrMQ)@t)SDsjU&zF4jqlz@cq~-Bk7LUaPEQ{m@4l$#*B!*o{dBP2zox&Jl7sAy=e(
zb&yq6JyX2))N*pXygw8rdaO~6jq>JuTd}=Vjm{NpTmR=7q*%~%J+-wJVxX0c&{QG3
z8|n~7j3^7E8lzm5yxF*iSW%Bpe)@CX2_Qp9-t%D6CVEMLJ7@>@tWak)IZG+{cJCby
zYv2GlzQ*}3JabXr4zJ4ls$AFK!x+2~uGeXU@XAG3F630OBa}6+SwoSK_DU7wXQGy?
z03H$eu83%gyfmFx20^=~C!xGYl+ov`s$9Qj0N3crUYU9qz1DglZ@3qtXqr=~(^D}~
zt}-G+Z@smSJo+r2O}ru00PS5^yKa@gy)|vxJ4lrk@$Wr*0KEMO=58iUB|dck4o?MT
zV`MA*9K5DNjM);30QZs8mtu=scaEMo=6tI)Z4-EjS`fvDGCuI^H1SHO=xWh*A_P7?
z6ZF!E9B9A@4y{aTn-u;6JV;nQv^mK?r2Pr`;Pi{EIZX<#v9;0fPyY#fK~X;c>HHb;
z>Ein~j_n{sE{`(@`K0i6Hs?QZbbnaSJd8@tbs8_;TgPB*#0fXvPO9#R(~oyP5R%vZ
zMOiLtV@~<L2v4D*{$!AMAt&JxFaHmER0hMZ(}Ul;ZB{HtdLENXoC#T@h16Lw05nC9
z&1BWNH#tfj-m<uI<*QawPGMeYCC*3a%};%$jkcvx-u>}{K98{u{Q1rz595#CQw8mU
z1genmYK2%P5+Zqd*LHjSu_x^A58pw*uEIAE9#5in_XMN3b?cI|w~SQ`HTB`OKhe|r
z(e6!!mqL2}@;5?JOFRuFWO8|VR3sFGC}+Hzq78=w)o^vMP>|wwkr0tqC}#0n^EN#c
zoH7Z7i5%-kd1fY{O4)mCKoy-)*w>#gIG!Hn4+1gdWc+vCyFa=-#vm}=?}dT9BUzTB
z8$EiIQ2gf8cl^23CKUQ3^*rhuRS4Y~)R)DzawOg&57mpT^m`zt-~~s~jBvQGQkMfY
z1c4EAmctq9JN|v$i3C(QPrL!WcQ3IS$%CRTN(kHd`?7?2hCDB}(D=}7LUV(Gw%kHR
z^9#0U*$o&jVG2-UN>FsJluhsUPI#J#7ToO*w-H}kYvgT5YNNv|QTR~ag0FQ%jy~f#
zQoMS<jLLeowZx&b80<k;@s>MB*5V3EWw7VrTyYn%LSHiGLNB`;NxCWZwd#FWx-ne@
zAeB@h5iE0rtlTC&g-#*b4ZG!rr?&wmI4izx=<ycTwXa8XPu=8Sik07E5eM{V==n?%
zMOtIp2~ca}p%`BWJ@?Fc3vK1|kJ-dmULzH7xwjB?vFDn=78o!J9j3jbK%8;?NqEe#
zk9u`;uoE;F9WNu?6{haV+x^3BDR@d9OE^3fkL@HX*XFqJ7|s!oWarDHll+nVh*mYa
zhV!lzuit(I{34HCU`V1#ibM5f9WJ@xAVwHv*$yA93v=$M58wCA>u_{GVV$)$G1_6E
zCtiNN@VT6lkgt_Y34Q+^x}MHSyONZ3NKI;vxV%y+doRNb9>4cLa~|OZ=n-^I$t~nh
zysi$C<hv8(Mtqzzo7Pbe9}`<FyVEJeXkU9A8a;2!zN&pubS*|@RHQ=2Edy(4TYdJ$
z753`e8|(%~T{aT)PZU4)L&g0m<HXlp-$XLg<##Mh`?x?vlYW#Ouzv32-TgR0n<xwf
zQ~?DmmtS?gz53iQ@ZM_e!ymlahEen&i?vfgCDE?M;U{N>XanOLO)y;ie&FY@X@0#p
zTpr$w1&}K~eVTH<NEWy&oFIZIY^&T#;%xq*h#gPL6>3nVUKpj{m9lc;7f1;o;N^<F
zqT7iGwfnV$V$f+L)gSF^pxu;kas1#ghT44{a?gcuu=1t-1$Yu*{`6<>f~mkni4~02
zD!zfl2i=89^o*hJG_)l7o%s#+^jCubOGSf9oHb<&!+T)^VqYzJTipd&FmDhc(dJ4B
zKJnCY`}xm*VRM&UXM;yhqk5gFK$eiD^va-6%%yVtFZx<UKT-}tLn|Z=Q-7+#o__Wv
zB0X1osM?h_UUUwHcY1#16&*2-b=k6ZlTV(?C4{G!JZE_r`D$w+ouM9H4XRL4*-6qF
zlO|7cPb-u#2#5y3&fnf=FF_m`QL!<V_$fsfZ(;P)_cgJiJwA*GJ$xr#<?cuKJYSD9
zyeogE6?}estZkwiko9Ig%BpH?-l8S;qx&Bss&&k6_`o$*PJ~0PiV2)&QC+kS-ETPT
zb2oY6q#Fx@#3F_jOfqZGBTn$$Y0}58#!DG1dcNyJR3d)y&Jyv9(|rnWb-TIniA;Jg
zt`hCZ@RoP1@A>rw(i2Uilc(y_>4I`syJ!F_Ns7l1Pf*G&-s9BWjek$R7mOA8+wwl+
z!V%<KwnD&C*nEZz3}{~Ic&o2xiyyQHpZVL#>&FICve+xRK>nV8J!Sn<$v8fhKdNAw
zg{mhbSNk0%j@6T<dx~+azj*FdyZ*NO>`VbIYK;Mk^@6{meTa?G@YBslf9Ax0x>t{A
z#766TTqG7Wry%Jx?TBzJO1iKdtm0elvKO9y%wGBZ|4zZm6*iAn9?cq6WpT{FG4x^2
z#XQ^eC*Q+pQ{xn)cs^DqJw==|g8qxBCH3<pg9d8xviYbm(66IsBYahYrPfNp*?wm9
zPMkCqYgBVkBjp_Er_Wc?_KFTk<+zk@d4NiBCO6Az3DOL0n5K!Apfd78ZGdKXsR+Z_
zJ-wppsi1>>o<?CMt{XKDc-%Uv2;z2vo(~m_jYu7&v4;C&ik_a8UzMuUCY0O(q8d*;
z{DhsNNbkO1`?8f(fyTBM6g5KI>UGR=9PZ3sNz+1JSO5zNN|6)+*Ap_>p55DR&Fa_f
zx@)fTHI{cF9PWB@`jWgFps{xCTD#-++db4Lx^1Yh^>eA9PB5&e$XBYe_QyZ|G4FTU
z6|^{=!2l>gk*jxAh+bucm{qLUK%P;c5(=X#%${yST3=*zVU%p_iC&nq1yV?Qnu(q1
ziy557q<tdg;z}x;)C%GI(GzTOc?r|P9=2zG@tocKfopBb_%V(H;7C@H(2w<Nk_tkt
zM*pOkYP>pU`zgAc`Qg0;K$7G}<j^LZ<XEXh_nyYY?na<N?no^M?h5_8A!;TaTYwjS
zly**aT8tV)?v$Lgq9N)ikRS>Xn^bKR_O5%eWOy%zB@W(6e4Gq#wSOu!?8z4tvXnE0
zyzpE}@gU@i(tHZR_ecWtv5(#Fr>CTduN^N`Pk!y8Ia6$*?p9Gx4XX&Bu=F*PTWDro
zA<Bj^UsO_UAN%x|thuY$_8zW-uR=T4d-;m>Tm17q^`Kob6PEJ<<nr|R*Nl?R%_*@Z
z*MHCsAP9FHJYu^Ky#krg4x~yvF}A|9%88{ALULjIQW5d8M+_Fp8fW=P52X!ni5XMm
zQo?8p8Yd}RoQa~)mp=*Z5`>*jfi2$3{9g5xe*gZTFjQa^71UJ-`W~is%GqKYR~X-!
zm~<Y37hs2SI6`>BFgS8}KZO@zl2i4tQG8BlT^4bww;aW;!&7u;j4*LaFPVR7$TnCn
zv^hl|rwAbbRu4YY->IjJ7cQO0<iao2bk@f7ST1>$ZR(i^3RP9p^RKwcCeE0L7@@E9
zz)@sND2yS%>#>c@Ub={cQM~R^3lC>d&hXID1NPX@pRjtW<2Bd#?X|1zja6@WK3c6#
zYu{c=rT0PysaW;KYc?IvdEf3mfYEGlAPN<4Em^X}Z)N4ml~e$a^L}SRELIOvPiVc5
zV|?eGb>8cGG3R>v>1X`2Lh{%j{pj5h=5pVPGCfc9_w?z{cW&qE`&#M4g0Z6R?;hjO
zyl5drsT9s_prEd>Y`9%}+sEzTuC4awhHbWf%a%aRBHhRv=~cDuQJ$2PPQ+>HbW4mU
zAMP-wjd;ys;h}6&Qo$vkCQ1rLf+lnxMD;X16<g{Ocw>JQJ&V{-JSrKO&%cBFc2TgZ
z<XM*;2RLWggsGm!QeIhwp9!JX?VM8jJs34{ZY_Y6vc9T&bWl}}&v(3mY&_@ImRi76
z4kA~Wk3bc8%@78%2<EuQ*7YC$6_15iQub(HqxFjfa`$LP>Q#Em&fc;#2#oNos>|`x
zF9icMy^T(Zt8Ti7;>p<<_*r&<_E&YMq>7pTsPWuCPgOi;IZLEy-ctpwN=2a%Ds-oO
zPJpguN|KaxZn2G?I>$y$Z1-bINahP^NrEeQV%<!rlqVHeM%<R}`4j6CDe7o%gAR)P
zr|1+(+U*`H42OnLMEr7gkBS`>6;PjW7sXTm^7nsb*WYl9edMDbvakHXA6mt*$#(r6
z_tB~prq9HlL<$dv5LSZMlY%6bmy*OShSC>QFhZ+^v>*jr5B}u)w(#QlwqfmhyY|jc
zaz|h+yAhFQQDRz7J`BI5Dz%g~^+(qA#O%G#)kDoESkRA*t($cGlya)x!P?%}aj__+
zAMG24F@-UBrYc79etN>gDhKe&A_=<)SmUgm6%=&HPsFqk!l3y?Lf&}e4cemy+vh&<
zDf{Pt`UiXNx#hG^jrJBb<-kXPiLO56@j$rVc*6}gnZEUvFTLcbcuN*9c27l^*CXhQ
zmT|fR0Ej75Cb3ToC{iiI>wb&t=Gbq4`OEeaU?xvJ`6R_qCHAp<@3!xK_j^>&9;0F$
zym)WT>HbP56yx`L=XHA;EWM4|ft|09MNQC(6MByu?qT;yF?2g3<u4C+DJ&d`^GLxd
z4Un5t6b4A-m)rOm3y~#r0Mr29R`P;0LKq&R>!&=k(@bo9^|-BW1uKDkMLvmFEI;B@
zgL6Yvo6#3Tq+Y`1hTiC|%)2Lrg3=EqQ{m-HKw(o+0YFIGx7ynE|7M^3wci9>Xo&sc
zfBOp?JL_tjJ{JR3Kta?jL<4pGJgKiBD<XzZh|yR8r0#$wph=NxvK>|2R6Fn6yBQ?B
zS8UppDYTg$un*kvF)$#wo|rJ!Zt*FS`Y}Zw$M=%5p#HshExIe=ATH7gtY}SoMihfU
z?LmwbrgbU`fS$?0SXWIB|Ftm};lOdaW{56kWdk52=SF+u(6xPEvkywo=xq;cCvGow
z|HGS!tH!d2_ug9tE$b#KPKtrn<0n<lO?eIpECInc9B;%jYz`BYq>Q>hQVMfNpG1qC
zN-r^6oNf6-aaHeEg5F}Hj*d$*R`e~mdX*beAq!R5B?6{DY}@goG^DC2Ylv;#*Wgo;
z;`<4<M#vJy#zh=f523E4Fblb>m}>){2k1IQaU!7m_C_~ya!^t#zS~9krXA3ZnBaTn
zcY5c0q?CeX9LpRxQDVcv6+Q3xjr11ou|h}+qHw>_(slcpB+QguNz>BPo9&VrJjeg_
z!5vuocn==Bbj)-;fbK87Fz&g_!E@Jos*p~FJ)w(0(FygVYp(L<^_%UrRj*?V)B;K~
z+D|ck`gB*^YQy^0x4z|GvVd$(96KJ?h|S68z7!%C%G*N^tzsVZs4#+&*A5CJ$BqH=
z5ldfd_7-rU`)P$4M*pfp-1@FZm=vS)LV`ez{dp>VSD%JT==jy&c@pH7D!3w|(KS4j
z%tCqLqD!F=htNI*)Gf)pkk%26hb{vhD?0N4ZuCq#uD9R{R;5CzsXP|CBs4uqx7DsX
z0I#v22l;fD)ty!gVUy=-W4eziteY{OLYIL^!%<OyD4|S~$|Brrs+>sbqO%M3=$qXl
zI>|js{ca?~BEFZ$ovj(|S=2A!tsJkTCMT~7u#g?}LZ3wOlmOXVY&-WLSG-U#=$OF2
z!9WSRPK9g9eeaduO=VDjO5Z46IUtke0{z-3W<ajA0ov4JTlND^#C?U)l1aJbMPbop
zx}7qGeiFuGQm7<uEFIl;qtRGi#&vP2*GhBk5TX|w2EZYop`fk>A5;@U^a>tG2c<1i
zOfFfHXVPtTAEEs~wc-D}u~1BBoGb7|plLl;0A^8v@q77-6pP<@yrl|D#<lq|r>LRa
zy&zS->Pe!oN{UgO>KSId$SKbruXpe7>XY8Pk?tCy#e=d6<;tOc0mLu4;U?Si%H#G9
zC{pF+l{Rh8#q=&KFWJ3BBot*NrDix&`fz<ufvRWM@f}>#+oaTUDWU1(B*Ua1uOJm+
ziU`lL=Y6kTPZb%Tr1$%MDd_a;7@sG3SFy8``ke6uvD8~n)Dw6meKf^L%E7lR6x0md
z7>*T$Jnx_ceFiTIdj9-*^g!3!PI^9<U3In10=o6(msfc2{!~^~Kd-*_Iy~ZqfQGzG
z>so^!C!m&LV5;k0762kKYV3GGM)uS1KN=95sd(bgdx7MYS6z$8T*Tkc0Uk5lZoK(s
zhg%h;EL^n6u>wMYZvV=;uPx408K?bzn(&JkU_~yb1fTwvC!*FFzgE;U9BeL*b^BVM
zd-<e`&7ihZ>8KA{>v{bsq}-F9<D6<(t7OeZ;;epK>9`<MUe}q@q)j{})&EPVVX@4M
zYgu|mjkGp7JfHH~9UAPQ5wSc=D~hEGV3Y-mm)W-M>#g=!5db06ZRiLg(t+t8#H1Sm
zNd+4?&yA_GDv@yS;aIh%hzEk~&=fq$-Ykucr5#lj=E5S=B)>R1k>s^BYwL=qFB#H(
z%@Xn>^=<AuR`zjpO8_c8Uugko#K*CG^;>}UqM6gFca*8#=yQjA37gcoh=g?Hghe})
zI8TpdiKD9G`}bBs_fN}-BZ9@6*dmV=bSnt!K@*uQcIsF9K0Z^X4PHYqH9|X6m_w>Q
zLA)m_9=&D3#}cMjy{Y#w5GAT(eP#G19`_a$ev;v03od{;^!>_Y-FmQ7KlGZsUZ&?x
z$Hr&7?`}_&^2flHb6CVUHyJ#?u#TG0Bk+;iZn*`8OKxA|HYwP;<3o4(WFm#YCn6}r
zgr_dM?SprPo@Mr0pe=$-RL}E};W>=8n;rE-%A4%64}bJt7o1^!w%Mn~Pjn@w^Iv@F
zW!}m)|KddsY|$2Z-2-5qvmSb03R`q1!5I;nE8occQ!$<Jz2i1FRaGZK#U2EZV2=fC
zOu-lGsUo^}T1cV4`1HJ$o)$Cb^>oH&`uBQ2Q<9dGk)7^b8EDW0=ZfM$6k+tIdW?fi
zQMZQLl{8M$+m_T9?_+N1m-msS>6Kw$JlInfhCL1ENUTb9Q2efFHH?uxyG+qJ`clnj
zlL_7Vx<?W~e45tC>b>56?bspe|5neL2-7=v=X^R}wf__fTEyZtRVj-bX51zsQoU9o
zSoWFi0D?e$zsA{*3l*&0lxLdrIzjvU$vkfyN(*gB>Q_`~EO>T(lkC|yG+kb?haBoA
zG|z`T-iz<LZxZ!!_P6FeqYfABekB7V0p$_fNCA1jKEN+(pw~ECy-(Y#no&VcqRq;2
z$wRB1_E!p5-m`;INJP2JBXlmPP46cS*x}wH<MbLvSH`{3I*SmWG{RJ1CjN@a>^vU!
ze3f$QrDc%F()ZTBND6y3vHEj0f0%-z)9MwES``H);_+h-y@oHuVR13Wx!zk^uPeII
zo;;JOTsV&<?&qsXxzt@w#qWoo!IKIpJvV&>{VQz$s2D7uy9u}`8M+nisO3*eI@yVl
z`I980Qf|eBFG?Av#;~1^!(N5Gi&S=We7ZgKBNC_UPcEnXJa*1fXePtQic^P~?0Y81
zgf+?V;_=!!>n88rV@6R_AZ^V}w66at6m+_!aHSmytklmlUf>MZ*A<5LBcXs(EJ|PW
zh**8kBJdGk{0IR^o8Yr*)gv2}bKDD=dJE|kZ@ODdtCXC1B)PkPBSZTn!<Be94~q#m
zmIuMJy3l($@F$4V4na5w`AZnkZKp%dy8yUD;VTPnHJ{=|{nI>NF`O#PHCH)bbHO7)
zrm&i;ZgnAOyCQ`aj7^1ynLiGevxA>-ocFRqd>VG*bEO0EL`prtO=^uibQyzFMBj^r
zXWWjMstDrWd(vF0U`;5zNcei#*t?bjodpCcO)&%2N|2U9j`Mmv3X13+Pz32T*v&`w
z9if9^h%<_mvwDK1RMh&H2=Syw#s<DgztnG>&49?HxG|#eZucDaBd!kbCe4CfmvBGj
zNe7@1&z(kH9!>+I6-8aVcb+<o*jh?__uQ7LXY%1}XUW94%7~}?tYmemki3Nqm1JC7
z(rsn?5RMrH1I}$B6W<!xhWtt?=sv?Q={(jx1b9XSFd*R{S&u!w(`}hOEE;+9{y`Mt
zc3&z~Vg@TWyhQY=v^5ZK-_P!dT|HiY4^hrEy4To33kXczefIv>DKqL%ckg|N5Bs9+
zaILV--9uSt<AzKGLO5?`&(bpv=g+47;%6QOUWbn#w!i<@-`c0{`<#uX*H)t?AAI0J
z`{EbB2#))Hd+gCi?em}iyjN{M_VCZ?m)^^OfFX9%jW>E1g6=~evgU6K{Ym;Rj83Hb
z9--O@4*I^`I~iEOFaiKd9P9)|_oMH9$3A-ZN39y@P*reeyLY5qZ%hZFS66f;5R|Yk
z5m<!;w;Ko{94Sv%N>U+E83f@a8V`{RT~qkddQYCPSGM|Jp&U@NiG@9_5O!Hvi9Pbj
zLq42i@fAy%;-t~31@`>&PgC?Z!d5f4IzPY2Zf6pga_&cHA*&fS1aOy9t0=1^{2jO<
zx`pUIBJVLG*f=`Wm*9-4B@}gq$VG3~NbY~8w2*pSIyy^tp1y%cy5CXn@21aPyCJWA
z_3*a;;!L8wbXZWQ?ciaD{J-ca$Qw^7WI*;Atw$oV5hx+S^N|ObnKv1N_Gz}~Y%Cr~
zBa;U?+gUso9~}^pN1yc6S9G-ByX@nDM3f<Xo;0?)AD?ja+#n0)mHz$8DCqOugjBZ7
zfG*E<x%>HEB+63SEdu!a+4CitK70I(=kk2#@|{c;DbsroqWImqi%jk`gJXIzX9zpX
zJCRaS3)K_9_=U}yHpecyXp(*VrRQmdddz<3x4&q+cWkp&udTGZ?!4Vc^{svDP5b??
z`~m1-wJ1%7CxD^+`s=Ux;QPs-h3(w2(-zU^Tv=6Nk3IGnXk*izBmerZ|JwfG5B|VM
zLO%5HLw3ocOPES_%<lj34{a8s{jR#^8hhcTm%UK!w%cxF_{lz7vu2ImKwH;P#!MbK
zaKN5@_E}rNY--K%{^1XQXk!^^dF7Q?*@_om_Rm#yuHv(WixzS(Q|#e~9`ePx@ur*H
zxY!BM%G+z-_T2i1KYSM$%O{vW{eUfCGS<~sU1iU|@SLrAdksdz-3(Bu;~A<v_b#QN
z@9*N?4l^9)rI%K4UpJwU1sDU=1$q3h{@veNHM7Zo>x;h)_HiliC5IDautU8MNhPWD
z`uUtrJ5ZzfoGud7Puj2cDaaGvcFNayFSSM^1UW9?V)VGfo+eNxK4A!v{|fMbKev#n
z(VwZ&mRP#zx&yT}eq|K&KnOe?fh1am26CbceyoJKXXGMF$vGuq4Gr{ieGz^p4AILz
zlaUZxyaT<F0UY0#!j3J%0i5cb4jqWW(EkNOt566(Q%#F95#rYo5S%t`+~pqO;>$1d
zQG*8<h;aS&*8wuJ)=o3w=c0?|+aQhMBs8s;6zSuSJ`6J6)u4y{$ZojqI(zZO7nmM(
zjSU@AgQEY1EuvC;!GihB$StE4>u0V=HIB6z!(hyqxwdiRdY=Wnaq|{Nh?dy{KlzD=
z*M|avQwnlc0iN|6uf1wV4jr_iH8<E#e)Izy&y43IOx60u<Bu@Xasv~%=JLHC+p?ug
z?e&!_nE(7XQ<4sOIKH?j-|o5lL-w6-KIc=(Ml%Za2jBgUhfU|ro@HCMZ01--TsGF(
ztQpgRRed0Y`k8(egTVxxW+rYi;Z1$unqMuUbnxH-TfcstO`I^1aht<|Or@nP1yQg6
zy-1^*dq}(fgzG?Q<K0)%lG=S~jGphy3seq4>mctq=BR;7gL7Hy@SPB8Nh+PQ8vz4d
z?{xQdA<l8`&)fGm)7@9^_d@hFUbA2{4a{(Q&lPm08_=h+iWFdco^)6Nsmq+{_2Tb1
zJ!WY3B$&n>X(?y@652@O*v`4K(?IWAx1DN*>$;u+y+B6nx!li%W|Rwk4_ca@)#4J;
zn#`qzQ*L+!;attv{h$Bqf7>l;gW9$g*w436UR!PA#0i9T*VxplQ&EaX9h3VMbD}jP
zSXJCLC}Jt$cbLz-^y+2yZ~yYIAd0=>Oza90B|B--Bs|heAFy#Fq485pPScFtE3aIJ
zLVt<tZ1JSYyg9QyoLmmT$?|8G+q$>k=9nvO@nx4WkGsvDeBuc^jsfwRPkqu}edSeG
zjy24qzU-2Pws`{+pys2f3D55#q&|KEbE8qfgQ^F)5u&MOvr)j)rcJZI{oB8#<!czg
zE7#eBO+Uvgewphm1$^f^+xq`DGY|MA)Xh*EO<t4YAmZ8v{A3BpXNm%h9yQXpy@QrN
z@yF=VBSBD`<T>?vAWTEJ{@s0@51sT>`sZ`5?%zF&au(vB%kfBVB)|{!W@>v^kTDK3
z9Gxz(_qj@$e)d7K)^91CKa-TgKz24>pG@m<&ZV_>Aomj=dp>*K{d#9Bg6zI$@fy7Q
z+;J`|@+<wF?t$js_E0*@Hr?V!;qVLktbJ?WU}$7^v3KLnGP`o$M`g|=>4Z~;51!`o
z9+^WRsUlg$P(rg)`1rZ!pS3x2=i3(Y(CgN3v|Dbw-IgxB#J=^-@7oZ1n2!Qda`(sX
zwXqY%+kg4J-?RLp691<*seCU41E-y7I+_Q)Y2!v8q9M=nrI%Owb*dR1`RUJm);;zr
zpguL*yA9>J7(}vHUwy@%dg>{=@~SIs)20pf&bqbCnV#Z6C~MwYZLhxeip`rh&*tOB
z|IU|x+d)xoz4cZUJYzVi3NK;=qMk{i=gTj@$sT|FaXWPIpxt%XU66>zCT7_;zxgdf
z=0oh0pZuhI-k<&4XFxrhM!x+w>|5Xdrak(^BX;x6H!(hQup1NK2B77}8*jBiV1^69
zOL=S!`|$QMl!}V!q_p+#+u#1S{m~zeu)!#P&7yuUUVVAnXQQ*sX|TU1I!nKFjF8gp
z6e)&&FAp{xD778t3iNpOcq6lsuj%gp+?9R^Z=c<4NL||tx6b|TL+{To?6tc~(x4gQ
z>h11T+`hU|tw=&t^Y?qApfj<MdXqzXA?uE6L;zuNdw(-s1#5Z|Ou0tnHLJ}*MH)UG
z%3Jm|x=fc5H-x;Kvm2pEfeK^`q+SAD_r-tuJI@z7H1y}V*%!{0xYg*kqjYs53Zm-o
zaP70}R-s<G72Q?j=wZQA4j>0v^z0VExy{*3PEyYznA`#7DXf5(mPL*HF{8)J*fScD
zo_I4=ewiMZc~M9}+v)!5v&5{gq+ZI`wKW08Md^Sj0OIfQAKNv0^jI5wW3|;(4YNP^
z!#}3*s~n|ti?_ZEp%|>aBcF*%H+zfAtXXqy>Wo?RJrBc!E<t$~*j*pF+aW#mGmoiQ
zH{Esz)!v0RWA--pl1Gl6U?0Bw<6giuxTf01PMnNaJ`v@Xi&8JOg_ohMnMXc|khVg`
zV*os<B%eER>U7Uf*ETl$H4972Jd|C?HA|UsJAA|linhiuj&qPzR8`xDKKv1@sHnuK
zxWf_9vYBh$#C-4a>Kf*H(|609>C2WbLwR4uz0I}}W5?OhQDZ1x8*8KSwm*9BeRhyg
z_kxQq@~DEwZ;qchjcb)zZC$-xbNvUb6c2gac!u0Ctfj8LnL#nrY{aOsRt9uwMOlr9
z{=*#Y2)R!JJf%3sfA_6O(rUa_XBVRB=q&Op`_(ahd^hpE<mZ{DQ`3e*{e01LJMSrl
zB4n%3n&-nV_$OeJ9OzD{30Ya1^9^rzfvMo2CB!XUHpED5q3AClwrMdV|5iC`9hImj
zOyWl*?k&y3xLg1>SRDwe9M{(cmZDPrGn%C=-ispcUi9iX|6z=#<9JIZ={vk36f`|=
zcqjQ9h%!v4Gcx^tzkS-NawH9nq@#+=_CM$dZ?Tos_xgb#n==V==o-It1)Yg<?j?2m
zc_UuH^y)ctfv?NNg-i)S?*b$a=7<mzVj^M!flGAxlq$iNIv+?u%V>12i29y|56!uJ
zNQP#%`fRvVgTOU<vXCnJJ<&UNwl$D4_A3L1BBtek_%7U&Dt%#S{&O2#y{L}Frb`QX
zOTsUJ;_J$B@GPANJ#e8o&|N&2<9oACTK_o%<s9}tvb$VChn#)bBh6aY4Cq3uDy_1P
zmM)adXje{}B&79h<M-2e!<E(5!CT<FAGq-*pjO++NjKwB77!{P;hyqH6jcje=dj_x
zebP6*c*!!a<Zj{nLWR=zrSz}6{zk5$S<<Sm2IORD8CBTrHeu3an>=lXS51!@m+x(R
zr#W8>UiRp56K&G8>DJuD_xR4$*WTdw*-ZPF6r>8ZhL0TM;rF4#%kf|VL0PcStI2hr
zbq!5+^))xR!JwkEdZ0;*87>g+rPXS|JD)h2@b`2E4XC}Wpwu^Ra5dBD_*^;ZVMGFS
zzh&jsu7qW96ql4+Nm+$MMP7FK5;q96rlFTNvPq+T3Z6#lehh>*`c}~0rDEm=W70fM
zQP2aqr5?v7<Wyo<MnF##uRCB3H0Kl4G}00I(S_n`KSMhkxqVlHg4cvuG4~NKjFHv(
z9e+N|WOw{|(XU{Xz2n2VKR~5Q|NA<J`Ru_~NW<}JS6BUo`l_kpEA)|;>cdvETu5c8
z?a=EpxK|qOxHk<8a^m;*9D_`sMFvUg`e&+K6Vf)rG-Kb}a+dw}$B#cxD?!e2w}b5H
z{z~^=->3hjE9eUy%1Aw5e?=lriy3Tmw|kV=E7pmKI834mmQgTEBj`+i?LzTNQL0eP
zN6)E+MvMa!wFpyOxlCpTceG0-_PzA6SK-R}Y!h#yeH9}KQAh$$SbrT|ErcD(4RZbZ
zrdkG(w=fpDGRzm|vd(zoBOghZ47UYD?{LXfPc)M?J4XsmeC?NUje*`{)VLNEdIXq6
zDIp1?R`RT}wOaTY)0NtiB*5bS<hpuBQSu#CHVZ&PN?8lviXzsz+fmj!wt?fkS{&MJ
z0ef2t*HOsWkB$!ds=dEB2P2>bMUSvX5jUSEr^|&;^SiUW1R>uO+L)BE_EtjrWNlrj
zu-3V`clF3BRIdAM*M0E*>4wwZQl-#zKIb1cbePN1dc0w$MXb*{&ZBeY0g};*B5#eN
zRucGmjL2+agr=TR$G0(#P?-500%gIwmLM1H={)+pmdbDa%+l=gpffUloeP~@2)S@B
z*FEb)IbX-hKuT3|L)ueXGxWr3zVsPniXb&LwN2RY0=@|&3c_@{4#1Cqh0%B({?<B&
z9%<b#<`371CTF>-K%!_Ke8Lb42579X6Us!2UWj-Y_o^?DCv8~;6b^#%FWO;*U2WY-
z_7>WAd8m_z<J_=yo#cLhinExSJI{E#&nh3%snT?3PUr3RE&vQ?OSjLNUgxY&bvBo~
zhiB>0qsT)2r7P(8Aua^L5A+=U9q)A2LxBhXISl)DJXgq0BNY677{$k#%i_g5%|poM
zD&)=I9Y9QF<*~}Fa5kt>xm3F55U<K5Jd~R+yzcInRqQFdVoZD_(;x%!C1ZfXo}xnT
z0mfSO!izS3L=~RdrMB*^P4*g7m#)0^!`{p5XcO>?!jhdX0HmNpkD@bIWN^IOEm84a
zy!(~1{&?LCj=mWwR9z+*)gujxdV~~$ypvoMR35@g=wO;)CB-HQCFP_ZVjUxe<#U_)
zegXZ=Cyt-+ko3%%v%G*xLR897LRdmn3RKnFEhu2cU;@8(*<nUh4jop*sL28VPy$lf
z$>S#-(owly33CCXxH#mx`CM1Ia(S%<gsJ7}w0Yk&pE>+vCv9J+{5}U!Fs9-+@3qFT
zE2dvr?O}%xANE2uJ$EVNF<TvY1tlC!kyGoH?oWN&K7x}9@Kd$5Hj|<<dEmP9V)FDM
z_k0GgxrE7W;eGuJL5a}ctF`kKlJnR=JlcT^`1AQje{!R*bNBzfNNJtXggzo6{6p(;
zx;EqqYvR#vsb1;9;03EMy)akspU@xtEQ3v<@S+?jsZg{d*IF_ticCn~D~ul4fVB@Z
zkCQ%g=u~i;Pk9iJr$LwP+)F<9kws_1&JAzcr58^m)w0lDc;PkM`1Wfy=dxwi%#;%O
z&YDFp+Qyu4xfNuH_BSA%#aHNmT{7FPAUon?2Sz^^>K-z?(@c&^Zw9<)3ObWpzEH=U
z|7K|MVvkuuT;7fBT09CEsSA&#nf8~C<_0E$hZcx4VlV__Gs3Ik*g-q82hX|Tgf$%5
zX=m`9vYio=uaL)y{*I_Fln8WJ(5cLoINTWk_(&{jF>K?}y_Q|pX>~{T<Kp2#;juR#
z-)&8;O!wh2@)){ML~b%4tGwL-EA(tJlO_rM{MRl04)zsAiH(y?LG{y}y{~(Y4WLYD
zDvn_2SP20S8>%{)>0~V^p$<lc7L|p(ZB^AESCS2cf>l(tX~Sj;w>Eo^vJ_=q^D&gz
zVSD)Dhsht8`SFD)=i|qZxU#AyBwk-vOR-oZ`QRE4bxLtbk?+~Jo7vJ#LZip}hU;!5
zZ#>8j9@qy!2>VBy(uotbpmf!^QK{)&hv;#Z;xDI7>(Ie{7=`&<uaf($2aSyLbFI3Q
z$E_ZZy}GI#1K<$tTIE(sUbuzpzqMwSz5Vt(_LZ-E#rEvoLowQGcGXo^aout|ux~Ht
zEw>^<-!c$ZtbEzg!}Ra@7hka9!v}NiA~y(*9X-i&Roc;`$L&pq#9V*f4TQom802k5
z;3RJ7YHcOB^}h_#5IyN8lkdcP=nANh=vk^!mgzbBqoaO#$MsblnUg9DsBy|g=jOu8
zIT&*7P1Z~lqYDE{6QdM`@W=~5H%&)(TN|`x4SCR6p*0-b3UXV$_uRXu?9nlIA6y+P
z&mGKEq8#pQL`G`}wD>C#>2|?_!sqLld)A7g?rJ_`^~d)TZK0;%(0<GAXflL~ojR}+
z7}_QuN0~<oNCRCgr&ta(`>XJ~YIDN*;~9kgtzEj$yYEXR`Md@wy7!bwU?%79cYiWD
zNyf*dF&;vJh3`$$G>X#^PPKma|4%6BjMp*Efx+$%ezX(2uyC<f^Z8eV;d}JJZd?8O
zs|<_Z0qHlpl63FDizHMaf%n1$m>2hMwUU|<_S*6%tnSz$s8^m(%o(~!5L5wKDuQs7
zu!hn6y~sNg<0ar5qx%ifMy}Qc^U15vX|scE_4cQ${s;j*(yE8%*^AHIZ?ynUDEFwa
z`;d|2Y(7OtqsC3~(UcSwbKZa;<s_4#L3%;LKfTsH!;5FUv6-JQ76krNLXM#rG8p7R
z?n7aI?f-t&igSystWqB5DZAr?cR1?T0}ni47gOD>9P@vC=Ra)h=n=Fwtp`M8HI>*)
z@u2tF|N38l=?ZVzvSs$wul~Isd+)vX+VbVgy%PHKU-*L63?{q`oz=IVq6KO<*EnJK
z|KxrfHe|Sc-~%^t4|~|ta(m+O$LL3Hw9kI#bF@i~w`Z3>Yv1_BHvk{G*juQ6a{o`<
zqyFq?KWjgsU;4<ABev+0OKb|jB=z-m_TqC#><L=2W=x-9w_;5E^FRMH;3vB%E}KK8
zbs?48@7O>6)7KEVK$sGu|H+SkLVkR*ed$YI;_niB;;~0~ri1qJkAED{la2NlfAQxa
zhTXw;OYEmV{V}an<J{o**ROwre(-9$@~UebPu%$_j^CYw*X*>Op+e7?JfZ_r_x@Z2
zcxKU{Se7Ks>mXr-;SP#hKC&gZ)pl%q+cq<Mx$f98_*!}1$cXlwvWmwvueqI!S+<o8
z9%1{Ry5AZAv~k5M<?Cw{QdvTfiz`eLBS95C6MegU3-=P>LnGPa;wbWb6*A}VJe2>_
z(A}dCJ!mx}#@mUb`=HTXR)6Xk#sqa17!D&RO|^LouAq34Itx-7EqK&j%3te3eGKsE
zy-#Q7*ARt?<Z+KLr`mb349kT3<6|<FXPFg=b-y`3cjEuzD@KYs*3<rZ_)O38o+#*Z
zA^y}yJ>TySh;fw<6hVaYFCXWYPuMBDv&mMz@Qk(99<zm1%#OeLN-Hg6K)ly$E4WC`
z4TYDd&=m^s3^P<a$S1XSDbJ@o5MH!~DWt$HCPRRMSvncakShfdDP@QAb7l@oG*>x1
z2SC<_s(3^=$G}FCk3NI7-PCxBYgKwxWp+NcGoBAgO)ntYx%VLbyD!`B%^PjuQpOw>
zlvBa0naUb77lKsXdoKH4wf=}Y;i2@i@GdBvP?LG_vwdY?bdU*~hN~qC^P~)1sHhh@
z$MdkmhYz<KuDsTs#?ZR^BOj*4YQ0?p_{c(9ns)BkZVN#N`|PJbjfYyvcRTIxzxsD5
z>J7GK>t<KR8YTIIAAX+-=dpOwh2A2SUzq1(Co8CU)^!wIk@7x_0$i|QuH}C09sp4m
z)8E{V=Y5pBX}7}Se48+FmQ_@iqHt^NE!wO8_`m%jO0n9$@$X-^-}&7y+wPsa?eWJR
z^$`01_=~>){Ny3}wBPX1w9vt>zUoTbjS=wu?|;{>z3v)PB!%8<-G;E8I(3SD^rIgp
zEI$q7<7f7FfA=>an>}oAzOl-q151}Kaic|JG-phoO3T&FZfM+i(~aKit-kB|^DnZG
zee7d)Ijv!yvyY0C;s{0NJJOB&qd)qiy5x7xMklGCrBkr}d4`wDlpZ5>C~4xf6{=cV
zFnn_CbnRh#<<+P8z00n<`f?jJloSVEX;zkIg@?i`pI<DAq$z38L`c0+hr;*Ikb22h
zJ%c>gsL(4Eph<Q_(LL4GsK6^&IzfJ<?2YeBXE63VrR0$bG9dD}hmOu>>K;xLof(AU
zEwBQv#a$4I>#!CgO6#`lus2_L(yB*Jw%H4>a9Pymk&}24Gg-{DQ$_;nIPGCkrF3_N
zkx+Wcx4Yj*CU-R;y^%OL_LO6#tF`VS-x3#(en}|l|3u>^&uww~4r}#1Ul1C-cihPu
z0#mz`hqUpG^H7{GKlL!c58w=c{!>=Uj9(FZ2Z~#T8b0`&TyqB&WL|ceS2s#QYc6w%
zsYg`sh8*jjau}YG8iMt{TmDI~x^>M#DjL#Dzo%kxJCk`D8HVb_1EwA03_o)yOe@2K
z>1bE$1I&f)&JqqYtr}U?RW@bnWV__jMIcN)V=JEcxh=Wz4unFvwMhslw+eS>rY6t6
zGnopl3#W+Bl~Tg@biX|d<l@nN%0&;NC%Kw-q-x+ThcX0W1$o<_-v3i?8&W}35koTC
zDaKMkSO+2QBS(%}EoqMO@^TwFa-=I|g~SDMIdASX2M1}USnJ22dsX6Tju|rnXwGrL
zC`5?n;=MLgbkzu&SP_C+LR$24%{5oscfa#J?q{%Fje#K26{4BO4eC|L+-jY-igVVX
zgpV9P;(2l1pJ+>7zv$>%5Y65O<fNA8XhuPMPMT}S2xv{J28T{h5-n)OXeb6#T<%aF
z;q$t>I@-1>t(4ZW8p8YXDjo+4)hm0sp(2jevo?{xETs3^xl1}h9^QbrDaM$Nzc}zS
z^mobBP<MaFo;$rJ3r=GNt)7eg+%9XXKTN&IW6TquWlNVW_Ii>tC_cwcr@cx_y7LTx
zFz|R*wv2J*`n6w##nqvqVlMUTE57Vbg@%@dItib3;zL?gP#O&TkiH3nR^n$DO-R-_
zIFEbol6sschx_Qv_po;b=WlHX&z)n-vRW-4dD!I`;6oU>I>nA&R%<_h;1PS{1)k;V
zTPa!%wL2MGI%iqj{^UuzIR!zk_oSEeq@Rp5x|DH>r|kAnsKW>?g~8nlKO^2qScBo7
z-xCiy!D5LD!t-H=U&43gfoc*FJ)*@WxwdA-D^@_k*F7J<+d2u`32Z@mTnZ|^dRrc}
zyc|Ipw!=_)IaFZ6MD6m3VWMW3PRds~%DD1XPay^p5evpqo7mFKc{ynaX@{Sxh;3@3
znm3yHsu|P4^A^K3bN*m0%c50VMmxjR^C?PeBZlo>v3uL(q{&07fa#<6e8|4}@87l6
zue@lBufHAT60GX;B;SOxJD=U@j~U;!bEiCf>{V&6YHDf-0neuYxzy%fbg_FjS6+Rs
zD_e!KXU|<=(`U}MU3>OX@!CNv(k#N$585(Nz%IRP3BuGcjHcV9$&*3<dd60-c^i1p
z8*KIJSAhmy;8pkn4f)OA{Gx}7=gpgs2Rp~MZryHcK_9z%*)?|2f{R@cuUfSR51Mu>
zz(d-g%bRbxjj;BQQTlV((|hf~`ycea<!foP`Ww)|9)0W=cIA~<(yBGo^X1BeKgPAP
zq0QUw_>hOu+uM($7_Q;o+c6w!Kt3C8d-oqA1b!z5#Dne`&zpBKIp$Loh0V1`84fah
zSQjDnMF{;uJm!Ut5cVo5pP94gdf#|yxx)N!0daawqM$8VYmte__K-><<??Q{Y4$}&
znWlLLOoyIq4pA??vQc;%^0i{cGd6qXM0)FQuqNsYn$^}M*&{jclf+c4h%!_v4QD`=
z--^{qwsg?erU2O)3^d6R6*J~YVe@KN!5+t`{-L#{6M2OZ@7E7XGlyCAdR7@zDpqva
zBqhy-^<6~+^N7H8v^9Gg%nQwtZ;r1{CAW7kbja#bgs#m74=S}!edZ(fwXgoG?cDsf
zO`LVPHNg)V=gkJZpuZYl=q<03besMT(@WW)yu<64uAncJmD)E`#ccxv@t(uk5|N&i
zlLvhkhNhG5u@*-E?c1}<?zsILuUKsMurNc@v2Js`4MM0>U0@IobNIv;pMS$Wh}`@$
zghDT6>d_&vl(%ute7kbVVz2Jqv17M0MFk$mjF~gt>Qy_BU>&tnqwu_hhdh4#c%OKr
z4cxeCqYpt)E6m<K`|;=oG5BDV?cBA8-q=yLo<gOTwlfILS$6W+DLX_+JBMD}c7@fW
zJi7NZ!ca@ET58|@-cPNe_N3(jBH`Y8NMgBg9Ox?uwt;_dpx4Rt_<<<;RQe32OsETJ
zLqV%AcqI8g<@)CjzQofWRfC7S_c0Y^EYOi$iuCTd^CO|+8;LppqD8K3<+X|~=FPp>
zbGo<P_96GO1@3X@ox|~t^K9+gYe5RT+&$frl2TwfFK5rP2sPi$d$eQG$~0q!=)=hI
zPWEdQQ)%4<WTpmVeBtw7bX@ELyxUKG`g2~?b&Nu-nX~6XuXlLCSO<GMe1yEMEc^H;
zK8@#=&v?jUhGN{~533@x*5+V1-h2}V8z~Wa(_i@f$lz7;?1~Hwt{!S1yXU@8wN9v8
z{m+XozRb5|+=NLUwpS$LjyvvjK2eC<?L+tM^op{g9=Ym=S|U=qPz78u-3){-&V|-I
zD%Y#{O;0OD8;Z5E`6pxh@PQr3j?;F@;zia*+glDEvml35;4KC0)pf|0`SWI2<)A!!
z{<#&Fi<}q)aLuKB=e5_@veyT_eqia6%YBkqU2TK+&5s^6oce)@j$YSLTaUrF&0%L1
z)e*hO@DzT$6!bQrYo`M7x)qsJSK9~}&PY;sMHCm-(|$LYLc(`2!pd#d?5Vb6*ETy@
zj{>JA<II^t@BhjsQrJp6mePGou2^6zUj=`C@;qvGC?IqP<lJ6q_bP27IF9?J#w5=v
zWOLRV9T4rLz0cUIkEy>$Xen~3Ggr|1g6Atd=o*~z$P{*@7QbF{XnVS+8_+|Y+ddBH
zTXA!T|BRk1{RyyC30D^*_;zhsN3O7dK>%a%o+<1Q2Ss5ddCdNTDGCs9!wG?o9#P{^
zkdr1%wPAyY*ong@FlpPo*R-Z`5Fzty+rN9C_dqV7xaY{x6Si&pE*I{tt&Lu6R9qxR
zr#id-I9B!wJfUSadEzL%dBUZqX`AV2#7i$nXja*}b(@@*Cr=#hJ+Rf~CAM?pZiGOA
z8_a6sIYX<35rS8bV=LD51oELHMh~`KJ2u$Ni?6a)!e*gAwR?~|8P$or8h_Y#A$-(h
z6VeO1l!M~Hz<_qYuY=>K3=Ho1I|O5#=L=pyXvdPr>+Mw-JetfT7|nL-4GIV&dutXa
zC_>Rn$vLQlzR5moWMmG|mt_@%DAf{$Vpphg=BzoMn$YLsEqzA{H3u(O9dezX#|t18
zCB@~g@TIur0V&#23UsJE{WiR$Qc%u>NmItqihF<@RsBJmheO$QIdI%(1z~#Sx^+EO
zVEg&_P}lKdL+(+(s4}~hsE(dj&nHhQJZG_o#ND35V+;3Z&})fDbo5z1Mq!r_seHC%
z1i%p~EiX!n!h5kXBvFz|bxB|#7eL8P^QCw<jKI`$#=oar*Ja=NzVw9R!(gUlWp~(~
z9b0Sy5sx9X&owvDpPpS9TKl{jTlA*1SDTekh&2k?F%n~O@7^QGl{uu^23rx{!x`kt
zxY1Lr98j3iBS%rhwbo%`=gygFZ@s;a7CW`*LAPDaL{h4#`aX@fJIHo!-^jW4;kjQ&
zeM+@el@}RvQ|x$a1BI~JHk>rf9&*bwrjGM5qGe@O+;@jZVnlnfpXZ2Z&_PxfbVyoe
z;oRA_a>Z&pb@ZrJ44=et1B7+$cYEWVNIfvT*Uc{K_dMsjpJ)5NbYpjliS96kp1aGO
zAX3A7nJZ{#FSP=Zqfkzi%}}MXUV1O|(86vKXnhp<q!wW$DkjrDTly8vM8WqAf%R2c
znW)T;n7o&v8{L=VjYzOScv70Rbw_Q`;9~klso8E&*qD3{{MJtB35n)CiP=aj6>#m?
zz8&kdiriue7Hc)$G6g=IPZsf{iQ}+xUw0VB;S}05!Yp}I$L`$ymJ4eMpKOZCs!-ym
zY8kkI&>uZ|s4ZE%#HwMs?b~+R1gdxEfd@Svh{*DaV#jOlz+l+Gq@^WG<}o>FjJ@*m
zIy@p&E%%$1g(t7;dm)>{ueh+)4B=rzD{arAV-7E%aF~Af^lOr26lG~6WtA$i&bCLH
zRzCJTM_-;(O!xiKMdkukD-zNSiDEo&Lz6rW{h|)nhaywNqpY-;bOYXwD{*QQpbshB
ze7usjHiaHhc&fIg`n8?nogiofqEmi8ZFfEsTEHe;!1)K@3H2>|4FGrIsBe+K8Rx9H
zJ@0YlB_lu>*YaLvNa$y5%;?;~U<?IrYSB>?NT<^?$jgoaF@)yT&M=FZ2eJ{$ogOtJ
z3Q&OJMKL?*NVGCV4E1P501G88JX6wBbX%RaKCOv(qn&WM?$M16fw)NMc%OLalh)Fz
z4JV*YMG=dz94@EiVFtY)_Y6lSp=<P{oXC{6VsX>AN0#h`4|J_PNK#NR6Ec%e9;)nh
zsP;J^`-T2w8Tswrrdb0DoM15}RXbRaY{7qu{<OZx+Aea>!Y?>@@C0&Wlta4~mKWPT
zTJQ2<?9$>w8wtMobI(0*bHQRSEobgF2AZH&4<9;;e95;~3?-!_%9zK!2ghK<h~abr
zOr$;nR6C5lqeqS*n<m=jmtJg5vzqbHD`=NH0X?_a`VAZHG7A1qfj0NbtE&jV7x5(Q
ztqe32b|?2NaFb4Q<B}`I1%%b<b~s6GM8yboh^Y3ae{PJ|EOn34eM_x{;T4SLVDLmo
ziY_BlZ=kf{XS_hhU-H^f^JqlZsrMQ{up+4w^{j{D;r9rOJ7$t!#?SLzXcfFjz{yR}
zo(aM*mwrD-)0UwE83^zrODJMqZ7t&kg@{n9XF`z(XZoz^o~t>1s*(38o+&OMTsqj{
z9aVL!2FT5um{NowS3c?txoUZBIe1(0l=kj92)1!KA#|<*iqEEv+wH`$I-54Nz)q2?
z+DD#HeXTXah7g7au?l#|<A7siohhfnw*h5<#Y<b5JQ?41xnSZdmyYg=(8pM8T~udg
z5v~svqLPy7LsH%B)&BWyK-)Z!{YtIB7|=!fJXjnaKV9V0iJ{ctB4tP}Ki6vl^1SzR
z{rY!&D23=lDTzkXAA-ny>#a2o_EAw$;YwJLt3nOa8I}9h@v8o=1P^=c*fD$;Fc5j^
z>_sjUs<a03gkAAU@Tllec-(}~wKqZ(Yi?=q(DLK7N~vv2`9(o*suEj@R^F~Yj}27a
zpL*o=ehGqn+cwfHyfhEGmFp;vuC^@Eue@q?7@RzL0^xiVLvVr{8+nAoMK7utS9(Ql
zRC=y9A(!#Fj7Sw1${>-^r!aaRksrM$gO#(>($|hrQ^!4&xVL^`svR!O?*H=65@8@X
ziK(zlMj$*$szKI@_CGtyL(1XtHYq7?$r+5m<5b`m;o?r4HW}cWV^#&7b<(3RoOa2T
z2@^)su2)GBBT%a#(J2?5tpZjVVVpzh6B*!b7*DzCG~t{LwN1?N-h@|8`zQBu_{a%l
zNUcK?JM;*9f0Dl&>DjL%Os?9S!UAe#BuaRUY=<9|V-fbf6L0?vKuy_2xz<E&OsD6=
zFR-vk*|2m<_*@k8g;dVrT-~Y43&bLmBK4E-UibBpvoIhJ`j<z*=Xa%n2>Jf5B=16k
zQwToo2-_k;hjq342m`Zx-X;|+UcoFPdM$_do$pjhomFVN_w2PBuD{w|1l_BeP?3c5
zBwAPw(zCb;0E&D7Am+`TYuV)NPShPCw=>Ol?b_=Y#chP2b&Wa{{TRHK15^aR_U4<O
z!^|brm6cayyZ7z|7-Nf##1gJTL3iZ^sL4iheg!a~24pCl-GzsrCHFb%({|4%at`F(
zoUCiK{Nl1;by9Wih-3Y{lAdjf*U{gX`uKdHdp6MHGrKLVRTxmBU38Q$g|bOm$SdBt
zbBhfkyjMy~+SYBG$q6g}zuUHN-{xWLXP<qRdCK<?WvNBsjkY&ezu~>Yi!ND2)FS|z
zy!65=2)kUz-Oj?hevSU<lP6BvR21c4LX|7mylhR>8A$OD88+07J}Kq{%yd?@^>`Fx
z7fSB_`|l@j{9${OD9q{84c@;zefl(xdDH6><U#G*e*ln_gRVFiEVzg;>MkFSapGhv
z;3r%0o<<ODS!c(Oov?ZH=i457`GpKNo533bQ0ah%PSS_F;hlH9kNUHp{S4<S#wa{)
zHPG@~^uS7)>)Jw3+e*vcQI4NGXBM8=VSn~nvt~I+%FdlTt%~pH`v3AT|Kg)GFS%?n
zJQW#2nQhSf;3zR&91U=n4<Rl@up;OQylq*7c)8ga)TV+gJ+VS`NOqZLMHtd28;@C6
zYp3t=<G*;uhFm-p`B8u;Jl5XXyx#Wh-ER%d^By;49695+t)Mi=rp=n_z%lI@XcZNN
zw<-8)l0i;{Wc|i1gt+&zhq)moLxuPzTJ#PcJVa+o9%1d#l+0jgabJxsZEp1I*e*PO
z8IFnwI(U;>uA*Tbiq>>78$dbg5yJ*^%)1e14rzkam&*lTv?Ro7CPee@$devd_7Ih1
za9qJ1d(PoF?^_SCl|+o@eW{=`*^rEn@%7~Y@Cp=C9LgYoRa@60gqtYpBG*D#Iaf$K
z$`yJshtme$vlyU_JaDbO{>Ey4o^tObn=p7DLT=NhJ$4E~nMIqz_U#}*(c<*>n#~B=
z={9-7be|6_;oL%=yPYcC6DR82vMyn&k@w1SPy6>Dq?M-C%0UG~Gt>9F-$RRnVXUXX
zqpOYIbJZ535Tkcc@*j#_*<~za!Sg9M*^K9PaL*o_H17(E-Wpv=IcWb`lxb?%`Ikc6
zDfe<d*GqgiO->_B#|rIs@uV!@PKVLV_o6)sMk(p_o7OW7qLh8y#NHftFSdi3$T@`h
zHdDaY02s(&l+<txr=R@jhxVl}f5|~dzV*$2w=ewq7udT!z-k_}cTj#yuUKMFKlP+n
z@2hZc_3AfCjSTW)KMlEPY-*qv`KMmI^E_iNYf$zIu`A^w`>O!uxZ>p(Z41}kw0V=a
zP;J<_9%XyPXF4lasF3o54?ajs)>WPxK7RZ-tyQO}Sy*pZUP(XnuAKmk{M5bvRj<Eh
z|MidmE8na0D8Vo$aw){@aJCe!3B;tmy~UoP68)aL@Ag6?(d)Oq{qH^=^U$FKw4VLg
zCuXf*zt%naa?ZPzJnP62BR#w?*xAr|prI}Q-+GD6JW1rTI84hMGGr9BC%f&cr9>(e
z>4=a9y-QlWsI&)mvv~eA{CbSSz*gjfhNSG>caW4r7IfH5*!lob3NR41A4D#du-Ccv
z#_Q|7b70cM!9KrR=y5XQgekv|=v)g*w+OkSYiKaWzI^~G@o6bxaMd>K-**_fQs6l5
zLWw)wgxq4^a&zc$mP}FgEa7XHD@u1FTZ&272??*ImccUBqxm>pxIgHtb0vVZUb9Ha
zLtdHF)WGG*Kpc`Nrk(liL<=JNINQXA0i4j+IOeheEX)8d@g5!;lxl|n05E(9RS$uX
z5rFS(wCk>2W=$Qn4hSGz<}mhAS?Da=f8wYMHC3~2LHHFB+T2erClscskRlgvL;wU?
zcrFJVJR*m}kacS}dN{BXCYvyMB85HbVa~&YIqV8sRkkszn5<qY>wNNwEiI>Q$Ierh
zQ^48DAvTgHYB)t$lYCQ%WUH53%9-j~C|f?Vn5+yV<CWK5vxd{Hpo@*94_YiITfKh_
z@DM&d|8D7lGe~-J=(CtCqRrI)<^XNf{iVI}(I+lAyLCf*RATPDx%R*he`*J*TAed*
z7Rq^}@5hZde!vZ@b%2h@n-tiGyy{CYy_6QFo9uUg_YYl33dedjZCbb9dZT^qYd|D2
z7()Ohx7>P*eV?A@COmR^I6@?wG+B7q0pt7Fv7;XD{>-QDvhRKOXAbE(XU;sXIm0ox
zZ@TGbd->%R0EIk*=R4SD(>)+$vU;K-cQB{=0LOp-2R|SLTIrSIy4T?p8p#N|a@i7$
z%~PHyRHR_qjH!+tuAH?)OR~LV@Suj_%?nmkg+_uQ9XWCY9Rl<009^<(W={8lMHMd!
zMpWz4hT*F4xx(z5F>J2A_F6XvWN@eweF5!a9;pxw#quLIhTlVOfA=pP1aDB$0n=ad
zW7OD*wsqYal-dDCjE(|Y69b$4v`@a%G5Qad+)M{aq57ja!zm&p*(mevc+8qvcjO3N
z7_4_8X%fkbEt_|ESApcvn$>IFkx=?<2K%pcjJ#k)Hbi3%T%tRIFSb!TBSXIgxpIm$
z$4TfxmF6PI0|!vn$ir-k!+d%cN?J{&O8Jq!^BDt5Zxm4Rzk2oCDESITj22r1-6Cm4
z$_2H~f`RR?3wqvkRFUoiJ>LuQ>`Wj|<BsU~N^$S@yW&9yf!kYCcT4)m9!!SG_)LX(
zrpJlcx(Vz)IWuaqN0_KkM#wmq01*HBbB|L^If!uJG%6oYyXOOhK$y`=LD?DgP2(Xr
zC<M7B6|tUC#iKqWG^Bh@hv#g#3*PP&zzFw{R~*Ju=D<Ar4(|(vJF3uBE=qYLeOI6a
zVkaR7DfBMz5e?^1H95H^UjuUBIe5;>|EZuaJg+=w6h6185tJGSxN*xSd-RcC*t|=x
zg4s(6V@Y@jyx%K7y1ilrm|BRJ;r8{tx*41x(>;y*2jkn0zZYBD-6=ASf@ZNLn3O|v
zoMb5vSJq*QmD=1SsM-lJ%bVTI+DSpnd(^cwh~k-NmWLV72*Ec=M{GhlO&CAXakP&!
z=t5Q6wY30u5Jgd5QK9h$MmQEARNGKqTQ+Z|HETYY+XrmLE3eQe{Q*MJBgxqo+yD5>
zuX@4O(#2QUlTSWnFTMB*tuj@7ANs@dx%867KJ22M_B!=XAD}it`AT_DG7tnx^3n@0
zxUvmi^a-lHOY9~3`h|ctdh}>-@lwBYuILA$t>=@_7Xq5R@k*4uo=*mV+H+og^;JJ!
zw5fKojT<)-h98f&Hii4>vgsHgs*z}H6try)9S~Kv3*eMr5SqP#ah!?-C}baCDMR>A
z#cAElqZE1KshRW8qGzS0*t0!{^Jhw<frrAV*T|3d!mnby)fsayf)^jNyFY#xQH#Mo
z6|AjIBRM^O;gPLe_Cquy#Vf_$g|hTn(Q3*fx)D$eHPudaTFP68!a+sK+!KfIx9r~T
z2B<vWkS})Fq^K}T@<{y~if%;R2byf<nuhOqZ?+alMW_5j?&T|Th>TI1uZV7d0`lX}
zy|CQgSoe-C{=kRm+Gg*e`%w9J_T9^L9eZw32yJH;);_OmoRv1xc&EB8-|AqD_LYN<
z=|Ork92Y{}7e+yIt^nhA;i})xfk)nzujsKf7g(FxsUZd^uxfB<=U%$Ze*W+ic&$6=
zSH0Bnh6@O9ih#SM7`dB#q`L;e!GY*yP=E+8tL|GlVWIuR`I3Y}iP_ejxWK>yKoJuK
zv@yxAB<fEfv|tQ5<Lh|AkV+L(&7DO-8PhvdT#lj!{!`=Qvg`Sy%^K=j?b%14uvb>D
zw28AXv5^z!+i5^bvIJV7)-k@<6YBF<tq--Yv{r&m;)M+y(l32zpQW3H2qs0H2=gnS
zh9J`X<&WR@an_aaA64^reDFhFE1)Xn9Ky;UyZ1gX?wU7$0YzI?-Va<?*MP^U+088!
z?F=I%d@m`5Ry^0MqXI5XiYjoxk_R7rz!n3cDde%|UwFwzF>^XcfD;JFdp>rbZAN*I
zqI!1>?-x-opeW1ix$_*IY!Ni5K4l@79X)!4>fJ#AmfYh-Yw~pd%kO=~!`Jh<w=zQM
z${kBdA3b`^K5^ft06m$2LO<YnV=2*A!k(j;8-437gS}riKaWU^3Wgx(yFdCdzxVvy
z{q}306MndI<z4>s_S-&4f!q{FF59<nKgzs>_wJ-6tH7#jhI#mQ%Ji9zLgwvWt`tR|
zYBvf3+*{O~rd?e1yKn!w4$#vkqfUB$$%+=V<hYr0t+}nqzVp4GFf)6h&7XlmL{6B>
zL7$+f1<_EetU{D0>!kuLhvM|M$*5^GB6FwsD72ZR{McuY6=hU`?+cy$qLc--*e;DU
zi#pU~g#C~rcK1NuGv0j;En7JtBewfwvRpd|4ZZZ-^Y#uAq}f;BXaz&Yk)om4Nk&)y
zEO?Gv87b#(=MOxu4gr_n=Rrs3s?cM7C>`Q8+%hiva9+cM_g<j$Q_zt`;6(!Z&y_^T
z*`Ciso#QUOD_?W9C#ggZ*RgL=u#GKUHhS`03Mz{2$w%(Dx7O_>EP1hwr~$}9E8w$Q
zv2yuWgwj@1Qx{Bhx`XdS)Y-CX-Rg{(DC}g^+LZDb4zuSI)?+>F>zZ6!=Rju~SLX73
z<01`CFHboqhxx)n9XeBHE$w*njHEn#;;_B_`a0XY>!@9G$L%(1@@%VX<UAUdp@KN=
zpCgi;{dKN;oay&6JuYSh{X8F}DHXPK;>}4pOL-}6;pdd{@NtmMUSK1j5~Ut02h~J*
zR60B{!bamc#t@2%sEnHsz(f=h7BZ7&_zt2-O28du<YyfrPEi-U)+*k=_5(NAV~;*g
zNO`PXcG+bp(sGZA2w<YHpcqf}QulDxlBZ+5t%`H#r;2;DUL!}3vJs<3IUQ;Ty>}Te
zZ1}Jd{(E(Gk@Kn)u1H61e2T)f(PA@%V}_3$?M8<3o9c7UN5LuzGj-Yw2Wt^xRRzYV
zp0f(HF}>P|E@<7SqImTZvR-w~5E}w+x$ZZ#jj^8O@kLWZxmO{YX|}KoPOk#yn7Axa
z`w$bK?}_&Uzbowh9-K5JQsP(elN1Gm7Fd88i<UAKs?2`=(_h%eiEC}{%*o{Mt9)&o
z9|#ra5lb$_%k6+xvsG}&z9@wii4kAAU<RZbrr{m^rzQ^3jn>xNeR^5CVaRRZzsM_f
zLqd4me5QyVw3Lf6-$v-B3lOGuKHqns)>gf=+Iiv1yFOxh)#E5|4dYogBLGh&6FWKc
zJ(2U`bP=8-`3lZTI-C4lWJ=~Y)cZ*Bg|}fwt&piZ((P#9h-l+dZhSxrI@J=>$#p*E
zIs{B026NyBO6zr8+(&vo5BIC^UF5QpXy|8^5E1F-F-8#ZhMLiK=O=%iaO6?jK_SJ~
z9s5Gd1O!YV6v0kjc+=bT1JVzQDK`d1*ePOF;35V!i5}9crz2tuoECcz3j4(eMMhAs
z_NQPyJDQJw6(xhBZf-nITf|N)sVZjTOg0|T0uRGym*&}ssf%pUb<-@Hp$n%lI6BFH
z=V658fM%rLM&akC%hUcU?8({gA#(<dsX69~5PtFyHy7|eUWN8#gnD{{9l}$VQpr{Y
zKYzFDC;KQESk)d#sl_2G-G`<(dGB$wD-w($=c>wZj@3VYS9GNDG#)kz@(aK5o8JGd
z<HTDXC|BhnHFB^O*jAsRjJMQGU#f&`R|FU9UZ;*{-(o!FFcVmGK|F+<uv({dZW+{}
zeURD;ozKJhK_IIjQ9rW@N$OeSE(T$IYo&Bf9ix|8$XwtkZNvGLcb4K-@tV>Ax+fpz
z;u)48Ol7#7p<qZwP+@vfAn(`+QZb%iN1<;=o+8}pJ?Q<Ji@)lWnR<VLP6AnkHYTrK
zk&-5gHDT%k(7z_z!F@aItsPWSHy@_QSSVez!eMN;w>8?H?VA8CAuYnbjF~h8{uMZk
zuUxdCx<pLlv0Bj2xSKs(+Z9|q4>C&Y#P=27arm~zPtr1Yx}LF<N35JwM+1dsLq<%u
zRyh)gw45U99~R$fLx<N`Cn-7r(NNCxO4Ejy0~m{P=x2Wo%nCajulJ^w=vn)_h3NCt
zbH^OqUo@w;ehk1o(u)Pqwc2JwbSPE!=z@{942m->f26Pnq@d%<R`;#ksgrfvj<w8;
zTQ;N(h&Q3wxMd~=^oc1UB$6}=qMJ*(nGDzLJPsS!#&^F^D2WdqrJhR<E`glO^e0vK
zR@jJf)i#<Cv7WJ$5O|hmqvo{R%BOyA7hirIVa+@3`#=1NHCd@$y6h%|rNZ3G$vEYQ
zR~+k$y$4s&icEw&bvP!nYNNG_zY>I;-jwoJ-V~H4?%~*;4R&JJN*gk91bwgdw&c1`
zSz{}$6#`YE4XhpfTrs#<R{hyXPN|OYyqcbq&IC<EzysNsOgy2?m275Lj^aA;orh&l
zkfE39BxqFaB8_z?ZA|qrdWuVkETEWB#yY}thwgc30D<;K{iUG=Cf-OzS;U0u@%5nu
zj=U8PiAVkU@7|&pr6y$5IWH;uAVrwmZ;y>|oUoO{jNgzWPvmQ5L@3<py|Upp{Jie9
zMsGOBM`KLYpRD|$3K8YKdXZmrUcYQm)*=ci@X*^I-D`AQB1++F68V53{+R$-3E}EM
zuO7yY<UsJI!*w0>MQag}zw+{G?>a(J-1zLNd{_4v#8)CHoRAv;RzRu0(M=|3bl^Om
zUggIUGKDXbHe8~*KkRoZ1Bbs8kz(C<AGaifC=4;xF(HlRS7l8!`qg_a3M*{%^h<2?
zYz@ee0V8xm)(s==xyOELORl}u?!4`0`<HKg-Ezvu*n%r=^$158AsO}}k*!a?5h`8%
zPGxvHrS-VUV5vFAgNz2f)SV*NBrmrURIojEaPvF%|8MUt0PH-g^zk$9K9iB?#NFNM
z-cqHsh2o2DVSn)7U0B?9VPOS#mW4uTONF-7HMO)&C26E-+&vk0`9IG&?|biezqxm2
zl1aA0T$tv{C-3*Z@9}e<Gk)TDR3NOEC1<@$>e?xwxt0j4!4uPoj#q7{xmFJp>af#T
z;;9%6@e)b{VlDEvKgt+4m#d=>E``o}a9#K~&I8luWfLq|ghvN2;Kg;U_0F=)2u)ya
z$yQknk%tn>RD`mai0Km}mCiLp;fymkc2&;Zv-Mv<lgJ$FU>dzHEjCsg7=9@d8p?q8
zx_|c;AW{uOVLE<gk^*^`3N(8{)6`A4+l$w*EuvEzc>c(q@~6j{yLj_$*NYx(%sBdu
zzmMvXoF5&9z4%_;Yk`-sIBNRlYG(2TA?tJ>L&#Fd>A4*cd~j!{bOLAszqNHY$WdV9
z<`<&2Fu6sJ9M~=G8N;O$rB8~Y1UI+NfS;Rq7J~7(z!>9efeM<U+z^Do=>^Vr7s@MW
zeWl`FxyTky0+rX&)d~SX0ZuEM7Bb(ba|{GWA<-sh8Qu>!PRvXs`k-tk@?#>VWKUui
zQ}Fl`7RJV9Y?DP^@d->_ih3*$v<zBJn9;enxU&hrPRS%d$BxZ%@m1&JH$rP*&NO7f
z&SWSx;k7_y*~qNtHPnjKIB_a)ho6yAaC4Wzeap^a#w0a7sP8$3$Ox5@+B4|CUNN&H
zjd1as>)~W{qx*rGxcUU{nl7SAL8{i1TMIs)p5u?R@7adbGVfJP>+!Z`PB6QnL_hoQ
zdA>tKa*x9y#IB#ahqC_Yt?lu+*WB~Ee<_x94b0~XmuaTVm^wrLaMK+)ej&cXffVS<
zC#b#HvnZWv_aqZC!B=1Pwn17~1()>VzN8`)WI~Y~4<|rvx7fk9{Tw~=8I+d<MiXZ%
zMnZseJ}YB(H}^)2x*7~`i=G>Fu7PLR+DS6(#7=cEu~CP<Uz&=bgiC|ez?w}<0%R+4
z1}LD3y-nrFZEZI-9G~NXo(zJM7BB!jw=osM#Dk*ifi}3MiFC(a_Q@TM+K{Ia{J$N_
zem4X&oAsz-#*{Kvjj*#ClVLSf#P6f7eZ8*kAGcQ`vl_FU2|wtnbAPz)9b}ZeQ;>T_
zSbBW+5V%M5fZ)FB>Ak_#gBqi|fwc&>$_KT80Zx^JdiLGhH_92OFP02I@wOa2Y~{G>
zm-Qh`ODOj3Ksg|tDa~Ozj+ZAtdkoXO`A1jaJ1)Lh{_R`em#LFxE9zBK9qMUyU$D=i
zw;m#=*j>3e(5yU(#ae7p!c%2HxoCK>{tF`=-pICqTR3;PS@3=_V~HuaZTwZ-72Me_
zR$~L!h1dV-?V@9{k`XcuOg62jv>Z7D8H_JI^e1@+S+d<p*|PZbixmRW6oc4@@z!wo
z34IS;Z^g%7E;3{O0;>-HQdiYYN}?np8Czgd06RQr^#JHYy4`Ibl=(2}#6H<PMTV(g
z$0|AzGc^97dc=jIX9p-Hj!E5PncdvS+{Q1ln>dqSZp?uNRO?MW9*#w*#cOM))}wQ^
z68WeI*{8cUuZG*WK~6hknZ}M484JgzBMGb-4F&GL_iprQ-i4&Bc~G<v+eMvo6OzZ6
zTy_5g528$IlDzNzAJDPTYUF}=4`PC83Va=4U@q%3@?%_7xA07PZpG&d+&8HC>XK4n
z>62SIOCT^je~RvlUd|6F#NlU-VRpJGq$soQ*>UZ(<)_IX|8yI0;a`_wzyoMG2E1qR
z5Vg*9%ewmlyd#!|?0e$?33gCW3DW!8EAk|M%f|>Y8>8F)(PODt>Ghm-roRLVYQh(H
zpG`<pDI!yL8`TdWuzdPfpOxMV{y{+Eyi}C<opte*vhleG<?$z;MMx3NG8Uf&!HHv$
z6smK@>oad6GWlL1Fr_a%J3XvueG=pCoE=3qi(HJM3S37~;4m&G#CEV0%t9khA}Ieb
zCB)V@;>8L)BL`?!B))VxFM16%>fGRaEK+1x7=zJug5{1peZ1$3Pm5G+Jby@Ve;toK
zo88y;hdv4a=|YZ?Jryu3a^%47)zaQ@6pfNj*QQD84bo?G#;OOciOhF&Pjan}LqLa?
zRS~JU5l}1-1e`0bxI~_PdX@a;_CLy{*L*|@fw<MwWW8kdfmDLnLj`pv!yN6$ix7Bj
zKl`JD?j*n1wyr^|%DHmf@V$Xya={axjg1;~WH@f&so@0$v7W_e2w1#&h>Ih!e=Fl>
z9oRhSfWk{=BLtk2kx__YA)}TG2{mRfV0d5SJW(T0m(K}UeIDDe>SzrtgWsH1(`<yV
zh(1WjNMQ*CnKbu|#<!g?(hU-@aNND3vt~DNB0jV*kwLrfLz;SksNymKx1s&G{Tf7$
zbyMvL-B!q6o~=YbTYM*$I%CJ@rd0*B3IhGY?GSvXwV^u&b5>jg%;D|p<mr2FldpW~
zA5kVW5*>UFs&%YjAOO}_vGQpM?^gNn2j4Hh`R#9{4&9|LhGNRhX`+fPSTGk2FQ$Sp
z(;>78nP`?_|6Z{()`N|Pglyt#1})xR?%d1uB3_Othqr0&hfq&=#}LivwEILvT8NmZ
zW+dSe`t<Mr{uA<*uY6O^y)+NyM#JR5;W`&5C02k52!;`C{bT2sJ6>JLp56m{l5cfy
zMVM@4bHxnXENN%)bLWL><|Eg3_i#Cyj#2j{8DqxAZEQHvcW!e>Pm0+F(WABSOf7bX
z)pCF&SO5zaan0-^gr@+p%1RM0*NA2qT08sfg+lBYdsv9PjzR(ZjBRi*d}P)(D+h=V
zPRL^-4zh_5UmCt)eu0}~qgWHZ>izIaPJl#%GB{GzseI0_QGosf^Wx<|#6j<W3-4F=
zn5swxSw-;1wj9P{IY#$e_>!@oac9NJ_xp$E;e&dycqE$DAQAG&fgPxn`LlfDhQE`^
z6UU+)5;zr}Dd~NkG8yrtaGbGx;5Y<ya8Vsm(2c<^HY`GiM)i;X_$fdLep>GT%kO3G
zl5-G8$p&f`>wa|!BQ9l&C{bwRnOvr<jyEiPY)|Pt=v;*Pam+6C<KsgHSITd4`#mzz
z!Ig--cMBPKR3oWqeO+{ZqYGrh7Orc!pwiQs7z1q*r4dO;zDh}jz(zCn6#QjmvWAe1
zCHky-J@;^7p6Nl<V~qd6vnesSd86=VFKYE`;D=Nsle7Rkx`7#&I4BJ}Ba2Dej4g%*
zw3{x!@p(~;7m>jHF87<!f2M#8?uj0vGWN&lD#m;t*To&WZt#R4ZF#3knBIb0#pc&s
zhqnISvcQUAO&BL@YHpORYu3q{C+?L?FF6aXAkPEH$5CYzw0^Bw1GYFylQe@C01iY|
z$^_ghk(`bJ<bw$yRJ<62ssU;oGnokj6L1QL<|E!m8)QKD>&H2vHE<SEWC~-n*uF34
zEvz0(pw?on;_GL$@2kc?!rb-*wxF_ParCC92D$M3bL6ELR>=eR-z_ueFOss#;YitF
zP6S=2P^vVyg%ro}gxsdODWjIGE}ffDzt>Di$1*}4p+2LhDksbnJ)Ao>Dv)@-yGG!g
z;B6u<^L|YjnZ98ou<kh3Sq@38$jIdLu_GGyW(N|G*bCYxC~}T$E~Afb33(AEwa@#T
z1xPnFA4(hO(BTb!(hNnlmfV5D8^%a3I_<R}A<*X3*1~%`Raw&2uzlkdr=Xr^{MF{%
zE9_BqJRk!DV~)~0uFJ=ATOhbSBj4$g;Edo_aoadXiE{#4=Z*Z_^F+5z!k?qOn#|mZ
z9PP<X^v4$22`J#_o_rMTW9Ome>LrL)G^!^8J`Ph{B8=4px(~gDm*zMGv|ThZIZngW
zz6)&70BFlHv^)IY-~LQ~^PAtxLytTTmlfh7++3{Vqe6x&L>Rv<NhA@$Rxtj~(R;=b
z#ywpZJ>55UYEO>ev$VkO-Sb#3ST7R84Vjy-6U4*jYno{b>gjH2l*Yq|J-1c?k!Odz
zwCW+aIqDI}VKuZPpwPw(PeD-lMB>$6Vz_m7`8Z0*YRzM(5)h;A$Q~Jz*(|M1xpHv#
zPI>W}$E5MtK{^z5KK(X{&#crgk6n-uQ;WnE-C@D8N8Sf75tk?SJ-4<u;+*W=Vtx(c
z%%!nwV<>zv`NhHkZZ8ut3s9Qbs1g4BXFo3QxcoenH8raK->q5urkt^v#6pxl{pGfs
z<tIP=nap3b5LwrifarWs0Y8W>U5k!HudH4Ti~2A?VDe<n?77IchVtrMxxo$YWRn|l
zRAA_;IB!ZMd)dhhFId#O=3T4-qKR6E?&;KUar=xePkrw>j$dAjg+>zAj0yrC3m5H<
zZWc$2Hs;_p6Ol<YsVsIonPtP0HhP`hbK`w86sFIA;h#{tI9qQ1^X;-{(+15HPIhsB
zojY#&K<vPticFp`wPCMCRLhL3(+7stQ=r;jN%V@$feznu>L`czE^QrMfaVfjFt~@2
zQ^I}75>3q~px{OAWILLTbT<Hyrnwl9zWe0mRgVKKsTq5e-NksLfCz}V3_}WcZ~*a0
zP?Puof`VsKm=ca1Nso=-DaEPa>rF*yox59JeD+~vYd5$xWSGw}dVN-(DPb0-ap%~%
zjCyN~AH`MJ6HHcOFyfy3EO_0>2%_7fw<V5qcc+L%_MFqr_!%CyPUQTgp`p?ZAHNnj
z0_PxQrB(BRQiwz05<+b}R%#noGJ`if4gqbanQX8W0wV|~!0>MiFk*87ZTXL%y+N*j
z&(+8r-i+Ef;6(!=sRhXe9mHeBidf#5vCgpYGsj3Af!hB-o=K^Q%ERF%Ca}H<#SvZb
zdU{FT!=0^DK>Qxm3Bv8f#0U*X1F!gzyAMkaQtT_rbI~diO$DH=q-a~ffs84%0d-D+
zCFIb{QZQF(>6yUU-6Y%AuLKHJs*D;@4xHq<sJE$A4DR^4Y4p1BMi)>02|DZiIl<#1
z6&%Jl`uB>%>EoRmcT0qbj`OTNbwhXdpd^GL9EY}@6DCanxJRDUgZUX~hC#L}G93Qp
z{>_09zwUkSL-|@G1Tb8S*u(FB_j@%#%#fOJ9QHa9xVXPrc0_Owt#|hO-ftPlz_i{P
z=lWjC5kcc>u?>RJzE$hiSvB;6SokQw)OeT*W!|4^2^j!s40Aw*F_6`5$vpI^(4$}$
zrwW_M+y`ci-}9N&f~BBm`5C+g^cqlrL@ZRx(2ik-z0sbMkkPx(D%R^mNVmh?ebGhd
zBNt#fTB~l79eZ|59TXt#^2KB*S509PWB;*LCQIvGu?%j7xXNk&c4_1&r$5>Kb(5R2
z5%;A(^)Kv!6kNStC*toEk`!@lPSIR<R9=9$Cl4OEkyS%v@!T2KFC6oh0!7C#&bbbL
z1S<M$p5kdyVXein&rV`C&`Zj)JYE5O?8u(2vSa-VfbUEJU{0BwwrCdCpX*^*?JVYw
z=me4HH0>^&U45L>?3Ow(ul+Eb>>hFCi4L;A45{Zxl_rCiC5>So$xo_BjF55TM{Bpb
zW`=ng2GBOmypF}V)w#_~YSOf>jiUjjaTkhkyZJcg$&JYQ5272=X%J*e(Bj(Kj%f^f
z5g-7U5oHN(L2vZwzitof)%cvDd5W`NOsMx~r2U-p{v;Q;;l*9Y@NIZKE&xDvY@Dcg
zqSmy1^-Cx{E0B?ZQM~TT%cQ&nP>JLr{Tye19$6P0li0>uT`VpdS|R40gf2Ck<on;-
z0930ynN~1V-hbVtQiySB93=3H$4kups2nu1#~mMxo=JWbnWQKksP*a23%Z6P>+J5Y
z+rV=-cO6SA>EGnU=YjFg^=_q@$5BhVi$Dtyk}Q9ytE*8jZWr;7NigaqGS?uJhKZ9+
zWUnkV%jiJQV-7we1NEnj$>BHd+jKx3YWWb}v)0*ShqmccwG_%WGN*tHmBN{M9CQOx
zuz3NeNKs18rhM^bR*3zn2gLjF)B?sGsEDYmokMe3+?oW3lU=w=GsD?zh2y|`#eG*d
zm>uJp1C<Kij|zkyug_x7)x|survUhzjbxUTsRCeSSst*Zul*a5XP&y9LPVE$Ey`2U
zaIGom(#5V=Oh%<wL7^_Ga5%vpy@tPAcn`#I(jG%P8A3WfJtf-57CPyR2sLwC*PBUl
z=E5e_XDzb0_iubzicr!zdRUfRefbq=If=NmHm%@Z^qJhjo46QuT%zeQ7>th)!L|ca
zu*h85bad3)wDuMGpC50QqTDQ*GI^X_bJdlSjZhC;R#GXj&Q`XMNKD2bNJFa1^|c-J
z_jt2r*W{1EU;8Yqw(G@x<{;w<?wfd0CeD5W?YW4%TO-YLQ(A6kaw*n;iPBbwVG6Si
z#&Thzywvdrb$#}np5wNl?JACiI#-H)=i&^wkAfMXRU#3LSaWL(i%gO)(-usFCr7|$
zip-B45i=c;d2~rWeJnAtVSBvd__g{c0&FZ1Wy>DjUST1pla9^Y&N3@7S73&8(rbY7
z1G+Z4fREf<j}BL<+0qUv&aCRbUgn+X>nIMzHcK0=9Naq{%&h}02J6uTfv#DCLa>K$
z3oO5Stc&(;bsBX-kA*UX&@1@-!8r(xQ3bR=HE>SUI`eZFb+h}+Srusi2-yUFcvr`M
zHqoekyWAtYd{PQ0=09M+P~b56h+zq{22ChixPbR?LQVy!H7-!RXxxgOgZQ#Iode?F
zs7(F=k`o>k{M(H7e>{iib1isJ!Iz&4JZ|2@d6SyprsP%F)7j`5@hspmr=ukxo2i(j
zg)N0xS3_e11QrxAc&r!?SHTauBI=kW@BpnWKg%&q%qf0vM&cTqYY+^CP@k>1Hm&CZ
zbmeNon5_Jdz(X8Yw_=RbD#!u@*4l0;-^ANylMf~b5f7S}-Sm(V&CINQC-4(lkTF||
z7P}5xUtaO>N&?q}Enb<^p#_diep0^S|MaB5i#&peReis7Ds_$eCNQ51(&tsZ6~XK3
z1Njg@?3wYlZM<Pv%XZEwAvMhcP0s>$driIJaO3wb#I+jH!#M+5H}fA@=A)cQy*5EQ
zvN<z_F~Y(9#K*1*g%9K3&dWm!ntqma)Hbup1{F=x2~pyR@!r*r{i^fnt#)q#(qORr
zDo^OQ3oYJEJGm2CE=Q+*E=qy}5-BS2WJQl-O-(i~XF1y%-OwqpIWVsfY1Zd-+YUEH
zB@xf+$@h*=K&#)@sp5XJoy*N`%8?oPdJ^5O6de%(>scum$`gh+@9k9Y+%`+WUS38;
zn7(KD;b-*g5Gh}X?mZouyP!^_V+#HAka&yEtw3<S{TP(cO)E}j+(>Ug{9Js2M5GSH
zrnyj>6A3gP1+))l_Xe&Lvz=@@joRZK<GxEm$%zU!tdGW5Ntn9UBvN3S0m6rkGdcl+
z&;<aKU}mvdiSGK5N$2yJD<*PVf3Ls*Ltg(VqjekFU(Pl!_k)#|M7$S)`{`x%Gns>b
z=-#Q1UBUYI;)A%lWT(OM!Km$10BO<@XE0E+Z^GH?-l_B%gE1wHv1t|L9yo-88=pP1
z_qFtySsCaN{UBmc?Pv^f0XmG;%PlwGBy;D@LC@rw^2{?&qv^%{$V+IJbI{0Q*|O!j
z-VZ%=Fa90`#ABXZdF54TU%5fnpz%NsgnJX({|y^9Qm(xgZ64u@dGNve<b~&-M>nZl
z89#QMEL(mC1T2!%;1Rgz?%QO=lTV<dP`+Gz(Z$+9>Lv6Ce&oRiF`kRj^=dj=L++QK
z|Lh0aTX-p2Me_BRJ8qSn++2+5Y(+u3>#p0Rs<H|&r}^^mLk}p%_mCk&<cSqe!|mK4
zXPt8{p4|W#G%l$7rf<O)W!;|GZQBxLh3nIS{mSfaUde|Yluz*b<Pk9?7q)*qZge~{
z4SuHvp7F~b2|>CQBYcAQ>CZ0HQEI}H9d1PBnQ;&D?FaKAScThpHc))-pgWmhBe0eU
zG1Ls9sa_ww9~Bt0R(*M3%sk*hlr2Q~Z*<;cpU_s1J{$^IohyEZGC)hvI$2TarC>tE
z3Rj);ML-{RZPE4dbL(fLe+HJ$TtbW2#vVP!%1R@zpiBtx7BvHcEJf)!-lE#vh4(~^
zJ3F|yx!*b0CcJcRnKZ3yMrd0o{1&=$e=#Lh9JLSe1_vIy68+_H(V2-nn45ULsY^gm
z?aZYHKvJli3lCr}FBMmj>)0aj8&}JwKSjwpIDNV~Yz}Om-F(MBihWXX8hT#6mS0%+
zUa#jDtq1i4AJ++JuUW;LOC1|FCrhYOp}~_7U^Tbn**jEVw>d~f#x&`EVo5^JIFv_f
zi$0f|h2TBo+~4Pz8zK>(-;@DMT4A>vcC}*D4Qw7N3;yM<MfZ4MY23rpEn`e9_=>l!
z!)p~~P<Ezc9cE?v@p~c(Ur@&$)g;496GMXz=_s->c&|9bO;)A=Gh{ZZHky}5EgZ*8
zcpjOIpB)9*$8QEqV_I><E$PZej4q@9i|#SAoH7B$_~he{Xg&42ufG}sr$zqs$KPqM
z=c3{w`Rr#tEz8hHx~!~3{@<tnUViqApKH6wFMjcJsHJ|tT0=W`p;c)P+6N+A_vV{!
zl(WyhNOH4*j|~A#<gI)EdJmdtY(SFQh4Qs8eL>EEu>9H2eknKo@kaU57yn7#`+*Oj
zJ>_1x;S(Q~zapV+`;IO0<NyAK&eNG^&6furcu{`%y)VlLKKdDr`R?1lPrmza-;`1a
z;B(JC6Zs1na?f3N%G|kgWy1Ke^55V7lDe6{@vSc)(|V<B+qzTE$Gz#2ZgbhZ{SnT7
zUqm!OolGNa74-DFbHBRA8H{gQY}Mx0X9x$+*RAA26ET}Mu2sZsZfrU}vknnS^hU7+
z5&Wdri<lBdQtsaI=q84);t3^Q&s~!)XH{OoOFPIzplGuqqzmX`@NKB@Rzc1A;TW`e
zM)b*)D=YCB1qJCOzCa{>Ks+eTICx6%5kkpQaJLdM46*S}5(y9E+Hf{CZp8b$wQvuq
zii*j<9tu%J(f5<&8NHt%o)Z?RaV9kQRgiC3-GAiKZ3@&o5amxQ3N(K1yo-UwiRnwg
z$DpS`ACLbvUgbkiRI2p4m<ReDqCB09CMv8WiUkb>2ZR&PvUUPGzDqGSqmGngi3;`#
z3K)N5|5VDkbaU!7_yBa^oG9}T4l6LlZua~)I;ZaP!S~@!9%SH=^|j$dUXis5ZiwK8
zY{uOtHl-tKf(KVFy25^~=#o<0TIKw_2CQ1tMEi}&MhjMl98t9cTA^c5Zhjg6?8__U
zW5v8;nsZk$v5DBdY5_8F1dLvVp1O32bmJb}{S(8#bSeFQ2+U?Y4ioxLeJgQ})Adq;
z*Yij7fcb&gocCn#QDV{&MK0sSY2b0<@M0Y9_Np>=cP%}~0WK;7uxEAb%hpb}F3+)8
znvrh26vimSi=i2Y8<2Io5A7D8eQE{zF4sdyw`q&VKmGA0nL2HTeCIpgg$o-k9pRk1
z1p@eTSj==Ojz=%>1?W)4&QnZ6n?Gm1yuNOOeE35jmGKj%!qtdmHg+q+S}$6(SibR%
zugL}HohSd_XFekj!K%Lfw%g_JK6-<E?sK1m<z6SB{P@S^)|+pUp~HqEV|@r(Wv-Ef
z`wz;>XP=P#k}4z>qOUmqo_Oq089ri|dcan_@Em%cpA8|Msc!D>4)lQ@HcI~bm)qs+
z(@&RDC>eXuznD!~nz+w2gPQC+vDFz@dDfY?b$97%I{CT}oTn+02_Ew~mXq7s_hfTn
z-fp*x7QjVzd6;<wH(SJq8QCP!eW<2*%*G5bn>c$u%xeOdjQL4<kkN-?H0ZNYxo4Y4
zA}^T7Og%Q<>*Vtl0^(Wstj2*kWcS>?xdr?@=+J3wu#GN<0gr~#iY3H$F#%Gi(#<)s
zDs+8tP(-9e>B_<|apuqSdX*VQV^QzCKPPr^;_=0JykEbwi$;_ZJ2!f?e`kEhT+;sf
zZVCcN^AUVw7iC_KZ@4*d^J*?`Ya$hSnbxAG*j|lr8?(CIqq>FC&&OdwC)j{-Hk%PZ
z><>NJ8V47T>&L%f+{q80-v7(FNli5PIN!&+cJMpAx0D52w4jDWQVK4T395i48`-x;
zg3--G%dM|?tV4_f198i5-UcN`wd)<DbDz0C`k1%q&&N5Tk%f;wgVzOYYT{f^7dH5e
zi6)xvw(z>RFFb+A+a&Ikge4hXq9<Tj=5FuXCRAnAUCSqW@iT?*23WYi`qgi=`NScV
zWTl~|mwlUArj>!DGRA{vqa^F86)R*m+|Zx>|Nc?_aN{53mp}W3T>swp%hgxEOB+-$
zBb@z#J5&*4a~hXXP3sl;4%4U4kYaS0TEBL^96feSCQO)w+ym6f!qOfwVw7xpeG@Eq
z^e{(@%KZES`H%njPmJdv`baNQWGG(a)?05y7p~D7fBy5We};fQ$1GNO!wB;@WBM#v
zxMYcZ^IPAP@#80H8%a%eLzsa0<0>rpFLz!q>ye1^B1&8jO)JEpIi`MZ&-e!(*YJ9H
znWAJGw(k16ZlYnw7cff5#@AKOP|0QwZBsRww5Yt*DG<hI?GB#jM&OTK7|u!k$P$F_
zYiApPFkRegB|F;gL>>Ygr)d9YN75dy*<aAvCV}-g&J>x#uxtqNQ5$<ypeAA+iS|&B
z?;~s?`lRu_299?JE)ah$6RmLUgT+_nZ9QX;^x-l0gIO&)isKZ}{hpG+1ACbPv&`bS
zxZODsy-Jfc;v{PYt{pA+8eGaZ!={T`dPZc;h#4<ldb<4Z$3K?+KpcC|HP;}Kt5rsf
z8YL?pe_S)D^YSy~!ABlJkLe<9XZewje@t%phmWDx@~7mNzxuUYb@jE{=8-Kcc|6^|
zv|*SyrU}@vu#582<+g{Pkgc1y$``)y6?x%>m*nZEpOJT6a~a~qZHPU;2*8BPRLC<?
zY{|0IP!9PSx#83QfTW{ZBz&dI>NT&*h7B9RzX3?m(j*68T_-zt?nV^`LL}I<9r*rO
zeWQHnqo0s<8@I@BfB7T1_Wd8z(22SSwbX{mcuuIC!UgG1a#y0;59HkNHBaWX;tG~H
zvVd+_b_=88l*Z)2e!f&F1ekxK)6`mzxMNK{<uH7M6GaS*%ItpL{mpaODP6OEJZ9qi
zn{pKllJtLd`*GvJL;5!Z>dZ^1W(Qos2?TlYF1FbHE!pqi_y&(Uu^I5$#~zS^!Za22
z=$R0%Y~Prcnt`nDJZ(#P^)=VZ^DCc|kACFuBnNKnwQFCMuYC2ZvTpqb`2*bFd3jl~
zcHMfp_|nTQj)mA`4v@*19At4xBjp?b@IU|Lvxqg{AX~R=llQ#ugED2x48*+OEC2D`
z@5(1W@fkS=WU~w;kzIJ{Wk?*m2f|)pZO=lo*(jL{q^@URxu-&CuXtjG%$vVJ{{4IZ
zp;_nu^x4nK0}nkcnc2D8<2)7CKFi3OQQ!S{AN#mG^W+MA&2CF(0no+G(z29(BtV_m
z4BJ@)VXy-^cOYXvo^vBgUV@XzI($i6Fvi`N<sR>H(NJR#)kAlfx?`Qar{O1EYZKOK
z$l~|)^vCmj@s9n!SeH|MkCS_Sv!(|H^gwsk37oI7wn#F9CoAX2Qf<{1hw*F=lNV80
zLoQi6%K-_Tz*q)PIe9Y>j6aisvaIQv>#kS#@iCOfP>uT1*T0GOtYuPCIz;~C2S1Xh
zo_Y$$HOq%T@-eBd9tBjg!?F|&BMu!pBLDK`i!{@^2AR@X$g2LwfBBMBBAdDu!jrMS
zdbpuK{NWGFo^#JrAwFWnNEtn9G~&}uvS`Ut`S0qH$P|AD8QwXveED+81~$PGWQxz2
zIZLXBj*wsd&+nxiowq6hrOD)$R*d%?WOrvG35|bW{L0s~L(;UFvyqU7e&MjPhmRZs
z4Dx3E_g6RG3fFrp#$(;xR8eHsbqK8F<jrvON<LZac&>eN8E8C#b|ND3c%Hx=t3or@
zUE7~Ks}&q5z4B$8;d${2pr(VtYr^<*G<NE|BUH$sG#(G~*9ko7NjW8o8rh#&I`Lb^
z+g}5npEpcEpITx$@ku`EXQ~n!yD`jVL^qMow8mYP==iSzOlY1eyV#I4B8dn7Ju_Ji
zoyyW(%{5}BCuYs~m?#r7Jkpc3RP6l;2eK}2)VTv$vw@6R*;XJB8om~5gNKi(R-x4b
zWUM4up_3+0(c1LJ#wH|-<pKBm9a=w31hNJQzO1ZVWKW;3l@IKe#qTNXGhw+-oP?M%
z;?)EVVJ;5K=0=RFmeFI!t5EDhW-U8waU2~Gn&lAY*S-5aTDwgpppkIA<rV0_H4LbK
zEi$Tl40@BdO4TqVg}IHvbDQuRH{;M@!y`#QTK|phR$MkjA$%J!{$T*$;fpSNO@h>9
zsc0;IAnTIo+z2i7wUJN7%>&o$xo-x@{51)ze=n{@8fxG9Vm-a5d*cE<`HlCo@pxY$
zVVUqzUg7U-qo5GxZ<fKLY>CltoI_rco&jVtBoPwZVW9NWzb8JiqhiN4!1W0Y;Zz9Y
z;4PH3<3DehfIhJ)e|wyzy+1v~A~(Gj{<~r|O}Te1DHURm%-Bh9<9~(%<-S*8OoS@9
zQMJPl2*>EFzvTY*nA11oQ;-R^vVX3=v{+SIAV5_aWBn)uIH4<b4PB-=m#q;NaHQ8T
znIrcI_Dd^-wK7YWv8&gIAZ{fjB)?bJvXwmYI_&^0VGBop4)4(c_cYMQH7&2nU9T%L
zMjNS)h36w7&AJoYi&lD@E0-j*reN;z8r*lMd@FLl5Qv1#K;QRUSuqA;)zD6qYqg;%
z^tQ;%k0I18f1nXS-o%7IyO$k@d;~U!KDjdQl+WAAxWWGkUk$MCK>>X-R_%DNp&6I1
zR+$@LQPx<TW$ZP@)i5fJcwy@_Y_*IvNy7-tEM{v9XGl)2d~1+V9`CB0n&X2^ObO4~
zIsSdb!{T%B?U-J9ZcH|Oz||SUFhjOfgy`KtG2`lu(}ul2r)HW4uiF0^u(B$PLwm19
zf6i9FoNfzCQ1w=H)D27Ac!L5~SRY_0u+tcC)(&HV)dMWQBMv(~Ig+NEcR;UGCGbwg
zbx*}L<4vA=F&zIM6wm|OUMF_4qEUg!w1ELoc@&w7;9sy#TG$Mrh4|3ziaAVTpo^5?
z5QIJ?tRu5`nZ3!3S+kcwPRQ!)hKo~My3wK@6woKOI4AwAfI6(QnHras;ps>Bvtf|)
zb$p(Wp7~f-vc~HN%hGt&laad>E_LgxPXDA&=imixhv<TuknMMzlg9#4(7$Z&(eq~B
zH-=8kyTiT0vPQrHV>>}k0~iJThE)Ufui#$-q3E7{lku5THJ(#--RN3)>UZ?-6rYHI
zwuScYGh3wy(1`tDe<%F%=N`v3oUxHeON)OcY9Ffp#f;SB4A_@uT~L$M_^@)B*hn!K
z#9Ybl*o4pBlc6dwfSb>lu~R4`wwT7g&^WCDNjZm)9+pE#>ZA@aJ+_O}hUgfN3Sd3i
zu0>Z9F_wMyCc!I+sZ7v|lA=r*f`%A*$Pgx>wF2jx!aqW|-e}Ux1+BB-v-S0yi6+3G
z7l8n=xpfa7Sp_}JuT5ZD^?>k7#uHNENWMQNdhUR>=LzrY{-5X{HJJs%;YW_lgWvSM
zT$c<q@^f@vf&yOmVB{uNCKD0T3Vad0e*AjPIQNgBHzb;K``(x3#9fd6l7Dnt*+7El
zg_pkPR)|he<UBV6;VmD$c5vH;mm&Nx;qgWIiqTknw&CU{&Kzj{cjW%|KFW{X<CA~T
z^9Di6rbNu5PD{6YnNiLE^ju9U?Ce8K*bLU<Q}J(y1<VjjClVN~^Ho&P+diSE4(CyL
z1DBgywiStrM~)m;>p2Cyhv(4Mu8mbxP}>7I1K*Y`X8wEbsYF~S(GvSB=w;o>J(nT?
zR^z;t4%*C}?gtgTiyMEOwQ<hMJ_)_wTRV<YV+ngccPOfOseoppK|0Do=*`GLGkS$&
z({)GV2ciQ-_I8>Ij}xJf$T>P;4v@od%J6)-g$+)8RQosUBT5hM10T*kILEHNU)ax=
z?b4WVqcLA>QPmWYL?da^iei6m_I4!OFc!#RP$;trKxPK4Q<TP}!=;mo7@uume21D(
zzO-u#^+}o(0m4$CN+L+1yGtrSBGULfJ9?#HesR49Tz~tvJwTV*t+l54=n7MS-oe90
z6`-^x7oYPa6PU}X?A#N5G>uUcAfH0IrL{?sr0VM$H9L6k&OP$_Yiz2JCl$j-ATzgA
za$sqvqyoe~1wayj?BlT0v*5l$ISru=*sf4Wc*LW|1E6REacoOUv%U+6J!&}HHjXJg
zwjvfYwHGR6&CQOv;gvd(*ru4<+M&svM_5z6ALdxE?PRsPh(}5C1Q&rG?Uf{WGRGDm
zi~drGdlK72Hpz(?MWP{?YcYBuy-M&R?tRZ8x%u>`M)po%8~J%j`23y*16S8IaD&jH
z1?VJjm<J||-0ftT)jExSv)ZyGoVQ-r)cvU89BvZZC;C+O(e87c3@AD_4~pxybG$Y4
z<8y0k;*K#`*A&6ct2X6fLmB++yLTBvpd%O3iN<%`a24*DSk(kHvK*A)&ZCFScMyxj
zm>I4jjpBbPU7%XDvdu=bonutk0omILUvzp}hGc-(<Ur}SStG2k83Mck<HrQKX++{5
zA!j*edf>9@iOb5;W+&{Z<^?pLm)BAJ1sy!CYvU6cI4=v3cl2)Ku7I~^5+hpdrsbfc
z6=Xwqi_$#(dJ65V{nQ!4Gd{q}kvEdJu>{e2O|uJ@tNf)^t}wdnR2HR8K8R0V)36^E
z3Y?p!F>?GukQ_q7YDkb{hUL#&;x9!LZMANuKRYkx7{71&>!IkcmEH3=SGmKidF-bw
z^gYi8z)?M9kV+eN*ZI}2ex)tlT99;Nh>=7sLT4QIa8}%63Lf{=!A<NpIsXk3W+EaA
z9;drGa9)5}g^4_hN<_xvZlsLJZF3dSTwMNUgs7RW#73nn7&WLJ*yLGgB#@6@zAZ?A
zA(|7rv1qw~(*(Kr)G9f!!lFW;JyoD?wON|c8A{rlFkzSnz%{aTh5;KMsW5mH;Cddc
zSIjaSIdnr?-Mwq46qlCEp@Zn*`uq#B=fHjeEy=Wr<7MKw36h(YCYiuWOasAn0ZOs?
zSiRI9Y}3|;PEy)z>phG?5w(d*L~(YCl;sslTQ?fFw<OEfy@%yt)Uwj@o>)CxHoUx2
zjvlR%?7~9Xv44l$dD~6ei<;R=w#jiVjYn~9J+_(acmqs7DsGH-X>8jGBvoQa6ai(3
zRz08G8XGw44A)C02Dm#`Te0=vtWIw0Y~wugJWy3<PslKxg5dVBFU-Lo-j0zkdV3T0
zusCKExt_mlcppaw;(iDV>3-e(#1Aq7<?kJ(gZ}0K$73S>wxHt;J0y(z%cM?x29E#C
zfsD!ci{VdOgB$W6?s0?j<u?S8(RQ1zbdti6jS?t|=_yl-7d)dCiZyvHg>)=bvLkWq
z$qX>&EOZk~2a_fPOHSp=f;TW@x)pWrS*hS9+vV_)eNsMjsBGK3Umm*mE(pX%8ynVx
z<#4=yXGang`33;hfX6`)=b?LAChF+f8j{L@(yjg(Ber?6>}?_#npkvkY5YRLv1!xm
z(uDH9bW|H0I(A6@diU+<npY1`UOHM{=Ha<9W4I>e245Xrt++Qkuwe$tW8K#EO_WTz
zH{Qmsa^!8yOH5`@a}_&INT`5kC4s?B>#C^Y?=sEVKRv>uY+cj?zyvquXL`$kg9>|s
zg1-f}SCq_p(Kus{?+f)YF{etV!pEWER`iT!09yCRk%K0nzx>57$Y1WcTV8&76|^aI
zD#4`a0;<Mi!iP*j<C{Dok?`%0fbP#RI#TyAPJqWSXVtvi)983i1JU)-jb|(;6@c=|
z(D-)lJt+GQ)JT45h2kG)qmlNIGFYwUxmvEE!W9clZIXR`DOA+5hN{?zxNiN?F4=qN
zpuD!`6$t5O83(N50su*{6<{Y_&u%MIKqVn)L)TFntXB%S7G%*j*40aMBZveWaQVWS
zQj(u3`M@`BX@W3DtGIezK{fIyo7H9-x|^em9xbDaE`qw5V3`Xv>EUJBQo4MO*1^^v
zIUtAj??l7!I%z>`LZVZ&*49WX2s<eS+PCUjD3`z=-C3P%3(7{)c$PH8so1fG@hXO;
z+K~B6?VAKbWrhNqf9cTh+LfNLU)s<r5zQcy;a)eaUIwn9^{e}gM1{^SxR+|^WB_h?
zy~ZBh=f)O#2;%@D=v!6N{9pLTzCXv)igir=qs54fj3K!bJh$)BMvv&{Esp1seb03-
zSBs3t>k54?+;I)<4L?}RAss_!CbQXMq!Uwe&C<s=a8Y$)zcVyNn%Ta2mmED(0}S&F
z@R~x&&jX%$7A#)S0^6Drg2E?h>2`Juy1S!MYS8cb7@%4Y9YuTC=1!@qs*vGBD<vxf
zyy!4JXNRCzW1>ORoh|j!Sbq?%YtWz4WIE8_4gl8mb@YKRk`cp);XLvs2+7t)2y3(z
z1%Fa6m=k)Q8Y5Jv0-Ba5EmZP<Q%Eu(pxavN&_=gGI$CpJ!L~_8S1t6AI_Yjpl67l0
z$X=l34IMgMMvWRN?ck5n1)czl*7_6RTJX|QaB7|mkrLUwhYACD82{Sa@H>P%F$6l0
zS3{S63Vx@;k)DqEg)yTRKKm|%pAy@igH*pAn|o-EY_utl9t)n_Kd)Sn0XV^9%%&gv
z(3GS8yu9EK@(%WBP@HxAubJzj_k_2B2c3D=S^B5o-dbPlgmQoG_GUXqt!Q&+Y~6KG
zR<GYFQ<}S_Vn~*Z8#@gD7V1NDE~(^Eh;lAWC|j*(WSMZCRCV>BTt!ZU6<RABx9o<y
zs6)!jvSh*Z@luLTLsqqbDP_47H9>r2D#p6kx1&wq%TfRfcHGzux%`rIrF;kon0=z5
zNw>AZ1x;5lEpAO7vg9!~*s$G9r6?Ba(-W1B(GeI`a(x~!h%UIa)6+8~H*=<>cht+i
zotvcu3JJIHCqDXjG8Br5wWGuzEo0R{J&riy;?Q1q?K>>H_a1=8PX&W+IgZIRVBS;b
z40p`VhS){>%<P;@sUBV>Ri*inx;<V~i87*KXny*eZMO`LXK)6NV+MSAQdDVXAjjw@
zMQFpWd3BR)+qPHET%IW-hnC3L(IXMIqGC#Z3xQ6^Rw}WMORIf|_dYXQElPEgbW2@x
zvb?@+yX*lyk}r>~u8?_C#>(dH+vFQx{hAbmt{2UlD_{PXe}Q!j+X3f2_uMP8Yv*41
z<i|cN)22>@OB_NESm^|mVGnwG{%C+%ev$WT#gQ!JLEuMLA7Y)}a$!{b8ql*3Kl&J~
z_aSod$Wi(D2d|b9RaI!60c9QhYSZ?8vTnmxDFZK9ykNEzv&o9`0zY@=jSDKs4fXA^
z4g6-$kz>*fcRcI++2+*8x5;lfW_E{5Pd5f#R$44$M-7uA#NZ>NSH6Z%zAQDevayCv
z{}#NT(l+K|{So95=@J@7d>4Eq2A#t0N7}y65(eJfudoRp9WCAQP55}{Umk-6StpC;
zPnGFY#~^lM$FyOiHnkpsaHJMS3(+(??;bL`iEf}2_VuJNqlH?UAww%>$YHp2)~?$j
zKl$}-a_-XkvT*iTJ6{Ra{vLRICA8S>h%4vI(5gzQtJxwg4K;EEv77W1XqKHVI?pPy
zbnjZM##%<2WoYg7V%;VYp-kbdf)YcctBnwg@ECMJV@=0zn>TKkZ++`4XleM5GH32$
zKtFz1zVmP2kstimH&uaQeBN&rj$uztt32@Vi*f*-hO**Z8CH=m!_XEnCp!&pH@M*u
zuj2k7;dFID!GLz#0F38WxVw%(tG|EkDml{B3NVdoIdkzuDbSroBB!$9*T=c5B6sHJ
z<Btu!x%cMa=-$3F;5V|lx{0SxSwQ;Py62eO_Ls+HNJXhEoHtR%3@=w@l{>rz3O!NU
zx;4CHNmnL_qYT}6u8A_wkJ3_dWai}YX!BVu`w${~e&t44_sUM0Jh@7ekx<gb_%s9(
z3`_7dkw5<NFKCvMFBhG^9A3Iyg><d2ZA6H!&cc7R(%=D8z!CL0`s6_yhaZ8hAN^u9
z0xUkAot-5wu6j<s_uYS!Z~y!EWH=D(F2Cwsa>uO`<R3rtDXDLOA22CP#-J(7u*zZb
z!m8DB<Nw|%S6y+gRKbG~q;vBeK$%##N1l0Zz2?4DloZIwVZ|~6JQg+vknFP5-On)+
z*oQ_)LnFMAh^4onfBKG1yXDCz)=4G=^zvoXW!mUUdjQsm^>}&Ce5!ZmKm>GrnWk*i
zHb-pAylFhaC8I^>w~#$(_>#fl`Dr?lV}jTA8z+(sq=8CW$sB;?i>e!*@eO>nyQW$0
zd-QotV7TO>r7~t%iH^0stq~v*EwBm!_CQURRyH<xs@C~AP10$yCZp~7DahJr;Zl${
zQS`S+B{oj^oUu}v-XYJv^oksWoBFI}Qzgf(|Kra*FMIbLkh9NOh9(71%j(syU=uPR
z-Xa;A)PV#G*w{>#AmLKjkybU5%V~C5<@#RL>FCC?SdG^%31ERZGPLB(%p9q2YJ?jZ
zRxf^MylL*d*|HKX18cFVbKzD`f;<0-XI9I?g);<RFTL#6eKqp(s~ZrjKB}0|r!AWz
zRU;~8NG_A(+7)P{0|e69)uhS{>mm_S!gC~Rf?HZjF{WyiR6|H_*$plD&|$gd&K1yZ
zt7PWXQBstNEyhQ1NGuvH@jxrO2J}#9HkwmRbk_SxN&P*ppO+ixVPW5u5!Z=dHQx0G
zdd(9b&EMpi>Mq5Ts~Q=hMGOB?GIMobS+`A|S-D!KOc*80mdz6MEdh88P~BQ;0T$B)
zcQE%jk~X^;8#ed08bZ33rrK*CXIiz6KGajyRuB40k-VHV$sJuG#rcJ@=H<=u2>9FK
zV+WxO6lepJqevEA@#J$-QCTJzpTAhWca2S55M+&@-4^f}xQ`ijVuGw10#qqn95>?T
z274m^W3PG*OR)=DCY1gR0OvGHBarBd0Z%)3{yg042`Sz9y0$JIi9DL^dti2Cr$dRy
zHDLfH0~=@IoLQRGa@W02pbhFW8Cg-R`v-QBytICYtlqRsTH%=+Hm*u0j2J3aCAm_V
ziR4{`71<PqvGMjcC^Z<9_Ui(#%qc)p8;l3WsT-<?%JzfDWXG-p^89m~Wc})WGHv=O
z89Sy}ILpYMitx@<X2^zZ16@zIrK7sh0QdL+XkB@}<Mp};DAX7j<mU6%loQl8aDTI&
zHx0AJcx>`y9pmRQ%I8#q>BBHHn*`*?zj^mTdGMiCGHKFyS+a1fE>r{JqODC0SZoMa
zxK7fNA*hnFRgh6Qgn3~2GrHU&X^ECD`z<rF3e6I+6(*i7m^Bft`OuZ<`E_#7{VS#Y
z$S%3{&o{!gy-kJ>A1Alpew)0uZnYfTyHiSv%jFXvL+77VWXywL3P5aUpM92Gapk32
zSJ(lo)O#<OY+`ORpAZ+AO<hMWB%U7{c{VVU4<9@tfB4-^vUU4bB%^R_U;&8Rv><l;
z^vcKOk;hg@eqpg}-nLaf^Uq(F3FAh}B^RHEW(i|t0|=$MdW0;PJqfOO#F&^N-h2cK
z2GFdK*=~t}wqY#WGOD)ODj-&k|7OAUG-q;&OzWzGtEyEtY~3xdZrms{CytS&b0(@A
zU$et?{M0h=2HLLAl8vQ|<JstMA|dTUE3wZqfbqq>UXZg4ke>{m-scQ(^(@k?rhsFM
z2qigV<>3{t$TsZt3(j4HFi*LPz53=R#A+Ln=t;;_3t`bB?P6XD$w}`Td86kjbf)VP
z<%MKEyjO<~?~&jB@J3m+W<6kBnM777TeohNg9o=l@n4PjY>qs-0=x&pZ2Y)Ua^F2S
z%Vn2bE=!jz28kj5%gku!gky}_`kP1hq=y0a6Jejb5i`%1SJ$tX-`#i<l9i4sE<+|_
z&`8OV`|f{Gt@EnkBjwM3xm#}h)2(oSr$J#)mCMlFWx@O<fQxOE1@orM`b~v$>t7$0
zvrk)y%<)ut`nfgWf!Q)^>R7nO3nV)WFt`nerKxVeG#s^3QfA%i9C56Xp_&q-(*_2Y
zlA0uy#VInpVjK)F<QeU1gfX&RR>E>$4kKf1)ez0AVd&5xj?KV~c?CZo56kIu*PO@!
zQ~~{-;J^0SYKA=5_1E=-9RP1Rks<bWPV5jlKqeYEJrt9_`@m7T``$<7yyXjI^2E`4
zsXA(Y&_X+zc27Z)oDR*3u6*yp?mH%$gv0{|@L8DEj${LE!OdcSeAm{{BIS8Ga@E;$
z<nqg}KsTT#WbzaUZL|_>YHXF-W3?J9sVFVPXi#DWcQA6Vq$RmSjvTF*fBC|f<!LlC
z_^<!`PnQjf7?H-ET_!XL+R0*l9*h544`7x~uz>+v7=G%8e~?)-=E%oB@i8exzhCy}
zWws+b6p`3lA*kt#YXdZ62CVH3P#}Kv)1RV#x={Y~yWb#tob}j^vVSL%$vRQvsLBH8
z7=++7qhQH_x!$>L7?*BQFqQh|G$g#$;x?U9443%nGpbPAT`AAJxK7q@-6dDQ;~acX
zE!{SkLJ8_U20|JAJO7Q{#shi2L==BPId%X5f96R<K~!-nu6eR4_U&;!pRA+ip!Q~G
zk(61~_pf*n@!oxM%~fYhL2jmoe(LIu!AnQzRn}5u;~d6ZDIDmv16_e$m|1KU2+<eC
zzdDpi<4As@dzZBR-uHY6393h=VnhWv5Ugd?A@g4OIa85DR*Pd<8{Lh>tRgvf^a!%L
zH_9Ei|4Bag&;Kl+`os<T9g{+7$gt#8b6P^%Clb;GQBz6CgD35&XP%XBeB)bk#XGN-
z4}NI5wkYj_!k(_R*XgSKHzNU-c{loONK)IpVZD6k+h3P=Uw0jPn7>aBql?<;F+(Id
zbE-UyxysKilvz_I$h0v-r5)kE#v^;=2$D}VVHL^)EqwAeUoNY2uP#IC^W=NV1Tmig
zae_;~12Oup<bBee+J)!OlA%c6-MuSI{`wd6Ri8dVmMxj)o|V_>4;SdqF{ff*oBG$&
zD0UWfxD+z7esKi#8^#)9B($GMy0y(RTk-VEGP-)K3g<2e<TfT@Auf`x1Y#u%9T1Fd
zG%w-uNX0{^K#=wM(hOvuz0Qnh##IR>0&;;bCj<54_ug}#Y+C=CoPNfcQc#?)0(`=R
zk&tz55Q@ii!__w+BOEn@sB?lqMDqhAtrZmI%bj=q1uX?Hfg9*tWM{%+)u#7+Dwa8!
z>Klz!*(7*~KV~=n>86{cY)Bd6Lf_D1ckSLU`}XbAW(LKjr6?)Om$I@VS-*a*l$MrA
zRYjFdfrnx8_;K>7Pk&sVeg1J7KXxp%*d}CPTQUpdRGLwUiPbxL3tB@1ybCP>{({61
zXuDb(PPaS$(wNcOgjiAIQMkSGWZBX=a_=K6<-P}>mMbq<s4lw*q-md%e{v3Z!}jdS
z8UEl^-oP2K6e-U<Ezyzx-3j5i?zK&F#XHVYfywYsBd`ftnvpIA4;_kSOn55dmL*kE
z**C!qzN5lE@S?&?;p4JYvyhPWz2E*(w(dAAr=7VR;j22y$U+VbI*+vhU!fHxS8XVx
z+JE>6T9`6Ry9wo*t;iT3hfMM``Pol@Dd(MY4zjpMz*uNe6hayqj6W;)RL_|47FD+0
zed&2?1wO;CfBkE@;QaID)1UmfR<e+%9I2^8o=E_1K#{*Any^%$1hqs8zzbi8LNFZ7
zR?5q&WiDEn^86qD;HR>5*?E$aUm&gE!6T8FTQGmJlopnOR~4X4Y!9kh>NK$~xf?k-
zn3oP@>~gNU@TcWcj_)Z4(vKW0eHk`yYCceCBk?T>)_qGu9r)r=sYZjBjO6LE^63|0
ztmMnINh6&?6`Joia8LETwHC9vr;7d6A&CVug>3<&OpO|n`=mdd><8_OeY)Rcv<9<$
zeLlcTYd69D(<1M<<P2s0?C4WphYf(NX0}UHtqkYWJ)H#Yi|!g{gZH^i>@1b08^!?R
z6^ui*-E`GlnK^mSefL7x7QjVZg!;roNYp5mX;Y@i;R6S7uROFCERlO)-A_cH-edKL
zWzWu?NK$K-0@MwbqV?cSH~mpgM>{|TLII(4!GB~j(cDpHMcbyO^>1<K6eOP2%c@l`
z$v=Pob7*3KmWC+n*o->GO`EpJgo#t-fd?LeyMMCGm_AjWdh7{V0=HLTehKEMO(sql
zEsGbQA;0<ct@7os{0j(!8Z6x7)P}Xp!n_l_zlQw-jxnEH!i~}e;_5=Cx8jGhhMc7j
zS~H3`9EiCqsaY;qK0}^exk~PS@Cmv6!ZU5|HQpAx_OYM566SYf*v&%<?rZP#xx9l1
z{H@IZw@hz_QfNz&ZCZ9q)Z!(NdHAvCW%leDGP<Hng>ysAQE6sb5QL)&61bOH|7-DF
zpTTT=RjYL4>|F{;dc4w+D?;1^hNeb=PU~8ZK)G*(P#hx*=Pr}i)~|!|odXYH9e|2<
zA=hJpY(@C$P{RS(4&5?x#5nCWe)}Ew$^ZL@f6$PZTA-{6R=_6XDSR1Kxr9{QpMreL
z=B-i-{DhBu=p%@ux5L|4huHTTjcE_9ESEcPze7$x^K5Nj`t+ku$^{pkCnb3Wa-i;r
zT>OrA$<4RiC->g_D6Hsr!X82SW_!I9WP)!ZS#8%2xXWSSa8T_S3x#qUb8vKiQQ<;{
z3Qwgr6!PQLNwd$EQR_0$wc-eT3;c&T7v$AP5AT({qFkAK+H|>R#k10c@Zo}SLn$r#
zxzqcyqWjuF{k%>1umrr!3FzRi?1kz1<fRiFL%h>WBjN_Jc%<IK(E<tKa80}H-hWJv
z)*nOM!z^Cb;%1@VuN;<RE>O2tzWf^c-OiI-BrY`}si_%Reyrmq5wQMEldc$u!38zz
zQj72-c5$Ci<HTg-I2O^n2r;e=YaGA;bn_BIk4gde-|Me!(Bv=VRja~~g)Ha}xQK=n
z50U)<FVWH}!hWV^;eD1I1waX(Nd>TGXLH<^pc2mbq=5FI0+ey>cxEl5#5MC!dQo0c
zDYdA*o;-Q7y4!Z*exuN9n69Z#xZyf6{#G1M4LlicxcXY60olf5y`yD^tG~^NSYyxX
zgj0%+l!)lyXz^QXL?s>-?2PRj(en~*sJ)yyW3oK)+^h1)%2(yIh0~-CL{(qkgnCEB
zx*h2ex-d5@2au)dKtl8VodN{mH*rvA+X!uKXdT!PO$pH8oBtH+QtWfl2M>7b&p;di
z3YHmJ4X#r@X-Miex4qud)&;Ay79~W0-$e*Z%ZzZHGzhMIBwh}yDhIB@K9osz%7U2_
z)IHmb&=spg$a9QV4XnsqwC>va*35$FU+ffn@DK`5#Tr1IwF4Gn2N1-P!B=QGzq0yO
z&@@AL$FyvUo;)hYxjDI7cTE~s4;c9$Dn@ESds;>uv6Q`m<#>oH*-<)Ssj26U?cf7U
zXXUv=%7@4yfGjnEpG-lI^8I*Uf$zt``<8;78YZZB!*kHu&M~9Y8Tdg1+M8;bD$Asp
zaSnLWNK9ERc$c`Qo&$VjX_aadOlI>9fsD3;UPJ@yVMP_k#;kOft{NHzaVQ$$KF`T1
zM48!mdGxVoWk~*cGNL?BYLGZrSJ$9WrR1$tR+ybmxMWmt33Lec$a)d&^R|q)*dNQ}
zBHaZ8tS7RPUVH}Sd|0N3kLg9^S{8S|OI=Q`#bUw-3ks{2+LMA{sKDuxZGf-bvgeR&
z-c=_@8zKCX*xJrj<$=i3kW`VEy%VnLcEH@B=5SbrE@B6SGX)GsYRMKVQEdK{X!zHE
zX3gU}0?9fGA;&l|EJZ7m>Xs#o7RfEQ+$tl{UpEIyTNK0_HlPH6tBx0&-e)3)bL8ND
zMe)hbLUtrH?N)#g95`@9-h2IgY-nh&h^3@Zd!&M`P<TP>IiU6OIYAKx1qCvCbhX@k
z^UZSF>C2J1T__VK<xBOL3CQAXf=ing{ZU-26S1IC*qAMnl?ODT%q-cv=di3;@q}E7
z*g38FG!U5zG(Ml!KSp5@RVW8Gt`Q3buxYfG(&ok&*_g%vyn;cx8#{K4y!i4ucoEQ>
zxT#Z)p<JyQadEvG<}?-Sp9j}oJ_K|*$}WbKl}J%x7Ty<0R-}!lqY4$)giN#=O&uST
z>zD|`rRI+Eidn*Bs|Z;QzInUMK!CfNfOHC)123X9rZTN9U9pEW!xyhZHBE3QACPUk
z4gm+?h_rymbRf?}xg+@ok}oqL{EG6oOEWCRc}S|vg@xP(p+d-BBU-1#Qb`XoXg9a9
zU-dk|E8WZ?DK0LQnKP%#t+(DT^Gg;2xeImH&5iQ%+7~rOtlgyW6gk;NNE+L$#sJa0
zQUEl?3KBm1#3_?BSt}RxM8BUY!Va1@;6_%8a-Z7}eyai~N(z+aTkg1BZus~|q^krj
zYJ}tJ>#MbjqY$3Lef#zz4xS^!Mvhc#I1L6!F>n#?fAm?*;SRa_nyaM&AS$G1#ad9s
zD3*trBxK0Yg%B}D#-Y8!9W?}^a}_L2qftTw2smv~uK@CPFdBq6o23$7&HZ_4a_>Vc
z;FhlhFRTYp3o2b4jsvg764Gppy)ZvVD$5I`v^WRZ@_ABToM#?d8XSZ}=D!R%s?p>F
z9|5<tGYm8@CnC-5e0{|eox$%Ch*oDozcJJq;hz+AV9xAz`^w83k!-LR6PJv}@&$7K
zS<|Eh3_2%WGr|<Zl`xppej4jrr0&>ZxLwL559wd+=x^HzVROn~)ZVa>sO2_7dw$2I
zm&&S_UXnZR{EJjE2IA`X8k@W#kOZr~!LktXqNUgh0^5zO^NTOJNER<$4DGlX)+4n?
z!}2zv=#sI5F&S=VO%{WO3K+i+eBcA}jc@*|eCqH2A7a^;N)E8RwKEou*|Ke$3NaFZ
z$Hng0z7r6qhvW}`_>)YVHcj1hgdog9nU=M&q!Zu31R`j`J&2i4(KFN$Ca54WbvM^Z
zIT%P9$|{)TQ86T6GDemu`VnU(1=K*rrW45~t<4S6P**FfccNY$R(>jK9fy=>!7V>h
zMq;fQ=QhEQ|3IP9`=}81#9<^7fdbVeom0Lm25<0YodHKPR_aIQYWsr<{6QpZKDX*M
zIdHfcl@3`la%6=pSvp$^QOKVP3y*CU+n_uf1aOiZJye5jRxP83Rcbh`kzpKMmi$YT
z!3OZ+KIWLHd=p9QA3psl;P!8m_3K_mNmT`)7+4p~5FStoK{w=|jC-5ef&W42CyL;~
z!$;-AAN`0b?*u4e4h}<4G4!a)zx{cB;@{KT_vuf4TE6?A|Ai#8qq1!IX)5?t&Zw~6
zq@_-~X$VolVbUsi$E$1C$)9iivs`ic<>1}r%A-4>I4HCl2CEs`?$ty1D!;SedlSsw
zI8g4$@TD4U(GY@Og9;Ut9P-==W2@z8O$}<rJEde)DN4acs0FOD7tcb3L?T8u!=O2^
zdyi~iPmcw#&GUeJF`_`mgXffjr;>qmVLvbl*5)a`%Y0xvpy%d!Lj^Re)sm13pO&00
z`)eBIo(G;s=5ewtI&G?q8Cs?(=IBC-*azwf8=)ytFf+c%?=eYPZ~^626e4EZjE&T&
z%WHeU5U+w8Z~%1E<5X?}5{SpL<@@ja`*&mn;O+kP-~JUYV?f_=L1_hB>Y@43bZnM&
znO{^YAN%Mh<*F;M(oK>DB$aOX#_57q_5qDwwMq3b#co_)h1YIIZDJu%%D(gMZ_8J{
z{w=xwJ?}AhJ}|Hqeo)H`+_`kkxFKXAUUdES@00V-I|stB5lJQ}J5!V)CVDaHjxMPv
z!32q>zwg7x!M}xgR4cOH0eq5~t>{LKNp-e3>l@lNlRjugXTS?lT$m~&Mv_@2L+fpa
z_S+!$-?s|ZLni9GC(3BlS!4N?&@|IrwOkX@F|Ncx;e0Z;{#)`|YVW8%Y3!5AE0OhH
zTDt=|9P4BZ_R>2pn2e5ahGfu!N`@9f<f6KP_|W|0xhW7v6(~hS+Au(R4ofqe@GxJ5
zB~m220nCmUj$TN&z}TonGS>g1%HngM`xp7$?{8E*0(D<2oG}apHmCv360Vr&TYSXo
zF=OTPpZ@}|4i-Up10x%rD2|^XDb|M8_=*4XL-wD^SL%?zGh@aK`R3QZE?@oH*X4&l
z_%ZGQ1%y>4oC)n%LGP6bIWiXJuv7t7^kXO`oiuTR8XV~e3D6rrv_!St15SgWvXF?U
zgcXYLaaudBBeJ-<y`U68(N891H7#Dy|4@LpWTe9Ygp0icAvMYlFQ8NLENp1R64PPD
zmEa+n(%8`;M_?dq1|r+@t2YDFVU*07J_gk|`KqWfZf>isW<q3NSy00nWxZL>$FWb|
zSOKkxLg`3E5V`qJ56iI8!{x$rXKSH7H(MPxSSzyq6qsJIoG}4xenDJWOaL2*w@?Vt
zO@c-ke5Go#k|n)`H^FhtOTQ201|_)pbI&~|H{N(7wAL|-flC5Yt=83;TVfXyswjlu
z0y~D7^Bt&@o;+!iEM2+?gpP6p;>vP^X{?+IfVrf4Y)lXll>%;l{`=rVkIHk;KPTs1
zaK02FK}|g|IG?TMEMWyOdC<N)7^}v9+6_%{<ugyqjA@f)JWz@{ac^SUTFs!#-qwBQ
zW8F3#eGyEeIoI>t+7T6~86_HqV{D3)xeLsCC$mEqfpjBYq~)U+a8_EDj2)gYlO~K%
zsMX)zc)y%>+EO`t*#xzwskT{et=)&%--aULsAM3Vv)?;m@W40M4A`Rk{1J;!LgB-H
zN`tp%^_D|&*Ml#}HJ6_yldFsL*e(DG)oYm)la>%q2A!rr*=2(q+rrps*k;;^33SJt
z6NTti!RIq^Piz)Q2i|)2kh;XazUihv$U_f4pb4IQ8Z|)NAL+w~@z{Qr0(0k{y_$47
zal%BY2Fz$H1QN5x%|*-d%c$WJk6yik!0vtzKJb97df^4Q+e@@$vkibN>_<-_P7B&6
z-?E0g4NQlE{n?c(aqsamq@)DiOxA%jsg;I@dAZ{85I<w_43Xd%dw2jM5n~Es<C7d4
zd143dO=C{WOxek+(J(LA$i#AEuorwN6mw5pZ{V(34og}mV)_|K;2n$ok}E5pT_dl&
zv_-DF<{SWDLE$mZ<y?5CAlU2VGnzM6KohG9&-MV~7Q;uD%7y35RCh%S-4lS3>})~P
z3AF|}1^AaO)X0vtR@fP&bl$R@fdKTh{@4rIG3HYVS!#Wmt@Fr+4IAW(U-*KYamE=k
zYtCGai>g*j++FrgRW~k_33Li$mLyA!sKLL0&Hvy3{hx59d{;)HhOY&vKePt9am?zD
zTCx6qelybz#;!MyKmM5f?svbH|M|@?q4my`nz|+=oYmm37RW-CiZVt3|AWXV&p<L;
z2?RL9xi{Z@tNiRIKasC|?Td(Ap~jIhBD<k#o!rgT(!<0PCKx}*y}70I99)|yLK?N#
zJq_Z)KumL2zk&%=Ei>bHRs+uXUkj3Ano-X#4Tq#^NU>aqvXj>~Zj)ON?F2x?QYi+a
znT4diaCSsPn9;%4-|!4XtsL(?Vz;H;NCJEM$!F!Amn@b^5YA-Htq8#o(1=2eiJscF
zQOlwz(2Py0l|});t>z$twQPy5Y0s|*Fx#YY54yxS^KG}?F2DHsFXa=T_$0hZ)lj0r
z1*vGmYG)$~cC;fOpmI%1Fa`9@B)5C-y<fij-S5hO{?~V%mx(PW*(2VN2R#i3J&e9|
zlfUI4wtN%HH-GrUAHjf_jQDpJLT80=`xhZetW_I%<ihL55F5L5Wg@4B$c*%g-E-Gn
zu-4lE|M?FfaU_cYxe>X$%2)Ir&eBaJsQWSkg1?*B!q=KuD332~9jv9Q@G4+F*dkc_
z8{l^;Xr}16WH_#yMil9)XD$>3c{|n~%1B+qKHyel%c41><<Oye%<JPwkQ*(hEkb>@
zZV0!(G#IWn`2bcw{;6-UfEH-7yX0Wa5qaOcE|g46YFh_fOAs=ht?We&w=XqT?eED9
zZ*xspAl}qSYOwl8Xd5m`L~x(HxeB_={Z;)&p;i35-~A39XNJn@r=KnR(87{Jdo;49
zo3VN6mLk#Z*s&9!B|sX&Zm2nSM8|#x8kFosec^9@{TuoE*S=z#i(0vEAZqQFfE5&e
zL01@w^Ojp~k&nZzv~<xz02kED)-78!_FMv3zD=7psYO2yHP4Sc@{r7)F$*=(L)4P^
z(1$)CtJk~?CUBd4=!5Um(lIIq+TI$IXx(*Ut@nXwzv@<0F6rW4Tr1bsQ}?>}j^N%Y
zfJLQiz7qfo?QC~SFGMFw=D<mtS`MORUXsk6oG%-99g~}GzF*#b^+i$$d`03CGZsh)
zSLFzCvUpG4t{A-1n{o!Uq$$WO>7}#psKoKz(<@(=iKDAz8uB6dYJ#9?P)n2h4p`7s
zBXM9dD;g9@P(`wPT+8#dI5vreS9a3*1o^Y4E3fQQp=bE&x4-?JoOAYhGH%=?IdJe0
z&<INq+a0F3*J%(s?GS|f_wAP<L(mcziE8zTKeJKJ6<1s#-~Ztc<c>S;l<Tj%2Dv)5
z$}L%G;nT6gZf<V?ke?kobO`tUEqGY9<U&!X!~A4sb;uNyj=uQH%P7xWgmS5!>Lr{q
zWwN~f`bNDjjgpBICIA=WZaHJwQh+C!Afwli7IgUD!Tl5FabZ3i{;cEIE1DcI4~AbO
z16<J;er7hhOW$+fc{Ra)cZZSdng@>Z7Jq~~?(R4MrDQLX$ns?hpo?F8X$Nuuy5*8H
zrz>wtMO$9-8OudH!41$0A-$mjnp3zDoms|=AB7&t=2~q7SVuQpOvI_CzD13PMB^9N
zYbqLQRRL{_#2Pql1a}H1$uD*=ZsX(2t<WgBp(&snkvYf=bjCZVwY4MlU+WqHX2L@J
zj0^*SKMHgo${dzQjR3g(#*G`K1{uxiI8SQ?`Am2|CUzL@N3~wv@YsALh8iS4@EQ{*
zPDEK%Gc0yEhfy!djLyo6A@bU5uc0n5UmD8GG($TRon?r2)P`~8AiHt`h-u|>Pb1S4
zASKRvwk%4k-}G*y-mK%^gtl&cH})tQm@wwcdc%@&dRIOf9`iCuaLk<L!<!qN32ZDU
zVGUawwDLCe<{mM0q}0}KLrv;)a>)gY75KoA&n%<%6ezU4kka5!Z<ZNwJU5cS?Z?HP
zaRh)tHFYg=`r>)|HS=0p0P3Up+T1pdV|OXy7GtZr8&$Y_o@1685wE-=;2E<Q5XUzY
zk!lln8U-|Y3Wanf_)0xWgJ?A?A`nX?QErtF@S)ZtN7Sk=Kxt(?7)niT1IPvLS>$k(
z4=G22*$(gngwAN0lW({l_CY@8`H81fj)l1VOnznCNd8M}w6+djIT%uh4;}zQ*J23h
z?U;rR2=S3X@7keNBhX|}NkXjbRM`QnhZ)nSIl=5Q$4ToUUgl@2F999@JSNoo)iz!e
z71ECPup$L(Xoa=PkoX^WTU$R9_4=dhAq|fN6*O&&2|f)z+|+(pQUM4vW%6hkHXG0o
zq(Ei>1Vs}AowDHCIz$)$B$Oq;p#r)YF5vpwCRu=l1io5<c+-Ib-Bff%VT_rv6HE9(
zoG}u6Ct(-^HfII@%f6yEF9S@Zv}=SmQM}EgjUzxv)Ho~QO5VI>t1Mc4ngWPWK<?67
zXG`KpPDYJ0+(3-QG@>I5-L~mS?`Lw>mMz<)qGA{Xj=5^oL!j*=1KHfp>h#t#$4Kp!
z*_H&fU%h&bOow&cgoLkQAn5e8OxcS#^RlH&qz1~s!2^3yhddoMl7t9t(j+ZzytU}x
zI;5-;*Fq@40skv{7zoe0XvHc9$7?}{g|lg>QMu`9i+7=pYwHKg8BB(2Oae)!D_oZt
z<D!dBW6pHRCrfkf5g7wZ=+$)_f%!XJW=|faI<#&D@7;`&%iz1eff<Oh>)40&z3g}I
zJp`9+CQznwbkEh)Bkl-2IGr`jjJGM86-unY)H`V%;s0tR>7H^{AceK&ANdf97tklR
z>C{E8iC@e=f!7Ew+9JU4=A(>q)8@^x2xXk<9qG~l7yJ$g!!#s7?cBXfYqQf)%GnHF
z&;(&l7k6e>uEGHCKX?%QXtCD)661iyhZJT^1Pu!4Ft6ji>0Zx+#dzrOVJRywM~I1a
z-6^si##BB^ke+&Kg(aNA!$97WiFR6Tt#q-YIt5-st^pAY8_<WI&4^fv#_}wyw>JJ7
z%Nt_9>kpr?>*#-Dcy`bvHVI*kH+21J87qhI_xBuEAu_PM@Y2C<=5@7v6Baao=!AjD
z<h*78!=z_708=7O9((F}Ksr}SeipLZxovt#XRinh%&LAv1+=;mI<qBRV+7sO+JVk5
zOe&z}%0vt>YR$~0-x~1&n@(#aZlquukf#3YV$j<58V$eqi`ak86i*oY?}Bj}UXd<l
z#$m3%{(AZ3CvT8H|M?blusT;`Lk*26g}`%p!pi^%$uVHlQoGDSc4I3D;Z~F+96E4F
z-v5CQ!}>=2IUn6x9O{p`f^FPk%iYJS_^emG^D6nl_kV<f`#iYA&Iat>aMgTCjBFvw
zn3`pJf{0LZK?R~7wSZs$+V^D#2<{V~{CmAOlOpH}q;<<IZmq+1-iYv==zP21;}M#l
z?J%JQw`!8QytsTWvs5i<1}?BEv=q|HydbVoCvWRY`ZhssL9Om2cGv>gKwc`6$F@Mb
z1sF@@=KWvu!6V-;GmuC;N1u-ZNE52?RXY^v4rFR4K|56(XobTxm7j(|ip$GLf|6*Y
z;9{t5BYR`OP_MkPaC~#=X@tDQzc@xJ-yiz$hvW-i_#zDFB$+yWrYa9DD2Zg%2l+}H
z=pq$fw<EB4Iiy@5dmTQCwwFNqDle~)g%HpL3n?yO)r70%b*^8}Q#>#6UP5{VndJI`
z54>N#@vVOY?RDW=mHK@9_U%#rMMHypnYi2=)~;1Ug$Zr-5Xfs@T`T7SB6K_w#n^kG
z03aZonT|j>t2YD4^SeYmB>218zP1>4O_$3ZV_=a_H~=hi7pH6~_i@{WrjedYo}+PS
zf}&EIgZrq?hEOXTcu?7>Z;;%~T*UfYQ15+MW{$5?qaollx9gg@u6xFr49B-I+|h5S
zfX<+1he>FJYbL2Q8=HZkAb2w73vuf4eEN7g!JKHgj*;}##kxdiTX#d?Br!W0?Ie{@
zGElRI&EAbti6p|mp#;lXxj_>qLJd)`T+VOM9TMCSiG;M@)WLsg$qpYrTt5Bj8|1s+
z`!95``m>_$Fd2gofhH(jdpBz1c+X^weftl<$~_<-_~1vS6p35>&etQFaJDjr;D!te
zY7#L8@0{7Q<)Vu&lz;!uw~=xAJjw+MEy>Iw<!B<7b8%_x9^eXFw(O9XUs;RT^G6g(
z$ACTvF>2YKUc>CmlMvQ~!@@dd>`Fv#mQ6Cdhl^^ly4JLu)m;K>0+x)%;3JZqdxF+A
zJu4(2C?Ci?%S7C*0RS~b2_(3Hwwd=?K_^5OgD1UpXTUSWsGv12!X2Ip;ZuN`*B!=^
zT@qwFJvPjoWa$$3A2yujyuh9!L)SWAT#p8WCMEG~DzW4z?5$1$viuF*ecF^lnV8bC
z6@~`(yeETzB^l-|bS<9_@S*G9`)(v`{YiH2+$C8+3-jIkG?SXKaWV<qpT+>`e#eg8
znw<LakAEDVNYuVSxO-GCCVi>`61p$>h*!G#8(r(?qBp?St=r_TyYGQQk0v_2Gx?YT
z1L4{5f5z%*MROb!g3UlooIh`#Tzv6GifNDo-a;jags&!4$TJz{ZT@qAt!ulc6UsKi
z7|YzefF_(xURdZ%$K$|@)LPbGEUB!UJS7=n0Zmk8f-+=?>odTRMshbw$C7{<0pp+!
zXpOq6P?n5~MaSZpo9>5!yiSpT_U3);;DY)sw>ZVth*3qdcHMfJG^Sh|es?A@lbM@c
zby%G!^pV1*$dY3nDf0aD=w}SrNTN+KCb{WoC)z!}AXlC}8=#eK^85RqlZ8O}8IIbw
z2cLRH&YNBZ%`#UvZALeRHQX@h2+j?a3he11VFWiwJU37<lbXL9A`Oy@VMQ-nwp`Ys
zVaE6W`}=S=A*Q85+0y*|c^YeCoZYpFeBTE@EYoIA!7*I`3c+UR#CTYDNdi(Pz};i+
zn0Vu%*4>I2(>VaeU%lp4`Ngk(p;|37+6~GM=eZ0+8xO(=a6wUVx%S%k$e1x`EP}W-
zwO=A7k=R*=p^Y+B+l;!Tf}5;2LJJaI_`SbIPeJaO1`gmIeO!sKdU_3|g6NjF(rz9J
zOCl*33Y#_Hh>{0?GZd)7*WcO<c*mwXXDpeNK5X4XT{5h^P(3u8UfU;ACjd-?9y!II
zhrmOouO^3a&#`kI_)wQJUnuq1iz&${gJe!bS`Lm!FL}6r+tN`%K-z7Ak)hp~SPsfu
z5(;Wxk>JBuMqAw0VSyY`&N)mBTr;&{&0cf$)v^Zgo&*3PSP1Ep^uaPG(yOYn&VxvF
zv7tkU0e|~5$j_)yOE)V6;~~~Ha!*Jf@ye_?mS7?*mHz^G{N8c#1+w<lHK;au(Mm*_
z8BP8`cQNj(<!1O-%dB|sVI$<sGtbl#E3JbjRs{Hqx|u^B!7wjKWDNAiPwX7WBlLZ2
zd2N)>cs}6xsb?w?OV_vu`ygm?DxR^^DflS>Ria_X5CPR2Ruj>~=smY)N|?umLpj+T
z=M)KOa~XtR@diI<>Lj`4wTI<}HE>Z*8iNK9HQJ%1o$-KVxLq+B85G!<o+jYDzPxdl
z%$iUQ-#;*%)AD4+hTU@0i~FT&T$7wVCQlxFd8@2H+#=V!<8*mqOO4Ej+cO98CAw<b
zP}`Wwj!SHqp=CVLY`?Go3=@#wD1Ol`wrm2Jr3Rn*%x6)Hyh>)woUQQ)ZfLb~Y0cwg
zmOD|PY6%$rh$ME)EjOcw^EUbFm%gM3HCoiqT1#5bma&phKr75B2!L7O{|UsOrBD#Q
z@|CYBjHf2PFh-3Sx8KBCjseb)ig?ihKmq>Z7r&O@|L%X~V}SB&W3Oz?i3&LWU-zFS
zZ<&q|Rjqons>8%|{Ga`OdhV2-LY<tH?zSW(iq%MYRV6x?SpX!aGt9}Rn7=i7_m+BI
zQ|i5U%}Hf&P$;Yl`<n#F*d&=hf1EtA@<l1GJPUal+2{aS3t>Vb0u~Hh271^irkN-5
z?3M$v5&g}tTsV%}tt4gU%U_<|By~voeE%6U<hhN9<SAq}fB5pnvS<5t*|%$toQ5pt
zB)HDeJ=rW=b%9d}bqPrU3)U;|9`wiyYPNS|e#)oO?1Gls;w4L9<?}h1e9DGD#(#Ll
z4qAAuOU9U)asBV#`yL>K56Xu>^g%-~Wa$`Vz>0AlbqNP)*;~>4j%{q8d+vGp$&Y_5
zQ-QmE!G#w=-(~5Uc?4-4vsBazM@8g9waWhe2j#c_^FLC1#pQA#Fd15KZ;p@POMDTV
zA#7~)C8)!Ew>Mst=vv`WT_U~&HN%t`gk33!lK?N>(OpOG4c<xbEwCk^l(a+XprONr
zIDOF&B3qB4mH0C7c**G$3Fy!;Voc}g2X2-^H2Pk$c&6NS-(zq;<w|8KT~I)nqNa#P
zPDT8O8Fi8d?UgmeaPy=<W6eau(|*X6*U*o3;{53#l>M@3bdHQhKjwqYU2@x#+a$fP
zN}7QT(+;BR0%93NvkJZxg3RNR+8;HJb=uc={GG(XO-+G#-+lMVV~;%sB3iE2F*B?e
zGyVf&*}HeI3g>zd*-^xYR6b)QS%}R{Mk2*iPdqM9oVH9ZJpUYNM0Tl4M;xQ>DD})m
zHAFuy3TA4oj1~R)&wrL`ltX;=D_=swOQY=By;p_)?p?dJE}F?21R8kY!3W_=FOj+P
z=gKg|slSDD-t(UK%8M_)0A#M&+LDeT0=3&!C`So7yrKIeu*1X>k0=rmir40YyQqhN
z#zb~@qxlDvj>e{Xl(3C=@n_B#l^f?`biRm_uiG9ksSO_ge=`FP=9L1${R!yb89kc#
zH527ktI^En?uS>()fX-W`$b|Ecn%foc39I|2|{HL9qabgb<65Kjq*;qyHm2I1}@G=
z*YB01hy`DH+GN=Uq`Tj(SSQsJP>GV(Et~f@%2If-GN2@<b+dl}J%F@&$!iR8%m&lb
zGsgKLPvKr?&dUG%_J82A-VW%|<;Xm5(D2plIrD&;cuWo+Lb)OM4BJ4qxR^B0%R^!r
zD@X{Mv<w~c#*L{4>Y3qoN1N<KE%+b}dj3LXp68DnKOU~`^W_lm{D&Z>U0htMab@<H
z&Tv&EUMj)qD?^8mL`%#pbkVv~=E2pSpPvg$8s0>8Cr3SwL1W0@zc0ai;udz#T^H|O
zIu3Q(+ln#gi6IQ)dTYOGylZWPrvzcyCU{Gvs~Nc61$uD<R<i^{t(#ZY>7(NVvk?Ao
z1axGMqAm%2FuHQEsV0mqmvhgUEB8P2w2U7!4wm#dxN2E|4|lA(gn;Hl;elfhwIs=_
z4G_3Fd9r%rMrk~HP=*aDk==W?%lchI(3zrDt~!5-+<n)R(C7|G)|n&Vx?sGP*?bm%
zP*<+%N<E1rm<Sduui|)vpJ^SN`?^zB0zHTI#UyHO;L_4EP4Zw1%*x6t{k#44+hzLn
z87Pf92I09K@u6fbxhh3D#N&@YE@wbUb7hr?+%OfYlS>^^B1k|~0tgte3)!56_Nzf>
zDAqylK=wG}+cRd(k|!Qt0le+0k_k(?rlwXV0=0}uAnX-ghWnm%_F0PjGkxYXHP-dn
zU5qL0QHUoj`y#3!@rU30>xBhxPfIyy!ABGSG^zzx<B?;~a1k3Ejcjhd%++M9S)a+-
zQv-_x^(6AaZ{DOc;M|rL6C|yhCrar^=?Wnv2;nO)I8E+*bd~(+)(2$K+&MB7Wr=8H
zj{Q#rKx8fRysiw%fHF*o{9JHKmV&N;YrH0@KvMG%ZbL{bEqjEVwrrNX_WJA6iTs!1
z0_2}iz{9<qLg-%IgVw-BW1@^@E8ns3QP6_+;V|MT97GoOt4O%2MvwbOBzm!2sx&P_
zmGXV4eV#mdiqyi}$m)@~^XAHyty|OpfPJS4V*B>)mnWZkQbvs&Zpe$Q%!mV0;#bjo
z1nK$PwQCo=QnhF!c@ZFXk7+l)L+CqAoc}$0_Mm)fx@<;vITOFCf%m-+MhG*#>yQyY
zZu~^aTk({<uxgc@eb$+l*h!_wxx+mlh$nCp3eH|Uc)jtM<Kr#ZBMy+J8(~%jEnzFm
z?o51-5C=n=jDNu3+p}jk`ae`iS#g$5AMX>1X~)RpfeB|``_u^Npr<loF!SM}M9n$p
z!nMP-3$MP+L2Iyb5XoatZ;@>eyd-BX9WN#M&}gAib^x%1i9xxD_movs$pb4l$)*x&
zsZH|!3+Bq~nd9Zb73l!7KO$4Bie!3zx|E(VSsr<+QSt#BnFg1Hxpp9ySqH4(eGK?V
zOAh>E_E$iA;^KKk2czr9XNb}T#H0=@nLs0V5EyF}c`Qq^_V3-JT5d8?(sWW%6y!b~
z?l&fuY0aa?Kr9X%-pqcCO5B)73SA0qy2#mfE*l7A+qZ2;8Nf&t;#)Rv(Hd;NFGGvY
zRCKQDgp017WhGD)Si`9P3PpvnAe<(t1zd5x5zmPdRwAJtkM(oEXk6WtRE_l=Io1dO
zhoiD!-c%W0Rcfc{e(T|HdXq|%!C{^B83-@E7B9OmHFj#b2{{l%SDd?0UfH-)o_b+D
z>V}8Nf;lh@z?=zCp~+$tq@b~5@Pw_~-yo&wZSuk^Yow}pC_3on$a8CVOVyY{nN^f5
zi>J+!Fa8Xc<0MoPXn4wUNf<aHx;`yv@*5@`QEBvf7Qwt0L%?GEnKrlWV+uiq35KG;
z*0GyG%k-e_M4d6u%|yv$I?Aic&{zI2dN`-UTSs6Y-$AMg$&)H2BVD3AY-zOA$<w*N
zzq;9RN;{Fu@J5jkF^yF6Re3;-HqAyN8D_y9uE}F~X7UxQwqTQtE?Dj;@j{ZCH)eu7
z)~|a!9uwwwK}BXD0yz<%id<7Yh}<vym%N#C#1N%HOH=vTv+F2~qa0bhV2*a!)2b8l
zNwom@$x;aIzXN}r5&<14KM0J^;`#0YG#<iwLrjBW-7?(=-Al6z0QfOP9$EJkEW&cQ
z5Q-%U8-$ZXblmKe7Ww4)Q;@NZ<`SsqB`$0#YZi|kkn?6D-5rTeNpM4Tb<{{%WtPl%
z*BO8dZ3KiSHX5@H;o5Ftj0qYM-ML}m7qnEv8z*eV`p+a1)*Ie&=Usr-9E!Maj=G=M
ztXZRRXwB-xF|?MqZr!R@cSc6G_K<FXW_tM0QJMFi1%^1rR%x0@W(-BsT@)TKYDN3a
z%4;(DZ6t*7?|=V$S$f(Tn#D=*k+EaPX$+db6NH4`gGrMxZy?fCB!p$5On`XY4?Xa(
zTz<u6iZH}(QVRNloz{u@V&aUGc0Ck?u#2j{L=%tjf`l4*&&PL)ot<M_US|SvEY>8_
zoxgMMQ9RdpnGWSHlQB5D4xMY;UyFota!6(1#5Q<^|BD%L8eBw4qs!WX@34A9At244
z(uB1C(qgnSMaXO`EYQXC$E($(VPpJGdMPO=k;6>~<!g7Wl_^6r(NZy8K5*7(ZPat)
z!^j(Hfzq9oBy+};$`xnKl1}svNM`94W0klcz<u>!b$K#Y3}b-_NLo@z+75-Vd@XcA
zVF5bL&6b<~bhFHvQ>>x1dMFAnz5KEYMe-PW(TJS)$}6vcETD7%qB9LvHp6PHW|%s4
zn$mwJV(IEZ&=RXyuc4=9pT*7V4uP^#TvDu_!OJeY9BnR<T#GYlRg<UDt<F+4#-Vot
zQH<xZ8YC~bK%RZ}S&f5_L2FrUiK%eAR+g!PEbzRZZ^Zj9$WzQh?U{WZ+)eR#%kf&!
z#NE)uRL08H14BiJkAO5~gwyuy1hgsOn3uz2GHOJH-Cp?=y)Agt!%a7E&T~oxbUZSo
z^<%si9)3JEF>!hG189uCe)B%r4VO$8w5~$LP~LUba;Y9Q1kVo37jSkd0I|;i)etEQ
zVIDM-VM9a;5hRnjOll&DF;?A<X6Z}<ONBMrili{jO4iIr5R)F$Dy`ZB7P@p`!vx*e
zVPPC}L-~#4tyq>rEM2-(F2C$DdFZjnf&5dYB@bF(sF{`)uV!X9pPvGlxVf!B^V)-F
zUVhr?Af&0-%pCww$gmicG6!{psYVyve7<gxS~i97B^O^JKl<@c<cnYYqFi+G#cDzO
zSLYrGUJ#U)Svk-YUUAQ!{YVh|Js<?f!8JS@Nhff}A$iO|O5FW)Z^dSDhh6@jaDv37
zXSrHSKaSprCtkc+-O>@y3#X7}9Yl#kLLN|*j@2GTtiKzzmg8jZtSRU+Q)J0?>Yn$?
zjnAzd6wvYL@$LIvz<p<~7IQD-EyWZq!|huS$c7zzWdE^4k`1~Tg}&n#ES(|c1t`~R
z$b>uDy5=$2a^{d!`QcTwq#nw1R~q;em`o|G>?CAHzjMhHFmHGOlhfod+TNZwf1)Hq
zD0Md0D&2QtzcS&B|I%`1?3rarRt^+Zx`X`2(+(})Yp=Z)b;YkLWN+orp-Kbfqjg9U
zW9D=R3>Dw7g3m{Oa|o{S{opI_eCO5bk<^-MAP5>jNmL<76u$G_vEF^%wer)S{#@?8
z@2@gp;$%&bQW?Y?9+#Zv1ut<QIF3~>tdggnepW6-*=H_tY%D2_lW!23i3IWS2<kAe
ziN|C5w3I`e-yg3MNuLp-8nPxC`3fD~*c0`rH9t}d5SV0{H)E<y8aGCAp!C=xGVEq3
zPXU%?MuE3220(15SU?ActQwFynN_<x3RukNfQftbK)sZdm&l?8v!rrJwq(+}MlD)B
zuw`3e$+2;QRxY!o0Oxl=Shpc2-G*8;UM&@|0`_g?M8O8tq#=d;1XJ&ztA!Sq-<b6D
zs01OLri-~cjqZ2^w8m3N_`E(gKDElPe(kF=eANHS_rL!`xU?G#48d(mA6tsVDR5pM
zT;A`#{{3<RHghwCd>Ro-=ps>gPdtalY}6SRxlYhU#QU;dF(0Tu|ML0I%TIpxbGZuH
zlXQ3S-oB@FL|8jlm1b)qtNrS$uaVQx=as+*$zU+bIFyMv5D;Z1u>!g;0*gm1@o>!J
z5m^jTad9GB$JI$=zK;P8wF!z%L2)?%Sw_hCvBPEbF!Xpuv1+$A+3<wIlZnR0XQ7g$
z`q<#>Z(s&AgWFXfaM7(3x@920wr!`p^x}GaN|#Esn4CH9bSce2!YPhm_oEhcvg$w$
zK9dhMLmD)Yo7y79sh~-?Z<{segqYSiCM8GmAgnW!8a1)35%u^5@bGm5fh-vZG48DR
z(+cK*^C_(GnFbmS1&^^G_S$&`mzHl8DiePFt6$0&zW62iGr&hu;a;YPON||UGJ8=F
zvbz>(o4DLJpqKO9xpR?hi&nA_lq}uU3K6<#14?+1=7Ri>$*q$BAN-Xse+lh#zb$tI
zTbm_bRPw#^R?!Y|K_=E|=_nMFO3>toKJ;OD@Wx0BcvD7BCe3y&^D+a?h&t?@4Dy3`
z$AtMsU)FM80y=D2d$KS97OoHC&v>?$cHojDjFys-FC#_|Rikmz*b!1uQfRzUBZRgJ
zs)y+8xOGv}+g*78yyw&lXdRpv&YA=#TlOB5Tkd#3W=x$dmtMk5W2UvE*%uO>YTN1{
zSX;2U3A>h|jI|T-#%}F=gl&(Fkxn5DE0vB23KVszV^XQDGMS7nY{r?@%2utwv{(L)
z>P5KCS<YnrQxgg1@Fogd)xIo&|1u%$jyrCboBsGmKy6lO?^MF?aYLJcGRs*prTH0m
zZiW_o&t12pJ!HOIaNc>q1FnZqWvrYTmwYle_BfihFR`K(O*jATcibT_Jpa6g1Q-Wm
zlMcGRwDf{h$tyCBM8*Mz(bCc`k39T<j2K=87x4sG^T6>|rG+tiUz2S0q+x;z6H{Nr
z;5UCfA`BB=ywBVKEV82lQHTAJky|7)X3v*#V=JT-*tqbKV1uw#rga`Nd2EV}wxG0<
z#X$ibT!^>zdrJ<q1{ri`GmMrjcR%`~tbJ{xoV|RW%$zb#`A{?SLy*{1*WRF(VLQq=
znenX+SJeFsY<q;zn)n?RSGHvB0v!QI0gh^T^+2x(n{|QTPz8`qz+8eKFsla6KxOjG
zd0~}4d6(ALvPN2I+mzoh{|V9nOR0YHlOHPp(bUP4m0wv$JfmxpHZ!D&aHS9=xPBun
z??2r5d(=Z$L4h5MT59$Oz!*4uf`&M;9?u)*d7L%tXhJ6U?-1+WF2isw?@`dXAwThP
zeSJ*aA7gF6T;6r(9rDqS0(_~o1d2?H-kY`u0ZXFbAU)&X@%Te;g19$h!Ef(GF79{&
z+Mb<w=WOCbg$I1JHC1XF8fC&r<R>heE~6`p;c-!6qyMwM*iH^dgz(9=22P29HWD!h
zZDibdgRqTk+jmIreeg+{KWDZqTQ~&_mgR*_sPk_{Pf=`m)qW8tWdaq5f(Slcbmu7O
zIg{R7K`d}}<KGMjGj4y@Olzz|QK;}c;URH8HP~bv!{h1dZfAEa{m$agns5}->Jn+R
zVL`>?EJ-6%W6M85>qf>dhC=AkqGnPUwMx37Y1Ok1k!~xxV3qzc7n@P%cr*IFPMb1G
zD#}VhOwhoc8_Xc-4A>+*Mo(N+3>bg9`R1E}om&V@?+VrYsd>}wa_G=u-Kz>{f<!Wo
zf$PHFt=qS5mpg%aHWF>&G7vIgJ34j8({9H;4K^L=kH*^{0UVFu`V!z4d#3DVQ+43`
zf<e8s>Ur#?sZu&^tTG%W360%b?Amk^uha6!x3xqXe7L|2M3*}1y?f$?b+Ucue!24E
zvt`@}xP7rV8tdz%4fIGz#}0-5BqAXdd?t_bTqvw?+3}t74%pdgY@VR4D3Mcw`q(rm
zwe6tS_GB6uxQ0q)dcTbKSumRkU&OX&n9X2{&E4BG2{V|WnvGnRN6~?f`6Z)9jX{}H
zxzcogVUfD6X<-xRn(rz6cxMV$()ot<8|C-E{a^Xgm%peqPvNO;CiVY4W6*y3{Qb$(
z?)~dM^1%HMAWM4;=njGj<H<sdo4`o*wRm>oZ-c+_FCBR;6uu1*X6x6lhsAxDeDHnm
zv&?NBBaMzIqFGp}Pb6&PeV>Sj^kr2C`BV6Pkbv0KNIjV3*(mKTD$YRZ>OOh-#dIlH
zFh#NnbfdE!4LB>m;oMTcQ)YAWg!Cy9&>TMp+m4YVY=gz4I|OyhHH~uDqc6zvg|lVW
z#A<zvdRUH4SXiFJI0tcWX$D#CAl))rWTti$t!Hj9!#+ht6^O+WnJoc<E-7YA@;AnO
zOiQIjZKVxnNwf7?&*Y4t`#5YZ2er*$e3kD>6s$#N8N~EibF~u;f##<Ju!Laotbb-5
z@`@EJq;mKOX+Tr+V@Cnl50HD7B&-Hf5Bt7;>XRQ=Y~4tLias-k+fzV$jg^FV=bd)~
zP$5g*OVnU#HIEoI7C;3DbPU88e&(5H;GU_L!-o&TOHrd>`{U5iea)+@<x#}VFTCI!
zfS9SaqPC~~-z@*&W<DMlRXidH3VQ#0Fa~Y+Gc=zl5qnFX<u1T6&x3W+S|g9$`-p6L
zZ8uQV7RZo7pgAd05}_LDAz>n!?LinkN=kz=`fo&zE6|VaUkaxuU)d&WUf(0vUv;(=
z=4K#lhVU7h9(2O8R1X(;O^T~)<o<D-!ZbbSPUcZbQ1ZDGJ7F>Fj#Mul!*RrECh1VY
zjS3;ow)IozUbfxmle84$Ab|z#c?vDq-~Ij%NIV^;$)|@=i(EBqn9P|sU(2AF5Y_@A
zO$B}A$dR)Dz&`Cfl?K?`X=wAf>g83S?MLPO^Uno{2ow>zZ(YJ_n7;+-k_!G2bjkYj
zZFe96bqpGIlql3^I<nSh&6+1KBS~%g^jSzU-6=a*DS|Sq9XofZVUdY3O-5PgiYK2`
z7yE>X<KT3_d}+AO6~4K!UvJiJe+70T-sE@s@mkQfNMsg<8OC)lVh2E!aqivmy8Le2
zW?3+QrYxH`Lwj7a0x1RISn?e12laMq^^M6LX44Op@0=O|?VdB1B_zp;XI=uJM3D+-
zz8dNpwZumW1tamXUESQADaJQURJaFqP;M$b*hYbg3!$Qa_nTRwUR&f987rYC8%Tsw
zB8tXY!`5@6WBoZ^P%^8L8YU6NNPKi>vuvYwQ>`vI!9oadpNBd^qR+4&G;f;*&p;sv
zU^kMs>R6J%>_I9I6f9I&0@|(-d{nWZl}>_W%SmQyD}*P(+*#+07!upnRaC%|h9S^~
z@{CgShvux-)nQB|RfGug;4a>agpw907hbcEWLxS^CF42%e-jZ#Ji-aP+Uywbfr$W~
znv%w{HGn_R9a&zSk3O_J<WNnWeDL}Ur2v_@o&1d}t*0{{t?Hcap21YHSZaKGeo}i^
zEg(&%g16<_=QltBU8uqt0cL4I_J2Es2KT?`Du$sQ&*S2iR4V`U!UdIOmL7SaBN_<7
zY75U({J%Z}xo18}&@k|MEi7fCkR)b8em;Pk5YHt8Oo0KzGR?JUP*DQVA-ZDep(6$Z
z`^d9%RVv0rkP}vk>;za5UE&%tV@-CbA|%M){JkllnXS!|uJZC6b#-gINm$MGFaW6d
zF9E9APT(zYKE{n5kM9ntMb9u~77|^V!b=Pa_MvCVDBbYZ#?~n+2@=No!)p>*%3-TK
z9<K@Vv+(|pT$j5-c`z{{a1?nCKuNMP02d7}$^8#M2~TIYTyXkKXT+E{grSd^EN<mJ
z_8N$gJ~aYbN8~CF`5p^&5W)5%H7#<{g>!V!EzNBjE7eej3MAXi@v?g3O{Ps~V)t)Y
z*!snZCxrQ1UxGS#e)v5#SQh3F??w$IV#0*?y!XC)A++K8!gC!wxL=9^Fu?j~ww<I4
zDG7;L$ta1aL!*${XccM6==3c!v4oSxWEDsF0U_y?7!oG0Q-X4c4X?e9_IV{LOjA(K
zwHq3CI>xbf?Ha9%EG{YrQ!>HE7<CGg#FC*AH8!<Md0B<kLn|nX0hMUhdjQwAH}_Fc
z`|iul)R%k8*3)lk&oF}u0zDRNR1cSZdo3E+7s$~g`_R4Te!2F_^CTOLNiX0m7DGOE
zwT)WpGWdFX&j9I0GgDL{dkOHtqlOm9#NoyI9m{{3Ah42Y{&?=$j|u7Ba}+Cd6VXFo
z%0GwUJ6h3AU4Uwqa=5j3?AU?!hB@j+X7cHs$TulQuE{zGX)5qVD9570!JVE3D>nu7
z&i1ig=%rp(TCUY0^c-qcxAQ=T4G-l!>IP@E2YNaq@sxs=ee26$XlN^3@T6_qwkkT<
zv(G-QV`b@R0~8+CV$(IuL^ARv@~*<d5+te74R0PzDo)<O2z%0c<E{M>+W!3Dzv1_Z
zev1+86s4?{cd|ttCCq?<m!w^L7<5ZnQMRmvM=~GDg$w7QbXBn|$a0KttGKf-1}2%^
zzC1+&+H?ks<=Bv4+q7GXN-Jb|A=B?sg9y!xNm16+A==u|Bih8Ho8V%3ff^R9ePv@0
zL_h~ESYC&pwbbd7OXNwobvAF=BqK(QgyPYp?rq9h?fio0PXpmlBjzg$E@{Suwr|=B
z0xOc!&o~2{xdq?{jFH=7^JH^x$CgF}H#hHpA#ifnZ+K17d`L{x+xG6;ZGw(&f80ME
zZm$<#d>+a}I*2M$K}t4n##o0BlbLXX(}GS%99kDf-FXJ2prHf3OiwGizl4+M{P6ll
z3B|09C<oODv>wi9;e1=;4}>mSk4PcP$~M2gRqlQ0S-Iqb<v@PofmAq*3HNBz8gF9_
ze)qPS0a~?85NpRC+K%4O^O2{ZI15NtYC?%#DjQC~B2uz6bcuwouwag-^oNB`JRa4X
za1PUv=Y{l;U3cAeim$&H$W=q&4P$t$7GNa&Oo2%c9Qn#B7zY%N>FKPG?vRbIZ$kg~
znQ%$Z0fcXp<gk3x$DjkT?=UZ+aHeuV0e$H^-XXvI)vs0H=fFcp1z^k8O?tmWfEiUh
z2b5P4iICPh;f%>gUdO!`ELbSR(BZEGf}Q1?+K<3hh4jY)j+emJ8y`s|@cqKZ2;l@C
zLA|~TXpaX$9_&>MVxK#Ci+N0gpuYFMM<uVMK&FizrhGDyl{^sZnPWO70-D$>W&_gQ
zWR^>PV}}$JmFo9h*hJL8w02J?#e{%wJ`s;%!kQ^R$Hp&XUDxr5DUooFckM*qacsdj
zG&eL+e7^C`Z^~D{`gM5`8JE;7wai^zZMH-_heW4>9qUewb5!+c`N$_e32n1bH*gZ;
zS(@Q#veLI`i^nK<UAnkg%lz5TepY_;qo2sSHLI<iCELG+oVpeRqF7_nNViOyJXNl_
z<{A*7VTyO7_Duo!T{(pHZc!DoR{@=faN-d~m|zke<70L)Zbv<tISC$9m`WWg<?$>z
zxta3POKZW9rpuV2m`gsTr;HGA$=gN}4L(TR8PJdz7Qdzm?q7I!%fLkWVhD&%suaz>
zG+yBWOZuA1ctY3j`|utP(`uMLf;=c5?eIHaLb-U+LhzI?%QwIIuP6^gM*&Pcv%@KP
zznF){$_;Pj>2s)+$^<sFdq8ITk|j&!eMr*MtYqftsMgOW5G>&|dXD$!yYrE+oOABE
zpsfzX!EaQfAq|SX@+2*-GR21FvK^Su6pX7Kv3)`tFI%=82Fu0pa?w-493g80WQkR=
z9?$R``nii2_Ug~PhWSgp&+!z5$Z;GW`#w7>+6)wqnJqQpxkE`R!-zy>Y(NNL#Z#+f
zLiI2pK!VTP6i0;mNim;sxl<ybeI}a;QG0v>1aLw5(jK9FuS60_%ZLa99^(aDkO2IG
z2DR4Uci{zzM+}LCba1ourSS%T=UA9YS&0nl`Sa%^d1AK_f)b3&XJ;}QYbe<OUfm!l
z(Lka5l<8A|t(ynJ>&7BO)6^I_YZlG)BeNm0js7n{RJ?|Fhw<LS&|+@NlqpC)JE|MV
z9DHVpdO4+prB->HLi9~U0!MBh8o8qsf+%90Y;~!GY^XTQrVk3}u$J1}=P(h(Tf^Rn
zCpMT9wWckx#xYj~rYAfp%GvOcZKy-th)!n|&{Qp~Hr{254OETwgB|?$%|8RqWnxg8
z8aq=xPm%hlFguT)@t@eo2`bZJe&9d*Gvaybf_u6*rN1vjfr3&)IiT%{Namb9dyYK(
z$RqkZw3^8`m8K$zW>D^xzqG+MUMw@AsOIF7wo&N<KGP0_Me9k;5SEXJ#}5yB%m(t8
znKNg>LVixO!jmx;tMPD69dZ9Q+&>vc2NS_4h?!|V1GxU_>8Pw>=RPJ<5#3R(XPceg
z6qI;;BOad#u0<k&8&9Bz*D$#Hc0A|Cn1!Me>dP|GJGGRP--Gue>5lmTd-fiYy$6p;
zb$L<1#qBrM$zeLDL_nK<Wg49l0mhn}lPU)xKtxzmXYO08&Gqif*ar$va9AjY7dyP^
zb!uHwRZuevZ;-xX&%q56c5(9_+F1%#^mozXtpRT8PyGE28ZV+SRyb1~12j-*lhiU(
zKwzm@+&W~EKK;z|@|)lMM*jX2A5%b<PCx`&vI)<ls;m1WMnLnPiq#8Y%X<@F`{zIZ
zg~p&ij(cmLSk;obkqq0{D+@Yj5L|U|m91Fuj2u07R4%{#QpB)W2W{;pHIG$2+fG67
z%)k*>Z^V&EF!v>}!-V4-ts8-OM&bpv`<EUU`WTQH)&&KJ-iIAKYNZ);l>vprwjCd&
zcQ>Y^!oh#uCNn_2jm<C$&<8m!wG#+mjc96+r>;wb_EooC+*eSMj3-2c^dAhdB@)K{
z<t<?zLm^2%!EEhse)C)EF8-%~`e$u5sfk{WuTbG8+-56;M+*20U6Kb59+G<iEOO+?
zA-Kq|waN~S{~9=xw!91|`<_qw2~p%Rly9<J>i6hqHF4r3^msl;G5|G7{zYJtHr7?+
zzA4%}naOKbmb44-!FSwoo1B9tJd2ksMxIfl_JgKQp=DmqXb8_&ke7$~dQaZa(+Urt
zAMbO#>-cAmH6WZE^2QD4iq@sZnDGbCCwqjare@2rx;Etd98v)tO+vM>pqG0CC96{+
zpiMcoawyA?6d7AxA#3k{Mru1ILx?!oPu3Oo@&xe+COE0_2qXM^cwu^5%-%HHcpHZV
z$P8_^W@C2a$3FQfxR?N#0u6X1V$l>d%&2C@D6Lx)*oN3uil!AKMvjr6{o<Es1^JL%
zap}cqH|c=wEkI_QI^<&ZF)EIgE^`uNCJ5^CE3T4S)OHd{Y|^BODuf#me@cZW&WvtN
z0RypclQFw{`0#4^1yG9Ctf@x4Y6^%67PML$rWmLgbZggJOsKCl3eJCD+HUmNSZ&tU
z)Ng$5EV}NT5(D8(KnXIh7CbK#-q>}>Tz(-FX`s|Hc>bGz28eHfQDy^lp&WvF)0Q1F
zX$)|a!BmmHsj+94x@z)Lob3^h2gDO7@%Tz_yd}&(;u#b^|AzEN0r;E$`K?-|mtB4Z
zl<6ADMimHYSKZ0j>*)~6hroA|h+{ynBxtuBzYhg0=&yeDEAW9yGJV=)l(E8!bwsU(
zcSt}hb-5&6>u=wJUiG&qmiOtWpCvWO>MkxRQ}7cS1iU{v#3A&YW`Fq>DEO&JJf$MR
zq}99bx=UN&78Mn!C!iDVZZpJ;+sAwM-h}q?D*nA01hK-{#u8jht&;Nlf)=w=D%ATx
zuN?Uf8=)Y{x1&8BNxmo%=F0)&80S2BM!_i&(3Xh|_&hu<fk@~SsVXZ#LR6MKvud4O
zuyC3**E2R^jJAibDP|ElVTtRO!$c9*T7#3{+r~&ln2FBUHNo?-P=CvoEi!q^RMl>|
zfpbAfg#aqy`<(1tjY;o9_nFG7VQS&-+p|miFX!eJq9OVWxR5qT^Eqd0W_1T$+CE9l
z6-6gf99VwArWf-UF4m+w!s`*woSBse&^&$As8LF6&4>+ESC4_RPzTNWu(Uwq<`~D1
zn<$$%ZIP(}O6k@n0k}7TT-5fAb*qQxAw2K>C89863k!JL?Ut-&?xvs$XD$VQjs^?x
zyy}dH2Y|^x8mCrFUFJ6M&%zA~F*f*mo6mqLZ)_Dw2h_|dW99aHpOsxl>Sahlw$wEp
zMqJbyW+Y<N@iL9$?d{%_`Q!a9Y(Z1;CY}OYJDz{R1xPNf)A(*)K@oUHK8%5bQ1FK!
zX{;6vcbbvQGD;eOB|(1E0WTi2x2uK@N2d3B(DoFN0m@Nf1)7kI(zU0>AkSnK3Y%>(
z;Y(XuLO2s(DK)JQ!nYI^DTfhGo2t!4=<cmTE8YDE_G_!#E+9ZwSC0eya3M0jcc6M?
zww9MFKT!oBDh$I)LOf$D(Y*Uj9Q-}rdd4#d60N(<g@pk;uZXz2JuZVcSin>0xl8WO
zb54IfIhyx!5~=Le2xzJx&O>W&VeP?`K4<xC`Td;_%TT1MPe5tXF=&MZB#(W0h8%Ti
znt-;W5-n`J#R@M_BI4_>)|^PdbHs|X%MvA5R<IA7mhK`hax)SNG7<O9&dJt=WKsoF
z@{^JI$X=t}D0FW{hN(f963{<NNOtYmZ0cyHyAhi;*dRg~1U#(snz|Z|VIKowv;Hsx
zrCoUic`C%2K*m3oTCuc?x<DK5&Bg$#Ez-)@MN3?>nP{&264HMCG=}EZ(p>O-j^O&*
z^I8&MR7ktC%o;GCfF|4#+n95mi(1zVme6Qiz(K$UF}Y77;S65t%{c>FvgzWp!(bFl
znKnu8xc@16@1@HmA6Nx75Ol=(Bu#l33ENlRnu_ur{Vwu-Ps{Ik6#g*pigzxL;kZ1E
zFdu`-q!u1!hIPBv7xVYShY#z&bUkNh<!ZwlT5hytlfhqz1Hg8Xig7?RM$)?CX2&lJ
z<9Ix-gC8q-f}}HR8GHp{HS%lnuEXdJ9l19Q5PAstJ^vKV5#c8CGuA*;=9#kJyP?&W
zfbNU8#8dQR`IKKxrzWTu!Blru@YSX53;<^!c*S1x3LU0`o&@+;4GH3H5z65l=Q<?>
zacTrKcqC)0?DK3PP)kv$D9V>BFFFIrTX#v#+!pk4o&u{5?pK0)Fj7J&R6^!a16ITy
z;DW)OKsR|OztcsIwd_vyXHPW#->`7v=Vi;6Yv-3K(`HI3GS!(NaS#?P-OYA9+Oa`E
zvqXZ46WO_0DzFb6u0c)VO1a|7E8!Z)eBnWp@YjXKH;!SODV|q=1j9OLCWk%s)KfAB
z)^I+oVz!oKZ8b4-sfBa?v$Jw!*AA3s;NH1;SwJ2`zv%6IWaDd_<ch0sZzNc8nYd<}
zy{*)woGCKjQ3jUSMHOU1ezyh*FOtcr0+eLIk_K8cMke;1D_YP5FH%N;kd%*_@}U2s
zF+mq#VY@mrGzn<fh!VKB;Zozi;auu<;lnvO`5LE$00%F6GG~Au6U1*d-fUi=GiHyJ
zuGVAnhnsGf%h35PE58)A&`9!8P#Xv@ph2NO2D(sLQ=Md3N5s=^2cfc6B(do=A2CjO
z68CnPHsi&qJq`30lMbFouUsMOo9E1#BY(Z;uX4i;pGIB_YmGbQAV5K~5z;c3cDLk0
z={O36K!Pw8phh_}uRvaS@fF##f4^Mu&UXUqpalu2W+0KzY7{FDUHk7Scv*j4QBj3F
zm8aw?bj2dj5lN9?C5(;l+qYM9Y8ZRo1w=9OjJ$l*PG{!foF`FY3QKy-c(uIK)Bv-w
znvgbSsK1`hzIaOTdLC>gmiO?J^|L0=P<#hPi8H=zgCQR>mZC0f8YfzTM1_XXu7+62
z!`Zr&SnJJbqyfE1hEx?8tAv-r=U(Z7iBlbpYr~%!0qv|JEm7Awu<Xe;Jmu&iMRL~Z
zOXP`XUIx-nhfE$<EqSQZ19S<rzjk$r(A{d2$c5y&6xxOu<`=9#PuZJ0Be;mYT`Q61
z=3~K(G0#EY))_Nq$Xx&tm<K4nECQ5h#<sTtX*CnM$OK+G5?BbB@WfLqv5`k35o00<
z4oXTo)Ae0Kf(kLZA!6e;{=Ot6T8+z=Et6N_%DV5~dm*gR7LG|`yacsnOjjfkkBp08
zHz3qT+<V1S&&wFJYpkjoihDPs4%%YWu7!wh+Awh>vKZnW7hETs!ytj0TRPHd%IO0p
zkPVT^x2WR=vXT<Z$X4P}A~M3FL%tmfMotzw&WtDzEG0`y2v6sTa8OA1hh*Lc$Jjz^
z#e(rvIcw2OX{b3WcRlzBGMwiiRyq_kh|W;pE$yfRU^a3F8e&+Fc!WsUECKYu@JXuT
z_s60YhIvq|5*j;&;ostY_GhS7@0#im$?GCu9ISbDo!oNkEi!HDbd94kdzdj`TD7Dh
zt&CwA5EE{plph8<<Ks_0Ez8e11C4k}72-1sS=H8>k~3l~KgidD32%NZXP<kH+z6=A
zhaP$mp|WbrhhZZLUoNWZHLu4^ZhGZ1WIr;RpTxZvFJ25N(romwK}Rcu6f9ZQ6!ApL
zL2wSjMo^Hyge~phvjml#m^Jb|RE-Y`XfqIOBFJNnw@_Kr93dyK*pEOH3)Q9FCFwXc
z1%^=<gmD`>nvJS1LUL}NlS;gpOG=H@cn+MLPKkgvdn`5qOf57_0(hy+o;(&^pUUOQ
zr`O0M4?ZUqXg4`xWGO(|vjNDSrCKm23}t89<eaI34oENI0*5zQB9}?L4Wd))TtC6h
z5KlYy$MRoaH%OP-XFl`)P}u()`RUJoqIG{-i|ooE_+DGWY4Vr3!&3nsa=}HHLd(4x
zNgROr1W1X3>Vu%nO=s?AZ^ioidI3#sku}(i8Qt)y8?;{Wr$7IxWo?s|GzrFpJjZ8o
zH@cj<F~_-b?)ewXQnZ_7H=i`PZ0MdaS2=|w2jH#T#2R;)(8F^Z`@5$J@3!`qGl_&p
zy6@GkZ46O?ZdgjCzw&(3OpT`4Kn0d_hsDn4&zp)w#Np04Wk4qS@+S|RRtB%|mYIR5
zHs&LrmtSzEtVg@aRWH0E8`i!mqehHE(o==x7Um%X8UhC4rfwqCHA7fqZ*@YbKxAw7
zbFl4dJcYeKyrwTtpKetO1jmP%Us8%b)!+K&*U`%M>+)a!{T~_@^K!)%XIOk!TS-#D
zq)0BB=Dh!dAJQK64X9_PF~F>A1x%vFAIAe3Tvpznu$_}8jgxo3=NkFN&wh!duR9fp
zgzQLpiB@8oOPqA7J*km2HD=5N^r5~2iE8EA_=ieAQO;EODF^ReK=)?Z_a?N%d??7n
zbzWV`l#L-8F16#V&jURr9pHl$%E@%8__n+BJS4G<3}HZaA_GEOJNRT?ex@v4G*=42
zw-eQh1Z?yZrkqnEplviRlZ`^cflKIm;v<v~DFI<zanTalj|7g_P-nOH)s0f$1o$|(
zesfTtn}c4W)g#N%7@HG_xDgs4SgL-k!064wjYkyW^N+U_!r#veXRB)#Z8y1p|33M`
z7e22*_7uoW4x=XQiOz$F5bdWCS<_EHvr-;~hI;;m=K{P1o&#F2Dxi%JEsMLSOFtZw
z{_9`whCBO^oPE|ADzHhA9H&~(_%}5bz$s49kx*-a+56gS>oqPt9W6iGfqX`g5-r70
zz1Uy@!yEm0-BLlqiN1F+wTM>BXSDvd7CWY5f^kF3CDbWLLuaL0(T+Q*%MorSb}=K=
z-jqpW<@D1QN;YDPMikt8#yre}GiW}aFo$>xpXgVe+Xna(GP!z$j0Jk$_Fa3?dUBg=
zeRdC&JaonbQdUt`9(Yoz3?E8d>skmL?0<N*lEJt;U6N2D>n+G<dUJX6xI{`nfAcY5
zquo@+!T$AcevM4-68ZYqzY4Gr2Y>_#$qrGfM=RteUEb*6hrfM@QNQ^7b26m35E<N4
z;htuXYBi4x(aU-9{Fpu1Q!qb=Sl-V(^Rztt@FQrdGe)M*n66<v=EkJJawngltJ^4z
ze3?L04M;#eCOfuok)bfY5JOPfB_E_WL(5JB37+wI3Ab7z9@CqE_KHnV!3px7NMjOj
z1UT7bp1Md-4g43+g0Xf`34tdi6@onl_z=nXw-bD(B?-``9U0)8g|d9<T$ws?wDB8t
zE;xR3lIi6X3TQu4D;d)MtYE%rEcyoHWvrBqLMux0q-q(Oi$gZ7Ub{_RSiM%Z?%oFE
zpAOl*bGV#!+B`UA*e<50!0>lSB&7ZK;p4)BC;T~)l^u3ZaYHcUa_hEja^HRTL(BaE
zgyiXpaZT6v5p<v#f^sSfO2TY1Cd>_3hQ<|y(7XTPN9A*${~Q1TroxL*tOTT+ni-es
z(v2!3u^Y}56@u!oTenW0e(Gtt{(bL<7h;48b!KQ=%&1lcHsjTdYo#HHBMpR~gue$K
zc~~BO_(2&rdIY|s=B_Pyl<4BM!t2dS=xsiuYe42;R;_vmoQKKYsKj-foo;?4n`k_o
z8m$Aa$No=d=tChqVLe03?L>0QD2#vU()pOvTodxn8uxJ^tL)|;Jb9%LCz%EZFLzRB
zAa<Q2-WO~=3TX<K@j!p#-+uH4Soy+>^6KU-vb7#@){azJx@3_|A6EvKFyhqC;`91l
zUjjN2Kk5&E@xt2+Y6{8w?|)P_Y}lwJPot1jTZh<g4Klac@{#C;>Se-znJ|`}ldt&Q
z6cpe2_P4c_>|`{npbNZ>l@1y{idDRW<MN58<Y`Bb9>YCvMGSndoPFlmYB^^@3FrXd
zW}kcS=59uvGZD5lF%7(Y4LlQnL3h1sc(R6}<!vjx0JQK~M{E_NvBpM!=S6u&AW=5V
z@8fwtqx_P0B@f_qIWL{(b2@{Txvle0Wy4esAkGnB#r(G5oYK^lA@D~?X8sVFgv7(y
zC{4{I-U5ZWy7g#?p45%37ds^aI#PZb7_eHJ`kB)}Lh%}hO;IKi4i?O;M&ekt)IvD#
z+;vc%cxaUpO<G2tw06|!bo#|fWch{{E4T@Q=l11t>g{)bP2P(|{r90U#<ka82SKqM
zB?reqRO_`zG@E6xRT~>+%wMnots(z{%{y8qPvUbV%QAF@x#Eh;wU+s#AAUc!k#j4n
zR%h}utaW=AH@_!QJ@Ld7a@JXABeA0j_0GpMHZ^P*+RvfGRu$URwL&lxaKEgy45b(i
zQrl3g+1_WIemX!6_9IE{89Dom)1(E6Vt(CxB8i{xu=d&)ql%|6Su=DJf@$2{>h9-f
z`%|{631j@1+>{7DOfDgU5k7(uG{a(U>qOF5D!PI}i=94tq%532MaH7el?_S_<A|B0
z<_eEejMoNEJ^>A0@y$O2J|q~ls5$D2!c4jBoF!;kx<s04o8`$DHpt%nM`ZT2VTdtu
zdonD={c4J3UpymxOn=S`A7gwnNjpb9`sicwwXb~x!nhKsRR?6%ORpe7Yd=~*<}1wa
z*fC?YS;m78J%n78({Ws>WS}njV;}jbtVUbNhaY}eF1X-)D6`0@R)7<8_{Vz=j-C93
zJnLTMvkXI-*7BvNL--%lDv8OHCd2E8m@*PfsXT1nvRN@8n2>i20-Xsith;7szsDYX
zRNnLM>-1jwe;+Q>8e;Q=g~#A`Q6ga*Z!Z0O2mkfQMZaURC_!476NFHPdgx4TQ)7s~
zsR7CVGB3fvk6M%3wOb-;Ly$X_B}r+SGOV&39>;MqfA&PFEX{ZF*tvz3dGaFUJ+{+M
zhP*x{0@`~Q6OnE-hHe|56Qv0R&Iewci3Es>A}K`xzOXP2n+`$wgQkV~S3H+T@P3JY
z@6D<Xk2id*|J|2C@H6AU1O*v`WG`yA9l*k+py8fmcbV3fcCBOFy=xDiGsWt5`5@3z
z7|S3Y_ahHKgrqS*R;qw<EiqlJB;Ipy6MA5K);Y7^bQ?-AG;WW7>*2y~h6|mgRD=;_
zeRU;-^^wDeWFOmmvhOzH;;d_|t*rqw;ysO!NI<$Of!cFVG(mTmCxHICq!_2_gbC9H
zH<BQsgykdbt*fpfSjk%Y?a|Ycn$<Sw>|pkPjuK8M+}<gO+n1FU%aF<nnScbhX=6r6
zWl0XaGPKU2V5pdPTiVf!S<WYeR1)px!SCPfGob7^3|iwgVC=sP?2nv+EGaKVMs9Z|
z1RxTex-z91AQUNHIGbyx*H_rX7LT8Vy>tE;Pe<e}^o&tJb3YFoIs*I!Xkdu(lD?^2
z=j9eCjqlmBPpwnM=yvFW3~v$2cNl<@4nSD4Nr-wYDLd4SZg-5w+q^Nr7Pb}TLm}Ad
z!?I*KR)*Ao&#@s-HcG1~<noa*o|l`0-|Ezj&Sw}3*x{{Pw(9sYp)622ATv})awrqt
zk0U%My$R#KjDw(j&}UR*hXt(g!xHw)!7XzvDwH)o?gTUeRgfswPIq=Pu*XxfQEiha
zLraFpm=RSnZQKZWUXZr{?0?lfbYJ;9de6<t<u#{9K<miez|~N8AL1fAS%{q_G4z5%
zcId-XSabmTvI_zF?o>d=v57X_o1x9smvt9j&_vo}BJDWdCh~%c=g@sk0r~RFugE(t
zy-JcBo3%`V0`#@lUek<5TCgnsAI=UhERVorFdH)y0Q9R@uaQEugXFUji(B<EZYsvT
zLYjMU<C2hBX2o961T+|pvW7MgDP8HTSLDAt(MX-OiFp7wV0?;1oCX-uRFp{Y_x<}1
zfdN#4en?zqv8yn4E}M8-Zg0dCo~z(zHcjc!n(qw6%@D`JJ<?D*!VGd^2wQR`v-c5)
zPk}Fiu!c$KqLWgn9+blDOc^n>NXCsUk`a|TGJ0egh$lz)3bkPC8iv0fd+g*AOdmXY
z@aH$>47e~#aBScwrtuS_o@@||8Z^RO4EFaS7QMz#nUCR^abFg6JYJNDCSquVJC|76
zpgkXlwgx)g^6IOv%9U4LC5H|k0gaDQ+N8q2Y}s;Tc&~;f-Hezo5x$Nnf>;JxKe8lx
zJxVCYjva$u#&%8X4`A@a@pziQH^;#on!OP2X;2iBaD8^LqQ%ZcG1fq{4JCOGc?c8A
zi2c9}?;N<<kDzpvRyGX)tIei?K<k`JbW|}&q}V6&I>Z}uP!@!hqv%?pJ}5a`S`ju&
z2hWAgf^c7p;yy$yd9|jw1}Lm!vS4bFWTq7&Nv}+*QMx&*DoaLJ79p{47^V=4lH!|E
zZUux~M8=(50yuR7I))hd!Q2WxUzEr`c1RY>2XB`=B#9-1nb!jEG&7spqn#N~1MTfQ
zf4_K^vwdeodOU*LZzBH7*zWn~ohLs79`>&Qoq5qk7fDfZKD6*$8IJ@D3euwD>5;K3
zu|OKpdj9z@evTUEXXL6Yuh1T@neY_YIG9ZhW<iZNFt*_H^WGG=OOUO3+ikZi%Fwv+
z<JB9{)YM=aGqc5^akKPl3tD0Fw~WkmjY<9WulGp{Y9uF3nhvX*j7WVvs^yvoBpOcW
zi}8e+O_0d^Z&W^*Xh8<SgqGpMN6L6K>}YANg$8~UiE40V!(wiw7XUpYS!bCCi@69H
z=fx=5C@(G4#KO|DT+FQrW|Qg$jG*_?|N2mht-MbgJGo>tc(u3I3`CsUk$s}x78eGw
zUps*QS0I~!fJJ4N`=8#ONXe{v`9d_|LQqjY66H@pz7ym<dJQ9rh!q>=U!-fgnlHHU
zd~~V%0WyYjW$xVh=zk6xD4C;{AZ6mRrAxGCn*xw@#Vqb4HMR1SAOB2yI8U2351zSp
zK_a)&fk!3`@KH~n6wJIYv&R=LS_By2U&~WZu7H8DM6<Lld6n^I<6rC-edH+HPQsEd
z%*PE<WbL{Q^6Yajz^#4(xH!C^^z>l@I}xT*qbo39VV>g05#%L(8CSt`;tPC+&%jeq
z%iNWoC!@h{%2DQ9hmyPIhI%bi?Na1MxW2(BQ;@Hd1w)`DFIURIV}_IzB0Nc+QwV`=
zJVtA})d=vOIVab8h&C@<2A2DBiUf2}V~q|l=p<4ZfIo_32IYNQO8W+}5NJE>%(81o
zJz(pG;ybue0xptx3)z>&7heO`D}@AfETO6ECj`6cOAIKWskwgO10Rq--F&P3@sEGd
zW*O?nc5Wq(TkD`bQDRfKz!jdFmMvFa`A)cv%9Q{NK+IY^SkeI#EZn_0SI(mL2_1|t
zGY-W#_Jc?`d;Ez<m0-AecrRbp#mo5+2^3pc>S(B5S}EsW{0;>zu`XIX%E}N_o9?CS
zO<&4Pcx`y`E@Z`abhp9fg{V$mnM|ENNfs`djRZB6bu>316oB7Qk-^&36c9`*GO{x=
zlA)=y=>dRVps}aGs@9iU`j#N0lT4F`bM1)4d@_l9v^q)~{O50E2E5`Hd|cf<+&a!S
zAk|e?lmgFvgVY|Yhj%L-jJ?r>sE2xV7w93Vxg~oMK0Sm{q8KdcgtUk2(K20vgtcS{
z#BYE5Ulpy3rG-{cZ0@ckB)n-UBKZR872dM?W^~p={P^-~t^=$oEMQi0P^hQ{O<vN|
z81dcleCcLsX{o&DJ=bZX*mKXVgtCyMWur{)rLu2hB&d?b%L#D|*$yM4OHM~p*@%&&
z@xIyWuh|8P!rft?_vWe8@lnwT&X0Oi<6HglgnW=sbBv6=Cxh>d99}BR=1r3cqbs#n
z0tGai91%^CsA~)dvNoQbxUw>mU@Rr;XKz$m9|bZNO?xvNCPY7;$DT~GIz<B7G0uLB
z)GQn)L6pP7)r({x%9)X)%jLyaUX$4iM#H_5g+wtFMw{GIfk~!MC`-#uw5(^=v_)!Q
zy@l*z5zfbA+AHJ1YBaKVo!X(*2%EcIO-Wq{-7x%?jo|UdYMhyg?m9o=8bl@<JGxr_
z?!$kFq^&3A5Zpj|wkwxXnWDni6c=n~)O;7ptl4wnelCC|+W?@AOdSWULfv?Nld90P
ztY_sFPV3i9Z+y|*-Xs&okA(%DFE72a2APvYV1vMNF@2NiRx3;|a9d{!6rUmh;m_0z
z^mc4g!mZjpy@a#ON4sZqJT`xf7vn-MUQ7+uqSic43n_FtS(2e(5o9Fz>%e5U;rbb{
zipP%~C6gwMlp%S52jnHQ;r4bLUN@wn7P`c1yPm`Lv8}?NqQM{iF8GQF?jFAke(|?G
z10gfVu^!#)*i}V&DTu44A^~bIT0D+JVj{||NH=t8s=|wX?C3#_3wpz#9C{0yI0g~k
z6EQ!GW}Jx8-&wY!S<T9`jNOygDCoHF+ac6=LMN(0SfNl{S|U$8`5c5VI=89Q9oa0r
zAbF8qTk)|#7^yN9*x0kdSCo_qU_y_QQ`YIekLRxUd%_FGR+MIq8aYg^yY^~%{P8E@
z#e||lGm5!25lxuMR=6H&9#e3iTx5CAoG}|YHPzaC8?423$Ri&#Oo(U=HXkqeKl`j6
zL!DSow^t<Gj4IEzmGb|iazZOzo9j}!QC-TaP&mvcgv{Wem#UI{nKhwG#t$z+sEn2{
z{_<QL+3|d3D)Fpf<=N%}H}<H2%+53Cxltmj>T$v2Ccjf8pyLlL{H@!Xs=??>53qO;
zH{9eYmGbiXR}rUuUFJ+cSp>Ao4hjZricW2lWmh!InwljwN^W`zSpE?E$91z*`{23G
z^wJFgLG7~eRIc$}cw?iZtA-^%a0RKB$Md*3OsF!cBM<T5OW$#sCRenn>x9Y%hojV}
zLegTq$f`trT`Lm2x*;%gbBM_e7q8QDwIWTQi`$VK+jfs_TAL^je9t3!?*ahSpLNFB
zn!G^^*{pEGsn**o0q|e;l5UkYB(!y+uc?8QIL4wtCZ^z+i(QB9p4F~rV=+SV31voD
z=9;&Or@~}8)kc&=kxP+`95e@+JV}-<S|DRl<L=T8bQOKCaGmOyU1@9Vag+5!Tw)3r
zQVpCq^j?FnxBLvm-3gvIK*<M1t4o&qal!nF^1uVn$Y@juWaJk~BVxPh5PU`tn%b?3
zt`UdsTqhJfeR>*obYs-w=$79_EnuZH1;ijdThfvyFYye8<`m%R*UNBJWnBN>2?$LY
zNQP!1tKxuoISyj=hbAWDJ*~nv2uK<@si=$rz=Dpz^SpSVD?SO-ylz%<S<i$pWQDUj
zrKQby5cvxKEJwwz$udahfH0f8t+g5VMn^p>$xx6f<6~xqS&|t4obc7(_?+f7<dh~;
zv3I;ukJV$8o0;<OEfw-oH552~_=SmZd`|Km;+Dh6W9+#Q8Srywjh6)gGAe@GTAxvQ
zh+`tIe|Y>&j$_>B@pu=}<KlE;jM-=>hyR=+0X+bk)(K>s19iT5#`Dfvh#2dAu(rCj
zyx?eKy%GxrX)<D#Y0L^H#;k4>F0xtE@ep%@I$J6>ZknRQP?%9WR60>NtZpkdp1?xG
zyQ;<N6gC7{X;TFNE?5vpn$`|8>yKqX7&ENdHV8d!oS~xCP`qq|nI&p293$#X#965|
zGp0j`Po*(c6r50Zo7;A$2|CL>q@~I^@WLOiB!cRrRLY?0?4C;O)YjqRqEf(Nbg@hc
zuXJ_W8Nn#AInRR!6X;YTq9tw_=}K~XKl3;++tHqh$shh$YO<UR&L}eP@xC2yw-&^J
zm<TrupeXa_&XBRAs^G3R<)^3CI)J@1c<SH`9M23mLBdVQw^UQd!WFt}VzoT<;1hE0
z1*fCD23_J1doiFK8UO~mkwX4MUPYx^tv6zKlka$=ArP8!0>+2RNFCj%Jg^c%GYXQ4
zVg-Igd=ysVGS=CFjPh<ICAA^^lhguh9z#gOy{L3EX%_fkS_-5c=#)sQD0jd$OC~{U
z()bR&j2@`S6n)k59Zj2{jdk1eT$D5-FQ%otUafXj+1+)NLq&uw^GYm(o389kD*Wmp
zaGp2iT_(^CLf;H14nb#14IPgfXnY9fivkttF!feuv2gC~Tsz;)0mja$gfLMQToJB#
z)+~3W6(Ff}ge;jp5v99h5k@SI?u=f%Z^yHJ{x6Pwa|mcN%IrVbg(L=UQCgqF;GUQ=
zZKB+_@-?~e{G}Qj=w<=D_8+IK86`OQ<Hk%vDY>qxE`Sq^whJPkyIG4%?aTG{^rBSj
zb2~G!i5Tm|7U^!r^_q~;2O)zJhgK*8M7T<$mDtI?%>>lveu29L*Gr+2pj*bYP$Ot+
z=W4qeA(~x_bI?SC8Oyq9DManh#_a#R>x+WS+}ZZK7nFA0=sA4Pdsu>txuMM!?VH%A
zsCI5BV<afLp^exSHQl+dOe-aUnzw;P{yc~Os-BDYzR88*eygCyF??FSG+cmBt>~B9
z-jyQ-WkY4!lrd=kH%dm2s6;j;l_;Ah^J$rO<aFCXnf-r3`G4#8pn~e?(Id}M;BuEQ
zTrfqpY}+C)zqB40`(x485e*@LQJez2?(R<CJi&#=&~Srv$E<I4g*y6GIxw40X~v`t
zzqFDgZNdN=>qgBj>4!ZB1m7{{%>Q+?qdx(g2tkNzkV|EhS*s?s4DHI^Q;3m%7*;aH
z-0n%%L<O2*K%Qc`DdE4kTY+xrh(I<kp+aV|B+`A)?^0;RW88c^HIS$@c<+LqV@84+
z2jmaRXz1p5!A<?0k6}s%c}P1DyVTkyN7BdhUOmS@ogbVHl{)C%P#9A*umDeO>dr#!
zJzK^OtCaau(d&M4HNc{Z)i6?a^A-}$T$eY8fR5}C6Rc__a&r<S0N<RxXofUFNdEP~
z=VkG<@lu84vF?sKEgfL}E8X4DpRkOu4mIlU2tzkz)KWBIWTJ@2YmC_0y0i$*V}%8W
zW{{eU;&jQDJx6P$5$9ADWlBajV&EwK;uShIuHs!a7H5GpS8b2?R5(f!jXn|w!q^2%
z$=rt34Xp>MSW_Xc!;2NtHe?@z_Ch+Uo$B!@O)_hm!rb+B=5wJ$jVifW?NnwgK4Y3Z
z&*RXXm9GS3u!brjb)11XkaNYUhe8>E0m)OF*Ah9LmJDXnM%NOG`&(eC=M@&oc;Fq+
zm@r;r&clb6AUm6ikd<CI=^mFq41PH{1E+EZtSJmB(p=0W21Sm-Ul#W0J1;v=ZoB(2
zS^0D$6w8s4ipl~eK5@@>LV2f!$4zgT`BY}3UMRB(OaU<AV}eCv!Jx%dy|p!_i74DD
z;7BODtZP8K*rUjj&M1(=d{#EpXmx|eyS+-GbPi#TYe1YCJuBp<34c}SmF7(;(8MzL
z+3N{Ct>)<QrobB>gOmPd<vS!l>o!P%3Z;cfV6=Jh9j$rtMSx`LJkeFncsmsd8qw{v
z_SJFbuC2nCb3|T*cN%Vkm!i|EcD(AY!rdQZ>W%$RlY-ziguzqanI+xnD2+nN>%@^m
zWah+C$aNWxtoI@}2ezA{b7G#3H~Z^NCZKgYDUlekfF)6onP0SEvQ#3*`@*VCvJ>SH
z<B^S*oxxtG^;jg}UDFK%cM!EwTHh>?*Z7VKNN3q9L2&cheRN|O<zNG`{+0v>LP^V&
z`r2;Ux$PKHz@<I4Sq|;q3-=e2406-q%BB@<f{;VBh^-}L*tLC{5<W8)?FiIVObSkO
zjeDEXyKI84C)+sQwct0Cb4f>bm9w%{W2Lr=asm~;IF2qeH!@~_GDKrqy1N#q7T;+-
zAU8W*cYXt_r41&e?r%P)OJ)hUn1pTl)HQD|?smH3;C<*wK|9ObVi{2}6fmO0WJ>iA
z88>{0Cb4+}QQ;i0oZsw3GC01s;|v(>sDO5ofINrZGtx}~+Ol5zuJh!fhhLOOS8PU2
z@ldHmYr&3ARFeP(QoU7bsFLa}6r@7MRX?ck*LbZ}6sUmIZSSpNdYKIVHYpW61?TVH
zTO$V#H{z%a#G30Q`&fsJ99kghnQ-GGw#+*vGkiy@75vHsDPeI*{`jm(W`-%@W6nx*
z7NCv@+%TVsb#F(H(;mnXDao6dcTJ5D%SwZB#My#7UaL^}Jg%aGiVXWE^DvB=Frg6;
zCg;6~cm-XSybsB#r_Xu!bd@wNO}9A(z8MfyjM_2x?OpI{08gQ)v;qi<;5Va(g6C8L
zYP3wT%e^AjTT<zpd3V3z0$Mk%mqogpEOp;rqyWpF=1!S6WrPd|+}iJNc}R8wn0?a3
z;ZlxTwX8I3i`E7liTE$d5jv1ek&F@q?aqWnRZEqmpaO>rOuT0kOd8w8{ZdkiSj7Y?
z0fu&yy#D$w0AUo!?5PvcimpXAYzNltmZLJPqD-oabKs`M`G|cejpAB_-cZFt1)r5F
zc_JYbh-`Fa2o`s?m)BC=yBG`FG`{GcY5o4?Eo03}B-kb5=jsW-vv;9}yb}<0?My7e
zL#3oaGet=g#3*vYqA@9rqp8yElo!39sT?{+y0NH%tHtaHR+SEml~M4sLs?4-LIZh2
zq@<`!CX6bRNh8sr40AOS7{c17jw`9Og|*cLzu=<3nMq`DY;VsQFeN%-rbYInMO;bI
z87L{b<h=Rv*s7f<VO$|&jt-SEqbnporvNkqs}V_2>caIcP}Q+yu4eKv@8Gsj94&5o
z)bJ~KM+ZDzsi_6ZD;k^F<f2}-Z9gPqCxFLQ7o+(^EgE|4lvg&lN%gQ|DMo#6GVlv%
zt<o4EZEB7S=uX2$CJHSuOP)y~<`Qe7!a7LfLB0}eJ$nIe*1hoqeJW43EW+j;!S~?1
z1J6ZSsRjqYW5E#GwQVi=IQRzmG3Ox}JSUYPO=^IV1v+=TE&=|hLYRDpiVOR6^INAB
z@E+>IXR;pd3j+yL0bZLc=_uJO0iT&MafFPj$U!+(C18y!ZCPnR(6jj#e!bxWx`(47
zBCVr>$mqx{--_Z4`Q+bSATO@nBCo!_Up8&-lJep#z_DdW0gC67nYrjPye+HP;PJE^
zi^5+w2(!Qe@Q(NeElAeIHPo~L%bK7WbxHtZM-M?_K@I@X56kHCk+OWrOxX&2@F!Qj
zCNFI{gp9xx8H%xFLF1;&N;4c?as%&gt|r~#N|?TVSx~_G_u4&5w{+~Uwv#yzQNbLo
z6Li`?PO_|Wdv1*sgZLZKHjl8H85#MC&eniZuI{cTJP-PA)3Km8Q%Z3H*%%GKquaVY
zDceE-6!;*xPM7py?sjf^CWm0$={b^HR4UZ~XBl2ufQ-{psY1KC3P1v~=-*UsD-DUh
zV%IjDfBhDwr@^7Wg=QeJlT(3aRUpvvTRL~ROd5Zgta|<xS^LTc)a7T&5THyI0iYv0
zn?eKDEBF9AU}+VEBIY?4tRpibYbo3<u1EX36<TfW!A3cJpjDbtPL-YAA@k;p1ip2K
z<fL_=1aqpKbJ}V0><jB<-J0!kxU~jAC8^*$@Dge)oZ&xM6Up#&vE3wbq#1ToVP_DX
zL3)d@68B|KZ(Z!dS#~+;lzr7rVJDV8lUf;L=Ji<<or-7eMB|!PBxW@L9Hk3<m1t(I
z=)~30f>yS0!>4MNH%CTSJ%zY4!Z1WNqWGOA*wG_L*SQIAy3HAiY{xy?)peexF7%AT
zTtGmVpkr65j2#NJuc~6HEGIN{F3`_R$m5PWAF#1iVez#%Z=vm}Lw&;qbY#LD&$cAU
z5b3Bip;pK(iA+Ic1}~d2UKZkS>sAWsUGn;-oyfNAkbK~z<^YS9O)S{%QTvz%;xVja
zW(&wx5K=AR>l%S`+lI}=M24KK6u`OVgAgEeh$w^l!*ZnQ=j7z+FvnMy%V_+q#XVPn
zP&e#2C<O?6SAb};G&vfYq-vZ#sfr$D6M9T!(DzD06mq6Xs<Q2@WIq>C;?X0Wd(7fh
z(fKkLom#%IP}}J4LL3HN=zwn4ij4P6^kpps$V&xcStWQ*bO+meNDdx7EVcD@=t@Hu
zb|lTr6d-kHu(lKB8X9A>dTOumq#`!Q7;<Jt8tO%J0C8Ffz>_i{?i9;#B=ZdgfP4-n
zA{7vUs-Gxx;@Vlm_ULwt&l=wvQK7dQi4Tr9-V8YV*?!WHi+@9Jl%*@`pVDlnROV;N
zC1)>{ntFKGz;Cwh*e$yN-^;jbPJRLSMHWJC0JlJ8Mk)js@vjXv5IhT5_iZ4|7Ic4V
zLW1itbk1r6id8BgZ3}<}Fluy>6zAtjKCV$#QUb$(xf&ctlAO12nk<?zSzbh`>DrC2
z%ie8`Qd|g^ZUN;cpefZWMGMyAw3c|uP@7rQ#!I|{AGMVIZ$UvF!-q79%N<YtL=K^R
z4Br#1gfV9r0xg}n(%cFK94_wiqFfn)<SZ)ZX@D<d`^lYX@^Ki=G#Z<l4Y`Zsg0iCX
zqNP#B2h|(EaT3r(V_<w1;*2Lt20)7n!B+}^&RA5G59O#BC1B-J3b%G;5lX2t&8@Cp
z3&(d-waSE+eAqa6Yth3SETEl)(&Y%gOd!X8YqhmnV@vl9{+9;LYXV$O{A+<Fykl>z
ztXa23HUX@?4sF>;7-{Kn4N-H|zNBnZ2>VzutAQ8;fQ-uWGPtdWAv+w+El{3NhywPZ
z6+^K2r9hW~1*nEFsel3y<cJM46Ze~rzwP@Q<gX8`kd^B;$&k__sVpvnCJYT1%^+Cc
z%nio+W-B>h2Bg~68WYkQJ|hA5?0jbDf)5auk6(L-nYsU+yV+f<9fZ;VEw%~Joml`3
z7&~zSP?4Bqk^#)>Ds)~c#~IK<F@(c)t?1Zu5P$pS2r#>A0fOHE4Za0UHktvfuL2*t
zJPX!1LHN_5;1Jf23QG<cNFL@VAMv@o+$;#_0x*<fDa^@IC%b<!?(UhK`uyqU!W{aN
zL!Yf3Uh(L94~puy78`jhj@Ah+bxB9WF&;!SNo*@B{bK*BBMx*5nkYoC`uVda$ZY)8
zHMPm6t$StltD9sUTFz1k5iyH+_jL6dW<Qi&2qwNK_I^HKBr8gbr6`|Wq0j~<qeIHj
z6liG0aL{X!30MrR3)X0IstL$^7!GGFoFwz+O_G<^?2?Bbc}%wNr~!_CIp{J+`=F;G
z3`a#;%PcWgjUT(xtEiARx{4oz4$v<JJs(;_T_!})SXbw%lNK}L-mM6oHKIpwEBIV7
zo@e~Xp)v#wM~0RGvl<{LS>O+RHNahP5Xfx1_a2mkz!PU{%zAXyYk`r(CO!OXSIh`1
z7Eo{iWW<hqGy?K+GN8D?T2`YgRf-{?%h1rI1o<qP0CuuPvN%7VN!N|vD7)sfQgAad
zE!KbcR@$v^uz(IQ;vPIX_6sfm1+0;hX@$Dc^e{j|!jC&)L@~h4i>0<{Is|l+96nMH
z_feA)4uv&00IlgX9GeRbFB_Uy2B0Lf@Ry&L2fz@<mI3z$Em*HhLeT^=I*uXYpgF3F
zrjC~+8C{VpAH427*|L9uyt;OW9NP7|95{r|GuXrgoTmk!hBjsJu;Y4k6T`eE>>ZOG
zG_dY2XZopG%lMvgVZASZCxVA&PQ$%}doxMB0~@-v6}|*EV5i$2kbb$a@~c4@Ln}*R
z^+RwLmq}Ssq2%D%Y~Mnmfx2B;1f`^CxXc(=1%ccKB5Q?U#~%oWL_;71K71;(Dftd=
zEp`*j%7UQI<X;A!3k^5Oh^XbO!axPY6enE`9W&pldqCq&z2X7HP>gcMw-OBvj`b}$
z1Kv3B`z;Ww^c&gz+eN&0XD|4lcyv*Ax-6JFN@h+%uVx4xD!)gL)`OlJk?{@e1SVi&
zD_cK!D7z3oIXEXTy<M^)#PjnDB^#bTe(&4wT7oRN3ri7MouQVX)mP`@rpsr+-9GwC
zlz|<T^&2-MsqBz86(SsN4ix1~@GtTkvM|qU6a-0YiFs|KOE1vOJg}r(WqB&-7*}TO
znB<GBl{Plo=>$*;YoQs=L%j?jf~yewtr(IAeCs@^piu(@r4W2H9Rk+MN(Fp2S#l8@
z9yMeXg!%}~OB=ihO_-x*<u@%b3e^2hZv)0id;}WA?C6yRg@#5!7KAaq66`C$CPQwZ
zxH@sMIZsfCm`9{VTE@RDFURFCy@lDyn?OL@?Dd>Ouhkm$6ZbWG9N$yZ?fIgoxeS&u
z|HhzYW%y;TAiH0mLW9O1jx^u^FMVu-`&SMu@#)C!=3hhGRM~~LlH1_=-nFMz4nT8k
zMduVkgQlh;R-N7jOWoSr`8q)L{8H0)acgScss&?^giL9pPzGTTh=hMkmPiE=W@P6{
zF|yhV;byLY20pAb2kxIj1=c5`S<KuxB_=rTRBZG-z^CSc0Hh?&ME3hDV{obf2hVYq
zKEDjFQ(}6FUGshqVer7g89444P>@;2Q$jm3^pW`W%6k%Q+zcqBWd(WqCjdI}uZRku
zdMY!-<DgH)j60ejYquhMHe|(!_X*cwBZsn?)v^$OM~>CXrd|8x^}Y47cQ@S02-$T4
zDKHJze+I)*5cFwq6SIa}jT)`9wj>lApJC)HxCj(~y5{M6Zh^3DcLJHBF9Vs<d4+J}
zL%}G9E4vD{#Y50Uq5!V>0(8q`cdHokcle9`J2vAWHg^^jlcIb!yBXk18IFN2k%d~w
zf(zv;cl_nw!ou0_fC0|bTkCYLR}8GA8@_k@#4lv;pNPqY);DQPwf;3h)2wZ1f<=7{
zP0SC<p56Q9C|a={t7(x&v|9vv9+JE0j&j1yX^@)Ds0d~xtW52xnh7m5A4zEi`DibR
zq?DYTbZDyuaI2T#y8>vM&^B>z0^0ZfIu*P1R9y3|wWkJ0`&ONSQ@eK~>ZZOqk$d$#
zC&H&V<+x@Eg3<h2I33v2@P^gZHzIs>M7Bd%?>$r_hmX}s0~%<wLmF#4WTrnWJgJE^
z4WX&x04pCBYC1xK8L0TkLkVkHX*zgK0fa9@TDi#0DUu4fu!|w6A^X*{76C$b2{KXs
zc_Pny9Q#NwAMYNg_`b(6#FKI88*D+Jj7J#QHPqFkLUMo$OLf$|QCeyYnJN{CGx2ZA
zn4!SkMvRxP<i>V6THhka8tOD*q#1bJ?Bh(2H{DI<%3*gEXsvKFQSfG?^=1xYI!u70
zn>h_Jr*!<D4p%e5T+C%<rBcD?81OR<Y-$J39-M){$r%X7cuzJB(h}8VE-#))`1Cu2
z=VT*Sgnt#VZl_EhhbBI)QV*AMU1J*((;9%;&#rMu)&ei0S59AGJZUV!WDPi6(`hLg
zFbFab_f3_8+-&VPPd-DB8#{dA(8#NsWu5d!(j`Ao{`oh#Q~G{r70_S*`qu|2o%+7f
t;1Po}FgOE)GcY&<gEKHV1O1<Y{~y=BtPj307Q+Al002ovPDHLkV1kAq&`kgU

diff --git a/doc/guides/xen/img/grant_refs.png b/doc/guides/xen/img/grant_refs.png
deleted file mode 100644
index baa34e1e3f5e8975ae0516a09f906933b1ac688d..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 6405
zcmaJ_byyV6(?41|1SFL1Q0Z=I5F`%p0BHnHK)O4nl<rR94!DC;Jfx5AK9KH`mWChS
zKi+@eoo8ofX6M;`=GocZXFjpIZ&is2=m-D+0I|B-8$AF36Z9y5euDMLr{L+5j{}Cg
zo~k0Id|M#uakgAn%Ru?j_}Ca38EI%}FfcI4$;t8Y@t-_-LPSJFN=o|t`Ex2NDiRVB
zOiWBVIyy>9N_u*FT3T8L1_o?wY%(%33JMA-DXG`5UkeHf%E`%badEM*u&}bSGBGhp
zN=kBbbMx`>ad2>miHWhXv5AU`%E-v@@bE}TNN8wiC@U+!d-qODOUu;MR837yMMXtb
zRn^?w+{DC0Q&Ur4U;q94_XY+AdU|?>hKAbO+Q!Dl>gwudW@bi4Mjt+WP*6|+fk3*t
zx^LdRvA4Ikwzjsgu&}eU`}FCPpPwHX3=Rwobai$0_Vx}63UYRK4h{~sw6yf}^mK4=
z`26{EKtO<#lar&Pqpz>;$B!SatgKvIT)e!z+}zxJe0<#9-TnRjJv=;YZEbCAY!VX_
zlai7mA|fIqBQrBIv$M0ava<5>@{*I2^Yil)5)#tW(^FGZzkdCil9Cb=6O)mV5gQwu
zlamu39v%`B5*-~~P*4yW8X6ZDmz$d#A0Pka%a?E8zNMw5MMXu0g@rXWHC0wtLZQ%-
zl9KP=zatQcqN1XfmX^Z8!m_e5I2>MDTH4UiP+nf%+}!;0=T9UO+1S_!gTa3P{#{#J
zTTxL_UteEWS65tI41qvuYHC_rTYvocQB_s->({U9>gt7s1r!Q3Iy&0h+uPRGHZU+S
zJw4sm*Vo<MJv21b+1WWUG11Y{vADR{)6+9GH8nXoIX5>qJUl!&I5<8&J~A>gKR-V<
zHikx{XJ%%WmX_Mv+q=5D{`~nfJ3HIo-+z01dwP1hv$Jz^b8~lhcYl9>d3pKw@89L+
z<>TYy>+9>))z#hI-NVDffB*iSpP#R+tel;lZEbBG92{(HY+PJiY;SMx@9&?SoUE;_
zU0q#mZf>rxuOA&9?d|P7JUo=dS_M3&DTasMTYZ51=B(YLg72zk;tl|ibp6*c(s)Ve
zAC0sg%Eli0E_NQ?mTtBHZ3k;N7xzbvNypC4!P++XK;$z3K-I1OM!~>m?jY|<iN(RM
z2Pv9k<COx2N!Y>AY&lvmw1l6Rzo3-R;{h+!NCnQy1n&P?keLt)-6U&j$Cda*{zlh;
z>{YXlJb5$eks=0_t^(?&@`0_egc{C*lPc;M7z|kSTfC_H@m+TExY_0RAv+nBmThaQ
zTWQe4?bv|6dC<o8#-S?Dkz=Rt+=q;pMT2c=r2=6XPc41lPK*s4%s#;>9pVB#(}(>j
z$<UEb)RkX!J3CP~jljGFrb6O|(y_4fid<%X%(_XmnpiwggKltIhSHsuI#aQ132k{R
z9Zd4`EdU!rz69PhAeA!N*0zcA6AfZZ@Q}uwb{B_Hwm*pwV>eK>NW$nZoYGU{mJ7rM
zQW$!cGLAfg7$K>9^DM!hDO|f&#A%|;8Bz6(x{9RKuT9M+&E2Ex%X)fG-)r=_iCE(Q
zw;7iaX?RoHuOOv^SMcci4Lkd@Y^ZFLtl?WPMYNl!`|PQXo{O7_*mWVeDV;0#K6F4w
zu%c0mv!A-3`Ux%%kEf5BSWzTrP87`6C1ZeR0(buEuD|~^;#OjuC*X=~%7R@?9(~eK
z>O_fcEi%Ky?NtOW0^`tTo8bOtrUu>;>LS{v0OG&tZq4(rHiz%%5z?Zh+mVuUtsKKI
z!zSSEE*D}y9)o+92a%(o3ztW0WJ0n_GG4v0ak|{zfOCN=JIeSZZijpz56c(tcURm7
zMkEr$v0Jy7w<aMOT6nQ2QWC<3yRgrhOhuos2)}=ur$zelk(pzJJQMuqx%IbwBt95B
z#2+tKF2LvLR1|Q#&2&s&+9rn~Pmpw>y}IU^3L)gVG0-J(?PMWqzPCnChPH)&7@iCc
z3jE8o0b{()y*oVontKzQ(21$v_;7+7J-LZ3gG?Mw(?wWKg=K3!$8O(YO}N9E_|`uJ
zvrjZ-2!IL4yh%tr{ZaAgk<uE%e5}&oJkG)LY=Huz+~DbMV)z)<Gm}6qVBRa3Z@8?V
z>CW_-b-d;kk(XHiG|rSFxyheh$(O2@J;w|@!aXKpl65R=zQ2Tv!R-d}9lFEM3(9`+
zeIb>yJh~*B76zht`lnIJu|uOZ%6&piiPyPe{Mqrz*1(?S{EWoM932xWh%OVGFWHzY
z*H-biE%Pb1HGy{P690qO+v_4ICQ9SqIYfO+S|IJoK~Sr3JXOe)i-vhFilh&7eF#gb
zXJgFo4D&LU*My}8r9#|msw}^K?84%8B4sSsVRXO+w%~|ljqkoeOBQ59ElP>o29aED
zou2e$koG}|m@O)uLU5iOijsS&u=@yXuNIx>X_mz<fgGCQ0;%>1C_ZiM8Fe$ArHH#2
zr@QoBK-*~0_fI!{lPYLuh%0MzH39Q7ouQJE(ds~#$AxSq$~l2~E$ptT++RO+yxhPx
zD@?=e9yeIStl*Ao-{ZQa*wlC%SQ(6>WhJt8`oLaOvClKb$(`ZSDMxt4H7M-6_^OOL
ze-IC@7BalKRlQilxH9#slMnXR;LG1dpK86%sh_%t;bNZZjc{+5+mn2X^>*2?oc-qs
z`;9${s7exNoeOhljg0pBj_rolC%HkEA-%qz#mhSbF5lH!O6NaufnJwFt}mzUlLpqa
zA}D5UF(W-?!h)%6mt#GCej8>mYl^*LJ~$ZR*#W(dYe>)7RWDfSqkTAaM4RlcN5UF|
zW!nj=IZY>W+>M292}inXYO!4Yx-gAf_AmuZXc9^x%8R^v&3`IWZvq2T7Cwn)t9%%=
z_AUbFar0ODuHOB9Re$~&T@+QEvqvaUJFbx+vCR-RhK@(&rrnQlf!eKs-8}K|<6+iB
zWbH>@vEeZ5otiH%QX%j{1%i^7f78=u!^&62sd_+e6=5hjth<6&;-J$h8b{1SLDFX&
zb<R>_l-?$)QdxFt|I+sfhk)`OT(3EGgHl^^dv_}wVx`YLk4@M$Ed=*4;blESj(=js
zUE@Tb)?ly~>5tfua8}*OeK0_zS39s-hsi`=;ft|6>!aY6D`VFOrHBH91<>!SDEd{O
zdg|%r`zWs`#QJTs5(rOlf%=M>Wh<n|{%-$OjH3wkcVI+T36Gr)mlJWGhpAT*b^{M!
z6=rXobefeysV?h@V+qhfC!9|BQpZ#Hih0fbDK#m(D66<rGroEYTznlpfDbA<gz-6m
z=4+*nJstCdj+_!&(fs8D+4BXgkOB}U;_upt2cAXK^;AKi`8*YW$_({X()E48QUttZ
z3}QWm6?Aws0QgE!{Wp#aB=C_<8K6qa&~o=OAs~REd%n)JY;_#9{xM6om3E4ho7fv~
z_*yXd1v^&O?ezv;LC5!-DgE8BVA<LJcg$OH;kng<SXR(KnCst_9Td@FwG=O`pqoNp
ztJ9lt1dK3n-KJQw+Vsi)dy4;GnijHfqE$ykk-Im>!aV<>PXZ%M8!z8?nSQb@2FuV_
zE%ilguf1Z5jb>ET7Aq`&<)TQDB#XYeU+!njlD)>>U9G-RO`V&Nsoa@^3|3zxHP|c$
z0r)-W6L+rtt1PSiT#1v_?v(8K{7?assv7}yX|GJ8wvWZxnDyngO;pqrGjP?n5BCFg
zLW@T9M7xB~Fea7p$&+b(utlmezhal$qIbl{VOkT46e3oYv87RLupK-(G5JH!k1Z_Z
zZ1v|mZhRfN<JIV`_3TV6?byPbxB56DV?`-=luA8X`S?ym(C|cC_;7f3gN7Q*Ej98z
zfjZfHRug$ykL)fIiOE#w2sV|%+8$_>NHJ)fDYmI5^B?t#-yGc?z}Y)$;$Mdb=ekev
z=Wq&DFx6)}0R2%dKHF4^+R8Y(`yC`c=Im?=&y#F0(9~*H#uy@H3R0s#lvHc~;A8bZ
zd4cq%dN#4Bc=%)0YM|yE8s0Ek7XV>xPpaQhLTK^dE%<{Q8^f31tg#rwgBN!lX@y7j
zVN*2HwfrW)_Wiq4p!-O(MBM=J-L@yBjoP^3(WmYV2k3<!PsG&}8Og&0rO?^CvbOVQ
zuy+C7K}WfbJMXiU(2@!W4ZQeJmRd`k6yDBo;XNA!V})pggiy3X8nj42cirWD(ZQir
zHtBF_61u$G-DBj&fL9x92ANP^Sku(`4l@44QU^!*FIa#H$aobR$0vp7evV6fJJsyR
zsbf?gzFyd!o@<LX)#W|dCCw%R>Gb1(;6!y0R6woN$Olz3aZ7~w@FIi8d;6Y$2P)9t
zS@e}T&9dW_E)TE_WIW8%t)HFj<BkVQl55Y;Ds1Hi(=xS6rf--DFDwK?lQxo{NFVdV
zITzaZ*@0wgrpX@%K%|?Wk4g#XvML4}yvqNL=803O^rCcc-DGEj%=os}V_*cI8^voF
z_c}IYIcDO<H5n*F5@t{YiHTj7ZZ+A@;ccDV?8%-iir!gtHL~vz*l|htXYU1C%~h<M
zy3v0WWubrph*}TT;}=orc%&E$tq+?TaNgbkkK!FgQu;QjOuyoFpIY&aEMsMl2ST$1
z_9-t$`>&D-3?(wgh=FT@yat^VFhj|?XnqQ$-axE|nVG^nLc-_1XUYt=ks2_b$%xvh
zH_%CnFE70#GE-21grt^H!DrkatiiTK)*a&FWwyUoz3hH`Yw4LTZ?ptk7C_F&n5zQ|
z_?Kosb`D~IHtVAVZe&68#6rXfEQBIQk1XgfZY}rO{XY_kBSW)1#G<_8WD7<jJS#aY
zj3O<{Vz{@C5j7n(+U3GMVsdLy1q_8zwZbB`0`6-nezr@`7$f-^3P<e*5m}xt(C#eG
zuC-H688ntqj^Qq`T}}v6!Z8O8PNi*6+*>{Sru@ThK+ep*e$4d3EuHQbv{|l4FYXrp
zy-o|V?o2G6Te3$pgS9X`IK4_HzJ-?{)@8ajX``(a-sIr{{P-XkJWp*5rg`;Yfwfm|
zR>Y?*-M7YN6h1Pom=siV6T<IQu-NdqEj`F$q+wv%cvRT)QEuRjSRm0JVIirV<%kv)
z<0}kJGThIc`Msw!uvi{jGJA5Ta_V%Qm!$Q82;#@F<qfK0gM97rdvAZSGJn|=2}$q#
zp{f1}_~hH4?#1w~ctAwvmzaZSom6v%N;zReAypDQ9y5D!=5VUK{X1$Wp4u%YTN@>n
zF!5`NF)Yd4x6uRSw~FX5A6AYbM>KDY19<sxzY)GjV3x)ur@kggQm8B{s)gvsD@0&W
zQimHq-tM<=%bJiMJpH3n@B@(|E{9Zw`!Y|-B?-EY7DGtT$ciF%ib+fVoxesX-EH?A
zToDtmwHMGY3u!gqia4++flac>IH`)H&aZ^~ae0c4F62wV`M;N;4lboj3LjI4hT|Mu
zR`A{-mYvplC3bd7D3_Z!Ckq#^V*D!U3yyfRyrF;*8R9bYRuTcTn{17hiUpjO3-Qce
zA9|~z#rxKUKW!HR?X^8FirN>!jMo8Jm)?3ugcrDz9;YwaK3@UZ2+#Xv)K*t+bSL~j
zC{TQ8!BekWBnWi7$Mo65SI)lYo-8_|a^&-4{G<~BiRE8Qsa^7y*$@PjHsaX60M8rh
zJQM~QEGgU`^>4kxkl%n-)gI`YSu1_o5&M805@u1{M^N98B^k~b?t&FuB|A6ykK@S5
zS6gAiI8&Weefx&RWL4<=5c+)=*>>t(Yg#gOMnvo(a(*GNRp<G>(<J{BLRvEq<>0}P
z1cHzf7xknE49G5(v5uFeFSAO+&tg`gB)_bBRg;ACo5OR_<PJlc20?v7XdB`o4CjBq
zcc?$BS!@O28-uXMO-AmLQE>yao7pieSDhqYWj-(SbxTAuMf%xn{YT27o@pkX6TTn8
zRTa5iOjO3e<Y#q4z0=)}`pR@Nah#C7Bw_RIKR!h<?ZZ-bZ7MTAGcy8jx8EG#yyHnO
zc!<A<_>IgSpddS;58wjD_KOH)8}(A!k@qKT#^~QUCuPKngAeMlLZP;BuCdLm`K~uI
zR<L5WS#BxZ7wN3&4R1LY>W1tiAqi<fGdf~bUVZNuLhA+dk44GlE*I9Is2Xi@CDwsN
z<(P|aURpOBT54KSG<uN#ALkT~;1${p;z`YmN}}Dl8UpnYFVU>>#6c3T0~Yu?*4t@*
zAr-N<GGTZr_Nx4elLW3lW;)~X44IQ)iRJ`D2fpWUMCH6UxLYKgXkcYVxnRRVoxQ8`
zi-vbQeZD`jTsD!^u6&CE6-G4os55)#@=#y@v|ez1YI<mz(_FE(8QiXt)GdwJ{$E{@
za5~9ip)cV&mCt!@8DE$>M~0YAU+3}Z&E`8qOWDRdNPMs5u`U1Dniw<G_|}R(*FC;7
z2Ib*n0aSDj1(~(_kZ373`D-4V%+4jI*&9cfS~-ms>OFC_@`XA`N%Av8Y4%O&oAI9j
zJrofPUdocCN4%fdW%o{%x`I<6D$Ew8&-P?S?C#V%(m}Opqwu<YKTW`JNuqx<K_^os
z*wy<zC&-wgvpELiJ>SoUGS1_GDCo|npnz(r5H$b(SAhhGq_r$!ghG#JFN(urK^E!n
zNkh%NgnRSZzbTT#G2YgXO3IU~T>GOD#}(zqDHc08RM%YC_1AeoI{1L-dm1Kgtl5;1
z6i#gfk{^$^YiquIxz?sSy^JOXVqTU_BUV~2+=M3RgA1~-3skcIp5MxaTwz$_M21p5
zBN}PTr?Nr@XYjgfd5dwds6O2@wf3_cBzHD5JLzn^S=t}8Ji(4Us1Wi;JHR*Q!2Q4{
zK5U5o1_HU5=7m(HHGxxlE2L9CSI20Mb<4Btwl3M~qUu6&Y2NG$V8w)Ss#VHO>5Ru0
z@Ta7N-j77t#?$)=w(w0{PZ|buDtG^VKMYmcku#nzK69U?Z|{Y$jMSvG&#m$cr(KKT
zG`R#I{XH4FFJwv@ujq0T9ELlZT6p-9ifPYL&HbVrwc=3qOi6;(xh|YrfKPXW1@N?<
zuN>jO5)W&XoMu6Ntsnf7e@-K2IZU~(Q9~P($LlJUp}HSi3z84njB{7wt`JVaht2I9
ze!*_IzE6p%&wmagyq_kJq-9Me@$Qj^oR}I>@%I`AJaDz9>LaM^%U%dXF*40j$c2+p
zu*@-3TPFAIuViuC+~s3~{;3C=(c!W(t&>1|7I&<na1F|JN3NFB=mq&6o1Ueog)CzC
zLkw-4=-Wtv1F_cnWUX?b2lFMKLMH!@89kMr6Seb%g=6U`@Lsi=^mn_#XIr~l8piu?
z%v<(~*<i=ow`_-P4BFL!S8NR0&O}TTY7sObecr(D!sI4}l|rAosqTs0l!@JJ6Iwl;
z3zH4$)okdeU&k(Z(WJ=8lPcwhQoke(pCMvj#7+W$pc3w?>{OkFKw+^i{3xkjs<_fI
z&e2`u*vk$CA18vHKr;-<g4`X1H&*xMKc|Z`n3c@Z)pW1|57nM+)+rO^!{!>E)+XUs
zza1p2`bDv7)tIY5gZb1TcLlFfBW?uGv`DVnaLCT$(i8DhiSig`>rGm<LCG9mOLsB1
z27L$<iS8h;(!$SoIST;p*n}a+ou6wc6~eVvd@T0=EaQa54K-p$8H<WP8$rpEAU3hO
z{V@LtRCyT}^im$5PLDGgT?NL<T#{({MD+=4u8I}R%UvqqVB&S6?vlJm$U)3kS|Wpd
z+09&Jdnp89#B(uvg)J|8Xl}=fx|82iN$pY@k*zgagEVeSHql_WoDO9+7FkR{s{&Jq
z_=WV*%)}NE^ecjnU78wM>dpX05?}B<wQ(Xy#0|o@P0#zrqxW5Ep(y5u`&x`vAzmWy
z=~mmt&iUHkWd~8WAXlu!>Y)eh`))!NG$xWTv05jX>r8cM-9u$SK-~wQsneujKsGW}
zRKCm9m*wZ&69&Gm8s#YMvL&1#VcY?uuaIh5*R#GQ%(jQ17;DSdil$v!MvU#B&yPt%
zxALv9e_9I#<`MKvWwc)H1e?XB@2rT3L!qWm>x=Dv1<Sop<jY>p^IoYroa-biO}!Se
zf-<~NRZ0hR_6INmT2e3vW~MYVplwp^O{xUN<}O0uI#X>@-eO$fVcWsBAiW5Qeu?~k
zKT`_xrpCMQ%xbh$OcP8wk9)vmo<xWzXk)yLa{Xn$;wvjC?5mSMmmbUJcgiM`a*g%H
ziw{GJgNB!6v9a7ZCWzbK`o{1~UQahznabc4i5vLp9pWVb<UGXmgwDWextwQi3h*Dk
z$ANIh7zszTVl^z+hCCu^Tp%@==bFEX#mrJ`-R|{{Tx!W9BFEg9E;Z>fNfuC?m2j;`
z@>os+wZJH*RQ~^?(%D~0xncrtF08R%tEa@>lolNuW19LIRh<dH&6^Nftvh-?jF&yr
zBbyj`$-23Vx*&5u-#vU}b51c$*9+A#O@4>UU8ZLDv~I%9uJ}~nQ^p^#!dqTLO)74#
R9${aAy7JpMP(_Qd{{c{~dJX^p

diff --git a/doc/guides/xen/img/grant_table.png b/doc/guides/xen/img/grant_table.png
deleted file mode 100644
index c23e5fa73e660c5be9c7cd01f55ff34e2917632b..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001

literal 96762
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
Z{{xM~vTICa&vpO+002ovPDHLkV1nHvhjah{

diff --git a/doc/guides/xen/index.rst b/doc/guides/xen/index.rst
deleted file mode 100644
index cb43cd2..0000000
--- a/doc/guides/xen/index.rst
+++ /dev/null
@@ -1,38 +0,0 @@
-..  BSD LICENSE
-    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    * Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
-    * Neither the name of Intel Corporation nor the names of its
-    contributors may be used to endorse or promote products derived
-    from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-Xen Guide
-=========
-
-.. toctree::
-    :maxdepth: 2
-    :numbered:
-
-    pkt_switch
diff --git a/doc/guides/xen/pkt_switch.rst b/doc/guides/xen/pkt_switch.rst
deleted file mode 100644
index 717a04b..0000000
--- a/doc/guides/xen/pkt_switch.rst
+++ /dev/null
@@ -1,470 +0,0 @@
-..  BSD LICENSE
-    Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-    All rights reserved.
-
-    Redistribution and use in source and binary forms, with or without
-    modification, are permitted provided that the following conditions
-    are met:
-
-    * Redistributions of source code must retain the above copyright
-    notice, this list of conditions and the following disclaimer.
-    * Redistributions in binary form must reproduce the above copyright
-    notice, this list of conditions and the following disclaimer in
-    the documentation and/or other materials provided with the
-    distribution.
-    * Neither the name of Intel Corporation nor the names of its
-    contributors may be used to endorse or promote products derived
-    from this software without specific prior written permission.
-
-    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-DPDK Xen Based Packet-Switching Solution
-========================================
-
-Introduction
-------------
-
-DPDK provides a para-virtualization packet switching solution, based on the Xen hypervisor's Grant Table, Note 1,
-which provides simple and fast packet switching capability between guest domains and host domain based on MAC address or VLAN tag.
-
-This solution is comprised of two components;
-a Poll Mode Driver (PMD) as the front end in the guest domain and a switching back end in the host domain.
-XenStore is used to exchange configure information between the PMD front end and switching back end,
-including grant reference IDs for shared Virtio RX/TX rings,
-MAC address, device state, and so on. XenStore is an information storage space shared between domains,
-see further information on XenStore below.
-
-The front end PMD can be found in the DPDK directory lib/ librte_pmd_xenvirt and back end example in examples/vhost_xen.
-
-The PMD front end and switching back end use shared Virtio RX/TX rings as para- virtualized interface.
-The Virtio ring is created by the front end, and Grant table references for the ring are passed to host.
-The switching back end maps those grant table references and creates shared rings in a mapped address space.
-
-The following diagram describes the functionality of the DPDK Xen Packet- Switching Solution.
-
-
-.. _figure_dpdk_xen_pkt_switch:
-
-.. figure:: img/dpdk_xen_pkt_switch.*
-
-   Functionality of the DPDK Xen Packet Switching Solution.
-
-
-Note 1 The Xen hypervisor uses a mechanism called a Grant Table to share memory between domains
-(`http://wiki.xen.org/wiki/Grant Table <http://wiki.xen.org/wiki/Grant%20Table>`_).
-
-A diagram of the design is shown below, where "gva" is the Guest Virtual Address,
-which is the data pointer of the mbuf, and "hva" is the Host Virtual Address:
-
-
-.. _figure_grant_table:
-
-.. figure:: img/grant_table.*
-
-   DPDK Xen Layout
-
-
-In this design, a Virtio ring is used as a para-virtualized interface for better performance over a Xen private ring
-when packet switching to and from a VM.
-The additional performance is gained by avoiding a system call and memory map in each memory copy with a XEN private ring.
-
-Device Creation
----------------
-
-Poll Mode Driver Front End
-~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-*   Mbuf pool allocation:
-
-    To use a Xen switching solution, the DPDK application should use rte_mempool_gntalloc_create()
-    to reserve mbuf pools during initialization.
-    rte_mempool_gntalloc_create() creates a mempool with objects from memory allocated and managed via gntalloc/gntdev.
-
-    The DPDK now supports construction of mempools from allocated virtual memory through the rte_mempool_xmem_create() API.
-
-    This front end constructs mempools based on memory allocated through the xen_gntalloc driver.
-    rte_mempool_gntalloc_create() allocates Grant pages, maps them to continuous virtual address space,
-    and calls rte_mempool_xmem_create() to build mempools.
-    The Grant IDs for all Grant pages are passed to the host through XenStore.
-
-*   Virtio Ring Creation:
-
-    The Virtio queue size is defined as 256 by default in the VQ_DESC_NUM macro.
-    Using the queue setup function,
-    Grant pages are allocated based on ring size and are mapped to continuous virtual address space to form the Virtio ring.
-    Normally, one ring is comprised of several pages.
-    Their Grant IDs are passed to the host through XenStore.
-
-    There is no requirement that this memory be physically continuous.
-
-*   Interrupt and Kick:
-
-    There are no interrupts in DPDK Xen Switching as both front and back ends work in polling mode.
-    There is no requirement for notification.
-
-*   Feature Negotiation:
-
-    Currently, feature negotiation through XenStore is not supported.
-
-*   Packet Reception & Transmission:
-
-    With mempools and Virtio rings created, the front end can operate Virtio devices,
-    as it does in Virtio PMD for KVM Virtio devices with the exception that the host
-    does not require notifications or deal with interrupts.
-
-XenStore is a database that stores guest and host information in the form of (key, value) pairs.
-The following is an example of the information generated during the startup of the front end PMD in a guest VM (domain ID 1):
-
-.. code-block:: console
-
-        xenstore -ls /local/domain/1/control/dpdk
-        0_mempool_gref="3042,3043,3044,3045"
-        0_mempool_va="0x7fcbc6881000"
-        0_tx_vring_gref="3049"
-        0_rx_vring_gref="3053"
-        0_ether_addr="4e:0b:d0:4e:aa:f1"
-        0_vring_flag="3054"
-        ...
-
-Multiple mempools and multiple Virtios may exist in the guest domain, the first number is the index, starting from zero.
-
-The idx#_mempool_va stores the guest virtual address for mempool idx#.
-
-The idx#_ether_adder stores the MAC address of the guest Virtio device.
-
-For idx#_rx_ring_gref, idx#_tx_ring_gref, and idx#_mempool_gref, the value is a list of Grant references.
-Take idx#_mempool_gref node for example, the host maps those Grant references to a continuous virtual address space.
-The real Grant reference information is stored in this virtual address space,
-where (gref, pfn) pairs follow each other with -1 as the terminator.
-
-
-.. _figure_grant_refs:
-
-.. figure:: img/grant_refs.*
-
-   Mapping Grant references to a continuous virtual address space
-
-
-After all gref# IDs are retrieved, the host maps them to a continuous virtual address space.
-With the guest mempool virtual address, the host establishes 1:1 address mapping.
-With multiple guest mempools, the host establishes multiple address translation regions.
-
-Switching Back End
-~~~~~~~~~~~~~~~~~~
-
-The switching back end monitors changes in XenStore.
-When the back end detects that a new Virtio device has been created in a guest domain, it will:
-
-#.  Retrieve Grant and configuration information from XenStore.
-
-#.  Map and create a Virtio ring.
-
-#.  Map mempools in the host and establish address translation between the guest address and host address.
-
-#.  Select a free VMDQ pool, set its affinity with the Virtio device, and set the MAC/ VLAN filter.
-
-Packet Reception
-~~~~~~~~~~~~~~~~
-
-When packets arrive from an external network, the MAC?VLAN filter classifies packets into queues in one VMDQ pool.
-As each pool is bonded to a Virtio device in some guest domain, the switching back end will:
-
-#.  Fetch an available entry from the Virtio RX ring.
-
-#.  Get gva, and translate it to hva.
-
-#.  Copy the contents of the packet to the memory buffer pointed to by gva.
-
-The DPDK application in the guest domain, based on the PMD front end,
-is polling the shared Virtio RX ring for available packets and receives them on arrival.
-
-Packet Transmission
-~~~~~~~~~~~~~~~~~~~
-
-When a Virtio device in one guest domain is to transmit a packet,
-it puts the virtual address of the packet's data area into the shared Virtio TX ring.
-
-The packet switching back end is continuously polling the Virtio TX ring.
-When new packets are available for transmission from a guest, it will:
-
-#.  Fetch an available entry from the Virtio TX ring.
-
-#.  Get gva, and translate it to hva.
-
-#.  Copy the packet from hva to the host mbuf's data area.
-
-#.  Compare the destination MAC address with all the MAC addresses of the Virtio devices it manages.
-    If a match exists, it directly copies the packet to the matched VIrtio RX ring.
-    Otherwise, it sends the packet out through hardware.
-
-.. note::
-
-    The packet switching back end is for demonstration purposes only.
-    The user could implement their switching logic based on this example.
-    In this example, only one physical port on the host is supported.
-    Multiple segments are not supported. The biggest mbuf supported is 4KB.
-    When the back end is restarted, all front ends must also be restarted.
-
-Running the Application
------------------------
-
-The following describes the steps required to run the application.
-
-Validated Environment
-~~~~~~~~~~~~~~~~~~~~~
-
-Host:
-
-    Xen-hypervisor: 4.2.2
-
-    Distribution: Fedora release 18
-
-    Kernel: 3.10.0
-
-    Xen development package (including Xen, Xen-libs, xen-devel): 4.2.3
-
-Guest:
-
-    Distribution: Fedora 16 and 18
-
-    Kernel: 3.6.11
-
-Xen Host Prerequisites
-~~~~~~~~~~~~~~~~~~~~~~
-
-Note that the following commands might not be the same on different Linux* distributions.
-
-*   Install xen-devel package:
-
-    .. code-block:: console
-
-        yum install xen-devel.x86_64
-
-*   Start xend if not already started:
-
-    .. code-block:: console
-
-        /etc/init.d/xend start
-
-*   Mount xenfs if not already mounted:
-
-    .. code-block:: console
-
-        mount -t xenfs none /proc/xen
-
-*   Enlarge the limit for xen_gntdev driver:
-
-    .. code-block:: console
-
-        modprobe -r xen_gntdev
-        modprobe xen_gntdev limit=1000000
-
-.. note::
-
-    The default limit for earlier versions of the xen_gntdev driver is 1024.
-    That is insufficient to support the mapping of multiple Virtio devices into multiple VMs,
-    so it is necessary to enlarge the limit by reloading this module.
-    The default limit of recent versions of xen_gntdev is 1048576.
-    The rough calculation of this limit is:
-
-        limit=nb_mbuf# * VM#.
-
-        In DPDK examples, nb_mbuf# is normally 8192.
-
-Building and Running the Switching Backend
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#.  Edit config/common_linuxapp, and change the default configuration value for the following two items:
-
-    .. code-block:: console
-
-        CONFIG_RTE_LIBRTE_XEN_DOM0=y
-        CONFIG RTE_LIBRTE_PMD_XENVIRT=n
-
-#.  Build the target:
-
-    .. code-block:: console
-
-        make install T=x86_64-native-linuxapp-gcc
-
-#.  Ensure that RTE_SDK and RTE_TARGET are correctly set. Build the switching example:
-
-    .. code-block:: console
-
-        make -C examples/vhost_xen/
-
-#.  Load the Xen DPDK memory management module and preallocate memory:
-
-    .. code-block:: console
-
-        insmod ./x86_64-native-linuxapp-gcc/build/lib/librte_eal/linuxapp/xen_dom0/rte_dom0_mm.ko
-        echo 2048> /sys/kernel/mm/dom0-mm/memsize-mB/memsize
-
-    .. note::
-
-        On Xen Dom0, there is no hugepage support.
-        Under Xen Dom0, the DPDK uses a special memory management kernel module
-        to allocate chunks of physically continuous memory.
-        Refer to the *DPDK Getting Started Guide* for more information on memory management in the DPDK.
-        In the above command, 4 GB memory is reserved (2048 of 2 MB pages) for DPDK.
-
-#.  Load uio_pci_generic and bind one Intel NIC controller to it:
-
-    .. code-block:: console
-
-        modprobe uio_pci_generic
-        python usertools/dpdk-devbind.py -b uio_pci_generic 0000:09:00:00.0
-
-    In this case, 0000:09:00.0 is the PCI address for the NIC controller.
-
-#.  Run the switching back end example:
-
-    .. code-block:: console
-
-        examples/vhost_xen/build/vhost-switch -l 0-3 -n 3 --xen-dom0 -- -p1
-
-.. note::
-
-    The -xen-dom0 option instructs the DPDK to use the Xen kernel module to allocate memory.
-
-Other Parameters:
-
-*   -vm2vm
-
-    The vm2vm parameter enables/disables packet switching in software.
-    Disabling vm2vm implies that on a VM packet transmission will always go to the Ethernet port
-    and will not be switched to another VM
-
-*   -Stats
-
-    The Stats parameter controls the printing of Virtio-net device statistics.
-    The parameter specifies the interval (in seconds) at which to print statistics,
-    an interval of 0 seconds will disable printing statistics.
-
-Xen PMD Frontend Prerequisites
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#.  Install xen-devel package for accessing XenStore:
-
-    .. code-block:: console
-
-        yum install xen-devel.x86_64
-
-#.  Mount xenfs, if it is not already mounted:
-
-    .. code-block:: console
-
-        mount -t xenfs none /proc/xen
-
-#.  Enlarge the default limit for xen_gntalloc driver:
-
-    .. code-block:: console
-
-        modprobe -r xen_gntalloc
-        modprobe xen_gntalloc limit=6000
-
-.. note::
-
-    Before the Linux kernel version 3.8-rc5, Jan 15th 2013,
-    a critical defect occurs when a guest is heavily allocating Grant pages.
-    The Grant driver allocates fewer pages than expected which causes kernel memory corruption.
-    This happens, for example, when a guest uses the v1 format of a Grant table entry and allocates
-    more than 8192 Grant pages (this number might be different on different hypervisor versions).
-    To work around this issue, set the limit for gntalloc driver to 6000.
-    (The kernel normally allocates hundreds of Grant pages with one Xen front end per virtualized device).
-    If the kernel allocates a lot of Grant pages, for example, if the user uses multiple net front devices,
-    it is best to upgrade the Grant alloc driver.
-    This defect has been fixed in kernel version 3.8-rc5 and later.
-
-Building and Running the Front End
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-#.  Edit config/common_linuxapp, and change the default configuration value:
-
-    .. code-block:: console
-
-        CONFIG_RTE_LIBRTE_XEN_DOM0=n
-        CONFIG_RTE_LIBRTE_PMD_XENVIRT=y
-
-#.  Build the package:
-
-    .. code-block:: console
-
-        make install T=x86_64-native-linuxapp-gcc
-
-#.  Enable hugepages. Refer to the  *DPDK Getting Started Guide* for instructions on
-    how to use hugepages in the DPDK.
-
-#.  Run TestPMD. Refer to *DPDK TestPMD Application User Guide* for detailed parameter usage.
-
-    .. code-block:: console
-
-        ./x86_64-native-linuxapp-gcc/app/testpmd -l 0-3 -n 4 --vdev="net_xenvirt0,mac=00:00:00:00:00:11"
-        testpmd>set fwd mac
-        testpmd>start
-
-    As an example to run two TestPMD instances over 2 Xen Virtio devices:
-
-    .. code-block:: console
-
-        --vdev="net_xenvirt0,mac=00:00:00:00:00:11" --vdev="net_xenvirt1;mac=00:00:00:00:00:22"
-
-
-Usage Examples: Injecting a Packet Stream Using a Packet Generator
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
-Loopback Mode
-^^^^^^^^^^^^^
-
-Run TestPMD in a guest VM:
-
-.. code-block:: console
-
-    ./x86_64-native-linuxapp-gcc/app/testpmd -l 0-3 -n 4 --vdev="net_xenvirt0,mac=00:00:00:00:00:11" -- -i --eth-peer=0,00:00:00:00:00:22
-    testpmd> set fwd mac
-    testpmd> start
-
-Example output of the vhost_switch would be:
-
-.. code-block:: console
-
-    DATA:(0) MAC_ADDRESS 00:00:00:00:00:11 and VLAN_TAG 1000 registered.
-
-The above message indicates that device 0 has been registered with MAC address 00:00:00:00:00:11 and VLAN tag 1000.
-Any packets received on the NIC with these values is placed on the device's receive queue.
-
-Configure a packet stream in the packet generator, set the destination MAC address to 00:00:00:00:00:11, and VLAN to 1000,
-the guest Virtio receives these packets and sends them out with destination MAC address 00:00:00:00:00:22.
-
-Inter-VM Mode
-^^^^^^^^^^^^^
-
-Run TestPMD in guest VM1:
-
-.. code-block:: console
-
-    ./x86_64-native-linuxapp-gcc/app/testpmd -l 0-3 -n 4 --vdev="net_xenvirt0,mac=00:00:00:00:00:11" -- -i --eth-peer=0,00:00:00:00:00:22 -- -i
-
-Run TestPMD in guest VM2:
-
-.. code-block:: console
-
-    ./x86_64-native-linuxapp-gcc/app/testpmd -l 0-3 -n 4 --vdev="net_xenvirt0,mac=00:00:00:00:00:22" -- -i --eth-peer=0,00:00:00:00:00:33
-
-Configure a packet stream in the packet generator, and set the destination MAC address to 00:00:00:00:00:11 and VLAN to 1000.
-The packets received in Virtio in guest VM1 will be forwarded to Virtio in guest VM2 and
-then sent out through hardware with destination MAC address 00:00:00:00:00:33.
-
-The packet flow is:
-
-packet generator->Virtio in guest VM1->switching backend->Virtio in guest VM2->switching backend->wire
diff --git a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h b/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
deleted file mode 100644
index 99a3343..0000000
--- a/lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- *   This file is provided under a dual BSD/LGPLv2 license.  When using or
- *   redistributing this file, you may do so under either license.
- *
- *   GNU LESSER GENERAL PUBLIC LICENSE
- *
- *   Copyright(c) 2007-2014 Intel Corporation. All rights reserved.
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of version 2.1 of the GNU Lesser General Public License
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful, but
- *   WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *   Lesser General Public License for more details.
- *
- *   You should have received a copy of the GNU Lesser General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *   Contact Information:
- *   Intel Corporation
- *
- *
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in
- *     the documentation and/or other materials provided with the
- *     distribution.
- *   * Neither the name of Intel Corporation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _RTE_DOM0_COMMON_H_
-#define _RTE_DOM0_COMMON_H_
-
-#ifdef __KERNEL__
-#include <linux/if.h>
-#endif
-
-#define DOM0_NAME_MAX   256
-#define DOM0_MM_DEV   "/dev/dom0_mm"
-
-#define DOM0_CONTIG_NUM_ORDER       9       /**< 2M order */
-#define DOM0_NUM_MEMSEG             512     /**< Maximum nb. of memory segment. */
-#define DOM0_MEMBLOCK_SIZE          0x200000 /**< Maximum nb. of memory block(2M). */
-#define DOM0_CONFIG_MEMSIZE         4096     /**< Maximum config memory size(4G). */
-#define DOM0_NUM_MEMBLOCK (DOM0_CONFIG_MEMSIZE / 2) /**< Maximum nb. of 2M memory block. */
-
-#define RTE_DOM0_IOCTL_PREPARE_MEMSEG    _IOWR(0, 1 , struct memory_info)
-#define RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG  _IOWR(0, 2 , char *)
-#define RTE_DOM0_IOCTL_GET_NUM_MEMSEG    _IOWR(0, 3, int)
-#define RTE_DOM0_IOCTL_GET_MEMSEG_INFO   _IOWR(0, 4, void *)
-
-/**
- * A structure used to store memory information.
- */
-struct memory_info {
-	char name[DOM0_NAME_MAX];
-	uint64_t size;
-};
-
-/**
- * A structure used to store memory segment information.
- */
-struct memseg_info {
-	uint32_t idx;
-	uint64_t pfn;
-	uint64_t size;
-	uint64_t mfn[DOM0_NUM_MEMBLOCK];
-};
-
-/**
- * A structure used to store memory block information.
- */
-struct memblock_info {
-	uint8_t  exchange_flag;
-	uint64_t vir_addr;
-	uint64_t pfn;
-	uint64_t mfn;
-};
-#endif /* _RTE_DOM0_COMMON_H_ */
diff --git a/lib/librte_eal/common/eal_common_options.c b/lib/librte_eal/common/eal_common_options.c
index 1da185e..354cded 100644
--- a/lib/librte_eal/common/eal_common_options.c
+++ b/lib/librte_eal/common/eal_common_options.c
@@ -97,7 +97,6 @@ eal_long_options[] = {
 	{OPT_VDEV,              1, NULL, OPT_VDEV_NUM             },
 	{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         },
 	{0,                     0, NULL, 0                        }
 };
 
@@ -208,8 +207,6 @@ eal_reset_internal_config(struct internal_config *internal_cfg)
 
 	internal_cfg->syslog_facility = LOG_DAEMON;
 
-	internal_cfg->xen_dom0_support = 0;
-
 	/* if set to NONE, interrupt mode is determined automatically */
 	internal_cfg->vfio_intr_mode = RTE_INTR_MODE_NONE;
 
diff --git a/lib/librte_eal/common/eal_internal_cfg.h b/lib/librte_eal/common/eal_internal_cfg.h
index 7b7e8c8..f7c885f 100644
--- a/lib/librte_eal/common/eal_internal_cfg.h
+++ b/lib/librte_eal/common/eal_internal_cfg.h
@@ -65,7 +65,6 @@ struct internal_config {
 	volatile unsigned force_nrank;    /**< force number of ranks */
 	volatile unsigned no_hugetlbfs;   /**< true to disable hugetlbfs */
 	unsigned hugepage_unlink;         /**< true to unlink backing files */
-	volatile unsigned xen_dom0_support; /**< support app running on Xen Dom0*/
 	volatile unsigned no_pci;         /**< true to disable PCI */
 	volatile unsigned no_hpet;        /**< true to disable HPET */
 	volatile unsigned vmware_tsc_map; /**< true to use VMware TSC mapping
diff --git a/lib/librte_eal/common/eal_options.h b/lib/librte_eal/common/eal_options.h
index 439a261..8770b85 100644
--- a/lib/librte_eal/common/eal_options.h
+++ b/lib/librte_eal/common/eal_options.h
@@ -81,8 +81,6 @@ enum {
 	OPT_VFIO_INTR_NUM,
 #define OPT_VMWARE_TSC_MAP    "vmware-tsc-map"
 	OPT_VMWARE_TSC_MAP_NUM,
-#define OPT_XEN_DOM0          "xen-dom0"
-	OPT_XEN_DOM0_NUM,
 	OPT_LONG_MAX_NUM
 };
 
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
index 4aa5d1f..d8543c0 100644
--- a/lib/librte_eal/common/include/rte_memory.h
+++ b/lib/librte_eal/common/include/rte_memory.h
@@ -46,10 +46,6 @@
 
 #include <rte_config.h>
 
-#ifdef RTE_EXEC_ENV_LINUXAPP
-#include <exec-env/rte_dom0_common.h>
-#endif
-
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -116,10 +112,6 @@ struct rte_memseg {
 	int32_t socket_id;          /**< NUMA socket ID. */
 	uint32_t nchannel;          /**< Number of channels. */
 	uint32_t nrank;             /**< Number of ranks. */
-#ifdef RTE_LIBRTE_XEN_DOM0
-	 /**< store segment MFNs */
-	uint64_t mfn[DOM0_NUM_MEMBLOCK];
-#endif
 } __rte_packed;
 
 /**
@@ -195,69 +187,11 @@ unsigned rte_memory_get_nchannel(void);
  */
 unsigned rte_memory_get_nrank(void);
 
-#ifdef RTE_LIBRTE_XEN_DOM0
-
-/**< Internal use only - should DOM0 memory mapping be used */
-int rte_xen_dom0_supported(void);
-
-/**< Internal use only - phys to virt mapping for xen */
-phys_addr_t rte_xen_mem_phy2mch(int32_t, const phys_addr_t);
-
-/**
- * Return the physical address of elt, which is an element of the pool mp.
- *
- * @param memseg_id
- *   Identifier of the memory segment owning the physical address. If
- *   set to -1, find it automatically.
- * @param phy_addr
- *   physical address of elt.
- *
- * @return
- *   The physical address or RTE_BAD_PHYS_ADDR on error.
- */
-static inline phys_addr_t
-rte_mem_phy2mch(int32_t memseg_id, const phys_addr_t phy_addr)
-{
-	if (rte_xen_dom0_supported())
-		return rte_xen_mem_phy2mch(memseg_id, phy_addr);
-	else
-		return phy_addr;
-}
-
-/**
- * Memory init for supporting application running on Xen domain0.
- *
- * @param void
- *
- * @return
- *       0: successfully
- *	 negative: error
- */
-int rte_xen_dom0_memory_init(void);
-
-/**
- * Attach to memory setments of primary process on Xen domain0.
- *
- * @param void
- *
- * @return
- *       0: successfully
- *       negative: error
- */
-int rte_xen_dom0_memory_attach(void);
-#else
-static inline int rte_xen_dom0_supported(void)
-{
-	return 0;
-}
-
 static inline phys_addr_t
 rte_mem_phy2mch(int32_t memseg_id __rte_unused, const phys_addr_t phy_addr)
 {
 	return phy_addr;
 }
-#endif
-
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_eal/linuxapp/Makefile b/lib/librte_eal/linuxapp/Makefile
index 4794696..2ebdf31 100644
--- a/lib/librte_eal/linuxapp/Makefile
+++ b/lib/librte_eal/linuxapp/Makefile
@@ -35,7 +35,5 @@ DIRS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal
 DIRS-$(CONFIG_RTE_EAL_IGB_UIO) += igb_uio
 DIRS-$(CONFIG_RTE_KNI_KMOD) += kni
 DEPDIRS-kni := eal
-DIRS-$(CONFIG_RTE_LIBRTE_XEN_DOM0) += xen_dom0
-DEPDIRS-xen_dom0 := eal
 
 include $(RTE_SDK)/mk/rte.subdir.mk
diff --git a/lib/librte_eal/linuxapp/eal/Makefile b/lib/librte_eal/linuxapp/eal/Makefile
index 90bca4d..d9f9985 100644
--- a/lib/librte_eal/linuxapp/eal/Makefile
+++ b/lib/librte_eal/linuxapp/eal/Makefile
@@ -58,9 +58,6 @@ endif
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) := eal.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_hugepage_info.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_memory.c
-ifeq ($(CONFIG_RTE_LIBRTE_XEN_DOM0),y)
-SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_xen_memory.c
-endif
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_thread.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_log.c
 SRCS-$(CONFIG_RTE_EXEC_ENV_LINUXAPP) += eal_vfio.c
@@ -130,7 +127,7 @@ ifeq ($(CONFIG_RTE_TOOLCHAIN_GCC),y)
 CFLAGS_eal_thread.o += -Wno-return-type
 endif
 
-INC := rte_interrupts.h rte_kni_common.h rte_dom0_common.h
+INC := rte_interrupts.h rte_kni_common.h
 
 SYMLINK-$(CONFIG_RTE_EXEC_ENV_LINUXAPP)-include/exec-env := \
 	$(addprefix include/exec-env/,$(INC))
diff --git a/lib/librte_eal/linuxapp/eal/eal.c b/lib/librte_eal/linuxapp/eal/eal.c
index 48f12f4..d995d03 100644
--- a/lib/librte_eal/linuxapp/eal/eal.c
+++ b/lib/librte_eal/linuxapp/eal/eal.c
@@ -354,7 +354,6 @@ eal_usage(const char *prgname)
 	       "  --"OPT_BASE_VIRTADDR"     Base virtual address\n"
 	       "  --"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"
 	       "\n");
 	/* Allow the application to print its usage message too if hook is set */
 	if ( rte_application_usage_hook ) {
@@ -555,19 +554,6 @@ eal_parse_args(int argc, char **argv)
 			eal_usage(prgname);
 			exit(EXIT_SUCCESS);
 
-		/* long options */
-		case OPT_XEN_DOM0_NUM:
-#ifdef RTE_LIBRTE_XEN_DOM0
-			internal_config.xen_dom0_support = 1;
-#else
-			RTE_LOG(ERR, EAL, "Can't support DPDK app "
-				"running on Dom0, please configure"
-				" RTE_LIBRTE_XEN_DOM0=y\n");
-			ret = -1;
-			goto out;
-#endif
-			break;
-
 		case OPT_HUGE_DIR_NUM:
 			internal_config.hugepage_dir = optarg;
 			break;
@@ -641,15 +627,6 @@ eal_parse_args(int argc, char **argv)
 		goto out;
 	}
 
-	/* --xen-dom0 doesn't make sense with --socket-mem */
-	if (internal_config.xen_dom0_support && internal_config.force_sockets == 1) {
-		RTE_LOG(ERR, EAL, "Options --"OPT_SOCKET_MEM" cannot be specified "
-			"together with --"OPT_XEN_DOM0"\n");
-		eal_usage(prgname);
-		ret = -1;
-		goto out;
-	}
-
 	if (optind >= 0)
 		argv[optind-1] = prgname;
 	ret = optind-1;
@@ -794,7 +771,6 @@ rte_eal_init(int argc, char **argv)
 
 	if (internal_config.no_hugetlbfs == 0 &&
 			internal_config.process_type != RTE_PROC_SECONDARY &&
-			internal_config.xen_dom0_support == 0 &&
 			eal_hugepage_info_init() < 0) {
 		rte_eal_init_alert("Cannot get hugepage information.");
 		rte_errno = EACCES;
diff --git a/lib/librte_eal/linuxapp/eal/eal_memory.c b/lib/librte_eal/linuxapp/eal/eal_memory.c
index 5279128..087fad4 100644
--- a/lib/librte_eal/linuxapp/eal/eal_memory.c
+++ b/lib/librte_eal/linuxapp/eal/eal_memory.c
@@ -75,13 +75,6 @@
 
 #define PFN_MASK_SIZE	8
 
-#ifdef RTE_LIBRTE_XEN_DOM0
-int rte_xen_dom0_supported(void)
-{
-	return internal_config.xen_dom0_support;
-}
-#endif
-
 /**
  * @file
  * Huge page mapping under linux
@@ -106,10 +99,6 @@ test_phys_addrs_available(void)
 	uint64_t tmp;
 	phys_addr_t physaddr;
 
-	/* For dom0, phys addresses can always be available */
-	if (rte_xen_dom0_supported())
-		return;
-
 	if (!rte_eal_has_hugepages()) {
 		RTE_LOG(ERR, EAL,
 			"Started without hugepages support, physical addresses not available\n");
@@ -139,29 +128,6 @@ rte_mem_virt2phy(const void *virtaddr)
 	int page_size;
 	off_t offset;
 
-	/* when using dom0, /proc/self/pagemap always returns 0, check in
-	 * dpdk memory by browsing the memsegs */
-	if (rte_xen_dom0_supported()) {
-		struct rte_mem_config *mcfg;
-		struct rte_memseg *memseg;
-		unsigned i;
-
-		mcfg = rte_eal_get_configuration()->mem_config;
-		for (i = 0; i < RTE_MAX_MEMSEG; i++) {
-			memseg = &mcfg->memseg[i];
-			if (memseg->addr == NULL)
-				break;
-			if (virtaddr > memseg->addr &&
-					virtaddr < RTE_PTR_ADD(memseg->addr,
-						memseg->len)) {
-				return memseg->phys_addr +
-					RTE_PTR_DIFF(virtaddr, memseg->addr);
-			}
-		}
-
-		return RTE_BAD_PHYS_ADDR;
-	}
-
 	/* Cannot parse /proc/self/pagemap, no need to log errors everywhere */
 	if (!phys_addrs_available)
 		return RTE_BAD_PHYS_ADDR;
@@ -1067,17 +1033,6 @@ rte_eal_hugepage_init(void)
 		return 0;
 	}
 
-/* check if app runs on Xen Dom0 */
-	if (internal_config.xen_dom0_support) {
-#ifdef RTE_LIBRTE_XEN_DOM0
-		/* use dom0_mm kernel driver to init memory */
-		if (rte_xen_dom0_memory_init() < 0)
-			return -1;
-		else
-			return 0;
-#endif
-	}
-
 	/* calculate total number of hugepages available. at this point we haven't
 	 * yet started sorting them so they all are on socket 0 */
 	for (i = 0; i < (int) internal_config.num_hugepage_sizes; i++) {
@@ -1400,17 +1355,6 @@ rte_eal_hugepage_attach(void)
 
 	test_phys_addrs_available();
 
-	if (internal_config.xen_dom0_support) {
-#ifdef RTE_LIBRTE_XEN_DOM0
-		if (rte_xen_dom0_memory_attach() < 0) {
-			RTE_LOG(ERR, EAL, "Failed to attach memory segments of primary "
-					"process\n");
-			return -1;
-		}
-		return 0;
-#endif
-	}
-
 	fd_zero = open("/dev/zero", O_RDONLY);
 	if (fd_zero < 0) {
 		RTE_LOG(ERR, EAL, "Could not open /dev/zero\n");
diff --git a/lib/librte_eal/linuxapp/eal/eal_xen_memory.c b/lib/librte_eal/linuxapp/eal/eal_xen_memory.c
deleted file mode 100644
index 19db1cb..0000000
--- a/lib/librte_eal/linuxapp/eal/eal_xen_memory.c
+++ /dev/null
@@ -1,381 +0,0 @@
-/*-
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include <errno.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <inttypes.h>
-#include <string.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <sys/queue.h>
-#include <sys/file.h>
-#include <unistd.h>
-#include <limits.h>
-#include <sys/ioctl.h>
-#include <sys/time.h>
-
-#include <rte_log.h>
-#include <rte_memory.h>
-#include <rte_memzone.h>
-#include <rte_launch.h>
-#include <rte_eal.h>
-#include <rte_eal_memconfig.h>
-#include <rte_per_lcore.h>
-#include <rte_lcore.h>
-#include <rte_common.h>
-#include <rte_string_fns.h>
-
-#include "eal_private.h"
-#include "eal_internal_cfg.h"
-#include "eal_filesystem.h"
-#include <exec-env/rte_dom0_common.h>
-
-#define PAGE_SIZE RTE_PGSIZE_4K
-#define DEFAUL_DOM0_NAME "dom0-mem"
-
-static int xen_fd = -1;
-static const char sys_dir_path[] = "/sys/kernel/mm/dom0-mm/memsize-mB";
-
-/*
- * Try to mmap *size bytes in /dev/zero. If it is successful, return the
- * pointer to the mmap'd area and keep *size unmodified. Else, retry
- * with a smaller zone: decrease *size by mem_size until it reaches
- * 0. In this case, return NULL. Note: this function returns an address
- * which is a multiple of mem_size size.
- */
-static void *
-xen_get_virtual_area(size_t *size, size_t mem_size)
-{
-	void *addr;
-	int fd;
-	long aligned_addr;
-
-	RTE_LOG(DEBUG, EAL, "Ask a virtual area of 0x%zu bytes\n", *size);
-
-	fd = open("/dev/zero", O_RDONLY);
-	if (fd < 0){
-		RTE_LOG(ERR, EAL, "Cannot open /dev/zero\n");
-		return NULL;
-	}
-	do {
-		addr = mmap(NULL, (*size) + mem_size, PROT_READ,
-			MAP_PRIVATE, fd, 0);
-		if (addr == MAP_FAILED)
-			*size -= mem_size;
-	} while (addr == MAP_FAILED && *size > 0);
-
-	if (addr == MAP_FAILED) {
-		close(fd);
-		RTE_LOG(ERR, EAL, "Cannot get a virtual area\n");
-		return NULL;
-	}
-
-	munmap(addr, (*size) + mem_size);
-	close(fd);
-
-	/* align addr to a mem_size boundary */
-	aligned_addr = (uintptr_t)addr;
-	aligned_addr = RTE_ALIGN_CEIL(aligned_addr, mem_size);
-        addr = (void *)(aligned_addr);
-
-	RTE_LOG(DEBUG, EAL, "Virtual area found at %p (size = 0x%zx)\n",
-		addr, *size);
-
-	return addr;
-}
-
-/**
- * Get memory size configuration from /sys/devices/virtual/misc/dom0_mm
- * /memsize-mB/memsize file, and the size unit is mB.
- */
-static int
-get_xen_memory_size(void)
-{
-	char path[PATH_MAX];
-	unsigned long mem_size = 0;
-	static const char *file_name;
-
-	file_name = "memsize";
-	snprintf(path, sizeof(path), "%s/%s",
-			sys_dir_path, file_name);
-
-	if (eal_parse_sysfs_value(path, &mem_size) < 0)
-		return -1;
-
-	if (mem_size == 0)
-		rte_exit(EXIT_FAILURE,"XEN-DOM0:the %s/%s was not"
-			" configured.\n",sys_dir_path, file_name);
-	if (mem_size % 2)
-		rte_exit(EXIT_FAILURE,"XEN-DOM0:the %s/%s must be"
-			" even number.\n",sys_dir_path, file_name);
-
-	if (mem_size > DOM0_CONFIG_MEMSIZE)
-		rte_exit(EXIT_FAILURE,"XEN-DOM0:the %s/%s should not be larger"
-			" than %d mB\n",sys_dir_path, file_name, DOM0_CONFIG_MEMSIZE);
-
-	return mem_size;
-}
-
-/**
- * Based on physical address to caculate MFN in Xen Dom0.
- */
-phys_addr_t
-rte_xen_mem_phy2mch(int32_t memseg_id, const phys_addr_t phy_addr)
-{
-	int mfn_id, i;
-	uint64_t mfn, mfn_offset;
-	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
-	struct rte_memseg *memseg = mcfg->memseg;
-
-	/* find the memory segment owning the physical address */
-	if (memseg_id == -1) {
-		for (i = 0; i < RTE_MAX_MEMSEG; i++) {
-			if ((phy_addr >= memseg[i].phys_addr) &&
-					(phy_addr < memseg[i].phys_addr +
-						memseg[i].len)) {
-				memseg_id = i;
-				break;
-			}
-		}
-		if (memseg_id == -1)
-			return RTE_BAD_PHYS_ADDR;
-	}
-
-	mfn_id = (phy_addr - memseg[memseg_id].phys_addr) / RTE_PGSIZE_2M;
-
-	/*the MFN is contiguous in 2M */
-	mfn_offset = (phy_addr - memseg[memseg_id].phys_addr) %
-					RTE_PGSIZE_2M / PAGE_SIZE;
-	mfn = mfn_offset + memseg[memseg_id].mfn[mfn_id];
-
-	/** return mechine address */
-	return mfn * PAGE_SIZE + phy_addr % PAGE_SIZE;
-}
-
-int
-rte_xen_dom0_memory_init(void)
-{
-	void *vir_addr, *vma_addr = NULL;
-	int err, ret = 0;
-	uint32_t i, requested, mem_size, memseg_idx, num_memseg = 0;
-	size_t vma_len = 0;
-	struct memory_info meminfo;
-	struct memseg_info seginfo[RTE_MAX_MEMSEG];
-	int flags, page_size = getpagesize();
-	struct rte_mem_config *mcfg = rte_eal_get_configuration()->mem_config;
-	struct rte_memseg *memseg = mcfg->memseg;
-	uint64_t total_mem = internal_config.memory;
-
-	memset(seginfo, 0, sizeof(seginfo));
-	memset(&meminfo, 0, sizeof(struct memory_info));
-
-	mem_size = get_xen_memory_size();
-	requested = (unsigned) (total_mem / 0x100000);
-	if (requested > mem_size)
-		/* if we didn't satisfy total memory requirements */
-		rte_exit(EXIT_FAILURE,"Not enough memory available! Requested: %uMB,"
-				" available: %uMB\n", requested, mem_size);
-	else if (total_mem != 0)
-		mem_size = requested;
-
-	/* Check FD and open once */
-	if (xen_fd < 0) {
-		xen_fd = open(DOM0_MM_DEV, O_RDWR);
-		if (xen_fd < 0) {
-			RTE_LOG(ERR, EAL, "Can not open %s\n",DOM0_MM_DEV);
-			return -1;
-		}
-	}
-
-	meminfo.size = mem_size;
-
-	/* construct memory mangement name for Dom0 */
-	snprintf(meminfo.name, DOM0_NAME_MAX, "%s-%s",
-		internal_config.hugefile_prefix, DEFAUL_DOM0_NAME);
-
-	/* Notify kernel driver to allocate memory */
-	ret = ioctl(xen_fd, RTE_DOM0_IOCTL_PREPARE_MEMSEG, &meminfo);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "XEN DOM0:failed to get memory\n");
-		err = -EIO;
-		goto fail;
-	}
-
-	/* Get number of memory segment from driver */
-	ret = ioctl(xen_fd, RTE_DOM0_IOCTL_GET_NUM_MEMSEG, &num_memseg);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "XEN DOM0:failed to get memseg count.\n");
-		err = -EIO;
-		goto fail;
-	}
-
-	if(num_memseg > RTE_MAX_MEMSEG){
-		RTE_LOG(ERR, EAL, "XEN DOM0: the memseg count %d is greater"
-			" than max memseg %d.\n",num_memseg, RTE_MAX_MEMSEG);
-		err = -EIO;
-		goto fail;
-	}
-
-	/* get all memory segements information */
-	ret = ioctl(xen_fd, RTE_DOM0_IOCTL_GET_MEMSEG_INFO, seginfo);
-	if (ret < 0) {
-		RTE_LOG(ERR, EAL, "XEN DOM0:failed to get memseg info.\n");
-		err = -EIO;
-		goto fail;
-	}
-
-	/* map all memory segments to contiguous user space */
-	for (memseg_idx = 0; memseg_idx < num_memseg; memseg_idx++)
-	{
-		vma_len = seginfo[memseg_idx].size;
-
-		/**
-		 * get the biggest virtual memory area up to vma_len. If it fails,
-		 * vma_addr is NULL, so let the kernel provide the address.
-		 */
-		vma_addr = xen_get_virtual_area(&vma_len, RTE_PGSIZE_2M);
-		if (vma_addr == NULL) {
-			flags = MAP_SHARED;
-			vma_len = RTE_PGSIZE_2M;
-		} else
-			flags = MAP_SHARED | MAP_FIXED;
-
-		seginfo[memseg_idx].size = vma_len;
-		vir_addr = mmap(vma_addr, seginfo[memseg_idx].size,
-			PROT_READ|PROT_WRITE, flags, xen_fd,
-			memseg_idx * page_size);
-		if (vir_addr == MAP_FAILED) {
-			RTE_LOG(ERR, EAL, "XEN DOM0:Could not mmap %s\n",
-				DOM0_MM_DEV);
-			err = -EIO;
-			goto fail;
-		}
-
-		memseg[memseg_idx].addr = vir_addr;
-		memseg[memseg_idx].phys_addr = page_size *
-			seginfo[memseg_idx].pfn ;
-		memseg[memseg_idx].len = seginfo[memseg_idx].size;
-		for ( i = 0; i < seginfo[memseg_idx].size / RTE_PGSIZE_2M; i++)
-			memseg[memseg_idx].mfn[i] = seginfo[memseg_idx].mfn[i];
-
-		/* MFNs are continuous in 2M, so assume that page size is 2M */
-		memseg[memseg_idx].hugepage_sz = RTE_PGSIZE_2M;
-
-		memseg[memseg_idx].nchannel = mcfg->nchannel;
-		memseg[memseg_idx].nrank = mcfg->nrank;
-
-		/* NUMA is not suppoted in Xen Dom0, so only set socket 0*/
-		memseg[memseg_idx].socket_id = 0;
-	}
-
-	return 0;
-fail:
-	if (xen_fd > 0) {
-		close(xen_fd);
-		xen_fd = -1;
-	}
-	return err;
-}
-
-/*
- * This creates the memory mappings in the secondary process to match that of
- * the server process. It goes through each memory segment in the DPDK runtime
- * configuration, mapping them in order to form a contiguous block in the
- * virtual memory space
- */
-int
-rte_xen_dom0_memory_attach(void)
-{
-	const struct rte_mem_config *mcfg;
-	unsigned s = 0; /* s used to track the segment number */
-	int xen_fd = -1;
-	int ret = -1;
-	void *vir_addr;
-	char name[DOM0_NAME_MAX] = {0};
-	int page_size = getpagesize();
-
-	mcfg = rte_eal_get_configuration()->mem_config;
-
-	/* Check FD and open once */
-	if (xen_fd < 0) {
-		xen_fd = open(DOM0_MM_DEV, O_RDWR);
-		if (xen_fd < 0) {
-			RTE_LOG(ERR, EAL, "Can not open %s\n",DOM0_MM_DEV);
-			goto error;
-		}
-	}
-
-	/* construct memory mangement name for Dom0 */
-	snprintf(name, DOM0_NAME_MAX, "%s-%s",
-		internal_config.hugefile_prefix, DEFAUL_DOM0_NAME);
-	/* attach to memory segments of primary process */
-	ret = ioctl(xen_fd, RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG, name);
-	if (ret) {
-		RTE_LOG(ERR, EAL,"attach memory segments fail.\n");
-		goto error;
-	}
-
-	/* map all segments into memory to make sure we get the addrs */
-	for (s = 0; s < RTE_MAX_MEMSEG; ++s) {
-
-		/*
-		 * the first memory segment with len==0 is the one that
-		 * follows the last valid segment.
-		 */
-		if (mcfg->memseg[s].len == 0)
-			break;
-
-		vir_addr = mmap(mcfg->memseg[s].addr, mcfg->memseg[s].len,
-				PROT_READ|PROT_WRITE, MAP_SHARED|MAP_FIXED, xen_fd,
-				s * page_size);
-		if (vir_addr == MAP_FAILED) {
-			RTE_LOG(ERR, EAL, "Could not mmap %llu bytes "
-				"in %s to requested address [%p]\n",
-				(unsigned long long)mcfg->memseg[s].len, DOM0_MM_DEV,
-				mcfg->memseg[s].addr);
-			goto error;
-		}
-	}
-	return 0;
-
-error:
-	if (xen_fd >= 0) {
-		close(xen_fd);
-		xen_fd = -1;
-	}
-	return -1;
-}
diff --git a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h b/lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
deleted file mode 100644
index d970778..0000000
--- a/lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
+++ /dev/null
@@ -1,108 +0,0 @@
-/*-
- *   This file is provided under a dual BSD/LGPLv2 license.  When using or
- *   redistributing this file, you may do so under either license.
- *
- *   GNU LESSER GENERAL PUBLIC LICENSE
- *
- *   Copyright(c) 2007-2014 Intel Corporation. All rights reserved.
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of version 2.1 of the GNU Lesser General Public License
- *   as published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful, but
- *   WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *   Lesser General Public License for more details.
- *
- *   You should have received a copy of the GNU Lesser General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *
- *   Contact Information:
- *   Intel Corporation
- *
- *
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in
- *     the documentation and/or other materials provided with the
- *     distribution.
- *   * Neither the name of Intel Corporation nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
- *
- *    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *    "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *    LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *    A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *    OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *    SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *    LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *    DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *    THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *    (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *    OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#ifndef _RTE_DOM0_COMMON_H_
-#define _RTE_DOM0_COMMON_H_
-
-#ifdef __KERNEL__
-#include <linux/if.h>
-#endif
-
-#define DOM0_NAME_MAX   256
-#define DOM0_MM_DEV   "/dev/dom0_mm"
-
-#define DOM0_CONTIG_NUM_ORDER       9       /**< order of 2M */
-#define DOM0_NUM_MEMSEG             512     /**< Maximum nb. of memory segment. */
-#define DOM0_MEMBLOCK_SIZE          0x200000 /**< size of memory block(2M). */
-#define DOM0_CONFIG_MEMSIZE         4096     /**< Maximum config memory size(4G). */
-#define DOM0_NUM_MEMBLOCK (DOM0_CONFIG_MEMSIZE / 2) /**< Maximum nb. of 2M memory block. */
-
-#define RTE_DOM0_IOCTL_PREPARE_MEMSEG    _IOWR(0, 1 , struct memory_info)
-#define RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG  _IOWR(0, 2 , char *)
-#define RTE_DOM0_IOCTL_GET_NUM_MEMSEG    _IOWR(0, 3, int)
-#define RTE_DOM0_IOCTL_GET_MEMSEG_INFO   _IOWR(0, 4, void *)
-
-/**
- * A structure used to store memory information.
- */
-struct memory_info {
-	char name[DOM0_NAME_MAX];
-	uint64_t size;
-};
-
-/**
- * A structure used to store memory segment information.
- */
-struct memseg_info {
-	uint32_t idx;
-	uint64_t pfn;
-	uint64_t size;
-	uint64_t mfn[DOM0_NUM_MEMBLOCK];
-};
-
-/**
- * A structure used to store memory block information.
- */
-struct memblock_info {
-	uint8_t exchange_flag;
-	uint8_t used;
-	uint64_t vir_addr;
-	uint64_t pfn;
-	uint64_t mfn;
-};
-#endif /* _RTE_DOM0_COMMON_H_ */
diff --git a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
index 07a19a3..3d5c2f3 100644
--- a/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
+++ b/lib/librte_eal/linuxapp/igb_uio/igb_uio.c
@@ -33,9 +33,6 @@
 #include <linux/version.h>
 #include <linux/slab.h>
 
-#ifdef CONFIG_XEN_DOM0
-#include <xen/xen.h>
-#endif
 #include <rte_pci_dev_features.h>
 
 #include "compat.h"
@@ -201,52 +198,6 @@ igbuio_pci_release(struct uio_info *info, struct inode *inode)
 	return 0;
 }
 
-#ifdef CONFIG_XEN_DOM0
-static int
-igbuio_dom0_mmap_phys(struct uio_info *info, struct vm_area_struct *vma)
-{
-	int idx;
-
-	idx = (int)vma->vm_pgoff;
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-#ifdef HAVE_PTE_MASK_PAGE_IOMAP
-	vma->vm_page_prot.pgprot |= _PAGE_IOMAP;
-#endif
-
-	return remap_pfn_range(vma,
-			vma->vm_start,
-			info->mem[idx].addr >> PAGE_SHIFT,
-			vma->vm_end - vma->vm_start,
-			vma->vm_page_prot);
-}
-
-/**
- * This is uio device mmap method which will use igbuio mmap for Xen
- * Dom0 environment.
- */
-static int
-igbuio_dom0_pci_mmap(struct uio_info *info, struct vm_area_struct *vma)
-{
-	int idx;
-
-	if (vma->vm_pgoff >= MAX_UIO_MAPS)
-		return -EINVAL;
-
-	if (info->mem[vma->vm_pgoff].size == 0)
-		return -EINVAL;
-
-	idx = (int)vma->vm_pgoff;
-	switch (info->mem[idx].memtype) {
-	case UIO_MEM_PHYS:
-		return igbuio_dom0_mmap_phys(info, vma);
-	case UIO_MEM_LOGICAL:
-	case UIO_MEM_VIRTUAL:
-	default:
-		return -EINVAL;
-	}
-}
-#endif
-
 /* Remap pci resources described by bar #pci_bar in uio resource n. */
 static int
 igbuio_pci_setup_iomem(struct pci_dev *dev, struct uio_info *info,
@@ -405,11 +356,6 @@ igbuio_pci_probe(struct pci_dev *dev, const struct pci_device_id *id)
 	udev->info.irqcontrol = igbuio_pci_irqcontrol;
 	udev->info.open = igbuio_pci_open;
 	udev->info.release = igbuio_pci_release;
-#ifdef CONFIG_XEN_DOM0
-	/* check if the driver run on Xen Dom0 */
-	if (xen_initial_domain())
-		udev->info.mmap = igbuio_dom0_pci_mmap;
-#endif
 	udev->info.priv = udev;
 	udev->pdev = dev;
 
diff --git a/lib/librte_eal/linuxapp/xen_dom0/Makefile b/lib/librte_eal/linuxapp/xen_dom0/Makefile
deleted file mode 100644
index be51a82..0000000
--- a/lib/librte_eal/linuxapp/xen_dom0/Makefile
+++ /dev/null
@@ -1,53 +0,0 @@
-#   BSD LICENSE
-#
-#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
-#   All rights reserved.
-#
-#   Redistribution and use in source and binary forms, with or without
-#   modification, are permitted provided that the following conditions
-#   are met:
-#
-#     * Redistributions of source code must retain the above copyright
-#       notice, this list of conditions and the following disclaimer.
-#     * Redistributions in binary form must reproduce the above copyright
-#       notice, this list of conditions and the following disclaimer in
-#       the documentation and/or other materials provided with the
-#       distribution.
-#     * Neither the name of Intel Corporation nor the names of its
-#       contributors may be used to endorse or promote products derived
-#       from this software without specific prior written permission.
-#
-#   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-#   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-#   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-#   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-#   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-#   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-#   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-#   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-#   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-#   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-#   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-include $(RTE_SDK)/mk/rte.vars.mk
-
-#
-# module name and path
-#
-MODULE = rte_dom0_mm
-
-#
-# CFLAGS
-#
-MODULE_CFLAGS += -I$(SRCDIR) --param max-inline-insns-single=50
-MODULE_CFLAGS += -I$(RTE_OUTPUT)/include
-MODULE_CFLAGS += -include $(RTE_OUTPUT)/include/rte_config.h
-MODULE_CFLAGS += -Wall -Werror
-
-#
-# all source are stored in SRCS-y
-#
-
-SRCS-y += dom0_mm_misc.c
-
-include $(RTE_SDK)/mk/rte.module.mk
diff --git a/lib/librte_eal/linuxapp/xen_dom0/compat.h b/lib/librte_eal/linuxapp/xen_dom0/compat.h
deleted file mode 100644
index e6eb97f..0000000
--- a/lib/librte_eal/linuxapp/xen_dom0/compat.h
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * Minimal wrappers to allow compiling xen_dom0 on older kernels.
- */
-
-#ifndef RHEL_RELEASE_VERSION
-#define RHEL_RELEASE_VERSION(a, b) (((a) << 8) + (b))
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 39) && \
-	(!(defined(RHEL_RELEASE_CODE) && \
-	 RHEL_RELEASE_CODE >= RHEL_RELEASE_VERSION(6, 4)))
-
-#define kstrtoul strict_strtoul
-
-#endif /* < 2.6.39 */
diff --git a/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h b/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h
deleted file mode 100644
index 9d5ffb2..0000000
--- a/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h
+++ /dev/null
@@ -1,107 +0,0 @@
-/*-
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- *   redistributing this file, you may do so under either license.
- *
- *   GPL LICENSE SUMMARY
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of version 2 of the GNU General Public License as
- *   published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful, but
- *   WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *   General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *   The full GNU General Public License is included in this distribution
- *   in the file called LICENSE.GPL.
- *
- *   Contact Information:
- *   Intel Corporation
- *
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-#ifndef _DOM0_MM_DEV_H_
-#define _DOM0_MM_DEV_H_
-
-#include <linux/wait.h>
-#include <linux/mutex.h>
-#include <linux/sched.h>
-#include <linux/spinlock.h>
-#include <exec-env/rte_dom0_common.h>
-
-#define NUM_MEM_CTX     256  /**< Maximum number of memory context*/
-#define MAX_EXCHANGE_FAIL_TIME 5  /**< Maximum times of allowing exchange fail .*/
-#define MAX_MEMBLOCK_SIZE (2 * DOM0_MEMBLOCK_SIZE)
-#define MAX_NUM_ORDER     (DOM0_CONTIG_NUM_ORDER + 1)
-#define SIZE_PER_BLOCK    2       /**< Size of memory block (2MB).*/
-
-/**
- * A structure describing the private information for a dom0 device.
- */
-struct dom0_mm_dev {
-	struct miscdevice miscdev;
-	uint8_t fail_times;
-	uint32_t used_memsize;
-	uint32_t num_mem_ctx;
-	uint32_t config_memsize;
-	uint32_t num_bigblock;
-	struct  dom0_mm_data *mm_data[NUM_MEM_CTX];
-	struct mutex data_lock;
-};
-
-struct dom0_mm_data{
-	uint32_t refcnt;
-	uint32_t num_memseg; /**< Number of memory segment. */
-	uint32_t mem_size;   /**< Size of requesting memory. */
-
-	char name[DOM0_NAME_MAX];
-
-	/** Store global memory block IDs used by an instance */
-	uint32_t block_num[DOM0_NUM_MEMBLOCK];
-
-	/** Store memory block information.*/
-	struct memblock_info block_info[DOM0_NUM_MEMBLOCK];
-
-	/** Store memory segment information.*/
-	struct memseg_info  seg_info[DOM0_NUM_MEMSEG];
-};
-
-#define XEN_ERR(args...) printk(KERN_DEBUG "XEN_DOM0: Error: " args)
-#define XEN_PRINT(args...) printk(KERN_DEBUG "XEN_DOM0: " args)
-#endif
diff --git a/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c b/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c
deleted file mode 100644
index 79630ba..0000000
--- a/lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c
+++ /dev/null
@@ -1,780 +0,0 @@
-/*-
- * This file is provided under a dual BSD/GPLv2 license.  When using or
- *   redistributing this file, you may do so under either license.
- *
- *   GPL LICENSE SUMMARY
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *
- *   This program is free software; you can redistribute it and/or modify
- *   it under the terms of version 2 of the GNU General Public License as
- *   published by the Free Software Foundation.
- *
- *   This program is distributed in the hope that it will be useful, but
- *   WITHOUT ANY WARRANTY; without even the implied warranty of
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- *   General Public License for more details.
- *
- *   You should have received a copy of the GNU General Public License
- *   along with this program; if not, write to the Free Software
- *   Foundation, Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
- *   The full GNU General Public License is included in this distribution
- *   in the file called LICENSE.GPL.
- *
- *   Contact Information:
- *   Intel Corporation
- *
- *   BSD LICENSE
- *
- *   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
- *   All rights reserved.
- *
- *   Redistribution and use in source and binary forms, with or without
- *   modification, are permitted provided that the following conditions
- *   are met:
- *
- *     * Redistributions of source code must retain the above copyright
- *       notice, this list of conditions and the following disclaimer.
- *     * Redistributions in binary form must reproduce the above copyright
- *       notice, this list of conditions and the following disclaimer in
- *       the documentation and/or other materials provided with the
- *       distribution.
- *     * Neither the name of Intel Corporation nor the names of its
- *       contributors may be used to endorse or promote products derived
- *       from this software without specific prior written permission.
- *
- *   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- *   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- *   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- *   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- *   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- *   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- *   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- *   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- *   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- *   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- */
-
-#include <linux/module.h>
-#include <linux/miscdevice.h>
-#include <linux/fs.h>
-#include <linux/device.h>
-#include <linux/errno.h>
-#include <linux/vmalloc.h>
-#include <linux/mm.h>
-#include <linux/version.h>
-
-#include <xen/xen.h>
-#include <xen/page.h>
-#include <xen/xen-ops.h>
-#include <xen/interface/memory.h>
-
-#include <exec-env/rte_dom0_common.h>
-
-#include "compat.h"
-#include "dom0_mm_dev.h"
-
-MODULE_LICENSE("Dual BSD/GPL");
-MODULE_AUTHOR("Intel Corporation");
-MODULE_DESCRIPTION("Kernel Module for supporting DPDK running on Xen Dom0");
-
-static struct dom0_mm_dev dom0_dev;
-static struct kobject *dom0_kobj = NULL;
-
-static struct memblock_info *rsv_mm_info;
-
-/* Default configuration for reserved memory size(2048 MB). */
-static uint32_t rsv_memsize = 2048;
-
-static int dom0_open(struct inode *inode, struct file *file);
-static int dom0_release(struct inode *inode, struct file *file);
-static int dom0_ioctl(struct file *file, unsigned int ioctl_num,
-		unsigned long ioctl_param);
-static int dom0_mmap(struct file *file, struct vm_area_struct *vma);
-static int dom0_memory_free(uint32_t size);
-static int dom0_memory_release(struct dom0_mm_data *mm_data);
-
-static const struct file_operations data_fops = {
-	.owner = THIS_MODULE,
-	.open = dom0_open,
-	.release = dom0_release,
-	.mmap = dom0_mmap,
-	.unlocked_ioctl = (void *)dom0_ioctl,
-};
-
-static ssize_t
-show_memsize_rsvd(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return snprintf(buf, 10, "%u\n", dom0_dev.used_memsize);
-}
-
-static ssize_t
-show_memsize(struct device *dev, struct device_attribute *attr, char *buf)
-{
-	return snprintf(buf, 10, "%u\n", dom0_dev.config_memsize);
-}
-
-static ssize_t
-store_memsize(struct device *dev, struct device_attribute *attr,
-            const char *buf, size_t count)
-{
-	int err = 0;
-	unsigned long mem_size;
-
-	if (0 != kstrtoul(buf, 0, &mem_size))
-		return  -EINVAL;
-
-	mutex_lock(&dom0_dev.data_lock);
-	if (0 == mem_size) {
-		err = -EINVAL;
-		goto fail;
-	} else if (mem_size > (rsv_memsize - dom0_dev.used_memsize)) {
-		XEN_ERR("configure memory size fail\n");
-		err = -EINVAL;
-		goto fail;
-	} else
-		dom0_dev.config_memsize = mem_size;
-
-fail:
-	mutex_unlock(&dom0_dev.data_lock);
-	return err ? err : count;
-}
-
-static DEVICE_ATTR(memsize, S_IRUGO | S_IWUSR, show_memsize, store_memsize);
-static DEVICE_ATTR(memsize_rsvd, S_IRUGO, show_memsize_rsvd, NULL);
-
-static struct attribute *dev_attrs[] = {
-	&dev_attr_memsize.attr,
-	&dev_attr_memsize_rsvd.attr,
-	NULL,
-};
-
-/* the memory size unit is MB */
-static const struct attribute_group dev_attr_grp = {
-	.name = "memsize-mB",
-	.attrs = dev_attrs,
-};
-
-
-static void
-sort_viraddr(struct memblock_info *mb, int cnt)
-{
-	int i,j;
-	uint64_t tmp_pfn;
-	uint64_t tmp_viraddr;
-
-	/*sort virtual address and pfn */
-	for(i = 0; i < cnt; i ++) {
-		for(j = cnt - 1; j > i; j--) {
-			if(mb[j].pfn < mb[j - 1].pfn) {
-				tmp_pfn = mb[j - 1].pfn;
-				mb[j - 1].pfn = mb[j].pfn;
-				mb[j].pfn = tmp_pfn;
-
-				tmp_viraddr = mb[j - 1].vir_addr;
-				mb[j - 1].vir_addr = mb[j].vir_addr;
-				mb[j].vir_addr = tmp_viraddr;
-			}
-		}
-	}
-}
-
-static int
-dom0_find_memdata(const char * mem_name)
-{
-	unsigned i;
-	int idx = -1;
-	for(i = 0; i< NUM_MEM_CTX; i++) {
-		if(dom0_dev.mm_data[i] == NULL)
-			continue;
-		if (!strncmp(dom0_dev.mm_data[i]->name, mem_name,
-			sizeof(char) * DOM0_NAME_MAX)) {
-			idx = i;
-			break;
-		}
-	}
-
-	return idx;
-}
-
-static int
-dom0_find_mempos(void)
-{
-	unsigned i;
-	int idx = -1;
-
-	for(i = 0; i< NUM_MEM_CTX; i++) {
-		if(dom0_dev.mm_data[i] == NULL){
-			idx = i;
-			break;
-		}
-	}
-
-	return idx;
-}
-
-static int
-dom0_memory_release(struct dom0_mm_data *mm_data)
-{
-	int idx;
-	uint32_t  num_block, block_id;
-
-	/* each memory block is 2M */
-	num_block = mm_data->mem_size / SIZE_PER_BLOCK;
-	if (num_block == 0)
-		return -EINVAL;
-
-	/* reset global memory data */
-	idx = dom0_find_memdata(mm_data->name);
-	if (idx >= 0) {
-		dom0_dev.used_memsize -= mm_data->mem_size;
-		dom0_dev.mm_data[idx] = NULL;
-		dom0_dev.num_mem_ctx--;
-	}
-
-	/* reset these memory blocks status as free */
-	for (idx = 0; idx < num_block; idx++) {
-		block_id = mm_data->block_num[idx];
-		rsv_mm_info[block_id].used = 0;
-	}
-
-	memset(mm_data, 0, sizeof(struct dom0_mm_data));
-	vfree(mm_data);
-	return 0;
-}
-
-static int
-dom0_memory_free(uint32_t rsv_size)
-{
-	uint64_t vstart, vaddr;
-	uint32_t i, num_block, size;
-
-	if (!xen_pv_domain())
-		return -1;
-
-	/* each memory block is 2M */
-	num_block = rsv_size / SIZE_PER_BLOCK;
-	if (num_block == 0)
-		return -EINVAL;
-
-	/* free all memory blocks of size of 4M and destroy contiguous region */
-	for (i = 0; i < dom0_dev.num_bigblock * 2; i += 2) {
-		vstart = rsv_mm_info[i].vir_addr;
-		if (vstart) {
-		#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
-			if (rsv_mm_info[i].exchange_flag)
-				xen_destroy_contiguous_region(vstart,
-						DOM0_CONTIG_NUM_ORDER);
-			if (rsv_mm_info[i + 1].exchange_flag)
-				xen_destroy_contiguous_region(vstart +
-						DOM0_MEMBLOCK_SIZE,
-						DOM0_CONTIG_NUM_ORDER);
-		#else
-			if (rsv_mm_info[i].exchange_flag)
-				xen_destroy_contiguous_region(rsv_mm_info[i].pfn
-					* PAGE_SIZE,
-					DOM0_CONTIG_NUM_ORDER);
-			if (rsv_mm_info[i + 1].exchange_flag)
-				xen_destroy_contiguous_region(rsv_mm_info[i].pfn
-					* PAGE_SIZE + DOM0_MEMBLOCK_SIZE,
-					DOM0_CONTIG_NUM_ORDER);
-		#endif
-
-			size = DOM0_MEMBLOCK_SIZE * 2;
-			vaddr = vstart;
-			while (size > 0) {
-				ClearPageReserved(virt_to_page(vaddr));
-				vaddr += PAGE_SIZE;
-				size -= PAGE_SIZE;
-			}
-			free_pages(vstart, MAX_NUM_ORDER);
-		}
-	}
-
-	/* free all memory blocks size of 2M and destroy contiguous region */
-	for (; i < num_block; i++) {
-		vstart = rsv_mm_info[i].vir_addr;
-		if (vstart) {
-			if (rsv_mm_info[i].exchange_flag)
-				xen_destroy_contiguous_region(vstart,
-					DOM0_CONTIG_NUM_ORDER);
-
-			size = DOM0_MEMBLOCK_SIZE;
-			vaddr = vstart;
-			while (size > 0) {
-				ClearPageReserved(virt_to_page(vaddr));
-				vaddr += PAGE_SIZE;
-				size -= PAGE_SIZE;
-			}
-			free_pages(vstart, DOM0_CONTIG_NUM_ORDER);
-		}
-	}
-
-	memset(rsv_mm_info, 0, sizeof(struct memblock_info) * num_block);
-	vfree(rsv_mm_info);
-	rsv_mm_info = NULL;
-
-	return 0;
-}
-
-static void
-find_free_memory(uint32_t count, struct dom0_mm_data *mm_data)
-{
-	uint32_t i = 0;
-	uint32_t j = 0;
-
-	while ((i < count) && (j < rsv_memsize / SIZE_PER_BLOCK)) {
-		if (rsv_mm_info[j].used == 0) {
-			mm_data->block_info[i].pfn = rsv_mm_info[j].pfn;
-			mm_data->block_info[i].vir_addr =
-				rsv_mm_info[j].vir_addr;
-			mm_data->block_info[i].mfn = rsv_mm_info[j].mfn;
-			mm_data->block_info[i].exchange_flag =
-				rsv_mm_info[j].exchange_flag;
-			mm_data->block_num[i] = j;
-			rsv_mm_info[j].used = 1;
-			i++;
-		}
-		j++;
-	}
-}
-
-/**
- * Find all memory segments in which physical addresses are contiguous.
- */
-static void
-find_memseg(int count, struct dom0_mm_data * mm_data)
-{
-	int i = 0;
-	int j, k, idx = 0;
-	uint64_t zone_len, pfn, num_block;
-
-	while(i < count) {
-		if (mm_data->block_info[i].exchange_flag == 0) {
-			i++;
-			continue;
-		}
-		k = 0;
-		pfn = mm_data->block_info[i].pfn;
-		mm_data->seg_info[idx].pfn = pfn;
-		mm_data->seg_info[idx].mfn[k] = mm_data->block_info[i].mfn;
-
-		for (j = i + 1; j < count; j++) {
-
-			/* ignore exchange fail memory block */
-			if (mm_data->block_info[j].exchange_flag == 0)
-				break;
-
-			if (mm_data->block_info[j].pfn !=
-				(mm_data->block_info[j - 1].pfn +
-					 DOM0_MEMBLOCK_SIZE / PAGE_SIZE))
-			    break;
-			++k;
-			mm_data->seg_info[idx].mfn[k] = mm_data->block_info[j].mfn;
-		}
-
-		num_block = j - i;
-		zone_len = num_block * DOM0_MEMBLOCK_SIZE;
-		mm_data->seg_info[idx].size = zone_len;
-
-		XEN_PRINT("memseg id=%d, size=0x%llx\n", idx, zone_len);
-		i = i+ num_block;
-		idx++;
-		if (idx == DOM0_NUM_MEMSEG)
-			break;
-	}
-	mm_data->num_memseg = idx;
-}
-
-static int
-dom0_memory_reserve(uint32_t rsv_size)
-{
-	uint64_t pfn, vstart, vaddr;
-	uint32_t i, num_block, size, allocated_size = 0;
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(3, 13, 0)
-	dma_addr_t dma_handle;
-#endif
-
-	/* 2M as memory block */
-	num_block = rsv_size / SIZE_PER_BLOCK;
-
-	rsv_mm_info = vmalloc(sizeof(struct memblock_info) * num_block);
-	if (!rsv_mm_info) {
-		XEN_ERR("Unable to allocate device memory information\n");
-		return -ENOMEM;
-	}
-	memset(rsv_mm_info, 0, sizeof(struct memblock_info) * num_block);
-
-	/* try alloc size of 4M once */
-	for (i = 0; i < num_block; i += 2) {
-		vstart = (unsigned long)
-			__get_free_pages(GFP_ATOMIC, MAX_NUM_ORDER);
-		if (vstart == 0)
-			break;
-
-		dom0_dev.num_bigblock = i / 2 + 1;
-		allocated_size =  SIZE_PER_BLOCK * (i + 2);
-
-		/* size of 4M */
-		size = DOM0_MEMBLOCK_SIZE * 2;
-
-		vaddr = vstart;
-		while (size > 0) {
-			SetPageReserved(virt_to_page(vaddr));
-			vaddr += PAGE_SIZE;
-			size -= PAGE_SIZE;
-		}
-
-		pfn = virt_to_pfn(vstart);
-		rsv_mm_info[i].pfn = pfn;
-		rsv_mm_info[i].vir_addr = vstart;
-		rsv_mm_info[i + 1].pfn =
-				pfn + DOM0_MEMBLOCK_SIZE / PAGE_SIZE;
-		rsv_mm_info[i + 1].vir_addr =
-				vstart + DOM0_MEMBLOCK_SIZE;
-	}
-
-	/*if it failed to alloc 4M, and continue to alloc 2M once */
-	for (; i < num_block; i++) {
-		vstart = (unsigned long)
-			__get_free_pages(GFP_ATOMIC, DOM0_CONTIG_NUM_ORDER);
-		if (vstart == 0) {
-			XEN_ERR("allocate memory fail.\n");
-			dom0_memory_free(allocated_size);
-			return -ENOMEM;
-		}
-
-		allocated_size += SIZE_PER_BLOCK;
-
-		size = DOM0_MEMBLOCK_SIZE;
-		vaddr = vstart;
-		while (size > 0) {
-			SetPageReserved(virt_to_page(vaddr));
-			vaddr += PAGE_SIZE;
-			size -= PAGE_SIZE;
-		}
-		pfn = virt_to_pfn(vstart);
-		rsv_mm_info[i].pfn = pfn;
-		rsv_mm_info[i].vir_addr = vstart;
-	}
-
-	sort_viraddr(rsv_mm_info, num_block);
-
-	for (i = 0; i< num_block; i++) {
-
-		/*
-		 * This API is used to exchage MFN for getting a block of
-		 * contiguous physical addresses, its maximum size is 2M.
-		 */
-	#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 13, 0)
-		if (xen_create_contiguous_region(rsv_mm_info[i].vir_addr,
-				DOM0_CONTIG_NUM_ORDER, 0) == 0) {
-	#else
-		if (xen_create_contiguous_region(rsv_mm_info[i].pfn * PAGE_SIZE,
-				DOM0_CONTIG_NUM_ORDER, 0, &dma_handle) == 0) {
-	#endif
-			rsv_mm_info[i].exchange_flag = 1;
-			rsv_mm_info[i].mfn =
-				pfn_to_mfn(rsv_mm_info[i].pfn);
-			rsv_mm_info[i].used = 0;
-		} else {
-			XEN_ERR("exchange memeory fail\n");
-			rsv_mm_info[i].exchange_flag = 0;
-			dom0_dev.fail_times++;
-			if (dom0_dev.fail_times > MAX_EXCHANGE_FAIL_TIME) {
-				dom0_memory_free(rsv_size);
-				return  -EFAULT;
-			}
-		}
-	}
-
-	return 0;
-}
-
-static int
-dom0_prepare_memsegs(struct memory_info *meminfo, struct dom0_mm_data *mm_data)
-{
-	uint32_t num_block;
-	int idx;
-
-	/* check if there is a free name buffer */
-	memcpy(mm_data->name, meminfo->name, DOM0_NAME_MAX);
-	mm_data->name[DOM0_NAME_MAX - 1] = '\0';
-	idx = dom0_find_mempos();
-	if (idx < 0)
-		return -1;
-
-	num_block = meminfo->size / SIZE_PER_BLOCK;
-	/* find free memory and new memory segments*/
-	find_free_memory(num_block, mm_data);
-	find_memseg(num_block, mm_data);
-
-	/* update private memory data */
-	mm_data->refcnt++;
-	mm_data->mem_size = meminfo->size;
-
-	/* update global memory data */
-	dom0_dev.mm_data[idx] = mm_data;
-	dom0_dev.num_mem_ctx++;
-	dom0_dev.used_memsize += mm_data->mem_size;
-
-	return 0;
-}
-
-static int
-dom0_check_memory (struct memory_info *meminfo)
-{
-	int idx;
-	uint64_t mem_size;
-
-	/* round memory size to the next even number. */
-	if (meminfo->size % 2)
-		++meminfo->size;
-
-	mem_size = meminfo->size;
-	if (dom0_dev.num_mem_ctx > NUM_MEM_CTX) {
-		XEN_ERR("Memory data space is full in Dom0 driver\n");
-		return -1;
-	}
-	idx = dom0_find_memdata(meminfo->name);
-	if (idx >= 0) {
-		XEN_ERR("Memory data name %s has already exsited in Dom0 driver.\n",
-			meminfo->name);
-		return -1;
-	}
-	if ((dom0_dev.used_memsize + mem_size) > rsv_memsize) {
-		XEN_ERR("Total size can't be larger than reserved size.\n");
-		return -1;
-	}
-
-	return 0;
-}
-
-static int __init
-dom0_init(void)
-{
-	if (!xen_domain())
-		return -ENODEV;
-
-	if (rsv_memsize > DOM0_CONFIG_MEMSIZE) {
-		XEN_ERR("The reserved memory size cannot be greater than %d\n",
-			DOM0_CONFIG_MEMSIZE);
-		return -EINVAL;
-	}
-
-	/* Setup the misc device */
-	dom0_dev.miscdev.minor = MISC_DYNAMIC_MINOR;
-	dom0_dev.miscdev.name = "dom0_mm";
-	dom0_dev.miscdev.fops = &data_fops;
-
-	/* register misc char device */
-	if (misc_register(&dom0_dev.miscdev) != 0) {
-		XEN_ERR("Misc device registration failed\n");
-		return -EPERM;
-	}
-
-	mutex_init(&dom0_dev.data_lock);
-	dom0_kobj = kobject_create_and_add("dom0-mm", mm_kobj);
-
-	if (!dom0_kobj) {
-		XEN_ERR("dom0-mm object creation failed\n");
-		misc_deregister(&dom0_dev.miscdev);
-		return -ENOMEM;
-	}
-
-	if (sysfs_create_group(dom0_kobj, &dev_attr_grp)) {
-		kobject_put(dom0_kobj);
-		misc_deregister(&dom0_dev.miscdev);
-		return -EPERM;
-	}
-
-	if (dom0_memory_reserve(rsv_memsize) < 0) {
-		sysfs_remove_group(dom0_kobj, &dev_attr_grp);
-		kobject_put(dom0_kobj);
-		misc_deregister(&dom0_dev.miscdev);
-		return -ENOMEM;
-	}
-
-	XEN_PRINT("####### DPDK Xen Dom0 module loaded  #######\n");
-
-	return 0;
-}
-
-static void __exit
-dom0_exit(void)
-{
-	if (rsv_mm_info != NULL)
-		dom0_memory_free(rsv_memsize);
-
-	sysfs_remove_group(dom0_kobj, &dev_attr_grp);
-	kobject_put(dom0_kobj);
-	misc_deregister(&dom0_dev.miscdev);
-
-	XEN_PRINT("####### DPDK Xen Dom0 module unloaded  #######\n");
-}
-
-static int
-dom0_open(struct inode *inode, struct file *file)
-{
-	file->private_data = NULL;
-
-	XEN_PRINT(KERN_INFO "/dev/dom0_mm opened\n");
-	return 0;
-}
-
-static int
-dom0_release(struct inode *inode, struct file *file)
-{
-	int ret = 0;
-	struct dom0_mm_data *mm_data = file->private_data;
-
-	if (mm_data == NULL)
-		return ret;
-
-	mutex_lock(&dom0_dev.data_lock);
-	if (--mm_data->refcnt == 0)
-		ret = dom0_memory_release(mm_data);
-	mutex_unlock(&dom0_dev.data_lock);
-
-	file->private_data = NULL;
-	XEN_PRINT(KERN_INFO "/dev/dom0_mm closed\n");
-	return ret;
-}
-
-static int
-dom0_mmap(struct file *file, struct vm_area_struct *vm)
-{
-	int status = 0;
-	uint32_t idx = vm->vm_pgoff;
-	uint64_t pfn, size = vm->vm_end - vm->vm_start;
-	struct dom0_mm_data *mm_data = file->private_data;
-
-	if(mm_data == NULL)
-		return -EINVAL;
-
-	mutex_lock(&dom0_dev.data_lock);
-	if (idx >= mm_data->num_memseg) {
-		mutex_unlock(&dom0_dev.data_lock);
-		return -EINVAL;
-	}
-
-	if (size > mm_data->seg_info[idx].size){
-		mutex_unlock(&dom0_dev.data_lock);
-		return -EINVAL;
-	}
-
-	XEN_PRINT("mmap memseg idx =%d,size = 0x%llx\n", idx, size);
-
-	pfn = mm_data->seg_info[idx].pfn;
-	mutex_unlock(&dom0_dev.data_lock);
-
-	status = remap_pfn_range(vm, vm->vm_start, pfn, size, PAGE_SHARED);
-
-	return status;
-}
-static int
-dom0_ioctl(struct file *file,
-	unsigned int ioctl_num,
-	unsigned long ioctl_param)
-{
-	int idx, ret;
-	char name[DOM0_NAME_MAX] = {0};
-	struct memory_info meminfo;
-	struct dom0_mm_data *mm_data = file->private_data;
-
-	XEN_PRINT("IOCTL num=0x%0x param=0x%0lx \n", ioctl_num, ioctl_param);
-
-	/**
-	 * Switch according to the ioctl called
-	 */
-	switch _IOC_NR(ioctl_num) {
-	case _IOC_NR(RTE_DOM0_IOCTL_PREPARE_MEMSEG):
-		ret = copy_from_user(&meminfo, (void *)ioctl_param,
-			sizeof(struct memory_info));
-		if (ret)
-			return  -EFAULT;
-
-		if (mm_data != NULL) {
-			XEN_ERR("Cannot create memory segment for the same"
-				" file descriptor\n");
-			return -EINVAL;
-		}
-
-		/* Allocate private data */
-		mm_data = vmalloc(sizeof(struct dom0_mm_data));
-		if (!mm_data) {
-			XEN_ERR("Unable to allocate device private data\n");
-			return -ENOMEM;
-		}
-		memset(mm_data, 0, sizeof(struct dom0_mm_data));
-
-		mutex_lock(&dom0_dev.data_lock);
-		/* check if we can allocate memory*/
-		if (dom0_check_memory(&meminfo) < 0) {
-			mutex_unlock(&dom0_dev.data_lock);
-			vfree(mm_data);
-			return -EINVAL;
-		}
-
-		/* allocate memory and created memory segments*/
-		if (dom0_prepare_memsegs(&meminfo, mm_data) < 0) {
-			XEN_ERR("create memory segment fail.\n");
-			mutex_unlock(&dom0_dev.data_lock);
-			return -EIO;
-		}
-
-		file->private_data = mm_data;
-		mutex_unlock(&dom0_dev.data_lock);
-		break;
-
-	/* support multiple process in term of memory mapping*/
-	case _IOC_NR(RTE_DOM0_IOCTL_ATTACH_TO_MEMSEG):
-		ret = copy_from_user(name, (void *)ioctl_param,
-				sizeof(char) * DOM0_NAME_MAX);
-		if (ret)
-			return -EFAULT;
-
-		mutex_lock(&dom0_dev.data_lock);
-		idx = dom0_find_memdata(name);
-		if (idx < 0) {
-			mutex_unlock(&dom0_dev.data_lock);
-			return -EINVAL;
-		}
-
-		mm_data = dom0_dev.mm_data[idx];
-		mm_data->refcnt++;
-		file->private_data = mm_data;
-		mutex_unlock(&dom0_dev.data_lock);
-		break;
-
-	case _IOC_NR(RTE_DOM0_IOCTL_GET_NUM_MEMSEG):
-		ret = copy_to_user((void *)ioctl_param, &mm_data->num_memseg,
-				sizeof(int));
-		if (ret)
-			return -EFAULT;
-		break;
-
-	case _IOC_NR(RTE_DOM0_IOCTL_GET_MEMSEG_INFO):
-		ret = copy_to_user((void *)ioctl_param,
-				&mm_data->seg_info[0],
-				sizeof(struct memseg_info) *
-				mm_data->num_memseg);
-		if (ret)
-			return -EFAULT;
-		break;
-	default:
-		XEN_PRINT("IOCTL default \n");
-		break;
-	}
-
-	return 0;
-}
-
-module_init(dom0_init);
-module_exit(dom0_exit);
-
-module_param(rsv_memsize, uint, S_IRUGO | S_IWUSR);
-MODULE_PARM_DESC(rsv_memsize, "Xen-dom0 reserved memory size(MB).\n");
diff --git a/pkg/dpdk.spec b/pkg/dpdk.spec
index 95c3335..fd1b5ef 100644
--- a/pkg/dpdk.spec
+++ b/pkg/dpdk.spec
@@ -52,9 +52,6 @@ ExclusiveArch: i686 x86_64 aarch64
 %endif
 
 BuildRequires: kernel-devel, kernel-headers, libpcap-devel
-%ifarch i686 x86_64
-BuildRequires: xen-devel
-%endif
 BuildRequires: doxygen, python-sphinx, inkscape
 BuildRequires: texlive-collection-latexextra
 
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* [PATCH 6/6] eal: remove API rte_mem_phy2mch
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
                   ` (8 preceding siblings ...)
  2017-08-30 18:10 ` [PATCH 5/6] eal: remove xen dom0 support Jianfeng Tan
@ 2017-08-30 18:10 ` Jianfeng Tan
  2017-09-04 14:52   ` [dpdk-dev] " Bruce Richardson
  2017-09-04 14:52   ` Bruce Richardson
  2017-08-31  8:44 ` [PATCH 0/6] remove xen dom0 support in DPDK Wei Liu
  10 siblings, 2 replies; 38+ messages in thread
From: Jianfeng Tan @ 2017-08-30 18:10 UTC (permalink / raw)
  To: dev
  Cc: jerin.jacob, shahafs, john.mcnamara, Jianfeng Tan, oao.m.martins,
	thomas, xen-devel

Previously, to get MFN address in dom0, this API is a wrapper to
obtain the "physical address".

As we removed xen dom0 support, this API is not necessary.

Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
---
 doc/guides/rel_notes/release_17_11.rst     | 2 ++
 drivers/net/e1000/em_rxtx.c                | 4 ++--
 drivers/net/e1000/igb_rxtx.c               | 4 ++--
 drivers/net/fm10k/fm10k_ethdev.c           | 4 ++--
 drivers/net/i40e/i40e_ethdev.c             | 2 +-
 drivers/net/i40e/i40e_fdir.c               | 2 +-
 drivers/net/i40e/i40e_rxtx.c               | 8 ++++----
 drivers/net/ixgbe/ixgbe_rxtx.c             | 4 ++--
 drivers/net/sfc/sfc.c                      | 2 +-
 lib/librte_eal/common/include/rte_memory.h | 5 -----
 lib/librte_mempool/rte_mempool.c           | 3 ---
 11 files changed, 17 insertions(+), 23 deletions(-)

diff --git a/doc/guides/rel_notes/release_17_11.rst b/doc/guides/rel_notes/release_17_11.rst
index d211084..06c334b 100644
--- a/doc/guides/rel_notes/release_17_11.rst
+++ b/doc/guides/rel_notes/release_17_11.rst
@@ -110,6 +110,8 @@ API Changes
    Also, make sure to start the actual text at the margin.
    =========================================================
 
+   * ``rte_mem_phy2mch`` was used in xen dom0 to obtain the physical address;
+     remove this API as xen dom0 support was removed.
 
 ABI Changes
 -----------
diff --git a/drivers/net/e1000/em_rxtx.c b/drivers/net/e1000/em_rxtx.c
index 31819c5..a0f63a7 100644
--- a/drivers/net/e1000/em_rxtx.c
+++ b/drivers/net/e1000/em_rxtx.c
@@ -1289,7 +1289,7 @@ eth_em_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->port_id = dev->data->port_id;
 
 	txq->tdt_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_TDT(queue_idx));
-	txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+	txq->tx_ring_phys_addr = tz->phys_addr;
 	txq->tx_ring = (struct e1000_data_desc *) tz->addr;
 
 	PMD_INIT_LOG(DEBUG, "sw_ring=%p hw_ring=%p dma_addr=0x%"PRIx64,
@@ -1416,7 +1416,7 @@ eth_em_rx_queue_setup(struct rte_eth_dev *dev,
 
 	rxq->rdt_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDT(queue_idx));
 	rxq->rdh_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDH(queue_idx));
-	rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+	rxq->rx_ring_phys_addr = rz->phys_addr;
 	rxq->rx_ring = (struct e1000_rx_desc *) rz->addr;
 
 	PMD_INIT_LOG(DEBUG, "sw_ring=%p hw_ring=%p dma_addr=0x%"PRIx64,
diff --git a/drivers/net/e1000/igb_rxtx.c b/drivers/net/e1000/igb_rxtx.c
index 1c80a2a..0fccb5d 100644
--- a/drivers/net/e1000/igb_rxtx.c
+++ b/drivers/net/e1000/igb_rxtx.c
@@ -1530,7 +1530,7 @@ eth_igb_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->port_id = dev->data->port_id;
 
 	txq->tdt_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_TDT(txq->reg_idx));
-	txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+	txq->tx_ring_phys_addr = tz->phys_addr;
 
 	txq->tx_ring = (union e1000_adv_tx_desc *) tz->addr;
 	/* Allocate software ring */
@@ -1667,7 +1667,7 @@ eth_igb_rx_queue_setup(struct rte_eth_dev *dev,
 	}
 	rxq->rdt_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDT(rxq->reg_idx));
 	rxq->rdh_reg_addr = E1000_PCI_REG_ADDR(hw, E1000_RDH(rxq->reg_idx));
-	rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+	rxq->rx_ring_phys_addr = rz->phys_addr;
 	rxq->rx_ring = (union e1000_adv_rx_desc *) rz->addr;
 
 	/* Allocate software ring. */
diff --git a/drivers/net/fm10k/fm10k_ethdev.c b/drivers/net/fm10k/fm10k_ethdev.c
index e60d3a3..15ea2a5 100644
--- a/drivers/net/fm10k/fm10k_ethdev.c
+++ b/drivers/net/fm10k/fm10k_ethdev.c
@@ -1887,7 +1887,7 @@ fm10k_rx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 		return -ENOMEM;
 	}
 	q->hw_ring = mz->addr;
-	q->hw_ring_phys_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+	q->hw_ring_phys_addr = mz->phys_addr;
 
 	/* Check if number of descs satisfied Vector requirement */
 	if (!rte_is_power_of_2(nb_desc)) {
@@ -2047,7 +2047,7 @@ fm10k_tx_queue_setup(struct rte_eth_dev *dev, uint16_t queue_id,
 		return -ENOMEM;
 	}
 	q->hw_ring = mz->addr;
-	q->hw_ring_phys_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+	q->hw_ring_phys_addr = mz->phys_addr;
 
 	/*
 	 * allocate memory for the RS bit tracker. Enough slots to hold the
diff --git a/drivers/net/i40e/i40e_ethdev.c b/drivers/net/i40e/i40e_ethdev.c
index 5f26e24..dc5458d 100644
--- a/drivers/net/i40e/i40e_ethdev.c
+++ b/drivers/net/i40e/i40e_ethdev.c
@@ -3741,7 +3741,7 @@ i40e_allocate_dma_mem_d(__attribute__((unused)) struct i40e_hw *hw,
 
 	mem->size = size;
 	mem->va = mz->addr;
-	mem->pa = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+	mem->pa = mz->phys_addr;
 	mem->zone = (const void *)mz;
 	PMD_DRV_LOG(DEBUG,
 		"memzone %s allocated with physical address: %"PRIu64,
diff --git a/drivers/net/i40e/i40e_fdir.c b/drivers/net/i40e/i40e_fdir.c
index 8013add..70dae92 100644
--- a/drivers/net/i40e/i40e_fdir.c
+++ b/drivers/net/i40e/i40e_fdir.c
@@ -249,7 +249,7 @@ i40e_fdir_setup(struct i40e_pf *pf)
 		goto fail_mem;
 	}
 	pf->fdir.prg_pkt = mz->addr;
-	pf->fdir.dma_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+	pf->fdir.dma_addr = mz->phys_addr;
 
 	pf->fdir.match_counter_index = I40E_COUNTER_INDEX_FDIR(hw->pf_id);
 	PMD_DRV_LOG(INFO, "FDIR setup successfully, with programming queue %u.",
diff --git a/drivers/net/i40e/i40e_rxtx.c b/drivers/net/i40e/i40e_rxtx.c
index f571e79..344c11c 100644
--- a/drivers/net/i40e/i40e_rxtx.c
+++ b/drivers/net/i40e/i40e_rxtx.c
@@ -1822,7 +1822,7 @@ i40e_dev_rx_queue_setup(struct rte_eth_dev *dev,
 	/* Zero all the descriptors in the ring. */
 	memset(rz->addr, 0, ring_size);
 
-	rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+	rxq->rx_ring_phys_addr = rz->phys_addr;
 	rxq->rx_ring = (union i40e_rx_desc *)rz->addr;
 
 	len = (uint16_t)(nb_desc + RTE_PMD_I40E_RX_MAX_BURST);
@@ -2159,7 +2159,7 @@ i40e_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	txq->vsi = vsi;
 	txq->tx_deferred_start = tx_conf->tx_deferred_start;
 
-	txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+	txq->tx_ring_phys_addr = tz->phys_addr;
 	txq->tx_ring = (struct i40e_tx_desc *)tz->addr;
 
 	/* Allocate software ring */
@@ -2671,7 +2671,7 @@ i40e_fdir_setup_tx_resources(struct i40e_pf *pf)
 	txq->reg_idx = pf->fdir.fdir_vsi->base_queue;
 	txq->vsi = pf->fdir.fdir_vsi;
 
-	txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+	txq->tx_ring_phys_addr = tz->phys_addr;
 	txq->tx_ring = (struct i40e_tx_desc *)tz->addr;
 	/*
 	 * don't need to allocate software ring and reset for the fdir
@@ -2727,7 +2727,7 @@ i40e_fdir_setup_rx_resources(struct i40e_pf *pf)
 	rxq->reg_idx = pf->fdir.fdir_vsi->base_queue;
 	rxq->vsi = pf->fdir.fdir_vsi;
 
-	rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+	rxq->rx_ring_phys_addr = rz->phys_addr;
 	rxq->rx_ring = (union i40e_rx_desc *)rz->addr;
 
 	/*
diff --git a/drivers/net/ixgbe/ixgbe_rxtx.c b/drivers/net/ixgbe/ixgbe_rxtx.c
index 64bff25..ac1415b 100644
--- a/drivers/net/ixgbe/ixgbe_rxtx.c
+++ b/drivers/net/ixgbe/ixgbe_rxtx.c
@@ -2548,7 +2548,7 @@ ixgbe_dev_tx_queue_setup(struct rte_eth_dev *dev,
 	else
 		txq->tdt_reg_addr = IXGBE_PCI_REG_ADDR(hw, IXGBE_TDT(txq->reg_idx));
 
-	txq->tx_ring_phys_addr = rte_mem_phy2mch(tz->memseg_id, tz->phys_addr);
+	txq->tx_ring_phys_addr = tz->phys_addr;
 	txq->tx_ring = (union ixgbe_adv_tx_desc *) tz->addr;
 
 	/* Allocate software ring */
@@ -2850,7 +2850,7 @@ ixgbe_dev_rx_queue_setup(struct rte_eth_dev *dev,
 			IXGBE_PCI_REG_ADDR(hw, IXGBE_RDH(rxq->reg_idx));
 	}
 
-	rxq->rx_ring_phys_addr = rte_mem_phy2mch(rz->memseg_id, rz->phys_addr);
+	rxq->rx_ring_phys_addr = rz->phys_addr;
 	rxq->rx_ring = (union ixgbe_adv_rx_desc *) rz->addr;
 
 	/*
diff --git a/drivers/net/sfc/sfc.c b/drivers/net/sfc/sfc.c
index 6cecfc0..f9e9916 100644
--- a/drivers/net/sfc/sfc.c
+++ b/drivers/net/sfc/sfc.c
@@ -61,7 +61,7 @@ sfc_dma_alloc(const struct sfc_adapter *sa, const char *name, uint16_t id,
 		return ENOMEM;
 	}
 
-	esmp->esm_addr = rte_mem_phy2mch(mz->memseg_id, mz->phys_addr);
+	esmp->esm_addr = mz->phys_addr;
 	if (esmp->esm_addr == RTE_BAD_PHYS_ADDR) {
 		(void)rte_memzone_free(mz);
 		return EFAULT;
diff --git a/lib/librte_eal/common/include/rte_memory.h b/lib/librte_eal/common/include/rte_memory.h
index d8543c0..c545963 100644
--- a/lib/librte_eal/common/include/rte_memory.h
+++ b/lib/librte_eal/common/include/rte_memory.h
@@ -187,11 +187,6 @@ unsigned rte_memory_get_nchannel(void);
  */
 unsigned rte_memory_get_nrank(void);
 
-static inline phys_addr_t
-rte_mem_phy2mch(int32_t memseg_id __rte_unused, const phys_addr_t phy_addr)
-{
-	return phy_addr;
-}
 #ifdef __cplusplus
 }
 #endif
diff --git a/lib/librte_mempool/rte_mempool.c b/lib/librte_mempool/rte_mempool.c
index 6d726ae..892a1ac 100644
--- a/lib/librte_mempool/rte_mempool.c
+++ b/lib/librte_mempool/rte_mempool.c
@@ -473,8 +473,6 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
 		     mp->populated_size < mp->size; off += phys_len) {
 
 		paddr = rte_mem_virt2phy(addr + off);
-		/* required for xen_dom0 to get the machine address */
-		paddr = rte_mem_phy2mch(-1, paddr);
 
 		if (paddr == RTE_BAD_PHYS_ADDR && rte_eal_has_hugepages()) {
 			ret = -EINVAL;
@@ -486,7 +484,6 @@ rte_mempool_populate_virt(struct rte_mempool *mp, char *addr,
 			phys_addr_t paddr_tmp;
 
 			paddr_tmp = rte_mem_virt2phy(addr + off + phys_len);
-			paddr_tmp = rte_mem_phy2mch(-1, paddr_tmp);
 
 			if (paddr_tmp != paddr + phys_len)
 				break;
-- 
2.7.4


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply related	[flat|nested] 38+ messages in thread

* Re: [PATCH 0/6] remove xen dom0 support in DPDK
  2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
                   ` (9 preceding siblings ...)
  2017-08-30 18:10 ` [PATCH 6/6] eal: remove API rte_mem_phy2mch Jianfeng Tan
@ 2017-08-31  8:44 ` Wei Liu
  10 siblings, 0 replies; 38+ messages in thread
From: Wei Liu @ 2017-08-31  8:44 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, Wei Liu, dev, john.mcnamara, thomas,
	xen-devel, joao.m.martins

CC Joao's correct address

On Wed, Aug 30, 2017 at 06:10:28PM +0000, Jianfeng Tan wrote:
> Following the calls on the mailing list:
>     http://dpdk.org/ml/archives/dev/2017-June/068151.html
> The Technical Board decided to drop Xen dom0 support from EAL:
>     http://dpdk.org/ml/archives/dev/2017-June/068615.html
> 
> This series remove xen dom0 support in DPDK, as well as xenvirt PMD and
> vhost_xen example.
> 
> What are effected?
> 
> After these patches, users cannot run DPDK applications inside xen dom0.
> 
> What are not effected?
> 
> Users can still run DPDK applications inside xen domU on pass-throughed
> physical devices and virtio devices; on the host, users still can run
> DPDK applications same as before.
> 
> Jianfeng Tan (6):
>   example/vhost_xen: remove
>   net/xenvirt: remove
>   xen: remove xen dependency in app, examples, test
>   xen: remove xen dependency in drivers, ether, mempool
>   eal: remove xen dom0 support
>   eal: remove API rte_mem_phy2mch
> 
>  MAINTAINERS                                        |   10 -
>  app/test-pmd/Makefile                              |    4 -
>  app/test-pmd/testpmd.c                             |   14 +-
>  config/common_base                                 |   10 -
>  config/defconfig_arm-armv7a-linuxapp-gcc           |    1 -
>  doc/guides/index.rst                               |    1 -
>  doc/guides/linux_gsg/build_sample_apps.rst         |    5 +-
>  doc/guides/linux_gsg/sys_reqs.rst                  |   53 -
>  doc/guides/nics/features/xenvirt.ini               |    6 -
>  doc/guides/prog_guide/source_org.rst               |    1 -
>  doc/guides/rel_notes/deprecation.rst               |    3 -
>  doc/guides/rel_notes/release_17_11.rst             |   14 +
>  doc/guides/testpmd_app_ug/run_app.rst              |    4 -
>  doc/guides/xen/img/dpdk_xen_pkt_switch.png         |  Bin 163842 -> 0 bytes
>  doc/guides/xen/img/grant_refs.png                  |  Bin 6405 -> 0 bytes
>  doc/guides/xen/img/grant_table.png                 |  Bin 96762 -> 0 bytes
>  doc/guides/xen/index.rst                           |   38 -
>  doc/guides/xen/pkt_switch.rst                      |  470 ------
>  drivers/crypto/qat/qat_qp.c                        |    7 +-
>  drivers/net/Makefile                               |    2 -
>  drivers/net/e1000/em_rxtx.c                        |    4 +-
>  drivers/net/e1000/igb_rxtx.c                       |    4 +-
>  drivers/net/fm10k/fm10k_ethdev.c                   |    4 +-
>  drivers/net/i40e/i40e_ethdev.c                     |    2 +-
>  drivers/net/i40e/i40e_fdir.c                       |    2 +-
>  drivers/net/i40e/i40e_rxtx.c                       |   16 +-
>  drivers/net/ixgbe/ixgbe_rxtx.c                     |    4 +-
>  drivers/net/sfc/sfc.c                              |    2 +-
>  drivers/net/xenvirt/Makefile                       |   57 -
>  drivers/net/xenvirt/rte_eth_xenvirt.c              |  766 ----------
>  drivers/net/xenvirt/rte_eth_xenvirt.h              |   61 -
>  drivers/net/xenvirt/rte_eth_xenvirt_version.map    |    7 -
>  drivers/net/xenvirt/rte_mempool_gntalloc.c         |  295 ----
>  drivers/net/xenvirt/rte_xen_lib.c                  |  454 ------
>  drivers/net/xenvirt/rte_xen_lib.h                  |  116 --
>  drivers/net/xenvirt/virtio_logs.h                  |   70 -
>  drivers/net/xenvirt/virtqueue.h                    |  273 ----
>  examples/Makefile                                  |    1 -
>  examples/ip_pipeline/app.h                         |    4 -
>  examples/ip_pipeline/config_parse.c                |   19 -
>  examples/ip_pipeline/init.c                        |    5 -
>  examples/kni/main.c                                |    3 -
>  examples/vhost_xen/Makefile                        |   52 -
>  examples/vhost_xen/main.c                          | 1522 --------------------
>  examples/vhost_xen/main.h                          |   66 -
>  examples/vhost_xen/vhost_monitor.c                 |  595 --------
>  examples/vhost_xen/virtio-net.h                    |  113 --
>  examples/vhost_xen/xen_vhost.h                     |  148 --
>  examples/vhost_xen/xenstore_parse.c                |  775 ----------
>  .../bsdapp/eal/include/exec-env/rte_dom0_common.h  |  107 --
>  lib/librte_eal/common/eal_common_options.c         |    3 -
>  lib/librte_eal/common/eal_internal_cfg.h           |    1 -
>  lib/librte_eal/common/eal_options.h                |    2 -
>  lib/librte_eal/common/include/rte_memory.h         |   71 -
>  lib/librte_eal/linuxapp/Makefile                   |    2 -
>  lib/librte_eal/linuxapp/eal/Makefile               |    5 +-
>  lib/librte_eal/linuxapp/eal/eal.c                  |   24 -
>  lib/librte_eal/linuxapp/eal/eal_memory.c           |   56 -
>  lib/librte_eal/linuxapp/eal/eal_xen_memory.c       |  381 -----
>  .../eal/include/exec-env/rte_dom0_common.h         |  108 --
>  lib/librte_eal/linuxapp/igb_uio/igb_uio.c          |   54 -
>  lib/librte_eal/linuxapp/xen_dom0/Makefile          |   53 -
>  lib/librte_eal/linuxapp/xen_dom0/compat.h          |   15 -
>  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h     |  107 --
>  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c    |  780 ----------
>  lib/librte_ether/rte_ethdev.c                      |    7 +-
>  lib/librte_mempool/rte_mempool.c                   |   11 +-
>  mk/rte.app.mk                                      |    1 -
>  pkg/dpdk.spec                                      |    6 -
>  test/test/process.h                                |   10 -
>  test/test/test.c                                   |    4 -
>  test/test/test_eal_flags.c                         |   81 --
>  72 files changed, 38 insertions(+), 7934 deletions(-)
>  delete mode 100644 doc/guides/nics/features/xenvirt.ini
>  delete mode 100644 doc/guides/xen/img/dpdk_xen_pkt_switch.png
>  delete mode 100644 doc/guides/xen/img/grant_refs.png
>  delete mode 100644 doc/guides/xen/img/grant_table.png
>  delete mode 100644 doc/guides/xen/index.rst
>  delete mode 100644 doc/guides/xen/pkt_switch.rst
>  delete mode 100644 drivers/net/xenvirt/Makefile
>  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
>  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
>  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
>  delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
>  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
>  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
>  delete mode 100644 drivers/net/xenvirt/virtio_logs.h
>  delete mode 100644 drivers/net/xenvirt/virtqueue.h
>  delete mode 100644 examples/vhost_xen/Makefile
>  delete mode 100644 examples/vhost_xen/main.c
>  delete mode 100644 examples/vhost_xen/main.h
>  delete mode 100644 examples/vhost_xen/vhost_monitor.c
>  delete mode 100644 examples/vhost_xen/virtio-net.h
>  delete mode 100644 examples/vhost_xen/xen_vhost.h
>  delete mode 100644 examples/vhost_xen/xenstore_parse.c
>  delete mode 100644 lib/librte_eal/bsdapp/eal/include/exec-env/rte_dom0_common.h
>  delete mode 100644 lib/librte_eal/linuxapp/eal/eal_xen_memory.c
>  delete mode 100644 lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
>  delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/Makefile
>  delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/compat.h
>  delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h
>  delete mode 100644 lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c
> 
> -- 
> 2.7.4
> 
> 
> _______________________________________________
> Xen-devel mailing list
> Xen-devel@lists.xen.org
> https://lists.xen.org/xen-devel

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 1/6] example/vhost_xen: remove
  2017-08-30 18:10 ` Jianfeng Tan
  2017-09-04 14:14   ` [dpdk-dev] " Bruce Richardson
@ 2017-09-04 14:14   ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:14 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
	jerin.jacob, shahafs

On Wed, Aug 30, 2017 at 06:10:29PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Minor nit: checkpatch points out that the prefix should be "examples/..."
rather than "example/..."

Otherwise:
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 1/6] example/vhost_xen: remove
  2017-08-30 18:10 ` Jianfeng Tan
@ 2017-09-04 14:14   ` Bruce Richardson
  2017-09-04 14:14   ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:14 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, dev, john.mcnamara, oao.m.martins, thomas,
	xen-devel

On Wed, Aug 30, 2017 at 06:10:29PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>

Minor nit: checkpatch points out that the prefix should be "examples/..."
rather than "example/..."

Otherwise:
Acked-by: Bruce Richardson <bruce.richardson@intel.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/6] xen: remove xen dependency in app, examples, test
  2017-08-30 18:10 ` [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
  2017-09-04 14:24   ` [dpdk-dev] " Bruce Richardson
@ 2017-09-04 14:24   ` Bruce Richardson
  2017-09-04 14:51   ` [dpdk-dev] " Bruce Richardson
  2017-09-04 14:51   ` Bruce Richardson
  3 siblings, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:24 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
	jerin.jacob, shahafs

On Wed, Aug 30, 2017 at 06:10:31PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  app/test-pmd/testpmd.c              |  2 +-
>  examples/ip_pipeline/app.h          |  4 --
>  examples/ip_pipeline/config_parse.c | 19 ---------
>  examples/ip_pipeline/init.c         |  5 ---
>  examples/kni/main.c                 |  3 --
>  test/test/process.h                 | 10 -----
>  test/test/test.c                    |  4 --
>  test/test/test_eal_flags.c          | 81 -------------------------------------
>  8 files changed, 1 insertion(+), 127 deletions(-)
> 
> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> index f8d02ae..d9c785c 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -494,7 +494,7 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
>  		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
>  		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
>  
> -	/* if the former XEN allocation failed fall back to normal allocation */
> +	/* if the former allocation failed fall back to normal allocation */
>  	if (rte_mp == NULL) {
>  		if (mp_anon != 0) {
>  			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,

There is no former allocation here, so I think the previous patch, which
removed the #ifdef block should also remove this comment entirely, and
the "if (rte_mp == NULL)" too

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 3/6] xen: remove xen dependency in app, examples, test
  2017-08-30 18:10 ` [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
@ 2017-09-04 14:24   ` Bruce Richardson
  2017-09-04 14:24   ` Bruce Richardson
                     ` (2 subsequent siblings)
  3 siblings, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:24 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, dev, john.mcnamara, oao.m.martins, thomas,
	xen-devel

On Wed, Aug 30, 2017 at 06:10:31PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  app/test-pmd/testpmd.c              |  2 +-
>  examples/ip_pipeline/app.h          |  4 --
>  examples/ip_pipeline/config_parse.c | 19 ---------
>  examples/ip_pipeline/init.c         |  5 ---
>  examples/kni/main.c                 |  3 --
>  test/test/process.h                 | 10 -----
>  test/test/test.c                    |  4 --
>  test/test/test_eal_flags.c          | 81 -------------------------------------
>  8 files changed, 1 insertion(+), 127 deletions(-)
> 
> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> index f8d02ae..d9c785c 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -494,7 +494,7 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
>  		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
>  		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
>  
> -	/* if the former XEN allocation failed fall back to normal allocation */
> +	/* if the former allocation failed fall back to normal allocation */
>  	if (rte_mp == NULL) {
>  		if (mp_anon != 0) {
>  			rte_mp = rte_mempool_create_empty(pool_name, nb_mbuf,

There is no former allocation here, so I think the previous patch, which
removed the #ifdef block should also remove this comment entirely, and
the "if (rte_mp == NULL)" too


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 2/6] net/xenvirt: remove
  2017-08-30 18:10 ` Jianfeng Tan
@ 2017-09-04 14:25   ` Bruce Richardson
  2017-09-04 14:50     ` Bruce Richardson
  2017-09-04 14:50     ` [dpdk-dev] " Bruce Richardson
  2017-09-04 14:25   ` Bruce Richardson
  1 sibling, 2 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:25 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
	jerin.jacob, shahafs

On Wed, Aug 30, 2017 at 06:10:30PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  MAINTAINERS                                     |   2 -
>  app/test-pmd/Makefile                           |   4 -
>  app/test-pmd/testpmd.c                          |  12 -
>  config/common_base                              |   5 -
>  config/defconfig_arm-armv7a-linuxapp-gcc        |   1 -
>  doc/guides/nics/features/xenvirt.ini            |   6 -
>  drivers/net/Makefile                            |   2 -
>  drivers/net/xenvirt/Makefile                    |  57 --
>  drivers/net/xenvirt/rte_eth_xenvirt.c           | 766 ------------------------
>  drivers/net/xenvirt/rte_eth_xenvirt.h           |  61 --
>  drivers/net/xenvirt/rte_eth_xenvirt_version.map |   7 -
>  drivers/net/xenvirt/rte_mempool_gntalloc.c      | 295 ---------
>  drivers/net/xenvirt/rte_xen_lib.c               | 454 --------------
>  drivers/net/xenvirt/rte_xen_lib.h               | 116 ----
>  drivers/net/xenvirt/virtio_logs.h               |  70 ---
>  drivers/net/xenvirt/virtqueue.h                 | 273 ---------
>  mk/rte.app.mk                                   |   1 -
>  pkg/dpdk.spec                                   |   3 -
>  18 files changed, 2135 deletions(-)
>  delete mode 100644 doc/guides/nics/features/xenvirt.ini
>  delete mode 100644 drivers/net/xenvirt/Makefile
>  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
>  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
>  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
>  delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
>  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
>  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
>  delete mode 100644 drivers/net/xenvirt/virtio_logs.h
>  delete mode 100644 drivers/net/xenvirt/virtqueue.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fe6c6db..003e72e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -194,9 +194,7 @@ M: Jianfeng Tan <jianfeng.tan@intel.com>
>  F: lib/librte_eal/linuxapp/xen_dom0/
>  F: lib/librte_eal/linuxapp/eal/*xen*
>  F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
> -F: drivers/net/xenvirt/
>  F: doc/guides/xen/
> -F: doc/guides/nics/features/xenvirt.ini
>  
>  FreeBSD EAL (with overlaps)
>  M: Bruce Richardson <bruce.richardson@intel.com>
> diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
> index c36be19..b6e80dd 100644
> --- a/app/test-pmd/Makefile
> +++ b/app/test-pmd/Makefile
> @@ -77,10 +77,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
>  LDLIBS += -lrte_pmd_bnxt
>  endif
>  
> -ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
> -LDLIBS += -lrte_pmd_xenvirt
> -endif
> -
>  endif
>  
>  CFLAGS_cmdline.o := -D_GNU_SOURCE
> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> index 7d40139..f8d02ae 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -76,9 +76,6 @@
>  #ifdef RTE_LIBRTE_IXGBE_PMD
>  #include <rte_pmd_ixgbe.h>
>  #endif
> -#ifdef RTE_LIBRTE_PMD_XENVIRT
> -#include <rte_eth_xenvirt.h>
> -#endif
>  #ifdef RTE_LIBRTE_PDUMP
>  #include <rte_pdump.h>
>  #endif
> @@ -497,15 +494,6 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
>  		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
>  		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
>  
> -#ifdef RTE_LIBRTE_PMD_XENVIRT
> -	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
> -		(unsigned) mb_mempool_cache,
> -		sizeof(struct rte_pktmbuf_pool_private),
> -		rte_pktmbuf_pool_init, NULL,
> -		rte_pktmbuf_init, NULL,
> -		socket_id, 0);
> -#endif
> -
>  	/* if the former XEN allocation failed fall back to normal allocation */
>  	if (rte_mp == NULL) {

Remove comment and if condition, as there is no way the the variable can
be non-null now.

/Bruce

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 2/6] net/xenvirt: remove
  2017-08-30 18:10 ` Jianfeng Tan
  2017-09-04 14:25   ` Bruce Richardson
@ 2017-09-04 14:25   ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:25 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, dev, john.mcnamara, oao.m.martins, thomas,
	xen-devel

On Wed, Aug 30, 2017 at 06:10:30PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  MAINTAINERS                                     |   2 -
>  app/test-pmd/Makefile                           |   4 -
>  app/test-pmd/testpmd.c                          |  12 -
>  config/common_base                              |   5 -
>  config/defconfig_arm-armv7a-linuxapp-gcc        |   1 -
>  doc/guides/nics/features/xenvirt.ini            |   6 -
>  drivers/net/Makefile                            |   2 -
>  drivers/net/xenvirt/Makefile                    |  57 --
>  drivers/net/xenvirt/rte_eth_xenvirt.c           | 766 ------------------------
>  drivers/net/xenvirt/rte_eth_xenvirt.h           |  61 --
>  drivers/net/xenvirt/rte_eth_xenvirt_version.map |   7 -
>  drivers/net/xenvirt/rte_mempool_gntalloc.c      | 295 ---------
>  drivers/net/xenvirt/rte_xen_lib.c               | 454 --------------
>  drivers/net/xenvirt/rte_xen_lib.h               | 116 ----
>  drivers/net/xenvirt/virtio_logs.h               |  70 ---
>  drivers/net/xenvirt/virtqueue.h                 | 273 ---------
>  mk/rte.app.mk                                   |   1 -
>  pkg/dpdk.spec                                   |   3 -
>  18 files changed, 2135 deletions(-)
>  delete mode 100644 doc/guides/nics/features/xenvirt.ini
>  delete mode 100644 drivers/net/xenvirt/Makefile
>  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
>  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
>  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
>  delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
>  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
>  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
>  delete mode 100644 drivers/net/xenvirt/virtio_logs.h
>  delete mode 100644 drivers/net/xenvirt/virtqueue.h
> 
> diff --git a/MAINTAINERS b/MAINTAINERS
> index fe6c6db..003e72e 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -194,9 +194,7 @@ M: Jianfeng Tan <jianfeng.tan@intel.com>
>  F: lib/librte_eal/linuxapp/xen_dom0/
>  F: lib/librte_eal/linuxapp/eal/*xen*
>  F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
> -F: drivers/net/xenvirt/
>  F: doc/guides/xen/
> -F: doc/guides/nics/features/xenvirt.ini
>  
>  FreeBSD EAL (with overlaps)
>  M: Bruce Richardson <bruce.richardson@intel.com>
> diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
> index c36be19..b6e80dd 100644
> --- a/app/test-pmd/Makefile
> +++ b/app/test-pmd/Makefile
> @@ -77,10 +77,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
>  LDLIBS += -lrte_pmd_bnxt
>  endif
>  
> -ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
> -LDLIBS += -lrte_pmd_xenvirt
> -endif
> -
>  endif
>  
>  CFLAGS_cmdline.o := -D_GNU_SOURCE
> diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> index 7d40139..f8d02ae 100644
> --- a/app/test-pmd/testpmd.c
> +++ b/app/test-pmd/testpmd.c
> @@ -76,9 +76,6 @@
>  #ifdef RTE_LIBRTE_IXGBE_PMD
>  #include <rte_pmd_ixgbe.h>
>  #endif
> -#ifdef RTE_LIBRTE_PMD_XENVIRT
> -#include <rte_eth_xenvirt.h>
> -#endif
>  #ifdef RTE_LIBRTE_PDUMP
>  #include <rte_pdump.h>
>  #endif
> @@ -497,15 +494,6 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
>  		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
>  		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
>  
> -#ifdef RTE_LIBRTE_PMD_XENVIRT
> -	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
> -		(unsigned) mb_mempool_cache,
> -		sizeof(struct rte_pktmbuf_pool_private),
> -		rte_pktmbuf_pool_init, NULL,
> -		rte_pktmbuf_init, NULL,
> -		socket_id, 0);
> -#endif
> -
>  	/* if the former XEN allocation failed fall back to normal allocation */
>  	if (rte_mp == NULL) {

Remove comment and if condition, as there is no way the the variable can
be non-null now.

/Bruce

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 5/6] eal: remove xen dom0 support
  2017-08-30 18:10 ` [PATCH 5/6] eal: remove xen dom0 support Jianfeng Tan
  2017-09-04 14:43   ` [dpdk-dev] " Bruce Richardson
@ 2017-09-04 14:43   ` Bruce Richardson
  2017-09-04 14:49     ` Bruce Richardson
  2017-09-04 14:49     ` Bruce Richardson
  1 sibling, 2 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:43 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, xen-devel, thomas, john.mcnamara, joao.m.martins,
	jerin.jacob, shahafs

On Wed, Aug 30, 2017 at 06:10:33PM +0000, Jianfeng Tan wrote:
> We remove xen-specific code in EAL, including the option --xen-dom0,
> memory initialization code, compiling dependency, etc.
> 
> Besides, related documents are removed or updated.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  MAINTAINERS                                        |   7 -
>  config/common_base                                 |   5 -
>  doc/guides/index.rst                               |   1 -
>  doc/guides/linux_gsg/build_sample_apps.rst         |   5 +-
>  doc/guides/linux_gsg/sys_reqs.rst                  |  53 --
>  doc/guides/prog_guide/source_org.rst               |   1 -
>  doc/guides/rel_notes/deprecation.rst               |   3 -
>  doc/guides/rel_notes/release_17_11.rst             |  12 +
>  doc/guides/testpmd_app_ug/run_app.rst              |   4 -
>  doc/guides/xen/img/dpdk_xen_pkt_switch.png         | Bin 163842 -> 0 bytes
>  doc/guides/xen/img/grant_refs.png                  | Bin 6405 -> 0 bytes
>  doc/guides/xen/img/grant_table.png                 | Bin 96762 -> 0 bytes
>  doc/guides/xen/index.rst                           |  38 -
>  doc/guides/xen/pkt_switch.rst                      | 470 -------------
>  .../bsdapp/eal/include/exec-env/rte_dom0_common.h  | 107 ---
>  lib/librte_eal/common/eal_common_options.c         |   3 -
>  lib/librte_eal/common/eal_internal_cfg.h           |   1 -
>  lib/librte_eal/common/eal_options.h                |   2 -
>  lib/librte_eal/common/include/rte_memory.h         |  66 --
>  lib/librte_eal/linuxapp/Makefile                   |   2 -
>  lib/librte_eal/linuxapp/eal/Makefile               |   5 +-
>  lib/librte_eal/linuxapp/eal/eal.c                  |  24 -
>  lib/librte_eal/linuxapp/eal/eal_memory.c           |  56 --
>  lib/librte_eal/linuxapp/eal/eal_xen_memory.c       | 381 ----------
>  .../eal/include/exec-env/rte_dom0_common.h         | 108 ---
>  lib/librte_eal/linuxapp/igb_uio/igb_uio.c          |  54 --
>  lib/librte_eal/linuxapp/xen_dom0/Makefile          |  53 --
>  lib/librte_eal/linuxapp/xen_dom0/compat.h          |  15 -
>  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h     | 107 ---
>  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c    | 780 ---------------------
>  pkg/dpdk.spec                                      |   3 -

The xen functions that were removed are still listed in the linux/bsd 
version.map files. Not an ABI versioning expert, but I believe they
should be removed as they are no longer present.

Also, I spot a reference to xen still in
doc/guides/contributing/documentation.rst.

/Bruce

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
  2017-08-30 18:10 ` [PATCH 5/6] eal: remove xen dom0 support Jianfeng Tan
@ 2017-09-04 14:43   ` Bruce Richardson
  2017-09-04 14:43   ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:43 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, dev, john.mcnamara, thomas, xen-devel,
	joao.m.martins

On Wed, Aug 30, 2017 at 06:10:33PM +0000, Jianfeng Tan wrote:
> We remove xen-specific code in EAL, including the option --xen-dom0,
> memory initialization code, compiling dependency, etc.
> 
> Besides, related documents are removed or updated.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
>  MAINTAINERS                                        |   7 -
>  config/common_base                                 |   5 -
>  doc/guides/index.rst                               |   1 -
>  doc/guides/linux_gsg/build_sample_apps.rst         |   5 +-
>  doc/guides/linux_gsg/sys_reqs.rst                  |  53 --
>  doc/guides/prog_guide/source_org.rst               |   1 -
>  doc/guides/rel_notes/deprecation.rst               |   3 -
>  doc/guides/rel_notes/release_17_11.rst             |  12 +
>  doc/guides/testpmd_app_ug/run_app.rst              |   4 -
>  doc/guides/xen/img/dpdk_xen_pkt_switch.png         | Bin 163842 -> 0 bytes
>  doc/guides/xen/img/grant_refs.png                  | Bin 6405 -> 0 bytes
>  doc/guides/xen/img/grant_table.png                 | Bin 96762 -> 0 bytes
>  doc/guides/xen/index.rst                           |  38 -
>  doc/guides/xen/pkt_switch.rst                      | 470 -------------
>  .../bsdapp/eal/include/exec-env/rte_dom0_common.h  | 107 ---
>  lib/librte_eal/common/eal_common_options.c         |   3 -
>  lib/librte_eal/common/eal_internal_cfg.h           |   1 -
>  lib/librte_eal/common/eal_options.h                |   2 -
>  lib/librte_eal/common/include/rte_memory.h         |  66 --
>  lib/librte_eal/linuxapp/Makefile                   |   2 -
>  lib/librte_eal/linuxapp/eal/Makefile               |   5 +-
>  lib/librte_eal/linuxapp/eal/eal.c                  |  24 -
>  lib/librte_eal/linuxapp/eal/eal_memory.c           |  56 --
>  lib/librte_eal/linuxapp/eal/eal_xen_memory.c       | 381 ----------
>  .../eal/include/exec-env/rte_dom0_common.h         | 108 ---
>  lib/librte_eal/linuxapp/igb_uio/igb_uio.c          |  54 --
>  lib/librte_eal/linuxapp/xen_dom0/Makefile          |  53 --
>  lib/librte_eal/linuxapp/xen_dom0/compat.h          |  15 -
>  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h     | 107 ---
>  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c    | 780 ---------------------
>  pkg/dpdk.spec                                      |   3 -

The xen functions that were removed are still listed in the linux/bsd 
version.map files. Not an ABI versioning expert, but I believe they
should be removed as they are no longer present.

Also, I spot a reference to xen still in
doc/guides/contributing/documentation.rst.

/Bruce

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 5/6] eal: remove xen dom0 support
  2017-09-04 14:43   ` Bruce Richardson
@ 2017-09-04 14:49     ` Bruce Richardson
  2017-09-05  3:41       ` Tan, Jianfeng
  2017-09-05  3:41       ` [dpdk-dev] " Tan, Jianfeng
  2017-09-04 14:49     ` Bruce Richardson
  1 sibling, 2 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:49 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, xen-devel, thomas, john.mcnamara, joao.m.martins,
	jerin.jacob, shahafs

On Mon, Sep 04, 2017 at 03:43:02PM +0100, Bruce Richardson wrote:
> On Wed, Aug 30, 2017 at 06:10:33PM +0000, Jianfeng Tan wrote:
> > We remove xen-specific code in EAL, including the option --xen-dom0,
> > memory initialization code, compiling dependency, etc.
> > 
> > Besides, related documents are removed or updated.
> > 
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >  MAINTAINERS                                        |   7 -
> >  config/common_base                                 |   5 -
> >  doc/guides/index.rst                               |   1 -
> >  doc/guides/linux_gsg/build_sample_apps.rst         |   5 +-
> >  doc/guides/linux_gsg/sys_reqs.rst                  |  53 --
> >  doc/guides/prog_guide/source_org.rst               |   1 -
> >  doc/guides/rel_notes/deprecation.rst               |   3 -
> >  doc/guides/rel_notes/release_17_11.rst             |  12 +
> >  doc/guides/testpmd_app_ug/run_app.rst              |   4 -
> >  doc/guides/xen/img/dpdk_xen_pkt_switch.png         | Bin 163842 -> 0 bytes
> >  doc/guides/xen/img/grant_refs.png                  | Bin 6405 -> 0 bytes
> >  doc/guides/xen/img/grant_table.png                 | Bin 96762 -> 0 bytes
> >  doc/guides/xen/index.rst                           |  38 -
> >  doc/guides/xen/pkt_switch.rst                      | 470 -------------
> >  .../bsdapp/eal/include/exec-env/rte_dom0_common.h  | 107 ---
> >  lib/librte_eal/common/eal_common_options.c         |   3 -
> >  lib/librte_eal/common/eal_internal_cfg.h           |   1 -
> >  lib/librte_eal/common/eal_options.h                |   2 -
> >  lib/librte_eal/common/include/rte_memory.h         |  66 --
> >  lib/librte_eal/linuxapp/Makefile                   |   2 -
> >  lib/librte_eal/linuxapp/eal/Makefile               |   5 +-
> >  lib/librte_eal/linuxapp/eal/eal.c                  |  24 -
> >  lib/librte_eal/linuxapp/eal/eal_memory.c           |  56 --
> >  lib/librte_eal/linuxapp/eal/eal_xen_memory.c       | 381 ----------
> >  .../eal/include/exec-env/rte_dom0_common.h         | 108 ---
> >  lib/librte_eal/linuxapp/igb_uio/igb_uio.c          |  54 --
> >  lib/librte_eal/linuxapp/xen_dom0/Makefile          |  53 --
> >  lib/librte_eal/linuxapp/xen_dom0/compat.h          |  15 -
> >  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h     | 107 ---
> >  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c    | 780 ---------------------
> >  pkg/dpdk.spec                                      |   3 -
> 
> The xen functions that were removed are still listed in the linux/bsd 
> version.map files. Not an ABI versioning expert, but I believe they
> should be removed as they are no longer present.
>
Reading the contributors guide section on ABI, specifically
http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-an-entire-abi-version
it seems like we should collapse down the versions to a single one
following the function removal, and also increment the whole library so
version.

/Bruce

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
  2017-09-04 14:43   ` Bruce Richardson
  2017-09-04 14:49     ` Bruce Richardson
@ 2017-09-04 14:49     ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:49 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, dev, john.mcnamara, thomas, xen-devel,
	joao.m.martins

On Mon, Sep 04, 2017 at 03:43:02PM +0100, Bruce Richardson wrote:
> On Wed, Aug 30, 2017 at 06:10:33PM +0000, Jianfeng Tan wrote:
> > We remove xen-specific code in EAL, including the option --xen-dom0,
> > memory initialization code, compiling dependency, etc.
> > 
> > Besides, related documents are removed or updated.
> > 
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >  MAINTAINERS                                        |   7 -
> >  config/common_base                                 |   5 -
> >  doc/guides/index.rst                               |   1 -
> >  doc/guides/linux_gsg/build_sample_apps.rst         |   5 +-
> >  doc/guides/linux_gsg/sys_reqs.rst                  |  53 --
> >  doc/guides/prog_guide/source_org.rst               |   1 -
> >  doc/guides/rel_notes/deprecation.rst               |   3 -
> >  doc/guides/rel_notes/release_17_11.rst             |  12 +
> >  doc/guides/testpmd_app_ug/run_app.rst              |   4 -
> >  doc/guides/xen/img/dpdk_xen_pkt_switch.png         | Bin 163842 -> 0 bytes
> >  doc/guides/xen/img/grant_refs.png                  | Bin 6405 -> 0 bytes
> >  doc/guides/xen/img/grant_table.png                 | Bin 96762 -> 0 bytes
> >  doc/guides/xen/index.rst                           |  38 -
> >  doc/guides/xen/pkt_switch.rst                      | 470 -------------
> >  .../bsdapp/eal/include/exec-env/rte_dom0_common.h  | 107 ---
> >  lib/librte_eal/common/eal_common_options.c         |   3 -
> >  lib/librte_eal/common/eal_internal_cfg.h           |   1 -
> >  lib/librte_eal/common/eal_options.h                |   2 -
> >  lib/librte_eal/common/include/rte_memory.h         |  66 --
> >  lib/librte_eal/linuxapp/Makefile                   |   2 -
> >  lib/librte_eal/linuxapp/eal/Makefile               |   5 +-
> >  lib/librte_eal/linuxapp/eal/eal.c                  |  24 -
> >  lib/librte_eal/linuxapp/eal/eal_memory.c           |  56 --
> >  lib/librte_eal/linuxapp/eal/eal_xen_memory.c       | 381 ----------
> >  .../eal/include/exec-env/rte_dom0_common.h         | 108 ---
> >  lib/librte_eal/linuxapp/igb_uio/igb_uio.c          |  54 --
> >  lib/librte_eal/linuxapp/xen_dom0/Makefile          |  53 --
> >  lib/librte_eal/linuxapp/xen_dom0/compat.h          |  15 -
> >  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h     | 107 ---
> >  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c    | 780 ---------------------
> >  pkg/dpdk.spec                                      |   3 -
> 
> The xen functions that were removed are still listed in the linux/bsd 
> version.map files. Not an ABI versioning expert, but I believe they
> should be removed as they are no longer present.
>
Reading the contributors guide section on ABI, specifically
http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-an-entire-abi-version
it seems like we should collapse down the versions to a single one
following the function removal, and also increment the whole library so
version.

/Bruce

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 2/6] net/xenvirt: remove
  2017-09-04 14:25   ` Bruce Richardson
@ 2017-09-04 14:50     ` Bruce Richardson
  2017-09-04 14:50     ` [dpdk-dev] " Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:50 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
	jerin.jacob, shahafs

On Mon, Sep 04, 2017 at 03:25:48PM +0100, Bruce Richardson wrote:
> On Wed, Aug 30, 2017 at 06:10:30PM +0000, Jianfeng Tan wrote:
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >  MAINTAINERS                                     |   2 -
> >  app/test-pmd/Makefile                           |   4 -
> >  app/test-pmd/testpmd.c                          |  12 -
> >  config/common_base                              |   5 -
> >  config/defconfig_arm-armv7a-linuxapp-gcc        |   1 -
> >  doc/guides/nics/features/xenvirt.ini            |   6 -
> >  drivers/net/Makefile                            |   2 -
> >  drivers/net/xenvirt/Makefile                    |  57 --
> >  drivers/net/xenvirt/rte_eth_xenvirt.c           | 766 ------------------------
> >  drivers/net/xenvirt/rte_eth_xenvirt.h           |  61 --
> >  drivers/net/xenvirt/rte_eth_xenvirt_version.map |   7 -
> >  drivers/net/xenvirt/rte_mempool_gntalloc.c      | 295 ---------
> >  drivers/net/xenvirt/rte_xen_lib.c               | 454 --------------
> >  drivers/net/xenvirt/rte_xen_lib.h               | 116 ----
> >  drivers/net/xenvirt/virtio_logs.h               |  70 ---
> >  drivers/net/xenvirt/virtqueue.h                 | 273 ---------
> >  mk/rte.app.mk                                   |   1 -
> >  pkg/dpdk.spec                                   |   3 -
> >  18 files changed, 2135 deletions(-)
> >  delete mode 100644 doc/guides/nics/features/xenvirt.ini
> >  delete mode 100644 drivers/net/xenvirt/Makefile
> >  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
> >  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
> >  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
> >  delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
> >  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
> >  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
> >  delete mode 100644 drivers/net/xenvirt/virtio_logs.h
> >  delete mode 100644 drivers/net/xenvirt/virtqueue.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fe6c6db..003e72e 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -194,9 +194,7 @@ M: Jianfeng Tan <jianfeng.tan@intel.com>
> >  F: lib/librte_eal/linuxapp/xen_dom0/
> >  F: lib/librte_eal/linuxapp/eal/*xen*
> >  F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
> > -F: drivers/net/xenvirt/
> >  F: doc/guides/xen/
> > -F: doc/guides/nics/features/xenvirt.ini
> >  
> >  FreeBSD EAL (with overlaps)
> >  M: Bruce Richardson <bruce.richardson@intel.com>
> > diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
> > index c36be19..b6e80dd 100644
> > --- a/app/test-pmd/Makefile
> > +++ b/app/test-pmd/Makefile
> > @@ -77,10 +77,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
> >  LDLIBS += -lrte_pmd_bnxt
> >  endif
> >  
> > -ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
> > -LDLIBS += -lrte_pmd_xenvirt
> > -endif
> > -
> >  endif
> >  
> >  CFLAGS_cmdline.o := -D_GNU_SOURCE
> > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> > index 7d40139..f8d02ae 100644
> > --- a/app/test-pmd/testpmd.c
> > +++ b/app/test-pmd/testpmd.c
> > @@ -76,9 +76,6 @@
> >  #ifdef RTE_LIBRTE_IXGBE_PMD
> >  #include <rte_pmd_ixgbe.h>
> >  #endif
> > -#ifdef RTE_LIBRTE_PMD_XENVIRT
> > -#include <rte_eth_xenvirt.h>
> > -#endif
> >  #ifdef RTE_LIBRTE_PDUMP
> >  #include <rte_pdump.h>
> >  #endif
> > @@ -497,15 +494,6 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
> >  		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
> >  		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
> >  
> > -#ifdef RTE_LIBRTE_PMD_XENVIRT
> > -	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
> > -		(unsigned) mb_mempool_cache,
> > -		sizeof(struct rte_pktmbuf_pool_private),
> > -		rte_pktmbuf_pool_init, NULL,
> > -		rte_pktmbuf_init, NULL,
> > -		socket_id, 0);
> > -#endif
> > -
> >  	/* if the former XEN allocation failed fall back to normal allocation */
> >  	if (rte_mp == NULL) {
> 
> Remove comment and if condition, as there is no way the the variable can
> be non-null now.
>

With this change:

Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 2/6] net/xenvirt: remove
  2017-09-04 14:25   ` Bruce Richardson
  2017-09-04 14:50     ` Bruce Richardson
@ 2017-09-04 14:50     ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:50 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, dev, john.mcnamara, oao.m.martins, thomas,
	xen-devel

On Mon, Sep 04, 2017 at 03:25:48PM +0100, Bruce Richardson wrote:
> On Wed, Aug 30, 2017 at 06:10:30PM +0000, Jianfeng Tan wrote:
> > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > ---
> >  MAINTAINERS                                     |   2 -
> >  app/test-pmd/Makefile                           |   4 -
> >  app/test-pmd/testpmd.c                          |  12 -
> >  config/common_base                              |   5 -
> >  config/defconfig_arm-armv7a-linuxapp-gcc        |   1 -
> >  doc/guides/nics/features/xenvirt.ini            |   6 -
> >  drivers/net/Makefile                            |   2 -
> >  drivers/net/xenvirt/Makefile                    |  57 --
> >  drivers/net/xenvirt/rte_eth_xenvirt.c           | 766 ------------------------
> >  drivers/net/xenvirt/rte_eth_xenvirt.h           |  61 --
> >  drivers/net/xenvirt/rte_eth_xenvirt_version.map |   7 -
> >  drivers/net/xenvirt/rte_mempool_gntalloc.c      | 295 ---------
> >  drivers/net/xenvirt/rte_xen_lib.c               | 454 --------------
> >  drivers/net/xenvirt/rte_xen_lib.h               | 116 ----
> >  drivers/net/xenvirt/virtio_logs.h               |  70 ---
> >  drivers/net/xenvirt/virtqueue.h                 | 273 ---------
> >  mk/rte.app.mk                                   |   1 -
> >  pkg/dpdk.spec                                   |   3 -
> >  18 files changed, 2135 deletions(-)
> >  delete mode 100644 doc/guides/nics/features/xenvirt.ini
> >  delete mode 100644 drivers/net/xenvirt/Makefile
> >  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.c
> >  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt.h
> >  delete mode 100644 drivers/net/xenvirt/rte_eth_xenvirt_version.map
> >  delete mode 100644 drivers/net/xenvirt/rte_mempool_gntalloc.c
> >  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.c
> >  delete mode 100644 drivers/net/xenvirt/rte_xen_lib.h
> >  delete mode 100644 drivers/net/xenvirt/virtio_logs.h
> >  delete mode 100644 drivers/net/xenvirt/virtqueue.h
> > 
> > diff --git a/MAINTAINERS b/MAINTAINERS
> > index fe6c6db..003e72e 100644
> > --- a/MAINTAINERS
> > +++ b/MAINTAINERS
> > @@ -194,9 +194,7 @@ M: Jianfeng Tan <jianfeng.tan@intel.com>
> >  F: lib/librte_eal/linuxapp/xen_dom0/
> >  F: lib/librte_eal/linuxapp/eal/*xen*
> >  F: lib/librte_eal/linuxapp/eal/include/exec-env/rte_dom0_common.h
> > -F: drivers/net/xenvirt/
> >  F: doc/guides/xen/
> > -F: doc/guides/nics/features/xenvirt.ini
> >  
> >  FreeBSD EAL (with overlaps)
> >  M: Bruce Richardson <bruce.richardson@intel.com>
> > diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
> > index c36be19..b6e80dd 100644
> > --- a/app/test-pmd/Makefile
> > +++ b/app/test-pmd/Makefile
> > @@ -77,10 +77,6 @@ ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
> >  LDLIBS += -lrte_pmd_bnxt
> >  endif
> >  
> > -ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
> > -LDLIBS += -lrte_pmd_xenvirt
> > -endif
> > -
> >  endif
> >  
> >  CFLAGS_cmdline.o := -D_GNU_SOURCE
> > diff --git a/app/test-pmd/testpmd.c b/app/test-pmd/testpmd.c
> > index 7d40139..f8d02ae 100644
> > --- a/app/test-pmd/testpmd.c
> > +++ b/app/test-pmd/testpmd.c
> > @@ -76,9 +76,6 @@
> >  #ifdef RTE_LIBRTE_IXGBE_PMD
> >  #include <rte_pmd_ixgbe.h>
> >  #endif
> > -#ifdef RTE_LIBRTE_PMD_XENVIRT
> > -#include <rte_eth_xenvirt.h>
> > -#endif
> >  #ifdef RTE_LIBRTE_PDUMP
> >  #include <rte_pdump.h>
> >  #endif
> > @@ -497,15 +494,6 @@ mbuf_pool_create(uint16_t mbuf_seg_size, unsigned nb_mbuf,
> >  		"create a new mbuf pool <%s>: n=%u, size=%u, socket=%u\n",
> >  		pool_name, nb_mbuf, mbuf_seg_size, socket_id);
> >  
> > -#ifdef RTE_LIBRTE_PMD_XENVIRT
> > -	rte_mp = rte_mempool_gntalloc_create(pool_name, nb_mbuf, mb_size,
> > -		(unsigned) mb_mempool_cache,
> > -		sizeof(struct rte_pktmbuf_pool_private),
> > -		rte_pktmbuf_pool_init, NULL,
> > -		rte_pktmbuf_init, NULL,
> > -		socket_id, 0);
> > -#endif
> > -
> >  	/* if the former XEN allocation failed fall back to normal allocation */
> >  	if (rte_mp == NULL) {
> 
> Remove comment and if condition, as there is no way the the variable can
> be non-null now.
>

With this change:

Acked-by: Bruce Richardson <bruce.richardson@intel.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 3/6] xen: remove xen dependency in app, examples, test
  2017-08-30 18:10 ` [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
                     ` (2 preceding siblings ...)
  2017-09-04 14:51   ` [dpdk-dev] " Bruce Richardson
@ 2017-09-04 14:51   ` Bruce Richardson
  3 siblings, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:51 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, xen-devel, thomas, john.mcnamara, joao.m.martins,
	jerin.jacob, shahafs

On Wed, Aug 30, 2017 at 06:10:31PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 3/6] xen: remove xen dependency in app, examples, test
  2017-08-30 18:10 ` [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
  2017-09-04 14:24   ` [dpdk-dev] " Bruce Richardson
  2017-09-04 14:24   ` Bruce Richardson
@ 2017-09-04 14:51   ` Bruce Richardson
  2017-09-04 14:51   ` Bruce Richardson
  3 siblings, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:51 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, dev, john.mcnamara, thomas, xen-devel,
	joao.m.martins

On Wed, Aug 30, 2017 at 06:10:31PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool
  2017-08-30 18:10 ` [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool Jianfeng Tan
  2017-09-04 14:51   ` [dpdk-dev] " Bruce Richardson
@ 2017-09-04 14:51   ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:51 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, xen-devel, thomas, john.mcnamara, oao.m.martins,
	jerin.jacob, shahafs

On Wed, Aug 30, 2017 at 06:10:32PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool
  2017-08-30 18:10 ` [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool Jianfeng Tan
@ 2017-09-04 14:51   ` Bruce Richardson
  2017-09-04 14:51   ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:51 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, dev, john.mcnamara, oao.m.martins, thomas,
	xen-devel

On Wed, Aug 30, 2017 at 06:10:32PM +0000, Jianfeng Tan wrote:
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> ---
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 6/6] eal: remove API rte_mem_phy2mch
  2017-08-30 18:10 ` [PATCH 6/6] eal: remove API rte_mem_phy2mch Jianfeng Tan
  2017-09-04 14:52   ` [dpdk-dev] " Bruce Richardson
@ 2017-09-04 14:52   ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:52 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: dev, xen-devel, thomas, john.mcnamara, joao.m.martins,
	jerin.jacob, shahafs

On Wed, Aug 30, 2017 at 06:10:34PM +0000, Jianfeng Tan wrote:
> Previously, to get MFN address in dom0, this API is a wrapper to
> obtain the "physical address".
> 
> As we removed xen dom0 support, this API is not necessary.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 6/6] eal: remove API rte_mem_phy2mch
  2017-08-30 18:10 ` [PATCH 6/6] eal: remove API rte_mem_phy2mch Jianfeng Tan
@ 2017-09-04 14:52   ` Bruce Richardson
  2017-09-04 14:52   ` Bruce Richardson
  1 sibling, 0 replies; 38+ messages in thread
From: Bruce Richardson @ 2017-09-04 14:52 UTC (permalink / raw)
  To: Jianfeng Tan
  Cc: jerin.jacob, shahafs, dev, john.mcnamara, thomas, xen-devel,
	joao.m.martins

On Wed, Aug 30, 2017 at 06:10:34PM +0000, Jianfeng Tan wrote:
> Previously, to get MFN address in dom0, this API is a wrapper to
> obtain the "physical address".
> 
> As we removed xen dom0 support, this API is not necessary.
> 
> Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
Acked-by: Bruce Richardson <bruce.richardson@intel.com>


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 5/6] eal: remove xen dom0 support
  2017-09-04 14:49     ` Bruce Richardson
@ 2017-09-05  3:41       ` Tan, Jianfeng
  2017-09-05  7:31         ` [dpdk-dev] " Thomas Monjalon
  2017-09-05  7:31         ` Thomas Monjalon
  2017-09-05  3:41       ` [dpdk-dev] " Tan, Jianfeng
  1 sibling, 2 replies; 38+ messages in thread
From: Tan, Jianfeng @ 2017-09-05  3:41 UTC (permalink / raw)
  To: Richardson, Bruce
  Cc: dev, xen-devel, thomas, Mcnamara, John, joao.m.martins,
	jerin.jacob, shahafs



> -----Original Message-----
> From: Richardson, Bruce
> Sent: Monday, September 4, 2017 10:49 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; xen-devel@lists.xenproject.org; thomas@monjalon.net;
> Mcnamara, John; joao.m.martins@oracle.com;
> jerin.jacob@caviumnetworks.com; shahafs@mellanox.com
> Subject: Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
> 
> On Mon, Sep 04, 2017 at 03:43:02PM +0100, Bruce Richardson wrote:
> > On Wed, Aug 30, 2017 at 06:10:33PM +0000, Jianfeng Tan wrote:
> > > We remove xen-specific code in EAL, including the option --xen-dom0,
> > > memory initialization code, compiling dependency, etc.
> > >
> > > Besides, related documents are removed or updated.
> > >
> > > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > > ---
> > >  MAINTAINERS                                        |   7 -
> > >  config/common_base                                 |   5 -
> > >  doc/guides/index.rst                               |   1 -
> > >  doc/guides/linux_gsg/build_sample_apps.rst         |   5 +-
> > >  doc/guides/linux_gsg/sys_reqs.rst                  |  53 --
> > >  doc/guides/prog_guide/source_org.rst               |   1 -
> > >  doc/guides/rel_notes/deprecation.rst               |   3 -
> > >  doc/guides/rel_notes/release_17_11.rst             |  12 +
> > >  doc/guides/testpmd_app_ug/run_app.rst              |   4 -
> > >  doc/guides/xen/img/dpdk_xen_pkt_switch.png         | Bin 163842 -> 0
> bytes
> > >  doc/guides/xen/img/grant_refs.png                  | Bin 6405 -> 0 bytes
> > >  doc/guides/xen/img/grant_table.png                 | Bin 96762 -> 0 bytes
> > >  doc/guides/xen/index.rst                           |  38 -
> > >  doc/guides/xen/pkt_switch.rst                      | 470 -------------
> > >  .../bsdapp/eal/include/exec-env/rte_dom0_common.h  | 107 ---
> > >  lib/librte_eal/common/eal_common_options.c         |   3 -
> > >  lib/librte_eal/common/eal_internal_cfg.h           |   1 -
> > >  lib/librte_eal/common/eal_options.h                |   2 -
> > >  lib/librte_eal/common/include/rte_memory.h         |  66 --
> > >  lib/librte_eal/linuxapp/Makefile                   |   2 -
> > >  lib/librte_eal/linuxapp/eal/Makefile               |   5 +-
> > >  lib/librte_eal/linuxapp/eal/eal.c                  |  24 -
> > >  lib/librte_eal/linuxapp/eal/eal_memory.c           |  56 --
> > >  lib/librte_eal/linuxapp/eal/eal_xen_memory.c       | 381 ----------
> > >  .../eal/include/exec-env/rte_dom0_common.h         | 108 ---
> > >  lib/librte_eal/linuxapp/igb_uio/igb_uio.c          |  54 --
> > >  lib/librte_eal/linuxapp/xen_dom0/Makefile          |  53 --
> > >  lib/librte_eal/linuxapp/xen_dom0/compat.h          |  15 -
> > >  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h     | 107 ---
> > >  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c    | 780 --------------
> -------
> > >  pkg/dpdk.spec                                      |   3 -
> >
> > The xen functions that were removed are still listed in the linux/bsd
> > version.map files. Not an ABI versioning expert, but I believe they
> > should be removed as they are no longer present.
> >
> Reading the contributors guide section on ABI, specifically
> http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-an-
> entire-abi-version
> it seems like we should collapse down the versions to a single one
> following the function removal, and also increment the whole library so
> version.

So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change it in below way?

DPDK_2.1 {
        {APIs in DPDK_2.0 except xen APIs}
        ...
};

DPDK_16.04 {
        {APIs in DPDK_2.1 except xen APIs}
        ...
} DPDK_2.1;

DPDK_16.07 {
        ...
} DPDK_16.04;
...

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
  2017-09-04 14:49     ` Bruce Richardson
  2017-09-05  3:41       ` Tan, Jianfeng
@ 2017-09-05  3:41       ` Tan, Jianfeng
  1 sibling, 0 replies; 38+ messages in thread
From: Tan, Jianfeng @ 2017-09-05  3:41 UTC (permalink / raw)
  To: Richardson, Bruce
  Cc: jerin.jacob, shahafs, dev, Mcnamara, John, thomas, xen-devel,
	joao.m.martins



> -----Original Message-----
> From: Richardson, Bruce
> Sent: Monday, September 4, 2017 10:49 PM
> To: Tan, Jianfeng
> Cc: dev@dpdk.org; xen-devel@lists.xenproject.org; thomas@monjalon.net;
> Mcnamara, John; joao.m.martins@oracle.com;
> jerin.jacob@caviumnetworks.com; shahafs@mellanox.com
> Subject: Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
> 
> On Mon, Sep 04, 2017 at 03:43:02PM +0100, Bruce Richardson wrote:
> > On Wed, Aug 30, 2017 at 06:10:33PM +0000, Jianfeng Tan wrote:
> > > We remove xen-specific code in EAL, including the option --xen-dom0,
> > > memory initialization code, compiling dependency, etc.
> > >
> > > Besides, related documents are removed or updated.
> > >
> > > Signed-off-by: Jianfeng Tan <jianfeng.tan@intel.com>
> > > ---
> > >  MAINTAINERS                                        |   7 -
> > >  config/common_base                                 |   5 -
> > >  doc/guides/index.rst                               |   1 -
> > >  doc/guides/linux_gsg/build_sample_apps.rst         |   5 +-
> > >  doc/guides/linux_gsg/sys_reqs.rst                  |  53 --
> > >  doc/guides/prog_guide/source_org.rst               |   1 -
> > >  doc/guides/rel_notes/deprecation.rst               |   3 -
> > >  doc/guides/rel_notes/release_17_11.rst             |  12 +
> > >  doc/guides/testpmd_app_ug/run_app.rst              |   4 -
> > >  doc/guides/xen/img/dpdk_xen_pkt_switch.png         | Bin 163842 -> 0
> bytes
> > >  doc/guides/xen/img/grant_refs.png                  | Bin 6405 -> 0 bytes
> > >  doc/guides/xen/img/grant_table.png                 | Bin 96762 -> 0 bytes
> > >  doc/guides/xen/index.rst                           |  38 -
> > >  doc/guides/xen/pkt_switch.rst                      | 470 -------------
> > >  .../bsdapp/eal/include/exec-env/rte_dom0_common.h  | 107 ---
> > >  lib/librte_eal/common/eal_common_options.c         |   3 -
> > >  lib/librte_eal/common/eal_internal_cfg.h           |   1 -
> > >  lib/librte_eal/common/eal_options.h                |   2 -
> > >  lib/librte_eal/common/include/rte_memory.h         |  66 --
> > >  lib/librte_eal/linuxapp/Makefile                   |   2 -
> > >  lib/librte_eal/linuxapp/eal/Makefile               |   5 +-
> > >  lib/librte_eal/linuxapp/eal/eal.c                  |  24 -
> > >  lib/librte_eal/linuxapp/eal/eal_memory.c           |  56 --
> > >  lib/librte_eal/linuxapp/eal/eal_xen_memory.c       | 381 ----------
> > >  .../eal/include/exec-env/rte_dom0_common.h         | 108 ---
> > >  lib/librte_eal/linuxapp/igb_uio/igb_uio.c          |  54 --
> > >  lib/librte_eal/linuxapp/xen_dom0/Makefile          |  53 --
> > >  lib/librte_eal/linuxapp/xen_dom0/compat.h          |  15 -
> > >  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_dev.h     | 107 ---
> > >  lib/librte_eal/linuxapp/xen_dom0/dom0_mm_misc.c    | 780 --------------
> -------
> > >  pkg/dpdk.spec                                      |   3 -
> >
> > The xen functions that were removed are still listed in the linux/bsd
> > version.map files. Not an ABI versioning expert, but I believe they
> > should be removed as they are no longer present.
> >
> Reading the contributors guide section on ABI, specifically
> http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-an-
> entire-abi-version
> it seems like we should collapse down the versions to a single one
> following the function removal, and also increment the whole library so
> version.

So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change it in below way?

DPDK_2.1 {
        {APIs in DPDK_2.0 except xen APIs}
        ...
};

DPDK_16.04 {
        {APIs in DPDK_2.1 except xen APIs}
        ...
} DPDK_2.1;

DPDK_16.07 {
        ...
} DPDK_16.04;
...

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 5/6] eal: remove xen dom0 support
  2017-09-05  3:41       ` Tan, Jianfeng
  2017-09-05  7:31         ` [dpdk-dev] " Thomas Monjalon
@ 2017-09-05  7:31         ` Thomas Monjalon
  2017-09-05  8:07           ` [dpdk-dev] " Tan, Jianfeng
  2017-09-05  8:07           ` Tan, Jianfeng
  1 sibling, 2 replies; 38+ messages in thread
From: Thomas Monjalon @ 2017-09-05  7:31 UTC (permalink / raw)
  To: Tan, Jianfeng
  Cc: Richardson, Bruce, dev, xen-devel, Mcnamara, John,
	joao.m.martins, jerin.jacob, shahafs

05/09/2017 05:41, Tan, Jianfeng:
> From: Richardson, Bruce
> > 
> > Reading the contributors guide section on ABI, specifically
> > http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-an-
> > entire-abi-version
> > it seems like we should collapse down the versions to a single one
> > following the function removal, and also increment the whole library so
> > version.
> 
> So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change it in below way?
> 
> DPDK_2.1 {
>         {APIs in DPDK_2.0 except xen APIs}
>         ...
> };
> 
> DPDK_16.04 {
>         {APIs in DPDK_2.1 except xen APIs}
>         ...
> } DPDK_2.1;

No, you don't need to collapse. You can just remove Xen functions.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
  2017-09-05  3:41       ` Tan, Jianfeng
@ 2017-09-05  7:31         ` Thomas Monjalon
  2017-09-05  7:31         ` Thomas Monjalon
  1 sibling, 0 replies; 38+ messages in thread
From: Thomas Monjalon @ 2017-09-05  7:31 UTC (permalink / raw)
  To: Tan, Jianfeng
  Cc: jerin.jacob, shahafs, dev, Richardson, Bruce, Mcnamara, John,
	xen-devel, joao.m.martins

05/09/2017 05:41, Tan, Jianfeng:
> From: Richardson, Bruce
> > 
> > Reading the contributors guide section on ABI, specifically
> > http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-an-
> > entire-abi-version
> > it seems like we should collapse down the versions to a single one
> > following the function removal, and also increment the whole library so
> > version.
> 
> So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change it in below way?
> 
> DPDK_2.1 {
>         {APIs in DPDK_2.0 except xen APIs}
>         ...
> };
> 
> DPDK_16.04 {
>         {APIs in DPDK_2.1 except xen APIs}
>         ...
> } DPDK_2.1;

No, you don't need to collapse. You can just remove Xen functions.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 5/6] eal: remove xen dom0 support
  2017-09-05  7:31         ` Thomas Monjalon
  2017-09-05  8:07           ` [dpdk-dev] " Tan, Jianfeng
@ 2017-09-05  8:07           ` Tan, Jianfeng
  2017-09-05  8:34             ` [dpdk-dev] " Thomas Monjalon
  2017-09-05  8:34             ` Thomas Monjalon
  1 sibling, 2 replies; 38+ messages in thread
From: Tan, Jianfeng @ 2017-09-05  8:07 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: Richardson, Bruce, dev, xen-devel, Mcnamara, John,
	joao.m.martins, jerin.jacob, shahafs



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Tuesday, September 5, 2017 3:31 PM
> To: Tan, Jianfeng
> Cc: Richardson, Bruce; dev@dpdk.org; xen-devel@lists.xenproject.org;
> Mcnamara, John; joao.m.martins@oracle.com;
> jerin.jacob@caviumnetworks.com; shahafs@mellanox.com
> Subject: Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
> 
> 05/09/2017 05:41, Tan, Jianfeng:
> > From: Richardson, Bruce
> > >
> > > Reading the contributors guide section on ABI, specifically
> > > http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-
> an-
> > > entire-abi-version
> > > it seems like we should collapse down the versions to a single one
> > > following the function removal, and also increment the whole library so
> > > version.
> >
> > So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change
> it in below way?
> >
> > DPDK_2.1 {
> >         {APIs in DPDK_2.0 except xen APIs}
> >         ...
> > };
> >
> > DPDK_16.04 {
> >         {APIs in DPDK_2.1 except xen APIs}
> >         ...
> > } DPDK_2.1;
> 
> No, you don't need to collapse. You can just remove Xen functions.

Thanks.

Besides, two more things: 
1. Shall we increase the so version?
2. This patch is about 8K lines long, do we need to split?

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
  2017-09-05  7:31         ` Thomas Monjalon
@ 2017-09-05  8:07           ` Tan, Jianfeng
  2017-09-05  8:07           ` Tan, Jianfeng
  1 sibling, 0 replies; 38+ messages in thread
From: Tan, Jianfeng @ 2017-09-05  8:07 UTC (permalink / raw)
  To: Thomas Monjalon
  Cc: jerin.jacob, shahafs, dev, Richardson, Bruce, Mcnamara, John,
	xen-devel, joao.m.martins



> -----Original Message-----
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> Sent: Tuesday, September 5, 2017 3:31 PM
> To: Tan, Jianfeng
> Cc: Richardson, Bruce; dev@dpdk.org; xen-devel@lists.xenproject.org;
> Mcnamara, John; joao.m.martins@oracle.com;
> jerin.jacob@caviumnetworks.com; shahafs@mellanox.com
> Subject: Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
> 
> 05/09/2017 05:41, Tan, Jianfeng:
> > From: Richardson, Bruce
> > >
> > > Reading the contributors guide section on ABI, specifically
> > > http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-
> an-
> > > entire-abi-version
> > > it seems like we should collapse down the versions to a single one
> > > following the function removal, and also increment the whole library so
> > > version.
> >
> > So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change
> it in below way?
> >
> > DPDK_2.1 {
> >         {APIs in DPDK_2.0 except xen APIs}
> >         ...
> > };
> >
> > DPDK_16.04 {
> >         {APIs in DPDK_2.1 except xen APIs}
> >         ...
> > } DPDK_2.1;
> 
> No, you don't need to collapse. You can just remove Xen functions.

Thanks.

Besides, two more things: 
1. Shall we increase the so version?
2. This patch is about 8K lines long, do we need to split?

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [PATCH 5/6] eal: remove xen dom0 support
  2017-09-05  8:07           ` Tan, Jianfeng
  2017-09-05  8:34             ` [dpdk-dev] " Thomas Monjalon
@ 2017-09-05  8:34             ` Thomas Monjalon
  1 sibling, 0 replies; 38+ messages in thread
From: Thomas Monjalon @ 2017-09-05  8:34 UTC (permalink / raw)
  To: Tan, Jianfeng
  Cc: Richardson, Bruce, dev, xen-devel, Mcnamara, John,
	joao.m.martins, jerin.jacob, shahafs

05/09/2017 10:07, Tan, Jianfeng:
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > 05/09/2017 05:41, Tan, Jianfeng:
> > > From: Richardson, Bruce
> > > >
> > > > Reading the contributors guide section on ABI, specifically
> > > > http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-
> > an-
> > > > entire-abi-version
> > > > it seems like we should collapse down the versions to a single one
> > > > following the function removal, and also increment the whole library so
> > > > version.
> > >
> > > So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change
> > it in below way?
> > >
> > > DPDK_2.1 {
> > >         {APIs in DPDK_2.0 except xen APIs}
> > >         ...
> > > };
> > >
> > > DPDK_16.04 {
> > >         {APIs in DPDK_2.1 except xen APIs}
> > >         ...
> > > } DPDK_2.1;
> > 
> > No, you don't need to collapse. You can just remove Xen functions.
> 
> Thanks.
> 
> Besides, two more things: 
> 1. Shall we increase the so version?

Yes

> 2. This patch is about 8K lines long, do we need to split?

I do not know how you can split a removal.
If you have ideas, feel free.

^ permalink raw reply	[flat|nested] 38+ messages in thread

* Re: [dpdk-dev] [PATCH 5/6] eal: remove xen dom0 support
  2017-09-05  8:07           ` Tan, Jianfeng
@ 2017-09-05  8:34             ` Thomas Monjalon
  2017-09-05  8:34             ` Thomas Monjalon
  1 sibling, 0 replies; 38+ messages in thread
From: Thomas Monjalon @ 2017-09-05  8:34 UTC (permalink / raw)
  To: Tan, Jianfeng
  Cc: jerin.jacob, shahafs, dev, Richardson, Bruce, Mcnamara, John,
	xen-devel, joao.m.martins

05/09/2017 10:07, Tan, Jianfeng:
> From: Thomas Monjalon [mailto:thomas@monjalon.net]
> > 05/09/2017 05:41, Tan, Jianfeng:
> > > From: Richardson, Bruce
> > > >
> > > > Reading the contributors guide section on ABI, specifically
> > > > http://dpdk.org/doc/guides/contributing/versioning.html#deprecating-
> > an-
> > > > entire-abi-version
> > > > it seems like we should collapse down the versions to a single one
> > > > following the function removal, and also increment the whole library so
> > > > version.
> > >
> > > So for lib/librte_eal/linuxapp/eal/rte_eal_version.map, we should change
> > it in below way?
> > >
> > > DPDK_2.1 {
> > >         {APIs in DPDK_2.0 except xen APIs}
> > >         ...
> > > };
> > >
> > > DPDK_16.04 {
> > >         {APIs in DPDK_2.1 except xen APIs}
> > >         ...
> > > } DPDK_2.1;
> > 
> > No, you don't need to collapse. You can just remove Xen functions.
> 
> Thanks.
> 
> Besides, two more things: 
> 1. Shall we increase the so version?

Yes

> 2. This patch is about 8K lines long, do we need to split?

I do not know how you can split a removal.
If you have ideas, feel free.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
https://lists.xen.org/xen-devel

^ permalink raw reply	[flat|nested] 38+ messages in thread

end of thread, other threads:[~2017-09-05  8:34 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-08-30 18:10 [PATCH 0/6] remove xen dom0 support in DPDK Jianfeng Tan
2017-08-30 18:10 ` [PATCH 1/6] example/vhost_xen: remove Jianfeng Tan
2017-08-30 18:10 ` Jianfeng Tan
2017-09-04 14:14   ` [dpdk-dev] " Bruce Richardson
2017-09-04 14:14   ` Bruce Richardson
2017-08-30 18:10 ` [PATCH 2/6] net/xenvirt: remove Jianfeng Tan
2017-08-30 18:10 ` Jianfeng Tan
2017-09-04 14:25   ` Bruce Richardson
2017-09-04 14:50     ` Bruce Richardson
2017-09-04 14:50     ` [dpdk-dev] " Bruce Richardson
2017-09-04 14:25   ` Bruce Richardson
2017-08-30 18:10 ` [PATCH 3/6] xen: remove xen dependency in app, examples, test Jianfeng Tan
2017-09-04 14:24   ` [dpdk-dev] " Bruce Richardson
2017-09-04 14:24   ` Bruce Richardson
2017-09-04 14:51   ` [dpdk-dev] " Bruce Richardson
2017-09-04 14:51   ` Bruce Richardson
2017-08-30 18:10 ` Jianfeng Tan
2017-08-30 18:10 ` [PATCH 4/6] xen: remove xen dependency in drivers, ether, mempool Jianfeng Tan
2017-09-04 14:51   ` [dpdk-dev] " Bruce Richardson
2017-09-04 14:51   ` Bruce Richardson
2017-08-30 18:10 ` Jianfeng Tan
2017-08-30 18:10 ` [PATCH 5/6] eal: remove xen dom0 support Jianfeng Tan
2017-09-04 14:43   ` [dpdk-dev] " Bruce Richardson
2017-09-04 14:43   ` Bruce Richardson
2017-09-04 14:49     ` Bruce Richardson
2017-09-05  3:41       ` Tan, Jianfeng
2017-09-05  7:31         ` [dpdk-dev] " Thomas Monjalon
2017-09-05  7:31         ` Thomas Monjalon
2017-09-05  8:07           ` [dpdk-dev] " Tan, Jianfeng
2017-09-05  8:07           ` Tan, Jianfeng
2017-09-05  8:34             ` [dpdk-dev] " Thomas Monjalon
2017-09-05  8:34             ` Thomas Monjalon
2017-09-05  3:41       ` [dpdk-dev] " Tan, Jianfeng
2017-09-04 14:49     ` Bruce Richardson
2017-08-30 18:10 ` [PATCH 6/6] eal: remove API rte_mem_phy2mch Jianfeng Tan
2017-09-04 14:52   ` [dpdk-dev] " Bruce Richardson
2017-09-04 14:52   ` Bruce Richardson
2017-08-31  8:44 ` [PATCH 0/6] remove xen dom0 support in DPDK Wei Liu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.