Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 27 Jul 2020 01:20:49 +0000 (UTC)
From:      Rick Macklem <rmacklem@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r363591 - in projects/nfs-over-tls/sys: amd64/amd64 amd64/include cddl/compat/opensolaris/kern cddl/contrib/opensolaris/uts/common/fs/zfs cddl/contrib/opensolaris/uts/common/fs/zfs/sys ...
Message-ID:  <202007270120.06R1KnsV089441@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: rmacklem
Date: Mon Jul 27 01:20:49 2020
New Revision: 363591
URL: https://svnweb.freebsd.org/changeset/base/363591

Log:
  Merge in an up to date kernel from head.

Added:
  projects/nfs-over-tls/sys/dev/extres/syscon/syscon_power.c
     - copied unchanged from r363587, head/sys/dev/extres/syscon/syscon_power.c
  projects/nfs-over-tls/sys/dev/goldfish/
     - copied from r363587, head/sys/dev/goldfish/
  projects/nfs-over-tls/sys/dev/iommu/iommu_gas.c
     - copied unchanged from r363587, head/sys/dev/iommu/iommu_gas.c
  projects/nfs-over-tls/sys/riscv/riscv/riscv_syscon.c
     - copied unchanged from r363587, head/sys/riscv/riscv/riscv_syscon.c
  projects/nfs-over-tls/sys/sys/_seqc.h
     - copied unchanged from r363587, head/sys/sys/_seqc.h
Deleted:
  projects/nfs-over-tls/sys/x86/iommu/intel_gas.c
Modified:
  projects/nfs-over-tls/sys/amd64/amd64/apic_vector.S
  projects/nfs-over-tls/sys/amd64/amd64/mp_machdep.c
  projects/nfs-over-tls/sys/amd64/include/smp.h
  projects/nfs-over-tls/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
  projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
  projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
  projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
  projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
  projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
  projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/hardirq.h
  projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/kernel.h
  projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/lockdep.h
  projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/preempt.h
  projects/nfs-over-tls/sys/conf/files
  projects/nfs-over-tls/sys/conf/files.arm64
  projects/nfs-over-tls/sys/conf/files.riscv
  projects/nfs-over-tls/sys/conf/files.x86
  projects/nfs-over-tls/sys/dev/extres/clk/clk.c
  projects/nfs-over-tls/sys/dev/iommu/busdma_iommu.c
  projects/nfs-over-tls/sys/dev/iommu/iommu.h
  projects/nfs-over-tls/sys/dev/usb/net/if_ure.c
  projects/nfs-over-tls/sys/dev/usb/net/if_urereg.h
  projects/nfs-over-tls/sys/fs/nfs/nfs_commonsubs.c
  projects/nfs-over-tls/sys/fs/nfsserver/nfs_nfsdport.c
  projects/nfs-over-tls/sys/fs/tmpfs/tmpfs.h
  projects/nfs-over-tls/sys/fs/tmpfs/tmpfs_subr.c
  projects/nfs-over-tls/sys/fs/tmpfs/tmpfs_vfsops.c
  projects/nfs-over-tls/sys/fs/tmpfs/tmpfs_vnops.c
  projects/nfs-over-tls/sys/fs/tmpfs/tmpfs_vnops.h
  projects/nfs-over-tls/sys/geom/geom.h
  projects/nfs-over-tls/sys/geom/geom_ccd.c
  projects/nfs-over-tls/sys/geom/geom_ctl.c
  projects/nfs-over-tls/sys/geom/geom_map.c
  projects/nfs-over-tls/sys/geom/geom_redboot.c
  projects/nfs-over-tls/sys/geom/label/g_label.c
  projects/nfs-over-tls/sys/geom/label/g_label.h
  projects/nfs-over-tls/sys/geom/label/g_label_disk_ident.c
  projects/nfs-over-tls/sys/geom/label/g_label_ext2fs.c
  projects/nfs-over-tls/sys/geom/label/g_label_flashmap.c
  projects/nfs-over-tls/sys/geom/label/g_label_gpt.c
  projects/nfs-over-tls/sys/geom/label/g_label_iso9660.c
  projects/nfs-over-tls/sys/geom/label/g_label_msdosfs.c
  projects/nfs-over-tls/sys/geom/label/g_label_ntfs.c
  projects/nfs-over-tls/sys/geom/label/g_label_reiserfs.c
  projects/nfs-over-tls/sys/geom/label/g_label_ufs.c
  projects/nfs-over-tls/sys/geom/part/g_part_vtoc8.c
  projects/nfs-over-tls/sys/geom/virstor/g_virstor.c
  projects/nfs-over-tls/sys/i386/i386/apic_vector.s
  projects/nfs-over-tls/sys/i386/i386/mp_machdep.c
  projects/nfs-over-tls/sys/kern/kern_clock.c
  projects/nfs-over-tls/sys/kern/kern_descrip.c
  projects/nfs-over-tls/sys/kern/kern_intr.c
  projects/nfs-over-tls/sys/kern/kern_kthread.c
  projects/nfs-over-tls/sys/kern/subr_blist.c
  projects/nfs-over-tls/sys/kern/uipc_sockbuf.c
  projects/nfs-over-tls/sys/kern/vfs_cache.c
  projects/nfs-over-tls/sys/kern/vfs_lookup.c
  projects/nfs-over-tls/sys/kern/vfs_mount.c
  projects/nfs-over-tls/sys/kern/vfs_subr.c
  projects/nfs-over-tls/sys/kern/vnode_if.src
  projects/nfs-over-tls/sys/riscv/conf/GENERIC
  projects/nfs-over-tls/sys/security/mac/mac_framework.h
  projects/nfs-over-tls/sys/sys/_eventhandler.h
  projects/nfs-over-tls/sys/sys/blist.h
  projects/nfs-over-tls/sys/sys/filedesc.h
  projects/nfs-over-tls/sys/sys/interrupt.h
  projects/nfs-over-tls/sys/sys/mount.h
  projects/nfs-over-tls/sys/sys/namei.h
  projects/nfs-over-tls/sys/sys/param.h
  projects/nfs-over-tls/sys/sys/resourcevar.h
  projects/nfs-over-tls/sys/sys/seqc.h
  projects/nfs-over-tls/sys/sys/vnode.h
  projects/nfs-over-tls/sys/ufs/ffs/ffs_vfsops.c
  projects/nfs-over-tls/sys/ufs/ffs/ffs_vnops.c
  projects/nfs-over-tls/sys/ufs/ufs/inode.h
  projects/nfs-over-tls/sys/ufs/ufs/ufs_acl.c
  projects/nfs-over-tls/sys/ufs/ufs/ufs_vnops.c
  projects/nfs-over-tls/sys/vm/swap_pager.c
  projects/nfs-over-tls/sys/x86/include/apicvar.h
  projects/nfs-over-tls/sys/x86/include/x86_smp.h
  projects/nfs-over-tls/sys/x86/iommu/intel_ctx.c
  projects/nfs-over-tls/sys/x86/iommu/intel_dmar.h
  projects/nfs-over-tls/sys/x86/iommu/intel_drv.c
  projects/nfs-over-tls/sys/x86/iommu/intel_idpgtbl.c
  projects/nfs-over-tls/sys/x86/iommu/intel_utils.c
  projects/nfs-over-tls/sys/x86/x86/mp_x86.c
  projects/nfs-over-tls/sys/x86/xen/xen_apic.c
