Kernel KVM virtualization development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Paolo Bonzini" <pbonzini@redhat.com>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH 14/24] KVM: Introduce a generation number for memory attributes
Date: Thu, 16 Jul 2026 18:36:26 +0000	[thread overview]
Message-ID: <20260716183627.53ED31F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260716181456.402786-15-pbonzini@redhat.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] xas_next() causes O(N) RCU stalls in kvm_range_has_any_memory_attributes()
- [High] Unconditional increment of kvm->mem_attrs.generation causes global cache invalidation
- [Medium] Data race and potential torn read of kvm->mem_attrs.generation
- [Low] Access to mem_attrs outside of #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES breaks compilation
--

--- Patch [14]: [PATCH 14/24] KVM: Introduce a generation number for memory attributes ---
commit 1b3b4442db618c511fecddd4a021c24933baeaa1
Author: Nicolas Saenz Julienne <nsaenz@amazon.com>
Subject: KVM: Introduce a generation number for memory attributes

Introduce a generation number to track memory attribute modifications.
This will allow KVM components to invalidate any assumptions they might
have about guest's physical addresses and their permissions when memory
attributes change.

> diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
> index 122af87d6f9a5..1fad3eb303c17 100644
> --- a/include/linux/kvm_host.h
> +++ b/include/linux/kvm_host.h

[ ... ]

> @@ -2559,29 +2560,49 @@ static inline bool kvm_mem_attributes_may_exec(u64 attrs)
>  	return !(attrs & KVM_MEMORY_ATTRIBUTE_NX);
>  }
>  
> -static inline bool kvm_memslots_check_gen(struct kvm *kvm, u64 slots_generation, struct kvm_memslots **p_slots)
> +static inline bool kvm_memslots_check_gen(struct kvm *kvm, u64 slots_generation,
> +					  u64 attrs_generation, struct kvm_memslots **p_slots)
>  {
>  	struct kvm_memslots *slots = *p_slots = kvm_memslots(kvm);
> -	return slots->generation == slots_generation;
> +	return slots->generation == slots_generation && kvm->mem_attrs.generation == attrs_generation;

[Severity: Low]
Does this break compilation when CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES is
disabled? The mem_attrs field in struct kvm is guarded by this config,
but it is accessed unconditionally here. Should this use the
kvm_mem_attributes_generation() helper instead?

[Severity: Medium]
Is there a data race on kvm->mem_attrs.generation here?

kvm_vm_set_mem_attributes() updates the generation counter using
smp_store_release(). Since kvm_memslots_check_gen() reads it concurrently
in lockless fast-paths, a plain C read could lead to torn reads on
some architectures. Would it be safer to use READ_ONCE() or the
kvm_mem_attributes_generation() helper?

>  }

[ ... ]

> diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
> index 1afaec56ecb37..2fe4087319adf 100644
> --- a/virt/kvm/kvm_main.c
> +++ b/virt/kvm/kvm_main.c

[ ... ]

> +bool kvm_range_has_any_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
> +					unsigned long mask)
> +{
> +	XA_STATE(xas, &kvm->mem_attrs.array, start);
> +	void *entry;
> +
> +	mask &= kvm_supported_mem_attributes(kvm);
> +	if (!mask)
> +		return false;
> +
> +	if (end == start + 1)
> +		return !!(kvm_get_memory_attributes(kvm, start) & mask);
> +
> +	guard(rcu)();
> +	for (;;) {
> +		do {
> +			entry = xas_next(&xas);
> +		} while (xas_retry(&xas, entry));
> +
> +		if (xas.xa_index >= end)
> +			break;
> +
> +		if (xa_to_value(entry) & mask)
> +			return true;
> +	}
> +
> +	return false;
> +}

[Severity: High]
Can this loop cause CPU soft lockups and RCU stalls when querying a large,
sparse memory range?

If the requested range is empty, xas_next() will return NULL and increment
the internal array index by 1 step-by-step. For millions of pages, this
will iterate millions of times under guard(rcu)().

Should this use xas_find() or xas_for_each() to skip empty entries in O(1)
time instead?

[ ... ]

> @@ -2594,10 +2645,16 @@ static int kvm_vm_set_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
>  		cond_resched();
>  	}
>  
> +	/* Pairs with acquire in kvm_mem_attributes_generation() */
> +	smp_store_release(&kvm->mem_attrs.generation,
> +			  kvm->mem_attrs.generation + 1);

[Severity: High]
The commit message states: "There shouldn't be any performance loss for
memory attributes that don't require synchronization ... because the
attributes generation will always remain unchanged."

