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 ...
Rick Macklem
rmacklem at FreeBSD.org
Mon Jul 27 01:20:54 UTC 2020
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 at 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 at 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 ***
More information about the svn-src-projects
mailing list