LKML Archive on lore.kernel.org
help / color / mirror / Atom feed
* [PATCH 0/9] suspend/resume support for amd iommu
@ 2009-05-22 12:15 Joerg Roedel
2009-05-22 12:15 ` [PATCH 1/9] amd-iommu: introduce for_each_iommu* macros Joerg Roedel
` (8 more replies)
0 siblings, 9 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel
This patchset implements support for suspend/resume in the AMD IOMMU
driver for Linux. Please review.
diffstat:
arch/x86/include/asm/amd_iommu.h | 2 +
arch/x86/include/asm/amd_iommu_types.h | 8 ++
arch/x86/kernel/amd_iommu.c | 37 +++++++-
arch/x86/kernel/amd_iommu_init.c | 144 ++++++++++++++++----------------
4 files changed, 114 insertions(+), 77 deletions(-)
shortlog:
Joerg Roedel (9):
amd-iommu: introduce for_each_iommu* macros
amd-iommu: consolidate hardware initialization to one function
amd-iommu: drop pointless iommu-loop in msi setup code
amd-iommu: remove support for msi-x
amd-iommu: add function to disable all iommus
amd-iommu: add function to flush tlb for all domains
amd-iommu: add function to flush tlb for all devices
amd_iommu: un __init functions required for suspend/resume
amd-iommu: implement suspend/resume
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 1/9] amd-iommu: introduce for_each_iommu* macros
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
@ 2009-05-22 12:15 ` Joerg Roedel
2009-05-22 12:15 ` [PATCH 2/9] amd-iommu: consolidate hardware initialization to one function Joerg Roedel
` (7 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel; +Cc: Joerg Roedel
Impact: simplify iterating over all iommus in the system
This patch introduces the for_each_iommu and for_each_iommu_safe macros
to simplify the developers life when having to iterate over all AMD
IOMMUs in the system.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/include/asm/amd_iommu_types.h | 8 ++++++++
arch/x86/kernel/amd_iommu.c | 8 ++++----
arch/x86/kernel/amd_iommu_init.c | 8 ++++----
3 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/arch/x86/include/asm/amd_iommu_types.h b/arch/x86/include/asm/amd_iommu_types.h
index 95c8cd9..cf5ef17 100644
--- a/arch/x86/include/asm/amd_iommu_types.h
+++ b/arch/x86/include/asm/amd_iommu_types.h
@@ -196,6 +196,14 @@
domain for an IOMMU */
/*
+ * Make iterating over all IOMMUs easier
+ */
+#define for_each_iommu(iommu) \
+ list_for_each_entry((iommu), &amd_iommu_list, list)
+#define for_each_iommu_safe(iommu, next) \
+ list_for_each_entry_safe((iommu), (next), &amd_iommu_list, list)
+
+/*
* This structure contains generic data for IOMMU protection domains
* independent of their use.
*/
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index a97db99..d9e9dc1 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -213,7 +213,7 @@ irqreturn_t amd_iommu_int_handler(int irq, void *data)
{
struct amd_iommu *iommu;
- list_for_each_entry(iommu, &amd_iommu_list, list)
+ for_each_iommu(iommu)
iommu_poll_events(iommu);
return IRQ_HANDLED;
@@ -440,7 +440,7 @@ static void iommu_flush_domain(u16 domid)
__iommu_build_inv_iommu_pages(&cmd, CMD_INV_IOMMU_ALL_PAGES_ADDRESS,
domid, 1, 1);
- list_for_each_entry(iommu, &amd_iommu_list, list) {
+ for_each_iommu(iommu) {
spin_lock_irqsave(&iommu->lock, flags);
__iommu_queue_command(iommu, &cmd);
__iommu_completion_wait(iommu);
@@ -1672,7 +1672,7 @@ int __init amd_iommu_init_dma_ops(void)
* found in the system. Devices not assigned to any other
* protection domain will be assigned to the default one.
*/
- list_for_each_entry(iommu, &amd_iommu_list, list) {
+ for_each_iommu(iommu) {
iommu->default_dom = dma_ops_domain_alloc(iommu, order);
if (iommu->default_dom == NULL)
return -ENOMEM;
@@ -1710,7 +1710,7 @@ int __init amd_iommu_init_dma_ops(void)
free_domains:
- list_for_each_entry(iommu, &amd_iommu_list, list) {
+ for_each_iommu(iommu) {
if (iommu->default_dom)
dma_ops_domain_free(iommu->default_dom);
}
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 8c0be09..675a4b6 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -679,7 +679,7 @@ static void __init free_iommu_all(void)
{
struct amd_iommu *iommu, *next;
- list_for_each_entry_safe(iommu, next, &amd_iommu_list, list) {
+ for_each_iommu_safe(iommu, next) {
list_del(&iommu->list);
free_iommu_one(iommu);
kfree(iommu);
@@ -779,7 +779,7 @@ static int __init iommu_setup_msix(struct amd_iommu *iommu)
struct msix_entry entries[32]; /* only 32 supported by AMD IOMMU */
int nvec = 0, i;
- list_for_each_entry(curr, &amd_iommu_list, list) {
+ for_each_iommu(curr) {
if (curr->dev == iommu->dev) {
entries[nvec].entry = curr->evt_msi_num;
entries[nvec].vector = 0;
@@ -818,7 +818,7 @@ static int __init iommu_setup_msi(struct amd_iommu *iommu)
int r;
struct amd_iommu *curr;
- list_for_each_entry(curr, &amd_iommu_list, list) {
+ for_each_iommu(curr) {
if (curr->dev == iommu->dev)
curr->int_enabled = true;
}
@@ -971,7 +971,7 @@ static void __init enable_iommus(void)
{
struct amd_iommu *iommu;
- list_for_each_entry(iommu, &amd_iommu_list, list) {
+ for_each_iommu(iommu) {
iommu_set_exclusion_range(iommu);
iommu_init_msi(iommu);
iommu_enable_event_logging(iommu);
--
1.6.3.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 2/9] amd-iommu: consolidate hardware initialization to one function
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
2009-05-22 12:15 ` [PATCH 1/9] amd-iommu: introduce for_each_iommu* macros Joerg Roedel
@ 2009-05-22 12:15 ` Joerg Roedel
2009-05-22 12:15 ` [PATCH 3/9] amd-iommu: drop pointless iommu-loop in msi setup code Joerg Roedel
` (6 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel; +Cc: Joerg Roedel
Impact: cleanup and consolidate hardware initialization
This patch restructures the AMD IOMMU initialization code to initialize
all hardware registers with one single function call.
This is helpful for suspend/resume support.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kernel/amd_iommu_init.c | 50 ++++++++++++++++++++++++-------------
1 files changed, 32 insertions(+), 18 deletions(-)
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 675a4b6..74f4f1f 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -252,13 +252,6 @@ static void __init iommu_enable(struct amd_iommu *iommu)
iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
}
-/* Function to enable IOMMU event logging and event interrupts */
-static void __init iommu_enable_event_logging(struct amd_iommu *iommu)
-{
- iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN);
- iommu_feature_enable(iommu, CONTROL_EVT_INT_EN);
-}
-
/*
* mapping and unmapping functions for the IOMMU MMIO space. Each AMD IOMMU in
* the system has one.
@@ -413,25 +406,36 @@ static u8 * __init alloc_command_buffer(struct amd_iommu *iommu)
{
u8 *cmd_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
get_order(CMD_BUFFER_SIZE));
- u64 entry;
if (cmd_buf == NULL)
return NULL;
iommu->cmd_buf_size = CMD_BUFFER_SIZE;
- entry = (u64)virt_to_phys(cmd_buf);
+ return cmd_buf;
+}
+
+/*
+ * This function writes the command buffer address to the hardware and
+ * enables it.
+ */
+static void iommu_enable_command_buffer(struct amd_iommu *iommu)
+{
+ u64 entry;
+
+ BUG_ON(iommu->cmd_buf == NULL);
+
+ entry = (u64)virt_to_phys(iommu->cmd_buf);
entry |= MMIO_CMD_SIZE_512;
+
memcpy_toio(iommu->mmio_base + MMIO_CMD_BUF_OFFSET,
- &entry, sizeof(entry));
+ &entry, sizeof(entry));
/* set head and tail to zero manually */
writel(0x00, iommu->mmio_base + MMIO_CMD_HEAD_OFFSET);
writel(0x00, iommu->mmio_base + MMIO_CMD_TAIL_OFFSET);
iommu_feature_enable(iommu, CONTROL_CMDBUF_EN);
-
- return cmd_buf;
}
static void __init free_command_buffer(struct amd_iommu *iommu)
@@ -443,20 +447,27 @@ static void __init free_command_buffer(struct amd_iommu *iommu)
/* allocates the memory where the IOMMU will log its events to */
static u8 * __init alloc_event_buffer(struct amd_iommu *iommu)
{
- u64 entry;
iommu->evt_buf = (u8 *)__get_free_pages(GFP_KERNEL | __GFP_ZERO,
get_order(EVT_BUFFER_SIZE));
if (iommu->evt_buf == NULL)
return NULL;
+ return iommu->evt_buf;
+}
+
+static void iommu_enable_event_buffer(struct amd_iommu *iommu)
+{
+ u64 entry;
+
+ BUG_ON(iommu->evt_buf == NULL);
+
entry = (u64)virt_to_phys(iommu->evt_buf) | EVT_LEN_MASK;
+
memcpy_toio(iommu->mmio_base + MMIO_EVT_BUF_OFFSET,
&entry, sizeof(entry));
- iommu->evt_buf_size = EVT_BUFFER_SIZE;
-
- return iommu->evt_buf;
+ iommu_feature_enable(iommu, CONTROL_EVT_LOG_EN);
}
static void __init free_event_buffer(struct amd_iommu *iommu)
@@ -710,7 +721,6 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h)
if (!iommu->mmio_base)
return -ENOMEM;
- iommu_set_device_table(iommu);
iommu->cmd_buf = alloc_command_buffer(iommu);
if (!iommu->cmd_buf)
return -ENOMEM;
@@ -837,6 +847,8 @@ static int __init iommu_setup_msi(struct amd_iommu *iommu)
return 1;
}
+ iommu_feature_enable(iommu, CONTROL_EVT_INT_EN);
+
return 0;
}
@@ -972,9 +984,11 @@ static void __init enable_iommus(void)
struct amd_iommu *iommu;
for_each_iommu(iommu) {
+ iommu_set_device_table(iommu);
+ iommu_enable_command_buffer(iommu);
+ iommu_enable_event_buffer(iommu);
iommu_set_exclusion_range(iommu);
iommu_init_msi(iommu);
- iommu_enable_event_logging(iommu);
iommu_enable(iommu);
}
}
--
1.6.3.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 3/9] amd-iommu: drop pointless iommu-loop in msi setup code
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
2009-05-22 12:15 ` [PATCH 1/9] amd-iommu: introduce for_each_iommu* macros Joerg Roedel
2009-05-22 12:15 ` [PATCH 2/9] amd-iommu: consolidate hardware initialization to one function Joerg Roedel
@ 2009-05-22 12:15 ` Joerg Roedel
2009-05-22 12:15 ` [PATCH 4/9] amd-iommu: remove support for msi-x Joerg Roedel
` (5 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel; +Cc: Joerg Roedel
Impact: cleanup
It is not necessary to loop again over all IOMMUs in this code. So drop
the loop.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kernel/amd_iommu_init.c | 8 +-------
1 files changed, 1 insertions(+), 7 deletions(-)
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 74f4f1f..cc99f60 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -826,13 +826,6 @@ out_free:
static int __init iommu_setup_msi(struct amd_iommu *iommu)
{
int r;
- struct amd_iommu *curr;
-
- for_each_iommu(curr) {
- if (curr->dev == iommu->dev)
- curr->int_enabled = true;
- }
-
if (pci_enable_msi(iommu->dev))
return 1;
@@ -847,6 +840,7 @@ static int __init iommu_setup_msi(struct amd_iommu *iommu)
return 1;
}
+ iommu->int_enabled = true;
iommu_feature_enable(iommu, CONTROL_EVT_INT_EN);
return 0;
--
1.6.3.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 4/9] amd-iommu: remove support for msi-x
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
` (2 preceding siblings ...)
2009-05-22 12:15 ` [PATCH 3/9] amd-iommu: drop pointless iommu-loop in msi setup code Joerg Roedel
@ 2009-05-22 12:15 ` Joerg Roedel
2009-05-22 12:15 ` [PATCH 5/9] amd-iommu: add function to disable all iommus Joerg Roedel
` (4 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel; +Cc: Joerg Roedel
Impact: drop support for msi-x in amd iommu code
Current hardware uses msi instead of msi-x so this code it not necessary
and can not be tested. The best thing is to drop this code.
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kernel/amd_iommu_init.c | 44 +-------------------------------------
1 files changed, 1 insertions(+), 43 deletions(-)
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index cc99f60..feee475 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -783,46 +783,6 @@ static int __init init_iommu_all(struct acpi_table_header *table)
*
****************************************************************************/
-static int __init iommu_setup_msix(struct amd_iommu *iommu)
-{
- struct amd_iommu *curr;
- struct msix_entry entries[32]; /* only 32 supported by AMD IOMMU */
- int nvec = 0, i;
-
- for_each_iommu(curr) {
- if (curr->dev == iommu->dev) {
- entries[nvec].entry = curr->evt_msi_num;
- entries[nvec].vector = 0;
- curr->int_enabled = true;
- nvec++;
- }
- }
-
- if (pci_enable_msix(iommu->dev, entries, nvec)) {
- pci_disable_msix(iommu->dev);
- return 1;
- }
-
- for (i = 0; i < nvec; ++i) {
- int r = request_irq(entries->vector, amd_iommu_int_handler,
- IRQF_SAMPLE_RANDOM,
- "AMD IOMMU",
- NULL);
- if (r)
- goto out_free;
- }
-
- return 0;
-
-out_free:
- for (i -= 1; i >= 0; --i)
- free_irq(entries->vector, NULL);
-
- pci_disable_msix(iommu->dev);
-
- return 1;
-}
-
static int __init iommu_setup_msi(struct amd_iommu *iommu)
{
int r;
@@ -851,9 +811,7 @@ static int __init iommu_init_msi(struct amd_iommu *iommu)
if (iommu->int_enabled)
return 0;
- if (pci_find_capability(iommu->dev, PCI_CAP_ID_MSIX))
- return iommu_setup_msix(iommu);
- else if (pci_find_capability(iommu->dev, PCI_CAP_ID_MSI))
+ if (pci_find_capability(iommu->dev, PCI_CAP_ID_MSI))
return iommu_setup_msi(iommu);
return 1;
--
1.6.3.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 5/9] amd-iommu: add function to disable all iommus
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
` (3 preceding siblings ...)
2009-05-22 12:15 ` [PATCH 4/9] amd-iommu: remove support for msi-x Joerg Roedel
@ 2009-05-22 12:15 ` Joerg Roedel
2009-05-22 12:15 ` [PATCH 6/9] amd-iommu: add function to flush tlb for all domains Joerg Roedel
` (3 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel; +Cc: Joerg Roedel
[ impact: add disable_iommus function needed for suspend/resume ]
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kernel/amd_iommu_init.c | 13 +++++++++++++
1 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index feee475..ed10c0f 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -252,6 +252,11 @@ static void __init iommu_enable(struct amd_iommu *iommu)
iommu_feature_enable(iommu, CONTROL_IOMMU_EN);
}
+static void iommu_disable(struct amd_iommu *iommu)
+{
+ iommu_feature_disable(iommu, CONTROL_IOMMU_EN);
+}
+
/*
* mapping and unmapping functions for the IOMMU MMIO space. Each AMD IOMMU in
* the system has one.
@@ -945,6 +950,14 @@ static void __init enable_iommus(void)
}
}
+static void disable_iommus(void)
+{
+ struct amd_iommu *iommu;
+
+ for_each_iommu(iommu)
+ iommu_disable(iommu);
+}
+
/*
* Suspend/Resume support
* disable suspend until real resume implemented
--
1.6.3.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6/9] amd-iommu: add function to flush tlb for all domains
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
` (4 preceding siblings ...)
2009-05-22 12:15 ` [PATCH 5/9] amd-iommu: add function to disable all iommus Joerg Roedel
@ 2009-05-22 12:15 ` Joerg Roedel
2009-05-22 12:15 ` [PATCH 7/9] amd-iommu: add function to flush tlb for all devices Joerg Roedel
` (2 subsequent siblings)
8 siblings, 0 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel; +Cc: Joerg Roedel
[ impact: be able to flush io/tlb for all allocated domains ]
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/include/asm/amd_iommu.h | 1 +
arch/x86/kernel/amd_iommu.c | 11 +++++++++++
2 files changed, 12 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h
index f712344..1750e1f 100644
--- a/arch/x86/include/asm/amd_iommu.h
+++ b/arch/x86/include/asm/amd_iommu.h
@@ -27,6 +27,7 @@ extern int amd_iommu_init(void);
extern int amd_iommu_init_dma_ops(void);
extern void amd_iommu_detect(void);
extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
+extern void amd_iommu_flush_all_domains(void);
#else
static inline int amd_iommu_init(void) { return -ENODEV; }
static inline void amd_iommu_detect(void) { }
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index d9e9dc1..826ad07 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -449,6 +449,17 @@ static void iommu_flush_domain(u16 domid)
}
}
+void amd_iommu_flush_all_domains(void)
+{
+ int i;
+
+ for (i = 1; i < MAX_DOMAIN_ID; ++i) {
+ if (!test_bit(i, amd_iommu_pd_alloc_bitmap))
+ continue;
+ iommu_flush_domain(i);
+ }
+}
+
/****************************************************************************
*
* The functions below are used the create the page table mappings for
--
1.6.3.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 7/9] amd-iommu: add function to flush tlb for all devices
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
` (5 preceding siblings ...)
2009-05-22 12:15 ` [PATCH 6/9] amd-iommu: add function to flush tlb for all domains Joerg Roedel
@ 2009-05-22 12:15 ` Joerg Roedel
2009-05-22 12:15 ` [PATCH 8/9] amd_iommu: un __init functions required for suspend/resume Joerg Roedel
2009-05-22 12:15 ` [PATCH 9/9] amd-iommu: implement suspend/resume Joerg Roedel
8 siblings, 0 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel; +Cc: Joerg Roedel
[ impact: be able to flush cache for all devtable entries ]
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/include/asm/amd_iommu.h | 1 +
arch/x86/kernel/amd_iommu.c | 18 ++++++++++++++++++
2 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/amd_iommu.h b/arch/x86/include/asm/amd_iommu.h
index 1750e1f..262e028 100644
--- a/arch/x86/include/asm/amd_iommu.h
+++ b/arch/x86/include/asm/amd_iommu.h
@@ -28,6 +28,7 @@ extern int amd_iommu_init_dma_ops(void);
extern void amd_iommu_detect(void);
extern irqreturn_t amd_iommu_int_handler(int irq, void *data);
extern void amd_iommu_flush_all_domains(void);
+extern void amd_iommu_flush_all_devices(void);
#else
static inline int amd_iommu_init(void) { return -ENODEV; }
static inline void amd_iommu_detect(void) { }
diff --git a/arch/x86/kernel/amd_iommu.c b/arch/x86/kernel/amd_iommu.c
index 826ad07..92b0e18 100644
--- a/arch/x86/kernel/amd_iommu.c
+++ b/arch/x86/kernel/amd_iommu.c
@@ -460,6 +460,24 @@ void amd_iommu_flush_all_domains(void)
}
}
+void amd_iommu_flush_all_devices(void)
+{
+ struct amd_iommu *iommu;
+ int i;
+
+ for (i = 0; i <= amd_iommu_last_bdf; ++i) {
+ if (amd_iommu_pd_table[i] == NULL)
+ continue;
+
+ iommu = amd_iommu_rlookup_table[i];
+ if (!iommu)
+ continue;
+
+ iommu_queue_inv_dev_entry(iommu, i);
+ iommu_completion_wait(iommu);
+ }
+}
+
/****************************************************************************
*
* The functions below are used the create the page table mappings for
--
1.6.3.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 8/9] amd_iommu: un __init functions required for suspend/resume
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
` (6 preceding siblings ...)
2009-05-22 12:15 ` [PATCH 7/9] amd-iommu: add function to flush tlb for all devices Joerg Roedel
@ 2009-05-22 12:15 ` Joerg Roedel
2009-05-22 12:15 ` [PATCH 9/9] amd-iommu: implement suspend/resume Joerg Roedel
8 siblings, 0 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel; +Cc: Joerg Roedel
[ impact: keep functions in kernel .text required in resume path ]
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kernel/amd_iommu_init.c | 10 +++++-----
1 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index ed10c0f..330896b 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -193,7 +193,7 @@ static inline unsigned long tbl_size(int entry_size)
* This function set the exclusion range in the IOMMU. DMA accesses to the
* exclusion range are passed through untranslated
*/
-static void __init iommu_set_exclusion_range(struct amd_iommu *iommu)
+static void iommu_set_exclusion_range(struct amd_iommu *iommu)
{
u64 start = iommu->exclusion_start & PAGE_MASK;
u64 limit = (start + iommu->exclusion_length) & PAGE_MASK;
@@ -225,7 +225,7 @@ static void __init iommu_set_device_table(struct amd_iommu *iommu)
}
/* Generic functions to enable/disable certain features of the IOMMU. */
-static void __init iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
+static void iommu_feature_enable(struct amd_iommu *iommu, u8 bit)
{
u32 ctrl;
@@ -244,7 +244,7 @@ static void __init iommu_feature_disable(struct amd_iommu *iommu, u8 bit)
}
/* Function to enable the hardware */
-static void __init iommu_enable(struct amd_iommu *iommu)
+static void iommu_enable(struct amd_iommu *iommu)
{
printk(KERN_INFO "AMD IOMMU: Enabling IOMMU at %s cap 0x%hx\n",
dev_name(&iommu->dev->dev), iommu->cap_ptr);
@@ -811,7 +811,7 @@ static int __init iommu_setup_msi(struct amd_iommu *iommu)
return 0;
}
-static int __init iommu_init_msi(struct amd_iommu *iommu)
+static int iommu_init_msi(struct amd_iommu *iommu)
{
if (iommu->int_enabled)
return 0;
@@ -936,7 +936,7 @@ static void init_device_table(void)
* This function finally enables all IOMMUs found in the system after
* they have been initialized
*/
-static void __init enable_iommus(void)
+static void enable_iommus(void)
{
struct amd_iommu *iommu;
--
1.6.3.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 9/9] amd-iommu: implement suspend/resume
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
` (7 preceding siblings ...)
2009-05-22 12:15 ` [PATCH 8/9] amd_iommu: un __init functions required for suspend/resume Joerg Roedel
@ 2009-05-22 12:15 ` Joerg Roedel
8 siblings, 0 replies; 10+ messages in thread
From: Joerg Roedel @ 2009-05-22 12:15 UTC (permalink / raw)
To: iommu, linux-kernel; +Cc: Joerg Roedel
[ impact: put everything together and enable suspend/resume ]
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
---
arch/x86/kernel/amd_iommu_init.c | 21 ++++++++++++++++++++-
1 files changed, 20 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kernel/amd_iommu_init.c b/arch/x86/kernel/amd_iommu_init.c
index 330896b..4ca8fbf 100644
--- a/arch/x86/kernel/amd_iommu_init.c
+++ b/arch/x86/kernel/amd_iommu_init.c
@@ -965,12 +965,31 @@ static void disable_iommus(void)
static int amd_iommu_resume(struct sys_device *dev)
{
+ /*
+ * Disable IOMMUs before reprogramming the hardware registers.
+ * IOMMU is still enabled from the resume kernel.
+ */
+ disable_iommus();
+
+ /* re-load the hardware */
+ enable_iommus();
+
+ /*
+ * we have to flush after the IOMMUs are enabled because a
+ * disabled IOMMU will never execute the commands we send
+ */
+ amd_iommu_flush_all_domains();
+ amd_iommu_flush_all_devices();
+
return 0;
}
static int amd_iommu_suspend(struct sys_device *dev, pm_message_t state)
{
- return -EINVAL;
+ /* disable IOMMUs to go out of the way for BIOS */
+ disable_iommus();
+
+ return 0;
}
static struct sysdev_class amd_iommu_sysdev_class = {
--
1.6.3.1
^ permalink raw reply related [flat|nested] 10+ messages in thread
end of thread, other threads:[~2009-05-22 12:18 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-05-22 12:15 [PATCH 0/9] suspend/resume support for amd iommu Joerg Roedel
2009-05-22 12:15 ` [PATCH 1/9] amd-iommu: introduce for_each_iommu* macros Joerg Roedel
2009-05-22 12:15 ` [PATCH 2/9] amd-iommu: consolidate hardware initialization to one function Joerg Roedel
2009-05-22 12:15 ` [PATCH 3/9] amd-iommu: drop pointless iommu-loop in msi setup code Joerg Roedel
2009-05-22 12:15 ` [PATCH 4/9] amd-iommu: remove support for msi-x Joerg Roedel
2009-05-22 12:15 ` [PATCH 5/9] amd-iommu: add function to disable all iommus Joerg Roedel
2009-05-22 12:15 ` [PATCH 6/9] amd-iommu: add function to flush tlb for all domains Joerg Roedel
2009-05-22 12:15 ` [PATCH 7/9] amd-iommu: add function to flush tlb for all devices Joerg Roedel
2009-05-22 12:15 ` [PATCH 8/9] amd_iommu: un __init functions required for suspend/resume Joerg Roedel
2009-05-22 12:15 ` [PATCH 9/9] amd-iommu: implement suspend/resume Joerg Roedel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).