All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 0/3] x2APIC improvement
@ 2010-07-05  7:07 Han, Weidong
  2010-07-06 14:49 ` Konrad Rzeszutek Wilk
  2010-07-15  7:56 ` Han, Weidong
  0 siblings, 2 replies; 6+ messages in thread
From: Han, Weidong @ 2010-07-05  7:07 UTC (permalink / raw)
  To: Xen-devel; +Cc: Keir Fraser

The patchset improves Xen x2APIC support. 

Patch 1/3: allocate iommu when create a drhd
	A drhd is created when parse ACPI DMAR table, but drhd->iommu is not allocated until iommu setup. But iommu is needed by x2APIC which will enable interrupt remapping before iommu setup. This patch allocates iommu when create drhd. And then drhd->ecap can be removed because it's the same as iommu->ecap.

Patch 2/3: improve interrupt remapping and queued invalidation enabling and disabling
	x2APIC depends on interrupt remapping, so interrupt remapping needs to be enabled before x2APIC. Usually x2APIC is not enabled (x2apic_enabled=0) when enable interrupt remapping, although x2APIC will be enabled later. So it needs to pass a parameter to set interrupt mode in intremap_enable, instead of checking x2apic_enable. This patch adds a parameter "eim" to intremap_enable to achieve it.
	Interrupt remapping and queued invalidation are already enabled when enable x2apic, so it needn't to enable them again when setup iommu. This patch checks if interrupt remapping and queued invalidation are already enable or not, and won't enable them if already enabled. It does the similar in disabling, that's to say don't disable them if already disabled.

Patch 3/3: improve x2apic enabling logic
	This patch masks PIC and IOAPIC RTE's before x2APIC enabling, unmask and restore them after x2APIC enabling. It also really enables interrupt remapping before x2APIC enabling instead of just checking interrupt remapping setting.
	This patch handles all configuration related to x2APIC. Especially, it handles that BIOS hands over in x2APIC mode (when there is apic id > 255). It checks if x2APIC is already enabled by BIOS. If already enabled, it will disable interrupt remapping and queued invalidation first, then enable them again.


Signed-off-by: Weidong Han <weidong.han@intel.com>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] x2APIC improvement
  2010-07-05  7:07 [PATCH 0/3] x2APIC improvement Han, Weidong
@ 2010-07-06 14:49 ` Konrad Rzeszutek Wilk
  2010-07-07  5:09   ` Weidong Han
  2010-07-15  7:56 ` Han, Weidong
  1 sibling, 1 reply; 6+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-07-06 14:49 UTC (permalink / raw)
  To: Han, Weidong; +Cc: Xen-devel, Keir Fraser

On Mon, Jul 05, 2010 at 03:07:58PM +0800, Han, Weidong wrote:
> The patchset improves Xen x2APIC support. 
> 
> Patch 1/3: allocate iommu when create a drhd
> 	A drhd is created when parse ACPI DMAR table, but drhd->iommu is not allocated until iommu setup. But iommu is needed by x2APIC which will enable interrupt remapping before iommu setup. This patch allocates iommu when create drhd. And then drhd->ecap can be removed because it's the same as iommu->ecap.
> 

Have these patches been tested on a machine where the number of DRHD !=
number of IOAPICs?

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] x2APIC improvement
  2010-07-06 14:49 ` Konrad Rzeszutek Wilk
@ 2010-07-07  5:09   ` Weidong Han
  2010-07-07 13:56     ` Konrad Rzeszutek Wilk
  0 siblings, 1 reply; 6+ messages in thread
From: Weidong Han @ 2010-07-07  5:09 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk; +Cc: Xen-devel, Keir Fraser

Konrad Rzeszutek Wilk wrote:
> On Mon, Jul 05, 2010 at 03:07:58PM +0800, Han, Weidong wrote:
>   
>> The patchset improves Xen x2APIC support. 
>>
>> Patch 1/3: allocate iommu when create a drhd
>> 	A drhd is created when parse ACPI DMAR table, but drhd->iommu is not allocated until iommu setup. But iommu is needed by x2APIC which will enable interrupt remapping before iommu setup. This patch allocates iommu when create drhd. And then drhd->ecap can be removed because it's the same as iommu->ecap.
>>
>>     
>
> Have these patches been tested on a machine where the number of DRHD !=
> number of IOAPICs?
>
>   
Why need to care about number of DRHD != number of IOAPICs? One DRHD may 
cover more than one IOAPICs. And there is already check if all IOAPICs 
have corresponding DRHD.

Regards,
Weidong

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] x2APIC improvement
  2010-07-07  5:09   ` Weidong Han
@ 2010-07-07 13:56     ` Konrad Rzeszutek Wilk
  2010-07-08  2:31       ` Weidong Han
  0 siblings, 1 reply; 6+ messages in thread
From: Konrad Rzeszutek Wilk @ 2010-07-07 13:56 UTC (permalink / raw)
  To: Weidong Han; +Cc: Xen-devel, Keir Fraser

On Wed, Jul 07, 2010 at 01:09:08PM +0800, Weidong Han wrote:
> Konrad Rzeszutek Wilk wrote:
> >On Mon, Jul 05, 2010 at 03:07:58PM +0800, Han, Weidong wrote:
> >>The patchset improves Xen x2APIC support.
> >>
> >>Patch 1/3: allocate iommu when create a drhd
> >>	A drhd is created when parse ACPI DMAR table, but drhd->iommu is not allocated until iommu setup. But iommu is needed by x2APIC which will enable interrupt remapping before iommu setup. This patch allocates iommu when create drhd. And then drhd->ecap can be removed because it's the same as iommu->ecap.
> >>
> >
> >Have these patches been tested on a machine where the number of DRHD !=
> >number of IOAPICs?
> >
> Why need to care about number of DRHD != number of IOAPICs? One DRHD
> may cover more than one IOAPICs. And there is already check if all

And the inverse might be true as well - in which case we should disable
x2APIC.

> IOAPICs have corresponding DRHD.

I understand. I am asking whether these patches have not changed that
behavior and whether you have tested for that.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH 0/3] x2APIC improvement
  2010-07-07 13:56     ` Konrad Rzeszutek Wilk
