From: Suravee Suthikulpanit <suravee.suthikulpanit@amd.com>
To: Jan Beulich <JBeulich@suse.com>
Cc: Jacob Shin <jacob.shin@amd.com>,
xiantao.zhang@intel.com, xen-devel <xen-devel@lists.xen.org>
Subject: Re: [PATCH v2 3/4] AMD IOMMU: allocate IRTE entries instead of using a static mapping
Date: Wed, 10 Apr 2013 19:34:11 -0500 [thread overview]
Message-ID: <51660503.8010107@amd.com> (raw)
In-Reply-To: <515AB50802000078000CA017@nat28.tlf.novell.com>
Jan,
This patch is still having the same issue. The table is NULL. I'm still
trying to root cause it.
Suravee
On 4/2/2013 3:38 AM, Jan Beulich wrote:
> AMD IOMMU: allocate IRTE entries instead of using a static mapping
>
> For multi-vector MSI, where we surely don't want to allocate
> contiguous vectors and be able to set affinities of the individual
> vectors separately, we need to drop the use of the tuple of vector and
> delivery mode to determine the IRTE to use, and instead allocate IRTEs
> (which imo should have been done from the beginning).
>
> Signed-off-by: Jan Beulich <jbeulich@suse.com>
> ---
> v2: {get,free}_intremap_entry()'s offset parameter is now an entry
> offset rather than a byte one. With the return type change of
> get_intremap_entry() also drop all the bogus casts its callers
> used.
> ---
> One thing I surely need confirmation on is whether this
>
> BUG_ON(get_ivrs_mappings(iommu->seg)[req_id].intremap_table !=
> get_ivrs_mappings(iommu->seg)[alias_id].intremap_table);
>
> in update_intremap_entry_from_msi_msg() is valid. If it isn't, it's not
> clear to me how to properly set up things for affected devices, as we
> would need an identical index allocated for two different remap table
> instances (which can hardly be expected to work out well).
>
> --- a/xen/drivers/passthrough/amd/iommu_acpi.c
> +++ b/xen/drivers/passthrough/amd/iommu_acpi.c
> @@ -72,12 +72,15 @@ static void __init add_ivrs_mapping_entr
> /* allocate per-device interrupt remapping table */
> if ( amd_iommu_perdev_intremap )
> ivrs_mappings[alias_id].intremap_table =
> - amd_iommu_alloc_intremap_table();
> + amd_iommu_alloc_intremap_table(
> + &ivrs_mappings[alias_id].intremap_inuse);
> else
> {
> if ( shared_intremap_table == NULL )
> - shared_intremap_table = amd_iommu_alloc_intremap_table();
> + shared_intremap_table = amd_iommu_alloc_intremap_table(
> + &shared_intremap_inuse);
> ivrs_mappings[alias_id].intremap_table = shared_intremap_table;
> + ivrs_mappings[alias_id].intremap_inuse = shared_intremap_inuse;
> }
> }
> /* assgin iommu hardware */
> @@ -671,7 +674,7 @@ static u16 __init parse_ivhd_device_spec
> if ( IO_APIC_ID(apic) != special->handle )
> continue;
>
> - if ( ioapic_sbdf[special->handle].pin_setup )
> + if ( ioapic_sbdf[special->handle].pin_2_idx )
> {
> if ( ioapic_sbdf[special->handle].bdf == bdf &&
> ioapic_sbdf[special->handle].seg == seg )
> @@ -691,14 +694,16 @@ static u16 __init parse_ivhd_device_spec
> ioapic_sbdf[special->handle].bdf = bdf;
> ioapic_sbdf[special->handle].seg = seg;
>
> - ioapic_sbdf[special->handle].pin_setup = xzalloc_array(
> - unsigned long, BITS_TO_LONGS(nr_ioapic_entries[apic]));
> + ioapic_sbdf[special->handle].pin_2_idx = xmalloc_array(
> + u16, nr_ioapic_entries[apic]);
> if ( nr_ioapic_entries[apic] &&
> - !ioapic_sbdf[IO_APIC_ID(apic)].pin_setup )
> + !ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx )
> {
> printk(XENLOG_ERR "IVHD Error: Out of memory\n");
> return 0;
> }
> + memset(ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx, -1,
> + nr_ioapic_entries[apic]);
> }
> break;
> }
> @@ -926,7 +931,7 @@ static int __init parse_ivrs_table(struc
> for ( apic = 0; !error && iommu_intremap && apic < nr_ioapics; ++apic )
> {
> if ( !nr_ioapic_entries[apic] ||
> - ioapic_sbdf[IO_APIC_ID(apic)].pin_setup )
> + ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx )
> continue;
>
> printk(XENLOG_ERR "IVHD Error: no information for IO-APIC %#x\n",
> @@ -935,13 +940,15 @@ static int __init parse_ivrs_table(struc
> error = -ENXIO;
> else
> {
> - ioapic_sbdf[IO_APIC_ID(apic)].pin_setup = xzalloc_array(
> - unsigned long, BITS_TO_LONGS(nr_ioapic_entries[apic]));
> - if ( !ioapic_sbdf[IO_APIC_ID(apic)].pin_setup )
> + ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx = xmalloc_array(
> + u16, nr_ioapic_entries[apic]);
> + if ( !ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx )
> {
> printk(XENLOG_ERR "IVHD Error: Out of memory\n");
> error = -ENOMEM;
> }
> + memset(ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx, -1,
> + nr_ioapic_entries[apic]);
> }
> }
>
> --- a/xen/drivers/passthrough/amd/iommu_intr.c
> +++ b/xen/drivers/passthrough/amd/iommu_intr.c
> @@ -30,6 +30,7 @@
> struct ioapic_sbdf ioapic_sbdf[MAX_IO_APICS];
> struct hpet_sbdf hpet_sbdf;
> void *shared_intremap_table;
> +unsigned long *shared_intremap_inuse;
> static DEFINE_SPINLOCK(shared_intremap_lock);
>
> static spinlock_t* get_intremap_lock(int seg, int req_id)
> @@ -45,30 +46,31 @@ static int get_intremap_requestor_id(int
> return get_ivrs_mappings(seg)[bdf].dte_requestor_id;
> }
>
> -static int get_intremap_offset(u8 vector, u8 dm)
> +static unsigned int alloc_intremap_entry(int seg, int bdf)
> {
> - int offset = 0;
> - offset = (dm << INT_REMAP_INDEX_DM_SHIFT) & INT_REMAP_INDEX_DM_MASK;
> - offset |= (vector << INT_REMAP_INDEX_VECTOR_SHIFT ) &
> - INT_REMAP_INDEX_VECTOR_MASK;
> - return offset;
> + unsigned long *inuse = get_ivrs_mappings(seg)[bdf].intremap_inuse;
> + unsigned int slot = find_first_zero_bit(inuse, INTREMAP_ENTRIES);
> +
> + if ( slot < INTREMAP_ENTRIES )
> + __set_bit(slot, inuse);
> + return slot;
> }
>
> -static u8 *get_intremap_entry(int seg, int bdf, int offset)
> +static u32 *get_intremap_entry(int seg, int bdf, int offset)
> {
> - u8 *table;
> + u32 *table = get_ivrs_mappings(seg)[bdf].intremap_table;
>
> - table = (u8*)get_ivrs_mappings(seg)[bdf].intremap_table;
> ASSERT( (table != NULL) && (offset < INTREMAP_ENTRIES) );
>
> - return (u8*) (table + offset);
> + return table + offset;
> }
>
> static void free_intremap_entry(int seg, int bdf, int offset)
> {
> - u32* entry;
> - entry = (u32*)get_intremap_entry(seg, bdf, offset);
> + u32 *entry = get_intremap_entry(seg, bdf, offset);
> +
> memset(entry, 0, sizeof(u32));
> + __clear_bit(offset, get_ivrs_mappings(seg)[bdf].intremap_inuse);
> }
>
> static void update_intremap_entry(u32* entry, u8 vector, u8 int_type,
> @@ -97,18 +99,24 @@ static void update_intremap_entry(u32* e
> INT_REMAP_ENTRY_VECTOR_SHIFT, entry);
> }
>
> -static void update_intremap_entry_from_ioapic(
> +static void set_rte_index(struct IO_APIC_route_entry *rte, int offset)
> +{
> + rte->vector = (u8)offset;
> + rte->delivery_mode = offset >> 8;
> +}
> +
> +static int update_intremap_entry_from_ioapic(
> int bdf,
> struct amd_iommu *iommu,
> - const struct IO_APIC_route_entry *rte,
> - const struct IO_APIC_route_entry *old_rte)
> + struct IO_APIC_route_entry *rte,
> + u16 *index)
> {
> unsigned long flags;
> u32* entry;
> u8 delivery_mode, dest, vector, dest_mode;
> int req_id;
> spinlock_t *lock;
> - int offset;
> + unsigned int offset;
>
> req_id = get_intremap_requestor_id(iommu->seg, bdf);
> lock = get_intremap_lock(iommu->seg, req_id);
> @@ -120,16 +128,20 @@ static void update_intremap_entry_from_i
>
> spin_lock_irqsave(lock, flags);
>
> - offset = get_intremap_offset(vector, delivery_mode);
> - if ( old_rte )
> + offset = *index;
> + if ( offset >= INTREMAP_ENTRIES )
> {
> - int old_offset = get_intremap_offset(old_rte->vector,
> - old_rte->delivery_mode);
> -
> - if ( offset != old_offset )
> - free_intremap_entry(iommu->seg, bdf, old_offset);
> + offset = alloc_intremap_entry(iommu->seg, req_id);
> + if ( offset >= INTREMAP_ENTRIES )
> + {
> + spin_unlock_irqrestore(lock, flags);
> + rte->mask = 1;
> + return -ENOSPC;
> + }
> + *index = offset;
> }
> - entry = (u32*)get_intremap_entry(iommu->seg, req_id, offset);
> +
> + entry = get_intremap_entry(iommu->seg, req_id, offset);
> update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
>
> spin_unlock_irqrestore(lock, flags);
> @@ -140,6 +152,10 @@ static void update_intremap_entry_from_i
> amd_iommu_flush_intremap(iommu, req_id);
> spin_unlock_irqrestore(&iommu->lock, flags);
> }
> +
> + set_rte_index(rte, offset);
> +
> + return 0;
> }
>
> int __init amd_iommu_setup_ioapic_remapping(void)
> @@ -152,7 +168,7 @@ int __init amd_iommu_setup_ioapic_remapp
> u16 seg, bdf, req_id;
> struct amd_iommu *iommu;
> spinlock_t *lock;
> - int offset;
> + unsigned int offset;
>
> /* Read ioapic entries and update interrupt remapping table accordingly */
> for ( apic = 0; apic < nr_ioapics; apic++ )
> @@ -183,19 +199,24 @@ int __init amd_iommu_setup_ioapic_remapp
> dest = rte.dest.logical.logical_dest;
>
> spin_lock_irqsave(lock, flags);
> - offset = get_intremap_offset(vector, delivery_mode);
> - entry = (u32*)get_intremap_entry(iommu->seg, req_id, offset);
> + offset = alloc_intremap_entry(seg, req_id);
> + BUG_ON(offset >= INTREMAP_ENTRIES);
> + ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx[pin] = offset;
> + entry = get_intremap_entry(iommu->seg, req_id, offset);
> update_intremap_entry(entry, vector,
> delivery_mode, dest_mode, dest);
> spin_unlock_irqrestore(lock, flags);
>
> + set_rte_index(&rte, offset);
> + ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx[pin] = offset;
> + __ioapic_write_entry(apic, pin, 1, rte);
> +
> if ( iommu->enabled )
> {
> spin_lock_irqsave(&iommu->lock, flags);
> amd_iommu_flush_intremap(iommu, req_id);
> spin_unlock_irqrestore(&iommu->lock, flags);
> }
> - set_bit(pin, ioapic_sbdf[IO_APIC_ID(apic)].pin_setup);
> }
> }
> return 0;
> @@ -208,7 +229,7 @@ void amd_iommu_ioapic_update_ire(
> struct IO_APIC_route_entry new_rte = { 0 };
> unsigned int rte_lo = (reg & 1) ? reg - 1 : reg;
> unsigned int pin = (reg - 0x10) / 2;
> - int saved_mask, seg, bdf;
> + int saved_mask, seg, bdf, rc;
> struct amd_iommu *iommu;
>
> if ( !iommu_intremap )
> @@ -246,7 +267,7 @@ void amd_iommu_ioapic_update_ire(
> }
>
> if ( new_rte.mask &&
> - !test_bit(pin, ioapic_sbdf[IO_APIC_ID(apic)].pin_setup) )
> + ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx[pin] >= INTREMAP_ENTRIES )
> {
> ASSERT(saved_mask);
> __io_apic_write(apic, reg, value);
> @@ -261,14 +282,19 @@ void amd_iommu_ioapic_update_ire(
> }
>
> /* Update interrupt remapping entry */
> - update_intremap_entry_from_ioapic(
> - bdf, iommu, &new_rte,
> - test_and_set_bit(pin,
> - ioapic_sbdf[IO_APIC_ID(apic)].pin_setup) ? &old_rte
> - : NULL);
> + rc = update_intremap_entry_from_ioapic(
> + bdf, iommu, &new_rte,
> + &ioapic_sbdf[IO_APIC_ID(apic)].pin_2_idx[pin]);
>
> - /* Forward write access to IO-APIC RTE */
> - __io_apic_write(apic, reg, value);
> + __io_apic_write(apic, reg, ((u32 *)&new_rte)[reg != rte_lo]);
> +
> + if ( rc )
> + {
> + /* Keep the entry masked. */
> + printk(XENLOG_ERR "Remapping IO-APIC %#x pin %u failed (%d)\n",
> + IO_APIC_ID(apic), pin, rc);
> + return;
> + }
>
> /* For lower bits access, return directly to avoid double writes */
> if ( reg == rte_lo )
> @@ -282,16 +308,41 @@ void amd_iommu_ioapic_update_ire(
> }
> }
>
> -static void update_intremap_entry_from_msi_msg(
> +unsigned int amd_iommu_read_ioapic_from_ire(
> + unsigned int apic, unsigned int reg)
> +{
> + unsigned int val = __io_apic_read(apic, reg);
> +
> + if ( !(reg & 1) )
> + {
> + unsigned int offset = val & (INTREMAP_ENTRIES - 1);
> + u16 bdf = ioapic_sbdf[IO_APIC_ID(apic)].bdf;
> + u16 seg = ioapic_sbdf[IO_APIC_ID(apic)].seg;
> + u16 req_id = get_intremap_requestor_id(seg, bdf);
> + const u32 *entry = get_intremap_entry(seg, req_id, offset);
> +
> + val &= ~(INTREMAP_ENTRIES - 1);
> + val |= get_field_from_reg_u32(*entry,
> + INT_REMAP_ENTRY_INTTYPE_MASK,
> + INT_REMAP_ENTRY_INTTYPE_SHIFT) << 8;
> + val |= get_field_from_reg_u32(*entry,
> + INT_REMAP_ENTRY_VECTOR_MASK,
> + INT_REMAP_ENTRY_VECTOR_SHIFT);
> + }
> +
> + return val;
> +}
> +
> +static int update_intremap_entry_from_msi_msg(
> struct amd_iommu *iommu, u16 bdf,
> - int *remap_index, const struct msi_msg *msg)
> + int *remap_index, const struct msi_msg *msg, u32 *data)
> {
> unsigned long flags;
> u32* entry;
> u16 req_id, alias_id;
> u8 delivery_mode, dest, vector, dest_mode;
> spinlock_t *lock;
> - int offset;
> + unsigned int offset;
>
> req_id = get_dma_requestor_id(iommu->seg, bdf);
> alias_id = get_intremap_requestor_id(iommu->seg, bdf);
> @@ -302,15 +353,6 @@ static void update_intremap_entry_from_m
> spin_lock_irqsave(lock, flags);
> free_intremap_entry(iommu->seg, req_id, *remap_index);
> spin_unlock_irqrestore(lock, flags);
> -
> - if ( ( req_id != alias_id ) &&
> - get_ivrs_mappings(iommu->seg)[alias_id].intremap_table != NULL )
> - {
> - lock = get_intremap_lock(iommu->seg, alias_id);
> - spin_lock_irqsave(lock, flags);
> - free_intremap_entry(iommu->seg, alias_id, *remap_index);
> - spin_unlock_irqrestore(lock, flags);
> - }
> goto done;
> }
>
> @@ -321,16 +363,24 @@ static void update_intremap_entry_from_m
> delivery_mode = (msg->data >> MSI_DATA_DELIVERY_MODE_SHIFT) & 0x1;
> vector = (msg->data >> MSI_DATA_VECTOR_SHIFT) & MSI_DATA_VECTOR_MASK;
> dest = (msg->address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff;
> - offset = get_intremap_offset(vector, delivery_mode);
> - if ( *remap_index < 0)
> + offset = *remap_index;
> + if ( offset >= INTREMAP_ENTRIES )
> + {
> + offset = alloc_intremap_entry(iommu->seg, bdf);
> + if ( offset >= INTREMAP_ENTRIES )
> + {
> + spin_unlock_irqrestore(lock, flags);
> + return -ENOSPC;
> + }
> *remap_index = offset;
> - else
> - BUG_ON(*remap_index != offset);
> + }
>
> - entry = (u32*)get_intremap_entry(iommu->seg, req_id, offset);
> + entry = get_intremap_entry(iommu->seg, req_id, offset);
> update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
> spin_unlock_irqrestore(lock, flags);
>
> + *data = (msg->data & ~(INTREMAP_ENTRIES - 1)) | offset;
> +
> /*
> * In some special cases, a pci-e device(e.g SATA controller in IDE mode)
> * will use alias id to index interrupt remapping table.
> @@ -342,10 +392,8 @@ static void update_intremap_entry_from_m
> if ( ( req_id != alias_id ) &&
> get_ivrs_mappings(iommu->seg)[alias_id].intremap_table != NULL )
> {
> - spin_lock_irqsave(lock, flags);
> - entry = (u32*)get_intremap_entry(iommu->seg, alias_id, offset);
> - update_intremap_entry(entry, vector, delivery_mode, dest_mode, dest);
> - spin_unlock_irqrestore(lock, flags);
> + BUG_ON(get_ivrs_mappings(iommu->seg)[req_id].intremap_table !=
> + get_ivrs_mappings(iommu->seg)[alias_id].intremap_table);
> }
>
> done:
> @@ -357,14 +405,17 @@ done:
> amd_iommu_flush_intremap(iommu, alias_id);
> spin_unlock_irqrestore(&iommu->lock, flags);
> }
> +
> + return 0;
> }
>
> int amd_iommu_msi_msg_update_ire(
> struct msi_desc *msi_desc, struct msi_msg *msg)
> {
> struct pci_dev *pdev = msi_desc->dev;
> - int bdf, seg;
> + int bdf, seg, rc;
> struct amd_iommu *iommu;
> + u32 data;
>
> bdf = pdev ? PCI_BDF2(pdev->bus, pdev->devfn) : hpet_sbdf.bdf;
> seg = pdev ? pdev->seg : hpet_sbdf.seg;
> @@ -376,11 +427,12 @@ int amd_iommu_msi_msg_update_ire(
> return -EINVAL;
> }
>
> - if ( msi_desc->remap_index >= 0 )
> + if ( msi_desc->remap_index >= 0 && !msg )
> {
> do {
> update_intremap_entry_from_msi_msg(iommu, bdf,
> - &msi_desc->remap_index, NULL);
> + &msi_desc->remap_index,
> + NULL, NULL);
> if ( !pdev || !pdev->phantom_stride )
> break;
> bdf += pdev->phantom_stride;
> @@ -395,19 +447,35 @@ int amd_iommu_msi_msg_update_ire(
> return 0;
>
> do {
> - update_intremap_entry_from_msi_msg(iommu, bdf, &msi_desc->remap_index,
> - msg);
> - if ( !pdev || !pdev->phantom_stride )
> + rc = update_intremap_entry_from_msi_msg(iommu, bdf,
> + &msi_desc->remap_index,
> + msg, &data);
> + if ( rc || !pdev || !pdev->phantom_stride )
> break;
> bdf += pdev->phantom_stride;
> } while ( PCI_SLOT(bdf) == PCI_SLOT(pdev->devfn) );
>
> - return 0;
> + msg->data = data;
> + return rc;
> }
>
> void amd_iommu_read_msi_from_ire(
> struct msi_desc *msi_desc, struct msi_msg *msg)
> {
> + unsigned int offset = msg->data & (INTREMAP_ENTRIES - 1);
> + const struct pci_dev *pdev = msi_desc->dev;
> + u16 bdf = pdev ? PCI_BDF2(pdev->bus, pdev->devfn) : hpet_sbdf.bdf;
> + u16 seg = pdev ? pdev->seg : hpet_sbdf.seg;
> + u16 req_id = get_dma_requestor_id(seg, bdf);
> + const u32 *entry = get_intremap_entry(seg, req_id, offset);
> +
> + msg->data &= ~(INTREMAP_ENTRIES - 1);
> + msg->data |= get_field_from_reg_u32(*entry,
> + INT_REMAP_ENTRY_INTTYPE_MASK,
> + INT_REMAP_ENTRY_INTTYPE_SHIFT) << 8;
> + msg->data |= get_field_from_reg_u32(*entry,
> + INT_REMAP_ENTRY_VECTOR_MASK,
> + INT_REMAP_ENTRY_VECTOR_SHIFT);
> }
>
> int __init amd_iommu_free_intremap_table(
> @@ -424,12 +492,14 @@ int __init amd_iommu_free_intremap_table
> return 0;
> }
>
> -void* __init amd_iommu_alloc_intremap_table(void)
> +void* __init amd_iommu_alloc_intremap_table(unsigned long **inuse_map)
> {
> void *tb;
> tb = __alloc_amd_iommu_tables(INTREMAP_TABLE_ORDER);
> BUG_ON(tb == NULL);
> memset(tb, 0, PAGE_SIZE * (1UL << INTREMAP_TABLE_ORDER));
> + *inuse_map = xzalloc_array(unsigned long, BITS_TO_LONGS(INTREMAP_ENTRIES));
> + BUG_ON(*inuse_map == NULL);
> return tb;
> }
>
> --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c
> +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c
> @@ -622,7 +622,7 @@ const struct iommu_ops amd_iommu_ops = {
> .get_device_group_id = amd_iommu_group_id,
> .update_ire_from_apic = amd_iommu_ioapic_update_ire,
> .update_ire_from_msi = amd_iommu_msi_msg_update_ire,
> - .read_apic_from_ire = __io_apic_read,
> + .read_apic_from_ire = amd_iommu_read_ioapic_from_ire,
> .read_msi_from_ire = amd_iommu_read_msi_from_ire,
> .setup_hpet_msi = amd_setup_hpet_msi,
> .suspend = amd_iommu_suspend,
> --- a/xen/include/asm-x86/amd-iommu.h
> +++ b/xen/include/asm-x86/amd-iommu.h
> @@ -119,6 +119,7 @@ struct ivrs_mappings {
>
> /* per device interrupt remapping table */
> void *intremap_table;
> + unsigned long *intremap_inuse;
> spinlock_t intremap_lock;
>
> /* ivhd device data settings */
> --- a/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
> +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-defs.h
> @@ -458,10 +458,6 @@
> #define MAX_AMD_IOMMUS 32
>
> /* interrupt remapping table */
> -#define INT_REMAP_INDEX_DM_MASK 0x1C00
> -#define INT_REMAP_INDEX_DM_SHIFT 10
> -#define INT_REMAP_INDEX_VECTOR_MASK 0x3FC
> -#define INT_REMAP_INDEX_VECTOR_SHIFT 2
> #define INT_REMAP_ENTRY_REMAPEN_MASK 0x00000001
> #define INT_REMAP_ENTRY_REMAPEN_SHIFT 0
> #define INT_REMAP_ENTRY_SUPIOPF_MASK 0x00000002
> --- a/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
> +++ b/xen/include/asm-x86/hvm/svm/amd-iommu-proto.h
> @@ -89,10 +89,12 @@ struct amd_iommu *find_iommu_for_device(
>
> /* interrupt remapping */
> int amd_iommu_setup_ioapic_remapping(void);
> -void *amd_iommu_alloc_intremap_table(void);
> +void *amd_iommu_alloc_intremap_table(unsigned long **);
> int amd_iommu_free_intremap_table(u16 seg, struct ivrs_mappings *);
> void amd_iommu_ioapic_update_ire(
> unsigned int apic, unsigned int reg, unsigned int value);
> +unsigned int amd_iommu_read_ioapic_from_ire(
> + unsigned int apic, unsigned int reg);
> int amd_iommu_msi_msg_update_ire(
> struct msi_desc *msi_desc, struct msi_msg *msg);
> void amd_iommu_read_msi_from_ire(
> @@ -101,15 +103,17 @@ int amd_setup_hpet_msi(struct msi_desc *
>
> extern struct ioapic_sbdf {
> u16 bdf, seg;
> - unsigned long *pin_setup;
> + u16 *pin_2_idx;
> } ioapic_sbdf[MAX_IO_APICS];
> -extern void *shared_intremap_table;
>
> extern struct hpet_sbdf {
> u16 bdf, seg, id;
> struct amd_iommu *iommu;
> } hpet_sbdf;
>
> +extern void *shared_intremap_table;
> +extern unsigned long *shared_intremap_inuse;
> +
> /* power management support */
> void amd_iommu_resume(void);
> void amd_iommu_suspend(void);
>
>
next prev parent reply other threads:[~2013-04-11 0:34 UTC|newest]
Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-03-26 8:51 [PATCH 0/4] x86/IOMMU: multi-vector MSI prerequisites Jan Beulich
2013-03-26 9:03 ` [PATCH 1/4] IOMMU: allow MSI message to IRTE propagation to fail Jan Beulich
2013-03-27 11:45 ` George Dunlap
2013-03-27 12:16 ` Jan Beulich
2013-03-27 14:45 ` Boris Ostrovsky
2013-03-27 14:55 ` George Dunlap
2013-03-28 8:25 ` Jan Beulich
2013-03-28 9:46 ` Tim Deegan
2013-03-28 9:49 ` George Dunlap
2013-03-28 10:33 ` George Dunlap
2013-03-28 11:14 ` Jan Beulich
2013-03-28 11:25 ` Tim Deegan
2013-03-28 11:39 ` George Dunlap
2013-03-28 13:47 ` Stefano Stabellini
2013-05-06 20:25 ` Is: git send-email, patch sending, etc Was: " Konrad Rzeszutek Wilk
2013-05-07 8:53 ` Ian Campbell
2013-05-07 9:26 ` Wei Liu
2013-05-07 14:03 ` Konrad Rzeszutek Wilk
2013-03-27 17:26 ` George Dunlap
2013-03-28 8:27 ` Jan Beulich
2013-03-26 9:03 ` [PATCH 2/4] x86/MSI: cleanup to prepare for multi-vector MSI Jan Beulich
2013-03-26 9:04 ` [PATCH 3/4] AMD IOMMU: allocate IRTE entries instead of using a static mapping Jan Beulich
2013-04-02 8:38 ` [PATCH v2 " Jan Beulich
2013-04-11 0:34 ` Suravee Suthikulpanit [this message]
2013-03-26 9:05 ` [PATCH 4/4] AMD IOMMU: untie remap and vector maps Jan Beulich
2013-03-28 12:37 ` George Dunlap
2013-03-28 13:09 ` Jan Beulich
2013-03-28 13:40 ` George Dunlap
2013-03-29 5:18 ` [PATCH 0/4] x86/IOMMU: multi-vector MSI prerequisites Suravee Suthikulpanit
2013-03-29 5:45 ` Suravee Suthikulpanit
2013-04-02 8:39 ` Jan Beulich
2013-04-10 13:55 ` Jan Beulich
2013-04-10 14:38 ` Suravee Suthikulanit
2013-04-10 14:46 ` Jan Beulich
2013-04-11 1:51 ` Suravee Suthikulpanit
2013-04-11 7:13 ` Jan Beulich
2013-04-11 15:40 ` suravee suthikulpanit
2013-04-11 16:11 ` Jan Beulich
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=51660503.8010107@amd.com \
--to=suravee.suthikulpanit@amd.com \
--cc=JBeulich@suse.com \
--cc=jacob.shin@amd.com \
--cc=xen-devel@lists.xen.org \
--cc=xiantao.zhang@intel.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 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).