Merge tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux
Pull more arm64 fixes from Will Deacon:
- Fix incorrect LDADD instruction encoding in our disassembly macros
- Disable the broken ARM64_PSEUDO_NMI support for now
- Add workaround for Cortex-A76 CPU erratum #1463225
- Handle Cortex-A76/Neoverse-N1 erratum #1418040 w/ existing workaround
- Fix IORT build failure if IOMMU_SUPPORT=n
- Fix place-relative module relocation range checking and its
interaction with KASLR
* tag 'arm64-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux:
arm64: insn: Add BUILD_BUG_ON() for invalid masks
arm64: insn: Fix ldadd instruction encoding
arm64: Kconfig: Make ARM64_PSEUDO_NMI depend on BROKEN for now
arm64: Handle erratum 1418040
as a superset of erratum 1188873
arm64/module: deal with ambiguity in PRELxx relocation ranges
ACPI/IORT: Fix build error when IOMMU_SUPPORT is disabled
arm64/kernel: kaslr: reduce module randomization range to 2 GB
arm64: errata: Add workaround for Cortex-A76 erratum #1463225
arm64: Remove useless message during oops
This commit is contained in:
@@ -753,31 +753,6 @@ static int __maybe_unused __get_pci_rid(struct pci_dev *pdev, u16 alias,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
|
||||
struct fwnode_handle *fwnode,
|
||||
const struct iommu_ops *ops)
|
||||
{
|
||||
int ret = iommu_fwspec_init(dev, fwnode, ops);
|
||||
|
||||
if (!ret)
|
||||
ret = iommu_fwspec_add_ids(dev, &streamid, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static inline bool iort_iommu_driver_enabled(u8 type)
|
||||
{
|
||||
switch (type) {
|
||||
case ACPI_IORT_NODE_SMMU_V3:
|
||||
return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
|
||||
case ACPI_IORT_NODE_SMMU:
|
||||
return IS_BUILTIN(CONFIG_ARM_SMMU);
|
||||
default:
|
||||
pr_warn("IORT node type %u does not describe an SMMU\n", type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IOMMU_API
|
||||
static struct acpi_iort_node *iort_get_msi_resv_iommu(struct device *dev)
|
||||
{
|
||||
@@ -878,15 +853,39 @@ int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
|
||||
|
||||
return (resv == its->its_count) ? resv : -ENODEV;
|
||||
}
|
||||
#else
|
||||
static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev)
|
||||
{ return NULL; }
|
||||
static inline int iort_add_device_replay(const struct iommu_ops *ops,
|
||||
struct device *dev)
|
||||
{ return 0; }
|
||||
int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
|
||||
{ return 0; }
|
||||
#endif
|
||||
|
||||
static inline bool iort_iommu_driver_enabled(u8 type)
|
||||
{
|
||||
switch (type) {
|
||||
case ACPI_IORT_NODE_SMMU_V3:
|
||||
return IS_BUILTIN(CONFIG_ARM_SMMU_V3);
|
||||
case ACPI_IORT_NODE_SMMU:
|
||||
return IS_BUILTIN(CONFIG_ARM_SMMU);
|
||||
default:
|
||||
pr_warn("IORT node type %u does not describe an SMMU\n", type);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static int arm_smmu_iort_xlate(struct device *dev, u32 streamid,
|
||||
struct fwnode_handle *fwnode,
|
||||
const struct iommu_ops *ops)
|
||||
{
|
||||
int ret = iommu_fwspec_init(dev, fwnode, ops);
|
||||
|
||||
if (!ret)
|
||||
ret = iommu_fwspec_add_ids(dev, &streamid, 1);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_root_complex *pci_rc;
|
||||
|
||||
pci_rc = (struct acpi_iort_root_complex *)node->node_data;
|
||||
return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
|
||||
}
|
||||
|
||||
static int iort_iommu_xlate(struct device *dev, struct acpi_iort_node *node,
|
||||
u32 streamid)
|
||||
@@ -933,6 +932,93 @@ static int iort_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data)
|
||||
return iort_iommu_xlate(info->dev, parent, streamid);
|
||||
}
|
||||
|
||||
/**
|
||||
* iort_iommu_configure - Set-up IOMMU configuration for a device.
|
||||
*
|
||||
* @dev: device to configure
|
||||
*
|
||||
* Returns: iommu_ops pointer on configuration success
|
||||
* NULL on configuration failure
|
||||
*/
|
||||
const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
||||
{
|
||||
struct acpi_iort_node *node, *parent;
|
||||
const struct iommu_ops *ops;
|
||||
u32 streamid = 0;
|
||||
int err = -ENODEV;
|
||||
|
||||
/*
|
||||
* If we already translated the fwspec there
|
||||
* is nothing left to do, return the iommu_ops.
|
||||
*/
|
||||
ops = iort_fwspec_iommu_ops(dev);
|
||||
if (ops)
|
||||
return ops;
|
||||
|
||||
if (dev_is_pci(dev)) {
|
||||
struct pci_bus *bus = to_pci_dev(dev)->bus;
|
||||
struct iort_pci_alias_info info = { .dev = dev };
|
||||
|
||||
node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
|
||||
iort_match_node_callback, &bus->dev);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
info.node = node;
|
||||
err = pci_for_each_dma_alias(to_pci_dev(dev),
|
||||
iort_pci_iommu_init, &info);
|
||||
|
||||
if (!err && iort_pci_rc_supports_ats(node))
|
||||
dev->iommu_fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
|
||||
} else {
|
||||
int i = 0;
|
||||
|
||||
node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
|
||||
iort_match_node_callback, dev);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
parent = iort_node_map_platform_id(node, &streamid,
|
||||
IORT_IOMMU_TYPE,
|
||||
i++);
|
||||
|
||||
if (parent)
|
||||
err = iort_iommu_xlate(dev, parent, streamid);
|
||||
} while (parent && !err);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have reason to believe the IOMMU driver missed the initial
|
||||
* add_device callback for dev, replay it to get things in order.
|
||||
*/
|
||||
if (!err) {
|
||||
ops = iort_fwspec_iommu_ops(dev);
|
||||
err = iort_add_device_replay(ops, dev);
|
||||
}
|
||||
|
||||
/* Ignore all other errors apart from EPROBE_DEFER */
|
||||
if (err == -EPROBE_DEFER) {
|
||||
ops = ERR_PTR(err);
|
||||
} else if (err) {
|
||||
dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
|
||||
ops = NULL;
|
||||
}
|
||||
|
||||
return ops;
|
||||
}
|
||||
#else
|
||||
static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev)
|
||||
{ return NULL; }
|
||||
static inline int iort_add_device_replay(const struct iommu_ops *ops,
|
||||
struct device *dev)
|
||||
{ return 0; }
|
||||
int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head)
|
||||
{ return 0; }
|
||||
const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
||||
{ return NULL; }
|
||||
#endif
|
||||
|
||||
static int nc_dma_get_range(struct device *dev, u64 *size)
|
||||
{
|
||||
struct acpi_iort_node *node;
|
||||
@@ -1031,90 +1117,6 @@ void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *dma_size)
|
||||
dev_dbg(dev, "dma_pfn_offset(%#08llx)\n", offset);
|
||||
}
|
||||
|
||||
static bool iort_pci_rc_supports_ats(struct acpi_iort_node *node)
|
||||
{
|
||||
struct acpi_iort_root_complex *pci_rc;
|
||||
|
||||
pci_rc = (struct acpi_iort_root_complex *)node->node_data;
|
||||
return pci_rc->ats_attribute & ACPI_IORT_ATS_SUPPORTED;
|
||||
}
|
||||
|
||||
/**
|
||||
* iort_iommu_configure - Set-up IOMMU configuration for a device.
|
||||
*
|
||||
* @dev: device to configure
|
||||
*
|
||||
* Returns: iommu_ops pointer on configuration success
|
||||
* NULL on configuration failure
|
||||
*/
|
||||
const struct iommu_ops *iort_iommu_configure(struct device *dev)
|
||||
{
|
||||
struct acpi_iort_node *node, *parent;
|
||||
const struct iommu_ops *ops;
|
||||
u32 streamid = 0;
|
||||
int err = -ENODEV;
|
||||
|
||||
/*
|
||||
* If we already translated the fwspec there
|
||||
* is nothing left to do, return the iommu_ops.
|
||||
*/
|
||||
ops = iort_fwspec_iommu_ops(dev);
|
||||
if (ops)
|
||||
return ops;
|
||||
|
||||
if (dev_is_pci(dev)) {
|
||||
struct pci_bus *bus = to_pci_dev(dev)->bus;
|
||||
struct iort_pci_alias_info info = { .dev = dev };
|
||||
|
||||
node = iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX,
|
||||
iort_match_node_callback, &bus->dev);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
info.node = node;
|
||||
err = pci_for_each_dma_alias(to_pci_dev(dev),
|
||||
iort_pci_iommu_init, &info);
|
||||
|
||||
if (!err && iort_pci_rc_supports_ats(node))
|
||||
dev->iommu_fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS;
|
||||
} else {
|
||||
int i = 0;
|
||||
|
||||
node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT,
|
||||
iort_match_node_callback, dev);
|
||||
if (!node)
|
||||
return NULL;
|
||||
|
||||
do {
|
||||
parent = iort_node_map_platform_id(node, &streamid,
|
||||
IORT_IOMMU_TYPE,
|
||||
i++);
|
||||
|
||||
if (parent)
|
||||
err = iort_iommu_xlate(dev, parent, streamid);
|
||||
} while (parent && !err);
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have reason to believe the IOMMU driver missed the initial
|
||||
* add_device callback for dev, replay it to get things in order.
|
||||
*/
|
||||
if (!err) {
|
||||
ops = iort_fwspec_iommu_ops(dev);
|
||||
err = iort_add_device_replay(ops, dev);
|
||||
}
|
||||
|
||||
/* Ignore all other errors apart from EPROBE_DEFER */
|
||||
if (err == -EPROBE_DEFER) {
|
||||
ops = ERR_PTR(err);
|
||||
} else if (err) {
|
||||
dev_dbg(dev, "Adding to IOMMU failed: %d\n", err);
|
||||
ops = NULL;
|
||||
}
|
||||
|
||||
return ops;
|
||||
}
|
||||
|
||||
static void __init acpi_iort_register_irq(int hwirq, const char *name,
|
||||
int trigger,
|
||||
struct resource *res)
|
||||
|
Reference in New Issue
Block a user