mirror of
https://github.com/xen-project/xen.git
synced 2026-10-29 18:50:05 +01:00
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:
1 parent
24cb0f67ea
commit
7ec2f53230
3 files changed
+49
-10
No files matched your search
@@ -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
@@ -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;
|
||||
|
||||
@@ -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 **
|
||||
|
||||