:: commit ebb543f87cbf3d2e63f1a4808da9b6988cdc3ec6

mintsuki <mintsuki@protonmail.com> — 2020-10-20 00:38

parents: 039196b0f4

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, &current_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, &current_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(&current_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;
                 }
 
tab: 248 wrap: offon