Skip to content

Commit

Permalink
zap identity mappings after init (#64)
Browse files Browse the repository at this point in the history
* pmm: export display_frames_count()

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>

* smp: use dedicated variable for CR3

Do not keep final, global cr3 variable in .data.init section.  When
init sections are being reclaimed, this breaks pagetables interface.

Instead, for SMP AP booting, use dedicated ap_cr3 variable, which can
be reclaimed after SMP initialization.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>

* smp: minor cleanup

* Rename smp_init() to init_smp() to follow naming convention
* Put boot_cpu() and init_smp() into the .text.init section

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>

* pmm: zap boot mappings after initialization

* PMM:
  - Add reclaim_frame() non-static wrapper over add_frame();
    it adds a frame being reclaimed to the list of free frames.
* Compiler:
  - Add IS_INIT_SECTION() macro; it decides, if section is an init
    section, based on its name.
* Setup:
  - Modify zap_boot_mappings() to iterate over all defined memory
    regions and unmap plus reclaim all frames belonging to identity
    mapped init sections. Additionally, zero-out non-text sections.

Signed-off-by: Pawel Wieczorkiewicz <[email protected]>

Co-authored-by: Bjoern Doebel <[email protected]>
  • Loading branch information
wipawel and bjoernd authored Aug 24, 2020
1 parent a718cc2 commit 320f68b
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 24 deletions.
2 changes: 1 addition & 1 deletion arch/x86/pagetables.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include <spinlock.h>
#include <string.h>

cr3_t __data_init cr3;
cr3_t cr3;

static inline const char *dump_pte_flags(char *buf, size_t size, pte_t pte) {
/* clang-format off */
Expand Down
1 change: 1 addition & 0 deletions common/kernel.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ void kernel_main(void) {
if (kernel_cmdline)
printk("Command line: %s\n", kernel_cmdline);

zap_boot_mappings();
display_memory_map();
display_multiboot_mmap();

Expand Down
27 changes: 13 additions & 14 deletions common/setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,17 +66,18 @@ static __always_inline void zero_bss(void) {
memset(_ptr(__start_bss_user), 0x0, _ptr(__end_bss_user) - _ptr(__start_bss_user));
}

static __always_inline void zap_boot_mappings(void) {
#if defined(__x86_64__)
memset(paddr_to_virt_kern(virt_to_paddr(l4_pt_entries)), 0,
L4_PT_ENTRIES * sizeof(pgentry_t));
#endif
memset(paddr_to_virt_kern(virt_to_paddr(l3_pt_entries)), 0,
L3_PT_ENTRIES * sizeof(pgentry_t));
memset(paddr_to_virt_kern(virt_to_paddr(l2_pt_entries)), 0,
L2_PT_ENTRIES * sizeof(pgentry_t));
memset(paddr_to_virt_kern(virt_to_paddr(l1_pt_entries)), 0,
L1_PT_ENTRIES * sizeof(pgentry_t));
void zap_boot_mappings(void) {
for_each_memory_range (r) {
if (r->base == VIRT_IDENT_BASE && IS_INIT_SECTION(r->name)) {
if (strcmp(r->name, ".text.init"))
memset(r->start, 0, r->end - r->start);

for (mfn_t mfn = virt_to_mfn(r->start); mfn < virt_to_mfn(r->end); mfn++) {
vunmap(mfn_to_virt(mfn), PAGE_ORDER_4K);
reclaim_frame(mfn, PAGE_ORDER_4K);
}
}
}
}

void __noreturn __text_init kernel_start(uint32_t multiboot_magic,
Expand Down Expand Up @@ -113,15 +114,13 @@ void __noreturn __text_init kernel_start(uint32_t multiboot_magic,

init_traps(0);

zap_boot_mappings();

init_slab();

init_apic(APIC_MODE_XAPIC);

init_tasks();

smp_init();
init_smp();

/* Jump from .text.init section to .text */
asm volatile("push %0; ret" ::"r"(&kernel_main));
Expand Down
4 changes: 4 additions & 0 deletions include/compiler.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,10 @@
#define __data_init __section(".data.init")
#define __bss_init __section(".bss.init")

#define IS_INIT_SECTION(name) \
(!strcmp(name, ".text.init") || !strcmp(name, ".data.init") || \
!strcmp(name, ".bss.init"))

#define __user_text __section(".text.user")
#define __user_data __section(".data.user")
#define __user_bss __section(".bss.user")
Expand Down
2 changes: 2 additions & 0 deletions include/mm/pmm.h
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ typedef struct frame frame_t;
/* External definitions */

extern void display_memory_map(void);
extern void display_frames_count(void);

extern addr_range_t get_memory_range(paddr_t pa);
extern paddr_t get_memory_range_start(paddr_t pa);
Expand All @@ -90,6 +91,7 @@ extern void init_pmm(void);

extern mfn_t get_free_frames(unsigned int order);
extern void put_frame(mfn_t mfn, unsigned int order);
extern void reclaim_frame(mfn_t mfn, unsigned int order);

extern void map_used_memory(void);

Expand Down
2 changes: 2 additions & 0 deletions include/setup.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ static inline void get_com_ports(void) {
com_ports[1] = 0x2f8;
}

extern void zap_boot_mappings(void);

#endif /* __ASSEMBLY__ */

#endif /* KTF_SETUP_H */
2 changes: 1 addition & 1 deletion include/smp/smp.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@

/* External declarations */

extern void smp_init(void);
extern void init_smp(void);
extern unsigned get_nr_cpus(void);

/* Static declarations */
Expand Down
17 changes: 12 additions & 5 deletions mm/pmm.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include <drivers/vga.h>
#include <mm/pmm.h>

size_t total_phys_memory;

static list_head_t free_frames[MAX_PAGE_ORDER + 1];
static list_head_t busy_frames[MAX_PAGE_ORDER + 1];

Expand Down Expand Up @@ -114,8 +116,8 @@ paddr_t get_memory_range_end(paddr_t pa) {
return _paddr(r.end);
}

static void display_frames_count(size_t size) {
printk("Avail memory frames: (total size: %lu MB)\n", size / MB(1));
void display_frames_count(void) {
printk("Avail memory frames: (total size: %lu MB)\n", total_phys_memory / MB(1));

for_each_order (order) {
size_t count = frames_count[order];
Expand Down Expand Up @@ -149,6 +151,12 @@ static void add_frame(paddr_t *pa, unsigned int order, bool initial) {
frames_count[order]++;
}

void reclaim_frame(mfn_t mfn, unsigned int order) {
paddr_t pa = mfn_to_paddr(mfn);

add_frame(&pa, order, false);
}

static size_t process_memory_range(unsigned index) {
paddr_t start, end, cur;
addr_range_t range;
Expand Down Expand Up @@ -200,7 +208,6 @@ bool paddr_invalid(paddr_t pa) {
}

void init_pmm(void) {
size_t total_size = 0;
unsigned num;

printk("Initialize Physical Memory Manager\n");
Expand All @@ -215,9 +222,9 @@ void init_pmm(void) {

/* Skip low memory range */
for (unsigned int i = 1; i < num; i++)
total_size += process_memory_range(i);
total_phys_memory += process_memory_range(i);

display_frames_count(total_size);
display_frames_count();

if (opt_debug) {
frame_t *frame;
Expand Down
2 changes: 1 addition & 1 deletion smp/bootstrap.S
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ GLOBAL(ap_start)
or $(X86_CR4_PAE | X86_CR4_PSE), %eax
mov %eax, %cr4

mov (cr3), %eax
mov (ap_cr3), %eax
mov %eax, %cr3

/* Enable long mode */
Expand Down
7 changes: 5 additions & 2 deletions smp/smp.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <console.h>
#include <ktf.h>
#include <lib.h>
#include <pagetable.h>
#include <percpu.h>
#include <sched.h>
#include <setup.h>
Expand All @@ -43,6 +44,7 @@ static unsigned nr_cpus;

static unsigned ap_cpuid;
static bool ap_callin;
cr3_t __data_init ap_cr3;

void __noreturn ap_startup(void) {
write_sp(get_free_pages_top(PAGE_ORDER_2M, GFP_KERNEL));
Expand All @@ -60,7 +62,7 @@ void __noreturn ap_startup(void) {
UNREACHABLE();
}

static void boot_cpu(unsigned int cpu) {
static __text_init void boot_cpu(unsigned int cpu) {
percpu_t *percpu = get_percpu_page(cpu);
uint64_t icr;

Expand Down Expand Up @@ -91,7 +93,7 @@ static void boot_cpu(unsigned int cpu) {
dprintk("AP: %u Done \n", cpu);
}

void smp_init(void) {
void __text_init init_smp(void) {
unsigned mp_nr_cpus = mptables_init();
unsigned acpi_nr_cpus = acpi_get_nr_cpus();

Expand All @@ -102,6 +104,7 @@ void smp_init(void) {
}

printk("Initializing SMP support (CPUs: %u)\n", nr_cpus);
ap_cr3 = cr3;

for (unsigned int i = 0; i < nr_cpus; i++)
boot_cpu(i);
Expand Down

0 comments on commit 320f68b

Please sign in to comment.