@ 2010-07-08  2:31       ` Weidong Han
  0 siblings, 0 replies; 6+ messages in thread
From: Weidong Han @ 2010-07-08  2:31 UTC (permalink / raw)
  To: Konrad Rzeszutek Wilk; +Cc: Xen-devel, Keir Fraser

Konrad Rzeszutek Wilk wrote:
> On Wed, Jul 07, 2010 at 01:09:08PM +0800, Weidong Han wrote:
>   
>> Konrad Rzeszutek Wilk wrote:
>>     
>>> On Mon, Jul 05, 2010 at 03:07:58PM +0800, Han, Weidong wrote:
>>>       
>>>> The patchset improves Xen x2APIC support.
>>>>
>>>> Patch 1/3: allocate iommu when create a drhd
>>>> 	A drhd is created when parse ACPI DMAR table, but drhd->iommu is not allocated until iommu setup. But iommu is needed by x2APIC which will enable interrupt remapping before iommu setup. This patch allocates iommu when create drhd. And then drhd->ecap can be removed because it's the same as iommu->ecap.
>>>>
>>>>         
>>> Have these patches been tested on a machine where the number of DRHD !=
>>> number of IOAPICs?
>>>
>>>       
>> Why need to care about number of DRHD != number of IOAPICs? One DRHD
>> may cover more than one IOAPICs. And there is already check if all
>>     
>
> And the inverse might be true as well - in which case we should disable
> x2APIC.
>
>   
Each IOAPIC must have a corresponding DRHD, but a DRHD maybe don't have 
a IOAPIC in its device scope. So it won't enable x2APIC if there is any 
IOAPIC which doesn't have corresponding DRHD.
>> IOAPICs have corresponding DRHD.
>>     
>
> I understand. I am asking whether these patches have not changed that
> behavior and whether you have tested for that.
>   
These patches don't change that behavior.

Regards,
Weidong

^ permalink raw reply	[flat|nested] 6+ messages in thread

* RE: [PATCH 0/3] x2APIC improvement
  2010-07-05  7:07 [PATCH 0/3] x2APIC improvement Han, Weidong
  2010-07-06 14:49 ` Konrad Rzeszutek Wilk
