The branch stable/13 has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=a8d453eec1e3ea7c62e82a8e591035876da2580e

commit a8d453eec1e3ea7c62e82a8e591035876da2580e
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2021-07-29 00:22:35 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2021-08-23 23:21:13 +0000

    amd64: stop doing special allocation for the AP startup trampoline
    
    (cherry picked from commit b27fe1c3ba2a1302c2866751e0c618b5a697bf30)
---
 sys/amd64/amd64/machdep.c    |  8 -------
 sys/amd64/amd64/mp_machdep.c | 19 +++++++++++----
 sys/i386/i386/mp_machdep.c   | 55 ++++++++++++++++++++++++++++++++++++++++++++
 sys/x86/include/x86_smp.h    | 10 ++++++--
 sys/x86/x86/mp_x86.c         | 54 -------------------------------------------
 5 files changed, 77 insertions(+), 69 deletions(-)

diff --git a/sys/amd64/amd64/machdep.c b/sys/amd64/amd64/machdep.c
index 840570be534a..63f933ad535c 100644
--- a/sys/amd64/amd64/machdep.c
+++ b/sys/amd64/amd64/machdep.c
@@ -1281,14 +1281,6 @@ getmemsize(caddr_t kmdp, u_int64_t first)
            (boothowto & RB_VERBOSE))
                printf("Physical memory use set to %ldK\n", Maxmem * 4);
 
-       /*
-        * Make hole for "AP -> long mode" bootstrap code.  The
-        * mp_bootaddress vector is only available when the kernel
-        * is configured to support APs and APs for the system start
-        * in real mode mode (e.g. SMP bare metal).
-        */
-       alloc_ap_trampoline(physmap, &physmap_idx);
-
        /* call pmap initialization to make new kernel address space */
        pmap_bootstrap(&first);
 
diff --git a/sys/amd64/amd64/mp_machdep.c b/sys/amd64/amd64/mp_machdep.c
index 082a58ada48f..383226b96d10 100644
--- a/sys/amd64/amd64/mp_machdep.c
+++ b/sys/amd64/amd64/mp_machdep.c
@@ -112,7 +112,7 @@ extern u_int mptramp_nx;
  * Local data and functions.
  */
 
