From mboxrd@z Thu Jan 1 00:00:00 1970 From: Dan Magenheimer Subject: [PATCH] [post-4.0] tmem: add page deduplication Date: Tue, 9 Mar 2010 15:20:29 -0800 (PST) Message-ID: <0c8184e8-3dbe-4127-a670-f2f05972aa14@default> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="__126817683329458327abhmt004" Return-path: List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Sender: xen-devel-bounces@lists.xensource.com Errors-To: xen-devel-bounces@lists.xensource.com To: "Xen-Devel (xen-devel@lists.xensource.com)" Cc: kurt.hackel@oracle.com, tmem-devel@oss.oracle.com List-Id: xen-devel@lists.xenproject.org --__126817683329458327abhmt004 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: quoted-printable (This is for post-4.0, but I'm posting now for feedback.) Add "page deduplication" capability to Xen-side of tmem. (Transparent to tmem-enabled guests.) Ephemeral pages that have the exact same content are "combined" so that only one page frame is needed. Since ephemeral pages are essentially read-only, no C-O-W (and thus no equivalent of swapping) is necessary. Anybody know of any good fast (SSE2?) assembly memory compare routines? (See tmh_page_cmp() in the patch.) Points of interest: - Modifications to LRU eviction algorithm to accommodate dedup'ed pages - New data structures to allow lookup of matching pages and track references. (Algorithm used is similar to that used by KSM in KVM/Linux: No hashing required.) - Lock (and rbtree) chosen by first byte of data to allow reasonably high concurrency without greatly complicating lock management. - Statistics added so "dedup ratio" can be monitored. - Dedup is disabled/enabled by Xen command line option. I'm seeing 1.08-1.52 dedup ratio for two self-ballooned guests simultaneously/continuously building linux; that's up to a 34% reduction in physical ephemeral pages used by tmem. Clearly this is very workload-dependent. YMMV. To obtain this savings, approx double the time is spent in tmem (increasing from roughly 0.1% to roughly 0.2%). This compares favorably to compression which costs approximately 10x for an approximate savings of 50%. Signed-off-by: Dan Magenheimer diff -r b8d2a4134a68 tools/misc/xen-tmem-list-parse.c --- a/tools/misc/xen-tmem-list-parse.c=09Wed Mar 03 17:41:58 2010 +0000 +++ b/tools/misc/xen-tmem-list-parse.c=09Tue Mar 09 14:58:37 2010 -0700 @@ -110,13 +110,20 @@ void parse_global(char *s) unsigned long long rtree_node_max =3D parse(s,"Nm"); unsigned long long pgp_count =3D parse(s,"Pc"); unsigned long long pgp_max =3D parse(s,"Pm"); + unsigned long long page_count =3D parse(s,"Fc"); + unsigned long long max_page_count =3D parse(s,"Fm"); + unsigned long long pcd_count =3D parse(s,"Sc"); + unsigned long long max_pcd_count =3D parse(s,"Sm"); =20 printf("total tmem ops=3D%llu (errors=3D%llu) -- tmem pages avail=3D%l= lu\n", total_ops, errored_ops, avail_pages); printf("datastructs: objs=3D%llu (max=3D%llu) pgps=3D%llu (max=3D%llu)= " - "nodes=3D%llu (max=3D%llu)\n", + "nodes=3D%llu (max=3D%llu) pages=3D%llu (max=3D%llu) pcds=3D%ll= u (max=3D%llu) " + "dedup ratio=3D%f\n", obj_count, obj_max, pgp_count, pgp_max, - rtree_node_count, rtree_node_max); + rtree_node_count, rtree_node_max, + page_count,max_page_count,pcd_count,max_pcd_count, + (pcd_count=3D=3D0)?0.0:(global_eph_count*1.0)/pcd_count); printf("misc: failed_copies=3D%llu alloc_failed=3D%llu alloc_page_fail= ed=3D%llu " "low_mem=3D%llu evicted=3D%llu/%llu relinq=3D%llu/%llu, " "max_evicts_per_relinq=3D%llu, flush_pools=3D%llu, " diff -r b8d2a4134a68 xen/common/tmem.c --- a/xen/common/tmem.c=09Wed Mar 03 17:41:58 2010 +0000 +++ b/xen/common/tmem.c=09Tue Mar 09 14:58:37 2010 -0700 @@ -79,6 +79,7 @@ static unsigned long low_on_memory =3D 0; static unsigned long low_on_memory =3D 0; static int global_obj_count_max =3D 0; static int global_pgp_count_max =3D 0; +static int global_pcd_count_max =3D 0; static int global_page_count_max =3D 0; static int global_rtree_node_count_max =3D 0; static long global_eph_count_max =3D 0; @@ -108,6 +109,7 @@ DECL_CYC_COUNTER(decompress); =20 struct tm_pool; struct tmem_page_descriptor; +struct tmem_page_content_descriptor; struct client { struct list_head client_list; struct tm_pool *pools[MAX_POOLS_PER_DOMAIN]; @@ -219,12 +221,17 @@ struct tmem_page_descriptor { obj_t *obj; uint64_t inv_oid; /* used for invalid list only */ }; - uint32_t index; size_t size; /* 0 =3D=3D PAGE_SIZE (pfp), -1 =3D=3D data invalid, else compressed data (cdata) */ + uint32_t index; + /* must hold pcd_tree_rwlocks[firstbyte] to use pcd pointer/siblings *= / + uint16_t firstbyte; /* NON_SHAREABLE->pfp otherwise->pcd */ + bool_t eviction_attempted; /* CHANGE TO lifetimes? (settable) */ + struct list_head pcd_siblings; union { pfp_t *pfp; /* page frame pointer */ char *cdata; /* compressed data */ + struct tmem_page_content_descriptor *pcd; /* page dedup */ }; union { uint64_t timestamp; @@ -233,6 +240,16 @@ struct tmem_page_descriptor { DECL_SENTINEL }; typedef struct tmem_page_descriptor pgp_t; + +struct tmem_page_content_descriptor { + pfp_t *pfp; + struct list_head pgp_list; + struct rb_node pcd_rb_tree_node; + uint32_t count; +}; +typedef struct tmem_page_content_descriptor pcd_t; +struct rb_root pcd_tree_roots[256]; /* choose based on first byte of page = */ +rwlock_t pcd_tree_rwlocks[256]; /* poor man's concurrency for now */ =20 static LIST_HEAD(global_ephemeral_page_list); /* all pages in ephemeral po= ols */ =20 @@ -267,6 +284,7 @@ static long global_eph_count =3D 0; /* ato static long global_eph_count =3D 0; /* atomicity depends on eph_lists_spin= lock */ static atomic_t global_obj_count =3D ATOMIC_INIT(0); static atomic_t global_pgp_count =3D ATOMIC_INIT(0); +static atomic_t global_pcd_count =3D ATOMIC_INIT(0); static atomic_t global_page_count =3D ATOMIC_INIT(0); static atomic_t global_rtree_node_count =3D ATOMIC_INIT(0); =20 @@ -336,6 +354,103 @@ static NOINLINE void tmem_page_free(pool atomic_dec_and_assert(global_page_count); } =20 +/************ PAGE CONTENT DESCRIPTOR MANIPULATION ROUTINES ***********/ + +#define NOT_SHAREABLE ((uint16_t)-1UL) + +/* ensure pgp no longer points to pcd, nor vice-versa */ +/* take pcd rwlock unless have_pcd_rwlock is set, always unlock when done = */ +static NOINLINE void pcd_disassociate(pgp_t *pgp, pool_t *pool, bool_t hav= e_pcd_rwlock) +{ + pcd_t *pcd =3D pgp->pcd; + pfp_t *pfp =3D pgp->pcd->pfp; + uint16_t firstbyte =3D pgp->firstbyte; + + ASSERT(tmh_dedup_enabled()); + ASSERT(firstbyte !=3D NOT_SHAREABLE); + ASSERT(firstbyte < 256); + ASSERT(!pgp->size); + =20 + if ( have_pcd_rwlock ) + ASSERT_WRITELOCK(&pcd_tree_rwlocks[firstbyte]); + else + tmem_write_lock(&pcd_tree_rwlocks[firstbyte]); + list_del_init(&pgp->pcd_siblings); + pgp->pcd =3D NULL; + pgp->firstbyte =3D NOT_SHAREABLE; + pgp->size =3D -1; + if ( --pcd->count ) + { + tmem_write_unlock(&pcd_tree_rwlocks[firstbyte]); + return; + } + + /* no more references to this pcd, recycle it and the physical page */ + ASSERT(list_empty(&pcd->pgp_list)); + pcd->pfp =3D NULL; + /* remove pcd from rbtree */ + rb_erase(&pcd->pcd_rb_tree_node,&pcd_tree_roots[firstbyte]); + /* reinit the struct for safety for now */ + RB_CLEAR_NODE(&pcd->pcd_rb_tree_node); + /* now free up the pcd memory */ + tmem_free(pcd,sizeof(pcd_t),NULL); + atomic_dec_and_assert(global_pcd_count); + tmem_page_free(pool,pfp); + tmem_write_unlock(&pcd_tree_rwlocks[firstbyte]); +} + +static NOINLINE int pcd_associate(pgp_t *pgp, uint8_t firstbyte) +{ + struct rb_node **new, *parent =3D NULL; + struct rb_root *root; + pcd_t *pcd; + int cmp; + + if ( !tmh_dedup_enabled() ) + return 0; + ASSERT(pgp->pfp !=3D NULL); + ASSERT(pgp->obj !=3D NULL); + ASSERT(pgp->obj->pool !=3D NULL); + ASSERT(!pgp->obj->pool->persistent); + tmem_write_lock(&pcd_tree_rwlocks[firstbyte]); + /* look for page match */ + root =3D &pcd_tree_roots[firstbyte]; + new =3D &(root->rb_node); + while ( *new ) + { + pcd =3D container_of(*new, pcd_t, pcd_rb_tree_node); + parent =3D *new; + if ( (cmp =3D tmh_page_cmp(pgp->pfp,pcd->pfp)) < 0 ) + new =3D &((*new)->rb_left); + else if ( cmp > 0 ) + new =3D &((*new)->rb_right); + else + { + /* match! free the no-longer-needed page frame from the pgp */ + tmem_page_free(pgp->obj->pool,pgp->pfp); + goto match; + } + } + /* no match, alloc a pcd and put it in the tree */ + if ( (pcd =3D tmem_malloc(pcd_t, NULL)) =3D=3D NULL ) + return -ENOMEM; + atomic_inc_and_max(global_pcd_count); + RB_CLEAR_NODE(&pcd->pcd_rb_tree_node); /* is this necessary */ + INIT_LIST_HEAD(&pcd->pgp_list); /* is this necessary */ + pcd->count =3D 0; + pcd->pfp =3D pgp->pfp; + rb_link_node(&pcd->pcd_rb_tree_node, parent, new); + rb_insert_color(&pcd->pcd_rb_tree_node, root); +match: + pcd->count++; + list_add(&pgp->pcd_siblings,&pcd->pgp_list); + pgp->firstbyte =3D firstbyte; + pgp->eviction_attempted =3D 0; + pgp->pcd =3D pcd; + tmem_write_unlock(&pcd_tree_rwlocks[firstbyte]); + return 0; +} + /************ PAGE DESCRIPTOR MANIPULATION ROUTINES *******************/ =20 /* allocate a pgp_t and associate it with an object */ @@ -353,6 +468,12 @@ static NOINLINE pgp_t *pgp_alloc(obj_t * INIT_LIST_HEAD(&pgp->global_eph_pages); INIT_LIST_HEAD(&pgp->client_eph_pages); pgp->pfp =3D NULL; + if ( tmh_dedup_enabled() ) + { + pgp->firstbyte =3D NOT_SHAREABLE; + pgp->eviction_attempted =3D 0; + INIT_LIST_HEAD(&pgp->pcd_siblings); + } pgp->size =3D -1; pgp->index =3D -1; pgp->timestamp =3D get_cycles(); @@ -376,7 +497,9 @@ static NOINLINE void pgp_free_data(pgp_t { if ( pgp->pfp =3D=3D NULL ) return; - if ( !pgp->size ) + if ( tmh_dedup_enabled() && pgp->firstbyte !=3D NOT_SHAREABLE ) + pcd_disassociate(pgp,pool,0); + else if ( !pgp->size ) tmem_page_free(pgp->obj->pool,pgp->pfp); else { @@ -987,10 +1110,56 @@ static void client_freeze(client_t *clie =20 /************ MEMORY REVOCATION ROUTINES *******************************/ =20 +static bool_t tmem_try_to_evict_pgp(pgp_t *pgp, bool_t *hold_pool_rwlock) +{ + obj_t *obj =3D pgp->obj; + pool_t *pool =3D obj->pool; + client_t *client =3D pool->client; + uint16_t firstbyte =3D pgp->firstbyte; + + if ( pool->is_dying ) + return 0; + if ( tmh_lock_all && !obj->no_evict ) + return 1;=20 + if ( tmem_spin_trylock(&obj->obj_spinlock) ) + { + if ( tmh_dedup_enabled() ) + { + firstbyte =3D pgp->firstbyte; + if ( firstbyte =3D=3D NOT_SHAREABLE ) + goto obj_unlock; + ASSERT(firstbyte < 256); + if ( !tmem_write_trylock(&pcd_tree_rwlocks[firstbyte]) ) + goto obj_unlock; + if ( pgp->pcd->count > 1 && !pgp->eviction_attempted ) + { + pgp->eviction_attempted++; + list_del(&pgp->global_eph_pages); + list_add_tail(&pgp->global_eph_pages,&global_ephemeral_pag= e_list); + list_del(&pgp->client_eph_pages); + list_add_tail(&pgp->client_eph_pages,&client->ephemeral_pa= ge_list); + goto pcd_unlock; + } + } + if ( obj->pgp_count > 1 ) + return 1; + if ( tmem_write_trylock(&pool->pool_rwlock) ) + { + *hold_pool_rwlock =3D 1; + return 1; + } +pcd_unlock: + tmem_write_unlock(&pcd_tree_rwlocks[firstbyte]); +obj_unlock: + tmem_spin_unlock(&obj->obj_spinlock); + } + return 0; +} + static int tmem_evict(void) { client_t *client =3D tmh_client_from_current(); - pgp_t *pgp =3D NULL, *pgp_del; + pgp_t *pgp =3D NULL, *pgp2, *pgp_del; obj_t *obj; pool_t *pool; int ret =3D 0; @@ -1001,49 +1170,15 @@ static int tmem_evict(void) if ( (client !=3D NULL) && client_over_quota(client) && !list_empty(&client->ephemeral_page_list) ) { - list_for_each_entry(pgp,&client->ephemeral_page_list,client_eph_pa= ges) - { - obj =3D pgp->obj; - pool =3D obj->pool; - if ( pool->is_dying ) - continue; - if ( tmh_lock_all && !obj->no_evict ) + list_for_each_entry_safe(pgp,pgp2,&client->ephemeral_page_list,cli= ent_eph_pages) + if ( tmem_try_to_evict_pgp(pgp,&hold_pool_rwlock) ) goto found; - if ( tmem_spin_trylock(&obj->obj_spinlock) ) - { - if ( obj->pgp_count > 1 ) - goto found; - if ( tmem_write_trylock(&pool->pool_rwlock) ) - { - hold_pool_rwlock =3D 1; - goto found; - } - tmem_spin_unlock(&obj->obj_spinlock); - } - } } else if ( list_empty(&global_ephemeral_page_list) ) { goto out; } else { - list_for_each_entry(pgp,&global_ephemeral_page_list,global_eph_pag= es) - { - obj =3D pgp->obj; - pool =3D obj->pool; - if ( pool->is_dying ) - continue; - if ( tmh_lock_all && !obj->no_evict ) + list_for_each_entry_safe(pgp,pgp2,&global_ephemeral_page_list,glob= al_eph_pages) + if ( tmem_try_to_evict_pgp(pgp,&hold_pool_rwlock) ) goto found; - if ( tmem_spin_trylock(&obj->obj_spinlock) ) - { - if ( obj->pgp_count > 1 ) - goto found; - if ( tmem_write_trylock(&pool->pool_rwlock) ) - { - hold_pool_rwlock =3D 1; - goto found; - } - tmem_spin_unlock(&obj->obj_spinlock); - } - } } =20 ret =3D 0; @@ -1057,10 +1192,16 @@ found: ASSERT(obj->no_evict =3D=3D 0); ASSERT(obj->pool !=3D NULL); ASSERT_SENTINEL(obj,OBJ); + pool =3D obj->pool; =20 ASSERT_SPINLOCK(&obj->obj_spinlock); pgp_del =3D pgp_delete_from_obj(obj, pgp->index); ASSERT(pgp_del =3D=3D pgp); + if ( tmh_dedup_enabled() && pgp->firstbyte !=3D NOT_SHAREABLE ) + { + ASSERT(pgp->pcd->count =3D=3D 1 || pgp->eviction_attempted); + pcd_disassociate(pgp,pool,1); + } pgp_delete(pgp,1); if ( obj->pgp_count =3D=3D 0 ) { @@ -1197,6 +1338,11 @@ copy_uncompressed: ret =3D tmh_copy_from_client(pgp->pfp,cmfn,tmem_offset,pfn_offset,len,= 0); if ( ret =3D=3D -EFAULT ) goto bad_copy; + if ( tmh_dedup_enabled() && !is_persistent(pool) ) + { + if ( pcd_associate(pgp,tmh_get_first_byte(pgp->pfp)) =3D=3D -ENOME= M ) + goto failed_dup; + } pgp->size =3D 0; =20 done: @@ -1308,13 +1454,16 @@ copy_uncompressed: copy_uncompressed: if ( ( pgp->pfp =3D tmem_page_alloc(pool) ) =3D=3D NULL ) { - ret =3D=3D -ENOMEM; + ret =3D -ENOMEM; goto delete_and_free; } /* tmh_copy_from_client properly handles len=3D=3D0 (TMEM_NEW_PAGE) */ ret =3D tmh_copy_from_client(pgp->pfp,cmfn,tmem_offset,pfn_offset,len,= cva); if ( ret =3D=3D -EFAULT ) goto bad_copy; + if ( tmh_dedup_enabled() && !is_persistent(pool) ) + if ( pcd_associate(pgp,tmh_get_first_byte(pgp->pfp)) =3D=3D -ENOME= M ) + goto delete_and_free; pgp->size =3D 0; =20 insert_page: @@ -1411,6 +1560,19 @@ static NOINLINE int do_tmem_get(pool_t * pgp->size, cva) =3D=3D -EFAULT ) goto bad_copy; END_CYC_COUNTER(decompress); + } + else if ( tmh_dedup_enabled() && !is_persistent(pool) && + pgp->firstbyte !=3D NOT_SHAREABLE ) + { + uint16_t firstbyte =3D pgp->firstbyte; + int ret; + + tmem_read_lock(&pcd_tree_rwlocks[firstbyte]); + ret =3D tmh_copy_to_client(cmfn, pgp->pcd->pfp, tmem_offset, + pfn_offset, len, cva); + tmem_read_unlock(&pcd_tree_rwlocks[firstbyte]); + if ( ret =3D=3D -EFAULT ) + goto bad_copy; } else if ( tmh_copy_to_client(cmfn, pgp->pfp, tmem_offset, pfn_offset, len, cva) =3D=3D -EFAULT) @@ -1855,11 +2017,14 @@ static int tmemc_list_global(tmem_cli_va total_flush_pool, use_long ? ',' : '\n'); if (use_long) n +=3D scnprintf(info+n,BSIZE-n, - "Ec:%ld,Em:%ld,Oc:%d,Om:%d,Nc:%d,Nm:%d,Pc:%d,Pm:%d\n", + "Ec:%ld,Em:%ld,Oc:%d,Om:%d,Nc:%d,Nm:%d,Pc:%d,Pm:%d," + "Fc:%d,Fm:%d,Sc:%d,Sm:%d\n", global_eph_count, global_eph_count_max, _atomic_read(global_obj_count), global_obj_count_max, _atomic_read(global_rtree_node_count), global_rtree_node_count_m= ax, - _atomic_read(global_pgp_count), global_pgp_count_max); + _atomic_read(global_pgp_count), global_pgp_count_max, + _atomic_read(global_page_count), global_page_count_max, + _atomic_read(global_pcd_count), global_pcd_count_max); if ( sum + n >=3D len ) return sum; tmh_copy_to_client_buf_offset(buf,off+sum,info,n+1); @@ -2569,10 +2734,18 @@ EXPORT void *tmem_relinquish_pages(unsig /* called at hypervisor startup */ EXPORT void init_tmem(void) { + int i; if ( !tmh_enabled() ) return; =20 radix_tree_init(); + if ( tmh_dedup_enabled() ) + for (i =3D 0; i < 256; i++ ) + { + pcd_tree_roots[i] =3D RB_ROOT; + rwlock_init(&pcd_tree_rwlocks[i]); + } + if ( tmh_init() ) { printk("tmem: initialized comp=3D%d global-lock=3D%d\n", diff -r b8d2a4134a68 xen/common/tmem_xen.c --- a/xen/common/tmem_xen.c=09Wed Mar 03 17:41:58 2010 +0000 +++ b/xen/common/tmem_xen.c=09Tue Mar 09 14:58:37 2010 -0700 @@ -19,6 +19,9 @@ boolean_param("tmem", opt_tmem); =20 EXPORT int opt_tmem_compress =3D 0; boolean_param("tmem_compress", opt_tmem_compress); + +EXPORT int opt_tmem_dedup =3D 1; +boolean_param("tmem_dedup", opt_tmem_dedup); =20 EXPORT int opt_tmem_shared_auth =3D 0; boolean_param("tmem_shared_auth", opt_tmem_shared_auth); diff -r b8d2a4134a68 xen/include/xen/tmem_xen.h --- a/xen/include/xen/tmem_xen.h=09Wed Mar 03 17:41:58 2010 +0000 +++ b/xen/include/xen/tmem_xen.h=09Tue Mar 09 14:58:37 2010 -0700 @@ -52,6 +52,12 @@ static inline int tmh_compression_enable static inline int tmh_compression_enabled(void) { return opt_tmem_compress; +} + +extern int opt_tmem_dedup; +static inline int tmh_dedup_enabled(void) +{ + return opt_tmem_dedup; } =20 extern int opt_tmem_shared_auth; @@ -326,6 +332,28 @@ static inline bool_t tmh_current_is_priv return IS_PRIV(current->domain); } =20 +static inline uint8_t tmh_get_first_byte(pfp_t *pfp) +{ + void *p =3D __map_domain_page(pfp); + + return (uint8_t)(*(char *)p); +} + +static inline int tmh_page_cmp(pfp_t *pfp1, pfp_t *pfp2) +{ + const uint64_t *p1 =3D (uint64_t *)__map_domain_page(pfp1); + const uint64_t *p2 =3D (uint64_t *)__map_domain_page(pfp2); + int i; + + // FIXME: code in assembly? + for ( i =3D PAGE_SIZE/sizeof(uint64_t); *p1 =3D=3D *p2; i--, *p1++, *p= 2++ ); + if ( !i ) + return 0; + if ( *p1 < *p2 ) + return -1; + return 1; +} + /* these typedefs are in the public/tmem.h interface typedef XEN_GUEST_HANDLE(void) cli_mfn_t; typedef XEN_GUEST_HANDLE(char) cli_va_t; --__126817683329458327abhmt004 Content-Type: application/octet-stream; name="tmem-dedup.patch" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="tmem-dedup.patch" ZGlmZiAtciBiOGQyYTQxMzRhNjggdG9vbHMvbWlzYy94ZW4tdG1lbS1saXN0LXBhcnNlLmMKLS0t IGEvdG9vbHMvbWlzYy94ZW4tdG1lbS1saXN0LXBhcnNlLmMJV2VkIE1hciAwMyAxNzo0MTo1OCAy MDEwICswMDAwCisrKyBiL3Rvb2xzL21pc2MveGVuLXRtZW0tbGlzdC1wYXJzZS5jCVR1ZSBNYXIg MDkgMTQ6NTg6MzcgMjAxMCAtMDcwMApAQCAtMTEwLDEzICsxMTAsMjAgQEAgdm9pZCBwYXJzZV9n bG9iYWwoY2hhciAqcykKICAgICB1bnNpZ25lZCBsb25nIGxvbmcgcnRyZWVfbm9kZV9tYXggPSBw YXJzZShzLCJObSIpOwogICAgIHVuc2lnbmVkIGxvbmcgbG9uZyBwZ3BfY291bnQgPSBwYXJzZShz LCJQYyIpOwogICAgIHVuc2lnbmVkIGxvbmcgbG9uZyBwZ3BfbWF4ID0gcGFyc2UocywiUG0iKTsK KyAgICB1bnNpZ25lZCBsb25nIGxvbmcgcGFnZV9jb3VudCA9IHBhcnNlKHMsIkZjIik7CisgICAg dW5zaWduZWQgbG9uZyBsb25nIG1heF9wYWdlX2NvdW50ID0gcGFyc2UocywiRm0iKTsKKyAgICB1 bnNpZ25lZCBsb25nIGxvbmcgcGNkX2NvdW50ID0gcGFyc2UocywiU2MiKTsKKyAgICB1bnNpZ25l ZCBsb25nIGxvbmcgbWF4X3BjZF9jb3VudCA9IHBhcnNlKHMsIlNtIik7CiAKICAgICBwcmludGYo InRvdGFsIHRtZW0gb3BzPSVsbHUgKGVycm9ycz0lbGx1KSAtLSB0bWVtIHBhZ2VzIGF2YWlsPSVs bHVcbiIsCiAgICAgICAgICAgIHRvdGFsX29wcywgZXJyb3JlZF9vcHMsIGF2YWlsX3BhZ2VzKTsK ICAgICBwcmludGYoImRhdGFzdHJ1Y3RzOiBvYmpzPSVsbHUgKG1heD0lbGx1KSBwZ3BzPSVsbHUg KG1heD0lbGx1KSAiCi0gICAgICAgICAgICJub2Rlcz0lbGx1IChtYXg9JWxsdSlcbiIsCisgICAg ICAgICAgICJub2Rlcz0lbGx1IChtYXg9JWxsdSkgcGFnZXM9JWxsdSAobWF4PSVsbHUpIHBjZHM9 JWxsdSAobWF4PSVsbHUpICIKKyAgICAgICAgICAgImRlZHVwIHJhdGlvPSVmXG4iLAogICAgICAg ICAgICBvYmpfY291bnQsIG9ial9tYXgsIHBncF9jb3VudCwgcGdwX21heCwKLSAgICAgICAgICAg cnRyZWVfbm9kZV9jb3VudCwgcnRyZWVfbm9kZV9tYXgpOworICAgICAgICAgICBydHJlZV9ub2Rl X2NvdW50LCBydHJlZV9ub2RlX21heCwKKyAgICAgICAgICAgcGFnZV9jb3VudCxtYXhfcGFnZV9j b3VudCxwY2RfY291bnQsbWF4X3BjZF9jb3VudCwKKyAgICAgICAgICAgKHBjZF9jb3VudD09MCk/ MC4wOihnbG9iYWxfZXBoX2NvdW50KjEuMCkvcGNkX2NvdW50KTsKICAgICBwcmludGYoIm1pc2M6 IGZhaWxlZF9jb3BpZXM9JWxsdSBhbGxvY19mYWlsZWQ9JWxsdSBhbGxvY19wYWdlX2ZhaWxlZD0l bGx1ICIKICAgICAgICAgICAgImxvd19tZW09JWxsdSBldmljdGVkPSVsbHUvJWxsdSByZWxpbnE9 JWxsdS8lbGx1LCAiCiAgICAgICAgICAgICJtYXhfZXZpY3RzX3Blcl9yZWxpbnE9JWxsdSwgZmx1 c2hfcG9vbHM9JWxsdSwgIgpkaWZmIC1yIGI4ZDJhNDEzNGE2OCB4ZW4vY29tbW9uL3RtZW0uYwot LS0gYS94ZW4vY29tbW9uL3RtZW0uYwlXZWQgTWFyIDAzIDE3OjQxOjU4IDIwMTAgKzAwMDAKKysr IGIveGVuL2NvbW1vbi90bWVtLmMJVHVlIE1hciAwOSAxNDo1ODozNyAyMDEwIC0wNzAwCkBAIC03 OSw2ICs3OSw3IEBAIHN0YXRpYyB1bnNpZ25lZCBsb25nIGxvd19vbl9tZW1vcnkgPSAwOwogc3Rh dGljIHVuc2lnbmVkIGxvbmcgbG93X29uX21lbW9yeSA9IDA7CiBzdGF0aWMgaW50IGdsb2JhbF9v YmpfY291bnRfbWF4ID0gMDsKIHN0YXRpYyBpbnQgZ2xvYmFsX3BncF9jb3VudF9tYXggPSAwOwor c3RhdGljIGludCBnbG9iYWxfcGNkX2NvdW50X21heCA9IDA7CiBzdGF0aWMgaW50IGdsb2JhbF9w YWdlX2NvdW50X21heCA9IDA7CiBzdGF0aWMgaW50IGdsb2JhbF9ydHJlZV9ub2RlX2NvdW50X21h eCA9IDA7CiBzdGF0aWMgbG9uZyBnbG9iYWxfZXBoX2NvdW50X21heCA9IDA7CkBAIC0xMDgsNiAr MTA5LDcgQEAgREVDTF9DWUNfQ09VTlRFUihkZWNvbXByZXNzKTsKIAogc3RydWN0IHRtX3Bvb2w7 CiBzdHJ1Y3QgdG1lbV9wYWdlX2Rlc2NyaXB0b3I7CitzdHJ1Y3QgdG1lbV9wYWdlX2NvbnRlbnRf ZGVzY3JpcHRvcjsKIHN0cnVjdCBjbGllbnQgewogICAgIHN0cnVjdCBsaXN0X2hlYWQgY2xpZW50 X2xpc3Q7CiAgICAgc3RydWN0IHRtX3Bvb2wgKnBvb2xzW01BWF9QT09MU19QRVJfRE9NQUlOXTsK QEAgLTIxOSwxMiArMjIxLDE3IEBAIHN0cnVjdCB0bWVtX3BhZ2VfZGVzY3JpcHRvciB7CiAgICAg ICAgIG9ial90ICpvYmo7CiAgICAgICAgIHVpbnQ2NF90IGludl9vaWQ7ICAvKiB1c2VkIGZvciBp bnZhbGlkIGxpc3Qgb25seSAqLwogICAgIH07Ci0gICAgdWludDMyX3QgaW5kZXg7CiAgICAgc2l6 ZV90IHNpemU7IC8qIDAgPT0gUEFHRV9TSVpFIChwZnApLCAtMSA9PSBkYXRhIGludmFsaWQsCiAg ICAgICAgICAgICAgICAgICAgIGVsc2UgY29tcHJlc3NlZCBkYXRhIChjZGF0YSkgKi8KKyAgICB1 aW50MzJfdCBpbmRleDsKKyAgICAvKiBtdXN0IGhvbGQgcGNkX3RyZWVfcndsb2Nrc1tmaXJzdGJ5 dGVdIHRvIHVzZSBwY2QgcG9pbnRlci9zaWJsaW5ncyAqLworICAgIHVpbnQxNl90IGZpcnN0Ynl0 ZTsgLyogTk9OX1NIQVJFQUJMRS0+cGZwICBvdGhlcndpc2UtPnBjZCAqLworICAgIGJvb2xfdCBl dmljdGlvbl9hdHRlbXB0ZWQ7ICAvKiBDSEFOR0UgVE8gbGlmZXRpbWVzPyAoc2V0dGFibGUpICov CisgICAgc3RydWN0IGxpc3RfaGVhZCBwY2Rfc2libGluZ3M7CiAgICAgdW5pb24gewogICAgICAg ICBwZnBfdCAqcGZwOyAgLyogcGFnZSBmcmFtZSBwb2ludGVyICovCiAgICAgICAgIGNoYXIgKmNk YXRhOyAvKiBjb21wcmVzc2VkIGRhdGEgKi8KKyAgICAgICAgc3RydWN0IHRtZW1fcGFnZV9jb250 ZW50X2Rlc2NyaXB0b3IgKnBjZDsgLyogcGFnZSBkZWR1cCAqLwogICAgIH07CiAgICAgdW5pb24g ewogICAgICAgICB1aW50NjRfdCB0aW1lc3RhbXA7CkBAIC0yMzMsNiArMjQwLDE2IEBAIHN0cnVj dCB0bWVtX3BhZ2VfZGVzY3JpcHRvciB7CiAgICAgREVDTF9TRU5USU5FTAogfTsKIHR5cGVkZWYg c3RydWN0IHRtZW1fcGFnZV9kZXNjcmlwdG9yIHBncF90OworCitzdHJ1Y3QgdG1lbV9wYWdlX2Nv bnRlbnRfZGVzY3JpcHRvciB7CisgICAgcGZwX3QgKnBmcDsKKyAgICBzdHJ1Y3QgbGlzdF9oZWFk IHBncF9saXN0OworICAgIHN0cnVjdCByYl9ub2RlIHBjZF9yYl90cmVlX25vZGU7CisgICAgdWlu dDMyX3QgY291bnQ7Cit9OwordHlwZWRlZiBzdHJ1Y3QgdG1lbV9wYWdlX2NvbnRlbnRfZGVzY3Jp cHRvciBwY2RfdDsKK3N0cnVjdCByYl9yb290IHBjZF90cmVlX3Jvb3RzWzI1Nl07IC8qIGNob29z ZSBiYXNlZCBvbiBmaXJzdCBieXRlIG9mIHBhZ2UgKi8KK3J3bG9ja190IHBjZF90cmVlX3J3bG9j a3NbMjU2XTsgLyogcG9vciBtYW4ncyBjb25jdXJyZW5jeSBmb3Igbm93ICovCiAKIHN0YXRpYyBM SVNUX0hFQUQoZ2xvYmFsX2VwaGVtZXJhbF9wYWdlX2xpc3QpOyAvKiBhbGwgcGFnZXMgaW4gZXBo ZW1lcmFsIHBvb2xzICovCiAKQEAgLTI2Nyw2ICsyODQsNyBAQCBzdGF0aWMgbG9uZyBnbG9iYWxf ZXBoX2NvdW50ID0gMDsgLyogYXRvCiBzdGF0aWMgbG9uZyBnbG9iYWxfZXBoX2NvdW50ID0gMDsg LyogYXRvbWljaXR5IGRlcGVuZHMgb24gZXBoX2xpc3RzX3NwaW5sb2NrICovCiBzdGF0aWMgYXRv bWljX3QgZ2xvYmFsX29ial9jb3VudCA9IEFUT01JQ19JTklUKDApOwogc3RhdGljIGF0b21pY190 IGdsb2JhbF9wZ3BfY291bnQgPSBBVE9NSUNfSU5JVCgwKTsKK3N0YXRpYyBhdG9taWNfdCBnbG9i YWxfcGNkX2NvdW50ID0gQVRPTUlDX0lOSVQoMCk7CiBzdGF0aWMgYXRvbWljX3QgZ2xvYmFsX3Bh Z2VfY291bnQgPSBBVE9NSUNfSU5JVCgwKTsKIHN0YXRpYyBhdG9taWNfdCBnbG9iYWxfcnRyZWVf bm9kZV9jb3VudCA9IEFUT01JQ19JTklUKDApOwogCkBAIC0zMzYsNiArMzU0LDEwMyBAQCBzdGF0 aWMgTk9JTkxJTkUgdm9pZCB0bWVtX3BhZ2VfZnJlZShwb29sCiAgICAgYXRvbWljX2RlY19hbmRf YXNzZXJ0KGdsb2JhbF9wYWdlX2NvdW50KTsKIH0KIAorLyoqKioqKioqKioqKiBQQUdFIENPTlRF TlQgREVTQ1JJUFRPUiBNQU5JUFVMQVRJT04gUk9VVElORVMgKioqKioqKioqKiovCisKKyNkZWZp bmUgTk9UX1NIQVJFQUJMRSAoKHVpbnQxNl90KS0xVUwpCisKKy8qIGVuc3VyZSBwZ3Agbm8gbG9u Z2VyIHBvaW50cyB0byBwY2QsIG5vciB2aWNlLXZlcnNhICovCisvKiB0YWtlIHBjZCByd2xvY2sg dW5sZXNzIGhhdmVfcGNkX3J3bG9jayBpcyBzZXQsIGFsd2F5cyB1bmxvY2sgd2hlbiBkb25lICov CitzdGF0aWMgTk9JTkxJTkUgdm9pZCBwY2RfZGlzYXNzb2NpYXRlKHBncF90ICpwZ3AsIHBvb2xf dCAqcG9vbCwgYm9vbF90IGhhdmVfcGNkX3J3bG9jaykKK3sKKyAgICBwY2RfdCAqcGNkID0gcGdw LT5wY2Q7CisgICAgcGZwX3QgKnBmcCA9IHBncC0+cGNkLT5wZnA7CisgICAgdWludDE2X3QgZmly c3RieXRlID0gcGdwLT5maXJzdGJ5dGU7CisKKyAgICBBU1NFUlQodG1oX2RlZHVwX2VuYWJsZWQo KSk7CisgICAgQVNTRVJUKGZpcnN0Ynl0ZSAhPSBOT1RfU0hBUkVBQkxFKTsKKyAgICBBU1NFUlQo Zmlyc3RieXRlIDwgMjU2KTsKKyAgICBBU1NFUlQoIXBncC0+c2l6ZSk7CisgICAgCisgICAgaWYg KCBoYXZlX3BjZF9yd2xvY2sgKQorICAgICAgICBBU1NFUlRfV1JJVEVMT0NLKCZwY2RfdHJlZV9y d2xvY2tzW2ZpcnN0Ynl0ZV0pOworICAgIGVsc2UKKyAgICAgICAgdG1lbV93cml0ZV9sb2NrKCZw Y2RfdHJlZV9yd2xvY2tzW2ZpcnN0Ynl0ZV0pOworICAgIGxpc3RfZGVsX2luaXQoJnBncC0+cGNk X3NpYmxpbmdzKTsKKyAgICBwZ3AtPnBjZCA9IE5VTEw7CisgICAgcGdwLT5maXJzdGJ5dGUgPSBO T1RfU0hBUkVBQkxFOworICAgIHBncC0+c2l6ZSA9IC0xOworICAgIGlmICggLS1wY2QtPmNvdW50 ICkKKyAgICB7CisgICAgICAgIHRtZW1fd3JpdGVfdW5sb2NrKCZwY2RfdHJlZV9yd2xvY2tzW2Zp cnN0Ynl0ZV0pOworICAgICAgICByZXR1cm47CisgICAgfQorCisgICAgLyogbm8gbW9yZSByZWZl cmVuY2VzIHRvIHRoaXMgcGNkLCByZWN5Y2xlIGl0IGFuZCB0aGUgcGh5c2ljYWwgcGFnZSAqLwor ICAgIEFTU0VSVChsaXN0X2VtcHR5KCZwY2QtPnBncF9saXN0KSk7CisgICAgcGNkLT5wZnAgPSBO VUxMOworICAgIC8qIHJlbW92ZSBwY2QgZnJvbSByYnRyZWUgKi8KKyAgICByYl9lcmFzZSgmcGNk LT5wY2RfcmJfdHJlZV9ub2RlLCZwY2RfdHJlZV9yb290c1tmaXJzdGJ5dGVdKTsKKyAgICAvKiBy ZWluaXQgdGhlIHN0cnVjdCBmb3Igc2FmZXR5IGZvciBub3cgKi8KKyAgICBSQl9DTEVBUl9OT0RF KCZwY2QtPnBjZF9yYl90cmVlX25vZGUpOworICAgIC8qIG5vdyBmcmVlIHVwIHRoZSBwY2QgbWVt b3J5ICovCisgICAgdG1lbV9mcmVlKHBjZCxzaXplb2YocGNkX3QpLE5VTEwpOworICAgIGF0b21p Y19kZWNfYW5kX2Fzc2VydChnbG9iYWxfcGNkX2NvdW50KTsKKyAgICB0bWVtX3BhZ2VfZnJlZShw b29sLHBmcCk7CisgICAgdG1lbV93cml0ZV91bmxvY2soJnBjZF90cmVlX3J3bG9ja3NbZmlyc3Ri eXRlXSk7Cit9CisKK3N0YXRpYyBOT0lOTElORSBpbnQgcGNkX2Fzc29jaWF0ZShwZ3BfdCAqcGdw LCB1aW50OF90IGZpcnN0Ynl0ZSkKK3sKKyAgICBzdHJ1Y3QgcmJfbm9kZSAqKm5ldywgKnBhcmVu dCA9IE5VTEw7CisgICAgc3RydWN0IHJiX3Jvb3QgKnJvb3Q7CisgICAgcGNkX3QgKnBjZDsKKyAg ICBpbnQgY21wOworCisgICAgaWYgKCAhdG1oX2RlZHVwX2VuYWJsZWQoKSApCisgICAgICAgIHJl dHVybiAwOworICAgIEFTU0VSVChwZ3AtPnBmcCAhPSBOVUxMKTsKKyAgICBBU1NFUlQocGdwLT5v YmogIT0gTlVMTCk7CisgICAgQVNTRVJUKHBncC0+b2JqLT5wb29sICE9IE5VTEwpOworICAgIEFT U0VSVCghcGdwLT5vYmotPnBvb2wtPnBlcnNpc3RlbnQpOworICAgIHRtZW1fd3JpdGVfbG9jaygm cGNkX3RyZWVfcndsb2Nrc1tmaXJzdGJ5dGVdKTsKKyAgICAvKiBsb29rIGZvciBwYWdlIG1hdGNo ICovCisgICAgcm9vdCA9ICZwY2RfdHJlZV9yb290c1tmaXJzdGJ5dGVdOworICAgIG5ldyA9ICYo cm9vdC0+cmJfbm9kZSk7CisgICAgd2hpbGUgKCAqbmV3ICkKKyAgICB7CisgICAgICAgIHBjZCA9 IGNvbnRhaW5lcl9vZigqbmV3LCBwY2RfdCwgcGNkX3JiX3RyZWVfbm9kZSk7CisgICAgICAgIHBh cmVudCA9ICpuZXc7CisgICAgICAgIGlmICggKGNtcCA9IHRtaF9wYWdlX2NtcChwZ3AtPnBmcCxw Y2QtPnBmcCkpIDwgMCApCisgICAgICAgICAgICBuZXcgPSAmKCgqbmV3KS0+cmJfbGVmdCk7Cisg ICAgICAgIGVsc2UgaWYgKCBjbXAgPiAwICkKKyAgICAgICAgICAgIG5ldyA9ICYoKCpuZXcpLT5y Yl9yaWdodCk7CisgICAgICAgIGVsc2UKKyAgICAgICAgeworICAgICAgICAgICAgLyogbWF0Y2gh IGZyZWUgdGhlIG5vLWxvbmdlci1uZWVkZWQgcGFnZSBmcmFtZSBmcm9tIHRoZSBwZ3AgKi8KKyAg ICAgICAgICAgIHRtZW1fcGFnZV9mcmVlKHBncC0+b2JqLT5wb29sLHBncC0+cGZwKTsKKyAgICAg ICAgICAgIGdvdG8gbWF0Y2g7CisgICAgICAgIH0KKyAgICB9CisgICAgLyogbm8gbWF0Y2gsIGFs bG9jIGEgcGNkIGFuZCBwdXQgaXQgaW4gdGhlIHRyZWUgKi8KKyAgICBpZiAoIChwY2QgPSB0bWVt X21hbGxvYyhwY2RfdCwgTlVMTCkpID09IE5VTEwgKQorICAgICAgICByZXR1cm4gLUVOT01FTTsK KyAgICBhdG9taWNfaW5jX2FuZF9tYXgoZ2xvYmFsX3BjZF9jb3VudCk7CisgICAgUkJfQ0xFQVJf Tk9ERSgmcGNkLT5wY2RfcmJfdHJlZV9ub2RlKTsgIC8qIGlzIHRoaXMgbmVjZXNzYXJ5ICovCisg ICAgSU5JVF9MSVNUX0hFQUQoJnBjZC0+cGdwX2xpc3QpOyAgLyogaXMgdGhpcyBuZWNlc3Nhcnkg Ki8KKyAgICBwY2QtPmNvdW50ID0gMDsKKyAgICBwY2QtPnBmcCA9IHBncC0+cGZwOworICAgIHJi X2xpbmtfbm9kZSgmcGNkLT5wY2RfcmJfdHJlZV9ub2RlLCBwYXJlbnQsIG5ldyk7CisgICAgcmJf aW5zZXJ0X2NvbG9yKCZwY2QtPnBjZF9yYl90cmVlX25vZGUsIHJvb3QpOworbWF0Y2g6CisgICAg cGNkLT5jb3VudCsrOworICAgIGxpc3RfYWRkKCZwZ3AtPnBjZF9zaWJsaW5ncywmcGNkLT5wZ3Bf bGlzdCk7CisgICAgcGdwLT5maXJzdGJ5dGUgPSBmaXJzdGJ5dGU7CisgICAgcGdwLT5ldmljdGlv bl9hdHRlbXB0ZWQgPSAwOworICAgIHBncC0+cGNkID0gcGNkOworICAgIHRtZW1fd3JpdGVfdW5s b2NrKCZwY2RfdHJlZV9yd2xvY2tzW2ZpcnN0Ynl0ZV0pOworICAgIHJldHVybiAwOworfQorCiAv KioqKioqKioqKioqIFBBR0UgREVTQ1JJUFRPUiBNQU5JUFVMQVRJT04gUk9VVElORVMgKioqKioq KioqKioqKioqKioqKi8KIAogLyogYWxsb2NhdGUgYSBwZ3BfdCBhbmQgYXNzb2NpYXRlIGl0IHdp dGggYW4gb2JqZWN0ICovCkBAIC0zNTMsNiArNDY4LDEyIEBAIHN0YXRpYyBOT0lOTElORSBwZ3Bf dCAqcGdwX2FsbG9jKG9ial90ICoKICAgICBJTklUX0xJU1RfSEVBRCgmcGdwLT5nbG9iYWxfZXBo X3BhZ2VzKTsKICAgICBJTklUX0xJU1RfSEVBRCgmcGdwLT5jbGllbnRfZXBoX3BhZ2VzKTsKICAg ICBwZ3AtPnBmcCA9IE5VTEw7CisgICAgaWYgKCB0bWhfZGVkdXBfZW5hYmxlZCgpICkKKyAgICB7 CisgICAgICAgIHBncC0+Zmlyc3RieXRlID0gTk9UX1NIQVJFQUJMRTsKKyAgICAgICAgcGdwLT5l dmljdGlvbl9hdHRlbXB0ZWQgPSAwOworICAgICAgICBJTklUX0xJU1RfSEVBRCgmcGdwLT5wY2Rf c2libGluZ3MpOworICAgIH0KICAgICBwZ3AtPnNpemUgPSAtMTsKICAgICBwZ3AtPmluZGV4ID0g LTE7CiAgICAgcGdwLT50aW1lc3RhbXAgPSBnZXRfY3ljbGVzKCk7CkBAIC0zNzYsNyArNDk3LDkg QEAgc3RhdGljIE5PSU5MSU5FIHZvaWQgcGdwX2ZyZWVfZGF0YShwZ3BfdAogewogICAgIGlmICgg cGdwLT5wZnAgPT0gTlVMTCApCiAgICAgICAgIHJldHVybjsKLSAgICBpZiAoICFwZ3AtPnNpemUg KQorICAgIGlmICggdG1oX2RlZHVwX2VuYWJsZWQoKSAmJiBwZ3AtPmZpcnN0Ynl0ZSAhPSBOT1Rf U0hBUkVBQkxFICkKKyAgICAgICAgcGNkX2Rpc2Fzc29jaWF0ZShwZ3AscG9vbCwwKTsKKyAgICBl bHNlIGlmICggIXBncC0+c2l6ZSApCiAgICAgICAgIHRtZW1fcGFnZV9mcmVlKHBncC0+b2JqLT5w b29sLHBncC0+cGZwKTsKICAgICBlbHNlCiAgICAgewpAQCAtOTg3LDEwICsxMTEwLDU2IEBAIHN0 YXRpYyB2b2lkIGNsaWVudF9mcmVlemUoY2xpZW50X3QgKmNsaWUKIAogLyoqKioqKioqKioqKiBN RU1PUlkgUkVWT0NBVElPTiBST1VUSU5FUyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioq LwogCitzdGF0aWMgYm9vbF90IHRtZW1fdHJ5X3RvX2V2aWN0X3BncChwZ3BfdCAqcGdwLCBib29s X3QgKmhvbGRfcG9vbF9yd2xvY2spCit7CisgICAgb2JqX3QgKm9iaiA9IHBncC0+b2JqOworICAg IHBvb2xfdCAqcG9vbCA9IG9iai0+cG9vbDsKKyAgICBjbGllbnRfdCAqY2xpZW50ID0gcG9vbC0+ Y2xpZW50OworICAgIHVpbnQxNl90IGZpcnN0Ynl0ZSA9IHBncC0+Zmlyc3RieXRlOworCisgICAg aWYgKCBwb29sLT5pc19keWluZyApCisgICAgICAgIHJldHVybiAwOworICAgIGlmICggdG1oX2xv Y2tfYWxsICYmICFvYmotPm5vX2V2aWN0ICkKKyAgICAgICByZXR1cm4gMTsgCisgICAgaWYgKCB0 bWVtX3NwaW5fdHJ5bG9jaygmb2JqLT5vYmpfc3BpbmxvY2spICkKKyAgICB7CisgICAgICAgIGlm ICggdG1oX2RlZHVwX2VuYWJsZWQoKSApCisgICAgICAgIHsKKyAgICAgICAgICAgIGZpcnN0Ynl0 ZSA9IHBncC0+Zmlyc3RieXRlOworICAgICAgICAgICAgaWYgKCBmaXJzdGJ5dGUgPT0gIE5PVF9T SEFSRUFCTEUgKQorICAgICAgICAgICAgICAgIGdvdG8gb2JqX3VubG9jazsKKyAgICAgICAgICAg IEFTU0VSVChmaXJzdGJ5dGUgPCAyNTYpOworICAgICAgICAgICAgaWYgKCAhdG1lbV93cml0ZV90 cnlsb2NrKCZwY2RfdHJlZV9yd2xvY2tzW2ZpcnN0Ynl0ZV0pICkKKyAgICAgICAgICAgICAgICBn b3RvIG9ial91bmxvY2s7CisgICAgICAgICAgICBpZiAoIHBncC0+cGNkLT5jb3VudCA+IDEgJiYg IXBncC0+ZXZpY3Rpb25fYXR0ZW1wdGVkICkKKyAgICAgICAgICAgIHsKKyAgICAgICAgICAgICAg ICBwZ3AtPmV2aWN0aW9uX2F0dGVtcHRlZCsrOworICAgICAgICAgICAgICAgIGxpc3RfZGVsKCZw Z3AtPmdsb2JhbF9lcGhfcGFnZXMpOworICAgICAgICAgICAgICAgIGxpc3RfYWRkX3RhaWwoJnBn cC0+Z2xvYmFsX2VwaF9wYWdlcywmZ2xvYmFsX2VwaGVtZXJhbF9wYWdlX2xpc3QpOworICAgICAg ICAgICAgICAgIGxpc3RfZGVsKCZwZ3AtPmNsaWVudF9lcGhfcGFnZXMpOworICAgICAgICAgICAg ICAgIGxpc3RfYWRkX3RhaWwoJnBncC0+Y2xpZW50X2VwaF9wYWdlcywmY2xpZW50LT5lcGhlbWVy YWxfcGFnZV9saXN0KTsKKyAgICAgICAgICAgICAgICBnb3RvIHBjZF91bmxvY2s7CisgICAgICAg ICAgICB9CisgICAgICAgIH0KKyAgICAgICAgaWYgKCBvYmotPnBncF9jb3VudCA+IDEgKQorICAg ICAgICAgICAgcmV0dXJuIDE7CisgICAgICAgIGlmICggdG1lbV93cml0ZV90cnlsb2NrKCZwb29s LT5wb29sX3J3bG9jaykgKQorICAgICAgICB7CisgICAgICAgICAgICAqaG9sZF9wb29sX3J3bG9j ayA9IDE7CisgICAgICAgICAgICByZXR1cm4gMTsKKyAgICAgICAgfQorcGNkX3VubG9jazoKKyAg ICAgICAgdG1lbV93cml0ZV91bmxvY2soJnBjZF90cmVlX3J3bG9ja3NbZmlyc3RieXRlXSk7Citv YmpfdW5sb2NrOgorICAgICAgICB0bWVtX3NwaW5fdW5sb2NrKCZvYmotPm9ial9zcGlubG9jayk7 CisgICAgfQorICAgIHJldHVybiAwOworfQorCiBzdGF0aWMgaW50IHRtZW1fZXZpY3Qodm9pZCkK IHsKICAgICBjbGllbnRfdCAqY2xpZW50ID0gdG1oX2NsaWVudF9mcm9tX2N1cnJlbnQoKTsKLSAg ICBwZ3BfdCAqcGdwID0gTlVMTCwgKnBncF9kZWw7CisgICAgcGdwX3QgKnBncCA9IE5VTEwsICpw Z3AyLCAqcGdwX2RlbDsKICAgICBvYmpfdCAqb2JqOwogICAgIHBvb2xfdCAqcG9vbDsKICAgICBp bnQgcmV0ID0gMDsKQEAgLTEwMDEsNDkgKzExNzAsMTUgQEAgc3RhdGljIGludCB0bWVtX2V2aWN0 KHZvaWQpCiAgICAgaWYgKCAoY2xpZW50ICE9IE5VTEwpICYmIGNsaWVudF9vdmVyX3F1b3RhKGNs aWVudCkgJiYKICAgICAgICAgICFsaXN0X2VtcHR5KCZjbGllbnQtPmVwaGVtZXJhbF9wYWdlX2xp c3QpICkKICAgICB7Ci0gICAgICAgIGxpc3RfZm9yX2VhY2hfZW50cnkocGdwLCZjbGllbnQtPmVw aGVtZXJhbF9wYWdlX2xpc3QsY2xpZW50X2VwaF9wYWdlcykKLSAgICAgICAgewotICAgICAgICAg ICAgb2JqID0gcGdwLT5vYmo7Ci0gICAgICAgICAgICBwb29sID0gb2JqLT5wb29sOwotICAgICAg ICAgICAgaWYgKCBwb29sLT5pc19keWluZyApCi0gICAgICAgICAgICAgICAgY29udGludWU7Ci0g ICAgICAgICAgICBpZiAoIHRtaF9sb2NrX2FsbCAmJiAhb2JqLT5ub19ldmljdCApCisgICAgICAg IGxpc3RfZm9yX2VhY2hfZW50cnlfc2FmZShwZ3AscGdwMiwmY2xpZW50LT5lcGhlbWVyYWxfcGFn ZV9saXN0LGNsaWVudF9lcGhfcGFnZXMpCisgICAgICAgICAgICBpZiAoIHRtZW1fdHJ5X3RvX2V2 aWN0X3BncChwZ3AsJmhvbGRfcG9vbF9yd2xvY2spICkKICAgICAgICAgICAgICAgICBnb3RvIGZv dW5kOwotICAgICAgICAgICAgaWYgKCB0bWVtX3NwaW5fdHJ5bG9jaygmb2JqLT5vYmpfc3Bpbmxv Y2spICkKLSAgICAgICAgICAgIHsKLSAgICAgICAgICAgICAgICBpZiAoIG9iai0+cGdwX2NvdW50 ID4gMSApCi0gICAgICAgICAgICAgICAgICAgIGdvdG8gZm91bmQ7Ci0gICAgICAgICAgICAgICAg aWYgKCB0bWVtX3dyaXRlX3RyeWxvY2soJnBvb2wtPnBvb2xfcndsb2NrKSApCi0gICAgICAgICAg ICAgICAgewotICAgICAgICAgICAgICAgICAgICBob2xkX3Bvb2xfcndsb2NrID0gMTsKLSAgICAg ICAgICAgICAgICAgICAgZ290byBmb3VuZDsKLSAgICAgICAgICAgICAgICB9Ci0gICAgICAgICAg ICAgICAgdG1lbV9zcGluX3VubG9jaygmb2JqLT5vYmpfc3BpbmxvY2spOwotICAgICAgICAgICAg fQotICAgICAgICB9CiAgICAgfSBlbHNlIGlmICggbGlzdF9lbXB0eSgmZ2xvYmFsX2VwaGVtZXJh bF9wYWdlX2xpc3QpICkgewogICAgICAgICBnb3RvIG91dDsKICAgICB9IGVsc2UgewotICAgICAg ICBsaXN0X2Zvcl9lYWNoX2VudHJ5KHBncCwmZ2xvYmFsX2VwaGVtZXJhbF9wYWdlX2xpc3QsZ2xv YmFsX2VwaF9wYWdlcykKLSAgICAgICAgewotICAgICAgICAgICAgb2JqID0gcGdwLT5vYmo7Ci0g ICAgICAgICAgICBwb29sID0gb2JqLT5wb29sOwotICAgICAgICAgICAgaWYgKCBwb29sLT5pc19k eWluZyApCi0gICAgICAgICAgICAgICAgY29udGludWU7Ci0gICAgICAgICAgICBpZiAoIHRtaF9s b2NrX2FsbCAmJiAhb2JqLT5ub19ldmljdCApCisgICAgICAgIGxpc3RfZm9yX2VhY2hfZW50cnlf c2FmZShwZ3AscGdwMiwmZ2xvYmFsX2VwaGVtZXJhbF9wYWdlX2xpc3QsZ2xvYmFsX2VwaF9wYWdl cykKKyAgICAgICAgICAgIGlmICggdG1lbV90cnlfdG9fZXZpY3RfcGdwKHBncCwmaG9sZF9wb29s X3J3bG9jaykgKQogICAgICAgICAgICAgICAgIGdvdG8gZm91bmQ7Ci0gICAgICAgICAgICBpZiAo IHRtZW1fc3Bpbl90cnlsb2NrKCZvYmotPm9ial9zcGlubG9jaykgKQotICAgICAgICAgICAgewot ICAgICAgICAgICAgICAgIGlmICggb2JqLT5wZ3BfY291bnQgPiAxICkKLSAgICAgICAgICAgICAg ICAgICAgZ290byBmb3VuZDsKLSAgICAgICAgICAgICAgICBpZiAoIHRtZW1fd3JpdGVfdHJ5bG9j aygmcG9vbC0+cG9vbF9yd2xvY2spICkKLSAgICAgICAgICAgICAgICB7Ci0gICAgICAgICAgICAg ICAgICAgIGhvbGRfcG9vbF9yd2xvY2sgPSAxOwotICAgICAgICAgICAgICAgICAgICBnb3RvIGZv dW5kOwotICAgICAgICAgICAgICAgIH0KLSAgICAgICAgICAgICAgICB0bWVtX3NwaW5fdW5sb2Nr KCZvYmotPm9ial9zcGlubG9jayk7Ci0gICAgICAgICAgICB9Ci0gICAgICAgIH0KICAgICB9CiAK ICAgICByZXQgPSAwOwpAQCAtMTA1NywxMCArMTE5MiwxNiBAQCBmb3VuZDoKICAgICBBU1NFUlQo b2JqLT5ub19ldmljdCA9PSAwKTsKICAgICBBU1NFUlQob2JqLT5wb29sICE9IE5VTEwpOwogICAg IEFTU0VSVF9TRU5USU5FTChvYmosT0JKKTsKKyAgICBwb29sID0gb2JqLT5wb29sOwogCiAgICAg QVNTRVJUX1NQSU5MT0NLKCZvYmotPm9ial9zcGlubG9jayk7CiAgICAgcGdwX2RlbCA9IHBncF9k ZWxldGVfZnJvbV9vYmoob2JqLCBwZ3AtPmluZGV4KTsKICAgICBBU1NFUlQocGdwX2RlbCA9PSBw Z3ApOworICAgIGlmICggdG1oX2RlZHVwX2VuYWJsZWQoKSAmJiBwZ3AtPmZpcnN0Ynl0ZSAhPSBO T1RfU0hBUkVBQkxFICkKKyAgICB7CisgICAgICAgIEFTU0VSVChwZ3AtPnBjZC0+Y291bnQgPT0g MSB8fCBwZ3AtPmV2aWN0aW9uX2F0dGVtcHRlZCk7CisgICAgICAgIHBjZF9kaXNhc3NvY2lhdGUo cGdwLHBvb2wsMSk7CisgICAgfQogICAgIHBncF9kZWxldGUocGdwLDEpOwogICAgIGlmICggb2Jq LT5wZ3BfY291bnQgPT0gMCApCiAgICAgewpAQCAtMTE5Nyw2ICsxMzM4LDExIEBAIGNvcHlfdW5j b21wcmVzc2VkOgogICAgIHJldCA9IHRtaF9jb3B5X2Zyb21fY2xpZW50KHBncC0+cGZwLGNtZm4s dG1lbV9vZmZzZXQscGZuX29mZnNldCxsZW4sMCk7CiAgICAgaWYgKCByZXQgPT0gLUVGQVVMVCAp CiAgICAgICAgIGdvdG8gYmFkX2NvcHk7CisgICAgaWYgKCB0bWhfZGVkdXBfZW5hYmxlZCgpICYm ICFpc19wZXJzaXN0ZW50KHBvb2wpICkKKyAgICB7CisgICAgICAgIGlmICggcGNkX2Fzc29jaWF0 ZShwZ3AsdG1oX2dldF9maXJzdF9ieXRlKHBncC0+cGZwKSkgPT0gLUVOT01FTSApCisgICAgICAg ICAgICBnb3RvIGZhaWxlZF9kdXA7CisgICAgfQogICAgIHBncC0+c2l6ZSA9IDA7CiAKIGRvbmU6 CkBAIC0xMzA4LDEzICsxNDU0LDE2IEBAIGNvcHlfdW5jb21wcmVzc2VkOgogY29weV91bmNvbXBy ZXNzZWQ6CiAgICAgaWYgKCAoIHBncC0+cGZwID0gdG1lbV9wYWdlX2FsbG9jKHBvb2wpICkgPT0g TlVMTCApCiAgICAgewotICAgICAgICByZXQgPT0gLUVOT01FTTsKKyAgICAgICAgcmV0ID0gLUVO T01FTTsKICAgICAgICAgZ290byBkZWxldGVfYW5kX2ZyZWU7CiAgICAgfQogICAgIC8qIHRtaF9j b3B5X2Zyb21fY2xpZW50IHByb3Blcmx5IGhhbmRsZXMgbGVuPT0wIChUTUVNX05FV19QQUdFKSAq LwogICAgIHJldCA9IHRtaF9jb3B5X2Zyb21fY2xpZW50KHBncC0+cGZwLGNtZm4sdG1lbV9vZmZz ZXQscGZuX29mZnNldCxsZW4sY3ZhKTsKICAgICBpZiAoIHJldCA9PSAtRUZBVUxUICkKICAgICAg ICAgZ290byBiYWRfY29weTsKKyAgICBpZiAoIHRtaF9kZWR1cF9lbmFibGVkKCkgJiYgIWlzX3Bl cnNpc3RlbnQocG9vbCkgKQorICAgICAgICBpZiAoIHBjZF9hc3NvY2lhdGUocGdwLHRtaF9nZXRf Zmlyc3RfYnl0ZShwZ3AtPnBmcCkpID09IC1FTk9NRU0gKQorICAgICAgICAgICAgZ290byBkZWxl dGVfYW5kX2ZyZWU7CiAgICAgcGdwLT5zaXplID0gMDsKIAogaW5zZXJ0X3BhZ2U6CkBAIC0xNDEx LDYgKzE1NjAsMTkgQEAgc3RhdGljIE5PSU5MSU5FIGludCBkb190bWVtX2dldChwb29sX3QgKgog ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwZ3AtPnNpemUsIGN2YSkgPT0g LUVGQVVMVCApCiAgICAgICAgICAgICBnb3RvIGJhZF9jb3B5OwogICAgICAgICBFTkRfQ1lDX0NP VU5URVIoZGVjb21wcmVzcyk7CisgICAgfQorICAgIGVsc2UgaWYgKCB0bWhfZGVkdXBfZW5hYmxl ZCgpICYmICFpc19wZXJzaXN0ZW50KHBvb2wpICYmCisgICAgICAgICAgICAgIHBncC0+Zmlyc3Ri eXRlICE9IE5PVF9TSEFSRUFCTEUgKQorICAgIHsKKyAgICAgICAgdWludDE2X3QgZmlyc3RieXRl ID0gcGdwLT5maXJzdGJ5dGU7CisgICAgICAgIGludCByZXQ7CisKKyAgICAgICAgdG1lbV9yZWFk X2xvY2soJnBjZF90cmVlX3J3bG9ja3NbZmlyc3RieXRlXSk7CisgICAgICAgIHJldCA9IHRtaF9j b3B5X3RvX2NsaWVudChjbWZuLCBwZ3AtPnBjZC0+cGZwLCB0bWVtX29mZnNldCwKKyAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIHBmbl9vZmZzZXQsIGxlbiwgY3ZhKTsKKyAgICAgICAg dG1lbV9yZWFkX3VubG9jaygmcGNkX3RyZWVfcndsb2Nrc1tmaXJzdGJ5dGVdKTsKKyAgICAgICAg aWYgKCByZXQgPT0gLUVGQVVMVCApCisgICAgICAgICAgICBnb3RvIGJhZF9jb3B5OwogICAgIH0K ICAgICBlbHNlIGlmICggdG1oX2NvcHlfdG9fY2xpZW50KGNtZm4sIHBncC0+cGZwLCB0bWVtX29m ZnNldCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHBmbl9vZmZzZXQsIGxlbiwg Y3ZhKSA9PSAtRUZBVUxUKQpAQCAtMTg1NSwxMSArMjAxNywxNCBAQCBzdGF0aWMgaW50IHRtZW1j X2xpc3RfZ2xvYmFsKHRtZW1fY2xpX3ZhCiAgICAgICB0b3RhbF9mbHVzaF9wb29sLCB1c2VfbG9u ZyA/ICcsJyA6ICdcbicpOwogICAgIGlmICh1c2VfbG9uZykKICAgICAgICAgbiArPSBzY25wcmlu dGYoaW5mbytuLEJTSVpFLW4sCi0gICAgICAgICAgIkVjOiVsZCxFbTolbGQsT2M6JWQsT206JWQs TmM6JWQsTm06JWQsUGM6JWQsUG06JWRcbiIsCisgICAgICAgICAgIkVjOiVsZCxFbTolbGQsT2M6 JWQsT206JWQsTmM6JWQsTm06JWQsUGM6JWQsUG06JWQsIgorICAgICAgICAgICJGYzolZCxGbTol ZCxTYzolZCxTbTolZFxuIiwKICAgICAgICAgICBnbG9iYWxfZXBoX2NvdW50LCBnbG9iYWxfZXBo X2NvdW50X21heCwKICAgICAgICAgICBfYXRvbWljX3JlYWQoZ2xvYmFsX29ial9jb3VudCksIGds b2JhbF9vYmpfY291bnRfbWF4LAogICAgICAgICAgIF9hdG9taWNfcmVhZChnbG9iYWxfcnRyZWVf bm9kZV9jb3VudCksIGdsb2JhbF9ydHJlZV9ub2RlX2NvdW50X21heCwKLSAgICAgICAgICBfYXRv bWljX3JlYWQoZ2xvYmFsX3BncF9jb3VudCksIGdsb2JhbF9wZ3BfY291bnRfbWF4KTsKKyAgICAg ICAgICBfYXRvbWljX3JlYWQoZ2xvYmFsX3BncF9jb3VudCksIGdsb2JhbF9wZ3BfY291bnRfbWF4 LAorICAgICAgICAgIF9hdG9taWNfcmVhZChnbG9iYWxfcGFnZV9jb3VudCksIGdsb2JhbF9wYWdl X2NvdW50X21heCwKKyAgICAgICAgICBfYXRvbWljX3JlYWQoZ2xvYmFsX3BjZF9jb3VudCksIGds b2JhbF9wY2RfY291bnRfbWF4KTsKICAgICBpZiAoIHN1bSArIG4gPj0gbGVuICkKICAgICAgICAg cmV0dXJuIHN1bTsKICAgICB0bWhfY29weV90b19jbGllbnRfYnVmX29mZnNldChidWYsb2ZmK3N1 bSxpbmZvLG4rMSk7CkBAIC0yNTY5LDEwICsyNzM0LDE4IEBAIEVYUE9SVCB2b2lkICp0bWVtX3Jl bGlucXVpc2hfcGFnZXModW5zaWcKIC8qIGNhbGxlZCBhdCBoeXBlcnZpc29yIHN0YXJ0dXAgKi8K IEVYUE9SVCB2b2lkIGluaXRfdG1lbSh2b2lkKQogeworICAgIGludCBpOwogICAgIGlmICggIXRt aF9lbmFibGVkKCkgKQogICAgICAgICByZXR1cm47CiAKICAgICByYWRpeF90cmVlX2luaXQoKTsK KyAgICBpZiAoIHRtaF9kZWR1cF9lbmFibGVkKCkgKQorICAgICAgICBmb3IgKGkgPSAwOyBpIDwg MjU2OyBpKysgKQorICAgICAgICB7CisgICAgICAgICAgICBwY2RfdHJlZV9yb290c1tpXSA9IFJC X1JPT1Q7CisgICAgICAgICAgICByd2xvY2tfaW5pdCgmcGNkX3RyZWVfcndsb2Nrc1tpXSk7Cisg ICAgICAgIH0KKwogICAgIGlmICggdG1oX2luaXQoKSApCiAgICAgewogICAgICAgICBwcmludGso InRtZW06IGluaXRpYWxpemVkIGNvbXA9JWQgZ2xvYmFsLWxvY2s9JWRcbiIsCmRpZmYgLXIgYjhk MmE0MTM0YTY4IHhlbi9jb21tb24vdG1lbV94ZW4uYwotLS0gYS94ZW4vY29tbW9uL3RtZW1feGVu LmMJV2VkIE1hciAwMyAxNzo0MTo1OCAyMDEwICswMDAwCisrKyBiL3hlbi9jb21tb24vdG1lbV94 ZW4uYwlUdWUgTWFyIDA5IDE0OjU4OjM3IDIwMTAgLTA3MDAKQEAgLTE5LDYgKzE5LDkgQEAgYm9v bGVhbl9wYXJhbSgidG1lbSIsIG9wdF90bWVtKTsKIAogRVhQT1JUIGludCBvcHRfdG1lbV9jb21w cmVzcyA9IDA7CiBib29sZWFuX3BhcmFtKCJ0bWVtX2NvbXByZXNzIiwgb3B0X3RtZW1fY29tcHJl c3MpOworCitFWFBPUlQgaW50IG9wdF90bWVtX2RlZHVwID0gMTsKK2Jvb2xlYW5fcGFyYW0oInRt ZW1fZGVkdXAiLCBvcHRfdG1lbV9kZWR1cCk7CiAKIEVYUE9SVCBpbnQgb3B0X3RtZW1fc2hhcmVk X2F1dGggPSAwOwogYm9vbGVhbl9wYXJhbSgidG1lbV9zaGFyZWRfYXV0aCIsIG9wdF90bWVtX3No YXJlZF9hdXRoKTsKZGlmZiAtciBiOGQyYTQxMzRhNjggeGVuL2luY2x1ZGUveGVuL3RtZW1feGVu LmgKLS0tIGEveGVuL2luY2x1ZGUveGVuL3RtZW1feGVuLmgJV2VkIE1hciAwMyAxNzo0MTo1OCAy MDEwICswMDAwCisrKyBiL3hlbi9pbmNsdWRlL3hlbi90bWVtX3hlbi5oCVR1ZSBNYXIgMDkgMTQ6 NTg6MzcgMjAxMCAtMDcwMApAQCAtNTIsNiArNTIsMTIgQEAgc3RhdGljIGlubGluZSBpbnQgdG1o X2NvbXByZXNzaW9uX2VuYWJsZQogc3RhdGljIGlubGluZSBpbnQgdG1oX2NvbXByZXNzaW9uX2Vu YWJsZWQodm9pZCkKIHsKICAgICByZXR1cm4gb3B0X3RtZW1fY29tcHJlc3M7Cit9CisKK2V4dGVy biBpbnQgb3B0X3RtZW1fZGVkdXA7CitzdGF0aWMgaW5saW5lIGludCB0bWhfZGVkdXBfZW5hYmxl ZCh2b2lkKQoreworICAgIHJldHVybiBvcHRfdG1lbV9kZWR1cDsKIH0KIAogZXh0ZXJuIGludCBv cHRfdG1lbV9zaGFyZWRfYXV0aDsKQEAgLTMyNiw2ICszMzIsMjggQEAgc3RhdGljIGlubGluZSBi b29sX3QgdG1oX2N1cnJlbnRfaXNfcHJpdgogICAgIHJldHVybiBJU19QUklWKGN1cnJlbnQtPmRv bWFpbik7CiB9CiAKK3N0YXRpYyBpbmxpbmUgdWludDhfdCB0bWhfZ2V0X2ZpcnN0X2J5dGUocGZw X3QgKnBmcCkKK3sKKyAgICB2b2lkICpwID0gX19tYXBfZG9tYWluX3BhZ2UocGZwKTsKKworICAg IHJldHVybiAodWludDhfdCkoKihjaGFyICopcCk7Cit9CisKK3N0YXRpYyBpbmxpbmUgaW50IHRt aF9wYWdlX2NtcChwZnBfdCAqcGZwMSwgcGZwX3QgKnBmcDIpCit7CisgICAgY29uc3QgdWludDY0 X3QgKnAxID0gKHVpbnQ2NF90ICopX19tYXBfZG9tYWluX3BhZ2UocGZwMSk7CisgICAgY29uc3Qg dWludDY0X3QgKnAyID0gKHVpbnQ2NF90ICopX19tYXBfZG9tYWluX3BhZ2UocGZwMik7CisgICAg aW50IGk7CisKKyAgICAvLyBGSVhNRTogY29kZSBpbiBhc3NlbWJseT8KKyAgICBmb3IgKCBpID0g UEFHRV9TSVpFL3NpemVvZih1aW50NjRfdCk7ICpwMSA9PSAqcDI7IGktLSwgKnAxKyssICpwMisr ICk7CisgICAgaWYgKCAhaSApCisgICAgICAgIHJldHVybiAwOworICAgIGlmICggKnAxIDwgKnAy ICkKKyAgICAgICAgcmV0dXJuIC0xOworICAgIHJldHVybiAxOworfQorCiAvKiB0aGVzZSB0eXBl ZGVmcyBhcmUgaW4gdGhlIHB1YmxpYy90bWVtLmggaW50ZXJmYWNlCiB0eXBlZGVmIFhFTl9HVUVT VF9IQU5ETEUodm9pZCkgY2xpX21mbl90OwogdHlwZWRlZiBYRU5fR1VFU1RfSEFORExFKGNoYXIp IGNsaV92YV90Owo= --__126817683329458327abhmt004 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Content-Disposition: inline _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel --__126817683329458327abhmt004--