- Support device ID 0x28C1 and assume that BIOS has already enumerated the hierarchy below VMD and stored bus range info for OS to use (Nirmal Patel) - Add support for VMCONFIG BUS_RESTRICT_CFG=3, which makes it possible to enumerate downstream devices on Intel Arrow Lake-HX systems and probably others (Ali Alaei) - Observe _OSC negotiation for VMD hierarchy only when running on bare metal, not when running in a VM (Nirmal Patel) - Add Nova Lake (NVL) and Dunlow (DNL) Device IDs (Szymon Durawa) * pci/controller/vmd: PCI: vmd: Add Nova Lake (NVL) and Dunlow (DNL) Device IDs PCI: vmd: Only copy root bridge _OSC control flags in bare metal OS PCI: vmd: Handle BUS_RESTRICT_CFG value 3 for Arrow Lake-HX PCI: vmd: Add feature to scan BIOS-enumerated devices
Unified · Split
| @@ -37,6 +37,12 @@ · 36 unmodified lines | |||
| 37 | #define MB2_SHADOW_OFFSET 0x2000 | 37 | #define MB2_SHADOW_OFFSET 0x2000 |
| 38 | #define MB2_SHADOW_SIZE 16 | 38 | #define MB2_SHADOW_SIZE 16 |
| 39 | 39 | ||
| 40 | /* DMR BAR4 register offsets */ | ||
| 41 | #define SHADOW_MEMBAR1_28C1 0x2818 /* MEMBAR1 physical address */ | ||
| 42 | #define SHADOW_MEMBAR2_28C1 0x2820 /* MEMBAR2 physical address */ | ||
| 43 | #define BASE_ID_REG_28C1 0x2840 | ||
| 44 | #define MEMBAR2_OFFSET_28C1 0x30d0 | ||
| 45 | |||
| 40 | enum vmd_features { | 46 | enum vmd_features { |
| 41 | /* | 47 | /* |
| 42 | * Device may contain registers which hint the physical location of the | 48 | * Device may contain registers which hint the physical location of the |
| @@ -77,6 +83,15 @@ enum vmd_features { · 34 unmodified lines | |||
| 77 | * proper power management of the SoC. | 83 | * proper power management of the SoC. |
| 78 | */ | 84 | */ |
| 79 | VMD_FEAT_BIOS_PM_QUIRK = (1 << 5), | 85 | VMD_FEAT_BIOS_PM_QUIRK = (1 << 5), |
| 86 | |||
| 87 | /* | ||
| 88 | * Newer VMD with device ID 0x28C1 has unique settings compared to its | ||
| 89 | * predecessor where BIOS enumerates the entire VMD device tree and | ||
| 90 | * stores respective configurations including bus start range and | ||
| 91 | * shadow registers in VMD MMIO space in VMD BAR4/BAR5, otherwise | ||
| 92 | * referred to as MEMBAR2 or MSI-X BAR. | ||
| 93 | */ | ||
| 94 | VMD_FEAT_USE_BIOS_INFO = (1 << 6), | ||
| 80 | }; | 95 | }; |
| 81 | 96 | ||
| 82 | #define VMD_BIOS_PM_QUIRK_LTR 0x1003 /* 3145728 ns */ | 97 | #define VMD_BIOS_PM_QUIRK_LTR 0x1003 /* 3145728 ns */ |
| @@ -142,6 +157,7 @@ struct vmd_dev { · 59 unmodified lines | |||
| 142 | u8 first_vec; | 157 | u8 first_vec; |
| 143 | char *name; | 158 | char *name; |
| 144 | int instance; | 159 | int instance; |
| 160 | unsigned long features; | ||
| 145 | }; | 161 | }; |
| 146 | 162 | ||
| 147 | static inline struct vmd_dev *vmd_from_bus(struct pci_bus *bus) | 163 | static inline struct vmd_dev *vmd_from_bus(struct pci_bus *bus) |
| @@ -366,6 +382,9 @@ static void vmd_set_msi_remapping(struct vmd_dev *vmd, bool enable) · 218 unmodified lines | |||
| 366 | { | 382 | { |
| 367 | u16 reg; | 383 | u16 reg; |
| 368 | 384 | ||
| 385 | if (!!(vmd->features & VMD_FEAT_USE_BIOS_INFO)) | ||
| 386 | return; | ||
| 387 | |||
| 369 | pci_read_config_word(vmd->dev, PCI_REG_VMCONFIG, ®); | 388 | pci_read_config_word(vmd->dev, PCI_REG_VMCONFIG, ®); |
| 370 | reg = enable ? (reg & ~VMCONFIG_MSI_REMAP) : | 389 | reg = enable ? (reg & ~VMCONFIG_MSI_REMAP) : |
| 371 | (reg | VMCONFIG_MSI_REMAP); | 390 | (reg | VMCONFIG_MSI_REMAP); |
| @@ -389,11 +408,22 @@ static void vmd_remove_irq_domain(struct vmd_dev *vmd) · 17 unmodified lines | |||
| 389 | } | 408 | } |
| 390 | } | 409 | } |
| 391 | 410 | ||
| 411 | static unsigned int vmd_bus_to_ecam(struct vmd_dev *vmd, unsigned int busnr) | ||
| 412 | { | ||
| 413 | if (!!(vmd->features & VMD_FEAT_USE_BIOS_INFO)) | ||
| 414 | return busnr; | ||
| 415 | |||
| 416 | return busnr - vmd->busn_start; | ||
| 417 | } | ||
| 418 | |||
| 392 | static void __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus, | 419 | static void __iomem *vmd_cfg_addr(struct vmd_dev *vmd, struct pci_bus *bus, |
| 393 | unsigned int devfn, int reg, int len) | 420 | unsigned int devfn, int reg, int len) |
| 394 | { | 421 | { |
| 395 | unsigned int busnr_ecam = bus->number - vmd->busn_start; | 422 | unsigned int busnr_ecam; |
| 396 | u32 offset = PCIE_ECAM_OFFSET(busnr_ecam, devfn, reg); | 423 | u32 offset; |
| 424 | |||
| 425 | busnr_ecam = vmd_bus_to_ecam(vmd, bus->number); | ||
| 426 | offset = PCIE_ECAM_OFFSET(busnr_ecam, devfn, reg); | ||
| 397 | 427 | ||
| 398 | if (offset + len >= resource_size(&vmd->dev->resource[VMD_CFGBAR])) | 428 | if (offset + len >= resource_size(&vmd->dev->resource[VMD_CFGBAR])) |
| 399 | return NULL; | 429 | return NULL; |
| @@ -518,22 +548,37 @@ static inline void vmd_acpi_begin(void) { } · 118 unmodified lines | |||
| 518 | static inline void vmd_acpi_end(void) { } | 548 | static inline void vmd_acpi_end(void) { } |
| 519 | #endif /* CONFIG_ACPI */ | 549 | #endif /* CONFIG_ACPI */ |
| 520 | 550 | ||
| 551 | static resource_size_t vmd_cfgbar_ecam_space(struct vmd_dev *vmd) | ||
| 552 | { | ||
| 553 | resource_size_t cfgbar_buses; | ||
| 554 | unsigned int ecam_start; | ||
| 555 | |||
| 556 | cfgbar_buses = resource_size(&vmd->dev->resource[VMD_CFGBAR]) >> 20; | ||
| 557 | ecam_start = vmd_bus_to_ecam(vmd, vmd->resources[0].start); | ||
| 558 | if (ecam_start >= cfgbar_buses) | ||
| 559 | return 0; | ||
| 560 | |||
| 561 | return cfgbar_buses - ecam_start; | ||
| 562 | } | ||
| 521 | static void vmd_domain_reset(struct vmd_dev *vmd) | 563 | static void vmd_domain_reset(struct vmd_dev *vmd) |
| 522 | { | 564 | { |
| 523 | u16 bus, max_buses = resource_size(&vmd->resources[0]); | 565 | u16 bus, max_buses = resource_size(&vmd->resources[0]); |
| 524 | u8 dev, functions, fn, hdr_type; | 566 | u8 dev, functions, fn, hdr_type; |
| 567 | unsigned int ecam_bus; | ||
| 525 | char __iomem *base; | 568 | char __iomem *base; |
| 526 | 569 | ||
| 570 | max_buses = min_t(u16, max_buses, vmd_cfgbar_ecam_space(vmd)); | ||
| 527 | for (bus = 0; bus < max_buses; bus++) { | 571 | for (bus = 0; bus < max_buses; bus++) { |
| 572 | ecam_bus = vmd_bus_to_ecam(vmd, vmd->resources[0].start + bus); | ||
| 528 | for (dev = 0; dev < 32; dev++) { | 573 | for (dev = 0; dev < 32; dev++) { |
| 529 | base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus, | 574 | base = vmd->cfgbar + PCIE_ECAM_OFFSET(ecam_bus, |
| 530 | PCI_DEVFN(dev, 0), 0); | 575 | PCI_DEVFN(dev, 0), 0); |
| 531 | 576 | ||
| 532 | hdr_type = readb(base + PCI_HEADER_TYPE); | 577 | hdr_type = readb(base + PCI_HEADER_TYPE); |
| 533 | 578 | ||
| 534 | functions = (hdr_type & PCI_HEADER_TYPE_MFD) ? 8 : 1; | 579 | functions = (hdr_type & PCI_HEADER_TYPE_MFD) ? 8 : 1; |
| 535 | for (fn = 0; fn < functions; fn++) { | 580 | for (fn = 0; fn < functions; fn++) { |
| 536 | base = vmd->cfgbar + PCIE_ECAM_OFFSET(bus, | 581 | base = vmd->cfgbar + PCIE_ECAM_OFFSET(ecam_bus, |
| 537 | PCI_DEVFN(dev, fn), 0); | 582 | PCI_DEVFN(dev, fn), 0); |
| 538 | 583 | ||
| 539 | hdr_type = readb(base + PCI_HEADER_TYPE) & | 584 | hdr_type = readb(base + PCI_HEADER_TYPE) & |
| @@ -640,6 +685,8 @@ static int vmd_get_bus_number_start(struct vmd_dev *vmd) · 100 unmodified lines | |||
| 640 | pci_read_config_word(dev, PCI_REG_VMCAP, ®); | 685 | pci_read_config_word(dev, PCI_REG_VMCAP, ®); |
| 641 | if (BUS_RESTRICT_CAP(reg)) { | 686 | if (BUS_RESTRICT_CAP(reg)) { |
| 642 | pci_read_config_word(dev, PCI_REG_VMCONFIG, ®); | 687 | pci_read_config_word(dev, PCI_REG_VMCONFIG, ®); |
| 688 | if (PCI_POSSIBLE_ERROR(reg)) | ||
| 689 | return -ENODEV; | ||
| 643 | 690 | ||
| 644 | switch (BUS_RESTRICT_CFG(reg)) { | 691 | switch (BUS_RESTRICT_CFG(reg)) { |
| 645 | case 0: | 692 | case 0: |
| @@ -648,6 +695,7 @@ static int vmd_get_bus_number_start(struct vmd_dev *vmd) · 2 unmodified lines | |||
| 648 | case 1: | 695 | case 1: |
| 649 | vmd->busn_start = 128; | 696 | vmd->busn_start = 128; |
| 650 | break; | 697 | break; |
| 698 | case 3: | ||
| 651 | case 2: | 699 | case 2: |
| 652 | vmd->busn_start = 224; | 700 | vmd->busn_start = 224; |
| 653 | break; | 701 | break; |
| @@ -661,6 +709,46 @@ static int vmd_get_bus_number_start(struct vmd_dev *vmd) · 7 unmodified lines | |||
| 661 | return 0; | 709 | return 0; |
| 662 | } | 710 | } |
| 663 | 711 | ||
| 712 | static int vmd_get_bus_info_from_bar4(struct vmd_dev *vmd, | ||
| 713 | resource_size_t *offset1, | ||
| 714 | resource_size_t *offset2) | ||
| 715 | { | ||
| 716 | u64 phys1, phys2, bar4_2840; | ||
| 717 | void __iomem *bar4; | ||
| 718 | u32 base_id; | ||
| 719 | u8 base_bus; | ||
| 720 | |||
| 721 | bar4 = pci_ioremap_bar(vmd->dev, 4); | ||
| 722 | if (!bar4) | ||
| 723 | return -ENOMEM; | ||
| 724 | |||
| 725 | /* Read shadow registers for MEMBAR1 and MEMBAR2 physical addresses */ | ||
| 726 | phys1 = readq(bar4 + SHADOW_MEMBAR1_28C1); | ||
| 727 | phys2 = readq(bar4 + SHADOW_MEMBAR2_28C1); | ||
| 728 | |||
| 729 | /* | ||
| 730 | * Read and set bus start number from Base ID register. 24-bit Base ID | ||
| 731 | * register is part of 64-bit shadowed reqid hide range register and | ||
| 732 | * holds segment, bus, device and function. | ||
| 733 | */ | ||
| 734 | bar4_2840 = readq(bar4 + BASE_ID_REG_28C1); | ||
| 735 | base_id = bar4_2840 & 0xFFFFFF; | ||
| 736 | base_bus = base_id >> 8; | ||
| 737 | vmd->busn_start = base_bus; | ||
| 738 | |||
| 739 | /* Calculate offsets like vmd_get_phys_offsets() does */ | ||
| 740 | if (phys1) | ||
| 741 | *offset1 = vmd->dev->resource[VMD_MEMBAR1].start - | ||
| 742 | (phys1 & PCI_BASE_ADDRESS_MEM_MASK); | ||
| 743 | if (phys2) | ||
| 744 | *offset2 = vmd->dev->resource[VMD_MEMBAR2].start - | ||
| 745 | (phys2 & PCI_BASE_ADDRESS_MEM_MASK); | ||
| 746 | |||
| 747 | pci_iounmap(vmd->dev, bar4); | ||
| 748 | |||
| 749 | return 0; | ||
| 750 | } | ||
| 751 | |||
| 664 | static irqreturn_t vmd_irq(int irq, void *data) | 752 | static irqreturn_t vmd_irq(int irq, void *data) |
| 665 | { | 753 | { |
| 666 | struct vmd_irq_list *irqs = data; | 754 | struct vmd_irq_list *irqs = data; |
| @@ -711,6 +799,52 @@ static int vmd_alloc_irqs(struct vmd_dev *vmd) · 44 unmodified lines | |||
| 711 | return 0; | 799 | return 0; |
| 712 | } | 800 | } |
| 713 | 801 | ||
| 802 | static int vmd_prepare_offsets_and_bus(struct vmd_dev *vmd, | ||
| 803 | unsigned long features, | ||
| 804 | resource_size_t *membar2_offset, | ||
| 805 | resource_size_t *offset1, | ||
| 806 | resource_size_t *offset2) | ||
| 807 | { | ||
| 808 | int ret; | ||
| 809 | |||
| 810 | /* | ||
| 811 | * Shadow registers may exist in certain VMD device IDs which allow | ||
| 812 | * guests to correctly assign host physical addresses to the root ports | ||
| 813 | * and child devices. These registers will either return the host value | ||
| 814 | * or 0, depending on an enable bit in the VMD device. | ||
| 815 | * | ||
| 816 | * For certain VMD devices (i.e. 0x28C1), BIOS places device info | ||
| 817 | * in BAR4 shadow registers to determine the base bus number and memory | ||
| 818 | * offsets. | ||
| 819 | */ | ||
| 820 | if (features & VMD_FEAT_USE_BIOS_INFO) { | ||
| 821 | *membar2_offset = MEMBAR2_OFFSET_28C1; | ||
| 822 | ret = vmd_get_bus_info_from_bar4(vmd, offset1, offset2); | ||
| 823 | if (ret) | ||
| 824 | return ret; | ||
| 825 | } else if (features & VMD_FEAT_HAS_MEMBAR_SHADOW) { | ||
| 826 | *membar2_offset = MB2_SHADOW_OFFSET + MB2_SHADOW_SIZE; | ||
| 827 | ret = vmd_get_phys_offsets(vmd, true, offset1, offset2); | ||
| 828 | if (ret) | ||
| 829 | return ret; | ||
| 830 | } else if (features & VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP) { | ||
| 831 | ret = vmd_get_phys_offsets(vmd, false, offset1, offset2); | ||
| 832 | if (ret) | ||
| 833 | return ret; | ||
| 834 | } | ||
| 835 | |||
| 836 | /* | ||
| 837 | * Certain VMD devices may have a root port configuration option which | ||
| 838 | * limits the bus range to between 0-127, 128-255, or 224-255. | ||
| 839 | */ | ||
| 840 | if (features & VMD_FEAT_HAS_BUS_RESTRICTIONS) { | ||
| 841 | ret = vmd_get_bus_number_start(vmd); | ||
| 842 | if (ret) | ||
| 843 | return ret; | ||
| 844 | } | ||
| 845 | return 0; | ||
| 846 | } | ||
| 847 | |||
| 714 | /* | 848 | /* |
| 715 | * Since VMD is an aperture to regular PCIe root ports, only allow it to | 849 | * Since VMD is an aperture to regular PCIe root ports, only allow it to |
| 716 | * control features that the OS is allowed to control on the physical PCI bus. | 850 | * control features that the OS is allowed to control on the physical PCI bus. |
| @@ -780,42 +914,25 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) · 63 unmodified lines | |||
| 780 | LIST_HEAD(resources); | 914 | LIST_HEAD(resources); |
| 781 | resource_size_t offset[2] = {0}; | 915 | resource_size_t offset[2] = {0}; |
| 782 | resource_size_t membar2_offset = 0x2000; | 916 | resource_size_t membar2_offset = 0x2000; |
| 917 | resource_size_t busn_end; | ||
| 783 | struct pci_bus *child; | 918 | struct pci_bus *child; |
| 784 | struct pci_dev *dev; | 919 | struct pci_dev *dev; |
| 920 | bool vmd_in_guest; | ||
| 785 | int ret; | 921 | int ret; |
| 786 | 922 | ||
| 787 | /* | 923 | ret = vmd_prepare_offsets_and_bus(vmd, features, &membar2_offset, |
| 788 | * Shadow registers may exist in certain VMD device ids which allow | 924 | &offset[0], &offset[1]); |
| 789 | * guests to correctly assign host physical addresses to the root ports | 925 | if (ret) |
| 790 | * and child devices. These registers will either return the host value | 926 | return ret; |
| 791 | * or 0, depending on an enable bit in the VMD device. | ||
| 792 | */ | ||
| 793 | if (features & VMD_FEAT_HAS_MEMBAR_SHADOW) { | ||
| 794 | membar2_offset = MB2_SHADOW_OFFSET + MB2_SHADOW_SIZE; | ||
| 795 | ret = vmd_get_phys_offsets(vmd, true, &offset[0], &offset[1]); | ||
| 796 | if (ret) | ||
| 797 | return ret; | ||
| 798 | } else if (features & VMD_FEAT_HAS_MEMBAR_SHADOW_VSCAP) { | ||
| 799 | ret = vmd_get_phys_offsets(vmd, false, &offset[0], &offset[1]); | ||
| 800 | if (ret) | ||
| 801 | return ret; | ||
| 802 | } | ||
| 803 | |||
| 804 | /* | ||
| 805 | * Certain VMD devices may have a root port configuration option which | ||
| 806 | * limits the bus range to between 0-127, 128-255, or 224-255 | ||
| 807 | */ | ||
| 808 | if (features & VMD_FEAT_HAS_BUS_RESTRICTIONS) { | ||
| 809 | ret = vmd_get_bus_number_start(vmd); | ||
| 810 | if (ret) | ||
| 811 | return ret; | ||
| 812 | } | ||
| 813 | 927 | ||
| 928 | /* Do not let resource[0] end go out of bounds */ | ||
| 814 | res = &vmd->dev->resource[VMD_CFGBAR]; | 929 | res = &vmd->dev->resource[VMD_CFGBAR]; |
| 930 | busn_end = vmd->busn_start + (resource_size(res) >> 20) - 1; | ||
| 931 | busn_end = min_t(resource_size_t, busn_end, 0xff); | ||
| 815 | vmd->resources[0] = (struct resource) { | 932 | vmd->resources[0] = (struct resource) { |
| 816 | .name = "VMD CFGBAR", | 933 | .name = "VMD CFGBAR", |
| 817 | .start = vmd->busn_start, | 934 | .start = vmd->busn_start, |
| 818 | .end = vmd->busn_start + (resource_size(res) >> 20) - 1, | 935 | .end = busn_end, |
| 819 | .flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED, | 936 | .flags = IORESOURCE_BUS | IORESOURCE_PCI_FIXED, |
| 820 | }; | 937 | }; |
| 821 | 938 | ||
| @@ -862,14 +979,16 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) · 40 unmodified lines | |||
| 862 | .parent = res, | 979 | .parent = res, |
| 863 | }; | 980 | }; |
| 864 | 981 | ||
| 982 | /* Non-zero offset means guest/direct assign view. */ | ||
| 983 | vmd_in_guest = offset[0] || offset[1]; | ||
| 984 | |||
| 865 | /* | 985 | /* |
| 866 | * Currently MSI remapping must be enabled in guest passthrough mode | 986 | * Currently MSI remapping must be enabled in guest passthrough mode |
| 867 | * due to some missing interrupt remapping plumbing. This is probably | 987 | * due to some missing interrupt remapping plumbing. This is probably |
| 868 | * acceptable because the guest is usually CPU-limited and MSI | 988 | * acceptable because the guest is usually CPU-limited and MSI |
| 869 | * remapping doesn't become a performance bottleneck. | 989 | * remapping doesn't become a performance bottleneck. |
| 870 | */ | 990 | */ |
| 871 | if (!(features & VMD_FEAT_CAN_BYPASS_MSI_REMAP) || | 991 | if (!(features & VMD_FEAT_CAN_BYPASS_MSI_REMAP) || vmd_in_guest) { |
| 872 | offset[0] || offset[1]) { | ||
| 873 | ret = vmd_alloc_irqs(vmd); | 992 | ret = vmd_alloc_irqs(vmd); |
| 874 | if (ret) | 993 | if (ret) |
| 875 | return ret; | 994 | return ret; |
| @@ -910,8 +1029,13 @@ static int vmd_enable_domain(struct vmd_dev *vmd, unsigned long features) · 34 unmodified lines | |||
| 910 | return -ENODEV; | 1029 | return -ENODEV; |
| 911 | } | 1030 | } |
| 912 | 1031 | ||
| 913 | vmd_copy_host_bridge_flags(pci_find_host_bridge(vmd->dev->bus), | 1032 | /* |
| 914 | to_pci_host_bridge(vmd->bus->bridge)); | 1033 | * Don't copy _OSC control flags from root bridge if running in a VM, as |
| 1034 | * they don't reflect the physical root bridge capabilities. | ||
| 1035 | */ | ||
| 1036 | if (!vmd_in_guest) | ||
| 1037 | vmd_copy_host_bridge_flags(pci_find_host_bridge(vmd->dev->bus), | ||
| 1038 | to_pci_host_bridge(vmd->bus->bridge)); | ||
| 915 | 1039 | ||
| 916 | vmd_attach_resources(vmd); | 1040 | vmd_attach_resources(vmd); |
| 917 | if (vmd->irq_domain) | 1041 | if (vmd->irq_domain) |
| @@ -998,6 +1122,7 @@ static int vmd_probe(struct pci_dev *dev, const struct pci_device_id *id) · 80 unmodified lines | |||
| 998 | 1122 | ||
| 999 | vmd->dev = dev; | 1123 | vmd->dev = dev; |
| 1000 | vmd->sysdata.domain = PCI_DOMAIN_NR_NOT_SET; | 1124 | vmd->sysdata.domain = PCI_DOMAIN_NR_NOT_SET; |
| 1125 | vmd->features = features; | ||
| 1001 | vmd->instance = ida_alloc(&vmd_instance_ida, GFP_KERNEL); | 1126 | vmd->instance = ida_alloc(&vmd_instance_ida, GFP_KERNEL); |
| 1002 | if (vmd->instance < 0) | 1127 | if (vmd->instance < 0) |
| 1003 | return vmd->instance; | 1128 | return vmd->instance; |
| @@ -1114,6 +1239,10 @@ static const struct pci_device_id vmd_ids[] = { · 110 unmodified lines | |||
| 1114 | .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW | | 1239 | .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW | |
| 1115 | VMD_FEAT_HAS_BUS_RESTRICTIONS | | 1240 | VMD_FEAT_HAS_BUS_RESTRICTIONS | |
| 1116 | VMD_FEAT_CAN_BYPASS_MSI_REMAP,}, | 1241 | VMD_FEAT_CAN_BYPASS_MSI_REMAP,}, |
| 1242 | {PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_VMD_28C1), | ||
| 1243 | .driver_data = VMD_FEAT_HAS_MEMBAR_SHADOW | | ||
| 1244 | VMD_FEAT_CAN_BYPASS_MSI_REMAP | | ||
| 1245 | VMD_FEAT_USE_BIOS_INFO,}, | ||
| 1117 | {PCI_VDEVICE(INTEL, 0x467f), | 1246 | {PCI_VDEVICE(INTEL, 0x467f), |
| 1118 | .driver_data = VMD_FEATS_CLIENT,}, | 1247 | .driver_data = VMD_FEATS_CLIENT,}, |
| 1119 | {PCI_VDEVICE(INTEL, 0x4c3d), | 1248 | {PCI_VDEVICE(INTEL, 0x4c3d), |
| @@ -1132,6 +1261,10 @@ static const struct pci_device_id vmd_ids[] = { · 12 unmodified lines | |||
| 1132 | .driver_data = VMD_FEATS_CLIENT,}, | 1261 | .driver_data = VMD_FEATS_CLIENT,}, |
| 1133 | {PCI_VDEVICE(INTEL, 0xb07f), | 1262 | {PCI_VDEVICE(INTEL, 0xb07f), |
| 1134 | .driver_data = VMD_FEATS_CLIENT,}, | 1263 | .driver_data = VMD_FEATS_CLIENT,}, |
| 1264 | {PCI_VDEVICE(INTEL, 0xd70b), | ||
| 1265 | .driver_data = VMD_FEATS_CLIENT,}, | ||
| 1266 | {PCI_VDEVICE(INTEL, 0xd73b), | ||
| 1267 | .driver_data = VMD_FEATS_CLIENT,}, | ||
| 1135 | {0,} | 1268 | {0,} |
| 1136 | }; | 1269 | }; |
| 1137 | MODULE_DEVICE_TABLE(pci, vmd_ids); | 1270 | MODULE_DEVICE_TABLE(pci, vmd_ids); |
| @@ -2892,6 +2892,7 @@ · 2891 unmodified lines | |||
| 2892 | #define PCI_DEVICE_ID_INTEL_HDA_ICH8 0x284b | 2892 | #define PCI_DEVICE_ID_INTEL_HDA_ICH8 0x284b |
| 2893 | #define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 | 2893 | #define PCI_DEVICE_ID_INTEL_ICH8_6 0x2850 |
| 2894 | #define PCI_DEVICE_ID_INTEL_VMD_28C0 0x28c0 | 2894 | #define PCI_DEVICE_ID_INTEL_VMD_28C0 0x28c0 |
| 2895 | #define PCI_DEVICE_ID_INTEL_VMD_28C1 0x28c1 | ||
| 2895 | #define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910 | 2896 | #define PCI_DEVICE_ID_INTEL_ICH9_0 0x2910 |
| 2896 | #define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912 | 2897 | #define PCI_DEVICE_ID_INTEL_ICH9_2 0x2912 |
| 2897 | #define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913 | 2898 | #define PCI_DEVICE_ID_INTEL_ICH9_3 0x2913 |