Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 313677
b: refs/heads/master
c: d6b9a81
h: refs/heads/master
i:
  313675: 2f7c743
v: v3
  • Loading branch information
Anton Blanchard authored and Benjamin Herrenschmidt committed Jul 10, 2012
1 parent e386a76 commit 4754564
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: a980349725346ce7e3c1774e327c2f1fdca4593d
refs/heads/master: d6b9a81b2a45786384f5bd3516bd6ddfb4b772c6
9 changes: 9 additions & 0 deletions trunk/arch/powerpc/Kconfig.debug
Original file line number Diff line number Diff line change
Expand Up @@ -331,4 +331,13 @@ config STRICT_DEVMEM

If you are unsure, say Y.

config FAIL_IOMMU
bool "Fault-injection capability for IOMMU"
depends on FAULT_INJECTION
help
Provide fault-injection capability for IOMMU. Each device can
be selectively enabled via the fail_iommu property.

If you are unsure, say N.

endmenu
3 changes: 3 additions & 0 deletions trunk/arch/powerpc/include/asm/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ struct dev_archdata {
#ifdef CONFIG_EEH
struct eeh_dev *edev;
#endif
#ifdef CONFIG_FAIL_IOMMU
int fail_iommu;
#endif
};

struct pdev_archdata {
Expand Down
94 changes: 94 additions & 0 deletions trunk/arch/powerpc/kernel/iommu.c
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,16 @@
#include <linux/iommu-helper.h>
#include <linux/crash_dump.h>
#include <linux/hash.h>
#include <linux/fault-inject.h>
#include <linux/pci.h>
#include <asm/io.h>
#include <asm/prom.h>
#include <asm/iommu.h>
#include <asm/pci-bridge.h>
#include <asm/machdep.h>
#include <asm/kdump.h>
#include <asm/fadump.h>
#include <asm/vio.h>

#define DBG(...)

Expand Down Expand Up @@ -79,6 +82,94 @@ static int __init setup_iommu_pool_hash(void)
}
subsys_initcall(setup_iommu_pool_hash);

#ifdef CONFIG_FAIL_IOMMU

static DECLARE_FAULT_ATTR(fail_iommu);

static int __init setup_fail_iommu(char *str)
{
return setup_fault_attr(&fail_iommu, str);
}
__setup("fail_iommu=", setup_fail_iommu);

static bool should_fail_iommu(struct device *dev)
{
return dev->archdata.fail_iommu && should_fail(&fail_iommu, 1);
}

static int __init fail_iommu_debugfs(void)
{
struct dentry *dir = fault_create_debugfs_attr("fail_iommu",
NULL, &fail_iommu);

return IS_ERR(dir) ? PTR_ERR(dir) : 0;
}
late_initcall(fail_iommu_debugfs);

static ssize_t fail_iommu_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
return sprintf(buf, "%d\n", dev->archdata.fail_iommu);
}

static ssize_t fail_iommu_store(struct device *dev,
struct device_attribute *attr, const char *buf,
size_t count)
{
int i;

if (count > 0 && sscanf(buf, "%d", &i) > 0)
dev->archdata.fail_iommu = (i == 0) ? 0 : 1;

return count;
}

static DEVICE_ATTR(fail_iommu, S_IRUGO|S_IWUSR, fail_iommu_show,
fail_iommu_store);

static int fail_iommu_bus_notify(struct notifier_block *nb,
unsigned long action, void *data)
{
struct device *dev = data;

if (action == BUS_NOTIFY_ADD_DEVICE) {
if (device_create_file(dev, &dev_attr_fail_iommu))
pr_warn("Unable to create IOMMU fault injection sysfs "
"entries\n");
} else if (action == BUS_NOTIFY_DEL_DEVICE) {
device_remove_file(dev, &dev_attr_fail_iommu);
}

return 0;
}

static struct notifier_block fail_iommu_bus_notifier = {
.notifier_call = fail_iommu_bus_notify
};

static int __init fail_iommu_setup(void)
{
#ifdef CONFIG_PCI
bus_register_notifier(&pci_bus_type, &fail_iommu_bus_notifier);
#endif
#ifdef CONFIG_IBMVIO
bus_register_notifier(&vio_bus_type, &fail_iommu_bus_notifier);
#endif

return 0;
}
/*
* Must execute after PCI and VIO subsystem have initialised but before
* devices are probed.
*/
arch_initcall(fail_iommu_setup);
#else
static inline bool should_fail_iommu(struct device *dev)
{
return false;
}
#endif

static unsigned long iommu_range_alloc(struct device *dev,
struct iommu_table *tbl,
unsigned long npages,
Expand Down Expand Up @@ -107,6 +198,9 @@ static unsigned long iommu_range_alloc(struct device *dev,
return DMA_ERROR_CODE;
}

if (should_fail_iommu(dev))
return DMA_ERROR_CODE;

/*
* We don't need to disable preemption here because any CPU can
* safely use any IOMMU pool.
Expand Down

0 comments on commit 4754564

Please sign in to comment.