Remove conv_mem_rewind() as it could be a dangerous source of bugs, modify code that used it accordingly
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 7856b646..5e4ca21c 100644
--- a/stage2/protos/stivale2.c
+++ b/stage2/protos/stivale2.c
@@ -303,13 +303,20 @@ void stivale2_load(char *cmdline, int boot_drive) {
{
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;
}
