From: Paolo Bonzini <pbonzini@redhat.com>
To: linux-kernel@vger.kernel.org, kvm@vger.kernel.org
Cc: nsaenz@amazon.com, vkuznets@redhat.com, snambakam@linux.microsoft.com
Subject: [PATCH 21/31] KVM: Introduce a generation number for memory attributes
Date: Fri, 18 Sep 2026 09:50:20 -0400 [thread overview]
Message-ID: <20260918135030.171564-22-pbonzini@redhat.com> (raw)
In-Reply-To: <20260918135030.171564-1-pbonzini@redhat.com>
From: Nicolas Saenz Julienne <nsaenz@amazon.com>
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.
Like with memory slot updates, it's mandatory for components that access
guest memory based on cached information to do so within a KVM SRCU
read-side critical section, and that they validate the generation number
before accessing memory. This, in combination with the
synchronize_srcu() call within the memory attributes ioctl handler,
ensures the following:
- A memory attribute modification operation only returns after all
users of outdated GPA data are done running.
- Any component accessing cached data after the memory attribute
modification returned will see the updated generation number.
Additionally, loads/stores of the generation number have
acquire/release semantics; which ensures all attribute writes are
visible before updating the generation, and loads from attributes happen
after having read the current generation number.
Ultimately, since synchronize_srcu_expedited() is an expensive
operation, only perform it when absolutely necessary. Do so if the
introduced memory attribute is known to require synchronization or if
the attribute being cleared contained a memory attribute that required
synchronization.
There shouldn't be any performance loss for memory attributes that
don't require synchronization (and in general for any VMM that does not
apply memory protections), because the attributes generation will always
remain unchanged.
Signed-off-by: Nicolas Saenz Julienne <nsaenz@amazon.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
arch/loongarch/kvm/vcpu.c | 6 ++-
arch/x86/kvm/x86.c | 4 +-
include/linux/kvm_host.h | 34 ++++++++++++++--
include/linux/kvm_types.h | 6 ++-
include/trace/events/kvm.h | 14 +++++--
virt/kvm/kvm_main.c | 80 +++++++++++++++++++++++++++++++++-----
virt/kvm/pfncache.c | 13 ++++---
7 files changed, 128 insertions(+), 29 deletions(-)
diff --git a/arch/loongarch/kvm/vcpu.c b/arch/loongarch/kvm/vcpu.c
index cf4f4d75374a..1179c413b048 100644
--- a/arch/loongarch/kvm/vcpu.c
+++ b/arch/loongarch/kvm/vcpu.c
@@ -163,7 +163,8 @@ static void kvm_update_stolen_time(struct kvm_vcpu *vcpu)
return;
gpa &= KVM_STEAL_PHYS_MASK;
- if (unlikely(!kvm_check_gen(vcpu->kvm, ghc->generation) || gpa != ghc->gpa ||
+ if (unlikely(!kvm_check_gen(vcpu->kvm, ghc->slots_generation, ghc->attrs_generation) ||
+ gpa != ghc->gpa ||
kvm_is_error_hva(ghc->hva) || !ghc->memslot) {
if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gpa, sizeof(*st))) {
ghc->gpa = INVALID_GPA;
@@ -1808,7 +1809,8 @@ static void kvm_vcpu_set_pv_preempted(struct kvm_vcpu *vcpu)
gpa &= KVM_STEAL_PHYS_MASK;
ghc = &vcpu->arch.st.cache;
- if (unlikely(!kvm_check_gen(vcpu->kvm, ghc->generation) || gpa != ghc->gpa ||
+ if (unlikely(!kvm_check_gen(vcpu->kvm, ghc->slots_generation, ghc->attrs_generation) ||
+ gpa != ghc->gpa ||
kvm_is_error_hva(ghc->hva) || !ghc->memslot) {
if (kvm_gfn_to_hva_cache_init(vcpu->kvm, ghc, gpa, sizeof(*st))) {
ghc->gpa = INVALID_GPA;
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 7a1e80bb28f5..ab4f5e44d74d 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -2064,7 +2064,7 @@ static void record_steal_time(struct kvm_vcpu *vcpu)
if (WARN_ON_ONCE(current->mm != vcpu->kvm->mm))
return;
- if (unlikely(!kvm_check_gen(vcpu->kvm, ghc->generation) ||
+ if (unlikely(!kvm_check_gen(vcpu->kvm, ghc->slots_generation, ghc->attrs_generation) ||
gpa != ghc->gpa ||
kvm_is_error_hva(ghc->hva) || !ghc->memslot)) {
/* We rely on the fact that it fits in a single page. */
@@ -2640,7 +2640,7 @@ static void kvm_steal_time_set_preempted(struct kvm_vcpu *vcpu)
if (unlikely(current->mm != vcpu->kvm->mm))
return;
- if (unlikely(!kvm_check_gen(vcpu->kvm, ghc->generation) ||
+ if (unlikely(!kvm_check_gen(vcpu->kvm, ghc->slots_generation, ghc->attrs_generation) ||
gpa != ghc->gpa ||
kvm_is_error_hva(ghc->hva) || !ghc->memslot))
return;
diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h
index 7599ab7ad7ef..ab62ce37bc18 100644
--- a/include/linux/kvm_host.h
+++ b/include/linux/kvm_host.h
@@ -878,6 +878,7 @@ struct kvm {
struct {
/* Protected by slots_lock (for writes) and RCU (for reads) */
struct xarray array;
+ u64 generation;
} mem_attrs;
#endif
char stats_id[KVM_STATS_NAME_SIZE];
@@ -2592,13 +2593,31 @@ static inline bool kvm_mem_attributes_may_exec(u64 attrs)
#define KVM_MEMORY_ATTRIBUTE_PROT \
(KVM_MEMORY_ATTRIBUTE_NR | KVM_MEMORY_ATTRIBUTE_NW | KVM_MEMORY_ATTRIBUTE_NX)
+#define KVM_MEMORY_ATTRIBUTE_NEEDS_SYNC_MASK KVM_MEMORY_ATTRIBUTE_PROT
+
static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn_t gfn)
{
return xa_to_value(xa_load(&kvm->mem_attrs.array, gfn));
}
+static inline u64 kvm_mem_attributes_generation(struct kvm *kvm)
+{
+ RCU_LOCKDEP_WARN(!lockdep_is_held(&kvm->slots_lock) &&
+ !srcu_read_lock_held(&kvm->srcu),
+ "Suspicious memory attribute generation usage\n");
+
+ /*
+ * The acquire pairs with the release in kvm_vm_set_mem_attributes().
+ * Memory attributes should only be queried _after_ storing the
+ * generation number.
+ */
+ return smp_load_acquire(&kvm->mem_attrs.generation);
+}
+
bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
unsigned long mask, unsigned long attrs);
+bool kvm_range_has_any_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
+ unsigned long mask);
bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm,
struct kvm_gfn_range *range);
bool kvm_arch_post_set_memory_attributes(struct kvm *kvm,
@@ -2628,6 +2647,10 @@ static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn_t gfn
{
return 0;
}
+static inline u64 kvm_mem_attributes_generation(struct kvm *kvm)
+{
+ return 0;
+}
#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */
static inline int kvm_mem_attributes_may_read_gfn(struct kvm *kvm, gfn_t gfn)
@@ -2644,16 +2667,19 @@ static inline int kvm_mem_attributes_may_write_gfn(struct kvm *kvm, gfn_t gfn)
return kvm_mem_attributes_may_write(attrs);
}
-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_attributes_generation(kvm) == attrs_generation;
}
-static inline bool kvm_check_gen(struct kvm *kvm, u64 slots_generation)
+static inline bool kvm_check_gen(struct kvm *kvm, u64 slots_generation,
+ u64 attrs_generation)
{
struct kvm_memslots *slots;
- return kvm_memslots_check_gen(kvm, slots_generation, &slots);
+ return kvm_memslots_check_gen(kvm, slots_generation, attrs_generation, &slots);
}
diff --git a/include/linux/kvm_types.h b/include/linux/kvm_types.h
index a568d8e6f4e8..7d911220e00d 100644
--- a/include/linux/kvm_types.h
+++ b/include/linux/kvm_types.h
@@ -74,7 +74,8 @@ typedef u64 hfn_t;
typedef hfn_t kvm_pfn_t;
struct gfn_to_hva_cache {
- u64 generation;
+ u64 slots_generation;
+ u64 attrs_generation;
gpa_t gpa;
unsigned long hva;
unsigned long len;
@@ -82,7 +83,8 @@ struct gfn_to_hva_cache {
};
struct gfn_to_pfn_cache {
- u64 generation;
+ u64 slots_generation;
+ u64 attrs_generation;
gpa_t gpa;
unsigned long uhva;
struct kvm_memory_slot *memslot;
diff --git a/include/trace/events/kvm.h b/include/trace/events/kvm.h
index b282e3a86769..a620131e9010 100644
--- a/include/trace/events/kvm.h
+++ b/include/trace/events/kvm.h
@@ -365,23 +365,29 @@ TRACE_EVENT(kvm_dirty_ring_exit,
* @attr: The value of the attribute being set.
*/
TRACE_EVENT(kvm_vm_set_mem_attributes,
- TP_PROTO(gfn_t start, gfn_t end, unsigned long attr),
- TP_ARGS(start, end, attr),
+ TP_PROTO(gfn_t start, gfn_t end, unsigned long attr, bool sync, u64 generation),
+ TP_ARGS(start, end, attr, sync, generation),
TP_STRUCT__entry(
__field(gfn_t, start)
__field(gfn_t, end)
__field(unsigned long, attr)
+ __field(bool, sync)
+ __field(u64, generation)
),
TP_fast_assign(
__entry->start = start;
__entry->end = end;
__entry->attr = attr;
+ __entry->sync = sync;
+ __entry->generation = generation;
),
- TP_printk("%#016llx -- %#016llx [0x%lx]",
- __entry->start, __entry->end, __entry->attr)
+ TP_printk("%#016llx -- %#016llx [0x%lx], sync %d gen %llu",
+ __entry->start, __entry->end, __entry->attr,
+ __entry->sync, __entry->generation)
+
);
#endif /* CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES */
diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c
index ea4e9425a82d..c00410bb62a2 100644
--- a/virt/kvm/kvm_main.c
+++ b/virt/kvm/kvm_main.c
@@ -1118,6 +1118,7 @@ static struct kvm *kvm_create_vm(unsigned long type, const char *fdname)
xa_init(&kvm->vcpu_array);
#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
xa_init(&kvm->mem_attrs.array);
+ kvm->mem_attrs.generation = 0;
#endif
INIT_LIST_HEAD(&kvm->gpc_list);
@@ -2470,6 +2471,51 @@ bool kvm_range_has_memory_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
return true;
}
+/*
+ * Returns true if _any_ gfns in the range [@start, @end) have attributes that
+ * match _any_ bit in @mask.
+ */
+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;
+}
+
+static bool kvm_range_memory_attributes_need_sync(struct kvm *kvm,
+ gfn_t start, gfn_t end,
+ unsigned long attributes)
+{
+ u64 mask = KVM_MEMORY_ATTRIBUTE_NEEDS_SYNC_MASK;
+
+ if (attributes & mask)
+ return true;
+
+ return kvm_range_has_any_memory_attributes(kvm, start, end, mask);
+}
+
static __always_inline void kvm_handle_gfn_range(struct kvm *kvm,
struct kvm_mmu_notifier_range *range)
{
@@ -2560,20 +2606,25 @@ static int kvm_vm_set_mem_attributes(struct kvm *kvm, gfn_t start, gfn_t end,
.on_lock = kvm_mmu_invalidate_end,
.may_block = true,
};
+ bool sync = false;
unsigned long i;
void *entry;
int r = 0;
entry = attributes ? xa_mk_value(attributes) : NULL;
- trace_kvm_vm_set_mem_attributes(start, end, attributes);
-
mutex_lock(&kvm->slots_lock);
/* Nothing to do if the entire range has the desired attributes. */
if (kvm_range_has_memory_attributes(kvm, start, end, ~0, attributes))
goto out_unlock;
+ sync = kvm_range_memory_attributes_need_sync(kvm, start, end,
+ attributes);
+
+ trace_kvm_vm_set_mem_attributes(start, end, attributes, sync,
+ kvm->mem_attrs.generation + 1);
+
/*
* Reserve memory ahead of time to avoid having to deal with failures
* partway through setting the new attributes.
@@ -2595,10 +2646,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);
+
kvm_handle_gfn_range(kvm, &post_set_range);
out_unlock:
mutex_unlock(&kvm->slots_lock);
+ if (sync)
+ synchronize_srcu_expedited(&kvm->srcu);
return r;
}
@@ -3473,7 +3530,8 @@ int kvm_vcpu_write_guest(struct kvm_vcpu *vcpu, gpa_t gpa, const void *data,
}
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_vcpu_write_guest);
-static int __kvm_gfn_to_hva_cache_init(struct kvm_memslots *slots,
+static int __kvm_gfn_to_hva_cache_init(struct kvm *kvm,
+ struct kvm_memslots *slots,
struct gfn_to_hva_cache *ghc,
gpa_t gpa, unsigned long len)
{
@@ -3483,8 +3541,8 @@ static int __kvm_gfn_to_hva_cache_init(struct kvm_memslots *slots,
gfn_t nr_pages_needed = end_gfn - start_gfn + 1;
gfn_t nr_pages_avail;
- /* Update ghc->generation before performing any error checks. */
- ghc->generation = slots->generation;
+ /* Update ghc->slots_generation before performing any error checks. */
+ ghc->slots_generation = slots->generation;
if (start_gfn > end_gfn) {
ghc->hva = KVM_HVA_ERR_BAD;
@@ -3503,6 +3561,8 @@ static int __kvm_gfn_to_hva_cache_init(struct kvm_memslots *slots,
return -EFAULT;
}
+ ghc->attrs_generation = kvm_mem_attributes_generation(kvm);
+
/* Use the slow path for cross page reads and writes. */
if (nr_pages_needed == 1)
ghc->hva += offset;
@@ -3518,7 +3578,7 @@ int kvm_gfn_to_hva_cache_init(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
gpa_t gpa, unsigned long len)
{
struct kvm_memslots *slots = kvm_memslots(kvm);
- return __kvm_gfn_to_hva_cache_init(slots, ghc, gpa, len);
+ return __kvm_gfn_to_hva_cache_init(kvm, slots, ghc, gpa, len);
}
EXPORT_SYMBOL_FOR_KVM_INTERNAL(kvm_gfn_to_hva_cache_init);
@@ -3533,8 +3593,8 @@ int kvm_write_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
if (WARN_ON_ONCE(len + offset > ghc->len))
return -EINVAL;
- if (unlikely(!kvm_memslots_check_gen(kvm, ghc->generation, &slots))) {
- if (__kvm_gfn_to_hva_cache_init(slots, ghc, ghc->gpa, ghc->len))
+ if (unlikely(!kvm_memslots_check_gen(kvm, ghc->slots_generation, ghc->attrs_generation, &slots))) {
+ if (__kvm_gfn_to_hva_cache_init(kvm, slots, ghc, ghc->gpa, ghc->len))
return -EFAULT;
}
@@ -3571,8 +3631,8 @@ int kvm_read_guest_offset_cached(struct kvm *kvm, struct gfn_to_hva_cache *ghc,
if (WARN_ON_ONCE(len + offset > ghc->len))
return -EINVAL;
- if (unlikely(!kvm_memslots_check_gen(kvm, ghc->generation, &slots))) {
- if (__kvm_gfn_to_hva_cache_init(slots, ghc, ghc->gpa, ghc->len))
+ if (unlikely(!kvm_memslots_check_gen(kvm, ghc->slots_generation, ghc->attrs_generation, &slots))) {
+ if (__kvm_gfn_to_hva_cache_init(kvm, slots, ghc, ghc->gpa, ghc->len))
return -EFAULT;
}
diff --git a/virt/kvm/pfncache.c b/virt/kvm/pfncache.c
index e09703d249bb..46ffae69fe77 100644
--- a/virt/kvm/pfncache.c
+++ b/virt/kvm/pfncache.c
@@ -76,10 +76,11 @@ bool kvm_gpc_check(struct gfn_to_pfn_cache *gpc, unsigned long len)
return false;
/*
- * If the page was cached from a memslot, make sure the memslots have
- * not been re-configured.
+ * If the page was cached from a memslot, make sure the memslots nor
+ * memory attributes have not been re-configured.
*/
- if (!kvm_is_error_gpa(gpc->gpa) && !kvm_check_gen(gpc->kvm, gpc->generation))
+ if (!kvm_is_error_gpa(gpc->gpa) &&
+ !kvm_check_gen(gpc->kvm, gpc->slots_generation, gpc->attrs_generation))
return false;
if (kvm_is_error_hva(gpc->uhva))
@@ -253,6 +254,7 @@ static kvm_pfn_t hva_to_pfn_retry(struct gfn_to_pfn_cache *gpc)
static int __kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned long uhva)
{
+ struct kvm *kvm = gpc->kvm;
unsigned long page_offset;
bool unmap_old = false;
unsigned long old_uhva;
@@ -292,12 +294,13 @@ static int __kvm_gpc_refresh(struct gfn_to_pfn_cache *gpc, gpa_t gpa, unsigned l
page_offset = offset_in_page(gpa);
- if (!kvm_memslots_check_gen(gpc->kvm, gpc->generation, &slots) ||
+ if (!kvm_memslots_check_gen(gpc->kvm, gpc->slots_generation, gpc->attrs_generation, &slots) ||
gpc->gpa != gpa || kvm_is_error_hva(gpc->uhva)) {
gfn_t gfn = gpa_to_gfn(gpa);
+ gpc->attrs_generation = kvm_mem_attributes_generation(kvm);
gpc->gpa = gpa;
- gpc->generation = slots->generation;
+ gpc->slots_generation = slots->generation;
gpc->memslot = __gfn_to_memslot(slots, gfn);
gpc->uhva = gfn_to_hva_memslot(gpc->memslot, gfn);
--
2.52.0
next prev parent reply other threads:[~2026-09-18 13:50 UTC|newest]
Thread overview: 35+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-18 13:49 [PATCH v3 00/28] KVM: x86: Introduce memory protection attributes Paolo Bonzini
2026-09-18 13:50 ` [PATCH 01/31] KVM: x86/hyperv: do not overwrite hc->ingpa for slow SIGNAL_EVENT hypercall Paolo Bonzini
2026-09-18 13:50 ` [PATCH 02/31] KVM: selftests: Take into account mixed memory fault flags Paolo Bonzini
2026-09-18 13:50 ` [PATCH 03/31] KVM: Define and communicate KVM_EXIT_MEMORY_FAULT RWX flags to userspace Paolo Bonzini
2026-09-18 13:50 ` [PATCH 04/31] KVM: selftests: Test address translation for Hyper-V direct L2 hypercalls Paolo Bonzini
2026-09-18 13:50 ` [PATCH 05/31] KVM: apply nGPA->GPA translation to KVM_HC_CLOCK_PAIRING Paolo Bonzini
2026-09-18 13:50 ` [PATCH 06/31] KVM: x86: Introduce memory fault on invalid hypercalls reads/writes Paolo Bonzini
2026-09-21 16:56 ` Vitaly Kuznetsov
2026-09-18 13:50 ` [PATCH 07/31] KVM: selftests: test hypercall memory fault exits Paolo Bonzini
2026-09-18 13:50 ` [PATCH 08/31] KVM: x86/mmu: intersect writability from __kvm_faultin_pfn with fault->map_writable Paolo Bonzini
2026-09-18 13:50 ` [PATCH 09/31] KVM: x86/mmu: Extend map_writable to a full ACC_* mask Paolo Bonzini
2026-09-18 13:50 ` [PATCH 10/31] KVM: x86/mmu: Init memslot hugepage information for non-private_mem VMs too Paolo Bonzini
2026-09-18 13:50 ` [PATCH 11/31] KVM: pass kvm == NULL case to kvm_arch_has_private_mem Paolo Bonzini
2026-09-18 13:50 ` [PATCH 12/31] KVM: adjust for presence of more than one attribute Paolo Bonzini
2026-09-18 13:50 ` [PATCH 13/31] KVM: Introduce NR/NW/NX memory attributes Paolo Bonzini
2026-09-18 13:50 ` [PATCH 14/31] KVM: Include memory protections in result of gfn->hva conversion Paolo Bonzini
2026-09-18 13:50 ` [PATCH 15/31] KVM: Introduce kvm_fetch_guest_page() and use it for x86 Paolo Bonzini
2026-09-18 13:50 ` [PATCH 16/31] KVM: Take memory protections into account for memory read/write/fetch Paolo Bonzini
2026-09-18 13:50 ` [PATCH 17/31] KVM: Take memory protections into account for __kvm_vcpu_map Paolo Bonzini
2026-09-18 13:50 ` [PATCH 18/31] KVM: Encapsulate memattrs array into anonymous struct Paolo Bonzini
2026-09-18 13:50 ` [PATCH 19/31] KVM: loongarch: do full validity check on the gfn-to-hva cache Paolo Bonzini
2026-09-18 13:50 ` [PATCH 20/31] KVM: Introduce kvm_check_gen()/kvm_memslots_check_gen() Paolo Bonzini
2026-09-18 13:50 ` Paolo Bonzini [this message]
2026-09-18 13:50 ` [PATCH 22/31] KVM: Take memory protections into account for accesses with cached gfn->hva Paolo Bonzini
2026-09-18 13:50 ` [PATCH 23/31] KVM: pfncache: Fail to refresh if it contains memory protections Paolo Bonzini
2026-09-18 13:50 ` [PATCH 24/31] KVM: x86/mmu: Do not prefetch sptes on gfns backed by memory attributes Paolo Bonzini
2026-09-18 13:50 ` [PATCH 25/31] KVM: x86/mmu: Take memory protection attributes into account during faults Paolo Bonzini
2026-09-18 13:50 ` [PATCH 26/31] KVM: x86/mmu: Issue memory fault exit if walk failed due to memory attribute Paolo Bonzini
2026-09-18 13:50 ` [PATCH 27/31] KVM: let kvm_arch_post_set_memory_attributes drop mmu_lock Paolo Bonzini
2026-09-18 13:50 ` [PATCH 28/31] KVM: x86/mmu: Obsolete all roots if memattr contains gPTEs Paolo Bonzini
2026-09-18 13:50 ` [PATCH 29/31] KVM: x86: selftests: Introduce memory protection attributes test Paolo Bonzini
2026-09-18 13:50 ` [PATCH 30/31] KVM: x86: selftests: Introduce memory attributes PTE test Paolo Bonzini
2026-09-18 13:50 ` [PATCH 31/31] KVM: x86: selftests: Introduce memory attributes side-channel tests Paolo Bonzini
2026-09-18 15:20 ` [PATCH v3 00/28] KVM: x86: Introduce memory protection attributes Paolo Bonzini
2026-09-21 16:56 ` Vitaly Kuznetsov
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=20260918135030.171564-22-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=nsaenz@amazon.com \
--cc=snambakam@linux.microsoft.com \
--cc=vkuznets@redhat.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®