Skip to content

Commit 8b5cb1c

Browse files
lienzechenhuacai
authored andcommitted
LoongArch: mm: Add page table mapped mode support for virt_to_page()
According to LoongArch documentations, there are two types of address translation modes: direct mapped address translation mode (DMW mode) and page table mapped address translation mode (TLB mode). Currently, virt_to_page() only supports direct mapped mode. This patch determines which mode is used, and adds corresponding handling functions for both modes. For more details on the two modes, see [1]. [1] https://loongson.github.io/LoongArch-Documentation/LoongArch-Vol1-EN.html#virtual-address-space-and-address-translation-mode Signed-off-by: Enze Li <lienze@kylinos.cn> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn>
1 parent ec9fee7 commit 8b5cb1c

File tree

3 files changed

+21
-1
lines changed

3 files changed

+21
-1
lines changed

arch/loongarch/include/asm/page.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,12 @@ typedef struct { unsigned long pgprot; } pgprot_t;
8484
#define sym_to_pfn(x) __phys_to_pfn(__pa_symbol(x))
8585

8686
#define virt_to_pfn(kaddr) PFN_DOWN(PHYSADDR(kaddr))
87-
#define virt_to_page(kaddr) pfn_to_page(virt_to_pfn(kaddr))
87+
88+
#define virt_to_page(kaddr) \
89+
({ \
90+
(likely((unsigned long)kaddr < vm_map_base)) ? \
91+
dmw_virt_to_page((unsigned long)kaddr) : tlb_virt_to_page((unsigned long)kaddr);\
92+
})
8893

8994
extern int __virt_addr_valid(volatile void *kaddr);
9095
#define virt_addr_valid(kaddr) __virt_addr_valid((volatile void *)(kaddr))

arch/loongarch/include/asm/pgtable.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,9 @@ static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *pt
353353
extern pgd_t swapper_pg_dir[];
354354
extern pgd_t invalid_pg_dir[];
355355

356+
struct page *dmw_virt_to_page(unsigned long kaddr);
357+
struct page *tlb_virt_to_page(unsigned long kaddr);
358+
356359
/*
357360
* The following only work if pte_present() is true.
358361
* Undefined behaviour if not..

arch/loongarch/mm/pgtable.c

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,18 @@
99
#include <asm/pgtable.h>
1010
#include <asm/tlbflush.h>
1111

12+
struct page *dmw_virt_to_page(unsigned long kaddr)
13+
{
14+
return pfn_to_page(virt_to_pfn(kaddr));
15+
}
16+
EXPORT_SYMBOL_GPL(dmw_virt_to_page);
17+
18+
struct page *tlb_virt_to_page(unsigned long kaddr)
19+
{
20+
return pfn_to_page(pte_pfn(*virt_to_kpte(kaddr)));
21+
}
22+
EXPORT_SYMBOL_GPL(tlb_virt_to_page);
23+
1224
pgd_t *pgd_alloc(struct mm_struct *mm)
1325
{
1426
pgd_t *ret, *init;

0 commit comments

Comments
 (0)