diff --git a/sys/amd64/amd64/support.S b/sys/amd64/amd64/support.S index ae2793aa758..6e541b75cda 100644 --- a/sys/amd64/amd64/support.S +++ b/sys/amd64/amd64/support.S @@ -1969,3 +1969,24 @@ ENTRY(mds_handler_silvermont) popq %rax retq END(mds_handler_silvermont) + +/* + * Do the same as Linux and execute IRET explicitly, despite IPI + * return does it as well. + */ +ENTRY(cpu_sync_core) +/* + * Can utilize SERIALIZE when instruction is moved from + * 'future extensions' to SDM. + */ + movq (%rsp), %rdx + movl %ss, %eax + pushq %rax + pushq %rsp + addq $16, (%rsp) + pushfq + movl %cs, %eax + pushq %rax + pushq %rdx + iretq +END(cpu_sync_core) diff --git a/sys/arm/arm/vm_machdep.c b/sys/arm/arm/vm_machdep.c index ace6b4ce668..b7c08cd4e97 100644 --- a/sys/arm/arm/vm_machdep.c +++ b/sys/arm/arm/vm_machdep.c @@ -311,3 +311,8 @@ cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, return (EINVAL); } + +void +cpu_sync_core(void) +{ +} diff --git a/sys/arm64/arm64/vm_machdep.c b/sys/arm64/arm64/vm_machdep.c index 06e063d916f..5e45b45dc32 100644 --- a/sys/arm64/arm64/vm_machdep.c +++ b/sys/arm64/arm64/vm_machdep.c @@ -310,3 +310,14 @@ cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, return (EINVAL); } + +void +cpu_sync_core(void) +{ + /* + * Do nothing. According to ARM ARMv8 D1.11 Exception return + * If FEAT_ExS is not implemented, or if FEAT_ExS is + * implemented and the SCTLR_ELx.EOS field is set, exception + * return from ELx is a context synchronization event. + */ +} diff --git a/sys/i386/i386/support.S b/sys/i386/i386/support.S index 58c01f37a3f..982108a0b96 100644 --- a/sys/i386/i386/support.S +++ b/sys/i386/i386/support.S @@ -578,3 +578,11 @@ ENTRY(mds_handler_silvermont) movl %eax, %cr0 3: ret END(mds_handler_silvermont) + +ENTRY(cpu_sync_core) + popl %eax + pushfl + pushl %cs + pushl %eax + iretl +END(cpu_sync_core) diff --git a/sys/powerpc/powerpc/vm_machdep.c b/sys/powerpc/powerpc/vm_machdep.c index b53da3dd04f..1a31959b278 100644 --- a/sys/powerpc/powerpc/vm_machdep.c +++ b/sys/powerpc/powerpc/vm_machdep.c @@ -239,3 +239,13 @@ cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, return (EINVAL); } + +void +cpu_sync_core(void) +{ + /* + * Linux performs "rfi" there. Our rendezvous IPI handler on + * the target cpu does "rfi" before and lwsync/sync after the + * action, which is stronger than required. + */ +} diff --git a/sys/riscv/riscv/vm_machdep.c b/sys/riscv/riscv/vm_machdep.c index 3b2553996bb..58acf5df9e1 100644 --- a/sys/riscv/riscv/vm_machdep.c +++ b/sys/riscv/riscv/vm_machdep.c @@ -49,6 +49,7 @@ #include #include +#include #include #include #include @@ -267,3 +268,9 @@ cpu_procctl(struct thread *td __unused, int idtype __unused, id_t id __unused, return (EINVAL); } + +void +cpu_sync_core(void) +{ + fence_i(); +} diff --git a/sys/sys/proc.h b/sys/sys/proc.h index a3544669052..05ab914af40 100644 --- a/sys/sys/proc.h +++ b/sys/sys/proc.h @@ -1229,6 +1229,7 @@ void cpu_idle(int); int cpu_idle_wakeup(int); extern void (*cpu_idle_hook)(sbintime_t); /* Hook to machdep CPU idler. */ void cpu_switch(struct thread *, struct thread *, struct mtx *); +void cpu_sync_core(void); void cpu_throw(struct thread *, struct thread *) __dead2; bool curproc_sigkilled(void); void userret(struct thread *, struct trapframe *);