path: root/sys/arm64/arm64/mp_machdep.c
diff options
authorAlan Cox <alc@FreeBSD.org>2019-11-03 17:45:30 +0000
committerAlan Cox <alc@FreeBSD.org>2019-11-03 17:45:30 +0000
commit50e3ab6bcf8c0e39e152ec356f26cf8c6df4487c (patch)
treecd33c9bed55b6a3c9757b70935a1790db91e70b7 /sys/arm64/arm64/mp_machdep.c
parent05f39d1a2d65b2960584e92f1616d7e9f1645436 (diff)
Utilize ASIDs to reduce both the direct and indirect costs of context
switching. The indirect costs being unnecessary TLB misses that are incurred when ASIDs are not used. In fact, currently, when we perform a context switch on one processor, we issue a broadcast TLB invalidation that flushes the TLB contents on every processor. Mark all user-space ("ttbr0") page table entries with the non-global flag so that they are cached in the TLB under their ASID. Correct an error in pmap_pinit0(). The pointer to the root of the page table was being initialized to the root of the kernel-space page table rather than a user-space page table. However, the root of the page table that was being cached in process 0's md_l0addr field correctly pointed to a user-space page table. As long as ASIDs weren't being used, this was harmless, except that it led to some unnecessary page table switches in pmap_switch(). Specifically, other kernel processes besides process 0 would have their md_l0addr field set to the root of the kernel-space page table, and so pmap_switch() would actually change page tables when switching between process 0 and other kernel processes. Implement a workaround for Cavium erratum 27456 affecting ThunderX machines. (I would like to thank andrew@ for providing the code to detect the affected machines.) Address integer overflow in the definition of TCR_ASID_16. Setup TCR according to the PARange and ASIDBits fields from ID_AA64MMFR0_EL1. Previously, TCR_ASID_16 was unconditionally set. Modify build_l1_block_pagetable so that lower attributes, such as ATTR_nG, can be specified as a parameter. Eliminate some unused code. Earlier versions were tested to varying degrees by: andrew, emaste, markj MFC after: 3 weeks Differential Revision: https://reviews.freebsd.org/D21922
Notes: svn path=/head/; revision=354286
Diffstat (limited to 'sys/arm64/arm64/mp_machdep.c')
1 files changed, 8 insertions, 0 deletions
diff --git a/sys/arm64/arm64/mp_machdep.c b/sys/arm64/arm64/mp_machdep.c
index db42ea763213..2efdce76c891 100644
--- a/sys/arm64/arm64/mp_machdep.c
+++ b/sys/arm64/arm64/mp_machdep.c
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
#include <vm/pmap.h>
#include <vm/vm_extern.h>
#include <vm/vm_kern.h>
+#include <vm/vm_map.h>
#include <machine/machdep.h>
#include <machine/debug_monitor.h>
@@ -192,6 +193,7 @@ void
init_secondary(uint64_t cpu)
struct pcpu *pcpup;
+ pmap_t pmap0;
pcpup = &__pcpu[cpu];
@@ -211,6 +213,12 @@ init_secondary(uint64_t cpu)
pcpup->pc_curthread = pcpup->pc_idlethread;
pcpup->pc_curpcb = pcpup->pc_idlethread->td_pcb;
+ /* Initialize curpmap to match TTBR0's current setting. */
+ pmap0 = vmspace_pmap(&vmspace0);
+ KASSERT(pmap_to_ttbr0(pmap0) == READ_SPECIALREG(ttbr0_el1),
+ ("pmap0 doesn't match cpu %ld's ttbr0", cpu));
+ pcpup->pc_curpmap = pmap0;
* Identify current CPU. This is necessary to setup
* affinity registers and to provide support for