From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from casper.infradead.org (casper.infradead.org [90.155.50.34]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2004E33A6F2 for ; Tue, 19 May 2026 15:50:54 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=90.155.50.34 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779205859; cv=none; b=c0AxERIR4ePtOV8j2oknAOy7Inh2Dg1l+DkRJmHLX5nWuXV6mG2Btf5E8qmlFbCRKaYwg1F7GV6l9SfH28tg9AqKtWmQvLClF4Pt/yKxC/8MsRdSZOWF/rt98tVZFGPpAfIZZ7vOlvPCWKO7LdNDK7BLfHZWEr1WWTcbi4ACsz0= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1779205859; c=relaxed/simple; bh=DFkEknl1C0KFY13qJklKzSFSM+hx+7VfqMJZVDs/nxw=; h=Message-ID:Subject:From:To:Cc:Date:In-Reply-To:References: Content-Type:MIME-Version; b=qZjnIROGZPJGq98GZODJhFBHvjcKVE6LjxVLvlmOwrJIGZciS8tKIscx7vAyiaCxDEWFqE+a16IAnz3e8MsiSkyC0veTKEqFPI/MwGg9if8HRmUjinEvxgFWoAUgc+wi6Abx0jtRpC1YrBdR/uYFx1el6hdhNA7NiPdkw88M03Q= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org; spf=none smtp.mailfrom=casper.srs.infradead.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b=R2DIqXyq; arc=none smtp.client-ip=90.155.50.34 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=infradead.org Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=casper.srs.infradead.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=infradead.org header.i=@infradead.org header.b="R2DIqXyq" 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=+vZTgzoSIUrM65S5U5N9HatX5Y/N0i2byd6MbRe4z54=; b=R2DIqXyq7jt+yo4nLmb2Zv9fZV YIqcH18u9BJI7LAov7j/+5CshGc//J7Cx2Q1ganjSYzf0UPSdTx0MskXrZdZc+lOS3a27vvnDQpkF B3/+SrFbUCC76RPyLFPZVA3rzrEYG2JoNMfZaJ6UUFWIhBsUnsEnrbd9xDBKpCLdWCLwkDjp4TFhS cSZzlsGKD4O//zTs/2TU/fqPl7oEUmZIJJdAUN7V2+Ob4C53reuUgDC82L3lDIEeabm7HgZjH/Qzd 9kt64qg5STQYQlM1/rI7uIy1Fc4PJQNSqlKPUOrVqen8U9qR6MeFqUPRhu3L0h18SK1rwz/2tvVEU K9zDdMeg==; Received: from 54-240-197-233.amazon.com ([54.240.197.233] helo=u09cd745991455d.ant.amazon.com) by casper.infradead.org with esmtpsa (Exim 4.99.1 #2 (Red Hat Linux)) id 1wPMiQ-000000064CY-1ZCE; Tue, 19 May 2026 15:50:42 +0000 Message-ID: <0d32da75fa88c92ac0225ef23a9045afdf2ac9fe.camel@infradead.org> Subject: Re: [RFC PATCH v2 0/8] timekeeping: Fix draft tracking precision and add feed-forward discipline via vmclock From: David Woodhouse To: Miroslav Lichvar Cc: Richard Cochran , Wen Gu , Andrew Lunn , "David S. Miller" , Eric Dumazet , Jakub Kicinski , Paolo Abeni , John Stultz , Thomas Gleixner , Stephen Boyd , Anna-Maria Behnsen , Frederic Weisbecker , Shuah Khan , Peter Zijlstra , Thomas =?ISO-8859-1?Q?Wei=DFschuh?= , Arnd Bergmann , Julien Ridoux , Ryan Luu , linux-kernel@vger.kernel.org Date: Tue, 19 May 2026 16:50:41 +0100 In-Reply-To: References: <20260517220326.4625-1-dwmw2@infradead.org> Content-Type: multipart/signed; micalg="sha-256"; protocol="application/pkcs7-signature"; boundary="=-TLkh93lmuNUIf12odsuA" User-Agent: Evolution 3.52.3-0ubuntu1.1 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-SRS-Rewrite: SMTP reverse-path rewritten from by casper.infradead.org. See http://www.infradead.org/rpr.html --=-TLkh93lmuNUIf12odsuA Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Tue, 2026-05-19 at 15:16 +0200, Miroslav Lichvar wrote: > On Sun, May 17, 2026 at 10:25:37PM +0100, David Woodhouse wrote: > > The vmclock device (https://uapi-group.org/specifications/specs/vmclock= /) > > provides a shared memory page containing a linear time function: > > time =3D base + (counter - counter_value) =C3=97 period. The guest can = read > > this at any time to determine the hypervisor's view of the current time= , > > without a VM exit. >=20 > That sounds nice. The design has two major purposes: =E2=80=A2 Atomically letting the guest know that live migration has pertur= bed its clock. Without this, some distributed databases which rely on precision timestamps on transactions for eventual coherency were getting corrupted when guests were live migrated. =E2=80=A2 Avoiding the redundant work of having *hundreds* of guests on th= e same host *all* calibrating the same underlying oscillator, while enjoying the added fun of steal time as they're trying to to so. Right now, the implementations in both QEMU and the EC2 Nitro Hypervisor only implement part 1, the disruption signal. I plan for QEMU to use the vmclock_host driver from this series, along with the QEMU patch I linked, to expose the host's real time clock guests to follow. For dedicated hosting environments like EC2, we don't care very much about the host's timekeeping; that host kernel exists *only* to host KVM guests. The host userspace can ignore the host's timekeeping completely and manage the relationship of the counter to real time directly =E2=80=94 and in some cases will have hardware which will latch th= e actual CPU's counter at the moment of a 1PPS signal. We'll feed that counter-to-realtime information *directly* to guests. (And will probably export timekeeping_set_reference() via a syscall of some kind so that we *can* set the host's clock from it too, if I can't find a way to precisely do so through adjtimex.)=20 > > The existing ptp_vmclock driver already exposes this as a PTP clock for > > userspace consumers (phc2sys, chrony). This series adds kernel-internal > > consumption: the tick mechanism can clamp directly to the vmclock > > reference, eliminating the need for NTP to discipline the guest clock. >=20 > I'm not very familiar with the VM timekeeping and other code. If I > understand this idea correctly, by loading the ptp_vmclock module the > guest kernel is giving the host control of its clock.=C2=A0 Right *now*, the ptp_vmclock module is only providing a PTP clock for userspace to discipline the kernel against, as noted above. But yes, the intent of what I'm doing here is to bypass all that complexity and manage the explicit counter-to-time relationship *directly* within the guest kernel. I did briefly play with simulating 1PPS, and injecting PPS events at the precise time that a PPS signal *would* have triggered, to the cycle:=20 https://lore.kernel.org/all/87cb97d5a26d0f4909d2ba2545c4b43281109470.camel@= infradead.org/ > Changes in the host's REALTIME/MONOTONIC clock frequency are mirrored > to the guest's clock.=C2=A0 Strictly, "changes in the realtime clock frequency advertised by the vmclock device", but basically yes. > Differences larger than 100 milliseconds are corrected by step, > whether the guest applications like it or not. Smaller steps and > errors accumulated due to a delay in the frequency update (is there a > limit to this delay?) are corrected by the kernel NTP PLL (with the > default time constant?).=C2=A0 That behaviour isn't set in stone for vmclock; I'm still only experimenting with the part where it *can* set the frequency, and an offset that the kernel will converge to and *stay* on. Right now it just calls my ntp_set_time_offset() which doesn't step at all, and always just injects via ->time_offset (the NTP PLL). Much the same as legacy adjtime() AIUI. > When the guest is migrated to a different host, the frequency offset > between the two hosts is injected to the NTP frequency (assuming > REALTIME clocks of the hosts have zero frequency error at that > moment?). When the advertised frequency changes (either due to the ongoing clock discipline on the host, or because of migration to a new host), the new frequency is injected directly into tick_length. > Have you considered a different approach that would address the > problem with frequency step by adjusting the guest's clocksource > frequency to match the original host? That would correct all system > clocks, i.e. not only REALTIME/MONOTONIC, but also MONOTONIC_RAW and > AUX clocks. You mean TSC scaling to change the frequency of the actual counter?=20 When stepping between non-identical hosts, that might be helpful. But we still have to deal with the variance of the counter over time even without migration in the picture. > The guest would still be in control of its clock and follow its own > preferences to stepping, maximum frequency errors, etc. It could still > compare the stability and accuracy of the host's clock and use it for > synchronization only when it's actually better than other available > time sources (some VPS providers are known to have poorly synchronized > host clocks). I think that mode is already available as a PTP clock, isn't it? While of course it should be optional for the guest, I'm deliberately optimising for the case here where the hosting provider *does* get it right and *can* be trusted. > An AUX clock could be used to more accurately compare > frequencies of the two hosts, ignoring phase corrections. >=20 > There is a work in progress for chrony to support MONOTONIC_RAW as the > main clock. It would be nice if that could be corrected in migrations. Not sure I understand this. I thought the whole point of MONOTONIC_RAW is that it *isn't* skewed by NTP? > That seems to be a common cause of disruptions of public NTP servers. > Polling for notifications about clock changes caused by migrations and > system suspend+resume would be useful in any case. That much you can do today with /dev/vmclock even when it isn't exposing the actual time information. Timekeeping in migration is fairly hosed in KVM. I don't think there are many implementations that actually set the TSC correctly on the destination host. But that's a different story... --=-TLkh93lmuNUIf12odsuA Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Disposition: attachment; filename="smime.p7s" Content-Transfer-Encoding: base64 MIAGCSqGSIb3DQEHAqCAMIACAQExDzANBglghkgBZQMEAgEFADCABgkqhkiG9w0BBwEAAKCCD9Aw ggSOMIIDdqADAgECAhAOmiw0ECVD4cWj5DqVrT9PMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYT AlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAi BgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0yNDAxMzAwMDAwMDBaFw0zMTEx MDkyMzU5NTlaMEExCzAJBgNVBAYTAkFVMRAwDgYDVQQKEwdWZXJva2V5MSAwHgYDVQQDExdWZXJv a2V5IFNlY3VyZSBFbWFpbCBHMjCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMjvgLKj jfhCFqxYyRiW8g3cNFAvltDbK5AzcOaR7yVzVGadr4YcCVxjKrEJOgi7WEOH8rUgCNB5cTD8N/Et GfZI+LGqSv0YtNa54T9D1AWJy08ZKkWvfGGIXN9UFAPMJ6OLLH/UUEgFa+7KlrEvMUupDFGnnR06 aDJAwtycb8yXtILj+TvfhLFhafxroXrflspavejQkEiHjNjtHnwbZ+o43g0/yxjwnarGI3kgcak7 nnI9/8Lqpq79tLHYwLajotwLiGTB71AGN5xK+tzB+D4eN9lXayrjcszgbOv2ZCgzExQUAIt98mre 8EggKs9mwtEuKAhYBIP/0K6WsoMnQCcCAwEAAaOCAVwwggFYMBIGA1UdEwEB/wQIMAYBAf8CAQAw HQYDVR0OBBYEFIlICOogTndrhuWByNfhjWSEf/xwMB8GA1UdIwQYMBaAFEXroq/0ksuCMS1Ri6en IZ3zbcgPMA4GA1UdDwEB/wQEAwIBhjAdBgNVHSUEFjAUBggrBgEFBQcDBAYIKwYBBQUHAwIweQYI KwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYB BQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RD QS5jcnQwRQYDVR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcNAQELBQADggEB ACiagCqvNVxOfSd0uYfJMiZsOEBXAKIR/kpqRp2YCfrP4Tz7fJogYN4fxNAw7iy/bPZcvpVCfe/H /CCcp3alXL0I8M/rnEnRlv8ItY4MEF+2T/MkdXI3u1vHy3ua8SxBM8eT9LBQokHZxGUX51cE0kwa uEOZ+PonVIOnMjuLp29kcNOVnzf8DGKiek+cT51FvGRjV6LbaxXOm2P47/aiaXrDD5O0RF5SiPo6 xD1/ClkCETyyEAE5LRJlXtx288R598koyFcwCSXijeVcRvBB1cNOLEbg7RMSw1AGq14fNe2cH1HG W7xyduY/ydQt6gv5r21mDOQ5SaZSWC/ZRfLDuEYwggWbMIIEg6ADAgECAhAH5JEPagNRXYDiRPdl c1vgMA0GCSqGSIb3DQEBCwUAMEExCzAJBgNVBAYTAkFVMRAwDgYDVQQKEwdWZXJva2V5MSAwHgYD VQQDExdWZXJva2V5IFNlY3VyZSBFbWFpbCBHMjAeFw0yNDEyMzAwMDAwMDBaFw0yODAxMDQyMzU5 NTlaMB4xHDAaBgNVBAMME2R3bXcyQGluZnJhZGVhZC5vcmcwggIiMA0GCSqGSIb3DQEBAQUAA4IC DwAwggIKAoICAQDali7HveR1thexYXx/W7oMk/3Wpyppl62zJ8+RmTQH4yZeYAS/SRV6zmfXlXaZ sNOE6emg8WXLRS6BA70liot+u0O0oPnIvnx+CsMH0PD4tCKSCsdp+XphIJ2zkC9S7/yHDYnqegqt w4smkqUqf0WX/ggH1Dckh0vHlpoS1OoxqUg+ocU6WCsnuz5q5rzFsHxhD1qGpgFdZEk2/c//ZvUN i12vPWipk8TcJwHw9zoZ/ZrVNybpMCC0THsJ/UEVyuyszPtNYeYZAhOJ41vav1RhZJzYan4a1gU0 kKBPQklcpQEhq48woEu15isvwWh9/+5jjh0L+YNaN0I//nHSp6U9COUG9Z0cvnO8FM6PTqsnSbcc 0j+GchwOHRC7aP2t5v2stVx3KbptaYEzi4MQHxm/0+HQpMEVLLUiizJqS4PWPU6zfQTOMZ9uLQRR ci+c5xhtMEBszlQDOvEQcyEG+hc++fH47K+MmZz21bFNfoBxLP6bjR6xtPXtREF5lLXxp+CJ6KKS blPKeVRg/UtyJHeFKAZXO8Zeco7TZUMVHmK0ZZ1EpnZbnAhKE19Z+FJrQPQrlR0gO3lBzuyPPArV hvWxjlO7S4DmaEhLzarWi/ze7EGwWSuI2eEa/8zU0INUsGI4ywe7vepQz7IqaAovAX0d+f1YjbmC VsAwjhLmveFjNwIDAQABo4IBsDCCAawwHwYDVR0jBBgwFoAUiUgI6iBOd2uG5YHI1+GNZIR//HAw HQYDVR0OBBYEFFxiGptwbOfWOtMk5loHw7uqWUOnMDAGA1UdEQQpMCeBE2R3bXcyQGluZnJhZGVh ZC5vcmeBEGRhdmlkQHdvb2Rob3Uuc2UwFAYDVR0gBA0wCzAJBgdngQwBBQEBMA4GA1UdDwEB/wQE AwIF4DAdBgNVHSUEFjAUBggrBgEFBQcDAgYIKwYBBQUHAwQwewYDVR0fBHQwcjA3oDWgM4YxaHR0 cDovL2NybDMuZGlnaWNlcnQuY29tL1Zlcm9rZXlTZWN1cmVFbWFpbEcyLmNybDA3oDWgM4YxaHR0 cDovL2NybDQuZGlnaWNlcnQuY29tL1Zlcm9rZXlTZWN1cmVFbWFpbEcyLmNybDB2BggrBgEFBQcB AQRqMGgwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBABggrBgEFBQcwAoY0 aHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL1Zlcm9rZXlTZWN1cmVFbWFpbEcyLmNydDANBgkq hkiG9w0BAQsFAAOCAQEAQXc4FPiPLRnTDvmOABEzkIumojfZAe5SlnuQoeFUfi+LsWCKiB8Uextv iBAvboKhLuN6eG/NC6WOzOCppn4mkQxRkOdLNThwMHW0d19jrZFEKtEG/epZ/hw/DdScTuZ2m7im 8ppItAT6GXD3aPhXkXnJpC/zTs85uNSQR64cEcBFjjoQDuSsTeJ5DAWf8EMyhMuD8pcbqx5kRvyt JPsWBQzv1Dsdv2LDPLNd/JUKhHSgr7nbUr4+aAP2PHTXGcEBh8lTeYea9p4d5k969pe0OHYMV5aL xERqTagmSetuIwolkAuBCzA9vulg8Y49Nz2zrpUGfKGOD0FMqenYxdJHgDCCBZswggSDoAMCAQIC EAfkkQ9qA1FdgOJE92VzW+AwDQYJKoZIhvcNAQELBQAwQTELMAkGA1UEBhMCQVUxEDAOBgNVBAoT B1Zlcm9rZXkxIDAeBgNVBAMTF1Zlcm9rZXkgU2VjdXJlIEVtYWlsIEcyMB4XDTI0MTIzMDAwMDAw MFoXDTI4MDEwNDIzNTk1OVowHjEcMBoGA1UEAwwTZHdtdzJAaW5mcmFkZWFkLm9yZzCCAiIwDQYJ KoZIhvcNAQEBBQADggIPADCCAgoCggIBANqWLse95HW2F7FhfH9bugyT/danKmmXrbMnz5GZNAfj Jl5gBL9JFXrOZ9eVdpmw04Tp6aDxZctFLoEDvSWKi367Q7Sg+ci+fH4KwwfQ8Pi0IpIKx2n5emEg nbOQL1Lv/IcNiep6Cq3DiyaSpSp/RZf+CAfUNySHS8eWmhLU6jGpSD6hxTpYKye7PmrmvMWwfGEP WoamAV1kSTb9z/9m9Q2LXa89aKmTxNwnAfD3Ohn9mtU3JukwILRMewn9QRXK7KzM+01h5hkCE4nj W9q/VGFknNhqfhrWBTSQoE9CSVylASGrjzCgS7XmKy/BaH3/7mOOHQv5g1o3Qj/+cdKnpT0I5Qb1 nRy+c7wUzo9OqydJtxzSP4ZyHA4dELto/a3m/ay1XHcpum1pgTOLgxAfGb/T4dCkwRUstSKLMmpL g9Y9TrN9BM4xn24tBFFyL5znGG0wQGzOVAM68RBzIQb6Fz758fjsr4yZnPbVsU1+gHEs/puNHrG0 9e1EQXmUtfGn4InoopJuU8p5VGD9S3Ikd4UoBlc7xl5yjtNlQxUeYrRlnUSmdlucCEoTX1n4UmtA 9CuVHSA7eUHO7I88CtWG9bGOU7tLgOZoSEvNqtaL/N7sQbBZK4jZ4Rr/zNTQg1SwYjjLB7u96lDP sipoCi8BfR35/ViNuYJWwDCOEua94WM3AgMBAAGjggGwMIIBrDAfBgNVHSMEGDAWgBSJSAjqIE53 a4blgcjX4Y1khH/8cDAdBgNVHQ4EFgQUXGIam3Bs59Y60yTmWgfDu6pZQ6cwMAYDVR0RBCkwJ4ET ZHdtdzJAaW5mcmFkZWFkLm9yZ4EQZGF2aWRAd29vZGhvdS5zZTAUBgNVHSAEDTALMAkGB2eBDAEF AQEwDgYDVR0PAQH/BAQDAgXgMB0GA1UdJQQWMBQGCCsGAQUFBwMCBggrBgEFBQcDBDB7BgNVHR8E dDByMDegNaAzhjFodHRwOi8vY3JsMy5kaWdpY2VydC5jb20vVmVyb2tleVNlY3VyZUVtYWlsRzIu Y3JsMDegNaAzhjFodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vVmVyb2tleVNlY3VyZUVtYWlsRzIu Y3JsMHYGCCsGAQUFBwEBBGowaDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29t MEAGCCsGAQUFBzAChjRodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vVmVyb2tleVNlY3VyZUVt YWlsRzIuY3J0MA0GCSqGSIb3DQEBCwUAA4IBAQBBdzgU+I8tGdMO+Y4AETOQi6aiN9kB7lKWe5Ch 4VR+L4uxYIqIHxR7G2+IEC9ugqEu43p4b80LpY7M4KmmfiaRDFGQ50s1OHAwdbR3X2OtkUQq0Qb9 6ln+HD8N1JxO5nabuKbymki0BPoZcPdo+FeRecmkL/NOzzm41JBHrhwRwEWOOhAO5KxN4nkMBZ/w QzKEy4PylxurHmRG/K0k+xYFDO/UOx2/YsM8s138lQqEdKCvudtSvj5oA/Y8dNcZwQGHyVN5h5r2 nh3mT3r2l7Q4dgxXlovERGpNqCZJ624jCiWQC4ELMD2+6WDxjj03PbOulQZ8oY4PQUyp6djF0keA MYIDuzCCA7cCAQEwVTBBMQswCQYDVQQGEwJBVTEQMA4GA1UEChMHVmVyb2tleTEgMB4GA1UEAxMX VmVyb2tleSBTZWN1cmUgRW1haWwgRzICEAfkkQ9qA1FdgOJE92VzW+AwDQYJYIZIAWUDBAIBBQCg ggE3MBgGCSqGSIb3DQEJAzELBgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTI2MDUxOTE1NTA0 MVowLwYJKoZIhvcNAQkEMSIEIEhkstC3V24xfvXXvZuMbxiTcWmWfaC/aPRrvKhrGft9MGQGCSsG AQQBgjcQBDFXMFUwQTELMAkGA1UEBhMCQVUxEDAOBgNVBAoTB1Zlcm9rZXkxIDAeBgNVBAMTF1Zl cm9rZXkgU2VjdXJlIEVtYWlsIEcyAhAH5JEPagNRXYDiRPdlc1vgMGYGCyqGSIb3DQEJEAILMVeg VTBBMQswCQYDVQQGEwJBVTEQMA4GA1UEChMHVmVyb2tleTEgMB4GA1UEAxMXVmVyb2tleSBTZWN1 cmUgRW1haWwgRzICEAfkkQ9qA1FdgOJE92VzW+AwDQYJKoZIhvcNAQEBBQAEggIAJEyLvCqC8qEJ RADNukza5pyDWTQWT7i72f0eoRBki+WvtkzKqxGiMsLguVpq293Uc7PXfqwtE+pEA/GM8NpAaGNz y3+8Uwe2uraj74zc0d2UtUJZ2Smmg2KSBRwMjbCZqeIKvqTfUS5L97oHWISjrjkh0Hv2mF8ias+a CYG7mRrWjKPGQeCZgVisGHN3jhnYMwLeiWTbec3iP6Eu+nHlp9io/ucYafRImRNmz1iPl/78Qfng AirxhtLvg43d/ea0sOdLav9TrgmBhVHO4nJJt3xOzeK0fNktnsBLSnBsuwnWm1Ddi6aTyzPJF/k4 rdCR79ai/gfIWFan9bjxgj26YPfzL3WFdIhbm3/MogwilG6nATycS90oT3uzGHYGK0SCNm332kmj ObLpSlq4VivxICzYlgml44zfO6Sj53kBkpoURs1aQpuk/DzT2ZoWKLGnzqFQjbYFlgrp4ShUbV4i l9MApeljE6MOgpfHGMPU87cBYaKUkbUuiwTeWMCAIAu5patode8ExcXqO014vNwS3SKtWtBsX6Aa spt+1UriuWt+vuRXsq4AZErStHIN1GOHofJookh3O9O44h7VFeSlmCZGTrQtfY3r7mIw9PcdzTYv znvTGY6rNQYrUlCsQ5G4fNzMHAnihQc8xvQrevhsUWShUvAHR1YrjDKfwpr/k8sAAAAAAAA= --=-TLkh93lmuNUIf12odsuA--