From 54eaf968603b9787dd7572ba6d5692e84b718b59 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Tue, 20 Oct 2020 02:38:01 +0200 Subject: [PATCH] Remove conv_mem_rewind() as it could be a dangerous source of bugs, modify code that used it accordingly --- stage2/fs/ext2.c | 17 +++++---------- stage2/mm/pmm.c | 4 ---- stage2/mm/pmm.h | 1 - stage2/protos/stivale2.c | 17 ++++++++++----- stage2/sys/smp.c | 47 +++++++++++++++++++++++++++++++++------- 5 files changed, 57 insertions(+), 29 deletions(-) diff --git a/stage2/fs/ext2.c b/stage2/fs/ext2.c index 16da0c19..87885fd7 100644 --- a/stage2/fs/ext2.c +++ b/stage2/fs/ext2.c @@ -211,8 +211,7 @@ static int ext2_parse_dirent(struct ext2_dir_entry *dir, struct ext2_file_handle if (*path == '/') path++; - struct ext2_inode *current_inode = conv_mem_alloc(sizeof(struct ext2_inode)); - *current_inode = fd->root_inode; + struct ext2_inode current_inode = fd->root_inode; bool escape = false; @@ -227,30 +226,27 @@ next: else path++; - for (uint32_t i = 0; i < current_inode->i_size; ) { + for (uint32_t i = 0; i < current_inode.i_size; ) { // preliminary read inode_read(dir, i, sizeof(struct ext2_dir_entry), - fd->block_size, current_inode, + fd->block_size, ¤t_inode, fd->drive, &fd->part); // name read - char *name = conv_mem_alloc(dir->name_len + 1); + char name[dir->name_len + 1]; memset(name, 0, dir->name_len + 1); inode_read(name, i + sizeof(struct ext2_dir_entry), dir->name_len, - fd->block_size, current_inode, fd->drive, &fd->part); + fd->block_size, ¤t_inode, fd->drive, &fd->part); int r = strcmp(token, name); - conv_mem_rewind(dir->name_len + 1); - if (!r) { if (escape) { - conv_mem_rewind(sizeof(struct ext2_inode)); return 0; } else { // update the current inode - ext2_get_inode(current_inode, fd->drive, &fd->part, dir->inode, sb); + ext2_get_inode(¤t_inode, fd->drive, &fd->part, dir->inode, sb); goto next; } } @@ -258,7 +254,6 @@ next: i += dir->rec_len; } - conv_mem_rewind(sizeof(struct ext2_inode)); return -1; } diff --git a/stage2/mm/pmm.c b/stage2/mm/pmm.c index 89bc7757..b747744e 100644 --- a/stage2/mm/pmm.c +++ b/stage2/mm/pmm.c @@ -281,10 +281,6 @@ extern symbol bss_end; static size_t bump_allocator_base = (size_t)bss_end; static size_t bump_allocator_limit = 0; -void conv_mem_rewind(size_t count) { - bump_allocator_base -= count; -} - void *conv_mem_alloc(size_t count) { return conv_mem_alloc_aligned(count, 4); } diff --git a/stage2/mm/pmm.h b/stage2/mm/pmm.h index 493daa32..9390f9a9 100644 --- a/stage2/mm/pmm.h +++ b/stage2/mm/pmm.h @@ -22,7 +22,6 @@ void *ext_mem_alloc_type(size_t count, uint32_t type); void *ext_mem_alloc_aligned(size_t count, size_t alignment); void *ext_mem_alloc_aligned_type(size_t count, size_t alignment, uint32_t type); -void conv_mem_rewind(size_t count); void *conv_mem_alloc(size_t count); void *conv_mem_alloc_aligned(size_t count, size_t alignment); diff --git a/stage2/protos/stivale2.c b/stage2/protos/stivale2.c index 6c215398..b952de42 100644 --- a/stage2/protos/stivale2.c +++ b/stage2/protos/stivale2.c @@ -311,13 +311,20 @@ void stivale2_load(char *cmdline) { { struct stivale2_header_tag_smp *smp_hdr_tag = get_tag(&stivale2_hdr, STIVALE2_HEADER_TAG_SMP_ID); if (smp_hdr_tag != NULL) { - struct stivale2_struct_tag_smp *tag = conv_mem_alloc(sizeof(struct stivale2_struct_tag_smp)); + struct smp_information *smp_info; + size_t cpu_count; + smp_info = init_smp(&cpu_count, bits == 64, level5pg && level5pg_requested, + pagemap, smp_hdr_tag->flags & 1); + + struct stivale2_struct_tag_smp *tag = + conv_mem_alloc(sizeof(struct stivale2_struct_tag_smp) + + sizeof(struct smp_information) * cpu_count); tag->tag.identifier = STIVALE2_STRUCT_TAG_SMP_ID; + tag->cpu_count = cpu_count; + tag->flags |= (smp_hdr_tag->flags & 1) && x2apic_check(); - tag->flags |= (smp_hdr_tag->flags & 1) && x2apic_check(); - - init_smp((size_t*)&tag->cpu_count, bits == 64, level5pg && level5pg_requested, - pagemap, smp_hdr_tag->flags & 1); + memcpy((void*)tag + sizeof(struct stivale2_struct_tag_smp), + smp_info, sizeof(struct smp_information) * cpu_count); append_tag(&stivale2_struct, (struct stivale2_tag *)tag); } diff --git a/stage2/sys/smp.c b/stage2/sys/smp.c index 6a98b845..673724ac 100644 --- a/stage2/sys/smp.c +++ b/stage2/sys/smp.c @@ -109,12 +109,47 @@ struct smp_information *init_smp(size_t *cpu_count, struct gdtr gdtr; asm volatile ("sgdt %0" :: "m"(gdtr) : "memory"); - struct smp_information *ret = conv_mem_alloc_aligned(0, 1); *cpu_count = 0; x2apic = x2apic && x2apic_enable(); - // Parse the MADT entries + // Count the MAX of startable APs and allocate accordingly + size_t max_cpus = 0; + + for (uint8_t *madt_ptr = (uint8_t *)madt->madt_entries_begin; + (uintptr_t)madt_ptr < (uintptr_t)madt + madt->length; + madt_ptr += *(madt_ptr + 1)) { + switch (*madt_ptr) { + case 0: { + // Processor local xAPIC + struct madt_lapic *lapic = (void *)madt_ptr; + + // Check if we can actually try to start the AP + if ((lapic->flags & 1) ^ ((lapic->flags >> 1) & 1)) + max_cpus++; + + continue; + } + case 9: { + // Processor local x2APIC + if (!x2apic) + continue; + + struct madt_x2apic *x2apic = (void *)madt_ptr; + + // Check if we can actually try to start the AP + if ((x2apic->flags & 1) ^ ((x2apic->flags >> 1) & 1)) + max_cpus++; + + continue; + } + } + } + + struct smp_information *ret = ext_mem_alloc(max_cpus * sizeof(struct smp_information)); + *cpu_count = 0; + + // Try to start all APs for (uint8_t *madt_ptr = (uint8_t *)madt->madt_entries_begin; (uintptr_t)madt_ptr < (uintptr_t)madt + madt->length; madt_ptr += *(madt_ptr + 1)) { @@ -127,8 +162,7 @@ struct smp_information *init_smp(size_t *cpu_count, if (!((lapic->flags & 1) ^ ((lapic->flags >> 1) & 1))) continue; - struct smp_information *info_struct = - conv_mem_alloc_aligned(sizeof(struct smp_information), 1); + struct smp_information *info_struct = &ret[*cpu_count]; info_struct->acpi_processor_uid = lapic->acpi_processor_uid; info_struct->lapic_id = lapic->lapic_id; @@ -146,7 +180,6 @@ struct smp_information *init_smp(size_t *cpu_count, longmode, lv5, (uint32_t)pagemap.top_level, x2apic)) { print("smp: FAILED to bring-up AP\n"); - conv_mem_rewind(sizeof(struct smp_information)); continue; } @@ -166,8 +199,7 @@ struct smp_information *init_smp(size_t *cpu_count, if (!((x2apic->flags & 1) ^ ((x2apic->flags >> 1) & 1))) continue; - struct smp_information *info_struct = - conv_mem_alloc_aligned(sizeof(struct smp_information), 1); + struct smp_information *info_struct = &ret[*cpu_count]; info_struct->acpi_processor_uid = x2apic->acpi_processor_uid; info_struct->lapic_id = x2apic->x2apic_id; @@ -185,7 +217,6 @@ struct smp_information *init_smp(size_t *cpu_count, longmode, lv5, (uint32_t)pagemap.top_level, true)) { print("smp: FAILED to bring-up AP\n"); - conv_mem_rewind(sizeof(struct smp_information)); continue; }