Directory Properties:
  projects/nfs-over-tls/sys/   (props changed)
  projects/nfs-over-tls/sys/cddl/contrib/opensolaris/   (props changed)

Modified: projects/nfs-over-tls/sys/amd64/amd64/apic_vector.S
==============================================================================
--- projects/nfs-over-tls/sys/amd64/amd64/apic_vector.S	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/amd64/amd64/apic_vector.S	Mon Jul 27 01:20:49 2020	(r363591)
@@ -206,6 +206,16 @@ IDTVEC(spuriousint)
 	jmp	doreti
 
 /*
+ * Executed by a CPU when it receives an IPI_SWI.
+ */
+	INTR_HANDLER ipi_swi
+	call	as_lapic_eoi
+	FAKE_MCOUNT(TF_RIP(%rsp))
+	call	ipi_swi_handler
+	MEXITCOUNT
+	jmp	doreti
+
+/*
  * Executed by a CPU when it receives a RENDEZVOUS IPI from another CPU.
  *
  * - Calls the generic rendezvous action function.

Modified: projects/nfs-over-tls/sys/amd64/amd64/mp_machdep.c
==============================================================================
--- projects/nfs-over-tls/sys/amd64/amd64/mp_machdep.c	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/amd64/amd64/mp_machdep.c	Mon Jul 27 01:20:49 2020	(r363591)
@@ -223,6 +223,10 @@ cpu_mp_start(void)
 	setidt(IPI_SUSPEND, pti ? IDTVEC(cpususpend_pti) : IDTVEC(cpususpend),
 	    SDT_SYSIGT, SEL_KPL, 0);
 
+	/* Install an IPI for calling delayed SWI */
+	setidt(IPI_SWI, pti ? IDTVEC(ipi_swi_pti) : IDTVEC(ipi_swi),
+	    SDT_SYSIGT, SEL_KPL, 0);
+
 	/* Set boot_cpu_id if needed. */
 	if (boot_cpu_id == -1) {
 		boot_cpu_id = PCPU_GET(apic_id);

Modified: projects/nfs-over-tls/sys/amd64/include/smp.h
==============================================================================
--- projects/nfs-over-tls/sys/amd64/include/smp.h	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/amd64/include/smp.h	Mon Jul 27 01:20:49 2020	(r363591)
@@ -32,6 +32,7 @@ inthand_t
 	IDTVEC(invlop_pti),
 	IDTVEC(invlop),
 	IDTVEC(ipi_intr_bitmap_handler_pti),
+	IDTVEC(ipi_swi_pti),
 	IDTVEC(cpustop_pti),
 	IDTVEC(cpususpend_pti),
 	IDTVEC(rendezvous_pti);

Modified: projects/nfs-over-tls/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c
==============================================================================
--- projects/nfs-over-tls/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c	Mon Jul 27 01:20:49 2020	(r363591)
@@ -154,6 +154,7 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const cha
 		vput(vp);
 		return (error);
 	}
