diff options
author | Dan McDonald <danmcd@joyent.com> | 2020-09-22 10:39:49 -0400 |
---|---|---|
committer | Dan McDonald <danmcd@joyent.com> | 2020-09-22 10:39:49 -0400 |
commit | 267e12a7d9bf6e5fcefb9cc00f46bfff0dc5226e (patch) | |
tree | 19a3941920d0039c35d53a5cbee189b5ca51995a /usr/src/uts/common | |
parent | 517abc5c668925e6092495bf332233c3599980d2 (diff) | |
parent | e9faba760cdf80d7dfa110fe0830917ab94668c2 (diff) | |
download | illumos-joyent-vpc.tar.gz |
Merge branch 'master' into vpcvpc
Diffstat (limited to 'usr/src/uts/common')
53 files changed, 1116 insertions, 329 deletions
diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index 08fb3d45ac..e973cf58ad 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -1694,7 +1694,7 @@ TEM_OBJS += tem.o tem_safe.o # Font data for generated console fonts # i386_FONT = 8x16 -i386_FONT_SRC= ter-u16n +i386_FONT_SRC= ter-u16b sparc_FONT = 12x22 sparc_FONT_SRC= Gallant19 FONT=$($(MACH)_FONT) @@ -2342,4 +2342,4 @@ BNX_OBJS += \ # mlxcx(7D) # MLXCX_OBJS += mlxcx.o mlxcx_dma.o mlxcx_cmd.o mlxcx_intr.o mlxcx_gld.o \ - mlxcx_ring.o + mlxcx_ring.o mlxcx_sensor.o diff --git a/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c b/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c index c44c32ef29..575acd59a2 100644 --- a/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c +++ b/usr/src/uts/common/brand/lx/procfs/lx_prvnops.c @@ -22,6 +22,7 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * Copyright 2019 Joyent, Inc. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* @@ -470,7 +471,7 @@ typedef struct lxpr_rlimtab { char *rlim_rctl; /* rctl source */ } lxpr_rlimtab_t; -#define RLIM_MAXFD "Max open files" +#define RLIM_MAXFD "Max open files" static lxpr_rlimtab_t lxpr_rlimtab[] = { { "Max cpu time", "seconds", "process.max-cpu-time" }, @@ -1737,8 +1738,9 @@ lxpr_read_pid_limits(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) * match the max value so that we do not output "unlimited". */ if (strcmp(lxpr_rlimtab[i].rlim_name, RLIM_MAXFD) == 0 && - cur[i] == RLIM_INFINITY) - cur[i] = max[i]; + cur[i] == RLIM_INFINITY) { + cur[i] = max[i]; + } } lxpr_unlock(p); @@ -4001,10 +4003,10 @@ lxpr_read_meminfo(lxpr_node_t *lxpnp, lxpr_uiobuf_t *uiobuf) * model, so just inform the caller that no swap is being used. * * MemAvailable - * MemAvailable entry is available since Linux Kernel +3.14, is an - * estimate of how much memory is available for starting new applications, - * without swapping. In lxbrand we will always return the available free - * memory as an estimate of this value. + * MemAvailable entry is available since Linux Kernel +3.14, is an + * estimate of how much memory is available for starting new + * applications, without swapping. In lxbrand we will always return the + * available free memory as an estimate of this value. */ lxpr_uiobuf_printf(uiobuf, "MemTotal: %8lu kB\n" @@ -8094,6 +8096,58 @@ lxpr_write_pid_loginuid(lxpr_node_t *lxpnp, struct uio *uio, struct cred *cr, return (0); } +static int +lxpr_readlink_exe(lxpr_node_t *lxpnp, char *buf, size_t size, cred_t *cr) +{ + size_t dlen = DIRENT64_RECLEN(MAXPATHLEN); + dirent64_t *dp; + vnode_t *dirvp; + int error = ENOENT; + char *dbuf; + proc_t *p; + size_t len; + + p = lxpr_lock(lxpnp, NO_ZOMB); + + if (p == NULL) + return (error); + + dirvp = p->p_execdir; + if (dirvp == NULL) { + lxpr_unlock(p); + return (error); + } + + VN_HOLD(dirvp); + lxpr_unlock(p); + + /* Look up the parent directory path */ + if ((error = vnodetopath(NULL, dirvp, buf, size, cr)) != 0) { + VN_RELE(dirvp); + return (error); + } + + len = strlen(buf); + + dbuf = kmem_alloc(dlen, KM_SLEEP); + + /* + * Walk the parent directory to find the vnode for p->p_exec, in order + * to derive its path. + */ + if ((error = dirfindvp(NULL, dirvp, lxpnp->lxpr_realvp, + cr, dbuf, dlen, &dp)) == 0 && + strlen(dp->d_name) + len + 1 < size) { + buf[len] = '/'; + (void) strcpy(buf + len + 1, dp->d_name); + } else { + error = ENOENT; + } + VN_RELE(dirvp); + kmem_free(dbuf, dlen); + return (error); +} + /* * lxpr_readlink(): Vnode operation for VOP_READLINK() */ @@ -8135,7 +8189,16 @@ lxpr_readlink(vnode_t *vp, uio_t *uiop, cred_t *cr, caller_context_t *ct) if (error != 0) return (error); - if ((error = vnodetopath(NULL, rvp, bp, buflen, cr)) != 0) { + error = vnodetopath(NULL, rvp, bp, buflen, cr); + + /* + * Special handling for /proc/<pid>/exe where the vnode path is + * not cached. + */ + if (error != 0 && lxpnp->lxpr_type == LXPR_PID_EXE) + error = lxpr_readlink_exe(lxpnp, bp, buflen, cr); + + if (error != 0) { /* * Special handling possible for /proc/<pid>/fd/<num> * Generate <type>:[<inode>] links, if allowed. diff --git a/usr/src/uts/common/conf/param.c b/usr/src/uts/common/conf/param.c index 1120748b98..06920c3574 100644 --- a/usr/src/uts/common/conf/param.c +++ b/usr/src/uts/common/conf/param.c @@ -116,7 +116,7 @@ const unsigned int _diskrpm = (unsigned int)DISKRPM; const unsigned long _pgthresh = (unsigned long)PGTHRESH; const unsigned int _maxslp = (unsigned int)MAXSLP; const unsigned long _maxhandspreadpages = (unsigned long)MAXHANDSPREADPAGES; -const int _ncpu = (int)NCPU; +const int _ncpu = (int)NCPU; const int _ncpu_log2 = (int)NCPU_LOG2; const int _ncpu_p2 = (int)NCPU_P2; const unsigned long _defaultstksz = (unsigned long)DEFAULTSTKSZ; @@ -131,9 +131,12 @@ const unsigned int _nbpg = (unsigned int)MMU_PAGESIZE; */ /* - * Default hz is 100, but if we set hires_tick we get higher resolution - * clock behavior (currently defined to be 1000 hz). Higher values seem - * to work, but are not supported. + * hz is 100, but we set hires_tick to get higher resolution clock behavior + * (currently defined to be 1000 hz). Higher values seem to work, but are not + * supported. + * + * This is configured via hires_tick to allow users to explicitly customize it + * to 0 should the need arise. * * If we do decide to play with higher values, remember that hz should * satisfy the following constraints to avoid integer round-off problems: @@ -160,7 +163,7 @@ const unsigned int _nbpg = (unsigned int)MMU_PAGESIZE; int hz = HZ_DEFAULT; int hires_hz = HIRES_HZ_DEFAULT; -int hires_tick = 0; +int hires_tick = 1; int cpu_decay_factor = 10; /* this is no longer tied to clock */ int max_hres_adj; /* maximum adjustment of hrtime per tick */ int tick_per_msec; /* clock ticks per millisecond (zero if hz < 1000) */ diff --git a/usr/src/uts/common/fs/smbsrv/smb2_fsctl_copychunk.c b/usr/src/uts/common/fs/smbsrv/smb2_fsctl_copychunk.c index 4240328207..4a657bbf19 100644 --- a/usr/src/uts/common/fs/smbsrv/smb2_fsctl_copychunk.c +++ b/usr/src/uts/common/fs/smbsrv/smb2_fsctl_copychunk.c @@ -447,6 +447,8 @@ smb2_fsctl_copychunk_meta(smb_request_t *sr, smb_ofile_t *src_of) * here don't generally have WRITE_DAC access (sigh) so we * have to bypass ofile access checks for this operation. * The file-system level still does its access checking. + * + * TODO: this should really copy the SACL, too. */ smb_fssd_init(&fs_sd, secinfo, sd_flags); sr->fid_ofile = NULL; diff --git a/usr/src/uts/common/fs/smbsrv/smb_fsops.c b/usr/src/uts/common/fs/smbsrv/smb_fsops.c index 8fafac5f60..43b513e840 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_fsops.c +++ b/usr/src/uts/common/fs/smbsrv/smb_fsops.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2018 Nexenta Systems, Inc. All rights reserved. + * Copyright 2020 Nexenta by DDN, Inc. All rights reserved. */ #include <sys/sid.h> @@ -147,10 +147,9 @@ smb_fsop_create_with_sd(smb_request_t *sr, cred_t *cr, is_dir = ((fs_sd->sd_flags & SMB_FSSD_FLAGS_DIR) != 0); if (smb_tree_has_feature(sr->tid_tree, SMB_TREE_ACLONCREATE)) { - if (fs_sd->sd_secinfo & SMB_ACL_SECINFO) { - dacl = fs_sd->sd_zdacl; - sacl = fs_sd->sd_zsacl; - ASSERT(dacl || sacl); + dacl = fs_sd->sd_zdacl; + sacl = fs_sd->sd_zsacl; + if (dacl != NULL || sacl != NULL) { if (dacl && sacl) { acl = smb_fsacl_merge(dacl, sacl); } else if (dacl) { @@ -466,15 +465,20 @@ smb_fsop_create_file(smb_request_t *sr, cred_t *cr, if (op->sd) { /* * SD sent by client in Windows format. Needs to be - * converted to FS format. No inheritance. + * converted to FS format. Inherit DACL/SACL if they're not + * specified. */ secinfo = smb_sd_get_secinfo(op->sd); + smb_fssd_init(&fs_sd, secinfo, 0); status = smb_sd_tofs(op->sd, &fs_sd); if (status == NT_STATUS_SUCCESS) { - rc = smb_fsop_create_with_sd(sr, cr, dnode, - name, attr, ret_snode, &fs_sd); + rc = smb_fsop_sdinherit(sr, dnode, &fs_sd); + if (rc == 0) + rc = smb_fsop_create_with_sd(sr, cr, dnode, + name, attr, ret_snode, &fs_sd); + } else { rc = EINVAL; } @@ -485,7 +489,7 @@ smb_fsop_create_file(smb_request_t *sr, cred_t *cr, * Server applies Windows inheritance rules, * see smb_fsop_sdinherit() comments as to why. */ - smb_fssd_init(&fs_sd, SMB_ACL_SECINFO, 0); + smb_fssd_init(&fs_sd, 0, 0); rc = smb_fsop_sdinherit(sr, dnode, &fs_sd); if (rc == 0) { rc = smb_fsop_create_with_sd(sr, cr, dnode, @@ -607,15 +611,19 @@ smb_fsop_mkdir( if (op->sd) { /* * SD sent by client in Windows format. Needs to be - * converted to FS format. No inheritance. + * converted to FS format. Inherit DACL/SACL if they're not + * specified. */ secinfo = smb_sd_get_secinfo(op->sd); + smb_fssd_init(&fs_sd, secinfo, SMB_FSSD_FLAGS_DIR); status = smb_sd_tofs(op->sd, &fs_sd); if (status == NT_STATUS_SUCCESS) { - rc = smb_fsop_create_with_sd(sr, cr, dnode, - name, attr, ret_snode, &fs_sd); + rc = smb_fsop_sdinherit(sr, dnode, &fs_sd); + if (rc == 0) + rc = smb_fsop_create_with_sd(sr, cr, dnode, + name, attr, ret_snode, &fs_sd); } else rc = EINVAL; @@ -626,7 +634,7 @@ smb_fsop_mkdir( * Server applies Windows inheritance rules, * see smb_fsop_sdinherit() comments as to why. */ - smb_fssd_init(&fs_sd, SMB_ACL_SECINFO, SMB_FSSD_FLAGS_DIR); + smb_fssd_init(&fs_sd, 0, SMB_FSSD_FLAGS_DIR); rc = smb_fsop_sdinherit(sr, dnode, &fs_sd); if (rc == 0) { rc = smb_fsop_create_with_sd(sr, cr, dnode, @@ -2391,6 +2399,8 @@ smb_fsop_sdmerge(smb_request_t *sr, smb_node_t *snode, smb_fssd_t *fs_sd) * owner has been specified. Callers should translate this to * STATUS_INVALID_OWNER which is not the normal mapping for EPERM * in upper layers, so EPERM is mapped to EBADE. + * + * If 'overwrite' is non-zero, then the existing ACL is ignored. */ int smb_fsop_sdwrite(smb_request_t *sr, cred_t *cr, smb_node_t *snode, @@ -2456,14 +2466,13 @@ smb_fsop_sdwrite(smb_request_t *sr, cred_t *cr, smb_node_t *snode, } if (fs_sd->sd_secinfo & SMB_ACL_SECINFO) { - if (overwrite == 0) { + if (overwrite == 0) error = smb_fsop_sdmerge(sr, snode, fs_sd); - if (error) - return (error); - } - error = smb_fsop_aclwrite(sr, cr, snode, fs_sd); - if (error) { + if (error == 0) + error = smb_fsop_aclwrite(sr, cr, snode, fs_sd); + + if (error != 0) { /* * Revert uid/gid changes if required. */ @@ -2511,39 +2520,46 @@ smb_fsop_sdinherit(smb_request_t *sr, smb_node_t *dnode, smb_fssd_t *fs_sd) acl_t *sacl = NULL; int is_dir; int error; + uint32_t secinfo; + smb_fssd_t pfs_sd; ASSERT(fs_sd); - if (sr->tid_tree->t_acltype != ACE_T) { - /* - * No forced inheritance for non-ZFS filesystems. - */ - fs_sd->sd_secinfo = 0; + secinfo = fs_sd->sd_secinfo; + + /* Anything to do? */ + if ((secinfo & SMB_ACL_SECINFO) == SMB_ACL_SECINFO) + return (0); + + /* + * No forced inheritance for non-ZFS filesystems. + */ + if (sr->tid_tree->t_acltype != ACE_T) return (0); - } + smb_fssd_init(&pfs_sd, SMB_ACL_SECINFO, fs_sd->sd_flags); /* Fetch parent directory's ACL */ - error = smb_fsop_sdread(sr, zone_kcred(), dnode, fs_sd); + error = smb_fsop_sdread(sr, zone_kcred(), dnode, &pfs_sd); if (error) { return (error); } is_dir = (fs_sd->sd_flags & SMB_FSSD_FLAGS_DIR); - dacl = smb_fsacl_inherit(fs_sd->sd_zdacl, is_dir, SMB_DACL_SECINFO, - sr->user_cr); - sacl = smb_fsacl_inherit(fs_sd->sd_zsacl, is_dir, SMB_SACL_SECINFO, - sr->user_cr); - - if (sacl == NULL) - fs_sd->sd_secinfo &= ~SMB_SACL_SECINFO; - - smb_fsacl_free(fs_sd->sd_zdacl); - smb_fsacl_free(fs_sd->sd_zsacl); + if ((secinfo & SMB_DACL_SECINFO) == 0) { + dacl = smb_fsacl_inherit(pfs_sd.sd_zdacl, is_dir, + SMB_DACL_SECINFO, sr->user_cr); + fs_sd->sd_zdacl = dacl; + } - fs_sd->sd_zdacl = dacl; - fs_sd->sd_zsacl = sacl; + if ((secinfo & SMB_SACL_SECINFO) == 0) { + sacl = smb_fsacl_inherit(pfs_sd.sd_zsacl, is_dir, + SMB_SACL_SECINFO, sr->user_cr); + fs_sd->sd_zsacl = sacl; + } + smb_fsacl_free(pfs_sd.sd_zdacl); + smb_fsacl_free(pfs_sd.sd_zsacl); return (0); } #endif /* _KERNEL */ diff --git a/usr/src/uts/common/fs/smbsrv/smb_idmap.c b/usr/src/uts/common/fs/smbsrv/smb_idmap.c index b9bfa991c4..e6c04193b0 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_idmap.c +++ b/usr/src/uts/common/fs/smbsrv/smb_idmap.c @@ -20,7 +20,7 @@ */ /* * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2018 Nexenta Systems, Inc. All rights reserved. + * Copyright 2020 Nexenta by DDN, Inc. All rights reserved. */ /* @@ -83,12 +83,12 @@ smb_idmap_getsid(uid_t id, int idtype, smb_sid_t **sid) switch (idtype) { case SMB_IDMAP_USER: - sim.sim_stat = kidmap_getsidbyuid(global_zone, id, + sim.sim_stat = kidmap_getsidbyuid(curzone, id, (const char **)&sim.sim_domsid, &sim.sim_rid); break; case SMB_IDMAP_GROUP: - sim.sim_stat = kidmap_getsidbygid(global_zone, id, + sim.sim_stat = kidmap_getsidbygid(curzone, id, (const char **)&sim.sim_domsid, &sim.sim_rid); break; @@ -150,17 +150,17 @@ smb_idmap_getid(smb_sid_t *sid, uid_t *id, int *idtype) switch (*idtype) { case SMB_IDMAP_USER: - sim.sim_stat = kidmap_getuidbysid(global_zone, sim.sim_domsid, + sim.sim_stat = kidmap_getuidbysid(curzone, sim.sim_domsid, sim.sim_rid, sim.sim_id); break; case SMB_IDMAP_GROUP: - sim.sim_stat = kidmap_getgidbysid(global_zone, sim.sim_domsid, + sim.sim_stat = kidmap_getgidbysid(curzone, sim.sim_domsid, sim.sim_rid, sim.sim_id); break; case SMB_IDMAP_UNKNOWN: - sim.sim_stat = kidmap_getpidbysid(global_zone, sim.sim_domsid, + sim.sim_stat = kidmap_getpidbysid(curzone, sim.sim_domsid, sim.sim_rid, sim.sim_id, &sim.sim_idtype); break; @@ -186,7 +186,7 @@ smb_idmap_batch_create(smb_idmap_batch_t *sib, uint16_t nmap, int flags) bzero(sib, sizeof (smb_idmap_batch_t)); - sib->sib_idmaph = kidmap_get_create(global_zone); + sib->sib_idmaph = kidmap_get_create(curzone); sib->sib_flags = flags; sib->sib_nmap = nmap; diff --git a/usr/src/uts/common/fs/smbsrv/smb_sd.c b/usr/src/uts/common/fs/smbsrv/smb_sd.c index ddbd7b9413..f7e056c511 100644 --- a/usr/src/uts/common/fs/smbsrv/smb_sd.c +++ b/usr/src/uts/common/fs/smbsrv/smb_sd.c @@ -22,7 +22,7 @@ * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * - * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * Copyright 2020 Nexenta by DDN, Inc. All rights reserved. */ /* @@ -243,16 +243,29 @@ smb_sd_tofs(smb_sd_t *sd, smb_fssd_t *fs_sd) } } + /* + * In SMB, the 'secinfo' determines which parts of the SD the client + * intends to change. Notably, this includes changing the DACL_PRESENT + * and SACL_PRESENT control bits. The client can specify e.g. + * SACL_SECINFO, but not SACL_PRESENT, and this means the client intends + * to remove the SACL. + * + * If the *_PRESENT bit isn't set, then the respective ACL will be NULL. + * [MS-DTYP] disallows providing an ACL when the PRESENT bit isn't set. + * This is enforced by smb_decode_sd(). + * + * We allow the SACL to be NULL, but we MUST have a DACL. + * If the DACL is NULL, that's equivalent to "everyone:full_set:allow". + */ + /* DACL */ if (fs_sd->sd_secinfo & SMB_DACL_SECINFO) { - if (sd->sd_control & SE_DACL_PRESENT) { - status = smb_acl_to_zfs(sd->sd_dacl, flags, - SMB_DACL_SECINFO, &fs_sd->sd_zdacl); - if (status != NT_STATUS_SUCCESS) - return (status); - } - else - return (NT_STATUS_INVALID_ACL); + ASSERT3U(((sd->sd_control & SE_DACL_PRESENT) != 0), ==, + (sd->sd_dacl != NULL)); + status = smb_acl_to_zfs(sd->sd_dacl, flags, + SMB_DACL_SECINFO, &fs_sd->sd_zdacl); + if (status != NT_STATUS_SUCCESS) + return (status); } /* SACL */ @@ -263,8 +276,6 @@ smb_sd_tofs(smb_sd_t *sd, smb_fssd_t *fs_sd) if (status != NT_STATUS_SUCCESS) { return (status); } - } else { - return (NT_STATUS_INVALID_ACL); } } diff --git a/usr/src/uts/common/fs/zfs/arc.c b/usr/src/uts/common/fs/zfs/arc.c index 9e04e5e00d..939282b378 100644 --- a/usr/src/uts/common/fs/zfs/arc.c +++ b/usr/src/uts/common/fs/zfs/arc.c @@ -2538,7 +2538,7 @@ arc_untransform(arc_buf_t *buf, spa_t *spa, const zbookmark_phys_t *zb, */ ret = SET_ERROR(EIO); spa_log_error(spa, zb); - zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION, + (void) zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION, spa, NULL, zb, NULL, 0, 0); } @@ -5801,7 +5801,8 @@ arc_read_done(zio_t *zio) error = SET_ERROR(EIO); if ((zio->io_flags & ZIO_FLAG_SPECULATIVE) == 0) { spa_log_error(zio->io_spa, &acb->acb_zb); - zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION, + (void) zfs_ereport_post( + FM_EREPORT_ZFS_AUTHENTICATION, zio->io_spa, NULL, &acb->acb_zb, zio, 0, 0); } } @@ -6058,7 +6059,7 @@ top: rc = SET_ERROR(EIO); if ((zio_flags & ZIO_FLAG_SPECULATIVE) == 0) { spa_log_error(spa, zb); - zfs_ereport_post( + (void) zfs_ereport_post( FM_EREPORT_ZFS_AUTHENTICATION, spa, NULL, zb, NULL, 0, 0); } diff --git a/usr/src/uts/common/fs/zfs/dnode.c b/usr/src/uts/common/fs/zfs/dnode.c index f5ef390896..345189f695 100644 --- a/usr/src/uts/common/fs/zfs/dnode.c +++ b/usr/src/uts/common/fs/zfs/dnode.c @@ -1197,7 +1197,7 @@ dnode_special_open(objset_t *os, dnode_phys_t *dnp, uint64_t object, dnode_t *dn; zrl_init(&dnh->dnh_zrlock); - zrl_tryenter(&dnh->dnh_zrlock); + VERIFY3U(1, ==, zrl_tryenter(&dnh->dnh_zrlock)); dn = dnode_create(os, dnp, NULL, object, dnh); DNODE_VERIFY(dn); diff --git a/usr/src/uts/common/fs/zfs/dnode_sync.c b/usr/src/uts/common/fs/zfs/dnode_sync.c index dc7317b411..4a060403da 100644 --- a/usr/src/uts/common/fs/zfs/dnode_sync.c +++ b/usr/src/uts/common/fs/zfs/dnode_sync.c @@ -23,6 +23,7 @@ * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2012, 2018 by Delphix. All rights reserved. * Copyright (c) 2014 Spectra Logic Corporation, All rights reserved. + * Copyright 2020 Oxide Computer Company */ #include <sys/zfs_context.h> @@ -736,13 +737,22 @@ dnode_sync(dnode_t *dn, dmu_tx_t *tx) dsfra.dsfra_dnode = dn; dsfra.dsfra_tx = tx; dsfra.dsfra_free_indirects = freeing_dnode; + mutex_enter(&dn->dn_mtx); if (freeing_dnode) { ASSERT(range_tree_contains(dn->dn_free_ranges[txgoff], 0, dn->dn_maxblkid + 1)); } - mutex_enter(&dn->dn_mtx); - range_tree_vacate(dn->dn_free_ranges[txgoff], + /* + * Because dnode_sync_free_range() must drop dn_mtx during its + * processing, using it as a callback to range_tree_vacate() is + * not safe. No other operations (besides destroy) are allowed + * once range_tree_vacate() has begun, and dropping dn_mtx + * would leave a window open for another thread to observe that + * invalid (and unsafe) state. + */ + range_tree_walk(dn->dn_free_ranges[txgoff], dnode_sync_free_range, &dsfra); + range_tree_vacate(dn->dn_free_ranges[txgoff], NULL, NULL); range_tree_destroy(dn->dn_free_ranges[txgoff]); dn->dn_free_ranges[txgoff] = NULL; mutex_exit(&dn->dn_mtx); diff --git a/usr/src/uts/common/fs/zfs/lua/ldebug.c b/usr/src/uts/common/fs/zfs/lua/ldebug.c index b8ddcff3c6..4ed0094bde 100644 --- a/usr/src/uts/common/fs/zfs/lua/ldebug.c +++ b/usr/src/uts/common/fs/zfs/lua/ldebug.c @@ -467,7 +467,7 @@ static const char *getfuncname (lua_State *L, CallInfo *ci, const char **name) { return getobjname(p, pc, GETARG_A(i), name); case OP_TFORCALL: { /* for iterator */ *name = "for iterator"; - return "for iterator"; + return "for iterator"; } /* all other instructions can call only through metamethods */ case OP_SELF: diff --git a/usr/src/uts/common/fs/zfs/metaslab.c b/usr/src/uts/common/fs/zfs/metaslab.c index 42ba1f9a46..fe53d142c2 100644 --- a/usr/src/uts/common/fs/zfs/metaslab.c +++ b/usr/src/uts/common/fs/zfs/metaslab.c @@ -2414,7 +2414,7 @@ metaslab_load_impl(metaslab_t *msp) msp->ms_max_size = metaslab_largest_allocatable(msp); ASSERT3U(max_size, <=, msp->ms_max_size); hrtime_t load_end = gethrtime(); - msp->ms_load_time = load_end; + msp->ms_load_time = load_end; if (zfs_flags & ZFS_DEBUG_LOG_SPACEMAP) { zfs_dbgmsg("loading: txg %llu, spa %s, vdev_id %llu, " "ms_id %llu, smp_length %llu, " diff --git a/usr/src/uts/common/fs/zfs/spa.c b/usr/src/uts/common/fs/zfs/spa.c index fc08eebbc0..a040fbfea5 100644 --- a/usr/src/uts/common/fs/zfs/spa.c +++ b/usr/src/uts/common/fs/zfs/spa.c @@ -2408,7 +2408,8 @@ spa_load(spa_t *spa, spa_load_state_t state, spa_import_type_t type) spa->spa_loaded_ts.tv_nsec = 0; } if (error != EBADF) { - zfs_ereport_post(ereport, spa, NULL, NULL, NULL, 0, 0); + (void) zfs_ereport_post(ereport, spa, + NULL, NULL, NULL, 0, 0); } } spa->spa_load_state = error ? SPA_LOAD_ERROR : SPA_LOAD_NONE; diff --git a/usr/src/uts/common/fs/zfs/spa_config.c b/usr/src/uts/common/fs/zfs/spa_config.c index 4719696ca4..ae814208fd 100644 --- a/usr/src/uts/common/fs/zfs/spa_config.c +++ b/usr/src/uts/common/fs/zfs/spa_config.c @@ -280,7 +280,8 @@ spa_write_cachefile(spa_t *target, boolean_t removing, boolean_t postsysevent) * resource issues are resolved. */ if (target->spa_ccw_fail_time == 0) { - zfs_ereport_post(FM_EREPORT_ZFS_CONFIG_CACHE_WRITE, + (void) zfs_ereport_post( + FM_EREPORT_ZFS_CONFIG_CACHE_WRITE, target, NULL, NULL, NULL, 0, 0); } target->spa_ccw_fail_time = gethrtime(); diff --git a/usr/src/uts/common/fs/zfs/vdev.c b/usr/src/uts/common/fs/zfs/vdev.c index e82b309537..254af68099 100644 --- a/usr/src/uts/common/fs/zfs/vdev.c +++ b/usr/src/uts/common/fs/zfs/vdev.c @@ -1365,7 +1365,7 @@ vdev_probe_done(zio_t *zio) } else { ASSERT(zio->io_error != 0); vdev_dbgmsg(vd, "failed probe"); - zfs_ereport_post(FM_EREPORT_ZFS_PROBE_FAILURE, + (void) zfs_ereport_post(FM_EREPORT_ZFS_PROBE_FAILURE, spa, vd, NULL, NULL, 0, 0); zio->io_error = SET_ERROR(ENXIO); } @@ -1717,7 +1717,8 @@ vdev_open(vdev_t *vd) */ if (ashift > vd->vdev_top->vdev_ashift && vd->vdev_ops->vdev_op_leaf) { - zfs_ereport_post(FM_EREPORT_ZFS_DEVICE_BAD_ASHIFT, + (void) zfs_ereport_post( + FM_EREPORT_ZFS_DEVICE_BAD_ASHIFT, spa, vd, NULL, NULL, 0, 0); } @@ -4408,7 +4409,7 @@ vdev_set_state(vdev_t *vd, boolean_t isopen, vdev_state_t state, vdev_aux_t aux) class = FM_EREPORT_ZFS_DEVICE_UNKNOWN; } - zfs_ereport_post(class, spa, vd, NULL, NULL, + (void) zfs_ereport_post(class, spa, vd, NULL, NULL, save_state, 0); } diff --git a/usr/src/uts/common/fs/zfs/vdev_indirect.c b/usr/src/uts/common/fs/zfs/vdev_indirect.c index effea61bc6..6c636dd4d2 100644 --- a/usr/src/uts/common/fs/zfs/vdev_indirect.c +++ b/usr/src/uts/common/fs/zfs/vdev_indirect.c @@ -1382,8 +1382,8 @@ vdev_indirect_checksum_error(zio_t *zio, void *bad_buf = abd_borrow_buf_copy(ic->ic_data, is->is_size); abd_t *good_abd = is->is_good_child->ic_data; void *good_buf = abd_borrow_buf_copy(good_abd, is->is_size); - zfs_ereport_post_checksum(zio->io_spa, vd, &zio->io_bookmark, zio, - is->is_target_offset, is->is_size, good_buf, bad_buf, &zbc); + (void) zfs_ereport_post_checksum(zio->io_spa, vd, &zio->io_bookmark, + zio, is->is_target_offset, is->is_size, good_buf, bad_buf, &zbc); abd_return_buf(ic->ic_data, bad_buf, is->is_size); abd_return_buf(good_abd, good_buf, is->is_size); } @@ -1459,7 +1459,7 @@ vdev_indirect_all_checksum_errors(zio_t *zio) vd->vdev_stat.vs_checksum_errors++; mutex_exit(&vd->vdev_stat_lock); - zfs_ereport_post_checksum(zio->io_spa, vd, + (void) zfs_ereport_post_checksum(zio->io_spa, vd, &zio->io_bookmark, zio, is->is_target_offset, is->is_size, NULL, NULL, NULL); } diff --git a/usr/src/uts/common/fs/zfs/vdev_raidz.c b/usr/src/uts/common/fs/zfs/vdev_raidz.c index e4db03ce89..381c2ff84f 100644 --- a/usr/src/uts/common/fs/zfs/vdev_raidz.c +++ b/usr/src/uts/common/fs/zfs/vdev_raidz.c @@ -1968,7 +1968,7 @@ raidz_checksum_error(zio_t *zio, raidz_col_t *rc, abd_t *bad_data) zbc.zbc_has_cksum = 0; zbc.zbc_injected = rm->rm_ecksuminjected; - zfs_ereport_post_checksum(zio->io_spa, vd, + (void) zfs_ereport_post_checksum(zio->io_spa, vd, &zio->io_bookmark, zio, rc->rc_offset, rc->rc_size, rc->rc_abd, bad_data, &zbc); } diff --git a/usr/src/uts/common/fs/zfs/zfs_fm.c b/usr/src/uts/common/fs/zfs/zfs_fm.c index dd854c12e1..2118fd549e 100644 --- a/usr/src/uts/common/fs/zfs/zfs_fm.c +++ b/usr/src/uts/common/fs/zfs/zfs_fm.c @@ -735,7 +735,7 @@ zfs_ereport_start_checksum(spa_t *spa, vdev_t *vd, const zbookmark_phys_t *zb, report->zcr_length = length; #ifdef _KERNEL - zfs_ereport_start(&report->zcr_ereport, &report->zcr_detector, + (void) zfs_ereport_start(&report->zcr_ereport, &report->zcr_detector, FM_EREPORT_ZFS_CHECKSUM, spa, vd, zb, zio, offset, length); if (report->zcr_ereport == NULL) { diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index 99011b83b4..c016b5c1ea 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -4839,7 +4839,7 @@ zfs_seek(vnode_t *vp, offset_t ooff, offset_t *noffp, { if (vp->v_type == VDIR) return (0); - return ((*noffp < 0 || *noffp > MAXOFFSET_T) ? EINVAL : 0); + return ((*noffp < 0) ? EINVAL : 0); } /* diff --git a/usr/src/uts/common/fs/zfs/zio.c b/usr/src/uts/common/fs/zfs/zio.c index 5215a58bf2..9981263343 100644 --- a/usr/src/uts/common/fs/zfs/zio.c +++ b/usr/src/uts/common/fs/zfs/zio.c @@ -483,7 +483,7 @@ error: zio->io_error = SET_ERROR(EIO); if ((zio->io_flags & ZIO_FLAG_SPECULATIVE) == 0) { spa_log_error(spa, &zio->io_bookmark); - zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION, + (void) zfs_ereport_post(FM_EREPORT_ZFS_AUTHENTICATION, spa, NULL, &zio->io_bookmark, zio, 0, 0); } } else { @@ -1995,7 +1995,7 @@ zio_suspend(spa_t *spa, zio_t *zio, zio_suspend_reason_t reason) "failure and has been suspended; `zpool clear` will be required " "before the pool can be written to.", spa_name(spa)); - zfs_ereport_post(FM_EREPORT_ZFS_IO_FAILURE, spa, NULL, + (void) zfs_ereport_post(FM_EREPORT_ZFS_IO_FAILURE, spa, NULL, NULL, NULL, 0, 0); mutex_enter(&spa->spa_suspend_lock); @@ -4265,7 +4265,7 @@ zio_done(zio_t *zio) zio->io_vd->vdev_stat.vs_slow_ios++; mutex_exit(&zio->io_vd->vdev_stat_lock); - zfs_ereport_post(FM_EREPORT_ZFS_DELAY, + (void) zfs_ereport_post(FM_EREPORT_ZFS_DELAY, zio->io_spa, zio->io_vd, &zio->io_bookmark, zio, 0, 0); } @@ -4280,7 +4280,7 @@ zio_done(zio_t *zio) * device is currently unavailable. */ if (zio->io_error != ECKSUM && vd != NULL && !vdev_is_dead(vd)) - zfs_ereport_post(FM_EREPORT_ZFS_IO, spa, vd, + (void) zfs_ereport_post(FM_EREPORT_ZFS_IO, spa, vd, &zio->io_bookmark, zio, 0, 0); if ((zio->io_error == EIO || !(zio->io_flags & @@ -4291,7 +4291,7 @@ zio_done(zio_t *zio) * error and generate a logical data ereport. */ spa_log_error(spa, &zio->io_bookmark); - zfs_ereport_post(FM_EREPORT_ZFS_DATA, spa, NULL, + (void) zfs_ereport_post(FM_EREPORT_ZFS_DATA, spa, NULL, &zio->io_bookmark, zio, 0, 0); } } diff --git a/usr/src/uts/common/fs/zfs/zvol.c b/usr/src/uts/common/fs/zfs/zvol.c index 2e684a5ff0..2495fb015d 100644 --- a/usr/src/uts/common/fs/zfs/zvol.c +++ b/usr/src/uts/common/fs/zfs/zvol.c @@ -1161,10 +1161,10 @@ zvol_dumpio(zvol_state_t *zv, void *addr, uint64_t offset, uint64_t size, ASSERT(size <= zv->zv_volblocksize); /* Locate the extent this belongs to */ - ze = list_head(&zv->zv_extents); - while (offset >= ze->ze_nblks * zv->zv_volblocksize) { + for (ze = list_head(&zv->zv_extents); + ze != NULL && offset >= ze->ze_nblks * zv->zv_volblocksize; + ze = list_next(&zv->zv_extents, ze)) { offset -= ze->ze_nblks * zv->zv_volblocksize; - ze = list_next(&zv->zv_extents, ze); } if (ze == NULL) @@ -1232,7 +1232,7 @@ zvol_strategy(buf_t *bp) addr = bp->b_un.b_addr; resid = bp->b_bcount; - if (resid > 0 && (off < 0 || off >= volsize)) { + if (resid > 0 && off >= volsize) { bioerror(bp, EIO); biodone(bp); return (0); diff --git a/usr/src/uts/common/inet/ip/ipclassifier.c b/usr/src/uts/common/inet/ip/ipclassifier.c index 4f3ec2d817..69af77db9a 100644 --- a/usr/src/uts/common/inet/ip/ipclassifier.c +++ b/usr/src/uts/common/inet/ip/ipclassifier.c @@ -22,6 +22,7 @@ * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2016 Joyent, Inc. * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 Joyent, Inc. */ /* @@ -2772,7 +2773,11 @@ conn_get_socket_info(conn_t *connp, mib2_socketInfoEntry_t *sie) return (NULL); } - mutex_exit(&connp->conn_lock); + /* + * Continue to hold conn_lock because we don't want to race with an + * in-progress close, which will have set-to-NULL (and destroyed + * upper_handle, aka sonode (and vnode)) BEFORE setting CONN_CLOSING. + */ if (connp->conn_upper_handle != NULL) { vn = (*connp->conn_upcalls->su_get_vnode) @@ -2784,6 +2789,8 @@ conn_get_socket_info(conn_t *connp, mib2_socketInfoEntry_t *sie) flags |= MIB2_SOCKINFO_STREAM; } + mutex_exit(&connp->conn_lock); + if (vn == NULL || VOP_GETATTR(vn, &attr, 0, CRED(), NULL) != 0) { if (vn != NULL) VN_RELE(vn); diff --git a/usr/src/uts/common/inet/ip/ipsecesp.c b/usr/src/uts/common/inet/ip/ipsecesp.c index e0efbbf3ce..4b4e88dcf6 100644 --- a/usr/src/uts/common/inet/ip/ipsecesp.c +++ b/usr/src/uts/common/inet/ip/ipsecesp.c @@ -1843,6 +1843,7 @@ esp_submit_req_inbound(mblk_t *esp_mp, ip_recv_attr_t *ira, ipsec_stack_t *ipss = ns->netstack_ipsec; ipsecesp_stack_t *espstack = ns->netstack_ipsecesp; + mp = NULL; do_auth = assoc->ipsa_auth_alg != SADB_AALG_NONE; do_encr = assoc->ipsa_encr_alg != SADB_EALG_NULL; force = (assoc->ipsa_flags & IPSA_F_ASYNC); @@ -2172,6 +2173,7 @@ esp_submit_req_outbound(mblk_t *data_mp, ip_xmit_attr_t *ixa, ipsa_t *assoc, esp3dbg(espstack, ("esp_submit_req_outbound:%s", is_natt ? "natt" : "not natt")); + mp = NULL; do_encr = assoc->ipsa_encr_alg != SADB_EALG_NULL; do_auth = assoc->ipsa_auth_alg != SADB_AALG_NONE; force = (assoc->ipsa_flags & IPSA_F_ASYNC); @@ -2441,6 +2443,7 @@ esp_outbound(mblk_t *data_mp, ip_xmit_attr_t *ixa) * Reality check.... */ ipha = (ipha_t *)data_mp->b_rptr; /* So we can call esp_acquire(). */ + ip6h = (ip6_t *)ipha; if (ixa->ixa_flags & IXAF_IS_IPV4) { ASSERT(IPH_HDR_VERSION(ipha) == IPV4_VERSION); @@ -2455,7 +2458,6 @@ esp_outbound(mblk_t *data_mp, ip_xmit_attr_t *ixa) ASSERT(IPH_HDR_VERSION(ipha) == IPV6_VERSION); af = AF_INET6; - ip6h = (ip6_t *)ipha; bzero(&ipp, sizeof (ipp)); divpoint = ip_find_hdr_v6(data_mp, ip6h, B_FALSE, &ipp, NULL); if (ipp.ipp_dstopts != NULL && diff --git a/usr/src/uts/common/inet/ip/sadb.c b/usr/src/uts/common/inet/ip/sadb.c index 288c0e3e18..5f1d1c96ee 100644 --- a/usr/src/uts/common/inet/ip/sadb.c +++ b/usr/src/uts/common/inet/ip/sadb.c @@ -1067,6 +1067,15 @@ sadb_sa2msg(ipsa_t *ipsa, sadb_msg_t *samsg) int srcidsize, dstidsize, senslen, osenslen; sa_family_t fam, pfam; /* Address family for SADB_EXT_ADDRESS */ /* src/dst and proxy sockaddrs. */ + + authsize = 0; + encrsize = 0; + pfam = 0; + srcidsize = 0; + dstidsize = 0; + paddrsize = 0; + senslen = 0; + osenslen = 0; /* * The following are pointers into the PF_KEY message this PF_KEY * message creates. @@ -1100,6 +1109,7 @@ sadb_sa2msg(ipsa_t *ipsa, sadb_msg_t *samsg) */ alloclen = sizeof (sadb_msg_t) + sizeof (sadb_sa_t) + sizeof (sadb_lifetime_t); + otherspi = 0; fam = ipsa->ipsa_addrfam; switch (fam) { @@ -1770,6 +1780,8 @@ sadb_addrcheck(queue_t *pfkey_q, mblk_t *mp, sadb_ext_t *ext, uint_t serial, (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_LOC) || (ext->sadb_ext_type == SADB_X_EXT_ADDRESS_NATT_REM)); + diagnostic = 0; + /* Assign both sockaddrs, the compiler will do the right thing. */ sin = (struct sockaddr_in *)(addr + 1); sin6 = (struct sockaddr_in6 *)(addr + 1); diff --git a/usr/src/uts/common/inet/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c index 554fe8b78f..88d558fd10 100644 --- a/usr/src/uts/common/inet/tcp/tcp.c +++ b/usr/src/uts/common/inet/tcp/tcp.c @@ -21,10 +21,10 @@ /* * Copyright (c) 1991, 2010, Oracle and/or its affiliates. All rights reserved. - * Copyright 2019 Joyent, Inc. * Copyright (c) 2011 Nexenta Systems, Inc. All rights reserved. * Copyright (c) 2013, 2017 by Delphix. All rights reserved. * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. + * Copyright 2020 Joyent, Inc. */ /* Copyright (c) 1990 Mentat Inc. */ @@ -1018,10 +1018,23 @@ finish: /* If we have an upper handle (socket), release it */ if (IPCL_IS_NONSTR(connp)) { - ASSERT(connp->conn_upper_handle != NULL); - (*connp->conn_upcalls->su_closed)(connp->conn_upper_handle); + sock_upcalls_t *upcalls = connp->conn_upcalls; + sock_upper_handle_t handle = connp->conn_upper_handle; + + ASSERT(upcalls != NULL); + ASSERT(upcalls->su_closed != NULL); + ASSERT(handle != NULL); + /* + * Set these to NULL first because closed() will free upper + * structures. Acquire conn_lock because an external caller + * like conn_get_socket_info() will upcall if these are + * non-NULL. + */ + mutex_enter(&connp->conn_lock); connp->conn_upper_handle = NULL; connp->conn_upcalls = NULL; + mutex_exit(&connp->conn_lock); + upcalls->su_closed(handle); } } @@ -1435,13 +1448,26 @@ tcp_free(tcp_t *tcp) * nothing to do other than clearing the field. */ if (connp->conn_upper_handle != NULL) { + sock_upcalls_t *upcalls = connp->conn_upcalls; + sock_upper_handle_t handle = connp->conn_upper_handle; + + /* + * Set these to NULL first because closed() will free upper + * structures. Acquire conn_lock because an external caller + * like conn_get_socket_info() will upcall if these are + * non-NULL. + */ + mutex_enter(&connp->conn_lock); + connp->conn_upper_handle = NULL; + connp->conn_upcalls = NULL; + mutex_exit(&connp->conn_lock); if (IPCL_IS_NONSTR(connp)) { - (*connp->conn_upcalls->su_closed)( - connp->conn_upper_handle); + ASSERT(upcalls != NULL); + ASSERT(upcalls->su_closed != NULL); + ASSERT(handle != NULL); + upcalls->su_closed(handle); tcp->tcp_detached = B_TRUE; } - connp->conn_upper_handle = NULL; - connp->conn_upcalls = NULL; } } diff --git a/usr/src/uts/common/inet/tcp/tcp_output.c b/usr/src/uts/common/inet/tcp/tcp_output.c index 7a0472f3dd..086668f435 100644 --- a/usr/src/uts/common/inet/tcp/tcp_output.c +++ b/usr/src/uts/common/inet/tcp/tcp_output.c @@ -22,7 +22,7 @@ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2014, 2017 by Delphix. All rights reserved. - * Copyright 2019 Joyent, Inc. + * Copyright 2020 Joyent, Inc. */ /* This file contains all TCP output processing functions. */ @@ -1677,11 +1677,23 @@ finish: /* non-STREAM socket, release the upper handle */ if (IPCL_IS_NONSTR(connp)) { - ASSERT(connp->conn_upper_handle != NULL); - (*connp->conn_upcalls->su_closed) - (connp->conn_upper_handle); + sock_upcalls_t *upcalls = connp->conn_upcalls; + sock_upper_handle_t handle = connp->conn_upper_handle; + + ASSERT(upcalls != NULL); + ASSERT(upcalls->su_closed != NULL); + ASSERT(handle != NULL); + /* + * Set these to NULL first because closed() will free + * upper structures. Acquire conn_lock because an + * external caller like conn_get_socket_info() will + * upcall if these are non-NULL. + */ + mutex_enter(&connp->conn_lock); connp->conn_upper_handle = NULL; connp->conn_upcalls = NULL; + mutex_exit(&connp->conn_lock); + upcalls->su_closed(handle); } } diff --git a/usr/src/uts/common/io/cxgbe/t4nex/adapter.h b/usr/src/uts/common/io/cxgbe/t4nex/adapter.h index 48edc44341..1192eeb43e 100644 --- a/usr/src/uts/common/io/cxgbe/t4nex/adapter.h +++ b/usr/src/uts/common/io/cxgbe/t4nex/adapter.h @@ -559,6 +559,10 @@ struct adapter { kmutex_t sfl_lock; /* same cache-line as sc_lock? but that's ok */ TAILQ_HEAD(, sge_fl) sfl; timeout_id_t sfl_timer; + + /* Sensors */ + id_t temp_sensor; + id_t volt_sensor; }; enum { diff --git a/usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c b/usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c index ec590228b6..05732e47a1 100644 --- a/usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c +++ b/usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c @@ -37,6 +37,7 @@ #include <sys/mkdev.h> #include <sys/queue.h> #include <sys/containerof.h> +#include <sys/sensors.h> #include "version.h" #include "common/common.h" @@ -180,6 +181,18 @@ static kmutex_t t4_uld_list_lock; static SLIST_HEAD(, uld_info) t4_uld_list; #endif +static int t4_temperature_read(void *, sensor_ioctl_scalar_t *); +static int t4_voltage_read(void *, sensor_ioctl_scalar_t *); +static const ksensor_ops_t t4_temp_ops = { + .kso_kind = ksensor_kind_temperature, + .kso_scalar = t4_temperature_read +}; + +static const ksensor_ops_t t4_volt_ops = { + .kso_kind = ksensor_kind_voltage, + .kso_scalar = t4_voltage_read +}; + int _init(void) { @@ -758,7 +771,23 @@ ofld_queues: } sc->flags |= INTR_ALLOCATED; - ASSERT(rc == DDI_SUCCESS); + if ((rc = ksensor_create_scalar_pcidev(dip, SENSOR_KIND_TEMPERATURE, + &t4_temp_ops, sc, "temp", &sc->temp_sensor)) != 0) { + cxgb_printf(dip, CE_WARN, "failed to create temperature " + "sensor: %d", rc); + rc = DDI_FAILURE; + goto done; + } + + if ((rc = ksensor_create_scalar_pcidev(dip, SENSOR_KIND_VOLTAGE, + &t4_volt_ops, sc, "vdd", &sc->volt_sensor)) != 0) { + cxgb_printf(dip, CE_WARN, "failed to create voltage " + "sensor: %d", rc); + rc = DDI_FAILURE; + goto done; + } + + ddi_report_dev(dip); /* @@ -849,6 +878,7 @@ t4_devo_detach(dev_info_t *dip, ddi_detach_cmd_t cmd) } /* Safe to call no matter what */ + (void) ksensor_remove(dip, KSENSOR_ALL_IDS); ddi_prop_remove_all(dip); ddi_remove_minor_node(dip, NULL); @@ -2919,3 +2949,76 @@ t4_iterate(void (*func)(int, void *), void *arg) } #endif + +static int +t4_sensor_read(struct adapter *sc, uint32_t diag, uint32_t *valp) +{ + int rc; + struct port_info *pi = sc->port[0]; + uint32_t param, val; + + rc = begin_synchronized_op(pi, 1, 1); + if (rc != 0) { + return (rc); + } + param = V_FW_PARAMS_MNEM(FW_PARAMS_MNEM_DEV) | + V_FW_PARAMS_PARAM_X(FW_PARAMS_PARAM_DEV_DIAG) | + V_FW_PARAMS_PARAM_Y(diag); + rc = -t4_query_params(sc, sc->mbox, sc->pf, 0, 1, ¶m, &val); + end_synchronized_op(pi, 1); + + if (rc != 0) { + return (rc); + } + + if (val == 0) { + return (EIO); + } + + *valp = val; + return (0); +} + +static int +t4_temperature_read(void *arg, sensor_ioctl_scalar_t *scalar) +{ + int ret; + struct adapter *sc = arg; + uint32_t val; + + ret = t4_sensor_read(sc, FW_PARAM_DEV_DIAG_TMP, &val); + if (ret != 0) { + return (ret); + } + + /* + * The device measures temperature in units of 1 degree Celsius. We + * don't know its precision. + */ + scalar->sis_unit = SENSOR_UNIT_CELSIUS; + scalar->sis_gran = 1; + scalar->sis_prec = 0; + scalar->sis_value = val; + + return (0); +} + +static int +t4_voltage_read(void *arg, sensor_ioctl_scalar_t *scalar) +{ + int ret; + struct adapter *sc = arg; + uint32_t val; + + ret = t4_sensor_read(sc, FW_PARAM_DEV_DIAG_VDD, &val); + if (ret != 0) { + return (ret); + } + + scalar->sis_unit = SENSOR_UNIT_VOLTS; + scalar->sis_gran = 1000; + scalar->sis_prec = 0; + scalar->sis_value = val; + + return (0); +} diff --git a/usr/src/uts/common/io/igb/igb_sensor.c b/usr/src/uts/common/io/igb/igb_sensor.c index b233af2a92..3b41a853c0 100644 --- a/usr/src/uts/common/io/igb/igb_sensor.c +++ b/usr/src/uts/common/io/igb/igb_sensor.c @@ -72,7 +72,7 @@ #define EMC1413_REG_EXT3_DIODE_LO 0x2b static int -igb_sensor_reg_temp(void *arg, sensor_ioctl_temperature_t *temp) +igb_sensor_reg_temperature(void *arg, sensor_ioctl_scalar_t *scalar) { igb_t *igb = arg; uint32_t reg; @@ -87,17 +87,17 @@ igb_sensor_reg_temp(void *arg, sensor_ioctl_temperature_t *temp) return (EIO); } - temp->sit_unit = SENSOR_UNIT_CELSIUS; - temp->sit_gran = E1000_THMJT_RESOLUTION; - temp->sit_prec = E1000_THMJT_PRECISION; - temp->sit_temp = E1000_THMJT_TEMP(reg); + scalar->sis_unit = SENSOR_UNIT_CELSIUS; + scalar->sis_gran = E1000_THMJT_RESOLUTION; + scalar->sis_prec = E1000_THMJT_PRECISION; + scalar->sis_value = E1000_THMJT_TEMP(reg); return (0); } static const ksensor_ops_t igb_sensor_reg_ops = { .kso_kind = ksensor_kind_temperature, - .kso_temp = igb_sensor_reg_temp + .kso_scalar = igb_sensor_reg_temperature }; static boolean_t @@ -106,8 +106,9 @@ igb_sensors_create_minors(igb_t *igb) int ret; igb_sensors_t *sp = &igb->igb_sensors; - if ((ret = ksensor_create_temp_pcidev(igb->dip, &igb_sensor_reg_ops, - igb, "builtin", &sp->isn_reg_ksensor)) != 0) { + if ((ret = ksensor_create_scalar_pcidev(igb->dip, + SENSOR_KIND_TEMPERATURE, &igb_sensor_reg_ops, igb, "builtin", + &sp->isn_reg_ksensor)) != 0) { igb_log(igb, IGB_LOG_ERROR, "failed to create main sensor: %d", ret); return (B_FALSE); diff --git a/usr/src/uts/common/io/ksensor/ksensor_drv.c b/usr/src/uts/common/io/ksensor/ksensor_drv.c index 6810e11758..70e99287a2 100644 --- a/usr/src/uts/common/io/ksensor/ksensor_drv.c +++ b/usr/src/uts/common/io/ksensor/ksensor_drv.c @@ -90,15 +90,15 @@ ksensor_ioctl_kind(minor_t min, intptr_t arg, int mode) } static int -ksensor_ioctl_temp(minor_t min, intptr_t arg, int mode) +ksensor_ioctl_scalar(minor_t min, intptr_t arg, int mode) { int ret; - sensor_ioctl_temperature_t temp; + sensor_ioctl_scalar_t scalar; - bzero(&temp, sizeof (temp)); - ret = ksensor_op_temperature((id_t)min, &temp); + bzero(&scalar, sizeof (scalar)); + ret = ksensor_op_scalar((id_t)min, &scalar); if (ret == 0) { - if (ddi_copyout(&temp, (void *)arg, sizeof (temp), + if (ddi_copyout(&scalar, (void *)arg, sizeof (scalar), mode & FKIOCTL) != 0) { ret = EFAULT; } @@ -118,10 +118,10 @@ ksensor_ioctl(dev_t dev, int cmd, intptr_t arg, int mode, cred_t *credp, m = getminor(dev); switch (cmd) { - case SENSOR_IOCTL_TYPE: + case SENSOR_IOCTL_KIND: return (ksensor_ioctl_kind(m, arg, mode)); - case SENSOR_IOCTL_TEMPERATURE: - return (ksensor_ioctl_temp(m, arg, mode)); + case SENSOR_IOCTL_SCALAR: + return (ksensor_ioctl_scalar(m, arg, mode)); default: return (ENOTTY); } diff --git a/usr/src/uts/common/io/ksensor/ksensor_test.c b/usr/src/uts/common/io/ksensor/ksensor_test.c index ea71ab5559..a98a8b77eb 100644 --- a/usr/src/uts/common/io/ksensor/ksensor_test.c +++ b/usr/src/uts/common/io/ksensor/ksensor_test.c @@ -32,21 +32,53 @@ typedef struct ksensor_test { id_t kt_sensor3; id_t kt_sensor4; id_t kt_sensor5; + id_t kt_volt; + id_t kt_current; } ksensor_test_t; static int -ksensor_test_temperature(void *arg, sensor_ioctl_temperature_t *temp) +ksensor_test_temp(void *arg, sensor_ioctl_scalar_t *scalar) { - temp->sit_unit = SENSOR_UNIT_CELSIUS; - temp->sit_gran = 4; - temp->sit_prec = -2; - temp->sit_temp = 23; + scalar->sis_unit = SENSOR_UNIT_CELSIUS; + scalar->sis_gran = 4; + scalar->sis_prec = -2; + scalar->sis_value = 23; return (0); } static const ksensor_ops_t ksensor_test_temp_ops = { - ksensor_kind_temperature, - ksensor_test_temperature + .kso_kind = ksensor_kind_temperature, + .kso_scalar = ksensor_test_temp +}; + +static int +ksensor_test_volt(void *arg, sensor_ioctl_scalar_t *scalar) +{ + scalar->sis_unit = SENSOR_UNIT_VOLTS; + scalar->sis_gran = 1000; + scalar->sis_prec = 0; + scalar->sis_value = 3300; + return (0); +} + +static const ksensor_ops_t ksensor_test_volt_ops = { + .kso_kind = ksensor_kind_voltage, + .kso_scalar = ksensor_test_volt +}; + +static int +ksensor_test_current(void *arg, sensor_ioctl_scalar_t *scalar) +{ + scalar->sis_unit = SENSOR_UNIT_AMPS; + scalar->sis_gran = 10; + scalar->sis_prec = 0; + scalar->sis_value = 5; + return (0); +} + +static const ksensor_ops_t ksensor_test_current_ops = { + .kso_kind = ksensor_kind_current, + .kso_scalar = ksensor_test_current }; static int @@ -56,14 +88,14 @@ ksensor_test_kind_eio(void *arg, sensor_ioctl_kind_t *kindp) } static int -ksensor_test_temp_eio(void *arg, sensor_ioctl_temperature_t *tempp) +ksensor_test_temp_eio(void *arg, sensor_ioctl_scalar_t *scalar) { return (EIO); } static const ksensor_ops_t ksensor_test_eio_ops = { - ksensor_test_kind_eio, - ksensor_test_temp_eio + .kso_kind = ksensor_test_kind_eio, + .kso_scalar = ksensor_test_temp_eio }; static int @@ -107,7 +139,7 @@ ksensor_test_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) ddi_get_instance(dip)); if ((ret = ksensor_create(dip, &ksensor_test_temp_ops, NULL, buf, "ddi_sensor:test", &kt->kt_sensor3)) != 0) { - dev_err(dip, CE_WARN, "failed to attatch sensor %s: %d", buf, + dev_err(dip, CE_WARN, "failed to attach sensor %s: %d", buf, ret); goto err; } @@ -116,7 +148,7 @@ ksensor_test_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) ddi_get_instance(dip)); if ((ret = ksensor_create(dip, &ksensor_test_temp_ops, NULL, buf, "ddi_sensor:test", &kt->kt_sensor4)) != 0) { - dev_err(dip, CE_WARN, "failed to attatch sensor %s: %d", buf, + dev_err(dip, CE_WARN, "failed to attach sensor %s: %d", buf, ret); goto err; } @@ -125,7 +157,25 @@ ksensor_test_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) ddi_get_instance(dip)); if ((ret = ksensor_create(dip, &ksensor_test_eio_ops, NULL, buf, "ddi_sensor:test", &kt->kt_sensor5)) != 0) { - dev_err(dip, CE_WARN, "failed to attatch sensor %s: %d", buf, + dev_err(dip, CE_WARN, "failed to attach sensor %s: %d", buf, + ret); + goto err; + } + + (void) snprintf(buf, sizeof (buf), "test.volt.%d.1", + ddi_get_instance(dip)); + if ((ret = ksensor_create(dip, &ksensor_test_volt_ops, NULL, buf, + "ddi_sensor:test", &kt->kt_volt)) != 0) { + dev_err(dip, CE_WARN, "failed to attach sensor %s: %d", buf, + ret); + goto err; + } + + (void) snprintf(buf, sizeof (buf), "test.current.%d.1", + ddi_get_instance(dip)); + if ((ret = ksensor_create(dip, &ksensor_test_current_ops, NULL, buf, + "ddi_sensor:test", &kt->kt_current)) != 0) { + dev_err(dip, CE_WARN, "failed to attach sensor %s: %d", buf, ret); goto err; } diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.c b/usr/src/uts/common/io/mlxcx/mlxcx.c index dbad9be958..90964d2fd1 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx.c @@ -1066,6 +1066,11 @@ mlxcx_teardown(mlxcx_t *mlxp) mlxcx_intr_disable(mlxp); } + if (mlxp->mlx_attach & MLXCX_ATTACH_SENSORS) { + mlxcx_teardown_sensors(mlxp); + mlxp->mlx_attach &= ~MLXCX_ATTACH_SENSORS; + } + if (mlxp->mlx_attach & MLXCX_ATTACH_CHKTIMERS) { mlxcx_teardown_checktimers(mlxp); mlxp->mlx_attach &= ~MLXCX_ATTACH_CHKTIMERS; @@ -1800,7 +1805,7 @@ mlxcx_setup_ports(mlxcx_t *mlxp) p->mlx_port_event.mla_mlx = mlxp; p->mlx_port_event.mla_port = p; mutex_init(&p->mlx_port_event.mla_mtx, NULL, - MUTEX_DRIVER, DDI_INTR_PRI(mlxp->mlx_intr_pri)); + MUTEX_DRIVER, DDI_INTR_PRI(mlxp->mlx_async_intr_pri)); p->mlp_init |= MLXCX_PORT_INIT; mutex_init(&p->mlp_mtx, NULL, MUTEX_DRIVER, DDI_INTR_PRI(mlxp->mlx_intr_pri)); @@ -2716,7 +2721,7 @@ mlxcx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) for (i = 0; i <= MLXCX_FUNC_ID_MAX; i++) { mlxp->mlx_npages_req[i].mla_mlx = mlxp; mutex_init(&mlxp->mlx_npages_req[i].mla_mtx, NULL, - MUTEX_DRIVER, DDI_INTR_PRI(mlxp->mlx_intr_pri)); + MUTEX_DRIVER, DDI_INTR_PRI(mlxp->mlx_async_intr_pri)); } mlxp->mlx_attach |= MLXCX_ATTACH_ASYNC_TQ; @@ -2869,6 +2874,11 @@ mlxcx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) } mlxp->mlx_attach |= MLXCX_ATTACH_CHKTIMERS; + if (!mlxcx_setup_sensors(mlxp)) { + goto err; + } + mlxp->mlx_attach |= MLXCX_ATTACH_SENSORS; + /* * Finally, tell MAC that we exist! */ @@ -2913,7 +2923,6 @@ static struct dev_ops mlxcx_dev_ops = { .devo_attach = mlxcx_attach, .devo_detach = mlxcx_detach, .devo_reset = nodev, - .devo_power = ddi_power, .devo_quiesce = ddi_quiesce_not_supported, .devo_cb_ops = &mlxcx_cb_ops }; diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.h b/usr/src/uts/common/io/mlxcx/mlxcx.h index 77d36447c6..e28fe89806 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx.h +++ b/usr/src/uts/common/io/mlxcx/mlxcx.h @@ -1009,6 +1009,15 @@ typedef struct { uint64_t mldp_wq_check_interval_sec; } mlxcx_drv_props_t; +typedef struct { + mlxcx_t *mlts_mlx; + uint8_t mlts_index; + id_t mlts_ksensor; + int16_t mlts_value; + int16_t mlts_max_value; + uint8_t mlts_name[MLXCX_MTMP_NAMELEN]; +} mlxcx_temp_sensor_t; + typedef enum { MLXCX_ATTACH_FM = 1 << 0, MLXCX_ATTACH_PCI_CONFIG = 1 << 1, @@ -1028,6 +1037,7 @@ typedef enum { MLXCX_ATTACH_CAPS = 1 << 15, MLXCX_ATTACH_CHKTIMERS = 1 << 16, MLXCX_ATTACH_ASYNC_TQ = 1 << 17, + MLXCX_ATTACH_SENSORS = 1 << 18 } mlxcx_attach_progress_t; struct mlxcx { @@ -1082,6 +1092,7 @@ struct mlxcx { * Interrupts */ uint_t mlx_intr_pri; + uint_t mlx_async_intr_pri; uint_t mlx_intr_type; /* always MSI-X */ int mlx_intr_count; size_t mlx_intr_size; /* allocation size */ @@ -1171,6 +1182,12 @@ struct mlxcx { ddi_periodic_t mlx_eq_checktimer; ddi_periodic_t mlx_cq_checktimer; ddi_periodic_t mlx_wq_checktimer; + + /* + * Sensors + */ + uint8_t mlx_temp_nsensors; + mlxcx_temp_sensor_t *mlx_temp_sensors; }; /* @@ -1446,6 +1463,12 @@ extern const char *mlxcx_port_status_string(mlxcx_port_status_t); extern const char *mlxcx_event_name(mlxcx_event_t); +/* + * Sensor Functions + */ +extern boolean_t mlxcx_setup_sensors(mlxcx_t *); +extern void mlxcx_teardown_sensors(mlxcx_t *); + #ifdef __cplusplus } #endif diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c index c8eb1335ea..32c40ec3ea 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c @@ -667,7 +667,8 @@ static void mlxcx_cmd_init(mlxcx_t *mlxp, mlxcx_cmd_t *cmd) { bzero(cmd, sizeof (*cmd)); - mutex_init(&cmd->mlcmd_lock, NULL, MUTEX_DRIVER, NULL); + mutex_init(&cmd->mlcmd_lock, NULL, MUTEX_DRIVER, + DDI_INTR_PRI(mlxp->mlx_async_intr_pri)); cv_init(&cmd->mlcmd_cv, NULL, CV_DRIVER, NULL); cmd->mlcmd_token = id_alloc(mlxp->mlx_cmd.mcmd_tokens); cmd->mlcmd_poll = mlxp->mlx_cmd.mcmd_polled; @@ -1687,6 +1688,10 @@ mlxcx_reg_name(mlxcx_register_id_t rid) return ("PPCNT"); case MLXCX_REG_PPLM: return ("PPLM"); + case MLXCX_REG_MTCAP: + return ("MTCAP"); + case MLXCX_REG_MTMP: + return ("MTMP"); default: return ("???"); } @@ -1736,6 +1741,12 @@ mlxcx_cmd_access_register(mlxcx_t *mlxp, mlxcx_cmd_reg_opmod_t opmod, case MLXCX_REG_PPLM: dsize = sizeof (mlxcx_reg_pplm_t); break; + case MLXCX_REG_MTCAP: + dsize = sizeof (mlxcx_reg_mtcap_t); + break; + case MLXCX_REG_MTMP: + dsize = sizeof (mlxcx_reg_mtmp_t); + break; default: dsize = 0; VERIFY(0); diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_gld.c b/usr/src/uts/common/io/mlxcx/mlxcx_gld.c index 89645bb2b1..941eb0f9e7 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx_gld.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx_gld.c @@ -809,19 +809,32 @@ mlxcx_mac_ring_stop(mac_ring_driver_t rh) if (wq->mlwq_state & MLXCX_WQ_BUFFERS) { + list_t cq_buffers; + + /* + * Take the buffers away from the CQ. If the CQ is being + * processed and the WQ has been stopped, a completion + * which does not match to a buffer will be ignored. + */ + list_create(&cq_buffers, sizeof (mlxcx_buffer_t), + offsetof(mlxcx_buffer_t, mlb_cq_entry)); + + list_move_tail(&cq_buffers, &cq->mlcq_buffers); + + mutex_enter(&cq->mlcq_bufbmtx); + list_move_tail(&cq_buffers, &cq->mlcq_buffers_b); + mutex_exit(&cq->mlcq_bufbmtx); + + cq->mlcq_bufcnt = 0; + mutex_exit(&wq->mlwq_mtx); mutex_exit(&cq->mlcq_mtx); /* Return any outstanding buffers to the free pool. */ - while ((buf = list_remove_head(&cq->mlcq_buffers)) != NULL) { + while ((buf = list_remove_head(&cq_buffers)) != NULL) { mlxcx_buf_return_chain(mlxp, buf, B_FALSE); } - mutex_enter(&cq->mlcq_bufbmtx); - while ((buf = list_remove_head(&cq->mlcq_buffers_b)) != NULL) { - mlxcx_buf_return_chain(mlxp, buf, B_FALSE); - } - mutex_exit(&cq->mlcq_bufbmtx); - cq->mlcq_bufcnt = 0; + list_destroy(&cq_buffers); s = wq->mlwq_bufs; mutex_enter(&s->mlbs_mtx); diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_intr.c b/usr/src/uts/common/io/mlxcx/mlxcx_intr.c index f79c148d20..53ea4d683e 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx_intr.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx_intr.c @@ -12,6 +12,7 @@ /* * Copyright (c) 2020, the University of Queensland * Copyright 2020 RackTop Systems, Inc. + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* @@ -922,6 +923,20 @@ lookagain: if (added) goto lookagain; + /* + * This check could go just after the lookagain + * label, but it is a hot code path so we don't + * want to unnecessarily grab a lock and check + * a flag for a relatively rare event (the ring + * being stopped). + */ + mutex_enter(&wq->mlwq_mtx); + if ((wq->mlwq_state & MLXCX_WQ_STARTED) == 0) { + mutex_exit(&wq->mlwq_mtx); + goto nextcq; + } + mutex_exit(&wq->mlwq_mtx); + buf = list_head(&mlcq->mlcq_buffers); mlxcx_warn(mlxp, "got completion on CQ %x but " "no buffer matching wqe found: %x (first " @@ -1165,6 +1180,7 @@ mlxcx_intr_setup(mlxcx_t *mlxp) ret = ddi_intr_get_supported_types(dip, &types); if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "Failed to get supported interrupt types"); return (B_FALSE); } @@ -1176,15 +1192,21 @@ mlxcx_intr_setup(mlxcx_t *mlxp) ret = ddi_intr_get_nintrs(dip, DDI_INTR_TYPE_MSIX, &nintrs); if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "Failed to get number of interrupts"); return (B_FALSE); } if (nintrs < 2) { - mlxcx_warn(mlxp, "%d MSI-X interrupts available, but mlxcx " + mlxcx_warn(mlxp, "%d MSI-X interrupts supported, but mlxcx " "requires 2", nintrs); return (B_FALSE); } ret = ddi_intr_get_navail(dip, DDI_INTR_TYPE_MSIX, &navail); + if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, + "Failed to get number of available interrupts"); + return (B_FALSE); + } if (navail < 2) { mlxcx_warn(mlxp, "%d MSI-X interrupts available, but mlxcx " "requires 2", navail); @@ -1203,10 +1225,14 @@ mlxcx_intr_setup(mlxcx_t *mlxp) ret = ddi_intr_alloc(dip, mlxp->mlx_intr_handles, DDI_INTR_TYPE_MSIX, 0, navail, &mlxp->mlx_intr_count, DDI_INTR_ALLOC_NORMAL); if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "Failed to allocate %d interrupts", navail); mlxcx_intr_teardown(mlxp); return (B_FALSE); } if (mlxp->mlx_intr_count < mlxp->mlx_intr_cq0 + 1) { + mlxcx_warn(mlxp, "%d MSI-X interrupts allocated, but mlxcx " + "requires %d", mlxp->mlx_intr_count, + mlxp->mlx_intr_cq0 + 1); mlxcx_intr_teardown(mlxp); return (B_FALSE); } @@ -1214,10 +1240,29 @@ mlxcx_intr_setup(mlxcx_t *mlxp) ret = ddi_intr_get_pri(mlxp->mlx_intr_handles[0], &mlxp->mlx_intr_pri); if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "Failed to get interrupt priority"); mlxcx_intr_teardown(mlxp); return (B_FALSE); } + /* + * Set the interrupt priority for the asynchronous handler higher + * than the ring handlers. Some operations which issue commands, + * and thus rely on the async interrupt handler for posting + * completion, do so with a CQ mutex held. The CQ mutex is also + * acquired during ring processing, so if the ring processing vector + * happens to be assigned to the same CPU as the async vector + * it can hold off the async interrupt thread and lead to a deadlock. + * By assigning a higher priority to the async vector, it will + * always be dispatched. + */ + mlxp->mlx_async_intr_pri = mlxp->mlx_intr_pri; + if (mlxp->mlx_async_intr_pri < LOCK_LEVEL) { + mlxp->mlx_async_intr_pri++; + } else { + mlxp->mlx_intr_pri--; + } + mlxp->mlx_eqs_size = mlxp->mlx_intr_count * sizeof (mlxcx_event_queue_t); mlxp->mlx_eqs = kmem_zalloc(mlxp->mlx_eqs_size, KM_SLEEP); @@ -1227,8 +1272,11 @@ mlxcx_intr_setup(mlxcx_t *mlxp) * mutex and avl tree to be init'ed - so do it now. */ for (i = 0; i < mlxp->mlx_intr_count; ++i) { + uint_t pri = (i == 0) ? mlxp->mlx_async_intr_pri : + mlxp->mlx_intr_pri; + mutex_init(&mlxp->mlx_eqs[i].mleq_mtx, NULL, MUTEX_DRIVER, - DDI_INTR_PRI(mlxp->mlx_intr_pri)); + DDI_INTR_PRI(pri)); cv_init(&mlxp->mlx_eqs[i].mleq_cv, NULL, CV_DRIVER, NULL); if (i < mlxp->mlx_intr_cq0) @@ -1239,9 +1287,38 @@ mlxcx_intr_setup(mlxcx_t *mlxp) offsetof(mlxcx_completion_queue_t, mlcq_eq_entry)); } + while (mlxp->mlx_async_intr_pri > DDI_INTR_PRI_MIN) { + ret = ddi_intr_set_pri(mlxp->mlx_intr_handles[0], + mlxp->mlx_async_intr_pri); + if (ret == DDI_SUCCESS) + break; + mlxcx_note(mlxp, + "!Failed to set interrupt priority to %u for " + "async interrupt vector", mlxp->mlx_async_intr_pri); + /* + * If it was not possible to set the IPL for the async + * interrupt to the desired value, then try a lower priority. + * Some PSMs can only accommodate a limited number of vectors + * at eatch priority level (or group of priority levels). Since + * the async priority must be set higher than the ring + * handlers, lower both. The ring handler priority is set + * below. + */ + mlxp->mlx_async_intr_pri--; + mlxp->mlx_intr_pri--; + } + + if (mlxp->mlx_async_intr_pri == DDI_INTR_PRI_MIN) { + mlxcx_warn(mlxp, "Failed to find an interrupt priority for " + "async interrupt vector"); + mlxcx_intr_teardown(mlxp); + return (B_FALSE); + } + ret = ddi_intr_add_handler(mlxp->mlx_intr_handles[0], mlxcx_intr_async, (caddr_t)mlxp, (caddr_t)&mlxp->mlx_eqs[0]); if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "Failed to add async interrupt handler"); mlxcx_intr_teardown(mlxp); return (B_FALSE); } @@ -1268,9 +1345,29 @@ mlxcx_intr_setup(mlxcx_t *mlxp) eqt = MLXCX_EQ_TYPE_RX; } + while (mlxp->mlx_intr_pri >= DDI_INTR_PRI_MIN) { + ret = ddi_intr_set_pri(mlxp->mlx_intr_handles[i], + mlxp->mlx_intr_pri); + if (ret == DDI_SUCCESS) + break; + mlxcx_note(mlxp, "!Failed to set interrupt priority to " + "%u for interrupt vector %d", + mlxp->mlx_intr_pri, i); + mlxp->mlx_intr_pri--; + } + if (mlxp->mlx_intr_pri < DDI_INTR_PRI_MIN) { + mlxcx_warn(mlxp, + "Failed to find an interrupt priority for " + "interrupt vector %d", i); + mlxcx_intr_teardown(mlxp); + return (B_FALSE); + } + ret = ddi_intr_add_handler(mlxp->mlx_intr_handles[i], mlxcx_intr_n, (caddr_t)mlxp, (caddr_t)&mlxp->mlx_eqs[i]); if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "Failed to add interrupt handler %d", + i); mlxcx_intr_teardown(mlxp); return (B_FALSE); } diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_reg.h b/usr/src/uts/common/io/mlxcx/mlxcx_reg.h index 1987ae06ea..4b92de92b8 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx_reg.h +++ b/usr/src/uts/common/io/mlxcx/mlxcx_reg.h @@ -2530,6 +2530,30 @@ typedef struct { uint16be_t mlrd_pplm_fec_override_admin_fdr10; } mlxcx_reg_pplm_t; +typedef struct { + uint8_t mlrd_mtcap_rsvd[3]; + uint8_t mlrd_mtcap_sensor_count; + uint8_t mlrd_mtcap_rsvd1[4]; + uint64be_t mlrd_mtcap_sensor_map; +} mlxcx_reg_mtcap_t; + +#define MLXCX_MTMP_NAMELEN 8 + +typedef struct { + uint8_t mlrd_mtmp_rsvd[2]; + uint16be_t mlrd_mtmp_sensor_index; + uint8_t mlrd_mtmp_rsvd1[2]; + uint16be_t mlrd_mtmp_temperature; + bits16_t mlrd_mtmp_max_flags; + uint16be_t mlrd_mtmp_max_temperature; + bits16_t mlrd_mtmp_tee; + uint16be_t mlrd_mtmp_temp_thresh_hi; + uint8_t mlrd_mtmp_rsvd2[2]; + uint16be_t mlrd_mtmp_temp_thresh_lo; + uint8_t mlrd_mtmp_rsvd3[4]; + uint8_t mlrd_mtmp_name[MLXCX_MTMP_NAMELEN]; +} mlxcx_reg_mtmp_t; + typedef enum { MLXCX_REG_PMTU = 0x5003, MLXCX_REG_PTYS = 0x5004, @@ -2540,6 +2564,8 @@ typedef enum { MLXCX_REG_MCIA = 0x9014, MLXCX_REG_PPCNT = 0x5008, MLXCX_REG_PPLM = 0x5023, + MLXCX_REG_MTCAP = 0x9009, + MLXCX_REG_MTMP = 0x900A } mlxcx_register_id_t; typedef union { @@ -2551,6 +2577,8 @@ typedef union { mlxcx_reg_mcia_t mlrd_mcia; mlxcx_reg_ppcnt_t mlrd_ppcnt; mlxcx_reg_pplm_t mlrd_pplm; + mlxcx_reg_mtcap_t mlrd_mtcap; + mlxcx_reg_mtmp_t mlrd_mtmp; } mlxcx_register_data_t; typedef enum { diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_sensor.c b/usr/src/uts/common/io/mlxcx/mlxcx_sensor.c new file mode 100644 index 0000000000..6d2c7d0778 --- /dev/null +++ b/usr/src/uts/common/io/mlxcx/mlxcx_sensor.c @@ -0,0 +1,126 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2020 Oxide Computer Company + */ + +#include <mlxcx.h> +#include <sys/sensors.h> + +/* + * The PRM indicates that the temperature is measured in 1/8th degrees. + */ +#define MLXCX_TEMP_GRAN 8 + +/* + * Read a single temperature sensor entry. The ksensor framework guarantees that + * it will only call this once for a given sensor at any time, though multiple + * sensors can be in parallel. + */ +static int +mlxcx_temperature_read(void *arg, sensor_ioctl_scalar_t *scalar) +{ + boolean_t ok; + uint16_t tmp; + mlxcx_register_data_t data; + mlxcx_temp_sensor_t *sensor = arg; + mlxcx_t *mlxp = sensor->mlts_mlx; + + bzero(&data, sizeof (data)); + data.mlrd_mtmp.mlrd_mtmp_sensor_index = to_be16(sensor->mlts_index); + ok = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ, + MLXCX_REG_MTMP, &data); + if (!ok) { + return (EIO); + } + + tmp = from_be16(data.mlrd_mtmp.mlrd_mtmp_temperature); + sensor->mlts_value = (int16_t)tmp; + tmp = from_be16(data.mlrd_mtmp.mlrd_mtmp_max_temperature); + sensor->mlts_max_value = (int16_t)tmp; + bcopy(data.mlrd_mtmp.mlrd_mtmp_name, sensor->mlts_name, + sizeof (sensor->mlts_name)); + + scalar->sis_unit = SENSOR_UNIT_CELSIUS; + scalar->sis_gran = MLXCX_TEMP_GRAN; + scalar->sis_prec = 0; + scalar->sis_value = (int64_t)sensor->mlts_value; + + return (0); +} + +static const ksensor_ops_t mlxcx_temp_ops = { + .kso_kind = ksensor_kind_temperature, + .kso_scalar = mlxcx_temperature_read +}; + +void +mlxcx_teardown_sensors(mlxcx_t *mlxp) +{ + if (mlxp->mlx_temp_nsensors == 0) + return; + (void) ksensor_remove(mlxp->mlx_dip, KSENSOR_ALL_IDS); + kmem_free(mlxp->mlx_temp_sensors, sizeof (mlxcx_temp_sensor_t) * + mlxp->mlx_temp_nsensors); +} + +boolean_t +mlxcx_setup_sensors(mlxcx_t *mlxp) +{ + mlxcx_register_data_t data; + boolean_t ok; + + mlxp->mlx_temp_nsensors = 0; + bzero(&data, sizeof (data)); + ok = mlxcx_cmd_access_register(mlxp, MLXCX_CMD_ACCESS_REGISTER_READ, + MLXCX_REG_MTCAP, &data); + if (!ok) { + return (B_FALSE); + } + + if (data.mlrd_mtcap.mlrd_mtcap_sensor_count == 0) { + return (B_TRUE); + } + + mlxp->mlx_temp_nsensors = data.mlrd_mtcap.mlrd_mtcap_sensor_count; + mlxp->mlx_temp_sensors = kmem_zalloc(sizeof (mlxcx_temp_sensor_t) * + mlxp->mlx_temp_nsensors, KM_SLEEP); + + for (uint8_t i = 0; i < mlxp->mlx_temp_nsensors; i++) { + char buf[32]; + int ret; + + if (snprintf(buf, sizeof (buf), "temp%u", i) >= sizeof (buf)) { + mlxcx_warn(mlxp, "sensor name %u would overflow " + "internal buffer"); + goto err; + } + + mlxp->mlx_temp_sensors[i].mlts_mlx = mlxp; + mlxp->mlx_temp_sensors[i].mlts_index = i; + + ret = ksensor_create_scalar_pcidev(mlxp->mlx_dip, + SENSOR_KIND_TEMPERATURE, &mlxcx_temp_ops, + &mlxp->mlx_temp_sensors[i], buf, + &mlxp->mlx_temp_sensors[i].mlts_ksensor); + if (ret != 0) { + mlxcx_warn(mlxp, "failed to create temp sensor %s: %d", + buf, ret); + goto err; + } + } + + return (B_TRUE); +err: + mlxcx_teardown_sensors(mlxp); + return (B_FALSE); +} diff --git a/usr/src/uts/common/io/tem.c b/usr/src/uts/common/io/tem.c index 573e10cd66..525aa5f585 100644 --- a/usr/src/uts/common/io/tem.c +++ b/usr/src/uts/common/io/tem.c @@ -524,10 +524,41 @@ tems_check_videomode(struct vis_devinit *tp) } static void -tems_setup_terminal(struct vis_devinit *tp, size_t height, size_t width) +tems_setup_font(screen_size_t height, screen_size_t width) { bitmap_data_t *font_data; int i; + + /* + * set_font() will select an appropriate sized font for + * the number of rows and columns selected. If we don't + * have a font that will fit, then it will use the + * default builtin font and adjust the rows and columns + * to fit on the screen. + */ + font_data = set_font(&tems.ts_c_dimension.height, + &tems.ts_c_dimension.width, height, width); + + /* + * To use loaded font, we assign the loaded font data to tems.ts_font. + * In case of next load, the previously loaded data is freed + * when loading the new font. + */ + for (i = 0; i < VFNT_MAPS; i++) { + tems.ts_font.vf_map[i] = + font_data->font->vf_map[i]; + tems.ts_font.vf_map_count[i] = + font_data->font->vf_map_count[i]; + } + + tems.ts_font.vf_bytes = font_data->font->vf_bytes; + tems.ts_font.vf_width = font_data->font->vf_width; + tems.ts_font.vf_height = font_data->font->vf_height; +} + +static void +tems_setup_terminal(struct vis_devinit *tp, size_t height, size_t width) +{ int old_blank_buf_size = tems.ts_c_dimension.width * sizeof (*tems.ts_blank_line); @@ -546,6 +577,9 @@ tems_setup_terminal(struct vis_devinit *tp, size_t height, size_t width) tems.ts_c_dimension.height = tp->height; tems.ts_callbacks = &tem_safe_text_callbacks; + tems_setup_font(16 * tp->height + BORDER_PIXELS, + 8 * tp->width + BORDER_PIXELS); + break; case VIS_PIXEL: @@ -559,33 +593,11 @@ tems_setup_terminal(struct vis_devinit *tp, size_t height, size_t width) } tems.ts_c_dimension.height = (screen_size_t)height; tems.ts_c_dimension.width = (screen_size_t)width; - tems.ts_p_dimension.height = tp->height; tems.ts_p_dimension.width = tp->width; - tems.ts_callbacks = &tem_safe_pix_callbacks; - /* - * set_font() will select a appropriate sized font for - * the number of rows and columns selected. If we don't - * have a font that will fit, then it will use the - * default builtin font. set_font() will adjust the rows - * and columns to fit on the screen. - */ - font_data = set_font(&tems.ts_c_dimension.height, - &tems.ts_c_dimension.width, - tems.ts_p_dimension.height, - tems.ts_p_dimension.width); - - for (i = 0; i < VFNT_MAPS; i++) { - tems.ts_font.vf_map[i] = - font_data->font->vf_map[i]; - tems.ts_font.vf_map_count[i] = - font_data->font->vf_map_count[i]; - } - tems.ts_font.vf_bytes = font_data->font->vf_bytes; - tems.ts_font.vf_width = font_data->font->vf_width; - tems.ts_font.vf_height = font_data->font->vf_height; + tems_setup_font(tp->height, tp->width); tems.ts_p_offset.y = (tems.ts_p_dimension.height - (tems.ts_c_dimension.height * tems.ts_font.vf_height)) / 2; @@ -594,9 +606,7 @@ tems_setup_terminal(struct vis_devinit *tp, size_t height, size_t width) tems.ts_pix_data_size = tems.ts_font.vf_width * tems.ts_font.vf_height; - tems.ts_pix_data_size *= 4; - tems.ts_pdepth = tp->depth; break; @@ -963,6 +973,7 @@ tems_get_initial_color(tem_color_t *pcolor) if (inverse_screen) flags |= TEM_ATTR_SCREEN_REVERSE; +#ifdef _HAVE_TEM_FIRMWARE if (flags != 0) { /* * If either reverse flag is set, the screen is in @@ -980,6 +991,21 @@ tems_get_initial_color(tem_color_t *pcolor) if (pcolor->bg_color == ANSI_COLOR_WHITE) flags |= TEM_ATTR_BRIGHT_BG; } +#else + if (flags != 0) { + if (pcolor->fg_color == ANSI_COLOR_WHITE) + flags |= TEM_ATTR_BRIGHT_BG; + + if (pcolor->fg_color == ANSI_COLOR_BLACK) + flags &= ~TEM_ATTR_BRIGHT_BG; + } else { + /* + * In case of black on white we want bright white for BG. + */ + if (pcolor->bg_color == ANSI_COLOR_WHITE) + flags |= TEM_ATTR_BRIGHT_BG; + } +#endif pcolor->a_flags = flags; } diff --git a/usr/src/uts/common/io/tem_safe.c b/usr/src/uts/common/io/tem_safe.c index 5008d4a4d6..8d47a00d5f 100644 --- a/usr/src/uts/common/io/tem_safe.c +++ b/usr/src/uts/common/io/tem_safe.c @@ -129,9 +129,12 @@ static void tem_safe_copy_area(struct tem_vt_state *tem, screen_pos_t e_col, screen_pos_t e_row, screen_pos_t t_col, screen_pos_t t_row, cred_t *credp, enum called_from called_from); +#if 0 +/* Currently unused */ static void tem_safe_image_display(struct tem_vt_state *, uchar_t *, int, int, screen_pos_t, screen_pos_t, cred_t *, enum called_from); +#endif static void tem_safe_bell(struct tem_vt_state *tem, enum called_from called_from); static void tem_safe_pix_clear_prom_output(struct tem_vt_state *tem, @@ -1568,6 +1571,7 @@ tem_safe_text_display(struct tem_vt_state *tem, term_char_t *string, } } +#if 0 /* * This function is used to blit a rectangular color image, * unperturbed on the underlying framebuffer, to render @@ -1600,6 +1604,7 @@ tem_safe_image_display(struct tem_vt_state *tem, uchar_t *image, mutex_exit(&tem->tvs_lock); mutex_exit(&tems.ts_lock); } +#endif /*ARGSUSED*/ void @@ -2385,12 +2390,22 @@ tem_safe_get_attr(struct tem_vt_state *tem, text_color_t *fg, static void tem_safe_get_color(text_color_t *fg, text_color_t *bg, term_char_t c) { + boolean_t bold_font; + *fg = c.tc_fg_color; *bg = c.tc_bg_color; + bold_font = tems.ts_font.vf_map_count[VFNT_MAP_BOLD] != 0; + + /* + * If we have both normal and bold font components, + * we use bold font for TEM_ATTR_BOLD. + * The bright color is traditionally used with TEM_ATTR_BOLD, + * in case there is no bold font. + */ if (c.tc_fg_color < XLATE_NCOLORS) { - if (TEM_ATTR_ISSET(c.tc_char, - TEM_ATTR_BRIGHT_FG | TEM_ATTR_BOLD)) + if (TEM_ATTR_ISSET(c.tc_char, TEM_ATTR_BRIGHT_FG) || + (TEM_ATTR_ISSET(c.tc_char, TEM_ATTR_BOLD) && !bold_font)) *fg = brt_xlate[c.tc_fg_color]; else *fg = dim_xlate[c.tc_fg_color]; diff --git a/usr/src/uts/common/io/usb/usba/hubdi.c b/usr/src/uts/common/io/usb/usba/hubdi.c index 99d75edce3..5207a51490 100644 --- a/usr/src/uts/common/io/usb/usba/hubdi.c +++ b/usr/src/uts/common/io/usb/usba/hubdi.c @@ -55,48 +55,45 @@ extern boolean_t consconfig_console_is_ready(void); /* * Prototypes for static functions */ -static int usba_hubdi_bus_ctl( - dev_info_t *dip, - dev_info_t *rdip, - ddi_ctl_enum_t op, - void *arg, - void *result); - -static int usba_hubdi_map_fault( - dev_info_t *dip, - dev_info_t *rdip, - struct hat *hat, - struct seg *seg, - caddr_t addr, - struct devpage *dp, - pfn_t pfn, - uint_t prot, - uint_t lock); +static int usba_hubdi_bus_ctl(dev_info_t *dip, + dev_info_t *rdip, + ddi_ctl_enum_t op, + void *arg, + void *result); + +static int usba_hubdi_map_fault(dev_info_t *dip, + dev_info_t *rdip, + struct hat *hat, + struct seg *seg, + caddr_t addr, + struct devpage *dp, + pfn_t pfn, + uint_t prot, + uint_t lock); static int hubd_busop_get_eventcookie(dev_info_t *dip, - dev_info_t *rdip, - char *eventname, - ddi_eventcookie_t *cookie); + dev_info_t *rdip, + char *eventname, + ddi_eventcookie_t *cookie); static int hubd_busop_add_eventcall(dev_info_t *dip, - dev_info_t *rdip, - ddi_eventcookie_t cookie, - void (*callback)(dev_info_t *dip, - ddi_eventcookie_t cookie, void *arg, - void *bus_impldata), - void *arg, ddi_callback_id_t *cb_id); + dev_info_t *rdip, + ddi_eventcookie_t cookie, + void (*callback)(dev_info_t *dip, ddi_eventcookie_t cookie, void *arg, + void *bus_impldata), + void *arg, ddi_callback_id_t *cb_id); static int hubd_busop_remove_eventcall(dev_info_t *dip, - ddi_callback_id_t cb_id); + ddi_callback_id_t cb_id); static int hubd_bus_config(dev_info_t *dip, - uint_t flag, - ddi_bus_config_op_t op, - void *arg, - dev_info_t **child); + uint_t flag, + ddi_bus_config_op_t op, + void *arg, + dev_info_t **child); static int hubd_bus_unconfig(dev_info_t *dip, - uint_t flag, - ddi_bus_config_op_t op, - void *arg); + uint_t flag, + ddi_bus_config_op_t op, + void *arg); static int hubd_bus_power(dev_info_t *dip, void *impl_arg, - pm_bus_power_op_t op, void *arg, void *result); + pm_bus_power_op_t op, void *arg, void *result); static usb_port_t hubd_get_port_num(hubd_t *, struct devctl_iocdata *); static dev_info_t *hubd_get_child_dip(hubd_t *, usb_port_t); @@ -251,14 +248,14 @@ usba_hubdi_unregister(dev_info_t *dip) /*ARGSUSED*/ static int usba_hubdi_map_fault(dev_info_t *dip, - dev_info_t *rdip, - struct hat *hat, - struct seg *seg, - caddr_t addr, - struct devpage *dp, - pfn_t pfn, - uint_t prot, - uint_t lock) + dev_info_t *rdip, + struct hat *hat, + struct seg *seg, + caddr_t addr, + struct devpage *dp, + pfn_t pfn, + uint_t prot, + uint_t lock) { return (DDI_FAILURE); } @@ -269,9 +266,9 @@ usba_hubdi_map_fault(dev_info_t *dip, */ int usba_hubdi_bind_root_hub(dev_info_t *dip, - uchar_t *root_hub_config_descriptor, - size_t config_length, - usb_dev_descr_t *root_hub_device_descriptor) + uchar_t *root_hub_config_descriptor, + size_t config_length, + usb_dev_descr_t *root_hub_device_descriptor) { usba_device_t *usba_device; usba_hcdi_t *hcdi = usba_hcdi_get_hcdi(dip); @@ -1145,10 +1142,10 @@ hubd_post_power(hubd_t *hubd, usb_port_t port, pm_bp_child_pwrchg_t *bpc, */ static int usba_hubdi_bus_ctl(dev_info_t *dip, - dev_info_t *rdip, - ddi_ctl_enum_t op, - void *arg, - void *result) + dev_info_t *rdip, + ddi_ctl_enum_t op, + void *arg, + void *result) { usba_device_t *hub_usba_device = usba_get_usba_device(rdip); dev_info_t *root_hub_dip = hub_usba_device->usb_root_hub_dip; @@ -1294,7 +1291,7 @@ usba_hubdi_bus_ctl(dev_info_t *dip, /* * hubd_config_one: - * enumerate one child according to 'port' + * enumerate one child according to 'port' */ static boolean_t @@ -2625,8 +2622,7 @@ hubd_restore_device_state(dev_info_t *dip, hubd_t *hubd) /* * wait at least 3 frames before accessing devices - * (note that delay's minimal time is one clock tick which - * is 10ms unless hires_tick has been changed) + * (note that delay's minimal time is one clock tick). */ mutex_exit(HUBD_MUTEX(hubd)); delay(drv_usectohz(10000)); @@ -3331,8 +3327,8 @@ hubd_set_hub_depth(hubd_t *hubd) int rval; usb_cr_t completion_reason; usb_cb_flags_t cb_flags; - usba_device_t *ud; - uint16_t depth; + usba_device_t *ud; + uint16_t depth; /* * We only need to set the hub depth devices for hubs that are at least @@ -6044,7 +6040,7 @@ hubd_ready_device(hubd_t *hubd, dev_info_t *child_dip, usba_device_t *child_ud, child_ud->usb_active_cfg_ndx = config_index; child_ud->usb_cfg = child_ud->usb_cfg_array[config_index]; child_ud->usb_cfg_length = config_descriptor.wTotalLength; - child_ud->usb_cfg_value = config_descriptor.bConfigurationValue; + child_ud->usb_cfg_value = config_descriptor.bConfigurationValue; child_ud->usb_n_ifs = config_descriptor.bNumInterfaces; child_ud->usb_dip = child_dip; @@ -6089,11 +6085,11 @@ hubd_ready_device(hubd_t *hubd, dev_info_t *child_dip, usba_device_t *child_ud, */ static int hubd_create_child(dev_info_t *dip, - hubd_t *hubd, - usba_device_t *hubd_ud, - usb_port_status_t port_status, - usb_port_t port, - int iteration) + hubd_t *hubd, + usba_device_t *hubd_ud, + usb_port_status_t port_status, + usb_port_t port, + int iteration) { dev_info_t *child_dip = NULL; usb_dev_descr_t usb_dev_descr; @@ -6869,9 +6865,9 @@ hubd_free_usba_device(hubd_t *hubd, usba_device_t *usba_device) */ static int hubd_busop_get_eventcookie(dev_info_t *dip, - dev_info_t *rdip, - char *eventname, - ddi_eventcookie_t *cookie) + dev_info_t *rdip, + char *eventname, + ddi_eventcookie_t *cookie) { hubd_t *hubd = (hubd_t *)hubd_get_soft_state(dip); @@ -6891,12 +6887,11 @@ hubd_busop_get_eventcookie(dev_info_t *dip, static int hubd_busop_add_eventcall(dev_info_t *dip, - dev_info_t *rdip, - ddi_eventcookie_t cookie, - void (*callback)(dev_info_t *dip, - ddi_eventcookie_t cookie, void *arg, - void *bus_impldata), - void *arg, ddi_callback_id_t *cb_id) + dev_info_t *rdip, + ddi_eventcookie_t cookie, + void (*callback)(dev_info_t *dip, ddi_eventcookie_t cookie, void *arg, + void *bus_impldata), + void *arg, ddi_callback_id_t *cb_id) { hubd_t *hubd = (hubd_t *)hubd_get_soft_state(dip); usb_port_t port = hubd_child_dip2port(hubd, rdip); @@ -7671,7 +7666,7 @@ usba_hubdi_open(dev_info_t *dip, dev_t *devp, int flags, int otyp, /* ARGSUSED */ int usba_hubdi_close(dev_info_t *dip, dev_t dev, int flag, int otyp, - cred_t *credp) + cred_t *credp) { hubd_t *hubd; diff --git a/usr/src/uts/common/mapfiles/ksensor.mapfile b/usr/src/uts/common/mapfiles/ksensor.mapfile index 0374c957f7..51b65a2b9d 100644 --- a/usr/src/uts/common/mapfiles/ksensor.mapfile +++ b/usr/src/uts/common/mapfiles/ksensor.mapfile @@ -36,8 +36,10 @@ $mapfile_version 2 SYMBOL_SCOPE { global: ksensor_create { FLAGS = EXTERN }; - ksensor_create_temp_pcidev { FLAGS = EXTERN }; + ksensor_create_scalar_pcidev { FLAGS = EXTERN }; ksensor_remove { FLAGS = EXTERN }; + ksensor_kind_current { FLAGS = EXTERN }; ksensor_kind_temperature { FLAGS = EXTERN }; + ksensor_kind_voltage { FLAGS = EXTERN }; }; diff --git a/usr/src/uts/common/os/cred.c b/usr/src/uts/common/os/cred.c index 0bd6cfd44f..5e909667de 100644 --- a/usr/src/uts/common/os/cred.c +++ b/usr/src/uts/common/os/cred.c @@ -20,13 +20,14 @@ */ /* * Copyright (c) 2013, Ira Cooper. All rights reserved. + * Copyright 2020 Nexenta by DDN, Inc. All rights reserved. */ /* * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved. */ /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */ -/* All Rights Reserved */ +/* All Rights Reserved */ /* * University Copyright- Copyright (c) 1982, 1986, 1988 @@ -288,7 +289,7 @@ crget(void) { cred_t *cr = kmem_cache_alloc(cred_cache, KM_SLEEP); - bcopy(kcred, cr, crsize); + bcopy(zone_kcred(), cr, crsize); cr->cr_ref = 1; zone_cred_hold(cr->cr_zone); if (cr->cr_label) @@ -377,7 +378,7 @@ crfree(cred_t *cr) /* * Copy a cred structure to a new one and free the old one. * The new cred will have two references. One for the calling process, - * and one for the thread. + * and one for the thread. */ cred_t * crcopy(cred_t *cr) @@ -404,7 +405,7 @@ crcopy(cred_t *cr) /* * Copy a cred structure to a new one and free the old one. * The new cred will have two references. One for the calling process, - * and one for the thread. + * and one for the thread. * This variation on crcopy uses a pre-allocated structure for the * "new" cred. */ diff --git a/usr/src/uts/common/os/ksensor.c b/usr/src/uts/common/os/ksensor.c index c89cad4206..491fbcc7cd 100644 --- a/usr/src/uts/common/os/ksensor.c +++ b/usr/src/uts/common/os/ksensor.c @@ -544,14 +544,29 @@ ksensor_create(dev_info_t *dip, const ksensor_ops_t *ops, void *arg, } int -ksensor_create_temp_pcidev(dev_info_t *dip, const ksensor_ops_t *ops, - void *arg, const char *name, id_t *idp) +ksensor_create_scalar_pcidev(dev_info_t *dip, uint_t kind, + const ksensor_ops_t *ops, void *arg, const char *name, id_t *idp) { char *pci_name, *type; + const char *class; int *regs, ret; uint_t nregs; uint16_t bus, dev; + switch (kind) { + case SENSOR_KIND_TEMPERATURE: + class = "ddi_sensor:temperature:pci"; + break; + case SENSOR_KIND_VOLTAGE: + class = "ddi_sensor:voltage:pci"; + break; + case SENSOR_KIND_CURRENT: + class = "ddi_sensor:current:pci"; + break; + default: + return (ENOTSUP); + } + if (ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0, "device_type", &type) != DDI_PROP_SUCCESS) { return (EINVAL); @@ -579,8 +594,7 @@ ksensor_create_temp_pcidev(dev_info_t *dip, const ksensor_ops_t *ops, pci_name = kmem_asprintf("%x.%x:%s", bus, dev, name); - ret = ksensor_create(dip, ops, arg, pci_name, - "ddi_sensor:temperature:pci", idp); + ret = ksensor_create(dip, ops, arg, pci_name, class, idp); strfree(pci_name); return (ret); } @@ -750,7 +764,7 @@ ksensor_op_kind(id_t id, sensor_ioctl_kind_t *kind) } int -ksensor_op_temperature(id_t id, sensor_ioctl_temperature_t *temp) +ksensor_op_scalar(id_t id, sensor_ioctl_scalar_t *scalar) { int ret; ksensor_t *sensor; @@ -759,7 +773,7 @@ ksensor_op_temperature(id_t id, sensor_ioctl_temperature_t *temp) return (ret); } - ret = sensor->ksensor_ops->kso_temp(sensor->ksensor_arg, temp); + ret = sensor->ksensor_ops->kso_scalar(sensor->ksensor_arg, scalar); ksensor_release(sensor); return (ret); @@ -831,6 +845,20 @@ ksensor_kind_temperature(void *unused, sensor_ioctl_kind_t *k) return (0); } +int +ksensor_kind_current(void *unused, sensor_ioctl_kind_t *k) +{ + k->sik_kind = SENSOR_KIND_CURRENT; + return (0); +} + +int +ksensor_kind_voltage(void *unused, sensor_ioctl_kind_t *k) +{ + k->sik_kind = SENSOR_KIND_VOLTAGE; + return (0); +} + void ksensor_init(void) { diff --git a/usr/src/uts/common/os/softint.c b/usr/src/uts/common/os/softint.c index ecdb038c79..8801340cf9 100644 --- a/usr/src/uts/common/os/softint.c +++ b/usr/src/uts/common/os/softint.c @@ -58,29 +58,29 @@ * * Starting state is IDLE. * - * softint() + * softint() * * * (c) - * ____________________________________________________ - * | ^ ^ - * v (a) | (b) | - * IDLE--------------------->PEND--------------------->DRAIN - * ^ | | - * | | | - * | | | - * | | | - * | | | - * | d d - * | | | - * | v v - * | PEND DRAIN - * | (e) & & - * |<-----------------------STEAL STEAL - * ^ | - * | | - * | (e) v - * |_________________________<__________________________| + * ____________________________________________________ + * | ^ ^ + * v (a) | (b) | + * IDLE--------------------->PEND--------------------->DRAIN + * ^ | | + * | | | + * | | | + * | | | + * | | | + * | d d + * | | | + * | v v + * | PEND DRAIN + * | (e) & & + * |<-----------------------STEAL STEAL + * ^ | + * | | + * | (e) v + * |_________________________<__________________________| * * * @@ -146,9 +146,9 @@ uint_t softcall_pokemax = 10; /* * This ensures that softcall entries don't get stuck for long. It's expressed - * in 10 milliseconds as 1 unit. When hires_tick is set or other clock frequency - * is used, softcall_init() ensures that it's still expressed as 1 = 10 milli - * seconds. + * in 10 milliseconds as 1 unit. Regardless of the value of hires_tick or + * clock frequency, softcall_init() ensures that it's still expressed as 1 = + * 10 milliseconds. */ unsigned int softcall_delay = 1; diff --git a/usr/src/uts/common/sys/font.h b/usr/src/uts/common/sys/font.h index 5733686bf3..f8f154f428 100644 --- a/usr/src/uts/common/sys/font.h +++ b/usr/src/uts/common/sys/font.h @@ -84,9 +84,11 @@ typedef struct bitmap_data { } bitmap_data_t; typedef enum { - FONT_AUTO, - FONT_MANUAL, - FONT_BOOT + FONT_AUTO, /* This font is loaded by software */ + FONT_MANUAL, /* This font is loaded manually by user */ + FONT_BOOT, /* This font was passed to kernel by bootloader */ + FONT_BUILTIN, /* This font was built in at compile time */ + FONT_RELOAD /* This font is marked to be re-read from file */ } FONT_FLAGS; struct fontlist { diff --git a/usr/src/uts/common/sys/ksensor_impl.h b/usr/src/uts/common/sys/ksensor_impl.h index 8d91973bc3..7407a264a2 100644 --- a/usr/src/uts/common/sys/ksensor_impl.h +++ b/usr/src/uts/common/sys/ksensor_impl.h @@ -35,7 +35,7 @@ extern void ksensor_init(void); * Operations vectors. */ extern int ksensor_op_kind(id_t, sensor_ioctl_kind_t *); -extern int ksensor_op_temperature(id_t, sensor_ioctl_temperature_t *); +extern int ksensor_op_scalar(id_t, sensor_ioctl_scalar_t *); /* * Registration callbacks. diff --git a/usr/src/uts/common/sys/mac.h b/usr/src/uts/common/sys/mac.h index a5974f6d7d..bd668cdb6b 100644 --- a/usr/src/uts/common/sys/mac.h +++ b/usr/src/uts/common/sys/mac.h @@ -171,6 +171,7 @@ typedef enum { * Please append properties to the end of this list. Do not reorder the list. */ typedef enum { + MAC_PROP_PRIVATE = -1, MAC_PROP_DUPLEX = 0x00000001, MAC_PROP_SPEED, MAC_PROP_STATUS, @@ -248,8 +249,7 @@ typedef enum { MAC_PROP_ADV_50GFDX_CAP, MAC_PROP_EN_50GFDX_CAP, MAC_PROP_EN_FEC_CAP, - MAC_PROP_ADV_FEC_CAP, - MAC_PROP_PRIVATE = -1 + MAC_PROP_ADV_FEC_CAP } mac_prop_id_t; /* diff --git a/usr/src/uts/common/sys/sensors.h b/usr/src/uts/common/sys/sensors.h index a39dfca239..a5d830a933 100644 --- a/usr/src/uts/common/sys/sensors.h +++ b/usr/src/uts/common/sys/sensors.h @@ -33,6 +33,8 @@ extern "C" { */ #define SENSOR_KIND_UNKNOWN 0x00 #define SENSOR_KIND_TEMPERATURE 0x01 +#define SENSOR_KIND_VOLTAGE 0x02 +#define SENSOR_KIND_CURRENT 0x03 /* * Lists of units that senors may have. @@ -41,52 +43,60 @@ extern "C" { #define SENSOR_UNIT_CELSIUS 0x01 #define SENSOR_UNIT_FAHRENHEIT 0x02 #define SENSOR_UNIT_KELVIN 0x03 +#define SENSOR_UNIT_VOLTS 0x04 +#define SENSOR_UNIT_AMPS 0x05 #define SENSOR_IOCTL (('s' << 24) | ('e' << 16) | ('n' << 8)) /* * Ask the sensor what kind of sensor it is. */ -#define SENSOR_IOCTL_TYPE (SENSOR_IOCTL | 0x01) +#define SENSOR_IOCTL_KIND (SENSOR_IOCTL | 0x01) typedef struct sensor_ioctl_kind { uint64_t sik_kind; } sensor_ioctl_kind_t; /* - * Ask the sensor for a temperature measurement. The sensor is responsible for - * returning the units it's in. A temperature measurement is broken down into a + * Ask the sensor for a scalar measurement. The sensor is responsible for + * returning the units it's in. A scalar measurement is broken down into a * signed value and a notion of its granularity. The sit_gran member indicates - * the granularity: the number of increments per degree in the temperature - * measurement (the sit_temp member). sit_gran is signed and the sign indicates - * whether one needs to multiply or divide the granularity. For example, a - * value that set sit_gran to 10 would mean that the value in sit_temp was in - * 10ths of a degree and that to get the actual value in degrees, one would - * divide by 10. On the other hand, a negative value means that we effectively - * have to multiply to get there. For example, a value of -2 would indicate that - * each value in sit_temp indicated two degrees and to get the temperature in - * degrees you would multiply sit_temp by two. + * the granularity: the number of increments per unit in the measurement (the + * sit_value member). sit_gran is signed and the sign indicates whether one + * needs to multiply or divide the granularity. The sit_prec member describes a + * +/- value (taking sit_gran into account) that describes the precision of the + * sensor. + * + * For example, consider a temperature sensor that set sit_gran to 10. This + * would mean that the value in sit_value was in 10ths of a degree and that to + * get the actual value in degrees, one would divide by 10. On the other hand, a + * negative value means that we effectively have to multiply to get there. For + * example, a value of -2 would indicate that each value in sit_value indicated + * two degrees and to get the temperature in degrees you would multiply + * sit_value * by two. */ -#define SENSOR_IOCTL_TEMPERATURE (SENSOR_IOCTL | 0x02) +#define SENSOR_IOCTL_SCALAR (SENSOR_IOCTL | 0x02) -typedef struct sensor_ioctl_temperature { - uint32_t sit_unit; - int32_t sit_gran; - uint32_t sit_prec; - uint32_t sit_pad; - int64_t sit_temp; -} sensor_ioctl_temperature_t; +typedef struct sensor_ioctl_scalar { + uint32_t sis_unit; + int32_t sis_gran; + uint32_t sis_prec; + uint32_t sis_pad; + int64_t sis_value; +} sensor_ioctl_scalar_t; #ifdef _KERNEL typedef int (*ksensor_kind_f)(void *, sensor_ioctl_kind_t *); -typedef int (*ksensor_temp_f)(void *, sensor_ioctl_temperature_t *); +typedef int (*ksensor_scalar_f)(void *, sensor_ioctl_scalar_t *); typedef struct { - ksensor_kind_f kso_kind; - ksensor_temp_f kso_temp; + ksensor_kind_f kso_kind; + ksensor_scalar_f kso_scalar; } ksensor_ops_t; extern int ksensor_kind_temperature(void *, sensor_ioctl_kind_t *); +extern int ksensor_kind_voltage(void *, sensor_ioctl_kind_t *); +extern int ksensor_kind_current(void *, sensor_ioctl_kind_t *); /* * Create a sensor where the class and name is supplied. @@ -95,11 +105,11 @@ extern int ksensor_create(dev_info_t *, const ksensor_ops_t *, void *, const char *, const char *, id_t *); /* - * Create a temperature sensor for a PCI device. If this is not a device-wide + * Create a scalar sensor for a PCI device. If this is not a device-wide * (e.g. per-function) sensor, this should not be used. */ -extern int ksensor_create_temp_pcidev(dev_info_t *, const ksensor_ops_t *, - void *, const char *, id_t *); +extern int ksensor_create_scalar_pcidev(dev_info_t *, uint_t, + const ksensor_ops_t *, void *, const char *, id_t *); /* * Remove a named or all sensors from this driver. diff --git a/usr/src/uts/common/sys/smbios.h b/usr/src/uts/common/sys/smbios.h index 55048d549d..b8b470b79a 100644 --- a/usr/src/uts/common/sys/smbios.h +++ b/usr/src/uts/common/sys/smbios.h @@ -22,6 +22,7 @@ /* * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Oxide Computer Company * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -527,6 +528,8 @@ typedef struct smbios_processor { #define SMB_PRU_BGA1392 0x3A /* Socket BGA1392 */ #define SMB_PRU_BGA1510 0x3B /* Socket BGA1510 */ #define SMB_PRU_BGA1528 0x3C /* Socket BGA1528 */ +#define SMB_PRU_LGA4189 0x3D /* Socket LGA4189 */ +#define SMB_PRU_LGA1200 0x3E /* Socket LGA1200 */ #define SMB_PRC_RESERVED 0x0001 /* reserved */ #define SMB_PRC_UNKNOWN 0x0002 /* unknown */ @@ -944,6 +947,9 @@ typedef struct smbios_slot { uint8_t smbl_df; /* device/function number */ uint8_t smbl_dbw; /* data bus width */ uint8_t smbl_npeers; /* PCIe bifurcation peers */ + uint8_t smbl_info; /* slot info */ + uint8_t smbl_pwidth; /* slot physical width */ + uint32_t smbl_pitch; /* slot pitch in 10um */ } smbios_slot_t; #define SMB_SLT_OTHER 0x01 /* other */ @@ -976,8 +982,8 @@ typedef struct smbios_slot { #define SMB_SLT_MXM_V 0x1C /* MXM Type IV */ #define SMB_SLT_MXM3_A 0x1D /* MXM 3.0 Type A */ #define SMB_SLT_MXM3_B 0x1E /* MXM 3.0 Type B */ -#define SMB_SLT_PCIEG2_SFF 0x1F /* PCI Express Gen 2 SFF-8639 */ -#define SMB_SLT_PCIEG3_SFF 0x20 /* PCI Express Gen 3 SFF-8639 */ +#define SMB_SLT_PCIEG2_SFF 0x1F /* PCI Express Gen 2 SFF-8639 (U.2) */ +#define SMB_SLT_PCIEG3_SFF 0x20 /* PCI Express Gen 3 SFF-8639 (U.2) */ /* * These lines must be on one line for the string generating code. */ @@ -986,6 +992,11 @@ typedef struct smbios_slot { #define SMB_SLT_PCIE_M52_WOBSKO 0x22 /* PCI Express Mini 52-pin without bottom-side keep-outs */ /* END CSTYLED */ #define SMB_SLT_PCIE_M76 0x23 /* PCI Express Mini 72-pin */ +#define SMB_SLT_PCIEG4_SFF 0x24 /* PCI Express Gen 4 SFF-8639 (U.2) */ +#define SMB_SLT_PCIEG5_SFF 0x25 /* PCI Express Gen 5 SFF-8639 (U.2) */ +#define SMB_SLT_OCP3_SFF 0x26 /* OCP NIC 3.0 Small Form Factor */ +#define SMB_SLT_OCP3_LFF 0x27 /* OCP NIC 3.0 Large Form Factor */ +#define SMB_SLT_OCP_PRE 0x28 /* OCP NIC prior to 3.0 */ #define SMB_SLT_CXL1 0x30 /* CXL Flexbus 1.0 */ #define SMB_SLT_PC98_C20 0xA0 /* PC-98/C20 */ #define SMB_SLT_PC98_C24 0xA1 /* PC-98/C24 */ @@ -1016,6 +1027,15 @@ typedef struct smbios_slot { #define SMB_SLT_PCIE4G4 0xBB /* PCI Exp. Gen 4 x4 */ #define SMB_SLT_PCIE4G8 0xBC /* PCI Exp. Gen 4 x8 */ #define SMB_SLT_PCIE4G16 0xBD /* PCI Exp. Gen 4 x16 */ +#define SMB_SLT_PCIE5G 0xBE /* PCI Exp. Gen 5 */ +#define SMB_SLT_PCIE5G1 0xBF /* PCI Exp. Gen 5 x1 */ +#define SMB_SLT_PCIE5G2 0xC0 /* PCI Exp. Gen 5 x2 */ +#define SMB_SLT_PCIE5G4 0xC1 /* PCI Exp. Gen 5 x4 */ +#define SMB_SLT_PCIE5G8 0xC2 /* PCI Exp. Gen 5 x8 */ +#define SMB_SLT_PCIE5G16 0xC3 /* PCI Exp. Gen 5 x16 */ +#define SMB_SLT_PCIEG6P 0xC4 /* PCI Exp. Gen 6+ */ +#define SMB_SLT_EDSFF_E1 0xC5 /* Ent. and DC 1U E1 Form Factor */ +#define SMB_SLT_EDSFF_E3 0xC6 /* Ent. and DC 3" E3 Form Factor */ #define SMB_SLW_OTHER 0x01 /* other */ #define SMB_SLW_UNKNOWN 0x02 /* unknown */ @@ -1041,6 +1061,8 @@ typedef struct smbios_slot { #define SMB_SLL_UNKNOWN 0x02 /* unknown */ #define SMB_SLL_SHORT 0x03 /* short length */ #define SMB_SLL_LONG 0x04 /* long length */ +#define SMB_SLL_2IN5 0x05 /* 2.5" drive form factor */ +#define SMB_SLL_3IN5 0x06 /* 3.5" drive form factor */ #define SMB_SLCH1_UNKNOWN 0x01 /* characteristics unknown */ #define SMB_SLCH1_5V 0x02 /* provides 5.0V */ @@ -1055,6 +1077,9 @@ typedef struct smbios_slot { #define SMB_SLCH2_HOTPLUG 0x02 /* slot supports hot-plug devices */ #define SMB_SLCH2_SMBUS 0x04 /* slot supports SMBus signal */ #define SMB_SLCH2_BIFUR 0x08 /* slot supports PCIe bifurcation */ +#define SMB_SLCH2_SURPREM 0x10 /* slot supports surprise removal */ +#define SMB_SLCH2_CXL1 0x20 /* Flexbus slot, CXL 1.0 capable */ +#define SMB_SLCH2_CXL2 0x40 /* Flexbus slot, CXL 2.0 capable */ /* * SMBIOS 7.10.9 Slot Peer Devices @@ -1178,7 +1203,7 @@ typedef struct smbios_memarray { #define SMB_MAL_PC98C24 0xA1 /* PC-98/C24 add-on card */ #define SMB_MAL_PC98E 0xA2 /* PC-98/E add-on card */ #define SMB_MAL_PC98LB 0xA3 /* PC-98/Local bus add-on card */ -#define SMB_MAL_CXL1 0xA4 /* CXL Flexbus 1.0 add-on card */ +#define SMB_MAL_CXL1 0xA4 /* CXL add-on card */ #define SMB_MAU_OTHER 0x01 /* other */ #define SMB_MAU_UNKNOWN 0x02 /* unknown */ @@ -1285,6 +1310,8 @@ typedef struct smbios_memdevice { #define SMB_MDT_LOGNV 0x1F /* Logical non-volatile device */ #define SMB_MDT_HBM 0x20 /* High Bandwidth Memory */ #define SMB_MDT_HBM2 0x21 /* High Bandwidth Memory 2 */ +#define SMB_MDT_DDR5 0x22 /* DDR5 */ +#define SMB_MDT_LPDDR5 0x23 /* LPDDR5 */ #define SMB_MDF_OTHER 0x0002 /* other */ #define SMB_MDF_UNKNOWN 0x0004 /* unknown */ @@ -1313,7 +1340,7 @@ typedef struct smbios_memdevice { #define SMB_MTECH_NVDIMM_N 0x04 /* NVDIMM-N */ #define SMB_MTECH_NVDIMM_F 0x05 /* NVDIMM-F */ #define SMB_MTECH_NVDIMM_P 0x06 /* NVDIMM-P */ -#define SMB_MTECH_INTCPM 0x07 /* Intel Optane DC Persistent Memory */ +#define SMB_MTECH_INTCPM 0x07 /* Intel Optane persistent memory */ #define SMB_MOMC_RESERVED 0x01 /* reserved */ #define SMB_MOMC_OTHER 0x02 /* other */ @@ -1838,7 +1865,8 @@ typedef struct smbios_memdevice_ext { #define SMB_VERSION_31 0x0301 /* SMBIOS encoding for DMTF spec 3.1 */ #define SMB_VERSION_32 0x0302 /* SMBIOS encoding for DMTF spec 3.2 */ #define SMB_VERSION_33 0x0303 /* SMBIOS encoding for DMTF spec 3.3 */ -#define SMB_VERSION SMB_VERSION_33 /* SMBIOS latest version definitions */ +#define SMB_VERSION_34 0x0304 /* SMBIOS encoding for DMTF spec 3.4 */ +#define SMB_VERSION SMB_VERSION_34 /* SMBIOS latest version definitions */ #define SMB_O_NOCKSUM 0x1 /* do not verify header checksums */ #define SMB_O_NOVERS 0x2 /* do not verify header versions */ diff --git a/usr/src/uts/common/sys/smbios_impl.h b/usr/src/uts/common/sys/smbios_impl.h index 69ca79e94f..4b951b702f 100644 --- a/usr/src/uts/common/sys/smbios_impl.h +++ b/usr/src/uts/common/sys/smbios_impl.h @@ -22,6 +22,7 @@ /* * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Oxide Computer Company * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -250,9 +251,26 @@ typedef struct smb_slot { uint8_t smbsl_dbw; /* Data bus width */ uint8_t smbsl_npeers; /* Peer bdf groups */ smb_slot_peer_t smbsl_peers[]; /* bifurcation peers */ + /* There are later additions in 3.4+, see smbios_slot_cont_t */ } smb_slot_t; /* + * After the variable number of smbsl_peers, the smbios_slot has continued in + * size and has the following members defined as of version 3.4. These occur + * starting at byte 14 + 5 * smbsl_npeers. + */ +typedef struct smb_slot_cont { + uint8_t smbsl_info; /* slot info */ + uint8_t smbsl_pwidth; /* slot physical width */ + uint16_t smbsl_pitch; /* slot pitch */ +} smb_slot_cont_t; + +/* + * The first byte that the smb_slot_cont_t is defined to start at. + */ +#define SMB_SLOT_CONT_START 0x14 + +/* * SMBIOS implementation structure for SMB_TYPE_OBDEVS. */ typedef struct smb_obdev { diff --git a/usr/src/uts/common/sys/socket_proto.h b/usr/src/uts/common/sys/socket_proto.h index 4e1a4a0f35..825d0501c7 100644 --- a/usr/src/uts/common/sys/socket_proto.h +++ b/usr/src/uts/common/sys/socket_proto.h @@ -21,6 +21,7 @@ /* * Copyright (c) 2008, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 Joyent, Inc. */ #ifndef _SYS_SOCKET_PROTO_H_ @@ -202,7 +203,16 @@ struct sock_upcalls_s { void (*su_signal_oob)(sock_upper_handle_t, ssize_t); void (*su_zcopy_notify)(sock_upper_handle_t); void (*su_set_error)(sock_upper_handle_t, int); + /* + * NOTE: This function frees upper handle items. Caller cannot + * rely on them after this upcall. + */ void (*su_closed)(sock_upper_handle_t); + /* + * NOTE: This function MUST be implemented without using lower-level + * downcalls or accesses. This allows callers to ensure su_closed() + * upcalls can happen indepdently or concurrently. + */ vnode_t *(*su_get_vnode)(sock_upper_handle_t); }; diff --git a/usr/src/uts/common/sys/time.h b/usr/src/uts/common/sys/time.h index a69bf4dd63..f6cfa1a7e5 100644 --- a/usr/src/uts/common/sys/time.h +++ b/usr/src/uts/common/sys/time.h @@ -16,6 +16,8 @@ * * Copyright 2013 Nexenta Systems, Inc. All rights reserved. * Copyright 2016 Joyent, Inc. + * + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* @@ -365,14 +367,14 @@ extern todinfo_t utc_to_tod(time_t); extern time_t tod_to_utc(todinfo_t); extern int hr_clock_lock(void); extern void hr_clock_unlock(int); -extern hrtime_t gethrtime(void); -extern hrtime_t gethrtime_unscaled(void); +extern hrtime_t gethrtime(void); +extern hrtime_t gethrtime_unscaled(void); extern hrtime_t gethrtime_max(void); extern hrtime_t gethrtime_waitfree(void); extern void scalehrtime(hrtime_t *); extern uint64_t unscalehrtime(hrtime_t); -extern void gethrestime(timespec_t *); -extern time_t gethrestime_sec(void); +extern void gethrestime(timespec_t *); +extern time_t gethrestime_sec(void); extern void gethrestime_lasttick(timespec_t *); extern void hrt2ts(hrtime_t, timestruc_t *); extern hrtime_t ts2hrt(const timestruc_t *); @@ -408,6 +410,7 @@ int futimesat(int, const char *, const struct timeval *); int getitimer(int, struct itimerval *); int utimes(const char *, const struct timeval *); + #if defined(_XPG4_2) int setitimer(int, const struct itimerval *_RESTRICT_KYWD, struct itimerval *_RESTRICT_KYWD); @@ -418,6 +421,22 @@ int setitimer(int, struct itimerval *_RESTRICT_KYWD, #endif /* !defined(_KERNEL) ... defined(_XPG4_2) */ +#if !defined(_KERNEL) && !defined(_STRICT_SYMBOLS) +int futimes(int, const struct timeval *); +int lutimes(const char *, const struct timeval *); + +#define TIMESPEC_TO_TIMEVAL(tv, ts) { \ + (tv)->tv_sec = (ts)->tv_sec; \ + (tv)->tv_usec = (ts)->tv_nsec / 1000; \ +} + +#define TIMEVAL_TO_TIMESPEC(tv, ts) { \ + (ts)->tv_sec = (tv)->tv_sec; \ + (ts)->tv_nsec = (tv)->tv_usec * 1000; \ +} + +#endif /* !defined(_KERNEL) && !defined(_STRICT_SYMBOLS) */ + /* * gettimeofday() and settimeofday() were included in SVr4 due to their * common use in BSD based applications. They were to be included exactly |