Index: svs.c =================================================================== RCS file: /cvsroot/src/sys/arch/x86/x86/svs.c,v retrieving revision 1.35 diff -u -p -r1.35 svs.c --- svs.c 2 May 2020 11:37:17 -0000 1.35 +++ svs.c 19 May 2020 22:47:34 -0000 @@ -1,7 +1,7 @@ /* $NetBSD: svs.c,v 1.35 2020/05/02 11:37:17 maxv Exp $ */ /* - * Copyright (c) 2018-2019 The NetBSD Foundation, Inc. + * Copyright (c) 2018-2020 The NetBSD Foundation, Inc. * All rights reserved. * * This code is derived from software contributed to The NetBSD Foundation @@ -575,6 +575,18 @@ svs_pmap_sync(struct pmap *pmap, int ind KASSERT(kpreempt_disabled()); KASSERT(index < PDIR_SLOT_USERLIM); + ci = curcpu(); + cid = cpu_index(ci); + + mutex_enter(&ci->ci_svs_mtx); + KASSERT(kcpuset_isset(pmap->pm_kernel_cpus, cid)); + ci->ci_svs_updir[index] = pmap->pm_pdir[index]; + mutex_exit(&ci->ci_svs_mtx); + + if (!kcpuset_isotherset(pmap->pm_kernel_cpus, cid)) { + return; + } + for (CPU_INFO_FOREACH(cii, ci)) { cid = cpu_index(ci); @@ -670,28 +682,16 @@ svs_lwp_switch(struct lwp *oldlwp, struc } } -static inline pt_entry_t -svs_pte_atomic_read(struct pmap *pmap, size_t idx) -{ - /* - * XXX: We don't have a basic atomic_fetch_64 function? - */ - return atomic_cas_64(&pmap->pm_pdir[idx], 666, 666); -} - /* - * We may come here with the pmap unlocked. So read its PTEs atomically. If - * a remote CPU is updating them at the same time, it's not a problem: the - * remote CPU will call svs_pmap_sync afterwards, and our updirpa will be - * synchronized properly. + * We may come here with the pmap unlocked. If a remote CPU is updating + * them at the same time, it's not a problem: the remote CPU will call + * svs_pmap_sync afterwards, and our updirpa will be synchronized properly. */ void svs_pdir_switch(struct pmap *pmap) { struct cpu_info *ci = curcpu(); struct svs_utls *utls; - pt_entry_t pte; - size_t i; KASSERT(kpreempt_disabled()); KASSERT(pmap != pmap_kernel()); @@ -700,14 +700,10 @@ svs_pdir_switch(struct pmap *pmap) utls = (struct svs_utls *)ci->ci_svs_utls; utls->kpdirpa = pmap_pdirpa(pmap, 0) | svs_pcid_kcr3; + /* Copy user slots. */ mutex_enter(&ci->ci_svs_mtx); - - /* User slots. */ - for (i = 0; i < PDIR_SLOT_USERLIM; i++) { - pte = svs_pte_atomic_read(pmap, i); - ci->ci_svs_updir[i] = pte; - } - + memcpy(ci->ci_svs_updir, pmap->pm_pdir, PDIR_SLOT_USERLIM * + sizeof(pt_entry_t)); mutex_exit(&ci->ci_svs_mtx); if (svs_pcid) {