From owner-dev-commits-src-branches@freebsd.org Mon Aug 23 23:22:21 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id 80EE26738C2; Mon, 23 Aug 2021 23:22:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4GtpDY2ftXz3tYX; Mon, 23 Aug 2021 23:22:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 3C0981D0B5; Mon, 23 Aug 2021 23:22:21 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 17NNMLPi094606; Mon, 23 Aug 2021 23:22:21 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 17NNML4T094605; Mon, 23 Aug 2021 23:22:21 GMT (envelope-from git) Date: Mon, 23 Aug 2021 23:22:21 GMT Message-Id: <202108232322.17NNML4T094605@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Konstantin Belousov Subject: git: a8d453eec1e3 - stable/13 - amd64: stop doing special allocation for the AP startup trampoline MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: kib X-Git-Repository: src X-Git-Refname: refs/heads/stable/13 X-Git-Reftype: branch X-Git-Commit: a8d453eec1e3ea7c62e82a8e591035876da2580e Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 23 Aug 2021 23:22:21 -0000 The branch stable/13 has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=a8d453eec1e3ea7c62e82a8e591035876da2580e commit a8d453eec1e3ea7c62e82a8e591035876da2580e Author: Konstantin Belousov AuthorDate: 2021-07-29 00:22:35 +0000 Commit: Konstantin Belousov 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. */