[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-3.4-testing] vtd: Fix apic pin to interrupt remapping table index
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1244109126 -3600 # Node ID 2e0834d5e01d6231753bd39849bf578670fb84de # Parent 75a24d7db2819f214ebebcea57bb7c8262190241 vtd: Fix apic pin to interrupt remapping table index Originally, it calls xmalloc to set index in ioapic_rte_to_remap_entry(). When make with debug=y, it may trigger spinlock BUG_ON because allocate memory with interrupt disabled. Signed-off-by: Weidong Han <weidong.han@xxxxxxxxx> Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> xen-unstable changeset: 19707:07cf79dfb59c xen-unstable date: Wed Jun 03 12:59:44 2009 +0100 vtd: ia64 fix of intremap.c 19707:07cf79dfb59c caused compilation error on ia64. This patch fixes it. Signed-off-by: Isaku Yamahata <yamahata@xxxxxxxxxxxxx> xen-unstable changeset: 19727:abdd365e2ec3 xen-unstable date: Thu Jun 04 10:48:45 2009 +0100 --- xen/arch/ia64/linux-xen/iosapic.c | 18 ++++ xen/drivers/passthrough/vtd/intremap.c | 110 +++++++++------------------ xen/include/asm-ia64/linux-xen/asm/iosapic.h | 3 3 files changed, 61 insertions(+), 70 deletions(-) diff -r 75a24d7db281 -r 2e0834d5e01d xen/arch/ia64/linux-xen/iosapic.c --- a/xen/arch/ia64/linux-xen/iosapic.c Wed Jun 03 15:16:49 2009 +0100 +++ b/xen/arch/ia64/linux-xen/iosapic.c Thu Jun 04 10:52:06 2009 +0100 @@ -1275,4 +1275,22 @@ int iosapic_guest_write(unsigned long ph spin_unlock_irqrestore(&irq_descp(vec)->lock, flags); return 0; } + +/* for vtd interrupt remapping. xen/drivers/vtd/intremap.c */ +int iosapic_get_nr_iosapics(void) +{ + int index; + + for (index = NR_IOSAPICS - 1; index >= 0; index--) { + if (iosapic_lists[index].addr) + break; + } + + return index + 1; +} + +int iosapic_get_nr_pins(int index) +{ + return iosapic_lists[index].num_rte; +} #endif /* XEN */ diff -r 75a24d7db281 -r 2e0834d5e01d xen/drivers/passthrough/vtd/intremap.c --- a/xen/drivers/passthrough/vtd/intremap.c Wed Jun 03 15:16:49 2009 +0100 +++ b/xen/drivers/passthrough/vtd/intremap.c Thu Jun 04 10:52:06 2009 +0100 @@ -31,71 +31,44 @@ #include "vtd.h" #include "extern.h" -#ifndef dest_SMI +#ifdef __ia64__ #define dest_SMI -1 +#define nr_ioapics iosapic_get_nr_iosapics() +#define nr_ioapic_registers(i) iosapic_get_nr_pins(i) +#else +#define nr_ioapic_registers(i) nr_ioapic_registers[i] #endif -/* The max number of IOAPIC (or IOSAPIC) pin. The typical values can be 24 or - * 48 on x86 and Itanium platforms. Here we use a biger number 256. This - * should be big enough. Actually now IREMAP_ENTRY_NR is also 256. - */ -#define MAX_IOAPIC_PIN_NUM 256 - -struct ioapicid_pin_intremap_index { - struct list_head list; - unsigned int ioapic_id; - unsigned int pin; - int intremap_index; -}; - -static struct list_head ioapic_pin_to_intremap_index[MAX_IOAPIC_PIN_NUM]; - -static int init_ioapic_pin_intremap_index(void) -{ - static int initialized = 0; - int i; - - if ( initialized == 1 ) - return 0; - - for ( i = 0; i < MAX_IOAPIC_PIN_NUM; i++ ) - INIT_LIST_HEAD(&ioapic_pin_to_intremap_index[i]); - - initialized = 1; - return 0; -} - -static int get_ioapic_pin_intremap_index(unsigned int ioapic_id, - unsigned int pin) -{ - struct ioapicid_pin_intremap_index *entry; - struct list_head *pos, *tmp; - - list_for_each_safe ( pos, tmp, &ioapic_pin_to_intremap_index[pin] ) - { - entry = list_entry(pos, struct ioapicid_pin_intremap_index, list); - if ( entry->ioapic_id == ioapic_id ) - return entry->intremap_index; - } - - return -1; -} - -static int set_ioapic_pin_intremap_index(unsigned int ioapic_id, - unsigned int pin, - int index) -{ - struct ioapicid_pin_intremap_index *entry; - - entry = xmalloc(struct ioapicid_pin_intremap_index); - if ( !entry ) +/* apic_pin_2_ir_idx[apicid][pin] = interrupt remapping table index */ +static unsigned int **apic_pin_2_ir_idx; + +static int init_apic_pin_2_ir_idx(void) +{ + unsigned int *_apic_pin_2_ir_idx; + unsigned int nr_pins, i; + + nr_pins = 0; + for ( i = 0; i < nr_ioapics; i++ ) + nr_pins += nr_ioapic_registers(i); + + _apic_pin_2_ir_idx = xmalloc_array(unsigned int, nr_pins); + apic_pin_2_ir_idx = xmalloc_array(unsigned int *, nr_ioapics); + if ( (_apic_pin_2_ir_idx == NULL) || (apic_pin_2_ir_idx == NULL) ) + { + xfree(_apic_pin_2_ir_idx); + xfree(apic_pin_2_ir_idx); return -ENOMEM; - - entry->ioapic_id = ioapic_id; - entry->pin = pin; - entry->intremap_index = index; - - list_add_tail(&entry->list, &ioapic_pin_to_intremap_index[pin]); + } + + for ( i = 0; i < nr_pins; i++ ) + _apic_pin_2_ir_idx[i] = -1; + + nr_pins = 0; + for ( i = 0; i < nr_ioapics; i++ ) + { + apic_pin_2_ir_idx[i] = &_apic_pin_2_ir_idx[nr_pins]; + nr_pins += nr_ioapic_registers(i); + } return 0; } @@ -160,7 +133,7 @@ static int remap_entry_to_ioapic_rte( } static int ioapic_rte_to_remap_entry(struct iommu *iommu, - int apic_id, unsigned int ioapic_pin, struct IO_xAPIC_route_entry *old_rte, + int apic, unsigned int ioapic_pin, struct IO_xAPIC_route_entry *old_rte, unsigned int rte_upper, unsigned int value) { struct iremap_entry *iremap_entry = NULL, *iremap_entries; @@ -174,12 +147,12 @@ static int ioapic_rte_to_remap_entry(str remap_rte = (struct IO_APIC_route_remap_entry *) old_rte; spin_lock_irqsave(&ir_ctrl->iremap_lock, flags); - index = get_ioapic_pin_intremap_index(apic_id, ioapic_pin); + index = apic_pin_2_ir_idx[apic][ioapic_pin]; if ( index < 0 ) { ir_ctrl->iremap_index++; index = ir_ctrl->iremap_index; - set_ioapic_pin_intremap_index(apic_id, ioapic_pin, index); + apic_pin_2_ir_idx[apic][ioapic_pin] = index; } if ( index > IREMAP_ENTRY_NR - 1 ) @@ -218,7 +191,7 @@ static int ioapic_rte_to_remap_entry(str new_ire.lo.res_1 = 0; new_ire.lo.vector = new_rte.vector; new_ire.lo.res_2 = 0; - new_ire.hi.sid = apicid_to_bdf(apic_id); + new_ire.hi.sid = apicid_to_bdf(IO_APIC_ID(apic)); new_ire.hi.sq = 0; /* comparing all 16-bit of SID */ new_ire.hi.svt = 1; /* requestor ID verification SID/SQ */ @@ -356,8 +329,7 @@ void io_apic_write_remap_rte( *(IO_APIC_BASE(apic)+4) = *(((int *)&old_rte)+0); remap_rte->mask = saved_mask; - ASSERT(ioapic_pin < MAX_IOAPIC_PIN_NUM); - if ( ioapic_rte_to_remap_entry(iommu, IO_APIC_ID(apic), ioapic_pin, + if ( ioapic_rte_to_remap_entry(iommu, apic, ioapic_pin, &old_rte, rte_upper, value) ) { *IO_APIC_BASE(apic) = rte_upper ? (reg + 1) : reg; @@ -628,9 +600,7 @@ int enable_intremap(struct iommu *iommu) /* After set SIRTP, we should do globally invalidate the IEC */ iommu_flush_iec_global(iommu); - init_ioapic_pin_intremap_index(); - - return 0; + return init_apic_pin_2_ir_idx(); } void disable_intremap(struct iommu *iommu) diff -r 75a24d7db281 -r 2e0834d5e01d xen/include/asm-ia64/linux-xen/asm/iosapic.h --- a/xen/include/asm-ia64/linux-xen/asm/iosapic.h Wed Jun 03 15:16:49 2009 +0100 +++ b/xen/include/asm-ia64/linux-xen/asm/iosapic.h Thu Jun 04 10:52:06 2009 +0100 @@ -186,6 +186,9 @@ struct rte_entry { #define IOSAPIC_RTEINDEX(reg) (((reg) - 0x10) >> 1) extern unsigned long ia64_vector_mask[]; extern unsigned long ia64_xen_vector[]; + +int iosapic_get_nr_iosapics(void); +int iosapic_get_nr_pins(int index); #endif /* XEN */ #define IO_APIC_BASE(idx) ((unsigned int *)iosapic_lists[idx].addr) _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |