From b14c0ca10299ece15f63861f808d305e2e2caf8e Mon Sep 17 00:00:00 2001 From: Pawel Wieczorkiewicz Date: Wed, 19 Jan 2022 15:26:09 +0100 Subject: [PATCH 1/3] pagetables: remove redundant kunmap(), make vunmap() return void Signed-off-by: Pawel Wieczorkiewicz --- arch/x86/pagetables.c | 10 ++-------- common/acpi.c | 2 +- drivers/acpi/acpica/osl.c | 2 +- include/arch/x86/page.h | 3 +-- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/arch/x86/pagetables.c b/arch/x86/pagetables.c index 12b9f880..6b52e42f 100644 --- a/arch/x86/pagetables.c +++ b/arch/x86/pagetables.c @@ -201,9 +201,8 @@ void *vmap(void *va, mfn_t mfn, unsigned int order, return va; } -void *vunmap(void *va, unsigned int order) { - return vmap(va, MFN_INVALID, order, PT_NO_FLAGS, PT_NO_FLAGS, PT_NO_FLAGS, - PT_NO_FLAGS); +void vunmap(void *va, unsigned int order) { + vmap(va, MFN_INVALID, order, PT_NO_FLAGS, PT_NO_FLAGS, PT_NO_FLAGS, PT_NO_FLAGS); } void *kmap(mfn_t mfn, unsigned int order, @@ -218,11 +217,6 @@ void *kmap(mfn_t mfn, unsigned int order, l3_flags, l2_flags, l1_flags); } -void *kunmap(void *va, unsigned int order) { - return vmap(va, MFN_INVALID, order, PT_NO_FLAGS, PT_NO_FLAGS, PT_NO_FLAGS, - PT_NO_FLAGS); -} - void init_pagetables(void) { for_each_memory_range (r) { switch (r->base) { diff --git a/common/acpi.c b/common/acpi.c index 9dfcd2b6..f72d4ae4 100644 --- a/common/acpi.c +++ b/common/acpi.c @@ -154,7 +154,7 @@ static void acpi_table_unmap_pages(void *addr, unsigned mapped_pages) { mfn_t mfn = virt_to_mfn(addr); for (unsigned i = 0; i < mapped_pages; i++, mfn++) { - kunmap(mfn_to_virt_kern(mfn), PAGE_ORDER_4K); + vunmap(mfn_to_virt_kern(mfn), PAGE_ORDER_4K); } } diff --git a/drivers/acpi/acpica/osl.c b/drivers/acpi/acpica/osl.c index cfa7cbef..fac4be24 100644 --- a/drivers/acpi/acpica/osl.c +++ b/drivers/acpi/acpica/osl.c @@ -270,7 +270,7 @@ void AcpiOsUnmapMemory(void *LogicalAddress, ACPI_SIZE Length) { mfn_t mfn = virt_to_mfn(LogicalAddress); for (unsigned i = 0; i < num_pages; i++, mfn++) - kunmap(mfn_to_virt_kern(mfn), PAGE_ORDER_4K); + vunmap(mfn_to_virt_kern(mfn), PAGE_ORDER_4K); } /* Task management functions */ diff --git a/include/arch/x86/page.h b/include/arch/x86/page.h index 40b767fa..5b0a13d4 100644 --- a/include/arch/x86/page.h +++ b/include/arch/x86/page.h @@ -139,14 +139,13 @@ extern void *vmap(void *va, mfn_t mfn, unsigned int order, unsigned long l4_flags, #endif unsigned long l3_flags, unsigned long l2_flags, unsigned long l1_flags); -extern void *vunmap(void *va, unsigned int order); extern void *kmap(mfn_t mfn, unsigned int order, #if defined(__x86_64__) unsigned long l4_flags, #endif unsigned long l3_flags, unsigned long l2_flags, unsigned long l1_flags); -extern void *kunmap(void *va, unsigned int order); +extern void vunmap(void *va, unsigned int order); /* Static declarations */ From 0a91b08bc63e75b29462727d110b32203e2b784f Mon Sep 17 00:00:00 2001 From: Pawel Wieczorkiewicz Date: Wed, 19 Jan 2022 15:36:15 +0100 Subject: [PATCH 2/3] pagetables: make kmap() static inline Signed-off-by: Pawel Wieczorkiewicz --- arch/x86/pagetables.c | 12 ------------ include/arch/x86/page.h | 18 +++++++++++++----- 2 files changed, 13 insertions(+), 17 deletions(-) diff --git a/arch/x86/pagetables.c b/arch/x86/pagetables.c index 6b52e42f..cf3da855 100644 --- a/arch/x86/pagetables.c +++ b/arch/x86/pagetables.c @@ -205,18 +205,6 @@ void vunmap(void *va, unsigned int order) { vmap(va, MFN_INVALID, order, PT_NO_FLAGS, PT_NO_FLAGS, PT_NO_FLAGS, PT_NO_FLAGS); } -void *kmap(mfn_t mfn, unsigned int order, -#if defined(__x86_64__) - unsigned long l4_flags, -#endif - unsigned long l3_flags, unsigned long l2_flags, unsigned long l1_flags) { - return vmap(mfn_to_virt_kern(mfn), mfn, order, -#if defined(__x86_64__) - l4_flags, -#endif - l3_flags, l2_flags, l1_flags); -} - void init_pagetables(void) { for_each_memory_range (r) { switch (r->base) { diff --git a/include/arch/x86/page.h b/include/arch/x86/page.h index 5b0a13d4..552fc16a 100644 --- a/include/arch/x86/page.h +++ b/include/arch/x86/page.h @@ -140,11 +140,6 @@ extern void *vmap(void *va, mfn_t mfn, unsigned int order, #endif unsigned long l3_flags, unsigned long l2_flags, unsigned long l1_flags); -extern void *kmap(mfn_t mfn, unsigned int order, -#if defined(__x86_64__) - unsigned long l4_flags, -#endif - unsigned long l3_flags, unsigned long l2_flags, unsigned long l1_flags); extern void vunmap(void *va, unsigned int order); /* Static declarations */ @@ -188,6 +183,19 @@ static inline mfn_t virt_to_mfn(const void *va) { return paddr_to_mfn(virt_to_paddr(va)); } +static inline void *kmap(mfn_t mfn, unsigned int order, +#if defined(__x86_64__) + unsigned long l4_flags, +#endif + unsigned long l3_flags, unsigned long l2_flags, + unsigned long l1_flags) { + return vmap(mfn_to_virt_kern(mfn), mfn, order, +#if defined(__x86_64__) + l4_flags, +#endif + l3_flags, l2_flags, l1_flags); +} + static inline void *vmap_1g(void *va, mfn_t mfn, unsigned long l3_flags) { return vmap(va, mfn, PAGE_ORDER_1G, L4_PROT_USER, l3_flags, PT_NO_FLAGS, PT_NO_FLAGS); } From 0bbf7a1064fc0abb5451426fb7f0a782d5619273 Mon Sep 17 00:00:00 2001 From: Pawel Wieczorkiewicz Date: Wed, 19 Jan 2022 15:48:54 +0100 Subject: [PATCH 3/3] mm,pagetables: add VIRT_KERNEL_MAP memory area The VIRT_KERNEL_MAP is currently located at the address 0xffff800000000000. The memory area should be used for high-address or large memory allocations. The VIRT_KERNEL_BASE area, while reachable from within the VIRT_IDENT_BASE area, does not have enough addressing space for high address allocations (base address overflow). All such allocations should go to the new area. Add mmap() helper (or its order size variants) to automatically use the VIRT_KERNEL_MAP area. The get_free_pages() gets a new flag GPF_KERNEL_MAP to use the area. Signed-off-by: Pawel Wieczorkiewicz --- include/arch/x86/page.h | 41 +++++++++++++++++++++++++++++++++++++++++ include/mm/vmm.h | 1 + mm/vmm.c | 2 ++ 3 files changed, 44 insertions(+) diff --git a/include/arch/x86/page.h b/include/arch/x86/page.h index 552fc16a..8def5426 100644 --- a/include/arch/x86/page.h +++ b/include/arch/x86/page.h @@ -117,6 +117,7 @@ #define PADDR_MASK (~(PADDR_SIZE - 1)) #define VIRT_KERNEL_BASE _U64(0xffffffff80000000) +#define VIRT_KERNEL_MAP _U64(0xffff800000000000) #define VIRT_USER_BASE _U64(0x0000000000400000) #define VIRT_IDENT_BASE _U64(0x0000000000000000) @@ -150,12 +151,19 @@ static inline paddr_t mfn_to_paddr(mfn_t mfn) { return (paddr_t)(mfn << PAGE_SHI static inline void *_paddr_to_virt(paddr_t pa, unsigned long addr_space) { return _ptr(pa + addr_space); } + static inline void *paddr_to_virt_kern(paddr_t pa) { return _paddr_to_virt(pa, VIRT_KERNEL_BASE); } + +static inline void *paddr_to_virt_map(paddr_t pa) { + return _paddr_to_virt(pa, VIRT_KERNEL_MAP); +} + static inline void *paddr_to_virt_user(paddr_t pa) { return _paddr_to_virt(pa, VIRT_USER_BASE); } + static inline void *paddr_to_virt(paddr_t pa) { return _paddr_to_virt(pa, VIRT_IDENT_BASE); } @@ -163,9 +171,15 @@ static inline void *paddr_to_virt(paddr_t pa) { static inline void *mfn_to_virt_kern(mfn_t mfn) { return paddr_to_virt_kern(mfn << PAGE_SHIFT); } + +static inline void *mfn_to_virt_map(mfn_t mfn) { + return paddr_to_virt_map(mfn << PAGE_SHIFT); +} + static inline void *mfn_to_virt_user(mfn_t mfn) { return paddr_to_virt_user(mfn << PAGE_SHIFT); } + static inline void *mfn_to_virt(mfn_t mfn) { return paddr_to_virt(mfn << PAGE_SHIFT); } static inline paddr_t virt_to_paddr(const void *va) { @@ -173,6 +187,8 @@ static inline paddr_t virt_to_paddr(const void *va) { if (IS_ADDR_SPACE_VA(va, VIRT_KERNEL_BASE)) return pa - VIRT_KERNEL_BASE; + if (IS_ADDR_SPACE_VA(va, VIRT_KERNEL_MAP)) + return pa - VIRT_KERNEL_MAP; if (IS_ADDR_SPACE_VA(va, VIRT_USER_BASE)) return pa - VIRT_USER_BASE; @@ -196,6 +212,19 @@ static inline void *kmap(mfn_t mfn, unsigned int order, l3_flags, l2_flags, l1_flags); } +static inline void *mmap(mfn_t mfn, unsigned int order, +#if defined(__x86_64__) + unsigned long l4_flags, +#endif + unsigned long l3_flags, unsigned long l2_flags, + unsigned long l1_flags) { + return vmap(mfn_to_virt_map(mfn), mfn, order, +#if defined(__x86_64__) + l4_flags, +#endif + l3_flags, l2_flags, l1_flags); +} + static inline void *vmap_1g(void *va, mfn_t mfn, unsigned long l3_flags) { return vmap(va, mfn, PAGE_ORDER_1G, L4_PROT_USER, l3_flags, PT_NO_FLAGS, PT_NO_FLAGS); } @@ -222,6 +251,18 @@ static inline void *kmap_4k(mfn_t mfn, unsigned long l1_flags) { return kmap(mfn, PAGE_ORDER_4K, L4_PROT_USER, L3_PROT_USER, L2_PROT_USER, l1_flags); } +static inline void *mmap_1g(mfn_t mfn, unsigned long l3_flags) { + return mmap(mfn, PAGE_ORDER_1G, L4_PROT_USER, l3_flags, PT_NO_FLAGS, PT_NO_FLAGS); +} + +static inline void *mmap_2m(mfn_t mfn, unsigned long l2_flags) { + return mmap(mfn, PAGE_ORDER_2M, L4_PROT_USER, L3_PROT_USER, l2_flags, PT_NO_FLAGS); +} + +static inline void *mmap_4k(mfn_t mfn, unsigned long l1_flags) { + return mmap(mfn, PAGE_ORDER_4K, L4_PROT_USER, L3_PROT_USER, L2_PROT_USER, l1_flags); +} + #endif /* __ASSEMBLY__ */ #endif /* KTF_PAGE_H */ diff --git a/include/mm/vmm.h b/include/mm/vmm.h index b0fd5e81..80f68a17 100644 --- a/include/mm/vmm.h +++ b/include/mm/vmm.h @@ -31,6 +31,7 @@ enum gfp_flags { GFP_KERNEL = 0x00000001, GFP_USER = 0x00000002, GFP_IDENT = 0x00000004, + GFP_KERNEL_MAP = 0x00000008, }; /* External definitions */ diff --git a/mm/vmm.c b/mm/vmm.c index 8a86acf8..6d86b21d 100644 --- a/mm/vmm.c +++ b/mm/vmm.c @@ -50,6 +50,8 @@ void *get_free_pages(unsigned int order, uint32_t flags) { L2_PROT_USER, L1_PROT_USER); if (flags & GFP_KERNEL) va = kmap(mfn, order, L4_PROT, L3_PROT, L2_PROT, L1_PROT); + if (flags & GFP_KERNEL_MAP) + va = mmap(mfn, order, L4_PROT, L3_PROT, L2_PROT, L1_PROT); return va; }