git: a8d453eec1e3 - stable/13 - amd64: stop doing special allocation for the AP startup trampoline
Konstantin Belousov
kib at FreeBSD.org
Mon Aug 23 23:22:21 UTC 2021
The branch stable/13 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=a8d453eec1e3ea7c62e82a8e591035876da2580e
commit a8d453eec1e3ea7c62e82a8e591035876da2580e
Author: Konstantin Belousov <kib at FreeBSD.org>
AuthorDate: 2021-07-29 00:22:35 +0000
Commit: Konstantin Belousov <kib at FreeBSD.org>
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.
*/
More information about the dev-commits-src-all
mailing list