However, kvm->mem_attrs.generation is unconditionally incremented here,
even if the sync flag is false. Will this global increment invalidate all
gfn_to_hva_cache and gfn_to_pfn_cache entries across the entire VM
unnecessarily? Should this be conditional on the sync flag being true?

> +
>  	kvm_handle_gfn_range(kvm, &post_set_range);
>  
>  out_unlock:

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260716181456.402786-1-pbonzini@redhat.com?part=14

  reply	other threads:[~2026-07-16 18:36 UTC|newest]

Thread overview: 44+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-16 18:14 [RFC PATCH 00/24] KVM: x86: Introduce memory protection attributes Paolo Bonzini
2026-07-16 18:14 ` [PATCH 01/24] KVM: selftests: Take into account mixed memory fault flags Paolo Bonzini
2026-07-16 18:14 ` [PATCH 02/24] KVM: Define and communicate KVM_EXIT_MEMORY_FAULT RWX flags to userspace Paolo Bonzini
2026-07-16 18:34   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 03/24] KVM: x86: hyperv: Introduce memory fault on hcalls with bad ingpas Paolo Bonzini
2026-07-16 18:34   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 04/24] KVM: x86/mmu: intersect writability from __kvm_faultin_pfn with fault->map_writable Paolo Bonzini
2026-07-16 18:14 ` [PATCH 05/24] KVM: x86/mmu: Extend map_writable to a full ACC_* mask Paolo Bonzini
2026-07-16 18:39   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 06/24] KVM: x86: Avoid warning when installing non-private memory attributes Paolo Bonzini
2026-07-16 18:42   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 07/24] KVM: x86/mmu: Init memslot hugepage information for non-private_mem VMs too Paolo Bonzini
2026-07-16 18:14 ` [PATCH 08/24] KVM: pass kvm == NULL case to kvm_arch_has_private_mem Paolo Bonzini
2026-07-16 18:14 ` [PATCH 09/24] KVM: Introduce NR/NW/NX memory attributes Paolo Bonzini
2026-07-16 18:39   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 10/24] KVM: Include memory protections in result of gfn->hva conversion Paolo Bonzini
2026-07-16 18:29   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 11/24] KVM: Take memory protections into account in kvm_read/write_guest() Paolo Bonzini
2026-07-16 18:36   ` sashiko-bot
2026-07-16 19:17   ` Edgecombe, Rick P
2026-07-16 18:14 ` [PATCH 12/24] KVM: Encapsulate memattrs array into anonymous struct Paolo Bonzini
2026-07-16 18:14 ` [PATCH 13/24] KVM: Introduce kvm_check_gen()/kvm_memslots_check_gen() Paolo Bonzini
2026-07-16 18:26   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 14/24] KVM: Introduce a generation number for memory attributes Paolo Bonzini
2026-07-16 18:36   ` sashiko-bot [this message]
2026-07-16 18:14 ` [PATCH 15/24] KVM: Take memory protections into account for accesses with cached gfn->hva Paolo Bonzini
2026-07-16 18:46   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 16/24] KVM: pfncache: Fail to refresh if it contains memory protections Paolo Bonzini
2026-07-16 18:14 ` [PATCH 17/24] KVM: x86/mmu: Take memory protection attributes into account during faults Paolo Bonzini
2026-07-16 19:13   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 18/24] KVM: x86/mmu: Issue memory fault exit if walk failed due to memory attribute Paolo Bonzini
2026-07-16 18:47   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 19/24] KVM: x86/mmu: Do not update accessed/dirty if guest PTE is read-only Paolo Bonzini
2026-07-16 18:40   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 20/24] KVM: x86/mmu: Do not prefetch sptes on gfns backed by memory attributes Paolo Bonzini
2026-07-16 18:35   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 21/24] KVM: x86/mmu: Obsolete all roots if memattr contains gPTEs Paolo Bonzini
2026-07-16 18:40   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 22/24] KVM: x86: selftests: Introduce memory attributes test Paolo Bonzini
2026-07-16 18:42   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 23/24] KVM: x86: selftests: Introduce memory attributes PTE test Paolo Bonzini
2026-07-16 18:49   ` sashiko-bot
2026-07-16 18:14 ` [PATCH 24/24] KVM: x86: selftests: Introduce memory attributes side-channel tests Paolo Bonzini
2026-07-16 18:54   ` sashiko-bot

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=20260716183627.53ED31F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=kvm@vger.kernel.org \
    --cc=pbonzini@redhat.com \
    --cc=sashiko-reviews@lists.linux.dev \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox