direct-io.hg

changeset 15528:2665a74a1351

allen: added vt-d interrupt method; fixed bugs created by the merge
author root@lweybridge0-64-fc6.sc.intel.com.sc.intel.com
date Fri Aug 17 17:05:09 2007 -0700 (2007-08-17)
parents 87a15869d43b
children 9ce39dc1425f
files tools/ioemu/hw/passthrough/pass-through.c tools/ioemu/hw/passthrough/pass-through.h xen/arch/x86/domain.c xen/arch/x86/domctl.c xen/arch/x86/hvm/io.c xen/arch/x86/hvm/vioapic.c xen/arch/x86/hvm/vmx/intr.c xen/arch/x86/hvm/vmx/vmx.c xen/arch/x86/hvm/vmx/vtd/intel-iommu.c xen/arch/x86/hvm/vpic.c xen/arch/x86/io_apic.c xen/arch/x86/irq.c xen/arch/x86/mm/p2m.c xen/arch/x86/pt/irq_bind.c xen/include/asm-x86/hvm/io.h xen/include/asm-x86/hvm/irq.h xen/include/asm-x86/iommu.h xen/include/xen/irq_bind.h
line diff
     1.1 --- a/tools/ioemu/hw/passthrough/pass-through.c	Thu Aug 16 05:42:24 2007 -0400
     1.2 +++ b/tools/ioemu/hw/passthrough/pass-through.c	Fri Aug 17 17:05:09 2007 -0700
     1.3 @@ -297,6 +297,7 @@ pt_dev_t * register_real_device(PCIBus *
     1.4      pt_dev_t * pci_dev = NULL;
     1.5      pci_phys_dev_t * real_device = NULL;
     1.6      uint8_t e_device, e_intx;
     1.7 +    struct pci_config_cf8 machine_bdf;
     1.8      int rc;
     1.9  
    1.10      fprintf(logfile,"Registering real physical device %s (devfn=0x%x)...\n", e_dev_name, e_devfn);
    1.11 @@ -326,6 +327,15 @@ pt_dev_t * register_real_device(PCIBus *
    1.12      pci_dev->d = r_dev;
    1.13      pci_dev->f = r_func;
    1.14      
    1.15 +    /* tell XEN vmm to change iommu settings */
    1.16 +    machine_bdf.reg = 0;
    1.17 +    machine_bdf.bus = pci_dev->b;
    1.18 +    machine_bdf.dev = pci_dev->d;
    1.19 +    machine_bdf.func = pci_dev->f;
    1.20 +    rc = xc_assign_device(xc_handle, domid, machine_bdf.value);
    1.21 +    if ( rc < 0 )
    1.22 +        fprintf(logfile, "Error: xc_domain_assign_device error %d\n", rc);
    1.23 +
    1.24      /* handle real device's MMIO/PIO BARs */
    1.25      rc = pt_register_regions(real_device, pci_dev);
    1.26      if ( rc != 0 )
     2.1 --- a/tools/ioemu/hw/passthrough/pass-through.h	Thu Aug 16 05:42:24 2007 -0400
     2.2 +++ b/tools/ioemu/hw/passthrough/pass-through.h	Fri Aug 17 17:05:09 2007 -0700
     2.3 @@ -63,6 +63,22 @@ typedef struct pt_dev_s {
     2.4      pt_region_t bases[PCI_NUM_REGIONS];
     2.5  } pt_dev_t;
     2.6  
     2.7 +/* Used for formatting PCI BDF into cf8 format */
     2.8 +struct pci_config_cf8 {
     2.9 +    union {
    2.10 +        unsigned int value;
    2.11 +        struct {
    2.12 +            unsigned int reserved1:2;
    2.13 +            unsigned int reg:6;
    2.14 +            unsigned int func:3;
    2.15 +            unsigned int dev:5;
    2.16 +            unsigned int bus:8;
    2.17 +            unsigned int reserved2:7;
    2.18 +            unsigned int enable:1;
    2.19 +        };
    2.20 +    };
    2.21 +};
    2.22 +
    2.23  /* Argument parsing */
    2.24  int pci_devs(const char *direct_pci);
    2.25  int next_token(char *direct_pci);
     3.1 --- a/xen/arch/x86/domain.c	Thu Aug 16 05:42:24 2007 -0400
     3.2 +++ b/xen/arch/x86/domain.c	Fri Aug 17 17:05:09 2007 -0700
     3.3 @@ -486,17 +486,14 @@ int arch_domain_create(struct domain *d)
     3.4              virt_to_page(d->shared_info), d, XENSHARE_writable);
     3.5      }
     3.6  
     3.7 +    if ( iommu_found() )
     3.8 +        iommu_domain_init(d);
     3.9 +
    3.10      if ( is_hvm_domain(d) )
    3.11      {
    3.12          /* Init common pass-through structures */
    3.13          passthrough_domain_init(d);
    3.14 -        
    3.15 -        if ( iommu_found() )
    3.16 -            iommu_domain_init(d);
    3.17 -    }
    3.18  
    3.19 -    if ( is_hvm_domain(d) )
    3.20 -    {
    3.21          if ( (rc = hvm_domain_initialise(d)) != 0 )
    3.22              goto fail;
    3.23      }
     4.1 --- a/xen/arch/x86/domctl.c	Thu Aug 16 05:42:24 2007 -0400
     4.2 +++ b/xen/arch/x86/domctl.c	Fri Aug 17 17:05:09 2007 -0700
     4.3 @@ -474,7 +474,10 @@ long arch_do_domctl(
     4.4  
     4.5          bind = &(domctl->u.bind_pt_irq);
     4.6          
     4.7 -        ret = pt_irq_create_bind(bind);
     4.8 +        if ( iommu_found() )
     4.9 +            ret = pt_irq_create_bind_vtd(d, bind);
    4.10 +        else
    4.11 +            ret = pt_irq_create_bind_neo(bind);
    4.12          if (ret < 0) {
    4.13              printk("Error: pt_irq_create_bind failed!\n");
    4.14          }
     5.1 --- a/xen/arch/x86/hvm/io.c	Thu Aug 16 05:42:24 2007 -0400
     5.2 +++ b/xen/arch/x86/hvm/io.c	Fri Aug 17 17:05:09 2007 -0700
     5.3 @@ -1003,14 +1003,73 @@ int dpci_ioport_intercept(ioreq_t *p)
     5.4      return ret;
     5.5  }
     5.6  
     5.7 +int hvm_do_IRQ_dpci(struct domain *d, unsigned int mirq)
     5.8 +{
     5.9 +    uint32_t device, intx;
    5.10 +    uint32_t link, isa_irq;
    5.11 +    struct hvm_irq *hvm_irq;
    5.12 +
    5.13 +    if ((d == dom0) || !iommu_found())
    5.14 +        return 0;
    5.15 +
    5.16 +    if (d->arch.hvm_domain.irq.mirq[mirq].valid)
    5.17 +    {
    5.18 +        device = d->arch.hvm_domain.irq.mirq[mirq].device;
    5.19 +        intx = d->arch.hvm_domain.irq.mirq[mirq].intx;
    5.20 +        link = hvm_pci_intx_link(device, intx);
    5.21 +        hvm_irq = &d->arch.hvm_domain.irq;
    5.22 +        isa_irq = hvm_irq->pci_link.route[link];
    5.23 +
    5.24 +        if ( !d->arch.hvm_domain.irq.girq[isa_irq].valid )
    5.25 +        {
    5.26 +            d->arch.hvm_domain.irq.girq[isa_irq].valid = 1;
    5.27 +            d->arch.hvm_domain.irq.girq[isa_irq].device = device;
    5.28 +            d->arch.hvm_domain.irq.girq[isa_irq].intx = intx;
    5.29 +            d->arch.hvm_domain.irq.girq[isa_irq].machine_gsi = mirq;
    5.30 +        }
    5.31 +
    5.32 +        if ( !test_and_set_bit(mirq, d->arch.hvm_domain.irq.dirq_mask) )
    5.33 +        {
    5.34 +            vcpu_kick(d->vcpu[0]);
    5.35 +            return 1;
    5.36 +        }
    5.37 +        else
    5.38 +            dprintk(XENLOG_INFO, "Want to pending mirq, but failed\n");
    5.39 +    }
    5.40 +    return 0;
    5.41 +}
    5.42 +
    5.43 +void hvm_dpci_eoi(unsigned int guest_gsi)
    5.44 +{
    5.45 +    struct domain *d = current->domain;
    5.46 +    uint32_t device, intx, machine_gsi;
    5.47 +    irq_desc_t *desc;
    5.48 +
    5.49 +    if (d->arch.hvm_domain.irq.girq[guest_gsi].valid)
    5.50 +    {
    5.51 +        device = d->arch.hvm_domain.irq.girq[guest_gsi].device;
    5.52 +        intx = d->arch.hvm_domain.irq.girq[guest_gsi].intx;
    5.53 +        machine_gsi = d->arch.hvm_domain.irq.girq[guest_gsi].machine_gsi;
    5.54 +        gdprintk(XENLOG_INFO, "hvm_dpci_eoi:: device %x intx %x\n",
    5.55 +            device, intx);
    5.56 +        hvm_pci_intx_deassert(d, device, intx);
    5.57 +        desc = &irq_desc[irq_to_vector(machine_gsi)];
    5.58 +        desc->handler->end(irq_to_vector(machine_gsi));
    5.59 +    }
    5.60 +}
    5.61 +
    5.62  int release_devices(struct vcpu *v)
    5.63  {
    5.64      int ret = 0;
    5.65      struct domain *d = v->domain;
    5.66 -    
    5.67 -    if (! dev_assigned(d))
    5.68 -        return ret;
    5.69 +    struct hvm_domain *hd = &d->arch.hvm_domain;
    5.70 +    uint32_t i;
    5.71  
    5.72 +    /* unbind irq */
    5.73 +    for (i = 0; i < NR_IRQS; i++) {
    5.74 +        if (hd->irq.mirq[i].valid)
    5.75 +            ret = pirq_guest_unbind(d, i);
    5.76 +    }
    5.77      if (iommu_found())
    5.78          iommu_domain_teardown(d);
    5.79      else {
     6.1 --- a/xen/arch/x86/hvm/vioapic.c	Thu Aug 16 05:42:24 2007 -0400
     6.2 +++ b/xen/arch/x86/hvm/vioapic.c	Fri Aug 17 17:05:09 2007 -0700
     6.3 @@ -462,6 +462,13 @@ void vioapic_update_EOI(struct domain *d
     6.4      ent = &vioapic->redirtbl[gsi];
     6.5  
     6.6      ent->fields.remote_irr = 0;
     6.7 +
     6.8 +    if (iommu_found()) {
     6.9 +        spin_unlock(&d->arch.hvm_domain.irq_lock);
    6.10 +        hvm_dpci_eoi(gsi);
    6.11 +        return;
    6.12 +    }
    6.13 +
    6.14      if ( (ent->fields.trig_mode == VIOAPIC_LEVEL_TRIG) &&
    6.15           !ent->fields.mask &&
    6.16           hvm_irq->gsi_assert_count[gsi] )
     7.1 --- a/xen/arch/x86/hvm/vmx/intr.c	Thu Aug 16 05:42:24 2007 -0400
     7.2 +++ b/xen/arch/x86/hvm/vmx/intr.c	Fri Aug 17 17:05:09 2007 -0700
     7.3 @@ -127,6 +127,27 @@ static void update_tpr_threshold(struct 
     7.4      __vmwrite(TPR_THRESHOLD, (max_irr > tpr) ? (tpr >> 4) : (max_irr >> 4));
     7.5  }
     7.6  
     7.7 +static void vmx_dirq_assist(struct domain *d)
     7.8 +{
     7.9 +    unsigned int irq;
    7.10 +    uint32_t device;
    7.11 +    uint32_t intx;
    7.12 +    struct hvm_irq *hvm_irq = &d->arch.hvm_domain.irq;
    7.13 +
    7.14 +    for (irq = find_first_bit(hvm_irq->dirq_mask, NR_IRQS);
    7.15 +         irq < NR_IRQS;
    7.16 +         irq = find_next_bit(hvm_irq->dirq_mask, NR_IRQS, irq + 1))
    7.17 +    {
    7.18 +        test_and_clear_bit(irq, &hvm_irq->dirq_mask);
    7.19 +        device = hvm_irq->mirq[irq].device;
    7.20 +        intx = hvm_irq->mirq[irq].intx;
    7.21 +        gdprintk(XENLOG_INFO VTDPREFIX,
    7.22 +            "injecting intr: device %x intx %x, irq= %x\n",
    7.23 +            device, intx, irq);
    7.24 +        hvm_pci_intx_assert(d, device, intx);
    7.25 +    }
    7.26 +}
    7.27 +
    7.28  asmlinkage void vmx_intr_assist(void)
    7.29  {
    7.30      int intr_vector;
    7.31 @@ -135,10 +156,16 @@ asmlinkage void vmx_intr_assist(void)
    7.32      unsigned int idtv_info_field;
    7.33      unsigned long inst_len;
    7.34  
    7.35 +    pt_update_irq(v);
    7.36 +
    7.37      /* Pass-through interrupts handling */
    7.38 -    pt_intr_assist(v->domain);
    7.39 -
    7.40 -    pt_update_irq(v);
    7.41 +    if ( iommu_found() )
    7.42 +    {
    7.43 +        if  (v->vcpu_id == 0)
    7.44 +            vmx_dirq_assist(v->domain);
    7.45 +    }
    7.46 +    else
    7.47 +        pt_intr_assist(v->domain);
    7.48  
    7.49      hvm_set_callback_irq_level();
    7.50  
     8.1 --- a/xen/arch/x86/hvm/vmx/vmx.c	Thu Aug 16 05:42:24 2007 -0400
     8.2 +++ b/xen/arch/x86/hvm/vmx/vmx.c	Fri Aug 17 17:05:09 2007 -0700
     8.3 @@ -99,9 +99,8 @@ static int vmx_vcpu_initialise(struct vc
     8.4  static void vmx_vcpu_destroy(struct vcpu *v)
     8.5  {
     8.6      vmx_destroy_vmcs(v);
     8.7 -#if 0
     8.8 -    release_devices(v);
     8.9 -#endif
    8.10 +    if (iommu_found())
    8.11 +        release_devices(v);
    8.12  }
    8.13  
    8.14  static int vmx_paging_enabled(struct vcpu *v)
     9.1 --- a/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c	Thu Aug 16 05:42:24 2007 -0400
     9.2 +++ b/xen/arch/x86/hvm/vmx/vtd/intel-iommu.c	Fri Aug 17 17:05:09 2007 -0700
     9.3 @@ -1845,7 +1845,7 @@ void iommu_set_pgd(struct domain *d)
     9.4      }
     9.5  #endif
     9.6      gdprintk(XENLOG_INFO VTDPREFIX,
     9.7 -        "iommu_set_pgd_2: hd->pgd = %p\n", hd->pgd);
     9.8 +        "iommu_set_pgd: hd->pgd = %p\n", hd->pgd);
     9.9  }
    9.10  
    9.11  
    10.1 --- a/xen/arch/x86/hvm/vpic.c	Thu Aug 16 05:42:24 2007 -0400
    10.2 +++ b/xen/arch/x86/hvm/vpic.c	Fri Aug 17 17:05:09 2007 -0700
    10.3 @@ -177,8 +177,9 @@ static int vpic_intack(struct hvm_hw_vpi
    10.4  static void vpic_ioport_write(
    10.5      struct hvm_hw_vpic *vpic, uint32_t addr, uint32_t val)
    10.6  {
    10.7 -    int priority, cmd, irq;
    10.8 +    int priority, cmd, irq = 0, pic_eoi = 0;
    10.9      uint8_t mask;
   10.10 +    uint32_t old_addr = addr;
   10.11  
   10.12      vpic_lock(vpic);
   10.13  
   10.14 @@ -250,6 +251,13 @@ static void vpic_ioport_write(
   10.15                  vpic->isr &= ~(1 << irq);
   10.16                  if ( cmd == 7 )
   10.17                      vpic->priority_add = (irq + 1) & 7;
   10.18 +                if (iommu_found()) {
   10.19 +                    /* chipset register 0xa0 is i8259 EOI register */
   10.20 +                    if (( old_addr & 0xa0) == 0xa0 )
   10.21 +                        irq = irq | 0x8;
   10.22 +                    if ( irq != 0 )
   10.23 +                        pic_eoi = 1;
   10.24 +                }
   10.25                  break;
   10.26              case 6: /* Set Priority                */
   10.27                  vpic->priority_add = (val + 1) & 7;
   10.28 @@ -295,6 +303,12 @@ static void vpic_ioport_write(
   10.29      vpic_update_int_output(vpic);
   10.30  
   10.31      vpic_unlock(vpic);
   10.32 +
   10.33 +    if (iommu_found() && pic_eoi && irq != 0)
   10.34 +    {
   10.35 +        hvm_dpci_eoi(irq);
   10.36 +        pic_eoi = 0;
   10.37 +    }
   10.38  }
   10.39  
   10.40  static uint32_t vpic_ioport_read(struct hvm_hw_vpic *vpic, uint32_t addr)
    11.1 --- a/xen/arch/x86/io_apic.c	Thu Aug 16 05:42:24 2007 -0400
    11.2 +++ b/xen/arch/x86/io_apic.c	Fri Aug 17 17:05:09 2007 -0700
    11.3 @@ -187,6 +187,68 @@ static void __modify_IO_APIC_irq (unsign
    11.4      }
    11.5  }
    11.6  
    11.7 +int real_vector[MAX_IRQ_SOURCES];
    11.8 +int fake_vector=-1;
    11.9 +
   11.10 +/*
   11.11 + * Following 2 functions are used to workaround spurious interrupt
   11.12 + * problem related to mask/unmask of interrupts.  Instead we program
   11.13 + * an unused vector in the IOAPIC before issueing EOI to LAPIC.
   11.14 + */
   11.15 +static void write_fake_IO_APIC_vector (unsigned int irq)
   11.16 +{
   11.17 +    struct irq_pin_list *entry = irq_2_pin + irq;
   11.18 +    unsigned int pin, reg;
   11.19 +    unsigned long flags;
   11.20 +
   11.21 +    spin_lock_irqsave(&ioapic_lock, flags);
   11.22 +    for (;;) {
   11.23 +        pin = entry->pin;
   11.24 +        if (pin == -1)
   11.25 +            break;
   11.26 +        reg = io_apic_read(entry->apic, 0x10 + pin*2);
   11.27 +        real_vector[irq] = reg & 0xff;
   11.28 +        reg &= ~0xff;
   11.29 +
   11.30 +        if (fake_vector == -1)
   11.31 +            fake_vector = assign_irq_vector(MAX_IRQ_SOURCES-1);
   11.32 +
   11.33 +        reg |= fake_vector;
   11.34 +        io_apic_write(entry->apic, 0x10 + pin*2, reg);
   11.35 +
   11.36 +        if (!entry->next)
   11.37 +            break;
   11.38 +        entry = irq_2_pin + entry->next;
   11.39 +    }
   11.40 +    spin_unlock_irqrestore(&ioapic_lock, flags);
   11.41 +}
   11.42 +
   11.43 +static void restore_real_IO_APIC_vector (unsigned int irq)
   11.44 +{
   11.45 +    struct irq_pin_list *entry = irq_2_pin + irq;
   11.46 +    unsigned int pin, reg;
   11.47 +    unsigned long flags;
   11.48 +
   11.49 +    spin_lock_irqsave(&ioapic_lock, flags);
   11.50 +    for (;;) {
   11.51 +        pin = entry->pin;
   11.52 +        if (pin == -1)
   11.53 +            break;
   11.54 +
   11.55 +        reg = io_apic_read(entry->apic, 0x10 + pin*2);
   11.56 +        reg &= ~0xff;
   11.57 +        reg |= real_vector[irq];
   11.58 +        io_apic_write(entry->apic, 0x10 + pin*2, reg);
   11.59 +        mb();
   11.60 +        *(IO_APIC_BASE(entry->apic) + 0x10) = reg & 0xff;
   11.61 +
   11.62 +        if (!entry->next)
   11.63 +            break;
   11.64 +        entry = irq_2_pin + entry->next;
   11.65 +    }
   11.66 +    spin_unlock_irqrestore(&ioapic_lock, flags);
   11.67 +}
   11.68 +
   11.69  /* mask = 1 */
   11.70  static void __mask_IO_APIC_irq (unsigned int irq)
   11.71  {
   11.72 @@ -1359,7 +1421,10 @@ static void mask_and_ack_level_ioapic_ir
   11.73      if ( ioapic_ack_new )
   11.74          return;
   11.75  
   11.76 -    mask_IO_APIC_irq(irq);
   11.77 +    if (iommu_found())
   11.78 +        write_fake_IO_APIC_vector(irq);
   11.79 +    else
   11.80 +        mask_IO_APIC_irq(irq);
   11.81  /*
   11.82   * It appears there is an erratum which affects at least version 0x11
   11.83   * of I/O APIC (that's the 82093AA and cores integrated into various
   11.84 @@ -1401,8 +1466,12 @@ static void end_level_ioapic_irq (unsign
   11.85  
   11.86      if ( !ioapic_ack_new )
   11.87      {
   11.88 -        if ( !(irq_desc[IO_APIC_VECTOR(irq)].status & IRQ_DISABLED) )
   11.89 -            unmask_IO_APIC_irq(irq);
   11.90 +        if ( !(irq_desc[IO_APIC_VECTOR(irq)].status & IRQ_DISABLED) ) {
   11.91 +            if (iommu_found())
   11.92 +                restore_real_IO_APIC_vector(irq);
   11.93 +            else
   11.94 +                unmask_IO_APIC_irq(irq);
   11.95 +        }
   11.96          return;
   11.97      }
   11.98  
    12.1 --- a/xen/arch/x86/irq.c	Thu Aug 16 05:42:24 2007 -0400
    12.2 +++ b/xen/arch/x86/irq.c	Fri Aug 17 17:05:09 2007 -0700
    12.3 @@ -19,6 +19,7 @@
    12.4  #include <asm/current.h>
    12.5  #include <asm/smpboot.h>
    12.6  #include <asm/domain.h>
    12.7 +#include <asm/iommu.h>
    12.8  
    12.9  /* opt_noirqbalance: If true, software IRQ balancing/affinity is disabled. */
   12.10  int opt_noirqbalance = 0;
   12.11 @@ -92,7 +93,7 @@ asmlinkage void do_IRQ(struct cpu_user_r
   12.12      spin_lock(&desc->lock);
   12.13      desc->handler->ack(vector);
   12.14  
   12.15 -    if ( do_IRQ_pt(vector) )
   12.16 +    if ( !iommu_found() && do_IRQ_pt(vector) )
   12.17          goto out; 
   12.18  
   12.19      if ( likely(desc->status & IRQ_GUEST) )
   12.20 @@ -270,7 +271,8 @@ static void __do_IRQ_guest(int vector)
   12.21          if ( (action->ack_type != ACKTYPE_NONE) &&
   12.22               !test_and_set_bit(irq, d->pirq_mask) )
   12.23              action->in_flight++;
   12.24 -        send_guest_pirq(d, irq);
   12.25 +        if (!hvm_do_IRQ_dpci(d, irq))
   12.26 +            send_guest_pirq(d, irq);
   12.27      }
   12.28  }
   12.29  
    13.1 --- a/xen/arch/x86/mm/p2m.c	Thu Aug 16 05:42:24 2007 -0400
    13.2 +++ b/xen/arch/x86/mm/p2m.c	Fri Aug 17 17:05:09 2007 -0700
    13.3 @@ -274,7 +274,10 @@ clear_mmio_p2m_entry(struct domain *d, u
    13.4      rc = set_p2m_entry(d, gfn, _mfn(INVALID_MFN),
    13.5          __PAGE_HYPERVISOR|_PAGE_USER);
    13.6          
    13.7 +#if !defined(__x86_64__)
    13.8 +    /* x86_64 xen does not map mmio entries in machine_to_phys_mapp[] */
    13.9      set_gpfn_from_mfn(mfn, INVALID_M2P_ENTRY);
   13.10 +#endif
   13.11  
   13.12      return rc;
   13.13  }
    14.1 --- a/xen/arch/x86/pt/irq_bind.c	Thu Aug 16 05:42:24 2007 -0400
    14.2 +++ b/xen/arch/x86/pt/irq_bind.c	Fri Aug 17 17:05:09 2007 -0700
    14.3 @@ -140,7 +140,7 @@ static int __pt_pci_bind_irq(unsigned lo
    14.4      return 0;
    14.5  }
    14.6  
    14.7 -int pt_irq_create_bind(xen_domctl_bind_pt_irq_t * pt_irq_bind)
    14.8 +int pt_irq_create_bind_neo(xen_domctl_bind_pt_irq_t * pt_irq_bind)
    14.9  {
   14.10      int rc;
   14.11      unsigned long vector, flags;
   14.12 @@ -223,3 +223,34 @@ out:
   14.13      
   14.14  }
   14.15  
   14.16 +int pt_irq_create_bind_vtd(
   14.17 +    struct domain *d,
   14.18 +    xen_domctl_bind_pt_irq_t * pt_irq_bind)
   14.19 +{
   14.20 +    struct hvm_domain *hd = &d->arch.hvm_domain;
   14.21 +    uint32_t machine_gsi, guest_gsi;
   14.22 +    uint32_t device, intx;
   14.23 +
   14.24 +    machine_gsi = pt_irq_bind->machine_irq;
   14.25 +    device = pt_irq_bind->u.pci.device;
   14.26 +    intx = pt_irq_bind->u.pci.intx;
   14.27 +    guest_gsi = hvm_pci_intx_gsi(device, intx);
   14.28 +
   14.29 +    hd->irq.mirq[machine_gsi].valid = 1;
   14.30 +    hd->irq.mirq[machine_gsi].device = device;
   14.31 +    hd->irq.mirq[machine_gsi].intx = intx;
   14.32 +    hd->irq.mirq[machine_gsi].guest_gsi = guest_gsi;
   14.33 +
   14.34 +    hd->irq.girq[guest_gsi].valid = 1;
   14.35 +    hd->irq.girq[guest_gsi].device = device;
   14.36 +    hd->irq.girq[guest_gsi].intx = intx;
   14.37 +    hd->irq.girq[guest_gsi].machine_gsi = machine_gsi;
   14.38 +
   14.39 +    /* Deal with gsi for legacy devices */
   14.40 +    pirq_guest_bind(d->vcpu[0], machine_gsi, BIND_PIRQ__WILL_SHARE);
   14.41 +    gdprintk(XENLOG_INFO,
   14.42 +        "XEN_DOMCTL_irq_mapping: m_irq = %x device = %x intx = %x\n",
   14.43 +        machine_gsi, device, intx);
   14.44 +
   14.45 +    return 0;
   14.46 +}
    15.1 --- a/xen/include/asm-x86/hvm/io.h	Thu Aug 16 05:42:24 2007 -0400
    15.2 +++ b/xen/include/asm-x86/hvm/io.h	Fri Aug 17 17:05:09 2007 -0700
    15.3 @@ -151,6 +151,7 @@ void send_invalidate_req(void);
    15.4  extern void handle_mmio(unsigned long gpa);
    15.5  extern void hvm_interrupt_post(struct vcpu *v, int vector, int type);
    15.6  extern void hvm_io_assist(void);
    15.7 +extern void hvm_dpci_eoi(unsigned int guest_irq);
    15.8  
    15.9  #endif /* __ASM_X86_HVM_IO_H__ */
   15.10  
    16.1 --- a/xen/include/asm-x86/hvm/irq.h	Thu Aug 16 05:42:24 2007 -0400
    16.2 +++ b/xen/include/asm-x86/hvm/irq.h	Fri Aug 17 17:05:09 2007 -0700
    16.3 @@ -29,6 +29,16 @@
    16.4  #include <asm/hvm/vioapic.h>
    16.5  #include <public/hvm/save.h>
    16.6  
    16.7 +struct hvm_irq_mapping {
    16.8 +    uint8_t valid;
    16.9 +    uint8_t device;
   16.10 +    uint8_t intx;
   16.11 +    union {
   16.12 +        uint8_t guest_gsi;
   16.13 +        uint8_t machine_gsi;
   16.14 +    };
   16.15 +};
   16.16 +
   16.17  struct hvm_irq {
   16.18      /*
   16.19       * Virtual interrupt wires for a single PCI bus.
   16.20 @@ -88,6 +98,12 @@ struct hvm_irq {
   16.21  
   16.22      /* Last VCPU that was delivered a LowestPrio interrupt. */
   16.23      u8 round_robin_prev_vcpu;
   16.24 +
   16.25 +    /* machine irq to guest device/intx mapping */
   16.26 +    struct hvm_irq_mapping mirq[NR_IRQS];
   16.27 +    /* guest irq to guest device/intx mapping */
   16.28 +    struct hvm_irq_mapping girq[NR_IRQS];
   16.29 +    DECLARE_BITMAP(dirq_mask, NR_IRQS);
   16.30  };
   16.31  
   16.32  #define hvm_pci_intx_gsi(dev, intx)  \
    17.1 --- a/xen/include/asm-x86/iommu.h	Thu Aug 16 05:42:24 2007 -0400
    17.2 +++ b/xen/include/asm-x86/iommu.h	Fri Aug 17 17:05:09 2007 -0700
    17.3 @@ -74,5 +74,6 @@ int iommu_unmap_page(struct domain *d, d
    17.4  void iommu_flush(struct domain *d, dma_addr_t gfn, u64 *p2m_entry);
    17.5  void iommu_set_pgd(struct domain *d);
    17.6  void iommu_domain_teardown(struct domain *d);
    17.7 +int hvm_do_IRQ_dpci(struct domain *d, unsigned int irq);
    17.8  
    17.9  #endif // _IOMMU_H_
    18.1 --- a/xen/include/xen/irq_bind.h	Thu Aug 16 05:42:24 2007 -0400
    18.2 +++ b/xen/include/xen/irq_bind.h	Fri Aug 17 17:05:09 2007 -0700
    18.3 @@ -45,7 +45,9 @@ typedef struct pt_vector_bind_s {
    18.4  int pt_irq_init(void);
    18.5  
    18.6  /* Create and remove mirq->girq bindings */
    18.7 -int pt_irq_create_bind(xen_domctl_bind_pt_irq_t * pt_irq_bind);
    18.8 +int pt_irq_create_bind_neo(xen_domctl_bind_pt_irq_t * pt_irq_bind);
    18.9 +int pt_irq_create_bind_vtd(struct domain *d,
   18.10 +                           xen_domctl_bind_pt_irq_t * pt_irq_bind);
   18.11  int pt_irq_remove_bind(unsigned long mirq);
   18.12  
   18.13  void pt_assert_irq(unsigned int vector);