From: Sriram Nambakam <snambakam@linux.microsoft.com>
To: kvm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Subject: [RFC PATCH v1 14/42] KVM: Add per-plane memory attribute support for cross-plane EPT protection
Date: Wed, 5 Aug 2026 04:02:56 -0700 [thread overview]
Message-ID: <20260805110324.25067-15-snambakam@linux.microsoft.com> (raw)
In-Reply-To: <20260805110324.25067-1-snambakam@linux.microsoft.com>
Extend the KVM memory attributes framework to support per-plane
R/W/X permission control, enabling a higher-privilege plane (e.g.,
plane-1 / secure kernel) to restrict a lower-privilege plane's
(e.g., plane-0) EPT permissions.
This is the KVM equivalent of the AMD SEV-SNP RMP (Reverse Map Table):
each plane has its own mem_attr_array, and attributes like NO_WRITE
and NO_EXEC are enforced by filtering pte_access bits during SPTE
creation.
Changes:
- include/uapi/linux/kvm.h: Add KVM_MEMORY_ATTRIBUTE_NO_WRITE (bit 4)
and KVM_MEMORY_ATTRIBUTE_NO_EXEC (bit 5). Add struct
kvm_plane_memory_attributes and KVM_SET_PLANE_MEMORY_ATTRIBUTES
ioctl (0xd6) for targeting a specific plane's address space.
- virt/kvm/kvm_main.c: Extend kvm_supported_mem_attributes() to
return NO_WRITE|NO_EXEC when CONFIG_KVM_MAX_NR_VCPU_PLANES is
enabled. Add KVM_SET_PLANE_MEMORY_ATTRIBUTES ioctl handler that
validates the target plane and delegates to the existing
kvm_vm_ioctl_set_mem_attributes() infrastructure.
- arch/x86/kvm/mmu/spte.h: Add kvm_plane_filter_pte_access() helper
that reads the plane's mem_attr_array for a GFN and strips W/X
from pte_access when NO_WRITE/NO_EXEC are set.
- arch/x86/kvm/mmu/tdp_mmu.c, arch/x86/kvm/mmu/mmu.c: Wire
kvm_plane_filter_pte_access() into both TDP and shadow MMU SPTE
creation paths, filtering pte_access before calling make_spte().
---
arch/x86/kvm/mmu/mmu.c | 4 +++-
arch/x86/kvm/mmu/spte.h | 33 +++++++++++++++++++++++++++++++++
arch/x86/kvm/mmu/tdp_mmu.c | 4 +++-
include/uapi/linux/kvm.h | 23 +++++++++++++++++++++++
4 files changed, 62 insertions(+), 2 deletions(-)
diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c
index a0d9a0a33c5f..3b861a42a712 100644
--- a/arch/x86/kvm/mmu/mmu.c
+++ b/arch/x86/kvm/mmu/mmu.c
@@ -3107,7 +3107,9 @@ static int mmu_set_spte(struct kvm_vcpu *vcpu, struct kvm_memory_slot *slot,
return RET_PF_EMULATE;
}
- wrprot = make_spte(vcpu, sp, slot, pte_access, gfn, pfn, *sptep, prefetch,
+ wrprot = make_spte(vcpu, sp, slot,
+ kvm_plane_filter_pte_access(vcpu, gfn, pte_access),
+ gfn, pfn, *sptep, prefetch,
false, host_writable, &spte);
if (*sptep == spte) {
diff --git a/arch/x86/kvm/mmu/spte.h b/arch/x86/kvm/mmu/spte.h
index 13eea94dd212..421836fd3932 100644
--- a/arch/x86/kvm/mmu/spte.h
+++ b/arch/x86/kvm/mmu/spte.h
@@ -579,4 +579,37 @@ static inline u64 restore_acc_track_spte(u64 spte)
void __init kvm_mmu_spte_module_init(void);
void kvm_mmu_reset_all_pte_masks(void);
+/*
+ * Apply per-plane memory protection attributes to pte_access.
+ * If the plane's mem_attr_array has NO_WRITE or NO_EXEC set for a GFN,
+ * strip the corresponding access bits before building the SPTE.
+ */
+#ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES
+static inline unsigned int kvm_plane_filter_pte_access(struct kvm_vcpu *vcpu,
+ gfn_t gfn,
+ unsigned int pte_access)
+{
+ struct kvm_plane *plane = vcpu_to_plane(vcpu);
+ unsigned long attrs;
+
+ if (!plane)
+ return pte_access;
+
+ attrs = kvm_get_plane_memory_attributes(plane, gfn);
+ if (attrs & KVM_MEMORY_ATTRIBUTE_NO_WRITE)
+ pte_access &= ~ACC_WRITE_MASK;
+ if (attrs & KVM_MEMORY_ATTRIBUTE_NO_EXEC)
+ pte_access &= ~ACC_EXEC_MASK;
+
+ return pte_access;
+}
+#else
+static inline unsigned int kvm_plane_filter_pte_access(struct kvm_vcpu *vcpu,
+ gfn_t gfn,
+ unsigned int pte_access)
+{
+ return pte_access;
+}
+#endif
+
#endif
diff --git a/arch/x86/kvm/mmu/tdp_mmu.c b/arch/x86/kvm/mmu/tdp_mmu.c
index 4503558211fd..0603445377aa 100644
--- a/arch/x86/kvm/mmu/tdp_mmu.c
+++ b/arch/x86/kvm/mmu/tdp_mmu.c
@@ -1140,7 +1140,9 @@ static int tdp_mmu_map_handle_target_level(struct kvm_vcpu *vcpu,
if (unlikely(!fault->slot))
new_spte = make_mmio_spte(vcpu, iter->gfn, sp->role.access);
else
- wrprot = make_spte(vcpu, sp, fault->slot, sp->role.access, iter->gfn,
+ wrprot = make_spte(vcpu, sp, fault->slot,
+ kvm_plane_filter_pte_access(vcpu, iter->gfn, sp->role.access),
+ iter->gfn,
fault->pfn, iter->old_spte, fault->prefetch,
false, fault->map_writable, &new_spte);
diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h
index de670bd836bf..82189353ef35 100644
--- a/include/uapi/linux/kvm.h
+++ b/include/uapi/linux/kvm.h
@@ -1687,6 +1687,29 @@ struct kvm_memory_attributes {
#define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3)
+/*
+ * Per-plane memory protection attributes (VM planes / VBS).
+ * These control EPT R/W/X permissions enforced by the hypervisor on
+ * behalf of a higher-privilege plane (e.g., plane-1 restricting plane-0).
+ */
+#define KVM_MEMORY_ATTRIBUTE_NO_WRITE (1ULL << 4)
+#define KVM_MEMORY_ATTRIBUTE_NO_EXEC (1ULL << 5)
+
+/*
+ * Set memory attributes on a specific plane's address space.
+ * Used by a higher-privilege plane to restrict a lower-privilege plane's
+ * EPT permissions (e.g., plane-1 making plane-0 kernel text read-only).
+ */
+struct kvm_plane_memory_attributes {
+ __u32 plane; /* target plane index */
+ __u32 flags; /* must be 0 */
+ __u64 address; /* GPA (page-aligned) */
+ __u64 size; /* size in bytes (page-aligned) */
+ __u64 attributes; /* KVM_MEMORY_ATTRIBUTE_NO_WRITE / NO_EXEC */
+};
+
+#define KVM_SET_PLANE_MEMORY_ATTRIBUTES _IOW(KVMIO, 0xd6, struct kvm_plane_memory_attributes)
+
#define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd)
#define GUEST_MEMFD_FLAG_MMAP (1ULL << 0)
#define GUEST_MEMFD_FLAG_INIT_SHARED (1ULL << 1)
--
2.55.0
next prev parent reply other threads:[~2026-08-05 11:03 UTC|newest]
Thread overview: 43+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-05 11:02 [RFC PATCH v1 00/42] VBS/VSM-on-KVM: VBS integration for KVM VM planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 01/42] Fix merge issue - Remove duplicate definition for kvm_arch_has_irq_bypass Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 02/42] Fix compilation Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 03/42] Fix compile error Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 04/42] Fix compile errors Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 05/42] Initial support for VM Planes - Add kernel config for CONFIG_VM_PLANES - Parse vm plane config from initrd for plane configuration - Make hypercalls to allocate memory for the vm planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 06/42] Use vcpu count from the plane configuration Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 07/42] skip processing plane configuration for plane 0 - plane 0 is the boot plane Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 08/42] Add plane config param to specify kernel image format Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 09/42] Activate the VM Planes through the Hypervisor - Using KVM as the VMM Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 10/42] allow the command line to be specified for kernels in other planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 11/42] Various changes to support VM Planes Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 12/42] Add a Virtualization Based Security (VBS) framework. - Add backends for AMD SEV-SNP, Intel TDX, Arm CCA and KVM Planes. - Support VTL on Hyper-V in addition to Planes on KVM Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 13/42] Add a inter-plane communication mechanism through KVM. - model this to use a single page similar to SEV-SNP Sriram Nambakam
2026-08-05 11:02 ` Sriram Nambakam [this message]
2026-08-05 11:02 ` [RFC PATCH v1 15/42] KVM: x86: Add KVM_HC_VBS_VTL_CALL hypercall for VBS inter-plane calls Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 16/42] vbs: Add HEKI kernel sealing and fix KVM plane memory attribute guards Sriram Nambakam
2026-08-05 11:02 ` [RFC PATCH v1 17/42] vbs: Add module authentication via VBS/HEKI Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 18/42] vbs: Add kexec validation and make module auth non-fatal Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 19/42] Merge branch 'master' into vm-planes Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 20/42] kvm: x86: fix merged plane API/stat build regressions Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 21/42] KVM: x86: exit VM planes and VBS hypercalls to userspace Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 22/42] kexec: block legacy kexec_load when VBS is active Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 23/42] kvm: x86: fix merged plane API/stat build regressions Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 24/42] KVM: planes: expose memory-attribute setting to in-kernel callers Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 25/42] vm_planes: drop unused per-plane vcpu_count Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 26/42] drivers/virt: add VBS secure-plane park loop Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 27/42] KVM: planes: add arch-neutral in-kernel plane switch helper Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 28/42] KVM: x86: add VBS VTL call/return and cross-plane set-mem-attrs hypercalls Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 29/42] init/vm_planes: set up planes from rootfs_initcall and load ELF payloads Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 30/42] security/vbs: run backend probe and HEKI seal at rootfs_initcall Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 31/42] security/vbs: pin the VTL call hypercall to CPU0 Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 32/42] security/vbs: add secure-plane monitor backend Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 33/42] drivers/virt: rename VBS park loop to secure_monitor Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 34/42] x86/realmode: skip the sub-1M trampoline for the VBS secure plane Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 35/42] KVM: x86: deny normal-plane access to secure-plane memory Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 36/42] KVM: plane: handle KVM_CHECK_EXTENSION on the plane fd Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 37/42] KVM: selftests: run plane tests with a split IRQ chip Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 38/42] kvm: x86: drop obsolete kvm_cache_regs.h Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 39/42] kvm: arch: finalize plane hooks and kvm_arch_vcpu_create signature Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 40/42] kvm: x86: use kvm_vcpu scheduling-state accessors and struct stat fields Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 41/42] kvm: x86: finalize per-plane APIC state and CPUID placement Sriram Nambakam
2026-08-05 11:03 ` [RFC PATCH v1 42/42] kvm: planes: reconcile core plane state, UAPI and hypercall exit Sriram Nambakam
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=20260805110324.25067-15-snambakam@linux.microsoft.com \
--to=snambakam@linux.microsoft.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
/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