From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id D01F0C3DA4A for ; Fri, 2 Aug 2024 16:06:39 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 666B86B0093; Fri, 2 Aug 2024 12:06:39 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 5F07F6B0096; Fri, 2 Aug 2024 12:06:39 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 469DD6B0098; Fri, 2 Aug 2024 12:06:39 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id 1E9586B0093 for ; Fri, 2 Aug 2024 12:06:39 -0400 (EDT) Received: from smtpin23.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id D173CC144E for ; Fri, 2 Aug 2024 16:06:38 +0000 (UTC) X-FDA: 82407783276.23.8B71EF6 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) by imf30.hostedemail.com (Postfix) with ESMTP id 64A308002F for ; Fri, 2 Aug 2024 16:06:35 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=dvZlp5k+; dmarc=none; spf=none (imf30.hostedemail.com: domain of BATV+a50a786cdf4715cf5701+7649+infradead.org+dwmw2@casper.srs.infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=BATV+a50a786cdf4715cf5701+7649+infradead.org+dwmw2@casper.srs.infradead.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1722614753; a=rsa-sha256; cv=none; b=wOUrPIEaBNGkkAMgebdvKVKRHLV6m5nKfMFdfc+ifVJTCo4w2rzOmUf58Tgjr0et6FWiR5 OlcA49TEz61rWNfLThrMAYVzhxec8R7DSUyNXo4wd8ew/IhqyUgBCp0nSkisUj13589hVt Qk2GnVADwK73MDZ0GbzyGWGqb999P/0= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=infradead.org header.s=casper.20170209 header.b=dvZlp5k+; dmarc=none; spf=none (imf30.hostedemail.com: domain of BATV+a50a786cdf4715cf5701+7649+infradead.org+dwmw2@casper.srs.infradead.org has no SPF policy when checking 90.155.50.34) smtp.mailfrom=BATV+a50a786cdf4715cf5701+7649+infradead.org+dwmw2@casper.srs.infradead.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1722614753; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=d1QQs2j9WvbjY7EOtsH3M71tofcwwHBlzkWo07sbTYw=; b=qiWFftpyxHBVAtko25yKJuIPXCsxQFrU92ejJBbhxQZQzJFMZ+/QmA4eJPBbHmaNdc44ei HiINtHduO9EXDuasUsiMTJjk/eAu8uToEwIneCa3wPAss7uYVcuDkBQoyi4pQ+TWqiO5jQ Q3hqvsCZ9Iw01wrFAo4ZHPR/aPOg5dg= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=casper.20170209; h=MIME-Version:Content-Type:References: In-Reply-To:Date:Cc:To:From:Subject:Message-ID:Sender:Reply-To: Content-Transfer-Encoding:Content-ID:Content-Description; bh=d1QQs2j9WvbjY7EOtsH3M71tofcwwHBlzkWo07sbTYw=; b=dvZlp5k+Bcyptd8d2RCa5E5prx c3brn5tA8EXUati41/ueUoJaR6eQHXpJ7jHy73F/S3xXCK9nV6f1GD0xFrTsx9gYmCMHXQbIRE8xw 4iN574s9xyGbzwtGGAn6RR83llDhA7LAb3vKNkiUzL5Tubs9zu+VJroDcRftDRJzvcxvo4tdxwgpC Oyu3OTdlbjpseoJeaW+ohbhqVMDJUDMTCBaRQSbWhLC/5rposBlvE9YxYAjEAHmbdNPDnB4oQqzyB YcTTNtfeQT5A/6BMWPQeW5WsoK07nZ9/305YyDanabrydpGv9yecsrSWHtl7ZnpWOZO5kls6Sc78R qd6bfp7Q==; Received: from [2001:8b0:10b:5:baa5:735b:df3b:ad66] (helo=u3832b3a9db3152.ant.amazon.com) by casper.infradead.org with esmtpsa (Exim 4.97.1 #2 (Red Hat Linux)) id 1sZunK-00000001BqP-21k4; Fri, 02 Aug 2024 16:06:18 +0000 Message-ID: <59f698cf899db7eecb9838069401161a06dad7b4.camel@infradead.org> Subject: Re: [PATCH] KVM: x86: Use gfn_to_pfn_cache for steal_time From: David Woodhouse To: Carsten Stollmaier , Sean Christopherson , Paolo Bonzini , Thomas Gleixner , Ingo Molnar , Borislav Petkov , Dave Hansen , x86@kernel.org, "H. Peter Anvin" Cc: nh-open-source@amazon.com, Peter Xu , Sebastian Biemueller , kvm@vger.kernel.org, linux-kernel@vger.kernel.org, Matthew Wilcox , Andrew Morton , "linux-mm@kvack.org" Date: Fri, 02 Aug 2024 17:06:17 +0100 In-Reply-To: References: <20240802114402.96669-1-stollmc@amazon.com> Content-Type: multipart/signed; micalg="sha-256"; protocol="application/pkcs7-signature"; boundary="=-YMQ3GU6gXOn3saq1BB65" User-Agent: Evolution 3.44.4-0ubuntu2 MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html X-Rspamd-Queue-Id: 64A308002F X-Rspam-User: X-Rspamd-Server: rspam05 X-Stat-Signature: auisqaxdmh18ws9w96oiu79k6ob3ntnq X-HE-Tag: 1722614795-266365 X-HE-Meta: U2FsdGVkX191A2UXRN245LJTVWRi8ybvkHZVua5G0Qa1CBF+RdaM9XKGDQCkHi8z6IAbpkz2F0UwXaO0d0rFTMRgdOGUCs9LSh5XPs8FxQ8F+xY3GhrWGdcC60DfmqLPLGtENpcFHy/0UUCFgyE+8jRGSufnXxTrsKoW3QkgRy5Dq2PwTcIgFGZqr8i0ZDoIXcE4IcPRk8M97MZRkqyjZlpI9SBow+jFhbQmeC08efeW/oqgvMGwBcvoLBy8k05m5lENE9eE9aW5xxsyY8VebmEmJ67EGS9E/mQppK7JjGy6IpFuyoMx6egGsBNYOMXg1a0q1KOXdh2FldAV8demMWlvUPOFOaIB9pDv+0K/lfBANhB3LjcFGTx4kxxkC6XH+A675PyauIbfDCT6gQhanU8uAibbhKVb0Z8TsaHk6Etzfql82fFyNx9uPe1vkBVyrWX0v8LjtKOpJxJ+BbxdHEoAqLDFxjnTPOa5p+M9Ui3X2tVcRWGQIzBAFpKqiaEkq9+PiliSPKgVmFWRSuLp0ggz0X842DbI2lum/oj5H85U1rH97E60UQ+LzgGUgQVRxtOVOTWMmYpHAK/Ln81e0/25iv+3f7S2H6q+F/+op2RwQ3YsxpUHaSK66/rDKKauL7e7x8J6w/c7OGXpfR9M7lin+EsImJHbQKJZwsOt5j07rwaw9i1xXm4ND7MP90K1JsYgG1b41u4uiXPgArTFVKhFMEXGxVFLXAZpN64//yp8g5A9KzwRuUhVZAE87EHLNCt+UWqP4fmAdPY0EKGxDQeWIKlsn9dAnR2sIQpN89Y0TG0p1XcNxlQDJBHRiRL/oOoXslUsPqZAY0FBucIV+DjEq4W43hAV9nay275CO0myl0jfglsmgSGvsmsFZi/89wiCqUTi2jq0x8jww9u7orVPenPUrTvzXoNSteXoKwtNJFI2yVvhdpHcnn6bS7uI64ZwsxRu24yUn6Yjekp zh6FMml8 /HOIJEMP13YDB++/PZ44XF+N2QBhn5bKYIVuvamKjgbOVY71OfguRVS6Ps94aABzYnfI5UI/y0H3uJCPVUyEqwqVKlALY+D0A9+asqW9SV7kq90PNg0i7UY/+Tz7Bi0aBD6TPxFyRar1E+u2sPv9bQQO3CIaq1pkgODib/8wBCLmADHk8BvTCn2dmBlDNx0T1ravoDM02Js20ZlHJzK5AsP4/eGe32FSnrMmdTAxDOOs3ZjC8wzJRYRtN/cTUXLF2QtCSOaa0iXt2Llzn39S2H+q6VxkM6SHHwTgYHT63gDcLp3Mb3zSSgyrdRHbFNEWBciyo2vVsZBhped2NOHhfJfzeZajUAUPFr34rhCm+Ojm0fb9LaXmxs83jo214p6lRA4evEegs9fS/+cYD+6YtwulxpfdS4zv0/hOsS20sNmyqIFga1UyTapSLLYWhqL26dbYz/4dGaIUWhxfFih1pxUy6NTRJjJmnTmrvPlDONgGUSe2XRN+zBmA3VBYpBhBYRnFHtNmw0DSyaqPGHcQhqn0D8wlAO41oWbwejvNkGmcIMthIkMj+xxAvuqo8bDzrqXaGkaU16I84zTxcejgBNP+tzEWnDawkAgn89SxmpJAIkvBeIU83e2a77CNwuUsfdK7eVcm/bqKd9sZEuVkUGFoSmn5E+wlgpHnooH1pdUgDW/Gzczq170mObV/yk7jPmZNyj76/1cIwgmywykW3++GzA6RaDZA/YwK8dGVtDtKdX1A= X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: --=-YMQ3GU6gXOn3saq1BB65 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Fri, 2024-08-02 at 13:03 +0100, David Woodhouse wrote: >=20 > I'm actually tempted to make user access *interruptible* though, and > either add copy_{from,to}_user_interruptible() or change the semantics > of the existing ones (which I believe are already killable). >=20 > That would require each architecture implementing interruptible > exceptions, by doing an extable lookup before the retry. Not overly > complex, but needs to be done for all architectures (although not at > once; we could live with not-yet-done architectures just remaining > killable). >=20 > Thoughts? Utterly untested, hasn't even built yet and would need some cleanup (and better thoughts about how to indicate -EFAULT vs. -EINTR instead of having the caller check signal_pending() for itself). But should demonstrate what I was thinking, at least... diff --git a/arch/x86/include/asm/asm.h b/arch/x86/include/asm/asm.h index 2bec0c89a95c..854ccd5f2342 100644 --- a/arch/x86/include/asm/asm.h +++ b/arch/x86/include/asm/asm.h @@ -229,6 +229,9 @@ register unsigned long current_stack_pointer asm(_ASM_S= P); #define _ASM_EXTABLE_UA(from, to) \ _ASM_EXTABLE_TYPE(from, to, EX_TYPE_UACCESS) =20 +#define _ASM_EXTABLE_UA_INTR(from, to) \ + _ASM_EXTABLE_TYPE(from, to, EX_TYPE_UACCESS_INTERRUPTIBLE) + #define _ASM_EXTABLE_FAULT(from, to) \ _ASM_EXTABLE_TYPE(from, to, EX_TYPE_FAULT) =20 diff --git a/arch/x86/include/asm/extable_fixup_types.h b/arch/x86/include/= asm/extable_fixup_types.h index 906b0d5541e8..651d42f39e9b 100644 --- a/arch/x86/include/asm/extable_fixup_types.h +++ b/arch/x86/include/asm/extable_fixup_types.h @@ -36,7 +36,7 @@ #define EX_TYPE_DEFAULT 1 #define EX_TYPE_FAULT 2 #define EX_TYPE_UACCESS 3 -/* unused, was: #define EX_TYPE_COPY 4 */ +#define EX_TYPE_UACCESS_INTERRUPTIBLE 4 #define EX_TYPE_CLEAR_FS 5 #define EX_TYPE_FPU_RESTORE 6 #define EX_TYPE_BPF 7 diff --git a/arch/x86/include/asm/trapnr.h b/arch/x86/include/asm/trapnr.h index 8d1154cdf787..9f6397bad398 100644 --- a/arch/x86/include/asm/trapnr.h +++ b/arch/x86/include/asm/trapnr.h @@ -41,4 +41,5 @@ #define X86_TRAP_VC 29 /* VMM Communication Exception */ #define X86_TRAP_IRET 32 /* IRET Exception */ =20 +#define X86_TRAP_INTERRUPTIBLE 0x40000000 /* Internal, for interruptible e= xceptions */ #endif diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index cef729a25655..ab00150d360b 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -3819,12 +3819,15 @@ static void record_steal_time(struct kvm_vcpu *vcpu= ) asm volatile("1: xchgb %0, %2\n" "xor %1, %1\n" "2:\n" - _ASM_EXTABLE_UA(1b, 2b) + _ASM_EXTABLE_UA_INTR(1b, 2b) : "+q" (st_preempted), "+&r" (err), "+m" (st->preempted)); - if (err) + if (err) { + if (signal_pending(current)) + err =3D -EINTR; goto out; + } =20 user_access_end(); =20 diff --git a/arch/x86/mm/extable.c b/arch/x86/mm/extable.c index 51986e8a9d35..d2cef84042a5 100644 --- a/arch/x86/mm/extable.c +++ b/arch/x86/mm/extable.c @@ -325,6 +325,12 @@ int fixup_exception(struct pt_regs *regs, int trapnr, = unsigned long error_code, reg =3D FIELD_GET(EX_DATA_REG_MASK, e->data); imm =3D FIELD_GET(EX_DATA_IMM_MASK, e->data); =20 + if (trapnr & X86_TRAP_INTERRUPTIBLE) { + trapnr &=3D ~X86_TRAP_INTERRUPTIBLE; + if (type !=3D EX_TYPE_UACCESS_INTERRUPTIBLE) + return 0; + } + switch (type) { case EX_TYPE_DEFAULT: case EX_TYPE_DEFAULT_MCE_SAFE: @@ -333,6 +339,7 @@ int fixup_exception(struct pt_regs *regs, int trapnr, u= nsigned long error_code, case EX_TYPE_FAULT_MCE_SAFE: return ex_handler_fault(e, regs, trapnr); case EX_TYPE_UACCESS: + case EX_TYPE_UACCESS_INTERRUPTIBLE: return ex_handler_uaccess(e, regs, trapnr, fault_addr); case EX_TYPE_CLEAR_FS: return ex_handler_clear_fs(e, regs); diff --git a/arch/x86/mm/fault.c b/arch/x86/mm/fault.c index e6c469b323cc..4b32348dbb23 100644 --- a/arch/x86/mm/fault.c +++ b/arch/x86/mm/fault.c @@ -1388,18 +1388,6 @@ void do_user_addr_fault(struct pt_regs *regs, */ fault =3D handle_mm_fault(vma, address, flags, regs); =20 - if (fault_signal_pending(fault, regs)) { - /* - * Quick path to respond to signals. The core mm code - * has unlocked the mm for us if we get here. - */ - if (!user_mode(regs)) - kernelmode_fixup_or_oops(regs, error_code, address, - SIGBUS, BUS_ADRERR, - ARCH_DEFAULT_PKEY); - return; - } - /* The fault is fully completed (including releasing mmap lock) */ if (fault & VM_FAULT_COMPLETED) return; @@ -1410,6 +1398,28 @@ void do_user_addr_fault(struct pt_regs *regs, * that we made any progress. Handle this case first. */ if (unlikely(fault & VM_FAULT_RETRY)) { + if (signal_pending(current)) { + if (user_mode(regs)) + return; + + if (fatal_signal_pending(current)) { + kernelmode_fixup_or_oops(regs, error_code, address, + SIGBUS, BUS_ADRERR, + ARCH_DEFAULT_PKEY); + return; + } + + /* + * First time round, if woken by a signal, see if there + * is an interruptible exception handler. If so, do it. + * Else, switch off FAULT_FLAG_INTERRUPTIBLE. + */ + if (fixup_exception(regs, X86_TRAP_INTERRUPTIBLE | X86_TRAP_PF, + error_code, address)) + return; + flags &=3D ~FAULT_FLAG_INTERRUPTIBLE; + } + flags |=3D FAULT_FLAG_TRIED; goto retry; } --=-YMQ3GU6gXOn3saq1BB65 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Disposition: attachment; filename="smime.p7s" Content-Transfer-Encoding: base64 MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCCEkQw ggYQMIID+KADAgECAhBNlCwQ1DvglAnFgS06KwZPMA0GCSqGSIb3DQEBDAUAMIGIMQswCQYDVQQG EwJVUzETMBEGA1UECBMKTmV3IEplcnNleTEUMBIGA1UEBxMLSmVyc2V5IENpdHkxHjAcBgNVBAoT FVRoZSBVU0VSVFJVU1QgTmV0d29yazEuMCwGA1UEAxMlVVNFUlRydXN0IFJTQSBDZXJ0aWZpY2F0 aW9uIEF1dGhvcml0eTAeFw0xODExMDIwMDAwMDBaFw0zMDEyMzEyMzU5NTlaMIGWMQswCQYDVQQG EwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYD VQQKEw9TZWN0aWdvIExpbWl0ZWQxPjA8BgNVBAMTNVNlY3RpZ28gUlNBIENsaWVudCBBdXRoZW50 aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKC AQEAyjztlApB/975Rrno1jvm2pK/KxBOqhq8gr2+JhwpKirSzZxQgT9tlC7zl6hn1fXjSo5MqXUf ItMltrMaXqcESJuK8dtK56NCSrq4iDKaKq9NxOXFmqXX2zN8HHGjQ2b2Xv0v1L5Nk1MQPKA19xeW QcpGEGFUUd0kN+oHox+L9aV1rjfNiCj3bJk6kJaOPabPi2503nn/ITX5e8WfPnGw4VuZ79Khj1YB rf24k5Ee1sLTHsLtpiK9OjG4iQRBdq6Z/TlVx/hGAez5h36bBJMxqdHLpdwIUkTqT8se3ed0PewD ch/8kHPo5fZl5u1B0ecpq/sDN/5sCG52Ds+QU5O5EwIDAQABo4IBZDCCAWAwHwYDVR0jBBgwFoAU U3m/WqorSs9UgOHYm8Cd8rIDZsswHQYDVR0OBBYEFAnA8vwL2pTbX/4r36iZQs/J4K0AMA4GA1Ud DwEB/wQEAwIBhjASBgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEF BQcDBDARBgNVHSAECjAIMAYGBFUdIAAwUAYDVR0fBEkwRzBFoEOgQYY/aHR0cDovL2NybC51c2Vy dHJ1c3QuY29tL1VTRVJUcnVzdFJTQUNlcnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHYGCCsGAQUF BwEBBGowaDA/BggrBgEFBQcwAoYzaHR0cDovL2NydC51c2VydHJ1c3QuY29tL1VTRVJUcnVzdFJT QUFkZFRydXN0Q0EuY3J0MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMA0G CSqGSIb3DQEBDAUAA4ICAQBBRHUAqznCFfXejpVtMnFojADdF9d6HBA4kMjjsb0XMZHztuOCtKF+ xswhh2GqkW5JQrM8zVlU+A2VP72Ky2nlRA1GwmIPgou74TZ/XTarHG8zdMSgaDrkVYzz1g3nIVO9 IHk96VwsacIvBF8JfqIs+8aWH2PfSUrNxP6Ys7U0sZYx4rXD6+cqFq/ZW5BUfClN/rhk2ddQXyn7 kkmka2RQb9d90nmNHdgKrwfQ49mQ2hWQNDkJJIXwKjYA6VUR/fZUFeCUisdDe/0ABLTI+jheXUV1 eoYV7lNwNBKpeHdNuO6Aacb533JlfeUHxvBz9OfYWUiXu09sMAviM11Q0DuMZ5760CdO2VnpsXP4 KxaYIhvqPqUMWqRdWyn7crItNkZeroXaecG03i3mM7dkiPaCkgocBg0EBYsbZDZ8bsG3a08LwEsL 1Ygz3SBsyECa0waq4hOf/Z85F2w2ZpXfP+w8q4ifwO90SGZZV+HR/Jh6rEaVPDRF/CEGVqR1hiuQ OZ1YL5ezMTX0ZSLwrymUE0pwi/KDaiYB15uswgeIAcA6JzPFf9pLkAFFWs1QNyN++niFhsM47qod x/PL+5jR87myx5uYdBEQkkDc+lKB1Wct6ucXqm2EmsaQ0M95QjTmy+rDWjkDYdw3Ms6mSWE3Bn7i 5ZgtwCLXgAIe5W8mybM2JzCCBhQwggT8oAMCAQICEQDGvhmWZ0DEAx0oURL6O6l+MA0GCSqGSIb3 DQEBCwUAMIGWMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAwDgYD VQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxPjA8BgNVBAMTNVNlY3RpZ28g UlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBMB4XDTIyMDEwNzAw MDAwMFoXDTI1MDEwNjIzNTk1OVowJDEiMCAGCSqGSIb3DQEJARYTZHdtdzJAaW5mcmFkZWFkLm9y ZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALQ3GpC2bomUqk+91wLYBzDMcCj5C9m6 oZaHwvmIdXftOgTbCJXADo6G9T7BBAebw2JV38EINgKpy/ZHh7htyAkWYVoFsFPrwHounto8xTsy SSePMiPlmIdQ10BcVSXMUJ3Juu16GlWOnAMJY2oYfEzmE7uT9YgcBqKCo65pTFmOnR/VVbjJk4K2 xE34GC2nAdUQkPFuyaFisicc6HRMOYXPuF0DuwITEKnjxgNjP+qDrh0db7PAjO1D4d5ftfrsf+kd RR4gKVGSk8Tz2WwvtLAroJM4nXjNPIBJNT4w/FWWc/5qPHJy2U+eITZ5LLE5s45mX2oPFknWqxBo bQZ8a9dsZ3dSPZBvE9ZrmtFLrVrN4eo1jsXgAp1+p7bkfqd3BgBEmfsYWlBXO8rVXfvPgLs32VdV NZxb/CDWPqBsiYv0Hv3HPsz07j5b+/cVoWqyHDKzkaVbxfq/7auNVRmPB3v5SWEsH8xi4Bez2V9U KxfYCnqsjp8RaC2/khxKt0A552Eaxnz/4ly/2C7wkwTQnBmdlFYhAflWKQ03Ufiu8t3iBE3VJbc2 5oMrglj7TRZrmKq3CkbFnX0fyulB+kHimrt6PIWn7kgyl9aelIl6vtbhMA+l0nfrsORMa4kobqQ5 C5rveVgmcIad67EDa+UqEKy/GltUwlSh6xy+TrK1tzDvAgMBAAGjggHMMIIByDAfBgNVHSMEGDAW gBQJwPL8C9qU21/+K9+omULPyeCtADAdBgNVHQ4EFgQUzMeDMcimo0oz8o1R1Nver3ZVpSkwDgYD VR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYwFAYIKwYBBQUHAwQGCCsGAQUFBwMC MEAGA1UdIAQ5MDcwNQYMKwYBBAGyMQECAQEBMCUwIwYIKwYBBQUHAgEWF2h0dHBzOi8vc2VjdGln by5jb20vQ1BTMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9jcmwuc2VjdGlnby5jb20vU2VjdGln b1JTQUNsaWVudEF1dGhlbnRpY2F0aW9uYW5kU2VjdXJlRW1haWxDQS5jcmwwgYoGCCsGAQUFBwEB BH4wfDBVBggrBgEFBQcwAoZJaHR0cDovL2NydC5zZWN0aWdvLmNvbS9TZWN0aWdvUlNBQ2xpZW50 QXV0aGVudGljYXRpb25hbmRTZWN1cmVFbWFpbENBLmNydDAjBggrBgEFBQcwAYYXaHR0cDovL29j c3Auc2VjdGlnby5jb20wHgYDVR0RBBcwFYETZHdtdzJAaW5mcmFkZWFkLm9yZzANBgkqhkiG9w0B AQsFAAOCAQEAyW6MUir5dm495teKqAQjDJwuFCi35h4xgnQvQ/fzPXmtR9t54rpmI2TfyvcKgOXp qa7BGXNFfh1JsqexVkIqZP9uWB2J+uVMD+XZEs/KYNNX2PvIlSPrzIB4Z2wyIGQpaPLlYflrrVFK v9CjT2zdqvy2maK7HKOQRt3BiJbVG5lRiwbbygldcALEV9ChWFfgSXvrWDZspnU3Gjw/rMHrGnql Htlyebp3pf3fSS9kzQ1FVtVIDrL6eqhTwJxe+pXSMMqFiN0whpBtXdyDjzBtQTaZJ7zTT/vlehc/ tDuqZwGHm/YJy883Ll+GP3NvOkgaRGWEuYWJJ6hFCkXYjyR9IzCCBhQwggT8oAMCAQICEQDGvhmW Z0DEAx0oURL6O6l+MA0GCSqGSIb3DQEBCwUAMIGWMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0 ZWQxPjA8BgNVBAMTNVNlY3RpZ28gUlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJl IEVtYWlsIENBMB4XDTIyMDEwNzAwMDAwMFoXDTI1MDEwNjIzNTk1OVowJDEiMCAGCSqGSIb3DQEJ ARYTZHdtdzJAaW5mcmFkZWFkLm9yZzCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBALQ3 GpC2bomUqk+91wLYBzDMcCj5C9m6oZaHwvmIdXftOgTbCJXADo6G9T7BBAebw2JV38EINgKpy/ZH h7htyAkWYVoFsFPrwHounto8xTsySSePMiPlmIdQ10BcVSXMUJ3Juu16GlWOnAMJY2oYfEzmE7uT 9YgcBqKCo65pTFmOnR/VVbjJk4K2xE34GC2nAdUQkPFuyaFisicc6HRMOYXPuF0DuwITEKnjxgNj P+qDrh0db7PAjO1D4d5ftfrsf+kdRR4gKVGSk8Tz2WwvtLAroJM4nXjNPIBJNT4w/FWWc/5qPHJy 2U+eITZ5LLE5s45mX2oPFknWqxBobQZ8a9dsZ3dSPZBvE9ZrmtFLrVrN4eo1jsXgAp1+p7bkfqd3 BgBEmfsYWlBXO8rVXfvPgLs32VdVNZxb/CDWPqBsiYv0Hv3HPsz07j5b+/cVoWqyHDKzkaVbxfq/ 7auNVRmPB3v5SWEsH8xi4Bez2V9UKxfYCnqsjp8RaC2/khxKt0A552Eaxnz/4ly/2C7wkwTQnBmd lFYhAflWKQ03Ufiu8t3iBE3VJbc25oMrglj7TRZrmKq3CkbFnX0fyulB+kHimrt6PIWn7kgyl9ae lIl6vtbhMA+l0nfrsORMa4kobqQ5C5rveVgmcIad67EDa+UqEKy/GltUwlSh6xy+TrK1tzDvAgMB AAGjggHMMIIByDAfBgNVHSMEGDAWgBQJwPL8C9qU21/+K9+omULPyeCtADAdBgNVHQ4EFgQUzMeD Mcimo0oz8o1R1Nver3ZVpSkwDgYDVR0PAQH/BAQDAgWgMAwGA1UdEwEB/wQCMAAwHQYDVR0lBBYw FAYIKwYBBQUHAwQGCCsGAQUFBwMCMEAGA1UdIAQ5MDcwNQYMKwYBBAGyMQECAQEBMCUwIwYIKwYB BQUHAgEWF2h0dHBzOi8vc2VjdGlnby5jb20vQ1BTMFoGA1UdHwRTMFEwT6BNoEuGSWh0dHA6Ly9j cmwuc2VjdGlnby5jb20vU2VjdGlnb1JTQUNsaWVudEF1dGhlbnRpY2F0aW9uYW5kU2VjdXJlRW1h aWxDQS5jcmwwgYoGCCsGAQUFBwEBBH4wfDBVBggrBgEFBQcwAoZJaHR0cDovL2NydC5zZWN0aWdv LmNvbS9TZWN0aWdvUlNBQ2xpZW50QXV0aGVudGljYXRpb25hbmRTZWN1cmVFbWFpbENBLmNydDAj BggrBgEFBQcwAYYXaHR0cDovL29jc3Auc2VjdGlnby5jb20wHgYDVR0RBBcwFYETZHdtdzJAaW5m cmFkZWFkLm9yZzANBgkqhkiG9w0BAQsFAAOCAQEAyW6MUir5dm495teKqAQjDJwuFCi35h4xgnQv Q/fzPXmtR9t54rpmI2TfyvcKgOXpqa7BGXNFfh1JsqexVkIqZP9uWB2J+uVMD+XZEs/KYNNX2PvI lSPrzIB4Z2wyIGQpaPLlYflrrVFKv9CjT2zdqvy2maK7HKOQRt3BiJbVG5lRiwbbygldcALEV9Ch WFfgSXvrWDZspnU3Gjw/rMHrGnqlHtlyebp3pf3fSS9kzQ1FVtVIDrL6eqhTwJxe+pXSMMqFiN0w hpBtXdyDjzBtQTaZJ7zTT/vlehc/tDuqZwGHm/YJy883Ll+GP3NvOkgaRGWEuYWJJ6hFCkXYjyR9 IzGCBMcwggTDAgEBMIGsMIGWMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVz dGVyMRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxPjA8BgNVBAMT NVNlY3RpZ28gUlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBAhEA xr4ZlmdAxAMdKFES+jupfjANBglghkgBZQMEAgEFAKCCAeswGAYJKoZIhvcNAQkDMQsGCSqGSIb3 DQEHATAcBgkqhkiG9w0BCQUxDxcNMjQwODAyMTYwNjE3WjAvBgkqhkiG9w0BCQQxIgQgOU4Vj6bt ewTUAS2Uq1lmzyjoRwDc2rjRiE9W2T0C0Wcwgb0GCSsGAQQBgjcQBDGBrzCBrDCBljELMAkGA1UE BhMCR0IxGzAZBgNVBAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEYMBYG A1UEChMPU2VjdGlnbyBMaW1pdGVkMT4wPAYDVQQDEzVTZWN0aWdvIFJTQSBDbGllbnQgQXV0aGVu dGljYXRpb24gYW5kIFNlY3VyZSBFbWFpbCBDQQIRAMa+GZZnQMQDHShREvo7qX4wgb8GCyqGSIb3 DQEJEAILMYGvoIGsMIGWMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVy MRAwDgYDVQQHEwdTYWxmb3JkMRgwFgYDVQQKEw9TZWN0aWdvIExpbWl0ZWQxPjA8BgNVBAMTNVNl Y3RpZ28gUlNBIENsaWVudCBBdXRoZW50aWNhdGlvbiBhbmQgU2VjdXJlIEVtYWlsIENBAhEAxr4Z lmdAxAMdKFES+jupfjANBgkqhkiG9w0BAQEFAASCAgB7Jw9KmmBRtOyhRsxGeocl+esfJuacZaaX yBmP+ihH+i9NsDY266PzSaVYOJ+7hgAlq+M28B6JWJ+ouku0QkWzo9QtnWCHJy4tFJtFh+pKqY/2 GlA30KG07X9RDQgM6/t6tDletAUK9jTeVwgb2OoW21yH/S2t/zLizdmx3l2MFXVWDiCCpa32zFyi trY9vCS3jM87mF+T6XzO8bsoVMDIFvSKVO4BOXjvlOOqRlK6it2q1kkR+xA1aWUrpVB0tScTAC49 u4mQfFtQ59NrQaXiq8VXNmbKlL7tFcV2U7SQD8OH+ON8+wRSWshQ10haobGdJRhi9keHx/567SkR 7Okg/CHG+QeILrgWfD3Zl8ClIOhUX0YHZxyv+i0QFFdY/8gDn9B7idvCTkMK9jPtPOcpIps+HXlX qE0v7eloaf8Jj97ehVoWQdoUcQFlAoDZuztgUpDt072tK3fXjcr2EgXwV4nr9/rsa2GsZkx29BVZ Al2JLij/2NFg/W90UXxTdEeke4fzFbWWZ7E6MdjZMnnBRVsxQzpKPWYIRCdiYfk9sAjvZ0rcoMf0 JfyPcSj6b/Shw9iPWkkh+4wq+H30hpWSlYibja9AbFrzkZ9P8oykM+ou2fY4kchtSQUOl32XxpRp 0GytUU6PqDomYM7lUOszmpzX4KoqseDHMHrrZSwLbgAAAAAAAA== --=-YMQ3GU6gXOn3saq1BB65--