From nobody Thu May 16 23:18:59 2024 Delivered-To: importer@patchew.org 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; Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=partner.samsung.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1580815955938109.61285130475903; Tue, 4 Feb 2020 03:32:35 -0800 (PST) Received: from localhost ([::1]:56690 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywRW-0001Fl-Tu for importer@patchew.org; Tue, 04 Feb 2020 06:32:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53715) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywQD-0008Jy-Bh for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iywQB-00008E-CK for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:13 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:51714) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iywQA-0008Md-Of for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:10 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200204113104euoutp025f13835f2d8b8d71d4c51c934d222f5a~wL6dS2FVJ3023230232euoutp020 for ; Tue, 4 Feb 2020 11:31:04 +0000 (GMT) Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20200204113104eucas1p2e83ce943e6f3e457f4fb0ee7a66762e0~wL6dEbzpa0683206832eucas1p29; Tue, 4 Feb 2020 11:31:04 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id E3.3C.60679.8F5593E5; Tue, 4 Feb 2020 11:31:04 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200204113104eucas1p2587768b7daa479ef5c01b45e1da99e45~wL6cruR6b0683106831eucas1p2y; Tue, 4 Feb 2020 11:31:04 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200204113104eusmtrp1c96f6997c3b56ea854e36622acafff48~wL6crMZJv2134721347eusmtrp1G; Tue, 4 Feb 2020 11:31:04 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id B7.0A.07950.8F5593E5; Tue, 4 Feb 2020 11:31:04 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200204113103eusmtip28249f773b8678ea801ba48f029313b35~wL6cYB82n1358713587eusmtip2S; Tue, 4 Feb 2020 11:31:03 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200204113104euoutp025f13835f2d8b8d71d4c51c934d222f5a~wL6dS2FVJ3023230232euoutp020 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580815864; bh=IJ1emGgN6d30HijKvqti3w0yHl5azRM1D5/4t/jSL+I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=K5D8veBTMDTaK61I+eY5LGmEHV3A4stKtN36RJSU3dlDJzUUgS051BFmTfsNsFaIC VrZwxd8LPjEw3aEA3iXNarS74phg94KM158MhowkEFRftDCKt+RrE60yk1JrawQZ+1 jKvoex3A08M7g2ZiYu4Dy7N6Icjqeh/Ke80qdGaQ= X-AuditID: cbfec7f4-0e5ff7000001ed07-ce-5e3955f8494a From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC 1/9] memory: Add function for finding flat memory ranges Date: Tue, 4 Feb 2020 12:30:43 +0100 Message-Id: <1580815851-28887-2-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOIsWRmVeSWpSXmKPExsWy7djP87o/Qi3jDBY1qVvsufCYzWL/tn+s FnPOPGCxON67g8WBxePOtT1sHk+ubWbyOPhuD5PH+31X2QJYorhsUlJzMstSi/TtErgy5v5r ZS14o1mxeNcK1gbGiXJdjJwcEgImEuu/zWbrYuTiEBJYwSix9/xydgjnC6PEonmPoZzPjBL9 t1tYYVre3JrMBJFYzijxc8k2sARYS9sbdRCbTUBNYueRz4wgtoiApMTvrtPMIDazQIbE81nd YLawgJvEveWtYDUsAqoSu5evBIvzCgRINK5+xQixTE7i5rlOsDinQKDE+z2TwBZLCJxhk1jU cByqyEViw9EdULawxKvjW9ghbBmJ05N7WCDseomWOzugmjsYJfpWTmeDSFhLfNmwFKiIA+g6 TYn1u/Qhwo4Sr0/NZwUJSwjwSdx4KwhxP5/EpG3TmSHCvBIdbUIQ1XoS3U9uMsFsXdb4CGqr h8StGdegwbOEUWLVA+0JjPKzEHYtYGRcxSieWlqcm55abJSXWq5XnJhbXJqXrpecn7uJERj9 p/8d/7KDcdefpEOMAhyMSjy8J89axAmxJpYVV+YeYpTgYFYS4T2vbxknxJuSWFmVWpQfX1Sa k1p8iFGag0VJnNd40ctYIYH0xJLU7NTUgtQimCwTB6dUA2PKB4Fbqb/n7/pz12j37UZJ1Qna 10/6ZWZ/Z72iVPX4hs3Dlz+bZiadynEKnHtTcELZMU2T2Dttaez/N35wKn/7e0u0quNUxiXb HZ6VbFM8aD138aGK9gNbjCympjHcaz+Vs3Mpe4pejobqeSYV9jNcd8Q1XT505cROm3h/hfnT 77v2P41/d5FPiaU4I9FQi7moOBEA/sKXAPoCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrJLMWRmVeSWpSXmKPExsVy+t/xe7o/Qi3jDK695rHYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlzP3XylrwRrNi8a4VrA2ME+W6GDk5 JARMJN7cmswEYgsJLGWU2D01DiIuI/Hj9Bo2CFtY4s+1LiCbC6jmE6PEqRWbwRrYBNQkdh75 zAhiiwhISvzuOs0MYjMLZEnsnH0frEZYwE3i3vJWsBoWAVWJ3ctXgtXwCgRINK5+xQixQE7i 5rlOsDinQKDE+z2ToA4KkLiwaxb7BEa+BYwMqxhFUkuLc9Nzi430ihNzi0vz0vWS83M3MQKD cduxn1t2MHa9Cz7EKMDBqMTDq+FoESfEmlhWXJl7iFGCg1lJhPe8vmWcEG9KYmVValF+fFFp TmrxIUZToKMmMkuJJucDIyWvJN7Q1NDcwtLQ3Njc2MxCSZy3Q+BgjJBAemJJanZqakFqEUwf EwenVAOjb+s+w4IpG/89+ZGstupLaR9jr/mRH0kzd8V++t5Qd3+zhW0Pk2G44d+1lVOvnz04 uTo4KWGdJ8MWAb7k8so7Th8O7trXFHvzjVdukQ6/7Usbz3V3JRQ6eav52OoZvmj+fVt7ZE5z ++P5jvc9Nmlv6TomwTOr+0/ikx9f/J7dZDC+b3zQ/OIqJZbijERDLeai4kQAaF15KVwCAAA= X-CMS-MailID: 20200204113104eucas1p2587768b7daa479ef5c01b45e1da99e45 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200204113104eucas1p2587768b7daa479ef5c01b45e1da99e45 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200204113104eucas1p2587768b7daa479ef5c01b45e1da99e45 References: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 210.118.77.12 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Igor Kotrasinski , pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Igor Kotrasinski Given an address this lets us find the largest contiguous memory range at that address. Signed-off-by: Igor Kotrasinski --- include/exec/memory.h | 19 +++++++++++++ memory.c | 79 +++++++++++++++++++++++++++++++++++++++++++++++= +++- 2 files changed, 97 insertions(+), 1 deletion(-) diff --git a/include/exec/memory.h b/include/exec/memory.h index e85b7de..6092528 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -1915,6 +1915,25 @@ MemoryRegionSection memory_region_find(MemoryRegion = *mr, hwaddr addr, uint64_t size); =20 /** + * memory_region_find_flat_range: translate an address/size relative to + * a MemoryRegion into a FlatRange containing it. + * + * Returns a #MemoryRegionSection that describes this FlatRange. + * It will have the following characteristics: + * .@size =3D 0 iff no containing FlatRange was found + * .@mr is non-%NULL iff a containing FlatRange was found + * + * Remember that in the return value the @offset_within_region is + * relative to the returned region (in the .@mr field), not to the + * @mr argument. + * + * @mr: a MemoryRegion within which @addr is a relative address + * @addr: start of the area within @as to be searched + * @size: size of the area to be searched + */ +MemoryRegionSection memory_region_find_flat_range(MemoryRegion *mr, + hwaddr addr, uint64_t si= ze); +/** * memory_global_dirty_log_sync: synchronize the dirty log for all memory * * Synchronizes the dirty page log for all address spaces. diff --git a/memory.c b/memory.c index aeaa8dc..e9f37e7 100644 --- a/memory.c +++ b/memory.c @@ -2523,6 +2523,25 @@ static FlatRange *flatview_lookup(FlatView *view, Ad= drRange addr) sizeof(FlatRange), cmp_flatrange_addr); } =20 +static int cmp_flatrange_addr_containing(const void *addr_, const void *fr= _) +{ + const AddrRange *addr =3D addr_; + const FlatRange *fr =3D fr_; + + if (int128_le(addr->start, fr->addr.start)) { + return -1; + } else if (int128_ge(addrrange_end(*addr), addrrange_end(fr->addr))) { + return 1; + } + return 0; +} + +static FlatRange *flatview_lookup_containing(FlatView *view, AddrRange add= r) +{ + return bsearch(&addr, view->ranges, view->nr, + sizeof(FlatRange), cmp_flatrange_addr_containing); +} + bool memory_region_is_mapped(MemoryRegion *mr) { return mr->container ? true : false; @@ -2532,7 +2551,8 @@ bool memory_region_is_mapped(MemoryRegion *mr) * returned region. It must be called from an RCU critical section. */ static MemoryRegionSection memory_region_find_rcu(MemoryRegion *mr, - hwaddr addr, uint64_t si= ze) + hwaddr addr, + uint64_t size) { MemoryRegionSection ret =3D { .mr =3D NULL }; MemoryRegion *root; @@ -2576,6 +2596,50 @@ static MemoryRegionSection memory_region_find_rcu(Me= moryRegion *mr, return ret; } =20 +/* + * Same as memory_region_find_flat_range, but it does not add a reference = to + * the returned region. It must be called from an RCU critical section. + */ +static MemoryRegionSection memory_region_find_flat_range_rcu(MemoryRegion = *mr, + hwaddr addr, + uint64_t size) +{ + MemoryRegionSection ret =3D { .mr =3D NULL, .size =3D 0 }; + MemoryRegion *root; + AddressSpace *as; + AddrRange range; + FlatView *view; + FlatRange *fr; + + addr +=3D mr->addr; + for (root =3D mr; root->container; ) { + root =3D root->container; + addr +=3D root->addr; + } + + as =3D memory_region_to_address_space(root); + if (!as) { + return ret; + } + range =3D addrrange_make(int128_make64(addr), int128_make64(size)); + + view =3D address_space_to_flatview(as); + fr =3D flatview_lookup_containing(view, range); + if (!fr) { + return ret; + } + + ret.mr =3D fr->mr; + ret.fv =3D view; + range =3D fr->addr; + ret.offset_within_region =3D fr->offset_in_region; + ret.size =3D range.size; + ret.offset_within_address_space =3D int128_get64(range.start); + ret.readonly =3D fr->readonly; + ret.nonvolatile =3D fr->nonvolatile; + return ret; +} + MemoryRegionSection memory_region_find(MemoryRegion *mr, hwaddr addr, uint64_t size) { @@ -2588,6 +2652,19 @@ MemoryRegionSection memory_region_find(MemoryRegion = *mr, return ret; } =20 +MemoryRegionSection memory_region_find_flat_range(MemoryRegion *mr, + hwaddr addr, uint64_t si= ze) +{ + MemoryRegionSection ret; + rcu_read_lock(); + ret =3D memory_region_find_flat_range_rcu(mr, addr, size); + if (ret.mr) { + memory_region_ref(ret.mr); + } + rcu_read_unlock(); + return ret; +} + bool memory_region_present(MemoryRegion *container, hwaddr addr) { MemoryRegion *mr; --=20 2.7.4 From nobody Thu May 16 23:18:59 2024 Delivered-To: importer@patchew.org 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; Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=partner.samsung.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1580816054868557.3497491315745; Tue, 4 Feb 2020 03:34:14 -0800 (PST) Received: from localhost ([::1]:56714 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywT7-0004bk-Mf for importer@patchew.org; Tue, 04 Feb 2020 06:34:13 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53724) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywQD-0008K2-Jj for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:16 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iywQB-00008W-E3 for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:13 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:51722) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iywQA-0008Nr-Ne for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:10 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200204113106euoutp024561a316f730dccbca7557c9dee47b89~wL6eWgl152964429644euoutp02h for ; Tue, 4 Feb 2020 11:31:06 +0000 (GMT) Received: from eusmges1new.samsung.com (unknown [203.254.199.242]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20200204113105eucas1p232efd275ab3e17e3486b55c40f29a5b8~wL6eNI-w20485604856eucas1p27; Tue, 4 Feb 2020 11:31:05 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges1new.samsung.com (EUCPMTA) with SMTP id 6D.FE.61286.9F5593E5; Tue, 4 Feb 2020 11:31:05 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200204113105eucas1p2981e8d1e49ca9621255a4aedf8f1ec6e~wL6d5MFVt0485604856eucas1p26; Tue, 4 Feb 2020 11:31:05 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200204113105eusmtrp1ec77f69912c3b23fd4cee12359ae0010~wL6d4oIDv2134721347eusmtrp1K; Tue, 4 Feb 2020 11:31:05 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 36.AC.08375.9F5593E5; Tue, 4 Feb 2020 11:31:05 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200204113105eusmtip2143bbf7c37fbc0780dbb857de0c5d40c~wL6djWhKg1398913989eusmtip2L; Tue, 4 Feb 2020 11:31:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200204113106euoutp024561a316f730dccbca7557c9dee47b89~wL6eWgl152964429644euoutp02h DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580815866; bh=G4wTiFmR0fBUdAn0Bzqm0G1Fin1w2mJXa+zDn8QifTo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=sgWYqNNlRMRiMLmo+wjBqdgsv2W9c9pP9+bzUFL5CHjVh055y9ORpBFkcEJ5Zun2r sUsHIYBMDLNfgjVDWlivS2W+BJIW8iqrSWEoF/diX50ektI6EpH/mgXPvtkOtetDmW UfUstrMQfWNJwPMxtNLCTbaIIgF4V929SYKsqyrs= X-AuditID: cbfec7f2-ef1ff7000001ef66-86-5e3955f94df9 From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC 2/9] memory: Support mmap offset for fd-backed memory regions Date: Tue, 4 Feb 2020 12:30:44 +0100 Message-Id: <1580815851-28887-3-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrGIsWRmVeSWpSXmKPExsWy7djP87o/Qy3jDK4sNbbYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlzL2m UvDBpWL/hAWsDYxzdbsYOTkkBEwk+h/9ZgGxhQRWMEo0XVfrYuQCsr8wSvzoW8sK4XxmlDj5 dxsbTMexhk9QieWMEvf6/rDCtVz+fxKsik1ATWLnkc+MILaIgKTE767TzCA2s0CGxPNZ3WC2 sIC3xNwXX1hBbBYBVYmmOxA1vAIBEg/7drFCbJOTuHmuEyzOKRAo8X7PJCaQZRICZ9gkPi8/ zARR5CIx6cAWZghbWOLV8S3sELaMxOnJPSwQdr1Ey50dUM0djBJ9K6dD/WMt8WXDUqAiDqDr NCXW79IHMSUEHCUefC2GMPkkbrwVhDifT2LStunMEGFeiY42IYgZehLdT24ywSxd1vgIaqmH RPvjNiZI8CxhlJi4bwfzBEb5WQi7FjAyrmIUTy0tzk1PLTbMSy3XK07MLS7NS9dLzs/dxAiM /dP/jn/awfj1UtIhRgEORiUe3gt2FnFCrIllxZW5hxglOJiVRHjP61vGCfGmJFZWpRblxxeV 5qQWH2KU5mBREuc1XvQyVkggPbEkNTs1tSC1CCbLxMEp1cB4YE+eUvjiL6/W1ZnqsPvunBF/ uijDZc09lwB9qR7vlo1GnHlXpZ9y+QT3Np1tL5nyee5Jhr0BV87/8wtjM3yTota31Htd7YeV C7V9FmhIpBq/krVb6DK/3vbJjS0Tfj5xb10sue2GdgKTgFlezu96HZWIxjULYz/8OKG47bnu 24mBF9gyVCcosRRnJBpqMRcVJwIA9HgH0PkCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrJLMWRmVeSWpSXmKPExsVy+t/xe7o/Qy3jDBYel7HYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlzL2mUvDBpWL/hAWsDYxzdbsYOTkk BEwkjjV8Yu1i5OIQEljKKDH94AlWiISMxI/Ta9ggbGGJP9e62CCKPjFKvF+3lBEkwSagJrHz yGcwW0RAUuJ312lmEJtZIEti5+z7TCC2sIC3xNwXX8CGsgioSjTdgajhFQiQeNi3C2qZnMTN c51gcU6BQIn3eyaB9QoB1VzYNYt9AiPfAkaGVYwiqaXFuem5xYZ6xYm5xaV56XrJ+bmbGIHB uO3Yz807GC9tDD7EKMDBqMTDe8HOIk6INbGsuDL3EKMEB7OSCO95fcs4Id6UxMqq1KL8+KLS nNTiQ4ymQEdNZJYSTc4HRkpeSbyhqaG5haWhubG5sZmFkjhvh8DBGCGB9MSS1OzU1ILUIpg+ Jg5OqQbGKgueu6Y1F93L7t009Pvx/mSWX+a79YfThc/uteZR2Ruef4ArKU6B6VjvomKXR6J2 mnNdgtkFGGbe11Vnyfs6OydDy1J+wbIF3SwCxj+DM6YpXBOW3ua9/n6I59nwmm03eCO2BuYv jmH/Ojn7/ZF0rQvNTtIzTjL92lh95FaNC8tS09YZx8yUWIozEg21mIuKEwE3to20XAIAAA== X-CMS-MailID: 20200204113105eucas1p2981e8d1e49ca9621255a4aedf8f1ec6e X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200204113105eucas1p2981e8d1e49ca9621255a4aedf8f1ec6e X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200204113105eucas1p2981e8d1e49ca9621255a4aedf8f1ec6e References: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 210.118.77.12 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Igor Kotrasinski , pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Igor Kotrasinski The memexpose device will receive shared memory from another VM and map parts of it as memory regions. For that, we need to be able to mmap the region at an offset from shared memory's start. Signed-off-by: Igor Kotrasinski --- backends/hostmem-memfd.c | 2 +- exec.c | 10 ++++++---- hw/misc/ivshmem.c | 3 ++- include/exec/memory.h | 1 + include/exec/ram_addr.h | 2 +- include/qemu/mmap-alloc.h | 1 + memory.c | 3 ++- util/mmap-alloc.c | 7 ++++--- util/oslib-posix.c | 2 +- 9 files changed, 19 insertions(+), 12 deletions(-) diff --git a/backends/hostmem-memfd.c b/backends/hostmem-memfd.c index 26070b4..7cd6c53 100644 --- a/backends/hostmem-memfd.c +++ b/backends/hostmem-memfd.c @@ -56,7 +56,7 @@ memfd_backend_memory_alloc(HostMemoryBackend *backend, Er= ror **errp) =20 name =3D host_memory_backend_get_name(backend); memory_region_init_ram_from_fd(&backend->mr, OBJECT(backend), - name, backend->size, + name, backend->size, 0, backend->share, fd, errp); g_free(name); } diff --git a/exec.c b/exec.c index 67e520d..afcb3c9 100644 --- a/exec.c +++ b/exec.c @@ -1839,6 +1839,7 @@ static int file_ram_open(const char *path, =20 static void *file_ram_alloc(RAMBlock *block, ram_addr_t memory, + size_t mmap_offset, int fd, bool truncate, Error **errp) @@ -1892,7 +1893,7 @@ static void *file_ram_alloc(RAMBlock *block, perror("ftruncate"); } =20 - area =3D qemu_ram_mmap(fd, memory, block->mr->align, + area =3D qemu_ram_mmap(fd, memory, mmap_offset, block->mr->align, block->flags & RAM_SHARED, block->flags & RAM_PME= M); if (area =3D=3D MAP_FAILED) { error_setg_errno(errp, errno, @@ -2314,7 +2315,7 @@ static void ram_block_add(RAMBlock *new_block, Error = **errp, bool shared) =20 #ifdef CONFIG_POSIX RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr, - uint32_t ram_flags, int fd, + uint32_t ram_flags, int fd, size_t mmap_o= ffset, Error **errp) { RAMBlock *new_block; @@ -2360,7 +2361,8 @@ RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, Mem= oryRegion *mr, new_block->used_length =3D size; new_block->max_length =3D size; new_block->flags =3D ram_flags; - new_block->host =3D file_ram_alloc(new_block, size, fd, !file_size, er= rp); + new_block->host =3D file_ram_alloc(new_block, size, mmap_offset, fd, + !file_size, errp); if (!new_block->host) { g_free(new_block); return NULL; @@ -2390,7 +2392,7 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, M= emoryRegion *mr, return NULL; } =20 - block =3D qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, errp); + block =3D qemu_ram_alloc_from_fd(size, mr, ram_flags, fd, 0, errp); if (!block) { if (created) { unlink(mem_path); diff --git a/hw/misc/ivshmem.c b/hw/misc/ivshmem.c index 1a0fad7..4967d4f 100644 --- a/hw/misc/ivshmem.c +++ b/hw/misc/ivshmem.c @@ -492,7 +492,8 @@ static void process_msg_shmem(IVShmemState *s, int fd, = Error **errp) =20 /* mmap the region and map into the BAR2 */ memory_region_init_ram_from_fd(&s->server_bar2, OBJECT(s), - "ivshmem.bar2", size, true, fd, &local_= err); + "ivshmem.bar2", size, 0, true, fd, + &local_err); if (local_err) { error_propagate(errp, local_err); return; diff --git a/include/exec/memory.h b/include/exec/memory.h index 6092528..28cb2e9 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -917,6 +917,7 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr, struct Object *owner, const char *name, uint64_t size, + uint64_t mmap_offset, bool share, int fd, Error **errp); diff --git a/include/exec/ram_addr.h b/include/exec/ram_addr.h index 5e59a3d..1e85362 100644 --- a/include/exec/ram_addr.h +++ b/include/exec/ram_addr.h @@ -120,7 +120,7 @@ RAMBlock *qemu_ram_alloc_from_file(ram_addr_t size, Mem= oryRegion *mr, uint32_t ram_flags, const char *mem_pat= h, Error **errp); RAMBlock *qemu_ram_alloc_from_fd(ram_addr_t size, MemoryRegion *mr, - uint32_t ram_flags, int fd, + uint32_t ram_flags, int fd, size_t mmap_o= ffset, Error **errp); =20 RAMBlock *qemu_ram_alloc_from_ptr(ram_addr_t size, void *host, diff --git a/include/qemu/mmap-alloc.h b/include/qemu/mmap-alloc.h index e786266..bd95504 100644 --- a/include/qemu/mmap-alloc.h +++ b/include/qemu/mmap-alloc.h @@ -23,6 +23,7 @@ size_t qemu_mempath_getpagesize(const char *mem_path); */ void *qemu_ram_mmap(int fd, size_t size, + size_t mmap_offset, size_t align, bool shared, bool is_pmem); diff --git a/memory.c b/memory.c index e9f37e7..65dd165 100644 --- a/memory.c +++ b/memory.c @@ -1584,6 +1584,7 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr, struct Object *owner, const char *name, uint64_t size, + uint64_t mmap_offset, bool share, int fd, Error **errp) @@ -1595,7 +1596,7 @@ void memory_region_init_ram_from_fd(MemoryRegion *mr, mr->destructor =3D memory_region_destructor_ram; mr->ram_block =3D qemu_ram_alloc_from_fd(size, mr, share ? RAM_SHARED : 0, - fd, &err); + fd, mmap_offset, &err); mr->dirty_log_mask =3D tcg_enabled() ? (1 << DIRTY_MEMORY_CODE) : 0; if (err) { mr->size =3D int128_zero(); diff --git a/util/mmap-alloc.c b/util/mmap-alloc.c index 27dcccd..191db45 100644 --- a/util/mmap-alloc.c +++ b/util/mmap-alloc.c @@ -84,6 +84,7 @@ size_t qemu_mempath_getpagesize(const char *mem_path) =20 void *qemu_ram_mmap(int fd, size_t size, + size_t mmap_offset, size_t align, bool shared, bool is_pmem) @@ -127,7 +128,7 @@ void *qemu_ram_mmap(int fd, flags =3D MAP_PRIVATE | MAP_ANONYMOUS; #endif =20 - guardptr =3D mmap(0, total, PROT_NONE, flags, guardfd, 0); + guardptr =3D mmap(0, total, PROT_NONE, flags, guardfd, mmap_offset); =20 if (guardptr =3D=3D MAP_FAILED) { return MAP_FAILED; @@ -147,7 +148,7 @@ void *qemu_ram_mmap(int fd, offset =3D QEMU_ALIGN_UP((uintptr_t)guardptr, align) - (uintptr_t)guar= dptr; =20 ptr =3D mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, - flags | map_sync_flags, fd, 0); + flags | map_sync_flags, fd, mmap_offset); =20 if (ptr =3D=3D MAP_FAILED && map_sync_flags) { if (errno =3D=3D ENOTSUP) { @@ -172,7 +173,7 @@ void *qemu_ram_mmap(int fd, * we will remove these flags to handle compatibility. */ ptr =3D mmap(guardptr + offset, size, PROT_READ | PROT_WRITE, - flags, fd, 0); + flags, fd, mmap_offset); } =20 if (ptr =3D=3D MAP_FAILED) { diff --git a/util/oslib-posix.c b/util/oslib-posix.c index 5a291cc..e4ffdc1 100644 --- a/util/oslib-posix.c +++ b/util/oslib-posix.c @@ -205,7 +205,7 @@ void *qemu_memalign(size_t alignment, size_t size) void *qemu_anon_ram_alloc(size_t size, uint64_t *alignment, bool shared) { size_t align =3D QEMU_VMALLOC_ALIGN; - void *ptr =3D qemu_ram_mmap(-1, size, align, shared, false); + void *ptr =3D qemu_ram_mmap(-1, size, 0, align, shared, false); =20 if (ptr =3D=3D MAP_FAILED) { return NULL; --=20 2.7.4 From nobody Thu May 16 23:18:59 2024 Delivered-To: importer@patchew.org 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; Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=partner.samsung.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1580816053564918.2982029483617; Tue, 4 Feb 2020 03:34:13 -0800 (PST) Received: from localhost ([::1]:56710 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywT6-0004Xo-6r for importer@patchew.org; Tue, 04 Feb 2020 06:34:12 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53815) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywQH-0008KU-Ng for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iywQB-00007i-A2 for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:17 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:47554) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iywQA-0008PZ-Ns for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:10 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20200204113106euoutp01ec75b1651519749f0e1199d109dca10e~wL6fAC49g1797417974euoutp01r for ; Tue, 4 Feb 2020 11:31:06 +0000 (GMT) Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200204113106eucas1p13e363f2494c18906ee275c5151d8b7d1~wL6e1a7iw0258702587eucas1p1-; Tue, 4 Feb 2020 11:31:06 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id 11.10.60698.AF5593E5; Tue, 4 Feb 2020 11:31:06 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200204113106eucas1p2cf218553048c75f5a8b7771cde90f5f1~wL6eo3BV10478604786eucas1p2C; Tue, 4 Feb 2020 11:31:06 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200204113106eusmtrp1ffe5da8837d5c18144dfda89f0007f07~wL6eoVMm32102721027eusmtrp11; Tue, 4 Feb 2020 11:31:06 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 37.AC.08375.AF5593E5; Tue, 4 Feb 2020 11:31:06 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200204113105eusmtip22c663d39e14f5f41623b9eaf9917cafb~wL6eTCcnj1895218952eusmtip2Y; Tue, 4 Feb 2020 11:31:05 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20200204113106euoutp01ec75b1651519749f0e1199d109dca10e~wL6fAC49g1797417974euoutp01r DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580815866; bh=ibNqqK8kMJTR6I/8H1P2J6EA3/WKQtaT/ZbDNoeJndI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Aqfd4DSAJImERZUZDRiRpHJS7cEn6EgKdBWTc2jPhY8/q9ihzvJTuk+HBFlh7oglZ N5QyTxZ2EcDU3uCvrUpHs0PPGeZzIvoHoipw5i6m+F5Yb/TIlRPkGy/ztKITIcSgAA Cp6MVq6ZV8GP2Q7s1EWRZvjdAMg0lb8Toy+RQrhA= X-AuditID: cbfec7f5-a29ff7000001ed1a-5b-5e3955fa463b From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC 3/9] memory: Hack - use shared memory when possible Date: Tue, 4 Feb 2020 12:30:45 +0100 Message-Id: <1580815851-28887-4-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOIsWRmVeSWpSXmKPExsWy7djPc7q/Qi3jDHo2KFjsufCYzWL/tn+s FnPOPGCxON67g8WBxePOtT1sHk+ubWbyOPhuD5PH+31X2QJYorhsUlJzMstSi/TtErgyVh7q Yin4zlYxb/VGxgbGnyxdjJwcEgImEvtu7GfqYuTiEBJYwSjRumciI4TzhVFi49RXrBDOZ0aJ yVeOssK0HHq5gwUisZxR4tTqG2xwLZOfLGIHqWITUJPYeeQzI4gtIiAp8bvrNDOIzSyQIfF8 VjeYLSzgKNH59wfYISwCqhI/Hu4BGsTBwSsQIPHoUBzEMjmJm+c6wco5BQIl3u+ZBHarhMBl Nonbm/azQRS5SPw7tIAJwhaWeHV8CzuELSNxenIP1KP1Ei13dkA1dzBK9K2cDtVsLfFlw1IW kMXMApoS63fpQ4QdJXZdWMkOEpYQ4JO48VYQ4nw+iUnbpjNDhHklOtqEIKr1JLqf3GSC2bqs 8RELRImHRMcJJUjoLGGU6L0zhW0Co/wshF0LGBlXMYqnlhbnpqcWG+ellusVJ+YWl+al6yXn 525iBEb/6X/Hv+5g3Pcn6RCjAAejEg+vhqNFnBBrYllxZe4hRgkOZiUR3vP6lnFCvCmJlVWp RfnxRaU5qcWHGKU5WJTEeY0XvYwVEkhPLEnNTk0tSC2CyTJxcEo1MJ54V3mRJYDjA8+rvFOn rNQLvoTtSnT4zj+RaWLZXyMxTtdwhZnis7/nvGLWm9TuYS+f5HtkWtLqa6k7eD19nSYfN/yz 6NOTOWZbA+TOyE0S4CgtdknMuj7hpIuKUsTSx/MVuzT3pwksdw/x2tUb+HyXWIPhYrZj5zaa bW9uO3clhz9I82o4jxJLcUaioRZzUXEiAB6A6PP6AgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrJLMWRmVeSWpSXmKPExsVy+t/xe7q/Qi3jDL7cFLLYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlrDzUxVLwna1i3uqNjA2MP1m6GDk5 JARMJA693AFkc3EICSxllPj99DEbREJG4sfpNVC2sMSfa11sEEWfGCVWH3zGDJJgE1CT2Hnk MyOILSIgKfG76zRYnFkgS2Ln7PtMILawgKNE598fYNtYBFQlfjzcAzSIg4NXIEDi0aE4iPly EjfPdYK1cgoESrzfMwmsVQio5MKuWewTGPkWMDKsYhRJLS3OTc8tNtQrTswtLs1L10vOz93E CAzGbcd+bt7BeGlj8CFGAQ5GJR7eC3YWcUKsiWXFlbmHGCU4mJVEeM/rW8YJ8aYkVlalFuXH F5XmpBYfYjQFumkis5Rocj4wUvJK4g1NDc0tLA3Njc2NzSyUxHk7BA7GCAmkJ5akZqemFqQW wfQxcXBKNTB2+T28wif/1n3XCb7yiUUXtHetVL2k4iGwrOb3vcsB/4562/G2nnHjuHXotdnd CdMMvQ3O3dg5wcGswmlqUugew3bB+m4dzbD+BBUunrQCkZnL26b5fZCL9DNjLOZpuqp+0l5f WuRt3M11J2s7t3a9irliU7VMJ+DW9vM3X3a06pU0q7ndmavEUpyRaKjFXFScCADRsg9SXAIA AA== X-CMS-MailID: 20200204113106eucas1p2cf218553048c75f5a8b7771cde90f5f1 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200204113106eucas1p2cf218553048c75f5a8b7771cde90f5f1 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200204113106eucas1p2cf218553048c75f5a8b7771cde90f5f1 References: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 210.118.77.11 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Igor Kotrasinski , pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Igor Kotrasinski Signed-off-by: Igor Kotrasinski --- hw/core/numa.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/hw/core/numa.c b/hw/core/numa.c index 0d1b4be..02fd7f5 100644 --- a/hw/core/numa.c +++ b/hw/core/numa.c @@ -785,8 +785,8 @@ static void allocate_system_memory_nonnuma(MemoryRegion= *mr, Object *owner, if (mem_path) { #ifdef __linux__ Error *err =3D NULL; - memory_region_init_ram_from_file(mr, owner, name, ram_size, 0, 0, - mem_path, &err); + memory_region_init_ram_from_file(mr, owner, name, ram_size, 0, + RAM_SHARED, mem_path, &err); if (err) { error_report_err(err); if (mem_prealloc) { --=20 2.7.4 From nobody Thu May 16 23:18:59 2024 Delivered-To: importer@patchew.org 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; Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=partner.samsung.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1580815954340814.3405169839217; Tue, 4 Feb 2020 03:32:34 -0800 (PST) Received: from localhost ([::1]:56686 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywRU-0001BU-NT for importer@patchew.org; Tue, 04 Feb 2020 06:32:32 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53716) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywQD-0008Jz-C7 for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:15 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iywQA-00005P-Tq for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:13 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:51735) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iywQ9-0008SV-2J for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:10 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200204113107euoutp026242c148d2784e5329fe7332e69f0c37~wL6f7u0q02964429644euoutp02k for ; Tue, 4 Feb 2020 11:31:07 +0000 (GMT) Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200204113107eucas1p1fd78c006df0101467b7fbd2641ef9d6c~wL6fqWhsz0453204532eucas1p16; Tue, 4 Feb 2020 11:31:07 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id 81.10.60698.BF5593E5; Tue, 4 Feb 2020 11:31:07 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200204113107eucas1p2769c0c8204a57751a4e6c5d4fb40e2d5~wL6fYmjsl0640206402eucas1p27; Tue, 4 Feb 2020 11:31:07 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200204113107eusmtrp162f6086b3ef6083eafaf341f3445b89f~wL6fYCDW82134721347eusmtrp1O; Tue, 4 Feb 2020 11:31:07 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 09.0A.07950.BF5593E5; Tue, 4 Feb 2020 11:31:07 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200204113106eusmtip24bd2d45e97ffffd6462b24e717764223~wL6fFHl4K1661216612eusmtip2U; Tue, 4 Feb 2020 11:31:06 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200204113107euoutp026242c148d2784e5329fe7332e69f0c37~wL6f7u0q02964429644euoutp02k DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580815867; bh=8LLBPAO/LldhOK3S6vWhA9qETZneTqAWHe8OySLFLVo=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=KgtLze268SxE9N6lABtn5q/6HvCTZyK+zptlcq9HzaXS63zLQtdnf/Rfvby8PVLiE ngzypLYdyWOvfqFv9D0c672R4/J7tVLi5PPDTpH1AfzhtGtrHJmwLNN9YurLPxKEKi dkbTgVPk8kOOQp0pb7koR2IR5ZbI5tABda6w7mfw= X-AuditID: cbfec7f5-e577d9c00001ed1a-5d-5e3955fb7dbb From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC 4/9] hw/misc/memexpose: Add documentation Date: Tue, 4 Feb 2020 12:30:46 +0100 Message-Id: <1580815851-28887-5-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOIsWRmVeSWpSXmKPExsWy7djP87q/Qy3jDPa8ELfYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlnJk2 j7HggWNFz5OVjA2MT427GDk5JARMJF6vWsoGYgsJrGCUuDNfqouRC8j+wijx5exeNgjnM6NE y7KZLDAd78//gupYzijx71g+XEdD3y5mkASbgJrEziOfGUFsEQFJid9dp8HizAIZEs9ndYPZ wgLmEudb7oDZLAKqEtPWnAGzeQUCJHbOesAKsUxO4ua5TrA4p0CgxPs9k5hAlkkInGGTuLLl KyNEkYtE772dzBC2sMSr41vYIWwZidOTe6CurpdoubMDqrmDUaJv5XQ2iIS1xJcNS4GKOICu 05RYv0sfIuwo0dl8BSwsIcAnceOtIMT9fBKTtk1nhgjzSnS0CUFU60l0P7nJBLN1WeMjqK0e Eg/bZjJBwmcJo8TEt8dZJzDKz0JYtoCRcRWjeGppcW56arFxXmq5XnFibnFpXrpecn7uJkZg 9J/+d/zrDsZ9f5IOMQpwMCrx8Go4WsQJsSaWFVfmHmKU4GBWEuE9r28ZJ8SbklhZlVqUH19U mpNafIhRmoNFSZzXeNHLWCGB9MSS1OzU1ILUIpgsEwenVAMja02s89xffvMvbz0SpGD5Zq/M YtXrBhc+yn5hrxHTC173scVCKMraS+tup5flJ81r75ttXi7QmLPRbdWpu2GbJvvO5TunHvNB dlbHsaSK4KNvmPa25qjOKvi6dt2EXarTNA8f4jVmM13L+CpIauHzio7SrXm2kwIMbB0jAjvX 6JfE5lyamBmmxFKckWioxVxUnAgAvMAoEvoCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRmVeSWpSXmKPExsVy+t/xe7q/Qy3jDI7fZLPYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlnJk2j7HggWNFz5OVjA2MT427GDk5 JARMJN6f/8XWxcjFISSwlFFi8+UDbBAJGYkfp9dA2cISf651QRV9YpQ4Na8JLMEmoCax88hn RhBbREBS4nfXaWYQm1kgS2Ln7PtMILawgLnE+ZY7YHEWAVWJaWvOgNm8AgESO2c9YIVYICdx 81wnWJxTIFDi/Z5JYL1CQDUXds1in8DIt4CRYRWjSGppcW56brGRXnFibnFpXrpecn7uJkZg OG479nPLDsaud8GHGAU4GJV4eDUcLeKEWBPLiitzDzFKcDArifCe17eME+JNSaysSi3Kjy8q zUktPsRoCnTURGYp0eR8YKzklcQbmhqaW1gamhubG5tZKInzdggcjBESSE8sSc1OTS1ILYLp Y+LglGpgTPO+sm6p4grDvOfHT0zZHLpQe5/eLNbymz8eHOR9cmXSjv3FevqlGtMbk9mmSzJH CjXPjxQP7r5eVXvH2Xuug3NyyRJ2BVmVTWL7Y61/bJK2kZFf1fP88a+ISPMD1uXsAjN13vp9 t+Cel7Pu0a9bbOXTrNdnbaq7plq/TEbxjNFS84+lyxpZlViKMxINtZiLihMBHpq8bl0CAAA= X-CMS-MailID: 20200204113107eucas1p2769c0c8204a57751a4e6c5d4fb40e2d5 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200204113107eucas1p2769c0c8204a57751a4e6c5d4fb40e2d5 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200204113107eucas1p2769c0c8204a57751a4e6c5d4fb40e2d5 References: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 210.118.77.12 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Igor Kotrasinski , pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Igor Kotrasinski Signed-off-by: Igor Kotrasinski --- docs/specs/memexpose-spec.txt | 168 ++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 168 insertions(+) create mode 100644 docs/specs/memexpose-spec.txt diff --git a/docs/specs/memexpose-spec.txt b/docs/specs/memexpose-spec.txt new file mode 100644 index 0000000..60ccea6 --- /dev/null +++ b/docs/specs/memexpose-spec.txt @@ -0,0 +1,168 @@ +=3D Specification for Inter-VM memory region sharing device =3D + +The inter-VM memory region sharing device (memexpose) is designed to allow= two +QEMU devices to share arbitrary physical memory regions between one anothe= r, as +well as pass simple interrupts. It attempts to share memory regions direct= ly +when feasible, falling back to MMIO via socket communication when it's not. + +The device is modeled by QEMU as a PCI device, as well as a memory +region/interrupt directly usable on platforms like ARM, with an entry in t= he +device tree. + +An example use case for memexpose is forwarding ARM Trustzone functionality +between two VMs running different architectures - one running a rich OS on= an +x86_64 VM, the other running the trusted OS on an ARM VM. In this scenario, +sharing arbitrary memory regions allows such forwarding to work with minim= al +changes to the trusted OS. + + +=3D=3D Configuring the memexpose device =3D=3D + +The device uses two character devices to communicate with the other VM - o= ne for +synchronous memory accesses, another for passing interrupts. A typical +configuration of the PCI device looks like this: + + -chardev socket,...,path=3D/tmp/qemu-memexpose-mem,id=3D"mem" \ + -chardev socket,...,path=3D/tmp/qemu-memexpose-intr,id=3D"intr" \ + -device memexpose-pci,mem_chardev=3D"mem",intr_chardev=3D"intr",sh= m_size=3D0xN... + +While the arm-virt machine device can be enabled like this: +=20 + -chardev socket,...,path=3D/tmp/qemu-memexpose-mem,id=3D"mem-mem" \ + -chardev socket,...,path=3D/tmp/qemu-memexpose-intr,id=3D"mem-intr= " \ + -machine memexpose-ep=3Dmem,memexpose-size=3D0xN... + +Normally one of the VMs would have 'server,nowait' options set on these +chardevs. + +At the moment the memory exposed to the other device always starts at 0 +(relative to system_memory). The shm_size/memexpose-size property indicate= s the +size of the exposed region. + +The *_chardev/memexpose-ep properties are used to point the memexpose devi= ce to +chardevs used to communicate with the other VM. + + +=3D=3D Memexpose PCI device interface =3D=3D=3D + +The device has vendor ID 1af4, device ID 1111, revision 0. + +=3D=3D=3D PCI BARs =3D=3D=3D + +The device has two BARs: +- BAR0 holds device registers and interrupt data (0x1000 byte MMIO), +- BAR1 maps memory from the other VM. + +To use the device, you must first enable it by writing 1 to BAR0 at addres= s 0. +This makes QEMU wait for another VM to connect. Once that is done, you can +access the other machine's memory via BAR1. + +Interrupts can be sent and received by configuring the device for interrup= ts and +reading and writing to registers in BAR0. + +=3D=3D=3D Device registers =3D=3D=3D + +BAR 0 has following registers: + + Offset Size Access On reset Function + 0 8 read/write 0 Enable/disable device + bit 0: device enabled / disabled + bit 1..63: reserved + 0x400 8 read/write 0 Interrupt RX address + bit 1: interrupt read + bit 1..63: reserved + 0x408 8 read-only UD RX Interrupt type + 0x410 128 read-only UD RX Interrupt data + 0x800 8 read/write 0 Interrupt TX address + 0x808 8 write-only N/A TX Interrupt type + 0x810 128 write-only N/A TX Interrupt data + +All other addresses are reserved. + +=3D=3D=3D Handling interrupts =3D=3D=3D + +To send interrupts, write to TX interrupt address. Contents of TX interrup= t type +and data regions will be send along with the interrupt. The device is hold= ing an +internal queue of 16 interrupts, any extra interrupts are silently dropped. + +To receive interrupts, read the interrupt RX address. If the value is 1, t= hen +RX interrupt type and data registers contain the data / type sent by the o= ther +VM. Otherwise (the value is 0), no more interrupts are queued and RX inter= rupt +type/data register contents are undefined. + + +=3D=3D=3D Platform device protocol =3D=3D=3D + +The other memexpose device type (provided on e.g. ARM via device tree) is +essentially identical to the PCI device. It provides two memory ranges tha= t work +exactly like the PCI BAR regions and an interrupt for signaling an interru= pt +from the other VM. + +=3D=3D Memexpose peer protocol =3D=3D + +This section describes the current memexpose protocol. It is a WIP and lik= ely to +change. + +A connection between two VMs connected via memexpose happens on two socket= s - an +interrupt socket and a memory socket. All communication on the earlier is +asynchronous, while communication on the latter is synchronous. + +When the device is enabled, QEMU waits for memexpose's chardevs to connect= . No +messages are exchanged upon connection. After devices are connected, the +following messages can be exchanged: + +1. Interrupt message, via interrupt socket. This message contains interrup= t type + and data. + +2. Memory access request message, via memory socket. It contains a target + address, access size and valueto write in case of writes. + +3. Memory access return message. This contains an access result (as + MemTxResult) and a value in case of reads. If the accessed region can be + shared directly, then this region's start, size and shmem file descript= or are + also sent. + +4. Memory invalidation message. This is sent when a VM's memory region cha= nges + status and contains such region's start and size. The other VM is expec= ted to + drop any shared regions overlapping with it. + +5. Memory invalidation response. This is sent in response to a memory + invalidation message; after receiving this the remote VM is guaranteed = have + scheduled region invalidation before accessing the region again. + +As QEMU performes memory accesses synchronously, we want to perform memory +invalidation before returning to guest OS and both VMs might try to perfor= m a +remote memory access at the same time, all messages passed via the memory = socket +have an associated priority. + +At any time, only one message with a given priority is in flight. After se= nding +a message, the VM reads messages on the memory socket, servicing all messa= ges +with a priority higher than its own. Once it receives a message with a pri= ority +lower than its own, it waits for a response to its own message before serv= icing +it. This guarantees no deadlocks, assuming that messages don't trigger fur= ther +messages. Message priorities, from highest to lowest, are as follows: + +1. Memory invalidation message/response. +2. Memory access message/response. + +Additionally, one of the VMs is assigned a sub-priority higher than anothe= r, so +that its messages of the same type have priority over the other VM's messa= ges. + +Memory access messages have the lowest priority in order to guarantee that= QEMU +will not attempt to access memory while in the middle of a memory region +listener. + +=3D=3D=3D Memexpose memory sharing =3D=3D=3D + +This section describes the memexpose memory sharing mechanism. + +Memory sharing is implemented lazily, initially no memory regions are shar= ed +between devices. When a memory access is performed via a socket, the remot= e VM +checks whether the underlying memory range is backed by shareable memory. = If it +is, the VM finds out the maximum contiguous flat range backed by this regi= on and +sends its file descriptor to the local VM, where it is mapped as a subregi= on. + +The memexpose device registers memory listeners for the memory region it's +using. Whenever a flat range for this region (that is not this device's +subregion) changes, that range is sent to the other VM and any directly sh= ared +memory region intersecting this range is scheduled for removal via a BH. --=20 2.7.4 From nobody Thu May 16 23:18:59 2024 Delivered-To: importer@patchew.org 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; Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=partner.samsung.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1580816337573234.77719740313057; Tue, 4 Feb 2020 03:38:57 -0800 (PST) Received: from localhost ([::1]:56786 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywXg-0001Y8-F0 for importer@patchew.org; Tue, 04 Feb 2020 06:38:56 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53856) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywQJ-0008L2-Qr for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iywQB-00009R-HI for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:19 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:51759) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iywQA-0008Ug-Qk for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:11 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200204113108euoutp0237834b4f316c3e736a51ef584fc87d81~wL6gyFjya3205332053euoutp02B for ; Tue, 4 Feb 2020 11:31:08 +0000 (GMT) Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200204113108eucas1p18f4b297263f5f42db2652c186660800d~wL6gg_H8U2455424554eucas1p1w; Tue, 4 Feb 2020 11:31:08 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id C5.3C.60679.CF5593E5; Tue, 4 Feb 2020 11:31:08 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200204113108eucas1p232d86a495fa8200473047ffb58548201~wL6gOHDPs2920029200eucas1p2j; Tue, 4 Feb 2020 11:31:08 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200204113108eusmtrp18c0f945aeda9d2dbe8e38a506e755f4c~wL6gNizhp2102721027eusmtrp13; Tue, 4 Feb 2020 11:31:08 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id A7.AC.08375.BF5593E5; Tue, 4 Feb 2020 11:31:07 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200204113107eusmtip2479f978ca66be05f90dc5da48d071543~wL6f0yb2H1398913989eusmtip2N; Tue, 4 Feb 2020 11:31:07 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200204113108euoutp0237834b4f316c3e736a51ef584fc87d81~wL6gyFjya3205332053euoutp02B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580815868; bh=TJ4ctMl64g0kZLzswqvsjCOlZegTzNt1tTTqd5jmVAg=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=G5kgQWysMv/uTqUbFEC8VZcq3inaqv/A8QSZNYRT4odS6ZP0PywoIHK0JLSP1Es3D G39GgzFnN/SWjrZknRdyo/NaxL+JuCA9hFb+SWr8/AMhOFE8ri73gLnKa5rQ7CCKtK 3Bd8tUP/vP3ZDpzclrtRHJFvtR+ej6C0GcitA1xo= X-AuditID: cbfec7f4-0e5ff7000001ed07-da-5e3955fc79e7 From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC 5/9] hw/misc/memexpose: Add core memexpose files Date: Tue, 4 Feb 2020 12:30:47 +0100 Message-Id: <1580815851-28887-6-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrKIsWRmVeSWpSXmKPExsWy7djPc7p/Qi3jDCatE7HYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlNDSy FLw8xVTR2/OQvYHx3ifGLkZODgkBE4mGe93MXYxcHEICKxgl5r1ezgrhfGGU+PBsB1iVkMBn Rol/U3m7GDnAOo4s9oaoWc4osf7RTYSGAwd/MYM0sAmoSew88hmsWURAUuJ312mwOLNAhsTz Wd1gtrCAncTctpksIDaLgKrE/gW/WEEW8AoESLxrlIC4Tk7i5rlOsHJOgUCJ93smMYHskhC4 ziaxYsseNoiDXCRuPbaEqBeWeHV8CzuELSNxenIPC4RdL9FyZwdUbwejRN/K6WwQCWuJLxuW soDMYRbQlFi/Sx9ipKPEopOMECafxI23ghDH80lM2jadGSLMK9HRJgQxQ0+i+8lNJpilyxof QS31kNj+ZS0jJHCWMEr86JjPMoFRfhbCrgWMjKsYxVNLi3PTU4uN8lLL9YoTc4tL89L1kvNz NzECI//0v+NfdjDu+pN0iFGAg1GJh/fkWYs4IdbEsuLK3EOMEhzMSiK85/Ut44R4UxIrq1KL 8uOLSnNSiw8xSnOwKInzGi96GSskkJ5YkpqdmlqQWgSTZeLglGpgLFqrbiTycO/vq1YJ1zPf iBvwqM0LaHnWxcbxzOzAuQWn63tWSGfOPbD1kfXWQ3yBx204tsn4vdvGPa+vtvV42qPtCkYu i4uNOftsJALq/k+44pk/tXTx+ltJGZ58C7OrX+8/3u7B6L5htvkX5ou3L+xOXGEcw96sWaR4 X999X1Ope/HiyQkblFiKMxINtZiLihMBz13CmvgCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrJLMWRmVeSWpSXmKPExsVy+t/xe7q/Qy3jDC69tLHYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlNDSyFLw8xVTR2/OQvYHx3ifGLkYO DgkBE4kji727GLk4hASWMkpMvfeEuYuREyguI/Hj9Bo2CFtY4s+1LjaIok+MEu+blzGCJNgE 1CR2HvkMZosISEr87joN1swskCWxc/Z9JhBbWMBOYm7bTBYQm0VAVWL/gl+sIIt5BQIk3jVK QMyXk7h5rhOslVMgUOL9nklgrUJAJRd2zWKfwMi3gJFhFaNIamlxbnpusaFecWJucWleul5y fu4mRmAwbjv2c/MOxksbgw8xCnAwKvHwXrCziBNiTSwrrsw9xCjBwawkwnte3zJOiDclsbIq tSg/vqg0J7X4EKMp0E0TmaVEk/OBkZJXEm9oamhuYWlobmxubGahJM7bIXAwRkggPbEkNTs1 tSC1CKaPiYNTqoGR77IV92XjhAvLe8KvfjylnvZRSeVu0Te/K3//nj2blPqeYcPNjTc+qqz/ 8Cg/get286xYI83uZ9cqZuvon7srwdO9zNmZ6d8a/YOz1iZ8P5W+5te/bX/PhQUVKu/d/KeG 6eM7u6yg032bz/e8+FqftEld62mg09XN++XkPuc3J1no6xxeqbzluBJLcUaioRZzUXEiAE/g Ju9cAgAA X-CMS-MailID: 20200204113108eucas1p232d86a495fa8200473047ffb58548201 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200204113108eucas1p232d86a495fa8200473047ffb58548201 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200204113108eucas1p232d86a495fa8200473047ffb58548201 References: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 210.118.77.12 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Igor Kotrasinski , pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Igor Kotrasinski Signed-off-by: Igor Kotrasinski --- Kconfig.host | 3 + MAINTAINERS | 8 + Makefile | 1 + configure | 8 + hw/mem/Kconfig | 3 + hw/misc/Makefile.objs | 1 + hw/misc/memexpose/Makefile.objs | 2 + hw/misc/memexpose/memexpose-core.c | 630 +++++++++++++++++++++++++++++++++= ++++ hw/misc/memexpose/memexpose-core.h | 109 +++++++ hw/misc/memexpose/memexpose-msg.c | 261 +++++++++++++++ hw/misc/memexpose/memexpose-msg.h | 161 ++++++++++ 11 files changed, 1187 insertions(+) create mode 100644 hw/misc/memexpose/Makefile.objs create mode 100644 hw/misc/memexpose/memexpose-core.c create mode 100644 hw/misc/memexpose/memexpose-core.h create mode 100644 hw/misc/memexpose/memexpose-msg.c create mode 100644 hw/misc/memexpose/memexpose-msg.h diff --git a/Kconfig.host b/Kconfig.host index 55136e0..7470210 100644 --- a/Kconfig.host +++ b/Kconfig.host @@ -20,6 +20,9 @@ config SPICE config IVSHMEM bool =20 +config MEMEXPOSE + bool + config TPM bool =20 diff --git a/MAINTAINERS b/MAINTAINERS index 1f0bc72..d6146c0 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1639,6 +1639,14 @@ F: hw/virtio/virtio-crypto.c F: hw/virtio/virtio-crypto-pci.c F: include/hw/virtio/virtio-crypto.h =20 +memexpose +M: Igor Kotrasinski +S: Maintained +F: hw/misc/memexpose/memexpose-core.h +F: hw/misc/memexpose/memexpose-core.c +F: hw/misc/memexpose/memexpose-msg.h +F: hw/misc/memexpose/memexpose-msg.c + nvme M: Keith Busch L: qemu-block@nongnu.org diff --git a/Makefile b/Makefile index a6f5d44..b125a1b 100644 --- a/Makefile +++ b/Makefile @@ -387,6 +387,7 @@ MINIKCONF_ARGS =3D \ CONFIG_KVM=3D$(CONFIG_KVM) \ CONFIG_SPICE=3D$(CONFIG_SPICE) \ CONFIG_IVSHMEM=3D$(CONFIG_IVSHMEM) \ + CONFIG_MEMEXPOSE=3D$(CONFIG_MEMEXPOSE) \ CONFIG_TPM=3D$(CONFIG_TPM) \ CONFIG_XEN=3D$(CONFIG_XEN) \ CONFIG_OPENGL=3D$(CONFIG_OPENGL) \ diff --git a/configure b/configure index 5095f01..710e739 100755 --- a/configure +++ b/configure @@ -505,6 +505,7 @@ debug_mutex=3D"no" libpmem=3D"" default_devices=3D"yes" plugins=3D"no" +memexpose=3D"no" =20 supported_cpu=3D"no" supported_os=3D"no" @@ -1020,6 +1021,10 @@ for opt do ;; --without-default-devices) default_devices=3D"no" ;; + --enable-memexpose) memexpose=3D"yes" + ;; + --disable-memexpose) memexpose=3D"no" + ;; --enable-gprof) gprof=3D"yes" ;; --enable-gcov) gcov=3D"yes" @@ -7400,6 +7405,9 @@ fi if test "$ivshmem" =3D "yes" ; then echo "CONFIG_IVSHMEM=3Dy" >> $config_host_mak fi +if test "$memexpose" =3D "yes" ; then + echo "CONFIG_MEMEXPOSE=3Dy" >> $config_host_mak +fi if test "$capstone" !=3D "no" ; then echo "CONFIG_CAPSTONE=3Dy" >> $config_host_mak fi diff --git a/hw/mem/Kconfig b/hw/mem/Kconfig index 620fd4c..e377b05 100644 --- a/hw/mem/Kconfig +++ b/hw/mem/Kconfig @@ -5,6 +5,9 @@ config DIMM config MEM_DEVICE bool =20 +config MEM_EXPOSE + bool + config NVDIMM bool default y diff --git a/hw/misc/Makefile.objs b/hw/misc/Makefile.objs index da993f4..7e9a692 100644 --- a/hw/misc/Makefile.objs +++ b/hw/misc/Makefile.objs @@ -27,6 +27,7 @@ common-obj-$(CONFIG_PUV3) +=3D puv3_pm.o common-obj-$(CONFIG_MACIO) +=3D macio/ =20 common-obj-$(CONFIG_IVSHMEM_DEVICE) +=3D ivshmem.o +common-obj-$(CONFIG_MEMEXPOSE) +=3D memexpose/ =20 common-obj-$(CONFIG_REALVIEW) +=3D arm_sysctl.o common-obj-$(CONFIG_NSERIES) +=3D cbus.o diff --git a/hw/misc/memexpose/Makefile.objs b/hw/misc/memexpose/Makefile.o= bjs new file mode 100644 index 0000000..f405fe7 --- /dev/null +++ b/hw/misc/memexpose/Makefile.objs @@ -0,0 +1,2 @@ +common-obj-y +=3D memexpose-msg.o +common-obj-y +=3D memexpose-core.o diff --git a/hw/misc/memexpose/memexpose-core.c b/hw/misc/memexpose/memexpo= se-core.c new file mode 100644 index 0000000..3b6ef3c --- /dev/null +++ b/hw/misc/memexpose/memexpose-core.c @@ -0,0 +1,630 @@ +/* + * Memexpose core + * + * Copyright (C) 2020 Samsung Electronics Co Ltd. + * Igor Kotrasinski, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "memexpose-core.h" +#include "exec/address-spaces.h" +#include "exec/cpu-common.h" + +static int memexpose_pop_intr(MemexposeIntr *s) +{ + if (s->queue_count =3D=3D 0) { + MEMEXPOSE_DPRINTF("No queued interrupts\n"); + return 0; + } + struct memexpose_op_intr *head =3D &s->intr_queue[s->queue_start]; + s->intr_rx =3D *head; + s->queue_start =3D (s->queue_start + 1) % MEMEXPOSE_INTR_QUEUE_SIZE; + s->queue_count--; + + if (!s->queue_count) { + s->ops.intr(s->ops.parent, 0); + } + MEMEXPOSE_DPRINTF("Popped interrupt %lx\n", s->intr_rx.type); + return 1; +} + +static void memexpose_push_intr(MemexposeIntr *s, struct memexpose_op_intr= *msg) +{ + int signal =3D 0, free_slot; + + if (s->queue_count =3D=3D MEMEXPOSE_INTR_QUEUE_SIZE) { + MEMEXPOSE_DPRINTF("Interrupt queue is already full!\n"); + return; + } + free_slot =3D (s->queue_start + s->queue_count) % MEMEXPOSE_INTR_QUEUE= _SIZE; + s->intr_queue[free_slot] =3D *msg; + if (!s->queue_count) { + signal =3D 1; + } + s->queue_count++; + + if (signal) { + s->ops.intr(s->ops.parent, 1); + } +} + +static void process_intr(void *opaque, struct memexpose_op *op, Error **er= r) +{ + MemexposeIntr *s =3D opaque; + switch (op->head.ot) { + case MOP_INTR: + memexpose_push_intr(s, &op->body.intr); + break; + default: + error_setg(err, "Unknown memexpose intr command %u", op->head.ot); + } +} + +static void memexpose_send_intr(MemexposeIntr *s) +{ + struct memexpose_op msg; + + msg.head.ot =3D MOP_INTR; + msg.head.size =3D sizeof(msg.head) + sizeof(msg.body.intr); + msg.head.prio =3D 0; + msg.body.intr =3D s->intr_tx; + memexpose_ep_write_async(&s->ep, &msg); + MEMEXPOSE_DPRINTF("Sending interrupt %lx\n", msg.body.intr.type); +} + +#define IN_INTR_DATA_RANGE(a, s, r) \ + (a >=3D r && \ + a < r + MEMEXPOSE_MAX_INTR_DATA_SIZE && \ + (s =3D MIN(s, r + MEMEXPOSE_MAX_INTR_DATA_SIZE - a), 1)) + +static uint64_t memexpose_intr_read(void *opaque, hwaddr addr, + unsigned size) +{ + MemexposeIntr *s =3D opaque; + uint64_t ret =3D 0; + unsigned int boff =3D 8 * (addr & 0x7); + + switch (addr & (~0x7)) { + case MEMEXPOSE_INTR_RX_TYPE_ADDR: + ret =3D s->intr_rx.type; + ret >>=3D boff; + return ret; + case MEMEXPOSE_INTR_TX_TYPE_ADDR: + ret =3D s->intr_tx.type; + ret >>=3D boff; + return ret; + case MEMEXPOSE_INTR_RECV_ADDR: + /* Make multiple read calls in readq and such behave as expected */ + if (addr & 0x7) { + return 0; + } + + ret =3D memexpose_pop_intr(s); + return ret; + case MEMEXPOSE_INTR_ENABLE_ADDR: + if (addr & 0x7) { + return 0; + } + return s->enabled; + default: + break; + } + + if (IN_INTR_DATA_RANGE(addr, size, MEMEXPOSE_INTR_RX_DATA_ADDR)) { + uint64_t off =3D addr - MEMEXPOSE_INTR_RX_DATA_ADDR; + memcpy(&ret, s->intr_rx.data + off, size); + return ret; + } else if (IN_INTR_DATA_RANGE(addr, size, MEMEXPOSE_INTR_TX_DATA_ADDR)= ) { + uint64_t off =3D addr - MEMEXPOSE_INTR_TX_DATA_ADDR; + memcpy(&ret, s->intr_tx.data + off, size); + return ret; + } else { + MEMEXPOSE_DPRINTF("Invalid mmio read at " TARGET_FMT_plx "\n", add= r); + ret =3D 0; + return ret; + } +} + +static void memexpose_intr_write(void *opaque, hwaddr addr, + uint64_t val, unsigned size) +{ + MemexposeIntr *s =3D opaque; + unsigned int boff =3D 8 * (addr & 0x7); + uint64_t mask =3D ((1LL << (size * 8)) - 1) << boff; + + switch (addr & (~0x7)) { + case MEMEXPOSE_INTR_RX_TYPE_ADDR: + s->intr_rx.type &=3D ~mask; + s->intr_rx.type |=3D (val << boff); + return; + case MEMEXPOSE_INTR_TX_TYPE_ADDR: + s->intr_tx.type &=3D ~mask; + s->intr_tx.type |=3D (val << boff); + return; + case MEMEXPOSE_INTR_SEND_ADDR: + /* Make multiple write calls in writeq and such behave as expected= */ + if (addr & 0x7) { + return; + } + memexpose_send_intr(s); + return; + case MEMEXPOSE_INTR_ENABLE_ADDR: + if (addr & 0x7) { + return; + } + if (val) { + if (s->ops.enable) { + s->enabled =3D s->ops.enable(s->ops.parent) ? 0 : 1; + } else { + s->enabled =3D 1; + } + } else { + if (s->ops.disable) { + s->ops.disable(s->ops.parent); + } + s->enabled =3D 0; + } + return; + } + + if (IN_INTR_DATA_RANGE(addr, size, MEMEXPOSE_INTR_RX_DATA_ADDR)) { + uint64_t off =3D addr - MEMEXPOSE_INTR_RX_DATA_ADDR; + memcpy(s->intr_rx.data + off, &val, size); + } else if (IN_INTR_DATA_RANGE(addr, size, MEMEXPOSE_INTR_TX_DATA_ADDR)= ) { + uint64_t off =3D addr - MEMEXPOSE_INTR_TX_DATA_ADDR; + memcpy(s->intr_tx.data + off, &val, size); + } else { + MEMEXPOSE_DPRINTF("Invalid mmio write at " TARGET_FMT_plx "\n", ad= dr); + } +} + +static const MemoryRegionOps memexpose_intr_ops =3D { + .read =3D memexpose_intr_read, + .write =3D memexpose_intr_write, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .impl =3D { + .min_access_size =3D 4, + .max_access_size =3D 4, + }, +}; + +void memexpose_intr_init(MemexposeIntr *s, struct memexpose_intr_ops *ops, + Object *parent, CharBackend *chr, Error **errp) +{ + if (!qemu_chr_fe_backend_connected(chr)) { + error_setg(errp, "You must specify a 'intr_chardev'"); + return; + } + + s->parent =3D parent; + s->ops =3D *ops; + s->enabled =3D 0; + s->queue_start =3D 0; + s->queue_count =3D 0; + memexpose_ep_init(&s->ep, chr, s, 0, process_intr); + s->ep.is_async =3D true; + memory_region_init_io(&s->shmem, parent, &memexpose_intr_ops, s, + "memexpose-intr", MEMEXPOSE_INTR_MEM_SIZE); +} + +int memexpose_intr_enable(MemexposeIntr *s) +{ + return memexpose_ep_connect(&s->ep); +} + +void memexpose_intr_disable(MemexposeIntr *s) +{ + memexpose_ep_disconnect(&s->ep); +} + +void memexpose_intr_destroy(MemexposeIntr *s) +{ + memexpose_intr_disable(s); + /* Region will be collected with its parent */ + memexpose_ep_destroy(&s->ep); +} + +static bool memshare_region_overlaps(MemexposeMem *s, + struct memexpose_memshare_info_fd *sh= are) +{ + MemexposeRemoteMemory *mem; + QLIST_FOREACH(mem, &s->remote_regions, list) { + uint64_t start =3D memory_region_get_ram_addr(&mem->region); + uint64_t size =3D memory_region_size(&mem->region); + MEMEXPOSE_DPRINTF("Comparing regions: received %"PRIx64"-%"PRIx64"= , "\ + "current mapped %"PRIx64"-%"PRIx64"\n", + share->start, share->start + share->size, + start, start + size); + if (start < share->start + share->size || + share->start < start + size) + return true; + } + return false; +} + +static void memshare_add_region(MemexposeMem *s, int fd, + struct memexpose_memshare_info_fd *share, + Error **errp) +{ + if (share->start >=3D s->shmem_size) { + /* TODO - error out */ + MEMEXPOSE_DPRINTF("Shared memory start too high: " + "%" PRIx64 " >=3D %" PRIx64, + share->start, s->shmem_size); + close(fd); + return; + } + + if (memshare_region_overlaps(s, share)) { + /* TODO - error out */ + MEMEXPOSE_DPRINTF("Shared memory %" PRIx64 "-%" PRIx64 + " overlaps with existing region", + share->start, share->start + share->size); + close(fd); + return; + } + + uint64_t clamped_size =3D s->shmem_size - share->start; + share->size =3D MIN(share->size, clamped_size); + + MemexposeRemoteMemory *mem =3D g_malloc(sizeof(*mem)); + char *rname =3D g_strdup_printf("Memexpose shmem " + "%" PRIx64 "-%" PRIx64" -> %" PRIx64, + share->start, share->start + share->size, + share->mmap_start); + + MEMEXPOSE_DPRINTF("Mapping remote memory: %" PRIx64 \ + "-%" PRIx64 ", fd offset %" PRIx64 "\n", + share->start, share->size, share->mmap_start); + + memory_region_init_ram_from_fd(&mem->region, s->parent, rname, + share->size, share->mmap_start, + true, fd, errp); + if (*errp) { + error_report_err(*errp); + close(fd); + return; + } + + memory_region_set_nonvolatile(&mem->region, share->nonvolatile); + memory_region_set_readonly(&mem->region, share->readonly); + g_free(rname); + memory_region_add_subregion_overlap(&s->shmem, share->start, + &mem->region, 1); + QLIST_INSERT_HEAD(&s->remote_regions, mem, list); +} + +static void memshare_remove_region(MemexposeMem *s, MemexposeRemoteMemory = *reg) +{ + /* TODO is this correct? Docs warn about leaked refcounts */ + QLIST_REMOVE(reg, list); + memory_region_del_subregion(&s->shmem, ®->region); + object_unparent(OBJECT(®->region)); +} + +static void memshare_handle(MemexposeMem *s, + struct memexpose_memshare_info *share) +{ + int fd; + switch (share->type) { + case MEMSHARE_NONE: + return; + case MEMSHARE_FD: + fd =3D memexpose_ep_recv_fd(&s->ep); + MEMEXPOSE_DPRINTF("Received memshare fd: %d\n", fd); + if (s->pending_invalidation) { + close(fd); + return; + } + Error *err =3D NULL; + memshare_add_region(s, fd, &share->fd, &err); /* TODO - handle err= ors */ + return; + default: + MEMEXPOSE_DPRINTF("Invalid memshare type: %u\n", share->type); + return; + } +} + +static MemTxResult memexpose_read_slow(void *opaque, hwaddr addr, + uint64_t *data, unsigned size, + MemTxAttrs attrs) +{ + MemexposeMem *s =3D opaque; + + struct memexpose_op msg; + msg.head.size =3D sizeof(msg.head) + sizeof(msg.body.read); + msg.head.ot =3D MOP_READ; + msg.head.prio =3D memexpose_ep_msg_prio(&s->ep, msg.head.ot); + msg.body.read.offset =3D addr; + msg.body.read.size =3D size; + memexpose_ep_write_sync(&s->ep, &msg); + + MemTxResult res =3D msg.body.read_ret.ret; + if (res =3D=3D MEMTX_OK) { + memshare_handle(s, &msg.body.read_ret.share); + } + memcpy(data, &msg.body.read_ret.value, size); + return res; +} + +static MemTxResult memexpose_write_slow(void *opaque, hwaddr addr, + uint64_t val, unsigned size, + MemTxAttrs attrs) +{ + MemexposeMem *s =3D opaque; + struct memexpose_op msg; + msg.head.size =3D sizeof(msg.head) + sizeof(msg.body.write); + msg.head.ot =3D MOP_WRITE; + msg.head.prio =3D memexpose_ep_msg_prio(&s->ep, msg.head.ot); + msg.body.write.offset =3D addr; + msg.body.write.size =3D size; + msg.body.write.value =3D val; + memexpose_ep_write_sync(&s->ep, &msg); + + MemTxResult res =3D msg.body.write_ret.ret; + if (res =3D=3D MEMTX_OK) { + memshare_handle(s, &msg.body.write_ret.share); + } + return res; +} + +static const MemoryRegionOps memexpose_region_ops =3D { + .read_with_attrs =3D memexpose_read_slow, + .write_with_attrs =3D memexpose_write_slow, + .endianness =3D DEVICE_NATIVE_ENDIAN, + .impl =3D { + .min_access_size =3D 1, + .max_access_size =3D 8, + }, +}; + +static void prepare_memshare(MemexposeMem *s, + uint64_t size, uint64_t offset, + struct memexpose_memshare_info *info) { + MemoryRegionSection section =3D memory_region_find_flat_range( + s->as.root, offset, size); + if (!section.mr) { + MEMEXPOSE_DPRINTF("No memory region under %lu!\n", offset); + goto unref; + } + + int fd =3D memory_region_get_fd(section.mr); + if (fd !=3D -1 && qemu_ram_is_shared(section.mr->ram_block)) { + info->type =3D MEMSHARE_FD; + info->fd.mmap_start =3D section.offset_within_region; + info->fd.start =3D section.offset_within_address_space; + info->fd.size =3D section.size; + info->fd.readonly =3D memory_region_is_rom(section.mr); + info->fd.nonvolatile =3D memory_region_is_nonvolatile(section.mr); + + MEMEXPOSE_DPRINTF("Prepared a memshare fd: %" PRIx64 \ + "-%" PRIx64 ", fd offset %" PRIx64 "\n", + info->fd.start, info->fd.size, info->fd.mmap_sta= rt); + memexpose_ep_send_fd(&s->ep, fd); + s->nothing_shared =3D false; + } else { + info->type =3D MEMSHARE_NONE; + } +unref: + memory_region_unref(section.mr); +} + +static void memexpose_perform_read_request( + MemexposeMem *s, struct memexpose_op_read *in, + struct memexpose_op *out) +{ + out->head.ot =3D MOP_READ_RET; + out->head.size =3D sizeof(out->head) + sizeof(out->body.read_ret); + out->body.read_ret.ret =3D 0; + out->body.read_ret.share.type =3D MEMSHARE_NONE; + + MEMEXPOSE_DPRINTF("Reading %u from %lx\n", in->size, in->offset); + MemTxResult r =3D address_space_read(&s->as, in->offset, + MEMTXATTRS_UNSPECIFIED, + (uint8_t *) &out->body.read_ret.val= ue, + in->size); + out->body.read_ret.ret =3D r; + if (r !=3D MEMTX_OK) { + MEMEXPOSE_DPRINTF("Failed to read\n"); + } else { + prepare_memshare(s, in->size, in->offset, &out->body.read_ret.shar= e); + } +} + +static void memexpose_perform_write_request( + MemexposeMem *s, struct memexpose_op_write *in, + struct memexpose_op *out) +{ + out->head.ot =3D MOP_WRITE_RET; + out->head.size =3D sizeof(out->head) + sizeof(out->body.write_ret); + out->body.write_ret.ret =3D 0; + out->body.write_ret.share.type =3D MEMSHARE_NONE; + + MEMEXPOSE_DPRINTF("Writing %u to %lx\n", in->size, in->offset); + MemTxResult r =3D address_space_write(&s->as, in->offset, + MEMTXATTRS_UNSPECIFIED, + (uint8_t *) &in->value, + in->size); + if (r !=3D MEMTX_OK) { + out->body.write_ret.ret =3D -EIO; + MEMEXPOSE_DPRINTF("Failed to write\n"); + return; + } + + out->body.write_ret.ret =3D r; + if (r !=3D MEMTX_OK) { + MEMEXPOSE_DPRINTF("Failed to read\n"); + } else { + prepare_memshare(s, in->size, in->offset, &out->body.write_ret.sha= re); + } +} + +static bool region_is_ours(MemexposeMem *s, MemoryRegion *mr) +{ + if (mr =3D=3D &s->shmem) { + return true; + } + + MemexposeRemoteMemory *mem; + QLIST_FOREACH(mem, &s->remote_regions, list) { + if (mr =3D=3D &mem->region) { + return true; + } + } + return false; +} + +static void memexpose_remote_invalidate(MemoryListener *inv, + MemoryRegionSection *sect) +{ + MemexposeMem *s =3D container_of(inv, MemexposeMem, remote_invalidator= ); + struct memexpose_op msg; + struct memexpose_op_reg_inv *ri =3D &msg.body.reg_inv; + + if (!sect->mr || region_is_ours(s, sect->mr)) { + return; + } + if (s->nothing_shared) { + return; + } + + msg.head.size =3D sizeof(msg.head) + sizeof(msg.body.reg_inv); + msg.head.ot =3D MOP_REG_INV; + msg.head.prio =3D memexpose_ep_msg_prio(&s->ep, msg.head.ot); + + ri->start =3D sect->offset_within_address_space; + ri->size =3D int128_get64(sect->size); + MEMEXPOSE_DPRINTF("Region %"PRIx64"-%"PRIx64" changed, " + "sending invalidation request\n", + ri->start, ri->start + ri->size); + memexpose_ep_write_sync(&s->ep, &msg); +} + +static void memexpose_invalidate_region(MemexposeMem *s, + struct memexpose_op_reg_inv *ri, + struct memexpose_op *out) +{ + MemexposeRemoteMemory *mem; + + QLIST_FOREACH(mem, &s->remote_regions, list) { + uint64_t start =3D memory_region_get_ram_addr(&mem->region); + uint64_t size =3D memory_region_size(&mem->region); + if (start < ri->start + ri->size || + start + size > ri->start) { + mem->should_invalidate =3D true; + s->pending_invalidation =3D true; + } + } + + if (s->pending_invalidation) { + qemu_bh_schedule(s->reg_inv_bh); + } + + out->head.ot =3D MOP_REG_INV_RET; + out->head.size =3D sizeof(out->head); +} + +static void memexpose_do_reg_inv_bh(void *opaque) +{ + MemexposeMem *s =3D opaque; + + MemexposeRemoteMemory *mem, *tmp; + QLIST_FOREACH_SAFE(mem, &s->remote_regions, list, tmp) { + if (mem->should_invalidate) { + memshare_remove_region(s, mem); + } + } + s->pending_invalidation =3D false; +} + +static void process_mem(void *opaque, struct memexpose_op *op, Error **err) +{ + MemexposeMem *s =3D opaque; + struct memexpose_op resp; + resp.head.prio =3D op->head.prio; + switch (op->head.ot) { + case MOP_READ: + memexpose_perform_read_request(s, &op->body.read, &resp); + break; + case MOP_WRITE: + memexpose_perform_write_request(s, &op->body.write, &resp); + break; + case MOP_REG_INV: + memexpose_invalidate_region(s, &op->body.reg_inv, &resp); + break; + default: + error_setg(err, "Unknown memexpose command %u", op->head.ot); + return; + } + memexpose_ep_write_async(&s->ep, &resp); +} + +void memexpose_mem_init(MemexposeMem *s, Object *parent, + MemoryRegion *as_root, + CharBackend *chr, int prio, Error **errp) +{ + if (!qemu_chr_fe_backend_connected(chr)) { + error_setg(errp, "You must specify a 'mem_chardev'"); + return; + } + + QLIST_INIT(&s->remote_regions); + s->parent =3D parent; + address_space_init(&s->as, as_root, "Memexpose"); + + memexpose_ep_init(&s->ep, chr, s, prio, process_mem); + s->ep.is_async =3D false; + memory_region_init_io(&s->shmem, parent, &memexpose_region_ops, s, + "memexpose-shmem", s->shmem_size); + MEMEXPOSE_DPRINTF("Shmem size %lx\n", memory_region_size(&s->shmem)); + + s->nothing_shared =3D true; + s->remote_invalidator =3D (MemoryListener) { + .region_add =3D memexpose_remote_invalidate, + .region_del =3D memexpose_remote_invalidate, + }; + s->reg_inv_bh =3D qemu_bh_new(memexpose_do_reg_inv_bh, s); + memory_listener_register(&s->remote_invalidator, &s->as); +} + +int memexpose_mem_enable(MemexposeMem *s) +{ + return memexpose_ep_connect(&s->ep); +} + +void memexpose_mem_disable(MemexposeMem *s) +{ + memexpose_ep_disconnect(&s->ep); + + MemexposeRemoteMemory *mem, *tmp; + QLIST_FOREACH_SAFE(mem, &s->remote_regions, list, tmp) { + memshare_remove_region(s, mem); + } + qemu_bh_cancel(s->reg_inv_bh); + s->pending_invalidation =3D false; +} + +void memexpose_mem_destroy(MemexposeMem *s) +{ + memexpose_mem_disable(s); + /* Region will be collected with its parent */ + memory_listener_unregister(&s->remote_invalidator); + memexpose_ep_destroy(&s->ep); + qemu_bh_delete(s->reg_inv_bh); + address_space_destroy(&s->as); +} diff --git a/hw/misc/memexpose/memexpose-core.h b/hw/misc/memexpose/memexpo= se-core.h new file mode 100644 index 0000000..fd0ac60 --- /dev/null +++ b/hw/misc/memexpose/memexpose-core.h @@ -0,0 +1,109 @@ +/* + * Memexpose core + * + * Copyright (C) 2020 Samsung Electronics Co Ltd. + * Igor Kotrasinski, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + */ + +#ifndef _MEMEXPOSE_CORE_H_ +#define _MEMEXPOSE_CORE_H_ +#include "qemu/osdep.h" + +#include +#include "chardev/char-fe.h" +#include "hw/hw.h" +#include "exec/memory.h" +#include "memexpose-msg.h" + +#define MEMEXPOSE_INTR_QUEUE_SIZE 16 + +#define MEMEXPOSE_DEBUG 1 +#define MEMEXPOSE_DPRINTF(fmt, ...) \ + do { \ + if (MEMEXPOSE_DEBUG) { \ + printf("MEMEXPOSE: " fmt, ## __VA_ARGS__); \ + } \ + } while (0) + +#define MEMEXPOSE_INTR_MEM_SIZE 0x1000 + + +#define MEMEXPOSE_INTR_ENABLE_ADDR 0x0 +#define MEMEXPOSE_INTR_RECV_ADDR 0x400 +#define MEMEXPOSE_INTR_RX_TYPE_ADDR 0x408 +#define MEMEXPOSE_INTR_RX_DATA_ADDR 0x410 +#define MEMEXPOSE_INTR_SEND_ADDR 0x800 +#define MEMEXPOSE_INTR_TX_TYPE_ADDR 0x808 +#define MEMEXPOSE_INTR_TX_DATA_ADDR 0x810 + +struct memexpose_intr_ops { + void *parent; + void (*intr) (void *opaque, int dir); + int (*enable) (void *opaque); + void (*disable) (void *opaque); +}; + +typedef struct MemexposeIntr { + Object *parent; + struct memexpose_intr_ops ops; + int enabled; + + MemexposeEp ep; + MemoryRegion shmem; + + struct memexpose_op_intr intr_queue[MEMEXPOSE_INTR_QUEUE_SIZE]; + int queue_start; + int queue_count; + struct memexpose_op_intr intr_tx; + struct memexpose_op_intr intr_rx; +} MemexposeIntr; + +typedef struct MemexposeMem { + Object *parent; + MemexposeEp ep; + + AddressSpace as; + MemoryRegion shmem; + uint64_t shmem_size; + QLIST_HEAD(, MemexposeRemoteMemory) remote_regions; + + MemoryListener remote_invalidator; + QEMUBH *reg_inv_bh; + bool pending_invalidation; + bool nothing_shared; +} MemexposeMem; + +typedef struct MemexposeRemoteMemory { + MemoryRegion region; + bool should_invalidate; + QLIST_ENTRY(MemexposeRemoteMemory) list; +} MemexposeRemoteMemory; + +void memexpose_intr_init(MemexposeIntr *s, struct memexpose_intr_ops *ops, + Object *parent, CharBackend *chr, Error **errp); +void memexpose_intr_destroy(MemexposeIntr *s); +int memexpose_intr_enable(MemexposeIntr *s); +void memexpose_intr_disable(MemexposeIntr *s); + +void memexpose_mem_init(MemexposeMem *s, Object *parent, + MemoryRegion *as_root, + CharBackend *chr, int prio, Error **errp); +void memexpose_mem_destroy(MemexposeMem *s); +int memexpose_mem_enable(MemexposeMem *s); +void memexpose_mem_disable(MemexposeMem *s); + +#endif /* _MEMEXPOSE_CORE_H_ */ diff --git a/hw/misc/memexpose/memexpose-msg.c b/hw/misc/memexpose/memexpos= e-msg.c new file mode 100644 index 0000000..7205dd0 --- /dev/null +++ b/hw/misc/memexpose/memexpose-msg.c @@ -0,0 +1,261 @@ +/* + * Memexpose core + * + * Copyright (C) 2020 Samsung Electronics Co Ltd. + * Igor Kotrasinski, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "memexpose-msg.h" +#include "memexpose-core.h" + +#define MIN_MSG_SIZE (sizeof(struct memexpose_op_head)) +#define MAX_MSG_SIZE (sizeof(struct memexpose_op)) + +int memexpose_ep_msg_prio(MemexposeEp *ep, enum memexpose_op_type ot) +{ + int ot_prio; + switch (ot) { + case MOP_READ: + case MOP_READ_RET: + case MOP_WRITE: + case MOP_WRITE_RET: + ot_prio =3D 2; + break; + default: + ot_prio =3D 0; + } + return ot_prio + ep->prio; +} + +static int mep_can_receive(void *opaque) +{ + int sz; + MemexposeEp *ep =3D opaque; + MemexposeMsg *msg =3D &ep->msg; + + switch (msg->read_state) { + case MEMEXPOSE_MSG_BROKEN: + return 0; + case MEMEXPOSE_MSG_READ_SIZE: + return sizeof(msg->buf.head.size) - msg->bytes; + case MEMEXPOSE_MSG_READ_BODY: + sz =3D msg->buf.head.size - msg->bytes; + if (sz > MAX_MSG_SIZE) { + return MAX_MSG_SIZE; /* We'll handle this as an error later */ + } + return sz; + default: + MEMEXPOSE_DPRINTF("Invalid read state %d\n", msg->read_state); + return 0; + } +} + +static int mep_do_receive(MemexposeMsg *msg, + const uint8_t *buf, int size) +{ + switch (msg->read_state) { + case MEMEXPOSE_MSG_BROKEN: + return -1; + case MEMEXPOSE_MSG_READ_SIZE: + memcpy((unsigned char *)&msg->buf + msg->bytes, buf, size); + msg->bytes +=3D size; + if (msg->bytes =3D=3D sizeof(msg->buf.head.size)) { + msg->read_state =3D MEMEXPOSE_MSG_READ_BODY; + } + return 0; + case MEMEXPOSE_MSG_READ_BODY: + if (msg->buf.head.size < MIN_MSG_SIZE || + msg->buf.head.size > MAX_MSG_SIZE) { + MEMEXPOSE_DPRINTF("Invalid message size %d, protocol broken!\n= ", + msg->buf.head.size); + msg->read_state =3D MEMEXPOSE_MSG_BROKEN; + return -1; + } + memcpy((unsigned char *)&msg->buf + msg->bytes, buf, size); + msg->bytes +=3D size; + if (msg->bytes < msg->buf.head.size) { + return 0; + } + msg->bytes =3D 0; + msg->read_state =3D MEMEXPOSE_MSG_READ_SIZE; + return 1; + default: + MEMEXPOSE_DPRINTF("Invalid read state %d\n", msg->read_state); + return -1; + } +} + +static void mep_receive(void *opaque, const uint8_t *buf, int size) +{ + MemexposeEp *ep =3D opaque; + Error *err =3D NULL; + int new_msg =3D mep_do_receive(&ep->msg, buf, size); + if (new_msg) { + ep->handle_msg(ep->data, &ep->msg.buf, &err); + if (err) { + error_report_err(err); + } + } else if (new_msg < 0) { + error_setg(&err, "Failed to receive memexpose message"); /* FIXME = */ + error_report_err(err); + } +} + +static int mep_receive_sync(MemexposeEp *ep, struct memexpose_op *op) +{ + int ret =3D 0; + MemexposeMsg *msg =3D &ep->msg; + assert(!ep->is_async); + + while (!ret) { + int can_receive =3D mep_can_receive(ep); + unsigned char *msgbuf =3D (unsigned char *)&msg->buf + msg->bytes; + qemu_chr_fe_read_all(ep->chr, msgbuf, can_receive); + ret =3D mep_do_receive(msg, msgbuf, can_receive); + if (ret =3D=3D -1) { + return -1; + } + } + *op =3D msg->buf; + return 0; +} + +void memexpose_ep_write_async(MemexposeEp *ep, struct memexpose_op *op) +{ + qemu_chr_fe_write_all(ep->chr, (unsigned char *) op, op->head.size); +} + +static void mep_queue_msg(MemexposeEp *ep, struct memexpose_op *op) +{ + ep->queued_op =3D *op; + qemu_bh_schedule(ep->queue_msg_bh); +} + +static void mep_queue_msg_bh(void *epp) +{ + Error *err =3D NULL; + MemexposeEp *ep =3D epp; + if (!ep->queued_op.head.size) { + return; + } + ep->handle_msg(ep->data, &ep->queued_op, &err); /* FIXME - handle */ + ep->queued_op.head.size =3D 0; +} + +/* + * Synchronously write a message to another QEMU and receive a response. + * To avoid deadlocks, each message type has its priority and no more than= one + * message of each priority is in flight. + * + * After we send a message, we await a response while handling all message= s of + * higher priority and deferring messages of lower priority. This way each= side + * will have its requests handled until they have time to handle ours. + * + * The above means that a handler for a message must be able to run while = an + * operation that sends any other lower priority message is in progress. M= ake + * sure to order operations in an order that does not upset QEMU! + */ +void memexpose_ep_write_sync(MemexposeEp *ep, struct memexpose_op *op) +{ + assert(!ep->is_async); + qemu_chr_fe_write_all(ep->chr, (unsigned char *) op, op->head.size); + + struct memexpose_op resp; + int prio =3D op->head.prio; + + /* FIXME - handle errors */ + while (true) { + Error *err =3D NULL; + mep_receive_sync(ep, &resp); + int resp_prio =3D resp.head.prio; + if (resp_prio > prio) { + ep->handle_msg(ep->data, &resp, &err); + } else if (resp_prio < prio) { + mep_queue_msg(ep, &resp); + } else { + *op =3D resp; + return; + } + } +} + +void memexpose_ep_init(MemexposeEp *ep, CharBackend *chr, void *data, int = prio, + void (*handle_msg)(void *data, struct memexpose_op = *op, + Error **errp)) +{ + ep->queue_msg_bh =3D qemu_bh_new(mep_queue_msg_bh, ep); + ep->queued_op.head.size =3D 0; + ep->handle_msg =3D handle_msg; + ep->msg.bytes =3D 0; + ep->msg.read_state =3D MEMEXPOSE_MSG_READ_SIZE; + ep->chr =3D chr; + ep->data =3D data; + ep->prio =3D prio; + ep->connected =3D 0; + + if (handle_msg) + qemu_chr_fe_set_handlers(ep->chr, mep_can_receive, + mep_receive, NULL, NULL, ep, NULL, true); + Chardev *chrd =3D qemu_chr_fe_get_driver(ep->chr); + assert(chrd); + MEMEXPOSE_DPRINTF("Memexpose endpoint at %s\n", + chrd->filename); + +} + +/* TODO - protocol for synchronously ending connection */ +void memexpose_ep_destroy(MemexposeEp *ep) +{ + qemu_chr_fe_set_handlers(ep->chr, NULL, NULL, NULL, NULL, NULL, NULL, = true); +} + +void memexpose_ep_send_fd(MemexposeEp *ep, int fd) +{ + qemu_chr_fe_set_msgfds(ep->chr, &fd, 1); +} + +int memexpose_ep_recv_fd(MemexposeEp *ep) +{ + return qemu_chr_fe_get_msgfd(ep->chr); +} + +int memexpose_ep_connect(MemexposeEp *ep) +{ + /* FIXME - report errors */ + Error *err =3D NULL; + if (ep->connected) { + return 0; + } + + int ret =3D qemu_chr_fe_wait_connected(ep->chr, &err); + if (ret) { + return ret; + } + + ep->connected =3D 1; + return 0; +} + +void memexpose_ep_disconnect(MemexposeEp *ep) +{ + if (ep->connected) { + qemu_chr_fe_disconnect(ep->chr); + } + ep->connected =3D 0; +} diff --git a/hw/misc/memexpose/memexpose-msg.h b/hw/misc/memexpose/memexpos= e-msg.h new file mode 100644 index 0000000..5543cd4 --- /dev/null +++ b/hw/misc/memexpose/memexpose-msg.h @@ -0,0 +1,161 @@ +/* + * Memexpose core + * + * Copyright (C) 2020 Samsung Electronics Co Ltd. + * Igor Kotrasinski, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + */ + +#ifndef _MEMEXPOSE_MSG_H_ +#define _MEMEXPOSE_MSG_H_ + +#include "qemu/osdep.h" +#include "qemu/typedefs.h" +#include "chardev/char-fe.h" +#include "exec/memattrs.h" +#include + +#define MEMEXPOSE_MAX_INTR_DATA_SIZE 128 + +enum memexpose_op_type { + MOP_READ, + MOP_READ_RET, + MOP_WRITE, + MOP_WRITE_RET, + MOP_REG_INV, + MOP_REG_INV_RET, + MOP_INTR, +}; + +enum memexpose_memshare_type { + MEMSHARE_NONE, + MEMSHARE_FD, +}; + +/* + * TODO - we'll need to share more info here, like access permissions for + * example + */ +struct memexpose_memshare_info_fd { + uint64_t start; + uint64_t mmap_start; + uint64_t size; + uint8_t readonly; + uint8_t nonvolatile; +} __attribute__((packed)); + +/* TODO - this might have variable size in the future */ +struct memexpose_memshare_info { + uint8_t type; + union { + struct memexpose_memshare_info_fd fd; + }; +} __attribute__((packed)); + +/* TODO - endianness */ +struct memexpose_op_head { + uint32_t size; + uint8_t ot; + uint8_t prio; +} __attribute__((packed)); + +struct memexpose_op_read { + uint64_t offset; + uint8_t size; +} __attribute__((packed)); + +struct memexpose_op_write { + uint64_t offset; + uint64_t value; + uint8_t size; +} __attribute__((packed)); + +struct memexpose_op_read_ret { + MemTxResult ret; + uint64_t value; + struct memexpose_memshare_info share; +} __attribute__((packed)); + +struct memexpose_op_write_ret { + MemTxResult ret; + struct memexpose_memshare_info share; +} __attribute__((packed)); + +struct memexpose_op_intr { + uint64_t type; + uint8_t data[MEMEXPOSE_MAX_INTR_DATA_SIZE]; +} __attribute__((packed)); + +struct memexpose_op_reg_inv { + uint64_t start; + uint64_t size; +} __attribute__((packed)); + +union memexpose_op_all { + struct memexpose_op_read read; + struct memexpose_op_write write; + struct memexpose_op_read_ret read_ret; + struct memexpose_op_write_ret write_ret; + struct memexpose_op_intr intr; + struct memexpose_op_reg_inv reg_inv; +} __attribute__((packed)); + +struct memexpose_op { + struct memexpose_op_head head; + union memexpose_op_all body; +} __attribute__((packed)); + +enum MemexposeMsgState { + MEMEXPOSE_MSG_READ_SIZE, + MEMEXPOSE_MSG_READ_BODY, + MEMEXPOSE_MSG_BROKEN, +}; + +typedef struct MemexposeMsg { + int read_state; + int bytes; + struct memexpose_op buf; +} MemexposeMsg; + +typedef struct MemexposeEp { + CharBackend *chr; + MemexposeMsg msg; + bool is_async; + int prio; + void *data; + void (*handle_msg)(void *data, struct memexpose_op *op, Error **err); + + int connected; + struct memexpose_op queued_op; + QEMUBH *queue_msg_bh; +} MemexposeEp; + +void memexpose_ep_init(MemexposeEp *ep, CharBackend *chr, void *data, int = prio, + void (*handle_msg)(void *data, struct memexpose_op = *op, + Error **errp)); +void memexpose_ep_destroy(MemexposeEp *ep); + +int memexpose_ep_connect(MemexposeEp *ep); +void memexpose_ep_disconnect(MemexposeEp *ep); + +/* TODO - functions for header boilerplate */ +void memexpose_ep_write_sync(MemexposeEp *ep, struct memexpose_op *op); +void memexpose_ep_write_async(MemexposeEp *ep, struct memexpose_op *op); +void memexpose_ep_send_fd(MemexposeEp *ep, int fd); +int memexpose_ep_recv_fd(MemexposeEp *ep); +int memexpose_ep_msg_prio(MemexposeEp *ep, enum memexpose_op_type); + +#endif /* _MEMEXPOSE_MSG_H_ */ --=20 2.7.4 From nobody Thu May 16 23:18:59 2024 Delivered-To: importer@patchew.org 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; Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=partner.samsung.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1580816149795376.83873642091623; Tue, 4 Feb 2020 03:35:49 -0800 (PST) Received: from localhost ([::1]:56744 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywUe-000731-Lf for importer@patchew.org; Tue, 04 Feb 2020 06:35:48 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53816) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywQH-0008KV-MG for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iywQB-00009F-GC for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:17 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:47571) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iywQA-0008VO-U5 for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:11 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20200204113109euoutp016936a7db4a5bc2d21a477dad0f72171c~wL6hgO4Gr1812218122euoutp01j for ; Tue, 4 Feb 2020 11:31:09 +0000 (GMT) Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20200204113109eucas1p206aae13a98a7c93fbefc9e02f6031c50~wL6hQvjxk0478504785eucas1p2Q; Tue, 4 Feb 2020 11:31:09 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id E6.3C.60679.DF5593E5; Tue, 4 Feb 2020 11:31:09 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200204113108eucas1p2526a9481bf8a4420d359c45f1183fe95~wL6g94hv12920129201eucas1p2p; Tue, 4 Feb 2020 11:31:08 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200204113108eusmtrp15ff8dc3372f0f9c4d90b3ff21b631956~wL6g9ZYjl2102721027eusmtrp17; Tue, 4 Feb 2020 11:31:08 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 98.AC.08375.CF5593E5; Tue, 4 Feb 2020 11:31:08 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200204113108eusmtip2a9301871dc3fa53b01e7e438c424dc53~wL6gqt1px1661216612eusmtip2V; Tue, 4 Feb 2020 11:31:08 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20200204113109euoutp016936a7db4a5bc2d21a477dad0f72171c~wL6hgO4Gr1812218122euoutp01j DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580815869; bh=8krbNE+KSXi0wI3VPtXD9yxn+/jNrWuebMdcGarMJl8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=aF4ipcngtPg1/lrXY88LlRA3FU4ruEik91qjCwEJoT0y+aro9j6ftQi5eXMsmswhH g5unuan2vHLOMzM6QSco8bWdCNTTWO9ht2VEx57QrpV+bZy03MrUpJtA+yixocvy8z Glxc01LC9S6HqBcclh/qfuzfwave6eHnjwTkyRHA= X-AuditID: cbfec7f4-0e5ff7000001ed07-e0-5e3955fd4e44 From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC 6/9] hw/misc/memexpose: Add memexpose pci device Date: Tue, 4 Feb 2020 12:30:48 +0100 Message-Id: <1580815851-28887-7-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrKIsWRmVeSWpSXmKPExsWy7djPc7p/Qy3jDK6dYbbYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlfNvx jr3gpXVFV7tcA+NRvS5GTg4JAROJY1s3sIHYQgIrGCW+rBWHsL8wSiw/z97FyAVkf2aUONFy iA2m4WjHTFaIxHJGiWfdy9kgHKCOd1N3sYJUsQmoSew88pkRxBYRkJT43XWaGcRmFsiQeD6r G8wWFrCT+LHgGzuIzSKgKnHt4T0WEJtXIEDiwqcfzBDb5CRunusEszkFAiXe75nEBBG/zCZx tdUHwnaRmND6Eeo6YYlXx7ewQ9gyEqcn97BA2PUSLXd2MIEcKiHQwSjRt3I6VIO1xJcNS4GK OICO05RYv0sfIuwoMWdCCxNIWEKAT+LGW0GI8/kkJm2bzgwR5pXoaBOCqNaT6H5ykwlm67LG R1BbPSTeTZ/BAgmeJYwSN75uYZnAKD8LYdkCRsZVjOKppcW56anFRnmp5XrFibnFpXnpesn5 uZsYgZF/+t/xLzsYd/1JOsQowMGoxMN78qxFnBBrYllxZe4hRgkOZiUR3vP6lnFCvCmJlVWp RfnxRaU5qcWHGKU5WJTEeY0XvYwVEkhPLEnNTk0tSC2CyTJxcEo1MParCMq+/Lk+fCMnN6f0 +1cqSYVL7C7ueb7h8Jxa1V8fnvMJTi/aPbVTZarPu4/72y4K5Jby/QhgbXPYZzzt9BaV3MmM ekHVzje3T/np+/Nd0To907QEbV+Bh8sPWSS8iM8KXqZQxqYRtlJoV4VLb0NKiMO1nQmK+8yE rk3p2l1yQkVfIqLuixJLcUaioRZzUXEiAP5ZBFj4AgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrJLMWRmVeSWpSXmKPExsVy+t/xe7p/Qi3jDJ7uNLTYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlfNvxjr3gpXVFV7tcA+NRvS5GTg4J AROJox0zWbsYuTiEBJYyShxavoMJIiEj8eP0GjYIW1jiz7UuNoiiT4wSc68eZQdJsAmoSew8 8pkRxBYRkJT43XWaGcRmFsiS2Dn7PtggYQE7iR8LvoHVswioSlx7eI8FxOYVCJC48OkHM8QC OYmb5zrBbE6BQIn3eyaB9QqB1OyaxT6BkW8BI8MqRpHU0uLc9NxiQ73ixNzi0rx0veT83E2M wGDcduzn5h2MlzYGH2IU4GBU4uG9YGcRJ8SaWFZcmXuIUYKDWUmE97y+ZZwQb0piZVVqUX58 UWlOavEhRlOgoyYyS4km5wMjJa8k3tDU0NzC0tDc2NzYzEJJnLdD4GCMkEB6YklqdmpqQWoR TB8TB6dUA6P/8Ucmv/cZC2yX6dx3p/+7T3jnXfswnQmhWjm9sS9cZl1cvTd5zg1ennmm3y/Z tTAUfM493BF9sMB08cSaqvPu2q9cjh5fcWfmNPOg1Se4hISYYpsT+Nt1zhzaaN49taWT61LK dKEt1tUPOSNmbjrS4vU3wszCR0e544zzxx/ler+CF7VsPqLEUpyRaKjFXFScCADpbVaxXAIA AA== X-CMS-MailID: 20200204113108eucas1p2526a9481bf8a4420d359c45f1183fe95 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200204113108eucas1p2526a9481bf8a4420d359c45f1183fe95 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200204113108eucas1p2526a9481bf8a4420d359c45f1183fe95 References: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 210.118.77.11 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Igor Kotrasinski , pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Igor Kotrasinski Signed-off-by: Igor Kotrasinski --- MAINTAINERS | 1 + hw/misc/memexpose/Makefile.objs | 1 + hw/misc/memexpose/memexpose-pci.c | 218 ++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 220 insertions(+) create mode 100644 hw/misc/memexpose/memexpose-pci.c diff --git a/MAINTAINERS b/MAINTAINERS index d6146c0..50628e4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1646,6 +1646,7 @@ F: hw/misc/memexpose/memexpose-core.h F: hw/misc/memexpose/memexpose-core.c F: hw/misc/memexpose/memexpose-msg.h F: hw/misc/memexpose/memexpose-msg.c +F: hw/misc/memexpose/memexpose-pci.c =20 nvme M: Keith Busch diff --git a/hw/misc/memexpose/Makefile.objs b/hw/misc/memexpose/Makefile.o= bjs index f405fe7..05a2395 100644 --- a/hw/misc/memexpose/Makefile.objs +++ b/hw/misc/memexpose/Makefile.objs @@ -1,2 +1,3 @@ common-obj-y +=3D memexpose-msg.o common-obj-y +=3D memexpose-core.o +common-obj-$(CONFIG_PCI) +=3D memexpose-pci.o diff --git a/hw/misc/memexpose/memexpose-pci.c b/hw/misc/memexpose/memexpos= e-pci.c new file mode 100644 index 0000000..7372651 --- /dev/null +++ b/hw/misc/memexpose/memexpose-pci.c @@ -0,0 +1,218 @@ +/* + * Memexpose PCI device + * + * Copyright (C) 2020 Samsung Electronics Co Ltd. + * Igor Kotrasinski, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "qemu/units.h" +#include "qapi/error.h" +#include "qemu/cutils.h" +#include "hw/hw.h" +#include "hw/pci/pci.h" +#include "hw/pci/msi.h" +#include "hw/pci/msix.h" +#include "hw/qdev-properties.h" +#include "exec/memory.h" +#include "exec/address-spaces.h" +#include "memexpose-core.h" + +#define PCI_VENDOR_ID_MEMEXPOSE PCI_VENDOR_ID_REDHAT_QUMRANET +#define TYPE_MEMEXPOSE_PCI "memexpose-pci" +#define PCI_DEVICE_ID_MEMEXPOSE 0x1111 +#define MEMEXPOSE_PCI(obj) \ + OBJECT_CHECK(MemexposePCIState, (obj), TYPE_MEMEXPOSE_PCI) + +typedef struct MemexposePCIState { + PCIDevice parent_obj; + + CharBackend intr_chr; + CharBackend mem_chr; + + MemexposeIntr intr; + uint32_t intr_status; + MemexposeMem mem; +} MemexposePCIState; + +static void raise_irq(MemexposePCIState *s) +{ + s->intr_status |=3D 1; + if (msi_enabled(&s->parent_obj)) { + msi_notify(&s->parent_obj, 0); + } else { + pci_set_irq(&s->parent_obj, 1); + } +} + +static void lower_irq(MemexposePCIState *s) +{ + s->intr_status &=3D (~1); + if (!s->intr_status && !msi_enabled(&s->parent_obj)) { + pci_set_irq(&s->parent_obj, 0); + } +} + +static void handle_irq(void *opaque, int dir) +{ + MemexposePCIState *s =3D opaque; + if (dir) { + raise_irq(s); + } else { + lower_irq(s); + } +} + +static int memexpose_enable(void *opaque) +{ + int ret; + MemexposePCIState *s =3D opaque; + + ret =3D memexpose_intr_enable(&s->intr); + if (ret) { + return ret; + } + + ret =3D memexpose_mem_enable(&s->mem); + if (ret) { + memexpose_intr_disable(&s->intr); + return ret; + } + + return 0; +} + +static void memexpose_disable(void *opaque) +{ + MemexposePCIState *s =3D opaque; + + memexpose_intr_disable(&s->intr); + memexpose_mem_disable(&s->mem); +} + +static void memexpose_pci_intr_init(PCIDevice *dev, Error **errp) +{ + MemexposePCIState *s =3D MEMEXPOSE_PCI(dev); + struct memexpose_intr_ops ops; + ops.intr =3D handle_irq; + ops.enable =3D memexpose_enable; + ops.disable =3D memexpose_disable; + ops.parent =3D s; + + memexpose_intr_init(&s->intr, &ops, OBJECT(dev), &s->intr_chr, errp); + if (*errp) { + return; + } + + s->intr_status =3D 0; + uint8_t *pci_conf; + pci_conf =3D dev->config; + pci_conf[PCI_COMMAND] =3D PCI_COMMAND_IO | PCI_COMMAND_MEMORY; + pci_config_set_interrupt_pin(pci_conf, 1); + if (msi_init(dev, 0, 1, true, false, errp)) { + error_setg(errp, "Failed to initialize memexpose PCI interrupts"); + memexpose_intr_destroy(&s->intr); + return; + } + + /* region for registers*/ + pci_register_bar(dev, 0, + PCI_BASE_ADDRESS_SPACE_MEMORY, + &s->intr.shmem); + MEMEXPOSE_DPRINTF("Initialized bar.\n"); +} + +static void memexpose_pci_intr_exit(PCIDevice *dev) +{ + MemexposePCIState *s =3D MEMEXPOSE_PCI(dev); + msi_uninit(dev); + memexpose_intr_destroy(&s->intr); +} + +static void memexpose_pci_realize(PCIDevice *dev, Error **errp) +{ + MemexposePCIState *s =3D MEMEXPOSE_PCI(dev); + memexpose_pci_intr_init(dev, errp); + if (*errp) { + return; + } + + Chardev *chrd =3D qemu_chr_fe_get_driver(&s->mem_chr); + assert(chrd); + MEMEXPOSE_DPRINTF("Memexpose endpoint at %s!\n", + chrd->filename); + memexpose_mem_init(&s->mem, OBJECT(dev), + get_system_memory(), + &s->mem_chr, 0, errp); + if (*errp) { + memexpose_pci_intr_exit(dev); + return; + } + + pci_register_bar(dev, 1, + PCI_BASE_ADDRESS_SPACE_MEMORY | + PCI_BASE_ADDRESS_MEM_TYPE_64, + &s->mem.shmem); + MEMEXPOSE_DPRINTF("Initialized second bar.\n"); +} + +static void memexpose_pci_exit(PCIDevice *dev) +{ + MemexposePCIState *s =3D MEMEXPOSE_PCI(dev); + memexpose_mem_destroy(&s->mem); + memexpose_pci_intr_exit(dev); +} + +static Property memexpose_pci_properties[] =3D { + DEFINE_PROP_CHR("mem_chardev", MemexposePCIState, mem_chr), + DEFINE_PROP_CHR("intr_chardev", MemexposePCIState, intr_chr), + DEFINE_PROP_UINT64("shm_size", MemexposePCIState, mem.shmem_size, 4096= ), + DEFINE_PROP_END_OF_LIST(), +}; + +static void memexpose_pci_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + PCIDeviceClass *k =3D PCI_DEVICE_CLASS(klass); + + k->realize =3D memexpose_pci_realize; + k->exit =3D memexpose_pci_exit; + k->vendor_id =3D PCI_VENDOR_ID_MEMEXPOSE; + k->device_id =3D PCI_DEVICE_ID_MEMEXPOSE; + k->class_id =3D PCI_CLASS_MEMORY_RAM; + k->revision =3D 1; + device_class_set_props(dc, memexpose_pci_properties); +} + +static const TypeInfo memexpose_pci_info =3D { + .name =3D TYPE_MEMEXPOSE_PCI, + .parent =3D TYPE_PCI_DEVICE, + .instance_size =3D sizeof(MemexposePCIState), + .class_init =3D memexpose_pci_class_init, + .interfaces =3D (InterfaceInfo[]) { + { INTERFACE_CONVENTIONAL_PCI_DEVICE }, + { }, + }, +}; + + +static void memexpose_pci_register_types(void) +{ + type_register_static(&memexpose_pci_info); +} + +type_init(memexpose_pci_register_types) --=20 2.7.4 From nobody Thu May 16 23:18:59 2024 Delivered-To: importer@patchew.org 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; Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=partner.samsung.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1580815954643623.654781240651; Tue, 4 Feb 2020 03:32:34 -0800 (PST) Received: from localhost ([::1]:56688 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywRV-0001Dr-GL for importer@patchew.org; Tue, 04 Feb 2020 06:32:33 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53784) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywQG-0008KA-0I for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:19 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iywQB-0000AA-Nq for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:15 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:51779) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iywQB-0008WF-Du for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:11 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200204113110euoutp0202991455384ff549a8866ce6ceef5cb4~wL6iaV5i93205332053euoutp02E for ; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) Received: from eusmges1new.samsung.com (unknown [203.254.199.242]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20200204113110eucas1p2c6e71cbf8619eba68d4dc5cb5010db54~wL6iMoqTH0683106831eucas1p29; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges1new.samsung.com (EUCPMTA) with SMTP id 4F.FE.61286.EF5593E5; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20200204113109eucas1p18527bb78c3d930d56e6ae9c205f64ba3~wL6hzdy9B0252702527eucas1p10; Tue, 4 Feb 2020 11:31:09 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200204113109eusmtrp1cbb2b2fdf04277c44eec670e4777b97a~wL6hy_UCD2134721347eusmtrp1W; Tue, 4 Feb 2020 11:31:09 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id AA.0A.07950.DF5593E5; Tue, 4 Feb 2020 11:31:09 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200204113109eusmtip20a5a255bb8b1cee1e2a4a810a2bb3455~wL6hcxiTr1203512035eusmtip29; Tue, 4 Feb 2020 11:31:09 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200204113110euoutp0202991455384ff549a8866ce6ceef5cb4~wL6iaV5i93205332053euoutp02E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580815870; bh=bRn11VpBM9t5t50jTYwBxqf13Abw0bNM2mE3Nrju/WU=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lv3cvY7006Vgj+xZYXg+PLBqYTIOUtKIPE1ELOKXnBZcm+3nEpOs57aQha0aDz5D7 mxA8thckjVa/I0gptYyBcRqe7w9uynk3Nfbz/9KzpMtpAwn356k8uk4MsEmIwXR8E4 m2JKGmaFq3Ma1vO7XDn/ERaYvfkuuynX3Knrq+RE= X-AuditID: cbfec7f2-f0bff7000001ef66-95-5e3955fe3de2 From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC 7/9] hw/misc/memexpose: Add memexpose memory region device Date: Tue, 4 Feb 2020 12:30:49 +0100 Message-Id: <1580815851-28887-8-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrJIsWRmVeSWpSXmKPExsWy7djP87r/Qi3jDCbOZbPYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBl/P94 hLVgtmXFnCNXmBoY2/W6GDk5JARMJH5dWMbUxcjFISSwglHi9N8TjBDOF0aJdVfusUI4nxkl Xuw7zQjTcu34XDaIxHJGiYsnzjPDtbQt/sYOUsUmoCax88hnsA4RAUmJ312nmUFsZoEMieez usFsYQEPiSP//rGA2CwCqhIP9t8H6+UVCJB4u2YrC8Q2OYmb5zrB6jkFAiXe75kEdqyEwGU2 iXOLz7JDFLlILH27nBnCFpZ4dXwLVFxG4vTkHqhB9RItd3ZANXcwSvStnM4GkbCW+LJhKVAR B9B1mhLrd+lDhB0lzjX8YwMJSwjwSdx4KwhxP5/EpG3TmSHCvBIdbUIQ1XoS3U9uMsFsXdb4 CGqrh8TU6yfZIeGzBBhYfTcYJzDKz0JYtoCRcRWjeGppcW56arFhXmq5XnFibnFpXrpecn7u JkZgAjj97/inHYxfLyUdYhTgYFTi4b1gZxEnxJpYVlyZe4hRgoNZSYT3vL5lnBBvSmJlVWpR fnxRaU5q8SFGaQ4WJXFe40UvY4UE0hNLUrNTUwtSi2CyTBycUg2MTdPVDiZVng1dxmGfefXw a8VHhw7ZCC3cW1TEaLhh1t2M9yLJ8lVh9+c+fh72dUK6zRcBJmm17zxHPBWLPuksTkretbZ4 u9Gf/5fl4iuYFV9N1/3z/0cE96+15lIN56MC7jzkOsOy1m2ZptjRd1PPh6y4LXmboy7VIvC8 6N8Dj7mUH3jIMDNeV2Ipzkg01GIuKk4EAFQfaSL8AgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRmVeSWpSXmKPExsVy+t/xe7p/Qy3jDF7+UbfYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehl/P94hLVgtmXFnCNXmBoY2/W6GDk5 JARMJK4dn8vWxcjFISSwlFGicfkMRoiEjMSP02vYIGxhiT/XuqCKPjFK9O2/ywqSYBNQk9h5 5DNYg4iApMTvrtPMIDazQJbEztn3mUBsYQEPiSP//rGA2CwCqhIP9t9nB7F5BQIk3q7ZygKx QE7i5rlOsF5OgUCJ93smgfUKAdVc2DWLfQIj3wJGhlWMIqmlxbnpucVGesWJucWleel6yfm5 mxiB4bjt2M8tOxi73gUfYhTgYFTi4dVwtIgTYk0sK67MPcQowcGsJMJ7Xt8yTog3JbGyKrUo P76oNCe1+BCjKdBRE5mlRJPzgbGSVxJvaGpobmFpaG5sbmxmoSTO2yFwMEZIID2xJDU7NbUg tQimj4mDU6qB0SO6+VyN/uWJ7r/KOU/N2F/FpezPxPSHUS/+f9nmCddXFr+z9VnX0bY6wvmV WjjXxEupCh7fNeflPWRdblndcWqZzIddGldmOLdmzvqk92RW90O769Jn4jgUGYxKs2czS+67 rGlX77/h0N7m8x3Zbvd2cL/Te6J3Y3XX38J5z59E2Z1elibLocRSnJFoqMVcVJwIACC6XuVd AgAA X-CMS-MailID: 20200204113109eucas1p18527bb78c3d930d56e6ae9c205f64ba3 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200204113109eucas1p18527bb78c3d930d56e6ae9c205f64ba3 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200204113109eucas1p18527bb78c3d930d56e6ae9c205f64ba3 References: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 210.118.77.12 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Igor Kotrasinski , pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Igor Kotrasinski Signed-off-by: Igor Kotrasinski --- MAINTAINERS | 2 + hw/misc/memexpose/Makefile.objs | 1 + hw/misc/memexpose/memexpose-memregion.c | 142 ++++++++++++++++++++++++++++= ++++ hw/misc/memexpose/memexpose-memregion.h | 41 +++++++++ 4 files changed, 186 insertions(+) create mode 100644 hw/misc/memexpose/memexpose-memregion.c create mode 100644 hw/misc/memexpose/memexpose-memregion.h diff --git a/MAINTAINERS b/MAINTAINERS index 50628e4..2142c07 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1647,6 +1647,8 @@ F: hw/misc/memexpose/memexpose-core.c F: hw/misc/memexpose/memexpose-msg.h F: hw/misc/memexpose/memexpose-msg.c F: hw/misc/memexpose/memexpose-pci.c +F: hw/misc/memexpose/memexpose-memregion.h +F: hw/misc/memexpose/memexpose-memregion.c =20 nvme M: Keith Busch diff --git a/hw/misc/memexpose/Makefile.objs b/hw/misc/memexpose/Makefile.o= bjs index 05a2395..056bff3 100644 --- a/hw/misc/memexpose/Makefile.objs +++ b/hw/misc/memexpose/Makefile.objs @@ -1,3 +1,4 @@ common-obj-y +=3D memexpose-msg.o common-obj-y +=3D memexpose-core.o common-obj-$(CONFIG_PCI) +=3D memexpose-pci.o +common-obj-y +=3D memexpose-memregion.o diff --git a/hw/misc/memexpose/memexpose-memregion.c b/hw/misc/memexpose/me= mexpose-memregion.c new file mode 100644 index 0000000..fbdd966 --- /dev/null +++ b/hw/misc/memexpose/memexpose-memregion.c @@ -0,0 +1,142 @@ +/* + * Memexpose ARM device + * + * Copyright (C) 2020 Samsung Electronics Co Ltd. + * Igor Kotrasinski, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + */ + +#include "qemu/osdep.h" +#include "hw/irq.h" +#include "hw/sysbus.h" +#include "hw/qdev-properties.h" +#include "exec/memory.h" +#include "exec/address-spaces.h" +#include "memexpose-core.h" +#include "memexpose-memregion.h" + +static void memexpose_memdev_intr(void *opaque, int dir) +{ + MemexposeMemdev *dev =3D opaque; + if (dir) { + qemu_set_irq(dev->irq, 1); + } else { + qemu_set_irq(dev->irq, 0); + } +} + +static int memexpose_memdev_enable(void *opaque) +{ + int ret; + MemexposeMemdev *s =3D opaque; + + ret =3D memexpose_intr_enable(&s->intr); + if (ret) { + return ret; + } + + ret =3D memexpose_mem_enable(&s->mem); + if (ret) { + memexpose_intr_disable(&s->intr); + return ret; + } + + return 0; +} + +static void memexpose_memdev_disable(void *opaque) +{ + MemexposeMemdev *s =3D opaque; + + memexpose_intr_disable(&s->intr); + memexpose_mem_disable(&s->mem); +} + +static void memexpose_memdev_init(Object *obj) +{ + SysBusDevice *sbd =3D SYS_BUS_DEVICE(obj); + MemexposeMemdev *mdev =3D MEMEXPOSE_MEMDEV(obj); + sysbus_init_mmio(sbd, &mdev->intr.shmem); + sysbus_init_irq(sbd, &mdev->irq); +} + +static void memexpose_memdev_finalize(Object *obj) +{ +} + +static void memexpose_memdev_realize(DeviceState *dev, Error **errp) +{ + MemexposeMemdev *mdev =3D MEMEXPOSE_MEMDEV(dev); + struct memexpose_intr_ops ops =3D { + .parent =3D dev, + .intr =3D memexpose_memdev_intr, + .enable =3D memexpose_memdev_enable, + .disable =3D memexpose_memdev_disable, + }; + + memexpose_intr_init(&mdev->intr, &ops, OBJECT(dev), &mdev->intr_chr, e= rrp); + if (*errp) { + return; + } + memexpose_mem_init(&mdev->mem, OBJECT(dev), + get_system_memory(), + &mdev->mem_chr, 1, errp); + if (*errp) { + goto free_intr; + } + return; + +free_intr: + memexpose_intr_destroy(&mdev->intr); +} + +static void memexpose_memdev_unrealize(DeviceState *dev, Error **errp) +{ + MemexposeMemdev *mdev =3D MEMEXPOSE_MEMDEV(dev); + memexpose_mem_destroy(&mdev->mem); + memexpose_intr_destroy(&mdev->intr); +} + +static Property memexpose_memdev_properties[] =3D { + DEFINE_PROP_CHR("intr_chardev", MemexposeMemdev, intr_chr), + DEFINE_PROP_CHR("mem_chardev", MemexposeMemdev, mem_chr), + DEFINE_PROP_UINT64("shm_size", MemexposeMemdev, mem.shmem_size, 4096), + DEFINE_PROP_END_OF_LIST(), +}; + +static void memexpose_memdev_class_init(ObjectClass *klass, void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + dc->realize =3D memexpose_memdev_realize; + dc->unrealize =3D memexpose_memdev_unrealize; + device_class_set_props(dc, memexpose_memdev_properties); +} + +static const TypeInfo memexpose_memdev_info =3D { + .name =3D TYPE_MEMEXPOSE_MEMDEV, + .parent =3D TYPE_SYS_BUS_DEVICE, + .instance_size =3D sizeof(MemexposeMemdev), + .instance_init =3D memexpose_memdev_init, + .instance_finalize =3D memexpose_memdev_finalize, + .class_init =3D memexpose_memdev_class_init, +}; + +static void register_types(void) +{ + type_register_static(&memexpose_memdev_info); +} + +type_init(register_types); diff --git a/hw/misc/memexpose/memexpose-memregion.h b/hw/misc/memexpose/me= mexpose-memregion.h new file mode 100644 index 0000000..7eddcbe --- /dev/null +++ b/hw/misc/memexpose/memexpose-memregion.h @@ -0,0 +1,41 @@ +/* + * Memexpose ARM device + * + * Copyright (C) 2020 Samsung Electronics Co Ltd. + * Igor Kotrasinski, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + */ + +#ifndef _MEMEXPOSE_MEMDEV_H_ +#define _MEMEXPOSE_MEMDEV_H_ + +#include "memexpose-core.h" +#include "hw/sysbus.h" + +#define TYPE_MEMEXPOSE_MEMDEV "memexpose-memdev" +#define MEMEXPOSE_MEMDEV(obj) \ + OBJECT_CHECK(MemexposeMemdev, (obj), TYPE_MEMEXPOSE_MEMDEV) + +typedef struct MemexposeMemdev { + SysBusDevice dev; + MemexposeIntr intr; + MemexposeMem mem; + CharBackend intr_chr; + CharBackend mem_chr; + qemu_irq irq; +} MemexposeMemdev; + +#endif /* _MEMEXPOSE_MEMDEV_H_ */ --=20 2.7.4 From nobody Thu May 16 23:18:59 2024 Delivered-To: importer@patchew.org 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; Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=partner.samsung.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1580816256436888.3622271555406; Tue, 4 Feb 2020 03:37:36 -0800 (PST) Received: from localhost ([::1]:56776 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywWN-0000ek-3Z for importer@patchew.org; Tue, 04 Feb 2020 06:37:35 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53813) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywQH-0008KT-MP for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iywQC-0000Dh-M7 for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:17 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:51786) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iywQC-00008T-0h for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:12 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200204113111euoutp029230faded0822d955196827631e723ab~wL6jCVKnH3205332053euoutp02F for ; Tue, 4 Feb 2020 11:31:11 +0000 (GMT) Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200204113110eucas1p1d070397e7469d97bbe8bee57d6b79b0a~wL6i1RKr32652426524eucas1p1a; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id 16.10.60698.EF5593E5; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200204113110eucas1p2f9ab3639730113139730d1853772d100~wL6ifqt0z0684606846eucas1p2G; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200204113110eusmtrp195b7659a7f76325945a4cb30c6b5e553~wL6ifKT3N2102721027eusmtrp1-; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id B9.AC.08375.EF5593E5; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200204113110eusmtip2a9dd98ee43404e462ba57526ef21ea9c~wL6iK_KWY1661216612eusmtip2W; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200204113111euoutp029230faded0822d955196827631e723ab~wL6jCVKnH3205332053euoutp02F DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580815871; bh=ejRMInsI0eAgVGBJdITPaeVcgEyvGRYngnK3dXvgDzk=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Bud90L7yRcJnxRAxKcYOpbtCFE/j+QN3qzbzc9M1JzArVrxqFB7z6EhD3c8PbAn5I lb5Ptj8SXkwn89YVTrL378O9G+lv2mvAfv6pOGYvanfDhPjZOKqr/OHwPBxNq8764I tXKMDcycfsoku221ybLWziqF86cNfKZPGOWil4Ak= X-AuditID: cbfec7f5-a0fff7000001ed1a-67-5e3955fe9775 From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC 8/9] hw/misc/memexpose: Add simple tests Date: Tue, 4 Feb 2020 12:30:50 +0100 Message-Id: <1580815851-28887-9-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOIsWRmVeSWpSXmKPExsWy7djPc7r/Qi3jDFZcMLDYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlrFpw jrWgO7Viwe23bA2Mc327GDk5JARMJF7uuMDUxcjFISSwglFi5qnVLBDOF0aJI3eXs0E4nxkl tr7vYYJpOd/eyQ5iCwksZ5TY08sI1zGv/zsbSIJNQE1i55HPjCC2iICkxO+u08wgNrNAhsTz Wd1gtrCAmcTHZR+Bajg4WARUJc7clwYJ8woESKxZcp8FYpecxM1znWDlnAKBEu/3TAI7VULg OpvEhiX/oA5ykXj54h0jhC0s8er4FnYIW0bi9OQeqEH1Ei13dkA1dzBK9K2czgaRsJb4smEp C8gRzAKaEut36UOEHSUWfv3ODhKWEOCTuPFWEOJ8PolJ26YzQ4R5JTrahCCq9SS6n9xkgtm6 rPER1FYPiYMPW6BhuIRR4u2UXpYJjPKzEJYtYGRcxSieWlqcm55abJyXWq5XnJhbXJqXrpec n7uJERj9p/8d/7qDcd+fpEOMAhyMSjy8Go4WcUKsiWXFlbmHGCU4mJVEeM/rW8YJ8aYkVlal FuXHF5XmpBYfYpTmYFES5zVe9DJWSCA9sSQ1OzW1ILUIJsvEwSnVwGjZv7CT7+xZ8+nH3nZf PX39a8VpZovpe0vm8v1tUDGo2ftheX75gqvMVzfbWT+sk7xYWndgK2N9X0KAy7f+1ie7T3Y9 jFs6T/iMQPPzG1b719xzqPnfbrzYVKoy6uqZD507L3tYMe385HktcLvphbh55pP520om9MRI Jm1782DDid1pm9YbhmxRYinOSDTUYi4qTgQAJEGnR/oCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrJLMWRmVeSWpSXmKPExsVy+t/xe7r/Qi3jDBZMlrLYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlrFpwjrWgO7Viwe23bA2Mc327GDk5 JARMJM63d7J3MXJxCAksZZS41N3OCpGQkfhxeg0bhC0s8edaFxtE0SdGiQWntzCCJNgE1CR2 HvkMZosISEr87jrNDGIzC2RJ7Jx9nwnEFhYwk/i47CNQDQcHi4CqxJn70iBhXoEAiTVL7rNA zJeTuHmuE6yVUyBQ4v2eSWCtQkA1F3bNYp/AyLeAkWEVo0hqaXFuem6xoV5xYm5xaV66XnJ+ 7iZGYDBuO/Zz8w7GSxuDDzEKcDAq8fBesLOIE2JNLCuuzD3EKMHBrCTCe17fMk6INyWxsiq1 KD++qDQntfgQoynQTROZpUST84GRklcSb2hqaG5haWhubG5sZqEkztshcDBGSCA9sSQ1OzW1 ILUIpo+Jg1OqgZFzqluUvOwFG5fDXccup52/4362dOPsBW+usy9+e3Zz+/YwJXurt/c+v7A0 rHxXqbvvpY7Juws3dshPtA1+pr53hbg956KdvUffMiTXy7uf4zsR8blgYsA0+TUnTB/q3pp5 atWXUI/2JREFtX4btytysxmKliX/6F+1Ke9/bAbfks1/FDSuLE5VYinOSDTUYi4qTgQAffb6 N1wCAAA= X-CMS-MailID: 20200204113110eucas1p2f9ab3639730113139730d1853772d100 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200204113110eucas1p2f9ab3639730113139730d1853772d100 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200204113110eucas1p2f9ab3639730113139730d1853772d100 References: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 210.118.77.12 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Igor Kotrasinski , pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Igor Kotrasinski Signed-off-by: Igor Kotrasinski --- MAINTAINERS | 1 + tests/qtest/Makefile.include | 2 + tests/qtest/memexpose-test.c | 364 +++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 367 insertions(+) create mode 100644 tests/qtest/memexpose-test.c diff --git a/MAINTAINERS b/MAINTAINERS index 2142c07..55bc6ab 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1649,6 +1649,7 @@ F: hw/misc/memexpose/memexpose-msg.c F: hw/misc/memexpose/memexpose-pci.c F: hw/misc/memexpose/memexpose-memregion.h F: hw/misc/memexpose/memexpose-memregion.c +F: tests/memexpose-test.c =20 nvme M: Keith Busch diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include index e6bb4ab..3b580bc 100644 --- a/tests/qtest/Makefile.include +++ b/tests/qtest/Makefile.include @@ -14,6 +14,7 @@ check-qtest-pci-$(CONFIG_RTL8139_PCI) +=3D rtl8139-test check-qtest-pci-$(CONFIG_VGA) +=3D display-vga-test check-qtest-pci-$(CONFIG_HDA) +=3D intel-hda-test check-qtest-pci-$(CONFIG_IVSHMEM_DEVICE) +=3D ivshmem-test +check-qtest-x86_64-$(CONFIG_MEMEXPOSE) +=3D memexpose-test =20 DBUS_DAEMON :=3D $(shell which dbus-daemon 2>/dev/null) ifneq ($(GDBUS_CODEGEN),) @@ -289,6 +290,7 @@ tests/qtest/test-filter-mirror$(EXESUF): tests/qtest/te= st-filter-mirror.o $(qtes tests/qtest/test-filter-redirector$(EXESUF): tests/qtest/test-filter-redir= ector.o $(qtest-obj-y) tests/qtest/test-x86-cpuid-compat$(EXESUF): tests/qtest/test-x86-cpuid-com= pat.o $(qtest-obj-y) tests/qtest/ivshmem-test$(EXESUF): tests/qtest/ivshmem-test.o contrib/ivsh= mem-server/ivshmem-server.o $(libqos-pc-obj-y) $(libqos-spapr-obj-y) +tests/qtest/memexpose-test$(EXESUF): tests/qtest/memexpose-test.o $(libqos= -pc-obj-y) tests/qtest/dbus-vmstate-test$(EXESUF): tests/qtest/dbus-vmstate-test.o te= sts/qtest/migration-helpers.o tests/qtest/dbus-vmstate1.o $(libqos-pc-obj-y= ) $(libqos-spapr-obj-y) tests/qtest/vhost-user-bridge$(EXESUF): tests/qtest/vhost-user-bridge.o $(= test-util-obj-y) libvhost-user.a tests/qtest/test-arm-mptimer$(EXESUF): tests/qtest/test-arm-mptimer.o diff --git a/tests/qtest/memexpose-test.c b/tests/qtest/memexpose-test.c new file mode 100644 index 0000000..70a8a73 --- /dev/null +++ b/tests/qtest/memexpose-test.c @@ -0,0 +1,364 @@ +/* + * Memexpose PCI device + * + * Copyright (C) 2020 Samsung Electronics Co Ltd. + * Igor Kotrasinski, + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WI= THOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, see . + * + */ + +#include "qemu/osdep.h" +#include +#include "libqos/libqos-pc.h" +#include "libqtest-single.h" +#include "hw/misc/memexpose/memexpose-core.h" + +static char *tmpshm; +static char *tmpdir; + +static void save_fn(QPCIDevice *dev, int devfn, void *data) +{ + QPCIDevice **pdev =3D (QPCIDevice **) data; + + *pdev =3D dev; +} + +static QPCIDevice *get_device(QPCIBus *pcibus) +{ + QPCIDevice *dev; + + dev =3D NULL; + qpci_device_foreach(pcibus, 0x1af4, 0x1111, save_fn, &dev); + g_assert(dev !=3D NULL); + + return dev; +} + +typedef struct _MexpState { + QOSState *qs; + QPCIBar reg_bar, mem_bar; + QPCIDevice *dev; +} MexpState; + + +static inline void read_mexp_mem(MexpState *s, uint64_t off, + void *buf, size_t len) +{ + qpci_memread(s->dev, s->mem_bar, off, buf, len); +} + +static inline void write_mexp_mem(MexpState *s, uint64_t off, + const void *buf, size_t len) +{ + qpci_memwrite(s->dev, s->mem_bar, off, buf, len); +} + +static inline void read_mem(MexpState *s, uint64_t off, + void *buf, size_t len) +{ + char *cbuf =3D buf; + for (size_t i =3D 0; i < len; i++) { + cbuf[i] =3D qtest_readb(s->qs->qts, off + i); + } +} + +static inline void write_mem(MexpState *s, uint64_t off, + const void *buf, size_t len) +{ + const char *cbuf =3D buf; + for (size_t i =3D 0; i < len; i++) { + qtest_writeb(s->qs->qts, off + i, cbuf[i]); + } +} + +static inline void write_mexp_reg(MexpState *s, uint64_t off, + uint64_t val) +{ + qpci_io_writeq(s->dev, s->reg_bar, off, val); +} + +static inline uint64_t read_mexp_reg(MexpState *s, uint64_t off) +{ + return qpci_io_readq(s->dev, s->reg_bar, off); +} + +static void mexp_send_intr(MexpState *s, uint64_t type, + uint64_t data) +{ + uint64_t send =3D 1; + write_mexp_reg(s, MEMEXPOSE_INTR_TX_TYPE_ADDR, type); + write_mexp_reg(s, MEMEXPOSE_INTR_TX_DATA_ADDR, data); + write_mexp_reg(s, MEMEXPOSE_INTR_SEND_ADDR, send); +} + +static uint64_t mexp_recv_intr(MexpState *s, uint64_t *type, + uint64_t *data) +{ + uint64_t recv =3D 0; + int tries =3D 0; + while (recv =3D=3D 0 && tries < 100) { + recv =3D read_mexp_reg(s, MEMEXPOSE_INTR_RECV_ADDR); + if (recv) { + break; + } + tries++; + g_usleep(10000); + } + *type =3D read_mexp_reg(s, MEMEXPOSE_INTR_RX_TYPE_ADDR); + *data =3D read_mexp_reg(s, MEMEXPOSE_INTR_RX_DATA_ADDR); + return recv; +} + +static void setup_vm_cmd(MexpState *s, const char *cmd, bool msix) +{ + uint64_t barsize; + const char *arch =3D qtest_get_arch(); + + if (strcmp(arch, "x86_64") =3D=3D 0) { + s->qs =3D qtest_pc_boot(cmd); + } else { + g_printerr("memexpose-test tests are only available on x86_64\n"); + exit(EXIT_FAILURE); + } + s->dev =3D get_device(s->qs->pcibus); + s->reg_bar =3D qpci_iomap(s->dev, 0, &barsize); + g_assert_cmpuint(barsize, =3D=3D, MEMEXPOSE_INTR_MEM_SIZE); + + if (msix) { + qpci_msix_enable(s->dev); + } + + s->mem_bar =3D qpci_iomap(s->dev, 1, &barsize); + + qpci_device_enable(s->dev); +} + +static void remove_socks(char *tmp_path) +{ + char *memsock =3D g_strdup_printf("%s/qemu-mexp-mem", tmp_path); + g_remove(memsock); + g_free(memsock); + + char *intsock =3D g_strdup_printf("%s/qemu-mexp-mem", tmp_path); + g_remove(intsock); + g_free(intsock); +} +static void add_socks(char *tmp_path) +{ + char *memsock =3D g_strdup_printf("%s/qemu-mexp-mem", tmp_path); + mkfifo(memsock, 0700); + g_free(memsock); + + char *intsock =3D g_strdup_printf("%s/qemu-mexp-mem", tmp_path); + mkfifo(intsock, 0700); + g_free(intsock); +} + +static void setup_vm(MexpState *s, int server) +{ + unsigned long shm_size =3D 1 << 28; + const char *socksrv =3D server ? "server,nowait," : ""; + char *cmd =3D g_strdup_printf("-mem-path %s " + "-device memexpose-pci,mem_chardev=3Dmem-m= em," + "intr_chardev=3Dmem-intr,shm_size=3D0x%lx " + "-chardev socket,%spath=3D%s/qemu-mexp-mem= ,id=3Dmem-mem " + "-chardev socket,%spath=3D%s/qemu-mexp-int= r,id=3Dmem-intr", + tmpshm, shm_size, + socksrv, tmpdir, socksrv, tmpdir); + setup_vm_cmd(s, cmd, false); + g_free(cmd); +} + +static void cleanup_vm(MexpState *s) +{ + assert(!global_qtest); + g_free(s->dev); + qtest_shutdown(s->qs); +} + +static void setup_connected_vms(MexpState *s1, MexpState *s2) +{ + remove_socks(tmpdir); + add_socks(tmpdir); + setup_vm(s1, 1); + setup_vm(s2, 0); + + write_mexp_reg(s1, MEMEXPOSE_INTR_ENABLE_ADDR, 1); + write_mexp_reg(s2, MEMEXPOSE_INTR_ENABLE_ADDR, 1); +} + +static void test_memexpose_simple_memshare(void) +{ + size_t sixty_four_megs =3D 1 << (20 + 6); + uint32_t in, out; + + MexpState s1, s2; + setup_connected_vms(&s1, &s2); + + in =3D 0xdeadbeef; + write_mem(&s1, sixty_four_megs, &in, 4); + read_mexp_mem(&s2, sixty_four_megs, &out, 4); + g_assert_cmphex(in, =3D=3D, out); + in =3D 0xbaba1510; + write_mem(&s1, sixty_four_megs, &in, 4); + read_mexp_mem(&s2, sixty_four_megs, &out, 4); + g_assert_cmphex(in, =3D=3D, out); + + in =3D 0xaaaaaaaa; + write_mexp_mem(&s1, sixty_four_megs, &in, 4); + read_mem(&s2, sixty_four_megs, &out, 4); + g_assert_cmphex(in, =3D=3D, out); + in =3D 0xbbbbbbbb; + write_mexp_mem(&s1, sixty_four_megs, &in, 4); + read_mem(&s2, sixty_four_megs, &out, 4); + g_assert_cmphex(in, =3D=3D, out); + + cleanup_vm(&s1); + cleanup_vm(&s2); +} + +static void test_memexpose_simple_interrupts(void) +{ + MexpState s1, s2; + setup_connected_vms(&s1, &s2); + + mexp_send_intr(&s1, 0x1, 0xdeadbea7); + mexp_send_intr(&s1, 0x2, 0xdeadbaba); + + uint64_t type, data, received; + + received =3D mexp_recv_intr(&s2, &type, &data); + g_assert_cmpuint(received, =3D=3D, 1); + g_assert_cmphex(type, =3D=3D, 0x1); + g_assert_cmphex(data, =3D=3D, 0xdeadbea7); + + received =3D mexp_recv_intr(&s2, &type, &data); + g_assert_cmpuint(received, =3D=3D, 1); + g_assert_cmphex(type, =3D=3D, 0x2); + g_assert_cmphex(data, =3D=3D, 0xdeadbaba); + + cleanup_vm(&s1); + cleanup_vm(&s2); +} + +static void test_memexpose_overfull_intr_queue(void) +{ + MexpState s1, s2; + setup_connected_vms(&s1, &s2); + + unsigned int i, expected, runs =3D MEMEXPOSE_INTR_QUEUE_SIZE + 10; + uint64_t type, data; + + for (i =3D 0; i < runs; i++) { + mexp_send_intr(&s1, i, i); + } + + expected =3D 0; + while (mexp_recv_intr(&s2, &type, &data)) { + if (expected < MEMEXPOSE_INTR_QUEUE_SIZE) { + g_assert_cmphex(type, =3D=3D, expected); + g_assert_cmphex(data, =3D=3D, expected); + expected +=3D 1; + } else { + g_assert_cmphex(type, >, expected); + g_assert_cmphex(type, <, runs); + g_assert_cmphex(data, >, expected); + g_assert_cmphex(data, <, runs); + expected =3D type; + } + } + g_assert_cmpuint(expected, >=3D, MEMEXPOSE_INTR_QUEUE_SIZE - 1); + + cleanup_vm(&s1); + cleanup_vm(&s2); +} + +static void test_memexpose_intr_data(void) +{ + MexpState s1, s2; + setup_connected_vms(&s1, &s2); + + unsigned int i; + uint64_t type, data, received; + + uint64_t send =3D 1; + write_mexp_reg(&s1, MEMEXPOSE_INTR_TX_TYPE_ADDR, 0); + for (i =3D 0; i < MEMEXPOSE_MAX_INTR_DATA_SIZE; i +=3D 8) { + write_mexp_reg(&s1, MEMEXPOSE_INTR_TX_DATA_ADDR + i, i); + } + write_mexp_reg(&s1, MEMEXPOSE_INTR_SEND_ADDR, send); + + received =3D mexp_recv_intr(&s2, &type, &data); + g_assert_cmpuint(received, =3D=3D, 1); + for (i =3D 0; i < MEMEXPOSE_MAX_INTR_DATA_SIZE; i +=3D 8) { + data =3D read_mexp_reg(&s1, MEMEXPOSE_INTR_TX_DATA_ADDR + i); + g_assert_cmphex(data, =3D=3D, i); + } + + cleanup_vm(&s1); + cleanup_vm(&s2); +} + +static void cleanup(void) +{ + if (tmpshm) { + g_rmdir(tmpshm); + tmpshm =3D NULL; + } + + if (tmpdir) { + remove_socks(tmpdir); + g_rmdir(tmpdir); + tmpdir =3D NULL; + } +} + +static void abrt_handler(void *data) +{ + cleanup(); +} + +int main(int argc, char **argv) +{ + int ret; + gchar dir[] =3D "/tmp/memexpose-test.XXXXXX"; + gchar shmdir[] =3D "/dev/shm/memexpose-test.XXXXXX"; + + g_test_init(&argc, &argv, NULL); + + qtest_add_abrt_handler(abrt_handler, NULL); + + if (mkdtemp(dir) =3D=3D NULL) { + g_error("mkdtemp: %s", g_strerror(errno)); + goto out; + } + tmpdir =3D dir; + if (mkdtemp(shmdir) =3D=3D NULL) { + g_error("mkdtemp: %s", g_strerror(errno)); + goto out; + } + tmpshm =3D shmdir; + + qtest_add_func("/memexpose/memory", test_memexpose_simple_memshare); + qtest_add_func("/memexpose/interrupts", test_memexpose_simple_interrup= ts); + qtest_add_func("/memexpose/interrupts_full_queue", + test_memexpose_overfull_intr_queue); + qtest_add_func("/memexpose/interrupts_all_data", test_memexpose_intr_d= ata); + ret =3D g_test_run(); + +out: + cleanup(); + return ret; +} --=20 2.7.4 From nobody Thu May 16 23:18:59 2024 Delivered-To: importer@patchew.org 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; Authentication-Results: mx.zohomail.com; dkim=fail; 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=fail(p=none dis=none) header.from=partner.samsung.com Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1580816151306553.1935727483699; Tue, 4 Feb 2020 03:35:51 -0800 (PST) Received: from localhost ([::1]:56750 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywUg-00075t-5Y for importer@patchew.org; Tue, 04 Feb 2020 06:35:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:53768) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iywQF-0008K3-EG for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:17 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iywQC-0000Dz-TC for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:15 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:51804) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iywQC-0000Bb-LJ for qemu-devel@nongnu.org; Tue, 04 Feb 2020 06:31:12 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200204113111euoutp022389a1179aece5b4857039857e2538f8~wL6jvMK7B3023230232euoutp02B for ; Tue, 4 Feb 2020 11:31:11 +0000 (GMT) Received: from eusmges1new.samsung.com (unknown [203.254.199.242]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200204113111eucas1p15eb69341c493393bdc1002f38ddbd3e7~wL6jg6pD80252702527eucas1p13; Tue, 4 Feb 2020 11:31:11 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges1new.samsung.com (EUCPMTA) with SMTP id E1.0F.61286.FF5593E5; Tue, 4 Feb 2020 11:31:11 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200204113111eucas1p2a96ec20fbaf679215b50d9f03245b33e~wL6jS9Qkq0683206832eucas1p2H; Tue, 4 Feb 2020 11:31:11 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200204113111eusmtrp1d95ab5ee4061de5f02ceb608f4104884~wL6jSdGA82102721027eusmtrp1D; Tue, 4 Feb 2020 11:31:11 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id FA.AC.08375.FF5593E5; Tue, 4 Feb 2020 11:31:11 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200204113110eusmtip279e2ff1405fc17f52f2b634b58c41bec~wL6i7LHvI1904519045eusmtip2T; Tue, 4 Feb 2020 11:31:10 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200204113111euoutp022389a1179aece5b4857039857e2538f8~wL6jvMK7B3023230232euoutp02B DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580815871; bh=2EdIg2dqS4is2/71/wtKDkcAjFpedYTyvl4ZZh7iwes=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=lelKUBo1RtXvLfmQ6kOLzJBttZIre5/mi/rwSGMMwhPlSlP39ze1tSzQdC9XjlXvU AHnsoDulk1xejdjVSgg4W3jjXgO/dHq8N+R6fZilcTLXs1/+/+WaqBxDbdxJdQfcLh eQOofZdBF8CuvKynbVQnkg6DFBc6QG9fkHnwqBLE= X-AuditID: cbfec7f2-f0bff7000001ef66-9d-5e3955fff99e From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC 9/9] hw/arm/virt: Hack in support for memexpose device Date: Tue, 4 Feb 2020 12:30:51 +0100 Message-Id: <1580815851-28887-10-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOIsWRmVeSWpSXmKPExsWy7djPc7r/Qy3jDFoPK1nsufCYzWL/tn+s FnPOPGCxON67g8WBxePOtT1sHk+ubWbyOPhuD5PH+31X2QJYorhsUlJzMstSi/TtErgyWvfM Yy9Ya1ex4DJXA+NO3S5GTg4JAROJT3v+MHUxcnEICaxglNiw4igLhPOFUWLapQlQmc+MEhO2 bAXKcIC19J1Ih4gvZ5T4d+0RE1zH7o5LzCBz2QTUJHYe+cwIYosISEr87joNFmcWyJB4Pqsb zBYWcJFo2rwYzGYRUJU42f+RFcTmFQiU2Pj/AhvEfXISN891gtVwAsXf75kEtkxC4DKbxN01 G5khilwkTj47zA5hC0u8Or4FypaROD25hwXCrpdoubMDqrmDUaJv5XSoDdYSXzYsBXuNWUBT Yv0ufYiwo8TGs2/YID7mk7jxVhDifj6JSdumM0OEeSU62oQgqvUkup/cZILZuqzxEdRWD4l1 62YwQ8JnCaPEg1/f2SYwys9CWLaAkXEVo3hqaXFuemqxYV5quV5xYm5xaV66XnJ+7iZGYPSf /nf80w7Gr5eSDjEKcDAq8fBesLOIE2JNLCuuzD3EKMHBrCTCe17fMk6INyWxsiq1KD++qDQn tfgQozQHi5I4r/Gil7FCAumJJanZqakFqUUwWSYOTqkGRobXq9k2/VWZWPl46uof09dOuvSE J2Or1R554dAP1XE+es/Tr22U/Sa+z1x+CuulHZf+XNs88dCZ388m3Pac8P7y6tIoYf+TWXPt W+Muy58vzv2keC77pOmSY1pC+3YJLPFLzX+4e9G9OXm8ExteCLZoxuQGbTVv2PZ+V27p/Q17 0hSnhl5YdNJfiaU4I9FQi7moOBEAor+X3voCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrOLMWRmVeSWpSXmKPExsVy+t/xe7r/Qy3jDBoX81nsufCYzWL/tn+s FnPOPGCxON67g8WBxePOtT1sHk+ubWbyOPhuD5PH+31X2QJYovRsivJLS1IVMvKLS2yVog0t jPQMLS30jEws9QyNzWOtjEyV9O1sUlJzMstSi/TtEvQyWvfMYy9Ya1ex4DJXA+NO3S5GDg4J AROJvhPpXYycHEICSxklHizPAbElBGQkfpxewwZhC0v8udYFZHMB1XxilDiy8RI7SIJNQE1i 55HPjCC2iICkxO+u08wgNrNAlsTO2feZQGxhAReJps2LweIsAqoSJ/s/soLYvAKBEhv/X4Ba ICdx81wnWA0nUPz9nklMEAcFSFzYNYt9AiPfAkaGVYwiqaXFuem5xYZ6xYm5xaV56XrJ+bmb GIGBuO3Yz807GC9tDD7EKMDBqMTDe8HOIk6INbGsuDL3EKMEB7OSCO95fcs4Id6UxMqq1KL8 +KLSnNTiQ4ymQEdNZJYSTc4HRkleSbyhqaG5haWhubG5sZmFkjhvh8DBGCGB9MSS1OzU1ILU Ipg+Jg5OqQbGxpuGM6cLMbAkJVbGHFL+sO337JO+jkvjz968d+mtzNoNHxj13DSY9Lzv8z+f EcWys/3Un2K7WWZuKcXtjGw+X3xP31jf9sXWPOqmptlv/+irJXHXi6z8L3PeXKPX+EB3ZzNr xaEF01YKs3GvZJh412Z5YnXf0h28a1fpV7zW2uMrcNC27HaQEktxRqKhFnNRcSIAVFhBKVoC AAA= X-CMS-MailID: 20200204113111eucas1p2a96ec20fbaf679215b50d9f03245b33e X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200204113111eucas1p2a96ec20fbaf679215b50d9f03245b33e X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200204113111eucas1p2a96ec20fbaf679215b50d9f03245b33e References: <1580815851-28887-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 3.x X-Received-From: 210.118.77.12 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: peter.maydell@linaro.org, Igor Kotrasinski , pbonzini@redhat.com Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 From: Igor Kotrasinski Signed-off-by: Igor Kotrasinski --- hw/arm/virt.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++= +++- include/hw/arm/virt.h | 5 +++ 2 files changed, 114 insertions(+), 1 deletion(-) diff --git a/hw/arm/virt.c b/hw/arm/virt.c index f788fe2..ba35b21 100644 --- a/hw/arm/virt.c +++ b/hw/arm/virt.c @@ -71,6 +71,8 @@ #include "hw/mem/pc-dimm.h" #include "hw/mem/nvdimm.h" #include "hw/acpi/generic_event_device.h" +#include "hw/misc/memexpose/memexpose-core.h" +#include "hw/misc/memexpose/memexpose-memregion.h" =20 #define DEFINE_VIRT_MACHINE_LATEST(major, minor, latest) \ static void virt_##major##_##minor##_class_init(ObjectClass *oc, \ @@ -168,6 +170,8 @@ static MemMapEntry extended_memmap[] =3D { /* Additional 64 MB redist region (can contain up to 512 redistributor= s) */ [VIRT_HIGH_GIC_REDIST2] =3D { 0x0, 64 * MiB }, [VIRT_HIGH_PCIE_ECAM] =3D { 0x0, 256 * MiB }, + [VIRT_HIGH_MEMEXPOSE_MMIO] =3D { 0x0, 256 * MiB }, + [VIRT_HIGH_MEMEXPOSE] =3D { 0x0, 32 * GiB }, /* Second PCIe window */ [VIRT_HIGH_PCIE_MMIO] =3D { 0x0, 512 * GiB }, }; @@ -179,6 +183,7 @@ static const int a15irqmap[] =3D { [VIRT_GPIO] =3D 7, [VIRT_SECURE_UART] =3D 8, [VIRT_ACPI_GED] =3D 9, + [VIRT_MEMEXPOSE] =3D 10, [VIRT_MMIO] =3D 16, /* ...to 16 + NUM_VIRTIO_TRANSPORTS - 1 */ [VIRT_GIC_V2M] =3D 48, /* ...to 48 + NUM_GICV2M_SPIS - 1 */ [VIRT_SMMU] =3D 74, /* ...to 74 + NUM_SMMU_IRQS - 1 */ @@ -763,6 +768,67 @@ static void create_uart(const VirtMachineState *vms, i= nt uart, g_free(nodename); } =20 +static void create_memexpose(const VirtMachineState *vms, MemoryRegion *me= m, + Error **errp) +{ + if (!vms->memexpose_size) { + error_setg(errp, "For memexpose support, memexpose_size " + "needs to be greater than zero"); + return; + } + if (!strcmp("", vms->memexpose_ep)) { + error_setg(errp, "For memexpose support, memexpose_ep " + "needs to be non-empty"); + return; + } + + DeviceState *dev =3D qdev_create(NULL, "memexpose-memdev"); + + hwaddr base =3D vms->memmap[VIRT_HIGH_MEMEXPOSE].base; + hwaddr size =3D vms->memexpose_size; + hwaddr mmio_base =3D vms->memmap[VIRT_HIGH_MEMEXPOSE_MMIO].base; + hwaddr mmio_size =3D MEMEXPOSE_INTR_MEM_SIZE; + int irq =3D vms->irqmap[VIRT_MEMEXPOSE]; + + qdev_prop_set_uint64(dev, "shm_size", size); + + char *intr_ep =3D g_strdup_printf("%s-intr", vms->memexpose_ep); + char *mem_ep =3D g_strdup_printf("%s-mem", vms->memexpose_ep); + Chardev *c =3D qemu_chr_find(mem_ep); + if (!c) { + error_setg(errp, "Failed to find memexpose memory endpoint"); + return; + } + qdev_prop_set_chr(dev, "mem_chardev", c); + c =3D qemu_chr_find(intr_ep); + if (!c) { + error_setg(errp, "Failed to find memexpose interrupt endpoint"); + return; + } + qdev_prop_set_chr(dev, "intr_chardev", c); + g_free(intr_ep); + g_free(mem_ep); + + qdev_init_nofail(dev); + MemexposeMemdev *mdev =3D MEMEXPOSE_MEMDEV(dev); + SysBusDevice *s =3D SYS_BUS_DEVICE(dev); + memory_region_add_subregion(mem, mmio_base, &mdev->intr.shmem); + memory_region_add_subregion(mem, base, &mdev->mem.shmem); + sysbus_connect_irq(s, 0, qdev_get_gpio_in(vms->gic, irq)); + + char *nodename =3D g_strdup_printf("/memexpose@%" PRIx64, mmio_base); + qemu_fdt_add_subnode(vms->fdt, nodename); + qemu_fdt_setprop_string(vms->fdt, nodename, "compatible", + "memexpose-memregion"); + qemu_fdt_setprop_sized_cells(vms->fdt, nodename, "reg", + 2, mmio_base, 2, mmio_size, + 2, base, 2, size); + qemu_fdt_setprop_cells(vms->fdt, nodename, "interrupts", + GIC_FDT_IRQ_TYPE_SPI, irq, + GIC_FDT_IRQ_FLAGS_LEVEL_HI); + g_free(nodename); +} + static void create_rtc(const VirtMachineState *vms) { char *nodename; @@ -1572,7 +1638,6 @@ static void machvirt_init(MachineState *machine) UINT64_MAX); memory_region_add_subregion_overlap(secure_sysmem, 0, sysmem, -1); } - firmware_loaded =3D virt_firmware_init(vms, sysmem, secure_sysmem ?: sysmem); =20 @@ -1721,6 +1786,8 @@ static void machvirt_init(MachineState *machine) fdt_add_pmu_nodes(vms); =20 create_uart(vms, VIRT_UART, sysmem, serial_hd(0)); + if (vms->memexpose_size > 0) + create_memexpose(vms, sysmem, &error_abort); =20 if (vms->secure) { create_secure_ram(vms, secure_sysmem); @@ -1849,6 +1916,32 @@ static void virt_set_gic_version(Object *obj, const = char *value, Error **errp) } } =20 +static char *virt_get_memexpose_ep(Object *obj, Error **errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(obj); + return g_strdup(vms->memexpose_ep); +} + +static void virt_set_memexpose_ep(Object *obj, const char *value, Error **= errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(obj); + g_free(vms->memexpose_ep); + vms->memexpose_ep =3D g_strdup(value); +} + +static char *virt_get_memexpose_size(Object *obj, Error **errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(obj); + return g_strdup_printf("%" PRIx64, vms->memexpose_size); +} + +static void virt_set_memexpose_size(Object *obj, const char *value, + Error **errp) +{ + VirtMachineState *vms =3D VIRT_MACHINE(obj); + parse_option_size("memexpose-size", value, &vms->memexpose_size, errp); +} + static char *virt_get_iommu(Object *obj, Error **errp) { VirtMachineState *vms =3D VIRT_MACHINE(obj); @@ -2103,6 +2196,21 @@ static void virt_instance_init(Object *obj) "Set GIC version. " "Valid values are 2, 3 and host", NULL= ); =20 + /* Memexpose disabled by default */ + vms->memexpose_ep =3D g_strdup(""); + object_property_add_str(obj, "memexpose-ep", virt_get_memexpose_ep, + virt_set_memexpose_ep, NULL); + object_property_set_description(obj, "memexpose-ep", + "Set path to memexpose server socket. " + "Sockets used for communication will b= e " + "-intr and -mem. Set to em= pty " + "to disable memexpose.", NULL); + vms->memexpose_size =3D 0; + object_property_add_str(obj, "memexpose-size", virt_get_memexpose_size, + virt_set_memexpose_size, NULL); + object_property_set_description(obj, "memexpose-size", + "Size of the memexpose region to acces= s.", + NULL); vms->highmem_ecam =3D !vmc->no_highmem_ecam; =20 if (vmc->no_its) { diff --git a/include/hw/arm/virt.h b/include/hw/arm/virt.h index 71508bf..d0aeb67 100644 --- a/include/hw/arm/virt.h +++ b/include/hw/arm/virt.h @@ -76,6 +76,7 @@ enum { VIRT_PLATFORM_BUS, VIRT_GPIO, VIRT_SECURE_UART, + VIRT_MEMEXPOSE, VIRT_SECURE_MEM, VIRT_PCDIMM_ACPI, VIRT_ACPI_GED, @@ -86,6 +87,8 @@ enum { enum { VIRT_HIGH_GIC_REDIST2 =3D VIRT_LOWMEMMAP_LAST, VIRT_HIGH_PCIE_ECAM, + VIRT_HIGH_MEMEXPOSE_MMIO, + VIRT_HIGH_MEMEXPOSE, VIRT_HIGH_PCIE_MMIO, }; =20 @@ -124,6 +127,8 @@ typedef struct { bool its; bool virt; int32_t gic_version; + char *memexpose_ep; + uint64_t memexpose_size; VirtIOMMUType iommu; struct arm_boot_info bootinfo; MemMapEntry *memmap; --=20 2.7.4