+	vn_seqc_write_begin(vp);
 	VOP_UNLOCK(vp);
 
 	/*
@@ -206,6 +207,7 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const cha
 		VI_LOCK(vp);
 		vp->v_iflag &= ~VI_MOUNT;
 		VI_UNLOCK(vp);
+		vn_seqc_write_end(vp);
 		vput(vp);
 		vfs_unbusy(mp);
 		vfs_freeopts(mp->mnt_optnew);
@@ -241,6 +243,7 @@ mount_snapshot(kthread_t *td, vnode_t **vpp, const cha
 	vfs_event_signal(NULL, VQ_MOUNT, 0);
 	if (VFS_ROOT(mp, LK_EXCLUSIVE, &mvp))
 		panic("mount: lost mount");
+	vn_seqc_write_end(vp);
 	VOP_UNLOCK(vp);
 	vfs_op_exit(mp);
 	vfs_unbusy(mp);

Modified: projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h
==============================================================================
--- projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/sys/zfs_znode.h	Mon Jul 27 01:20:49 2020	(r363591)
@@ -246,6 +246,8 @@ VTOZ(vnode_t *vp)
 #define	VTOZ(VP)	((znode_t *)(VP)->v_data)
 #endif
 
+#define	VTOZ_SMR(VP)	((znode_t *)vn_load_v_data_smr(VP))
+
 /* Called on entry to each ZFS vnode and vfs operation  */
 #define	ZFS_ENTER(zfsvfs) \
 	{ \

Modified: projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c
==============================================================================
--- projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_acl.c	Mon Jul 27 01:20:49 2020	(r363591)
@@ -1146,6 +1146,7 @@ zfs_acl_chown_setattr(znode_t *zp)
 
 	ASSERT_VOP_ELOCKED(ZTOV(zp), __func__);
 	ASSERT(MUTEX_HELD(&zp->z_acl_lock));
+	ASSERT_VOP_IN_SEQC(ZTOV(zp));
 
 	if ((error = zfs_acl_node_read(zp, &aclp, B_FALSE)) == 0)
 		zp->z_mode = zfs_mode_compute(zp->z_mode, aclp,
@@ -1172,6 +1173,8 @@ zfs_aclset_common(znode_t *zp, zfs_acl_t *aclp, cred_t
 	uint64_t		ctime[2];
 	int			count = 0;
 	zfs_acl_phys_t		acl_phys;
+
+	ASSERT_VOP_IN_SEQC(ZTOV(zp));
 
 	mode = zp->z_mode;
 

Modified: projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c
==============================================================================
--- projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vfsops.c	Mon Jul 27 01:20:49 2020	(r363591)
@@ -1391,6 +1391,9 @@ zfs_domount(vfs_t *vfsp, char *osname)
 
 	vfsp->vfs_data = zfsvfs;
 	vfsp->mnt_flag |= MNT_LOCAL;
+#if defined(_KERNEL) && !defined(KMEM_DEBUG)
+	vfsp->mnt_kern_flag |= MNTK_FPLOOKUP;
+#endif
 	vfsp->mnt_kern_flag |= MNTK_LOOKUP_SHARED;
 	vfsp->mnt_kern_flag |= MNTK_SHARED_WRITES;
 	vfsp->mnt_kern_flag |= MNTK_EXTENDED_SHARED;

Modified: projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c
==============================================================================
--- projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c	Mon Jul 27 01:20:49 2020	(r363591)
@@ -38,6 +38,7 @@
 #include <sys/vfs.h>
 #include <sys/vm.h>
 #include <sys/vnode.h>
+#include <sys/smr.h>
 #include <sys/file.h>
 #include <sys/stat.h>
 #include <sys/kmem.h>
@@ -78,6 +79,8 @@
 #include <vm/vm_param.h>
 #include <sys/zil.h>
 
+VFS_SMR_DECLARE;
+
 /*
  * Programming rules.
  *
@@ -3698,6 +3701,7 @@ zfs_rename(vnode_t *sdvp, vnode_t **svpp, struct compo
 	char		*snm = scnp->cn_nameptr;
 	char		*tnm = tcnp->cn_nameptr;
 	int		error = 0;
+	bool		want_seqc_end = false;
 
 	/* Reject renames across filesystems. */
 	if ((*svpp)->v_mount != tdvp->v_mount ||
@@ -3828,6 +3832,14 @@ zfs_rename(vnode_t *sdvp, vnode_t **svpp, struct compo
 		}
 	}
 
+	vn_seqc_write_begin(*svpp);
+	vn_seqc_write_begin(sdvp);
+	if (*tvpp != NULL)
+		vn_seqc_write_begin(*tvpp);
+	if (tdvp != *tvpp)
+		vn_seqc_write_begin(tdvp);
+	want_seqc_end = true;
+
 	vnevent_rename_src(*svpp, sdvp, scnp->cn_nameptr, ct);
 	if (tzp)
 		vnevent_rename_dest(*tvpp, tdvp, tnm, ct);
@@ -3914,10 +3926,20 @@ zfs_rename(vnode_t *sdvp, vnode_t **svpp, struct compo
 
 unlockout:			/* all 4 vnodes are locked, ZFS_ENTER called */
 	ZFS_EXIT(zfsvfs);
+	if (want_seqc_end) {
+		vn_seqc_write_end(*svpp);
+		vn_seqc_write_end(sdvp);
+		if (*tvpp != NULL)
+			vn_seqc_write_end(*tvpp);
+		if (tdvp != *tvpp)
+			vn_seqc_write_end(tdvp);
+		want_seqc_end = false;
+	}
 	VOP_UNLOCK(*svpp);
 	VOP_UNLOCK(sdvp);
 
 out:				/* original two vnodes are locked */
+	MPASS(!want_seqc_end);
 	if (error == 0 && zfsvfs->z_os->os_sync == ZFS_SYNC_ALWAYS)
 		zil_commit(zilog, 0);
 
@@ -4861,7 +4883,32 @@ zfs_freebsd_write(ap)
 	    ap->a_cred, NULL));
 }
 
+/*
+ * VOP_FPLOOKUP_VEXEC routines are subject to special circumstances, see
+ * the comment above cache_fplookup for details.
+ */
 static int
+zfs_freebsd_fplookup_vexec(struct vop_fplookup_vexec_args *v)
+{
+	vnode_t *vp;
+	znode_t *zp;
+	uint64_t pflags;
+
+	vp = v->a_vp;
+	zp = VTOZ_SMR(vp);
+	if (__predict_false(zp == NULL))
+		return (EAGAIN);
+	pflags = atomic_load_64(&zp->z_pflags);
+	if (pflags & ZFS_AV_QUARANTINED)
+		return (EAGAIN);
+	if (pflags & ZFS_XATTR)
+		return (EAGAIN);
+	if ((pflags & ZFS_NO_EXECS_DENIED) == 0)
+		return (EAGAIN);
+	return (0);
+}
+
+static int
 zfs_freebsd_access(ap)
 	struct vop_access_args /* {
 		struct vnode *a_vp;
@@ -5998,6 +6045,7 @@ struct vop_vector zfs_vnodeops = {
 	.vop_inactive =		zfs_freebsd_inactive,
 	.vop_need_inactive =	zfs_freebsd_need_inactive,
 	.vop_reclaim =		zfs_freebsd_reclaim,
+	.vop_fplookup_vexec =	zfs_freebsd_fplookup_vexec,
 	.vop_access =		zfs_freebsd_access,
 	.vop_allocate =		VOP_EINVAL,
 	.vop_lookup =		zfs_cache_lookup,
@@ -6066,6 +6114,7 @@ VFS_VOP_VECTOR_REGISTER(zfs_fifoops);
  */
 struct vop_vector zfs_shareops = {
 	.vop_default =		&default_vnodeops,
+	.vop_fplookup_vexec =	zfs_freebsd_fplookup_vexec,
 	.vop_access =		zfs_freebsd_access,
 	.vop_inactive =		zfs_freebsd_inactive,
 	.vop_reclaim =		zfs_freebsd_reclaim,

Modified: projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c
==============================================================================
--- projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_znode.c	Mon Jul 27 01:20:49 2020	(r363591)
@@ -99,7 +99,12 @@ SYSCTL_INT(_debug_sizeof, OID_AUTO, znode, CTLFLAG_RD,
  */
 krwlock_t zfsvfs_lock;
 
+#if defined(_KERNEL) && !defined(KMEM_DEBUG)
+#define _ZFS_USE_SMR
+static uma_zone_t znode_uma_zone;
+#else
 static kmem_cache_t *znode_cache = NULL;
+#endif
 
 /*ARGSUSED*/
 static void
@@ -366,6 +371,23 @@ zfs_znode_move(void *buf, void *newbuf, size_t size, v
 }
 #endif /* illumos */
 
+#ifdef _ZFS_USE_SMR
+VFS_SMR_DECLARE;
+
+static int
+zfs_znode_cache_constructor_smr(void *mem, int size __unused, void *private, int flags)
+{
+
+	return (zfs_znode_cache_constructor(mem, private, flags));
+}
+
+static void
+zfs_znode_cache_destructor_smr(void *mem, int size __unused, void *private)
+{
+
+	zfs_znode_cache_destructor(mem, private);
+}
+
 void
 zfs_znode_init(void)
 {
@@ -373,6 +395,34 @@ zfs_znode_init(void)
 	 * Initialize zcache
 	 */
 	rw_init(&zfsvfs_lock, NULL, RW_DEFAULT, NULL);
+	ASSERT(znode_uma_zone == NULL);
+	znode_uma_zone = uma_zcreate("zfs_znode_cache",
+	    sizeof (znode_t), zfs_znode_cache_constructor_smr,
+	    zfs_znode_cache_destructor_smr, NULL, NULL, 0, 0);
+	VFS_SMR_ZONE_SET(znode_uma_zone);
+}
+
+static znode_t *
+zfs_znode_alloc_kmem(int flags)
+{
+
+	return (uma_zalloc_smr(znode_uma_zone, flags));
+}
+
+static void
+zfs_znode_free_kmem(znode_t *zp)
+{
+
+	uma_zfree_smr(znode_uma_zone, zp);
+}
+#else
+void
+zfs_znode_init(void)
+{
+	/*
+	 * Initialize zcache
+	 */
+	rw_init(&zfsvfs_lock, NULL, RW_DEFAULT, NULL);
 	ASSERT(znode_cache == NULL);
 	znode_cache = kmem_cache_create("zfs_znode_cache",
 	    sizeof (znode_t), 0, zfs_znode_cache_constructor,
@@ -380,6 +430,21 @@ zfs_znode_init(void)
 	kmem_cache_set_move(znode_cache, zfs_znode_move);
 }
 
+static znode_t *
+zfs_znode_alloc_kmem(int flags)
+{
+
+	return (kmem_cache_alloc(znode_cache, flags));
+}
+
+static void
+zfs_znode_free_kmem(znode_t *zp)
+{
+
+	kmem_cache_free(znode_cache, zp);
+}
+#endif
+
 void
 zfs_znode_fini(void)
 {
@@ -393,9 +458,17 @@ zfs_znode_fini(void)
 	/*
 	 * Cleanup zcache
 	 */
-	if (znode_cache)
+#ifdef _ZFS_USE_SMR
+	if (znode_uma_zone) {
+		uma_zdestroy(znode_uma_zone);
+		znode_uma_zone = NULL;
+	}
+#else
+	if (znode_cache) {
 		kmem_cache_destroy(znode_cache);
-	znode_cache = NULL;
+		znode_cache = NULL;
+	}
+#endif
 	rw_destroy(&zfsvfs_lock);
 }
 
@@ -508,7 +581,7 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
 	vattr.va_uid = crgetuid(kcred);
 	vattr.va_gid = crgetgid(kcred);
 
-	sharezp = kmem_cache_alloc(znode_cache, KM_SLEEP);
+	sharezp = zfs_znode_alloc_kmem(KM_SLEEP);
 	ASSERT(!POINTER_IS_VALID(sharezp->z_zfsvfs));
 	sharezp->z_moved = 0;
 	sharezp->z_unlinked = 0;
@@ -527,7 +600,7 @@ zfs_create_share_dir(zfsvfs_t *zfsvfs, dmu_tx_t *tx)
 
 	zfs_acl_ids_free(&acl_ids);
 	sa_handle_destroy(sharezp->z_sa_hdl);
-	kmem_cache_free(znode_cache, sharezp);
+	zfs_znode_free_kmem(sharezp);
 
 	return (error);
 }
@@ -642,13 +715,18 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int b
 	int count = 0;
 	int error;
 
-	zp = kmem_cache_alloc(znode_cache, KM_SLEEP);
+	zp = zfs_znode_alloc_kmem(KM_SLEEP);
 
+#ifndef _ZFS_USE_SMR
+	KASSERT((zfsvfs->z_parent->z_vfs->mnt_kern_flag & MNTK_FPLOOKUP) == 0,
+	    ("%s: fast path lookup enabled without smr", __func__));
+#endif
+
 	KASSERT(curthread->td_vp_reserved != NULL,
 	    ("zfs_znode_alloc: getnewvnode without preallocated vnode"));
 	error = getnewvnode("zfs", zfsvfs->z_parent->z_vfs, &zfs_vnodeops, &vp);
 	if (error != 0) {
-		kmem_cache_free(znode_cache, zp);
+		zfs_znode_free_kmem(zp);
 		return (NULL);
 	}
 	zp->z_vnode = vp;
@@ -695,7 +773,7 @@ zfs_znode_alloc(zfsvfs_t *zfsvfs, dmu_buf_t *db, int b
 			sa_handle_destroy(zp->z_sa_hdl);
 		zfs_vnode_forget(vp);
 		zp->z_vnode = NULL;
-		kmem_cache_free(znode_cache, zp);
+		zfs_znode_free_kmem(zp);
 		return (NULL);
 	}
 
@@ -1061,6 +1139,8 @@ zfs_xvattr_set(znode_t *zp, xvattr_t *xvap, dmu_tx_t *
 	xoap = xva_getxoptattr(xvap);
 	ASSERT(xoap);
 
+	ASSERT_VOP_IN_SEQC(ZTOV(zp));
+
 	if (XVA_ISSET_REQ(xvap, XAT_CREATETIME)) {
 		uint64_t times[2];
 		ZFS_TIME_ENCODE(&xoap->xoa_createtime, times);
@@ -1490,7 +1570,7 @@ zfs_znode_free(znode_t *zp)
 		zp->z_acl_cached = NULL;
 	}
 
-	kmem_cache_free(znode_cache, zp);
+	zfs_znode_free_kmem(zp);
 
 #ifdef illumos
 	VFS_RELE(zfsvfs->z_vfs);
@@ -1950,7 +2030,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplp
 
 	zfsvfs = kmem_zalloc(sizeof (zfsvfs_t), KM_SLEEP);
 
-	rootzp = kmem_cache_alloc(znode_cache, KM_SLEEP);
+	rootzp = zfs_znode_alloc_kmem(KM_SLEEP);
 	ASSERT(!POINTER_IS_VALID(rootzp->z_zfsvfs));
 	rootzp->z_moved = 0;
 	rootzp->z_unlinked = 0;
@@ -1994,7 +2074,7 @@ zfs_create_fs(objset_t *os, cred_t *cr, nvlist_t *zplp
 	POINTER_INVALIDATE(&rootzp->z_zfsvfs);
 
 	sa_handle_destroy(rootzp->z_sa_hdl);
-	kmem_cache_free(znode_cache, rootzp);
+	zfs_znode_free_kmem(rootzp);
 
 	/*
 	 * Create shares directory

Modified: projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/hardirq.h
==============================================================================
--- projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/hardirq.h	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/hardirq.h	Mon Jul 27 01:20:49 2020	(r363591)
@@ -32,6 +32,7 @@
 #define	_LINUX_HARDIRQ_H_
 
 #include <linux/types.h>
+#include <linux/lockdep.h>
 
 #include <sys/param.h>
 #include <sys/bus.h>

Modified: projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/kernel.h
==============================================================================
--- projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/kernel.h	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/kernel.h	Mon Jul 27 01:20:49 2020	(r363591)
@@ -593,4 +593,7 @@ linux_ratelimited(linux_ratelimit_t *rl)
 			    (is_signed(datatype) ? INT8_MIN : 0) \
 )
 
+#define	TAINT_WARN	0
+#define	test_taint(x)	(0)
+
 #endif	/* _LINUX_KERNEL_H_ */

Modified: projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/lockdep.h
==============================================================================
--- projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/lockdep.h	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/lockdep.h	Mon Jul 27 01:20:49 2020	(r363591)
@@ -32,6 +32,8 @@
 #ifndef _LINUX_LOCKDEP_H_
 #define	_LINUX_LOCKDEP_H_
 
+#include <sys/lock.h>
+
 struct lock_class_key {
 };
 

Modified: projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/preempt.h
==============================================================================
--- projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/preempt.h	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/compat/linuxkpi/common/include/linux/preempt.h	Mon Jul 27 01:20:49 2020	(r363591)
@@ -29,6 +29,7 @@
 #ifndef _LINUX_PREEMPT_H_
 #define	_LINUX_PREEMPT_H_
 
+#include <linux/hardirq.h>
 #include <linux/list.h>
 
 #define	in_interrupt() \

Modified: projects/nfs-over-tls/sys/conf/files
==============================================================================
--- projects/nfs-over-tls/sys/conf/files	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/conf/files	Mon Jul 27 01:20:49 2020	(r363591)
@@ -1702,6 +1702,7 @@ dev/extres/regulator/regulator_fixed.c	optional ext_re
 dev/extres/syscon/syscon.c		optional ext_resources syscon
 dev/extres/syscon/syscon_generic.c	optional ext_resources syscon fdt
 dev/extres/syscon/syscon_if.m		optional ext_resources syscon
+dev/extres/syscon/syscon_power.c	optional ext_resources syscon syscon_power fdt
 dev/fb/fbd.c			optional fbd | vt
 dev/fb/fb_if.m			standard
 dev/fb/splash.c			optional sc splash
@@ -1736,6 +1737,7 @@ dev/fxp/if_fxp.c		optional fxp
 dev/fxp/inphy.c			optional fxp
 dev/gem/if_gem.c		optional gem
 dev/gem/if_gem_pci.c		optional gem pci
+dev/goldfish/goldfish_rtc.c	optional goldfish_rtc fdt
 dev/gpio/dwgpio/dwgpio.c	optional gpio dwgpio fdt
 dev/gpio/dwgpio/dwgpio_bus.c	optional gpio dwgpio fdt
 dev/gpio/dwgpio/dwgpio_if.m	optional gpio dwgpio fdt

Modified: projects/nfs-over-tls/sys/conf/files.arm64
==============================================================================
--- projects/nfs-over-tls/sys/conf/files.arm64	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/conf/files.arm64	Mon Jul 27 01:20:49 2020	(r363591)
@@ -408,8 +408,8 @@ arm64/freescale/imx/clk/imx_clk_sscg_pll.c	optional fd
 arm64/freescale/imx/clk/imx_clk_frac_pll.c	optional fdt soc_freescale_imx8
 
 # iMX drivers
-arm/freescale/imx/imx_gpio.c		optional gpio
+arm/freescale/imx/imx_gpio.c		optional gpio soc_freescale_imx8
 arm/freescale/imx/imx_i2c.c		optional fsliic
-arm/freescale/imx/imx_machdep.c		standard
+arm/freescale/imx/imx_machdep.c		optional fdt soc_freescale_imx8
 arm64/freescale/imx/imx7gpc.c		optional fdt soc_freescale_imx8
 dev/ffec/if_ffec.c			optional ffec

Modified: projects/nfs-over-tls/sys/conf/files.riscv
==============================================================================
--- projects/nfs-over-tls/sys/conf/files.riscv	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/conf/files.riscv	Mon Jul 27 01:20:49 2020	(r363591)
@@ -57,6 +57,7 @@ riscv/riscv/ofw_machdep.c	optional	fdt
 riscv/riscv/plic.c		standard
 riscv/riscv/pmap.c		standard
 riscv/riscv/riscv_console.c	optional	rcons
+riscv/riscv/riscv_syscon.c	optional	ext_resources syscon riscv_syscon fdt
 riscv/riscv/sbi.c		standard
 riscv/riscv/soc.c		standard
 riscv/riscv/stack_machdep.c	optional	ddb | stack

Modified: projects/nfs-over-tls/sys/conf/files.x86
==============================================================================
--- projects/nfs-over-tls/sys/conf/files.x86	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/conf/files.x86	Mon Jul 27 01:20:49 2020	(r363591)
@@ -166,6 +166,7 @@ dev/imcsmb/imcsmb_pci.c		optional	imcsmb pci
 dev/intel/spi.c			optional	intelspi
 dev/io/iodev.c			optional	io
 dev/iommu/busdma_iommu.c	optional	acpi acpi_dmar pci
+dev/iommu/iommu_gas.c		optional	acpi acpi_dmar pci
 dev/ipmi/ipmi.c			optional	ipmi
 dev/ipmi/ipmi_acpi.c		optional	ipmi acpi
 dev/ipmi/ipmi_isa.c		optional	ipmi isa
@@ -304,7 +305,6 @@ x86/cpufreq/powernow.c		optional	cpufreq
 x86/iommu/intel_ctx.c		optional	acpi acpi_dmar pci
 x86/iommu/intel_drv.c		optional	acpi acpi_dmar pci
 x86/iommu/intel_fault.c		optional	acpi acpi_dmar pci
-x86/iommu/intel_gas.c		optional	acpi acpi_dmar pci
 x86/iommu/intel_idpgtbl.c	optional	acpi acpi_dmar pci
 x86/iommu/intel_intrmap.c	optional	acpi acpi_dmar pci
 x86/iommu/intel_qi.c		optional	acpi acpi_dmar pci

Modified: projects/nfs-over-tls/sys/dev/extres/clk/clk.c
==============================================================================
--- projects/nfs-over-tls/sys/dev/extres/clk/clk.c	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/dev/extres/clk/clk.c	Mon Jul 27 01:20:49 2020	(r363591)
@@ -1407,7 +1407,7 @@ clk_set_assigned(device_t dev, phandle_t node)
 	if (ofw_bus_parse_xref_list_get_length(node,
 	    "assigned-clock-parents", "#clock-cells", &nparents) != 0)
 		nparents = -1;
-	for (i = nclocks - 1; i >= 0; i--) {
+	for (i = 0; i < nclocks; i++) {
 		/* First get the clock we are supposed to modify */
 		rv = clk_get_by_ofw_index_prop(dev, 0, "assigned-clocks",
 		    i, &clk);

Copied: projects/nfs-over-tls/sys/dev/extres/syscon/syscon_power.c (from r363587, head/sys/dev/extres/syscon/syscon_power.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nfs-over-tls/sys/dev/extres/syscon/syscon_power.c	Mon Jul 27 01:20:49 2020	(r363591, copy of r363587, head/sys/dev/extres/syscon/syscon_power.c)
@@ -0,0 +1,198 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2020 Jessica Clarke <jrtc27@FreeBSD.org>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * Driver for simple syscon poweroff and reset devices. The device tree
+ * specifications are fully described at:
+ *
+ * https://www.kernel.org/doc/Documentation/devicetree/bindings/power/reset/syscon-poweroff.txt
+ * https://www.kernel.org/doc/Documentation/devicetree/bindings/power/reset/syscon-reboot.txt
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#include <sys/param.h>
+#include <sys/bus.h>
+#include <sys/types.h>
+#include <sys/eventhandler.h>
+#include <sys/kernel.h>
+#include <sys/module.h>
+#include <sys/reboot.h>
+
+#include <machine/bus.h>
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+#include <dev/ofw/openfirm.h>
+
+#include "syscon_if.h"
+#include "syscon.h"
+
+struct syscon_power_softc {
+	struct syscon		*regmap;
+	uint32_t		offset;
+	uint32_t		value;
+	uint32_t		mask;
+	bool			reboot;
+	eventhandler_tag	shutdown_tag;
+};
+
+static void
+syscon_power_shutdown_final(device_t dev, int howto)
+{
+	struct syscon_power_softc *sc;
+	bool write;
+
+	sc = device_get_softc(dev);
+	if (sc->reboot)
+		write = (howto & RB_HALT) == 0;
+	else
+		write = (howto & RB_POWEROFF) != 0;
+
+	if (write)
+		SYSCON_MODIFY_4(sc->regmap, sc->offset, sc->mask,
+		    sc->value & sc->mask);
+}
+
+static int
+syscon_power_probe(device_t dev)
+{
+
+	if (!ofw_bus_status_okay(dev))
+		return (ENXIO);
+
+	if (ofw_bus_is_compatible(dev, "syscon-poweroff")) {
+		device_set_desc(dev, "Syscon poweroff");
+		return (BUS_PROBE_DEFAULT);
+	} else if (ofw_bus_is_compatible(dev, "syscon-reboot")) {
+		device_set_desc(dev, "Syscon reboot");
+		return (BUS_PROBE_DEFAULT);
+	}
+
+	return (ENXIO);
+}
+
+static int
+syscon_power_attach(device_t dev)
+{
+	struct syscon_power_softc *sc;
+	phandle_t node;
+	int error, len;
+	bool has_mask;
+
+	sc = device_get_softc(dev);
+	node = ofw_bus_get_node(dev);
+
+	if (!OF_hasprop(node, "regmap")) {
+		device_printf(dev, "could not find regmap\n");
+		return (ENXIO);
+	}
+
+	error = syscon_get_by_ofw_property(dev, node, "regmap", &sc->regmap);
+	if (error != 0) {
+		device_printf(dev, "could not get syscon\n");
+		return (ENXIO);
+	}
+
+	len = OF_getproplen(node, "offset");
+	if (len != 4) {
+		device_printf(dev, "could not get offset\n");
+		return (ENXIO);
+	}
+
+	OF_getencprop(node, "offset", &sc->offset, sizeof(sc->offset));
+
+	/* Optional mask */
+	has_mask = OF_hasprop(node, "mask");
+	if (has_mask) {
+		len = OF_getproplen(node, "mask");
+		if (len != 4) {
+			device_printf(dev, "cannot handle mask\n");
+			return (ENXIO);
+		}
+
+		OF_getencprop(node, "mask", &sc->mask, sizeof(sc->mask));
+	} else {
+		sc->mask = 0xffffffff;
+	}
+
+	/*
+	 * From the device tree specification:
+	 *
+	 *   Legacy usage: If a node doesn't contain a value property but
+	 *   contains a mask property, the mask property is used as the value.
+	 */
+	if (!OF_hasprop(node, "value")) {
+		if (!has_mask) {
+			device_printf(dev, "must have a value or a mask\n");
+			return (ENXIO);
+		}
+
+		sc->value = sc->mask;
+	} else {
+		len = OF_getproplen(node, "value");
+		if (len != 4) {
+			device_printf(dev, "cannot handle value\n");
+			return (ENXIO);
+		}
+
+		OF_getencprop(node, "value", &sc->value, sizeof(sc->value));
+	}
+
+	sc->reboot = ofw_bus_is_compatible(dev, "syscon-reboot");
+	sc->shutdown_tag = EVENTHANDLER_REGISTER(shutdown_final,
+	    syscon_power_shutdown_final, dev, SHUTDOWN_PRI_LAST);
+
+	return (0);
+}
+
+static int
+syscon_power_detach(device_t dev)
+{
+	struct syscon_power_softc *sc;
+
+	sc = device_get_softc(dev);
+	EVENTHANDLER_DEREGISTER(shutdown_final, sc->shutdown_tag);
+
+	return (0);
+}
+
+static device_method_t syscon_power_methods[] = {
+	DEVMETHOD(device_probe,		syscon_power_probe),
+	DEVMETHOD(device_attach,	syscon_power_attach),
+	DEVMETHOD(device_detach,	syscon_power_detach),
+
+	DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(syscon_power, syscon_power_driver, syscon_power_methods,
+    sizeof(struct syscon_power_softc));
+static devclass_t syscon_power_devclass;
+
+DRIVER_MODULE(syscon_power, simplebus, syscon_power_driver,
+    syscon_power_devclass, NULL, NULL);

Modified: projects/nfs-over-tls/sys/dev/iommu/busdma_iommu.c
==============================================================================
--- projects/nfs-over-tls/sys/dev/iommu/busdma_iommu.c	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/dev/iommu/busdma_iommu.c	Mon Jul 27 01:20:49 2020	(r363591)
@@ -1017,7 +1017,7 @@ bus_dma_dmar_load_ident(bus_dma_tag_t dmat, bus_dmamap
 	map = (struct bus_dmamap_iommu *)map1;
 	waitok = (flags & BUS_DMA_NOWAIT) != 0;
 
-	entry = iommu_map_alloc_entry(domain, waitok ? 0 : DMAR_PGF_WAITOK);
+	entry = iommu_map_alloc_entry(domain, waitok ? 0 : IOMMU_PGF_WAITOK);
 	if (entry == NULL)
 		return (ENOMEM);
 	entry->start = start;

Modified: projects/nfs-over-tls/sys/dev/iommu/iommu.h
==============================================================================
--- projects/nfs-over-tls/sys/dev/iommu/iommu.h	Mon Jul 27 01:17:59 2020	(r363590)
+++ projects/nfs-over-tls/sys/dev/iommu/iommu.h	Mon Jul 27 01:20:49 2020	(r363591)
@@ -35,6 +35,7 @@
 #define _SYS_IOMMU_H_
 
 #include <sys/queue.h>
+#include <sys/sysctl.h>
 #include <sys/taskqueue.h>
 #include <sys/tree.h>
 #include <sys/types.h>
@@ -48,6 +49,10 @@ struct bus_dma_tag_common;
 struct iommu_map_entry;
 TAILQ_HEAD(iommu_map_entries_tailq, iommu_map_entry);
 
+RB_HEAD(iommu_gas_entries_tree, iommu_map_entry);
+RB_PROTOTYPE(iommu_gas_entries_tree, iommu_map_entry, rb_entry,
+    iommu_gas_cmp_entries);
+
 struct iommu_qi_genseq {
 	u_int gen;
 	uint32_t seq;
@@ -107,6 +112,11 @@ struct iommu_domain {
 	u_int entries_cnt;		/* (d) */
 	struct iommu_map_entries_tailq unload_entries; /* (d) Entries to
 							 unload */
+	struct iommu_gas_entries_tree rb_root; /* (d) */
+	iommu_gaddr_t end;		/* (c) Highest address + 1 in
+					   the guest AS */
+	struct iommu_map_entry *first_place, *last_place; /* (d) */
+	u_int flags;			/* (u) */
 };
 
 struct iommu_ctx {
@@ -124,6 +134,24 @@ struct iommu_ctx {
 					   ephemeral reference is kept
 					   to prevent context destruction */
 
+#define	IOMMU_DOMAIN_GAS_INITED		0x0001
+#define	IOMMU_DOMAIN_PGTBL_INITED	0x0002
+#define	IOMMU_DOMAIN_IDMAP		0x0010	/* Domain uses identity
+						   page table */
+#define	IOMMU_DOMAIN_RMRR		0x0020	/* Domain contains RMRR entry,
+						   cannot be turned off */
+
+/* Map flags */
+#define	IOMMU_MF_CANWAIT	0x0001
+#define	IOMMU_MF_CANSPLIT	0x0002
+#define	IOMMU_MF_RMRR		0x0004
+
+#define	IOMMU_PGF_WAITOK	0x0001
+#define	IOMMU_PGF_ZERO		0x0002
+#define	IOMMU_PGF_ALLOC		0x0004
+#define	IOMMU_PGF_NOALLOC	0x0008
+#define	IOMMU_PGF_OBJL		0x0010
+
 #define	IOMMU_LOCK(unit)		mtx_lock(&(unit)->lock)
 #define	IOMMU_UNLOCK(unit)		mtx_unlock(&(unit)->lock)
 #define	IOMMU_ASSERT_LOCKED(unit)	mtx_assert(&(unit)->lock, MA_OWNED)
@@ -164,5 +192,25 @@ int iommu_map(struct iommu_domain *iodom,
     u_int eflags, u_int flags, vm_page_t *ma, struct iommu_map_entry **res);
 int iommu_map_region(struct iommu_domain *domain,
     struct iommu_map_entry *entry, u_int eflags, u_int flags, vm_page_t *ma);
+
+void iommu_gas_init_domain(struct iommu_domain *domain);
+void iommu_gas_fini_domain(struct iommu_domain *domain);
+struct iommu_map_entry *iommu_gas_alloc_entry(struct iommu_domain *domain,
+    u_int flags);
+void iommu_gas_free_entry(struct iommu_domain *domain,
+    struct iommu_map_entry *entry);
+void iommu_gas_free_space(struct iommu_domain *domain,
+    struct iommu_map_entry *entry);
+int iommu_gas_map(struct iommu_domain *domain,
+    const struct bus_dma_tag_common *common, iommu_gaddr_t size, int offset,
+    u_int eflags, u_int flags, vm_page_t *ma, struct iommu_map_entry **res);
+void iommu_gas_free_region(struct iommu_domain *domain,
+    struct iommu_map_entry *entry);
+int iommu_gas_map_region(struct iommu_domain *domain,
+    struct iommu_map_entry *entry, u_int eflags, u_int flags, vm_page_t *ma);
+int iommu_gas_reserve_region(struct iommu_domain *domain, iommu_gaddr_t start,
+    iommu_gaddr_t end);
+
+SYSCTL_DECL(_hw_iommu);
 
 #endif /* !_SYS_IOMMU_H_ */

Copied: projects/nfs-over-tls/sys/dev/iommu/iommu_gas.c (from r363587, head/sys/dev/iommu/iommu_gas.c)
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nfs-over-tls/sys/dev/iommu/iommu_gas.c	Mon Jul 27 01:20:49 2020	(r363591, copy of r363587, head/sys/dev/iommu/iommu_gas.c)
@@ -0,0 +1,741 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2013 The FreeBSD Foundation
+ * All rights reserved.
+ *
+ * This software was developed by Konstantin Belousov <kib@FreeBSD.org>
+ * under sponsorship from the FreeBSD Foundation.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD$");
+
+#define	RB_AUGMENT(entry) iommu_gas_augment_entry(entry)
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/bus.h>
+#include <sys/interrupt.h>
+#include <sys/kernel.h>
+#include <sys/ktr.h>
+#include <sys/lock.h>
+#include <sys/proc.h>
+#include <sys/rwlock.h>
+#include <sys/memdesc.h>
+#include <sys/mutex.h>
+#include <sys/sysctl.h>
+#include <sys/rman.h>
+#include <sys/taskqueue.h>
+#include <sys/tree.h>
+#include <sys/uio.h>
+#include <sys/vmem.h>
+#include <dev/pci/pcivar.h>
+#include <vm/vm.h>
+#include <vm/vm_extern.h>
+#include <vm/vm_kern.h>
+#include <vm/vm_object.h>
+#include <vm/vm_page.h>
+#include <vm/vm_map.h>
+#include <vm/uma.h>
+#include <machine/atomic.h>
+#include <machine/bus.h>
+#include <machine/md_var.h>
+#if defined(__amd64__) || defined(__i386__)
+#include <machine/specialreg.h>
+#include <x86/include/busdma_impl.h>
+#include <x86/iommu/intel_reg.h>
+#include <dev/iommu/busdma_iommu.h>
+#include <dev/iommu/iommu.h>
+#include <dev/pci/pcireg.h>
+#include <x86/iommu/intel_dmar.h>
+#endif
+
+/*
+ * Guest Address Space management.
+ */
+
+static uma_zone_t iommu_map_entry_zone;
+
+#ifdef INVARIANTS
+static int iommu_check_free;
+#endif
+
+static void
+intel_gas_init(void)
+{
+
+	iommu_map_entry_zone = uma_zcreate("IOMMU_MAP_ENTRY",
+	    sizeof(struct iommu_map_entry), NULL, NULL,
+	    NULL, NULL, UMA_ALIGN_PTR, UMA_ZONE_NODUMP);
+}
+SYSINIT(intel_gas, SI_SUB_DRIVERS, SI_ORDER_FIRST, intel_gas_init, NULL);
+
+struct iommu_map_entry *
+iommu_gas_alloc_entry(struct iommu_domain *domain, u_int flags)
+{
+	struct iommu_map_entry *res;
+
+	KASSERT((flags & ~(IOMMU_PGF_WAITOK)) == 0,
+	    ("unsupported flags %x", flags));
+
+	res = uma_zalloc(iommu_map_entry_zone, ((flags & IOMMU_PGF_WAITOK) !=
+	    0 ? M_WAITOK : M_NOWAIT) | M_ZERO);
+	if (res != NULL) {
+		res->domain = domain;
+		atomic_add_int(&domain->entries_cnt, 1);
+	}
+	return (res);
+}
+
+void
+iommu_gas_free_entry(struct iommu_domain *domain, struct iommu_map_entry *entry)
+{
+
+	KASSERT(domain == (struct iommu_domain *)entry->domain,
+	    ("mismatched free domain %p entry %p entry->domain %p", domain,
+	    entry, entry->domain));
+	atomic_subtract_int(&domain->entries_cnt, 1);
+	uma_zfree(iommu_map_entry_zone, entry);
+}
+
+static int
+iommu_gas_cmp_entries(struct iommu_map_entry *a, struct iommu_map_entry *b)
+{
+
+	/* Last entry have zero size, so <= */
+	KASSERT(a->start <= a->end, ("inverted entry %p (%jx, %jx)",
+	    a, (uintmax_t)a->start, (uintmax_t)a->end));
+	KASSERT(b->start <= b->end, ("inverted entry %p (%jx, %jx)",
+	    b, (uintmax_t)b->start, (uintmax_t)b->end));
+	KASSERT(a->end <= b->start || b->end <= a->start ||
+	    a->end == a->start || b->end == b->start,
+	    ("overlapping entries %p (%jx, %jx) %p (%jx, %jx)",
+	    a, (uintmax_t)a->start, (uintmax_t)a->end,
+	    b, (uintmax_t)b->start, (uintmax_t)b->end));
+
+	if (a->end < b->end)
+		return (-1);
+	else if (b->end < a->end)
+		return (1);
+	return (0);
+}
+
+static void
+iommu_gas_augment_entry(struct iommu_map_entry *entry)
+{
+	struct iommu_map_entry *child;
+	iommu_gaddr_t free_down;
+
+	free_down = 0;
+	if ((child = RB_LEFT(entry, rb_entry)) != NULL) {
+		free_down = MAX(free_down, child->free_down);
+		free_down = MAX(free_down, entry->start - child->last);
+		entry->first = child->first;
+	} else
+		entry->first = entry->start;
+	
+	if ((child = RB_RIGHT(entry, rb_entry)) != NULL) {
+		free_down = MAX(free_down, child->free_down);
+		free_down = MAX(free_down, child->first - entry->end);
+		entry->last = child->last;
+	} else
+		entry->last = entry->end;
+	entry->free_down = free_down;
+}
+

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202007270120.06R1KnsV089441>