From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail02.groups.io (mail02.groups.io [66.175.222.108]) by spool.mail.gandi.net (Postfix) with ESMTPS id 97555AC0D03 for ; Fri, 1 Mar 2024 08:38:14 +0000 (UTC) DKIM-Signature: a=rsa-sha256; bh=lafHemn4bQNqIjiqTxfTYCXFUKQC7hAeXrxCfif0lcM=; c=relaxed/simple; d=groups.io; h=MIME-Version:References:In-Reply-To:From:Date:Message-ID:Subject:To:Cc:Precedence:List-Subscribe:List-Help:Sender:List-Id:Mailing-List:Delivered-To:Reply-To:List-Unsubscribe-Post:List-Unsubscribe:Content-Type; s=20140610; t=1709282293; v=1; b=rakAnlqX1Q0HMhXIP3Sy2SUSpxPkXtgsaxIde8QR/6p64HOhwQpXcBegtcbOEtMil+i+ZEa4 0eK4X8ltBol90YrXfDS+G1yTHmIz4iSRPEVg0xjVZxVC5PTFY+sYaJ+uP1nSfkWmgCfNs/M7s1X TwJ8GDdoPxpznNr0kjXPRktI= X-Received: by 127.0.0.2 with SMTP id flq7YY7687511xZT1qGEy8Z0; Fri, 01 Mar 2024 00:38:13 -0800 X-Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by mx.groups.io with SMTP id smtpd.web10.18263.1709282292410063717 for ; Fri, 01 Mar 2024 00:38:12 -0800 X-Received: from mail-ej1-f69.google.com (mail-ej1-f69.google.com [209.85.218.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-641-6_hSOBCjOrGfCUnEaA9GIQ-1; Fri, 01 Mar 2024 03:38:09 -0500 X-MC-Unique: 6_hSOBCjOrGfCUnEaA9GIQ-1 X-Received: by mail-ej1-f69.google.com with SMTP id a640c23a62f3a-a449ac4522cso16102066b.2 for ; Fri, 01 Mar 2024 00:38:09 -0800 (PST) X-Gm-Message-State: VIHA9SCYyvlJjRoPiQJn8OCIx7686176AA= X-Received: by 2002:a17:907:20e3:b0:a44:4c9e:8809 with SMTP id rh3-20020a17090720e300b00a444c9e8809mr778332ejb.32.1709282288559; Fri, 01 Mar 2024 00:38:08 -0800 (PST) X-Google-Smtp-Source: AGHT+IEhB6BhnvZJnb4wa7kLAmTRA4aaYMZKKLGqgP94CImJQo2lH/B6D6ebe45wZJ9BZcrbqJFE0sSUhG7TLIOqtu4= X-Received: by 2002:a17:907:20e3:b0:a44:4c9e:8809 with SMTP id rh3-20020a17090720e300b00a444c9e8809mr778320ejb.32.1709282288210; Fri, 01 Mar 2024 00:38:08 -0800 (PST) MIME-Version: 1.0 References: <20240229130246.3-1-ray.ni@intel.com> <20240229130246.3-3-ray.ni@intel.com> In-Reply-To: From: "Paolo Bonzini" Date: Fri, 1 Mar 2024 09:37:55 +0100 Message-ID: Subject: Re: [edk2-devel] [PATCH 2/2] MdeModulePkg/DxeCore: Fix stack overflow issue due to nested interrupts To: "Ni, Ray" Cc: "devel@edk2.groups.io" , "Kinney, Michael D" , Liming Gao , Laszlo Ersek , Michael Brown X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Precedence: Bulk List-Subscribe: List-Help: Sender: devel@edk2.groups.io List-Id: Mailing-List: list devel@edk2.groups.io; contact devel+owner@edk2.groups.io Reply-To: devel@edk2.groups.io,pbonzini@redhat.com List-Unsubscribe-Post: List-Unsubscribe=One-Click List-Unsubscribe: Content-Type: multipart/mixed; boundary="0000000000009c5b2e0612954bc6" X-GND-Status: LEGIT Authentication-Results: spool.mail.gandi.net; dkim=pass header.d=groups.io header.s=20140610 header.b=rakAnlqX; dmarc=fail reason="SPF not aligned (relaxed), DKIM not aligned (relaxed)" header.from=redhat.com (policy=none); spf=pass (spool.mail.gandi.net: domain of bounce@groups.io designates 66.175.222.108 as permitted sender) smtp.mailfrom=bounce@groups.io --0000000000009c5b2e0612954bc6 Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable On Fri, Mar 1, 2024 at 4:08=E2=80=AFAM Ni, Ray wrote: > @@ -161,5 +191,46 @@ CoreRestoreTpl ( > IN EFI_TPL NewTpl > ) > { > + BOOLEAN InInterruptHandler =3D FALSE; > + > + // > + // Unwind the nested interrupt handlers up to the required > + // TPL, paying attention not to overflow the stack. While > + // not strictly necessary according to the specification, > + // accept the possibility that multiple RaiseTPL calls are > + // undone by a single RestoreTPL > + // > + while ((INTN)NewTpl <=3D HighBitSet64 (mInterruptedTplMask)) { > 1. why "<=3D"? I thought when RestoreTPL() is called there are only two c= ases: > a. NewTpl =3D=3D HighBitSet64 (...) > b. NewTpl > HighBitSet64 (...) > 1.a is the case when TimerInterruptHandler() or CoreTimerTick() restore= s > TPL from HIGH to non-HIGH. > 1.b is the case when the pending event backs call RaiseTPL/RestoreTPL()= . > Because only pending events whose TPL > "Interrupted TPL" can run, the > RestoreTPL() call from the event callbacks cannot change the TPL to a v= alue > less than or equal to "Interrupted TPL". > So, I think "<=3D" can be "=3D=3D". > > 2. can you explain a bit more about the reason of "while"? Both are just for extra safety. The required invariant is that all bits at or below current TPL are cleared, and using "while (... <=3D ...)" makes it more robust to incorrect usage of gBS->RestoreTPL(). Indeed, the patch at the top of thread also uses "(INTN)gEfiCurrentTpl > HighBitSet64 (mInterruptedTplMask)", which is <=3D when you reverse the condition. It then asserts inside the conditional that "=3D=3D" would be enough. So I am starting to see more and more similarities between the two approaches. I went a step further with fresh mind, removing the while loop... and basically reinvented your and Michael's patch. :) The only difference in the logic is a slightly different handling of mInterruptedTplMask in CoreRestoreTpl(), which is a bit safer in my case. However, my roundabout way of getting to the same patch resulted in very different comments. Personally, I found the large text at the head of mInterruptedTplMask a bit too much, and the ones inside the function too focused on "how" and not "why". Maybe it's my exposure to NestedInterruptTplLib, but I find that a much smaller text can achieve the same purpose, by explaining the logic instead of the individual steps. My version is attached, feel free to reuse it (either entirely or partially) for a hypothetical v2. Apologies to you and Mike K for the confusion! > + > + if (InterruptedTpl =3D=3D NewTpl) { > + break; > 3. "break" or "return"? I think we should exit from this function. Indeed, this should have been a return. Paolo -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- Groups.io Links: You receive all messages sent to this group. View/Reply Online (#116224): https://edk2.groups.io/g/devel/message/116224 Mute This Topic: https://groups.io/mt/104642317/7686176 Group Owner: devel+owner@edk2.groups.io Unsubscribe: https://edk2.groups.io/g/devel/unsub [rebecca@openfw.io] -=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D-=3D- --0000000000009c5b2e0612954bc6 Content-Type: text/x-patch; charset="US-ASCII"; name="tpl.patch" Content-Disposition: attachment; filename="tpl.patch" Content-Transfer-Encoding: base64 Content-ID: X-Attachment-Id: f_lt8ecws50 RnJvbSBiOWYwYmMzZWY4M2I0MGMyOWUwOTNhY2RhMWQwNzQxYjhmNTYxMGU1IE1vbiBTZXAgMTcg MDA6MDA6MDAgMjAwMQpGcm9tOiBQYW9sbyBCb256aW5pIDxwYm9uemluaUByZWRoYXQuY29tPgpE YXRlOiBGcmksIDEgTWFyIDIwMjQgMDk6MTE6NDggKzAxMDAKU3ViamVjdDogW1BBVENIXSBNZGVN b2R1bGVQa2c6IGZpeCBzdGFjayBvdmVyZmxvdyBpc3N1ZSBkdWUgdG8gbmVzdGVkCiBpbnRlcnJ1 cHRzCkNvbnRlbnQtVHlwZTogdGV4dC9wbGFpbjsgY2hhcnNldD1VVEYtOAoKVGhpcyBpcyBhIGhl YXZpbHkgc2ltcGxpZmllZCB2ZXJzaW9uIG9mIHRoZSBmaXggaW4gdGhlIE92bWZQa2cKTmVzdGVk SW50ZXJydXB0VHBsTGliLiAgUHV0dGluZyBpdCBpbiBEWEUgY29yZSBhbGxvd3MgQ29yZVJlc3Rv cmVUcGwoKQp0byBsb3dlciB0aGUgVFBMIHdoaWxlIGtlZXBpbmcgaW50ZXJydXB0cyBkaXNhYmxl ZCwgcmVtb3ZpbmcgdGhlIG5lZWQKZm9yIGVpdGhlciBEaXNhYmxlSW50ZXJydXB0c09uSXJldCgp IG9yIHRoZSBjb21wbGV4IGRlZmVycmVkIGV4ZWN1dGlvbgptZWNoYW5pc20uCgpJbnN0ZWFkLCBD b3JlUmFpc2VUcGwoKSB1c2VzIHRoZSBjdXJyZW50IHN0YXRlIG9mIHRoZSBpbnRlcnJ1cHQgZmxh ZyB0bwpzZWNvbmQgZ3Vlc3Mgd2hldGhlciBpdCdzIGJlaW5nIGNhbGxlZCBmcm9tIGFuIGludGVy cnVwdCBoYW5kbGVyOyB3aGVuCnJlc3RvcmluZyB0aGUgb3V0ZXIgVFBMIGF0IHRoZSBlbmQgb2Yg dGhlIGhhbmRsZXIsIGludGVycnVwdHMgcmVtYWluCmRpc2FibGVkIHVudGlsIElSRVQuICBUaGlz IGVsaW1pbmF0ZXMgdGhlIHBvc3NpYmlsaXR5IHRoYXQgYSBuZXN0ZWQKaW52b2NhdGlvbiBvZiB0 aGUgaW50ZXJydXB0IGhhbmRsZXIgaGFzIHRoZSBzYW1lIFRQTCBhcyB0aGUgb3V0ZXIgb25lLgoK U2lnbmVkLW9mZi1ieTogTWljaGFlbCBEIEtpbm5leSA8bWljaGFlbC5kLmtpbm5leUBpbnRlbC5j b20+ClNpZ25lZC1vZmYtYnk6IFJheSBOaSA8cmF5Lm5pQGludGVsLmNvbT4KW1Jld3JvdGUgdGhl IENvcmVSZXN0b3JlVHBsIHBhcnQgYW5kIHRoZSBjb21taXQgbWVzc2FnZS4gLSBQYW9sb10KU2ln bmVkLW9mZi1ieTogUGFvbG8gQm9uemluaSA8cGJvbnppbmlAcmVkaGF0LmNvbT4KLS0tCiBNZGVN b2R1bGVQa2cvQ29yZS9EeGUvRXZlbnQvVHBsLmMgfCA4NSArKysrKysrKysrKysrKysrKysrKysr KysrKy0tLS0tCiAxIGZpbGUgY2hhbmdlZCwgNzIgaW5zZXJ0aW9ucygrKSwgMTMgZGVsZXRpb25z KC0pCgpkaWZmIC0tZ2l0IGEvTWRlTW9kdWxlUGtnL0NvcmUvRHhlL0V2ZW50L1RwbC5jIGIvTWRl TW9kdWxlUGtnL0NvcmUvRHhlL0V2ZW50L1RwbC5jCmluZGV4IGIzM2Y4MDU3M2MuLjBhNGY5OTUy MWMgMTAwNjQ0Ci0tLSBhL01kZU1vZHVsZVBrZy9Db3JlL0R4ZS9FdmVudC9UcGwuYworKysgYi9N ZGVNb2R1bGVQa2cvQ29yZS9EeGUvRXZlbnQvVHBsLmMKQEAgLTksNiArOSwxNiBAQCBTUERYLUxp Y2Vuc2UtSWRlbnRpZmllcjogQlNELTItQ2xhdXNlLVBhdGVudAogI2luY2x1ZGUgIkR4ZU1haW4u aCINCiAjaW5jbHVkZSAiRXZlbnQuaCINCiANCisvLy8NCisvLy8gQml0IG1hc2sgb2YgVFBMcyB0 aGF0IHdlcmUgaW50ZXJydXB0ZWQgKHR5cGljYWxseSBkdXJpbmcgUmVzdG9yZVRQTCdzDQorLy8v IGV2ZW50IGRpc3BhdGNoaW5nLCB0aG91Z2ggdGhlcmUgYXJlIHJlcG9ydHMgdGhhdCB0aGUgV2lu ZG93cyBib290IGxvYWRlcg0KKy8vLyBleGVjdXRlcyBzdHJheSBTVElzIGF0IFRQTF9ISUdIX0xF VkVMKS4gIENvcmVSYWlzZVRwbCgpIHNldHMgdGhlDQorLy8vIE9sZFRwbC10aCBiaXQgd2hlbiBp dCBkZXRlY3RzIGl0IHdhcyBjYWxsZWQgZnJvbSBhbmQgaW50ZXJydXB0IGhhbmRsZXIsDQorLy8v IGJlY2F1c2UgdGhlIGNvcnJlc3BvbmRpbmcgQ29yZVJlc3RvcmVUcGwoKSBuZWVkcyBkaWZmZXJl bnQgc2VtYW50aWNzIGZvcg0KKy8vLyB0aGUgQ1BVIGludGVycnVwdCBzdGF0ZS4gIFNlZSBDb3Jl UmFpc2VUcGwoKSBhbmQgQ29yZVJlc3RvcmVUcGwoKSBiZWxvdy4NCisvLy8NCitzdGF0aWMgVUlO VE4gICBtSW50ZXJydXB0ZWRUcGxNYXNrID0gMDsNCisNCiAvKioNCiAgIFNldCBJbnRlcnJ1cHQg U3RhdGUuDQogDQpAQCAtNTksNiArNjksNyBAQCBDb3JlUmFpc2VUcGwgKAogICApDQogew0KICAg RUZJX1RQTCAgT2xkVHBsOw0KKyAgQk9PTEVBTiAgSW50ZXJydXB0U3RhdGU7DQogDQogICBPbGRU cGwgPSBnRWZpQ3VycmVudFRwbDsNCiAgIGlmIChPbGRUcGwgPiBOZXdUcGwpIHsNCkBAIC03Miw3 ICs4MywzMSBAQCBDb3JlUmFpc2VUcGwgKAogICAvLyBJZiByYWlzaW5nIHRvIGhpZ2ggbGV2ZWws IGRpc2FibGUgaW50ZXJydXB0cw0KICAgLy8NCiAgIGlmICgoTmV3VHBsID49IFRQTF9ISUdIX0xF VkVMKSAmJiAgKE9sZFRwbCA8IFRQTF9ISUdIX0xFVkVMKSkgew0KLSAgICBDb3JlU2V0SW50ZXJy dXB0U3RhdGUgKEZBTFNFKTsNCisgICAgLy8NCisgICAgLy8gV2hlbiBnQ3B1IGlzIE5VTEwsIGFz c3VtZSB3ZSdyZSBub3QgY2FsbGVkIGZyb20gYW4gaW50ZXJydXB0IGhhbmRsZXIuDQorICAgIC8v IENhbGxpbmcgQ29yZVNldEludGVycnVwdFN0YXRlKCkgd2l0aCBUUlVFIGlzIHNhZmUgYXMgQ29y ZVNldEludGVycnVwdFN0YXRlKCkgd2lsbCBkaXJlY3RseSByZXR1cm4NCisgICAgLy8gd2hlbiBn Q3B1IGlzIE5VTEwuDQorICAgIC8vDQorICAgIEludGVycnVwdFN0YXRlID0gVFJVRTsNCisgICAg aWYgKGdDcHUgIT0gTlVMTCkgew0KKyAgICAgIGdDcHUtPkdldEludGVycnVwdFN0YXRlIChnQ3B1 LCAmSW50ZXJydXB0U3RhdGUpOw0KKyAgICB9DQorDQorICAgIGlmIChJbnRlcnJ1cHRTdGF0ZSkg ew0KKyAgICAgIC8vDQorICAgICAgLy8gSW50ZXJydXB0cyBhcmUgY3VycmVudGx5IGVuYWJsZWQu DQorICAgICAgLy8gS2VlcCB0aGVtIGRpc2FibGVkIHdoaWxlIGF0IFRQTF9ISUdIX0xFVkVMLg0K KyAgICAgIC8vDQorICAgICAgQ29yZVNldEludGVycnVwdFN0YXRlIChGQUxTRSk7DQorICAgIH0g ZWxzZSB7DQorICAgICAgLy8NCisgICAgICAvLyBXaXRoaW4gYW4gaW50ZXJydXB0IGhhbmRsZXIu ICBTYXZlIHRoZSBUUEwgdGhhdCB3YXMgaW50ZXJydXB0ZWQ7DQorICAgICAgLy8gSXQgbXVzdCBi ZSBoaWdoZXIgdGhhbiB0aGUgcHJldmlvdXNseSBpbnRlcnJ1cHRlZCBUUEwsIHNpbmNlDQorICAg ICAgLy8gQ29yZVJlc3RvcmVUcGwgcmVzZXQgYWxsIGJpdHMgdXAgdG8gYW5kIGluY2x1ZGluZyB0 aGUgcmVxdWVzdGVkIFRQTC4NCisgICAgICAvLw0KKyAgICAgIEFTU0VSVCAoKElOVE4pT2xkVHBs ID4gSGlnaEJpdFNldDY0IChtSW50ZXJydXB0ZWRUcGxNYXNrKSk7DQorICAgICAgbUludGVycnVw dGVkVHBsTWFzayB8PSAoVUlOVE4pKDEgPDwgT2xkVHBsKTsNCisgICAgfQ0KICAgfQ0KIA0KICAg Ly8NCkBAIC0xMDcsMTEgKzE0Miw2IEBAIENvcmVSZXN0b3JlVHBsICgKIA0KICAgQVNTRVJUIChW QUxJRF9UUEwgKE5ld1RwbCkpOw0KIA0KLSAgLy8NCi0gIC8vIElmIGxvd2VyaW5nIGJlbG93IEhJ R0hfTEVWRUwsIG1ha2Ugc3VyZQ0KLSAgLy8gaW50ZXJydXB0cyBhcmUgZW5hYmxlZA0KLSAgLy8N Ci0NCiAgIGlmICgoT2xkVHBsID49IFRQTF9ISUdIX0xFVkVMKSAmJiAgKE5ld1RwbCA8IFRQTF9I SUdIX0xFVkVMKSkgew0KICAgICBnRWZpQ3VycmVudFRwbCA9IFRQTF9ISUdIX0xFVkVMOw0KICAg fQ0KQEAgLTEyNiw2ICsxNTYsMTMgQEAgQ29yZVJlc3RvcmVUcGwgKAogICAgIH0NCiANCiAgICAg Z0VmaUN1cnJlbnRUcGwgPSBQZW5kaW5nVHBsOw0KKw0KKyAgICAvLw0KKyAgICAvLyBJZiBsb3dl cmluZyBiZWxvdyBUUExfSElHSF9MRVZFTCwgbWFrZSBzdXJlIGludGVycnVwdHMgYXJlDQorICAg IC8vIGVuYWJsZWQgdG8gYXZvaWQgcHJpb3JpdHkgaW52ZXJzaW9ucy4gIE5vdGUgaG93ZXZlciB0 aGF0DQorICAgIC8vIHRoZSBUUEwgcmVtYWlucyBoaWdoZXIgdGhhbiB0aGUgY2FsbGVyJ3MuICBU aGlzIGxpbWl0cyB0aGUNCisgICAgLy8gbnVtYmVyIG9mIG5lc3RlZCBpbnRlcnJ1cHRzIHRoYXQg Y2FuIGhhcHBlbi4KKyAgICAvLw0KICAgICBpZiAoZ0VmaUN1cnJlbnRUcGwgPCBUUExfSElHSF9M RVZFTCkgew0KICAgICAgIENvcmVTZXRJbnRlcnJ1cHRTdGF0ZSAoVFJVRSk7DQogICAgIH0NCkBA IC0xMzQsMTYgKzE3MSw0MyBAQCBDb3JlUmVzdG9yZVRwbCAoCiAgIH0NCiANCiAgIC8vDQotICAv LyBTZXQgdGhlIG5ldyB2YWx1ZQ0KKyAgLy8gVGhlIENQVSBkaXNhYmxlcyBpbnRlcnJ1cHRzIHdo aWxlIGhhbmRsZXJzIHJ1biwgdGhlcmVmb3JlIHRoZQ0KKyAgLy8gaW50ZXJydXB0IGhhbmRsZXIg d2FudHMgdG8gc2V0IFRQTF9ISUdIX0xFVkVMIHdoaWxlIGl0IHJ1bnMsDQorICAvLyBmb3IgY29u c2lzdGVuY3kuICBIb3dldmVyLCB3aGVuIHRoZSBoYW5kbGVyIGNhbGxzIFJlc3RvcmVUUEwNCisg IC8vIGJlZm9yZSByZXR1cm5pbmcsIHdlIHdhbnQgdG8ga2VlcCBpbnRlcnJ1cHRzIGRpc2FibGVk LiAgVGhpcw0KKyAgLy8gcmVzdG9yZXMgdGhlIGV4YWN0IHN0YXRlIGF0IHRoZSBiZWdpbm5pbmcg b2YgdGhlIGhhbmRsZXIsDQorICAvLyBiZWZvcmUgdGhlIGNhbGwgdG8gUmFpc2VUUEwoKTogbG93 IFRQTCBhbmQgaW50ZXJydXB0cyBkaXNhYmxlZC4NCiAgIC8vDQotDQorICAvLyBEaXNhYmxpbmcg aW50ZXJydXB0cyBiZWxvdyBUUExfSElHSF9MRVZFTCBpcyB0ZW1wb3JhcmlseQ0KKyAgLy8gaW5j b25zaXN0ZW50IGJ1dCwgaWYgd2UgZGlkIG5vdCBkbyBzbywgYW5vdGhlciBpbnRlcnJ1cHQNCisg IC8vIGNvdWxkIHRyaWdnZXIgaW4gdGhlIHNtYWxsIHdpbmRvdyBiZXR3ZWVuDQorICAvLyBDb3Jl U2V0SW50ZXJydXB0U3RhdGUgKFRSVUUpIGFuZCB0aGUgSVJFVCBpbnN0cnVjdGlvbi4NCisgIC8v IFRoZSBuZXN0ZWQgaW50ZXJydXB0IHdvdWxkIHN0YXJ0IHdpdGggdGhlIHNhbWUgVFBMIGFzIHRo ZQ0KKyAgLy8gb3V0ZXIgb25lLCBhbmQgbm90aGluZyB3b3VsZCBwcmV2ZW50cyBpbmZpbml0ZSBy ZWN1cnNpb24gYW5kDQorICAvLyBhIHN0YWNrIG92ZXJmbG93Lg0KKyAgLy8NCisgIC8vIEluc3Rl YWQsIGRpc2FibGUgaW50ZXJydXB0cyBzbyB0aGF0IG5lc3RlZCBpbnRlcnJ1cHQgaGFuZGxlcnMN CisgIC8vIHdpbGwgb25seSBmaXJlIGJlZm9yZSBnRWZpQ3VycmVudFRwbCBnZXRzIGl0cyBmaW5h bCB2YWx1ZS4NCisgIC8vIFRoaXMgZW5zdXJlcyB0aGF0IG5lc3RlZCBoYW5kbGVycyBzZWUgYSBU UEwgaGlnaGVyIHRoYW4NCisgIC8vIHRoZSBvdXRlciBoYW5kbGVyLCB0aHVzIGJvdW5kaW5nIHRo ZSBvdmVyYWxsIHN0YWNrIGRlcHRoLg0KKyAgLy8NCisgIENvcmVTZXRJbnRlcnJ1cHRTdGF0ZSAo RkFMU0UpOw0KICAgZ0VmaUN1cnJlbnRUcGwgPSBOZXdUcGw7DQogDQotICAvLw0KLSAgLy8gSWYg bG93ZXJpbmcgYmVsb3cgSElHSF9MRVZFTCwgbWFrZSBzdXJlDQotICAvLyBpbnRlcnJ1cHRzIGFy ZSBlbmFibGVkDQotICAvLw0KLSAgaWYgKGdFZmlDdXJyZW50VHBsIDwgVFBMX0hJR0hfTEVWRUwp IHsNCisgIGlmICgoSU5UTilOZXdUcGwgPD0gSGlnaEJpdFNldDY0IChtSW50ZXJydXB0ZWRUcGxN YXNrKSkgew0KKyAgICAvLw0KKyAgICAvLyBXZSB3ZXJlIGNhbGxlZCBmcm9tIGFuIGludGVycnVw dCBoYW5kbGVyLiAgUmV0dXJuIHdpdGgNCisgICAgLy8gaW50ZXJydXB0cyBkaXNhYmxlZCB0byBl bnN1cmUgdGhhdCB0aGUgc3RhY2sgZG9lcw0KKyAgICAvLyBub3QgYmxvdyB1cC4NCisgICAgLy8N CisgICAgQVNTRVJUIChtSW50ZXJydXB0ZWRUcGxNYXNrICYgKDEgPDwgTmV3VHBsKSk7DQorICAg IEFTU0VSVCAoR2V0SW50ZXJydXB0U3RhdGUgKCkgPT0gRkFMU0UpOw0KKyAgICBtSW50ZXJydXB0 ZWRUcGxNYXNrICY9IChVSU5UTikoMSA8PCBOZXdUcGwpIC0gMTsNCisgIH0gZWxzZSBpZiAoTmV3 VHBsIDwgVFBMX0hJR0hfTEVWRUwpIHsNCisgICAgLy8NCisgICAgLy8gTG93ZXJpbmcgYmVsb3cg VFBMX0hJR0hfTEVWRUwsIG1ha2Ugc3VyZQ0KKyAgICAvLyBpbnRlcnJ1cHRzIGFyZSBlbmFibGVk DQorICAgIC8vDQogICAgIENvcmVTZXRJbnRlcnJ1cHRTdGF0ZSAoVFJVRSk7DQogICB9DQogfQ0K LS0gCjIuNDMuMgoK --0000000000009c5b2e0612954bc6--