[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [RFC 6/6] acpi:arm64: Add support for parsing IORT table
Add limited support for parsing IORT table to initialize SMMU devices. Signed-off-by: Sameer Goel <sgoel@xxxxxxxxxxxxxx> --- xen/arch/arm/setup.c | 3 + xen/drivers/acpi/Makefile | 1 + xen/drivers/acpi/arm/Makefile | 1 + xen/drivers/acpi/arm/iort.c | 232 +++++++++++++++++++----------------- xen/drivers/passthrough/arm/iommu.c | 15 +-- xen/include/acpi/acpi.h | 1 + xen/include/acpi/acpi_iort.h | 25 ++-- xen/include/asm-arm/device.h | 2 + xen/include/xen/acpi.h | 21 ++++ xen/include/xen/lib.h | 7 +- xen/include/xen/pci.h | 1 + 11 files changed, 184 insertions(+), 125 deletions(-) create mode 100644 xen/drivers/acpi/arm/Makefile diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c index 92a2de6..5dc93ff 100644 --- a/xen/arch/arm/setup.c +++ b/xen/arch/arm/setup.c @@ -753,6 +753,9 @@ void __init start_xen(unsigned long boot_phys_offset, /* Parse the ACPI tables for possible boot-time configuration */ acpi_boot_table_init(); + /* Initialize the IORT tables */ + acpi_iort_init(); + if ( acpi_disabled ) printk("Booting using Device Tree\n"); else diff --git a/xen/drivers/acpi/Makefile b/xen/drivers/acpi/Makefile index 444b11d..4165318 100644 --- a/xen/drivers/acpi/Makefile +++ b/xen/drivers/acpi/Makefile @@ -1,5 +1,6 @@ subdir-y += tables subdir-y += utilities +subdir-$(CONFIG_ARM_64) += arm subdir-$(CONFIG_X86) += apei obj-bin-y += tables.init.o diff --git a/xen/drivers/acpi/arm/Makefile b/xen/drivers/acpi/arm/Makefile new file mode 100644 index 0000000..7c039bb --- /dev/null +++ b/xen/drivers/acpi/arm/Makefile @@ -0,0 +1 @@ +obj-y += iort.o diff --git a/xen/drivers/acpi/arm/iort.c b/xen/drivers/acpi/arm/iort.c index 4a5bb96..c22ec31 100644 --- a/xen/drivers/acpi/arm/iort.c +++ b/xen/drivers/acpi/arm/iort.c @@ -14,29 +14,40 @@ * This file implements early detection/parsing of I/O mapping * reported to OS through firmware via I/O Remapping Table (IORT) * IORT document number: ARM DEN 0049A + * + * Based on Linux drivers/acpi/arm64/iort.c + * => commit ca78d3173cff3503bcd15723b049757f75762d15 + * + * Xen modification: + * Sameer Goel <sgoel@xxxxxxxxxxxxxx> + * Copyright (C) 2017, The Linux Foundation, All rights reserved. + * */ -#define pr_fmt(fmt) "ACPI: IORT: " fmt +#include <xen/acpi.h> +#include <xen/fwnode.h> +#include <xen/iommu.h> +#include <xen/lib.h> +#include <xen/list.h> +#include <xen/pci.h> + +#include <asm/device.h> -#include <linux/acpi_iort.h> -#include <linux/iommu.h> -#include <linux/kernel.h> -#include <linux/list.h> -#include <linux/pci.h> -#include <linux/platform_device.h> -#include <linux/slab.h> #define IORT_TYPE_MASK(type) (1 << (type)) #define IORT_MSI_TYPE (1 << ACPI_IORT_NODE_ITS_GROUP) #define IORT_IOMMU_TYPE ((1 << ACPI_IORT_NODE_SMMU) | \ (1 << ACPI_IORT_NODE_SMMU_V3)) +#if 0 struct iort_its_msi_chip { struct list_head list; struct fwnode_handle *fw_node; u32 translation_id; }; +#endif + struct iort_fwnode { struct list_head list; struct acpi_iort_node *iort_node; @@ -60,7 +71,7 @@ static inline int iort_set_fwnode(struct acpi_iort_node *iort_node, { struct iort_fwnode *np; - np = kzalloc(sizeof(struct iort_fwnode), GFP_ATOMIC); + np = xzalloc(struct iort_fwnode); if (WARN_ON(!np)) return -ENOMEM; @@ -114,7 +125,7 @@ static inline void iort_delete_fwnode(struct acpi_iort_node *node) list_for_each_entry_safe(curr, tmp, &iort_fwnode_list, list) { if (curr->iort_node == node) { list_del(&curr->list); - kfree(curr); + xfree(curr); break; } } @@ -127,6 +138,7 @@ typedef acpi_status (*iort_find_node_callback) /* Root pointer to the mapped IORT table */ static struct acpi_table_header *iort_table; +#if 0 static LIST_HEAD(iort_msi_chip_list); static DEFINE_SPINLOCK(iort_msi_chip_lock); @@ -199,7 +211,7 @@ struct fwnode_handle *iort_find_domain_token(int trans_id) return fw_node; } - +#endif static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type, iort_find_node_callback callback, void *context) @@ -219,9 +231,10 @@ static struct acpi_iort_node *iort_scan_node(enum acpi_iort_node_type type, iort_table->length); for (i = 0; i < iort->node_count; i++) { - if (WARN_TAINT(iort_node >= iort_end, TAINT_FIRMWARE_WORKAROUND, - "IORT node pointer overflows, bad table!\n")) + if (iort_node >= iort_end) { + printk(XENLOG_ERR "IORT node pointer overflows, bad table!\n"); return NULL; + } if (iort_node->type == type && ACPI_SUCCESS(callback(iort_node, context))) @@ -249,6 +262,14 @@ bool iort_node_match(u8 type) return node != NULL; } +/* + * Following 2 definies should come from the PCI passthrough implementation. + * Based on the current pci_dev define the bus number and seg number come + * from pci_dev so making an API assumption + */ +#define to_pci_dev(p) container_of(p, struct pci_dev,dev) +#define pci_domain_nr(dev) dev->seg + static acpi_status iort_match_node_callback(struct acpi_iort_node *node, void *context) { @@ -256,6 +277,11 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node, acpi_status status; if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) { + status = AE_NOT_IMPLEMENTED; +/* + * Named components not supported yet. + */ +#if 0 struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; struct acpi_device *adev = to_acpi_device_node(dev->fwnode); struct acpi_iort_named_component *ncomp; @@ -275,11 +301,12 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node, status = !strcmp(ncomp->device_name, buf.pointer) ? AE_OK : AE_NOT_FOUND; acpi_os_free(buf.pointer); +#endif } else if (node->type == ACPI_IORT_NODE_PCI_ROOT_COMPLEX) { struct acpi_iort_root_complex *pci_rc; - struct pci_bus *bus; + struct pci_dev *pci_dev; - bus = to_pci_bus(dev); + pci_dev = to_pci_dev(dev); pci_rc = (struct acpi_iort_root_complex *)node->node_data; /* @@ -287,12 +314,11 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node, * with root complexes. Each segment number can represent only * one root complex. */ - status = pci_rc->pci_segment_number == pci_domain_nr(bus) ? + status = pci_rc->pci_segment_number == pci_domain_nr(pci_dev) ? AE_OK : AE_NOT_FOUND; } else { status = AE_NOT_FOUND; } -out: return status; } @@ -307,7 +333,8 @@ static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in, return 0; } - pr_warn(FW_BUG "[map %p] SINGLE MAPPING flag not allowed for node type %d, skipping ID map\n", + printk(XENLOG_WARNING "[map %p] SINGLE MAPPING flag not \ + allowed for node type %d, skipping ID map\n", map, type); return -ENXIO; } @@ -320,6 +347,11 @@ static int iort_id_map(struct acpi_iort_id_mapping *map, u8 type, u32 rid_in, return 0; } +/* + * Name components are not supported yet so we do not need the + * iort_node_get_id function + */ +#if 0 static struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, u32 *id_out, u8 type_mask, @@ -337,8 +369,8 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, /* Firmware bug! */ if (!map->output_reference) { - pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", - node, node->type); + printk(XENLOG_ERR "[node %p type %d] ID map has NULL parent \ + reference\n", node, node->type); return NULL; } @@ -358,6 +390,7 @@ struct acpi_iort_node *iort_node_get_id(struct acpi_iort_node *node, return NULL; } +#endif static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node, u32 rid_in, u32 *rid_out, @@ -384,8 +417,8 @@ static struct acpi_iort_node *iort_node_map_rid(struct acpi_iort_node *node, /* Firmware bug! */ if (!map->output_reference) { - pr_err(FW_BUG "[node %p type %d] ID map has NULL parent reference\n", - node, node->type); + printk(XENLOG_ERR "[node %p type %d] ID map has NULL \ + parent reference\n", node, node->type); goto fail_map; } @@ -410,6 +443,10 @@ fail_map: return NULL; } +/* Xen: Comment out the NamedComponent and ITS mapping code till the support + * is available. + * */ +#if 0 static struct acpi_iort_node *iort_find_dev_node(struct device *dev) { struct pci_bus *pbus; @@ -503,6 +540,9 @@ struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id) return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI); } +/* + * RID is the same as PCI_DEVID(BDF) for QDF2400 + */ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data) { u32 *rid = data; @@ -510,7 +550,7 @@ static int __get_pci_rid(struct pci_dev *pdev, u16 alias, void *data) *rid = alias; return 0; } - +#endif static int arm_smmu_iort_xlate(struct device *dev, u32 streamid, struct fwnode_handle *fwnode, const struct iommu_ops *ops) @@ -523,29 +563,24 @@ static int arm_smmu_iort_xlate(struct device *dev, u32 streamid, return ret; } -static const struct iommu_ops *iort_iommu_xlate(struct device *dev, - struct acpi_iort_node *node, - u32 streamid) +static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node, + u32 streamid) { - const struct iommu_ops *ops = NULL; int ret = -ENODEV; struct fwnode_handle *iort_fwnode; if (node) { iort_fwnode = iort_get_fwnode(node); if (!iort_fwnode) - return NULL; - - ops = iommu_ops_from_fwnode(iort_fwnode); - if (!ops) - return NULL; + return ret; - ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, ops); + ret = arm_smmu_iort_xlate(dev, streamid, iort_fwnode, NULL); } - return ret ? NULL : ops; + return ret; } +#if 0 /* Xen: We do not need this function for Xen */ /** * iort_set_dma_mask - Set-up dma mask for a device. * @@ -567,39 +602,43 @@ void iort_set_dma_mask(struct device *dev) if (!dev->dma_mask) dev->dma_mask = &dev->coherent_dma_mask; } - +#endif /** - * iort_iommu_configure - Set-up IOMMU configuration for a device. + * iort_iommu_configure - Set-up IOMMU configuration for a device. This + * function sets up the fwspec as needed for a given device. Only PCI + * devices are supported for now. * * @dev: device to configure * - * Returns: iommu_ops pointer on configuration success - * NULL on configuration failure + * Returns: Appropriate acpi_status */ -const struct iommu_ops *iort_iommu_configure(struct device *dev) +acpi_status iort_iommu_configure(struct device *dev) { struct acpi_iort_node *node, *parent; - const struct iommu_ops *ops = NULL; u32 streamid = 0; + acpi_status status = AE_OK; if (dev_is_pci(dev)) { - struct pci_bus *bus = to_pci_dev(dev)->bus; + struct pci_dev *pci_device = to_pci_dev(dev); u32 rid; - pci_for_each_dma_alias(to_pci_dev(dev), __get_pci_rid, - &rid); + rid = PCI_BDF2(pci_device->bus,pci_device->devfn); node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, - iort_match_node_callback, &bus->dev); + iort_match_node_callback, dev); if (!node) - return NULL; + return AE_NOT_FOUND; parent = iort_node_map_rid(node, rid, &streamid, IORT_IOMMU_TYPE); - ops = iort_iommu_xlate(dev, parent, streamid); + status = iort_iommu_xlate(dev, parent, streamid); + + status = status ? AE_ERROR : AE_OK; } else { + status = AE_NOT_IMPLEMENTED; +#if 0 int i = 0; node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, @@ -616,11 +655,17 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev) parent = iort_node_get_id(node, &streamid, IORT_IOMMU_TYPE, i++); } +#endif } - return ops; + return status; } +/* + * Xen: Not using the parsin ops for now. Need to check and see if it will + * be useful to use these in some form, or let the driver parse IORT node. + */ +#if 0 static void __init acpi_iort_register_irq(int hwirq, const char *name, int trigger, struct resource *res) @@ -807,93 +852,63 @@ const struct iort_iommu_config *iort_get_iommu_cfg(struct acpi_iort_node *node) return NULL; } } - +#endif /** - * iort_add_smmu_platform_device() - Allocate a platform device for SMMU + * Xen: rename the function to iort_add_smmu_device + * iort_add_smmu_device() - Allocate a device for SMMU * @node: Pointer to SMMU ACPI IORT node * * Returns: 0 on success, <0 failure */ -static int __init iort_add_smmu_platform_device(struct acpi_iort_node *node) +static int __init iort_add_smmu_device(struct acpi_iort_node *node) { struct fwnode_handle *fwnode; - struct platform_device *pdev; - struct resource *r; - enum dev_dma_attr attr; - int ret, count; - const struct iort_iommu_config *ops = iort_get_iommu_cfg(node); - - if (!ops) - return -ENODEV; - - pdev = platform_device_alloc(ops->name, PLATFORM_DEVID_AUTO); - if (!pdev) - return -ENOMEM; - - count = ops->iommu_count_resources(node); + struct device *dev; + int ret; - r = kcalloc(count, sizeof(*r), GFP_KERNEL); - if (!r) { - ret = -ENOMEM; - goto dev_put; - } - - ops->iommu_init_resources(r, node); - - ret = platform_device_add_resources(pdev, r, count); /* - * Resources are duplicated in platform_device_add_resources, - * free their allocated memory + * Not enabling the parsing ops for now. The corresponding driver + * can parse this information as needed, so deleting relevent code as + * compared to base revision. */ - kfree(r); - if (ret) - goto dev_put; + dev = xzalloc(struct device); + if (!dev) + return -ENOMEM; /* * Add a copy of IORT node pointer to platform_data to * be used to retrieve IORT data information. */ - ret = platform_device_add_data(pdev, &node, sizeof(node)); - if (ret) - goto dev_put; - - /* - * We expect the dma masks to be equivalent for - * all SMMUs set-ups - */ - pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask; + dev->type = DEV_ACPI; /* This should not be needed and we can check + fwnode. Defining for legacy support */ + dev->acpi_node = node;/* A copy of the node does not seem necessary */ fwnode = iort_get_fwnode(node); if (!fwnode) { ret = -ENODEV; - goto dev_put; + goto error; } - pdev->dev.fwnode = fwnode; - - attr = ops->iommu_is_coherent(node) ? - DEV_DMA_COHERENT : DEV_DMA_NON_COHERENT; - - /* Configure DMA for the page table walker */ - acpi_dma_configure(&pdev->dev, attr); + dev->fwnode = fwnode; - ret = platform_device_add(pdev); - if (ret) - goto dma_deconfigure; + /* Call the acpi init functions for IOMMU devices */ + ret = acpi_device_init(DEVICE_IOMMU, (void*)dev, node->type); return 0; -dma_deconfigure: - acpi_dma_deconfigure(&pdev->dev); -dev_put: - platform_device_put(pdev); +error: + xfree(dev); return ret; } -static void __init iort_init_platform_devices(void) +/* + * Xen: Rename the function to iort_init_devices as this function will + * populate the device object for SMMU devices. + */ +static void __init iort_init_devices(void) { struct acpi_iort_node *iort_node, *iort_end; struct acpi_table_iort *iort; @@ -914,7 +929,7 @@ static void __init iort_init_platform_devices(void) for (i = 0; i < iort->node_count; i++) { if (iort_node >= iort_end) { - pr_err("iort node pointer overflows, bad table\n"); + printk(XENLOG_ERR "iort node pointer overflows, bad table\n"); return; } @@ -927,7 +942,7 @@ static void __init iort_init_platform_devices(void) iort_set_fwnode(iort_node, fwnode); - ret = iort_add_smmu_platform_device(iort_node); + ret = iort_add_smmu_device(iort_node); if (ret) { iort_delete_fwnode(iort_node); acpi_free_fwnode_static(fwnode); @@ -949,13 +964,14 @@ void __init acpi_iort_init(void) if (status != AE_NOT_FOUND) { const char *msg = acpi_format_exception(status); - pr_err("Failed to get table, %s\n", msg); + printk(XENLOG_ERR "Failed to get table, %s\n", msg); } return; } - iort_init_platform_devices(); + iort_init_devices(); - acpi_probe_device_table(iort); + /* Not used for now */ + //acpi_probe_device_table(iort); } diff --git a/xen/drivers/passthrough/arm/iommu.c b/xen/drivers/passthrough/arm/iommu.c index edf70c2..1397da5 100644 --- a/xen/drivers/passthrough/arm/iommu.c +++ b/xen/drivers/passthrough/arm/iommu.c @@ -74,24 +74,26 @@ int arch_iommu_populate_page_table(struct domain *d) return -ENOSYS; } +/* + * The ops parameter in this function will always be NULL for Xen, + * as the ops are set per domain. + */ int iommu_fwspec_init(struct device *dev, struct fwnode_handle *iommu_fwnode, const struct iommu_ops *ops) { struct iommu_fwspec *fwspec = dev->iommu_fwspec; + /* + * fwspec is already allocated for this device. + */ if (fwspec) - return ops == fwspec->ops ? 0 : -EINVAL; + return 0; fwspec = xzalloc(struct iommu_fwspec); if (!fwspec) return -ENOMEM; - /* Ref counting for the dt device node is not needed */ - - /*of_node_get(to_of_node(iommu_fwnode));*/ - fwspec->iommu_fwnode = iommu_fwnode; - fwspec->ops = ops; dev->iommu_fwspec = fwspec; return 0; } @@ -101,7 +103,6 @@ void iommu_fwspec_free(struct device *dev) struct iommu_fwspec *fwspec = dev->iommu_fwspec; if (fwspec) { - /*fwnode_handle_put(fwspec->iommu_fwnode);*/ xfree(fwspec); dev->iommu_fwspec = NULL; } diff --git a/xen/include/acpi/acpi.h b/xen/include/acpi/acpi.h index c852701..1ac92b2 100644 --- a/xen/include/acpi/acpi.h +++ b/xen/include/acpi/acpi.h @@ -60,6 +60,7 @@ #include "actbl.h" /* ACPI table definitions */ #include "aclocal.h" /* Internal data types */ #include "acoutput.h" /* Error output and Debug macros */ +#include "acpi_iort.h" /* Utility defines for IORT */ #include "acpiosxf.h" /* Interfaces to the ACPI-to-OS layer */ #include "acpixf.h" /* ACPI core subsystem external interfaces */ #include "acglobal.h" /* All global variables */ diff --git a/xen/include/acpi/acpi_iort.h b/xen/include/acpi/acpi_iort.h index 77e0809..c0b5b8d 100644 --- a/xen/include/acpi/acpi_iort.h +++ b/xen/include/acpi/acpi_iort.h @@ -19,27 +19,35 @@ #ifndef __ACPI_IORT_H__ #define __ACPI_IORT_H__ -#include <linux/acpi.h> -#include <linux/fwnode.h> -#include <linux/irqdomain.h> +#include <xen/acpi.h> +#include <asm/device.h> +/* + * We are not using IORT IRQ bindings for this change set + */ +#if 0 #define IORT_IRQ_MASK(irq) (irq & 0xffffffffULL) #define IORT_IRQ_TRIGGER_MASK(irq) ((irq >> 32) & 0xffffffffULL) int iort_register_domain_token(int trans_id, struct fwnode_handle *fw_node); void iort_deregister_domain_token(int trans_id); struct fwnode_handle *iort_find_domain_token(int trans_id); -#ifdef CONFIG_ACPI_IORT +#endif + +#ifdef CONFIG_ARM_64 void acpi_iort_init(void); bool iort_node_match(u8 type); +#if 0 u32 iort_msi_map_rid(struct device *dev, u32 req_id); struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id); /* IOMMU interface */ void iort_set_dma_mask(struct device *dev); -const struct iommu_ops *iort_iommu_configure(struct device *dev); +#endif +acpi_status iort_iommu_configure(struct device *dev); #else static inline void acpi_iort_init(void) { } static inline bool iort_node_match(u8 type) { return false; } +#if 0 static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id) { return req_id; } static inline struct irq_domain *iort_get_device_domain(struct device *dev, @@ -47,12 +55,11 @@ static inline struct irq_domain *iort_get_device_domain(struct device *dev, { return NULL; } /* IOMMU interface */ static inline void iort_set_dma_mask(struct device *dev) { } +#endif static inline -const struct iommu_ops *iort_iommu_configure(struct device *dev) -{ return NULL; } +acpi_status iommu_ops iort_iommu_configure(struct device *dev) +{ return AE_NOT_IMPLEMENTED; } #endif -#define IORT_ACPI_DECLARE(name, table_id, fn) \ - ACPI_DECLARE_PROBE_ENTRY(iort, name, table_id, 0, NULL, 0, fn) #endif /* __ACPI_IORT_H__ */ diff --git a/xen/include/asm-arm/device.h b/xen/include/asm-arm/device.h index 5027c87..4eef9ce 100644 --- a/xen/include/asm-arm/device.h +++ b/xen/include/asm-arm/device.h @@ -7,6 +7,7 @@ enum device_type { DEV_DT, + DEV_ACPI, }; struct dev_archdata { @@ -20,6 +21,7 @@ struct device #ifdef CONFIG_HAS_DEVICE_TREE struct dt_device_node *of_node; /* Used by drivers imported from Linux */ #endif + void *acpi_node; /*Current use case is acpi_iort_node */ struct fwnode_handle *fwnode; /*fw device node identifier */ struct iommu_fwspec *iommu_fwspec; struct dev_archdata archdata; diff --git a/xen/include/xen/acpi.h b/xen/include/xen/acpi.h index 30ec0ee..2106ba9 100644 --- a/xen/include/xen/acpi.h +++ b/xen/include/xen/acpi.h @@ -32,6 +32,7 @@ #include <acpi/acpi.h> #include <asm/acpi.h> +#include <xen/fwnode.h> #define ACPI_MADT_GET_(fld, x) (((x) & ACPI_MADT_##fld##_MASK) / \ (ACPI_MADT_##fld##_MASK & -ACPI_MADT_##fld##_MASK)) @@ -49,6 +50,26 @@ (!(entry)) || (unsigned long)(entry) + sizeof(*(entry)) > (end) || \ (entry)->header.length < sizeof(*(entry))) +static inline struct fwnode_handle *acpi_alloc_fwnode_static(void) +{ + struct fwnode_handle *fwnode; + + fwnode = xzalloc(struct fwnode_handle); + if (!fwnode) + return NULL; + + fwnode->type = FWNODE_ACPI_STATIC; + + return fwnode; +} + +static inline void acpi_free_fwnode_static(struct fwnode_handle *fwnode) +{ + if (WARN_ON(!fwnode || fwnode->type != FWNODE_ACPI_STATIC)) + return; + + xfree(fwnode); +} #ifdef CONFIG_ACPI enum acpi_interrupt_id { diff --git a/xen/include/xen/lib.h b/xen/include/xen/lib.h index 995a85a..3785fae 100644 --- a/xen/include/xen/lib.h +++ b/xen/include/xen/lib.h @@ -9,7 +9,12 @@ #include <asm/bug.h> #define BUG_ON(p) do { if (unlikely(p)) BUG(); } while (0) -#define WARN_ON(p) do { if (unlikely(p)) WARN(); } while (0) +#define WARN_ON(p) ({ \ + int __ret_warn_on = !!(p); \ + if (unlikely(__ret_warn_on)) \ + WARN(); \ + unlikely(__ret_warn_on); \ +}) #if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 6) /* Force a compilation error if condition is true */ diff --git a/xen/include/xen/pci.h b/xen/include/xen/pci.h index 59b6e8a..c518569 100644 --- a/xen/include/xen/pci.h +++ b/xen/include/xen/pci.h @@ -88,6 +88,7 @@ struct pci_dev { #define PT_FAULT_THRESHOLD 10 } fault; u64 vf_rlen[6]; + struct device dev; }; #define for_each_pdev(domain, pdev) \ -- Qualcomm Datacenter Technologies as an affiliate of Qualcomm Technologies, Inc. Qualcomm Technologies, Inc. is a member of the Code Aurora Forum, a Linux Foundation Collaborative Project. _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx https://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |