Skip to content

Commit

Permalink
mem: extend vmap and kmap apis
Browse files Browse the repository at this point in the history
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 <ahmeddan amazon c;0m >
  • Loading branch information
82marbag committed Jul 30, 2021
1 parent ffef790 commit 5d29781
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 32 deletions.
2 changes: 1 addition & 1 deletion arch/x86/apic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 2 additions & 3 deletions arch/x86/ioapic.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
46 changes: 32 additions & 14 deletions arch/x86/pagetables.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -159,60 +163,74 @@ 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

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;
Expand Down
2 changes: 1 addition & 1 deletion common/acpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions drivers/hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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;
}
}
53 changes: 46 additions & 7 deletions include/arch/x86/page.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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); }

Expand All @@ -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;

Expand All @@ -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__ */

Expand Down
2 changes: 1 addition & 1 deletion mm/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
7 changes: 4 additions & 3 deletions mm/vmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down

0 comments on commit 5d29781

Please sign in to comment.