From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from smtp1.osuosl.org (smtp1.osuosl.org [140.211.166.138]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 31245C433F5 for ; Wed, 23 Feb 2022 02:04:15 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp1.osuosl.org (Postfix) with ESMTP id C3D9F80D0F; Wed, 23 Feb 2022 02:04:14 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Received: from smtp1.osuosl.org ([127.0.0.1]) by localhost (smtp1.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id ieb1vvW9TjUu; Wed, 23 Feb 2022 02:04:13 +0000 (UTC) Received: from lists.linuxfoundation.org (lf-lists.osuosl.org [140.211.9.56]) by smtp1.osuosl.org (Postfix) with ESMTPS id 60C6C80C7A; Wed, 23 Feb 2022 02:04:12 +0000 (UTC) Received: from lf-lists.osuosl.org (localhost [127.0.0.1]) by lists.linuxfoundation.org (Postfix) with ESMTP id 2F0E3C0021; Wed, 23 Feb 2022 02:04:12 +0000 (UTC) Received: from smtp4.osuosl.org (smtp4.osuosl.org [IPv6:2605:bc80:3010::137]) by lists.linuxfoundation.org (Postfix) with ESMTP id 843EEC0011 for ; Wed, 23 Feb 2022 02:04:10 +0000 (UTC) Received: from localhost (localhost [127.0.0.1]) by smtp4.osuosl.org (Postfix) with ESMTP id 69BBC40347 for ; Wed, 23 Feb 2022 02:04:10 +0000 (UTC) X-Virus-Scanned: amavisd-new at osuosl.org Authentication-Results: smtp4.osuosl.org (amavisd-new); dkim=pass (1024-bit key) header.d=redhat.com Received: from smtp4.osuosl.org ([127.0.0.1]) by localhost (smtp4.osuosl.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 0kpqIylXB3hh for ; Wed, 23 Feb 2022 02:04:08 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.8.0 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by smtp4.osuosl.org (Postfix) with ESMTPS id 6BDF140339 for ; Wed, 23 Feb 2022 02:04:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1645581847; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qKehpGX8N3Zv2mECHng3CbLXmSkX7YEgc+QoYwmB+x0=; b=ORfT34AleDkLcnQuX4Ugl1/9ByPaeV57X+if6MszboPWCnkiboupO8KIYx7GF0kBqNrzwA bcAU+NPphxm8M20FMdOxC8SB6DBmgQRe5qvSCD2izA4ee0wfae+TDvxHr+QIMlY/oySn0r sWJ5c8iSFUm1HKrXBE2sl8uX5rytntc= Received: from mail-lj1-f200.google.com (mail-lj1-f200.google.com [209.85.208.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-372-ZgfiuCazOFGW1ajO_g2kkg-1; Tue, 22 Feb 2022 21:04:04 -0500 X-MC-Unique: ZgfiuCazOFGW1ajO_g2kkg-1 Received: by mail-lj1-f200.google.com with SMTP id b16-20020a05651c0b1000b0024647a956a2so2777066ljr.5 for ; Tue, 22 Feb 2022 18:04:04 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=qKehpGX8N3Zv2mECHng3CbLXmSkX7YEgc+QoYwmB+x0=; b=6hjefuERd+FVkl20plD9DPtpCr6uO9B5FrapoFTsT+0woJRthbaDNF20R30zzKGvhP qRvx02QnOlzRu34tXwfAar8w0EWDEIFy5AuD3MOLb2R2DPC1KF5OAn7N09jFL2wPtHWP K9ROWzTVgNeZo/TuL/n7Sgdzx8icHNor+/Va25UrZAgkSF2V9Qdn5uptjGMdaucNlgaf FFta3j+qO88sIb+l5amvqgE8S+JniyV2psUOWo6kpBYCroGxEhVePRxtO1i1bpFrhBh7 olmi5YV9gDprgbati4u4xS28SQxKRwDazOzK/LWqotPB7XWOXsOrV5PGRjhS/L+BQQJ0 t7/g== X-Gm-Message-State: AOAM530+juIOBpS2PZv8GEkLcrYBWvT2Fc6liiClP9Hdj7a77+E8rU5K YiMQ5HIiCD2SjRp05nuTevPcWZmQ7bei10X3cRgVttaTpUzrXZvSryH0K7PT+QmqO5xw4CeatJM MQOvYHVafhoPDRzUOMuqtyRr4za+h5cVanFKbyz/twD5bfboEYjLHnxWxuw== X-Received: by 2002:a05:651c:982:b0:244:c35d:b1ef with SMTP id b2-20020a05651c098200b00244c35db1efmr19548014ljq.243.1645581842830; Tue, 22 Feb 2022 18:04:02 -0800 (PST) X-Google-Smtp-Source: ABdhPJxbc0Hi1KK6AAjiWX4JAIIKqQVmpzwKozIPTs/mQQS1xZEoI5AqJfUM9Tlf6lTc/TpxuE6Ym9mtKLfWE19dXXA= X-Received: by 2002:a05:651c:982:b0:244:c35d:b1ef with SMTP id b2-20020a05651c098200b00244c35db1efmr19547989ljq.243.1645581842379; Tue, 22 Feb 2022 18:04:02 -0800 (PST) MIME-Version: 1.0 References: <20220121202733.404989-1-eperezma@redhat.com> <20220121202733.404989-19-eperezma@redhat.com> <6c98f4e8-8695-ab83-ae37-2d6293a1fafa@redhat.com> <75e2fd97-1e34-2b1a-cca4-ceb1aa440479@redhat.com> In-Reply-To: From: Jason Wang Date: Wed, 23 Feb 2022 10:03:51 +0800 Message-ID: Subject: Re: [PATCH 18/31] vhost: Shadow virtqueue buffers forwarding To: Eugenio Perez Martin Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jasowang@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Cc: Laurent Vivier , Parav Pandit , Cindy Lu , "Michael S. Tsirkin" , Richard Henderson , qemu-level , Gautam Dawar , Markus Armbruster , Eduardo Habkost , Harpreet Singh Anand , Xiao W Wang , Stefan Hajnoczi , Eli Cohen , Paolo Bonzini , Zhu Lingshan , virtualization , Eric Blake X-BeenThere: virtualization@lists.linux-foundation.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux virtualization List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Errors-To: virtualization-bounces@lists.linux-foundation.org Sender: "Virtualization" T24gV2VkLCBGZWIgMjMsIDIwMjIgYXQgMzowMSBBTSBFdWdlbmlvIFBlcmV6IE1hcnRpbgo8ZXBl cmV6bWFAcmVkaGF0LmNvbT4gd3JvdGU6Cj4KPiBPbiBUdWUsIEZlYiA4LCAyMDIyIGF0IDk6MTEg QU0gSmFzb24gV2FuZyA8amFzb3dhbmdAcmVkaGF0LmNvbT4gd3JvdGU6Cj4gPgo+ID4KPiA+IOWc qCAyMDIyLzIvMiDkuIrljYgxOjA4LCBFdWdlbmlvIFBlcmV6IE1hcnRpbiDlhpnpgZM6Cj4gPiA+ IE9uIFN1biwgSmFuIDMwLCAyMDIyIGF0IDU6NDMgQU0gSmFzb24gV2FuZyA8amFzb3dhbmdAcmVk aGF0LmNvbT4gd3JvdGU6Cj4gPiA+Pgo+ID4gPj4g5ZyoIDIwMjIvMS8yMiDkuIrljYg0OjI3LCBF dWdlbmlvIFDDqXJleiDlhpnpgZM6Cj4gPiA+Pj4gSW5pdGlhbCB2ZXJzaW9uIG9mIHNoYWRvdyB2 aXJ0cXVldWUgdGhhdCBhY3R1YWxseSBmb3J3YXJkIGJ1ZmZlcnMuIFRoZXJlCj4gPiA+Pj4gaXMg bm8gaW9tbXUgc3VwcG9ydCBhdCB0aGUgbW9tZW50LCBhbmQgdGhhdCB3aWxsIGJlIGFkZHJlc3Nl ZCBpbiBmdXR1cmUKPiA+ID4+PiBwYXRjaGVzIG9mIHRoaXMgc2VyaWVzLiBTaW5jZSBhbGwgdmhv c3QtdmRwYSBkZXZpY2VzIHVzZSBmb3JjZWQgSU9NTVUsCj4gPiA+Pj4gdGhpcyBtZWFucyB0aGF0 IFNWUSBpcyBub3QgdXNhYmxlIGF0IHRoaXMgcG9pbnQgb2YgdGhlIHNlcmllcyBvbiBhbnkKPiA+ ID4+PiBkZXZpY2UuCj4gPiA+Pj4KPiA+ID4+PiBGb3Igc2ltcGxpY2l0eSBpdCBvbmx5IHN1cHBv cnRzIG1vZGVybiBkZXZpY2VzLCB0aGF0IGV4cGVjdHMgdnJpbmcKPiA+ID4+PiBpbiBsaXR0bGUg ZW5kaWFuLCB3aXRoIHNwbGl0IHJpbmcgYW5kIG5vIGV2ZW50IGlkeCBvciBpbmRpcmVjdAo+ID4g Pj4+IGRlc2NyaXB0b3JzLiBTdXBwb3J0IGZvciB0aGVtIHdpbGwgbm90IGJlIGFkZGVkIGluIHRo aXMgc2VyaWVzLgo+ID4gPj4+Cj4gPiA+Pj4gSXQgcmV1c2VzIHRoZSBWaXJ0UXVldWUgY29kZSBm b3IgdGhlIGRldmljZSBwYXJ0LiBUaGUgZHJpdmVyIHBhcnQgaXMKPiA+ID4+PiBiYXNlZCBvbiBM aW51eCdzIHZpcnRpb19yaW5nIGRyaXZlciwgYnV0IHdpdGggc3RyaXBwZWQgZnVuY3Rpb25hbGl0 eQo+ID4gPj4+IGFuZCBvcHRpbWl6YXRpb25zIHNvIGl0J3MgZWFzaWVyIHRvIHJldmlldy4KPiA+ ID4+Pgo+ID4gPj4+IEhvd2V2ZXIsIGZvcndhcmRpbmcgYnVmZmVycyBoYXZlIHNvbWUgcGFydGlj dWxhciBwaWVjZXM6IE9uZSBvZiB0aGUgbW9zdAo+ID4gPj4+IHVuZXhwZWN0ZWQgb25lcyBpcyB0 aGF0IGEgZ3Vlc3QncyBidWZmZXIgY2FuIGV4cGFuZCB0aHJvdWdoIG1vcmUgdGhhbgo+ID4gPj4+ IG9uZSBkZXNjcmlwdG9yIGluIFNWUS4gV2hpbGUgdGhpcyBpcyBoYW5kbGVkIGdyYWNlZnVsbHkg YnkgcWVtdSdzCj4gPiA+Pj4gZW11bGF0ZWQgdmlydGlvIGRldmljZXMsIGl0IG1heSBjYXVzZSB1 bmV4cGVjdGVkIFNWUSBxdWV1ZSBmdWxsLiBUaGlzCj4gPiA+Pj4gcGF0Y2ggYWxzbyBzb2x2ZXMg aXQgYnkgY2hlY2tpbmcgZm9yIHRoaXMgY29uZGl0aW9uIGF0IGJvdGggZ3Vlc3Qncwo+ID4gPj4+ IGtpY2tzIGFuZCBkZXZpY2UncyBjYWxscy4gVGhlIGNvZGUgbWF5IGJlIG1vcmUgZWxlZ2FudCBp biB0aGUgZnV0dXJlIGlmCj4gPiA+Pj4gU1ZRIGNvZGUgcnVucyBpbiBpdHMgb3duIGlvY29udGV4 dC4KPiA+ID4+Pgo+ID4gPj4+IFNpZ25lZC1vZmYtYnk6IEV1Z2VuaW8gUMOpcmV6IDxlcGVyZXpt YUByZWRoYXQuY29tPgo+ID4gPj4+IC0tLQo+ID4gPj4+ICAgIGh3L3ZpcnRpby92aG9zdC1zaGFk b3ctdmlydHF1ZXVlLmggfCAgIDIgKwo+ID4gPj4+ICAgIGh3L3ZpcnRpby92aG9zdC1zaGFkb3ct dmlydHF1ZXVlLmMgfCAzNjUgKysrKysrKysrKysrKysrKysrKysrKysrKysrKy0KPiA+ID4+PiAg ICBody92aXJ0aW8vdmhvc3QtdmRwYS5jICAgICAgICAgICAgIHwgMTExICsrKysrKysrLQo+ID4g Pj4+ICAgIDMgZmlsZXMgY2hhbmdlZCwgNDYyIGluc2VydGlvbnMoKyksIDE2IGRlbGV0aW9ucygt KQo+ID4gPj4+Cj4gPiA+Pj4gZGlmZiAtLWdpdCBhL2h3L3ZpcnRpby92aG9zdC1zaGFkb3ctdmly dHF1ZXVlLmggYi9ody92aXJ0aW8vdmhvc3Qtc2hhZG93LXZpcnRxdWV1ZS5oCj4gPiA+Pj4gaW5k ZXggMzlhZWY1ZmZkZi4uMTljOTM0YWY0OSAxMDA2NDQKPiA+ID4+PiAtLS0gYS9ody92aXJ0aW8v dmhvc3Qtc2hhZG93LXZpcnRxdWV1ZS5oCj4gPiA+Pj4gKysrIGIvaHcvdmlydGlvL3Zob3N0LXNo YWRvdy12aXJ0cXVldWUuaAo+ID4gPj4+IEBAIC0zMyw2ICszMyw4IEBAIHVpbnQxNl90IHZob3N0 X3N2cV9nZXRfbnVtKGNvbnN0IFZob3N0U2hhZG93VmlydHF1ZXVlICpzdnEpOwo+ID4gPj4+ICAg IHNpemVfdCB2aG9zdF9zdnFfZHJpdmVyX2FyZWFfc2l6ZShjb25zdCBWaG9zdFNoYWRvd1ZpcnRx dWV1ZSAqc3ZxKTsKPiA+ID4+PiAgICBzaXplX3Qgdmhvc3Rfc3ZxX2RldmljZV9hcmVhX3NpemUo Y29uc3QgVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSk7Cj4gPiA+Pj4KPiA+ID4+PiArdm9pZCB2 aG9zdF9zdnFfc3RhcnQoVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSwgVmlydElPRGV2aWNlICp2 ZGV2LAo+ID4gPj4+ICsgICAgICAgICAgICAgICAgICAgICBWaXJ0UXVldWUgKnZxKTsKPiA+ID4+ PiAgICB2b2lkIHZob3N0X3N2cV9zdG9wKFZob3N0U2hhZG93VmlydHF1ZXVlICpzdnEpOwo+ID4g Pj4+Cj4gPiA+Pj4gICAgVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnZob3N0X3N2cV9uZXcodWludDE2 X3QgcXNpemUpOwo+ID4gPj4+IGRpZmYgLS1naXQgYS9ody92aXJ0aW8vdmhvc3Qtc2hhZG93LXZp cnRxdWV1ZS5jIGIvaHcvdmlydGlvL3Zob3N0LXNoYWRvdy12aXJ0cXVldWUuYwo+ID4gPj4+IGlu ZGV4IDdjMTY4MDc1ZDcuLmExYTQwNGY2OGYgMTAwNjQ0Cj4gPiA+Pj4gLS0tIGEvaHcvdmlydGlv L3Zob3N0LXNoYWRvdy12aXJ0cXVldWUuYwo+ID4gPj4+ICsrKyBiL2h3L3ZpcnRpby92aG9zdC1z aGFkb3ctdmlydHF1ZXVlLmMKPiA+ID4+PiBAQCAtOSw2ICs5LDggQEAKPiA+ID4+Pgo+ID4gPj4+ ICAgICNpbmNsdWRlICJxZW11L29zZGVwLmgiCj4gPiA+Pj4gICAgI2luY2x1ZGUgImh3L3ZpcnRp by92aG9zdC1zaGFkb3ctdmlydHF1ZXVlLmgiCj4gPiA+Pj4gKyNpbmNsdWRlICJody92aXJ0aW8v dmhvc3QuaCIKPiA+ID4+PiArI2luY2x1ZGUgImh3L3ZpcnRpby92aXJ0aW8tYWNjZXNzLmgiCj4g PiA+Pj4gICAgI2luY2x1ZGUgInN0YW5kYXJkLWhlYWRlcnMvbGludXgvdmhvc3RfdHlwZXMuaCIK PiA+ID4+Pgo+ID4gPj4+ICAgICNpbmNsdWRlICJxZW11L2Vycm9yLXJlcG9ydC5oIgo+ID4gPj4+ IEBAIC0zNiw2ICszOCwzMyBAQCB0eXBlZGVmIHN0cnVjdCBWaG9zdFNoYWRvd1ZpcnRxdWV1ZSB7 Cj4gPiA+Pj4KPiA+ID4+PiAgICAgICAgLyogR3Vlc3QncyBjYWxsIG5vdGlmaWVyLCB3aGVyZSBT VlEgY2FsbHMgZ3Vlc3QuICovCj4gPiA+Pj4gICAgICAgIEV2ZW50Tm90aWZpZXIgc3ZxX2NhbGw7 Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgLyogVmlydGlvIHF1ZXVlIHNoYWRvd2luZyAqLwo+ID4g Pj4+ICsgICAgVmlydFF1ZXVlICp2cTsKPiA+ID4+PiArCj4gPiA+Pj4gKyAgICAvKiBWaXJ0aW8g ZGV2aWNlICovCj4gPiA+Pj4gKyAgICBWaXJ0SU9EZXZpY2UgKnZkZXY7Cj4gPiA+Pj4gKwo+ID4g Pj4+ICsgICAgLyogTWFwIGZvciByZXR1cm5pbmcgZ3Vlc3QncyBkZXNjcmlwdG9ycyAqLwo+ID4g Pj4+ICsgICAgVmlydFF1ZXVlRWxlbWVudCAqKnJpbmdfaWRfbWFwczsKPiA+ID4+PiArCj4gPiA+ Pj4gKyAgICAvKiBOZXh0IFZpcnRRdWV1ZSBlbGVtZW50IHRoYXQgZ3Vlc3QgbWFkZSBhdmFpbGFi bGUgKi8KPiA+ID4+PiArICAgIFZpcnRRdWV1ZUVsZW1lbnQgKm5leHRfZ3Vlc3RfYXZhaWxfZWxl bTsKPiA+ID4+PiArCj4gPiA+Pj4gKyAgICAvKiBOZXh0IGhlYWQgdG8gZXhwb3NlIHRvIGRldmlj ZSAqLwo+ID4gPj4+ICsgICAgdWludDE2X3QgYXZhaWxfaWR4X3NoYWRvdzsKPiA+ID4+PiArCj4g PiA+Pj4gKyAgICAvKiBOZXh0IGZyZWUgZGVzY3JpcHRvciAqLwo+ID4gPj4+ICsgICAgdWludDE2 X3QgZnJlZV9oZWFkOwo+ID4gPj4+ICsKPiA+ID4+PiArICAgIC8qIExhc3Qgc2VlbiB1c2VkIGlk eCAqLwo+ID4gPj4+ICsgICAgdWludDE2X3Qgc2hhZG93X3VzZWRfaWR4Owo+ID4gPj4+ICsKPiA+ ID4+PiArICAgIC8qIE5leHQgaGVhZCB0byBjb25zdW1lIGZyb20gZGV2aWNlICovCj4gPiA+Pj4g KyAgICB1aW50MTZfdCBsYXN0X3VzZWRfaWR4Owo+ID4gPj4+ICsKPiA+ID4+PiArICAgIC8qIENh Y2hlIGZvciB0aGUgZXhwb3NlZCBub3RpZmljYXRpb24gZmxhZyAqLwo+ID4gPj4+ICsgICAgYm9v bCBub3RpZmljYXRpb247Cj4gPiA+Pj4gICAgfSBWaG9zdFNoYWRvd1ZpcnRxdWV1ZTsKPiA+ID4+ Pgo+ID4gPj4+ICAgICNkZWZpbmUgSU5WQUxJRF9TVlFfS0lDS19GRCAtMQo+ID4gPj4+IEBAIC0x NDgsMzAgKzE3NywyOTQgQEAgYm9vbCB2aG9zdF9zdnFfYWNrX2d1ZXN0X2ZlYXR1cmVzKHVpbnQ2 NF90IGRldl9mZWF0dXJlcywKPiA+ID4+PiAgICAgICAgcmV0dXJuIHRydWU7Cj4gPiA+Pj4gICAg fQo+ID4gPj4+Cj4gPiA+Pj4gLS8qIEZvcndhcmQgZ3Vlc3Qgbm90aWZpY2F0aW9ucyAqLwo+ID4g Pj4+IC1zdGF0aWMgdm9pZCB2aG9zdF9oYW5kbGVfZ3Vlc3Rfa2ljayhFdmVudE5vdGlmaWVyICpu KQo+ID4gPj4+ICsvKioKPiA+ID4+PiArICogTnVtYmVyIG9mIGRlc2NyaXB0b3JzIHRoYXQgU1ZR IGNhbiBtYWtlIGF2YWlsYWJsZSBmcm9tIHRoZSBndWVzdC4KPiA+ID4+PiArICoKPiA+ID4+PiAr ICogQHN2cSAgIFRoZSBzdnEKPiA+ID4+PiArICovCj4gPiA+Pj4gK3N0YXRpYyB1aW50MTZfdCB2 aG9zdF9zdnFfYXZhaWxhYmxlX3Nsb3RzKGNvbnN0IFZob3N0U2hhZG93VmlydHF1ZXVlICpzdnEp Cj4gPiA+Pj4gICAgewo+ID4gPj4+IC0gICAgVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSA9IGNv bnRhaW5lcl9vZihuLCBWaG9zdFNoYWRvd1ZpcnRxdWV1ZSwKPiA+ID4+PiAtICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ZxX2tpY2spOwo+ID4gPj4+ICsgICAg cmV0dXJuIHN2cS0+dnJpbmcubnVtIC0gKHN2cS0+YXZhaWxfaWR4X3NoYWRvdyAtIHN2cS0+c2hh ZG93X3VzZWRfaWR4KTsKPiA+ID4+PiArfQo+ID4gPj4+ICsKPiA+ID4+PiArc3RhdGljIHZvaWQg dmhvc3Rfc3ZxX3NldF9ub3RpZmljYXRpb24oVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSwgYm9v bCBlbmFibGUpCj4gPiA+Pj4gK3sKPiA+ID4+PiArICAgIHVpbnQxNl90IG5vdGlmaWNhdGlvbl9m bGFnOwo+ID4gPj4+Cj4gPiA+Pj4gLSAgICBpZiAodW5saWtlbHkoIWV2ZW50X25vdGlmaWVyX3Rl c3RfYW5kX2NsZWFyKG4pKSkgewo+ID4gPj4+ICsgICAgaWYgKHN2cS0+bm90aWZpY2F0aW9uID09 IGVuYWJsZSkgewo+ID4gPj4+ICsgICAgICAgIHJldHVybjsKPiA+ID4+PiArICAgIH0KPiA+ID4+ PiArCj4gPiA+Pj4gKyAgICBub3RpZmljYXRpb25fZmxhZyA9IGNwdV90b19sZTE2KFZSSU5HX0FW QUlMX0ZfTk9fSU5URVJSVVBUKTsKPiA+ID4+PiArCj4gPiA+Pj4gKyAgICBzdnEtPm5vdGlmaWNh dGlvbiA9IGVuYWJsZTsKPiA+ID4+PiArICAgIGlmIChlbmFibGUpIHsKPiA+ID4+PiArICAgICAg ICBzdnEtPnZyaW5nLmF2YWlsLT5mbGFncyAmPSB+bm90aWZpY2F0aW9uX2ZsYWc7Cj4gPiA+Pj4g KyAgICB9IGVsc2Ugewo+ID4gPj4+ICsgICAgICAgIHN2cS0+dnJpbmcuYXZhaWwtPmZsYWdzIHw9 IG5vdGlmaWNhdGlvbl9mbGFnOwo+ID4gPj4+ICsgICAgfQo+ID4gPj4+ICt9Cj4gPiA+Pj4gKwo+ ID4gPj4+ICtzdGF0aWMgdm9pZCB2aG9zdF92cmluZ193cml0ZV9kZXNjcyhWaG9zdFNoYWRvd1Zp cnRxdWV1ZSAqc3ZxLAo+ID4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICBjb25zdCBzdHJ1Y3QgaW92ZWMgKmlvdmVjLAo+ID4gPj4+ICsgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICBzaXplX3QgbnVtLCBib29sIG1vcmVfZGVzY3MsIGJvb2wgd3JpdGUp Cj4gPiA+Pj4gK3sKPiA+ID4+PiArICAgIHVpbnQxNl90IGkgPSBzdnEtPmZyZWVfaGVhZCwgbGFz dCA9IHN2cS0+ZnJlZV9oZWFkOwo+ID4gPj4+ICsgICAgdW5zaWduZWQgbjsKPiA+ID4+PiArICAg IHVpbnQxNl90IGZsYWdzID0gd3JpdGUgPyBjcHVfdG9fbGUxNihWUklOR19ERVNDX0ZfV1JJVEUp IDogMDsKPiA+ID4+PiArICAgIHZyaW5nX2Rlc2NfdCAqZGVzY3MgPSBzdnEtPnZyaW5nLmRlc2M7 Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgaWYgKG51bSA9PSAwKSB7Cj4gPiA+Pj4gKyAgICAgICAg cmV0dXJuOwo+ID4gPj4+ICsgICAgfQo+ID4gPj4+ICsKPiA+ID4+PiArICAgIGZvciAobiA9IDA7 IG4gPCBudW07IG4rKykgewo+ID4gPj4+ICsgICAgICAgIGlmIChtb3JlX2Rlc2NzIHx8IChuICsg MSA8IG51bSkpIHsKPiA+ID4+PiArICAgICAgICAgICAgZGVzY3NbaV0uZmxhZ3MgPSBmbGFncyB8 IGNwdV90b19sZTE2KFZSSU5HX0RFU0NfRl9ORVhUKTsKPiA+ID4+PiArICAgICAgICB9IGVsc2Ug ewo+ID4gPj4+ICsgICAgICAgICAgICBkZXNjc1tpXS5mbGFncyA9IGZsYWdzOwo+ID4gPj4+ICsg ICAgICAgIH0KPiA+ID4+PiArICAgICAgICBkZXNjc1tpXS5hZGRyID0gY3B1X3RvX2xlNjQoKGh3 YWRkcilpb3ZlY1tuXS5pb3ZfYmFzZSk7Cj4gPiA+Pj4gKyAgICAgICAgZGVzY3NbaV0ubGVuID0g Y3B1X3RvX2xlMzIoaW92ZWNbbl0uaW92X2xlbik7Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgICAg IGxhc3QgPSBpOwo+ID4gPj4+ICsgICAgICAgIGkgPSBjcHVfdG9fbGUxNihkZXNjc1tpXS5uZXh0 KTsKPiA+ID4+PiArICAgIH0KPiA+ID4+PiArCj4gPiA+Pj4gKyAgICBzdnEtPmZyZWVfaGVhZCA9 IGxlMTZfdG9fY3B1KGRlc2NzW2xhc3RdLm5leHQpOwo+ID4gPj4+ICt9Cj4gPiA+Pj4gKwo+ID4g Pj4+ICtzdGF0aWMgdW5zaWduZWQgdmhvc3Rfc3ZxX2FkZF9zcGxpdChWaG9zdFNoYWRvd1ZpcnRx dWV1ZSAqc3ZxLAo+ID4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBW aXJ0UXVldWVFbGVtZW50ICplbGVtKQo+ID4gPj4+ICt7Cj4gPiA+Pj4gKyAgICBpbnQgaGVhZDsK PiA+ID4+PiArICAgIHVuc2lnbmVkIGF2YWlsX2lkeDsKPiA+ID4+PiArICAgIHZyaW5nX2F2YWls X3QgKmF2YWlsID0gc3ZxLT52cmluZy5hdmFpbDsKPiA+ID4+PiArCj4gPiA+Pj4gKyAgICBoZWFk ID0gc3ZxLT5mcmVlX2hlYWQ7Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgLyogV2UgbmVlZCBzb21l IGRlc2NyaXB0b3JzIGhlcmUgKi8KPiA+ID4+PiArICAgIGFzc2VydChlbGVtLT5vdXRfbnVtIHx8 IGVsZW0tPmluX251bSk7Cj4gPiA+Pgo+ID4gPj4gTG9va3MgbGlrZSB0aGlzIGNvdWxkIGJlIHRy aWdnZXJlZCBieSBndWVzdCwgd2UgbmVlZCBmYWlsIGluc3RlYWQgYXNzZXJ0Cj4gPiA+PiBoZXJl Lgo+ID4gPj4KPiA+ID4gTXkgdW5kZXJzdGFuZGluZyB3YXMgdGhhdCB2aXJ0cXVldWVfcG9wIGFs cmVhZHkgc2FuaXRpemVkIHRoYXQgY2FzZSwKPiA+ID4gYnV0IEknbSBub3QgYWJsZSB0byBmaW5k IHdoZXJlIG5vdy4gSSB3aWxsIHJlY2hlY2sgYW5kLCBpbiBjYXNlIGl0J3MKPiA+ID4gbm90LCBJ IHdpbGwgbW92ZSB0byBhIGZhaWx1cmUuCj4gPiA+Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgdmhv c3RfdnJpbmdfd3JpdGVfZGVzY3Moc3ZxLCBlbGVtLT5vdXRfc2csIGVsZW0tPm91dF9udW0sCj4g PiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICBlbGVtLT5pbl9udW0gPiAwLCBmYWxz ZSk7Cj4gPiA+Pj4gKyAgICB2aG9zdF92cmluZ193cml0ZV9kZXNjcyhzdnEsIGVsZW0tPmluX3Nn LCBlbGVtLT5pbl9udW0sIGZhbHNlLCB0cnVlKTsKPiA+ID4+PiArCj4gPiA+Pj4gKyAgICAvKgo+ ID4gPj4+ICsgICAgICogUHV0IGVudHJ5IGluIGF2YWlsYWJsZSBhcnJheSAoYnV0IGRvbid0IHVw ZGF0ZSBhdmFpbC0+aWR4IHVudGlsIHRoZXkKPiA+ID4+PiArICAgICAqIGRvIHN5bmMpLgo+ID4g Pj4+ICsgICAgICovCj4gPiA+Pj4gKyAgICBhdmFpbF9pZHggPSBzdnEtPmF2YWlsX2lkeF9zaGFk b3cgJiAoc3ZxLT52cmluZy5udW0gLSAxKTsKPiA+ID4+PiArICAgIGF2YWlsLT5yaW5nW2F2YWls X2lkeF0gPSBjcHVfdG9fbGUxNihoZWFkKTsKPiA+ID4+PiArICAgIHN2cS0+YXZhaWxfaWR4X3No YWRvdysrOwo+ID4gPj4+ICsKPiA+ID4+PiArICAgIC8qIFVwZGF0ZSBhdmFpbCBpbmRleCBhZnRl ciB0aGUgZGVzY3JpcHRvciBpcyB3cm90ZSAqLwo+ID4gPj4+ICsgICAgc21wX3dtYigpOwo+ID4g Pj4+ICsgICAgYXZhaWwtPmlkeCA9IGNwdV90b19sZTE2KHN2cS0+YXZhaWxfaWR4X3NoYWRvdyk7 Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgcmV0dXJuIGhlYWQ7Cj4gPiA+Pj4gK30KPiA+ID4+PiAr Cj4gPiA+Pj4gK3N0YXRpYyB2b2lkIHZob3N0X3N2cV9hZGQoVmhvc3RTaGFkb3dWaXJ0cXVldWUg KnN2cSwgVmlydFF1ZXVlRWxlbWVudCAqZWxlbSkKPiA+ID4+PiArewo+ID4gPj4+ICsgICAgdW5z aWduZWQgcWVtdV9oZWFkID0gdmhvc3Rfc3ZxX2FkZF9zcGxpdChzdnEsIGVsZW0pOwo+ID4gPj4+ ICsKPiA+ID4+PiArICAgIHN2cS0+cmluZ19pZF9tYXBzW3FlbXVfaGVhZF0gPSBlbGVtOwo+ID4g Pj4+ICt9Cj4gPiA+Pj4gKwo+ID4gPj4+ICtzdGF0aWMgdm9pZCB2aG9zdF9zdnFfa2ljayhWaG9z dFNoYWRvd1ZpcnRxdWV1ZSAqc3ZxKQo+ID4gPj4+ICt7Cj4gPiA+Pj4gKyAgICAvKiBXZSBuZWVk IHRvIGV4cG9zZSBhdmFpbGFibGUgYXJyYXkgZW50cmllcyBiZWZvcmUgY2hlY2tpbmcgdXNlZCBm bGFncyAqLwo+ID4gPj4+ICsgICAgc21wX21iKCk7Cj4gPiA+Pj4gKyAgICBpZiAoc3ZxLT52cmlu Zy51c2VkLT5mbGFncyAmIFZSSU5HX1VTRURfRl9OT19OT1RJRlkpIHsKPiA+ID4+PiAgICAgICAg ICAgIHJldHVybjsKPiA+ID4+PiAgICAgICAgfQo+ID4gPj4+Cj4gPiA+Pj4gICAgICAgIGV2ZW50 X25vdGlmaWVyX3NldCgmc3ZxLT5oZGV2X2tpY2spOwo+ID4gPj4+ICAgIH0KPiA+ID4+Pgo+ID4g Pj4+IC0vKiBGb3J3YXJkIHZob3N0IG5vdGlmaWNhdGlvbnMgKi8KPiA+ID4+PiArLyoqCj4gPiA+ Pj4gKyAqIEZvcndhcmQgYXZhaWxhYmxlIGJ1ZmZlcnMuCj4gPiA+Pj4gKyAqCj4gPiA+Pj4gKyAq IEBzdnEgU2hhZG93IFZpcnRRdWV1ZQo+ID4gPj4+ICsgKgo+ID4gPj4+ICsgKiBOb3RlIHRoYXQg dGhpcyBmdW5jdGlvbiBkb2VzIG5vdCBndWFyYW50ZWUgdGhhdCBhbGwgZ3Vlc3QncyBhdmFpbGFi bGUKPiA+ID4+PiArICogYnVmZmVycyBhcmUgYXZhaWxhYmxlIHRvIHRoZSBkZXZpY2UgaW4gU1ZR IGF2YWlsIHJpbmcuIFRoZSBndWVzdCBtYXkgaGF2ZQo+ID4gPj4+ICsgKiBleHBvc2VkIGEgR1BB IC8gR0lPVkEgY29uZ2l1b3VzIGJ1ZmZlciwgYnV0IGl0IG1heSBub3QgYmUgY29udGlndW91cyBp biBxZW11Cj4gPiA+Pj4gKyAqIHZhZGRyLgo+ID4gPj4+ICsgKgo+ID4gPj4+ICsgKiBJZiB0aGF0 IGhhcHBlbnMsIGd1ZXN0J3Mga2ljayBub3RpZmljYXRpb25zIHdpbGwgYmUgZGlzYWJsZWQgdW50 aWwgZGV2aWNlCj4gPiA+Pj4gKyAqIG1ha2VzIHNvbWUgYnVmZmVycyB1c2VkLgo+ID4gPj4+ICsg Ki8KPiA+ID4+PiArc3RhdGljIHZvaWQgdmhvc3RfaGFuZGxlX2d1ZXN0X2tpY2soVmhvc3RTaGFk b3dWaXJ0cXVldWUgKnN2cSkKPiA+ID4+PiArewo+ID4gPj4+ICsgICAgLyogQ2xlYXIgZXZlbnQg bm90aWZpZXIgKi8KPiA+ID4+PiArICAgIGV2ZW50X25vdGlmaWVyX3Rlc3RfYW5kX2NsZWFyKCZz dnEtPnN2cV9raWNrKTsKPiA+ID4+PiArCj4gPiA+Pj4gKyAgICAvKiBNYWtlIGF2YWlsYWJsZSBh cyBtYW55IGJ1ZmZlcnMgYXMgcG9zc2libGUgKi8KPiA+ID4+PiArICAgIGRvIHsKPiA+ID4+PiAr ICAgICAgICBpZiAodmlydGlvX3F1ZXVlX2dldF9ub3RpZmljYXRpb24oc3ZxLT52cSkpIHsKPiA+ ID4+PiArICAgICAgICAgICAgdmlydGlvX3F1ZXVlX3NldF9ub3RpZmljYXRpb24oc3ZxLT52cSwg ZmFsc2UpOwo+ID4gPj4KPiA+ID4+IFRoaXMgbG9va3MgbGlrZSBhbiBvcHRpbWl6YXRpb24gdGhl IHNob3VsZCBiZWxvbmcgdG8KPiA+ID4+IHZpcnRpb19xdWV1ZV9zZXRfbm90aWZpY2F0aW9uKCkg aXRzZWxmLgo+ID4gPj4KPiA+ID4gU3VyZSB3ZSBjYW4gbW92ZS4KPiA+ID4KPiA+ID4+PiArICAg ICAgICB9Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgICAgIHdoaWxlICh0cnVlKSB7Cj4gPiA+Pj4g KyAgICAgICAgICAgIFZpcnRRdWV1ZUVsZW1lbnQgKmVsZW07Cj4gPiA+Pj4gKwo+ID4gPj4+ICsg ICAgICAgICAgICBpZiAoc3ZxLT5uZXh0X2d1ZXN0X2F2YWlsX2VsZW0pIHsKPiA+ID4+PiArICAg ICAgICAgICAgICAgIGVsZW0gPSBnX3N0ZWFsX3BvaW50ZXIoJnN2cS0+bmV4dF9ndWVzdF9hdmFp bF9lbGVtKTsKPiA+ID4+PiArICAgICAgICAgICAgfSBlbHNlIHsKPiA+ID4+PiArICAgICAgICAg ICAgICAgIGVsZW0gPSB2aXJ0cXVldWVfcG9wKHN2cS0+dnEsIHNpemVvZigqZWxlbSkpOwo+ID4g Pj4+ICsgICAgICAgICAgICB9Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgICAgICAgICBpZiAoIWVs ZW0pIHsKPiA+ID4+PiArICAgICAgICAgICAgICAgIGJyZWFrOwo+ID4gPj4+ICsgICAgICAgICAg ICB9Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgICAgICAgICBpZiAoZWxlbS0+b3V0X251bSArIGVs ZW0tPmluX251bSA+Cj4gPiA+Pj4gKyAgICAgICAgICAgICAgICB2aG9zdF9zdnFfYXZhaWxhYmxl X3Nsb3RzKHN2cSkpIHsKPiA+ID4+PiArICAgICAgICAgICAgICAgIC8qCj4gPiA+Pj4gKyAgICAg ICAgICAgICAgICAgKiBUaGlzIGNvbmRpdGlvbiBpcyBwb3NzaWJsZSBzaW5jZSBhIGNvbnRpZ3Vv dXMgYnVmZmVyIGluIEdQQQo+ID4gPj4+ICsgICAgICAgICAgICAgICAgICogZG9lcyBub3QgaW1w bHkgYSBjb250aWd1b3VzIGJ1ZmZlciBpbiBxZW11J3MgVkEKPiA+ID4+PiArICAgICAgICAgICAg ICAgICAqIHNjYXR0ZXItZ2F0aGVyIHNlZ21lbnRzLiBJZiB0aGF0IGhhcHBlbiwgdGhlIGJ1ZmZl ciBleHBvc2VkCj4gPiA+Pj4gKyAgICAgICAgICAgICAgICAgKiB0byB0aGUgZGV2aWNlIG5lZWRz IHRvIGJlIGEgY2hhaW4gb2YgZGVzY3JpcHRvcnMgYXQgdGhpcwo+ID4gPj4+ICsgICAgICAgICAg ICAgICAgICogbW9tZW50Lgo+ID4gPj4+ICsgICAgICAgICAgICAgICAgICoKPiA+ID4+PiArICAg ICAgICAgICAgICAgICAqIFNWUSBjYW5ub3QgaG9sZCBtb3JlIGF2YWlsYWJsZSBidWZmZXJzIGlm IHdlIGFyZSBoZXJlOgo+ID4gPj4+ICsgICAgICAgICAgICAgICAgICogcXVldWUgdGhlIGN1cnJl bnQgZ3Vlc3QgZGVzY3JpcHRvciBhbmQgaWdub3JlIGZ1cnRoZXIga2lja3MKPiA+ID4+PiArICAg ICAgICAgICAgICAgICAqIHVudGlsIHNvbWUgZWxlbWVudHMgYXJlIHVzZWQuCj4gPiA+Pj4gKyAg ICAgICAgICAgICAgICAgKi8KPiA+ID4+PiArICAgICAgICAgICAgICAgIHN2cS0+bmV4dF9ndWVz dF9hdmFpbF9lbGVtID0gZWxlbTsKPiA+ID4+PiArICAgICAgICAgICAgICAgIHJldHVybjsKPiA+ ID4+PiArICAgICAgICAgICAgfQo+ID4gPj4+ICsKPiA+ID4+PiArICAgICAgICAgICAgdmhvc3Rf c3ZxX2FkZChzdnEsIGVsZW0pOwo+ID4gPj4+ICsgICAgICAgICAgICB2aG9zdF9zdnFfa2ljayhz dnEpOwo+ID4gPj4+ICsgICAgICAgIH0KPiA+ID4+PiArCj4gPiA+Pj4gKyAgICAgICAgdmlydGlv X3F1ZXVlX3NldF9ub3RpZmljYXRpb24oc3ZxLT52cSwgdHJ1ZSk7Cj4gPiA+Pj4gKyAgICB9IHdo aWxlICghdmlydGlvX3F1ZXVlX2VtcHR5KHN2cS0+dnEpKTsKPiA+ID4+PiArfQo+ID4gPj4+ICsK PiA+ID4+PiArLyoqCj4gPiA+Pj4gKyAqIEhhbmRsZSBndWVzdCdzIGtpY2suCj4gPiA+Pj4gKyAq Cj4gPiA+Pj4gKyAqIEBuIGd1ZXN0IGtpY2sgZXZlbnQgbm90aWZpZXIsIHRoZSBvbmUgdGhhdCBn dWVzdCBzZXQgdG8gbm90aWZ5IHN2cS4KPiA+ID4+PiArICovCj4gPiA+Pj4gK3N0YXRpYyB2b2lk IHZob3N0X2hhbmRsZV9ndWVzdF9raWNrX25vdGlmaWVyKEV2ZW50Tm90aWZpZXIgKm4pCj4gPiA+ Pj4gK3sKPiA+ID4+PiArICAgIFZob3N0U2hhZG93VmlydHF1ZXVlICpzdnEgPSBjb250YWluZXJf b2YobiwgVmhvc3RTaGFkb3dWaXJ0cXVldWUsCj4gPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgIHN2cV9raWNrKTsKPiA+ID4+PiArICAgIHZob3N0X2hh bmRsZV9ndWVzdF9raWNrKHN2cSk7Cj4gPiA+Pj4gK30KPiA+ID4+PiArCj4gPiA+Pj4gK3N0YXRp YyBib29sIHZob3N0X3N2cV9tb3JlX3VzZWQoVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSkKPiA+ ID4+PiArewo+ID4gPj4+ICsgICAgaWYgKHN2cS0+bGFzdF91c2VkX2lkeCAhPSBzdnEtPnNoYWRv d191c2VkX2lkeCkgewo+ID4gPj4+ICsgICAgICAgIHJldHVybiB0cnVlOwo+ID4gPj4+ICsgICAg fQo+ID4gPj4+ICsKPiA+ID4+PiArICAgIHN2cS0+c2hhZG93X3VzZWRfaWR4ID0gY3B1X3RvX2xl MTYoc3ZxLT52cmluZy51c2VkLT5pZHgpOwo+ID4gPj4+ICsKPiA+ID4+PiArICAgIHJldHVybiBz dnEtPmxhc3RfdXNlZF9pZHggIT0gc3ZxLT5zaGFkb3dfdXNlZF9pZHg7Cj4gPiA+Pj4gK30KPiA+ ID4+PiArCj4gPiA+Pj4gK3N0YXRpYyBWaXJ0UXVldWVFbGVtZW50ICp2aG9zdF9zdnFfZ2V0X2J1 ZihWaG9zdFNoYWRvd1ZpcnRxdWV1ZSAqc3ZxKQo+ID4gPj4+ICt7Cj4gPiA+Pj4gKyAgICB2cmlu Z19kZXNjX3QgKmRlc2NzID0gc3ZxLT52cmluZy5kZXNjOwo+ID4gPj4+ICsgICAgY29uc3QgdnJp bmdfdXNlZF90ICp1c2VkID0gc3ZxLT52cmluZy51c2VkOwo+ID4gPj4+ICsgICAgdnJpbmdfdXNl ZF9lbGVtX3QgdXNlZF9lbGVtOwo+ID4gPj4+ICsgICAgdWludDE2X3QgbGFzdF91c2VkOwo+ID4g Pj4+ICsKPiA+ID4+PiArICAgIGlmICghdmhvc3Rfc3ZxX21vcmVfdXNlZChzdnEpKSB7Cj4gPiA+ Pj4gKyAgICAgICAgcmV0dXJuIE5VTEw7Cj4gPiA+Pj4gKyAgICB9Cj4gPiA+Pj4gKwo+ID4gPj4+ ICsgICAgLyogT25seSBnZXQgdXNlZCBhcnJheSBlbnRyaWVzIGFmdGVyIHRoZXkgaGF2ZSBiZWVu IGV4cG9zZWQgYnkgZGV2ICovCj4gPiA+Pj4gKyAgICBzbXBfcm1iKCk7Cj4gPiA+Pj4gKyAgICBs YXN0X3VzZWQgPSBzdnEtPmxhc3RfdXNlZF9pZHggJiAoc3ZxLT52cmluZy5udW0gLSAxKTsKPiA+ ID4+PiArICAgIHVzZWRfZWxlbS5pZCA9IGxlMzJfdG9fY3B1KHVzZWQtPnJpbmdbbGFzdF91c2Vk XS5pZCk7Cj4gPiA+Pj4gKyAgICB1c2VkX2VsZW0ubGVuID0gbGUzMl90b19jcHUodXNlZC0+cmlu Z1tsYXN0X3VzZWRdLmxlbik7Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgc3ZxLT5sYXN0X3VzZWRf aWR4Kys7Cj4gPiA+Pj4gKyAgICBpZiAodW5saWtlbHkodXNlZF9lbGVtLmlkID49IHN2cS0+dnJp bmcubnVtKSkgewo+ID4gPj4+ICsgICAgICAgIGVycm9yX3JlcG9ydCgiRGV2aWNlICVzIHNheXMg aW5kZXggJXUgaXMgdXNlZCIsIHN2cS0+dmRldi0+bmFtZSwKPiA+ID4+PiArICAgICAgICAgICAg ICAgICAgICAgdXNlZF9lbGVtLmlkKTsKPiA+ID4+PiArICAgICAgICByZXR1cm4gTlVMTDsKPiA+ ID4+PiArICAgIH0KPiA+ID4+PiArCj4gPiA+Pj4gKyAgICBpZiAodW5saWtlbHkoIXN2cS0+cmlu Z19pZF9tYXBzW3VzZWRfZWxlbS5pZF0pKSB7Cj4gPiA+Pj4gKyAgICAgICAgZXJyb3JfcmVwb3J0 KAo+ID4gPj4+ICsgICAgICAgICAgICAiRGV2aWNlICVzIHNheXMgaW5kZXggJXUgaXMgdXNlZCwg YnV0IGl0IHdhcyBub3QgYXZhaWxhYmxlIiwKPiA+ID4+PiArICAgICAgICAgICAgc3ZxLT52ZGV2 LT5uYW1lLCB1c2VkX2VsZW0uaWQpOwo+ID4gPj4+ICsgICAgICAgIHJldHVybiBOVUxMOwo+ID4g Pj4+ICsgICAgfQo+ID4gPj4+ICsKPiA+ID4+PiArICAgIGRlc2NzW3VzZWRfZWxlbS5pZF0ubmV4 dCA9IHN2cS0+ZnJlZV9oZWFkOwo+ID4gPj4+ICsgICAgc3ZxLT5mcmVlX2hlYWQgPSB1c2VkX2Vs ZW0uaWQ7Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgc3ZxLT5yaW5nX2lkX21hcHNbdXNlZF9lbGVt LmlkXS0+bGVuID0gdXNlZF9lbGVtLmxlbjsKPiA+ID4+PiArICAgIHJldHVybiBnX3N0ZWFsX3Bv aW50ZXIoJnN2cS0+cmluZ19pZF9tYXBzW3VzZWRfZWxlbS5pZF0pOwo+ID4gPj4+ICt9Cj4gPiA+ Pj4gKwo+ID4gPj4+ICtzdGF0aWMgdm9pZCB2aG9zdF9zdnFfZmx1c2goVmhvc3RTaGFkb3dWaXJ0 cXVldWUgKnN2cSwKPiA+ID4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJvb2wgY2hl Y2tfZm9yX2F2YWlsX3F1ZXVlKQo+ID4gPj4+ICt7Cj4gPiA+Pj4gKyAgICBWaXJ0UXVldWUgKnZx ID0gc3ZxLT52cTsKPiA+ID4+PiArCj4gPiA+Pj4gKyAgICAvKiBNYWtlIGFzIG1hbnkgYnVmZmVy cyBhcyBwb3NzaWJsZSB1c2VkLiAqLwo+ID4gPj4+ICsgICAgZG8gewo+ID4gPj4+ICsgICAgICAg IHVuc2lnbmVkIGkgPSAwOwo+ID4gPj4+ICsKPiA+ID4+PiArICAgICAgICB2aG9zdF9zdnFfc2V0 X25vdGlmaWNhdGlvbihzdnEsIGZhbHNlKTsKPiA+ID4+PiArICAgICAgICB3aGlsZSAodHJ1ZSkg ewo+ID4gPj4+ICsgICAgICAgICAgICBnX2F1dG9mcmVlIFZpcnRRdWV1ZUVsZW1lbnQgKmVsZW0g PSB2aG9zdF9zdnFfZ2V0X2J1ZihzdnEpOwo+ID4gPj4+ICsgICAgICAgICAgICBpZiAoIWVsZW0p IHsKPiA+ID4+PiArICAgICAgICAgICAgICAgIGJyZWFrOwo+ID4gPj4+ICsgICAgICAgICAgICB9 Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgICAgICAgICBpZiAodW5saWtlbHkoaSA+PSBzdnEtPnZy aW5nLm51bSkpIHsKPiA+ID4+PiArICAgICAgICAgICAgICAgIHZpcnRpb19lcnJvcihzdnEtPnZk ZXYsCj4gPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAiTW9yZSB0aGFuICV1IHVzZWQg YnVmZmVycyBvYnRhaW5lZCBpbiBhICV1IHNpemUgU1ZRIiwKPiA+ID4+PiArICAgICAgICAgICAg ICAgICAgICAgICAgIGksIHN2cS0+dnJpbmcubnVtKTsKPiA+ID4+PiArICAgICAgICAgICAgICAg IHZpcnRxdWV1ZV9maWxsKHZxLCBlbGVtLCBlbGVtLT5sZW4sIGkpOwo+ID4gPj4+ICsgICAgICAg ICAgICAgICAgdmlydHF1ZXVlX2ZsdXNoKHZxLCBpKTsKPiA+ID4+Cj4gPiA+PiBMZXQncyBzaW1w bHkgdXNlIHZpcnRxdWV1ZV9wdXNoKCkgaGVyZT8KPiA+ID4+Cj4gPiA+IHZpcnRxdWV1ZV9wdXNo IHN1cHBvcnQgdG8gZmlsbCBhbmQgZmx1c2ggb25seSBvbmUgZWxlbWVudCwgaW5zdGVhZCBvZgo+ ID4gPiBiYXRjaC4gSSdtIGZpbmUgd2l0aCBlaXRoZXIgYnV0IEkgdGhpbmsgdGhlIGxlc3MgdXBk YXRlcyB0byB0aGUgdXNlZAo+ID4gPiBpZHgsIHRoZSBiZXR0ZXIuCj4gPgo+ID4KPiA+IEZpbmUu Cj4gPgo+ID4KPiA+ID4KPiA+ID4+PiArICAgICAgICAgICAgICAgIGkgPSAwOwo+ID4gPj4KPiA+ ID4+IERvIHdlIG5lZWQgdG8gYmFpbCBvdXQgaGVyZT8KPiA+ID4+Cj4gPiA+IFllcyBJIGd1ZXNz IHdlIGNhbiBzaW1wbHkgcmV0dXJuLgo+ID4gPgo+ID4gPj4+ICsgICAgICAgICAgICB9Cj4gPiA+ Pj4gKyAgICAgICAgICAgIHZpcnRxdWV1ZV9maWxsKHZxLCBlbGVtLCBlbGVtLT5sZW4sIGkrKyk7 Cj4gPiA+Pj4gKyAgICAgICAgfQo+ID4gPj4+ICsKPiA+ID4+PiArICAgICAgICB2aXJ0cXVldWVf Zmx1c2godnEsIGkpOwo+ID4gPj4+ICsgICAgICAgIGV2ZW50X25vdGlmaWVyX3NldCgmc3ZxLT5z dnFfY2FsbCk7Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgICAgIGlmIChjaGVja19mb3JfYXZhaWxf cXVldWUgJiYgc3ZxLT5uZXh0X2d1ZXN0X2F2YWlsX2VsZW0pIHsKPiA+ID4+PiArICAgICAgICAg ICAgLyoKPiA+ID4+PiArICAgICAgICAgICAgICogQXZhaWwgcmluZyB3YXMgZnVsbCB3aGVuIHZo b3N0X3N2cV9mbHVzaCB3YXMgY2FsbGVkLCBzbyBpdCdzIGEKPiA+ID4+PiArICAgICAgICAgICAg ICogZ29vZCBtb21lbnQgdG8gbWFrZSBtb3JlIGRlc2NyaXB0b3JzIGF2YWlsYWJsZSBpZiBwb3Nz aWJsZQo+ID4gPj4+ICsgICAgICAgICAgICAgKi8KPiA+ID4+PiArICAgICAgICAgICAgdmhvc3Rf aGFuZGxlX2d1ZXN0X2tpY2soc3ZxKTsKPiA+ID4+Cj4gPiA+PiBJcyB0aGVyZSBiZXR0ZXIgdG8g aGF2ZSBhIHNpbWlsYXIgY2hlY2sgYXMgdmhvc3RfaGFuZGxlX2d1ZXN0X2tpY2soKSBkaWQ/Cj4g PiA+Pgo+ID4gPj4gICAgICAgICAgICAgICBpZiAoZWxlbS0+b3V0X251bSArIGVsZW0tPmluX251 bSA+Cj4gPiA+PiAgICAgICAgICAgICAgICAgICB2aG9zdF9zdnFfYXZhaWxhYmxlX3Nsb3RzKHN2 cSkpIHsKPiA+ID4+Cj4gPiA+IEl0IHdpbGwgYmUgZHVwbGljYXRlZCB3aGVuIHdlIGNhbGwgdmhv c3RfaGFuZGxlX2d1ZXN0X2tpY2ssIHdvbid0IGl0Pwo+ID4KPiA+Cj4gPiBSaWdodCwgSSBtaXMt cmVhZCB0aGUgY29kZS4KPiA+Cj4gPgo+ID4gPgo+ID4gPj4+ICsgICAgICAgIH0KPiA+ID4+PiAr Cj4gPiA+Pj4gKyAgICAgICAgdmhvc3Rfc3ZxX3NldF9ub3RpZmljYXRpb24oc3ZxLCB0cnVlKTsK PiA+ID4+Cj4gPiA+PiBBIG1iKCkgaXMgbmVlZGVkIGhlcmU/IE90aGVyd2lzZSB3ZSBtYXkgbG9z dCBhIGNhbGwgaGVyZSAod2hlcmUKPiA+ID4+IHZob3N0X3N2cV9tb3JlX3VzZWQoKSBpcyBydW4g YmVmb3JlIHZob3N0X3N2cV9zZXRfbm90aWZpY2F0aW9uKCkpLgo+ID4gPj4KPiA+ID4gSSdtIGNv bmZ1c2VkIGhlcmUgdGhlbiwgSSB0aG91Z2h0IHlvdSBzYWlkIHRoaXMgaXMganVzdCBhIGhpbnQg c28KPiA+ID4gdGhlcmUgd2FzIG5vIG5lZWQ/IFsxXS4gSSB0aGluayB0aGUgbWVtb3J5IGJhcnJp ZXIgaXMgbmVlZGVkIHRvby4KPiA+Cj4gPgo+ID4gWWVzLCBpdCdzIGEgaGludCBidXQ6Cj4gPgo+ ID4gMSkgV2hlbiB3ZSBkaXNhYmxlIHRoZSBub3RpZmljYXRpb24sIGNvbnNpZGVyIHRoZSBub3Rp ZmljYXRpb24gZGlzYWJsZQo+ID4gaXMganVzdCBhIGhpbnQsIGRldmljZSBjYW4gc3RpbGwgcmFp c2UgYW4gaW50ZXJydXB0LCBzbyB0aGUgb3JkZXJpbmcgaXMKPiA+IG1lYW5pbmdsZXNzIGFuZCBh IG1lbW9yeSBiYXJyaWVyIGlzIG5vdCBuZWNlc3NhcnkgKHRoZQo+ID4gdmhvc3Rfc3ZxX3NldF9u b3RpZmljYXRpb24oc3ZxLCBmYWxzZSkpCj4gPgo+ID4gMikgV2hlbiB3ZSBlbmFibGUgdGhlIG5v dGlmaWNhdGlvbiwgdGhvdWdoIGl0J3MgYSBoaW50LCB0aGUgZGV2aWNlIGNhbgo+ID4gY2hvb3Nl IHRvIGltcGxlbWVudCBpdCBieSBlbmFibGluZyB0aGUgaW50ZXJydXB0LCBpbiB0aGlzIGNhc2Us IHRoZQo+ID4gbm90aWZpY2F0aW9uIGVuYWJsZSBzaG91bGQgYmUgZG9uZSBiZWZvcmUgY2hlY2tp bmcgdGhlIHVzZWQuIE90aGVyd2lzZSwKPiA+IHRoZSBjaGVja2luZyBvZiBtb3JlIHVzZWQgbWln aHQgYmUgZG9uZSBiZWZvcmUgZW5hYmxlIHRoZSBub3RpZmljYXRpb246Cj4gPgo+ID4gMSkgZHJp dmVyIGNoZWNrIG1vcmUgdXNlZAo+ID4gMikgZGV2aWNlIGFkZCBtb3JlIHVzZWQgYnV0IG5vIG5v dGlmaWNhdGlvbgo+ID4gMykgZHJpdmVyIGVuYWJsZSB0aGUgbm90aWZpY2F0aW9uIHRoZW4gd2Ug bG9zdCBhIG5vdGlmaWNhdGlvbiBoZXJlCj4gPgo+Cj4gVGhhdCB3YXMgbXkgdW5kZXJzdGFuZGlu ZyB0b28uIFNvIHRoZSByaWdodCB3YXkgaXMgdG8gb25seSBhZGQgdGhlCj4gbWVtb3J5IGJhcnJp ZXIgaW4gY2FzZSAyKSwgd2hlbiBzZXR0aW5nIHRoZSBmbGFnLCByaWdodD8KClllcy4KCj4KPiA+ Cj4gPiA+Pj4gKyAgICB9IHdoaWxlICh2aG9zdF9zdnFfbW9yZV91c2VkKHN2cSkpOwo+ID4gPj4+ ICt9Cj4gPiA+Pj4gKwo+ID4gPj4+ICsvKioKPiA+ID4+PiArICogRm9yd2FyZCB1c2VkIGJ1ZmZl cnMuCj4gPiA+Pj4gKyAqCj4gPiA+Pj4gKyAqIEBuIGhkZXYgY2FsbCBldmVudCBub3RpZmllciwg dGhlIG9uZSB0aGF0IGRldmljZSBzZXQgdG8gbm90aWZ5IHN2cS4KPiA+ID4+PiArICoKPiA+ID4+ PiArICogTm90ZSB0aGF0IHdlIGFyZSBub3QgbWFraW5nIGFueSBidWZmZXJzIGF2YWlsYWJsZSBp biB0aGUgbG9vcCwgdGhlcmUgaXMgbm8KPiA+ID4+PiArICogd2F5IHRoYXQgaXQgcnVucyBtb3Jl IHRoYW4gdmlydHF1ZXVlIHNpemUgdGltZXMuCj4gPiA+Pj4gKyAqLwo+ID4gPj4+ICAgIHN0YXRp YyB2b2lkIHZob3N0X3N2cV9oYW5kbGVfY2FsbChFdmVudE5vdGlmaWVyICpuKQo+ID4gPj4+ICAg IHsKPiA+ID4+PiAgICAgICAgVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSA9IGNvbnRhaW5lcl9v ZihuLCBWaG9zdFNoYWRvd1ZpcnRxdWV1ZSwKPiA+ID4+PiAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICBoZGV2X2NhbGwpOwo+ID4gPj4+Cj4gPiA+Pj4gLSAg ICBpZiAodW5saWtlbHkoIWV2ZW50X25vdGlmaWVyX3Rlc3RfYW5kX2NsZWFyKG4pKSkgewo+ID4g Pj4+IC0gICAgICAgIHJldHVybjsKPiA+ID4+PiAtICAgIH0KPiA+ID4+PiArICAgIC8qIENsZWFy IGV2ZW50IG5vdGlmaWVyICovCj4gPiA+Pj4gKyAgICBldmVudF9ub3RpZmllcl90ZXN0X2FuZF9j bGVhcihuKTsKPiA+ID4+Cj4gPiA+PiBBbnkgcmVhc29uIHRoYXQgd2UgcmVtb3ZlIHRoZSBhYm92 ZSBjaGVjaz8KPiA+ID4+Cj4gPiA+IFRoaXMgY29tZXMgZnJvbSB0aGUgcHJldmlvdXMgdmVyc2lv bnMsIHdoZXJlIHRoaXMgbWFkZSBzdXJlIHdlIG1pc3NlZAo+ID4gPiBubyB1c2VkIGJ1ZmZlcnMg aW4gdGhlIHByb2Nlc3Mgb2Ygc3dpdGNoaW5nIHRvIFNWUSBtb2RlLgo+ID4KPiA+Cj4gPiBJJ20g bm90IHN1cmUgSSBnZXQgaGVyZS4gRXZlbiBpZiBmb3IgdGhlIHN3aXRjaGluZywgaXQgc2hvdWxk IGJlIG1vcmUKPiA+IHNhZmUgdGhlIGhhbmRsZSB0aGUgZmx1c2ggdW5jb25kaXRpb25hbGx5Pwo+ ID4KPgo+IFllcywgSSBhbHNvIHRoaW5rIGl0J3MgYmV0dGVyIHRvIGZvcndhcmQgYW5kIGtpY2sv Y2FsbCB1bmNvbmRpdGlvbmFsbHkuCj4KPiBUaGFua3MhCgpPay4KClRoYW5rcwoKPgo+ID4gVGhh bmtzCj4gPgo+ID4KPiA+ID4KPiA+ID4gSWYgd2UgZW5hYmxlIFNWUSBmcm9tIHRoZSBiZWdpbm5p bmcgSSB0aGluayB3ZSBjYW4gcmVseSBvbiBnZXR0aW5nIGFsbAo+ID4gPiB0aGUgZGV2aWNlJ3Mg dXNlZCBidWZmZXIgbm90aWZpY2F0aW9ucywgc28gbGV0IG1lIHRoaW5rIGEgbGl0dGxlIGJpdAo+ ID4gPiBhbmQgSSBjYW4gbW92ZSB0byBjaGVjayB0aGUgZXZlbnRmZC4KPiA+ID4KPiA+ID4+PiAt ICAgIGV2ZW50X25vdGlmaWVyX3NldCgmc3ZxLT5zdnFfY2FsbCk7Cj4gPiA+Pj4gKyAgICB2aG9z dF9zdnFfZmx1c2goc3ZxLCB0cnVlKTsKPiA+ID4+PiAgICB9Cj4gPiA+Pj4KPiA+ID4+PiAgICAv KioKPiA+ID4+PiBAQCAtMjU4LDEzICs1NTEsMzggQEAgdm9pZCB2aG9zdF9zdnFfc2V0X3N2cV9r aWNrX2ZkKFZob3N0U2hhZG93VmlydHF1ZXVlICpzdnEsIGludCBzdnFfa2lja19mZCkKPiA+ID4+ PiAgICAgICAgICogbmVlZCB0byBleHBsaWNpdGVseSBjaGVjayBmb3IgdGhlbS4KPiA+ID4+PiAg ICAgICAgICovCj4gPiA+Pj4gICAgICAgIGV2ZW50X25vdGlmaWVyX2luaXRfZmQoJnN2cS0+c3Zx X2tpY2ssIHN2cV9raWNrX2ZkKTsKPiA+ID4+PiAtICAgIGV2ZW50X25vdGlmaWVyX3NldF9oYW5k bGVyKCZzdnEtPnN2cV9raWNrLCB2aG9zdF9oYW5kbGVfZ3Vlc3Rfa2ljayk7Cj4gPiA+Pj4gKyAg ICBldmVudF9ub3RpZmllcl9zZXRfaGFuZGxlcigmc3ZxLT5zdnFfa2ljaywKPiA+ID4+PiArICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZob3N0X2hhbmRsZV9ndWVzdF9raWNrX25vdGlm aWVyKTsKPiA+ID4+Pgo+ID4gPj4+ICAgICAgICBpZiAoIWNoZWNrX29sZCB8fCBldmVudF9ub3Rp Zmllcl90ZXN0X2FuZF9jbGVhcigmdG1wKSkgewo+ID4gPj4+ICAgICAgICAgICAgZXZlbnRfbm90 aWZpZXJfc2V0KCZzdnEtPmhkZXZfa2ljayk7Cj4gPiA+Pj4gICAgICAgIH0KPiA+ID4+PiAgICB9 Cj4gPiA+Pj4KPiA+ID4+PiArLyoqCj4gPiA+Pj4gKyAqIFN0YXJ0IHNoYWRvdyB2aXJ0cXVldWUg b3BlcmF0aW9uLgo+ID4gPj4+ICsgKgo+ID4gPj4+ICsgKiBAc3ZxIFNoYWRvdyBWaXJ0cXVldWUK PiA+ID4+PiArICogQHZkZXYgICAgICAgIFZpcnRJTyBkZXZpY2UKPiA+ID4+PiArICogQHZxICAg ICAgICAgIFZpcnRxdWV1ZSB0byBzaGFkb3cKPiA+ID4+PiArICovCj4gPiA+Pj4gK3ZvaWQgdmhv c3Rfc3ZxX3N0YXJ0KFZob3N0U2hhZG93VmlydHF1ZXVlICpzdnEsIFZpcnRJT0RldmljZSAqdmRl diwKPiA+ID4+PiArICAgICAgICAgICAgICAgICAgICAgVmlydFF1ZXVlICp2cSkKPiA+ID4+PiAr ewo+ID4gPj4+ICsgICAgc3ZxLT5uZXh0X2d1ZXN0X2F2YWlsX2VsZW0gPSBOVUxMOwo+ID4gPj4+ ICsgICAgc3ZxLT5hdmFpbF9pZHhfc2hhZG93ID0gMDsKPiA+ID4+PiArICAgIHN2cS0+c2hhZG93 X3VzZWRfaWR4ID0gMDsKPiA+ID4+PiArICAgIHN2cS0+bGFzdF91c2VkX2lkeCA9IDA7Cj4gPiA+ Pj4gKyAgICBzdnEtPnZkZXYgPSB2ZGV2Owo+ID4gPj4+ICsgICAgc3ZxLT52cSA9IHZxOwo+ID4g Pj4+ICsKPiA+ID4+PiArICAgIG1lbXNldChzdnEtPnZyaW5nLmF2YWlsLCAwLCBzaXplb2YoKnN2 cS0+dnJpbmcuYXZhaWwpKTsKPiA+ID4+PiArICAgIG1lbXNldChzdnEtPnZyaW5nLnVzZWQsIDAs IHNpemVvZigqc3ZxLT52cmluZy5hdmFpbCkpOwo+ID4gPj4+ICsgICAgZm9yICh1bnNpZ25lZCBp ID0gMDsgaSA8IHN2cS0+dnJpbmcubnVtIC0gMTsgaSsrKSB7Cj4gPiA+Pj4gKyAgICAgICAgc3Zx LT52cmluZy5kZXNjW2ldLm5leHQgPSBjcHVfdG9fbGUxNihpICsgMSk7Cj4gPiA+Pj4gKyAgICB9 Cj4gPiA+Pj4gK30KPiA+ID4+PiArCj4gPiA+Pj4gICAgLyoqCj4gPiA+Pj4gICAgICogU3RvcCBz aGFkb3cgdmlydHF1ZXVlIG9wZXJhdGlvbi4KPiA+ID4+PiAgICAgKiBAc3ZxIFNoYWRvdyBWaXJ0 cXVldWUKPiA+ID4+PiBAQCAtMjcyLDYgKzU5MCwyOCBAQCB2b2lkIHZob3N0X3N2cV9zZXRfc3Zx X2tpY2tfZmQoVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSwgaW50IHN2cV9raWNrX2ZkKQo+ID4g Pj4+ICAgIHZvaWQgdmhvc3Rfc3ZxX3N0b3AoVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSkKPiA+ ID4+PiAgICB7Cj4gPiA+Pj4gICAgICAgIGV2ZW50X25vdGlmaWVyX3NldF9oYW5kbGVyKCZzdnEt PnN2cV9raWNrLCBOVUxMKTsKPiA+ID4+PiArICAgIGdfYXV0b2ZyZWUgVmlydFF1ZXVlRWxlbWVu dCAqbmV4dF9hdmFpbF9lbGVtID0gTlVMTDsKPiA+ID4+PiArCj4gPiA+Pj4gKyAgICBpZiAoIXN2 cS0+dnEpIHsKPiA+ID4+PiArICAgICAgICByZXR1cm47Cj4gPiA+Pj4gKyAgICB9Cj4gPiA+Pj4g Kwo+ID4gPj4+ICsgICAgLyogU2VuZCBhbGwgcGVuZGluZyB1c2VkIGRlc2NyaXB0b3JzIHRvIGd1 ZXN0ICovCj4gPiA+Pj4gKyAgICB2aG9zdF9zdnFfZmx1c2goc3ZxLCBmYWxzZSk7Cj4gPiA+Pj4g Kwo+ID4gPj4+ICsgICAgZm9yICh1bnNpZ25lZCBpID0gMDsgaSA8IHN2cS0+dnJpbmcubnVtOyAr K2kpIHsKPiA+ID4+PiArICAgICAgICBnX2F1dG9mcmVlIFZpcnRRdWV1ZUVsZW1lbnQgKmVsZW0g PSBOVUxMOwo+ID4gPj4+ICsgICAgICAgIGVsZW0gPSBnX3N0ZWFsX3BvaW50ZXIoJnN2cS0+cmlu Z19pZF9tYXBzW2ldKTsKPiA+ID4+PiArICAgICAgICBpZiAoZWxlbSkgewo+ID4gPj4+ICsgICAg ICAgICAgICB2aXJ0cXVldWVfZGV0YWNoX2VsZW1lbnQoc3ZxLT52cSwgZWxlbSwgZWxlbS0+bGVu KTsKPiA+ID4+PiArICAgICAgICB9Cj4gPiA+Pj4gKyAgICB9Cj4gPiA+Pj4gKwo+ID4gPj4+ICsg ICAgbmV4dF9hdmFpbF9lbGVtID0gZ19zdGVhbF9wb2ludGVyKCZzdnEtPm5leHRfZ3Vlc3RfYXZh aWxfZWxlbSk7Cj4gPiA+Pj4gKyAgICBpZiAobmV4dF9hdmFpbF9lbGVtKSB7Cj4gPiA+Pj4gKyAg ICAgICAgdmlydHF1ZXVlX2RldGFjaF9lbGVtZW50KHN2cS0+dnEsIG5leHRfYXZhaWxfZWxlbSwK PiA+ID4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmV4dF9hdmFpbF9lbGVt LT5sZW4pOwo+ID4gPj4+ICsgICAgfQo+ID4gPj4+ICAgIH0KPiA+ID4+Pgo+ID4gPj4+ICAgIC8q Kgo+ID4gPj4+IEBAIC0zMTYsNyArNjU2LDcgQEAgVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnZob3N0 X3N2cV9uZXcodWludDE2X3QgcXNpemUpCj4gPiA+Pj4gICAgICAgIG1lbXNldChzdnEtPnZyaW5n LmRlc2MsIDAsIGRyaXZlcl9zaXplKTsKPiA+ID4+PiAgICAgICAgc3ZxLT52cmluZy51c2VkID0g cWVtdV9tZW1hbGlnbihxZW11X3JlYWxfaG9zdF9wYWdlX3NpemUsIGRldmljZV9zaXplKTsKPiA+ ID4+PiAgICAgICAgbWVtc2V0KHN2cS0+dnJpbmcudXNlZCwgMCwgZGV2aWNlX3NpemUpOwo+ID4g Pj4+IC0KPiA+ID4+PiArICAgIHN2cS0+cmluZ19pZF9tYXBzID0gZ19uZXcwKFZpcnRRdWV1ZUVs ZW1lbnQgKiwgcXNpemUpOwo+ID4gPj4+ICAgICAgICBldmVudF9ub3RpZmllcl9zZXRfaGFuZGxl cigmc3ZxLT5oZGV2X2NhbGwsIHZob3N0X3N2cV9oYW5kbGVfY2FsbCk7Cj4gPiA+Pj4gICAgICAg IHJldHVybiBnX3N0ZWFsX3BvaW50ZXIoJnN2cSk7Cj4gPiA+Pj4KPiA+ID4+PiBAQCAtMzM1LDYg KzY3NSw3IEBAIHZvaWQgdmhvc3Rfc3ZxX2ZyZWUoVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnZxKQo+ ID4gPj4+ICAgICAgICBldmVudF9ub3RpZmllcl9jbGVhbnVwKCZ2cS0+aGRldl9raWNrKTsKPiA+ ID4+PiAgICAgICAgZXZlbnRfbm90aWZpZXJfc2V0X2hhbmRsZXIoJnZxLT5oZGV2X2NhbGwsIE5V TEwpOwo+ID4gPj4+ICAgICAgICBldmVudF9ub3RpZmllcl9jbGVhbnVwKCZ2cS0+aGRldl9jYWxs KTsKPiA+ID4+PiArICAgIGdfZnJlZSh2cS0+cmluZ19pZF9tYXBzKTsKPiA+ID4+PiAgICAgICAg cWVtdV92ZnJlZSh2cS0+dnJpbmcuZGVzYyk7Cj4gPiA+Pj4gICAgICAgIHFlbXVfdmZyZWUodnEt PnZyaW5nLnVzZWQpOwo+ID4gPj4+ICAgICAgICBnX2ZyZWUodnEpOwo+ID4gPj4+IGRpZmYgLS1n aXQgYS9ody92aXJ0aW8vdmhvc3QtdmRwYS5jIGIvaHcvdmlydGlvL3Zob3N0LXZkcGEuYwo+ID4g Pj4+IGluZGV4IDUzZTE0YmFmYTAuLjBlNWMwMGVkN2UgMTAwNjQ0Cj4gPiA+Pj4gLS0tIGEvaHcv dmlydGlvL3Zob3N0LXZkcGEuYwo+ID4gPj4+ICsrKyBiL2h3L3ZpcnRpby92aG9zdC12ZHBhLmMK PiA+ID4+PiBAQCAtNzUyLDkgKzc1Miw5IEBAIHN0YXRpYyBpbnQgdmhvc3RfdmRwYV9zZXRfdnJp bmdfY2FsbChzdHJ1Y3Qgdmhvc3RfZGV2ICpkZXYsCj4gPiA+Pj4gICAgICogTm90ZSB0aGF0IHRo aXMgZnVuY3Rpb24gZG9lcyBub3QgcmV3aW5kIGtpY2sgZmlsZSBkZXNjcmlwdG9yIGlmIGNhbm5v dCBzZXQKPiA+ID4+PiAgICAgKiBjYWxsIG9uZS4KPiA+ID4+PiAgICAgKi8KPiA+ID4+PiAtc3Rh dGljIGJvb2wgdmhvc3RfdmRwYV9zdnFfc2V0dXAoc3RydWN0IHZob3N0X2RldiAqZGV2LAo+ID4g Pj4+IC0gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFZob3N0U2hhZG93VmlydHF1ZXVl ICpzdnEsCj4gPiA+Pj4gLSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQg aWR4KQo+ID4gPj4+ICtzdGF0aWMgaW50IHZob3N0X3ZkcGFfc3ZxX3NldF9mZHMoc3RydWN0IHZo b3N0X2RldiAqZGV2LAo+ID4gPj4+ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg Vmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSwKPiA+ID4+PiArICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgIHVuc2lnbmVkIGlkeCkKPiA+ID4+PiAgICB7Cj4gPiA+Pj4gICAgICAgIHN0 cnVjdCB2aG9zdF92cmluZ19maWxlIGZpbGUgPSB7Cj4gPiA+Pj4gICAgICAgICAgICAuaW5kZXgg PSBkZXYtPnZxX2luZGV4ICsgaWR4LAo+ID4gPj4+IEBAIC03NjcsNyArNzY3LDcgQEAgc3RhdGlj IGJvb2wgdmhvc3RfdmRwYV9zdnFfc2V0dXAoc3RydWN0IHZob3N0X2RldiAqZGV2LAo+ID4gPj4+ ICAgICAgICByID0gdmhvc3RfdmRwYV9zZXRfdnJpbmdfZGV2X2tpY2soZGV2LCAmZmlsZSk7Cj4g PiA+Pj4gICAgICAgIGlmICh1bmxpa2VseShyICE9IDApKSB7Cj4gPiA+Pj4gICAgICAgICAgICBl cnJvcl9yZXBvcnQoIkNhbid0IHNldCBkZXZpY2Uga2ljayBmZCAoJWQpIiwgLXIpOwo+ID4gPj4+ IC0gICAgICAgIHJldHVybiBmYWxzZTsKPiA+ID4+PiArICAgICAgICByZXR1cm4gcjsKPiA+ID4+ PiAgICAgICAgfQo+ID4gPj4+Cj4gPiA+Pj4gICAgICAgIGV2ZW50X25vdGlmaWVyID0gdmhvc3Rf c3ZxX2dldF9zdnFfY2FsbF9ub3RpZmllcihzdnEpOwo+ID4gPj4+IEBAIC03NzcsNiArNzc3LDk5 IEBAIHN0YXRpYyBib29sIHZob3N0X3ZkcGFfc3ZxX3NldHVwKHN0cnVjdCB2aG9zdF9kZXYgKmRl diwKPiA+ID4+PiAgICAgICAgICAgIGVycm9yX3JlcG9ydCgiQ2FuJ3Qgc2V0IGRldmljZSBjYWxs IGZkICglZCkiLCAtcik7Cj4gPiA+Pj4gICAgICAgIH0KPiA+ID4+Pgo+ID4gPj4+ICsgICAgcmV0 dXJuIHI7Cj4gPiA+Pj4gK30KPiA+ID4+PiArCj4gPiA+Pj4gKy8qKgo+ID4gPj4+ICsgKiBVbm1h cCBTVlEgYXJlYSBpbiB0aGUgZGV2aWNlCj4gPiA+Pj4gKyAqLwo+ID4gPj4+ICtzdGF0aWMgYm9v bCB2aG9zdF92ZHBhX3N2cV91bm1hcF9yaW5nKHN0cnVjdCB2aG9zdF92ZHBhICp2LCBod2FkZHIg aW92YSwKPiA+ID4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBod2Fk ZHIgc2l6ZSkKPiA+ID4+PiArewo+ID4gPj4+ICsgICAgaW50IHI7Cj4gPiA+Pj4gKwo+ID4gPj4+ ICsgICAgc2l6ZSA9IFJPVU5EX1VQKHNpemUsIHFlbXVfcmVhbF9ob3N0X3BhZ2Vfc2l6ZSk7Cj4g PiA+Pj4gKyAgICByID0gdmhvc3RfdmRwYV9kbWFfdW5tYXAodiwgaW92YSwgc2l6ZSk7Cj4gPiA+ Pj4gKyAgICByZXR1cm4gciA9PSAwOwo+ID4gPj4+ICt9Cj4gPiA+Pj4gKwo+ID4gPj4+ICtzdGF0 aWMgYm9vbCB2aG9zdF92ZHBhX3N2cV91bm1hcF9yaW5ncyhzdHJ1Y3Qgdmhvc3RfZGV2ICpkZXYs Cj4gPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IFZo b3N0U2hhZG93VmlydHF1ZXVlICpzdnEpCj4gPiA+Pj4gK3sKPiA+ID4+PiArICAgIHN0cnVjdCB2 aG9zdF92ZHBhICp2ID0gZGV2LT5vcGFxdWU7Cj4gPiA+Pj4gKyAgICBzdHJ1Y3Qgdmhvc3RfdnJp bmdfYWRkciBzdnFfYWRkcjsKPiA+ID4+PiArICAgIHNpemVfdCBkZXZpY2Vfc2l6ZSA9IHZob3N0 X3N2cV9kZXZpY2VfYXJlYV9zaXplKHN2cSk7Cj4gPiA+Pj4gKyAgICBzaXplX3QgZHJpdmVyX3Np emUgPSB2aG9zdF9zdnFfZHJpdmVyX2FyZWFfc2l6ZShzdnEpOwo+ID4gPj4+ICsgICAgYm9vbCBv azsKPiA+ID4+PiArCj4gPiA+Pj4gKyAgICB2aG9zdF9zdnFfZ2V0X3ZyaW5nX2FkZHIoc3ZxLCAm c3ZxX2FkZHIpOwo+ID4gPj4+ICsKPiA+ID4+PiArICAgIG9rID0gdmhvc3RfdmRwYV9zdnFfdW5t YXBfcmluZyh2LCBzdnFfYWRkci5kZXNjX3VzZXJfYWRkciwgZHJpdmVyX3NpemUpOwo+ID4gPj4+ ICsgICAgaWYgKHVubGlrZWx5KCFvaykpIHsKPiA+ID4+PiArICAgICAgICByZXR1cm4gZmFsc2U7 Cj4gPiA+Pj4gKyAgICB9Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgcmV0dXJuIHZob3N0X3ZkcGFf c3ZxX3VubWFwX3Jpbmcodiwgc3ZxX2FkZHIudXNlZF91c2VyX2FkZHIsIGRldmljZV9zaXplKTsK PiA+ID4+PiArfQo+ID4gPj4+ICsKPiA+ID4+PiArLyoqCj4gPiA+Pj4gKyAqIE1hcCBzaGFkb3cg dmlydHF1ZXVlIHJpbmdzIGluIGRldmljZQo+ID4gPj4+ICsgKgo+ID4gPj4+ICsgKiBAZGV2ICAg VGhlIHZob3N0IGRldmljZQo+ID4gPj4+ICsgKiBAc3ZxICAgVGhlIHNoYWRvdyB2aXJ0cXVldWUK PiA+ID4+PiArICovCj4gPiA+Pj4gK3N0YXRpYyBib29sIHZob3N0X3ZkcGFfc3ZxX21hcF9yaW5n cyhzdHJ1Y3Qgdmhvc3RfZGV2ICpkZXYsCj4gPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICBjb25zdCBWaG9zdFNoYWRvd1ZpcnRxdWV1ZSAqc3ZxKQo+ID4gPj4+ICt7 Cj4gPiA+Pj4gKyAgICBzdHJ1Y3Qgdmhvc3RfdmRwYSAqdiA9IGRldi0+b3BhcXVlOwo+ID4gPj4+ ICsgICAgc3RydWN0IHZob3N0X3ZyaW5nX2FkZHIgc3ZxX2FkZHI7Cj4gPiA+Pj4gKyAgICBzaXpl X3QgZGV2aWNlX3NpemUgPSB2aG9zdF9zdnFfZGV2aWNlX2FyZWFfc2l6ZShzdnEpOwo+ID4gPj4+ ICsgICAgc2l6ZV90IGRyaXZlcl9zaXplID0gdmhvc3Rfc3ZxX2RyaXZlcl9hcmVhX3NpemUoc3Zx KTsKPiA+ID4+PiArICAgIGludCByOwo+ID4gPj4+ICsKPiA+ID4+PiArICAgIHZob3N0X3N2cV9n ZXRfdnJpbmdfYWRkcihzdnEsICZzdnFfYWRkcik7Cj4gPiA+Pj4gKwo+ID4gPj4+ICsgICAgciA9 IHZob3N0X3ZkcGFfZG1hX21hcCh2LCBzdnFfYWRkci5kZXNjX3VzZXJfYWRkciwgZHJpdmVyX3Np emUsCj4gPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAgICh2b2lkICopc3ZxX2FkZHIu ZGVzY191c2VyX2FkZHIsIHRydWUpOwo+ID4gPj4+ICsgICAgaWYgKHVubGlrZWx5KHIgIT0gMCkp IHsKPiA+ID4+PiArICAgICAgICByZXR1cm4gZmFsc2U7Cj4gPiA+Pj4gKyAgICB9Cj4gPiA+Pj4g Kwo+ID4gPj4+ICsgICAgciA9IHZob3N0X3ZkcGFfZG1hX21hcCh2LCBzdnFfYWRkci51c2VkX3Vz ZXJfYWRkciwgZGV2aWNlX3NpemUsCj4gPiA+Pj4gKyAgICAgICAgICAgICAgICAgICAgICAgICAg ICh2b2lkICopc3ZxX2FkZHIudXNlZF91c2VyX2FkZHIsIGZhbHNlKTsKPiA+ID4+Cj4gPiA+PiBE byB3ZSBuZWVkIHVubWFwIHRoZSBkcml2ZXIgYXJlYSBpZiB3ZSBmYWlsIGhlcmU/Cj4gPiA+Pgo+ ID4gPiBZZXMsIHRoaXMgdXNlZCB0byB0cnVzdCBpbiB1bm1hcCB0aGVtIGF0IHRoZSBkaXNhYmxp bmcgb2YgU1ZRLiBOb3cgSQo+ID4gPiB0aGluayB3ZSBuZWVkIHRvIHVubWFwIGFzIHlvdSBzYXku Cj4gPiA+Cj4gPiA+IFRoYW5rcyEKPiA+ID4KPiA+ID4gWzFdIGh0dHBzOi8vbGlzdHMubGludXhm b3VuZGF0aW9uLm9yZy9waXBlcm1haWwvdmlydHVhbGl6YXRpb24vMjAyMS1NYXJjaC8wNTMzMjIu aHRtbAo+ID4gPgo+ID4gPj4gVGhhbmtzCj4gPiA+Pgo+ID4gPj4KPiA+ID4+PiArICAgIHJldHVy biByID09IDA7Cj4gPiA+Pj4gK30KPiA+ID4+PiArCj4gPiA+Pj4gK3N0YXRpYyBib29sIHZob3N0 X3ZkcGFfc3ZxX3NldHVwKHN0cnVjdCB2aG9zdF9kZXYgKmRldiwKPiA+ID4+PiArICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICBWaG9zdFNoYWRvd1ZpcnRxdWV1ZSAqc3ZxLAo+ID4gPj4+ ICsgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHVuc2lnbmVkIGlkeCkKPiA+ID4+PiAr ewo+ID4gPj4+ICsgICAgdWludDE2X3QgdnFfaW5kZXggPSBkZXYtPnZxX2luZGV4ICsgaWR4Owo+ ID4gPj4+ICsgICAgc3RydWN0IHZob3N0X3ZyaW5nX3N0YXRlIHMgPSB7Cj4gPiA+Pj4gKyAgICAg ICAgLmluZGV4ID0gdnFfaW5kZXgsCj4gPiA+Pj4gKyAgICB9Owo+ID4gPj4+ICsgICAgaW50IHI7 Cj4gPiA+Pj4gKyAgICBib29sIG9rOwo+ID4gPj4+ICsKPiA+ID4+PiArICAgIHIgPSB2aG9zdF92 ZHBhX3NldF9kZXZfdnJpbmdfYmFzZShkZXYsICZzKTsKPiA+ID4+PiArICAgIGlmICh1bmxpa2Vs eShyKSkgewo+ID4gPj4+ICsgICAgICAgIGVycm9yX3JlcG9ydCgiQ2FuJ3Qgc2V0IHZyaW5nIGJh c2UgKCVkKSIsIHIpOwo+ID4gPj4+ICsgICAgICAgIHJldHVybiBmYWxzZTsKPiA+ID4+PiArICAg IH0KPiA+ID4+PiArCj4gPiA+Pj4gKyAgICBzLm51bSA9IHZob3N0X3N2cV9nZXRfbnVtKHN2cSk7 Cj4gPiA+Pj4gKyAgICByID0gdmhvc3RfdmRwYV9zZXRfZGV2X3ZyaW5nX251bShkZXYsICZzKTsK PiA+ID4+PiArICAgIGlmICh1bmxpa2VseShyKSkgewo+ID4gPj4+ICsgICAgICAgIGVycm9yX3Jl cG9ydCgiQ2FuJ3Qgc2V0IHZyaW5nIG51bSAoJWQpIiwgcik7Cj4gPiA+Pj4gKyAgICAgICAgcmV0 dXJuIGZhbHNlOwo+ID4gPj4+ICsgICAgfQo+ID4gPj4+ICsKPiA+ID4+PiArICAgIG9rID0gdmhv c3RfdmRwYV9zdnFfbWFwX3JpbmdzKGRldiwgc3ZxKTsKPiA+ID4+PiArICAgIGlmICh1bmxpa2Vs eSghb2spKSB7Cj4gPiA+Pj4gKyAgICAgICAgcmV0dXJuIGZhbHNlOwo+ID4gPj4+ICsgICAgfQo+ ID4gPj4+ICsKPiA+ID4+PiArICAgIHIgPSB2aG9zdF92ZHBhX3N2cV9zZXRfZmRzKGRldiwgc3Zx LCBpZHgpOwo+ID4gPj4+ICAgICAgICByZXR1cm4gciA9PSAwOwo+ID4gPj4+ICAgIH0KPiA+ID4+ Pgo+ID4gPj4+IEBAIC03ODgsMTQgKzg4MSwyNCBAQCBzdGF0aWMgaW50IHZob3N0X3ZkcGFfZGV2 X3N0YXJ0KHN0cnVjdCB2aG9zdF9kZXYgKmRldiwgYm9vbCBzdGFydGVkKQo+ID4gPj4+ICAgICAg ICBpZiAoc3RhcnRlZCkgewo+ID4gPj4+ICAgICAgICAgICAgdmhvc3RfdmRwYV9ob3N0X25vdGlm aWVyc19pbml0KGRldik7Cj4gPiA+Pj4gICAgICAgICAgICBmb3IgKHVuc2lnbmVkIGkgPSAwOyBp IDwgdi0+c2hhZG93X3Zxcy0+bGVuOyArK2kpIHsKPiA+ID4+PiArICAgICAgICAgICAgVmlydFF1 ZXVlICp2cSA9IHZpcnRpb19nZXRfcXVldWUoZGV2LT52ZGV2LCBkZXYtPnZxX2luZGV4ICsgaSk7 Cj4gPiA+Pj4gICAgICAgICAgICAgICAgVmhvc3RTaGFkb3dWaXJ0cXVldWUgKnN2cSA9IGdfcHRy X2FycmF5X2luZGV4KHYtPnNoYWRvd192cXMsIGkpOwo+ID4gPj4+ICAgICAgICAgICAgICAgIGJv b2wgb2sgPSB2aG9zdF92ZHBhX3N2cV9zZXR1cChkZXYsIHN2cSwgaSk7Cj4gPiA+Pj4gICAgICAg ICAgICAgICAgaWYgKHVubGlrZWx5KCFvaykpIHsKPiA+ID4+PiAgICAgICAgICAgICAgICAgICAg cmV0dXJuIC0xOwo+ID4gPj4+ICAgICAgICAgICAgICAgIH0KPiA+ID4+PiArICAgICAgICAgICAg dmhvc3Rfc3ZxX3N0YXJ0KHN2cSwgZGV2LT52ZGV2LCB2cSk7Cj4gPiA+Pj4gICAgICAgICAgICB9 Cj4gPiA+Pj4gICAgICAgICAgICB2aG9zdF92ZHBhX3NldF92cmluZ19yZWFkeShkZXYpOwo+ID4g Pj4+ICAgICAgICB9IGVsc2Ugewo+ID4gPj4+ICsgICAgICAgIGZvciAodW5zaWduZWQgaSA9IDA7 IGkgPCB2LT5zaGFkb3dfdnFzLT5sZW47ICsraSkgewo+ID4gPj4+ICsgICAgICAgICAgICBWaG9z dFNoYWRvd1ZpcnRxdWV1ZSAqc3ZxID0gZ19wdHJfYXJyYXlfaW5kZXgodi0+c2hhZG93X3ZxcywK PiA+ID4+PiArICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgIGkpOwo+ID4gPj4+ICsgICAgICAgICAgICBib29sIG9rID0gdmhvc3RfdmRwYV9z dnFfdW5tYXBfcmluZ3MoZGV2LCBzdnEpOwo+ID4gPj4+ICsgICAgICAgICAgICBpZiAodW5saWtl bHkoIW9rKSkgewo+ID4gPj4+ICsgICAgICAgICAgICAgICAgcmV0dXJuIC0xOwo+ID4gPj4+ICsg ICAgICAgICAgICB9Cj4gPiA+Pj4gKyAgICAgICAgfQo+ID4gPj4+ICAgICAgICAgICAgdmhvc3Rf dmRwYV9ob3N0X25vdGlmaWVyc191bmluaXQoZGV2LCBkZXYtPm52cXMpOwo+ID4gPj4+ICAgICAg ICB9Cj4gPiA+Pj4KPiA+Cj4KCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fClZpcnR1YWxpemF0aW9uIG1haWxpbmcgbGlzdApWaXJ0dWFsaXphdGlvbkBsaXN0 cy5saW51eC1mb3VuZGF0aW9uLm9yZwpodHRwczovL2xpc3RzLmxpbnV4Zm91bmRhdGlvbi5vcmcv bWFpbG1hbi9saXN0aW5mby92aXJ0dWFsaXphdGlvbg== From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5463AC433F5 for ; Wed, 23 Feb 2022 02:06:14 +0000 (UTC) Received: from localhost ([::1]:46086 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1nMh2j-0005Ll-1p for qemu-devel@archiver.kernel.org; Tue, 22 Feb 2022 21:06:13 -0500 Received: from eggs.gnu.org ([209.51.188.92]:43808) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMh0u-0004TR-VV for qemu-devel@nongnu.org; Tue, 22 Feb 2022 21:04:20 -0500 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]:20252) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1nMh0m-0001jb-11 for qemu-devel@nongnu.org; Tue, 22 Feb 2022 21:04:18 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1645581850; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qKehpGX8N3Zv2mECHng3CbLXmSkX7YEgc+QoYwmB+x0=; b=JXMIfliwT5bRj4pZN4rJNs9Pc4zJlrj531TEXiOsAHvKKKR2zIQtFCdIPNPEVWOlrfe/Tx LjloDin6MMH5WZEngqDm5fMAxxM/vVrnTTPTOXeqzY9c7cmbUB0sGh621dAg1HfzwopEL/ bk/xExETd+VEtbs/YSR2u3ckgppYsBc= Received: from mail-lj1-f197.google.com (mail-lj1-f197.google.com [209.85.208.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-199-ZT8NIPuLPIq4m3iil95hBA-1; Tue, 22 Feb 2022 21:04:06 -0500 X-MC-Unique: ZT8NIPuLPIq4m3iil95hBA-1 Received: by mail-lj1-f197.google.com with SMTP id 20-20020a2e0914000000b0024635d136ddso4800882ljj.22 for ; Tue, 22 Feb 2022 18:04:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc:content-transfer-encoding; bh=qKehpGX8N3Zv2mECHng3CbLXmSkX7YEgc+QoYwmB+x0=; b=idFmXeqW5IT80JAnrcqIMzIaydJUyBzOycESF/oR4/7RsNB4pq/65wR8f9oGVHgGGm ze//8uM4zh6kjpW2m68MHadeIO6Vh7PEVOk1XNSxdBBpq1OhsiDE2+SikoH9/LrFBSGs kLlcVdeaVCDSn2KnixY0bWXYeLrzu7jp1ngkKy6NUqmXbdqO2PlcEDh7SMTIaqlnvJco UIe0YU14/6dFDO7BqzowjLPyD5WAQr2GgftMtyQAdyTnR6VlrPk1okpYY6rkMXrkC78X F4jAJMok8kQ4S86G+pF+mNUaF9Se2DimEtnPCKhZsf7OIvu+8Lv161Igb/+r/PoXoxzU o81A== X-Gm-Message-State: AOAM531UvqaTmpBmmzZ+2PUdN4rRtqzYDRUBMz/nOonABRC+OnhwM/Bp ZinvU64qFlX+/eKHaw2fjp5bizMeM2eAejscbDAtz3Ht0/uJazXnzdLkveU8zM2EqtHXokgv3bb dtnHGCed+8lH6FplsPruMZNcemE7h4u8= X-Received: by 2002:a05:651c:982:b0:244:c35d:b1ef with SMTP id b2-20020a05651c098200b00244c35db1efmr19548032ljq.243.1645581842933; Tue, 22 Feb 2022 18:04:02 -0800 (PST) X-Google-Smtp-Source: ABdhPJxbc0Hi1KK6AAjiWX4JAIIKqQVmpzwKozIPTs/mQQS1xZEoI5AqJfUM9Tlf6lTc/TpxuE6Ym9mtKLfWE19dXXA= X-Received: by 2002:a05:651c:982:b0:244:c35d:b1ef with SMTP id b2-20020a05651c098200b00244c35db1efmr19547989ljq.243.1645581842379; Tue, 22 Feb 2022 18:04:02 -0800 (PST) MIME-Version: 1.0 References: <20220121202733.404989-1-eperezma@redhat.com> <20220121202733.404989-19-eperezma@redhat.com> <6c98f4e8-8695-ab83-ae37-2d6293a1fafa@redhat.com> <75e2fd97-1e34-2b1a-cca4-ceb1aa440479@redhat.com> In-Reply-To: From: Jason Wang Date: Wed, 23 Feb 2022 10:03:51 +0800 Message-ID: Subject: Re: [PATCH 18/31] vhost: Shadow virtqueue buffers forwarding To: Eugenio Perez Martin Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jasowang@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable Received-SPF: pass client-ip=170.10.129.124; envelope-from=jasowang@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -27 X-Spam_score: -2.8 X-Spam_bar: -- X-Spam_report: (-2.8 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_PASS=-0.001, T_SCC_BODY_TEXT_LINE=-0.01, T_SPF_HELO_TEMPERROR=0.01 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Laurent Vivier , Parav Pandit , Cindy Lu , "Michael S. Tsirkin" , Juan Quintela , Richard Henderson , qemu-level , Gautam Dawar , Markus Armbruster , Eduardo Habkost , Harpreet Singh Anand , Xiao W Wang , Peter Xu , Stefan Hajnoczi , Eli Cohen , Paolo Bonzini , Zhu Lingshan , virtualization , Eric Blake , Stefano Garzarella Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" On Wed, Feb 23, 2022 at 3:01 AM Eugenio Perez Martin wrote: > > On Tue, Feb 8, 2022 at 9:11 AM Jason Wang wrote: > > > > > > =E5=9C=A8 2022/2/2 =E4=B8=8A=E5=8D=881:08, Eugenio Perez Martin =E5=86= =99=E9=81=93: > > > On Sun, Jan 30, 2022 at 5:43 AM Jason Wang wrot= e: > > >> > > >> =E5=9C=A8 2022/1/22 =E4=B8=8A=E5=8D=884:27, Eugenio P=C3=A9rez =E5= =86=99=E9=81=93: > > >>> Initial version of shadow virtqueue that actually forward buffers. = There > > >>> is no iommu support at the moment, and that will be addressed in fu= ture > > >>> patches of this series. Since all vhost-vdpa devices use forced IOM= MU, > > >>> this means that SVQ is not usable at this point of the series on an= y > > >>> device. > > >>> > > >>> For simplicity it only supports modern devices, that expects vring > > >>> in little endian, with split ring and no event idx or indirect > > >>> descriptors. Support for them will not be added in this series. > > >>> > > >>> It reuses the VirtQueue code for the device part. The driver part i= s > > >>> based on Linux's virtio_ring driver, but with stripped functionalit= y > > >>> and optimizations so it's easier to review. > > >>> > > >>> However, forwarding buffers have some particular pieces: One of the= most > > >>> unexpected ones is that a guest's buffer can expand through more th= an > > >>> one descriptor in SVQ. While this is handled gracefully by qemu's > > >>> emulated virtio devices, it may cause unexpected SVQ queue full. Th= is > > >>> patch also solves it by checking for this condition at both guest's > > >>> kicks and device's calls. The code may be more elegant in the futur= e if > > >>> SVQ code runs in its own iocontext. > > >>> > > >>> Signed-off-by: Eugenio P=C3=A9rez > > >>> --- > > >>> hw/virtio/vhost-shadow-virtqueue.h | 2 + > > >>> hw/virtio/vhost-shadow-virtqueue.c | 365 +++++++++++++++++++++++= +++++- > > >>> hw/virtio/vhost-vdpa.c | 111 ++++++++- > > >>> 3 files changed, 462 insertions(+), 16 deletions(-) > > >>> > > >>> diff --git a/hw/virtio/vhost-shadow-virtqueue.h b/hw/virtio/vhost-s= hadow-virtqueue.h > > >>> index 39aef5ffdf..19c934af49 100644 > > >>> --- a/hw/virtio/vhost-shadow-virtqueue.h > > >>> +++ b/hw/virtio/vhost-shadow-virtqueue.h > > >>> @@ -33,6 +33,8 @@ uint16_t vhost_svq_get_num(const VhostShadowVirtq= ueue *svq); > > >>> size_t vhost_svq_driver_area_size(const VhostShadowVirtqueue *sv= q); > > >>> size_t vhost_svq_device_area_size(const VhostShadowVirtqueue *sv= q); > > >>> > > >>> +void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev= , > > >>> + VirtQueue *vq); > > >>> void vhost_svq_stop(VhostShadowVirtqueue *svq); > > >>> > > >>> VhostShadowVirtqueue *vhost_svq_new(uint16_t qsize); > > >>> diff --git a/hw/virtio/vhost-shadow-virtqueue.c b/hw/virtio/vhost-s= hadow-virtqueue.c > > >>> index 7c168075d7..a1a404f68f 100644 > > >>> --- a/hw/virtio/vhost-shadow-virtqueue.c > > >>> +++ b/hw/virtio/vhost-shadow-virtqueue.c > > >>> @@ -9,6 +9,8 @@ > > >>> > > >>> #include "qemu/osdep.h" > > >>> #include "hw/virtio/vhost-shadow-virtqueue.h" > > >>> +#include "hw/virtio/vhost.h" > > >>> +#include "hw/virtio/virtio-access.h" > > >>> #include "standard-headers/linux/vhost_types.h" > > >>> > > >>> #include "qemu/error-report.h" > > >>> @@ -36,6 +38,33 @@ typedef struct VhostShadowVirtqueue { > > >>> > > >>> /* Guest's call notifier, where SVQ calls guest. */ > > >>> EventNotifier svq_call; > > >>> + > > >>> + /* Virtio queue shadowing */ > > >>> + VirtQueue *vq; > > >>> + > > >>> + /* Virtio device */ > > >>> + VirtIODevice *vdev; > > >>> + > > >>> + /* Map for returning guest's descriptors */ > > >>> + VirtQueueElement **ring_id_maps; > > >>> + > > >>> + /* Next VirtQueue element that guest made available */ > > >>> + VirtQueueElement *next_guest_avail_elem; > > >>> + > > >>> + /* Next head to expose to device */ > > >>> + uint16_t avail_idx_shadow; > > >>> + > > >>> + /* Next free descriptor */ > > >>> + uint16_t free_head; > > >>> + > > >>> + /* Last seen used idx */ > > >>> + uint16_t shadow_used_idx; > > >>> + > > >>> + /* Next head to consume from device */ > > >>> + uint16_t last_used_idx; > > >>> + > > >>> + /* Cache for the exposed notification flag */ > > >>> + bool notification; > > >>> } VhostShadowVirtqueue; > > >>> > > >>> #define INVALID_SVQ_KICK_FD -1 > > >>> @@ -148,30 +177,294 @@ bool vhost_svq_ack_guest_features(uint64_t d= ev_features, > > >>> return true; > > >>> } > > >>> > > >>> -/* Forward guest notifications */ > > >>> -static void vhost_handle_guest_kick(EventNotifier *n) > > >>> +/** > > >>> + * Number of descriptors that SVQ can make available from the gues= t. > > >>> + * > > >>> + * @svq The svq > > >>> + */ > > >>> +static uint16_t vhost_svq_available_slots(const VhostShadowVirtque= ue *svq) > > >>> { > > >>> - VhostShadowVirtqueue *svq =3D container_of(n, VhostShadowVirtq= ueue, > > >>> - svq_kick); > > >>> + return svq->vring.num - (svq->avail_idx_shadow - svq->shadow_u= sed_idx); > > >>> +} > > >>> + > > >>> +static void vhost_svq_set_notification(VhostShadowVirtqueue *svq, = bool enable) > > >>> +{ > > >>> + uint16_t notification_flag; > > >>> > > >>> - if (unlikely(!event_notifier_test_and_clear(n))) { > > >>> + if (svq->notification =3D=3D enable) { > > >>> + return; > > >>> + } > > >>> + > > >>> + notification_flag =3D cpu_to_le16(VRING_AVAIL_F_NO_INTERRUPT); > > >>> + > > >>> + svq->notification =3D enable; > > >>> + if (enable) { > > >>> + svq->vring.avail->flags &=3D ~notification_flag; > > >>> + } else { > > >>> + svq->vring.avail->flags |=3D notification_flag; > > >>> + } > > >>> +} > > >>> + > > >>> +static void vhost_vring_write_descs(VhostShadowVirtqueue *svq, > > >>> + const struct iovec *iovec, > > >>> + size_t num, bool more_descs, b= ool write) > > >>> +{ > > >>> + uint16_t i =3D svq->free_head, last =3D svq->free_head; > > >>> + unsigned n; > > >>> + uint16_t flags =3D write ? cpu_to_le16(VRING_DESC_F_WRITE) : 0= ; > > >>> + vring_desc_t *descs =3D svq->vring.desc; > > >>> + > > >>> + if (num =3D=3D 0) { > > >>> + return; > > >>> + } > > >>> + > > >>> + for (n =3D 0; n < num; n++) { > > >>> + if (more_descs || (n + 1 < num)) { > > >>> + descs[i].flags =3D flags | cpu_to_le16(VRING_DESC_F_NE= XT); > > >>> + } else { > > >>> + descs[i].flags =3D flags; > > >>> + } > > >>> + descs[i].addr =3D cpu_to_le64((hwaddr)iovec[n].iov_base); > > >>> + descs[i].len =3D cpu_to_le32(iovec[n].iov_len); > > >>> + > > >>> + last =3D i; > > >>> + i =3D cpu_to_le16(descs[i].next); > > >>> + } > > >>> + > > >>> + svq->free_head =3D le16_to_cpu(descs[last].next); > > >>> +} > > >>> + > > >>> +static unsigned vhost_svq_add_split(VhostShadowVirtqueue *svq, > > >>> + VirtQueueElement *elem) > > >>> +{ > > >>> + int head; > > >>> + unsigned avail_idx; > > >>> + vring_avail_t *avail =3D svq->vring.avail; > > >>> + > > >>> + head =3D svq->free_head; > > >>> + > > >>> + /* We need some descriptors here */ > > >>> + assert(elem->out_num || elem->in_num); > > >> > > >> Looks like this could be triggered by guest, we need fail instead as= sert > > >> here. > > >> > > > My understanding was that virtqueue_pop already sanitized that case, > > > but I'm not able to find where now. I will recheck and, in case it's > > > not, I will move to a failure. > > > > > >>> + > > >>> + vhost_vring_write_descs(svq, elem->out_sg, elem->out_num, > > >>> + elem->in_num > 0, false); > > >>> + vhost_vring_write_descs(svq, elem->in_sg, elem->in_num, false,= true); > > >>> + > > >>> + /* > > >>> + * Put entry in available array (but don't update avail->idx u= ntil they > > >>> + * do sync). > > >>> + */ > > >>> + avail_idx =3D svq->avail_idx_shadow & (svq->vring.num - 1); > > >>> + avail->ring[avail_idx] =3D cpu_to_le16(head); > > >>> + svq->avail_idx_shadow++; > > >>> + > > >>> + /* Update avail index after the descriptor is wrote */ > > >>> + smp_wmb(); > > >>> + avail->idx =3D cpu_to_le16(svq->avail_idx_shadow); > > >>> + > > >>> + return head; > > >>> +} > > >>> + > > >>> +static void vhost_svq_add(VhostShadowVirtqueue *svq, VirtQueueElem= ent *elem) > > >>> +{ > > >>> + unsigned qemu_head =3D vhost_svq_add_split(svq, elem); > > >>> + > > >>> + svq->ring_id_maps[qemu_head] =3D elem; > > >>> +} > > >>> + > > >>> +static void vhost_svq_kick(VhostShadowVirtqueue *svq) > > >>> +{ > > >>> + /* We need to expose available array entries before checking u= sed flags */ > > >>> + smp_mb(); > > >>> + if (svq->vring.used->flags & VRING_USED_F_NO_NOTIFY) { > > >>> return; > > >>> } > > >>> > > >>> event_notifier_set(&svq->hdev_kick); > > >>> } > > >>> > > >>> -/* Forward vhost notifications */ > > >>> +/** > > >>> + * Forward available buffers. > > >>> + * > > >>> + * @svq Shadow VirtQueue > > >>> + * > > >>> + * Note that this function does not guarantee that all guest's ava= ilable > > >>> + * buffers are available to the device in SVQ avail ring. The gues= t may have > > >>> + * exposed a GPA / GIOVA congiuous buffer, but it may not be conti= guous in qemu > > >>> + * vaddr. > > >>> + * > > >>> + * If that happens, guest's kick notifications will be disabled un= til device > > >>> + * makes some buffers used. > > >>> + */ > > >>> +static void vhost_handle_guest_kick(VhostShadowVirtqueue *svq) > > >>> +{ > > >>> + /* Clear event notifier */ > > >>> + event_notifier_test_and_clear(&svq->svq_kick); > > >>> + > > >>> + /* Make available as many buffers as possible */ > > >>> + do { > > >>> + if (virtio_queue_get_notification(svq->vq)) { > > >>> + virtio_queue_set_notification(svq->vq, false); > > >> > > >> This looks like an optimization the should belong to > > >> virtio_queue_set_notification() itself. > > >> > > > Sure we can move. > > > > > >>> + } > > >>> + > > >>> + while (true) { > > >>> + VirtQueueElement *elem; > > >>> + > > >>> + if (svq->next_guest_avail_elem) { > > >>> + elem =3D g_steal_pointer(&svq->next_guest_avail_el= em); > > >>> + } else { > > >>> + elem =3D virtqueue_pop(svq->vq, sizeof(*elem)); > > >>> + } > > >>> + > > >>> + if (!elem) { > > >>> + break; > > >>> + } > > >>> + > > >>> + if (elem->out_num + elem->in_num > > > >>> + vhost_svq_available_slots(svq)) { > > >>> + /* > > >>> + * This condition is possible since a contiguous b= uffer in GPA > > >>> + * does not imply a contiguous buffer in qemu's VA > > >>> + * scatter-gather segments. If that happen, the bu= ffer exposed > > >>> + * to the device needs to be a chain of descriptor= s at this > > >>> + * moment. > > >>> + * > > >>> + * SVQ cannot hold more available buffers if we ar= e here: > > >>> + * queue the current guest descriptor and ignore f= urther kicks > > >>> + * until some elements are used. > > >>> + */ > > >>> + svq->next_guest_avail_elem =3D elem; > > >>> + return; > > >>> + } > > >>> + > > >>> + vhost_svq_add(svq, elem); > > >>> + vhost_svq_kick(svq); > > >>> + } > > >>> + > > >>> + virtio_queue_set_notification(svq->vq, true); > > >>> + } while (!virtio_queue_empty(svq->vq)); > > >>> +} > > >>> + > > >>> +/** > > >>> + * Handle guest's kick. > > >>> + * > > >>> + * @n guest kick event notifier, the one that guest set to notify = svq. > > >>> + */ > > >>> +static void vhost_handle_guest_kick_notifier(EventNotifier *n) > > >>> +{ > > >>> + VhostShadowVirtqueue *svq =3D container_of(n, VhostShadowVirtq= ueue, > > >>> + svq_kick); > > >>> + vhost_handle_guest_kick(svq); > > >>> +} > > >>> + > > >>> +static bool vhost_svq_more_used(VhostShadowVirtqueue *svq) > > >>> +{ > > >>> + if (svq->last_used_idx !=3D svq->shadow_used_idx) { > > >>> + return true; > > >>> + } > > >>> + > > >>> + svq->shadow_used_idx =3D cpu_to_le16(svq->vring.used->idx); > > >>> + > > >>> + return svq->last_used_idx !=3D svq->shadow_used_idx; > > >>> +} > > >>> + > > >>> +static VirtQueueElement *vhost_svq_get_buf(VhostShadowVirtqueue *s= vq) > > >>> +{ > > >>> + vring_desc_t *descs =3D svq->vring.desc; > > >>> + const vring_used_t *used =3D svq->vring.used; > > >>> + vring_used_elem_t used_elem; > > >>> + uint16_t last_used; > > >>> + > > >>> + if (!vhost_svq_more_used(svq)) { > > >>> + return NULL; > > >>> + } > > >>> + > > >>> + /* Only get used array entries after they have been exposed by= dev */ > > >>> + smp_rmb(); > > >>> + last_used =3D svq->last_used_idx & (svq->vring.num - 1); > > >>> + used_elem.id =3D le32_to_cpu(used->ring[last_used].id); > > >>> + used_elem.len =3D le32_to_cpu(used->ring[last_used].len); > > >>> + > > >>> + svq->last_used_idx++; > > >>> + if (unlikely(used_elem.id >=3D svq->vring.num)) { > > >>> + error_report("Device %s says index %u is used", svq->vdev-= >name, > > >>> + used_elem.id); > > >>> + return NULL; > > >>> + } > > >>> + > > >>> + if (unlikely(!svq->ring_id_maps[used_elem.id])) { > > >>> + error_report( > > >>> + "Device %s says index %u is used, but it was not avail= able", > > >>> + svq->vdev->name, used_elem.id); > > >>> + return NULL; > > >>> + } > > >>> + > > >>> + descs[used_elem.id].next =3D svq->free_head; > > >>> + svq->free_head =3D used_elem.id; > > >>> + > > >>> + svq->ring_id_maps[used_elem.id]->len =3D used_elem.len; > > >>> + return g_steal_pointer(&svq->ring_id_maps[used_elem.id]); > > >>> +} > > >>> + > > >>> +static void vhost_svq_flush(VhostShadowVirtqueue *svq, > > >>> + bool check_for_avail_queue) > > >>> +{ > > >>> + VirtQueue *vq =3D svq->vq; > > >>> + > > >>> + /* Make as many buffers as possible used. */ > > >>> + do { > > >>> + unsigned i =3D 0; > > >>> + > > >>> + vhost_svq_set_notification(svq, false); > > >>> + while (true) { > > >>> + g_autofree VirtQueueElement *elem =3D vhost_svq_get_bu= f(svq); > > >>> + if (!elem) { > > >>> + break; > > >>> + } > > >>> + > > >>> + if (unlikely(i >=3D svq->vring.num)) { > > >>> + virtio_error(svq->vdev, > > >>> + "More than %u used buffers obtained in a = %u size SVQ", > > >>> + i, svq->vring.num); > > >>> + virtqueue_fill(vq, elem, elem->len, i); > > >>> + virtqueue_flush(vq, i); > > >> > > >> Let's simply use virtqueue_push() here? > > >> > > > virtqueue_push support to fill and flush only one element, instead of > > > batch. I'm fine with either but I think the less updates to the used > > > idx, the better. > > > > > > Fine. > > > > > > > > > >>> + i =3D 0; > > >> > > >> Do we need to bail out here? > > >> > > > Yes I guess we can simply return. > > > > > >>> + } > > >>> + virtqueue_fill(vq, elem, elem->len, i++); > > >>> + } > > >>> + > > >>> + virtqueue_flush(vq, i); > > >>> + event_notifier_set(&svq->svq_call); > > >>> + > > >>> + if (check_for_avail_queue && svq->next_guest_avail_elem) { > > >>> + /* > > >>> + * Avail ring was full when vhost_svq_flush was called= , so it's a > > >>> + * good moment to make more descriptors available if p= ossible > > >>> + */ > > >>> + vhost_handle_guest_kick(svq); > > >> > > >> Is there better to have a similar check as vhost_handle_guest_kick()= did? > > >> > > >> if (elem->out_num + elem->in_num > > > >> vhost_svq_available_slots(svq)) { > > >> > > > It will be duplicated when we call vhost_handle_guest_kick, won't it? > > > > > > Right, I mis-read the code. > > > > > > > > > >>> + } > > >>> + > > >>> + vhost_svq_set_notification(svq, true); > > >> > > >> A mb() is needed here? Otherwise we may lost a call here (where > > >> vhost_svq_more_used() is run before vhost_svq_set_notification()). > > >> > > > I'm confused here then, I thought you said this is just a hint so > > > there was no need? [1]. I think the memory barrier is needed too. > > > > > > Yes, it's a hint but: > > > > 1) When we disable the notification, consider the notification disable > > is just a hint, device can still raise an interrupt, so the ordering is > > meaningless and a memory barrier is not necessary (the > > vhost_svq_set_notification(svq, false)) > > > > 2) When we enable the notification, though it's a hint, the device can > > choose to implement it by enabling the interrupt, in this case, the > > notification enable should be done before checking the used. Otherwise, > > the checking of more used might be done before enable the notification: > > > > 1) driver check more used > > 2) device add more used but no notification > > 3) driver enable the notification then we lost a notification here > > > > That was my understanding too. So the right way is to only add the > memory barrier in case 2), when setting the flag, right? Yes. > > > > > >>> + } while (vhost_svq_more_used(svq)); > > >>> +} > > >>> + > > >>> +/** > > >>> + * Forward used buffers. > > >>> + * > > >>> + * @n hdev call event notifier, the one that device set to notify = svq. > > >>> + * > > >>> + * Note that we are not making any buffers available in the loop, = there is no > > >>> + * way that it runs more than virtqueue size times. > > >>> + */ > > >>> static void vhost_svq_handle_call(EventNotifier *n) > > >>> { > > >>> VhostShadowVirtqueue *svq =3D container_of(n, VhostShadowVir= tqueue, > > >>> hdev_call); > > >>> > > >>> - if (unlikely(!event_notifier_test_and_clear(n))) { > > >>> - return; > > >>> - } > > >>> + /* Clear event notifier */ > > >>> + event_notifier_test_and_clear(n); > > >> > > >> Any reason that we remove the above check? > > >> > > > This comes from the previous versions, where this made sure we missed > > > no used buffers in the process of switching to SVQ mode. > > > > > > I'm not sure I get here. Even if for the switching, it should be more > > safe the handle the flush unconditionally? > > > > Yes, I also think it's better to forward and kick/call unconditionally. > > Thanks! Ok. Thanks > > > Thanks > > > > > > > > > > If we enable SVQ from the beginning I think we can rely on getting al= l > > > the device's used buffer notifications, so let me think a little bit > > > and I can move to check the eventfd. > > > > > >>> - event_notifier_set(&svq->svq_call); > > >>> + vhost_svq_flush(svq, true); > > >>> } > > >>> > > >>> /** > > >>> @@ -258,13 +551,38 @@ void vhost_svq_set_svq_kick_fd(VhostShadowVir= tqueue *svq, int svq_kick_fd) > > >>> * need to explicitely check for them. > > >>> */ > > >>> event_notifier_init_fd(&svq->svq_kick, svq_kick_fd); > > >>> - event_notifier_set_handler(&svq->svq_kick, vhost_handle_guest_= kick); > > >>> + event_notifier_set_handler(&svq->svq_kick, > > >>> + vhost_handle_guest_kick_notifier); > > >>> > > >>> if (!check_old || event_notifier_test_and_clear(&tmp)) { > > >>> event_notifier_set(&svq->hdev_kick); > > >>> } > > >>> } > > >>> > > >>> +/** > > >>> + * Start shadow virtqueue operation. > > >>> + * > > >>> + * @svq Shadow Virtqueue > > >>> + * @vdev VirtIO device > > >>> + * @vq Virtqueue to shadow > > >>> + */ > > >>> +void vhost_svq_start(VhostShadowVirtqueue *svq, VirtIODevice *vdev= , > > >>> + VirtQueue *vq) > > >>> +{ > > >>> + svq->next_guest_avail_elem =3D NULL; > > >>> + svq->avail_idx_shadow =3D 0; > > >>> + svq->shadow_used_idx =3D 0; > > >>> + svq->last_used_idx =3D 0; > > >>> + svq->vdev =3D vdev; > > >>> + svq->vq =3D vq; > > >>> + > > >>> + memset(svq->vring.avail, 0, sizeof(*svq->vring.avail)); > > >>> + memset(svq->vring.used, 0, sizeof(*svq->vring.avail)); > > >>> + for (unsigned i =3D 0; i < svq->vring.num - 1; i++) { > > >>> + svq->vring.desc[i].next =3D cpu_to_le16(i + 1); > > >>> + } > > >>> +} > > >>> + > > >>> /** > > >>> * Stop shadow virtqueue operation. > > >>> * @svq Shadow Virtqueue > > >>> @@ -272,6 +590,28 @@ void vhost_svq_set_svq_kick_fd(VhostShadowVirt= queue *svq, int svq_kick_fd) > > >>> void vhost_svq_stop(VhostShadowVirtqueue *svq) > > >>> { > > >>> event_notifier_set_handler(&svq->svq_kick, NULL); > > >>> + g_autofree VirtQueueElement *next_avail_elem =3D NULL; > > >>> + > > >>> + if (!svq->vq) { > > >>> + return; > > >>> + } > > >>> + > > >>> + /* Send all pending used descriptors to guest */ > > >>> + vhost_svq_flush(svq, false); > > >>> + > > >>> + for (unsigned i =3D 0; i < svq->vring.num; ++i) { > > >>> + g_autofree VirtQueueElement *elem =3D NULL; > > >>> + elem =3D g_steal_pointer(&svq->ring_id_maps[i]); > > >>> + if (elem) { > > >>> + virtqueue_detach_element(svq->vq, elem, elem->len); > > >>> + } > > >>> + } > > >>> + > > >>> + next_avail_elem =3D g_steal_pointer(&svq->next_guest_avail_ele= m); > > >>> + if (next_avail_elem) { > > >>> + virtqueue_detach_element(svq->vq, next_avail_elem, > > >>> + next_avail_elem->len); > > >>> + } > > >>> } > > >>> > > >>> /** > > >>> @@ -316,7 +656,7 @@ VhostShadowVirtqueue *vhost_svq_new(uint16_t qs= ize) > > >>> memset(svq->vring.desc, 0, driver_size); > > >>> svq->vring.used =3D qemu_memalign(qemu_real_host_page_size, = device_size); > > >>> memset(svq->vring.used, 0, device_size); > > >>> - > > >>> + svq->ring_id_maps =3D g_new0(VirtQueueElement *, qsize); > > >>> event_notifier_set_handler(&svq->hdev_call, vhost_svq_handle= _call); > > >>> return g_steal_pointer(&svq); > > >>> > > >>> @@ -335,6 +675,7 @@ void vhost_svq_free(VhostShadowVirtqueue *vq) > > >>> event_notifier_cleanup(&vq->hdev_kick); > > >>> event_notifier_set_handler(&vq->hdev_call, NULL); > > >>> event_notifier_cleanup(&vq->hdev_call); > > >>> + g_free(vq->ring_id_maps); > > >>> qemu_vfree(vq->vring.desc); > > >>> qemu_vfree(vq->vring.used); > > >>> g_free(vq); > > >>> diff --git a/hw/virtio/vhost-vdpa.c b/hw/virtio/vhost-vdpa.c > > >>> index 53e14bafa0..0e5c00ed7e 100644 > > >>> --- a/hw/virtio/vhost-vdpa.c > > >>> +++ b/hw/virtio/vhost-vdpa.c > > >>> @@ -752,9 +752,9 @@ static int vhost_vdpa_set_vring_call(struct vho= st_dev *dev, > > >>> * Note that this function does not rewind kick file descriptor = if cannot set > > >>> * call one. > > >>> */ > > >>> -static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, > > >>> - VhostShadowVirtqueue *svq, > > >>> - unsigned idx) > > >>> +static int vhost_vdpa_svq_set_fds(struct vhost_dev *dev, > > >>> + VhostShadowVirtqueue *svq, > > >>> + unsigned idx) > > >>> { > > >>> struct vhost_vring_file file =3D { > > >>> .index =3D dev->vq_index + idx, > > >>> @@ -767,7 +767,7 @@ static bool vhost_vdpa_svq_setup(struct vhost_d= ev *dev, > > >>> r =3D vhost_vdpa_set_vring_dev_kick(dev, &file); > > >>> if (unlikely(r !=3D 0)) { > > >>> error_report("Can't set device kick fd (%d)", -r); > > >>> - return false; > > >>> + return r; > > >>> } > > >>> > > >>> event_notifier =3D vhost_svq_get_svq_call_notifier(svq); > > >>> @@ -777,6 +777,99 @@ static bool vhost_vdpa_svq_setup(struct vhost_= dev *dev, > > >>> error_report("Can't set device call fd (%d)", -r); > > >>> } > > >>> > > >>> + return r; > > >>> +} > > >>> + > > >>> +/** > > >>> + * Unmap SVQ area in the device > > >>> + */ > > >>> +static bool vhost_vdpa_svq_unmap_ring(struct vhost_vdpa *v, hwaddr= iova, > > >>> + hwaddr size) > > >>> +{ > > >>> + int r; > > >>> + > > >>> + size =3D ROUND_UP(size, qemu_real_host_page_size); > > >>> + r =3D vhost_vdpa_dma_unmap(v, iova, size); > > >>> + return r =3D=3D 0; > > >>> +} > > >>> + > > >>> +static bool vhost_vdpa_svq_unmap_rings(struct vhost_dev *dev, > > >>> + const VhostShadowVirtqueue = *svq) > > >>> +{ > > >>> + struct vhost_vdpa *v =3D dev->opaque; > > >>> + struct vhost_vring_addr svq_addr; > > >>> + size_t device_size =3D vhost_svq_device_area_size(svq); > > >>> + size_t driver_size =3D vhost_svq_driver_area_size(svq); > > >>> + bool ok; > > >>> + > > >>> + vhost_svq_get_vring_addr(svq, &svq_addr); > > >>> + > > >>> + ok =3D vhost_vdpa_svq_unmap_ring(v, svq_addr.desc_user_addr, d= river_size); > > >>> + if (unlikely(!ok)) { > > >>> + return false; > > >>> + } > > >>> + > > >>> + return vhost_vdpa_svq_unmap_ring(v, svq_addr.used_user_addr, d= evice_size); > > >>> +} > > >>> + > > >>> +/** > > >>> + * Map shadow virtqueue rings in device > > >>> + * > > >>> + * @dev The vhost device > > >>> + * @svq The shadow virtqueue > > >>> + */ > > >>> +static bool vhost_vdpa_svq_map_rings(struct vhost_dev *dev, > > >>> + const VhostShadowVirtqueue *s= vq) > > >>> +{ > > >>> + struct vhost_vdpa *v =3D dev->opaque; > > >>> + struct vhost_vring_addr svq_addr; > > >>> + size_t device_size =3D vhost_svq_device_area_size(svq); > > >>> + size_t driver_size =3D vhost_svq_driver_area_size(svq); > > >>> + int r; > > >>> + > > >>> + vhost_svq_get_vring_addr(svq, &svq_addr); > > >>> + > > >>> + r =3D vhost_vdpa_dma_map(v, svq_addr.desc_user_addr, driver_si= ze, > > >>> + (void *)svq_addr.desc_user_addr, true); > > >>> + if (unlikely(r !=3D 0)) { > > >>> + return false; > > >>> + } > > >>> + > > >>> + r =3D vhost_vdpa_dma_map(v, svq_addr.used_user_addr, device_si= ze, > > >>> + (void *)svq_addr.used_user_addr, false)= ; > > >> > > >> Do we need unmap the driver area if we fail here? > > >> > > > Yes, this used to trust in unmap them at the disabling of SVQ. Now I > > > think we need to unmap as you say. > > > > > > Thanks! > > > > > > [1] https://lists.linuxfoundation.org/pipermail/virtualization/2021-M= arch/053322.html > > > > > >> Thanks > > >> > > >> > > >>> + return r =3D=3D 0; > > >>> +} > > >>> + > > >>> +static bool vhost_vdpa_svq_setup(struct vhost_dev *dev, > > >>> + VhostShadowVirtqueue *svq, > > >>> + unsigned idx) > > >>> +{ > > >>> + uint16_t vq_index =3D dev->vq_index + idx; > > >>> + struct vhost_vring_state s =3D { > > >>> + .index =3D vq_index, > > >>> + }; > > >>> + int r; > > >>> + bool ok; > > >>> + > > >>> + r =3D vhost_vdpa_set_dev_vring_base(dev, &s); > > >>> + if (unlikely(r)) { > > >>> + error_report("Can't set vring base (%d)", r); > > >>> + return false; > > >>> + } > > >>> + > > >>> + s.num =3D vhost_svq_get_num(svq); > > >>> + r =3D vhost_vdpa_set_dev_vring_num(dev, &s); > > >>> + if (unlikely(r)) { > > >>> + error_report("Can't set vring num (%d)", r); > > >>> + return false; > > >>> + } > > >>> + > > >>> + ok =3D vhost_vdpa_svq_map_rings(dev, svq); > > >>> + if (unlikely(!ok)) { > > >>> + return false; > > >>> + } > > >>> + > > >>> + r =3D vhost_vdpa_svq_set_fds(dev, svq, idx); > > >>> return r =3D=3D 0; > > >>> } > > >>> > > >>> @@ -788,14 +881,24 @@ static int vhost_vdpa_dev_start(struct vhost_= dev *dev, bool started) > > >>> if (started) { > > >>> vhost_vdpa_host_notifiers_init(dev); > > >>> for (unsigned i =3D 0; i < v->shadow_vqs->len; ++i) { > > >>> + VirtQueue *vq =3D virtio_get_queue(dev->vdev, dev->vq_= index + i); > > >>> VhostShadowVirtqueue *svq =3D g_ptr_array_index(v->s= hadow_vqs, i); > > >>> bool ok =3D vhost_vdpa_svq_setup(dev, svq, i); > > >>> if (unlikely(!ok)) { > > >>> return -1; > > >>> } > > >>> + vhost_svq_start(svq, dev->vdev, vq); > > >>> } > > >>> vhost_vdpa_set_vring_ready(dev); > > >>> } else { > > >>> + for (unsigned i =3D 0; i < v->shadow_vqs->len; ++i) { > > >>> + VhostShadowVirtqueue *svq =3D g_ptr_array_index(v->sha= dow_vqs, > > >>> + i); > > >>> + bool ok =3D vhost_vdpa_svq_unmap_rings(dev, svq); > > >>> + if (unlikely(!ok)) { > > >>> + return -1; > > >>> + } > > >>> + } > > >>> vhost_vdpa_host_notifiers_uninit(dev, dev->nvqs); > > >>> } > > >>> > > >