@ 2010-07-15  7:56 ` Han, Weidong
  1 sibling, 0 replies; 6+ messages in thread
From: Han, Weidong @ 2010-07-15  7:56 UTC (permalink / raw)
  To: Xen-devel; +Cc: Keir Fraser

[-- Attachment #1: Type: text/plain, Size: 2552 bytes --]

Hi Keir,

In order to support that BIOS hands over in x2APIC mode, these patches are necessary. So it's better to also back port them to xen 4.0. I already ported these patches to xen-4.0-testing tree, pls check them in. Thanks.

Regards,
Weidong

-----Original Message-----
From: xen-devel-bounces@lists.xensource.com [mailto:xen-devel-bounces@lists.xensource.com] On Behalf Of Han, Weidong
Sent: Monday, July 05, 2010 3:08 PM
To: Xen-devel
Cc: Keir Fraser
Subject: [Xen-devel] [PATCH 0/3] x2APIC improvement

The patchset improves Xen x2APIC support. 

Patch 1/3: allocate iommu when create a drhd
	A drhd is created when parse ACPI DMAR table, but drhd->iommu is not allocated until iommu setup. But iommu is needed by x2APIC which will enable interrupt remapping before iommu setup. This patch allocates iommu when create drhd. And then drhd->ecap can be removed because it's the same as iommu->ecap.

Patch 2/3: improve interrupt remapping and queued invalidation enabling and disabling
	x2APIC depends on interrupt remapping, so interrupt remapping needs to be enabled before x2APIC. Usually x2APIC is not enabled (x2apic_enabled=0) when enable interrupt remapping, although x2APIC will be enabled later. So it needs to pass a parameter to set interrupt mode in intremap_enable, instead of checking x2apic_enable. This patch adds a parameter "eim" to intremap_enable to achieve it.
	Interrupt remapping and queued invalidation are already enabled when enable x2apic, so it needn't to enable them again when setup iommu. This patch checks if interrupt remapping and queued invalidation are already enable or not, and won't enable them if already enabled. It does the similar in disabling, that's to say don't disable them if already disabled.

Patch 3/3: improve x2apic enabling logic
	This patch masks PIC and IOAPIC RTE's before x2APIC enabling, unmask and restore them after x2APIC enabling. It also really enables interrupt remapping before x2APIC enabling instead of just checking interrupt remapping setting.
	This patch handles all configuration related to x2APIC. Especially, it handles that BIOS hands over in x2APIC mode (when there is apic id > 255). It checks if x2APIC is already enabled by BIOS. If already enabled, it will disable interrupt remapping and queued invalidation first, then enable them again.


Signed-off-by: Weidong Han <weidong.han@intel.com>

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

[-- Attachment #2: iommu-alloc-xen4.0.patch --]
[-- Type: application/octet-stream, Size: 6113 bytes --]

diff -r 24f2bc79eb23 xen/drivers/passthrough/vtd/dmar.c
--- a/xen/drivers/passthrough/vtd/dmar.c	Wed Jul 14 21:24:48 2010 +0800
+++ b/xen/drivers/passthrough/vtd/dmar.c	Wed Jul 14 21:25:25 2010 +0800
@@ -32,6 +32,7 @@
 #include "dmar.h"
 #include "iommu.h"
 #include "extern.h"
+#include "vtd.h"
 
 #undef PREFIX
 #define PREFIX VTDPREFIX "ACPI DMAR:"
@@ -378,7 +379,6 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
     struct acpi_table_drhd * drhd = (struct acpi_table_drhd *)header;
     void *dev_scope_start, *dev_scope_end;
     struct acpi_drhd_unit *dmaru;
-    void *addr;
     int ret;
     static int include_all = 0;
 
@@ -397,8 +397,9 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
         dprintk(VTDPREFIX, "  dmaru->address = %"PRIx64"\n",
                 dmaru->address);
 
-    addr = map_to_nocache_virt(0, drhd->address);
-    dmaru->ecap = dmar_readq(addr, DMAR_ECAP_REG);
+    ret = iommu_alloc(dmaru);
+    if ( ret )
+        goto out;
 
     dev_scope_start = (void *)(drhd + 1);
     dev_scope_end = ((void *)drhd) + header->length;
@@ -420,7 +421,7 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
     }
 
     if ( ret )
-        xfree(dmaru);
+        goto out;
     else if ( force_iommu || dmaru->include_all )
         acpi_register_drhd_unit(dmaru);
     else
@@ -451,14 +452,15 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
 
         if ( invalid_cnt )
         {
-            xfree(dmaru);
-
             if ( iommu_workaround_bios_bug &&
                  invalid_cnt == dmaru->scope.devices_cnt )
             {
                 dprintk(XENLOG_WARNING VTDPREFIX,
                     "  Workaround BIOS bug: ignore the DRHD due to all "
                     "devices under its scope are not PCI discoverable!\n");
+
+                iommu_free(dmaru);
+                xfree(dmaru);
             }
             else
             {
@@ -474,6 +476,12 @@ acpi_parse_one_drhd(struct acpi_dmar_ent
             acpi_register_drhd_unit(dmaru);
     }
 
+out:
+    if ( ret )
+    {
+        iommu_free(dmaru);
+        xfree(dmaru);
+    }
     return ret;
 }
 
diff -r 24f2bc79eb23 xen/drivers/passthrough/vtd/dmar.h
--- a/xen/drivers/passthrough/vtd/dmar.h	Wed Jul 14 21:24:48 2010 +0800
+++ b/xen/drivers/passthrough/vtd/dmar.h	Wed Jul 14 21:25:25 2010 +0800
@@ -50,7 +50,6 @@ struct acpi_drhd_unit {
     struct dmar_scope scope;            /* must be first member of struct */
     struct list_head list;
     u64    address;                     /* register base address of the unit */
-    u64    ecap;
     u8     include_all:1;
     struct iommu *iommu;
     struct list_head ioapic_list;
diff -r 24f2bc79eb23 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c	Wed Jul 14 21:24:48 2010 +0800
+++ b/xen/drivers/passthrough/vtd/intremap.c	Wed Jul 14 21:25:25 2010 +0800
@@ -135,15 +135,20 @@ int iommu_supports_eim(void)
     /* We MUST have a DRHD unit for each IOAPIC. */
     for ( apic = 0; apic < nr_ioapics; apic++ )
         if ( !ioapic_to_drhd(IO_APIC_ID(apic)) )
+    {
+            dprintk(XENLOG_WARNING VTDPREFIX,
+                    "There is not a DRHD for IOAPIC 0x%x (id: 0x%x)!\n",
+                    apic, IO_APIC_ID(apic));
             return 0;
+    }
 
     if ( list_empty(&acpi_drhd_units) )
         return 0;
 
     for_each_drhd_unit ( drhd )
-        if ( !ecap_queued_inval(drhd->ecap) ||
-             !ecap_intr_remap(drhd->ecap) ||
-             !ecap_eim(drhd->ecap) )
+        if ( !ecap_queued_inval(drhd->iommu->ecap) ||
+             !ecap_intr_remap(drhd->iommu->ecap) ||
+             !ecap_eim(drhd->iommu->ecap) )
             return 0;
 
     return 1;
diff -r 24f2bc79eb23 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c	Wed Jul 14 21:24:48 2010 +0800
+++ b/xen/drivers/passthrough/vtd/iommu.c	Wed Jul 14 21:27:05 2010 +0800
@@ -143,14 +143,17 @@ struct iommu_flush *iommu_get_flush(stru
     return iommu ? &iommu->intel->flush : NULL;
 }
 
-static unsigned int clflush_size;
 static int iommus_incoherent;
 static void __iommu_flush_cache(void *addr, unsigned int size)
 {
     int i;
+    static unsigned int clflush_size = 0;
 
     if ( !iommus_incoherent )
         return;
+
+    if ( clflush_size == 0 )
+        clflush_size = get_cache_line_size();
 
     for ( i = 0; i < size; i += clflush_size )
         cacheline_flush((char *)addr + i);
@@ -1036,7 +1039,7 @@ static int iommu_set_interrupt(struct io
     return irq;
 }
 
-static int iommu_alloc(struct acpi_drhd_unit *drhd)
+int __init iommu_alloc(struct acpi_drhd_unit *drhd)
 {
     struct iommu *iommu;
     unsigned long sagaw, nr_dom;
@@ -1130,7 +1133,7 @@ static int iommu_alloc(struct acpi_drhd_
     return 0;
 }
 
-static void iommu_free(struct acpi_drhd_unit *drhd)
+void __init iommu_free(struct acpi_drhd_unit *drhd)
 {
     struct iommu *iommu = drhd->iommu;
 
@@ -1938,8 +1941,6 @@ int intel_vtd_setup(void)
 
     platform_quirks();
 
-    clflush_size = get_cache_line_size();
-
     irq_to_iommu = xmalloc_array(struct iommu*, nr_irqs);
     BUG_ON(!irq_to_iommu);
     memset(irq_to_iommu, 0, nr_irqs * sizeof(struct iommu*));
@@ -1953,9 +1954,6 @@ int intel_vtd_setup(void)
      */
     for_each_drhd_unit ( drhd )
     {
-        if ( iommu_alloc(drhd) != 0 )
-            goto error;
-
         iommu = drhd->iommu;
 
         if ( iommu_snoop && !ecap_snp_ctl(iommu->ecap) )
@@ -1995,8 +1993,6 @@ int intel_vtd_setup(void)
     return 0;
 
  error:
-    for_each_drhd_unit ( drhd )
-        iommu_free(drhd);
     iommu_enabled = 0;
     iommu_snoop = 0;
     iommu_passthrough = 0;
diff -r 24f2bc79eb23 xen/drivers/passthrough/vtd/vtd.h
--- a/xen/drivers/passthrough/vtd/vtd.h	Wed Jul 14 21:24:48 2010 +0800
+++ b/xen/drivers/passthrough/vtd/vtd.h	Wed Jul 14 21:25:25 2010 +0800
@@ -108,4 +108,7 @@ void iommu_flush_cache_entry(void *addr,
 void iommu_flush_cache_entry(void *addr, unsigned int size);
 void iommu_flush_cache_page(void *addr, unsigned long npages);
 
+int iommu_alloc(struct acpi_drhd_unit *drhd);
+void iommu_free(struct acpi_drhd_unit *drhd);
+
 #endif // _VTD_H_

[-- Attachment #3: ir-qi-xen4.0.patch --]
[-- Type: application/octet-stream, Size: 6250 bytes --]

diff -r 53536a779c06 xen/drivers/passthrough/vtd/extern.h
--- a/xen/drivers/passthrough/vtd/extern.h	Thu Jul 01 15:54:51 2010 +0800
+++ b/xen/drivers/passthrough/vtd/extern.h	Fri Jul 02 17:52:29 2010 +0800
@@ -33,7 +33,7 @@ extern struct keyhandler dump_iommu_info
 
 int enable_qinval(struct iommu *iommu);
 void disable_qinval(struct iommu *iommu);
-int enable_intremap(struct iommu *iommu);
+int enable_intremap(struct iommu *iommu, int eim);
 void disable_intremap(struct iommu *iommu);
 int queue_invalidate_context(struct iommu *iommu,
     u16 did, u16 source_id, u8 function_mask, u8 granu);
diff -r 53536a779c06 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c	Thu Jul 01 15:54:51 2010 +0800
+++ b/xen/drivers/passthrough/vtd/intremap.c	Fri Jul 02 18:03:28 2010 +0800
@@ -711,7 +711,7 @@ void msi_msg_write_remap_rte(
 }
 #endif
 
-int enable_intremap(struct iommu *iommu)
+int enable_intremap(struct iommu *iommu, int eim)
 {
     struct acpi_drhd_unit *drhd;
     struct ir_ctrl *ir_ctrl;
@@ -721,10 +721,25 @@ int enable_intremap(struct iommu *iommu)
     ASSERT(ecap_intr_remap(iommu->ecap) && iommu_intremap);
 
     ir_ctrl = iommu_ir_ctrl(iommu);
+    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+
+    /* Return if already enabled by Xen */
+    if ( (sts & DMA_GSTS_IRES) && ir_ctrl->iremap_maddr )
+        return 0;
+
+    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    if ( !(sts & DMA_GSTS_QIES) )
+    {
+        dprintk(XENLOG_ERR VTDPREFIX,
+                "Queued invalidation is not enabled, should not enable "
+                "interrupt remapping\n");
+        return -EINVAL;
+    }
+
     if ( ir_ctrl->iremap_maddr == 0 )
     {
         drhd = iommu_to_drhd(iommu);
-        ir_ctrl->iremap_maddr = alloc_pgtable_maddr(drhd, IREMAP_ARCH_PAGE_NR );
+        ir_ctrl->iremap_maddr = alloc_pgtable_maddr(drhd, IREMAP_ARCH_PAGE_NR);
         if ( ir_ctrl->iremap_maddr == 0 )
         {
             dprintk(XENLOG_WARNING VTDPREFIX,
@@ -737,7 +752,7 @@ int enable_intremap(struct iommu *iommu)
 #ifdef CONFIG_X86
     /* set extended interrupt mode bit */
     ir_ctrl->iremap_maddr |=
-            x2apic_enabled ? (1 << IRTA_REG_EIME_SHIFT) : 0;
+            eim ? (1 << IRTA_REG_EIME_SHIFT) : 0;
 #endif
     spin_lock_irqsave(&iommu->register_lock, flags);
 
@@ -774,13 +789,18 @@ void disable_intremap(struct iommu *iomm
     u32 sts;
     unsigned long flags;
 
-    ASSERT(ecap_intr_remap(iommu->ecap) && iommu_intremap);
+    if ( !ecap_intr_remap(iommu->ecap) )
+        return;
 
     spin_lock_irqsave(&iommu->register_lock, flags);
     sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    if ( !(sts & DMA_GSTS_IRES) )
+        goto out;
+
     dmar_writel(iommu->reg, DMAR_GCMD_REG, sts & (~DMA_GCMD_IRE));
 
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
                   !(sts & DMA_GSTS_IRES), sts);
+out:
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
diff -r 53536a779c06 xen/drivers/passthrough/vtd/iommu.c
--- a/xen/drivers/passthrough/vtd/iommu.c	Thu Jul 01 15:54:51 2010 +0800
+++ b/xen/drivers/passthrough/vtd/iommu.c	Fri Jul 02 17:52:30 2010 +0800
@@ -1834,24 +1834,20 @@ static int init_vtd_hw(void)
         spin_lock_irqsave(&iommu->register_lock, flags);
         dmar_writel(iommu->reg, DMAR_FECTL_REG, 0);
         spin_unlock_irqrestore(&iommu->register_lock, flags);
-
-        /* initialize flush functions */
-        flush = iommu_get_flush(iommu);
-        flush->context = flush_context_reg;
-        flush->iotlb = flush_iotlb_reg;
-    }
-
-    if ( iommu_qinval )
-    {
-        for_each_drhd_unit ( drhd )
-        {
-            iommu = drhd->iommu;
-            if ( enable_qinval(iommu) != 0 )
-            {
-                dprintk(XENLOG_INFO VTDPREFIX,
-                        "Failed to enable Queued Invalidation!\n");
-                break;
-            }
+    }
+
+    for_each_drhd_unit ( drhd )
+    {
+        iommu = drhd->iommu;
+        /*
+         * If queued invalidation not enabled, use regiser based
+         * invalidation
+         */
+        if ( enable_qinval(iommu) != 0 )
+        {
+            flush = iommu_get_flush(iommu);
+            flush->context = flush_context_reg;
+            flush->iotlb = flush_iotlb_reg;
         }
     }
 
@@ -1877,9 +1873,9 @@ static int init_vtd_hw(void)
         for_each_drhd_unit ( drhd )
         {
             iommu = drhd->iommu;
-            if ( enable_intremap(iommu) != 0 )
+            if ( enable_intremap(iommu, 0) != 0 )
             {
-                dprintk(XENLOG_INFO VTDPREFIX,
+                dprintk(XENLOG_WARNING VTDPREFIX,
                         "Failed to enable Interrupt Remapping!\n");
                 break;
             }
diff -r 53536a779c06 xen/drivers/passthrough/vtd/qinval.c
--- a/xen/drivers/passthrough/vtd/qinval.c	Thu Jul 01 15:54:51 2010 +0800
+++ b/xen/drivers/passthrough/vtd/qinval.c	Fri Jul 02 18:03:15 2010 +0800
@@ -437,10 +437,16 @@ int enable_qinval(struct iommu *iommu)
     u32 sts;
     unsigned long flags;
 
+    if ( !ecap_queued_inval(iommu->ecap) || !iommu_qinval )
+        return -ENOENT;
+
     qi_ctrl = iommu_qi_ctrl(iommu);
     flush = iommu_get_flush(iommu);
 
-    ASSERT(ecap_queued_inval(iommu->ecap) && iommu_qinval);
+    /* Return if already enabled by Xen */
+    sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    if ( (sts & DMA_GSTS_QIES) && qi_ctrl->qinval_maddr )
+        return 0;
 
     if ( qi_ctrl->qinval_maddr == 0 )
     {
@@ -488,14 +494,19 @@ void disable_qinval(struct iommu *iommu)
     u32 sts;
     unsigned long flags;
 
-    ASSERT(ecap_queued_inval(iommu->ecap) && iommu_qinval);
+    if ( !ecap_queued_inval(iommu->ecap) )
+        return;
 
     spin_lock_irqsave(&iommu->register_lock, flags);
     sts = dmar_readl(iommu->reg, DMAR_GSTS_REG);
+    if ( !(sts & DMA_GSTS_QIES) )
+        goto out;
+
     dmar_writel(iommu->reg, DMAR_GCMD_REG, sts & (~DMA_GCMD_QIE));
 
     /* Make sure hardware complete it */
     IOMMU_WAIT_OP(iommu, DMAR_GSTS_REG, dmar_readl,
                   !(sts & DMA_GSTS_QIES), sts);
-    spin_unlock_irqrestore(&iommu->register_lock, flags);
-}
+out:
+    spin_unlock_irqrestore(&iommu->register_lock, flags);
+}

[-- Attachment #4: x2apic-logic-xen4.0.patch --]
[-- Type: application/octet-stream, Size: 18140 bytes --]

diff -r 1a1a7b7c39e2 xen/arch/x86/apic.c
--- a/xen/arch/x86/apic.c	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/arch/x86/apic.c	Thu Jul 15 09:28:13 2010 +0800
@@ -70,6 +70,9 @@ int x2apic_enabled __read_mostly = 0;
 int x2apic_enabled __read_mostly = 0;
 int directed_eoi_enabled __read_mostly = 0;
 
+/* x2APIC is enabled in BIOS */
+static int x2apic_preenabled;
+
 /*
  * The following vectors are part of the Linux architecture, there
  * is no hardware IRQ pin equivalent for them, they are triggered
@@ -488,6 +491,47 @@ static void apic_pm_activate(void)
 static void apic_pm_activate(void)
 {
     apic_pm_state.active = 1;
+}
+
+static void resume_x2apic(void)
+{
+    uint64_t msr_content;
+    struct IO_APIC_route_entry **ioapic_entries = NULL;
+
+    ASSERT(x2apic_enabled);
+
+    ioapic_entries = alloc_ioapic_entries();
+    if ( !ioapic_entries )
+    {
+        printk("Allocate ioapic_entries failed\n");
+        goto out;
+    }
+
+    if ( save_IO_APIC_setup(ioapic_entries) )
+    {
+        printk("Saving IO-APIC state failed\n");
+        goto out;
+    }
+
+    mask_8259A();
+    mask_IO_APIC_setup(ioapic_entries);
+
+    iommu_enable_IR();
+
+    rdmsrl(MSR_IA32_APICBASE, msr_content);
+    if ( !(msr_content & MSR_IA32_APICBASE_EXTD) )
+    {
+        msr_content |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD;
+        msr_content = (uint32_t)msr_content;
+        wrmsrl(MSR_IA32_APICBASE, msr_content);
+    }
+
+    restore_IO_APIC_setup(ioapic_entries);
+    unmask_8259A();
+
+out:
+    if ( ioapic_entries )
+        free_ioapic_entries(ioapic_entries);
 }
 
 void __devinit setup_local_APIC(void)
@@ -728,7 +772,7 @@ int lapic_resume(void)
         wrmsr(MSR_IA32_APICBASE, l, h);
     }
     else
-        enable_x2apic();
+        resume_x2apic();
 
     apic_write(APIC_LVTERR, ERROR_APIC_VECTOR | APIC_LVT_MASKED);
     apic_write(APIC_ID, apic_pm_state.apic_id);
@@ -892,45 +936,152 @@ no_apic:
     return -1;
 }
 
-void enable_x2apic(void)
+void check_x2apic_preenabled(void)
 {
     u32 lo, hi;
 
-    if ( smp_processor_id() == 0 )
+    if ( !x2apic_is_available() )
+        return;
+
+    rdmsr(MSR_IA32_APICBASE, lo, hi);
+    if ( lo & MSR_IA32_APICBASE_EXTD )
     {
-        if ( !iommu_supports_eim() )
+        printk("x2APIC mode is already enabled by BIOS.\n");
+        x2apic_preenabled = 1;
+        x2apic_enabled = 1;
+    }
+}
+
+static void enable_bsp_x2apic(void)
+{
+    struct IO_APIC_route_entry **ioapic_entries = NULL;
+    const struct genapic *x2apic_genapic = NULL;
+
+    ASSERT(smp_processor_id() == 0);
+
+    if ( x2apic_preenabled )
+    {
+        /*
+         * Interrupt remapping should be also enabled by BIOS when
+         * x2APIC is already enabled by BIOS, otherwise it's a BIOS
+         * bug
+         */
+        if ( !intremap_enabled() )
+            panic("Interrupt remapping is not enabled by BIOS while "
+                  "x2APIC is already enabled by BIOS!\n");
+    }
+
+    x2apic_genapic = apic_x2apic_probe();
+    if ( x2apic_genapic )
+        genapic = x2apic_genapic;
+    else
+    {
+        if ( x2apic_cmdline_disable() )
         {
-            printk("x2APIC would not be enabled without EIM.\n");
-            return;
+            if ( x2apic_preenabled )
+            {
+                /* Ignore x2apic=0, and set default x2apic mode */
+                genapic = &apic_x2apic_cluster;
+                printk("x2APIC: already enabled by BIOS, ignore x2apic=0.\n");
+            }
+            else
+            {
+                printk("Not enable x2APIC due to x2apic=0 is set.\n");
+                return;
+            }
         }
-
-        if ( apic_x2apic_phys.probe() )
-            genapic = &apic_x2apic_phys;
-        else if ( apic_x2apic_cluster.probe() )
-            genapic = &apic_x2apic_cluster;
         else
         {
-            printk("x2APIC would not be enabled due to x2apic=off.\n");
-            return;
+            if ( !iommu_enabled || !iommu_intremap || !iommu_qinval )
+                panic("Cannot enable x2APIC due to iommu or interrupt "
+                      "remapping or queued invalidation is disabled "
+                      "by command line!\n");
+            else
+            {
+                if ( x2apic_preenabled )
+                    panic("x2APIC: already enabled by BIOS, but "
+                          "iommu_supports_eim fails\n");
+                else
+                {
+                    printk("Not enable x2APIC due to "
+                           "iommu_supports_eim fails!\n");
+                    return;
+                }
+            }
         }
-
-        x2apic_enabled = 1;
-        printk("Switched to APIC driver %s.\n", genapic->name);
-    }
-    else
+    }
+
+    ioapic_entries = alloc_ioapic_entries();
+    if ( !ioapic_entries )
     {
-        BUG_ON(!x2apic_enabled); /* APs only enable x2apic when BSP did so. */
-    }
+        printk("Allocate ioapic_entries failed\n");
+        goto out;
+    }
+
+    if ( save_IO_APIC_setup(ioapic_entries) )
+    {
+        printk("Saving IO-APIC state failed\n");
+        goto out;
+    }
+
+    mask_8259A();
+    mask_IO_APIC_setup(ioapic_entries);
+
+    if ( iommu_enable_IR() )
+    {
+        printk("Would not enable x2APIC due to interrupt remapping "
+               "cannot be enabled.\n");
+        goto restore_out;
+    }
+
+    x2apic_enabled = 1;
+    printk("Switched to APIC driver %s.\n", genapic->name);
+
+    if ( !x2apic_preenabled )
+    {
+        u32 lo, hi;
+
+        rdmsr(MSR_IA32_APICBASE, lo, hi);
+        if ( !(lo & MSR_IA32_APICBASE_EXTD) )
+        {
+            lo |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD;
+            wrmsr(MSR_IA32_APICBASE, lo, 0);
+            printk("x2APIC mode enabled.\n");
+        }
+    }
+
+restore_out:
+    restore_IO_APIC_setup(ioapic_entries);
+    unmask_8259A();
+
+out:
+    if ( ioapic_entries )
+        free_ioapic_entries(ioapic_entries);
+}
+
+static void enable_ap_x2apic(void)
+{
+    u32 lo, hi;
+
+    ASSERT(smp_processor_id() != 0);
+
+    /* APs only enable x2apic when BSP did so. */
+    BUG_ON(!x2apic_enabled);
 
     rdmsr(MSR_IA32_APICBASE, lo, hi);
     if ( !(lo & MSR_IA32_APICBASE_EXTD) )
     {
         lo |= MSR_IA32_APICBASE_ENABLE | MSR_IA32_APICBASE_EXTD;
         wrmsr(MSR_IA32_APICBASE, lo, 0);
-        printk("x2APIC mode enabled.\n");
-    }
+    }
+}
+
+void enable_x2apic(void)
+{
+    if ( smp_processor_id() == 0 )
+        enable_bsp_x2apic();
     else
-        printk("x2APIC mode enabled by BIOS.\n");
+        enable_ap_x2apic();
 }
 
 void __init init_apic_mappings(void)
diff -r 1a1a7b7c39e2 xen/arch/x86/genapic/x2apic.c
--- a/xen/arch/x86/genapic/x2apic.c	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/arch/x86/genapic/x2apic.c	Wed Jul 14 21:33:59 2010 +0800
@@ -29,6 +29,11 @@ static int  x2apic_phys; /* By default w
 static int  x2apic_phys; /* By default we use logical cluster mode. */
 boolean_param("x2apic_phys", x2apic_phys);
 
+int x2apic_cmdline_disable(void)
+{
+    return (x2apic == 0);
+}
+
 static int probe_x2apic_phys(void)
 {
     return x2apic && x2apic_phys && x2apic_is_available() &&
@@ -50,6 +55,20 @@ const struct genapic apic_x2apic_cluster
     APIC_INIT("x2apic_cluster", probe_x2apic_cluster),
     GENAPIC_X2APIC_CLUSTER
 };
+
+const struct genapic *apic_x2apic_probe(void)
+{
+    if ( !x2apic || !x2apic_is_available() )
+        return NULL;
+
+    if ( !iommu_supports_eim() )
+        return NULL;
+
+    if ( x2apic_phys )
+        return &apic_x2apic_phys;
+    else
+        return &apic_x2apic_cluster;
+}
 
 void init_apic_ldr_x2apic_phys(void)
 {
diff -r 1a1a7b7c39e2 xen/arch/x86/i8259.c
--- a/xen/arch/x86/i8259.c	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/arch/x86/i8259.c	Wed Jul 14 21:33:59 2010 +0800
@@ -173,6 +173,26 @@ int i8259A_irq_pending(unsigned int irq)
     spin_unlock_irqrestore(&i8259A_lock, flags);
 
     return ret;
+}
+
+void mask_8259A(void)
+{
+    unsigned long flags;
+
+    spin_lock_irqsave(&i8259A_lock, flags);
+    outb(0xff, 0xA1);
+    outb(0xff, 0x21);
+    spin_unlock_irqrestore(&i8259A_lock, flags);
+}
+
+void unmask_8259A(void)
+{
+    unsigned long flags;
+
+    spin_lock_irqsave(&i8259A_lock, flags);
+    outb(cached_A1, 0xA1);
+    outb(cached_21, 0x21);
+    spin_unlock_irqrestore(&i8259A_lock, flags);
 }
 
 /*
diff -r 1a1a7b7c39e2 xen/arch/x86/io_apic.c
--- a/xen/arch/x86/io_apic.c	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/arch/x86/io_apic.c	Wed Jul 14 21:33:59 2010 +0800
@@ -134,6 +134,126 @@ static void __init replace_pin_at_irq(un
             break;
         entry = irq_2_pin + entry->next;
     }
+}
+
+struct IO_APIC_route_entry **alloc_ioapic_entries(void)
+{
+    int apic;
+    struct IO_APIC_route_entry **ioapic_entries;
+
+    ioapic_entries = xmalloc_array(struct IO_APIC_route_entry *, nr_ioapics);
+    if (!ioapic_entries)
+        return 0;
+
+    for (apic = 0; apic < nr_ioapics; apic++) {
+        ioapic_entries[apic] =
+            xmalloc_array(struct IO_APIC_route_entry,
+                          nr_ioapic_registers[apic]);
+        if (!ioapic_entries[apic])
+            goto nomem;
+    }
+
+    return ioapic_entries;
+
+nomem:
+    while (--apic >= 0)
+        xfree(ioapic_entries[apic]);
+    xfree(ioapic_entries);
+
+    return 0;
+}
+
+/*
+ * Saves all the IO-APIC RTE's
+ */
+int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+{
+    int apic, pin;
+
+    if (!ioapic_entries)
+        return -ENOMEM;
+
+    for (apic = 0; apic < nr_ioapics; apic++) {
+        if (!ioapic_entries[apic])
+            return -ENOMEM;
+
+        for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+            *(((int *)&ioapic_entries[apic][pin])+0) =
+                __io_apic_read(apic, 0x10+pin*2);
+            *(((int *)&ioapic_entries[apic][pin])+1) =
+                __io_apic_read(apic, 0x11+pin*2);
+        }
+    }
+
+    return 0;
+}
+
+/*
+ * Mask all IO APIC entries.
+ */
+void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+{
+    int apic, pin;
+
+    if (!ioapic_entries)
+        return;
+
+    for (apic = 0; apic < nr_ioapics; apic++) {
+        if (!ioapic_entries[apic])
+            break;
+
+        for (pin = 0; pin < nr_ioapic_registers[apic]; pin++) {
+            struct IO_APIC_route_entry entry;
+            unsigned long flags;
+
+            entry = ioapic_entries[apic][pin];
+            if (!entry.mask) {
+                entry.mask = 1;
+
+                spin_lock_irqsave(&ioapic_lock, flags);
+                __io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
+                __io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
+                spin_unlock_irqrestore(&ioapic_lock, flags);
+            }
+        }
+    }
+}
+
+/*
+ * Restore IO APIC entries which was saved in ioapic_entries.
+ */
+int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries)
+{
+    int apic, pin;
+    unsigned long flags;
+    struct IO_APIC_route_entry entry;
+
+    if (!ioapic_entries)
+        return -ENOMEM;
+
+    for (apic = 0; apic < nr_ioapics; apic++) {
+        if (!ioapic_entries[apic])
+            return -ENOMEM;
+
+        for (pin = 0; pin < nr_ioapic_registers[apic]; pin++)
+            entry = ioapic_entries[apic][pin];
+            spin_lock_irqsave(&ioapic_lock, flags);
+            __io_apic_write(apic, 0x11+2*pin, *(((int *)&entry)+1));
+            __io_apic_write(apic, 0x10+2*pin, *(((int *)&entry)+0));
+            spin_unlock_irqrestore(&ioapic_lock, flags);
+    }
+
+    return 0;
+}
+
+void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries)
+{
+    int apic;
+
+    for (apic = 0; apic < nr_ioapics; apic++)
+        xfree(ioapic_entries[apic]);
+
+    xfree(ioapic_entries);
 }
 
 static void __modify_IO_APIC_irq (unsigned int irq, unsigned long enable, unsigned long disable)
diff -r 1a1a7b7c39e2 xen/arch/x86/setup.c
--- a/xen/arch/x86/setup.c	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/arch/x86/setup.c	Wed Jul 14 21:33:59 2010 +0800
@@ -979,6 +979,9 @@ void __init __start_xen(unsigned long mb
 
     tboot_probe();
 
+    /* Check if x2APIC is already enabled in BIOS */
+    check_x2apic_preenabled();
+
     /* Unmap the first page of CPU0's stack. */
     memguard_guard_stack(cpu0_stack);
 
@@ -996,9 +999,6 @@ void __init __start_xen(unsigned long mb
     generic_apic_probe();
 
     acpi_boot_init();
-
-    if ( x2apic_is_available() )
-        enable_x2apic();
 
     init_cpu_to_node();
 
@@ -1011,6 +1011,9 @@ void __init __start_xen(unsigned long mb
 #endif
 
     init_apic_mappings();
+
+    if ( x2apic_is_available() )
+        enable_x2apic();
 
     percpu_free_unused_areas();
 
diff -r 1a1a7b7c39e2 xen/drivers/passthrough/vtd/intremap.c
--- a/xen/drivers/passthrough/vtd/intremap.c	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/drivers/passthrough/vtd/intremap.c	Wed Jul 14 21:33:59 2010 +0800
@@ -132,6 +132,12 @@ int iommu_supports_eim(void)
     if ( !iommu_enabled || !iommu_qinval || !iommu_intremap )
         return 0;
 
+    if ( list_empty(&acpi_drhd_units) )
+    {
+        dprintk(XENLOG_WARNING VTDPREFIX, "VT-d is not supported\n");
+        return 0;
+    }
+
     /* We MUST have a DRHD unit for each IOAPIC. */
     for ( apic = 0; apic < nr_ioapics; apic++ )
         if ( !ioapic_to_drhd(IO_APIC_ID(apic)) )
@@ -141,9 +147,6 @@ int iommu_supports_eim(void)
                     apic, IO_APIC_ID(apic));
             return 0;
     }
-
-    if ( list_empty(&acpi_drhd_units) )
-        return 0;
 
     for_each_drhd_unit ( drhd )
         if ( !ecap_queued_inval(drhd->iommu->ecap) ||
@@ -802,3 +805,80 @@ out:
 out:
     spin_unlock_irqrestore(&iommu->register_lock, flags);
 }
+
+/*
+ * This function is used to enable Interrutp remapping when
+ * enable x2apic
+ */
+int iommu_enable_IR(void)
+{
+    struct acpi_drhd_unit *drhd;
+    struct iommu *iommu;
+
+    if ( !iommu_supports_eim() )
+        return -1;
+
+    for_each_drhd_unit ( drhd )
+    {
+        struct qi_ctrl *qi_ctrl = NULL;
+
+        iommu = drhd->iommu;
+        qi_ctrl = iommu_qi_ctrl(iommu);
+
+        /* Clear previous faults */
+        clear_fault_bits(iommu);
+
+        /*
+         * Disable interrupt remapping and queued invalidation if
+         * already enabled by BIOS
+         */
+        disable_intremap(iommu);
+        disable_qinval(iommu);
+    }
+
+    /* Enable queue invalidation */
+    for_each_drhd_unit ( drhd )
+    {
+        iommu = drhd->iommu;
+        if ( enable_qinval(iommu) != 0 )
+        {
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "Failed to enable Queued Invalidation!\n");
+            return -1;
+        }
+    }
+
+    /* Enable interrupt remapping */
+    for_each_drhd_unit ( drhd )
+    {
+        iommu = drhd->iommu;
+        if ( enable_intremap(iommu, 1) )
+        {
+            dprintk(XENLOG_INFO VTDPREFIX,
+                    "Failed to enable Interrupt Remapping!\n");
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+/*
+ * Check if interrupt remapping is enabled or not
+ * return 1: enabled
+ * return 0: not enabled
+ */
+int intremap_enabled(void)
+{
+    struct acpi_drhd_unit *drhd;
+    u32 sts;
+
+    for_each_drhd_unit ( drhd )
+    {
+        sts = dmar_readl(drhd->iommu->reg, DMAR_GSTS_REG);
+        if ( !(sts & DMA_GSTS_IRES) )
+            return 0;
+    }
+
+    return 1;
+}
diff -r 1a1a7b7c39e2 xen/include/asm-x86/apic.h
--- a/xen/include/asm-x86/apic.h	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/include/asm-x86/apic.h	Wed Jul 14 21:33:59 2010 +0800
@@ -25,6 +25,8 @@ extern int x2apic_enabled;
 extern int x2apic_enabled;
 extern int directed_eoi_enabled;
 
+extern void check_x2apic_preenabled(void);
+extern int x2apic_cmdline_disable(void);
 extern void enable_x2apic(void);
 
 static __inline int x2apic_is_available(void)
diff -r 1a1a7b7c39e2 xen/include/asm-x86/genapic.h
--- a/xen/include/asm-x86/genapic.h	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/include/asm-x86/genapic.h	Wed Jul 14 21:33:59 2010 +0800
@@ -70,6 +70,7 @@ cpumask_t vector_allocation_domain_flat(
 	.send_IPI_mask = send_IPI_mask_flat, \
 	.send_IPI_self = send_IPI_self_flat
 
+const struct genapic *apic_x2apic_probe(void);
 void init_apic_ldr_x2apic_phys(void);
 void init_apic_ldr_x2apic_cluster(void);
 void clustered_apic_check_x2apic(void);
diff -r 1a1a7b7c39e2 xen/include/asm-x86/io_apic.h
--- a/xen/include/asm-x86/io_apic.h	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/include/asm-x86/io_apic.h	Wed Jul 14 21:33:59 2010 +0800
@@ -199,6 +199,12 @@ extern void ioapic_suspend(void);
 extern void ioapic_suspend(void);
 extern void ioapic_resume(void);
 
+extern struct IO_APIC_route_entry **alloc_ioapic_entries(void);
+extern void free_ioapic_entries(struct IO_APIC_route_entry **ioapic_entries);
+extern int save_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern void mask_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+extern int restore_IO_APIC_setup(struct IO_APIC_route_entry **ioapic_entries);
+
 #else  /* !CONFIG_X86_IO_APIC */
 static inline void init_ioapic_mappings(void) {}
 static inline void ioapic_suspend(void) {}
diff -r 1a1a7b7c39e2 xen/include/asm-x86/irq.h
--- a/xen/include/asm-x86/irq.h	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/include/asm-x86/irq.h	Wed Jul 14 21:33:59 2010 +0800
@@ -91,6 +91,8 @@ void disable_8259A_irq(unsigned int irq)
 void disable_8259A_irq(unsigned int irq);
 void enable_8259A_irq(unsigned int irq);
 int i8259A_irq_pending(unsigned int irq);
+void mask_8259A(void);
+void unmask_8259A(void);
 void init_8259A(int aeoi);
 int i8259A_suspend(void);
 int i8259A_resume(void);
diff -r 1a1a7b7c39e2 xen/include/xen/iommu.h
--- a/xen/include/xen/iommu.h	Wed Jul 14 21:33:40 2010 +0800
+++ b/xen/include/xen/iommu.h	Wed Jul 14 21:33:59 2010 +0800
@@ -58,6 +58,8 @@ struct iommu {
 
 int iommu_setup(void);
 int iommu_supports_eim(void);
+int iommu_enable_IR(void);
+int intremap_enabled(void);
 
 int iommu_add_device(struct pci_dev *pdev);
 int iommu_remove_device(struct pci_dev *pdev);

[-- Attachment #5: Type: text/plain, Size: 138 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2010-07-15  7:56 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-07-05  7:07 [PATCH 0/3] x2APIC improvement Han, Weidong
2010-07-06 14:49 ` Konrad Rzeszutek Wilk
2010-07-07  5:09   ` Weidong Han
2010-07-07 13:56     ` Konrad Rzeszutek Wilk
2010-07-08  2:31       ` Weidong Han
2010-07-15  7:56 ` Han, Weidong

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.