ia64/xen-unstable

changeset 17443:80ba1b427032

x86: Emulate accesses to PCI window registers cf8/cfc to synchronise
with accesses by teh hypervisor itself. All users of cf8/cfc go
through new access functions which take the appropriate spinlock.

Based on a patch by Haitao Shan <haitao.shan@intel.com>

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Apr 11 13:19:55 2008 +0100 (2008-04-11)
parents 082d3886fded
children 96b099ad0497
files xen/arch/x86/Makefile xen/arch/x86/cpu/amd.c xen/arch/x86/domain_build.c xen/arch/x86/pci.c xen/arch/x86/traps.c xen/drivers/passthrough/amd/iommu_detect.c xen/drivers/passthrough/amd/iommu_init.c xen/drivers/passthrough/amd/pci_amd_iommu.c xen/drivers/passthrough/pci-direct.h xen/drivers/passthrough/vtd/dmar.c xen/drivers/passthrough/vtd/intremap.c xen/drivers/passthrough/vtd/iommu.c xen/drivers/passthrough/vtd/qinval.c xen/drivers/passthrough/vtd/utils.c xen/include/asm-x86/domain.h xen/include/xen/pci.h
line diff
     1.1 --- a/xen/arch/x86/Makefile	Fri Apr 11 09:14:03 2008 +0100
     1.2 +++ b/xen/arch/x86/Makefile	Fri Apr 11 13:19:55 2008 +0100
     1.3 @@ -31,6 +31,7 @@ obj-y += mm.o
     1.4  obj-y += mpparse.o
     1.5  obj-y += nmi.o
     1.6  obj-y += numa.o
     1.7 +obj-y += pci.o
     1.8  obj-y += physdev.o
     1.9  obj-y += rwlock.o
    1.10  obj-y += setup.o
     2.1 --- a/xen/arch/x86/cpu/amd.c	Fri Apr 11 09:14:03 2008 +0100
     2.2 +++ b/xen/arch/x86/cpu/amd.c	Fri Apr 11 13:19:55 2008 +0100
     2.3 @@ -3,6 +3,7 @@
     2.4  #include <xen/bitops.h>
     2.5  #include <xen/mm.h>
     2.6  #include <xen/smp.h>
     2.7 +#include <xen/pci.h>
     2.8  #include <asm/io.h>
     2.9  #include <asm/msr.h>
    2.10  #include <asm/processor.h>
    2.11 @@ -66,19 +67,6 @@ static int c1_ramping_may_cause_clock_dr
    2.12  	return 1;
    2.13  }
    2.14  
    2.15 -/* PCI access functions. Should be safe to use 0xcf8/0xcfc port accesses here. */
    2.16 -static u8 pci_read_byte(u32 bus, u32 dev, u32 fn, u32 reg)
    2.17 -{
    2.18 -	outl((1U<<31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3), 0xcf8);
    2.19 -	return inb(0xcfc + (reg & 3));
    2.20 -}
    2.21 -
    2.22 -static void pci_write_byte(u32 bus, u32 dev, u32 fn, u32 reg, u8 val)
    2.23 -{
    2.24 -	outl((1U<<31) | (bus << 16) | (dev << 11) | (fn << 8) | (reg & ~3), 0xcf8);
    2.25 -	outb(val, 0xcfc + (reg & 3));
    2.26 -}
    2.27 -
    2.28  /*
    2.29   * Disable C1-Clock ramping if enabled in PMM7.CpuLowPwrEnh on 8th-generation
    2.30   * cores only. Assume BIOS has setup all Northbridges equivalently.
    2.31 @@ -90,12 +78,12 @@ static void disable_c1_ramping(void)
    2.32  
    2.33  	for (node=0; node < NR_CPUS; node++) {
    2.34  		/* PMM7: bus=0, dev=0x18+node, function=0x3, register=0x87. */
    2.35 -		pmm7 = pci_read_byte(0, 0x18+node, 0x3, 0x87);
    2.36 +		pmm7 = pci_conf_read8(0, 0x18+node, 0x3, 0x87);
    2.37  		/* Invalid read means we've updated every Northbridge. */
    2.38  		if (pmm7 == 0xFF)
    2.39  			break;
    2.40  		pmm7 &= 0xFC; /* clear pmm7[1:0] */
    2.41 -		pci_write_byte(0, 0x18+node, 0x3, 0x87, pmm7);
    2.42 +		pci_conf_write8(0, 0x18+node, 0x3, 0x87, pmm7);
    2.43  		printk ("AMD: Disabling C1 Clock Ramping Node #%x\n", node);
    2.44  	}
    2.45  }
     3.1 --- a/xen/arch/x86/domain_build.c	Fri Apr 11 09:14:03 2008 +0100
     3.2 +++ b/xen/arch/x86/domain_build.c	Fri Apr 11 13:19:55 2008 +0100
     3.3 @@ -957,6 +957,8 @@ int __init construct_dom0(
     3.4      rc |= ioports_deny_access(dom0, 0x40, 0x43);
     3.5      /* PIT Channel 2 / PC Speaker Control. */
     3.6      rc |= ioports_deny_access(dom0, 0x61, 0x61);
     3.7 +    /* PCI configuration spaces. */
     3.8 +    rc |= ioports_deny_access(dom0, 0xcf8, 0xcff);
     3.9      /* Command-line I/O ranges. */
    3.10      process_dom0_ioports_disable();
    3.11  
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/xen/arch/x86/pci.c	Fri Apr 11 13:19:55 2008 +0100
     4.3 @@ -0,0 +1,118 @@
     4.4 +/******************************************************************************
     4.5 + * pci.c
     4.6 + * 
     4.7 + * PCI access functions.
     4.8 + */
     4.9 +
    4.10 +#include <xen/config.h>
    4.11 +#include <xen/pci.h>
    4.12 +#include <xen/spinlock.h>
    4.13 +#include <asm/io.h>
    4.14 +
    4.15 +#define PCI_CONF_ADDRESS(bus, dev, func, reg) \
    4.16 +    (0x80000000 | (bus << 16) | (dev << 11) | (func << 8) | (reg & ~3))
    4.17 +
    4.18 +static DEFINE_SPINLOCK(pci_config_lock);
    4.19 +
    4.20 +uint32_t pci_conf_read(uint32_t cf8, uint8_t offset, uint8_t bytes)
    4.21 +{
    4.22 +    unsigned long flags;
    4.23 +    uint32_t value;
    4.24 +
    4.25 +    BUG_ON((offset + bytes) > 4);
    4.26 +
    4.27 +    spin_lock_irqsave(&pci_config_lock, flags);
    4.28 +
    4.29 +    outl(cf8, 0xcf8);
    4.30 +
    4.31 +    switch ( bytes )
    4.32 +    {
    4.33 +    case 1:
    4.34 +        value = inb(0xcfc + offset);
    4.35 +        break;
    4.36 +    case 2:
    4.37 +        value = inw(0xcfc + offset);
    4.38 +        break;
    4.39 +    case 4:
    4.40 +        value = inl(0xcfc + offset);
    4.41 +        break;
    4.42 +    default:
    4.43 +        value = 0;
    4.44 +        BUG();
    4.45 +    }
    4.46 +
    4.47 +    spin_unlock_irqrestore(&pci_config_lock, flags);
    4.48 +
    4.49 +    return value;
    4.50 +}
    4.51 +
    4.52 +void pci_conf_write(uint32_t cf8, uint8_t offset, uint8_t bytes, uint32_t data)
    4.53 +{
    4.54 +    unsigned long flags;
    4.55 +
    4.56 +    BUG_ON((offset + bytes) > 4);
    4.57 +
    4.58 +    spin_lock_irqsave(&pci_config_lock, flags);
    4.59 +
    4.60 +    outl(cf8, 0xcf8);
    4.61 +
    4.62 +    switch ( bytes )
    4.63 +    {
    4.64 +    case 1:
    4.65 +        outb((uint8_t)data, 0xcfc + offset);
    4.66 +        break;
    4.67 +    case 2:
    4.68 +        outw((uint16_t)data, 0xcfc + offset);
    4.69 +        break;
    4.70 +    case 4:
    4.71 +        outl(data, 0xcfc + offset);
    4.72 +        break;
    4.73 +    }
    4.74 +
    4.75 +    spin_unlock_irqrestore(&pci_config_lock, flags);
    4.76 +}
    4.77 +
    4.78 +uint8_t pci_conf_read8(
    4.79 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg)
    4.80 +{
    4.81 +    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
    4.82 +    return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1);
    4.83 +}
    4.84 +
    4.85 +uint16_t pci_conf_read16(
    4.86 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg)
    4.87 +{
    4.88 +    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
    4.89 +    return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2);
    4.90 +}
    4.91 +
    4.92 +uint32_t pci_conf_read32(
    4.93 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg)
    4.94 +{
    4.95 +    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
    4.96 +    return pci_conf_read(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4);
    4.97 +}
    4.98 +
    4.99 +void pci_conf_write8(
   4.100 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
   4.101 +    uint8_t data)
   4.102 +{
   4.103 +    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
   4.104 +    pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 3, 1, data);
   4.105 +}
   4.106 +
   4.107 +void pci_conf_write16(
   4.108 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
   4.109 +    uint16_t data)
   4.110 +{
   4.111 +    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
   4.112 +    pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), reg & 2, 2, data);
   4.113 +}
   4.114 +
   4.115 +void pci_conf_write32(
   4.116 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
   4.117 +    uint32_t data)
   4.118 +{
   4.119 +    BUG_ON((bus > 255) || (dev > 31) || (func > 7) || (reg > 255));
   4.120 +    pci_conf_write(PCI_CONF_ADDRESS(bus, dev, func, reg), 0, 4, data);
   4.121 +}
     5.1 --- a/xen/arch/x86/traps.c	Fri Apr 11 09:14:03 2008 +0100
     5.2 +++ b/xen/arch/x86/traps.c	Fri Apr 11 13:19:55 2008 +0100
     5.3 @@ -1353,7 +1353,7 @@ static int read_gate_descriptor(unsigned
     5.4  #endif
     5.5  
     5.6  /* Has the guest requested sufficient permission for this I/O access? */
     5.7 -static inline int guest_io_okay(
     5.8 +static int guest_io_okay(
     5.9      unsigned int port, unsigned int bytes,
    5.10      struct vcpu *v, struct cpu_user_regs *regs)
    5.11  {
    5.12 @@ -1395,19 +1395,130 @@ static inline int guest_io_okay(
    5.13  }
    5.14  
    5.15  /* Has the administrator granted sufficient permission for this I/O access? */
    5.16 -static inline int admin_io_okay(
    5.17 +static int admin_io_okay(
    5.18      unsigned int port, unsigned int bytes,
    5.19      struct vcpu *v, struct cpu_user_regs *regs)
    5.20  {
    5.21      return ioports_access_permitted(v->domain, port, port + bytes - 1);
    5.22  }
    5.23  
    5.24 -#define guest_inb_okay(_p, _d, _r) admin_io_okay(_p, 1, _d, _r)
    5.25 -#define guest_inw_okay(_p, _d, _r) admin_io_okay(_p, 2, _d, _r)
    5.26 -#define guest_inl_okay(_p, _d, _r) admin_io_okay(_p, 4, _d, _r)
    5.27 -#define guest_outb_okay(_p, _d, _r) admin_io_okay(_p, 1, _d, _r)
    5.28 -#define guest_outw_okay(_p, _d, _r) admin_io_okay(_p, 2, _d, _r)
    5.29 -#define guest_outl_okay(_p, _d, _r) admin_io_okay(_p, 4, _d, _r)
    5.30 +static uint32_t guest_io_read(
    5.31 +    unsigned int port, unsigned int bytes,
    5.32 +    struct vcpu *v, struct cpu_user_regs *regs)
    5.33 +{
    5.34 +    extern uint32_t pci_conf_read(
    5.35 +        uint32_t cf8, uint8_t offset, uint8_t bytes);
    5.36 +
    5.37 +    uint32_t data = 0;
    5.38 +    unsigned int shift = 0;
    5.39 +
    5.40 +    if ( admin_io_okay(port, bytes, v, regs) )
    5.41 +    {
    5.42 +        switch ( bytes )
    5.43 +        {
    5.44 +        case 1: return inb(port);
    5.45 +        case 2: return inw(port);
    5.46 +        case 4: return inl(port);
    5.47 +        }
    5.48 +    }
    5.49 +
    5.50 +    while ( bytes != 0 )
    5.51 +    {
    5.52 +        unsigned int size = 1;
    5.53 +        uint32_t sub_data = 0xff;
    5.54 +
    5.55 +        if ( (port == 0x42) || (port == 0x43) || (port == 0x61) )
    5.56 +        {
    5.57 +            sub_data = pv_pit_handler(port, 0, 0);
    5.58 +        }
    5.59 +        else if ( (port & 0xfffc) == 0xcf8 )
    5.60 +        {
    5.61 +            size = min(bytes, 4 - (port & 3));
    5.62 +            sub_data = v->domain->arch.pci_cf8 >> ((port & 3) * 8);
    5.63 +        }
    5.64 +        else if ( ((port & 0xfffc) == 0xcfc) && IS_PRIV(v->domain) )
    5.65 +        {
    5.66 +            size = min(bytes, 4 - (port & 3));
    5.67 +            if ( size == 3 )
    5.68 +                size = 2;
    5.69 +            sub_data = pci_conf_read(v->domain->arch.pci_cf8, port & 3, size);
    5.70 +        }
    5.71 +
    5.72 +        if ( size == 4 )
    5.73 +            return sub_data;
    5.74 +
    5.75 +        data |= (sub_data & ((1u << (size * 8)) - 1)) << shift;
    5.76 +        shift += size * 8;
    5.77 +        port += size;
    5.78 +        bytes -= size;
    5.79 +    }
    5.80 +
    5.81 +    return data;
    5.82 +}
    5.83 +
    5.84 +static void guest_io_write(
    5.85 +    unsigned int port, unsigned int bytes, uint32_t data,
    5.86 +    struct vcpu *v, struct cpu_user_regs *regs)
    5.87 +{
    5.88 +    extern void pci_conf_write(
    5.89 +        uint32_t cf8, uint8_t offset, uint8_t bytes, uint32_t data);
    5.90 +
    5.91 +    if ( admin_io_okay(port, bytes, v, regs) )
    5.92 +    {
    5.93 +        switch ( bytes ) {
    5.94 +        case 1:
    5.95 +            outb((uint8_t)data, port);
    5.96 +            if ( pv_post_outb_hook )
    5.97 +                pv_post_outb_hook(port, (uint8_t)data);
    5.98 +            break;
    5.99 +        case 2:
   5.100 +            outw((uint16_t)data, port);
   5.101 +            break;
   5.102 +        case 4:
   5.103 +            outl(data, port);
   5.104 +            break;
   5.105 +        }
   5.106 +        return;
   5.107 +    }
   5.108 +
   5.109 +    while ( bytes != 0 )
   5.110 +    {
   5.111 +        unsigned int size = 1;
   5.112 +
   5.113 +        if ( (port == 0x42) || (port == 0x43) || (port == 0x61) )
   5.114 +        {
   5.115 +            pv_pit_handler(port, (uint8_t)data, 1);
   5.116 +        }
   5.117 +        else if ( (port & 0xfffc) == 0xcf8 )
   5.118 +        {
   5.119 +            size = min(bytes, 4 - (port & 3));
   5.120 +            if ( size == 4 )
   5.121 +            {
   5.122 +                v->domain->arch.pci_cf8 = data;
   5.123 +            }
   5.124 +            else
   5.125 +            {
   5.126 +                uint32_t mask = ((1u << (size * 8)) - 1) << ((port & 3) * 8);
   5.127 +                v->domain->arch.pci_cf8 &= ~mask;
   5.128 +                v->domain->arch.pci_cf8 |= (data << ((port & 3) * 8)) & mask;
   5.129 +            }
   5.130 +        }
   5.131 +        else if ( ((port & 0xfffc) == 0xcfc) && IS_PRIV(v->domain) )
   5.132 +        {
   5.133 +            size = min(bytes, 4 - (port & 3));
   5.134 +            if ( size == 3 )
   5.135 +                size = 2;
   5.136 +            pci_conf_write(v->domain->arch.pci_cf8, port & 3, size, data);
   5.137 +        }
   5.138 +
   5.139 +        if ( size == 4 )
   5.140 +            return;
   5.141 +
   5.142 +        port += size;
   5.143 +        bytes -= size;
   5.144 +        data >>= size * 8;
   5.145 +    }
   5.146 +}
   5.147  
   5.148  /* I/O emulation support. Helper routines for, and type of, the stack stub.*/
   5.149  void host_to_guest_gpr_switch(struct cpu_user_regs *)
   5.150 @@ -1526,7 +1637,7 @@ static int emulate_privileged_op(struct 
   5.151  
   5.152      /* REX prefix. */
   5.153      if ( rex & 8 ) /* REX.W */
   5.154 -        op_bytes = 4; /* emulating only opcodes not supporting 64-bit operands */
   5.155 +        op_bytes = 4; /* emulate only opcodes not supporting 64-bit operands */
   5.156      modrm_reg = (rex & 4) << 1;  /* REX.R */
   5.157      /* REX.X does not need to be decoded. */
   5.158      modrm_rm  = (rex & 1) << 3;  /* REX.B */
   5.159 @@ -1555,7 +1666,8 @@ static int emulate_privileged_op(struct 
   5.160          {
   5.161              if ( !read_descriptor(data_sel, v, regs,
   5.162                                    &data_base, &data_limit, &ar,
   5.163 -                                  _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|_SEGMENT_P) )
   5.164 +                                  _SEGMENT_WR|_SEGMENT_S|_SEGMENT_DPL|
   5.165 +                                  _SEGMENT_P) )
   5.166                  goto fail;
   5.167              if ( !(ar & _SEGMENT_S) ||
   5.168                   !(ar & _SEGMENT_P) ||
   5.169 @@ -1602,69 +1714,39 @@ static int emulate_privileged_op(struct 
   5.170          case 0x6c: /* INSB */
   5.171              op_bytes = 1;
   5.172          case 0x6d: /* INSW/INSL */
   5.173 -            if ( data_limit < op_bytes - 1 ||
   5.174 -                 rd_ad(edi) > data_limit - (op_bytes - 1) ||
   5.175 +            if ( (data_limit < (op_bytes - 1)) ||
   5.176 +                 (rd_ad(edi) > (data_limit - (op_bytes - 1))) ||
   5.177                   !guest_io_okay(port, op_bytes, v, regs) )
   5.178                  goto fail;
   5.179 -            switch ( op_bytes )
   5.180 -            {
   5.181 -            case 1:
   5.182 -                /* emulate PIT counter 2 */
   5.183 -                data = (u8)(guest_inb_okay(port, v, regs) ? inb(port) : 
   5.184 -                       ((port == 0x42 || port == 0x43 || port == 0x61) ?
   5.185 -                       pv_pit_handler(port, 0, 0) : ~0)); 
   5.186 -                break;
   5.187 -            case 2:
   5.188 -                data = (u16)(guest_inw_okay(port, v, regs) ? inw(port) : ~0);
   5.189 -                break;
   5.190 -            case 4:
   5.191 -                data = (u32)(guest_inl_okay(port, v, regs) ? inl(port) : ~0);
   5.192 -                break;
   5.193 -            }
   5.194 -            if ( (rc = copy_to_user((void *)data_base + rd_ad(edi), &data, op_bytes)) != 0 )
   5.195 +            data = guest_io_read(port, op_bytes, v, regs);
   5.196 +            if ( (rc = copy_to_user((void *)data_base + rd_ad(edi),
   5.197 +                                    &data, op_bytes)) != 0 )
   5.198              {
   5.199                  propagate_page_fault(data_base + rd_ad(edi) + op_bytes - rc,
   5.200                                       PFEC_write_access);
   5.201                  return EXCRET_fault_fixed;
   5.202              }
   5.203 -            wr_ad(edi, regs->edi + (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes));
   5.204 +            wr_ad(edi, regs->edi + (int)((regs->eflags & EF_DF)
   5.205 +                                         ? -op_bytes : op_bytes));
   5.206              break;
   5.207  
   5.208          case 0x6e: /* OUTSB */
   5.209              op_bytes = 1;
   5.210          case 0x6f: /* OUTSW/OUTSL */
   5.211 -            if ( data_limit < op_bytes - 1 ||
   5.212 -                 rd_ad(esi) > data_limit - (op_bytes - 1) ||
   5.213 -                 !guest_io_okay(port, op_bytes, v, regs) )
   5.214 +            if ( (data_limit < (op_bytes - 1)) ||
   5.215 +                 (rd_ad(esi) > (data_limit - (op_bytes - 1))) ||
   5.216 +                  !guest_io_okay(port, op_bytes, v, regs) )
   5.217                  goto fail;
   5.218 -            rc = copy_from_user(&data, (void *)data_base + rd_ad(esi), op_bytes);
   5.219 -            if ( rc != 0 )
   5.220 +            if ( (rc = copy_from_user(&data, (void *)data_base + rd_ad(esi),
   5.221 +                                      op_bytes)) != 0 )
   5.222              {
   5.223 -                propagate_page_fault(data_base + rd_ad(esi) + op_bytes - rc, 0);
   5.224 +                propagate_page_fault(data_base + rd_ad(esi)
   5.225 +                                     + op_bytes - rc, 0);
   5.226                  return EXCRET_fault_fixed;
   5.227              }
   5.228 -            switch ( op_bytes )
   5.229 -            {
   5.230 -            case 1:
   5.231 -                if ( guest_outb_okay(port, v, regs) )
   5.232 -                {
   5.233 -                    outb((u8)data, port);
   5.234 -                    if ( pv_post_outb_hook )
   5.235 -                        pv_post_outb_hook(port, data);
   5.236 -                }
   5.237 -                else if ( port == 0x42 || port == 0x43 || port == 0x61 )
   5.238 -                    pv_pit_handler(port, data, 1);
   5.239 -                break;
   5.240 -            case 2:
   5.241 -                if ( guest_outw_okay(port, v, regs) )
   5.242 -                    outw((u16)data, port);
   5.243 -                break;
   5.244 -            case 4:
   5.245 -                if ( guest_outl_okay(port, v, regs) )
   5.246 -                    outl((u32)data, port);
   5.247 -                break;
   5.248 -            }
   5.249 -            wr_ad(esi, regs->esi + (int)((regs->eflags & EF_DF) ? -op_bytes : op_bytes));
   5.250 +            guest_io_write(port, op_bytes, data, v, regs);
   5.251 +            wr_ad(esi, regs->esi + (int)((regs->eflags & EF_DF)
   5.252 +                                         ? -op_bytes : op_bytes));
   5.253              break;
   5.254          }
   5.255  
   5.256 @@ -1728,31 +1810,17 @@ static int emulate_privileged_op(struct 
   5.257      exec_in:
   5.258          if ( !guest_io_okay(port, op_bytes, v, regs) )
   5.259              goto fail;
   5.260 -        switch ( op_bytes )
   5.261 +        if ( admin_io_okay(port, op_bytes, v, regs) )
   5.262          {
   5.263 -        case 1:
   5.264 -            if ( guest_inb_okay(port, v, regs) )
   5.265 -                io_emul(regs);
   5.266 -            else if ( port == 0x42 || port == 0x43 || port == 0x61 )
   5.267 -            {
   5.268 -                regs->eax &= ~0xffUL;
   5.269 -                regs->eax |= pv_pit_handler(port, 0, 0);
   5.270 -            } 
   5.271 +            io_emul(regs);            
   5.272 +        }
   5.273 +        else
   5.274 +        {
   5.275 +            if ( op_bytes == 4 )
   5.276 +                regs->eax = 0;
   5.277              else
   5.278 -                regs->eax |= (u8)~0;
   5.279 -            break;
   5.280 -        case 2:
   5.281 -            if ( guest_inw_okay(port, v, regs) )
   5.282 -                io_emul(regs);
   5.283 -            else
   5.284 -                regs->eax |= (u16)~0;
   5.285 -            break;
   5.286 -        case 4:
   5.287 -            if ( guest_inl_okay(port, v, regs) )
   5.288 -                io_emul(regs);
   5.289 -            else
   5.290 -                regs->eax = (u32)~0;
   5.291 -            break;
   5.292 +                regs->eax &= ~((1u << (op_bytes * 8)) - 1);
   5.293 +            regs->eax |= guest_io_read(port, op_bytes, v, regs);
   5.294          }
   5.295          bpmatch = check_guest_io_breakpoint(v, port, op_bytes);
   5.296          goto done;
   5.297 @@ -1771,26 +1839,15 @@ static int emulate_privileged_op(struct 
   5.298      exec_out:
   5.299          if ( !guest_io_okay(port, op_bytes, v, regs) )
   5.300              goto fail;
   5.301 -        switch ( op_bytes )
   5.302 +        if ( admin_io_okay(port, op_bytes, v, regs) )
   5.303          {
   5.304 -        case 1:
   5.305 -            if ( guest_outb_okay(port, v, regs) )
   5.306 -            {
   5.307 -                io_emul(regs);
   5.308 -                if ( pv_post_outb_hook )
   5.309 -                    pv_post_outb_hook(port, regs->eax);
   5.310 -            }
   5.311 -            else if ( port == 0x42 || port == 0x43 || port == 0x61 )
   5.312 -                pv_pit_handler(port, regs->eax, 1);
   5.313 -            break;
   5.314 -        case 2:
   5.315 -            if ( guest_outw_okay(port, v, regs) )
   5.316 -                io_emul(regs);
   5.317 -            break;
   5.318 -        case 4:
   5.319 -            if ( guest_outl_okay(port, v, regs) )
   5.320 -                io_emul(regs);
   5.321 -            break;
   5.322 +            io_emul(regs);            
   5.323 +            if ( (op_bytes == 1) && pv_post_outb_hook )
   5.324 +                pv_post_outb_hook(port, regs->eax);
   5.325 +        }
   5.326 +        else
   5.327 +        {
   5.328 +            guest_io_write(port, op_bytes, regs->eax, v, regs);
   5.329          }
   5.330          bpmatch = check_guest_io_breakpoint(v, port, op_bytes);
   5.331          goto done;
     6.1 --- a/xen/drivers/passthrough/amd/iommu_detect.c	Fri Apr 11 09:14:03 2008 +0100
     6.2 +++ b/xen/drivers/passthrough/amd/iommu_detect.c	Fri Apr 11 13:19:55 2008 +0100
     6.3 @@ -21,9 +21,9 @@
     6.4  #include <xen/config.h>
     6.5  #include <xen/errno.h>
     6.6  #include <xen/iommu.h>
     6.7 +#include <xen/pci.h>
     6.8  #include <asm/amd-iommu.h>
     6.9  #include <asm/hvm/svm/amd-iommu-proto.h>
    6.10 -#include "../pci-direct.h"
    6.11  #include "../pci_regs.h"
    6.12  
    6.13  static int __init valid_bridge_bus_config(
    6.14 @@ -31,9 +31,9 @@ static int __init valid_bridge_bus_confi
    6.15  {
    6.16      int pri_bus;
    6.17  
    6.18 -    pri_bus = read_pci_config_byte(bus, dev, func, PCI_PRIMARY_BUS);
    6.19 -    *sec_bus = read_pci_config_byte(bus, dev, func, PCI_SECONDARY_BUS);
    6.20 -    *sub_bus = read_pci_config_byte(bus, dev, func, PCI_SUBORDINATE_BUS);
    6.21 +    pri_bus = pci_conf_read8(bus, dev, func, PCI_PRIMARY_BUS);
    6.22 +    *sec_bus = pci_conf_read8(bus, dev, func, PCI_SECONDARY_BUS);
    6.23 +    *sub_bus = pci_conf_read8(bus, dev, func, PCI_SUBORDINATE_BUS);
    6.24  
    6.25      return ((pri_bus == bus) && (*sec_bus > bus) && (*sub_bus >= *sec_bus));
    6.26  }
    6.27 @@ -59,12 +59,11 @@ int __init get_iommu_last_downstream_bus
    6.28          }
    6.29          func = PCI_FUNC(devfn);
    6.30   
    6.31 -        if ( !VALID_PCI_VENDOR_ID(
    6.32 -            read_pci_config_16(bus, dev, func, PCI_VENDOR_ID)) )
    6.33 +        if ( !VALID_PCI_VENDOR_ID(pci_conf_read16(bus, dev, func,
    6.34 +                                                  PCI_VENDOR_ID)) )
    6.35              continue;
    6.36  
    6.37 -        hdr_type = read_pci_config_byte(bus, dev, func,
    6.38 -                                        PCI_HEADER_TYPE);
    6.39 +        hdr_type = pci_conf_read8(bus, dev, func, PCI_HEADER_TYPE);
    6.40          if ( func == 0 )
    6.41              multi_func = IS_PCI_MULTI_FUNCTION(hdr_type);
    6.42  
    6.43 @@ -92,9 +91,9 @@ int __init get_iommu_capabilities(u8 bus
    6.44      u32 cap_header, cap_range, misc_info;
    6.45      u64 mmio_bar;
    6.46  
    6.47 -    mmio_bar = (u64)read_pci_config(
    6.48 +    mmio_bar = (u64)pci_conf_read32(
    6.49          bus, dev, func, cap_ptr + PCI_CAP_MMIO_BAR_HIGH_OFFSET) << 32;
    6.50 -    mmio_bar |= read_pci_config(bus, dev, func,
    6.51 +    mmio_bar |= pci_conf_read32(bus, dev, func,
    6.52                                  cap_ptr + PCI_CAP_MMIO_BAR_LOW_OFFSET);
    6.53      iommu->mmio_base_phys = mmio_bar & (u64)~0x3FFF;
    6.54  
    6.55 @@ -108,7 +107,7 @@ int __init get_iommu_capabilities(u8 bus
    6.56      iommu->bdf = (bus << 8) | PCI_DEVFN(dev, func);
    6.57      iommu->cap_offset = cap_ptr;
    6.58  
    6.59 -    cap_header = read_pci_config(bus, dev, func, cap_ptr);
    6.60 +    cap_header = pci_conf_read32(bus, dev, func, cap_ptr);
    6.61      iommu->revision = get_field_from_reg_u32(
    6.62          cap_header, PCI_CAP_REV_MASK, PCI_CAP_REV_SHIFT);
    6.63      iommu->iotlb_support = get_field_from_reg_u32(
    6.64 @@ -118,7 +117,7 @@ int __init get_iommu_capabilities(u8 bus
    6.65      iommu->pte_not_present_cached = get_field_from_reg_u32(
    6.66          cap_header, PCI_CAP_NP_CACHE_MASK, PCI_CAP_NP_CACHE_SHIFT);
    6.67  
    6.68 -    cap_range = read_pci_config(bus, dev, func,
    6.69 +    cap_range = pci_conf_read32(bus, dev, func,
    6.70                                  cap_ptr + PCI_CAP_RANGE_OFFSET);
    6.71      iommu->unit_id = get_field_from_reg_u32(
    6.72          cap_range, PCI_CAP_UNIT_ID_MASK, PCI_CAP_UNIT_ID_SHIFT);
    6.73 @@ -129,7 +128,7 @@ int __init get_iommu_capabilities(u8 bus
    6.74      iommu->last_devfn = get_field_from_reg_u32(
    6.75          cap_range, PCI_CAP_LAST_DEVICE_MASK, PCI_CAP_LAST_DEVICE_SHIFT);
    6.76  
    6.77 -    misc_info = read_pci_config(bus, dev, func,
    6.78 +    misc_info = pci_conf_read32(bus, dev, func,
    6.79                                  cap_ptr + PCI_MISC_INFO_OFFSET);
    6.80      iommu->msi_number = get_field_from_reg_u32(
    6.81          misc_info, PCI_CAP_MSI_NUMBER_MASK, PCI_CAP_MSI_NUMBER_SHIFT);
    6.82 @@ -146,14 +145,13 @@ static int __init scan_caps_for_iommu(
    6.83      int count, error = 0;
    6.84  
    6.85      count = 0;
    6.86 -    cap_ptr = read_pci_config_byte(bus, dev, func,
    6.87 -                                   PCI_CAPABILITY_LIST);
    6.88 +    cap_ptr = pci_conf_read8(bus, dev, func, PCI_CAPABILITY_LIST);
    6.89      while ( (cap_ptr >= PCI_MIN_CAP_OFFSET) &&
    6.90              (count < PCI_MAX_CAP_BLOCKS) &&
    6.91              !error )
    6.92      {
    6.93          cap_ptr &= PCI_CAP_PTR_MASK;
    6.94 -        cap_header = read_pci_config(bus, dev, func, cap_ptr);
    6.95 +        cap_header = pci_conf_read32(bus, dev, func, cap_ptr);
    6.96          cap_id = get_field_from_reg_u32(
    6.97              cap_header, PCI_CAP_ID_MASK, PCI_CAP_ID_SHIFT);
    6.98  
    6.99 @@ -182,12 +180,11 @@ static int __init scan_functions_for_iom
   6.100  
   6.101      func = 0;
   6.102      count = 1;
   6.103 -    while ( VALID_PCI_VENDOR_ID(read_pci_config_16(bus, dev, func,
   6.104 -                                                   PCI_VENDOR_ID)) &&
   6.105 +    while ( VALID_PCI_VENDOR_ID(pci_conf_read16(bus, dev, func,
   6.106 +                                                PCI_VENDOR_ID)) &&
   6.107              !error && (func < count) )
   6.108      {
   6.109 -        hdr_type = read_pci_config_byte(bus, dev, func,
   6.110 -                                        PCI_HEADER_TYPE);
   6.111 +        hdr_type = pci_conf_read8(bus, dev, func, PCI_HEADER_TYPE);
   6.112  
   6.113          if ( func == 0 && IS_PCI_MULTI_FUNCTION(hdr_type) )
   6.114              count = PCI_MAX_FUNC_COUNT;
     7.1 --- a/xen/drivers/passthrough/amd/iommu_init.c	Fri Apr 11 09:14:03 2008 +0100
     7.2 +++ b/xen/drivers/passthrough/amd/iommu_init.c	Fri Apr 11 13:19:55 2008 +0100
     7.3 @@ -20,10 +20,10 @@
     7.4  
     7.5  #include <xen/config.h>
     7.6  #include <xen/errno.h>
     7.7 +#include <xen/pci.h>
     7.8  #include <asm/amd-iommu.h>
     7.9  #include <asm/hvm/svm/amd-iommu-proto.h>
    7.10  #include <asm-x86/fixmap.h>
    7.11 -#include "../pci-direct.h"
    7.12  #include "../pci_regs.h"
    7.13  
    7.14  extern int nr_amd_iommus;
     8.1 --- a/xen/drivers/passthrough/amd/pci_amd_iommu.c	Fri Apr 11 09:14:03 2008 +0100
     8.2 +++ b/xen/drivers/passthrough/amd/pci_amd_iommu.c	Fri Apr 11 13:19:55 2008 +0100
     8.3 @@ -18,12 +18,12 @@
     8.4   * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
     8.5   */
     8.6  
     8.7 +#include <xen/sched.h>
     8.8 +#include <xen/pci.h>
     8.9  #include <asm/amd-iommu.h>
    8.10  #include <asm/hvm/svm/amd-iommu-proto.h>
    8.11  #include <asm/hvm/svm/amd-iommu-acpi.h>
    8.12 -#include <xen/sched.h>
    8.13  #include <asm/mm.h>
    8.14 -#include "../pci-direct.h"
    8.15  #include "../pci_regs.h"
    8.16  
    8.17  struct list_head amd_iommu_head;
    8.18 @@ -316,7 +316,7 @@ void __init amd_iommu_setup_dom0_devices
    8.19          {
    8.20              for ( func = 0; func < 8; func++ )
    8.21              {
    8.22 -                l = read_pci_config(bus, dev, func, PCI_VENDOR_ID);
    8.23 +                l = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID);
    8.24                  /* some broken boards return 0 or ~0 if a slot is empty: */
    8.25                  if ( (l == 0xffffffff) || (l == 0x00000000) ||
    8.26                       (l == 0x0000ffff) || (l == 0xffff0000) )
     9.1 --- a/xen/drivers/passthrough/pci-direct.h	Fri Apr 11 09:14:03 2008 +0100
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,48 +0,0 @@
     9.4 -#ifndef ASM_PCI_DIRECT_H
     9.5 -#define ASM_PCI_DIRECT_H 1
     9.6 -
     9.7 -#include <xen/types.h>
     9.8 -#include <asm/io.h>
     9.9 -
    9.10 -/* Direct PCI access. This is used for PCI accesses in early boot before
    9.11 -   the PCI subsystem works. */
    9.12 -
    9.13 -#define PDprintk(x...)
    9.14 -
    9.15 -static inline u32 read_pci_config(u8 bus, u8 slot, u8 func, u8 offset)
    9.16 -{
    9.17 -    u32 v;
    9.18 -    outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
    9.19 -    v = inl(0xcfc);
    9.20 -    if (v != 0xffffffff)
    9.21 -        PDprintk("%x reading 4 from %x: %x\n", slot, offset, v);
    9.22 -    return v;
    9.23 -}
    9.24 -
    9.25 -static inline u8 read_pci_config_byte(u8 bus, u8 slot, u8 func, u8 offset)
    9.26 -{
    9.27 -    u8 v;
    9.28 -    outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
    9.29 -    v = inb(0xcfc + (offset&3));
    9.30 -    PDprintk("%x reading 1 from %x: %x\n", slot, offset, v);
    9.31 -    return v;
    9.32 -}
    9.33 -
    9.34 -static inline u16 read_pci_config_16(u8 bus, u8 slot, u8 func, u8 offset)
    9.35 -{
    9.36 -    u16 v;
    9.37 -    outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
    9.38 -    v = inw(0xcfc + (offset&2));
    9.39 -    PDprintk("%x reading 2 from %x: %x\n", slot, offset, v);
    9.40 -    return v;
    9.41 -}
    9.42 -
    9.43 -static inline void write_pci_config(
    9.44 -    u8 bus, u8 slot, u8 func, u8 offset, u32 val)
    9.45 -{
    9.46 -    PDprintk("%x writing to %x: %x\n", slot, offset, val);
    9.47 -    outl(0x80000000 | (bus<<16) | (slot<<11) | (func<<8) | offset, 0xcf8);
    9.48 -    outl(val, 0xcfc);
    9.49 -}
    9.50 -
    9.51 -#endif
    10.1 --- a/xen/drivers/passthrough/vtd/dmar.c	Fri Apr 11 09:14:03 2008 +0100
    10.2 +++ b/xen/drivers/passthrough/vtd/dmar.c	Fri Apr 11 13:19:55 2008 +0100
    10.3 @@ -25,9 +25,9 @@
    10.4  #include <xen/acpi.h>
    10.5  #include <xen/mm.h>
    10.6  #include <xen/xmalloc.h>
    10.7 +#include <xen/pci.h>
    10.8  #include <asm/string.h>
    10.9  #include "dmar.h"
   10.10 -#include "../pci-direct.h"
   10.11  #include "../pci_regs.h"
   10.12  
   10.13  int vtd_enabled;
   10.14 @@ -233,7 +233,7 @@ static int scope_device_count(void *star
   10.15  		    / sizeof(struct acpi_pci_path);
   10.16          while ( --depth > 0 )
   10.17          {
   10.18 -            bus = read_pci_config_byte(
   10.19 +            bus = pci_conf_read8(
   10.20                  bus, path->dev, path->fn, PCI_SECONDARY_BUS);
   10.21              path++;
   10.22          }
   10.23 @@ -250,9 +250,9 @@ static int scope_device_count(void *star
   10.24              dprintk(XENLOG_INFO VTDPREFIX,
   10.25                      "found bridge: bdf = %x:%x:%x\n",
   10.26                      bus, path->dev, path->fn);
   10.27 -            sec_bus = read_pci_config_byte(
   10.28 +            sec_bus = pci_conf_read8(
   10.29                  bus, path->dev, path->fn, PCI_SECONDARY_BUS);
   10.30 -            sub_bus = read_pci_config_byte(
   10.31 +            sub_bus = pci_conf_read8(
   10.32                  bus, path->dev, path->fn, PCI_SUBORDINATE_BUS);
   10.33  
   10.34              while ( sec_bus <= sub_bus )
   10.35 @@ -261,7 +261,7 @@ static int scope_device_count(void *star
   10.36                  {
   10.37                      for ( func = 0; func < 8; func++ )
   10.38                      {
   10.39 -                        l = read_pci_config(
   10.40 +                        l = pci_conf_read32(
   10.41                              sec_bus, dev, func, PCI_VENDOR_ID);
   10.42  
   10.43                          /* some broken boards return 0 or
   10.44 @@ -355,7 +355,7 @@ static int __init acpi_parse_dev_scope(
   10.45  
   10.46          while ( --depth > 0 )
   10.47          {
   10.48 -            bus = read_pci_config_byte(
   10.49 +            bus = pci_conf_read8(
   10.50                  bus, path->dev, path->fn, PCI_SECONDARY_BUS);
   10.51              path++;
   10.52          }
   10.53 @@ -374,9 +374,9 @@ static int __init acpi_parse_dev_scope(
   10.54              dprintk(XENLOG_INFO VTDPREFIX,
   10.55                      "found bridge: bus = %x dev = %x func = %x\n",
   10.56                      bus, path->dev, path->fn);
   10.57 -            sec_bus = read_pci_config_byte(
   10.58 +            sec_bus = pci_conf_read8(
   10.59                  bus, path->dev, path->fn, PCI_SECONDARY_BUS);
   10.60 -            sub_bus = read_pci_config_byte(
   10.61 +            sub_bus = pci_conf_read8(
   10.62                  bus, path->dev, path->fn, PCI_SUBORDINATE_BUS);
   10.63  
   10.64              while ( sec_bus <= sub_bus )
   10.65 @@ -385,7 +385,7 @@ static int __init acpi_parse_dev_scope(
   10.66                  {
   10.67                      for ( func = 0; func < 8; func++ )
   10.68                      {
   10.69 -                        l = read_pci_config(
   10.70 +                        l = pci_conf_read32(
   10.71                              sec_bus, dev, func, PCI_VENDOR_ID);
   10.72  
   10.73                          /* some broken boards return 0 or
    11.1 --- a/xen/drivers/passthrough/vtd/intremap.c	Fri Apr 11 09:14:03 2008 +0100
    11.2 +++ b/xen/drivers/passthrough/vtd/intremap.c	Fri Apr 11 13:19:55 2008 +0100
    11.3 @@ -22,10 +22,10 @@
    11.4  #include <xen/sched.h>
    11.5  #include <xen/iommu.h>
    11.6  #include <xen/time.h>
    11.7 +#include <xen/pci.h>
    11.8  #include "iommu.h"
    11.9  #include "dmar.h"
   11.10  #include "vtd.h"
   11.11 -#include "../pci-direct.h"
   11.12  #include "../pci_regs.h"
   11.13  #include "msi.h"
   11.14  #include "extern.h"
    12.1 --- a/xen/drivers/passthrough/vtd/iommu.c	Fri Apr 11 09:14:03 2008 +0100
    12.2 +++ b/xen/drivers/passthrough/vtd/iommu.c	Fri Apr 11 13:19:55 2008 +0100
    12.3 @@ -23,13 +23,13 @@
    12.4  #include <xen/sched.h>
    12.5  #include <xen/xmalloc.h>
    12.6  #include <xen/domain_page.h>
    12.7 -#include <asm/paging.h>
    12.8  #include <xen/iommu.h>
    12.9  #include <xen/numa.h>
   12.10  #include <xen/time.h>
   12.11 +#include <xen/pci.h>
   12.12 +#include <asm/paging.h>
   12.13  #include "iommu.h"
   12.14  #include "dmar.h"
   12.15 -#include "../pci-direct.h"
   12.16  #include "../pci_regs.h"
   12.17  #include "msi.h"
   12.18  #include "extern.h"
   12.19 @@ -1228,13 +1228,13 @@ static int __pci_find_next_cap(u8 bus, u
   12.20  
   12.21      while ( ttl-- )
   12.22      {
   12.23 -        pos = read_pci_config_byte(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
   12.24 +        pos = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn), pos);
   12.25          if ( pos < 0x40 )
   12.26              break;
   12.27  
   12.28          pos &= ~3;
   12.29 -        id = read_pci_config_byte(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
   12.30 -                                  pos + PCI_CAP_LIST_ID);
   12.31 +        id = pci_conf_read8(bus, PCI_SLOT(devfn), PCI_FUNC(devfn),
   12.32 +                            pos + PCI_CAP_LIST_ID);
   12.33  
   12.34          if ( id == 0xff )
   12.35              break;
   12.36 @@ -1258,13 +1258,13 @@ int pdev_type(struct pci_dev *dev)
   12.37      u16 class_device;
   12.38      u16 status;
   12.39  
   12.40 -    class_device = read_pci_config_16(dev->bus, PCI_SLOT(dev->devfn),
   12.41 -                                      PCI_FUNC(dev->devfn), PCI_CLASS_DEVICE);
   12.42 +    class_device = pci_conf_read16(dev->bus, PCI_SLOT(dev->devfn),
   12.43 +                                   PCI_FUNC(dev->devfn), PCI_CLASS_DEVICE);
   12.44      if ( class_device == PCI_CLASS_BRIDGE_PCI )
   12.45          return DEV_TYPE_PCI_BRIDGE;
   12.46  
   12.47 -    status = read_pci_config_16(dev->bus, PCI_SLOT(dev->devfn),
   12.48 -                                PCI_FUNC(dev->devfn), PCI_STATUS);
   12.49 +    status = pci_conf_read16(dev->bus, PCI_SLOT(dev->devfn),
   12.50 +                             PCI_FUNC(dev->devfn), PCI_STATUS);
   12.51  
   12.52      if ( !(status & PCI_STATUS_CAP_LIST) )
   12.53          return DEV_TYPE_PCI;
   12.54 @@ -1292,7 +1292,7 @@ static int domain_context_mapping(
   12.55      switch ( type )
   12.56      {
   12.57      case DEV_TYPE_PCI_BRIDGE:
   12.58 -        sec_bus = read_pci_config_byte(
   12.59 +        sec_bus = pci_conf_read8(
   12.60              pdev->bus, PCI_SLOT(pdev->devfn),
   12.61              PCI_FUNC(pdev->devfn), PCI_SECONDARY_BUS);
   12.62  
   12.63 @@ -1302,7 +1302,7 @@ static int domain_context_mapping(
   12.64              bus2bridge[sec_bus].devfn =  pdev->devfn;
   12.65          }
   12.66  
   12.67 -        sub_bus = read_pci_config_byte(
   12.68 +        sub_bus = pci_conf_read8(
   12.69              pdev->bus, PCI_SLOT(pdev->devfn),
   12.70              PCI_FUNC(pdev->devfn), PCI_SUBORDINATE_BUS);
   12.71  
   12.72 @@ -1425,10 +1425,10 @@ static int domain_context_unmap(
   12.73      switch ( type )
   12.74      {
   12.75      case DEV_TYPE_PCI_BRIDGE:
   12.76 -        sec_bus = read_pci_config_byte(
   12.77 +        sec_bus = pci_conf_read8(
   12.78              pdev->bus, PCI_SLOT(pdev->devfn),
   12.79              PCI_FUNC(pdev->devfn), PCI_SECONDARY_BUS);
   12.80 -        sub_bus = read_pci_config_byte(
   12.81 +        sub_bus = pci_conf_read8(
   12.82              pdev->bus, PCI_SLOT(pdev->devfn),
   12.83              PCI_FUNC(pdev->devfn), PCI_SUBORDINATE_BUS);
   12.84  
   12.85 @@ -1781,7 +1781,7 @@ void __init setup_dom0_devices(void)
   12.86          {
   12.87              for ( func = 0; func < 8; func++ )
   12.88              {
   12.89 -                l = read_pci_config(bus, dev, func, PCI_VENDOR_ID);
   12.90 +                l = pci_conf_read32(bus, dev, func, PCI_VENDOR_ID);
   12.91                  /* some broken boards return 0 or ~0 if a slot is empty: */
   12.92                  if ( (l == 0xffffffff) || (l == 0x00000000) ||
   12.93                       (l == 0x0000ffff) || (l == 0xffff0000) )
    13.1 --- a/xen/drivers/passthrough/vtd/qinval.c	Fri Apr 11 09:14:03 2008 +0100
    13.2 +++ b/xen/drivers/passthrough/vtd/qinval.c	Fri Apr 11 13:19:55 2008 +0100
    13.3 @@ -22,10 +22,10 @@
    13.4  #include <xen/sched.h>
    13.5  #include <xen/iommu.h>
    13.6  #include <xen/time.h>
    13.7 +#include <xen/pci.h>
    13.8  #include "iommu.h"
    13.9  #include "dmar.h"
   13.10  #include "vtd.h"
   13.11 -#include "../pci-direct.h"
   13.12  #include "../pci_regs.h"
   13.13  #include "msi.h"
   13.14  #include "extern.h"
    14.1 --- a/xen/drivers/passthrough/vtd/utils.c	Fri Apr 11 09:14:03 2008 +0100
    14.2 +++ b/xen/drivers/passthrough/vtd/utils.c	Fri Apr 11 13:19:55 2008 +0100
    14.3 @@ -21,9 +21,9 @@
    14.4  #include <xen/delay.h>
    14.5  #include <xen/iommu.h>
    14.6  #include <xen/time.h>
    14.7 +#include <xen/pci.h>
    14.8  #include "iommu.h"
    14.9  #include "dmar.h"
   14.10 -#include "../pci-direct.h"
   14.11  #include "../pci_regs.h"
   14.12  #include "msi.h"
   14.13  #include "vtd.h"
   14.14 @@ -37,7 +37,7 @@ int is_usb_device(struct pci_dev *pdev)
   14.15      u8 bus = pdev->bus;
   14.16      u8 dev = PCI_SLOT(pdev->devfn);
   14.17      u8 func = PCI_FUNC(pdev->devfn);
   14.18 -    u16 class = read_pci_config_16(bus, dev, func, PCI_CLASS_DEVICE);
   14.19 +    u16 class = pci_conf_read16(bus, dev, func, PCI_CLASS_DEVICE);
   14.20      return (class == 0xc03);
   14.21  }
   14.22  
   14.23 @@ -46,9 +46,9 @@ int vtd_hw_check(void)
   14.24      u16 vendor, device;
   14.25      u8 revision, stepping;
   14.26  
   14.27 -    vendor   = read_pci_config_16(0, 0, 0, PCI_VENDOR_ID);
   14.28 -    device   = read_pci_config_16(0, 0, 0, PCI_DEVICE_ID);
   14.29 -    revision = read_pci_config_byte(0, 0, 0, PCI_REVISION_ID);
   14.30 +    vendor   = pci_conf_read16(0, 0, 0, PCI_VENDOR_ID);
   14.31 +    device   = pci_conf_read16(0, 0, 0, PCI_DEVICE_ID);
   14.32 +    revision = pci_conf_read8(0, 0, 0, PCI_REVISION_ID);
   14.33      stepping = revision & 0xf;
   14.34  
   14.35      if ( (vendor == INTEL) && (device == SEABURG) )
   14.36 @@ -103,18 +103,18 @@ static u8 find_cap_offset(u8 bus, u8 dev
   14.37      u8 pos = PCI_CAPABILITY_LIST;
   14.38      u16 status;
   14.39  
   14.40 -    status = read_pci_config_16(bus, dev, func, PCI_STATUS);
   14.41 +    status = pci_conf_read16(bus, dev, func, PCI_STATUS);
   14.42      if ( (status & PCI_STATUS_CAP_LIST) == 0 )
   14.43          return 0;
   14.44  
   14.45      while ( max_cap-- )
   14.46      {
   14.47 -        pos = read_pci_config_byte(bus, dev, func, pos);
   14.48 +        pos = pci_conf_read8(bus, dev, func, pos);
   14.49          if ( pos < 0x40 )
   14.50              break;
   14.51  
   14.52          pos &= ~3;
   14.53 -        id = read_pci_config_byte(bus, dev, func, pos + PCI_CAP_LIST_ID);
   14.54 +        id = pci_conf_read8(bus, dev, func, pos + PCI_CAP_LIST_ID);
   14.55  
   14.56          if ( id == 0xff )
   14.57              break;
   14.58 @@ -143,13 +143,13 @@ void pdev_flr(u8 bus, u8 devfn)
   14.59      pos = find_cap_offset(bus, dev, func, PCI_CAP_ID_EXP);
   14.60      if ( pos != 0 )
   14.61      {
   14.62 -        dev_cap = read_pci_config(bus, dev, func, pos + PCI_EXP_DEVCAP);
   14.63 +        dev_cap = pci_conf_read32(bus, dev, func, pos + PCI_EXP_DEVCAP);
   14.64          if ( dev_cap & PCI_EXP_DEVCAP_FLR )
   14.65          {
   14.66 -            write_pci_config(bus, dev, func,
   14.67 +            pci_conf_write32(bus, dev, func,
   14.68                               pos + PCI_EXP_DEVCTL, PCI_EXP_DEVCTL_FLR);
   14.69              do {
   14.70 -                dev_status = read_pci_config(bus, dev, func,
   14.71 +                dev_status = pci_conf_read32(bus, dev, func,
   14.72                                               pos + PCI_EXP_DEVSTA);
   14.73              } while ( dev_status & PCI_EXP_DEVSTA_TRPND );
   14.74  
   14.75 @@ -169,23 +169,23 @@ void pdev_flr(u8 bus, u8 devfn)
   14.76              int i;
   14.77              u32 config[PCI_CONFIG_DWORD_SIZE];
   14.78              for ( i = 0; i < PCI_CONFIG_DWORD_SIZE; i++ )
   14.79 -                config[i] = read_pci_config(bus, dev, func, i*4);
   14.80 +                config[i] = pci_conf_read32(bus, dev, func, i*4);
   14.81  
   14.82              /* Enter D3hot without soft reset */
   14.83 -            pm_ctl = read_pci_config(bus, dev, func, pos + PCI_PM_CTRL);
   14.84 +            pm_ctl = pci_conf_read32(bus, dev, func, pos + PCI_PM_CTRL);
   14.85              pm_ctl |= PCI_PM_CTRL_NO_SOFT_RESET;
   14.86              pm_ctl &= ~PCI_PM_CTRL_STATE_MASK;
   14.87              pm_ctl |= PCI_D3hot;
   14.88 -            write_pci_config(bus, dev, func, pos + PCI_PM_CTRL, pm_ctl);
   14.89 +            pci_conf_write32(bus, dev, func, pos + PCI_PM_CTRL, pm_ctl);
   14.90              mdelay(10);
   14.91  
   14.92              /* From D3hot to D0 */
   14.93 -            write_pci_config(bus, dev, func, pos + PCI_PM_CTRL, 0);
   14.94 +            pci_conf_write32(bus, dev, func, pos + PCI_PM_CTRL, 0);
   14.95              mdelay(10);
   14.96  
   14.97              /* Write saved configurations to device */
   14.98              for ( i = 0; i < PCI_CONFIG_DWORD_SIZE; i++ )
   14.99 -                write_pci_config(bus, dev, func, i*4, config[i]);
  14.100 +                pci_conf_write32(bus, dev, func, i*4, config[i]);
  14.101  
  14.102              flr = 1;
  14.103          }
    15.1 --- a/xen/include/asm-x86/domain.h	Fri Apr 11 09:14:03 2008 +0100
    15.2 +++ b/xen/include/asm-x86/domain.h	Fri Apr 11 13:19:55 2008 +0100
    15.3 @@ -209,6 +209,7 @@ struct arch_domain
    15.4  
    15.5      /* I/O-port admin-specified access capabilities. */
    15.6      struct rangeset *ioport_caps;
    15.7 +    uint32_t pci_cf8;
    15.8  
    15.9      struct hvm_domain hvm_domain;
   15.10  
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/xen/include/xen/pci.h	Fri Apr 11 13:19:55 2008 +0100
    16.3 @@ -0,0 +1,29 @@
    16.4 +/******************************************************************************
    16.5 + * pci.h
    16.6 + * 
    16.7 + * PCI access functions.
    16.8 + */
    16.9 +
   16.10 +#ifndef __XEN_PCI_H__
   16.11 +#define __XEN_PCI_H__
   16.12 +
   16.13 +#include <xen/config.h>
   16.14 +#include <xen/types.h>
   16.15 +
   16.16 +uint8_t pci_conf_read8(
   16.17 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg);
   16.18 +uint16_t pci_conf_read16(
   16.19 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg);
   16.20 +uint32_t pci_conf_read32(
   16.21 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg);
   16.22 +void pci_conf_write8(
   16.23 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
   16.24 +    uint8_t data);
   16.25 +void pci_conf_write16(
   16.26 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
   16.27 +    uint16_t data);
   16.28 +void pci_conf_write32(
   16.29 +    unsigned int bus, unsigned int dev, unsigned int func, unsigned int reg,
   16.30 +    uint32_t data);
   16.31 +
   16.32 +#endif /* __XEN_PCI_H__ */