Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
db3b4ca
mm: introduce ARCH_SUPPORTS_HUGE_PFNMAP and special bits to pmd/pud
PlaidCat Jul 15, 2025
aececef
mm: drop is_huge_zero_pud()
PlaidCat Jul 15, 2025
f5dec21
mm: mark special bits for huge pfn mappings when inject
PlaidCat Jul 15, 2025
95c222a
mm/gup: detect huge pfnmap entries in gup-fast
PlaidCat Jul 15, 2025
76f066c
mm/pagewalk: check pfnmap for folio_walk_start()
PlaidCat Jul 15, 2025
0aae8b4
mm/fork: accept huge pfnmap entries
PlaidCat Jul 15, 2025
bfd3c70
mm/huge_memory: check pmd_special() only after pmd_present()
PlaidCat Jul 15, 2025
1361da3
mm: always define pxx_pgprot()
PlaidCat Jul 15, 2025
50d5012
mm: remove follow_pfn
PlaidCat Jul 15, 2025
1117214
mm: new follow_pfnmap API
PlaidCat Jul 15, 2025
9ee6edd
mm: fix follow_pfnmap API lockdep assert
PlaidCat Jul 15, 2025
a9e0603
mm: move follow_phys to arch/x86/mm/pat/memtype.c
PlaidCat Jul 15, 2025
e64e7d7
mm: pass VMA instead of MM to follow_pte()
PlaidCat Jul 15, 2025
ce993ca
KVM: use follow_pfnmap API
PlaidCat Jul 15, 2025
43f37c3
s390/pci_mmio: use follow_pfnmap API
PlaidCat Jul 15, 2025
ced875c
mm/x86/pat: use the new follow_pfnmap API
PlaidCat Jul 15, 2025
5f19a10
vfio: use the new follow_pfnmap API
PlaidCat Jul 15, 2025
f3963f6
mm/access_process_vm: use the new follow_pfnmap API
PlaidCat Jul 15, 2025
5de61c7
mm: follow_pte() improvements
PlaidCat Jul 15, 2025
7eb43fb
mm: remove follow_pte()
PlaidCat Jul 15, 2025
37c3a64
mm/x86: support large pfn mappings
PlaidCat Jul 15, 2025
42ad41e
mm/arm64: support large pfn mappings
PlaidCat Jul 15, 2025
43c17b5
vfio/pci: implement huge_fault support
PlaidCat Jul 15, 2025
a19d26d
vfio/pci: Fallback huge faults for unaligned pfn
PlaidCat Jul 15, 2025
ce902cc
vfio/type1: Catch zero from pin_user_pages_remote()
PlaidCat Jul 15, 2025
7ce8549
vfio/type1: Convert all vaddr_get_pfns() callers to use vfio_batch
PlaidCat Jul 15, 2025
258edb7
vfio/type1: Use vfio_batch for vaddr_get_pfns()
PlaidCat Jul 15, 2025
6987ff5
vfio/type1: Use consistent types for page counts
PlaidCat Jul 15, 2025
a72ae6f
mm: Provide address mask in struct follow_pfnmap_args
PlaidCat Jul 15, 2025
d844479
vfio/type1: Use mapping page mask for pfnmaps
PlaidCat Jul 15, 2025
cec3aae
vfio/pci: Align huge faults to order
PlaidCat Jul 15, 2025
123e6c2
Fix mmu notifiers for range-based invalidates
PlaidCat Jul 15, 2025
10ebde9
smb3 client: fix open hardlink on deferred close file error
PlaidCat Jul 15, 2025
d384cc1
smb: client: fix perf regression with deferred closes
PlaidCat Jul 15, 2025
432f1ba
cpufreq: intel_pstate: Unchecked MSR aceess in legacy mode
PlaidCat Jul 15, 2025
88a999f
x86/microcode/AMD: Fix out-of-bounds on systems with CPU-less NUMA nodes
PlaidCat Jul 15, 2025
8cc6f28
Rebuild rocky9_6 with kernel-5.14.0-570.26.1.el9_6
PlaidCat Jul 15, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
File renamed without changes.
2 changes: 1 addition & 1 deletion Makefile.rhelver
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ RHEL_MINOR = 6
#
# Use this spot to avoid future merge conflicts.
# Do not trim this comment.
RHEL_RELEASE = 570.25.1
RHEL_RELEASE = 570.26.1

