@@ -501,6 +501,40 @@ static inline void vmd_acpi_begin(void) { }
501501static inline void vmd_acpi_end (void ) { }
502502#endif /* CONFIG_ACPI */
503503
504+ static void vmd_domain_reset (struct vmd_dev * vmd )
505+ {
506+ u16 bus , max_buses = resource_size (& vmd -> resources [0 ]);
507+ u8 dev , functions , fn , hdr_type ;
508+ char __iomem * base ;
509+
510+ for (bus = 0 ; bus < max_buses ; bus ++ ) {
511+ for (dev = 0 ; dev < 32 ; dev ++ ) {
512+ base = vmd -> cfgbar + PCIE_ECAM_OFFSET (bus ,
513+ PCI_DEVFN (dev , 0 ), 0 );
514+
515+ hdr_type = readb (base + PCI_HEADER_TYPE ) &
516+ PCI_HEADER_TYPE_MASK ;
517+
518+ functions = (hdr_type & 0x80 ) ? 8 : 1 ;
519+ for (fn = 0 ; fn < functions ; fn ++ ) {
520+ base = vmd -> cfgbar + PCIE_ECAM_OFFSET (bus ,
521+ PCI_DEVFN (dev , fn ), 0 );
522+
523+ hdr_type = readb (base + PCI_HEADER_TYPE ) &
524+ PCI_HEADER_TYPE_MASK ;
525+
526+ if (hdr_type != PCI_HEADER_TYPE_BRIDGE ||
527+ (readw (base + PCI_CLASS_DEVICE ) !=
528+ PCI_CLASS_BRIDGE_PCI ))
529+ continue ;
530+
531+ memset_io (base + PCI_IO_BASE , 0 ,
532+ PCI_ROM_ADDRESS1 - PCI_IO_BASE );
533+ }
534+ }
535+ }
536+ }
537+
504538static void vmd_attach_resources (struct vmd_dev * vmd )
505539{
506540 vmd -> dev -> resource [VMD_MEMBAR1 ].child = & vmd -> resources [1 ];
@@ -661,6 +695,21 @@ static int vmd_alloc_irqs(struct vmd_dev *vmd)
661695 return 0 ;
662696}
663697
698+ /*
699+ * Since VMD is an aperture to regular PCIe root ports, only allow it to
700+ * control features that the OS is allowed to control on the physical PCI bus.
701+ */
702+ static void vmd_copy_host_bridge_flags (struct pci_host_bridge * root_bridge ,
703+ struct pci_host_bridge * vmd_bridge )
704+ {
705+ vmd_bridge -> native_pcie_hotplug = root_bridge -> native_pcie_hotplug ;
706+ vmd_bridge -> native_shpc_hotplug = root_bridge -> native_shpc_hotplug ;
707+ vmd_bridge -> native_aer = root_bridge -> native_aer ;
708+ vmd_bridge -> native_pme = root_bridge -> native_pme ;
709+ vmd_bridge -> native_ltr = root_bridge -> native_ltr ;
710+ vmd_bridge -> native_dpc = root_bridge -> native_dpc ;
711+ }
712+
664713static int vmd_enable_domain (struct vmd_dev * vmd , unsigned long features )
665714{
666715 struct pci_sysdata * sd = & vmd -> sysdata ;
@@ -798,13 +847,19 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
798847 return - ENODEV ;
799848 }
800849
850+ vmd_copy_host_bridge_flags (pci_find_host_bridge (vmd -> dev -> bus ),
851+ to_pci_host_bridge (vmd -> bus -> bridge ));
852+
801853 vmd_attach_resources (vmd );
802854 if (vmd -> irq_domain )
803855 dev_set_msi_domain (& vmd -> bus -> dev , vmd -> irq_domain );
804856
805857 vmd_acpi_begin ();
806858
807859 pci_scan_child_bus (vmd -> bus );
860+ vmd_domain_reset (vmd );
861+ list_for_each_entry (child , & vmd -> bus -> children , node )
862+ pci_reset_bus (child -> self );
808863 pci_assign_unassigned_bus_resources (vmd -> bus );
809864
810865 /*
@@ -953,6 +1008,10 @@ static const struct pci_device_id vmd_ids[] = {
9531008 .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP |
9541009 VMD_FEAT_HAS_BUS_RESTRICTIONS |
9551010 VMD_FEAT_OFFSET_FIRST_VECTOR ,},
1011+ {PCI_DEVICE (PCI_VENDOR_ID_INTEL , 0xa77f ),
1012+ .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP |
1013+ VMD_FEAT_HAS_BUS_RESTRICTIONS |
1014+ VMD_FEAT_OFFSET_FIRST_VECTOR ,},
9561015 {PCI_DEVICE (PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_VMD_9A0B ),
9571016 .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP |
9581017 VMD_FEAT_HAS_BUS_RESTRICTIONS |
0 commit comments