From nobody Sun Nov 24 11:47:35 2024 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1722721873; cv=none; d=zohomail.com; s=zohoarc; b=PU754oe9KjOgncwAaXGpAIrkgAIlxBssitDp7bU+MUDawTP25EieiZH50e32UiXaMTE19weCyWj92EsDv4L6X1ujQuVDLfTiTd8jK83SYXG8ZvD/JCIyykNynGYflWqzyt7EfAmVdmTHFBSEK5fCFCWiqwlXSYBGCAshs9Dg5G8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1722721873; h=Content-Type:Date:Date:From:From:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Sender:Subject:Subject:To:To:Message-Id:Reply-To:Cc; bh=WCoXiAufGWS6jpEZvdBT5+z+kguZP6eWPxFSVnIROy4=; b=nuqqPIIjT24JMbZ1vZXg7Qdid3b1o2P8AdWI8enevDYK1WvJe8J5R9ziiLSBijRq0bps00ER5UeuSdI5Dx7CADbWC/jgGQkqmmse5B5U9rSAhQP/x/JjpYNgbqNKBei+3mmxRgviHx7rVOmFf047O38TufdOXveu/jAdJCoX8Q4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1722721873611542.6951432094103; Sat, 3 Aug 2024 14:51:13 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1saMdh-0006xy-Nn; Sat, 03 Aug 2024 17:50:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1saMST-00062Z-Nl for qemu-devel@nongnu.org; Sat, 03 Aug 2024 17:38:37 -0400 Received: from mail-ej1-x630.google.com ([2a00:1450:4864:20::630]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1saMSQ-00013b-NC for qemu-devel@nongnu.org; Sat, 03 Aug 2024 17:38:37 -0400 Received: by mail-ej1-x630.google.com with SMTP id a640c23a62f3a-a7d638a1f27so502818366b.2 for ; Sat, 03 Aug 2024 14:38:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1722721112; x=1723325912; darn=nongnu.org; h=to:subject:message-id:date:from:mime-version:from:to:cc:subject :date:message-id:reply-to; bh=WCoXiAufGWS6jpEZvdBT5+z+kguZP6eWPxFSVnIROy4=; b=VfAOKD4Tz/n4P5GaTxne+t5mMc+ZENJEJs/bkj/aexL/uxvA7DVHHFLHtapzh4UeMF ZsekB5ebzilIklNuUjoU9pFc4eUq9EiXjMtVrNlXCLuMB9HszHGiGXFcBP27QLBGrcjJ VyZyzaEwTOOHxHhzM/vgd3KWj9zriJOELVvs0RdSaqT8wolEdP5z63Yq1sdeBbzrngch rEv4YuqDNuusbf0ppw3o3Zwtv08ykoF6vCmEQG3kTsI8IYmg90H63RREb48rTV4uK+wh +twr9N0VBiTpyXdURcDCwJqvZwKZzh5Ugvtx5Q643+ICArlPSKl112Az4U2dEymtIkIc kgUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1722721112; x=1723325912; h=to:subject:message-id:date:from:mime-version:x-gm-message-state :from:to:cc:subject:date:message-id:reply-to; bh=WCoXiAufGWS6jpEZvdBT5+z+kguZP6eWPxFSVnIROy4=; b=N7ZX3dUt3FZNJwzbHdWF9fZSZfmbiT7ulg0+NPZoSmZf5gdP/Jgv0CiXsVuexZYmP5 coHrefXMrfNbFShW+SqEAE10XcdT/FCCYExSC2LrIJJccY8M4J8qWQbtcSu6EHV7OpqD 2FM0ejErqxFjH1rp9MEjcpKl9GlzmJVCl6LpPDMiXxT5lJHhiX2s/sIO0K3Xrlzl2xhS Tlmdb8wN9wqXE1m20TF1TE5biLmseVDgQQ0r43J170VTKjVPD0ZcpjWbVHiLDUUaQctx yxqV4izpAbwOrac4DukHArHP8yKjSfcbyVYiAhi9lsKRspQjsCKzEpWCYi0SokaemXuf X21w== X-Gm-Message-State: AOJu0YyK620UQwJ5pMYkpsWAzANUQVj2w/IASo4VjhxQdzu+As3DWekn 9zHFMSmaoyMs5H/be47XVTFKcJYFJe94yQYvLRZgERfiG6Ky6ikDKkzF/rmDjcsIMfc6keOIN7u DGdhIW47M2YxUBo/ZCHA1fieWWkgvcJZb X-Google-Smtp-Source: AGHT+IFbRInqYARBQ8ktd16C1nkG7fGZsBB5rBHKPI8pppYb5xnxB4wNV1kTcK++/7+8R9tMj9XIen95JMWTdSPKANY= X-Received: by 2002:a50:eac1:0:b0:5a2:97d7:c728 with SMTP id 4fb4d7f45d1cf-5b7f0ccf807mr6157524a12.0.1722721111306; Sat, 03 Aug 2024 14:38:31 -0700 (PDT) MIME-Version: 1.0 From: Zero Tang Date: Sun, 4 Aug 2024 05:38:17 +0800 Message-ID: Subject: hw/misc: Add a virtual PCILeech device To: qemu-devel@nongnu.org Content-Type: multipart/alternative; boundary="000000000000e2f8ff061ece439e" Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2a00:1450:4864:20::630; envelope-from=zero.tangptr@gmail.com; helo=mail-ej1-x630.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 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, FREEMAIL_FROM=0.001, HK_RANDOM_ENVFROM=0.001, HK_RANDOM_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-Mailman-Approved-At: Sat, 03 Aug 2024 17:50:09 -0400 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: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1722721875310116600 Content-Transfer-Encoding: quoted-printable --000000000000e2f8ff061ece439e MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 VGhpcyB2aXJ0dWFsIFBDSSBkZXZpY2UgaXMgaW50ZW5kZWQgZm9yIHNlY3VyaXR5IHJlc2VhcmNo ZXJzIHRvIGF0dGFjayB0aGUKZ3Vlc3QgdmlhIERNQS4KVGhpcyBpcyBteSBmaXJzdC10aW1lIGNv bnRyaWJ1dGlvbiBhbmQgSSBob3BlIEkgYW0gZG9pbmcgdGhpbmdzIGNvcnJlY3RseS4KClNpZ25l ZC1vZmYtYnk6IFplcm8gVGFuZyA8emVyby50YW5ncHRyQGdtYWlsLmNvbT4KLS0tCiBody9taXNj L0tjb25maWcgICAgIHwgICA1ICsKIGh3L21pc2MvbWVzb24uYnVpbGQgfCAgIDEgKwogaHcvbWlz Yy9wY2lsZWVjaC5jICB8IDI4MworKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysrCiAzIGZpbGVzIGNoYW5nZWQsIDI4OSBpbnNlcnRpb25zKCspCgpkaWZm IC0tZ2l0IGEvaHcvbWlzYy9LY29uZmlnIGIvaHcvbWlzYy9LY29uZmlnCmluZGV4IDFlMDg3ODVi ODMuLjBiZGJlMjZmMjYgMTAwNjQ0Ci0tLSBhL2h3L21pc2MvS2NvbmZpZworKysgYi9ody9taXNj L0tjb25maWcKQEAgLTMwLDYgKzMwLDExIEBAIGNvbmZpZyBFRFUKICAgICBkZWZhdWx0IHkgaWYg VEVTVF9ERVZJQ0VTCiAgICAgZGVwZW5kcyBvbiBQQ0kgJiYgTVNJX05PTkJST0tFTgoKK2NvbmZp ZyBQQ0lfTEVFQ0gKKyAgICBib29sCisgICAgZGVmYXVsdCB5CisgICAgZGVwZW5kcyBvbiBQQ0kK KwogY29uZmlnIFBDQTk1NTIKICAgICBib29sCiAgICAgZGVwZW5kcyBvbiBJMkMKZGlmZiAtLWdp dCBhL2h3L21pc2MvbWVzb24uYnVpbGQgYi9ody9taXNjL21lc29uLmJ1aWxkCmluZGV4IDJjYTg3 MTdiZTIuLjcxNzhlYWZhNzUgMTAwNjQ0Ci0tLSBhL2h3L21pc2MvbWVzb24uYnVpbGQKKysrIGIv aHcvbWlzYy9tZXNvbi5idWlsZApAQCAtMSw1ICsxLDYgQEAKIHN5c3RlbV9zcy5hZGQod2hlbjog J0NPTkZJR19BUFBMRVNNQycsIGlmX3RydWU6IGZpbGVzKCdhcHBsZXNtYy5jJykpCiBzeXN0ZW1f c3MuYWRkKHdoZW46ICdDT05GSUdfRURVJywgaWZfdHJ1ZTogZmlsZXMoJ2VkdS5jJykpCitzeXN0 ZW1fc3MuYWRkKHdoZW46ICdDT05GSUdfUENJX0xFRUNIJywgaWZfdHJ1ZTogZmlsZXMoJ3BjaWxl ZWNoLmMnKSkKIHN5c3RlbV9zcy5hZGQod2hlbjogJ0NPTkZJR19GV19DRkdfRE1BJywgaWZfdHJ1 ZTogZmlsZXMoJ3ZtY29yZWluZm8uYycpKQogc3lzdGVtX3NzLmFkZCh3aGVuOiAnQ09ORklHX0lT QV9ERUJVRycsIGlmX3RydWU6IGZpbGVzKCdkZWJ1Z2V4aXQuYycpKQogc3lzdGVtX3NzLmFkZCh3 aGVuOiAnQ09ORklHX0lTQV9URVNUREVWJywgaWZfdHJ1ZTogZmlsZXMoJ3BjLXRlc3RkZXYuYycp KQpkaWZmIC0tZ2l0IGEvaHcvbWlzYy9wY2lsZWVjaC5jIGIvaHcvbWlzYy9wY2lsZWVjaC5jCm5l dyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAwMDAuLmY2NzgyZDA1NWUKLS0tIC9kZXYv bnVsbAorKysgYi9ody9taXNjL3BjaWxlZWNoLmMKQEAgLTAsMCArMSwyODMgQEAKKy8qCisgKiBR RU1VIFZpcnR1YWwgUENJTGVlY2ggRGV2aWNlCisgKgorICogQ29weXJpZ2h0IChjKSAyMDI0IFpl cm8gVGFuZworICoKKyAqIFBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hh cmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhCisgKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUg YW5kIGFzc29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlCiJTb2Z0d2FyZSIpLAorICog dG8gZGVhbCBpbiB0aGUgU29mdHdhcmUgd2l0aG91dCByZXN0cmljdGlvbiwgaW5jbHVkaW5nIHdp dGhvdXQKbGltaXRhdGlvbgorICogdGhlIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVy Z2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsCisgKiBhbmQvb3Igc2VsbCBjb3Bp ZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKKyAq IFNvZnR3YXJlIGlzIGZ1cm5pc2hlZCB0byBkbyBzbywgc3ViamVjdCB0byB0aGUgZm9sbG93aW5n IGNvbmRpdGlvbnM6CisgKgorICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMg cGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQKaW4KKyAqIGFsbCBjb3BpZXMgb3Ig c3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLgorICoKKyAqIFRIRSBTT0ZUV0FS RSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFOWSBLSU5ELCBFWFBS RVNTCk9SCisgKiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJS QU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKKyAqIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQ VVJQT1NFIEFORCBOT05JTkZSSU5HRU1FTlQuIElOIE5PIEVWRU5UIFNIQUxMClRIRQorICogQVVU SE9SUyBPUiBDT1BZUklHSFQgSE9MREVSUyBCRSBMSUFCTEUgRk9SIEFOWSBDTEFJTSwgREFNQUdF UyBPUiBPVEhFUgorICogTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFD VCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcKKyAqIEZST00sIE9VVCBPRiBPUiBJTiBDT05O RUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRIRSBVU0UgT1IgT1RIRVIKKyAqIERFQUxJTkdT IElOIFRIRSBTT0ZUV0FSRS4KKyAqLworCisjaW5jbHVkZSAicWVtdS9vc2RlcC5oIgorI2luY2x1 ZGUgInFlbXUvdW5pdHMuaCIKKyNpbmNsdWRlICJody9wY2kvcGNpLmgiCisjaW5jbHVkZSAiaHcv aHcuaCIKKyNpbmNsdWRlICJody9wY2kvbXNpLmgiCisjaW5jbHVkZSAicWVtdS90aW1lci5oIgor I2luY2x1ZGUgImh3L3FkZXYtcHJvcGVydGllcy5oIgorI2luY2x1ZGUgImh3L3FkZXYtcHJvcGVy dGllcy1zeXN0ZW0uaCIKKyNpbmNsdWRlICJxb20vb2JqZWN0LmgiCisjaW5jbHVkZSAicWVtdS9t YWluLWxvb3AuaCIgLyogaW90aHJlYWQgbXV0ZXggKi8KKyNpbmNsdWRlICJxZW11L21vZHVsZS5o IgorI2luY2x1ZGUgInFhcGkvdmlzaXRvci5oIgorCisjZGVmaW5lIFRZUEVfUENJTEVFQ0hfREVW SUNFICJwY2lsZWVjaCIKKworc3RydWN0IExlZWNoUmVxdWVzdEhlYWRlciB7CisgICAgdWludDhf dCBlbmRpYW5uZXNzOyAvKiAwIC0gTGl0dGxlLCAxIC0gQmlnICovCisgICAgdWludDhfdCBjb21t YW5kOyAgICAvKiAwIC0gUmVhZCwgMSAtIFdyaXRlICovCisgICAgdWludDhfdCByZXNlcnZlZFs2 XTsKKyAgICAvKiBWYXJpYWJsZSBFbmRpYW5uZXNzICovCisgICAgdWludDY0X3QgYWRkcmVzczsK KyAgICB1aW50NjRfdCBsZW5ndGg7Cit9OworCitzdHJ1Y3QgTGVlY2hSZXNwb25zZUhlYWRlciB7 CisgICAgdWludDhfdCBlbmRpYW5uZXNzOyAvKiAwIC0gTGl0dGxlLCAxIC0gQmlnICovCisgICAg dWludDhfdCByZXNlcnZlZFszXTsKKyAgICBNZW1UeFJlc3VsdCByZXN1bHQ7CisgICAgdWludDY0 X3QgbGVuZ3RoOyAgICAvKiBJbmRpY2F0ZXMgbGVuZ3RoIG9mIGRhdGEgZm9sbG93ZWQgYnkgaGVh ZGVyICovCit9OworCitzdGF0aWNfYXNzZXJ0KHNpemVvZihzdHJ1Y3QgTGVlY2hSZXF1ZXN0SGVh ZGVyKSA9M0Q9M0QgMjQpOworc3RhdGljX2Fzc2VydChzaXplb2Yoc3RydWN0IExlZWNoUmVzcG9u c2VIZWFkZXIpID0zRD0zRCAxNik7CisKK3N0cnVjdCBQY2lMZWVjaFN0YXRlIHsKKyAgICAvKiBJ bnRlcm5hbCBTdGF0ZSAqLworICAgIFBDSURldmljZSBkZXZpY2U7CisgICAgUWVtdVRocmVhZCB0 aHJlYWQ7CisgICAgUWVtdU11dGV4IG11dGV4OworICAgIGJvb2wgZW5kaWFubmVzczsKKyAgICBi b29sIHN0b3BwaW5nOworICAgIC8qIENvbW11bmljYXRpb24gKi8KKyAgICBjaGFyICpob3N0Owor ICAgIHVpbnQxNl90IHBvcnQ7CisgICAgaW50IHNvY2tmZDsKK307CisKK3R5cGVkZWYgc3RydWN0 IExlZWNoUmVxdWVzdEhlYWRlciBMZWVjaFJlcXVlc3RIZWFkZXI7Cit0eXBlZGVmIHN0cnVjdCBQ Y2lMZWVjaFN0YXRlIFBjaUxlZWNoU3RhdGU7CisKK0RFQ0xBUkVfSU5TVEFOQ0VfQ0hFQ0tFUihQ Y2lMZWVjaFN0YXRlLCBQQ0lMRUVDSCwgVFlQRV9QQ0lMRUVDSF9ERVZJQ0UpCisKK3N0YXRpYyB2 b2lkIHBjaV9sZWVjaF9wcm9jZXNzX3dyaXRlX3JlcXVlc3QoUGNpTGVlY2hTdGF0ZSAqc3RhdGUs CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExlZWNoUmVxdWVz dEhlYWRlciAqcmVxdWVzdCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgaW50IGluY29taW5nKQoreworICAgIGNoYXIgYnVmZlsxMDI0XTsKKyAgICBmb3IgKHVp bnQ2NF90IGkgPTNEIDA7IGkgPCByZXF1ZXN0LT5sZW5ndGg7IGkgKz0zRCBzaXplb2YoYnVmZikp IHsKKyAgICAgICAgc3RydWN0IExlZWNoUmVzcG9uc2VIZWFkZXIgcmVzcG9uc2UgPTNEIHsgMCB9 OworICAgICAgICBjaGFyKiByZXNwb25zZV9idWZmZXIgPTNEIChjaGFyICopJnJlc3BvbnNlOwor ICAgICAgICBjb25zdCB1aW50NjRfdCB3cml0ZWxlbiA9M0QgKHJlcXVlc3QtPmxlbmd0aCAtIGkp IDw9M0Qgc2l6ZW9mKGJ1ZmY9CikgPworICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAocmVxdWVzdC0+bGVuZ3RoIC0gaSkgOgpzaXplb2YoYnVmZik7CisgICAgICAgIHNz aXplX3QgcmVjdmxlbiA9M0QgMCwgc2VuZGxlbiA9M0QgMDsKKyAgICAgICAgd2hpbGUgKHJlY3Zs ZW4gPCB3cml0ZWxlbikgeworICAgICAgICAgICAgcmVjdmxlbiArPTNEIHJlY3YoaW5jb21pbmcs ICZidWZmW3JlY3ZsZW5dLCB3cml0ZWxlbiAtIHJlY3ZsZW4sCjApOworICAgICAgICB9CisgICAg ICAgIHJlc3BvbnNlLmVuZGlhbm5lc3MgPTNEIHN0YXRlLT5lbmRpYW5uZXNzOworICAgICAgICBy ZXNwb25zZS5yZXN1bHQgPTNEIHBjaV9kbWFfd3JpdGUoJnN0YXRlLT5kZXZpY2UsIHJlcXVlc3Qt PmFkZHJlc3M9CiArCmksCisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICBidWZmLAp3cml0ZWxlbik7CisgICAgICAgIHByaW50ZigiUENJ TGVlY2g6IFdyaXRlIE1lbVR4UmVzdWx0OiAweCVYXG4iLCByZXNwb25zZS5yZXN1bHQpOworICAg ICAgICByZXNwb25zZS5sZW5ndGggPTNEIDA7CisgICAgICAgIHdoaWxlIChzZW5kbGVuIDwgc2l6 ZW9mKHN0cnVjdCBMZWVjaFJlc3BvbnNlSGVhZGVyKSkgeworICAgICAgICAgICAgc2VuZGxlbiAr PTNEIHNlbmQoaW5jb21pbmcsICZyZXNwb25zZV9idWZmZXJbc2VuZGxlbl0sCisgICAgICAgICAg ICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBMZWVjaFJlc3BvbnNlSGVhZGVyKSAtIHNl bmRsZW4sCjApOworICAgICAgICB9CisgICAgfQorfQorCitzdGF0aWMgdm9pZCBwY2lfbGVlY2hf cHJvY2Vzc19yZWFkX3JlcXVlc3QoUGNpTGVlY2hTdGF0ZSAqc3RhdGUsCisgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIExlZWNoUmVxdWVzdEhlYWRlciAqcmVxdWVz dCwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaW50IGluY29t aW5nKQoreworICAgIGNoYXIgYnVmZlsxMDI0XTsKKyAgICBmb3IgKHVpbnQ2NF90IGkgPTNEIDA7 IGkgPCByZXF1ZXN0LT5sZW5ndGg7IGkgKz0zRCBzaXplb2YoYnVmZikpIHsKKyAgICAgICAgc3Ry dWN0IExlZWNoUmVzcG9uc2VIZWFkZXIgcmVzcG9uc2UgPTNEIHsgMCB9OworICAgICAgICBjaGFy KiByZXNwb25zZV9idWZmZXIgPTNEIChjaGFyICopJnJlc3BvbnNlOworICAgICAgICBjb25zdCB1 aW50NjRfdCByZWFkbGVuID0zRCAocmVxdWVzdC0+bGVuZ3RoIC0gaSkgPD0zRCBzaXplb2YoYnVm Zik9CiA/CisgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAocmVxdWVzdC0+bGVu Z3RoIC0gaSkgOiBzaXplb2YoYnVmZik7CisgICAgICAgIHNzaXplX3Qgc2VuZGxlbiA9M0QgMDsK KyAgICAgICAgcmVzcG9uc2UuZW5kaWFubmVzcyA9M0Qgc3RhdGUtPmVuZGlhbm5lc3M7CisgICAg ICAgIHJlc3BvbnNlLnJlc3VsdCA9M0QgcGNpX2RtYV9yZWFkKCZzdGF0ZS0+ZGV2aWNlLCByZXF1 ZXN0LT5hZGRyZXNzICsKaSwKKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgIGJ1ZmYsIHJlYWRsZW4pOworICAgICAgICBwcmludGYoIlBD SUxlZWNoOiBSZWFkIE1lbVR4UmVzdWx0OiAweCVYXG4iLCByZXNwb25zZS5yZXN1bHQpOworICAg ICAgICByZXNwb25zZS5sZW5ndGggPTNEIChyZXF1ZXN0LT5lbmRpYW5uZXNzICE9M0Qgc3RhdGUt PmVuZGlhbm5lc3MpID8KKyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgYnN3YXA2NChyZWFkbGVuKSA6IHJlYWRsZW47CisgICAgICAgIHdoaWxlIChzZW5kbGVuIDwg c2l6ZW9mKHN0cnVjdCBMZWVjaFJlc3BvbnNlSGVhZGVyKSkgeworICAgICAgICAgICAgc2VuZGxl biArPTNEIHNlbmQoaW5jb21pbmcsICZyZXNwb25zZV9idWZmZXJbc2VuZGxlbl0sCisgICAgICAg ICAgICAgICAgICAgICAgICAgICAgc2l6ZW9mKHN0cnVjdCBMZWVjaFJlc3BvbnNlSGVhZGVyKSAt IHNlbmRsZW4sCjApOworICAgICAgICB9CisgICAgICAgIHNlbmRsZW4gPTNEIDA7CisgICAgICAg IHdoaWxlIChzZW5kbGVuIDwgcmVhZGxlbikgeworICAgICAgICAgICAgc2VuZGxlbiArPTNEIHNl bmQoaW5jb21pbmcsICZidWZmW3NlbmRsZW5dLCByZWFkbGVuIC0gc2VuZGxlbiwKMCk7CisgICAg ICAgIH0KKyAgICB9Cit9CisKK3N0YXRpYyB2b2lkICpwY2lfbGVlY2hfd29ya2VyX3RocmVhZCh2 b2lkICpvcGFxdWUpCit7CisgICAgUGNpTGVlY2hTdGF0ZSAqc3RhdGUgPTNEIFBDSUxFRUNIKG9w YXF1ZSk7CisgICAgd2hpbGUgKDEpIHsKKyAgICAgICAgTGVlY2hSZXF1ZXN0SGVhZGVyIHJlcXVl c3Q7CisgICAgICAgIGNoYXIgKnJlcXVlc3RfYnVmZmVyID0zRCAoY2hhciAqKSZyZXF1ZXN0Owor ICAgICAgICBzc2l6ZV90IHJlY2VpdmVkID0zRCAwOworICAgICAgICBpbnQgaW5jb21pbmc7Cisg ICAgICAgIHN0cnVjdCBzb2NrYWRkciBhZGRyZXNzOworICAgICAgICBzb2NrbGVuX3QgYWRkcmxl bjsKKyAgICAgICAgLyogQ2hlY2sgaWYgd2UgYXJlIHN0b3BwaW5nLiAqLworICAgICAgICBxZW11 X211dGV4X2xvY2soJnN0YXRlLT5tdXRleCk7CisgICAgICAgIGlmIChzdGF0ZS0+c3RvcHBpbmcp IHsKKyAgICAgICAgICAgIHFlbXVfbXV0ZXhfdW5sb2NrKCZzdGF0ZS0+bXV0ZXgpOworICAgICAg ICAgICAgYnJlYWs7CisgICAgICAgIH0KKyAgICAgICAgcWVtdV9tdXRleF91bmxvY2soJnN0YXRl LT5tdXRleCk7CisgICAgICAgIC8qIEFjY2VwdCBQQ0lMZWVjaCByZXF1ZXN0cy4gKi8KKyAgICAg ICAgaW5jb21pbmcgPTNEIGFjY2VwdChzdGF0ZS0+c29ja2ZkLCAmYWRkcmVzcywgJmFkZHJsZW4p OworICAgICAgICBpZiAoaW5jb21pbmcgPCAwKSB7CisgICAgICAgICAgICBwdXRzKCJXQVJOSU5H OiBGYWlsZWQgdG8gYWNjZXB0IHNvY2tldCBmb3IgUENJTGVlY2ghIFNraXBwaW5nICIKKyAgICAg ICAgICAgICAgICAgIlJlcXVlc3QuLi5cbiIpOworICAgICAgICAgICAgY29udGludWU7CisgICAg ICAgIH0KKyAgICAgICAgLyogR2V0IFBDSUxlZWNoIHJlcXVlc3RzLiAqLworICAgICAgICB3aGls ZSAocmVjZWl2ZWQgPCBzaXplb2YoTGVlY2hSZXF1ZXN0SGVhZGVyKSkgeworICAgICAgICAgICAg cmVjZWl2ZWQgKz0zRCByZWN2KGluY29taW5nLCAmcmVxdWVzdF9idWZmZXJbcmVjZWl2ZWRdLAor ICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNpemVvZihMZWVjaFJlcXVlc3RIZWFkZXIpIC0g cmVjZWl2ZWQsIDApOworICAgICAgICB9CisgICAgICAgIC8qIFN3YXAgZW5kaWFubmVzcyAqLwor ICAgICAgICBpZiAocmVxdWVzdC5lbmRpYW5uZXNzICE9M0Qgc3RhdGUtPmVuZGlhbm5lc3MpIHsK KyAgICAgICAgICAgIHJlcXVlc3QuYWRkcmVzcyA9M0QgYnN3YXA2NChyZXF1ZXN0LmFkZHJlc3Mp OworICAgICAgICAgICAgcmVxdWVzdC5sZW5ndGggPTNEIGJzd2FwNjQocmVxdWVzdC5sZW5ndGgp OworICAgICAgICB9CisgICAgICAgIC8qIFByb2Nlc3MgUENJTGVlY2ggcmVxdWVzdHMuICovCisg ICAgICAgIHFlbXVfbXV0ZXhfbG9jaygmc3RhdGUtPm11dGV4KTsKKyAgICAgICAgaWYgKHJlcXVl c3QuY29tbWFuZCkgeworICAgICAgICAgICAgcGNpX2xlZWNoX3Byb2Nlc3Nfd3JpdGVfcmVxdWVz dChzdGF0ZSwgJnJlcXVlc3QsIGluY29taW5nKTsKKyAgICAgICAgfSBlbHNlIHsKKyAgICAgICAg ICAgIHBjaV9sZWVjaF9wcm9jZXNzX3JlYWRfcmVxdWVzdChzdGF0ZSwgJnJlcXVlc3QsIGluY29t aW5nKTsKKyAgICAgICAgfQorICAgICAgICBxZW11X211dGV4X3VubG9jaygmc3RhdGUtPm11dGV4 KTsKKyAgICAgICAgY2xvc2UoaW5jb21pbmcpOworICAgIH0KKyAgICByZXR1cm4gTlVMTDsKK30K Kworc3RhdGljIHZvaWQgcGNpX2xlZWNoX3JlYWxpemUoUENJRGV2aWNlICpwZGV2LCBFcnJvciAq KmVycnApCit7CisgICAgUGNpTGVlY2hTdGF0ZSAqc3RhdGUgPTNEIFBDSUxFRUNIKHBkZXYpOwor ICAgIHN0cnVjdCBzb2NrYWRkcl9pbiBzb2NrX2FkZHI7CisgICAgY2hhciBob3N0X2lwWzE2XTsK KyAgICBzdHJ1Y3QgaG9zdGVudCAqaGUgPTNEIGdldGhvc3RieW5hbWUoc3RhdGUtPmhvc3QpOwor ICAgIGlmIChoZSA9M0Q9M0QgTlVMTCkgeworICAgICAgICBwdXRzKCJnZXRob3N0YnluYW1lIGZh aWxlZCEiKTsKKyAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOworICAgIH0KKyAgICAvKiBJbml0 aWFsaXplIHRoZSBzb2NrZXQgZm9yIFBDSUxlZWNoLiovCisgICAgc3RhdGUtPnNvY2tmZCA9M0Qg c29ja2V0KEFGX0lORVQsIFNPQ0tfU1RSRUFNLCAwKTsKKyAgICBpZiAoc3RhdGUtPnNvY2tmZCA8 IDApIHsKKyAgICAgICAgcHV0cygiRmFpbGVkIHRvIGluaXRpYWxpemUgc29ja2V0IGZvciBQQ0lM ZWVjaCEiKTsKKyAgICAgICAgZXhpdChFWElUX0ZBSUxVUkUpOworICAgIH0KKyAgICBzb2NrX2Fk ZHIuc2luX2ZhbWlseSA9M0QgQUZfSU5FVDsKKyAgICBzb2NrX2FkZHIuc2luX2FkZHIgPTNEICoo c3RydWN0IGluX2FkZHIgKiloZS0+aF9hZGRyOworICAgIHNvY2tfYWRkci5zaW5fcG9ydCA9M0Qg aHRvbnMoc3RhdGUtPnBvcnQpOworICAgIGluZXRfbnRvcChBRl9JTkVULCAmc29ja19hZGRyLnNp bl9hZGRyLCBob3N0X2lwLCBzaXplb2YoaG9zdF9pcCkpOworICAgIGlmIChiaW5kKHN0YXRlLT5z b2NrZmQsIChzdHJ1Y3Qgc29ja2FkZHIgKikmc29ja19hZGRyLApzaXplb2Yoc29ja19hZGRyKSkK KyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgPCAwKSB7CisgICAgICAgIHB1dHMoIkZhaWxlZCB0byBiaW5kIHNvY2tldCBm b3IgUENJTGVlY2ghIik7CisgICAgICAgIGNsb3NlKHN0YXRlLT5zb2NrZmQpOworICAgICAgICBl eGl0KEVYSVRfRkFJTFVSRSk7CisgICAgfQorICAgIGlmIChsaXN0ZW4oc3RhdGUtPnNvY2tmZCwg MTApIDwgMCkgeworICAgICAgICBwdXRzKCJGYWlsZWQgdG8gbGlzdGVuIHRvIHNvY2tldCBmb3Ig UENJTGVlY2ghIik7CisgICAgICAgIGNsb3NlKHN0YXRlLT5zb2NrZmQpOworICAgICAgICBleGl0 KEVYSVRfRkFJTFVSRSk7CisgICAgfQorICAgIHByaW50ZigiSU5GTzogUENJTGVlY2ggaXMgbGlz dGVuaW5nIG9uICVzOiV1Li4uXG4iLCBob3N0X2lwLApzdGF0ZS0+cG9ydCk7CisgICAgLyogSW5p dGlhbGl6ZSB0aGUgdGhyZWFkIGZvciBQQ0lMZWVjaC4gKi8KKyAgICBxZW11X211dGV4X2luaXQo JnN0YXRlLT5tdXRleCk7CisgICAgcWVtdV90aHJlYWRfY3JlYXRlKCZzdGF0ZS0+dGhyZWFkLCAi cGNpbGVlY2giLCBwY2lfbGVlY2hfd29ya2VyX3RocmVhZCwKKyAgICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgc3RhdGUsIFFFTVVfVEhSRUFEX0pPSU5BQkxFKTsKK30K Kworc3RhdGljIHZvaWQgcGNpX2xlZWNoX2ZpbmFsaXplKFBDSURldmljZSAqcGRldikKK3sKKyAg ICBQY2lMZWVjaFN0YXRlICpzdGF0ZSA9M0QgUENJTEVFQ0gocGRldik7CisgICAgcHV0cygiU3Rv cHBpbmcgUENJTGVlY2ggV29ya2VyLi4uIik7CisgICAgcWVtdV9tdXRleF9sb2NrKCZzdGF0ZS0+ bXV0ZXgpOworICAgIHN0YXRlLT5zdG9wcGluZyA9M0QgdHJ1ZTsKKyAgICBxZW11X211dGV4X3Vu bG9jaygmc3RhdGUtPm11dGV4KTsKKyAgICBjbG9zZShzdGF0ZS0+c29ja2ZkKTsKKyAgICBxZW11 X3RocmVhZF9qb2luKCZzdGF0ZS0+dGhyZWFkKTsKKyAgICBxZW11X211dGV4X2Rlc3Ryb3koJnN0 YXRlLT5tdXRleCk7Cit9CisKK2NoYXIgcGNpX2xlZWNoX2RlZmF1bHRfaG9zdFtdID0zRCAiMC4w LjAuMCI7CisKK3N0YXRpYyB2b2lkIHBjaV9sZWVjaF9pbnN0YW5jZV9pbml0KE9iamVjdCAqb2Jq KQoreworICAgIGludCB4ID0zRCAxOworICAgIGNoYXIqIHkgPTNEIChjaGFyICopJng7CisgICAg UGNpTGVlY2hTdGF0ZSAqc3RhdGUgPTNEIFBDSUxFRUNIKG9iaik7CisgICAgLyogUUVNVSdzIFN0 cmluZy1Qcm9wZXJ0eSBjYW4ndCBzcGVjaWZ5IGRlZmF1bHQgdmFsdWUuICovCisgICAgLyogU28g d2UgaGF2ZSB0byBzZXQgdGhlIGRlZmF1bHQgb24gb3VyIG93bi4gKi8KKyAgICBpZiAoc3RhdGUt Pmhvc3QgPTNEPTNEIE5VTEwpIHsKKyAgICAgICAgc3RhdGUtPmhvc3QgPTNEIHBjaV9sZWVjaF9k ZWZhdWx0X2hvc3Q7CisgICAgfQorICAgIC8qIFNhdmUgRW5kaWFubmVzcyAqLworICAgIHN0YXRl LT5lbmRpYW5uZXNzID0zRCAoKnkgPTNEPTNEIDApOworfQorCitzdGF0aWMgUHJvcGVydHkgbGVl Y2hfcHJvcGVydGllc1tdID0zRCB7CisgICAgREVGSU5FX1BST1BfVUlOVDE2KCJwb3J0IiwgUGNp TGVlY2hTdGF0ZSwgcG9ydCwgNjc4OSksCisgICAgREVGSU5FX1BST1BfU1RSSU5HKCJob3N0Iiwg UGNpTGVlY2hTdGF0ZSwgaG9zdCksCisgICAgREVGSU5FX1BST1BfRU5EX09GX0xJU1QoKSwKK307 CisKK3N0YXRpYyB2b2lkIHBjaV9sZWVjaF9jbGFzc19pbml0KE9iamVjdENsYXNzICpjbGFzcywg dm9pZCAqZGF0YSkKK3sKKyAgICBEZXZpY2VDbGFzcyAqZGMgPTNEIERFVklDRV9DTEFTUyhjbGFz cyk7CisgICAgUENJRGV2aWNlQ2xhc3MgKmsgPTNEIFBDSV9ERVZJQ0VfQ0xBU1MoY2xhc3MpOwor ICAgIGstPnJlYWxpemUgPTNEIHBjaV9sZWVjaF9yZWFsaXplOworICAgIGstPmV4aXQgPTNEIHBj aV9sZWVjaF9maW5hbGl6ZTsKKyAgICAvKiBDaGFuZ2UgdGhlIFZlbmRvci9EZXZpY2UgSUQgdG8g eW91ciBmYXZvci4gKi8KKyAgICAvKiBUaGVzZSBhcmUgdGhlIGRlZmF1bHQgdmFsdWVzIGZyb20g UENJTGVlY2gtRlBHQS4gKi8KKyAgICBrLT52ZW5kb3JfaWQgPTNEIFBDSV9WRU5ET1JfSURfWElM SU5YOworICAgIGstPmRldmljZV9pZCA9M0QgMHgwNjY2OworICAgIGstPnJldmlzaW9uID0zRCAw OworICAgIGstPmNsYXNzX2lkID0zRCBQQ0lfQ0xBU1NfTkVUV09SS19FVEhFUk5FVDsKKyAgICBk ZXZpY2VfY2xhc3Nfc2V0X3Byb3BzKGRjLCBsZWVjaF9wcm9wZXJ0aWVzKTsKKyAgICBzZXRfYml0 KERFVklDRV9DQVRFR09SWV9NSVNDLCBkYy0+Y2F0ZWdvcmllcyk7Cit9CisKK3N0YXRpYyB2b2lk IHBjaV9sZWVjaF9yZWdpc3Rlcl90eXBlcyh2b2lkKQoreworICAgIHN0YXRpYyBJbnRlcmZhY2VJ bmZvIGludGVyZmFjZXNbXSA9M0QgeworICAgICAgICB7SU5URVJGQUNFX0NPTlZFTlRJT05BTF9Q Q0lfREVWSUNFfSwKKyAgICAgICAge30sCisgICAgfTsKKyAgICBzdGF0aWMgY29uc3QgVHlwZUlu Zm8gbGVlY2hfaW5mbyA9M0QgeworICAgICAgICAubmFtZSA9M0QgVFlQRV9QQ0lMRUVDSF9ERVZJ Q0UsCisgICAgICAgIC5wYXJlbnQgPTNEIFRZUEVfUENJX0RFVklDRSwKKyAgICAgICAgLmluc3Rh bmNlX3NpemUgPTNEIHNpemVvZihQY2lMZWVjaFN0YXRlKSwKKyAgICAgICAgLmluc3RhbmNlX2lu aXQgPTNEIHBjaV9sZWVjaF9pbnN0YW5jZV9pbml0LAorICAgICAgICAuY2xhc3NfaW5pdCA9M0Qg cGNpX2xlZWNoX2NsYXNzX2luaXQsCisgICAgICAgIC5pbnRlcmZhY2VzID0zRCBpbnRlcmZhY2Vz LAorICAgIH07CisgICAgdHlwZV9yZWdpc3Rlcl9zdGF0aWMoJmxlZWNoX2luZm8pOworfQorCit0 eXBlX2luaXQocGNpX2xlZWNoX3JlZ2lzdGVyX3R5cGVzKQ== --000000000000e2f8ff061ece439e Content-Type: text/html; charset="UTF-8" Content-Transfer-Encoding: quoted-printable
This virtual PCI dev= ice is intended for security researchers to attack the guest via DMA.
This is my first-time contribu= tion and I hope I am doing things correctly.

= Signed-off-by: Zero Tang <zero= .tangptr@gmail.com>
---
=C2=A0hw/misc/Kconfig =C2=A0 =C2=A0= | =C2=A0 5 +
=C2=A0hw/misc/meson.build | =C2=A0 1 +
=C2=A0hw/misc/pc= ileech.c =C2=A0| 283 ++++++++++++++++++++++++++++++++++++++++++++++++++++=C2=A03 files changed, 289 insertions(+)

diff --git a/hw/misc/Kcon= fig b/hw/misc/Kconfig
index 1e08785b83..0bdbe26f26 100644
--- a/hw/mi= sc/Kconfig
+++ b/hw/misc/Kconfig
@@ -30,6 +30,11 @@ config EDU
=C2= =A0 =C2=A0 =C2=A0default y if TEST_DEVICES
=C2=A0 =C2=A0 =C2=A0depends o= n PCI && MSI_NONBROKEN
=C2=A0
+config PCI_LEECH
+ =C2=A0 = =C2=A0bool
+ =C2=A0 =C2=A0default y
+ =C2=A0 =C2=A0depends on PCI
= +
=C2=A0config PCA9552
=C2=A0 =C2=A0 =C2=A0bool
=C2=A0 =C2=A0 =C2= =A0depends on I2C
diff --git a/hw/misc/meson.build b/hw/misc/meson.build=
index 2ca8717be2..7178eafa75 100644
--- a/hw/misc/meson.build
+++= b/hw/misc/meson.build
@@ -1,5 +1,6 @@
=C2=A0system_ss.add(when: '= ;CONFIG_APPLESMC', if_true: files('applesmc.c'))
=C2=A0syste= m_ss.add(when: 'CONFIG_EDU', if_true: files('edu.c'))
+s= ystem_ss.add(when: 'CONFIG_PCI_LEECH', if_true: files('pcileech= .c'))
=C2=A0system_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true= : files('vmcoreinfo.c'))
=C2=A0system_ss.add(when: 'CONFIG_I= SA_DEBUG', if_true: files('debugexit.c'))
=C2=A0system_ss.ad= d(when: 'CONFIG_ISA_TESTDEV', if_true: files('pc-testdev.c'= ))
diff --git a/hw/misc/pcileech.c b/hw/misc/pcileech.c
new file mode= 100644
index 0000000000..f6782d055e
--- /dev/null
+++ b/hw/misc/p= cileech.c
@@ -0,0 +1,283 @@
+/*
+ * QEMU Virtual PCILeech Device+ *
+ * Copyright (c) 2024 Zero Tang
+ *
+ * Permission is hereb= y granted, free of charge, to any person obtaining a
+ * copy of this so= ftware and associated documentation files (the "Software"),
+ = * to deal in the Software without restriction, including without limitation=
+ * the rights to use, copy, modify, merge, publish, distribute, sublic= ense,
+ * and/or sell copies of the Software, and to permit persons to w= hom the
+ * Software is furnished to do so, subject to the following con= ditions:
+ *
+ * The above copyright notice and this permission notic= e shall be included in
+ * all copies or substantial portions of the Sof= tware.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WA= RRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO= THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE= AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOL= DERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN= AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR I= N CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE S= OFTWARE.
+ */
+
+#include "qemu/osdep.h"
+#include &q= uot;qemu/units.h"
+#include "hw/pci/pci.h"
+#include &= quot;hw/hw.h"
+#include "hw/pci/msi.h"
+#include "= ;qemu/timer.h"
+#include "hw/qdev-properties.h"
+#incl= ude "hw/qdev-properties-system.h"
+#include "qom/object.h= "
+#include "qemu/main-loop.h" /* iothread mutex */
+#= include "qemu/module.h"
+#include "qapi/visitor.h"+
+#define TYPE_PCILEECH_DEVICE "pcileech"
+
+struct L= eechRequestHeader {
+ =C2=A0 =C2=A0uint8_t endianness; /* 0 - Little, 1 = - Big */
+ =C2=A0 =C2=A0uint8_t command; =C2=A0 =C2=A0/* 0 - Read, 1 - W= rite */
+ =C2=A0 =C2=A0uint8_t reserved[6];
+=C2=A0 =C2=A0 /* Variabl= e Endianness */
+ =C2=A0 =C2=A0uint64_t address;
+ =C2=A0 =C2=A0uint6= 4_t length;
+};
+
+struct LeechResponseHeader {
+ =C2=A0 =C2=A0= uint8_t endianness; /* 0 - Little, 1 - Big */
+ =C2=A0 =C2=A0uint8_t res= erved[3];
+ =C2=A0 =C2=A0MemTxResult result;
+ =C2=A0 =C2=A0uint64_t = length; =C2=A0 =C2=A0/* Indicates length of data followed by header */
+= };
+
+static_assert(sizeof(struct LeechRequestHeader) =3D=3D 24);
= +static_assert(sizeof(struct LeechResponseHeader) =3D=3D 16);
+
+stru= ct PciLeechState {
+ =C2=A0 =C2=A0/* Internal State */
+ =C2=A0 =C2= =A0PCIDevice device;
+ =C2=A0 =C2=A0QemuThread thread;
+ =C2=A0 =C2= =A0QemuMutex mutex;
+ =C2=A0 =C2=A0bool endianness;
+ =C2=A0 =C2=A0bo= ol stopping;
+ =C2=A0 =C2=A0/* Communication */
+ =C2=A0 =C2=A0char *= host;
+ =C2=A0 =C2=A0uint16_t port;
+ =C2=A0 =C2=A0int sockfd;
+};=
+
+typedef struct LeechRequestHeader LeechRequestHeader;
+typedef= struct PciLeechState PciLeechState;
+
+DECLARE_INSTANCE_CHECKER(PciL= eechState, PCILEECH, TYPE_PCILEECH_DEVICE)
+
+static void pci_leech_p= rocess_write_request(PciLeechState *state,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0LeechRequestHeader *req= uest,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0int incoming)
+{
+ =C2=A0 =C2=A0char buff[1024];
= + =C2=A0 =C2=A0for (uint64_t i =3D 0; i < request->length; i +=3D siz= eof(buff)) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0struct LeechResponseHeader res= ponse =3D { 0 };
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0char* response_buffer =3D = (char *)&response;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0const uint64_t write= len =3D (request->length - i) <=3D sizeof(buff) ?
+ =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 (request->length - = i) : sizeof(buff);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0ssize_t recvlen =3D 0, s= endlen =3D 0;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0while (recvlen < writelen)= {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0recvlen +=3D recv(incoming= , &buff[recvlen], writelen - recvlen, 0);
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0}
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0response.endianness =3D state->endi= anness;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0response.result =3D pci_dma_write(&= amp;state->device, request->address + i,
+ =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0buff, writelen);
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0printf("PCILeech: Write MemTxResult: 0x%X\n", re= sponse.result);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0response.length =3D 0;
+= =C2=A0 =C2=A0 =C2=A0 =C2=A0while (sendlen < sizeof(struct LeechResponse= Header)) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sendlen +=3D send(= incoming, &response_buffer[sendlen],
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeof= (struct LeechResponseHeader) - sendlen, 0);
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0}
+ =C2=A0 =C2=A0}
+}
+
+static void pci_leech_process_read_= request(PciLeechState *state,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0LeechRequestHeader *request,
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0int incoming)
+{
+ =C2=A0 =C2=A0char buff[1024];
+ =C2=A0 = =C2=A0for (uint64_t i =3D 0; i < request->length; i +=3D sizeof(buff)= ) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0struct LeechResponseHeader response =3D= { 0 };
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0char* response_buffer =3D (char *)&= amp;response;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0const uint64_t readlen =3D (r= equest->length - i) <=3D sizeof(buff) ?
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0(request->length - i) : sizeof(buff);
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0ssize_t sendlen =3D 0;
+ =C2=A0 =C2=A0 =C2=A0= =C2=A0response.endianness =3D state->endianness;
+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0response.result =3D pci_dma_read(&state->device, request-&= gt;address + i,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0buff, readlen);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0printf("PCIL= eech: Read MemTxResult: 0x%X\n", response.result);
+ =C2=A0 =C2=A0 = =C2=A0 =C2=A0response.length =3D (request->endianness !=3D state->end= ianness) ?
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0bswap64(readlen) : readlen;
+ =C2=A0 =C2=A0 =C2=A0 = =C2=A0while (sendlen < sizeof(struct LeechResponseHeader)) {
+ =C2=A0= =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sendlen +=3D send(incoming, &respons= e_buffer[sendlen],
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeof(struct LeechResponse= Header) - sendlen, 0);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0= =C2=A0 =C2=A0sendlen =3D 0;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0while (sendlen= < readlen) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sendlen +=3D= send(incoming, &buff[sendlen], readlen - sendlen, 0);
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0}
+}
+
+static void *pci_leec= h_worker_thread(void *opaque)
+{
+ =C2=A0 =C2=A0PciLeechState *state = =3D PCILEECH(opaque);
+ =C2=A0 =C2=A0while (1) {
+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0LeechRequestHeader request;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0char = *request_buffer =3D (char *)&request;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0s= size_t received =3D 0;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0int incoming;
+ = =C2=A0 =C2=A0 =C2=A0 =C2=A0struct sockaddr address;
+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0socklen_t addrlen;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Check if we= are stopping. */
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_mutex_lock(&stat= e->mutex);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0if (state->stopping) {
= + =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_mutex_unlock(&state->= ;mutex);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0break;
+ =C2=A0 = =C2=A0 =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_mutex_unlock(&am= p;state->mutex);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Accept PCILeech requ= ests. */
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0incoming =3D accept(state->sock= fd, &address, &addrlen);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0if (incomi= ng < 0) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0puts("WARNI= NG: Failed to accept socket for PCILeech! Skipping "
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 "Request...\n");+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0continue;
+ =C2=A0 =C2=A0 = =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Get PCILeech requests. */=
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0while (received < sizeof(LeechRequestHe= ader)) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0received +=3D recv(i= ncoming, &request_buffer[received],
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0sizeof= (LeechRequestHeader) - received, 0);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+= =C2=A0 =C2=A0 =C2=A0 =C2=A0/* Swap endianness */
+ =C2=A0 =C2=A0 =C2=A0= =C2=A0if (request.endianness !=3D state->endianness) {
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0request.address =3D bswap64(request.address)= ;
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0request.length =3D bswap64(= request.length);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0 =C2= =A0 =C2=A0/* Process PCILeech requests. */
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0= qemu_mutex_lock(&state->mutex);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0if (= request.command) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pci_leech_= process_write_request(state, &request, incoming);
+ =C2=A0 =C2=A0 = =C2=A0 =C2=A0} else {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0pci_lee= ch_process_read_request(state, &request, incoming);
+ =C2=A0 =C2=A0 = =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0qemu_mutex_unlock(&state= ->mutex);
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0close(incoming);
+ =C2=A0 = =C2=A0}
+ =C2=A0 =C2=A0return NULL;
+}
+
+static void pci_leech= _realize(PCIDevice *pdev, Error **errp)
+{
+ =C2=A0 =C2=A0PciLeechSta= te *state =3D PCILEECH(pdev);
+ =C2=A0 =C2=A0struct sockaddr_in sock_add= r;
+ =C2=A0 =C2=A0char host_ip[16];
+ =C2=A0 =C2=A0struct hostent *he= =3D gethostbyname(state->host);
+ =C2=A0 =C2=A0if (he =3D=3D NULL) {=
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0puts("gethostbyname failed!");+ =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(EXIT_FAILURE);
+ =C2=A0 =C2=A0}
+= =C2=A0 =C2=A0/* Initialize the socket for PCILeech.*/
+ =C2=A0 =C2=A0st= ate->sockfd =3D socket(AF_INET, SOCK_STREAM, 0);
+ =C2=A0 =C2=A0if (s= tate->sockfd < 0) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0puts("Failed= to initialize socket for PCILeech!");
+ =C2=A0 =C2=A0 =C2=A0 =C2= =A0exit(EXIT_FAILURE);
+ =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0sock_addr.sin_= family =3D AF_INET;
+ =C2=A0 =C2=A0sock_addr.sin_addr =3D *(struct in_ad= dr *)he->h_addr;
+ =C2=A0 =C2=A0sock_addr.sin_port =3D htons(state-&g= t;port);
+ =C2=A0 =C2=A0inet_ntop(AF_INET, &sock_addr.sin_addr, host= _ip, sizeof(host_ip));
+ =C2=A0 =C2=A0if (bind(state->sockfd, (struct= sockaddr *)&sock_addr, sizeof(sock_addr))
+ =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0< 0= ) {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0puts("Failed to bind socket for PC= ILeech!");
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0close(state->sockfd);+ =C2=A0 =C2=A0 =C2=A0 =C2=A0exit(EXIT_FAILURE);
+ =C2=A0 =C2=A0}
+ = =C2=A0 =C2=A0if (listen(state->sockfd, 10) < 0) {
+ =C2=A0 =C2=A0 = =C2=A0 =C2=A0puts("Failed to listen to socket for PCILeech!");+ =C2=A0 =C2=A0 =C2=A0 =C2=A0close(state->sockfd);
+ =C2=A0 =C2=A0 = =C2=A0 =C2=A0exit(EXIT_FAILURE);
+ =C2=A0 =C2=A0}
+ =C2=A0 =C2=A0prin= tf("INFO: PCILeech is listening on %s:%u...\n", host_ip, state-&g= t;port);
+ =C2=A0 =C2=A0/* Initialize the thread for PCILeech. */
+ = =C2=A0 =C2=A0qemu_mutex_init(&state->mutex);
+ =C2=A0 =C2=A0qemu_= thread_create(&state->thread, "pcileech", pci_leech_worker= _thread,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2= =A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 =C2=A0 = =C2=A0 =C2=A0 =C2=A0state, QEMU_THREAD_JOINABLE);
+}
+
+static voi= d pci_leech_finalize(PCIDevice *pdev)
+{
+ =C2=A0 =C2=A0PciLeechState= *state =3D PCILEECH(pdev);
+ =C2=A0 =C2=A0puts("Stopping PCILeech = Worker...");
+ =C2=A0 =C2=A0qemu_mutex_lock(&state->mutex);<= br>+ =C2=A0 =C2=A0state->stopping =3D true;
+ =C2=A0 =C2=A0qemu_mutex= _unlock(&state->mutex);
+ =C2=A0 =C2=A0close(state->sockfd);+ =C2=A0 =C2=A0qemu_thread_join(&state->thread);
+ =C2=A0 =C2= =A0qemu_mutex_destroy(&state->mutex);
+}
+
+char pci_leech_= default_host[] =3D "0.0.0.0";
+
+static void pci_leech_inst= ance_init(Object *obj)
+{
+ =C2=A0 =C2=A0int x =3D 1;
+ =C2=A0 =C2= =A0char* y =3D (char *)&x;
+ =C2=A0 =C2=A0PciLeechState *state =3D P= CILEECH(obj);
+ =C2=A0 =C2=A0/* QEMU's String-Property can't spe= cify default value. */
+ =C2=A0 =C2=A0/* So we have to set the default o= n our own. */
+ =C2=A0 =C2=A0if (state->host =3D=3D NULL) {
+ =C2= =A0 =C2=A0 =C2=A0 =C2=A0state->host =3D pci_leech_default_host;
+ =C2= =A0 =C2=A0}
+ =C2=A0 =C2=A0/* Save Endianness */
+ =C2=A0 =C2=A0state= ->endianness =3D (*y =3D=3D 0);
+}
+
+static Property leech_pro= perties[] =3D {
+ =C2=A0 =C2=A0DEFINE_PROP_UINT16("port", PciL= eechState, port, 6789),
+ =C2=A0 =C2=A0DEFINE_PROP_STRING("host&quo= t;, PciLeechState, host),
+ =C2=A0 =C2=A0DEFINE_PROP_END_OF_LIST(),
+= };
+
+static void pci_leech_class_init(ObjectClass *class, void *data= )
+{
+ =C2=A0 =C2=A0DeviceClass *dc =3D DEVICE_CLASS(class);
+ =C2= =A0 =C2=A0PCIDeviceClass *k =3D PCI_DEVICE_CLASS(class);
+ =C2=A0 =C2=A0= k->realize =3D pci_leech_realize;
+ =C2=A0 =C2=A0k->exit =3D pci_l= eech_finalize;
+ =C2=A0 =C2=A0/* Change the Vendor/Device ID to your fav= or. */
+ =C2=A0 =C2=A0/* These are the default values from PCILeech-FPGA= . */
+ =C2=A0 =C2=A0k->vendor_id =3D PCI_VENDOR_ID_XILINX;
+ =C2= =A0 =C2=A0k->device_id =3D 0x0666;
+ =C2=A0 =C2=A0k->revision =3D = 0;
+ =C2=A0 =C2=A0k->class_id =3D PCI_CLASS_NETWORK_ETHERNET;
+ = =C2=A0 =C2=A0device_class_set_props(dc, leech_properties);
+ =C2=A0 =C2= =A0set_bit(DEVICE_CATEGORY_MISC, dc->categories);
+}
+
+static = void pci_leech_register_types(void)
+{
+ =C2=A0 =C2=A0static Interfac= eInfo interfaces[] =3D {
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0{INTERFACE_CONVENT= IONAL_PCI_DEVICE},
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0{},
+ =C2=A0 =C2=A0};=
+ =C2=A0 =C2=A0static const TypeInfo leech_info =3D {
+ =C2=A0 =C2= =A0 =C2=A0 =C2=A0.name =3D TYPE_PCILEECH_DEVICE,
+ =C2=A0 =C2=A0 =C2=A0 = =C2=A0.parent =3D TYPE_PCI_DEVICE,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0.instanc= e_size =3D sizeof(PciLeechState),
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0.instance= _init =3D pci_leech_instance_init,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0.class_i= nit =3D pci_leech_class_init,
+ =C2=A0 =C2=A0 =C2=A0 =C2=A0.interfaces = =3D interfaces,
+ =C2=A0 =C2=A0};
+ =C2=A0 =C2=A0type_register_static= (&leech_info);
+}
+
+type_init(pci_leech_register_types)
--000000000000e2f8ff061ece439e--