Hello, On Mon, 26 Oct 2026 at 18:00, Stephen Hemminger <[email protected]> wrote: > Subject: Re: [PATCH 0/4] raw/ntb: AMD NTB support > > Post-merge review of the raw/ntb series (1/4 - 3/4) against current > main. Findings below are for follow-up fixes. > > Series summary > -------------- > The ops-table refactor in 1/4 and 2/4 is reasonable. The main problems > are a type-confusion hole in the new public API, an unbounded > peer-supplied loop count that writes past peer_mw_base[], and AMD event > handling that cannot actually run as wired. > > > [PATCH 2/4] raw/ntb: generalize framework for multiple vendors > -------------------------------------------------------------- > > Error: rte_pmd_ntb_get_mem_align() trusts any rawdev id. > > It checks only dev_id < RTE_RAWDEV_MAX_DEVS and dev_private != NULL, > then casts dev_private to struct ntb_hw. Passing the id of an > unattached slot or of a non-NTB rawdev (dpaa2, ifpga, cnxk...) calls > through a garbage ntb_ops pointer. Check the device is valid and is > ours: > > if (!rte_rawdev_pmd_is_valid_dev(dev_id)) > return 0; > dev = rte_rawdev_pmd_get_dev(dev_id); > if (dev->dev_ops != &ntb_ops) > return 0; > > Also, an out of range mw_id returns RTE_CACHE_LINE_SIZE, which > contradicts the doxygen ("0 on error"). Return 0. > > Warning: Rx EOP guard leaks the partial chain and desyncs the ring. > > On the new "Malformed rx stream" path the descriptors already walked > have advanced last_used/last_avail and been chained under `first`, > but nb_rx is not incremented, so the chain is never returned or > freed. If nb_rx == 0 the refilled descriptors are not published > either (avail_cnt not written) while rxq->last_avail has moved. > The mbuf-alloc failure path has the same bug already; the guard > copies it. Free the partial chain and only advance ring indexes for > completed packets. > > The guard also bounds on nb_rx_desc, not on the descriptors the peer > actually published (used_cnt - last_used), so it still reads entries > the peer has not written. This is a fix for code in released > versions; it should be its own patch with Fixes: and > Cc: [email protected], not folded into the refactor. > > Info: removing mw_size_align changes the layout of the installed > struct ntb_dev_info; note it under ABI Changes as well. > > Info: examples/ntb/Makefile adds -lrte_raw_ntb to LDFLAGS, which also > hits the static target. Other examples (l2fwd-crypto, > vm_power_manager) use LDFLAGS_SHARED. > > > [PATCH 3/4] raw/ntb: support AMD NTB > ------------------------------------ > > Error: peer_used_mws from the scratchpad overflows peer_mw_base[]. > > amd_ntb_read_peer_config(): > > ntb->peer_used_mws = (info >> 16) & 0xff; > for (i = 0; i < ntb->peer_used_mws; i++) > ... > ntb->peer_mw_base[i] = ... > > peer_mw_base is rte_zmalloc'd with mw_cnt (2) entries. A peer > advertising more than 2 (bug, version skew, or just garbage in an > uninitialised scratchpad) writes past the allocation. Intel has the > same pattern; fix both: > > if (peer_used_mws > ntb->mw_cnt) { > NTB_LOG(ERR, "Peer used mws %u > mw cnt %u", > peer_used_mws, ntb->mw_cnt); > return -EINVAL; > } > > Warning: hardware events are never delivered. > > - AMD_INTMASK_OFFSET is defined but never written, so event > delivery depends on the reset default. > - ntb_init_hw() enables db_cnt (16) eventfds; the comment in > amd_ntb_vector_bind() says events have their own MSI-X vectors > (AMD_MSIX_VECTOR_COUNT is 24), and those are never enabled. > - handle_hw_event is only called at the bottom of > ntb_dev_intr_handler(), after doorbells 0/1/2 have already > returned early, so it runs only on a stray doorbell. > > As written amd_ntb_handle_hw_event() is effectively dead code. > Either wire up the event vector and INTMASK, or drop it. > > Warning: doorbell interrupts with vfio-pci MSI-X. > > amd_ntb_vector_bind() is a no-op and doorbells map 1:1 to MSI-X > vectors. The callback is registered on the device intr handle only, > so with vfio-pci only vector 0 (DB0) reaches ntb_dev_intr_handler(). > DB1 (peer going down) and DB2 are lost, so the stop handshake in > ntb_dev_stop() never completes. Was this tested with vfio-pci, or > only igb_uio? If uio only, say so in ntb.rst. > > Warning: amd_ntb_handle_hw_event() switches on a bitmask. > > INTSTAT can have several bits set at once; any combination falls to > default and is logged as unknown and never acked to the SMU. Loop > over the set bits, or ack all of (event & AMD_EVENT_INTMASK) after > handling D0. Also drop the duplicated fallthrough comment; one > /* fallthrough */ is enough. > > Warning: ioremap range check is off by one. > > addr <= ntb->peer_mw_base[i] + ntb->mw_size[i] > > accepts one past the end of the window. Should be <. Copied from > intel_ntb_ioremap(), which needs the same fix. > > Warning: ntb->mw_size is never freed. > > Allocated in amd_ntb_dev_init(), not freed on later ntb_init_hw() > failure or in ntb_destroy(). Same leak exists on the Intel side; > free it in common code at release. > > Info: unused defines in ntb_hw_amd.h: AMD_SPADMUTEX_OFFSET, > AMD_DBFM_OFFSET, AMD_INTMASK_OFFSET, AMD_MSIX_VECTOR_COUNT. > > Info: amd_ntb_mw_set_trans() checks IOVA alignment, but > rte_memzone_reserve_aligned() aligns the VA. With IOVA as PA and a > window larger than the hugepage size the IOVA is not guaranteed to > be aligned, and configure fails with -EINVAL. Worth a line in > ntb.rst that large windows need IOVA as VA (or 1G pages). > > Info: amd_ntb_peer_mw_validate() only compares the window count; the > Intel version also checks sizes. Mismatched BAR sizes between hosts > go undetected.
Please look into those warnings and send fixes if confirmed. Thanks. -- David Marchand

