From 5d29781335607647a567dae1776e74a86dc145e0 Mon Sep 17 00:00:00 2001 From: 82marbag <69267416+82marbag@users.noreply.github.com> Date: Wed, 28 Jul 2021 14:45:08 -0400 Subject: [PATCH] mem: extend vmap and kmap apis Update vmap and kmap to allow mapping pages and frames with no default flag. Add vmap_1g, vmap_2m, vmap_4k with default flags and similarly with kmap. Signed-off-by: Daniele Ahmed --- arch/x86/apic.c | 2 +- arch/x86/ioapic.c | 5 ++-- arch/x86/pagetables.c | 46 ++++++++++++++++++++++++----------- common/acpi.c | 2 +- drivers/hpet.c | 4 ++-- include/arch/x86/page.h | 53 +++++++++++++++++++++++++++++++++++------ mm/pmm.c | 2 +- mm/vmm.c | 7 +++--- 8 files changed, 89 insertions(+), 32 deletions(-) diff --git a/arch/x86/apic.c b/arch/x86/apic.c index dcac4b9f..f3a6d66c 100644 --- a/arch/x86/apic.c +++ b/arch/x86/apic.c @@ -153,7 +153,7 @@ void init_apic(unsigned int cpu, apic_mode_t mode) { * X2APIC uses MSRs for accesses, so no mapping needed. */ if (apic_mode == APIC_MODE_XAPIC) - vmap(apic_get_base(apic_base), apic_base.base, PAGE_ORDER_4K, L1_PROT); + vmap_4k(apic_get_base(apic_base), apic_base.base, L1_PROT); spiv.reg = apic_read(APIC_SPIV); spiv.vector = 0xFF; diff --git a/arch/x86/ioapic.c b/arch/x86/ioapic.c index 352a3801..3b73da42 100644 --- a/arch/x86/ioapic.c +++ b/arch/x86/ioapic.c @@ -217,9 +217,8 @@ ioapic_t *add_ioapic(uint8_t id, uint8_t version, bool enabled, uint64_t base_ad ioapic->base_address = base_address; ioapic->gsi_base = gsi_base; - ioapic->virt_address = - vmap(paddr_to_virt(ioapic->base_address), paddr_to_mfn(ioapic->base_address), - PAGE_ORDER_4K, L1_PROT); + ioapic->virt_address = vmap_4k(paddr_to_virt(ioapic->base_address), + paddr_to_mfn(ioapic->base_address), L1_PROT); BUG_ON(!ioapic->virt_address); return ioapic; diff --git a/arch/x86/pagetables.c b/arch/x86/pagetables.c index c902fb4a..d51c1303 100644 --- a/arch/x86/pagetables.c +++ b/arch/x86/pagetables.c @@ -146,7 +146,11 @@ static mfn_t get_pgentry_mfn(mfn_t tab_mfn, pt_index_t index, unsigned long flag return mfn; } -void *vmap(void *va, mfn_t mfn, unsigned int order, unsigned long flags) { +void *vmap(void *va, 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) { static spinlock_t lock = SPINLOCK_INIT; mfn_t l1t_mfn, l2t_mfn, l3t_mfn; pgentry_t *tab, *entry; @@ -159,7 +163,7 @@ void *vmap(void *va, mfn_t mfn, unsigned int order, unsigned long flags) { spin_lock(&lock); #if defined(__x86_64__) - l3t_mfn = get_pgentry_mfn(get_cr3_mfn(&cr3), l4_table_index(va), L4_PROT_USER); + l3t_mfn = get_pgentry_mfn(get_cr3_mfn(&cr3), l4_table_index(va), l4_flags); #else l3t_mfn = get_cr3_mfn(&cr3); #endif @@ -167,52 +171,66 @@ void *vmap(void *va, mfn_t mfn, unsigned int order, unsigned long flags) { if (order == PAGE_ORDER_1G) { tab = init_map_mfn(l3t_mfn); entry = &tab[l3_table_index(va)]; - set_pgentry(entry, mfn, flags | _PAGE_PSE); + set_pgentry(entry, mfn, l3_flags | _PAGE_PSE); goto done; } - l2t_mfn = get_pgentry_mfn(l3t_mfn, l3_table_index(va), L3_PROT_USER); + l2t_mfn = get_pgentry_mfn(l3t_mfn, l3_table_index(va), l3_flags); if (order == PAGE_ORDER_2M) { tab = init_map_mfn(l2t_mfn); entry = &tab[l2_table_index(va)]; - set_pgentry(entry, mfn, flags | _PAGE_PSE); + set_pgentry(entry, mfn, l2_flags | _PAGE_PSE); goto done; } - l1t_mfn = get_pgentry_mfn(l2t_mfn, l2_table_index(va), L2_PROT_USER); + l1t_mfn = get_pgentry_mfn(l2t_mfn, l2_table_index(va), l2_flags); tab = init_map_mfn(l1t_mfn); entry = &tab[l1_table_index(va)]; - set_pgentry(entry, mfn, flags); + set_pgentry(entry, mfn, l1_flags); done: spin_unlock(&lock); return va; } -void *vunmap(void *va, unsigned int order) { return vmap(va, MFN_INVALID, order, 0x0); } +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 *kmap(mfn_t mfn, unsigned int order, unsigned long flags) { - return vmap(mfn_to_virt_kern(mfn), mfn, order, 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 *kunmap(void *va, unsigned int order) { return vmap(va, MFN_INVALID, order, 0x0); } +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) { case VIRT_IDENT_BASE: for (mfn_t mfn = virt_to_mfn(r->start); mfn < virt_to_mfn(r->end); mfn++) - vmap(mfn_to_virt(mfn), mfn, PAGE_ORDER_4K, r->flags); + vmap_4k(mfn_to_virt(mfn), mfn, r->flags); break; case VIRT_KERNEL_BASE: for (mfn_t mfn = virt_to_mfn(r->start); mfn < virt_to_mfn(r->end); mfn++) - kmap(mfn, PAGE_ORDER_4K, r->flags); + kmap_4k(mfn, r->flags); break; case VIRT_USER_BASE: for (mfn_t mfn = virt_to_mfn(r->start); mfn < virt_to_mfn(r->end); mfn++) - vmap(mfn_to_virt_user(mfn), mfn, PAGE_ORDER_4K, r->flags); + vmap_4k(mfn_to_virt_user(mfn), mfn, r->flags); break; default: break; diff --git a/common/acpi.c b/common/acpi.c index 3519d8df..997ff244 100644 --- a/common/acpi.c +++ b/common/acpi.c @@ -128,7 +128,7 @@ static unsigned acpi_table_map_pages(paddr_t pa, size_t len) { mfn); } - BUG_ON(!kmap(mfn, PAGE_ORDER_4K, L1_PROT)); + BUG_ON(!kmap_4k(mfn, L1_PROT)); } return num_pages; diff --git a/drivers/hpet.c b/drivers/hpet.c index f3b23715..66b69a5f 100644 --- a/drivers/hpet.c +++ b/drivers/hpet.c @@ -43,7 +43,7 @@ bool init_hpet(uint8_t dst_cpus) { } hpet_base_mfn = paddr_to_mfn(hpet->address.address); - vmap((uint64_t *) hpet->address.address, hpet_base_mfn, PAGE_ORDER_4K, L1_PROT); + vmap_4k((uint64_t *) hpet->address.address, hpet_base_mfn, L1_PROT); config = (acpi_hpet_timer_t *) (hpet->address.address + HPET_OFFSET_TIMER_0_CONFIG_CAP_REG); general = @@ -89,4 +89,4 @@ bool init_hpet(uint8_t dst_cpus) { configure_isa_irq(HPET_IRQ, HPET_IRQ_OFFSET, IOAPIC_DEST_MODE_PHYSICAL, dst_cpus); dprintk("Initialized HPET\n"); return true; -} \ No newline at end of file +} diff --git a/include/arch/x86/page.h b/include/arch/x86/page.h index ae13be27..d393d949 100644 --- a/include/arch/x86/page.h +++ b/include/arch/x86/page.h @@ -65,6 +65,8 @@ #define PTE_FLAGS(...) (TOKEN_OR(_PAGE_, ##__VA_ARGS__)) +#define PT_NO_FLAGS 0 + #define L1_PROT (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY) #define L1_PROT_RO (_PAGE_PRESENT | _PAGE_ACCESSED) #define L1_PROT_NOCACHE (L1_PROT | _PAGE_PCD) @@ -127,6 +129,26 @@ typedef unsigned long mfn_t; #define PADDR_INVALID (0UL) #define MFN_INVALID (0UL) +#define IS_ADDR_SPACE_VA(va, as) ((_ul(va) & (as)) == (as)) + +/* External declarations */ + +extern void *vmap(void *va, 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); + +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); + +/* Static declarations */ + static inline mfn_t paddr_to_mfn(paddr_t pa) { return (mfn_t)(pa >> PAGE_SHIFT); } static inline paddr_t mfn_to_paddr(mfn_t mfn) { return (paddr_t)(mfn << PAGE_SHIFT); } @@ -151,8 +173,6 @@ static inline void *mfn_to_virt_user(mfn_t mfn) { } static inline void *mfn_to_virt(mfn_t mfn) { return paddr_to_virt(mfn << PAGE_SHIFT); } -#define IS_ADDR_SPACE_VA(va, as) ((_ul(va) & (as)) == (as)) - static inline paddr_t virt_to_paddr(const void *va) { paddr_t pa = (paddr_t) va; @@ -168,12 +188,31 @@ static inline mfn_t virt_to_mfn(const void *va) { return paddr_to_mfn(virt_to_paddr(va)); } -/* External declarations */ +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); +} -extern void *vmap(void *va, mfn_t mfn, unsigned int order, unsigned long flags); -extern void *vunmap(void *va, unsigned int order); -extern void *kmap(mfn_t mfn, unsigned int order, unsigned long flags); -extern void *kunmap(void *va, unsigned int order); +static inline void *vmap_2m(void *va, mfn_t mfn, unsigned long l2_flags) { + return vmap(va, mfn, PAGE_ORDER_2M, L4_PROT_USER, L3_PROT_USER, PT_NO_FLAGS, + PT_NO_FLAGS); +} + +static inline void *vmap_4k(void *va, mfn_t mfn, unsigned long l1_flags) { + return vmap(va, mfn, PAGE_ORDER_4K, L4_PROT_USER, L3_PROT_USER, L2_PROT_USER, + l1_flags); +} + +static inline void *kmap_1g(mfn_t mfn, unsigned long l3_flags) { + return kmap(mfn, PAGE_ORDER_1G, L4_PROT_USER, l3_flags, PT_NO_FLAGS, PT_NO_FLAGS); +} + +static inline void *kmap_2m(mfn_t mfn, unsigned long l2_flags) { + return kmap(mfn, PAGE_ORDER_2M, L4_PROT_USER, L3_PROT_USER, l2_flags, PT_NO_FLAGS); +} + +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); +} #endif /* __ASSEMBLY__ */ diff --git a/mm/pmm.c b/mm/pmm.c index 4b913c95..d8b6069c 100644 --- a/mm/pmm.c +++ b/mm/pmm.c @@ -306,7 +306,7 @@ void map_used_memory(void) { for_each_order (order) { list_for_each_entry (frame, &busy_frames[order], list) { if (!frame->mapped) { - kmap(frame->mfn, order, L1_PROT); + kmap(frame->mfn, order, L4_PROT, L3_PROT, L2_PROT, L1_PROT); frame->mapped = true; } } diff --git a/mm/vmm.c b/mm/vmm.c index c492192f..eec7ed20 100644 --- a/mm/vmm.c +++ b/mm/vmm.c @@ -37,11 +37,12 @@ void *get_free_pages(unsigned int order, uint32_t flags) { return NULL; if (flags & GFP_IDENT) - va = vmap(mfn_to_virt(mfn), mfn, order, L1_PROT); + va = vmap(mfn_to_virt(mfn), mfn, order, L4_PROT, L3_PROT, L2_PROT, L1_PROT); if (flags & GFP_USER) - va = vmap(mfn_to_virt_user(mfn), mfn, order, L1_PROT_USER); + va = vmap(mfn_to_virt_user(mfn), mfn, order, L4_PROT_USER, L3_PROT_USER, + L2_PROT_USER, L1_PROT_USER); if (flags & GFP_KERNEL) - va = kmap(mfn, order, L1_PROT); + va = kmap(mfn, order, L4_PROT, L3_PROT, L2_PROT, L1_PROT); return va; }