From nobody@FreeBSD.org  Thu Jul 26 18:13:51 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 54F32106567B
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 26 Jul 2012 18:13:51 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 3EC048FC15
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 26 Jul 2012 18:13:51 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.4/8.14.4) with ESMTP id q6QIDohT040202
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 26 Jul 2012 18:13:50 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.4/8.14.4/Submit) id q6QIDo7R040201;
	Thu, 26 Jul 2012 18:13:50 GMT
	(envelope-from nobody)
Message-Id: <201207261813.q6QIDo7R040201@red.freebsd.org>
Date: Thu, 26 Jul 2012 18:13:50 GMT
From: Shane Nievera <nievera@mm.st>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] AES-NI XTS mode performance lower than CBC
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         170200
>Category:       kern
>Synopsis:       [crypto] [patch] AES-NI XTS mode performance lower than CBC
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    jmg
>State:          feedback
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          change-request
>Submitter-Id:   current-users
>Arrival-Date:   Thu Jul 26 18:20:07 UTC 2012
>Closed-Date:    
>Last-Modified:  Fri Jan 24 21:51:12 UTC 2014
>Originator:     Shane Nievera
>Release:        10.0-CURRENT
>Organization:
None
>Environment:
FreeBSD taxeater.zerocs.ca 10.0-CURRENT FreeBSD 10.0-CURRENT #0 r238772M: Wed Jul 25 18:18:50 UTC 2012     root@taxeater.zerocs.ca:/usr/obj/usr/src/sys/GENERIC  amd64

>Description:
Performance of XTS mode using aesni.ko driver is lower than expected.  AES-XTS mode is often slower than AES-CBC.

>How-To-Repeat:
Benchmark using tools/tools/cryptotest, or perform large file operations on a GEOM_ELI filesystem.

>Fix:
A patch is attached that makes the aesni driver call the assembly routines in
crypto/openssl.  This at least doubles the current throughput.  The attached
benchmark output is for an i5-2500, 10.0-current, Clang system with debugging
options on.  Appplying the patch to stable with gcc results in 16Gbps throughput
without maxing out the CPU.  Perl will be required to generate the assembly
instructions from the scripts in crypto/openssl.


Patch attached with submission follows:

Index: modules/aesni/Makefile
===================================================================
--- modules/aesni/Makefile	(revision 238810)
+++ modules/aesni/Makefile	(working copy)
@@ -4,7 +4,15 @@
 
 KMOD=	aesni
 SRCS=	aesni.c aesni_wrap.c
-SRCS+=	aesencdec_${MACHINE_CPUARCH}.S aeskeys_${MACHINE_CPUARCH}.S
+# SRCS+=	aesencdec_${MACHINE_CPUARCH}.S aeskeys_${MACHINE_CPUARCH}.S
+SRCS+=	aesencdec_${MACHINE_CPUARCH}.S aesni-xts-${MACHINE_CPUARCH}.s
 SRCS+=	device_if.h bus_if.h opt_bus.h cryptodev_if.h
 
+CLEANFILES+=	aesni-xts-${MACHINE_CPUARCH}.s
+
+aesni-xts-amd64.s: 
+	perl ${.CURDIR}/../../../crypto/openssl/crypto/aes/asm/aesni-x86_64.pl elf > ${.TARGET}
+aesni-xts-i386.s: 
+	perl ${.CURDIR}/../../../crypto/openssl/crypto/aes/asm/aesni-x86.pl elf > ${.TARGET}
+
 .include <bsd.kmod.mk>
Index: crypto/aesni/aesni.h
===================================================================
--- crypto/aesni/aesni.h	(revision 238810)
+++ crypto/aesni/aesni.h	(working copy)
@@ -52,13 +52,18 @@
 #define	AES256_ROUNDS	14
 #define	AES_SCHED_LEN	((AES256_ROUNDS + 1) * AES_BLOCK_LEN)
 
+struct aesni_sched {
+	uint8_t ks[AES_SCHED_LEN] __aligned(16);
+	int rounds;
+};
+
 struct aesni_session {
-	uint8_t enc_schedule[AES_SCHED_LEN] __aligned(16);
-	uint8_t dec_schedule[AES_SCHED_LEN] __aligned(16);
-	uint8_t xts_schedule[AES_SCHED_LEN] __aligned(16);
+	struct aesni_sched enc_sched __aligned(32);
+	struct aesni_sched dec_sched __aligned(32);
+	struct aesni_sched xts_sched __aligned(32);
 	uint8_t iv[AES_BLOCK_LEN];
 	int algo;
-	int rounds;
+	/* int rounds; */
 	/* uint8_t *ses_ictx; */
 	/* uint8_t *ses_octx; */
 	/* int ses_mlen; */
@@ -77,10 +82,16 @@
 void aesni_dec(int rounds, const uint8_t *key_schedule,
     const uint8_t from[AES_BLOCK_LEN], uint8_t to[AES_BLOCK_LEN],
     const uint8_t iv[AES_BLOCK_LEN]);
-void aesni_set_enckey(const uint8_t *userkey, uint8_t *encrypt_schedule,
-    int number_of_rounds);
-void aesni_set_deckey(const uint8_t *encrypt_schedule,
-    uint8_t *decrypt_schedule, int number_of_rounds);
+int aesni_set_encrypt_key(const uint8_t *userkey, int keylen,
+    struct aesni_sched *sched);
+int aesni_set_decrypt_key(const uint8_t *userkey, int keylen,
+    struct aesni_sched *sched);
+void aesni_xts_encrypt(uint8_t *from, uint8_t *to, size_t len,
+    struct aesni_sched *key1, struct aesni_sched *key2,
+    uint8_t iv[AES_BLOCK_LEN]);
+void aesni_xts_decrypt(uint8_t *from, uint8_t *to, size_t len,
+    struct aesni_sched *key1, struct aesni_sched *key2,
+    uint8_t iv[AES_BLOCK_LEN]);
 
 /*
  * Slightly more public interfaces.
Index: crypto/aesni/aesni_wrap.c
===================================================================
--- crypto/aesni/aesni_wrap.c	(revision 238810)
+++ crypto/aesni/aesni_wrap.c	(working copy)
@@ -82,6 +82,7 @@
 	}
 }
 
+#if 0
 #define	AES_XTS_BLOCKSIZE	16
 #define	AES_XTS_IVSIZE		8
 #define	AES_XTS_ALPHA		0x87	/* GF(2^128) generator polynomial */
@@ -169,6 +170,7 @@
 	aesni_crypt_xts(rounds, data_schedule, tweak_schedule, len, from, to,
 	    iv, 0);
 }
