Date: Mon, 29 Jul 2019 14:59:14 +0000 (UTC) From: Kristof Provost <kp@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r350416 - head/sys/riscv/riscv Message-ID: <201907291459.x6TExE8x094444@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kp Date: Mon Jul 29 14:59:14 2019 New Revision: 350416 URL: https://svnweb.freebsd.org/changeset/base/350416 Log: riscv: Fix copyin/copyout r343275 introduced a performance optimisation to the copyin/copyout routines by attempting to copy word-per-word rather than byte-per-byte where possible. This optimisation failed to account for cases where the buffer is longer than XLEN_BYTES, but due to misalignment does not not allow for any word-sized copies. E.g. a 9 byte buffer (with XLEN_BYTES == 8) which is misaligned by 2 bytes. The code nevertheless did a single full-word copy, which meant we copied too much data. This potentially clobbered other data. This is most easily demonstrated by a simple `sysctl -a`. Fix it by not assuming that we'll always have at least one full-word copy to do, but instead checking the remaining length first. Reviewed by: markj@, mhorne@, br@ (previous version) MFC after: 1 week Sponsored by: Axiado Differential Revision: https://reviews.freebsd.org/D21100 Modified: head/sys/riscv/riscv/copyinout.S Modified: head/sys/riscv/riscv/copyinout.S ============================================================================== --- head/sys/riscv/riscv/copyinout.S Mon Jul 29 14:58:29 2019 (r350415) +++ head/sys/riscv/riscv/copyinout.S Mon Jul 29 14:59:14 2019 (r350416) @@ -65,7 +65,7 @@ END(copyio_fault) ENTER_USER_ACCESS(a7) li t2, XLEN_BYTES - blt a2, t2, 3f /* Byte-copy if len < XLEN_BYTES */ + blt a2, t2, 4f /* Byte-copy if len < XLEN_BYTES */ /* * Compare lower bits of src and dest. @@ -73,7 +73,7 @@ END(copyio_fault) */ andi t0, a0, (XLEN_BYTES-1) /* Low bits of src */ andi t1, a1, (XLEN_BYTES-1) /* Low bits of dest */ - bne t0, t1, 3f /* Misaligned. Go to byte copy */ + bne t0, t1, 4f /* Misaligned. Go to byte copy */ beqz t0, 2f /* Already word-aligned, skip ahead */ /* Byte copy until the first word-aligned address */ @@ -84,6 +84,7 @@ END(copyio_fault) addi a2, a2, -1 /* len-- */ andi t0, a0, (XLEN_BYTES-1) bnez t0, 1b + j 3f /* Copy words */ 2: ld a4, 0(a0) /* Load word from src */ @@ -91,20 +92,20 @@ END(copyio_fault) sd a4, 0(a1) /* Store word in dest */ addi a1, a1, XLEN_BYTES addi a2, a2, -XLEN_BYTES /* len -= XLEN_BYTES */ - bgeu a2, t2, 2b /* Again if len >= XLEN_BYTES */ +3: bgeu a2, t2, 2b /* Again if len >= XLEN_BYTES */ /* Check if we're finished */ - beqz a2, 4f + beqz a2, 5f /* Copy any remaining bytes */ -3: lb a4, 0(a0) /* Load byte from src */ +4: lb a4, 0(a0) /* Load byte from src */ addi a0, a0, 1 sb a4, 0(a1) /* Store byte in dest */ addi a1, a1, 1 addi a2, a2, -1 /* len-- */ - bnez a2, 3b + bnez a2, 4b -4: EXIT_USER_ACCESS(a7) +5: EXIT_USER_ACCESS(a7) SET_FAULT_HANDLER(x0, a7) /* Clear the handler */ .endm
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201907291459.x6TExE8x094444>