Print this page
OS-7125 Need mitigation of L1TF (CVE-2018-3646)
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
@@ -23,11 +23,10 @@
*
* Portions Copyright 2010 Robert Milkowski
*
* Copyright 2017 Nexenta Systems, Inc. All rights reserved.
* Copyright (c) 2012, 2017 by Delphix. All rights reserved.
- * Copyright (c) 2013, Joyent, Inc. All rights reserved.
* Copyright (c) 2014 Integros [integros.com]
* Copyright (c) 2019, Joyent, Inc.
*/
/*
@@ -88,10 +87,11 @@
#include <sys/dbuf.h>
#include <sys/dmu_tx.h>
#include <sys/zfeature.h>
#include <sys/zio_checksum.h>
#include <sys/zil_impl.h>
+#include <sys/ht.h>
#include <sys/dkioc_free_util.h>
#include <sys/zfs_rlock.h>
#include "zfs_namecheck.h"
@@ -1270,10 +1270,12 @@
sync = ((!(bp->b_flags & B_ASYNC) &&
!(zv->zv_flags & ZVOL_WCE)) ||
(zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS)) &&
!doread && !is_dumpified;
+ ht_begin_unsafe();
+
/*
* There must be no buffer changes when doing a dmu_sync() because
* we can't change the data whilst calculating the checksum.
*/
locked_range_t *lr = rangelock_enter(&zv->zv_rangelock, off, resid,
@@ -1317,10 +1319,12 @@
if (sync)
zil_commit(zv->zv_zilog, ZVOL_OBJ);
biodone(bp);
+ ht_end_unsafe();
+
return (0);
}
/*
* Set the buffer count to the zvol maximum transfer.
@@ -1394,10 +1398,12 @@
error = physio(zvol_strategy, NULL, dev, B_READ,
zvol_minphys, uio);
return (error);
}
+ ht_begin_unsafe();
+
locked_range_t *lr = rangelock_enter(&zv->zv_rangelock,
uio->uio_loffset, uio->uio_resid, RL_READER);
while (uio->uio_resid > 0 && uio->uio_loffset < volsize) {
uint64_t bytes = MIN(uio->uio_resid, DMU_MAX_ACCESS >> 1);
@@ -1413,10 +1419,12 @@
break;
}
}
rangelock_exit(lr);
+ ht_end_unsafe();
+
return (error);
}
/*ARGSUSED*/
int
@@ -1441,10 +1449,12 @@
error = physio(zvol_strategy, NULL, dev, B_WRITE,
zvol_minphys, uio);
return (error);
}
+ ht_begin_unsafe();
+
sync = !(zv->zv_flags & ZVOL_WCE) ||
(zv->zv_objset->os_sync == ZFS_SYNC_ALWAYS);
locked_range_t *lr = rangelock_enter(&zv->zv_rangelock,
uio->uio_loffset, uio->uio_resid, RL_WRITER);
@@ -1472,10 +1482,13 @@
}
rangelock_exit(lr);
if (sync)
zil_commit(zv->zv_zilog, ZVOL_OBJ);
+
+ ht_end_unsafe();
+
return (error);
}
int
zvol_getefi(void *arg, int flag, uint64_t vs, uint8_t bs)
@@ -1712,15 +1725,21 @@
}
case DKIOCFLUSHWRITECACHE:
dkc = (struct dk_callback *)arg;
mutex_exit(&zfsdev_state_lock);
+
+ ht_begin_unsafe();
+
zil_commit(zv->zv_zilog, ZVOL_OBJ);
if ((flag & FKIOCTL) && dkc != NULL && dkc->dkc_callback) {
(*dkc->dkc_callback)(dkc->dkc_cookie, error);
error = 0;
}
+
+ ht_end_unsafe();
+
return (error);
case DKIOCGETWCE:
{
int wce = (zv->zv_flags & ZVOL_WCE) ? 1 : 0;
@@ -1741,11 +1760,13 @@
zv->zv_flags |= ZVOL_WCE;
mutex_exit(&zfsdev_state_lock);
} else {
zv->zv_flags &= ~ZVOL_WCE;
mutex_exit(&zfsdev_state_lock);
+ ht_begin_unsafe();
zil_commit(zv->zv_zilog, ZVOL_OBJ);
+ ht_end_unsafe();
}
return (0);
}
case DKIOCGGEOM:
@@ -1794,10 +1815,12 @@
}
}
mutex_exit(&zfsdev_state_lock);
+ ht_begin_unsafe();
+
for (int i = 0; i < dfl->dfl_num_exts; i++) {
uint64_t start = dfl->dfl_exts[i].dfle_start,
length = dfl->dfl_exts[i].dfle_length,
end = start + length;
@@ -1849,10 +1872,12 @@
}
if (!(flag & FKIOCTL))
dfl_free(dfl);
+ ht_end_unsafe();
+
return (error);
}
default:
error = SET_ERROR(ENOTTY);