#
# ZSTREAM
Expand Down
1 change: 1 addition & 0 deletions arch/arm64/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,7 @@ config ARM64
select ARCH_SUPPORTS_NUMA_BALANCING
select ARCH_SUPPORTS_PAGE_TABLE_CHECK
select ARCH_SUPPORTS_PER_VMA_LOCK
select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
select ARCH_SUPPORTS_RT
select ARCH_WANT_BATCHED_UNMAP_TLB_FLUSH
select ARCH_WANT_COMPAT_IPC_PARSE_VERSION if COMPAT
Expand Down
30 changes: 30 additions & 0 deletions arch/arm64/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@ static inline void __sync_cache_and_tags(pte_t pte, unsigned int nr_pages)
/*
* Select all bits except the pfn
*/
#define pte_pgprot pte_pgprot
static inline pgprot_t pte_pgprot(pte_t pte)
{
unsigned long pfn = pte_pfn(pte);
Expand Down Expand Up @@ -527,6 +528,14 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
return pte_pmd(set_pte_bit(pmd_pte(pmd), __pgprot(PTE_DEVMAP)));
}

#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
#define pmd_special(pte) (!!((pmd_val(pte) & PTE_SPECIAL)))
static inline pmd_t pmd_mkspecial(pmd_t pmd)
{
return set_pmd_bit(pmd, __pgprot(PTE_SPECIAL));
}
#endif

#define __pmd_to_phys(pmd) __pte_to_phys(pmd_pte(pmd))
#define __phys_to_pmd_val(phys) __phys_to_pte_val(phys)
#define pmd_pfn(pmd) ((__pmd_to_phys(pmd) & PMD_MASK) >> PAGE_SHIFT)
Expand All @@ -544,6 +553,27 @@ static inline pmd_t pmd_mkdevmap(pmd_t pmd)
#define pud_pfn(pud) ((__pud_to_phys(pud) & PUD_MASK) >> PAGE_SHIFT)
#define pfn_pud(pfn,prot) __pud(__phys_to_pud_val((phys_addr_t)(pfn) << PAGE_SHIFT) | pgprot_val(prot))

#ifdef CONFIG_ARCH_SUPPORTS_PUD_PFNMAP
#define pud_special(pte) pte_special(pud_pte(pud))
#define pud_mkspecial(pte) pte_pud(pte_mkspecial(pud_pte(pud)))
#endif

#define pmd_pgprot pmd_pgprot
static inline pgprot_t pmd_pgprot(pmd_t pmd)
{
unsigned long pfn = pmd_pfn(pmd);

return __pgprot(pmd_val(pfn_pmd(pfn, __pgprot(0))) ^ pmd_val(pmd));
}

#define pud_pgprot pud_pgprot
static inline pgprot_t pud_pgprot(pud_t pud)
{
unsigned long pfn = pud_pfn(pud);

return __pgprot(pud_val(pfn_pud(pfn, __pgprot(0))) ^ pud_val(pud));
}

