diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2017-11-01 01:20:50 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2017-11-01 01:26:48 +0100 |
commit | 4282cb6241f47f9db9071814c284fd8a704b3cf3 (patch) | |
tree | b0c26c4f8fd39406c3bd85293bccb9b1074051ae /linux | |
parent | 0e91d138a30a85eedceb3dbfd28b478a83232979 (diff) | |
download | gnumach-4282cb6241f47f9db9071814c284fd8a704b3cf3.tar.gz gnumach-4282cb6241f47f9db9071814c284fd8a704b3cf3.tar.bz2 gnumach-4282cb6241f47f9db9071814c284fd8a704b3cf3.zip |
linux block: fix outbound access to non-directmap user data
* linux/dev/glue/block.c (rdwr_full): Set BH_Bounce if the physical
address of the user data is not in directmap.
Diffstat (limited to 'linux')
-rw-r--r-- | linux/dev/glue/block.c | 10 |
1 files changed, 6 insertions, 4 deletions
diff --git a/linux/dev/glue/block.c b/linux/dev/glue/block.c index a8fa9153..0a5b1c87 100644 --- a/linux/dev/glue/block.c +++ b/linux/dev/glue/block.c @@ -578,6 +578,7 @@ rdwr_full (int rw, kdev_t dev, loff_t *off, char **buf, int *resid, int bshift) int cc, err = 0, i, j, nb, nbuf; long blk; struct buffer_head bhead[MAX_BUF], *bh, *bhp[MAX_BUF]; + phys_addr_t pa; assert ((*off & BMASK) == 0); @@ -592,7 +593,10 @@ rdwr_full (int rw, kdev_t dev, loff_t *off, char **buf, int *resid, int bshift) if (rw == WRITE) set_bit (BH_Dirty, &bh->b_state); cc = PAGE_SIZE - (((int) *buf + (nb << bshift)) & PAGE_MASK); - if (cc >= BSIZE && (((int) *buf + (nb << bshift)) & 511) == 0) + pa = pmap_extract (vm_map_pmap (device_io_map), + (((vm_offset_t) *buf) + (nb << bshift))); + if (cc >= BSIZE && (((int) *buf + (nb << bshift)) & 511) == 0 + && pa + cc <= VM_PAGE_DIRECTMAP_LIMIT) cc &= ~BMASK; else { @@ -602,9 +606,7 @@ rdwr_full (int rw, kdev_t dev, loff_t *off, char **buf, int *resid, int bshift) if (cc > ((nbuf - nb) << bshift)) cc = (nbuf - nb) << bshift; if (! test_bit (BH_Bounce, &bh->b_state)) - bh->b_data = (char *) phystokv(pmap_extract (vm_map_pmap (device_io_map), - (((vm_offset_t) *buf) - + (nb << bshift)))); + bh->b_data = (char *) phystokv(pa); else { bh->b_data = alloc_buffer (cc); |