On Thu, Apr 09, 2026 at 02:52:32PM -0700, Dexuan Cui wrote:
> With commit f84b21da3624 ("PCI: hv: Don't load the driver for baremetal root 
> partition"),
> the bare metal Linux root partition won't use the pci-hyperv driver, but
> when a Linux VM runs on the Linux root partition, pci-hyperv's module_init
> function init_hv_pci_drv() can still run, e.g. in the case of
> CONFIG_PCI_HYPERV=y, even if the VMBus driver is not used in such a VM
> (i.e. the hv_vmbus driver's init function returns -ENODEV due to
> vmbus_root_device being NULL).
> 
> In such a Linux VM, init_hv_pci_drv() runs with a side effect: the 3
> hvpci_block_ops callbacks are set to functions that depend on hv_vmbus.
> 
> Later, when the MLX driver in such a VM invokes the callbacks, e.g. in
> drivers/net/ethernet/mellanox/mlx5/core/lib/hv.c:
> mlx5_hv_register_invalidate(), hvpci_block_ops.reg_blk_invalidate() is
> hv_register_block_invalidate() rather than a NULL function pointer, and
> hv_register_block_invalidate() assumes that it can find a struct
> hv_pcibus_device from pdev->bus->sysdata, which is false in such a VM.
> 
> Consequently, hv_register_block_invalidate() -> get_pcichild_wslot() ->
> spin_lock_irqsave() may hang since it can be accessing an invalid
> spinlock pointer.
> 
> Fix the issue by exporting hv_vmbus_exists() and using it in pci-hyperv:
> 
>     hv_root_partition() is true and hv_nested is false ==>
>       hv_vmbus_exists() is false.
> 
>     hv_root_partition() is true and hv_nested is true ==>
>       hv_vmbus_exists() is true.
> 
>     hv_root_partition() is false ==> hv_vmbus_exists() is true.
> 
> While at it, rename vmbus_exists() to hv_vmbus_exists() to follow the
> convention that all public functions have the hv_ prefix; also change
> the return value's type from int to bool to make the code more readable;
> also move the two pr_info() calls.
> 
> Reported-by: Mukesh Rathor <[email protected]>
> Signed-off-by: Dexuan Cui <[email protected]>

Applied. Thanks.

Reply via email to