anthony.perard@citrix.com
2010-Oct-25 18:28 UTC
[Xen-devel] [PATCH V2 0/3] firmware changes as part of QEMU/Xen merge.
From: Anthony PERARD <anthony.perard@citrix.com> This patches are for Xen-unstable and Qemu-DM. With the integration of Xen into QEMU, we would like to minimise the change and use the ACPI implementation of QEMU. So there are some change to make on the firmware to match the QEMU''s BIOS. Some IO Ports are different and the sleep state values are different. Change with the v1: This time, both old and new ioport are handled. In QEMU-Xen, the choice between one or the other is made when a saved state is restored. In Xen, both ioports are registered. Anthony PERARD (2): firmware, Change ACPI IO addresses and values to match QEMU BIOS. xen, handle both old and new acpi ioport. tools/firmware/hvmloader/acpi/dsdt.asl | 12 ++++++------ tools/firmware/hvmloader/hvmloader.c | 4 ++++ xen/arch/x86/hvm/pmtimer.c | 10 ++++++++++ xen/include/public/hvm/ioreq.h | 16 +++++++++++++--- 4 files changed, 33 insertions(+), 9 deletions(-) Anthony PERARD (1): piix4acpi: change in ACPI to match the change in the BIOS. hw/piix4acpi.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 80 insertions(+), 17 deletions(-) -- Anthony PERARD _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Oct-25 18:28 UTC
[Xen-devel] [PATCH V2 1/3] firmware, Change ACPI IO addresses and values to match QEMU BIOS.
From: Anthony PERARD <anthony.perard@citrix.com> As part of the QEMU/Xen merge, this patch comes to change the IO Port adresses, the value of sleep states and add some information in the PCI registers to match the implementation of the BIOS of QEMU. This patch must be applied at the same time with an other patch for the piix4acpi of qemu-xen. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- tools/firmware/hvmloader/acpi/dsdt.asl | 12 ++++++------ tools/firmware/hvmloader/hvmloader.c | 4 ++++ xen/include/public/hvm/ioreq.h | 16 +++++++++++++--- 3 files changed, 23 insertions(+), 9 deletions(-) diff --git a/tools/firmware/hvmloader/acpi/dsdt.asl b/tools/firmware/hvmloader/acpi/dsdt.asl index 03799d3..ea8e324 100644 --- a/tools/firmware/hvmloader/acpi/dsdt.asl +++ b/tools/firmware/hvmloader/acpi/dsdt.asl @@ -33,22 +33,22 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0) */ Name (\_S3, Package (0x04) { - 0x05, /* PM1a_CNT.SLP_TYP */ - 0x05, /* PM1b_CNT.SLP_TYP */ + 0x01, /* PM1a_CNT.SLP_TYP */ + 0x01, /* PM1b_CNT.SLP_TYP */ 0x0, /* reserved */ 0x0 /* reserved */ }) Name (\_S4, Package (0x04) { - 0x06, /* PM1a_CNT.SLP_TYP */ - 0x06, /* PM1b_CNT.SLP_TYP */ + 0x00, /* PM1a_CNT.SLP_TYP */ + 0x00, /* PM1b_CNT.SLP_TYP */ 0x00, /* reserved */ 0x00 /* reserved */ }) Name (\_S5, Package (0x04) { - 0x07, /* PM1a_CNT.SLP_TYP */ - 0x07, /* PM1b_CNT.SLP_TYP */ + 0x00, /* PM1a_CNT.SLP_TYP */ + 0x00, /* PM1b_CNT.SLP_TYP */ 0x00, /* reserved */ 0x00 /* reserved */ }) diff --git a/tools/firmware/hvmloader/hvmloader.c b/tools/firmware/hvmloader/hvmloader.c index c4c5ddc..cfe026f 100644 --- a/tools/firmware/hvmloader/hvmloader.c +++ b/tools/firmware/hvmloader/hvmloader.c @@ -31,6 +31,7 @@ #include "option_rom.h" #include <xen/version.h> #include <xen/hvm/params.h> +#include <xen/hvm/ioreq.h> #include <xen/memory.h> asm ( @@ -222,9 +223,12 @@ static void pci_setup(void) /* PIIX4 ACPI PM. Special device with special PCI config space. */ ASSERT((vendor_id == 0x8086) && (device_id == 0x7113)); pci_writew(devfn, 0x20, 0x0000); /* No smb bus IO enable */ + pci_writew(devfn, 0xd2, 0x0000); /* No smb bus IO enable */ pci_writew(devfn, 0x22, 0x0000); pci_writew(devfn, 0x3c, 0x0009); /* Hardcoded IRQ9 */ pci_writew(devfn, 0x3d, 0x0001); + pci_writel(devfn, 0x40, ACPI_PM1A_EVT_BLK_ADDRESS | 1); + pci_writeb(devfn, 0x80, 0x01); /* enable PM io space */ break; case 0x0101: if ( vendor_id == 0x8086 ) diff --git a/xen/include/public/hvm/ioreq.h b/xen/include/public/hvm/ioreq.h index 0c10c08..8c11767 100644 --- a/xen/include/public/hvm/ioreq.h +++ b/xen/include/public/hvm/ioreq.h @@ -100,11 +100,21 @@ struct buffered_piopage { }; #endif /* defined(__ia64__) */ -#define ACPI_PM1A_EVT_BLK_ADDRESS 0x0000000000001f40 +/* + * Value used by old qemu-dm, there have been replace to match + * the QEMU BIOS. + */ +#define ACPI_PM1A_EVT_BLK_ADDRESS_OLD 0x0000000000001f40 +#define ACPI_PM1A_CNT_BLK_ADDRESS_OLD (ACPI_PM1A_EVT_BLK_ADDRESS_OLD + 0x04) +#define ACPI_PM_TMR_BLK_ADDRESS_OLD (ACPI_PM1A_EVT_BLK_ADDRESS_OLD + 0x08) +#define ACPI_GPE0_BLK_ADDRESS_OLD (ACPI_PM_TMR_BLK_ADDRESS_OLD + 0x20) +#define ACPI_GPE0_BLK_LEN_OLD 0x08 + +#define ACPI_PM1A_EVT_BLK_ADDRESS 0x000000000000b000 #define ACPI_PM1A_CNT_BLK_ADDRESS (ACPI_PM1A_EVT_BLK_ADDRESS + 0x04) #define ACPI_PM_TMR_BLK_ADDRESS (ACPI_PM1A_EVT_BLK_ADDRESS + 0x08) -#define ACPI_GPE0_BLK_ADDRESS (ACPI_PM_TMR_BLK_ADDRESS + 0x20) -#define ACPI_GPE0_BLK_LEN 0x08 +#define ACPI_GPE0_BLK_ADDRESS (0x000000000000afe0) +#define ACPI_GPE0_BLK_LEN 0x04 #endif /* _IOREQ_H_ */ -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Oct-25 18:28 UTC
[Xen-devel] [PATCH V2 2/3] xen, handle both old and new acpi ioport.
From: Anthony PERARD <anthony.perard@citrix.com> With the change of the firmware, we have to handle the new ioport and keep the old one. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- xen/arch/x86/hvm/pmtimer.c | 10 ++++++++++ 1 files changed, 10 insertions(+), 0 deletions(-) diff --git a/xen/arch/x86/hvm/pmtimer.c b/xen/arch/x86/hvm/pmtimer.c index 48fe26a..ee0558f 100644 --- a/xen/arch/x86/hvm/pmtimer.c +++ b/xen/arch/x86/hvm/pmtimer.c @@ -24,6 +24,9 @@ #include <asm/acpi.h> /* for hvm_acpi_power_button prototype */ /* Slightly more readable port I/O addresses for the registers we intercept */ +#define PM1a_STS_ADDR_OLD (ACPI_PM1A_EVT_BLK_ADDRESS_OLD) +#define PM1a_EN_ADDR_OLD (ACPI_PM1A_EVT_BLK_ADDRESS_OLD + 2) +#define TMR_VAL_ADDR_OLD (ACPI_PM_TMR_BLK_ADDRESS_OLD) #define PM1a_STS_ADDR (ACPI_PM1A_EVT_BLK_ADDRESS) #define PM1a_EN_ADDR (ACPI_PM1A_EVT_BLK_ADDRESS + 2) #define TMR_VAL_ADDR (ACPI_PM_TMR_BLK_ADDRESS) @@ -153,16 +156,20 @@ static int handle_evt_io( switch ( addr ) { /* PM1a_STS register bits are write-to-clear */ + case PM1a_STS_ADDR_OLD: case PM1a_STS_ADDR: s->pm.pm1a_sts &= ~byte; break; + case PM1a_STS_ADDR_OLD + 1: case PM1a_STS_ADDR + 1: s->pm.pm1a_sts &= ~(byte << 8); break; + case PM1a_EN_ADDR_OLD: case PM1a_EN_ADDR: s->pm.pm1a_en = (s->pm.pm1a_en & 0xff00) | byte; break; + case PM1a_EN_ADDR_OLD + 1: case PM1a_EN_ADDR + 1: s->pm.pm1a_en = (s->pm.pm1a_en & 0xff) | (byte << 8); break; @@ -280,6 +287,9 @@ void pmtimer_init(struct vcpu *v) /* Intercept port I/O (need two handlers because PM1a_CNT is between * PM1a_EN and TMR_VAL and is handled by qemu) */ + /* Add handler for both old and new port I/O of the firmware */ + register_portio_handler(v->domain, TMR_VAL_ADDR_OLD, 4, handle_pmt_io); + register_portio_handler(v->domain, PM1a_STS_ADDR_OLD, 4, handle_evt_io); register_portio_handler(v->domain, TMR_VAL_ADDR, 4, handle_pmt_io); register_portio_handler(v->domain, PM1a_STS_ADDR, 4, handle_evt_io); -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
anthony.perard@citrix.com
2010-Oct-25 18:28 UTC
[Xen-devel] [PATCH V2 3/3] piix4acpi: change in ACPI to match the change in the BIOS.
From: Anthony PERARD <anthony.perard@citrix.com> Some change have been introduced in the firmware to match QEMU''s BIOS. So this patch adds the new sleep state values and handle old and new ACPI IOPort mapping. QEMU-Xen uses new ioport by default, but if it''s a saved state with old firmware, it unmaps the new ioport and maps the old one. Signed-off-by: Anthony PERARD <anthony.perard@citrix.com> --- hw/piix4acpi.c | 97 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 files changed, 80 insertions(+), 17 deletions(-) diff --git a/hw/piix4acpi.c b/hw/piix4acpi.c index 1efa77d..589d4a4 100644 --- a/hw/piix4acpi.c +++ b/hw/piix4acpi.c @@ -52,9 +52,12 @@ /* Sleep state type codes as defined by the \_Sx objects in the DSDT. */ /* These must be kept in sync with the DSDT (hvmloader/acpi/dsdt.asl) */ -#define SLP_TYP_S4 (6 << 10) -#define SLP_TYP_S3 (5 << 10) -#define SLP_TYP_S5 (7 << 10) +#define SLP_TYP_S4_OLD (6 << 10) +#define SLP_TYP_S3_OLD (5 << 10) +#define SLP_TYP_S5_OLD (7 << 10) +#define SLP_TYP_S4 (0 << 10) +#define SLP_TYP_S3 (1 << 10) +#define SLP_TYP_S5 (0 << 10) #define ACPI_DBG_IO_ADDR 0xb044 #define ACPI_PHP_IO_ADDR 0x10c0 @@ -75,12 +78,15 @@ typedef struct PCIAcpiState { PCIDevice dev; uint16_t pm1_control; /* pm1a_ECNT_BLK */ + + /* if true, use old ioport of the firmware. */ + uint8_t use_old_ioport; } PCIAcpiState; typedef struct GPEState { /* GPE0 block */ - uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN / 2]; - uint8_t gpe0_en[ACPI_GPE0_BLK_LEN / 2]; + uint8_t gpe0_sts[ACPI_GPE0_BLK_LEN_OLD / 2]; + uint8_t gpe0_en[ACPI_GPE0_BLK_LEN_OLD / 2]; /* CPU bitmap */ uint8_t cpus_sts[32]; @@ -88,6 +94,8 @@ typedef struct GPEState { /* SCI IRQ level */ uint8_t sci_asserted; + /* if true, use old ioport of the firmware. */ + uint8_t use_old_ioport; } GPEState; static GPEState gpe_state; @@ -100,6 +108,9 @@ typedef struct PHPDevFn { * PSTB in ASL */ } PHPDevFn; +static void acpi_map(PCIDevice *pci_dev, int region_num, + uint32_t addr, uint32_t size, int type); + static PHPDevFn php_devfn; int s3_shutdown_flag; static qemu_irq sci_irq; @@ -138,18 +149,34 @@ static void piix4acpi_save(QEMUFile *f, void *opaque) PCIAcpiState *s = opaque; pci_device_save(&s->dev, f); qemu_put_be16s(f, &s->pm1_control); + qemu_put_8s(f, &s->use_old_ioport); } static int piix4acpi_load(QEMUFile *f, void *opaque, int version_id) { PCIAcpiState *s = opaque; int ret; - if (version_id > 1) + + if (version_id > 2) return -EINVAL; ret = pci_device_load(&s->dev, f); if (ret < 0) return ret; qemu_get_be16s(f, &s->pm1_control); + + if (version_id <= 1) { + /* map to old ioport instead of the new one */ + s->use_old_ioport = 1; + } else { + qemu_get_8s(f, &s->use_old_ioport); + } + + if (s->use_old_ioport) { + PIIX4ACPI_LOG(PIIX4ACPI_LOG_INFO, "ACPI: Use old firmware IOPorts.\n"); + /* unmap new ioport to use old ioport */ + isa_unassign_ioport(ACPI_PM1A_EVT_BLK_ADDRESS + 4, 2); + acpi_map((PCIDevice *)s, 0, ACPI_PM1A_EVT_BLK_ADDRESS_OLD, 0x10, PCI_ADDRESS_SPACE_IO); + } return 0; } @@ -172,6 +199,7 @@ static void acpi_shutdown(uint32_t val) return; switch (val & SLP_TYP_Sx) { + case SLP_TYP_S3_OLD: case SLP_TYP_S3: s3_shutdown_flag = 1; qemu_system_reset(); @@ -179,7 +207,8 @@ static void acpi_shutdown(uint32_t val) cmos_set_s3_resume(); xc_set_hvm_param(xc_handle, domid, HVM_PARAM_ACPI_S_STATE, 3); break; - case SLP_TYP_S4: + case SLP_TYP_S4_OLD: + case SLP_TYP_S5_OLD: case SLP_TYP_S5: qemu_system_shutdown_request(); break; @@ -403,7 +432,10 @@ static uint32_t gpe_sts_read(void *opaque, uint32_t addr) { GPEState *s = opaque; - return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS]; + if (s->use_old_ioport) + return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS_OLD]; + else + return s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS]; } /* write 1 to clear specific GPE bits */ @@ -415,7 +447,10 @@ static void gpe_sts_write(void *opaque, uint32_t addr, uint32_t val) PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "gpe_sts_write: addr=0x%x, val=0x%x.\n", addr, val); hotplugged = test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT); - s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS] &= ~val; + if (s->use_old_ioport) + s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS_OLD] &= ~val; + else + s->gpe0_sts[addr - ACPI_GPE0_BLK_ADDRESS] &= ~val; if ( s->sci_asserted && hotplugged && !test_bit(&s->gpe0_sts[0], ACPI_PHP_GPE_BIT)) { @@ -429,7 +464,10 @@ static uint32_t gpe_en_read(void *opaque, uint32_t addr) { GPEState *s = opaque; - return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2)]; + if (s->use_old_ioport) + return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD / 2)]; + else + return s->gpe0_en[addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2)]; } /* write 0 to clear en bit */ @@ -439,7 +477,10 @@ static void gpe_en_write(void *opaque, uint32_t addr, uint32_t val) int reg_count; PIIX4ACPI_LOG(PIIX4ACPI_LOG_DEBUG, "gpe_en_write: addr=0x%x, val=0x%x.\n", addr, val); - reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2); + if (s->use_old_ioport) + reg_count = addr - (ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD / 2); + else + reg_count = addr - (ACPI_GPE0_BLK_ADDRESS + ACPI_GPE0_BLK_LEN / 2); s->gpe0_en[reg_count] = val; /* If disable GPE bit right after generating SCI on it, * need deassert the intr to avoid redundant intrs @@ -459,7 +500,7 @@ static void gpe_save(QEMUFile* f, void* opaque) GPEState *s = (GPEState*)opaque; int i; - for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) { + for ( i = 0; i < ACPI_GPE0_BLK_LEN_OLD / 2; i++ ) { qemu_put_8s(f, &s->gpe0_sts[i]); qemu_put_8s(f, &s->gpe0_en[i]); } @@ -468,21 +509,43 @@ static void gpe_save(QEMUFile* f, void* opaque) if ( s->sci_asserted ) { PIIX4ACPI_LOG(PIIX4ACPI_LOG_INFO, "gpe_save with sci asserted!\n"); } + + qemu_put_8s(f, &s->use_old_ioport); } static int gpe_load(QEMUFile* f, void* opaque, int version_id) { GPEState *s = (GPEState*)opaque; int i; - if (version_id != 1) + if (version_id > 2) return -EINVAL; - for ( i = 0; i < ACPI_GPE0_BLK_LEN / 2; i++ ) { + for ( i = 0; i < ACPI_GPE0_BLK_LEN_OLD / 2; i++ ) { qemu_get_8s(f, &s->gpe0_sts[i]); qemu_get_8s(f, &s->gpe0_en[i]); } qemu_get_8s(f, &s->sci_asserted); + + if (version_id <= 1) { + s->use_old_ioport = 1; + } else { + qemu_get_8s(f, &s->use_old_ioport); + } + + if (s->use_old_ioport) { + isa_unassign_ioport(ACPI_GPE0_BLK_ADDRESS, ACPI_GPE0_BLK_LEN); + + register_ioport_read(ACPI_GPE0_BLK_ADDRESS_OLD, ACPI_GPE0_BLK_LEN_OLD / 2, + 1, gpe_sts_read, s); + register_ioport_read(ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD / 2, + ACPI_GPE0_BLK_LEN_OLD / 2, 1, gpe_en_read, s); + register_ioport_write(ACPI_GPE0_BLK_ADDRESS_OLD, ACPI_GPE0_BLK_LEN_OLD / 2, + 1, gpe_sts_write, s); + register_ioport_write(ACPI_GPE0_BLK_ADDRESS_OLD + ACPI_GPE0_BLK_LEN_OLD / 2, + ACPI_GPE0_BLK_LEN_OLD / 2, 1, gpe_en_write, s); + } + return 0; } @@ -551,7 +614,7 @@ static void gpe_acpi_init(void) gpe_en_write, s); - register_savevm("gpe", 0, 1, gpe_save, gpe_load, s); + register_savevm("gpe", 0, 2, gpe_save, gpe_load, s); } #ifdef CONFIG_PASSTHROUGH @@ -703,7 +766,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, pci_conf[0x43] = 0x00; d->pm1_control = SCI_EN; - acpi_map((PCIDevice *)d, 0, 0x1f40, 0x10, PCI_ADDRESS_SPACE_IO); + acpi_map((PCIDevice *)d, 0, ACPI_PM1A_EVT_BLK_ADDRESS, 0x10, PCI_ADDRESS_SPACE_IO); gpe_acpi_init(); #ifdef CONFIG_PASSTHROUGH @@ -711,7 +774,7 @@ i2c_bus *piix4_pm_init(PCIBus *bus, int devfn, uint32_t smb_io_base, #endif register_ioport_write(ACPI_DBG_IO_ADDR, 4, 4, acpi_dbg_writel, d); - register_savevm("piix4acpi", 0, 1, piix4acpi_save, piix4acpi_load, d); + register_savevm("piix4acpi", 0, 2, piix4acpi_save, piix4acpi_load, d); return NULL; } -- 1.7.1 _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Keir Fraser
2010-Oct-28 10:32 UTC
Re: [Xen-devel] [PATCH V2 0/3] firmware changes as part of QEMU/Xen merge.
I''m fine with all these patches. Ian Jackson can check them in across qemu and xen-unstable at the same time, and update QEMU_TAG. Acked-by: Keir Fraser <keir@xen.org> -- Keir On 25/10/2010 19:28, "anthony.perard@citrix.com" <anthony.perard@citrix.com> wrote:> From: Anthony PERARD <anthony.perard@citrix.com> > > This patches are for Xen-unstable and Qemu-DM. > > With the integration of Xen into QEMU, we would like to minimise the change > and use the ACPI implementation of QEMU. So there are some change to make on > the firmware to match the QEMU''s BIOS. Some IO Ports are different and the > sleep state values are different. > > Change with the v1: > > This time, both old and new ioport are handled. > In QEMU-Xen, the choice between one or the other is made when a saved state is > restored. > In Xen, both ioports are registered. > > Anthony PERARD (2): > firmware, Change ACPI IO addresses and values to match QEMU BIOS. > xen, handle both old and new acpi ioport. > > tools/firmware/hvmloader/acpi/dsdt.asl | 12 ++++++------ > tools/firmware/hvmloader/hvmloader.c | 4 ++++ > xen/arch/x86/hvm/pmtimer.c | 10 ++++++++++ > xen/include/public/hvm/ioreq.h | 16 +++++++++++++--- > 4 files changed, 33 insertions(+), 9 deletions(-) > > > Anthony PERARD (1): > piix4acpi: change in ACPI to match the change in the BIOS. > > hw/piix4acpi.c | 97 > ++++++++++++++++++++++++++++++++++++++++++++++---------- > 1 files changed, 80 insertions(+), 17 deletions(-)_______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2010-Oct-28 10:37 UTC
Re: [Xen-devel] [PATCH V2 0/3] firmware changes as part of QEMU/Xen merge.
Keir Fraser writes ("Re: [Xen-devel] [PATCH V2 0/3] firmware changes as part of QEMU/Xen merge."):> I''m fine with all these patches. Ian Jackson can check them in across qemu > and xen-unstable at the same time, and update QEMU_TAG.Following in-person discussion, we''ve concluded that we have to make a mechanism to avoid the hypervisor exposing both ports to all guests; as that would make us fail certain parts of the Windows platform validation tests. So we''re intending to invent an HVMPARAM to control old or new ACPI port location, which will default to old, and the new hvmloader will set it to new. Ian. _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel