x86: Add a new physdev_op PHYSDEVOP_setup_gsi for GSI setup.

GSI 0-15 is setup by hypervisor, and GSI > =16 is setup by dom0
this physdev_op PHYSDEVOP_setup_gsi. This patch can help dom0
to get rid of intrusive changes of ioapic.

Signed-off-by: Xiantao Zhang <xiantao.zhang@intel.com>
This commit is contained in:
Keir Fraser committed 2009-11-24 14:43:07 +00:00
1 parent 24cb0f67ea
commit 7ec2f53230
3 files changed
+49 -10

No files matched your search

+5 -6
View File
@@ -1122,7 +1122,7 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity)
ioapic = mp_find_ioapic(gsi);
if (ioapic < 0) {
printk(KERN_WARNING "No IOAPIC for GSI %u\n", gsi);
return gsi;
return -EINVAL;
}
ioapic_pin = gsi - mp_ioapic_routing[ioapic].gsi_base;
@@ -1141,12 +1141,12 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity)
printk(KERN_ERR "Invalid reference to IOAPIC pin "
"%d-%d\n", mp_ioapic_routing[ioapic].apic_id,
ioapic_pin);
return gsi;
return -EINVAL;
}
if ((1<<bit) & mp_ioapic_routing[ioapic].pin_programmed[idx]) {
Dprintk(KERN_DEBUG "Pin %d-%d already programmed\n",
mp_ioapic_routing[ioapic].apic_id, ioapic_pin);
return gsi_to_irq[gsi];
return -EEXIST;
}
mp_ioapic_routing[ioapic].pin_programmed[idx] |= (1<<bit);
@@ -1180,14 +1180,13 @@ int mp_register_gsi (u32 gsi, int triggering, int polarity)
gsi_to_irq[irq] = gsi;
} else {
printk(KERN_ERR "GSI %u is too high\n", gsi);
return gsi;
return -E2BIG;
}
}
io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
return io_apic_set_pci_routing(ioapic, ioapic_pin, gsi,
triggering == ACPI_EDGE_SENSITIVE ? 0 : 1,
polarity == ACPI_ACTIVE_HIGH ? 0 : 1);
return gsi;
}
#endif /* CONFIG_X86_IO_APIC */
+31 -4
View File
@@ -62,13 +62,18 @@ static int physdev_map_pirq(struct physdev_map_pirq *map)
ret = -EINVAL;
goto free_domain;
}
irq = domain_pirq_to_irq(current->domain, map->index);
if ( !irq )
{
dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n",
d->domain_id);
ret = -EINVAL;
goto free_domain;
if ( IS_PRIV(current->domain) )
irq = map->index;
else {
dprintk(XENLOG_G_ERR, "dom%d: map pirq with incorrect irq!\n",
d->domain_id);
ret = -EINVAL;
goto free_domain;
}
}
break;
@@ -457,6 +462,28 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
spin_unlock(&pcidevs_lock);
break;
}
case PHYSDEVOP_setup_gsi: {
struct physdev_setup_gsi setup_gsi;
ret = -EPERM;
if ( !IS_PRIV(v->domain) )
break;
ret = -EFAULT;
if ( copy_from_guest(&setup_gsi, arg, 1) != 0 )
break;
ret = -EINVAL;
if ( setup_gsi.gsi < 0 || setup_gsi.gsi >= nr_irqs_gsi )
break;
/* GSI < 16 has been setup by hypervisor */
if ( setup_gsi.gsi >= 16 )
ret = mp_register_gsi(setup_gsi.gsi, setup_gsi.triggering,
setup_gsi.polarity);
else
ret = -EEXIST;
break;
}
default:
ret = -ENOSYS;
break;
+13
View File
@@ -227,6 +227,19 @@ struct physdev_op {
typedef struct physdev_op physdev_op_t;
DEFINE_XEN_GUEST_HANDLE(physdev_op_t);
#define PHYSDEVOP_setup_gsi 21
struct physdev_setup_gsi {
int gsi;
/* IN */
uint8_t triggering;
/* IN */
uint8_t polarity;
/* IN */
};
typedef struct physdev_setup_gsi physdev_setup_gsi_t;
DEFINE_XEN_GUEST_HANDLE(physdev_setup_gsi_t);
/*
* Notify that some PIRQ-bound event channels have been unmasked.
* ** This command is obsolete since interface version 0x00030202 and is **
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.