From e0721d5ae1542c80097f6fcd487736fdfe601233 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Mon, 27 Jul 2020 00:00:34 +0300 Subject: 13003 console: multiple issues related to colors and font loading and switching Reviewed by: Robert Mustacchi Approved by: Dan McDonald --- usr/src/uts/common/Makefile.files | 2 +- usr/src/uts/common/io/tem.c | 78 ++++++++++++++++++++++++++------------- usr/src/uts/common/io/tem_safe.c | 19 +++++++++- usr/src/uts/common/sys/font.h | 8 ++-- 4 files changed, 75 insertions(+), 32 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index 39ee71dc58..4a44510cb8 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -1660,7 +1660,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) 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/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 { -- cgit v1.2.3 From e1447ca93391f31609bda487cb922dbff9dcdef5 Mon Sep 17 00:00:00 2001 From: Paul Winder Date: Fri, 24 Jul 2020 12:16:05 +0100 Subject: 12980 attempting to change MTU on mlxcx based aggregation can induce FMA event 12987 devo_power misconfigured in mlxcx 12988 potential hang in mlxcx when async and ring vectors end up on same CPU Reviewed by: Robert Mustacchi Reviewed by: Dan McDonald Reviewed by: Igor Kozhukhov Approved by: Garrett D'Amore --- usr/src/uts/common/io/mlxcx/mlxcx.c | 5 +-- usr/src/uts/common/io/mlxcx/mlxcx.h | 1 + usr/src/uts/common/io/mlxcx/mlxcx_cmd.c | 3 +- usr/src/uts/common/io/mlxcx/mlxcx_gld.c | 27 +++++++++---- usr/src/uts/common/io/mlxcx/mlxcx_intr.c | 66 +++++++++++++++++++++++++++++++- 5 files changed, 90 insertions(+), 12 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.c b/usr/src/uts/common/io/mlxcx/mlxcx.c index dbad9be958..6421b47126 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx.c @@ -1800,7 +1800,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 +2716,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; @@ -2913,7 +2913,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..dd91ea3734 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx.h +++ b/usr/src/uts/common/io/mlxcx/mlxcx.h @@ -1082,6 +1082,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 */ diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c index c8eb1335ea..3cb531df39 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; 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..10d8d19b2f 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx_intr.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx_intr.c @@ -922,6 +922,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 +1179,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,6 +1191,7 @@ 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) { @@ -1203,10 +1219,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 +1234,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 +1266,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 +1281,19 @@ mlxcx_intr_setup(mlxcx_t *mlxp) offsetof(mlxcx_completion_queue_t, mlcq_eq_entry)); } + ret = ddi_intr_set_pri(mlxp->mlx_intr_handles[0], + mlxp->mlx_async_intr_pri); + if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "Failed to set interrupt priority to %u for " + "async interrupt vector", mlxp->mlx_async_intr_pri); + 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 +1320,21 @@ mlxcx_intr_setup(mlxcx_t *mlxp) eqt = MLXCX_EQ_TYPE_RX; } + ret = ddi_intr_set_pri(mlxp->mlx_intr_handles[i], + mlxp->mlx_intr_pri); + if (ret != DDI_SUCCESS) { + mlxcx_warn(mlxp, "Failed to set interrupt priority to " + "%u for interrupt vector %d", mlxp->mlx_intr_pri, + 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); } -- cgit v1.2.3 From 7611ab7b771a068fbab94a90143de2afd495769f Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Mon, 24 Aug 2020 23:53:07 +0000 Subject: 13034 dnode_sync is careless with range tree Reviewed by: Matthew Ahrens Reviewed by: Brian Behlendorf Reviewed by: Igor Kozhukhov Reviewed by: Andrew Stormont Reviewed by: Jason King Approved by: Dan McDonald --- usr/src/uts/common/fs/zfs/dnode_sync.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'usr/src/uts/common') 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 @@ -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); -- cgit v1.2.3 From 526073d8a2a73617d29e806e575a271bc992905b Mon Sep 17 00:00:00 2001 From: Matt Barden Date: Mon, 8 Jun 2020 11:21:33 -0400 Subject: 13026 SMB and NFS use the global zone's IDMAP when they shouldn't Reviewed by: Robert Mustacchi Reviewed by: Gordon Ross Approved by: Dan McDonald --- usr/src/man/man9f/Makefile | 20 ++- usr/src/man/man9f/credentials.9f | 201 +++++++++++++++++++++++++ usr/src/pkg/manifests/system-kernel.man9f.inc | 10 +- usr/src/uts/common/fs/smbsrv/smb_idmap.c | 14 +- usr/src/uts/common/os/cred.c | 9 +- usr/src/uts/sun4u/chicago/io/fpc/fpc-impl-4u.c | 16 +- 6 files changed, 248 insertions(+), 22 deletions(-) create mode 100644 usr/src/man/man9f/credentials.9f (limited to 'usr/src/uts/common') diff --git a/usr/src/man/man9f/Makefile b/usr/src/man/man9f/Makefile index dec8aa99d7..4b4dd80396 100644 --- a/usr/src/man/man9f/Makefile +++ b/usr/src/man/man9f/Makefile @@ -13,7 +13,7 @@ # Copyright 2017, Richard Lowe # Copyright 2014 Garrett D'Amore # Copyright 2019 Joyent, Inc. -# Copyright 2016 Nexenta Systems, Inc. +# Copyright 2020 Nexenta by DDN, Inc. All rights reserved. # Copyright 2016 Hans Rosenfeld # @@ -70,6 +70,7 @@ MANFILES= ASSERT.9f \ copyin.9f \ copymsg.9f \ copyout.9f \ + credentials.9f \ csx_AccessConfigurationRegister.9f \ csx_CS_DDI_Info.9f \ csx_ConvertSize.9f \ @@ -556,6 +557,7 @@ MANFILES= ASSERT.9f \ MANLINKS= AVL_NEXT.9f \ AVL_PREV.9f \ + CRED.9f \ SIZEOF_PTR.9f \ SIZEOF_STRUCT.9f \ STRUCT_BUF.9f \ @@ -690,6 +692,9 @@ MANLINKS= AVL_NEXT.9f \ avl_remove.9f \ avl_swap.9f \ bcanputnext.9f \ + crdup.9f \ + crfree.9f \ + crget.9f \ crgetgid.9f \ crgetgroups.9f \ crgetngroups.9f \ @@ -699,6 +704,7 @@ MANLINKS= AVL_NEXT.9f \ crgetsuid.9f \ crgetuid.9f \ crgetzoneid.9f \ + crhold.9f \ csx_Get16.9f \ csx_Get32.9f \ csx_Get64.9f \ @@ -969,6 +975,7 @@ MANLINKS= AVL_NEXT.9f \ inl.9f \ intro.9f \ inw.9f \ + kcred.9f \ kmem_cache_alloc.9f \ kmem_cache_destroy.9f \ kmem_cache_free.9f \ @@ -1310,7 +1317,8 @@ MANLINKS= AVL_NEXT.9f \ vsprintf.9f \ vzcmn_err.9f \ wr.9f \ - zcmn_err.9f + zcmn_err.9f \ + zone_kcred.9f assert.9f := LINKSRC = ASSERT.9f @@ -1483,6 +1491,14 @@ cv_timedwait_sig.9f := LINKSRC = condvar.9f cv_wait.9f := LINKSRC = condvar.9f cv_wait_sig.9f := LINKSRC = condvar.9f +CRED.9f := LINKSRC = credentials.9f +crdup.9f := LINKSRC = credentials.9f +crfree.9f := LINKSRC = credentials.9f +crget.9f := LINKSRC = credentials.9f +crhold.9f := LINKSRC = credentials.9f +kcred.9f := LINKSRC = credentials.9f +zone_kcred.9f := LINKSRC = credentials.9f + csx_Get16.9f := LINKSRC = csx_Get8.9f csx_Get32.9f := LINKSRC = csx_Get8.9f csx_Get64.9f := LINKSRC = csx_Get8.9f diff --git a/usr/src/man/man9f/credentials.9f b/usr/src/man/man9f/credentials.9f new file mode 100644 index 0000000000..89d2138c95 --- /dev/null +++ b/usr/src/man/man9f/credentials.9f @@ -0,0 +1,201 @@ +.\" +.\" 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 Nexenta by DDN, Inc. All rights reserved. +.\" +.Dd Aug 21, 2020 +.Dt CREDENTIALS 9F +.Os +.Sh NAME +.Nm credentials , +.Nm CRED , +.Nm crdup , +.Nm crfree , +.Nm crget , +.Nm crhold , +.Nm kcred , +.Nm zone_kcred +.Nd Functions for obtaining credentials in the kernel +.Sh SYNOPSIS +.In sys/cred.h +.Ft "cred_t *" +.Fo CRED +.Fc +.Ft "cred_t *" +.Fo crdup +.Fa "cred_t *cr" +.Fc +.Ft "void" +.Fo crfree +.Fa "cred_t *cr" +.Fc +.Ft "cred_t *" +.Fo crget +.Fc +.Ft "void" +.Fo crhold +.Fa "cred_t *cr" +.Fc +.Ft "cred_t *" +.Fo zone_kcred +.Fc +.Vt cred_t *kcred +.Sh INTERFACE LEVEL +.Sy Volatile - +This interface is still evolving in illumos. +API and ABI stability is not guaranteed. +.Sh PARAMETERS +.Bl -tag -width Fa +.It Fa cr +pointer to the user credential structure. +.El +.Sh DESCRIPTION +Some kernel interfaces require a credential as an argument. +This page documents the credentials available in the system, +as well as interfaces for creating new credentials. +.Pp +Most users do not need to create new credentials. +Instead, users should generally use the credentials of the executing context. +.Pp +This interface is primarily intended for services that must perform operations +on behalf of multiple remotely authenticated users, whose authentication context +is unrelated to the context of the executing thread or process. +Drivers MUST NOT create new credentials. +Drivers should use the provided credential. +.Pp +For functions that do not return new credentials, +if the credentials will be used outside of their context +(i.e. if the output of zone_kcred() is referenced outside of the zone), +then one should use +.Fn crdup +or +.Fn crhold +to ensure that the credentials remain valid. +.Ss Fn CRED +The +.Fn CRED +function returns the credential of the calling thread. +Its contents depend on the calling context (user, kernel, interrupt). +.Ss Fn crdup +.Fn crdup +returns a newly-allocated copy of +.Fa cr +with reference count of 1. +It sleeps until the allocation succeeds. +.Ss Fn crfree +.Fn crfree +releases a reference to +.Fa cr . +If this is the last reference, the credential is destroyed. +.Ss Fn crhold +.Fn crhold +takes a reference to +.Fa cr . +.Ss Va kcred +.Va kcred +is the root credential of the global zone. +Its UIDs and GIDs are all 0. +It has the following privilege sets by default: +.Bd -literal -offset indent +E: basic,proc_secflags +I: basic,proc_secflags +P: basic,proc_secflags +L: all +.Ed +.Pp +.Dv NET_MAC_AWARE +is set in the credential's flags. +It is not marked privilege-aware. +.Pp +.Va kcred +will never be freed by the system. +.Ss Fn zone_kcred +The +.Fn zone_kcred +function returns the root credential of the zone to which the calling thread belongs. +This cred is derived from the global kcred, minus any privileges denied to the zone. +.Ss Fn crget +The +.Fn crget +function returns a copy of +.Fn zone_kcred +suitable for modification by the caller. +This is useful for obtaining a default, +well-initialized credential in the appropriate zone context, +that is free of privileges or limitations of the originating thread. +It must be freed with +.Fn crfree . +It sleeps until the allocation succeeds. +.Ss Considerations +.Va kcred +and +.Fn zone_kcred +are not privilege-aware, and have all IDs set to 0. +This causes their Limit set to be used in place of the Effective and Permitted sets, +which significantly expands their privileges. +.Pp +If the output of +.Fn crget +is not later marked as privilege aware, and its UID is not set to a non-zero value, +then its Limit set will be used in place of its Effective and Permitted sets, +significantly expanding its privileges. +Callers should either mark the credential as privilege-aware, +reduce the Limit set appropriately, +or ensure that they intend for zero-uid users to have expanded privileges. +.Pp +.Va kcred , +.Fn zone_kcred , +and +.Fn CRED +are not suitable for modfication by the caller. +Callers must use +.Fn crdup +to create a copy of these credentials that are suitable for modification. +.Pp +Callers of +.Fn zone_kcred +and +.Fn crget +must take care to ensure that the calling thread is +executing in the context of the appropriate zone. +If the thread is performing work on behalf of a different zone, +or if one is uncertain of the zone context of the calling thread, +then one should find the appropriate zone by other means, and reference +.Em zone->zone_kcred +explicitly. +.Sh CONTEXT +These functions can be called from +.Sy user +and +.Sy kernel +contexts. +.Sh RETURN VALUES +.Fn zone_kcred +and +.Fn CRED +return a pointer to a +.Vt cred_t +that should not be modified. +.Pp +.Fn crget +and +.Fn crdup +return a pointer to a newly allocated +.Vt cred_t . +.Pp +.Fn zone_kcred , +.Fn CRED , +.Fn crdup , +and +.Fn crget +can never fail, and always return a valid credential. +.Sh SEE ALSO +.Xr ddi_cred 9f diff --git a/usr/src/pkg/manifests/system-kernel.man9f.inc b/usr/src/pkg/manifests/system-kernel.man9f.inc index 5b3dc6d94e..78107ef373 100644 --- a/usr/src/pkg/manifests/system-kernel.man9f.inc +++ b/usr/src/pkg/manifests/system-kernel.man9f.inc @@ -12,7 +12,7 @@ # # Copyright 2017, Richard Lowe # Copyright 2014 Garrett D'Amore -# Copyright 2016 Nexenta Systems, Inc. +# Copyright 2020 Nexenta by DDN, Inc. All rights reserved. # Copyright 2016 Hans Rosenfeld # Copyright 2019 Joyent, Inc. # @@ -66,6 +66,7 @@ file path=usr/share/man/man9f/copyb.9f file path=usr/share/man/man9f/copyin.9f file path=usr/share/man/man9f/copymsg.9f file path=usr/share/man/man9f/copyout.9f +file path=usr/share/man/man9f/credentials.9f file path=usr/share/man/man9f/csx_AccessConfigurationRegister.9f file path=usr/share/man/man9f/csx_CS_DDI_Info.9f file path=usr/share/man/man9f/csx_ConvertSize.9f @@ -513,6 +514,7 @@ file path=usr/share/man/man9f/vmem_create.9f file path=usr/share/man/man9f/vmem_walk.9f link path=usr/share/man/man9f/AVL_NEXT.9f target=avl.9f link path=usr/share/man/man9f/AVL_PREV.9f target=avl.9f +link path=usr/share/man/man9f/CRED.9f target=credentials.9f link path=usr/share/man/man9f/SIZEOF_PTR.9f target=STRUCT_DECL.9f link path=usr/share/man/man9f/SIZEOF_STRUCT.9f target=STRUCT_DECL.9f link path=usr/share/man/man9f/STRUCT_BUF.9f target=STRUCT_DECL.9f @@ -647,6 +649,9 @@ link path=usr/share/man/man9f/avl_numnodes.9f target=avl.9f link path=usr/share/man/man9f/avl_remove.9f target=avl.9f link path=usr/share/man/man9f/avl_swap.9f target=avl.9f link path=usr/share/man/man9f/bcanputnext.9f target=canputnext.9f +link path=usr/share/man/man9f/crdup.9f target=credentials.9f +link path=usr/share/man/man9f/crfree.9f target=credentials.9f +link path=usr/share/man/man9f/crget.9f target=credentials.9f link path=usr/share/man/man9f/crgetgid.9f target=ddi_cred.9f link path=usr/share/man/man9f/crgetgroups.9f target=ddi_cred.9f link path=usr/share/man/man9f/crgetngroups.9f target=ddi_cred.9f @@ -656,6 +661,7 @@ link path=usr/share/man/man9f/crgetsgid.9f target=ddi_cred.9f link path=usr/share/man/man9f/crgetsuid.9f target=ddi_cred.9f link path=usr/share/man/man9f/crgetuid.9f target=ddi_cred.9f link path=usr/share/man/man9f/crgetzoneid.9f target=ddi_cred.9f +link path=usr/share/man/man9f/crhold.9f target=credentials.9f link path=usr/share/man/man9f/csx_Get16.9f target=csx_Get8.9f link path=usr/share/man/man9f/csx_Get32.9f target=csx_Get8.9f link path=usr/share/man/man9f/csx_Get64.9f target=csx_Get8.9f @@ -969,6 +975,7 @@ link path=usr/share/man/man9f/id_space_extend.9f target=id_space.9f link path=usr/share/man/man9f/inl.9f target=inb.9f link path=usr/share/man/man9f/intro.9f target=Intro.9f link path=usr/share/man/man9f/inw.9f target=inb.9f +link path=usr/share/man/man9f/kcred.9f target=credentials.9f link path=usr/share/man/man9f/kmem_cache_alloc.9f target=kmem_cache_create.9f link path=usr/share/man/man9f/kmem_cache_destroy.9f \ target=kmem_cache_create.9f @@ -1402,3 +1409,4 @@ link path=usr/share/man/man9f/vsprintf.9f target=sprintf.9f link path=usr/share/man/man9f/vzcmn_err.9f target=cmn_err.9f link path=usr/share/man/man9f/wr.9f target=WR.9f link path=usr/share/man/man9f/zcmn_err.9f target=cmn_err.9f +link path=usr/share/man/man9f/zone_kcred.9f target=credentials.9f 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/os/cred.c b/usr/src/uts/common/os/cred.c index 25727d54c5..3e1df330b7 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/sun4u/chicago/io/fpc/fpc-impl-4u.c b/usr/src/uts/sun4u/chicago/io/fpc/fpc-impl-4u.c index aa96f19079..a8ceea0344 100644 --- a/usr/src/uts/sun4u/chicago/io/fpc/fpc-impl-4u.c +++ b/usr/src/uts/sun4u/chicago/io/fpc/fpc-impl-4u.c @@ -24,6 +24,10 @@ * Use is subject to license terms. */ +/* + * Copyright 2020 Nexenta by DDN, Inc. All rights reserved. + */ + #include #include #include @@ -101,7 +105,6 @@ static uint64_t counter_reg_offsets[] = { static ldi_ident_t ldi_identifier; static boolean_t ldi_identifier_valid = B_FALSE; -static cred_t *credentials = NULL; /* Called by _init to determine if it is OK to install driver. */ int @@ -116,7 +119,6 @@ fpc_platform_module_init(dev_info_t *dip) { int status; - credentials = crget(); status = ldi_ident_from_dip(dip, &ldi_identifier); if (status == 0) ldi_identifier_valid = B_TRUE; @@ -211,8 +213,6 @@ fpc_platform_module_fini(dev_info_t *dip) { if (ldi_identifier_valid) ldi_ident_release(ldi_identifier); - if (credentials) - crfree(credentials); } fire_perfreg_handle_t @@ -226,7 +226,7 @@ fpc_get_perfreg_handle(int devnum) if ((handle_impl->devspec = fpc_get_platform_data_by_number(devnum)) != NULL) { rval = ldi_open_by_name(handle_impl->devspec->nodename, - OPEN_FLAGS, credentials, &handle_impl->devhandle, + OPEN_FLAGS, kcred, &handle_impl->devhandle, ldi_identifier); } @@ -243,7 +243,7 @@ fpc_free_counter_handle(fire_perfreg_handle_t handle) { fire_counter_handle_impl_t *handle_impl = (fire_counter_handle_impl_t *)handle; - (void) ldi_close(handle_impl->devhandle, OPEN_FLAGS, credentials); + (void) ldi_close(handle_impl->devhandle, OPEN_FLAGS, kcred); kmem_free(handle_impl, sizeof (fire_counter_handle_impl_t)); return (SUCCESS); } @@ -281,7 +281,7 @@ fpc_event_io(fire_perfreg_handle_t handle, fire_perfcnt_t group, /* Read original value. */ if (((rval = ldi_ioctl(handle_impl->devhandle, cmd, (intptr_t)&prg, - FKIOCTL, credentials, &ioctl_rval)) == SUCCESS) && (!is_write)) { + FKIOCTL, kcred, &ioctl_rval)) == SUCCESS) && (!is_write)) { *reg_data = prg.data; } @@ -322,7 +322,7 @@ fpc_counter_io(fire_perfreg_handle_t handle, fire_perfcnt_t group, prg.data = *value; if (((rval = ldi_ioctl(handle_impl->devhandle, command, (intptr_t)&prg, - FKIOCTL, credentials, &ioctl_rval)) == SUCCESS) && (!is_write)) { + FKIOCTL, kcred, &ioctl_rval)) == SUCCESS) && (!is_write)) { *value = prg.data; } -- cgit v1.2.3 From d11e14a72ad0bfccf84405261d5d93e6eaafe6a7 Mon Sep 17 00:00:00 2001 From: Matt Barden Date: Fri, 6 Mar 2020 15:11:38 -0500 Subject: 13047 SMB server is too strict about security descriptors Reviewed by: Dan McDonald Approved by: Robert Mustacchi --- .../uts/common/fs/smbsrv/smb2_fsctl_copychunk.c | 2 + usr/src/uts/common/fs/smbsrv/smb_fsops.c | 92 +++++++++++++--------- usr/src/uts/common/fs/smbsrv/smb_sd.c | 33 +++++--- 3 files changed, 78 insertions(+), 49 deletions(-) (limited to 'usr/src/uts/common') 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 @@ -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_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); } } -- cgit v1.2.3 From 1c8449e95a93a750df972545379490366b392934 Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Mon, 13 Mar 2017 23:10:42 +0000 Subject: 13084 tl_open should handle id_space exhaustion Reviewed by: Robert Mustacchi Reviewed by: Ryan Zezeski Reviewed by: Jerry Jelinek Reviewed by: Toomas Soome Reviewed by: Andrew Stormont Approved by: Robert Mustacchi --- usr/src/uts/common/io/tl.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/io/tl.c b/usr/src/uts/common/io/tl.c index c11af49b64..10466c22da 100644 --- a/usr/src/uts/common/io/tl.c +++ b/usr/src/uts/common/io/tl.c @@ -1484,8 +1484,9 @@ tl_closeok(tl_endpt_t *tep) static int tl_open(queue_t *rq, dev_t *devp, int oflag, int sflag, cred_t *credp) { - tl_endpt_t *tep; - minor_t minor = getminor(*devp); + tl_endpt_t *tep; + minor_t minor = getminor(*devp); + id_t inst_minor; /* * Driver is called directly. Both CLONEOPEN and MODOPEN @@ -1505,6 +1506,14 @@ tl_open(queue_t *rq, dev_t *devp, int oflag, int sflag, cred_t *credp) minor |= TL_SOCKET; } + /* + * Attempt to allocate a unique minor number for this instance. + * Avoid an uninterruptable sleep if none are available. + */ + if ((inst_minor = id_alloc_nosleep(tl_minors)) == -1) { + return (ENOMEM); + } + tep = kmem_cache_alloc(tl_cache, KM_SLEEP); tep->te_refcnt = 1; tep->te_cpid = curproc->p_pid; @@ -1516,9 +1525,7 @@ tl_open(queue_t *rq, dev_t *devp, int oflag, int sflag, cred_t *credp) tep->te_flag = minor & TL_MINOR_MASK; tep->te_transport = &tl_transports[minor]; - - /* Allocate a unique minor number for this instance. */ - tep->te_minor = (minor_t)id_alloc(tl_minors); + tep->te_minor = (minor_t)inst_minor; /* Reserve hash handle for bind(). */ (void) mod_hash_reserve(tep->te_addrhash, &tep->te_hash_hndl); -- cgit v1.2.3 From 2ad530425ac9cd3f429e64463a85f6f58703061c Mon Sep 17 00:00:00 2001 From: Dan McDonald Date: Thu, 13 Aug 2020 12:54:05 -0400 Subject: 12976 system panics with error in IP module Reviewed by: Andy Fiddaman Reviewed by: Paul Winder Approved by: Robert Mustacchi --- usr/src/uts/common/inet/ip/ipclassifier.c | 9 ++++++- usr/src/uts/common/inet/tcp/tcp.c | 40 +++++++++++++++++++++++++------ usr/src/uts/common/inet/tcp/tcp_output.c | 20 ++++++++++++---- usr/src/uts/common/sys/socket_proto.h | 10 ++++++++ 4 files changed, 67 insertions(+), 12 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/inet/ip/ipclassifier.c b/usr/src/uts/common/inet/ip/ipclassifier.c index 09cafcb4e7..26cc629cca 100644 --- a/usr/src/uts/common/inet/ip/ipclassifier.c +++ b/usr/src/uts/common/inet/ip/ipclassifier.c @@ -21,6 +21,7 @@ /* * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved. * Copyright 2019 OmniOS Community Edition (OmniOSce) Association. + * Copyright 2020 Joyent, Inc. */ /* @@ -2745,7 +2746,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) @@ -2757,6 +2762,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/tcp/tcp.c b/usr/src/uts/common/inet/tcp/tcp.c index eef7ded43a..6cae350878 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. */ @@ -1019,10 +1019,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); } } @@ -1421,13 +1434,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/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); }; -- cgit v1.2.3 From 4132743a134e253014b777399c8f8275cf71636c Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Wed, 1 Jan 2020 11:54:17 +0200 Subject: 12456 ipsec: variable may be used uninitialized Reviewed by: Dan McDonald Reviewed by: Jason King Approved by: Dan McDonald --- usr/src/uts/common/inet/ip/ipsecesp.c | 4 +++- usr/src/uts/common/inet/ip/sadb.c | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) (limited to 'usr/src/uts/common') 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 2792f1825c..dbdd97e6ce 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); -- cgit v1.2.3 From 88b8d9620aed414dab5fb34108dee58556f060f0 Mon Sep 17 00:00:00 2001 From: Patrick Mooney Date: Wed, 7 Sep 2016 01:03:12 +0000 Subject: 7709 hrt2ts and friends are too clever for their own good Reviewed by: Jerry Jelinek Reviewed by: Jason King Reviewed by: Toomas Soome Approved by: Richard Lowe --- usr/src/lib/libc/port/sys/time_util.c | 12 ++++++--- usr/src/uts/common/os/timers.c | 49 ++++++++++++++++++++++++++--------- 2 files changed, 45 insertions(+), 16 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/lib/libc/port/sys/time_util.c b/usr/src/lib/libc/port/sys/time_util.c index 93a07aaee0..b6ea0291e2 100644 --- a/usr/src/lib/libc/port/sys/time_util.c +++ b/usr/src/lib/libc/port/sys/time_util.c @@ -22,10 +22,9 @@ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2016 Joyent, Inc. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include #include #include @@ -39,6 +38,10 @@ void hrt2ts(hrtime_t hrt, timespec_t *tsp) { +#if defined(__amd64) + tsp->tv_sec = hrt / NANOSEC; + tsp->tv_nsec = hrt % NANOSEC; +#else uint32_t sec, nsec, tmp; tmp = (uint32_t)(hrt >> 30); @@ -60,6 +63,7 @@ hrt2ts(hrtime_t hrt, timespec_t *tsp) } tsp->tv_sec = (time_t)sec; tsp->tv_nsec = nsec; +#endif /* defined(__amd64) */ } /* @@ -67,8 +71,8 @@ hrt2ts(hrtime_t hrt, timespec_t *tsp) * All *timedwait() system call traps expect relative time. */ void -abstime_to_reltime(clockid_t clock_id, - const timespec_t *abstime, timespec_t *reltime) +abstime_to_reltime(clockid_t clock_id, const timespec_t *abstime, + timespec_t *reltime) { extern int __clock_gettime(clockid_t, timespec_t *); timespec_t now; diff --git a/usr/src/uts/common/os/timers.c b/usr/src/uts/common/os/timers.c index 61acc6cf97..53be806026 100644 --- a/usr/src/uts/common/os/timers.c +++ b/usr/src/uts/common/os/timers.c @@ -22,6 +22,7 @@ /* * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * Copyright 2016 Joyent, Inc. */ /* @@ -1172,6 +1173,14 @@ timespectohz64(timespec_t *tv) void hrt2ts(hrtime_t hrt, timestruc_t *tsp) { +#if defined(__amd64) + /* + * The cleverness explained above is unecessary on x86_64 CPUs where + * modern compilers are able to optimize down to faster operations. + */ + tsp->tv_sec = hrt / NANOSEC; + tsp->tv_nsec = hrt % NANOSEC; +#else uint32_t sec, nsec, tmp; tmp = (uint32_t)(hrt >> 30); @@ -1193,20 +1202,28 @@ hrt2ts(hrtime_t hrt, timestruc_t *tsp) } tsp->tv_sec = (time_t)sec; tsp->tv_nsec = nsec; +#endif /* defined(__amd64) */ } /* * Convert from timestruc_t to hrtime_t. - * - * The code below is equivalent to: - * - * hrt = tsp->tv_sec * NANOSEC + tsp->tv_nsec; - * - * but requires no integer multiply. */ hrtime_t ts2hrt(const timestruc_t *tsp) { +#if defined(__amd64) || defined(__i386) + /* + * On modern x86 CPUs, the simple version is faster. + */ + return ((tsp->tv_sec * NANOSEC) + tsp->tv_nsec); +#else + /* + * The code below is equivalent to: + * + * hrt = tsp->tv_sec * NANOSEC + tsp->tv_nsec; + * + * but requires no integer multiply. + */ hrtime_t hrt; hrt = tsp->tv_sec; @@ -1215,6 +1232,7 @@ ts2hrt(const timestruc_t *tsp) hrt = (hrt << 7) - hrt - hrt - hrt; hrt = (hrt << 9) + tsp->tv_nsec; return (hrt); +#endif /* defined(__amd64) || defined(__i386) */ } /* @@ -1246,6 +1264,13 @@ tv2hrt(struct timeval *tvp) void hrt2tv(hrtime_t hrt, struct timeval *tvp) { +#if defined(__amd64) + /* + * Like hrt2ts, the simple version is faster on x86_64. + */ + tvp->tv_sec = hrt / NANOSEC; + tvp->tv_usec = (hrt % NANOSEC) / (NANOSEC / MICROSEC); +#else uint32_t sec, nsec, tmp; uint32_t q, r, t; @@ -1267,17 +1292,17 @@ hrt2tv(hrtime_t hrt, struct timeval *tvp) sec++; } tvp->tv_sec = (time_t)sec; -/* - * this routine is very similar to hr2ts, but requires microseconds - * instead of nanoseconds, so an interger divide by 1000 routine - * completes the conversion - */ + /* + * this routine is very similar to hr2ts, but requires microseconds + * instead of nanoseconds, so an interger divide by 1000 routine + * completes the conversion + */ t = (nsec >> 7) + (nsec >> 8) + (nsec >> 12); q = (nsec >> 1) + t + (nsec >> 15) + (t >> 11) + (t >> 14); q = q >> 9; r = nsec - q*1000; tvp->tv_usec = q + ((r + 24) >> 10); - +#endif /* defined(__amd64) */ } int -- cgit v1.2.3 From 9b0881404678e5235132f9320785c3f5ce6e71f6 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Mon, 17 Feb 2020 12:31:13 +0200 Subject: 13087 zfs: zfs_ereport_post() and zfs_ereport_start() return values are ignored Reviewed by: C Fraire Reviewed by: Patrick Mooney Approved by: Robert Mustacchi --- usr/src/uts/common/fs/zfs/arc.c | 7 ++++--- usr/src/uts/common/fs/zfs/spa.c | 3 ++- usr/src/uts/common/fs/zfs/spa_config.c | 3 ++- usr/src/uts/common/fs/zfs/vdev.c | 7 ++++--- usr/src/uts/common/fs/zfs/vdev_indirect.c | 6 +++--- usr/src/uts/common/fs/zfs/vdev_raidz.c | 2 +- usr/src/uts/common/fs/zfs/zfs_fm.c | 2 +- usr/src/uts/common/fs/zfs/zio.c | 10 +++++----- 8 files changed, 22 insertions(+), 18 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/fs/zfs/arc.c b/usr/src/uts/common/fs/zfs/arc.c index c89b7a2505..48ae3aa829 100644 --- a/usr/src/uts/common/fs/zfs/arc.c +++ b/usr/src/uts/common/fs/zfs/arc.c @@ -2537,7 +2537,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); } @@ -5800,7 +5800,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); } } @@ -6057,7 +6058,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/spa.c b/usr/src/uts/common/fs/zfs/spa.c index 67c9784f75..21a8595b72 100644 --- a/usr/src/uts/common/fs/zfs/spa.c +++ b/usr/src/uts/common/fs/zfs/spa.c @@ -2391,7 +2391,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/zio.c b/usr/src/uts/common/fs/zfs/zio.c index cb27c250c6..a00e7ff850 100644 --- a/usr/src/uts/common/fs/zfs/zio.c +++ b/usr/src/uts/common/fs/zfs/zio.c @@ -480,7 +480,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 { @@ -1989,7 +1989,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); @@ -4259,7 +4259,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); } @@ -4274,7 +4274,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 & @@ -4285,7 +4285,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); } } -- cgit v1.2.3 From 712669c9fa9278704a4ccefe1d96acaf29397d36 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Wed, 2 Sep 2020 12:43:02 +0300 Subject: 13103 zfs: zvol_strategy() warn: unsigned 'off' is never less than zero Reviewed by: Robert Mustacchi Reviewed by: Igor Kozhukhov Approved by: Dan McDonald --- usr/src/uts/common/fs/zfs/zvol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/fs/zfs/zvol.c b/usr/src/uts/common/fs/zfs/zvol.c index 83dbf67e98..02eb0b8e1a 100644 --- a/usr/src/uts/common/fs/zfs/zvol.c +++ b/usr/src/uts/common/fs/zfs/zvol.c @@ -1226,7 +1226,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); -- cgit v1.2.3 From e4af2f17fac5babc25d094f1bf22dd06515f66c7 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Wed, 2 Sep 2020 12:21:37 +0300 Subject: 13104 zfs: offset_t is signed and can not be > MAXOFFSET_T Reviewed by: Robert Mustacchi Reviewed by: Igor Kozhukhov Approved by: Dan McDonald --- usr/src/uts/common/fs/zfs/zfs_vnops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/fs/zfs/zfs_vnops.c b/usr/src/uts/common/fs/zfs/zfs_vnops.c index 162c565c45..a4b5a17f73 100644 --- a/usr/src/uts/common/fs/zfs/zfs_vnops.c +++ b/usr/src/uts/common/fs/zfs/zfs_vnops.c @@ -4841,7 +4841,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); } /* -- cgit v1.2.3 From d061fa1f216e55ded9f2c41eb77f6aa67479a1c5 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Wed, 2 Sep 2020 14:26:13 +0300 Subject: 13105 dnode_special_open() error: unchecked function return 'zrl_tryenter' Reviewed by: Jason King Reviewed by: Robert Mustacchi Approved by: Dan McDonald --- usr/src/uts/common/fs/zfs/dnode.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'usr/src/uts/common') 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); -- cgit v1.2.3 From df8c2508aa717e719c0726c616d47f2c94a58dab Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Wed, 9 Sep 2020 22:30:42 -0700 Subject: 13119 Want support for SMBIOS 3.4 Change-Id: I88fd5a7e8f5b49b806f27d550bf49921b5fb8a28 --- usr/src/cmd/smbios/smbios.c | 22 +- usr/src/common/smbios/smb_info.c | 42 ++- usr/src/common/smbios/smb_open.c | 1 + usr/src/test/util-tests/tests/smbios/smbios.c | 19 +- usr/src/test/util-tests/tests/smbios/smbios_test.h | 5 + .../util-tests/tests/smbios/smbios_test_slot.c | 375 ++++++++++++++++++--- usr/src/uts/common/sys/smbios.h | 38 ++- usr/src/uts/common/sys/smbios_impl.h | 18 + 8 files changed, 466 insertions(+), 54 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/cmd/smbios/smbios.c b/usr/src/cmd/smbios/smbios.c index 5597e04fc5..dedfe29e9c 100644 --- a/usr/src/cmd/smbios/smbios.c +++ b/usr/src/cmd/smbios/smbios.c @@ -22,6 +22,7 @@ /* * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2017, Joyent, Inc. + * Copyright 2020 Oxide Computer Company * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -716,7 +717,7 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) oprintf(fp, " Slot Peer %u:\n", i); oprintf(fp, " Segment group: %u\n", peer[i].smblp_group); - oprintf(fp, " Bus/Device/Function: %u/%u/%u", + oprintf(fp, " Bus/Device/Function: %u/%u/%u\n", peer[i].smblp_bus, peer[i].smblp_device, peer[i].smblp_function); oprintf(fp, " Electrical width: %u\n", @@ -725,6 +726,25 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) smbios_info_slot_peers_free(shp, npeers, peer); } + + if (s.smbl_info != 0) { + if (s.smbl_type >= SMB_SLT_PCIE && + s.smbl_type <= SMB_SLT_PCIEG6P) { + oprintf(fp, " PCIe Generation: %d\n", s.smbl_info); + } else { + oprintf(fp, " Slot Type: 0x%x\n", s.smbl_info); + } + } + + if (s.smbl_pwidth != 0) { + desc_printf(smbios_slot_width_desc(s.smbl_pwidth), + fp, " Physical Width: 0x%x", s.smbl_pwidth); + } + + if (s.smbl_pitch != 0) { + oprintf(fp, " Slot Pitch: %u.%u mm\n", s.smbl_pitch / 100, + s.smbl_pitch % 100); + } } static void diff --git a/usr/src/common/smbios/smb_info.c b/usr/src/common/smbios/smb_info.c index 47c19e7fcb..9aba4deba8 100644 --- a/usr/src/common/smbios/smb_info.c +++ b/usr/src/common/smbios/smb_info.c @@ -22,6 +22,7 @@ /* * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2019 Joyent, Inc. + * Copyright 2020 Oxide Computer Company * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -231,14 +232,25 @@ smb_info_strptr(const smb_struct_t *stp, uint8_t off, int *n) return (smb_strptr(stp, 0)); } +static void +smb_info_bcopy_offset(const smb_header_t *hp, void *dst, size_t dstlen, + size_t offset) +{ + if (offset >= hp->smbh_len) { + bzero(dst, dstlen); + } else if (offset + dstlen > hp->smbh_len) { + size_t nvalid = MIN(hp->smbh_len - offset, dstlen); + bcopy((char *)hp + offset, dst, nvalid); + bzero((char *)dst + nvalid, dstlen - nvalid); + } else { + bcopy((char *)hp + offset, dst, dstlen); + } +} + static void smb_info_bcopy(const smb_header_t *hp, void *dst, size_t dstlen) { - if (dstlen > hp->smbh_len) { - bcopy(hp, dst, hp->smbh_len); - bzero((char *)dst + hp->smbh_len, dstlen - hp->smbh_len); - } else - bcopy(hp, dst, dstlen); + return (smb_info_bcopy_offset(hp, dst, dstlen, 0)); } smbios_entry_point_t @@ -674,6 +686,8 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp) { const smb_struct_t *stp = smb_lookup_id(shp, id); smb_slot_t s; + smb_slot_cont_t cont; + size_t off; if (stp == NULL) return (-1); /* errno is set for us */ @@ -701,6 +715,24 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp) sp->smbl_npeers = s.smbsl_npeers; } + if (!smb_libgteq(shp, SMB_VERSION_34)) { + return (0); + } + + /* + * In SMBIOS 3.4, several members were added to follow the variable + * number of peers. These are defined to start at byte 0x14 + 5 * + * npeers. If the table is from before 3.4, we simple zero things out. + * Otherwise we check if the length covers the peers and this addendum + * to include it as the table length is allowed to be less than this and + * not include it. + */ + off = SMB_SLOT_CONT_START + 5 * s.smbsl_npeers; + smb_info_bcopy_offset(stp->smbst_hdr, &cont, sizeof (cont), off); + sp->smbl_info = cont.smbsl_info; + sp->smbl_pwidth = cont.smbsl_pwidth; + sp->smbl_pitch = cont.smbsl_pitch; + return (0); } diff --git a/usr/src/common/smbios/smb_open.c b/usr/src/common/smbios/smb_open.c index 372b2b619b..6747c84499 100644 --- a/usr/src/common/smbios/smb_open.c +++ b/usr/src/common/smbios/smb_open.c @@ -231,6 +231,7 @@ smbios_bufopen(const smbios_entry_t *ep, const void *buf, size_t len, case SMB_VERSION_31: case SMB_VERSION_32: case SMB_VERSION_33: + case SMB_VERSION_34: break; default: return (smb_open_error(shp, errp, ESMB_VERSION)); diff --git a/usr/src/test/util-tests/tests/smbios/smbios.c b/usr/src/test/util-tests/tests/smbios/smbios.c index 364cb9344f..429d4f81be 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios.c +++ b/usr/src/test/util-tests/tests/smbios/smbios.c @@ -11,6 +11,7 @@ /* * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* @@ -219,7 +220,23 @@ static const smbios_test_t smbios_tests[] = { .st_mktable = smbios_test_slot_mktable, .st_canopen = B_TRUE, .st_verify = smbios_test_slot_verify, - .st_desc = "slot tests" + .st_desc = "slot 3.2" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION_34, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_slot_mktable_34_nopeers, + .st_canopen = B_TRUE, + .st_verify = smbios_test_slot_verify_34_nopeers, + .st_desc = "slot 3.4 without peers" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION_34, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_slot_mktable_34_peers, + .st_canopen = B_TRUE, + .st_verify = smbios_test_slot_verify_34_peers, + .st_desc = "slot 3.4 with peers" }, { .st_entry = SMBIOS_ENTRY_POINT_30, .st_tvers = SMB_VERSION, diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test.h b/usr/src/test/util-tests/tests/smbios/smbios_test.h index 62baed7813..c6490f1d13 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios_test.h +++ b/usr/src/test/util-tests/tests/smbios/smbios_test.h @@ -11,6 +11,7 @@ /* * Copyright 2019 Robert Mustacchi + * Copyright 2020 Oxide Computer Company */ #ifndef _SMBIOS_TEST_H @@ -78,7 +79,11 @@ typedef struct smbios_test { * Test functions */ extern boolean_t smbios_test_slot_mktable(smbios_test_table_t *); +extern boolean_t smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *); +extern boolean_t smbios_test_slot_mktable_34_peers(smbios_test_table_t *); extern boolean_t smbios_test_slot_verify(smbios_hdl_t *); +extern boolean_t smbios_test_slot_verify_34_nopeers(smbios_hdl_t *); +extern boolean_t smbios_test_slot_verify_34_peers(smbios_hdl_t *); extern boolean_t smbios_test_badvers_mktable(smbios_test_table_t *); extern boolean_t smbios_test_memdevice_mktable_32(smbios_test_table_t *); diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c b/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c index d84cc10e91..95a709a088 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c +++ b/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c @@ -11,6 +11,7 @@ /* * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* @@ -20,6 +21,29 @@ #include "smbios_test.h" static const char *smbios_test_name = "The One Slot"; +static uint8_t smbios_slot_bus = 0x42; +static uint8_t smbios_slot_df = 0x23; +static uint8_t smbios_slot_info = 0x65; +static uint16_t smbios_slot_pitch = 0x12af; + +static void +smbios_test_slot_fill(smb_slot_t *slot) +{ + bzero(slot, sizeof (smb_slot_t)); + slot->smbsl_hdr.smbh_type = SMB_TYPE_SLOT; + slot->smbsl_hdr.smbh_len = sizeof (smb_slot_t); + slot->smbsl_name = 1; + slot->smbsl_type = SMB_SLT_PCIE3G16; + slot->smbsl_width = SMB_SLW_16X; + slot->smbsl_length = SMB_SLL_SHORT; + slot->smbsl_id = htole16(1); + slot->smbsl_ch1 = SMB_SLCH1_33V; + slot->smbsl_ch2 = SMB_SLCH2_PME; + slot->smbsl_sg = htole16(1); + slot->smbsl_bus = smbios_slot_bus; + slot->smbsl_df = smbios_slot_df; + slot->smbsl_dbw = SMB_SLW_16X; +} boolean_t smbios_test_slot_mktable(smbios_test_table_t *table) @@ -28,21 +52,11 @@ smbios_test_slot_mktable(smbios_test_table_t *table) smb_slot_peer_t peers[2]; const uint8_t endstring = 0; - slot.smbsl_hdr.smbh_type = SMB_TYPE_SLOT; - slot.smbsl_hdr.smbh_len = sizeof (smb_slot_t) + sizeof (peers); - - slot.smbsl_name = 1; - slot.smbsl_type = SMB_SLT_PCIE3G16; - slot.smbsl_width = SMB_SLW_16X; - slot.smbsl_length = SMB_SLL_SHORT; - slot.smbsl_id = htole16(1); - slot.smbsl_ch1 = SMB_SLCH1_33V; - slot.smbsl_ch2 = SMB_SLCH2_PME; - slot.smbsl_sg = htole16(1); - slot.smbsl_bus = 0x42; - slot.smbsl_df = 0x23; - slot.smbsl_dbw = SMB_SLW_16X; + smbios_test_slot_fill(&slot); + + slot.smbsl_hdr.smbh_len += sizeof (peers); slot.smbsl_npeers = 2; + peers[0].smbspb_group_no = htole16(1); peers[0].smbspb_bus = 0x42; peers[0].smbspb_df = 0x42; @@ -64,6 +78,121 @@ smbios_test_slot_mktable(smbios_test_table_t *table) return (B_TRUE); } +/* + * 3.4 introduced additional data after peers. This verison constructs a variant + * with no peers. + */ +boolean_t +smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *table) +{ + smb_slot_t slot; + smb_slot_cont_t cont; + const uint8_t endstring = 0; + + smbios_test_slot_fill(&slot); + slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + sizeof (cont); + + cont.smbsl_info = smbios_slot_info; + cont.smbsl_pwidth = SMB_SLW_32X; + cont.smbsl_pitch = htole16(smbios_slot_pitch); + + (void) smbios_test_table_append(table, &slot, sizeof (slot)); + /* + * Append a raw zero to fill in the gaps that the peers would have had + * so the cont structure starts at the right offset. + */ + (void) smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + (void) smbios_test_table_append_raw(table, &cont, sizeof (cont)); + (void) smbios_test_table_append_string(table, smbios_test_name); + (void) smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + smbios_test_table_append_eot(table); + return (B_TRUE); +} + +boolean_t +smbios_test_slot_mktable_34_peers(smbios_test_table_t *table) +{ + smb_slot_t slot; + smb_slot_cont_t cont; + smb_slot_peer_t peers[1]; + const uint8_t endstring = 0; + + smbios_test_slot_fill(&slot); + slot.smbsl_npeers = 1; + slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + 5 * slot.smbsl_npeers + + sizeof (cont); + + peers[0].smbspb_group_no = htole16(1); + peers[0].smbspb_bus = 0x42; + peers[0].smbspb_df = 0x9a; + peers[0].smbspb_width = SMB_SLW_8X; + + cont.smbsl_info = smbios_slot_info; + cont.smbsl_pwidth = SMB_SLW_32X; + cont.smbsl_pitch = htole16(smbios_slot_pitch); + + (void) smbios_test_table_append(table, &slot, sizeof (slot)); + (void) smbios_test_table_append_raw(table, peers, sizeof (peers)); + (void) smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + (void) smbios_test_table_append_raw(table, &cont, sizeof (cont)); + (void) smbios_test_table_append_string(table, smbios_test_name); + (void) smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + smbios_test_table_append_eot(table); + return (B_TRUE); +} + + +static boolean_t +smbios_test_slot_common(smbios_slot_t *slot) +{ + uint_t errs = 0; + + if (strcmp(slot->smbl_name, smbios_test_name) != 0) { + warnx("slot name mismatch, expected %s, found %s", + smbios_test_name, slot->smbl_name); + errs++; + } + + if (slot->smbl_type != SMB_SLT_PCIE3G16) { + warnx("incorrect slot type, found %u", slot->smbl_type); + errs++; + } + + if (slot->smbl_width != SMB_SLW_16X) { + warnx("incorrect slot width, found %u", slot->smbl_width); + errs++; + } + + if (slot->smbl_length != SMB_SLL_SHORT) { + warnx("incorrect slot length, found %u", slot->smbl_length); + errs++; + } + + if (slot->smbl_dbw != SMB_SLW_16X) { + warnx("incorrect slot data bus width, found %u", + slot->smbl_dbw); + errs++; + } + + if (slot->smbl_bus != smbios_slot_bus) { + warnx("incorrect slot bus id, found 0x%x\n", slot->smbl_bus); + } + + if (slot->smbl_df != smbios_slot_df) { + warnx("incorrect slot df id, found 0x%x\n", slot->smbl_df); + } + + if (errs > 0) { + return (B_FALSE); + } + + return (B_TRUE); +} + boolean_t smbios_test_slot_verify(smbios_hdl_t *hdl) { @@ -85,32 +214,7 @@ smbios_test_slot_verify(smbios_hdl_t *hdl) return (B_FALSE); } - /* - * Verify everything we'd expect about the slot. - */ - if (strcmp(slot.smbl_name, smbios_test_name) != 0) { - warnx("slot name mismatch, expected %s, found %s", - smbios_test_name, slot.smbl_name); - errs++; - } - - if (slot.smbl_type != SMB_SLT_PCIE3G16) { - warnx("incorrect slot type, found %u", slot.smbl_type); - errs++; - } - - if (slot.smbl_width != SMB_SLW_16X) { - warnx("incorrect slot width, found %u", slot.smbl_width); - errs++; - } - - if (slot.smbl_length != SMB_SLL_SHORT) { - warnx("incorrect slot length, found %u", slot.smbl_length); - errs++; - } - - if (slot.smbl_dbw != SMB_SLW_16X) { - warnx("incorrect slot data bus width, found %u", slot.smbl_dbw); + if (!smbios_test_slot_common(&slot)) { errs++; } @@ -127,8 +231,7 @@ smbios_test_slot_verify(smbios_hdl_t *hdl) } if (npeers != 2) { - warnx("got wrong number of slot peers: %u\n", - npeers); + warnx("got wrong number of slot peers: %u", npeers); return (B_FALSE); } @@ -180,6 +283,194 @@ smbios_test_slot_verify(smbios_hdl_t *hdl) smbios_info_slot_peers_free(hdl, npeers, peers); + if (slot.smbl_info != 0) { + warnx("found wrong slot info: 0x%x", slot.smbl_info); + errs++; + } + + if (slot.smbl_pwidth != 0) { + warnx("found wrong slot physical width: 0x%x", + slot.smbl_pwidth); + errs++; + } + + if (slot.smbl_pitch != 0) { + warnx("found wrong slot pitch: 0x%x", slot.smbl_pitch); + errs++; + } + + if (errs > 0) { + return (B_FALSE); + } + + return (B_TRUE); +} + +boolean_t +smbios_test_slot_verify_34_nopeers(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_slot_t slot; + uint_t npeers; + smbios_slot_peer_t *peers; + uint_t errs = 0; + + if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) { + warnx("failed to lookup SMBIOS slot: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) { + warnx("failed to get SMBIOS slot info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (!smbios_test_slot_common(&slot)) { + errs++; + } + + if (slot.smbl_npeers != 0) { + warnx("incorrect number of slot peers, found %u", + slot.smbl_npeers); + errs++; + } + + if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) { + warnx("failed to get SMBIOS peer info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (npeers != 0) { + warnx("got wrong number of slot peers: %u", npeers); + errs++; + } + + if (peers != NULL) { + warnx("expected NULL peers pointer, but found %p", peers); + errs++; + } + + smbios_info_slot_peers_free(hdl, npeers, peers); + + if (slot.smbl_info != smbios_slot_info) { + warnx("found wrong slot info: 0x%x, expected 0x%x", + slot.smbl_info, smbios_slot_info); + errs++; + } + + if (slot.smbl_pwidth != SMB_SLW_32X) { + warnx("found wrong slot physical width: 0x%x, expected 0x%x", + slot.smbl_pwidth, SMB_SLW_32X); + errs++; + } + + if (slot.smbl_pitch != smbios_slot_pitch) { + warnx("found wrong slot pitch: 0x%x, expected 0x%x", + slot.smbl_pitch, smbios_slot_pitch); + errs++; + } + + if (errs > 0) { + return (B_FALSE); + } + + return (B_TRUE); +} + +boolean_t +smbios_test_slot_verify_34_peers(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_slot_t slot; + uint_t npeers; + smbios_slot_peer_t *peers; + uint_t errs = 0; + + if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) { + warnx("failed to lookup SMBIOS slot: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) { + warnx("failed to get SMBIOS slot info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (!smbios_test_slot_common(&slot)) { + errs++; + } + + if (slot.smbl_npeers != 1) { + warnx("incorrect number of slot peers, found %u", + slot.smbl_npeers); + errs++; + } + + if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) { + warnx("failed to get SMBIOS peer info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (npeers != 1) { + warnx("got wrong number of slot peers: %u", npeers); + errs++; + } + + if (peers[0].smblp_group != 1) { + warnx("incorrect group for peer 0: %u", peers[0].smblp_group); + errs++; + } + + if (peers[0].smblp_data_width != SMB_SLW_8X) { + warnx("incorrect data width for peer 0: %u", + peers[0].smblp_data_width); + errs++; + } + + if (peers[0].smblp_bus != 0x42) { + warnx("incorrect PCI bus for peer 0: %u", + peers[0].smblp_bus); + errs++; + } + + if (peers[0].smblp_device != (0x9a >> 3)) { + warnx("incorrect PCI device for peer 0: %u", + peers[0].smblp_device); + errs++; + } + + if (peers[0].smblp_function != (0x9a & 0x7)) { + warnx("incorrect PCI function for peer 0: %u", + peers[0].smblp_function); + errs++; + } + + smbios_info_slot_peers_free(hdl, npeers, peers); + + if (slot.smbl_info != smbios_slot_info) { + warnx("found wrong slot info: 0x%x, expected 0x%x", + slot.smbl_info, smbios_slot_info); + errs++; + } + + if (slot.smbl_pwidth != SMB_SLW_32X) { + warnx("found wrong slot physical width: 0x%x, expected 0x%x", + slot.smbl_pwidth, SMB_SLW_32X); + errs++; + } + + if (slot.smbl_pitch != smbios_slot_pitch) { + warnx("found wrong slot pitch: 0x%x, expected 0x%x", + slot.smbl_pitch, smbios_slot_pitch); + errs++; + } + if (errs > 0) { return (B_FALSE); } diff --git a/usr/src/uts/common/sys/smbios.h b/usr/src/uts/common/sys/smbios.h index 55048d549d..debe1fe72d 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,8 +251,25 @@ 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. */ -- cgit v1.2.3 From 374fc6954a786a037fbb28b1cd6fd62d05d13a37 Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Thu, 10 Sep 2020 08:38:39 -0700 Subject: backout: 13119, 13121 (mistaken integration) --- usr/src/cmd/mdb/intel/amd64/Makefile | 2 +- usr/src/cmd/mdb/intel/amd64/libsmbios/Makefile | 27 -- usr/src/cmd/mdb/intel/ia32/Makefile | 2 +- usr/src/cmd/mdb/intel/ia32/libsmbios/Makefile | 26 -- usr/src/cmd/mdb/intel/modules/smbios/smbios.c | 2 +- usr/src/cmd/smbios/smbios.c | 22 +- usr/src/common/smbios/smb_info.c | 42 +-- usr/src/common/smbios/smb_open.c | 1 - usr/src/pkg/manifests/developer-debug-mdb.mf | 3 - usr/src/test/util-tests/tests/smbios/smbios.c | 19 +- usr/src/test/util-tests/tests/smbios/smbios_test.h | 5 - .../util-tests/tests/smbios/smbios_test_slot.c | 375 +++------------------ usr/src/uts/common/sys/smbios.h | 38 +-- usr/src/uts/common/sys/smbios_impl.h | 18 - 14 files changed, 57 insertions(+), 525 deletions(-) delete mode 100644 usr/src/cmd/mdb/intel/amd64/libsmbios/Makefile delete mode 100644 usr/src/cmd/mdb/intel/ia32/libsmbios/Makefile (limited to 'usr/src/uts/common') diff --git a/usr/src/cmd/mdb/intel/amd64/Makefile b/usr/src/cmd/mdb/intel/amd64/Makefile index 39d3574f15..6ddc6b59d5 100644 --- a/usr/src/cmd/mdb/intel/amd64/Makefile +++ b/usr/src/cmd/mdb/intel/amd64/Makefile @@ -27,7 +27,7 @@ include ../../Makefile.common MODULES = $(COMMON_MODULES_PROC) $(COMMON_MODULES_KVM) -MODULES += disk_label uhci libsmbios +MODULES += disk_label uhci SUBDIRS = mdb mdb_ks kmdb libstandctf libstand .WAIT $(MODULES) diff --git a/usr/src/cmd/mdb/intel/amd64/libsmbios/Makefile b/usr/src/cmd/mdb/intel/amd64/libsmbios/Makefile deleted file mode 100644 index a04ca7df17..0000000000 --- a/usr/src/cmd/mdb/intel/amd64/libsmbios/Makefile +++ /dev/null @@ -1,27 +0,0 @@ -# -# 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 -# - -MODULE = libsmbios.so -MDBTGT = proc - -MODSRCS = smbios.c - -include ../../../../Makefile.cmd -include ../../../../Makefile.cmd.64 -include ../../Makefile.amd64 -include ../../../Makefile.module - -MODSRCS_DIR = ../../modules/smbios -LDLIBS += -lsmbios diff --git a/usr/src/cmd/mdb/intel/ia32/Makefile b/usr/src/cmd/mdb/intel/ia32/Makefile index 9d8f9efe87..cb544a52d2 100644 --- a/usr/src/cmd/mdb/intel/ia32/Makefile +++ b/usr/src/cmd/mdb/intel/ia32/Makefile @@ -28,7 +28,7 @@ include ../../Makefile.common MODULES = $(COMMON_MODULES_PROC) $(COMMON_MODULES_PROC_32BIT) -MODULES += disk_label libsmbios +MODULES += disk_label SUBDIRS = mdb .WAIT $(MODULES) diff --git a/usr/src/cmd/mdb/intel/ia32/libsmbios/Makefile b/usr/src/cmd/mdb/intel/ia32/libsmbios/Makefile deleted file mode 100644 index 14491786c2..0000000000 --- a/usr/src/cmd/mdb/intel/ia32/libsmbios/Makefile +++ /dev/null @@ -1,26 +0,0 @@ -# -# 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 -# - -MODULE = libsmbios.so -MDBTGT = proc - -MODSRCS = smbios.c - -include ../../../../Makefile.cmd -include ../../Makefile.ia32 -include ../../../Makefile.module - -MODSRCS_DIR = ../../modules/smbios -LDLIBS += -lsmbios diff --git a/usr/src/cmd/mdb/intel/modules/smbios/smbios.c b/usr/src/cmd/mdb/intel/modules/smbios/smbios.c index 1b692d45b1..429a5fba0e 100644 --- a/usr/src/cmd/mdb/intel/modules/smbios/smbios.c +++ b/usr/src/cmd/mdb/intel/modules/smbios/smbios.c @@ -28,7 +28,7 @@ * _KERNEL. Therefore we have to manually declare an extern delaration for * strerror(). */ -extern char *strerror(int); +extern const char *strerror(int); /* * Take an existing smbios_hdl_t from a dump and slurp out its memory so we can diff --git a/usr/src/cmd/smbios/smbios.c b/usr/src/cmd/smbios/smbios.c index dedfe29e9c..5597e04fc5 100644 --- a/usr/src/cmd/smbios/smbios.c +++ b/usr/src/cmd/smbios/smbios.c @@ -22,7 +22,6 @@ /* * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2017, Joyent, Inc. - * Copyright 2020 Oxide Computer Company * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -717,7 +716,7 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) oprintf(fp, " Slot Peer %u:\n", i); oprintf(fp, " Segment group: %u\n", peer[i].smblp_group); - oprintf(fp, " Bus/Device/Function: %u/%u/%u\n", + oprintf(fp, " Bus/Device/Function: %u/%u/%u", peer[i].smblp_bus, peer[i].smblp_device, peer[i].smblp_function); oprintf(fp, " Electrical width: %u\n", @@ -726,25 +725,6 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) smbios_info_slot_peers_free(shp, npeers, peer); } - - if (s.smbl_info != 0) { - if (s.smbl_type >= SMB_SLT_PCIE && - s.smbl_type <= SMB_SLT_PCIEG6P) { - oprintf(fp, " PCIe Generation: %d\n", s.smbl_info); - } else { - oprintf(fp, " Slot Type: 0x%x\n", s.smbl_info); - } - } - - if (s.smbl_pwidth != 0) { - desc_printf(smbios_slot_width_desc(s.smbl_pwidth), - fp, " Physical Width: 0x%x", s.smbl_pwidth); - } - - if (s.smbl_pitch != 0) { - oprintf(fp, " Slot Pitch: %u.%u mm\n", s.smbl_pitch / 100, - s.smbl_pitch % 100); - } } static void diff --git a/usr/src/common/smbios/smb_info.c b/usr/src/common/smbios/smb_info.c index 9aba4deba8..47c19e7fcb 100644 --- a/usr/src/common/smbios/smb_info.c +++ b/usr/src/common/smbios/smb_info.c @@ -22,7 +22,6 @@ /* * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2019 Joyent, Inc. - * Copyright 2020 Oxide Computer Company * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -232,25 +231,14 @@ smb_info_strptr(const smb_struct_t *stp, uint8_t off, int *n) return (smb_strptr(stp, 0)); } -static void -smb_info_bcopy_offset(const smb_header_t *hp, void *dst, size_t dstlen, - size_t offset) -{ - if (offset >= hp->smbh_len) { - bzero(dst, dstlen); - } else if (offset + dstlen > hp->smbh_len) { - size_t nvalid = MIN(hp->smbh_len - offset, dstlen); - bcopy((char *)hp + offset, dst, nvalid); - bzero((char *)dst + nvalid, dstlen - nvalid); - } else { - bcopy((char *)hp + offset, dst, dstlen); - } -} - static void smb_info_bcopy(const smb_header_t *hp, void *dst, size_t dstlen) { - return (smb_info_bcopy_offset(hp, dst, dstlen, 0)); + if (dstlen > hp->smbh_len) { + bcopy(hp, dst, hp->smbh_len); + bzero((char *)dst + hp->smbh_len, dstlen - hp->smbh_len); + } else + bcopy(hp, dst, dstlen); } smbios_entry_point_t @@ -686,8 +674,6 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp) { const smb_struct_t *stp = smb_lookup_id(shp, id); smb_slot_t s; - smb_slot_cont_t cont; - size_t off; if (stp == NULL) return (-1); /* errno is set for us */ @@ -715,24 +701,6 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp) sp->smbl_npeers = s.smbsl_npeers; } - if (!smb_libgteq(shp, SMB_VERSION_34)) { - return (0); - } - - /* - * In SMBIOS 3.4, several members were added to follow the variable - * number of peers. These are defined to start at byte 0x14 + 5 * - * npeers. If the table is from before 3.4, we simple zero things out. - * Otherwise we check if the length covers the peers and this addendum - * to include it as the table length is allowed to be less than this and - * not include it. - */ - off = SMB_SLOT_CONT_START + 5 * s.smbsl_npeers; - smb_info_bcopy_offset(stp->smbst_hdr, &cont, sizeof (cont), off); - sp->smbl_info = cont.smbsl_info; - sp->smbl_pwidth = cont.smbsl_pwidth; - sp->smbl_pitch = cont.smbsl_pitch; - return (0); } diff --git a/usr/src/common/smbios/smb_open.c b/usr/src/common/smbios/smb_open.c index 6747c84499..372b2b619b 100644 --- a/usr/src/common/smbios/smb_open.c +++ b/usr/src/common/smbios/smb_open.c @@ -231,7 +231,6 @@ smbios_bufopen(const smbios_entry_t *ep, const void *buf, size_t len, case SMB_VERSION_31: case SMB_VERSION_32: case SMB_VERSION_33: - case SMB_VERSION_34: break; default: return (smb_open_error(shp, errp, ESMB_VERSION)); diff --git a/usr/src/pkg/manifests/developer-debug-mdb.mf b/usr/src/pkg/manifests/developer-debug-mdb.mf index 63c7982c3c..af99982b2c 100644 --- a/usr/src/pkg/manifests/developer-debug-mdb.mf +++ b/usr/src/pkg/manifests/developer-debug-mdb.mf @@ -216,8 +216,6 @@ file path=usr/lib/mdb/proc/$(ARCH64)/libnvpair.so group=sys mode=0555 file path=usr/lib/mdb/proc/$(ARCH64)/libproc.so group=sys mode=0555 file path=usr/lib/mdb/proc/$(ARCH64)/libpython$(PYTHON_VERSION).so group=sys \ mode=0555 -$(i386_ONLY)file path=usr/lib/mdb/proc/$(ARCH64)/libsmbios.so group=sys \ - mode=0555 file path=usr/lib/mdb/proc/$(ARCH64)/libsysevent.so group=sys mode=0555 file path=usr/lib/mdb/proc/$(ARCH64)/libtopo.so group=sys mode=0555 file path=usr/lib/mdb/proc/$(ARCH64)/libumem.so group=sys mode=0555 @@ -232,7 +230,6 @@ file path=usr/lib/mdb/proc/libcmdutils.so group=sys mode=0555 file path=usr/lib/mdb/proc/libnvpair.so group=sys mode=0555 file path=usr/lib/mdb/proc/libproc.so group=sys mode=0555 file path=usr/lib/mdb/proc/libpython$(PYTHON_VERSION).so group=sys mode=0555 -$(i386_ONLY)file path=usr/lib/mdb/proc/libsmbios.so group=sys mode=0555 file path=usr/lib/mdb/proc/libsysevent.so group=sys mode=0555 file path=usr/lib/mdb/proc/libtopo.so group=sys mode=0555 file path=usr/lib/mdb/proc/libumem.so group=sys mode=0555 diff --git a/usr/src/test/util-tests/tests/smbios/smbios.c b/usr/src/test/util-tests/tests/smbios/smbios.c index 429d4f81be..364cb9344f 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios.c +++ b/usr/src/test/util-tests/tests/smbios/smbios.c @@ -11,7 +11,6 @@ /* * Copyright (c) 2018, Joyent, Inc. - * Copyright 2020 Oxide Computer Company */ /* @@ -220,23 +219,7 @@ static const smbios_test_t smbios_tests[] = { .st_mktable = smbios_test_slot_mktable, .st_canopen = B_TRUE, .st_verify = smbios_test_slot_verify, - .st_desc = "slot 3.2" - }, { - .st_entry = SMBIOS_ENTRY_POINT_30, - .st_tvers = SMB_VERSION_34, - .st_libvers = SMB_VERSION, - .st_mktable = smbios_test_slot_mktable_34_nopeers, - .st_canopen = B_TRUE, - .st_verify = smbios_test_slot_verify_34_nopeers, - .st_desc = "slot 3.4 without peers" - }, { - .st_entry = SMBIOS_ENTRY_POINT_30, - .st_tvers = SMB_VERSION_34, - .st_libvers = SMB_VERSION, - .st_mktable = smbios_test_slot_mktable_34_peers, - .st_canopen = B_TRUE, - .st_verify = smbios_test_slot_verify_34_peers, - .st_desc = "slot 3.4 with peers" + .st_desc = "slot tests" }, { .st_entry = SMBIOS_ENTRY_POINT_30, .st_tvers = SMB_VERSION, diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test.h b/usr/src/test/util-tests/tests/smbios/smbios_test.h index c6490f1d13..62baed7813 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios_test.h +++ b/usr/src/test/util-tests/tests/smbios/smbios_test.h @@ -11,7 +11,6 @@ /* * Copyright 2019 Robert Mustacchi - * Copyright 2020 Oxide Computer Company */ #ifndef _SMBIOS_TEST_H @@ -79,11 +78,7 @@ typedef struct smbios_test { * Test functions */ extern boolean_t smbios_test_slot_mktable(smbios_test_table_t *); -extern boolean_t smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *); -extern boolean_t smbios_test_slot_mktable_34_peers(smbios_test_table_t *); extern boolean_t smbios_test_slot_verify(smbios_hdl_t *); -extern boolean_t smbios_test_slot_verify_34_nopeers(smbios_hdl_t *); -extern boolean_t smbios_test_slot_verify_34_peers(smbios_hdl_t *); extern boolean_t smbios_test_badvers_mktable(smbios_test_table_t *); extern boolean_t smbios_test_memdevice_mktable_32(smbios_test_table_t *); diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c b/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c index 95a709a088..d84cc10e91 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c +++ b/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c @@ -11,7 +11,6 @@ /* * Copyright (c) 2018, Joyent, Inc. - * Copyright 2020 Oxide Computer Company */ /* @@ -21,29 +20,6 @@ #include "smbios_test.h" static const char *smbios_test_name = "The One Slot"; -static uint8_t smbios_slot_bus = 0x42; -static uint8_t smbios_slot_df = 0x23; -static uint8_t smbios_slot_info = 0x65; -static uint16_t smbios_slot_pitch = 0x12af; - -static void -smbios_test_slot_fill(smb_slot_t *slot) -{ - bzero(slot, sizeof (smb_slot_t)); - slot->smbsl_hdr.smbh_type = SMB_TYPE_SLOT; - slot->smbsl_hdr.smbh_len = sizeof (smb_slot_t); - slot->smbsl_name = 1; - slot->smbsl_type = SMB_SLT_PCIE3G16; - slot->smbsl_width = SMB_SLW_16X; - slot->smbsl_length = SMB_SLL_SHORT; - slot->smbsl_id = htole16(1); - slot->smbsl_ch1 = SMB_SLCH1_33V; - slot->smbsl_ch2 = SMB_SLCH2_PME; - slot->smbsl_sg = htole16(1); - slot->smbsl_bus = smbios_slot_bus; - slot->smbsl_df = smbios_slot_df; - slot->smbsl_dbw = SMB_SLW_16X; -} boolean_t smbios_test_slot_mktable(smbios_test_table_t *table) @@ -52,11 +28,21 @@ smbios_test_slot_mktable(smbios_test_table_t *table) smb_slot_peer_t peers[2]; const uint8_t endstring = 0; - smbios_test_slot_fill(&slot); - - slot.smbsl_hdr.smbh_len += sizeof (peers); + slot.smbsl_hdr.smbh_type = SMB_TYPE_SLOT; + slot.smbsl_hdr.smbh_len = sizeof (smb_slot_t) + sizeof (peers); + + slot.smbsl_name = 1; + slot.smbsl_type = SMB_SLT_PCIE3G16; + slot.smbsl_width = SMB_SLW_16X; + slot.smbsl_length = SMB_SLL_SHORT; + slot.smbsl_id = htole16(1); + slot.smbsl_ch1 = SMB_SLCH1_33V; + slot.smbsl_ch2 = SMB_SLCH2_PME; + slot.smbsl_sg = htole16(1); + slot.smbsl_bus = 0x42; + slot.smbsl_df = 0x23; + slot.smbsl_dbw = SMB_SLW_16X; slot.smbsl_npeers = 2; - peers[0].smbspb_group_no = htole16(1); peers[0].smbspb_bus = 0x42; peers[0].smbspb_df = 0x42; @@ -78,121 +64,6 @@ smbios_test_slot_mktable(smbios_test_table_t *table) return (B_TRUE); } -/* - * 3.4 introduced additional data after peers. This verison constructs a variant - * with no peers. - */ -boolean_t -smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *table) -{ - smb_slot_t slot; - smb_slot_cont_t cont; - const uint8_t endstring = 0; - - smbios_test_slot_fill(&slot); - slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + sizeof (cont); - - cont.smbsl_info = smbios_slot_info; - cont.smbsl_pwidth = SMB_SLW_32X; - cont.smbsl_pitch = htole16(smbios_slot_pitch); - - (void) smbios_test_table_append(table, &slot, sizeof (slot)); - /* - * Append a raw zero to fill in the gaps that the peers would have had - * so the cont structure starts at the right offset. - */ - (void) smbios_test_table_append_raw(table, &endstring, - sizeof (endstring)); - (void) smbios_test_table_append_raw(table, &cont, sizeof (cont)); - (void) smbios_test_table_append_string(table, smbios_test_name); - (void) smbios_test_table_append_raw(table, &endstring, - sizeof (endstring)); - smbios_test_table_append_eot(table); - return (B_TRUE); -} - -boolean_t -smbios_test_slot_mktable_34_peers(smbios_test_table_t *table) -{ - smb_slot_t slot; - smb_slot_cont_t cont; - smb_slot_peer_t peers[1]; - const uint8_t endstring = 0; - - smbios_test_slot_fill(&slot); - slot.smbsl_npeers = 1; - slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + 5 * slot.smbsl_npeers + - sizeof (cont); - - peers[0].smbspb_group_no = htole16(1); - peers[0].smbspb_bus = 0x42; - peers[0].smbspb_df = 0x9a; - peers[0].smbspb_width = SMB_SLW_8X; - - cont.smbsl_info = smbios_slot_info; - cont.smbsl_pwidth = SMB_SLW_32X; - cont.smbsl_pitch = htole16(smbios_slot_pitch); - - (void) smbios_test_table_append(table, &slot, sizeof (slot)); - (void) smbios_test_table_append_raw(table, peers, sizeof (peers)); - (void) smbios_test_table_append_raw(table, &endstring, - sizeof (endstring)); - (void) smbios_test_table_append_raw(table, &cont, sizeof (cont)); - (void) smbios_test_table_append_string(table, smbios_test_name); - (void) smbios_test_table_append_raw(table, &endstring, - sizeof (endstring)); - smbios_test_table_append_eot(table); - return (B_TRUE); -} - - -static boolean_t -smbios_test_slot_common(smbios_slot_t *slot) -{ - uint_t errs = 0; - - if (strcmp(slot->smbl_name, smbios_test_name) != 0) { - warnx("slot name mismatch, expected %s, found %s", - smbios_test_name, slot->smbl_name); - errs++; - } - - if (slot->smbl_type != SMB_SLT_PCIE3G16) { - warnx("incorrect slot type, found %u", slot->smbl_type); - errs++; - } - - if (slot->smbl_width != SMB_SLW_16X) { - warnx("incorrect slot width, found %u", slot->smbl_width); - errs++; - } - - if (slot->smbl_length != SMB_SLL_SHORT) { - warnx("incorrect slot length, found %u", slot->smbl_length); - errs++; - } - - if (slot->smbl_dbw != SMB_SLW_16X) { - warnx("incorrect slot data bus width, found %u", - slot->smbl_dbw); - errs++; - } - - if (slot->smbl_bus != smbios_slot_bus) { - warnx("incorrect slot bus id, found 0x%x\n", slot->smbl_bus); - } - - if (slot->smbl_df != smbios_slot_df) { - warnx("incorrect slot df id, found 0x%x\n", slot->smbl_df); - } - - if (errs > 0) { - return (B_FALSE); - } - - return (B_TRUE); -} - boolean_t smbios_test_slot_verify(smbios_hdl_t *hdl) { @@ -214,7 +85,32 @@ smbios_test_slot_verify(smbios_hdl_t *hdl) return (B_FALSE); } - if (!smbios_test_slot_common(&slot)) { + /* + * Verify everything we'd expect about the slot. + */ + if (strcmp(slot.smbl_name, smbios_test_name) != 0) { + warnx("slot name mismatch, expected %s, found %s", + smbios_test_name, slot.smbl_name); + errs++; + } + + if (slot.smbl_type != SMB_SLT_PCIE3G16) { + warnx("incorrect slot type, found %u", slot.smbl_type); + errs++; + } + + if (slot.smbl_width != SMB_SLW_16X) { + warnx("incorrect slot width, found %u", slot.smbl_width); + errs++; + } + + if (slot.smbl_length != SMB_SLL_SHORT) { + warnx("incorrect slot length, found %u", slot.smbl_length); + errs++; + } + + if (slot.smbl_dbw != SMB_SLW_16X) { + warnx("incorrect slot data bus width, found %u", slot.smbl_dbw); errs++; } @@ -231,7 +127,8 @@ smbios_test_slot_verify(smbios_hdl_t *hdl) } if (npeers != 2) { - warnx("got wrong number of slot peers: %u", npeers); + warnx("got wrong number of slot peers: %u\n", + npeers); return (B_FALSE); } @@ -283,194 +180,6 @@ smbios_test_slot_verify(smbios_hdl_t *hdl) smbios_info_slot_peers_free(hdl, npeers, peers); - if (slot.smbl_info != 0) { - warnx("found wrong slot info: 0x%x", slot.smbl_info); - errs++; - } - - if (slot.smbl_pwidth != 0) { - warnx("found wrong slot physical width: 0x%x", - slot.smbl_pwidth); - errs++; - } - - if (slot.smbl_pitch != 0) { - warnx("found wrong slot pitch: 0x%x", slot.smbl_pitch); - errs++; - } - - if (errs > 0) { - return (B_FALSE); - } - - return (B_TRUE); -} - -boolean_t -smbios_test_slot_verify_34_nopeers(smbios_hdl_t *hdl) -{ - smbios_struct_t sp; - smbios_slot_t slot; - uint_t npeers; - smbios_slot_peer_t *peers; - uint_t errs = 0; - - if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) { - warnx("failed to lookup SMBIOS slot: %s", - smbios_errmsg(smbios_errno(hdl))); - return (B_FALSE); - } - - if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) { - warnx("failed to get SMBIOS slot info: %s", - smbios_errmsg(smbios_errno(hdl))); - return (B_FALSE); - } - - if (!smbios_test_slot_common(&slot)) { - errs++; - } - - if (slot.smbl_npeers != 0) { - warnx("incorrect number of slot peers, found %u", - slot.smbl_npeers); - errs++; - } - - if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) { - warnx("failed to get SMBIOS peer info: %s", - smbios_errmsg(smbios_errno(hdl))); - return (B_FALSE); - } - - if (npeers != 0) { - warnx("got wrong number of slot peers: %u", npeers); - errs++; - } - - if (peers != NULL) { - warnx("expected NULL peers pointer, but found %p", peers); - errs++; - } - - smbios_info_slot_peers_free(hdl, npeers, peers); - - if (slot.smbl_info != smbios_slot_info) { - warnx("found wrong slot info: 0x%x, expected 0x%x", - slot.smbl_info, smbios_slot_info); - errs++; - } - - if (slot.smbl_pwidth != SMB_SLW_32X) { - warnx("found wrong slot physical width: 0x%x, expected 0x%x", - slot.smbl_pwidth, SMB_SLW_32X); - errs++; - } - - if (slot.smbl_pitch != smbios_slot_pitch) { - warnx("found wrong slot pitch: 0x%x, expected 0x%x", - slot.smbl_pitch, smbios_slot_pitch); - errs++; - } - - if (errs > 0) { - return (B_FALSE); - } - - return (B_TRUE); -} - -boolean_t -smbios_test_slot_verify_34_peers(smbios_hdl_t *hdl) -{ - smbios_struct_t sp; - smbios_slot_t slot; - uint_t npeers; - smbios_slot_peer_t *peers; - uint_t errs = 0; - - if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) { - warnx("failed to lookup SMBIOS slot: %s", - smbios_errmsg(smbios_errno(hdl))); - return (B_FALSE); - } - - if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) { - warnx("failed to get SMBIOS slot info: %s", - smbios_errmsg(smbios_errno(hdl))); - return (B_FALSE); - } - - if (!smbios_test_slot_common(&slot)) { - errs++; - } - - if (slot.smbl_npeers != 1) { - warnx("incorrect number of slot peers, found %u", - slot.smbl_npeers); - errs++; - } - - if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) { - warnx("failed to get SMBIOS peer info: %s", - smbios_errmsg(smbios_errno(hdl))); - return (B_FALSE); - } - - if (npeers != 1) { - warnx("got wrong number of slot peers: %u", npeers); - errs++; - } - - if (peers[0].smblp_group != 1) { - warnx("incorrect group for peer 0: %u", peers[0].smblp_group); - errs++; - } - - if (peers[0].smblp_data_width != SMB_SLW_8X) { - warnx("incorrect data width for peer 0: %u", - peers[0].smblp_data_width); - errs++; - } - - if (peers[0].smblp_bus != 0x42) { - warnx("incorrect PCI bus for peer 0: %u", - peers[0].smblp_bus); - errs++; - } - - if (peers[0].smblp_device != (0x9a >> 3)) { - warnx("incorrect PCI device for peer 0: %u", - peers[0].smblp_device); - errs++; - } - - if (peers[0].smblp_function != (0x9a & 0x7)) { - warnx("incorrect PCI function for peer 0: %u", - peers[0].smblp_function); - errs++; - } - - smbios_info_slot_peers_free(hdl, npeers, peers); - - if (slot.smbl_info != smbios_slot_info) { - warnx("found wrong slot info: 0x%x, expected 0x%x", - slot.smbl_info, smbios_slot_info); - errs++; - } - - if (slot.smbl_pwidth != SMB_SLW_32X) { - warnx("found wrong slot physical width: 0x%x, expected 0x%x", - slot.smbl_pwidth, SMB_SLW_32X); - errs++; - } - - if (slot.smbl_pitch != smbios_slot_pitch) { - warnx("found wrong slot pitch: 0x%x, expected 0x%x", - slot.smbl_pitch, smbios_slot_pitch); - errs++; - } - if (errs > 0) { return (B_FALSE); } diff --git a/usr/src/uts/common/sys/smbios.h b/usr/src/uts/common/sys/smbios.h index debe1fe72d..55048d549d 100644 --- a/usr/src/uts/common/sys/smbios.h +++ b/usr/src/uts/common/sys/smbios.h @@ -22,7 +22,6 @@ /* * 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. */ @@ -528,8 +527,6 @@ 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 */ @@ -947,9 +944,6 @@ 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 */ @@ -982,8 +976,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 U.2) */ -#define SMB_SLT_PCIEG3_SFF 0x20 /* PCI Express Gen 3 SFF-8639 (U.2) */ +#define SMB_SLT_PCIEG2_SFF 0x1F /* PCI Express Gen 2 SFF-8639 */ +#define SMB_SLT_PCIEG3_SFF 0x20 /* PCI Express Gen 3 SFF-8639 */ /* * These lines must be on one line for the string generating code. */ @@ -992,11 +986,6 @@ 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 */ @@ -1027,15 +1016,6 @@ 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 */ @@ -1061,8 +1041,6 @@ 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 */ @@ -1077,9 +1055,6 @@ 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 @@ -1203,7 +1178,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 add-on card */ +#define SMB_MAL_CXL1 0xA4 /* CXL Flexbus 1.0 add-on card */ #define SMB_MAU_OTHER 0x01 /* other */ #define SMB_MAU_UNKNOWN 0x02 /* unknown */ @@ -1310,8 +1285,6 @@ 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 */ @@ -1340,7 +1313,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 persistent memory */ +#define SMB_MTECH_INTCPM 0x07 /* Intel Optane DC Persistent Memory */ #define SMB_MOMC_RESERVED 0x01 /* reserved */ #define SMB_MOMC_OTHER 0x02 /* other */ @@ -1865,8 +1838,7 @@ 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_34 0x0304 /* SMBIOS encoding for DMTF spec 3.4 */ -#define SMB_VERSION SMB_VERSION_34 /* SMBIOS latest version definitions */ +#define SMB_VERSION SMB_VERSION_33 /* 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 4b951b702f..69ca79e94f 100644 --- a/usr/src/uts/common/sys/smbios_impl.h +++ b/usr/src/uts/common/sys/smbios_impl.h @@ -22,7 +22,6 @@ /* * 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. */ @@ -251,25 +250,8 @@ 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. */ -- cgit v1.2.3 From d96925c4917df4be0de8533ddaa487c9d915b8c5 Mon Sep 17 00:00:00 2001 From: Richard Lowe Date: Mon, 17 Aug 2020 15:53:38 -0400 Subject: 11499 default to hires tick Reviewed by: Joshua M. Clulow Reviewed by: Andy Fiddaman Reviewed by: Patrick Mooney Reviewed by: John Levon Approved by: Joshua M. Clulow --- usr/src/man/man1m/dispadmin.1m | 10 +-- usr/src/man/man4/fx_dptbl.4 | 22 ++---- usr/src/man/man4/rt_dptbl.4 | 17 ++-- usr/src/man/man4/ts_dptbl.4 | 19 ++--- usr/src/uts/common/conf/param.c | 13 ++-- usr/src/uts/common/io/usb/usba/hubdi.c | 137 ++++++++++++++++----------------- usr/src/uts/common/os/softint.c | 46 +++++------ usr/src/uts/sun/sys/ser_async.h | 10 +-- 8 files changed, 121 insertions(+), 153 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/man/man1m/dispadmin.1m b/usr/src/man/man1m/dispadmin.1m index 91f260bc01..0f7af2d255 100644 --- a/usr/src/man/man1m/dispadmin.1m +++ b/usr/src/man/man1m/dispadmin.1m @@ -127,11 +127,11 @@ Moreover, the values must describe a table that is the same size (has same number of priority levels) as the table being overwritten. Super-user privileges are required in order to use the \fB-s\fR option. .sp -Specify time quantum values for scheduling classes in system clock ticks, and -not in constant-time units. Time quantum values are based on the value of the -kernel's \fBhz\fR variable. If kernel variable \fBhires_tick\fR is set to -\fB1\fR to get higher resolution clock behavior, the actual time quanta will be -reduced by the order of \fB10\fR. +Time quantum values for scheduling classes are specified in system clock ticks +rather than constant-time units. These values are based on the value of the +kernel's \fBhz\fR variable. By default, the system operates at 1000 Hz and +thus with a quantum of 1 millisecond. If the kernel tunable \fBhires_tick\fR +is set to 0, this drops to 100 Hz for a larger quantum of 10 milliseconds. .sp The \fB-g\fR and \fB-s\fR options are mutually exclusive: you may not retrieve the table at the same time you are overwriting it. diff --git a/usr/src/man/man4/fx_dptbl.4 b/usr/src/man/man4/fx_dptbl.4 index 4373e7705c..ce2ad1bc3f 100644 --- a/usr/src/man/man4/fx_dptbl.4 +++ b/usr/src/man/man4/fx_dptbl.4 @@ -7,14 +7,11 @@ .SH NAME fx_dptbl \- fixed priority dispatcher parameter table .SH SYNOPSIS -.LP .nf \fBfx_dptbl\fR .fi .SH DESCRIPTION -.sp -.LP The process scheduler or dispatcher is the portion of the kernel that controls allocation of the CPU to processes. The scheduler supports the notion of scheduling classes, where each class defines a scheduling policy used to @@ -67,9 +64,11 @@ processes at a particular level, as the time quantum of a fixed priority process can be changed by the user with the \fBpriocntl\fR(1) command or the \fBpriocntl\fR(2) system call. .sp -In the high resolution clock mode (\fBhires_tick\fR set to \fB1\fR), the value -of \fBhz\fR is set to \fB1000\fR. Increase quantums to maintain the same -absolute time quantums. +In the default high resolution clock mode (\fBhires_tick\fR set to \fB1\fR), +the value of \fBhz\fR is set to \fB1000\fR. If this value is overridden to +\fB0\fR then \fBhz\fR will instead be \fB100\fR; the number of ticks per +quantum must then be decreased to maintain the same length of quantum in +absolute time. .sp An administrator can affect the behavior of the fixed priority portion of the scheduler by reconfiguring the \fBfx_dptbl\fR. There are two methods available @@ -78,8 +77,6 @@ for doing this: reconfigure with a loadable module at boot-time or by using .RE .SS "fx_dptbl Loadable Module" -.sp -.LP The \fBfx_dptbl\fR can be reconfigured with a loadable module that contains a new fixed priority dispatch table. The module containing the dispatch table is separate from the \fBFX\fR loadable module, which contains the rest of the @@ -88,8 +85,6 @@ number of fixed priority priority levels or the set of global scheduling priorities used by the fixed priority class. The relevant procedure and source code is described in Replacing the fx_dptbl Loadable Module below. .SS "dispadmin Configuration File" -.sp -.LP The \fBfx_quantum\fR values in the \fBfx_dptbl\fR can be examined and modified on a running system using the \fBdispadmin\fR(1M) command. Invoking \fBdispadmin\fR for the fixed-priority class allows the administrator to @@ -141,8 +136,6 @@ positive integer specifying the desired time quantum in the resolution given by See Examples for an example of an excerpt of a \fBdispadmin\fR configuration file. .SS "Replacing the fx_dptbl Loadable Module" -.sp -.LP To change the size of the fixed priority dispatch table, you must build the loadable module that contains the dispatch table information. Save the existing module before using the following procedure. @@ -202,7 +195,6 @@ Reboot the system to use the new dispatch table. Exercise great care in using the preceding method to replace the dispatch table. A mistake can result in panics, thus making the system unusable. .SH EXAMPLES -.LP \fBExample 1 \fRConfiguration File Excerpt .sp .LP @@ -395,15 +387,11 @@ fx_getmaxumdpri() .sp .SH SEE ALSO -.sp -.LP \fBpriocntl\fR(1), \fBdispadmin\fR(1M), \fBpriocntl\fR(2), \fBsystem\fR(4) .sp .LP \fISystem Administration Guide, Volume 1, System Interface Guide\fR .SH NOTES -.sp -.LP In order to improve performance under heavy system load, both the \fBnfsd\fR daemon and the \fBlockd\fR daemon utilize the maximum priority in the \fBFX\fR class. Unusual \fBfx_dptbl\fR configurations may have significant negative diff --git a/usr/src/man/man4/rt_dptbl.4 b/usr/src/man/man4/rt_dptbl.4 index b24b3d72f4..bace4ec80b 100644 --- a/usr/src/man/man4/rt_dptbl.4 +++ b/usr/src/man/man4/rt_dptbl.4 @@ -7,8 +7,6 @@ .SH NAME rt_dptbl \- real-time dispatcher parameter table .SH DESCRIPTION -.sp -.LP The process scheduler (or dispatcher) is the portion of the kernel that controls allocation of the \fBCPU\fR to processes. The scheduler supports the notion of scheduling classes where each class defines a scheduling policy, used @@ -59,9 +57,11 @@ processes at a particular level as the time quantum of a real-time process can be changed by the user with the \fBpriocntl\fR command or the \fBpriocntl\fR system call. .sp -In the high resolution clock mode (\fBhires_tick\fR set to \fB1\fR), the value -of \fBhz\fR is set to \fB1000\fR. Increase quantums to maintain the same -absolute time quantums. +In the default high resolution clock mode (\fBhires_tick\fR set to \fB1\fR), +the value of \fBhz\fR is set to \fB1000\fR. If this value is overridden to +\fB0\fR then \fBhz\fR will instead be \fB100\fR; the number of ticks per +quantum must then be decreased to maintain the same length of quantum in +absolute time. .RE .sp @@ -71,8 +71,6 @@ scheduler by reconfiguring the \fBrt_dptbl\fR. There are two methods available for doing this: reconfigure with a loadable module at boot-time or by using \fBdispadmin\fR(1M) at run-time. .SS "rt_dptbl Loadable Module" -.sp -.LP The \fBrt_dptbl\fR can be reconfigured with a loadable module which contains a new real time dispatch table. The module containing the dispatch table is separate from the RT loadable module which contains the rest of the real time @@ -81,8 +79,6 @@ time priority levels or the set of global scheduling priorities used by the real time class. The relevant procedure and source code is described in the Examples section. .SS "dispadmin Configuration File" -.sp -.LP The \fBrt_quantum\fR values in the \fBrt_dptbl\fR can be examined and modified on a running system using the \fBdispadmin\fR(1M) command. Invoking \fBdispadmin\fR for the real-time class allows the administrator to retrieve @@ -120,7 +116,6 @@ level. Each \fBrt_quantum\fR entry must be either a positive integer specifying the desired time quantum (in the resolution given by \fIres\fR), or the value -2 indicating an infinite time quantum for that level. .SH EXAMPLES -.LP \fBExample 1 \fRA Sample \fBdispadmin\fR Configuration File .sp .LP @@ -341,8 +336,6 @@ rtdpent_t config_rt_dptbl[] = { .in -2 .SH SEE ALSO -.sp -.LP \fBpriocntl\fR(1), \fBdispadmin\fR(1M), \fBpriocntl\fR(2), \fBsystem\fR(4) .sp .LP diff --git a/usr/src/man/man4/ts_dptbl.4 b/usr/src/man/man4/ts_dptbl.4 index f6e7db3482..9dbcc11d15 100644 --- a/usr/src/man/man4/ts_dptbl.4 +++ b/usr/src/man/man4/ts_dptbl.4 @@ -7,8 +7,6 @@ .SH NAME ts_dptbl \- time-sharing dispatcher parameter table .SH DESCRIPTION -.sp -.LP The process scheduler (or dispatcher) is the portion of the kernel that controls allocation of the \fBCPU\fR to processes. The scheduler supports the notion of scheduling classes where each class defines a scheduling policy, used @@ -65,9 +63,11 @@ only member of the \fBts_dptbl\fR which cannot be changed with The length of the time quantum allocated to processes at this level in ticks (\fBhz\fR). .sp -In the high resolution clock mode (\fBhires_tick\fR set to \fB1\fR), the value -of \fBhz\fR is set to \fB1000\fR. Increase quantums to maintain the same -absolute time quantums. +In the default high resolution clock mode (\fBhires_tick\fR set to \fB1\fR), +the value of \fBhz\fR is set to \fB1000\fR. If this value is overridden to +\fB0\fR then \fBhz\fR will instead be \fB100\fR; the number of ticks per +quantum must then be decreased to maintain the same length of quantum in +absolute time. .RE .sp @@ -129,8 +129,6 @@ scheduling classes. There are two methods available for doing this: reconfigure with a loadable module at boot-time or by using \fBdispadmin\fR(1M) at run-time. .SS "ts_dptbl Loadable Module" -.sp -.LP The \fBts_dptbl\fR can be reconfigured with a loadable module which contains a new time sharing dispatch table. The module containing the dispatch table is separate from the TS loadable module which contains the rest of the @@ -140,8 +138,6 @@ scheduling priorities used by the time-sharing and inter-active classes. The relevant procedure and source code is described in the \fBREPLACING THE TS_DPTBL LOADABLE MODULE\fR section. .SS "dispadmin Configuration File" -.sp -.LP With the exception of \fBts_globpri\fR all of the members of the \fBts_dptbl\fR can be examined and modified on a running system using the \fBdispadmin\fR(1M) command. Invoking \fBdispadmin\fR for the time-sharing or inter-active class @@ -177,7 +173,6 @@ parameters for time-sharing level 0, the second line specifies the parameters for time-sharing level 1, etc. There must be exactly one line for each configured time-sharing priority level. .SH EXAMPLES -.LP \fBExample 1 \fRA Sample From a Configuration File .sp .LP @@ -435,8 +430,6 @@ ts_getmaxumdpri() .in -2 .SH SEE ALSO -.sp -.LP \fBpriocntl\fR(1), \fBdispadmin\fR(1M), \fBpriocntl\fR(2), \fBsystem\fR(4) .sp .LP @@ -445,8 +438,6 @@ ts_getmaxumdpri() .LP \fIProgramming Interfaces Guide\fR .SH NOTES -.sp -.LP \fBdispadmin\fR does some limited sanity checking on the values supplied in the configuration file. The sanity checking is intended to ensure that the new \fBts_dptbl\fR values do not cause the system to panic. The sanity checking diff --git a/usr/src/uts/common/conf/param.c b/usr/src/uts/common/conf/param.c index 64227a3998..045a3872fc 100644 --- a/usr/src/uts/common/conf/param.c +++ b/usr/src/uts/common/conf/param.c @@ -115,7 +115,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; @@ -130,9 +130,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: @@ -159,7 +162,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/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/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/sun/sys/ser_async.h b/usr/src/uts/sun/sys/ser_async.h index 8e8a573829..0f89bce4c5 100644 --- a/usr/src/uts/sun/sys/ser_async.h +++ b/usr/src/uts/sun/sys/ser_async.h @@ -27,8 +27,6 @@ #ifndef _SYS_SER_ASYNC_H #define _SYS_SER_ASYNC_H -#pragma ident "%Z%%M% %I% %E% SMI" - /* * Initial port setup parameters for async lines */ @@ -57,9 +55,9 @@ extern "C" { #define ZFIFOSZ 3 /* - * this macro needs a constant Hertz, but we can now have a hires_tick. + * This macro needs a constant 100 Hz, but hires_tick or hz may change that. * ztdelay in zs_async.c converts to a true delay based on hz so we - * can use 100 for Hertz here. + * can use 100 Hz here. */ #define ZDELAY(n) ZSDelayConst(100, ZFIFOSZ, NBBY, n) @@ -166,9 +164,9 @@ struct asyncline { * and the second byte is the actual data. The ring buffer * needs to be defined as ushort_t to accomodate this. */ - ushort_t za_ring[RINGSIZE]; + ushort_t za_ring[RINGSIZE]; timeout_id_t za_kick_rcv_id; - int za_kick_rcv_count; + int za_kick_rcv_count; timeout_id_t za_zsa_restart_id; bufcall_id_t za_bufcid; mblk_t *za_rstandby[ZSA_MAX_RSTANDBY]; -- cgit v1.2.3 From 92db730eedd4fcf11958d5b89b6d63f99488d594 Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Wed, 2 Sep 2020 12:48:02 +0300 Subject: 13117 zfs: variable dereferenced before check Reviewed by: Andrew Stormont Reviewed by: C Fraire Reviewed by: Patrick Mooney Approved by: Robert Mustacchi --- usr/src/uts/common/fs/zfs/zvol.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/fs/zfs/zvol.c b/usr/src/uts/common/fs/zfs/zvol.c index 02eb0b8e1a..55dd9a2681 100644 --- a/usr/src/uts/common/fs/zfs/zvol.c +++ b/usr/src/uts/common/fs/zfs/zvol.c @@ -1155,10 +1155,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) -- cgit v1.2.3 From 1045e13a248d94941f864998aa859970ae3a4154 Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Fri, 24 Jul 2020 11:42:23 -0700 Subject: 13079 Add ksensor support for voltage and current sensors Reviewed by: Andy Fiddaman Reviewed by: Paul Winder Approved by: Dan McDonald --- .../lib/fm/topo/modules/common/pcibus/pci_sensor.c | 61 +++++++---- .../fm/topo/modules/common/shared/topo_sensor.c | 117 ++++++++++++--------- .../fm/topo/modules/common/shared/topo_sensor.h | 4 +- usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c | 4 +- .../lib/fm/topo/modules/i86pc/chipset/chipset.c | 2 +- .../test/os-tests/tests/ksensor/ksensor_basic.c | 111 ++++++++++++------- usr/src/test/os-tests/tests/ksensor/ksensor_err.c | 24 ++--- .../test/os-tests/tests/ksensor/ksensor_sread.c | 12 +-- .../test/os-tests/tests/ksensor/ksensor_stress.ksh | 2 +- usr/src/uts/common/io/igb/igb_sensor.c | 17 +-- usr/src/uts/common/io/ksensor/ksensor_drv.c | 16 +-- usr/src/uts/common/io/ksensor/ksensor_test.c | 76 ++++++++++--- usr/src/uts/common/mapfiles/ksensor.mapfile | 4 +- usr/src/uts/common/os/ksensor.c | 40 +++++-- usr/src/uts/common/sys/ksensor_impl.h | 2 +- usr/src/uts/common/sys/sensors.h | 62 ++++++----- usr/src/uts/intel/io/amdf17nbdf/amdf17nbdf.c | 21 ++-- usr/src/uts/intel/io/amdnbtemp/amdnbtemp.c | 10 +- usr/src/uts/intel/io/coretemp/coretemp.c | 12 +-- usr/src/uts/intel/io/pchtemp/pchtemp.c | 10 +- 20 files changed, 384 insertions(+), 223 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/lib/fm/topo/modules/common/pcibus/pci_sensor.c b/usr/src/lib/fm/topo/modules/common/pcibus/pci_sensor.c index bb2cf6d344..390017fd4a 100644 --- a/usr/src/lib/fm/topo/modules/common/pcibus/pci_sensor.c +++ b/usr/src/lib/fm/topo/modules/common/pcibus/pci_sensor.c @@ -29,27 +29,14 @@ #include #include -int -pci_create_dev_sensors(topo_mod_t *mod, tnode_t *dev) +static const char *pci_sensor_types[] = { "current", "voltage", "temperature" }; + +static int +pci_create_dev_scandir(topo_mod_t *mod, tnode_t *dev, const char *path) { int ret; DIR *d; - char path[PATH_MAX]; - topo_instance_t binst, dinst; struct dirent *ent; - tnode_t *parent = topo_node_parent(dev); - - binst = topo_node_instance(parent); - dinst = topo_node_instance(dev); - - if (snprintf(path, sizeof (path), "/dev/sensors/temperature/pci/%x.%x", - binst, dinst) >= sizeof (path)) { - topo_mod_dprintf(mod, "failed to construct temp sensor " - "directory path, path too long"); - return (topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM)); - } - - topo_mod_dprintf(mod, "searching for sensors in %s", path); d = opendir(path); if (d == NULL) { @@ -72,24 +59,54 @@ pci_create_dev_sensors(topo_mod_t *mod, tnode_t *dev) if (snprintf(spath, sizeof (spath), "%s/%s", path, ent->d_name) >= sizeof (spath)) { - topo_mod_dprintf(mod, "failed to construct temp sensor " - "path for %s/%s, path too long", path, ent->d_name); + topo_mod_dprintf(mod, "failed to construct sensor path " + "for %s/%s, path too long", path, ent->d_name); ret = topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM); goto out; } topo_mod_dprintf(mod, "attempting to create sensor at %s", spath); - if ((ret = topo_sensor_create_temp_sensor(mod, dev, spath, + if ((ret = topo_sensor_create_scalar_sensor(mod, dev, spath, ent->d_name)) < 0) { goto out; } - } + ret = 0; out: (void) closedir(d); - return (ret); } + +int +pci_create_dev_sensors(topo_mod_t *mod, tnode_t *dev) +{ + uint_t i; + char path[PATH_MAX]; + topo_instance_t binst, dinst; + tnode_t *parent = topo_node_parent(dev); + + binst = topo_node_instance(parent); + dinst = topo_node_instance(dev); + + for (i = 0; i < ARRAY_SIZE(pci_sensor_types); i++) { + int ret; + + if (snprintf(path, sizeof (path), "/dev/sensors/%s/pci/%x.%x", + pci_sensor_types[i], binst, dinst) >= sizeof (path)) { + topo_mod_dprintf(mod, "failed to construct %s sensor " + "directory path, path too long", + pci_sensor_types[i]); + return (topo_mod_seterrno(mod, EMOD_UKNOWN_ENUM)); + } + + topo_mod_dprintf(mod, "searching for sensors in %s", path); + if ((ret = pci_create_dev_scandir(mod, dev, path)) != 0) { + return (ret); + } + } + + return (0); +} diff --git a/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c b/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c index c9e56e9e1f..a716c57a66 100644 --- a/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c +++ b/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.c @@ -11,13 +11,14 @@ /* * Copyright 2019, Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* * This file provides routines to interact with the kernel sensor framework. * Currently, modules that require interacting with a kernel sensor need to * build this file as part of the module. This takes care of all the work of - * setting up and creating the temperature sensor, given a path to that sensor. + * setting up and creating the sensor, given a path to that sensor. */ #include @@ -31,21 +32,21 @@ #include #include -#define TOPO_METH_TOPO_SENSOR_TEMP "topo_sensor_temp_reading" -#define TOPO_METH_TOPO_SENSOR_TEMP_DESC "Kernel Temperature Reading" -#define TOPO_METH_TOPO_SENSOR_TEMP_VERSION 0 +#define TOPO_METH_TOPO_SENSOR_SCALAR "topo_sensor_scalar_reading" +#define TOPO_METH_TOPO_SENSOR_SCALAR_DESC "Kernel Sensor Scalar Reading" +#define TOPO_METH_TOPO_SENSOR_SCALAR_VERSION 0 static int -topo_sensor_temp_read(topo_mod_t *mod, tnode_t *node, topo_version_t vers, +topo_sensor_scalar_read(topo_mod_t *mod, tnode_t *node, topo_version_t vers, nvlist_t *in, nvlist_t **out) { int fd = -1, ret; nvlist_t *args, *nvl; char *path; - sensor_ioctl_temperature_t temp; - double degrees; + sensor_ioctl_scalar_t scalar; + double value; - if (vers != TOPO_METH_TOPO_SENSOR_TEMP_VERSION) { + if (vers != TOPO_METH_TOPO_SENSOR_SCALAR_VERSION) { return (topo_mod_seterrno(mod, ETOPO_METHOD_VERNEW)); } @@ -62,31 +63,30 @@ topo_sensor_temp_read(topo_mod_t *mod, tnode_t *node, topo_version_t vers, return (topo_mod_seterrno(mod, EMOD_UNKNOWN)); } - (void) memset(&temp, '\0', sizeof (temp)); - if (ioctl(fd, SENSOR_IOCTL_TEMPERATURE, &temp) != 0) { - topo_mod_dprintf(mod, "failed to read temperature sensor " - "%s: %s", path, strerror(errno)); + (void) memset(&scalar, '\0', sizeof (scalar)); + if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) { + topo_mod_dprintf(mod, "failed to read sensor %s: %s", path, + strerror(errno)); ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); goto out; } /* * Check to see if we need to change the value to get it into an - * accurate reading. Positive values indicate that the temperature - * reading is in a fractional number of degrees and that each degree - * contains temp.sit_gran steps. A negative number means that the - * temperature reading represents temp.sit_gran degrees. + * accurate reading. Positive granularities indicate that the sensor + * reading is in a fractional number of units and that each unit + * contains scalar.sis_gran steps. A negative number means that the + * sensor reading represents scalar.sis_gran units. */ - degrees = (double)temp.sit_temp; - if (temp.sit_gran > 1) { - degrees /= (double)temp.sit_gran; - } else if (temp.sit_gran < -1) { - degrees *= (double)labs(temp.sit_gran); + value = (double)scalar.sis_value; + if (scalar.sis_gran > 1) { + value /= (double)scalar.sis_gran; + } else if (scalar.sis_gran < -1) { + value *= (double)labs(scalar.sis_gran); } if (topo_mod_nvalloc(mod, &nvl, NV_UNIQUE_NAME) != 0) { - topo_mod_dprintf(mod, "failed to allocate output temperature " - "nvl"); + topo_mod_dprintf(mod, "failed to allocate output nvl"); ret = topo_mod_seterrno(mod, EMOD_NOMEM); goto out; } @@ -94,9 +94,9 @@ topo_sensor_temp_read(topo_mod_t *mod, tnode_t *node, topo_version_t vers, if (nvlist_add_string(nvl, TOPO_PROP_VAL_NAME, TOPO_SENSOR_READING) != 0 || nvlist_add_uint32(nvl, TOPO_PROP_VAL_TYPE, TOPO_TYPE_DOUBLE) != 0 || - nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, degrees) != 0) { + nvlist_add_double(nvl, TOPO_PROP_VAL_VAL, value) != 0) { topo_mod_dprintf(mod, "failed to add members to output " - "temperature nvlist"); + "sensor nvlist"); nvlist_free(nvl); ret = topo_mod_seterrno(mod, EMOD_NOMEM); goto out; @@ -111,35 +111,40 @@ out: return (ret); } -static const topo_method_t topo_sensor_temp_fac_methods[] = { - { TOPO_METH_TOPO_SENSOR_TEMP, TOPO_METH_TOPO_SENSOR_TEMP_DESC, - TOPO_METH_TOPO_SENSOR_TEMP_VERSION, TOPO_STABILITY_INTERNAL, - topo_sensor_temp_read }, +static const topo_method_t topo_sensor_scalar_fac_methods[] = { + { TOPO_METH_TOPO_SENSOR_SCALAR, TOPO_METH_TOPO_SENSOR_SCALAR_DESC, + TOPO_METH_TOPO_SENSOR_SCALAR_VERSION, TOPO_STABILITY_INTERNAL, + topo_sensor_scalar_read }, { NULL } }; static topo_sensor_unit_t -topo_sensor_units(const sensor_ioctl_temperature_t *temp) +topo_sensor_units(const sensor_ioctl_scalar_t *scalar) { - switch (temp->sit_unit) { + switch (scalar->sis_unit) { case SENSOR_UNIT_CELSIUS: return (TOPO_SENSOR_UNITS_DEGREES_C); case SENSOR_UNIT_FAHRENHEIT: return (TOPO_SENSOR_UNITS_DEGREES_F); case SENSOR_UNIT_KELVIN: return (TOPO_SENSOR_UNITS_DEGREES_K); + case SENSOR_UNIT_VOLTS: + return (TOPO_SENSOR_UNITS_VOLTS); + case SENSOR_UNIT_AMPS: + return (TOPO_SENSOR_UNITS_AMPS); default: return (TOPO_SENSOR_UNITS_UNSPECIFIED); } } int -topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode, +topo_sensor_create_scalar_sensor(topo_mod_t *mod, tnode_t *pnode, const char *path, const char *fname) { int fd, ret, err; sensor_ioctl_kind_t sik; - sensor_ioctl_temperature_t temp; + sensor_ioctl_scalar_t scalar; + uint32_t topo_type; tnode_t *fnode = NULL; topo_pgroup_info_t pgi; nvlist_t *reader_arg = NULL; @@ -148,16 +153,16 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode, topo_node_name(pnode), path); (void) memset(&sik, '\0', sizeof (sik)); - (void) memset(&temp, '\0', sizeof (temp)); + (void) memset(&scalar, '\0', sizeof (scalar)); if ((fd = open(path, O_RDONLY)) < 0) { topo_mod_dprintf(mod, "failed to open sensor path %s: %s", path, strerror(errno)); /* - * We always try to create temperature sensors; however, they - * may not exist or be supported on the system in question. - * Therefore ENOENT is totally acceptable. + * We always try to create sensors; however, they may not exist + * or be supported on the system in question. Therefore ENOENT + * is totally acceptable. */ if (errno == ENOENT) { return (0); @@ -165,23 +170,34 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode, return (topo_mod_seterrno(mod, EMOD_UNKNOWN)); } - if (ioctl(fd, SENSOR_IOCTL_TYPE, &sik) != 0) { + if (ioctl(fd, SENSOR_IOCTL_KIND, &sik) != 0) { topo_mod_dprintf(mod, "failed to verify sensor kind for sensor " "%s: %s", path, strerror(errno)); ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); goto out; } - if (sik.sik_kind != SENSOR_KIND_TEMPERATURE) { - topo_mod_dprintf(mod, "sensor kind for %s is not temperature, " - "found 0x%x", path, sik.sik_kind); + switch (sik.sik_kind) { + case SENSOR_KIND_TEMPERATURE: + topo_type = TOPO_SENSOR_TYPE_TEMP; + break; + case SENSOR_KIND_VOLTAGE: + topo_type = TOPO_SENSOR_TYPE_VOLTAGE; + break; + case SENSOR_KIND_CURRENT: + topo_type = TOPO_SENSOR_TYPE_CURRENT; + break; + default: + topo_mod_dprintf(mod, "unknown sensor kind for %s, found 0x%x", + path, sik.sik_kind); ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); goto out; + } - if (ioctl(fd, SENSOR_IOCTL_TEMPERATURE, &temp) != 0) { - topo_mod_dprintf(mod, "failed to read temperature sensor " - "%s: %s", path, strerror(errno)); + if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) { + topo_mod_dprintf(mod, "failed to read scalar sensor %s: %s", + path, strerror(errno)); ret = topo_mod_seterrno(mod, EMOD_UNKNOWN); goto out; } @@ -191,7 +207,7 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode, if ((fnode = topo_node_facbind(mod, pnode, fname, TOPO_FAC_TYPE_SENSOR)) == NULL) { - topo_mod_dprintf(mod, "failed to bind temperature facility " + topo_mod_dprintf(mod, "failed to bind sensor facility " "node to %s: %d", path, topo_mod_errno(mod)); ret = -1; goto out; @@ -213,10 +229,9 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode, TOPO_SENSOR_CLASS, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_CLASS_THRESHOLD, &err) != 0 || topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, - TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, TOPO_SENSOR_TYPE_TEMP, - &err) != 0 || + TOPO_FACILITY_TYPE, TOPO_PROP_IMMUTABLE, topo_type, &err) != 0 || topo_prop_set_uint32(fnode, TOPO_PGROUP_FACILITY, - TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, topo_sensor_units(&temp), + TOPO_SENSOR_UNITS, TOPO_PROP_IMMUTABLE, topo_sensor_units(&scalar), &err) != 0) { topo_mod_dprintf(mod, "failed to set properties for sensor " "%s: %s", path, topo_strerror(err)); @@ -225,7 +240,7 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode, } - if (topo_method_register(mod, fnode, topo_sensor_temp_fac_methods) < + if (topo_method_register(mod, fnode, topo_sensor_scalar_fac_methods) < 0) { topo_mod_dprintf(mod, "failed to register reading methods on " "%s", path); @@ -241,7 +256,7 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode, } if (topo_prop_method_register(fnode, TOPO_PGROUP_FACILITY, - TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, TOPO_METH_TOPO_SENSOR_TEMP, + TOPO_SENSOR_READING, TOPO_TYPE_DOUBLE, TOPO_METH_TOPO_SENSOR_SCALAR, reader_arg, &err) != 0) { topo_mod_dprintf(mod, "failed to set argument for sensor %s: " "%s", path, topo_strerror(err)); @@ -249,6 +264,8 @@ topo_sensor_create_temp_sensor(topo_mod_t *mod, tnode_t *pnode, goto out; } + topo_mod_dprintf(mod, "created sensor at %s", path); + nvlist_free(reader_arg); return (0); out: diff --git a/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.h b/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.h index ff6e1ea92e..753dcbd8d8 100644 --- a/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.h +++ b/usr/src/lib/fm/topo/modules/common/shared/topo_sensor.h @@ -24,8 +24,8 @@ extern "C" { #endif -extern int topo_sensor_create_temp_sensor(topo_mod_t *, tnode_t *, const char *, - const char *); +extern int topo_sensor_create_scalar_sensor(topo_mod_t *, tnode_t *, + const char *, const char *); #ifdef __cplusplus } diff --git a/usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c b/usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c index 89f8d57fb6..f06190bb46 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c +++ b/usr/src/lib/fm/topo/modules/i86pc/chip/chip_temp.c @@ -71,7 +71,7 @@ chip_create_core_temp_sensor(topo_mod_t *mod, tnode_t *pnode) } } - return (topo_sensor_create_temp_sensor(mod, pnode, buf, "temp")); + return (topo_sensor_create_scalar_sensor(mod, pnode, buf, "temp")); } int @@ -87,5 +87,5 @@ chip_create_chip_temp_sensor(topo_mod_t *mod, tnode_t *pnode) return (topo_mod_seterrno(mod, EMOD_UNKNOWN)); } - return (topo_sensor_create_temp_sensor(mod, pnode, buf, "temp")); + return (topo_sensor_create_scalar_sensor(mod, pnode, buf, "temp")); } diff --git a/usr/src/lib/fm/topo/modules/i86pc/chipset/chipset.c b/usr/src/lib/fm/topo/modules/i86pc/chipset/chipset.c index cc306b4b2f..2f3781c932 100644 --- a/usr/src/lib/fm/topo/modules/i86pc/chipset/chipset.c +++ b/usr/src/lib/fm/topo/modules/i86pc/chipset/chipset.c @@ -136,7 +136,7 @@ topo_chipset_enum(topo_mod_t *mod, tnode_t *pnode, const char *name, /* * Finally, create the temperature sensor. */ - if ((ret = topo_sensor_create_temp_sensor(mod, tn, + if ((ret = topo_sensor_create_scalar_sensor(mod, tn, topo_chipset_temp_sensor, "temp")) != 0) { topo_mod_dprintf(mod, "failed to create chipset temperature " "sensor"); diff --git a/usr/src/test/os-tests/tests/ksensor/ksensor_basic.c b/usr/src/test/os-tests/tests/ksensor/ksensor_basic.c index 35590df264..22f79d18a7 100644 --- a/usr/src/test/os-tests/tests/ksensor/ksensor_basic.c +++ b/usr/src/test/os-tests/tests/ksensor/ksensor_basic.c @@ -26,66 +26,101 @@ #include #include #include +#include -static const char *ksensor_path = "/dev/sensors/test/test.temp.0.1"; +typedef struct sensor_test { + const char *st_path; + uint64_t st_kind; + uint32_t st_unit; + int32_t st_gran; + uint32_t st_prec; + int64_t st_val; +} sensor_test_t; -int -main(void) +/* + * These values come from the dummy sensors in the ksensor_test driver. + */ +static sensor_test_t ksensor_basic_tests[] = { + { "/dev/sensors/test/test.temp.0.1", SENSOR_KIND_TEMPERATURE, + SENSOR_UNIT_CELSIUS, 4, -2, 23 }, + { "/dev/sensors/test/test.volt.0.1", SENSOR_KIND_VOLTAGE, + SENSOR_UNIT_VOLTS, 1000, 0, 3300 }, + { "/dev/sensors/test/test.current.0.1", SENSOR_KIND_CURRENT, + SENSOR_UNIT_AMPS, 10, 0, 5 }, +}; + +static boolean_t +ksensor_basic(sensor_test_t *st) { sensor_ioctl_kind_t kind; - sensor_ioctl_temperature_t temp; - int ret = 0; + sensor_ioctl_scalar_t scalar; + int fd; - int fd = open(ksensor_path, O_RDONLY); + fd = open(st->st_path, O_RDONLY); if (fd < 0) { - err(EXIT_FAILURE, "TEST FAILED: failed to open %s", - ksensor_path); + warn("TEST FAILED: failed to open %s", st->st_path); + return (B_FALSE); } arc4random_buf(&kind, sizeof (kind)); - arc4random_buf(&temp, sizeof (temp)); + arc4random_buf(&scalar, sizeof (scalar)); + + if (ioctl(fd, SENSOR_IOCTL_KIND, &kind) != 0) { + warn("TEST FAILED: %s: failed to get sensor kind", st->st_path); + goto err; + } - if (ioctl(fd, SENSOR_IOCTL_TYPE, &kind) != 0) { - warn("TEST FAILED: failed to get sensor type"); - ret = EXIT_FAILURE; + if (kind.sik_kind != st->st_kind) { + warnx("TEST FAILED: %s: expected kind %" PRIu64 ", found kind %" + PRIu64, st->st_path, st->st_kind, kind); + goto err; } - if (kind.sik_kind != SENSOR_KIND_TEMPERATURE) { - warnx("TEST FAILED: expected temperature sensor, found kind %d", - kind); - ret = EXIT_FAILURE; + if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) { + warn("TEST FAILED: %s: failed to read sensor", st->st_path); + goto err; } - if (ioctl(fd, SENSOR_IOCTL_TEMPERATURE, &temp) != 0) { - warn("TEST FAILED: failed to get sensor temperature"); - ret = EXIT_FAILURE; + if (scalar.sis_unit != st->st_unit) { + warnx("TEST FAILED: %s: expected unit %" PRIu32 ", but found " + "%" PRIu32, st->st_path, st->st_unit, scalar.sis_unit); + goto err; } - /* - * These values come from the dummy temperature sensor in ksensor_test. - */ - if (temp.sit_unit != SENSOR_UNIT_CELSIUS) { - warnx("TEST FAILED: expected temp unit %" PRIu32 ", but found " - "%" PRIu32, SENSOR_UNIT_CELSIUS, temp.sit_unit); - ret = EXIT_FAILURE; + if (scalar.sis_gran != st->st_gran) { + warnx("TEST FAILED: %s: expected gran %" PRId32 ", but found " + "%" PRId32, st->st_path, st->st_gran, scalar.sis_gran); + goto err; } - if (temp.sit_gran != 4) { - warnx("TEST FAILED: expected temp gran %" PRId32 ", but found " - "%" PRId32, 4, temp.sit_gran); - ret = EXIT_FAILURE; + if (scalar.sis_prec != st->st_prec) { + warnx("TEST FAILED: %s: expected prec %" PRIu32 ", but found " + "%" PRIu32, st->st_path, st->st_prec, scalar.sis_prec); + goto err; } - if (temp.sit_prec != -2) { - warnx("TEST FAILED: expected temp prec %" PRId32 ", but found " - "%" PRId32, -2, temp.sit_prec); - ret = EXIT_FAILURE; + if (scalar.sis_value != st->st_val) { + warnx("TEST FAILED: %s: expected value %" PRId64 ", but found " + "%" PRId64, st->st_path, st->st_val, scalar.sis_value); + goto err; } - if (temp.sit_temp != 23) { - warnx("TEST FAILED: expected temp %" PRId64 ", but found " - "%" PRId64, 23, temp.sit_temp); - ret = EXIT_FAILURE; + return (B_TRUE); +err: + (void) close(fd); + return (B_FALSE); +} + +int +main(void) +{ + size_t i; + int ret = EXIT_SUCCESS; + + for (i = 0; i < ARRAY_SIZE(ksensor_basic_tests); i++) { + if (!ksensor_basic(&ksensor_basic_tests[i])) { + ret = EXIT_FAILURE; + } } return (ret); diff --git a/usr/src/test/os-tests/tests/ksensor/ksensor_err.c b/usr/src/test/os-tests/tests/ksensor/ksensor_err.c index 2818327f78..784dc477d8 100644 --- a/usr/src/test/os-tests/tests/ksensor/ksensor_err.c +++ b/usr/src/test/os-tests/tests/ksensor/ksensor_err.c @@ -39,20 +39,20 @@ error_kind(int fd, int exp) arc4random_buf(&alt_kind, sizeof (alt_kind)); (void) memcpy(&kind, &alt_kind, sizeof (alt_kind)); - if (ioctl(fd, SENSOR_IOCTL_TYPE, &kind) == 0) { - warnx("TEST FAILED: SENSIOR_IOCTL_TYPE succeeded on EIO " + if (ioctl(fd, SENSOR_IOCTL_KIND, &kind) == 0) { + warnx("TEST FAILED: SENSOR_IOCTL_KIND succeeded on EIO " "sensor"); error_exit = EXIT_FAILURE; } if (errno != exp) { - warnx("TEST FAILED: SENSIOR_IOCTL_TYPE got errno %d, " + warnx("TEST FAILED: SENSOR_IOCTL_KIND got errno %d, " "expected %d", errno, exp); error_exit = EXIT_FAILURE; } if (memcmp(&kind, &alt_kind, sizeof (alt_kind)) != 0) { - warnx("TEST FAILED: SENSIOR_IOCTL_TYPE modified data on error"); + warnx("TEST FAILED: SENSOR_IOCTL_KIND modified data on error"); error_exit = EXIT_FAILURE; } } @@ -60,25 +60,25 @@ error_kind(int fd, int exp) static void error_temp(int fd, int exp) { - sensor_ioctl_temperature_t temp, alt_temp; + sensor_ioctl_scalar_t scalar, alt_scalar; - arc4random_buf(&alt_temp, sizeof (alt_temp)); - (void) memcpy(&temp, &alt_temp, sizeof (alt_temp)); + arc4random_buf(&alt_scalar, sizeof (alt_scalar)); + (void) memcpy(&scalar, &alt_scalar, sizeof (alt_scalar)); - if (ioctl(fd, SENSOR_IOCTL_TEMPERATURE, &temp) == 0) { - warnx("TEST FAILED: SENSIOR_IOCTL_TEMPERATURE suceeded on " + if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) == 0) { + warnx("TEST FAILED: SENSIOR_IOCTL_SCALAR suceeded on " "EIO sensor"); error_exit = EXIT_FAILURE; } if (errno != exp) { - warnx("TEST FAILED: SENSIOR_IOCTL_TEMPERATURE got errno %d, " + warnx("TEST FAILED: SENSIOR_IOCTL_SCALAR got errno %d, " "expected %d", errno, EIO); error_exit = EXIT_FAILURE; } - if (memcmp(&temp, &alt_temp, sizeof (alt_temp)) != 0) { - warnx("TEST FAILED: SENSIOR_IOCTL_TEMPERATURE modified " + if (memcmp(&scalar, &alt_scalar, sizeof (alt_scalar)) != 0) { + warnx("TEST FAILED: SENSIOR_IOCTL_SCALAR modified " "data on error"); error_exit = EXIT_FAILURE; } diff --git a/usr/src/test/os-tests/tests/ksensor/ksensor_sread.c b/usr/src/test/os-tests/tests/ksensor/ksensor_sread.c index fef8b78f73..42be85f10e 100644 --- a/usr/src/test/os-tests/tests/ksensor/ksensor_sread.c +++ b/usr/src/test/os-tests/tests/ksensor/ksensor_sread.c @@ -58,7 +58,7 @@ main(int argc, const char *argv[]) char buf[PATH_MAX]; uint32_t sens, inst; struct timespec ts; - sensor_ioctl_temperature_t temp; + sensor_ioctl_scalar_t scalar; /* 0s based */ sens = arc4random_uniform(nsensors); @@ -73,15 +73,15 @@ main(int argc, const char *argv[]) goto wait; } - bzero(&temp, sizeof (temp)); - if (ioctl(fd, SENSOR_IOCTL_TEMPERATURE, &temp) != 0) { - warn("failed to get sensor temp on %s", buf); + bzero(&scalar, sizeof (scalar)); + if (ioctl(fd, SENSOR_IOCTL_SCALAR, &scalar) != 0) { + warn("failed to get sensor temperature on %s", buf); } - if (temp.sit_unit != SENSOR_UNIT_CELSIUS) { + if (scalar.sis_unit != SENSOR_UNIT_CELSIUS) { warnx("data from sensor %s looks off, expected sensor " "to indicate Celsius, but instead %u", - temp.sit_unit); + scalar.sis_unit); } (void) close(fd); diff --git a/usr/src/test/os-tests/tests/ksensor/ksensor_stress.ksh b/usr/src/test/os-tests/tests/ksensor/ksensor_stress.ksh index 805e464eb0..9a27a151ff 100644 --- a/usr/src/test/os-tests/tests/ksensor/ksensor_stress.ksh +++ b/usr/src/test/os-tests/tests/ksensor/ksensor_stress.ksh @@ -50,7 +50,7 @@ fi if [[ ! -L "$sensor_base/test.temp.0.1" ]]; then - printf "missing ksensor test data, ksensor_temp driver loaded\n" 2>&1 + printf "missing ksensor test data, ksensor_tstp driver loaded?\n" 2>&1 exit 1 fi 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/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/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/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/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/intel/io/amdf17nbdf/amdf17nbdf.c b/usr/src/uts/intel/io/amdf17nbdf/amdf17nbdf.c index 6b7da6a99a..7be8a4a9f8 100644 --- a/usr/src/uts/intel/io/amdf17nbdf/amdf17nbdf.c +++ b/usr/src/uts/intel/io/amdf17nbdf/amdf17nbdf.c @@ -684,13 +684,14 @@ amdf17nbdf_ioctl_kind(intptr_t arg, int mode) } static int -amdf17nbdf_ioctl_temp(amdf17nbdf_t *nbdf, minor_t minor, intptr_t arg, int mode) +amdf17nbdf_ioctl_scalar(amdf17nbdf_t *nbdf, minor_t minor, intptr_t arg, + int mode) { amdf17nb_t *nb; hrtime_t diff; - sensor_ioctl_temperature_t temp; + sensor_ioctl_scalar_t scalar; - bzero(&temp, sizeof (temp)); + bzero(&scalar, sizeof (scalar)); mutex_enter(&nbdf->amd_nbdf_lock); nb = amdf17nbdf_lookup_nb(nbdf, minor); @@ -710,12 +711,12 @@ amdf17nbdf_ioctl_temp(amdf17nbdf_t *nbdf, minor_t minor, intptr_t arg, int mode) } } - temp.sit_unit = SENSOR_UNIT_CELSIUS; - temp.sit_temp = nb->amd_nb_temp; - temp.sit_gran = AMDF17_THERMAL_GRANULARITY; + scalar.sis_unit = SENSOR_UNIT_CELSIUS; + scalar.sis_value = nb->amd_nb_temp; + scalar.sis_gran = AMDF17_THERMAL_GRANULARITY; mutex_exit(&nbdf->amd_nbdf_lock); - if (ddi_copyout(&temp, (void *)arg, sizeof (temp), + if (ddi_copyout(&scalar, (void *)arg, sizeof (scalar), mode & FKIOCTL) != 0) { return (EFAULT); } @@ -737,10 +738,10 @@ amdf17nbdf_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 (amdf17nbdf_ioctl_kind(arg, mode)); - case SENSOR_IOCTL_TEMPERATURE: - return (amdf17nbdf_ioctl_temp(nbdf, m, arg, mode)); + case SENSOR_IOCTL_SCALAR: + return (amdf17nbdf_ioctl_scalar(nbdf, m, arg, mode)); default: return (ENOTTY); } diff --git a/usr/src/uts/intel/io/amdnbtemp/amdnbtemp.c b/usr/src/uts/intel/io/amdnbtemp/amdnbtemp.c index 1330f8563f..17934520fd 100644 --- a/usr/src/uts/intel/io/amdnbtemp/amdnbtemp.c +++ b/usr/src/uts/intel/io/amdnbtemp/amdnbtemp.c @@ -103,7 +103,7 @@ typedef struct amdnbtemp { static void *amdnbtemp_state; static int -amdnbtemp_read(void *arg, sensor_ioctl_temperature_t *temp) +amdnbtemp_read(void *arg, sensor_ioctl_scalar_t *scalar) { amdnbtemp_t *at = arg; @@ -120,9 +120,9 @@ amdnbtemp_read(void *arg, sensor_ioctl_temperature_t *temp) at->at_temp -= AMDNBTEMP_TEMP_ADJUST; } - temp->sit_unit = SENSOR_UNIT_CELSIUS; - temp->sit_gran = AMDNBTEMP_GRANULARITY; - temp->sit_temp = at->at_temp; + scalar->sis_unit = SENSOR_UNIT_CELSIUS; + scalar->sis_gran = AMDNBTEMP_GRANULARITY; + scalar->sis_value = at->at_temp; mutex_exit(&at->at_mutex); return (0); @@ -130,7 +130,7 @@ amdnbtemp_read(void *arg, sensor_ioctl_temperature_t *temp) static const ksensor_ops_t amdnbtemp_temp_ops = { .kso_kind = ksensor_kind_temperature, - .kso_temp = amdnbtemp_read + .kso_scalar = amdnbtemp_read }; static void diff --git a/usr/src/uts/intel/io/coretemp/coretemp.c b/usr/src/uts/intel/io/coretemp/coretemp.c index ee2d143554..bea8078002 100644 --- a/usr/src/uts/intel/io/coretemp/coretemp.c +++ b/usr/src/uts/intel/io/coretemp/coretemp.c @@ -259,7 +259,7 @@ coretemp_update(coretemp_t *ct, coretemp_sensor_t *sensor, cmi_hdl_t hdl) } static int -coretemp_read(void *arg, sensor_ioctl_temperature_t *sit) +coretemp_read(void *arg, sensor_ioctl_scalar_t *scalar) { coretemp_sensor_t *sensor = arg; coretemp_t *ct = sensor->cs_coretemp; @@ -313,10 +313,10 @@ coretemp_read(void *arg, sensor_ioctl_temperature_t *sit) sensor->cs_temperature = sensor->cs_tjmax - reading; sensor->cs_resolution = resolution; - sit->sit_unit = SENSOR_UNIT_CELSIUS; - sit->sit_temp = sensor->cs_temperature; - sit->sit_gran = CORETEMP_GRANULARITY; - sit->sit_prec = sensor->cs_resolution; + scalar->sis_unit = SENSOR_UNIT_CELSIUS; + scalar->sis_value = sensor->cs_temperature; + scalar->sis_gran = CORETEMP_GRANULARITY; + scalar->sis_prec = sensor->cs_resolution; mutex_exit(&ct->coretemp_mutex); return (0); @@ -324,7 +324,7 @@ coretemp_read(void *arg, sensor_ioctl_temperature_t *sit) static const ksensor_ops_t coretemp_temp_ops = { .kso_kind = ksensor_kind_temperature, - .kso_temp = coretemp_read + .kso_scalar = coretemp_read }; static void diff --git a/usr/src/uts/intel/io/pchtemp/pchtemp.c b/usr/src/uts/intel/io/pchtemp/pchtemp.c index 4aeb098112..2cfd7ae806 100644 --- a/usr/src/uts/intel/io/pchtemp/pchtemp.c +++ b/usr/src/uts/intel/io/pchtemp/pchtemp.c @@ -137,7 +137,7 @@ pchtemp_read_check(pchtemp_t *pch) } static int -pchtemp_read(void *arg, sensor_ioctl_temperature_t *sit) +pchtemp_read(void *arg, sensor_ioctl_scalar_t *scalar) { uint16_t temp, ctt, tahv, talv; uint8_t tsel; @@ -175,9 +175,9 @@ pchtemp_read(void *arg, sensor_ioctl_temperature_t *sit) } pch->pcht_temp = (temp & PCHTEMP_REG_TEMP_TSR) - PCHTEMP_TEMP_OFFSET; - sit->sit_unit = SENSOR_UNIT_CELSIUS; - sit->sit_gran = PCHTEMP_TEMP_RESOLUTION; - sit->sit_temp = pch->pcht_temp; + scalar->sis_unit = SENSOR_UNIT_CELSIUS; + scalar->sis_gran = PCHTEMP_TEMP_RESOLUTION; + scalar->sis_value = pch->pcht_temp; mutex_exit(&pch->pcht_mutex); return (0); @@ -185,7 +185,7 @@ pchtemp_read(void *arg, sensor_ioctl_temperature_t *sit) static const ksensor_ops_t pchtemp_temp_ops = { .kso_kind = ksensor_kind_temperature, - .kso_temp = pchtemp_read + .kso_scalar = pchtemp_read }; static void -- cgit v1.2.3 From 1718c31669d146508ea805e88322f5b74d892762 Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Thu, 30 Jul 2020 19:11:57 -0700 Subject: 13081 add mlxcx temp sensor Reviewed by: Alex Wilson Reviewed by: Andy Fiddaman Reviewed by: Paul Winder Approved by: Dan McDonald --- usr/src/man/man7d/mlxcx.7d | 4 +- usr/src/uts/common/Makefile.files | 2 +- usr/src/uts/common/io/mlxcx/mlxcx.c | 10 +++ usr/src/uts/common/io/mlxcx/mlxcx.h | 22 +++++ usr/src/uts/common/io/mlxcx/mlxcx_cmd.c | 10 +++ usr/src/uts/common/io/mlxcx/mlxcx_reg.h | 28 +++++++ usr/src/uts/common/io/mlxcx/mlxcx_sensor.c | 126 +++++++++++++++++++++++++++++ 7 files changed, 200 insertions(+), 2 deletions(-) create mode 100644 usr/src/uts/common/io/mlxcx/mlxcx_sensor.c (limited to 'usr/src/uts/common') diff --git a/usr/src/man/man7d/mlxcx.7d b/usr/src/man/man7d/mlxcx.7d index d7b0cf8ad9..ccbc257641 100644 --- a/usr/src/man/man7d/mlxcx.7d +++ b/usr/src/man/man7d/mlxcx.7d @@ -11,7 +11,7 @@ .\" .\" Copyright 2020 the University of Queensland .\" -.Dd April 9, 2020 +.Dd August 27, 2020 .Dt MLXCX 7D .Os .Sh NAME @@ -44,6 +44,8 @@ Promiscuous access via LED control .It Transceiver information +.It +Internal temperature sensors .El .Pp At this time, the driver does not support Large Send Offload (LSO), energy diff --git a/usr/src/uts/common/Makefile.files b/usr/src/uts/common/Makefile.files index 4a44510cb8..5f38c6eb5f 100644 --- a/usr/src/uts/common/Makefile.files +++ b/usr/src/uts/common/Makefile.files @@ -2284,4 +2284,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/io/mlxcx/mlxcx.c b/usr/src/uts/common/io/mlxcx/mlxcx.c index 6421b47126..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; @@ -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! */ diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.h b/usr/src/uts/common/io/mlxcx/mlxcx.h index dd91ea3734..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 { @@ -1172,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; }; /* @@ -1447,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 3cb531df39..32c40ec3ea 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx_cmd.c @@ -1688,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 ("???"); } @@ -1737,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_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 +#include + +/* + * 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); +} -- cgit v1.2.3 From c6795799963479a5ddb9b97ebb4cf6c1c97c1fba Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Wed, 9 Sep 2020 22:30:42 -0700 Subject: 13119 Want support for SMBIOS 3.4 Reviewed by: C Fraire Reviewed by: Toomas Soome Approved by: Dan McDonald --- usr/src/cmd/smbios/smbios.c | 22 +- usr/src/common/smbios/smb_info.c | 42 ++- usr/src/common/smbios/smb_open.c | 1 + usr/src/test/util-tests/tests/smbios/smbios.c | 19 +- usr/src/test/util-tests/tests/smbios/smbios_test.h | 5 + .../util-tests/tests/smbios/smbios_test_slot.c | 375 ++++++++++++++++++--- usr/src/uts/common/sys/smbios.h | 38 ++- usr/src/uts/common/sys/smbios_impl.h | 18 + 8 files changed, 466 insertions(+), 54 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/cmd/smbios/smbios.c b/usr/src/cmd/smbios/smbios.c index 5597e04fc5..dedfe29e9c 100644 --- a/usr/src/cmd/smbios/smbios.c +++ b/usr/src/cmd/smbios/smbios.c @@ -22,6 +22,7 @@ /* * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright (c) 2017, Joyent, Inc. + * Copyright 2020 Oxide Computer Company * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -716,7 +717,7 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) oprintf(fp, " Slot Peer %u:\n", i); oprintf(fp, " Segment group: %u\n", peer[i].smblp_group); - oprintf(fp, " Bus/Device/Function: %u/%u/%u", + oprintf(fp, " Bus/Device/Function: %u/%u/%u\n", peer[i].smblp_bus, peer[i].smblp_device, peer[i].smblp_function); oprintf(fp, " Electrical width: %u\n", @@ -725,6 +726,25 @@ print_slot(smbios_hdl_t *shp, id_t id, FILE *fp) smbios_info_slot_peers_free(shp, npeers, peer); } + + if (s.smbl_info != 0) { + if (s.smbl_type >= SMB_SLT_PCIE && + s.smbl_type <= SMB_SLT_PCIEG6P) { + oprintf(fp, " PCIe Generation: %d\n", s.smbl_info); + } else { + oprintf(fp, " Slot Type: 0x%x\n", s.smbl_info); + } + } + + if (s.smbl_pwidth != 0) { + desc_printf(smbios_slot_width_desc(s.smbl_pwidth), + fp, " Physical Width: 0x%x", s.smbl_pwidth); + } + + if (s.smbl_pitch != 0) { + oprintf(fp, " Slot Pitch: %u.%u mm\n", s.smbl_pitch / 100, + s.smbl_pitch % 100); + } } static void diff --git a/usr/src/common/smbios/smb_info.c b/usr/src/common/smbios/smb_info.c index 47c19e7fcb..9aba4deba8 100644 --- a/usr/src/common/smbios/smb_info.c +++ b/usr/src/common/smbios/smb_info.c @@ -22,6 +22,7 @@ /* * Copyright 2015 OmniTI Computer Consulting, Inc. All rights reserved. * Copyright 2019 Joyent, Inc. + * Copyright 2020 Oxide Computer Company * Copyright 2010 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -231,14 +232,25 @@ smb_info_strptr(const smb_struct_t *stp, uint8_t off, int *n) return (smb_strptr(stp, 0)); } +static void +smb_info_bcopy_offset(const smb_header_t *hp, void *dst, size_t dstlen, + size_t offset) +{ + if (offset >= hp->smbh_len) { + bzero(dst, dstlen); + } else if (offset + dstlen > hp->smbh_len) { + size_t nvalid = MIN(hp->smbh_len - offset, dstlen); + bcopy((char *)hp + offset, dst, nvalid); + bzero((char *)dst + nvalid, dstlen - nvalid); + } else { + bcopy((char *)hp + offset, dst, dstlen); + } +} + static void smb_info_bcopy(const smb_header_t *hp, void *dst, size_t dstlen) { - if (dstlen > hp->smbh_len) { - bcopy(hp, dst, hp->smbh_len); - bzero((char *)dst + hp->smbh_len, dstlen - hp->smbh_len); - } else - bcopy(hp, dst, dstlen); + return (smb_info_bcopy_offset(hp, dst, dstlen, 0)); } smbios_entry_point_t @@ -674,6 +686,8 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp) { const smb_struct_t *stp = smb_lookup_id(shp, id); smb_slot_t s; + smb_slot_cont_t cont; + size_t off; if (stp == NULL) return (-1); /* errno is set for us */ @@ -701,6 +715,24 @@ smbios_info_slot(smbios_hdl_t *shp, id_t id, smbios_slot_t *sp) sp->smbl_npeers = s.smbsl_npeers; } + if (!smb_libgteq(shp, SMB_VERSION_34)) { + return (0); + } + + /* + * In SMBIOS 3.4, several members were added to follow the variable + * number of peers. These are defined to start at byte 0x14 + 5 * + * npeers. If the table is from before 3.4, we simple zero things out. + * Otherwise we check if the length covers the peers and this addendum + * to include it as the table length is allowed to be less than this and + * not include it. + */ + off = SMB_SLOT_CONT_START + 5 * s.smbsl_npeers; + smb_info_bcopy_offset(stp->smbst_hdr, &cont, sizeof (cont), off); + sp->smbl_info = cont.smbsl_info; + sp->smbl_pwidth = cont.smbsl_pwidth; + sp->smbl_pitch = cont.smbsl_pitch; + return (0); } diff --git a/usr/src/common/smbios/smb_open.c b/usr/src/common/smbios/smb_open.c index 372b2b619b..6747c84499 100644 --- a/usr/src/common/smbios/smb_open.c +++ b/usr/src/common/smbios/smb_open.c @@ -231,6 +231,7 @@ smbios_bufopen(const smbios_entry_t *ep, const void *buf, size_t len, case SMB_VERSION_31: case SMB_VERSION_32: case SMB_VERSION_33: + case SMB_VERSION_34: break; default: return (smb_open_error(shp, errp, ESMB_VERSION)); diff --git a/usr/src/test/util-tests/tests/smbios/smbios.c b/usr/src/test/util-tests/tests/smbios/smbios.c index 364cb9344f..429d4f81be 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios.c +++ b/usr/src/test/util-tests/tests/smbios/smbios.c @@ -11,6 +11,7 @@ /* * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* @@ -219,7 +220,23 @@ static const smbios_test_t smbios_tests[] = { .st_mktable = smbios_test_slot_mktable, .st_canopen = B_TRUE, .st_verify = smbios_test_slot_verify, - .st_desc = "slot tests" + .st_desc = "slot 3.2" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION_34, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_slot_mktable_34_nopeers, + .st_canopen = B_TRUE, + .st_verify = smbios_test_slot_verify_34_nopeers, + .st_desc = "slot 3.4 without peers" + }, { + .st_entry = SMBIOS_ENTRY_POINT_30, + .st_tvers = SMB_VERSION_34, + .st_libvers = SMB_VERSION, + .st_mktable = smbios_test_slot_mktable_34_peers, + .st_canopen = B_TRUE, + .st_verify = smbios_test_slot_verify_34_peers, + .st_desc = "slot 3.4 with peers" }, { .st_entry = SMBIOS_ENTRY_POINT_30, .st_tvers = SMB_VERSION, diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test.h b/usr/src/test/util-tests/tests/smbios/smbios_test.h index 62baed7813..c6490f1d13 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios_test.h +++ b/usr/src/test/util-tests/tests/smbios/smbios_test.h @@ -11,6 +11,7 @@ /* * Copyright 2019 Robert Mustacchi + * Copyright 2020 Oxide Computer Company */ #ifndef _SMBIOS_TEST_H @@ -78,7 +79,11 @@ typedef struct smbios_test { * Test functions */ extern boolean_t smbios_test_slot_mktable(smbios_test_table_t *); +extern boolean_t smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *); +extern boolean_t smbios_test_slot_mktable_34_peers(smbios_test_table_t *); extern boolean_t smbios_test_slot_verify(smbios_hdl_t *); +extern boolean_t smbios_test_slot_verify_34_nopeers(smbios_hdl_t *); +extern boolean_t smbios_test_slot_verify_34_peers(smbios_hdl_t *); extern boolean_t smbios_test_badvers_mktable(smbios_test_table_t *); extern boolean_t smbios_test_memdevice_mktable_32(smbios_test_table_t *); diff --git a/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c b/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c index d84cc10e91..95a709a088 100644 --- a/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c +++ b/usr/src/test/util-tests/tests/smbios/smbios_test_slot.c @@ -11,6 +11,7 @@ /* * Copyright (c) 2018, Joyent, Inc. + * Copyright 2020 Oxide Computer Company */ /* @@ -20,6 +21,29 @@ #include "smbios_test.h" static const char *smbios_test_name = "The One Slot"; +static uint8_t smbios_slot_bus = 0x42; +static uint8_t smbios_slot_df = 0x23; +static uint8_t smbios_slot_info = 0x65; +static uint16_t smbios_slot_pitch = 0x12af; + +static void +smbios_test_slot_fill(smb_slot_t *slot) +{ + bzero(slot, sizeof (smb_slot_t)); + slot->smbsl_hdr.smbh_type = SMB_TYPE_SLOT; + slot->smbsl_hdr.smbh_len = sizeof (smb_slot_t); + slot->smbsl_name = 1; + slot->smbsl_type = SMB_SLT_PCIE3G16; + slot->smbsl_width = SMB_SLW_16X; + slot->smbsl_length = SMB_SLL_SHORT; + slot->smbsl_id = htole16(1); + slot->smbsl_ch1 = SMB_SLCH1_33V; + slot->smbsl_ch2 = SMB_SLCH2_PME; + slot->smbsl_sg = htole16(1); + slot->smbsl_bus = smbios_slot_bus; + slot->smbsl_df = smbios_slot_df; + slot->smbsl_dbw = SMB_SLW_16X; +} boolean_t smbios_test_slot_mktable(smbios_test_table_t *table) @@ -28,21 +52,11 @@ smbios_test_slot_mktable(smbios_test_table_t *table) smb_slot_peer_t peers[2]; const uint8_t endstring = 0; - slot.smbsl_hdr.smbh_type = SMB_TYPE_SLOT; - slot.smbsl_hdr.smbh_len = sizeof (smb_slot_t) + sizeof (peers); - - slot.smbsl_name = 1; - slot.smbsl_type = SMB_SLT_PCIE3G16; - slot.smbsl_width = SMB_SLW_16X; - slot.smbsl_length = SMB_SLL_SHORT; - slot.smbsl_id = htole16(1); - slot.smbsl_ch1 = SMB_SLCH1_33V; - slot.smbsl_ch2 = SMB_SLCH2_PME; - slot.smbsl_sg = htole16(1); - slot.smbsl_bus = 0x42; - slot.smbsl_df = 0x23; - slot.smbsl_dbw = SMB_SLW_16X; + smbios_test_slot_fill(&slot); + + slot.smbsl_hdr.smbh_len += sizeof (peers); slot.smbsl_npeers = 2; + peers[0].smbspb_group_no = htole16(1); peers[0].smbspb_bus = 0x42; peers[0].smbspb_df = 0x42; @@ -64,6 +78,121 @@ smbios_test_slot_mktable(smbios_test_table_t *table) return (B_TRUE); } +/* + * 3.4 introduced additional data after peers. This verison constructs a variant + * with no peers. + */ +boolean_t +smbios_test_slot_mktable_34_nopeers(smbios_test_table_t *table) +{ + smb_slot_t slot; + smb_slot_cont_t cont; + const uint8_t endstring = 0; + + smbios_test_slot_fill(&slot); + slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + sizeof (cont); + + cont.smbsl_info = smbios_slot_info; + cont.smbsl_pwidth = SMB_SLW_32X; + cont.smbsl_pitch = htole16(smbios_slot_pitch); + + (void) smbios_test_table_append(table, &slot, sizeof (slot)); + /* + * Append a raw zero to fill in the gaps that the peers would have had + * so the cont structure starts at the right offset. + */ + (void) smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + (void) smbios_test_table_append_raw(table, &cont, sizeof (cont)); + (void) smbios_test_table_append_string(table, smbios_test_name); + (void) smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + smbios_test_table_append_eot(table); + return (B_TRUE); +} + +boolean_t +smbios_test_slot_mktable_34_peers(smbios_test_table_t *table) +{ + smb_slot_t slot; + smb_slot_cont_t cont; + smb_slot_peer_t peers[1]; + const uint8_t endstring = 0; + + smbios_test_slot_fill(&slot); + slot.smbsl_npeers = 1; + slot.smbsl_hdr.smbh_len = SMB_SLOT_CONT_START + 5 * slot.smbsl_npeers + + sizeof (cont); + + peers[0].smbspb_group_no = htole16(1); + peers[0].smbspb_bus = 0x42; + peers[0].smbspb_df = 0x9a; + peers[0].smbspb_width = SMB_SLW_8X; + + cont.smbsl_info = smbios_slot_info; + cont.smbsl_pwidth = SMB_SLW_32X; + cont.smbsl_pitch = htole16(smbios_slot_pitch); + + (void) smbios_test_table_append(table, &slot, sizeof (slot)); + (void) smbios_test_table_append_raw(table, peers, sizeof (peers)); + (void) smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + (void) smbios_test_table_append_raw(table, &cont, sizeof (cont)); + (void) smbios_test_table_append_string(table, smbios_test_name); + (void) smbios_test_table_append_raw(table, &endstring, + sizeof (endstring)); + smbios_test_table_append_eot(table); + return (B_TRUE); +} + + +static boolean_t +smbios_test_slot_common(smbios_slot_t *slot) +{ + uint_t errs = 0; + + if (strcmp(slot->smbl_name, smbios_test_name) != 0) { + warnx("slot name mismatch, expected %s, found %s", + smbios_test_name, slot->smbl_name); + errs++; + } + + if (slot->smbl_type != SMB_SLT_PCIE3G16) { + warnx("incorrect slot type, found %u", slot->smbl_type); + errs++; + } + + if (slot->smbl_width != SMB_SLW_16X) { + warnx("incorrect slot width, found %u", slot->smbl_width); + errs++; + } + + if (slot->smbl_length != SMB_SLL_SHORT) { + warnx("incorrect slot length, found %u", slot->smbl_length); + errs++; + } + + if (slot->smbl_dbw != SMB_SLW_16X) { + warnx("incorrect slot data bus width, found %u", + slot->smbl_dbw); + errs++; + } + + if (slot->smbl_bus != smbios_slot_bus) { + warnx("incorrect slot bus id, found 0x%x\n", slot->smbl_bus); + } + + if (slot->smbl_df != smbios_slot_df) { + warnx("incorrect slot df id, found 0x%x\n", slot->smbl_df); + } + + if (errs > 0) { + return (B_FALSE); + } + + return (B_TRUE); +} + boolean_t smbios_test_slot_verify(smbios_hdl_t *hdl) { @@ -85,32 +214,7 @@ smbios_test_slot_verify(smbios_hdl_t *hdl) return (B_FALSE); } - /* - * Verify everything we'd expect about the slot. - */ - if (strcmp(slot.smbl_name, smbios_test_name) != 0) { - warnx("slot name mismatch, expected %s, found %s", - smbios_test_name, slot.smbl_name); - errs++; - } - - if (slot.smbl_type != SMB_SLT_PCIE3G16) { - warnx("incorrect slot type, found %u", slot.smbl_type); - errs++; - } - - if (slot.smbl_width != SMB_SLW_16X) { - warnx("incorrect slot width, found %u", slot.smbl_width); - errs++; - } - - if (slot.smbl_length != SMB_SLL_SHORT) { - warnx("incorrect slot length, found %u", slot.smbl_length); - errs++; - } - - if (slot.smbl_dbw != SMB_SLW_16X) { - warnx("incorrect slot data bus width, found %u", slot.smbl_dbw); + if (!smbios_test_slot_common(&slot)) { errs++; } @@ -127,8 +231,7 @@ smbios_test_slot_verify(smbios_hdl_t *hdl) } if (npeers != 2) { - warnx("got wrong number of slot peers: %u\n", - npeers); + warnx("got wrong number of slot peers: %u", npeers); return (B_FALSE); } @@ -180,6 +283,194 @@ smbios_test_slot_verify(smbios_hdl_t *hdl) smbios_info_slot_peers_free(hdl, npeers, peers); + if (slot.smbl_info != 0) { + warnx("found wrong slot info: 0x%x", slot.smbl_info); + errs++; + } + + if (slot.smbl_pwidth != 0) { + warnx("found wrong slot physical width: 0x%x", + slot.smbl_pwidth); + errs++; + } + + if (slot.smbl_pitch != 0) { + warnx("found wrong slot pitch: 0x%x", slot.smbl_pitch); + errs++; + } + + if (errs > 0) { + return (B_FALSE); + } + + return (B_TRUE); +} + +boolean_t +smbios_test_slot_verify_34_nopeers(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_slot_t slot; + uint_t npeers; + smbios_slot_peer_t *peers; + uint_t errs = 0; + + if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) { + warnx("failed to lookup SMBIOS slot: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) { + warnx("failed to get SMBIOS slot info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (!smbios_test_slot_common(&slot)) { + errs++; + } + + if (slot.smbl_npeers != 0) { + warnx("incorrect number of slot peers, found %u", + slot.smbl_npeers); + errs++; + } + + if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) { + warnx("failed to get SMBIOS peer info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (npeers != 0) { + warnx("got wrong number of slot peers: %u", npeers); + errs++; + } + + if (peers != NULL) { + warnx("expected NULL peers pointer, but found %p", peers); + errs++; + } + + smbios_info_slot_peers_free(hdl, npeers, peers); + + if (slot.smbl_info != smbios_slot_info) { + warnx("found wrong slot info: 0x%x, expected 0x%x", + slot.smbl_info, smbios_slot_info); + errs++; + } + + if (slot.smbl_pwidth != SMB_SLW_32X) { + warnx("found wrong slot physical width: 0x%x, expected 0x%x", + slot.smbl_pwidth, SMB_SLW_32X); + errs++; + } + + if (slot.smbl_pitch != smbios_slot_pitch) { + warnx("found wrong slot pitch: 0x%x, expected 0x%x", + slot.smbl_pitch, smbios_slot_pitch); + errs++; + } + + if (errs > 0) { + return (B_FALSE); + } + + return (B_TRUE); +} + +boolean_t +smbios_test_slot_verify_34_peers(smbios_hdl_t *hdl) +{ + smbios_struct_t sp; + smbios_slot_t slot; + uint_t npeers; + smbios_slot_peer_t *peers; + uint_t errs = 0; + + if (smbios_lookup_type(hdl, SMB_TYPE_SLOT, &sp) == -1) { + warnx("failed to lookup SMBIOS slot: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (smbios_info_slot(hdl, sp.smbstr_id, &slot) != 0) { + warnx("failed to get SMBIOS slot info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (!smbios_test_slot_common(&slot)) { + errs++; + } + + if (slot.smbl_npeers != 1) { + warnx("incorrect number of slot peers, found %u", + slot.smbl_npeers); + errs++; + } + + if (smbios_info_slot_peers(hdl, sp.smbstr_id, &npeers, &peers) != 0) { + warnx("failed to get SMBIOS peer info: %s", + smbios_errmsg(smbios_errno(hdl))); + return (B_FALSE); + } + + if (npeers != 1) { + warnx("got wrong number of slot peers: %u", npeers); + errs++; + } + + if (peers[0].smblp_group != 1) { + warnx("incorrect group for peer 0: %u", peers[0].smblp_group); + errs++; + } + + if (peers[0].smblp_data_width != SMB_SLW_8X) { + warnx("incorrect data width for peer 0: %u", + peers[0].smblp_data_width); + errs++; + } + + if (peers[0].smblp_bus != 0x42) { + warnx("incorrect PCI bus for peer 0: %u", + peers[0].smblp_bus); + errs++; + } + + if (peers[0].smblp_device != (0x9a >> 3)) { + warnx("incorrect PCI device for peer 0: %u", + peers[0].smblp_device); + errs++; + } + + if (peers[0].smblp_function != (0x9a & 0x7)) { + warnx("incorrect PCI function for peer 0: %u", + peers[0].smblp_function); + errs++; + } + + smbios_info_slot_peers_free(hdl, npeers, peers); + + if (slot.smbl_info != smbios_slot_info) { + warnx("found wrong slot info: 0x%x, expected 0x%x", + slot.smbl_info, smbios_slot_info); + errs++; + } + + if (slot.smbl_pwidth != SMB_SLW_32X) { + warnx("found wrong slot physical width: 0x%x, expected 0x%x", + slot.smbl_pwidth, SMB_SLW_32X); + errs++; + } + + if (slot.smbl_pitch != smbios_slot_pitch) { + warnx("found wrong slot pitch: 0x%x, expected 0x%x", + slot.smbl_pitch, smbios_slot_pitch); + errs++; + } + if (errs > 0) { return (B_FALSE); } 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,8 +251,25 @@ 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. */ -- cgit v1.2.3 From 9cfcc091666d5546e419c22f4963474d11673f5e Mon Sep 17 00:00:00 2001 From: Toomas Soome Date: Wed, 2 Sep 2020 09:56:02 +0300 Subject: 13137 zfs: warn: inconsistent indenting Reviewed by: Marco van Wieringen Reviewed by: C Fraire Approved by: Robert Mustacchi --- usr/src/uts/common/fs/zfs/lua/ldebug.c | 2 +- usr/src/uts/common/fs/zfs/metaslab.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'usr/src/uts/common') 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 794da5d27a..c46ee1bc20 100644 --- a/usr/src/uts/common/fs/zfs/metaslab.c +++ b/usr/src/uts/common/fs/zfs/metaslab.c @@ -2372,7 +2372,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, " -- cgit v1.2.3 From 73fb888b08574ef1b33df70ad8f9adc7f2508b41 Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Wed, 16 Sep 2020 16:23:43 +0100 Subject: OS-8233 LX: readlink("/proc//exe") can fail (#318) Reviewed by: Mike Zeller Approved by: Jason King --- usr/src/uts/common/brand/lx/procfs/lx_prvnops.c | 79 ++++++++++++++++++++++--- 1 file changed, 71 insertions(+), 8 deletions(-) (limited to 'usr/src/uts/common') 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//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//fd/ * Generate :[] links, if allowed. -- cgit v1.2.3 From 260b78324e5b8479cc94f897a36e996f026c3fef Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Sat, 5 Sep 2020 19:56:13 +0000 Subject: 13108 mlxcx fails to attach on system using pcplusmp after 12988 Reviewed by: Robert Mustacchi Reviewed by: Paul Winder Approved by: Dan McDonald --- usr/src/uts/common/io/mlxcx/mlxcx_intr.c | 55 +++++++++++++++++++++++++------- 1 file changed, 44 insertions(+), 11 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/io/mlxcx/mlxcx_intr.c b/usr/src/uts/common/io/mlxcx/mlxcx_intr.c index 10d8d19b2f..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. */ /* @@ -1195,12 +1196,17 @@ mlxcx_intr_setup(mlxcx_t *mlxp) 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); @@ -1281,11 +1287,30 @@ mlxcx_intr_setup(mlxcx_t *mlxp) offsetof(mlxcx_completion_queue_t, mlcq_eq_entry)); } - ret = ddi_intr_set_pri(mlxp->mlx_intr_handles[0], - mlxp->mlx_async_intr_pri); - if (ret != DDI_SUCCESS) { - mlxcx_warn(mlxp, "Failed to set interrupt priority to %u for " + 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); } @@ -1320,12 +1345,20 @@ mlxcx_intr_setup(mlxcx_t *mlxp) eqt = MLXCX_EQ_TYPE_RX; } - ret = ddi_intr_set_pri(mlxp->mlx_intr_handles[i], - mlxp->mlx_intr_pri); - if (ret != DDI_SUCCESS) { - mlxcx_warn(mlxp, "Failed to set interrupt priority to " - "%u for interrupt vector %d", mlxp->mlx_intr_pri, - i); + 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); } -- cgit v1.2.3 From b7a7784945b3504d0b69ea02a08e1cddb5578907 Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Sat, 5 Sep 2020 22:23:36 +0000 Subject: 13111 Want futimes(), lutimes() and timespec/timeval conversion macros Reviewed by: Robert Mustacchi Reviewed by: Marco van Wieringen Approved by: Dan McDonald --- usr/src/lib/libc/port/mapfile-vers | 6 + usr/src/lib/libc/port/sys/utimesys.c | 28 +- usr/src/man/man2/Makefile | 5 + usr/src/man/man2/utimes.2 | 58 ++- usr/src/man/man3head/Makefile | 9 + usr/src/man/man3head/timespec.3head | 106 +++++ usr/src/man/man3lib/libc.3lib | 251 +++++----- usr/src/pkg/manifests/system-header.mf | 7 + usr/src/pkg/manifests/system-kernel.man2.inc | 5 +- usr/src/pkg/manifests/system-test-libctest.mf | 3 + usr/src/prototypes/prototype.man3x | 2 +- usr/src/test/libc-tests/cfg/symbols/sys_time_h.cfg | 14 + usr/src/test/libc-tests/runfiles/default.run | 3 + usr/src/test/libc-tests/tests/Makefile | 4 +- usr/src/test/libc-tests/tests/utimes.c | 521 +++++++++++++++++++++ usr/src/uts/common/sys/time.h | 27 +- 16 files changed, 893 insertions(+), 156 deletions(-) create mode 100644 usr/src/man/man3head/timespec.3head create mode 100644 usr/src/test/libc-tests/tests/utimes.c (limited to 'usr/src/uts/common') diff --git a/usr/src/lib/libc/port/mapfile-vers b/usr/src/lib/libc/port/mapfile-vers index 6a4c274258..be5b7e73bf 100644 --- a/usr/src/lib/libc/port/mapfile-vers +++ b/usr/src/lib/libc/port/mapfile-vers @@ -78,6 +78,12 @@ $if _x86 && _ELF64 $add amd64 $endif +SYMBOL_VERSION ILLUMOS_0.34 { + protected: + futimes; + lutimes; +} ILLUMOS_0.33; + SYMBOL_VERSION ILLUMOS_0.33 { protected: c16rtomb; diff --git a/usr/src/lib/libc/port/sys/utimesys.c b/usr/src/lib/libc/port/sys/utimesys.c index dc917f27ae..55e53dbb53 100644 --- a/usr/src/lib/libc/port/sys/utimesys.c +++ b/usr/src/lib/libc/port/sys/utimesys.c @@ -24,6 +24,10 @@ * Use is subject to license terms. */ +/* + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. + */ + #include "lint.h" #include #include @@ -67,8 +71,8 @@ utime(const char *path, const struct utimbuf *times) return (utimensat(AT_FDCWD, path, tsp, 0)); } -int -utimes(const char *path, const struct timeval times[2]) +static int +utimes_impl(const char *path, const struct timeval times[2], int flag) { struct timeval ltimes[2]; timespec_t ts[2]; @@ -86,7 +90,19 @@ utimes(const char *path, const struct timeval times[2]) ts[1].tv_nsec = ltimes[1].tv_usec * 1000; tsp = ts; } - return (utimensat(AT_FDCWD, path, tsp, 0)); + return (utimensat(AT_FDCWD, path, tsp, flag)); +} + +int +utimes(const char *path, const struct timeval times[2]) +{ + return (utimes_impl(path, times, 0)); +} + +int +lutimes(const char *path, const struct timeval times[2]) +{ + return (utimes_impl(path, times, AT_SYMLINK_NOFOLLOW)); } #pragma weak _futimesat = futimesat @@ -115,3 +131,9 @@ futimesat(int fd, const char *path, const struct timeval times[2]) return (utimensat(fd, path, tsp, 0)); } + +int +futimes(int fd, const struct timeval times[2]) +{ + return (futimesat(fd, NULL, times)); +} diff --git a/usr/src/man/man2/Makefile b/usr/src/man/man2/Makefile index 556de2d03b..8f664a56fc 100644 --- a/usr/src/man/man2/Makefile +++ b/usr/src/man/man2/Makefile @@ -15,6 +15,7 @@ # Copyright 2013 Nexenta Systems, Inc. All rights reserved. # Copyright (c) 2018, Joyent, Inc. All rights reserved. # Copyright 2017 Peter Tribble +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # include $(SRC)/Makefile.master @@ -196,6 +197,7 @@ MANLINKS= _Exit.2 \ fstat.2 \ fstatat.2 \ fstatvfs.2 \ + futimes.2 \ futimesat.2 \ futimens.2 \ getaudit_addr.2 \ @@ -213,6 +215,7 @@ MANLINKS= _Exit.2 \ lchown.2 \ linkat.2 \ lstat.2 \ + lutimes.2 \ mkdirat.2 \ mknodat.2 \ openat.2 \ @@ -396,7 +399,9 @@ umount2.2 := LINKSRC = umount.2 unlinkat.2 := LINKSRC = unlink.2 futimens.2 := LINKSRC = utimes.2 +futimes.2 := LINKSRC = utimes.2 futimesat.2 := LINKSRC = utimes.2 +lutimes.2 := LINKSRC = utimes.2 utimensat.2 := LINKSRC = utimes.2 vforkx.2 := LINKSRC = vfork.2 diff --git a/usr/src/man/man2/utimes.2 b/usr/src/man/man2/utimes.2 index 69eee29879..404fea7180 100644 --- a/usr/src/man/man2/utimes.2 +++ b/usr/src/man/man2/utimes.2 @@ -43,18 +43,28 @@ .\" Portions Copyright (c) 1992, X/Open Company Limited. All Rights Reserved. .\" Copyright (c) 2009, Sun Microsystems, Inc. All Rights Reserved. .\" Copyright (c) 2014, Joyent, Inc. +.\" Copyright 2020 OmniOS Community Edition (OmniOSce) Association. .\" -.TH UTIMES 2 "Dec 20, 2014" +.TH UTIMES 2 "Sep 06, 2020" .SH NAME -utimes, futimesat \- set file access and modification times +utimes, lutimes, futimes, futimesat, utimens, utimensat \- set file access and modification times .SH SYNOPSIS -.LP .nf #include \fBint\fR \fButimes\fR(\fBconst char *\fR\fIpath\fR, \fBconst struct timeval\fR \fItimes\fR[2]); .fi +.LP +.nf +\fBint\fR \fBlutimes\fR(\fBconst char *\fR\fIpath\fR, \fBconst struct timeval\fR \fItimes\fR[2]); +.fi + +.LP +.nf +\fBint\fR \fBfutimes\fR(\fBint\fR \fIfildes\fR, \fBconst struct timeval\fR \fItimes\fR[2]); +.fi + .LP .nf \fBint\fR \fBfutimesat\fR(\fBint\fR \fIfildes\fR, \fBconst char *\fR\fIpath\fR, @@ -65,18 +75,27 @@ utimes, futimesat \- set file access and modification times .nf #include -\fBint\fR \fBfutimens\fR(\fBint\fR \fIfiledes\fR, \fBconst timespec_t\fR \fInstimes[2]\fR); +\fBint\fR \fBfutimens\fR(\fBint\fR \fIfildes\fR, \fBconst timespec_t\fR \fInstimes[2]\fR); -\fBint\fR \fButimensat\fR(\fBint\fR \fIfiledes\fR, \fBconst char *\fR\fIpath\fR, +\fBint\fR \fButimensat\fR(\fBint\fR \fIfildes\fR, \fBconst char *\fR\fIpath\fR, \fBconst timespec_t\fR \fInstimes[2]\fR, \fBint\fR \fIflag\fR); .SH DESCRIPTION -.LP The \fButimes()\fR function sets the access and modification times of the file pointed to by the \fIpath\fR argument to the value of the \fItimes\fR argument. It allows time specifications accurate to the microsecond. .sp .LP +The \fBlutimes()\fR function operates like \fButimes()\fR except if \fIpath\fR +points to a symbolic link; in that case \fBlutimes()\fR changes the access and +modifications times of the link, while \fButimes()\fR changes the file that +is referenced by the link. +.sp +.LP +The \fBfutimes()\fR function sets the access and modification times of the +file referenced by the file descriptor \fIfildes\fR. +.sp +.LP The \fBfutimesat()\fR function also sets access and modification times. See \fBfsattr\fR(5). If \fIpath\fR is a relative path name, however, \fBfutimesat()\fR resolves the path relative to the \fIfildes\fR argument @@ -84,7 +103,7 @@ rather than the current working directory. If \fIfildes\fR is set to \fBAT_FDCWD\fR, defined in <\fBfcntl.h\fR>, \fBfutimesat()\fR resolves the path relative to the current working directory. If \fIpath\fR is a null pointer, \fBfutimesat()\fR sets the access and modification times on the file referenced -by \fIfildes\fR. The \fIfildes\fR argument is ignored even when +by \fIfildes\fR. The \fIfildes\fR argument is ignored if \fBfutimesat()\fR is provided with an absolute path. .sp .LP @@ -107,28 +126,28 @@ The \fBfutimens()\fR and \fButimensat()\fR functions also set access and modification times; however, instead of taking \fBstruct timeval\fR, they take \fBtimespec_t\fR which allows for nanosecond granularity. The \fBfutimens()\fR function sets the access and modification times on the file descriptor -referenced by \fIfiledes\fR. +referenced by \fIfildes\fR. .sp .LP The \fButimensat()\fR function determines the file to set the access and -modification times in an similar way to \fBfutemsat()\fR. If the argument -\fIpath\fR is an absolute path, then the argument \fIfiledes\fR is ignored; +modification times in an similar way to \fBfutimesat()\fR. If the argument +\fIpath\fR is an absolute path, then the argument \fIfildes\fR is ignored; otherwise, \fIpath\fR is interpreted as a path relative to the directory -specified by \fIfiledes\fR. If \fIfiledes\fR is set to \fBAT_FDCWD\fR, then +specified by \fIfildes\fR. If \fIfildes\fR is set to \fBAT_FDCWD\fR, then \fIpath\fR is resolved relative to the current working directory. The behavior when encountering symbolic links may be controlled by the value of the \fIflag\fR argument. If the value of flag is the constant \fBAT_SYMLINK_NOFOLLOW\fR, then when a symbolic link is encountered while resolving a path, it will not be followed. Otherwise, the value of \fIflag\fR -should be \fB0\fR. +should be \fB0\fR. Note that, unlike \fBfutimesat()\fR, \fButimensat()\fR +does not accept a null pointer for the \fIpath\fR argument. .SH RETURN VALUES -.LP Upon successful completion, \fB0\fR is returned. Otherwise, \fB\(mi1\fR is returned, \fBerrno\fR is set to indicate the error, and the file times will not be affected. .SH ERRORS -.LP -The \fButimes()\fR, \fBfutimesat()\fR, \fBfutimens()\fR, and \fButimensat()\fR +The \fButimes()\fR, \fBlutimes()\fR, \fBfutimes()\fR, \fBfutimesat()\fR, +\fBfutimens()\fR, and \fButimensat()\fR functions will fail if: .sp .ne 2 @@ -147,9 +166,7 @@ process does not match the owner of the file and write access is denied. \fB\fBEFAULT\fR\fR .ad .RS 16n -The \fIpath\fR or \fItimes\fR argument points to an illegal address. For -\fBfutimesat()\fR, \fIpath\fR might have the value \fINULL\fR if the -\fIfildes\fR argument refers to a valid open file descriptor. +The \fIpath\fR or \fItimes\fR argument points to an illegal address. .RE .sp @@ -159,6 +176,7 @@ The \fIpath\fR or \fItimes\fR argument points to an illegal address. For .ad .RS 16n A signal was caught during the execution of the \fButimes()\fR, +\fBlutimes()\fR, \fBfutimes()\fR, \fBfutimesat()\fR, \fBfutimens()\fR, or \fButimensat()\fR functions. .RE @@ -270,7 +288,6 @@ length exceeds {\fIPATH_MAX\fR}. .RE .SH ATTRIBUTES -.LP See \fBattributes\fR(5) for descriptions of the following attributes: .sp @@ -290,6 +307,5 @@ Standard See below. .LP For \fButimes()\fR, \fButimensat()\fR and \fBfutimensat()\fR, see \fBstandards\fR(5). .SH SEE ALSO -.LP -\fBfutimens\fR(2), \fBstat\fR(2), \fButime\fR(2), \fBattributes\fR(5), +fBstat\fR(2), \fButime\fR(2), \fBattributes\fR(5), \fBfsattr\fR(5), \fBstandards\fR(5) diff --git a/usr/src/man/man3head/Makefile b/usr/src/man/man3head/Makefile index fdc94ef4ef..8e1e75e6fb 100644 --- a/usr/src/man/man3head/Makefile +++ b/usr/src/man/man3head/Makefile @@ -13,6 +13,7 @@ # Copyright 2011, Richard Lowe # Copyright 2013 Nexenta Systems, Inc. All rights reserved. # Copyright 2014 Garrett D'Amore +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # include $(SRC)/Makefile.master @@ -93,6 +94,7 @@ MANFILES= acct.h.3head \ time.h.3head \ timeb.h.3head \ times.h.3head \ + timespec.3head \ types.h.3head \ types32.h.3head \ uchar.h.3head \ @@ -273,6 +275,9 @@ MANLINKS += acct.3head \ time.3head \ timeb.3head \ times.3head \ + timeval.3head \ + TIMEVAL_TO_TIMESPEC.3head \ + TIMESPEC_TO_TIMEVAL.3head \ types.3head \ types32.3head \ ucontext.3head \ @@ -451,6 +456,10 @@ tgmath.3head := LINKSRC = tgmath.h.3head time.3head := LINKSRC = time.h.3head timeb.3head := LINKSRC = timeb.h.3head times.3head := LINKSRC = times.h.3head +timespec.3head := LINKSRC = time.h.3head +timeval.3head := LINKSRC = timespec.3head +TIMEVAL_TO_TIMESPEC.3head := LINKSRC = timespec.3head +TIMESPEC_TO_TIMEVAL.3head := LINKSRC = timespec.3head types.3head := LINKSRC = types.h.3head types32.3head := LINKSRC = types32.h.3head ucontext.3head := LINKSRC = ucontext.h.3head diff --git a/usr/src/man/man3head/timespec.3head b/usr/src/man/man3head/timespec.3head new file mode 100644 index 0000000000..54aaab14f5 --- /dev/null +++ b/usr/src/man/man3head/timespec.3head @@ -0,0 +1,106 @@ +.\" +.\" 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 OmniOS Community Edition (OmniOSce) Association. +.\" +.Dd Sep 06, 2020 +.Dt timespec 3HEAD +.Os +.Sh NAME +.Nm timespec , +.Nm timeval , +.Nm TIMESPEC_TO_TIMEVAL , +.Nm TIMEVAL_TO_TIMESPEC +.Nd time structures and conversion +.Sh SYNOPSIS +.In sys/time.h +.Ft void +.Fo TIMESPEC_TO_TIMEVAL +.Fa "struct timeval *tv" +.Fa "const struct timespec *ts" +.Fc +.Ft void +.Fo TIMEVAL_TO_TIMESPEC +.Fa "const struct timeval *tv" +.Fa "struct timespec *ts" +.Fc +.Sh DESCRIPTION +The +.Vt timeval +and +.Vt timespec +structures are declared in the +.In time.h +and +.In sys/time.h +headers respectively: +.Bd -literal -offset indent +typedef struct timespec { + time_t tv_sec; /* seconds */ + long tv_nsec; /* and nanoseconds */ +} timespec_t; + +struct timeval { + time_t tv_sec; /* seconds */ + suseconds_t tv_usec; /* and microseconds */ +}; +.Ed +.Pp +In both cases, the +.Fa tv_sec +member represents elapsed time in whole seconds. +The +.Fa tv_nsec +and +.Fa tv_usec +members represent the rest of the elapsed time in nanoseconds and +microseconds respectively, depending on the structure. +.Pp +The +.Dv TIMEVAL_TO_TIMESPEC +macro can be used to convert a +.Vt struct timeval +structure to a +.Vt struct timespec +structure, while the +.Dv TIMESPEC_TO_TIMEVAL +macro works in the opposite direction. +.Pp +When converting from a +.Vt struct timespec +to a +.Vt struct timeval +structure, the +.Fa tv_nsec +member is truncated, losing precision. +When converting from a +.Vt struct timeval +to a +.Vt struct timespec +structure, the +.Fa tv_usec +member is multiplied by 1000 to reach the precision of the target +structure. +The +.Fa tv_sec +member is always preserved, no matter which conversion is performed. +.Pp +Note that the +.Dv TIMEVAL_TO_TIMESPEC +and +.Dv TIMESPEC_TO_TIMEVAL +macros are non-standard but are commonly found on UNIX and UNIX-like systems. +.Sh INTERFACE STABILITY +.Sy Committed +.Sh MT-LEVEL +.Sy MT-Safe +.Sh SEE ALSO +.Xr time.h 3HEAD diff --git a/usr/src/man/man3lib/libc.3lib b/usr/src/man/man3lib/libc.3lib index 83df10408b..9bdf613acf 100644 --- a/usr/src/man/man3lib/libc.3lib +++ b/usr/src/man/man3lib/libc.3lib @@ -7,7 +7,7 @@ .\" See the License for the specific language governing permissions and limitations under the License. When distributing Covered Code, include this CDDL HEADER in each file and include the License file at usr/src/OPENSOLARIS.LICENSE. If applicable, add the following below this CDDL HEADER, with .\" the fields enclosed by brackets "[]" replaced with your own identifying information: Portions Copyright [yyyy] [name of copyright owner] .\" Copyright 2011 by Delphix. All rights reserved. -.TH LIBC 3LIB "Feb 14, 2020" +.TH LIBC 3LIB "Sep 06, 2020" .SH NAME libc \- C library .SH DESCRIPTION @@ -261,130 +261,131 @@ l l . \fBftok\fR \fBftruncate\fR \fBftrylockfile\fR \fBftw\fR \fBfunc_to_decimal\fR \fBfunlockfile\fR -\fBfutimens\fR \fBfutimesat\fR -\fBfwide\fR \fBfwprintf\fR -\fBfwrite\fR \fBfwscanf\fR -\fBgconvert\fR \fBgcvt\fR -\fBgetacct\fR \fBgetattrat\fR -\fBgetc\fR \fBgetc_unlocked\fR -\fBgetchar\fR \fBgetchar_unlocked\fR -\fBgetcontext\fR \fBgetcpuid\fR -\fBgetcwd\fR \fBgetdate\fR -\fBgetdate_err\fR \fBgetdents\fR -\fBgetdtablesize\fR \fBgetegid\fR -\fBgetenv\fR \fBgeteuid\fR -\fBgetexecname\fR \fBgetextmntent\fR -\fBgetgid\fR \fBgetgrent\fR -\fBgetgrent_r\fR \fBgetgrgid\fR -\fBgetgrgid_r\fR \fBgetgrnam\fR -\fBgetgrnam_r\fR \fBgetgroups\fR -\fBgethomelgroup\fR \fBgethostid\fR -\fBgethostname\fR \fBgethrtime\fR -\fBgethrvtime\fR \fBgetisax\fR -\fBgetitimer\fR \fBgetloadavg\fR -\fBgetlogin\fR \fBgetlogin_r\fR -\fBgetmntany\fR \fBgetmntent\fR -\fBgetmsg\fR \fBget_nprocs\fR -\fBget_nprocs_conf\fR \fBgetnetgrent\fR -\fBgetnetgrent_r\fR \fBgetopt\fR -\fBgetopt_clip\fR \fBgetopt_long\fR -\fBgetopt_long_only\fR \fBgetpagesize\fR -\fBgetpagesizes\fR \fBgetpass\fR -\fBgetpassphrase\fR \fBgetpeerucred\fR -\fBgetpflags\fR \fBgetpgid\fR -\fBgetpgrp\fR \fBgetpid\fR -\fBgetpmsg\fR \fBgetppid\fR -\fBgetppriv\fR \fBgetpriority\fR -\fBgetprogname\fR \fBgetprojid\fR -\fBgetpw\fR \fBgetpwent\fR -\fBgetpwent_r\fR \fBgetpwnam\fR -\fBgetpwnam_r\fR \fBgetpwuid\fR -\fBgetpwuid_r\fR \fBgetrctl\fR -\fBgetrlimit\fR \fBgetrusage\fR -\fBgets\fR \fBgetsid\fR -\fBgetspent\fR \fBgetspent_r\fR -\fBgetspnam\fR \fBgetspnam_r\fR -\fBgetsubopt\fR \fBgettaskid\fR -\fBgettext\fR \fBgettimeofday\fR -\fBgettxt\fR \fBgetuid\fR -\fBgetusershell\fR \fBgetustack\fR -\fBgetutent\fR \fBgetutid\fR -\fBgetutline\fR \fBgetutmp\fR -\fBgetutmpx\fR \fBgetutxent\fR -\fBgetutxid\fR \fBgetutxline\fR -\fBgetvfsany\fR \fBgetvfsent\fR -\fBgetvfsfile\fR \fBgetvfsspec\fR -\fBgetw\fR \fBgetwc\fR -\fBgetwc_l\fR \fBgetwchar\fR -\fBgetwchar_l\fR \fBgetwd\fR -\fBgetwidth\fR \fBgetws\fR -\fBgetzoneid\fR \fBgetzoneidbyname\fR -\fBgetzonenamebyid\fR \fBglob\fR -\fBglobfree\fR \fBgmtime\fR -\fBgmtime_r\fR \fBgrantpt\fR -\fBgsignal\fR \fBhasmntopt\fR -\fBhcreate\fR \fBhdestroy\fR -\fBhsearch\fR \fBiconv\fR -\fBiconv_close\fR \fBiconv_open\fR -\fBimaxabs\fR \fBimaxdiv\fR -\fBindex\fR \fBinitgroups\fR -\fBinitstate\fR \fBinnetgr\fR -\fBinsque\fR \fBioctl\fR -\fBis_system_labeled\fR \fBisaexec\fR -\fBisalnum\fR \fBisalnum_l\fR -\fBisalpha\fR \fBisalpha_l\fR -\fBisascii\fR \fBisastream\fR -\fBisatty\fR \fBisblank\fR -\fBisblank_l\fR \fBiscntrl\fR -\fBiscntrl_l\fR \fBisdigit\fR -\fBisdigit_l\fR \fBisenglish\fR -\fBisgraph\fR \fBisgraph_l\fR -\fBisideogram\fR \fBislower\fR -\fBislower_l\fR \fBisnan\fR -\fBisnand\fR \fBisnanf\fR -\fBisnumber\fR \fBisphonogram\fR -\fBisprint\fR \fBisprint_l\fR -\fBispunct\fR \fBispunct_l\fR -\fBissetugid\fR \fBisspace\fR -\fBisspace_l\fR \fBisspecial\fR -\fBisupper\fR \fBisupper_l\fR -\fBiswalnum\fR \fBiswalnum_l\fR -\fBiswalpha\fR \fBiswalpha_l\fR -\fBiswblank\fR \fBiswblank_l\fR -\fBiswcntrl\fR \fBiswcntrl_l\fR -\fBiswctype\fR \fBiswctype_l\fR -\fBiswdigit\fR \fBiswdigit_l\fR -\fBiswideogram\fR \fBiswideogram_l\fR -\fBiswgraph\fR \fBiswgraph_l\fR -\fBiswhexnumber\fR \fBiswhexnumber_l\fR -\fBiswlower\fR \fBiswlower_l\fR -\fBiswnumber\fR \fBiswnumber_l\fR -\fBiswphonogram\fR \fBiswphonogram_l\fR -\fBiswprint\fR \fBiswprint_l\fR -\fBiswpunct\fR \fBiswpunct_l\fR -\fBiswspace\fR \fBiswspace_l\fR -\fBiswspecial\fR \fBiswspecial_l\fR -\fBiswupper\fR \fBiswupper_l\fR -\fBiswxdigit\fR \fBiswxdigit_l\fR -\fBisxdigit\fR \fBisxdigit_l\fR -\fBjrand48\fR \fBkill\fR -\fBkillpg\fR \fBl64a\fR -\fBlabs\fR \fBladd\fR -\fBlchown\fR \fBlckpwdf\fR -\fBlcong48\fR \fBldexp\fR -\fBldivide\fR \fBlexp10\fR -\fBlfind\fR \fBlfmt\fR -\fBlink\fR \fBlinkat\fR -\fBlio_listio\fR \fBllabs\fR -\fBlldiv\fR \fBllog10\fR -\fBllseek\fR \fBlltostr\fR -\fBlocaleconv\fR \fBlocaltime\fR -\fBlocaltime_r\fR \fBlockf\fR -\fBlogb\fR \fBlone\fR -\fBlongjmp\fR \fBlrand48\fR -\fBlsearch\fR \fBlseek\fR -\fBlshiftl\fR \fBlstat\fR -\fBlsub\fR \fBlten\fR +\fBfutimens\fR \fBfutimes\fR +\fBfutimesat\fR \fBfwide\fR +\fBfwprintf\fR \fBfwrite\fR +\fBfwscanf\fR \fBgconvert\fR +\fBgcvt\fR \fBgetacct\fR +\fBgetattrat\fR \fBgetc\fR +\fBgetc_unlocked\fR \fBgetchar\fR +\fBgetchar_unlocked\fR \fBgetcontext\fR +\fBgetcpuid\fR \fBgetcwd\fR +\fBgetdate\fR \fBgetdate_err\fR +\fBgetdents\fR \fBgetdtablesize\fR +\fBgetegid\fR \fBgetenv\fR +\fBgeteuid\fR \fBgetexecname\fR +\fBgetextmntent\fR \fBgetgid\fR +\fBgetgrent\fR \fBgetgrent_r\fR +\fBgetgrgid\fR \fBgetgrgid_r\fR +\fBgetgrnam\fR \fBgetgrnam_r\fR +\fBgetgroups\fR \fBgethomelgroup\fR +\fBgethostid\fR \fBgethostname\fR +\fBgethrtime\fR \fBgethrvtime\fR +\fBgetisax\fR \fBgetitimer\fR +\fBgetloadavg\fR \fBgetlogin\fR +\fBgetlogin_r\fR \fBgetmntany\fR +\fBgetmntent\fR \fBgetmsg\fR +\fBget_nprocs\fR \fBget_nprocs_conf\fR +\fBgetnetgrent\fR \fBgetnetgrent_r\fR +\fBgetopt\fR \fBgetopt_clip\fR +\fBgetopt_long\fR \fBgetopt_long_only\fR +\fBgetpagesize\fR \fBgetpagesizes\fR +\fBgetpass\fR \fBgetpassphrase\fR +\fBgetpeerucred\fR \fBgetpflags\fR +\fBgetpgid\fR \fBgetpgrp\fR +\fBgetpid\fR \fBgetpmsg\fR +\fBgetppid\fR \fBgetppriv\fR +\fBgetpriority\fR \fBgetprogname\fR +\fBgetprojid\fR \fBgetpw\fR +\fBgetpwent\fR \fBgetpwent_r\fR +\fBgetpwnam\fR \fBgetpwnam_r\fR +\fBgetpwuid\fR \fBgetpwuid_r\fR +\fBgetrctl\fR \fBgetrlimit\fR +\fBgetrusage\fR \fBgets\fR +\fBgetsid\fR \fBgetspent\fR +\fBgetspent_r\fR \fBgetspnam\fR +\fBgetspnam_r\fR \fBgetsubopt\fR +\fBgettaskid\fR \fBgettext\fR +\fBgettimeofday\fR \fBgettxt\fR +\fBgetuid\fR \fBgetusershell\fR +\fBgetustack\fR \fBgetutent\fR +\fBgetutid\fR \fBgetutline\fR +\fBgetutmp\fR \fBgetutmpx\fR +\fBgetutxent\fR \fBgetutxid\fR +\fBgetutxline\fR \fBgetvfsany\fR +\fBgetvfsent\fR \fBgetvfsfile\fR +\fBgetvfsspec\fR \fBgetw\fR +\fBgetwc\fR \fBgetwc_l\fR +\fBgetwchar\fR \fBgetwchar_l\fR +\fBgetwd\fR \fBgetwidth\fR +\fBgetws\fR \fBgetzoneid\fR +\fBgetzoneidbyname\fR \fBgetzonenamebyid\fR +\fBglob\fR \fBglobfree\fR +\fBgmtime\fR \fBgmtime_r\fR +\fBgrantpt\fR \fBgsignal\fR +\fBhasmntopt\fR \fBhcreate\fR +\fBhdestroy\fR \fBhsearch\fR +\fBiconv\fR \fBiconv_close\fR +\fBiconv_open\fR \fBimaxabs\fR +\fBimaxdiv\fR \fBindex\fR +\fBinitgroups\fR \fBinitstate\fR +\fBinnetgr\fR \fBinsque\fR +\fBioctl\fR \fBis_system_labeled\fR +\fBisaexec\fR \fBisalnum\fR +\fBisalnum_l\fR \fBisalpha\fR +\fBisalpha_l\fR \fBisascii\fR +\fBisastream\fR \fBisatty\fR +\fBisblank\fR \fBisblank_l\fR +\fBiscntrl\fR \fBiscntrl_l\fR +\fBisdigit\fR \fBisdigit_l\fR +\fBisenglish\fR \fBisgraph\fR +\fBisgraph_l\fR \fBisideogram\fR +\fBislower\fR \fBislower_l\fR +\fBisnan\fR \fBisnand\fR +\fBisnanf\fR \fBisnumber\fR +\fBisphonogram\fR \fBisprint\fR +\fBisprint_l\fR \fBispunct\fR +\fBispunct_l\fR \fBissetugid\fR +\fBisspace\fR \fBisspace_l\fR +\fBisspecial\fR \fBisupper\fR +\fBisupper_l\fR \fBiswalnum\fR +\fBiswalnum_l\fR \fBiswalpha\fR +\fBiswalpha_l\fR \fBiswblank\fR +\fBiswblank_l\fR \fBiswcntrl\fR +\fBiswcntrl_l\fR \fBiswctype\fR +\fBiswctype_l\fR \fBiswdigit\fR +\fBiswdigit_l\fR \fBiswideogram\fR +\fBiswideogram_l\fR \fBiswgraph\fR +\fBiswgraph_l\fR \fBiswhexnumber\fR +\fBiswhexnumber_l\fR \fBiswlower\fR +\fBiswlower_l\fR \fBiswnumber\fR +\fBiswnumber_l\fR \fBiswphonogram\fR +\fBiswphonogram_l\fR \fBiswprint\fR +\fBiswprint_l\fR \fBiswpunct\fR +\fBiswpunct_l\fR \fBiswspace\fR +\fBiswspace_l\fR \fBiswspecial\fR +\fBiswspecial_l\fR \fBiswupper\fR +\fBiswupper_l\fR \fBiswxdigit\fR +\fBiswxdigit_l\fR \fBisxdigit\fR +\fBisxdigit_l\fR \fBjrand48\fR +\fBkill\fR \fBkillpg\fR +\fBl64a\fR \fBlabs\fR +\fBladd\fR \fBlchown\fR +\fBlckpwdf\fR \fBlcong48\fR +\fBldexp\fR \fBldivide\fR +\fBlexp10\fR \fBlfind\fR +\fBlfmt\fR \fBlink\fR +\fBlinkat\fR \fBlio_listio\fR +\fBllabs\fR \fBlldiv\fR +\fBllog10\fR \fBllseek\fR +\fBlltostr\fR \fBlocaleconv\fR +\fBlocaltime\fR \fBlocaltime_r\fR +\fBlockf\fR \fBlogb\fR +\fBlone\fR \fBlongjmp\fR +\fBlrand48\fR \fBlsearch\fR +\fBlseek\fR \fBlshiftl\fR +\fBlstat\fR \fBlsub\fR +\fBlten\fR \fBlutimes\fR \fBlzero\fR \fBmadvise\fR \fBmakecontext\fR \fBmakeutx\fR \fBmalloc\fR \fBmblen\fR diff --git a/usr/src/pkg/manifests/system-header.mf b/usr/src/pkg/manifests/system-header.mf index 8a5436aba7..d9d94487f0 100644 --- a/usr/src/pkg/manifests/system-header.mf +++ b/usr/src/pkg/manifests/system-header.mf @@ -28,6 +28,7 @@ # Copyright 2016 Hans Rosenfeld # Copyright 2020 Joyent, Inc. # Copyright 2019 Peter Tribble. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # set name=pkg.fmri value=pkg:/system/header@$(PKGVERS) @@ -1909,6 +1910,7 @@ file path=usr/share/man/man3head/tgmath.h.3head file path=usr/share/man/man3head/time.h.3head file path=usr/share/man/man3head/timeb.h.3head file path=usr/share/man/man3head/times.h.3head +file path=usr/share/man/man3head/timespec.3head file path=usr/share/man/man3head/types.h.3head file path=usr/share/man/man3head/types32.h.3head file path=usr/share/man/man3head/uchar.h.3head @@ -2113,6 +2115,10 @@ link path=usr/share/man/man3head/TAILQ_NEXT.3head target=queue.h.3head link path=usr/share/man/man3head/TAILQ_PREV.3head target=queue.h.3head link path=usr/share/man/man3head/TAILQ_REMOVE.3head target=queue.h.3head link path=usr/share/man/man3head/TAILQ_SWAP.3head target=queue.h.3head +link path=usr/share/man/man3head/TIMESPEC_TO_TIMEVAL.3head \ + target=timespec.3head +link path=usr/share/man/man3head/TIMEVAL_TO_TIMESPEC.3head \ + target=timespec.3head link path=usr/share/man/man3head/acct.3head target=acct.h.3head link path=usr/share/man/man3head/aio.3head target=aio.h.3head link path=usr/share/man/man3head/ar.3head target=ar.h.3head @@ -2186,6 +2192,7 @@ link path=usr/share/man/man3head/tgmath.3head target=tgmath.h.3head link path=usr/share/man/man3head/time.3head target=time.h.3head link path=usr/share/man/man3head/timeb.3head target=timeb.h.3head link path=usr/share/man/man3head/times.3head target=times.h.3head +link path=usr/share/man/man3head/timeval.3head target=timespec.3head link path=usr/share/man/man3head/types.3head target=types.h.3head link path=usr/share/man/man3head/types32.3head target=types32.h.3head link path=usr/share/man/man3head/ucontext.3head target=ucontext.h.3head diff --git a/usr/src/pkg/manifests/system-kernel.man2.inc b/usr/src/pkg/manifests/system-kernel.man2.inc index e5e1ace483..6a45a39b55 100644 --- a/usr/src/pkg/manifests/system-kernel.man2.inc +++ b/usr/src/pkg/manifests/system-kernel.man2.inc @@ -15,6 +15,7 @@ # Copyright 2013, OmniTI Computer Consulting, Inc. # Copyright 2017 Peter Tribble # Copyright 2018, Joyent, Inc. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # file path=usr/share/man/man2/Intro.2 @@ -192,6 +193,7 @@ link path=usr/share/man/man2/fstat.2 target=stat.2 link path=usr/share/man/man2/fstatat.2 target=stat.2 link path=usr/share/man/man2/fstatvfs.2 target=statvfs.2 link path=usr/share/man/man2/futimens.2 target=utimes.2 +link path=usr/share/man/man2/futimes.2 target=utimes.2 link path=usr/share/man/man2/futimesat.2 target=utimes.2 link path=usr/share/man/man2/getaudit_addr.2 target=getaudit.2 link path=usr/share/man/man2/getegid.2 target=getuid.2 @@ -205,9 +207,10 @@ link path=usr/share/man/man2/getprojid.2 target=settaskid.2 link path=usr/share/man/man2/getrctl.2 target=setrctl.2 link path=usr/share/man/man2/gettaskid.2 target=settaskid.2 link path=usr/share/man/man2/intro.2 target=Intro.2 -link path=usr/share/man/man2/linkat.2 target=link.2 link path=usr/share/man/man2/lchown.2 target=chown.2 +link path=usr/share/man/man2/linkat.2 target=link.2 link path=usr/share/man/man2/lstat.2 target=stat.2 +link path=usr/share/man/man2/lutimes.2 target=utimes.2 link path=usr/share/man/man2/mkdirat.2 target=mkdir.2 link path=usr/share/man/man2/mknodat.2 target=mknod.2 link path=usr/share/man/man2/openat.2 target=open.2 diff --git a/usr/src/pkg/manifests/system-test-libctest.mf b/usr/src/pkg/manifests/system-test-libctest.mf index 659006a358..3145beeadc 100644 --- a/usr/src/pkg/manifests/system-test-libctest.mf +++ b/usr/src/pkg/manifests/system-test-libctest.mf @@ -14,6 +14,7 @@ # Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved. # Copyright 2015 Garrett D'Amore # Copyright 2018 Joyent, Inc. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # set name=pkg.fmri value=pkg:/system/test/libctest@$(PKGVERS) @@ -189,6 +190,8 @@ file path=opt/libc-tests/tests/timespec_get.32 mode=0555 file path=opt/libc-tests/tests/timespec_get.64 mode=0555 file path=opt/libc-tests/tests/uchar.32 mode=0555 file path=opt/libc-tests/tests/uchar.64 mode=0555 +file path=opt/libc-tests/tests/utimes.32 mode=0555 +file path=opt/libc-tests/tests/utimes.64 mode=0555 file path=opt/libc-tests/tests/wcsncasecmp-7344.32 mode=0555 file path=opt/libc-tests/tests/wcsncasecmp-7344.64 mode=0555 file path=opt/libc-tests/tests/wcsncasecmp-7350.32 mode=0555 diff --git a/usr/src/prototypes/prototype.man3x b/usr/src/prototypes/prototype.man3x index 598315f959..3604b4a0e2 100644 --- a/usr/src/prototypes/prototype.man3x +++ b/usr/src/prototypes/prototype.man3x @@ -59,7 +59,7 @@ A Reason why ERRNO1 could occur. A Reason why ERRNO2 could occur. .El .Sh INTERFACE STABILITY -.\" Indicate the stability per attribute(5). One of: +.\" Indicate the stability per attributes(5). One of: .\" .Sy Committed .\" .Sy Uncommitted .\" .Sy Volatile diff --git a/usr/src/test/libc-tests/cfg/symbols/sys_time_h.cfg b/usr/src/test/libc-tests/cfg/symbols/sys_time_h.cfg index afed10a6bb..8ca9bacb9d 100644 --- a/usr/src/test/libc-tests/cfg/symbols/sys_time_h.cfg +++ b/usr/src/test/libc-tests/cfg/symbols/sys_time_h.cfg @@ -11,6 +11,7 @@ # # Copyright 2015 Garrett D'Amore +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # # @@ -40,3 +41,16 @@ func | utimes |\ int |\ const char *; const struct timeval [2] |\ sys/time.h | -POSIX+ -XPG3+ SUS+ + +func | lutimes |\ + int |\ + const char *; const struct timeval [2] |\ + sys/time.h | -ALL + +func | futimes |\ + int |\ + int; const struct timeval [2] |\ + sys/time.h | -ALL + +define | TIMEVAL_TO_TIMESPEC | | sys/time.h | -ALL +define | TIMESPEC_TO_TIMEVAL | | sys/time.h | -ALL diff --git a/usr/src/test/libc-tests/runfiles/default.run b/usr/src/test/libc-tests/runfiles/default.run index 0ad4526774..bada7ea85b 100644 --- a/usr/src/test/libc-tests/runfiles/default.run +++ b/usr/src/test/libc-tests/runfiles/default.run @@ -13,6 +13,7 @@ # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2014 Garrett D'Amore # Copyright 2019 Joyent, Inc. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # [DEFAULT] @@ -124,6 +125,8 @@ timeout = 600 [/opt/libc-tests/tests/timespec_get.64] [/opt/libc-tests/tests/uchar.32] [/opt/libc-tests/tests/uchar.64] +[/opt/libc-tests/tests/utimes.32] +[/opt/libc-tests/tests/utimes.64] # # root privs required for priority changes diff --git a/usr/src/test/libc-tests/tests/Makefile b/usr/src/test/libc-tests/tests/Makefile index 0b460ff2f2..54a9a23572 100644 --- a/usr/src/test/libc-tests/tests/Makefile +++ b/usr/src/test/libc-tests/tests/Makefile @@ -13,6 +13,7 @@ # Copyright (c) 2012 by Delphix. All rights reserved. # Copyright 2015 Garrett D'Amore # Copyright 2019 Joyent, Inc. +# Copyright 2020 OmniOS Community Edition (OmniOSce) Association. # SUBDIRS = \ @@ -52,7 +53,8 @@ PROGS = \ wcsncasecmp \ wcsncasecmp-7344 \ wcsncasecmp-7350 \ - uchar + uchar \ + utimes SCRIPTS = \ quick_exit \ diff --git a/usr/src/test/libc-tests/tests/utimes.c b/usr/src/test/libc-tests/tests/utimes.c new file mode 100644 index 0000000000..7585289fe6 --- /dev/null +++ b/usr/src/test/libc-tests/tests/utimes.c @@ -0,0 +1,521 @@ +/* + * 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 OmniOS Community Edition (OmniOSce) Association. + */ + +/* + * Test the implementation of the various *utimes() and *utimens() functions + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +timespec_t testtimes[] = { + { + .tv_sec = 1280793678, + .tv_nsec = 123456789 + }, + { + .tv_sec = 1492732800, + .tv_nsec = 17 + }, + { + .tv_sec = 1320796855, + .tv_nsec = 9 + }, + { + .tv_sec = 1498953611, + .tv_nsec = 987654321 + } +}; + +enum ttype { + UTIMES, + LUTIMES, + FUTIMES, + FUTIMESAT, + FUTIMENS, + UTIMENSAT +}; + +static bool +compare_times(struct stat *st, bool trunc, timespec_t *atim, timespec_t *mtim, + bool invert) +{ + bool ret = true; + + if (st->st_atim.tv_sec != atim->tv_sec) { + ret = false; + } else if (st->st_atim.tv_nsec != ( + trunc ? atim->tv_nsec / 1000 * 1000 : atim->tv_nsec)) { + ret = false; + } else if (st->st_mtim.tv_sec != mtim->tv_sec) { + ret = false; + } else if (st->st_mtim.tv_nsec != ( + trunc ? mtim->tv_nsec / 1000 * 1000 : mtim->tv_nsec)) { + ret = false; + } + + if ((!ret && !invert) || (ret && invert)) { + printf(" actual atime: %ld.%.9ld\n", + st->st_atim.tv_sec, st->st_atim.tv_nsec); + printf(" actual mtime: %ld.%.9ld\n", + st->st_mtim.tv_sec, st->st_mtim.tv_nsec); + } + + return (ret); +} + +static bool +compare_filetime(char *path, bool trunc, timespec_t *atim, timespec_t *mtim, + bool invert) +{ + struct stat st; + + if (stat(path, &st) == -1) + err(EXIT_FAILURE, "stat %s", path); + + return (compare_times(&st, trunc, atim, mtim, invert)); +} + +static bool +compare_linktime(char *path, bool trunc, timespec_t *atim, timespec_t *mtim, + bool invert) +{ + struct stat st; + + if (lstat(path, &st) == -1) + err(EXIT_FAILURE, "lstat %s", path); + + return (compare_times(&st, trunc, atim, mtim, invert)); +} + +static bool +reset(char *path, timespec_t *atim, timespec_t *mtim) +{ + if (utimes(path, NULL) == -1) + err(EXIT_FAILURE, "utimes reset"); + if (compare_filetime(path, true, atim, mtim, true)) { + warnx("reset failed"); + return (false); + } + return (true); +} + +static bool +reset_link(char *lpath, timespec_t *atim, timespec_t *mtim) +{ + if (lutimes(lpath, NULL) == -1) + err(EXIT_FAILURE, "lutimes reset"); + if (compare_linktime(lpath, true, atim, mtim, true)) { + warnx("link reset failed"); + return (false); + } + return (true); +} + +static bool +runtest(enum ttype fn, char *dir, timespec_t *atim, timespec_t *mtim) +{ + char path[MAXPATHLEN + 1]; + char lpath[MAXPATHLEN + 1]; + struct timespec ts[2]; + struct timeval tv[2]; + int fd, lfd, dfd, ret = true; + + ts[0] = *atim; + ts[1] = *mtim; + TIMESPEC_TO_TIMEVAL(&tv[0], &ts[0]); + TIMESPEC_TO_TIMEVAL(&tv[1], &ts[1]); + + if (snprintf(path, sizeof (path), "%s/file", dir) >= sizeof (path)) + err(EXIT_FAILURE, "snprintf failed to build file path"); + + if ((fd = open(path, O_CREAT, 0644)) == -1) + err(EXIT_FAILURE, "open file %s", path); + + if (snprintf(lpath, sizeof (lpath), "%s/link", dir) >= sizeof (path)) + err(EXIT_FAILURE, "snprintf failed to build link path"); + + if (symlink(path, lpath) == -1) + err(EXIT_FAILURE, "link(%s)", lpath); + + if ((lfd = open(lpath, O_RDWR)) == -1) + err(EXIT_FAILURE, "open link(%s)", lpath); + + if ((dfd = open(dir, O_DIRECTORY|O_RDONLY)) == -1) + err(EXIT_FAILURE, "open dir(%s)", dir); + + switch (fn) { + case UTIMES: + printf("..... utimes()\n"); + + if (utimes(path, tv) == -1) + err(EXIT_FAILURE, "utimes(%s)", path); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed on file"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* repeat against symbolic link path */ + if (utimes(lpath, tv) == -1) + err(EXIT_FAILURE, "utimes(%s), link", lpath); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed on file through link"); + ret = false; + } + + break; + + case LUTIMES: + printf("..... lutimes()\n"); + + /* Use lutimes() against a plain file */ + if (lutimes(path, tv) == -1) + err(EXIT_FAILURE, "lutimes(%s)", path); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed on file"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* Set the time on the link, not on the target */ + if (lutimes(lpath, tv) == -1) + err(EXIT_FAILURE, "lutimes(%s)", lpath); + if (!compare_linktime(lpath, true, atim, mtim, false)) { + warnx("link time is incorrect"); + ret = false; + } + if (compare_filetime(path, true, atim, mtim, true)) { + warnx("target time was updated incorrectly"); + ret = false; + } + + /* Reset the time on the path and link to the current time */ + if (!reset(path, atim, mtim) || !reset_link(lpath, atim, mtim)) + ret = false; + + /* and modify the target */ + if (utimes(path, tv) == -1) + err(EXIT_FAILURE, "utimes(%s)", path); + /* Now the target should match but the link should not */ + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("target time is incorrect"); + ret = false; + } + if (compare_linktime(lpath, true, atim, mtim, true)) { + warnx("link time was updated incorrectly"); + ret = false; + } + break; + + case FUTIMES: + printf("..... futimes()\n"); + + if (futimes(fd, tv) == -1) + err(EXIT_FAILURE, "futimes(%s)", path); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed on file"); + ret = false; + } + + break; + + case FUTIMESAT: { + int rfd; + printf("..... futimesat()\n"); + + /* NULL path, should modify the file for 'fd' */ + if (futimesat(fd, NULL, tv) == -1) + err(EXIT_FAILURE, "futimesat(fd, NULL)"); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed with null path"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* random descriptor, FQ path, descriptor is ignored */ + if ((rfd = open("/dev/null", O_RDONLY)) == -1) + err(EXIT_FAILURE, "open(/dev/null)"); + if (futimesat(rfd, path, tv) == -1) + err(EXIT_FAILURE, "futimesat(dnfd, %s)", path); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed with random descriptor and fq path"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* repeat against symbolic link path */ + if (futimesat(rfd, lpath, tv) == -1) + err(EXIT_FAILURE, "futimesat(dnfd, %s), link", lpath); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed through link with " + "random descriptor, fq path"); + ret = false; + } + + (void) close(rfd); + + if (!reset(path, atim, mtim)) + ret = false; + + /* relative to a directory */ + if (futimesat(dfd, "file", tv) == -1) + err(EXIT_FAILURE, "futimesat(dir, file)", path); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed relative to a directory"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* repeat against symbolic link path */ + if (futimesat(dfd, "link", tv) == -1) + err(EXIT_FAILURE, "futimesat(dir, link)"); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed through link relative to a directory"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* AT_FDCWD */ + if (fchdir(dfd) == -1) + err(EXIT_FAILURE, "fchdir(%s)", dir); + if (futimesat(AT_FDCWD, "file", tv) == -1) + err(EXIT_FAILURE, "futimesat(AT_FDCWD, file)", path); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed with AT_FDCWD relative"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* repeat against symbolic link path */ + if (futimesat(AT_FDCWD, "link", tv) == -1) + err(EXIT_FAILURE, "futimesat(AT_FDCWD, link)"); + if (!compare_filetime(path, true, atim, mtim, false)) { + warnx("failed through link with AT_FDCWD relative"); + ret = false; + } + + break; + } + + case FUTIMENS: + printf("..... futimens()\n"); + if (futimens(fd, ts) == -1) + err(EXIT_FAILURE, "futimesns(%s)", path); + if (!compare_filetime(path, false, atim, mtim, false)) { + warnx("failed with plain file fd"); + ret = false; + } + + break; + + case UTIMENSAT: { + int rfd; + + printf("..... utimensat()\n"); + + /* NULL path, expect EFAULT (cf. futimesat()) */ + if (utimensat(fd, NULL, ts, 0) != -1 || errno != EFAULT) { + warnx("null path should return EFAULT but got %d/%s", + errno, strerror(errno)); + ret = false; + } + + /* random descriptor, FQ path, descriptor is ignored */ + if ((rfd = open("/dev/null", O_RDONLY)) == -1) + err(EXIT_FAILURE, "open(/dev/null)"); + if (utimensat(rfd, path, ts, 0) == -1) + err(EXIT_FAILURE, "utimensat(dnfd, %s)", path); + if (!compare_filetime(path, false, atim, mtim, false)) { + warnx("failed with random descriptor, fq path"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* repeat against symbolic link path */ + if (utimensat(rfd, lpath, ts, 0) == -1) + err(EXIT_FAILURE, "utimensat(dnfd, link %s)", lpath); + if (!compare_filetime(path, false, atim, mtim, false)) { + warnx("failed against link with random descriptor, " + "fq path"); + ret = false; + } + + (void) close(rfd); + + if (!reset(path, atim, mtim)) + ret = false; + + /* relative to a directory */ + if (utimensat(dfd, "file", ts, 0) == -1) + err(EXIT_FAILURE, "utimensat(dir, file)", path); + if (!compare_filetime(path, false, atim, mtim, false)) { + warnx("failed relative to a directory"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* repeat against symbolic link path */ + if (utimensat(dfd, "link", ts, 0) == -1) + err(EXIT_FAILURE, "utimensat(dir, link)", path); + if (!compare_filetime(path, false, atim, mtim, false)) { + warnx("failed through link relative to a directory"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* AT_FDCWD */ + if (fchdir(dfd) == -1) + err(EXIT_FAILURE, "fchdir(%s)", dir); + if (utimensat(AT_FDCWD, "file", ts, 0) == -1) + err(EXIT_FAILURE, "utimensat(AT_FDCWD, file)"); + if (!compare_filetime(path, false, atim, mtim, false)) { + warnx("failed with AT_FDCWD relative"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* repeat against symbolic link path */ + if (utimensat(AT_FDCWD, "link", ts, 0) == -1) + err(EXIT_FAILURE, "utimensat(AT_FDCWD, link)"); + if (!compare_filetime(path, false, atim, mtim, false)) { + warnx("failed through link with AT_FDCWD relative"); + ret = false; + } + + if (!reset(path, atim, mtim)) + ret = false; + + /* + * Check that none of the above operations have changed the + * timestamp on the link. + */ + if (compare_linktime(lpath, true, atim, mtim, true)) { + warnx("link timestamp was unexpectedly modified"); + ret = false; + } + + /* Set the time on the link, not on the target */ + if (utimensat(AT_FDCWD, "link", ts, AT_SYMLINK_NOFOLLOW) == -1) + err(EXIT_FAILURE, "utimensat(AT_FDCWD, lflag)"); + if (!compare_linktime(lpath, false, atim, mtim, false)) { + warnx("link time is incorrect"); + ret = false; + } + if (compare_filetime(path, false, atim, mtim, true)) { + warnx("target time was updated incorrectly"); + ret = false; + } + } + break; + } + + (void) close(dfd); + (void) close(lfd); + (void) close(fd); + + if (unlink(lpath) == -1) + err(EXIT_FAILURE, "unlink(%s)", lpath); + if (unlink(path) == -1) + err(EXIT_FAILURE, "unlink(%s)", path); + + if (!ret) + warnx("Test failed"); + + return (ret); +} + +static bool +runtests(char *dir, timespec_t *atim, timespec_t *mtim) +{ + bool ret = true; + + printf("Testing:\n... atime: %ld.%.9ld\n... mtime: %ld.%.9ld\n", + atim->tv_sec, atim->tv_nsec, mtim->tv_sec, mtim->tv_nsec); + + if (!runtest(UTIMES, dir, atim, mtim)) + ret = false; + if (!runtest(LUTIMES, dir, atim, mtim)) + ret = false; + if (!runtest(FUTIMES, dir, atim, mtim)) + ret = false; + if (!runtest(FUTIMESAT, dir, atim, mtim)) + ret = false; + if (!runtest(FUTIMENS, dir, atim, mtim)) + ret = false; + if (!runtest(UTIMENSAT, dir, atim, mtim)) + ret = false; + + return (ret); +} + +int +main(void) +{ + char dir[] = "/tmp/utimes.XXXXXX"; + int ret = EXIT_SUCCESS; + int i; + + if (mkdtemp(dir) == NULL) + err(EXIT_FAILURE, "failed to create temporary directory"); + + for (i = 0; i < ARRAY_SIZE(testtimes); i += 2) { + if (!runtests(dir, &testtimes[i], &testtimes[i + 1])) + ret = EXIT_FAILURE; + } + + /* + * Some tests will have changed directory into 'dir' to test the + * AT_FDCWD case. Change back to / to avoid EBUSY when removing dir. + */ + if (chdir("/") == -1) + err(EXIT_FAILURE, "chdir(/)"); + if (rmdir(dir) == -1) + err(EXIT_FAILURE, "rmdir %s", dir); + + return (ret); +} diff --git a/usr/src/uts/common/sys/time.h b/usr/src/uts/common/sys/time.h index 8a36f622c3..8ec74d4ecd 100644 --- a/usr/src/uts/common/sys/time.h +++ b/usr/src/uts/common/sys/time.h @@ -15,6 +15,8 @@ * Use is subject to license terms. * * Copyright 2013 Nexenta Systems, Inc. All rights reserved. + * + * Copyright 2020 OmniOS Community Edition (OmniOSce) Association. */ /* @@ -356,14 +358,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 *); @@ -399,6 +401,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); @@ -409,6 +412,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 -- cgit v1.2.3 From 73439c833efecf3010718112f4fce6bb183a6803 Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Sun, 19 Jul 2020 13:30:50 -0700 Subject: 13080 Add support for cxgbe temp/volt sensor Reviewed by: Andy Fiddaman Reviewed by: Paul Winder Reviewed by: Toomas Soome Approved by: Dan McDonald --- usr/src/uts/common/io/cxgbe/t4nex/adapter.h | 4 + usr/src/uts/common/io/cxgbe/t4nex/t4_nexus.c | 105 ++++++++++++++++++++++++++- 2 files changed, 108 insertions(+), 1 deletion(-) (limited to 'usr/src/uts/common') 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 #include #include +#include #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); +} -- cgit v1.2.3 From fd147c98dbdbc9e5ac99fa51cb608e8eeb1f16f1 Mon Sep 17 00:00:00 2001 From: Robert Mustacchi Date: Tue, 15 Sep 2020 00:04:46 -0700 Subject: 13168 reality should reflect the mac_prop_id_t comment Reviewed by: Dan McDonald Reviewed by: Patrick Mooney Reviewed by: Toomas Soome Approved by: Hans Rosenfeld --- usr/src/uts/common/sys/mac.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'usr/src/uts/common') diff --git a/usr/src/uts/common/sys/mac.h b/usr/src/uts/common/sys/mac.h index 00d9901719..e90df8746c 100644 --- a/usr/src/uts/common/sys/mac.h +++ b/usr/src/uts/common/sys/mac.h @@ -162,6 +162,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, @@ -239,8 +240,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; /* -- cgit v1.2.3