diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2013-03-19 14:43:57 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2013-03-19 14:43:57 +0000 |
commit | e81ff91e620e9485d5573d96e6893875f446b3b2 (patch) | |
tree | e048114eb9989a7f49051ebcc4027da6e0a571e4 /sys/kern/vfs_bio.c | |
parent | 2cc718a11c906f87202048034d5e384be16b9cfe (diff) | |
download | src-e81ff91e620e9485d5573d96e6893875f446b3b2.tar.gz src-e81ff91e620e9485d5573d96e6893875f446b3b2.zip |
Do not remap usermode pages into KVA for physio.
Sponsored by: The FreeBSD Foundation
Tested by: pho
Notes
Notes:
svn path=/head/; revision=248515
Diffstat (limited to 'sys/kern/vfs_bio.c')
-rw-r--r-- | sys/kern/vfs_bio.c | 24 |
1 files changed, 17 insertions, 7 deletions
diff --git a/sys/kern/vfs_bio.c b/sys/kern/vfs_bio.c index 6f790d230b54..19eb89567d47 100644 --- a/sys/kern/vfs_bio.c +++ b/sys/kern/vfs_bio.c @@ -4279,7 +4279,7 @@ vm_hold_free_pages(struct buf *bp, int newbsize) * check the return value. */ int -vmapbuf(struct buf *bp) +vmapbuf(struct buf *bp, int mapbuf) { caddr_t kva; vm_prot_t prot; @@ -4294,12 +4294,19 @@ vmapbuf(struct buf *bp) (vm_offset_t)bp->b_data, bp->b_bufsize, prot, bp->b_pages, btoc(MAXPHYS))) < 0) return (-1); - pmap_qenter((vm_offset_t)bp->b_saveaddr, bp->b_pages, pidx); - - kva = bp->b_saveaddr; bp->b_npages = pidx; - bp->b_saveaddr = bp->b_data; - bp->b_data = kva + (((vm_offset_t) bp->b_data) & PAGE_MASK); + if (mapbuf || !unmapped_buf_allowed) { + pmap_qenter((vm_offset_t)bp->b_saveaddr, bp->b_pages, pidx); + kva = bp->b_saveaddr; + bp->b_saveaddr = bp->b_data; + bp->b_data = kva + (((vm_offset_t)bp->b_data) & PAGE_MASK); + bp->b_flags &= ~B_UNMAPPED; + } else { + bp->b_flags |= B_UNMAPPED; + bp->b_offset = ((vm_offset_t)bp->b_data) & PAGE_MASK; + bp->b_saveaddr = bp->b_data; + bp->b_data = unmapped_buf; + } return(0); } @@ -4313,7 +4320,10 @@ vunmapbuf(struct buf *bp) int npages; npages = bp->b_npages; - pmap_qremove(trunc_page((vm_offset_t)bp->b_data), npages); + if (bp->b_flags & B_UNMAPPED) + bp->b_flags &= ~B_UNMAPPED; + else + pmap_qremove(trunc_page((vm_offset_t)bp->b_data), npages); vm_page_unhold_pages(bp->b_pages, npages); bp->b_data = bp->b_saveaddr; |