static inline void __set_pte_at(struct mm_struct *mm,
unsigned long __always_unused addr,
pte_t *ptep, pte_t pte, unsigned int nr)
Expand Down
22 changes: 12 additions & 10 deletions arch/arm64/include/asm/tlbflush.h
Original file line number Diff line number Diff line change
Expand Up @@ -396,33 +396,35 @@ static inline void arch_tlbbatch_flush(struct arch_tlbflush_unmap_batch *batch)
#define __flush_tlb_range_op(op, start, pages, stride, \
asid, tlb_level, tlbi_user, lpa2) \
do { \
typeof(start) __flush_start = start; \
typeof(pages) __flush_pages = pages; \
int num = 0; \
int scale = 3; \
int shift = lpa2 ? 16 : PAGE_SHIFT; \
unsigned long addr; \
\
while (pages > 0) { \
while (__flush_pages > 0) { \
if (!system_supports_tlb_range() || \
pages == 1 || \
(lpa2 && start != ALIGN(start, SZ_64K))) { \
addr = __TLBI_VADDR(start, asid); \
__flush_pages == 1 || \
(lpa2 && __flush_start != ALIGN(__flush_start, SZ_64K))) { \
addr = __TLBI_VADDR(__flush_start, asid); \
__tlbi_level(op, addr, tlb_level); \
if (tlbi_user) \
__tlbi_user_level(op, addr, tlb_level); \
start += stride; \
pages -= stride >> PAGE_SHIFT; \
__flush_start += stride; \
__flush_pages -= stride >> PAGE_SHIFT; \
continue; \
} \
\
num = __TLBI_RANGE_NUM(pages, scale); \
num = __TLBI_RANGE_NUM(__flush_pages, scale); \
if (num >= 0) { \
addr = __TLBI_VADDR_RANGE(start >> shift, asid, \
addr = __TLBI_VADDR_RANGE(__flush_start >> shift, asid, \
scale, num, tlb_level); \
__tlbi(r##op, addr); \
if (tlbi_user) \
__tlbi_user(r##op, addr); \
start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \
pages -= __TLBI_RANGE_PAGES(num, scale); \
__flush_start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; \
__flush_pages -= __TLBI_RANGE_PAGES(num, scale);\
} \
scale--; \
} \
Expand Down
1 change: 1 addition & 0 deletions arch/powerpc/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ static inline unsigned long pte_pfn(pte_t pte)
/*
* Select all bits except the pfn
*/
#define pte_pgprot pte_pgprot
static inline pgprot_t pte_pgprot(pte_t pte)
{
unsigned long pte_flags;
Expand Down
1 change: 1 addition & 0 deletions arch/s390/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -941,6 +941,7 @@ static inline int pte_unused(pte_t pte)
* young/old accounting is not supported, i.e _PAGE_PROTECT and _PAGE_INVALID
* must not be set.
*/
#define pte_pgprot pte_pgprot
static inline pgprot_t pte_pgprot(pte_t pte)
{
unsigned long pte_flags = pte_val(pte) & _PAGE_CHG_MASK;
Expand Down
22 changes: 12 additions & 10 deletions arch/s390/pci/pci_mmio.c
Original file line number Diff line number Diff line change
Expand Up @@ -118,12 +118,11 @@ static inline int __memcpy_toio_inuser(void __iomem *dst,
SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
const void __user *, user_buffer, size_t, length)
{
struct follow_pfnmap_args args = { };
u8 local_buf[64];
void __iomem *io_addr;
void *buf;
struct vm_area_struct *vma;
pte_t *ptep;
spinlock_t *ptl;
long ret;

if (!zpci_is_enabled())
Expand Down Expand Up @@ -169,19 +168,21 @@ SYSCALL_DEFINE3(s390_pci_mmio_write, unsigned long, mmio_addr,
if (!(vma->vm_flags & VM_WRITE))
goto out_unlock_mmap;

ret = follow_pte(vma->vm_mm, mmio_addr, &ptep, &ptl);
args.address = mmio_addr;
args.vma = vma;
ret = follow_pfnmap_start(&args);
if (ret)
goto out_unlock_mmap;

io_addr = (void __iomem *)((pte_pfn(*ptep) << PAGE_SHIFT) |
io_addr = (void __iomem *)((args.pfn << PAGE_SHIFT) |
(mmio_addr & ~PAGE_MASK));

if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE)
goto out_unlock_pt;

ret = zpci_memcpy_toio(io_addr, buf, length);
out_unlock_pt:
pte_unmap_unlock(ptep, ptl);
follow_pfnmap_end(&args);
out_unlock_mmap:
mmap_read_unlock(current->mm);
out_free:
Expand Down Expand Up @@ -260,12 +261,11 @@ static inline int __memcpy_fromio_inuser(void __user *dst,
SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
void __user *, user_buffer, size_t, length)
{
struct follow_pfnmap_args args = { };
u8 local_buf[64];
void __iomem *io_addr;
void *buf;
struct vm_area_struct *vma;
pte_t *ptep;
spinlock_t *ptl;
long ret;

if (!zpci_is_enabled())
Expand Down Expand Up @@ -308,11 +308,13 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
if (!(vma->vm_flags & VM_WRITE))
goto out_unlock_mmap;

ret = follow_pte(vma->vm_mm, mmio_addr, &ptep, &ptl);
args.vma = vma;
args.address = mmio_addr;
ret = follow_pfnmap_start(&args);
if (ret)
goto out_unlock_mmap;

io_addr = (void __iomem *)((pte_pfn(*ptep) << PAGE_SHIFT) |
io_addr = (void __iomem *)((args.pfn << PAGE_SHIFT) |
(mmio_addr & ~PAGE_MASK));

if ((unsigned long) io_addr < ZPCI_IOMAP_ADDR_BASE) {
Expand All @@ -322,7 +324,7 @@ SYSCALL_DEFINE3(s390_pci_mmio_read, unsigned long, mmio_addr,
ret = zpci_memcpy_fromio(buf, io_addr, length);

out_unlock_pt:
pte_unmap_unlock(ptep, ptl);
follow_pfnmap_end(&args);
out_unlock_mmap:
mmap_read_unlock(current->mm);

Expand Down
1 change: 1 addition & 0 deletions arch/sparc/include/asm/pgtable_64.h
Original file line number Diff line number Diff line change
Expand Up @@ -782,6 +782,7 @@ static inline pmd_t pmd_mkwrite_novma(pmd_t pmd)
return __pmd(pte_val(pte));
}

#define pmd_pgprot pmd_pgprot
static inline pgprot_t pmd_pgprot(pmd_t entry)
{
unsigned long val = pmd_val(entry);
Expand Down
1 change: 1 addition & 0 deletions arch/x86/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ config X86_64
select ARCH_HAS_GIGANTIC_PAGE
select ARCH_SUPPORTS_INT128 if CC_HAS_INT128
select ARCH_SUPPORTS_PER_VMA_LOCK
select ARCH_SUPPORTS_HUGE_PFNMAP if TRANSPARENT_HUGEPAGE
select ARCH_SUPPORTS_RT
select HAVE_ARCH_SOFT_DIRTY
select MODULES_USE_ELF_RELA
Expand Down
80 changes: 52 additions & 28 deletions arch/x86/include/asm/pgtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,34 @@ extern pmdval_t early_pmd_flags;
#define arch_end_context_switch(prev) do {} while(0)
#endif /* CONFIG_PARAVIRT_XXL */

static inline pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set)
{
pmdval_t v = native_pmd_val(pmd);

return native_make_pmd(v | set);
}

static inline pmd_t pmd_clear_flags(pmd_t pmd, pmdval_t clear)
{
pmdval_t v = native_pmd_val(pmd);

return native_make_pmd(v & ~clear);
}

static inline pud_t pud_set_flags(pud_t pud, pudval_t set)
{
pudval_t v = native_pud_val(pud);

return native_make_pud(v | set);
}

static inline pud_t pud_clear_flags(pud_t pud, pudval_t clear)
{
pudval_t v = native_pud_val(pud);

return native_make_pud(v & ~clear);
}

/*
* The following only work if pte_present() is true.
* Undefined behaviour if not..
Expand Down Expand Up @@ -310,6 +338,30 @@ static inline int pud_devmap(pud_t pud)
}
#endif

#ifdef CONFIG_ARCH_SUPPORTS_PMD_PFNMAP
static inline bool pmd_special(pmd_t pmd)
{
return pmd_flags(pmd) & _PAGE_SPECIAL;
}

static inline pmd_t pmd_mkspecial(pmd_t pmd)
{
return pmd_set_flags(pmd, _PAGE_SPECIAL);
}
#endif /* CONFIG_ARCH_SUPPORTS_PMD_PFNMAP */

#ifdef CONFIG_ARCH_SUPPORTS_PUD_PFNMAP
static inline bool pud_special(pud_t pud)
{
return pud_flags(pud) & _PAGE_SPECIAL;
}

static inline pud_t pud_mkspecial(pud_t pud)
{
return pud_set_flags(pud, _PAGE_SPECIAL);
}
#endif /* CONFIG_ARCH_SUPPORTS_PUD_PFNMAP */

static inline int pgd_devmap(pgd_t pgd)
{
return 0;
Expand Down Expand Up @@ -480,20 +532,6 @@ static inline pte_t pte_mkdevmap(pte_t pte)
return pte_set_flags(pte, _PAGE_SPECIAL|_PAGE_DEVMAP);
}

static inline pmd_t pmd_set_flags(pmd_t pmd, pmdval_t set)
{
pmdval_t v = native_pmd_val(pmd);

return native_make_pmd(v | set);
}

static inline pmd_t pmd_clear_flags(pmd_t pmd, pmdval_t clear)
{
pmdval_t v = native_pmd_val(pmd);

return native_make_pmd(v & ~clear);
}

/* See comments above mksaveddirty_shift() */
static inline pmd_t pmd_mksaveddirty(pmd_t pmd)
{
Expand Down Expand Up @@ -588,20 +626,6 @@ static inline pmd_t pmd_mkwrite_novma(pmd_t pmd)
pmd_t pmd_mkwrite(pmd_t pmd, struct vm_area_struct *vma);
#define pmd_mkwrite pmd_mkwrite

static inline pud_t pud_set_flags(pud_t pud, pudval_t set)
{
pudval_t v = native_pud_val(pud);

return native_make_pud(v | set);
}

static inline pud_t pud_clear_flags(pud_t pud, pudval_t clear)
{
pudval_t v = native_pud_val(pud);

return native_make_pud(v & ~clear);
}

/* See comments above mksaveddirty_shift() */
static inline pud_t pud_mksaveddirty(pud_t pud)
{
Expand Down
2 changes: 1 addition & 1 deletion arch/x86/kernel/cpu/microcode/amd.c
Original file line number Diff line number Diff line change
Expand Up @@ -834,7 +834,7 @@ static enum ucode_state load_microcode_amd(u8 family, const u8 *data, size_t siz
return ret;
}

for_each_node(nid) {
for_each_node_with_cpus(nid) {
cpu = cpumask_first(cpumask_of_node(nid));
c = &cpu_data(cpu);

Expand Down
23 changes: 22 additions & 1 deletion arch/x86/mm/pat/memtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
#include <linux/pfn_t.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/highmem.h>
#include <linux/fs.h>
#include <linux/rbtree.h>

Expand Down Expand Up @@ -947,6 +948,26 @@ static void free_pfn_range(u64 paddr, unsigned long size)
memtype_free(paddr, paddr + size);
}

static int follow_phys(struct vm_area_struct *vma, unsigned long *prot,
resource_size_t *phys)
{
struct follow_pfnmap_args args = { .vma = vma, .address = vma->vm_start };

if (follow_pfnmap_start(&args))
return -EINVAL;

/* Never return PFNs of anon folios in COW mappings. */
if (!args.special) {
follow_pfnmap_end(&args);
return -EINVAL;
}

*prot = pgprot_val(args.pgprot);
*phys = (resource_size_t)args.pfn << PAGE_SHIFT;
follow_pfnmap_end(&args);
return 0;
}

static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr,
pgprot_t *pgprot)
{
Expand All @@ -964,7 +985,7 @@ static int get_pat_info(struct vm_area_struct *vma, resource_size_t *paddr,
* detect the PFN. If we need the cachemode as well, we're out of luck
* for now and have to fail fork().
*/
if (!follow_phys(vma, vma->vm_start, 0, &prot, paddr)) {
if (!follow_phys(vma, &prot, paddr)) {
if (pgprot)
*pgprot = __pgprot(prot);
return 0;
Expand Down
Loading