On Wed, May 13, 2026 at 08:08:37AM -0700, Souradeep Chakrabarti wrote:
> On Mon, May 11, 2026 at 07:02:56PM -0700, Mukesh R wrote:
> > On Hyper-V, most hypercalls related to PCI passthru to map/unmap regions,
> > interrupts, etc need a device ID as a parameter. This device ID refers
> > to that specific device during the lifetime of passthru.
> > 
> > An L1VH VM only contains VMBus based devices. A device ID for a VMBus
> > device is slightly different in that it uses the hv_pcibus_device info
> > for building it to make sure it matches exactly what the hypervisor
> > expects. This VMBus based device ID is needed when attaching devices in
> > an L1VH based guest VM. Add a function to build and export it. Before
> > building it, a check is done to make sure the device is a valid VMBus
> > device.
> > 
> > In remaining cases, PCI device ID is used. So, also make PCI device ID
> > build function hv_build_devid_type_pci() public.
> >
Reviewed-by: Souradeep Chakrabarti <[email protected]>
> Reviewed-by: Souradeep Chakrabarti <[email protected]>
> > Signed-off-by: Mukesh R <[email protected]>
> > ---
> >  arch/x86/hyperv/irqdomain.c         |  9 +++++----
> >  arch/x86/include/asm/mshyperv.h     |  6 ++++++
> >  drivers/pci/controller/pci-hyperv.c | 24 ++++++++++++++++++++++++
> >  include/asm-generic/mshyperv.h      | 11 +++++++++++
> >  4 files changed, 46 insertions(+), 4 deletions(-)
> > 
> > diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
> > index b3ad50a874dc..8780573a4332 100644
> > --- a/arch/x86/hyperv/irqdomain.c
> > +++ b/arch/x86/hyperv/irqdomain.c
> > @@ -112,7 +112,7 @@ static int get_rid_cb(struct pci_dev *pdev, u16 alias, 
> > void *data)
> >     return 0;
> >  }
> >  
> > -static union hv_device_id hv_build_devid_type_pci(struct pci_dev *pdev)
> > +u64 hv_build_devid_type_pci(struct pci_dev *pdev)
> >  {
> >     int pos;
> >     union hv_device_id hv_devid;
> > @@ -172,8 +172,9 @@ static union hv_device_id 
> > hv_build_devid_type_pci(struct pci_dev *pdev)
> >     }
> >  
> >  out:
> > -   return hv_devid;
> > +   return hv_devid.as_uint64;
> >  }
> > +EXPORT_SYMBOL_GPL(hv_build_devid_type_pci);
> >  
> >  /*
> >   * hv_map_msi_interrupt() - Map the MSI IRQ in the hypervisor.
> > @@ -196,7 +197,7 @@ int hv_map_msi_interrupt(struct irq_data *data,
> >  
> >     msidesc = irq_data_get_msi_desc(data);
> >     pdev = msi_desc_to_pci_dev(msidesc);
> > -   hv_devid = hv_build_devid_type_pci(pdev);
> > +   hv_devid.as_uint64 = hv_build_devid_type_pci(pdev);
> >     cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
> >  
> >     return hv_map_interrupt(hv_devid, false, cpu, cfg->vector,
> > @@ -271,7 +272,7 @@ static int hv_unmap_msi_interrupt(struct pci_dev *pdev,
> >  {
> >     union hv_device_id hv_devid;
> >  
> > -   hv_devid = hv_build_devid_type_pci(pdev);
> > +   hv_devid.as_uint64 = hv_build_devid_type_pci(pdev);
> >     return hv_unmap_interrupt(hv_devid.as_uint64, irq_entry);
> >  }
> >  
> > diff --git a/arch/x86/include/asm/mshyperv.h 
> > b/arch/x86/include/asm/mshyperv.h
> > index f64393e853ee..2ef34001f8d3 100644
> > --- a/arch/x86/include/asm/mshyperv.h
> > +++ b/arch/x86/include/asm/mshyperv.h
> > @@ -248,6 +248,12 @@ void hv_crash_asm_end(void);
> >  static inline void hv_root_crash_init(void) {}
> >  #endif  /* CONFIG_MSHV_ROOT && CONFIG_CRASH_DUMP */
> >  
> > +#if IS_ENABLED(CONFIG_HYPERV_IOMMU)
> > +u64 hv_build_devid_type_pci(struct pci_dev *pdev);
> > +#else
> > +static inline u64 hv_build_devid_type_pci(struct pci_dev *pdev) { return 
> > 0; }
> > +#endif /* IS_ENABLED(CONFIG_HYPERV_IOMMU) */
> > +
> >  #else /* CONFIG_HYPERV */
> >  static inline void hyperv_init(void) {}
> >  static inline void hyperv_setup_mmu_ops(void) {}
> > diff --git a/drivers/pci/controller/pci-hyperv.c 
> > b/drivers/pci/controller/pci-hyperv.c
> > index cfc8fa403dad..50d793ca8f31 100644
> > --- a/drivers/pci/controller/pci-hyperv.c
> > +++ b/drivers/pci/controller/pci-hyperv.c
> > @@ -573,6 +573,7 @@ struct hv_pci_compl {
> >  };
> >  
> >  static void hv_pci_onchannelcallback(void *context);
> > +static bool hv_vmbus_pci_device(struct pci_bus *pbus);
> >  
> >  #ifdef CONFIG_X86
> >  #define DELIVERY_MODE              APIC_DELIVERY_MODE_FIXED
> > @@ -1005,6 +1006,24 @@ static struct irq_domain 
> > *hv_pci_get_root_domain(void)
> >  static void hv_arch_irq_unmask(struct irq_data *data) { }
> >  #endif /* CONFIG_ARM64 */
> >  
> > +u64 hv_pci_vmbus_device_id(struct pci_dev *pdev)
> > +{
> > +   struct hv_pcibus_device *hbus;
> > +   struct pci_bus *pbus = pdev->bus;
> > +
> > +   if (!hv_vmbus_pci_device(pbus))
> > +           return 0;
> > +
> > +   hbus = container_of(pbus->sysdata, struct hv_pcibus_device, sysdata);
> > +
> > +   return  (hbus->hdev->dev_instance.b[5] << 24) |
> > +           (hbus->hdev->dev_instance.b[4] << 16) |
> > +           (hbus->hdev->dev_instance.b[7] << 8) |
> > +           (hbus->hdev->dev_instance.b[6] & 0xf8) |
> > +           PCI_FUNC(pdev->devfn);
> > +}
> > +EXPORT_SYMBOL_GPL(hv_pci_vmbus_device_id);
> > +
> >  /**
> >   * hv_pci_generic_compl() - Invoked for a completion packet
> >   * @context:               Set up by the sender of the packet.
> > @@ -1403,6 +1422,11 @@ static struct pci_ops hv_pcifront_ops = {
> >     .write = hv_pcifront_write_config,
> >  };
> >  
> > +static bool hv_vmbus_pci_device(struct pci_bus *pbus)
> > +{
> > +   return pbus->ops == &hv_pcifront_ops;
> > +}
> > +
> >  /*
> >   * Paravirtual backchannel
> >   *
> > diff --git a/include/asm-generic/mshyperv.h b/include/asm-generic/mshyperv.h
> > index e8cbc4e3f7ad..25ac7ca0fd8b 100644
> > --- a/include/asm-generic/mshyperv.h
> > +++ b/include/asm-generic/mshyperv.h
> > @@ -204,6 +204,9 @@ extern u64 (*hv_read_reference_counter)(void);
> >  /* Sentinel value for an uninitialized entry in hv_vp_index array */
> >  #define VP_INVAL   U32_MAX
> >  
> > +/* Forward declarations */
> > +struct pci_dev;
> > +
> >  int __init hv_common_init(void);
> >  void __init hv_get_partition_id(void);
> >  void __init hv_common_free(void);
> > @@ -316,6 +319,14 @@ void hv_para_set_synic_register(unsigned int reg, u64 
> > val);
> >  void hyperv_cleanup(void);
> >  bool hv_query_ext_cap(u64 cap_query);
> >  void hv_setup_dma_ops(struct device *dev, bool coherent);
> > +
> > +#if IS_ENABLED(CONFIG_PCI_HYPERV)
> > +u64 hv_pci_vmbus_device_id(struct pci_dev *pdev);
> > +#else
> > +static inline u64 hv_pci_vmbus_device_id(struct pci_dev *pdev)
> > +{ return 0; }
> > +#endif /* IS_ENABLED(CONFIG_PCI_HYPERV) */
> > +
> >  #else /* CONFIG_HYPERV */
> >  static inline void hv_identify_partition_type(void) {}
> >  static inline bool hv_is_hyperv_initialized(void) { return false; }
> > -- 
> > 2.51.2.vfs.0.1
> > 

Reply via email to