The branch stable/13 has been updated by jhb:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c8a6e51a4f866f5c497546f9657e44fe1ae0ff66

commit c8a6e51a4f866f5c497546f9657e44fe1ae0ff66
Author:     Mark Johnston <[email protected]>
AuthorDate: 2022-11-18 19:07:38 +0000
Commit:     John Baldwin <[email protected]>
CommitDate: 2023-01-26 20:06:39 +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
    
    (cherry picked from commit 0705b7f4e64fdbad49a3a6d9131029a9734deb2c)
---
 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

Reply via email to