@@ -1360,6 +1360,35 @@ static int prepare_dtb(struct domain *d, struct kernel_info *kinfo)
#define XEN_HYPERVISOR_ID 0x000058656E564D4D /* "XenVMM" */
#define ACPI_DOM0_FDT_MIN_SIZE 4096
+static int acpi_route_spi(struct domain *d)
+{
+ int i, res;
+ struct irq_desc *desc;
+
+ /* Don't route Xen used interrupt to Dom0. Since Xen already uses the uart
+ * interrupt, the desc->action will not be NULL, so it will skip it.
+ */
+ for( i = NR_LOCAL_IRQS; i < vgic_num_irqs(d); i++ )
+ {
+ /* Don't route uart interrupt to Dom0 */
+ desc = irq_to_desc(i);
+ if( desc->action != NULL)
+ continue;
+
+ vgic_reserve_virq(d, i);
+ irq_set_type(i, ACPI_IRQ_TYPE_NONE);
+ res = route_irq_to_guest(d, i, i, NULL);
+ if ( res )
+ {
+ printk(XENLOG_ERR "Unable to route IRQ %u to domain %u\n",
+ i, d->domain_id);
+ continue;
+ }
+ }
+
+ return 0;
+}
+
static int make_chosen_node(const struct kernel_info *kinfo,
struct membank tbl_add[])
{
@@ -1897,6 +1926,10 @@ static int prepare_acpi(struct domain *d, struct kernel_info *kinfo)
if ( rc != 0 )
return rc;
+ rc = acpi_route_spi(d);
+ if ( rc != 0 )
+ return rc;
+
return 0;
}
#else