From nobody Fri Dec 19 13:06:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1747965911; cv=none; d=zohomail.com; s=zohoarc; b=YTxDahFRya8VfofIYyQrIRl+d5+xFmkJK41UkSGt6Yr7z59OfEcoW9U4BsRYRy6w8ROZTDkxKiYttF6AuUqc8HqBOAcB3Hjw9jJa+fO2Nqm3ijug26mtlWYldP7jvYHtaZoiTyy0yoAziLIwkNukHKxOU8UPoKMX2mjvCc2VrE8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747965911; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=cE/rElsE+sxHsKrFd8ZdZIhXnJuddVorLW+oNsQpqho=; b=PKhVGQEaaABdiIOlZAnWccHViyQEusPYQuE40tfhIZJJ16l+ciqKSf9q5LURX0bCQEgwE/JWKP1I3Kn3LIzwKv4KDdCbYmn056o773kBPXmymjEFmvh2VlJ5UWCjt46c4YS/nV264lDl88SjiuVls7ABk/lNz+m2Iw7Ivj+W8+s= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747965911038233.03152385698274; Thu, 22 May 2025 19:05:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uIHlU-0001Fk-0T; Thu, 22 May 2025 22:04:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uIHlK-0001EX-0R for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:54 -0400 Received: from mail-pf1-x431.google.com ([2607:f8b0:4864:20::431]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1uIHlE-0007in-SW for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:53 -0400 Received: by mail-pf1-x431.google.com with SMTP id d2e1a72fcca58-742b0840d98so5146390b3a.1 for ; Thu, 22 May 2025 19:03:48 -0700 (PDT) Received: from shemhazi.lan ([50.46.174.34]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-742a98a242asm11820818b3a.164.2025.05.22.19.03.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 May 2025 19:03:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747965826; x=1748570626; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cE/rElsE+sxHsKrFd8ZdZIhXnJuddVorLW+oNsQpqho=; b=JHbSQ2t1fZ0u4rdhhPvcpJAXtuaAbSdjjncaIa2jxhoNOtBCpYg327cOh0Zvzv82Hf LrXNGNs3ZKLs0cZIF2TySwkBW9ruFDRfsboSPvjeQZyCKqzk7yXICTd0q5q9lKzsXg66 Oez5FUYJP+LlMlAnzAwVsy4uecAQnVpyLZfJl8baGbarHqWExCVGqWiJ2I11jAIREzVs vhzaT4UuvBubLgqnwWVb7/ex2WlDB//rPi+cHS0RZrsj80Nsn2FgtDTAd8H8JSqgtQti obT/B+laHgQAk9tV9kxL/+y5ssi1njk11XWGIBppUTXDzzqf/8M/YSQLd5/lNffS3OWR mW0w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747965826; x=1748570626; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cE/rElsE+sxHsKrFd8ZdZIhXnJuddVorLW+oNsQpqho=; b=tgY+/OY/cmZVY0og2uGTL6E5dtxwcZeJIFrKsmdn8/ZdEou0qaNTPLE4DBRSOCC19M V/Vs0xRVZzDd7C4xxew1csrYryQuAIW+gm6U7OGe8v6GsKW//Dj3uktr5vUU1xIYAEEH acQbFNsgmZitc6CSf89OJXj6oamO2t9UK7Ss414zMt7Tq2gj3mK0PR09SyGQDZ+hcgs2 7daRpD+dq2XDfSbo5veU5UT7bGGG4ZoP5HD4+hvFyWJZGbR9X34hPUMlKPY3RnF4zuiP wVOU8x9M0UhddnJUlAMXOJ9Yu709GFWNm3ig+h+nLSb/uL6++O1JA+G5hX7jEz8KhMiS dvew== X-Gm-Message-State: AOJu0YzyMYyeU1ymuKClqhux2r8llZEwnxDokhL9OW0hkYUU0P9z0Y6E 39MbkIswteaC7SHP8XqQ7haxdkZ0fRm5dwRZ/kzvvtKbiuGZXh4wH7xuw4usWsww/XQ= X-Gm-Gg: ASbGncu5PGDoqxEW/RS6JGT1mnoyu83yBileKv3JMb/5Lkq5cEYbBvhBbicA30RnhVO zn2YnMmkjZiaM5SoryqgkVKFGkK4yN6rUGv2V+gf3/5CsgFj/gpyJihyJAf3PA5Tnb4/OtBJGQq PWaMJAvohgIyYRQLLj1/Z32hXqILK+wvnXLx3pkvWLGN5KlwnAqkj0NMCCBTA36R6DM3q7+Ar4w Kfup/1IIY6XyZqPs6qBNUVOdv+5KudHTYliA6h8vMCzGFrdHyiZcdCVeNwBJfJlCwPhsH6Obkg8 sqiye+9S9pTnqbeWJIsvbhWib49AKc5IfOiIcwhci1+X1er3pAA= X-Google-Smtp-Source: AGHT+IGpcZUZLs3jS/WUrLCd2zphu3OeoV8Dnx72o2Wrv8Z9Yej/6A43JNbF8vBh50RmeVuzc5wtdQ== X-Received: by 2002:a05:6a00:858f:b0:73e:1566:5960 with SMTP id d2e1a72fcca58-742acd507c1mr34646406b3a.19.1747965826328; Thu, 22 May 2025 19:03:46 -0700 (PDT) From: Rowan Hart To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , Paolo Bonzini , Mahmoud Mandour , Alexandre Iooss , Eduardo Habkost , novafacing Subject: [PATCH v4 1/9] gdbstub: Expose gdb_write_register function to consumers of gdbstub Date: Thu, 22 May 2025 19:03:35 -0700 Message-ID: <20250523020344.1341179-2-rowanbhart@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250523020344.1341179-1-rowanbhart@gmail.com> References: <20250523020344.1341179-1-rowanbhart@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::431; envelope-from=rowanbhart@gmail.com; helo=mail-pf1-x431.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1747965912836116600 Content-Type: text/plain; charset="utf-8" From: novafacing This patch exposes the gdb_write_register function from gdbstub/gdbstub.c via the exec/gdbstub.h header file to support use in plugins to write register contents. Signed-off-by: novafacing Signed-off-by: Rowan Hart Reviewed-by: Pierrick Bouvier --- gdbstub/gdbstub.c | 2 +- include/exec/gdbstub.h | 14 ++++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/gdbstub/gdbstub.c b/gdbstub/gdbstub.c index 565f6b33a9..5846e481be 100644 --- a/gdbstub/gdbstub.c +++ b/gdbstub/gdbstub.c @@ -534,7 +534,7 @@ int gdb_read_register(CPUState *cpu, GByteArray *buf, i= nt reg) return 0; } =20 -static int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) +int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg) { GDBRegisterState *r; =20 diff --git a/include/exec/gdbstub.h b/include/exec/gdbstub.h index 0675b0b646..a16c0051ce 100644 --- a/include/exec/gdbstub.h +++ b/include/exec/gdbstub.h @@ -124,6 +124,20 @@ const GDBFeature *gdb_find_static_feature(const char *= xmlname); */ int gdb_read_register(CPUState *cpu, GByteArray *buf, int reg); =20 +/** + * gdb_write_register() - Write a register associated with a CPU. + * @cpu: The CPU associated with the register. + * @buf: The buffer that the register contents will be set to. + * @reg: The register's number returned by gdb_find_feature_register(). + * + * The size of @buf must be at least the size of the register being + * written. + * + * Return: The number of written bytes, or 0 if an error occurred (for + * example, an unknown register was provided). + */ +int gdb_write_register(CPUState *cpu, uint8_t *mem_buf, int reg); + /** * typedef GDBRegDesc - a register description from gdbstub */ --=20 2.49.0 From nobody Fri Dec 19 13:06:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1747965935; cv=none; d=zohomail.com; s=zohoarc; b=X9ScFnNv1Nz//41RtbFPQ1axLDdiqtyW2QTUAG7QFZy7qACOSjcctBBch5SN0irzTeanZl0He6aQ49q/wctZYmaGUNYmS8E6UHce+tP6IGHMLzgmlQjVdeB52hhLlhu/rslR9XhxCL7vtrfuhgr6wBV0aLiNM46LdGLC7ZGh2OQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747965935; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=19nm1BE1atXqg2lUu6wBedzxuVyUaQdQO9+pie3X/Tw=; b=Mobhweb4gJJ8SfU22izDEryfM5UCcTzHOuv2BEWOXSU34Cpu3LSWEf1ZAAsJf79hB6vxH03Ovp9gyOvoCHDS5b9B5ExM2/Bd84jn+ikR7GftADFg9d9v8865+PKQG1FNECJw5j70lhi9WFXQNFdc24d/iuzLKvybM35RksxOQkA= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747965935801449.6682064166423; Thu, 22 May 2025 19:05:35 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uIHlX-0001HB-Ax; Thu, 22 May 2025 22:04:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uIHlN-0001Ep-LF for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:57 -0400 Received: from mail-pf1-x42f.google.com ([2607:f8b0:4864:20::42f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1uIHlF-0007j1-GI for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:56 -0400 Received: by mail-pf1-x42f.google.com with SMTP id d2e1a72fcca58-742c96af71dso6847267b3a.0 for ; Thu, 22 May 2025 19:03:48 -0700 (PDT) Received: from shemhazi.lan ([50.46.174.34]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-742a98a242asm11820818b3a.164.2025.05.22.19.03.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 May 2025 19:03:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747965827; x=1748570627; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=19nm1BE1atXqg2lUu6wBedzxuVyUaQdQO9+pie3X/Tw=; b=VoAF43g1SbNBdg/v0FlzNiyGElsvK1AE8qcGN7gtl/wIQg431SKZYsPXe44ntpUycH FNeFCpxqYkDg4HtdrL0scdNLMucvyXpo7ISZDJoofVhey9dvLzZnvQehJpewA8Aem/nx RJhD89B1Uk9S1VbRF4+Lhoo6w8jYHm3XbrXWYZCtPVPu0mNtBaKW15pF2CZTZ8gX41VE 2wuK0MzJB32Og2/9L9jhuOYRGDR/Vy0dzM1WhedwVyS3Q5dmFBWnipEtSuRDIFmlv+Sq PcrF30KdqgaIVA5+RZ1T7tmg/krhsx1fpcdUmFpFf0Kv7UIOIafnCVKfyRGYF4NsJbU2 CnvQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747965827; x=1748570627; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=19nm1BE1atXqg2lUu6wBedzxuVyUaQdQO9+pie3X/Tw=; b=GLYcr3YR+l/uXtVQQ4RMvbLOObe/tTfEGKWMP5WwgCnLkLfRmcE48hG4rJxNQ4yzQh T+W5jqhwz1Ylj0ZnEx5GYvFni2hXbLnQ6hQnvv6Tr7i4ULin4AeSqBZbnoNJBMBS3Ys1 BPq8/iYGkfk1U7aEOOHSrWX3bUcp9d0zKsfS6ciBaVMctSCsxSpTCnJg5VAt7BcA7wSi 4xvUoHzRL5f3/EFoxCXTLNky9rRd197Mr8gEtqL89f0VpKiS76UGUyuK38fWUWKfHo/i GP3oDpPQs512vDiHW7jy0gK96w69GUH3cMVOPXVU/cUBPc1Skpyxrdd63z14udS7/sRi uDuw== X-Gm-Message-State: AOJu0Yyt6KCP6oanQ2VA8vcjb5Yr/D1vjgyLtA3ur1EISrc226MoEr// QdM5IqM70bJyX4F0Q9MHeHJ4FAuyoeK6nLw3eajrKjtkR2u2PnbAIdGdEaqvjVB3MTE= X-Gm-Gg: ASbGncsmT/+zD82RtCZEFqz7gdN1GFVX9SNBNo5WoDHv/SYbEB/7x7dIhFPsqyQJiqG 8gwPG1SaeWcdJ+MPLEyN0DVonYuPUgnsLZW1p+w4G/9X9R/b4XjSH/PsW6KOr5ZHCufugFlZ2FL u8LXd4+XzReAYpYqk0MFYc7RGQPunGT9KzURlFmu+B6pK7r4cH0jEAfir1+DD8LdNTAmTa+H7By pVFZ2GCvYyvCyRxBUfcjToSRfAMtNrM/TkZh8U9SocIyfihhJSg1Mk33RIoqDaX4DCQbymk+XC7 IpHUOEyyytMJq10OfYlXzgDaWp53nQpXdNxSRF52qGgMRyJTGzljY8RzT4zS/g== X-Google-Smtp-Source: AGHT+IHql7dQxnULfpnkVRTXtRD8dYjyUajmz3EKCB5gN3XXH39JdGhto5uO1F+iD2pqGr/TwnX2Cg== X-Received: by 2002:a05:6a00:6f57:b0:73d:b1ff:c758 with SMTP id d2e1a72fcca58-742a98abbecmr37775090b3a.18.1747965827008; Thu, 22 May 2025 19:03:47 -0700 (PDT) From: Rowan Hart To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , Paolo Bonzini , Mahmoud Mandour , Alexandre Iooss , Eduardo Habkost , novafacing Subject: [PATCH v4 2/9] plugins: Add register write API Date: Thu, 22 May 2025 19:03:36 -0700 Message-ID: <20250523020344.1341179-3-rowanbhart@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250523020344.1341179-1-rowanbhart@gmail.com> References: <20250523020344.1341179-1-rowanbhart@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42f; envelope-from=rowanbhart@gmail.com; helo=mail-pf1-x42f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1747965937303116600 Content-Type: text/plain; charset="utf-8" From: novafacing This patch adds a function to the plugins API to allow plugins to write register contents. It also moves the qemu_plugin_read_register function so all the register-related functions are grouped together in the file. Signed-off-by: novafacing Signed-off-by: Rowan Hart Reviewed-by: Pierrick Bouvier --- include/qemu/qemu-plugin.h | 54 ++++++++++++++++++++++++++------------ plugins/api.c | 22 +++++++++++----- 2 files changed, 52 insertions(+), 24 deletions(-) diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index 3a850aa216..cfe1692ecb 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -871,7 +871,8 @@ struct qemu_plugin_register; /** * typedef qemu_plugin_reg_descriptor - register descriptions * - * @handle: opaque handle for retrieving value with qemu_plugin_read_regis= ter + * @handle: opaque handle for retrieving value with qemu_plugin_read_regis= ter or + * writing value with qemu_plugin_write_register * @name: register name * @feature: optional feature descriptor, can be NULL */ @@ -893,6 +894,41 @@ typedef struct { QEMU_PLUGIN_API GArray *qemu_plugin_get_registers(void); =20 +/** + * qemu_plugin_read_register() - read register for current vCPU + * + * @handle: a @qemu_plugin_reg_handle handle + * @buf: A GByteArray for the data owned by the plugin + * + * This function is only available in a context that register read access = is + * explicitly requested via the QEMU_PLUGIN_CB_R_REGS flag. + * + * Returns the size of the read register. The content of @buf is in target= byte + * order. On failure returns -1. + */ +QEMU_PLUGIN_API +int qemu_plugin_read_register(struct qemu_plugin_register *handle, + GByteArray *buf); + +/** + * qemu_plugin_write_register() - write register for current vCPU + * + * @handle: a @qemu_plugin_reg_handle handle + * @buf: A GByteArray for the data owned by the plugin + * + * This function is only available in a context that register write access= is + * explicitly requested via the QEMU_PLUGIN_CB_RW_REGS flag. + * + * The size of @buf must be at least the size of the requested register. + * Attempting to write a register with @buf smaller than the register size + * will result in a crash or other undesired behavior. + * + * Returns the number of bytes written. On failure returns 0. + */ +QEMU_PLUGIN_API +int qemu_plugin_write_register(struct qemu_plugin_register *handle, + GByteArray *buf); + /** * qemu_plugin_read_memory_vaddr() - read from memory using a virtual addr= ess * @@ -915,22 +951,6 @@ QEMU_PLUGIN_API bool qemu_plugin_read_memory_vaddr(uint64_t addr, GByteArray *data, size_t len); =20 -/** - * qemu_plugin_read_register() - read register for current vCPU - * - * @handle: a @qemu_plugin_reg_handle handle - * @buf: A GByteArray for the data owned by the plugin - * - * This function is only available in a context that register read access = is - * explicitly requested via the QEMU_PLUGIN_CB_R_REGS flag. - * - * Returns the size of the read register. The content of @buf is in target= byte - * order. On failure returns -1. - */ -QEMU_PLUGIN_API -int qemu_plugin_read_register(struct qemu_plugin_register *handle, - GByteArray *buf); - /** * qemu_plugin_scoreboard_new() - alloc a new scoreboard * diff --git a/plugins/api.c b/plugins/api.c index 3c9d4832e9..3a7add50d2 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -433,6 +433,21 @@ GArray *qemu_plugin_get_registers(void) return create_register_handles(regs); } =20 +int qemu_plugin_read_register(struct qemu_plugin_register *reg, GByteArray= *buf) +{ + g_assert(current_cpu); + + return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg) - 1); +} + +int qemu_plugin_write_register(struct qemu_plugin_register *reg, + GByteArray *buf) +{ + g_assert(current_cpu); + + return gdb_write_register(current_cpu, buf->data, GPOINTER_TO_INT(reg)= - 1); +} + bool qemu_plugin_read_memory_vaddr(uint64_t addr, GByteArray *data, size_t= len) { g_assert(current_cpu); @@ -453,13 +468,6 @@ bool qemu_plugin_read_memory_vaddr(uint64_t addr, GByt= eArray *data, size_t len) return true; } =20 -int qemu_plugin_read_register(struct qemu_plugin_register *reg, GByteArray= *buf) -{ - g_assert(current_cpu); - - return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg) - 1); -} - struct qemu_plugin_scoreboard *qemu_plugin_scoreboard_new(size_t element_s= ize) { return plugin_scoreboard_new(element_size); --=20 2.49.0 From nobody Fri Dec 19 13:06:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1747965922; cv=none; d=zohomail.com; s=zohoarc; b=m5MD3KJgkh96mIVu2FAr3VuKi7JwZyN8hLYWAEtqzoFP0GHyYEbTZqnpnGGMn+AHcC85sz/p384fM9lHdpJty4qonarWC0K7LsgytsAzHormfLqJHGkWi1L6NhIFjk+y4qzmtGNVO3AO8ffwb+NrGyRtQLvh0403SbTQ7ECOT6M= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747965922; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ZaHbTkEBubNAQpkCtAP0YTzxiH/VFIPfImRnxNMGa9s=; b=C7kINYq5JZ1l/0Sr2YQXcPnDPwafcGNlBaqb8B3YtfI0kjMsutDuaNo/v2+QZZjlnS71Arzkwf+OCWK45Vfvali9b0+xCCkDzRcirh904xIwHFPejvG5xMqEgFWBoiIy18IR3qI2TwWozZHsDRcrUNLLlybQjoPrwOVl0Us2/VQ= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747965922322878.3385266299066; Thu, 22 May 2025 19:05:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uIHlU-0001GJ-Pu; Thu, 22 May 2025 22:04:04 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uIHlN-0001En-Km for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:57 -0400 Received: from mail-pf1-x42c.google.com ([2607:f8b0:4864:20::42c]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1uIHlH-0007ju-Rm for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:57 -0400 Received: by mail-pf1-x42c.google.com with SMTP id d2e1a72fcca58-7398d65476eso338452b3a.1 for ; Thu, 22 May 2025 19:03:49 -0700 (PDT) Received: from shemhazi.lan ([50.46.174.34]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-742a98a242asm11820818b3a.164.2025.05.22.19.03.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 May 2025 19:03:47 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747965828; x=1748570628; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ZaHbTkEBubNAQpkCtAP0YTzxiH/VFIPfImRnxNMGa9s=; b=HVxgQQKoGAhoTrnZ3w0eNyaIwZ/lWUNNyOLUjE32MHZJspbs4hFT03Zu8d+cUlNLGU xiG+BxpsLXyeL9eH0f67QnWoSkVAS1bx71zLy0a+1gXCp1SrdoBO85WPfP31HJGgh35/ Ed8GIRcFEY1OjgxST9Npx8y+jCF2a5p23NCeXzbg4eunJAkIWG/rbaKS/DYFRnhJz94r sq8ftD3FWlD9rzUq5D3Jhcw98ssAwuhb0cq3pkdAvzT8kTw6poKwF4mvlW/VEa2ztH49 uALumra73YacJCPeVtgMxCCdlCxDK/PfdQZe9oN3x7LC/N7FxuJFXKIC4NpaflCWjclW 1bMQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747965828; x=1748570628; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ZaHbTkEBubNAQpkCtAP0YTzxiH/VFIPfImRnxNMGa9s=; b=GZvqwG7g2aEfgAnasE2fFzEUtBZ6li24HrbaZzNkjDqhXsO+6QQtZwQHkxAoNWuGPJ 78uBDJnh7gfxnClEzLoRHPWRK550+ajtOTQtlla8LZ49B/tv1ok/K9lIgVRy3hwmuGo6 PAuadPwHfTtvD+6i350SFi4Bc7kHgR+GFHEmTDk1vskJN7nEstS2eRhLera725GhWkBc Vg95r89nkYekOnpFX0Nq6RKC/k2jeQPIgDln9rhKKw1jwLXyAzYLbzdu6nYsHFJeeve+ MB0f2kaAd2JuV0WLVpKVc3Ib6umV/ARZnxQKEGPWfwthdBhg+1GFcM1Hw4oBSipPeeX8 3lVg== X-Gm-Message-State: AOJu0Yz3okioXTg4S77d76w/9TytRIZTUSDPqR09tYsGslz3H/xQdQBH 96K34+p9tWC1bsCD3FQnq17KVB7CIEnV02Fzlz2TaOEQCGjs1eLaazNRyT6uk3r75BA= X-Gm-Gg: ASbGncvpqBes9dPTuJf9o5yDWSXVnpaG3kjm7Nb960gLyKv/jKoH605tktU8NMvldrJ jqLVGA2qnWCb3uLVKf3RbEdN9XrW+1jUxl+Pp5PcCblqI5S5xh+Atc45vGCXXREA9NHMzkpv360 fM1AIUhJ1j/gKq/ehSZ+yXTByHySijJC0yjwBax2pYJL74CDs0Fx4KIJKRn2QeO6LDtynd5oBXX ppRGkQ/qGa3dF/k3XuNHzqXIK8Y107Q8RkrhY60anb7fdGn+/ziCKkyIw50VzQVx3JjyZH2p9qv KxYSCzt0gric5V9MGBzQ+6t6dbionhgx8vEAuaZqvhJ8Ci91xgE= X-Google-Smtp-Source: AGHT+IFckDCU/JBVBOJqQ8MU8HM4V6/Q845XL4CqxkfAskItS6BYKiALZLIhwXlh3cVB/lEIEjNuMQ== X-Received: by 2002:a05:6a00:2e17:b0:742:a628:f53c with SMTP id d2e1a72fcca58-745ece8b604mr2202448b3a.10.1747965827857; Thu, 22 May 2025 19:03:47 -0700 (PDT) From: Rowan Hart To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , Paolo Bonzini , Mahmoud Mandour , Alexandre Iooss , Eduardo Habkost , Rowan Hart Subject: [PATCH v4 3/9] plugins: Add enforcement of QEMU_PLUGIN_CB flags in register R/W callbacks Date: Thu, 22 May 2025 19:03:37 -0700 Message-ID: <20250523020344.1341179-4-rowanbhart@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250523020344.1341179-1-rowanbhart@gmail.com> References: <20250523020344.1341179-1-rowanbhart@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42c; envelope-from=rowanbhart@gmail.com; helo=mail-pf1-x42c.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1747965923282116600 Content-Type: text/plain; charset="utf-8" This patch adds functionality to enforce the requested QEMU_PLUGIN_CB_ flags level passed when registering a callback function using the plugins API. Each time a callback is about to be invoked, a thread-local variable will be updated with the level that callback requested. Then, called API functions (in particular, the register read and write API) will call qemu_plugin_get_cb_flags() to check the level is at least the level they require. Signed-off-by: Rowan Hart --- accel/tcg/plugin-gen.c | 27 +++++++++++++++++ include/qemu/plugin.h | 12 ++++++++ include/qemu/qemu-plugin.h | 3 -- plugins/api.c | 8 +++++ plugins/core.c | 60 ++++++++++++++++++++++++++++++++++---- 5 files changed, 101 insertions(+), 9 deletions(-) diff --git a/accel/tcg/plugin-gen.c b/accel/tcg/plugin-gen.c index c1da753894..ceb2314bc1 100644 --- a/accel/tcg/plugin-gen.c +++ b/accel/tcg/plugin-gen.c @@ -117,10 +117,19 @@ static TCGv_i32 gen_cpu_index(void) static void gen_udata_cb(struct qemu_plugin_regular_cb *cb) { TCGv_i32 cpu_index =3D gen_cpu_index(); + enum qemu_plugin_cb_flags cb_flags =3D + tcg_call_to_qemu_plugin_cb_flags(cb->info->flags); + TCGv_i32 flags =3D tcg_constant_i32(cb_flags); + tcg_gen_call1(qemu_plugin_set_cb_flags, + qemu_plugin_get_set_cb_flags_helper_info(), NULL, + tcgv_i32_temp(flags)); tcg_gen_call2(cb->f.vcpu_udata, cb->info, NULL, tcgv_i32_temp(cpu_index), tcgv_ptr_temp(tcg_constant_ptr(cb->userp))); + tcg_gen_call0(qemu_plugin_clear_cb_flags, + qemu_plugin_get_clear_cb_flags_helper_info(), NULL); tcg_temp_free_i32(cpu_index); + tcg_temp_free_i32(flags); } =20 static TCGv_ptr gen_plugin_u64_ptr(qemu_plugin_u64 entry) @@ -173,10 +182,19 @@ static void gen_udata_cond_cb(struct qemu_plugin_cond= itional_cb *cb) tcg_gen_ld_i64(val, ptr, 0); tcg_gen_brcondi_i64(cond, val, cb->imm, after_cb); TCGv_i32 cpu_index =3D gen_cpu_index(); + enum qemu_plugin_cb_flags cb_flags =3D + tcg_call_to_qemu_plugin_cb_flags(cb->info->flags); + TCGv_i32 flags =3D tcg_constant_i32(cb_flags); + tcg_gen_call1(qemu_plugin_set_cb_flags, + qemu_plugin_get_set_cb_flags_helper_info(), NULL, + tcgv_i32_temp(flags)); tcg_gen_call2(cb->f.vcpu_udata, cb->info, NULL, tcgv_i32_temp(cpu_index), tcgv_ptr_temp(tcg_constant_ptr(cb->userp))); + tcg_gen_call0(qemu_plugin_clear_cb_flags, + qemu_plugin_get_clear_cb_flags_helper_info(), NULL); tcg_temp_free_i32(cpu_index); + tcg_temp_free_i32(flags); gen_set_label(after_cb); =20 tcg_temp_free_i64(val); @@ -210,12 +228,21 @@ static void gen_mem_cb(struct qemu_plugin_regular_cb = *cb, qemu_plugin_meminfo_t meminfo, TCGv_i64 addr) { TCGv_i32 cpu_index =3D gen_cpu_index(); + enum qemu_plugin_cb_flags cb_flags =3D + tcg_call_to_qemu_plugin_cb_flags(cb->info->flags); + TCGv_i32 flags =3D tcg_constant_i32(cb_flags); + tcg_gen_call1(qemu_plugin_set_cb_flags, + qemu_plugin_get_set_cb_flags_helper_info(), NULL, + tcgv_i32_temp(flags)); tcg_gen_call4(cb->f.vcpu_mem, cb->info, NULL, tcgv_i32_temp(cpu_index), tcgv_i32_temp(tcg_constant_i32(meminfo)), tcgv_i64_temp(addr), tcgv_ptr_temp(tcg_constant_ptr(cb->userp))); + tcg_gen_call0(qemu_plugin_clear_cb_flags, + qemu_plugin_get_clear_cb_flags_helper_info(), NULL); tcg_temp_free_i32(cpu_index); + tcg_temp_free_i32(flags); } =20 static void inject_cb(struct qemu_plugin_dyn_cb *cb) diff --git a/include/qemu/plugin.h b/include/qemu/plugin.h index 9726a9ebf3..f312cc1a72 100644 --- a/include/qemu/plugin.h +++ b/include/qemu/plugin.h @@ -209,6 +209,18 @@ void qemu_plugin_user_prefork_lock(void); */ void qemu_plugin_user_postfork(bool is_child); =20 +enum qemu_plugin_cb_flags tcg_call_to_qemu_plugin_cb_flags(int flags); + +void qemu_plugin_set_cb_flags(enum qemu_plugin_cb_flags flags); + +enum qemu_plugin_cb_flags qemu_plugin_get_cb_flags(void); + +void qemu_plugin_clear_cb_flags(void); + +TCGHelperInfo *qemu_plugin_get_set_cb_flags_helper_info(void); + +TCGHelperInfo *qemu_plugin_get_clear_cb_flags_helper_info(void); + #else /* !CONFIG_PLUGIN */ =20 static inline void qemu_plugin_add_opts(void) diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index cfe1692ecb..120fb626a6 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -254,9 +254,6 @@ typedef struct { * @QEMU_PLUGIN_CB_NO_REGS: callback does not access the CPU's regs * @QEMU_PLUGIN_CB_R_REGS: callback reads the CPU's regs * @QEMU_PLUGIN_CB_RW_REGS: callback reads and writes the CPU's regs - * - * Note: currently QEMU_PLUGIN_CB_RW_REGS is unused, plugins cannot change - * system register state. */ enum qemu_plugin_cb_flags { QEMU_PLUGIN_CB_NO_REGS, diff --git a/plugins/api.c b/plugins/api.c index 3a7add50d2..16141f5c25 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -437,6 +437,10 @@ int qemu_plugin_read_register(struct qemu_plugin_regis= ter *reg, GByteArray *buf) { g_assert(current_cpu); =20 + if (qemu_plugin_get_cb_flags() =3D=3D QEMU_PLUGIN_CB_NO_REGS) { + return -1; + } + return gdb_read_register(current_cpu, buf, GPOINTER_TO_INT(reg) - 1); } =20 @@ -445,6 +449,10 @@ int qemu_plugin_write_register(struct qemu_plugin_regi= ster *reg, { g_assert(current_cpu); =20 + if (buf->len =3D=3D 0 || qemu_plugin_get_cb_flags() !=3D QEMU_PLUGIN_C= B_RW_REGS) { + return 0; + } + return gdb_write_register(current_cpu, buf->data, GPOINTER_TO_INT(reg)= - 1); } =20 diff --git a/plugins/core.c b/plugins/core.c index eb9281fe54..0ebde1fb87 100644 --- a/plugins/core.c +++ b/plugins/core.c @@ -30,6 +30,9 @@ struct qemu_plugin_cb { }; =20 struct qemu_plugin_state plugin; +static __thread enum qemu_plugin_cb_flags call_cb_flags; +static TCGHelperInfo qemu_plugin_set_cb_flags_helper; +static TCGHelperInfo qemu_plugin_clear_cb_flags_helper; =20 struct qemu_plugin_ctx *plugin_id_to_ctx_locked(qemu_plugin_id_t id) { @@ -364,14 +367,15 @@ void plugin_register_dyn_cb__udata(GArray **arr, enum qemu_plugin_cb_flags flags, void *udata) { - static TCGHelperInfo info[3] =3D { + static TCGHelperInfo info[4] =3D { [QEMU_PLUGIN_CB_NO_REGS].flags =3D TCG_CALL_NO_RWG, [QEMU_PLUGIN_CB_R_REGS].flags =3D TCG_CALL_NO_WG, + [QEMU_PLUGIN_CB_RW_REGS].flags =3D 0, /* * Match qemu_plugin_vcpu_udata_cb_t: * void (*)(uint32_t, void *) */ - [0 ... 2].typemask =3D (dh_typemask(void, 0) | + [0 ... 3].typemask =3D (dh_typemask(void, 0) | dh_typemask(i32, 1) | dh_typemask(ptr, 2)) }; @@ -393,14 +397,15 @@ void plugin_register_dyn_cond_cb__udata(GArray **arr, uint64_t imm, void *udata) { - static TCGHelperInfo info[3] =3D { + static TCGHelperInfo info[4] =3D { [QEMU_PLUGIN_CB_NO_REGS].flags =3D TCG_CALL_NO_RWG, [QEMU_PLUGIN_CB_R_REGS].flags =3D TCG_CALL_NO_WG, + [QEMU_PLUGIN_CB_RW_REGS].flags =3D 0, /* * Match qemu_plugin_vcpu_udata_cb_t: * void (*)(uint32_t, void *) */ - [0 ... 2].typemask =3D (dh_typemask(void, 0) | + [0 ... 3].typemask =3D (dh_typemask(void, 0) | dh_typemask(i32, 1) | dh_typemask(ptr, 2)) }; @@ -431,14 +436,15 @@ void plugin_register_vcpu_mem_cb(GArray **arr, !__builtin_types_compatible_p(qemu_plugin_meminfo_t, uint32_t) && !__builtin_types_compatible_p(qemu_plugin_meminfo_t, int32_t)); =20 - static TCGHelperInfo info[3] =3D { + static TCGHelperInfo info[4] =3D { [QEMU_PLUGIN_CB_NO_REGS].flags =3D TCG_CALL_NO_RWG, [QEMU_PLUGIN_CB_R_REGS].flags =3D TCG_CALL_NO_WG, + [QEMU_PLUGIN_CB_RW_REGS].flags =3D 0, /* * Match qemu_plugin_vcpu_mem_cb_t: * void (*)(uint32_t, qemu_plugin_meminfo_t, uint64_t, void *) */ - [0 ... 2].typemask =3D + [0 ... 3].typemask =3D (dh_typemask(void, 0) | dh_typemask(i32, 1) | (__builtin_types_compatible_p(qemu_plugin_meminfo_t, uint32_t) @@ -730,6 +736,11 @@ static void __attribute__((__constructor__)) plugin_in= it(void) qht_init(&plugin.dyn_cb_arr_ht, plugin_dyn_cb_arr_cmp, 16, QHT_MODE_AUTO_RESIZE); atexit(qemu_plugin_atexit_cb); + qemu_plugin_set_cb_flags_helper.flags =3D 0; + qemu_plugin_set_cb_flags_helper.typemask =3D (dh_typemask(void, 0) | + dh_typemask(i32, 1)); + qemu_plugin_clear_cb_flags_helper.flags =3D 0; + qemu_plugin_clear_cb_flags_helper.typemask =3D dh_typemask(void, 0); } =20 int plugin_num_vcpus(void) @@ -760,3 +771,40 @@ void plugin_scoreboard_free(struct qemu_plugin_scorebo= ard *score) g_array_free(score->data, TRUE); g_free(score); } + +enum qemu_plugin_cb_flags tcg_call_to_qemu_plugin_cb_flags(int flags) +{ + if (flags & TCG_CALL_NO_RWG) { + return QEMU_PLUGIN_CB_NO_REGS; + } else if (flags & TCG_CALL_NO_WG) { + return QEMU_PLUGIN_CB_R_REGS; + } else { + return QEMU_PLUGIN_CB_RW_REGS; + } +} + +void qemu_plugin_set_cb_flags(enum qemu_plugin_cb_flags flags) +{ + call_cb_flags =3D flags; +} + +enum qemu_plugin_cb_flags qemu_plugin_get_cb_flags(void) +{ + return call_cb_flags; +} + +void qemu_plugin_clear_cb_flags(void) +{ + call_cb_flags =3D QEMU_PLUGIN_CB_NO_REGS; +} + + +TCGHelperInfo *qemu_plugin_get_set_cb_flags_helper_info(void) +{ + return &qemu_plugin_set_cb_flags_helper; +} + +TCGHelperInfo *qemu_plugin_get_clear_cb_flags_helper_info(void) +{ + return &qemu_plugin_clear_cb_flags_helper; +} --=20 2.49.0 From nobody Fri Dec 19 13:06:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1747965952; cv=none; d=zohomail.com; s=zohoarc; b=HVmJPIF5bPn8u/tSWzlVoS+wfAHMDkgdahgZX7R+k0ffc4IDtQ2aYrXx7fSPYglKcOErBY6xEsZfNdsa7+yPUakT+u8PfijeaCU1J/0OmdUVxG9egB+ubYN5gb65nzMQuIitjQZiuhv7QhdiQO7dHC57WSEtoiGh0YryDnOtlHk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747965952; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=TL3Io6uv1wYqEJLOSkdLO7yEUmLjlnt6GTg1df0N+1g=; b=j8gDJsQbdGVloFZMYwramN2SyTo8sg5iVafCuX5lugTCELX/wSF9SfZ+icgMJKZdh2QbLf6nnsTfyRQJrA1v7YoRYWB4AjP+WHDNR/oyyt6H+QV/ESG2ima7udKKdz3hcnZoyVx5mkcWhbRZdcTpDfbvsbmJ8TX3UTH+mtIM/Kg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747965952510139.76478274379235; Thu, 22 May 2025 19:05:52 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uIHlV-0001Ge-97; Thu, 22 May 2025 22:04:05 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uIHlN-0001Eo-Kk for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:57 -0400 Received: from mail-pf1-x42b.google.com ([2607:f8b0:4864:20::42b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1uIHlH-0007k8-U0 for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:57 -0400 Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-739b3fe7ce8so6983014b3a.0 for ; Thu, 22 May 2025 19:03:50 -0700 (PDT) Received: from shemhazi.lan ([50.46.174.34]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-742a98a242asm11820818b3a.164.2025.05.22.19.03.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 May 2025 19:03:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747965829; x=1748570629; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TL3Io6uv1wYqEJLOSkdLO7yEUmLjlnt6GTg1df0N+1g=; b=eNZEd2O404eftQiLnph3APLJ7Eo+Zw8VKZM7yk9uW9wSHze9FqTHXvfscOnWwFHeb0 iAXejo5xCU54JtpTvo0pDRpNXBkkzBlghZEKoU/W1FgJpu3dCfh0i5uXpHTbGuWW7ylk CeflY+5b2Hrh9aX12nfqCVtAZgwamX9Otb21Pt4orhLO6AIPDmWEqbMz12UgTj5BOUGt Ps+YRmxMBAN1v68npooFC30VSKd/iS6XccAadNQ5TmdnLztmmuf7d96UbVXia2LjBHd8 WljEERtJQXrZf05KD+HQAacMMyaAerNuRcM7ck9sMzzD0M7my8xiYhsUfS7bPJYv7ugn IyhQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747965829; x=1748570629; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TL3Io6uv1wYqEJLOSkdLO7yEUmLjlnt6GTg1df0N+1g=; b=HGHY0v4hn/7WLLIbKdA7qw4dViPDufZ8IL2Vp4bnW9wi7Lp1w1EDJDovEKwBg6+ETo v+76AQvr+LivNKdaXOnsuKq4UFiU+DU0kogh1WStGefMC3hjhTVhpcwKSzI9eg4gDNrm AixVPMgClRrGlyHq9ntKveWj5kElhLIanqQ1iLHPJwceMZhrC4sNSMaVLHWA22z1kYaX Hz1HJXrIzvDiE0UD3gVC3UWjVv50uswRR8L1kUpD3QRgJKfW0nFebslCiE7dFV7QwZ8E mc5lM7QDq5ybFDgYwP9WGbCJ6fEQJcB/Q49e9COORJZY2qhs0bjmc+127H0XhJf1qjJf Umjg== X-Gm-Message-State: AOJu0YxHN6eACbVpRzHBJcoeaCc3ay0AizChpid3ZGraJu0+rLW9u4yb plO7/oaEd3seed3mtkHS+Rd4WQSMQGwaARc1wCqPHxL2teWVtF+wXZwWnCW3wd1Lzn4= X-Gm-Gg: ASbGncv5DFzM1T1LeymyJqYsNbvYAKI/01Q+q6Lj7gUuhh9F3FVRo8kFLjIyO1z4NXe xXV1NLGTur6DCAC2GrW7XZUn9GRLgDZSc4JjDqb+NDG3/VpkVn/ZauL3tnQKb/YanfFNFuTVTCi i5Pv+KOaZbLdafGrJIqbNwfk6mUjgjFqo8a6R67kD7szu97KDAvhZDBoKb2OzjcRsgwsHS/3RsS mPrNNfvveG/FKnJldNHYSjcXuPCfjcwbk+WSLIPeAerDGQmqppXRuoL4k/QDWilS+Ko7JbxKJIZ jAk+An1cIcpzTGMREcDMN418a9xZwddQgRa/z+ltCexHnvDKwmk= X-Google-Smtp-Source: AGHT+IGvHk6WQrsF7M3tQWAkfOk5ZWuoDwGq2l4gQ0sYK9spcEev+7khcDvBWnvJ2cOFsappRkgSWw== X-Received: by 2002:a05:6a00:3e16:b0:736:53ce:a32c with SMTP id d2e1a72fcca58-742a98a252cmr34200830b3a.17.1747965828727; Thu, 22 May 2025 19:03:48 -0700 (PDT) From: Rowan Hart To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , Paolo Bonzini , Mahmoud Mandour , Alexandre Iooss , Eduardo Habkost , novafacing Subject: [PATCH v4 4/9] plugins: Add memory virtual address write API Date: Thu, 22 May 2025 19:03:38 -0700 Message-ID: <20250523020344.1341179-5-rowanbhart@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250523020344.1341179-1-rowanbhart@gmail.com> References: <20250523020344.1341179-1-rowanbhart@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42b; envelope-from=rowanbhart@gmail.com; helo=mail-pf1-x42b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1747965953623116600 Content-Type: text/plain; charset="utf-8" From: novafacing This patch adds functions to the plugins API to allow reading and writing memory via virtual addresses. These functions only permit doing so on the current CPU, because there is no way to ensure consistency if plugins are allowed to read or write to other CPUs that aren't currently in the context of the plugin. Signed-off-by: novafacing Signed-off-by: Rowan Hart Reviewed-by: Pierrick Bouvier --- include/qemu/qemu-plugin.h | 21 +++++++++++++++++++++ plugins/api.c | 18 ++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index 120fb626a6..8ae7758b95 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -948,6 +948,27 @@ QEMU_PLUGIN_API bool qemu_plugin_read_memory_vaddr(uint64_t addr, GByteArray *data, size_t len); =20 +/** + * qemu_plugin_write_memory_vaddr() - write to memory using a virtual addr= ess + * + * @addr: A virtual address to write to + * @data: A byte array containing the data to write + * + * The contents of @data will be written to memory starting at the virtual + * address @addr. + * + * This function does not guarantee consistency of writes, nor does it ens= ure + * that pending writes are flushed either before or after the write takes = place, + * so callers should take care to only call this function in vCPU context = (i.e. + * in callbacks) and avoid depending on the existence of data written usin= g this + * function which may be overwritten afterward. + * + * Returns true on success and false on failure. + */ +QEMU_PLUGIN_API +bool qemu_plugin_write_memory_vaddr(uint64_t addr, + GByteArray *data); + /** * qemu_plugin_scoreboard_new() - alloc a new scoreboard * diff --git a/plugins/api.c b/plugins/api.c index 16141f5c25..7258b6590b 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -476,6 +476,24 @@ bool qemu_plugin_read_memory_vaddr(uint64_t addr, GByt= eArray *data, size_t len) return true; } =20 +bool qemu_plugin_write_memory_vaddr(uint64_t addr, GByteArray *data) +{ + g_assert(current_cpu); + + if (data->len =3D=3D 0) { + return false; + } + + int result =3D cpu_memory_rw_debug(current_cpu, addr, data->data, + data->len, true); + + if (result < 0) { + return false; + } + + return true; +} + struct qemu_plugin_scoreboard *qemu_plugin_scoreboard_new(size_t element_s= ize) { return plugin_scoreboard_new(element_size); --=20 2.49.0 From nobody Fri Dec 19 13:06:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1747965963; cv=none; d=zohomail.com; s=zohoarc; b=FXB2EqZ+EYJrGaEVWDEGNQX9crN3L3XOkdBfHTf/8XN30QHxZAPFSNoHC/XeRXMa9KKzVy6oKR6NOdyUsvYoURt+5XJglRyPploMXQ3YntCMSUNJOS2qnbF1QklEdSmV2MgrOvFtTsBTJn3QGQ0TT8MaL1itDtBtyfpa0j++w3o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747965963; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=gZm+6Hf7yjTndCGJAZXhWR9OV/ex2x6ZVedPPTJsqTo=; b=j0kl8Y1v2R4cvSL/nPmPdr6zLlOX0HxL65IfPQm1hDeo3aZfVxOQ6gY+Dpv4y3UJmDDB/hiqomL5OKuc7OPjTP3UPDMtH1l14TgnT1PtJVex1IIptNHsMQyqmsXM4aEVRtjHd4BlBwDlr55BfsLQPMJzGGF7WlgK54X0WGvM9hg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747965963445822.1430776305727; Thu, 22 May 2025 19:06:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uIHlW-0001Gp-6A; Thu, 22 May 2025 22:04:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uIHlO-0001FY-5T for qemu-devel@nongnu.org; Thu, 22 May 2025 22:04:00 -0400 Received: from mail-pf1-x42e.google.com ([2607:f8b0:4864:20::42e]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1uIHlI-0007kH-13 for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:57 -0400 Received: by mail-pf1-x42e.google.com with SMTP id d2e1a72fcca58-7399838db7fso423227b3a.0 for ; Thu, 22 May 2025 19:03:51 -0700 (PDT) Received: from shemhazi.lan ([50.46.174.34]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-742a98a242asm11820818b3a.164.2025.05.22.19.03.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 May 2025 19:03:49 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747965830; x=1748570630; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=gZm+6Hf7yjTndCGJAZXhWR9OV/ex2x6ZVedPPTJsqTo=; b=m84OxmXrYxsLdoqWNejH6Ut3vHGLPmcmapAqbJxMi/QB9VvTCJYo9ooXosddj9xh+t 3FYwZhB0MjpNd8uQToUpYbkW0z2y6MjQKDfw1XQIebHdjF+3xJFQbD+HobW1NfE3eiVH YnVCt8PNURfDHde8rkDr5FabE1gor3h/a90knmdL/M05eD7Ivehn10Y3r1NKSNQ37LSo JEnhXz/SOwhz2L9YcyxaB8YwoWs8WcpFZoJWRYyW3KBnuo/vh26GLmD3LsSdH4dL/o0z T8L4SgzKL3iYA/HrbmRxGHPbd14ypKZbhP8ZL/a+TLMeaAFICixNFbHOE1RrxF/R/dSu c17Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747965830; x=1748570630; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gZm+6Hf7yjTndCGJAZXhWR9OV/ex2x6ZVedPPTJsqTo=; b=UAKjpXkv8kbLvTRAA1CilDUvSrfD+HSLrz4Kmm3RRJ1WDycnomWwJ+qSqYzOEMzrph RnjuaUhdw0UGsXf56HQNuWUddT8nBdEAUBMvFe1hnwon7t1EBH7vUW7cYe5I7VOvtxYA 1jx0oOIC0VPknFyIyNwL/3NR/bThECW/ygZyDBobysvRRbEKnSYmyTU7OZUrkj+gq9TY 4Yv5Mrg2iZIVqSn9ZceSq15ILkimCFLQsI3iXj2nDF4rBGrYSh9F6EMzVXd6Ll3tTll/ Wet3E9qtHf1uBUK15+XnDmd0KmriLQ8Nue3FJnc1f1oBKhJr/xN4V7G83RVYs/EPMxnm My9g== X-Gm-Message-State: AOJu0YxstWoYPJphCBOMp2mhsGo7mzbAxafsaJaybvMO9W/t6D4oysQ0 znKa/0RpFXLWGacZCIkrV+QJcwvvPmcewgTcVKJPqpOK4q2Egrs0vuXnOP+i9bn4V1M= X-Gm-Gg: ASbGncuEuvBHTO47t5F6bTG4ls87tsZudJ16vpn+fIomE+ffRbR7yd+VWPjQy7OR+Vu xnEwg78tOHCs5KAu9T0VPhTPwe13M8MHeNXwZCdgyMqagD8u5oFRhujNKnrNUIBf1ydQGkiQ7BZ 5Y4Dxse1B6ldf3G3zX7VH/XwMMKKMDoNOxyhKWM4ant0Ce4NKNV/+OYl5ACg/kBtv+P24xGNWuZ pii9EOf05csqdxqJZDML1omgkgLUy9p5UzeI5oU+ASESZdBMv7arOf5jpZVyiFSwMeTKHQQaHLU zcZY8aINrxFaalc/CSGME47GNfovHFh9qvV8qB5bDwyjycbzLoHBoYvUWPrQuw== X-Google-Smtp-Source: AGHT+IFVGJMYr5nRYc0FXJiSSSB4UASirB2czNxRFfHZbir3qUvfq7VKJWcL06oIUijL2AMMLYEB7Q== X-Received: by 2002:a05:6a00:3cc1:b0:73d:f9d2:9c64 with SMTP id d2e1a72fcca58-745ece323edmr2302394b3a.10.1747965829625; Thu, 22 May 2025 19:03:49 -0700 (PDT) From: Rowan Hart To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , Paolo Bonzini , Mahmoud Mandour , Alexandre Iooss , Eduardo Habkost , novafacing Subject: [PATCH v4 5/9] plugins: Add memory hardware address read/write API Date: Thu, 22 May 2025 19:03:39 -0700 Message-ID: <20250523020344.1341179-6-rowanbhart@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250523020344.1341179-1-rowanbhart@gmail.com> References: <20250523020344.1341179-1-rowanbhart@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42e; envelope-from=rowanbhart@gmail.com; helo=mail-pf1-x42e.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1747965965612116600 Content-Type: text/plain; charset="utf-8" From: novafacing This patch adds functions to the plugins API to allow plugins to read and write memory via hardware addresses. The functions use the current address space of the current CPU in order to avoid exposing address space information to users. A later patch may want to add a function to permit a specified address space, for example to facilitate architecture-specific plugins that want to operate on them, for example reading ARM secure memory. Signed-off-by: novafacing Signed-off-by: Rowan Hart Reviewed-by: Pierrick Bouvier --- include/qemu/qemu-plugin.h | 93 ++++++++++++++++++++++++++++++++++++ plugins/api.c | 97 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+) diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index 8ae7758b95..2cb5de9f64 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -969,6 +969,99 @@ QEMU_PLUGIN_API bool qemu_plugin_write_memory_vaddr(uint64_t addr, GByteArray *data); =20 +/** + * enum qemu_plugin_hwaddr_operation_result - result of a memory operation + * + * @QEMU_PLUGIN_HWADDR_OPERATION_OK: hwaddr operation succeeded + * @QEMU_PLUGIN_HWADDR_OPERATION_ERROR: unexpected error occurred + * @QEMU_PLUGIN_HWADDR_OPERATION_DEVICE_ERROR: error in memory device + * @QEMU_PLUGIN_HWADDR_OPERATION_ACCESS_DENIED: permission error + * @QEMU_PLUGIN_HWADDR_OPERATION_INVALID_ADDRESS: address was invalid + * @QEMU_PLUGIN_HWADDR_OPERATION_INVALID_ADDRESS_SPACE: invalid address sp= ace + */ +enum qemu_plugin_hwaddr_operation_result { + QEMU_PLUGIN_HWADDR_OPERATION_OK, + QEMU_PLUGIN_HWADDR_OPERATION_ERROR, + QEMU_PLUGIN_HWADDR_OPERATION_DEVICE_ERROR, + QEMU_PLUGIN_HWADDR_OPERATION_ACCESS_DENIED, + QEMU_PLUGIN_HWADDR_OPERATION_INVALID_ADDRESS, + QEMU_PLUGIN_HWADDR_OPERATION_INVALID_ADDRESS_SPACE, +}; + +/** + * qemu_plugin_read_memory_hwaddr() - read from memory using a hardware ad= dress + * + * @addr: The physical address to read from + * @data: A byte array to store data into + * @len: The number of bytes to read, starting from @addr + * + * @len bytes of data is read from the current memory space for the current + * vCPU starting at @addr and stored into @data. If @data is not large eno= ugh to + * hold @len bytes, it will be expanded to the necessary size, reallocatin= g if + * necessary. @len must be greater than 0. + * + * This function does not ensure writes are flushed prior to reading, so + * callers should take care when calling this function in plugin callbacks= to + * avoid attempting to read data which may not yet be written and should u= se + * the memory callback API instead. + * + * This function is only valid for softmmu targets. + * + * Returns a qemu_plugin_hwaddr_operation_result indicating the result of = the + * operation. + */ +QEMU_PLUGIN_API +enum qemu_plugin_hwaddr_operation_result +qemu_plugin_read_memory_hwaddr(uint64_t addr, GByteArray *data, size_t len= ); + +/** + * qemu_plugin_write_memory_hwaddr() - write to memory using a hardware ad= dress + * + * @addr: A physical address to write to + * @data: A byte array containing the data to write + * + * The contents of @data will be written to memory starting at the hardware + * address @addr in the current address space for the current vCPU. + * + * This function does not guarantee consistency of writes, nor does it ens= ure + * that pending writes are flushed either before or after the write takes = place, + * so callers should take care when calling this function in plugin callba= cks to + * avoid depending on the existence of data written using this function wh= ich + * may be overwritten afterward. In addition, this function requires that = the + * pages containing the address are not locked. Practically, this means th= at you + * should not write instruction memory in a current translation block insi= de a + * callback registered with qemu_plugin_register_vcpu_tb_trans_cb. + * + * You can, for example, write instruction memory in a current translation= block + * in a callback registered with qemu_plugin_register_vcpu_tb_exec_cb, alt= hough + * be aware that the write will not be flushed until after the translation= block + * has finished executing. In general, this function should be used to wr= ite + * data memory or to patch code at a known address, not in a current trans= lation + * block. + * + * This function is only valid for softmmu targets. + * + * Returns a qemu_plugin_hwaddr_operation_result indicating the result of = the + * operation. + */ +QEMU_PLUGIN_API +enum qemu_plugin_hwaddr_operation_result +qemu_plugin_write_memory_hwaddr(uint64_t addr, GByteArray *data); + +/** + * qemu_plugin_translate_vaddr() - translate virtual address for current v= CPU + * + * @vaddr: virtual address to translate + * @hwaddr: pointer to store the physical address + * + * This function is only valid in vCPU context (i.e. in callbacks) and is = only + * valid for softmmu targets. + * + * Returns true on success and false on failure. + */ +QEMU_PLUGIN_API +bool qemu_plugin_translate_vaddr(uint64_t vaddr, uint64_t *hwaddr); + /** * qemu_plugin_scoreboard_new() - alloc a new scoreboard * diff --git a/plugins/api.c b/plugins/api.c index 7258b6590b..a0d980e113 100644 --- a/plugins/api.c +++ b/plugins/api.c @@ -39,6 +39,7 @@ #include "qemu/main-loop.h" #include "qemu/plugin.h" #include "qemu/log.h" +#include "system/memory.h" #include "tcg/tcg.h" #include "exec/gdbstub.h" #include "exec/target_page.h" @@ -494,6 +495,102 @@ bool qemu_plugin_write_memory_vaddr(uint64_t addr, GB= yteArray *data) return true; } =20 +enum qemu_plugin_hwaddr_operation_result +qemu_plugin_read_memory_hwaddr(hwaddr addr, GByteArray *data, size_t len) +{ +#ifdef CONFIG_SOFTMMU + if (len =3D=3D 0) { + return QEMU_PLUGIN_HWADDR_OPERATION_ERROR; + } + + g_assert(current_cpu); + + + int as_idx =3D cpu_asidx_from_attrs(current_cpu, MEMTXATTRS_UNSPECIFIE= D); + AddressSpace *as =3D cpu_get_address_space(current_cpu, as_idx); + + if (as =3D=3D NULL) { + return QEMU_PLUGIN_HWADDR_OPERATION_INVALID_ADDRESS_SPACE; + } + + g_byte_array_set_size(data, len); + MemTxResult res =3D address_space_rw(as, addr, + MEMTXATTRS_UNSPECIFIED, data->data, + data->len, false); + + switch (res) { + case MEMTX_OK: + return QEMU_PLUGIN_HWADDR_OPERATION_OK; + case MEMTX_ERROR: + return QEMU_PLUGIN_HWADDR_OPERATION_DEVICE_ERROR; + case MEMTX_DECODE_ERROR: + return QEMU_PLUGIN_HWADDR_OPERATION_INVALID_ADDRESS; + case MEMTX_ACCESS_ERROR: + return QEMU_PLUGIN_HWADDR_OPERATION_ACCESS_DENIED; + default: + return QEMU_PLUGIN_HWADDR_OPERATION_ERROR; + } +#else + return QEMU_PLUGIN_HWADDR_OPERATION_ERROR; +#endif +} + +enum qemu_plugin_hwaddr_operation_result +qemu_plugin_write_memory_hwaddr(hwaddr addr, GByteArray *data) +{ +#ifdef CONFIG_SOFTMMU + if (data->len =3D=3D 0) { + return QEMU_PLUGIN_HWADDR_OPERATION_ERROR; + } + + g_assert(current_cpu); + + int as_idx =3D cpu_asidx_from_attrs(current_cpu, MEMTXATTRS_UNSPECIFIE= D); + AddressSpace *as =3D cpu_get_address_space(current_cpu, as_idx); + + if (as =3D=3D NULL) { + return QEMU_PLUGIN_HWADDR_OPERATION_INVALID_ADDRESS_SPACE; + } + + MemTxResult res =3D address_space_rw(as, addr, + MEMTXATTRS_UNSPECIFIED, data->data, + data->len, true); + switch (res) { + case MEMTX_OK: + return QEMU_PLUGIN_HWADDR_OPERATION_OK; + case MEMTX_ERROR: + return QEMU_PLUGIN_HWADDR_OPERATION_DEVICE_ERROR; + case MEMTX_DECODE_ERROR: + return QEMU_PLUGIN_HWADDR_OPERATION_INVALID_ADDRESS; + case MEMTX_ACCESS_ERROR: + return QEMU_PLUGIN_HWADDR_OPERATION_ACCESS_DENIED; + default: + return QEMU_PLUGIN_HWADDR_OPERATION_ERROR; + } +#else + return QEMU_PLUGIN_HWADDR_OPERATION_ERROR; +#endif +} + +bool qemu_plugin_translate_vaddr(uint64_t vaddr, uint64_t *hwaddr) +{ +#ifdef CONFIG_SOFTMMU + g_assert(current_cpu); + + uint64_t res =3D cpu_get_phys_page_debug(current_cpu, vaddr); + + if (res =3D=3D (uint64_t)-1) { + return false; + } + + *hwaddr =3D res | (vaddr & ~TARGET_PAGE_MASK); + + return true; +#else + return false; +#endif +} + struct qemu_plugin_scoreboard *qemu_plugin_scoreboard_new(size_t element_s= ize) { return plugin_scoreboard_new(element_size); --=20 2.49.0 From nobody Fri Dec 19 13:06:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1747965963; cv=none; d=zohomail.com; s=zohoarc; b=K3jMFQn1PNflLQt6FVrMKlgZUUlSwmeUJdv/zR+Dl5XOc8LsfAZF1jvW6w7VkqNv48N37VrKLiU4cimxHM1JTQ3bs0HsY7ez1Znyw+1gzaHVqd+CBidyPcRmkh93jbaQmQGxTvbSoz/+GzWW/oCF2AWFPvhaneG6QTPCtDR6N80= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747965963; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=B9eLvDalIjlXyUkR8wTsvfaoz94Xil7ORIqzjzFs5NQ=; b=FKdFZc+vYoHeSnSRrmcSlIRbV/h9/dUprXacIcHizRPLDImGtTqHhpCzM3RANmNvf5Ggf2evZIfA/xm23BrtUsKnR71tCJqkHeHm18cKBT6UrPMHtca+pMZbKolqmLMgAafuLsIZS6VbgTUFW/MEFn7qFuaeqBxEDvFca0oTiAc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747965963183843.9487747995712; Thu, 22 May 2025 19:06:03 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uIHlW-0001Gr-6R; Thu, 22 May 2025 22:04:06 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uIHlN-0001Eq-Kn for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:57 -0400 Received: from mail-pf1-x42b.google.com ([2607:f8b0:4864:20::42b]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1uIHlJ-0007kO-8C for qemu-devel@nongnu.org; Thu, 22 May 2025 22:03:57 -0400 Received: by mail-pf1-x42b.google.com with SMTP id d2e1a72fcca58-73972a54919so7924746b3a.3 for ; Thu, 22 May 2025 19:03:51 -0700 (PDT) Received: from shemhazi.lan ([50.46.174.34]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-742a98a242asm11820818b3a.164.2025.05.22.19.03.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 May 2025 19:03:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747965831; x=1748570631; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=B9eLvDalIjlXyUkR8wTsvfaoz94Xil7ORIqzjzFs5NQ=; b=MlttPjPDbjghvUSUW8O8sZKdd69WdKcQ7yDLjJnnbV8QHwwdr7b5E77gcvXURtcUiz WlV3gyyafWJa4asDTuaxHyu2cIhg+bHDM1N9kr2MG3Vh0/vWUoZFq5hIsu45EC9ik2EQ bIZ+Or/2+7fm80/ddLhS8rhz3XVLbZ/dq04KuX8qddR4bV1aDlm5qs3JyjifJ5+80oVe XW1un9eBkOks5N+5t9NBdk1wgqq/NOgvnrHRuoMg+//dR4o3/7w0ezNlbbdH+mIGV3WP tGGM8qU0jRIikZbIJhe34hGTj9RZ+up6KWxYxHpizEHrmbK9MpgmMolwWYY3wF3r4Zg1 fNAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747965831; x=1748570631; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=B9eLvDalIjlXyUkR8wTsvfaoz94Xil7ORIqzjzFs5NQ=; b=Cx8g5aHMLZozUP1Gbz05/cE5kSB6ucvtnEn/rs8liZU5LoWN1cO1e+hFCoUzEdYJHo 5rlY3c5zIpe76APskvGe7hnTeYTrEF/fa1Qxsme+XJ3IMWQT+v8XN+VoLC4Hwx0BbKAx +t9QNgWZgNGIOOzpcaS+JQ71lUygFTLxllm/PajKDgfr0nsBh70fbdV9mo8ARo3CdAgQ mp2o75Ha2WlKITg8Hn1usTWuOLlYS++dheBP3RxpvVDq0tECnbu4eFPkoGEsh1IH7kBB VwI4492NytMrzWS7zqLNyoiuTLNcvqgNY3hYsF9ZOJEDuClXPzICs5delP+2+nSUxjKv HKRg== X-Gm-Message-State: AOJu0Ywz6Vxn1+1ealaI6ubyqnqDnYttl/CAw3xiw37gnnfcZU3lXTDZ 0mNBaPpBeKmNDAfTTBqRlZU9jRU0SBHRawxZdFnqPoIM4qJtjwDH7swhXOKEPky3ZgM= X-Gm-Gg: ASbGnctBoMbxeri4vF1FjoIvgkyFk/k7Ft/9kiwBm9qpjhlll8WeKULI/TTxAIldzFF JTzTT2yB05L4mxTOj/qohQb0sCBCcgN024dEcBcr7GfkYX+amzPaUL8XeqAUUkAL9AaUAPpCrQy eMMM2BT2XPrc2u9k7sRobPEApzNfqHxxqcotTPrAh2yX4IoKTlCBfJ/raK8AZ2qL3tArVBuGFX1 je6pl12CFdqXCg6+3HTpSKqYAUFNElrlC8yXnzm8+ZgLo3govWkvHOdOsMOFKu4WHvcSTYOS4QQ 6DxVF1Fp4tpeZuRwPdgIPZcvpEWx8zE6MdzLjIBuf69x3Xvc9cc= X-Google-Smtp-Source: AGHT+IE51pPnRo1lTZehXW8ppZ2dAyl82fyB2bYo12Q0yCDkO7ajWwGtGzHCGmF6/VFgdRPz0Asu8g== X-Received: by 2002:a05:6a00:2e2a:b0:736:3979:369e with SMTP id d2e1a72fcca58-745ed86507amr1573766b3a.9.1747965830471; Thu, 22 May 2025 19:03:50 -0700 (PDT) From: Rowan Hart To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , Paolo Bonzini , Mahmoud Mandour , Alexandre Iooss , Eduardo Habkost , novafacing Subject: [PATCH v4 6/9] plugins: Add patcher plugin and test Date: Thu, 22 May 2025 19:03:40 -0700 Message-ID: <20250523020344.1341179-7-rowanbhart@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250523020344.1341179-1-rowanbhart@gmail.com> References: <20250523020344.1341179-1-rowanbhart@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42b; envelope-from=rowanbhart@gmail.com; helo=mail-pf1-x42b.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1747965965604116600 Content-Type: text/plain; charset="utf-8" From: novafacing This patch adds a plugin that exercises the virtual and hardware memory read-write API functions added in a previous patch. The plugin takes a target and patch byte sequence, and will overwrite any instruction matching the target byte sequence with the patch. Signed-off-by: novafacing Signed-off-by: Rowan Hart --- tests/tcg/Makefile.target | 1 + tests/tcg/plugins/meson.build | 2 +- tests/tcg/plugins/patch.c | 302 ++++++++++++++++++++++ tests/tcg/x86_64/Makefile.softmmu-target | 32 ++- tests/tcg/x86_64/system/patch-target.c | 32 +++ tests/tcg/x86_64/system/validate-patch.py | 39 +++ 6 files changed, 402 insertions(+), 6 deletions(-) create mode 100644 tests/tcg/plugins/patch.c create mode 100644 tests/tcg/x86_64/system/patch-target.c create mode 100755 tests/tcg/x86_64/system/validate-patch.py diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target index 95ff76ea44..4b709a9d18 100644 --- a/tests/tcg/Makefile.target +++ b/tests/tcg/Makefile.target @@ -176,6 +176,7 @@ RUN_TESTS+=3D$(EXTRA_RUNS) # Some plugins need additional arguments above the default to fully # exercise things. We can define them on a per-test basis here. run-plugin-%-with-libmem.so: PLUGIN_ARGS=3D$(COMMA)inline=3Dtrue +run-plugin-%-with-libpatch.so: PLUGIN_ARGS=3D$(COMMA)target=3Dffffffff$(CO= MMA)patch=3D00000000 =20 ifeq ($(filter %-softmmu, $(TARGET)),) run-%: % diff --git a/tests/tcg/plugins/meson.build b/tests/tcg/plugins/meson.build index 41f02f2c7f..163042e601 100644 --- a/tests/tcg/plugins/meson.build +++ b/tests/tcg/plugins/meson.build @@ -1,6 +1,6 @@ t =3D [] if get_option('plugins') - foreach i : ['bb', 'empty', 'inline', 'insn', 'mem', 'reset', 'syscall'] + foreach i : ['bb', 'empty', 'inline', 'insn', 'mem', 'reset', 'syscall',= 'patch'] if host_os =3D=3D 'windows' t +=3D shared_module(i, files(i + '.c') + '../../../contrib/plugins/= win32_linker.c', include_directories: '../../../include/qemu', diff --git a/tests/tcg/plugins/patch.c b/tests/tcg/plugins/patch.c new file mode 100644 index 0000000000..3767d14a53 --- /dev/null +++ b/tests/tcg/plugins/patch.c @@ -0,0 +1,302 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (C) 2025, Rowan Hart + * + * License: GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * This plugin patches instructions matching a pattern to a different + * instruction as they execute + * + */ + +#include "glib.h" +#include "glibconfig.h" + +#include +#include +#include + +QEMU_PLUGIN_EXPORT int qemu_plugin_version =3D QEMU_PLUGIN_VERSION; + +static bool use_hwaddr; +static bool debug_insns; +static GByteArray *target_data; +static GByteArray *patch_data; + +/** + * Parse a string of hexadecimal digits into a GByteArray. The string must= be + * even length + */ +static GByteArray *str_to_bytes(const char *str) +{ + GByteArray *bytes =3D g_byte_array_new(); + char byte[3] =3D {0}; + size_t len =3D strlen(str); + guint8 value =3D 0; + + if (len % 2 !=3D 0) { + g_byte_array_free(bytes, true); + return NULL; + } + + for (size_t i =3D 0; i < len; i +=3D 2) { + byte[0] =3D str[i]; + byte[1] =3D str[i + 1]; + value =3D (guint8)g_ascii_strtoull(byte, NULL, 16); + g_byte_array_append(bytes, &value, 1); + } + + return bytes; +} + +static void patch_hwaddr(unsigned int vcpu_index, void *userdata) +{ + uint64_t addr =3D (uint64_t)userdata; + GString *str =3D g_string_new(NULL); + g_string_printf(str, "patching: @0x%" + PRIx64 "\n", + addr); + qemu_plugin_outs(str->str); + g_string_free(str, true); + + enum qemu_plugin_hwaddr_operation_result result =3D + qemu_plugin_write_memory_hwaddr(addr, patch_data); + + + if (result !=3D QEMU_PLUGIN_HWADDR_OPERATION_OK) { + GString *errmsg =3D g_string_new(NULL); + g_string_printf(errmsg, "Failed to write memory: %d\n", result); + qemu_plugin_outs(errmsg->str); + g_string_free(errmsg, true); + return; + } + + GByteArray *read_data =3D g_byte_array_new(); + + result =3D qemu_plugin_read_memory_hwaddr(addr, read_data, + patch_data->len); + + qemu_plugin_outs("Reading memory...\n"); + + if (result !=3D QEMU_PLUGIN_HWADDR_OPERATION_OK) { + GString *errmsg =3D g_string_new(NULL); + g_string_printf(errmsg, "Failed to read memory: %d\n", result); + qemu_plugin_outs(errmsg->str); + g_string_free(errmsg, true); + return; + } + + if (memcmp(patch_data->data, read_data->data, patch_data->len) !=3D 0)= { + qemu_plugin_outs("Failed to read back written data\n"); + } + + qemu_plugin_outs("Success!\n"); + + return; +} + +static void patch_vaddr(unsigned int vcpu_index, void *userdata) +{ + uint64_t addr =3D (uint64_t)userdata; + uint64_t hwaddr =3D 0; + if (!qemu_plugin_translate_vaddr(addr, &hwaddr)) { + qemu_plugin_outs("Failed to translate vaddr\n"); + return; + } + GString *str =3D g_string_new(NULL); + g_string_printf(str, "patching: @0x%" + PRIx64 " hw: @0x%" PRIx64 "\n", + addr, hwaddr); + qemu_plugin_outs(str->str); + g_string_free(str, true); + + qemu_plugin_outs("Writing memory (vaddr)...\n"); + + if (!qemu_plugin_write_memory_vaddr(addr, patch_data)) { + qemu_plugin_outs("Failed to write memory\n"); + return; + } + + qemu_plugin_outs("Reading memory (vaddr)...\n"); + + + GByteArray *read_data =3D g_byte_array_new(); + + if (!qemu_plugin_read_memory_vaddr(addr, read_data, patch_data->len)) { + qemu_plugin_outs("Failed to read memory\n"); + return; + } + + if (memcmp(patch_data->data, read_data->data, patch_data->len) !=3D 0)= { + qemu_plugin_outs("Failed to read back written data\n"); + } + + qemu_plugin_outs("Success!\n"); + + return; +} + +static void debug_disas(unsigned int vcpu_index, void *userdata) +{ + GString *debug_info =3D (GString *)userdata; + qemu_plugin_outs(debug_info->str); +} + +static void debug_print_newline(unsigned int vcpu_index, void *userdata) +{ + qemu_plugin_outs("\n"); +} + +/* + * Callback on translation of a translation block. + */ +static void vcpu_tb_trans_cb(qemu_plugin_id_t id, struct qemu_plugin_tb *t= b) +{ + uint64_t addr =3D 0; + GByteArray *insn_data =3D g_byte_array_new(); + for (size_t i =3D 0; i < qemu_plugin_tb_n_insns(tb); i++) { + struct qemu_plugin_insn *insn =3D qemu_plugin_tb_get_insn(tb, i); + + if (use_hwaddr) { + uint64_t vaddr =3D qemu_plugin_insn_vaddr(insn); + if (!qemu_plugin_translate_vaddr(vaddr, &addr)) { + qemu_plugin_outs("Failed to translate vaddr\n"); + continue; + } + } else { + addr =3D qemu_plugin_insn_vaddr(insn); + } + + g_byte_array_set_size(insn_data, qemu_plugin_insn_size(insn)); + qemu_plugin_insn_data(insn, insn_data->data, insn_data->len); + + if (insn_data->len >=3D target_data->len && + !memcmp(insn_data->data, target_data->data, + MIN(target_data->len, insn_data->len))) { + if (use_hwaddr) { + qemu_plugin_register_vcpu_tb_exec_cb(tb, patch_hwaddr, + QEMU_PLUGIN_CB_NO_REG= S, + (void *)addr); + } else { + qemu_plugin_register_vcpu_tb_exec_cb(tb, patch_vaddr, + QEMU_PLUGIN_CB_NO_REG= S, + (void *)addr); + } + } + } + for (size_t i =3D 0; i < qemu_plugin_tb_n_insns(tb); i++) { + struct qemu_plugin_insn *insn =3D qemu_plugin_tb_get_insn(tb, i); + uint64_t vaddr =3D qemu_plugin_insn_vaddr(insn); + uint64_t hwaddr =3D (uint64_t)qemu_plugin_insn_haddr(insn); + uint64_t translated_hwaddr =3D 0; + if (!qemu_plugin_translate_vaddr(vaddr, &translated_hwaddr)) { + qemu_plugin_outs("Failed to translate vaddr\n"); + continue; + } + char *disas =3D qemu_plugin_insn_disas(insn); + GString *str =3D g_string_new(NULL); + g_string_printf(str, + "vaddr: 0x%" PRIx64 " hwaddr: 0x%" PRIx64 + " translated: 0x%" PRIx64 " : %s\n", + vaddr, hwaddr, translated_hwaddr, disas); + g_free(disas); + if (debug_insns) { + qemu_plugin_register_vcpu_insn_exec_cb(insn, debug_disas, + QEMU_PLUGIN_CB_NO_REGS, + str); + } + + } + + if (debug_insns) { + qemu_plugin_register_vcpu_tb_exec_cb(tb, debug_print_newline, + QEMU_PLUGIN_CB_NO_REGS, + NULL); + } + + g_byte_array_free(insn_data, true); +} + +static void usage(void) +{ + fprintf(stderr, "Usage: ,target=3D,patch=3D" + "[,use_hwaddr=3D]" + "[,debug_insns=3D]\n"); +} + +/* + * Called when the plugin is installed + */ +QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, + const qemu_info_t *info, int ar= gc, + char **argv) +{ + + use_hwaddr =3D true; + debug_insns =3D false; + target_data =3D NULL; + patch_data =3D NULL; + + if (argc > 4) { + usage(); + return -1; + } + + for (size_t i =3D 0; i < argc; i++) { + char *opt =3D argv[i]; + g_auto(GStrv) tokens =3D g_strsplit(opt, "=3D", 2); + if (g_strcmp0(tokens[0], "use_hwaddr") =3D=3D 0) { + if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &use_hwaddr)= ) { + fprintf(stderr, + "Failed to parse boolean argument use_hwaddr\n"); + return -1; + } + } else if (g_strcmp0(tokens[0], "debug_insns") =3D=3D 0) { + if (!qemu_plugin_bool_parse(tokens[0], tokens[1], &debug_insns= )) { + fprintf(stderr, + "Failed to parse boolean argument debug_insns\n"); + return -1; + } + } else if (g_strcmp0(tokens[0], "target") =3D=3D 0) { + target_data =3D str_to_bytes(tokens[1]); + if (!target_data) { + fprintf(stderr, + "Failed to parse target bytes.\n"); + return -1; + } + } else if (g_strcmp0(tokens[0], "patch") =3D=3D 0) { + patch_data =3D str_to_bytes(tokens[1]); + if (!patch_data) { + fprintf(stderr, "Failed to parse patch bytes.\n"); + return -1; + } + } else { + fprintf(stderr, "Unknown argument: %s\n", tokens[0]); + usage(); + return -1; + } + } + + if (!target_data) { + fprintf(stderr, "target argument is required\n"); + usage(); + return -1; + } + + if (!patch_data) { + fprintf(stderr, "patch argument is required\n"); + usage(); + return -1; + } + + if (target_data->len !=3D patch_data->len) { + fprintf(stderr, "Target and patch data must be the same length\n"); + return -1; + } + + qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans_cb); + + return 0; +} diff --git a/tests/tcg/x86_64/Makefile.softmmu-target b/tests/tcg/x86_64/Ma= kefile.softmmu-target index ef6bcb4dc7..8d3a067c33 100644 --- a/tests/tcg/x86_64/Makefile.softmmu-target +++ b/tests/tcg/x86_64/Makefile.softmmu-target @@ -7,18 +7,27 @@ # =20 I386_SYSTEM_SRC=3D$(SRC_PATH)/tests/tcg/i386/system -X64_SYSTEM_SRC=3D$(SRC_PATH)/tests/tcg/x86_64/system +X86_64_SYSTEM_SRC=3D$(SRC_PATH)/tests/tcg/x86_64/system =20 # These objects provide the basic boot code and helper functions for all t= ests CRT_OBJS=3Dboot.o =20 -CRT_PATH=3D$(X64_SYSTEM_SRC) -LINK_SCRIPT=3D$(X64_SYSTEM_SRC)/kernel.ld +X86_64_TEST_C_SRCS=3D$(wildcard $(X86_64_SYSTEM_SRC)/*.c) +X86_64_TEST_S_SRCS=3D + +X86_64_C_TESTS =3D $(patsubst $(X86_64_SYSTEM_SRC)/%.c, %, $(X86_64_TEST_C= _SRCS)) +X86_64_S_TESTS =3D $(patsubst $(X86_64_SYSTEM_SRC)/%.S, %, $(X86_64_TEST_S= _SRCS)) + +X86_64_TESTS =3D $(X86_64_C_TESTS) +X86_64_TESTS +=3D $(X86_64_S_TESTS) + +CRT_PATH=3D$(X86_64_SYSTEM_SRC) +LINK_SCRIPT=3D$(X86_64_SYSTEM_SRC)/kernel.ld LDFLAGS=3D-Wl,-T$(LINK_SCRIPT) -Wl,-melf_x86_64 CFLAGS+=3D-nostdlib -ggdb -O0 $(MINILIB_INC) LDFLAGS+=3D-static -nostdlib $(CRT_OBJS) $(MINILIB_OBJS) -lgcc =20 -TESTS+=3D$(MULTIARCH_TESTS) +TESTS+=3D$(X86_64_TESTS) $(MULTIARCH_TESTS) EXTRA_RUNS+=3D$(MULTIARCH_RUNS) =20 # building head blobs @@ -27,11 +36,24 @@ EXTRA_RUNS+=3D$(MULTIARCH_RUNS) %.o: $(CRT_PATH)/%.S $(CC) $(CFLAGS) $(EXTRA_CFLAGS) -Wa,--noexecstack -c $< -o $@ =20 -# Build and link the tests +# Build and link the multiarch tests %: %.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS) $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) =20 +# Build and link the arch tests +%: $(X86_64_SYSTEM_SRC)/%.c $(LINK_SCRIPT) $(CRT_OBJS) $(MINILIB_OBJS) + $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $< -o $@ $(LDFLAGS) + memory: CFLAGS+=3D-DCHECK_UNALIGNED=3D1 +patch-target: CFLAGS+=3D-O0 =20 # Running QEMU_OPTS+=3D-device isa-debugcon,chardev=3Doutput -device isa-debug-exit,= iobase=3D0xf4,iosize=3D0x4 -kernel + +# Add patch-target to ADDITIONAL_PLUGINS_TESTS +ADDITIONAL_PLUGINS_TESTS +=3D patch-target + +run-plugin-patch-target-with-libpatch.so: \ + PLUGIN_ARGS=3D$(COMMA)target=3Dffc0$(COMMA)patch=3D9090$(COMMA)use_hwaddr= =3Dtrue$(COMMA)debug_insns=3Dfalse +run-plugin-patch-target-with-libpatch.so: \ + CHECK_PLUGIN_OUTPUT_COMMAND=3D$(X86_64_SYSTEM_SRC)/validate-patch.py $@.o= ut \ No newline at end of file diff --git a/tests/tcg/x86_64/system/patch-target.c b/tests/tcg/x86_64/syst= em/patch-target.c new file mode 100644 index 0000000000..671987a873 --- /dev/null +++ b/tests/tcg/x86_64/system/patch-target.c @@ -0,0 +1,32 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (C) 2025, Rowan Hart + * + * License: GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * This test target increments a value 100 times. The patcher converts the + * inc instruction to a nop, so it only increments the value once. + * + */ +#include + +int main(void) +{ + ml_printf("Running test...\n"); +#if defined(__x86_64__) + ml_printf("Testing insn memory read/write...\n"); + unsigned int x =3D 0; + for (int i =3D 0; i < 100; i++) { + asm volatile ( + "inc %[x]" + : [x] "+a" (x) + ); + } + ml_printf("Value: %d\n", x); +#else + #error "This test is only valid for x86_64 architecture." +#endif + return 0; +} diff --git a/tests/tcg/x86_64/system/validate-patch.py b/tests/tcg/x86_64/s= ystem/validate-patch.py new file mode 100755 index 0000000000..700950eae5 --- /dev/null +++ b/tests/tcg/x86_64/system/validate-patch.py @@ -0,0 +1,39 @@ +#!/usr/bin/env python3 +# +# validate-patch.py: check the patch applies +# +# This program takes two inputs: +# - the plugin output +# - the binary output +# +# Copyright (C) 2024 +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import sys +from argparse import ArgumentParser + +def main() -> None: + """ + Process the arguments, injest the program and plugin out and + verify they match up and report if they do not. + """ + parser =3D ArgumentParser(description=3D"Validate patch") + parser.add_argument('test_output', + help=3D"The output from the test itself") + parser.add_argument('plugin_output', + help=3D"The output from plugin") + args =3D parser.parse_args() + + with open(args.test_output, 'r') as f: + test_data =3D f.read() + with open(args.plugin_output, 'r') as f: + plugin_data =3D f.read() + if "Value: 1" in test_data: + sys.exit(0) + else: + sys.exit(1) + +if __name__ =3D=3D "__main__": + main() + --=20 2.49.0 From nobody Fri Dec 19 13:06:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1747965930; cv=none; d=zohomail.com; s=zohoarc; b=Rl35+5kQe0VT78eYShgmwpSYaVhR1Ma8Gzpxt2lPJiIihMmSYsEXmThJOiMQKuH23lTxvs1e8fdk0JW65pKVT6C9I88orBroK/bwqrTDwQNAGjdRf6K4VhxzDF4Qah+zF5LJ7FxQMENX1jIUj7JWfDilTsElbG1uLyXFN33TTFM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747965930; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=ezXosNFfgXBg6PJCV3m2vrTMDcaA5X2aQFU8P/ZfaMo=; b=DJDbxciSI6NMiwvA3a4kr0GJ96C7HMxPpJYjS+LK15GULkw6ecK0MVMzhiRKCzteerHnHt+pSRbnHLKfW7RQSyJS3PKmUtcuPc0W3hHkDIXkK0SZMagoZjpiE47PbuKEk7UDJegXZyWUgEwXz78VNdXjWiy6sWYaE+4OxUXJIbs= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747965930409783.6848552805435; Thu, 22 May 2025 19:05:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uIHlX-0001HC-AQ; Thu, 22 May 2025 22:04:07 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uIHlR-0001Fd-PQ for qemu-devel@nongnu.org; Thu, 22 May 2025 22:04:03 -0400 Received: from mail-pf1-x42f.google.com ([2607:f8b0:4864:20::42f]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1uIHlN-0007kt-CF for qemu-devel@nongnu.org; Thu, 22 May 2025 22:04:01 -0400 Received: by mail-pf1-x42f.google.com with SMTP id d2e1a72fcca58-742c46611b6so7243507b3a.1 for ; Thu, 22 May 2025 19:03:55 -0700 (PDT) Received: from shemhazi.lan ([50.46.174.34]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-742a98a242asm11820818b3a.164.2025.05.22.19.03.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 May 2025 19:03:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747965834; x=1748570634; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ezXosNFfgXBg6PJCV3m2vrTMDcaA5X2aQFU8P/ZfaMo=; b=H1hfdPFFCC43CfqBgM4EZ8eClFIWcKHfoghKgTl2L98W6rYiu3KE6uZ/Uu9XSan14K 3BRq6MAC5dVBRtfCDogGCjT0Zz2QEf3w0C9FDq4OwMTvUrvFZOLW+9G9AxPrCJ7sL7u7 9lE2f4vjocSJxXvJdVFV52Cg2FuOCjhU0EDpi4zi+66HS1zXfIMZNMdaJiYLTWUHKKo/ cVah/L2Z+fFmIRVXki2leVmhuUcvIU18Bmh09jWYxHcOJ3YLTXqVLUvOqd+PkDOrlLNM yQnfZY77VtH6g/GTfGpsVLX0hES8Bb/VlOcnU/lne0W9jamfvYs7fVIlz0vY5CO1zv2Z hDOw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747965834; x=1748570634; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ezXosNFfgXBg6PJCV3m2vrTMDcaA5X2aQFU8P/ZfaMo=; b=sZ01kN96LVZHZI83Pcl1ewvyLvQdTJFegbKRa6dNFb1h6547oC2/IhQ53B9WEJvnAy 7mxBL3J9ZEwbksFnhZvC3Z83WOahgaf8ZwZciV4/nCyjV9Um+GoIggYnXXA+CTG92cQf Fw80vXAE/z0l5agPY4Gky1WJc0LhIGHB5wAH5zJDL5Ta6nu/LW7/RzCWvIdGmOT5ps87 4rA1TYPxtMdwrULnz7nH++nkB4CC0eDZGWs0SCu3Ui6qOUKGwCwc5w4tlUIIBo0VRthV Tlv8qZt2CCiPggVohwNuB90J9LjYKuz1UsxN6R63Vvspqjm56e/KAOyC0SceRn9IGOHb 5tKQ== X-Gm-Message-State: AOJu0YzDIsp+EQiOiEOCDHFtYLtmpIaOerQAkhIvR9IH4brmvaAb0VfB PE0B5k4k4Y9mvvzuJVwvLd+HXGNDn3TQC31Xh5e9bijQxZe8BPyr4KO2Xo/jKz/hGx8= X-Gm-Gg: ASbGncsUbhYnsOGhN9dzbKl7KnL9J7PbQi7VUAQezAVIuouAPdc+O7qsA+RhXDHuw5/ JkALEGjhJcYUqH+C0jgYXimhwrzSMW8z7JwCCiKFj1rGnDuSDpAu5h9/Orxn950bHfl/NzIuWL6 LnI1+2wPpUnCgHG6PiodKu589QE50coI95xCttAxRYA/N1w8nM/m5pgV9WglCWbIUxY9bR0H/Eg OwAFUH5lhHoYtqFE2BcKAzUZAZRybOS+8EPjD8KxIEr1avDbdsM8qbGeCv3ma5SV9N5TrUAWCvf iTf0xwwCqGsO6xOLW+NYCt+U89ioJewUzTUFFqzn99MqrPkOyUo= X-Google-Smtp-Source: AGHT+IG58M6+Ltyt/slfa5cmevXL5Vh8JvS1OHm/lj44fvRpUR2VKAzlDwAsw4usYvIn6+ZqYiYg7g== X-Received: by 2002:a05:6a00:3492:b0:742:9bd3:cd1f with SMTP id d2e1a72fcca58-742acd728eamr35672043b3a.23.1747965831520; Thu, 22 May 2025 19:03:51 -0700 (PDT) From: Rowan Hart To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , Paolo Bonzini , Mahmoud Mandour , Alexandre Iooss , Eduardo Habkost , novafacing Subject: [PATCH v4 7/9] plugins: Add hypercalls plugin and test Date: Thu, 22 May 2025 19:03:41 -0700 Message-ID: <20250523020344.1341179-8-rowanbhart@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250523020344.1341179-1-rowanbhart@gmail.com> References: <20250523020344.1341179-1-rowanbhart@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::42f; envelope-from=rowanbhart@gmail.com; helo=mail-pf1-x42f.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1747965931097116600 Content-Type: text/plain; charset="utf-8" From: novafacing This patch adds a plugin that implements a simple form of hypercalls from guest code to the plugin by using the register read API. It accepts only one hypercall, which writes a magic value to guest memory. Signed-off-by: novafacing Signed-off-by: Rowan Hart --- tests/tcg/Makefile.target | 1 + tests/tcg/plugins/hypercalls.c | 552 ++++++++++++++++++ tests/tcg/plugins/meson.build | 2 +- tests/tcg/x86_64/Makefile.softmmu-target | 6 +- tests/tcg/x86_64/system/hypercalls-target.c | 45 ++ .../tcg/x86_64/system/validate-hypercalls.py | 40 ++ 6 files changed, 644 insertions(+), 2 deletions(-) create mode 100644 tests/tcg/plugins/hypercalls.c create mode 100644 tests/tcg/x86_64/system/hypercalls-target.c create mode 100755 tests/tcg/x86_64/system/validate-hypercalls.py diff --git a/tests/tcg/Makefile.target b/tests/tcg/Makefile.target index 4b709a9d18..5ac9638102 100644 --- a/tests/tcg/Makefile.target +++ b/tests/tcg/Makefile.target @@ -177,6 +177,7 @@ RUN_TESTS+=3D$(EXTRA_RUNS) # exercise things. We can define them on a per-test basis here. run-plugin-%-with-libmem.so: PLUGIN_ARGS=3D$(COMMA)inline=3Dtrue run-plugin-%-with-libpatch.so: PLUGIN_ARGS=3D$(COMMA)target=3Dffffffff$(CO= MMA)patch=3D00000000 +run-plugin-%-with-libhypercalls.so: PLUGIN_ARGS=3D$(COMMA)ignore_unsupport= ed=3Dtrue =20 ifeq ($(filter %-softmmu, $(TARGET)),) run-%: % diff --git a/tests/tcg/plugins/hypercalls.c b/tests/tcg/plugins/hypercalls.c new file mode 100644 index 0000000000..3abbe1bf30 --- /dev/null +++ b/tests/tcg/plugins/hypercalls.c @@ -0,0 +1,552 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (C) 2024, Rowan Hart + * + * License: GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * This plugin implements a simple hypercall interface for guests (both sy= stem + * and user mode) to call certain operations from the host. + */ +#include "glib.h" +#include "glibconfig.h" +#include +#include +#include +#include +#include +#include +#include + +#include + +QEMU_PLUGIN_EXPORT int qemu_plugin_version =3D QEMU_PLUGIN_VERSION; + +#define AARCH64_N_HYPERCALL_INSNS (28) +#define AARCH64_HYPERCALL_INSN_LEN (4) +#define AARCH64_HYPERCALL_MAX (AARCH64_N_HYPERCALL_INSNS) +#define ARM_N_HYPERCALL_INSNS (12) +#define ARM_HYPERCALL_INSN_LEN (4) +#define ARM_HYPERCALL_MAX (ARM_N_HYPERCALL_INSNS) +#define X86_HYPERCALL_INSN_LEN (2) +#define X86_HYPERCALL_VALUE_BASE (0x4711) +#define X86_HYPERCALL_MAX (0x10000) +#define N_HYPERCALL_ARGS (4) + +static bool ignore_unsupported; + +static struct qemu_plugin_register *get_register(const char *name); +static uint64_t byte_array_to_uint64(GByteArray *buf); + +enum HypercallInsnType { + CONSTANT, + CALLBACK, +}; + + +/* + * Checks an instruction and returns its hypercall number, if it is + * a hypercall instruction, or -1 if it is not. Called at execution + * time. + */ +typedef int32_t (*hypercall_nr_cb)(GByteArray *); + +/* + * Checks an instruction and returns whether it is a hypercall, or -1 if i= t is + * not. Called at execution time. + */ +typedef bool (*is_hypercall_cb)(GByteArray *); + +/* + * Specifies a Hypercall for an architecture: + * + * - Architecture name + * - Whether it is enabled + * - The hypercall instruction + * - The register names to pass the hypercall # and args + */ +struct HypercallSpec { + const bool enabled; + const char *name; + const bool le; + const char *args[N_HYPERCALL_ARGS]; + const hypercall_nr_cb hypercall_nr_cb; + const is_hypercall_cb is_hypercall_cb; +}; + +static int32_t aarch64_hypercall_nr_cb(GByteArray *insn) +{ + if (insn->len !=3D AARCH64_HYPERCALL_INSN_LEN) { + return -1; + } + + static const uint8_t + hypercall_insns[AARCH64_N_HYPERCALL_INSNS][AARCH64_HYPERCALL_INSN_LEN]= =3D { + { 0xaa, 0x4, 0x0, 0x84 }, + { 0xaa, 0x5, 0x0, 0xa5 }, + { 0xaa, 0x6, 0x0, 0xc6 }, + { 0xaa, 0x7, 0x0, 0xe7 }, + { 0xaa, 0x8, 0x1, 0x8 }, + { 0xaa, 0x9, 0x1, 0x29 }, + { 0xaa, 0xa, 0x1, 0x4a }, + { 0xaa, 0xb, 0x1, 0x6b }, + { 0xaa, 0xc, 0x1, 0x8c }, + { 0xaa, 0xd, 0x1, 0xad }, + { 0xaa, 0xe, 0x1, 0xce }, + { 0xaa, 0xf, 0x1, 0xef }, + { 0xaa, 0x10, 0x2, 0x10 }, + { 0xaa, 0x11, 0x2, 0x31 }, + { 0xaa, 0x12, 0x2, 0x52 }, + { 0xaa, 0x13, 0x2, 0x73 }, + { 0xaa, 0x14, 0x2, 0x94 }, + { 0xaa, 0x15, 0x2, 0xb5 }, + { 0xaa, 0x16, 0x2, 0xd6 }, + { 0xaa, 0x17, 0x2, 0xf7 }, + { 0xaa, 0x18, 0x3, 0x18 }, + { 0xaa, 0x19, 0x3, 0x39 }, + { 0xaa, 0x1a, 0x3, 0x5a }, + { 0xaa, 0x1b, 0x3, 0x7b }, + { 0xaa, 0x1c, 0x3, 0x9c }, + { 0xaa, 0x1d, 0x3, 0xbd }, + { 0xaa, 0x1e, 0x3, 0xde }, + { 0xaa, 0x1f, 0x3, 0xff }, + }; + + for (int32_t i =3D 0; i < AARCH64_N_HYPERCALL_INSNS; i++) { + if (!memcmp(hypercall_insns[i], insn->data, insn->len)) { + return i; + } + } + return -1; +} + +static bool aarch64_is_hypercall_cb(GByteArray *insn) +{ + return aarch64_hypercall_nr_cb(insn) < 0; +} + + +static int32_t aarch64_be_hypercall_nr_cb(GByteArray *insn) +{ + if (insn->len !=3D AARCH64_HYPERCALL_INSN_LEN) { + return -1; + } + + static const uint8_t + hypercall_insns[AARCH64_N_HYPERCALL_INSNS][AARCH64_HYPERCALL_INSN_LEN]= =3D { + {0x84, 0x0, 0x4, 0xaa}, + {0xa5, 0x0, 0x5, 0xaa}, + {0xc6, 0x0, 0x6, 0xaa}, + {0xe7, 0x0, 0x7, 0xaa}, + {0x8, 0x1, 0x8, 0xaa}, + {0x29, 0x1, 0x9, 0xaa}, + {0x4a, 0x1, 0xa, 0xaa}, + {0x6b, 0x1, 0xb, 0xaa}, + {0x8c, 0x1, 0xc, 0xaa}, + {0xad, 0x1, 0xd, 0xaa}, + {0xce, 0x1, 0xe, 0xaa}, + {0xef, 0x1, 0xf, 0xaa}, + {0x10, 0x2, 0x10, 0xaa}, + {0x31, 0x2, 0x11, 0xaa}, + {0x52, 0x2, 0x12, 0xaa}, + {0x73, 0x2, 0x13, 0xaa}, + {0x94, 0x2, 0x14, 0xaa}, + {0xb5, 0x2, 0x15, 0xaa}, + {0xd6, 0x2, 0x16, 0xaa}, + {0xf7, 0x2, 0x17, 0xaa}, + {0x18, 0x3, 0x18, 0xaa}, + {0x39, 0x3, 0x19, 0xaa}, + {0x5a, 0x3, 0x1a, 0xaa}, + {0x7b, 0x3, 0x1b, 0xaa}, + {0x9c, 0x3, 0x1c, 0xaa}, + {0xbd, 0x3, 0x1d, 0xaa}, + {0xde, 0x3, 0x1e, 0xaa}, + {0xff, 0x3, 0x1f, 0xaa}, + }; + + for (int32_t i =3D 0; i < AARCH64_N_HYPERCALL_INSNS; i++) { + if (!memcmp(hypercall_insns[i], insn->data, insn->len)) { + return i; + } + } + return -1; +} + +static bool aarch64_be_is_hypercall_cb(GByteArray *insn) +{ + return aarch64_be_hypercall_nr_cb(insn) < 0; +} + + +static int32_t arm_hypercall_nr_cb(GByteArray *insn) +{ + if (insn->len !=3D ARM_HYPERCALL_INSN_LEN) { + return -1; + } + + static const uint8_t + hypercall_insns[ARM_N_HYPERCALL_INSNS][ARM_HYPERCALL_INSN_LEN] =3D { + { 0xe1, 0x84, 0x40, 0x4 }, + { 0xe1, 0x85, 0x50, 0x5 }, + { 0xe1, 0x86, 0x60, 0x6 }, + { 0xe1, 0x87, 0x70, 0x7 }, + { 0xe1, 0x88, 0x80, 0x8 }, + { 0xe1, 0x89, 0x90, 0x9 }, + { 0xe1, 0x8a, 0xa0, 0xa }, + { 0xe1, 0x8b, 0xb0, 0xb }, + { 0xe1, 0x8c, 0xc0, 0xc }, + { 0xe1, 0x8d, 0xd0, 0xd }, + { 0xe1, 0x8e, 0xe0, 0xe }, + { 0xe1, 0x8f, 0xf0, 0xf }, + }; + + for (int32_t i =3D 0; i < ARM_N_HYPERCALL_INSNS; i++) { + if (!memcmp(hypercall_insns[i], insn->data, insn->len)) { + return i; + } + } + return -1; +} + +static bool arm_is_hypercall_cb(GByteArray *insn) +{ + return arm_hypercall_nr_cb(insn) < 0; +} + +static int32_t arm_be_hypercall_nr_cb(GByteArray *insn) +{ + if (insn->len !=3D ARM_HYPERCALL_INSN_LEN) { + return -1; + } + + static const uint8_t + hypercall_insns[ARM_N_HYPERCALL_INSNS][ARM_HYPERCALL_INSN_LEN] =3D { + {0x4, 0x40, 0x84, 0xe1}, + {0x5, 0x50, 0x85, 0xe1}, + {0x6, 0x60, 0x86, 0xe1}, + {0x7, 0x70, 0x87, 0xe1}, + {0x8, 0x80, 0x88, 0xe1}, + {0x9, 0x90, 0x89, 0xe1}, + {0xa, 0xa0, 0x8a, 0xe1}, + {0xb, 0xb0, 0x8b, 0xe1}, + {0xc, 0xc0, 0x8c, 0xe1}, + {0xd, 0xd0, 0x8d, 0xe1}, + {0xe, 0xe0, 0x8e, 0xe1}, + {0xf, 0xf0, 0x8f, 0xe1}, + }; + + for (int32_t i =3D 0; i < ARM_N_HYPERCALL_INSNS; i++) { + if (!memcmp(hypercall_insns[i], insn->data, insn->len)) { + return i; + } + } + return -1; +} + +static bool arm_be_is_hypercall_cb(GByteArray *insn) +{ + return arm_be_hypercall_nr_cb(insn) < 0; +} + +static int32_t x86_64_hypercall_nr_cb(GByteArray *insn) +{ + if (insn->len !=3D X86_HYPERCALL_INSN_LEN) { + return -1; + } + + uint8_t cpuid[] =3D { 0x0f, 0xa2 }; + if (!memcmp(cpuid, insn->data, insn->len)) { + GByteArray *reg =3D g_byte_array_new(); + qemu_plugin_read_register(get_register("rax"), reg); + uint64_t value =3D byte_array_to_uint64(reg); + g_byte_array_free(reg, true); + + if (!(value & X86_HYPERCALL_VALUE_BASE)) { + return -1; + } + + value =3D (value >> 16) & 0xffff; + + if (value >=3D X86_HYPERCALL_MAX) { + return -1; + } + + return (int32_t)value; + } + + return -1; +} + +static bool x86_64_is_hypercall_cb(GByteArray *insn) +{ + if (insn->len !=3D X86_HYPERCALL_INSN_LEN) { + return false; + } + + uint8_t cpuid[] =3D { 0x0f, 0xa2 }; + if (!memcmp(cpuid, insn->data, insn->len)) { + return true; + } + + return false; +} + +static int32_t i386_hypercall_nr_cb(GByteArray *insn) +{ + if (insn->len !=3D X86_HYPERCALL_INSN_LEN) { + return -1; + } + + uint8_t cpuid[] =3D { 0x0f, 0xa2 }; + if (!memcmp(cpuid, insn->data, insn->len)) { + GByteArray *reg =3D g_byte_array_new(); + qemu_plugin_read_register(get_register("eax"), reg); + uint64_t value =3D byte_array_to_uint64(reg); + g_byte_array_free(reg, true); + + if (!(value & X86_HYPERCALL_VALUE_BASE)) { + return -1; + } + + value =3D (value >> 16) & 0xffff; + + if (value >=3D X86_HYPERCALL_MAX) { + return -1; + } + return (int32_t)value; + } + + return -1; + +} + +static bool i386_is_hypercall_cb(GByteArray *insn) +{ + if (insn->len !=3D X86_HYPERCALL_INSN_LEN) { + return false; + } + + uint8_t cpuid[] =3D { 0x0f, 0xa2 }; + if (!memcmp(cpuid, insn->data, insn->len)) { + return true; + } + + return false; + +} + +static const struct HypercallSpec *hypercall_spec; + +static const struct HypercallSpec hypercall_specs[] =3D { + { true, "aarch64", true, { + "x0", "x1", "x2", "x3", + }, aarch64_hypercall_nr_cb, aarch64_is_hypercall_cb + }, + { true, "aarch64_be", false, { + "x0", "x1", "x2", "x3", + }, aarch64_be_hypercall_nr_cb, aarch64_be_is_hypercall_cb + }, + { true, "arm", true, { + "r0", "r1", "r2", "r3", + }, arm_hypercall_nr_cb, arm_is_hypercall_cb + }, + { true, "armeb", false, { + "r0", "r1", "r2", "r3" + }, arm_be_hypercall_nr_cb, arm_be_is_hypercall_cb + }, + { true, "i386", true, { + "edi", "esi", "edx", "ecx" + }, i386_hypercall_nr_cb, i386_is_hypercall_cb + }, + { true, "x86_64", true, { + "rdi", "rsi", "rdx", "rcx" + + }, x86_64_hypercall_nr_cb, x86_64_is_hypercall_cb + }, + { false, NULL, .le =3D false, {NULL, NULL, NULL, NULL}, NULL}, +}; + +static GArray *hypercall_insns; + +/* + * Returns a handle to a register with a given name, or NULL if there is no + * such register. + */ +static struct qemu_plugin_register *get_register(const char *name) +{ + GArray *registers =3D qemu_plugin_get_registers(); + + struct qemu_plugin_register *handle =3D NULL; + + qemu_plugin_reg_descriptor *reg_descriptors =3D + (qemu_plugin_reg_descriptor *)registers->data; + + for (size_t i =3D 0; i < registers->len; i++) { + if (!strcmp(reg_descriptors[i].name, name)) { + handle =3D reg_descriptors[i].handle; + } + } + + g_array_free(registers, true); + + return handle; +} + +/* + * Transforms a byte array with at most 8 entries into a uint64_t + * depending on the target machine's endianness. + */ +static uint64_t byte_array_to_uint64(GByteArray *buf) +{ + uint64_t value =3D 0; + if (hypercall_spec->le) { + for (int i =3D 0; i < buf->len && i < sizeof(uint64_t); i++) { + value |=3D ((uint64_t)buf->data[i]) << (i * 8); + } + } else { + for (int i =3D 0; i < buf->len && i < sizeof(uint64_t); i++) { + value |=3D ((uint64_t)buf->data[i]) << ((buf->len - 1 - i) * 8= ); + } + } + return value; +} + +/* + * Handle a "hypercall" instruction, which has some special meaning for th= is + * plugin. + */ +static void hypercall(unsigned int vcpu_index, void *userdata) +{ + GByteArray *insn_data =3D (GByteArray *)userdata; + int32_t hypercall_nr =3D hypercall_spec->hypercall_nr_cb(insn_data); + + if (hypercall_nr < 0) { + return; + } + + uint64_t args[N_HYPERCALL_ARGS] =3D {0}; + GByteArray *buf =3D g_byte_array_new(); + for (size_t i =3D 0; i < N_HYPERCALL_ARGS; i++) { + g_byte_array_set_size(buf, 0); + struct qemu_plugin_register *reg =3D + get_register(hypercall_spec->args[i]); + qemu_plugin_read_register(reg, buf); + args[i] =3D byte_array_to_uint64(buf); + } + g_byte_array_free(buf, true); + + switch (hypercall_nr) { + /* + * The write hypercall (#0x01) tells the plugin to write random bytes + * of a given size into the memory of the emulated system at a particu= lar + * vaddr + */ + case 1: { + GByteArray *data =3D g_byte_array_new(); + g_byte_array_set_size(data, args[1]); + for (uint64_t i =3D 0; i < args[1]; i++) { + data->data[i] =3D (uint8_t)g_random_int(); + } + qemu_plugin_write_memory_vaddr(args[0], data); + break; + } + default: + break; + } +} + +/* + * Callback on translation of a translation block. + */ +static void vcpu_tb_trans_cb(qemu_plugin_id_t id, struct qemu_plugin_tb *t= b) +{ + for (size_t i =3D 0; i < qemu_plugin_tb_n_insns(tb); i++) { + struct qemu_plugin_insn *insn =3D qemu_plugin_tb_get_insn(tb, i); + GByteArray *insn_data =3D g_byte_array_new(); + size_t insn_len =3D qemu_plugin_insn_size(insn); + g_byte_array_set_size(insn_data, insn_len); + qemu_plugin_insn_data(insn, insn_data->data, insn_data->len); + + if (hypercall_spec->is_hypercall_cb(insn_data)) { + g_array_append_val(hypercall_insns, insn_data); + qemu_plugin_register_vcpu_insn_exec_cb(insn, hypercall, + QEMU_PLUGIN_CB_R_REGS, + (void *)insn_data); + } else { + g_byte_array_free(insn_data, true); + } + + } +} + +static void atexit_cb(qemu_plugin_id_t id, void *userdata) +{ + for (size_t i =3D 0; i < hypercall_insns->len; i++) { + g_byte_array_free(g_array_index(hypercall_insns, GByteArray *, i), + true); + } + + g_array_free(hypercall_insns, true); +} + +static void usage(void) +{ + fprintf(stderr, + "Usage: ,[ignore_unsupported=3D]"); +} + +/* + * Called when the plugin is installed + */ +QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_id_t id, + const qemu_info_t *info, int ar= gc, + char **argv) +{ + if (argc > 1) { + usage(); + return -1; + } + + for (size_t i =3D 0; i < argc; i++) { + char *opt =3D argv[i]; + g_auto(GStrv) tokens =3D g_strsplit(opt, "=3D", 2); + if (g_strcmp0(tokens[0], "ignore_unsupported") =3D=3D 0) { + if (!qemu_plugin_bool_parse(tokens[0], + tokens[1], &ignore_unsupported)) { + fprintf(stderr, + "Failed to parse argument ignore_unsupported\n"); + return -1; + } + } else { + fprintf(stderr, "Unknown argument: %s\n", tokens[0]); + usage(); + return -1; + } + } + + + hypercall_spec =3D &hypercall_specs[0]; + + while (hypercall_spec->name !=3D NULL) { + if (!strcmp(hypercall_spec->name, info->target_name)) { + break; + } + hypercall_spec++; + } + + if (hypercall_spec->name =3D=3D NULL || !hypercall_spec->enabled) { + qemu_plugin_outs("Error: no hypercall spec."); + if (ignore_unsupported) { + return 0; + } + return -1; + } + + hypercall_insns =3D g_array_new(true, true, sizeof(GByteArray *)); + + qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans_cb); + qemu_plugin_register_atexit_cb(id, atexit_cb, NULL); + + return 0; +} diff --git a/tests/tcg/plugins/meson.build b/tests/tcg/plugins/meson.build index 163042e601..909bf3005a 100644 --- a/tests/tcg/plugins/meson.build +++ b/tests/tcg/plugins/meson.build @@ -1,6 +1,6 @@ t =3D [] if get_option('plugins') - foreach i : ['bb', 'empty', 'inline', 'insn', 'mem', 'reset', 'syscall',= 'patch'] + foreach i : ['bb', 'empty', 'inline', 'insn', 'mem', 'reset', 'syscall',= 'hypercalls', 'patch'] if host_os =3D=3D 'windows' t +=3D shared_module(i, files(i + '.c') + '../../../contrib/plugins/= win32_linker.c', include_directories: '../../../include/qemu', diff --git a/tests/tcg/x86_64/Makefile.softmmu-target b/tests/tcg/x86_64/Ma= kefile.softmmu-target index 8d3a067c33..8cb2a19461 100644 --- a/tests/tcg/x86_64/Makefile.softmmu-target +++ b/tests/tcg/x86_64/Makefile.softmmu-target @@ -46,14 +46,18 @@ EXTRA_RUNS+=3D$(MULTIARCH_RUNS) =20 memory: CFLAGS+=3D-DCHECK_UNALIGNED=3D1 patch-target: CFLAGS+=3D-O0 +hypercalls-target: CFLAGS+=3D-O0 =20 # Running QEMU_OPTS+=3D-device isa-debugcon,chardev=3Doutput -device isa-debug-exit,= iobase=3D0xf4,iosize=3D0x4 -kernel =20 # Add patch-target to ADDITIONAL_PLUGINS_TESTS ADDITIONAL_PLUGINS_TESTS +=3D patch-target +ADDITIONAL_PLUGINS_TESTS +=3D hypercalls-target =20 run-plugin-patch-target-with-libpatch.so: \ PLUGIN_ARGS=3D$(COMMA)target=3Dffc0$(COMMA)patch=3D9090$(COMMA)use_hwaddr= =3Dtrue$(COMMA)debug_insns=3Dfalse run-plugin-patch-target-with-libpatch.so: \ - CHECK_PLUGIN_OUTPUT_COMMAND=3D$(X86_64_SYSTEM_SRC)/validate-patch.py $@.o= ut \ No newline at end of file + CHECK_PLUGIN_OUTPUT_COMMAND=3D$(X86_64_SYSTEM_SRC)/validate-patch.py $@.o= ut +run-plugin-hypercalls-target-with-libhypercalls.so: \ + CHECK_PLUGIN_OUTPUT_COMMAND=3D$(X86_64_SYSTEM_SRC)/validate-hypercalls.py= $@.out diff --git a/tests/tcg/x86_64/system/hypercalls-target.c b/tests/tcg/x86_64= /system/hypercalls-target.c new file mode 100644 index 0000000000..643d489e9c --- /dev/null +++ b/tests/tcg/x86_64/system/hypercalls-target.c @@ -0,0 +1,45 @@ +/* + * SPDX-License-Identifier: GPL-2.0-or-later + * + * Copyright (C) 2025, Rowan Hart + * + * License: GNU GPL, version 2 or later. + * See the COPYING file in the top-level directory. + * + * This test target invokes a hypercall to write the value 0x1337 to a + * variable. + * + */ +#include +#include +#include + +#define _hypercall(num, arg0, arg1, arg2, arg3) \ + unsigned int a __attribute__((unused)) =3D 0; \ + unsigned int b __attribute__((unused)) =3D 0; \ + unsigned int c __attribute__((unused)) =3D 0; \ + unsigned int d __attribute__((unused)) =3D 0; \ + __asm__ __volatile__("cpuid\n\t" \ + : "=3Da"(a), "=3Db"(b), "=3Dc"(c), "=3Dd"(d) = \ + : "a"(num), "D"(arg0), "S"(arg1), \ + "d"(arg2), "c"(arg3)); + +#define hypercall(num, arg0, arg1, arg2, arg3) \ + { \ + unsigned int __num =3D 0x4711 | (num << 16); \ + _hypercall(__num, arg0, arg1, arg2, arg3); \ + } + +int main(void) +{ + uint16_t value =3D 0; + + for (size_t i =3D 0; i < 1000000; i++) { + hypercall(1, &value, sizeof(value), 0, 0); + if (value =3D=3D 0x1337) { + ml_printf("Victory!\n"); + return 0; + } + } + return 0; +} diff --git a/tests/tcg/x86_64/system/validate-hypercalls.py b/tests/tcg/x86= _64/system/validate-hypercalls.py new file mode 100755 index 0000000000..6e7c980706 --- /dev/null +++ b/tests/tcg/x86_64/system/validate-hypercalls.py @@ -0,0 +1,40 @@ +#!/usr/bin/env python3 +# +# validate-patch.py: check the patch applies +# +# This program takes two inputs: +# - the plugin output +# - the binary output +# +# Copyright (C) 2024 +# +# SPDX-License-Identifier: GPL-2.0-or-later + +import sys +from argparse import ArgumentParser + +def main() -> None: + """ + Process the arguments, injest the program and plugin out and + verify they match up and report if they do not. + """ + parser =3D ArgumentParser(description=3D"Validate patch") + parser.add_argument('test_output', + help=3D"The output from the test itself") + parser.add_argument('plugin_output', + help=3D"The output from plugin") + args =3D parser.parse_args() + + with open(args.test_output, 'r') as f: + test_data =3D f.read() + with open(args.plugin_output, 'r') as f: + plugin_data =3D f.read() + + if "Victory" in test_data: + sys.exit(0) + else: + sys.exit(1) + +if __name__ =3D=3D "__main__": + main() + --=20 2.49.0 From nobody Fri Dec 19 13:06:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1747965930; cv=none; d=zohomail.com; s=zohoarc; b=NC71ZDBmGHVzu6EJJNrehgOWk6VDDvqRY2n70ZxbnztmU8LjIVz+xwoIlSMrcN7XSLsN6xbiM1wIDLHyHXumunssRCFT+lr/p2eMoIgIe+h/EtpnCgmS8WJumajqasK1GKJjtwJ8E8UwZ0CEkaM3e74WkuHD/RCEnMf14zBCDMs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747965930; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wVjrW993BqqXU9EpDADVH1dB+hpwPyajnX8KVD/tm+w=; b=MpsoAkd9VJ6Zl+jCk0uxHUhCacihrnbDhJbwaSF2H/hSrVyviyM73AwY3/Z3ZuWkO/ZRE3oVs45GIuBt4oc/rSw+kP88zmh7lPwSmFMqiCrm/IY87DCdVtVHYzOxNBPw2+SYMLqmYdHKe7DuA9Se/MGymr5UCiaMtELHJTW5rqc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1747965930178103.80152468721178; Thu, 22 May 2025 19:05:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uIHlY-0001IL-II; Thu, 22 May 2025 22:04:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uIHlR-0001Fb-Kf for qemu-devel@nongnu.org; Thu, 22 May 2025 22:04:02 -0400 Received: from mail-pf1-x433.google.com ([2607:f8b0:4864:20::433]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1uIHlK-0007kY-8m for qemu-devel@nongnu.org; Thu, 22 May 2025 22:04:01 -0400 Received: by mail-pf1-x433.google.com with SMTP id d2e1a72fcca58-742c5eb7d1cso7276735b3a.3 for ; Thu, 22 May 2025 19:03:53 -0700 (PDT) Received: from shemhazi.lan ([50.46.174.34]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-742a98a242asm11820818b3a.164.2025.05.22.19.03.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 May 2025 19:03:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747965832; x=1748570632; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=wVjrW993BqqXU9EpDADVH1dB+hpwPyajnX8KVD/tm+w=; b=KPtJTBCjpu4yKyYaF50u7cuy0NGXkpcD4uC9z0/x/qu9S0L5XAdbPmZ4u+/FhvHp/b NHigaHMweOX1lxjArpikI/Ak/M8fUXWWugHysoPMdMgaocXkQVFwA8LnBw1tjHnPwOVS NqU45LrkHtAYUbwxtp5cv/CMa6xtnHGRFLkNOjGbQNg56Q4gJP9kga2abT8TdjnN8BoB FwSyEDeSoqWveggXvKXmxrJnK8YhPsC5MH1K/Kr2z2ARdTTlsvYgZntGomBnX5ahbSS3 7arl8bZlctdG6Q1ZKcWPs6awzyfloBAW6GV1vskcPjU6aypS65Ja6KFVIRByexbKZg/Q C1jg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747965832; x=1748570632; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wVjrW993BqqXU9EpDADVH1dB+hpwPyajnX8KVD/tm+w=; b=v8XmbquWQ/GRs3DmT7qQAGyvhOxDsOkyyyOCxHHyPIHtL6ysRwsHgZwtp37wejWjaj L4speum6Hd9qDedR7OHVD/dXsJnW4qdZXn2HjEBHaIf1oc0muYJE1I9Ql5HAVY5lsBjK CSitoroXxT3PSWPbZoDdEvolkko1Rc+heWxxts0lAgZ9BqH9k8HYZnew5oqJPuGJcqR8 v3EVrGIGFp9b/oVXpd0kkojJwYxv92XsHp4O4WcbOuMIzOf8VSBWtN4Sk//AzfE+QCv9 wDgbIjjP781TEM4yfCWQKbVAYZfaXxfqHuouFmchk4MZS8f8OdliQu4B1svVsQuzditd /VVg== X-Gm-Message-State: AOJu0YySRKQUHFTCw8/M7cUgygfr4xL9uq4uPkKuJ8T/406P/qV1mpON wiknNaGQR7myq3CxFWd1Fafa9UdFoBT0jHsuG9vcU1r7Rgr+wns2NXDw665SKVEXs3o= X-Gm-Gg: ASbGnctfHQBS4NKaWxJbnZowy46tFGahDdxgTaSpxtriayryf0KLQKOuoxN31TAgglW bPASpIZaG/PwGXfGhjjkyxE9pRB1WEpc5CGgh45m+2E+tbSnviTWuO4fEOb7FnNtwpvgEYAwZlB UL8g7+78lJ5blfr6WzGmm0gT/Cr3YTcRW21a2XcvE91LV759VPcBbELIAaby4hjJQM8wTkIq9pV HEhFOutjUbUiWjmVxFK54VPecVNykXwtywk1y0/cLMmU0QXACaDFdRxViBYJoDvEeXSRE2ySEuO /PkYNOhWDqWgcn7cJXOCG7rUOFgND0P6MDUYZGqFZCTJyIgf36Q= X-Google-Smtp-Source: AGHT+IGz2k4fDV9rjGYiKdTpJPGXIe/yOlC77/dhqjjBjm7sOduhKPxFLeaUDfyRXF0isS7EIj2rgg== X-Received: by 2002:a05:6a20:3d12:b0:1f5:59e5:8ada with SMTP id adf61e73a8af0-2162187a945mr37029337637.4.1747965832319; Thu, 22 May 2025 19:03:52 -0700 (PDT) From: Rowan Hart To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , Paolo Bonzini , Mahmoud Mandour , Alexandre Iooss , Eduardo Habkost , Rowan Hart Subject: [PATCH v4 8/9] plugins: Remove use of qemu_plugin_read_register where it is not permitted Date: Thu, 22 May 2025 19:03:42 -0700 Message-ID: <20250523020344.1341179-9-rowanbhart@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250523020344.1341179-1-rowanbhart@gmail.com> References: <20250523020344.1341179-1-rowanbhart@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::433; envelope-from=rowanbhart@gmail.com; helo=mail-pf1-x433.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1747965931161116600 Content-Type: text/plain; charset="utf-8" This patch is required to make the insn plugin work after adding enforcement of QEMU_PLUGIN_CB_ flags in calls to read or write registers. Previously, these flags were not enforced and the API could be called from anywhere, but this was not intended as described by the documentation. Now, the flags are enforced and qemu_plugin_read_register can no longer be called from a vcpu_init callback because it does not request the QEMU_PLUGIN_CB_ flag (nor does it have a mechanism to do so). Signed-off-by: Rowan Hart --- tests/tcg/plugins/insn.c | 22 +--------------------- 1 file changed, 1 insertion(+), 21 deletions(-) diff --git a/tests/tcg/plugins/insn.c b/tests/tcg/plugins/insn.c index 0c723cb9ed..265d3ebe9e 100644 --- a/tests/tcg/plugins/insn.c +++ b/tests/tcg/plugins/insn.c @@ -81,25 +81,6 @@ static Instruction * get_insn_record(const char *disas, = uint64_t vaddr, Match *m return record; } =20 -/* - * Initialise a new vcpu with reading the register list - */ -static void vcpu_init(qemu_plugin_id_t id, unsigned int vcpu_index) -{ - g_autoptr(GArray) reg_list =3D qemu_plugin_get_registers(); - g_autoptr(GByteArray) reg_value =3D g_byte_array_new(); - - if (reg_list) { - for (int i =3D 0; i < reg_list->len; i++) { - qemu_plugin_reg_descriptor *rd =3D &g_array_index( - reg_list, qemu_plugin_reg_descriptor, i); - int count =3D qemu_plugin_read_register(rd->handle, reg_value); - g_assert(count > 0); - } - } -} - - static void vcpu_insn_exec_before(unsigned int cpu_index, void *udata) { qemu_plugin_u64_add(insn_count, cpu_index, 1); @@ -295,8 +276,7 @@ QEMU_PLUGIN_EXPORT int qemu_plugin_install(qemu_plugin_= id_t id, insn_count =3D qemu_plugin_scoreboard_u64( qemu_plugin_scoreboard_new(sizeof(uint64_t))); =20 - /* Register init, translation block and exit callbacks */ - qemu_plugin_register_vcpu_init_cb(id, vcpu_init); + /* Register translation block and exit callbacks */ qemu_plugin_register_vcpu_tb_trans_cb(id, vcpu_tb_trans); qemu_plugin_register_atexit_cb(id, plugin_exit, NULL); return 0; --=20 2.49.0 From nobody Fri Dec 19 13:06:36 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1747965901; cv=none; d=zohomail.com; s=zohoarc; b=XM5OT33Sobyoqw1JFKQDxAbgHEhimZ1JhS5OSNoCpqobJq4zUNp+eIhPT4vOnHlMeqHNr6Yo2t/+F/Z3z2ckwk09iG3UhZLiS2+H/8FrkM98IflTxX+zkgsmLnGubDQPsX8caa2OzS5jmrG2uD8dxjcyRfxLUGqoH+EF9TSam6o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1747965901; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=Io8QAlH/AZbTYfjODl1SD6d4ZkI/a0qoPWASwOSekic=; b=S8KBfCIecmwpetFQY4gxdErBkesPfRGKLxmpqwHC5U1cSOJHx4g+sl2p8ATNIC3YTxnbm19XjOlhY3zrpsvO4hdunM0nCwqqUwuy8+lNILTnrzICP6OCrXLCqEfEUo8K2iyv/yAhVO+3UogAqV13xudYkKk0fc0o5cfiit7+odw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 174796590140077.30661961455371; Thu, 22 May 2025 19:05:01 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1uIHlY-0001I7-C1; Thu, 22 May 2025 22:04:08 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1uIHlR-0001Fc-OY for qemu-devel@nongnu.org; Thu, 22 May 2025 22:04:02 -0400 Received: from mail-pf1-x433.google.com ([2607:f8b0:4864:20::433]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1uIHlK-0007ki-V8 for qemu-devel@nongnu.org; Thu, 22 May 2025 22:04:01 -0400 Received: by mail-pf1-x433.google.com with SMTP id d2e1a72fcca58-742c5f3456fso4363031b3a.0 for ; Thu, 22 May 2025 19:03:54 -0700 (PDT) Received: from shemhazi.lan ([50.46.174.34]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-742a98a242asm11820818b3a.164.2025.05.22.19.03.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 22 May 2025 19:03:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1747965833; x=1748570633; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Io8QAlH/AZbTYfjODl1SD6d4ZkI/a0qoPWASwOSekic=; b=VkgJWWSrJOxj8cqyEbqWQJ8t1muJ2xduSTJZSegqLvZEki8sLx1FJICKpk5hnJLmUE NxCJwDoclwNCK6/8Y9a/sBnDjoZy1XOnpzU8IZPDa5nawhiuIKt9KID9hmY8BTWVm04c wYC4qTPuEkI/FWZ1cyrVfEiLTsHf8trDqKICsKH40C3GdIlrXwuHpgw7uwiCkU/5kUjC I3ZQb9lwzMF8IOiBZE2cijypJDZKjS3/uTenk8lqmn4PVZ1BEHDrhs0jEKgkN5tyjo0u Vj468QzqO8BNntN5dV6mu9GnWqr6e0HUsVHgCePyE5dErwJsjkgvNF2rlwrxZKeoU3EX 0ijw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1747965833; x=1748570633; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Io8QAlH/AZbTYfjODl1SD6d4ZkI/a0qoPWASwOSekic=; b=KbnmAigxWl7Fly2XvaYw9e/kw0sn/Eb2ZYOKWqBQfWfUWiRuxyYCviLObeBIj9uTTp kGCQyH+PbwO6W+vuuS9QEy703/FbFTpquKnOEAfHDAYdUn164RmyZ0Aav4oKUP8hEEsw x6VUi4eAx/tBDttwUfoyyIC5JCsr3WJY0UdDaPYHzHMe1FK2kZeM7+nsP8fXhrNV0Uv8 /jrPlua92E/velI9gc/As7cyWg+s9MbOYXaOb6OhuYa21T5VIigP51Y3u/eeUT52E9Xp 21o5zQrGvdldVtPpNlsGUNleLGR5meym/0iknqYatVaUfpgwJREXdE0QDA+9O4hbu993 rJuQ== X-Gm-Message-State: AOJu0YwW+WpRUnA5luIqtbDQpG4uH5kUTP3UstMFFQ+3GobNJERGRmRf sXc04TcGQzDiMkbhqxoA0SbJZgMUPfztPF7apydyfvfyVXFJauHUUV9nYPzczMs8RrA= X-Gm-Gg: ASbGncv2YRdX/TJtHRBFKBqkCkKBL53yz36OcJQTafWDu257p9yZ59PAZPlJbBYn8fZ hgamhGpnxrJby+8HHEmUKWDJuDjX1sISMv3VEFWVS5h6b4XcBTqFk9Nv69OdcwnHwTtWv+38s8L 0Yfzx1d/eol2xV+WtXdGrpmp38SD6eN+WVCcDgqVgHN69hg7FM1F8CamtBx2CVLiZ+vQqc7DK4K HEXEu0n2saH1njGMMOgXd+uF5okatF9Y8y2ebnh2p1e5ztX2npSWbk769koWBtXCQ3NY+MZ27sl p01Px3UFaoFTvuT5xfDCxktcugL6frKOad0LY+es4pZfeaur+qBcAkfp4aZvqg== X-Google-Smtp-Source: AGHT+IFsujTE/WP91RBzfc4Ma15ALzQau+vs5gDpYvGLFDvfVcUDHt1l2MbdxhInoQW48PhI//cgVw== X-Received: by 2002:a05:6a00:98d:b0:736:34a2:8a23 with SMTP id d2e1a72fcca58-745ed8f5d5bmr1702673b3a.15.1747965833047; Thu, 22 May 2025 19:03:53 -0700 (PDT) From: Rowan Hart To: qemu-devel@nongnu.org Cc: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= , Pierrick Bouvier , =?UTF-8?q?Alex=20Benn=C3=A9e?= , Richard Henderson , Paolo Bonzini , Mahmoud Mandour , Alexandre Iooss , Eduardo Habkost , novafacing Subject: [PATCH v4 9/9] plugins: Update plugin version and add notes Date: Thu, 22 May 2025 19:03:43 -0700 Message-ID: <20250523020344.1341179-10-rowanbhart@gmail.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250523020344.1341179-1-rowanbhart@gmail.com> References: <20250523020344.1341179-1-rowanbhart@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=2607:f8b0:4864:20::433; envelope-from=rowanbhart@gmail.com; helo=mail-pf1-x433.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1747965903014116600 Content-Type: text/plain; charset="utf-8" From: novafacing This patch updates the plugin version to gate new APIs and adds notes describing what has been added. Signed-off-by: Rowan Hart Reviewed-by: Pierrick Bouvier --- include/qemu/qemu-plugin.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/qemu/qemu-plugin.h b/include/qemu/qemu-plugin.h index 2cb5de9f64..170a79e667 100644 --- a/include/qemu/qemu-plugin.h +++ b/include/qemu/qemu-plugin.h @@ -65,11 +65,18 @@ typedef uint64_t qemu_plugin_id_t; * * version 4: * - added qemu_plugin_read_memory_vaddr + * + * version 5: + * - added qemu_plugin_write_memory_vaddr + * - added qemu_plugin_read_memory_hwaddr + * - added qemu_plugin_write_memory_hwaddr + * - added qemu_plugin_write_register + * - added qemu_plugin_translate_vaddr */ =20 extern QEMU_PLUGIN_EXPORT int qemu_plugin_version; =20 -#define QEMU_PLUGIN_VERSION 4 +#define QEMU_PLUGIN_VERSION 5 =20 /** * struct qemu_info_t - system information for plugins --=20 2.49.0