From: Wei Wang2 <wei.wang2@amd.com>
To: xen-devel@lists.xensource.com
Subject: [PATCH] AMD IOMMU: Use global interrupt remapping table by default
Date: Wed, 28 Oct 2009 17:32:07 +0100 [thread overview]
Message-ID: <200910281732.07420.wei.wang2@amd.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 613 bytes --]
Using a global interrupt remapping table shared by all devices has better
compatibility with certain old BIOSes. Per-device interrupt remapping table
can still be enabled by using a new parameter "amd-iommu-perdev-intremap".
Thanks,
Wei
Signed-off-by: Wei Wang <wei.wang2@amd.com>
--
AMD GmbH, Germany
Operating System Research Center
Legal Information:
Advanced Micro Devices GmbH
Karl-Hammerschmidt-Str. 34
85609 Dornach b. München
Geschäftsführer: Andrew Bowd, Thomas M. McCoy, Giuliano Meroni
Sitz: Dornach, Gemeinde Aschheim, Landkreis München
Registergericht München, HRB Nr. 43632
[-- Attachment #2: perdev-intremap.patch --]
[-- Type: text/x-diff, Size: 8166 bytes --]
diff -r f8bb0f8e0ae7 xen/drivers/passthrough/amd/iommu_acpi.c
--- a/xen/drivers/passthrough/amd/iommu_acpi.c Wed Oct 28 14:04:51 2009 +0100
+++ b/xen/drivers/passthrough/amd/iommu_acpi.c Wed Oct 28 14:26:38 2009 +0100
@@ -29,6 +29,7 @@ extern struct ivrs_mappings *ivrs_mappin
extern struct ivrs_mappings *ivrs_mappings;
extern unsigned short last_bdf;
extern int ioapic_bdf[MAX_IO_APICS];
+extern void *shared_intremap_table;
static void add_ivrs_mapping_entry(
u16 bdf, u16 alias_id, u8 flags, struct amd_iommu *iommu)
@@ -66,10 +67,19 @@ static void add_ivrs_mapping_entry(
ivrs_mappings[bdf].dte_ext_int_pass = ext_int_pass;
ivrs_mappings[bdf].dte_init_pass = init_pass;
- /* allocate per-device interrupt remapping table */
- if ( ivrs_mappings[alias_id].intremap_table == NULL )
- ivrs_mappings[alias_id].intremap_table =
- amd_iommu_alloc_intremap_table();
+ if (ivrs_mappings[alias_id].intremap_table == NULL )
+ {
+ /* allocate per-device interrupt remapping table */
+ if ( amd_iommu_perdev_intremap )
+ ivrs_mappings[alias_id].intremap_table =
+ amd_iommu_alloc_intremap_table();
+ else
+ {
+ if ( shared_intremap_table == NULL )
+ shared_intremap_table = amd_iommu_alloc_intremap_table();
+ ivrs_mappings[alias_id].intremap_table = shared_intremap_table;
+ }
+ }
/* assgin iommu hardware */
ivrs_mappings[bdf].iommu = iommu;
}
diff -r f8bb0f8e0ae7 xen/drivers/passthrough/amd/iommu_init.c
--- a/xen/drivers/passthrough/amd/iommu_init.c Wed Oct 28 14:04:51 2009 +0100
+++ b/xen/drivers/passthrough/amd/iommu_init.c Wed Oct 28 14:26:38 2009 +0100
@@ -706,7 +706,8 @@ static int __init init_ivrs_mapping(void
ivrs_mappings[bdf].dte_ext_int_pass = IOMMU_CONTROL_DISABLED;
ivrs_mappings[bdf].dte_init_pass = IOMMU_CONTROL_DISABLED;
- spin_lock_init(&ivrs_mappings[bdf].intremap_lock);
+ if ( amd_iommu_perdev_intremap )
+ spin_lock_init(&ivrs_mappings[bdf].intremap_lock);
}
return 0;
}
diff -r f8bb0f8e0ae7 xen/drivers/passthrough/amd/iommu_intr.c
--- a/xen/drivers/passthrough/amd/iommu_intr.c Wed Oct 28 14:04:51 2009 +0100
+++ b/xen/drivers/passthrough/amd/iommu_intr.c Wed Oct 28 14:26:38 2009 +0100
@@ -26,6 +26,15 @@ int ioapic_bdf[MAX_IO_APICS];
int ioapic_bdf[MAX_IO_APICS];
extern struct ivrs_mappings *ivrs_mappings;
extern unsigned short ivrs_bdf_entries;
+void *shared_intremap_table;
+static DEFINE_SPINLOCK(shared_intremap_lock);
+
+static spinlock_t* get_intremap_lock(int req_id)
+{
+ return (amd_iommu_perdev_intremap ?
+ &ivrs_mappings[req_id].intremap_lock:
+ &shared_intremap_lock);
+}
static int get_intremap_requestor_id(int bdf)
{
@@ -101,9 +110,10 @@ static void update_intremap_entry_from_i
u8 delivery_mode, dest, vector, dest_mode;
struct IO_APIC_route_entry *rte = ioapic_rte;
int req_id;
+ spinlock_t *lock;
req_id = get_intremap_requestor_id(bdf);
-
+ lock = get_intremap_lock(req_id);
/* only remap interrupt vector when lower 32 bits in ioapic ire changed */
if ( likely(!rte_upper) )
{
@@ -112,10 +122,10 @@ static void update_intremap_entry_from_i
dest_mode = rte->dest_mode;
dest = rte->dest.logical.logical_dest;
- spin_lock_irqsave(&ivrs_mappings[req_id].intremap_lock, flags);
+ spin_lock_irqsave(lock, flags);
entry = (u32*)get_intremap_entry(req_id, vector, delivery_mode);
update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
- spin_unlock_irqrestore(&ivrs_mappings[req_id].intremap_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
if ( iommu->enabled )
{
@@ -136,6 +146,7 @@ int __init amd_iommu_setup_ioapic_remapp
u8 delivery_mode, dest, vector, dest_mode;
u16 bdf, req_id;
struct amd_iommu *iommu;
+ spinlock_t *lock;
/* Read ioapic entries and update interrupt remapping table accordingly */
for ( apic = 0; apic < nr_ioapics; apic++ )
@@ -159,15 +170,17 @@ int __init amd_iommu_setup_ioapic_remapp
}
req_id = get_intremap_requestor_id(bdf);
+ lock = get_intremap_lock(req_id);
+
delivery_mode = rte.delivery_mode;
vector = rte.vector;
dest_mode = rte.dest_mode;
dest = rte.dest.logical.logical_dest;
- spin_lock_irqsave(&ivrs_mappings[req_id].intremap_lock, flags);
+ spin_lock_irqsave(lock, flags);
entry = (u32*)get_intremap_entry(req_id, vector, delivery_mode);
update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
- spin_unlock_irqrestore(&ivrs_mappings[req_id].intremap_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
if ( iommu->enabled )
{
@@ -234,13 +247,14 @@ static void update_intremap_entry_from_m
unsigned long flags;
u32* entry;
u16 bdf, req_id, alias_id;
-
u8 delivery_mode, dest, vector, dest_mode;
+ spinlock_t *lock;
bdf = (pdev->bus << 8) | pdev->devfn;
req_id = get_dma_requestor_id(bdf);
-
- spin_lock_irqsave(&ivrs_mappings[req_id].intremap_lock, flags);
+ lock = get_intremap_lock(req_id);
+
+ spin_lock_irqsave(lock, flags);
dest_mode = (msg->address_lo >> MSI_ADDR_DESTMODE_SHIFT) & 0x1;
delivery_mode = (msg->data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x1;
vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK;
@@ -248,7 +262,7 @@ static void update_intremap_entry_from_m
entry = (u32*)get_intremap_entry(req_id, vector, delivery_mode);
update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
- spin_unlock_irqrestore(&ivrs_mappings[req_id].intremap_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
/*
* In some special cases, a pci-e device(e.g SATA controller in IDE mode)
@@ -257,14 +271,15 @@ static void update_intremap_entry_from_m
* devices.
*/
alias_id = get_intremap_requestor_id(bdf);
+ lock = get_intremap_lock(alias_id);
if ( ( bdf != alias_id ) &&
ivrs_mappings[alias_id].intremap_table != NULL )
{
- spin_lock_irqsave(&ivrs_mappings[alias_id].intremap_lock, flags);
+ spin_lock_irqsave(lock, flags);
entry = (u32*)get_intremap_entry(alias_id, vector, delivery_mode);
update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
invalidate_interrupt_table(iommu, alias_id);
- spin_unlock_irqrestore(&ivrs_mappings[alias_id].intremap_lock, flags);
+ spin_unlock_irqrestore(lock, flags);
}
if ( iommu->enabled )
diff -r f8bb0f8e0ae7 xen/drivers/passthrough/iommu.c
--- a/xen/drivers/passthrough/iommu.c Wed Oct 28 14:04:51 2009 +0100
+++ b/xen/drivers/passthrough/iommu.c Wed Oct 28 14:26:38 2009 +0100
@@ -45,6 +45,7 @@ int iommu_qinval = 0;
int iommu_qinval = 0;
int iommu_intremap = 0;
int amd_iommu_debug = 0;
+int amd_iommu_perdev_intremap = 0;
static void __init parse_iommu_param(char *s)
{
@@ -54,6 +55,7 @@ static void __init parse_iommu_param(cha
iommu_qinval = 1;
iommu_intremap = 1;
amd_iommu_debug = 0;
+ amd_iommu_perdev_intremap = 0;
do {
ss = strchr(s, ',');
@@ -79,6 +81,8 @@ static void __init parse_iommu_param(cha
iommu_intremap = 0;
else if ( !strcmp(s, "amd-iommu-debug") )
amd_iommu_debug = 1;
+ else if ( !strcmp(s, "amd-iommu-perdev-intremap") )
+ amd_iommu_perdev_intremap = 1;
s = ss + 1;
} while ( ss );
diff -r f8bb0f8e0ae7 xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
--- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Oct 28 14:04:51 2009 +0100
+++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h Wed Oct 28 14:26:38 2009 +0100
@@ -33,6 +33,7 @@
#define PAGE_ALIGN(addr) (((addr) + PAGE_SIZE - 1) & PAGE_MASK)
extern int amd_iommu_debug;
+extern int amd_iommu_perdev_intremap;
#define AMD_IOMMU_DEBUG(fmt, args...) \
do \
[-- Attachment #3: Type: text/plain, Size: 138 bytes --]
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
next reply other threads:[~2009-10-28 16:32 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2009-10-28 16:32 Wei Wang2 [this message]
2011-07-19 14:14 ` [PATCH] AMD IOMMU: Use global interrupt remapping table by default George Dunlap
2011-07-20 9:52 ` Wei Wang2
2011-07-20 10:50 ` Ian Campbell
2011-07-20 12:34 ` Wei Wang2
2011-07-20 13:01 ` Ian Campbell
2011-07-20 15:56 ` Wei Wang2
2011-07-21 9:07 ` George Dunlap
2011-07-21 10:38 ` Wei Wang2
2011-07-21 14:36 ` George Dunlap
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200910281732.07420.wei.wang2@amd.com \
--to=wei.wang2@amd.com \
--cc=xen-devel@lists.xensource.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.