@@ -501,6 +501,40 @@ static inline void vmd_acpi_begin(void) { }
501
501
static inline void vmd_acpi_end (void ) { }
502
502
#endif /* CONFIG_ACPI */
503
503
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
+
504
538
static void vmd_attach_resources (struct vmd_dev * vmd )
505
539
{
506
540
vmd -> dev -> resource [VMD_MEMBAR1 ].child = & vmd -> resources [1 ];
@@ -661,6 +695,21 @@ static int vmd_alloc_irqs(struct vmd_dev *vmd)
661
695
return 0 ;
662
696
}
663
697
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
+
664
713
static int vmd_enable_domain (struct vmd_dev * vmd , unsigned long features )
665
714
{
666
715
struct pci_sysdata * sd = & vmd -> sysdata ;
@@ -798,13 +847,19 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features)
798
847
return - ENODEV ;
799
848
}
800
849
850
+ vmd_copy_host_bridge_flags (pci_find_host_bridge (vmd -> dev -> bus ),
851
+ to_pci_host_bridge (vmd -> bus -> bridge ));
852
+
801
853
vmd_attach_resources (vmd );
802
854
if (vmd -> irq_domain )
803
855
dev_set_msi_domain (& vmd -> bus -> dev , vmd -> irq_domain );
804
856
805
857
vmd_acpi_begin ();
806
858
807
859
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 );
808
863
pci_assign_unassigned_bus_resources (vmd -> bus );
809
864
810
865
/*
@@ -953,6 +1008,10 @@ static const struct pci_device_id vmd_ids[] = {
953
1008
.driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP |
954
1009
VMD_FEAT_HAS_BUS_RESTRICTIONS |
955
1010
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 ,},
956
1015
{PCI_DEVICE (PCI_VENDOR_ID_INTEL , PCI_DEVICE_ID_INTEL_VMD_9A0B ),
957
1016
.driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP |
958
1017
VMD_FEAT_HAS_BUS_RESTRICTIONS |
0 commit comments