FAILED: patch "[PATCH] KVM: arm64: Use stage-1 leaf size for VM_PFNMAP" failed to apply to 6.18-stable tree
Subsystems (3)
[email protected]
maintainerThe patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x 71cc2c67fb8f8d5aa8154eb482e9846d2214f11b
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026100530-impulse-jiffy-87f1@gregkh' --subject-prefix 'PATCH 6.18.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 71cc2c67fb8f8d5aa8154eb482e9846d2214f11b Mon Sep 17 00:00:00 2001
From: Mostafa Saleh <[email protected]>
Date: Tue, 29 Sep 2026 20:02:09 +0000
Subject: [PATCH] KVM: arm64: Use stage-1 leaf size for VM_PFNMAP
When commit 2aa53d68cee6 ("KVM: arm64: Try stage2 block mapping for host device MMIO") added VM_PFNMAP support to get_vma_page_shift(), stage-1 page tables did not support huge PFNMAP (as in VFIO-PCI vfio_pci_mmap_huge_fault()) and transparent_hugepage_adjust() was unsafe for MMIO as it dereferenced struct page.
Since commit 6011cf68c885 ("KVM: arm64: Walk userspace page tables to compute the THP mapping size"), transparent_hugepage_adjust() instead walks the host stage-1 page tables via get_user_mapping_size() without touching struct page. Meanwhile, commit 3e509c9b03f9 ("mm/arm64:
support large pfn mappings") enabled stage-1 huge PFNMAP.
So. we can drop the VMA-based VM_PFNMAP size calculation in get_vma_page_shift() and let transparent_hugepage_adjust() derive the stage-2 mapping size directly from the populated stage-1 leaf for non-cacheable mappings as well.
arch/arm64/kvm/mmu.c +6 -41
@@ -1468,32 +1468,11 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,return PAGE_SIZE ; } -static int get_vma_page_shift (struct vm_area_struct *vma,unsigned long hva) +static int get_vma_page_shift (struct vm_area_struct *vma) { -unsigned long pa; - -if (is_vm_hugetlb_page (vma) && !(vma->vm_flags &VM_PFNMAP )) +if (is_vm_hugetlb_page (vma))return huge_page_shift (hstate_vma (vma)); -if (!(vma->vm_flags &VM_PFNMAP )) -return PAGE_SHIFT ; - -VM_BUG_ON (is_vm_hugetlb_page (vma)); - - pa = (vma->vm_pgoff <<PAGE_SHIFT ) + (hva - vma->vm_start); - -#ifndef __PAGETABLE_PMD_FOLDED -if ((hva & (PUD_SIZE -1 )) == (pa & (PUD_SIZE -1 )) && -ALIGN_DOWN (hva,PUD_SIZE ) >= vma->vm_start && -ALIGN (hva,PUD_SIZE ) <= vma->vm_end) -return PUD_SHIFT ; -#endif - -if ((hva & (PMD_SIZE -1 )) == (pa & (PMD_SIZE -1 )) && -ALIGN_DOWN (hva,PMD_SIZE ) >= vma->vm_start && -ALIGN (hva,PMD_SIZE ) <= vma->vm_end) -return PMD_SHIFT ; -return PAGE_SHIFT ; }
@@ -1794,7 +1773,7 @@ static short kvm_s2_resolve_vma_size(const struct kvm_s2_fault_desc *s2fd, vma_shift =PAGE_SHIFT ; }else { s2vi->max_map_size =PUD_SIZE ; - vma_shift =get_vma_page_shift (vma, s2fd->hva); + vma_shift =get_vma_page_shift (vma); }switch (vma_shift) {
@@ -1952,16 +1931,6 @@ static int kvm_s2_fault_pin_pfn(const struct kvm_s2_fault_desc *s2fd,return -EFAULT ; } }else { -/* -* If the page was identified as device early by looking at -* the VMA flags, vma_pagesize is already representing the -* largest quantity we can map. If instead it was mapped -* via __kvm_faultin_pfn(), vma_pagesize is set to PAGE_SIZE -* and must not be upgraded. -* -* In both cases, we don't let transparent_hugepage_adjust() -* change things at the last minute. -*/ s2vi->map_non_cacheable = true; }
@@ -2051,10 +2020,10 @@ static int kvm_s2_fault_map(const struct kvm_s2_fault_desc *s2fd,/* * If we are not forced to use page mapping, check if we are -* backed by a THP and thus use block mapping if possible. +* backed by a huge stage-1 mapping and thus use block mapping if +* possible. */ -if (mapping_size ==PAGE_SIZE && - !(s2vi->max_map_size ==PAGE_SIZE || s2vi->map_non_cacheable)) { +if (mapping_size ==PAGE_SIZE && s2vi->max_map_size !=PAGE_SIZE ) {if (perm_fault_granule >PAGE_SIZE ) { mapping_size = perm_fault_granule; }else {
@@ -2135,10 +2104,6 @@ static int user_mem_abort(const struct kvm_s2_fault_desc *s2fd)return ret; } -/* -* Let's check if we will get back a huge page backed by hugetlbfs, or -* get block mapping for device MMIO region. -*/ ret =kvm_s2_fault_pin_pfn (s2fd, &s2vi);if (ret !=1 )return ret;
Sasha Levin
maintainerPATCH 1/1 KVM: arm64: Use stage-1 leaf size for VM_PFNMAP
From: Mostafa Saleh <[email protected]>
[ Upstream commit 71cc2c67fb8f8d5aa8154eb482e9846d2214f11b ]
When commit 2aa53d68cee6 ("KVM: arm64: Try stage2 block mapping for host device MMIO") added VM_PFNMAP support to get_vma_page_shift(), stage-1 page tables did not support huge PFNMAP (as in VFIO-PCI vfio_pci_mmap_huge_fault()) and transparent_hugepage_adjust() was unsafe for MMIO as it dereferenced struct page.
Since commit 6011cf68c885 ("KVM: arm64: Walk userspace page tables to compute the THP mapping size"), transparent_hugepage_adjust() instead walks the host stage-1 page tables via get_user_mapping_size() without touching struct page. Meanwhile, commit 3e509c9b03f9 ("mm/arm64:
support large pfn mappings") enabled stage-1 huge PFNMAP.
So. we can drop the VMA-based VM_PFNMAP size calculation in get_vma_page_shift() and let transparent_hugepage_adjust() derive the stage-2 mapping size directly from the populated stage-1 leaf for non-cacheable mappings as well.
--- arch/arm64/kvm/mmu.c | 46 ++++++-------------------------------------- 1 file changed, 6 insertions(+), 40 deletions(-)
arch/arm64/kvm/mmu.c +6 -40
@@ -1406,32 +1406,11 @@ transparent_hugepage_adjust(struct kvm *kvm, struct kvm_memory_slot *memslot,return PAGE_SIZE ; } -static int get_vma_page_shift (struct vm_area_struct *vma,unsigned long hva) +static int get_vma_page_shift (struct vm_area_struct *vma) { -unsigned long pa; - -if (is_vm_hugetlb_page (vma) && !(vma->vm_flags &VM_PFNMAP )) +if (is_vm_hugetlb_page (vma))return huge_page_shift (hstate_vma (vma)); -if (!(vma->vm_flags &VM_PFNMAP )) -return PAGE_SHIFT ; - -VM_BUG_ON (is_vm_hugetlb_page (vma)); - - pa = (vma->vm_pgoff <<PAGE_SHIFT ) + (hva - vma->vm_start); - -#ifndef __PAGETABLE_PMD_FOLDED -if ((hva & (PUD_SIZE -1 )) == (pa & (PUD_SIZE -1 )) && -ALIGN_DOWN (hva,PUD_SIZE ) >= vma->vm_start && -ALIGN (hva,PUD_SIZE ) <= vma->vm_end) -return PUD_SHIFT ; -#endif - -if ((hva & (PMD_SIZE -1 )) == (pa & (PMD_SIZE -1 )) && -ALIGN_DOWN (hva,PMD_SIZE ) >= vma->vm_start && -ALIGN (hva,PMD_SIZE ) <= vma->vm_end) -return PMD_SHIFT ; -return PAGE_SHIFT ; }
@@ -1655,10 +1634,6 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,if (ret)return ret; -/* -* Let's check if we will get back a huge page backed by hugetlbfs, or -* get block mapping for device MMIO region. -*/ mmap_read_lock (current->mm); vma =vma_lookup (current->mm, hva);if (unlikely (!vma)) {
@@ -1670,7 +1645,7 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,if (force_pte) vma_shift =PAGE_SHIFT ;else - vma_shift =get_vma_page_shift (vma, hva); + vma_shift =get_vma_page_shift (vma);switch (vma_shift) {#ifndef __PAGETABLE_PMD_FOLDED
@@ -1786,16 +1761,6 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,if (!kvm_supports_cacheable_pfnmap ()) ret = -EFAULT ; }else { -/* -* If the page was identified as device early by looking at -* the VMA flags, vma_pagesize is already representing the -* largest quantity we can map. If instead it was mapped -* via __kvm_faultin_pfn(), vma_pagesize is set to PAGE_SIZE -* and must not be upgraded. -* -* In both cases, we don't let transparent_hugepage_adjust() -* change things at the last minute. -*/ s2_force_noncacheable = true; } }else if (logging_active && !write_fault) {
@@ -1826,9 +1791,10 @@ static int user_mem_abort(struct kvm_vcpu *vcpu, phys_addr_t fault_ipa,/* * If we are not forced to use page mapping, check if we are -* backed by a THP and thus use block mapping if possible. +* backed by a huge stage-1 mapping and thus use block mapping if +* possible. */ -if (vma_pagesize ==PAGE_SIZE && !(force_pte || s2_force_noncacheable)) { +if (vma_pagesize ==PAGE_SIZE && !force_pte) {if (fault_is_perm && fault_granule >PAGE_SIZE ) vma_pagesize = fault_granule;else
Signature · 1 line
2.53.0