diff --git a/config.yaml b/config.yaml index 93a9f84..1ba5cfb 100644 --- a/config.yaml +++ b/config.yaml @@ -33,6 +33,10 @@ actions: - type: "source" name: "almalinuxima.x509" number: 103 + - type: "patch" + name: "ppc64le-kvm-support.patch" + number: "Latest" + modify_spec: false - replace: - target: "kernel*rhel.config" @@ -169,7 +173,154 @@ actions: find: "# Red Hat UEFI Secure Boot CA cert, which can be used to authenticate the kernel" replace: "# AlmaLinux UEFI Secure Boot CA cert, which can be used to authenticate the kernel" count: 1 - + - target: "spec" + find: | + # kernel-64k (aarch64 kernel with 64K page_size) + %define with_arm64_64k %{?_without_arm64_64k: 0} %{?!_without_arm64_64k: 1} + replace: | + # kernel-64k (aarch64 kernel with 64K page_size) + %define with_arm64_64k %{?_without_arm64_64k: 0} %{?!_without_arm64_64k: 1} + # kernel-kvm ppc64le kernel with kvm support) + %define with_ppc_kvm %{?_without_ppc_kvm: 0} %{?!_without_ppc_kvm: 1} + count: 1 + - target: "spec" + find: | + # 64k variant only for aarch64 + %ifnarch aarch64 + %define with_arm64_64k 0 + %endif + replace: | + # 64k variant only for aarch64 + %ifnarch aarch64 + %define with_arm64_64k 0 + %endif + + # kvm variant only for ppc64le + %ifnarch ppc64le + %define with_ppc_kvm 0 + %endif + count: 1 + - target: "spec" + find: | + %ifarch %nobuildarches + # disable BuildKernel commands + %define with_up 0 + %define with_debug 0 + %define with_pae 0 + %define with_zfcpdump 0 + %define with_arm64_64k 0 + replace: | + %ifarch %nobuildarches + # disable BuildKernel commands + %define with_up 0 + %define with_debug 0 + %define with_pae 0 + %define with_zfcpdump 0 + %define with_arm64_64k 0 + %define with_ppc_kvm 0 + count: 1 + - target: "spec" + find: | + Source47: kernel-aarch64-rt-debug-rhel.config + replace: | + Source47: kernel-aarch64-rt-debug-rhel.config + + # PPC64le KVM support config + Source10001: kernel-ppc64le-kvm-rhel.config + count: 1 + - target: "spec" + find: | + # END OF PATCH DEFINITIONS + replace: | + Patch11111: ppc64le-kvm-support.patch + + # END OF PATCH DEFINITIONS + count: 1 + - target: "spec" + find: | + %if %{with_arm64_64k} + %define variant_summary The Linux kernel compiled for 64k pagesize usage + %kernel_variant_package 64k + %description 64k-core + The kernel package contains a variant of the ARM64 Linux kernel using + a 64K page size. + %endif + replace: | + %if %{with_arm64_64k} + %define variant_summary The Linux kernel compiled for 64k pagesize usage + %kernel_variant_package 64k + %description 64k-core + The kernel package contains a variant of the ARM64 Linux kernel using + a 64K page size. + %endif + + %if %{with_ppc_kvm} + %define variant_summary The Linux kernel compiled for KVM usage on ppc64le + %kernel_variant_package kvm + %description kvm-core + The kernel package contains a variant of the PPC64le Linux kernel with + KVM support. + %endif + count: 1 + - target: "spec" + find: | + %if %{with_up} + BuildKernel %make_target %kernel_image %{_use_vdso} + %endif + replace: | + %if %{with_up} + BuildKernel %make_target %kernel_image %{_use_vdso} + %endif + + %if %{with_ppc_kvm} + git apply $RPM_SOURCE_DIR/ppc64le-kvm-support.patch + BuildKernel %make_target %kernel_image %{_use_vdso} kvm + %endif + count: 1 + - target: "spec" + find: | + %if !%{with_debug} && !%{with_zfcpdump} && !%{with_pae} && !%{with_up} && !%{with_arm64_64k} && !%{with_realtime} + replace: | + %if !%{with_debug} && !%{with_zfcpdump} && !%{with_pae} && !%{with_up} && !%{with_arm64_64k} && !%{with_realtime} && !%{with_ppc_kvm} + count: 1 + - target: "spec" + find: | + if [ "%{with_arm64_64k}" -ne "0" ] && [ "%{with_debug}" -ne "0" ]; then \ + %{modsign_cmd} certs/signing_key.pem.sign+64k-debug certs/signing_key.x509.sign+64k-debug $RPM_BUILD_ROOT/lib/modules/%{KVERREL}+64k-debug/ \ + fi \ + replace: | + if [ "%{with_arm64_64k}" -ne "0" ] && [ "%{with_debug}" -ne "0" ]; then \ + %{modsign_cmd} certs/signing_key.pem.sign+64k-debug certs/signing_key.x509.sign+64k-debug $RPM_BUILD_ROOT/lib/modules/%{KVERREL}+64k-debug/ \ + fi \ + if [ "%{with_ppc_kvm}" -ne "0" ]; then \ + %{modsign_cmd} certs/signing_key.pem.sign+kvm certs/signing_key.x509.sign+kvm $RPM_BUILD_ROOT/lib/modules/%{KVERREL}+kvm/ \ + fi \ + count: 1 + - target: "spec" + find: | + %if %{with_arm64_64k} + %kernel_variant_preun -v 64k + %kernel_variant_post -v 64k + %endif + replace: | + %if %{with_arm64_64k} + %kernel_variant_preun -v 64k + %kernel_variant_post -v 64k + %endif + + %if %{with_ppc_kvm} + %kernel_variant_preun -v kvm + %kernel_variant_post -v kvm + %endif + count: 1 + - target: "spec" + find: | + %kernel_variant_files %{_use_vdso} %{with_arm64_64k} 64k + replace: | + %kernel_variant_files %{_use_vdso} %{with_arm64_64k} 64k + %kernel_variant_files %{_use_vdso} %{with_ppc_kvm} kvm + count: 1 + - delete_line: - target: "spec" lines: @@ -196,6 +347,10 @@ actions: gzip -f9 $SignImage fi + - run_script: + - script: "copy_ppc64le_config.sh" + cwd: "rpms" + - changelog_entry: - name: "Andrei Lukoshko" email: "alukoshko@almalinux.org" @@ -213,3 +368,4 @@ actions: line: - "Use AlmaLinux OS secure boot cert" - "Debrand for AlmaLinux OS" + - "Add KVM support for ppc64le" diff --git a/files/ppc64le-kvm-support.patch b/files/ppc64le-kvm-support.patch new file mode 100644 index 0000000..241560a --- /dev/null +++ b/files/ppc64le-kvm-support.patch @@ -0,0 +1,290 @@ +From 524ab50336b1190547ceb8074260a1fbebfee0be Mon Sep 17 00:00:00 2001 +From: Sean Christopherson +Date: Mon, 6 Dec 2021 20:54:14 +0100 +Subject: [PATCH 1/3] KVM: PPC: Avoid referencing userspace memory region in + memslot updates + +For PPC HV, get the number of pages directly from the new memslot instead +of computing the same from the userspace memory region, and explicitly +check for !DELETE instead of inferring the same when toggling mmio_update. +The motivation for these changes is to avoid referencing the @mem param +so that it can be dropped in a future commit. + +No functional change intended. + +Signed-off-by: Sean Christopherson +Signed-off-by: Maciej S. Szmigiero +Message-Id: <1e97fb5198be25f98ef82e63a8d770c682264cc9.1638817639.git.maciej.szmigiero@oracle.com> +--- + arch/powerpc/include/asm/kvm_ppc.h | 4 ---- + arch/powerpc/kvm/book3s.c | 6 ++---- + arch/powerpc/kvm/book3s_hv.c | 12 +++--------- + arch/powerpc/kvm/book3s_pr.c | 2 -- + arch/powerpc/kvm/booke.c | 2 -- + arch/powerpc/kvm/powerpc.c | 4 ++-- + 6 files changed, 7 insertions(+), 23 deletions(-) + +diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h +index 5c80c4955..6874cd89d 100644 +--- a/arch/powerpc/include/asm/kvm_ppc.h ++++ b/arch/powerpc/include/asm/kvm_ppc.h +@@ -199,12 +199,10 @@ extern void kvmppc_core_destroy_vm(struct kvm *kvm); + extern void kvmppc_core_free_memslot(struct kvm *kvm, + struct kvm_memory_slot *slot); + extern int kvmppc_core_prepare_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old, + struct kvm_memory_slot *new, + enum kvm_mr_change change); + extern void kvmppc_core_commit_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + struct kvm_memory_slot *old, + const struct kvm_memory_slot *new, + enum kvm_mr_change change); +@@ -274,12 +272,10 @@ struct kvmppc_ops { + int (*get_dirty_log)(struct kvm *kvm, struct kvm_dirty_log *log); + void (*flush_memslot)(struct kvm *kvm, struct kvm_memory_slot *memslot); + int (*prepare_memory_region)(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old, + struct kvm_memory_slot *new, + enum kvm_mr_change change); + void (*commit_memory_region)(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + struct kvm_memory_slot *old, + const struct kvm_memory_slot *new, + enum kvm_mr_change change); +diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c +index 64fd4b3ea..cb7b5f365 100644 +--- a/arch/powerpc/kvm/book3s.c ++++ b/arch/powerpc/kvm/book3s.c +@@ -847,21 +847,19 @@ void kvmppc_core_flush_memslot(struct kvm *kvm, struct kvm_memory_slot *memslot) + } + + int kvmppc_core_prepare_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old, + struct kvm_memory_slot *new, + enum kvm_mr_change change) + { +- return kvm->arch.kvm_ops->prepare_memory_region(kvm, mem, old, new, change); ++ return kvm->arch.kvm_ops->prepare_memory_region(kvm, old, new, change); + } + + void kvmppc_core_commit_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + struct kvm_memory_slot *old, + const struct kvm_memory_slot *new, + enum kvm_mr_change change) + { +- kvm->arch.kvm_ops->commit_memory_region(kvm, mem, old, new, change); ++ kvm->arch.kvm_ops->commit_memory_region(kvm, old, new, change); + } + + bool kvm_unmap_gfn_range(struct kvm *kvm, struct kvm_gfn_range *range) +diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c +index 9c3c9fd5e..7f4c188f3 100644 +--- a/arch/powerpc/kvm/book3s_hv.c ++++ b/arch/powerpc/kvm/book3s_hv.c +@@ -4777,15 +4777,12 @@ static void kvmppc_core_free_memslot_hv(struct kvm_memory_slot *slot) + } + + static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old, + struct kvm_memory_slot *new, + enum kvm_mr_change change) + { +- unsigned long npages = mem->memory_size >> PAGE_SHIFT; +- + if (change == KVM_MR_CREATE) { +- new->arch.rmap = vzalloc(array_size(npages, ++ new->arch.rmap = vzalloc(array_size(new->npages, + sizeof(*new->arch.rmap))); + if (!new->arch.rmap) + return -ENOMEM; +@@ -4797,20 +4794,17 @@ static int kvmppc_core_prepare_memory_region_hv(struct kvm *kvm, + } + + static void kvmppc_core_commit_memory_region_hv(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + struct kvm_memory_slot *old, + const struct kvm_memory_slot *new, + enum kvm_mr_change change) + { +- unsigned long npages = mem->memory_size >> PAGE_SHIFT; +- + /* +- * If we are making a new memslot, it might make ++ * If we are creating or modifying a memslot, it might make + * some address that was previously cached as emulated + * MMIO be no longer emulated MMIO, so invalidate + * all the caches of emulated MMIO translations. + */ +- if (npages) ++ if (change != KVM_MR_DELETE) + atomic64_inc(&kvm->arch.mmio_update); + + /* +diff --git a/arch/powerpc/kvm/book3s_pr.c b/arch/powerpc/kvm/book3s_pr.c +index 7891b9d0c..c0ae926af 100644 +--- a/arch/powerpc/kvm/book3s_pr.c ++++ b/arch/powerpc/kvm/book3s_pr.c +@@ -1892,7 +1892,6 @@ static void kvmppc_core_flush_memslot_pr(struct kvm *kvm, + } + + static int kvmppc_core_prepare_memory_region_pr(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old, + struct kvm_memory_slot *new, + enum kvm_mr_change change) +@@ -1901,7 +1900,6 @@ static int kvmppc_core_prepare_memory_region_pr(struct kvm *kvm, + } + + static void kvmppc_core_commit_memory_region_pr(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + struct kvm_memory_slot *old, + const struct kvm_memory_slot *new, + enum kvm_mr_change change) +diff --git a/arch/powerpc/kvm/booke.c b/arch/powerpc/kvm/booke.c +index b06ca6646..6cf2db284 100644 +--- a/arch/powerpc/kvm/booke.c ++++ b/arch/powerpc/kvm/booke.c +@@ -1806,7 +1806,6 @@ void kvmppc_core_free_memslot(struct kvm *kvm, struct kvm_memory_slot *slot) + } + + int kvmppc_core_prepare_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + const struct kvm_memory_slot *old, + struct kvm_memory_slot *new, + enum kvm_mr_change change) +@@ -1815,7 +1814,6 @@ int kvmppc_core_prepare_memory_region(struct kvm *kvm, + } + + void kvmppc_core_commit_memory_region(struct kvm *kvm, +- const struct kvm_userspace_memory_region *mem, + struct kvm_memory_slot *old, + const struct kvm_memory_slot *new, + enum kvm_mr_change change) +diff --git a/arch/powerpc/kvm/powerpc.c b/arch/powerpc/kvm/powerpc.c +index 818815e15..f8f39a858 100644 +--- a/arch/powerpc/kvm/powerpc.c ++++ b/arch/powerpc/kvm/powerpc.c +@@ -686,7 +686,7 @@ int kvm_arch_prepare_memory_region(struct kvm *kvm, + struct kvm_memory_slot *new, + enum kvm_mr_change change) + { +- return kvmppc_core_prepare_memory_region(kvm, mem, old, new, change); ++ return kvmppc_core_prepare_memory_region(kvm, old, new, change); + } + + void kvm_arch_commit_memory_region(struct kvm *kvm, +@@ -694,7 +694,7 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, + const struct kvm_memory_slot *new, + enum kvm_mr_change change) + { +- kvmppc_core_commit_memory_region(kvm, mem, old, new, change); ++ kvmppc_core_commit_memory_region(kvm, old, new, change); + } + + void kvm_arch_flush_shadow_memslot(struct kvm *kvm, +-- +2.39.5 (Apple Git-154) + + +From a8d04f4f09f371e3b4fca9a40e9d3b5a1e0016d3 Mon Sep 17 00:00:00 2001 +From: Hugh Dickins +Date: Thu, 8 Jun 2023 12:22:39 -0700 +Subject: [PATCH 2/3] powerpc: kvmppc_unmap_free_pmd() pte_offset_kernel() + +kvmppc_unmap_free_pmd() use pte_offset_kernel(), like everywhere else +in book3s_64_mmu_radix.c: instead of pte_offset_map(), which will come +to need a pte_unmap() to balance it. + +But note that this is a more complex case than most: see those -EAGAINs +in kvmppc_create_pte(), which is coping with kvmppc races beween page +table and huge entry, of the kind which we are expecting to address +in pte_offset_map() - this might want to be revisited in future. + +Link: https://lkml.kernel.org/r/c76aa421-aec3-4cc8-cc61-4130f2e27e1@google.com +Signed-off-by: Hugh Dickins +Cc: Alexander Gordeev +Cc: Alexandre Ghiti +Cc: Aneesh Kumar K.V +Cc: Catalin Marinas +Cc: Christian Borntraeger +Cc: Chris Zankel +Cc: Claudio Imbrenda +Cc: David Hildenbrand +Cc: "David S. Miller" +Cc: Geert Uytterhoeven +Cc: Greg Ungerer +Cc: Heiko Carstens +Cc: Helge Deller +Cc: "H. Peter Anvin" +Cc: Ingo Molnar +Cc: John David Anglin +Cc: John Paul Adrian Glaubitz +Cc: Kirill A. Shutemov +Cc: Matthew Wilcox (Oracle) +Cc: Max Filippov +Cc: Michael Ellerman +Cc: Michal Simek +Cc: Mike Kravetz +Cc: Mike Rapoport (IBM) +Cc: Palmer Dabbelt +Cc: Peter Zijlstra +Cc: Qi Zheng +Cc: Russell King +Cc: Suren Baghdasaryan +Cc: Thomas Bogendoerfer +Cc: Thomas Gleixner +Cc: Will Deacon +Signed-off-by: Andrew Morton +--- + arch/powerpc/kvm/book3s_64_mmu_radix.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c +index e565a84cf..57fe60b51 100644 +--- a/arch/powerpc/kvm/book3s_64_mmu_radix.c ++++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c +@@ -502,7 +502,7 @@ static void kvmppc_unmap_free_pmd(struct kvm *kvm, pmd_t *pmd, bool full, + } else { + pte_t *pte; + +- pte = pte_offset_map(p, 0); ++ pte = pte_offset_kernel(p, 0); + kvmppc_unmap_free_pte(kvm, pte, full, lpid); + pmd_clear(p); + } +-- +2.39.5 (Apple Git-154) + + +From 8c62d250a23bbbb1ecd84d4d475e7623810275aa Mon Sep 17 00:00:00 2001 +From: eabdullin +Date: Tue, 8 Apr 2025 10:13:43 +0300 +Subject: [PATCH 3/3] powerpc/kvm: use mmu_invalidate_seq instead of + mmu_notifier_seq + +--- + arch/powerpc/kvm/book3s_64_vio_hv.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/arch/powerpc/kvm/book3s_64_vio_hv.c b/arch/powerpc/kvm/book3s_64_vio_hv.c +index f38dfe195..16e5872a1 100644 +--- a/arch/powerpc/kvm/book3s_64_vio_hv.c ++++ b/arch/powerpc/kvm/book3s_64_vio_hv.c +@@ -488,7 +488,7 @@ long kvmppc_rm_h_put_tce_indirect(struct kvm_vcpu *vcpu, + /* + * used to check for invalidations in progress + */ +- mmu_seq = kvm->mmu_notifier_seq; ++ mmu_seq = kvm->mmu_invalidate_seq; + smp_rmb(); + + stt = kvmppc_find_table(vcpu->kvm, liobn); +-- +2.39.5 (Apple Git-154) + diff --git a/scripts/copy_ppc64le_config.sh b/scripts/copy_ppc64le_config.sh new file mode 100644 index 0000000..71d7ce6 --- /dev/null +++ b/scripts/copy_ppc64le_config.sh @@ -0,0 +1,2 @@ +cp SOURCES/kernel-ppc64le-rhel.config SOURCES/kernel-ppc64le-kvm-rhel.config +sed -i 's|# CONFIG_KVM_BOOK3S_64 is not set|CONFIG_KVM_BOOK3S_64=m\nCONFIG_KVM_BOOK3S_64_HV=m\n# CONFIG_KVM_BOOK3S_64_PR is not set\n# CONFIG_KVM_BOOK3S_HV_EXIT_TIMING is not set\nCONFIG_KVM_BOOK3S_PR_POSSIBLE=y\nCONFIG_KVM_XICS=y|g' SOURCES/kernel-ppc64le-kvm-rhel.config