NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

kern/60145: vioif(4) panic on NetBSD/virt68k 11.0_RC2



>Number:         60145
>Category:       kern
>Synopsis:       vioif(4) panic on NetBSD/virt68k 11.0_RC2
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 30 03:00:00 +0000 2026
>Originator:     Tetsuya Isaki
>Release:        NetBSD/virt68k 11.0_RC2
>Organization:
>Environment:
NetBSD 11.0_RC2 virt68k
>Description:
A kernel panic occurred after boot up virt68k, without any
user interaction.  Here is a hand-copied panic message.

trap: bad kernel read/write access at 0x28
trap type 8, code = 0x4025105, v = 0x28
kernel program counter = 0x1e2ca4
kernel: MMU fault trap
pid = 0, lid = 3, pc = 001E2CA4, ps = 2500 , sfc = 1, dfc = 1
dreg: 0000005A 00002004 00000001 00458C00 00431C40 00000100 02F9DF28 02F9DF2C
areg: 00000000 00458C00 00468400 004337C0 001E07C6 001BD824 001E2B8A FFEFFFFC
:

Here are the corresponding C and assembly sources (with comment)
around PC=0x1e2ca4.

001e2c24 <vioif_rx_deq_locked>:
 :
  1e2c86:       4878 0002       pea 2 <E1>          ; BUS_DMASYNC_POSTREAD
  1e2c8a:       2200            movel %d0,%d1
  1e2c8c:       e989            lsll #4,%d1
  1e2c8e:       d2ab 0010       addl %a3@(16),%d1
  1e2c92:       2f01            movel %d1,%sp@-     ; map
  1e2c94:       2f00            movel %d0,%sp@-     ; slot
  1e2c96:       2f03            movel %d3,%sp@-     ; vq
  1e2c98:       2f04            movel %d4,%sp@-     ; vsc
  1e2c9a:       4e96            jsr %a6@            ; vioif_net_dequeue_commit
  1e2c9c:       202f 0048       movel %sp@(72),%d0  ; len 
  1e2ca0:       90aa 0014       subl %a2@(20),%d0   ; minus sc->sc_hdr_size
  1e2ca4:       2140 0028       movel %d0,%a0@(40)  ; assign to two vars. <==
  1e2ca8:       2140 0010       movel %d0,%a0@(16)  ; assign to two vars.

sys/dev/pci/if_vioif.c:
 1810 vioif_rx_deq_locked(struct vioif_softc *sc, struct virtio_softc *vsc,
 1811     struct vioif_netqueue *netq, u_int limit, size_t *ndeqp)
 1812 {
 :
 1835         if (virtio_dequeue(vsc, vq, &slot, &len) != 0)
 1836             break;
 1837
 1838         map = &netq->netq_maps[slot];
 1839         KASSERT(map->vnm_mbuf != NULL);
 1840         m = vioif_net_dequeue_commit(vsc, vq, slot,
 1841             map, BUS_DMASYNC_POSTREAD);
 1842         KASSERT(m != NULL);
 1843
 1844         m->m_len = m->m_pkthdr.len = len - sc->sc_hdr_size;

If m happens to be NULL at line 1840, it will cause this panic at 1844.
In fact, %a0 was 0 according to the panic message.
I think this KASSERT at 1842 means that "if virtio_dequeue() returns
0(success, dequeue-able), vioif_net_dequeue_commit() must be succeeded".
If so, I suspect that virtio_dequeue() accidentally returns 0 even
though vq was just dequeued and is empty.

I'm not sure but how about this?

sys/dev/pci/virtio.c:
 1322 virtio_dequeue(struct virtio_softc *sc, struct virtqueue *vq,
 1323     int *slotp, int *lenp)
 1324 {
 1325     uint16_t slot, usedidx;
 1326

  <== need vq_sync_uring_all(PREREAD) to invalidate vq->vq_used->idx
      (and following vq->vq_used->ring[].id payload together ?)
      on the cache line?

 1327     if (vq->vq_used_idx == virtio_rw16(sc, vq->vq_used->idx))
 1328         return ENOENT;
 1329     mutex_enter(&vq->vq_uring_lock);
 1330     usedidx = vq->vq_used_idx++;
 1331     mutex_exit(&vq->vq_uring_lock);
 1332     usedidx %= vq->vq_num;
 1333     slot = virtio_rw32(sc, vq->vq_used->ring[usedidx].id);
 1334
 1335     if (vq->vq_descx[slot].use_indirect)
 1336         vq_sync_indirect(sc, vq, slot, BUS_DMASYNC_POSTWRITE);
 1337
 1338     if (slotp)
 1339         *slotp = slot;
 1340     if (lenp)
 1341         *lenp = virtio_rw32(sc, vq->vq_used->ring[usedidx].len);
 1342
 1343     return 0;
 1344 }

>How-To-Repeat:
Boot NetBSD/virt68k on emulator which implements a data cache.
Up vioif(4) and wait...
>Fix:
See above.




Home | Main Index | Thread Index | Old Index