git: 7cd6d2365b31 - main - e1000: Correct VF register validation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 30 Jul 2026 14:06:06 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=7cd6d2365b3121743dfd6012e259a3b05b0e7adb
commit 7cd6d2365b3121743dfd6012e259a3b05b0e7adb
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-07-30 10:29:57 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-07-30 14:05:59 +0000
e1000: Correct VF register validation
Pass the VF generation through the CSR accessors so the validator can
distinguish the sparse 82576 and I350 register maps.
Admit the queue-zero RXCTRL, TXCTRL, TDWBAL, TDWBAH, and
VFPSRTYPE registers exposed by both families.
82576 exposes VFMPRC at 0xf3c. I350 erratum 31 makes its
corrected 0xf38 address inaccessible to a VF, so reject both I350
spellings while retaining read access on 82576.
Sponsored by: BBOX.io
---
sys/dev/e1000/e1000_osdep.h | 22 ++++++++++++++++++----
sys/dev/e1000/if_em.c | 1 +
2 files changed, 19 insertions(+), 4 deletions(-)
diff --git a/sys/dev/e1000/e1000_osdep.h b/sys/dev/e1000/e1000_osdep.h
index c7e938f5c93c..0f6364f9a7b5 100644
--- a/sys/dev/e1000/e1000_osdep.h
+++ b/sys/dev/e1000/e1000_osdep.h
@@ -162,6 +162,7 @@ struct e1000_osdep
device_t dev;
if_ctx_t ctx;
bool vf;
+ bool vf_82576;
};
#ifdef INVARIANTS
@@ -174,7 +175,7 @@ struct e1000_osdep
* support must extend this predicate from the applicable device CSR map.
*/
static __inline bool
-e1000_vf_reg_valid(uint32_t reg, bool write)
+e1000_vf_reg_valid(uint32_t reg, bool write, bool vf_82576)
{
/* VF mailbox memory: 16 dwords beginning at 0x800. */
if (reg >= 0x00800 && reg <= 0x0083c && (reg & 3) == 0)
@@ -191,6 +192,7 @@ e1000_vf_reg_valid(uint32_t reg, bool write)
case 0x02808: /* RDLEN */
case 0x0280c: /* SRRCTL */
case 0x02810: /* RDH */
+ case 0x02814: /* RXCTL */
case 0x02818: /* RDT */
case 0x02828: /* RXDCTL */
return (true);
@@ -202,15 +204,26 @@ e1000_vf_reg_valid(uint32_t reg, bool write)
case 0x03804: /* TDBAH */
case 0x03808: /* TDLEN */
case 0x03810: /* TDH */
+ case 0x03814: /* TXCTL */
case 0x03818: /* TDT */
case 0x03828: /* TXDCTL */
+ case 0x03838: /* TDWBAL */
+ case 0x0383c: /* TDWBAH */
return (true);
}
+ /*
+ * 82576 exposes VFMPRC at 0xf3c. I350 erratum 31 makes
+ * its corrected 0xf38 address inaccessible to a VF.
+ */
+ if (vf_82576 && reg == 0x00f3c)
+ return (!write);
+
switch (reg) {
case 0x00000: /* CTRL */
case 0x000c4: /* Legacy ITR, listed but unused by igb VFs */
case 0x00c40: /* V2PMAILBOX(0) */
+ case 0x00f0c: /* VFPSRTYPE */
case 0x01524: /* EIMS */
case 0x0152c: /* EIAC */
case 0x01530: /* EIAM */
@@ -225,7 +238,6 @@ e1000_vf_reg_valid(uint32_t reg, bool write)
case 0x00f14: /* VFGPTC */
case 0x00f18: /* VFGORC */
case 0x00f34: /* VFGOTC */
- case 0x00f3c: /* VFMPRC */
case 0x00f40: /* VFGPRLBC */
case 0x00f44: /* VFGPTLBC */
case 0x00f48: /* VFGORLBC */
@@ -261,7 +273,8 @@ e1000_rd32(struct e1000_osdep *osdep, uint32_t reg)
("e1000: register offset %#jx too large (max is %#jx)",
(uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size));
#ifdef INVARIANTS
- KASSERT(!osdep->vf || e1000_vf_reg_valid(reg, false),
+ KASSERT(!osdep->vf ||
+ e1000_vf_reg_valid(reg, false, osdep->vf_82576),
("e1000: invalid VF register read at %#x", reg));
#endif
@@ -278,7 +291,8 @@ e1000_wr32(struct e1000_osdep *osdep, uint32_t reg, uint32_t value)
("e1000: register offset %#jx too large (max is %#jx)",
(uintmax_t)reg, (uintmax_t)osdep->mem_bus_space_size));
#ifdef INVARIANTS
- KASSERT(!osdep->vf || e1000_vf_reg_valid(reg, true),
+ KASSERT(!osdep->vf ||
+ e1000_vf_reg_valid(reg, true, osdep->vf_82576),
("e1000: invalid VF register write at %#x", reg));
#endif
diff --git a/sys/dev/e1000/if_em.c b/sys/dev/e1000/if_em.c
index 2269f3014abb..db84004643f2 100644
--- a/sys/dev/e1000/if_em.c
+++ b/sys/dev/e1000/if_em.c
@@ -1254,6 +1254,7 @@ em_if_attach_pre(if_ctx_t ctx)
/* Determine hardware and mac info */
em_identify_hardware(ctx);
+ sc->osdep.vf_82576 = sc->hw.mac.type == e1000_vfadapt;
/* VF sysctls are deferred until attach-post confirms MSI-X. */
ctx_list = device_get_sysctl_ctx(dev);