From nobody Sun Jul 26 12:33:35 2026 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=1782280571; cv=none; d=zohomail.com; s=zohoarc; b=PnVijTyY1k+YpsQh0ovv5PXxZLLOdSTl6YurVKJTJWShs+6OFTxTOkv70ffTsGekjxrsmfuCnmpWCgV9gjiHAPSaCHhfW7ktAo7bwid3+3eSILFs2p63DURNA2sKd/5vR5kINAz+IoumcD+kY/r47EmYI3BvxuiKPcERvCcweds= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782280571; 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=L1uvo9RPO6TNl4nAj04B5KNyUa4/1mdy4K3DUeLED7o=; b=n13toLgsTnk6UKkrElG7aKcwUpR+2UQT3JkSw46mievd/zHwFNqFU+qhi76fQs1Xvlxb1VzFJApVv3kCvplYBGuVsRU1w4FSEMZflO4ZxLFyH8VWlu40O1EIWoord6l7zGh/NrwSIOI6EjtI0oQpL5r54fDvOkBeWwlGSVifcKc= 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1782280571236976.0643374910045; Tue, 23 Jun 2026 22:56:11 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wcGZ4-00070W-A1; Wed, 24 Jun 2026 01:54:22 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wcGZ2-000704-Cw for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:20 -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 1wcGZ0-00062U-6g for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:20 -0400 Received: from mail-dy1-f200.google.com (mail-dy1-f200.google.com [74.125.82.200]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-629-CuefhXN0P4-tQZl2zGArhA-1; Wed, 24 Jun 2026 01:54:15 -0400 Received: by mail-dy1-f200.google.com with SMTP id 5a478bee46e88-30c108c19d4so807735eec.0 for ; Tue, 23 Jun 2026 22:54:15 -0700 (PDT) Received: from rhel9-box.lan ([110.227.100.91]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-30c1bd8d6edsm21075803eec.14.2026.06.23.22.54.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 22:54:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782280457; 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=L1uvo9RPO6TNl4nAj04B5KNyUa4/1mdy4K3DUeLED7o=; b=IDUjDTzhbhA0REFcF9leUYRgarwOHxkwZgtKsjmZDm3YxRZ/FIIt6GSl2OL4ZUP8ZsC3Dp YG0q1GixtCPy7OVUJGfu+jG32dz5bso+ndxpzdFW9pTCvC5B1ewzMCDM9l77kwI+n625pd RSKajQGbaB/b70t5nFAsD/pT8GW7NTk= X-MC-Unique: CuefhXN0P4-tQZl2zGArhA-1 X-Mimecast-MFC-AGG-ID: CuefhXN0P4-tQZl2zGArhA_1782280454 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1782280454; x=1782885254; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=L1uvo9RPO6TNl4nAj04B5KNyUa4/1mdy4K3DUeLED7o=; b=JzpFAY9/giy3pOUjLXtDHjlzwGwcs0kpF6IxSK28S/UsNokHv4D/w+19E5R1kq88TT pkDAA+qGV6ER+PWM5OqfIe/EGU1D/RrKhP7tw/ihL2PTSuuyzG01wMgmvSspUJPBVB0h soJn7CbQlKDIa11LAItExpNGVFizJx6gKyz8ox5J78pjCtx8bN7VgTGFpKTVPeNI3quW aXb1f7AdAu1e3T2LTDUMc7A23WwMr859KuXnpYb2AFaqk42+QhZI3+dV0JY610HX5Kq1 mqQjkduQFgZz0kdzeXCFf2J3+G/SGV/AzWnEuxPgV866czINa1XP0baWCdYOmoewxoaI fr1g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782280454; x=1782885254; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=L1uvo9RPO6TNl4nAj04B5KNyUa4/1mdy4K3DUeLED7o=; b=ryq9zC3pCHG+kG6SEI+9FERbpDQsGYJS9ra/pzsEEGyM0T8SkG0hrWxmzqEmlvcsSx E6AV892qHCaodVtuBE7Qj/+GS6LRxvNF4ykfLJO7h6410eBUx4SbtoPwTUEW6H5glZrP AmjQjkoXNUQOZn8PQCrXXmWrR5W0mxV2l90HtY2OtTQpAWJmFYfiVwgqtYXeZ3c66jDK neDqc77Q9hJKS0v62ZRUa7gpUg4AJ7fmzITmMQt4sbLO/M49+HamrO9PmOYdT5+m5rJ6 6nO67ns0lmPHvhA/UA5q4/npJAueiZSwB4pGUNxMFzXLouiXvKXEyF9TBLvbUOrVGIdv OmLw== X-Gm-Message-State: AOJu0YzQDmbIK4yMxOEsq3LNPCG99RABjwBSMhEZ/SA5NbbwnZ/GQtay ZCK93VqM1idmU2G/hMU79xjLz5ouK2LL16qPZRNfYCIdcL36DSdcjDwg4otoQ1h77zCZJ/OS6b2 k3LC1q5ZyQX7xYP1rLZcLI37b30kCMzbeezl8cTIDxdmC9GfxIv8TFg+V X-Gm-Gg: AfdE7cmIiuJD7kpCqtOPqUIZTm8UC0cfQ09ejRpj6BaeE2d97Qih4DeQBuEhSc+DjAQ SKig7gl4nmOj2W81Tqcq0mjr6HjtqRd1YmwY2x3ht0/dgGCGEEAdbO+qSsJrGpOcojE/CPPfyYH 45Rla+Vn4BhK2+JN+52V/zQ/2VQsDKQ5qekm54Yc+4I9FftGt8vyhst6ExPdas+Bfbjkj8xnfDv xaUVhHcELLfnQ0QIPKUcvPx+khBMqtwwtVCnB2tactLp+NHwHhITGXCO0mBQkJTTQRIkc5IFJ2g A5BtugyGx0f72zlhIHhiA9QhPeBkVBJ/j6/H11P5KeHkooGMovNz+bi3dzm7PM08zxWWulW0HEG ECFz/SLSAWpZYuI4tA9N73BUHJgcYtS4tFujGb1lGYaB7 X-Received: by 2002:a05:7300:f60b:b0:303:f2dc:8ab4 with SMTP id 5a478bee46e88-30c6918496emr2477483eec.2.1782280454279; Tue, 23 Jun 2026 22:54:14 -0700 (PDT) X-Received: by 2002:a05:7300:f60b:b0:303:f2dc:8ab4 with SMTP id 5a478bee46e88-30c6918496emr2477459eec.2.1782280453608; Tue, 23 Jun 2026 22:54:13 -0700 (PDT) From: Ani Sinha To: Gerd Hoffmann , Stefano Garzarella , Ani Sinha Cc: qemu-devel@nongnu.org Subject: [PATCH v1 1/8] igvm: store IgvmCfg pointer in QIgvm Date: Wed, 24 Jun 2026 11:23:23 +0530 Message-ID: <20260624055339.46862-2-anisinha@redhat.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260624055339.46862-1-anisinha@redhat.com> References: <20260624055339.46862-1-anisinha@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=lists1p.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=anisinha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-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: qemu development 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: 1782280572252158500 Content-Type: text/plain; charset="utf-8" From: Gerd Hoffmann Store a pointer to IgvmCfg instead of only IgvmFile in QIgvm. Allows to store additional state in the (persistent) IgvmCfg struct. Signed-off-by: Gerd Hoffmann Reviewed-by: Ani Sinha --- backends/igvm.c | 57 ++++++++++++++++++++-------------- include/system/igvm-internal.h | 2 +- 2 files changed, 34 insertions(+), 25 deletions(-) diff --git a/backends/igvm.c b/backends/igvm.c index 3f4b97a5d4..2995e82cee 100644 --- a/backends/igvm.c +++ b/backends/igvm.c @@ -164,7 +164,8 @@ static int qigvm_handler(QIgvm *ctx, IgvmVariableHeader= Type raw_type, if (handlers[handler].type !=3D type) { continue; } - header_handle =3D igvm_get_header(ctx->file, handlers[handler].sec= tion, + header_handle =3D igvm_get_header(ctx->cfg->file, + handlers[handler].section, ctx->current_header_index); if (header_handle < 0) { error_setg( @@ -173,7 +174,7 @@ static int qigvm_handler(QIgvm *ctx, IgvmVariableHeader= Type raw_type, (int)header_handle); return -1; } - header_data =3D igvm_get_buffer(ctx->file, header_handle); + header_data =3D igvm_get_buffer(ctx->cfg->file, header_handle); if (header_data !=3D NULL) { header_data +=3D sizeof(IGVM_VHS_VARIABLE_HEADER); result =3D handlers[handler].handler(ctx, header_data, errp); @@ -184,7 +185,7 @@ static int qigvm_handler(QIgvm *ctx, IgvmVariableHeader= Type raw_type, header_handle, type); result =3D -1; } - igvm_free_buffer(ctx->file, header_handle); + igvm_free_buffer(ctx->cfg->file, header_handle); return result; } =20 @@ -330,7 +331,8 @@ static int qigvm_process_mem_region(QIgvm *ctx, unsigne= d start_index, =20 for (page_index =3D 0; page_index < page_count; page_index++) { data_handle =3D igvm_get_header_data( - ctx->file, IGVM_HEADER_SECTION_DIRECTIVE, page_index + start_i= ndex); + ctx->cfg->file, IGVM_HEADER_SECTION_DIRECTIVE, + page_index + start_index); if (data_handle =3D=3D IGVMAPI_NO_DATA) { /* No data indicates a zero page */ memset(®ion[page_index * page_size], 0, page_size); @@ -343,7 +345,7 @@ static int qigvm_process_mem_region(QIgvm *ctx, unsigne= d start_index, return -1; } else { zero =3D false; - data_size =3D igvm_get_buffer_size(ctx->file, data_handle); + data_size =3D igvm_get_buffer_size(ctx->cfg->file, data_handle= ); if (data_size < page_size) { memset(®ion[page_index * page_size], 0, page_size); } else if (data_size > page_size) { @@ -353,14 +355,14 @@ static int qigvm_process_mem_region(QIgvm *ctx, unsig= ned start_index, page_index + start_index); return -1; } - data =3D igvm_get_buffer(ctx->file, data_handle); + data =3D igvm_get_buffer(ctx->cfg->file, data_handle); if (data =3D=3D NULL) { error_setg(errp, "IGVM: No buffer for handle %d", data_han= dle); - igvm_free_buffer(ctx->file, data_handle); + igvm_free_buffer(ctx->cfg->file, data_handle); return -1; } memcpy(®ion[page_index * page_size], data, data_size); - igvm_free_buffer(ctx->file, data_handle); + igvm_free_buffer(ctx->cfg->file, data_handle); } } =20 @@ -397,7 +399,8 @@ static int qigvm_process_mem_page(QIgvm *ctx, ctx->region_start =3D page_data->gpa; ctx->region_start_index =3D ctx->current_header_index; } else { - if (!qigvm_page_attrs_equal(ctx->file, ctx->current_header_ind= ex, + if (!qigvm_page_attrs_equal(ctx->cfg->file, + ctx->current_header_index, page_data, &ctx->region_prev_page_data) || ((ctx->region_prev_page_data.gpa + @@ -460,7 +463,8 @@ static int qigvm_directive_vp_context(QIgvm *ctx, const= uint8_t *header_data, return 0; } =20 - data_handle =3D igvm_get_header_data(ctx->file, IGVM_HEADER_SECTION_DI= RECTIVE, + data_handle =3D igvm_get_header_data(ctx->cfg->file, + IGVM_HEADER_SECTION_DIRECTIVE, ctx->current_header_index); if (data_handle < 0) { error_setg(errp, "Invalid VP context in IGVM file. Error code: %X", @@ -468,7 +472,7 @@ static int qigvm_directive_vp_context(QIgvm *ctx, const= uint8_t *header_data, return -1; } =20 - data =3D (uint8_t *)igvm_get_buffer(ctx->file, data_handle); + data =3D (uint8_t *)igvm_get_buffer(ctx->cfg->file, data_handle); if (data =3D=3D NULL) { error_setg(errp, "IGVM: No buffer for handle %d", data_handle); result =3D -1; @@ -477,7 +481,8 @@ static int qigvm_directive_vp_context(QIgvm *ctx, const= uint8_t *header_data, =20 if (ctx->machine_state->cgs) { result =3D ctx->cgsc->set_guest_state( - vp_context->gpa, data, igvm_get_buffer_size(ctx->file, data_ha= ndle), + vp_context->gpa, data, + igvm_get_buffer_size(ctx->cfg->file, data_handle), CGS_PAGE_TYPE_VMSA, vp_context->vp_index, errp); } else if (target_arch() =3D=3D SYS_EMU_TARGET_X86_64) { result =3D qigvm_x86_set_vp_context(data, vp_context->vp_index, er= rp); @@ -490,7 +495,7 @@ static int qigvm_directive_vp_context(QIgvm *ctx, const= uint8_t *header_data, } =20 exit: - igvm_free_buffer(ctx->file, data_handle); + igvm_free_buffer(ctx->cfg->file, data_handle); if (result < 0) { return result; } @@ -803,7 +808,8 @@ static int qigvm_supported_platform_compat_mask(QIgvm *= ctx, Error **errp) uint32_t compatibility_mask_sev_snp =3D 0; uint32_t compatibility_mask =3D 0; =20 - header_count =3D igvm_header_count(ctx->file, IGVM_HEADER_SECTION_PLAT= FORM); + header_count =3D igvm_header_count(ctx->cfg->file, + IGVM_HEADER_SECTION_PLATFORM); if (header_count < 0) { error_setg(errp, "Invalid platform header count in IGVM file. Error code= : %X", @@ -814,11 +820,11 @@ static int qigvm_supported_platform_compat_mask(QIgvm= *ctx, Error **errp) for (header_index =3D 0; header_index < (unsigned)header_count; header_index++) { IgvmVariableHeaderType typ =3D igvm_get_header_type( - ctx->file, IGVM_HEADER_SECTION_PLATFORM, header_index); + ctx->cfg->file, IGVM_HEADER_SECTION_PLATFORM, header_index); typ =3D igvm_vht_type(typ); if (typ =3D=3D IGVM_VHT_SUPPORTED_PLATFORM) { header_handle =3D igvm_get_header( - ctx->file, IGVM_HEADER_SECTION_PLATFORM, header_index); + ctx->cfg->file, IGVM_HEADER_SECTION_PLATFORM, header_index= ); if (header_handle < 0) { error_setg(errp, "Invalid platform header in IGVM file. " @@ -827,11 +833,11 @@ static int qigvm_supported_platform_compat_mask(QIgvm= *ctx, Error **errp) return -1; } platform =3D - (IGVM_VHS_SUPPORTED_PLATFORM *)(igvm_get_buffer(ctx->file, + (IGVM_VHS_SUPPORTED_PLATFORM *)(igvm_get_buffer(ctx->cfg->= file, header_han= dle)); if (platform =3D=3D NULL) { error_setg(errp, "IGVM: No buffer for handle %d", header_h= andle); - igvm_free_buffer(ctx->file, header_handle); + igvm_free_buffer(ctx->cfg->file, header_handle); return -1; } =20 @@ -862,7 +868,7 @@ static int qigvm_supported_platform_compat_mask(QIgvm *= ctx, Error **errp) } else if (platform->platform_type =3D=3D IGVM_PLATFORM_TYPE_N= ATIVE) { compatibility_mask =3D platform->compatibility_mask; } - igvm_free_buffer(ctx->file, header_handle); + igvm_free_buffer(ctx->cfg->file, header_handle); } } /* Choose the strongest supported isolation technology */ @@ -939,7 +945,7 @@ int qigvm_process_file(IgvmCfg *cfg, MachineState *mach= ine_state, error_setg(errp, "No IGVM file loaded."); return -1; } - ctx.file =3D cfg->file; + ctx.cfg =3D cfg; trace_igvm_process_file(cfg->file, onlyVpContext); =20 ctx.machine_state =3D machine_state; @@ -961,7 +967,8 @@ int qigvm_process_file(IgvmCfg *cfg, MachineState *mach= ine_state, goto cleanup; } =20 - header_count =3D igvm_header_count(ctx.file, IGVM_HEADER_SECTION_DIREC= TIVE); + header_count =3D igvm_header_count(ctx.cfg->file, + IGVM_HEADER_SECTION_DIRECTIVE); if (header_count <=3D 0) { error_setg( errp, "Invalid directive header count in IGVM file. Error code= : %X", @@ -975,7 +982,8 @@ int qigvm_process_file(IgvmCfg *cfg, MachineState *mach= ine_state, ctx.current_header_index < (unsigned)header_count; ctx.current_header_index++) { IgvmVariableHeaderType raw_type =3D igvm_get_header_type( - ctx.file, IGVM_HEADER_SECTION_DIRECTIVE, ctx.current_header_in= dex); + ctx.cfg->file, IGVM_HEADER_SECTION_DIRECTIVE, + ctx.current_header_index); if (!onlyVpContext || igvm_vht_type(raw_type) =3D=3D IGVM_VHT_VP_C= ONTEXT) { if (qigvm_handler(&ctx, raw_type, errp) < 0) { goto cleanup_parameters; @@ -993,7 +1001,7 @@ int qigvm_process_file(IgvmCfg *cfg, MachineState *mac= hine_state, } =20 header_count =3D - igvm_header_count(ctx.file, IGVM_HEADER_SECTION_INITIALIZATION); + igvm_header_count(ctx.cfg->file, IGVM_HEADER_SECTION_INITIALIZATIO= N); if (header_count < 0) { error_setg( errp, @@ -1006,7 +1014,8 @@ int qigvm_process_file(IgvmCfg *cfg, MachineState *ma= chine_state, ctx.current_header_index < (unsigned)header_count; ctx.current_header_index++) { IgvmVariableHeaderType type =3D - igvm_get_header_type(ctx.file, IGVM_HEADER_SECTION_INITIALIZAT= ION, + igvm_get_header_type(ctx.cfg->file, + IGVM_HEADER_SECTION_INITIALIZATION, ctx.current_header_index); if (qigvm_handler(&ctx, type, errp) < 0) { goto cleanup_parameters; diff --git a/include/system/igvm-internal.h b/include/system/igvm-internal.h index 7f131c4d03..b55b35328a 100644 --- a/include/system/igvm-internal.h +++ b/include/system/igvm-internal.h @@ -43,7 +43,7 @@ typedef struct QIgvmParameterData { * file. */ struct QIgvm { - IgvmHandle file; + IgvmCfg *cfg; MachineState *machine_state; ConfidentialGuestSupportClass *cgsc; uint32_t compatibility_mask; --=20 2.42.0 From nobody Sun Jul 26 12:33:35 2026 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=1782280497; cv=none; d=zohomail.com; s=zohoarc; b=mFnuvJGyXiV/ahfTKiAWxGiAEbHcbU/YTdDfONPaM+B20E5pvYntgyeeysBeJqhIPytXp5oRGSAb+UeeovUfyMZxl9/KTuvJx4bPHooC3L4QvMsZtdy5f9Z5KKf+KI0BjcEfHRZ5BFqm++8uqqG2SIGV+m9HOksa6FNp3qNo8N0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782280497; 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=IlIB0gyVXIdZ9I8a3u7xyO2vP3rsljTTT0Q5gAGep+E=; b=nlhOUst9LAr0Lxrtoh6ZwyVwdpDcIbZTPOWK2UWWSQbzxR5zTiNVSMjRWtopK9Vxara/TdjvDxwc2GLRFsX7Jq27KZPDvjAEVO3aInw5nfIcQcPBGTUed9v0E25BJ4hL6xmT5lhaKUROVlFwcwMS8/IfcOAX5aE2wKQJaC3FC5M= 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1782280497763159.93798239227897; Tue, 23 Jun 2026 22:54:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wcGZA-00071G-Fa; Wed, 24 Jun 2026 01:54:28 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wcGZ4-00070X-Kv for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:23 -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 1wcGZ3-00063f-1Y for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:22 -0400 Received: from mail-dy1-f198.google.com (mail-dy1-f198.google.com [74.125.82.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-618-6SeZwH7cNYq-HF44q88H4g-1; Wed, 24 Jun 2026 01:54:18 -0400 Received: by mail-dy1-f198.google.com with SMTP id 5a478bee46e88-30c13bb8ca9so832812eec.0 for ; Tue, 23 Jun 2026 22:54:18 -0700 (PDT) Received: from rhel9-box.lan ([110.227.100.91]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-30c1bd8d6edsm21075803eec.14.2026.06.23.22.54.14 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 22:54:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782280460; 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=IlIB0gyVXIdZ9I8a3u7xyO2vP3rsljTTT0Q5gAGep+E=; b=J3Zq754/W1u8mJbdwLcEmJUxTFblFmZe+bN0EBi7DLC5xsPSyz2JRLHHyAwH04WZpLbB7N uL0IWdyS7uJ+BsUTcGvdD533MPRdeGK9EUSmFcEYYaNq5f6Ha+TqKz6Fksnugmc+U4Qr6V N+GID/no7IVl+ceKASekUBfV+LFMjJ8= X-MC-Unique: 6SeZwH7cNYq-HF44q88H4g-1 X-Mimecast-MFC-AGG-ID: 6SeZwH7cNYq-HF44q88H4g_1782280458 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1782280458; x=1782885258; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=IlIB0gyVXIdZ9I8a3u7xyO2vP3rsljTTT0Q5gAGep+E=; b=UAgKix9wcV+2ckQZmbKT87iCXTauykTp6n/6BERh7+SFxsSMTQbI7BQN2YlnbKwTob ChQQfvRfnOmjQ2JvWXnJQz40XHK/rmzoMFjW7xoHt9XJzCykjpzcW79bkwLVtLt11+ay Q1v+KSpCHAKxBMW2dBpXauTlbWQ1ELdm9bAxpljhlIehp/luHyqj95uAa1tHVuTWGSus ChCK9a7Pe1OeJ9G3vHzV46e3BewFmsg2pn0DkySGXkcBwTV1BEt+ne7wBS+49/WZ19ed AknXTrz7l0b7UyH0DcVkK4Jr3kT2jJQryUF514JoFYllWnpICXASfN+q1tdwwvYxhHsk cvIw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782280458; x=1782885258; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=IlIB0gyVXIdZ9I8a3u7xyO2vP3rsljTTT0Q5gAGep+E=; b=rsEPrGciNSHNatWJD0IBTwUYoZRv77QiYck6R4Ph1/IWidCR85K0UV5k7PPgekmhTD 0BeZrDGQe2abzi87lG8XNLhxJ8FYsnrZuPX5skb8oEOyohXt5ix/8rNzzjLLDLGKr6sJ FTr6c1BbNqe0FwIstxn2pKhC8OqqwVEc/ykW6Dfrm1DCm8dT99b2ENm+MU3kx/Tuvv0Q nzx0CYXGl6CarY3BC8Oa1/EiSv39ear3udZvgMD5kaor2Nx7hhOeyvBYP03ydbXHE1bO 0vKIATCikqKo8ru0nDwLAgdRcozAND5T3srv4MaTAKIYKwkygvLKcjqH+14u6ReCPduO VD+w== X-Gm-Message-State: AOJu0YyXAVgNnvmM3u1cjY+8AQ5Ted+srI4ovwbKqarGwnv5r3adtg54 4PXPmi2Bb1+pGbF56KNkqik1oPHZvt80OdgP9N+w0bIxDurgY/gwVYYfUUKpLcKhyz4gWDOxoxH 4gzn/yYNH3M3hNI7gGMHOF2TXWOLQ4NDHDjL30NmQeEPZE33DAhFdAe7U X-Gm-Gg: AfdE7cl9Kp/VS2kwCDdTY4Irt+/yNTYOtkcQ5/ff+7/77/Iq17BeuMkJpDLa5prKd+N 09MYVIjofMcs4pwQ4i/wxG+ds+kDV6u7MqqPn7F+B7BIfRDIjCdr/OVPGITYVrbm48t65j8i2/P f+sz1ZrjKMTabjg+KVnqEXjXF7vWsDZvebY0ROAehbqD7tl5jG9KT2ydO+qSPbL4SWnQU22xpTT tq6m03M6qPaNs1CRDxavrrOl2m/FHer15y1iSxLdSP4IKb/hVbIgmEY9tngv6gY4LtdNkSVmnIN YDQ00nH14QdGrIxbEDVKcycfJwTlDH9Ir5mZPQToVi2Pe8EINyFup5eK+VUaGa8eiyegwCDB+na OzH42PSYw1epKh3HabZ5SjQ6Ji+e4M31WVVX7c3wu4vU9 X-Received: by 2002:a05:7300:7245:b0:30b:c4e3:8235 with SMTP id 5a478bee46e88-30c68def98bmr2162752eec.27.1782280457570; Tue, 23 Jun 2026 22:54:17 -0700 (PDT) X-Received: by 2002:a05:7300:7245:b0:30b:c4e3:8235 with SMTP id 5a478bee46e88-30c68def98bmr2162734eec.27.1782280457027; Tue, 23 Jun 2026 22:54:17 -0700 (PDT) From: Ani Sinha To: Gerd Hoffmann , Stefano Garzarella , Ani Sinha Cc: qemu-devel@nongnu.org Subject: [PATCH v1 2/8] igvm: track memory regions Date: Wed, 24 Jun 2026 11:23:24 +0530 Message-ID: <20260624055339.46862-3-anisinha@redhat.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260624055339.46862-1-anisinha@redhat.com> References: <20260624055339.46862-1-anisinha@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=lists1p.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=anisinha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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, SPF_HELO_PASS=-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: qemu development 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: 1782280500364158500 Content-Type: text/plain; charset="utf-8" From: Gerd Hoffmann Memory regions added by the current IGVM needs to be tracked so that they c= an be freed when a new IGVM is loaded. Signed-off-by: Gerd Hoffmann Reviewed-by: Ani Sinha --- backends/igvm-cfg.c | 1 + backends/igvm.c | 17 +++++++++-------- include/system/igvm-internal.h | 6 ++++++ 3 files changed, 16 insertions(+), 8 deletions(-) diff --git a/backends/igvm-cfg.c b/backends/igvm-cfg.c index e1f09855f6..38438a7b1e 100644 --- a/backends/igvm-cfg.c +++ b/backends/igvm-cfg.c @@ -65,6 +65,7 @@ static void igvm_complete(UserCreatable *uc, Error **errp) IgvmCfg *igvm =3D IGVM_CFG(uc); =20 igvm->file =3D qigvm_file_init(igvm->filename, errp); + QTAILQ_INIT(&igvm->memory_regions); } =20 OBJECT_DEFINE_TYPE_WITH_INTERFACES(IgvmCfg, igvm_cfg, IGVM_CFG, OBJECT, diff --git a/backends/igvm.c b/backends/igvm.c index 2995e82cee..1c9751812d 100644 --- a/backends/igvm.c +++ b/backends/igvm.c @@ -206,7 +206,7 @@ static void *qigvm_prepare_memory(QIgvm *ctx, uint64_t = addr, uint64_t size, int region_identifier, Error **errp) { ERRP_GUARD(); - MemoryRegion *igvm_pages =3D NULL; + IgvmMemoryRegion *imr =3D NULL; Int128 gpa_region_size; MemoryRegionSection mrs =3D memory_region_find(get_system_memory(), addr, size); @@ -240,23 +240,24 @@ static void *qigvm_prepare_memory(QIgvm *ctx, uint64_= t addr, uint64_t size, */ g_autofree char *region_name =3D g_strdup_printf("igvm.%X", region_identifier); - igvm_pages =3D g_new0(MemoryRegion, 1); + imr =3D g_new0(IgvmMemoryRegion, 1); if (ctx->machine_state->cgs && ctx->machine_state->cgs->require_guest_memfd) { - if (!memory_region_init_ram_guest_memfd(igvm_pages, NULL, + if (!memory_region_init_ram_guest_memfd(&imr->mr, NULL, region_name, size, err= p)) { - g_free(igvm_pages); + g_free(imr); return NULL; } } else { - if (!memory_region_init_ram(igvm_pages, NULL, region_name, siz= e, + if (!memory_region_init_ram(&imr->mr, NULL, region_name, size, errp)) { - g_free(igvm_pages); + g_free(imr); return NULL; } } - memory_region_add_subregion(get_system_memory(), addr, igvm_pages); - return memory_region_get_ram_ptr(igvm_pages); + memory_region_add_subregion(get_system_memory(), addr, &imr->mr); + QTAILQ_INSERT_TAIL(&ctx->cfg->memory_regions, imr, next); + return memory_region_get_ram_ptr(&imr->mr); } } =20 diff --git a/include/system/igvm-internal.h b/include/system/igvm-internal.h index b55b35328a..cab74cfd1d 100644 --- a/include/system/igvm-internal.h +++ b/include/system/igvm-internal.h @@ -18,6 +18,11 @@ #include "system/confidential-guest-support.h" #include =20 +typedef struct IgvmMemoryRegion { + QTAILQ_ENTRY(IgvmMemoryRegion) next; + MemoryRegion mr; +} IgvmMemoryRegion; + struct IgvmCfg { Object parent_obj; =20 @@ -29,6 +34,7 @@ struct IgvmCfg { char *filename; IgvmHandle file; ResettableState reset_state; + QTAILQ_HEAD(, IgvmMemoryRegion) memory_regions; }; =20 typedef struct QIgvmParameterData { --=20 2.42.0 From nobody Sun Jul 26 12:33:35 2026 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=1782280498; cv=none; d=zohomail.com; s=zohoarc; b=CwL7ks/SH+Eu8MZ9jemOGNjTWLpJCrO9wfIh5rH/sPPBKHHx0ZuvgUR/ipBYaB6QgvBpMjKhFfZ63/kiBIXSd/an1cLXqpybNqo8RRBRlfy8WKPUVvfXSTHy/GpqmhRqIXVAC3KoJHk+sGwFTp5VZMlez+oMGKhMAqkL+qfjIqY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782280498; 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=pDd03COlLGY3G5rHg6IQzNdZVrq4oPUHbOZUxRyvGHY=; b=ejw+eM1VWfyr//j1u+Jz4BCZcwo8bB/SnbAYxOoprXq+awp1OAHy52KGu4xUpefmoso2o1mCYQ/vrBxVCAX/TEE/2QzE/MnIQPYYl1zqYa7Swoq+tfmDlAFPrezJCwnDWdzSp//ymVMZ6mFEpdNxKN4aSUR69/t2YDs/6ITwFe0= 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1782280498025567.1298893142151; Tue, 23 Jun 2026 22:54:58 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wcGZF-00072W-WC; Wed, 24 Jun 2026 01:54:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wcGZD-00071Z-I1 for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:32 -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 1wcGZ8-00064b-L3 for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:29 -0400 Received: from mail-dy1-f197.google.com (mail-dy1-f197.google.com [74.125.82.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-42-X41QGKCxN82CwDcmJjcTug-1; Wed, 24 Jun 2026 01:54:21 -0400 Received: by mail-dy1-f197.google.com with SMTP id 5a478bee46e88-30c0d568830so2385186eec.1 for ; Tue, 23 Jun 2026 22:54:21 -0700 (PDT) Received: from rhel9-box.lan ([110.227.100.91]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-30c1bd8d6edsm21075803eec.14.2026.06.23.22.54.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 22:54:19 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782280465; 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=pDd03COlLGY3G5rHg6IQzNdZVrq4oPUHbOZUxRyvGHY=; b=BWNLvyVo1qq7u4h4DV7wt503crd8DoBp9Cgisv2YcFHIffRdM2C2xqlZLwtSOipcN4X3m7 XU/8kCfAzBR2y/FkvoX226MQonrdVDeGwQ72kYLJ2ZCM+eA0nuSHPd2kGJv1QxV2gJQac+ FT8fh0z/Ye7+S5fu7ppAvPXUPNqizDg= X-MC-Unique: X41QGKCxN82CwDcmJjcTug-1 X-Mimecast-MFC-AGG-ID: X41QGKCxN82CwDcmJjcTug_1782280460 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1782280460; x=1782885260; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=pDd03COlLGY3G5rHg6IQzNdZVrq4oPUHbOZUxRyvGHY=; b=qROXlG9vzci/IuSMCCy7LmQnKo2RRfwZ5rdqbmlURzlnk++heO6w2AXbbR42JEvEOi D9rDjwFQ3oQLUMYZ21omFe/w+z+8AYQZgdSTcU/rccZXufYVRSpcBZw46LG0rXb+bj+W tSQztQRy5cE7C3Qdj4eVYTr0hxVnHowg3pcqdaIfedp+NJMgJhczjYIJ1NGwp/KtqbcK n33Jak+depVU1BJHuoIuSiaZElIG3yCOmz/8bzZJLZJJfyHnmO/MwvKSOHVwEgoqwsbO 5lq+y5RxKaBKBBIBezblNdYqz8iUptXWhoDVsnevxJ5x6pwFRebE7oF1GX7jo2aog2V/ mMHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782280460; x=1782885260; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=pDd03COlLGY3G5rHg6IQzNdZVrq4oPUHbOZUxRyvGHY=; b=IAPfcSppUuiGeUa75xRX1mF7w9PGMR78Xy17NU+IQcQVgiqnM6FpgDPcjZ9ABtPZJD XLBNw1yQHUQMuh7/QD6GnwMGW8Ty6UIuVLiV6GkS1jY3k0uPG6pWtbdEZqCNg2e0JE/u dTxjSG/Jo8HYRfxPSpFklFfvhfTUwPC3fQNNF3rln6kHDyNVqBvQkSkDKynV8pDEDWjc PTXXiuu41UUxMJXMwyDGqWSXrcT+zogkPfk2iTeev7aNOuZL83bkNLMnqAgb5GlyyGf6 HSJzcyfr3Wd6MEYYpxfOnRhP7zOiJDQbFRxgZsigzXVbuUkpaimyx0CtSbvN5GYQdF7h xJag== X-Gm-Message-State: AOJu0YxTVA6uSUPPxN+MmukFBYjIODbEIouCtnjedwWxAH7hyca9P9Po /bVoPPgTxwxFPzwlTbJSJtzAZ1XrDGyB545aBSdK4maKYW5y5xXPW5G1SvdVmMUabUEl3ClVUp6 dcCloo6GnHLC7oiZcTzQlxAIHx7im1khUVAXj/GLASQk/NeEv8rR5sEqR X-Gm-Gg: AfdE7cnUtlauUaE+M7++a6IjpZ6p+VgsRLJMwlIgGzG9aBX1zkZN+oyCee+RQNeAV+G Pu/RSAuWPJZ1h9F5hQs7Y3n/bE0EyHyssYSQfcRg0QthTQAbhOcYd6KWQRluKlZVDGrPrM2GNVF 6PsumJUkap1tvxdM67PK6kcrfcA0iTGhxj8EdzFn5BoIY+ak1e4vF34pJf7DKrwAfogv0nSCaIX 0LTIj+qvUdX4FVcMJgAgx0+Ul9LlWD/D7GmtbAgCZ6ZVJ/2VYHJRjFkkKJaFnHx9zrVhCd3Sb80 wBbLiqsEMpJDG7y8PKSqvbZ5uJ8nEkHS1wllyJtuH1mhCV1kQRAjqBFIdnyBoNnimvR2gyw0Gve YvKggoz+VsSLW/0Q6ZYB0mZvapIWPdwQtbfcbAC6Npm4m X-Received: by 2002:a05:7300:d4c5:b0:2d1:d434:cfe3 with SMTP id 5a478bee46e88-30c587e82e0mr5591569eec.0.1782280460130; Tue, 23 Jun 2026 22:54:20 -0700 (PDT) X-Received: by 2002:a05:7300:d4c5:b0:2d1:d434:cfe3 with SMTP id 5a478bee46e88-30c587e82e0mr5591556eec.0.1782280459658; Tue, 23 Jun 2026 22:54:19 -0700 (PDT) From: Ani Sinha To: Gerd Hoffmann , Stefano Garzarella , Ani Sinha Cc: qemu-devel@nongnu.org Subject: [PATCH v1 3/8] igvm: cleanup memory regions Date: Wed, 24 Jun 2026 11:23:25 +0530 Message-ID: <20260624055339.46862-4-anisinha@redhat.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260624055339.46862-1-anisinha@redhat.com> References: <20260624055339.46862-1-anisinha@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=lists1p.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=anisinha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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, SPF_HELO_PASS=-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: qemu development 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: 1782280500336158500 Content-Type: text/plain; charset="utf-8" From: Gerd Hoffmann This change cleans up existing memory regions that were created by the curr= ent IGVM. The cleanup would be necessary when a new IGVM is loaded. This cleanup function is called in a subsequent patch. Signed-off-by: Gerd Hoffmann --- backends/igvm.c | 17 +++++++++++++++++ include/system/igvm.h | 1 + 2 files changed, 18 insertions(+) diff --git a/backends/igvm.c b/backends/igvm.c index 1c9751812d..61040d1be2 100644 --- a/backends/igvm.c +++ b/backends/igvm.c @@ -14,6 +14,7 @@ #include "qapi/error.h" #include "qemu/error-report.h" #include "qemu/target-info-qapi.h" +#include "migration/vmstate.h" #include "system/igvm.h" #include "system/igvm-cfg.h" #include "system/igvm-internal.h" @@ -1046,3 +1047,19 @@ cleanup_parameters: cleanup: return retval; } + +/* + * cleanup any memory regions created by qigvm_prepare_memory() + */ +void qigvm_cleanup_memory(IgvmCfg *cfg) +{ + IgvmMemoryRegion *imr, *tmp; + + QTAILQ_FOREACH_SAFE(imr, &cfg->memory_regions, next, tmp) + { + memory_region_del_subregion(get_system_memory(), &imr->mr); + vmstate_unregister_ram(&imr->mr, NULL); + QTAILQ_REMOVE(&cfg->memory_regions, imr, next); + g_free(imr); + } +} diff --git a/include/system/igvm.h b/include/system/igvm.h index 64d3542311..e219f1a4ed 100644 --- a/include/system/igvm.h +++ b/include/system/igvm.h @@ -20,6 +20,7 @@ typedef struct QIgvm QIgvm; =20 int qigvm_process_file(IgvmCfg *igvm, MachineState *machine_state, bool onlyVpContext, Error **errp); +void qigvm_cleanup_memory(IgvmCfg *igvm); =20 /* x86 native */ int qigvm_x86_get_mem_map_entry(int index, --=20 2.42.0 From nobody Sun Jul 26 12:33:35 2026 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=1782280497; cv=none; d=zohomail.com; s=zohoarc; b=TgXppAFLKq1i5ucFr1LocpBdzwT1p5Ddp0NQfN5CKsP77Cv8QJZQlHFGmdB7s+H9fNPN9iwszRrwoBcKIcihzJLLE5/nI1JJr8AOMYhlLJbPLe2VQPPM9hzXxNdMrCsKFn1L0ZjqEd9VLBb2pKdqXyg9b0InILJ/J+Wi2jUF3bU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782280497; 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=ssW03Dn5AeZWkODFXTT7NI4oiMDlz/9jXiRM25HGFig=; b=WCskhFba+G8gRmZCsjg0xU+z5wiEnf0LGrvVKV1VaadkF0F5Gk2nMtN3X1Ajy8AIHCsj2hYvITUxnn3+qwdiUYCc9PQ3PTIrM5MoR/RR7KN7lkzf/63Gn+DrlNGUqqtuoSuUus5pu98r56jltv54Yd3pWz9ZsXa4ecXad0WEx/4= 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1782280497700115.98560265366223; Tue, 23 Jun 2026 22:54:57 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wcGZG-00072v-Bk; Wed, 24 Jun 2026 01:54:34 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wcGZD-00071X-HQ for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:32 -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 1wcGZA-00064n-8s for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:30 -0400 Received: from mail-dy1-f198.google.com (mail-dy1-f198.google.com [74.125.82.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-352-uNPHT6eQNBCRhK3Y1BbKmw-1; Wed, 24 Jun 2026 01:54:24 -0400 Received: by mail-dy1-f198.google.com with SMTP id 5a478bee46e88-30c03c1dda3so2116695eec.1 for ; Tue, 23 Jun 2026 22:54:24 -0700 (PDT) Received: from rhel9-box.lan ([110.227.100.91]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-30c1bd8d6edsm21075803eec.14.2026.06.23.22.54.20 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 22:54:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782280466; 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=ssW03Dn5AeZWkODFXTT7NI4oiMDlz/9jXiRM25HGFig=; b=OeOVE6Gg8jEjY5Mir0Aieyneg6QIXulvwjE8/ozizU/AdmjDvN+1wSqIsYPedQH5rtbeUZ I/AFAuZuO0+0M5Bc/0Q3+y6KQSN0y36nDhub4u/skUxNz69kfwltGRYwKbub6dDvFJDTA+ k/rPG5w4T9yqGFjhO82HutzeXcSUDfE= X-MC-Unique: uNPHT6eQNBCRhK3Y1BbKmw-1 X-Mimecast-MFC-AGG-ID: uNPHT6eQNBCRhK3Y1BbKmw_1782280464 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1782280464; x=1782885264; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ssW03Dn5AeZWkODFXTT7NI4oiMDlz/9jXiRM25HGFig=; b=rbxWcjDPAKRu8U/15JV579yi8wu8EeO+V0HNRFo6P3gC0kLLAvszI8NGzc5Zj5GKl/ 7KEelmiGHP8o3ysht73ViPoHJYb3rdhnYAJx/xq+8kwRxAjcbnLtEfUsLHLcWeMqw0t3 Pe+GAdJqsEpPkvNT5veLml2EfzA2mBe3R/tZV7lJI65SqY/E2L8BDHDkLggynwuH+3je mu5U6JKLxR+C+tgTXCH0ppr+ak2xKeaegkIXFtAdICHplTvdW/2WMLxO4pYdpBcXhp1O xkbbv08k9ZJd9Wt6XZFxMRJTx0M+deq+mLe2ZHJd6WlM50/lAiKtZ8SB2M+xVEpButrF GYuA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782280464; x=1782885264; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ssW03Dn5AeZWkODFXTT7NI4oiMDlz/9jXiRM25HGFig=; b=n8WY6jGmqHQlyWrk2Rp2XNpx4FIdNYb1g5YFvlkvIXUMu19T2D6FG6KjUI2WmwgZnl 4u2ctp+83P8+bB/DN0jTBpE03ralthwqqMX8yRMhenx9C8by6Mcnv3yTs3lZf6QCvlWC v4BP1EEJ6kizED/fZhzcEHL+erCHnOi0YbbXroPcNmDPOzYfHUno4XKOV/M1RDionOVU 0+Z/154MBlySlVInv8bf6ZI6W+MbkfW7BgpzqjO7q2BaYx8G+JlIOGtC0Vh9JBK1qy6K iVwrRg87VIGQqehkl6iq5fLyEgme2kUz2ujZ7L+L9bKYjx97yoaFsOlf6sVGZS9FqlGT lYtQ== X-Forwarded-Encrypted: i=1; AHgh+RqkbHSrk3bY659pB/zQhUN+44W3pQNQ3C8vtwCkkFQDCUhN2+0FG3Ew8nD+bIH01hXAg2vAhHYsCJUe@nongnu.org X-Gm-Message-State: AOJu0YzCMv7abLQXkd3irBD3J7dvyRyEVdfXfpKSY3oAr18jItvDDGLB XPQprajXvwgA9UhRN3+POulMOfYKFS2uZgeu+0tr179pOZZAXH27duh45wknaq6ZLeMJbOrX9xM 6vXMPi8OnTtXR2wBQ0vxRtschsnkYeJC0fygVsY0VyjOST2wviKt21+l1 X-Gm-Gg: AfdE7ckZ9161A/D5WXJPpCCfxNwP+YuqdOJXJWfiJd7Xk0pb3gTB8Pmh1zALBmxaHf6 PfOk8STnYMo10/NDCifhBexZ800InNCKhWN3KftDqZ1wXhQIXpyGNtOpqhJC9aCzByJ0tK+BcS9 4KyOY8yFQ1LrpM8B1g+BRx7CN0PQM0plfAhNAuGPbl+p4aC0LDl1qebroxpV2G21CKd8VxUI78e 2F8hHXVQCXVd3y4VZQJfx5AUZfwmc8aMsvW5Fr/6lY4wblw+csQb3Rr9fRHK1jAqX0zMaV1wDew 8HBuZqL3Z2UsUecyFNoLqisyr91aGOFmLA2kPAleQ204sTKEswFzgxbWoZohtLrDPzYarSFaEpt HCOXJI9YcXZy/quUgt2isB0jzA6mWp9+sD9hFVpkc/kua X-Received: by 2002:a05:7300:ac8a:b0:304:6d18:3646 with SMTP id 5a478bee46e88-30c1d5955c6mr13998205eec.0.1782280463486; Tue, 23 Jun 2026 22:54:23 -0700 (PDT) X-Received: by 2002:a05:7300:ac8a:b0:304:6d18:3646 with SMTP id 5a478bee46e88-30c1d5955c6mr13998192eec.0.1782280462847; Tue, 23 Jun 2026 22:54:22 -0700 (PDT) From: Ani Sinha To: Ani Sinha , Gerd Hoffman , Stefano Garzarella Cc: Alex Graf , qemu-devel@nongnu.org Subject: [PATCH v1 4/8] hw/misc/vmlaunchupdate: Introduce hypervisor fw-cfg interface support Date: Wed, 24 Jun 2026 11:23:26 +0530 Message-ID: <20260624055339.46862-5-anisinha@redhat.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260624055339.46862-1-anisinha@redhat.com> References: <20260624055339.46862-1-anisinha@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=lists1p.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=anisinha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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, SPF_HELO_PASS=-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: qemu development 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: 1782280500423158500 Content-Type: text/plain; charset="utf-8" VM launch update is a mechanism where the virtual machines can use IGVM file bundle to boot into a trusted execution environment without having to depend on a untrusted party to provide the IGVM bundle or firmware image. This is particularly useful for confidential virtual machines that are deployed in the cloud where the tenant and the cloud provider are two different entities. In this scenario, virtual machines can bring their own trusted IGVM file containing a trusted firmware image bundled as a part of their filesystem and then use this hypervisor interface to update to a trusted and deterministic boot state. This also allows the guests to have a consistent measurements on the firmwa= re image. Currently, this mechanism only works if the VM was started with IGVM in the first place. This change introduces support for the fw-cfg based hypervisor interface and the corresponding device.The change also includes the specification document for this interface. The interface is made generic enough so that guests are free to use their own ABI to pass required information between initial and trusted execution contexts (where they are running their own trusted boot state) without the hypervisor getting involved in between. Currently, this device is only supported for x86 machines. Presence of IGVM host libraries is also required for parsing IGVM files. Hence, the dev= ice cannot be initialized for other machine types or hosts where IGVM support is not present. Trying to initialize it for arm for example will lead to fa= ilure: $ ./qemu-system-arm -device vm-launch-update -machine virt qemu-system-arm: -device vmfwupdate: This machine does not support vm-launc= h-update device Functional and qtests will be added in a subsequent patch. CC: Alex Graf CC: Gerd Hoffman Signed-off-by: Ani Sinha --- hw/misc/meson.build | 3 + hw/misc/trace-events | 5 + hw/misc/vmlaunchupdate.c | 236 +++++++++++++++++++++++++++++++ include/hw/misc/vmlaunchupdate.h | 85 +++++++++++ include/system/igvm.h | 2 + 5 files changed, 331 insertions(+) create mode 100644 hw/misc/vmlaunchupdate.c create mode 100644 include/hw/misc/vmlaunchupdate.h diff --git a/hw/misc/meson.build b/hw/misc/meson.build index 23265f6035..b8c7de295e 100644 --- a/hw/misc/meson.build +++ b/hw/misc/meson.build @@ -163,6 +163,9 @@ specific_ss.add(when: 'CONFIG_MIPS_ITU', if_true: files= ('mips_itu.c')) =20 specific_ss.add(when: 'CONFIG_RISCV_MIPS_CMGCR', if_true: files('riscv_cmg= cr.c')) specific_ss.add(when: 'CONFIG_RISCV_MIPS_CPC', if_true: files('riscv_cpc.c= ')) +if igvm.found() + specific_ss.add(when: 'CONFIG_FW_CFG_DMA', if_true: files('vmlaunchupda= te.c')) +endif =20 system_ss.add(when: 'CONFIG_SBSA_REF', if_true: files('sbsa_ec.c')) =20 diff --git a/hw/misc/trace-events b/hw/misc/trace-events index b88accc437..f440987501 100644 --- a/hw/misc/trace-events +++ b/hw/misc/trace-events @@ -417,3 +417,8 @@ iommu_testdev_dma_read(uint64_t gva, uint32_t len) "gva= =3D0x%" PRIx64 " len=3D%u" iommu_testdev_dma_verify(uint32_t expected, uint32_t actual) "expected=3D0= x%x actual=3D0x%x" iommu_testdev_dma_result(uint32_t result) "DMA completed result=3D0x%x" iommu_testdev_dma_armed(bool armed) "armed=3D%d" + +# vmlaunchupdate.c +launch_update_write(void) "" +vmlaunch_reset(void) "" +vm_launchupdate_finalize(void) "" diff --git a/hw/misc/vmlaunchupdate.c b/hw/misc/vmlaunchupdate.c new file mode 100644 index 0000000000..b19cf6b8cd --- /dev/null +++ b/hw/misc/vmlaunchupdate.c @@ -0,0 +1,236 @@ +/* + * Guest driven VM launch component update (using IGVM) device + * For details and specification, please look at docs/specs/vmlaunchupdate= .rst. + * + * Copyright (C) 2026 Red Hat, Inc. + * + * Authors: Ani Sinha + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "qapi/error.h" +#include "qemu/module.h" +#include "system/physmem.h" +#include "system/reset.h" +#include "qemu/target-info-qapi.h" +#include "hw/nvram/fw_cfg.h" +#include "hw/core/qdev-properties.h" +#include "hw/i386/pc.h" +#include "exec/cpu-common.h" +#include "hw/misc/vmlaunchupdate.h" +#include "system/igvm.h" +#include "system/igvm-internal.h" +#include "qemu/error-report.h" +#include "trace.h" + +static bool disabled; + +static bool vmlaunchupdate_supported(void) +{ + return target_arch() =3D=3D SYS_EMU_TARGET_X86_64; +} + +static void init_vm_launch_update(VMLaunchUpdateState *s) +{ + s->launch_update.capabilities =3D VM_LAUNCHUPDATE_FORMAT_IGVM; + + if (disabled) { + s->launch_update.control =3D VM_LAUNCHUPDATE_CTL_DISABLE; + } + + s->launch_update.version =3D VM_LAUNCHUPDATE_VERSION; + return; +} + +static void clear_init_vm_launch_update(VMLaunchUpdateState *s) +{ + memset(&s->launch_update, 0, sizeof(s->launch_update)); + init_vm_launch_update(s); +} + +static int process_x86_igvm(VMLaunchUpdateState *s, + uint64_t fw_image_addr, uint32_t fw_image_size) +{ + X86MachineState *x86machine =3D X86_MACHINE(qdev_get_machine()); + IgvmCfg *igvmc =3D x86machine->igvm; + IgvmHandle igvm; + void *image_addr_ptr; + hwaddr len; + + if (!igvmc) { + /* The VM was not started with an IGVM, bail */ + info_report("guest was not initially started with IGVM, " + "not chnaging launch state."); + return -1; + } + + if (!fw_image_addr || !fw_image_size) { + return -1; + } + + len =3D (hwaddr) fw_image_size; + image_addr_ptr =3D physical_memory_map((hwaddr) fw_image_addr, + (hwaddr *) &len, 0); + + if (!image_addr_ptr || (len < fw_image_size)) { + warn_report("vmlaunchupdate: Invalid guest addresses."); + physical_memory_unmap(image_addr_ptr, len, 0, 0); + return -1; + } + + igvm =3D igvm_new_from_binary(image_addr_ptr, fw_image_size); + if (igvm < 0) { + warn_report("vmlaunchupdate: Unable to parse IGVM file %" + PRIx64 ": %d", fw_image_addr, fw_image_size); + return -1; + } + + /* free previous file context */ + if (igvmc->file >=3D 0) { + igvm_free(igvmc->file); + } + g_free(igvmc->filename); + /* set new context */ + igvmc->file =3D igvm; + + + /* free existing memory regions and ram blocks */ + qigvm_cleanup_memory(igvmc); + + physical_memory_unmap(image_addr_ptr, len, 0, 0); + info_report("vmlaunchupdate: new IGVM context set"); + + return 0; +} + +static void launch_update_write(void *dev, off_t offset, size_t len) +{ + VMLaunchUpdateState *s =3D VMLAUNCHUPDATE(dev); + uint64_t addr; + uint32_t size; + + if (disabled) { + return; + } + + if (s->launch_update.control & VM_LAUNCHUPDATE_CTL_DISABLE) { + disabled =3D true; + return; + } + + + /* process guest provided IGVM image */ + if (s->launch_update.control & VM_LAUNCHUPDATE_FORMAT_IGVM) { + if (target_arch() =3D=3D SYS_EMU_TARGET_X86_64) { + addr =3D le64_to_cpu(s->launch_update.fw_image_addr); + size =3D le32_to_cpu(s->launch_update.fw_image_size); + if (process_x86_igvm(s, addr, size) < 0) { + goto end; + } + + } + /* process other machines here when support is added */ + } + + /* clear the addresses */ + s->launch_update.fw_image_addr =3D 0x0; + s->launch_update.fw_image_size =3D 0x0; + + end: + trace_launch_update_write(); + + return; +} + +static void launch_update_select(void *dev) +{ + VMLaunchUpdateState *s =3D VMLAUNCHUPDATE(dev); + init_vm_launch_update(s); +} + +static void vmlaunch_reset(Object *obj, ResetType type) +{ + trace_vmlaunch_reset(); +} + +static ResettableState *vmlaunch_reset_state(Object *obj) +{ + VMLaunchUpdateState *s =3D VMLAUNCHUPDATE(obj); + + return &s->reset_state; +} + +static void vm_launchupdate_realize(DeviceState *dev, Error **errp) +{ + VMLaunchUpdateState *s =3D VMLAUNCHUPDATE(dev); + FWCfgState *fw_cfg =3D fw_cfg_find(); + + /* multiple devices are not supported */ + if (!vm_launchupdate_find()) { + error_setg(errp, "at most one %s device is permitted", + TYPE_VMLAUNCHUPDATE); + return; + } + + /* if current machine is not supported, do not initialize */ + if (!vmlaunchupdate_supported()) { + error_setg(errp, + "This machine does not support vm-launch-update device"= ); + return; + } + + /* fw_cfg with DMA support is necessary to support this device */ + if (!fw_cfg || !fw_cfg_dma_enabled(fw_cfg)) { + error_setg(errp, "%s device requires fw_cfg", + TYPE_VMLAUNCHUPDATE); + return; + } + + fw_cfg_add_file_callback(fw_cfg, FILE_VMLAUNCHUPDATE, + launch_update_select, launch_update_write, s, + &s->launch_update, + sizeof(s->launch_update), + false); + + clear_init_vm_launch_update(s); + /* + * This device requires to register a global reset because it is + * not plugged to a bus (which, as its QOM parent, would reset it). + */ + qemu_register_resettable(OBJECT(s)); +} + +static void vm_launchupdate_finalize(Object *obj) +{ + qemu_unregister_resettable(obj); + trace_vm_launchupdate_finalize(); +} + +static void vmlaunchupdate_device_class_init(ObjectClass *klass, + const void *data) +{ + DeviceClass *dc =3D DEVICE_CLASS(klass); + ResettableClass *rc =3D RESETTABLE_CLASS(klass); + + /* we are not interested in migration - so no need to populate dc->vms= d */ + dc->desc =3D "VM launch state update device"; + dc->realize =3D vm_launchupdate_realize; + dc->hotpluggable =3D false; + set_bit(DEVICE_CATEGORY_MISC, dc->categories); + rc->phases.hold =3D vmlaunch_reset; + rc->get_state =3D vmlaunch_reset_state; +} + +static const TypeInfo vmlaunchupdate_device_types[] =3D { + { + .name =3D TYPE_VMLAUNCHUPDATE, + .parent =3D TYPE_DEVICE, + .instance_size =3D sizeof(VMLaunchUpdateState), + .class_init =3D vmlaunchupdate_device_class_init, + .instance_finalize =3D vm_launchupdate_finalize, + }, +}; + +DEFINE_TYPES(vmlaunchupdate_device_types) diff --git a/include/hw/misc/vmlaunchupdate.h b/include/hw/misc/vmlaunchupd= ate.h new file mode 100644 index 0000000000..1d13f4b176 --- /dev/null +++ b/include/hw/misc/vmlaunchupdate.h @@ -0,0 +1,85 @@ +/* + * Guest driven VM launch state update device via IGVM. + * For details and specification, please look at docs/specs/vmlaunchupdate= .rst. + * + * Copyright (C) 2026 Red Hat, Inc. + * + * Authors: Ani Sinha + * + * SPDX-License-Identifier: GPL-2.0-or-later + * + */ +#ifndef VMLAUNCHUPDATE_H +#define VMLAUNCHUPDATE_H + +#include "hw/core/qdev.h" +#include "qom/object.h" +#include "qemu/units.h" +#include "system/igvm-cfg.h" + +#define TYPE_VMLAUNCHUPDATE "vm-launch-update" + +/* fw-cfg file definition */ +#define FILE_VMLAUNCHUPDATE "etc/vmlaunchupdate" + +/* version */ +#define VM_LAUNCHUPDATE_VERSION 0x01 + +/* format bits, used by both 'capabilities' and 'control' */ + +/* igvm */ +#define VM_LAUNCHUPDATE_FORMAT_IGVM (1ULL << 32) + +/* 'control' field bits */ + +/* disable vmlaunchupdate interface */ +#define VM_LAUNCHUPDATE_CTL_DISABLE (1 << 0) + +typedef struct { + /* api version */ + uint16_t version; + + /* VMM capabilities, read-only. */ + uint64_t capabilities; + /* control bits, see VMFWUPDATE_CTL_* */ + uint64_t control; + + /* + * address and size of the IGVM image. Will be cleared when + * the write completes successfully and IGVM file is correctly parsed. + */ + uint64_t fw_image_addr; + uint32_t fw_image_size; + + /* + * address + size of opaque blob. The guest can use this to pass on + * information, for example which memory region the linux kernel has b= een + * loaded to. writable, will be kept intact on firmware update. + */ + uint64_t opaque_addr; + uint64_t opaque_size; + +} VMLaunchUpdate; + +typedef struct VMLaunchUpdateState { + DeviceState parent_obj; + VMLaunchUpdate launch_update; + ResettableState reset_state; +} VMLaunchUpdateState; + + +typedef struct VMLaunchUpdateStateClass { + ObjectClass parent_class; +} VMLaunchUpdateStateClass; + +OBJECT_DECLARE_SIMPLE_TYPE(VMLaunchUpdateState, VMLAUNCHUPDATE); + +/* returns NULL unless there is exactly one device */ +static inline VMLaunchUpdateState *vm_launchupdate_find(void) +{ + Object *o =3D object_resolve_path_type("", TYPE_VMLAUNCHUPDATE, NULL); + + return o ? VMLAUNCHUPDATE(o) : NULL; +} + +#endif diff --git a/include/system/igvm.h b/include/system/igvm.h index e219f1a4ed..e6879550b1 100644 --- a/include/system/igvm.h +++ b/include/system/igvm.h @@ -22,6 +22,8 @@ int qigvm_process_file(IgvmCfg *igvm, MachineState *machi= ne_state, bool onlyVpContext, Error **errp); void qigvm_cleanup_memory(IgvmCfg *igvm); =20 +void qigvm_free_memory_regions(void); + /* x86 native */ int qigvm_x86_get_mem_map_entry(int index, ConfidentialGuestMemoryMapEntry *entry, --=20 2.42.0 From nobody Sun Jul 26 12:33:35 2026 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=1782280529; cv=none; d=zohomail.com; s=zohoarc; b=Ur6m0hVvOGSqCKWcEPwj3bafvNRt2mxRBaJx5CvoGexZyB2b1e9N8JO9TP6q1jG1tGby2GnZ+yiH75bXij77n96GyqiV43Uuvx88O2IdS+S/NoryBoIcwZfR1mv+gdp3gjjW9BEV8vtltZTSwC/AAiD+0g49RMOTDy39iQDmX10= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782280529; 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=ADh+O37DTAktIcZ73zzXhpRrNLuHeLwq4/clgPng32A=; b=VsVco3A/N6QvHkNMzAxu5BfjmWEmvtHj6Y3vh+U/tMp9+FFZsf2b4jj8QY8/lltAJWvtomHEiO7vq4i9nqndE/xXqvtjAJfwiPFu2hqBGNhSLSvyayxoUvu9Iu1bEfuypn+/rHzMK1kBCS0s/Qo4zoTeYpUPjk9d6NGlUkWHEX8= 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1782280529950831.200269787202; Tue, 23 Jun 2026 22:55:29 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wcGZJ-00074V-Qo; Wed, 24 Jun 2026 01:54:37 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wcGZH-00073G-7u for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:35 -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 1wcGZD-000671-7y for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:34 -0400 Received: from mail-dy1-f197.google.com (mail-dy1-f197.google.com [74.125.82.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-271-8gZJVO3YN4-w6In-sezdqg-1; Wed, 24 Jun 2026 01:54:27 -0400 Received: by mail-dy1-f197.google.com with SMTP id 5a478bee46e88-30c5b9f6a51so379865eec.1 for ; Tue, 23 Jun 2026 22:54:27 -0700 (PDT) Received: from rhel9-box.lan ([110.227.100.91]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-30c1bd8d6edsm21075803eec.14.2026.06.23.22.54.23 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 22:54:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782280469; 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=ADh+O37DTAktIcZ73zzXhpRrNLuHeLwq4/clgPng32A=; b=M7enAKzM58IIjeviKz9Yw9WUIi1YW/sayh/rrR78KRJvgMWmnFLIyEeF4ARIk16GlOYFdM EQDNeBljUPtE3msNxvuyH20mYYikEkNpUG64I5EEEZSbnqTS0Q5QBEKFGPhf/dlG77yMAx OnA6hgfxlvfs7ROfzhjYE20+6EMYqSs= X-MC-Unique: 8gZJVO3YN4-w6In-sezdqg-1 X-Mimecast-MFC-AGG-ID: 8gZJVO3YN4-w6In-sezdqg_1782280467 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1782280467; x=1782885267; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ADh+O37DTAktIcZ73zzXhpRrNLuHeLwq4/clgPng32A=; b=mGX8OziLXXZERpMhPrEQci+U9EoLGEaMjOuZ1A1wq4lsWfboGd8LhRRrwlQ9+sglQG wjWFSvhXmht3xyBunHqNmDXBTTCjg0xUUi5jvyHu20nUfMwofYbkKJRFreXdswPDehGQ jPchLv5maSn4XLa3htD+JBnjvcvuDwgwvBIkJ16P49P1wjLlPTOyesgO8fpcI6ldL5J4 TN/uwLZwpYqSTgcNMBfVwRZzEgthbHi4PQM5EZtxPGgOBqNI1H/fKqHUZEip34Sr/WHN rNBTYv+I2s4usLX/peiVNdG7e+S3BmNyFYhIWj4mDNyHDVV4ugPSBycV8g6XoszhgylN fHHA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782280467; x=1782885267; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=ADh+O37DTAktIcZ73zzXhpRrNLuHeLwq4/clgPng32A=; b=DrEeLUvFXxto6Vn9x6VC+FsdLRJwxfeHHt8CKxiF7uvyTm7lMb8Pjp7NNlmrjCm4kN Chawy6cv5w3Y2gybE1s75RgH+oV4v8/SgwNgafSHlNGGl6bl8vRlzx8Adktgu4z39+yZ 1sx6wc3Zl5eYR42cDykRm2wD9f9uXYdQj02+JCQnAKq7sUtvDAGCjUIDnEFiMGYsLsWR EgrokQsg0L/2QoHffhiWHbFKZTyh6zNznunTJZSiTLdvCkLH7EByaygnXFQSb6UiM6IJ 0VAOkxVS66dW7DZuqbPbQ1+3cWWBK/d+ZPR9AGLIt03k1PbMkMzO6Ovv5+iQ49dA1AnO OXYA== X-Forwarded-Encrypted: i=1; AHgh+RqIUUsQiHFY6HbazypJdPlxAIQYTMNN1m4OiPTsbSYIe6kNtatrJnCq5Dgmx6G/+eZlkoH/BJwUP5za@nongnu.org X-Gm-Message-State: AOJu0Yz/nWMbNwwZiuBLxvPCi9KyekTr2i3kjeHMnjfCF8q/0WXNE+wk OYOUGDQ/UY79TtsGbIts87x6+gBjMyKOVR7Pz29o4qdYUC0XBrCAfgsqPdQ5YDhU8Q3ELQ1y32i 8Zm7ZLJsGmCWoc5la0DeUegTFyhp/eHZJNaxx5dwruGdt6vaQjm1MtQMy X-Gm-Gg: AfdE7cmhl/ctDvgi1OR2X4JohPUZc+s2KS3FANQp6xbEgjgJX5Zzx9zVeewn9GLJL3y kHguqdD46qmA5xu6mBXTcGnU560fLt/g0DLTYy+248pZfzi+1PUYStMmhksqvr4bFPYyThjehaI fDRuZ3YwNQUVbWJ9UEjZxuh3okbMp34oeV7WBkHVMn8oWSJMDEjLI1jaMa0SCaWZ4n6p0DySCh8 8n3i6Pmq3Z1wK7SN1HoD0DlwmNQXVgZK7mna+lEAJxNEUHoOTjbi1t42igHtVfCqshs8vscxXT8 3LKvtW6MKmlbInx/HDNi72HbWbTD0rgYqkaVFfvV9TspjY8fBgh5eBdzwhC2AMTVZIxP9XUoRNL MeQux59ynd8qWzvOKLDesk7nCHnslcouDTauoGwaJRets X-Received: by 2002:a05:693c:2d82:b0:30c:a0f:3bd0 with SMTP id 5a478bee46e88-30c555dc677mr5660879eec.13.1782280466365; Tue, 23 Jun 2026 22:54:26 -0700 (PDT) X-Received: by 2002:a05:693c:2d82:b0:30c:a0f:3bd0 with SMTP id 5a478bee46e88-30c555dc677mr5660869eec.13.1782280465725; Tue, 23 Jun 2026 22:54:25 -0700 (PDT) From: Ani Sinha To: Pierrick Bouvier , Ani Sinha , Gerd Hoffman Cc: Alex Graf , qemu-devel@nongnu.org Subject: [PATCH v1 5/8] docs/spec: Add a specification document for vm-launch-update device Date: Wed, 24 Jun 2026 11:23:27 +0530 Message-ID: <20260624055339.46862-6-anisinha@redhat.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260624055339.46862-1-anisinha@redhat.com> References: <20260624055339.46862-1-anisinha@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=lists1p.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=anisinha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-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: qemu development 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: 1782280531837158500 Content-Type: text/plain; charset="utf-8" This change adds a specification document and expanation for the vm-launch-update device. CC: Alex Graf CC: Gerd Hoffman Signed-off-by: Ani Sinha --- docs/specs/index.rst | 1 + docs/specs/vmlaunchupdate.rst | 147 ++++++++++++++++++++++++++++++++++ 2 files changed, 148 insertions(+) create mode 100644 docs/specs/vmlaunchupdate.rst diff --git a/docs/specs/index.rst b/docs/specs/index.rst index b7909a108a..3cdf242661 100644 --- a/docs/specs/index.rst +++ b/docs/specs/index.rst @@ -34,6 +34,7 @@ guest hardware that is specific to QEMU. virt-ctlr vmcoreinfo vmgenid + vmlaunchupdate rapl-msr rocker riscv-iommu diff --git a/docs/specs/vmlaunchupdate.rst b/docs/specs/vmlaunchupdate.rst new file mode 100644 index 0000000000..ee6e7599bd --- /dev/null +++ b/docs/specs/vmlaunchupdate.rst @@ -0,0 +1,147 @@ +.. SPDX-License-Identifier: GPL-2.0-or-later + +VMLAUNCHUPDATE INTERFACE SPECIFICATION +###################################### + +Introduction +************ + +``VmLaunchUpdate`` is an extension to ``fw-cfg`` that allows guests to rep= lace +boot state in their virtual machine using IGVM file container. Through a c= ombination +of this ``fw-cfg`` hypervisor interface, an IGVM file containing specific = directives +and with hypervisor stack knowledge, guests can deterministically replace = the launch +state for guests. This is useful for environments like SEV-SNP where the +launch payload becomes the launch digest. Guests can use vm-launch-update = device to +provide a measured, full guest payload (BIOS image, kernel, initramfs, ker= nel +command line) to the virtual machine which enables them to easily reason a= bout +integrity of the resulting system. +It is also to be noted that this mechanism currently works only when the g= uest was +already started with an IGVM file defining its initial launch state. Subse= quent +guest resets will use the launch state as defined in the guest provided IG= VM file, +not the file with which the guest was initially started. If the guest was = not started +with IGVM, writing a new bundle through the ``fw-cfg`` interface has no ef= fect. + +For more information, please see the `KVM Forum 2024 presentation `__ +about this work. + + +.. _KVMFORUM: https://www.youtube.com/watch?v=3DVCMBxU6tAto + +Base Requirements +***************** + +#. **fw-cfg**: + The target system must provide a ``fw-cfg`` interface. For x86 based + environments, this ``fw-cfg`` interface must be accessible through PI= O ports + 0x510 and 0x511. The ``fw-cfg`` interface does not need to be announc= ed as part + of system device tables such as DSDT. The ``fw-cfg`` interface must s= upport the + DMA interface. It may only support the DMA interface for write operat= ions. + +#. **IGVM support**: + The hypervisor must provide support for parsing and executing the IGV= M file bundle. + +#. **Confidential guests**: + For confidential guests, the hypervisor must support guest reset. Oth= erwise, the new + boot state provided through IGVM will not be applied. + +The Fw-cfg File +*************** + +Guests drive vmlaunchupdate through special ``fw-cfg`` files that control = its flow +followed by a standard system reset operation. When the ``vm-launch-update= `` device +is available, it provides the following ``fw-cfg`` file: + +* ``etc/vmlaunchupdate`` - It exposes a structure of the following type, a= ll in + little-endian format: + +.. code-block:: c + :linenos: + + typedef struct { + uint16_t version; + + uint64_t capabilities; + uint64_t control; + + uint64_t fw_image_addr; + uint32_t fw_image_size; + + uint64_t opaque_addr; + uint64_t opaque_size; + + } VMLaunchUpdate; + + +Currently, the ``version`` number (line 2 above) is initialized to the val= ue ``1``. +Only IGVM files are supported at present. The ``capabilities`` (line 4) an= d ``control`` (line 5) both support +the following single value: + +* ``VM_LAUNCHUPDATE_FORMAT_IGVM`` + + This value is used by the hypervisor to indicate that only IGVM containe= r files are supported. + This is set as a part of ``capabilities`` parameter (line 4) in the abo= ve structure. This same value + is passed by the guest to the hypervisor in the ``control`` parameter (l= ine 5) in the above structure + to indicate that the guest passed IGVM file in memory to the hypervisor.= The starting guest physical + address of the IGVM file in memory is specified in ``fw_image_addr`` and= it's length is specified in + ``fw_image_size`` by the guest. If any other value is passed by the gues= t in the ``control`` parameter, + the write is ignored by the hypervisor. + +One additional ``control`` parameter is supported in order to disable the = interface: + +* ``VM_LAUNCHUPDATE_CTL_DISABLE`` + + This value is set in the ``control`` parameter by the guest in order to = disable this ``fw-cfg`` + hypervisor interface from further updating the guest launch state with a= new IGVM file. + +``fw_image_addr`` (line 7) is the base guest physical address of the guest= memory where the IGVM file of size +``fw_image_size`` (line 8) is loaded. ``opaque_addr`` (line 10) and ``opaq= ue_size`` (line 11) are used by +the guest for passing data across resets. The contents of this guest memor= y are preserved across the +reset. For confidential guests, this memory region must come from guest sh= ared unencrypted memory. + +Triggering the Launch State Update using IGVM +********************************************* + +To initiate the launch update process, the guest issues a standard system = reset +operation through any of the means implemented by the machine model. + +On a write to the ``etc/vmlaunchupdate`` interface, the hypervisor evaluat= es whether this +hypervisor interface is disabled. If it is, it ignores any writes to this = ``fw-cfg`` file +by the guest. No updates to initial launch state is performed. + +If the hypervisor interface is enabled, upon write to the ``etc/vmlaunchup= date`` interface, +the hypervisor parses the IGVM file bundle passed to it in memory, with st= arting guest physical +address at ``fw_image_addr`` and length ``fw_image_size``. If parsing is s= uccessful, it creates +a context handle to the IGVM file. If parsing and context loading is succe= ssful and there are no +errors, ``fw_image_addr`` and ``fw_image_size`` are cleared. The guest can= check this in order +to determine if the IGVM was successfully parsed and the new context was l= oaded. If not, the +guest can throw error and abort rebooting to new IGVM boot state. +Upon guest reset, the hypervisor executes the IGVM bundle using +the context handle, setting the initial launch state of the guest accordin= gly. +If an invalid IGVM file is passed, parsing the file fails and the hypervis= or ignores it +when ``fw-cfg`` files are written. In this case, the initial launch state +is not modified. If invalid addresses are passed, the hypervisor ignores t= hem as well and no +new launch state is set. + +The launch state update mechanism works both for confidential and non-conf= idential +guests. In confidential guests, as a part of the reset operation, all exis= ting +guest shared memory (shared with the hypervisor) as well as the guest memo= ry region +starting with ``opaque_addr`` and length ``opaque_size`` are preserved. +The reset causes recreation of the VM context which triggers a fresh +measurement of the replaced BIOS region and reset CPU state. + +For non-confidential guests, there is no concept of guest private memory a= nd all the existing +guest memory is preserved (this is the default behavior today - QEMU does = not reset/clear +guest memory upon reset). + +In both confidential and non-confidential cases, CPU and device state are = reset to +the reset states specified in IGVM. In confidential environments, the guest +always resumes operation in the highest privileged mode available to it (V= MPL0 in SEV-SNP). + +Closing Remarks +*************** +The exact content of the memory region specified by starting address ``opa= que_addr`` +and length ``opaque_size`` is guest specific and is hypervisor agnostic. T= he hypervisor does +not care about the contents of this memory region. Therefore, it is not in= cluded in this +specification. As of writing this document, TDX guests on QEMU does not su= pport IGVM. +Therefore, this mechanism cannot be used to change launch state of TDX gue= sts. + --=20 2.42.0 From nobody Sun Jul 26 12:33:35 2026 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=1782280530; cv=none; d=zohomail.com; s=zohoarc; b=JY8Xku3s03m16DPvYPzSN5OgM1OV6KqmkILYksq7fBLEkOLxdl8+FHVba1kJb6R6SGxGLJXvjVsfHxhqUOUCRJyTtaTvmYmcwv+mP7YlwvO889E86LRRir5ay5KkP7j0530sGsrvW08d4P8h5BB+Hpe7iO3Bo3li47WE0GOvzfE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782280530; 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=H7I+7UyfZpuokuRVtkKAjCJ6x81P+gjhmb7WODDDQ9g=; b=CKs8eraAlIcfaWA3snNc0R53fHtc5eTx8+dfC+yj646xOyEPlELLSuYkX4mfLl+GAENvbgDvyVGjoVrv92YbEl8iNYHq58YzHd1numUBDfuj4j5F+QKrvxqn4XJAJLqNfMaYWXo76lFJ99vkNwoJI//zRFHSOvoF52rTVLKGdHY= 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1782280530067780.4537390256824; Tue, 23 Jun 2026 22:55:30 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wcGZX-00079P-1j; Wed, 24 Jun 2026 01:54:52 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wcGZS-00078a-I9 for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:46 -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 1wcGZM-0006JP-2e for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:45 -0400 Received: from mail-dy1-f199.google.com (mail-dy1-f199.google.com [74.125.82.199]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-227-keZ_tzoqNVyVpBl2cOzkLg-1; Wed, 24 Jun 2026 01:54:36 -0400 Received: by mail-dy1-f199.google.com with SMTP id 5a478bee46e88-30c5319332eso915494eec.1 for ; Tue, 23 Jun 2026 22:54:36 -0700 (PDT) Received: from rhel9-box.lan ([110.227.100.91]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-30c1bd8d6edsm21075803eec.14.2026.06.23.22.54.26 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 22:54:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782280479; 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=H7I+7UyfZpuokuRVtkKAjCJ6x81P+gjhmb7WODDDQ9g=; b=jFnzJQYL3TQyKWJUFMS54QqgXpBROrYav0DD36n3Xma/4RPHXXhojdF8iWaJpZotS+7xwQ zIIXuoxhggbSXo+DT7QPAkcrvIwUKduJJ9eX/XTKJe8roHsMr3nZ/2u17ohXy0f48+u6NI h0SVIfdkBPlP/UAau8e0mfw5zscSE30= X-MC-Unique: keZ_tzoqNVyVpBl2cOzkLg-1 X-Mimecast-MFC-AGG-ID: keZ_tzoqNVyVpBl2cOzkLg_1782280475 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1782280475; x=1782885275; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=H7I+7UyfZpuokuRVtkKAjCJ6x81P+gjhmb7WODDDQ9g=; b=qcneY0jZQ2a7X1RwJHx8FT3AdjDeCTon1EDWlNoL3RNmpRcTp1EdXhJf8O2bFlJv8J yVgOeP4hz2W5bK+re8Iiv97zi76fKQv9QoplDNhQHkLkRMnRLHX50gFdamfUIiZRM7N7 gGr3BNOIbzPHILZC2tSfEBdPk/FLFh1IFJY/RxhJkyyfT833du6Hgz1SHP4NvOS8n404 MduLxP4w6TmQX4aku4wHra08Qz5dvjRWA5P47J4M/vuSiVvrdAWIV1Azq6HRI/vghz5R HQiuszYGb3/qQdKk83fMuLUOvsWwl8ap8yNY1+oR6z4fpAEDxpxpiaTa9qIRjEJj0NBM 0z2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782280475; x=1782885275; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=H7I+7UyfZpuokuRVtkKAjCJ6x81P+gjhmb7WODDDQ9g=; b=SeAVdhzpt/uB5K9RRaCgQmrZgUhGK40fdWfDyAYPh7/1IVARRKDw1LZ9+fIshbyPeV seC98TXW6KKe7plts2MfaWHrzaBjTsSg+w7s081kdOkBIzqlQucnX27BQy7F/VxbF5by hi69Tud2+5jDsJwV8Dem8LiAPaBYSO+5WWOHg+nsff5EOMj6p5i7qKgTRbAkmS2a6jz4 JgkOCgLue2m37Jm4HHoT8ZqX3JaxJ7a4jl0m/E3duygAmwGxJzppRLEB1rnRWnoCyakX K5rw2+RyzMJpZXu0iQrvCnPtUqr7KT8hkx5/KkYv8eM5rPjIMIfCNCE7p/894QoT5d+p FIYg== X-Forwarded-Encrypted: i=1; AHgh+RpLpGdzty3sYnk5lgmaWaDmOcaQWEJZV4XhsFMLCsMnoJUdZm4NUSRX3oUsuCofx0DeAmoN/pYhWdpo@nongnu.org X-Gm-Message-State: AOJu0YxcCK42cz/UfMttS81R86ZygQ5vPOgfjU16fosJ0SGGDZDhm5GC PqCDuBdxCme+b+71e8vF6Bywf6LxNpp77/U1xExCxIElB7AxAPQOZgth9z8AH1m7VVmfNFA97Ue rLmBW5BZMjccm1vbPx/fDnZcKWLtOXMpthZCoFAOox0/wRlWbqmEQTq+J X-Gm-Gg: AfdE7cmgDp6kzFCexZwo2Uq0EPNTreGZdOhwsGGGJ5okUQ8liwURREv3dV2ii7LvWU2 dUNcrwi0ReqjWED5Xf0XdcAKjdlTf4eV2As+8wdNQnQmR4unuRNHINWAKhpAa4k1jMrdO1yLK0A EFyfmo9CiZM43Il4deu0ybQENLZuzqL1X7BB3wQqs+7EB+wXPOJoLE7AH5p9hzeVrMk05WZhhtb 8dgVMGsixGIbMyJJgvzz0ibdZNfsBHkgSJK1C4Y7C+ZPuKIAkSTrEdrTOFcHFov1qvigWkrOuPl Ex0fsbg/iYvLNxj3+27pC0o8R0u6bivyyhj5XE8PfG47zMPnNeqzGUlBbf1RCdni8PmgqQkI9Q4 JZv/2mt6dBo8kkNRD5FVGCoFm2RViU+UZmkMBo5yeuZiP X-Received: by 2002:a05:7300:2209:b0:30b:f3b8:3e7f with SMTP id 5a478bee46e88-30c68c43c61mr2121970eec.1.1782280472010; Tue, 23 Jun 2026 22:54:32 -0700 (PDT) X-Received: by 2002:a05:7300:2209:b0:30b:f3b8:3e7f with SMTP id 5a478bee46e88-30c68c43c61mr2121941eec.1.1782280470078; Tue, 23 Jun 2026 22:54:30 -0700 (PDT) From: Ani Sinha To: Ani Sinha , Gerd Hoffman Cc: Alex Graf , qemu-devel@nongnu.org Subject: [PATCH v1 6/8] tests/qtest: Add small igvm files for testing purpose Date: Wed, 24 Jun 2026 11:23:28 +0530 Message-ID: <20260624055339.46862-7-anisinha@redhat.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260624055339.46862-1-anisinha@redhat.com> References: <20260624055339.46862-1-anisinha@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=lists1p.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=anisinha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-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: qemu development 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: 1782280531801158500 Content-Type: text/plain; charset="utf-8" Needed by launchupdate-test.c. README file is added with explanation on how to build these IGVM files. CC: Alex Graf CC: Gerd Hoffman Signed-off-by: Ani Sinha --- tests/data/igvm/README | 24 ++++++++++++++++++++++++ tests/data/igvm/hello.igvm | Bin 0 -> 153624 bytes tests/data/igvm/qemuinit.igvm | Bin 0 -> 256856 bytes 3 files changed, 24 insertions(+) create mode 100644 tests/data/igvm/README create mode 100644 tests/data/igvm/hello.igvm create mode 100644 tests/data/igvm/qemuinit.igvm diff --git a/tests/data/igvm/README b/tests/data/igvm/README new file mode 100644 index 0000000000..e785099579 --- /dev/null +++ b/tests/data/igvm/README @@ -0,0 +1,24 @@ +Small IGVM file bundles required for tesing vm-launch-update device +=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D= =3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D + +This directory contains IGVM files required for launchupdate-test.c. +These IGVM bundles can be built from the following repository: +https://gitlab.com/anisinha/virt-firmware-rs + +Just type "make" in the top of the repository. The built IGVM files +can be found in the target/x86_64-unknown-none/debug directory. + +$ ls -l ./target/x86_64-unknown-none/debug/*.igvm +-rw-r--r--. 1 anisinha anisinha 153624 Jun 8 10:05 ./target/x86_64-unknow= n-none/debug/hello.igvm +-rw-r--r--. 1 anisinha anisinha 157848 Jun 8 10:05 ./target/x86_64-unknow= n-none/debug/igvmtest.igvm +-rw-r--r--. 1 anisinha anisinha 987384 Jun 8 10:05 ./target/x86_64-unknow= n-none/debug/mefisto.igvm +-rw-r--r--. 1 anisinha anisinha 368312 Jun 8 10:05 ./target/x86_64-unknow= n-none/debug/qemuinit.igvm +-rw-r--r--. 1 anisinha anisinha 223944 Jun 8 10:05 ./target/x86_64-unknow= n-none/debug/snptest.igvm + + +Following files are used by the tests/qtest/launchupdate-test.c: + +hello.igvm +qemuinit.igvm + + diff --git a/tests/data/igvm/hello.igvm b/tests/data/igvm/hello.igvm new file mode 100644 index 0000000000000000000000000000000000000000..62196ba40a1bd63a7fb68cdb3eb= 26ac93fed40db GIT binary patch literal 153624 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

wA#imq72Gq!+;-p^pz_^0R-=3DZzMhEdP}|K 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 (p=quarantine dis=none) Return-Path: Received: from lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1782280513925163.4025164800904; Tue, 23 Jun 2026 22:55:13 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wcGZP-000778-Ig; Wed, 24 Jun 2026 01:54:43 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wcGZO-00076T-9q for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:42 -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 1wcGZL-0006HK-7g for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:41 -0400 Received: from mail-dy1-f198.google.com (mail-dy1-f198.google.com [74.125.82.198]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-39-NslUdNAKMsOS1XHwgvRK3A-1; Wed, 24 Jun 2026 01:54:36 -0400 Received: by mail-dy1-f198.google.com with SMTP id 5a478bee46e88-30c13bb8ca9so833010eec.0 for ; Tue, 23 Jun 2026 22:54:36 -0700 (PDT) Received: from rhel9-box.lan ([110.227.100.91]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-30c1bd8d6edsm21075803eec.14.2026.06.23.22.54.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 22:54:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782280478; 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=34jMeIE3M2vwUm6cv4K9cmcXI75mLxkqEp1TheFx/gw=; b=QXwnkkU58xTGO7F6+VZQIxcJDjsj7NKLt6jafP4IeHyyKimsjP4+nvPNfhcGo3I7RK6Lys K3UKPkWedMDF9BEpQ9Ebbk/MfpnPy2V3wpnAh/mnIJpzoC3GWPJoU8EH4y50sx3kso0twv Z3+BiZdPVkCQRi7yEwLR4fB1ggyOG3c= X-MC-Unique: NslUdNAKMsOS1XHwgvRK3A-1 X-Mimecast-MFC-AGG-ID: NslUdNAKMsOS1XHwgvRK3A_1782280475 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1782280475; x=1782885275; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=34jMeIE3M2vwUm6cv4K9cmcXI75mLxkqEp1TheFx/gw=; b=j76Mx0Cg3jtpY2u585O26w+r7eHUw/waeDPIOtOwARM39QrTJt3Yabq1LAM6Kz/jfq fJ/hHCkvbDTyEBdXHH8DcchuoffyByKd/TaQt8Faf153xT2mmkbWev4WRZ8YTLJYzpGl TABSc8wRgetGOeoqxarFH9q1Akl0Zln5jM1XsPVR2UceKvO/qhboKVxnLbpjWVebOr8y EuD/SVFSUZ193y5LpyMLGAVmt3KKhis+oOrX3KcfpQPbJ6PNZtg1zz03T+8GjOgpxUHK OYojqTjerZawA120S2kpSfWZKGaur8dnmTqm1sIbCCEtLn18HWrfhUfCZqt331xjNL4j A7GQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782280475; x=1782885275; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=34jMeIE3M2vwUm6cv4K9cmcXI75mLxkqEp1TheFx/gw=; b=hjps9gCE2L0cI7LA3gwTG1pnG7N8dAWQ/ZN5tXLUVoiFrHZt+5RBaygra8Im2M686E dDxPc6ByBFSPLAsbd1yEGduIUFVGtmUXfJQ6n8awLNZLlhvFpXU80nfLIDLFHyxpxD3h A4iu0mtM7mcHzbCLK47zuBNNYCD3kgUCwUJFusEjs7ZnZrEuvQY3XUeqVPK9CopLjpos nqREVJFlffyV5XbICNgGhS+eWntdQYmcFCiDD2B01nQuKB/5n+bDkrCEqva8gjnLjTz6 XwK7dl+zH7P8fLVYF1p55oAi7KUQ4At8tyX0cJ1bl7Fnv3WLCBgLF6izo+zqbWPsNlX6 h/nQ== X-Forwarded-Encrypted: i=1; AHgh+RpacJWGOqn018ug+1qwY81X6KGMwg2q9qNs9qfrYhSQe9FGDugZmR/ynFYvy5tBz7nEnoA3yqa3zhcu@nongnu.org X-Gm-Message-State: AOJu0YyzI8O2CJWmG931y1eIxY612H7xgn1wNCRPEP0/TmHKeagau/wD HiwvRkTpXvTyVZyaNjcu8ebYWpQrnDmSH9xwCu9gq7LkahUxvoXiLGFPDZGZfKwg7XWBE/eloWZ 9X9EMFMNYgG8Otezuh7FMn6W9bJM/LmUIjAzL7lHvnFTSFvXGIr+Pos4H X-Gm-Gg: AfdE7clu/8kh4xsaLjOMw8Ch9gh26XE5a34n3T2FMVVjAqNoCwM9TDglVmmKmb5n3og g20yemAf4IuTFVDc2sAblY48I23HMiFdVuQctUFUG6xBXMO2H/YjuLk2tDWXZ875fXdjpdFKlZd N/oszEs7/5jCoPurH4zwRWi3WTzaD/fO/O3lDYoQnhRGNdd1Ulp045aMKwySEh1YBwkr7r8SHUd R9/5NDgqWNHuE2SJSQ4if+4TnvlANsD1Z9i44sEKEiaiznMnMCAekyAaTPOPFYQpzLZ6jVtX8Nd HFzvtUDmgKTUcnX51XexL77SRqOsnSoVNfzCmt4q9kcRtt4MilQ2Thu/kha7lHIqAqPETQ+tR+9 R48wHLMMBohDIUbpUfEWw/kNy3Ib1BijtgpOS+LTCDbrg X-Received: by 2002:a05:7300:80cf:b0:304:4f23:4466 with SMTP id 5a478bee46e88-30c68d23953mr2386320eec.15.1782280475101; Tue, 23 Jun 2026 22:54:35 -0700 (PDT) X-Received: by 2002:a05:7300:80cf:b0:304:4f23:4466 with SMTP id 5a478bee46e88-30c68d23953mr2386298eec.15.1782280474506; Tue, 23 Jun 2026 22:54:34 -0700 (PDT) From: Ani Sinha To: Peter Maydell , Ani Sinha , Gerd Hoffman , Paolo Bonzini , Zhao Liu , Fabiano Rosas , Laurent Vivier Cc: Alex Graf , qemu-arm@nongnu.org, qemu-devel@nongnu.org Subject: [PATCH v1 7/8] Add functional and unit tests for the vm-launch-update device Date: Wed, 24 Jun 2026 11:23:29 +0530 Message-ID: <20260624055339.46862-8-anisinha@redhat.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260624055339.46862-1-anisinha@redhat.com> References: <20260624055339.46862-1-anisinha@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=lists1p.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=anisinha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_PASS=-0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: qemu development 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: 1782280515914158500 Content-Type: text/plain; charset="utf-8" This patchset adds functional and unit tests that exercize various functions and behaviors of vm-launch-update device. It uses the IGVM files that were introduced in the previous patch for exercizing the hypervisor interface. CC: Alex Graf CC: Gerd Hoffman Signed-off-by: Ani Sinha --- tests/functional/aarch64/meson.build | 1 + .../aarch64/test_vm_launch_update_aarch.py | 33 ++ tests/functional/x86_64/meson.build | 1 + .../x86_64/test_vm_launch_update.py | 48 +++ tests/qtest/launchupdate-test.c | 321 ++++++++++++++++++ tests/qtest/meson.build | 2 + 6 files changed, 406 insertions(+) create mode 100755 tests/functional/aarch64/test_vm_launch_update_aarch.py create mode 100755 tests/functional/x86_64/test_vm_launch_update.py create mode 100644 tests/qtest/launchupdate-test.c diff --git a/tests/functional/aarch64/meson.build b/tests/functional/aarch6= 4/meson.build index e81afd6c39..b07373189e 100644 --- a/tests/functional/aarch64/meson.build +++ b/tests/functional/aarch64/meson.build @@ -23,6 +23,7 @@ test_aarch64_timeouts =3D { tests_aarch64_system_quick =3D [ 'migration', 'vmstate', + 'vm_launch_update_aarch', ] =20 tests_aarch64_system_thorough =3D [ diff --git a/tests/functional/aarch64/test_vm_launch_update_aarch.py b/test= s/functional/aarch64/test_vm_launch_update_aarch.py new file mode 100755 index 0000000000..2b3d7cf4a3 --- /dev/null +++ b/tests/functional/aarch64/test_vm_launch_update_aarch.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +# +# Check for vm-launch-update device. +# +# Copyright (c) 2026 Red Hat, Inc. +# +# Author: +# Ani Sinha +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import QemuSystemTest + +class VmLaunchUpdateDeviceCheck(QemuSystemTest): + + def aarch64_fail_test(self): + """ + Currently the device is only supported for pc platforms. + """ + self.vm.add_args('-machine', 'virt', '-device', + 'vm-launch-update,id=3Dfwupd1') + self.vm.set_qmp_monitor(enabled=3DFalse) + self.vm.launch() + self.vm.wait() + self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be = 1") + self.assertRegex(self.vm.get_log(), + r'This machine does not support vm-launch-update devic= e') + + def test_vm_launch_update(self): + self.aarch64_fail_test() + +if __name__ =3D=3D '__main__': + QemuSystemTest.main() diff --git a/tests/functional/x86_64/meson.build b/tests/functional/x86_64/= meson.build index 1ed10ad6c2..9b98e61e63 100644 --- a/tests/functional/x86_64/meson.build +++ b/tests/functional/x86_64/meson.build @@ -18,6 +18,7 @@ tests_x86_64_system_quick =3D [ 'pc_cpu_hotplug_props', 'virtio_version', 'vmstate', + 'vm_launch_update', ] =20 # The address-sanitizer makes mlock() a no-op because it diff --git a/tests/functional/x86_64/test_vm_launch_update.py b/tests/funct= ional/x86_64/test_vm_launch_update.py new file mode 100755 index 0000000000..aac7ef915f --- /dev/null +++ b/tests/functional/x86_64/test_vm_launch_update.py @@ -0,0 +1,48 @@ +#!/usr/bin/env python3 +# +# Check for vm-launch-update device. +# +# Copyright (c) 2026 Red Hat, Inc. +# +# Author: +# Ani Sinha +# +# SPDX-License-Identifier: GPL-2.0-or-later + +from qemu_test import QemuSystemTest +import time + +class VmLaunchUpdateDeviceCheck(QemuSystemTest): + DELAY_BOOT_SEQUENCE =3D 1 + + def vm_launch_update_pass(self): + """ + Basic test to make sure vm-launch-update device can be instantiate= d. + """ + self.vm.add_args('-device', 'vm-launch-update,id=3Dfwupd1') + self.vm.set_qmp_monitor(enabled=3DFalse) + self.vm.launch() + time.sleep(self.DELAY_BOOT_SEQUENCE) + self.vm.shutdown() + self.assertEqual(self.vm.exitcode(), 0, "QEMU exit code should be = 0") + + def multiple_device_fail(self): + """ + Only one vm-launch-update device can be instantiated. Ensure failu= re if + user tries to create more than one device. + """ + self.vm.add_args('-device', 'vm-launch-update,id=3Dfw1', + '-device', 'vm-launch-update,id=3Dfw2') + self.vm.set_qmp_monitor(enabled=3DFalse) + self.vm.launch() + self.vm.wait() + self.assertEqual(self.vm.exitcode(), 1, "QEMU exit code should be = 1") + self.assertRegex(self.vm.get_log(), + r'at most one vm-launch-update device is permitte= d') + + def test_vm_launch_update(self): + self.vm_launch_update_pass() + self.multiple_device_fail() + +if __name__ =3D=3D '__main__': + QemuSystemTest.main() diff --git a/tests/qtest/launchupdate-test.c b/tests/qtest/launchupdate-tes= t.c new file mode 100644 index 0000000000..ac5b820864 --- /dev/null +++ b/tests/qtest/launchupdate-test.c @@ -0,0 +1,321 @@ +/* + * vmlaunchupdate device fwcfg test. + * + * Copyright (c) 2026 Red Hat, Inc. + * + * Author: + * Ani Sinha + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ + +#include "qemu/osdep.h" +#include "libqos/libqos-pc.h" +#include "libqtest.h" +#include "standard-headers/linux/qemu_fw_cfg.h" +#include "libqos/fw_cfg.h" +#include "qemu/bswap.h" +#include "hw/misc/vmlaunchupdate.h" + +#define WAIT_SEC 10 +static bool debug; +static bool confidential; + +static void test_vm_launch_update_capability(void) +{ + QFWCFG *fw_cfg; + QTestState *s; + VMLaunchUpdate launch_update; + size_t filesize; + uint64_t capabilities; + + s =3D qtest_init("-device vm-launch-update"); + fw_cfg =3D pc_fw_cfg_init(s); + + filesize =3D qfw_cfg_get_file(fw_cfg, FILE_VMLAUNCHUPDATE, + &launch_update, sizeof(launch_update)); + g_assert_cmpint(filesize, =3D=3D, sizeof(launch_update)); + capabilities =3D le64_to_cpu(launch_update.capabilities); + g_assert_cmpint(capabilities, =3D=3D, VM_LAUNCHUPDATE_FORMAT_IGVM); + pc_fw_cfg_uninit(fw_cfg); + qtest_quit(s); +} + + +static void test_vm_launch_update_disable(void) +{ + QFWCFG *fw_cfg; + QOSState *qs; + VMLaunchUpdate launch_update; + uint64_t control; + size_t filesize; + + qs =3D qtest_pc_boot("-device vm-launch-update"); + + fw_cfg =3D pc_fw_cfg_init(qs->qts); + + filesize =3D qfw_cfg_get_file(fw_cfg, FILE_VMLAUNCHUPDATE, + &launch_update, sizeof(launch_update)); + g_assert_cmpint(filesize, =3D=3D, sizeof(launch_update)); + control =3D le64_to_cpu(launch_update.control); + g_assert_cmpint(VM_LAUNCHUPDATE_CTL_DISABLE & control, =3D=3D, 0); + + /* disable the device */ + memset(&launch_update, 0, sizeof(launch_update)); + launch_update.control |=3D VM_LAUNCHUPDATE_CTL_DISABLE; + + filesize =3D qfw_cfg_write_file(fw_cfg, qs, FILE_VMLAUNCHUPDATE, + &launch_update, sizeof(launch_update)); + g_assert_cmpint(filesize, =3D=3D, sizeof(launch_update)); + + /* try to clear the dsable flag */ + memset(&launch_update, 0, sizeof(launch_update)); + + filesize =3D qfw_cfg_write_file(fw_cfg, qs, FILE_VMLAUNCHUPDATE, + &launch_update, sizeof(launch_update)); + g_assert_cmpint(filesize, =3D=3D, sizeof(launch_update)); + + /* check if the device is still disabled */ + filesize =3D qfw_cfg_get_file(fw_cfg, FILE_VMLAUNCHUPDATE, + &launch_update, sizeof(launch_update)); + g_assert_cmpint(filesize, =3D=3D, sizeof(launch_update)); + control =3D le64_to_cpu(launch_update.control); + g_assert_cmpint(VM_LAUNCHUPDATE_CTL_DISABLE & control, =3D=3D, 1); + + pc_fw_cfg_uninit(fw_cfg); + qtest_shutdown(qs); +} + +static int64_t get_image_size(const char *filename) +{ + int fd; + int64_t size; + fd =3D open(filename, O_RDONLY | O_BINARY); + g_assert_true(fd > 0); + size =3D lseek(fd, 0, SEEK_END); + close(fd); + return size; +} + +static ssize_t load_image(const char *igvm_f, void **addr, size_t *size) +{ + ssize_t actsize =3D 0, l =3D 0; + int f_igvm_f; + size_t l_size; + + f_igvm_f =3D open(igvm_f, O_RDONLY | O_BINARY); + g_assert_true(f_igvm_f); + l_size =3D get_image_size(igvm_f); + g_assert_true(l_size > 0); + *addr =3D g_malloc0(l_size); + g_assert_true(*addr); + + while (l < l_size) { + actsize =3D read(f_igvm_f, *addr + l, 1); + if (actsize < 0) { + break; + } + l +=3D actsize; + } + + close(f_igvm_f); + *size =3D l_size; + return actsize < 0 ? -1 : l; +} + +static gboolean match_hello_world(char *serial_f, const char *exp_out) +{ + GError *error =3D NULL; + g_autofree gchar *f_contents =3D NULL; + g_autofree GRegex *regex =3D NULL; + g_autofree GMatchInfo *match_info =3D NULL; + gsize len; + gboolean ret; + + ret =3D g_file_get_contents(serial_f, &f_contents, &len, &error); + g_assert(ret); + g_assert_no_error(error); + + regex =3D g_regex_new(exp_out, G_REGEX_CASELESS, 0, &error); + g_assert_no_error(error); + + ret =3D g_regex_match_full(regex, f_contents, -1, 0, 0, &match_info, &= error); + g_assert_no_error(error); + + return ret; +} + +static int wait_for_match(char *serial_f, + const char *exp_out, int64_t timeout_s) +{ + time_t start, delta; + int ret =3D -1; + + start =3D time(NULL); + while (1) { + if (match_hello_world(serial_f, exp_out)) { + ret =3D 0; + break; + } + + delta =3D time(NULL) - start; + if (delta >=3D timeout_s) { + fprintf(stderr, "timed out waiting to read serial output\n"); + break; + } + + /* wait 20 ms before trying again */ + if (false) { + fprintf(stderr, + "sleeping 20 ms before checking serial output again.\n= "); + } + g_usleep(20000); + } + return ret; +} + +static void test_load_igvm(void) +{ + const char *igvm_f; + const char *igvm_init; + int ser_fd; + g_autofree void *igvm_blob =3D NULL; + g_autofree char *serialtmp =3D NULL; + const char exp_out[] =3D "Hello world!"; + const char exp_out2[] =3D "Test succeeded!"; + const char *snp, *cgs; + uint64_t gaddr; + size_t igvm_sz; + size_t filesize; + QFWCFG *fw_cfg; + QOSState *qs; + VMLaunchUpdate launch_update; + + if (confidential) { + snp =3D "-object \'{\"qom-type\":\"sev-snp-guest\",\"id\":\"lsec0\= "," + "\"cbitpos\":51,\"reduced-phys-bits\":1,\"policy\":196608}\'"; + cgs =3D "confidential-guest-support=3Dlsec0"; + /* + * The following two IGVM files can be built from the source + * present in https://gitlab.com/anisinha/virt-firmware-rs . + * Typing 'make' from the top of this repository will build the + * IGVM files for both confidential and + * non-confidential tests. The IGVM files for the non-coco + * case has been checked-in into the QEMU repository for + * convenience and easy CI pipeline testing. + */ + igvm_f =3D "tests/data/igvm/snptest.igvm"; /* + * this prints 'hello wor= ld' + * on console + */ + igvm_init =3D "tests/data/igvm/snptest-nohello.igvm"; + } else { + igvm_f =3D "tests/data/igvm/hello.igvm"; + igvm_init =3D "tests/data/igvm/qemuinit.igvm"; + snp =3D ""; + cgs =3D ""; + } + + if (!g_file_test(igvm_f, G_FILE_TEST_EXISTS)) { + g_test_skip("igvm file bundle does not exist!"); + return; + } + + ser_fd =3D g_file_open_tmp("launchupdate-qtest-serial-sXXXXXX", + &serialtmp, NULL); + g_assert_true(ser_fd !=3D -1); + + if (debug) { + fprintf(stderr, "serial console file is %s\n", serialtmp); + } + + qs =3D qtest_pc_boot("-machine q35,igvm-cfg=3Digvm0,%s -m 1G -accel kv= m " + "-device vm-launch-update " + "-chardev file,id=3Dserial0,path=3D%s " + "-serial chardev:serial0 " + "-object igvm-cfg,id=3Digvm0,file=3D%s %s", + cgs, serialtmp, igvm_init, snp); + + fw_cfg =3D pc_fw_cfg_init(qs->qts); + + if (debug) { + fprintf(stderr, "target endianness: %s\n", + qtest_big_endian(qs->qts) ? "big" : "little"); + } + + g_assert_true(load_image(igvm_f, &igvm_blob, &igvm_sz) =3D=3D igvm_sz); + + /* create a data buffer in guest memory */ + gaddr =3D guest_alloc(&qs->alloc, igvm_sz); + + if (debug) { + fprintf(stderr, "guest paddr: %"PRIx64 " igvm size: %lu\n", + gaddr, igvm_sz); + } + + if (debug) { + fprintf(stderr, "writing igvm file into the guest memory\n"); + } + + qtest_bufwrite(qs->qts, gaddr, igvm_blob, igvm_sz); + + if (debug) { + fprintf(stderr, + "tell hypervisor where igvm is loaded in guest memory\n"); + } + + /* now tell hypervisor where we loaded the bios */ + memset(&launch_update, 0, sizeof(launch_update)); + launch_update.fw_image_size =3D cpu_to_le32(igvm_sz); + launch_update.fw_image_addr =3D cpu_to_le64(gaddr); + launch_update.control |=3D VM_LAUNCHUPDATE_FORMAT_IGVM; + + filesize =3D qfw_cfg_write_file(fw_cfg, qs, FILE_VMLAUNCHUPDATE, + &launch_update, sizeof(launch_update)); + g_assert_cmpint(filesize, =3D=3D, sizeof(launch_update)); + + if (debug) { + fprintf(stderr, "resetting the virtual machine now\n"); + } + + qtest_system_reset(qs->qts); + + /* expected string should be printed on the console */ + g_assert_true(wait_for_match(serialtmp, exp_out, WAIT_SEC) =3D=3D 0); + g_assert_true(wait_for_match(serialtmp, exp_out2, WAIT_SEC) =3D=3D 0); + + close(ser_fd); + + guest_free(&qs->alloc, gaddr); + pc_fw_cfg_uninit(fw_cfg); + /* qtest_quit() kils QEMU, first by sending SIGTERM, then SIGKILL */ + qtest_quit(qs->qts); +} + +int main(int argc, char **argv) +{ + const char *arch =3D qtest_get_arch(); + + g_test_init(&argc, &argv, NULL); + + if (strcmp(arch, "i386") && strcmp(arch, "x86_64")) { + g_printerr("vmlaunchupdate tests are only available on x86\n"); + exit(EXIT_FAILURE); + } + + g_test_add_func("/vm-launch-update/cap", test_vm_launch_update_capabil= ity); + g_test_add_func("/vm-launch-update/disabled", + test_vm_launch_update_disable); + + g_test_add_func("/vm-launch-update/load_igvm", + test_load_igvm); + + if (getenv("LAUNCHUPDATE_DEBUG")) { + debug =3D true; + } + if (getenv("COCO")) { + confidential =3D true; + } + + return g_test_run(); +} diff --git a/tests/qtest/meson.build b/tests/qtest/meson.build index 4897325d84..d23c76963e 100644 --- a/tests/qtest/meson.build +++ b/tests/qtest/meson.build @@ -59,6 +59,8 @@ qtests_i386 =3D \ (config_all_devices.has_key('CONFIG_FDC_ISA') ? ['fdc-test'] : []) + = \ (config_all_devices.has_key('CONFIG_I440FX') ? ['fw_cfg-test'] : []) + = \ (config_all_devices.has_key('CONFIG_FW_CFG_DMA') ? ['vmcoreinfo-test'] := []) + \ + (igvm.found() and + config_all_devices.has_key('CONFIG_FW_CFG_DMA') ? ['launchupdate-test']= : []) + \ (config_all_devices.has_key('CONFIG_I440FX') ? ['i440fx-test'] : []) + = \ (config_all_devices.has_key('CONFIG_I440FX') ? ['ide-test'] : []) + = \ (config_all_devices.has_key('CONFIG_I440FX') ? ['numa-test'] : []) + = \ --=20 2.42.0 From nobody Sun Jul 26 12:33:36 2026 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=1782280582; cv=none; d=zohomail.com; s=zohoarc; b=celfwxD0wSYw/UsgdJ6FjqyjzjP/aJR5rgTlWqMySTVrgBc34ND7iGOQuViLJWh5mvURngqaJ/HhHcR5Mu20P5M5HB/xCaiEab4sM+I9V2dy+aHTTanyZRTcy5jpG1KZ/j+wM88LPAOIXi81LBnDDHBWY25rQUOtwwNBqa/Ed8A= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1782280582; h=Content-Type: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=FSxZKxqrJVYUG9v1bZKPhHIbfbJ0pdhQC07vvjbSt1k=; b=BfqrZ545gUdLpMmpRibX09iJoekRLGj1hoXdtjuVw7C2Cg6oZ/T5tmroc1DMxJmOlrG6jh0xl+0bc57N9yf2noO4J66rT2V5g75vEqPGiiF7dQl0sBP90wRnzwVRwjGc5PAn+XVqa+EPYOchp2iDduzKrXNslx3PuKNsVXSLRwo= 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 lists1p.gnu.org (lists1p.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1782280582181429.292908454751; Tue, 23 Jun 2026 22:56:22 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists1p.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1wcGZQ-000787-P3; Wed, 24 Jun 2026 01:54:44 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists1p.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1wcGZO-00076U-CH for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:42 -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 1wcGZN-0006La-0D for qemu-devel@nongnu.org; Wed, 24 Jun 2026 01:54:42 -0400 Received: from mail-dy1-f197.google.com (mail-dy1-f197.google.com [74.125.82.197]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-646-MPpsxJgMOIaK5NDERqeSnw-1; Wed, 24 Jun 2026 01:54:38 -0400 Received: by mail-dy1-f197.google.com with SMTP id 5a478bee46e88-30c5978b108so1744720eec.1 for ; Tue, 23 Jun 2026 22:54:38 -0700 (PDT) Received: from rhel9-box.lan ([110.227.100.91]) by smtp.googlemail.com with ESMTPSA id 5a478bee46e88-30c1bd8d6edsm21075803eec.14.2026.06.23.22.54.35 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 23 Jun 2026 22:54:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1782280480; 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=FSxZKxqrJVYUG9v1bZKPhHIbfbJ0pdhQC07vvjbSt1k=; b=emWgyeJoxUmpznzLP7zMU8gyLaLPZUOVvOP+Fg3KOWaD5xoOlWt+oX4qFpB55ATznFXs35 hXfZupyfyzhB/agBXnTj9IVh3pibDpi/f0xa5+UoLa/3mXJstmaYK+P55OD5TYGzhhQQYS nrJXRH5e6atZRzvvn/D6TuKvCOkrDAw= X-MC-Unique: MPpsxJgMOIaK5NDERqeSnw-1 X-Mimecast-MFC-AGG-ID: MPpsxJgMOIaK5NDERqeSnw_1782280477 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=google; t=1782280477; x=1782885277; darn=nongnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FSxZKxqrJVYUG9v1bZKPhHIbfbJ0pdhQC07vvjbSt1k=; b=e/7sdQSvlouB9ZJRvQAQS2vc3ea9+gz1iJKPCNMXo6zBZ5/TKxiOlGGbvl+GO6YNGA I0qcrEo6QJopTXCaKoILzw26Gyv0bjEn7qgoLuImwEqCsMIdi5tBLJk2ghW4Rjcd684m zR8va2ErYoeLQPmsCL2ptdo4/8D8IjRJpsttK7GOVksk/ZNWdnt1f/JXPyRVRlBjax4e mEewFptEKMhfPsavTH50jiaFMyWQhLXqEmty8VsM/eUnpdGacAPjPI6wBoqj39mlonPi ay15eoDZ9CZ50L6doHZ0KGIzFvACC6fTJMMwutaLSYw4SyOetfiU+FpBEOVrb6rqeLVi jMeQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1782280477; x=1782885277; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=FSxZKxqrJVYUG9v1bZKPhHIbfbJ0pdhQC07vvjbSt1k=; b=J8wAbyrh8fcn5j7ytnFKQXgJVONEA5fQItyA6ck8OTwHYv7/j45JN9d5NiTv5PCFzY 4cHGy2pD74qcN2T3yoXwqF2ySRhrUd9pL8twXiFE6vv4xuGMzRIQKfDVdhkV1v4M28f9 1u42mVzoYFTjoTcmGlCi8xd+iRa6dLRqbTgHHXbIMj1GeTOtl4PxpgxzYWgjonk0zxMQ SabzjM1lxGBEmxohMlQu3kgEBQPls69oKMlzqJbVAIQ4ufoDFlN+a+RoiZOKlpiHM9AT de/R5x09KOYePk1QSO1veCDveyGqbewn5zIR/yOzVsBa1Ipv9tyks2LNlxzNGvtLIs+K 7T7A== X-Forwarded-Encrypted: i=1; AHgh+RoZ5Pc5Rh0ltTSBXin6D+OpNka0Q2EhhokeKlkMweuuxgpq1kHoi6x7/7lYsHdhCSqDkS12cUpWluRt@nongnu.org X-Gm-Message-State: AOJu0Yw6wv6UdTr1C07XHZX9F22L3dLM9jo4SdGM2Odnb66ec9lE2xKP UGw/oei5Vqvtjfjb2ftdbbtHXis2XCx5go0WZZPLyy6PzjqRgCUVouCsmPI99APzj+jGxDH7U+M qp1Do2n6txZPsAsEzos2B1TS2/SLxjDRGRcMMNHLj7fxfUdVzed+7u3pQ3BNUrryH X-Gm-Gg: AfdE7clVm+X6XzmO6NLxQ8Y9/QFHsoug2K3vyUsEp9OE85521NEoNjsbmuQMqcaH32O 8EaU+bUK/PvZon04322Of3pGTjlZeoaRo6idgkKtRU8a/zD6gLZHfJV6gLD7B7d3uinMSU5hqv3 um1QbcF+l9N+T6Pa4pUeYI1IOTEXOWUA06Fyp0R9aLEm4OJDEdPuom/QCovHBLudZUxF2Akz/Gg zpY6ft99cUrVKEUzP+1Y8fthjxf1zqhO5vQewHXQJGRGg+D8T/6OnMgkRbPqfXB0LJUIyk5SujM IF+OgZ0Ly1eKxI6GrD1TIuHzxBaWc7MZtoHfAP6QeomVxKf5CEhZptqXhvqlvSRiPbRPp8XhHNX clY9uY7FxBc+k1lzN7Jto/A6jEwn4MoqNE0AmYMNMQlNC X-Received: by 2002:a05:7300:8607:b0:30c:536e:3a95 with SMTP id 5a478bee46e88-30c68c41dacmr1997334eec.2.1782280477059; Tue, 23 Jun 2026 22:54:37 -0700 (PDT) X-Received: by 2002:a05:7300:8607:b0:30c:536e:3a95 with SMTP id 5a478bee46e88-30c68c41dacmr1997316eec.2.1782280476515; Tue, 23 Jun 2026 22:54:36 -0700 (PDT) From: Ani Sinha To: Cc: Ani Sinha , qemu-devel@nongnu.org Subject: [PATCH v1 8/8] Update MAINTAINERS Date: Wed, 24 Jun 2026 11:23:30 +0530 Message-ID: <20260624055339.46862-9-anisinha@redhat.com> X-Mailer: git-send-email 2.42.0 In-Reply-To: <20260624055339.46862-1-anisinha@redhat.com> References: <20260624055339.46862-1-anisinha@redhat.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 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=lists1p.gnu.org; Received-SPF: pass client-ip=170.10.133.124; envelope-from=anisinha@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -24 X-Spam_score: -2.5 X-Spam_bar: -- X-Spam_report: (-2.5 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.445, 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, SPF_HELO_PASS=-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: qemu development 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: 1782280583986158500 Add maintainers for vm-launch-update device and associated documentation and test code. Signed-off-by: Ani Sinha --- MAINTAINERS | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 93df53d87f..98b63b40d4 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -2773,6 +2773,18 @@ F: include/hw/acpi/vmgenid.h F: docs/specs/vmgenid.rst F: tests/qtest/vmgenid-test.c =20 +VM Launch Update +M: Ani Sinha +M: Gerd Hoffman +S: Maintained +F: hw/misc/vmlaunchupdate.c +F: include/hw/misc/vmlaunchupdate.h +F: docs/specs/vmlaunchupdate.rst +F: tests/functional/aarch64/test_vm_launch_update_aarch.py +F: tests/functional/x86_64/test_vm_launch_update.py +F: tests/qtest/launchupdate-test.c +F: tests/data/igvm/* + LED M: Philippe Mathieu-Daud=C3=A9 S: Maintained --=20 2.42.0