From patchwork Sun Mar 9 10:30:55 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008288 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 66EE6C282D1 for ; Sun, 9 Mar 2025 10:32:50 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwY-0007zH-Cp; Sun, 09 Mar 2025 06:31:38 -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 1trDwU-0007yc-Nu for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:34 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwS-0003zI-3u for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:34 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516289; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SsvDN1gwhkxvwdyT20oUdLZoM+J5t+ejAH8C+7BX97A=; b=MRKZvolS5xtGezY+SyOfzQdopZ9JKcX8Zfmi3yfkhq01iEyRq+57ezNDBQyd4UN3V3W7iN BvYKNWXa0kS9vQLgTSDfAxrowOwFEPSm4/Yh/QCLvc9IgADkgtLTDE3rwkWb0O+79AcR3R z0/xJwBDFfjr0IVU10Gh/9AP3KPxwxY= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-627-DEL9vmNbNDOd7s4YgR2iZA-1; Sun, 09 Mar 2025 06:31:26 -0400 X-MC-Unique: DEL9vmNbNDOd7s4YgR2iZA-1 X-Mimecast-MFC-AGG-ID: DEL9vmNbNDOd7s4YgR2iZA_1741516285 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-3913f97d115so269458f8f.0 for ; Sun, 09 Mar 2025 03:31:25 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516283; x=1742121083; 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=SsvDN1gwhkxvwdyT20oUdLZoM+J5t+ejAH8C+7BX97A=; b=tnKgIWsigv5oyXKA/uzZ6a6uy7pjR5sHytPJPwfzNes4LwIsWKsmmZh0C1NGHmRolh waB69AASMXReviNE8Y5iO223j5cNanzMKVNxYkF6kOEfv0j1huFOZxbPB47uCBpIne+B u67CtWYVr1p+XxangMxdU/L6eIYMqLatmsoieewTjNZxt87nPnsfQ2tpocXCQ6GfspX7 8jUeGbOvjFjJT5ZWmUiqilRrcgjR3mscx9mO9OnVR+AnMs/xOSZUnxfxExT9hehTVlEt eCuevg5rwA3MH5peJVHUtUeaxCZXAtRim7fBGuROmStNlSmKbzNof5jzSEqHjrcLgeQ2 Jjxg== X-Gm-Message-State: AOJu0YycKVTZ7pIR5TzTFJu5IW3It0TvqPYsPGjOvC78FABlk1LZtnjR myAkDNk9txsYB3CilC0LpLnkmJU96HLrZ5VYK66YTONqPhmD8h/Jged8Xp8fTSioCy6kaVbXEOw Aa7g2eHu21XKxZrW7rK4MbivuvSKDuzB8egyOLbW5M4mNK9EsPxUThFHHqgn/1aqmKrBMgnidSi y5EHdr+mTeqfSX7tDnxKdM3sU700lFtcY1vJSknRE= X-Gm-Gg: ASbGncuFkHFskhGWxa5aXZG1CDwqjSEWbwtUoApBmb3aNSE7ez0PQUcsJ6J6TSg/oVJ xuE2LAmwVgVt3E/6x6A8lWvaDKo8+Rid/l6WnMXeqtNYVQzrDF0DDDKixF60hIJ+Ro6l5G6PXCd HYih1XMULq6UdAAzBmUPFqumbe5jv0QT1Q+Jd408BEA092I3DYgYLpew9manQOP0bTDapMlNW6K Tl8kD4xq/flJ+Irqv140fMzzSE/XmbHgkpsl76TCPRyCdxMIFwtTGBPjEJE0QOeBW2mg3EPpt8e 5LUP/zrH60JgKZ76N5NeMw== X-Received: by 2002:a05:6000:1567:b0:391:1199:22b5 with SMTP id ffacd0b85a97d-3913aeeee27mr3093572f8f.10.1741516283731; Sun, 09 Mar 2025 03:31:23 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHnPLB17+OJadRP/lO3w7H8kpMKz4GrPxlGhHMWUEvxCua+y5byhEStnnZwTUHg9p2YpnsaWQ== X-Received: by 2002:a05:6000:1567:b0:391:1199:22b5 with SMTP id ffacd0b85a97d-3913aeeee27mr3093558f8f.10.1741516283316; Sun, 09 Mar 2025 03:31:23 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43cf86b1d80sm164685e9.9.2025.03.09.03.31.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:22 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: =?utf-8?q?Daniel_P=2E_Berrang=C3=A9?= Subject: [PULL 01/25] chardev: express dependency on io/ Date: Sun, 9 Mar 2025 11:30:55 +0100 Message-ID: <20250309103120.1116448-2-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org chardev is using qio functions, so express that in the Meson internal dependency. (I found this when adding character devices bindings for Rust; they initially needed the io dependency added by hand). Reviewed-by: Daniel P. Berrangé Signed-off-by: Paolo Bonzini --- meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/meson.build b/meson.build index 8b9fda4d95e..67ec2b78319 100644 --- a/meson.build +++ b/meson.build @@ -4015,7 +4015,7 @@ libchardev = static_library('chardev', chardev_ss.sources() + genh, build_by_default: false) chardev = declare_dependency(objects: libchardev.extract_all_objects(recursive: false), - dependencies: chardev_ss.dependencies()) + dependencies: [chardev_ss.dependencies(), io]) hwcore_ss = hwcore_ss.apply({}) libhwcore = static_library('hwcore', sources: hwcore_ss.sources() + genh, From patchwork Sun Mar 9 10:30:56 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008285 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 86CF5C282D1 for ; Sun, 9 Mar 2025 10:32:35 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwZ-0007zw-72; Sun, 09 Mar 2025 06:31:39 -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 1trDwU-0007yR-Ca for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:34 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwQ-0003zK-Tu for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:33 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516290; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=sgIRhA8V2yoGG7hQoR/1cCd/zfNZuMqAha1UxtZ8iWY=; b=eZFInYglTldYCPlwjQu1YQRQufeyyVVESJ5j/Wf9qapjhc8eEpKviXNj/f8Agv0i2Hupyf XAi4jfQVgT9c9kyu59hQWMqhsSjXMQrErBh6nH0MH4+l5AYNoLqF1TzynFu2hxFSX/SFdk 1UDWXRCwL/NkgdyFD2dk11lrJ3iUnPQ= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-224-hqNRVrjQPgW1w-KaP1XSuw-1; Sun, 09 Mar 2025 06:31:28 -0400 X-MC-Unique: hqNRVrjQPgW1w-KaP1XSuw-1 X-Mimecast-MFC-AGG-ID: hqNRVrjQPgW1w-KaP1XSuw_1741516287 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43947a0919aso27254715e9.0 for ; Sun, 09 Mar 2025 03:31:27 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516286; x=1742121086; 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=sgIRhA8V2yoGG7hQoR/1cCd/zfNZuMqAha1UxtZ8iWY=; b=s60xVvhMzvFhocwHY1g8aX8PUOPVk/slh+BoZ+Q969H4uiAQuuYpSfTFpEnIAN6/B2 ZAuaPew9xEIyz4zWb+8u80C5szsV/4/OuF4ba7KRubtWbmVjdNVErkEXexvVJxoRBRxe kf24h/vtxsdaf7urNB0AGc95RlpKGMpZ2l5b9Iorqr6a5EMs7zp3+egGcHPlj0Dz85sT Jblu3m52h8z5lGkAE/XkZoDy/mDwvl0aBATbYLA1E4oCZoo6azHTm5pL6NvikiaKu9TN g4NG+mGzcrItVA8JGy3CDcJYQG/5lPripjUV0MMPFTppm1N9EIWV1Td7PQi/t+c/Y/IY Y2pg== X-Gm-Message-State: AOJu0YyiqlOLgFm5TK/CrXELWMlJcYTy6cvzHg7otw9riim8+VXgVI5Q 6qYjnn7t7ckwf3jn5vZjG/b7PY6/pxnxDcJXbmsyY/UHt58QJLJGmHR2KwpwxU//F9wkjF83pdl jmzUNQ7mmh03AmaN0Dspux+A0IlL+rjGzc43A3LGtDyYZKZDi+wC/83VI1U0qt7ZMXGDEGvF4Jg svM2o9jZ4a9NcqTosr5M5fkxrX59B2pGK/5R3n1Po= X-Gm-Gg: ASbGncs+MZPWrFq9ggpg3SqoK5w2+eE1SWkpTNmykyHHeTohjQQzoBBAzNq2pNLYlbG C63lzXA5wlOv0+/3Y+NpROKSWawgEXgedUN8wQs9lvqV50qN2AdrCbnQUIv1gzACX5SoOlFfs0U /a8BzlrpudV7LS2eKy7OQgZFvDquxB4KJIiyiSVvkhOJY4w5+FQgYWFB+XKnVGhTgaIQj6XDi8n RWjEZLYIH8aJL5mo4CLbdGTSS73cZ9lClDiJbz6i4oLR0ymB/WLCxoXwqm8OynA3+sS6hqoESPX aIdmlj0o1BBFNnksWJlpVQ== X-Received: by 2002:a05:6000:1a88:b0:385:d7f9:f157 with SMTP id ffacd0b85a97d-39132da227bmr6500345f8f.36.1741516286426; Sun, 09 Mar 2025 03:31:26 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGaDlPjXUfgjM8InPOnJ0iOMoCeRWqonODvrAmP8IvItYQAdPMu3UHu2/qS3UzGctv9e2cfkg== X-Received: by 2002:a05:6000:1a88:b0:385:d7f9:f157 with SMTP id ffacd0b85a97d-39132da227bmr6500337f8f.36.1741516286047; Sun, 09 Mar 2025 03:31:26 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912c1030cfsm11732833f8f.90.2025.03.09.03.31.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:24 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Nabih Estefan , Patrick Venture Subject: [PULL 02/25] scripts: dump stdin on meson-buildoptions error Date: Sun, 9 Mar 2025 11:30:56 +0100 Message-ID: <20250309103120.1116448-3-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Nabih Estefan Dump sys.stdin when it errors on meson-buildoptions.py, letting us debug the build errors instead of just saying "Couldn't parse" Signed-off-by: Nabih Estefan Signed-off-by: Patrick Venture Link: https://lore.kernel.org/r/20250227180454.2006757-1-venture@google.com Signed-off-by: Paolo Bonzini --- scripts/meson-buildoptions.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/scripts/meson-buildoptions.py b/scripts/meson-buildoptions.py index 4814a8ff61f..a3e22471b2f 100644 --- a/scripts/meson-buildoptions.py +++ b/scripts/meson-buildoptions.py @@ -241,8 +241,14 @@ def print_parse(options): print(" esac") print("}") - -options = load_options(json.load(sys.stdin)) +json_data = sys.stdin.read() +try: + options = load_options(json.loads(json_data)) +except: + print("Failure in scripts/meson-buildoptions.py parsing stdin as json", + file=sys.stderr) + print(json_data, file=sys.stderr) + sys.exit(1) print("# This file is generated by meson-buildoptions.py, do not edit!") print_help(options) print_parse(options) From patchwork Sun Mar 9 10:30:57 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008284 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 61854C28B28 for ; Sun, 9 Mar 2025 10:32:32 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwc-00080t-6h; Sun, 09 Mar 2025 06:31:42 -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 1trDwZ-000804-LC for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:39 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwX-000405-Ar for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:39 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516295; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=viSHum1crcV4RV7TPCLWJy02Jkp+ZoiOfr0o/fqrkDo=; b=L4df99hwdUVYbhQ8nBn9f/82TI4j/mdiimLF8TR/gJZ5YLMHHX73BJkkYBF9V2QPVdzVtj JnDUzeBA69JkM1uKgkyhzc5RAG6rG7nUPsoqzYob4SMHaCPAENY5QGjQWwvJsQ8MqzoVpq n2nNz+3Xaz8GqliMAUkSgwQ3ayrhUuc= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-528-giSkTPpxOI-cEpRIFoM_6A-1; Sun, 09 Mar 2025 06:31:32 -0400 X-MC-Unique: giSkTPpxOI-cEpRIFoM_6A-1 X-Mimecast-MFC-AGG-ID: giSkTPpxOI-cEpRIFoM_6A_1741516291 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43cf446681cso986875e9.1 for ; Sun, 09 Mar 2025 03:31:32 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516290; x=1742121090; 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=viSHum1crcV4RV7TPCLWJy02Jkp+ZoiOfr0o/fqrkDo=; b=s8xBH6sfquthHFpx0lAdjawpQtQxaJn7QhDkAhm/bgxoIeu288KJQ/TBiwGOB67YzM p7JAmxuha00Pyg8t6Z6XihF+mqToXNwkwJQQBha+VSmDg8gKHl7DOUVNYz7MWNIJ1Lqz dEn2wDsbJG243iitAJfkbV6/Wxw4UqyT6s0WEBNtlx+TXeDJXWuVxsrZaWwsdwsMM7YI juawewiFPfjyjqBmLPc81ZkIm+lbIvAyylLB1LSLW2S6b3nNCJxdcN9TAehynU1EhLBy v8FuJvjy7HzAuBfYZg188bBpnpzB882EquStRKHMR5A+Sq3sqOambVTHKYn0wXu/IyeZ AyJQ== X-Gm-Message-State: AOJu0YwTyW8fNupmvCJ5Y7ZnDQyv8hgdGLt4A3wOE4gF/TMfuDMDzU2y IRhX23E835so9i8vFQ9lkXGGPZzpgGM5PZhprFsSieE/t7gQedPEBxXnD9PZYiSXVJW1yJkdrln 8W7GWyFxHdJwbmmhKRhlquVEpR1rscbBFNmA+ZVXKLMDwQA8KgHl+9c6lA5dLPPaeXSFAvFsNTg BTLF1c/P9ufL+/QdG1oZxJ+QJF89O8/UBw1Ztit20= X-Gm-Gg: ASbGncszTWqii2nAt31+EbwRO74dCnrUClkva/2jgYIngzuyrwls+kIJcHrs61auR7z Rqa/grpQM4Xu6HbqfrCCnvcMPZPlPnU4QLm5k0jzeQezP9381veNhCN0Uhi41LoRd7jSDoWYKZV nkoCPySH7Juco9HDK2XqAvr1Hs4LlR1xLmdxX5zvUI9GgJ8VinmeEgoITrmrPf9nn3U79fSwcbv fpOFS0gs3cYXeTxMfNo3AP7YlrCrVYuXQiG/YQP0xGUZSA4am/zo9V75Ljc7UQCoAD1CWOJ3BkQ PqBRLnqQ2dySpDEBxQ8+LQ== X-Received: by 2002:a05:600c:1d26:b0:43c:f597:d589 with SMTP id 5b1f17b1804b1-43cf597d965mr4128905e9.27.1741516290123; Sun, 09 Mar 2025 03:31:30 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFgNCnhjZXjoG+gFIDi1UiyEC4XK4hZTnxSHDJo41/fQCplS2oqZybXlXjVUtPBlD78117hBQ== X-Received: by 2002:a05:600c:1d26:b0:43c:f597:d589 with SMTP id 5b1f17b1804b1-43cf597d965mr4128685e9.27.1741516289519; Sun, 09 Mar 2025 03:31:29 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912bfba8a9sm11509952f8f.9.2025.03.09.03.31.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:27 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 03/25] rust: cell: add wrapper for FFI types Date: Sun, 9 Mar 2025 11:30:57 +0100 Message-ID: <20250309103120.1116448-4-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Inspired by the same-named type in Linux. This type provides the compiler with a correct view of what goes on with FFI types. In addition, it separates the glue code from the bindgen-generated code, allowing traits such as Send, Sync or Zeroable to be specified independently for C and Rust structs. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- docs/devel/rust.rst | 34 +++++-- rust/qemu-api/src/cell.rs | 204 ++++++++++++++++++++++++++++++++++++-- 2 files changed, 223 insertions(+), 15 deletions(-) diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst index 5d8aa3a45bc..784c3e40bdc 100644 --- a/docs/devel/rust.rst +++ b/docs/devel/rust.rst @@ -296,15 +296,33 @@ of ``&mut self``; access to internal fields must use *interior mutability* to go from a shared reference to a ``&mut``. Whenever C code provides you with an opaque ``void *``, avoid converting it -to a Rust mutable reference, and use a shared reference instead. Rust code -will then have to use QEMU's ``BqlRefCell`` and ``BqlCell`` type, which -enforce that locking rules for the "Big QEMU Lock" are respected. These cell -types are also known to the ``vmstate`` crate, which is able to "look inside" -them when building an in-memory representation of a ``struct``'s layout. -Note that the same is not true of a ``RefCell`` or ``Mutex``. +to a Rust mutable reference, and use a shared reference instead. The +``qemu_api::cell`` module provides wrappers that can be used to tell the +Rust compiler about interior mutability, and optionally to enforce locking +rules for the "Big QEMU Lock". In the future, similar cell types might +also be provided for ``AioContext``-based locking as well. -In the future, similar cell types might also be provided for ``AioContext``-based -locking as well. +In particular, device code will usually rely on the ``BqlRefCell`` and +``BqlCell`` type to ensure that data is accessed correctly under the +"Big QEMU Lock". These cell types are also known to the ``vmstate`` +crate, which is able to "look inside" them when building an in-memory +representation of a ``struct``'s layout. Note that the same is not true +of a ``RefCell`` or ``Mutex``. + +Bindings code instead will usually use the ``Opaque`` type, which hides +the contents of the underlying struct and can be easily converted to +a raw pointer, for use in calls to C functions. It can be used for +example as follows:: + + #[repr(transparent)] + #[derive(Debug)] + pub struct Object(Opaque); + +The bindings will then manually check for the big QEMU lock with +assertions, which allows the wrapper to be declared thread-safe:: + + unsafe impl Send for Object {} + unsafe impl Sync for Object {} Writing bindings to C code '''''''''''''''''''''''''' diff --git a/rust/qemu-api/src/cell.rs b/rust/qemu-api/src/cell.rs index eae4e2ce786..2889abb868e 100644 --- a/rust/qemu-api/src/cell.rs +++ b/rust/qemu-api/src/cell.rs @@ -27,7 +27,7 @@ // IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//! BQL-protected mutable containers. +//! QEMU-specific mutable containers //! //! Rust memory safety is based on this rule: Given an object `T`, it is only //! possible to have one of the following: @@ -43,8 +43,10 @@ //! usually have their pointer shared with the "outside world very early in //! their lifetime", for example when they create their //! [`MemoryRegion`s](crate::bindings::MemoryRegion). Therefore, individual -//! parts of a device must be made mutable in a controlled manner through the -//! use of cell types. +//! parts of a device must be made mutable in a controlled manner; this module +//! provides the tools to do so. +//! +//! ## Cell types //! //! [`BqlCell`] and [`BqlRefCell`] allow doing this via the Big QEMU Lock. //! While they are essentially the same single-threaded primitives that are @@ -71,7 +73,7 @@ //! QEMU device implementations is usually incorrect and can lead to //! thread-safety issues. //! -//! ## `BqlCell` +//! ### `BqlCell` //! //! [`BqlCell`] implements interior mutability by moving values in and out of //! the cell. That is, an `&mut T` to the inner value can never be obtained as @@ -91,7 +93,7 @@ //! - [`set`](BqlCell::set): this method replaces the interior value, //! dropping the replaced value. //! -//! ## `BqlRefCell` +//! ### `BqlRefCell` //! //! [`BqlRefCell`] uses Rust's lifetimes to implement "dynamic borrowing", a //! process whereby one can claim temporary, exclusive, mutable access to the @@ -111,13 +113,82 @@ //! Multiple immutable borrows are allowed via [`borrow`](BqlRefCell::borrow), //! or a single mutable borrow via [`borrow_mut`](BqlRefCell::borrow_mut). The //! thread will panic if these rules are violated or if the BQL is not held. +//! +//! ## Opaque wrappers +//! +//! The cell types from the previous section are useful at the boundaries +//! of code that requires interior mutability. When writing glue code that +//! interacts directly with C structs, however, it is useful to operate +//! at a lower level. +//! +//! C functions often violate Rust's fundamental assumptions about memory +//! safety by modifying memory even if it is shared. Furthermore, C structs +//! often start their life uninitialized and may be populated lazily. +//! +//! For this reason, this module provides the [`Opaque`] type to opt out +//! of Rust's usual guarantees about the wrapped type. Access to the wrapped +//! value is always through raw pointers, obtained via methods like +//! [`as_mut_ptr()`](Opaque::as_mut_ptr) and [`as_ptr()`](Opaque::as_ptr). These +//! pointers can then be passed to C functions or dereferenced; both actions +//! require `unsafe` blocks, making it clear where safety guarantees must be +//! manually verified. For example +//! +//! ```ignore +//! unsafe { +//! let state = Opaque::::uninit(); +//! qemu_struct_init(state.as_mut_ptr()); +//! } +//! ``` +//! +//! [`Opaque`] will usually be wrapped one level further, so that +//! bridge methods can be added to the wrapper: +//! +//! ```ignore +//! pub struct MyStruct(Opaque); +//! +//! impl MyStruct { +//! fn new() -> Pin> { +//! let result = Box::pin(unsafe { Opaque::uninit() }); +//! unsafe { qemu_struct_init(result.as_mut_ptr()) }; +//! result +//! } +//! } +//! ``` +//! +//! This pattern of wrapping bindgen-generated types in [`Opaque`] provides +//! several advantages: +//! +//! * The choice of traits to be implemented is not limited by the +//! bindgen-generated code. For example, [`Drop`] can be added without +//! disabling [`Copy`] on the underlying bindgen type +//! +//! * [`Send`] and [`Sync`] implementations can be controlled by the wrapper +//! type rather than being automatically derived from the C struct's layout +//! +//! * Methods can be implemented in a separate crate from the bindgen-generated +//! bindings +//! +//! * [`Debug`](std::fmt::Debug) and [`Display`](std::fmt::Display) +//! implementations can be customized to be more readable than the raw C +//! struct representation +//! +//! The [`Opaque`] type does not include BQL validation; it is possible to +//! assert in the code that the right lock is taken, to use it together +//! with a custom lock guard type, or to let C code take the lock, as +//! appropriate. It is also possible to use it with non-thread-safe +//! types, since by default (unlike [`BqlCell`] and [`BqlRefCell`] +//! it is neither `Sync` nor `Send`. +//! +//! While [`Opaque`] is necessary for C interop, it should be used sparingly +//! and only at FFI boundaries. For QEMU-specific types that need interior +//! mutability, prefer [`BqlCell`] or [`BqlRefCell`]. use std::{ cell::{Cell, UnsafeCell}, cmp::Ordering, fmt, - marker::PhantomData, - mem, + marker::{PhantomData, PhantomPinned}, + mem::{self, MaybeUninit}, ops::{Deref, DerefMut}, ptr::NonNull, }; @@ -840,3 +911,122 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { (**self).fmt(f) } } + +/// Stores an opaque value that is shared with C code. +/// +/// Often, C structs can changed when calling a C function even if they are +/// behind a shared Rust reference, or they can be initialized lazily and have +/// invalid bit patterns (e.g. `3` for a [`bool`]). This goes against Rust's +/// strict aliasing rules, which normally prevent mutation through shared +/// references. +/// +/// Wrapping the struct with `Opaque` ensures that the Rust compiler does not +/// assume the usual constraints that Rust structs require, and allows using +/// shared references on the Rust side. +/// +/// `Opaque` is `#[repr(transparent)]`, so that it matches the memory layout +/// of `T`. +#[repr(transparent)] +pub struct Opaque { + value: UnsafeCell>, + // PhantomPinned also allows multiple references to the `Opaque`, i.e. + // one `&mut Opaque` can coexist with a `&mut T` or any number of `&T`; + // see https://docs.rs/pinned-aliasable/latest/pinned_aliasable/. + _pin: PhantomPinned, +} + +impl Opaque { + /// Creates a new shared reference from a C pointer + /// + /// # Safety + /// + /// The pointer must be valid, though it need not point to a valid value. + pub unsafe fn from_raw<'a>(ptr: *mut T) -> &'a Self { + let ptr = NonNull::new(ptr).unwrap().cast::(); + // SAFETY: Self is a transparent wrapper over T + unsafe { ptr.as_ref() } + } + + /// Creates a new opaque object with uninitialized contents. + /// + /// # Safety + /// + /// Ultimately the pointer to the returned value will be dereferenced + /// in another `unsafe` block, for example when passing it to a C function, + /// but the functions containing the dereference are usually safe. The + /// value returned from `uninit()` must be initialized and pinned before + /// calling them. + #[allow(clippy::missing_const_for_fn)] + pub unsafe fn uninit() -> Self { + Self { + value: UnsafeCell::new(MaybeUninit::uninit()), + _pin: PhantomPinned, + } + } + + /// Creates a new opaque object with zeroed contents. + /// + /// # Safety + /// + /// Ultimately the pointer to the returned value will be dereferenced + /// in another `unsafe` block, for example when passing it to a C function, + /// but the functions containing the dereference are usually safe. The + /// value returned from `uninit()` must be pinned (and possibly initialized) + /// before calling them. + #[allow(clippy::missing_const_for_fn)] + pub unsafe fn zeroed() -> Self { + Self { + value: UnsafeCell::new(MaybeUninit::zeroed()), + _pin: PhantomPinned, + } + } + + /// Returns a raw mutable pointer to the opaque data. + pub const fn as_mut_ptr(&self) -> *mut T { + UnsafeCell::get(&self.value).cast() + } + + /// Returns a raw pointer to the opaque data. + pub const fn as_ptr(&self) -> *const T { + self.as_mut_ptr() as *const _ + } + + /// Returns a raw pointer to the opaque data that can be passed to a + /// C function as `void *`. + pub const fn as_void_ptr(&self) -> *mut std::ffi::c_void { + UnsafeCell::get(&self.value).cast() + } + + /// Converts a raw pointer to the wrapped type. + pub const fn raw_get(slot: *mut Self) -> *mut T { + // Compare with Linux's raw_get method, which goes through an UnsafeCell + // because it takes a *const Self instead. + slot.cast() + } +} + +impl fmt::Debug for Opaque { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + let mut name: String = "Opaque<".to_string(); + name += std::any::type_name::(); + name += ">"; + f.debug_tuple(&name).field(&self.as_ptr()).finish() + } +} + +impl Opaque { + /// Creates a new opaque object with default contents. + /// + /// # Safety + /// + /// Ultimately the pointer to the returned value will be dereferenced + /// in another `unsafe` block, for example when passing it to a C function, + /// but the functions containing the dereference are usually safe. The + /// value returned from `uninit()` must be pinned before calling them. + pub unsafe fn new() -> Self { + Self { + value: UnsafeCell::new(MaybeUninit::new(T::default())), + _pin: PhantomPinned, + } + } +} From patchwork Sun Mar 9 10:30:58 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008282 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9E1AEC282D1 for ; Sun, 9 Mar 2025 10:32:21 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwZ-000801-Ol; Sun, 09 Mar 2025 06:31:39 -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 1trDwY-0007zX-KN for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:38 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwW-000407-OX for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:38 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516296; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=zc9FIm4JAe4PY9QTV9e+w4Xx2pwitv+RMwdbYEMBz+Q=; b=BEKOmTILacvPv6P3EvNjPVQMHCAicSrTA+l7MbrurA3GJAc9ROmzGCxTLw25+RX+s449op sWQ5F/XS2J6+BFrby/IrBG99Hmyt3nx1ffOM8ysL1udYuRNBfYvivyEaLctmjapx4iya+N glCzFg7fBFMyMY0oeIqj40KZxqCftd0= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-544-L3iNhFF8M6GnkN2pYuwSiw-1; Sun, 09 Mar 2025 06:31:34 -0400 X-MC-Unique: L3iNhFF8M6GnkN2pYuwSiw-1 X-Mimecast-MFC-AGG-ID: L3iNhFF8M6GnkN2pYuwSiw_1741516293 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-3911232fd8bso1941461f8f.3 for ; Sun, 09 Mar 2025 03:31:34 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516291; x=1742121091; 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=zc9FIm4JAe4PY9QTV9e+w4Xx2pwitv+RMwdbYEMBz+Q=; b=DKSSxGsGY7swwtM/ZK/6LhC85Soz1m/FixZoJlSmc7GeM8HcuIT0MY0xjO2xBHIEmR ZvELrlDqpB0U8LK5sF+i+Yvazm2a8YuI251GzWymEd13yR/m8UlJbZ6QuuV1Aw6AuAIm ffBaAabkKNzpic2AUHPa+VwzXd0mchYnOzSk/evj6TGGxVb3ICeUVhhJ97PuY97/oVqn MVpcCQL57G2o+8l4FEG4dJg+xBEca9PUZqx+Fsc7IsDBliBuCfn981MIM2YTfb2gjWfk vie1MdM8IkaAGwQ2vQ/LLtbx2DnCLcu8bkpslURcR0AiIxGsg4FVxtjnD07unZsMC1KH a1JA== X-Gm-Message-State: AOJu0YyGrL/l0LxZhUWB6olUiOFM4YZBkwqE4nLwxXWRmNnwezw6Ai8X gTUK8ZXc2WFBlNqKoRIDRQXgjppW5iZdmlCuWLmBz5O60vhex9ONOcnkvB994Cf/y7Ard2ZhNB1 llaNMWs+p6lHwhjs0FmxdMGDOkHuhIeS6p4dBjgDkxLCf8yCqcnpmNiwPIc5lLG6HK5fToUdnXj L7aaQkZlQLyrb4dEqXr+shnY7dqnzq0UnuM9iJ+9A= X-Gm-Gg: ASbGncsRdxq4jSOZeZ9pC/o+Ru6RjPjZBsfuGUVFGorq5/uMVqolDI4KMpNvk8NNZv8 /u/Ep1mRQn2lKCu7ymTKnfRPbRGGLnpmPW/60XdWI+FHNs68xMJvPqdG2LSfb4fDXgN7e7FMe3R HGL9+88kj3GlTaGbTbQhT8lT8U8wNOG/ReDHCbZLwqUhlA2kwOv3KuEW0/IMM1p9nzZSy66QlMO y0RIfB6WW31H3Fu6UqLXT90QdTn3JVIYvyz3rztsJx6mloo+0ew4pJJqjmpWO0XcTO/fP33M6RE BaryBURYvV8W6Lldp5+rjg== X-Received: by 2002:a05:6000:1844:b0:38f:4fa6:bb24 with SMTP id ffacd0b85a97d-39132dbb511mr7387771f8f.39.1741516291480; Sun, 09 Mar 2025 03:31:31 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHi3FSPUY5T8blrpgOA/ktkboI2JQ1UP6+t/U1Hataa2xqYXOylQGP1gmuBw86VfmOJN4yIyQ== X-Received: by 2002:a05:6000:1844:b0:38f:4fa6:bb24 with SMTP id ffacd0b85a97d-39132dbb511mr7387752f8f.39.1741516291009; Sun, 09 Mar 2025 03:31:31 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912bfdfdfdsm11812348f8f.34.2025.03.09.03.31.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:30 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 04/25] rust: qemu_api_macros: add Wrapper derive macro Date: Sun, 9 Mar 2025 11:30:58 +0100 Message-ID: <20250309103120.1116448-5-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Add a derive macro that makes it easy to peel off all the layers of specialness (UnsafeCell, MaybeUninit, etc.) and just get a pointer to the wrapped type; and likewise add them back starting from a *mut. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- docs/devel/rust.rst | 8 +-- rust/qemu-api-macros/src/lib.rs | 90 ++++++++++++++++++++++++++++++++- rust/qemu-api/meson.build | 7 +-- rust/qemu-api/src/cell.rs | 45 +++++++++++++++++ 4 files changed, 141 insertions(+), 9 deletions(-) diff --git a/docs/devel/rust.rst b/docs/devel/rust.rst index 784c3e40bdc..88bdec1eb28 100644 --- a/docs/devel/rust.rst +++ b/docs/devel/rust.rst @@ -315,11 +315,13 @@ a raw pointer, for use in calls to C functions. It can be used for example as follows:: #[repr(transparent)] - #[derive(Debug)] + #[derive(Debug, qemu_api_macros::Wrapper)] pub struct Object(Opaque); -The bindings will then manually check for the big QEMU lock with -assertions, which allows the wrapper to be declared thread-safe:: +where the special ``derive`` macro provides useful methods such as +``from_raw``, ``as_ptr`, ``as_mut_ptr`` and ``raw_get``. The bindings will +then manually check for the big QEMU lock with assertions, which allows +the wrapper to be declared thread-safe:: unsafe impl Send for Object {} unsafe impl Sync for Object {} diff --git a/rust/qemu-api-macros/src/lib.rs b/rust/qemu-api-macros/src/lib.rs index 7ec218202f4..eda0d46d122 100644 --- a/rust/qemu-api-macros/src/lib.rs +++ b/rust/qemu-api-macros/src/lib.rs @@ -6,7 +6,7 @@ use quote::quote; use syn::{ parse_macro_input, parse_quote, punctuated::Punctuated, spanned::Spanned, token::Comma, Data, - DeriveInput, Field, Fields, Ident, Meta, Path, Token, Type, Variant, Visibility, + DeriveInput, Field, Fields, FieldsUnnamed, Ident, Meta, Path, Token, Type, Variant, Visibility, }; mod utils; @@ -33,6 +33,35 @@ fn get_fields<'a>( } } +fn get_unnamed_field<'a>(input: &'a DeriveInput, msg: &str) -> Result<&'a Field, MacroError> { + if let Data::Struct(s) = &input.data { + let unnamed = match &s.fields { + Fields::Unnamed(FieldsUnnamed { + unnamed: ref fields, + .. + }) => fields, + _ => { + return Err(MacroError::Message( + format!("Tuple struct required for {}", msg), + s.fields.span(), + )) + } + }; + if unnamed.len() != 1 { + return Err(MacroError::Message( + format!("A single field is required for {}", msg), + s.fields.span(), + )); + } + Ok(&unnamed[0]) + } else { + Err(MacroError::Message( + format!("Struct required for {}", msg), + input.ident.span(), + )) + } +} + fn is_c_repr(input: &DeriveInput, msg: &str) -> Result<(), MacroError> { let expected = parse_quote! { #[repr(C)] }; @@ -46,6 +75,19 @@ fn is_c_repr(input: &DeriveInput, msg: &str) -> Result<(), MacroError> { } } +fn is_transparent_repr(input: &DeriveInput, msg: &str) -> Result<(), MacroError> { + let expected = parse_quote! { #[repr(transparent)] }; + + if input.attrs.iter().any(|attr| attr == &expected) { + Ok(()) + } else { + Err(MacroError::Message( + format!("#[repr(transparent)] required for {}", msg), + input.ident.span(), + )) + } +} + fn derive_object_or_error(input: DeriveInput) -> Result { is_c_repr(&input, "#[derive(Object)]")?; @@ -72,6 +114,52 @@ pub fn derive_object(input: TokenStream) -> TokenStream { TokenStream::from(expanded) } +fn derive_opaque_or_error(input: DeriveInput) -> Result { + is_transparent_repr(&input, "#[derive(Wrapper)]")?; + + let name = &input.ident; + let field = &get_unnamed_field(&input, "#[derive(Wrapper)]")?; + let typ = &field.ty; + + // TODO: how to add "::qemu_api"? For now, this is only used in the + // qemu_api crate so it's not a problem. + Ok(quote! { + unsafe impl crate::cell::Wrapper for #name { + type Wrapped = <#typ as crate::cell::Wrapper>::Wrapped; + } + impl #name { + pub unsafe fn from_raw<'a>(ptr: *mut ::Wrapped) -> &'a Self { + let ptr = ::std::ptr::NonNull::new(ptr).unwrap().cast::(); + unsafe { ptr.as_ref() } + } + + pub const fn as_mut_ptr(&self) -> *mut ::Wrapped { + self.0.as_mut_ptr() + } + + pub const fn as_ptr(&self) -> *const ::Wrapped { + self.0.as_ptr() + } + + pub const fn as_void_ptr(&self) -> *mut ::core::ffi::c_void { + self.0.as_void_ptr() + } + + pub const fn raw_get(slot: *mut Self) -> *mut ::Wrapped { + slot.cast() + } + } + }) +} + +#[proc_macro_derive(Wrapper)] +pub fn derive_opaque(input: TokenStream) -> TokenStream { + let input = parse_macro_input!(input as DeriveInput); + let expanded = derive_opaque_or_error(input).unwrap_or_else(Into::into); + + TokenStream::from(expanded) +} + #[rustfmt::skip::macros(quote)] fn derive_offsets_or_error(input: DeriveInput) -> Result { is_c_repr(&input, "#[derive(offsets)]")?; diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build index bcf1cf780f3..6e52c4bad74 100644 --- a/rust/qemu-api/meson.build +++ b/rust/qemu-api/meson.build @@ -42,16 +42,13 @@ _qemu_api_rs = static_library( override_options: ['rust_std=2021', 'build.rust_std=2021'], rust_abi: 'rust', rust_args: _qemu_api_cfg, - dependencies: libc_dep, + dependencies: [libc_dep, qemu_api_macros], ) rust.test('rust-qemu-api-tests', _qemu_api_rs, suite: ['unit', 'rust']) -qemu_api = declare_dependency( - link_with: _qemu_api_rs, - dependencies: qemu_api_macros, -) +qemu_api = declare_dependency(link_with: _qemu_api_rs) # Rust executables do not support objects, so add an intermediate step. rust_qemu_api_objs = static_library( diff --git a/rust/qemu-api/src/cell.rs b/rust/qemu-api/src/cell.rs index 2889abb868e..448638e8967 100644 --- a/rust/qemu-api/src/cell.rs +++ b/rust/qemu-api/src/cell.rs @@ -1030,3 +1030,48 @@ pub unsafe fn new() -> Self { } } } + +/// Annotates [`Self`] as a transparent wrapper for another type. +/// +/// Usually defined via the [`qemu_api_macros::Wrapper`] derive macro. +/// +/// # Examples +/// +/// ``` +/// # use std::mem::ManuallyDrop; +/// # use qemu_api::cell::Wrapper; +/// #[repr(transparent)] +/// pub struct Example { +/// inner: ManuallyDrop, +/// } +/// +/// unsafe impl Wrapper for Example { +/// type Wrapped = String; +/// } +/// ``` +/// +/// # Safety +/// +/// `Self` must be a `#[repr(transparent)]` wrapper for the `Wrapped` type, +/// whether directly or indirectly. +/// +/// # Methods +/// +/// By convention, types that implement Wrapper also implement the following +/// methods: +/// +/// ```ignore +/// pub const unsafe fn from_raw<'a>(value: *mut Self::Wrapped) -> &'a Self; +/// pub const unsafe fn as_mut_ptr(&self) -> *mut Self::Wrapped; +/// pub const unsafe fn as_ptr(&self) -> *const Self::Wrapped; +/// pub const unsafe fn raw_get(slot: *mut Self) -> *const Self::Wrapped; +/// ``` +/// +/// They are not defined here to allow them to be `const`. +pub unsafe trait Wrapper { + type Wrapped; +} + +unsafe impl Wrapper for Opaque { + type Wrapped = T; +} From patchwork Sun Mar 9 10:30:59 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008302 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1B274C282D1 for ; Sun, 9 Mar 2025 10:34:25 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwc-00081M-LW; Sun, 09 Mar 2025 06:31:42 -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 1trDwa-00080H-RG for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:41 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwZ-00040M-Dx for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516298; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=OAGa/1zAiQKppBasu/YtxlNDeSsZyMqPAmmwgiPHU8k=; b=H2xM+jc/t9jCkKmsw3A1dNrBzjMHfPXOL5mKDq08N2nueGSK4GlmK91EzwRSn93kufLTX6 xkB9btr+rbLpRzqtx/54CYBb3JVeudxLvCy7WV5u2TJMljveYSee+9soSyafXovy/iTzjT pB95uPBzYKiSq9CrafsTX2PEojYtt2E= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-554-_KOHpi6HPxygD5QJ6_A7TA-1; Sun, 09 Mar 2025 06:31:36 -0400 X-MC-Unique: _KOHpi6HPxygD5QJ6_A7TA-1 X-Mimecast-MFC-AGG-ID: _KOHpi6HPxygD5QJ6_A7TA_1741516295 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43cf446681cso986925e9.1 for ; Sun, 09 Mar 2025 03:31:36 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516295; x=1742121095; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=OAGa/1zAiQKppBasu/YtxlNDeSsZyMqPAmmwgiPHU8k=; b=pipD/3qzXI6Yv6hLz3ZFOCspeiDdQ257vCmCVKOhCDN5pWnwnekiDzjnDoIqP5p82X 7cf1JmnysyAzN4mUTu7AmUUGX3O2pB6uwtUehFlvehdy0M3nCHbUcMDeJwThNWg3+CLE OajIHWdMs+uAm1q8xx4/TMqpaIbBcvzxWZxJeA+tB2M12mTIZVR5ALTGtoDJUorsMo1y Pt+Hz08rNKaTWh5XBWqekdYmOQCM6OCFytFU15luGg4BLfOQwOcnXGJJZLwDoAX78tvS qHbMQNmPPAia1qBznuoNaGlZEDpdxy1+392Eg0v7ZnrBmet4jMVc1cjyFHsN45gmo7QJ Zm5g== X-Gm-Message-State: AOJu0Ywf1IiWMn6JZzCnSlitI8ewdLjkzANmbpZFt86lez6XIQW/pupZ QmhZlbOhmfJcbMQeSo65TBd9gxiRJgD58wMlU6XOq8F9CKF1N+hL78W203+dW+be0EZzhiiE2dW uDQoJGfgRtvOOlDhbwq3IrWeCZs1z3kHyIJh17ANI4jjFQaqItWuCw5nuRvX33/ye3LhHGUygqq 0KHc9qien/67sonlOHK6uktsYcqIKoVXgEG44HDI8= X-Gm-Gg: ASbGncvSHBcgV6pcF4aqx9bmyAPHLRR+5bx+lccpOS70H0dGbG46yhEAc6Lg6Ngs+EH 5kNOM7Qi71dPb17/7/6nU9ygFbR7YLN5cbfYNdRQdWIjxpk4fliSlSseohnHHxEa3ZLAoiYj851 Sh6SnTkRR5JCY2jHlLwBOT5G0fOB22mncYP6Sn1AbIYDGglRRYkPtfLsbMG6/uMpJJe3pUPlkzj cPenHACM22oN+ZDnMI6H8Rvqe9/QS7/PPk2HNTzkxqKHwkFZjg4Zle1P0+mgNWogVLDEADX0FWa b++n/3KZQguqZ37TmJBSkw== X-Received: by 2002:a05:600c:1d26:b0:43c:f597:d589 with SMTP id 5b1f17b1804b1-43cf597d965mr4130165e9.27.1741516294832; Sun, 09 Mar 2025 03:31:34 -0700 (PDT) X-Google-Smtp-Source: AGHT+IG7J2vK48uHu/SyE8clHo8n5m1IDtVJBUbnFxAXVlukOpXGOEF0/8uDv84yaUwoY0fbFjO06A== X-Received: by 2002:a05:600c:1d26:b0:43c:f597:d589 with SMTP id 5b1f17b1804b1-43cf597d965mr4130005e9.27.1741516294346; Sun, 09 Mar 2025 03:31:34 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43cec487fb2sm37825215e9.37.2025.03.09.03.31.31 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:31 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 05/25] rust: vmstate: add std::pin::Pin as transparent wrapper Date: Sun, 9 Mar 2025 11:30:59 +0100 Message-ID: <20250309103120.1116448-6-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 24a4dc81e7f..1e7ba531e2a 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -330,6 +330,7 @@ unsafe impl<$base> VMState for $type where $base: VMState $($where)* { impl_vmstate_transparent!(std::cell::Cell where T: VMState); impl_vmstate_transparent!(std::cell::UnsafeCell where T: VMState); +impl_vmstate_transparent!(std::pin::Pin where T: VMState); impl_vmstate_transparent!(crate::cell::BqlCell where T: VMState); impl_vmstate_transparent!(crate::cell::BqlRefCell where T: VMState); From patchwork Sun Mar 9 10:31:00 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008289 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 58782C282D1 for ; Sun, 9 Mar 2025 10:33:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwe-00081w-R3; Sun, 09 Mar 2025 06:31:44 -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 1trDwd-00081e-DQ for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:43 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwb-00040l-SI for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:43 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516301; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=c3qiG+kkygojNezILoTV1kBIMSGFFOkaYAkVQzTVlDk=; b=WPrS6pXIjABb61nhjgi/TcsJ/o9F7ukC7U+nEKsBtYDryrx0qW6chhHkiukkl1CLD38Yup eVqpUaaTJkqy8+EFt2jRMc3Upxf/VEB8rfQZg7FBGELKup0WSNFEPdE7givBAKiznzeJre pN49V9h6K2YlxYKbIHajES1xyqBtLN0= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-592-I1qb1SVTMLGSMhONB75CTA-1; Sun, 09 Mar 2025 06:31:38 -0400 X-MC-Unique: I1qb1SVTMLGSMhONB75CTA-1 X-Mimecast-MFC-AGG-ID: I1qb1SVTMLGSMhONB75CTA_1741516298 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43cebfa08ccso5198715e9.2 for ; Sun, 09 Mar 2025 03:31:38 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516297; x=1742121097; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=c3qiG+kkygojNezILoTV1kBIMSGFFOkaYAkVQzTVlDk=; b=bAE68axzBfevjj0lKtaW/wRd0TdkXNjMnNjhbvdEKpcDSQhwGVW+emvlb7qJKEK79Z i3415Sk510h30kawK0ePDUKcbl434MpWsxqYGRKt337LGRXxJqX9/CAD7uTk78JzcE+S iOySPcO6Ajqn7NXQgGZ8ucCnOSoN17bwKG+vX5TmkwZRnGsseJ+4A6xgLJGkwi2NFeLh TrtL8f6CSjXtcCLTdMWu4VvajgHcXzJxC8l5bCBEZm5o3hDLuhDxpqDritAzqq66Z+6D oqQYrgwPMjFCViWrR/gMoXcgMdQq3HzCEOun/r2U+3W+vFYIGai4Gjm4icml2FU/tXRr /rzA== X-Gm-Message-State: AOJu0YwOtY9Kluj6nkuGo/TDLRH9b9f/HEYwbTS+xuTuEvtbCpLRcHW4 rsqF5UIAVi6tPxYJXDny4uFq0Wu1LLzGywa71q1dC+BMAdfYEdWdVB3lLex6H9BlSyreTOfjp6w pJwGOuQkn1Rrn75qNE4uTcSSy6PCTjdYjTtxid7C8L79nPe79Bf4WcR4gR8C5vwKMqm96KNbZr1 OPj0+rqrg2mJk2CuWJjOe2JNB1acjkcCBBmaJdDGU= X-Gm-Gg: ASbGncs5WJPeb3lXYMc3AGR7kDeQm8+nEaqDy9q9kzBhuhpzsOaxNipeB7shCdc3sLh hTMizjhpSxdGNVjEvtWC0Y76Wt20svH++PUFUxFmHB7aKEj4xWWSzYsE3na/Ku/8e9OOzvhP4C8 Ngmi3OHQ0MJAQO3Rdz5tqDT6NqmS684lawqvi86gGtuOrYgWeGSZs+UkXgFCFI2SKU7A33hZHQu FYsgoggshL2heM9UYj+Wj6CpZ0XwHHXc/D5v6gknch2sj9IwrC8hQEg+CFJRO3Om2xgFYnXYZrl oZ9ycx09sxcl0/OwknPwFA== X-Received: by 2002:a05:600c:1d15:b0:43c:f75a:eb3c with SMTP id 5b1f17b1804b1-43cf75aecf4mr2297665e9.21.1741516297181; Sun, 09 Mar 2025 03:31:37 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHfxOf65Otv3A18xGvSzbYshD9D+3CNw2CkoIHVIt2KbEY6d3JaFnykfvXnO/Fjm3p9SG+PEA== X-Received: by 2002:a05:600c:1d15:b0:43c:f75a:eb3c with SMTP id 5b1f17b1804b1-43cf75aecf4mr2297545e9.21.1741516296741; Sun, 09 Mar 2025 03:31:36 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43ced9a4b19sm34313535e9.29.2025.03.09.03.31.35 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:35 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 06/25] rust: hpet: embed Timer without the Option and Box indirection Date: Sun, 9 Mar 2025 11:31:00 +0100 Message-ID: <20250309103120.1116448-7-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org This simplifies things for migration, since Option> does not implement VMState. This also shows a soundness issue because Timer::new() will leave a NULL timer list pointer, which can then be dereferenced by Timer::modify(). It will be fixed shortly. Signed-off-by: Paolo Bonzini --- rust/hw/timer/hpet/src/hpet.rs | 59 ++++++++++++++++------------------ 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index be27eb0eff4..02c81ae048f 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -151,14 +151,14 @@ fn timer_handler(timer_cell: &BqlRefCell) { /// HPET Timer Abstraction #[repr(C)] -#[derive(Debug, Default, qemu_api_macros::offsets)] +#[derive(Debug, qemu_api_macros::offsets)] pub struct HPETTimer { /// timer N index within the timer block (`HPETState`) #[doc(alias = "tn")] index: usize, - qemu_timer: Option>, + qemu_timer: Timer, /// timer block abstraction containing this timer - state: Option>, + state: NonNull, // Memory-mapped, software visible timer registers /// Timer N Configuration and Capability Register @@ -181,32 +181,34 @@ pub struct HPETTimer { } impl HPETTimer { - fn init(&mut self, index: usize, state_ptr: *mut HPETState) -> &mut Self { - *self = HPETTimer::default(); - self.index = index; - self.state = NonNull::new(state_ptr); - self - } + fn init(&mut self, index: usize, state: &HPETState) { + *self = HPETTimer { + index, + qemu_timer: Timer::new(), + state: NonNull::new(state as *const _ as *mut _).unwrap(), + config: 0, + cmp: 0, + fsb: 0, + cmp64: 0, + period: 0, + wrap_flag: 0, + last: 0, + }; - fn init_timer_with_state(&mut self) { - self.qemu_timer = Some(Box::new({ - let mut t = Timer::new(); - t.init_full( - None, - CLOCK_VIRTUAL, - Timer::NS, - 0, - timer_handler, - &self.get_state().timers[self.index], - ); - t - })); + self.qemu_timer.init_full( + None, + CLOCK_VIRTUAL, + Timer::NS, + 0, + timer_handler, + &state.timers[self.index], + ) } fn get_state(&self) -> &HPETState { // SAFETY: // the pointer is convertible to a reference - unsafe { self.state.unwrap().as_ref() } + unsafe { self.state.as_ref() } } fn is_int_active(&self) -> bool { @@ -330,7 +332,7 @@ fn arm_timer(&mut self, tick: u64) { } self.last = ns; - self.qemu_timer.as_ref().unwrap().modify(self.last); + self.qemu_timer.modify(self.last); } fn set_timer(&mut self) { @@ -353,7 +355,7 @@ fn set_timer(&mut self) { fn del_timer(&mut self) { // Just remove the timer from the timer_list without destroying // this timer instance. - self.qemu_timer.as_ref().unwrap().delete(); + self.qemu_timer.delete(); if self.is_int_active() { // For level-triggered interrupt, this leaves interrupt status @@ -581,13 +583,8 @@ fn handle_legacy_irq(&self, irq: u32, level: u32) { } fn init_timer(&self) { - let raw_ptr: *mut HPETState = self as *const HPETState as *mut HPETState; - for (index, timer) in self.timers.iter().enumerate() { - timer - .borrow_mut() - .init(index, raw_ptr) - .init_timer_with_state(); + timer.borrow_mut().init(index, self); } } From patchwork Sun Mar 9 10:31:01 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008298 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6898DC28B2E for ; Sun, 9 Mar 2025 10:34:01 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwg-00082G-PU; Sun, 09 Mar 2025 06:31:46 -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 1trDwe-00081x-SC for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:44 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwd-00040v-2i for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:44 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516302; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=gKG0+7vvmzJjH9RZ/kZaNMaiamUMnuHG7RF4nx4rnY8=; b=MIrF61OtPJViGNOYX7cH5M/W4bXyp5W+5hjdxsRa2S7Zo4XM7YzExtY+PGiI2oKBm6o+dZ QPmm5cOm+yZhUa6xQklbBuKDgmrcT3jEBN3kZibjOCykbzOBqQVyeO26mPu09L0MjZCxm7 RyCJzQK8cJo9buIpG4PBPPZeA+y6Yp0= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-576-pYuEZ0n_P9WnqoFmZXjImg-1; Sun, 09 Mar 2025 06:31:40 -0400 X-MC-Unique: pYuEZ0n_P9WnqoFmZXjImg-1 X-Mimecast-MFC-AGG-ID: pYuEZ0n_P9WnqoFmZXjImg_1741516299 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-3912fe32b08so1541298f8f.3 for ; Sun, 09 Mar 2025 03:31:40 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516299; x=1742121099; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=gKG0+7vvmzJjH9RZ/kZaNMaiamUMnuHG7RF4nx4rnY8=; b=u2UKPYfqPadgHk4enQVSg+C2ezVStZUhjxAXk4Uh8VJ8pEs0p8bnqSlSfIJ6rlMeCs 2ycPXiCqpP6bCRSlYqPDRe6ApXValM9X3xZAqmiL3r/tAd4d/QLyuV1525RFg/lEiHQB DfH+GktdoMfOzxipCoLcq+3YSPjr+FFRMKbYswnPMShrt1Z7IRK98Wa5MvQ7QQ3yeljf xjDXagJD8hbhqaqGUwZB9I4kgFNb/IACY0pYOOMG72iLauVLr7tJlBnHYPntKNyWYjUd DdJNefTXk0nAcaYSuO32RvSGPaLVUGaXKQieSFDGgLY5GPIpyqVwq/AzyA/XgqX80Bmn csnA== X-Gm-Message-State: AOJu0Yy4BYCn7uS6VUNTWyJzQucuQ5Z2IxZ9nL1etfifKuE8WXAsjzi1 I6j8iYJVM0vzf7/ww/kQOxgt8g2ZM3+cez8riWuoNMzbGZAfT91rDbWHvQMEZo0rNli8ZBLcS+J Z75We9jl7zKM3QgauH0moP7SBJztHrEyPxJ0p6wP5of4gX1JOC9iT+gtz1TnVZDyLuvEaXC0nXM YyNlFFjbSDI/caxeGpsHpyPnzxXr+7JJ+427Iys5s= X-Gm-Gg: ASbGncvRKyRkHr7vC3gQeABWSjfWaMtQdh86/BFwng/rS0DvGauvcm/KwL2UIgG0JUH o9BFqff0oj4RgU+LE/xyZ+eVgtychoJ7InNnR+klZPrp3fdhclmj3AbNfcL06KEezP9/AW72eEg 5Ebw6CQjPPZfRT2CdpFvTmstxxU01cowDDtvRHUTD7IzfGNA6dVak1Cs0idAveELIhoseY2qFSs Vdp9htiVfWJ1KausTvcJ0KQyt63vbZsYSRXNT3eie7Z11oc7Yv0eY+bl9H9HXZdMQQnEGbQmrJx 8G4Z9bOce6bQnEezVHFklQ== X-Received: by 2002:a05:6000:4107:b0:391:441b:baac with SMTP id ffacd0b85a97d-391441bbe46mr842848f8f.50.1741516298940; Sun, 09 Mar 2025 03:31:38 -0700 (PDT) X-Google-Smtp-Source: AGHT+IElMvNAk97L6LFWmT2+LvqrPo//7Saw/7zAClcolLQrawQNjp67Uu+oNtBuPb9VACiTztamPg== X-Received: by 2002:a05:6000:4107:b0:391:441b:baac with SMTP id ffacd0b85a97d-391441bbe46mr842829f8f.50.1741516298397; Sun, 09 Mar 2025 03:31:38 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43bdd8da097sm113501555e9.17.2025.03.09.03.31.37 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:37 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 07/25] rust: timer: wrap QEMUTimer with Opaque<> and express pinning requirements Date: Sun, 9 Mar 2025 11:31:01 +0100 Message-ID: <20250309103120.1116448-8-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Timers must be pinned in memory, because modify() stores a pointer to them in the TimerList. To express this requirement, change init_full() to take a pinned reference. Because the only way to obtain a Timer is through Timer::new(), which is unsafe, modify() can assume that the timer it got was later initialized; and because the initialization takes a Pin<&mut Timer> modify() can assume that the timer is pinned. In the future the pinning requirement will be expressed through the pin_init crate instead. Note that Timer is a bit different from other users of Opaque, in that it is created in Rust code rather than C code. This is why it has to use the unsafe constructors provided by Opaque; and in fact Timer::new() is also unsafe, because it leaves it to the caller to invoke init_full() before modify(). Without a call to init_full(), modify() will cause a NULL pointer dereference. An alternative could be to combine new() + init_full() by returning a pinned box; however, using a reference makes it easier to express the requirement that the opaque outlives the timer. Signed-off-by: Paolo Bonzini --- meson.build | 7 ----- rust/hw/timer/hpet/src/hpet.rs | 10 ++++++-- rust/qemu-api/src/timer.rs | 47 ++++++++++++++++++++++++++-------- 3 files changed, 44 insertions(+), 20 deletions(-) diff --git a/meson.build b/meson.build index 67ec2b78319..6da4eb317c2 100644 --- a/meson.build +++ b/meson.build @@ -4100,13 +4100,6 @@ if have_rust foreach enum : c_bitfields bindgen_args += ['--bitfield-enum', enum] endforeach - c_nocopy = [ - 'QEMUTimer', - ] - # Used to customize Drop trait - foreach struct : c_nocopy - bindgen_args += ['--no-copy', struct] - endforeach # TODO: Remove this comment when the clang/libclang mismatch issue is solved. # diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index 02c81ae048f..3d3d6ef8eec 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -4,6 +4,7 @@ use std::{ ffi::CStr, + pin::Pin, ptr::{addr_of_mut, null_mut, NonNull}, slice::from_ref, }; @@ -184,7 +185,9 @@ impl HPETTimer { fn init(&mut self, index: usize, state: &HPETState) { *self = HPETTimer { index, - qemu_timer: Timer::new(), + // SAFETY: the HPETTimer will only be used after the timer + // is initialized below. + qemu_timer: unsafe { Timer::new() }, state: NonNull::new(state as *const _ as *mut _).unwrap(), config: 0, cmp: 0, @@ -195,7 +198,10 @@ fn init(&mut self, index: usize, state: &HPETState) { last: 0, }; - self.qemu_timer.init_full( + // SAFETY: HPETTimer is only used as part of HPETState, which is + // always pinned. + let qemu_timer = unsafe { Pin::new_unchecked(&mut self.qemu_timer) }; + qemu_timer.init_full( None, CLOCK_VIRTUAL, Timer::NS, diff --git a/rust/qemu-api/src/timer.rs b/rust/qemu-api/src/timer.rs index a593538917a..f0b04ef95d7 100644 --- a/rust/qemu-api/src/timer.rs +++ b/rust/qemu-api/src/timer.rs @@ -2,31 +2,51 @@ // Author(s): Zhao Liu // SPDX-License-Identifier: GPL-2.0-or-later -use std::os::raw::{c_int, c_void}; +use std::{ + os::raw::{c_int, c_void}, + pin::Pin, +}; use crate::{ bindings::{self, qemu_clock_get_ns, timer_del, timer_init_full, timer_mod, QEMUClockType}, callbacks::FnCall, + cell::Opaque, }; -pub type Timer = bindings::QEMUTimer; -pub type TimerListGroup = bindings::QEMUTimerListGroup; +/// A safe wrapper around [`bindings::QEMUTimer`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct Timer(Opaque); + +unsafe impl Send for Timer {} +unsafe impl Sync for Timer {} + +#[repr(transparent)] +#[derive(qemu_api_macros::Wrapper)] +pub struct TimerListGroup(Opaque); + +unsafe impl Send for TimerListGroup {} +unsafe impl Sync for TimerListGroup {} impl Timer { pub const MS: u32 = bindings::SCALE_MS; pub const US: u32 = bindings::SCALE_US; pub const NS: u32 = bindings::SCALE_NS; - pub fn new() -> Self { - Default::default() - } - - const fn as_mut_ptr(&self) -> *mut Self { - self as *const Timer as *mut _ + /// Create a `Timer` struct without initializing it. + /// + /// # Safety + /// + /// The timer must be initialized before it is armed with + /// [`modify`](Self::modify). + pub unsafe fn new() -> Self { + // SAFETY: requirements relayed to callers of Timer::new + Self(unsafe { Opaque::zeroed() }) } + /// Create a new timer with the given attributes. pub fn init_full<'timer, 'opaque: 'timer, T, F>( - &'timer mut self, + self: Pin<&'timer mut Self>, timer_list_group: Option<&TimerListGroup>, clk_type: ClockType, scale: u32, @@ -51,7 +71,7 @@ pub fn init_full<'timer, 'opaque: 'timer, T, F>( // SAFETY: the opaque outlives the timer unsafe { timer_init_full( - self, + self.as_mut_ptr(), if let Some(g) = timer_list_group { g as *const TimerListGroup as *mut _ } else { @@ -67,14 +87,19 @@ pub fn init_full<'timer, 'opaque: 'timer, T, F>( } pub fn modify(&self, expire_time: u64) { + // SAFETY: the only way to obtain a Timer safely is via methods that + // take a Pin<&mut Self>, therefore the timer is pinned unsafe { timer_mod(self.as_mut_ptr(), expire_time as i64) } } pub fn delete(&self) { + // SAFETY: the only way to obtain a Timer safely is via methods that + // take a Pin<&mut Self>, therefore the timer is pinned unsafe { timer_del(self.as_mut_ptr()) } } } +// FIXME: use something like PinnedDrop from the pinned_init crate impl Drop for Timer { fn drop(&mut self) { self.delete() From patchwork Sun Mar 9 10:31:02 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008301 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 62DA6C28B28 for ; Sun, 9 Mar 2025 10:34:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwj-00083U-By; Sun, 09 Mar 2025 06:31:49 -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 1trDwi-000838-2o for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:48 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwg-00041g-Hf for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:47 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516305; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rpP0mKR1bYf8x/BopqJJucrB8oxIRdemZl6JUWYmoLk=; b=G048KqRL5/UH7IhSVqF0yeio9WnrJsjQfCO5ocmNaBcnvuj+5Z0C5lFLrfEQmDVNU6GDJO jJ1IsMNwi+jzC11i57bQCvL6XX4sAe1dlCwR9vu/KpomWqttEjao0WSkAFHto1BapkKdBN nQg3QdQC6748p1mCKIvg9K3rJ8qkUW0= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-507-2JADQTNEP4q9HxD7HLNsjw-1; Sun, 09 Mar 2025 06:31:42 -0400 X-MC-Unique: 2JADQTNEP4q9HxD7HLNsjw-1 X-Mimecast-MFC-AGG-ID: 2JADQTNEP4q9HxD7HLNsjw_1741516301 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-3911232fd8bso1941488f8f.3 for ; Sun, 09 Mar 2025 03:31:42 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516301; x=1742121101; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rpP0mKR1bYf8x/BopqJJucrB8oxIRdemZl6JUWYmoLk=; b=J5kwlwDXNd1ojPXbxpNBv1GBXythiMVcbBraiU/d029+g4eoCWYOitVqwfDsYRsUfU rnhs0K5v9gtOzStDhMV9raMC7T0P7xMWrsmUXtchTdcrNXN2mThgGntXtg0faCZfH2WF piqdcYhXmFYQ4ekwSnaPsw8KZr76ewmWGWFbUOtCZrG0KHgL9ftH8F00LkvvLABgqVAx V98RtiB4C8h4XVIcNhFbAMhdpIGlWhB3gKkj9BHQJ0VP3WerZHRDvLqPClda8j92t0f+ NzQFf3cyLwkMHh1+yZMgoAULSBVdxToAmhMDLJdRlKhXcXMz4HWfdyszLdYAI+MKWJis T6yw== X-Gm-Message-State: AOJu0Yxi2zlCRD3rsJJGOQK0V7XfdLhtVzE0nb0UTYvHce+pCkp+C2Qv 11kZTGGWDOj8L461WEpBjwEoiokfPGep1e8n2eH4zGGaepyo7K+/LDOAM19CSANbp72VOJ9/4b3 nAzkY5CwflPD45Y7TToGMjKkSy4l9nWIYzwl5wD32cuBir3mtxnRI+RU9290u5McQShpKbnfPSv CUsJq20C30+7TrOieCVmyNxM+x2utPzeVyhx8EwGs= X-Gm-Gg: ASbGncvO9Zn97cZHRqRtiuR51wvmrr5FRVwEhg1qY6qLrSdlFKk0mGAMEv1Txs1sQwO L1QYvVXWySEQGGRlAZPXc271ASWU1GthJR95xE56Z7PVEccD6Cy4EHEMWgmQSE9wJ081k6aIc4J a2SLPveyQs0phk+P0fSkFZEvlUprTj+Txtq3BBnFUhcgxUoMQiMttzBQUZslDmb228UlEFTCHRa dKoj1+wbVMJIwha3iX1trC3TGyJkOBX6cIEXzMDSocLQ6Hs8I/8oIYFWtU7iZdkm7LSAJX8mQsE SDvXXN5hK/ZKJ30JFSHyQg== X-Received: by 2002:a5d:47a2:0:b0:391:12a5:3c95 with SMTP id ffacd0b85a97d-39132d6b98dmr5849368f8f.22.1741516300769; Sun, 09 Mar 2025 03:31:40 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEC8xW0p15YI0G2kw5a9Cy55asrzW+m2sD/bDeBFe7BXW4JBK2+fzFvwTNG2qWioZFSZ37nrQ== X-Received: by 2002:a5d:47a2:0:b0:391:12a5:3c95 with SMTP id ffacd0b85a97d-39132d6b98dmr5849353f8f.22.1741516300321; Sun, 09 Mar 2025 03:31:40 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43bdd8b0461sm114507295e9.4.2025.03.09.03.31.39 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:39 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 08/25] rust: irq: wrap IRQState with Opaque<> Date: Sun, 9 Mar 2025 11:31:02 +0100 Message-ID: <20250309103120.1116448-9-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/irq.rs | 15 ++++++++++----- rust/qemu-api/src/sysbus.rs | 1 + 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/rust/qemu-api/src/irq.rs b/rust/qemu-api/src/irq.rs index 34c19263c23..1222d4fde30 100644 --- a/rust/qemu-api/src/irq.rs +++ b/rust/qemu-api/src/irq.rs @@ -8,10 +8,16 @@ use crate::{ bindings::{self, qemu_set_irq}, + cell::Opaque, prelude::*, qom::ObjectClass, }; +/// An opaque wrapper around [`bindings::IRQState`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct IRQState(Opaque); + /// Interrupt sources are used by devices to pass changes to a value (typically /// a boolean). The interrupt sink is usually an interrupt controller or /// GPIO controller. @@ -21,8 +27,7 @@ /// method sends a `true` value to the sink. If the guest has to see a /// different polarity, that change is performed by the board between the /// device and the interrupt controller. -pub type IRQState = bindings::IRQState; - +/// /// Interrupts are implemented as a pointer to the interrupt "sink", which has /// type [`IRQState`]. A device exposes its source as a QOM link property using /// a function such as [`SysBusDeviceMethods::init_irq`], and @@ -40,7 +45,7 @@ pub struct InterruptSource where c_int: From, { - cell: BqlCell<*mut IRQState>, + cell: BqlCell<*mut bindings::IRQState>, _marker: PhantomData, } @@ -79,11 +84,11 @@ pub fn set(&self, level: T) { } } - pub(crate) const fn as_ptr(&self) -> *mut *mut IRQState { + pub(crate) const fn as_ptr(&self) -> *mut *mut bindings::IRQState { self.cell.as_ptr() } - pub(crate) const fn slice_as_ptr(slice: &[Self]) -> *mut *mut IRQState { + pub(crate) const fn slice_as_ptr(slice: &[Self]) -> *mut *mut bindings::IRQState { assert!(!slice.is_empty()); slice[0].as_ptr() } diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index 04821a2b9b3..48803a655f9 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -79,6 +79,7 @@ fn mmio_map(&self, id: u32, addr: u64) { fn connect_irq(&self, id: u32, irq: &Owned) { assert!(bql_locked()); let id: i32 = id.try_into().unwrap(); + let irq: &IRQState = irq; unsafe { bindings::sysbus_connect_irq(self.as_mut_ptr(), id, irq.as_mut_ptr()); } From patchwork Sun Mar 9 10:31:03 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008305 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BA9D3C28B28 for ; Sun, 9 Mar 2025 10:35:22 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwl-00083z-Hx; Sun, 09 Mar 2025 06:31:51 -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 1trDwi-00083L-OF for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:48 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwg-00041l-R3 for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:48 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516306; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=tXHZ7ahE0SuDjTAp4gMKpg+0aMsCMDD4X5FjTPi4lj4=; b=hhA55siOyuJl1Klib18/ehrWJTYrijb6tS0SJOm2cm8hTwsETD40q36LDSySqwMHPmFLAw VWFV9gK2JBoIZlQK0iU8er6omC5eNN7Et/pgfjIItNUUVH6dQ9ujN/KEz4jTucu+TJ3n/g Ln3K7HWl4zegAqYv50wCOJ80vTJeE9U= Received: from mail-wr1-f70.google.com (mail-wr1-f70.google.com [209.85.221.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-644--IauSEMsP-Spia04ili-5Q-1; Sun, 09 Mar 2025 06:31:44 -0400 X-MC-Unique: -IauSEMsP-Spia04ili-5Q-1 X-Mimecast-MFC-AGG-ID: -IauSEMsP-Spia04ili-5Q_1741516304 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-39137e17c50so604966f8f.3 for ; Sun, 09 Mar 2025 03:31:44 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516303; x=1742121103; 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=tXHZ7ahE0SuDjTAp4gMKpg+0aMsCMDD4X5FjTPi4lj4=; b=TgQ2qeMzDCrghBwEbr45M+fX6EPYBMGuNq8mhWQpHv5S2SNc9UEZPmRhi3nOT1FHAl op+1BRZS/wF6GRVYkkIhJMynSgxVZewq24Eww0ZWRRqD0r8put8kmyRwVsyk3FYt4ENq SmVppSmW+/dAh6q1q85nzybXMmmtOpN6NSdfOnvMgvUTv6modqCSJegu/baq0xtF7HUh LKgYovLzoTBl0mnFSp9DBT53sAmX9vL6Ah0LtzYyceaPTczz23PoEjMq2S0YC1ZA8jR6 iE29Iv727LbutXlS7N6z/c2DAivXiDDWEXos7gLwYFQCwOtUqLoeXhSz3sD1vxsJgU+H +2Hg== X-Gm-Message-State: AOJu0YzTS53gGajYzLATQfvDCDtQoXWdrXw19orb4wYIy+LLUVt8IeHe y+ozMNbD076+uMk/7BGzP1i8Elb7wReCzkkLo8+BFeHQkrSuglN7cunAuxqmyGxb7A//nYnkNwX 1TNJw8dFU6CQIMAEltgfqkxsex1AMSxSvnvlufO46C+v2X9aIEthyRxAoKDAbUSw/MnI6D3tTA8 26iCYiK5RfFLi/wyCc//+HW8ZhYgLQDIdPx0cRLkc= X-Gm-Gg: ASbGncsyyDWdL1lAH295YD/xhiRG5rztrW5P3sJtc8WH7FXafnxUmoJFliEDACLulfr MReRQq2nQfRX4wXzv0LDWRAuPGbkV62A/n9XtiN2jKt59nJvg7QK0znvXE3G4/bRUn2iDX/vPHw /ViYn+d4AL7Lk7ChVUUT4aaPsnruAmMakSVLXF6bRxmdFHSIS6SkZ5lFUzmhouSShBo4K4R0Pad Ea96RvEh6VfrW7fxMr8T23HQBcwRbRQt7RsLAeWgXrYiPhlp5JiAIIYL5jxkLfx11DGmcw02eR3 DShmZ9F0k4RvejlnLexkfw== X-Received: by 2002:a5d:6d8c:0:b0:390:e85b:a8ee with SMTP id ffacd0b85a97d-39132d163dbmr5743276f8f.1.1741516302867; Sun, 09 Mar 2025 03:31:42 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEtO8ZDO4bBoHP3ty4n26uKI3z7LBjpJRqN4v1t6hywcGQCYL8ZUwvUVmyR2Hwla7X9rBgdYA== X-Received: by 2002:a5d:6d8c:0:b0:390:e85b:a8ee with SMTP id ffacd0b85a97d-39132d163dbmr5743259f8f.1.1741516302378; Sun, 09 Mar 2025 03:31:42 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43cec28e1c4sm20191175e9.1.2025.03.09.03.31.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:41 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 09/25] rust: qom: wrap Object with Opaque<> Date: Sun, 9 Mar 2025 11:31:03 +0100 Message-ID: <20250309103120.1116448-10-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 3 --- rust/qemu-api/src/memory.rs | 2 +- rust/qemu-api/src/qdev.rs | 6 +++--- rust/qemu-api/src/qom.rs | 35 ++++++++++++++++++++++------------- 4 files changed, 26 insertions(+), 20 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index d2868639ff6..be6dd68c09c 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -46,9 +46,6 @@ unsafe impl Sync for MemoryRegion {} unsafe impl Send for ObjectClass {} unsafe impl Sync for ObjectClass {} -unsafe impl Send for Object {} -unsafe impl Sync for Object {} - unsafe impl Send for SysBusDevice {} unsafe impl Sync for SysBusDevice {} diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs index 682951ab44e..713c494ca2e 100644 --- a/rust/qemu-api/src/memory.rs +++ b/rust/qemu-api/src/memory.rs @@ -157,7 +157,7 @@ unsafe fn do_init_io( let cstr = CString::new(name).unwrap(); memory_region_init_io( slot, - owner.cast::(), + owner.cast::(), ops, owner.cast::(), cstr.as_ptr(), diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index c136457090c..1a4d1f38762 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -52,7 +52,7 @@ pub trait ResettablePhasesImpl { /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. unsafe extern "C" fn rust_resettable_enter_fn( - obj: *mut Object, + obj: *mut bindings::Object, typ: ResetType, ) { let state = NonNull::new(obj).unwrap().cast::(); @@ -65,7 +65,7 @@ pub trait ResettablePhasesImpl { /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. unsafe extern "C" fn rust_resettable_hold_fn( - obj: *mut Object, + obj: *mut bindings::Object, typ: ResetType, ) { let state = NonNull::new(obj).unwrap().cast::(); @@ -78,7 +78,7 @@ pub trait ResettablePhasesImpl { /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. unsafe extern "C" fn rust_resettable_exit_fn( - obj: *mut Object, + obj: *mut bindings::Object, typ: ResetType, ) { let state = NonNull::new(obj).unwrap().cast::(); diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 5488643a2fd..2defbd23516 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -101,16 +101,24 @@ ptr::NonNull, }; -pub use bindings::{Object, ObjectClass}; +pub use bindings::ObjectClass; use crate::{ bindings::{ self, object_class_dynamic_cast, object_dynamic_cast, object_get_class, object_get_typename, object_new, object_ref, object_unref, TypeInfo, }, - cell::bql_locked, + cell::{bql_locked, Opaque}, }; +/// A safe wrapper around [`bindings::Object`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct Object(Opaque); + +unsafe impl Send for Object {} +unsafe impl Sync for Object {} + /// Marker trait: `Self` can be statically upcasted to `P` (i.e. `P` is a direct /// or indirect parent of `Self`). /// @@ -199,7 +207,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { } } -unsafe extern "C" fn rust_instance_init(obj: *mut Object) { +unsafe extern "C" fn rust_instance_init(obj: *mut bindings::Object) { let mut state = NonNull::new(obj).unwrap().cast::(); // SAFETY: obj is an instance of T, since rust_instance_init // is called from QOM core as the instance_init function @@ -209,7 +217,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { } } -unsafe extern "C" fn rust_instance_post_init(obj: *mut Object) { +unsafe extern "C" fn rust_instance_post_init(obj: *mut bindings::Object) { let state = NonNull::new(obj).unwrap().cast::(); // SAFETY: obj is an instance of T, since rust_instance_post_init // is called from QOM core as the instance_post_init function @@ -230,7 +238,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> { ::CLASS_INIT(unsafe { klass.as_mut() }) } -unsafe extern "C" fn drop_object(obj: *mut Object) { +unsafe extern "C" fn drop_object(obj: *mut bindings::Object) { // SAFETY: obj is an instance of T, since drop_object is called // from the QOM core function object_deinit() as the instance_finalize // function for class T. Note that while object_deinit() will drop the @@ -280,14 +288,14 @@ pub unsafe trait ObjectType: Sized { /// Return the receiver as an Object. This is always safe, even /// if this type represents an interface. fn as_object(&self) -> &Object { - unsafe { &*self.as_object_ptr() } + unsafe { &*self.as_ptr().cast() } } /// Return the receiver as a const raw pointer to Object. /// This is preferrable to `as_object_mut_ptr()` if a C /// function only needs a `const Object *`. - fn as_object_ptr(&self) -> *const Object { - self.as_ptr().cast() + fn as_object_ptr(&self) -> *const bindings::Object { + self.as_object().as_ptr() } /// Return the receiver as a mutable raw pointer to Object. @@ -297,8 +305,8 @@ fn as_object_ptr(&self) -> *const Object { /// This cast is always safe, but because the result is mutable /// and the incoming reference is not, this should only be used /// for calls to C functions, and only if needed. - unsafe fn as_object_mut_ptr(&self) -> *mut Object { - self.as_object_ptr() as *mut _ + unsafe fn as_object_mut_ptr(&self) -> *mut bindings::Object { + self.as_object().as_mut_ptr() } } @@ -621,7 +629,7 @@ pub trait ObjectImpl: ObjectType + IsA { /// We expect the FFI user of this function to pass a valid pointer that /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. -unsafe extern "C" fn rust_unparent_fn(dev: *mut Object) { +unsafe extern "C" fn rust_unparent_fn(dev: *mut bindings::Object) { let state = NonNull::new(dev).unwrap().cast::(); T::UNPARENT.unwrap()(unsafe { state.as_ref() }); } @@ -796,8 +804,9 @@ fn new() -> Owned { // SAFETY: the object created by object_new is allocated on // the heap and has a reference count of 1 unsafe { - let obj = &*object_new(Self::TYPE_NAME.as_ptr()); - Owned::from_raw(obj.unsafe_cast::()) + let raw_obj = object_new(Self::TYPE_NAME.as_ptr()); + let obj = Object::from_raw(raw_obj).unsafe_cast::(); + Owned::from_raw(obj) } } } From patchwork Sun Mar 9 10:31:04 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008292 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E3D42C28B28 for ; Sun, 9 Mar 2025 10:33:14 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwn-00084m-6L; Sun, 09 Mar 2025 06:31:53 -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 1trDwk-00083v-M3 for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:51 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwi-000424-T5 for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:50 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516308; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=SqsGJNftWM1nTyRVPF20AlSEyETSkxx30EnRjrvmmVk=; b=a2fy4vuLgAeosAVhHbMnHUExe8zRdBenzINgJEewVw9z70Y3+Z1Y7NgjERbg21AOTvut7D wANpXPRIUIRT9uqH+4MuQlMXLk5a86oKGmgHlR2P7U9blGlm+nqpCE/N1aeKrq1JFGzNEY O/IpChDHOzaf1sT0EYPFCmv9pQvtr+M= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-630-tSD7srqgPGWEQ60yu0FWFg-1; Sun, 09 Mar 2025 06:31:47 -0400 X-MC-Unique: tSD7srqgPGWEQ60yu0FWFg-1 X-Mimecast-MFC-AGG-ID: tSD7srqgPGWEQ60yu0FWFg_1741516306 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-43bd8fd03a2so14698095e9.3 for ; Sun, 09 Mar 2025 03:31:46 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516305; x=1742121105; 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=SqsGJNftWM1nTyRVPF20AlSEyETSkxx30EnRjrvmmVk=; b=L4v5XeF1jrQKnzydpacHJOCQ5RRt1HZGVnQrQTzoAymUIw4elFRGR4mV+1vfbjj8X1 azXBkQl727UG67XkRygFyj3ecRtuJnltatN0yaRuyxmMHFTyvXBnMFGf0CZrUUfAQxRu vqYDyO7+kQay2acQxC2BuCjTJrH6lEGyD/WTniSOFPRExQ/HJrWa6KF8p2ZFSRgtoeN0 oG3i6mupzpLuuzLXT4pj3cWsIQL9Idynlf9XQ66NDrwliOY7obFwkG6CC7Xupt3O99J3 25sfnugimMnlQPi/mcboIOdm0zFWjlw4HqKXQ0spbYniMT2SikyOczeDaX9qns76ghKe gGRA== X-Gm-Message-State: AOJu0YwuNgAsVHM7PZqpk/MP7fffMIxLpRK+0y7W2XotzqIuaKEqZyrv XES+535VS3F8JYEBF43ARnpq/9IcU0wefuz3mbZR7yyc+be+UU+2jH/vMkcCtcnqavhlZThI5Ro Gt56+ecfOP9IozGGjfHozjzP0yPyvlTLE9j9kGKVx5ypBw4A/Hmm1Y0xcHR7plweVnGlr46Kx5x c8cipiZHaC4o1hNFPzCsJoyRasP7msdgQ7FzS+z0U= X-Gm-Gg: ASbGncsJQ2x2wUJ0tbWJgmV2GE1ewdJmme1qGfIV9chzrKL73xLqqDstfwGHORWyPHl zQaYST2+I8YPxAsrJwcs1qGEWMPpxjyydCoeC9MHEmAhJpcukMK2ZIK24McA7EzIRUieTxmLnfs n6b858cmdvWYvm22JDTbiM92DYzcEfL2h4sbSawZi4t1vKft6dwGrusbAFPaICmrrbb664g0dHm P7+4kSIpS02PTX4llASleC0UfPiUgWaVlbFL10o1bPUVFfwzXqiVvIIbwLdGHkZ3V4iorLgquNQ rh4Oy/nE7QpE+XEw7RozvA== X-Received: by 2002:a05:6000:402a:b0:38f:23f4:2d7a with SMTP id ffacd0b85a97d-39132dc51admr6999166f8f.40.1741516304913; Sun, 09 Mar 2025 03:31:44 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFWqMHHrs3+v9xNSfsdPe2fT+UdNsRv2a2d2TEsa8aRq4RBxexPzD7OXhMaZobte132CpXg1Q== X-Received: by 2002:a05:6000:402a:b0:38f:23f4:2d7a with SMTP id ffacd0b85a97d-39132dc51admr6999147f8f.40.1741516304407; Sun, 09 Mar 2025 03:31:44 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912c01d81csm11650657f8f.58.2025.03.09.03.31.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:43 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 10/25] rust: qdev: wrap Clock and DeviceState with Opaque<> Date: Sun, 9 Mar 2025 11:31:04 +0100 Message-ID: <20250309103120.1116448-11-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 6 ---- rust/qemu-api/src/qdev.rs | 68 ++++++++++++++++++++++++----------- rust/qemu-api/src/vmstate.rs | 2 +- 3 files changed, 49 insertions(+), 27 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index be6dd68c09c..6e70a75a0e6 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -34,12 +34,6 @@ unsafe impl Sync for CharBackend {} unsafe impl Send for Chardev {} unsafe impl Sync for Chardev {} -unsafe impl Send for Clock {} -unsafe impl Sync for Clock {} - -unsafe impl Send for DeviceState {} -unsafe impl Sync for DeviceState {} - unsafe impl Send for MemoryRegion {} unsafe impl Sync for MemoryRegion {} diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index 1a4d1f38762..1c4a67b5728 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -10,12 +10,12 @@ ptr::NonNull, }; -pub use bindings::{Clock, ClockEvent, DeviceClass, DeviceState, Property, ResetType}; +pub use bindings::{ClockEvent, DeviceClass, Property, ResetType}; use crate::{ bindings::{self, qdev_init_gpio_in, qdev_init_gpio_out, Error, ResettableClass}, callbacks::FnCall, - cell::bql_locked, + cell::{bql_locked, Opaque}, chardev::Chardev, irq::InterruptSource, prelude::*, @@ -23,6 +23,22 @@ vmstate::VMStateDescription, }; +/// A safe wrapper around [`bindings::Clock`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct Clock(Opaque); + +unsafe impl Send for Clock {} +unsafe impl Sync for Clock {} + +/// A safe wrapper around [`bindings::DeviceState`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct DeviceState(Opaque); + +unsafe impl Send for DeviceState {} +unsafe impl Sync for DeviceState {} + /// Trait providing the contents of the `ResettablePhases` struct, /// which is part of the QOM `Resettable` interface. pub trait ResettablePhasesImpl { @@ -117,7 +133,10 @@ fn vmsd() -> Option<&'static VMStateDescription> { /// We expect the FFI user of this function to pass a valid pointer that /// can be downcasted to type `T`. We also expect the device is /// readable/writeable from one thread at any time. -unsafe extern "C" fn rust_realize_fn(dev: *mut DeviceState, _errp: *mut *mut Error) { +unsafe extern "C" fn rust_realize_fn( + dev: *mut bindings::DeviceState, + _errp: *mut *mut Error, +) { let state = NonNull::new(dev).unwrap().cast::(); T::REALIZE.unwrap()(unsafe { state.as_ref() }); } @@ -251,7 +270,7 @@ fn init_clock_in FnCall<(&'a Self::Target, ClockEvent)>>( events: ClockEvent, ) -> Owned { fn do_init_clock_in( - dev: *mut DeviceState, + dev: &DeviceState, name: &str, cb: Option, events: ClockEvent, @@ -265,14 +284,15 @@ fn do_init_clock_in( unsafe { let cstr = CString::new(name).unwrap(); let clk = bindings::qdev_init_clock_in( - dev, + dev.as_mut_ptr(), cstr.as_ptr(), cb, - dev.cast::(), + dev.as_void_ptr(), events.0, ); - Owned::from(&*clk) + let clk: &Clock = Clock::from_raw(clk); + Owned::from(clk) } } @@ -289,7 +309,7 @@ fn do_init_clock_in( None }; - do_init_clock_in(self.as_mut_ptr(), name, cb, events) + do_init_clock_in(self.upcast(), name, cb, events) } /// Add an output clock named `name`. @@ -304,9 +324,10 @@ fn do_init_clock_in( fn init_clock_out(&self, name: &str) -> Owned { unsafe { let cstr = CString::new(name).unwrap(); - let clk = bindings::qdev_init_clock_out(self.as_mut_ptr(), cstr.as_ptr()); + let clk = bindings::qdev_init_clock_out(self.upcast().as_mut_ptr(), cstr.as_ptr()); - Owned::from(&*clk) + let clk: &Clock = Clock::from_raw(clk); + Owned::from(clk) } } @@ -314,7 +335,11 @@ fn prop_set_chr(&self, propname: &str, chr: &Owned) { assert!(bql_locked()); let c_propname = CString::new(propname).unwrap(); unsafe { - bindings::qdev_prop_set_chr(self.as_mut_ptr(), c_propname.as_ptr(), chr.as_mut_ptr()); + bindings::qdev_prop_set_chr( + self.upcast().as_mut_ptr(), + c_propname.as_ptr(), + chr.as_mut_ptr(), + ); } } @@ -323,8 +348,17 @@ fn init_gpio_in FnCall<(&'a Self::Target, u32, u32)>>( num_lines: u32, _cb: F, ) { - let _: () = F::ASSERT_IS_SOME; + fn do_init_gpio_in( + dev: &DeviceState, + num_lines: u32, + gpio_in_cb: unsafe extern "C" fn(*mut c_void, c_int, c_int), + ) { + unsafe { + qdev_init_gpio_in(dev.as_mut_ptr(), Some(gpio_in_cb), num_lines as c_int); + } + } + let _: () = F::ASSERT_IS_SOME; unsafe extern "C" fn rust_irq_handler FnCall<(&'a T, u32, u32)>>( opaque: *mut c_void, line: c_int, @@ -337,19 +371,13 @@ fn init_gpio_in FnCall<(&'a Self::Target, u32, u32)>>( let gpio_in_cb: unsafe extern "C" fn(*mut c_void, c_int, c_int) = rust_irq_handler::; - unsafe { - qdev_init_gpio_in( - self.as_mut_ptr::(), - Some(gpio_in_cb), - num_lines as c_int, - ); - } + do_init_gpio_in(self.upcast(), num_lines, gpio_in_cb); } fn init_gpio_out(&self, pins: &[InterruptSource]) { unsafe { qdev_init_gpio_out( - self.as_mut_ptr::(), + self.upcast().as_mut_ptr(), InterruptSource::slice_as_ptr(pins), pins.len() as c_int, ); diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 1e7ba531e2a..f0510ae769d 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -470,7 +470,7 @@ macro_rules! vmstate_clock { $crate::assert_field_type!( $struct_name, $field_name, - $crate::qom::Owned<$crate::bindings::Clock> + $crate::qom::Owned<$crate::qdev::Clock> ); $crate::offset_of!($struct_name, $field_name) }, From patchwork Sun Mar 9 10:31:05 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008290 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 109BBC28B28 for ; Sun, 9 Mar 2025 10:33:05 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwo-000859-5w; Sun, 09 Mar 2025 06:31:54 -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 1trDwm-00084Y-2X for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:52 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwk-00042I-It for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:51 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516310; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=B8+l2RbHUK94td6RHPrgOYB0tXiyNEPAhvV3YsF6B9k=; b=evo3a0egDcrh3kaxrGybjQ+03YrcuZVshIaRnDc4t1fjcOISdNsI4loihiV6sMtUKF6v2f wcuiQPzHbuaJNsvj8alrGldjuQS9Fgi8H1LzxBQoT2xID8kCuxMLKAh2iMlRK2+4lEskUx sYzH6j5x4tWg2bMSl4hSabSIwu44xWo= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-632-2nFxXlSvOdWG2td_cu31Ow-1; Sun, 09 Mar 2025 06:31:48 -0400 X-MC-Unique: 2nFxXlSvOdWG2td_cu31Ow-1 X-Mimecast-MFC-AGG-ID: 2nFxXlSvOdWG2td_cu31Ow_1741516307 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43bdfb04bffso21110315e9.2 for ; Sun, 09 Mar 2025 03:31:48 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516307; x=1742121107; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=B8+l2RbHUK94td6RHPrgOYB0tXiyNEPAhvV3YsF6B9k=; b=d6ju6POHZAmYeFzJ67tGcdYZiLJVG2vj/tLVcy7GAbvm62x46Axc3IadlMl7L1O5C8 HQ70EOfSxt1/p1VfYmUkyhb+wIOrISHSqkRPv6K37vdVlZJUR2UZx8KM5aSKS0GU2RZf +hm6ypgSZtpjJnpoqvwdyfY5W0G3dEbQDU37FEEgscR8IdRq5eOLg1gA0oXTurcszGge tkj6DUZzCRadj/+vsR13esBzQWifcjgDJb6b8fauT5CTH3/dzidGXygD63TvsR86/oD/ W4LV3xKJ25SO0bNSe1GaT7t+/RErFJJXQy1BimHhHt9h/LCcRZYRf34TqUzpXezgP9gj ehkQ== X-Gm-Message-State: AOJu0Yyp4Y6b36JtSIUlshzlQvhEU1NvQJtGBIBFtDrf+qX0GvM0hVLi BoMUuPRvUSggCrWl47ELnxwRD+e+b3hxymUUqCFC05imAydI2V+dCoRzzmyVtWoYNV19Wey0i3G TgSCNt1EuYZMnaSe2uk6P3dIEWhSWYBgzdzfrs+J6/Gz9z+6i0ygktU5nERy0fJKd9KaZNIdHkU ci1Ffqnx4gYO/j2A/MZndx5RM0ULtYVCIG8Vl4km8= X-Gm-Gg: ASbGnctLV3rDLxmKxiphT9utcS+F6PVO2olA79K1I83/5xNKnJJf2qxNleQNIZnTUyr RLj+TJq1DlHB+NEmvCIYd8346V2+xgmESHpsfWqmO3zKy4RpHI1lMKx+E7uIapEwBMtPu9JeXSX Q2x7xeiLoeLLrxCwlF4zSiKvVOiGZNNUdlMEdpoQAPQzgrXh7d8fWQ5Oksi3oKuoM4IlOapN2Dj z85LRC4yvwMfR/tEFqVIkwAyB+B8rNp2mp7aDWNtxOKTFKKfTssrM1DtU1keBwW658i0cUy5jQK M/BLAnMJ9dR6XgLOz0hKmw== X-Received: by 2002:a05:600c:5248:b0:43c:ed61:2c26 with SMTP id 5b1f17b1804b1-43ced612d1amr20028105e9.17.1741516306978; Sun, 09 Mar 2025 03:31:46 -0700 (PDT) X-Google-Smtp-Source: AGHT+IE7BWf9FyNUaUa6iRAVsu4zXYUv94wDhXA1+QLL7hhF2WS5VaOVEAHMbz+4rD+we00QuJsTqQ== X-Received: by 2002:a05:600c:5248:b0:43c:ed61:2c26 with SMTP id 5b1f17b1804b1-43ced612d1amr20027905e9.17.1741516306509; Sun, 09 Mar 2025 03:31:46 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912c0e1d67sm11506919f8f.74.2025.03.09.03.31.45 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:45 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 11/25] rust: hpet: do not access fields of SysBusDevice Date: Sun, 9 Mar 2025 11:31:05 +0100 Message-ID: <20250309103120.1116448-12-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Fields of SysBusDevice must only be accessed with the BQL taken. Add a wrapper that verifies that. Signed-off-by: Paolo Bonzini --- rust/hw/timer/hpet/src/hpet.rs | 4 +--- rust/qemu-api/src/sysbus.rs | 12 ++++++++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index 3d3d6ef8eec..d989360ede8 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -730,8 +730,6 @@ fn realize(&self) { } fn reset_hold(&self, _type: ResetType) { - let sbd = self.upcast::(); - for timer in self.timers.iter().take(self.num_timers.get()) { timer.borrow_mut().reset(); } @@ -744,7 +742,7 @@ fn reset_hold(&self, _type: ResetType) { HPETFwConfig::update_hpet_cfg( self.hpet_id.get(), self.capability.get() as u32, - sbd.mmio[0].addr, + self.mmio_addr(0).unwrap(), ); // to document that the RTC lowers its output on reset as well diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index 48803a655f9..0790576d446 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -64,6 +64,18 @@ fn init_irq(&self, irq: &InterruptSource) { } } + // TODO: do we want a type like GuestAddress here? + fn mmio_addr(&self, id: u32) -> Option { + assert!(bql_locked()); + let sbd = self.upcast(); + let id: usize = id.try_into().unwrap(); + if sbd.mmio[id].memory.is_null() { + None + } else { + Some(sbd.mmio[id].addr) + } + } + // TODO: do we want a type like GuestAddress here? fn mmio_map(&self, id: u32, addr: u64) { assert!(bql_locked()); From patchwork Sun Mar 9 10:31:06 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008303 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 91904C28B2E for ; Sun, 9 Mar 2025 10:34:33 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwr-00085q-8a; Sun, 09 Mar 2025 06:31:57 -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 1trDwp-00085P-9B for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:55 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwn-00042o-JM for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516312; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Hp60NgzpFm3jMkNxot3ICZaotMUbZm/BSXyoCpaAV7I=; b=Pa47r29bOM3jK34OxvDj8dXR8bojhtZo6bRy+8a3nHknCg1jep0zi+Vm3ys99b3MClQanb UIiAsO/3mkKNLjcZ1BDd7UeB+PyJdIgiu1V9zzVzGkeiq9pw6BH1RKRQcz2tgOXfdvJbEb QLnVPDDH9PpUECsW+fDJpc2HpDr1R88= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-327-IumTV9SnNla_oK7-K6eE7w-1; Sun, 09 Mar 2025 06:31:50 -0400 X-MC-Unique: IumTV9SnNla_oK7-K6eE7w-1 X-Mimecast-MFC-AGG-ID: IumTV9SnNla_oK7-K6eE7w_1741516309 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-39142ce2151so136462f8f.1 for ; Sun, 09 Mar 2025 03:31:49 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516308; x=1742121108; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=Hp60NgzpFm3jMkNxot3ICZaotMUbZm/BSXyoCpaAV7I=; b=hz1MTepqXqNKjRnl/GUIzafzp/4AQbuimBnR8MjDmHSavNWIA5XQcHsUUzHtGoJSI6 VTCLShkWL0aYh2giMPULbjlMK2Me+Wl5dQrg2ZUMdzohRaTA4jqIa1uZ9NKnxKW6+CEs 0KcEoK2+8dgBcb6H5mAUPZ7JhwsqRazu+lriWAi7sb+8KBDiWKs0FdthlX6ZdpAAPbmT rEM2RoA1ILTN/qxymvyYrfMC8SsMGuZlaboWj2Z57mJvo8BywWtB5Uk5lzcmVXlGax/S Qrf/Su7Xx8qCMDFvGi8dji4sKk1+XeP8KaNoR7YH4afuHmjXx/m2LC83nFmZ/M361vft PQqg== X-Gm-Message-State: AOJu0Yz2ZB6G+4ftK4130wXMkG1CKLfNuvIPYO2LnP66DlrlMHaOxo6/ als6U46NlUugSdp2OeZ467YAQ7M2DTtX31bBrtNCiIK6pdNplbVomkOz6HdUmNTh7uyL8p+NtcP OA+UthCDdFT8pEIgs0/oblnQz4d34UO2M0S6OpYpM4Szn0dvL/36GsVSTfhN8xDzuNb/XNdRy0s 8bOK1em8ysFnUQ/ifo/9cfYBxCTB7zmvtCH2s/wLw= X-Gm-Gg: ASbGnctwBsekvyFB5a99TbWrzqwhEds6OtIC+LYazuDBqtpeQ99yVyUMHsLKsIH0P9X nsyJqibkQEIj0XApTQ59p177YqgKTq4nxzhftjfBl6mlU2hV6J4zKVGCIeoPZcltdyoqNDb1naH Ks8gxaXJOv0X4J9IlL4CdE7Q+hTpV6/0Omqp4jGrHfm5BoKyEa9Tpyagpu7m0JdXAPrvm54G/wx 8OS/qe4cR9R1i0c/oQrYzl5pwYgTUkXm11Z0JDV5f6rhYATT8miKjs0tObcR+GqXzBnCH3TNckv dqMBIwOb8L2WkKxtSC1t+g== X-Received: by 2002:a5d:47cc:0:b0:391:23de:b1b4 with SMTP id ffacd0b85a97d-39132db0648mr6275542f8f.45.1741516308602; Sun, 09 Mar 2025 03:31:48 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGUGvbKAW3FccWIUTK2Y3T66VPkgXr2R6M+osFDEOctQI2KE0VCwH2WHNCtzOXg98YsFaVZsg== X-Received: by 2002:a5d:47cc:0:b0:391:23de:b1b4 with SMTP id ffacd0b85a97d-39132db0648mr6275527f8f.45.1741516308147; Sun, 09 Mar 2025 03:31:48 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912c0e2f10sm11558920f8f.65.2025.03.09.03.31.47 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:47 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 12/25] rust: sysbus: wrap SysBusDevice with Opaque<> Date: Sun, 9 Mar 2025 11:31:06 +0100 Message-ID: <20250309103120.1116448-13-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 3 --- rust/qemu-api/src/sysbus.rs | 29 +++++++++++++++++++++-------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index 6e70a75a0e6..b791ca6d87f 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -40,9 +40,6 @@ unsafe impl Sync for MemoryRegion {} unsafe impl Send for ObjectClass {} unsafe impl Sync for ObjectClass {} -unsafe impl Send for SysBusDevice {} -unsafe impl Sync for SysBusDevice {} - // SAFETY: this is a pure data struct unsafe impl Send for CoalescedMemoryRange {} unsafe impl Sync for CoalescedMemoryRange {} diff --git a/rust/qemu-api/src/sysbus.rs b/rust/qemu-api/src/sysbus.rs index 0790576d446..e92502a8fe6 100644 --- a/rust/qemu-api/src/sysbus.rs +++ b/rust/qemu-api/src/sysbus.rs @@ -6,11 +6,11 @@ use std::{ffi::CStr, ptr::addr_of_mut}; -pub use bindings::{SysBusDevice, SysBusDeviceClass}; +pub use bindings::SysBusDeviceClass; use crate::{ bindings, - cell::bql_locked, + cell::{bql_locked, Opaque}, irq::{IRQState, InterruptSource}, memory::MemoryRegion, prelude::*, @@ -18,6 +18,14 @@ qom::Owned, }; +/// A safe wrapper around [`bindings::SysBusDevice`]. +#[repr(transparent)] +#[derive(Debug, qemu_api_macros::Wrapper)] +pub struct SysBusDevice(Opaque); + +unsafe impl Send for SysBusDevice {} +unsafe impl Sync for SysBusDevice {} + unsafe impl ObjectType for SysBusDevice { type Class = SysBusDeviceClass; const TYPE_NAME: &'static CStr = @@ -49,7 +57,7 @@ pub trait SysBusDeviceMethods: ObjectDeref fn init_mmio(&self, iomem: &MemoryRegion) { assert!(bql_locked()); unsafe { - bindings::sysbus_init_mmio(self.as_mut_ptr(), iomem.as_mut_ptr()); + bindings::sysbus_init_mmio(self.upcast().as_mut_ptr(), iomem.as_mut_ptr()); } } @@ -60,14 +68,16 @@ fn init_mmio(&self, iomem: &MemoryRegion) { fn init_irq(&self, irq: &InterruptSource) { assert!(bql_locked()); unsafe { - bindings::sysbus_init_irq(self.as_mut_ptr(), irq.as_ptr()); + bindings::sysbus_init_irq(self.upcast().as_mut_ptr(), irq.as_ptr()); } } // TODO: do we want a type like GuestAddress here? fn mmio_addr(&self, id: u32) -> Option { assert!(bql_locked()); - let sbd = self.upcast(); + // SAFETY: the BQL ensures that no one else writes to sbd.mmio[], and + // the SysBusDevice must be initialized to get an IsA. + let sbd = unsafe { *self.upcast().as_ptr() }; let id: usize = id.try_into().unwrap(); if sbd.mmio[id].memory.is_null() { None @@ -81,7 +91,7 @@ fn mmio_map(&self, id: u32, addr: u64) { assert!(bql_locked()); let id: i32 = id.try_into().unwrap(); unsafe { - bindings::sysbus_mmio_map(self.as_mut_ptr(), id, addr); + bindings::sysbus_mmio_map(self.upcast().as_mut_ptr(), id, addr); } } @@ -93,7 +103,7 @@ fn connect_irq(&self, id: u32, irq: &Owned) { let id: i32 = id.try_into().unwrap(); let irq: &IRQState = irq; unsafe { - bindings::sysbus_connect_irq(self.as_mut_ptr(), id, irq.as_mut_ptr()); + bindings::sysbus_connect_irq(self.upcast().as_mut_ptr(), id, irq.as_mut_ptr()); } } @@ -101,7 +111,10 @@ fn sysbus_realize(&self) { // TODO: return an Error assert!(bql_locked()); unsafe { - bindings::sysbus_realize(self.as_mut_ptr(), addr_of_mut!(bindings::error_fatal)); + bindings::sysbus_realize( + self.upcast().as_mut_ptr(), + addr_of_mut!(bindings::error_fatal), + ); } } } From patchwork Sun Mar 9 10:31:07 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008294 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9C937C282D1 for ; Sun, 9 Mar 2025 10:33:34 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDws-00086N-68; Sun, 09 Mar 2025 06:31:58 -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 1trDwq-00085g-BZ for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:56 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwo-00042x-Ld for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:55 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516314; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=S8IXFl1tjzcTpL3RiOm0U3qS7SeRxt+gon+nIrKlE5k=; b=et7PYwuTYJOEFOpUlS1MQ6EYEVZy6jEJ02FgVpMA8IlNiBUe1S5NZA1ZpiBD1pdXxrsmot pNLLT+ZFVUDhHugHsFhpllBwkemNLFo5h+Xlng9frKgftKWMknGyVhy6122VF5aJvdJdwS QCFKtgXZNJC/7s+cNuvUUXNBYNX2RL8= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-86-RRRoSOgCPi-aNM--X11fQQ-1; Sun, 09 Mar 2025 06:31:52 -0400 X-MC-Unique: RRRoSOgCPi-aNM--X11fQQ-1 X-Mimecast-MFC-AGG-ID: RRRoSOgCPi-aNM--X11fQQ_1741516311 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-391425471ddso276396f8f.0 for ; Sun, 09 Mar 2025 03:31:51 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516310; x=1742121110; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=S8IXFl1tjzcTpL3RiOm0U3qS7SeRxt+gon+nIrKlE5k=; b=AtBNfrWAJ1F7smSEUbeXXCDDP/gUHgooaq/mqrl0nHT+uRtuFUEsNNuRrdG5E1mGan fEB1xeHQLY1XW3bhs8GEbiYnguFylaNyqeUgleT0VnRZcMXuiDOOlRc4eYZp6YBExsbA VS/0gDKYZ0hznb+LMJ9D6O/BFRTOXA2sanKhSgAa+q9x+fVXazGbQdsg/saFsA/BfS6g W2T8wrUuQ8U0xrRQMzEK7ZNkqWAt4chPn8RyEIA3QfjKfS9qf/1Sgoz8oAsv6noTRuyO /YSxTAXJJfbkjaLo8SGG7F62vYsXSnykAljLNOzSIHbQDDTH3qipGwdb6eclNqNPnd12 u+8A== X-Gm-Message-State: AOJu0Yw2Pv2HmDFYgdf47SZ00F5O7ZOlrNWOgHy03vlKjJqhENucxvTl XUmD0iY/q39gBllIsIZGtUrXy5aYOVCwrwvGEfZ4GOMZwIIqWC4MRBhdBGNyN919bIYWGtc/5uY bgQgKM6EalM9Dmaz9FnYX5eVBzxFQ8CxAThkchixX6W7N6Jl3xHP8Cj5EE7boZM/VW+VSFum26U zC2xOxyXIOcWhM3/TEEj665dQDI1egZtHpQ7Ayn/E= X-Gm-Gg: ASbGnctMQSVMiU8Rn3kVNRfN3JZ4ZQz+tZdw7vlTDMYZxi+rdaDbGRcT99dzaMzdZrd J+G1p460IA2tn7d+FksrVLn6EbaZ5bsYTnuE3RQSmI66fhdIf+ET1rOGVhJLirbZOwRNxp9RASK cFCp/J5k+SiaeQ1gK4c3TAOdPxAEw7vgxVHe+YdgAPZI99UrnJOIFAL1kZJhjMZVMD+Op00TwJI P5HT6VSn5J7iHVEoSanHSJOM4zvZeEbsl1XHNLPKG1YY+BfEmah7t3CTNgZYmU3QaZv14bshHIV CCxEV2ZT7qY4V17siSs6lw== X-Received: by 2002:a5d:59a8:0:b0:391:2d76:baaa with SMTP id ffacd0b85a97d-39132db1be7mr7390410f8f.46.1741516310313; Sun, 09 Mar 2025 03:31:50 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHMGDQfpoP1jSEc42gXxru/mIgJyHc3uFrRPXfX8vLnbnBb8beohFmnKEXXVsNoq7Z99WuZqw== X-Received: by 2002:a5d:59a8:0:b0:391:2d76:baaa with SMTP id ffacd0b85a97d-39132db1be7mr7390392f8f.46.1741516309796; Sun, 09 Mar 2025 03:31:49 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912c0e1476sm11511766f8f.70.2025.03.09.03.31.48 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:49 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 13/25] rust: memory: wrap MemoryRegion with Opaque<> Date: Sun, 9 Mar 2025 11:31:07 +0100 Message-ID: <20250309103120.1116448-14-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 3 --- rust/qemu-api/src/memory.rs | 35 +++++++++++++++++++++-------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index b791ca6d87f..26cc8de0cf2 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -34,9 +34,6 @@ unsafe impl Sync for CharBackend {} unsafe impl Send for Chardev {} unsafe impl Sync for Chardev {} -unsafe impl Send for MemoryRegion {} -unsafe impl Sync for MemoryRegion {} - unsafe impl Send for ObjectClass {} unsafe impl Sync for ObjectClass {} diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs index 713c494ca2e..eff9f09fd7f 100644 --- a/rust/qemu-api/src/memory.rs +++ b/rust/qemu-api/src/memory.rs @@ -6,9 +6,8 @@ use std::{ ffi::{CStr, CString}, - marker::{PhantomData, PhantomPinned}, + marker::PhantomData, os::raw::{c_uint, c_void}, - ptr::addr_of, }; pub use bindings::{hwaddr, MemTxAttrs}; @@ -16,6 +15,7 @@ use crate::{ bindings::{self, device_endian, memory_region_init_io}, callbacks::FnCall, + cell::Opaque, prelude::*, zeroable::Zeroable, }; @@ -132,13 +132,13 @@ fn default() -> Self { } } -/// A safe wrapper around [`bindings::MemoryRegion`]. Compared to the -/// underlying C struct it is marked as pinned because the QOM tree -/// contains a pointer to it. -pub struct MemoryRegion { - inner: bindings::MemoryRegion, - _pin: PhantomPinned, -} +/// A safe wrapper around [`bindings::MemoryRegion`]. +#[repr(transparent)] +#[derive(qemu_api_macros::Wrapper)] +pub struct MemoryRegion(Opaque); + +unsafe impl Send for MemoryRegion {} +unsafe impl Sync for MemoryRegion {} impl MemoryRegion { // inline to ensure that it is not included in tests, which only @@ -174,13 +174,20 @@ pub fn init_io>( size: u64, ) { unsafe { - Self::do_init_io(&mut self.inner, owner.cast::(), &ops.0, name, size); + Self::do_init_io( + // self.0.as_mut_ptr() needed because Rust tries to call + // ObjectDeref::as_mut_ptr() on "&mut Self", instead of coercing + // to "&Self" and then calling MemoryRegion::as_mut_ptr(). + // Revisit if/when ObjectCastMut is not needed anymore; it is + // only used in a couple places for initialization. + self.0.as_mut_ptr(), + owner.cast::(), + &ops.0, + name, + size, + ); } } - - pub(crate) const fn as_mut_ptr(&self) -> *mut bindings::MemoryRegion { - addr_of!(self.inner) as *mut _ - } } unsafe impl ObjectType for MemoryRegion { From patchwork Sun Mar 9 10:31:08 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008286 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 58EB7C282D1 for ; Sun, 9 Mar 2025 10:32:44 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDwu-00086m-Ic; Sun, 09 Mar 2025 06:32:00 -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 1trDwr-00086C-JJ for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:57 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwq-00043D-2T for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:57 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516315; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=vQFYgL5OvkIroXqJVu4wnMdYvtwWSlXNwP+wGqmQy7o=; b=cEZZK01HQAeUVcF1MIbpY3PXmN5cYC8O0PRinTqpBGHxkirgM8bytihkkhnuaaJSUJu/+3 D+G99tJ2Brx6b+lKibgkOG/S97pBVQJWgY/uSouIt/6nlN+UlMLyunlUNgDvFAHC/Vk3sK RfKe2MenTl5n+R+AMhwgq9Q6ClegCUQ= Received: from mail-wr1-f69.google.com (mail-wr1-f69.google.com [209.85.221.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-694-sgc4Zv6PM--BMi1USbMh-w-1; Sun, 09 Mar 2025 06:31:53 -0400 X-MC-Unique: sgc4Zv6PM--BMi1USbMh-w-1 X-Mimecast-MFC-AGG-ID: sgc4Zv6PM--BMi1USbMh-w_1741516313 Received: by mail-wr1-f69.google.com with SMTP id ffacd0b85a97d-39131851046so869601f8f.0 for ; Sun, 09 Mar 2025 03:31:53 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516312; x=1742121112; 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=vQFYgL5OvkIroXqJVu4wnMdYvtwWSlXNwP+wGqmQy7o=; b=C90L4imPSNubAsmJg0DdPCN/Kc64qWsztAfhE3LelRuZGyk4nCedut3HQJIuulvw8j 0gx8/jMR6ReHNnOvaIBFefvCEITW1CTBH3+sUxvLJ5c7ytrq+kxJrnEt6FLHSBHYj6Rg 9Q2dV593bU4NHfpOV+RMoAHdo7moanpGBq9OP7FWoF15ivPshzlxCf3e77VDL33LSwFd 6pSdupcezclvIZBhTTGjIZ2ICPy66U+VXm14DmSBZ9j3MBw44hR9Cod2+whE4KUoKuCG Qg0CG+0hz/l+aw3sWE+GD/UYubjcNyYieljoS+mZbRQ8r5sfdp1Slb8i4Y8EpvYixGjJ 6Jxg== X-Gm-Message-State: AOJu0YwdFmC3vSxalMTtLrN3o8SYx1VTC4zMeVJrhwHgOV6c6bmJS5iM jGioX+UBnel/qGyTJbQEF9Bp/1vyWNDuVVF0ePKo+X3EFkgywnKq6Oj6Ueb4gvGdAR1LgdbvZwe 8EP84uq+Hh1G71vzm84JX1QkTmEuH6mqVvM+UDzjq9WvGBrLUsYJwyLVZ9g530pN/iT/2kwrs1S JhVBXjSnXmrGhpToLi3nyhCuzp6gD6xdMCE5UBAi8= X-Gm-Gg: ASbGnculxDF4kBioIXQmjOp2yrvuR/KOfD3RhSHnlqdk/igoXaB/VvbqmtzZFPKWjho dSrfXqtjr92Cjk0y7x08iP8vV1dDTRV9vleoJPUnygBt6LzSvIV4JLAJ3S0Qf7D1se+MuNLOzQA l7F6c20CVSIXSnlxi3HoE92jKq0oC6y1efcMzLaZ0QTUexrZrAoNtQxDKbNVv6tvUFWUxLF/C3w vWRCrIHcdJ6QTZYWUnuvt1oN7qBYL+fYlrXOWZ7pVJVF/VFJserVVfw35lOS4f7dBOwtipmoGDr 6nUAEcfAny+KrxVT9ZX2wA== X-Received: by 2002:a5d:64c7:0:b0:38f:2856:7d96 with SMTP id ffacd0b85a97d-39132d05fdcmr5696771f8f.1.1741516311977; Sun, 09 Mar 2025 03:31:51 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHCO6TT+AKB+eZ9XjXxviPBqg8zAPsrPqdDOO+q5CXmhHGGaBLNxE1LLFkxshKbXCOnraZSUw== X-Received: by 2002:a5d:64c7:0:b0:38f:2856:7d96 with SMTP id ffacd0b85a97d-39132d05fdcmr5696759f8f.1.1741516311565; Sun, 09 Mar 2025 03:31:51 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912c01cd62sm11289481f8f.46.2025.03.09.03.31.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:50 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 14/25] rust: chardev: wrap Chardev with Opaque<> Date: Sun, 9 Mar 2025 11:31:08 +0100 Message-ID: <20250309103120.1116448-15-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 3 --- rust/qemu-api/src/chardev.rs | 8 ++++++-- rust/qemu-api/src/qdev.rs | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index 26cc8de0cf2..c3f36108bd5 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -31,9 +31,6 @@ unsafe impl Sync for BusState {} unsafe impl Send for CharBackend {} unsafe impl Sync for CharBackend {} -unsafe impl Send for Chardev {} -unsafe impl Sync for Chardev {} - unsafe impl Send for ObjectClass {} unsafe impl Sync for ObjectClass {} diff --git a/rust/qemu-api/src/chardev.rs b/rust/qemu-api/src/chardev.rs index 74cfb634e5f..a35b9217e90 100644 --- a/rust/qemu-api/src/chardev.rs +++ b/rust/qemu-api/src/chardev.rs @@ -6,9 +6,13 @@ use std::ffi::CStr; -use crate::{bindings, prelude::*}; +use crate::{bindings, cell::Opaque, prelude::*}; + +/// A safe wrapper around [`bindings::Chardev`]. +#[repr(transparent)] +#[derive(qemu_api_macros::Wrapper)] +pub struct Chardev(Opaque); -pub type Chardev = bindings::Chardev; pub type ChardevClass = bindings::ChardevClass; unsafe impl ObjectType for Chardev { diff --git a/rust/qemu-api/src/qdev.rs b/rust/qemu-api/src/qdev.rs index 1c4a67b5728..18b4a9ba687 100644 --- a/rust/qemu-api/src/qdev.rs +++ b/rust/qemu-api/src/qdev.rs @@ -334,6 +334,7 @@ fn init_clock_out(&self, name: &str) -> Owned { fn prop_set_chr(&self, propname: &str, chr: &Owned) { assert!(bql_locked()); let c_propname = CString::new(propname).unwrap(); + let chr: &Chardev = chr; unsafe { bindings::qdev_prop_set_chr( self.upcast().as_mut_ptr(), From patchwork Sun Mar 9 10:31:09 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008291 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id C3F9CC282D1 for ; Sun, 9 Mar 2025 10:33:14 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDx7-0008RZ-Uo; Sun, 09 Mar 2025 06:32:14 -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 1trDwt-00086a-JV for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:59 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDws-00043Q-0I for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:31:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516317; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=5YnANE3o7k98qiD5yXSXBYpiijAd3VVlrkAgduC094U=; b=dfJTURuOs89YqsVJrFB52UxDLctHezqwIVaQWNDf6x+qIKllj6x2lnXdlBs57UgfTk9bfI jjjxXKwKp40ECltyR+2sKw7gqSuymwtsVj6OMrIuKQP/J/1e7maROVQV0D9kSL7HfS/hcT +aV1cQbqv3XJCSuhs5KUyduHIYMvXCc= Received: from mail-wm1-f71.google.com (mail-wm1-f71.google.com [209.85.128.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-696-rn5ZKZZqOAS4u09LVGV24g-1; Sun, 09 Mar 2025 06:31:55 -0400 X-MC-Unique: rn5ZKZZqOAS4u09LVGV24g-1 X-Mimecast-MFC-AGG-ID: rn5ZKZZqOAS4u09LVGV24g_1741516315 Received: by mail-wm1-f71.google.com with SMTP id 5b1f17b1804b1-43cf3168b87so1391415e9.2 for ; Sun, 09 Mar 2025 03:31:55 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516314; x=1742121114; 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=5YnANE3o7k98qiD5yXSXBYpiijAd3VVlrkAgduC094U=; b=AyC9HJ6nofTy3LWp0modTndsl+vLWAdKms9J11NgA8+9/GKUPA0LzuSCRK2Nkms9u/ n68O9VvsTx5cmYh+c5bIrtUFAGdpKRZvzkVncb50YVoEntZrm+fBoWzGPnWu27hOWQFZ ZdvjzYDCyVYYFkymTvS7P9KvcoBFr8Mm8DSF8lE8OjvHH8K/0fYcfzYcUWf6SZ02v13b hi1DgROiPYfUvv+2+xB4XiRfKphf1yvKWuoUEIrAEIw0ht4GwtAJ7kmq9upvI4Xp+AaO PR6i54jzK08x3OCWTWR2AkmtMZKmeS9+K9MTJmslqJlqdBdD9IWrThv8ed5wy3eeQzI7 5OEg== X-Gm-Message-State: AOJu0YyO2iZoRaD+orOKcdlHvC/rIDxjSdMo+gvozMe81E6Mo+cPN898 1o6pfJ9nzCbLA3GlXcQKcHS9ViGQRlSpmwitWln3AoY7Opo9z4SPsRJ/SSztmSRnJ5hnUPC7aCB q4uqLl1K86zXFBH/ps7tLHG1uwHej1JOSztNHtlrx2GziAGhFOeyY3uHAjAAp7FLnOquQ54P9NC E1vQoPgNYPy3UpoTTUSfNTUZi17XuGVqardruEbAE= X-Gm-Gg: ASbGnctoZmFCAfif5qEhdMNnCi5A9XjPCySMf0LbaRcbqz8slmXpIP0a2KljgMzxvfU uHCi83hiUd20lH3sG7fQwQG4ZVA4715jNJVnIYEUWV1+2mplsYM7wd9HpXo8llJucDmn5c60bDV hVuy1naMVQEq2svT/j6VcaGth0OTnV3XK6nUf8UFiyMe84Fk7vJ9SASlyDfvuMgxKq/vpiOgty1 GZxJAlTt2eqjkupDP+lbCFjxjgU2hQ1UUvtQMff3ohXvJN/reyMAMxCf75IYQ+b1UWWP1X+1du6 vtlTyJ5SxlBb1uIBkNjsow== X-Received: by 2002:a05:600c:6b0a:b0:43c:e9d0:9ee5 with SMTP id 5b1f17b1804b1-43ce9d0a0bfmr25891325e9.18.1741516314299; Sun, 09 Mar 2025 03:31:54 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFuhYqMLwd298dkGxipeo3Le4223qTSDe1Lu0xFlNfgDEENkxnCjfhfsI5bwlscAzlO2BdTew== X-Received: by 2002:a05:600c:6b0a:b0:43c:e9d0:9ee5 with SMTP id 5b1f17b1804b1-43ce9d0a0bfmr25891175e9.18.1741516313858; Sun, 09 Mar 2025 03:31:53 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43cf1b36d14sm17827475e9.37.2025.03.09.03.31.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:52 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 15/25] rust: bindings: remove more unnecessary Send/Sync impls Date: Sun, 9 Mar 2025 11:31:09 +0100 Message-ID: <20250309103120.1116448-16-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Send and Sync are now implemented on the opaque wrappers. Remove them from the bindings module, unless the structs are pure data containers and/or have no C functions defined on them. Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/bindings.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/rust/qemu-api/src/bindings.rs b/rust/qemu-api/src/bindings.rs index c3f36108bd5..3c1d297581e 100644 --- a/rust/qemu-api/src/bindings.rs +++ b/rust/qemu-api/src/bindings.rs @@ -25,15 +25,11 @@ // SAFETY: these are implemented in C; the bindings need to assert that the // BQL is taken, either directly or via `BqlCell` and `BqlRefCell`. -unsafe impl Send for BusState {} -unsafe impl Sync for BusState {} - +// When bindings for character devices are introduced, this can be +// moved to the Opaque<> wrapper in src/chardev.rs. unsafe impl Send for CharBackend {} unsafe impl Sync for CharBackend {} -unsafe impl Send for ObjectClass {} -unsafe impl Sync for ObjectClass {} - // SAFETY: this is a pure data struct unsafe impl Send for CoalescedMemoryRange {} unsafe impl Sync for CoalescedMemoryRange {} From patchwork Sun Mar 9 10:31:10 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008300 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1C2AEC28B2E for ; Sun, 9 Mar 2025 10:34:18 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDx6-0008Ok-RV; Sun, 09 Mar 2025 06:32:13 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwx-0008AU-5z for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:04 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwu-00043p-LB for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:02 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516320; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=X6mhZ60j81W24GLpu0Kz4HHiix+PtR6lsoSKDnwJfGI=; b=MMkrTM/5HHiJ+a87rpt4UN92DsaKq9Uj6Oa8ChLqUrkFHPijA1bQOwJpsE0LobY4x5+tWM VQbKvGtAlIeDB1pCbIId1H3g8ZGGBFsVThLmcJD9eXZS/CYxx7oOzzvnuGcb/P1c8TWMv0 gBh2j1jw3fiB7A52S8dHORwMAauZq5k= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-154-FqHsJ4UyO6uxHSszynNXaQ-1; Sun, 09 Mar 2025 06:31:58 -0400 X-MC-Unique: FqHsJ4UyO6uxHSszynNXaQ-1 X-Mimecast-MFC-AGG-ID: FqHsJ4UyO6uxHSszynNXaQ_1741516317 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-39131851046so869609f8f.0 for ; Sun, 09 Mar 2025 03:31:57 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516316; x=1742121116; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=X6mhZ60j81W24GLpu0Kz4HHiix+PtR6lsoSKDnwJfGI=; b=ZqRVIPuyK4XU7nOfgrmws/8nx7me6RHFwGZamlqtItCFQh76kwv81m8+scY9dUGnim twsAFexFg/H0rXi8AlYcVTFsxISuAM/1yN7RT0oF/e3Vf5nmlFLZoZxi8SyKINv4zTX5 refUSKpKEkyLPGNit/O79ZXf8MEWfh4c8gVctixBIPAOITb93aKhiwY3OoQcUFPAQOqQ rIvDskwRvTq0rdPfs2fKjcpvDmPXxYr45eQAVX6pmoQcvw8bzXOCg9qFUHGIBajnBIdS 5Y5wiWwKARMJRyvTM1QbXaTJikEIlESwFNJ4351uR9V53Qk7I7Vl7go12oTQUfMZTPT4 b/tA== X-Gm-Message-State: AOJu0YyirmjObcXT7SIyJIHPoBAOleps2xzXa3a6qPUXLun9Xdeo4eV5 YFWbxwq4PPds+uWIkJu3TYx6YW9TBowf5xuIGKhsAs9Sg3IE6PN8D/4RLCfx7doyaHYjNW4bOHQ Yo4C4e0PDdSzFfZOQRidkE8REq2DTusqi7KE9COL+Ue05Bsqzp5DO+WJVoJMy+RxxejYPoBnM/5 1AXOvxCmmYhyNhu2ZkdUEXwDo9/RjHXXE5lf1TN1w= X-Gm-Gg: ASbGnctm9N7xTJ0dJ/UdUzyMlCVO4YubbJzpPXLhKfoRZyA6mfFqN90e0609SVhC6VD O10HEgyEd04y6MQWDMm1nusCO2BqxGr/r4Btg0/Vb/k7aA4pYNmBA+AnsR+AnOgoHsxPtvje/+X SYRfZjdgLvTc2g6wt5JpWJ1VFzeXIkPxeMi1PMX6RqEj+6CWX81ojSoMyZG0FXu9POHBGhOt7s5 u7E8IgTO5EI3UzqwLn0eOcXF8EDjnjmT1W4ywv81ogIY13MRmz+8kwTF/2XgvTGwKgGXN6bHVs4 udKmh1sbFm5qZY4K9EJXaw== X-Received: by 2002:adf:8b97:0:b0:391:42f2:5c7b with SMTP id ffacd0b85a97d-39142f25d2emr1203125f8f.16.1741516316148; Sun, 09 Mar 2025 03:31:56 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGh85U/SxwTSwKIMrw3PXpjjcNN7o8n2e2VcD9C/kRZaBcMNt3wcPnoFYD97FHkSIc4XlS/Rg== X-Received: by 2002:adf:8b97:0:b0:391:42f2:5c7b with SMTP id ffacd0b85a97d-39142f25d2emr1203102f8f.16.1741516315587; Sun, 09 Mar 2025 03:31:55 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912bfdfdb9sm11401560f8f.27.2025.03.09.03.31.54 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:54 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 16/25] rust: chardev: provide basic bindings to character devices Date: Sun, 9 Mar 2025 11:31:10 +0100 Message-ID: <20250309103120.1116448-17-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Most of the character device API is pretty simple, with "0 or -errno" or "number of bytes or -errno" as the convention for return codes. Add safe wrappers for the API to the CharBackend bindgen-generated struct. The API is not complete, but it covers the parts that are used by the PL011 device, plus qemu_chr_fe_write which is needed to implement the standard library Write trait. Signed-off-by: Paolo Bonzini --- rust/qemu-api/meson.build | 17 ++- rust/qemu-api/src/chardev.rs | 242 +++++++++++++++++++++++++++++++++- rust/qemu-api/src/zeroable.rs | 1 + 3 files changed, 255 insertions(+), 5 deletions(-) diff --git a/rust/qemu-api/meson.build b/rust/qemu-api/meson.build index 6e52c4bad74..a3f226ccc2a 100644 --- a/rust/qemu-api/meson.build +++ b/rust/qemu-api/meson.build @@ -54,7 +54,19 @@ qemu_api = declare_dependency(link_with: _qemu_api_rs) rust_qemu_api_objs = static_library( 'rust_qemu_api_objs', objects: [libqom.extract_all_objects(recursive: false), - libhwcore.extract_all_objects(recursive: false)]) + libhwcore.extract_all_objects(recursive: false), + libchardev.extract_all_objects(recursive: false), + libcrypto.extract_all_objects(recursive: false), + libauthz.extract_all_objects(recursive: false), + libio.extract_all_objects(recursive: false)]) +rust_qemu_api_deps = declare_dependency( + dependencies: [ + qom_ss.dependencies(), + chardev_ss.dependencies(), + crypto_ss.dependencies(), + authz_ss.dependencies(), + io_ss.dependencies()], + link_whole: [rust_qemu_api_objs, libqemuutil]) test('rust-qemu-api-integration', executable( @@ -63,8 +75,7 @@ test('rust-qemu-api-integration', override_options: ['rust_std=2021', 'build.rust_std=2021'], rust_args: ['--test'], install: false, - dependencies: [qemu_api, qemu_api_macros], - link_whole: [rust_qemu_api_objs, libqemuutil]), + dependencies: [qemu_api, qemu_api_macros, rust_qemu_api_deps]), args: [ '--test', '--test-threads', '1', '--format', 'pretty', diff --git a/rust/qemu-api/src/chardev.rs b/rust/qemu-api/src/chardev.rs index a35b9217e90..11e6c45afaf 100644 --- a/rust/qemu-api/src/chardev.rs +++ b/rust/qemu-api/src/chardev.rs @@ -3,10 +3,28 @@ // SPDX-License-Identifier: GPL-2.0-or-later //! Bindings for character devices +//! +//! Character devices in QEMU can run under the big QEMU lock or in a separate +//! `GMainContext`. Here we only support the former, because the bindings +//! enforce that the BQL is taken whenever the functions in [`CharBackend`] are +//! called. -use std::ffi::CStr; +use std::{ + ffi::CStr, + fmt::{self, Debug}, + io::{self, ErrorKind, Write}, + marker::PhantomPinned, + os::raw::{c_int, c_void}, + ptr::addr_of_mut, + slice, +}; -use crate::{bindings, cell::Opaque, prelude::*}; +use crate::{ + bindings, + callbacks::FnCall, + cell::{BqlRefMut, Opaque}, + prelude::*, +}; /// A safe wrapper around [`bindings::Chardev`]. #[repr(transparent)] @@ -14,6 +32,226 @@ pub struct Chardev(Opaque); pub type ChardevClass = bindings::ChardevClass; +pub type Event = bindings::QEMUChrEvent; + +/// A safe wrapper around [`bindings::CharBackend`], denoting the character +/// back-end that is used for example by a device. Compared to the +/// underlying C struct it adds BQL protection, and is marked as pinned +/// because the QOM object ([`bindings::Chardev`]) contains a pointer to +/// the `CharBackend`. +pub struct CharBackend { + inner: BqlRefCell, + _pin: PhantomPinned, +} + +impl Write for BqlRefMut<'_, bindings::CharBackend> { + fn flush(&mut self) -> io::Result<()> { + Ok(()) + } + + fn write(&mut self, buf: &[u8]) -> io::Result { + let chr: &mut bindings::CharBackend = self; + + let len = buf.len().try_into().unwrap(); + let r = unsafe { bindings::qemu_chr_fe_write(addr_of_mut!(*chr), buf.as_ptr(), len) }; + errno::into_io_result(r).map(|cnt| cnt as usize) + } + + fn write_all(&mut self, buf: &[u8]) -> io::Result<()> { + let chr: &mut bindings::CharBackend = self; + + let len = buf.len().try_into().unwrap(); + let r = unsafe { bindings::qemu_chr_fe_write_all(addr_of_mut!(*chr), buf.as_ptr(), len) }; + errno::into_io_result(r).and_then(|cnt| { + if cnt as usize == buf.len() { + Ok(()) + } else { + Err(ErrorKind::WriteZero.into()) + } + }) + } +} + +impl Debug for CharBackend { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + // SAFETY: accessed just to print the values + let chr = self.inner.as_ptr(); + Debug::fmt(unsafe { &*chr }, f) + } +} + +// FIXME: use something like PinnedDrop from the pinned_init crate +impl Drop for CharBackend { + fn drop(&mut self) { + self.disable_handlers(); + } +} + +impl CharBackend { + /// Enable the front-end's character device handlers, if there is an + /// associated `Chardev`. + pub fn enable_handlers< + 'chardev, + 'owner: 'chardev, + T, + CanReceiveFn: for<'a> FnCall<(&'a T,), u32>, + ReceiveFn: for<'a, 'b> FnCall<(&'a T, &'b [u8])>, + EventFn: for<'a> FnCall<(&'a T, Event)>, + >( + // When "self" is dropped, the handlers are automatically disabled. + // However, this is not necessarily true if the owner is dropped. + // So require the owner to outlive the character device. + &'chardev self, + owner: &'owner T, + _can_receive: CanReceiveFn, + _receive: ReceiveFn, + _event: EventFn, + ) { + unsafe extern "C" fn rust_can_receive_cb FnCall<(&'a T,), u32>>( + opaque: *mut c_void, + ) -> c_int { + // SAFETY: the values are safe according to the contract of + // enable_handlers() and qemu_chr_fe_set_handlers() + let owner: &T = unsafe { &*(opaque.cast::()) }; + let r = F::call((owner,)); + r.try_into().unwrap() + } + + unsafe extern "C" fn rust_receive_cb FnCall<(&'a T, &'b [u8])>>( + opaque: *mut c_void, + buf: *const u8, + size: c_int, + ) { + // SAFETY: the values are safe according to the contract of + // enable_handlers() and qemu_chr_fe_set_handlers() + let owner: &T = unsafe { &*(opaque.cast::()) }; + let buf = unsafe { slice::from_raw_parts(buf, size.try_into().unwrap()) }; + F::call((owner, buf)) + } + + unsafe extern "C" fn rust_event_cb FnCall<(&'a T, Event)>>( + opaque: *mut c_void, + event: Event, + ) { + // SAFETY: the values are safe according to the contract of + // enable_handlers() and qemu_chr_fe_set_handlers() + let owner: &T = unsafe { &*(opaque.cast::()) }; + F::call((owner, event)) + } + + let _: () = CanReceiveFn::ASSERT_IS_SOME; + let receive_cb: Option = + if ReceiveFn::is_some() { + Some(rust_receive_cb::) + } else { + None + }; + let event_cb: Option = if EventFn::is_some() { + Some(rust_event_cb::) + } else { + None + }; + + let mut chr = self.inner.borrow_mut(); + // SAFETY: the borrow promises that the BQL is taken + unsafe { + bindings::qemu_chr_fe_set_handlers( + addr_of_mut!(*chr), + Some(rust_can_receive_cb::), + receive_cb, + event_cb, + None, + (owner as *const T as *mut T).cast::(), + core::ptr::null_mut(), + true, + ); + } + } + + /// Disable the front-end's character device handlers. + pub fn disable_handlers(&self) { + let mut chr = self.inner.borrow_mut(); + // SAFETY: the borrow promises that the BQL is taken + unsafe { + bindings::qemu_chr_fe_set_handlers( + addr_of_mut!(*chr), + None, + None, + None, + None, + core::ptr::null_mut(), + core::ptr::null_mut(), + true, + ); + } + } + + /// Notify that the frontend is ready to receive data. + pub fn accept_input(&self) { + let mut chr = self.inner.borrow_mut(); + // SAFETY: the borrow promises that the BQL is taken + unsafe { bindings::qemu_chr_fe_accept_input(addr_of_mut!(*chr)) } + } + + /// Temporarily borrow the character device, allowing it to be used + /// as an implementor of `Write`. Note that it is not valid to drop + /// the big QEMU lock while the character device is borrowed, as + /// that might cause C code to write to the character device. + pub fn borrow_mut(&self) -> impl Write + '_ { + self.inner.borrow_mut() + } + + /// Send a continuous stream of zero bits on the line if `enabled` is + /// true, or a short stream if `enabled` is false. + pub fn send_break(&self, long: bool) -> io::Result<()> { + let mut chr = self.inner.borrow_mut(); + let mut duration: c_int = long.into(); + // SAFETY: the borrow promises that the BQL is taken + let r = unsafe { + bindings::qemu_chr_fe_ioctl( + addr_of_mut!(*chr), + bindings::CHR_IOCTL_SERIAL_SET_BREAK as i32, + addr_of_mut!(duration).cast::(), + ) + }; + + errno::into_io_result(r).map(|_| ()) + } + + /// Write data to a character backend from the front end. This function + /// will send data from the front end to the back end. Unlike + /// `write`, this function will block if the back end cannot + /// consume all of the data attempted to be written. + /// + /// Returns the number of bytes consumed (0 if no associated Chardev) or an + /// error. + pub fn write(&self, buf: &[u8]) -> io::Result { + let len = buf.len().try_into().unwrap(); + // SAFETY: qemu_chr_fe_write is thread-safe + let r = unsafe { bindings::qemu_chr_fe_write(self.inner.as_ptr(), buf.as_ptr(), len) }; + errno::into_io_result(r).map(|cnt| cnt as usize) + } + + /// Write data to a character backend from the front end. This function + /// will send data from the front end to the back end. Unlike + /// `write`, this function will block if the back end cannot + /// consume all of the data attempted to be written. + /// + /// Returns the number of bytes consumed (0 if no associated Chardev) or an + /// error. + pub fn write_all(&self, buf: &[u8]) -> io::Result<()> { + let len = buf.len().try_into().unwrap(); + // SAFETY: qemu_chr_fe_write_all is thread-safe + let r = unsafe { bindings::qemu_chr_fe_write_all(self.inner.as_ptr(), buf.as_ptr(), len) }; + errno::into_io_result(r).and_then(|cnt| { + if cnt as usize == buf.len() { + Ok(()) + } else { + Err(ErrorKind::WriteZero.into()) + } + }) + } +} unsafe impl ObjectType for Chardev { type Class = ChardevClass; diff --git a/rust/qemu-api/src/zeroable.rs b/rust/qemu-api/src/zeroable.rs index 47b6977828d..a3415a2ebcc 100644 --- a/rust/qemu-api/src/zeroable.rs +++ b/rust/qemu-api/src/zeroable.rs @@ -106,3 +106,4 @@ fn default() -> Self { impl_zeroable!(crate::bindings::MemoryRegionOps__bindgen_ty_2); impl_zeroable!(crate::bindings::MemoryRegionOps); impl_zeroable!(crate::bindings::MemTxAttrs); +impl_zeroable!(crate::bindings::CharBackend); From patchwork Sun Mar 9 10:31:11 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008287 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 94DD8C28B28 for ; Sun, 9 Mar 2025 10:32:47 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDx9-0008Vv-8m; Sun, 09 Mar 2025 06:32:15 -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 1trDx5-0008Mo-Gu for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:12 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDx0-00044Y-RD for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:11 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516325; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=aQdYkLvG/kXL2x3jf6uWXJB1T4NSBqUoJeieljteXgw=; b=h0mw/TFSURGeh+lKDzCRB2bquHVX0SR0OfXHiJQyrogSkgxiHFdP4Ml5dAvXeuXEaTVU9+ 2NADLhdrkpY0mmFN+GA4SJxoODuhRW8/lROhSTZeu3hrJGagzkPsmyCemTkGuAV/7C1+cc M8dSTNmqBuK4DFRsPG57GEZx1HHtZ84= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-444-q_3PmCK6MK2P9Pe_LXWX0Q-1; Sun, 09 Mar 2025 06:32:02 -0400 X-MC-Unique: q_3PmCK6MK2P9Pe_LXWX0Q-1 X-Mimecast-MFC-AGG-ID: q_3PmCK6MK2P9Pe_LXWX0Q_1741516321 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43ce245c5acso10039805e9.2 for ; Sun, 09 Mar 2025 03:32:02 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516320; x=1742121120; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=aQdYkLvG/kXL2x3jf6uWXJB1T4NSBqUoJeieljteXgw=; b=NN/XMAy0bz9fwJ1EDoYyQK+AiSZxWJt4FMX4dCXtvXkYzhhMKAkHqMQ8FM8kK2rYOF v/eLqPJvOXjSqc6EzHWefejp0MxI0bIUdqPtQTkujR2l/tIrU/7AJLei0Drf6Izzqz7w m1F983oidUuQUGkdQab0AQmXsuwoUMGWuP7WVqbJVwLfSenjbKb6e3XSZrpL6lH3aLvN HFTzEwlV8EBSq9ctO9JZcfez9kN5w/+njTEMH0gums4dSN8xaGbjn1AnrDGz3F8BeEoi IO/lkXmGTiolO+WZFqXxftgo9FKoytqsYU5JTkNirSv9JIBmcTPc68cq5Txw5jpiPgtq SKYA== X-Gm-Message-State: AOJu0Yz4gF991VDBoZe5HX8Ls+Y9bgDSqvu5+iQLs5jUtSToxuXuM+6/ XZ9gOpkVY1Ws3BR0owl6LQ1kU8trVhbTpff2cfLOAqOmHuEpxNBpTomgB6ORwHi0wd+Rw824+nE Cb8C37zjlDzPkQv1XlKgPwjBt4hQmwWZegAMiCFy6Je6eUDW8NUcjcPjTt0nPqz9TdP/rvak9+o 78+SDKHh15m4e5oO+VqrPSosJOYJMl5FB0zcS3pa4= X-Gm-Gg: ASbGncs+gVhETgBQlTQLq/SyYAFvf8v6S5xUV4cA9sFbY7zQevqjbNrZypQfm7QdHHc eC5OSWAK8t/iZbQzliTfUFKi92FC+XdLDCZx2K0A7CN/lyUbfROxG2bNCkTXkhKFyq5hN7OWN3P cVrbTzg65zjz6EHCtn6RSbn/xydDCFTtKl4dLJJU+LG1i24wRzSPcDo4rS0BBhlMvwBl6KGpMs6 eJ05la5Pv15x+ZHKOwnWZ861COJOGHuFJPKOC0/aJFUGOE4cSanms/BCjmwvBFJArNFSH2L/Y4c u0Yxe938w+U8DIlk34+wqA== X-Received: by 2002:a05:600c:35d3:b0:43c:f1cd:3d78 with SMTP id 5b1f17b1804b1-43cf1cd3ecbmr8101125e9.12.1741516319606; Sun, 09 Mar 2025 03:31:59 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFDM4e3z41aCAyz/8K3Nw5w+1t4ZoENoEPL5+Uk/xeRafLGvj5VF5oWAin9CWgC9Rj+hDUJkg== X-Received: by 2002:a05:600c:35d3:b0:43c:f1cd:3d78 with SMTP id 5b1f17b1804b1-43cf1cd3ecbmr8100615e9.12.1741516317566; Sun, 09 Mar 2025 03:31:57 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912bfba679sm11351700f8f.8.2025.03.09.03.31.56 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:56 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 17/25] rust: pl011: move register definitions out of lib.rs Date: Sun, 9 Mar 2025 11:31:11 +0100 Message-ID: <20250309103120.1116448-18-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 7 +- rust/hw/char/pl011/src/lib.rs | 509 +--------------------------- rust/hw/char/pl011/src/registers.rs | 506 +++++++++++++++++++++++++++ 3 files changed, 512 insertions(+), 510 deletions(-) create mode 100644 rust/hw/char/pl011/src/registers.rs diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index d0857b470c9..01540654cc9 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -26,10 +26,13 @@ use crate::{ device_class, - registers::{self, Interrupt}, - RegisterOffset, + registers::{self, Interrupt, RegisterOffset}, }; +// TODO: You must disable the UART before any of the control registers are +// reprogrammed. When the UART is disabled in the middle of transmission or +// reception, it completes the current character before stopping + /// Integer Baud Rate Divider, `UARTIBRD` const IBRD_MASK: u32 = 0xffff; diff --git a/rust/hw/char/pl011/src/lib.rs b/rust/hw/char/pl011/src/lib.rs index 1bf46c65af2..45c13ba899e 100644 --- a/rust/hw/char/pl011/src/lib.rs +++ b/rust/hw/char/pl011/src/lib.rs @@ -18,516 +18,9 @@ mod device; mod device_class; +mod registers; pub use device::pl011_create; pub const TYPE_PL011: &::std::ffi::CStr = c_str!("pl011"); pub const TYPE_PL011_LUMINARY: &::std::ffi::CStr = c_str!("pl011_luminary"); - -/// Offset of each register from the base memory address of the device. -/// -/// # Source -/// ARM DDI 0183G, Table 3-1 p.3-3 -#[doc(alias = "offset")] -#[allow(non_camel_case_types)] -#[repr(u64)] -#[derive(Debug, Eq, PartialEq, qemu_api_macros::TryInto)] -enum RegisterOffset { - /// Data Register - /// - /// A write to this register initiates the actual data transmission - #[doc(alias = "UARTDR")] - DR = 0x000, - /// Receive Status Register or Error Clear Register - #[doc(alias = "UARTRSR")] - #[doc(alias = "UARTECR")] - RSR = 0x004, - /// Flag Register - /// - /// A read of this register shows if transmission is complete - #[doc(alias = "UARTFR")] - FR = 0x018, - /// Fractional Baud Rate Register - /// - /// responsible for baud rate speed - #[doc(alias = "UARTFBRD")] - FBRD = 0x028, - /// `IrDA` Low-Power Counter Register - #[doc(alias = "UARTILPR")] - ILPR = 0x020, - /// Integer Baud Rate Register - /// - /// Responsible for baud rate speed - #[doc(alias = "UARTIBRD")] - IBRD = 0x024, - /// line control register (data frame format) - #[doc(alias = "UARTLCR_H")] - LCR_H = 0x02C, - /// Toggle UART, transmission or reception - #[doc(alias = "UARTCR")] - CR = 0x030, - /// Interrupt FIFO Level Select Register - #[doc(alias = "UARTIFLS")] - FLS = 0x034, - /// Interrupt Mask Set/Clear Register - #[doc(alias = "UARTIMSC")] - IMSC = 0x038, - /// Raw Interrupt Status Register - #[doc(alias = "UARTRIS")] - RIS = 0x03C, - /// Masked Interrupt Status Register - #[doc(alias = "UARTMIS")] - MIS = 0x040, - /// Interrupt Clear Register - #[doc(alias = "UARTICR")] - ICR = 0x044, - /// DMA control Register - #[doc(alias = "UARTDMACR")] - DMACR = 0x048, - ///// Reserved, offsets `0x04C` to `0x07C`. - //Reserved = 0x04C, -} - -mod registers { - //! Device registers exposed as typed structs which are backed by arbitrary - //! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc. - use bilge::prelude::*; - use qemu_api::impl_vmstate_bitsized; - - /// Receive Status Register / Data Register common error bits - /// - /// The `UARTRSR` register is updated only when a read occurs - /// from the `UARTDR` register with the same status information - /// that can also be obtained by reading the `UARTDR` register - #[bitsize(8)] - #[derive(Clone, Copy, Default, DebugBits, FromBits)] - pub struct Errors { - pub framing_error: bool, - pub parity_error: bool, - pub break_error: bool, - pub overrun_error: bool, - _reserved_unpredictable: u4, - } - - // TODO: FIFO Mode has different semantics - /// Data Register, `UARTDR` - /// - /// The `UARTDR` register is the data register. - /// - /// For words to be transmitted: - /// - /// - if the FIFOs are enabled, data written to this location is pushed onto - /// the transmit - /// FIFO - /// - if the FIFOs are not enabled, data is stored in the transmitter - /// holding register (the - /// bottom word of the transmit FIFO). - /// - /// The write operation initiates transmission from the UART. The data is - /// prefixed with a start bit, appended with the appropriate parity bit - /// (if parity is enabled), and a stop bit. The resultant word is then - /// transmitted. - /// - /// For received words: - /// - /// - if the FIFOs are enabled, the data byte and the 4-bit status (break, - /// frame, parity, - /// and overrun) is pushed onto the 12-bit wide receive FIFO - /// - if the FIFOs are not enabled, the data byte and status are stored in - /// the receiving - /// holding register (the bottom word of the receive FIFO). - /// - /// The received data byte is read by performing reads from the `UARTDR` - /// register along with the corresponding status information. The status - /// information can also be read by a read of the `UARTRSR/UARTECR` - /// register. - /// - /// # Note - /// - /// You must disable the UART before any of the control registers are - /// reprogrammed. When the UART is disabled in the middle of - /// transmission or reception, it completes the current character before - /// stopping. - /// - /// # Source - /// ARM DDI 0183G 3.3.1 Data Register, UARTDR - #[bitsize(32)] - #[derive(Clone, Copy, Default, DebugBits, FromBits)] - #[doc(alias = "UARTDR")] - pub struct Data { - pub data: u8, - pub errors: Errors, - _reserved: u16, - } - impl_vmstate_bitsized!(Data); - - impl Data { - // bilge is not very const-friendly, unfortunately - pub const BREAK: Self = Self { value: 1 << 10 }; - } - - // TODO: FIFO Mode has different semantics - /// Receive Status Register / Error Clear Register, `UARTRSR/UARTECR` - /// - /// The UARTRSR/UARTECR register is the receive status register/error clear - /// register. Receive status can also be read from the `UARTRSR` - /// register. If the status is read from this register, then the status - /// information for break, framing and parity corresponds to the - /// data character read from the [Data register](Data), `UARTDR` prior to - /// reading the UARTRSR register. The status information for overrun is - /// set immediately when an overrun condition occurs. - /// - /// - /// # Note - /// The received data character must be read first from the [Data - /// Register](Data), `UARTDR` before reading the error status associated - /// with that data character from the `UARTRSR` register. This read - /// sequence cannot be reversed, because the `UARTRSR` register is - /// updated only when a read occurs from the `UARTDR` register. However, - /// the status information can also be obtained by reading the `UARTDR` - /// register - /// - /// # Source - /// ARM DDI 0183G 3.3.2 Receive Status Register/Error Clear Register, - /// UARTRSR/UARTECR - #[bitsize(32)] - #[derive(Clone, Copy, DebugBits, FromBits)] - pub struct ReceiveStatusErrorClear { - pub errors: Errors, - _reserved_unpredictable: u24, - } - impl_vmstate_bitsized!(ReceiveStatusErrorClear); - - impl ReceiveStatusErrorClear { - pub fn set_from_data(&mut self, data: Data) { - self.set_errors(data.errors()); - } - - pub fn reset(&mut self) { - // All the bits are cleared to 0 on reset. - *self = Self::default(); - } - } - - impl Default for ReceiveStatusErrorClear { - fn default() -> Self { - 0.into() - } - } - - #[bitsize(32)] - #[derive(Clone, Copy, DebugBits, FromBits)] - /// Flag Register, `UARTFR` - #[doc(alias = "UARTFR")] - pub struct Flags { - /// CTS Clear to send. This bit is the complement of the UART clear to - /// send, `nUARTCTS`, modem status input. That is, the bit is 1 - /// when `nUARTCTS` is LOW. - pub clear_to_send: bool, - /// DSR Data set ready. This bit is the complement of the UART data set - /// ready, `nUARTDSR`, modem status input. That is, the bit is 1 when - /// `nUARTDSR` is LOW. - pub data_set_ready: bool, - /// DCD Data carrier detect. This bit is the complement of the UART data - /// carrier detect, `nUARTDCD`, modem status input. That is, the bit is - /// 1 when `nUARTDCD` is LOW. - pub data_carrier_detect: bool, - /// BUSY UART busy. If this bit is set to 1, the UART is busy - /// transmitting data. This bit remains set until the complete - /// byte, including all the stop bits, has been sent from the - /// shift register. This bit is set as soon as the transmit FIFO - /// becomes non-empty, regardless of whether the UART is enabled - /// or not. - pub busy: bool, - /// RXFE Receive FIFO empty. The meaning of this bit depends on the - /// state of the FEN bit in the UARTLCR_H register. If the FIFO - /// is disabled, this bit is set when the receive holding - /// register is empty. If the FIFO is enabled, the RXFE bit is - /// set when the receive FIFO is empty. - pub receive_fifo_empty: bool, - /// TXFF Transmit FIFO full. The meaning of this bit depends on the - /// state of the FEN bit in the UARTLCR_H register. If the FIFO - /// is disabled, this bit is set when the transmit holding - /// register is full. If the FIFO is enabled, the TXFF bit is - /// set when the transmit FIFO is full. - pub transmit_fifo_full: bool, - /// RXFF Receive FIFO full. The meaning of this bit depends on the state - /// of the FEN bit in the UARTLCR_H register. If the FIFO is - /// disabled, this bit is set when the receive holding register - /// is full. If the FIFO is enabled, the RXFF bit is set when - /// the receive FIFO is full. - pub receive_fifo_full: bool, - /// Transmit FIFO empty. The meaning of this bit depends on the state of - /// the FEN bit in the [Line Control register](LineControl), - /// `UARTLCR_H`. If the FIFO is disabled, this bit is set when the - /// transmit holding register is empty. If the FIFO is enabled, - /// the TXFE bit is set when the transmit FIFO is empty. This - /// bit does not indicate if there is data in the transmit shift - /// register. - pub transmit_fifo_empty: bool, - /// `RI`, is `true` when `nUARTRI` is `LOW`. - pub ring_indicator: bool, - _reserved_zero_no_modify: u23, - } - impl_vmstate_bitsized!(Flags); - - impl Flags { - pub fn reset(&mut self) { - *self = Self::default(); - } - } - - impl Default for Flags { - fn default() -> Self { - let mut ret: Self = 0.into(); - // After reset TXFF, RXFF, and BUSY are 0, and TXFE and RXFE are 1 - ret.set_receive_fifo_empty(true); - ret.set_transmit_fifo_empty(true); - ret - } - } - - #[bitsize(32)] - #[derive(Clone, Copy, DebugBits, FromBits)] - /// Line Control Register, `UARTLCR_H` - #[doc(alias = "UARTLCR_H")] - pub struct LineControl { - /// BRK Send break. - /// - /// If this bit is set to `1`, a low-level is continually output on the - /// `UARTTXD` output, after completing transmission of the - /// current character. For the proper execution of the break command, - /// the software must set this bit for at least two complete - /// frames. For normal use, this bit must be cleared to `0`. - pub send_break: bool, - /// 1 PEN Parity enable: - /// - /// - 0 = parity is disabled and no parity bit added to the data frame - /// - 1 = parity checking and generation is enabled. - /// - /// See Table 3-11 on page 3-14 for the parity truth table. - pub parity_enabled: bool, - /// EPS Even parity select. Controls the type of parity the UART uses - /// during transmission and reception: - /// - 0 = odd parity. The UART generates or checks for an odd number of - /// 1s in the data and parity bits. - /// - 1 = even parity. The UART generates or checks for an even number - /// of 1s in the data and parity bits. - /// This bit has no effect when the `PEN` bit disables parity checking - /// and generation. See Table 3-11 on page 3-14 for the parity - /// truth table. - pub parity: Parity, - /// 3 STP2 Two stop bits select. If this bit is set to 1, two stop bits - /// are transmitted at the end of the frame. The receive - /// logic does not check for two stop bits being received. - pub two_stops_bits: bool, - /// FEN Enable FIFOs: - /// 0 = FIFOs are disabled (character mode) that is, the FIFOs become - /// 1-byte-deep holding registers 1 = transmit and receive FIFO - /// buffers are enabled (FIFO mode). - pub fifos_enabled: Mode, - /// WLEN Word length. These bits indicate the number of data bits - /// transmitted or received in a frame as follows: b11 = 8 bits - /// b10 = 7 bits - /// b01 = 6 bits - /// b00 = 5 bits. - pub word_length: WordLength, - /// 7 SPS Stick parity select. - /// 0 = stick parity is disabled - /// 1 = either: - /// • if the EPS bit is 0 then the parity bit is transmitted and checked - /// as a 1 • if the EPS bit is 1 then the parity bit is - /// transmitted and checked as a 0. This bit has no effect when - /// the PEN bit disables parity checking and generation. See Table 3-11 - /// on page 3-14 for the parity truth table. - pub sticky_parity: bool, - /// 31:8 - Reserved, do not modify, read as zero. - _reserved_zero_no_modify: u24, - } - impl_vmstate_bitsized!(LineControl); - - impl LineControl { - pub fn reset(&mut self) { - // All the bits are cleared to 0 when reset. - *self = 0.into(); - } - } - - impl Default for LineControl { - fn default() -> Self { - 0.into() - } - } - - #[bitsize(1)] - #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] - /// `EPS` "Even parity select", field of [Line Control - /// register](LineControl). - pub enum Parity { - /// - 0 = odd parity. The UART generates or checks for an odd number of - /// 1s in the data and parity bits. - Odd = 0, - /// - 1 = even parity. The UART generates or checks for an even number - /// of 1s in the data and parity bits. - Even = 1, - } - - #[bitsize(1)] - #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] - /// `FEN` "Enable FIFOs" or Device mode, field of [Line Control - /// register](LineControl). - pub enum Mode { - /// 0 = FIFOs are disabled (character mode) that is, the FIFOs become - /// 1-byte-deep holding registers - Character = 0, - /// 1 = transmit and receive FIFO buffers are enabled (FIFO mode). - FIFO = 1, - } - - #[bitsize(2)] - #[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] - /// `WLEN` Word length, field of [Line Control register](LineControl). - /// - /// These bits indicate the number of data bits transmitted or received in a - /// frame as follows: - pub enum WordLength { - /// b11 = 8 bits - _8Bits = 0b11, - /// b10 = 7 bits - _7Bits = 0b10, - /// b01 = 6 bits - _6Bits = 0b01, - /// b00 = 5 bits. - _5Bits = 0b00, - } - - /// Control Register, `UARTCR` - /// - /// The `UARTCR` register is the control register. All the bits are cleared - /// to `0` on reset except for bits `9` and `8` that are set to `1`. - /// - /// # Source - /// ARM DDI 0183G, 3.3.8 Control Register, `UARTCR`, Table 3-12 - #[bitsize(32)] - #[doc(alias = "UARTCR")] - #[derive(Clone, Copy, DebugBits, FromBits)] - pub struct Control { - /// `UARTEN` UART enable: 0 = UART is disabled. If the UART is disabled - /// in the middle of transmission or reception, it completes the current - /// character before stopping. 1 = the UART is enabled. Data - /// transmission and reception occurs for either UART signals or SIR - /// signals depending on the setting of the SIREN bit. - pub enable_uart: bool, - /// `SIREN` `SIR` enable: 0 = IrDA SIR ENDEC is disabled. `nSIROUT` - /// remains LOW (no light pulse generated), and signal transitions on - /// SIRIN have no effect. 1 = IrDA SIR ENDEC is enabled. Data is - /// transmitted and received on nSIROUT and SIRIN. UARTTXD remains HIGH, - /// in the marking state. Signal transitions on UARTRXD or modem status - /// inputs have no effect. This bit has no effect if the UARTEN bit - /// disables the UART. - pub enable_sir: bool, - /// `SIRLP` SIR low-power IrDA mode. This bit selects the IrDA encoding - /// mode. If this bit is cleared to 0, low-level bits are transmitted as - /// an active high pulse with a width of 3/ 16th of the bit period. If - /// this bit is set to 1, low-level bits are transmitted with a pulse - /// width that is 3 times the period of the IrLPBaud16 input signal, - /// regardless of the selected bit rate. Setting this bit uses less - /// power, but might reduce transmission distances. - pub sir_lowpower_irda_mode: u1, - /// Reserved, do not modify, read as zero. - _reserved_zero_no_modify: u4, - /// `LBE` Loopback enable. If this bit is set to 1 and the SIREN bit is - /// set to 1 and the SIRTEST bit in the Test Control register, UARTTCR - /// on page 4-5 is set to 1, then the nSIROUT path is inverted, and fed - /// through to the SIRIN path. The SIRTEST bit in the test register must - /// be set to 1 to override the normal half-duplex SIR operation. This - /// must be the requirement for accessing the test registers during - /// normal operation, and SIRTEST must be cleared to 0 when loopback - /// testing is finished. This feature reduces the amount of external - /// coupling required during system test. If this bit is set to 1, and - /// the SIRTEST bit is set to 0, the UARTTXD path is fed through to the - /// UARTRXD path. In either SIR mode or UART mode, when this bit is set, - /// the modem outputs are also fed through to the modem inputs. This bit - /// is cleared to 0 on reset, to disable loopback. - pub enable_loopback: bool, - /// `TXE` Transmit enable. If this bit is set to 1, the transmit section - /// of the UART is enabled. Data transmission occurs for either UART - /// signals, or SIR signals depending on the setting of the SIREN bit. - /// When the UART is disabled in the middle of transmission, it - /// completes the current character before stopping. - pub enable_transmit: bool, - /// `RXE` Receive enable. If this bit is set to 1, the receive section - /// of the UART is enabled. Data reception occurs for either UART - /// signals or SIR signals depending on the setting of the SIREN bit. - /// When the UART is disabled in the middle of reception, it completes - /// the current character before stopping. - pub enable_receive: bool, - /// `DTR` Data transmit ready. This bit is the complement of the UART - /// data transmit ready, `nUARTDTR`, modem status output. That is, when - /// the bit is programmed to a 1 then `nUARTDTR` is LOW. - pub data_transmit_ready: bool, - /// `RTS` Request to send. This bit is the complement of the UART - /// request to send, `nUARTRTS`, modem status output. That is, when the - /// bit is programmed to a 1 then `nUARTRTS` is LOW. - pub request_to_send: bool, - /// `Out1` This bit is the complement of the UART Out1 (`nUARTOut1`) - /// modem status output. That is, when the bit is programmed to a 1 the - /// output is 0. For DTE this can be used as Data Carrier Detect (DCD). - pub out_1: bool, - /// `Out2` This bit is the complement of the UART Out2 (`nUARTOut2`) - /// modem status output. That is, when the bit is programmed to a 1, the - /// output is 0. For DTE this can be used as Ring Indicator (RI). - pub out_2: bool, - /// `RTSEn` RTS hardware flow control enable. If this bit is set to 1, - /// RTS hardware flow control is enabled. Data is only requested when - /// there is space in the receive FIFO for it to be received. - pub rts_hardware_flow_control_enable: bool, - /// `CTSEn` CTS hardware flow control enable. If this bit is set to 1, - /// CTS hardware flow control is enabled. Data is only transmitted when - /// the `nUARTCTS` signal is asserted. - pub cts_hardware_flow_control_enable: bool, - /// 31:16 - Reserved, do not modify, read as zero. - _reserved_zero_no_modify2: u16, - } - impl_vmstate_bitsized!(Control); - - impl Control { - pub fn reset(&mut self) { - *self = 0.into(); - self.set_enable_receive(true); - self.set_enable_transmit(true); - } - } - - impl Default for Control { - fn default() -> Self { - let mut ret: Self = 0.into(); - ret.reset(); - ret - } - } - - /// Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC - pub struct Interrupt(pub u32); - - impl Interrupt { - pub const OE: Self = Self(1 << 10); - pub const BE: Self = Self(1 << 9); - pub const PE: Self = Self(1 << 8); - pub const FE: Self = Self(1 << 7); - pub const RT: Self = Self(1 << 6); - pub const TX: Self = Self(1 << 5); - pub const RX: Self = Self(1 << 4); - pub const DSR: Self = Self(1 << 3); - pub const DCD: Self = Self(1 << 2); - pub const CTS: Self = Self(1 << 1); - pub const RI: Self = Self(1 << 0); - - pub const E: Self = Self(Self::OE.0 | Self::BE.0 | Self::PE.0 | Self::FE.0); - pub const MS: Self = Self(Self::RI.0 | Self::DSR.0 | Self::DCD.0 | Self::CTS.0); - } -} - -// TODO: You must disable the UART before any of the control registers are -// reprogrammed. When the UART is disabled in the middle of transmission or -// reception, it completes the current character before stopping diff --git a/rust/hw/char/pl011/src/registers.rs b/rust/hw/char/pl011/src/registers.rs new file mode 100644 index 00000000000..cd92fa2c300 --- /dev/null +++ b/rust/hw/char/pl011/src/registers.rs @@ -0,0 +1,506 @@ +// Copyright 2024, Linaro Limited +// Author(s): Manos Pitsidianakis +// SPDX-License-Identifier: GPL-2.0-or-later + +//! Device registers exposed as typed structs which are backed by arbitrary +//! integer bitmaps. [`Data`], [`Control`], [`LineControl`], etc. + +use bilge::prelude::*; +use qemu_api::impl_vmstate_bitsized; + +/// Offset of each register from the base memory address of the device. +/// +/// # Source +/// ARM DDI 0183G, Table 3-1 p.3-3 +#[doc(alias = "offset")] +#[allow(non_camel_case_types)] +#[repr(u64)] +#[derive(Debug, Eq, PartialEq, qemu_api_macros::TryInto)] +pub enum RegisterOffset { + /// Data Register + /// + /// A write to this register initiates the actual data transmission + #[doc(alias = "UARTDR")] + DR = 0x000, + /// Receive Status Register or Error Clear Register + #[doc(alias = "UARTRSR")] + #[doc(alias = "UARTECR")] + RSR = 0x004, + /// Flag Register + /// + /// A read of this register shows if transmission is complete + #[doc(alias = "UARTFR")] + FR = 0x018, + /// Fractional Baud Rate Register + /// + /// responsible for baud rate speed + #[doc(alias = "UARTFBRD")] + FBRD = 0x028, + /// `IrDA` Low-Power Counter Register + #[doc(alias = "UARTILPR")] + ILPR = 0x020, + /// Integer Baud Rate Register + /// + /// Responsible for baud rate speed + #[doc(alias = "UARTIBRD")] + IBRD = 0x024, + /// line control register (data frame format) + #[doc(alias = "UARTLCR_H")] + LCR_H = 0x02C, + /// Toggle UART, transmission or reception + #[doc(alias = "UARTCR")] + CR = 0x030, + /// Interrupt FIFO Level Select Register + #[doc(alias = "UARTIFLS")] + FLS = 0x034, + /// Interrupt Mask Set/Clear Register + #[doc(alias = "UARTIMSC")] + IMSC = 0x038, + /// Raw Interrupt Status Register + #[doc(alias = "UARTRIS")] + RIS = 0x03C, + /// Masked Interrupt Status Register + #[doc(alias = "UARTMIS")] + MIS = 0x040, + /// Interrupt Clear Register + #[doc(alias = "UARTICR")] + ICR = 0x044, + /// DMA control Register + #[doc(alias = "UARTDMACR")] + DMACR = 0x048, + ///// Reserved, offsets `0x04C` to `0x07C`. + //Reserved = 0x04C, +} + +/// Receive Status Register / Data Register common error bits +/// +/// The `UARTRSR` register is updated only when a read occurs +/// from the `UARTDR` register with the same status information +/// that can also be obtained by reading the `UARTDR` register +#[bitsize(8)] +#[derive(Clone, Copy, Default, DebugBits, FromBits)] +pub struct Errors { + pub framing_error: bool, + pub parity_error: bool, + pub break_error: bool, + pub overrun_error: bool, + _reserved_unpredictable: u4, +} + +// TODO: FIFO Mode has different semantics +/// Data Register, `UARTDR` +/// +/// The `UARTDR` register is the data register. +/// +/// For words to be transmitted: +/// +/// - if the FIFOs are enabled, data written to this location is pushed onto the +/// transmit +/// FIFO +/// - if the FIFOs are not enabled, data is stored in the transmitter holding +/// register (the +/// bottom word of the transmit FIFO). +/// +/// The write operation initiates transmission from the UART. The data is +/// prefixed with a start bit, appended with the appropriate parity bit +/// (if parity is enabled), and a stop bit. The resultant word is then +/// transmitted. +/// +/// For received words: +/// +/// - if the FIFOs are enabled, the data byte and the 4-bit status (break, +/// frame, parity, +/// and overrun) is pushed onto the 12-bit wide receive FIFO +/// - if the FIFOs are not enabled, the data byte and status are stored in the +/// receiving +/// holding register (the bottom word of the receive FIFO). +/// +/// The received data byte is read by performing reads from the `UARTDR` +/// register along with the corresponding status information. The status +/// information can also be read by a read of the `UARTRSR/UARTECR` +/// register. +/// +/// # Note +/// +/// You must disable the UART before any of the control registers are +/// reprogrammed. When the UART is disabled in the middle of +/// transmission or reception, it completes the current character before +/// stopping. +/// +/// # Source +/// ARM DDI 0183G 3.3.1 Data Register, UARTDR +#[bitsize(32)] +#[derive(Clone, Copy, Default, DebugBits, FromBits)] +#[doc(alias = "UARTDR")] +pub struct Data { + pub data: u8, + pub errors: Errors, + _reserved: u16, +} +impl_vmstate_bitsized!(Data); + +impl Data { + // bilge is not very const-friendly, unfortunately + pub const BREAK: Self = Self { value: 1 << 10 }; +} + +// TODO: FIFO Mode has different semantics +/// Receive Status Register / Error Clear Register, `UARTRSR/UARTECR` +/// +/// The UARTRSR/UARTECR register is the receive status register/error clear +/// register. Receive status can also be read from the `UARTRSR` +/// register. If the status is read from this register, then the status +/// information for break, framing and parity corresponds to the +/// data character read from the [Data register](Data), `UARTDR` prior to +/// reading the UARTRSR register. The status information for overrun is +/// set immediately when an overrun condition occurs. +/// +/// +/// # Note +/// The received data character must be read first from the [Data +/// Register](Data), `UARTDR` before reading the error status associated +/// with that data character from the `UARTRSR` register. This read +/// sequence cannot be reversed, because the `UARTRSR` register is +/// updated only when a read occurs from the `UARTDR` register. However, +/// the status information can also be obtained by reading the `UARTDR` +/// register +/// +/// # Source +/// ARM DDI 0183G 3.3.2 Receive Status Register/Error Clear Register, +/// UARTRSR/UARTECR +#[bitsize(32)] +#[derive(Clone, Copy, DebugBits, FromBits)] +pub struct ReceiveStatusErrorClear { + pub errors: Errors, + _reserved_unpredictable: u24, +} +impl_vmstate_bitsized!(ReceiveStatusErrorClear); + +impl ReceiveStatusErrorClear { + pub fn set_from_data(&mut self, data: Data) { + self.set_errors(data.errors()); + } + + pub fn reset(&mut self) { + // All the bits are cleared to 0 on reset. + *self = Self::default(); + } +} + +impl Default for ReceiveStatusErrorClear { + fn default() -> Self { + 0.into() + } +} + +#[bitsize(32)] +#[derive(Clone, Copy, DebugBits, FromBits)] +/// Flag Register, `UARTFR` +#[doc(alias = "UARTFR")] +pub struct Flags { + /// CTS Clear to send. This bit is the complement of the UART clear to + /// send, `nUARTCTS`, modem status input. That is, the bit is 1 + /// when `nUARTCTS` is LOW. + pub clear_to_send: bool, + /// DSR Data set ready. This bit is the complement of the UART data set + /// ready, `nUARTDSR`, modem status input. That is, the bit is 1 when + /// `nUARTDSR` is LOW. + pub data_set_ready: bool, + /// DCD Data carrier detect. This bit is the complement of the UART data + /// carrier detect, `nUARTDCD`, modem status input. That is, the bit is + /// 1 when `nUARTDCD` is LOW. + pub data_carrier_detect: bool, + /// BUSY UART busy. If this bit is set to 1, the UART is busy + /// transmitting data. This bit remains set until the complete + /// byte, including all the stop bits, has been sent from the + /// shift register. This bit is set as soon as the transmit FIFO + /// becomes non-empty, regardless of whether the UART is enabled + /// or not. + pub busy: bool, + /// RXFE Receive FIFO empty. The meaning of this bit depends on the + /// state of the FEN bit in the UARTLCR_H register. If the FIFO + /// is disabled, this bit is set when the receive holding + /// register is empty. If the FIFO is enabled, the RXFE bit is + /// set when the receive FIFO is empty. + pub receive_fifo_empty: bool, + /// TXFF Transmit FIFO full. The meaning of this bit depends on the + /// state of the FEN bit in the UARTLCR_H register. If the FIFO + /// is disabled, this bit is set when the transmit holding + /// register is full. If the FIFO is enabled, the TXFF bit is + /// set when the transmit FIFO is full. + pub transmit_fifo_full: bool, + /// RXFF Receive FIFO full. The meaning of this bit depends on the state + /// of the FEN bit in the UARTLCR_H register. If the FIFO is + /// disabled, this bit is set when the receive holding register + /// is full. If the FIFO is enabled, the RXFF bit is set when + /// the receive FIFO is full. + pub receive_fifo_full: bool, + /// Transmit FIFO empty. The meaning of this bit depends on the state of + /// the FEN bit in the [Line Control register](LineControl), + /// `UARTLCR_H`. If the FIFO is disabled, this bit is set when the + /// transmit holding register is empty. If the FIFO is enabled, + /// the TXFE bit is set when the transmit FIFO is empty. This + /// bit does not indicate if there is data in the transmit shift + /// register. + pub transmit_fifo_empty: bool, + /// `RI`, is `true` when `nUARTRI` is `LOW`. + pub ring_indicator: bool, + _reserved_zero_no_modify: u23, +} +impl_vmstate_bitsized!(Flags); + +impl Flags { + pub fn reset(&mut self) { + *self = Self::default(); + } +} + +impl Default for Flags { + fn default() -> Self { + let mut ret: Self = 0.into(); + // After reset TXFF, RXFF, and BUSY are 0, and TXFE and RXFE are 1 + ret.set_receive_fifo_empty(true); + ret.set_transmit_fifo_empty(true); + ret + } +} + +#[bitsize(32)] +#[derive(Clone, Copy, DebugBits, FromBits)] +/// Line Control Register, `UARTLCR_H` +#[doc(alias = "UARTLCR_H")] +pub struct LineControl { + /// BRK Send break. + /// + /// If this bit is set to `1`, a low-level is continually output on the + /// `UARTTXD` output, after completing transmission of the + /// current character. For the proper execution of the break command, + /// the software must set this bit for at least two complete + /// frames. For normal use, this bit must be cleared to `0`. + pub send_break: bool, + /// 1 PEN Parity enable: + /// + /// - 0 = parity is disabled and no parity bit added to the data frame + /// - 1 = parity checking and generation is enabled. + /// + /// See Table 3-11 on page 3-14 for the parity truth table. + pub parity_enabled: bool, + /// EPS Even parity select. Controls the type of parity the UART uses + /// during transmission and reception: + /// - 0 = odd parity. The UART generates or checks for an odd number of 1s + /// in the data and parity bits. + /// - 1 = even parity. The UART generates or checks for an even number of 1s + /// in the data and parity bits. + /// This bit has no effect when the `PEN` bit disables parity checking + /// and generation. See Table 3-11 on page 3-14 for the parity + /// truth table. + pub parity: Parity, + /// 3 STP2 Two stop bits select. If this bit is set to 1, two stop bits + /// are transmitted at the end of the frame. The receive + /// logic does not check for two stop bits being received. + pub two_stops_bits: bool, + /// FEN Enable FIFOs: + /// 0 = FIFOs are disabled (character mode) that is, the FIFOs become + /// 1-byte-deep holding registers 1 = transmit and receive FIFO + /// buffers are enabled (FIFO mode). + pub fifos_enabled: Mode, + /// WLEN Word length. These bits indicate the number of data bits + /// transmitted or received in a frame as follows: b11 = 8 bits + /// b10 = 7 bits + /// b01 = 6 bits + /// b00 = 5 bits. + pub word_length: WordLength, + /// 7 SPS Stick parity select. + /// 0 = stick parity is disabled + /// 1 = either: + /// • if the EPS bit is 0 then the parity bit is transmitted and checked + /// as a 1 • if the EPS bit is 1 then the parity bit is + /// transmitted and checked as a 0. This bit has no effect when + /// the PEN bit disables parity checking and generation. See Table 3-11 + /// on page 3-14 for the parity truth table. + pub sticky_parity: bool, + /// 31:8 - Reserved, do not modify, read as zero. + _reserved_zero_no_modify: u24, +} +impl_vmstate_bitsized!(LineControl); + +impl LineControl { + pub fn reset(&mut self) { + // All the bits are cleared to 0 when reset. + *self = 0.into(); + } +} + +impl Default for LineControl { + fn default() -> Self { + 0.into() + } +} + +#[bitsize(1)] +#[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] +/// `EPS` "Even parity select", field of [Line Control +/// register](LineControl). +pub enum Parity { + /// - 0 = odd parity. The UART generates or checks for an odd number of 1s + /// in the data and parity bits. + Odd = 0, + /// - 1 = even parity. The UART generates or checks for an even number of 1s + /// in the data and parity bits. + Even = 1, +} + +#[bitsize(1)] +#[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] +/// `FEN` "Enable FIFOs" or Device mode, field of [Line Control +/// register](LineControl). +pub enum Mode { + /// 0 = FIFOs are disabled (character mode) that is, the FIFOs become + /// 1-byte-deep holding registers + Character = 0, + /// 1 = transmit and receive FIFO buffers are enabled (FIFO mode). + FIFO = 1, +} + +#[bitsize(2)] +#[derive(Clone, Copy, Debug, Eq, FromBits, PartialEq)] +/// `WLEN` Word length, field of [Line Control register](LineControl). +/// +/// These bits indicate the number of data bits transmitted or received in a +/// frame as follows: +pub enum WordLength { + /// b11 = 8 bits + _8Bits = 0b11, + /// b10 = 7 bits + _7Bits = 0b10, + /// b01 = 6 bits + _6Bits = 0b01, + /// b00 = 5 bits. + _5Bits = 0b00, +} + +/// Control Register, `UARTCR` +/// +/// The `UARTCR` register is the control register. All the bits are cleared +/// to `0` on reset except for bits `9` and `8` that are set to `1`. +/// +/// # Source +/// ARM DDI 0183G, 3.3.8 Control Register, `UARTCR`, Table 3-12 +#[bitsize(32)] +#[doc(alias = "UARTCR")] +#[derive(Clone, Copy, DebugBits, FromBits)] +pub struct Control { + /// `UARTEN` UART enable: 0 = UART is disabled. If the UART is disabled + /// in the middle of transmission or reception, it completes the current + /// character before stopping. 1 = the UART is enabled. Data + /// transmission and reception occurs for either UART signals or SIR + /// signals depending on the setting of the SIREN bit. + pub enable_uart: bool, + /// `SIREN` `SIR` enable: 0 = IrDA SIR ENDEC is disabled. `nSIROUT` + /// remains LOW (no light pulse generated), and signal transitions on + /// SIRIN have no effect. 1 = IrDA SIR ENDEC is enabled. Data is + /// transmitted and received on nSIROUT and SIRIN. UARTTXD remains HIGH, + /// in the marking state. Signal transitions on UARTRXD or modem status + /// inputs have no effect. This bit has no effect if the UARTEN bit + /// disables the UART. + pub enable_sir: bool, + /// `SIRLP` SIR low-power IrDA mode. This bit selects the IrDA encoding + /// mode. If this bit is cleared to 0, low-level bits are transmitted as + /// an active high pulse with a width of 3/ 16th of the bit period. If + /// this bit is set to 1, low-level bits are transmitted with a pulse + /// width that is 3 times the period of the IrLPBaud16 input signal, + /// regardless of the selected bit rate. Setting this bit uses less + /// power, but might reduce transmission distances. + pub sir_lowpower_irda_mode: u1, + /// Reserved, do not modify, read as zero. + _reserved_zero_no_modify: u4, + /// `LBE` Loopback enable. If this bit is set to 1 and the SIREN bit is + /// set to 1 and the SIRTEST bit in the Test Control register, UARTTCR + /// on page 4-5 is set to 1, then the nSIROUT path is inverted, and fed + /// through to the SIRIN path. The SIRTEST bit in the test register must + /// be set to 1 to override the normal half-duplex SIR operation. This + /// must be the requirement for accessing the test registers during + /// normal operation, and SIRTEST must be cleared to 0 when loopback + /// testing is finished. This feature reduces the amount of external + /// coupling required during system test. If this bit is set to 1, and + /// the SIRTEST bit is set to 0, the UARTTXD path is fed through to the + /// UARTRXD path. In either SIR mode or UART mode, when this bit is set, + /// the modem outputs are also fed through to the modem inputs. This bit + /// is cleared to 0 on reset, to disable loopback. + pub enable_loopback: bool, + /// `TXE` Transmit enable. If this bit is set to 1, the transmit section + /// of the UART is enabled. Data transmission occurs for either UART + /// signals, or SIR signals depending on the setting of the SIREN bit. + /// When the UART is disabled in the middle of transmission, it + /// completes the current character before stopping. + pub enable_transmit: bool, + /// `RXE` Receive enable. If this bit is set to 1, the receive section + /// of the UART is enabled. Data reception occurs for either UART + /// signals or SIR signals depending on the setting of the SIREN bit. + /// When the UART is disabled in the middle of reception, it completes + /// the current character before stopping. + pub enable_receive: bool, + /// `DTR` Data transmit ready. This bit is the complement of the UART + /// data transmit ready, `nUARTDTR`, modem status output. That is, when + /// the bit is programmed to a 1 then `nUARTDTR` is LOW. + pub data_transmit_ready: bool, + /// `RTS` Request to send. This bit is the complement of the UART + /// request to send, `nUARTRTS`, modem status output. That is, when the + /// bit is programmed to a 1 then `nUARTRTS` is LOW. + pub request_to_send: bool, + /// `Out1` This bit is the complement of the UART Out1 (`nUARTOut1`) + /// modem status output. That is, when the bit is programmed to a 1 the + /// output is 0. For DTE this can be used as Data Carrier Detect (DCD). + pub out_1: bool, + /// `Out2` This bit is the complement of the UART Out2 (`nUARTOut2`) + /// modem status output. That is, when the bit is programmed to a 1, the + /// output is 0. For DTE this can be used as Ring Indicator (RI). + pub out_2: bool, + /// `RTSEn` RTS hardware flow control enable. If this bit is set to 1, + /// RTS hardware flow control is enabled. Data is only requested when + /// there is space in the receive FIFO for it to be received. + pub rts_hardware_flow_control_enable: bool, + /// `CTSEn` CTS hardware flow control enable. If this bit is set to 1, + /// CTS hardware flow control is enabled. Data is only transmitted when + /// the `nUARTCTS` signal is asserted. + pub cts_hardware_flow_control_enable: bool, + /// 31:16 - Reserved, do not modify, read as zero. + _reserved_zero_no_modify2: u16, +} +impl_vmstate_bitsized!(Control); + +impl Control { + pub fn reset(&mut self) { + *self = 0.into(); + self.set_enable_receive(true); + self.set_enable_transmit(true); + } +} + +impl Default for Control { + fn default() -> Self { + let mut ret: Self = 0.into(); + ret.reset(); + ret + } +} + +/// Interrupt status bits in UARTRIS, UARTMIS, UARTIMSC +pub struct Interrupt(pub u32); + +impl Interrupt { + pub const OE: Self = Self(1 << 10); + pub const BE: Self = Self(1 << 9); + pub const PE: Self = Self(1 << 8); + pub const FE: Self = Self(1 << 7); + pub const RT: Self = Self(1 << 6); + pub const TX: Self = Self(1 << 5); + pub const RX: Self = Self(1 << 4); + pub const DSR: Self = Self(1 << 3); + pub const DCD: Self = Self(1 << 2); + pub const CTS: Self = Self(1 << 1); + pub const RI: Self = Self(1 << 0); + + pub const E: Self = Self(Self::OE.0 | Self::BE.0 | Self::PE.0 | Self::FE.0); + pub const MS: Self = Self(Self::RI.0 | Self::DSR.0 | Self::DCD.0 | Self::CTS.0); +} From patchwork Sun Mar 9 10:31:12 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008283 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 21189C28B28 for ; Sun, 9 Mar 2025 10:32:25 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDx9-0008WC-6G; Sun, 09 Mar 2025 06:32:15 -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 1trDx1-0008Hb-4h for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:07 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDwy-00044K-EK for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:05 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516323; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=rMJXw2z6gbTxYfWWplVTHw1usKZlq5SZRfFTDJ86AUQ=; b=TU2QbAcs5ibjlJ4ENAl8CvSuLLemiICZQCTAhLSxbujeT5Yb9muhGDHO02JY6JYYfM4x2W EeJMYXhNlb5WKepDgCHaMecKzJFXokVnpPsHrCOeSqwcf4LPEiwKlwmVeUTXms8jgN/h8c tiAmzzPaTFxCY+6pm98EgoHWJAnPKJY= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-659-nCypOI8LOsC5756DQudR8w-1; Sun, 09 Mar 2025 06:32:01 -0400 X-MC-Unique: nCypOI8LOsC5756DQudR8w-1 X-Mimecast-MFC-AGG-ID: nCypOI8LOsC5756DQudR8w_1741516320 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43ced8c2eb7so4303345e9.1 for ; Sun, 09 Mar 2025 03:32:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516319; x=1742121119; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=rMJXw2z6gbTxYfWWplVTHw1usKZlq5SZRfFTDJ86AUQ=; b=ifshUxyCsqatyW9zHnfG0l7UuGGxLlJM4h4ZOQLdmG9Tsz1G5b7YkXqdtNOT18oTtN Bwc3HjejZTL18Hw8q/1Vd5uriYrCSX17hnngY97tO3soTQFavL6XcPxgNv/qXn4UNRMO ANbsL6RR6l6LZv6FQtMNU0R/Y65kk+CIUanxuWiMAsJWtYkt5RD7BDvDaU+1m8oRZ9RE VBUXzxiD4gR/Sgk62IT2ZCGeQ89HBhf+8ZIUBiVyQyZTuCdxpwmcp+6JZSax5MoV/VTk KRCm6ZB+gnOWMWvs/XD+Bvkor9Cm9dWK439VyFobZsusgW+vvul8+vMg6c2dpgW684SF s+rw== X-Gm-Message-State: AOJu0YzQgSnvMJ+mTCgGuAJNer2b99pRCbt6SzX/nUZllrPYT07NMM59 k94rVfT9buKyNRi0HYpfaj1LyQ5vE3tSbfbeEkjGLrZmgeyQ0X6dnHBaVoT1QTwiVSTL/nR+48U FdswBvunTlf8cGAMPIERU3xW6vn1moIr5SYmkRfZ0CNryqS1VBdaHasJoQq1grS1DmLaLqe5g6I dOlsYxutzZTrR7CShmVZn4MDSIWUEEFv9fKdsMz+g= X-Gm-Gg: ASbGncvhngBfYIA42cNJfQ0IxpgdysUD8pn/spmuGab+UPuSBm/Qc5GGWvc9NuonPxO mqh4to1sxkqYOMlFfJM88sB9BZsHBqyhUr8sJt63blPhjveTH/GKngIayzK4OiOM3ioJgYCMw/v apPrrb1S6SN/fC9lpySb/1DfTwv/2URYagUw4D/hsyiEqpqDfzSR7F3NauT3Y0l22jbpzyOPpAC m9qiCD5hWupQSbOe7CZTrp3rw04O6KUJ/iG98Ex0Fx5q9bGspOgZrKhuPmItuSaGz7aoe16EoKY AZxUb+GSajeDcjB7TA1cgw== X-Received: by 2002:a05:600c:450d:b0:439:7c0b:13f6 with SMTP id 5b1f17b1804b1-43c6872e1ffmr70893405e9.31.1741516319553; Sun, 09 Mar 2025 03:31:59 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFd/tWN761T5J3RV1qC4TQ0PkogVSb9CcwIq3cftaWZkCmWseFfZaAqA5COICW+y/m4dDOI1w== X-Received: by 2002:a05:600c:450d:b0:439:7c0b:13f6 with SMTP id 5b1f17b1804b1-43c6872e1ffmr70893175e9.31.1741516319038; Sun, 09 Mar 2025 03:31:59 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43bd4292b06sm140510635e9.14.2025.03.09.03.31.58 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:31:58 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 18/25] rust: pl011: clean up visibilities of callbacks Date: Sun, 9 Mar 2025 11:31:12 +0100 Message-ID: <20250309103120.1116448-19-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Do not make callbacks unnecessarily "pub", they are only used through function pointers. Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 01540654cc9..4cdbbf4b73d 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -537,7 +537,7 @@ fn post_init(&self) { } } - pub fn read(&self, offset: hwaddr, _size: u32) -> u64 { + fn read(&self, offset: hwaddr, _size: u32) -> u64 { match RegisterOffset::try_from(offset) { Err(v) if (0x3f8..0x400).contains(&(v >> 2)) => { let device_id = self.get_class().device_id; @@ -560,7 +560,7 @@ pub fn read(&self, offset: hwaddr, _size: u32) -> u64 { } } - pub fn write(&self, offset: hwaddr, value: u64, _size: u32) { + fn write(&self, offset: hwaddr, value: u64, _size: u32) { let mut update_irq = false; if let Ok(field) = RegisterOffset::try_from(offset) { // qemu_chr_fe_write_all() calls into the can_receive @@ -621,7 +621,7 @@ pub fn event(&self, event: QEMUChrEvent) { } } - pub fn realize(&self) { + fn realize(&self) { // SAFETY: self.char_backend has the correct size and alignment for a // CharBackend object, and its callbacks are of the correct types. unsafe { @@ -638,11 +638,11 @@ pub fn realize(&self) { } } - pub fn reset_hold(&self, _type: ResetType) { + fn reset_hold(&self, _type: ResetType) { self.regs.borrow_mut().reset(); } - pub fn update(&self) { + fn update(&self) { let regs = self.regs.borrow(); let flags = regs.int_level & regs.int_enabled; for (irq, i) in self.interrupts.iter().zip(IRQMASK) { From patchwork Sun Mar 9 10:31:13 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008296 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 48860C28B2E for ; Sun, 9 Mar 2025 10:33:47 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDyB-0003ob-7U; Sun, 09 Mar 2025 06:33:19 -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 1trDy8-0003Vq-2l for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:33:16 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.129.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDy5-0004AI-5T for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:33:14 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516392; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=EU/CFazaZVh5PdNZNlABB6euybR9YpGeNLleuhzibQc=; b=CznxBIihyf1mf2dXrWjBbnyVdmZGixPxL0HdNSB2BWqbEcaQsv8ZAWfMujh+oTgUQ0TFP+ jKEgmR8hJr3gVDqVwc2bRPgXaJNHDjkwRgNDHq8rFGsBQzMenUnGulk1ClrTe9AzVtKEfA g7uUuzUKj7LCAlgP8DDIEyLzc6XDVj8= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-607--Otb_IiuMZq3vKqC7fG2aA-1; Sun, 09 Mar 2025 06:32:03 -0400 X-MC-Unique: -Otb_IiuMZq3vKqC7fG2aA-1 X-Mimecast-MFC-AGG-ID: -Otb_IiuMZq3vKqC7fG2aA_1741516322 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-3912539665cso1912017f8f.1 for ; Sun, 09 Mar 2025 03:32:03 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516321; x=1742121121; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=EU/CFazaZVh5PdNZNlABB6euybR9YpGeNLleuhzibQc=; b=CUZmM+lpZiXNabM58RJ5rnSoPOPEoe4D6FmhxFHIO8k/pxMGRnyie/0pKRn2y8rR5P Ehqp7AHoRzO0bJ1Nt1nyMTfmkaytd5SqbWkcIrYAerfnqLr++Wt/jifGIvhRwEPF0UDV mlh9QfRMLYDYkGyVWRnolV0U9QZtWiXAINWvz+ac5OvYvNNuigUXvuBrM0c03MAYaJ/p prjXeO57QNFowitjn4inlxlK68UNddbB7UDS+d5bGtz7GnFJU+jYSdAUR71enalDgEnk DUWyRC+tOkBnjvvQlIMgE+BoA6JEEZ4eX80q+fj82cSgya5urcEsTLa9tNnMVMVmDwYS VL4A== X-Gm-Message-State: AOJu0YyYkj9Am56blUaWDdWls++fmq6e/TLMPSSX8vj1ecbv2ONt65+j bHWaxnF+/U6iME4nr3Fw6vnCsvotOGeN3e6xuI1QZGjEAEvQgs65f4CV8QIEXJmAGfFmvNU40UC bM9SNasNtukjAfoiRJ4YWmzQFv0VVyC129rlxaPG/ggOOn5LhjYowJFB81axf/595+YD9MWOqsX aADfaZUEkFq/m0iA3oRQvqgfwvwDIHeF0RJqkv9/s= X-Gm-Gg: ASbGncu9H5O9dScmGZvLi7IsvzhvTaVOZzJqWKh2MnJs/tuZSSki+M4RthKgUw51lGC r+g3+KdosZnKhed43RNWnc7AiOkRrL3NYTfZheXl1ASsRHz02GOQBkZo/KXFBYCBG3hXY1ZdXX/ Pns9faB/53SppQt5MOXA+UWNJMekAUdo+ks8io/U37OgAT7v59Wy64SV211rmOY6oIzVXQrJcEX t8KsSHHhpRyi3zFwCxjTDCHd2V7/jABZp3Ix4znMIzhX2qa/R5bg57zvgg62VtTa55kVOWyhRKp A4V4TNHACppMa971zjYm5g== X-Received: by 2002:a5d:648e:0:b0:390:ef45:1a36 with SMTP id ffacd0b85a97d-3913af33e09mr3403089f8f.19.1741516321314; Sun, 09 Mar 2025 03:32:01 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEjzQtYdZI9taC7o0Z7eeylZcL7fUFhxPrScN/zFKSMRPEbyFiq5DEF7UyAGssLcSqUkV50PA== X-Received: by 2002:a5d:648e:0:b0:390:ef45:1a36 with SMTP id ffacd0b85a97d-3913af33e09mr3403070f8f.19.1741516320711; Sun, 09 Mar 2025 03:32:00 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912bfb7934sm11680011f8f.12.2025.03.09.03.31.59 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:32:00 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 19/25] rust: pl011: switch to safe chardev operation Date: Sun, 9 Mar 2025 11:31:13 +0100 Message-ID: <20250309103120.1116448-20-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.129.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H5=0.001, RCVD_IN_MSPIKE_WL=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Switch bindings::CharBackend with chardev::CharBackend. This removes occurrences of "unsafe" due to FFI and switches the wrappers for receive, can_receive and event callbacks to the common ones implemented by chardev::CharBackend. Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 119 +++++++------------------------ 1 file changed, 25 insertions(+), 94 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 4cdbbf4b73d..4e282bc9e9d 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -2,18 +2,10 @@ // Author(s): Manos Pitsidianakis // SPDX-License-Identifier: GPL-2.0-or-later -use std::{ - ffi::CStr, - os::raw::{c_int, c_void}, - ptr::{addr_of, addr_of_mut, NonNull}, -}; +use std::{ffi::CStr, ptr::addr_of_mut}; use qemu_api::{ - bindings::{ - qemu_chr_fe_accept_input, qemu_chr_fe_ioctl, qemu_chr_fe_set_handlers, - qemu_chr_fe_write_all, CharBackend, QEMUChrEvent, CHR_IOCTL_SERIAL_SET_BREAK, - }, - chardev::Chardev, + chardev::{CharBackend, Chardev, Event}, impl_vmstate_forward, irq::{IRQState, InterruptSource}, memory::{hwaddr, MemoryRegion, MemoryRegionOps, MemoryRegionOpsBuilder}, @@ -235,7 +227,7 @@ pub(self) fn write( &mut self, offset: RegisterOffset, value: u32, - char_backend: *mut CharBackend, + char_backend: &CharBackend, ) -> bool { // eprintln!("write offset {offset} value {value}"); use RegisterOffset::*; @@ -269,17 +261,9 @@ pub(self) fn write( self.reset_tx_fifo(); } let update = (self.line_control.send_break() != new_val.send_break()) && { - let mut break_enable: c_int = new_val.send_break().into(); - // SAFETY: self.char_backend is a valid CharBackend instance after it's been - // initialized in realize(). - unsafe { - qemu_chr_fe_ioctl( - char_backend, - CHR_IOCTL_SERIAL_SET_BREAK as i32, - addr_of_mut!(break_enable).cast::(), - ); - } - self.loopback_break(break_enable > 0) + let break_enable = new_val.send_break(); + let _ = char_backend.send_break(break_enable); + self.loopback_break(break_enable) }; self.line_control = new_val; self.set_read_trigger(); @@ -551,9 +535,7 @@ fn read(&self, offset: hwaddr, _size: u32) -> u64 { let (update_irq, result) = self.regs.borrow_mut().read(field); if update_irq { self.update(); - unsafe { - qemu_chr_fe_accept_input(addr_of!(self.char_backend) as *mut _); - } + self.char_backend.accept_input(); } result.into() } @@ -567,21 +549,16 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) { // callback, so handle writes before entering PL011Registers. if field == RegisterOffset::DR { // ??? Check if transmitter is enabled. - let ch: u8 = value as u8; - // SAFETY: char_backend is a valid CharBackend instance after it's been - // initialized in realize(). + let ch: [u8; 1] = [value as u8]; // XXX this blocks entire thread. Rewrite to use // qemu_chr_fe_write and background I/O callbacks - unsafe { - qemu_chr_fe_write_all(addr_of!(self.char_backend) as *mut _, &ch, 1); - } + let _ = self.char_backend.write_all(&ch); } - update_irq = self.regs.borrow_mut().write( - field, - value as u32, - addr_of!(self.char_backend) as *mut _, - ); + update_irq = self + .regs + .borrow_mut() + .write(field, value as u32, &self.char_backend); } else { eprintln!("write bad offset {offset} value {value}"); } @@ -590,15 +567,18 @@ fn write(&self, offset: hwaddr, value: u64, _size: u32) { } } - pub fn can_receive(&self) -> bool { - // trace_pl011_can_receive(s->lcr, s->read_count, r); + fn can_receive(&self) -> u32 { let regs = self.regs.borrow(); - regs.read_count < regs.fifo_depth() + // trace_pl011_can_receive(s->lcr, s->read_count, r); + u32::from(regs.read_count < regs.fifo_depth()) } - pub fn receive(&self, ch: u32) { + fn receive(&self, buf: &[u8]) { + if buf.is_empty() { + return; + } let mut regs = self.regs.borrow_mut(); - let update_irq = !regs.loopback_enabled() && regs.put_fifo(ch); + let update_irq = !regs.loopback_enabled() && regs.put_fifo(buf[0].into()); // Release the BqlRefCell before calling self.update() drop(regs); @@ -607,10 +587,10 @@ pub fn receive(&self, ch: u32) { } } - pub fn event(&self, event: QEMUChrEvent) { + fn event(&self, event: Event) { let mut update_irq = false; let mut regs = self.regs.borrow_mut(); - if event == QEMUChrEvent::CHR_EVENT_BREAK && !regs.loopback_enabled() { + if event == Event::CHR_EVENT_BREAK && !regs.loopback_enabled() { update_irq = regs.put_fifo(registers::Data::BREAK.into()); } // Release the BqlRefCell before calling self.update() @@ -622,20 +602,8 @@ pub fn event(&self, event: QEMUChrEvent) { } fn realize(&self) { - // SAFETY: self.char_backend has the correct size and alignment for a - // CharBackend object, and its callbacks are of the correct types. - unsafe { - qemu_chr_fe_set_handlers( - addr_of!(self.char_backend) as *mut CharBackend, - Some(pl011_can_receive), - Some(pl011_receive), - Some(pl011_event), - None, - addr_of!(*self).cast::() as *mut c_void, - core::ptr::null_mut(), - true, - ); - } + self.char_backend + .enable_handlers(self, Self::can_receive, Self::receive, Self::event); } fn reset_hold(&self, _type: ResetType) { @@ -666,43 +634,6 @@ pub fn post_load(&self, _version_id: u32) -> Result<(), ()> { Interrupt::E.0, ]; -/// # Safety -/// -/// We expect the FFI user of this function to pass a valid pointer, that has -/// the same size as [`PL011State`]. We also expect the device is -/// readable/writeable from one thread at any time. -pub unsafe extern "C" fn pl011_can_receive(opaque: *mut c_void) -> c_int { - let state = NonNull::new(opaque).unwrap().cast::(); - unsafe { state.as_ref().can_receive().into() } -} - -/// # Safety -/// -/// We expect the FFI user of this function to pass a valid pointer, that has -/// the same size as [`PL011State`]. We also expect the device is -/// readable/writeable from one thread at any time. -/// -/// The buffer and size arguments must also be valid. -pub unsafe extern "C" fn pl011_receive(opaque: *mut c_void, buf: *const u8, size: c_int) { - let state = NonNull::new(opaque).unwrap().cast::(); - unsafe { - if size > 0 { - debug_assert!(!buf.is_null()); - state.as_ref().receive(u32::from(buf.read_volatile())); - } - } -} - -/// # Safety -/// -/// We expect the FFI user of this function to pass a valid pointer, that has -/// the same size as [`PL011State`]. We also expect the device is -/// readable/writeable from one thread at any time. -pub unsafe extern "C" fn pl011_event(opaque: *mut c_void, event: QEMUChrEvent) { - let state = NonNull::new(opaque).unwrap().cast::(); - unsafe { state.as_ref().event(event) } -} - /// # Safety /// /// We expect the FFI user of this function to pass a valid pointer for `chr` From patchwork Sun Mar 9 10:31:14 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008304 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id ECDB7C282D1 for ; Sun, 9 Mar 2025 10:35:10 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDxE-0000GY-Dz; Sun, 09 Mar 2025 06:32:20 -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 1trDx3-0008Km-Hx for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:11 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDx1-00044x-V9 for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:09 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516327; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=wbOO8hVPA/iWAR/aAhdUbZRw20JyRLfj8f5+lfhW6z4=; b=f56xFQ/q5fRRJ5xKwH10x7sJzVgqR7d66isShiuPnevRosR6+0c/h4xqoMDV4ufrQpDElV 0fByPyWKgTZyentDyLvCLdt4VDLoB+A12UqZaesIMAKXS9G/imfW5+V8WADy/nnngHxZkG 7gcXcxfHvtJmZW0bTc+SZk/SexSRctE= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-102-ZD91VZRqMv2_raEFtfK2tw-1; Sun, 09 Mar 2025 06:32:05 -0400 X-MC-Unique: ZD91VZRqMv2_raEFtfK2tw-1 X-Mimecast-MFC-AGG-ID: ZD91VZRqMv2_raEFtfK2tw_1741516324 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-4388eee7073so19653695e9.0 for ; Sun, 09 Mar 2025 03:32:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516324; x=1742121124; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=wbOO8hVPA/iWAR/aAhdUbZRw20JyRLfj8f5+lfhW6z4=; b=AGK0qh0Xa8a/nmnbvXGSTu3C1pWHZYuDnZBPFt+xeD8r2nb8ntmp5/ra3FeCQAjIvd +JiBf32hLIxpXDDNv1iGV3KU7dJ2a2KEDHS0pFniJPxUCKmHE1ZUY8yxYX7t3bH0EHnJ mFb0aRyCFZt1IRydYeh2NUipAFYhaaRuGNc81/mvnxEX9Hpb7WNp2pD7orxIMZgOG0Bs 8EDXX11V/W+aag+hkXjM9GJnAL1+HeCLcB5gVNiDdb9EOgDjhuPxtQV5WkCQoafpE8+k 9JdjAGwO7pit2jUJEQFEvl88a1cwxsueTTFwtiwtvq+BEmdfM/XTaXPNvPGvBQJytCoD vy2Q== X-Gm-Message-State: AOJu0YxCyvam0bHiLvp9R9hyWYC/Wc0+RggL7KAr4iWwi+g17lsxMhcx PpUxBIxIl50PVNSS1u6yCWJp/+KKhp3u67hi4BZlmo8AcTqZFkEgxRRe4mFZAU2q1WHNSdvlBNX EH7Qxnd2xBEce+MBRRchPz6XpQszzYX9ZorlXzYc8tkPc3CMdAGcKv2QdiKXBrGN4FYxfeXvWsC 66pLiXFwkXglEX6naAk5LW6+/mutWqrKLQdY0UMGg= X-Gm-Gg: ASbGncuq2fAZaGd3StVRBKW5ZH5lH++VNwLtPpvd2EIvBIIiyRAIndK/jVQUhsS38zn Dghy0VGhCtpc8NUIDVGh5R2a2CYrpD3aN32yUo0wB5sy0W2Q40WsAD6Zst2DQ4AOg+2G8Qhy8rj /cud9x8APHpy45+Y5NQkSTF27f9lqVXR/X1RiTfzpTtXmqj2C/q/eFYhzKjYWgosIEhlYedXTG6 5G+V5NrU1zg5XlefBE6qdA7iEi0k4cf4v7pTosp5ueuYNWHW0u7/0Sgub46UuKbLuT3uty6WM03 gM/KFTvLbyCaATHPBL9zzA== X-Received: by 2002:a05:600c:754:b0:43b:bfa7:c7d with SMTP id 5b1f17b1804b1-43ce4aa8771mr35085235e9.2.1741516323984; Sun, 09 Mar 2025 03:32:03 -0700 (PDT) X-Google-Smtp-Source: AGHT+IF4U1sgQ7Yw11hS4ilbfOvsS17ZMTC35iONV4y2gUHL6UcXuIB0x3ffoCM4oxaREM4OhAelVA== X-Received: by 2002:a05:600c:754:b0:43b:bfa7:c7d with SMTP id 5b1f17b1804b1-43ce4aa8771mr35085035e9.2.1741516323467; Sun, 09 Mar 2025 03:32:03 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43bdd8b0461sm114516235e9.4.2025.03.09.03.32.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:32:01 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 20/25] rust: pl011: pass around registers::Data Date: Sun, 9 Mar 2025 11:31:14 +0100 Message-ID: <20250309103120.1116448-21-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The values stored in the Fifo are instances of the bitfield-struct registers::Data. Convert as soon as possible the value written into DR, and always refer to the bitfield struct; it's generally cleaner other than PL011State::receive having to do a double conversion u8=>u32=>registers::Data. Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index 4e282bc9e9d..af93ae8bebe 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -234,7 +234,7 @@ pub(self) fn write( match offset { DR => { // interrupts always checked - let _ = self.loopback_tx(value); + let _ = self.loopback_tx(value.into()); self.int_level |= Interrupt::TX.0; return true; } @@ -301,7 +301,7 @@ pub(self) fn write( #[inline] #[must_use] - fn loopback_tx(&mut self, value: u32) -> bool { + fn loopback_tx(&mut self, value: registers::Data) -> bool { // Caveat: // // In real hardware, TX loopback happens at the serial-bit level @@ -370,7 +370,7 @@ fn loopback_mdmctrl(&mut self) -> bool { } fn loopback_break(&mut self, enable: bool) -> bool { - enable && self.loopback_tx(registers::Data::BREAK.into()) + enable && self.loopback_tx(registers::Data::BREAK) } fn set_read_trigger(&mut self) { @@ -429,11 +429,11 @@ pub fn fifo_depth(&self) -> u32 { } #[must_use] - pub fn put_fifo(&mut self, value: u32) -> bool { + pub fn put_fifo(&mut self, value: registers::Data) -> bool { let depth = self.fifo_depth(); assert!(depth > 0); let slot = (self.read_pos + self.read_count) & (depth - 1); - self.read_fifo[slot] = registers::Data::from(value); + self.read_fifo[slot] = value; self.read_count += 1; self.flags.set_receive_fifo_empty(false); if self.read_count == depth { @@ -578,7 +578,8 @@ fn receive(&self, buf: &[u8]) { return; } let mut regs = self.regs.borrow_mut(); - let update_irq = !regs.loopback_enabled() && regs.put_fifo(buf[0].into()); + let c: u32 = buf[0].into(); + let update_irq = !regs.loopback_enabled() && regs.put_fifo(c.into()); // Release the BqlRefCell before calling self.update() drop(regs); @@ -591,7 +592,7 @@ fn event(&self, event: Event) { let mut update_irq = false; let mut regs = self.regs.borrow_mut(); if event == Event::CHR_EVENT_BREAK && !regs.loopback_enabled() { - update_irq = regs.put_fifo(registers::Data::BREAK.into()); + update_irq = regs.put_fifo(registers::Data::BREAK); } // Release the BqlRefCell before calling self.update() drop(regs); From patchwork Sun Mar 9 10:31:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008307 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id BA354C28B28 for ; Sun, 9 Mar 2025 10:35:31 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDxL-0000Nm-4q; Sun, 09 Mar 2025 06:32:27 -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 1trDx6-0008Pg-Ue for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:13 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDx4-00045C-9q for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516329; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F9+Wxi/x9MmY8CxDvN4TGCD/sbZnRsQl3OJcT3nCjd8=; b=XXfa0/VbwBc1FVUwuYYFCYZ5zyeV3x7jAwnnGlOIZLC3shTMUTsg2wLO+J5L4ZSyjd9goa VZejAebby0Ii8Yd4EnIgnA0dk7U1V/x4xaEyA+ORyybv6uh9IHP9cmg70cJExWuZCjmTRb kAMiR+jr6KC7tsqSqPTkQrF90jo/h+A= Received: from mail-wr1-f71.google.com (mail-wr1-f71.google.com [209.85.221.71]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-474-gfPkjX1xMVWBuKYSwk_l7w-1; Sun, 09 Mar 2025 06:32:07 -0400 X-MC-Unique: gfPkjX1xMVWBuKYSwk_l7w-1 X-Mimecast-MFC-AGG-ID: gfPkjX1xMVWBuKYSwk_l7w_1741516326 Received: by mail-wr1-f71.google.com with SMTP id ffacd0b85a97d-39137e17c50so605007f8f.3 for ; Sun, 09 Mar 2025 03:32:07 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516326; x=1742121126; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=F9+Wxi/x9MmY8CxDvN4TGCD/sbZnRsQl3OJcT3nCjd8=; b=Kg7iNrRijkq0c7m0nlOcrG27sxyejfuPn3is8gETXabnQVgAFxVbnsW8FlKUoFYHmq yhKfeF5SmXnCOZe01JIb+Rte0FgzHdFlHKMbSKB+3dXwavWAdj5SGRwPDUp0YLw9rcZZ CztGNtCSNLI/Mla/SiSklwlqVXLSLnMiv5dZOh6spnX1buMATYJBDxoEQc1sM4aWPMft 7Jf6fG+g2QaChtmLP8KlzpVWvgepkDMnuHInau205NL1GzWozn3ssnho17zxhgedtbIT YEyBp2OlLUlW/Rgzj0a401dgCBEPwvg3lK1urVoeuSe7+QW+C1SoyoX/TS5riRa+LzhH INEg== X-Gm-Message-State: AOJu0Yzrtx3M73Q8ctASlJWS8EAP5gh6+XdGHcCDNRnw3LKe92ZjBlW8 TOPvKJY/cBd8t1e4VK20diWLzuyzNaCmjGYklD3/q0mcekN2hpcOb3x+4tG8ocbYkO4jROa7w0F UHl6XZe7DB7jzP7i1Wu9czARzHfQMovjn7Xylw0q85asleFMpglZl6hKJGWSs6D/ENLi/3HYGz+ /QIBhBtRSw3ycUesrpUT6Ed7h3raA77aBxp8Yhzas= X-Gm-Gg: ASbGncswivTsAASjf092pm2q9SKm1ayrXUTyamWjxVY9+9PH5YyodmmakkZylo/7BFn 82/2XlfXDPcZOQcPgSi4GR1Yuji0a8uixcNc+Xp/FrzlgaMEpa3vHikOnPaUpBxMabMSgr7nAXK sRDDByeP0YJKbhZcHlz0m0utRKJy77XnrZOvasEcAExqLlyq7Ffwg2IuqRvVr8AkAsA+TfIAqvQ LyCoU1A41lkry/O3v4SNGhIKr6BFhLGwiaDetL1UC/APGxwBirf4jsIhZU+DbduTUIIoc+VYI70 Oi0TU2g1tR2KOEH8q6n0CA== X-Received: by 2002:a05:6000:1867:b0:390:fbcf:56be with SMTP id ffacd0b85a97d-39132b63fb8mr6368084f8f.0.1741516325793; Sun, 09 Mar 2025 03:32:05 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEpN1Ruxltms+1KzxliH3CaLjBWBxi39ybCTDvELTRt1q9o/aSDzhIxQGr3tZDGfScuNsbSzw== X-Received: by 2002:a05:6000:1867:b0:390:fbcf:56be with SMTP id ffacd0b85a97d-39132b63fb8mr6368067f8f.0.1741516325262; Sun, 09 Mar 2025 03:32:05 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912bfba8b6sm11719579f8f.11.2025.03.09.03.32.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:32:04 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 21/25] rust: hpet: decode HPET registers into enums Date: Sun, 9 Mar 2025 11:31:15 +0100 Message-ID: <20250309103120.1116448-22-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Generalize timer_and_addr() to decode all registers into a single enum HPETRegister, and use the TryInto derive to separate valid and invalid values. The main advantage lies in checking that all registers are enumerated in the "match" statements. Signed-off-by: Paolo Bonzini --- rust/Cargo.toml | 2 + rust/hw/char/pl011/src/lib.rs | 2 - rust/hw/timer/hpet/src/hpet.rs | 222 +++++++++++++++++---------------- 3 files changed, 119 insertions(+), 107 deletions(-) diff --git a/rust/Cargo.toml b/rust/Cargo.toml index 5041d6291fd..ab1185a8143 100644 --- a/rust/Cargo.toml +++ b/rust/Cargo.toml @@ -37,6 +37,8 @@ result_unit_err = "allow" should_implement_trait = "deny" # can be for a reason, e.g. in callbacks unused_self = "allow" +# common in device crates +upper_case_acronyms = "allow" # default-allow lints as_ptr_cast_mut = "deny" diff --git a/rust/hw/char/pl011/src/lib.rs b/rust/hw/char/pl011/src/lib.rs index 45c13ba899e..dbae76991c9 100644 --- a/rust/hw/char/pl011/src/lib.rs +++ b/rust/hw/char/pl011/src/lib.rs @@ -12,8 +12,6 @@ //! See [`PL011State`](crate::device::PL011State) for the device model type and //! the [`registers`] module for register types. -#![allow(clippy::upper_case_acronyms)] - use qemu_api::c_str; mod device; diff --git a/rust/hw/timer/hpet/src/hpet.rs b/rust/hw/timer/hpet/src/hpet.rs index d989360ede8..20e0afdfca8 100644 --- a/rust/hw/timer/hpet/src/hpet.rs +++ b/rust/hw/timer/hpet/src/hpet.rs @@ -48,8 +48,6 @@ const HPET_CLK_PERIOD: u64 = 10; // 10 ns const FS_PER_NS: u64 = 1000000; // 1000000 femtoseconds == 1 ns -/// General Capabilities and ID Register -const HPET_CAP_REG: u64 = 0x000; /// Revision ID (bits 0:7). Revision 1 is implemented (refer to v1.0a spec). const HPET_CAP_REV_ID_VALUE: u64 = 0x1; const HPET_CAP_REV_ID_SHIFT: usize = 0; @@ -65,8 +63,6 @@ /// Main Counter Tick Period (bits 32:63) const HPET_CAP_CNT_CLK_PERIOD_SHIFT: usize = 32; -/// General Configuration Register -const HPET_CFG_REG: u64 = 0x010; /// Overall Enable (bit 0) const HPET_CFG_ENABLE_SHIFT: usize = 0; /// Legacy Replacement Route (bit 1) @@ -74,14 +70,6 @@ /// Other bits are reserved. const HPET_CFG_WRITE_MASK: u64 = 0x003; -/// General Interrupt Status Register -const HPET_INT_STATUS_REG: u64 = 0x020; - -/// Main Counter Value Register -const HPET_COUNTER_REG: u64 = 0x0f0; - -/// Timer N Configuration and Capability Register (masked by 0x18) -const HPET_TN_CFG_REG: u64 = 0x000; /// bit 0, 7, and bits 16:31 are reserved. /// bit 4, 5, 15, and bits 32:64 are read-only. const HPET_TN_CFG_WRITE_MASK: u64 = 0x7f4e; @@ -109,11 +97,51 @@ /// Timer N Interrupt Routing Capability (bits 32:63) const HPET_TN_CFG_INT_ROUTE_CAP_SHIFT: usize = 32; -/// Timer N Comparator Value Register (masked by 0x18) -const HPET_TN_CMP_REG: u64 = 0x008; +#[derive(qemu_api_macros::TryInto)] +#[repr(u64)] +#[allow(non_camel_case_types)] +/// Timer registers, masked by 0x18 +enum TimerRegister { + /// Timer N Configuration and Capability Register + CFG = 0, + /// Timer N Comparator Value Register + CMP = 8, + /// Timer N FSB Interrupt Route Register + ROUTE = 16, +} -/// Timer N FSB Interrupt Route Register (masked by 0x18) -const HPET_TN_FSB_ROUTE_REG: u64 = 0x010; +#[derive(qemu_api_macros::TryInto)] +#[repr(u64)] +#[allow(non_camel_case_types)] +/// Global registers +enum GlobalRegister { + /// General Capabilities and ID Register + CAP = 0, + /// General Configuration Register + CFG = 0x10, + /// General Interrupt Status Register + INT_STATUS = 0x20, + /// Main Counter Value Register + COUNTER = 0xF0, +} + +enum HPETRegister<'a> { + /// Global register in the range from `0` to `0xff` + Global(GlobalRegister), + + /// Register in the timer block `0x100`...`0x3ff` + Timer(&'a BqlRefCell, TimerRegister), + + /// Invalid address + #[allow(dead_code)] + Unknown(hwaddr), +} + +struct HPETAddrDecode<'a> { + shift: u32, + len: u32, + reg: HPETRegister<'a>, +} const fn hpet_next_wrap(cur_tick: u64) -> u64 { (cur_tick | 0xffffffff) + 1 @@ -471,33 +499,21 @@ fn callback(&mut self) { self.update_irq(true); } - const fn read(&self, addr: hwaddr, _size: u32) -> u64 { - let shift: u64 = (addr & 4) * 8; - - match addr & !4 { - HPET_TN_CFG_REG => self.config >> shift, // including interrupt capabilities - HPET_TN_CMP_REG => self.cmp >> shift, // comparator register - HPET_TN_FSB_ROUTE_REG => self.fsb >> shift, - _ => { - // TODO: Add trace point - trace_hpet_ram_read_invalid() - // Reserved. - 0 - } + const fn read(&self, reg: TimerRegister) -> u64 { + use TimerRegister::*; + match reg { + CFG => self.config, // including interrupt capabilities + CMP => self.cmp, // comparator register + ROUTE => self.fsb, } } - fn write(&mut self, addr: hwaddr, value: u64, size: u32) { - let shift = ((addr & 4) * 8) as u32; - let len = std::cmp::min(size * 8, 64 - shift); - - match addr & !4 { - HPET_TN_CFG_REG => self.set_tn_cfg_reg(shift, len, value), - HPET_TN_CMP_REG => self.set_tn_cmp_reg(shift, len, value), - HPET_TN_FSB_ROUTE_REG => self.set_tn_fsb_route_reg(shift, len, value), - _ => { - // TODO: Add trace point - trace_hpet_ram_write_invalid() - // Reserved. - } + fn write(&mut self, reg: TimerRegister, value: u64, shift: u32, len: u32) { + use TimerRegister::*; + match reg { + CFG => self.set_tn_cfg_reg(shift, len, value), + CMP => self.set_tn_cmp_reg(shift, len, value), + ROUTE => self.set_tn_fsb_route_reg(shift, len, value), } } } @@ -749,77 +765,73 @@ fn reset_hold(&self, _type: ResetType) { self.rtc_irq_level.set(0); } - fn timer_and_addr(&self, addr: hwaddr) -> Option<(&BqlRefCell, hwaddr)> { - let timer_id: usize = ((addr - 0x100) / 0x20) as usize; - - // TODO: Add trace point - trace_hpet_ram_[read|write]_timer_id(timer_id) - if timer_id > self.num_timers.get() { - // TODO: Add trace point - trace_hpet_timer_id_out_of_range(timer_id) - None - } else { - // Keep the complete address so that HPETTimer's read and write could - // detect the invalid access. - Some((&self.timers[timer_id], addr & 0x1F)) - } - } - - fn read(&self, addr: hwaddr, size: u32) -> u64 { - let shift: u64 = (addr & 4) * 8; - - // address range of all TN regs - // TODO: Add trace point - trace_hpet_ram_read(addr) - if (0x100..=0x3ff).contains(&addr) { - match self.timer_and_addr(addr) { - None => 0, // Reserved, - Some((timer, tn_addr)) => timer.borrow_mut().read(tn_addr, size), - } - } else { - match addr & !4 { - HPET_CAP_REG => self.capability.get() >> shift, /* including HPET_PERIOD 0x004 */ - // (CNT_CLK_PERIOD field) - HPET_CFG_REG => self.config.get() >> shift, - HPET_COUNTER_REG => { - let cur_tick: u64 = if self.is_hpet_enabled() { - self.get_ticks() - } else { - self.counter.get() - }; - - // TODO: Add trace point - trace_hpet_ram_read_reading_counter(addr & 4, - // cur_tick) - cur_tick >> shift - } - HPET_INT_STATUS_REG => self.int_status.get() >> shift, - _ => { - // TODO: Add trace point- trace_hpet_ram_read_invalid() - // Reserved. - 0 - } - } - } - } - - fn write(&self, addr: hwaddr, value: u64, size: u32) { + fn decode(&self, mut addr: hwaddr, size: u32) -> HPETAddrDecode { let shift = ((addr & 4) * 8) as u32; let len = std::cmp::min(size * 8, 64 - shift); - // TODO: Add trace point - trace_hpet_ram_write(addr, value) - if (0x100..=0x3ff).contains(&addr) { - match self.timer_and_addr(addr) { - None => (), // Reserved. - Some((timer, tn_addr)) => timer.borrow_mut().write(tn_addr, value, size), - } + addr &= !4; + let reg = if (0..=0xff).contains(&addr) { + GlobalRegister::try_from(addr).map(HPETRegister::Global) } else { - match addr & !0x4 { - HPET_CAP_REG => {} // General Capabilities and ID Register: Read Only - HPET_CFG_REG => self.set_cfg_reg(shift, len, value), - HPET_INT_STATUS_REG => self.set_int_status_reg(shift, len, value), - HPET_COUNTER_REG => self.set_counter_reg(shift, len, value), - _ => { - // TODO: Add trace point - trace_hpet_ram_write_invalid() - // Reserved. + let timer_id: usize = ((addr - 0x100) / 0x20) as usize; + if timer_id <= self.num_timers.get() { + // TODO: Add trace point - trace_hpet_ram_[read|write]_timer_id(timer_id) + TimerRegister::try_from(addr) + .map(|reg| HPETRegister::Timer(&self.timers[timer_id], reg)) + } else { + // TODO: Add trace point - trace_hpet_timer_id_out_of_range(timer_id) + Err(addr) + } + }; + + // reg is now a Result + // convert the Err case into HPETRegister as well + let reg = reg.unwrap_or_else(HPETRegister::Unknown); + HPETAddrDecode { shift, len, reg } + } + + fn read(&self, addr: hwaddr, size: u32) -> u64 { + // TODO: Add trace point - trace_hpet_ram_read(addr) + let HPETAddrDecode { shift, reg, .. } = self.decode(addr, size); + + use GlobalRegister::*; + use HPETRegister::*; + (match reg { + Timer(timer, tn_reg) => timer.borrow_mut().read(tn_reg), + Global(CAP) => self.capability.get(), /* including HPET_PERIOD 0x004 */ + Global(CFG) => self.config.get(), + Global(INT_STATUS) => self.int_status.get(), + Global(COUNTER) => { + // TODO: Add trace point + // trace_hpet_ram_read_reading_counter(addr & 4, cur_tick) + if self.is_hpet_enabled() { + self.get_ticks() + } else { + self.counter.get() } } + Unknown(_) => { + // TODO: Add trace point- trace_hpet_ram_read_invalid() + 0 + } + }) >> shift + } + + fn write(&self, addr: hwaddr, value: u64, size: u32) { + let HPETAddrDecode { shift, len, reg } = self.decode(addr, size); + + // TODO: Add trace point - trace_hpet_ram_write(addr, value) + use GlobalRegister::*; + use HPETRegister::*; + match reg { + Timer(timer, tn_reg) => timer.borrow_mut().write(tn_reg, value, shift, len), + Global(CAP) => {} // General Capabilities and ID Register: Read Only + Global(CFG) => self.set_cfg_reg(shift, len, value), + Global(INT_STATUS) => self.set_int_status_reg(shift, len, value), + Global(COUNTER) => self.set_counter_reg(shift, len, value), + Unknown(_) => { + // TODO: Add trace point - trace_hpet_ram_write_invalid() + } } } } From patchwork Sun Mar 9 10:31:16 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008306 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 08FB8C28B28 for ; Sun, 9 Mar 2025 10:35:29 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDxM-0000U4-J0; Sun, 09 Mar 2025 06:32:28 -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 1trDx7-0008Pu-4F for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:13 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDx5-00045L-Mv for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:12 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516331; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nQpu7Fg7nG7FJGPLBMD8H+r3cpml2kmQYbEDHrDsnBc=; b=Zy0ORAhguyXYke04nTbxWUypoqWinlXdM+VhQxhFO3RyRpY0qW768ACWb25rdq8H8VdPlI XHquvV0P8UQqb2XWiEg3jkZysSvK2pcdfZ/5p9cIZ01bOdLWCKXrSP6eBOt56QCh54CH4k TQOSjJGZsL8c2IQ+8WqRkNhPMYdZTxE= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-502-iK4eyUm4P26WTE-5WeIblA-1; Sun, 09 Mar 2025 06:32:09 -0400 X-MC-Unique: iK4eyUm4P26WTE-5WeIblA-1 X-Mimecast-MFC-AGG-ID: iK4eyUm4P26WTE-5WeIblA_1741516328 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43bd0586b86so22431785e9.3 for ; Sun, 09 Mar 2025 03:32:09 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516328; x=1742121128; 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=nQpu7Fg7nG7FJGPLBMD8H+r3cpml2kmQYbEDHrDsnBc=; b=JwjZdx9OF2l/hmBWI0BYufbdpHSnLWCO9WyuI81EgVEJl9D4y6MtIp6CfiZAgz0GIP VHYODTG97RnivhaX5kvNrsTsBaimWvZ6HoL6FH9nT6xZmOzZCwii47miCfu/kdD7xEOP td3OFVBH4GktkzUq52x86o6Zl9ChG++w8iAAHAMjmsob3t3g+ogjPdgNKjwBfDrMF3im sp9XdoUMHiHDPtWpg7uLusOFQ+khxahcWSrHHOsvVPu+WGlUPN7vnOdMqt+0V9IhTjiH D0Nl4d4UjYhsWTyjIN3uaMStHmVgYCshuJAKrE1h25JBPD61tUgpi0v+979QGZzPgyqO B7MQ== X-Gm-Message-State: AOJu0Yx4IeMgo3y7vaaizRXoCGkxEpgJwUnbrCbZ+024dzlxDdnz8hgt ai/PclwYyH+S00sjVwxxDXIkdz787cZ7emHgccGxHDA/Xgi5vybCaZXDabmteojSJP6UPtHGW1h TUrAcHs5gIAn5coXiLWlP8GGlgtARZmbDyX5wVgLzBbrEyAjcKOBzwPhgKV1YWBqr3w+jVOeR9x CENeukQNni9mCVZZ68vtNxq1zW4J7B8REgFzK8iHY= X-Gm-Gg: ASbGncumWpu8j8wb6T1XRxTm14QPu/W24bitGzBfu23uZtObBF9vCubzf1vDf677Rtx BvsMnChoH0qJ5/zORKrFUq7BIoP6HlMiUXMnNHwbJ0F2e2WuAvdhD69BD2EuS0gyhfPwW6GmVD5 fdnxLdnLUBhq4ddY1hNcYIq+Rj1/D4UoBg3J0My5SWGvyZQsXq4SVYB3UXjE7A2eZ/rpl3WHhi/ 69D2Dtu5Vc7fbPqessS0Tbd1R4U+XScQWJhG/INNxZYtiXH7agJ4Xm0wKHwUrDhoEsA4H1nfG4O XrcoB9bpD2T5dPJpJcs2RA== X-Received: by 2002:a05:600c:4fcc:b0:439:30bd:7df9 with SMTP id 5b1f17b1804b1-43c601d93c7mr55904935e9.9.1741516327658; Sun, 09 Mar 2025 03:32:07 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEBE2IQ1lbtcKJtuXjuuudxHWBkQviq0iYHj/tJwtukJQTQWWbUGArhxys10lEYTpYyPVdP7Q== X-Received: by 2002:a05:600c:4fcc:b0:439:30bd:7df9 with SMTP id 5b1f17b1804b1-43c601d93c7mr55904845e9.9.1741516327174; Sun, 09 Mar 2025 03:32:07 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43ce3d5a0e2sm58128765e9.12.2025.03.09.03.32.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:32:06 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 22/25] rust: cell: add full example of declaring a SysBusDevice Date: Sun, 9 Mar 2025 11:31:16 +0100 Message-ID: <20250309103120.1116448-23-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Reviewed-by: Zhao Liu Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/cell.rs | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/rust/qemu-api/src/cell.rs b/rust/qemu-api/src/cell.rs index 448638e8967..ab0785a2692 100644 --- a/rust/qemu-api/src/cell.rs +++ b/rust/qemu-api/src/cell.rs @@ -73,6 +73,34 @@ //! QEMU device implementations is usually incorrect and can lead to //! thread-safety issues. //! +//! ### Example +//! +//! ``` +//! # use qemu_api::prelude::*; +//! # use qemu_api::{c_str, cell::BqlRefCell, irq::InterruptSource, irq::IRQState}; +//! # use qemu_api::{sysbus::SysBusDevice, qom::Owned, qom::ParentField}; +//! # const N_GPIOS: usize = 8; +//! # struct PL061Registers { /* ... */ } +//! # unsafe impl ObjectType for PL061State { +//! # type Class = ::Class; +//! # const TYPE_NAME: &'static std::ffi::CStr = c_str!("pl061"); +//! # } +//! struct PL061State { +//! parent_obj: ParentField, +//! +//! // Configuration is read-only after initialization +//! pullups: u32, +//! pulldowns: u32, +//! +//! // Single values shared with C code use BqlCell, in this case via InterruptSource +//! out: [InterruptSource; N_GPIOS], +//! interrupt: InterruptSource, +//! +//! // Larger state accessed by device methods uses BqlRefCell or Mutex +//! registers: BqlRefCell, +//! } +//! ``` +//! //! ### `BqlCell` //! //! [`BqlCell`] implements interior mutability by moving values in and out of From patchwork Sun Mar 9 10:31:17 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008297 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 5B035C282D1 for ; Sun, 9 Mar 2025 10:34:00 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDxO-0000dI-3K; Sun, 09 Mar 2025 06:32:30 -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 1trDxA-0000BC-8v for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:17 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDx8-00045l-Av for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:15 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516333; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=+11c/N4D4n5nsZ2e2p64dlWgYqM6+Rie5jL418qQFDM=; b=KTuedrZ1LeyyggNy/1uT0KfGKj2JsOrl2Pq//ZNhrtZzage84GjtVJQPXScuD2fsV5kmgM librU7Z9pMXxb6KZnbi0U4laGGr5N0AF5ed70WBmPCXVicJJieAey1abu4QyAa0FOzzn9e moFnFgCyNKVyFROS0akSTsjLaJY7Hw0= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-110-9Y99PB1INtOf-1lOTGr2lQ-1; Sun, 09 Mar 2025 06:32:11 -0400 X-MC-Unique: 9Y99PB1INtOf-1lOTGr2lQ-1 X-Mimecast-MFC-AGG-ID: 9Y99PB1INtOf-1lOTGr2lQ_1741516331 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-3912d5f6689so1974612f8f.1 for ; Sun, 09 Mar 2025 03:32:11 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516330; x=1742121130; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=+11c/N4D4n5nsZ2e2p64dlWgYqM6+Rie5jL418qQFDM=; b=O4oUUsSWJwSwVPNMRkb5fXJfT6gc3uK6qt1vdCjMVcbWTDizvNYPjN07B9+9MgF8tD sk4iRSOQOx66R/7PLfADe+c5GkkPnRt9YF9LSloehgy+LIQE6GeYPxrXT3rX02zOH3QH meJMFggyOv9C/BGkrtOs9Z2lapgg2nOiDJIMK1wHpqnLW4gK6Bmm2Oelzrsv8bD0Sc+8 w9XbeY/FIK5x+ifw0QJrBiR90Dy6xB2fiNWly5Brf+tjV+sAgrB+l9fOUcQrINwvi2x4 NrrrNTgNVOEGNh/M84s5+NjWvAAAmaT1qraEk6JZptzVhsF6hA7BwQHvGdK6uurTWRun oeWQ== X-Gm-Message-State: AOJu0YzGqqFBlvNrDvSqmGua88ASaF/VBrRb6380/1Nc+57G9wFTC85q ZAJTPV1ytw8lw/BHbXzTgD9ocHKScoHKiTvGLiDdR8kuG9u7/1pY8O5v5a8fIyCOaTbyeTDDbJs 75Mz46XzaB/16+XAao3IfL2ufwTTc5h0oC4j8NFguy1grnS041BIoZkoqh+YlKR/QFC/sdOWjR9 WSpcmCMC2+hPCcbUjdEPs72NDiQrv+BPNrRiiLR4A= X-Gm-Gg: ASbGncujUNNngfsO1uydxnC2+hFh+IeMEWgsJXmJ2GHXEIsfyKSt7zEm5QWzR5L2d7d aBWAqVcKRvqiRNXVcqtm0OkNm43VH6H2qNcp5w6/W98cmtWQqdOM8GP/L5JVEQM2LRweZ68J2R9 gAfPxR5VbXINiHwQkzyog05Xqeuy7JwZBQfwG0U9DU8hsrxz3+VXxEG6AOMUAur2uTgvWJq0Q+U qfq30qTkjtKNI+7WP/IvGUlCyzRZOuLV3LREeYLlW+fI03zqaVUqnF3oI3X5R2RDXLURj9kN4ZB 17xXdK60YmdAdLV1sk39gg== X-Received: by 2002:a5d:6483:0:b0:38f:28cb:4d35 with SMTP id ffacd0b85a97d-39132d4e38cmr6390587f8f.13.1741516330206; Sun, 09 Mar 2025 03:32:10 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHyDahsDFJKm03RaFadlSUd4jcH2SDu8CYjbfEAiNNa8zSJjrJr216wdNO99+gnaY5j3TnMxg== X-Received: by 2002:a5d:6483:0:b0:38f:28cb:4d35 with SMTP id ffacd0b85a97d-39132d4e38cmr6390568f8f.13.1741516329647; Sun, 09 Mar 2025 03:32:09 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3912bfba8a9sm11511475f8f.9.2025.03.09.03.32.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:32:08 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Subject: [PULL 23/25] rust: qom: remove operations on &mut Date: Sun, 9 Mar 2025 11:31:17 +0100 Message-ID: <20250309103120.1116448-24-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org The dubious casts of mutable references to objects are not used anymore: the wrappers for qdev_init_clock_in and for IRQ and MMIO initialization can be called directly on the subclasses, without casts, plus they take a shared reference so they can just use "upcast()" instead of "upcast_mut()". Remove them. Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/memory.rs | 5 --- rust/qemu-api/src/prelude.rs | 1 - rust/qemu-api/src/qom.rs | 83 ------------------------------------ rust/qemu-api/tests/tests.rs | 34 +-------------- 4 files changed, 2 insertions(+), 121 deletions(-) diff --git a/rust/qemu-api/src/memory.rs b/rust/qemu-api/src/memory.rs index eff9f09fd7f..fdb1ea11fcf 100644 --- a/rust/qemu-api/src/memory.rs +++ b/rust/qemu-api/src/memory.rs @@ -175,11 +175,6 @@ pub fn init_io>( ) { unsafe { Self::do_init_io( - // self.0.as_mut_ptr() needed because Rust tries to call - // ObjectDeref::as_mut_ptr() on "&mut Self", instead of coercing - // to "&Self" and then calling MemoryRegion::as_mut_ptr(). - // Revisit if/when ObjectCastMut is not needed anymore; it is - // only used in a couple places for initialization. self.0.as_mut_ptr(), owner.cast::(), &ops.0, diff --git a/rust/qemu-api/src/prelude.rs b/rust/qemu-api/src/prelude.rs index 634acf37a85..43bfcd5fcab 100644 --- a/rust/qemu-api/src/prelude.rs +++ b/rust/qemu-api/src/prelude.rs @@ -17,7 +17,6 @@ pub use crate::qom::IsA; pub use crate::qom::Object; pub use crate::qom::ObjectCast; -pub use crate::qom::ObjectCastMut; pub use crate::qom::ObjectDeref; pub use crate::qom::ObjectClassMethods; pub use crate::qom::ObjectMethods; diff --git a/rust/qemu-api/src/qom.rs b/rust/qemu-api/src/qom.rs index 2defbd23516..34d7bc0ef96 100644 --- a/rust/qemu-api/src/qom.rs +++ b/rust/qemu-api/src/qom.rs @@ -463,90 +463,7 @@ unsafe fn unsafe_cast<'a, U: ObjectType>(self) -> &'a U impl ObjectDeref for &T {} impl ObjectCast for &T {} -/// Trait for mutable type casting operations in the QOM hierarchy. -/// -/// This trait provides the mutable counterparts to [`ObjectCast`]'s conversion -/// functions. Unlike `ObjectCast`, this trait returns `Result` for fallible -/// conversions to preserve the original smart pointer if the cast fails. This -/// is necessary because mutable references cannot be copied, so a failed cast -/// must return ownership of the original reference. For example: -/// -/// ```ignore -/// let mut dev = get_device(); -/// // If this fails, we need the original `dev` back to try something else -/// match dev.dynamic_cast_mut::() { -/// Ok(foodev) => /* use foodev */, -/// Err(dev) => /* still have ownership of dev */ -/// } -/// ``` -pub trait ObjectCastMut: Sized + ObjectDeref + DerefMut -where - Self::Target: ObjectType, -{ - /// Safely convert from a derived type to one of its parent types. - /// - /// This is always safe; the [`IsA`] trait provides static verification - /// that `Self` dereferences to `U` or a child of `U`. - fn upcast_mut<'a, U: ObjectType>(self) -> &'a mut U - where - Self::Target: IsA, - Self: 'a, - { - // SAFETY: soundness is declared via IsA, which is an unsafe trait - unsafe { self.unsafe_cast_mut::() } - } - - /// Attempt to convert to a derived type. - /// - /// Returns `Ok(..)` if the object is of type `U`, or `Err(self)` if the - /// object if the conversion failed. This is verified at runtime by - /// checking the object's type information. - fn downcast_mut<'a, U: IsA>(self) -> Result<&'a mut U, Self> - where - Self: 'a, - { - self.dynamic_cast_mut::() - } - - /// Attempt to convert between any two types in the QOM hierarchy. - /// - /// Returns `Ok(..)` if the object is of type `U`, or `Err(self)` if the - /// object if the conversion failed. This is verified at runtime by - /// checking the object's type information. - fn dynamic_cast_mut<'a, U: ObjectType>(self) -> Result<&'a mut U, Self> - where - Self: 'a, - { - unsafe { - // SAFETY: upcasting to Object is always valid, and the - // return type is either NULL or the argument itself - let result: *mut U = - object_dynamic_cast(self.as_object_mut_ptr(), U::TYPE_NAME.as_ptr()).cast(); - - result.as_mut().ok_or(self) - } - } - - /// Convert to any QOM type without verification. - /// - /// # Safety - /// - /// What safety? You need to know yourself that the cast is correct; only - /// use when performance is paramount. It is still better than a raw - /// pointer `cast()`, which does not even check that you remain in the - /// realm of QOM `ObjectType`s. - /// - /// `unsafe_cast::()` is always safe. - unsafe fn unsafe_cast_mut<'a, U: ObjectType>(self) -> &'a mut U - where - Self: 'a, - { - unsafe { &mut *self.as_mut_ptr::().cast::() } - } -} - impl ObjectDeref for &mut T {} -impl ObjectCastMut for &mut T {} /// Trait a type must implement to be registered with QEMU. pub trait ObjectImpl: ObjectType + IsA { diff --git a/rust/qemu-api/tests/tests.rs b/rust/qemu-api/tests/tests.rs index e3985782a38..269122e7ec1 100644 --- a/rust/qemu-api/tests/tests.rs +++ b/rust/qemu-api/tests/tests.rs @@ -2,13 +2,10 @@ // Author(s): Manos Pitsidianakis // SPDX-License-Identifier: GPL-2.0-or-later -use std::{ - ffi::{c_void, CStr}, - ptr::{addr_of, addr_of_mut}, -}; +use std::{ffi::CStr, ptr::addr_of}; use qemu_api::{ - bindings::{module_call_init, module_init_type, object_new, object_unref, qdev_prop_bool}, + bindings::{module_call_init, module_init_type, qdev_prop_bool}, c_str, cell::{self, BqlCell}, declare_properties, define_property, @@ -182,30 +179,3 @@ fn test_cast() { assert_eq!(addr_of!(*sbd_ref), p_ptr.cast()); } } - -#[test] -#[allow(clippy::shadow_unrelated)] -/// Test casts on mutable references. -fn test_cast_mut() { - init_qom(); - let p: *mut DummyState = unsafe { object_new(DummyState::TYPE_NAME.as_ptr()).cast() }; - - let p_ref: &mut DummyState = unsafe { &mut *p }; - let obj_ref: &mut Object = p_ref.upcast_mut(); - assert_eq!(addr_of_mut!(*obj_ref), p.cast()); - - let sbd_ref: Result<&mut SysBusDevice, &mut Object> = obj_ref.dynamic_cast_mut(); - let obj_ref = sbd_ref.unwrap_err(); - - let dev_ref: Result<&mut DeviceState, &mut Object> = obj_ref.downcast_mut(); - let dev_ref = dev_ref.unwrap(); - assert_eq!(addr_of_mut!(*dev_ref), p.cast()); - - // SAFETY: the cast is wrong, but the value is only used for comparison - unsafe { - let sbd_ref: &mut SysBusDevice = obj_ref.unsafe_cast_mut(); - assert_eq!(addr_of_mut!(*sbd_ref), p.cast()); - - object_unref(p_ref.as_object_mut_ptr().cast::()); - } -} From patchwork Sun Mar 9 10:31:18 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008293 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A5FD6C28B28 for ; Sun, 9 Mar 2025 10:33:34 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDxS-0000pq-D7; Sun, 09 Mar 2025 06:32:34 -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 1trDxB-0000Bq-F2 for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:18 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDx9-00045r-Cb for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:17 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516334; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dMUKogfKyzAz46Y4Z8OW5xUGWyWP2F2XLF8CrapiAvY=; b=S1F9lOjCctdCtdqIPB9Jry2i/riAmjCL79E/orUy3hvaRDIXQIs20yczyrMfDXaox4ETBG jUHpg/vpostIhSgaekFd/+QStsyjv9ZfDng9+5p08sm+mEUrTSCQm3C0dBZXDDtZg7xEsd BxZa3fy/NP5oWgI5fnbWVCZrRBoZQbU= Received: from mail-wm1-f72.google.com (mail-wm1-f72.google.com [209.85.128.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-364-STkgT4KGN5m1HWmZ2CCzfg-1; Sun, 09 Mar 2025 06:32:13 -0400 X-MC-Unique: STkgT4KGN5m1HWmZ2CCzfg-1 X-Mimecast-MFC-AGG-ID: STkgT4KGN5m1HWmZ2CCzfg_1741516332 Received: by mail-wm1-f72.google.com with SMTP id 5b1f17b1804b1-43cf3168b87so1391965e9.2 for ; Sun, 09 Mar 2025 03:32:13 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516332; x=1742121132; 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=dMUKogfKyzAz46Y4Z8OW5xUGWyWP2F2XLF8CrapiAvY=; b=xK8wfSgDiv3NZ7d/XSSLzflAJj8ug+f12XWYUmklKtS9q0YB9Mf2E+EWwGXcpeyYQT K3Do665ywQwIIcNOdHS7v+SKQu7tX6Uz8oAw2RLUSPSYRy/tm7zUYiF7MtBhLwF/eQQ1 /V6SnW77vs7w7zz/5p/Z3rJgThmpKBQaDjPIPzOQ81pWebILzqXQbN7nliJn1qNL3Ssy 3bIRsAoTo1Vi7IhFzaE9YDXhTWwDmzuRceLpZlXntrDQ1+phxRFt5WLyjSFT1YD3dla0 9hnf381sUUb8YwiqF/F3vQbCOEbzGfvxIys70D57MKMrfKrTIiwwF22EG5oMncjugUyZ Wydw== X-Gm-Message-State: AOJu0YzCZLEow6RZDjpO6okyNKkfhw9gNu3LxEP0N/P3MWtzwFXeI5vf 3gfW+sW+4N8kfYH1gCiaJsBABX6fU/1dDpgTOGk3ABr20kjSxBEcRrRRxwQMhnCuGsufS0ImK+q 8+Uktu6GLbsi5aifarpl5u4uFkqX4j8J+nLB0bCpUV4jzYolhKGaMzJ1etnDY3ZZZY1B6A+f8BR cj8vSq4Ehj4iduCe4RrTeO2vCijk91uwDnk+X+pMY= X-Gm-Gg: ASbGncvd/doq8C1ME56KJOUrGzy1e+6jK07gg4QejOcEwpHAW1OBdw+rLab0PRPeWB6 /6kxgjcOyTIZUX3CGXcMfXuxFU+3hMuPxCKdYhBrvAZEn1Qf4CUUoEcXfXxDEcELZlc6B8ME4Ca Yxx7vZsnecaJa5vwixwEP+VERCGzlsSFIlAQWNT6enFN3BelCkSPBPC+rdc0ust4vkwZ0jB13/N wFR8U/FM1msP5Jyr9Jyj7I5XgQyw2vVHnkx7+kudT41cZwOz20j2MFxjzFTZdB/xjaOgsJnCLvI 1BXt8eNK4IFVHesx4hA+ZA== X-Received: by 2002:a05:600c:19cd:b0:43c:f1b8:16ad with SMTP id 5b1f17b1804b1-43cf1b81b78mr9503155e9.30.1741516331920; Sun, 09 Mar 2025 03:32:11 -0700 (PDT) X-Google-Smtp-Source: AGHT+IH3i7HQ3BfMVkTqOhiH/ic9cHN5EaI1ROqBFR5mD3dFqHP7nZMruL9PBgJiwzGxWf86YzeFIA== X-Received: by 2002:a05:600c:19cd:b0:43c:f1b8:16ad with SMTP id 5b1f17b1804b1-43cf1b81b78mr9503005e9.30.1741516331476; Sun, 09 Mar 2025 03:32:11 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43ce3d5a0e2sm58130275e9.12.2025.03.09.03.32.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:32:10 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: =?utf-8?q?Alex_Benn=C3=A9e?= , =?utf-8?q?Daniel_?= =?utf-8?q?P=2E_Berrang=C3=A9?= Subject: [PULL 24/25] meson.build: default to -gsplit-dwarf for debug info Date: Sun, 9 Mar 2025 11:31:18 +0100 Message-ID: <20250309103120.1116448-25-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Alex Bennée This option is supported by both gcc (since 4.7) and clang (since 7.0). Not only does this make the linkers job easier by reducing the amount of ELF it needs to parse it also reduces the total build size quite considerably. In my case a default build went from 5.8G to 3.9G (vs 1.9G for --disable-debug-info). The --disable-split-debug option allows distros to keep all the info together for ease of packaging. Signed-off-by: Alex Bennée Reviewed-by: Daniel P. Berrangé Link: https://lore.kernel.org/r/20250306161631.2477685-1-alex.bennee@linaro.org Signed-off-by: Paolo Bonzini --- meson.build | 6 ++++++ meson_options.txt | 2 ++ scripts/meson-buildoptions.sh | 2 ++ 3 files changed, 10 insertions(+) diff --git a/meson.build b/meson.build index 6da4eb317c2..4899d896de0 100644 --- a/meson.build +++ b/meson.build @@ -601,6 +601,10 @@ if get_option('tsan') qemu_ldflags = ['-fsanitize=thread'] + qemu_ldflags endif +if get_option('debug') and get_option('split_debug') + qemu_cflags += '-gsplit-dwarf' +endif + # Detect support for PT_GNU_RELRO + DT_BIND_NOW. # The combination is known as "full relro", because .got.plt is read-only too. qemu_ldflags += cc.get_supported_link_arguments('-Wl,-z,relro', '-Wl,-z,now') @@ -4583,6 +4587,8 @@ if have_rust summary_info += {'bindgen': bindgen.full_path()} summary_info += {'bindgen version': bindgen.version()} endif +# option_cflags is purely for the summary display, meson will pass +# -g/-O options directly option_cflags = (get_option('debug') ? ['-g'] : []) if get_option('optimization') != 'plain' option_cflags += ['-O' + get_option('optimization')] diff --git a/meson_options.txt b/meson_options.txt index 59d973bca00..3432123fee2 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -362,6 +362,8 @@ option('debug_mutex', type: 'boolean', value: false, description: 'mutex debugging support') option('debug_stack_usage', type: 'boolean', value: false, description: 'measure coroutine stack usage') +option('split_debug', type: 'boolean', value: true, + description: 'split debug info from object files') option('qom_cast_debug', type: 'boolean', value: true, description: 'cast debugging support') option('slirp_smbd', type : 'feature', value : 'auto', diff --git a/scripts/meson-buildoptions.sh b/scripts/meson-buildoptions.sh index 3e8e00852b2..aca6e688302 100644 --- a/scripts/meson-buildoptions.sh +++ b/scripts/meson-buildoptions.sh @@ -504,6 +504,8 @@ _meson_option_parse() { --disable-strict-rust-lints) printf "%s" -Dstrict_rust_lints=false ;; --enable-strip) printf "%s" -Dstrip=true ;; --disable-strip) printf "%s" -Dstrip=false ;; + --enable-split-debug) printf "%s" -Dsplit_debug=true ;; + --disable-split-debug) printf "%s" -Dsplit_debug=false ;; --sysconfdir=*) quote_sh "-Dsysconfdir=$2" ;; --enable-tcg) printf "%s" -Dtcg=enabled ;; --disable-tcg) printf "%s" -Dtcg=disabled ;; From patchwork Sun Mar 9 10:31:19 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 14008295 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 24EF3C282D1 for ; Sun, 9 Mar 2025 10:33:46 +0000 (UTC) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1trDxN-0000Yx-Bk; Sun, 09 Mar 2025 06:32:29 -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 1trDxD-0000FV-KB for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:19 -0400 Received: from us-smtp-delivery-124.mimecast.com ([170.10.133.124]) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1trDxB-00046B-Vn for qemu-devel@nongnu.org; Sun, 09 Mar 2025 06:32:19 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1741516337; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=04PJRmuUiucourfgT/J1T0+xS+Kfg0driBOXjjm6/8k=; b=BWelvljqiE9D3vhlod2js8v/a3OokgjKOY3rbvMpwPJjCk4T/yZEE9axHibkQJ2M2wxFDx XbDU08d/2zEucEwSLWYQ8fd0RH4NJezFquWc6l8yJfQII23hwgSmicFU2BgVGXqsaTFInP p3J3ZXOw6XFp2SaPq3L5mfXcCLozD/A= Received: from mail-wm1-f70.google.com (mail-wm1-f70.google.com [209.85.128.70]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-410-eU8B3-oANgWy4P1-lqIYUg-1; Sun, 09 Mar 2025 06:32:16 -0400 X-MC-Unique: eU8B3-oANgWy4P1-lqIYUg-1 X-Mimecast-MFC-AGG-ID: eU8B3-oANgWy4P1-lqIYUg_1741516335 Received: by mail-wm1-f70.google.com with SMTP id 5b1f17b1804b1-43cf6c03535so373155e9.0 for ; Sun, 09 Mar 2025 03:32:16 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1741516334; x=1742121134; 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=04PJRmuUiucourfgT/J1T0+xS+Kfg0driBOXjjm6/8k=; b=faId3iJ5Tiw7USSCs99JUB1wPkTFTmMpHWA1PbIeRMPl1m3IreoLGu6uYkysmlBAz1 X+VkE2nbW/IAOabxXcuR8vRmOgEAAldlgne95sfsk5JXrkpMm2FwJ85r3yKOiMc9CBJk 3aQk625iGdj/Ttx1IBmh4zvesYxiwI4O096htUSCEkDyw6AOqK3XWhWP3CvLWBVeswy4 /jiEsZcOL6K454BzZhOUbDCo88SAMT+r20mFIQ8EIvIixeF5pH6AvwG5IedJDTS6SsqC reauUiWZf91h2Hjf5r0eDfGbFlJzP3M3B4T+DI9v5GyQq8sgU1OrHvqWG6beCdRVcclb Q2bw== X-Gm-Message-State: AOJu0YxzPqodbSzChPhy08w0nCX1o1oi+hpSloKU37ApzWYZdLBEpTon 5eLTyiw4YFEaLIDsu0M5n+cMtYyOrRenmbGKoVzGUBbjZMMvewBapY3P2cpUgfwDBYJZKaH43VX nmLjfRmsTzuYEGKpeYGLtFMoP/p0tJgQpGpoJoNuc7a0dm7zDsf2xJrSYxOKI0RTu/+7oGpLFBG jcV5qGP1oX8LZDGoWKZmYVnQs51kJCLVY+FJp8HyA= X-Gm-Gg: ASbGncuBDGQaXRf8KvU6HHHVNOwZItAeFTOFZj58m56FZTqeCXvRNDuZFAcVbREJ4x+ GkBGnlQc9vy3Mc/FAjWRFdqjZz98HnnyJmNlm/Eh2S1a9ox1HziXmDM4uQ7DlsIl1StjUiGwhLu ljHJ/ClmHa7ZJIa0KeT1l+Qk2WgK3NqMvMEjnw3+LdSOA8Mhgy1jnnV8vwIrpJDCPBzZPXcw47e GTNav4Io+UByPa/KBZpThfxM1Kyd0J/IBjwvqkbXv/0mp9v/cGwDdKrpxm2emEy2UVCnCj5KgVh MeKgDwtlcZ/+vC0o5Jqlmw== X-Received: by 2002:a05:600c:3510:b0:43b:cf12:2ca5 with SMTP id 5b1f17b1804b1-43c601d9145mr57763075e9.8.1741516334382; Sun, 09 Mar 2025 03:32:14 -0700 (PDT) X-Google-Smtp-Source: AGHT+IEg58JPD3eO13I8Q7YpVRP4M0Qc8+j/cGJObbGoPvO8WabBqZjwqRAsWCWFheYT/ahYE8QNXQ== X-Received: by 2002:a05:600c:3510:b0:43b:cf12:2ca5 with SMTP id 5b1f17b1804b1-43c601d9145mr57762905e9.8.1741516333928; Sun, 09 Mar 2025 03:32:13 -0700 (PDT) Received: from [192.168.10.48] ([176.206.122.167]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-43bdd9471b7sm109267005e9.34.2025.03.09.03.32.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 09 Mar 2025 03:32:12 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Peter Maydell , =?utf-8?q?Philippe_Mathieu-Dau?= =?utf-8?q?d=C3=A9?= Subject: [PULL 25/25] rust: pl011: Allow NULL chardev argument to pl011_create() Date: Sun, 9 Mar 2025 11:31:19 +0100 Message-ID: <20250309103120.1116448-26-pbonzini@redhat.com> X-Mailer: git-send-email 2.48.1 In-Reply-To: <20250309103120.1116448-1-pbonzini@redhat.com> References: <20250309103120.1116448-1-pbonzini@redhat.com> MIME-Version: 1.0 Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.001, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_NONE=-0.0001, RCVD_IN_MSPIKE_H2=0.001, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=0.001, 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+qemu-devel=archiver.kernel.org@nongnu.org Sender: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org From: Peter Maydell It's valid for the caller to pass a NULL chardev to pl011_create(); this means "don't set the chardev property on the device", which in turn means "act like there's no chardev". All the chardev frontend APIs (in C, at least) accept a NULL pointer to mean "do nothing". This fixes some failures in 'make check-functional' when Rust support is enabled. Signed-off-by: Peter Maydell Reviewed-by: Philippe Mathieu-Daudé Link: https://lore.kernel.org/r/20250307190051.3274226-1-peter.maydell@linaro.org Signed-off-by: Paolo Bonzini --- rust/hw/char/pl011/src/device.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/rust/hw/char/pl011/src/device.rs b/rust/hw/char/pl011/src/device.rs index af93ae8bebe..f137b49feaf 100644 --- a/rust/hw/char/pl011/src/device.rs +++ b/rust/hw/char/pl011/src/device.rs @@ -648,10 +648,12 @@ pub fn post_load(&self, _version_id: u32) -> Result<(), ()> { // SAFETY: The callers promise that they have owned references. // They do not gift them to pl011_create, so use `Owned::from`. let irq = unsafe { Owned::::from(&*irq) }; - let chr = unsafe { Owned::::from(&*chr) }; let dev = PL011State::new(); - dev.prop_set_chr("chardev", &chr); + if !chr.is_null() { + let chr = unsafe { Owned::::from(&*chr) }; + dev.prop_set_chr("chardev", &chr); + } dev.sysbus_realize(); dev.mmio_map(0, addr); dev.connect_irq(0, &irq);