From nobody Wed Apr 2 14:32:16 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1742582455; cv=none; d=zohomail.com; s=zohoarc; b=RsHqSD7DecKQWsUzdsHMfEVDhqVqk0Pokcs2CJE5HQRcPyzKJaaN8Muw7gnn97lHxxt7cU6XRmoSf4bfjHWxKRbAiWXRM1Vi4uLXhk6TxDlGP6vTz5YQLAh2IuhHXUMr8bybpuympA/4FZeOjUsrexD5vIG8+3AjsuvcipgM1kM= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1742582455; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=zxHQkV48tuPPh4skSGkR+Kk+7dztE2eJ25IcFhaYuDw=; b=ZlruYhast3h/taV6CuWTiFWLZRiSg/fmaLXGBNfDC0cwWatB3p+bXDe6+hdPJ0EtbzM73HACT1WsLZ64lXQumaqX6FLBwcqH+QIOgURidtmzPYvwWvjNwqeq2UnxFu0NnlRKjejmjbnarVcKK9I7HTR5CxjTImgUxxHpgKTOGT0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1742582455192532.8192759444086; Fri, 21 Mar 2025 11:40:55 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1tvhFT-0004GP-Un; Fri, 21 Mar 2025 14:37:41 -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 1tvhEs-0003NV-6I for qemu-devel@nongnu.org; Fri, 21 Mar 2025 14:37:07 -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 1tvhEo-000780-O6 for qemu-devel@nongnu.org; Fri, 21 Mar 2025 14:37:00 -0400 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-670-Wxv2xBd8PEyIJkCpbaS6AA-1; Fri, 21 Mar 2025 14:36:49 -0400 Received: by mail-wr1-f70.google.com with SMTP id ffacd0b85a97d-3914bc0cc4aso1156855f8f.3 for ; Fri, 21 Mar 2025 11:36:48 -0700 (PDT) Received: from [192.168.122.1] ([151.49.194.153]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3997f995789sm3089435f8f.17.2025.03.21.11.36.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Fri, 21 Mar 2025 11:36:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1742582218; 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=zxHQkV48tuPPh4skSGkR+Kk+7dztE2eJ25IcFhaYuDw=; b=hnF922Ubj75bJf5JnfasYewTPXH3KZ2fYeKdfjsBgVKUO/LDniL1AZuzaLPQYKs930dH+H roVthlvZav7MN+fR5s+67TMV9fkQcSxG2HIMb4SnMWwh/ekwzN0oLVcjBwK6o50H0RRsem dDoGt8Kp5Iu6dTEgJKC5roYv8Nsl+0M= X-MC-Unique: Wxv2xBd8PEyIJkCpbaS6AA-1 X-Mimecast-MFC-AGG-ID: Wxv2xBd8PEyIJkCpbaS6AA_1742582208 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742582207; x=1743187007; 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=zxHQkV48tuPPh4skSGkR+Kk+7dztE2eJ25IcFhaYuDw=; b=E2bpMdjzu+ofaWiFFvScHqUObZHGiucK87Xle3eFFSjkou8ZqzaEwPyBbs67MssbSM j+5+Nk9xOelBaTDbEe00XwhuKhvujdxNPU/1bkgPb6fYbU4EpuFSH/HxibGsGHefwOrP NNYW1ZXE7NYaFVjVKVDheki8QR3xP03jnk2t94doH9Q3z7lLo4tDc1vtCKQbIQvCewn6 gQZxDvmZignb7XPKRLSQW00FGuarfRuy/xNcNFktxanpRqqQUzK5R6EKkYuCDxigjIgh C/9XZRruP90TPgiBs7kKRTnl5XxYXW4nWEWVVl2QQ3kpM3ssQzNcWXti1YSVBmmdQN/t q5Fg== X-Gm-Message-State: AOJu0YwQ35ky9qsPVy8ZmOMbcqyqVhWFnzAeZUW1aG/VH/1wSiatlPl6 73SqoOWmIc58vTlKlAH1rtBMliXHcU7NI5Aov4ysdREhB9mg0QDIJ4FWURKbmgN1+5NcyARLyy1 e+8mdLkQ4zKStFiTrIrmTaiqPSJ28FCdup8shnf4iK3AFHVA68VTRbuMssDEY2WhBmcDD2/pugs 79bfOkUGPEF7LttHbzoW3wLpULmSJ29ZLWKvCm X-Gm-Gg: ASbGncsfJGQ/R3QmutVyo5/ObYGlMBzxvUIG1DFTi6LaccQWWLYBz7CvQCYVCXgVnLc JxFN115CTGBKEu6RjrXwG3xPhZA0MUKpovo8wMwjX3i8zvHzVGZ8hhKqvjcEZkZ2w02wDU78/LW dp2l+WecU1r6Fcl7mw8vyV8saDxfMe+zuPzpDyhpgsdXTSKOcvKaCZHF8KfKoi9fNevXCxVie6z 0SLDf6AMuTaoyUtairyTq6/Al7v6s3i/Rf8f37PHUAgb1IB0eWeEGckklcDkTHn+mveX/ClOixS llZDrtGa87Fzrv7UircH X-Received: by 2002:a5d:6d88:0:b0:391:1473:336a with SMTP id ffacd0b85a97d-3997f937d76mr4210009f8f.36.1742582206816; Fri, 21 Mar 2025 11:36:46 -0700 (PDT) X-Google-Smtp-Source: AGHT+IGdmEXaFsqQICMncMlB+Im2KoVQ0WuRm+oQI7eQBf/kavf0U6/RvXqgRMDxpjx7DUDCoTL14A== X-Received: by 2002:a5d:6d88:0:b0:391:1473:336a with SMTP id ffacd0b85a97d-3997f937d76mr4209992f8f.36.1742582206284; Fri, 21 Mar 2025 11:36:46 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Cc: Zhao Liu Subject: [PULL 18/24] rust/vmstate: Support vmstate_validate Date: Fri, 21 Mar 2025 19:35:50 +0100 Message-ID: <20250321183556.155097-19-pbonzini@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250321183556.155097-1-pbonzini@redhat.com> References: <20250321183556.155097-1-pbonzini@redhat.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=pbonzini@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -23 X-Spam_score: -2.4 X-Spam_bar: -- X-Spam_report: (-2.4 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.332, 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+importer=patchew.org@nongnu.org Sender: qemu-devel-bounces+importer=patchew.org@nongnu.org X-ZohoMail-DKIM: pass (identity @redhat.com) X-ZM-MESSAGEID: 1742582456712019100 Content-Type: text/plain; charset="utf-8" From: Zhao Liu In C version, VMSTATE_VALIDATE accepts the function pointer, which is used to check if some conditions of structure could meet, although the C version macro doesn't accept any structure as the opaque type. But it's hard to integrate VMSTATE_VALIDAE into vmstate_struct, a new macro has to be introduced to specifically handle the case corresponding to VMSTATE_VALIDATE. One of the difficulties is inferring the type of a callback by its name `test_fn`. We can't directly use `test_fn` as a parameter of test_cb_builder__() to get its type "F", because in this way, Rust compiler will be too conservative on drop check and complain "the destructor for this type cannot be evaluated in constant functions". Fortunately, PhantomData could help in this case, because it is considered to never have a destructor, no matter its field type [*]. The `phantom__()` in the `call_func_with_field` macro provides a good example of using PhantomData to infer type. So copy this idea and apply it to the `vmstate_validate` macro. [*]: https://doc.rust-lang.org/std/ops/trait.Drop.html#drop-check Signed-off-by: Zhao Liu Link: https://lore.kernel.org/r/20250318130219.1799170-11-zhao1.liu@intel.c= om Signed-off-by: Paolo Bonzini --- rust/qemu-api/src/vmstate.rs | 52 +++++++++++++++++++++++++++++++++++- 1 file changed, 51 insertions(+), 1 deletion(-) diff --git a/rust/qemu-api/src/vmstate.rs b/rust/qemu-api/src/vmstate.rs index 01f06ed7379..9740931fb16 100644 --- a/rust/qemu-api/src/vmstate.rs +++ b/rust/qemu-api/src/vmstate.rs @@ -25,9 +25,12 @@ //! functionality that is missing from `vmstate_of!`. =20 use core::{marker::PhantomData, mem, ptr::NonNull}; +use std::os::raw::{c_int, c_void}; =20 pub use crate::bindings::{VMStateDescription, VMStateField}; -use crate::{bindings::VMStateFlags, prelude::*, qom::Owned, zeroable::Zero= able}; +use crate::{ + bindings::VMStateFlags, callbacks::FnCall, prelude::*, qom::Owned, zer= oable::Zeroable, +}; =20 /// This macro is used to call a function with a generic argument bound /// to the type of a field. The function must take a @@ -508,6 +511,53 @@ macro_rules! vmstate_fields { }} } =20 +pub extern "C" fn rust_vms_test_field_exists FnCall<(&'a T, = u8), bool>>( + opaque: *mut c_void, + version_id: c_int, +) -> bool { + let owner: &T =3D unsafe { &*(opaque.cast::()) }; + let version: u8 =3D version_id.try_into().unwrap(); + // SAFETY: the opaque was passed as a reference to `T`. + F::call((owner, version)) +} + +pub type VMSFieldExistCb =3D unsafe extern "C" fn( + opaque: *mut std::os::raw::c_void, + version_id: std::os::raw::c_int, +) -> bool; + +#[doc(alias =3D "VMSTATE_VALIDATE")] +#[macro_export] +macro_rules! vmstate_validate { + ($struct_name:ty, $test_name:expr, $test_fn:expr $(,)?) =3D> { + $crate::bindings::VMStateField { + name: ::std::ffi::CStr::as_ptr($test_name), + field_exists: { + const fn test_cb_builder__< + T, + F: for<'a> $crate::callbacks::FnCall<(&'a T, u8), bool= >, + >( + _phantom: ::core::marker::PhantomData, + ) -> $crate::vmstate::VMSFieldExistCb { + let _: () =3D F::ASSERT_IS_SOME; + $crate::vmstate::rust_vms_test_field_exists:: + } + + const fn phantom__(_: &T) -> ::core::marker::PhantomDat= a { + ::core::marker::PhantomData + } + Some(test_cb_builder__::<$struct_name, _>(phantom__(&$test= _fn))) + }, + flags: $crate::bindings::VMStateFlags( + $crate::bindings::VMStateFlags::VMS_MUST_EXIST.0 + | $crate::bindings::VMStateFlags::VMS_ARRAY.0, + ), + num: 0, // 0 elements: no data, only run test_fn callback + ..$crate::zeroable::Zeroable::ZERO + } + }; +} + /// A transparent wrapper type for the `subsections` field of /// [`VMStateDescription`]. /// --=20 2.49.0