From nobody Mon Feb 9 13:51:51 2026 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 15808954636131019.2100612332744; Wed, 5 Feb 2020 01:37:43 -0800 (PST) Received: from localhost ([::1]:43626 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH7u-0005yQ-Ex for importer@patchew.org; Wed, 05 Feb 2020 04:37:42 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49846) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH3f-0000hF-Sv for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:21 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1izH3e-0004xI-4J for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:19 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:41525) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1izH3d-0004T7-Pm for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:18 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200205093315euoutp02481d807c3c8de208aa0fce5275384064~wd83QouJs1428814288euoutp02b for ; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200205093314eucas1p1e652240bb7dc2f6f398ec5965bbffc3c~wd83CLIxv3063130631eucas1p1S; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id CC.8A.60698.ADB8A3E5; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20200205093314eucas1p15a5cc16c92fd8004343acb1fd551f42a~wd82piy9L3273232732eucas1p1R; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200205093314eusmtrp1cb67ae381efaf7f721ba2b96b24f08c9~wd82pDnt11029010290eusmtrp1S; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 6D.8D.08375.ADB8A3E5; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200205093314eusmtip267a15f48e03480c51a79618a064617a4~wd82YhnTK3043930439eusmtip2B; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200205093315euoutp02481d807c3c8de208aa0fce5275384064~wd83QouJs1428814288euoutp02b DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580895195; bh=VI8ZZsYihdmS6uzzMRU8CCMFMKBACwzdMDlOnQ0OCcE=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=IlFZSBp8C1ioTsnT+EIDWeNrj6VY9CSdAM8I06Gr57O/Ue9D6+hF7LjBBBDHS6RuE Nq2NdIEE17FmXgDViEB0ni4jQ893CfSWNd1yQJpWTJHgOrR82bygY82TitHpw8k2SW FGAWHAqNHh9uFI3WIXSoZVus+JaJhFbSSbPRurgs= X-AuditID: cbfec7f5-a0fff7000001ed1a-bd-5e3a8bdada91 From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 1/9] memory: Add function for finding flat memory ranges Date: Wed, 5 Feb 2020 10:32:57 +0100 Message-Id: <1580895185-24341-2-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580895185-24341-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrJIsWRmVeSWpSXmKPExsWy7djPc7q3uq3iDHZe0LbYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlLGhc x1bwQrPic/8SxgbGiXJdjJwcEgImEn++XWPpYuTiEBJYwSixtfk/M4TzhVHiy9sVrBDOZ0aJ 2U+/MMO0HOm6xwiRWM4osWvZc3a4llWtb9lBqtgE1CR2HvnMCGKLCEhK/O46DdbNLJAh8XxW N5gtLBAosXNTHxOIzSKgKtH2axZYPa9AgMSpL41sENvkJG6e6wSr5wSq3/TpIxvIMgmBy2wS VyefZIIocpHYdGITlC0s8er4FnYIW0bi9OQeFgi7XqLlzg4miOYORom+ldOhNlhLfNmwFKiI A+g6TYn1u/Qhwo4Sq+6cZwYJSwjwSdx4KwhxP5/EpG3TocK8Eh1tQhDVehLdT24ywWxd1vgI aquHxLmD79gg4bOEUWLR5qOMExjlZyEsW8DIuIpRPLW0ODc9tdg4L7Vcrzgxt7g0L10vOT93 EyMwAZz+d/zrDsZ9f5IOMQpwMCrx8AZMsIwTYk0sK67MPcQowcGsJMJ7Xh8oxJuSWFmVWpQf X1Sak1p8iFGag0VJnNd40ctYIYH0xJLU7NTUgtQimCwTB6dUA6P24wjDef1Wcj9Nj21os1vm u6Y4uTLx795yR84klaoP0cFPNvLvPrRj0RzrwIC04+y2p/U3nvm4MbPubojIKd8HEec09uoe EC7r/bR6+SWrJXse3vapnmM++1efZbNaEfOLTUy8pyeFM5yvCLfuW2WucP/66vxImwnXm9ft nhYS8/Litsrqx5pKLMUZiYZazEXFiQD3F0Gb/AIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRmVeSWpSXmKPExsVy+t/xe7q3uq3iDK7MErPYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlLGhcx1bwQrPic/8SxgbGiXJdjJwc EgImEke67jF2MXJxCAksZZToefabFSIhI/Hj9Bo2CFtY4s+1LjaIok+MEutndzGBJNgE1CR2 HvnMCGKLCEhK/O46zQxiMwtkSeycfR+sRljAX+LCgh3sIDaLgKpE269ZYPW8AgESp740Qi2Q k7h5rhOsl1MgUGLTp49gcSGgmmtfv7JOYORbwMiwilEktbQ4Nz232FCvODG3uDQvXS85P3cT IzActx37uXkH46WNwYcYBTgYlXh4V0yyjBNiTSwrrsw9xCjBwawkwnteHyjEm5JYWZValB9f VJqTWnyI0RToqInMUqLJ+cBYySuJNzQ1NLewNDQ3Njc2s1AS5+0QOBgjJJCeWJKanZpakFoE 08fEwSnVwGiUqMmQ/KxypwyP+qdUzv+piVb120x3rlVsZTyQsv4Li8bmXMajr3+7m5923uPG 86FK/Oi6jesyJZ0uljm4tMVPsDoider4Z86VjnN27/H4LPxRa/mlow8Mrn/i+pDE+LVo8+E3 vXm7NOtnH+14ombbx9v7Ju8XxwtlkUdHIjtOus+6aHC7xFSJpTgj0VCLuag4EQCePDhwXQIA AA== X-CMS-MailID: 20200205093314eucas1p15a5cc16c92fd8004343acb1fd551f42a X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200205093314eucas1p15a5cc16c92fd8004343acb1fd551f42a X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200205093314eucas1p15a5cc16c92fd8004343acb1fd551f42a References: <1580895185-24341-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..ac09221 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 Mon Feb 9 13:51:51 2026 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 1580895455333824.403586287427; Wed, 5 Feb 2020 01:37:35 -0800 (PST) Received: from localhost ([::1]:43622 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH7m-0005lx-4R for importer@patchew.org; Wed, 05 Feb 2020 04:37:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49866) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH3g-0000hu-CQ for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1izH3e-0004x0-3x for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:20 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:38000) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1izH3d-0004Uv-PX for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:18 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20200205093315euoutp0127bf4070e62721b1e5c8198e5bb25e05~wd83dRHXz2281422814euoutp01e for ; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20200205093315eucas1p2465111564150ef49c1b208fbb1cd6cb3~wd83Ns1Wt1343613436eucas1p2z; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id 6C.39.60679.ADB8A3E5; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200205093314eucas1p23f60704a2ba3e1732c37ec76b8b3ef5a~wd824yxtk0722307223eucas1p2k; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200205093314eusmtrp1984fffd7e5dbd6d03d6e561e3caf2dd6~wd824QzLF1029010290eusmtrp1U; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id F8.9A.07950.ADB8A3E5; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200205093314eusmtip2afe5c81bfd9e90e2e1f33252135b3646~wd82ovdMv3043630436eusmtip2I; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20200205093315euoutp0127bf4070e62721b1e5c8198e5bb25e05~wd83dRHXz2281422814euoutp01e DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580895195; bh=VrEMlIgxEJjU0sxujhBCFCGXNdNA8F72SurqAsUMMcM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=C8+qr1KE8I9fzrzeVcvF9wi+qyzSozxM+ZAx/dVgkg8gDJ7rGyqpo/LK1gwYkegaY b9H0akge+B9CI55St/LvsLT/LCJDQ7vVveHPDtLv08VDtLi7eA5y88flcx54UtyxT7 Gq+qaZmqfS8rm68A4Tv6FuP4XBH2x2IqwDBtDse8= X-AuditID: cbfec7f4-0e5ff7000001ed07-90-5e3a8bdac6c1 From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 2/9] memory: Support mmap offset for fd-backed memory regions Date: Wed, 5 Feb 2020 10:32:58 +0100 Message-Id: <1580895185-24341-3-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580895185-24341-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOIsWRmVeSWpSXmKPExsWy7djPc7q3uq3iDP7st7LYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlzOzu Zy+Y61Hx4FEPcwPjO/0uRk4OCQETiXUL77J3MXJxCAmsYJSYsGMaC0hCSOALo8S0Lg6IxGdG ie8tm5lhOp6v62ODSCxnlJj4sg+qHahj9aX9YFVsAmoSO498ZgSxRQQkJX53nQaLMwtkSDyf 1Q1mCwuESfy/uB2shkVAVeLHpmNsIDavQIDE6Y6JjBDb5CRunusEq+cUCJTY9Okj2GYJgTNs EvcPHWeCKHKR+PLzARuELSzx6vgWdghbRuL05B4WCLteouXODiaI5g5Gib6V06EarCW+bFgK VMQBdJ2mxPpd0IBxlPj39iUjSFhCgE/ixltBiPv5JCZtm84MEeaV6GgTgqjWk+h+cpMJZuuy xkcsECUeEkve8kGCZwmjxLar+5gmMMrPQti1gJFxFaN4amlxbnpqsVFearlecWJucWleul5y fu4mRmD0n/53/MsOxl1/kg4xCnAwKvHwrphkGSfEmlhWXJl7iFGCg1lJhPe8PlCINyWxsiq1 KD++qDQntfgQozQHi5I4r/Gil7FCAumJJanZqakFqUUwWSYOTqkGxhnC61at2cHheO7lXFVP i9NtNXePf9Po0k+XzzsTLqbXsUPg3HlZEzeZeSxXHm27ZGh70on3woRFVtN3BfywPFh44+WD zhS+Xq3KoFxugXVHa45ya7WsPVq/RW5N5wq99MCvfzweH2C80v1vj9Ql10VVcfvPn8ue03sq SqzFbebxWINbze/yU5RYijMSDbWYi4oTATo+dCH6AgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRmVeSWpSXmKPExsVy+t/xe7q3uq3iDP5cVLPYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlzOzuZy+Y61Hx4FEPcwPjO/0uRk4O CQETiefr+ti6GLk4hASWMkrM+bmRESIhI/Hj9Bo2CFtY4s+1LqiiT4wSF6evYAdJsAmoSew8 8hmsQURAUuJ312lmEJtZIEti5+z7TCC2sECIxIed58EGsQioSvzYdAzM5hUIkDjdMRFqmZzE zXOdYL2cAoESmz59BKsRAqq59vUr6wRGvgWMDKsYRVJLi3PTc4uN9IoTc4tL89L1kvNzNzEC w3HbsZ9bdjB2vQs+xCjAwajEwxswwTJOiDWxrLgy9xCjBAezkgjveX2gEG9KYmVValF+fFFp TmrxIUZToKMmMkuJJucDYyWvJN7Q1NDcwtLQ3Njc2MxCSZy3Q+BgjJBAemJJanZqakFqEUwf EwenVANjU9vVw3wMcU3t7kwvHoreOy2oO23nrcI1KxbUJGbckOtKquyd8rqg7GGlcUrirskz FawuJB2OdeNkfl27tWaj9qXa1jU9v408tkdViZ5bvS2wev5XR44ohpv7n33Ju/16Etv9I5Zx K47+zjna+G9qvtQX1uSSLx2mE9WjdJ9/dpzz/vxdrk3hSizFGYmGWsxFxYkASJ5MnV0CAAA= X-CMS-MailID: 20200205093314eucas1p23f60704a2ba3e1732c37ec76b8b3ef5a X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200205093314eucas1p23f60704a2ba3e1732c37ec76b8b3ef5a X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200205093314eucas1p23f60704a2ba3e1732c37ec76b8b3ef5a References: <1580895185-24341-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 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 | 2 ++ 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, 20 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 ac09221..c5554cc 100644 --- a/include/exec/memory.h +++ b/include/exec/memory.h @@ -906,6 +906,7 @@ void memory_region_init_ram_from_file(MemoryRegion *mr, * @owner: the object that tracks the region's reference count * @name: the name of the region. * @size: size of the region. + * @mmap_offset: offset at which the fd is to be mapped. * @share: %true if memory must be mmaped with the MAP_SHARED flag * @fd: the fd to mmap. * @errp: pointer to Error*, to store an error if it happens. @@ -917,6 +918,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 Mon Feb 9 13:51:51 2026 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 15808952963401021.8910771198448; Wed, 5 Feb 2020 01:34:56 -0800 (PST) Received: from localhost ([::1]:43584 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH5D-0002QL-6Z for importer@patchew.org; Wed, 05 Feb 2020 04:34:55 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49827) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH3f-0000gR-DB for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1izH3e-0004xU-4z for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:19 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:41535) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1izH3d-0004Yd-UG for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:18 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200205093315euoutp024fab0caf68e7eca75bbc838207639127~wd830lAhY1428814288euoutp02d for ; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmges1new.samsung.com (unknown [203.254.199.242]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200205093315eucas1p1659d0bb62e8a0e5ea4e9e30747e5f886~wd83iKgo42000320003eucas1p1N; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges1new.samsung.com (EUCPMTA) with SMTP id BD.19.61286.BDB8A3E5; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20200205093315eucas1p1b77dcc2238588a6b6efb5e89aa902b6d~wd83NOUKu3061730617eucas1p1o; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200205093314eusmtrp16ed2e5b5e59501cd5056ec80093fb2b3~wd83MxAE51029010290eusmtrp1W; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id BD.8D.08375.ADB8A3E5; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200205093314eusmtip2ae18c554db84e1488a305d02a6f85b9a~wd825APGN0075700757eusmtip2L; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200205093315euoutp024fab0caf68e7eca75bbc838207639127~wd830lAhY1428814288euoutp02d DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580895195; bh=ibNqqK8kMJTR6I/8H1P2J6EA3/WKQtaT/ZbDNoeJndI=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=TILI/D/6Pmtp2T1OVmmA1Y7YPUt2cqmNBaolwH/RbpRiUysovJB19KBfXkEXj3tpW frQzc/fT6prwMpeYCTcCQhSo410lO5tMcb8bs3n3e5eeiGLOcD1emc3x866VqX4wg9 UUI0SsfqzZrLmCUHpof9k+Uaq7hK6Gv+0bcc/qoQ= X-AuditID: cbfec7f2-ef1ff7000001ef66-53-5e3a8bdb8eff From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 3/9] memory: Hack - use shared memory when possible Date: Wed, 5 Feb 2020 10:32:59 +0100 Message-Id: <1580895185-24341-4-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580895185-24341-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrBIsWRmVeSWpSXmKPExsWy7djPc7q3u63iDD78FLLYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlrDzU xVLwna1i3uqNjA2MP1m6GDk5JARMJL6cucPaxcjFISSwglHi4dGzzBDOF0aJ2/tPs0M4nxkl Xs7ewQTT0tl5ggkisZxR4vyRl2xwLZfeHgMbzCagJrHzyGdGEFtEQFLid9dpZhCbWSBD4vms bjBbWMBL4uijLawgNouAqsTcY21gG3gFAiTeN7axQmyTk7h5rhOsnlMgUGLTp49gyyQELrNJ zH23kRmiyEVi0eLtUA3CEq+Ob2GHsGUkTk/ugfq0XqLlzg4miOYORom+ldPZIBLWEl82LAUq 4gC6TlNi/S59iLCjxJT7IMdxANl8EjfeCkLczycxadt0Zogwr0RHmxBEtZ5E95ObTDBblzU+ gtrqIXGg8SLYZUICSxglfrdaT2CUn4WwawEj4ypG8dTS4tz01GLDvNRyveLE3OLSvHS95Pzc TYzA+D/97/inHYxfLyUdYhTgYFTi4V0xyTJOiDWxrLgy9xCjBAezkgjveX2gEG9KYmVValF+ fFFpTmrxIUZpDhYlcV7jRS9jhQTSE0tSs1NTC1KLYLJMHJxSDYxdNtfOiW+2i1vQ865a/UUl 35vXXA2af0T1U9Vv7VlU892gO2aT0fEVx/y5f1QUqCrP5Cvt2Xv+iM3cSGen/XWKcSqZV6Xn OTCuyvcPM8/QPGJZE586U/2NZcptdnuZ1oyaqk1XWj+rewtumRZ3PGvHuUKjRX79oj+a1qmq 1hoxca79k+XXq8RSnJFoqMVcVJwIAJPuQCX7AgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRmVeSWpSXmKPExsVy+t/xe7q3uq3iDCZftrTYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlrDzUxVLwna1i3uqNjA2MP1m6GDk5 JARMJDo7TzB1MXJxCAksZZS49/gbI0RCRuLH6TVsELawxJ9rXWwQRZ8YJRp3fmMHSbAJqEns PPIZrEFEQFLid9dpZhCbWSBLYufs+0wgtrCAl8TRR1tYQWwWAVWJucfawOK8AgES7xvbWCEW yEncPNcJ1sspECix6dNHsMVCQDXXvn5lncDIt4CRYRWjSGppcW56brGhXnFibnFpXrpecn7u JkZgOG479nPzDsZLG4MPMQpwMCrx8K6YZBknxJpYVlyZe4hRgoNZSYT3vD5QiDclsbIqtSg/ vqg0J7X4EKMp0FETmaVEk/OBsZJXEm9oamhuYWlobmxubGahJM7bIXAwRkggPbEkNTs1tSC1 CKaPiYNTqoGxKKv1qfzvLdPiC++7CnasKCrIOfhisReby2e/uwInj01h+xeyMqil8sGx5RPt 98+bEeHb+fsD25UVmx65Lbuxzfr7BePEVTWqDEVz5F9sUJkaUyr9guUPx+ZGq8mvrzMHPlLa UNOU+/qgZt2f2OdL1+mtU+Q6cPrL6mnVx9IvWAluqOetvV52TImlOCPRUIu5qDgRAKMCOeJd AgAA X-CMS-MailID: 20200205093315eucas1p1b77dcc2238588a6b6efb5e89aa902b6d X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200205093315eucas1p1b77dcc2238588a6b6efb5e89aa902b6d X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200205093315eucas1p1b77dcc2238588a6b6efb5e89aa902b6d References: <1580895185-24341-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/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 Mon Feb 9 13:51:51 2026 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 1580895590710113.02105939802641; Wed, 5 Feb 2020 01:39:50 -0800 (PST) Received: from localhost ([::1]:43652 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH9x-0000g1-Hb for importer@patchew.org; Wed, 05 Feb 2020 04:39:49 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49880) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH3g-0000iX-Ov for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1izH3e-0004xk-7B for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:20 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:41536) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1izH3d-0004aJ-U9 for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:18 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200205093315euoutp02cecf5403a8e64ae29d5f59b97db4a8aa~wd839G0ej1409714097euoutp02- for ; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20200205093315eucas1p2fd736ab9bf748bb0ca772adae2e96c34~wd83x0GYf1343613436eucas1p21; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id 3D.8A.60698.BDB8A3E5; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200205093315eucas1p2e1ae9525ecdee6b9f2462f71a20b0fa4~wd83fJsUT1336113361eucas1p2H; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200205093315eusmtrp194afe1bce4705a7b0eca2295005cd5bd~wd83erjsi1029010290eusmtrp1X; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 0E.8D.08375.BDB8A3E5; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200205093314eusmtip22b0f35e96b2eb2c657488a4dde39dc8e~wd83Lb3QK0075000750eusmtip2L; Wed, 5 Feb 2020 09:33:14 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200205093315euoutp02cecf5403a8e64ae29d5f59b97db4a8aa~wd839G0ej1409714097euoutp02- DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580895195; bh=+wnUiFJnUH2TCdGlOKcFQFDHt2RwQPVUHtykAtH6SQY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=NIDeHcR77KzVh7MgpL0IkLtxXygWKV12zh3UMQJHMuEFGc/1LtEOrS1eBm+ccP9e/ oz8YBa1xz80ftmo8e3LFQFTFFgVfOJOjiGZ2ldwYsy5LUqVlFeR+e8U1iLR2j+9Hs3 at09EqHBu5MD8jUt2QjtlWsF88Zy15/J4GQLo6KI= X-AuditID: cbfec7f5-a29ff7000001ed1a-c0-5e3a8bdb8d6e From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 4/9] hw/misc/memexpose: Add documentation Date: Wed, 5 Feb 2020 10:33:00 +0100 Message-Id: <1580895185-24341-5-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580895185-24341-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrGIsWRmVeSWpSXmKPExsWy7djP87q3u63iDF4flrfYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlfD+4 hblgm2vF5CU1DYxvzboYOTgkBEwkVjSEdzFycQgJrGCUaO9fwAjhfGGUuNZ4kwXC+cwocbd5 A3sXIydYx46Gi0wQieWMEg/b7yG0XOjdxwxSxSagJrHzyGdGEFtEQFLid9dpsDizQIbE81nd YLawgIPE1M1nmUHuYBFQlbh0hxskzCsQIHG4+zDUMjmJm+c6wco5BQIlNn36yAayS0LgMpvE +hMLoIpcJGZ3PWSDsIUlXh3fAhWXkTg9uYcFwq6XaLmzgwmiuYNRom/ldKgGa4kvG5aygBzB LKApsX6XPkTYUWLO9q1MkDDik7jxVhDifD6JSdumM0OEeSU62oQgqvUkup/cZILZuqzxEdRW D4n3b7qYIcGzhFFi1/6F7BMY5WchLFvAyLiKUTy1tDg3PbXYOC+1XK84Mbe4NC9dLzk/dxMj MPZP/zv+dQfjvj9JhxgFOBiVeHgDJljGCbEmlhVX5h5ilOBgVhLhPa8PFOJNSaysSi3Kjy8q zUktPsQozcGiJM5rvOhlrJBAemJJanZqakFqEUyWiYNTqoFx+p9Hp+Ssf3jvnNz333qFdvMd X56jy3SE/B6WVoW4snktkaw939W2LnbHCft3usL+nTMPTqn9c1jfT/fDkTtu3THRbfcvL6rO rZW/efBQhLuKw9+/hkfYD6/f9vOee+ajiYl9dcLuJkJbHY+USuX/0E1qNHh7n5vTkrXf+g6r TlFu4Iv0lY+UWIozEg21mIuKEwGxdeDn+QIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrBLMWRmVeSWpSXmKPExsVy+t/xe7q3u63iDCav57XYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlfD+4hblgm2vF5CU1DYxvzboYOTkk BEwkdjRcZOpi5OIQEljKKDG3A8QBSchI/Di9hg3CFpb4c62LDaLoE6NEy9F5jCAJNgE1iZ1H PoPZIgKSEr+7TjOD2MwCWRI7Z98HGyQs4CAxdfNZoDgHB4uAqsSlO9wgYV6BAInD3YfZIebL Sdw81wnWyikQKLHp00ewvUJANde+fmWdwMi3gJFhFaNIamlxbnpusaFecWJucWleul5yfu4m RmAobjv2c/MOxksbgw8xCnAwKvHwrphkGSfEmlhWXJl7iFGCg1lJhPe8PlCINyWxsiq1KD++ qDQntfgQoynQTROZpUST84FxklcSb2hqaG5haWhubG5sZqEkztshcDBGSCA9sSQ1OzW1ILUI po+Jg1OqgdHC+NnBK7+Ob4x/dbxH0XujK3+am1SWdEfhy8v6pdd99+2+3qTKdvPu2519b7RD FuuI1Bqxvfj5ddp5uVCpzYKbZzxJSJ905eeqrjdCTQ+uT9w1cfepvarKMWy5czpD2G/uNt0e d67wpPSqwPnTW/bL/pl2IVwh3e/kxqSp3NuFviVxK+qaP+tWYinOSDTUYi4qTgQAhObok1sC AAA= X-CMS-MailID: 20200205093315eucas1p2e1ae9525ecdee6b9f2462f71a20b0fa4 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200205093315eucas1p2e1ae9525ecdee6b9f2462f71a20b0fa4 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200205093315eucas1p2e1ae9525ecdee6b9f2462f71a20b0fa4 References: <1580895185-24341-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 | 5 ++ docs/specs/memexpose-spec.txt | 168 ++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 173 insertions(+) create mode 100644 docs/specs/memexpose-spec.txt diff --git a/MAINTAINERS b/MAINTAINERS index 1f0bc72..73dd571 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1639,6 +1639,11 @@ 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: docs/specs/memexpose-spec.txt + nvme M: Keith Busch L: qemu-block@nongnu.org diff --git a/docs/specs/memexpose-spec.txt b/docs/specs/memexpose-spec.txt new file mode 100644 index 0000000..6266149 --- /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: + =20 + -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",shm_si= ze=3D0xN... + =20 +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... + =20 +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 Mon Feb 9 13:51:51 2026 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 1580895744194636.5508267223997; Wed, 5 Feb 2020 01:42:24 -0800 (PST) Received: from localhost ([::1]:43686 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izHCR-0003E7-1C for importer@patchew.org; Wed, 05 Feb 2020 04:42:23 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49977) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH3l-0000rB-Ki for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:31 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1izH3e-0004yP-Bg for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:25 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:38014) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1izH3d-0004eN-UJ for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:18 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20200205093316euoutp018d0905840addc411a8378a5753466920~wd84PqF6U2272522725euoutp01w for ; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200205093315eucas1p161b8aae2796f4857b0700c26d1920f6a~wd84Db7-u3063030630eucas1p1c; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eucas1p2.samsung.com ( [182.198.249.207]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id FD.39.60679.BDB8A3E5; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20200205093315eucas1p19f8f9a40b48b8917d5e2cd6c8a4f010e~wd83xBSFE3269132691eucas1p1a; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200205093315eusmtrp1020e979679240f3da540b84ac15a7a20~wd83wixEX1029010290eusmtrp1Y; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 5E.8D.08375.BDB8A3E5; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200205093315eusmtip230fdffe31af0b2cabcf8d54bd59f8e7a~wd83b05cg0072900729eusmtip2M; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20200205093316euoutp018d0905840addc411a8378a5753466920~wd84PqF6U2272522725euoutp01w DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580895196; bh=eA2VRTKHri+EcLrE9E0xX8BQK07jxM4QOEd083wQnCQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=Y+KgpVguNSLTQgM8+JaXqB6Dmb+rMSH3Z7yEhv4akMR29AqGSVDZdnWHjTC9aCPT0 D5Ybve+0DxcwYhbvgzICA74108TmlymgDZJTJV9COAl7XsVTOtc/PDED47LM6XBAHI DQl+FjoyKfVP04Y96+lP/jYO8dcEV5CP4ua8dhmg= X-AuditID: cbfec7f4-0e5ff7000001ed07-96-5e3a8bdb0371 From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 5/9] hw/misc/memexpose: Add core memexpose files Date: Wed, 5 Feb 2020 10:33:01 +0100 Message-Id: <1580895185-24341-6-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580895185-24341-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrJIsWRmVeSWpSXmKPExsWy7djP87q3u63iDPafNbbYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlbD5w lqWg9RRTxburnxgbGFs/MXYxcnJICJhILN//lRnEFhJYwSixaGcZhP2FUeL0Ee8uRi4g+zOj RM/zX0wwDcenzWWBSCxnlNi/5i0jhAPUcfPkTjaQKjYBNYmdRz6DrRARkJT43XUabAWzQIbE 81ndYLawgLvEuwnfwaayCKhKvJzzEayeVyBAYsHXBhaIbXISN891gtVzCgRKbPr0kQ1kmYTA ZTaJYzu+Qp3kIvFv+TU2CFtY4tXxLewQtozE6ck9UIPqJVru7GCCaO5glOhbOR2qwVriy4al QEUcQNdpSqzfpQ8RdpQ4tfYfI0hYQoBP4sZbQYj7+SQmbZvODBHmlehoE4Ko1pPofnKTCWbr ssZHUFs9JPrXLmKDhM8SRomjP96yTmCUn4WwbAEj4ypG8dTS4tz01GKjvNRyveLE3OLSvHS9 5PzcTYzABHD63/EvOxh3/Uk6xCjAwajEw7tikmWcEGtiWXFl7iFGCQ5mJRHe8/pAId6UxMqq 1KL8+KLSnNTiQ4zSHCxK4rzGi17GCgmkJ5akZqemFqQWwWSZODilGhhjlqzucbnO1GrG9rS3 NDfxbFl6+Lx/DEkbN9lfnr7LiPv6y8y+3oI0t4jgXvmlz7rYZS0XPSgQLBJhqliiH/TlQ1vH VNk7bxK9EiOaKjMsln4LZoqPaTbYU/rx5uL0XB/mSRpPjEJtS6brVTVfzig98fJrXBfnz2TX /UK+IYV/P8+919PSrMRSnJFoqMVcVJwIALvvzVr8AgAA X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrDLMWRmVeSWpSXmKPExsVy+t/xe7q3u63iDJpXKVnsufCYzWL/tn+s FnPOPGCxON67g8WBxePOtT1sHk+ubWbyOPhuD5PH+31X2QJYovRsivJLS1IVMvKLS2yVog0t jPQMLS30jEws9QyNzWOtjEyV9O1sUlJzMstSi/TtEvQyNh84y1LQeoqp4t3VT4wNjK2fGLsY OTkkBEwkjk+by9LFyMUhJLCUUeLGw19MEAkZiR+n17BB2MISf651sUEUfWKU2LdyDjNIgk1A TWLnkc9gk0QEJCV+d50GizMLZEnsnH0fbJCwgLvEuwnfwWwWAVWJl3M+gtXzCgRILPjawAKx QE7i5rlOsF5OgUCJTZ8+gi0WAqq59vUr6wRGvgWMDKsYRVJLi3PTc4sN9YoTc4tL89L1kvNz NzECQ3LbsZ+bdzBe2hh8iFGAg1GJh3fFJMs4IdbEsuLK3EOMEhzMSiK85/WBQrwpiZVVqUX5 8UWlOanFhxhNgY6ayCwlmpwPjJe8knhDU0NzC0tDc2NzYzMLJXHeDoGDMUIC6YklqdmpqQWp RTB9TBycUg2M85OE+Db8iDK8Km4QtU5XWPSHXu/PlbPfMJvwd5UkM2YvmDrhf8tZod+MM2yk 2LdwrC3I3j1z706/xVc9g9xvCpY+vG3h8YunJIDrA/c8xZRMd77Yf0aX40IdJv3uSfPkOTqR qX4Gw2xWvo1Tm63lT731ePi7WfmSu8JuQZdpu5aLzuu8O/2dEktxRqKhFnNRcSIAUMnCFV8C AAA= X-CMS-MailID: 20200205093315eucas1p19f8f9a40b48b8917d5e2cd6c8a4f010e X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200205093315eucas1p19f8f9a40b48b8917d5e2cd6c8a4f010e X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200205093315eucas1p19f8f9a40b48b8917d5e2cd6c8a4f010e References: <1580895185-24341-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 --- Kconfig.host | 3 + MAINTAINERS | 4 + 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, 1183 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 73dd571..7c98fef 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1643,6 +1643,10 @@ memexpose M: Igor Kotrasinski S: Maintained F: docs/specs/memexpose-spec.txt +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 =20 nvme M: Keith Busch diff --git a/Makefile b/Makefile index 461d40b..82e7259 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 115dc38..9c63c21 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 Mon Feb 9 13:51:51 2026 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 1580895398616309.32259148244077; Wed, 5 Feb 2020 01:36:38 -0800 (PST) Received: from localhost ([::1]:43620 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH6r-0004Kp-E7 for importer@patchew.org; Wed, 05 Feb 2020 04:36:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49864) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH3g-0000ht-BT for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:22 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1izH3e-0004wk-2d for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:20 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:38020) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1izH3d-0004lr-PW for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:18 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20200205093316euoutp01ebfdfdc03836fa6a6b1acb6d0039205d~wd84mgcjD2281022810euoutp01i for ; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmges1new.samsung.com (unknown [203.254.199.242]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200205093316eucas1p15f8292c186b65b72173d4ae737a3d5f2~wd84R7axw3063030630eucas1p1e; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges1new.samsung.com (EUCPMTA) with SMTP id CE.19.61286.CDB8A3E5; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20200205093315eucas1p1d39671ae41a5918bf60f10e110d4e938~wd84C8hIr3269132691eucas1p1b; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200205093315eusmtrp1b256f0e25641520329abc3226a864010~wd84CchSn1029010290eusmtrp1b; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id AE.8D.08375.BDB8A3E5; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200205093315eusmtip2f87bfe96c9baf2725353fa028c5069ab~wd83wLOR60077300773eusmtip2K; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20200205093316euoutp01ebfdfdc03836fa6a6b1acb6d0039205d~wd84mgcjD2281022810euoutp01i DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580895196; bh=2F49GVD50FFc7SohifeVm5zou/I4maN8aL4yyICPULM=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=e6Y3oBddYo1sK7yoqG+xm+ImvKPn7wTVNss2r7Z8Bf7kcGpUmUAC9knr/6jOI72++ h7wL6Jtwlf5Zf/BEO6Cyh5+Qp/axC6/Up4pwLcVTYBB9OHjaZXBWZQMSQmrjxpXBvt ZgVqre592nB72ia5UIPDzAS9sKg8yhJH+ZPCuUvE= X-AuditID: cbfec7f2-ef1ff7000001ef66-58-5e3a8bdcd28f From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 6/9] hw/misc/memexpose: Add memexpose pci device Date: Wed, 5 Feb 2020 10:33:02 +0100 Message-Id: <1580895185-24341-7-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580895185-24341-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrGIsWRmVeSWpSXmKPExsWy7djPc7p3uq3iDC6v5bDYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBlvDl0 kbXgpXXFs483GBsYj+p1MXJySAiYSMyeeoEZxBYSWMEo0TfDoouRC8j+wigxbcMeRgjnM6PE urPtQFUcYB33m/wh4suBitadZ4LruHLtERvIKDYBNYmdRz4zgtgiApISv7tOg61gFsiQeD6r G8wWFnCXmPv0DSPIUBYBVYnHv+NBwrwCARJfN/QyQ1wnJ3HzXCeYzSkQKLHp00c2kF0SApfZ JD4dewdV5CLx68clVghbWOLV8S3sELaMxOnJPSwQdr1Ey50dTBDNHUBvrpzOBpGwlviyYSkL yBHMApoS63fpQ4QdJWbPvgn1MJ/EjbeCEOfzSUzaNh0qzCvR0SYEUa0n0f3kJhPM1mWNj6C2 ekg8OneZGRI8SxglFvz7wzqBUX4WwrIFjIyrGMVTS4tz01OLDfNSy/WKE3OLS/PS9ZLzczcx AmP/9L/jn3Ywfr2UdIhRgINRiYd3xSTLOCHWxLLiytxDjBIczEoivOf1gUK8KYmVValF+fFF pTmpxYcYpTlYlMR5jRe9jBUSSE8sSc1OTS1ILYLJMnFwSjUw8sok3JixqEzMQOeYv827ZW/X bhb3KTx/+lvDUv8NV3qLTXub12uZrROO/dGitP7i24vuXyU2aeyTFS1a9eXIGtmo6H6PQJP2 GF8p2cNPePoWJl++P4lTmjvW23bpv1WPJS1XPrF3bXjF4KlixBUr+fO2s9411l/bjyjfsDfo uLj6fsTWxucGSizFGYmGWsxFxYkAr3GlnPkCAAA= X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrOLMWRmVeSWpSXmKPExsVy+t/xe7q3u63iDLZ9MrLYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehlvDl0kbXgpXXFs483GBsYj+p1MXJw SAiYSNxv8u9i5OIQEljKKPGl4T9LFyMnUFxG4sfpNWwQtrDEn2tdYLaQwCdGiXV9SSA2m4Ca xM4jnxlBbBEBSYnfXaeZQWxmgSyJnbPvM4HYwgLuEnOfvmEE2cUioCrx+Hc8SJhXIEDi64Ze ZojxchI3z3WC2ZwCgRKbPn2EWhUgce3rV9YJjHwLGBlWMYqklhbnpucWG+oVJ+YWl+al6yXn 525iBAbitmM/N+9gvLQx+BCjAAejEg/vikmWcUKsiWXFlbmHGCU4mJVEeM/rA4V4UxIrq1KL 8uOLSnNSiw8xmgLdNJFZSjQ5HxgleSXxhqaG5haWhubG5sZmFkrivB0CB2OEBNITS1KzU1ML Uotg+pg4OKUaGPVj5qVWsVlxeQh6/w6czPmII7RA4dTj67wOWosKZrbenXIt5OYZHvV5hyws HjsycSzblCnybvX+T40rK6umre7+G7+wuVf+oe+39mBd07frY2az8NovuHqvXfh7mV/Xmx7R qYyyfpNZPVh3FlpcjH2xPPFv+KNP7CXebtOd3NTKzjw2Uy90V2Ipzkg01GIuKk4EAPZxshZa AgAA X-CMS-MailID: 20200205093315eucas1p1d39671ae41a5918bf60f10e110d4e938 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200205093315eucas1p1d39671ae41a5918bf60f10e110d4e938 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200205093315eucas1p1d39671ae41a5918bf60f10e110d4e938 References: <1580895185-24341-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 7c98fef..0517556 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1647,6 +1647,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 Mon Feb 9 13:51:51 2026 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 1580895459695178.35372696132436; Wed, 5 Feb 2020 01:37:39 -0800 (PST) Received: from localhost ([::1]:43624 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH7q-0005tJ-GZ for importer@patchew.org; Wed, 05 Feb 2020 04:37:38 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49878) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH3g-0000iV-OB for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1izH3e-0004wf-2U for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:20 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:38024) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1izH3d-0004oU-Po for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:18 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20200205093316euoutp01017670c7811583e057200bf344bf8625~wd8485UOW2287922879euoutp01a for ; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200205093316eucas1p14053f56abe04a156d36b4fd96dc28044~wd84vG7Lx3273232732eucas1p1V; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id BF.8A.60698.CDB8A3E5; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20200205093316eucas1p1983761c17c0b3b6d70070bd9e1d99e23~wd84U0-Bc3269332693eucas1p1U; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200205093316eusmtrp141fbf836f679b0a13965ab9e75500ea1~wd84UXhs51029010290eusmtrp1d; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id FE.8D.08375.CDB8A3E5; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200205093315eusmtip269ab0d5182838f9db242b28df4b28388~wd84AZ69J0075000750eusmtip2M; Wed, 5 Feb 2020 09:33:15 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20200205093316euoutp01017670c7811583e057200bf344bf8625~wd8485UOW2287922879euoutp01a DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580895196; bh=U1WBsYzE1zwNDyuAmKB3GlVSl401j/4uBIO1UaB6OLY=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=QbvMfeuLkSVRnRtefSF8Nq6K30n3BY07Th0UNZhAWy73amBnCM0ZK2FtRPCup4l73 6rk6vU0EYYAdGvB6PDqI86rJULKIWqp8HPNF9GWii2ju/7v4tYnurdnKlxNR9vtXG6 Tf506g1FpBnpzYQicSJrxR/eKNSp7snNYpHJU9mU= X-AuditID: cbfec7f5-a0fff7000001ed1a-c5-5e3a8bdc5c4c From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 7/9] hw/misc/memexpose: Add memexpose memory region device Date: Wed, 5 Feb 2020 10:33:03 +0100 Message-Id: <1580895185-24341-8-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580895185-24341-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrBIsWRmVeSWpSXmKPExsWy7djPc7p3uq3iDPZuVbDYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBltN7+ zlow27LiUvsv5gbGdr0uRk4OCQETiZbbO1m6GLk4hARWMEqsaDrFCuF8YZTYO/0ylPOZUWLJ 5DXMMC19034xQiSWM0pc+HgToeXmvf3sIFVsAmoSO498ZgSxRQQkJX53nQbrZhbIkHg+qxvM FhYIlviwtJUFxGYRUJWYsGs2mM0rECDxbNYLFohtchI3z3WC1XMKBEps+vSRDWSZhMBlNolH J+YwQRS5SMyZtowRwhaWeHV8CzuELSNxenIP1KB6iZY7O5ggmjsYJfpWTmeDSFhLfNmwFKiI A+g6TYn1u/Qhwo4Spw61MoOEJQT4JG68FYS4n09i0rbpUGFeiY42IYhqPYnuJzeZYLYua3zE AlHiIXGmMQISPEsYJd4+28E+gVF+FsKuBYyMqxjFU0uLc9NTi43zUsv1ihNzi0vz0vWS83M3 MQLj//S/4193MO77k3SIUYCDUYmHN2CCZZwQa2JZcWXuIUYJDmYlEd7z+kAh3pTEyqrUovz4 otKc1OJDjNIcLErivMaLXsYKCaQnlqRmp6YWpBbBZJk4OKUaGGUsV/npV3keki/naGjSylv0 QsnqjXJaoK7TfZ2Ga20upYsXb7y0ytz279u09U8lVBeuzrXeasW4+eF2e+2HVntnTKyz0BGt EGrhzPzJICJwTUadWzpJfJ9acLOU5FWV8mkdKSqPNcVTwlUT+hd33jXa/d4tKOFBjX24tKij qdDjPavKjfqUWIozEg21mIuKEwEBEaEP+wIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRmVeSWpSXmKPExsVy+t/xe7p3uq3iDPbtZLPYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwROnZFOWXlqQqZOQXl9gqRRta GOkZWlroGZlY6hkam8daGZkq6dvZpKTmZJalFunbJehltN7+zlow27LiUvsv5gbGdr0uRk4O CQETib5pvxi7GLk4hASWMkr839fJDpGQkfhxeg0bhC0s8edaFxtE0SdGiV1vdrGCJNgE1CR2 HvnMCGKLCEhK/O46zQxiMwtkSeycfZ8JxBYWCJT49m4zWA2LgKrEhF2zWUBsXoEAiWezXrBA LJCTuHmuE6yXE6h+06ePYIuFgGquff3KOoGRbwEjwypGkdTS4tz03GJDveLE3OLSvHS95Pzc TYzAcNx27OfmHYyXNgYfYhTgYFTi4V0xyTJOiDWxrLgy9xCjBAezkgjveX2gEG9KYmVValF+ fFFpTmrxIUZToKMmMkuJJucDYyWvJN7Q1NDcwtLQ3Njc2MxCSZy3Q+BgjJBAemJJanZqakFq EUwfEwenVAOj5eGiFIGKZ36/6kvSSmcymh3bklkS56P3RUDkBl9u/sqQF7uSTq/mLV/+N/t4 2slXe7bv8jvauPSKAN9XB+2nupsEtvnb+n+9v6ic+3eGm02nINMr35DHB/iy063F/7M94Hwn WxWm5vdDXUi6N18uhj3qV4FsVbazjc8Hmc8Jmu+SnA7cu6PEUpyRaKjFXFScCADjm4dBXQIA AA== X-CMS-MailID: 20200205093316eucas1p1983761c17c0b3b6d70070bd9e1d99e23 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200205093316eucas1p1983761c17c0b3b6d70070bd9e1d99e23 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200205093316eucas1p1983761c17c0b3b6d70070bd9e1d99e23 References: <1580895185-24341-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 | 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 0517556..e016cff 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1648,6 +1648,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 Mon Feb 9 13:51:51 2026 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 158089553949076.01186114569884; Wed, 5 Feb 2020 01:38:59 -0800 (PST) Received: from localhost ([::1]:43644 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH98-0007k7-AB for importer@patchew.org; Wed, 05 Feb 2020 04:38:58 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49947) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH3j-0000oN-NX for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:26 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1izH3g-0005Hv-K4 for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:23 -0500 Received: from mailout1.w1.samsung.com ([210.118.77.11]:38028) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1izH3g-0004tO-7o for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:20 -0500 Received: from eucas1p2.samsung.com (unknown [182.198.249.207]) by mailout1.w1.samsung.com (KnoxPortal) with ESMTP id 20200205093317euoutp015307305565e66d32fd9375a9ae30ae98~wd85Vs1Y_2272522725euoutp01y for ; Wed, 5 Feb 2020 09:33:17 +0000 (GMT) Received: from eusmges3new.samsung.com (unknown [203.254.199.245]) by eucas1p1.samsung.com (KnoxPortal) with ESMTP id 20200205093316eucas1p145f5fb66adbfc7b10647e79fb2be701c~wd84-ansJ3063030630eucas1p1g; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges3new.samsung.com (EUCPMTA) with SMTP id 00.9A.60698.CDB8A3E5; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p1.samsung.com (KnoxPortal) with ESMTPA id 20200205093316eucas1p17ba08bfb90d6ddbf3fe5d10c1ee798f0~wd84xNQEF3269932699eucas1p1a; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmgms1.samsung.com (unknown [182.198.249.179]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200205093316eusmtrp15bffceee97e16800f077f220a349b9f9~wd84woqwJ1029010290eusmtrp1h; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms1.samsung.com (EUCPMTA) with SMTP id 40.9D.08375.CDB8A3E5; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200205093316eusmtip28fa9f5cac715e83348550134f511cc33~wd84QrtoM3043930439eusmtip2C; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout1.w1.samsung.com 20200205093317euoutp015307305565e66d32fd9375a9ae30ae98~wd85Vs1Y_2272522725euoutp01y DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580895197; bh=v5HP50D6ioOR5ulyJBYlkL4pC4y3uMp9hQG5R8Nz3DQ=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=CzJ0CygXrniTb5uny8LT4/xGFRL67m+ZsoiqqxnRpdkdOnXUDt7dyUtKnWoGkkIEd irmLIwjzgAtufPZFefd13MP418OFjNrNsGd1hvLff7heP7Rg25Day3pTBmL2F1X9YN EoiK89FTqTJnpG3A2G3rHhjo4GsoxvEzxf8FfqLg= X-AuditID: cbfec7f5-a29ff7000001ed1a-c6-5e3a8bdc3cf1 From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 8/9] hw/misc/memexpose: Add simple tests Date: Wed, 5 Feb 2020 10:33:04 +0100 Message-Id: <1580895185-24341-9-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580895185-24341-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrJIsWRmVeSWpSXmKPExsWy7djPc7p3uq3iDKb0mlrsufCYzWL/tn+s FnPOPGCxON67g8WBxePOtT1sHk+ubWbyOPhuD5PH+31X2QJYorhsUlJzMstSi/TtErgyfl7o Zy24l1Lx+Fg/awPjJ58uRk4OCQETie3Tmxm7GLk4hARWMEpc65jEBuF8YZRoPbkIyvnMKHF8 zkRWmJbZpx6yQCSWM0ocWrSbFa6lYeYMRpAqNgE1iZ1HPoPZIgKSEr+7TjOD2MwCGRLPZ3WD 2cIC9hIXnr5iAbFZBFQlnu+dxwRi8woESNy5Pg1qm5zEzXOdYPWcAoESmz59BDtJQuAym8TE ydsYIYpcJKY/XcQEYQtLvDq+hR3ClpE4PbmHBcKul2i5s4MJormDUaJv5XQ2iIS1xJcNS4GK OICu05RYv0sfIuwosfjIK0aQsIQAn8SNt4IQ9/NJTNo2nRkizCvR0SYEUa0n0f3kJhPM1mWN j6C2ekg0X+2AhuISRolj7fvZJjDKz0JYtoCRcRWjeGppcW56arFxXmq5XnFibnFpXrpecn7u JkZgAjj97/jXHYz7/iQdYhTgYFTi4Q2YYBknxJpYVlyZe4hRgoNZSYT3vD5QiDclsbIqtSg/ vqg0J7X4EKM0B4uSOK/xopexQgLpiSWp2ampBalFMFkmDk6pBkaF3edPRCfMWOUvsExw65n1 dhGK8x+xSNxR4dn49cTh91eKA+PcsqtMrhkcMnpxfOH8LZ/eN9RrZ5ydx5DQVHq/TPj/tqbM csXzgg9zrJ0qpOd1Op6/rM3CFNP7hEdTw+ti7PTI1fGfQnIc1BSmms6advpHfJBUd6XoklbD 48xx69vWV78J/6rEUpyRaKjFXFScCACnQ0kh/AIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrFLMWRmVeSWpSXmKPExsVy+t/xe7p3uq3iDPpXqVrsufCYzWL/tn+s FnPOPGCxON67g8WBxePOtT1sHk+ubWbyOPhuD5PH+31X2QJYovRsivJLS1IVMvKLS2yVog0t jPQMLS30jEws9QyNzWOtjEyV9O1sUlJzMstSi/TtEvQyfl7oZy24l1Lx+Fg/awPjJ58uRk4O CQETidmnHrJ0MXJxCAksZZTYsXI1O0RCRuLH6TVsELawxJ9rXWwQRZ8YJb5um8kEkmATUJPY eeQzI4gtIiAp8bvrNDOIzSyQJbFz9n2wGmEBe4kLT1+xgNgsAqoSz/fOA4vzCgRI3Lk+jRVi gZzEzXOdYL2cAoESmz59BFssBFRz7etX1gmMfAsYGVYxiqSWFuem5xYb6hUn5haX5qXrJefn bmIEhuO2Yz8372C8tDH4EKMAB6MSD++KSZZxQqyJZcWVuYcYJTiYlUR4z+sDhXhTEiurUovy 44tKc1KLDzGaAh01kVlKNDkfGCt5JfGGpobmFpaG5sbmxmYWSuK8HQIHY4QE0hNLUrNTUwtS i2D6mDg4pRoY0xU9+m4aq+k4ezZ+TQiNurTo5XN5Jqsbc5XfTrZfePvCrZ/PNlUw3mEpb1pt c0/i2aKlKbIvwswWP9GTv3qzg6NUvMPA50DFx1Pfr25jy3+5RfKk4t2LRhKmJzpLV200iGb6 evXT50mRbY9MHqZMLeZ9kNA45cJBO/Yms/tmESurs3fb7ru6TYmlOCPRUIu5qDgRAHcHwa1d AgAA X-CMS-MailID: 20200205093316eucas1p17ba08bfb90d6ddbf3fe5d10c1ee798f0 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200205093316eucas1p17ba08bfb90d6ddbf3fe5d10c1ee798f0 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200205093316eucas1p17ba08bfb90d6ddbf3fe5d10c1ee798f0 References: <1580895185-24341-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 + 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 e016cff..6f30382 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -1650,6 +1650,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/qtest/memexpose-test.c =20 nvme M: Keith Busch diff --git a/tests/qtest/Makefile.include b/tests/qtest/Makefile.include index eb0f23b..f19da40 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/test-arm-mptimer$(EXESUF): tests/qtest/test-arm-mptimer.o tests/qtest/numa-test$(EXESUF): tests/qtest/numa-test.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 Mon Feb 9 13:51:51 2026 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 1580895599407264.71147390329565; Wed, 5 Feb 2020 01:39:59 -0800 (PST) Received: from localhost ([::1]:43656 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izHA5-0000oE-5r for importer@patchew.org; Wed, 05 Feb 2020 04:39:57 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:49890) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1izH3h-0000jL-9F for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:23 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1izH3f-00054S-4a for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:21 -0500 Received: from mailout2.w1.samsung.com ([210.118.77.12]:41566) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1izH3e-0004xZ-Pl for qemu-devel@nongnu.org; Wed, 05 Feb 2020 04:33:18 -0500 Received: from eucas1p1.samsung.com (unknown [182.198.249.206]) by mailout2.w1.samsung.com (KnoxPortal) with ESMTP id 20200205093317euoutp0215c1cc0fbe42fa57edf6c038e154c329~wd85oHY1f1429014290euoutp02h for ; Wed, 5 Feb 2020 09:33:17 +0000 (GMT) Received: from eusmges2new.samsung.com (unknown [203.254.199.244]) by eucas1p2.samsung.com (KnoxPortal) with ESMTP id 20200205093317eucas1p25d1445ba03cefeea41c146eb62ce70a8~wd85Sacka1343613436eucas1p25; Wed, 5 Feb 2020 09:33:17 +0000 (GMT) Received: from eucas1p1.samsung.com ( [182.198.249.206]) by eusmges2new.samsung.com (EUCPMTA) with SMTP id 1F.39.60679.DDB8A3E5; Wed, 5 Feb 2020 09:33:17 +0000 (GMT) Received: from eusmtrp1.samsung.com (unknown [182.198.249.138]) by eucas1p2.samsung.com (KnoxPortal) with ESMTPA id 20200205093316eucas1p2b1b7b0cec7991ec53f26bd1444b7e596~wd85Adxar1341413414eucas1p29; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmgms2.samsung.com (unknown [182.198.249.180]) by eusmtrp1.samsung.com (KnoxPortal) with ESMTP id 20200205093316eusmtrp19f6f09f53f4e984eec28ec1f1649cc97~wd85ADF8l1029010290eusmtrp1k; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from eusmtip2.samsung.com ( [203.254.199.222]) by eusmgms2.samsung.com (EUCPMTA) with SMTP id 9A.9A.07950.CDB8A3E5; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) Received: from AMDC3304.digital.local (unknown [106.120.51.21]) by eusmtip2.samsung.com (KnoxPortal) with ESMTPA id 20200205093316eusmtip29c56a815c32c0e8bffd05bc6b6c4cde6~wd84uzYT00075700757eusmtip2M; Wed, 5 Feb 2020 09:33:16 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 mailout2.w1.samsung.com 20200205093317euoutp0215c1cc0fbe42fa57edf6c038e154c329~wd85oHY1f1429014290euoutp02h DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=samsung.com; s=mail20170921; t=1580895197; bh=2EdIg2dqS4is2/71/wtKDkcAjFpedYTyvl4ZZh7iwes=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=j4JdmbobcWRIstHh552DYk5UOjm+m38MEJfxzJoQQdhEqZSd8vcBKKq779K7UrxN7 jE31U+loVUg+8dy6WvkzE1d+Wk4+hmdOY5bJbogX9MtBKrlFTgPItdXYJhVyb4OyNP ijUcCMihRaGE5R06H8cTBX+hHyihPmrDz5SnyaKY= X-AuditID: cbfec7f4-0cbff7000001ed07-9b-5e3a8bdd4b7b From: i.kotrasinsk@partner.samsung.com To: qemu-devel@nongnu.org Subject: [RFC PATCH v2 9/9] hw/arm/virt: Hack in support for memexpose device Date: Wed, 5 Feb 2020 10:33:05 +0100 Message-Id: <1580895185-24341-10-git-send-email-i.kotrasinsk@partner.samsung.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1580895185-24341-1-git-send-email-i.kotrasinsk@partner.samsung.com> X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFnrOIsWRmVeSWpSXmKPExsWy7djPc7p3u63iDD6e4bbYc+Exm8X+bf9Y LeacecBicbx3B4sDi8eda3vYPJ5c28zkcfDdHiaP9/uusgWwRHHZpKTmZJalFunbJXBltO6Z x16w1q5iwWWuBsadul2MnBwSAiYSi67eZuli5OIQEljBKHHwfD8ThPOFUWLFt3VQzmdGiRuP trHBtGza85MZIrGcUeLe1TcsCC0dP8Cq2ATUJHYe+cwIYosISEr87jrNDGIzC2RIPJ/VDWYL C/hLnJr3DMxmEVCVuHV0Jlgvr0CgRNf080wQ2+Qkbp7rBKvhBIpv+vQR6orLbBJnJgVD2C4S y9/sZIawhSVeHd/CDmHLSJye3MMCYddLtNzZAfaOhEAHo0TfyulQg6wlvmxYClTEAXScpsT6 XfoQYUeJDwuns4KEJQT4JG68FYQ4n09i0rbpzBBhXomONiGIaj2J7ic3mWC2Lmt8BLXVQ+Lm 5XvQsFrCKLGu5z3LBEb5WQjLFjAyrmIUTy0tzk1PLTbKSy3XK07MLS7NS9dLzs/dxAiM/tP/ jn/ZwbjrT9IhRgEORiUe3hWTLOOEWBPLiitzDzFKcDArifCe1wcK8aYkVlalFuXHF5XmpBYf YpTmYFES5zVe9DJWSCA9sSQ1OzW1ILUIJsvEwSnVwMha/kg16Ep10F+xeW++rztyYGWWGedt jwcJnQ3cCjF/tS0c5Jcmyuv13GqK+nlk09NbSruf3XfTrLZnUymRtd3QXNb65kkZl4i79YaY JUUPtwk07cgNn3mzOvBpBsNC2yU/DVofyeSrrJn6q2rC/co3C17sFzl8MqbqRt8Ulmn1+xVq 8ov2T1diKc5INNRiLipOBAD/2Jep+gIAAA== X-Brightmail-Tracker: H4sIAAAAAAAAA+NgFjrJLMWRmVeSWpSXmKPExsVy+t/xe7p3uq3iDHa3mVnsufCYzWL/tn+s FnPOPGCxON67g8WBxePOtT1sHk+ubWbyOPhuD5PH+31X2QJYovRsivJLS1IVMvKLS2yVog0t jPQMLS30jEws9QyNzWOtjEyV9O1sUlJzMstSi/TtEvQyWvfMYy9Ya1ex4DJXA+NO3S5GTg4J AROJTXt+MncxcnEICSxllJi/6QAbREJG4sfpNVC2sMSfa11sEEWfGCV+fr3NDJJgE1CT2Hnk MyOILSIgKfG76zRYnFkgS2Ln7PtMILawgK/E+Xc/2UFsFgFViVtHZ4IN5RUIlOiafp4JYoGc xM1znWC9nEDxTZ8+gtUICQRIXPv6lXUCI98CRoZVjCKppcW56bnFRnrFibnFpXnpesn5uZsY gcG47djPLTsYu94FH2IU4GBU4uENmGAZJ8SaWFZcmXuIUYKDWUmE97w+UIg3JbGyKrUoP76o NCe1+BCjKdBRE5mlRJPzgZGSVxJvaGpobmFpaG5sbmxmoSTO2yFwMEZIID2xJDU7NbUgtQim j4mDU6qBcer0k60b6zQjD2Q1bz2ZOJsz2HGe3eY1qgGP3W+FBYpMqw//f3nFs5vCMVnLqta/ 5xdacX591pEdzieFBI0Mi7xLV2hdcvvyI01v50/3FxvFb1zYNq84tEqbs/bf+6ZNmX18E57x 79sy8aL1+idZQekBy5zfXzn+ToX78xSn2RUeXDzpr4tE9iixFGckGmoxFxUnAgBycBdHXAIA AA== X-CMS-MailID: 20200205093316eucas1p2b1b7b0cec7991ec53f26bd1444b7e596 X-Msg-Generator: CA Content-Type: text/plain; charset="utf-8" X-RootMTR: 20200205093316eucas1p2b1b7b0cec7991ec53f26bd1444b7e596 X-EPHeader: CA CMS-TYPE: 201P X-CMS-RootMailID: 20200205093316eucas1p2b1b7b0cec7991ec53f26bd1444b7e596 References: <1580895185-24341-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