From: Alexey Kardashevskiy <aik@amd.com>
To: "Chenyi Qiang" <chenyi.qiang@intel.com>,
"David Hildenbrand" <david@redhat.com>,
"Peter Xu" <peterx@redhat.com>,
"Gupta Pankaj" <pankaj.gupta@amd.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Philippe Mathieu-Daudé" <philmd@linaro.org>,
"Michael Roth" <michael.roth@amd.com>
Cc: qemu-devel@nongnu.org, kvm@vger.kernel.org,
Williams Dan J <dan.j.williams@intel.com>,
Zhao Liu <zhao1.liu@intel.com>,
Baolu Lu <baolu.lu@linux.intel.com>,
Gao Chao <chao.gao@intel.com>, Xu Yilun <yilun.xu@intel.com>,
Li Xiaoyao <xiaoyao.li@intel.com>
Subject: Re: [PATCH v5 09/10] KVM: Introduce RamDiscardListener for attribute changes during memory conversions
Date: Tue, 27 May 2025 18:01:27 +1000 [thread overview]
Message-ID: <577cff65-bc20-48f1-a776-999ee96a7035@amd.com> (raw)
In-Reply-To: <20250520102856.132417-10-chenyi.qiang@intel.com>
On 20/5/25 20:28, Chenyi Qiang wrote:
> With the introduction of the RamBlockAttribute object to manage
> RAMBlocks with guest_memfd, it is more elegant to move KVM set attribute
> into a RamDiscardListener.
>
> The KVM attribute change RamDiscardListener is registered/unregistered
> for each memory region section during kvm_region_add/del(). The listener
> handler performs attribute change upon receiving notifications from
> ram_block_attribute_state_change() calls. After this change, the
> operations in kvm_convert_memory() can be removed.
>
> Note that, errors can be returned in
> ram_block_attribute_notify_to_discard() by KVM attribute changes,
> although it is currently unlikely to happen. With in-place conversion
> guest_memfd in the future, it would be more likely to encounter errors
> and require error handling. For now, simply return the result, and
> kvm_convert_memory() will cause QEMU to quit if any issue arises.
>
> Signed-off-by: Chenyi Qiang <chenyi.qiang@intel.com>
> ---
> Changes in v5:
> - Revert to use RamDiscardListener
>
> Changes in v4:
> - Newly added.
> ---
> accel/kvm/kvm-all.c | 72 ++++++++++++++++++---
> include/system/confidential-guest-support.h | 9 +++
> system/ram-block-attribute.c | 16 +++--
> target/i386/kvm/tdx.c | 1 +
> target/i386/sev.c | 1 +
imho this diffstat disagrees with the "more elegant" :)
+1 for ditching it from this patchset. Thanks,
> 5 files changed, 85 insertions(+), 14 deletions(-)
>
> diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
> index 2d7ecaeb6a..ca4ef8062b 100644
> --- a/accel/kvm/kvm-all.c
> +++ b/accel/kvm/kvm-all.c
> @@ -49,6 +49,7 @@
> #include "kvm-cpus.h"
> #include "system/dirtylimit.h"
> #include "qemu/range.h"
> +#include "system/confidential-guest-support.h"
>
> #include "hw/boards.h"
> #include "system/stats.h"
> @@ -1689,28 +1690,90 @@ static int kvm_dirty_ring_init(KVMState *s)
> return 0;
> }
>
> +static int kvm_private_shared_notify(RamDiscardListener *rdl,
> + MemoryRegionSection *section,
> + bool to_private)
> +{
> + hwaddr start = section->offset_within_address_space;
> + hwaddr size = section->size;
> +
> + if (to_private) {
> + return kvm_set_memory_attributes_private(start, size);
> + } else {
> + return kvm_set_memory_attributes_shared(start, size);
> + }
> +}
> +
> +static int kvm_ram_discard_notify_to_shared(RamDiscardListener *rdl,
> + MemoryRegionSection *section)
> +{
> + return kvm_private_shared_notify(rdl, section, false);
> +}
> +
> +static int kvm_ram_discard_notify_to_private(RamDiscardListener *rdl,
> + MemoryRegionSection *section)
> +{
> + return kvm_private_shared_notify(rdl, section, true);
> +}
> +
> static void kvm_region_add(MemoryListener *listener,
> MemoryRegionSection *section)
> {
> KVMMemoryListener *kml = container_of(listener, KVMMemoryListener, listener);
> + ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
> + RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr);
> KVMMemoryUpdate *update;
> + CGSRamDiscardListener *crdl;
> + RamDiscardListener *rdl;
> +
>
> update = g_new0(KVMMemoryUpdate, 1);
> update->section = *section;
>
> QSIMPLEQ_INSERT_TAIL(&kml->transaction_add, update, next);
> +
> + if (!memory_region_has_guest_memfd(section->mr) || !rdm) {
> + return;
> + }
> +
> + crdl = g_new0(CGSRamDiscardListener, 1);
> + crdl->mr = section->mr;
> + crdl->offset_within_address_space = section->offset_within_address_space;
> + rdl = &crdl->listener;
> + QLIST_INSERT_HEAD(&cgs->cgs_rdl_list, crdl, next);
> + ram_discard_listener_init(rdl, kvm_ram_discard_notify_to_shared,
> + kvm_ram_discard_notify_to_private, true);
> + ram_discard_manager_register_listener(rdm, rdl, section);
> }
>
> static void kvm_region_del(MemoryListener *listener,
> MemoryRegionSection *section)
> {
> KVMMemoryListener *kml = container_of(listener, KVMMemoryListener, listener);
> + ConfidentialGuestSupport *cgs = MACHINE(qdev_get_machine())->cgs;
> + RamDiscardManager *rdm = memory_region_get_ram_discard_manager(section->mr);
> KVMMemoryUpdate *update;
> + CGSRamDiscardListener *crdl;
> + RamDiscardListener *rdl;
>
> update = g_new0(KVMMemoryUpdate, 1);
> update->section = *section;
>
> QSIMPLEQ_INSERT_TAIL(&kml->transaction_del, update, next);
> + if (!memory_region_has_guest_memfd(section->mr) || !rdm) {
> + return;
> + }
> +
> + QLIST_FOREACH(crdl, &cgs->cgs_rdl_list, next) {
> + if (crdl->mr == section->mr &&
> + crdl->offset_within_address_space == section->offset_within_address_space) {
> + rdl = &crdl->listener;
> + ram_discard_manager_unregister_listener(rdm, rdl);
> + QLIST_REMOVE(crdl, next);
> + g_free(crdl);
> + break;
> + }
> + }
> }
>
> static void kvm_region_commit(MemoryListener *listener)
> @@ -3077,15 +3140,6 @@ int kvm_convert_memory(hwaddr start, hwaddr size, bool to_private)
> goto out_unref;
> }
>
> - if (to_private) {
> - ret = kvm_set_memory_attributes_private(start, size);
> - } else {
> - ret = kvm_set_memory_attributes_shared(start, size);
> - }
> - if (ret) {
> - goto out_unref;
> - }
> -
> addr = memory_region_get_ram_ptr(mr) + section.offset_within_region;
> rb = qemu_ram_block_from_host(addr, false, &offset);
>
> diff --git a/include/system/confidential-guest-support.h b/include/system/confidential-guest-support.h
> index ea46b50c56..974abdbf6b 100644
> --- a/include/system/confidential-guest-support.h
> +++ b/include/system/confidential-guest-support.h
> @@ -19,12 +19,19 @@
> #define QEMU_CONFIDENTIAL_GUEST_SUPPORT_H
>
> #include "qom/object.h"
> +#include "system/memory.h"
>
> #define TYPE_CONFIDENTIAL_GUEST_SUPPORT "confidential-guest-support"
> OBJECT_DECLARE_TYPE(ConfidentialGuestSupport,
> ConfidentialGuestSupportClass,
> CONFIDENTIAL_GUEST_SUPPORT)
>
> +typedef struct CGSRamDiscardListener {
> + MemoryRegion *mr;
> + hwaddr offset_within_address_space;
> + RamDiscardListener listener;
> + QLIST_ENTRY(CGSRamDiscardListener) next;
> +} CGSRamDiscardListener;
>
> struct ConfidentialGuestSupport {
> Object parent;
> @@ -34,6 +41,8 @@ struct ConfidentialGuestSupport {
> */
> bool require_guest_memfd;
>
> + QLIST_HEAD(, CGSRamDiscardListener) cgs_rdl_list;
> +
> /*
> * ready: flag set by CGS initialization code once it's ready to
> * start executing instructions in a potentially-secure
> diff --git a/system/ram-block-attribute.c b/system/ram-block-attribute.c
> index 896c3d7543..387501b569 100644
> --- a/system/ram-block-attribute.c
> +++ b/system/ram-block-attribute.c
> @@ -274,11 +274,12 @@ static bool ram_block_attribute_is_valid_range(RamBlockAttribute *attr,
> return true;
> }
>
> -static void ram_block_attribute_notify_to_discard(RamBlockAttribute *attr,
> - uint64_t offset,
> - uint64_t size)
> +static int ram_block_attribute_notify_to_discard(RamBlockAttribute *attr,
> + uint64_t offset,
> + uint64_t size)
> {
> RamDiscardListener *rdl;
> + int ret = 0;
>
> QLIST_FOREACH(rdl, &attr->rdl_list, next) {
> MemoryRegionSection tmp = *rdl->section;
> @@ -286,8 +287,13 @@ static void ram_block_attribute_notify_to_discard(RamBlockAttribute *attr,
> if (!memory_region_section_intersect_range(&tmp, offset, size)) {
> continue;
> }
> - rdl->notify_discard(rdl, &tmp);
> + ret = rdl->notify_discard(rdl, &tmp);
> + if (ret) {
> + break;
> + }
> }
> +
> + return ret;
> }
>
> static int
> @@ -377,7 +383,7 @@ int ram_block_attribute_state_change(RamBlockAttribute *attr, uint64_t offset,
>
> if (to_private) {
> bitmap_clear(attr->bitmap, first_bit, nbits);
> - ram_block_attribute_notify_to_discard(attr, offset, size);
> + ret = ram_block_attribute_notify_to_discard(attr, offset, size);
> } else {
> bitmap_set(attr->bitmap, first_bit, nbits);
> ret = ram_block_attribute_notify_to_populated(attr, offset, size);
> diff --git a/target/i386/kvm/tdx.c b/target/i386/kvm/tdx.c
> index 7ef49690bd..17b360059c 100644
> --- a/target/i386/kvm/tdx.c
> +++ b/target/i386/kvm/tdx.c
> @@ -1492,6 +1492,7 @@ static void tdx_guest_init(Object *obj)
> qemu_mutex_init(&tdx->lock);
>
> cgs->require_guest_memfd = true;
> + QLIST_INIT(&cgs->cgs_rdl_list);
> tdx->attributes = TDX_TD_ATTRIBUTES_SEPT_VE_DISABLE;
>
> object_property_add_uint64_ptr(obj, "attributes", &tdx->attributes,
> diff --git a/target/i386/sev.c b/target/i386/sev.c
> index adf787797e..f1b9c35fc3 100644
> --- a/target/i386/sev.c
> +++ b/target/i386/sev.c
> @@ -2430,6 +2430,7 @@ sev_snp_guest_instance_init(Object *obj)
> SevSnpGuestState *sev_snp_guest = SEV_SNP_GUEST(obj);
>
> cgs->require_guest_memfd = true;
> + QLIST_INIT(&cgs->cgs_rdl_list);
>
> /* default init/start/finish params for kvm */
> sev_snp_guest->kvm_start_conf.policy = DEFAULT_SEV_SNP_POLICY;
--
Alexey
next prev parent reply other threads:[~2025-05-27 8:01 UTC|newest]
Thread overview: 51+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-05-20 10:28 [PATCH v5 00/10] Enable shared device assignment Chenyi Qiang
2025-05-20 10:28 ` [PATCH v5 01/10] memory: Export a helper to get intersection of a MemoryRegionSection with a given range Chenyi Qiang
2025-05-20 10:28 ` [PATCH v5 02/10] memory: Change memory_region_set_ram_discard_manager() to return the result Chenyi Qiang
2025-05-26 8:40 ` David Hildenbrand
2025-05-27 6:56 ` Alexey Kardashevskiy
2025-05-20 10:28 ` [PATCH v5 03/10] memory: Unify the definiton of ReplayRamPopulate() and ReplayRamDiscard() Chenyi Qiang
2025-05-26 8:42 ` David Hildenbrand
2025-05-26 9:35 ` Philippe Mathieu-Daudé
2025-05-26 10:21 ` Chenyi Qiang
2025-05-27 6:56 ` Alexey Kardashevskiy
2025-05-20 10:28 ` [PATCH v5 04/10] ram-block-attribute: Introduce RamBlockAttribute to manage RAMBlock with guest_memfd Chenyi Qiang
2025-05-26 9:01 ` David Hildenbrand
2025-05-26 9:28 ` Chenyi Qiang
2025-05-26 11:16 ` Alexey Kardashevskiy
2025-05-27 1:15 ` Chenyi Qiang
2025-05-27 1:20 ` Alexey Kardashevskiy
2025-05-27 3:14 ` Chenyi Qiang
2025-05-27 6:06 ` Alexey Kardashevskiy
2025-05-20 10:28 ` [PATCH v5 05/10] ram-block-attribute: Introduce a helper to notify shared/private state changes Chenyi Qiang
2025-05-26 9:02 ` David Hildenbrand
2025-05-27 7:35 ` Alexey Kardashevskiy
2025-05-27 9:06 ` Chenyi Qiang
2025-05-27 9:19 ` Alexey Kardashevskiy
2025-05-20 10:28 ` [PATCH v5 06/10] memory: Attach RamBlockAttribute to guest_memfd-backed RAMBlocks Chenyi Qiang
2025-05-26 9:06 ` David Hildenbrand
2025-05-26 9:46 ` Chenyi Qiang
2025-05-20 10:28 ` [PATCH v5 07/10] RAMBlock: Make guest_memfd require coordinate discard Chenyi Qiang
2025-05-26 9:08 ` David Hildenbrand
2025-05-27 5:47 ` Chenyi Qiang
2025-05-27 7:42 ` Alexey Kardashevskiy
2025-05-27 8:12 ` Chenyi Qiang
2025-05-27 11:20 ` David Hildenbrand
2025-05-28 1:57 ` Chenyi Qiang
2025-05-20 10:28 ` [PATCH v5 08/10] memory: Change NotifyRamDiscard() definition to return the result Chenyi Qiang
2025-05-26 9:31 ` Philippe Mathieu-Daudé
2025-05-26 10:36 ` Cédric Le Goater
2025-05-26 12:44 ` Cédric Le Goater
2025-05-27 5:29 ` Chenyi Qiang
2025-05-20 10:28 ` [PATCH v5 09/10] KVM: Introduce RamDiscardListener for attribute changes during memory conversions Chenyi Qiang
2025-05-26 9:22 ` David Hildenbrand
2025-05-27 8:01 ` Alexey Kardashevskiy [this message]
2025-05-20 10:28 ` [PATCH v5 10/10] ram-block-attribute: Add more error handling during state changes Chenyi Qiang
2025-05-26 9:17 ` David Hildenbrand
2025-05-26 10:19 ` Chenyi Qiang
2025-05-26 12:10 ` David Hildenbrand
2025-05-26 12:39 ` Chenyi Qiang
2025-05-27 9:11 ` Alexey Kardashevskiy
2025-05-27 10:18 ` Chenyi Qiang
2025-05-27 11:21 ` David Hildenbrand
2025-05-26 11:37 ` [PATCH v5 00/10] Enable shared device assignment Cédric Le Goater
2025-05-26 12:16 ` Chenyi Qiang
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=577cff65-bc20-48f1-a776-999ee96a7035@amd.com \
--to=aik@amd.com \
--cc=baolu.lu@linux.intel.com \
--cc=chao.gao@intel.com \
--cc=chenyi.qiang@intel.com \
--cc=dan.j.williams@intel.com \
--cc=david@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=michael.roth@amd.com \
--cc=pankaj.gupta@amd.com \
--cc=pbonzini@redhat.com \
--cc=peterx@redhat.com \
--cc=philmd@linaro.org \
--cc=qemu-devel@nongnu.org \
--cc=xiaoyao.li@intel.com \
--cc=yilun.xu@intel.com \
--cc=zhao1.liu@intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.