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 X-Spam-Level: X-Spam-Status: No, score=-12.0 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 42C8BC43460 for ; Wed, 12 May 2021 14:06:25 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id C933F61418 for ; Wed, 12 May 2021 14:06:24 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org C933F61418 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=amd-gfx-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 5189B6EC03; Wed, 12 May 2021 14:06:22 +0000 (UTC) Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by gabe.freedesktop.org (Postfix) with ESMTPS id EF5466EC01; Wed, 12 May 2021 14:06:20 +0000 (UTC) Received: by mail-ed1-x52e.google.com with SMTP id l7so27269676edb.1; Wed, 12 May 2021 07:06:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding:content-language; bh=D6pHKTcVLI3s2kmC/tuhuU6NBUj7V+KFfP9rb+MWD9M=; b=ZbJHTbndRqixSt9sp8AM3pHQSqH81l5Y6aZTWCdxgrpw/0YgXAEJ6myX8rAR0PBgrZ zMeuDainJ4Yvlfb+6qrbeTANZXlKZCE0vguPRb3pqbJri090cZKE2+p38PHL/R/Qm+OP NIDr/32pYrqgR2//vBZku9Whwe9qmSx3pIRTi5SkoVdQ6hDoTvDX+5DglKTJ5bheR2tx NiWQQk/H+PcXiFnlIfkEhQY9OcM7gjJRvmHkXp9m6vLR+1J9ssZ3vTuon2KBQiuKAgeY YEThKiK/hUY2XqKrX6DkBjyGSis7QW5LZPUT1qFnb+FxC+vtV8wdPHFkSTcm84+83B6V hXdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=D6pHKTcVLI3s2kmC/tuhuU6NBUj7V+KFfP9rb+MWD9M=; b=rnHokIVo9UH6I0hK8WYchUACiWS47BRFwzn61uGa/AlNpy9HJOLsdsHOsaNrIAJICg E8N9j+LdoMPlmBCtz4+d/V3q9BQhDLCiuWaZwgjZtyM4wJYjgvXD8iv3MHJr+R8NeNGK A/wdaHe8bgGGmiVas4GZPygUcQKE/iXcBMxjPYIQ/NmNTSUkYQlPmSFwyLMam4qzXXRP mspkXYd7zSdkq14RqRFOStNHdMeJCn38ke5UK2s4/kp5Sz8mvWfkHv31tX9A7OvX+kD6 DFaPDOJdCE5vvrBx2JU1pAmAnaT00PuQMWO/L24KY291k+B3NLWFILTZIw1Cf53SIBlp OSwg== X-Gm-Message-State: AOAM531qWxJMRJ81Wf3m1xh4243n5qKzCoLztDNkXfIfNJ76s1p2OCo0 AvLtdJmbIPuuuFq5HEP26mY= X-Google-Smtp-Source: ABdhPJxiKsTHipPbWVJ64GPlWD8cpCSwHAT7KOwJVVdh/z6uTMvnrlVGZ9Zt0/rN/JyGFjldy/mqkQ== X-Received: by 2002:a05:6402:51d3:: with SMTP id r19mr43279881edd.360.1620828379389; Wed, 12 May 2021 07:06:19 -0700 (PDT) Received: from ?IPv6:2a02:908:1252:fb60:c533:38e4:26b8:d73? ([2a02:908:1252:fb60:c533:38e4:26b8:d73]) by smtp.gmail.com with ESMTPSA id h9sm17210007ede.93.2021.05.12.07.06.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 12 May 2021 07:06:18 -0700 (PDT) Subject: Re: [PATCH v6 10/16] drm/amdgpu: Guard against write accesses after device removal To: Andrey Grodzovsky , dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, linux-pci@vger.kernel.org, daniel.vetter@ffwll.ch, Harry.Wentland@amd.com References: <20210510163625.407105-1-andrey.grodzovsky@amd.com> <20210510163625.407105-11-andrey.grodzovsky@amd.com> <19ec5ffa-48a7-863d-0b5a-5c2a43d65e81@gmail.com> <8f1bae42-7567-9f7e-d891-8eb92af3e58a@amd.com> From: =?UTF-8?Q?Christian_K=c3=b6nig?= Message-ID: <4bcbc970-eaff-6321-0f6c-c662c53bfc32@gmail.com> Date: Wed, 12 May 2021 16:06:17 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.1 MIME-Version: 1.0 In-Reply-To: <8f1bae42-7567-9f7e-d891-8eb92af3e58a@amd.com> Content-Language: en-US X-BeenThere: amd-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Discussion list for AMD gfx List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander.Deucher@amd.com, gregkh@linuxfoundation.org, ppaalanen@gmail.com, helgaas@kernel.org, Felix.Kuehling@amd.com Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Errors-To: amd-gfx-bounces@lists.freedesktop.org Sender: "amd-gfx" QW0gMTIuMDUuMjEgdW0gMTY6MDEgc2NocmllYiBBbmRyZXkgR3JvZHpvdnNreToKPiBQaW5nIC0g bmVlZCBhIGNvbmZpcm1hdGlvbiBpdCdzIG9rIHRvIGtlZXAgdGhpcyBhcyBhIHNpbmdsZSBwYXRj aCBnaXZlbgo+IG15IGV4cGxhbmF0aW9uIGJlbGxvdy4KCkl0IHdhcyBqdXN0IGFuIHN1Z2dlc3Rp b24uIEtleSBwb2ludCBpcyB0aGUgYXBwcm9hY2ggc291bmRzIHNhbmUgdG8gbWUsIApidXQgSSBj YW4ndCBzYXkgbXVjaCBhYm91dCB0aGUgcHNwIGNvZGUgZm9yIGV4YW1wbGUuCgpTbyBtYXhpbXVt IEkgY2FuIGdpdmUgeW91IGlzIGFuIEFja2VkLWJ5IGZvciB0aGF0LgoKQ2hyaXN0aWFuLgoKPgo+ IEFuZHJleQo+Cj4gT24gMjAyMS0wNS0xMSAxOjUyIHAubS4sIEFuZHJleSBHcm9kem92c2t5IHdy b3RlOgo+Pgo+Pgo+PiBPbiAyMDIxLTA1LTExIDI6NTAgYS5tLiwgQ2hyaXN0aWFuIEvDtm5pZyB3 cm90ZToKPj4+IEFtIDEwLjA1LjIxIHVtIDE4OjM2IHNjaHJpZWIgQW5kcmV5IEdyb2R6b3Zza3k6 Cj4+Pj4gVGhpcyBzaG91bGQgcHJldmVudCB3cml0aW5nIHRvIG1lbW9yeSBvciBJTyByYW5nZXMg cG9zc2libHkKPj4+PiBhbHJlYWR5IGFsbG9jYXRlZCBmb3Igb3RoZXIgdXNlcyBhZnRlciBvdXIg ZGV2aWNlIGlzIHJlbW92ZWQuCj4+Pj4KPj4+PiB2NToKPj4+PiBQcm90ZWN0IG1vcmUgcGxhY2Vz IHdoZXIgbWVtY29weV90by9mb3JtX2lvIHRha2VzIHBsYWNlCj4+Pj4gUHJvdGVjdCBJQiBzdWJt aXNzaW9ucwo+Pj4+Cj4+Pj4gdjY6IFN3aXRjaCB0byAhZHJtX2Rldl9lbnRlciBpbnN0ZWFkIG9m IHNjb3BpbmcgZW50aXJlIGNvZGUKPj4+PiB3aXRoIGJyYWNrZXRzLgo+Pj4+Cj4+Pj4gU2lnbmVk LW9mZi1ieTogQW5kcmV5IEdyb2R6b3Zza3kgPGFuZHJleS5ncm9kem92c2t5QGFtZC5jb20+Cj4+ Pj4gLS0tCj4+Pj4gwqAgZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X2RldmljZS5j wqDCoMKgIHwgMTEgKystCj4+Pj4gwqAgZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1 X2dtYy5jwqDCoMKgwqDCoMKgIHzCoCA5ICsrKwo+Pj4+IMKgIGRyaXZlcnMvZ3B1L2RybS9hbWQv YW1kZ3B1L2FtZGdwdV9pYi5jwqDCoMKgwqDCoMKgwqAgfCAxNyArKystLQo+Pj4+IMKgIGRyaXZl cnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV9wc3AuY8KgwqDCoMKgwqDCoCB8IDYzICsrKysr KysrKysrLS0tLS0tCj4+Pj4gwqAgZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3Bz cC5owqDCoMKgwqDCoMKgIHzCoCAyICsKPj4+PiDCoCBkcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdw dS9hbWRncHVfcmluZy5jwqDCoMKgwqDCoCB8IDcwIAo+Pj4+ICsrKysrKysrKysrKysrKysrKysK Pj4+PiDCoCBkcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfcmluZy5owqDCoMKgwqDC oCB8IDQ5ICsrLS0tLS0tLS0tLS0KPj4+PiDCoCBkcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9h bWRncHVfdXZkLmPCoMKgwqDCoMKgwqAgfCAzMSArKysrKy0tLQo+Pj4+IMKgIGRyaXZlcnMvZ3B1 L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV92Y2UuY8KgwqDCoMKgwqDCoCB8IDExICsrLQo+Pj4+IMKg IGRyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV92Y24uY8KgwqDCoMKgwqDCoCB8IDIy ICsrKystLQo+Pj4+IMKgIGRyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV92bS5jwqDC oMKgwqDCoMKgwqAgfMKgIDcgKy0KPj4+PiDCoCBkcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9w c3BfdjExXzAuY8KgwqDCoMKgwqDCoMKgIHwgNDQgKysrKysrLS0tLS0tCj4+Pj4gwqAgZHJpdmVy cy9ncHUvZHJtL2FtZC9hbWRncHUvcHNwX3YxMl8wLmPCoMKgwqDCoMKgwqDCoCB8wqAgOCArLS0K Pj4+PiDCoCBkcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9wc3BfdjNfMS5jwqDCoMKgwqDCoMKg wqDCoCB8wqAgOCArLS0KPj4+PiDCoCBkcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS92Y2VfdjRf MC5jwqDCoMKgwqDCoMKgwqDCoCB8IDI2ICsrKystLS0KPj4+PiDCoCBkcml2ZXJzL2dwdS9kcm0v YW1kL2FtZGdwdS92Y25fdjNfMC5jwqDCoMKgwqDCoMKgwqDCoCB8IDIyICsrKy0tLQo+Pj4+IMKg IC4uLi9kcm0vYW1kL3BtL3Bvd2VycGxheS9zbXVtZ3Ivc211N19zbXVtZ3IuYyB8wqAgMiArCj4+ Pj4gwqAgMTcgZmlsZXMgY2hhbmdlZCwgMjU3IGluc2VydGlvbnMoKyksIDE0NSBkZWxldGlvbnMo LSkKPj4+Pgo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRn cHVfZGV2aWNlLmMgCj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfZGV2 aWNlLmMKPj4+PiBpbmRleCBhMGJmZjQ3MTM2NzIuLjk0YzQxNTE3NmNkYyAxMDA2NDQKPj4+PiAt LS0gYS9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfZGV2aWNlLmMKPj4+PiArKysg Yi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfZGV2aWNlLmMKPj4+PiBAQCAtNzEs NiArNzEsOCBAQAo+Pj4+IMKgICNpbmNsdWRlIDxkcm0vdGFza19iYXJyaWVyLmg+Cj4+Pj4gwqAg I2luY2x1ZGUgPGxpbnV4L3BtX3J1bnRpbWUuaD4KPj4+PiArI2luY2x1ZGUgPGRybS9kcm1fZHJ2 Lmg+Cj4+Pj4gKwo+Pj4+IMKgIE1PRFVMRV9GSVJNV0FSRSgiYW1kZ3B1L3ZlZ2ExMF9ncHVfaW5m by5iaW4iKTsKPj4+PiDCoCBNT0RVTEVfRklSTVdBUkUoImFtZGdwdS92ZWdhMTJfZ3B1X2luZm8u YmluIik7Cj4+Pj4gwqAgTU9EVUxFX0ZJUk1XQVJFKCJhbWRncHUvcmF2ZW5fZ3B1X2luZm8uYmlu Iik7Cj4+Pj4gQEAgLTI4MSw3ICsyODMsMTAgQEAgdm9pZCBhbWRncHVfZGV2aWNlX3ZyYW1fYWNj ZXNzKHN0cnVjdCAKPj4+PiBhbWRncHVfZGV2aWNlICphZGV2LCBsb2ZmX3QgcG9zLAo+Pj4+IMKg wqDCoMKgwqAgdW5zaWduZWQgbG9uZyBmbGFnczsKPj4+PiDCoMKgwqDCoMKgIHVpbnQzMl90IGhp ID0gfjA7Cj4+Pj4gwqDCoMKgwqDCoCB1aW50NjRfdCBsYXN0Owo+Pj4+ICvCoMKgwqAgaW50IGlk eDsKPj4+PiArwqDCoMKgwqAgaWYgKCFkcm1fZGV2X2VudGVyKCZhZGV2LT5kZGV2LCAmaWR4KSkK Pj4+PiArwqDCoMKgwqDCoMKgwqDCoCByZXR1cm47Cj4+Pj4gwqAgI2lmZGVmIENPTkZJR182NEJJ VAo+Pj4+IMKgwqDCoMKgwqAgbGFzdCA9IG1pbihwb3MgKyBzaXplLCBhZGV2LT5nbWMudmlzaWJs ZV92cmFtX3NpemUpOwo+Pj4+IEBAIC0yOTksOCArMzA0LDEwIEBAIHZvaWQgYW1kZ3B1X2Rldmlj ZV92cmFtX2FjY2VzcyhzdHJ1Y3QgCj4+Pj4gYW1kZ3B1X2RldmljZSAqYWRldiwgbG9mZl90IHBv cywKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBtZW1jcHlfZnJvbWlvKGJ1ZiwgYWRk ciwgY291bnQpOwo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4+Pj4gLcKgwqDCoMKgwqDCoMKg IGlmIChjb3VudCA9PSBzaXplKQo+Pj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAoY291bnQgPT0gc2l6 ZSkgewo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGRybV9kZXZfZXhpdChpZHgpOwo+Pj4+ IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybjsKPj4+PiArwqDCoMKgwqDCoMKgwqAg fQo+Pj4KPj4+IE1heWJlIHVzZSBhIGdvdG8gaW5zdGVhZCwgYnV0IHJlYWxseSBqdXN0IGEgbml0 IHBpY2suCj4+Pgo+Pj4KPj4+Cj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIHBvcyArPSBjb3VudDsK Pj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgYnVmICs9IGNvdW50IC8gNDsKPj4+PiBAQCAtMzIzLDYg KzMzMCw4IEBAIHZvaWQgYW1kZ3B1X2RldmljZV92cmFtX2FjY2VzcyhzdHJ1Y3QgCj4+Pj4gYW1k Z3B1X2RldmljZSAqYWRldiwgbG9mZl90IHBvcywKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCAqYnVmKysgPSBSUkVHMzJfTk9fS0lRKG1tTU1fREFUQSk7Cj4+Pj4gwqDCoMKgwqDCoCB9 Cj4+Pj4gwqDCoMKgwqDCoCBzcGluX3VubG9ja19pcnFyZXN0b3JlKCZhZGV2LT5tbWlvX2lkeF9s b2NrLCBmbGFncyk7Cj4+Pj4gKwo+Pj4+ICvCoMKgwqAgZHJtX2Rldl9leGl0KGlkeCk7Cj4+Pj4g wqAgfQo+Pj4+IMKgIC8qCj4+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1k Z3B1L2FtZGdwdV9nbWMuYyAKPj4+PiBiL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdw dV9nbWMuYwo+Pj4+IGluZGV4IDRkMzIyMzNjZGU5Mi4uMDRiYTVlZWYxZTg4IDEwMDY0NAo+Pj4+ IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV9nbWMuYwo+Pj4+ICsrKyBi L2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV9nbWMuYwo+Pj4+IEBAIC0zMSw2ICsz MSw4IEBACj4+Pj4gwqAgI2luY2x1ZGUgImFtZGdwdV9yYXMuaCIKPj4+PiDCoCAjaW5jbHVkZSAi YW1kZ3B1X3hnbWkuaCIKPj4+PiArI2luY2x1ZGUgPGRybS9kcm1fZHJ2Lmg+Cj4+Pj4gKwo+Pj4+ IMKgIC8qKgo+Pj4+IMKgwqAgKiBhbWRncHVfZ21jX3BkYjBfYWxsb2MgLSBhbGxvY2F0ZSB2cmFt IGZvciBwZGIwCj4+Pj4gwqDCoCAqCj4+Pj4gQEAgLTE1MSw2ICsxNTMsMTAgQEAgaW50IGFtZGdw dV9nbWNfc2V0X3B0ZV9wZGUoc3RydWN0IAo+Pj4+IGFtZGdwdV9kZXZpY2UgKmFkZXYsIHZvaWQg KmNwdV9wdF9hZGRyLAo+Pj4+IMKgIHsKPj4+PiDCoMKgwqDCoMKgIHZvaWQgX19pb21lbSAqcHRy ID0gKHZvaWQgKiljcHVfcHRfYWRkcjsKPj4+PiDCoMKgwqDCoMKgIHVpbnQ2NF90IHZhbHVlOwo+ Pj4+ICvCoMKgwqAgaW50IGlkeDsKPj4+PiArCj4+Pj4gK8KgwqDCoCBpZiAoIWRybV9kZXZfZW50 ZXIoJmFkZXYtPmRkZXYsICZpZHgpKQo+Pj4+ICvCoMKgwqDCoMKgwqDCoCByZXR1cm4gMDsKPj4+ PiDCoMKgwqDCoMKgIC8qCj4+Pj4gwqDCoMKgwqDCoMKgICogVGhlIGZvbGxvd2luZyBpcyBmb3Ig UFRFIG9ubHkuIEdBUlQgZG9lcyBub3QgaGF2ZSBQREVzLgo+Pj4+IEBAIC0xNTgsNiArMTY0LDkg QEAgaW50IGFtZGdwdV9nbWNfc2V0X3B0ZV9wZGUoc3RydWN0IGFtZGdwdV9kZXZpY2UgCj4+Pj4g KmFkZXYsIHZvaWQgKmNwdV9wdF9hZGRyLAo+Pj4+IMKgwqDCoMKgwqAgdmFsdWUgPSBhZGRyICYg MHgwMDAwRkZGRkZGRkZGMDAwVUxMOwo+Pj4+IMKgwqDCoMKgwqAgdmFsdWUgfD0gZmxhZ3M7Cj4+ Pj4gwqDCoMKgwqDCoCB3cml0ZXEodmFsdWUsIHB0ciArIChncHVfcGFnZV9pZHggKiA4KSk7Cj4+ Pj4gKwo+Pj4+ICvCoMKgwqAgZHJtX2Rldl9leGl0KGlkeCk7Cj4+Pj4gKwo+Pj4+IMKgwqDCoMKg wqAgcmV0dXJuIDA7Cj4+Pj4gwqAgfQo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0v YW1kL2FtZGdwdS9hbWRncHVfaWIuYyAKPj4+PiBiL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1 L2FtZGdwdV9pYi5jCj4+Pj4gaW5kZXggMTQ4YTNiNDgxYjEyLi42MmZjYmQ0NDZjNzEgMTAwNjQ0 Cj4+Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X2liLmMKPj4+PiAr KysgYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfaWIuYwo+Pj4+IEBAIC0zMCw2 ICszMCw3IEBACj4+Pj4gwqAgI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KPj4+PiDCoCAjaW5jbHVk ZSA8ZHJtL2FtZGdwdV9kcm0uaD4KPj4+PiArI2luY2x1ZGUgPGRybS9kcm1fZHJ2Lmg+Cj4+Pj4g wqAgI2luY2x1ZGUgImFtZGdwdS5oIgo+Pj4+IMKgICNpbmNsdWRlICJhdG9tLmgiCj4+Pj4gQEAg LTEzNyw3ICsxMzgsNyBAQCBpbnQgYW1kZ3B1X2liX3NjaGVkdWxlKHN0cnVjdCBhbWRncHVfcmlu ZyAKPj4+PiAqcmluZywgdW5zaWduZWQgbnVtX2licywKPj4+PiDCoMKgwqDCoMKgIGJvb2wgc2Vj dXJlOwo+Pj4+IMKgwqDCoMKgwqAgdW5zaWduZWQgaTsKPj4+PiAtwqDCoMKgIGludCByID0gMDsK Pj4+PiArwqDCoMKgIGludCBpZHgsIHIgPSAwOwo+Pj4+IMKgwqDCoMKgwqAgYm9vbCBuZWVkX3Bp cGVfc3luYyA9IGZhbHNlOwo+Pj4+IMKgwqDCoMKgwqAgaWYgKG51bV9pYnMgPT0gMCkKPj4+PiBA QCAtMTY5LDEzICsxNzAsMTYgQEAgaW50IGFtZGdwdV9pYl9zY2hlZHVsZShzdHJ1Y3QgYW1kZ3B1 X3JpbmcgCj4+Pj4gKnJpbmcsIHVuc2lnbmVkIG51bV9pYnMsCj4+Pj4gwqDCoMKgwqDCoMKgwqDC oMKgIHJldHVybiAtRUlOVkFMOwo+Pj4+IMKgwqDCoMKgwqAgfQo+Pj4+ICvCoMKgwqAgaWYgKCFk cm1fZGV2X2VudGVyKCZhZGV2LT5kZGV2LCAmaWR4KSkKPj4+PiArwqDCoMKgwqDCoMKgwqAgcmV0 dXJuIC1FTk9ERVY7Cj4+Pj4gKwo+Pj4+IMKgwqDCoMKgwqAgYWxsb2Nfc2l6ZSA9IHJpbmctPmZ1 bmNzLT5lbWl0X2ZyYW1lX3NpemUgKyBudW1faWJzICoKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAg cmluZy0+ZnVuY3MtPmVtaXRfaWJfc2l6ZTsKPj4+PiDCoMKgwqDCoMKgIHIgPSBhbWRncHVfcmlu Z19hbGxvYyhyaW5nLCBhbGxvY19zaXplKTsKPj4+PiDCoMKgwqDCoMKgIGlmIChyKSB7Cj4+Pj4g wqDCoMKgwqDCoMKgwqDCoMKgIGRldl9lcnIoYWRldi0+ZGV2LCAic2NoZWR1bGluZyBJQiBmYWls ZWQgKCVkKS5cbiIsIHIpOwo+Pj4+IC3CoMKgwqDCoMKgwqDCoCByZXR1cm4gcjsKPj4+PiArwqDC oMKgwqDCoMKgwqAgZ290byBleGl0Owo+Pj4+IMKgwqDCoMKgwqAgfQo+Pj4+IMKgwqDCoMKgwqAg bmVlZF9jdHhfc3dpdGNoID0gcmluZy0+Y3VycmVudF9jdHggIT0gZmVuY2VfY3R4Owo+Pj4+IEBA IC0yMDUsNyArMjA5LDcgQEAgaW50IGFtZGdwdV9pYl9zY2hlZHVsZShzdHJ1Y3QgYW1kZ3B1X3Jp bmcgCj4+Pj4gKnJpbmcsIHVuc2lnbmVkIG51bV9pYnMsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKg IHIgPSBhbWRncHVfdm1fZmx1c2gocmluZywgam9iLCBuZWVkX3BpcGVfc3luYyk7Cj4+Pj4gwqDC oMKgwqDCoMKgwqDCoMKgIGlmIChyKSB7Cj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg YW1kZ3B1X3JpbmdfdW5kbyhyaW5nKTsKPj4+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1 cm4gcjsKPj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBnb3RvIGV4aXQ7Cj4+Pj4gwqDCoMKg wqDCoMKgwqDCoMKgIH0KPj4+PiDCoMKgwqDCoMKgIH0KPj4+PiBAQCAtMjg2LDcgKzI5MCw3IEBA IGludCBhbWRncHVfaWJfc2NoZWR1bGUoc3RydWN0IGFtZGdwdV9yaW5nIAo+Pj4+ICpyaW5nLCB1 bnNpZ25lZCBudW1faWJzLAo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBpZiAoam9iICYmIGpvYi0+ dm1pZCkKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhbWRncHVfdm1pZF9yZXNldChh ZGV2LCByaW5nLT5mdW5jcy0+dm1odWIsIGpvYi0+dm1pZCk7Cj4+Pj4gwqDCoMKgwqDCoMKgwqDC oMKgIGFtZGdwdV9yaW5nX3VuZG8ocmluZyk7Cj4+Pj4gLcKgwqDCoMKgwqDCoMKgIHJldHVybiBy Owo+Pj4+ICvCoMKgwqDCoMKgwqDCoCBnb3RvIGV4aXQ7Cj4+Pj4gwqDCoMKgwqDCoCB9Cj4+Pj4g wqDCoMKgwqDCoCBpZiAocmluZy0+ZnVuY3MtPmluc2VydF9lbmQpCj4+Pj4gQEAgLTMwNCw3ICsz MDgsMTAgQEAgaW50IGFtZGdwdV9pYl9zY2hlZHVsZShzdHJ1Y3QgYW1kZ3B1X3JpbmcgCj4+Pj4g KnJpbmcsIHVuc2lnbmVkIG51bV9pYnMsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIHJpbmctPmZ1 bmNzLT5lbWl0X3dhdmVfbGltaXQocmluZywgZmFsc2UpOwo+Pj4+IMKgwqDCoMKgwqAgYW1kZ3B1 X3JpbmdfY29tbWl0KHJpbmcpOwo+Pj4+IC3CoMKgwqAgcmV0dXJuIDA7Cj4+Pj4gKwo+Pj4+ICtl eGl0Ogo+Pj4+ICvCoMKgwqAgZHJtX2Rldl9leGl0KGlkeCk7Cj4+Pj4gK8KgwqDCoCByZXR1cm4g cjsKPj4+PiDCoCB9Cj4+Pj4gwqAgLyoqCj4+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2Ry bS9hbWQvYW1kZ3B1L2FtZGdwdV9wc3AuYyAKPj4+PiBiL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1k Z3B1L2FtZGdwdV9wc3AuYwo+Pj4+IGluZGV4IDllNzY5Y2Y2MDk1Yi4uYmI2YWZlZTYxNjY2IDEw MDY0NAo+Pj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV9wc3AuYwo+ Pj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV9wc3AuYwo+Pj4+IEBA IC0yNSw2ICsyNSw3IEBACj4+Pj4gwqAgI2luY2x1ZGUgPGxpbnV4L2Zpcm13YXJlLmg+Cj4+Pj4g wqAgI2luY2x1ZGUgPGxpbnV4L2RtYS1tYXBwaW5nLmg+Cj4+Pj4gKyNpbmNsdWRlIDxkcm0vZHJt X2Rydi5oPgo+Pj4+IMKgICNpbmNsdWRlICJhbWRncHUuaCIKPj4+PiDCoCAjaW5jbHVkZSAiYW1k Z3B1X3BzcC5oIgo+Pj4+IEBAIC0zOSw2ICs0MCw4IEBACj4+Pj4gwqAgI2luY2x1ZGUgImFtZGdw dV9yYXMuaCIKPj4+PiDCoCAjaW5jbHVkZSAiYW1kZ3B1X3NlY3VyZWRpc3BsYXkuaCIKPj4+PiAr I2luY2x1ZGUgPGRybS9kcm1fZHJ2Lmg+Cj4+Pj4gKwo+Pj4+IMKgIHN0YXRpYyBpbnQgcHNwX3N5 c2ZzX2luaXQoc3RydWN0IGFtZGdwdV9kZXZpY2UgKmFkZXYpOwo+Pj4+IMKgIHN0YXRpYyB2b2lk IHBzcF9zeXNmc19maW5pKHN0cnVjdCBhbWRncHVfZGV2aWNlICphZGV2KTsKPj4+PiBAQCAtMjUz LDcgKzI1Niw3IEBAIHBzcF9jbWRfc3VibWl0X2J1ZihzdHJ1Y3QgcHNwX2NvbnRleHQgKnBzcCwK Pj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgc3RydWN0IHBzcF9nZnhfY21kX3Jlc3AgKmNt ZCwgdWludDY0X3QgZmVuY2VfbWNfYWRkcikKPj4+PiDCoCB7Cj4+Pj4gwqDCoMKgwqDCoCBpbnQg cmV0Owo+Pj4+IC3CoMKgwqAgaW50IGluZGV4Owo+Pj4+ICvCoMKgwqAgaW50IGluZGV4LCBpZHg7 Cj4+Pj4gwqDCoMKgwqDCoCBpbnQgdGltZW91dCA9IDIwMDAwOwo+Pj4+IMKgwqDCoMKgwqAgYm9v bCByYXNfaW50ciA9IGZhbHNlOwo+Pj4+IMKgwqDCoMKgwqAgYm9vbCBza2lwX3Vuc3VwcG9ydCA9 IGZhbHNlOwo+Pj4+IEBAIC0yNjEsNiArMjY0LDkgQEAgcHNwX2NtZF9zdWJtaXRfYnVmKHN0cnVj dCBwc3BfY29udGV4dCAqcHNwLAo+Pj4+IMKgwqDCoMKgwqAgaWYgKHBzcC0+YWRldi0+aW5fcGNp X2Vycl9yZWNvdmVyeSkKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIDA7Cj4+Pj4gK8Kg wqDCoCBpZiAoIWRybV9kZXZfZW50ZXIoJnBzcC0+YWRldi0+ZGRldiwgJmlkeCkpCj4+Pj4gK8Kg wqDCoMKgwqDCoMKgIHJldHVybiAwOwo+Pj4+ICsKPj4+PiDCoMKgwqDCoMKgIG11dGV4X2xvY2so JnBzcC0+bXV0ZXgpOwo+Pj4+IMKgwqDCoMKgwqAgbWVtc2V0KHBzcC0+Y21kX2J1Zl9tZW0sIDAs IFBTUF9DTURfQlVGRkVSX1NJWkUpOwo+Pj4+IEBAIC0yNzEsOCArMjc3LDcgQEAgcHNwX2NtZF9z dWJtaXRfYnVmKHN0cnVjdCBwc3BfY29udGV4dCAqcHNwLAo+Pj4+IMKgwqDCoMKgwqAgcmV0ID0g cHNwX3JpbmdfY21kX3N1Ym1pdChwc3AsIHBzcC0+Y21kX2J1Zl9tY19hZGRyLCAKPj4+PiBmZW5j ZV9tY19hZGRyLCBpbmRleCk7Cj4+Pj4gwqDCoMKgwqDCoCBpZiAocmV0KSB7Cj4+Pj4gwqDCoMKg wqDCoMKgwqDCoMKgIGF0b21pY19kZWMoJnBzcC0+ZmVuY2VfdmFsdWUpOwo+Pj4+IC3CoMKgwqDC oMKgwqDCoCBtdXRleF91bmxvY2soJnBzcC0+bXV0ZXgpOwo+Pj4+IC3CoMKgwqDCoMKgwqDCoCBy ZXR1cm4gcmV0Owo+Pj4+ICvCoMKgwqDCoMKgwqDCoCBnb3RvIGV4aXQ7Cj4+Pj4gwqDCoMKgwqDC oCB9Cj4+Pj4gwqDCoMKgwqDCoCBhbWRncHVfYXNpY19pbnZhbGlkYXRlX2hkcChwc3AtPmFkZXYs IE5VTEwpOwo+Pj4+IEBAIC0zMTIsOCArMzE3LDggQEAgcHNwX2NtZF9zdWJtaXRfYnVmKHN0cnVj dCBwc3BfY29udGV4dCAqcHNwLAo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcHNw LT5jbWRfYnVmX21lbS0+Y21kX2lkLAo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg cHNwLT5jbWRfYnVmX21lbS0+cmVzcC5zdGF0dXMpOwo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBp ZiAoIXRpbWVvdXQpIHsKPj4+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBtdXRleF91bmxvY2so JnBzcC0+bXV0ZXgpOwo+Pj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiAtRUlOVkFM Owo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldCA9IC1FSU5WQUw7Cj4+Pj4gK8KgwqDC oMKgwqDCoMKgwqDCoMKgwqAgZ290byBleGl0Owo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4+ Pj4gwqDCoMKgwqDCoCB9Cj4+Pj4gQEAgLTMyMSw4ICszMjYsMTAgQEAgcHNwX2NtZF9zdWJtaXRf YnVmKHN0cnVjdCBwc3BfY29udGV4dCAqcHNwLAo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB1Y29k ZS0+dG1yX21jX2FkZHJfbG8gPSBwc3AtPmNtZF9idWZfbWVtLT5yZXNwLmZ3X2FkZHJfbG87Cj4+ Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIHVjb2RlLT50bXJfbWNfYWRkcl9oaSA9IHBzcC0+Y21kX2J1 Zl9tZW0tPnJlc3AuZndfYWRkcl9oaTsKPj4+PiDCoMKgwqDCoMKgIH0KPj4+PiAtwqDCoMKgIG11 dGV4X3VubG9jaygmcHNwLT5tdXRleCk7Cj4+Pj4gK2V4aXQ6Cj4+Pj4gK8KgwqDCoCBtdXRleF91 bmxvY2soJnBzcC0+bXV0ZXgpOwo+Pj4+ICvCoMKgwqAgZHJtX2Rldl9leGl0KGlkeCk7Cj4+Pj4g wqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+Pj4+IMKgIH0KPj4+PiBAQCAtMzU5LDggKzM2Niw3IEBA IHN0YXRpYyBpbnQgcHNwX2xvYWRfdG9jKHN0cnVjdCBwc3BfY29udGV4dCAqcHNwLAo+Pj4+IMKg wqDCoMKgwqAgaWYgKCFjbWQpCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiAtRU5PTUVN Owo+Pj4+IMKgwqDCoMKgwqAgLyogQ29weSB0b2MgdG8gcHNwIGZpcm13YXJlIHByaXZhdGUgYnVm ZmVyICovCj4+Pj4gLcKgwqDCoCBtZW1zZXQocHNwLT5md19wcmlfYnVmLCAwLCBQU1BfMV9NRUcp Owo+Pj4+IC3CoMKgwqAgbWVtY3B5KHBzcC0+ZndfcHJpX2J1ZiwgcHNwLT50b2Nfc3RhcnRfYWRk ciwgcHNwLT50b2NfYmluX3NpemUpOwo+Pj4+ICvCoMKgwqAgcHNwX2NvcHlfZncocHNwLCBwc3At PnRvY19zdGFydF9hZGRyLCBwc3AtPnRvY19iaW5fc2l6ZSk7Cj4+Pj4gwqDCoMKgwqDCoCBwc3Bf cHJlcF9sb2FkX3RvY19jbWRfYnVmKGNtZCwgcHNwLT5md19wcmlfbWNfYWRkciwgCj4+Pj4gcHNw LT50b2NfYmluX3NpemUpOwo+Pj4+IEBAIC02MjUsOCArNjMxLDcgQEAgc3RhdGljIGludCBwc3Bf YXNkX2xvYWQoc3RydWN0IHBzcF9jb250ZXh0ICpwc3ApCj4+Pj4gwqDCoMKgwqDCoCBpZiAoIWNt ZCkKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9NRU07Cj4+Pj4gLcKgwqDCoCBt ZW1zZXQocHNwLT5md19wcmlfYnVmLCAwLCBQU1BfMV9NRUcpOwo+Pj4+IC3CoMKgwqAgbWVtY3B5 KHBzcC0+ZndfcHJpX2J1ZiwgcHNwLT5hc2Rfc3RhcnRfYWRkciwgCj4+Pj4gcHNwLT5hc2RfdWNv ZGVfc2l6ZSk7Cj4+Pj4gK8KgwqDCoCBwc3BfY29weV9mdyhwc3AsIHBzcC0+YXNkX3N0YXJ0X2Fk ZHIsIHBzcC0+YXNkX3Vjb2RlX3NpemUpOwo+Pj4+IMKgwqDCoMKgwqAgcHNwX3ByZXBfYXNkX2xv YWRfY21kX2J1ZihjbWQsIHBzcC0+ZndfcHJpX21jX2FkZHIsCj4+Pj4gwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcHNwLT5hc2RfdWNvZGVfc2l6ZSk7Cj4+Pj4gQEAgLTc4 MSw4ICs3ODYsNyBAQCBzdGF0aWMgaW50IHBzcF94Z21pX2xvYWQoc3RydWN0IHBzcF9jb250ZXh0 ICpwc3ApCj4+Pj4gwqDCoMKgwqDCoCBpZiAoIWNtZCkKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAg cmV0dXJuIC1FTk9NRU07Cj4+Pj4gLcKgwqDCoCBtZW1zZXQocHNwLT5md19wcmlfYnVmLCAwLCBQ U1BfMV9NRUcpOwo+Pj4+IC3CoMKgwqAgbWVtY3B5KHBzcC0+ZndfcHJpX2J1ZiwgcHNwLT50YV94 Z21pX3N0YXJ0X2FkZHIsIAo+Pj4+IHBzcC0+dGFfeGdtaV91Y29kZV9zaXplKTsKPj4+PiArwqDC oMKgIHBzcF9jb3B5X2Z3KHBzcCwgcHNwLT50YV94Z21pX3N0YXJ0X2FkZHIsIAo+Pj4+IHBzcC0+ dGFfeGdtaV91Y29kZV9zaXplKTsKPj4+PiDCoMKgwqDCoMKgIHBzcF9wcmVwX3RhX2xvYWRfY21k X2J1ZihjbWQsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHBzcC0+ ZndfcHJpX21jX2FkZHIsCj4+Pj4gQEAgLTEwMzgsOCArMTA0Miw3IEBAIHN0YXRpYyBpbnQgcHNw X3Jhc19sb2FkKHN0cnVjdCBwc3BfY29udGV4dCAqcHNwKQo+Pj4+IMKgwqDCoMKgwqAgaWYgKCFj bWQpCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiAtRU5PTUVNOwo+Pj4+IC3CoMKgwqAg bWVtc2V0KHBzcC0+ZndfcHJpX2J1ZiwgMCwgUFNQXzFfTUVHKTsKPj4+PiAtwqDCoMKgIG1lbWNw eShwc3AtPmZ3X3ByaV9idWYsIHBzcC0+dGFfcmFzX3N0YXJ0X2FkZHIsIAo+Pj4+IHBzcC0+dGFf cmFzX3Vjb2RlX3NpemUpOwo+Pj4+ICvCoMKgwqAgcHNwX2NvcHlfZncocHNwLCBwc3AtPnRhX3Jh c19zdGFydF9hZGRyLCBwc3AtPnRhX3Jhc191Y29kZV9zaXplKTsKPj4+PiDCoMKgwqDCoMKgIHBz cF9wcmVwX3RhX2xvYWRfY21kX2J1ZihjbWQsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIHBzcC0+ZndfcHJpX21jX2FkZHIsCj4+Pj4gQEAgLTEyNzUsOCArMTI3OCw3 IEBAIHN0YXRpYyBpbnQgcHNwX2hkY3BfbG9hZChzdHJ1Y3QgcHNwX2NvbnRleHQgCj4+Pj4gKnBz cCkKPj4+PiDCoMKgwqDCoMKgIGlmICghY21kKQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1 cm4gLUVOT01FTTsKPj4+PiAtwqDCoMKgIG1lbXNldChwc3AtPmZ3X3ByaV9idWYsIDAsIFBTUF8x X01FRyk7Cj4+Pj4gLcKgwqDCoCBtZW1jcHkocHNwLT5md19wcmlfYnVmLCBwc3AtPnRhX2hkY3Bf c3RhcnRfYWRkciwKPj4+PiArwqDCoMKgIHBzcF9jb3B5X2Z3KHBzcCwgcHNwLT50YV9oZGNwX3N0 YXJ0X2FkZHIsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHBzcC0+dGFfaGRjcF91Y29k ZV9zaXplKTsKPj4+PiDCoMKgwqDCoMKgIHBzcF9wcmVwX3RhX2xvYWRfY21kX2J1ZihjbWQsCj4+ Pj4gQEAgLTE0MjcsOCArMTQyOSw3IEBAIHN0YXRpYyBpbnQgcHNwX2R0bV9sb2FkKHN0cnVjdCBw c3BfY29udGV4dCAqcHNwKQo+Pj4+IMKgwqDCoMKgwqAgaWYgKCFjbWQpCj4+Pj4gwqDCoMKgwqDC oMKgwqDCoMKgIHJldHVybiAtRU5PTUVNOwo+Pj4+IC3CoMKgwqAgbWVtc2V0KHBzcC0+ZndfcHJp X2J1ZiwgMCwgUFNQXzFfTUVHKTsKPj4+PiAtwqDCoMKgIG1lbWNweShwc3AtPmZ3X3ByaV9idWYs IHBzcC0+dGFfZHRtX3N0YXJ0X2FkZHIsIAo+Pj4+IHBzcC0+dGFfZHRtX3Vjb2RlX3NpemUpOwo+ Pj4+ICvCoMKgwqAgcHNwX2NvcHlfZncocHNwLCBwc3AtPnRhX2R0bV9zdGFydF9hZGRyLCBwc3At PnRhX2R0bV91Y29kZV9zaXplKTsKPj4+PiDCoMKgwqDCoMKgIHBzcF9wcmVwX3RhX2xvYWRfY21k X2J1ZihjbWQsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHBzcC0+ ZndfcHJpX21jX2FkZHIsCj4+Pj4gQEAgLTE1NzMsOCArMTU3NCw3IEBAIHN0YXRpYyBpbnQgcHNw X3JhcF9sb2FkKHN0cnVjdCBwc3BfY29udGV4dCAqcHNwKQo+Pj4+IMKgwqDCoMKgwqAgaWYgKCFj bWQpCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiAtRU5PTUVNOwo+Pj4+IC3CoMKgwqAg bWVtc2V0KHBzcC0+ZndfcHJpX2J1ZiwgMCwgUFNQXzFfTUVHKTsKPj4+PiAtwqDCoMKgIG1lbWNw eShwc3AtPmZ3X3ByaV9idWYsIHBzcC0+dGFfcmFwX3N0YXJ0X2FkZHIsIAo+Pj4+IHBzcC0+dGFf cmFwX3Vjb2RlX3NpemUpOwo+Pj4+ICvCoMKgwqAgcHNwX2NvcHlfZncocHNwLCBwc3AtPnRhX3Jh cF9zdGFydF9hZGRyLCBwc3AtPnRhX3JhcF91Y29kZV9zaXplKTsKPj4+PiDCoMKgwqDCoMKgIHBz cF9wcmVwX3RhX2xvYWRfY21kX2J1ZihjbWQsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIHBzcC0+ZndfcHJpX21jX2FkZHIsCj4+Pj4gQEAgLTMwMjIsNyArMzAyMiw3 IEBAIHN0YXRpYyBzc2l6ZV90IAo+Pj4+IHBzcF91c2JjX3BkX2Z3X3N5c2ZzX3dyaXRlKHN0cnVj dCBkZXZpY2UgKmRldiwKPj4+PiDCoMKgwqDCoMKgIHN0cnVjdCBhbWRncHVfZGV2aWNlICphZGV2 ID0gZHJtX3RvX2FkZXYoZGRldik7Cj4+Pj4gwqDCoMKgwqDCoCB2b2lkICpjcHVfYWRkcjsKPj4+ PiDCoMKgwqDCoMKgIGRtYV9hZGRyX3QgZG1hX2FkZHI7Cj4+Pj4gLcKgwqDCoCBpbnQgcmV0Owo+ Pj4+ICvCoMKgwqAgaW50IHJldCwgaWR4Owo+Pj4+IMKgwqDCoMKgwqAgY2hhciBmd19uYW1lWzEw MF07Cj4+Pj4gwqDCoMKgwqDCoCBjb25zdCBzdHJ1Y3QgZmlybXdhcmUgKnVzYmNfcGRfZnc7Cj4+ Pj4gQEAgLTMwMzEsNiArMzAzMSw5IEBAIHN0YXRpYyBzc2l6ZV90IAo+Pj4+IHBzcF91c2JjX3Bk X2Z3X3N5c2ZzX3dyaXRlKHN0cnVjdCBkZXZpY2UgKmRldiwKPj4+PiDCoMKgwqDCoMKgwqDCoMKg wqAgcmV0dXJuIC1FQlVTWTsKPj4+PiDCoMKgwqDCoMKgIH0KPj4+PiArwqDCoMKgIGlmICghZHJt X2Rldl9lbnRlcihkZGV2LCAmaWR4KSkKPj4+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9E RVY7Cj4+Pj4gKwo+Pj4+IMKgwqDCoMKgwqAgc25wcmludGYoZndfbmFtZSwgc2l6ZW9mKGZ3X25h bWUpLCAiYW1kZ3B1LyVzIiwgYnVmKTsKPj4+PiDCoMKgwqDCoMKgIHJldCA9IHJlcXVlc3RfZmly bXdhcmUoJnVzYmNfcGRfZncsIGZ3X25hbWUsIGFkZXYtPmRldik7Cj4+Pj4gwqDCoMKgwqDCoCBp ZiAocmV0KQo+Pj4+IEBAIC0zMDYyLDE2ICszMDY1LDMwIEBAIHN0YXRpYyBzc2l6ZV90IAo+Pj4+ IHBzcF91c2JjX3BkX2Z3X3N5c2ZzX3dyaXRlKHN0cnVjdCBkZXZpY2UgKmRldiwKPj4+PiDCoCBy ZWxfYnVmOgo+Pj4+IMKgwqDCoMKgwqAgZG1hX2ZyZWVfY29oZXJlbnQoYWRldi0+ZGV2LCB1c2Jj X3BkX2Z3LT5zaXplLCBjcHVfYWRkciwgCj4+Pj4gZG1hX2FkZHIpOwo+Pj4+IMKgwqDCoMKgwqAg cmVsZWFzZV9maXJtd2FyZSh1c2JjX3BkX2Z3KTsKPj4+PiAtCj4+Pj4gwqAgZmFpbDoKPj4+PiDC oMKgwqDCoMKgIGlmIChyZXQpIHsKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgRFJNX0VSUk9SKCJG YWlsZWQgdG8gbG9hZCBVU0JDIFBEIEZXLCBlcnIgPSAlZCIsIHJldCk7Cj4+Pj4gLcKgwqDCoMKg wqDCoMKgIHJldHVybiByZXQ7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgIGNvdW50ID0gcmV0Owo+Pj4+ IMKgwqDCoMKgwqAgfQo+Pj4+ICvCoMKgwqAgZHJtX2Rldl9leGl0KGlkeCk7Cj4+Pj4gwqDCoMKg wqDCoCByZXR1cm4gY291bnQ7Cj4+Pj4gwqAgfQo+Pj4+ICt2b2lkIHBzcF9jb3B5X2Z3KHN0cnVj dCBwc3BfY29udGV4dCAqcHNwLCB1aW50OF90ICpzdGFydF9hZGRyLCAKPj4+PiB1aW50MzJfdCBi aW5fc2l6ZSkKPj4+PiArewo+Pj4+ICvCoMKgwqAgaW50IGlkeDsKPj4+PiArCj4+Pj4gK8KgwqDC oCBpZiAoIWRybV9kZXZfZW50ZXIoJnBzcC0+YWRldi0+ZGRldiwgJmlkeCkpCj4+Pj4gK8KgwqDC oMKgwqDCoMKgIHJldHVybjsKPj4+PiArCj4+Pj4gK8KgwqDCoCBtZW1zZXQocHNwLT5md19wcmlf YnVmLCAwLCBQU1BfMV9NRUcpOwo+Pj4+ICvCoMKgwqAgbWVtY3B5KHBzcC0+ZndfcHJpX2J1Ziwg c3RhcnRfYWRkciwgYmluX3NpemUpOwo+Pj4+ICsKPj4+PiArwqDCoMKgIGRybV9kZXZfZXhpdChp ZHgpOwo+Pj4+ICt9Cj4+Pj4gKwo+Pj4+ICsKPj4+PiDCoCBzdGF0aWMgREVWSUNFX0FUVFIodXNi Y19wZF9mdywgU19JUlVHTyB8IFNfSVdVU1IsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IHBzcF91c2JjX3BkX2Z3X3N5c2ZzX3JlYWQsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IHBzcF91c2JjX3BkX2Z3X3N5c2ZzX3dyaXRlKTsKPj4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9n cHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3BzcC5oIAo+Pj4+IGIvZHJpdmVycy9ncHUvZHJtL2Ft ZC9hbWRncHUvYW1kZ3B1X3BzcC5oCj4+Pj4gaW5kZXggNDZhNTMyOGUwMGUwLi4yYmZkYzI3ODgx N2YgMTAwNjQ0Cj4+Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3Bz cC5oCj4+Pj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3BzcC5oCj4+ Pj4gQEAgLTQyMyw0ICs0MjMsNiBAQCBpbnQgcHNwX2dldF9md19hdHRlc3RhdGlvbl9yZWNvcmRz X2FkZHIoc3RydWN0IAo+Pj4+IHBzcF9jb250ZXh0ICpwc3AsCj4+Pj4gwqAgaW50IHBzcF9sb2Fk X2Z3X2xpc3Qoc3RydWN0IHBzcF9jb250ZXh0ICpwc3AsCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCBzdHJ1Y3QgYW1kZ3B1X2Zpcm13YXJlX2luZm8gKip1Y29kZV9saXN0LCBpbnQg Cj4+Pj4gdWNvZGVfY291bnQpOwo+Pj4+ICt2b2lkIHBzcF9jb3B5X2Z3KHN0cnVjdCBwc3BfY29u dGV4dCAqcHNwLCB1aW50OF90ICpzdGFydF9hZGRyLCAKPj4+PiB1aW50MzJfdCBiaW5fc2l6ZSk7 Cj4+Pj4gKwo+Pj4+IMKgICNlbmRpZgo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0v YW1kL2FtZGdwdS9hbWRncHVfcmluZy5jIAo+Pj4+IGIvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRn cHUvYW1kZ3B1X3JpbmcuYwo+Pj4+IGluZGV4IDY4ODYyNGViZTQyMS4uZTE5ODViYzM0NDM2IDEw MDY0NAo+Pj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV9yaW5nLmMK Pj4+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfcmluZy5jCj4+Pj4g QEAgLTM1LDYgKzM1LDggQEAKPj4+PiDCoCAjaW5jbHVkZSAiYW1kZ3B1LmgiCj4+Pj4gwqAgI2lu Y2x1ZGUgImF0b20uaCIKPj4+PiArI2luY2x1ZGUgPGRybS9kcm1fZHJ2Lmg+Cj4+Pj4gKwo+Pj4+ IMKgIC8qCj4+Pj4gwqDCoCAqIFJpbmdzCj4+Pj4gwqDCoCAqIE1vc3QgZW5naW5lcyBvbiB0aGUg R1BVIGFyZSBmZWQgdmlhIHJpbmcgYnVmZmVycy7CoCBSaW5nCj4+Pj4gQEAgLTQ2MSwzICs0NjMs NzEgQEAgaW50IGFtZGdwdV9yaW5nX3Rlc3RfaGVscGVyKHN0cnVjdCBhbWRncHVfcmluZyAKPj4+ PiAqcmluZykKPj4+PiDCoMKgwqDCoMKgIHJpbmctPnNjaGVkLnJlYWR5ID0gIXI7Cj4+Pj4gwqDC oMKgwqDCoCByZXR1cm4gcjsKPj4+PiDCoCB9Cj4+Pj4gKwo+Pj4+ICt2b2lkIGFtZGdwdV9yaW5n X2NsZWFyX3Jpbmcoc3RydWN0IGFtZGdwdV9yaW5nICpyaW5nKQo+Pj4+ICt7Cj4+Pj4gK8KgwqDC oCBpbnQgaWR4Owo+Pj4+ICvCoMKgwqAgaW50IGkgPSAwOwo+Pj4+ICsKPj4+PiArwqDCoMKgIGlm ICghZHJtX2Rldl9lbnRlcigmcmluZy0+YWRldi0+ZGRldiwgJmlkeCkpCj4+Pj4gK8KgwqDCoMKg wqDCoMKgIHJldHVybjsKPj4+PiArCj4+Pj4gK8KgwqDCoCB3aGlsZSAoaSA8PSByaW5nLT5idWZf bWFzaykKPj4+PiArwqDCoMKgwqDCoMKgwqAgcmluZy0+cmluZ1tpKytdID0gcmluZy0+ZnVuY3Mt Pm5vcDsKPj4+PiArCj4+Pj4gK8KgwqDCoCBkcm1fZGV2X2V4aXQoaWR4KTsKPj4+PiArCj4+Pj4g K30KPj4+PiArCj4+Pj4gK3ZvaWQgYW1kZ3B1X3Jpbmdfd3JpdGUoc3RydWN0IGFtZGdwdV9yaW5n ICpyaW5nLCB1aW50MzJfdCB2KQo+Pj4+ICt7Cj4+Pj4gK8KgwqDCoCBpbnQgaWR4Owo+Pj4+ICsK Pj4+PiArwqDCoMKgIGlmICghZHJtX2Rldl9lbnRlcigmcmluZy0+YWRldi0+ZGRldiwgJmlkeCkp Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgIHJldHVybjsKPj4+PiArCj4+Pj4gK8KgwqDCoCBpZiAocmlu Zy0+Y291bnRfZHcgPD0gMCkKPj4+PiArwqDCoMKgwqDCoMKgwqAgRFJNX0VSUk9SKCJhbWRncHU6 IHdyaXRpbmcgbW9yZSBkd29yZHMgdG8gdGhlIHJpbmcgdGhhbiAKPj4+PiBleHBlY3RlZCFcbiIp Owo+Pj4+ICvCoMKgwqAgcmluZy0+cmluZ1tyaW5nLT53cHRyKysgJiByaW5nLT5idWZfbWFza10g PSB2Owo+Pj4+ICvCoMKgwqAgcmluZy0+d3B0ciAmPSByaW5nLT5wdHJfbWFzazsKPj4+PiArwqDC oMKgIHJpbmctPmNvdW50X2R3LS07Cj4+Pj4gKwo+Pj4+ICvCoMKgwqAgZHJtX2Rldl9leGl0KGlk eCk7Cj4+Pj4gK30KPj4+PiArCj4+Pj4gK3ZvaWQgYW1kZ3B1X3Jpbmdfd3JpdGVfbXVsdGlwbGUo c3RydWN0IGFtZGdwdV9yaW5nICpyaW5nLAo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB2b2lkICpzcmMsIGludCBjb3VudF9kdykKPj4+PiAr ewo+Pj4+ICvCoMKgwqAgdW5zaWduZWQgb2NjdXBpZWQsIGNodW5rMSwgY2h1bmsyOwo+Pj4+ICvC oMKgwqAgdm9pZCAqZHN0Owo+Pj4+ICvCoMKgwqAgaW50IGlkeDsKPj4+PiArCj4+Pj4gK8KgwqDC oCBpZiAoIWRybV9kZXZfZW50ZXIoJnJpbmctPmFkZXYtPmRkZXYsICZpZHgpKQo+Pj4+ICvCoMKg wqDCoMKgwqDCoCByZXR1cm47Cj4+Pj4gKwo+Pj4+ICvCoMKgwqAgaWYgKHVubGlrZWx5KHJpbmct PmNvdW50X2R3IDwgY291bnRfZHcpKQo+Pj4+ICvCoMKgwqDCoMKgwqDCoCBEUk1fRVJST1IoImFt ZGdwdTogd3JpdGluZyBtb3JlIGR3b3JkcyB0byB0aGUgcmluZyB0aGFuIAo+Pj4+IGV4cGVjdGVk IVxuIik7Cj4+Pj4gKwo+Pj4+ICvCoMKgwqAgb2NjdXBpZWQgPSByaW5nLT53cHRyICYgcmluZy0+ YnVmX21hc2s7Cj4+Pj4gK8KgwqDCoCBkc3QgPSAodm9pZCAqKSZyaW5nLT5yaW5nW29jY3VwaWVk XTsKPj4+PiArwqDCoMKgIGNodW5rMSA9IHJpbmctPmJ1Zl9tYXNrICsgMSAtIG9jY3VwaWVkOwo+ Pj4+ICvCoMKgwqAgY2h1bmsxID0gKGNodW5rMSA+PSBjb3VudF9kdykgPyBjb3VudF9kdzogY2h1 bmsxOwo+Pj4+ICvCoMKgwqAgY2h1bmsyID0gY291bnRfZHcgLSBjaHVuazE7Cj4+Pj4gK8KgwqDC oCBjaHVuazEgPDw9IDI7Cj4+Pj4gK8KgwqDCoCBjaHVuazIgPDw9IDI7Cj4+Pj4gKwo+Pj4+ICvC oMKgwqAgaWYgKGNodW5rMSkKPj4+PiArwqDCoMKgwqDCoMKgwqAgbWVtY3B5KGRzdCwgc3JjLCBj aHVuazEpOwo+Pj4+ICsKPj4+PiArwqDCoMKgIGlmIChjaHVuazIpIHsKPj4+PiArwqDCoMKgwqDC oMKgwqAgc3JjICs9IGNodW5rMTsKPj4+PiArwqDCoMKgwqDCoMKgwqAgZHN0ID0gKHZvaWQgKily aW5nLT5yaW5nOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoCBtZW1jcHkoZHN0LCBzcmMsIGNodW5rMik7 Cj4+Pj4gK8KgwqDCoCB9Cj4+Pj4gKwo+Pj4+ICvCoMKgwqAgcmluZy0+d3B0ciArPSBjb3VudF9k dzsKPj4+PiArwqDCoMKgIHJpbmctPndwdHIgJj0gcmluZy0+cHRyX21hc2s7Cj4+Pj4gK8KgwqDC oCByaW5nLT5jb3VudF9kdyAtPSBjb3VudF9kdzsKPj4+PiArCj4+Pj4gK8KgwqDCoCBkcm1fZGV2 X2V4aXQoaWR4KTsKPj4+PiArfQo+Pj4KPj4+IFRoZSByaW5nIHNob3VsZCBuZXZlciB3ZSBpbiBN TUlPIG1lbW9yeSwgc28geW91IGNhbiBjb21wbGV0ZWx5IGRyb3AgCj4+PiB0aGF0IGFzIGZhciBh cyBJIGNhbiBzZWUuCj4+Cj4+IFllYSwgaXQncyBpbiBhbGwgaW4gR0FSVCwgbWlzc2VkIGl0IGZv ciBzb21lIHJlYXNvbi4uLgo+Pj4KPj4+IE1heWJlIHNwbGl0IHRoYXQgcGF0Y2ggYnkgdXNlIGNh c2Ugc28gdGhhdCB3ZSBjYW4gbW9yZSBlYXNpbHkgCj4+PiByZXZpZXcvYWNrIGl0Lgo+Pgo+PiBJ biBmYWN0IGV2ZXJ5dGhpbmcgaGVyZSBpcyB0aGUgc2FtZSB1c2UgY2FzZSwgb25jZSBJIGFkZGVk IHVubWFwIG9mCj4+IGFsbCBNTUlPIHJhbmdlcyAoYm90aCByZWdpc3RlcnMgYW5uIFZSQU0pIGkg Z290IGEgbG90IG9mIHBhZ2UgZmF1bHRzCj4+IG9uIGRldmljZSByZW1vdmUgYXJvdW5kIGFueSBt ZW1jcHkgdG8gZnJvbSBJTy4gVGhhdCB3aGVyZSBJIHB1dCB0aGUKPj4gZHJuX2Rldl9lbnRlci9l eGl0IHNjb3BlLiBBbHNvIEkgc2VhcmNoZWQgaW4gY29kZSBhbmQgcHJlZW1lcHRpdmx5Cj4+IGFk ZGVkIGd1YXJkcyB0byBhbnkgb3RoZXIgc3VjaCBwbGFjZS4gSSBkaWQgZHJvcCBhbWRncHVfc2No ZWR1bGVfaWIKPj4gZnJvbSB0aGlzIHBhdGNoIGJvdGggYmVjYXVzZSBpdCBoYWQgZG1hX2ZlbmNl X3dhaXQgaW5zaWRlIGFuZCBzbyB3ZQo+PiB3aWxsIHRha2UgY2FyZSBvZiB0aGlzIG9uY2Ugd2Ug ZGVjaWRlIG9uIGhvdyB0byBoYW5kbGUgZG1hX2ZlbmNlIHdhaXRzLgo+Pgo+PiBBbmRyZXkKPj4K Pj4+Cj4+PiBUaGFua3MsCj4+PiBDaHJpc3RpYW4uCj4+Pgo+Pj4+IGRpZmYgLS1naXQgYS9kcml2 ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfcmluZy5oIAo+Pj4+IGIvZHJpdmVycy9ncHUv ZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3JpbmcuaAo+Pj4+IGluZGV4IGU3ZDNkMGRiZGQ5Ni4uYzY3 YmM2ZDNkMDM5IDEwMDY0NAo+Pj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L2Ft ZGdwdV9yaW5nLmgKPj4+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVf cmluZy5oCj4+Pj4gQEAgLTI5OSw1MyArMjk5LDEyIEBAIHN0YXRpYyBpbmxpbmUgdm9pZCAKPj4+ PiBhbWRncHVfcmluZ19zZXRfcHJlZW1wdF9jb25kX2V4ZWMoc3RydWN0IGFtZGdwdV9yaW5nICpy aW5nLAo+Pj4+IMKgwqDCoMKgwqAgKnJpbmctPmNvbmRfZXhlX2NwdV9hZGRyID0gY29uZF9leGVj Owo+Pj4+IMKgIH0KPj4+PiAtc3RhdGljIGlubGluZSB2b2lkIGFtZGdwdV9yaW5nX2NsZWFyX3Jp bmcoc3RydWN0IGFtZGdwdV9yaW5nICpyaW5nKQo+Pj4+IC17Cj4+Pj4gLcKgwqDCoCBpbnQgaSA9 IDA7Cj4+Pj4gLcKgwqDCoCB3aGlsZSAoaSA8PSByaW5nLT5idWZfbWFzaykKPj4+PiAtwqDCoMKg wqDCoMKgwqAgcmluZy0+cmluZ1tpKytdID0gcmluZy0+ZnVuY3MtPm5vcDsKPj4+PiAtCj4+Pj4g LX0KPj4+PiAtCj4+Pj4gLXN0YXRpYyBpbmxpbmUgdm9pZCBhbWRncHVfcmluZ193cml0ZShzdHJ1 Y3QgYW1kZ3B1X3JpbmcgKnJpbmcsIAo+Pj4+IHVpbnQzMl90IHYpCj4+Pj4gLXsKPj4+PiAtwqDC oMKgIGlmIChyaW5nLT5jb3VudF9kdyA8PSAwKQo+Pj4+IC3CoMKgwqDCoMKgwqDCoCBEUk1fRVJS T1IoImFtZGdwdTogd3JpdGluZyBtb3JlIGR3b3JkcyB0byB0aGUgcmluZyB0aGFuIAo+Pj4+IGV4 cGVjdGVkIVxuIik7Cj4+Pj4gLcKgwqDCoCByaW5nLT5yaW5nW3JpbmctPndwdHIrKyAmIHJpbmct PmJ1Zl9tYXNrXSA9IHY7Cj4+Pj4gLcKgwqDCoCByaW5nLT53cHRyICY9IHJpbmctPnB0cl9tYXNr Owo+Pj4+IC3CoMKgwqAgcmluZy0+Y291bnRfZHctLTsKPj4+PiAtfQo+Pj4+ICt2b2lkIGFtZGdw dV9yaW5nX2NsZWFyX3Jpbmcoc3RydWN0IGFtZGdwdV9yaW5nICpyaW5nKTsKPj4+PiAtc3RhdGlj IGlubGluZSB2b2lkIGFtZGdwdV9yaW5nX3dyaXRlX211bHRpcGxlKHN0cnVjdCBhbWRncHVfcmlu ZyAKPj4+PiAqcmluZywKPj4+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqAgdm9pZCAqc3JjLCBpbnQgY291bnRfZHcpCj4+Pj4gLXsKPj4+PiAtwqDC oMKgIHVuc2lnbmVkIG9jY3VwaWVkLCBjaHVuazEsIGNodW5rMjsKPj4+PiAtwqDCoMKgIHZvaWQg KmRzdDsKPj4+PiAtCj4+Pj4gLcKgwqDCoCBpZiAodW5saWtlbHkocmluZy0+Y291bnRfZHcgPCBj b3VudF9kdykpCj4+Pj4gLcKgwqDCoMKgwqDCoMKgIERSTV9FUlJPUigiYW1kZ3B1OiB3cml0aW5n IG1vcmUgZHdvcmRzIHRvIHRoZSByaW5nIHRoYW4gCj4+Pj4gZXhwZWN0ZWQhXG4iKTsKPj4+PiAt Cj4+Pj4gLcKgwqDCoCBvY2N1cGllZCA9IHJpbmctPndwdHIgJiByaW5nLT5idWZfbWFzazsKPj4+ PiAtwqDCoMKgIGRzdCA9ICh2b2lkICopJnJpbmctPnJpbmdbb2NjdXBpZWRdOwo+Pj4+IC3CoMKg wqAgY2h1bmsxID0gcmluZy0+YnVmX21hc2sgKyAxIC0gb2NjdXBpZWQ7Cj4+Pj4gLcKgwqDCoCBj aHVuazEgPSAoY2h1bmsxID49IGNvdW50X2R3KSA/IGNvdW50X2R3OiBjaHVuazE7Cj4+Pj4gLcKg wqDCoCBjaHVuazIgPSBjb3VudF9kdyAtIGNodW5rMTsKPj4+PiAtwqDCoMKgIGNodW5rMSA8PD0g MjsKPj4+PiAtwqDCoMKgIGNodW5rMiA8PD0gMjsKPj4+PiArdm9pZCBhbWRncHVfcmluZ193cml0 ZShzdHJ1Y3QgYW1kZ3B1X3JpbmcgKnJpbmcsIHVpbnQzMl90IHYpOwo+Pj4+IC3CoMKgwqAgaWYg KGNodW5rMSkKPj4+PiAtwqDCoMKgwqDCoMKgwqAgbWVtY3B5KGRzdCwgc3JjLCBjaHVuazEpOwo+ Pj4+IC0KPj4+PiAtwqDCoMKgIGlmIChjaHVuazIpIHsKPj4+PiAtwqDCoMKgwqDCoMKgwqAgc3Jj ICs9IGNodW5rMTsKPj4+PiAtwqDCoMKgwqDCoMKgwqAgZHN0ID0gKHZvaWQgKilyaW5nLT5yaW5n Owo+Pj4+IC3CoMKgwqDCoMKgwqDCoCBtZW1jcHkoZHN0LCBzcmMsIGNodW5rMik7Cj4+Pj4gLcKg wqDCoCB9Cj4+Pj4gLQo+Pj4+IC3CoMKgwqAgcmluZy0+d3B0ciArPSBjb3VudF9kdzsKPj4+PiAt wqDCoMKgIHJpbmctPndwdHIgJj0gcmluZy0+cHRyX21hc2s7Cj4+Pj4gLcKgwqDCoCByaW5nLT5j b3VudF9kdyAtPSBjb3VudF9kdzsKPj4+PiAtfQo+Pj4+ICt2b2lkIGFtZGdwdV9yaW5nX3dyaXRl X211bHRpcGxlKHN0cnVjdCBhbWRncHVfcmluZyAqcmluZywKPj4+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdm9pZCAqc3JjLCBpbnQgY291bnRf ZHcpOwo+Pj4+IMKgIGludCBhbWRncHVfcmluZ190ZXN0X2hlbHBlcihzdHJ1Y3QgYW1kZ3B1X3Jp bmcgKnJpbmcpOwo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9h bWRncHVfdXZkLmMgCj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfdXZk LmMKPj4+PiBpbmRleCBjNmRiYzA4MDE2MDQuLjgyZjA1NDJjNzc5MiAxMDA2NDQKPj4+PiAtLS0g YS9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfdXZkLmMKPj4+PiArKysgYi9kcml2 ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfdXZkLmMKPj4+PiBAQCAtMzIsNiArMzIsNyBA QAo+Pj4+IMKgICNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPj4+PiDCoCAjaW5jbHVkZSA8ZHJt L2RybS5oPgo+Pj4+ICsjaW5jbHVkZSA8ZHJtL2RybV9kcnYuaD4KPj4+PiDCoCAjaW5jbHVkZSAi YW1kZ3B1LmgiCj4+Pj4gwqAgI2luY2x1ZGUgImFtZGdwdV9wbS5oIgo+Pj4+IEBAIC0zNzUsNyAr Mzc2LDcgQEAgaW50IGFtZGdwdV91dmRfc3VzcGVuZChzdHJ1Y3QgYW1kZ3B1X2RldmljZSAqYWRl dikKPj4+PiDCoCB7Cj4+Pj4gwqDCoMKgwqDCoCB1bnNpZ25lZCBzaXplOwo+Pj4+IMKgwqDCoMKg wqAgdm9pZCAqcHRyOwo+Pj4+IC3CoMKgwqAgaW50IGksIGo7Cj4+Pj4gK8KgwqDCoCBpbnQgaSwg aiwgaWR4Owo+Pj4+IMKgwqDCoMKgwqAgYm9vbCBpbl9yYXNfaW50ciA9IGFtZGdwdV9yYXNfaW50 cl90cmlnZ2VyZWQoKTsKPj4+PiDCoMKgwqDCoMKgIGNhbmNlbF9kZWxheWVkX3dvcmtfc3luYygm YWRldi0+dXZkLmlkbGVfd29yayk7Cj4+Pj4gQEAgLTQwMywxMSArNDA0LDE1IEBAIGludCBhbWRn cHVfdXZkX3N1c3BlbmQoc3RydWN0IGFtZGdwdV9kZXZpY2UgCj4+Pj4gKmFkZXYpCj4+Pj4gwqDC oMKgwqDCoMKgwqDCoMKgIGlmICghYWRldi0+dXZkLmluc3Rbal0uc2F2ZWRfYm8pCj4+Pj4gwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9NRU07Cj4+Pj4gLcKgwqDCoMKgwqDC oMKgIC8qIHJlLXdyaXRlIDAgc2luY2UgZXJyX2V2ZW50X2F0aHViIHdpbGwgY29ycnVwdCBWQ1BV IAo+Pj4+IGJ1ZmZlciAqLwo+Pj4+IC3CoMKgwqDCoMKgwqDCoCBpZiAoaW5fcmFzX2ludHIpCj4+ Pj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbWVtc2V0KGFkZXYtPnV2ZC5pbnN0W2pdLnNhdmVk X2JvLCAwLCBzaXplKTsKPj4+PiAtwqDCoMKgwqDCoMKgwqAgZWxzZQo+Pj4+IC3CoMKgwqDCoMKg wqDCoMKgwqDCoMKgIG1lbWNweV9mcm9taW8oYWRldi0+dXZkLmluc3Rbal0uc2F2ZWRfYm8sIHB0 ciwgc2l6ZSk7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgIGlmIChkcm1fZGV2X2VudGVyKCZhZGV2LT5k ZGV2LCAmaWR4KSkgewo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIC8qIHJlLXdyaXRlIDAg c2luY2UgZXJyX2V2ZW50X2F0aHViIHdpbGwgY29ycnVwdCBWQ1BVIAo+Pj4+IGJ1ZmZlciAqLwo+ Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlmIChpbl9yYXNfaW50cikKPj4+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIG1lbXNldChhZGV2LT51dmQuaW5zdFtqXS5zYXZlZF9i bywgMCwgc2l6ZSk7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZWxzZQo+Pj4+ICsgbWVt Y3B5X2Zyb21pbyhhZGV2LT51dmQuaW5zdFtqXS5zYXZlZF9ibywgcHRyLCBzaXplKTsKPj4+PiAr Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZHJtX2Rldl9leGl0KGlkeCk7Cj4+Pj4gK8Kg wqDCoMKgwqDCoMKgIH0KPj4+PiDCoMKgwqDCoMKgIH0KPj4+PiDCoMKgwqDCoMKgIGlmIChpbl9y YXNfaW50cikKPj4+PiBAQCAtNDIwLDcgKzQyNSw3IEBAIGludCBhbWRncHVfdXZkX3Jlc3VtZShz dHJ1Y3QgYW1kZ3B1X2RldmljZSAqYWRldikKPj4+PiDCoCB7Cj4+Pj4gwqDCoMKgwqDCoCB1bnNp Z25lZCBzaXplOwo+Pj4+IMKgwqDCoMKgwqAgdm9pZCAqcHRyOwo+Pj4+IC3CoMKgwqAgaW50IGk7 Cj4+Pj4gK8KgwqDCoCBpbnQgaSwgaWR4Owo+Pj4+IMKgwqDCoMKgwqAgZm9yIChpID0gMDsgaSA8 IGFkZXYtPnV2ZC5udW1fdXZkX2luc3Q7IGkrKykgewo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBp ZiAoYWRldi0+dXZkLmhhcnZlc3RfY29uZmlnICYgKDEgPDwgaSkpCj4+Pj4gQEAgLTQzMiw3ICs0 MzcsMTAgQEAgaW50IGFtZGdwdV91dmRfcmVzdW1lKHN0cnVjdCBhbWRncHVfZGV2aWNlICphZGV2 KQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBwdHIgPSBhZGV2LT51dmQuaW5zdFtpXS5jcHVfYWRk cjsKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKGFkZXYtPnV2ZC5pbnN0W2ldLnNhdmVkX2Jv ICE9IE5VTEwpIHsKPj4+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBtZW1jcHlfdG9pbyhwdHIs IGFkZXYtPnV2ZC5pbnN0W2ldLnNhdmVkX2JvLCBzaXplKTsKPj4+PiArwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBpZiAoZHJtX2Rldl9lbnRlcigmYWRldi0+ZGRldiwgJmlkeCkpIHsKPj4+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIG1lbWNweV90b2lvKHB0ciwgYWRldi0+dXZkLmlu c3RbaV0uc2F2ZWRfYm8sIHNpemUpOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqAgZHJtX2Rldl9leGl0KGlkeCk7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgfQo+Pj4+ IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGt2ZnJlZShhZGV2LT51dmQuaW5zdFtpXS5zYXZl ZF9ibyk7Cj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgYWRldi0+dXZkLmluc3RbaV0u c2F2ZWRfYm8gPSBOVUxMOwo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCB9IGVsc2Ugewo+Pj4+IEBA IC00NDIsOCArNDUwLDExIEBAIGludCBhbWRncHVfdXZkX3Jlc3VtZShzdHJ1Y3QgYW1kZ3B1X2Rl dmljZSAqYWRldikKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBoZHIgPSAoY29uc3Qg c3RydWN0IGNvbW1vbl9maXJtd2FyZV9oZWFkZXIgCj4+Pj4gKilhZGV2LT51dmQuZnctPmRhdGE7 Cj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKGFkZXYtPmZpcm13YXJlLmxvYWRf dHlwZSAhPSBBTURHUFVfRldfTE9BRF9QU1ApIHsKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIG9mZnNldCA9IGxlMzJfdG9fY3B1KGhkci0+dWNvZGVfYXJyYXlfb2Zmc2V0 X2J5dGVzKTsKPj4+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIG1lbWNweV90b2lv KGFkZXYtPnV2ZC5pbnN0W2ldLmNwdV9hZGRyLCAKPj4+PiBhZGV2LT51dmQuZnctPmRhdGEgKyBv ZmZzZXQsCj4+Pj4gLSBsZTMyX3RvX2NwdShoZHItPnVjb2RlX3NpemVfYnl0ZXMpKTsKPj4+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlmIChkcm1fZGV2X2VudGVyKCZhZGV2LT5k ZGV2LCAmaWR4KSkgewo+Pj4+ICsgbWVtY3B5X3RvaW8oYWRldi0+dXZkLmluc3RbaV0uY3B1X2Fk ZHIsIGFkZXYtPnV2ZC5mdy0+ZGF0YSArIG9mZnNldCwKPj4+PiArIGxlMzJfdG9fY3B1KGhkci0+ dWNvZGVfc2l6ZV9ieXRlcykpOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoCBkcm1fZGV2X2V4aXQoaWR4KTsKPj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIH0KPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHNpemUgLT0g bGUzMl90b19jcHUoaGRyLT51Y29kZV9zaXplX2J5dGVzKTsKPj4+PiDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIHB0ciArPSBsZTMyX3RvX2NwdShoZHItPnVjb2RlX3NpemVfYnl0 ZXMpOwo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0KPj4+PiBkaWZmIC0tZ2l0IGEv ZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3ZjZS5jIAo+Pj4+IGIvZHJpdmVycy9n cHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3ZjZS5jCj4+Pj4gaW5kZXggZWE2YTYyZjY3ZTM4Li44 MzMyMDM0MDFlZjQgMTAwNjQ0Cj4+Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUv YW1kZ3B1X3ZjZS5jCj4+Pj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1 X3ZjZS5jCj4+Pj4gQEAgLTI5LDYgKzI5LDcgQEAKPj4+PiDCoCAjaW5jbHVkZSA8bGludXgvbW9k dWxlLmg+Cj4+Pj4gwqAgI2luY2x1ZGUgPGRybS9kcm0uaD4KPj4+PiArI2luY2x1ZGUgPGRybS9k cm1fZHJ2Lmg+Cj4+Pj4gwqAgI2luY2x1ZGUgImFtZGdwdS5oIgo+Pj4+IMKgICNpbmNsdWRlICJh bWRncHVfcG0uaCIKPj4+PiBAQCAtMjkzLDcgKzI5NCw3IEBAIGludCBhbWRncHVfdmNlX3Jlc3Vt ZShzdHJ1Y3QgYW1kZ3B1X2RldmljZSAqYWRldikKPj4+PiDCoMKgwqDCoMKgIHZvaWQgKmNwdV9h ZGRyOwo+Pj4+IMKgwqDCoMKgwqAgY29uc3Qgc3RydWN0IGNvbW1vbl9maXJtd2FyZV9oZWFkZXIg KmhkcjsKPj4+PiDCoMKgwqDCoMKgIHVuc2lnbmVkIG9mZnNldDsKPj4+PiAtwqDCoMKgIGludCBy Owo+Pj4+ICvCoMKgwqAgaW50IHIsIGlkeDsKPj4+PiDCoMKgwqDCoMKgIGlmIChhZGV2LT52Y2Uu dmNwdV9ibyA9PSBOVUxMKQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVJTlZBTDsK Pj4+PiBAQCAtMzEzLDggKzMxNCwxMiBAQCBpbnQgYW1kZ3B1X3ZjZV9yZXN1bWUoc3RydWN0IGFt ZGdwdV9kZXZpY2UgKmFkZXYpCj4+Pj4gwqDCoMKgwqDCoCBoZHIgPSAoY29uc3Qgc3RydWN0IGNv bW1vbl9maXJtd2FyZV9oZWFkZXIgKilhZGV2LT52Y2UuZnctPmRhdGE7Cj4+Pj4gwqDCoMKgwqDC oCBvZmZzZXQgPSBsZTMyX3RvX2NwdShoZHItPnVjb2RlX2FycmF5X29mZnNldF9ieXRlcyk7Cj4+ Pj4gLcKgwqDCoCBtZW1jcHlfdG9pbyhjcHVfYWRkciwgYWRldi0+dmNlLmZ3LT5kYXRhICsgb2Zm c2V0LAo+Pj4+IC3CoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGFkZXYtPnZjZS5mdy0+c2l6ZSAtIG9m ZnNldCk7Cj4+Pj4gKwo+Pj4+ICvCoMKgwqAgaWYgKGRybV9kZXZfZW50ZXIoJmFkZXYtPmRkZXYs ICZpZHgpKSB7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgIG1lbWNweV90b2lvKGNwdV9hZGRyLCBhZGV2 LT52Y2UuZnctPmRhdGEgKyBvZmZzZXQsCj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCBhZGV2LT52Y2UuZnctPnNpemUgLSBvZmZzZXQpOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoCBk cm1fZGV2X2V4aXQoaWR4KTsKPj4+PiArwqDCoMKgIH0KPj4+PiDCoMKgwqDCoMKgIGFtZGdwdV9i b19rdW5tYXAoYWRldi0+dmNlLnZjcHVfYm8pOwo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dw dS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfdmNuLmMgCj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vYW1k L2FtZGdwdS9hbWRncHVfdmNuLmMKPj4+PiBpbmRleCAyMDE2NDU5NjNiYTUuLjIxZjdkMzY0NGQ3 MCAxMDA2NDQKPj4+PiAtLS0gYS9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfdmNu LmMKPj4+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfdmNuLmMKPj4+ PiBAQCAtMjcsNiArMjcsNyBAQAo+Pj4+IMKgICNpbmNsdWRlIDxsaW51eC9maXJtd2FyZS5oPgo+ Pj4+IMKgICNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KPj4+PiDCoCAjaW5jbHVkZSA8bGludXgv cGNpLmg+Cj4+Pj4gKyNpbmNsdWRlIDxkcm0vZHJtX2Rydi5oPgo+Pj4+IMKgICNpbmNsdWRlICJh bWRncHUuaCIKPj4+PiDCoCAjaW5jbHVkZSAiYW1kZ3B1X3BtLmgiCj4+Pj4gQEAgLTI3NSw3ICsy NzYsNyBAQCBpbnQgYW1kZ3B1X3Zjbl9zdXNwZW5kKHN0cnVjdCBhbWRncHVfZGV2aWNlICphZGV2 KQo+Pj4+IMKgIHsKPj4+PiDCoMKgwqDCoMKgIHVuc2lnbmVkIHNpemU7Cj4+Pj4gwqDCoMKgwqDC oCB2b2lkICpwdHI7Cj4+Pj4gLcKgwqDCoCBpbnQgaTsKPj4+PiArwqDCoMKgIGludCBpLCBpZHg7 Cj4+Pj4gwqDCoMKgwqDCoCBjYW5jZWxfZGVsYXllZF93b3JrX3N5bmMoJmFkZXYtPnZjbi5pZGxl X3dvcmspOwo+Pj4+IEBAIC0yOTIsNyArMjkzLDEwIEBAIGludCBhbWRncHVfdmNuX3N1c3BlbmQo c3RydWN0IGFtZGdwdV9kZXZpY2UgCj4+Pj4gKmFkZXYpCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKg IGlmICghYWRldi0+dmNuLmluc3RbaV0uc2F2ZWRfYm8pCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqAgcmV0dXJuIC1FTk9NRU07Cj4+Pj4gLcKgwqDCoMKgwqDCoMKgIG1lbWNweV9mcm9t aW8oYWRldi0+dmNuLmluc3RbaV0uc2F2ZWRfYm8sIHB0ciwgc2l6ZSk7Cj4+Pj4gK8KgwqDCoMKg wqDCoMKgIGlmIChkcm1fZGV2X2VudGVyKCZhZGV2LT5kZGV2LCAmaWR4KSkgewo+Pj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIG1lbWNweV9mcm9taW8oYWRldi0+dmNuLmluc3RbaV0uc2F2ZWRf Ym8sIHB0ciwgc2l6ZSk7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZHJtX2Rldl9leGl0 KGlkeCk7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgIH0KPj4+PiDCoMKgwqDCoMKgIH0KPj4+PiDCoMKg wqDCoMKgIHJldHVybiAwOwo+Pj4+IMKgIH0KPj4+PiBAQCAtMzAxLDcgKzMwNSw3IEBAIGludCBh bWRncHVfdmNuX3Jlc3VtZShzdHJ1Y3QgYW1kZ3B1X2RldmljZSAqYWRldikKPj4+PiDCoCB7Cj4+ Pj4gwqDCoMKgwqDCoCB1bnNpZ25lZCBzaXplOwo+Pj4+IMKgwqDCoMKgwqAgdm9pZCAqcHRyOwo+ Pj4+IC3CoMKgwqAgaW50IGk7Cj4+Pj4gK8KgwqDCoCBpbnQgaSwgaWR4Owo+Pj4+IMKgwqDCoMKg wqAgZm9yIChpID0gMDsgaSA8IGFkZXYtPnZjbi5udW1fdmNuX2luc3Q7ICsraSkgewo+Pj4+IMKg wqDCoMKgwqDCoMKgwqDCoCBpZiAoYWRldi0+dmNuLmhhcnZlc3RfY29uZmlnICYgKDEgPDwgaSkp Cj4+Pj4gQEAgLTMxMyw3ICszMTcsMTAgQEAgaW50IGFtZGdwdV92Y25fcmVzdW1lKHN0cnVjdCBh bWRncHVfZGV2aWNlICphZGV2KQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCBwdHIgPSBhZGV2LT52 Y24uaW5zdFtpXS5jcHVfYWRkcjsKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKGFkZXYtPnZj bi5pbnN0W2ldLnNhdmVkX2JvICE9IE5VTEwpIHsKPj4+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDC oCBtZW1jcHlfdG9pbyhwdHIsIGFkZXYtPnZjbi5pbnN0W2ldLnNhdmVkX2JvLCBzaXplKTsKPj4+ PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBpZiAoZHJtX2Rldl9lbnRlcigmYWRldi0+ZGRldiwg JmlkeCkpIHsKPj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIG1lbWNweV90b2lv KHB0ciwgYWRldi0+dmNuLmluc3RbaV0uc2F2ZWRfYm8sIHNpemUpOwo+Pj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqAgZHJtX2Rldl9leGl0KGlkeCk7Cj4+Pj4gK8KgwqDCoMKgwqDC oMKgwqDCoMKgwqAgfQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGt2ZnJlZShhZGV2 LT52Y24uaW5zdFtpXS5zYXZlZF9ibyk7Cj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAg YWRldi0+dmNuLmluc3RbaV0uc2F2ZWRfYm8gPSBOVUxMOwo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDC oCB9IGVsc2Ugewo+Pj4+IEBAIC0zMjMsOCArMzMwLDExIEBAIGludCBhbWRncHVfdmNuX3Jlc3Vt ZShzdHJ1Y3QgYW1kZ3B1X2RldmljZSAqYWRldikKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoCBoZHIgPSAoY29uc3Qgc3RydWN0IGNvbW1vbl9maXJtd2FyZV9oZWFkZXIgCj4+Pj4gKilh ZGV2LT52Y24uZnctPmRhdGE7Cj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKGFk ZXYtPmZpcm13YXJlLmxvYWRfdHlwZSAhPSBBTURHUFVfRldfTE9BRF9QU1ApIHsKPj4+PiDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIG9mZnNldCA9IGxlMzJfdG9fY3B1KGhkci0+ dWNvZGVfYXJyYXlfb2Zmc2V0X2J5dGVzKTsKPj4+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgIG1lbWNweV90b2lvKGFkZXYtPnZjbi5pbnN0W2ldLmNwdV9hZGRyLCAKPj4+PiBhZGV2 LT52Y24uZnctPmRhdGEgKyBvZmZzZXQsCj4+Pj4gLSBsZTMyX3RvX2NwdShoZHItPnVjb2RlX3Np emVfYnl0ZXMpKTsKPj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGlmIChkcm1f ZGV2X2VudGVyKCZhZGV2LT5kZGV2LCAmaWR4KSkgewo+Pj4+ICsgbWVtY3B5X3RvaW8oYWRldi0+ dmNuLmluc3RbaV0uY3B1X2FkZHIsIGFkZXYtPnZjbi5mdy0+ZGF0YSArIG9mZnNldCwKPj4+PiAr IGxlMzJfdG9fY3B1KGhkci0+dWNvZGVfc2l6ZV9ieXRlcykpOwo+Pj4+ICvCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBkcm1fZGV2X2V4aXQoaWR4KTsKPj4+PiArwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0KPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIHNpemUgLT0gbGUzMl90b19jcHUoaGRyLT51Y29kZV9zaXplX2J5dGVzKTsKPj4+ PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHB0ciArPSBsZTMyX3RvX2NwdSho ZHItPnVjb2RlX3NpemVfYnl0ZXMpOwo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIH0K Pj4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvYW1kZ3B1X3ZtLmMg Cj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9hbWRncHVfdm0uYwo+Pj4+IGluZGV4 IDlmODY4Y2YzYjgzMi4uN2RkNWYxMGFiNTcwIDEwMDY0NAo+Pj4+IC0tLSBhL2RyaXZlcnMvZ3B1 L2RybS9hbWQvYW1kZ3B1L2FtZGdwdV92bS5jCj4+Pj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2Ft ZC9hbWRncHUvYW1kZ3B1X3ZtLmMKPj4+PiBAQCAtMzIsNiArMzIsNyBAQAo+Pj4+IMKgICNpbmNs dWRlIDxsaW51eC9kbWEtYnVmLmg+Cj4+Pj4gwqAgI2luY2x1ZGUgPGRybS9hbWRncHVfZHJtLmg+ Cj4+Pj4gKyNpbmNsdWRlIDxkcm0vZHJtX2Rydi5oPgo+Pj4+IMKgICNpbmNsdWRlICJhbWRncHUu aCIKPj4+PiDCoCAjaW5jbHVkZSAiYW1kZ3B1X3RyYWNlLmgiCj4+Pj4gwqAgI2luY2x1ZGUgImFt ZGdwdV9hbWRrZmQuaCIKPj4+PiBAQCAtMTYwNiw3ICsxNjA3LDEwIEBAIHN0YXRpYyBpbnQgCj4+ Pj4gYW1kZ3B1X3ZtX2JvX3VwZGF0ZV9tYXBwaW5nKHN0cnVjdCBhbWRncHVfZGV2aWNlICphZGV2 LAo+Pj4+IMKgwqDCoMKgwqAgc3RydWN0IGFtZGdwdV92bV91cGRhdGVfcGFyYW1zIHBhcmFtczsK Pj4+PiDCoMKgwqDCoMKgIGVudW0gYW1kZ3B1X3N5bmNfbW9kZSBzeW5jX21vZGU7Cj4+Pj4gwqDC oMKgwqDCoCB1aW50NjRfdCBwZm47Cj4+Pj4gLcKgwqDCoCBpbnQgcjsKPj4+PiArwqDCoMKgIGlu dCByLCBpZHg7Cj4+Pj4gKwo+Pj4+ICvCoMKgwqAgaWYgKCFkcm1fZGV2X2VudGVyKCZhZGV2LT5k ZGV2LCAmaWR4KSkKPj4+PiArwqDCoMKgwqDCoMKgwqAgcmV0dXJuIC1FTk9ERVY7Cj4+Pj4gwqDC oMKgwqDCoCBtZW1zZXQoJnBhcmFtcywgMCwgc2l6ZW9mKHBhcmFtcykpOwo+Pj4+IMKgwqDCoMKg wqAgcGFyYW1zLmFkZXYgPSBhZGV2Owo+Pj4+IEBAIC0xNzE1LDYgKzE3MTksNyBAQCBzdGF0aWMg aW50IGFtZGdwdV92bV9ib191cGRhdGVfbWFwcGluZyhzdHJ1Y3QgCj4+Pj4gYW1kZ3B1X2Rldmlj ZSAqYWRldiwKPj4+PiDCoCBlcnJvcl91bmxvY2s6Cj4+Pj4gwqDCoMKgwqDCoCBhbWRncHVfdm1f ZXZpY3Rpb25fdW5sb2NrKHZtKTsKPj4+PiArwqDCoMKgIGRybV9kZXZfZXhpdChpZHgpOwo+Pj4+ IMKgwqDCoMKgwqAgcmV0dXJuIHI7Cj4+Pj4gwqAgfQo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJz L2dwdS9kcm0vYW1kL2FtZGdwdS9wc3BfdjExXzAuYyAKPj4+PiBiL2RyaXZlcnMvZ3B1L2RybS9h bWQvYW1kZ3B1L3BzcF92MTFfMC5jCj4+Pj4gaW5kZXggNTg5NDEwYzMyZDA5Li4yY2VjNzFlODIz ZjUgMTAwNjQ0Cj4+Pj4gLS0tIGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvcHNwX3YxMV8w LmMKPj4+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9wc3BfdjExXzAuYwo+Pj4+ IEBAIC0yMyw2ICsyMyw3IEBACj4+Pj4gwqAgI2luY2x1ZGUgPGxpbnV4L2Zpcm13YXJlLmg+Cj4+ Pj4gwqAgI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgo+Pj4+IMKgICNpbmNsdWRlIDxsaW51eC92 bWFsbG9jLmg+Cj4+Pj4gKyNpbmNsdWRlIDxkcm0vZHJtX2Rydi5oPgo+Pj4+IMKgICNpbmNsdWRl ICJhbWRncHUuaCIKPj4+PiDCoCAjaW5jbHVkZSAiYW1kZ3B1X3BzcC5oIgo+Pj4+IEBAIC0yNjks MTAgKzI3MCw4IEBAIHN0YXRpYyBpbnQgCj4+Pj4gcHNwX3YxMV8wX2Jvb3Rsb2FkZXJfbG9hZF9r ZGIoc3RydWN0IHBzcF9jb250ZXh0ICpwc3ApCj4+Pj4gwqDCoMKgwqDCoCBpZiAocmV0KQo+Pj4+ IMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gcmV0Owo+Pj4+IC3CoMKgwqAgbWVtc2V0KHBzcC0+ ZndfcHJpX2J1ZiwgMCwgUFNQXzFfTUVHKTsKPj4+PiAtCj4+Pj4gwqDCoMKgwqDCoCAvKiBDb3B5 IFBTUCBLREIgYmluYXJ5IHRvIG1lbW9yeSAqLwo+Pj4+IC3CoMKgwqAgbWVtY3B5KHBzcC0+Zndf cHJpX2J1ZiwgcHNwLT5rZGJfc3RhcnRfYWRkciwgcHNwLT5rZGJfYmluX3NpemUpOwo+Pj4+ICvC oMKgwqAgcHNwX2NvcHlfZncocHNwLCBwc3AtPmtkYl9zdGFydF9hZGRyLCBwc3AtPmtkYl9iaW5f c2l6ZSk7Cj4+Pj4gwqDCoMKgwqDCoCAvKiBQcm92aWRlIHRoZSBQU1AgS0RCIHRvIGJvb3Rsb2Fk ZXIgKi8KPj4+PiDCoMKgwqDCoMKgIFdSRUczMl9TT0MxNShNUDAsIDAsIG1tTVAwX1NNTl9DMlBN U0dfMzYsCj4+Pj4gQEAgLTMwMiwxMCArMzAxLDggQEAgc3RhdGljIGludCAKPj4+PiBwc3BfdjEx XzBfYm9vdGxvYWRlcl9sb2FkX3NwbChzdHJ1Y3QgcHNwX2NvbnRleHQgKnBzcCkKPj4+PiDCoMKg wqDCoMKgIGlmIChyZXQpCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+Pj4g LcKgwqDCoCBtZW1zZXQocHNwLT5md19wcmlfYnVmLCAwLCBQU1BfMV9NRUcpOwo+Pj4+IC0KPj4+ PiDCoMKgwqDCoMKgIC8qIENvcHkgUFNQIFNQTCBiaW5hcnkgdG8gbWVtb3J5ICovCj4+Pj4gLcKg wqDCoCBtZW1jcHkocHNwLT5md19wcmlfYnVmLCBwc3AtPnNwbF9zdGFydF9hZGRyLCBwc3AtPnNw bF9iaW5fc2l6ZSk7Cj4+Pj4gK8KgwqDCoCBwc3BfY29weV9mdyhwc3AsIHBzcC0+c3BsX3N0YXJ0 X2FkZHIsIHBzcC0+c3BsX2Jpbl9zaXplKTsKPj4+PiDCoMKgwqDCoMKgIC8qIFByb3ZpZGUgdGhl IFBTUCBTUEwgdG8gYm9vdGxvYWRlciAqLwo+Pj4+IMKgwqDCoMKgwqAgV1JFRzMyX1NPQzE1KE1Q MCwgMCwgbW1NUDBfU01OX0MyUE1TR18zNiwKPj4+PiBAQCAtMzM1LDEwICszMzIsOCBAQCBzdGF0 aWMgaW50IAo+Pj4+IHBzcF92MTFfMF9ib290bG9hZGVyX2xvYWRfc3lzZHJ2KHN0cnVjdCBwc3Bf Y29udGV4dCAqcHNwKQo+Pj4+IMKgwqDCoMKgwqAgaWYgKHJldCkKPj4+PiDCoMKgwqDCoMKgwqDC oMKgwqAgcmV0dXJuIHJldDsKPj4+PiAtwqDCoMKgIG1lbXNldChwc3AtPmZ3X3ByaV9idWYsIDAs IFBTUF8xX01FRyk7Cj4+Pj4gLQo+Pj4+IMKgwqDCoMKgwqAgLyogQ29weSBQU1AgU3lzdGVtIERy aXZlciBiaW5hcnkgdG8gbWVtb3J5ICovCj4+Pj4gLcKgwqDCoCBtZW1jcHkocHNwLT5md19wcmlf YnVmLCBwc3AtPnN5c19zdGFydF9hZGRyLCBwc3AtPnN5c19iaW5fc2l6ZSk7Cj4+Pj4gK8KgwqDC oCBwc3BfY29weV9mdyhwc3AsIHBzcC0+c3lzX3N0YXJ0X2FkZHIsIHBzcC0+c3lzX2Jpbl9zaXpl KTsKPj4+PiDCoMKgwqDCoMKgIC8qIFByb3ZpZGUgdGhlIHN5cyBkcml2ZXIgdG8gYm9vdGxvYWRl ciAqLwo+Pj4+IMKgwqDCoMKgwqAgV1JFRzMyX1NPQzE1KE1QMCwgMCwgbW1NUDBfU01OX0MyUE1T R18zNiwKPj4+PiBAQCAtMzcxLDEwICszNjYsOCBAQCBzdGF0aWMgaW50IAo+Pj4+IHBzcF92MTFf MF9ib290bG9hZGVyX2xvYWRfc29zKHN0cnVjdCBwc3BfY29udGV4dCAqcHNwKQo+Pj4+IMKgwqDC oMKgwqAgaWYgKHJldCkKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4+PiAt wqDCoMKgIG1lbXNldChwc3AtPmZ3X3ByaV9idWYsIDAsIFBTUF8xX01FRyk7Cj4+Pj4gLQo+Pj4+ IMKgwqDCoMKgwqAgLyogQ29weSBTZWN1cmUgT1MgYmluYXJ5IHRvIFBTUCBtZW1vcnkgKi8KPj4+ PiAtwqDCoMKgIG1lbWNweShwc3AtPmZ3X3ByaV9idWYsIHBzcC0+c29zX3N0YXJ0X2FkZHIsIHBz cC0+c29zX2Jpbl9zaXplKTsKPj4+PiArwqDCoMKgIHBzcF9jb3B5X2Z3KHBzcCwgcHNwLT5zb3Nf c3RhcnRfYWRkciwgcHNwLT5zb3NfYmluX3NpemUpOwo+Pj4+IMKgwqDCoMKgwqAgLyogUHJvdmlk ZSB0aGUgUFNQIHNlY3VyZSBPUyB0byBib290bG9hZGVyICovCj4+Pj4gwqDCoMKgwqDCoCBXUkVH MzJfU09DMTUoTVAwLCAwLCBtbU1QMF9TTU5fQzJQTVNHXzM2LAo+Pj4+IEBAIC02MDgsNyArNjAx LDcgQEAgc3RhdGljIGludCBwc3BfdjExXzBfbWVtb3J5X3RyYWluaW5nKHN0cnVjdCAKPj4+PiBw c3BfY29udGV4dCAqcHNwLCB1aW50MzJfdCBvcHMpCj4+Pj4gwqDCoMKgwqDCoCB1aW50MzJfdCBw MmNfaGVhZGVyWzRdOwo+Pj4+IMKgwqDCoMKgwqAgdWludDMyX3Qgc3o7Cj4+Pj4gwqDCoMKgwqDC oCB2b2lkICpidWY7Cj4+Pj4gLcKgwqDCoCBpbnQgcmV0Owo+Pj4+ICvCoMKgwqAgaW50IHJldCwg aWR4Owo+Pj4+IMKgwqDCoMKgwqAgaWYgKGN0eC0+aW5pdCA9PSBQU1BfTUVNX1RSQUlOX05PVF9T VVBQT1JUKSB7Cj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIERSTV9ERUJVRygiTWVtb3J5IHRyYWlu aW5nIGlzIG5vdCBzdXBwb3J0ZWQuXG4iKTsKPj4+PiBAQCAtNjgxLDE3ICs2NzQsMjQgQEAgc3Rh dGljIGludCBwc3BfdjExXzBfbWVtb3J5X3RyYWluaW5nKHN0cnVjdCAKPj4+PiBwc3BfY29udGV4 dCAqcHNwLCB1aW50MzJfdCBvcHMpCj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0 dXJuIC1FTk9NRU07Cj4+Pj4gwqDCoMKgwqDCoMKgwqDCoMKgIH0KPj4+PiAtwqDCoMKgwqDCoMKg wqAgbWVtY3B5X2Zyb21pbyhidWYsIGFkZXYtPm1tYW4uYXBlcl9iYXNlX2thZGRyLCBzeik7Cj4+ Pj4gLcKgwqDCoMKgwqDCoMKgIHJldCA9IHBzcF92MTFfMF9tZW1vcnlfdHJhaW5pbmdfc2VuZF9t c2cocHNwLCAKPj4+PiBQU1BfQkxfX0RSQU1fTE9OR19UUkFJTik7Cj4+Pj4gLcKgwqDCoMKgwqDC oMKgIGlmIChyZXQpIHsKPj4+PiAtwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBEUk1fRVJST1IoIlNl bmQgbG9uZyB0cmFpbmluZyBtc2cgZmFpbGVkLlxuIik7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgIGlm IChkcm1fZGV2X2VudGVyKCZhZGV2LT5kZGV2LCAmaWR4KSkgewo+Pj4+ICvCoMKgwqDCoMKgwqDC oMKgwqDCoMKgIG1lbWNweV9mcm9taW8oYnVmLCBhZGV2LT5tbWFuLmFwZXJfYmFzZV9rYWRkciwg c3opOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldCA9IHBzcF92MTFfMF9tZW1vcnlf dHJhaW5pbmdfc2VuZF9tc2cocHNwLCAKPj4+PiBQU1BfQkxfX0RSQU1fTE9OR19UUkFJTik7Cj4+ Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKHJldCkgewo+Pj4+ICvCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqAgRFJNX0VSUk9SKCJTZW5kIGxvbmcgdHJhaW5pbmcgbXNnIGZhaWxl ZC5cbiIpOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdmZyZWUoYnVmKTsK Pj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGRybV9kZXZfZXhpdChpZHgpOwo+ Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4+PiArwqDC oMKgwqDCoMKgwqDCoMKgwqDCoCB9Cj4+Pj4gKwo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKg IG1lbWNweV90b2lvKGFkZXYtPm1tYW4uYXBlcl9iYXNlX2thZGRyLCBidWYsIHN6KTsKPj4+PiAr wqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBhZGV2LT5oZHAuZnVuY3MtPmZsdXNoX2hkcChhZGV2LCBO VUxMKTsKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB2ZnJlZShidWYpOwo+Pj4+IC3C oMKgwqDCoMKgwqDCoMKgwqDCoMKgIHJldHVybiByZXQ7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDC oMKgwqAgZHJtX2Rldl9leGl0KGlkeCk7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgIH0gZWxzZSB7Cj4+ Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdmZyZWUoYnVmKTsKPj4+PiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCByZXR1cm4gLUVOT0RFVjsKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgfQo+Pj4+ IC0KPj4+PiAtwqDCoMKgwqDCoMKgwqAgbWVtY3B5X3RvaW8oYWRldi0+bW1hbi5hcGVyX2Jhc2Vf a2FkZHIsIGJ1Ziwgc3opOwo+Pj4+IC3CoMKgwqDCoMKgwqDCoCBhZGV2LT5oZHAuZnVuY3MtPmZs dXNoX2hkcChhZGV2LCBOVUxMKTsKPj4+PiAtwqDCoMKgwqDCoMKgwqAgdmZyZWUoYnVmKTsKPj4+ PiDCoMKgwqDCoMKgIH0KPj4+PiDCoMKgwqDCoMKgIGlmIChvcHMgJiBQU1BfTUVNX1RSQUlOX1NB VkUpIHsKPj4+PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRncHUvcHNwX3Yx Ml8wLmMgCj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9wc3BfdjEyXzAuYwo+Pj4+ IGluZGV4IGM0ODI4YmQzMjY0Yi4uNjE4ZTViNmI4NWQ5IDEwMDY0NAo+Pj4+IC0tLSBhL2RyaXZl cnMvZ3B1L2RybS9hbWQvYW1kZ3B1L3BzcF92MTJfMC5jCj4+Pj4gKysrIGIvZHJpdmVycy9ncHUv ZHJtL2FtZC9hbWRncHUvcHNwX3YxMl8wLmMKPj4+PiBAQCAtMTM4LDEwICsxMzgsOCBAQCBzdGF0 aWMgaW50IAo+Pj4+IHBzcF92MTJfMF9ib290bG9hZGVyX2xvYWRfc3lzZHJ2KHN0cnVjdCBwc3Bf Y29udGV4dCAqcHNwKQo+Pj4+IMKgwqDCoMKgwqAgaWYgKHJldCkKPj4+PiDCoMKgwqDCoMKgwqDC oMKgwqAgcmV0dXJuIHJldDsKPj4+PiAtwqDCoMKgIG1lbXNldChwc3AtPmZ3X3ByaV9idWYsIDAs IFBTUF8xX01FRyk7Cj4+Pj4gLQo+Pj4+IMKgwqDCoMKgwqAgLyogQ29weSBQU1AgU3lzdGVtIERy aXZlciBiaW5hcnkgdG8gbWVtb3J5ICovCj4+Pj4gLcKgwqDCoCBtZW1jcHkocHNwLT5md19wcmlf YnVmLCBwc3AtPnN5c19zdGFydF9hZGRyLCBwc3AtPnN5c19iaW5fc2l6ZSk7Cj4+Pj4gK8KgwqDC oCBwc3BfY29weV9mdyhwc3AsIHBzcC0+c3lzX3N0YXJ0X2FkZHIsIHBzcC0+c3lzX2Jpbl9zaXpl KTsKPj4+PiDCoMKgwqDCoMKgIC8qIFByb3ZpZGUgdGhlIHN5cyBkcml2ZXIgdG8gYm9vdGxvYWRl ciAqLwo+Pj4+IMKgwqDCoMKgwqAgV1JFRzMyX1NPQzE1KE1QMCwgMCwgbW1NUDBfU01OX0MyUE1T R18zNiwKPj4+PiBAQCAtMTc5LDEwICsxNzcsOCBAQCBzdGF0aWMgaW50IAo+Pj4+IHBzcF92MTJf MF9ib290bG9hZGVyX2xvYWRfc29zKHN0cnVjdCBwc3BfY29udGV4dCAqcHNwKQo+Pj4+IMKgwqDC oMKgwqAgaWYgKHJldCkKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4+PiAt wqDCoMKgIG1lbXNldChwc3AtPmZ3X3ByaV9idWYsIDAsIFBTUF8xX01FRyk7Cj4+Pj4gLQo+Pj4+ IMKgwqDCoMKgwqAgLyogQ29weSBTZWN1cmUgT1MgYmluYXJ5IHRvIFBTUCBtZW1vcnkgKi8KPj4+ PiAtwqDCoMKgIG1lbWNweShwc3AtPmZ3X3ByaV9idWYsIHBzcC0+c29zX3N0YXJ0X2FkZHIsIHBz cC0+c29zX2Jpbl9zaXplKTsKPj4+PiArwqDCoMKgIHBzcF9jb3B5X2Z3KHBzcCwgcHNwLT5zb3Nf c3RhcnRfYWRkciwgcHNwLT5zb3NfYmluX3NpemUpOwo+Pj4+IMKgwqDCoMKgwqAgLyogUHJvdmlk ZSB0aGUgUFNQIHNlY3VyZSBPUyB0byBib290bG9hZGVyICovCj4+Pj4gwqDCoMKgwqDCoCBXUkVH MzJfU09DMTUoTVAwLCAwLCBtbU1QMF9TTU5fQzJQTVNHXzM2LAo+Pj4+IGRpZmYgLS1naXQgYS9k cml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9wc3BfdjNfMS5jIAo+Pj4+IGIvZHJpdmVycy9ncHUv ZHJtL2FtZC9hbWRncHUvcHNwX3YzXzEuYwo+Pj4+IGluZGV4IGYyZTcyNWY3MmQyZi4uZDBhNmNj Y2QwODk3IDEwMDY0NAo+Pj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L3BzcF92 M18xLmMKPj4+PiArKysgYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS9wc3BfdjNfMS5jCj4+ Pj4gQEAgLTEwMiwxMCArMTAyLDggQEAgc3RhdGljIGludCAKPj4+PiBwc3BfdjNfMV9ib290bG9h ZGVyX2xvYWRfc3lzZHJ2KHN0cnVjdCBwc3BfY29udGV4dCAqcHNwKQo+Pj4+IMKgwqDCoMKgwqAg aWYgKHJldCkKPj4+PiDCoMKgwqDCoMKgwqDCoMKgwqAgcmV0dXJuIHJldDsKPj4+PiAtwqDCoMKg IG1lbXNldChwc3AtPmZ3X3ByaV9idWYsIDAsIFBTUF8xX01FRyk7Cj4+Pj4gLQo+Pj4+IMKgwqDC oMKgwqAgLyogQ29weSBQU1AgU3lzdGVtIERyaXZlciBiaW5hcnkgdG8gbWVtb3J5ICovCj4+Pj4g LcKgwqDCoCBtZW1jcHkocHNwLT5md19wcmlfYnVmLCBwc3AtPnN5c19zdGFydF9hZGRyLCBwc3At PnN5c19iaW5fc2l6ZSk7Cj4+Pj4gK8KgwqDCoCBwc3BfY29weV9mdyhwc3AsIHBzcC0+c3lzX3N0 YXJ0X2FkZHIsIHBzcC0+c3lzX2Jpbl9zaXplKTsKPj4+PiDCoMKgwqDCoMKgIC8qIFByb3ZpZGUg dGhlIHN5cyBkcml2ZXIgdG8gYm9vdGxvYWRlciAqLwo+Pj4+IMKgwqDCoMKgwqAgV1JFRzMyX1NP QzE1KE1QMCwgMCwgbW1NUDBfU01OX0MyUE1TR18zNiwKPj4+PiBAQCAtMTQzLDEwICsxNDEsOCBA QCBzdGF0aWMgaW50IHBzcF92M18xX2Jvb3Rsb2FkZXJfbG9hZF9zb3Moc3RydWN0IAo+Pj4+IHBz cF9jb250ZXh0ICpwc3ApCj4+Pj4gwqDCoMKgwqDCoCBpZiAocmV0KQo+Pj4+IMKgwqDCoMKgwqDC oMKgwqDCoCByZXR1cm4gcmV0Owo+Pj4+IC3CoMKgwqAgbWVtc2V0KHBzcC0+ZndfcHJpX2J1Ziwg MCwgUFNQXzFfTUVHKTsKPj4+PiAtCj4+Pj4gwqDCoMKgwqDCoCAvKiBDb3B5IFNlY3VyZSBPUyBi aW5hcnkgdG8gUFNQIG1lbW9yeSAqLwo+Pj4+IC3CoMKgwqAgbWVtY3B5KHBzcC0+ZndfcHJpX2J1 ZiwgcHNwLT5zb3Nfc3RhcnRfYWRkciwgcHNwLT5zb3NfYmluX3NpemUpOwo+Pj4+ICvCoMKgwqAg cHNwX2NvcHlfZncocHNwLCBwc3AtPnNvc19zdGFydF9hZGRyLCBwc3AtPnNvc19iaW5fc2l6ZSk7 Cj4+Pj4gwqDCoMKgwqDCoCAvKiBQcm92aWRlIHRoZSBQU1Agc2VjdXJlIE9TIHRvIGJvb3Rsb2Fk ZXIgKi8KPj4+PiDCoMKgwqDCoMKgIFdSRUczMl9TT0MxNShNUDAsIDAsIG1tTVAwX1NNTl9DMlBN U0dfMzYsCj4+Pj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L3ZjZV92 NF8wLmMgCj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS92Y2VfdjRfMC5jCj4+Pj4g aW5kZXggOGUyMzhkZWE3YmVmLi45MDkxMGQxOWRiMTIgMTAwNjQ0Cj4+Pj4gLS0tIGEvZHJpdmVy cy9ncHUvZHJtL2FtZC9hbWRncHUvdmNlX3Y0XzAuYwo+Pj4+ICsrKyBiL2RyaXZlcnMvZ3B1L2Ry bS9hbWQvYW1kZ3B1L3ZjZV92NF8wLmMKPj4+PiBAQCAtMjUsNiArMjUsNyBAQAo+Pj4+IMKgwqAg Ki8KPj4+PiDCoCAjaW5jbHVkZSA8bGludXgvZmlybXdhcmUuaD4KPj4+PiArI2luY2x1ZGUgPGRy bS9kcm1fZHJ2Lmg+Cj4+Pj4gwqAgI2luY2x1ZGUgImFtZGdwdS5oIgo+Pj4+IMKgICNpbmNsdWRl ICJhbWRncHVfdmNlLmgiCj4+Pj4gQEAgLTU1NSwxNiArNTU2LDE5IEBAIHN0YXRpYyBpbnQgdmNl X3Y0XzBfaHdfZmluaSh2b2lkICpoYW5kbGUpCj4+Pj4gwqAgc3RhdGljIGludCB2Y2VfdjRfMF9z dXNwZW5kKHZvaWQgKmhhbmRsZSkKPj4+PiDCoCB7Cj4+Pj4gwqDCoMKgwqDCoCBzdHJ1Y3QgYW1k Z3B1X2RldmljZSAqYWRldiA9IChzdHJ1Y3QgYW1kZ3B1X2RldmljZSAqKWhhbmRsZTsKPj4+PiAt wqDCoMKgIGludCByOwo+Pj4+ICvCoMKgwqAgaW50IHIsIGlkeDsKPj4+PiDCoMKgwqDCoMKgIGlm IChhZGV2LT52Y2UudmNwdV9ibyA9PSBOVUxMKQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1 cm4gMDsKPj4+PiAtwqDCoMKgIGlmIChhZGV2LT5maXJtd2FyZS5sb2FkX3R5cGUgPT0gQU1ER1BV X0ZXX0xPQURfUFNQKSB7Cj4+Pj4gLcKgwqDCoMKgwqDCoMKgIHVuc2lnbmVkIHNpemUgPSBhbWRn cHVfYm9fc2l6ZShhZGV2LT52Y2UudmNwdV9ibyk7Cj4+Pj4gLcKgwqDCoMKgwqDCoMKgIHZvaWQg KnB0ciA9IGFkZXYtPnZjZS5jcHVfYWRkcjsKPj4+PiArwqDCoMKgIGlmIChkcm1fZGV2X2VudGVy KCZhZGV2LT5kZGV2LCAmaWR4KSkgewo+Pj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAoYWRldi0+Zmly bXdhcmUubG9hZF90eXBlID09IEFNREdQVV9GV19MT0FEX1BTUCkgewo+Pj4+ICvCoMKgwqDCoMKg wqDCoMKgwqDCoMKgIHVuc2lnbmVkIHNpemUgPSBhbWRncHVfYm9fc2l6ZShhZGV2LT52Y2UudmNw dV9ibyk7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgdm9pZCAqcHRyID0gYWRldi0+dmNl LmNwdV9hZGRyOwo+Pj4+IC3CoMKgwqDCoMKgwqDCoCBtZW1jcHlfZnJvbWlvKGFkZXYtPnZjZS5z YXZlZF9ibywgcHRyLCBzaXplKTsKPj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBtZW1jcHlf ZnJvbWlvKGFkZXYtPnZjZS5zYXZlZF9ibywgcHRyLCBzaXplKTsKPj4+PiArwqDCoMKgwqDCoMKg wqAgfQo+Pj4+ICvCoMKgwqDCoMKgwqDCoCBkcm1fZGV2X2V4aXQoaWR4KTsKPj4+PiDCoMKgwqDC oMKgIH0KPj4+PiDCoMKgwqDCoMKgIHIgPSB2Y2VfdjRfMF9od19maW5pKGFkZXYpOwo+Pj4+IEBA IC01NzcsMTYgKzU4MSwyMCBAQCBzdGF0aWMgaW50IHZjZV92NF8wX3N1c3BlbmQodm9pZCAqaGFu ZGxlKQo+Pj4+IMKgIHN0YXRpYyBpbnQgdmNlX3Y0XzBfcmVzdW1lKHZvaWQgKmhhbmRsZSkKPj4+ PiDCoCB7Cj4+Pj4gwqDCoMKgwqDCoCBzdHJ1Y3QgYW1kZ3B1X2RldmljZSAqYWRldiA9IChzdHJ1 Y3QgYW1kZ3B1X2RldmljZSAqKWhhbmRsZTsKPj4+PiAtwqDCoMKgIGludCByOwo+Pj4+ICvCoMKg wqAgaW50IHIsIGlkeDsKPj4+PiDCoMKgwqDCoMKgIGlmIChhZGV2LT52Y2UudmNwdV9ibyA9PSBO VUxMKQo+Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCByZXR1cm4gLUVJTlZBTDsKPj4+PiDCoMKgwqDC oMKgIGlmIChhZGV2LT5maXJtd2FyZS5sb2FkX3R5cGUgPT0gQU1ER1BVX0ZXX0xPQURfUFNQKSB7 Cj4+Pj4gLcKgwqDCoMKgwqDCoMKgIHVuc2lnbmVkIHNpemUgPSBhbWRncHVfYm9fc2l6ZShhZGV2 LT52Y2UudmNwdV9ibyk7Cj4+Pj4gLcKgwqDCoMKgwqDCoMKgIHZvaWQgKnB0ciA9IGFkZXYtPnZj ZS5jcHVfYWRkcjsKPj4+PiAtwqDCoMKgwqDCoMKgwqAgbWVtY3B5X3RvaW8ocHRyLCBhZGV2LT52 Y2Uuc2F2ZWRfYm8sIHNpemUpOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoCBpZiAoZHJtX2Rldl9lbnRl cigmYWRldi0+ZGRldiwgJmlkeCkpIHsKPj4+PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCB1bnNp Z25lZCBzaXplID0gYW1kZ3B1X2JvX3NpemUoYWRldi0+dmNlLnZjcHVfYm8pOwo+Pj4+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgIHZvaWQgKnB0ciA9IGFkZXYtPnZjZS5jcHVfYWRkcjsKPj4+PiAr Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgbWVtY3B5X3RvaW8ocHRyLCBhZGV2LT52Y2Uu c2F2ZWRfYm8sIHNpemUpOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGRybV9kZXZfZXhp dChpZHgpOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoCB9Cj4+Pj4gwqDCoMKgwqDCoCB9IGVsc2Ugewo+ Pj4+IMKgwqDCoMKgwqDCoMKgwqDCoCByID0gYW1kZ3B1X3ZjZV9yZXN1bWUoYWRldik7Cj4+Pj4g wqDCoMKgwqDCoMKgwqDCoMKgIGlmIChyKQo+Pj4+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9k cm0vYW1kL2FtZGdwdS92Y25fdjNfMC5jIAo+Pj4+IGIvZHJpdmVycy9ncHUvZHJtL2FtZC9hbWRn cHUvdmNuX3YzXzAuYwo+Pj4+IGluZGV4IDNmMTViZjM0MTIzYS4uZGYzNGJlOGVjODJkIDEwMDY0 NAo+Pj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvYW1kZ3B1L3Zjbl92M18wLmMKPj4+PiAr KysgYi9kcml2ZXJzL2dwdS9kcm0vYW1kL2FtZGdwdS92Y25fdjNfMC5jCj4+Pj4gQEAgLTM0LDYg KzM0LDggQEAKPj4+PiDCoCAjaW5jbHVkZSAidmNuL3Zjbl8zXzBfMF9zaF9tYXNrLmgiCj4+Pj4g wqAgI2luY2x1ZGUgIml2c3JjaWQvdmNuL2lycXNyY3NfdmNuXzJfMC5oIgo+Pj4+ICsjaW5jbHVk ZSA8ZHJtL2RybV9kcnYuaD4KPj4+PiArCj4+Pj4gwqAgI2RlZmluZSBtbVVWRF9DT05URVhUX0lE X0lOVEVSTkFMX09GRlNFVMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgMHgyNwo+Pj4+IMKgICNkZWZp bmUgbW1VVkRfR1BDT01fVkNQVV9DTURfSU5URVJOQUxfT0ZGU0VUIDB4MGYKPj4+PiDCoCAjZGVm aW5lIG1tVVZEX0dQQ09NX1ZDUFVfREFUQTBfSU5URVJOQUxfT0ZGU0VUIDB4MTAKPj4+PiBAQCAt MjY4LDE2ICsyNzAsMjAgQEAgc3RhdGljIGludCB2Y25fdjNfMF9zd19pbml0KHZvaWQgKmhhbmRs ZSkKPj4+PiDCoCBzdGF0aWMgaW50IHZjbl92M18wX3N3X2Zpbmkodm9pZCAqaGFuZGxlKQo+Pj4+ IMKgIHsKPj4+PiDCoMKgwqDCoMKgIHN0cnVjdCBhbWRncHVfZGV2aWNlICphZGV2ID0gKHN0cnVj dCBhbWRncHVfZGV2aWNlICopaGFuZGxlOwo+Pj4+IC3CoMKgwqAgaW50IGksIHI7Cj4+Pj4gK8Kg wqDCoCBpbnQgaSwgciwgaWR4Owo+Pj4+IC3CoMKgwqAgZm9yIChpID0gMDsgaSA8IGFkZXYtPnZj bi5udW1fdmNuX2luc3Q7IGkrKykgewo+Pj4+IC3CoMKgwqDCoMKgwqDCoCB2b2xhdGlsZSBzdHJ1 Y3QgYW1kZ3B1X2Z3X3NoYXJlZCAqZndfc2hhcmVkOwo+Pj4+ICvCoMKgwqAgaWYgKGRybV9kZXZf ZW50ZXIoJmFkZXYtPmRkZXYsICZpZHgpKSB7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgIGZvciAoaSA9 IDA7IGkgPCBhZGV2LT52Y24ubnVtX3Zjbl9pbnN0OyBpKyspIHsKPj4+PiArwqDCoMKgwqDCoMKg wqDCoMKgwqDCoCB2b2xhdGlsZSBzdHJ1Y3QgYW1kZ3B1X2Z3X3NoYXJlZCAqZndfc2hhcmVkOwo+ Pj4+IC3CoMKgwqDCoMKgwqDCoCBpZiAoYWRldi0+dmNuLmhhcnZlc3RfY29uZmlnICYgKDEgPDwg aSkpCj4+Pj4gLcKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY29udGludWU7Cj4+Pj4gLcKgwqDCoMKg wqDCoMKgIGZ3X3NoYXJlZCA9IGFkZXYtPnZjbi5pbnN0W2ldLmZ3X3NoYXJlZF9jcHVfYWRkcjsK Pj4+PiAtwqDCoMKgwqDCoMKgwqAgZndfc2hhcmVkLT5wcmVzZW50X2ZsYWdfMCA9IDA7Cj4+Pj4g LcKgwqDCoMKgwqDCoMKgIGZ3X3NoYXJlZC0+c3dfcmluZy5pc19lbmFibGVkID0gZmFsc2U7Cj4+ Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgaWYgKGFkZXYtPnZjbi5oYXJ2ZXN0X2NvbmZpZyAm ICgxIDw8IGkpKQo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqAgY29udGludWU7 Cj4+Pj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqAgZndfc2hhcmVkID0gYWRldi0+dmNuLmluc3Rb aV0uZndfc2hhcmVkX2NwdV9hZGRyOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGZ3X3No YXJlZC0+cHJlc2VudF9mbGFnXzAgPSAwOwo+Pj4+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIGZ3 X3NoYXJlZC0+c3dfcmluZy5pc19lbmFibGVkID0gZmFsc2U7Cj4+Pj4gK8KgwqDCoMKgwqDCoMKg IH0KPj4+PiArCj4+Pj4gK8KgwqDCoMKgwqDCoMKgIGRybV9kZXZfZXhpdChpZHgpOwo+Pj4+IMKg wqDCoMKgwqAgfQo+Pj4+IMKgwqDCoMKgwqAgaWYgKGFtZGdwdV9zcmlvdl92ZihhZGV2KSkKPj4+ PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2FtZC9wbS9wb3dlcnBsYXkvc211bWdyL3Nt dTdfc211bWdyLmMgCj4+Pj4gYi9kcml2ZXJzL2dwdS9kcm0vYW1kL3BtL3Bvd2VycGxheS9zbXVt Z3Ivc211N19zbXVtZ3IuYwo+Pj4+IGluZGV4IGFhZTI1MjQzZWIxMC4uZDYyOGI5MTg0NmM5IDEw MDY0NAo+Pj4+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9hbWQvcG0vcG93ZXJwbGF5L3NtdW1nci9z bXU3X3NtdW1nci5jCj4+Pj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2FtZC9wbS9wb3dlcnBsYXkv c211bWdyL3NtdTdfc211bWdyLmMKPj4+PiBAQCAtNDA1LDYgKzQwNSw4IEBAIGludCBzbXU3X3Jl cXVlc3Rfc211X2xvYWRfZncoc3RydWN0IHBwX2h3bWdyIAo+Pj4+ICpod21ncikKPj4+PiDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgIFVDT0RFX0lEX01FQ19TVE9SQUdFLCAKPj4+ PiAmdG9jLT5lbnRyeVt0b2MtPm51bV9lbnRyaWVzKytdKSwKPj4+PiDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgICJGYWlsZWQgdG8gR2V0IEZpcm13YXJlIEVudHJ5LiIsIHIgPSAt RUlOVkFMOyAKPj4+PiBnb3RvIGZhaWxlZCk7Cj4+Pj4gwqDCoMKgwqDCoCB9Cj4+Pj4gKwo+Pj4+ ICvCoMKgwqAgLyogQUcgVE9ETyBDYW4ndCBjYWxsIGRybV9kZXZfZW50ZXIvZXhpdCBiZWNhdXNl IGFjY2VzcyAKPj4+PiBhZGV2LT5kZGV2IGhlcmUgLi4uICovCj4+Pj4gwqDCoMKgwqDCoCBtZW1j cHlfdG9pbyhzbXVfZGF0YS0+aGVhZGVyX2J1ZmZlci5rYWRkciwgc211X2RhdGEtPnRvYywKPj4+ PiDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCBzaXplb2Yoc3RydWN0IFNNVV9EUkFNRGF0YV9U T0MpKTsKPj4+PiDCoMKgwqDCoMKgIHNtdW1fc2VuZF9tc2dfdG9fc21jX3dpdGhfcGFyYW1ldGVy KGh3bWdyLAo+Pj4KCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fCmFtZC1nZnggbWFpbGluZyBsaXN0CmFtZC1nZnhAbGlzdHMuZnJlZWRlc2t0b3Aub3JnCmh0 dHBzOi8vbGlzdHMuZnJlZWRlc2t0b3Aub3JnL21haWxtYW4vbGlzdGluZm8vYW1kLWdmeAo= 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 X-Spam-Level: X-Spam-Status: No, score=-14.2 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C7061C433ED for ; Wed, 12 May 2021 14:06:25 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 81FF861413 for ; Wed, 12 May 2021 14:06:25 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230353AbhELOHc (ORCPT ); Wed, 12 May 2021 10:07:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57042 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230338AbhELOHb (ORCPT ); Wed, 12 May 2021 10:07:31 -0400 Received: from mail-ed1-x530.google.com (mail-ed1-x530.google.com [IPv6:2a00:1450:4864:20::530]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE45FC06174A for ; Wed, 12 May 2021 07:06:20 -0700 (PDT) Received: by mail-ed1-x530.google.com with SMTP id n25so27235506edr.5 for ; Wed, 12 May 2021 07:06:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding:content-language; bh=D6pHKTcVLI3s2kmC/tuhuU6NBUj7V+KFfP9rb+MWD9M=; b=ZbJHTbndRqixSt9sp8AM3pHQSqH81l5Y6aZTWCdxgrpw/0YgXAEJ6myX8rAR0PBgrZ zMeuDainJ4Yvlfb+6qrbeTANZXlKZCE0vguPRb3pqbJri090cZKE2+p38PHL/R/Qm+OP NIDr/32pYrqgR2//vBZku9Whwe9qmSx3pIRTi5SkoVdQ6hDoTvDX+5DglKTJ5bheR2tx NiWQQk/H+PcXiFnlIfkEhQY9OcM7gjJRvmHkXp9m6vLR+1J9ssZ3vTuon2KBQiuKAgeY YEThKiK/hUY2XqKrX6DkBjyGSis7QW5LZPUT1qFnb+FxC+vtV8wdPHFkSTcm84+83B6V hXdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=D6pHKTcVLI3s2kmC/tuhuU6NBUj7V+KFfP9rb+MWD9M=; b=s2XORUX1W9TqYcSYQR4XM5BE6LT2xBF5dlsPOHzUyBhl6xpc9cbopu8elVZ51p06Gj +0/UForT9F54DN75QWhG+J2jbOE6m81agSJ+5Ify7vJG/09P+DUU4NOFA0gbJx08DGq+ JyHuCwAi1gqp640nmSIEJjATZTjJeArBdnOaPNmft00pmb1YaAFYpbktvK+QOmWU1z78 8H+Mcl89L0nLl2t+UU1hCE5P4IlNmq2p3HY4QRNZ0uy6+DhCt+MGjBUpVsxPUE+YLWj5 mF4rVvQu7orJVLaro8gpQ7c1Nw9r0VhkAjKH95JTkKDfdE3FTDikqFGbOwy6MfizjVI8 mGhg== X-Gm-Message-State: AOAM531mpOY/iM8g/F+3IyPxjwUOgsvqEhbgTGXaa/NPn313Aq+XZnnL eZX3MWMUnQ+qVF+LW/R9fLw= X-Google-Smtp-Source: ABdhPJxiKsTHipPbWVJ64GPlWD8cpCSwHAT7KOwJVVdh/z6uTMvnrlVGZ9Zt0/rN/JyGFjldy/mqkQ== X-Received: by 2002:a05:6402:51d3:: with SMTP id r19mr43279881edd.360.1620828379389; Wed, 12 May 2021 07:06:19 -0700 (PDT) Received: from ?IPv6:2a02:908:1252:fb60:c533:38e4:26b8:d73? ([2a02:908:1252:fb60:c533:38e4:26b8:d73]) by smtp.gmail.com with ESMTPSA id h9sm17210007ede.93.2021.05.12.07.06.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 12 May 2021 07:06:18 -0700 (PDT) Subject: Re: [PATCH v6 10/16] drm/amdgpu: Guard against write accesses after device removal To: Andrey Grodzovsky , dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, linux-pci@vger.kernel.org, daniel.vetter@ffwll.ch, Harry.Wentland@amd.com Cc: ppaalanen@gmail.com, Alexander.Deucher@amd.com, gregkh@linuxfoundation.org, helgaas@kernel.org, Felix.Kuehling@amd.com References: <20210510163625.407105-1-andrey.grodzovsky@amd.com> <20210510163625.407105-11-andrey.grodzovsky@amd.com> <19ec5ffa-48a7-863d-0b5a-5c2a43d65e81@gmail.com> <8f1bae42-7567-9f7e-d891-8eb92af3e58a@amd.com> From: =?UTF-8?Q?Christian_K=c3=b6nig?= Message-ID: <4bcbc970-eaff-6321-0f6c-c662c53bfc32@gmail.com> Date: Wed, 12 May 2021 16:06:17 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.1 MIME-Version: 1.0 In-Reply-To: <8f1bae42-7567-9f7e-d891-8eb92af3e58a@amd.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Am 12.05.21 um 16:01 schrieb Andrey Grodzovsky: > Ping - need a confirmation it's ok to keep this as a single patch given > my explanation bellow. It was just an suggestion. Key point is the approach sounds sane to me, but I can't say much about the psp code for example. So maximum I can give you is an Acked-by for that. Christian. > > Andrey > > On 2021-05-11 1:52 p.m., Andrey Grodzovsky wrote: >> >> >> On 2021-05-11 2:50 a.m., Christian König wrote: >>> Am 10.05.21 um 18:36 schrieb Andrey Grodzovsky: >>>> This should prevent writing to memory or IO ranges possibly >>>> already allocated for other uses after our device is removed. >>>> >>>> v5: >>>> Protect more places wher memcopy_to/form_io takes place >>>> Protect IB submissions >>>> >>>> v6: Switch to !drm_dev_enter instead of scoping entire code >>>> with brackets. >>>> >>>> Signed-off-by: Andrey Grodzovsky >>>> --- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 11 ++- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c       |  9 +++ >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c        | 17 +++-- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c       | 63 +++++++++++------ >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h       |  2 + >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c      | 70 >>>> +++++++++++++++++++ >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h      | 49 ++----------- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c       | 31 +++++--- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c       | 11 ++- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c       | 22 ++++-- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c        |  7 +- >>>>   drivers/gpu/drm/amd/amdgpu/psp_v11_0.c        | 44 ++++++------ >>>>   drivers/gpu/drm/amd/amdgpu/psp_v12_0.c        |  8 +-- >>>>   drivers/gpu/drm/amd/amdgpu/psp_v3_1.c         |  8 +-- >>>>   drivers/gpu/drm/amd/amdgpu/vce_v4_0.c         | 26 ++++--- >>>>   drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c         | 22 +++--- >>>>   .../drm/amd/pm/powerplay/smumgr/smu7_smumgr.c |  2 + >>>>   17 files changed, 257 insertions(+), 145 deletions(-) >>>> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >>>> index a0bff4713672..94c415176cdc 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >>>> @@ -71,6 +71,8 @@ >>>>   #include >>>>   #include >>>> +#include >>>> + >>>>   MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin"); >>>>   MODULE_FIRMWARE("amdgpu/vega12_gpu_info.bin"); >>>>   MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); >>>> @@ -281,7 +283,10 @@ void amdgpu_device_vram_access(struct >>>> amdgpu_device *adev, loff_t pos, >>>>       unsigned long flags; >>>>       uint32_t hi = ~0; >>>>       uint64_t last; >>>> +    int idx; >>>> +     if (!drm_dev_enter(&adev->ddev, &idx)) >>>> +         return; >>>>   #ifdef CONFIG_64BIT >>>>       last = min(pos + size, adev->gmc.visible_vram_size); >>>> @@ -299,8 +304,10 @@ void amdgpu_device_vram_access(struct >>>> amdgpu_device *adev, loff_t pos, >>>>               memcpy_fromio(buf, addr, count); >>>>           } >>>> -        if (count == size) >>>> +        if (count == size) { >>>> +            drm_dev_exit(idx); >>>>               return; >>>> +        } >>> >>> Maybe use a goto instead, but really just a nit pick. >>> >>> >>> >>>>           pos += count; >>>>           buf += count / 4; >>>> @@ -323,6 +330,8 @@ void amdgpu_device_vram_access(struct >>>> amdgpu_device *adev, loff_t pos, >>>>               *buf++ = RREG32_NO_KIQ(mmMM_DATA); >>>>       } >>>>       spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); >>>> + >>>> +    drm_dev_exit(idx); >>>>   } >>>>   /* >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c >>>> index 4d32233cde92..04ba5eef1e88 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c >>>> @@ -31,6 +31,8 @@ >>>>   #include "amdgpu_ras.h" >>>>   #include "amdgpu_xgmi.h" >>>> +#include >>>> + >>>>   /** >>>>    * amdgpu_gmc_pdb0_alloc - allocate vram for pdb0 >>>>    * >>>> @@ -151,6 +153,10 @@ int amdgpu_gmc_set_pte_pde(struct >>>> amdgpu_device *adev, void *cpu_pt_addr, >>>>   { >>>>       void __iomem *ptr = (void *)cpu_pt_addr; >>>>       uint64_t value; >>>> +    int idx; >>>> + >>>> +    if (!drm_dev_enter(&adev->ddev, &idx)) >>>> +        return 0; >>>>       /* >>>>        * The following is for PTE only. GART does not have PDEs. >>>> @@ -158,6 +164,9 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device >>>> *adev, void *cpu_pt_addr, >>>>       value = addr & 0x0000FFFFFFFFF000ULL; >>>>       value |= flags; >>>>       writeq(value, ptr + (gpu_page_idx * 8)); >>>> + >>>> +    drm_dev_exit(idx); >>>> + >>>>       return 0; >>>>   } >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>>> index 148a3b481b12..62fcbd446c71 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>>> @@ -30,6 +30,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "atom.h" >>>> @@ -137,7 +138,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>       bool secure; >>>>       unsigned i; >>>> -    int r = 0; >>>> +    int idx, r = 0; >>>>       bool need_pipe_sync = false; >>>>       if (num_ibs == 0) >>>> @@ -169,13 +170,16 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>           return -EINVAL; >>>>       } >>>> +    if (!drm_dev_enter(&adev->ddev, &idx)) >>>> +        return -ENODEV; >>>> + >>>>       alloc_size = ring->funcs->emit_frame_size + num_ibs * >>>>           ring->funcs->emit_ib_size; >>>>       r = amdgpu_ring_alloc(ring, alloc_size); >>>>       if (r) { >>>>           dev_err(adev->dev, "scheduling IB failed (%d).\n", r); >>>> -        return r; >>>> +        goto exit; >>>>       } >>>>       need_ctx_switch = ring->current_ctx != fence_ctx; >>>> @@ -205,7 +209,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>           r = amdgpu_vm_flush(ring, job, need_pipe_sync); >>>>           if (r) { >>>>               amdgpu_ring_undo(ring); >>>> -            return r; >>>> +            goto exit; >>>>           } >>>>       } >>>> @@ -286,7 +290,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>           if (job && job->vmid) >>>>               amdgpu_vmid_reset(adev, ring->funcs->vmhub, job->vmid); >>>>           amdgpu_ring_undo(ring); >>>> -        return r; >>>> +        goto exit; >>>>       } >>>>       if (ring->funcs->insert_end) >>>> @@ -304,7 +308,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>           ring->funcs->emit_wave_limit(ring, false); >>>>       amdgpu_ring_commit(ring); >>>> -    return 0; >>>> + >>>> +exit: >>>> +    drm_dev_exit(idx); >>>> +    return r; >>>>   } >>>>   /** >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c >>>> index 9e769cf6095b..bb6afee61666 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c >>>> @@ -25,6 +25,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_psp.h" >>>> @@ -39,6 +40,8 @@ >>>>   #include "amdgpu_ras.h" >>>>   #include "amdgpu_securedisplay.h" >>>> +#include >>>> + >>>>   static int psp_sysfs_init(struct amdgpu_device *adev); >>>>   static void psp_sysfs_fini(struct amdgpu_device *adev); >>>> @@ -253,7 +256,7 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>              struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr) >>>>   { >>>>       int ret; >>>> -    int index; >>>> +    int index, idx; >>>>       int timeout = 20000; >>>>       bool ras_intr = false; >>>>       bool skip_unsupport = false; >>>> @@ -261,6 +264,9 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>       if (psp->adev->in_pci_err_recovery) >>>>           return 0; >>>> +    if (!drm_dev_enter(&psp->adev->ddev, &idx)) >>>> +        return 0; >>>> + >>>>       mutex_lock(&psp->mutex); >>>>       memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE); >>>> @@ -271,8 +277,7 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>       ret = psp_ring_cmd_submit(psp, psp->cmd_buf_mc_addr, >>>> fence_mc_addr, index); >>>>       if (ret) { >>>>           atomic_dec(&psp->fence_value); >>>> -        mutex_unlock(&psp->mutex); >>>> -        return ret; >>>> +        goto exit; >>>>       } >>>>       amdgpu_asic_invalidate_hdp(psp->adev, NULL); >>>> @@ -312,8 +317,8 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>                psp->cmd_buf_mem->cmd_id, >>>>                psp->cmd_buf_mem->resp.status); >>>>           if (!timeout) { >>>> -            mutex_unlock(&psp->mutex); >>>> -            return -EINVAL; >>>> +            ret = -EINVAL; >>>> +            goto exit; >>>>           } >>>>       } >>>> @@ -321,8 +326,10 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>           ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo; >>>>           ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi; >>>>       } >>>> -    mutex_unlock(&psp->mutex); >>>> +exit: >>>> +    mutex_unlock(&psp->mutex); >>>> +    drm_dev_exit(idx); >>>>       return ret; >>>>   } >>>> @@ -359,8 +366,7 @@ static int psp_load_toc(struct psp_context *psp, >>>>       if (!cmd) >>>>           return -ENOMEM; >>>>       /* Copy toc to psp firmware private buffer */ >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->toc_start_addr, psp->toc_bin_size); >>>> +    psp_copy_fw(psp, psp->toc_start_addr, psp->toc_bin_size); >>>>       psp_prep_load_toc_cmd_buf(cmd, psp->fw_pri_mc_addr, >>>> psp->toc_bin_size); >>>> @@ -625,8 +631,7 @@ static int psp_asd_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->asd_start_addr, >>>> psp->asd_ucode_size); >>>> +    psp_copy_fw(psp, psp->asd_start_addr, psp->asd_ucode_size); >>>>       psp_prep_asd_load_cmd_buf(cmd, psp->fw_pri_mc_addr, >>>>                     psp->asd_ucode_size); >>>> @@ -781,8 +786,7 @@ static int psp_xgmi_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_xgmi_start_addr, >>>> psp->ta_xgmi_ucode_size); >>>> +    psp_copy_fw(psp, psp->ta_xgmi_start_addr, >>>> psp->ta_xgmi_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>>                    psp->fw_pri_mc_addr, >>>> @@ -1038,8 +1042,7 @@ static int psp_ras_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_ras_start_addr, >>>> psp->ta_ras_ucode_size); >>>> +    psp_copy_fw(psp, psp->ta_ras_start_addr, psp->ta_ras_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>>                    psp->fw_pri_mc_addr, >>>> @@ -1275,8 +1278,7 @@ static int psp_hdcp_load(struct psp_context >>>> *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_hdcp_start_addr, >>>> +    psp_copy_fw(psp, psp->ta_hdcp_start_addr, >>>>              psp->ta_hdcp_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>> @@ -1427,8 +1429,7 @@ static int psp_dtm_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_dtm_start_addr, >>>> psp->ta_dtm_ucode_size); >>>> +    psp_copy_fw(psp, psp->ta_dtm_start_addr, psp->ta_dtm_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>>                    psp->fw_pri_mc_addr, >>>> @@ -1573,8 +1574,7 @@ static int psp_rap_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_rap_start_addr, >>>> psp->ta_rap_ucode_size); >>>> +    psp_copy_fw(psp, psp->ta_rap_start_addr, psp->ta_rap_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>>                    psp->fw_pri_mc_addr, >>>> @@ -3022,7 +3022,7 @@ static ssize_t >>>> psp_usbc_pd_fw_sysfs_write(struct device *dev, >>>>       struct amdgpu_device *adev = drm_to_adev(ddev); >>>>       void *cpu_addr; >>>>       dma_addr_t dma_addr; >>>> -    int ret; >>>> +    int ret, idx; >>>>       char fw_name[100]; >>>>       const struct firmware *usbc_pd_fw; >>>> @@ -3031,6 +3031,9 @@ static ssize_t >>>> psp_usbc_pd_fw_sysfs_write(struct device *dev, >>>>           return -EBUSY; >>>>       } >>>> +    if (!drm_dev_enter(ddev, &idx)) >>>> +        return -ENODEV; >>>> + >>>>       snprintf(fw_name, sizeof(fw_name), "amdgpu/%s", buf); >>>>       ret = request_firmware(&usbc_pd_fw, fw_name, adev->dev); >>>>       if (ret) >>>> @@ -3062,16 +3065,30 @@ static ssize_t >>>> psp_usbc_pd_fw_sysfs_write(struct device *dev, >>>>   rel_buf: >>>>       dma_free_coherent(adev->dev, usbc_pd_fw->size, cpu_addr, >>>> dma_addr); >>>>       release_firmware(usbc_pd_fw); >>>> - >>>>   fail: >>>>       if (ret) { >>>>           DRM_ERROR("Failed to load USBC PD FW, err = %d", ret); >>>> -        return ret; >>>> +        count = ret; >>>>       } >>>> +    drm_dev_exit(idx); >>>>       return count; >>>>   } >>>> +void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, >>>> uint32_t bin_size) >>>> +{ >>>> +    int idx; >>>> + >>>> +    if (!drm_dev_enter(&psp->adev->ddev, &idx)) >>>> +        return; >>>> + >>>> +    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> +    memcpy(psp->fw_pri_buf, start_addr, bin_size); >>>> + >>>> +    drm_dev_exit(idx); >>>> +} >>>> + >>>> + >>>>   static DEVICE_ATTR(usbc_pd_fw, S_IRUGO | S_IWUSR, >>>>              psp_usbc_pd_fw_sysfs_read, >>>>              psp_usbc_pd_fw_sysfs_write); >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h >>>> index 46a5328e00e0..2bfdc278817f 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h >>>> @@ -423,4 +423,6 @@ int psp_get_fw_attestation_records_addr(struct >>>> psp_context *psp, >>>>   int psp_load_fw_list(struct psp_context *psp, >>>>                struct amdgpu_firmware_info **ucode_list, int >>>> ucode_count); >>>> +void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, >>>> uint32_t bin_size); >>>> + >>>>   #endif >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c >>>> index 688624ebe421..e1985bc34436 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c >>>> @@ -35,6 +35,8 @@ >>>>   #include "amdgpu.h" >>>>   #include "atom.h" >>>> +#include >>>> + >>>>   /* >>>>    * Rings >>>>    * Most engines on the GPU are fed via ring buffers.  Ring >>>> @@ -461,3 +463,71 @@ int amdgpu_ring_test_helper(struct amdgpu_ring >>>> *ring) >>>>       ring->sched.ready = !r; >>>>       return r; >>>>   } >>>> + >>>> +void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) >>>> +{ >>>> +    int idx; >>>> +    int i = 0; >>>> + >>>> +    if (!drm_dev_enter(&ring->adev->ddev, &idx)) >>>> +        return; >>>> + >>>> +    while (i <= ring->buf_mask) >>>> +        ring->ring[i++] = ring->funcs->nop; >>>> + >>>> +    drm_dev_exit(idx); >>>> + >>>> +} >>>> + >>>> +void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v) >>>> +{ >>>> +    int idx; >>>> + >>>> +    if (!drm_dev_enter(&ring->adev->ddev, &idx)) >>>> +        return; >>>> + >>>> +    if (ring->count_dw <= 0) >>>> +        DRM_ERROR("amdgpu: writing more dwords to the ring than >>>> expected!\n"); >>>> +    ring->ring[ring->wptr++ & ring->buf_mask] = v; >>>> +    ring->wptr &= ring->ptr_mask; >>>> +    ring->count_dw--; >>>> + >>>> +    drm_dev_exit(idx); >>>> +} >>>> + >>>> +void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, >>>> +                          void *src, int count_dw) >>>> +{ >>>> +    unsigned occupied, chunk1, chunk2; >>>> +    void *dst; >>>> +    int idx; >>>> + >>>> +    if (!drm_dev_enter(&ring->adev->ddev, &idx)) >>>> +        return; >>>> + >>>> +    if (unlikely(ring->count_dw < count_dw)) >>>> +        DRM_ERROR("amdgpu: writing more dwords to the ring than >>>> expected!\n"); >>>> + >>>> +    occupied = ring->wptr & ring->buf_mask; >>>> +    dst = (void *)&ring->ring[occupied]; >>>> +    chunk1 = ring->buf_mask + 1 - occupied; >>>> +    chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1; >>>> +    chunk2 = count_dw - chunk1; >>>> +    chunk1 <<= 2; >>>> +    chunk2 <<= 2; >>>> + >>>> +    if (chunk1) >>>> +        memcpy(dst, src, chunk1); >>>> + >>>> +    if (chunk2) { >>>> +        src += chunk1; >>>> +        dst = (void *)ring->ring; >>>> +        memcpy(dst, src, chunk2); >>>> +    } >>>> + >>>> +    ring->wptr += count_dw; >>>> +    ring->wptr &= ring->ptr_mask; >>>> +    ring->count_dw -= count_dw; >>>> + >>>> +    drm_dev_exit(idx); >>>> +} >>> >>> The ring should never we in MMIO memory, so you can completely drop >>> that as far as I can see. >> >> Yea, it's in all in GART, missed it for some reason... >>> >>> Maybe split that patch by use case so that we can more easily >>> review/ack it. >> >> In fact everything here is the same use case, once I added unmap of >> all MMIO ranges (both registers ann VRAM) i got a lot of page faults >> on device remove around any memcpy to from IO. That where I put the >> drn_dev_enter/exit scope. Also I searched in code and preemeptivly >> added guards to any other such place. I did drop amdgpu_schedule_ib >> from this patch both because it had dma_fence_wait inside and so we >> will take care of this once we decide on how to handle dma_fence waits. >> >> Andrey >> >>> >>> Thanks, >>> Christian. >>> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>>> index e7d3d0dbdd96..c67bc6d3d039 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>>> @@ -299,53 +299,12 @@ static inline void >>>> amdgpu_ring_set_preempt_cond_exec(struct amdgpu_ring *ring, >>>>       *ring->cond_exe_cpu_addr = cond_exec; >>>>   } >>>> -static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) >>>> -{ >>>> -    int i = 0; >>>> -    while (i <= ring->buf_mask) >>>> -        ring->ring[i++] = ring->funcs->nop; >>>> - >>>> -} >>>> - >>>> -static inline void amdgpu_ring_write(struct amdgpu_ring *ring, >>>> uint32_t v) >>>> -{ >>>> -    if (ring->count_dw <= 0) >>>> -        DRM_ERROR("amdgpu: writing more dwords to the ring than >>>> expected!\n"); >>>> -    ring->ring[ring->wptr++ & ring->buf_mask] = v; >>>> -    ring->wptr &= ring->ptr_mask; >>>> -    ring->count_dw--; >>>> -} >>>> +void amdgpu_ring_clear_ring(struct amdgpu_ring *ring); >>>> -static inline void amdgpu_ring_write_multiple(struct amdgpu_ring >>>> *ring, >>>> -                          void *src, int count_dw) >>>> -{ >>>> -    unsigned occupied, chunk1, chunk2; >>>> -    void *dst; >>>> - >>>> -    if (unlikely(ring->count_dw < count_dw)) >>>> -        DRM_ERROR("amdgpu: writing more dwords to the ring than >>>> expected!\n"); >>>> - >>>> -    occupied = ring->wptr & ring->buf_mask; >>>> -    dst = (void *)&ring->ring[occupied]; >>>> -    chunk1 = ring->buf_mask + 1 - occupied; >>>> -    chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1; >>>> -    chunk2 = count_dw - chunk1; >>>> -    chunk1 <<= 2; >>>> -    chunk2 <<= 2; >>>> +void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v); >>>> -    if (chunk1) >>>> -        memcpy(dst, src, chunk1); >>>> - >>>> -    if (chunk2) { >>>> -        src += chunk1; >>>> -        dst = (void *)ring->ring; >>>> -        memcpy(dst, src, chunk2); >>>> -    } >>>> - >>>> -    ring->wptr += count_dw; >>>> -    ring->wptr &= ring->ptr_mask; >>>> -    ring->count_dw -= count_dw; >>>> -} >>>> +void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, >>>> +                          void *src, int count_dw); >>>>   int amdgpu_ring_test_helper(struct amdgpu_ring *ring); >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c >>>> index c6dbc0801604..82f0542c7792 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c >>>> @@ -32,6 +32,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_pm.h" >>>> @@ -375,7 +376,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) >>>>   { >>>>       unsigned size; >>>>       void *ptr; >>>> -    int i, j; >>>> +    int i, j, idx; >>>>       bool in_ras_intr = amdgpu_ras_intr_triggered(); >>>>       cancel_delayed_work_sync(&adev->uvd.idle_work); >>>> @@ -403,11 +404,15 @@ int amdgpu_uvd_suspend(struct amdgpu_device >>>> *adev) >>>>           if (!adev->uvd.inst[j].saved_bo) >>>>               return -ENOMEM; >>>> -        /* re-write 0 since err_event_athub will corrupt VCPU >>>> buffer */ >>>> -        if (in_ras_intr) >>>> -            memset(adev->uvd.inst[j].saved_bo, 0, size); >>>> -        else >>>> -            memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size); >>>> +        if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +            /* re-write 0 since err_event_athub will corrupt VCPU >>>> buffer */ >>>> +            if (in_ras_intr) >>>> +                memset(adev->uvd.inst[j].saved_bo, 0, size); >>>> +            else >>>> + memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size); >>>> + >>>> +            drm_dev_exit(idx); >>>> +        } >>>>       } >>>>       if (in_ras_intr) >>>> @@ -420,7 +425,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) >>>>   { >>>>       unsigned size; >>>>       void *ptr; >>>> -    int i; >>>> +    int i, idx; >>>>       for (i = 0; i < adev->uvd.num_uvd_inst; i++) { >>>>           if (adev->uvd.harvest_config & (1 << i)) >>>> @@ -432,7 +437,10 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) >>>>           ptr = adev->uvd.inst[i].cpu_addr; >>>>           if (adev->uvd.inst[i].saved_bo != NULL) { >>>> -            memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size); >>>> +            if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +                memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size); >>>> +                drm_dev_exit(idx); >>>> +            } >>>>               kvfree(adev->uvd.inst[i].saved_bo); >>>>               adev->uvd.inst[i].saved_bo = NULL; >>>>           } else { >>>> @@ -442,8 +450,11 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) >>>>               hdr = (const struct common_firmware_header >>>> *)adev->uvd.fw->data; >>>>               if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { >>>>                   offset = le32_to_cpu(hdr->ucode_array_offset_bytes); >>>> -                memcpy_toio(adev->uvd.inst[i].cpu_addr, >>>> adev->uvd.fw->data + offset, >>>> - le32_to_cpu(hdr->ucode_size_bytes)); >>>> +                if (drm_dev_enter(&adev->ddev, &idx)) { >>>> + memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset, >>>> + le32_to_cpu(hdr->ucode_size_bytes)); >>>> +                    drm_dev_exit(idx); >>>> +                } >>>>                   size -= le32_to_cpu(hdr->ucode_size_bytes); >>>>                   ptr += le32_to_cpu(hdr->ucode_size_bytes); >>>>               } >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c >>>> index ea6a62f67e38..833203401ef4 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c >>>> @@ -29,6 +29,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_pm.h" >>>> @@ -293,7 +294,7 @@ int amdgpu_vce_resume(struct amdgpu_device *adev) >>>>       void *cpu_addr; >>>>       const struct common_firmware_header *hdr; >>>>       unsigned offset; >>>> -    int r; >>>> +    int r, idx; >>>>       if (adev->vce.vcpu_bo == NULL) >>>>           return -EINVAL; >>>> @@ -313,8 +314,12 @@ int amdgpu_vce_resume(struct amdgpu_device *adev) >>>>       hdr = (const struct common_firmware_header *)adev->vce.fw->data; >>>>       offset = le32_to_cpu(hdr->ucode_array_offset_bytes); >>>> -    memcpy_toio(cpu_addr, adev->vce.fw->data + offset, >>>> -            adev->vce.fw->size - offset); >>>> + >>>> +    if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +        memcpy_toio(cpu_addr, adev->vce.fw->data + offset, >>>> +                adev->vce.fw->size - offset); >>>> +        drm_dev_exit(idx); >>>> +    } >>>>       amdgpu_bo_kunmap(adev->vce.vcpu_bo); >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c >>>> index 201645963ba5..21f7d3644d70 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c >>>> @@ -27,6 +27,7 @@ >>>>   #include >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_pm.h" >>>> @@ -275,7 +276,7 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev) >>>>   { >>>>       unsigned size; >>>>       void *ptr; >>>> -    int i; >>>> +    int i, idx; >>>>       cancel_delayed_work_sync(&adev->vcn.idle_work); >>>> @@ -292,7 +293,10 @@ int amdgpu_vcn_suspend(struct amdgpu_device >>>> *adev) >>>>           if (!adev->vcn.inst[i].saved_bo) >>>>               return -ENOMEM; >>>> -        memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size); >>>> +        if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +            memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size); >>>> +            drm_dev_exit(idx); >>>> +        } >>>>       } >>>>       return 0; >>>>   } >>>> @@ -301,7 +305,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) >>>>   { >>>>       unsigned size; >>>>       void *ptr; >>>> -    int i; >>>> +    int i, idx; >>>>       for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { >>>>           if (adev->vcn.harvest_config & (1 << i)) >>>> @@ -313,7 +317,10 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) >>>>           ptr = adev->vcn.inst[i].cpu_addr; >>>>           if (adev->vcn.inst[i].saved_bo != NULL) { >>>> -            memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size); >>>> +            if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +                memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size); >>>> +                drm_dev_exit(idx); >>>> +            } >>>>               kvfree(adev->vcn.inst[i].saved_bo); >>>>               adev->vcn.inst[i].saved_bo = NULL; >>>>           } else { >>>> @@ -323,8 +330,11 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) >>>>               hdr = (const struct common_firmware_header >>>> *)adev->vcn.fw->data; >>>>               if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { >>>>                   offset = le32_to_cpu(hdr->ucode_array_offset_bytes); >>>> -                memcpy_toio(adev->vcn.inst[i].cpu_addr, >>>> adev->vcn.fw->data + offset, >>>> - le32_to_cpu(hdr->ucode_size_bytes)); >>>> +                if (drm_dev_enter(&adev->ddev, &idx)) { >>>> + memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset, >>>> + le32_to_cpu(hdr->ucode_size_bytes)); >>>> +                    drm_dev_exit(idx); >>>> +                } >>>>                   size -= le32_to_cpu(hdr->ucode_size_bytes); >>>>                   ptr += le32_to_cpu(hdr->ucode_size_bytes); >>>>               } >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >>>> index 9f868cf3b832..7dd5f10ab570 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >>>> @@ -32,6 +32,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_trace.h" >>>>   #include "amdgpu_amdkfd.h" >>>> @@ -1606,7 +1607,10 @@ static int >>>> amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, >>>>       struct amdgpu_vm_update_params params; >>>>       enum amdgpu_sync_mode sync_mode; >>>>       uint64_t pfn; >>>> -    int r; >>>> +    int r, idx; >>>> + >>>> +    if (!drm_dev_enter(&adev->ddev, &idx)) >>>> +        return -ENODEV; >>>>       memset(¶ms, 0, sizeof(params)); >>>>       params.adev = adev; >>>> @@ -1715,6 +1719,7 @@ static int amdgpu_vm_bo_update_mapping(struct >>>> amdgpu_device *adev, >>>>   error_unlock: >>>>       amdgpu_vm_eviction_unlock(vm); >>>> +    drm_dev_exit(idx); >>>>       return r; >>>>   } >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c >>>> b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c >>>> index 589410c32d09..2cec71e823f5 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c >>>> @@ -23,6 +23,7 @@ >>>>   #include >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_psp.h" >>>> @@ -269,10 +270,8 @@ static int >>>> psp_v11_0_bootloader_load_kdb(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP KDB binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->kdb_start_addr, psp->kdb_bin_size); >>>> +    psp_copy_fw(psp, psp->kdb_start_addr, psp->kdb_bin_size); >>>>       /* Provide the PSP KDB to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -302,10 +301,8 @@ static int >>>> psp_v11_0_bootloader_load_spl(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP SPL binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->spl_start_addr, psp->spl_bin_size); >>>> +    psp_copy_fw(psp, psp->spl_start_addr, psp->spl_bin_size); >>>>       /* Provide the PSP SPL to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -335,10 +332,8 @@ static int >>>> psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP System Driver binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); >>>> +    psp_copy_fw(psp, psp->sys_start_addr, psp->sys_bin_size); >>>>       /* Provide the sys driver to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -371,10 +366,8 @@ static int >>>> psp_v11_0_bootloader_load_sos(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy Secure OS binary to PSP memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); >>>> +    psp_copy_fw(psp, psp->sos_start_addr, psp->sos_bin_size); >>>>       /* Provide the PSP secure OS to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -608,7 +601,7 @@ static int psp_v11_0_memory_training(struct >>>> psp_context *psp, uint32_t ops) >>>>       uint32_t p2c_header[4]; >>>>       uint32_t sz; >>>>       void *buf; >>>> -    int ret; >>>> +    int ret, idx; >>>>       if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) { >>>>           DRM_DEBUG("Memory training is not supported.\n"); >>>> @@ -681,17 +674,24 @@ static int psp_v11_0_memory_training(struct >>>> psp_context *psp, uint32_t ops) >>>>               return -ENOMEM; >>>>           } >>>> -        memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz); >>>> -        ret = psp_v11_0_memory_training_send_msg(psp, >>>> PSP_BL__DRAM_LONG_TRAIN); >>>> -        if (ret) { >>>> -            DRM_ERROR("Send long training msg failed.\n"); >>>> +        if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +            memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz); >>>> +            ret = psp_v11_0_memory_training_send_msg(psp, >>>> PSP_BL__DRAM_LONG_TRAIN); >>>> +            if (ret) { >>>> +                DRM_ERROR("Send long training msg failed.\n"); >>>> +                vfree(buf); >>>> +                drm_dev_exit(idx); >>>> +                return ret; >>>> +            } >>>> + >>>> +            memcpy_toio(adev->mman.aper_base_kaddr, buf, sz); >>>> +            adev->hdp.funcs->flush_hdp(adev, NULL); >>>>               vfree(buf); >>>> -            return ret; >>>> +            drm_dev_exit(idx); >>>> +        } else { >>>> +            vfree(buf); >>>> +            return -ENODEV; >>>>           } >>>> - >>>> -        memcpy_toio(adev->mman.aper_base_kaddr, buf, sz); >>>> -        adev->hdp.funcs->flush_hdp(adev, NULL); >>>> -        vfree(buf); >>>>       } >>>>       if (ops & PSP_MEM_TRAIN_SAVE) { >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c >>>> b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c >>>> index c4828bd3264b..618e5b6b85d9 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c >>>> @@ -138,10 +138,8 @@ static int >>>> psp_v12_0_bootloader_load_sysdrv(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP System Driver binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); >>>> +    psp_copy_fw(psp, psp->sys_start_addr, psp->sys_bin_size); >>>>       /* Provide the sys driver to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -179,10 +177,8 @@ static int >>>> psp_v12_0_bootloader_load_sos(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy Secure OS binary to PSP memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); >>>> +    psp_copy_fw(psp, psp->sos_start_addr, psp->sos_bin_size); >>>>       /* Provide the PSP secure OS to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c >>>> b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c >>>> index f2e725f72d2f..d0a6cccd0897 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c >>>> @@ -102,10 +102,8 @@ static int >>>> psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP System Driver binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); >>>> +    psp_copy_fw(psp, psp->sys_start_addr, psp->sys_bin_size); >>>>       /* Provide the sys driver to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -143,10 +141,8 @@ static int psp_v3_1_bootloader_load_sos(struct >>>> psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy Secure OS binary to PSP memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); >>>> +    psp_copy_fw(psp, psp->sos_start_addr, psp->sos_bin_size); >>>>       /* Provide the PSP secure OS to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c >>>> b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c >>>> index 8e238dea7bef..90910d19db12 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c >>>> @@ -25,6 +25,7 @@ >>>>    */ >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_vce.h" >>>> @@ -555,16 +556,19 @@ static int vce_v4_0_hw_fini(void *handle) >>>>   static int vce_v4_0_suspend(void *handle) >>>>   { >>>>       struct amdgpu_device *adev = (struct amdgpu_device *)handle; >>>> -    int r; >>>> +    int r, idx; >>>>       if (adev->vce.vcpu_bo == NULL) >>>>           return 0; >>>> -    if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { >>>> -        unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); >>>> -        void *ptr = adev->vce.cpu_addr; >>>> +    if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +        if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { >>>> +            unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); >>>> +            void *ptr = adev->vce.cpu_addr; >>>> -        memcpy_fromio(adev->vce.saved_bo, ptr, size); >>>> +            memcpy_fromio(adev->vce.saved_bo, ptr, size); >>>> +        } >>>> +        drm_dev_exit(idx); >>>>       } >>>>       r = vce_v4_0_hw_fini(adev); >>>> @@ -577,16 +581,20 @@ static int vce_v4_0_suspend(void *handle) >>>>   static int vce_v4_0_resume(void *handle) >>>>   { >>>>       struct amdgpu_device *adev = (struct amdgpu_device *)handle; >>>> -    int r; >>>> +    int r, idx; >>>>       if (adev->vce.vcpu_bo == NULL) >>>>           return -EINVAL; >>>>       if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { >>>> -        unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); >>>> -        void *ptr = adev->vce.cpu_addr; >>>> -        memcpy_toio(ptr, adev->vce.saved_bo, size); >>>> +        if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +            unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); >>>> +            void *ptr = adev->vce.cpu_addr; >>>> + >>>> +            memcpy_toio(ptr, adev->vce.saved_bo, size); >>>> +            drm_dev_exit(idx); >>>> +        } >>>>       } else { >>>>           r = amdgpu_vce_resume(adev); >>>>           if (r) >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c >>>> b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c >>>> index 3f15bf34123a..df34be8ec82d 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c >>>> @@ -34,6 +34,8 @@ >>>>   #include "vcn/vcn_3_0_0_sh_mask.h" >>>>   #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h" >>>> +#include >>>> + >>>>   #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET            0x27 >>>>   #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f >>>>   #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET 0x10 >>>> @@ -268,16 +270,20 @@ static int vcn_v3_0_sw_init(void *handle) >>>>   static int vcn_v3_0_sw_fini(void *handle) >>>>   { >>>>       struct amdgpu_device *adev = (struct amdgpu_device *)handle; >>>> -    int i, r; >>>> +    int i, r, idx; >>>> -    for (i = 0; i < adev->vcn.num_vcn_inst; i++) { >>>> -        volatile struct amdgpu_fw_shared *fw_shared; >>>> +    if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +        for (i = 0; i < adev->vcn.num_vcn_inst; i++) { >>>> +            volatile struct amdgpu_fw_shared *fw_shared; >>>> -        if (adev->vcn.harvest_config & (1 << i)) >>>> -            continue; >>>> -        fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr; >>>> -        fw_shared->present_flag_0 = 0; >>>> -        fw_shared->sw_ring.is_enabled = false; >>>> +            if (adev->vcn.harvest_config & (1 << i)) >>>> +                continue; >>>> +            fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr; >>>> +            fw_shared->present_flag_0 = 0; >>>> +            fw_shared->sw_ring.is_enabled = false; >>>> +        } >>>> + >>>> +        drm_dev_exit(idx); >>>>       } >>>>       if (amdgpu_sriov_vf(adev)) >>>> diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c >>>> b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c >>>> index aae25243eb10..d628b91846c9 100644 >>>> --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c >>>> +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c >>>> @@ -405,6 +405,8 @@ int smu7_request_smu_load_fw(struct pp_hwmgr >>>> *hwmgr) >>>>                   UCODE_ID_MEC_STORAGE, >>>> &toc->entry[toc->num_entries++]), >>>>                   "Failed to Get Firmware Entry.", r = -EINVAL; >>>> goto failed); >>>>       } >>>> + >>>> +    /* AG TODO Can't call drm_dev_enter/exit because access >>>> adev->ddev here ... */ >>>>       memcpy_toio(smu_data->header_buffer.kaddr, smu_data->toc, >>>>               sizeof(struct SMU_DRAMData_TOC)); >>>>       smum_send_msg_to_smc_with_parameter(hwmgr, >>> 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 X-Spam-Level: X-Spam-Status: No, score=-12.0 required=3.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED,DKIM_INVALID,DKIM_SIGNED,FREEMAIL_FORGED_FROMDOMAIN, FREEMAIL_FROM,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 65B38C433B4 for ; Wed, 12 May 2021 14:06:23 +0000 (UTC) Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id E9D8361418 for ; Wed, 12 May 2021 14:06:22 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E9D8361418 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=dri-devel-bounces@lists.freedesktop.org Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 031266EC02; Wed, 12 May 2021 14:06:22 +0000 (UTC) Received: from mail-ed1-x52e.google.com (mail-ed1-x52e.google.com [IPv6:2a00:1450:4864:20::52e]) by gabe.freedesktop.org (Postfix) with ESMTPS id EF5466EC01; Wed, 12 May 2021 14:06:20 +0000 (UTC) Received: by mail-ed1-x52e.google.com with SMTP id l7so27269676edb.1; Wed, 12 May 2021 07:06:20 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=subject:to:cc:references:from:message-id:date:user-agent :mime-version:in-reply-to:content-transfer-encoding:content-language; bh=D6pHKTcVLI3s2kmC/tuhuU6NBUj7V+KFfP9rb+MWD9M=; b=ZbJHTbndRqixSt9sp8AM3pHQSqH81l5Y6aZTWCdxgrpw/0YgXAEJ6myX8rAR0PBgrZ zMeuDainJ4Yvlfb+6qrbeTANZXlKZCE0vguPRb3pqbJri090cZKE2+p38PHL/R/Qm+OP NIDr/32pYrqgR2//vBZku9Whwe9qmSx3pIRTi5SkoVdQ6hDoTvDX+5DglKTJ5bheR2tx NiWQQk/H+PcXiFnlIfkEhQY9OcM7gjJRvmHkXp9m6vLR+1J9ssZ3vTuon2KBQiuKAgeY YEThKiK/hUY2XqKrX6DkBjyGSis7QW5LZPUT1qFnb+FxC+vtV8wdPHFkSTcm84+83B6V hXdg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:subject:to:cc:references:from:message-id:date :user-agent:mime-version:in-reply-to:content-transfer-encoding :content-language; bh=D6pHKTcVLI3s2kmC/tuhuU6NBUj7V+KFfP9rb+MWD9M=; b=rnHokIVo9UH6I0hK8WYchUACiWS47BRFwzn61uGa/AlNpy9HJOLsdsHOsaNrIAJICg E8N9j+LdoMPlmBCtz4+d/V3q9BQhDLCiuWaZwgjZtyM4wJYjgvXD8iv3MHJr+R8NeNGK A/wdaHe8bgGGmiVas4GZPygUcQKE/iXcBMxjPYIQ/NmNTSUkYQlPmSFwyLMam4qzXXRP mspkXYd7zSdkq14RqRFOStNHdMeJCn38ke5UK2s4/kp5Sz8mvWfkHv31tX9A7OvX+kD6 DFaPDOJdCE5vvrBx2JU1pAmAnaT00PuQMWO/L24KY291k+B3NLWFILTZIw1Cf53SIBlp OSwg== X-Gm-Message-State: AOAM531qWxJMRJ81Wf3m1xh4243n5qKzCoLztDNkXfIfNJ76s1p2OCo0 AvLtdJmbIPuuuFq5HEP26mY= X-Google-Smtp-Source: ABdhPJxiKsTHipPbWVJ64GPlWD8cpCSwHAT7KOwJVVdh/z6uTMvnrlVGZ9Zt0/rN/JyGFjldy/mqkQ== X-Received: by 2002:a05:6402:51d3:: with SMTP id r19mr43279881edd.360.1620828379389; Wed, 12 May 2021 07:06:19 -0700 (PDT) Received: from ?IPv6:2a02:908:1252:fb60:c533:38e4:26b8:d73? ([2a02:908:1252:fb60:c533:38e4:26b8:d73]) by smtp.gmail.com with ESMTPSA id h9sm17210007ede.93.2021.05.12.07.06.18 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Wed, 12 May 2021 07:06:18 -0700 (PDT) Subject: Re: [PATCH v6 10/16] drm/amdgpu: Guard against write accesses after device removal To: Andrey Grodzovsky , dri-devel@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, linux-pci@vger.kernel.org, daniel.vetter@ffwll.ch, Harry.Wentland@amd.com References: <20210510163625.407105-1-andrey.grodzovsky@amd.com> <20210510163625.407105-11-andrey.grodzovsky@amd.com> <19ec5ffa-48a7-863d-0b5a-5c2a43d65e81@gmail.com> <8f1bae42-7567-9f7e-d891-8eb92af3e58a@amd.com> From: =?UTF-8?Q?Christian_K=c3=b6nig?= Message-ID: <4bcbc970-eaff-6321-0f6c-c662c53bfc32@gmail.com> Date: Wed, 12 May 2021 16:06:17 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.1 MIME-Version: 1.0 In-Reply-To: <8f1bae42-7567-9f7e-d891-8eb92af3e58a@amd.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 8bit Content-Language: en-US X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Alexander.Deucher@amd.com, gregkh@linuxfoundation.org, helgaas@kernel.org, Felix.Kuehling@amd.com Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" Am 12.05.21 um 16:01 schrieb Andrey Grodzovsky: > Ping - need a confirmation it's ok to keep this as a single patch given > my explanation bellow. It was just an suggestion. Key point is the approach sounds sane to me, but I can't say much about the psp code for example. So maximum I can give you is an Acked-by for that. Christian. > > Andrey > > On 2021-05-11 1:52 p.m., Andrey Grodzovsky wrote: >> >> >> On 2021-05-11 2:50 a.m., Christian König wrote: >>> Am 10.05.21 um 18:36 schrieb Andrey Grodzovsky: >>>> This should prevent writing to memory or IO ranges possibly >>>> already allocated for other uses after our device is removed. >>>> >>>> v5: >>>> Protect more places wher memcopy_to/form_io takes place >>>> Protect IB submissions >>>> >>>> v6: Switch to !drm_dev_enter instead of scoping entire code >>>> with brackets. >>>> >>>> Signed-off-by: Andrey Grodzovsky >>>> --- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_device.c    | 11 ++- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c       |  9 +++ >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c        | 17 +++-- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c       | 63 +++++++++++------ >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h       |  2 + >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c      | 70 >>>> +++++++++++++++++++ >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h      | 49 ++----------- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c       | 31 +++++--- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c       | 11 ++- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c       | 22 ++++-- >>>>   drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c        |  7 +- >>>>   drivers/gpu/drm/amd/amdgpu/psp_v11_0.c        | 44 ++++++------ >>>>   drivers/gpu/drm/amd/amdgpu/psp_v12_0.c        |  8 +-- >>>>   drivers/gpu/drm/amd/amdgpu/psp_v3_1.c         |  8 +-- >>>>   drivers/gpu/drm/amd/amdgpu/vce_v4_0.c         | 26 ++++--- >>>>   drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c         | 22 +++--- >>>>   .../drm/amd/pm/powerplay/smumgr/smu7_smumgr.c |  2 + >>>>   17 files changed, 257 insertions(+), 145 deletions(-) >>>> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >>>> index a0bff4713672..94c415176cdc 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c >>>> @@ -71,6 +71,8 @@ >>>>   #include >>>>   #include >>>> +#include >>>> + >>>>   MODULE_FIRMWARE("amdgpu/vega10_gpu_info.bin"); >>>>   MODULE_FIRMWARE("amdgpu/vega12_gpu_info.bin"); >>>>   MODULE_FIRMWARE("amdgpu/raven_gpu_info.bin"); >>>> @@ -281,7 +283,10 @@ void amdgpu_device_vram_access(struct >>>> amdgpu_device *adev, loff_t pos, >>>>       unsigned long flags; >>>>       uint32_t hi = ~0; >>>>       uint64_t last; >>>> +    int idx; >>>> +     if (!drm_dev_enter(&adev->ddev, &idx)) >>>> +         return; >>>>   #ifdef CONFIG_64BIT >>>>       last = min(pos + size, adev->gmc.visible_vram_size); >>>> @@ -299,8 +304,10 @@ void amdgpu_device_vram_access(struct >>>> amdgpu_device *adev, loff_t pos, >>>>               memcpy_fromio(buf, addr, count); >>>>           } >>>> -        if (count == size) >>>> +        if (count == size) { >>>> +            drm_dev_exit(idx); >>>>               return; >>>> +        } >>> >>> Maybe use a goto instead, but really just a nit pick. >>> >>> >>> >>>>           pos += count; >>>>           buf += count / 4; >>>> @@ -323,6 +330,8 @@ void amdgpu_device_vram_access(struct >>>> amdgpu_device *adev, loff_t pos, >>>>               *buf++ = RREG32_NO_KIQ(mmMM_DATA); >>>>       } >>>>       spin_unlock_irqrestore(&adev->mmio_idx_lock, flags); >>>> + >>>> +    drm_dev_exit(idx); >>>>   } >>>>   /* >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c >>>> index 4d32233cde92..04ba5eef1e88 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gmc.c >>>> @@ -31,6 +31,8 @@ >>>>   #include "amdgpu_ras.h" >>>>   #include "amdgpu_xgmi.h" >>>> +#include >>>> + >>>>   /** >>>>    * amdgpu_gmc_pdb0_alloc - allocate vram for pdb0 >>>>    * >>>> @@ -151,6 +153,10 @@ int amdgpu_gmc_set_pte_pde(struct >>>> amdgpu_device *adev, void *cpu_pt_addr, >>>>   { >>>>       void __iomem *ptr = (void *)cpu_pt_addr; >>>>       uint64_t value; >>>> +    int idx; >>>> + >>>> +    if (!drm_dev_enter(&adev->ddev, &idx)) >>>> +        return 0; >>>>       /* >>>>        * The following is for PTE only. GART does not have PDEs. >>>> @@ -158,6 +164,9 @@ int amdgpu_gmc_set_pte_pde(struct amdgpu_device >>>> *adev, void *cpu_pt_addr, >>>>       value = addr & 0x0000FFFFFFFFF000ULL; >>>>       value |= flags; >>>>       writeq(value, ptr + (gpu_page_idx * 8)); >>>> + >>>> +    drm_dev_exit(idx); >>>> + >>>>       return 0; >>>>   } >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>>> index 148a3b481b12..62fcbd446c71 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c >>>> @@ -30,6 +30,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "atom.h" >>>> @@ -137,7 +138,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>       bool secure; >>>>       unsigned i; >>>> -    int r = 0; >>>> +    int idx, r = 0; >>>>       bool need_pipe_sync = false; >>>>       if (num_ibs == 0) >>>> @@ -169,13 +170,16 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>           return -EINVAL; >>>>       } >>>> +    if (!drm_dev_enter(&adev->ddev, &idx)) >>>> +        return -ENODEV; >>>> + >>>>       alloc_size = ring->funcs->emit_frame_size + num_ibs * >>>>           ring->funcs->emit_ib_size; >>>>       r = amdgpu_ring_alloc(ring, alloc_size); >>>>       if (r) { >>>>           dev_err(adev->dev, "scheduling IB failed (%d).\n", r); >>>> -        return r; >>>> +        goto exit; >>>>       } >>>>       need_ctx_switch = ring->current_ctx != fence_ctx; >>>> @@ -205,7 +209,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>           r = amdgpu_vm_flush(ring, job, need_pipe_sync); >>>>           if (r) { >>>>               amdgpu_ring_undo(ring); >>>> -            return r; >>>> +            goto exit; >>>>           } >>>>       } >>>> @@ -286,7 +290,7 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>           if (job && job->vmid) >>>>               amdgpu_vmid_reset(adev, ring->funcs->vmhub, job->vmid); >>>>           amdgpu_ring_undo(ring); >>>> -        return r; >>>> +        goto exit; >>>>       } >>>>       if (ring->funcs->insert_end) >>>> @@ -304,7 +308,10 @@ int amdgpu_ib_schedule(struct amdgpu_ring >>>> *ring, unsigned num_ibs, >>>>           ring->funcs->emit_wave_limit(ring, false); >>>>       amdgpu_ring_commit(ring); >>>> -    return 0; >>>> + >>>> +exit: >>>> +    drm_dev_exit(idx); >>>> +    return r; >>>>   } >>>>   /** >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c >>>> index 9e769cf6095b..bb6afee61666 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.c >>>> @@ -25,6 +25,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_psp.h" >>>> @@ -39,6 +40,8 @@ >>>>   #include "amdgpu_ras.h" >>>>   #include "amdgpu_securedisplay.h" >>>> +#include >>>> + >>>>   static int psp_sysfs_init(struct amdgpu_device *adev); >>>>   static void psp_sysfs_fini(struct amdgpu_device *adev); >>>> @@ -253,7 +256,7 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>              struct psp_gfx_cmd_resp *cmd, uint64_t fence_mc_addr) >>>>   { >>>>       int ret; >>>> -    int index; >>>> +    int index, idx; >>>>       int timeout = 20000; >>>>       bool ras_intr = false; >>>>       bool skip_unsupport = false; >>>> @@ -261,6 +264,9 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>       if (psp->adev->in_pci_err_recovery) >>>>           return 0; >>>> +    if (!drm_dev_enter(&psp->adev->ddev, &idx)) >>>> +        return 0; >>>> + >>>>       mutex_lock(&psp->mutex); >>>>       memset(psp->cmd_buf_mem, 0, PSP_CMD_BUFFER_SIZE); >>>> @@ -271,8 +277,7 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>       ret = psp_ring_cmd_submit(psp, psp->cmd_buf_mc_addr, >>>> fence_mc_addr, index); >>>>       if (ret) { >>>>           atomic_dec(&psp->fence_value); >>>> -        mutex_unlock(&psp->mutex); >>>> -        return ret; >>>> +        goto exit; >>>>       } >>>>       amdgpu_asic_invalidate_hdp(psp->adev, NULL); >>>> @@ -312,8 +317,8 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>                psp->cmd_buf_mem->cmd_id, >>>>                psp->cmd_buf_mem->resp.status); >>>>           if (!timeout) { >>>> -            mutex_unlock(&psp->mutex); >>>> -            return -EINVAL; >>>> +            ret = -EINVAL; >>>> +            goto exit; >>>>           } >>>>       } >>>> @@ -321,8 +326,10 @@ psp_cmd_submit_buf(struct psp_context *psp, >>>>           ucode->tmr_mc_addr_lo = psp->cmd_buf_mem->resp.fw_addr_lo; >>>>           ucode->tmr_mc_addr_hi = psp->cmd_buf_mem->resp.fw_addr_hi; >>>>       } >>>> -    mutex_unlock(&psp->mutex); >>>> +exit: >>>> +    mutex_unlock(&psp->mutex); >>>> +    drm_dev_exit(idx); >>>>       return ret; >>>>   } >>>> @@ -359,8 +366,7 @@ static int psp_load_toc(struct psp_context *psp, >>>>       if (!cmd) >>>>           return -ENOMEM; >>>>       /* Copy toc to psp firmware private buffer */ >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->toc_start_addr, psp->toc_bin_size); >>>> +    psp_copy_fw(psp, psp->toc_start_addr, psp->toc_bin_size); >>>>       psp_prep_load_toc_cmd_buf(cmd, psp->fw_pri_mc_addr, >>>> psp->toc_bin_size); >>>> @@ -625,8 +631,7 @@ static int psp_asd_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->asd_start_addr, >>>> psp->asd_ucode_size); >>>> +    psp_copy_fw(psp, psp->asd_start_addr, psp->asd_ucode_size); >>>>       psp_prep_asd_load_cmd_buf(cmd, psp->fw_pri_mc_addr, >>>>                     psp->asd_ucode_size); >>>> @@ -781,8 +786,7 @@ static int psp_xgmi_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_xgmi_start_addr, >>>> psp->ta_xgmi_ucode_size); >>>> +    psp_copy_fw(psp, psp->ta_xgmi_start_addr, >>>> psp->ta_xgmi_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>>                    psp->fw_pri_mc_addr, >>>> @@ -1038,8 +1042,7 @@ static int psp_ras_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_ras_start_addr, >>>> psp->ta_ras_ucode_size); >>>> +    psp_copy_fw(psp, psp->ta_ras_start_addr, psp->ta_ras_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>>                    psp->fw_pri_mc_addr, >>>> @@ -1275,8 +1278,7 @@ static int psp_hdcp_load(struct psp_context >>>> *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_hdcp_start_addr, >>>> +    psp_copy_fw(psp, psp->ta_hdcp_start_addr, >>>>              psp->ta_hdcp_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>> @@ -1427,8 +1429,7 @@ static int psp_dtm_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_dtm_start_addr, >>>> psp->ta_dtm_ucode_size); >>>> +    psp_copy_fw(psp, psp->ta_dtm_start_addr, psp->ta_dtm_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>>                    psp->fw_pri_mc_addr, >>>> @@ -1573,8 +1574,7 @@ static int psp_rap_load(struct psp_context *psp) >>>>       if (!cmd) >>>>           return -ENOMEM; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> -    memcpy(psp->fw_pri_buf, psp->ta_rap_start_addr, >>>> psp->ta_rap_ucode_size); >>>> +    psp_copy_fw(psp, psp->ta_rap_start_addr, psp->ta_rap_ucode_size); >>>>       psp_prep_ta_load_cmd_buf(cmd, >>>>                    psp->fw_pri_mc_addr, >>>> @@ -3022,7 +3022,7 @@ static ssize_t >>>> psp_usbc_pd_fw_sysfs_write(struct device *dev, >>>>       struct amdgpu_device *adev = drm_to_adev(ddev); >>>>       void *cpu_addr; >>>>       dma_addr_t dma_addr; >>>> -    int ret; >>>> +    int ret, idx; >>>>       char fw_name[100]; >>>>       const struct firmware *usbc_pd_fw; >>>> @@ -3031,6 +3031,9 @@ static ssize_t >>>> psp_usbc_pd_fw_sysfs_write(struct device *dev, >>>>           return -EBUSY; >>>>       } >>>> +    if (!drm_dev_enter(ddev, &idx)) >>>> +        return -ENODEV; >>>> + >>>>       snprintf(fw_name, sizeof(fw_name), "amdgpu/%s", buf); >>>>       ret = request_firmware(&usbc_pd_fw, fw_name, adev->dev); >>>>       if (ret) >>>> @@ -3062,16 +3065,30 @@ static ssize_t >>>> psp_usbc_pd_fw_sysfs_write(struct device *dev, >>>>   rel_buf: >>>>       dma_free_coherent(adev->dev, usbc_pd_fw->size, cpu_addr, >>>> dma_addr); >>>>       release_firmware(usbc_pd_fw); >>>> - >>>>   fail: >>>>       if (ret) { >>>>           DRM_ERROR("Failed to load USBC PD FW, err = %d", ret); >>>> -        return ret; >>>> +        count = ret; >>>>       } >>>> +    drm_dev_exit(idx); >>>>       return count; >>>>   } >>>> +void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, >>>> uint32_t bin_size) >>>> +{ >>>> +    int idx; >>>> + >>>> +    if (!drm_dev_enter(&psp->adev->ddev, &idx)) >>>> +        return; >>>> + >>>> +    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> +    memcpy(psp->fw_pri_buf, start_addr, bin_size); >>>> + >>>> +    drm_dev_exit(idx); >>>> +} >>>> + >>>> + >>>>   static DEVICE_ATTR(usbc_pd_fw, S_IRUGO | S_IWUSR, >>>>              psp_usbc_pd_fw_sysfs_read, >>>>              psp_usbc_pd_fw_sysfs_write); >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h >>>> index 46a5328e00e0..2bfdc278817f 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_psp.h >>>> @@ -423,4 +423,6 @@ int psp_get_fw_attestation_records_addr(struct >>>> psp_context *psp, >>>>   int psp_load_fw_list(struct psp_context *psp, >>>>                struct amdgpu_firmware_info **ucode_list, int >>>> ucode_count); >>>> +void psp_copy_fw(struct psp_context *psp, uint8_t *start_addr, >>>> uint32_t bin_size); >>>> + >>>>   #endif >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c >>>> index 688624ebe421..e1985bc34436 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.c >>>> @@ -35,6 +35,8 @@ >>>>   #include "amdgpu.h" >>>>   #include "atom.h" >>>> +#include >>>> + >>>>   /* >>>>    * Rings >>>>    * Most engines on the GPU are fed via ring buffers.  Ring >>>> @@ -461,3 +463,71 @@ int amdgpu_ring_test_helper(struct amdgpu_ring >>>> *ring) >>>>       ring->sched.ready = !r; >>>>       return r; >>>>   } >>>> + >>>> +void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) >>>> +{ >>>> +    int idx; >>>> +    int i = 0; >>>> + >>>> +    if (!drm_dev_enter(&ring->adev->ddev, &idx)) >>>> +        return; >>>> + >>>> +    while (i <= ring->buf_mask) >>>> +        ring->ring[i++] = ring->funcs->nop; >>>> + >>>> +    drm_dev_exit(idx); >>>> + >>>> +} >>>> + >>>> +void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v) >>>> +{ >>>> +    int idx; >>>> + >>>> +    if (!drm_dev_enter(&ring->adev->ddev, &idx)) >>>> +        return; >>>> + >>>> +    if (ring->count_dw <= 0) >>>> +        DRM_ERROR("amdgpu: writing more dwords to the ring than >>>> expected!\n"); >>>> +    ring->ring[ring->wptr++ & ring->buf_mask] = v; >>>> +    ring->wptr &= ring->ptr_mask; >>>> +    ring->count_dw--; >>>> + >>>> +    drm_dev_exit(idx); >>>> +} >>>> + >>>> +void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, >>>> +                          void *src, int count_dw) >>>> +{ >>>> +    unsigned occupied, chunk1, chunk2; >>>> +    void *dst; >>>> +    int idx; >>>> + >>>> +    if (!drm_dev_enter(&ring->adev->ddev, &idx)) >>>> +        return; >>>> + >>>> +    if (unlikely(ring->count_dw < count_dw)) >>>> +        DRM_ERROR("amdgpu: writing more dwords to the ring than >>>> expected!\n"); >>>> + >>>> +    occupied = ring->wptr & ring->buf_mask; >>>> +    dst = (void *)&ring->ring[occupied]; >>>> +    chunk1 = ring->buf_mask + 1 - occupied; >>>> +    chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1; >>>> +    chunk2 = count_dw - chunk1; >>>> +    chunk1 <<= 2; >>>> +    chunk2 <<= 2; >>>> + >>>> +    if (chunk1) >>>> +        memcpy(dst, src, chunk1); >>>> + >>>> +    if (chunk2) { >>>> +        src += chunk1; >>>> +        dst = (void *)ring->ring; >>>> +        memcpy(dst, src, chunk2); >>>> +    } >>>> + >>>> +    ring->wptr += count_dw; >>>> +    ring->wptr &= ring->ptr_mask; >>>> +    ring->count_dw -= count_dw; >>>> + >>>> +    drm_dev_exit(idx); >>>> +} >>> >>> The ring should never we in MMIO memory, so you can completely drop >>> that as far as I can see. >> >> Yea, it's in all in GART, missed it for some reason... >>> >>> Maybe split that patch by use case so that we can more easily >>> review/ack it. >> >> In fact everything here is the same use case, once I added unmap of >> all MMIO ranges (both registers ann VRAM) i got a lot of page faults >> on device remove around any memcpy to from IO. That where I put the >> drn_dev_enter/exit scope. Also I searched in code and preemeptivly >> added guards to any other such place. I did drop amdgpu_schedule_ib >> from this patch both because it had dma_fence_wait inside and so we >> will take care of this once we decide on how to handle dma_fence waits. >> >> Andrey >> >>> >>> Thanks, >>> Christian. >>> >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>>> index e7d3d0dbdd96..c67bc6d3d039 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ring.h >>>> @@ -299,53 +299,12 @@ static inline void >>>> amdgpu_ring_set_preempt_cond_exec(struct amdgpu_ring *ring, >>>>       *ring->cond_exe_cpu_addr = cond_exec; >>>>   } >>>> -static inline void amdgpu_ring_clear_ring(struct amdgpu_ring *ring) >>>> -{ >>>> -    int i = 0; >>>> -    while (i <= ring->buf_mask) >>>> -        ring->ring[i++] = ring->funcs->nop; >>>> - >>>> -} >>>> - >>>> -static inline void amdgpu_ring_write(struct amdgpu_ring *ring, >>>> uint32_t v) >>>> -{ >>>> -    if (ring->count_dw <= 0) >>>> -        DRM_ERROR("amdgpu: writing more dwords to the ring than >>>> expected!\n"); >>>> -    ring->ring[ring->wptr++ & ring->buf_mask] = v; >>>> -    ring->wptr &= ring->ptr_mask; >>>> -    ring->count_dw--; >>>> -} >>>> +void amdgpu_ring_clear_ring(struct amdgpu_ring *ring); >>>> -static inline void amdgpu_ring_write_multiple(struct amdgpu_ring >>>> *ring, >>>> -                          void *src, int count_dw) >>>> -{ >>>> -    unsigned occupied, chunk1, chunk2; >>>> -    void *dst; >>>> - >>>> -    if (unlikely(ring->count_dw < count_dw)) >>>> -        DRM_ERROR("amdgpu: writing more dwords to the ring than >>>> expected!\n"); >>>> - >>>> -    occupied = ring->wptr & ring->buf_mask; >>>> -    dst = (void *)&ring->ring[occupied]; >>>> -    chunk1 = ring->buf_mask + 1 - occupied; >>>> -    chunk1 = (chunk1 >= count_dw) ? count_dw: chunk1; >>>> -    chunk2 = count_dw - chunk1; >>>> -    chunk1 <<= 2; >>>> -    chunk2 <<= 2; >>>> +void amdgpu_ring_write(struct amdgpu_ring *ring, uint32_t v); >>>> -    if (chunk1) >>>> -        memcpy(dst, src, chunk1); >>>> - >>>> -    if (chunk2) { >>>> -        src += chunk1; >>>> -        dst = (void *)ring->ring; >>>> -        memcpy(dst, src, chunk2); >>>> -    } >>>> - >>>> -    ring->wptr += count_dw; >>>> -    ring->wptr &= ring->ptr_mask; >>>> -    ring->count_dw -= count_dw; >>>> -} >>>> +void amdgpu_ring_write_multiple(struct amdgpu_ring *ring, >>>> +                          void *src, int count_dw); >>>>   int amdgpu_ring_test_helper(struct amdgpu_ring *ring); >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c >>>> index c6dbc0801604..82f0542c7792 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c >>>> @@ -32,6 +32,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_pm.h" >>>> @@ -375,7 +376,7 @@ int amdgpu_uvd_suspend(struct amdgpu_device *adev) >>>>   { >>>>       unsigned size; >>>>       void *ptr; >>>> -    int i, j; >>>> +    int i, j, idx; >>>>       bool in_ras_intr = amdgpu_ras_intr_triggered(); >>>>       cancel_delayed_work_sync(&adev->uvd.idle_work); >>>> @@ -403,11 +404,15 @@ int amdgpu_uvd_suspend(struct amdgpu_device >>>> *adev) >>>>           if (!adev->uvd.inst[j].saved_bo) >>>>               return -ENOMEM; >>>> -        /* re-write 0 since err_event_athub will corrupt VCPU >>>> buffer */ >>>> -        if (in_ras_intr) >>>> -            memset(adev->uvd.inst[j].saved_bo, 0, size); >>>> -        else >>>> -            memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size); >>>> +        if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +            /* re-write 0 since err_event_athub will corrupt VCPU >>>> buffer */ >>>> +            if (in_ras_intr) >>>> +                memset(adev->uvd.inst[j].saved_bo, 0, size); >>>> +            else >>>> + memcpy_fromio(adev->uvd.inst[j].saved_bo, ptr, size); >>>> + >>>> +            drm_dev_exit(idx); >>>> +        } >>>>       } >>>>       if (in_ras_intr) >>>> @@ -420,7 +425,7 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) >>>>   { >>>>       unsigned size; >>>>       void *ptr; >>>> -    int i; >>>> +    int i, idx; >>>>       for (i = 0; i < adev->uvd.num_uvd_inst; i++) { >>>>           if (adev->uvd.harvest_config & (1 << i)) >>>> @@ -432,7 +437,10 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) >>>>           ptr = adev->uvd.inst[i].cpu_addr; >>>>           if (adev->uvd.inst[i].saved_bo != NULL) { >>>> -            memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size); >>>> +            if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +                memcpy_toio(ptr, adev->uvd.inst[i].saved_bo, size); >>>> +                drm_dev_exit(idx); >>>> +            } >>>>               kvfree(adev->uvd.inst[i].saved_bo); >>>>               adev->uvd.inst[i].saved_bo = NULL; >>>>           } else { >>>> @@ -442,8 +450,11 @@ int amdgpu_uvd_resume(struct amdgpu_device *adev) >>>>               hdr = (const struct common_firmware_header >>>> *)adev->uvd.fw->data; >>>>               if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { >>>>                   offset = le32_to_cpu(hdr->ucode_array_offset_bytes); >>>> -                memcpy_toio(adev->uvd.inst[i].cpu_addr, >>>> adev->uvd.fw->data + offset, >>>> - le32_to_cpu(hdr->ucode_size_bytes)); >>>> +                if (drm_dev_enter(&adev->ddev, &idx)) { >>>> + memcpy_toio(adev->uvd.inst[i].cpu_addr, adev->uvd.fw->data + offset, >>>> + le32_to_cpu(hdr->ucode_size_bytes)); >>>> +                    drm_dev_exit(idx); >>>> +                } >>>>                   size -= le32_to_cpu(hdr->ucode_size_bytes); >>>>                   ptr += le32_to_cpu(hdr->ucode_size_bytes); >>>>               } >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c >>>> index ea6a62f67e38..833203401ef4 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c >>>> @@ -29,6 +29,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_pm.h" >>>> @@ -293,7 +294,7 @@ int amdgpu_vce_resume(struct amdgpu_device *adev) >>>>       void *cpu_addr; >>>>       const struct common_firmware_header *hdr; >>>>       unsigned offset; >>>> -    int r; >>>> +    int r, idx; >>>>       if (adev->vce.vcpu_bo == NULL) >>>>           return -EINVAL; >>>> @@ -313,8 +314,12 @@ int amdgpu_vce_resume(struct amdgpu_device *adev) >>>>       hdr = (const struct common_firmware_header *)adev->vce.fw->data; >>>>       offset = le32_to_cpu(hdr->ucode_array_offset_bytes); >>>> -    memcpy_toio(cpu_addr, adev->vce.fw->data + offset, >>>> -            adev->vce.fw->size - offset); >>>> + >>>> +    if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +        memcpy_toio(cpu_addr, adev->vce.fw->data + offset, >>>> +                adev->vce.fw->size - offset); >>>> +        drm_dev_exit(idx); >>>> +    } >>>>       amdgpu_bo_kunmap(adev->vce.vcpu_bo); >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c >>>> index 201645963ba5..21f7d3644d70 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vcn.c >>>> @@ -27,6 +27,7 @@ >>>>   #include >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_pm.h" >>>> @@ -275,7 +276,7 @@ int amdgpu_vcn_suspend(struct amdgpu_device *adev) >>>>   { >>>>       unsigned size; >>>>       void *ptr; >>>> -    int i; >>>> +    int i, idx; >>>>       cancel_delayed_work_sync(&adev->vcn.idle_work); >>>> @@ -292,7 +293,10 @@ int amdgpu_vcn_suspend(struct amdgpu_device >>>> *adev) >>>>           if (!adev->vcn.inst[i].saved_bo) >>>>               return -ENOMEM; >>>> -        memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size); >>>> +        if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +            memcpy_fromio(adev->vcn.inst[i].saved_bo, ptr, size); >>>> +            drm_dev_exit(idx); >>>> +        } >>>>       } >>>>       return 0; >>>>   } >>>> @@ -301,7 +305,7 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) >>>>   { >>>>       unsigned size; >>>>       void *ptr; >>>> -    int i; >>>> +    int i, idx; >>>>       for (i = 0; i < adev->vcn.num_vcn_inst; ++i) { >>>>           if (adev->vcn.harvest_config & (1 << i)) >>>> @@ -313,7 +317,10 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) >>>>           ptr = adev->vcn.inst[i].cpu_addr; >>>>           if (adev->vcn.inst[i].saved_bo != NULL) { >>>> -            memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size); >>>> +            if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +                memcpy_toio(ptr, adev->vcn.inst[i].saved_bo, size); >>>> +                drm_dev_exit(idx); >>>> +            } >>>>               kvfree(adev->vcn.inst[i].saved_bo); >>>>               adev->vcn.inst[i].saved_bo = NULL; >>>>           } else { >>>> @@ -323,8 +330,11 @@ int amdgpu_vcn_resume(struct amdgpu_device *adev) >>>>               hdr = (const struct common_firmware_header >>>> *)adev->vcn.fw->data; >>>>               if (adev->firmware.load_type != AMDGPU_FW_LOAD_PSP) { >>>>                   offset = le32_to_cpu(hdr->ucode_array_offset_bytes); >>>> -                memcpy_toio(adev->vcn.inst[i].cpu_addr, >>>> adev->vcn.fw->data + offset, >>>> - le32_to_cpu(hdr->ucode_size_bytes)); >>>> +                if (drm_dev_enter(&adev->ddev, &idx)) { >>>> + memcpy_toio(adev->vcn.inst[i].cpu_addr, adev->vcn.fw->data + offset, >>>> + le32_to_cpu(hdr->ucode_size_bytes)); >>>> +                    drm_dev_exit(idx); >>>> +                } >>>>                   size -= le32_to_cpu(hdr->ucode_size_bytes); >>>>                   ptr += le32_to_cpu(hdr->ucode_size_bytes); >>>>               } >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >>>> b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >>>> index 9f868cf3b832..7dd5f10ab570 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vm.c >>>> @@ -32,6 +32,7 @@ >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_trace.h" >>>>   #include "amdgpu_amdkfd.h" >>>> @@ -1606,7 +1607,10 @@ static int >>>> amdgpu_vm_bo_update_mapping(struct amdgpu_device *adev, >>>>       struct amdgpu_vm_update_params params; >>>>       enum amdgpu_sync_mode sync_mode; >>>>       uint64_t pfn; >>>> -    int r; >>>> +    int r, idx; >>>> + >>>> +    if (!drm_dev_enter(&adev->ddev, &idx)) >>>> +        return -ENODEV; >>>>       memset(¶ms, 0, sizeof(params)); >>>>       params.adev = adev; >>>> @@ -1715,6 +1719,7 @@ static int amdgpu_vm_bo_update_mapping(struct >>>> amdgpu_device *adev, >>>>   error_unlock: >>>>       amdgpu_vm_eviction_unlock(vm); >>>> +    drm_dev_exit(idx); >>>>       return r; >>>>   } >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c >>>> b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c >>>> index 589410c32d09..2cec71e823f5 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v11_0.c >>>> @@ -23,6 +23,7 @@ >>>>   #include >>>>   #include >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_psp.h" >>>> @@ -269,10 +270,8 @@ static int >>>> psp_v11_0_bootloader_load_kdb(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP KDB binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->kdb_start_addr, psp->kdb_bin_size); >>>> +    psp_copy_fw(psp, psp->kdb_start_addr, psp->kdb_bin_size); >>>>       /* Provide the PSP KDB to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -302,10 +301,8 @@ static int >>>> psp_v11_0_bootloader_load_spl(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP SPL binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->spl_start_addr, psp->spl_bin_size); >>>> +    psp_copy_fw(psp, psp->spl_start_addr, psp->spl_bin_size); >>>>       /* Provide the PSP SPL to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -335,10 +332,8 @@ static int >>>> psp_v11_0_bootloader_load_sysdrv(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP System Driver binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); >>>> +    psp_copy_fw(psp, psp->sys_start_addr, psp->sys_bin_size); >>>>       /* Provide the sys driver to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -371,10 +366,8 @@ static int >>>> psp_v11_0_bootloader_load_sos(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy Secure OS binary to PSP memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); >>>> +    psp_copy_fw(psp, psp->sos_start_addr, psp->sos_bin_size); >>>>       /* Provide the PSP secure OS to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -608,7 +601,7 @@ static int psp_v11_0_memory_training(struct >>>> psp_context *psp, uint32_t ops) >>>>       uint32_t p2c_header[4]; >>>>       uint32_t sz; >>>>       void *buf; >>>> -    int ret; >>>> +    int ret, idx; >>>>       if (ctx->init == PSP_MEM_TRAIN_NOT_SUPPORT) { >>>>           DRM_DEBUG("Memory training is not supported.\n"); >>>> @@ -681,17 +674,24 @@ static int psp_v11_0_memory_training(struct >>>> psp_context *psp, uint32_t ops) >>>>               return -ENOMEM; >>>>           } >>>> -        memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz); >>>> -        ret = psp_v11_0_memory_training_send_msg(psp, >>>> PSP_BL__DRAM_LONG_TRAIN); >>>> -        if (ret) { >>>> -            DRM_ERROR("Send long training msg failed.\n"); >>>> +        if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +            memcpy_fromio(buf, adev->mman.aper_base_kaddr, sz); >>>> +            ret = psp_v11_0_memory_training_send_msg(psp, >>>> PSP_BL__DRAM_LONG_TRAIN); >>>> +            if (ret) { >>>> +                DRM_ERROR("Send long training msg failed.\n"); >>>> +                vfree(buf); >>>> +                drm_dev_exit(idx); >>>> +                return ret; >>>> +            } >>>> + >>>> +            memcpy_toio(adev->mman.aper_base_kaddr, buf, sz); >>>> +            adev->hdp.funcs->flush_hdp(adev, NULL); >>>>               vfree(buf); >>>> -            return ret; >>>> +            drm_dev_exit(idx); >>>> +        } else { >>>> +            vfree(buf); >>>> +            return -ENODEV; >>>>           } >>>> - >>>> -        memcpy_toio(adev->mman.aper_base_kaddr, buf, sz); >>>> -        adev->hdp.funcs->flush_hdp(adev, NULL); >>>> -        vfree(buf); >>>>       } >>>>       if (ops & PSP_MEM_TRAIN_SAVE) { >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c >>>> b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c >>>> index c4828bd3264b..618e5b6b85d9 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v12_0.c >>>> @@ -138,10 +138,8 @@ static int >>>> psp_v12_0_bootloader_load_sysdrv(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP System Driver binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); >>>> +    psp_copy_fw(psp, psp->sys_start_addr, psp->sys_bin_size); >>>>       /* Provide the sys driver to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -179,10 +177,8 @@ static int >>>> psp_v12_0_bootloader_load_sos(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy Secure OS binary to PSP memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); >>>> +    psp_copy_fw(psp, psp->sos_start_addr, psp->sos_bin_size); >>>>       /* Provide the PSP secure OS to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c >>>> b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c >>>> index f2e725f72d2f..d0a6cccd0897 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/psp_v3_1.c >>>> @@ -102,10 +102,8 @@ static int >>>> psp_v3_1_bootloader_load_sysdrv(struct psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy PSP System Driver binary to memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sys_start_addr, psp->sys_bin_size); >>>> +    psp_copy_fw(psp, psp->sys_start_addr, psp->sys_bin_size); >>>>       /* Provide the sys driver to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> @@ -143,10 +141,8 @@ static int psp_v3_1_bootloader_load_sos(struct >>>> psp_context *psp) >>>>       if (ret) >>>>           return ret; >>>> -    memset(psp->fw_pri_buf, 0, PSP_1_MEG); >>>> - >>>>       /* Copy Secure OS binary to PSP memory */ >>>> -    memcpy(psp->fw_pri_buf, psp->sos_start_addr, psp->sos_bin_size); >>>> +    psp_copy_fw(psp, psp->sos_start_addr, psp->sos_bin_size); >>>>       /* Provide the PSP secure OS to bootloader */ >>>>       WREG32_SOC15(MP0, 0, mmMP0_SMN_C2PMSG_36, >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c >>>> b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c >>>> index 8e238dea7bef..90910d19db12 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c >>>> @@ -25,6 +25,7 @@ >>>>    */ >>>>   #include >>>> +#include >>>>   #include "amdgpu.h" >>>>   #include "amdgpu_vce.h" >>>> @@ -555,16 +556,19 @@ static int vce_v4_0_hw_fini(void *handle) >>>>   static int vce_v4_0_suspend(void *handle) >>>>   { >>>>       struct amdgpu_device *adev = (struct amdgpu_device *)handle; >>>> -    int r; >>>> +    int r, idx; >>>>       if (adev->vce.vcpu_bo == NULL) >>>>           return 0; >>>> -    if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { >>>> -        unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); >>>> -        void *ptr = adev->vce.cpu_addr; >>>> +    if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +        if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { >>>> +            unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); >>>> +            void *ptr = adev->vce.cpu_addr; >>>> -        memcpy_fromio(adev->vce.saved_bo, ptr, size); >>>> +            memcpy_fromio(adev->vce.saved_bo, ptr, size); >>>> +        } >>>> +        drm_dev_exit(idx); >>>>       } >>>>       r = vce_v4_0_hw_fini(adev); >>>> @@ -577,16 +581,20 @@ static int vce_v4_0_suspend(void *handle) >>>>   static int vce_v4_0_resume(void *handle) >>>>   { >>>>       struct amdgpu_device *adev = (struct amdgpu_device *)handle; >>>> -    int r; >>>> +    int r, idx; >>>>       if (adev->vce.vcpu_bo == NULL) >>>>           return -EINVAL; >>>>       if (adev->firmware.load_type == AMDGPU_FW_LOAD_PSP) { >>>> -        unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); >>>> -        void *ptr = adev->vce.cpu_addr; >>>> -        memcpy_toio(ptr, adev->vce.saved_bo, size); >>>> +        if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +            unsigned size = amdgpu_bo_size(adev->vce.vcpu_bo); >>>> +            void *ptr = adev->vce.cpu_addr; >>>> + >>>> +            memcpy_toio(ptr, adev->vce.saved_bo, size); >>>> +            drm_dev_exit(idx); >>>> +        } >>>>       } else { >>>>           r = amdgpu_vce_resume(adev); >>>>           if (r) >>>> diff --git a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c >>>> b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c >>>> index 3f15bf34123a..df34be8ec82d 100644 >>>> --- a/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c >>>> +++ b/drivers/gpu/drm/amd/amdgpu/vcn_v3_0.c >>>> @@ -34,6 +34,8 @@ >>>>   #include "vcn/vcn_3_0_0_sh_mask.h" >>>>   #include "ivsrcid/vcn/irqsrcs_vcn_2_0.h" >>>> +#include >>>> + >>>>   #define mmUVD_CONTEXT_ID_INTERNAL_OFFSET            0x27 >>>>   #define mmUVD_GPCOM_VCPU_CMD_INTERNAL_OFFSET 0x0f >>>>   #define mmUVD_GPCOM_VCPU_DATA0_INTERNAL_OFFSET 0x10 >>>> @@ -268,16 +270,20 @@ static int vcn_v3_0_sw_init(void *handle) >>>>   static int vcn_v3_0_sw_fini(void *handle) >>>>   { >>>>       struct amdgpu_device *adev = (struct amdgpu_device *)handle; >>>> -    int i, r; >>>> +    int i, r, idx; >>>> -    for (i = 0; i < adev->vcn.num_vcn_inst; i++) { >>>> -        volatile struct amdgpu_fw_shared *fw_shared; >>>> +    if (drm_dev_enter(&adev->ddev, &idx)) { >>>> +        for (i = 0; i < adev->vcn.num_vcn_inst; i++) { >>>> +            volatile struct amdgpu_fw_shared *fw_shared; >>>> -        if (adev->vcn.harvest_config & (1 << i)) >>>> -            continue; >>>> -        fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr; >>>> -        fw_shared->present_flag_0 = 0; >>>> -        fw_shared->sw_ring.is_enabled = false; >>>> +            if (adev->vcn.harvest_config & (1 << i)) >>>> +                continue; >>>> +            fw_shared = adev->vcn.inst[i].fw_shared_cpu_addr; >>>> +            fw_shared->present_flag_0 = 0; >>>> +            fw_shared->sw_ring.is_enabled = false; >>>> +        } >>>> + >>>> +        drm_dev_exit(idx); >>>>       } >>>>       if (amdgpu_sriov_vf(adev)) >>>> diff --git a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c >>>> b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c >>>> index aae25243eb10..d628b91846c9 100644 >>>> --- a/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c >>>> +++ b/drivers/gpu/drm/amd/pm/powerplay/smumgr/smu7_smumgr.c >>>> @@ -405,6 +405,8 @@ int smu7_request_smu_load_fw(struct pp_hwmgr >>>> *hwmgr) >>>>                   UCODE_ID_MEC_STORAGE, >>>> &toc->entry[toc->num_entries++]), >>>>                   "Failed to Get Firmware Entry.", r = -EINVAL; >>>> goto failed); >>>>       } >>>> + >>>> +    /* AG TODO Can't call drm_dev_enter/exit because access >>>> adev->ddev here ... */ >>>>       memcpy_toio(smu_data->header_buffer.kaddr, smu_data->toc, >>>>               sizeof(struct SMU_DRAMData_TOC)); >>>>       smum_send_msg_to_smc_with_parameter(hwmgr, >>>