summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/boot/Makefile.version2
-rw-r--r--usr/src/boot/lib/libstand/zfs/nvlist.c24
-rw-r--r--usr/src/boot/sys/boot/common/gfx_fb.c61
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/vbe.h1
-rw-r--r--usr/src/boot/sys/boot/i386/libi386/vidconsole.c16
-rw-r--r--usr/src/uts/common/io/aggr/aggr_grp.c117
-rw-r--r--usr/src/uts/common/io/mlxcx/mlxcx.c10
-rw-r--r--usr/src/uts/common/sys/aggr_impl.h5
-rw-r--r--usr/src/uts/i86pc/io/vmm/vmm_lapic.c18
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;