MSI 2/6: change the pirq to be per-domain

Signed-off-by: Jiang Yunhong <yunhong.jiang@intel.com>
Signed-off-by: Shan Haitao <haitao.shan@intel.com>
This commit is contained in:
Keir Fraser committed 2008-05-01 10:30:22 +01:00
1 parent 154c5516cb
commit ca0074e519
18 files changed
+529 -25

No files matched your search

+14
View File
@@ -519,7 +519,21 @@ struct pt_dev * register_real_device(PCIBus *e_bus,
e_intx = assigned_device->dev.config[0x3d]-1;
if ( PT_MACHINE_IRQ_AUTO == machine_irq )
{
int pirq = pci_dev->irq;
machine_irq = pci_dev->irq;
rc = xc_physdev_map_pirq(xc_handle, domid, MAP_PIRQ_TYPE_GSI,
machine_irq, &pirq);
if ( rc )
{
/* TBD: unregister device in case of an error */
PT_LOG("Error: Mapping irq failed, rc = %d\n", rc);
}
else
machine_irq = pirq;
}
/* bind machine_irq to device */
if ( 0 != machine_irq )
+40
View File
@@ -19,3 +19,43 @@ int xc_physdev_pci_access_modify(int xc_handle,
errno = ENOSYS;
return -1;
}
int xc_physdev_map_pirq(int xc_handle,
int domid,
int type,
int index,
int *pirq)
{
int rc;
struct physdev_map_pirq map;
if ( !pirq )
return -EINVAL;
map.domid = domid;
map.type = type;
map.index = index;
map.pirq = *pirq;
rc = do_physdev_op(xc_handle, PHYSDEVOP_map_pirq, &map);
if ( !rc )
*pirq = map.pirq;
return rc;
}
int xc_physdev_unmap_pirq(int xc_handle,
int domid,
int pirq)
{
int rc;
struct physdev_unmap_pirq unmap;
unmap.domid = domid;
unmap.pirq = pirq;
rc = do_physdev_op(xc_handle, PHYSDEVOP_unmap_pirq, &unmap);
return rc;
}
+30
View File
@@ -24,10 +24,12 @@
#define DECLARE_HYPERCALL privcmd_hypercall_t hypercall = { 0 }
#define DECLARE_DOMCTL struct xen_domctl domctl = { 0 }
#define DECLARE_SYSCTL struct xen_sysctl sysctl = { 0 }
#define DECLARE_PHYSDEV_OP struct physdev_op physdev_op = { 0 }
#else
#define DECLARE_HYPERCALL privcmd_hypercall_t hypercall
#define DECLARE_DOMCTL struct xen_domctl domctl
#define DECLARE_SYSCTL struct xen_sysctl sysctl
#define DECLARE_PHYSDEV_OP struct physdev_op physdev_op
#endif
#undef PAGE_SHIFT
@@ -96,6 +98,34 @@ static inline int do_xen_version(int xc_handle, int cmd, void *dest)
return do_xen_hypercall(xc_handle, &hypercall);
}
static inline int do_physdev_op(int xc_handle, int cmd, void *op)
{
int ret = -1;
DECLARE_HYPERCALL;
hypercall.op = __HYPERVISOR_physdev_op;
hypercall.arg[0] = (unsigned long) cmd;
hypercall.arg[1] = (unsigned long) op;
if ( lock_pages(op, sizeof(*op)) != 0 )
{
PERROR("Could not lock memory for Xen hypercall");
goto out1;
}
if ( (ret = do_xen_hypercall(xc_handle, &hypercall)) < 0 )
{
if ( errno == EACCES )
DPRINTF("physdev operation failed -- need to"
" rebuild the user-space tool set?\n");
}
unlock_pages(op, sizeof(*op));
out1:
return ret;
}
static inline int do_domctl(int xc_handle, struct xen_domctl *domctl)
{
int ret = -1;
+11
View File
@@ -21,6 +21,7 @@
#include <stdint.h>
#include <xen/xen.h>
#include <xen/domctl.h>
#include <xen/physdev.h>
#include <xen/sysctl.h>
#include <xen/version.h>
#include <xen/event_channel.h>
@@ -849,6 +850,16 @@ int xc_gnttab_munmap(int xcg_handle,
int xc_gnttab_set_max_grants(int xcg_handle,
uint32_t count);
int xc_physdev_map_pirq(int xc_handle,
int domid,
int type,
int index,
int *pirq);
int xc_physdev_unmap_pirq(int xc_handle,
int domid,
int pirq);
int xc_hvm_set_pci_intx_level(
int xc_handle, domid_t dom,
uint8_t domain, uint8_t bus, uint8_t device, uint8_t intx,
+29
View File
@@ -799,6 +799,26 @@ static PyObject *pyxc_evtchn_reset(XcObject *self,
return zero;
}
static PyObject *pyxc_physdev_map_pirq(PyObject *self,
PyObject *args,
PyObject *kwds)
{
XcObject *xc = (XcObject *)self;
uint32_t dom;
int index, pirq, ret;
static char *kwd_list[] = {"domid", "index", "pirq", NULL};
if ( !PyArg_ParseTupleAndKeywords(args, kwds, "iii", kwd_list,
&dom, &index, &pirq) )
return NULL;
ret = xc_physdev_map_pirq(xc->xc_handle, dom, MAP_PIRQ_TYPE_GSI,
index, &pirq);
if ( ret != 0 )
return pyxc_error_to_exception();
return PyLong_FromUnsignedLong(pirq);
}
static PyObject *pyxc_physdev_pci_access_modify(XcObject *self,
PyObject *args,
PyObject *kwds)
@@ -1589,6 +1609,15 @@ static PyMethodDef pyxc_methods[] = {
"Reset all connections.\n"
" dom [int]: Domain to reset.\n" },
{ "physdev_map_pirq",
(PyCFunction)pyxc_physdev_map_pirq,
METH_VARARGS | METH_KEYWORDS, "\n"
"map physical irq to guest pirq.\n"
" dom [int]: Identifier of domain to map for.\n"
" index [int]: physical irq.\n"
" pirq [int]: guest pirq.\n"
"Returns: [long] value of the param.\n" },
{ "physdev_pci_access_modify",
(PyCFunction)pyxc_physdev_pci_access_modify,
METH_VARARGS | METH_KEYWORDS, "\n"
+6 -1
View File
@@ -69,5 +69,10 @@ class IRQController(DevController):
#todo non-fatal
raise VmError(
'irq: Failed to configure irq: %d' % (pirq))
rc = xc.physdev_map_pirq(domid = self.getDomid(),
index = pirq,
pirq = pirq)
if rc < 0:
raise VmError(
'irq: Failed to map irq %x' % (pirq))
return (None, {}, {})
+6
View File
@@ -271,6 +271,12 @@ class PciController(DevController):
if rc<0:
raise VmError(('pci: failed to configure I/O memory on device '+
'%s - errno=%d')%(dev.name,rc))
rc = xc.physdev_map_pirq(domid = fe_domid,
index = dev.irq,
pirq = dev.irq)
if rc < 0:
raise VmError(('pci: failed to map irq on device '+
'%s - errno=%d')%(dev.name,rc))
if dev.irq>0:
log.debug('pci: enabling irq %d'%dev.irq)
+2
View File
@@ -525,6 +525,8 @@ int arch_domain_create(struct domain *d, unsigned int domcr_flags)
goto fail;
}
spin_lock_init(&d->arch.irq_lock);
if ( is_hvm_domain(d) )
{
if ( (rc = hvm_domain_initialise(d)) != 0 )
+2 -2
View File
@@ -121,7 +121,7 @@ static void vmx_dirq_assist(struct vcpu *v)
if ( !test_and_clear_bit(irq, &hvm_irq_dpci->dirq_mask) )
continue;
stop_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(irq)]);
stop_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)]);
list_for_each_entry ( digl, &hvm_irq_dpci->mirq[irq].digl_list, list )
{
@@ -140,7 +140,7 @@ static void vmx_dirq_assist(struct vcpu *v)
* guest will never deal with the irq, then the physical interrupt line
* will never be deasserted.
*/
set_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(irq)],
set_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, irq)],
NOW() + PT_IRQ_TIME_OUT);
}
}
+19
View File
@@ -41,6 +41,25 @@
int (*ioapic_renumber_irq)(int ioapic, int irq);
atomic_t irq_mis_count;
int msi_irq_enable = 0;
boolean_param("msi_irq_enable", msi_irq_enable);
int domain_irq_to_vector(struct domain *d, int irq)
{
if ( !msi_irq_enable )
return irq_to_vector(irq);
else
return d->arch.pirq_vector[irq];
}
int domain_vector_to_irq(struct domain *d, int vector)
{
if ( !msi_irq_enable )
return vector_to_irq(vector);
else
return d->arch.vector_pirq[vector];
}
/* Where if anywhere is the i8259 connect in external int mode */
static struct { int pin, apic; } ioapic_i8259 = { -1, -1 };
+16 -11
View File
@@ -203,7 +203,6 @@ static DEFINE_PER_CPU(struct pending_eoi, pending_eoi[NR_VECTORS]);
static void __do_IRQ_guest(int vector)
{
unsigned int irq = vector_to_irq(vector);
irq_desc_t *desc = &irq_desc[vector];
irq_guest_action_t *action = (irq_guest_action_t *)desc->action;
struct domain *d;
@@ -232,7 +231,9 @@ static void __do_IRQ_guest(int vector)
for ( i = 0; i < action->nr_guests; i++ )
{
unsigned int irq;
d = action->guest[i];
irq = domain_vector_to_irq(d, vector);
if ( (action->ack_type != ACKTYPE_NONE) &&
!test_and_set_bit(irq, d->pirq_mask) )
action->in_flight++;
@@ -305,8 +306,10 @@ static void __pirq_guest_eoi(struct domain *d, int irq)
irq_desc_t *desc;
irq_guest_action_t *action;
cpumask_t cpu_eoi_map;
int vector;
desc = &irq_desc[irq_to_vector(irq)];
vector = domain_irq_to_vector(d, irq);
desc = &irq_desc[vector];
action = (irq_guest_action_t *)desc->action;
spin_lock_irq(&desc->lock);
@@ -324,7 +327,7 @@ static void __pirq_guest_eoi(struct domain *d, int irq)
if ( action->ack_type == ACKTYPE_UNMASK )
{
ASSERT(cpus_empty(action->cpu_eoi_map));
desc->handler->end(irq_to_vector(irq));
desc->handler->end(vector);
spin_unlock_irq(&desc->lock);
return;
}
@@ -375,12 +378,12 @@ int pirq_guest_unmask(struct domain *d)
}
extern int ioapic_ack_new;
int pirq_acktype(int irq)
int pirq_acktype(struct domain *d, int irq)
{
irq_desc_t *desc;
unsigned int vector;
vector = irq_to_vector(irq);
vector = domain_irq_to_vector(d, irq);
if ( vector == 0 )
return ACKTYPE_NONE;
@@ -421,7 +424,7 @@ int pirq_acktype(int irq)
return 0;
}
int pirq_shared(int irq)
int pirq_shared(struct domain *d, int irq)
{
unsigned int vector;
irq_desc_t *desc;
@@ -429,7 +432,7 @@ int pirq_shared(int irq)
unsigned long flags;
int shared;
vector = irq_to_vector(irq);
vector = domain_irq_to_vector(d, irq);
if ( vector == 0 )
return 0;
@@ -453,7 +456,7 @@ int pirq_guest_bind(struct vcpu *v, int irq, int will_share)
cpumask_t cpumask = CPU_MASK_NONE;
retry:
vector = irq_to_vector(irq);
vector = domain_irq_to_vector(v->domain, irq);
if ( vector == 0 )
return -EINVAL;
@@ -487,7 +490,7 @@ int pirq_guest_bind(struct vcpu *v, int irq, int will_share)
action->nr_guests = 0;
action->in_flight = 0;
action->shareable = will_share;
action->ack_type = pirq_acktype(irq);
action->ack_type = pirq_acktype(v->domain, irq);
cpus_clear(action->cpu_eoi_map);
desc->depth = 0;
@@ -538,13 +541,15 @@ int pirq_guest_bind(struct vcpu *v, int irq, int will_share)
int pirq_guest_unbind(struct domain *d, int irq)
{
unsigned int vector = irq_to_vector(irq);
irq_desc_t *desc = &irq_desc[vector];
unsigned int vector;
irq_desc_t *desc;
irq_guest_action_t *action;
cpumask_t cpu_eoi_map;
unsigned long flags;
int i;
vector = domain_irq_to_vector(d, irq);
desc = &irq_desc[vector];
BUG_ON(vector == 0);
spin_lock_irqsave(&desc->lock, flags);
+299 -3
View File
@@ -7,6 +7,7 @@
#include <xen/irq.h>
#include <xen/event.h>
#include <xen/guest_access.h>
#include <xen/iocap.h>
#include <asm/current.h>
#include <asm/hypercall.h>
#include <public/xen.h>
@@ -24,6 +25,263 @@ int
ioapic_guest_write(
unsigned long physbase, unsigned int reg, u32 pval);
static int get_free_pirq(struct domain *d, int type, int index)
{
int i;
if ( d == NULL )
return -EINVAL;
ASSERT(spin_is_locked(&d->arch.irq_lock));
if ( type == MAP_PIRQ_TYPE_GSI )
{
for ( i = 16; i < NR_PIRQS; i++ )
if ( !d->arch.pirq_vector[i] )
break;
if ( i == NR_PIRQS )
return -ENOSPC;
}
else
{
for ( i = NR_PIRQS - 1; i >= 16; i-- )
if ( !d->arch.pirq_vector[i] )
break;
if ( i == 16 )
return -ENOSPC;
}
return i;
}
/*
* Caller hold the irq_lock
*/
static int map_domain_pirq(struct domain *d, int pirq, int vector, int type)
{
int ret = 0;
int old_vector, old_pirq;
if ( d == NULL )
return -EINVAL;
ASSERT(spin_is_locked(&d->arch.irq_lock));
if ( !IS_PRIV(current->domain) )
return -EPERM;
if ( pirq < 0 || pirq >= NR_PIRQS || vector < 0 || vector >= NR_VECTORS )
{
gdprintk(XENLOG_G_ERR,
"invalid pirq %x or vector %x\n", pirq, vector);
return -EINVAL;
}
old_vector = d->arch.pirq_vector[pirq];
old_pirq = d->arch.vector_pirq[vector];
if ( (old_vector && (old_vector != vector) ) ||
(old_pirq && (old_pirq != pirq)) )
{
gdprintk(XENLOG_G_ERR, "remap pirq %x vector %x while not unmap\n",
pirq, vector);
ret = -EINVAL;
goto done;
}
ret = irq_permit_access(d, pirq);
if ( ret )
{
gdprintk(XENLOG_G_ERR, "add irq permit access %x failed\n", pirq);
ret = -EINVAL;
goto done;
}
d->arch.pirq_vector[pirq] = vector;
d->arch.vector_pirq[vector] = pirq;
done:
return ret;
}
/*
* The pirq should has been unbound before this call
*/
static int unmap_domain_pirq(struct domain *d, int pirq)
{
int ret = 0;
int vector;
if ( d == NULL || pirq < 0 || pirq > NR_PIRQS )
return -EINVAL;
if ( !IS_PRIV(current->domain) )
return -EINVAL;
ASSERT(spin_is_locked(&d->arch.irq_lock));
vector = d->arch.pirq_vector[pirq];
if ( !vector )
{
gdprintk(XENLOG_G_ERR, "domain %X: pirq %x not mapped still\n",
d->domain_id, pirq);
ret = -EINVAL;
}
else
d->arch.pirq_vector[pirq] = d->arch.vector_pirq[vector] = 0;
ret = irq_deny_access(d, pirq);
if ( ret )
gdprintk(XENLOG_G_ERR, "deny irq %x access failed\n", pirq);
return ret;
}
extern int msi_irq_enable;
static int physdev_map_pirq(struct physdev_map_pirq *map)
{
struct domain *d;
int vector, pirq, ret = 0;
unsigned long flags;
/* if msi_irq_enable is not enabled,map always success */
if ( !msi_irq_enable )
return 0;
if ( !IS_PRIV(current->domain) )
return -EPERM;
if ( !map )
return -EINVAL;
if ( map->domid == DOMID_SELF )
d = rcu_lock_domain(current->domain);
else
d = rcu_lock_domain_by_id(map->domid);
if ( d == NULL )
{
ret = -ESRCH;
goto free_domain;
}
switch ( map->type )
{
case MAP_PIRQ_TYPE_GSI:
if ( map->index >= NR_IRQS )
{
ret = -EINVAL;
gdprintk(XENLOG_G_ERR,
"map invalid irq %x\n", map->index);
goto free_domain;
}
vector = IO_APIC_VECTOR(map->index);
if ( !vector )
{
ret = -EINVAL;
gdprintk(XENLOG_G_ERR,
"map irq with no vector %x\n", map->index);
goto free_domain;
}
break;
case MAP_PIRQ_TYPE_MSI:
vector = map->index;
if ( vector < 0 || vector >= NR_VECTORS )
{
ret = -EINVAL;
gdprintk(XENLOG_G_ERR,
"map_pirq with wrong vector %x\n", map->index);
goto free_domain;
}
break;
default:
ret = -EINVAL;
gdprintk(XENLOG_G_ERR, "wrong map_pirq type %x\n", map->type);
goto free_domain;
break;
}
spin_lock_irqsave(&d->arch.irq_lock, flags);
if ( map->pirq == -1 )
{
if ( d->arch.vector_pirq[vector] )
{
gdprintk(XENLOG_G_ERR, "%x %x mapped already%x\n",
map->index, map->pirq,
d->arch.vector_pirq[vector]);
pirq = d->arch.vector_pirq[vector];
}
else
{
pirq = get_free_pirq(d, map->type, map->index);
if ( pirq < 0 )
{
ret = pirq;
gdprintk(XENLOG_G_ERR, "No free pirq\n");
goto done;
}
}
}
else
{
if ( d->arch.vector_pirq[vector] &&
d->arch.vector_pirq[vector] != map->pirq )
{
gdprintk(XENLOG_G_ERR, "%x conflict with %x\n",
map->index, map->pirq);
ret = -EEXIST;
goto done;
}
else
pirq = map->pirq;
}
ret = map_domain_pirq(d, pirq, vector, map->type);
if ( !ret )
map->pirq = pirq;
done:
spin_unlock_irqrestore(&d->arch.irq_lock, flags);
free_domain:
rcu_unlock_domain(d);
return ret;
}
static int physdev_unmap_pirq(struct physdev_unmap_pirq *unmap)
{
struct domain *d;
unsigned long flags;
int ret;
if ( !msi_irq_enable )
return 0;
if ( !IS_PRIV(current->domain) )
return -EPERM;
if ( !unmap )
return -EINVAL;
if ( unmap->domid == DOMID_SELF )
d = rcu_lock_domain(current->domain);
else
d = rcu_lock_domain_by_id(unmap->domid);
if ( d == NULL )
{
rcu_unlock_domain(d);
return -ESRCH;
}
spin_lock_irqsave(&d->arch.irq_lock, flags);
ret = unmap_domain_pirq(d, unmap->pirq);
spin_unlock_irqrestore(&d->arch.irq_lock, flags);
rcu_unlock_domain(d);
return ret;
}
ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
{
int irq;
@@ -57,14 +315,38 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
if ( (irq < 0) || (irq >= NR_IRQS) )
break;
irq_status_query.flags = 0;
if ( pirq_acktype(irq) != 0 )
if ( pirq_acktype(v->domain, irq) != 0 )
irq_status_query.flags |= XENIRQSTAT_needs_eoi;
if ( pirq_shared(irq) )
if ( pirq_shared(v->domain, irq) )
irq_status_query.flags |= XENIRQSTAT_shared;
ret = copy_to_guest(arg, &irq_status_query, 1) ? -EFAULT : 0;
break;
}
case PHYSDEVOP_map_pirq: {
struct physdev_map_pirq map;
ret = -EFAULT;
if ( copy_from_guest(&map, arg, 1) != 0 )
break;
ret = physdev_map_pirq(&map);
if ( copy_to_guest(arg, &map, 1) != 0 )
ret = -EFAULT;
break;
}
case PHYSDEVOP_unmap_pirq: {
struct physdev_unmap_pirq unmap;
ret = -EFAULT;
if ( copy_from_guest(&unmap, arg, 1) != 0 )
break;
ret = physdev_unmap_pirq(&unmap);
break;
}
case PHYSDEVOP_apic_read: {
struct physdev_apic apic;
ret = -EFAULT;
@@ -99,6 +381,7 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
case PHYSDEVOP_alloc_irq_vector: {
struct physdev_irq irq_op;
unsigned long flags;
ret = -EFAULT;
if ( copy_from_guest(&irq_op, arg, 1) != 0 )
@@ -118,7 +401,20 @@ ret_t do_physdev_op(int cmd, XEN_GUEST_HANDLE(void) arg)
break;
irq_op.vector = assign_irq_vector(irq);
ret = copy_to_guest(arg, &irq_op, 1) ? -EFAULT : 0;
ret = 0;
if ( msi_irq_enable )
{
spin_lock_irqsave(&dom0->arch.irq_lock, flags);
if ( irq != AUTO_ASSIGN )
ret = map_domain_pirq(dom0, irq_op.irq, irq_op.vector,
MAP_PIRQ_TYPE_GSI);
spin_unlock_irqrestore(&dom0->arch.irq_lock, flags);
}
if ( copy_to_guest(arg, &irq_op, 1) != 0 )
ret = -EFAULT;
break;
}
+7 -5
View File
@@ -25,6 +25,7 @@ static void pt_irq_time_out(void *data)
{
struct hvm_mirq_dpci_mapping *irq_map = data;
unsigned int guest_gsi, machine_gsi = 0;
int vector;
struct hvm_irq_dpci *dpci = domain_get_irq_dpci(irq_map->dom);
struct dev_intx_gsi_link *digl;
uint32_t device, intx;
@@ -39,7 +40,8 @@ static void pt_irq_time_out(void *data)
}
clear_bit(machine_gsi, dpci->dirq_mask);
stop_timer(&dpci->hvm_timer[irq_to_vector(machine_gsi)]);
vector = domain_irq_to_vector(irq_map->dom, machine_gsi);
stop_timer(&dpci->hvm_timer[vector]);
spin_lock(&dpci->dirq_lock);
dpci->mirq[machine_gsi].pending = 0;
spin_unlock(&dpci->dirq_lock);
@@ -98,7 +100,7 @@ int pt_irq_create_bind_vtd(
hvm_irq_dpci->mirq[machine_gsi].valid = 1;
hvm_irq_dpci->mirq[machine_gsi].dom = d;
init_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)],
init_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, machine_gsi)],
pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], 0);
/* Deal with gsi for legacy devices */
pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WILL_SHARE);
@@ -157,7 +159,7 @@ int pt_irq_destroy_bind_vtd(
if ( list_empty(&hvm_irq_dpci->mirq[machine_gsi].digl_list) )
{
pirq_guest_unbind(d, machine_gsi);
kill_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)]);
kill_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, machine_gsi)]);
hvm_irq_dpci->mirq[machine_gsi].dom = NULL;
hvm_irq_dpci->mirq[machine_gsi].valid = 0;
}
@@ -185,7 +187,7 @@ int hvm_do_IRQ_dpci(struct domain *d, unsigned int mirq)
* PIC) and we need to detect that.
*/
set_bit(mirq, dpci->dirq_mask);
set_timer(&dpci->hvm_timer[irq_to_vector(mirq)],
set_timer(&dpci->hvm_timer[domain_irq_to_vector(d, mirq)],
NOW() + PT_IRQ_TIME_OUT);
vcpu_kick(d->vcpu[0]);
@@ -221,7 +223,7 @@ void hvm_dpci_eoi(struct domain *d, unsigned int guest_gsi,
gdprintk(XENLOG_INFO VTDPREFIX,
"hvm_dpci_eoi:: mirq = %x\n", machine_gsi);
stop_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)]);
stop_timer(&hvm_irq_dpci->hvm_timer[domain_irq_to_vector(d, machine_gsi)]);
if ( (ent == NULL) || !ent->fields.mask )
pirq_guest_eoi(d, machine_gsi);
}
+1 -1
View File
@@ -114,7 +114,7 @@ void hvm_dpci_isairq_eoi(struct domain *d, unsigned int isairq)
if ( --dpci->mirq[i].pending == 0 )
{
spin_unlock(&dpci->dirq_lock);
stop_timer(&dpci->hvm_timer[irq_to_vector(i)]);
stop_timer(&dpci->hvm_timer[domain_irq_to_vector(d, i)]);
pirq_guest_eoi(d, i);
}
else
+5
View File
@@ -6,6 +6,7 @@
#include <asm/hvm/vcpu.h>
#include <asm/hvm/domain.h>
#include <asm/e820.h>
#include <asm/pirq.h>
#define has_32bit_shinfo(d) ((d)->arch.has_32bit_shinfo)
#define is_pv_32bit_domain(d) ((d)->arch.is_32bit_pv)
@@ -222,6 +223,10 @@ struct arch_domain
/* Shadow translated domain: P2M mapping */
pagetable_t phys_table;
spinlock_t irq_lock;
int vector_pirq[NR_VECTORS];
int pirq_vector[NR_PIRQS];
/* Pseudophysical e820 map (XENMEM_memory_map). */
struct e820entry e820[3];
unsigned int nr_e820;
+4 -2
View File
@@ -49,7 +49,9 @@ extern unsigned long io_apic_irqs;
extern atomic_t irq_err_count;
extern atomic_t irq_mis_count;
int pirq_acktype(int irq);
int pirq_shared(int irq);
int pirq_acktype(struct domain *d, int irq);
int pirq_shared(struct domain *d , int irq);
extern int domain_irq_to_vector(struct domain *d, int irq);
extern int domain_vector_to_irq(struct domain *d, int vector);
#endif /* _ASM_HW_IRQ_H */
+11
View File
@@ -0,0 +1,11 @@
#ifndef __XEN_PIRQ_H
#define __XEN_PIRQ_H
#define PIRQ_BASE 0
#define NR_PIRQS 256
#define DYNIRQ_BASE (PIRQ_BASE + NR_PIRQS)
#define NR_DYNIRQS 256
#endif /* __XEN_PIRQ_H */
+27
View File
@@ -121,6 +121,33 @@ struct physdev_irq {
};
typedef struct physdev_irq physdev_irq_t;
DEFINE_XEN_GUEST_HANDLE(physdev_irq_t);
#define MAP_PIRQ_TYPE_MSI 0x0
#define MAP_PIRQ_TYPE_GSI 0x1
#define MAP_PIRQ_TYPE_UNKNOWN 0x2
#define PHYSDEVOP_map_pirq 13
struct physdev_map_pirq {
domid_t domid;
/* IN */
int type;
/* IN */
int index;
/* IN or OUT */
int pirq;
};
typedef struct physdev_map_pirq physdev_map_pirq_t;
DEFINE_XEN_GUEST_HANDLE(physdev_map_pirq_t);
#define PHYSDEVOP_unmap_pirq 14
struct physdev_unmap_pirq {
domid_t domid;
/* IN */
int pirq;
};
typedef struct physdev_unmap_pirq physdev_unmap_pirq_t;
DEFINE_XEN_GUEST_HANDLE(physdev_unmap_pirq_t);
/*
* Argument to physdev_op_compat() hypercall. Superceded by new physdev_op()
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.