IOMMU Updates for Linux 3.5
Not much stuff this time. The only change to the IOMMU core code is the addition of a handle to the fault handling code. A few updates to the AMD IOMMU driver to work around new errata. The other patches are mostly fixes and enhancements to the existing ARM IOMMU drivers and documentation updates. A new IOMMU driver for the Exynos platform was also underway but got merged via the Samsung tree and is not part of this tree. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.11 (GNU/Linux) iQIcBAABAgAGBQJPxfseAAoJECvwRC2XARrjvL4QAL39988y7ajHSI3ym3Dxovn9 w8md63xKNlTpCB8NJPRIJpcGrE7QFtNXPFCagTqO713ulwCoKayEwKGOU7VQagFc 0/JoHxE5usE5OuA6tyAJbpWK10kWKDzu6HjZfqF2yoa0q/REbsu65KsY7zc7HbpF qEAXX1xr9IC7GUM7gv75OR8CP2VJCW3+6VyhiD/37t3KpNwINMpRDO/eN/KiwoUI 1t+/DVwO6pH5UrGReWrmjs/gcxFMzkeelt+iCA32kzkWLtyWjeWBujVWnFvVtpkz R4pV2T2jvs6fWPU5MMBXZRd5AvLLqcu/g/Yr21WYHz07jCcGxlCUp9qpnGLt2el0 /YTY3LBZUQJ5sx3OSJV+oQVTtI5x0EkAiOrJ8Dx20wNAFqun9bhJb1WX0IXflmZc oC7SF5wjXq8pUQmX/wpGMbW7XYompypJGqlEsftJEytf4dfR6KJ2Vo1h3pHtpaex IaY6TqmdW44e0EgbFTM7RMNFtC7GrIY9NE+WKlrFtsHhUFrqt1NVBEcO3faU0ES6 UAguFRPM/HAdkVmY620+DUT/JkEMemWq2jgWExLGLC9gI8L1Xj2cdU8esstuMUoV GGG4u9a5W1rALwg+zPCQGoVxPKmd6fpeC3U+Rmg2639chy+h4c/cBXkzfUsxe2lg wvMDVbjDN1Fz0c29YJit =K23I -----END PGP SIGNATURE----- Merge tag 'iommu-updates-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu Pull IOMMU updates from Joerg Roedel: "Not much stuff this time. The only change to the IOMMU core code is the addition of a handle to the fault handling code. A few updates to the AMD IOMMU driver to work around new errata. The other patches are mostly fixes and enhancements to the existing ARM IOMMU drivers and documentation updates. A new IOMMU driver for the Exynos platform was also underway but got merged via the Samsung tree and is not part of this tree." * tag 'iommu-updates-v3.5' of git://git.kernel.org/pub/scm/linux/kernel/git/joro/iommu: Documentation: kernel-parameters.txt Add amd_iommu_dump iommu/core: pass a user-provided token to fault handlers iommu/tegra: gart: Fix register offset correctly iommu: OMAP: device detach on domain destroy iommu: tegra/gart: Add device tree support iommu: tegra/gart: use correct gart_device iommu/tegra: smmu: Print device name correctly iommu/amd: Add workaround for event log erratum iommu/amd: Check for the right TLP prefix bit dma-debug: release free_entries_lock before saving stack trace
This commit is contained in:
commit
2f83766d4b
@ -0,0 +1,14 @@
|
|||||||
|
NVIDIA Tegra 20 GART
|
||||||
|
|
||||||
|
Required properties:
|
||||||
|
- compatible: "nvidia,tegra20-gart"
|
||||||
|
- reg: Two pairs of cells specifying the physical address and size of
|
||||||
|
the memory controller registers and the GART aperture respectively.
|
||||||
|
|
||||||
|
Example:
|
||||||
|
|
||||||
|
gart {
|
||||||
|
compatible = "nvidia,tegra20-gart";
|
||||||
|
reg = <0x7000f024 0x00000018 /* controller registers */
|
||||||
|
0x58000000 0x02000000>; /* GART aperture */
|
||||||
|
};
|
@ -335,6 +335,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
|
|||||||
requirements as needed. This option
|
requirements as needed. This option
|
||||||
does not override iommu=pt
|
does not override iommu=pt
|
||||||
|
|
||||||
|
amd_iommu_dump= [HW,X86-64]
|
||||||
|
Enable AMD IOMMU driver option to dump the ACPI table
|
||||||
|
for AMD IOMMU. With this option enabled, AMD IOMMU
|
||||||
|
driver will print ACPI tables for AMD IOMMU during
|
||||||
|
IOMMU initialization.
|
||||||
|
|
||||||
amijoy.map= [HW,JOY] Amiga joystick support
|
amijoy.map= [HW,JOY] Amiga joystick support
|
||||||
Map of devices attached to JOY0DAT and JOY1DAT
|
Map of devices attached to JOY0DAT and JOY1DAT
|
||||||
Format: <a>,<b>
|
Format: <a>,<b>
|
||||||
|
@ -450,12 +450,27 @@ static void dump_command(unsigned long phys_addr)
|
|||||||
|
|
||||||
static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
|
static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
|
||||||
{
|
{
|
||||||
u32 *event = __evt;
|
int type, devid, domid, flags;
|
||||||
int type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK;
|
volatile u32 *event = __evt;
|
||||||
int devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
|
int count = 0;
|
||||||
int domid = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
|
u64 address;
|
||||||
int flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
|
|
||||||
u64 address = (u64)(((u64)event[3]) << 32) | event[2];
|
retry:
|
||||||
|
type = (event[1] >> EVENT_TYPE_SHIFT) & EVENT_TYPE_MASK;
|
||||||
|
devid = (event[0] >> EVENT_DEVID_SHIFT) & EVENT_DEVID_MASK;
|
||||||
|
domid = (event[1] >> EVENT_DOMID_SHIFT) & EVENT_DOMID_MASK;
|
||||||
|
flags = (event[1] >> EVENT_FLAGS_SHIFT) & EVENT_FLAGS_MASK;
|
||||||
|
address = (u64)(((u64)event[3]) << 32) | event[2];
|
||||||
|
|
||||||
|
if (type == 0) {
|
||||||
|
/* Did we hit the erratum? */
|
||||||
|
if (++count == LOOP_TIMEOUT) {
|
||||||
|
pr_err("AMD-Vi: No event written to event log\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
udelay(1);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
|
|
||||||
printk(KERN_ERR "AMD-Vi: Event logged [");
|
printk(KERN_ERR "AMD-Vi: Event logged [");
|
||||||
|
|
||||||
@ -508,6 +523,8 @@ static void iommu_print_event(struct amd_iommu *iommu, void *__evt)
|
|||||||
default:
|
default:
|
||||||
printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
|
printk(KERN_ERR "UNKNOWN type=0x%02x]\n", type);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
memset(__evt, 0, 4 * sizeof(u32));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void iommu_poll_events(struct amd_iommu *iommu)
|
static void iommu_poll_events(struct amd_iommu *iommu)
|
||||||
@ -2035,20 +2052,20 @@ out_err:
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: Move this to PCI code */
|
/* FIXME: Move this to PCI code */
|
||||||
#define PCI_PRI_TLP_OFF (1 << 2)
|
#define PCI_PRI_TLP_OFF (1 << 15)
|
||||||
|
|
||||||
bool pci_pri_tlp_required(struct pci_dev *pdev)
|
bool pci_pri_tlp_required(struct pci_dev *pdev)
|
||||||
{
|
{
|
||||||
u16 control;
|
u16 status;
|
||||||
int pos;
|
int pos;
|
||||||
|
|
||||||
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
|
pos = pci_find_ext_capability(pdev, PCI_EXT_CAP_ID_PRI);
|
||||||
if (!pos)
|
if (!pos)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
pci_read_config_word(pdev, pos + PCI_PRI_CTRL, &control);
|
pci_read_config_word(pdev, pos + PCI_PRI_STATUS, &status);
|
||||||
|
|
||||||
return (control & PCI_PRI_TLP_OFF) ? true : false;
|
return (status & PCI_PRI_TLP_OFF) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -119,6 +119,7 @@ EXPORT_SYMBOL_GPL(iommu_present);
|
|||||||
* iommu_set_fault_handler() - set a fault handler for an iommu domain
|
* iommu_set_fault_handler() - set a fault handler for an iommu domain
|
||||||
* @domain: iommu domain
|
* @domain: iommu domain
|
||||||
* @handler: fault handler
|
* @handler: fault handler
|
||||||
|
* @token: user data, will be passed back to the fault handler
|
||||||
*
|
*
|
||||||
* This function should be used by IOMMU users which want to be notified
|
* This function should be used by IOMMU users which want to be notified
|
||||||
* whenever an IOMMU fault happens.
|
* whenever an IOMMU fault happens.
|
||||||
@ -127,11 +128,13 @@ EXPORT_SYMBOL_GPL(iommu_present);
|
|||||||
* error code otherwise.
|
* error code otherwise.
|
||||||
*/
|
*/
|
||||||
void iommu_set_fault_handler(struct iommu_domain *domain,
|
void iommu_set_fault_handler(struct iommu_domain *domain,
|
||||||
iommu_fault_handler_t handler)
|
iommu_fault_handler_t handler,
|
||||||
|
void *token)
|
||||||
{
|
{
|
||||||
BUG_ON(!domain);
|
BUG_ON(!domain);
|
||||||
|
|
||||||
domain->handler = handler;
|
domain->handler = handler;
|
||||||
|
domain->handler_token = token;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
|
EXPORT_SYMBOL_GPL(iommu_set_fault_handler);
|
||||||
|
|
||||||
|
@ -41,11 +41,13 @@
|
|||||||
* @pgtable: the page table
|
* @pgtable: the page table
|
||||||
* @iommu_dev: an omap iommu device attached to this domain. only a single
|
* @iommu_dev: an omap iommu device attached to this domain. only a single
|
||||||
* iommu device can be attached for now.
|
* iommu device can be attached for now.
|
||||||
|
* @dev: Device using this domain.
|
||||||
* @lock: domain lock, should be taken when attaching/detaching
|
* @lock: domain lock, should be taken when attaching/detaching
|
||||||
*/
|
*/
|
||||||
struct omap_iommu_domain {
|
struct omap_iommu_domain {
|
||||||
u32 *pgtable;
|
u32 *pgtable;
|
||||||
struct omap_iommu *iommu_dev;
|
struct omap_iommu *iommu_dev;
|
||||||
|
struct device *dev;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1081,6 +1083,7 @@ omap_iommu_attach_dev(struct iommu_domain *domain, struct device *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
omap_domain->iommu_dev = arch_data->iommu_dev = oiommu;
|
omap_domain->iommu_dev = arch_data->iommu_dev = oiommu;
|
||||||
|
omap_domain->dev = dev;
|
||||||
oiommu->domain = domain;
|
oiommu->domain = domain;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
@ -1088,19 +1091,16 @@ out:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void omap_iommu_detach_dev(struct iommu_domain *domain,
|
static void _omap_iommu_detach_dev(struct omap_iommu_domain *omap_domain,
|
||||||
struct device *dev)
|
struct device *dev)
|
||||||
{
|
{
|
||||||
struct omap_iommu_domain *omap_domain = domain->priv;
|
|
||||||
struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
|
|
||||||
struct omap_iommu *oiommu = dev_to_omap_iommu(dev);
|
struct omap_iommu *oiommu = dev_to_omap_iommu(dev);
|
||||||
|
struct omap_iommu_arch_data *arch_data = dev->archdata.iommu;
|
||||||
spin_lock(&omap_domain->lock);
|
|
||||||
|
|
||||||
/* only a single device is supported per domain for now */
|
/* only a single device is supported per domain for now */
|
||||||
if (omap_domain->iommu_dev != oiommu) {
|
if (omap_domain->iommu_dev != oiommu) {
|
||||||
dev_err(dev, "invalid iommu device\n");
|
dev_err(dev, "invalid iommu device\n");
|
||||||
goto out;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
iopgtable_clear_entry_all(oiommu);
|
iopgtable_clear_entry_all(oiommu);
|
||||||
@ -1108,8 +1108,16 @@ static void omap_iommu_detach_dev(struct iommu_domain *domain,
|
|||||||
omap_iommu_detach(oiommu);
|
omap_iommu_detach(oiommu);
|
||||||
|
|
||||||
omap_domain->iommu_dev = arch_data->iommu_dev = NULL;
|
omap_domain->iommu_dev = arch_data->iommu_dev = NULL;
|
||||||
|
omap_domain->dev = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
out:
|
static void omap_iommu_detach_dev(struct iommu_domain *domain,
|
||||||
|
struct device *dev)
|
||||||
|
{
|
||||||
|
struct omap_iommu_domain *omap_domain = domain->priv;
|
||||||
|
|
||||||
|
spin_lock(&omap_domain->lock);
|
||||||
|
_omap_iommu_detach_dev(omap_domain, dev);
|
||||||
spin_unlock(&omap_domain->lock);
|
spin_unlock(&omap_domain->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1148,13 +1156,19 @@ out:
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* assume device was already detached */
|
|
||||||
static void omap_iommu_domain_destroy(struct iommu_domain *domain)
|
static void omap_iommu_domain_destroy(struct iommu_domain *domain)
|
||||||
{
|
{
|
||||||
struct omap_iommu_domain *omap_domain = domain->priv;
|
struct omap_iommu_domain *omap_domain = domain->priv;
|
||||||
|
|
||||||
domain->priv = NULL;
|
domain->priv = NULL;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* An iommu device is still attached
|
||||||
|
* (currently, only one device can be attached) ?
|
||||||
|
*/
|
||||||
|
if (omap_domain->iommu_dev)
|
||||||
|
_omap_iommu_detach_dev(omap_domain, omap_domain->dev);
|
||||||
|
|
||||||
kfree(omap_domain->pgtable);
|
kfree(omap_domain->pgtable);
|
||||||
kfree(omap_domain);
|
kfree(omap_domain);
|
||||||
}
|
}
|
||||||
|
@ -29,15 +29,17 @@
|
|||||||
#include <linux/device.h>
|
#include <linux/device.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/iommu.h>
|
#include <linux/iommu.h>
|
||||||
|
#include <linux/of.h>
|
||||||
|
|
||||||
#include <asm/cacheflush.h>
|
#include <asm/cacheflush.h>
|
||||||
|
|
||||||
/* bitmap of the page sizes currently supported */
|
/* bitmap of the page sizes currently supported */
|
||||||
#define GART_IOMMU_PGSIZES (SZ_4K)
|
#define GART_IOMMU_PGSIZES (SZ_4K)
|
||||||
|
|
||||||
#define GART_CONFIG 0x24
|
#define GART_REG_BASE 0x24
|
||||||
#define GART_ENTRY_ADDR 0x28
|
#define GART_CONFIG (0x24 - GART_REG_BASE)
|
||||||
#define GART_ENTRY_DATA 0x2c
|
#define GART_ENTRY_ADDR (0x28 - GART_REG_BASE)
|
||||||
|
#define GART_ENTRY_DATA (0x2c - GART_REG_BASE)
|
||||||
#define GART_ENTRY_PHYS_ADDR_VALID (1 << 31)
|
#define GART_ENTRY_PHYS_ADDR_VALID (1 << 31)
|
||||||
|
|
||||||
#define GART_PAGE_SHIFT 12
|
#define GART_PAGE_SHIFT 12
|
||||||
@ -158,7 +160,7 @@ static int gart_iommu_attach_dev(struct iommu_domain *domain,
|
|||||||
struct gart_client *client, *c;
|
struct gart_client *client, *c;
|
||||||
int err = 0;
|
int err = 0;
|
||||||
|
|
||||||
gart = dev_get_drvdata(dev->parent);
|
gart = gart_handle;
|
||||||
if (!gart)
|
if (!gart)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
domain->priv = gart;
|
domain->priv = gart;
|
||||||
@ -422,6 +424,14 @@ const struct dev_pm_ops tegra_gart_pm_ops = {
|
|||||||
.resume = tegra_gart_resume,
|
.resume = tegra_gart_resume,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_OF
|
||||||
|
static struct of_device_id tegra_gart_of_match[] __devinitdata = {
|
||||||
|
{ .compatible = "nvidia,tegra20-gart", },
|
||||||
|
{ },
|
||||||
|
};
|
||||||
|
MODULE_DEVICE_TABLE(of, tegra_gart_of_match);
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct platform_driver tegra_gart_driver = {
|
static struct platform_driver tegra_gart_driver = {
|
||||||
.probe = tegra_gart_probe,
|
.probe = tegra_gart_probe,
|
||||||
.remove = tegra_gart_remove,
|
.remove = tegra_gart_remove,
|
||||||
@ -429,6 +439,7 @@ static struct platform_driver tegra_gart_driver = {
|
|||||||
.owner = THIS_MODULE,
|
.owner = THIS_MODULE,
|
||||||
.name = "tegra-gart",
|
.name = "tegra-gart",
|
||||||
.pm = &tegra_gart_pm_ops,
|
.pm = &tegra_gart_pm_ops,
|
||||||
|
.of_match_table = of_match_ptr(tegra_gart_of_match),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -448,4 +459,5 @@ module_exit(tegra_gart_exit);
|
|||||||
|
|
||||||
MODULE_DESCRIPTION("IOMMU API for GART in Tegra20");
|
MODULE_DESCRIPTION("IOMMU API for GART in Tegra20");
|
||||||
MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
|
MODULE_AUTHOR("Hiroshi DOYU <hdoyu@nvidia.com>");
|
||||||
|
MODULE_ALIAS("platform:tegra-gart");
|
||||||
MODULE_LICENSE("GPL v2");
|
MODULE_LICENSE("GPL v2");
|
||||||
|
@ -733,7 +733,7 @@ static int smmu_iommu_attach_dev(struct iommu_domain *domain,
|
|||||||
pr_info("Reserve \"page zero\" for AVP vectors using a common dummy\n");
|
pr_info("Reserve \"page zero\" for AVP vectors using a common dummy\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
dev_dbg(smmu->dev, "%s is attached\n", dev_name(c->dev));
|
dev_dbg(smmu->dev, "%s is attached\n", dev_name(dev));
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_client:
|
err_client:
|
||||||
|
@ -78,7 +78,7 @@ typedef int (*rproc_handle_resource_t)(struct rproc *rproc, void *, int avail);
|
|||||||
* the recovery of the remote processor.
|
* the recovery of the remote processor.
|
||||||
*/
|
*/
|
||||||
static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev,
|
static int rproc_iommu_fault(struct iommu_domain *domain, struct device *dev,
|
||||||
unsigned long iova, int flags)
|
unsigned long iova, int flags, void *token)
|
||||||
{
|
{
|
||||||
dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags);
|
dev_err(dev, "iommu fault: da 0x%lx flags 0x%x\n", iova, flags);
|
||||||
|
|
||||||
@ -117,7 +117,7 @@ static int rproc_enable_iommu(struct rproc *rproc)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
|
||||||
iommu_set_fault_handler(domain, rproc_iommu_fault);
|
iommu_set_fault_handler(domain, rproc_iommu_fault, rproc);
|
||||||
|
|
||||||
ret = iommu_attach_device(domain, dev);
|
ret = iommu_attach_device(domain, dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -35,12 +35,13 @@ struct iommu_domain;
|
|||||||
#define IOMMU_FAULT_WRITE 0x1
|
#define IOMMU_FAULT_WRITE 0x1
|
||||||
|
|
||||||
typedef int (*iommu_fault_handler_t)(struct iommu_domain *,
|
typedef int (*iommu_fault_handler_t)(struct iommu_domain *,
|
||||||
struct device *, unsigned long, int);
|
struct device *, unsigned long, int, void *);
|
||||||
|
|
||||||
struct iommu_domain {
|
struct iommu_domain {
|
||||||
struct iommu_ops *ops;
|
struct iommu_ops *ops;
|
||||||
void *priv;
|
void *priv;
|
||||||
iommu_fault_handler_t handler;
|
iommu_fault_handler_t handler;
|
||||||
|
void *handler_token;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define IOMMU_CAP_CACHE_COHERENCY 0x1
|
#define IOMMU_CAP_CACHE_COHERENCY 0x1
|
||||||
@ -95,7 +96,7 @@ extern phys_addr_t iommu_iova_to_phys(struct iommu_domain *domain,
|
|||||||
extern int iommu_domain_has_cap(struct iommu_domain *domain,
|
extern int iommu_domain_has_cap(struct iommu_domain *domain,
|
||||||
unsigned long cap);
|
unsigned long cap);
|
||||||
extern void iommu_set_fault_handler(struct iommu_domain *domain,
|
extern void iommu_set_fault_handler(struct iommu_domain *domain,
|
||||||
iommu_fault_handler_t handler);
|
iommu_fault_handler_t handler, void *token);
|
||||||
extern int iommu_device_group(struct device *dev, unsigned int *groupid);
|
extern int iommu_device_group(struct device *dev, unsigned int *groupid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -132,7 +133,8 @@ static inline int report_iommu_fault(struct iommu_domain *domain,
|
|||||||
* invoke it.
|
* invoke it.
|
||||||
*/
|
*/
|
||||||
if (domain->handler)
|
if (domain->handler)
|
||||||
ret = domain->handler(domain, dev, iova, flags);
|
ret = domain->handler(domain, dev, iova, flags,
|
||||||
|
domain->handler_token);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -191,7 +193,7 @@ static inline int domain_has_cap(struct iommu_domain *domain,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void iommu_set_fault_handler(struct iommu_domain *domain,
|
static inline void iommu_set_fault_handler(struct iommu_domain *domain,
|
||||||
iommu_fault_handler_t handler)
|
iommu_fault_handler_t handler, void *token)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -430,7 +430,7 @@ static struct dma_debug_entry *__dma_entry_alloc(void)
|
|||||||
*/
|
*/
|
||||||
static struct dma_debug_entry *dma_entry_alloc(void)
|
static struct dma_debug_entry *dma_entry_alloc(void)
|
||||||
{
|
{
|
||||||
struct dma_debug_entry *entry = NULL;
|
struct dma_debug_entry *entry;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
spin_lock_irqsave(&free_entries_lock, flags);
|
spin_lock_irqsave(&free_entries_lock, flags);
|
||||||
@ -438,11 +438,14 @@ static struct dma_debug_entry *dma_entry_alloc(void)
|
|||||||
if (list_empty(&free_entries)) {
|
if (list_empty(&free_entries)) {
|
||||||
pr_err("DMA-API: debugging out of memory - disabling\n");
|
pr_err("DMA-API: debugging out of memory - disabling\n");
|
||||||
global_disable = true;
|
global_disable = true;
|
||||||
goto out;
|
spin_unlock_irqrestore(&free_entries_lock, flags);
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = __dma_entry_alloc();
|
entry = __dma_entry_alloc();
|
||||||
|
|
||||||
|
spin_unlock_irqrestore(&free_entries_lock, flags);
|
||||||
|
|
||||||
#ifdef CONFIG_STACKTRACE
|
#ifdef CONFIG_STACKTRACE
|
||||||
entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES;
|
entry->stacktrace.max_entries = DMA_DEBUG_STACKTRACE_ENTRIES;
|
||||||
entry->stacktrace.entries = entry->st_entries;
|
entry->stacktrace.entries = entry->st_entries;
|
||||||
@ -450,9 +453,6 @@ static struct dma_debug_entry *dma_entry_alloc(void)
|
|||||||
save_stack_trace(&entry->stacktrace);
|
save_stack_trace(&entry->stacktrace);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
out:
|
|
||||||
spin_unlock_irqrestore(&free_entries_lock, flags);
|
|
||||||
|
|
||||||
return entry;
|
return entry;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user