-static int     start_ap(int apic_id);
+static int start_ap(int apic_id, vm_paddr_t boot_address);
 
 /*
  * Initialize the IPI handlers and start up the AP's.
@@ -322,17 +322,25 @@ mp_realloc_pcpu(int cpuid, int domain)
 int
 native_start_all_aps(void)
 {
-       vm_page_t m_pml4, m_pdp, m_pd[4];
+       vm_page_t m_boottramp, m_pml4, m_pdp, m_pd[4];
        pml5_entry_t old_pml45;
        pml4_entry_t *v_pml4;
        pdp_entry_t *v_pdp;
        pd_entry_t *v_pd;
+       vm_paddr_t boot_address;
        u_int32_t mpbioswarmvec;
        int apic_id, cpu, domain, i;
        u_char mpbiosreason;
 
        mtx_init(&ap_boot_mtx, "ap boot", NULL, MTX_SPIN);
 
+       MPASS(bootMP_size <= PAGE_SIZE);
+       m_boottramp = vm_page_alloc_contig(NULL, 0, VM_ALLOC_NORMAL |
+           VM_ALLOC_NOBUSY | VM_ALLOC_NOOBJ, 1, 0,
+           (1ULL << 20), /* Trampoline should be below 1M for real mode */
+           PAGE_SIZE, 0, VM_MEMATTR_DEFAULT);
+       boot_address = VM_PAGE_TO_PHYS(m_boottramp);
+
        /* Create a transient 1:1 mapping of low 4G */
        if (la57) {
                m_pml4 = pmap_page_alloc_below_4g(true);
@@ -382,7 +390,7 @@ native_start_all_aps(void)
        /* copy the AP 1st level boot code */
        bcopy(mptramp_start, (void *)PHYS_TO_DMAP(boot_address), bootMP_size);
        if (bootverbose)
-               printf("AP boot address %#x\n", boot_address);
+               printf("AP boot address %#lx\n", boot_address);
 
        /* save the current value of the warm-start vector */
        if (!efi_boot)
@@ -436,7 +444,7 @@ native_start_all_aps(void)
                bootAP = cpu;
 
                /* attempt to start the Application Processor */
-               if (!start_ap(apic_id)) {
+               if (!start_ap(apic_id, boot_address)) {
                        /* restore the warmstart vector */
                        if (!efi_boot)
                                *(u_int32_t *)WARMBOOT_OFF = mpbioswarmvec;
@@ -463,6 +471,7 @@ native_start_all_aps(void)
        vm_page_free(m_pd[1]);
        vm_page_free(m_pd[0]);
        vm_page_free(m_pdp);
+       vm_page_free(m_boottramp);
 
        /* number of APs actually started */
        return (mp_naps);
@@ -476,7 +485,7 @@ native_start_all_aps(void)
  * but it seems to work.
  */
 static int
-start_ap(int apic_id)
+start_ap(int apic_id, vm_paddr_t boot_address)
 {
        int vector, ms;
        int cpus;
diff --git a/sys/i386/i386/mp_machdep.c b/sys/i386/i386/mp_machdep.c
index 91ca6945f1ae..156702118c45 100644
--- a/sys/i386/i386/mp_machdep.c
+++ b/sys/i386/i386/mp_machdep.c
@@ -147,6 +147,61 @@ static int start_ap(int apic_id);
 
 static char *ap_copyout_buf;
 static char *ap_tramp_stack_base;
+
+unsigned int boot_address;
+
+#define MiB(v) (v ## ULL << 20)
+
+/* Allocate memory for the AP trampoline. */
+void
+alloc_ap_trampoline(vm_paddr_t *physmap, unsigned int *physmap_idx)
+{
+       unsigned int i;
+       bool allocated;
+
+       allocated = false;
+       for (i = *physmap_idx; i <= *physmap_idx; i -= 2) {
+               /*
+                * Find a memory region big enough and below the 1MB boundary
+                * for the trampoline code.
+                * NB: needs to be page aligned.
+                */
+               if (physmap[i] >= MiB(1) ||
+                   (trunc_page(physmap[i + 1]) - round_page(physmap[i])) <
+                   round_page(bootMP_size))
+                       continue;
+
+               allocated = true;
+               /*
+                * Try to steal from the end of the region to mimic previous
+                * behaviour, else fallback to steal from the start.
+                */
+               if (physmap[i + 1] < MiB(1)) {
+                       boot_address = trunc_page(physmap[i + 1]);
+                       if ((physmap[i + 1] - boot_address) < bootMP_size)
+                               boot_address -= round_page(bootMP_size);
+                       physmap[i + 1] = boot_address;
+               } else {
+                       boot_address = round_page(physmap[i]);
+                       physmap[i] = boot_address + round_page(bootMP_size);
+               }
+               if (physmap[i] == physmap[i + 1] && *physmap_idx != 0) {
+                       memmove(&physmap[i], &physmap[i + 2],
+                           sizeof(*physmap) * (*physmap_idx - i + 2));
+                       *physmap_idx -= 2;
+               }
+               break;
+       }
+
+       if (!allocated) {
+               boot_address = basemem * 1024 - bootMP_size;
+               if (bootverbose)
+                       printf(
+"Cannot find enough space for the boot trampoline, placing it at %#x",
+                           boot_address);
+       }
+}
+
 /*
  * Initialize the IPI handlers and start up the AP's.
  */
diff --git a/sys/x86/include/x86_smp.h b/sys/x86/include/x86_smp.h
index e01f869a58f6..b9a1febb70f2 100644
--- a/sys/x86/include/x86_smp.h
+++ b/sys/x86/include/x86_smp.h
@@ -23,6 +23,10 @@
 
 struct pmap;
 
+#ifdef __i386__
+extern unsigned int boot_address;
+#endif
+
 /* global data in mp_x86.c */
 extern int mp_naps;
 extern int boot_cpu_id;
@@ -32,7 +36,6 @@ extern int bootAP;
 extern void *dpcpu;
 extern char *bootSTK;
 extern void *bootstacks[];
-extern unsigned int boot_address;
 extern unsigned int bootMP_size;
 extern volatile int aps_ready;
 extern struct mtx ap_boot_mtx;
@@ -84,12 +87,15 @@ inthand_t
 typedef void (*smp_invl_cb_t)(struct pmap *, vm_offset_t addr1,
     vm_offset_t addr2);
 
+#ifdef __i386__
+void   alloc_ap_trampoline(vm_paddr_t *physmap, unsigned int *physmap_idx);
+#endif
+
 /* functions in x86_mp.c */
 void   assign_cpu_ids(void);
 void   cpu_add(u_int apic_id, char boot_cpu);
 void   cpustop_handler(void);
 void   cpususpend_handler(void);
-void   alloc_ap_trampoline(vm_paddr_t *physmap, unsigned int *physmap_idx);
 void   init_secondary_tail(void);
 void   init_secondary(void);
 void   ipi_startup(int apic_id, int vector);
diff --git a/sys/x86/x86/mp_x86.c b/sys/x86/x86/mp_x86.c
index 441a766f87fb..db40aab28ad5 100644
--- a/sys/x86/x86/mp_x86.c
+++ b/sys/x86/x86/mp_x86.c
@@ -167,14 +167,10 @@ struct cache_info {
        int     present;
 } static caches[MAX_CACHE_LEVELS];
 
-unsigned int boot_address;
-
 static bool stop_mwait = false;
 SYSCTL_BOOL(_machdep, OID_AUTO, stop_mwait, CTLFLAG_RWTUN, &stop_mwait, 0,
     "Use MONITOR/MWAIT when stopping CPU, if available");
 
-#define MiB(v) (v ## ULL << 20)
-
 void
 mem_range_AP_init(void)
 {
@@ -938,56 +934,6 @@ cpu_mp_probe(void)
        return (mp_ncpus > 1);
 }
 
-/* Allocate memory for the AP trampoline. */
-void
-alloc_ap_trampoline(vm_paddr_t *physmap, unsigned int *physmap_idx)
-{
-       unsigned int i;
-       bool allocated;
-
-       allocated = false;
-       for (i = *physmap_idx; i <= *physmap_idx; i -= 2) {
-               /*
-                * Find a memory region big enough and below the 1MB boundary
-                * for the trampoline code.
-                * NB: needs to be page aligned.
-                */
-               if (physmap[i] >= MiB(1) ||
-                   (trunc_page(physmap[i + 1]) - round_page(physmap[i])) <
-                   round_page(bootMP_size))
-                       continue;
-
-               allocated = true;
-               /*
-                * Try to steal from the end of the region to mimic previous
-                * behaviour, else fallback to steal from the start.
-                */
-               if (physmap[i + 1] < MiB(1)) {
-                       boot_address = trunc_page(physmap[i + 1]);
-                       if ((physmap[i + 1] - boot_address) < bootMP_size)
-                               boot_address -= round_page(bootMP_size);
-                       physmap[i + 1] = boot_address;
-               } else {
-                       boot_address = round_page(physmap[i]);
-                       physmap[i] = boot_address + round_page(bootMP_size);
-               }
-               if (physmap[i] == physmap[i + 1] && *physmap_idx != 0) {
-                       memmove(&physmap[i], &physmap[i + 2],
-                           sizeof(*physmap) * (*physmap_idx - i + 2));
-                       *physmap_idx -= 2;
-               }
-               break;
-       }
-
-       if (!allocated) {
-               boot_address = basemem * 1024 - bootMP_size;
-               if (bootverbose)
-                       printf(
-"Cannot find enough space for the boot trampoline, placing it at %#x",
-                           boot_address);
-       }
-}
-
 /*
  * AP CPU's call this to initialize themselves.
  */
_______________________________________________
[email protected] mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "[email protected]"

Reply via email to