diff --git a/resources/hiding_ci/kernel_commit_hash b/resources/hiding_ci/kernel_commit_hash index d5c975dba9e..927b0259c87 100644 --- a/resources/hiding_ci/kernel_commit_hash +++ b/resources/hiding_ci/kernel_commit_hash @@ -1 +1 @@ -86731a2a651e58953fc949573895f2fa6d456841 \ No newline at end of file +d7b8f8e20813f0179d8ef519541a3527e7661d3a diff --git a/resources/hiding_ci/kernel_config_overrides b/resources/hiding_ci/kernel_config_overrides index 5746d788a05..6cb1dd1f894 100644 --- a/resources/hiding_ci/kernel_config_overrides +++ b/resources/hiding_ci/kernel_config_overrides @@ -14,3 +14,4 @@ CONFIG_KVM_GENERIC_HARDWARE_ENABLING=y CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES=y CONFIG_KVM_GENERIC_PRIVATE_MEM=y CONFIG_DEBUG_INFO=y +CONFIG_KVM_XEN=n diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0002-KVM-Rename-CONFIG_KVM_PRIVATE_MEM-to-CONFIG_KVM_GMEM.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0001-KVM-Rename-CONFIG_KVM_PRIVATE_MEM-to-CONFIG_KVM_GMEM.patch similarity index 81% rename from resources/hiding_ci/linux_patches/05-mmap-support/0002-KVM-Rename-CONFIG_KVM_PRIVATE_MEM-to-CONFIG_KVM_GMEM.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0001-KVM-Rename-CONFIG_KVM_PRIVATE_MEM-to-CONFIG_KVM_GMEM.patch index 953a109ffbb..6180afd4712 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0002-KVM-Rename-CONFIG_KVM_PRIVATE_MEM-to-CONFIG_KVM_GMEM.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0001-KVM-Rename-CONFIG_KVM_PRIVATE_MEM-to-CONFIG_KVM_GMEM.patch @@ -1,11 +1,19 @@ -From ba45bc1cd4624badfab75d73286d753403b3cfb5 Mon Sep 17 00:00:00 2001 +From fc57b8c1deda99bc1e64d45dd7f97a1b9259d16e Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:13 +0100 -Subject: [PATCH 02/42] KVM: Rename CONFIG_KVM_PRIVATE_MEM to CONFIG_KVM_GMEM +Date: Wed, 9 Jul 2025 11:59:27 +0100 +Subject: [PATCH 01/45] KVM: Rename CONFIG_KVM_PRIVATE_MEM to CONFIG_KVM_GMEM -The option KVM_PRIVATE_MEM enables guest_memfd in general. Subsequent -patches add shared memory support to guest_memfd. Therefore, rename it -to KVM_GMEM to make its purpose clearer. +Rename the Kconfig option CONFIG_KVM_PRIVATE_MEM to CONFIG_KVM_GMEM. The +original name implied that the feature only supported "private" memory. +However, CONFIG_KVM_PRIVATE_MEM enables guest_memfd in general, which is +not exclusively for private memory. Subsequent patches in this series +will add guest_memfd support for non-CoCo VMs, whose memory is not +private. + +Renaming the Kconfig option to CONFIG_KVM_GMEM more accurately reflects +its broader scope as the main Kconfig option for all guest_memfd-backed +memory. This provides clearer semantics for the option and avoids +confusion as new features are introduced. Reviewed-by: Ira Weiny Reviewed-by: Gavin Shan @@ -16,15 +24,15 @@ Signed-off-by: David Hildenbrand Signed-off-by: Fuad Tabba --- arch/x86/include/asm/kvm_host.h | 2 +- - include/linux/kvm_host.h | 10 +++++----- + include/linux/kvm_host.h | 14 +++++++------- virt/kvm/Kconfig | 8 ++++---- virt/kvm/Makefile.kvm | 2 +- virt/kvm/kvm_main.c | 4 ++-- virt/kvm/kvm_mm.h | 4 ++-- - 6 files changed, 15 insertions(+), 15 deletions(-) + 6 files changed, 17 insertions(+), 17 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index b4a391929cdb..6e0bbf4c2202 100644 +index 639d9bcee842..66bdd0759d27 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -2269,7 +2269,7 @@ void kvm_configure_mmu(bool enable_tdp, int tdp_forced_root_level, @@ -37,7 +45,7 @@ index b4a391929cdb..6e0bbf4c2202 100644 #else #define kvm_arch_has_private_mem(kvm) false diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 3bde4fb5c6aa..b2c415e81e2e 100644 +index 3bde4fb5c6aa..755b09dcafce 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -601,7 +601,7 @@ struct kvm_memory_slot { @@ -49,9 +57,14 @@ index 3bde4fb5c6aa..b2c415e81e2e 100644 struct { /* * Writes protected by kvm->slots_lock. Acquiring a -@@ -722,7 +722,7 @@ static inline int kvm_arch_vcpu_memslots_id(struct kvm_vcpu *vcpu) - * Arch code must define kvm_arch_has_private_mem if support for private memory - * is enabled. +@@ -719,10 +719,10 @@ static inline int kvm_arch_vcpu_memslots_id(struct kvm_vcpu *vcpu) + #endif + + /* +- * Arch code must define kvm_arch_has_private_mem if support for private memory +- * is enabled. ++ * Arch code must define kvm_arch_has_private_mem if support for guest_memfd is ++ * enabled. */ -#if !defined(kvm_arch_has_private_mem) && !IS_ENABLED(CONFIG_KVM_PRIVATE_MEM) +#if !defined(kvm_arch_has_private_mem) && !IS_ENABLED(CONFIG_KVM_GMEM) diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0003-KVM-Rename-CONFIG_KVM_GENERIC_PRIVATE_MEM-to-CONFIG_.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0002-KVM-Rename-CONFIG_KVM_GENERIC_PRIVATE_MEM-to-CONFIG_.patch similarity index 67% rename from resources/hiding_ci/linux_patches/05-mmap-support/0003-KVM-Rename-CONFIG_KVM_GENERIC_PRIVATE_MEM-to-CONFIG_.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0002-KVM-Rename-CONFIG_KVM_GENERIC_PRIVATE_MEM-to-CONFIG_.patch index 4f3e49ef2bf..3446b605a9f 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0003-KVM-Rename-CONFIG_KVM_GENERIC_PRIVATE_MEM-to-CONFIG_.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0002-KVM-Rename-CONFIG_KVM_GENERIC_PRIVATE_MEM-to-CONFIG_.patch @@ -1,12 +1,18 @@ -From 3d9f3ec523f188f416761e52a5c47f7a7b457ad0 Mon Sep 17 00:00:00 2001 +From 2ce4cc59bb3e067e019842870824d7a459d140f0 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:14 +0100 -Subject: [PATCH 03/42] KVM: Rename CONFIG_KVM_GENERIC_PRIVATE_MEM to +Date: Wed, 9 Jul 2025 11:59:28 +0100 +Subject: [PATCH 02/45] KVM: Rename CONFIG_KVM_GENERIC_PRIVATE_MEM to CONFIG_KVM_GENERIC_GMEM_POPULATE -The option KVM_GENERIC_PRIVATE_MEM enables populating a GPA range with -guest data. Rename it to KVM_GENERIC_GMEM_POPULATE to make its purpose -clearer. +The original name was vague regarding its functionality. This Kconfig +option specifically enables and gates the kvm_gmem_populate() function, +which is responsible for populating a GPA range with guest data. + +The new name, KVM_GENERIC_GMEM_POPULATE, describes the purpose of the +option: to enable generic guest_memfd population mechanisms. This +improves clarity for developers and ensures the name accurately reflects +the functionality it controls, especially as guest_memfd support expands +beyond purely "private" memory scenarios. Reviewed-by: Ira Weiny Reviewed-by: Gavin Shan @@ -16,14 +22,14 @@ Co-developed-by: David Hildenbrand Signed-off-by: David Hildenbrand Signed-off-by: Fuad Tabba --- - arch/x86/kvm/Kconfig | 4 ++-- + arch/x86/kvm/Kconfig | 6 +++--- include/linux/kvm_host.h | 2 +- virt/kvm/Kconfig | 2 +- virt/kvm/guest_memfd.c | 2 +- - 4 files changed, 5 insertions(+), 5 deletions(-) + 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig -index 2eeffcec5382..9151cd82adab 100644 +index 2eeffcec5382..df1fdbb4024b 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -46,7 +46,7 @@ config KVM_X86 @@ -35,6 +41,15 @@ index 2eeffcec5382..9151cd82adab 100644 select KVM_WERROR if WERROR config KVM +@@ -95,7 +95,7 @@ config KVM_SW_PROTECTED_VM + config KVM_INTEL + tristate "KVM for Intel (and compatible) processors support" + depends on KVM && IA32_FEAT_CTL +- select KVM_GENERIC_PRIVATE_MEM if INTEL_TDX_HOST ++ select KVM_GENERIC_GMEM_POPULATE if INTEL_TDX_HOST + select KVM_GENERIC_MEMORY_ATTRIBUTES if INTEL_TDX_HOST + help + Provides support for KVM on processors equipped with Intel's VT @@ -157,7 +157,7 @@ config KVM_AMD_SEV depends on KVM_AMD && X86_64 depends on CRYPTO_DEV_SP_PSP && !(KVM_AMD=y && CRYPTO_DEV_CCP_DD=m) @@ -45,7 +60,7 @@ index 2eeffcec5382..9151cd82adab 100644 select HAVE_KVM_ARCH_GMEM_INVALIDATE help diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index b2c415e81e2e..7700efc06e35 100644 +index 755b09dcafce..359baaae5e9f 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -2556,7 +2556,7 @@ static inline int kvm_gmem_get_pfn(struct kvm *kvm, diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0003-KVM-Introduce-kvm_arch_supports_gmem.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0003-KVM-Introduce-kvm_arch_supports_gmem.patch new file mode 100644 index 00000000000..584e13cf170 --- /dev/null +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0003-KVM-Introduce-kvm_arch_supports_gmem.patch @@ -0,0 +1,102 @@ +From 85b1525e138e76dd43f58e8b5cfd2f0f861ae6a6 Mon Sep 17 00:00:00 2001 +From: Fuad Tabba +Date: Wed, 9 Jul 2025 11:59:29 +0100 +Subject: [PATCH 03/45] KVM: Introduce kvm_arch_supports_gmem() + +Introduce kvm_arch_supports_gmem() to explicitly indicate whether an +architecture supports guest_memfd. + +Previously, kvm_arch_has_private_mem() was used to check for guest_memfd +support. However, this conflated guest_memfd with "private" memory, +implying that guest_memfd was exclusively for CoCo VMs or other private +memory use cases. + +With the expansion of guest_memfd to support non-private memory, such as +shared host mappings, it is necessary to decouple these concepts. The +new kvm_arch_supports_gmem() function provides a clear way to check for +guest_memfd support. + +Reviewed-by: Ira Weiny +Reviewed-by: Gavin Shan +Reviewed-by: Shivank Garg +Reviewed-by: Vlastimil Babka +Co-developed-by: David Hildenbrand +Signed-off-by: David Hildenbrand +Signed-off-by: Fuad Tabba +--- + arch/x86/include/asm/kvm_host.h | 4 +++- + include/linux/kvm_host.h | 11 +++++++++++ + virt/kvm/kvm_main.c | 4 ++-- + 3 files changed, 16 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 66bdd0759d27..09f4f6240d9d 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -2271,8 +2271,10 @@ void kvm_configure_mmu(bool enable_tdp, int tdp_forced_root_level, + + #ifdef CONFIG_KVM_GMEM + #define kvm_arch_has_private_mem(kvm) ((kvm)->arch.has_private_mem) ++#define kvm_arch_supports_gmem(kvm) kvm_arch_has_private_mem(kvm) + #else + #define kvm_arch_has_private_mem(kvm) false ++#define kvm_arch_supports_gmem(kvm) false + #endif + + #define kvm_arch_has_readonly_mem(kvm) (!(kvm)->arch.has_protected_state) +@@ -2325,7 +2327,7 @@ enum { + #define HF_SMM_INSIDE_NMI_MASK (1 << 2) + + # define KVM_MAX_NR_ADDRESS_SPACES 2 +-/* SMM is currently unsupported for guests with private memory. */ ++/* SMM is currently unsupported for guests with guest_memfd private memory. */ + # define kvm_arch_nr_memslot_as_ids(kvm) (kvm_arch_has_private_mem(kvm) ? 1 : 2) + # define kvm_arch_vcpu_memslots_id(vcpu) ((vcpu)->arch.hflags & HF_SMM_MASK ? 1 : 0) + # define kvm_memslots_for_spte_role(kvm, role) __kvm_memslots(kvm, (role).smm) +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index 359baaae5e9f..ab1bde048034 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -729,6 +729,17 @@ static inline bool kvm_arch_has_private_mem(struct kvm *kvm) + } + #endif + ++/* ++ * Arch code must define kvm_arch_supports_gmem if support for guest_memfd is ++ * enabled. ++ */ ++#if !defined(kvm_arch_supports_gmem) && !IS_ENABLED(CONFIG_KVM_GMEM) ++static inline bool kvm_arch_supports_gmem(struct kvm *kvm) ++{ ++ return false; ++} ++#endif ++ + #ifndef kvm_arch_has_readonly_mem + static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) + { +diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c +index 898c3d5a7ba8..afbc025ce4d3 100644 +--- a/virt/kvm/kvm_main.c ++++ b/virt/kvm/kvm_main.c +@@ -1588,7 +1588,7 @@ static int check_memory_region_flags(struct kvm *kvm, + { + u32 valid_flags = KVM_MEM_LOG_DIRTY_PAGES; + +- if (kvm_arch_has_private_mem(kvm)) ++ if (kvm_arch_supports_gmem(kvm)) + valid_flags |= KVM_MEM_GUEST_MEMFD; + + /* Dirty logging private memory is not currently supported. */ +@@ -4912,7 +4912,7 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) + #endif + #ifdef CONFIG_KVM_GMEM + case KVM_CAP_GUEST_MEMFD: +- return !kvm || kvm_arch_has_private_mem(kvm); ++ return !kvm || kvm_arch_supports_gmem(kvm); + #endif + default: + break; +-- +2.49.0 + diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0004-KVM-Rename-kvm_arch_has_private_mem-to-kvm_arch_supp.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0004-KVM-Rename-kvm_arch_has_private_mem-to-kvm_arch_supp.patch deleted file mode 100644 index f055a1658ce..00000000000 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0004-KVM-Rename-kvm_arch_has_private_mem-to-kvm_arch_supp.patch +++ /dev/null @@ -1,147 +0,0 @@ -From e5c3c69a2795226cfd06a78acae8934de610eb21 Mon Sep 17 00:00:00 2001 -From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:15 +0100 -Subject: [PATCH 04/42] KVM: Rename kvm_arch_has_private_mem() to - kvm_arch_supports_gmem() - -The function kvm_arch_has_private_mem() indicates whether an architecture -supports guest_memfd. Until now, this support implied the memory was -strictly private. - -To decouple guest_memfd support from memory privacy, rename this -function to kvm_arch_supports_gmem(). - -Reviewed-by: Ira Weiny -Reviewed-by: Gavin Shan -Reviewed-by: Shivank Garg -Reviewed-by: Vlastimil Babka -Co-developed-by: David Hildenbrand -Signed-off-by: David Hildenbrand -Signed-off-by: Fuad Tabba ---- - arch/x86/include/asm/kvm_host.h | 8 ++++---- - arch/x86/kvm/mmu/mmu.c | 8 ++++---- - include/linux/kvm_host.h | 6 +++--- - virt/kvm/kvm_main.c | 6 +++--- - 4 files changed, 14 insertions(+), 14 deletions(-) - -diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index 6e0bbf4c2202..3d69da6d2d9e 100644 ---- a/arch/x86/include/asm/kvm_host.h -+++ b/arch/x86/include/asm/kvm_host.h -@@ -2270,9 +2270,9 @@ void kvm_configure_mmu(bool enable_tdp, int tdp_forced_root_level, - - - #ifdef CONFIG_KVM_GMEM --#define kvm_arch_has_private_mem(kvm) ((kvm)->arch.has_private_mem) -+#define kvm_arch_supports_gmem(kvm) ((kvm)->arch.has_private_mem) - #else --#define kvm_arch_has_private_mem(kvm) false -+#define kvm_arch_supports_gmem(kvm) false - #endif - - #define kvm_arch_has_readonly_mem(kvm) (!(kvm)->arch.has_protected_state) -@@ -2325,8 +2325,8 @@ enum { - #define HF_SMM_INSIDE_NMI_MASK (1 << 2) - - # define KVM_MAX_NR_ADDRESS_SPACES 2 --/* SMM is currently unsupported for guests with private memory. */ --# define kvm_arch_nr_memslot_as_ids(kvm) (kvm_arch_has_private_mem(kvm) ? 1 : 2) -+/* SMM is currently unsupported for guests with guest_memfd (esp private) memory. */ -+# define kvm_arch_nr_memslot_as_ids(kvm) (kvm_arch_supports_gmem(kvm) ? 1 : 2) - # define kvm_arch_vcpu_memslots_id(vcpu) ((vcpu)->arch.hflags & HF_SMM_MASK ? 1 : 0) - # define kvm_memslots_for_spte_role(kvm, role) __kvm_memslots(kvm, (role).smm) - #else -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index 4e06e2e89a8f..b13f76630b1a 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -4915,7 +4915,7 @@ long kvm_arch_vcpu_pre_fault_memory(struct kvm_vcpu *vcpu, - return r; - - direct_bits = 0; -- if (kvm_arch_has_private_mem(vcpu->kvm) && -+ if (kvm_arch_supports_gmem(vcpu->kvm) && - kvm_mem_is_private(vcpu->kvm, gpa_to_gfn(range->gpa))) - error_code |= PFERR_PRIVATE_ACCESS; - else -@@ -7714,7 +7714,7 @@ bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, - * Zapping SPTEs in this case ensures KVM will reassess whether or not - * a hugepage can be used for affected ranges. - */ -- if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm))) -+ if (WARN_ON_ONCE(!kvm_arch_supports_gmem(kvm))) - return false; - - if (WARN_ON_ONCE(range->end <= range->start)) -@@ -7793,7 +7793,7 @@ bool kvm_arch_post_set_memory_attributes(struct kvm *kvm, - * a range that has PRIVATE GFNs, and conversely converting a range to - * SHARED may now allow hugepages. - */ -- if (WARN_ON_ONCE(!kvm_arch_has_private_mem(kvm))) -+ if (WARN_ON_ONCE(!kvm_arch_supports_gmem(kvm))) - return false; - - /* -@@ -7849,7 +7849,7 @@ void kvm_mmu_init_memslot_memory_attributes(struct kvm *kvm, - { - int level; - -- if (!kvm_arch_has_private_mem(kvm)) -+ if (!kvm_arch_supports_gmem(kvm)) - return; - - for (level = PG_LEVEL_2M; level <= KVM_MAX_HUGEPAGE_LEVEL; level++) { -diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 7700efc06e35..a0e661aa3f8a 100644 ---- a/include/linux/kvm_host.h -+++ b/include/linux/kvm_host.h -@@ -719,11 +719,11 @@ static inline int kvm_arch_vcpu_memslots_id(struct kvm_vcpu *vcpu) - #endif - - /* -- * Arch code must define kvm_arch_has_private_mem if support for private memory -+ * Arch code must define kvm_arch_supports_gmem if support for guest_memfd - * is enabled. - */ --#if !defined(kvm_arch_has_private_mem) && !IS_ENABLED(CONFIG_KVM_GMEM) --static inline bool kvm_arch_has_private_mem(struct kvm *kvm) -+#if !defined(kvm_arch_supports_gmem) && !IS_ENABLED(CONFIG_KVM_GMEM) -+static inline bool kvm_arch_supports_gmem(struct kvm *kvm) - { - return false; - } -diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c -index 898c3d5a7ba8..6efbea208fa6 100644 ---- a/virt/kvm/kvm_main.c -+++ b/virt/kvm/kvm_main.c -@@ -1588,7 +1588,7 @@ static int check_memory_region_flags(struct kvm *kvm, - { - u32 valid_flags = KVM_MEM_LOG_DIRTY_PAGES; - -- if (kvm_arch_has_private_mem(kvm)) -+ if (kvm_arch_supports_gmem(kvm)) - valid_flags |= KVM_MEM_GUEST_MEMFD; - - /* Dirty logging private memory is not currently supported. */ -@@ -2419,7 +2419,7 @@ static int kvm_vm_ioctl_clear_dirty_log(struct kvm *kvm, - #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES - static u64 kvm_supported_mem_attributes(struct kvm *kvm) - { -- if (!kvm || kvm_arch_has_private_mem(kvm)) -+ if (!kvm || kvm_arch_supports_gmem(kvm)) - return KVM_MEMORY_ATTRIBUTE_PRIVATE; - - return 0; -@@ -4912,7 +4912,7 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) - #endif - #ifdef CONFIG_KVM_GMEM - case KVM_CAP_GUEST_MEMFD: -- return !kvm || kvm_arch_has_private_mem(kvm); -+ return !kvm || kvm_arch_supports_gmem(kvm); - #endif - default: - break; --- -2.49.0 - diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0004-KVM-x86-Introduce-kvm-arch.supports_gmem.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0004-KVM-x86-Introduce-kvm-arch.supports_gmem.patch new file mode 100644 index 00000000000..64399f119ec --- /dev/null +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0004-KVM-x86-Introduce-kvm-arch.supports_gmem.patch @@ -0,0 +1,95 @@ +From 50a700bdda054eaa3f86c79a1510a1d60325f2be Mon Sep 17 00:00:00 2001 +From: Fuad Tabba +Date: Wed, 9 Jul 2025 11:59:30 +0100 +Subject: [PATCH 04/45] KVM: x86: Introduce kvm->arch.supports_gmem + +Introduce a new boolean member, supports_gmem, to kvm->arch. + +Previously, the has_private_mem boolean within kvm->arch was implicitly +used to indicate whether guest_memfd was supported for a KVM instance. +However, with the broader support for guest_memfd, it's not exclusively +for private or confidential memory. Therefore, it's necessary to +distinguish between a VM's general guest_memfd capabilities and its +support for private memory. + +This new supports_gmem member will now explicitly indicate guest_memfd +support for a given VM, allowing has_private_mem to represent only +support for private memory. + +Reviewed-by: Ira Weiny +Reviewed-by: Gavin Shan +Reviewed-by: Shivank Garg +Reviewed-by: Vlastimil Babka +Co-developed-by: David Hildenbrand +Signed-off-by: David Hildenbrand +Signed-off-by: Fuad Tabba +--- + arch/x86/include/asm/kvm_host.h | 3 ++- + arch/x86/kvm/svm/svm.c | 1 + + arch/x86/kvm/vmx/tdx.c | 1 + + arch/x86/kvm/x86.c | 4 ++-- + 4 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 09f4f6240d9d..ebddedf0a1f2 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -1342,6 +1342,7 @@ struct kvm_arch { + u8 mmu_valid_gen; + u8 vm_type; + bool has_private_mem; ++ bool supports_gmem; + bool has_protected_state; + bool pre_fault_allowed; + struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES]; +@@ -2271,7 +2272,7 @@ void kvm_configure_mmu(bool enable_tdp, int tdp_forced_root_level, + + #ifdef CONFIG_KVM_GMEM + #define kvm_arch_has_private_mem(kvm) ((kvm)->arch.has_private_mem) +-#define kvm_arch_supports_gmem(kvm) kvm_arch_has_private_mem(kvm) ++#define kvm_arch_supports_gmem(kvm) ((kvm)->arch.supports_gmem) + #else + #define kvm_arch_has_private_mem(kvm) false + #define kvm_arch_supports_gmem(kvm) false +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index ab9b947dbf4f..d1c484eaa8ad 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -5181,6 +5181,7 @@ static int svm_vm_init(struct kvm *kvm) + to_kvm_sev_info(kvm)->need_init = true; + + kvm->arch.has_private_mem = (type == KVM_X86_SNP_VM); ++ kvm->arch.supports_gmem = (type == KVM_X86_SNP_VM); + kvm->arch.pre_fault_allowed = !kvm->arch.has_private_mem; + } + +diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c +index 1ad20c273f3b..c227516e6a02 100644 +--- a/arch/x86/kvm/vmx/tdx.c ++++ b/arch/x86/kvm/vmx/tdx.c +@@ -625,6 +625,7 @@ int tdx_vm_init(struct kvm *kvm) + + kvm->arch.has_protected_state = true; + kvm->arch.has_private_mem = true; ++ kvm->arch.supports_gmem = true; + kvm->arch.disabled_quirks |= KVM_X86_QUIRK_IGNORE_GUEST_PAT; + + /* +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index a9d992d5652f..b34236029383 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -12778,8 +12778,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) + return -EINVAL; + + kvm->arch.vm_type = type; +- kvm->arch.has_private_mem = +- (type == KVM_X86_SW_PROTECTED_VM); ++ kvm->arch.has_private_mem = (type == KVM_X86_SW_PROTECTED_VM); ++ kvm->arch.supports_gmem = (type == KVM_X86_SW_PROTECTED_VM); + /* Decided by the vendor code for other VM types. */ + kvm->arch.pre_fault_allowed = + type == KVM_X86_DEFAULT_VM || type == KVM_X86_SW_PROTECTED_VM; +-- +2.49.0 + diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0006-KVM-Rename-kvm_slot_can_be_private-to-kvm_slot_has_g.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0005-KVM-Rename-kvm_slot_can_be_private-to-kvm_slot_has_g.patch similarity index 78% rename from resources/hiding_ci/linux_patches/05-mmap-support/0006-KVM-Rename-kvm_slot_can_be_private-to-kvm_slot_has_g.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0005-KVM-Rename-kvm_slot_can_be_private-to-kvm_slot_has_g.patch index c4575d9fdf6..d4b1324e5f9 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0006-KVM-Rename-kvm_slot_can_be_private-to-kvm_slot_has_g.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0005-KVM-Rename-kvm_slot_can_be_private-to-kvm_slot_has_g.patch @@ -1,12 +1,21 @@ -From 2b5255551cda9733eeb2c0a52ce4b5e083701e63 Mon Sep 17 00:00:00 2001 +From c16d4a48f6fbad7bdb9024c1c91c38b6d9bdc4e8 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:17 +0100 -Subject: [PATCH 06/42] KVM: Rename kvm_slot_can_be_private() to +Date: Wed, 9 Jul 2025 11:59:31 +0100 +Subject: [PATCH 05/45] KVM: Rename kvm_slot_can_be_private() to kvm_slot_has_gmem() -The function kvm_slot_can_be_private() is used to check whether a memory -slot is backed by guest_memfd. Rename it to kvm_slot_has_gmem() to make -that clearer and to decouple memory being private from guest_memfd. +Rename kvm_slot_can_be_private() to kvm_slot_has_gmem() to improve +clarity and accurately reflect its purpose. + +The function kvm_slot_can_be_private() was previously used to check if a +given kvm_memory_slot is backed by guest_memfd. However, its name +implied that the memory in such a slot was exclusively "private". + +As guest_memfd support expands to include non-private memory (e.g., +shared host mappings), it's important to remove this association. The +new name, kvm_slot_has_gmem(), states that the slot is backed by +guest_memfd without making assumptions about the memory's privacy +attributes. Reviewed-by: Ira Weiny Reviewed-by: Gavin Shan @@ -23,7 +32,7 @@ Signed-off-by: Fuad Tabba 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index 72ed7344cbf4..ada81a75d790 100644 +index 4e06e2e89a8f..213904daf1e5 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c @@ -3285,7 +3285,7 @@ static int __kvm_mmu_max_mapping_level(struct kvm *kvm, @@ -67,7 +76,7 @@ index 459c3b791fd4..ade7a5b36c68 100644 gpa); return; diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index a0e661aa3f8a..76b85099da99 100644 +index ab1bde048034..ed00c2b40e4b 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -614,7 +614,7 @@ struct kvm_memory_slot { diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0005-KVM-x86-Rename-kvm-arch.has_private_mem-to-kvm-arch..patch b/resources/hiding_ci/linux_patches/05-mmap-support/0005-KVM-x86-Rename-kvm-arch.has_private_mem-to-kvm-arch..patch deleted file mode 100644 index d5088b8cbc3..00000000000 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0005-KVM-x86-Rename-kvm-arch.has_private_mem-to-kvm-arch..patch +++ /dev/null @@ -1,91 +0,0 @@ -From 6724239b0af354b909d224394ba639d1a9d66d09 Mon Sep 17 00:00:00 2001 -From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:16 +0100 -Subject: [PATCH 05/42] KVM: x86: Rename kvm->arch.has_private_mem to - kvm->arch.supports_gmem - -The bool has_private_mem is used to indicate whether guest_memfd is -supported. Rename it to supports_gmem to make its meaning clearer and to -decouple memory being private from guest_memfd. - -Reviewed-by: Ira Weiny -Reviewed-by: Gavin Shan -Reviewed-by: Shivank Garg -Reviewed-by: Vlastimil Babka -Co-developed-by: David Hildenbrand -Signed-off-by: David Hildenbrand -Signed-off-by: Fuad Tabba ---- - arch/x86/include/asm/kvm_host.h | 4 ++-- - arch/x86/kvm/mmu/mmu.c | 2 +- - arch/x86/kvm/svm/svm.c | 4 ++-- - arch/x86/kvm/x86.c | 3 +-- - 4 files changed, 6 insertions(+), 7 deletions(-) - -diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index 3d69da6d2d9e..4bc50c1e21bd 100644 ---- a/arch/x86/include/asm/kvm_host.h -+++ b/arch/x86/include/asm/kvm_host.h -@@ -1341,7 +1341,7 @@ struct kvm_arch { - unsigned int indirect_shadow_pages; - u8 mmu_valid_gen; - u8 vm_type; -- bool has_private_mem; -+ bool supports_gmem; - bool has_protected_state; - bool pre_fault_allowed; - struct hlist_head mmu_page_hash[KVM_NUM_MMU_PAGES]; -@@ -2270,7 +2270,7 @@ void kvm_configure_mmu(bool enable_tdp, int tdp_forced_root_level, - - - #ifdef CONFIG_KVM_GMEM --#define kvm_arch_supports_gmem(kvm) ((kvm)->arch.has_private_mem) -+#define kvm_arch_supports_gmem(kvm) ((kvm)->arch.supports_gmem) - #else - #define kvm_arch_supports_gmem(kvm) false - #endif -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index b13f76630b1a..72ed7344cbf4 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -3488,7 +3488,7 @@ static bool page_fault_can_be_fast(struct kvm *kvm, struct kvm_page_fault *fault - * on RET_PF_SPURIOUS until the update completes, or an actual spurious - * case might go down the slow path. Either case will resolve itself. - */ -- if (kvm->arch.has_private_mem && -+ if (kvm->arch.supports_gmem && - fault->is_private != kvm_mem_is_private(kvm, fault->gfn)) - return false; - -diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c -index ab9b947dbf4f..67ab05fd3517 100644 ---- a/arch/x86/kvm/svm/svm.c -+++ b/arch/x86/kvm/svm/svm.c -@@ -5180,8 +5180,8 @@ static int svm_vm_init(struct kvm *kvm) - (type == KVM_X86_SEV_ES_VM || type == KVM_X86_SNP_VM); - to_kvm_sev_info(kvm)->need_init = true; - -- kvm->arch.has_private_mem = (type == KVM_X86_SNP_VM); -- kvm->arch.pre_fault_allowed = !kvm->arch.has_private_mem; -+ kvm->arch.supports_gmem = (type == KVM_X86_SNP_VM); -+ kvm->arch.pre_fault_allowed = !kvm->arch.supports_gmem; - } - - if (!pause_filter_count || !pause_filter_thresh) -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index b58a74c1722d..401256ee817f 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -12778,8 +12778,7 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) - return -EINVAL; - - kvm->arch.vm_type = type; -- kvm->arch.has_private_mem = -- (type == KVM_X86_SW_PROTECTED_VM); -+ kvm->arch.supports_gmem = (type == KVM_X86_SW_PROTECTED_VM); - /* Decided by the vendor code for other VM types. */ - kvm->arch.pre_fault_allowed = - type == KVM_X86_DEFAULT_VM || type == KVM_X86_SW_PROTECTED_VM; --- -2.49.0 - diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0007-KVM-Fix-comments-that-refer-to-slots_lock.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0006-KVM-Fix-comments-that-refer-to-slots_lock.patch similarity index 85% rename from resources/hiding_ci/linux_patches/05-mmap-support/0007-KVM-Fix-comments-that-refer-to-slots_lock.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0006-KVM-Fix-comments-that-refer-to-slots_lock.patch index 12d5e48f102..b49a911a052 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0007-KVM-Fix-comments-that-refer-to-slots_lock.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0006-KVM-Fix-comments-that-refer-to-slots_lock.patch @@ -1,7 +1,7 @@ -From 69fff3f1af3aa61fb0d855904400f52d748b8c42 Mon Sep 17 00:00:00 2001 +From 4e0120bc233422b398683f708873242163972916 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:18 +0100 -Subject: [PATCH 07/42] KVM: Fix comments that refer to slots_lock +Date: Wed, 9 Jul 2025 11:59:32 +0100 +Subject: [PATCH 06/45] KVM: Fix comments that refer to slots_lock Fix comments so that they refer to slots_lock instead of slots_locks (remove trailing s). @@ -18,10 +18,10 @@ Signed-off-by: Fuad Tabba 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 76b85099da99..aec8e4182a65 100644 +index ed00c2b40e4b..9c654dfb6dce 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h -@@ -859,7 +859,7 @@ struct kvm { +@@ -870,7 +870,7 @@ struct kvm { struct notifier_block pm_notifier; #endif #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES @@ -31,7 +31,7 @@ index 76b85099da99..aec8e4182a65 100644 #endif char stats_id[KVM_STATS_NAME_SIZE]; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c -index 6efbea208fa6..d41bcc6a78b0 100644 +index afbc025ce4d3..81bb18fa8655 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -331,7 +331,7 @@ void kvm_flush_remote_tlbs_memslot(struct kvm *kvm, diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0008-KVM-Fix-comment-that-refers-to-kvm-uapi-header-path.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0007-KVM-Fix-comment-that-refers-to-kvm-uapi-header-path.patch similarity index 82% rename from resources/hiding_ci/linux_patches/05-mmap-support/0008-KVM-Fix-comment-that-refers-to-kvm-uapi-header-path.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0007-KVM-Fix-comment-that-refers-to-kvm-uapi-header-path.patch index 640d04e8546..e0b8e21a60c 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0008-KVM-Fix-comment-that-refers-to-kvm-uapi-header-path.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0007-KVM-Fix-comment-that-refers-to-kvm-uapi-header-path.patch @@ -1,7 +1,7 @@ -From b0d555e0113bd1044ad484411c281d411d604af8 Mon Sep 17 00:00:00 2001 +From b9cc809ebdf2e73ebdd42300d3d1b0702aed3d21 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:19 +0100 -Subject: [PATCH 08/42] KVM: Fix comment that refers to kvm uapi header path +Date: Wed, 9 Jul 2025 11:59:33 +0100 +Subject: [PATCH 07/45] KVM: Fix comment that refers to kvm uapi header path The comment that points to the path where the user-visible memslot flags are refers to an outdated path and has a typo. @@ -18,7 +18,7 @@ Signed-off-by: Fuad Tabba 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index aec8e4182a65..9a6712151a74 100644 +index 9c654dfb6dce..1ec71648824c 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -52,7 +52,7 @@ diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0008-KVM-guest_memfd-Allow-host-to-map-guest_memfd-pages.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0008-KVM-guest_memfd-Allow-host-to-map-guest_memfd-pages.patch new file mode 100644 index 00000000000..d5834656c24 --- /dev/null +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0008-KVM-guest_memfd-Allow-host-to-map-guest_memfd-pages.patch @@ -0,0 +1,216 @@ +From 58c6400113b15dce2c25f61927c0572e85c497c4 Mon Sep 17 00:00:00 2001 +From: Fuad Tabba +Date: Wed, 9 Jul 2025 11:59:34 +0100 +Subject: [PATCH 08/45] KVM: guest_memfd: Allow host to map guest_memfd pages + +Introduce the core infrastructure to enable host userspace to mmap() +guest_memfd-backed memory. This is needed for several evolving KVM use +cases: + +* Non-CoCo VM backing: Allows VMMs like Firecracker to run guests + entirely backed by guest_memfd, even for non-CoCo VMs [1]. This + provides a unified memory management model and simplifies guest memory + handling. + +* Direct map removal for enhanced security: This is an important step + for direct map removal of guest memory [2]. By allowing host userspace + to fault in guest_memfd pages directly, we can avoid maintaining host + kernel direct maps of guest memory. This provides additional hardening + against Spectre-like transient execution attacks by removing a + potential attack surface within the kernel. + +* Future guest_memfd features: This also lays the groundwork for future + enhancements to guest_memfd, such as supporting huge pages and + enabling in-place sharing of guest memory with the host for CoCo + platforms that permit it [3]. + +Therefore, enable the basic mmap and fault handling logic within +guest_memfd. However, this functionality is not yet exposed to userspace +and remains inactive until two conditions are met in subsequent patches: + +* Kconfig Gate (CONFIG_KVM_GMEM_SUPPORTS_MMAP): A new Kconfig option, + KVM_GMEM_SUPPORTS_MMAP, is introduced later in this series. This + option gates the compilation and availability of this mmap + functionality at a system level. While the code changes in this patch + might seem small, the Kconfig option is introduced to explicitly + signal the intent to enable this new capability and to provide a clear + compile-time switch for it. It also helps ensure that the necessary + architecture-specific glue (like kvm_arch_supports_gmem_mmap) is + properly defined. + +* Per-instance opt-in (GUEST_MEMFD_FLAG_MMAP): On a per-instance basis, + this functionality is enabled by the guest_memfd flag + GUEST_MEMFD_FLAG_MMAP, which will be set in the KVM_CREATE_GUEST_MEMFD + ioctl. This flag is crucial because when host userspace maps + guest_memfd pages, KVM must *not* manage the these memory regions in + the same way it does for traditional KVM memory slots. The presence of + GUEST_MEMFD_FLAG_MMAP on a guest_memfd instance allows mmap() and + faulting of guest_memfd memory to host userspace. Additionally, it + informs KVM to always consume guest faults to this memory from + guest_memfd, regardless of whether it is a shared or a private fault. + This opt-in mechanism ensures compatibility and prevents conflicts + with existing KVM memory management. This is a per-guest_memfd flag + rather than a per-memslot or per-VM capability because the ability to + mmap directly applies to the specific guest_memfd object, regardless + of how it might be used within various memory slots or VMs. + +[1] https://github.com/firecracker-microvm/firecracker/tree/feature/secret-hiding +[2] https://lore.kernel.org/linux-mm/cc1bb8e9bc3e1ab637700a4d3defeec95b55060a.camel@amazon.com +[3] https://lore.kernel.org/all/c1c9591d-218a-495c-957b-ba356c8f8e09@redhat.com/T/#u + +Reviewed-by: Gavin Shan +Reviewed-by: Shivank Garg +Acked-by: David Hildenbrand +Co-developed-by: Ackerley Tng +Signed-off-by: Ackerley Tng +Signed-off-by: Fuad Tabba +--- + include/linux/kvm_host.h | 13 +++++++ + include/uapi/linux/kvm.h | 1 + + virt/kvm/Kconfig | 4 +++ + virt/kvm/guest_memfd.c | 73 ++++++++++++++++++++++++++++++++++++++++ + 4 files changed, 91 insertions(+) + +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index 1ec71648824c..9ac21985f3b5 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -740,6 +740,19 @@ static inline bool kvm_arch_supports_gmem(struct kvm *kvm) + } + #endif + ++/* ++ * Returns true if this VM supports mmap() in guest_memfd. ++ * ++ * Arch code must define kvm_arch_supports_gmem_mmap if support for guest_memfd ++ * is enabled. ++ */ ++#if !defined(kvm_arch_supports_gmem_mmap) ++static inline bool kvm_arch_supports_gmem_mmap(struct kvm *kvm) ++{ ++ return false; ++} ++#endif ++ + #ifndef kvm_arch_has_readonly_mem + static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) + { +diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h +index 37891580d05d..c71348db818f 100644 +--- a/include/uapi/linux/kvm.h ++++ b/include/uapi/linux/kvm.h +@@ -1592,6 +1592,7 @@ struct kvm_memory_attributes { + #define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3) + + #define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd) ++#define GUEST_MEMFD_FLAG_MMAP (1ULL << 0) + + struct kvm_create_guest_memfd { + __u64 size; +diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig +index 559c93ad90be..fa4acbedb953 100644 +--- a/virt/kvm/Kconfig ++++ b/virt/kvm/Kconfig +@@ -128,3 +128,7 @@ config HAVE_KVM_ARCH_GMEM_PREPARE + config HAVE_KVM_ARCH_GMEM_INVALIDATE + bool + depends on KVM_GMEM ++ ++config KVM_GMEM_SUPPORTS_MMAP ++ select KVM_GMEM ++ bool +diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c +index 6db515833f61..07a4b165471d 100644 +--- a/virt/kvm/guest_memfd.c ++++ b/virt/kvm/guest_memfd.c +@@ -312,7 +312,77 @@ static pgoff_t kvm_gmem_get_index(struct kvm_memory_slot *slot, gfn_t gfn) + return gfn - slot->base_gfn + slot->gmem.pgoff; + } + ++static bool kvm_gmem_supports_mmap(struct inode *inode) ++{ ++ const u64 flags = (u64)inode->i_private; ++ ++ if (!IS_ENABLED(CONFIG_KVM_GMEM_SUPPORTS_MMAP)) ++ return false; ++ ++ return flags & GUEST_MEMFD_FLAG_MMAP; ++} ++ ++static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf) ++{ ++ struct inode *inode = file_inode(vmf->vma->vm_file); ++ struct folio *folio; ++ vm_fault_t ret = VM_FAULT_LOCKED; ++ ++ if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode)) ++ return VM_FAULT_SIGBUS; ++ ++ folio = kvm_gmem_get_folio(inode, vmf->pgoff); ++ if (IS_ERR(folio)) { ++ int err = PTR_ERR(folio); ++ ++ if (err == -EAGAIN) ++ return VM_FAULT_RETRY; ++ ++ return vmf_error(err); ++ } ++ ++ if (WARN_ON_ONCE(folio_test_large(folio))) { ++ ret = VM_FAULT_SIGBUS; ++ goto out_folio; ++ } ++ ++ if (!folio_test_uptodate(folio)) { ++ clear_highpage(folio_page(folio, 0)); ++ kvm_gmem_mark_prepared(folio); ++ } ++ ++ vmf->page = folio_file_page(folio, vmf->pgoff); ++ ++out_folio: ++ if (ret != VM_FAULT_LOCKED) { ++ folio_unlock(folio); ++ folio_put(folio); ++ } ++ ++ return ret; ++} ++ ++static const struct vm_operations_struct kvm_gmem_vm_ops = { ++ .fault = kvm_gmem_fault_user_mapping, ++}; ++ ++static int kvm_gmem_mmap(struct file *file, struct vm_area_struct *vma) ++{ ++ if (!kvm_gmem_supports_mmap(file_inode(file))) ++ return -ENODEV; ++ ++ if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) != ++ (VM_SHARED | VM_MAYSHARE)) { ++ return -EINVAL; ++ } ++ ++ vma->vm_ops = &kvm_gmem_vm_ops; ++ ++ return 0; ++} ++ + static struct file_operations kvm_gmem_fops = { ++ .mmap = kvm_gmem_mmap, + .open = generic_file_open, + .release = kvm_gmem_release, + .fallocate = kvm_gmem_fallocate, +@@ -463,6 +533,9 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args) + u64 flags = args->flags; + u64 valid_flags = 0; + ++ if (kvm_arch_supports_gmem_mmap(kvm)) ++ valid_flags |= GUEST_MEMFD_FLAG_MMAP; ++ + if (flags & ~valid_flags) + return -EINVAL; + +-- +2.49.0 + diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0009-KVM-guest_memfd-Allow-host-to-map-guest_memfd-pages.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0009-KVM-guest_memfd-Allow-host-to-map-guest_memfd-pages.patch deleted file mode 100644 index 2d07ac711fe..00000000000 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0009-KVM-guest_memfd-Allow-host-to-map-guest_memfd-pages.patch +++ /dev/null @@ -1,167 +0,0 @@ -From fdaf4ca0334c928429992096ce96dbdba7d78687 Mon Sep 17 00:00:00 2001 -From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:20 +0100 -Subject: [PATCH 09/42] KVM: guest_memfd: Allow host to map guest_memfd pages - -This patch enables support for shared memory in guest_memfd, including -mapping that memory from host userspace. - -This functionality is gated by the KVM_GMEM_SHARED_MEM Kconfig option, -and enabled for a given instance by the GUEST_MEMFD_FLAG_SUPPORT_SHARED -flag at creation time. - -Reviewed-by: Gavin Shan -Acked-by: David Hildenbrand -Co-developed-by: Ackerley Tng -Signed-off-by: Ackerley Tng -Signed-off-by: Fuad Tabba ---- - include/linux/kvm_host.h | 13 +++++++ - include/uapi/linux/kvm.h | 1 + - virt/kvm/Kconfig | 4 +++ - virt/kvm/guest_memfd.c | 73 ++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 91 insertions(+) - -diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 9a6712151a74..6b63556ca150 100644 ---- a/include/linux/kvm_host.h -+++ b/include/linux/kvm_host.h -@@ -729,6 +729,19 @@ static inline bool kvm_arch_supports_gmem(struct kvm *kvm) - } - #endif - -+/* -+ * Returns true if this VM supports shared mem in guest_memfd. -+ * -+ * Arch code must define kvm_arch_supports_gmem_shared_mem if support for -+ * guest_memfd is enabled. -+ */ -+#if !defined(kvm_arch_supports_gmem_shared_mem) -+static inline bool kvm_arch_supports_gmem_shared_mem(struct kvm *kvm) -+{ -+ return false; -+} -+#endif -+ - #ifndef kvm_arch_has_readonly_mem - static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) - { -diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h -index 37891580d05d..954f0668130c 100644 ---- a/include/uapi/linux/kvm.h -+++ b/include/uapi/linux/kvm.h -@@ -1592,6 +1592,7 @@ struct kvm_memory_attributes { - #define KVM_MEMORY_ATTRIBUTE_PRIVATE (1ULL << 3) - - #define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd) -+#define GUEST_MEMFD_FLAG_SUPPORT_SHARED (1ULL << 0) - - struct kvm_create_guest_memfd { - __u64 size; -diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig -index 559c93ad90be..e90884f74404 100644 ---- a/virt/kvm/Kconfig -+++ b/virt/kvm/Kconfig -@@ -128,3 +128,7 @@ config HAVE_KVM_ARCH_GMEM_PREPARE - config HAVE_KVM_ARCH_GMEM_INVALIDATE - bool - depends on KVM_GMEM -+ -+config KVM_GMEM_SHARED_MEM -+ select KVM_GMEM -+ bool -diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index 6db515833f61..06616b6b493b 100644 ---- a/virt/kvm/guest_memfd.c -+++ b/virt/kvm/guest_memfd.c -@@ -312,7 +312,77 @@ static pgoff_t kvm_gmem_get_index(struct kvm_memory_slot *slot, gfn_t gfn) - return gfn - slot->base_gfn + slot->gmem.pgoff; - } - -+static bool kvm_gmem_supports_shared(struct inode *inode) -+{ -+ const u64 flags = (u64)inode->i_private; -+ -+ if (!IS_ENABLED(CONFIG_KVM_GMEM_SHARED_MEM)) -+ return false; -+ -+ return flags & GUEST_MEMFD_FLAG_SUPPORT_SHARED; -+} -+ -+static vm_fault_t kvm_gmem_fault_shared(struct vm_fault *vmf) -+{ -+ struct inode *inode = file_inode(vmf->vma->vm_file); -+ struct folio *folio; -+ vm_fault_t ret = VM_FAULT_LOCKED; -+ -+ if (((loff_t)vmf->pgoff << PAGE_SHIFT) >= i_size_read(inode)) -+ return VM_FAULT_SIGBUS; -+ -+ folio = kvm_gmem_get_folio(inode, vmf->pgoff); -+ if (IS_ERR(folio)) { -+ int err = PTR_ERR(folio); -+ -+ if (err == -EAGAIN) -+ return VM_FAULT_RETRY; -+ -+ return vmf_error(err); -+ } -+ -+ if (WARN_ON_ONCE(folio_test_large(folio))) { -+ ret = VM_FAULT_SIGBUS; -+ goto out_folio; -+ } -+ -+ if (!folio_test_uptodate(folio)) { -+ clear_highpage(folio_page(folio, 0)); -+ kvm_gmem_mark_prepared(folio); -+ } -+ -+ vmf->page = folio_file_page(folio, vmf->pgoff); -+ -+out_folio: -+ if (ret != VM_FAULT_LOCKED) { -+ folio_unlock(folio); -+ folio_put(folio); -+ } -+ -+ return ret; -+} -+ -+static const struct vm_operations_struct kvm_gmem_vm_ops = { -+ .fault = kvm_gmem_fault_shared, -+}; -+ -+static int kvm_gmem_mmap(struct file *file, struct vm_area_struct *vma) -+{ -+ if (!kvm_gmem_supports_shared(file_inode(file))) -+ return -ENODEV; -+ -+ if ((vma->vm_flags & (VM_SHARED | VM_MAYSHARE)) != -+ (VM_SHARED | VM_MAYSHARE)) { -+ return -EINVAL; -+ } -+ -+ vma->vm_ops = &kvm_gmem_vm_ops; -+ -+ return 0; -+} -+ - static struct file_operations kvm_gmem_fops = { -+ .mmap = kvm_gmem_mmap, - .open = generic_file_open, - .release = kvm_gmem_release, - .fallocate = kvm_gmem_fallocate, -@@ -463,6 +533,9 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args) - u64 flags = args->flags; - u64 valid_flags = 0; - -+ if (kvm_arch_supports_gmem_shared_mem(kvm)) -+ valid_flags |= GUEST_MEMFD_FLAG_SUPPORT_SHARED; -+ - if (flags & ~valid_flags) - return -EINVAL; - --- -2.49.0 - diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0010-KVM-guest_memfd-Track-shared-memory-support-in-memsl.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0009-KVM-guest_memfd-Track-guest_memfd-mmap-support-in-me.patch similarity index 55% rename from resources/hiding_ci/linux_patches/05-mmap-support/0010-KVM-guest_memfd-Track-shared-memory-support-in-memsl.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0009-KVM-guest_memfd-Track-guest_memfd-mmap-support-in-me.patch index 20bb5b39272..6613bbcdc3e 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0010-KVM-guest_memfd-Track-shared-memory-support-in-memsl.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0009-KVM-guest_memfd-Track-guest_memfd-mmap-support-in-me.patch @@ -1,15 +1,19 @@ -From c7a6f2f513fd0cc93092a67c74223438496a5dc2 Mon Sep 17 00:00:00 2001 +From e841f1cf86506f567df73da1a9429fe8586f90a5 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:21 +0100 -Subject: [PATCH 10/42] KVM: guest_memfd: Track shared memory support in +Date: Wed, 9 Jul 2025 11:59:35 +0100 +Subject: [PATCH 09/45] KVM: guest_memfd: Track guest_memfd mmap support in memslot -Add a new internal flag in the top half of memslot->flags to track when -a guest_memfd-backed slot supports shared memory, which is reserved for -internal use in KVM. +Add a new internal flag, KVM_MEMSLOT_GMEM_ONLY, to the top half of +memslot->flags. This flag tracks when a guest_memfd-backed memory slot +supports host userspace mmap operations. It's strictly for KVM's +internal use. -This avoids repeatedly checking the underlying guest_memfd file for -shared memory support, which requires taking a reference on the file. +This optimization avoids repeatedly checking the underlying guest_memfd +file for mmap support, which would otherwise require taking and +releasing a reference on the file for each check. By caching this +information directly in the memslot, we reduce overhead and simplify the +logic involved in handling guest_memfd-backed pages for host mappings. Reviewed-by: Gavin Shan Acked-by: David Hildenbrand @@ -21,7 +25,7 @@ Signed-off-by: Fuad Tabba 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 6b63556ca150..bba7d2c14177 100644 +index 9ac21985f3b5..d2218ec57ceb 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -54,7 +54,8 @@ @@ -30,35 +34,35 @@ index 6b63556ca150..bba7d2c14177 100644 */ -#define KVM_MEMSLOT_INVALID (1UL << 16) +#define KVM_MEMSLOT_INVALID (1UL << 16) -+#define KVM_MEMSLOT_SUPPORTS_GMEM_SHARED (1UL << 17) ++#define KVM_MEMSLOT_GMEM_ONLY (1UL << 17) /* * Bit 63 of the memslot generation number is an "update in-progress flag", -@@ -2525,6 +2526,14 @@ static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu, +@@ -2536,6 +2537,14 @@ static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu, vcpu->run->memory_fault.flags |= KVM_MEMORY_EXIT_FLAG_PRIVATE; } -+static inline bool kvm_gmem_memslot_supports_shared(const struct kvm_memory_slot *slot) ++static inline bool kvm_memslot_is_gmem_only(const struct kvm_memory_slot *slot) +{ -+ if (!IS_ENABLED(CONFIG_KVM_GMEM_SHARED_MEM)) ++ if (!IS_ENABLED(CONFIG_KVM_GMEM_SUPPORTS_MMAP)) + return false; + -+ return slot->flags & KVM_MEMSLOT_SUPPORTS_GMEM_SHARED; ++ return slot->flags & KVM_MEMSLOT_GMEM_ONLY; +} + #ifdef CONFIG_KVM_GENERIC_MEMORY_ATTRIBUTES static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn_t gfn) { diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index 06616b6b493b..73b0aa2bc45f 100644 +index 07a4b165471d..2b00f8796a15 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -592,6 +592,8 @@ int kvm_gmem_bind(struct kvm *kvm, struct kvm_memory_slot *slot, */ WRITE_ONCE(slot->gmem.file, file); slot->gmem.pgoff = start; -+ if (kvm_gmem_supports_shared(inode)) -+ slot->flags |= KVM_MEMSLOT_SUPPORTS_GMEM_SHARED; ++ if (kvm_gmem_supports_mmap(inode)) ++ slot->flags |= KVM_MEMSLOT_GMEM_ONLY; xa_store_range(&gmem->bindings, start, end - 1, slot, GFP_KERNEL); filemap_invalidate_unlock(inode->i_mapping); diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0010-KVM-x86-mmu-Generalize-private_max_mapping_level-x86.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0010-KVM-x86-mmu-Generalize-private_max_mapping_level-x86.patch new file mode 100644 index 00000000000..343e8416320 --- /dev/null +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0010-KVM-x86-mmu-Generalize-private_max_mapping_level-x86.patch @@ -0,0 +1,240 @@ +From 1405fe03056846a5f0cebe06721a290a0f436094 Mon Sep 17 00:00:00 2001 +From: Ackerley Tng +Date: Wed, 9 Jul 2025 11:59:36 +0100 +Subject: [PATCH 10/45] KVM: x86/mmu: Generalize private_max_mapping_level x86 + op to max_mapping_level + +Generalize the private_max_mapping_level x86 operation to +max_mapping_level. + +The private_max_mapping_level operation allows platform-specific code to +limit mapping levels (e.g., forcing 4K pages for certain memory types). +While it was previously used exclusively for private memory, guest_memfd +can now back both private and non-private memory. Platforms may have +specific mapping level restrictions that apply to guest_memfd memory +regardless of its privacy attribute. Therefore, generalize this +operation. + +Rename the operation: Removes the "private" prefix to reflect its +broader applicability to any guest_memfd-backed memory. + +Pass kvm_page_fault information: The operation is updated to receive a +struct kvm_page_fault object instead of just the pfn. This provides +platform-specific implementations (e.g., for TDX or SEV) with additional +context about the fault, such as whether it is private or shared, +allowing them to apply different mapping level rules as needed. + +Enforce "private-only" behavior (for now): Since the current consumers +of this hook (TDX and SEV) still primarily use it to enforce private +memory constraints, platform-specific implementations are made to return +0 for non-private pages. A return value of 0 signals to callers that +platform-specific input should be ignored for that particular fault, +indicating no specific platform-imposed mapping level limits for +non-private pages. This allows the core MMU to continue determining the +mapping level based on generic rules for such cases. + +Suggested-by: Sean Christoperson +Signed-off-by: Ackerley Tng +Signed-off-by: Fuad Tabba +--- + arch/x86/include/asm/kvm-x86-ops.h | 2 +- + arch/x86/include/asm/kvm_host.h | 2 +- + arch/x86/kvm/mmu/mmu.c | 11 ++++++----- + arch/x86/kvm/svm/sev.c | 8 ++++++-- + arch/x86/kvm/svm/svm.c | 2 +- + arch/x86/kvm/svm/svm.h | 4 ++-- + arch/x86/kvm/vmx/main.c | 6 +++--- + arch/x86/kvm/vmx/tdx.c | 5 ++++- + arch/x86/kvm/vmx/x86_ops.h | 2 +- + 9 files changed, 25 insertions(+), 17 deletions(-) + +diff --git a/arch/x86/include/asm/kvm-x86-ops.h b/arch/x86/include/asm/kvm-x86-ops.h +index 8d50e3e0a19b..02301fbad449 100644 +--- a/arch/x86/include/asm/kvm-x86-ops.h ++++ b/arch/x86/include/asm/kvm-x86-ops.h +@@ -146,7 +146,7 @@ KVM_X86_OP_OPTIONAL_RET0(vcpu_get_apicv_inhibit_reasons); + KVM_X86_OP_OPTIONAL(get_untagged_addr) + KVM_X86_OP_OPTIONAL(alloc_apic_backing_page) + KVM_X86_OP_OPTIONAL_RET0(gmem_prepare) +-KVM_X86_OP_OPTIONAL_RET0(private_max_mapping_level) ++KVM_X86_OP_OPTIONAL_RET0(max_mapping_level) + KVM_X86_OP_OPTIONAL(gmem_invalidate) + + #undef KVM_X86_OP +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index ebddedf0a1f2..4c764faa12f3 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -1901,7 +1901,7 @@ struct kvm_x86_ops { + void *(*alloc_apic_backing_page)(struct kvm_vcpu *vcpu); + int (*gmem_prepare)(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order); + void (*gmem_invalidate)(kvm_pfn_t start, kvm_pfn_t end); +- int (*private_max_mapping_level)(struct kvm *kvm, kvm_pfn_t pfn); ++ int (*max_mapping_level)(struct kvm *kvm, struct kvm_page_fault *fault); + }; + + struct kvm_x86_nested_ops { +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index 213904daf1e5..bb925994cbc5 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -4467,9 +4467,11 @@ static inline u8 kvm_max_level_for_order(int order) + return PG_LEVEL_4K; + } + +-static u8 kvm_max_private_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, +- u8 max_level, int gmem_order) ++static u8 kvm_max_private_mapping_level(struct kvm *kvm, ++ struct kvm_page_fault *fault, ++ int gmem_order) + { ++ u8 max_level = fault->max_level; + u8 req_max_level; + + if (max_level == PG_LEVEL_4K) +@@ -4479,7 +4481,7 @@ static u8 kvm_max_private_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, + if (max_level == PG_LEVEL_4K) + return PG_LEVEL_4K; + +- req_max_level = kvm_x86_call(private_max_mapping_level)(kvm, pfn); ++ req_max_level = kvm_x86_call(max_mapping_level)(kvm, fault); + if (req_max_level) + max_level = min(max_level, req_max_level); + +@@ -4511,8 +4513,7 @@ static int kvm_mmu_faultin_pfn_private(struct kvm_vcpu *vcpu, + } + + fault->map_writable = !(fault->slot->flags & KVM_MEM_READONLY); +- fault->max_level = kvm_max_private_mapping_level(vcpu->kvm, fault->pfn, +- fault->max_level, max_order); ++ fault->max_level = kvm_max_private_mapping_level(vcpu->kvm, fault, max_order); + + return RET_PF_CONTINUE; + } +diff --git a/arch/x86/kvm/svm/sev.c b/arch/x86/kvm/svm/sev.c +index ade7a5b36c68..58116439d7c0 100644 +--- a/arch/x86/kvm/svm/sev.c ++++ b/arch/x86/kvm/svm/sev.c +@@ -29,6 +29,7 @@ + #include + #include + ++#include "mmu/mmu_internal.h" + #include "mmu.h" + #include "x86.h" + #include "svm.h" +@@ -4898,7 +4899,7 @@ void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end) + } + } + +-int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn) ++int sev_max_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault) + { + int level, rc; + bool assigned; +@@ -4906,7 +4907,10 @@ int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn) + if (!sev_snp_guest(kvm)) + return 0; + +- rc = snp_lookup_rmpentry(pfn, &assigned, &level); ++ if (!fault->is_private) ++ return 0; ++ ++ rc = snp_lookup_rmpentry(fault->pfn, &assigned, &level); + if (rc || !assigned) + return PG_LEVEL_4K; + +diff --git a/arch/x86/kvm/svm/svm.c b/arch/x86/kvm/svm/svm.c +index d1c484eaa8ad..6ad047189210 100644 +--- a/arch/x86/kvm/svm/svm.c ++++ b/arch/x86/kvm/svm/svm.c +@@ -5347,7 +5347,7 @@ static struct kvm_x86_ops svm_x86_ops __initdata = { + + .gmem_prepare = sev_gmem_prepare, + .gmem_invalidate = sev_gmem_invalidate, +- .private_max_mapping_level = sev_private_max_mapping_level, ++ .max_mapping_level = sev_max_mapping_level, + }; + + /* +diff --git a/arch/x86/kvm/svm/svm.h b/arch/x86/kvm/svm/svm.h +index e6f3c6a153a0..c2579f7df734 100644 +--- a/arch/x86/kvm/svm/svm.h ++++ b/arch/x86/kvm/svm/svm.h +@@ -787,7 +787,7 @@ void sev_handle_rmp_fault(struct kvm_vcpu *vcpu, gpa_t gpa, u64 error_code); + void sev_snp_init_protected_guest_state(struct kvm_vcpu *vcpu); + int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, int max_order); + void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end); +-int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn); ++int sev_max_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault); + struct vmcb_save_area *sev_decrypt_vmsa(struct kvm_vcpu *vcpu); + void sev_free_decrypted_vmsa(struct kvm_vcpu *vcpu, struct vmcb_save_area *vmsa); + #else +@@ -816,7 +816,7 @@ static inline int sev_gmem_prepare(struct kvm *kvm, kvm_pfn_t pfn, gfn_t gfn, in + return 0; + } + static inline void sev_gmem_invalidate(kvm_pfn_t start, kvm_pfn_t end) {} +-static inline int sev_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn) ++static inline int sev_max_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault) + { + return 0; + } +diff --git a/arch/x86/kvm/vmx/main.c b/arch/x86/kvm/vmx/main.c +index d1e02e567b57..8e53554932ba 100644 +--- a/arch/x86/kvm/vmx/main.c ++++ b/arch/x86/kvm/vmx/main.c +@@ -871,10 +871,10 @@ static int vt_vcpu_mem_enc_ioctl(struct kvm_vcpu *vcpu, void __user *argp) + return tdx_vcpu_ioctl(vcpu, argp); + } + +-static int vt_gmem_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn) ++static int vt_gmem_max_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault) + { + if (is_td(kvm)) +- return tdx_gmem_private_max_mapping_level(kvm, pfn); ++ return tdx_gmem_max_mapping_level(kvm, fault); + + return 0; + } +@@ -1044,7 +1044,7 @@ struct kvm_x86_ops vt_x86_ops __initdata = { + .mem_enc_ioctl = vt_op_tdx_only(mem_enc_ioctl), + .vcpu_mem_enc_ioctl = vt_op_tdx_only(vcpu_mem_enc_ioctl), + +- .private_max_mapping_level = vt_op_tdx_only(gmem_private_max_mapping_level) ++ .max_mapping_level = vt_op_tdx_only(gmem_max_mapping_level) + }; + + struct kvm_x86_init_ops vt_init_ops __initdata = { +diff --git a/arch/x86/kvm/vmx/tdx.c b/arch/x86/kvm/vmx/tdx.c +index c227516e6a02..1607b1f6be21 100644 +--- a/arch/x86/kvm/vmx/tdx.c ++++ b/arch/x86/kvm/vmx/tdx.c +@@ -3292,8 +3292,11 @@ int tdx_vcpu_ioctl(struct kvm_vcpu *vcpu, void __user *argp) + return ret; + } + +-int tdx_gmem_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn) ++int tdx_gmem_max_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault) + { ++ if (!fault->is_private) ++ return 0; ++ + return PG_LEVEL_4K; + } + +diff --git a/arch/x86/kvm/vmx/x86_ops.h b/arch/x86/kvm/vmx/x86_ops.h +index b4596f651232..ca7bc9e0fce5 100644 +--- a/arch/x86/kvm/vmx/x86_ops.h ++++ b/arch/x86/kvm/vmx/x86_ops.h +@@ -163,7 +163,7 @@ int tdx_sept_remove_private_spte(struct kvm *kvm, gfn_t gfn, + void tdx_flush_tlb_current(struct kvm_vcpu *vcpu); + void tdx_flush_tlb_all(struct kvm_vcpu *vcpu); + void tdx_load_mmu_pgd(struct kvm_vcpu *vcpu, hpa_t root_hpa, int root_level); +-int tdx_gmem_private_max_mapping_level(struct kvm *kvm, kvm_pfn_t pfn); ++int tdx_gmem_max_mapping_level(struct kvm *kvm, struct kvm_page_fault *fault); + #endif + + #endif /* __KVM_X86_VMX_X86_OPS_H */ +-- +2.49.0 + diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0011-KVM-x86-mmu-Allow-NULL-able-fault-in-kvm_max_private.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0011-KVM-x86-mmu-Allow-NULL-able-fault-in-kvm_max_private.patch new file mode 100644 index 00000000000..8df25675397 --- /dev/null +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0011-KVM-x86-mmu-Allow-NULL-able-fault-in-kvm_max_private.patch @@ -0,0 +1,76 @@ +From 0bbaadd1753792a845481f48cbc9c524cf85d2ea Mon Sep 17 00:00:00 2001 +From: Ackerley Tng +Date: Wed, 9 Jul 2025 11:59:37 +0100 +Subject: [PATCH 11/45] KVM: x86/mmu: Allow NULL-able fault in + kvm_max_private_mapping_level + +Refactor kvm_max_private_mapping_level() to accept a NULL kvm_page_fault +pointer and rename it to kvm_gmem_max_mapping_level(). + +The max_mapping_level x86 operation (previously private_max_mapping_level) +is designed to potentially be called without an active page fault, for +instance, when kvm_mmu_max_mapping_level() is determining the maximum +mapping level for a gfn proactively. + +Allow NULL fault pointer: Modify kvm_max_private_mapping_level() to +safely handle a NULL fault argument. This aligns its interface with the +kvm_x86_ops.max_mapping_level operation it wraps, which can also be +called with NULL. + +Rename function to kvm_gmem_max_mapping_level(): This reinforces that +the function's scope is for guest_memfd-backed memory, which can be +either private or non-private, removing any remaining "private" +connotation from its name. + +Optimize max_level checks: Introduce a check in the caller to skip +querying for max_mapping_level if the current max_level is already +PG_LEVEL_4K, as no further reduction is possible. + +Suggested-by: Sean Christoperson +Signed-off-by: Ackerley Tng +Signed-off-by: Fuad Tabba +--- + arch/x86/kvm/mmu/mmu.c | 17 ++++++++--------- + 1 file changed, 8 insertions(+), 9 deletions(-) + +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index bb925994cbc5..495dcedaeafa 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -4467,17 +4467,13 @@ static inline u8 kvm_max_level_for_order(int order) + return PG_LEVEL_4K; + } + +-static u8 kvm_max_private_mapping_level(struct kvm *kvm, +- struct kvm_page_fault *fault, +- int gmem_order) ++static u8 kvm_gmem_max_mapping_level(struct kvm *kvm, int order, ++ struct kvm_page_fault *fault) + { +- u8 max_level = fault->max_level; + u8 req_max_level; ++ u8 max_level; + +- if (max_level == PG_LEVEL_4K) +- return PG_LEVEL_4K; +- +- max_level = min(kvm_max_level_for_order(gmem_order), max_level); ++ max_level = kvm_max_level_for_order(order); + if (max_level == PG_LEVEL_4K) + return PG_LEVEL_4K; + +@@ -4513,7 +4509,10 @@ static int kvm_mmu_faultin_pfn_private(struct kvm_vcpu *vcpu, + } + + fault->map_writable = !(fault->slot->flags & KVM_MEM_READONLY); +- fault->max_level = kvm_max_private_mapping_level(vcpu->kvm, fault, max_order); ++ if (fault->max_level >= PG_LEVEL_4K) { ++ fault->max_level = kvm_gmem_max_mapping_level(vcpu->kvm, ++ max_order, fault); ++ } + + return RET_PF_CONTINUE; + } +-- +2.49.0 + diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0011-KVM-x86-mmu-Handle-guest-page-faults-for-guest_memfd.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0011-KVM-x86-mmu-Handle-guest-page-faults-for-guest_memfd.patch deleted file mode 100644 index 02621a9c119..00000000000 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0011-KVM-x86-mmu-Handle-guest-page-faults-for-guest_memfd.patch +++ /dev/null @@ -1,163 +0,0 @@ -From aa57cd34d53f8cc0e6af44b4070c39945ac556b4 Mon Sep 17 00:00:00 2001 -From: Ackerley Tng -Date: Wed, 11 Jun 2025 14:33:22 +0100 -Subject: [PATCH 11/42] KVM: x86/mmu: Handle guest page faults for guest_memfd - with shared memory - -For memslots backed by guest_memfd with shared mem support, the KVM MMU -must always fault in pages from guest_memfd, and not from the host -userspace_addr. Update the fault handler to do so. - -This patch also refactors related function names for accuracy: - -kvm_mem_is_private() returns true only when the current private/shared -state (in the CoCo sense) of the memory is private, and returns false if -the current state is shared explicitly or impicitly, e.g., belongs to a -non-CoCo VM. - -kvm_mmu_faultin_pfn_gmem() is updated to indicate that it can be used to -fault in not just private memory, but more generally, from guest_memfd. - -Co-developed-by: David Hildenbrand -Signed-off-by: David Hildenbrand -Signed-off-by: Ackerley Tng -Co-developed-by: Fuad Tabba -Signed-off-by: Fuad Tabba ---- - arch/x86/kvm/mmu/mmu.c | 38 +++++++++++++++++++++++--------------- - include/linux/kvm_host.h | 25 +++++++++++++++++++++++-- - 2 files changed, 46 insertions(+), 17 deletions(-) - -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index ada81a75d790..0932c1af47b6 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -3291,6 +3291,11 @@ int kvm_mmu_max_mapping_level(struct kvm *kvm, - return __kvm_mmu_max_mapping_level(kvm, slot, gfn, PG_LEVEL_NUM, is_private); - } - -+static inline bool fault_from_gmem(struct kvm_page_fault *fault) -+{ -+ return fault->is_private || kvm_gmem_memslot_supports_shared(fault->slot); -+} -+ - void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) - { - struct kvm_memory_slot *slot = fault->slot; -@@ -4467,21 +4472,25 @@ static inline u8 kvm_max_level_for_order(int order) - return PG_LEVEL_4K; - } - --static u8 kvm_max_private_mapping_level(struct kvm *kvm, kvm_pfn_t pfn, -- u8 max_level, int gmem_order) -+static u8 kvm_max_level_for_fault_and_order(struct kvm *kvm, -+ struct kvm_page_fault *fault, -+ int order) - { -- u8 req_max_level; -+ u8 max_level = fault->max_level; - - if (max_level == PG_LEVEL_4K) - return PG_LEVEL_4K; - -- max_level = min(kvm_max_level_for_order(gmem_order), max_level); -+ max_level = min(kvm_max_level_for_order(order), max_level); - if (max_level == PG_LEVEL_4K) - return PG_LEVEL_4K; - -- req_max_level = kvm_x86_call(private_max_mapping_level)(kvm, pfn); -- if (req_max_level) -- max_level = min(max_level, req_max_level); -+ if (fault->is_private) { -+ u8 level = kvm_x86_call(private_max_mapping_level)(kvm, fault->pfn); -+ -+ if (level) -+ max_level = min(max_level, level); -+ } - - return max_level; - } -@@ -4493,10 +4502,10 @@ static void kvm_mmu_finish_page_fault(struct kvm_vcpu *vcpu, - r == RET_PF_RETRY, fault->map_writable); - } - --static int kvm_mmu_faultin_pfn_private(struct kvm_vcpu *vcpu, -- struct kvm_page_fault *fault) -+static int kvm_mmu_faultin_pfn_gmem(struct kvm_vcpu *vcpu, -+ struct kvm_page_fault *fault) - { -- int max_order, r; -+ int gmem_order, r; - - if (!kvm_slot_has_gmem(fault->slot)) { - kvm_mmu_prepare_memory_fault_exit(vcpu, fault); -@@ -4504,15 +4513,14 @@ static int kvm_mmu_faultin_pfn_private(struct kvm_vcpu *vcpu, - } - - r = kvm_gmem_get_pfn(vcpu->kvm, fault->slot, fault->gfn, &fault->pfn, -- &fault->refcounted_page, &max_order); -+ &fault->refcounted_page, &gmem_order); - if (r) { - kvm_mmu_prepare_memory_fault_exit(vcpu, fault); - return r; - } - - fault->map_writable = !(fault->slot->flags & KVM_MEM_READONLY); -- fault->max_level = kvm_max_private_mapping_level(vcpu->kvm, fault->pfn, -- fault->max_level, max_order); -+ fault->max_level = kvm_max_level_for_fault_and_order(vcpu->kvm, fault, gmem_order); - - return RET_PF_CONTINUE; - } -@@ -4522,8 +4530,8 @@ static int __kvm_mmu_faultin_pfn(struct kvm_vcpu *vcpu, - { - unsigned int foll = fault->write ? FOLL_WRITE : 0; - -- if (fault->is_private) -- return kvm_mmu_faultin_pfn_private(vcpu, fault); -+ if (fault_from_gmem(fault)) -+ return kvm_mmu_faultin_pfn_gmem(vcpu, fault); - - foll |= FOLL_NOWAIT; - fault->pfn = __kvm_faultin_pfn(fault->slot, fault->gfn, foll, -diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index bba7d2c14177..8f7069385189 100644 ---- a/include/linux/kvm_host.h -+++ b/include/linux/kvm_host.h -@@ -2547,10 +2547,31 @@ bool kvm_arch_pre_set_memory_attributes(struct kvm *kvm, - bool kvm_arch_post_set_memory_attributes(struct kvm *kvm, - struct kvm_gfn_range *range); - -+/* -+ * Returns true if the given gfn's private/shared status (in the CoCo sense) is -+ * private. -+ * -+ * A return value of false indicates that the gfn is explicitly or implicitly -+ * shared (i.e., non-CoCo VMs). -+ */ - static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) - { -- return IS_ENABLED(CONFIG_KVM_GMEM) && -- kvm_get_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIVATE; -+ struct kvm_memory_slot *slot; -+ -+ if (!IS_ENABLED(CONFIG_KVM_GMEM)) -+ return false; -+ -+ slot = gfn_to_memslot(kvm, gfn); -+ if (kvm_slot_has_gmem(slot) && kvm_gmem_memslot_supports_shared(slot)) { -+ /* -+ * Without in-place conversion support, if a guest_memfd memslot -+ * supports shared memory, then all the slot's memory is -+ * considered not private, i.e., implicitly shared. -+ */ -+ return false; -+ } -+ -+ return kvm_get_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIVATE; - } - #else - static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) --- -2.49.0 - diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0012-KVM-x86-Consult-guest_memfd-when-computing-max_mappi.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0012-KVM-x86-Consult-guest_memfd-when-computing-max_mappi.patch deleted file mode 100644 index 685ca3d98a2..00000000000 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0012-KVM-x86-Consult-guest_memfd-when-computing-max_mappi.patch +++ /dev/null @@ -1,245 +0,0 @@ -From 0d6ad36493831412e14582768d66363a60d52405 Mon Sep 17 00:00:00 2001 -From: Ackerley Tng -Date: Wed, 11 Jun 2025 14:33:23 +0100 -Subject: [PATCH 12/42] KVM: x86: Consult guest_memfd when computing - max_mapping_level - -This patch adds kvm_gmem_max_mapping_level(), which always returns -PG_LEVEL_4K since guest_memfd only supports 4K pages for now. - -When guest_memfd supports shared memory, max_mapping_level (especially -when recovering huge pages - see call to __kvm_mmu_max_mapping_level() -from recover_huge_pages_range()) should take input from -guest_memfd. - -Input from guest_memfd should be taken in these cases: - -+ if the memslot supports shared memory (guest_memfd is used for - shared memory, or in future both shared and private memory) or -+ if the memslot is only used for private memory and that gfn is - private. - -If the memslot doesn't use guest_memfd, figure out the -max_mapping_level using the host page tables like before. - -This patch also refactors and inlines the other call to -__kvm_mmu_max_mapping_level(). - -In kvm_mmu_hugepage_adjust(), guest_memfd's input is already -provided (if applicable) in fault->max_level. Hence, there is no need -to query guest_memfd. - -lpage_info is queried like before, and then if the fault is not from -guest_memfd, adjust fault->req_level based on input from host page -tables. - -Acked-by: David Hildenbrand -Signed-off-by: Ackerley Tng -Co-developed-by: Fuad Tabba -Signed-off-by: Fuad Tabba ---- - arch/x86/kvm/mmu/mmu.c | 87 +++++++++++++++++++++++++--------------- - include/linux/kvm_host.h | 11 +++++ - virt/kvm/guest_memfd.c | 12 ++++++ - 3 files changed, 78 insertions(+), 32 deletions(-) - -diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index 0932c1af47b6..b071b9afb8ad 100644 ---- a/arch/x86/kvm/mmu/mmu.c -+++ b/arch/x86/kvm/mmu/mmu.c -@@ -3258,12 +3258,11 @@ static int host_pfn_mapping_level(struct kvm *kvm, gfn_t gfn, - return level; - } - --static int __kvm_mmu_max_mapping_level(struct kvm *kvm, -- const struct kvm_memory_slot *slot, -- gfn_t gfn, int max_level, bool is_private) -+static int kvm_lpage_info_max_mapping_level(struct kvm *kvm, -+ const struct kvm_memory_slot *slot, -+ gfn_t gfn, int max_level) - { - struct kvm_lpage_info *linfo; -- int host_level; - - max_level = min(max_level, max_huge_page_level); - for ( ; max_level > PG_LEVEL_4K; max_level--) { -@@ -3272,28 +3271,61 @@ static int __kvm_mmu_max_mapping_level(struct kvm *kvm, - break; - } - -- if (is_private) -- return max_level; -+ return max_level; -+} -+ -+static inline u8 kvm_max_level_for_order(int order) -+{ -+ BUILD_BUG_ON(KVM_MAX_HUGEPAGE_LEVEL > PG_LEVEL_1G); -+ -+ KVM_MMU_WARN_ON(order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_1G) && -+ order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M) && -+ order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_4K)); -+ -+ if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_1G)) -+ return PG_LEVEL_1G; -+ -+ if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M)) -+ return PG_LEVEL_2M; -+ -+ return PG_LEVEL_4K; -+} -+ -+static inline int kvm_gmem_max_mapping_level(const struct kvm_memory_slot *slot, -+ gfn_t gfn, int max_level) -+{ -+ int max_order; - - if (max_level == PG_LEVEL_4K) - return PG_LEVEL_4K; - -- host_level = host_pfn_mapping_level(kvm, gfn, slot); -- return min(host_level, max_level); -+ max_order = kvm_gmem_mapping_order(slot, gfn); -+ return min(max_level, kvm_max_level_for_order(max_order)); - } - - int kvm_mmu_max_mapping_level(struct kvm *kvm, - const struct kvm_memory_slot *slot, gfn_t gfn) - { -- bool is_private = kvm_slot_has_gmem(slot) && -- kvm_mem_is_private(kvm, gfn); -+ int max_level; - -- return __kvm_mmu_max_mapping_level(kvm, slot, gfn, PG_LEVEL_NUM, is_private); -+ max_level = kvm_lpage_info_max_mapping_level(kvm, slot, gfn, PG_LEVEL_NUM); -+ if (max_level == PG_LEVEL_4K) -+ return PG_LEVEL_4K; -+ -+ if (kvm_slot_has_gmem(slot) && -+ (kvm_gmem_memslot_supports_shared(slot) || -+ kvm_get_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIVATE)) { -+ return kvm_gmem_max_mapping_level(slot, gfn, max_level); -+ } -+ -+ return min(max_level, host_pfn_mapping_level(kvm, gfn, slot)); - } - - static inline bool fault_from_gmem(struct kvm_page_fault *fault) - { -- return fault->is_private || kvm_gmem_memslot_supports_shared(fault->slot); -+ return fault->is_private || -+ (kvm_slot_has_gmem(fault->slot) && -+ kvm_gmem_memslot_supports_shared(fault->slot)); - } - - void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) -@@ -3316,12 +3348,20 @@ void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault - * Enforce the iTLB multihit workaround after capturing the requested - * level, which will be used to do precise, accurate accounting. - */ -- fault->req_level = __kvm_mmu_max_mapping_level(vcpu->kvm, slot, -- fault->gfn, fault->max_level, -- fault->is_private); -+ fault->req_level = kvm_lpage_info_max_mapping_level(vcpu->kvm, slot, -+ fault->gfn, fault->max_level); - if (fault->req_level == PG_LEVEL_4K || fault->huge_page_disallowed) - return; - -+ if (!fault_from_gmem(fault)) { -+ int host_level; -+ -+ host_level = host_pfn_mapping_level(vcpu->kvm, fault->gfn, slot); -+ fault->req_level = min(fault->req_level, host_level); -+ if (fault->req_level == PG_LEVEL_4K) -+ return; -+ } -+ - /* - * mmu_invalidate_retry() was successful and mmu_lock is held, so - * the pmd can't be split from under us. -@@ -4455,23 +4495,6 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) - vcpu->stat.pf_fixed++; - } - --static inline u8 kvm_max_level_for_order(int order) --{ -- BUILD_BUG_ON(KVM_MAX_HUGEPAGE_LEVEL > PG_LEVEL_1G); -- -- KVM_MMU_WARN_ON(order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_1G) && -- order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M) && -- order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_4K)); -- -- if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_1G)) -- return PG_LEVEL_1G; -- -- if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M)) -- return PG_LEVEL_2M; -- -- return PG_LEVEL_4K; --} -- - static u8 kvm_max_level_for_fault_and_order(struct kvm *kvm, - struct kvm_page_fault *fault, - int order) -diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 8f7069385189..58d7761c2a90 100644 ---- a/include/linux/kvm_host.h -+++ b/include/linux/kvm_host.h -@@ -2574,6 +2574,10 @@ static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) - return kvm_get_memory_attributes(kvm, gfn) & KVM_MEMORY_ATTRIBUTE_PRIVATE; - } - #else -+static inline unsigned long kvm_get_memory_attributes(struct kvm *kvm, gfn_t gfn) -+{ -+ return 0; -+} - static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) - { - return false; -@@ -2584,6 +2588,7 @@ static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) - int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, - gfn_t gfn, kvm_pfn_t *pfn, struct page **page, - int *max_order); -+int kvm_gmem_mapping_order(const struct kvm_memory_slot *slot, gfn_t gfn); - #else - static inline int kvm_gmem_get_pfn(struct kvm *kvm, - struct kvm_memory_slot *slot, gfn_t gfn, -@@ -2593,6 +2598,12 @@ static inline int kvm_gmem_get_pfn(struct kvm *kvm, - KVM_BUG_ON(1, kvm); - return -EIO; - } -+static inline int kvm_gmem_mapping_order(const struct kvm_memory_slot *slot, -+ gfn_t gfn) -+{ -+ BUILD_BUG(); -+ return 0; -+} - #endif /* CONFIG_KVM_GMEM */ - - #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_PREPARE -diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index 73b0aa2bc45f..ebdb2d8bf57a 100644 ---- a/virt/kvm/guest_memfd.c -+++ b/virt/kvm/guest_memfd.c -@@ -713,6 +713,18 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, - } - EXPORT_SYMBOL_GPL(kvm_gmem_get_pfn); - -+/* -+ * Returns the mapping order for this @gfn in @slot. -+ * -+ * This is equal to max_order that would be returned if kvm_gmem_get_pfn() were -+ * called now. -+ */ -+int kvm_gmem_mapping_order(const struct kvm_memory_slot *slot, gfn_t gfn) -+{ -+ return 0; -+} -+EXPORT_SYMBOL_GPL(kvm_gmem_mapping_order); -+ - #ifdef CONFIG_KVM_GENERIC_GMEM_POPULATE - long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, long npages, - kvm_gmem_populate_cb post_populate, void *opaque) --- -2.49.0 - diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0012-KVM-x86-mmu-Consult-guest_memfd-when-computing-max_m.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0012-KVM-x86-mmu-Consult-guest_memfd-when-computing-max_m.patch new file mode 100644 index 00000000000..e18b0a8e470 --- /dev/null +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0012-KVM-x86-mmu-Consult-guest_memfd-when-computing-max_m.patch @@ -0,0 +1,212 @@ +From b8f1e64371756c75ef3d952f76342a48203b93fd Mon Sep 17 00:00:00 2001 +From: Ackerley Tng +Date: Wed, 9 Jul 2025 11:59:38 +0100 +Subject: [PATCH 12/45] KVM: x86/mmu: Consult guest_memfd when computing + max_mapping_level + +Modify kvm_mmu_max_mapping_level() to consult guest_memfd for memory +regions backed by it when computing the maximum mapping level, +especially during huge page recovery. + +Previously, kvm_mmu_max_mapping_level() was designed primarily for +host-backed memory and private pages. With guest_memfd now supporting +non-private memory, it's necessary to factor in guest_memfd's influence +on mapping levels for such memory. + +Since guest_memfd can now be used for non-private memory, make +kvm_max_max_mapping_level, when recovering huge pages, take input from +guest_memfd. + +Input is taken from guest_memfd as long as a fault to that slot and gfn +would have been served from guest_memfd. For now, take a shortcut if the +slot and gfn points to memory that is private, since recovering huge +pages aren't supported for private memory yet. + +Since guest_memfd memory can also be faulted into host page tables, +__kvm_mmu_max_mapping_level() still applies since consulting lpage_info +and host page tables are required. + +Move functions kvm_max_level_for_order() and +kvm_gmem_max_mapping_level() so kvm_mmu_max_mapping_level() can use +those functions. + +Acked-by: David Hildenbrand +Signed-off-by: Ackerley Tng +Co-developed-by: Fuad Tabba +Signed-off-by: Fuad Tabba +--- + arch/x86/kvm/mmu/mmu.c | 90 ++++++++++++++++++++++++---------------- + include/linux/kvm_host.h | 7 ++++ + virt/kvm/guest_memfd.c | 17 ++++++++ + 3 files changed, 79 insertions(+), 35 deletions(-) + +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index 495dcedaeafa..6d997063f76f 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -3282,13 +3282,67 @@ static int __kvm_mmu_max_mapping_level(struct kvm *kvm, + return min(host_level, max_level); + } + ++static u8 kvm_max_level_for_order(int order) ++{ ++ BUILD_BUG_ON(KVM_MAX_HUGEPAGE_LEVEL > PG_LEVEL_1G); ++ ++ KVM_MMU_WARN_ON(order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_1G) && ++ order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M) && ++ order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_4K)); ++ ++ if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_1G)) ++ return PG_LEVEL_1G; ++ ++ if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M)) ++ return PG_LEVEL_2M; ++ ++ return PG_LEVEL_4K; ++} ++ ++static u8 kvm_gmem_max_mapping_level(struct kvm *kvm, int order, ++ struct kvm_page_fault *fault) ++{ ++ u8 req_max_level; ++ u8 max_level; ++ ++ max_level = kvm_max_level_for_order(order); ++ if (max_level == PG_LEVEL_4K) ++ return PG_LEVEL_4K; ++ ++ req_max_level = kvm_x86_call(max_mapping_level)(kvm, fault); ++ if (req_max_level) ++ max_level = min(max_level, req_max_level); ++ ++ return max_level; ++} ++ + int kvm_mmu_max_mapping_level(struct kvm *kvm, + const struct kvm_memory_slot *slot, gfn_t gfn) + { + bool is_private = kvm_slot_has_gmem(slot) && + kvm_mem_is_private(kvm, gfn); ++ int max_level = PG_LEVEL_NUM; ++ ++ /* ++ * For now, kvm_mmu_max_mapping_level() is only called from ++ * kvm_mmu_recover_huge_pages(), and that's not yet supported for ++ * private memory, hence we can take a shortcut and return early. ++ */ ++ if (is_private) ++ return PG_LEVEL_4K; + +- return __kvm_mmu_max_mapping_level(kvm, slot, gfn, PG_LEVEL_NUM, is_private); ++ /* ++ * For non-private pages that would have been faulted from guest_memfd, ++ * let guest_memfd influence max_mapping_level. ++ */ ++ if (kvm_memslot_is_gmem_only(slot)) { ++ int order = kvm_gmem_mapping_order(slot, gfn); ++ ++ max_level = min(max_level, ++ kvm_gmem_max_mapping_level(kvm, order, NULL)); ++ } ++ ++ return __kvm_mmu_max_mapping_level(kvm, slot, gfn, max_level, is_private); + } + + void kvm_mmu_hugepage_adjust(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) +@@ -4450,40 +4504,6 @@ void kvm_arch_async_page_ready(struct kvm_vcpu *vcpu, struct kvm_async_pf *work) + vcpu->stat.pf_fixed++; + } + +-static inline u8 kvm_max_level_for_order(int order) +-{ +- BUILD_BUG_ON(KVM_MAX_HUGEPAGE_LEVEL > PG_LEVEL_1G); +- +- KVM_MMU_WARN_ON(order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_1G) && +- order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M) && +- order != KVM_HPAGE_GFN_SHIFT(PG_LEVEL_4K)); +- +- if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_1G)) +- return PG_LEVEL_1G; +- +- if (order >= KVM_HPAGE_GFN_SHIFT(PG_LEVEL_2M)) +- return PG_LEVEL_2M; +- +- return PG_LEVEL_4K; +-} +- +-static u8 kvm_gmem_max_mapping_level(struct kvm *kvm, int order, +- struct kvm_page_fault *fault) +-{ +- u8 req_max_level; +- u8 max_level; +- +- max_level = kvm_max_level_for_order(order); +- if (max_level == PG_LEVEL_4K) +- return PG_LEVEL_4K; +- +- req_max_level = kvm_x86_call(max_mapping_level)(kvm, fault); +- if (req_max_level) +- max_level = min(max_level, req_max_level); +- +- return max_level; +-} +- + static void kvm_mmu_finish_page_fault(struct kvm_vcpu *vcpu, + struct kvm_page_fault *fault, int r) + { +diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h +index d2218ec57ceb..662271314778 100644 +--- a/include/linux/kvm_host.h ++++ b/include/linux/kvm_host.h +@@ -2574,6 +2574,7 @@ static inline bool kvm_mem_is_private(struct kvm *kvm, gfn_t gfn) + int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, + gfn_t gfn, kvm_pfn_t *pfn, struct page **page, + int *max_order); ++int kvm_gmem_mapping_order(const struct kvm_memory_slot *slot, gfn_t gfn); + #else + static inline int kvm_gmem_get_pfn(struct kvm *kvm, + struct kvm_memory_slot *slot, gfn_t gfn, +@@ -2583,6 +2584,12 @@ static inline int kvm_gmem_get_pfn(struct kvm *kvm, + KVM_BUG_ON(1, kvm); + return -EIO; + } ++static inline int kvm_gmem_mapping_order(const struct kvm_memory_slot *slot, ++ gfn_t gfn) ++{ ++ WARN_ONCE(1, "Unexpected call since gmem is disabled."); ++ return 0; ++} + #endif /* CONFIG_KVM_GMEM */ + + #ifdef CONFIG_HAVE_KVM_ARCH_GMEM_PREPARE +diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c +index 2b00f8796a15..d01bd7a2c2bd 100644 +--- a/virt/kvm/guest_memfd.c ++++ b/virt/kvm/guest_memfd.c +@@ -713,6 +713,23 @@ int kvm_gmem_get_pfn(struct kvm *kvm, struct kvm_memory_slot *slot, + } + EXPORT_SYMBOL_GPL(kvm_gmem_get_pfn); + ++/** ++ * kvm_gmem_mapping_order() - Get the mapping order for this @gfn in @slot. ++ * ++ * @slot: the memslot that gfn belongs to. ++ * @gfn: the gfn to look up mapping order for. ++ * ++ * This is equal to max_order that would be returned if kvm_gmem_get_pfn() were ++ * called now. ++ * ++ * Return: the mapping order for this @gfn in @slot. ++ */ ++int kvm_gmem_mapping_order(const struct kvm_memory_slot *slot, gfn_t gfn) ++{ ++ return 0; ++} ++EXPORT_SYMBOL_GPL(kvm_gmem_mapping_order); ++ + #ifdef CONFIG_KVM_GENERIC_GMEM_POPULATE + long kvm_gmem_populate(struct kvm *kvm, gfn_t start_gfn, void __user *src, long npages, + kvm_gmem_populate_cb post_populate, void *opaque) +-- +2.49.0 + diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0013-KVM-x86-Enable-guest_memfd-shared-memory-for-non-CoC.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0013-KVM-x86-Enable-guest_memfd-shared-memory-for-non-CoC.patch deleted file mode 100644 index 8049de981d0..00000000000 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0013-KVM-x86-Enable-guest_memfd-shared-memory-for-non-CoC.patch +++ /dev/null @@ -1,74 +0,0 @@ -From 661b138e0604819c4b93b2bda4d5e3f78011d4eb Mon Sep 17 00:00:00 2001 -From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:24 +0100 -Subject: [PATCH 13/42] KVM: x86: Enable guest_memfd shared memory for non-CoCo - VMs - -Define the architecture-specific macro to enable shared memory support -in guest_memfd for ordinary, i.e., non-CoCo, VM types, specifically -KVM_X86_DEFAULT_VM and KVM_X86_SW_PROTECTED_VM. - -Enable the KVM_GMEM_SHARED_MEM Kconfig option if KVM_SW_PROTECTED_VM is -enabled. - -Co-developed-by: Ackerley Tng -Signed-off-by: Ackerley Tng -Signed-off-by: Fuad Tabba ---- - arch/x86/include/asm/kvm_host.h | 10 ++++++++++ - arch/x86/kvm/Kconfig | 1 + - arch/x86/kvm/x86.c | 3 ++- - 3 files changed, 13 insertions(+), 1 deletion(-) - -diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index 4bc50c1e21bd..7b9ccdd99f32 100644 ---- a/arch/x86/include/asm/kvm_host.h -+++ b/arch/x86/include/asm/kvm_host.h -@@ -2271,8 +2271,18 @@ void kvm_configure_mmu(bool enable_tdp, int tdp_forced_root_level, - - #ifdef CONFIG_KVM_GMEM - #define kvm_arch_supports_gmem(kvm) ((kvm)->arch.supports_gmem) -+ -+/* -+ * CoCo VMs with hardware support that use guest_memfd only for backing private -+ * memory, e.g., TDX, cannot use guest_memfd with userspace mapping enabled. -+ */ -+#define kvm_arch_supports_gmem_shared_mem(kvm) \ -+ (IS_ENABLED(CONFIG_KVM_GMEM_SHARED_MEM) && \ -+ ((kvm)->arch.vm_type == KVM_X86_SW_PROTECTED_VM || \ -+ (kvm)->arch.vm_type == KVM_X86_DEFAULT_VM)) - #else - #define kvm_arch_supports_gmem(kvm) false -+#define kvm_arch_supports_gmem_shared_mem(kvm) false - #endif - - #define kvm_arch_has_readonly_mem(kvm) (!(kvm)->arch.has_protected_state) -diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig -index 9151cd82adab..29845a286430 100644 ---- a/arch/x86/kvm/Kconfig -+++ b/arch/x86/kvm/Kconfig -@@ -47,6 +47,7 @@ config KVM_X86 - select KVM_GENERIC_HARDWARE_ENABLING - select KVM_GENERIC_PRE_FAULT_MEMORY - select KVM_GENERIC_GMEM_POPULATE if KVM_SW_PROTECTED_VM -+ select KVM_GMEM_SHARED_MEM if KVM_SW_PROTECTED_VM - select KVM_WERROR if WERROR - - config KVM -diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index 401256ee817f..e21f5f2fe059 100644 ---- a/arch/x86/kvm/x86.c -+++ b/arch/x86/kvm/x86.c -@@ -12778,7 +12778,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) - return -EINVAL; - - kvm->arch.vm_type = type; -- kvm->arch.supports_gmem = (type == KVM_X86_SW_PROTECTED_VM); -+ kvm->arch.supports_gmem = -+ type == KVM_X86_DEFAULT_VM || type == KVM_X86_SW_PROTECTED_VM; - /* Decided by the vendor code for other VM types. */ - kvm->arch.pre_fault_allowed = - type == KVM_X86_DEFAULT_VM || type == KVM_X86_SW_PROTECTED_VM; --- -2.49.0 - diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0013-KVM-x86-mmu-Handle-guest-page-faults-for-guest_memfd.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0013-KVM-x86-mmu-Handle-guest-page-faults-for-guest_memfd.patch new file mode 100644 index 00000000000..52ebe9b7bc8 --- /dev/null +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0013-KVM-x86-mmu-Handle-guest-page-faults-for-guest_memfd.patch @@ -0,0 +1,68 @@ +From f83651ebccced465c3d399cf9df2705c6bb70e9c Mon Sep 17 00:00:00 2001 +From: Ackerley Tng +Date: Wed, 9 Jul 2025 11:59:39 +0100 +Subject: [PATCH 13/45] KVM: x86/mmu: Handle guest page faults for guest_memfd + with shared memory + +Update the KVM MMU fault handler to service guest page faults +for memory slots backed by guest_memfd with mmap support. For such +slots, the MMU must always fault in pages directly from guest_memfd, +bypassing the host's userspace_addr. + +This ensures that guest_memfd-backed memory is always handled through +the guest_memfd specific faulting path, regardless of whether it's for +private or non-private (shared) use cases. + +Additionally, rename kvm_mmu_faultin_pfn_private() to +kvm_mmu_faultin_pfn_gmem(), as this function is now used to fault in +pages from guest_memfd for both private and non-private memory, +accommodating the new use cases. + +Co-developed-by: David Hildenbrand +Signed-off-by: David Hildenbrand +Signed-off-by: Ackerley Tng +Co-developed-by: Fuad Tabba +Signed-off-by: Fuad Tabba +--- + arch/x86/kvm/mmu/mmu.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c +index 6d997063f76f..cc4cdfea343b 100644 +--- a/arch/x86/kvm/mmu/mmu.c ++++ b/arch/x86/kvm/mmu/mmu.c +@@ -4511,8 +4511,8 @@ static void kvm_mmu_finish_page_fault(struct kvm_vcpu *vcpu, + r == RET_PF_RETRY, fault->map_writable); + } + +-static int kvm_mmu_faultin_pfn_private(struct kvm_vcpu *vcpu, +- struct kvm_page_fault *fault) ++static int kvm_mmu_faultin_pfn_gmem(struct kvm_vcpu *vcpu, ++ struct kvm_page_fault *fault) + { + int max_order, r; + +@@ -4537,13 +4537,18 @@ static int kvm_mmu_faultin_pfn_private(struct kvm_vcpu *vcpu, + return RET_PF_CONTINUE; + } + ++static bool fault_from_gmem(struct kvm_page_fault *fault) ++{ ++ return fault->is_private || kvm_memslot_is_gmem_only(fault->slot); ++} ++ + static int __kvm_mmu_faultin_pfn(struct kvm_vcpu *vcpu, + struct kvm_page_fault *fault) + { + unsigned int foll = fault->write ? FOLL_WRITE : 0; + +- if (fault->is_private) +- return kvm_mmu_faultin_pfn_private(vcpu, fault); ++ if (fault_from_gmem(fault)) ++ return kvm_mmu_faultin_pfn_gmem(vcpu, fault); + + foll |= FOLL_NOWAIT; + fault->pfn = __kvm_faultin_pfn(fault->slot, fault->gfn, foll, +-- +2.49.0 + diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0014-KVM-x86-Enable-guest_memfd-mmap-for-default-VM-type.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0014-KVM-x86-Enable-guest_memfd-mmap-for-default-VM-type.patch new file mode 100644 index 00000000000..85f788fb3b8 --- /dev/null +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0014-KVM-x86-Enable-guest_memfd-mmap-for-default-VM-type.patch @@ -0,0 +1,94 @@ +From 793235f72611c1bcf25801391fbe1aab6fb2373b Mon Sep 17 00:00:00 2001 +From: Fuad Tabba +Date: Wed, 9 Jul 2025 11:59:40 +0100 +Subject: [PATCH 14/45] KVM: x86: Enable guest_memfd mmap for default VM type + +Enable host userspace mmap support for guest_memfd-backed memory when +running KVM with the KVM_X86_DEFAULT_VM type: + +* Define kvm_arch_supports_gmem_mmap() for KVM_X86_DEFAULT_VM: Introduce + the architecture-specific kvm_arch_supports_gmem_mmap() macro, + specifically enabling mmap support for KVM_X86_DEFAULT_VM instances. + This macro, gated by CONFIG_KVM_GMEM_SUPPORTS_MMAP, ensures that only + the default VM type can leverage guest_memfd mmap functionality on + x86. This explicit enablement prevents CoCo VMs, which use guest_memfd + primarily for private memory and rely on hardware-enforced privacy, + from accidentally exposing guest memory via host userspace mappings. + +* Select CONFIG_KVM_GMEM_SUPPORTS_MMAP in KVM_X86: Enable the + CONFIG_KVM_GMEM_SUPPORTS_MMAP Kconfig option when KVM_X86 is selected. + This ensures that the necessary code for guest_memfd mmap support + (introduced earlier) is compiled into the kernel for x86. This Kconfig + option acts as a system-wide gate for the guest_memfd mmap capability. + It implicitly enables CONFIG_KVM_GMEM, making guest_memfd available, + and then layers the mmap capability on top specifically for the + default VM. + +These changes make guest_memfd a more versatile memory backing for +standard KVM guests, allowing VMMs to use a unified guest_memfd model +for both private (CoCo) and non-private (default) VMs. This is a +prerequisite for use cases such as running Firecracker guests entirely +backed by guest_memfd and implementing direct map removal for non-CoCo +VMs. + +Co-developed-by: Ackerley Tng +Signed-off-by: Ackerley Tng +Signed-off-by: Fuad Tabba +--- + arch/x86/include/asm/kvm_host.h | 9 +++++++++ + arch/x86/kvm/Kconfig | 1 + + arch/x86/kvm/x86.c | 3 ++- + 3 files changed, 12 insertions(+), 1 deletion(-) + +diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h +index 4c764faa12f3..4c89feaa1910 100644 +--- a/arch/x86/include/asm/kvm_host.h ++++ b/arch/x86/include/asm/kvm_host.h +@@ -2273,9 +2273,18 @@ void kvm_configure_mmu(bool enable_tdp, int tdp_forced_root_level, + #ifdef CONFIG_KVM_GMEM + #define kvm_arch_has_private_mem(kvm) ((kvm)->arch.has_private_mem) + #define kvm_arch_supports_gmem(kvm) ((kvm)->arch.supports_gmem) ++ ++/* ++ * CoCo VMs with hardware support that use guest_memfd only for backing private ++ * memory, e.g., TDX, cannot use guest_memfd with userspace mapping enabled. ++ */ ++#define kvm_arch_supports_gmem_mmap(kvm) \ ++ (IS_ENABLED(CONFIG_KVM_GMEM_SUPPORTS_MMAP) && \ ++ (kvm)->arch.vm_type == KVM_X86_DEFAULT_VM) + #else + #define kvm_arch_has_private_mem(kvm) false + #define kvm_arch_supports_gmem(kvm) false ++#define kvm_arch_supports_gmem_mmap(kvm) false + #endif + + #define kvm_arch_has_readonly_mem(kvm) (!(kvm)->arch.has_protected_state) +diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig +index df1fdbb4024b..239637b663dc 100644 +--- a/arch/x86/kvm/Kconfig ++++ b/arch/x86/kvm/Kconfig +@@ -47,6 +47,7 @@ config KVM_X86 + select KVM_GENERIC_HARDWARE_ENABLING + select KVM_GENERIC_PRE_FAULT_MEMORY + select KVM_GENERIC_GMEM_POPULATE if KVM_SW_PROTECTED_VM ++ select KVM_GMEM_SUPPORTS_MMAP + select KVM_WERROR if WERROR + + config KVM +diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c +index b34236029383..17c655e5716e 100644 +--- a/arch/x86/kvm/x86.c ++++ b/arch/x86/kvm/x86.c +@@ -12779,7 +12779,8 @@ int kvm_arch_init_vm(struct kvm *kvm, unsigned long type) + + kvm->arch.vm_type = type; + kvm->arch.has_private_mem = (type == KVM_X86_SW_PROTECTED_VM); +- kvm->arch.supports_gmem = (type == KVM_X86_SW_PROTECTED_VM); ++ kvm->arch.supports_gmem = ++ type == KVM_X86_DEFAULT_VM || type == KVM_X86_SW_PROTECTED_VM; + /* Decided by the vendor code for other VM types. */ + kvm->arch.pre_fault_allowed = + type == KVM_X86_DEFAULT_VM || type == KVM_X86_SW_PROTECTED_VM; +-- +2.49.0 + diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0014-KVM-arm64-Refactor-user_mem_abort.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0015-KVM-arm64-Refactor-user_mem_abort.patch similarity index 82% rename from resources/hiding_ci/linux_patches/05-mmap-support/0014-KVM-arm64-Refactor-user_mem_abort.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0015-KVM-arm64-Refactor-user_mem_abort.patch index f5b96a0df5f..e7f4fb30c31 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0014-KVM-arm64-Refactor-user_mem_abort.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0015-KVM-arm64-Refactor-user_mem_abort.patch @@ -1,19 +1,35 @@ -From d8bd2cf8aac924d4e2a992c72e71212dd4e93c8f Mon Sep 17 00:00:00 2001 +From 560781ab8f7341d20675678bf4b4bf8bcee2e438 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:25 +0100 -Subject: [PATCH 14/42] KVM: arm64: Refactor user_mem_abort() +Date: Wed, 9 Jul 2025 11:59:41 +0100 +Subject: [PATCH 15/45] KVM: arm64: Refactor user_mem_abort() -To simplify the code and to make the assumptions clearer, -refactor user_mem_abort() by immediately setting force_pte to -true if the conditions are met. +Refactor user_mem_abort() to improve code clarity and simplify +assumptions within the function. -Remove the comment about logging_active being guaranteed to never be -true for VM_PFNMAP memslots, since it's not actually correct. +Key changes include: -Move code that will be reused in the following patch into separate -functions. +* Immediately set force_pte to true at the beginning of the function if + logging_active is true. This simplifies the flow and makes the + condition for forcing a PTE more explicit. -Other small instances of tidying up. +* Remove the misleading comment stating that logging_active is + guaranteed to never be true for VM_PFNMAP memslots, as this assertion + is not entirely correct. + +* Extract reusable code blocks into new helper functions: + * prepare_mmu_memcache(): Encapsulates the logic for preparing and + topping up the MMU page cache. + * adjust_nested_fault_perms(): Isolates the adjustments to shadow S2 + permissions and the encoding of nested translation levels. + +* Update min(a, (long)b) to min_t(long, a, b) for better type safety and + consistency. + +* Perform other minor tidying up of the code. + +These changes primarily aim to simplify user_mem_abort() and make its +logic easier to understand and maintain, setting the stage for future +modifications. No functional change intended. diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0016-KVM-arm64-Enable-host-mapping-of-shared-guest_memfd-.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0016-KVM-arm64-Enable-host-mapping-of-shared-guest_memfd-.patch deleted file mode 100644 index 2a129dc7a11..00000000000 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0016-KVM-arm64-Enable-host-mapping-of-shared-guest_memfd-.patch +++ /dev/null @@ -1,69 +0,0 @@ -From 3833ce3bfc91b7446fbbf749410a8ad7cf6767f1 Mon Sep 17 00:00:00 2001 -From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:27 +0100 -Subject: [PATCH 16/42] KVM: arm64: Enable host mapping of shared guest_memfd - memory - -Enable the host mapping of guest_memfd-backed memory on arm64. - -This applies to all current arm64 VM types that support guest_memfd. -Future VM types can restrict this behavior via the -kvm_arch_gmem_supports_shared_mem() hook if needed. - -Reviewed-by: James Houghton -Reviewed-by: Gavin Shan -Acked-by: David Hildenbrand -Signed-off-by: Fuad Tabba ---- - arch/arm64/include/asm/kvm_host.h | 4 ++++ - arch/arm64/kvm/Kconfig | 1 + - arch/arm64/kvm/mmu.c | 7 +++++++ - 3 files changed, 12 insertions(+) - -diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h -index d27079968341..678e7b93bb01 100644 ---- a/arch/arm64/include/asm/kvm_host.h -+++ b/arch/arm64/include/asm/kvm_host.h -@@ -1675,5 +1675,9 @@ void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt); - void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *res1); - void check_feature_map(void); - -+#ifdef CONFIG_KVM_GMEM -+#define kvm_arch_supports_gmem(kvm) true -+#define kvm_arch_supports_gmem_shared_mem(kvm) IS_ENABLED(CONFIG_KVM_GMEM_SHARED_MEM) -+#endif - - #endif /* __ARM64_KVM_HOST_H__ */ -diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig -index 713248f240e0..87120d46919a 100644 ---- a/arch/arm64/kvm/Kconfig -+++ b/arch/arm64/kvm/Kconfig -@@ -37,6 +37,7 @@ menuconfig KVM - select HAVE_KVM_VCPU_RUN_PID_CHANGE - select SCHED_INFO - select GUEST_PERF_EVENTS if PERF_EVENTS -+ select KVM_GMEM_SHARED_MEM - help - Support hosting virtualized guest machines. - -diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c -index 71f8b53683e7..55ac03f277e0 100644 ---- a/arch/arm64/kvm/mmu.c -+++ b/arch/arm64/kvm/mmu.c -@@ -2274,6 +2274,13 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, - if ((new->base_gfn + new->npages) > (kvm_phys_size(&kvm->arch.mmu) >> PAGE_SHIFT)) - return -EFAULT; - -+ /* -+ * Only support guest_memfd backed memslots with shared memory, since -+ * there aren't any CoCo VMs that support only private memory on arm64. -+ */ -+ if (kvm_slot_has_gmem(new) && !kvm_gmem_memslot_supports_shared(new)) -+ return -EINVAL; -+ - hva = new->userspace_addr; - reg_end = hva + (new->npages << PAGE_SHIFT); - --- -2.49.0 - diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0015-KVM-arm64-Handle-guest_memfd-backed-guest-page-fault.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0016-KVM-arm64-Handle-guest_memfd-backed-guest-page-fault.patch similarity index 83% rename from resources/hiding_ci/linux_patches/05-mmap-support/0015-KVM-arm64-Handle-guest_memfd-backed-guest-page-fault.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0016-KVM-arm64-Handle-guest_memfd-backed-guest-page-fault.patch index 7b4aa15486a..fbe2d912e65 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0015-KVM-arm64-Handle-guest_memfd-backed-guest-page-fault.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0016-KVM-arm64-Handle-guest_memfd-backed-guest-page-fault.patch @@ -1,13 +1,22 @@ -From c04bce997f55f5463df73708c15ba0fae0d142b9 Mon Sep 17 00:00:00 2001 +From 7ad514bb5df2e781f742c113cae15f1169ac99f5 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:26 +0100 -Subject: [PATCH 15/42] KVM: arm64: Handle guest_memfd-backed guest page faults +Date: Wed, 9 Jul 2025 11:59:42 +0100 +Subject: [PATCH 16/45] KVM: arm64: Handle guest_memfd-backed guest page faults -Add arm64 support for handling guest page faults on guest_memfd backed -memslots. Until guest_memfd supports huge pages, the fault granule is -restricted to PAGE_SIZE. +Add arm64 architecture support for handling guest page faults on memory +slots backed by guest_memfd. + +This change introduces a new function, gmem_abort(), which encapsulates +the fault handling logic specific to guest_memfd-backed memory. The +kvm_handle_guest_abort() entry point is updated to dispatch to +gmem_abort() when a fault occurs on a guest_memfd-backed memory slot (as +determined by kvm_slot_has_gmem()). + +Until guest_memfd gains support for huge pages, the fault granule for +these memory regions is restricted to PAGE_SIZE. Reviewed-by: Gavin Shan +Reviewed-by: James Houghton Signed-off-by: Fuad Tabba --- arch/arm64/kvm/mmu.c | 82 ++++++++++++++++++++++++++++++++++++++++++-- diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0017-KVM-arm64-Enable-host-mapping-of-shared-guest_memfd-.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0017-KVM-arm64-Enable-host-mapping-of-shared-guest_memfd-.patch new file mode 100644 index 00000000000..5144561b628 --- /dev/null +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0017-KVM-arm64-Enable-host-mapping-of-shared-guest_memfd-.patch @@ -0,0 +1,89 @@ +From 1b1ada64197d513955774384c6589c51d9f84569 Mon Sep 17 00:00:00 2001 +From: Fuad Tabba +Date: Wed, 9 Jul 2025 11:59:43 +0100 +Subject: [PATCH 17/45] KVM: arm64: Enable host mapping of shared guest_memfd + memory + +Enable host userspace mmap support for guest_memfd-backed memory on +arm64. This change provides arm64 with the capability to map guest +memory at the host directly from guest_memfd: + +* Define kvm_arch_supports_gmem_mmap() for arm64: The + kvm_arch_supports_gmem_mmap() macro is defined for arm64 to be true if + CONFIG_KVM_GMEM_SUPPORTS_MMAP is enabled. For existing arm64 KVM VM + types that support guest_memfd, this enables them to use guest_memfd + with host userspace mappings. This provides a consistent behavior as + there are currently no arm64 CoCo VMs that rely on guest_memfd solely + for private, non-mappable memory. Future arm64 VM types can override + or restrict this behavior via the kvm_arch_supports_gmem_mmap() hook + if needed. + +* Select CONFIG_KVM_GMEM_SUPPORTS_MMAP in arm64 Kconfig. + +* Enforce KVM_MEMSLOT_GMEM_ONLY for guest_memfd on arm64: Compile and + runtime checks are added to ensure that if guest_memfd is enabled on + arm64, KVM_GMEM_SUPPORTS_MMAP must also be enabled. This means + guest_memfd-backed memory slots on arm64 are currently only supported + if they are intended for shared memory use cases (i.e., + kvm_memslot_is_gmem_only() is true). This design reflects the current + arm64 KVM ecosystem where guest_memfd is primarily being introduced + for VMs that support shared memory. + +Reviewed-by: James Houghton +Reviewed-by: Gavin Shan +Acked-by: David Hildenbrand +Signed-off-by: Fuad Tabba +--- + arch/arm64/include/asm/kvm_host.h | 4 ++++ + arch/arm64/kvm/Kconfig | 1 + + arch/arm64/kvm/mmu.c | 8 ++++++++ + 3 files changed, 13 insertions(+) + +diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h +index d27079968341..bd2af5470c66 100644 +--- a/arch/arm64/include/asm/kvm_host.h ++++ b/arch/arm64/include/asm/kvm_host.h +@@ -1675,5 +1675,9 @@ void compute_fgu(struct kvm *kvm, enum fgt_group_id fgt); + void get_reg_fixed_bits(struct kvm *kvm, enum vcpu_sysreg reg, u64 *res0, u64 *res1); + void check_feature_map(void); + ++#ifdef CONFIG_KVM_GMEM ++#define kvm_arch_supports_gmem(kvm) true ++#define kvm_arch_supports_gmem_mmap(kvm) IS_ENABLED(CONFIG_KVM_GMEM_SUPPORTS_MMAP) ++#endif + + #endif /* __ARM64_KVM_HOST_H__ */ +diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig +index 713248f240e0..28539479f083 100644 +--- a/arch/arm64/kvm/Kconfig ++++ b/arch/arm64/kvm/Kconfig +@@ -37,6 +37,7 @@ menuconfig KVM + select HAVE_KVM_VCPU_RUN_PID_CHANGE + select SCHED_INFO + select GUEST_PERF_EVENTS if PERF_EVENTS ++ select KVM_GMEM_SUPPORTS_MMAP + help + Support hosting virtualized guest machines. + +diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c +index 71f8b53683e7..b92ce4d9b4e0 100644 +--- a/arch/arm64/kvm/mmu.c ++++ b/arch/arm64/kvm/mmu.c +@@ -2274,6 +2274,14 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + if ((new->base_gfn + new->npages) > (kvm_phys_size(&kvm->arch.mmu) >> PAGE_SHIFT)) + return -EFAULT; + ++ /* ++ * Only support guest_memfd backed memslots with mappable memory, since ++ * there aren't any CoCo VMs that support only private memory on arm64. ++ */ ++ BUILD_BUG_ON(IS_ENABLED(CONFIG_KVM_GMEM) && !IS_ENABLED(CONFIG_KVM_GMEM_SUPPORTS_MMAP)); ++ if (kvm_slot_has_gmem(new) && !kvm_memslot_is_gmem_only(new)) ++ return -EINVAL; ++ + hva = new->userspace_addr; + reg_end = hva + (new->npages << PAGE_SHIFT); + +-- +2.49.0 + diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0017-KVM-Introduce-the-KVM-capability-KVM_CAP_GMEM_SHARED.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0018-KVM-Introduce-the-KVM-capability-KVM_CAP_GMEM_MMAP.patch similarity index 53% rename from resources/hiding_ci/linux_patches/05-mmap-support/0017-KVM-Introduce-the-KVM-capability-KVM_CAP_GMEM_SHARED.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0018-KVM-Introduce-the-KVM-capability-KVM_CAP_GMEM_MMAP.patch index 7d71be4e3f7..475bf1e6857 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0017-KVM-Introduce-the-KVM-capability-KVM_CAP_GMEM_SHARED.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0018-KVM-Introduce-the-KVM-capability-KVM_CAP_GMEM_MMAP.patch @@ -1,17 +1,19 @@ -From 1b14ab18d7a76d54667c1dc399348c36423d7570 Mon Sep 17 00:00:00 2001 +From 7bbe202f36cc3e670d47f353398f434063323169 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:28 +0100 -Subject: [PATCH 17/42] KVM: Introduce the KVM capability - KVM_CAP_GMEM_SHARED_MEM +Date: Wed, 9 Jul 2025 11:59:44 +0100 +Subject: [PATCH 18/45] KVM: Introduce the KVM capability KVM_CAP_GMEM_MMAP -This patch introduces the KVM capability KVM_CAP_GMEM_SHARED_MEM, which -indicates that guest_memfd supports shared memory (when enabled by the -flag). This support is limited to certain VM types, determined per -architecture. +Introduce the new KVM capability KVM_CAP_GMEM_MMAP. This capability +signals to userspace that a KVM instance supports host userspace mapping +of guest_memfd-backed memory. -This patch also updates the KVM documentation with details on the new -capability, flag, and other information about support for shared memory -in guest_memfd. +The availability of this capability is determined per architecture, and +its enablement for a specific guest_memfd instance is controlled by the +GUEST_MEMFD_FLAG_MMAP flag at creation time. + +Update the KVM API documentation to detail the KVM_CAP_GMEM_MMAP +capability, the associated GUEST_MEMFD_FLAG_MMAP, and provide essential +information regarding support for mmap in guest_memfd. Reviewed-by: David Hildenbrand Reviewed-by: Gavin Shan @@ -23,39 +25,39 @@ Signed-off-by: Fuad Tabba 3 files changed, 14 insertions(+) diff --git a/Documentation/virt/kvm/api.rst b/Documentation/virt/kvm/api.rst -index 9abf93ee5f65..0fe90d0a74b4 100644 +index 9abf93ee5f65..70261e189162 100644 --- a/Documentation/virt/kvm/api.rst +++ b/Documentation/virt/kvm/api.rst @@ -6407,6 +6407,15 @@ most one mapping per page, i.e. binding multiple memory regions to a single guest_memfd range is not allowed (any number of memory regions can be bound to a single guest_memfd file, but the bound ranges must not overlap). -+When the capability KVM_CAP_GMEM_SHARED_MEM is supported, the 'flags' field -+supports GUEST_MEMFD_FLAG_SUPPORT_SHARED. Setting this flag on guest_memfd -+creation enables mmap() and faulting of guest_memfd memory to host userspace. ++When the capability KVM_CAP_GMEM_MMAP is supported, the 'flags' field supports ++GUEST_MEMFD_FLAG_MMAP. Setting this flag on guest_memfd creation enables mmap() ++and faulting of guest_memfd memory to host userspace. + +When the KVM MMU performs a PFN lookup to service a guest fault and the backing -+guest_memfd has the GUEST_MEMFD_FLAG_SUPPORT_SHARED set, then the fault will -+always be consumed from guest_memfd, regardless of whether it is a shared or a -+private fault. ++guest_memfd has the GUEST_MEMFD_FLAG_MMAP set, then the fault will always be ++consumed from guest_memfd, regardless of whether it is a shared or a private ++fault. + See KVM_SET_USER_MEMORY_REGION2 for additional details. 4.143 KVM_PRE_FAULT_MEMORY diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h -index 954f0668130c..4fba730ec62b 100644 +index c71348db818f..cbf28237af79 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -956,6 +956,7 @@ struct kvm_enable_cap { #define KVM_CAP_ARM_EL2 240 #define KVM_CAP_ARM_EL2_E2H0 241 #define KVM_CAP_RISCV_MP_STATE_RESET 242 -+#define KVM_CAP_GMEM_SHARED_MEM 243 ++#define KVM_CAP_GMEM_MMAP 243 struct kvm_irq_routing_irqchip { __u32 irqchip; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c -index d41bcc6a78b0..441c9b53b876 100644 +index 81bb18fa8655..5463e81b08b9 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4913,6 +4913,10 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) @@ -63,9 +65,9 @@ index d41bcc6a78b0..441c9b53b876 100644 case KVM_CAP_GUEST_MEMFD: return !kvm || kvm_arch_supports_gmem(kvm); +#endif -+#ifdef CONFIG_KVM_GMEM_SHARED_MEM -+ case KVM_CAP_GMEM_SHARED_MEM: -+ return !kvm || kvm_arch_supports_gmem_shared_mem(kvm); ++#ifdef CONFIG_KVM_GMEM_SUPPORTS_MMAP ++ case KVM_CAP_GMEM_MMAP: ++ return !kvm || kvm_arch_supports_gmem_mmap(kvm); #endif default: break; diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0018-KVM-selftests-Don-t-use-hardcoded-page-sizes-in-gues.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0019-KVM-selftests-Do-not-use-hardcoded-page-sizes-in-gue.patch similarity index 80% rename from resources/hiding_ci/linux_patches/05-mmap-support/0018-KVM-selftests-Don-t-use-hardcoded-page-sizes-in-gues.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0019-KVM-selftests-Do-not-use-hardcoded-page-sizes-in-gue.patch index 6e86f9bc830..afc0e5e3c91 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0018-KVM-selftests-Don-t-use-hardcoded-page-sizes-in-gues.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0019-KVM-selftests-Do-not-use-hardcoded-page-sizes-in-gue.patch @@ -1,16 +1,21 @@ -From 5840c7c2ee0622e1206d29f8c48f469dce0d53ed Mon Sep 17 00:00:00 2001 +From 5ad1a2fce09c242511f3ce9de606016542a7c390 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:29 +0100 -Subject: [PATCH 18/42] KVM: selftests: Don't use hardcoded page sizes in +Date: Wed, 9 Jul 2025 11:59:45 +0100 +Subject: [PATCH 19/45] KVM: selftests: Do not use hardcoded page sizes in guest_memfd test -Using hardcoded page size values could cause the test to fail on systems -that have larger pages, e.g., arm64 with 64kB pages. Use getpagesize() -instead. +Update the guest_memfd_test selftest to use getpagesize() instead of +hardcoded 4KB page size values. -Also, build the guest_memfd selftest for arm64. +Using hardcoded page sizes can cause test failures on architectures or +systems configured with larger page sizes, such as arm64 with 64KB +pages. By dynamically querying the system's page size, the test becomes +more portable and robust across different environments. + +Additionally, build the guest_memfd_test selftest for arm64. Reviewed-by: David Hildenbrand +Reviewed-by: Shivank Garg Suggested-by: Gavin Shan Reviewed-by: Gavin Shan Signed-off-by: Fuad Tabba diff --git a/resources/hiding_ci/linux_patches/05-mmap-support/0019-KVM-selftests-guest_memfd-mmap-test-when-mapping-is-.patch b/resources/hiding_ci/linux_patches/05-mmap-support/0020-KVM-selftests-guest_memfd-mmap-test-when-mmap-is-sup.patch similarity index 76% rename from resources/hiding_ci/linux_patches/05-mmap-support/0019-KVM-selftests-guest_memfd-mmap-test-when-mapping-is-.patch rename to resources/hiding_ci/linux_patches/05-mmap-support/0020-KVM-selftests-guest_memfd-mmap-test-when-mmap-is-sup.patch index 012c9c9488d..c6657f50166 100644 --- a/resources/hiding_ci/linux_patches/05-mmap-support/0019-KVM-selftests-guest_memfd-mmap-test-when-mapping-is-.patch +++ b/resources/hiding_ci/linux_patches/05-mmap-support/0020-KVM-selftests-guest_memfd-mmap-test-when-mmap-is-sup.patch @@ -1,23 +1,53 @@ -From 79c7f768a4dcdea740277dd1b3dc8c9027e5339a Mon Sep 17 00:00:00 2001 +From 942e67ffcabf0218347c6e61a0656d58ac12f365 Mon Sep 17 00:00:00 2001 From: Fuad Tabba -Date: Wed, 11 Jun 2025 14:33:30 +0100 -Subject: [PATCH 19/42] KVM: selftests: guest_memfd mmap() test when mapping is - allowed +Date: Wed, 9 Jul 2025 11:59:46 +0100 +Subject: [PATCH 20/45] KVM: selftests: guest_memfd mmap() test when mmap is + supported -Expand the guest_memfd selftests to include testing mapping guest -memory for VM types that support it. +Expand the guest_memfd selftests to comprehensively test host userspace +mmap functionality for guest_memfd-backed memory when supported by the +VM type. + +Introduce new test cases to verify the following: + +* Successful mmap operations: Ensure that MAP_SHARED mappings succeed + when guest_memfd mmap is enabled. + +* Data integrity: Validate that data written to the mmap'd region is + correctly persistent and readable. + +* fallocate interaction: Test that fallocate(FALLOC_FL_PUNCH_HOLE) + correctly zeros out mapped pages. + +* Out-of-bounds access: Verify that accessing memory beyond the + guest_memfd's size correctly triggers a SIGBUS signal. + +* Unsupported mmap: Confirm that mmap attempts fail as expected when + guest_memfd mmap support is not enabled for the specific guest_memfd + instance or VM type. + +* Flag validity: Introduce test_vm_type_gmem_flag_validity() to + systematically test that only allowed guest_memfd creation flags are + accepted for different VM types (e.g., GUEST_MEMFD_FLAG_MMAP for + default VMs, no flags for CoCo VMs). + +The existing tests for guest_memfd creation (multiple instances, invalid +sizes), file read/write, file size, and invalid punch hole operations +are integrated into the new test_with_type() framework to allow testing +across different VM types. Reviewed-by: James Houghton Reviewed-by: Gavin Shan +Reviewed-by: Shivank Garg Co-developed-by: Ackerley Tng Signed-off-by: Ackerley Tng Signed-off-by: Fuad Tabba --- - .../testing/selftests/kvm/guest_memfd_test.c | 201 ++++++++++++++++-- - 1 file changed, 180 insertions(+), 21 deletions(-) + .../testing/selftests/kvm/guest_memfd_test.c | 197 ++++++++++++++++-- + 1 file changed, 176 insertions(+), 21 deletions(-) diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing/selftests/kvm/guest_memfd_test.c -index 341ba616cf55..5da2ed6277ac 100644 +index 341ba616cf55..1252e74fbb8f 100644 --- a/tools/testing/selftests/kvm/guest_memfd_test.c +++ b/tools/testing/selftests/kvm/guest_memfd_test.c @@ -13,6 +13,8 @@ @@ -45,7 +75,7 @@ index 341ba616cf55..5da2ed6277ac 100644 + TEST_ASSERT(mem == MAP_FAILED, "Copy-on-write not allowed by guest_memfd."); + + mem = mmap(NULL, total_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); -+ TEST_ASSERT(mem != MAP_FAILED, "mmap() for shared guest memory should succeed."); ++ TEST_ASSERT(mem != MAP_FAILED, "mmap() for guest_memfd should succeed."); + + memset(mem, val, total_size); + for (i = 0; i < total_size; i++) @@ -86,7 +116,7 @@ index 341ba616cf55..5da2ed6277ac 100644 + int ret; + + mem = mmap(NULL, map_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); -+ TEST_ASSERT(mem != MAP_FAILED, "mmap() for shared guest memory should succeed."); ++ TEST_ASSERT(mem != MAP_FAILED, "mmap() for guest_memfd should succeed."); + + sigaction(SIGBUS, &sa_new, &sa_old); + if (sigsetjmp(jmpbuf, 1) == 0) { @@ -146,7 +176,7 @@ index 341ba616cf55..5da2ed6277ac 100644 } static void test_create_guest_memfd_multiple(struct kvm_vm *vm) -@@ -171,30 +237,123 @@ static void test_create_guest_memfd_multiple(struct kvm_vm *vm) +@@ -171,30 +237,119 @@ static void test_create_guest_memfd_multiple(struct kvm_vm *vm) close(fd1); } @@ -244,13 +274,13 @@ index 341ba616cf55..5da2ed6277ac 100644 +{ + uint64_t non_coco_vm_valid_flags = 0; + -+ if (kvm_has_cap(KVM_CAP_GMEM_SHARED_MEM)) -+ non_coco_vm_valid_flags = GUEST_MEMFD_FLAG_SUPPORT_SHARED; ++ if (kvm_has_cap(KVM_CAP_GMEM_MMAP)) ++ non_coco_vm_valid_flags = GUEST_MEMFD_FLAG_MMAP; + + test_vm_type_gmem_flag_validity(VM_TYPE_DEFAULT, non_coco_vm_valid_flags); + +#ifdef __x86_64__ -+ test_vm_type_gmem_flag_validity(KVM_X86_SW_PROTECTED_VM, non_coco_vm_valid_flags); ++ test_vm_type_gmem_flag_validity(KVM_X86_SW_PROTECTED_VM, 0); + test_vm_type_gmem_flag_validity(KVM_X86_SEV_VM, 0); + test_vm_type_gmem_flag_validity(KVM_X86_SEV_ES_VM, 0); + test_vm_type_gmem_flag_validity(KVM_X86_SNP_VM, 0); @@ -265,17 +295,13 @@ index 341ba616cf55..5da2ed6277ac 100644 + test_gmem_flag_validity(); + + test_with_type(VM_TYPE_DEFAULT, 0, false); -+ if (kvm_has_cap(KVM_CAP_GMEM_SHARED_MEM)) { -+ test_with_type(VM_TYPE_DEFAULT, GUEST_MEMFD_FLAG_SUPPORT_SHARED, ++ if (kvm_has_cap(KVM_CAP_GMEM_MMAP)) { ++ test_with_type(VM_TYPE_DEFAULT, GUEST_MEMFD_FLAG_MMAP, + true); + } + +#ifdef __x86_64__ + test_with_type(KVM_X86_SW_PROTECTED_VM, 0, false); -+ if (kvm_has_cap(KVM_CAP_GMEM_SHARED_MEM)) { -+ test_with_type(KVM_X86_SW_PROTECTED_VM, -+ GUEST_MEMFD_FLAG_SUPPORT_SHARED, true); -+ } +#endif } -- diff --git a/resources/hiding_ci/linux_patches/10-direct-map-removal/0020-filemap-Pass-address_space-mapping-to-free_folio.patch b/resources/hiding_ci/linux_patches/10-direct-map-removal/0021-filemap-Pass-address_space-mapping-to-free_folio.patch similarity index 97% rename from resources/hiding_ci/linux_patches/10-direct-map-removal/0020-filemap-Pass-address_space-mapping-to-free_folio.patch rename to resources/hiding_ci/linux_patches/10-direct-map-removal/0021-filemap-Pass-address_space-mapping-to-free_folio.patch index a3f04233a99..53654d38c63 100644 --- a/resources/hiding_ci/linux_patches/10-direct-map-removal/0020-filemap-Pass-address_space-mapping-to-free_folio.patch +++ b/resources/hiding_ci/linux_patches/10-direct-map-removal/0021-filemap-Pass-address_space-mapping-to-free_folio.patch @@ -1,7 +1,7 @@ -From 98800ece9d818fa9cf08a16c16cd62bc472b569f Mon Sep 17 00:00:00 2001 +From dfd8fbdb2145de31f39d3a6e0a290e3c9b6a1bbe Mon Sep 17 00:00:00 2001 From: Elliot Berman Date: Fri, 22 Nov 2024 09:29:38 -0800 -Subject: [PATCH 20/42] filemap: Pass address_space mapping to ->free_folio() +Subject: [PATCH 21/45] filemap: Pass address_space mapping to ->free_folio() When guest_memfd removes memory from the host kernel's direct map, direct map entries must be restored before the memory is freed again. To @@ -110,7 +110,7 @@ index 08a6f372a352..14ac9ffc4431 100644 kfree(folio_detach_private(folio)); } diff --git a/include/linux/fs.h b/include/linux/fs.h -index b085f161ed22..218d0d620633 100644 +index 040c0036320f..9d7ff57794fa 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -457,7 +457,7 @@ struct address_space_operations { @@ -160,7 +160,7 @@ index bada249b9fb7..6af53c5096fc 100644 } EXPORT_SYMBOL_GPL(replace_page_cache_folio); diff --git a/mm/secretmem.c b/mm/secretmem.c -index 589b26c2d553..6eb3bbe34d08 100644 +index 9a11a38a6770..4d2d6c0e342f 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -152,7 +152,8 @@ static int secretmem_migrate_folio(struct address_space *mapping, @@ -196,7 +196,7 @@ index f8dfd2864bbf..e23e1a44b92c 100644 return 1; diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index ebdb2d8bf57a..dfb799d0cead 100644 +index d01bd7a2c2bd..0ac1c3a5a433 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -433,7 +433,8 @@ static int kvm_gmem_error_folio(struct address_space *mapping, struct folio *fol diff --git a/resources/hiding_ci/linux_patches/10-direct-map-removal/0021-arch-export-set_direct_map_valid_noflush-to-KVM-modu.patch b/resources/hiding_ci/linux_patches/10-direct-map-removal/0022-arch-export-set_direct_map_valid_noflush-to-KVM-modu.patch similarity index 96% rename from resources/hiding_ci/linux_patches/10-direct-map-removal/0021-arch-export-set_direct_map_valid_noflush-to-KVM-modu.patch rename to resources/hiding_ci/linux_patches/10-direct-map-removal/0022-arch-export-set_direct_map_valid_noflush-to-KVM-modu.patch index d300a1d7d00..24c8db19ff7 100644 --- a/resources/hiding_ci/linux_patches/10-direct-map-removal/0021-arch-export-set_direct_map_valid_noflush-to-KVM-modu.patch +++ b/resources/hiding_ci/linux_patches/10-direct-map-removal/0022-arch-export-set_direct_map_valid_noflush-to-KVM-modu.patch @@ -1,7 +1,7 @@ -From 6d909fb5883da3a6b752d28438d2497637b8e9db Mon Sep 17 00:00:00 2001 +From 7a5e5c1d8bb2fe2d28205e89070d55f21e965d8d Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Mon, 2 Jun 2025 12:06:10 +0100 -Subject: [PATCH 21/42] arch: export set_direct_map_valid_noflush to KVM module +Subject: [PATCH 22/45] arch: export set_direct_map_valid_noflush to KVM module Use the new per-module export functionality to allow KVM (and only KVM) access to set_direct_map_valid_noflush(). This allows guest_memfd to diff --git a/resources/hiding_ci/linux_patches/10-direct-map-removal/0022-mm-introduce-AS_NO_DIRECT_MAP.patch b/resources/hiding_ci/linux_patches/10-direct-map-removal/0023-mm-introduce-AS_NO_DIRECT_MAP.patch similarity index 93% rename from resources/hiding_ci/linux_patches/10-direct-map-removal/0022-mm-introduce-AS_NO_DIRECT_MAP.patch rename to resources/hiding_ci/linux_patches/10-direct-map-removal/0023-mm-introduce-AS_NO_DIRECT_MAP.patch index f7ca3c23a73..2c6286a4027 100644 --- a/resources/hiding_ci/linux_patches/10-direct-map-removal/0022-mm-introduce-AS_NO_DIRECT_MAP.patch +++ b/resources/hiding_ci/linux_patches/10-direct-map-removal/0023-mm-introduce-AS_NO_DIRECT_MAP.patch @@ -1,7 +1,7 @@ -From 958156f418ccaac8c55d7e290c4eae03fc2792c3 Mon Sep 17 00:00:00 2001 +From 77947852711525793cd470b1c1cae0b82ffc3cce Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Fri, 7 Feb 2025 11:16:06 +0000 -Subject: [PATCH 22/42] mm: introduce AS_NO_DIRECT_MAP +Subject: [PATCH 23/45] mm: introduce AS_NO_DIRECT_MAP Add AS_NO_DIRECT_MAP for mappings where direct map entries of folios are set to not present . Currently, mappings that match this description are @@ -120,7 +120,7 @@ index c4b0f376fb34..33f173a607ad 100644 r->folio = filemap_get_folio(r->file->f_mapping, file_off >> PAGE_SHIFT); diff --git a/mm/gup.c b/mm/gup.c -index e065a49842a8..0f0af9f23324 100644 +index 3c39cbbeebef..b8e2d868cb60 100644 --- a/mm/gup.c +++ b/mm/gup.c @@ -1276,7 +1276,7 @@ static int check_vma_flags(struct vm_area_struct *vma, unsigned long gup_flags) @@ -132,7 +132,7 @@ index e065a49842a8..0f0af9f23324 100644 return -EFAULT; if (write) { -@@ -2769,7 +2769,6 @@ static bool gup_fast_folio_allowed(struct folio *folio, unsigned int flags) +@@ -2775,7 +2775,6 @@ static bool gup_fast_folio_allowed(struct folio *folio, unsigned int flags) { bool reject_file_backed = false; struct address_space *mapping; @@ -140,7 +140,7 @@ index e065a49842a8..0f0af9f23324 100644 unsigned long mapping_flags; /* -@@ -2781,14 +2780,6 @@ static bool gup_fast_folio_allowed(struct folio *folio, unsigned int flags) +@@ -2787,14 +2786,6 @@ static bool gup_fast_folio_allowed(struct folio *folio, unsigned int flags) reject_file_backed = true; /* We hold a folio reference, so we can safely access folio fields. */ @@ -155,7 +155,7 @@ index e065a49842a8..0f0af9f23324 100644 if (WARN_ON_ONCE(folio_test_slab(folio))) return false; -@@ -2830,8 +2821,9 @@ static bool gup_fast_folio_allowed(struct folio *folio, unsigned int flags) +@@ -2836,8 +2827,9 @@ static bool gup_fast_folio_allowed(struct folio *folio, unsigned int flags) * At this point, we know the mapping is non-null and points to an * address_space object. */ @@ -180,7 +180,7 @@ index 3cb72b579ffd..6cde2a5073f0 100644 goto out; diff --git a/mm/secretmem.c b/mm/secretmem.c -index 6eb3bbe34d08..18986567fc0e 100644 +index 4d2d6c0e342f..d85c0225b7f4 100644 --- a/mm/secretmem.c +++ b/mm/secretmem.c @@ -136,11 +136,6 @@ static int secretmem_mmap_prepare(struct vm_area_desc *desc) @@ -195,7 +195,7 @@ index 6eb3bbe34d08..18986567fc0e 100644 static const struct file_operations secretmem_fops = { .release = secretmem_release, .mmap_prepare = secretmem_mmap_prepare, -@@ -215,6 +210,7 @@ static struct file *secretmem_file_create(unsigned long flags) +@@ -208,6 +203,7 @@ static struct file *secretmem_file_create(unsigned long flags) mapping_set_gfp_mask(inode->i_mapping, GFP_HIGHUSER); mapping_set_unevictable(inode->i_mapping); diff --git a/resources/hiding_ci/linux_patches/10-direct-map-removal/0023-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch b/resources/hiding_ci/linux_patches/10-direct-map-removal/0024-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch similarity index 92% rename from resources/hiding_ci/linux_patches/10-direct-map-removal/0023-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch rename to resources/hiding_ci/linux_patches/10-direct-map-removal/0024-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch index 52738b7c57e..eaa4f849e34 100644 --- a/resources/hiding_ci/linux_patches/10-direct-map-removal/0023-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch +++ b/resources/hiding_ci/linux_patches/10-direct-map-removal/0024-KVM-guest_memfd-Add-flag-to-remove-from-direct-map.patch @@ -1,7 +1,7 @@ -From 469cd9a1a5380aa110b6e20a7efab5ae8762d7d3 Mon Sep 17 00:00:00 2001 +From 9df5ae94f7773b773d1b22032a7a5e35ef377f8d Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Fri, 7 Feb 2025 14:33:01 +0000 -Subject: [PATCH 23/42] KVM: guest_memfd: Add flag to remove from direct map +Subject: [PATCH 24/45] KVM: guest_memfd: Add flag to remove from direct map Add KVM_GMEM_NO_DIRECT_MAP flag for KVM_CREATE_GUEST_MEMFD() ioctl. When set, guest_memfd folios will be removed from the direct map after @@ -56,7 +56,7 @@ Signed-off-by: Patrick Roy 5 files changed, 50 insertions(+), 5 deletions(-) diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h -index 678e7b93bb01..27490e8ae9f6 100644 +index bd2af5470c66..ee2324c971c9 100644 --- a/arch/arm64/include/asm/kvm_host.h +++ b/arch/arm64/include/asm/kvm_host.h @@ -19,6 +19,7 @@ @@ -70,7 +70,7 @@ index 678e7b93bb01..27490e8ae9f6 100644 @@ -1678,6 +1679,15 @@ void check_feature_map(void); #ifdef CONFIG_KVM_GMEM #define kvm_arch_supports_gmem(kvm) true - #define kvm_arch_supports_gmem_shared_mem(kvm) IS_ENABLED(CONFIG_KVM_GMEM_SHARED_MEM) + #define kvm_arch_supports_gmem_mmap(kvm) IS_ENABLED(CONFIG_KVM_GMEM_SUPPORTS_MMAP) -#endif + +static inline bool kvm_arch_gmem_supports_no_direct_map(void) { @@ -85,7 +85,7 @@ index 678e7b93bb01..27490e8ae9f6 100644 #endif /* __ARM64_KVM_HOST_H__ */ diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 58d7761c2a90..1ad1d7f4ac6e 100644 +index 662271314778..7dc9190d2fef 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -36,6 +36,7 @@ @@ -96,7 +96,7 @@ index 58d7761c2a90..1ad1d7f4ac6e 100644 #include #include -@@ -743,6 +744,12 @@ static inline bool kvm_arch_supports_gmem_shared_mem(struct kvm *kvm) +@@ -754,6 +755,12 @@ static inline bool kvm_arch_supports_gmem_mmap(struct kvm *kvm) } #endif @@ -110,13 +110,13 @@ index 58d7761c2a90..1ad1d7f4ac6e 100644 static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) { diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h -index 4fba730ec62b..cfb99bfd496d 100644 +index cbf28237af79..edaba6966cad 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -957,6 +957,7 @@ struct kvm_enable_cap { #define KVM_CAP_ARM_EL2_E2H0 241 #define KVM_CAP_RISCV_MP_STATE_RESET 242 - #define KVM_CAP_GMEM_SHARED_MEM 243 + #define KVM_CAP_GMEM_MMAP 243 +#define KVM_CAP_GMEM_NO_DIRECT_MAP 244 struct kvm_irq_routing_irqchip { @@ -124,13 +124,13 @@ index 4fba730ec62b..cfb99bfd496d 100644 @@ -1594,6 +1595,7 @@ struct kvm_memory_attributes { #define KVM_CREATE_GUEST_MEMFD _IOWR(KVMIO, 0xd4, struct kvm_create_guest_memfd) - #define GUEST_MEMFD_FLAG_SUPPORT_SHARED (1ULL << 0) + #define GUEST_MEMFD_FLAG_MMAP (1ULL << 0) +#define GUEST_MEMFD_FLAG_NO_DIRECT_MAP (1ULL << 1) struct kvm_create_guest_memfd { __u64 size; diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index dfb799d0cead..99e1b20a9977 100644 +index 0ac1c3a5a433..d70ee66bb96d 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -4,6 +4,7 @@ @@ -205,8 +205,8 @@ index dfb799d0cead..99e1b20a9977 100644 gmem->kvm = kvm; xa_init(&gmem->bindings); @@ -537,6 +555,9 @@ int kvm_gmem_create(struct kvm *kvm, struct kvm_create_guest_memfd *args) - if (kvm_arch_supports_gmem_shared_mem(kvm)) - valid_flags |= GUEST_MEMFD_FLAG_SUPPORT_SHARED; + if (kvm_arch_supports_gmem_mmap(kvm)) + valid_flags |= GUEST_MEMFD_FLAG_MMAP; + if (kvm_arch_gmem_supports_no_direct_map()) + valid_flags |= GUEST_MEMFD_FLAG_NO_DIRECT_MAP; @@ -215,7 +215,7 @@ index dfb799d0cead..99e1b20a9977 100644 return -EINVAL; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c -index 441c9b53b876..d99d820a5a29 100644 +index 5463e81b08b9..a0d14659ee2c 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -65,6 +65,7 @@ diff --git a/resources/hiding_ci/linux_patches/11-kvm-clock/0024-de-gpc-ify-kvm-clock.patch b/resources/hiding_ci/linux_patches/11-kvm-clock/0025-de-gpc-ify-kvm-clock.patch similarity index 96% rename from resources/hiding_ci/linux_patches/11-kvm-clock/0024-de-gpc-ify-kvm-clock.patch rename to resources/hiding_ci/linux_patches/11-kvm-clock/0025-de-gpc-ify-kvm-clock.patch index 569fede2eb8..91c592adcf1 100644 --- a/resources/hiding_ci/linux_patches/11-kvm-clock/0024-de-gpc-ify-kvm-clock.patch +++ b/resources/hiding_ci/linux_patches/11-kvm-clock/0025-de-gpc-ify-kvm-clock.patch @@ -1,7 +1,7 @@ -From fbc945f79a95e653951563d360762698a0c2f077 Mon Sep 17 00:00:00 2001 +From 34c70a6d6eb856050b755c1db905ae8fcc34309d Mon Sep 17 00:00:00 2001 From: Patrick Roy Date: Tue, 3 Jun 2025 13:57:15 +0100 -Subject: [PATCH 24/42] de-gpc-ify kvm-clock +Subject: [PATCH 25/45] de-gpc-ify kvm-clock Signed-off-by: Patrick Roy --- @@ -10,7 +10,7 @@ Signed-off-by: Patrick Roy 2 files changed, 15 insertions(+), 34 deletions(-) diff --git a/arch/x86/include/asm/kvm_host.h b/arch/x86/include/asm/kvm_host.h -index 7b9ccdd99f32..d4130899bd08 100644 +index 4c89feaa1910..e709a54fb935 100644 --- a/arch/x86/include/asm/kvm_host.h +++ b/arch/x86/include/asm/kvm_host.h @@ -924,7 +924,7 @@ struct kvm_vcpu_arch { @@ -23,7 +23,7 @@ index 7b9ccdd99f32..d4130899bd08 100644 bool pvclock_set_guest_stopped_request; diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index e21f5f2fe059..03f1a5d6b2b0 100644 +index 17c655e5716e..6f3bd41f048d 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -2349,12 +2349,9 @@ static void kvm_write_system_time(struct kvm_vcpu *vcpu, gpa_t system_time, diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0001-KVM-Add-KVM_MEM_USERFAULT-memslot-flag-and-bitmap.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0026-KVM-Add-KVM_MEM_USERFAULT-memslot-flag-and-bitmap.patch similarity index 90% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0001-KVM-Add-KVM_MEM_USERFAULT-memslot-flag-and-bitmap.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0026-KVM-Add-KVM_MEM_USERFAULT-memslot-flag-and-bitmap.patch index a4b9c3c88fa..b4d78992eeb 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0001-KVM-Add-KVM_MEM_USERFAULT-memslot-flag-and-bitmap.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0026-KVM-Add-KVM_MEM_USERFAULT-memslot-flag-and-bitmap.patch @@ -1,7 +1,7 @@ -From 7da9dbce26d357193434938cf5e6095c01cdd727 Mon Sep 17 00:00:00 2001 +From fca809bc76438579b831ecaef7b56731888b5c2c Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:17 +0000 -Subject: [PATCH 01/12] KVM: Add KVM_MEM_USERFAULT memslot flag and bitmap +Subject: [PATCH 26/45] KVM: Add KVM_MEM_USERFAULT memslot flag and bitmap Use one of the 14 reserved u64s in struct kvm_userspace_memory_region2 for the user to provide `userfault_bitmap`. @@ -20,7 +20,7 @@ Signed-off-by: James Houghton 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 1ad1d7f4ac6e..0d7e46b00886 100644 +index 7dc9190d2fef..ad37db1bed39 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h @@ -599,6 +599,7 @@ struct kvm_memory_slot { @@ -31,7 +31,7 @@ index 1ad1d7f4ac6e..0d7e46b00886 100644 u32 flags; short id; u16 as_id; -@@ -757,6 +758,11 @@ static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) +@@ -768,6 +769,11 @@ static inline bool kvm_arch_has_readonly_mem(struct kvm *kvm) } #endif @@ -43,7 +43,7 @@ index 1ad1d7f4ac6e..0d7e46b00886 100644 struct kvm_memslots { u64 generation; atomic_long_t last_used_slot; -@@ -2663,4 +2669,12 @@ static inline int kvm_enable_virtualization(void) { return 0; } +@@ -2649,4 +2655,12 @@ static inline int kvm_enable_virtualization(void) { return 0; } static inline void kvm_disable_virtualization(void) { } #endif @@ -57,7 +57,7 @@ index 1ad1d7f4ac6e..0d7e46b00886 100644 + #endif diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h -index cfb99bfd496d..24d27bcc5c51 100644 +index edaba6966cad..eea58b3d99e8 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -40,7 +40,8 @@ struct kvm_userspace_memory_region2 { @@ -79,18 +79,18 @@ index cfb99bfd496d..24d27bcc5c51 100644 /* for KVM_IRQ_LINE */ struct kvm_irq_level { diff --git a/virt/kvm/Kconfig b/virt/kvm/Kconfig -index e90884f74404..9e45d72f8057 100644 +index fa4acbedb953..fd46bc7d194a 100644 --- a/virt/kvm/Kconfig +++ b/virt/kvm/Kconfig @@ -132,3 +132,6 @@ config HAVE_KVM_ARCH_GMEM_INVALIDATE - config KVM_GMEM_SHARED_MEM + config KVM_GMEM_SUPPORTS_MMAP select KVM_GMEM bool + +config HAVE_KVM_USERFAULT + bool diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c -index d99d820a5a29..c00094348f80 100644 +index a0d14659ee2c..fe203a518ddb 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -1605,6 +1605,9 @@ static int check_memory_region_flags(struct kvm *kvm, diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0002-KVM-Add-KVM_MEMORY_EXIT_FLAG_USERFAULT.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0027-KVM-Add-KVM_MEMORY_EXIT_FLAG_USERFAULT.patch similarity index 81% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0002-KVM-Add-KVM_MEMORY_EXIT_FLAG_USERFAULT.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0027-KVM-Add-KVM_MEMORY_EXIT_FLAG_USERFAULT.patch index 9367b6c9350..22e3795c74a 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0002-KVM-Add-KVM_MEMORY_EXIT_FLAG_USERFAULT.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0027-KVM-Add-KVM_MEMORY_EXIT_FLAG_USERFAULT.patch @@ -1,7 +1,7 @@ -From 783b11ddc87a63b9299b67b679c37bc5d58f9922 Mon Sep 17 00:00:00 2001 +From e592af4f9956ac0ee72e2d7472da4cea5d873408 Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:18 +0000 -Subject: [PATCH 02/12] KVM: Add KVM_MEMORY_EXIT_FLAG_USERFAULT +Subject: [PATCH 27/45] KVM: Add KVM_MEMORY_EXIT_FLAG_USERFAULT This flag is used for vCPU memory faults caused by KVM Userfault; i.e., the bit in `userfault_bitmap` corresponding to the faulting gfn was set. @@ -12,7 +12,7 @@ Signed-off-by: James Houghton 1 file changed, 1 insertion(+) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h -index 24d27bcc5c51..4ce2282f7a18 100644 +index eea58b3d99e8..c75b7c183140 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -446,6 +446,7 @@ struct kvm_run { diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0003-KVM-Allow-late-setting-of-KVM_MEM_USERFAULT-on-guest.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0028-KVM-Allow-late-setting-of-KVM_MEM_USERFAULT-on-guest.patch similarity index 92% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0003-KVM-Allow-late-setting-of-KVM_MEM_USERFAULT-on-guest.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0028-KVM-Allow-late-setting-of-KVM_MEM_USERFAULT-on-guest.patch index 574e1664c8c..6ff5d5fcde5 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0003-KVM-Allow-late-setting-of-KVM_MEM_USERFAULT-on-guest.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0028-KVM-Allow-late-setting-of-KVM_MEM_USERFAULT-on-guest.patch @@ -1,7 +1,7 @@ -From 852a599e29590c3339191006bb15b6396dbda0cb Mon Sep 17 00:00:00 2001 +From 9978794ee7f6b3130f4e82daca38c1b073e35828 Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:19 +0000 -Subject: [PATCH 03/12] KVM: Allow late setting of KVM_MEM_USERFAULT on +Subject: [PATCH 28/45] KVM: Allow late setting of KVM_MEM_USERFAULT on guest_memfd memslot Currently guest_memfd memslots can only be deleted. Slightly change the @@ -14,7 +14,7 @@ Signed-off-by: James Houghton 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c -index c00094348f80..2208033d5dd4 100644 +index fe203a518ddb..bd9e5fb6cc80 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -2081,9 +2081,6 @@ static int kvm_set_memory_region(struct kvm *kvm, diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0004-KVM-x86-mmu-Add-support-for-KVM_MEM_USERFAULT.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0029-KVM-x86-mmu-Add-support-for-KVM_MEM_USERFAULT.patch similarity index 83% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0004-KVM-x86-mmu-Add-support-for-KVM_MEM_USERFAULT.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0029-KVM-x86-mmu-Add-support-for-KVM_MEM_USERFAULT.patch index 0c785643479..bf41c27334b 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0004-KVM-x86-mmu-Add-support-for-KVM_MEM_USERFAULT.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0029-KVM-x86-mmu-Add-support-for-KVM_MEM_USERFAULT.patch @@ -1,7 +1,7 @@ -From c2287b66f61a55e2f2eaeabb1fbe52a020f5dde1 Mon Sep 17 00:00:00 2001 +From fbe3a7384aa789c32aa1aa034ece2180a7b970ad Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:21 +0000 -Subject: [PATCH 04/12] KVM: x86/mmu: Add support for KVM_MEM_USERFAULT +Subject: [PATCH 29/45] KVM: x86/mmu: Add support for KVM_MEM_USERFAULT Adhering to the requirements of KVM Userfault: @@ -21,14 +21,14 @@ Signed-off-by: James Houghton --- arch/arm64/kvm/mmu.c | 2 +- arch/x86/kvm/Kconfig | 1 + - arch/x86/kvm/mmu/mmu.c | 15 ++++++++++++++ + arch/x86/kvm/mmu/mmu.c | 12 +++++++++++ arch/x86/kvm/mmu/mmu_internal.h | 20 +++++++++++++++--- arch/x86/kvm/x86.c | 36 ++++++++++++++++++++++++--------- include/linux/kvm_host.h | 5 ++++- - 6 files changed, 64 insertions(+), 15 deletions(-) + 6 files changed, 61 insertions(+), 15 deletions(-) diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c -index 55ac03f277e0..c673bbafc1e3 100644 +index b92ce4d9b4e0..dae1f3fea842 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1554,7 +1554,7 @@ static int gmem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, @@ -41,32 +41,22 @@ index 55ac03f277e0..c673bbafc1e3 100644 } diff --git a/arch/x86/kvm/Kconfig b/arch/x86/kvm/Kconfig -index 29845a286430..1139635d4e03 100644 +index 239637b663dc..1f3e359a58d0 100644 --- a/arch/x86/kvm/Kconfig +++ b/arch/x86/kvm/Kconfig @@ -49,6 +49,7 @@ config KVM_X86 select KVM_GENERIC_GMEM_POPULATE if KVM_SW_PROTECTED_VM - select KVM_GMEM_SHARED_MEM if KVM_SW_PROTECTED_VM + select KVM_GMEM_SUPPORTS_MMAP select KVM_WERROR if WERROR + select HAVE_KVM_USERFAULT config KVM tristate "Kernel-based Virtual Machine (KVM) support" diff --git a/arch/x86/kvm/mmu/mmu.c b/arch/x86/kvm/mmu/mmu.c -index b071b9afb8ad..9e3d8e05dd30 100644 +index cc4cdfea343b..bd19b2f2acc1 100644 --- a/arch/x86/kvm/mmu/mmu.c +++ b/arch/x86/kvm/mmu/mmu.c -@@ -4504,6 +4504,9 @@ static u8 kvm_max_level_for_fault_and_order(struct kvm *kvm, - if (max_level == PG_LEVEL_4K) - return PG_LEVEL_4K; - -+ if (kvm_memslot_userfault(fault->slot)) -+ return PG_LEVEL_4K; -+ - max_level = min(kvm_max_level_for_order(order), max_level); - if (max_level == PG_LEVEL_4K) - return PG_LEVEL_4K; -@@ -4552,6 +4555,18 @@ static int __kvm_mmu_faultin_pfn(struct kvm_vcpu *vcpu, +@@ -4546,6 +4546,18 @@ static int __kvm_mmu_faultin_pfn(struct kvm_vcpu *vcpu, struct kvm_page_fault *fault) { unsigned int foll = fault->write ? FOLL_WRITE : 0; @@ -120,10 +110,10 @@ index db8f33e4de62..84e4bb34abed 100644 static inline int kvm_mmu_do_page_fault(struct kvm_vcpu *vcpu, gpa_t cr2_or_gpa, diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c -index 03f1a5d6b2b0..e0c62bb9b105 100644 +index 6f3bd41f048d..947980f6c337 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c -@@ -13133,12 +13133,36 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm, +@@ -13134,12 +13134,36 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm, u32 new_flags = new ? new->flags : 0; bool log_dirty_pages = new_flags & KVM_MEM_LOG_DIRTY_PAGES; @@ -162,7 +152,7 @@ index 03f1a5d6b2b0..e0c62bb9b105 100644 /* * Nothing more to do for RO slots (which can't be dirtied and can't be -@@ -13158,14 +13182,6 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm, +@@ -13159,14 +13183,6 @@ static void kvm_mmu_slot_apply_flags(struct kvm *kvm, if ((change != KVM_MR_FLAGS_ONLY) || (new_flags & KVM_MEM_READONLY)) return; @@ -178,10 +168,10 @@ index 03f1a5d6b2b0..e0c62bb9b105 100644 /* * Recover huge page mappings in the slot now that dirty logging diff --git a/include/linux/kvm_host.h b/include/linux/kvm_host.h -index 0d7e46b00886..a2341ddbffb9 100644 +index ad37db1bed39..fb9cdfe3a2cd 100644 --- a/include/linux/kvm_host.h +++ b/include/linux/kvm_host.h -@@ -2527,7 +2527,8 @@ static inline void kvm_account_pgtable_pages(void *virt, int nr) +@@ -2538,7 +2538,8 @@ static inline void kvm_account_pgtable_pages(void *virt, int nr) static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu, gpa_t gpa, gpa_t size, bool is_write, bool is_exec, @@ -191,7 +181,7 @@ index 0d7e46b00886..a2341ddbffb9 100644 { vcpu->run->exit_reason = KVM_EXIT_MEMORY_FAULT; vcpu->run->memory_fault.gpa = gpa; -@@ -2537,6 +2538,8 @@ static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu, +@@ -2548,6 +2549,8 @@ static inline void kvm_prepare_memory_fault_exit(struct kvm_vcpu *vcpu, vcpu->run->memory_fault.flags = 0; if (is_private) vcpu->run->memory_fault.flags |= KVM_MEMORY_EXIT_FLAG_PRIVATE; @@ -199,7 +189,7 @@ index 0d7e46b00886..a2341ddbffb9 100644 + vcpu->run->memory_fault.flags |= KVM_MEMORY_EXIT_FLAG_USERFAULT; } - static inline bool kvm_gmem_memslot_supports_shared(const struct kvm_memory_slot *slot) + static inline bool kvm_memslot_is_gmem_only(const struct kvm_memory_slot *slot) -- 2.49.0 diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0005-KVM-Advertise-KVM_CAP_USERFAULT-in-KVM_CHECK_EXTENSI.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0030-KVM-Advertise-KVM_CAP_USERFAULT-in-KVM_CHECK_EXTENSI.patch similarity index 68% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0005-KVM-Advertise-KVM_CAP_USERFAULT-in-KVM_CHECK_EXTENSI.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0030-KVM-Advertise-KVM_CAP_USERFAULT-in-KVM_CHECK_EXTENSI.patch index a7e5e2d567f..86e1a03f343 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0005-KVM-Advertise-KVM_CAP_USERFAULT-in-KVM_CHECK_EXTENSI.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0030-KVM-Advertise-KVM_CAP_USERFAULT-in-KVM_CHECK_EXTENSI.patch @@ -1,7 +1,7 @@ -From 24ebc5c5026700260ff0a69cad25f0c1454dbc10 Mon Sep 17 00:00:00 2001 +From e8911baf94b5da0d0aa4da2fcea758ea7c61b24d Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:20 +0000 -Subject: [PATCH 05/12] KVM: Advertise KVM_CAP_USERFAULT in KVM_CHECK_EXTENSION +Subject: [PATCH 30/45] KVM: Advertise KVM_CAP_USERFAULT in KVM_CHECK_EXTENSION Advertise support for KVM_CAP_USERFAULT when kvm_has_userfault() returns true. Currently this is merely IS_ENABLED(CONFIG_HAVE_KVM_USERFAULT), so @@ -14,29 +14,29 @@ Signed-off-by: James Houghton 2 files changed, 5 insertions(+) diff --git a/include/uapi/linux/kvm.h b/include/uapi/linux/kvm.h -index 4ce2282f7a18..1c023deb54d7 100644 +index c75b7c183140..f3f6de7c33d2 100644 --- a/include/uapi/linux/kvm.h +++ b/include/uapi/linux/kvm.h @@ -961,6 +961,7 @@ struct kvm_enable_cap { #define KVM_CAP_RISCV_MP_STATE_RESET 242 - #define KVM_CAP_GMEM_SHARED_MEM 243 + #define KVM_CAP_GMEM_MMAP 243 #define KVM_CAP_GMEM_NO_DIRECT_MAP 244 +#define KVM_CAP_USERFAULT 245 struct kvm_irq_routing_irqchip { __u32 irqchip; diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c -index 2208033d5dd4..b224f167aeac 100644 +index bd9e5fb6cc80..94c8799ba4c3 100644 --- a/virt/kvm/kvm_main.c +++ b/virt/kvm/kvm_main.c @@ -4941,6 +4941,10 @@ static int kvm_vm_ioctl_check_extension_generic(struct kvm *kvm, long arg) - #ifdef CONFIG_KVM_GMEM_SHARED_MEM - case KVM_CAP_GMEM_SHARED_MEM: - return !kvm || kvm_arch_supports_gmem_shared_mem(kvm); + #ifdef CONFIG_KVM_GMEM_SUPPORTS_MMAP + case KVM_CAP_GMEM_MMAP: + return !kvm || kvm_arch_supports_gmem_mmap(kvm); +#endif -+#ifdef CONFIG_KVM_HAVE_USERFAULT -+ case KVM_CAP_USERFAULT: -+ return kvm_has_userfault(kvm); ++#ifdef CONFIG_HAVE_KVM_USERFAULT ++ case KVM_CAP_USERFAULT: ++ return kvm_has_userfault(kvm); #endif default: break; diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0006-KVM-arm64-Add-support-for-KVM_MEM_USERFAULT.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0031-KVM-arm64-Add-support-for-KVM_MEM_USERFAULT.patch similarity index 92% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0006-KVM-arm64-Add-support-for-KVM_MEM_USERFAULT.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0031-KVM-arm64-Add-support-for-KVM_MEM_USERFAULT.patch index 10f794efe82..21b1342ea1f 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0006-KVM-arm64-Add-support-for-KVM_MEM_USERFAULT.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0031-KVM-arm64-Add-support-for-KVM_MEM_USERFAULT.patch @@ -1,7 +1,7 @@ -From 9dfa044aa41bcf6f11934379fbc20cdcfe568b3b Mon Sep 17 00:00:00 2001 +From 17eb3696822641bdb78a7a75f135b28d6399deff Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:22 +0000 -Subject: [PATCH 06/12] KVM: arm64: Add support for KVM_MEM_USERFAULT +Subject: [PATCH 31/45] KVM: arm64: Add support for KVM_MEM_USERFAULT Adhering to the requirements of KVM Userfault: 1. When it is toggled on, zap the second stage with @@ -19,19 +19,19 @@ Signed-off-by: James Houghton 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/arch/arm64/kvm/Kconfig b/arch/arm64/kvm/Kconfig -index 87120d46919a..2b74fb15fcde 100644 +index 28539479f083..1eb76db26f28 100644 --- a/arch/arm64/kvm/Kconfig +++ b/arch/arm64/kvm/Kconfig @@ -38,6 +38,7 @@ menuconfig KVM select SCHED_INFO select GUEST_PERF_EVENTS if PERF_EVENTS - select KVM_GMEM_SHARED_MEM + select KVM_GMEM_SUPPORTS_MMAP + select HAVE_KVM_USERFAULT help Support hosting virtualized guest machines. diff --git a/arch/arm64/kvm/mmu.c b/arch/arm64/kvm/mmu.c -index c673bbafc1e3..1213bb84197d 100644 +index dae1f3fea842..f122c3786525 100644 --- a/arch/arm64/kvm/mmu.c +++ b/arch/arm64/kvm/mmu.c @@ -1551,6 +1551,13 @@ static int gmem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa, diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0007-KVM-selftests-Fix-vm_mem_region_set_flags-docstring.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0032-KVM-selftests-Fix-vm_mem_region_set_flags-docstring.patch similarity index 86% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0007-KVM-selftests-Fix-vm_mem_region_set_flags-docstring.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0032-KVM-selftests-Fix-vm_mem_region_set_flags-docstring.patch index 5e1835a9f67..fbfc3075bca 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0007-KVM-selftests-Fix-vm_mem_region_set_flags-docstring.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0032-KVM-selftests-Fix-vm_mem_region_set_flags-docstring.patch @@ -1,7 +1,7 @@ -From 4b29cd637ae9d9b76c22ad9d9859723a27f32ee5 Mon Sep 17 00:00:00 2001 +From 301f08c231f8643eae8dbbb8106492cc3807c0fe Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:23 +0000 -Subject: [PATCH 07/12] KVM: selftests: Fix vm_mem_region_set_flags docstring +Subject: [PATCH 32/45] KVM: selftests: Fix vm_mem_region_set_flags docstring `flags` is what region->region.flags gets set to. diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0008-KVM-selftests-Fix-prefault_mem-logic.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0033-KVM-selftests-Fix-prefault_mem-logic.patch similarity index 91% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0008-KVM-selftests-Fix-prefault_mem-logic.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0033-KVM-selftests-Fix-prefault_mem-logic.patch index 8223e278efd..bdc0aa4d245 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0008-KVM-selftests-Fix-prefault_mem-logic.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0033-KVM-selftests-Fix-prefault_mem-logic.patch @@ -1,7 +1,7 @@ -From f9ac1ed774dd6f712780b694dfd3cd3fca108ba6 Mon Sep 17 00:00:00 2001 +From 8d6b56ab8dd935c34063b88bde731a95c234357b Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:24 +0000 -Subject: [PATCH 08/12] KVM: selftests: Fix prefault_mem logic +Subject: [PATCH 33/45] KVM: selftests: Fix prefault_mem logic The previous logic didn't handle the case where memory was partitioned AND we were using a single userfaultfd. It would only prefault the first diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0009-KVM-selftests-Add-va_start-end-into-uffd_desc.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0034-KVM-selftests-Add-va_start-end-into-uffd_desc.patch similarity index 92% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0009-KVM-selftests-Add-va_start-end-into-uffd_desc.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0034-KVM-selftests-Add-va_start-end-into-uffd_desc.patch index 6c9e983c94e..a61aafdd0ce 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0009-KVM-selftests-Add-va_start-end-into-uffd_desc.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0034-KVM-selftests-Add-va_start-end-into-uffd_desc.patch @@ -1,7 +1,7 @@ -From 9ba5bb07f565a05b1f3692db4efbc6c934064cee Mon Sep 17 00:00:00 2001 +From 297809c9cd184698d1b92da1ece0ab9cd36cbfca Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:25 +0000 -Subject: [PATCH 09/12] KVM: selftests: Add va_start/end into uffd_desc +Subject: [PATCH 34/45] KVM: selftests: Add va_start/end into uffd_desc This will be used for the self-test to look up which userfaultfd we should be using when handling a KVM Userfault (in the event KVM diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0010-KVM-selftests-Inform-set_memory_region_test-of-KVM_M.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0035-KVM-selftests-Inform-set_memory_region_test-of-KVM_M.patch similarity index 88% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0010-KVM-selftests-Inform-set_memory_region_test-of-KVM_M.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0035-KVM-selftests-Inform-set_memory_region_test-of-KVM_M.patch index 2ec812f076a..37636476ee8 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0010-KVM-selftests-Inform-set_memory_region_test-of-KVM_M.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0035-KVM-selftests-Inform-set_memory_region_test-of-KVM_M.patch @@ -1,7 +1,7 @@ -From 5aa2c3386b0569737b0a0adda1fc2e22cf7e5a84 Mon Sep 17 00:00:00 2001 +From eadccd3481d3c5eff60143480be9076a1c8b57bb Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:27 +0000 -Subject: [PATCH 10/12] KVM: selftests: Inform set_memory_region_test of +Subject: [PATCH 35/45] KVM: selftests: Inform set_memory_region_test of KVM_MEM_USERFAULT The KVM_MEM_USERFAULT flag is supported iff KVM_CAP_USERFAULT is diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0011-KVM-selftests-Add-KVM-Userfault-mode-to-demand_pagin.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0036-KVM-selftests-Add-KVM-Userfault-mode-to-demand_pagin.patch similarity index 99% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0011-KVM-selftests-Add-KVM-Userfault-mode-to-demand_pagin.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0036-KVM-selftests-Add-KVM-Userfault-mode-to-demand_pagin.patch index dd7f106daa4..fc8edf80e62 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0011-KVM-selftests-Add-KVM-Userfault-mode-to-demand_pagin.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0036-KVM-selftests-Add-KVM-Userfault-mode-to-demand_pagin.patch @@ -1,7 +1,7 @@ -From 67a2c0276b1898f0fba9c3e6eccc07feaaf2d20d Mon Sep 17 00:00:00 2001 +From 24eda5ec46fce47d5f4aec35fcf1919b3ee1eee8 Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:26 +0000 -Subject: [PATCH 11/12] KVM: selftests: Add KVM Userfault mode to +Subject: [PATCH 36/45] KVM: selftests: Add KVM Userfault mode to demand_paging_test Add a way for the KVM_RUN loop to handle -EFAULT exits when they are for diff --git a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0012-KVM-selftests-Add-KVM_MEM_USERFAULT-guest_memfd-togg.patch b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0037-KVM-selftests-Add-KVM_MEM_USERFAULT-guest_memfd-togg.patch similarity index 94% rename from resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0012-KVM-selftests-Add-KVM_MEM_USERFAULT-guest_memfd-togg.patch rename to resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0037-KVM-selftests-Add-KVM_MEM_USERFAULT-guest_memfd-togg.patch index 01e26d8036a..38de0d24699 100644 --- a/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0012-KVM-selftests-Add-KVM_MEM_USERFAULT-guest_memfd-togg.patch +++ b/resources/hiding_ci/linux_patches/15-kvm-mem-userfault/0037-KVM-selftests-Add-KVM_MEM_USERFAULT-guest_memfd-togg.patch @@ -1,7 +1,7 @@ -From eed010571ed963539440319eace2395b47b2b4a6 Mon Sep 17 00:00:00 2001 +From de25686b2ed59bc7e2269d06cfa17649b8b3c50e Mon Sep 17 00:00:00 2001 From: James Houghton Date: Thu, 9 Jan 2025 20:49:28 +0000 -Subject: [PATCH 12/12] KVM: selftests: Add KVM_MEM_USERFAULT + guest_memfd +Subject: [PATCH 37/45] KVM: selftests: Add KVM_MEM_USERFAULT + guest_memfd toggle tests Make sure KVM_MEM_USERFAULT can be toggled on and off for diff --git a/resources/hiding_ci/linux_patches/20-gmem-write/0037-KVM-guest_memfd-add-generic-population-via-write.patch b/resources/hiding_ci/linux_patches/20-gmem-write/0038-KVM-guest_memfd-add-generic-population-via-write.patch similarity index 84% rename from resources/hiding_ci/linux_patches/20-gmem-write/0037-KVM-guest_memfd-add-generic-population-via-write.patch rename to resources/hiding_ci/linux_patches/20-gmem-write/0038-KVM-guest_memfd-add-generic-population-via-write.patch index daad8db5d25..fee92b61af6 100644 --- a/resources/hiding_ci/linux_patches/20-gmem-write/0037-KVM-guest_memfd-add-generic-population-via-write.patch +++ b/resources/hiding_ci/linux_patches/20-gmem-write/0038-KVM-guest_memfd-add-generic-population-via-write.patch @@ -1,7 +1,7 @@ -From 39043385e22a91db6aec81b35ca1c6b6ac48a7b3 Mon Sep 17 00:00:00 2001 +From 1aaa001d27626a7f53cac6590e827eddd10e14df Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Mon, 3 Mar 2025 13:08:37 +0000 -Subject: [PATCH 37/42] KVM: guest_memfd: add generic population via write +Subject: [PATCH 38/45] KVM: guest_memfd: add generic population via write write syscall populates guest_memfd with user-supplied data in a generic way, ie no vendor-specific preparation is performed. This is supposed @@ -18,14 +18,14 @@ The following behaviour is implemented: Signed-off-by: Nikita Kalyazin --- - virt/kvm/guest_memfd.c | 92 +++++++++++++++++++++++++++++++++++++++++- - 1 file changed, 91 insertions(+), 1 deletion(-) + virt/kvm/guest_memfd.c | 88 +++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 87 insertions(+), 1 deletion(-) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index 99e1b20a9977..54ddad35bb5c 100644 +index d70ee66bb96d..809da2a2fb37 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c -@@ -392,8 +392,95 @@ static int kvm_gmem_mmap(struct file *file, struct vm_area_struct *vma) +@@ -392,8 +392,93 @@ static int kvm_gmem_mmap(struct file *file, struct vm_area_struct *vma) return 0; } @@ -114,21 +114,17 @@ index 99e1b20a9977..54ddad35bb5c 100644 + static struct file_operations kvm_gmem_fops = { - .mmap = kvm_gmem_mmap, -+#ifdef CONFIG_KVM_GMEM_SHARED_MEM + .mmap = kvm_gmem_mmap, + .llseek = default_llseek, + .write = kvm_kmem_gmem_write, -+#endif /* CONFIG_KVM_GMEM_SHARED_MEM */ .open = generic_file_open, .release = kvm_gmem_release, .fallocate = kvm_gmem_fallocate, -@@ -514,6 +601,9 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) +@@ -514,6 +599,7 @@ static int __kvm_gmem_create(struct kvm *kvm, loff_t size, u64 flags) } file->f_flags |= O_LARGEFILE; -+#ifdef CONFIG_KVM_GMEM_SHARED_MEM + file->f_mode |= FMODE_LSEEK | FMODE_PWRITE; -+#endif /* CONFIG_KVM_GMEM_SHARED_MEM */ inode = file->f_inode; WARN_ON(file->f_mapping != inode->i_mapping); diff --git a/resources/hiding_ci/linux_patches/20-gmem-write/0038-KVM-selftests-update-guest_memfd-write-tests.patch b/resources/hiding_ci/linux_patches/20-gmem-write/0039-KVM-selftests-update-guest_memfd-write-tests.patch similarity index 96% rename from resources/hiding_ci/linux_patches/20-gmem-write/0038-KVM-selftests-update-guest_memfd-write-tests.patch rename to resources/hiding_ci/linux_patches/20-gmem-write/0039-KVM-selftests-update-guest_memfd-write-tests.patch index 942c8c32678..f17e06e4b4e 100644 --- a/resources/hiding_ci/linux_patches/20-gmem-write/0038-KVM-selftests-update-guest_memfd-write-tests.patch +++ b/resources/hiding_ci/linux_patches/20-gmem-write/0039-KVM-selftests-update-guest_memfd-write-tests.patch @@ -1,7 +1,7 @@ -From f694f4128da12fa8153c952c7746b2290019ac94 Mon Sep 17 00:00:00 2001 +From 548fccdfb8036d53e5a4053ac7e4a031bc40a07e Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Mon, 3 Mar 2025 13:08:38 +0000 -Subject: [PATCH 38/42] KVM: selftests: update guest_memfd write tests +Subject: [PATCH 39/45] KVM: selftests: update guest_memfd write tests This is to reflect that the write syscall is now implemented for guest_memfd. @@ -12,7 +12,7 @@ Signed-off-by: Nikita Kalyazin 1 file changed, 79 insertions(+), 6 deletions(-) diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing/selftests/kvm/guest_memfd_test.c -index 5da2ed6277ac..bd001e2b3f6e 100644 +index 1252e74fbb8f..3965a842896e 100644 --- a/tools/testing/selftests/kvm/guest_memfd_test.c +++ b/tools/testing/selftests/kvm/guest_memfd_test.c @@ -22,18 +22,90 @@ diff --git a/resources/hiding_ci/linux_patches/25-gmem-uffd/0001-mm-userfaultfd-generic-continue-for-non-hugetlbfs.patch b/resources/hiding_ci/linux_patches/25-gmem-uffd/0040-mm-userfaultfd-generic-continue-for-non-hugetlbfs.patch similarity index 90% rename from resources/hiding_ci/linux_patches/25-gmem-uffd/0001-mm-userfaultfd-generic-continue-for-non-hugetlbfs.patch rename to resources/hiding_ci/linux_patches/25-gmem-uffd/0040-mm-userfaultfd-generic-continue-for-non-hugetlbfs.patch index 618a6631f84..1f4a75bcb26 100644 --- a/resources/hiding_ci/linux_patches/25-gmem-uffd/0001-mm-userfaultfd-generic-continue-for-non-hugetlbfs.patch +++ b/resources/hiding_ci/linux_patches/25-gmem-uffd/0040-mm-userfaultfd-generic-continue-for-non-hugetlbfs.patch @@ -1,7 +1,7 @@ -From 8815daa4b4574f5bddc6632e254d61053e642d06 Mon Sep 17 00:00:00 2001 +From 4725838afbca877e0fb8ac428370f0d16b73f3a1 Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Mon, 31 Mar 2025 10:15:35 +0000 -Subject: [PATCH 1/6] mm: userfaultfd: generic continue for non hugetlbfs +Subject: [PATCH 40/45] mm: userfaultfd: generic continue for non hugetlbfs Remove shmem-specific code from UFFDIO_CONTINUE implementation for non-huge pages by calling vm_ops->fault(). A new VMF flag, @@ -40,10 +40,10 @@ index d6b91e8a66d6..d4c35a50058c 100644 typedef unsigned int __bitwise zap_flags_t; diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index 8746ed2fec13..ff9c0ffa128d 100644 +index 9dc95eac558c..6ac2c763b3ec 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c -@@ -6553,7 +6553,7 @@ static vm_fault_t hugetlb_no_page(struct address_space *mapping, +@@ -6533,7 +6533,7 @@ static vm_fault_t hugetlb_no_page(struct address_space *mapping, } /* Check for page in userfault range. */ @@ -53,10 +53,10 @@ index 8746ed2fec13..ff9c0ffa128d 100644 folio_put(folio); /* See comment in userfaultfd_missing() block above */ diff --git a/mm/shmem.c b/mm/shmem.c -index 0c5fb4ffa03a..bca13ee02574 100644 +index 3a5a65b1f41a..01e20e0216bc 100644 --- a/mm/shmem.c +++ b/mm/shmem.c -@@ -2454,7 +2454,8 @@ static int shmem_get_folio_gfp(struct inode *inode, pgoff_t index, +@@ -2458,7 +2458,8 @@ static int shmem_get_folio_gfp(struct inode *inode, pgoff_t index, fault_mm = vma ? vma->vm_mm : NULL; folio = filemap_get_entry(inode->i_mapping, index); @@ -66,7 +66,7 @@ index 0c5fb4ffa03a..bca13ee02574 100644 if (!xa_is_value(folio)) folio_put(folio); *fault_type = handle_userfault(vmf, VM_UFFD_MINOR); -@@ -2714,6 +2715,8 @@ static vm_fault_t shmem_falloc_wait(struct vm_fault *vmf, struct inode *inode) +@@ -2718,6 +2719,8 @@ static vm_fault_t shmem_falloc_wait(struct vm_fault *vmf, struct inode *inode) static vm_fault_t shmem_fault(struct vm_fault *vmf) { struct inode *inode = file_inode(vmf->vma->vm_file); @@ -75,7 +75,7 @@ index 0c5fb4ffa03a..bca13ee02574 100644 gfp_t gfp = mapping_gfp_mask(inode->i_mapping); struct folio *folio = NULL; vm_fault_t ret = 0; -@@ -2730,8 +2733,8 @@ static vm_fault_t shmem_fault(struct vm_fault *vmf) +@@ -2734,8 +2737,8 @@ static vm_fault_t shmem_fault(struct vm_fault *vmf) } WARN_ON_ONCE(vmf->page != NULL); @@ -87,7 +87,7 @@ index 0c5fb4ffa03a..bca13ee02574 100644 return vmf_error(err); if (folio) { diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c -index bc473ad21202..f88bb8de7fff 100644 +index 8253978ee0fb..46380f262c4d 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -376,30 +376,47 @@ static int mfill_atomic_pte_zeropage(pmd_t *dst_pmd, diff --git a/resources/hiding_ci/linux_patches/25-gmem-uffd/0002-mm-provide-can_userfault-vma-operation.patch b/resources/hiding_ci/linux_patches/25-gmem-uffd/0041-mm-provide-can_userfault-vma-operation.patch similarity index 83% rename from resources/hiding_ci/linux_patches/25-gmem-uffd/0002-mm-provide-can_userfault-vma-operation.patch rename to resources/hiding_ci/linux_patches/25-gmem-uffd/0041-mm-provide-can_userfault-vma-operation.patch index d8ee451933c..6b7a128facb 100644 --- a/resources/hiding_ci/linux_patches/25-gmem-uffd/0002-mm-provide-can_userfault-vma-operation.patch +++ b/resources/hiding_ci/linux_patches/25-gmem-uffd/0041-mm-provide-can_userfault-vma-operation.patch @@ -1,7 +1,7 @@ -From d539c525dcb6e20c77b3921caf5a057301dc3880 Mon Sep 17 00:00:00 2001 +From 4cda7eded3f46f118c4053803921964210819b62 Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Fri, 4 Apr 2025 14:15:18 +0000 -Subject: [PATCH 2/6] mm: provide can_userfault vma operation +Subject: [PATCH 41/45] mm: provide can_userfault vma operation The new operation allows to decouple the userfaulfd code from dependencies to VMA types, specifically, shmem and hugetlb. The @@ -33,10 +33,10 @@ index 0ef2ba0c667a..72a29c83a7cd 100644 #ifdef CONFIG_NUMA_BALANCING diff --git a/mm/hugetlb.c b/mm/hugetlb.c -index ff9c0ffa128d..bfd78f572210 100644 +index 6ac2c763b3ec..d7f70adda621 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c -@@ -5467,6 +5467,12 @@ static unsigned long hugetlb_vm_op_pagesize(struct vm_area_struct *vma) +@@ -5447,6 +5447,12 @@ static unsigned long hugetlb_vm_op_pagesize(struct vm_area_struct *vma) return huge_page_size(hstate_vma(vma)); } @@ -49,7 +49,7 @@ index ff9c0ffa128d..bfd78f572210 100644 /* * We cannot handle pagefaults against hugetlb pages at all. They cause * handle_mm_fault() to try to instantiate regular-sized pages in the -@@ -5492,6 +5498,7 @@ const struct vm_operations_struct hugetlb_vm_ops = { +@@ -5472,6 +5478,7 @@ const struct vm_operations_struct hugetlb_vm_ops = { .close = hugetlb_vm_op_close, .may_split = hugetlb_vm_op_split, .pagesize = hugetlb_vm_op_pagesize, @@ -58,10 +58,10 @@ index ff9c0ffa128d..bfd78f572210 100644 static pte_t make_huge_pte(struct vm_area_struct *vma, struct folio *folio, diff --git a/mm/shmem.c b/mm/shmem.c -index bca13ee02574..920a0fc023f1 100644 +index 01e20e0216bc..296bca653f77 100644 --- a/mm/shmem.c +++ b/mm/shmem.c -@@ -2878,6 +2878,12 @@ static struct mempolicy *shmem_get_policy(struct vm_area_struct *vma, +@@ -2882,6 +2882,12 @@ static struct mempolicy *shmem_get_policy(struct vm_area_struct *vma, return mpol_shared_policy_lookup(&SHMEM_I(inode)->policy, index); } @@ -74,7 +74,7 @@ index bca13ee02574..920a0fc023f1 100644 static struct mempolicy *shmem_get_pgoff_policy(struct shmem_inode_info *info, pgoff_t index, unsigned int order, pgoff_t *ilx) { -@@ -5294,6 +5300,7 @@ static const struct vm_operations_struct shmem_vm_ops = { +@@ -5298,6 +5304,7 @@ static const struct vm_operations_struct shmem_vm_ops = { .set_policy = shmem_set_policy, .get_policy = shmem_get_policy, #endif @@ -82,7 +82,7 @@ index bca13ee02574..920a0fc023f1 100644 }; static const struct vm_operations_struct shmem_anon_vm_ops = { -@@ -5303,6 +5310,7 @@ static const struct vm_operations_struct shmem_anon_vm_ops = { +@@ -5307,6 +5314,7 @@ static const struct vm_operations_struct shmem_anon_vm_ops = { .set_policy = shmem_set_policy, .get_policy = shmem_get_policy, #endif diff --git a/resources/hiding_ci/linux_patches/25-gmem-uffd/0003-mm-userfaultfd-use-can_userfault-vma-operation.patch b/resources/hiding_ci/linux_patches/25-gmem-uffd/0042-mm-userfaultfd-use-can_userfault-vma-operation.patch similarity index 93% rename from resources/hiding_ci/linux_patches/25-gmem-uffd/0003-mm-userfaultfd-use-can_userfault-vma-operation.patch rename to resources/hiding_ci/linux_patches/25-gmem-uffd/0042-mm-userfaultfd-use-can_userfault-vma-operation.patch index aaa7b5670a9..5fc64121ac9 100644 --- a/resources/hiding_ci/linux_patches/25-gmem-uffd/0003-mm-userfaultfd-use-can_userfault-vma-operation.patch +++ b/resources/hiding_ci/linux_patches/25-gmem-uffd/0042-mm-userfaultfd-use-can_userfault-vma-operation.patch @@ -1,7 +1,7 @@ -From 1730062eb660fc23e0d9211225c240add60764e6 Mon Sep 17 00:00:00 2001 +From 2318ed356c02e81c205e9f73f37f2ee2beac0e94 Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Fri, 4 Apr 2025 14:16:49 +0000 -Subject: [PATCH 3/6] mm: userfaultfd: use can_userfault vma operation +Subject: [PATCH 42/45] mm: userfaultfd: use can_userfault vma operation Signed-off-by: Nikita Kalyazin --- @@ -46,7 +46,7 @@ index 75342022d144..64551e8a55fb 100644 static inline bool vma_has_uffd_without_event_remap(struct vm_area_struct *vma) diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c -index f88bb8de7fff..8d8df51615b5 100644 +index 46380f262c4d..d900dfd03bbe 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -724,6 +724,7 @@ static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx, diff --git a/resources/hiding_ci/linux_patches/25-gmem-uffd/0004-KVM-guest_memfd-add-support-for-userfaultfd-minor.patch b/resources/hiding_ci/linux_patches/25-gmem-uffd/0043-KVM-guest_memfd-add-support-for-userfaultfd-minor.patch similarity index 77% rename from resources/hiding_ci/linux_patches/25-gmem-uffd/0004-KVM-guest_memfd-add-support-for-userfaultfd-minor.patch rename to resources/hiding_ci/linux_patches/25-gmem-uffd/0043-KVM-guest_memfd-add-support-for-userfaultfd-minor.patch index 27a3137b453..86eceb097b8 100644 --- a/resources/hiding_ci/linux_patches/25-gmem-uffd/0004-KVM-guest_memfd-add-support-for-userfaultfd-minor.patch +++ b/resources/hiding_ci/linux_patches/25-gmem-uffd/0043-KVM-guest_memfd-add-support-for-userfaultfd-minor.patch @@ -1,7 +1,7 @@ -From 14384ede95c5fb7292696fc43268dfe6c5e0830e Mon Sep 17 00:00:00 2001 +From 8b3a8e678098839da1e54f60cea7991a157a4c0e Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Tue, 1 Apr 2025 15:02:56 +0000 -Subject: [PATCH 4/6] KVM: guest_memfd: add support for userfaultfd minor +Subject: [PATCH 43/45] KVM: guest_memfd: add support for userfaultfd minor Add support for sending a pagefault event if userfaultfd is registered. Only page minor event is currently supported. @@ -12,7 +12,7 @@ Signed-off-by: Nikita Kalyazin 1 file changed, 7 insertions(+) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index 54ddad35bb5c..212c70b8da0c 100644 +index 809da2a2fb37..e7fcd422c801 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c @@ -5,6 +5,7 @@ @@ -23,7 +23,7 @@ index 54ddad35bb5c..212c70b8da0c 100644 #include "kvm_mm.h" -@@ -362,6 +363,12 @@ static vm_fault_t kvm_gmem_fault_shared(struct vm_fault *vmf) +@@ -362,6 +363,12 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf) kvm_gmem_mark_prepared(folio); } diff --git a/resources/hiding_ci/linux_patches/25-gmem-uffd/0005-mm-userfaultfd-add-UFFD_FEATURE_MINOR_GUEST_MEMFD.patch b/resources/hiding_ci/linux_patches/25-gmem-uffd/0044-mm-userfaultfd-add-UFFD_FEATURE_MINOR_GUEST_MEMFD.patch similarity index 93% rename from resources/hiding_ci/linux_patches/25-gmem-uffd/0005-mm-userfaultfd-add-UFFD_FEATURE_MINOR_GUEST_MEMFD.patch rename to resources/hiding_ci/linux_patches/25-gmem-uffd/0044-mm-userfaultfd-add-UFFD_FEATURE_MINOR_GUEST_MEMFD.patch index 12f976584ad..5219409cf34 100644 --- a/resources/hiding_ci/linux_patches/25-gmem-uffd/0005-mm-userfaultfd-add-UFFD_FEATURE_MINOR_GUEST_MEMFD.patch +++ b/resources/hiding_ci/linux_patches/25-gmem-uffd/0044-mm-userfaultfd-add-UFFD_FEATURE_MINOR_GUEST_MEMFD.patch @@ -1,7 +1,7 @@ -From 6949cc0ef279aad43df07a04122d8ea073011862 Mon Sep 17 00:00:00 2001 +From 7b9d0141ede5557c7609b2fadf79be7e103c0917 Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Fri, 4 Apr 2025 14:18:03 +0000 -Subject: [PATCH 5/6] mm: userfaultfd: add UFFD_FEATURE_MINOR_GUEST_MEMFD +Subject: [PATCH 44/45] mm: userfaultfd: add UFFD_FEATURE_MINOR_GUEST_MEMFD Signed-off-by: Nikita Kalyazin --- diff --git a/resources/hiding_ci/linux_patches/25-gmem-uffd/0006-fixup-for-guest_memfd-uffd-v3.patch b/resources/hiding_ci/linux_patches/25-gmem-uffd/0045-fixup-for-guest_memfd-uffd-v3.patch similarity index 86% rename from resources/hiding_ci/linux_patches/25-gmem-uffd/0006-fixup-for-guest_memfd-uffd-v3.patch rename to resources/hiding_ci/linux_patches/25-gmem-uffd/0045-fixup-for-guest_memfd-uffd-v3.patch index 696e8c9f831..bf6c356884c 100644 --- a/resources/hiding_ci/linux_patches/25-gmem-uffd/0006-fixup-for-guest_memfd-uffd-v3.patch +++ b/resources/hiding_ci/linux_patches/25-gmem-uffd/0045-fixup-for-guest_memfd-uffd-v3.patch @@ -1,7 +1,7 @@ -From 357ef010655d59d9d138fa176674f3c62e0e21e9 Mon Sep 17 00:00:00 2001 +From 46a18cd195d8c68e319ba7142cd923db7ccff967 Mon Sep 17 00:00:00 2001 From: Nikita Kalyazin Date: Thu, 10 Apr 2025 14:18:53 +0000 -Subject: [PATCH 6/6] fixup for guest_memfd uffd v3 +Subject: [PATCH 45/45] fixup for guest_memfd uffd v3 - implement can_userfault for guest_memfd - check vma->vm_ops pointer before dereferencing @@ -32,7 +32,7 @@ index 64551e8a55fb..8a05a7880393 100644 /* * If wp async enabled, and WP is the only mode enabled, allow any diff --git a/mm/userfaultfd.c b/mm/userfaultfd.c -index 8d8df51615b5..6257e8fcbd49 100644 +index d900dfd03bbe..7fb92714bc5c 100644 --- a/mm/userfaultfd.c +++ b/mm/userfaultfd.c @@ -784,7 +784,9 @@ static __always_inline ssize_t mfill_atomic(struct userfaultfd_ctx *ctx, @@ -47,10 +47,10 @@ index 8d8df51615b5..6257e8fcbd49 100644 if (!vma_is_anonymous(dst_vma) && !can_userfault) diff --git a/virt/kvm/guest_memfd.c b/virt/kvm/guest_memfd.c -index 212c70b8da0c..672a3cf4796f 100644 +index e7fcd422c801..0226086a1a01 100644 --- a/virt/kvm/guest_memfd.c +++ b/virt/kvm/guest_memfd.c -@@ -380,8 +380,15 @@ static vm_fault_t kvm_gmem_fault_shared(struct vm_fault *vmf) +@@ -380,8 +380,15 @@ static vm_fault_t kvm_gmem_fault_user_mapping(struct vm_fault *vmf) return ret; } @@ -61,7 +61,7 @@ index 212c70b8da0c..672a3cf4796f 100644 +} + static const struct vm_operations_struct kvm_gmem_vm_ops = { - .fault = kvm_gmem_fault_shared, + .fault = kvm_gmem_fault_user_mapping, + .can_userfault = kvm_gmem_can_userfault, };