Print this page
10924 Need mitigation of L1TF (CVE-2018-3646)
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Peter Tribble <peter.tribble@gmail.com>

@@ -23,13 +23,12 @@
  *
  * 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.
+ * Copyright 2019 Joyent, Inc.
  */
 
 /*
  * ZFS volume emulation driver.
  *

@@ -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);