[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Xen-devel] [RFC 6/6] acpi:arm64: Add support for parsing IORT table



CCing Jan

On Thu, 8 Jun 2017, Sameer Goel wrote:
> 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

This patch doesn't apply with "git am" and doesn't build on x86 with:

In file included from /local/repos/xen-upstream/xen/include/xen/iommu.h:24:0,
                 from /local/repos/xen-upstream/xen/include/asm/hvm/domain.h:23,
                 from /local/repos/xen-upstream/xen/include/asm/domain.h:7,
                 from /local/repos/xen-upstream/xen/include/xen/domain.h:8,
                 from /local/repos/xen-upstream/xen/include/xen/sched.h:11,
                 from x86_64/asm-offsets.c:9:
/local/repos/xen-upstream/xen/include/xen/pci.h:91:19: error: field ‘dev’ has 
incomplete type
     struct device dev;
                   ^
In file included from /local/repos/xen-upstream/xen/include/acpi/acpi.h:63:0,
                 from /local/repos/xen-upstream/xen/include/xen/acpi.h:33,
                 from /local/repos/xen-upstream/xen/include/asm/fixmap.h:21,
                 from x86_64/asm-offsets.c:12:
/local/repos/xen-upstream/xen/include/acpi/acpi_iort.h:60:23: error: expected 
‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘iort_iommu_configure’
 acpi_status iommu_ops iort_iommu_configure(struct device *dev)
                       ^
make[3]: *** [asm-offsets.s] Error 1


And it doesn't build on arm64 with:

/local/repos/xen-upstream/xen/arch/arm/setup.c:765: undefined reference to 
`acpi_iort_init'
/local/repos/gcc-linaro-4.9-2014.05-aarch64-linux-gnu-x86_64-linux-gnu/bin/aarch64-linux-gnu-ld:
 /local/repos/xen-upstream/xen/.xen-syms.0: hidden symbol `acpi_iort_init' 
isn't defined
/local/repos/gcc-linaro-4.9-2014.05-aarch64-linux-gnu-x86_64-linux-gnu/bin/aarch64-linux-gnu-ld:
 final link failed: Bad value
make[3]: *** [/local/repos/xen-upstream/xen/xen-syms] Error 1


> 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);                               \
> +})

Why this change?


>  #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) \
_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxx
https://lists.xen.org/xen-devel

 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.