From 20e7b4098f625f874158b0e166f2f9db9d043c5a Mon Sep 17 00:00:00 2001 From: Keir Fraser Date: Mon, 29 Oct 2007 09:16:59 +0000 Subject: [PATCH] x86, vt-d: Move out isa irq mapping from hvm_do_IRQ_dpci() Setting isa irq mapping in hvm_do_IRQ_dpci() costs time when each interrupt occurs, and it doesn't update isa irq mapping when pci_link is updated. Signed-off-by: Weidong Han Signed-off-by: Keir Fraser --- xen/arch/x86/hvm/irq.c | 12 ++++++++++++ xen/arch/x86/hvm/vmx/vtd/io.c | 24 +++++++++--------------- 2 files changed, 21 insertions(+), 15 deletions(-) diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index c19d23724e..9d1d2d7e49 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -191,6 +191,18 @@ void hvm_set_pci_link_route(struct domain *d, u8 link, u8 isa_irq) goto out; hvm_irq->pci_link.route[link] = isa_irq; + /* PCI pass-through fixup. */ + if ( hvm_irq->dpci && hvm_irq->dpci->girq[old_isa_irq].valid ) + { + uint32_t device = hvm_irq->dpci->girq[old_isa_irq].device; + uint32_t intx = hvm_irq->dpci->girq[old_isa_irq].intx; + if ( link == hvm_pci_intx_link(device, intx) ) + { + hvm_irq->dpci->girq[isa_irq] = hvm_irq->dpci->girq[old_isa_irq]; + hvm_irq->dpci->girq[old_isa_irq].valid = 0; + } + } + if ( hvm_irq->pci_link_assert_count[link] == 0 ) goto out; diff --git a/xen/arch/x86/hvm/vmx/vtd/io.c b/xen/arch/x86/hvm/vmx/vtd/io.c index 81cf1ae609..a724bb7986 100644 --- a/xen/arch/x86/hvm/vmx/vtd/io.c +++ b/xen/arch/x86/hvm/vmx/vtd/io.c @@ -63,6 +63,7 @@ int pt_irq_create_bind_vtd( struct hvm_irq_dpci *hvm_irq_dpci = d->arch.hvm_domain.irq.dpci; uint32_t machine_gsi, guest_gsi; uint32_t device, intx; + uint32_t link, isa_irq; if ( hvm_irq_dpci == NULL ) { @@ -83,6 +84,8 @@ int pt_irq_create_bind_vtd( device = pt_irq_bind->u.pci.device; intx = pt_irq_bind->u.pci.intx; guest_gsi = hvm_pci_intx_gsi(device, intx); + link = hvm_pci_intx_link(device, intx); + isa_irq = d->arch.hvm_domain.irq.pci_link.route[link]; hvm_irq_dpci->mirq[machine_gsi].valid = 1; hvm_irq_dpci->mirq[machine_gsi].device = device; @@ -96,6 +99,12 @@ int pt_irq_create_bind_vtd( hvm_irq_dpci->girq[guest_gsi].machine_gsi = machine_gsi; hvm_irq_dpci->girq[guest_gsi].dom = d; + hvm_irq_dpci->girq[isa_irq].valid = 1; + hvm_irq_dpci->girq[isa_irq].device = device; + hvm_irq_dpci->girq[isa_irq].intx = intx; + hvm_irq_dpci->girq[isa_irq].machine_gsi = machine_gsi; + hvm_irq_dpci->girq[isa_irq].dom = d; + init_timer(&hvm_irq_dpci->hvm_timer[irq_to_vector(machine_gsi)], pt_irq_time_out, &hvm_irq_dpci->mirq[machine_gsi], 0); @@ -110,27 +119,12 @@ int pt_irq_create_bind_vtd( int hvm_do_IRQ_dpci(struct domain *d, unsigned int mirq) { - uint32_t device, intx; - uint32_t link, isa_irq; struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq; if ( !vtd_enabled || (d == dom0) || (hvm_irq->dpci == NULL) || !hvm_irq->dpci->mirq[mirq].valid ) return 0; - device = hvm_irq->dpci->mirq[mirq].device; - intx = hvm_irq->dpci->mirq[mirq].intx; - link = hvm_pci_intx_link(device, intx); - isa_irq = hvm_irq->pci_link.route[link]; - - if ( !hvm_irq->dpci->girq[isa_irq].valid ) - { - hvm_irq->dpci->girq[isa_irq].valid = 1; - hvm_irq->dpci->girq[isa_irq].device = device; - hvm_irq->dpci->girq[isa_irq].intx = intx; - hvm_irq->dpci->girq[isa_irq].machine_gsi = mirq; - } - /* * Set a timer here to avoid situations where the IRQ line is shared, and * the device belonging to the pass-through guest is not yet active. In -- 2.30.2