From nobody Fri Jan 9 08:49:51 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org ARC-Seal: i=1; a=rsa-sha256; t=1766970364; cv=none; d=zohomail.com; s=zohoarc; b=Px2cjOXD9+8S85bHHNaus2idONS4Q2QVrpAJEyFttGEo4345K1RF5qv/5OiQb1055gghbtaNxOPLpfKd5PgHAM1j1UKq12uKX1bLt2FaQTYrVuOflZjkleASvSVoNnVQcDPxaKezDJDZCbg1lF0HkJdxmRBOrDiRuvbX7lYXJtE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1766970364; h=Content-Type:Content-Transfer-Encoding:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Owner:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:Reply-To:Reply-To:References:Subject:Subject:To:To:Message-Id:Cc; bh=vKhuctd6aFAIYwCk0vbcnYhhzY4GHvhxWjfOICdhn2U=; b=ahQQ1K4yprkt2i5g9Ups6sb3dLJClB/S5eDHIc8Y25J1I+fX5EjtNxY7iBKTpv+cyuD+wL3H6abBBIawEQJePFYAEBbMMh83Rvokret1eEYdbWjPqA3ZZ+0r130YS86I4/1Ia2VT+HeOFuLiUDu9X9UikS2ECI+lIhGEYP8TFr4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; dmarc=pass header.from= (p=reject dis=none) Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 1766970364801764.7921475922305; Sun, 28 Dec 2025 17:06:04 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id BC6813F31C; Sun, 28 Dec 2025 20:05:59 -0500 (EST) Received: from [172.19.199.83] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id D850B41A07; Sun, 28 Dec 2025 20:01:09 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 8F374417F8; Sun, 28 Dec 2025 18:49:50 -0500 (EST) Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id CC9BD418CA for ; Sun, 28 Dec 2025 18:41:22 -0500 (EST) Received: from mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (ec2-35-165-154-97.us-west-2.compute.amazonaws.com [35.165.154.97]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-49-0mCVV_NjM864gaKz65wy1Q-1; Sun, 28 Dec 2025 18:41:21 -0500 Received: from mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.93]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 563411800657 for ; Sun, 28 Dec 2025 23:41:20 +0000 (UTC) Received: from harajuku.usersys.redhat.com.homenet.telecomitalia.it (unknown [10.45.224.19]) by mx-prod-int-06.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 98D751800367 for ; Sun, 28 Dec 2025 23:41:19 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1766965282; 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=vKhuctd6aFAIYwCk0vbcnYhhzY4GHvhxWjfOICdhn2U=; b=hDsBYX1Oi56nBG2VaiEwzXp565frUXJtFZ6JlPJU2VgIl6N9hZ8gtAozOGC+RoEJWM+etN E6x7PQPRtKTxpbughHXXWZV3lmFN55ggMxyS3ac+gBMRqHLCpWdc2Fu4mZAmrH9jXI+RKp DaCCDQh7rIVPXn/mRLc+PNaxFkKu2UQ= X-MC-Unique: 0mCVV_NjM864gaKz65wy1Q-1 X-Mimecast-MFC-AGG-ID: 0mCVV_NjM864gaKz65wy1Q_1766965280 To: devel@lists.libvirt.org Subject: [PATCH 24/29] qemu_firmware: Update matching logic for ROMs Date: Mon, 29 Dec 2025 00:40:43 +0100 Message-ID: <20251228234048.1711701-25-abologna@redhat.com> In-Reply-To: <20251228234048.1711701-1-abologna@redhat.com> References: <20251228234048.1711701-1-abologna@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.93 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 83XbcWlbaQOknm11vAem1t5Q90UIOPiI-huNtazmx38_1766965280 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: quoted-printable Message-ID-Hash: GFMFB35632FCXSFLBCT5QUYALZY367ZC X-Message-ID-Hash: GFMFB35632FCXSFLBCT5QUYALZY367ZC X-MailFrom: abologna@redhat.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: From: Andrea Bolognani via Devel Reply-To: Andrea Bolognani X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1766970365868158500 Content-Type: text/plain; charset="utf-8"; x-default="true" Now that NVRAM can be used together with ROM firmware builds, we need to update the matching logic so that it behaves correctly in all scenarios. This effectively involves taking the logic we currently use when matching firmware descriptors for pflash builds and replicating it pretty much verbatim. The only real difference is that read/write loaders can, by definition, never match. Signed-off-by: Andrea Bolognani --- src/qemu/qemu_firmware.c | 76 ++++++++++++++++++++++++++++++++++++---- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/src/qemu/qemu_firmware.c b/src/qemu/qemu_firmware.c index 0504eef727..f56a4977cf 100644 --- a/src/qemu/qemu_firmware.c +++ b/src/qemu/qemu_firmware.c @@ -1009,6 +1009,12 @@ qemuFirmwareMatchesPaths(const qemuFirmware *fw, if (loader && loader->path && !virFileComparePaths(loader->path, memory->executable.filename= )) return false; + if (loader && loader->nvramTemplate) { + if (memory->mode !=3D QEMU_FIRMWARE_MEMORY_MODE_SPLIT) + return false; + if (!virFileComparePaths(loader->nvramTemplate, memory->nvram_= template.filename)) + return false; + } break; case QEMU_FIRMWARE_DEVICE_NONE: case QEMU_FIRMWARE_DEVICE_LAST: @@ -1457,32 +1463,88 @@ qemuFirmwareMatchDomain(const virDomainDef *def, } } } else if (fw->mapping.device =3D=3D QEMU_FIRMWARE_DEVICE_MEMORY) { + const qemuFirmwareMappingMemory *memory =3D &fw->mapping.data.memo= ry; + if (loader && loader->type && loader->type !=3D VIR_DOMAIN_LOADER_TYPE_ROM) { VIR_DEBUG("Discarding rom loader"); return false; } =20 - if (loader && loader->stateless =3D=3D VIR_TRISTATE_BOOL_NO) { + /* Explicit requests for either a stateless or stateful + * firmware should be fulfilled, but if no preference is + * provided either one is fine as long as the other match + * criteria are satisfied */ + if (loader && + loader->stateless =3D=3D VIR_TRISTATE_BOOL_NO && + memory->mode =3D=3D QEMU_FIRMWARE_MEMORY_MODE_STATELESS) { VIR_DEBUG("Discarding stateless loader"); return false; } + if (loader && + loader->stateless =3D=3D VIR_TRISTATE_BOOL_YES && + memory->mode !=3D QEMU_FIRMWARE_MEMORY_MODE_STATELESS) { + VIR_DEBUG("Discarding non-stateless loader"); + return false; + } =20 if (loader && loader->readonly =3D=3D VIR_TRISTATE_BOOL_NO) { VIR_DEBUG("Discarding readonly loader"); return false; } =20 - if (loader && loader->nvram && - (loader->nvram->path || loader->nvram->format)) { - VIR_DEBUG("Discarding rom loader (nvram configured)"); + if (STRNEQ(memory->executable.format, "raw")) { + VIR_DEBUG("Discarding loader with unsupported executable forma= t '%s'", + memory->executable.format); return false; } - if (loader && - (loader->nvramTemplate || loader->nvramTemplateFormat)) { - VIR_DEBUG("Discarding rom loader (nvram template configured)"); + if (loader && loader->format && + STRNEQ(memory->executable.format, virStorageFileFormatTypeToSt= ring(loader->format))) { + VIR_DEBUG("Discarding loader with mismatching executable forma= t '%s' !=3D '%s'", + memory->executable.format, + virStorageFileFormatTypeToString(loader->format)); return false; } + if (memory->mode =3D=3D QEMU_FIRMWARE_MEMORY_MODE_SPLIT) { + if (STRNEQ(memory->nvram_template.format, "json")) { + VIR_DEBUG("Discarding loader with unsupported nvram templa= te format '%s'", + memory->nvram_template.format); + return false; + } + if (loader && loader->nvramTemplateFormat && + STRNEQ(memory->nvram_template.format, virStorageFileFormat= TypeToString(loader->nvramTemplateFormat))) { + VIR_DEBUG("Discarding loader with mismatching nvram templa= te format '%s' !=3D '%s'", + memory->nvram_template.format, + virStorageFileFormatTypeToString(loader->format)= ); + return false; + } + /* If nvram.format was specified and no other information + * that can influence firmware selection was, then treat it + * the same as if nvram.templateFormat had been specified. + * This ensures that continues to work + * as a shorthand while not getting in the way otherwise */ + if (loader && loader->nvram && loader->nvram->format && + !loader->readonly && !loader->type && !loader->secure && + !loader->stateless && !loader->format && !loader->path && + !loader->nvramTemplateFormat && !loader->nvramTemplate && + STRNEQ(memory->nvram_template.format, virStorageFileFormat= TypeToString(loader->nvram->format))) { + VIR_DEBUG("Discarding loader with mismatching nvram templa= te format '%s' !=3D '%s'", + memory->nvram_template.format, + virStorageFileFormatTypeToString(loader->nvram->= format)); + return false; + } + } else { + if (loader && loader->nvram && + (loader->nvram->path || loader->nvram->format)) { + VIR_DEBUG("Discarding non split loader (nvram configured)"= ); + return false; + } + if (loader && + (loader->nvramTemplate || loader->nvramTemplateFormat)) { + VIR_DEBUG("Discarding non split loader (nvram template con= figured)"); + return false; + } + } } =20 if (def->sec) { --=20 2.52.0