diff options
author | Dan McDonald <danmcd@joyent.com> | 2020-12-14 10:45:44 -0500 |
---|---|---|
committer | Dan McDonald <danmcd@joyent.com> | 2020-12-14 10:45:44 -0500 |
commit | fbbddd469d9daea7e493dd9ae6ad2861372aed18 (patch) | |
tree | ec73668f3d3b573ac4ee220fea1e2e8fd7b742db /usr/src | |
parent | b1e92d38ed920e9dcddad6df733657d248710c19 (diff) | |
parent | 13810335a5a8384eed97a8661536eb5352f0c933 (diff) | |
download | illumos-joyent-fbbddd469d9daea7e493dd9ae6ad2861372aed18.tar.gz |
[illumos-gate merge]
commit 13810335a5a8384eed97a8661536eb5352f0c933
13208 Create aggr fails when underlying links have more than 128 Tx rings
commit fe17aa88307d9cacf6677bbbe955585b11920199
13325 bhyve misinterprets MSI redir hint
commit 15174c59605d00b59ea3aae8ba85744a42aa1e96
13343 some mlxcx devices don't support temperature sensors
commit 9a2cc6e2be46528f552f7ed112fed60a329cd001
13353 loader: 13345 did miss byte and nvlist array
commit 34e16b78b1d2e5f513ee90af24e76d9703518b4c
13347 loader: gfx_fb_putimage 8 bit color translation is not good
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/boot/Makefile.version | 2 | ||||
-rw-r--r-- | usr/src/boot/lib/libstand/zfs/nvlist.c | 24 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/common/gfx_fb.c | 61 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/vbe.h | 1 | ||||
-rw-r--r-- | usr/src/boot/sys/boot/i386/libi386/vidconsole.c | 16 | ||||
-rw-r--r-- | usr/src/uts/common/io/aggr/aggr_grp.c | 117 | ||||
-rw-r--r-- | usr/src/uts/common/io/mlxcx/mlxcx.c | 10 | ||||
-rw-r--r-- | usr/src/uts/common/sys/aggr_impl.h | 5 | ||||
-rw-r--r-- | usr/src/uts/i86pc/io/vmm/vmm_lapic.c | 18 |
9 files changed, 195 insertions, 59 deletions
diff --git a/usr/src/boot/Makefile.version b/usr/src/boot/Makefile.version index 5661e6deab..ecd10c4cd9 100644 --- a/usr/src/boot/Makefile.version +++ b/usr/src/boot/Makefile.version @@ -34,4 +34,4 @@ LOADER_VERSION = 1.1 # Use date like formatting here, YYYY.MM.DD.XX, without leading zeroes. # The version is processed from left to right, the version number can only # be increased. -BOOT_VERSION = $(LOADER_VERSION)-2020.12.04.2 +BOOT_VERSION = $(LOADER_VERSION)-2020.12.07.1 diff --git a/usr/src/boot/lib/libstand/zfs/nvlist.c b/usr/src/boot/lib/libstand/zfs/nvlist.c index 95e919672a..f786bfd9db 100644 --- a/usr/src/boot/lib/libstand/zfs/nvlist.c +++ b/usr/src/boot/lib/libstand/zfs/nvlist.c @@ -1222,10 +1222,9 @@ nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type, break; case DATA_TYPE_BYTE_ARRAY: - *(unsigned *)nvl->nv_idx = encoded_size; - nvl->nv_idx += sizeof (unsigned); - bcopy(data, nvl->nv_idx, nelem); - nvl->nv_idx += encoded_size; + xdr.xdr_idx += xdr.xdr_putuint(&xdr, encoded_size); + bcopy(data, xdr.xdr_idx, nelem); + xdr.xdr_idx += NV_ALIGN4(encoded_size); break; case DATA_TYPE_STRING: @@ -1311,20 +1310,20 @@ nvlist_add_common(nvlist_t *nvl, const char *name, data_type_t type, break; case DATA_TYPE_NVLIST_ARRAY: { - uint8_t *buf = nvl->nv_idx; size_t size; - xdr_t xdr; + xdr_t xdr_nv; for (uint32_t i = 0; i < nelem; i++) { - xdr.xdr_idx = ((nvlist_t **)data)[i]->nv_data; - xdr.xdr_buf = xdr.xdr_idx; - xdr.xdr_buf_size = ((nvlist_t **)data)[i]->nv_size; + xdr_nv.xdr_idx = ((nvlist_t **)data)[i]->nv_data; + xdr_nv.xdr_buf = xdr_nv.xdr_idx; + xdr_nv.xdr_buf_size = ((nvlist_t **)data)[i]->nv_size; - if (!nvlist_size_native(&xdr, &size)) + if (!nvlist_size_native(&xdr_nv, &size)) return (EINVAL); - bcopy(((nvlist_t **)data)[i]->nv_data, buf, size); - buf += size; + bcopy(((nvlist_t **)data)[i]->nv_data, xdr.xdr_idx, + size); + xdr.xdr_idx += size; } break; } @@ -1617,6 +1616,7 @@ nvpair_print(nvp_header_t *nvp, unsigned int indent) case DATA_TYPE_INT64_ARRAY: case DATA_TYPE_UINT64_ARRAY: { uint64_t *u; + if (xdr_array(&xdr, nvp_data->nv_nelem, (xdrproc_t)xdr_uint64)) { u = (uint64_t *)(nvp_data->nv_data + sizeof (unsigned)); diff --git a/usr/src/boot/sys/boot/common/gfx_fb.c b/usr/src/boot/sys/boot/common/gfx_fb.c index 94b9c71bef..361076fc2b 100644 --- a/usr/src/boot/sys/boot/common/gfx_fb.c +++ b/usr/src/boot/sys/boot/common/gfx_fb.c @@ -27,6 +27,7 @@ #include <efilib.h> #else #include <btxv86.h> +#include <vbe.h> #endif #include <sys/tem_impl.h> #include <sys/consplat.h> @@ -1205,7 +1206,7 @@ gfx_fb_putimage(png_t *png, uint32_t ux1, uint32_t uy1, uint32_t ux2, struct vis_consdisplay da; uint32_t i, j, x, y, fheight, fwidth, color; int fbpp; - uint8_t r, g, b, a, *p; + uint8_t r, g, b, a; bool scale = false; bool trace = false; @@ -1433,40 +1434,74 @@ gfx_fb_putimage(png_t *png, uint32_t ux1, uint32_t uy1, uint32_t ux2, << gfx_fb.u.fb2.framebuffer_blue_field_position; switch (gfx_fb.framebuffer_common.framebuffer_bpp) { +#if !defined(EFI) case 8: { uint32_t best, dist, k; int diff; + /* if alpha is 0, use screen bg color */ + if (a == 0) { + text_color_t fg, bg; + + tem_get_colors( + (tem_vt_state_t)tems.ts_active, + &fg, &bg); + da.data[j] = gfx_fb_color_map(bg); + break; + } + color = 0; - best = 256 * 256 * 256; - for (k = 0; k < 16; k++) { - diff = r - cmap4_to_24.red[k]; + best = CMAP_SIZE * CMAP_SIZE * CMAP_SIZE; + for (k = 0; k < CMAP_SIZE; k++) { + diff = r - pe8[k].Red; dist = diff * diff; - diff = g - cmap4_to_24.green[k]; + diff = g - pe8[k].Green; dist += diff * diff; - diff = b - cmap4_to_24.blue[k]; + diff = b - pe8[k].Blue; dist += diff * diff; + if (dist == 0) + break; + if (dist < best) { color = k; best = dist; - if (dist == 0) - break; } } - da.data[j] = solaris_color_to_pc_color[color]; + if (k == CMAP_SIZE) + k = color; + da.data[j] = (k < 16) ? + solaris_color_to_pc_color[k] : k; break; } case 15: case 16: + /* if alpha is 0, use screen bg color */ + if (a == 0) { + text_color_t fg, bg; + + tem_get_colors( + (tem_vt_state_t)tems.ts_active, + &fg, &bg); + color = gfx_fb_color_map(bg); + } *(uint16_t *)(da.data+j) = color; break; case 24: - p = (uint8_t *)&color; - da.data[j] = p[0]; - da.data[j+1] = p[1]; - da.data[j+2] = p[2]; + /* if alpha is 0, use screen bg color */ + if (a == 0) { + text_color_t fg, bg; + + tem_get_colors( + (tem_vt_state_t)tems.ts_active, + &fg, &bg); + color = gfx_fb_color_map(bg); + } + da.data[j] = ((uint8_t *)&color)[0]; + da.data[j + 1] = ((uint8_t *)&color)[1]; + da.data[j + 2] = ((uint8_t *)&color)[2]; break; +#endif case 32: color |= a << 24; *(uint32_t *)(da.data+j) = color; diff --git a/usr/src/boot/sys/boot/i386/libi386/vbe.h b/usr/src/boot/sys/boot/i386/libi386/vbe.h index 1a9ff770d1..c775b13012 100644 --- a/usr/src/boot/sys/boot/i386/libi386/vbe.h +++ b/usr/src/boot/sys/boot/i386/libi386/vbe.h @@ -142,6 +142,7 @@ struct flatpanelinfo #define CMAP_SIZE 256 /* Number of colors in palette */ +extern struct paletteentry pe8[CMAP_SIZE]; extern int palette_format; /* high-level VBE helpers, from vbe.c */ diff --git a/usr/src/boot/sys/boot/i386/libi386/vidconsole.c b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c index a1eb1b37c9..9dff446903 100644 --- a/usr/src/boot/sys/boot/i386/libi386/vidconsole.c +++ b/usr/src/boot/sys/boot/i386/libi386/vidconsole.c @@ -78,6 +78,9 @@ static vis_modechg_cb_t modechg_cb; static struct vis_modechg_arg *modechg_arg; static tem_vt_state_t tem; +/* RGB colors for 8-bit depth */ +struct paletteentry pe8[CMAP_SIZE]; + #define KEYBUFSZ 10 #define DEFAULT_FGCOLOR 7 #define DEFAULT_BGCOLOR 0 @@ -542,7 +545,6 @@ static int vidc_vbe_cons_put_cmap(struct vis_cmap *cm) { int i, rc; - struct paletteentry pe; rgb_t rgb; uint32_t c; @@ -568,8 +570,6 @@ vidc_vbe_cons_put_cmap(struct vis_cmap *cm) rgb.blue.pos = gfx_fb.u.fb2.framebuffer_blue_field_position; rgb.blue.size = gfx_fb.u.fb2.framebuffer_blue_mask_size; - pe.Alignment = 0; - /* * The first 16 colors need to be in VGA color order. */ @@ -582,10 +582,12 @@ vidc_vbe_cons_put_cmap(struct vis_cmap *cm) } else { c = rgb_color_map(&rgb, i); } - pe.Red = (c >> rgb.red.pos) & ((1 << rgb.red.size) - 1); - pe.Green = (c >> rgb.green.pos) & ((1 << rgb.green.size) - 1); - pe.Blue = (c >> rgb.blue.pos) & ((1 << rgb.blue.size) - 1); - rc = vbe_set_palette(&pe, i); + pe8[i].Red = (c >> rgb.red.pos) & ((1 << rgb.red.size) - 1); + pe8[i].Green = + (c >> rgb.green.pos) & ((1 << rgb.green.size) - 1); + pe8[i].Blue = (c >> rgb.blue.pos) & ((1 << rgb.blue.size) - 1); + pe8[i].Alignment = 0; + rc = vbe_set_palette(&pe8[i], i); } return (rc); } diff --git a/usr/src/uts/common/io/aggr/aggr_grp.c b/usr/src/uts/common/io/aggr/aggr_grp.c index 9a4a936450..a4cfdad51e 100644 --- a/usr/src/uts/common/io/aggr/aggr_grp.c +++ b/usr/src/uts/common/io/aggr/aggr_grp.c @@ -607,6 +607,8 @@ aggr_grp_add_port(aggr_grp_t *grp, datalink_id_t port_linkid, boolean_t force, port->lp_grp = grp; AGGR_GRP_REFHOLD(grp); grp->lg_nports++; + if (grp->lg_nports > grp->lg_nports_high) + grp->lg_nports_high = grp->lg_nports; aggr_lacp_init_port(port); mac_perim_exit(mph); @@ -675,7 +677,7 @@ aggr_add_pseudo_rx_ring(aggr_port_t *port, * No slot for this new RX ring. */ if (j == MAX_RINGS_PER_GROUP) - return (EIO); + return (ENOSPC); ring->arr_flags |= MAC_PSEUDO_RING_INUSE; ring->arr_hw_rh = hw_rh; @@ -884,7 +886,7 @@ aggr_add_pseudo_tx_ring(aggr_port_t *port, * No slot for this new TX ring. */ if (i == MAX_RINGS_PER_GROUP) - return (EIO); + return (ENOSPC); /* * The following 4 statements needs to be done before * calling mac_group_add_ring(). Otherwise it will @@ -948,7 +950,8 @@ aggr_rem_pseudo_tx_ring(aggr_pseudo_tx_group_t *tx_grp, * rings of the aggr and the hardware rings of the underlying port. */ static int -aggr_add_pseudo_tx_group(aggr_port_t *port, aggr_pseudo_tx_group_t *tx_grp) +aggr_add_pseudo_tx_group(aggr_port_t *port, aggr_pseudo_tx_group_t *tx_grp, + uint_t limit) { aggr_grp_t *grp = port->lp_grp; mac_ring_handle_t hw_rh[MAX_RINGS_PER_GROUP], pseudo_rh; @@ -956,6 +959,9 @@ aggr_add_pseudo_tx_group(aggr_port_t *port, aggr_pseudo_tx_group_t *tx_grp) int hw_rh_cnt, i = 0, j; int err = 0; + if (limit == 0) + return (ENOSPC); + ASSERT(MAC_PERIM_HELD(grp->lg_mh)); mac_perim_enter_by_mh(port->lp_mh, &pmph); @@ -973,12 +979,13 @@ aggr_add_pseudo_tx_group(aggr_port_t *port, aggr_pseudo_tx_group_t *tx_grp) if (hw_rh_cnt == 0) port->lp_tx_ring_cnt = 1; else - port->lp_tx_ring_cnt = hw_rh_cnt; + port->lp_tx_ring_cnt = MIN(hw_rh_cnt, limit); + port->lp_tx_ring_alloc = port->lp_tx_ring_cnt; port->lp_tx_rings = kmem_zalloc((sizeof (mac_ring_handle_t *) * - port->lp_tx_ring_cnt), KM_SLEEP); + port->lp_tx_ring_alloc), KM_SLEEP); port->lp_pseudo_tx_rings = kmem_zalloc((sizeof (mac_ring_handle_t *) * - port->lp_tx_ring_cnt), KM_SLEEP); + port->lp_tx_ring_alloc), KM_SLEEP); if (hw_rh_cnt == 0) { if ((err = aggr_add_pseudo_tx_ring(port, tx_grp, @@ -987,7 +994,7 @@ aggr_add_pseudo_tx_group(aggr_port_t *port, aggr_pseudo_tx_group_t *tx_grp) port->lp_pseudo_tx_rings[0] = pseudo_rh; } } else { - for (i = 0; err == 0 && i < hw_rh_cnt; i++) { + for (i = 0; err == 0 && i < port->lp_tx_ring_cnt; i++) { err = aggr_add_pseudo_tx_ring(port, tx_grp, hw_rh[i], &pseudo_rh); if (err != 0) @@ -1005,10 +1012,11 @@ aggr_add_pseudo_tx_group(aggr_port_t *port, aggr_pseudo_tx_group_t *tx_grp) } } kmem_free(port->lp_tx_rings, - (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_cnt)); + (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_alloc)); kmem_free(port->lp_pseudo_tx_rings, - (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_cnt)); + (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_alloc)); port->lp_tx_ring_cnt = 0; + port->lp_tx_ring_alloc = 0; } else { port->lp_tx_grp_added = B_TRUE; port->lp_tx_notify_mh = mac_client_tx_notify(port->lp_mch, @@ -1042,9 +1050,9 @@ aggr_rem_pseudo_tx_group(aggr_port_t *port, aggr_pseudo_tx_group_t *tx_grp) aggr_rem_pseudo_tx_ring(tx_grp, port->lp_pseudo_tx_rings[i]); kmem_free(port->lp_tx_rings, - (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_cnt)); + (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_alloc)); kmem_free(port->lp_pseudo_tx_rings, - (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_cnt)); + (sizeof (mac_ring_handle_t *) * port->lp_tx_ring_alloc)); port->lp_tx_ring_cnt = 0; (void) mac_client_tx_notify(port->lp_mch, NULL, port->lp_tx_notify_mh); @@ -1111,6 +1119,48 @@ aggr_pseudo_stop_rx_ring(mac_ring_driver_t arg) } /* + * Trim each port in a group to ensure it uses no more than tx_ring_limit + * rings. + */ +static void +aggr_grp_balance_tx(aggr_grp_t *grp, uint_t tx_ring_limit) +{ + aggr_port_t *port; + mac_perim_handle_t mph; + uint_t i, tx_ring_cnt; + + ASSERT(tx_ring_limit > 0); + ASSERT(MAC_PERIM_HELD(grp->lg_mh)); + + for (port = grp->lg_ports; port != NULL; port = port->lp_next) { + mac_perim_enter_by_mh(port->lp_mh, &mph); + + /* + * Reduce the Tx ring count first to prevent rings being + * used as they are removed. + */ + rw_enter(&grp->lg_tx_lock, RW_WRITER); + if (port->lp_tx_ring_cnt <= tx_ring_limit) { + rw_exit(&grp->lg_tx_lock); + mac_perim_exit(mph); + continue; + } + + tx_ring_cnt = port->lp_tx_ring_cnt; + port->lp_tx_ring_cnt = tx_ring_limit; + rw_exit(&grp->lg_tx_lock); + + for (i = tx_ring_cnt - 1; i >= tx_ring_limit; i--) { + aggr_rem_pseudo_tx_ring(&grp->lg_tx_group, + port->lp_pseudo_tx_rings[i]); + + } + + mac_perim_exit(mph); + } +} + +/* * Add one or more ports to an existing link aggregation group. */ int @@ -1120,6 +1170,7 @@ aggr_grp_add_ports(datalink_id_t linkid, uint_t nports, boolean_t force, int rc; uint_t port_added = 0; uint_t grp_added; + uint_t nports_high, tx_ring_limit; aggr_grp_t *grp = NULL; aggr_port_t *port; boolean_t link_state_changed = B_FALSE; @@ -1140,6 +1191,24 @@ aggr_grp_add_ports(datalink_id_t linkid, uint_t nports, boolean_t force, mac_perim_enter_by_mh(grp->lg_mh, &mph); rw_exit(&aggr_grp_lock); + /* + * Limit the number of Tx rings per port. When determining the + * number of ports take into consideration the existing high + * value, and what the new high value may be after this request. + */ + nports_high = MAX(grp->lg_nports_high, grp->lg_nports + nports); + tx_ring_limit = MAX_RINGS_PER_GROUP / nports_high; + + if (tx_ring_limit == 0) { + rc = ENOSPC; + goto bail; + } + + /* + * Balance the Tx rings so each port has a fair share of rings. + */ + aggr_grp_balance_tx(grp, tx_ring_limit); + /* Add the specified ports to the aggr. */ for (uint_t i = 0; i < nports; i++) { grp_added = 0; @@ -1164,7 +1233,8 @@ aggr_grp_add_ports(datalink_id_t linkid, uint_t nports, boolean_t force, * Create the pseudo ring for each HW ring of the underlying * port. */ - rc = aggr_add_pseudo_tx_group(port, &grp->lg_tx_group); + rc = aggr_add_pseudo_tx_group(port, &grp->lg_tx_group, + tx_ring_limit); if (rc != 0) goto bail; @@ -1380,6 +1450,7 @@ aggr_grp_create(datalink_id_t linkid, uint32_t key, uint_t nports, mac_perim_handle_t mph, pmph; datalink_id_t tempid; boolean_t mac_registered = B_FALSE; + uint_t tx_ring_limit; int err; int i, j; kt_did_t tid = 0; @@ -1551,6 +1622,25 @@ aggr_grp_create(datalink_id_t linkid, uint32_t key, uint_t nports, aggr_lacp_set_mode(grp, lacp_mode, lacp_timer); /* + * The pseudo Tx group holds a maximum of MAX_RINGS_PER_GROUP + * rings, when all the Tx rings of all the ports are accumulated + * it is conceivable this limit is exceeded. We try and prevent + * this by limiting the number of rings an individual port will use. + * + * - When an aggr is first created, we will not let an + * individual port use more than MAX_RINGS_PER_GROUP/nports + * rings. + * - As ports are added to an existing aggr, each of the + * ports will not use more than MAX_RINGS_PER_GROUP/nports_high. + * Where nports_high is the highest number of ports the aggr has + * held (including any ports being added). This may involve + * trimming rings from existing ports. + */ + + /* Leave room for 4 ports */ + tx_ring_limit = MAX_RINGS_PER_GROUP / MAX(4, nports); + + /* * Attach each port if necessary. */ for (port = grp->lg_ports; port != NULL; port = port->lp_next) { @@ -1559,7 +1649,8 @@ aggr_grp_create(datalink_id_t linkid, uint32_t key, uint_t nports, * underlying port. Note that this is done after the * aggr registers its MAC. */ - err = aggr_add_pseudo_tx_group(port, &grp->lg_tx_group); + err = aggr_add_pseudo_tx_group(port, &grp->lg_tx_group, + tx_ring_limit); if (err != 0) { mac_perim_exit(mph); diff --git a/usr/src/uts/common/io/mlxcx/mlxcx.c b/usr/src/uts/common/io/mlxcx/mlxcx.c index 90964d2fd1..9aae5244de 100644 --- a/usr/src/uts/common/io/mlxcx/mlxcx.c +++ b/usr/src/uts/common/io/mlxcx/mlxcx.c @@ -2874,10 +2874,14 @@ mlxcx_attach(dev_info_t *dip, ddi_attach_cmd_t cmd) } mlxp->mlx_attach |= MLXCX_ATTACH_CHKTIMERS; - if (!mlxcx_setup_sensors(mlxp)) { - goto err; + /* + * Some devices may not have a working temperature sensor; however, + * there isn't a great way for us to know. We shouldn't fail attach if + * this doesn't work. + */ + if (mlxcx_setup_sensors(mlxp)) { + mlxp->mlx_attach |= MLXCX_ATTACH_SENSORS; } - mlxp->mlx_attach |= MLXCX_ATTACH_SENSORS; /* * Finally, tell MAC that we exist! diff --git a/usr/src/uts/common/sys/aggr_impl.h b/usr/src/uts/common/sys/aggr_impl.h index 80733aa31e..de4162bc61 100644 --- a/usr/src/uts/common/sys/aggr_impl.h +++ b/usr/src/uts/common/sys/aggr_impl.h @@ -23,6 +23,7 @@ * Use is subject to license terms. * Copyright 2012 OmniTI Computer Consulting, Inc All rights reserved. * Copyright 2018 Joyent, Inc. + * Copyright 2020 RackTop Systems, Inc. */ #ifndef _SYS_AGGR_IMPL_H @@ -161,7 +162,8 @@ typedef struct aggr_port_s { */ mac_group_handle_t lp_hwghs[MAX_GROUPS_PER_PORT]; - int lp_tx_ring_cnt; + uint_t lp_tx_ring_alloc; + uint_t lp_tx_ring_cnt; /* handles of the underlying HW TX rings */ mac_ring_handle_t *lp_tx_rings; /* @@ -195,6 +197,7 @@ typedef struct aggr_grp_s { uint16_t lg_key; /* key (group port number) */ uint32_t lg_refs; /* refcount */ uint16_t lg_nports; /* number of MAC ports */ + uint16_t lg_nports_high; /* highest no. of MAC ports */ uint8_t lg_addr[ETHERADDRL]; /* group MAC address */ uint16_t lg_closing : 1, diff --git a/usr/src/uts/i86pc/io/vmm/vmm_lapic.c b/usr/src/uts/i86pc/io/vmm/vmm_lapic.c index f28a2f1ffd..a5118c15af 100644 --- a/usr/src/uts/i86pc/io/vmm/vmm_lapic.c +++ b/usr/src/uts/i86pc/io/vmm/vmm_lapic.c @@ -38,6 +38,7 @@ * http://www.illumos.org/license/CDDL. * * Copyright 2014 Pluribus Networks Inc. + * Copyright 2020 Oxide Computer Company */ #include <sys/cdefs.h> @@ -127,19 +128,18 @@ lapic_intr_msi(struct vm *vm, uint64_t addr, uint64_t msg) } /* - * Extract the x86-specific fields from the MSI addr/msg - * params according to the Intel Arch spec, Vol3 Ch 10. + * Extract the x86-specific fields from the MSI addr/msg params + * according to the Intel Arch spec, Vol3 Ch 10. * - * The PCI specification does not support level triggered - * MSI/MSI-X so ignore trigger level in 'msg'. + * The PCI specification does not support level triggered MSI/MSI-X so + * ignore trigger level in 'msg'. * - * The 'dest' is interpreted as a logical APIC ID if both - * the Redirection Hint and Destination Mode are '1' and - * physical otherwise. + * Certain kinds of interrupt broadcasts (physical or logical-clustered + * for destination 0xff) are prohibited when the redirection hint bit is + * set for a given message. Those edge cases are ignored for now. */ dest = (addr >> 12) & 0xff; - phys = ((addr & (MSI_X86_ADDR_RH | MSI_X86_ADDR_LOG)) != - (MSI_X86_ADDR_RH | MSI_X86_ADDR_LOG)); + phys = (addr & MSI_X86_ADDR_LOG) == 0; delmode = msg & APIC_DELMODE_MASK; vec = msg & 0xff; |