Skip to content

Commit e9b39cc

Browse files
committed
mm/arm64: support large pfn mappings
JIRA: https://issues.redhat.com/browse/RHEL-73613 commit 3e509c9 Author: Peter Xu <peterx@redhat.com> Date: Mon Aug 26 16:43:52 2024 -0400 mm/arm64: support large pfn mappings Support huge pfnmaps by using bit 56 (PTE_SPECIAL) for "special" on pmds/puds. Provide the pmd/pud helpers to set/get special bit. There's one more thing missing for arm64 which is the pxx_pgprot() for pmd/pud. Add them too, which is mostly the same as the pte version by dropping the pfn field. These helpers are essential to be used in the new follow_pfnmap*() API to report valid pgprot_t results. Note that arm64 doesn't yet support huge PUD yet, but it's still straightforward to provide the pud helpers that we need altogether. Only PMD helpers will make an immediate benefit until arm64 will support huge PUDs first in general (e.g. in THPs). Link: https://lkml.kernel.org/r/20240826204353.2228736-19-peterx@redhat.com Signed-off-by: Peter Xu <peterx@redhat.com> Cc: Catalin Marinas <catalin.marinas@arm.com> Cc: Will Deacon <will@kernel.org> Cc: Alexander Gordeev <agordeev@linux.ibm.com> Cc: Alex Williamson <alex.williamson@redhat.com> Cc: Aneesh Kumar K.V <aneesh.kumar@linux.ibm.com> Cc: Borislav Petkov <bp@alien8.de> Cc: Christian Borntraeger <borntraeger@linux.ibm.com> Cc: Dave Hansen <dave.hansen@linux.intel.com> Cc: David Hildenbrand <david@redhat.com> Cc: Gavin Shan <gshan@redhat.com> Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com> Cc: Heiko Carstens <hca@linux.ibm.com> Cc: Ingo Molnar <mingo@redhat.com> Cc: Jason Gunthorpe <jgg@nvidia.com> Cc: Matthew Wilcox <willy@infradead.org> Cc: Niklas Schnelle <schnelle@linux.ibm.com> Cc: Paolo Bonzini <pbonzini@redhat.com> Cc: Ryan Roberts <ryan.roberts@arm.com> Cc: Sean Christopherson <seanjc@google.com> Cc: Sven Schnelle <svens@linux.ibm.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Vasily Gorbik <gor@linux.ibm.com> Cc: Zi Yan <ziy@nvidia.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Donald Dutile <ddutile@redhat.com>
1 parent f884ae0 commit e9b39cc

File tree

2 files changed

+30
-0
lines changed

2 files changed

+30
-0
lines changed

arch/arm64/Kconfig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ config ARM64
9797
select ARCH_SUPPORTS_NUMA_BALANCING
9898
select ARCH_SUPPORTS_PAGE_TABLE_CHECK
9999
select ARCH_SUPPORTS_PER_VMA_LOCK
100+
select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
100101
select ARCH_SUPPORTS_RT
101102
select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
102103
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT

arch/arm64/include/asm/pgtable.h

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,14 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
528528
return pte_pmd(set_pte_bit(pmd_pte(pmd), __pgprot(PTE_DEVMAP)));
529529
}
530530

531+
#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
532+
#define pmd_special(pte) (!!((pmd_val(pte) & PTE_SPECIAL)))
533+
static inline pmd_t pmd_mkspecial(pmd_t pmd)
534+
{
535+
return set_pmd_bit(pmd, __pgprot(PTE_SPECIAL));
536+
}
537+
#endif
538+
531539
#define __pmd_to_phys(pmd) __pte_to_phys(pmd_pte(pmd))
532540
#define __phys_to_pmd_val(phys) __phys_to_pte_val(phys)
533541
#define pmd_pfn(pmd) ((__pmd_to_phys(pmd) & PMD_MASK) >> PAGE_SHIFT)
@@ -545,6 +553,27 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
545553
#define pud_pfn(pud) ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT)
546554
#define pfn_pud(pfn,prot) __pud(__phys_to_pud_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))
547555

556+
#ifdef CONFIG_ARCH_SUPPORTS_PUD_PFNMAP
557+
#define pud_special(pte) pte_special(pud_pte(pud))
558+
#define pud_mkspecial(pte) pte_pud(pte_mkspecial(pud_pte(pud)))
559+
#endif
560+
561+
#define pmd_pgprot pmd_pgprot
562+
static inline pgprot_t pmd_pgprot(pmd_t pmd)
563+
{
564+
unsigned long pfn = pmd_pfn(pmd);
565+
566+
return __pgprot(pmd_val(pfn_pmd(pfn, __pgprot(0))) ^ pmd_val(pmd));
567+
}
568+
569+
#define pud_pgprot pud_pgprot
570+
static inline pgprot_t pud_pgprot(pud_t pud)
571+
{
572+
unsigned long pfn = pud_pfn(pud);
573+
574+
return __pgprot(pud_val(pfn_pud(pfn, __pgprot(0))) ^ pud_val(pud));
575+
}
576+
548577
static inline void __set_pte_at(struct mm_struct *mm,
549578
unsigned long __always_unused addr,
550579
pte_t *ptep, pte_t pte, unsigned int nr)

0 commit comments

Comments
 (0)