git: 0705b7f4e64f - main - bhyve: Avoid using a packed struct for xhci port registers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 18 Nov 2022 19:13:06 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=0705b7f4e64fdbad49a3a6d9131029a9734deb2c
commit 0705b7f4e64fdbad49a3a6d9131029a9734deb2c
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2022-11-18 19:07:38 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2022-11-18 19:11:48 +0000
bhyve: Avoid using a packed struct for xhci port registers
I believe the __packed annotation is there only because
pci_xhci_portregs_read() is treating the register set as an array of
uint32_t. clang warns about taking the address of portregs->portsc
because it is a packed member and thus might not have expected
alignment.
Fix the problem by simply selecting the field to read with a switch
statement. This mimics pci_xhci_portregs_write(). While here, switch
to using some symbolic constants.
There is a small semantic change here in that pci_xhci_portregs_read()
would silently truncate unaligned offsets. For consistency with
pci_xhci_portregs_write(), which does not do that, return all ones for
unaligned reads instead.
MFC after: 2 weeks
Reviewed by: corvink, jhb
Differential Revision: https://reviews.freebsd.org/D37408
---
usr.sbin/bhyve/pci_xhci.c | 36 ++++++++++++++++++++++++++++--------
1 file changed, 28 insertions(+), 8 deletions(-)
diff --git a/usr.sbin/bhyve/pci_xhci.c b/usr.sbin/bhyve/pci_xhci.c
index 1f3d78a4cfea..f95f62fbf0e5 100644
--- a/usr.sbin/bhyve/pci_xhci.c
+++ b/usr.sbin/bhyve/pci_xhci.c
@@ -568,6 +568,10 @@ pci_xhci_portregs_write(struct pci_xhci_softc *sc, uint64_t offset,
*/
p->porthlpmc = value;
break;
+ default:
+ DPRINTF(("pci_xhci: unaligned portreg write offset %#lx",
+ offset));
+ break;
}
}
@@ -2132,12 +2136,13 @@ pci_xhci_portregs_read(struct pci_xhci_softc *sc, uint64_t offset)
{
struct pci_xhci_portregs *portregs;
int port;
- uint32_t *p;
+ uint32_t reg;
if (sc->portregs == NULL)
return (0);
- port = (offset - 0x3F0) / 0x10;
+ port = (offset - XHCI_PORTREGS_PORT0) / XHCI_PORTREGS_SETSZ;
+ offset = (offset - XHCI_PORTREGS_PORT0) % XHCI_PORTREGS_SETSZ;
if (port > XHCI_MAX_DEVS) {
DPRINTF(("pci_xhci: portregs_read port %d >= XHCI_MAX_DEVS",
@@ -2147,16 +2152,31 @@ pci_xhci_portregs_read(struct pci_xhci_softc *sc, uint64_t offset)
return (XHCI_PS_SPEED_SET(3));
}
- offset = (offset - 0x3F0) % 0x10;
-
portregs = XHCI_PORTREG_PTR(sc, port);
- p = &portregs->portsc;
- p += offset / sizeof(uint32_t);
+ switch (offset) {
+ case 0:
+ reg = portregs->portsc;
+ break;
+ case 4:
+ reg = portregs->portpmsc;
+ break;
+ case 8:
+ reg = portregs->portli;
+ break;
+ case 12:
+ reg = portregs->porthlpmc;
+ break;
+ default:
+ DPRINTF(("pci_xhci: unaligned portregs read offset %#lx",
+ offset));
+ reg = 0xffffffff;
+ break;
+ }
DPRINTF(("pci_xhci: portregs read offset 0x%lx port %u -> 0x%x",
- offset, port, *p));
+ offset, port, reg));
- return (*p);
+ return (reg);
}
static void