| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
1 parent 1e1918e commit f45edca
4 files changed
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -21,6 +21,47 @@ struct mk_mmcfg_snapshot { | |||
| 21 | 21 | size_t count; | |
| 22 | 22 | }; | |
| 23 | 23 | ||
| 24 | + static struct pci_ops mk_pci_native_ops; | ||
| 25 | + | ||
| 26 | + static bool mk_pci_identity_read(struct pci_bus *bus, unsigned int devfn, | ||
| 27 | + int where, int size, u32 *value) | ||
| 28 | + { | ||
| 29 | + u16 vendor, device; | ||
| 30 | + u32 identity; | ||
| 31 | + u32 mask; | ||
| 32 | + | ||
| 33 | + if (where < PCI_VENDOR_ID || where + size > PCI_COMMAND || | ||
| 34 | + !mk_pci_get_assigned_identity(bus, devfn, &vendor, &device)) | ||
| 35 | + return false; | ||
| 36 | + | ||
| 37 | + identity = vendor | (u32)device << 16; | ||
| 38 | + mask = size == sizeof(identity) ? ~0U : (1U << (size * 8)) - 1; | ||
| 39 | + *value = (identity >> (where * 8)) & mask; | ||
| 40 | + return true; | ||
| 41 | + } | ||
| 42 | + | ||
| 43 | + static int mk_pci_read(struct pci_bus *bus, unsigned int devfn, int where, | ||
| 44 | + int size, u32 *value) | ||
| 45 | + { | ||
| 46 | + if (!mk_pci_should_probe(bus, devfn, &mk_pci_native_ops)) { | ||
| 47 | + *value = ~0U; | ||
| 48 | + return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 49 | + } | ||
| 50 | + if (mk_pci_identity_read(bus, devfn, where, size, value)) | ||
| 51 | + return PCIBIOS_SUCCESSFUL; | ||
| 52 | + | ||
| 53 | + return mk_pci_native_ops.read(bus, devfn, where, size, value); | ||
| 54 | + } | ||
| 55 | + | ||
| 56 | + static int mk_pci_write(struct pci_bus *bus, unsigned int devfn, int where, | ||
| 57 | + int size, u32 value) | ||
| 58 | + { | ||
| 59 | + if (!mk_pci_should_probe(bus, devfn, &mk_pci_native_ops)) | ||
| 60 | + return PCIBIOS_DEVICE_NOT_FOUND; | ||
| 61 | + | ||
| 62 | + return mk_pci_native_ops.write(bus, devfn, where, size, value); | ||
| 63 | + } | ||
| 64 | + | ||
| 24 | 65 | #ifdef CONFIG_PCI_MMCONFIG | |
| 25 | 66 | static int mk_mmcfg_snapshot_region(const struct pci_mmcfg_region *region, | |
| 26 | 67 | void *data) | |
@@ -98,6 +139,9 @@ static int __init x86_multikernel_pci_arch_init(void) | |||
| 98 | 139 | ||
| 99 | 140 | raw_pci_ops = &pci_mmcfg; | |
| 100 | 141 | raw_pci_ext_ops = &pci_mmcfg; | |
| 142 | + mk_pci_native_ops = pci_root_ops; | ||
| 143 | + pci_root_ops.read = mk_pci_read; | ||
| 144 | + pci_root_ops.write = mk_pci_write; | ||
| 101 | 145 | pr_notice("Multikernel selected ECAM for PCI config access\n"); | |
| 102 | 146 | ||
| 103 | 147 | return 0; | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -22,9 +22,6 @@ | |||
| 22 | 22 | #include <linux/irqdomain.h> | |
| 23 | 23 | #include <linux/pm_runtime.h> | |
| 24 | 24 | #include <linux/bitfield.h> | |
| 25 | - #ifdef CONFIG_MULTIKERNEL | ||
| 26 | - #include <linux/multikernel.h> | ||
| 27 | - #endif | ||
| 28 | 25 | #include "pci.h" | |
| 29 | 26 | ||
| 30 | 27 | #define CARDBUS_LATENCY_TIMER 176 /* secondary latency timer */ | |
@@ -2625,14 +2622,6 @@ static struct pci_dev *pci_scan_device(struct pci_bus *bus, int devfn) | |||
| 2625 | 2622 | struct pci_dev *dev; | |
| 2626 | 2623 | u32 l; | |
| 2627 | 2624 | ||
| 2628 | - /* | ||
| 2629 | - * For multikernel spawns, check if we should even probe this location | ||
| 2630 | - * BEFORE any config space access. This prevents hardware conflicts | ||
| 2631 | - * when the host kernel is also using PCI devices. | ||
| 2632 | - */ | ||
| 2633 | - if (IS_ENABLED(CONFIG_MULTIKERNEL) && !mk_pci_should_probe(bus, devfn)) | ||
| 2634 | - return NULL; | ||
| 2635 | - | ||
| 2636 | 2625 | /* | |
| 2637 | 2626 | * Create pwrctrl device (if required) for the PCI device to handle the | |
| 2638 | 2627 | * power state. If the pwrctrl device is created, then skip scanning | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -15,7 +15,7 @@ | |||
| 15 | 15 | #include <linux/genalloc.h> | |
| 16 | 16 | #include <linux/sizes.h> | |
| 17 | 17 | struct pci_bus; | |
| 18 | - struct pci_dev; | ||
| 18 | + struct pci_ops; | ||
| 19 | 19 | ||
| 20 | 20 | /** | |
| 21 | 21 | * Multikernel IPI interface | |
@@ -873,10 +873,10 @@ void __init mk_register_cpus_from_kho(void); | |||
| 873 | 873 | * | |
| 874 | 874 | * Returns: true if probing should proceed, false to skip entirely | |
| 875 | 875 | */ | |
| 876 | - bool mk_pci_should_probe(struct pci_bus *bus, int devfn); | ||
| 876 | + bool mk_pci_should_probe(struct pci_bus *bus, int devfn, | ||
| 877 | + const struct pci_ops *ops); | ||
| 877 | 878 | bool mk_pci_get_assigned_identity(struct pci_bus *bus, int devfn, | |
| 878 | 879 | u16 *vendor, u16 *device); | |
| 879 | - void mk_pci_restore_resources(struct pci_dev *dev); | ||
| 880 | 880 | ||
| 881 | 881 | /** | |
| 882 | 882 | * mk_platform_device_allowed() - Check if a platform device is allowed by DTB allowlist | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -12,8 +12,7 @@ | |||
| 12 | 12 | ||
| 13 | 13 | #include "internal.h" | |
| 14 | 14 | ||
| 15 | - static struct mk_pci_device *mk_pci_find_assigned(struct pci_bus *bus, | ||
| 16 | - int devfn) | ||
| 15 | + static struct mk_pci_device *mk_pci_find_assigned(struct pci_bus *bus, int devfn) | ||
| 17 | 16 | { | |
| 18 | 17 | struct mk_pci_device *device; | |
| 19 | 18 | u16 domain = pci_domain_nr(bus); | |
@@ -52,13 +51,10 @@ bool mk_pci_get_assigned_identity(struct pci_bus *bus, int devfn, | |||
| 52 | 51 | ||
| 53 | 52 | *vendor = device->vendor; | |
| 54 | 53 | *device_id = device->device; | |
| 55 | - pr_notice("MK_SECONDARY_ASSIGNED_PCI_IDENTITY bdf=%04x:%02x:%02x.%x vendor=%04x device=%04x\n", | ||
| 56 | - device->domain, device->bus, device->slot, device->func, | ||
| 57 | - *vendor, *device_id); | ||
| 58 | 54 | return true; | |
| 59 | 55 | } | |
| 60 | 56 | ||
| 61 | - void mk_pci_restore_resources(struct pci_dev *dev) | ||
| 57 | + static void mk_pci_restore_resources(struct pci_dev *dev) | ||
| 62 | 58 | { | |
| 63 | 59 | struct mk_pci_device *device; | |
| 64 | 60 | int i; | |
@@ -75,23 +71,33 @@ void mk_pci_restore_resources(struct pci_dev *dev) | |||
| 75 | 71 | } | |
| 76 | 72 | pr_info("Restored PCI BAR resources for %s\n", pci_name(dev)); | |
| 77 | 73 | } | |
| 78 | - EXPORT_SYMBOL_GPL(mk_pci_restore_resources); | ||
| 79 | 74 | ||
| 80 | - static bool mk_pci_bridge_reaches_assigned(struct pci_bus *bus, int devfn) | ||
| 75 | + DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, mk_pci_restore_resources); | ||
| 76 | + | ||
| 77 | + static bool mk_pci_bridge_reaches_assigned(struct pci_bus *bus, int devfn, | ||
| 78 | + const struct pci_ops *ops) | ||
| 81 | 79 | { | |
| 82 | 80 | struct mk_pci_device *device; | |
| 83 | 81 | u16 domain = pci_domain_nr(bus); | |
| 84 | 82 | u8 secondary_bus = 0; | |
| 85 | 83 | u8 subordinate_bus = 0; | |
| 86 | 84 | u8 hdr_type; | |
| 85 | + u32 value; | ||
| 87 | 86 | ||
| 88 | - if (pci_bus_read_config_byte(bus, devfn, PCI_HEADER_TYPE, &hdr_type) || | ||
| 89 | - (hdr_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE) | ||
| 87 | + if (ops->read(bus, devfn, PCI_HEADER_TYPE, sizeof(hdr_type), &value)) | ||
| 88 | + return false; | ||
| 89 | + hdr_type = value; | ||
| 90 | + if ((hdr_type & PCI_HEADER_TYPE_MASK) != PCI_HEADER_TYPE_BRIDGE) | ||
| 90 | 91 | return false; | |
| 91 | 92 | ||
| 92 | - pci_bus_read_config_byte(bus, devfn, PCI_SECONDARY_BUS, &secondary_bus); | ||
| 93 | - pci_bus_read_config_byte(bus, devfn, PCI_SUBORDINATE_BUS, | ||
| 94 | - &subordinate_bus); | ||
| 93 | + if (ops->read(bus, devfn, PCI_SECONDARY_BUS, sizeof(secondary_bus), | ||
| 94 | + &value)) | ||
| 95 | + return false; | ||
| 96 | + secondary_bus = value; | ||
| 97 | + if (ops->read(bus, devfn, PCI_SUBORDINATE_BUS, | ||
| 98 | + sizeof(subordinate_bus), &value)) | ||
| 99 | + return false; | ||
| 100 | + subordinate_bus = value; | ||
| 95 | 101 | if (!secondary_bus || subordinate_bus < secondary_bus) | |
| 96 | 102 | return false; | |
| 97 | 103 | ||
@@ -108,18 +114,20 @@ static bool mk_pci_bridge_reaches_assigned(struct pci_bus *bus, int devfn) | |||
| 108 | 114 | * mk_pci_should_probe - Check whether PCI probing may access a location | |
| 109 | 115 | * @bus: PCI bus | |
| 110 | 116 | * @devfn: device/function number | |
| 117 | + * @ops: unfiltered config-space operations used to identify bridge paths | ||
| 111 | 118 | * | |
| 112 | 119 | * Exact assigned functions and bridges leading to downstream assignments are | |
| 113 | 120 | * visible. Other functions are rejected before their config space is read. | |
| 114 | 121 | * | |
| 115 | 122 | * Returns: true if probing should proceed, false to skip entirely. | |
| 116 | 123 | */ | |
| 117 | - bool mk_pci_should_probe(struct pci_bus *bus, int devfn) | ||
| 124 | + bool mk_pci_should_probe(struct pci_bus *bus, int devfn, | ||
| 125 | + const struct pci_ops *ops) | ||
| 118 | 126 | { | |
| 119 | 127 | struct mk_pci_device *device; | |
| 120 | 128 | u16 domain = pci_domain_nr(bus); | |
| 121 | 129 | ||
| 122 | - if (!root_instance || !root_instance->dtb_data) | ||
| 130 | + if (!ops || !root_instance || !root_instance->dtb_data) | ||
| 123 | 131 | return true; | |
| 124 | 132 | if (!root_instance->pci_devices_valid || | |
| 125 | 133 | !root_instance->pci_device_count) | |
@@ -129,7 +137,7 @@ bool mk_pci_should_probe(struct pci_bus *bus, int devfn) | |||
| 129 | 137 | ||
| 130 | 138 | list_for_each_entry(device, &root_instance->pci_devices, list) { | |
| 131 | 139 | if (device->domain == domain && device->bus > bus->number) | |
| 132 | - return mk_pci_bridge_reaches_assigned(bus, devfn); | ||
| 140 | + return mk_pci_bridge_reaches_assigned(bus, devfn, ops); | ||
| 133 | 141 | } | |
| 134 | 142 | ||
| 135 | 143 | return false; | |
| Back | FazBrowse Home | New Git URL |
0 commit comments