Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753238AbeAEWCB (ORCPT + 1 other); Fri, 5 Jan 2018 17:02:01 -0500 Received: from smtp-fw-33001.amazon.com ([207.171.190.10]:14756 "EHLO smtp-fw-33001.amazon.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753080AbeAEWB7 (ORCPT ); Fri, 5 Jan 2018 17:01:59 -0500 X-Amazon-filename: smime.p7s X-IronPort-AV: E=Sophos;i="5.46,320,1511827200"; d="p7s'?scan'208";a="713739949" Message-ID: <1515189618.29312.197.camel@amazon.co.uk> Subject: Re: [PATCH v3 01/13] x86/retpoline: Add initial retpoline support To: Linus Torvalds CC: "bp@suse.de" , "linux-kernel@vger.kernel.org" , "peterz@infradead.org" , "tim.c.chen@linux.intel.com" , "tglx@linutronix.de" , "ak@linux.intel.com" , "riel@redhat.com" , "keescook@google.com" , "gnomes@lxorguk.ukuu.org.uk" , "pjt@google.com" , "dave.hansen@intel.com" , "luto@amacapital.net" , "jikos@kernel.org" , "gregkh@linux-foundation.org" In-Reply-To: References: <1515058213.12987.89.camel@amazon.co.uk> <20180104143710.8961-1-dwmw@amazon.co.uk> <1515160619.29312.126.camel@amazon.co.uk> <1515170506.29312.149.camel@amazon.co.uk> <20180105164505.xpw5pefxsyu3z56e@pd.tnic> <1515172353.29312.161.camel@amazon.co.uk> Face: iVBORw0KGgoAAAANSUhEUgAAADAAAAAwBAMAAAClLOS0AAAAG1BMVEUHBwcUFBQpKSlGRkZhYWF9fX2Xl5eysrLMzMxFF+rXAAACaElEQVQ4y21UQXbbIBQE9wJALmAg6ToWON22FrhZthHgbvssUPathC7QWMful2JHSmtWwGg+zPxBCE0DU4QoJQgRgsg4w2gJjBNE8PjFBZgnQMBs+uZ1NQNQjZO3BV4AGDFC0f+l4DBG0VUAM4yv7SO8IgRdHXQ+A78HKL5OAeCfNQV5cHX8DsBUyIJKtYbt98BKaGNCKjfgFVkqYVLbkHKsRsbSCSa0T6npIqLrpRBgQKHUpQmgs9eEKaiUcooE8WWfCGVnBiUcn1uF2XhbfmN9apKnmMP2K4kizKkQWxuaVNOpU2cACIyxO1Po8ETHcXEDMVnozcejkAYA9iaD4pU0ZvNQ8VurNnTuFAYVtuIPUZW25PjDIjQAlGyffIiRQxoWAZBmJ0LTdW2Nyc0iP3DqRhxizvGJkBWZmyFVyZkddWzmBoIBVMpCCJ1CFzl98xav4VJKSSD45KbUT75ixikTphDSRh8+Uz7JLgUTAgAFwzqzjxc/nDY7WUApqY0OMdTwCKZSXplSKkgIRCHElCp8ZnhnKqXuwcNbk1L0VXE+I9alUXoHlLHl3mv7/dWQlJwtjREC7mu9L/U2jQyMUuO2EDS4q9Kl2ddm232bxIE5pjJuVwiljNn/Cfv25/T0cu5cZbwHGVq7h/zp0B4n3S99V/utD+Uo8BiGx9xCsOAV5z7/tjo4Z4z1Lvb90KZ7eFOoOeXOukqF2seo234YYuaQPpRP+cVZU5adT1Edun5Iz3z8fTz3+eSDh0Ip1c7zx1MaijGzTd/3MbRuBHz8cvcVgCMBRpOHvgu59WDhoat+nIZm+LWm9C/aaaGq5DCP9QAAAABJRU5ErkJggg== Organization: Amazon Content-Type: multipart/signed; micalg=sha-256; protocol="application/x-pkcs7-signature"; boundary="=-4bUkoCld5FB/0tU12vK1" Date: Fri, 5 Jan 2018 22:00:18 +0000 X-Mailer: Evolution 3.18.5.2-0ubuntu3.2 MIME-Version: 1.0 From: "Woodhouse, David" X-Evolution-Source: 1481217574.17989.4@uc8d3ff76b9bc5848a9cc Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Return-Path: --=-4bUkoCld5FB/0tU12vK1 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Fri, 2018-01-05 at 09:28 -0800, Linus Torvalds wrote: > That said, I honestly like the inline version (the one that is in the > google paper first) of the retpoline more than the out-of-line one. > And that one shouldn't have any relocagtion issues, because all the > offsets are relative. >=20 > We want to use that one for the entry stub anyway, can't we just > standardize on that one for all our assembly? >=20 > If the *compiler* uses the out-of-line version, that's a separate > thing. But for our asm cases, let's just make it all be the inline > case, ok? OK, this one looks saner, and I think I've tested all the 32/64 bit retpoline/amd/none permutations. Pushed to http://git.infradead.org/users/dwmw2/linux-retpoline.git/ If this matches what you were thinking, I'll refactor the series in the morning to do it this way. =46rom cfddb3bcae1524da52e782398da2809ec8faa200 Mon Sep 17 00:00:00 2001 From: David Woodhouse Date: Fri, 5 Jan 2018 21:50:41 +0000 Subject: [PATCH] x86/retpoline: Clean up inverted X86_FEATURE_NO_RETPOLINE =C2=A0logic If we make the thunks inline so they don't need relocations to branch to __x86.indirect_thunk.xxx then we don't fall foul of the alternatives handling, and we can have the retpoline variant in 'altinstr'. This means that we can use X86_FEATURE_RETPOLINE which is more natural. Unfortunately, it does mean that the X86_FEATURE_K8 trick doesn't work any more, so we need an additional X86_FEATURE_RETPOLINE_AMD for that. Signed-off-by: David Woodhouse --- =C2=A0arch/x86/entry/entry_64.S=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0=C2=A0=C2=A0| 12 +-------- =C2=A0arch/x86/include/asm/cpufeatures.h=C2=A0=C2=A0=C2=A0|=C2=A0=C2=A03 ++= - =C2=A0arch/x86/include/asm/nospec-branch.h | 50 +++++++++++++++++++++++++++= --------- =C2=A0arch/x86/kernel/cpu/common.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0|=C2=A0=C2=A05 ++++ =C2=A0arch/x86/kernel/cpu/intel.c=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0= =C2=A0=C2=A0=C2=A0|=C2=A0=C2=A03 ++- =C2=A0arch/x86/lib/retpoline.S=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2= =A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0| 17 +++++------- =C2=A06 files changed, 54 insertions(+), 36 deletions(-) diff --git a/arch/x86/entry/entry_64.S b/arch/x86/entry/entry_64.S index 76f94bbacaec..8f7e1129f493 100644 --- a/arch/x86/entry/entry_64.S +++ b/arch/x86/entry/entry_64.S @@ -188,17 +188,7 @@ ENTRY(entry_SYSCALL_64_trampoline) =C2=A0 =C2=A0*/ =C2=A0 pushq %rdi =C2=A0 movq $entry_SYSCALL_64_stage2, %rdi - /* - =C2=A0* Open-code the retpoline from retpoline.S, because we can't - =C2=A0* just jump to it directly. - =C2=A0*/ - ALTERNATIVE "call 2f", "jmp *%rdi", X86_FEATURE_NO_RETPOLINE -1: - lfence - jmp 1b -2: - mov %rdi, (%rsp) - ret + NOSPEC_JMP rdi =C2=A0END(entry_SYSCALL_64_trampoline) =C2=A0 =C2=A0 .popsection diff --git a/arch/x86/include/asm/cpufeatures.h b/arch/x86/include/asm/cpuf= eatures.h index 2d916fd13bf9..6f10edabbf82 100644 --- a/arch/x86/include/asm/cpufeatures.h +++ b/arch/x86/include/asm/cpufeatures.h @@ -203,7 +203,8 @@ =C2=A0#define X86_FEATURE_PROC_FEEDBACK ( 7*32+ 9) /* AMD ProcFeedbackInter= face */ =C2=A0#define X86_FEATURE_SME ( 7*32+10) /* AMD Secure Memory Encryption = */ =C2=A0#define X86_FEATURE_PTI ( 7*32+11) /* Kernel Page Table Isolation e= nabled */ -#define X86_FEATURE_NO_RETPOLINE ( 7*32+12) /* Retpoline mitigation for Sp= ectre variant 2 */ +#define X86_FEATURE_RETPOLINE ( 7*32+12) /* Intel Retpoline mitigation fo= r Spectre variant 2 */ +#define X86_FEATURE_RETPOLINE_AMD ( 7*32+13) /* AMD Retpoline mitigation f= or Spectre variant 2 */ =C2=A0#define X86_FEATURE_INTEL_PPIN ( 7*32+14) /* Intel Processor Invento= ry Number */ =C2=A0#define X86_FEATURE_INTEL_PT ( 7*32+15) /* Intel Processor Trace */ =C2=A0#define X86_FEATURE_AVX512_4VNNIW ( 7*32+16) /* AVX-512 Neural Networ= k Instructions */ diff --git a/arch/x86/include/asm/nospec-branch.h b/arch/x86/include/asm/no= spec-branch.h index eced0dfaddc9..6e92edf64e53 100644 --- a/arch/x86/include/asm/nospec-branch.h +++ b/arch/x86/include/asm/nospec-branch.h @@ -8,23 +8,44 @@ =C2=A0#include =C2=A0 =C2=A0#ifdef __ASSEMBLY__ + =C2=A0/* - * The asm code uses CONFIG_RETPOLINE; this part will happen even if - * the toolchain isn't retpoline-capable. + * These are the bare retpoline primitives for indirect jmp and call. + * Do not use these directly. =C2=A0 */ +.macro RETPOLINE_JMP reg:req + call 1112f +1111: lfence + jmp 1111b +1112: mov %\reg, (%_ASM_SP) + ret +.endm + +.macro RETPOLINE_CALL reg:req + jmp 1113f +1110: RETPOLINE_JMP \reg +1113: call 1110b +.endm + + + =C2=A0.macro NOSPEC_JMP reg:req =C2=A0#ifdef CONFIG_RETPOLINE - ALTERNATIVE __stringify(jmp __x86.indirect_thunk.\reg), __stringify(jmp *= %\reg), X86_FEATURE_NO_RETPOLINE + ALTERNATIVE_2 __stringify(jmp *%\reg), \ + __stringify(RETPOLINE_JMP \reg), X86_FEATURE_RETPOLINE, \ + __stringify(lfence; jmp *%\reg), X86_FEATURE_RETPOLINE_AMD =C2=A0#else - jmp *%\reg + jmp *%\reg =C2=A0#endif =C2=A0.endm =C2=A0 =C2=A0.macro NOSPEC_CALL reg:req =C2=A0#ifdef CONFIG_RETPOLINE - ALTERNATIVE __stringify(call __x86.indirect_thunk.\reg), __stringify(call= *%\reg), X86_FEATURE_NO_RETPOLINE + ALTERNATIVE_2 __stringify(call *%\reg), \ + __stringify(RETPOLINE_CALL \reg), X86_FEATURE_RETPOLINE,\ + __stringify(lfence; call *%\reg), X86_FEATURE_RETPOLINE_AMD =C2=A0#else - call *%\reg + call *%\reg =C2=A0#endif =C2=A0.endm =C2=A0 @@ -36,16 +57,21 @@ =C2=A0 */ =C2=A0#if defined(CONFIG_X86_64) && defined(RETPOLINE) =C2=A0#=C2=A0=C2=A0define NOSPEC_CALL ALTERNATIVE( \ + "call *%[thunk_target]\n", \ =C2=A0 "call __x86.indirect_thunk.%V[thunk_target]\n", \ - "call *%[thunk_target]\n", X86_FEATURE_NO_RETPOLINE) + X86_FEATURE_RETPOLINE) =C2=A0#=C2=A0=C2=A0define THUNK_TARGET(addr) [thunk_target] "r" (addr) =C2=A0#elif defined(CONFIG_X86_64) && defined(CONFIG_RETPOLINE) =C2=A0# define NOSPEC_CALL ALTERNATIVE( \ - "=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0jmp 1221f; " \ - "1222:=C2=A0=C2=A0push %[thunk_target];" \ - "=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0jmp __x86.indirect_thunk;" \ - "1221:=C2=A0=C2=A0call 1222b;\n", \ - "call *%[thunk_target]\n", X86_FEATURE_NO_RETPOLINE) + "call *%[thunk_target]\n", \ + "=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0jmp=C2=A0=C2=A0=C2=A0=C2=A0111= 3f; " \ + "1110:=C2=A0=C2=A0call=C2=A0=C2=A0=C2=A01112f; " \ + "1111: lfence; " \ + "=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0jmp=C2=A0=C2=A0=C2=A0=C2=A0111= 1b; " \ + "1112: movl=C2=A0=C2=A0=C2=A0%[thunk_target], (%esp); " \ + "=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0=C2=A0ret; " \ + "1113:=C2=A0=C2=A0call=C2=A0=C2=A0=C2=A01110b;\n", \ + X86_FEATURE_RETPOLINE) =C2=A0# define THUNK_TARGET(addr) [thunk_target] "rm" (addr) =C2=A0#else =C2=A0# define NOSPEC_CALL "call *%[thunk_target]\n" diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c index 372ba3fb400f..40e6e54d8501 100644 --- a/arch/x86/kernel/cpu/common.c +++ b/arch/x86/kernel/cpu/common.c @@ -904,6 +904,11 @@ static void __init early_identify_cpu(struct cpuinfo_x= 86 *c) =C2=A0 =C2=A0 setup_force_cpu_bug(X86_BUG_SPECTRE_V1); =C2=A0 setup_force_cpu_bug(X86_BUG_SPECTRE_V2); +#ifdef CONFIG_RETPOLINE + setup_force_cpu_cap(X86_FEATURE_RETPOLINE); + if (c->x86_vendor =3D=3D X86_VENDOR_AMD) + setup_force_cpu_cap(X86_FEATURE_RETPOLINE_AMD); +#endif =C2=A0 =C2=A0 fpu__init_system(c); =C2=A0 diff --git a/arch/x86/kernel/cpu/intel.c b/arch/x86/kernel/cpu/intel.c index e1812d07b53e..35e123e5f413 100644 --- a/arch/x86/kernel/cpu/intel.c +++ b/arch/x86/kernel/cpu/intel.c @@ -35,7 +35,8 @@ =C2=A0static int __init noretpoline_setup(char *__unused) =C2=A0{ =C2=A0 pr_info("Retpoline runtime disabled\n"); - setup_force_cpu_cap(X86_FEATURE_NO_RETPOLINE); + setup_clear_cpu_cap(X86_FEATURE_RETPOLINE); + setup_clear_cpu_cap(X86_FEATURE_RETPOLINE_AMD); =C2=A0 return 1; =C2=A0} =C2=A0__setup("noretpoline", noretpoline_setup); diff --git a/arch/x86/lib/retpoline.S b/arch/x86/lib/retpoline.S index 2a4b1f09eb84..90d9a1589a54 100644 --- a/arch/x86/lib/retpoline.S +++ b/arch/x86/lib/retpoline.S @@ -6,19 +6,14 @@ =C2=A0#include =C2=A0#include =C2=A0#include +#include =C2=A0 -.macro THUNK sp reg +.macro THUNK reg =C2=A0 .section .text.__x86.indirect_thunk.\reg =C2=A0 =C2=A0ENTRY(__x86.indirect_thunk.\reg) =C2=A0 CFI_STARTPROC - ALTERNATIVE_2 "call 2f", __stringify(lfence;jmp *%\reg), X86_FEATURE_K8, = __stringify(jmp *%\reg), X86_FEATURE_NO_RETPOLINE -1: - lfence - jmp 1b -2: - mov %\reg, (%\sp) - ret + NOSPEC_JMP \reg =C2=A0 CFI_ENDPROC =C2=A0ENDPROC(__x86.indirect_thunk.\reg) =C2=A0EXPORT_SYMBOL(__x86.indirect_thunk.\reg) @@ -26,11 +21,11 @@ EXPORT_SYMBOL(__x86.indirect_thunk.\reg) =C2=A0 =C2=A0#ifdef CONFIG_64BIT =C2=A0.irp reg rax rbx rcx rdx rsi rdi rbp r8 r9 r10 r11 r12 r13 r14 r15 - THUNK rsp \reg + THUNK \reg =C2=A0.endr =C2=A0#else =C2=A0.irp reg eax ebx ecx edx esi edi ebp - THUNK esp \reg + THUNK \reg =C2=A0.endr =C2=A0 =C2=A0/* @@ -39,7 +34,7 @@ EXPORT_SYMBOL(__x86.indirect_thunk.\reg) =C2=A0 */ =C2=A0ENTRY(__x86.indirect_thunk) =C2=A0 CFI_STARTPROC - ALTERNATIVE "call 2f", "ret", X86_FEATURE_NO_RETPOLINE + ALTERNATIVE "ret", "call 2f", X86_FEATURE_RETPOLINE =C2=A01: =C2=A0 lfence =C2=A0 jmp 1b --=C2=A0 2.14.3 --=-4bUkoCld5FB/0tU12vK1 Content-Type: application/x-pkcs7-signature; name="smime.p7s" Content-Disposition: attachment; filename="smime.p7s" Content-Transfer-Encoding: base64 MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCCEE4w ggUuMIIEFqADAgECAhEApEtL31g6H7ROXdOiQnA9RjANBgkqhkiG9w0BAQsFADCBlzELMAkGA1UE BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgG A1UEChMRQ09NT0RPIENBIExpbWl0ZWQxPTA7BgNVBAMTNENPTU9ETyBSU0EgQ2xpZW50IEF1dGhl bnRpY2F0aW9uIGFuZCBTZWN1cmUgRW1haWwgQ0EwHhcNMTcxMjIxMDAwMDAwWhcNMTgxMjIxMjM1 OTU5WjAiMSAwHgYJKoZIhvcNAQkBFhFkd213QGFtYXpvbi5jby51azCCASIwDQYJKoZIhvcNAQEB BQADggEPADCCAQoCggEBAKdGKgXuwKMg2r+i/4BZZC0ddRxNq3xIKTakie/VCSzoO7P17A36ZzUc VMEYPfqDt/65xoc6Tdih+qkY2pNDppZ1DZ8mVrAX6O2O60ZhmXB60wMoDvXPZInvkMOW4drqnje/ 7/NOypn/XQAY+ln4KT+3tHG3TfryyJFMedqC/r29KJlCeeCxIzdtq2j5mN42tvPVv4+p+Kr77uui GOASNdFJbNdgx7UGF+il6kRGSle17LJZKMgRiLJXYjECwnGwdfLdN5SINWD5IC3yXY8d14Bq6DyD jNts1DFw+SKhW8kVFYRZpv7TE3/42QJKQVL6YWka5T4EJO7AD3gy2ypRsd8CAwEAAaOCAecwggHj MB8GA1UdIwQYMBaAFIKvbIz4xf6WYXzoHz0rcUhexIvAMB0GA1UdDgQWBBT/vhvBExl2wDr8f50u b+0yzFyZRjAOBgNVHQ8BAf8EBAMCBaAwDAYDVR0TAQH/BAIwADAgBgNVHSUEGTAXBggrBgEFBQcD BAYLKwYBBAGyMQEDBQIwEQYJYIZIAYb4QgEBBAQDAgUgMEYGA1UdIAQ/MD0wOwYMKwYBBAGyMQEC AQEBMCswKQYIKwYBBQUHAgEWHWh0dHBzOi8vc2VjdXJlLmNvbW9kby5uZXQvQ1BTMFoGA1UdHwRT MFEwT6BNoEuGSWh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0NPTU9ET1JTQUNsaWVudEF1dGhlbnRp Y2F0aW9uYW5kU2VjdXJlRW1haWxDQS5jcmwwgYsGCCsGAQUFBwEBBH8wfTBVBggrBgEFBQcwAoZJ aHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPUlNBQ2xpZW50QXV0aGVudGljYXRpb25hbmRT ZWN1cmVFbWFpbENBLmNydDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuY29tb2RvY2EuY29tMBwG A1UdEQQVMBOBEWR3bXdAYW1hem9uLmNvLnVrMA0GCSqGSIb3DQEBCwUAA4IBAQCK2HofespbCaDu udwwfh8GxDpVUnVbZZVWScpZMxfYpXzLot7L6iZrr16oMQ+UOiDDAK6/D3+u2QN8u0lJ6yLKVmvh lGOzDywGsyG2Ohy8Dt5jcEK5sz84OsPtrRH7ahZHLxYPhWlUKOjOPN6sb9h6uMYlXmG/KmAr2rwF exN6Zrwh6YwF7ukuMs175YcNyYRdB8kVYq3WikfbTHOoRbJiu9Unw7LqnvPTfx+xUvD6aN2CKLtr mactWbk98swNgbI18UWjfEpugvAqw09CDLjeq7N1v0SkUkQEDqGSUE+hKFryTNXtZ6zOfl+MQfD8 U7T5oJa34DmWXK9+x7dl+MrqMIIFLjCCBBagAwIBAgIRAKRLS99YOh+0Tl3TokJwPUYwDQYJKoZI hvcNAQELBQAwgZcxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVyIE1hbmNoZXN0ZXIxEDAO BgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVkMT0wOwYDVQQDEzRDT01P RE8gUlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBMB4XDTE3MTIy MTAwMDAwMFoXDTE4MTIyMTIzNTk1OVowIjEgMB4GCSqGSIb3DQEJARYRZHdtd0BhbWF6b24uY28u dWswggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCnRioF7sCjINq/ov+AWWQtHXUcTat8 SCk2pInv1Qks6Duz9ewN+mc1HFTBGD36g7f+ucaHOk3YofqpGNqTQ6aWdQ2fJlawF+jtjutGYZlw etMDKA71z2SJ75DDluHa6p43v+/zTsqZ/10AGPpZ+Ck/t7Rxt0368siRTHnagv69vSiZQnngsSM3 bato+ZjeNrbz1b+Pqfiq++7rohjgEjXRSWzXYMe1BhfopepERkpXteyyWSjIEYiyV2IxAsJxsHXy 3TeUiDVg+SAt8l2PHdeAaug8g4zbbNQxcPkioVvJFRWEWab+0xN/+NkCSkFS+mFpGuU+BCTuwA94 MtsqUbHfAgMBAAGjggHnMIIB4zAfBgNVHSMEGDAWgBSCr2yM+MX+lmF86B89K3FIXsSLwDAdBgNV HQ4EFgQU/74bwRMZdsA6/H+dLm/tMsxcmUYwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAw IAYDVR0lBBkwFwYIKwYBBQUHAwQGCysGAQQBsjEBAwUCMBEGCWCGSAGG+EIBAQQEAwIFIDBGBgNV HSAEPzA9MDsGDCsGAQQBsjEBAgEBATArMCkGCCsGAQUFBwIBFh1odHRwczovL3NlY3VyZS5jb21v ZG8ubmV0L0NQUzBaBgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLmNvbW9kb2NhLmNvbS9DT01P RE9SU0FDbGllbnRBdXRoZW50aWNhdGlvbmFuZFNlY3VyZUVtYWlsQ0EuY3JsMIGLBggrBgEFBQcB AQR/MH0wVQYIKwYBBQUHMAKGSWh0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUNsaWVu dEF1dGhlbnRpY2F0aW9uYW5kU2VjdXJlRW1haWxDQS5jcnQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v Y3NwLmNvbW9kb2NhLmNvbTAcBgNVHREEFTATgRFkd213QGFtYXpvbi5jby51azANBgkqhkiG9w0B AQsFAAOCAQEAith6H3rKWwmg7rncMH4fBsQ6VVJ1W2WVVknKWTMX2KV8y6Ley+oma69eqDEPlDog wwCuvw9/rtkDfLtJSesiylZr4ZRjsw8sBrMhtjocvA7eY3BCubM/ODrD7a0R+2oWRy8WD4VpVCjo zjzerG/YerjGJV5hvypgK9q8BXsTema8IemMBe7pLjLNe+WHDcmEXQfJFWKt1opH20xzqEWyYrvV J8Oy6p7z038fsVLw+mjdgii7a5mnLVm5PfLMDYGyNfFFo3xKboLwKsNPQgy43quzdb9EpFJEBA6h klBPoSha8kzV7Weszn5fjEHw/FO0+aCWt+A5llyvfse3ZfjK6jCCBeYwggPOoAMCAQICEGqb4Tg7 /ytrnwHV2binUlYwDQYJKoZIhvcNAQEMBQAwgYUxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVh dGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1p dGVkMSswKQYDVQQDEyJDT01PRE8gUlNBIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTEzMDEx MDAwMDAwMFoXDTI4MDEwOTIzNTk1OVowgZcxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVhdGVy IE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1pdGVk MT0wOwYDVQQDEzRDT01PRE8gUlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVt YWlsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvrOeV6wodnVAFsc4A5jTxhh2 IVDzJXkLTLWg0X06WD6cpzEup/Y0dtmEatrQPTRI5Or1u6zf+bGBSyD9aH95dDSmeny1nxdlYCeX IoymMv6pQHJGNcIDpFDIMypVpVSRsivlJTRENf+RKwrB6vcfWlP8dSsE3Rfywq09N0ZfxcBa39V0 wsGtkGWC+eQKiz4pBZYKjrc5NOpG9qrxpZxyb4o4yNNwTqzaaPpGRqXB7IMjtf7tTmU2jqPMLxFN e1VXj9XB1rHvbRikw8lBoNoSWY66nJN/VCJv5ym6Q0mdCbDKCMPybTjoNCQuelc0IAaO4nLUXk0B OSxSxt8kCvsUtQIDAQABo4IBPDCCATgwHwYDVR0jBBgwFoAUu69+Aj36pvE8hI6t7jiY7NkyMtQw HQYDVR0OBBYEFIKvbIz4xf6WYXzoHz0rcUhexIvAMA4GA1UdDwEB/wQEAwIBhjASBgNVHRMBAf8E CDAGAQH/AgEAMBEGA1UdIAQKMAgwBgYEVR0gADBMBgNVHR8ERTBDMEGgP6A9hjtodHRwOi8vY3Js LmNvbW9kb2NhLmNvbS9DT01PRE9SU0FDZXJ0aWZpY2F0aW9uQXV0aG9yaXR5LmNybDBxBggrBgEF BQcBAQRlMGMwOwYIKwYBBQUHMAKGL2h0dHA6Ly9jcnQuY29tb2RvY2EuY29tL0NPTU9ET1JTQUFk ZFRydXN0Q0EuY3J0MCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5jb21vZG9jYS5jb20wDQYJKoZI hvcNAQEMBQADggIBAHhcsoEoNE887l9Wzp+XVuyPomsX9vP2SQgG1NgvNc3fQP7TcePo7EIMERoh 42awGGsma65u/ITse2hKZHzT0CBxhuhb6txM1n/y78e/4ZOs0j8CGpfb+SJA3GaBQ+394k+z3ZBy WPQedXLL1OdK8aRINTsjk/H5Ns77zwbjOKkDamxlpZ4TKSDMKVmU/PUWNMKSTvtlenlxBhh7ETrN 543j/Q6qqgCWgWuMAXijnRglp9fyadqGOncjZjaaSOGTTFB+E2pvOUtY+hPebuPtTbq7vODqzCM6 ryEhNhzf+enm0zlpXK7q332nXttNtjv7VFNYG+I31gnMrwfHM5tdhYF/8v5UY5g2xANPECTQdu9v WPoqNSGDt87b3gXb1AiGGaI06vzgkejL580ul+9hz9D0S0U4jkhJiA7EuTecP/CFtR72uYRBcunw wH3fciPjviDDAI9SnC/2aPY8ydehzuZutLbZdRJ5PDEJM/1tyZR2niOYihZ+FCbtf3D9mB12D4ln 9icgc7CwaxpNSCPt8i/GqK2HsOgkL3VYnwtx7cJUmpvVdZ4ognzgXtgtdk3ShrtOS1iAN2ZBXFiR mjVzmehoMof06r1xub+85hFQzVxZx5/bRaTKTlL8YXLI8nAbR9HWdFqzcOoB/hxfEyIQpx9/s81r gzdEZOofSlZHynoSMYIDyjCCA8YCAQEwga0wgZcxCzAJBgNVBAYTAkdCMRswGQYDVQQIExJHcmVh dGVyIE1hbmNoZXN0ZXIxEDAOBgNVBAcTB1NhbGZvcmQxGjAYBgNVBAoTEUNPTU9ETyBDQSBMaW1p dGVkMT0wOwYDVQQDEzRDT01PRE8gUlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJl IEVtYWlsIENBAhEApEtL31g6H7ROXdOiQnA9RjANBglghkgBZQMEAgEFAKCCAe0wGAYJKoZIhvcN AQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTgwMTA1MjIwMDE4WjAvBgkqhkiG9w0B CQQxIgQgiNJ98d1yVkqyPO20QIczeuPYwk54FwOXV2EeprwKnZgwgb4GCSsGAQQBgjcQBDGBsDCB rTCBlzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMH U2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0ZWQxPTA7BgNVBAMTNENPTU9ETyBSU0Eg Q2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBTZWN1cmUgRW1haWwgQ0ECEQCkS0vfWDoftE5d06JC cD1GMIHABgsqhkiG9w0BCRACCzGBsKCBrTCBlzELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdyZWF0 ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09NT0RPIENBIExpbWl0 ZWQxPTA7BgNVBAMTNENPTU9ETyBSU0EgQ2xpZW50IEF1dGhlbnRpY2F0aW9uIGFuZCBTZWN1cmUg RW1haWwgQ0ECEQCkS0vfWDoftE5d06JCcD1GMA0GCSqGSIb3DQEBAQUABIIBAD4WZ03ul7k/RpFy AjBNTLlAE+vWpf7BRIpERVinJoybCC9WZW4PGbtUmix7zW9sqiLInN6V/EnTWfCTxsKTAcggbKHk j+bzwqI3xoKb50liRiF/+CDkdTeOS5Wvx4Oe4xzItTlCtGwF15m1InGe3oGFQ2RbXXCn0OySTinF l6yPOkWj064DtPaVSUrtJG3cmnXj4Y6Shg1txXNDeYPwadsPaBLYMF/6WNmiBhSL2O4fTz6imZvY 41ZxDoTYxkAjjSsiiT+L8TwXlmXZF7aqNauNGmhTaepWVZunZhSJ3txU9HDVfWCJlD2DXEq+XPwm db1TLobSL4evAYGJ8wri3hUAAAAAAAA= --=-4bUkoCld5FB/0tU12vK1--