[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [RFCv4,17/35] plat/pci_bus: Split specific code into different files
Hi, Justin. After applying all the patches in this series, I've tried to run httpreply and everything worked fine with the arm64 build. However, when I've tried to build and run the same app on x86_64, I've got this error: `[ 0.100170] ERR: [libkvmpci] <pci_bus_x86.c @ 88> PCI 00:02.00: Failed to initialize: Out of memory!` Here is a description of the problem I've found. The pci_bus_handler (ph) used in the x86 specific code is declared in "pc_bus.h" as a static variable. This header file is included in "pci_bus.c", where the functions that initialize the fields of ph are defined, and also in "pci_bus_x86.c", where functions that use ph during probing are defined. Since ph is declared as static in "pci_bus.h", all of it's fields are seen as empty in "pci_bus_x86.c". When pci_driver_add_device() tries to use one of these fields during probing, it fails and generates that OOM error. The problem is not the memory, but the fact that uk_calloc() gets a null value as it's alloc function. Since the only field of ph used in pci_bus_x86.c code was "ph.a"(uk_alloc), I've solved the issue by sending it as a parameter to all of the functions that use it ("ph.a" was already provided by "pci_probe()" to "arch_pci_probe()", the function that connects "pci_bus.c" to architecture-specific sources). Here is the diff between the original "pci_bus_x86.c" source in the patch and the fixed one. --- pci_bus_x86_original.c 2021-03-14 20:34:34.610336281 +0200 +++ pci_bus_x86.c 2021-03-14 20:36:45.523341015 +0200 @@ -68,7 +68,8 @@ static inline int pci_driver_add_device(struct pci_driver *drv, struct pci_address *addr, - struct pci_device_id *devid) + struct pci_device_id *devid, + struct uk_alloc *pha) { struct pci_device *dev; uint32_t config_addr; @@ -79,7 +80,7 @@ UK_ASSERT(addr != NULL); UK_ASSERT(devid != NULL); - dev = (struct pci_device *) uk_calloc(ph.a, 1, sizeof(*dev)); + dev = (struct pci_device *) uk_calloc(pha, 1, sizeof(*dev)); if (!dev) { uk_pr_err("PCI %02x:%02x.%02x: Failed to initialize: Out of memory!\n", (int) addr->bus, @@ -109,12 +110,12 @@ return 0; } -static void probe_bus(uint32_t); +static void probe_bus(uint32_t, struct uk_alloc *pha); /* Probe a function. Return 1 if the function does not exist in the device, 0 * otherwise. */ -static int probe_function(uint32_t bus, uint32_t device, uint32_t function) +static int probe_function(uint32_t bus, uint32_t device, uint32_t function, struct uk_alloc *pha) { uint32_t config_addr, config_data, subclass, secondary_bus; struct pci_address addr; @@ -169,14 +170,14 @@ uk_pr_info("<no driver>\n"); } else { uk_pr_info("driver %p\n", drv); - pci_driver_add_device(drv, &addr, &devid); + pci_driver_add_device(drv, &addr, &devid, pha); } /* 0x06 = Bridge Device, 0x04 = PCI-to-PCI bridge */ if ((devid.class_id == 0x06) && (subclass == 0x04) ) { PCI_CONF_READ(uint32_t, &secondary_bus, config_addr, SECONDARY_BUS); - probe_bus(secondary_bus); + probe_bus(secondary_bus, pha); } return 0; @@ -185,12 +186,12 @@ /* Recursive PCI enumeration: this function is called recursively by * probe_function upon discovering PCI-to-PCI bridges. */ -static void probe_bus(uint32_t bus) +static void probe_bus(uint32_t bus, struct uk_alloc *pha) { uint32_t config_addr, device, header_type, function = 0; for (device = 0; device < PCI_MAX_DEVICES; ++device) { - if (!probe_function(bus, device, function)) + if (!probe_function(bus, device, function, pha)) continue; config_addr = (PCI_ENABLE_BIT); @@ -203,11 +204,11 @@ /* Check remaining functions */ for (function = 1; function < PCI_MAX_FUNCTIONS; function++) - probe_function(bus, device, function); + probe_function(bus, device, function, pha); } } -int arch_pci_probe(void) +int arch_pci_probe(struct uk_alloc *pha) { uint32_t config_addr, function, header_type, vendor_id; @@ -219,7 +220,7 @@ if ((header_type & PCI_HEADER_TYPE_MSB_MASK) == 0) { /* Single PCI host controller */ - probe_bus(0); + probe_bus(0, pha); } else { /* Multiple PCI host controllers */ for (function = 0; function < PCI_MAX_FUNCTIONS; function++) { @@ -232,7 +233,7 @@ if (vendor_id != PCI_INVALID_ID) break; - probe_bus(function); + probe_bus(function, pha); } } Reviewed-by: Razvan Virtan <virtanrazvan@xxxxxxxxx>
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |