{"id":1954400,"url":"http://patchwork.ozlabs.org/api/patches/1954400/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/patch/1719776434-435013-2-git-send-email-steven.sistare@oracle.com/","project":{"id":14,"url":"http://patchwork.ozlabs.org/api/projects/14/?format=json","name":"QEMU Development","link_name":"qemu-devel","list_id":"qemu-devel.nongnu.org","list_email":"qemu-devel@nongnu.org","web_url":"","scm_url":"","webscm_url":"","list_archive_url":"","list_archive_url_format":"","commit_url_format":""},"msgid":"<1719776434-435013-2-git-send-email-steven.sistare@oracle.com>","list_archive_url":null,"date":"2024-06-30T19:40:24","name":"[V2,01/11] machine: alloc-anon option","commit_ref":null,"pull_url":null,"state":"new","archived":false,"hash":"291b07763a7afeedb055d7302d085080ac37b77c","submitter":{"id":71906,"url":"http://patchwork.ozlabs.org/api/people/71906/?format=json","name":"Steve Sistare","email":"steven.sistare@oracle.com"},"delegate":null,"mbox":"http://patchwork.ozlabs.org/project/qemu-devel/patch/1719776434-435013-2-git-send-email-steven.sistare@oracle.com/mbox/","series":[{"id":413181,"url":"http://patchwork.ozlabs.org/api/series/413181/?format=json","web_url":"http://patchwork.ozlabs.org/project/qemu-devel/list/?series=413181","date":"2024-06-30T19:40:26","name":"Live update: cpr-exec","version":2,"mbox":"http://patchwork.ozlabs.org/series/413181/mbox/"}],"comments":"http://patchwork.ozlabs.org/api/patches/1954400/comments/","check":"pending","checks":"http://patchwork.ozlabs.org/api/patches/1954400/checks/","tags":{},"related":[],"headers":{"Return-Path":"<qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org>","X-Original-To":"incoming@patchwork.ozlabs.org","Delivered-To":"patchwork-incoming@legolas.ozlabs.org","Authentication-Results":["legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=oracle.com header.i=@oracle.com header.a=rsa-sha256\n header.s=corp-2023-11-20 header.b=nTOyazqK;\n\tdkim-atps=neutral","legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org\n (client-ip=209.51.188.17; helo=lists.gnu.org;\n envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org;\n receiver=patchwork.ozlabs.org)"],"Received":["from lists.gnu.org (lists.gnu.org [209.51.188.17])\n\t(using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits))\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4WC01B1Y1wz1xpV\n\tfor <incoming@patchwork.ozlabs.org>; Mon,  1 Jul 2024 05:41:49 +1000 (AEST)","from localhost ([::1] helo=lists1p.gnu.org)\n\tby lists.gnu.org with esmtp (Exim 4.90_1)\n\t(envelope-from <qemu-devel-bounces@nongnu.org>)\n\tid 1sO0Pz-00005d-4P; Sun, 30 Jun 2024 15:40:59 -0400","from eggs.gnu.org ([2001:470:142:3::10])\n by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <steven.sistare@oracle.com>)\n id 1sO0Pu-0008S5-D7\n for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:40:54 -0400","from mx0a-00069f02.pphosted.com ([205.220.165.32])\n by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256)\n (Exim 4.90_1) (envelope-from <steven.sistare@oracle.com>)\n id 1sO0Pn-0004O1-Lq\n for qemu-devel@nongnu.org; Sun, 30 Jun 2024 15:40:51 -0400","from pps.filterd (m0246617.ppops.net [127.0.0.1])\n by mx0b-00069f02.pphosted.com (8.18.1.2/8.18.1.2) with ESMTP id\n 45UJcvCO020058;\n Sun, 30 Jun 2024 19:40:40 GMT","from iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com\n (iadpaimrmta02.appoci.oracle.com [147.154.18.20])\n by mx0b-00069f02.pphosted.com (PPS) with ESMTPS id 402att9e1v-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK);\n Sun, 30 Jun 2024 19:40:39 +0000 (GMT)","from pps.filterd\n (iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1])\n by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (8.17.1.19/8.17.1.19)\n with ESMTP id 45UIwiMG018459; Sun, 30 Jun 2024 19:40:38 GMT","from pps.reinject (localhost [127.0.0.1])\n by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with ESMTPS id\n 4028qc16cw-1\n (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK);\n Sun, 30 Jun 2024 19:40:38 +0000","from iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com\n (iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com [127.0.0.1])\n by pps.reinject (8.17.1.5/8.17.1.5) with ESMTP id 45UJeaSQ014044;\n Sun, 30 Jun 2024 19:40:37 GMT","from ca-dev63.us.oracle.com (ca-dev63.us.oracle.com [10.211.8.221])\n by iadpaimrmta02.imrmtpd1.prodappiadaev1.oraclevcn.com (PPS) with\n ESMTP id 4028qc16cc-2; Sun, 30 Jun 2024 19:40:37 +0000"],"DKIM-Signature":"v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=\n from:to:cc:subject:date:message-id:in-reply-to:references; s=\n corp-2023-11-20; bh=3raiXCm8kRFGnYk1UPCeOPFpx20xzLtvntIeQ9Dkyxg=; b=\n nTOyazqKQSjW8LQP4azBJFbllje1B+NYVtLw44T/XhuvOyoWtet5VNLEyKbXbVr4\n krdeu1XUMY1iLnaOPV8XBj+pwhXTkfBeEsGPQGpR99ZuaSSVDVknXLlXaaU1AHiV\n t06F565AqlLOS0Nac/lu7gnGPL9gW2V3rGFE23e6A2f4hLapW5eHYx4cynWE03/n\n AJGJP/RcnEUQjOFE4dFU5+XFhWFT3hQ+iMXWY2q0k/CjCPirrs+ClPXhwGTBwL+r\n fbWTHNMG3bEKp2dKlwVOCDcskzWg4nZiNu1LHOSk57K4c5oSKILoRAHfSiIwm8qs\n L1HvQg/a2hpj9byramVirw==","From":"Steve Sistare <steven.sistare@oracle.com>","To":"qemu-devel@nongnu.org","Cc":"Peter Xu <peterx@redhat.com>, Fabiano Rosas <farosas@suse.de>,\n David Hildenbrand <david@redhat.com>,\n Marcel Apfelbaum <marcel.apfelbaum@gmail.com>,\n Eduardo Habkost <eduardo@habkost.net>,\n Philippe Mathieu-Daude <philmd@linaro.org>,\n Paolo Bonzini <pbonzini@redhat.com>,\n \"Daniel P. Berrange\" <berrange@redhat.com>,\n Markus Armbruster <armbru@redhat.com>,\n Steve Sistare <steven.sistare@oracle.com>","Subject":"[PATCH V2 01/11] machine: alloc-anon option","Date":"Sun, 30 Jun 2024 12:40:24 -0700","Message-Id":"<1719776434-435013-2-git-send-email-steven.sistare@oracle.com>","X-Mailer":"git-send-email 1.8.3.1","In-Reply-To":"<1719776434-435013-1-git-send-email-steven.sistare@oracle.com>","References":"<1719776434-435013-1-git-send-email-steven.sistare@oracle.com>","X-Proofpoint-Virus-Version":"vendor=baseguard\n engine=ICAP:2.0.293,Aquarius:18.0.1039,Hydra:6.0.680,FMLib:17.12.28.16\n definitions=2024-06-30_16,2024-06-28_01,2024-05-17_01","X-Proofpoint-Spam-Details":"rule=notspam policy=default score=0 suspectscore=0\n malwarescore=0\n adultscore=0 bulkscore=0 mlxlogscore=999 phishscore=0 spamscore=0\n mlxscore=0 classifier=spam adjust=0 reason=mlx scancount=1\n engine=8.12.0-2406180000 definitions=main-2406300157","X-Proofpoint-GUID":"LLqZLkOEv4-f0KPQWrpRiUV3jHhgo8HX","X-Proofpoint-ORIG-GUID":"LLqZLkOEv4-f0KPQWrpRiUV3jHhgo8HX","Received-SPF":"pass client-ip=205.220.165.32;\n envelope-from=steven.sistare@oracle.com; helo=mx0a-00069f02.pphosted.com","X-Spam_score_int":"-20","X-Spam_score":"-2.1","X-Spam_bar":"--","X-Spam_report":"(-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_MED=-0.001,\n DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1,\n RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, SPF_HELO_NONE=0.001,\n SPF_PASS=-0.001 autolearn=ham autolearn_force=no","X-Spam_action":"no action","X-BeenThere":"qemu-devel@nongnu.org","X-Mailman-Version":"2.1.29","Precedence":"list","List-Id":"<qemu-devel.nongnu.org>","List-Unsubscribe":"<https://lists.nongnu.org/mailman/options/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=unsubscribe>","List-Archive":"<https://lists.nongnu.org/archive/html/qemu-devel>","List-Post":"<mailto:qemu-devel@nongnu.org>","List-Help":"<mailto:qemu-devel-request@nongnu.org?subject=help>","List-Subscribe":"<https://lists.nongnu.org/mailman/listinfo/qemu-devel>,\n <mailto:qemu-devel-request@nongnu.org?subject=subscribe>","Errors-To":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org","Sender":"qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org"},"content":"Allocate anonymous memory using mmap MAP_ANON or memfd_create depending\non the value of the anon-alloc machine property.  This affects\nmemory-backend-ram objects, guest RAM created with the global -m option\nbut without an associated memory-backend object and without the -mem-path\noption, and various memory regions such as ROMs that are allocated when\ndevices are created.  This option does not affect memory-backend-file,\nmemory-backend-memfd, or memory-backend-epc objects.\n\nThe memfd option is intended to support new migration modes, in which the\nmemory region can be transferred in place to a new QEMU process, by sending\nthe memfd file descriptor to the process.  Memory contents are preserved,\nand if the mode also transfers device descriptors, then pages that are\nlocked in memory for DMA remain locked.  This behavior is a pre-requisite\nfor supporting vfio, vdpa, and iommufd devices with the new modes.\n\nTo access the same memory in the old and new QEMU processes, the memory\nmust be mapped shared.  Therefore, the implementation always sets\nRAM_SHARED if alloc-anon=memfd, except for memory-backend-ram, where the\nuser must explicitly specify the share option.  In lieu of defining a new\nRAM flag, at the lowest level the implementation uses RAM_SHARED with fd=-1\nas the condition for calling memfd_create.\n\nSigned-off-by: Steve Sistare <steven.sistare@oracle.com>\n---\n hw/core/machine.c   | 24 ++++++++++++++++++++++++\n include/hw/boards.h |  1 +\n qapi/machine.json   | 14 ++++++++++++++\n qemu-options.hx     | 13 +++++++++++++\n system/memory.c     | 12 +++++++++---\n system/physmem.c    | 38 +++++++++++++++++++++++++++++++++++++-\n system/trace-events |  3 +++\n 7 files changed, 101 insertions(+), 4 deletions(-)","diff":"diff --git a/hw/core/machine.c b/hw/core/machine.c\nindex 655d75c..7ca2ad0 100644\n--- a/hw/core/machine.c\n+++ b/hw/core/machine.c\n@@ -454,6 +454,20 @@ static void machine_set_mem_merge(Object *obj, bool value, Error **errp)\n     ms->mem_merge = value;\n }\n \n+static int machine_get_anon_alloc(Object *obj, Error **errp)\n+{\n+    MachineState *ms = MACHINE(obj);\n+\n+    return ms->anon_alloc;\n+}\n+\n+static void machine_set_anon_alloc(Object *obj, int value, Error **errp)\n+{\n+    MachineState *ms = MACHINE(obj);\n+\n+    ms->anon_alloc = value;\n+}\n+\n static bool machine_get_usb(Object *obj, Error **errp)\n {\n     MachineState *ms = MACHINE(obj);\n@@ -1066,6 +1080,11 @@ static void machine_class_init(ObjectClass *oc, void *data)\n     object_class_property_set_description(oc, \"mem-merge\",\n         \"Enable/disable memory merge support\");\n \n+    object_class_property_add_enum(oc, \"anon-alloc\", \"AnonAllocOption\",\n+                                   &AnonAllocOption_lookup,\n+                                   machine_get_anon_alloc,\n+                                   machine_set_anon_alloc);\n+\n     object_class_property_add_bool(oc, \"usb\",\n         machine_get_usb, machine_set_usb);\n     object_class_property_set_description(oc, \"usb\",\n@@ -1416,6 +1435,11 @@ static bool create_default_memdev(MachineState *ms, const char *path, Error **er\n     if (!object_property_set_int(obj, \"size\", ms->ram_size, errp)) {\n         goto out;\n     }\n+    if (!object_property_set_bool(obj, \"share\",\n+                                  ms->anon_alloc == ANON_ALLOC_OPTION_MEMFD,\n+                                  errp)) {\n+        goto out;\n+    }\n     object_property_add_child(object_get_objects_root(), mc->default_ram_id,\n                               obj);\n     /* Ensure backend's memory region name is equal to mc->default_ram_id */\ndiff --git a/include/hw/boards.h b/include/hw/boards.h\nindex 73ad319..77f16ad 100644\n--- a/include/hw/boards.h\n+++ b/include/hw/boards.h\n@@ -383,6 +383,7 @@ struct MachineState {\n     bool enable_graphics;\n     ConfidentialGuestSupport *cgs;\n     HostMemoryBackend *memdev;\n+    AnonAllocOption anon_alloc;\n     /*\n      * convenience alias to ram_memdev_id backend memory region\n      * or to numa container memory region\ndiff --git a/qapi/machine.json b/qapi/machine.json\nindex 2fd3e9c..9173953 100644\n--- a/qapi/machine.json\n+++ b/qapi/machine.json\n@@ -1881,3 +1881,17 @@\n { 'command': 'x-query-interrupt-controllers',\n   'returns': 'HumanReadableText',\n   'features': [ 'unstable' ]}\n+\n+##\n+# @AnonAllocOption:\n+#\n+# An enumeration of the options for allocating anonymous guest memory.\n+#\n+# @mmap: allocate using mmap MAP_ANON\n+#\n+# @memfd: allocate using memfd_create\n+#\n+# Since: 9.1\n+##\n+{ 'enum': 'AnonAllocOption',\n+  'data': [ 'mmap', 'memfd' ] }\ndiff --git a/qemu-options.hx b/qemu-options.hx\nindex 8ca7f34..595b693 100644\n--- a/qemu-options.hx\n+++ b/qemu-options.hx\n@@ -38,6 +38,7 @@ DEF(\"machine\", HAS_ARG, QEMU_OPTION_machine, \\\n     \"                nvdimm=on|off controls NVDIMM support (default=off)\\n\"\n     \"                memory-encryption=@var{} memory encryption object to use (default=none)\\n\"\n     \"                hmat=on|off controls ACPI HMAT support (default=off)\\n\"\n+    \"                anon-alloc=mmap|memfd allocate anonymous guest RAM using mmap MAP_ANON or memfd_create (default: mmap)\\n\"\n     \"                memory-backend='backend-id' specifies explicitly provided backend for main RAM (default=none)\\n\"\n     \"                cxl-fmw.0.targets.0=firsttarget,cxl-fmw.0.targets.1=secondtarget,cxl-fmw.0.size=size[,cxl-fmw.0.interleave-granularity=granularity]\\n\",\n     QEMU_ARCH_ALL)\n@@ -101,6 +102,18 @@ SRST\n         Enables or disables ACPI Heterogeneous Memory Attribute Table\n         (HMAT) support. The default is off.\n \n+    ``anon-alloc=mmap|memfd``\n+        Allocate anonymous guest RAM using mmap MAP_ANON (the default)\n+        or memfd_create.  This affects memory-backend-ram objects,\n+        RAM created with the global -m option but without an\n+        associated memory-backend object and without the -mem-path\n+        option, and various memory regions such as ROMs that are\n+        allocated when devices are created.  This option does not\n+        affect memory-backend-file, memory-backend-memfd, or\n+        memory-backend-epc objects.\n+\n+        Some migration modes require anon-alloc=memfd.\n+\n     ``memory-backend='id'``\n         An alternative to legacy ``-mem-path`` and ``mem-prealloc`` options.\n         Allows to use a memory backend as main RAM.\ndiff --git a/system/memory.c b/system/memory.c\nindex 2d69521..28a837d 100644\n--- a/system/memory.c\n+++ b/system/memory.c\n@@ -1552,8 +1552,10 @@ bool memory_region_init_ram_nomigrate(MemoryRegion *mr,\n                                       uint64_t size,\n                                       Error **errp)\n {\n+    uint32_t flags = (current_machine->anon_alloc == ANON_ALLOC_OPTION_MEMFD) ?\n+                     RAM_SHARED : 0;\n     return memory_region_init_ram_flags_nomigrate(mr, owner, name,\n-                                                  size, 0, errp);\n+                                                  size, flags, errp);\n }\n \n bool memory_region_init_ram_flags_nomigrate(MemoryRegion *mr,\n@@ -1713,8 +1715,10 @@ bool memory_region_init_rom_nomigrate(MemoryRegion *mr,\n                                       uint64_t size,\n                                       Error **errp)\n {\n+    uint32_t flags = (current_machine->anon_alloc == ANON_ALLOC_OPTION_MEMFD) ?\n+                     RAM_SHARED : 0;\n     if (!memory_region_init_ram_flags_nomigrate(mr, owner, name,\n-                                                size, 0, errp)) {\n+                                                size, flags, errp)) {\n          return false;\n     }\n     mr->readonly = true;\n@@ -1731,6 +1735,8 @@ bool memory_region_init_rom_device_nomigrate(MemoryRegion *mr,\n                                              Error **errp)\n {\n     Error *err = NULL;\n+    uint32_t flags = (current_machine->anon_alloc == ANON_ALLOC_OPTION_MEMFD) ?\n+                     RAM_SHARED : 0;\n     assert(ops);\n     memory_region_init(mr, owner, name, size);\n     mr->ops = ops;\n@@ -1738,7 +1744,7 @@ bool memory_region_init_rom_device_nomigrate(MemoryRegion *mr,\n     mr->terminates = true;\n     mr->rom_device = true;\n     mr->destructor = memory_region_destructor_ram;\n-    mr->ram_block = qemu_ram_alloc(size, 0, mr, &err);\n+    mr->ram_block = qemu_ram_alloc(size, flags, mr, &err);\n     if (err) {\n         mr->size = int128_zero();\n         object_unparent(OBJECT(mr));\ndiff --git a/system/physmem.c b/system/physmem.c\nindex 33d09f7..efe95ff 100644\n--- a/system/physmem.c\n+++ b/system/physmem.c\n@@ -47,6 +47,7 @@\n #include \"qemu/qemu-print.h\"\n #include \"qemu/log.h\"\n #include \"qemu/memalign.h\"\n+#include \"qemu/memfd.h\"\n #include \"exec/memory.h\"\n #include \"exec/ioport.h\"\n #include \"sysemu/dma.h\"\n@@ -54,6 +55,7 @@\n #include \"sysemu/hw_accel.h\"\n #include \"sysemu/xen-mapcache.h\"\n #include \"trace/trace-root.h\"\n+#include \"trace.h\"\n \n #ifdef CONFIG_FALLOCATE_PUNCH_HOLE\n #include <linux/falloc.h>\n@@ -69,6 +71,8 @@\n \n #include \"qemu/pmem.h\"\n \n+#include \"qapi/qapi-types-migration.h\"\n+#include \"migration/options.h\"\n #include \"migration/vmstate.h\"\n \n #include \"qemu/range.h\"\n@@ -1828,6 +1832,32 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)\n                 qemu_mutex_unlock_ramlist();\n                 return;\n             }\n+\n+        } else if (new_block->flags & RAM_SHARED) {\n+            size_t max_length = new_block->max_length;\n+            MemoryRegion *mr = new_block->mr;\n+            const char *name = memory_region_name(mr);\n+\n+            new_block->mr->align = QEMU_VMALLOC_ALIGN;\n+\n+            if (new_block->fd == -1) {\n+                new_block->fd = qemu_memfd_create(name, max_length + mr->align,\n+                                                  0, 0, 0, errp);\n+            }\n+\n+            if (new_block->fd >= 0) {\n+                int mfd = new_block->fd;\n+                qemu_set_cloexec(mfd);\n+                new_block->host = file_ram_alloc(new_block, max_length, mfd,\n+                                                 false, 0, errp);\n+            }\n+            if (!new_block->host) {\n+                qemu_mutex_unlock_ramlist();\n+                return;\n+            }\n+            memory_try_enable_merging(new_block->host, new_block->max_length);\n+            free_on_error = true;\n+\n         } else {\n             new_block->host = qemu_anon_ram_alloc(new_block->max_length,\n                                                   &new_block->mr->align,\n@@ -1911,6 +1941,9 @@ static void ram_block_add(RAMBlock *new_block, Error **errp)\n         ram_block_notify_add(new_block->host, new_block->used_length,\n                              new_block->max_length);\n     }\n+    trace_ram_block_add(memory_region_name(new_block->mr), new_block->flags,\n+                        new_block->fd, new_block->used_length,\n+                        new_block->max_length);\n     return;\n \n out_free:\n@@ -2097,8 +2130,11 @@ RAMBlock *qemu_ram_alloc_resizeable(ram_addr_t size, ram_addr_t maxsz,\n                                                      void *host),\n                                      MemoryRegion *mr, Error **errp)\n {\n+    uint32_t flags = (current_machine->anon_alloc == ANON_ALLOC_OPTION_MEMFD) ?\n+                     RAM_SHARED : 0;\n+    flags |= RAM_RESIZEABLE;\n     return qemu_ram_alloc_internal(size, maxsz, resized, NULL,\n-                                   RAM_RESIZEABLE, mr, errp);\n+                                   flags, mr, errp);\n }\n \n static void reclaim_ramblock(RAMBlock *block)\ndiff --git a/system/trace-events b/system/trace-events\nindex 69c9044..f8ebf42 100644\n--- a/system/trace-events\n+++ b/system/trace-events\n@@ -38,3 +38,6 @@ dirtylimit_state_finalize(void)\n dirtylimit_throttle_pct(int cpu_index, uint64_t pct, int64_t time_us) \"CPU[%d] throttle percent: %\" PRIu64 \", throttle adjust time %\"PRIi64 \" us\"\n dirtylimit_set_vcpu(int cpu_index, uint64_t quota) \"CPU[%d] set dirty page rate limit %\"PRIu64\n dirtylimit_vcpu_execute(int cpu_index, int64_t sleep_time_us) \"CPU[%d] sleep %\"PRIi64 \" us\"\n+\n+#physmem.c\n+ram_block_add(const char *name, uint32_t flags, int fd, size_t used_length, size_t max_length) \"%s, flags %u, fd %d, len %lu, maxlen %lu\"\n","prefixes":["V2","01/11"]}