+#endif
 
 static int
 aesni_cipher_setup_common(struct aesni_session *ses, const uint8_t *key,
@@ -179,13 +181,8 @@
 	case CRYPTO_AES_CBC:
 		switch (keylen) {
 		case 128:
-			ses->rounds = AES128_ROUNDS;
-			break;
 		case 192:
-			ses->rounds = AES192_ROUNDS;
-			break;
 		case 256:
-			ses->rounds = AES256_ROUNDS;
 			break;
 		default:
 			return (EINVAL);
@@ -194,10 +191,8 @@
 	case CRYPTO_AES_XTS:
 		switch (keylen) {
 		case 256:
-			ses->rounds = AES128_ROUNDS;
-			break;
 		case 512:
-			ses->rounds = AES256_ROUNDS;
+			keylen >>= 1;
 			break;
 		default:
 			return (EINVAL);
@@ -207,13 +202,13 @@
 		return (EINVAL);
 	}
 
-	aesni_set_enckey(key, ses->enc_schedule, ses->rounds);
-	aesni_set_deckey(ses->enc_schedule, ses->dec_schedule, ses->rounds);
+	aesni_set_encrypt_key(key, keylen, &ses->enc_sched);
+	aesni_set_decrypt_key(key, keylen, &ses->dec_sched);
 	if (ses->algo == CRYPTO_AES_CBC)
 		arc4rand(ses->iv, sizeof(ses->iv), 0);
 	else /* if (ses->algo == CRYPTO_AES_XTS) */ {
-		aesni_set_enckey(key + keylen / 16, ses->xts_schedule,
-		    ses->rounds);
+		aesni_set_encrypt_key(key + (keylen >> 3), keylen,
+		    &ses->xts_sched);
 	}
 
 	return (0);
@@ -279,12 +274,12 @@
 			crypto_copyback(crp->crp_flags, crp->crp_buf,
 			    enccrd->crd_inject, AES_BLOCK_LEN, ses->iv);
 		if (ses->algo == CRYPTO_AES_CBC) {
-			aesni_encrypt_cbc(ses->rounds, ses->enc_schedule,
-			    enccrd->crd_len, buf, buf, ses->iv);
+			aesni_encrypt_cbc(ses->enc_sched.rounds + 1,
+			    &ses->enc_sched, enccrd->crd_len, buf, buf,
+			    ses->iv);
 		} else /* if (ses->algo == CRYPTO_AES_XTS) */ {
-			aesni_encrypt_xts(ses->rounds, ses->enc_schedule,
-			    ses->xts_schedule, enccrd->crd_len, buf, buf,
-			    ses->iv);
+			aesni_xts_encrypt(buf, buf, enccrd->crd_len,
+			    &ses->enc_sched, &ses->xts_sched, ses->iv);
 		}
 	} else {
 		if ((enccrd->crd_flags & CRD_F_IV_EXPLICIT) != 0)
@@ -293,12 +288,11 @@
 			crypto_copydata(crp->crp_flags, crp->crp_buf,
 			    enccrd->crd_inject, AES_BLOCK_LEN, ses->iv);
 		if (ses->algo == CRYPTO_AES_CBC) {
-			aesni_decrypt_cbc(ses->rounds, ses->dec_schedule,
-			    enccrd->crd_len, buf, ses->iv);
+			aesni_decrypt_cbc(ses->dec_sched.rounds + 1,
+			    &ses->dec_sched, enccrd->crd_len, buf, ses->iv);
 		} else /* if (ses->algo == CRYPTO_AES_XTS) */ {
-			aesni_decrypt_xts(ses->rounds, ses->dec_schedule,
-			    ses->xts_schedule, enccrd->crd_len, buf, buf,
-			    ses->iv);
+			aesni_xts_decrypt(buf, buf, enccrd->crd_len,
+			    &ses->dec_sched, &ses->xts_sched, ses->iv);
 		}
 	}
 	if (saved_ctx)

============= END DIFF =================

aesni@revision 238810:
   3.937 sec, 2000000    aes crypts,      16 bytes,  8128621 byte/sec,    62.0 Mb/sec
   4.105 sec, 2000000    xts crypts,      16 bytes,  7795364 byte/sec,    59.5 Mb/sec
   3.911 sec, 2000000 aes192 crypts,      16 bytes,  8182867 byte/sec,    62.4 Mb/sec
   3.912 sec, 2000000 aes256 crypts,      16 bytes,  8180568 byte/sec,    62.4 Mb/sec
   4.157 sec, 2000000 xts-256 crypts,      16 bytes,  7697874 byte/sec,    58.7 Mb/sec
   5.574 sec, 2000000    aes crypts,     512 bytes, 183701283 byte/sec,  1401.5 Mb/sec
   7.064 sec, 2000000    xts crypts,     512 bytes, 144957859 byte/sec,  1105.9 Mb/sec
   5.793 sec, 2000000 aes192 crypts,     512 bytes, 176753253 byte/sec,  1348.5 Mb/sec
   6.032 sec, 2000000 aes256 crypts,     512 bytes, 169761639 byte/sec,  1295.2 Mb/sec
   7.720 sec, 2000000 xts-256 crypts,     512 bytes, 132636989 byte/sec,  1011.9 Mb/sec
   1.631 sec,  200000    aes crypts,    4096 bytes, 502211582 byte/sec,  3831.6 Mb/sec
   2.690 sec,  200000    xts crypts,    4096 bytes, 304562262 byte/sec,  2323.6 Mb/sec
   1.817 sec,  200000 aes192 crypts,    4096 bytes, 450952825 byte/sec,  3440.5 Mb/sec
   2.001 sec,  200000 aes256 crypts,    4096 bytes, 409313072 byte/sec,  3122.8 Mb/sec
   3.231 sec,  200000 xts-256 crypts,    4096 bytes, 253510291 byte/sec,  1934.1 Mb/sec
aesni_openssl:
   3.927 sec, 2000000    aes crypts,      16 bytes,  8147903 byte/sec,    62.2 Mb/sec
   3.973 sec, 2000000    xts crypts,      16 bytes,  8054614 byte/sec,    61.5 Mb/sec
   3.936 sec, 2000000 aes192 crypts,      16 bytes,  8130494 byte/sec,    62.0 Mb/sec
   3.928 sec, 2000000 aes256 crypts,      16 bytes,  8147643 byte/sec,    62.2 Mb/sec
   4.025 sec, 2000000 xts-256 crypts,      16 bytes,  7950927 byte/sec,    60.7 Mb/sec
   5.500 sec, 2000000    aes crypts,     512 bytes, 186165740 byte/sec,  1420.3 Mb/sec
   4.820 sec, 2000000    xts crypts,     512 bytes, 212429975 byte/sec,  1620.7 Mb/sec
   5.769 sec, 2000000 aes192 crypts,     512 bytes, 177498680 byte/sec,  1354.2 Mb/sec
   5.981 sec, 2000000 aes256 crypts,     512 bytes, 171220193 byte/sec,  1306.3 Mb/sec
   4.956 sec, 2000000 xts-256 crypts,     512 bytes, 206606318 byte/sec,  1576.3 Mb/sec
   1.625 sec,  200000    aes crypts,    4096 bytes, 504053595 byte/sec,  3845.6 Mb/sec
   0.956 sec,  200000    xts crypts,    4096 bytes, 856864328 byte/sec,  6537.4 Mb/sec
   1.813 sec,  200000 aes192 crypts,    4096 bytes, 451837050 byte/sec,  3447.2 Mb/sec
   2.001 sec,  200000 aes256 crypts,    4096 bytes, 409391620 byte/sec,  3123.4 Mb/sec
   1.044 sec,  200000 xts-256 crypts,    4096 bytes, 784530799 byte/sec,  5985.5 Mb/sec


>Release-Note:
>Audit-Trail:

From: Shane Nievera Tablizo <nievera@mm.st>
To: bug-followup@FreeBSD.org
Cc:  
Subject: kern/170200: [crypto] [patch] AES-NI XTS mode performance lower than CBC
 revised patch
Date: Fri, 07 Sep 2012 12:40:48 -0600

 This is a multi-part message in MIME format.
 
 --_----------=_1347043248118301
 Content-Transfer-Encoding: 7bit
 Content-Type: text/plain
 
 This update removes the perl/openssl dependencies.  The c implementation
 is a drop-in replacement for the existing assembly code.  It captures
 most of the performance of the openssl module, and I still have a few
 optimizations to try.  amd64 only until I get clang to cross compile the
 module.  gcc4.2 lacks the opcodes for the new instructions, but it will
 compile with gcc47 from ports.  The module will compile with -mavx and
 improves performance in user-space.
 
 Shane Nievera Tablizo nievera@mm.st
 
 --_----------=_1347043248118301
 Content-Disposition: attachment; filename="patchv2.txt"
 Content-Id: <1347042863.10252.fae6270cf6c45bc6aa9d45c129ec3636611c6b50@messagingengine.com>
 Content-Transfer-Encoding: base64
 Content-Type: text/plain; name="patchv2.txt"
 
 SW5kZXg6IGNvbmYvZmlsZXMuYW1kNjQKPT09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
 PQotLS0gY29uZi9maWxlcy5hbWQ2NAkocmV2aXNpb24gMjQwMTI3KQorKysg
 Y29uZi9maWxlcy5hbWQ2NAkod29ya2luZyBjb3B5KQpAQCAtOTMsNiArOTMs
 MTEgQEAKIAluby1vYmogbm8taW1wbGljaXQtcnVsZQliZWZvcmUtZGVwZW5k
 CQkJCVwKIAljbGVhbgkJImFjcGlfd2FrZWRhdGEuaCIKICMKK2Flc19lbmNk
 ZWMubwkJCW9wdGlvbmFsCWFlc25pCQkJXAorCWRlcGVuZGVuY3kJIiRTL2Ny
 eXB0by9hZXNuaS9hZXNfZW5jZGVjLmMiCQkJXAorCWNvbXBpbGUtd2l0aAki
 Y2xhbmcgJHtDRkxBR1M6Ti1tbm8tc3NlfSAtbXNzZSAtYyAkey5JTVBTUkN9
 IglcCisJbm8taW1wbGljaXQtcnVsZSBjbGVhbiAiYWVzX2VuY2RlYy5vIgor
 IwogYW1kNjQvYW1kNjQvYW1kNjRfbWVtLmMJCW9wdGlvbmFsCW1lbQogI2Ft
 ZDY0L2FtZDY0L2FwaWNfdmVjdG9yLlMJc3RhbmRhcmQKIGFtZDY0L2FtZDY0
 L2F0b21pYy5jCQlzdGFuZGFyZApAQCAtMTMxLDcgKzEzNiw3IEBACiBhbWQ2
 NC9hbWQ2NC92bV9tYWNoZGVwLmMJc3RhbmRhcmQKIGFtZDY0L3BjaS9wY2lf
 Y2ZncmVnLmMJCW9wdGlvbmFsCXBjaQogY2RkbC9jb250cmliL29wZW5zb2xh
 cmlzL2NvbW1vbi9hdG9taWMvYW1kNjQvb3BlbnNvbGFyaXNfYXRvbWljLlMJ
 b3B0aW9uYWwgemZzIGNvbXBpbGUtd2l0aCAiJHtaRlNfU30iCi1jcnlwdG8v
 YWVzbmkvYWVzZW5jZGVjX2FtZDY0LlMJb3B0aW9uYWwgYWVzbmkKKyNjcnlw
 dG8vYWVzbmkvYWVzZW5jZGVjX2FtZDY0LlMJb3B0aW9uYWwgYWVzbmkKIGNy
 eXB0by9hZXNuaS9hZXNrZXlzX2FtZDY0LlMJb3B0aW9uYWwgYWVzbmkKIGNy
 eXB0by9hZXNuaS9hZXNuaS5jCQlvcHRpb25hbCBhZXNuaQogY3J5cHRvL2Fl
 c25pL2Flc25pX3dyYXAuYwlvcHRpb25hbCBhZXNuaQpJbmRleDogY3J5cHRv
 L2Flc25pL2Flc25pLmgKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gY3J5
 cHRvL2Flc25pL2Flc25pLmgJKHJldmlzaW9uIDI0MDEyNykKKysrIGNyeXB0
 by9hZXNuaS9hZXNuaS5oCSh3b3JraW5nIGNvcHkpCkBAIC05NCw2ICs5NCwx
 NSBAQAogdm9pZCBhZXNuaV9kZWNyeXB0X2VjYihpbnQgcm91bmRzLCBjb25z
 dCB2b2lkICprZXlfc2NoZWR1bGUsIHNpemVfdCBsZW4sCiAgICAgY29uc3Qg
 dWludDhfdCBmcm9tW0FFU19CTE9DS19MRU5dLCB1aW50OF90IHRvW0FFU19C
 TE9DS19MRU5dKTsKIAorI2lmZGVmIF9fYW1kNjRfXwordm9pZCBhZXNuaV9l
 bmNyeXB0X3h0cyhpbnQgcm91bmRzLCBjb25zdCB2b2lkICpkYXRhX3NjaGVk
 dWxlLAorICAgIGNvbnN0IHZvaWQgKnR3ZWFrX3NjaGVkdWxlLCBzaXplX3Qg
 bGVuLCBjb25zdCB1aW50OF90ICpmcm9tLCB1aW50OF90ICp0bywKKyAgICBj
 b25zdCB1aW50OF90IGl2W0FFU19CTE9DS19MRU5dKTsKK3ZvaWQgYWVzbmlf
 ZGVjcnlwdF94dHMoaW50IHJvdW5kcywgY29uc3Qgdm9pZCAqZGF0YV9zY2hl
 ZHVsZSwKKyAgICBjb25zdCB2b2lkICp0d2Vha19zY2hlZHVsZSwgc2l6ZV90
 IGxlbiwgY29uc3QgdWludDhfdCAqZnJvbSwgdWludDhfdCAqdG8sCisgICAg
 Y29uc3QgdWludDhfdCBpdltBRVNfQkxPQ0tfTEVOXSk7CisjZW5kaWYKKwog
 aW50IGFlc25pX2NpcGhlcl9zZXR1cChzdHJ1Y3QgYWVzbmlfc2Vzc2lvbiAq
 c2VzLAogICAgIHN0cnVjdCBjcnlwdG9pbmkgKmVuY2luaSk7CiBpbnQgYWVz
 bmlfY2lwaGVyX3Byb2Nlc3Moc3RydWN0IGFlc25pX3Nlc3Npb24gKnNlcywK
 SW5kZXg6IGNyeXB0by9hZXNuaS9hZXNfZW5jZGVjLmMKPT09PT09PT09PT09
 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PQotLS0gY3J5cHRvL2Flc25pL2Flc19lbmNkZWMuYwkocmV2
 aXNpb24gMCkKKysrIGNyeXB0by9hZXNuaS9hZXNfZW5jZGVjLmMJKHdvcmtp
 bmcgY29weSkKQEAgLTAsMCArMSwzMTEgQEAKKy8qLQorICogQ29weXJpZ2h0
 IChjKSAyMDEyIFNoYW5lIE5pZXZlcmEgVGFibGl6bworICogQWxsIHJpZ2h0
 cyByZXNlcnZlZC4KKyAqCisgKiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGlu
 IHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRoIG9yIHdpdGhvdXQKKyAq
 IG1vZGlmaWNhdGlvbiwgYXJlIHBlcm1pdHRlZCBwcm92aWRlZCB0aGF0IHRo
 ZSBmb2xsb3dpbmcgY29uZGl0aW9ucworICogYXJlIG1ldDoKKyAqIDEuIFJl
 ZGlzdHJpYnV0aW9ucyBvZiBzb3VyY2UgY29kZSBtdXN0IHJldGFpbiB0aGUg
 YWJvdmUgY29weXJpZ2h0CisgKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBj
 b25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIuCisgKiAy
 LiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVzdCByZXByb2R1
 Y2UgdGhlIGFib3ZlIGNvcHlyaWdodAorICogICAgbm90aWNlLCB0aGlzIGxp
 c3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVy
 IGluIHRoZQorICogICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0
 ZXJpYWxzIHByb3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4KKyAqCisg
 KiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBBVVRIT1IgQU5E
 IENPTlRSSUJVVE9SUyBgYEFTIElTJycgQU5ECisgKiBBTlkgRVhQUkVTUyBP
 UiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1J
 VEVEIFRPLCBUSEUKKyAqIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFO
 VEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NF
 CisgKiBBUkUgRElTQ0xBSU1FRC4gIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBB
 VVRIT1IgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRQorICogRk9SIEFOWSBE
 SVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExB
 UlksIE9SIENPTlNFUVVFTlRJQUwKKyAqIERBTUFHRVMgKElOQ0xVRElORywg
 QlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRF
 IEdPT0RTCisgKiBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsIERBVEEsIE9S
 IFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikKKyAqIEhPV0VW
 RVIgQ0FVU0VEIEFORCBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hF
 VEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUCisgKiBMSUFCSUxJVFksIE9SIFRP
 UlQgKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lO
 RyBJTiBBTlkgV0FZCisgKiBPVVQgT0YgVEhFIFVTRSBPRiBUSElTIFNPRlRX
 QVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GCisg
 KiBTVUNIIERBTUFHRS4KKyAqCisgKi8KKworI2luY2x1ZGUgPHN5cy9wYXJh
 bS5oPgorI2lmZGVmIF9LRVJORUwKKyNpbmNsdWRlIDxjcnlwdG8vYWVzbmkv
 YWVzbmkuaD4KKyNlbmRpZgorCisjaWZuZGVmIF9LRVJORUwKKyNpbmNsdWRl
 ICJhZXNfZW5jZGVjLmgiCisjZW5kaWYKKwordHlwZWRlZiB1aW50NjRfdAlk
 cXVhZCBfX2F0dHJpYnV0ZV9fKChfX3ZlY3Rvcl9zaXplX18oMTYpKSk7Cit0
 eXBlZGVmIGludAkJcV9pbnQgX19hdHRyaWJ1dGVfXygoX192ZWN0b3Jfc2l6
 ZV9fKDE2KSkpOworCisjZGVmaW5lIFY0WkVSTwkJKHFfaW50KXsgMCwgMCwg
 MCwgMH0KKworI2RlZmluZSBERUZBU00obW4sIG91dF90LCBpbl90LCBpbl9z
 cGVjKQkJCQlcCisJc3RhdGljIGlubGluZSBvdXRfdCBfX2F0dHJpYnV0ZV9f
 KChhbHdheXNfaW5saW5lKSkJCVwKKwltbiAjIyBfYXNtKG91dF90IF9fYSwg
 aW5fdCBfX2IpCQkJCQlcCisJeyAgICAgICAgICAgICAgICAgICAgICAgICAg
 ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFwKKwkJX19h
 c21fXygjbW4gIiAlMSwgJTAiIDogIismeCIgKF9fYSkgOiBpbl9zcGVjIChf
 X2IpKTsJXAorCQlyZXR1cm4gKF9fYSk7CQkJCQkJXAorCX0KKworI2RlZmlu
 ZSBTV19ST1VORFMocm91bmRzLCBmKQkJCQkJCVwKKwlzd2l0Y2ggKHJvdW5k
 cykgewkJCQkJCVwKKwkJY2FzZSBBRVMxMjhfUk9VTkRTOiByb3VuZHMgPSBB
 RVMxMjhfUk9VTkRTOyBmOyBicmVhazsJXAorCQljYXNlIEFFUzE5Ml9ST1VO
 RFM6IHJvdW5kcyA9IEFFUzE5Ml9ST1VORFM7IGY7IGJyZWFrOwlcCisJCWNh
 c2UgQUVTMjU2X1JPVU5EUzogcm91bmRzID0gQUVTMjU2X1JPVU5EUzsgZjsg
 YnJlYWs7CVwKKwl9CisKK0RFRkFTTShwc3JhZCwgZHF1YWQsIGludCwgIkki
 KQorREVGQVNNKGFlc2VuYywgZHF1YWQsIGRxdWFkLCAieCIpCitERUZBU00o
 YWVzZGVjLCBkcXVhZCwgZHF1YWQsICJ4IikKK0RFRkFTTShhZXNlbmNsYXN0
 LCBkcXVhZCwgZHF1YWQsICJ4IikKK0RFRkFTTShhZXNkZWNsYXN0LCBkcXVh
 ZCwgZHF1YWQsICJ4IikKKworc3RhdGljIGlubGluZSBkcXVhZCBfX2F0dHJp
 YnV0ZV9fKChhbHdheXNfaW5saW5lKSkKK2xvYWR1X2FzbShjb25zdCBkcXVh
 ZCAqcmVzdHJpY3QgcCkKK3sKKwlkcXVhZCB6OworCisJX19hc21fXygibW92
 ZHF1CSUxLCAlMCIgOiAiPXgiICh6KSA6ICJtIiAoKnApKTsKKworCXJldHVy
 biAoeik7Cit9CisKKyNkZWZpbmUgbG9hZHUoeCkJCWxvYWR1X2FzbSgoeCkp
 CisjZGVmaW5lIHBzcmFkKGkseCkJCXBzcmFkX2FzbSgoeCksIChpKSkKKyNk
 ZWZpbmUgYWVzZW5jCQkJYWVzZW5jX2FzbQorI2RlZmluZSBhZXNkZWMJCQlh
 ZXNkZWNfYXNtCisjZGVmaW5lIGFlc2RlY2xhc3QJCWFlc2RlY2xhc3RfYXNt
 CisjZGVmaW5lIGFlc2VuY2xhc3QJCWFlc2VuY2xhc3RfYXNtCisKK3N0YXRp
 YyBpbmxpbmUgZHF1YWQgX19hdHRyaWJ1dGVfXygoYWx3YXlzX2lubGluZSkp
 Cittb3ZkcXUoY29uc3QgdWludDhfdCAqcmVzdHJpY3QgcCkKK3sKKworCXJl
 dHVybiAobG9hZHUoKGRxdWFkKilwKSk7Cit9CisKK3N0YXRpYyBpbmxpbmUg
 ZHF1YWQgX19hdHRyaWJ1dGUoKGFsd2F5c19pbmxpbmUpKQorZW5jZGVjKGlu
 dCBkaXIsIGludCByb3VuZHMsIGNvbnN0IGRxdWFkICpyZXN0cmljdCBzY2hl
 ZCwgZHF1YWQgdCkKK3sKKworCXQgXj0gKnNjaGVkOworCisJZm9yICg7IC0t
 cm91bmRzOykKKwkJdCA9IChkaXIgPyBhZXNlbmMgOiBhZXNkZWMpKHQsICor
 K3NjaGVkKTsKKworCXJldHVybiAoZGlyID8gYWVzZW5jbGFzdCA6IGFlc2Rl
 Y2xhc3QpKHQsICorK3NjaGVkKTsKK30KKyNkZWZpbmUgQ1JZUFQoeCkJZW5j
 ZGVjKGRpciwgcm91bmRzLCAoZHF1YWQqKXNjaGVkLCAoeCkpCisjZGVmaW5l
 IERFQyh4KQkJZW5jZGVjKDAsIHJvdW5kcywgKGRxdWFkKilzY2hlZCwgKHgp
 KQorCitzdGF0aWMgaW5saW5lIHZvaWQgX19hdHRyaWJ1dGUoKGFsd2F5c19p
 bmxpbmUpKQorZGVjcnlwdF9jYmNfWDYoaW50IHJvdW5kcywgY29uc3QgZHF1
 YWQgKnJlc3RyaWN0IHNjaGVkLCBzaXplX3QgbiwKKyAgICBkcXVhZCAqcmVz
 dHJpY3Qgc3JjLCBkcXVhZCB0MCkKKy8qIFRPRE86ICBQaXBlbGluZSB0aGlz
 IHdpdGhvdXQgZXhwbGljaXQgdmFycy4gKi8KK3sKKwlkcXVhZAkgdDEsIHQy
 LCB0MywgdDQsIHQ1LCB0NjsKKwlkcXVhZAkgZGEsIGRiLCBkYywgZGQsIGRl
 LCBkZjsKKworCXNpemVfdAkgbTsKKwkKKwlpZiAoMCA8IChtID0gbiAvIDYp
 KSB7CisJCWRhID0gdDEgPSBzcmNbMF07IGRiID0gdDIgPSBzcmNbMV07IGRj
 ID0gdDMgPSBzcmNbMl07CisJCWRkID0gdDQgPSBzcmNbM107IGRlID0gdDUg
 PSBzcmNbNF07IGRmID0gdDYgPSBzcmNbNV07CisJCWZvciAoOzspIHsKKwkJ
 CWRhID0gREVDKGRhKTsgZGIgPSBERUMoZGIpOyBkYyA9IERFQyhkYyk7CisJ
 CQlkZCA9IERFQyhkZCk7IGRlID0gREVDKGRlKTsgZGYgPSBERUMoZGYpOwor
 CisJCQkqc3JjID0gZGEgXiB0MDsgKisrc3JjID0gZGIgXiB0MTsgKisrc3Jj
 ID0gZGMgXiB0MjsKKwkJCSorK3NyYyA9IGRkIF4gdDM7ICorK3NyYyA9IGRl
 IF4gdDQ7ICorK3NyYyA9IGRmIF4gdDU7CisKKwkJCSsrc3JjOworCQkJdDAg
 PSB0NjsKKwkJCWlmICgtLW0gPT0gMCkKKwkJCQlicmVhazsKKwkJCWRhID0g
 dDEgPSBzcmNbMF07IGRiID0gdDIgPSBzcmNbMV07IGRjID0gdDMgPSBzcmNb
 Ml07CisJCQlkZCA9IHQ0ID0gc3JjWzNdOyBkZSA9IHQ1ID0gc3JjWzRdOyBk
 ZiA9IHQ2ID0gc3JjWzVdOworCQl9CisJfQorCWlmIChuICUgMiA9PSAxKSB7
 CisJCWRhID0gdDEgPSBzcmNbMF07CisJCWRhID0gREVDKGRhKTsKKwkJKnNy
 YyA9IGRhIF4gdDA7CisJCSsrc3JjOyAtLW47CisJCXQwID0gdDE7CisKKwl9
 CisJc3dpdGNoIChuICU9IDYpIHsKKwkJY2FzZSAyOgorCQkJZGEgPSB0MSA9
 IHNyY1swXTsgZGIgPSB0MiA9IHNyY1sxXTsKKwkJCWRhID0gREVDKGRhKTsg
 ZGIgPSBERUMoZGIpOworCQkJKnNyYyA9IGRhIF4gdDA7ICorK3NyYyA9IGRi
 IF4gdDE7CisJCQkrK3NyYzsKKwkJCXQwID0gdDI7CisJCQlicmVhazsKKwkJ
 Y2FzZSA0OgorCQkJZGEgPSB0MSA9IHNyY1swXTsgZGIgPSB0MiA9IHNyY1sx
 XTsKKwkJCWRjID0gdDMgPSBzcmNbMl07IGRkID0gdDQgPSBzcmNbM107CisJ
 CQlkYSA9IERFQyhkYSk7IGRiID0gREVDKGRiKTsgZGMgPSBERUMoZGMpOyBk
 ZCA9IERFQyhkZCk7CisJCQkqc3JjID0gZGEgXiB0MDsgKisrc3JjID0gZGIg
 XiB0MTsKKwkJCSorK3NyYyA9IGRjIF4gdDI7ICorK3NyYyA9IGRkIF4gdDM7
 CisJCQlicmVhazsKKwl9Cit9CisKKy8qICNkZWZpbmUgR0YxMjhfR0VORVJB
 VE9SCTB4ODcgKi8KKworc3RhdGljIGlubGluZSBkcXVhZCBfX2F0dHJpYnV0
 ZSgoYWx3YXlzX2lubGluZSkpCitHRjEyOF9zaGwoZHF1YWQgeikKK3sKKwlk
 cXVhZCBhLCBjOworCisJYyA9IChkcXVhZCl7IDB4ODcgLyogR0YxMjggZ2Vu
 ZXJhdG9yICovLCAxIH07CisKKwlhID0gcHNyYWQoMzEsIF9fYnVpbHRpbl9z
 aHVmZmxldmVjdG9yKChxX2ludCl6LCBWNFpFUk8sIDMsIDMsIDEsIDEpKTsK
 KworCXJldHVybiAoeiArIHogXiBhICYgYyk7Cit9CisKK3N0YXRpYyBpbmxp
 bmUgdm9pZAoraW5pdF90d2Vha3MoZHF1YWQgKnJlc3RyaWN0IHRzLCBpbnQg
 bikKK3sKKwlpbnQgaTsKKworCWZvciAoaSA9IDA7ICBpIDwgbiAtIDE7ICsr
 aSkKKwkJdHNbaSsxXSA9IEdGMTI4X3NobCh0c1tpXSk7Cit9CisKK3N0YXRp
 YyBpbmxpbmUgdm9pZAorb3V0X3hvcihkcXVhZCAqcmVzdHJpY3QgZHMsIGRx
 dWFkICpyZXN0cmljdCB0cywgZHF1YWQgKnJlc3RyaWN0ICpkc3QsIGludCBu
 KQoreworCWludCBpOworCisJZm9yIChpID0gMDsgaSA8IG47ICsraSwgKysq
 ZHN0KQorCQkqKmRzdCA9IGRzW2ldIF4gdHNbaV07Cit9CisKK3N0YXRpYyBp
 bmxpbmUgdm9pZAorbGxlbF9jcnlwdChpbnQgZGlyLCBpbnQgcm91bmRzLCBj
 b25zdCBkcXVhZCAqcmVzdHJpY3Qgc2NoZWQsIGRxdWFkICpyZXN0cmljdCBk
 cywKKyAgICBkcXVhZCAqcmVzdHJpY3QgdHMsIGNvbnN0IGRxdWFkICoqc3Jj
 LCBpbnQgbikKK3sKKwlpbnQgaTsKKworCWZvciAoaSA9IDA7IGkgPCBuOyAr
 K2ksICsrKnNyYykKKwkJZHNbaV0gPSBDUllQVCggKipzcmMgXiB0c1tpXSk7
 Cit9CisKK3N0YXRpYyBpbmxpbmUgdm9pZCBfX2F0dHJpYnV0ZSgoYWx3YXlz
 X2lubGluZSkpCitjcnlwdF94ZXhfWDYoaW50IGRpciwgaW50IHJvdW5kcywg
 Y29uc3QgZHF1YWQgKnJlc3RyaWN0IHNjaGVkLCBzaXplX3QgbiwKKyAgICBj
 b25zdCBkcXVhZCAqc3JjLCBkcXVhZCAqZHN0LCBkcXVhZCB0MCkKK3sKKwlk
 cXVhZAlkWzZdOworCWRxdWFkCXRbNl07CisJc2l6ZV90CW07CisKKwl0WzBd
 ID0gdDA7CisKKwlpZiAoMCA8IChtID0gbiAvIDYpKSB7CisJCWluaXRfdHdl
 YWtzKHQsIDYpOworCQlmb3IgKDs7KSB7CisJCQlsbGVsX2NyeXB0KGRpciwg
 cm91bmRzLCBzY2hlZCwgZCwgdCwgJnNyYywgNik7CisJCQlvdXRfeG9yKGQs
 IHQsICZkc3QsIDYpOworCQkJdFswXSA9IEdGMTI4X3NobCh0WzVdKTsKKwkJ
 CWlmICgtLW0gPT0gMCkKKwkJCQlicmVhazsKKwkJCWluaXRfdHdlYWtzKHQs
 IDYpOworCQl9CisKKwl9CisJaWYgKG4gJSAyID09IDEpIHsKKwkJKmRzdCsr
 ID0gKnQgXiBDUllQVCgqdCBeICpzcmMrKyk7CisJCSp0ID0gR0YxMjhfc2hs
 KCp0KTsKKwkJLS1uOworCX0KKwlzd2l0Y2ggKG4gJT0gNikgeworCWNhc2Ug
 MjoKKwkJbiA9IDI7CisJCWluaXRfdHdlYWtzKHQsIG4pOworCQlsbGVsX2Ny
 eXB0KGRpciwgcm91bmRzLCBzY2hlZCwgZCwgdCwgJnNyYywgbik7CisJCW91
 dF94b3IoZCwgdCwgJmRzdCwgbik7CisJCWJyZWFrOworCWNhc2UgNDoKKwkJ
 biA9IDQ7CisJCWluaXRfdHdlYWtzKHQsIG4pOworCQlsbGVsX2NyeXB0KGRp
 ciwgcm91bmRzLCBzY2hlZCwgZCwgdCwgJnNyYywgbik7CisJCW91dF94b3Io
 ZCwgdCwgJmRzdCwgbik7CisJCWJyZWFrOworCX0KK30KKwordm9pZAorYWVz
 bmlfZW5jKGludCByb3VuZHMsIGNvbnN0IHVpbnQ4X3QgKnJlc3RyaWN0IHNj
 aGVkLCBjb25zdCB1aW50OF90ICpzcmMsCisgICAgdWludDhfdCAqZHN0LCBj
 b25zdCB1aW50OF90ICpyZXN0cmljdCBpdikKK3sKKworCSooZHF1YWQqKWRz
 dCA9IGVuY2RlYygxLCByb3VuZHMsIChkcXVhZCopc2NoZWQsIGl2ID09IE5V
 TEwgPworCQkJCSooZHF1YWQqKXNyYyA6ICooZHF1YWQqKXNyYyBeIG1vdmRx
 dShpdikpOworfQorCit2b2lkCithZXNuaV9kZWMoaW50IHJvdW5kcywgY29u
 c3QgdWludDhfdCAqcmVzdHJpY3Qgc2NoZWQsIGNvbnN0IHVpbnQ4X3QgKnNy
 YywKKyAgICB1aW50OF90ICpkc3QsIGNvbnN0IHVpbnQ4X3QgKnJlc3RyaWN0
 IGl2KQoreworCisJKihkcXVhZCopZHN0ID0gZW5jZGVjKDAsIHJvdW5kcywg
 KGRxdWFkKilzY2hlZCwgKihkcXVhZCopc3JjKTsKKwkqKGRxdWFkKilkc3Qg
 PSAoaXYgPT0gTlVMTCkgPyAqKGRxdWFkKilkc3QgOiAqKGRxdWFkKilkc3Qg
 XiBtb3ZkcXUoaXYpOworfQorCit2b2lkCithZXNuaV9lbmNyeXB0X2NiYyhp
 bnQgcm91bmRzLCBjb25zdCB2b2lkICpyZXN0cmljdCBzY2hlZCwgc2l6ZV90
 IGxlbiwKKyAgICBjb25zdCB1aW50OF90ICpzcmMsIHVpbnQ4X3QgKmRzdCwg
 Y29uc3QgdWludDhfdCAqcmVzdHJpY3QgaXZwKQoreworCWRxdWFkCSBpdjsK
 KwlkcXVhZAkqcCwgKnE7CisKKwlsZW4gLz0gQUVTX0JMT0NLX0xFTjsKKwlp
 diA9IG1vdmRxdShpdnApOworCXAgPSAoZHF1YWQqKXNyYzsKKwlxID0gKGRx
 dWFkKilkc3Q7CisKKyNkZWZpbmUJRU5DUllQVF9DQkNfTE9PUAkJCQkJCVwK
 Kwlmb3IgKDsgbGVuLS07ICsrcCwgKytxKSB7CQkJCQlcCisJCWl2ID0gZW5j
 ZGVjKDEsIHJvdW5kcywgKGRxdWFkKilzY2hlZCwgKnAgXiBpdik7CQlcCisJ
 CSpxID0gaXY7CQkJCQkJXAorCX0KKwlTV19ST1VORFMocm91bmRzLCBFTkNS
 WVBUX0NCQ19MT09QKQorfQorCit2b2lkCithZXNuaV9kZWNyeXB0X2NiYyhp
 bnQgcm91bmRzLCBjb25zdCB2b2lkICpyZXN0cmljdCBzY2hlZCwgc2l6ZV90
 IGxlbiwKKyAgICBjb25zdCB1aW50OF90ICpyZXN0cmljdCBkYXQsIGNvbnN0
 IHVpbnQ4X3QgKnJlc3RyaWN0IGl2cCkKK3sKKwlkcXVhZCBpdjsKKworCWl2
 ID0gbW92ZHF1KGl2cCk7CisJU1dfUk9VTkRTKHJvdW5kcywgZGVjcnlwdF9j
 YmNfWDYocm91bmRzLCBzY2hlZCwgbGVuIC8gQUVTX0JMT0NLX0xFTiwKKwkJ
 CQkoZHF1YWQqKWRhdCwgaXYpKQorfQorCisjZGVmaW5lIENSWVBUX1hFWF9Y
 NihkaXIpCShcCisJCWNyeXB0X3hleF9YNigoZGlyKSwgcm91bmRzLCBzY2hl
 ZCwgbGVuIC8gQUVTX0JMT0NLX0xFTiwJXAorCQkJKGRxdWFkKilzcmMsIChk
 cXVhZCopZHN0LAkJCVwKKwkJCWVuY2RlYygxLCByb3VuZHMsIHhzY2hlZCwg
 bW92ZHF1KGl2cCkpKQkJXAorCQkpCit2b2lkCithZXNuaV9lbmNyeXB0X3h0
 cyhpbnQgcm91bmRzLCBjb25zdCB2b2lkICpyZXN0cmljdCBzY2hlZCwKKyAg
 ICBjb25zdCB2b2lkICpyZXN0cmljdCB4c2NoZWQsIHNpemVfdCBsZW4sIGNv
 bnN0IHVpbnQ4X3QgKnNyYywgdWludDhfdCAqZHN0LAorICAgIGNvbnN0IHVp
 bnQ4X3QgKnJlc3RyaWN0IGl2cCkKK3sKKworCVNXX1JPVU5EUyhyb3VuZHMs
 IENSWVBUX1hFWF9YNigxKSkKK30KKwordm9pZAorYWVzbmlfZGVjcnlwdF94
 dHMoaW50IHJvdW5kcywgY29uc3Qgdm9pZCAqcmVzdHJpY3Qgc2NoZWQsCisg
 ICAgY29uc3Qgdm9pZCAqcmVzdHJpY3QgeHNjaGVkLCBzaXplX3QgbGVuLCBj
 b25zdCB1aW50OF90ICpzcmMsIHVpbnQ4X3QgKmRzdCwKKyAgICBjb25zdCB1
 aW50OF90ICpyZXN0cmljdCBpdnApCit7CisKKwlTV19ST1VORFMocm91bmRz
 LCBDUllQVF9YRVhfWDYoMCkpCit9CisKSW5kZXg6IGNyeXB0by9hZXNuaS9h
 ZXNuaV93cmFwLmMKPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PQotLS0gY3J5cHRv
 L2Flc25pL2Flc25pX3dyYXAuYwkocmV2aXNpb24gMjQwMTI3KQorKysgY3J5
 cHRvL2Flc25pL2Flc25pX3dyYXAuYwkod29ya2luZyBjb3B5KQpAQCAtMzcs
 NiArMzcsNyBAQAogCiBNQUxMT0NfREVDTEFSRShNX0FFU05JKTsKIAorI2lm
 bmRlZiBfX2FtZDY0X18KIHZvaWQKIGFlc25pX2VuY3J5cHRfY2JjKGludCBy
 b3VuZHMsIGNvbnN0IHZvaWQgKmtleV9zY2hlZHVsZSwgc2l6ZV90IGxlbiwK
 ICAgICBjb25zdCB1aW50OF90ICpmcm9tLCB1aW50OF90ICp0bywgY29uc3Qg
 dWludDhfdCBpdltBRVNfQkxPQ0tfTEVOXSkKQEAgLTUzLDYgKzU0LDcgQEAK
 IAkJdG8gKz0gQUVTX0JMT0NLX0xFTjsKIAl9CiB9CisjZW5kaWYKIAogdm9p
 ZAogYWVzbmlfZW5jcnlwdF9lY2IoaW50IHJvdW5kcywgY29uc3Qgdm9pZCAq
 a2V5X3NjaGVkdWxlLCBzaXplX3QgbGVuLApAQCAtODIsNiArODQsNyBAQAog
 CX0KIH0KIAorI2lmbmRlZiBfX2FtZDY0X18KICNkZWZpbmUJQUVTX1hUU19C
 TE9DS1NJWkUJMTYKICNkZWZpbmUJQUVTX1hUU19JVlNJWkUJCTgKICNkZWZp
 bmUJQUVTX1hUU19BTFBIQQkJMHg4NwkvKiBHRigyXjEyOCkgZ2VuZXJhdG9y
 IHBvbHlub21pYWwgKi8KQEAgLTE2OSw2ICsxNzIsNyBAQAogCWFlc25pX2Ny
 eXB0X3h0cyhyb3VuZHMsIGRhdGFfc2NoZWR1bGUsIHR3ZWFrX3NjaGVkdWxl
 LCBsZW4sIGZyb20sIHRvLAogCSAgICBpdiwgMCk7CiB9CisjZW5kaWYKIAog
 c3RhdGljIGludAogYWVzbmlfY2lwaGVyX3NldHVwX2NvbW1vbihzdHJ1Y3Qg
 YWVzbmlfc2Vzc2lvbiAqc2VzLCBjb25zdCB1aW50OF90ICprZXksCkluZGV4
 OiBtb2R1bGVzL2Flc25pL01ha2VmaWxlCj09PT09PT09PT09PT09PT09PT09
 PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09
 PT0KLS0tIG1vZHVsZXMvYWVzbmkvTWFrZWZpbGUJKHJldmlzaW9uIDI0MDEy
 NykKKysrIG1vZHVsZXMvYWVzbmkvTWFrZWZpbGUJKHdvcmtpbmcgY29weSkK
 QEAgLTQsNyArNCwxOSBAQAogCiBLTU9EPQlhZXNuaQogU1JDUz0JYWVzbmku
 YyBhZXNuaV93cmFwLmMKLVNSQ1MrPQlhZXNlbmNkZWNfJHtNQUNISU5FX0NQ
 VUFSQ0h9LlMgYWVza2V5c18ke01BQ0hJTkVfQ1BVQVJDSH0uUworU1JDUys9
 CWFlc2tleXNfJHtNQUNISU5FX0NQVUFSQ0h9LlMKKworLmlmICR7TUFDSElO
 RV9DUFVBUkNIfSA9PSAiaTM4NiIKK1NSQ1MrPQlhZXNlbmNkZWNfJHtNQUNI
 SU5FX0NQVUFSQ0h9LlMKKy5lbmRpZgorCisuaWYgJHtNQUNISU5FX0NQVUFS
 Q0h9ID09ICJhbWQ2NCIKK0FFU05JX0NGTEFHUz0gJChDRkxBR1M6Ti1tbm8t
 c3NlKSAtbXNzZQorT0JKUz0JYWVzX2VuY2RlYy5vCithZXNfZW5jZGVjLm86
 CWFlc19lbmNkZWMuYworCWNsYW5nICQoQUVTTklfQ0ZMQUdTKSAtbyAkKC5U
 QVJHRVQpIC1jICQoLklNUFNSQykKKy5lbmRpZgorCiBTUkNTKz0JZGV2aWNl
 X2lmLmggYnVzX2lmLmggb3B0X2J1cy5oIGNyeXB0b2Rldl9pZi5oCiAKIC5p
 bmNsdWRlIDxic2Qua21vZC5taz4KCiNiZW5jaG1hcmsKICAgMy45MTcgc2Vj
 LCAyMDAwMDAwICAgIGFlcyBjcnlwdHMsICAgICAgMTYgYnl0ZXMsICA4MTY5
 Mzk0IGJ5dGUvc2VjLCAgICA2Mi4zIE1iL3NlYwogICAzLjk1NyBzZWMsIDIw
 MDAwMDAgICAgeHRzIGNyeXB0cywgICAgICAxNiBieXRlcywgIDgwODc0MTMg
 Ynl0ZS9zZWMsICAgIDYxLjcgTWIvc2VjCiAgIDMuOTI1IHNlYywgMjAwMDAw
 MCBhZXMxOTIgY3J5cHRzLCAgICAgIDE2IGJ5dGVzLCAgODE1MjU4NiBieXRl
 L3NlYywgICAgNjIuMiBNYi9zZWMKICAgMy45Mjkgc2VjLCAyMDAwMDAwIGFl
 czI1NiBjcnlwdHMsICAgICAgMTYgYnl0ZXMsICA4MTQzNzM3IGJ5dGUvc2Vj
 LCAgICA2Mi4xIE1iL3NlYwogICAzLjk4OCBzZWMsIDIwMDAwMDAgeHRzMjU2
 IGNyeXB0cywgICAgICAxNiBieXRlcywgIDgwMjM2MjQgYnl0ZS9zZWMsICAg
 IDYxLjIgTWIvc2VjCiAgIDUuMzA5IHNlYywgMjAwMDAwMCAgICBhZXMgY3J5
 cHRzLCAgICAgNTEyIGJ5dGVzLCAxOTI4OTE3MTQgYnl0ZS9zZWMsICAxNDcx
 LjYgTWIvc2VjCiAgIDQuODA0IHNlYywgMjAwMDAwMCAgICB4dHMgY3J5cHRz
 LCAgICAgNTEyIGJ5dGVzLCAyMTMxNTM5NzMgYnl0ZS9zZWMsICAxNjI2LjIg
 TWIvc2VjCiAgIDUuNTE1IHNlYywgMjAwMDAwMCBhZXMxOTIgY3J5cHRzLCAg
 ICAgNTEyIGJ5dGVzLCAxODU2NzQxODUgYnl0ZS9zZWMsICAxNDE2LjYgTWIv
 c2VjCiAgIDUuNzM0IHNlYywgMjAwMDAwMCBhZXMyNTYgY3J5cHRzLCAgICAg
 NTEyIGJ5dGVzLCAxNzg1NzA3MTIgYnl0ZS9zZWMsICAxMzYyLjQgTWIvc2Vj
 CiAgIDQuODgxIHNlYywgMjAwMDAwMCB4dHMyNTYgY3J5cHRzLCAgICAgNTEy
 IGJ5dGVzLCAyMDk3ODU1MTEgYnl0ZS9zZWMsICAxNjAwLjUgTWIvc2VjCiAg
 IDEuNTA1IHNlYywgIDIwMDAwMCAgICBhZXMgY3J5cHRzLCAgICA0MDk2IGJ5
 dGVzLCA1NDQzMzAxNDkgYnl0ZS9zZWMsICA0MTUyLjkgTWIvc2VjCiAgIDAu
 OTkwIHNlYywgIDIwMDAwMCAgICB4dHMgY3J5cHRzLCAgICA0MDk2IGJ5dGVz
 LCA4MjczOTc4NTggYnl0ZS9zZWMsICA2MzEyLjUgTWIvc2VjCiAgIDEuNjYy
 IHNlYywgIDIwMDAwMCBhZXMxOTIgY3J5cHRzLCAgICA0MDk2IGJ5dGVzLCA0
 OTI5MDc1MzUgYnl0ZS9zZWMsICAzNzYwLjYgTWIvc2VjCiAgIDEuODE2IHNl
 YywgIDIwMDAwMCBhZXMyNTYgY3J5cHRzLCAgICA0MDk2IGJ5dGVzLCA0NTEw
 NzQyNDcgYnl0ZS9zZWMsICAzNDQxLjQgTWIvc2VjCiAgIDEuMDgxIHNlYywg
 IDIwMDAwMCB4dHMyNTYgY3J5cHRzLCAgICA0MDk2IGJ5dGVzLCA3NTc3ODE3
 ODYgYnl0ZS9zZWMsICA1NzgxLjQgTWIvc2VjCg==
 
 --_----------=_1347043248118301--
 
State-Changed-From-To: open->feedback 
State-Changed-By: jmg 
State-Changed-When: Fri Jan 24 21:47:52 UTC 2014 
State-Changed-Why:  
I recently did some work on pipelining aes-ni and I'm not sure how 
applicable your patch is anymore, can you evaluate and maybe we can 
work together to get even better performance from it? 

Thanks. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=170200 
Responsible-Changed-From-To: freebsd-bugs->jmg 
Responsible-Changed-By: jmg 
Responsible-Changed-When: Fri Jan 24 21:50:59 UTC 2014 
Responsible-Changed-Why:  
forgot to take ownership of this bug.. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=170200 
>Unformatted:
