mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-09-01 15:14:52 +00:00

Convert page_table_check_p[mu]d_set(...) to page_table_check_p[mu]ds_set(..., nr) to allow checking a contiguous set of pmds/puds in single batch. We retain page_table_check_p[mu]d_set(...) as macros that call new batch functions with nr=1 for compatibility. arm64 is about to reorganise its pte/pmd/pud helpers to reuse more code and to allow the implementation for huge_pte to more efficiently set ptes/pmds/puds in batches. We need these batch-helpers to make the refactoring possible. Reviewed-by: Anshuman Khandual <anshuman.khandual@arm.com> Reviewed-by: Pasha Tatashin <pasha.tatashin@soleen.com> Reviewed-by: Catalin Marinas <catalin.marinas@arm.com> Signed-off-by: Ryan Roberts <ryan.roberts@arm.com> Tested-by: Luiz Capitulino <luizcap@redhat.com> Link: https://lore.kernel.org/r/20250422081822.1836315-4-ryan.roberts@arm.com Signed-off-by: Will Deacon <will@kernel.org>
156 lines
4.0 KiB
C
156 lines
4.0 KiB
C
/* SPDX-License-Identifier: GPL-2.0 */
|
|
|
|
/*
|
|
* Copyright (c) 2021, Google LLC.
|
|
* Pasha Tatashin <pasha.tatashin@soleen.com>
|
|
*/
|
|
#ifndef __LINUX_PAGE_TABLE_CHECK_H
|
|
#define __LINUX_PAGE_TABLE_CHECK_H
|
|
|
|
#ifdef CONFIG_PAGE_TABLE_CHECK
|
|
#include <linux/jump_label.h>
|
|
|
|
extern struct static_key_true page_table_check_disabled;
|
|
extern struct page_ext_operations page_table_check_ops;
|
|
|
|
void __page_table_check_zero(struct page *page, unsigned int order);
|
|
void __page_table_check_pte_clear(struct mm_struct *mm, pte_t pte);
|
|
void __page_table_check_pmd_clear(struct mm_struct *mm, pmd_t pmd);
|
|
void __page_table_check_pud_clear(struct mm_struct *mm, pud_t pud);
|
|
void __page_table_check_ptes_set(struct mm_struct *mm, pte_t *ptep, pte_t pte,
|
|
unsigned int nr);
|
|
void __page_table_check_pmds_set(struct mm_struct *mm, pmd_t *pmdp, pmd_t pmd,
|
|
unsigned int nr);
|
|
void __page_table_check_puds_set(struct mm_struct *mm, pud_t *pudp, pud_t pud,
|
|
unsigned int nr);
|
|
void __page_table_check_pte_clear_range(struct mm_struct *mm,
|
|
unsigned long addr,
|
|
pmd_t pmd);
|
|
|
|
static inline void page_table_check_alloc(struct page *page, unsigned int order)
|
|
{
|
|
if (static_branch_likely(&page_table_check_disabled))
|
|
return;
|
|
|
|
__page_table_check_zero(page, order);
|
|
}
|
|
|
|
static inline void page_table_check_free(struct page *page, unsigned int order)
|
|
{
|
|
if (static_branch_likely(&page_table_check_disabled))
|
|
return;
|
|
|
|
__page_table_check_zero(page, order);
|
|
}
|
|
|
|
static inline void page_table_check_pte_clear(struct mm_struct *mm, pte_t pte)
|
|
{
|
|
if (static_branch_likely(&page_table_check_disabled))
|
|
return;
|
|
|
|
__page_table_check_pte_clear(mm, pte);
|
|
}
|
|
|
|
static inline void page_table_check_pmd_clear(struct mm_struct *mm, pmd_t pmd)
|
|
{
|
|
if (static_branch_likely(&page_table_check_disabled))
|
|
return;
|
|
|
|
__page_table_check_pmd_clear(mm, pmd);
|
|
}
|
|
|
|
static inline void page_table_check_pud_clear(struct mm_struct *mm, pud_t pud)
|
|
{
|
|
if (static_branch_likely(&page_table_check_disabled))
|
|
return;
|
|
|
|
__page_table_check_pud_clear(mm, pud);
|
|
}
|
|
|
|
static inline void page_table_check_ptes_set(struct mm_struct *mm,
|
|
pte_t *ptep, pte_t pte, unsigned int nr)
|
|
{
|
|
if (static_branch_likely(&page_table_check_disabled))
|
|
return;
|
|
|
|
__page_table_check_ptes_set(mm, ptep, pte, nr);
|
|
}
|
|
|
|
static inline void page_table_check_pmds_set(struct mm_struct *mm,
|
|
pmd_t *pmdp, pmd_t pmd, unsigned int nr)
|
|
{
|
|
if (static_branch_likely(&page_table_check_disabled))
|
|
return;
|
|
|
|
__page_table_check_pmds_set(mm, pmdp, pmd, nr);
|
|
}
|
|
|
|
static inline void page_table_check_puds_set(struct mm_struct *mm,
|
|
pud_t *pudp, pud_t pud, unsigned int nr)
|
|
{
|
|
if (static_branch_likely(&page_table_check_disabled))
|
|
return;
|
|
|
|
__page_table_check_puds_set(mm, pudp, pud, nr);
|
|
}
|
|
|
|
static inline void page_table_check_pte_clear_range(struct mm_struct *mm,
|
|
unsigned long addr,
|
|
pmd_t pmd)
|
|
{
|
|
if (static_branch_likely(&page_table_check_disabled))
|
|
return;
|
|
|
|
__page_table_check_pte_clear_range(mm, addr, pmd);
|
|
}
|
|
|
|
#else
|
|
|
|
static inline void page_table_check_alloc(struct page *page, unsigned int order)
|
|
{
|
|
}
|
|
|
|
static inline void page_table_check_free(struct page *page, unsigned int order)
|
|
{
|
|
}
|
|
|
|
static inline void page_table_check_pte_clear(struct mm_struct *mm, pte_t pte)
|
|
{
|
|
}
|
|
|
|
static inline void page_table_check_pmd_clear(struct mm_struct *mm, pmd_t pmd)
|
|
{
|
|
}
|
|
|
|
static inline void page_table_check_pud_clear(struct mm_struct *mm, pud_t pud)
|
|
{
|
|
}
|
|
|
|
static inline void page_table_check_ptes_set(struct mm_struct *mm,
|
|
pte_t *ptep, pte_t pte, unsigned int nr)
|
|
{
|
|
}
|
|
|
|
static inline void page_table_check_pmds_set(struct mm_struct *mm,
|
|
pmd_t *pmdp, pmd_t pmd, unsigned int nr)
|
|
{
|
|
}
|
|
|
|
static inline void page_table_check_puds_set(struct mm_struct *mm,
|
|
pud_t *pudp, pud_t pud, unsigned int nr)
|
|
{
|
|
}
|
|
|
|
static inline void page_table_check_pte_clear_range(struct mm_struct *mm,
|
|
unsigned long addr,
|
|
pmd_t pmd)
|
|
{
|
|
}
|
|
|
|
#endif /* CONFIG_PAGE_TABLE_CHECK */
|
|
|
|
#define page_table_check_pmd_set(mm, pmdp, pmd) page_table_check_pmds_set(mm, pmdp, pmd, 1)
|
|
#define page_table_check_pud_set(mm, pudp, pud) page_table_check_puds_set(mm, pudp, pud, 1)
|
|
|
|
#endif /* __LINUX_PAGE_TABLE_CHECK_H */
|