Date: Sat, 21 Sep 2019 19:51:58 +0000 (UTC) From: Alan Cox <alc@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r352584 - head/sys/arm64/arm64 Message-ID: <201909211951.x8LJpwDd012346@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: alc Date: Sat Sep 21 19:51:57 2019 New Revision: 352584 URL: https://svnweb.freebsd.org/changeset/base/352584 Log: In case a translation fault on the kernel address space occurs from within a critical section, we must perform a lock-free check on the faulting address. Reported by: andrew Reviewed by: andrew, markj X-MFC with: r350579 Differential Revision: https://reviews.freebsd.org/D21685 Modified: head/sys/arm64/arm64/pmap.c Modified: head/sys/arm64/arm64/pmap.c ============================================================================== --- head/sys/arm64/arm64/pmap.c Sat Sep 21 19:05:38 2019 (r352583) +++ head/sys/arm64/arm64/pmap.c Sat Sep 21 19:51:57 2019 (r352584) @@ -5810,23 +5810,33 @@ pmap_fault(pmap_t pmap, uint64_t esr, uint64_t far) case ISS_DATA_DFSC_TF_L1: case ISS_DATA_DFSC_TF_L2: case ISS_DATA_DFSC_TF_L3: - PMAP_LOCK(pmap); - /* Ask the MMU to check the address */ - intr = intr_disable(); - if (pmap == kernel_pmap) - par = arm64_address_translate_s1e1r(far); - else - par = arm64_address_translate_s1e0r(far); - intr_restore(intr); - PMAP_UNLOCK(pmap); - /* - * If the translation was successful the address was invalid - * due to a break-before-make sequence. We can unlock and - * return success to the trap handler. + * Retry the translation. A break-before-make sequence can + * produce a transient fault. */ - if (PAR_SUCCESS(par)) - rv = KERN_SUCCESS; + if (pmap == kernel_pmap) { + /* + * The translation fault may have occurred within a + * critical section. Therefore, we must check the + * address without acquiring the kernel pmap's lock. + */ + if (pmap_kextract(far) != 0) + rv = KERN_SUCCESS; + } else { + PMAP_LOCK(pmap); + /* Ask the MMU to check the address. */ + intr = intr_disable(); + par = arm64_address_translate_s1e0r(far); + intr_restore(intr); + PMAP_UNLOCK(pmap); + + /* + * If the translation was successful, then we can + * return success to the trap handler. + */ + if (PAR_SUCCESS(par)) + rv = KERN_SUCCESS; + } break; }
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201909211951.x8LJpwDd012346>