From nobody Fri Nov 14 23:31:43 2025 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass(p=quarantine dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1759691841; cv=none; d=zohomail.com; s=zohoarc; b=lK8gBUeUM9hpaRRpIzgfCbOEmnJI3A2pnoiUvtJeuzJK7CCoe7wFJFAlITcRiXOA/jTi14S+a1xtZPMalU79BXo0aG6qe26nYo2WP3bxz7lN9XKfv2ZR8iIdoX487GfMG+JtDOzj87LwjxV+cZBWISIbOjotbBb4H+Q5NtbqaVE= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1759691841; h=Content-Type: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=CYadMOaENieYb148icK+VaNmWm4vj/PKt597pX2AzBE=; b=nesQ5jyZWavMPIdF8BeXth/dpbQ+3GPh3GczXJozv2+ucwURi2EIy1NhDZp6LkJ2Pugswd8TE5Vg8I5dJx05nGZGq+/OZaLh8I2ugFTitNNHmQ4/niT9wAQj/hMbKx+bPVV4rBvXjqKfUMFQybYZ0aV/d/gKbzP4ndEh09maRHU= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=pass header.from= (p=quarantine dis=none) Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1759691841558654.714336852172; Sun, 5 Oct 2025 12:17:21 -0700 (PDT) Received: from localhost ([::1] helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1v5UDo-0007Up-L0; Sun, 05 Oct 2025 15:16:40 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1v5UDZ-0007RD-96 for qemu-devel@nongnu.org; Sun, 05 Oct 2025 15:16:27 -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 1v5UDX-0006MD-4R for qemu-devel@nongnu.org; Sun, 05 Oct 2025 15:16:24 -0400 Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-411-f1f9_LJENjyTO6ZX_CGNHQ-1; Sun, 05 Oct 2025 15:16:20 -0400 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-46e41c32209so19661805e9.0 for ; Sun, 05 Oct 2025 12:16:20 -0700 (PDT) Received: from redhat.com ([2a0d:6fc0:1518:6900:b69a:73e1:9698:9cd3]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-46e619c3b75sm217403965e9.7.2025.10.05.12.16.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 05 Oct 2025 12:16:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1759691782; 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: in-reply-to:in-reply-to:references:references; bh=CYadMOaENieYb148icK+VaNmWm4vj/PKt597pX2AzBE=; b=DT1q2XlXoIL3+iC4eP3mOQXqkAMU4xSS9JhDEey3GjxyHO+qCwHRQbv76b7ke73vV1/LXV ra8foS6NLxSXK/HREU+xpkdeevZGW0UwkfM4cXnxKcEnSB/u4knZWkbECbKE97SQ+zmwqH eFJk8sOGyHrGeeT2r+MuolTHVDcWb/U= X-MC-Unique: f1f9_LJENjyTO6ZX_CGNHQ-1 X-Mimecast-MFC-AGG-ID: f1f9_LJENjyTO6ZX_CGNHQ_1759691779 X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1759691779; x=1760296579; h=in-reply-to:content-disposition:mime-version:references:message-id :subject:cc:to:from:date:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=CYadMOaENieYb148icK+VaNmWm4vj/PKt597pX2AzBE=; b=ca/c5HjXdvc7FN/0iXijJTSNbH8SsE2IM4eHJBDJGZsDBE5LVYjzWypwxAE3KuZkEO LiFA+271kfKmjYxiRPoImisPW9bXpdg0hBjheXkPXvv/YHs6XOw/nI0ulnX6qf3Ma7Dw mw2ChICgkF/VQFP5ltycNJeY8hz/WjE6e8MRF+Z7ESkhnk9O6Cdylp2/3VLqjqr6yonw MnHq4Nbg/sH4KQnPnKk4UkqLdb8H3KYCVGGpDILjsnoFCR5yW2tnNbxblOX+tR406I/+ UE9BxLEmLhb8Am+w1S2CEEsoc6fUmNT2jJ8ajVDzT/RFd4vEDYm856zUYlmTiN9GRZuB ZYbg== X-Gm-Message-State: AOJu0YzNmZBjC2I4MhP/qVn2TmZNHyrFy8OvEN3dlAF/88Gtoz3hbAlQ yBhyF/93uWH+CugDmr+u7j2EoxM3I/OqiaiSKQVmmn4sbYEVmA8h9jvojXRjWgJjwzzqjTtzsKv Fv3m6UsA4PvpaDqmfUG+eDCb9AMER14xfDbdGq0Kc4UVJZotEgGOLpepEllhpIf2Fvy6nuF+4kB KM8F7XH7Ox+m+xB98QXp65lwoMxqmrRP/UTQ== X-Gm-Gg: ASbGncv0C8WZfw+z/Qfuc8CG6MGdE6NmixYUFhltn6NgcBgqHkgmk0hN0QEzLUoQBR3 TV79WKqEeCaKMa1ih4seMEpj9pM0qXwRbeGGJOOfsaeluOFWn+I+h9lwU8wgmYmYFMTVYU53Q+4 0crWVTPH9BPIzqUobs1U26h0ft7gLOeV/S45YDtpBKzmdT1c5NMPgaIjINqPgeXvNxrZl5eqQFV TLT9ecleXIS6HGv7/YhdtB/gmWL+pi7otAWsgIJQUXtgRfbo4Bo2Cobls5DAUbsWN54FUzyidvF jSjJcKFrhoTKjGndr9zjwOZLmBTlejHNaRQ6PRM= X-Received: by 2002:a05:600c:8185:b0:468:7a5a:1494 with SMTP id 5b1f17b1804b1-46e710f6c7amr58387995e9.1.1759691779209; Sun, 05 Oct 2025 12:16:19 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHVWPKvvenOMbUd1eVy/txA2vZ0SV/DPwJyyKrRQzLERmJditeSADYlFiEOHf7tbmEjv5f+Eg== X-Received: by 2002:a05:600c:8185:b0:468:7a5a:1494 with SMTP id 5b1f17b1804b1-46e710f6c7amr58387875e9.1.1759691778776; Sun, 05 Oct 2025 12:16:18 -0700 (PDT) Date: Sun, 5 Oct 2025 15:16:16 -0400 From: "Michael S. Tsirkin" To: qemu-devel@nongnu.org Cc: Peter Maydell , Paolo Abeni , Akihiko Odaki , Jason Wang , Stefano Garzarella , Lei Yang Subject: [PULL 07/75] virtio-pci: implement support for extended features Message-ID: <712c79d6d374e7abe94599de5ba2d155d5a79955.1759691708.git.mst@redhat.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: X-Mailer: git-send-email 2.27.0.106.g8ac3dc51b1 X-Mutt-Fcc: =sent Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=170.10.129.124; envelope-from=mst@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.43, 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.01, RCVD_IN_MSPIKE_WL=-0.01, RCVD_IN_VALIDITY_RPBL_BLOCKED=0.001, RCVD_IN_VALIDITY_SAFE_BLOCKED=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: 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: 1759691853387116600 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: Paolo Abeni Extend the features configuration space to 128 bits. If the virtio device supports any extended features, allow the common read/write operation to access all of it, otherwise keep exposing only the lower 64 bits. On migration, save the 128 bit version of the features only if the upper bits are non zero. Relay on reset to clear all the feature space before load. Reviewed-by: Akihiko Odaki Acked-by: Jason Wang Acked-by: Stefano Garzarella Signed-off-by: Paolo Abeni Tested-by: Lei Yang Reviewed-by: Michael S. Tsirkin Message-ID: Signed-off-by: Michael S. Tsirkin --- include/hw/virtio/virtio-pci.h | 2 +- hw/virtio/virtio-pci.c | 76 ++++++++++++++++++++++++++++++---- 2 files changed, 68 insertions(+), 10 deletions(-) diff --git a/include/hw/virtio/virtio-pci.h b/include/hw/virtio/virtio-pci.h index eab5394898..639752977e 100644 --- a/include/hw/virtio/virtio-pci.h +++ b/include/hw/virtio/virtio-pci.h @@ -158,7 +158,7 @@ struct VirtIOPCIProxy { uint32_t nvectors; uint32_t dfselect; uint32_t gfselect; - uint32_t guest_features[2]; + uint32_t guest_features[VIRTIO_FEATURES_NU32S]; VirtIOPCIQueue vqs[VIRTIO_QUEUE_MAX]; =20 VirtIOIRQFD *vector_irqfd; diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c index 767216d795..01e4fecaf4 100644 --- a/hw/virtio/virtio-pci.c +++ b/hw/virtio/virtio-pci.c @@ -109,6 +109,29 @@ static const VMStateDescription vmstate_virtio_pci_mod= ern_queue_state =3D { } }; =20 +static bool virtio_pci_modern_state_features128_needed(void *opaque) +{ + VirtIOPCIProxy *proxy =3D opaque; + uint32_t features =3D 0; + int i; + + for (i =3D 2; i < ARRAY_SIZE(proxy->guest_features); ++i) { + features |=3D proxy->guest_features[i]; + } + return features; +} + +static const VMStateDescription vmstate_virtio_pci_modern_state_features12= 8 =3D { + .name =3D "virtio_pci/modern_state/features128", + .version_id =3D 1, + .minimum_version_id =3D 1, + .needed =3D &virtio_pci_modern_state_features128_needed, + .fields =3D (const VMStateField[]) { + VMSTATE_UINT32_SUB_ARRAY(guest_features, VirtIOPCIProxy, 2, 2), + VMSTATE_END_OF_LIST() + } +}; + static bool virtio_pci_modern_state_needed(void *opaque) { VirtIOPCIProxy *proxy =3D opaque; @@ -116,6 +139,12 @@ static bool virtio_pci_modern_state_needed(void *opaqu= e) return virtio_pci_modern(proxy); } =20 +/* + * Avoid silently breaking migration should the feature space increase + * even more in the (far away) future + */ +QEMU_BUILD_BUG_ON(VIRTIO_FEATURES_NU32S !=3D 4); + static const VMStateDescription vmstate_virtio_pci_modern_state_sub =3D { .name =3D "virtio_pci/modern_state", .version_id =3D 1, @@ -124,11 +153,15 @@ static const VMStateDescription vmstate_virtio_pci_mo= dern_state_sub =3D { .fields =3D (const VMStateField[]) { VMSTATE_UINT32(dfselect, VirtIOPCIProxy), VMSTATE_UINT32(gfselect, VirtIOPCIProxy), - VMSTATE_UINT32_ARRAY(guest_features, VirtIOPCIProxy, 2), + VMSTATE_UINT32_SUB_ARRAY(guest_features, VirtIOPCIProxy, 0, 2), VMSTATE_STRUCT_ARRAY(vqs, VirtIOPCIProxy, VIRTIO_QUEUE_MAX, 0, vmstate_virtio_pci_modern_queue_state, VirtIOPCIQueue), VMSTATE_END_OF_LIST() + }, + .subsections =3D (const VMStateDescription * const []) { + &vmstate_virtio_pci_modern_state_features128, + NULL } }; =20 @@ -1477,6 +1510,19 @@ int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy, return virtio_pci_add_mem_cap(proxy, &cap.cap); } =20 +static int virtio_pci_select_max(const VirtIODevice *vdev) +{ + int i; + + for (i =3D VIRTIO_FEATURES_NU64S - 1; i > 0; i--) { + if (vdev->host_features_ex[i]) { + return (i + 1) * 2; + } + } + + return 2; +} + static uint64_t virtio_pci_common_read(void *opaque, hwaddr addr, unsigned size) { @@ -1494,18 +1540,21 @@ static uint64_t virtio_pci_common_read(void *opaque= , hwaddr addr, val =3D proxy->dfselect; break; case VIRTIO_PCI_COMMON_DF: - if (proxy->dfselect <=3D 1) { + if (proxy->dfselect < virtio_pci_select_max(vdev)) { VirtioDeviceClass *vdc =3D VIRTIO_DEVICE_GET_CLASS(vdev); =20 - val =3D (vdev->host_features & ~vdc->legacy_features) >> - (32 * proxy->dfselect); + val =3D vdev->host_features_ex[proxy->dfselect >> 1] >> + (32 * (proxy->dfselect & 1)); + if (proxy->dfselect <=3D 1) { + val &=3D (~vdc->legacy_features) >> (32 * proxy->dfselect); + } } break; case VIRTIO_PCI_COMMON_GFSELECT: val =3D proxy->gfselect; break; case VIRTIO_PCI_COMMON_GF: - if (proxy->gfselect < ARRAY_SIZE(proxy->guest_features)) { + if (proxy->gfselect < virtio_pci_select_max(vdev)) { val =3D proxy->guest_features[proxy->gfselect]; } break; @@ -1588,11 +1637,18 @@ static void virtio_pci_common_write(void *opaque, h= waddr addr, proxy->gfselect =3D val; break; case VIRTIO_PCI_COMMON_GF: - if (proxy->gfselect < ARRAY_SIZE(proxy->guest_features)) { + if (proxy->gfselect < virtio_pci_select_max(vdev)) { + uint64_t features[VIRTIO_FEATURES_NU64S]; + int i; + proxy->guest_features[proxy->gfselect] =3D val; - virtio_set_features(vdev, - (((uint64_t)proxy->guest_features[1]) << 3= 2) | - proxy->guest_features[0]); + virtio_features_clear(features); + for (i =3D 0; i < ARRAY_SIZE(proxy->guest_features); ++i) { + uint64_t cur =3D proxy->guest_features[i]; + + features[i >> 1] |=3D cur << ((i & 1) * 32); + } + virtio_set_features_ex(vdev, features); } break; case VIRTIO_PCI_COMMON_MSIX: @@ -2311,6 +2367,8 @@ static void virtio_pci_reset(DeviceState *qdev) virtio_bus_reset(bus); msix_unuse_all_vectors(&proxy->pci_dev); =20 + memset(proxy->guest_features, 0, sizeof(proxy->guest_features)); + for (i =3D 0; i < VIRTIO_QUEUE_MAX; i++) { proxy->vqs[i].enabled =3D 0; proxy->vqs[i].reset =3D 0; --=20 MST