diff --git a/hw/ide.c b/hw/ide.c
index dae6e7f..b7b6871 100644
--- a/hw/ide.c
+++ b/hw/ide.c
@@ -3419,6 +3419,8 @@ void pci_piix3_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
                                            sizeof(PCIIDEState),
                                            devfn,
                                            NULL, NULL);
+    d->dev.disable_flag = 1;
+
     d->type = IDE_TYPE_PIIX3;
 
     pci_conf = d->dev.config;
diff --git a/hw/pci.c b/hw/pci.c
index 1de68fd..c55c371 100644
--- a/hw/pci.c
+++ b/hw/pci.c
@@ -26,6 +26,8 @@
 #include "console.h"
 #include "net.h"
 
+uint32_t xen_pci_disable_devices;
+
 //#define DEBUG_PCI
 
 struct PCIBus {
@@ -160,6 +162,7 @@ PCIDevice *pci_register_device(PCIBus *bus, const char *name,
     pci_dev->config_write = config_write;
     bus->devices[devfn] = pci_dev;
     pci_dev->irq = qemu_allocate_irqs(pci_set_irq, pci_dev, 4);
+    pci_dev->disable_flag = 0;
     return pci_dev;
 }
 
@@ -465,6 +468,12 @@ uint32_t pci_data_read(void *opaque, uint32_t addr, int len)
         }
         goto the_end;
     }
+    if (pci_dev->disable_flag && xen_pci_disable_devices)
+    {
+        printf("read disabled device\n");
+	goto fail;
+    }
+
     config_addr = addr & 0xff;
     val = pci_dev->config_read(pci_dev, config_addr, len);
 #if defined(DEBUG_PCI)
diff --git a/hw/pci.h b/hw/pci.h
index 4adc4d7..c57841a 100644
--- a/hw/pci.h
+++ b/hw/pci.h
@@ -61,6 +61,9 @@ struct PCIDevice {
 
     /* Current IRQ levels.  Used internally by the generic PCI code.  */
     int irq_state[4];
+
+    /* when set, this device will be disabled when xen_pci_disable_devices is set */
+    int disable_flag;
 };
 
 extern char direct_pci_str[];
diff --git a/hw/rtl8139.c b/hw/rtl8139.c
index 9ae76e6..d5f0774 100644
--- a/hw/rtl8139.c
+++ b/hw/rtl8139.c
@@ -536,7 +536,7 @@ static void prom9346_decode_command(EEprom9346 *eeprom, uint8_t command)
                     DEBUG_PRINT(("RTL8139: eeprom begin write all\n"));
                     break;
                 case Chip9346_op_write_disable:
-                    DEBUG_PRINT(("RTL8139: eeprom write disabled\n"));
+                    DEBUG_PRINT(("RTL8139: eeprom write disable\n"));
                     break;
             }
             break;
@@ -3429,6 +3429,7 @@ void pci_rtl8139_init(PCIBus *bus, NICInfo *nd, int devfn)
                                               "RTL8139", sizeof(PCIRTL8139State),
                                               devfn,
                                               NULL, NULL);
+    d->dev.disable_flag = 1; /* should be disabled by PV on HVM drivers */
     pci_conf = d->dev.config;
     pci_conf[0x00] = 0xec; /* Realtek 8139 */
     pci_conf[0x01] = 0x10;
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index 430e603..11acac3 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -30,6 +30,7 @@
 #include <xenguest.h>
 
 extern FILE *logfile;
+extern uint32_t xen_pci_disable_devices;
 
 #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
 
@@ -39,6 +40,59 @@ typedef struct PCIXenPlatformState
   uint8_t    platform_flags;
 } PCIXenPlatformState;
 
+static uint32_t platform_global_ioport_readb(void *opaque, uint32_t addr)
+{
+    switch (addr & 0x0f)
+    {
+    case 0:
+	return 'X';
+    case 1:
+	return 'E';
+    case 2:
+	return 'N';
+    case 3:
+	return 1; /* version */
+    default:
+	return 0;
+    }
+}
+
+static void platform_global_ioport_writeb(void *opaque, uint32_t addr, uint32_t val)
+{
+    static char buffer[8][512];
+    static int bufpos[8] = {0};
+    int cpu;
+
+    switch (addr & 0x0f)
+    {
+    case 0:
+    case 1:
+    case 2:
+    case 3:
+    case 4:
+    case 5:
+    case 6:
+    case 7:
+	cpu = addr & 0x07;
+    	if (bufpos[cpu] == 511 || val == '\n')
+    	{
+            buffer[cpu][bufpos[cpu]] = 0;
+            printf("%02d: %s\n", cpu, buffer[cpu]);
+            bufpos[cpu] = 0;
+        }
+        if (val == '\n')
+	    return;
+        buffer[cpu][bufpos[cpu]++] = val;
+	break;
+    case 8:
+	xen_pci_disable_devices = val;
+	printf("set xen_pci_disable_devices = %d\n", val);
+	break;
+    default:
+	break;
+    }
+}
+
 static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
 {
     PCIXenPlatformState *s = opaque;
@@ -208,6 +262,9 @@ void pci_xen_platform_init(PCIBus *bus)
     pci_register_io_region(&d->pci_dev, 0, 0x100,
                            PCI_ADDRESS_SPACE_IO, platform_ioport_map);
 
+    register_ioport_write(0x10, 0x10, 1, platform_global_ioport_writeb, NULL);
+    register_ioport_read(0x10, 0x10, 1, platform_global_ioport_readb, NULL);
+
     /* reserve 16MB mmio address for share memory*/
     pci_register_io_region(&d->pci_dev, 1, 0x1000000,
                            PCI_ADDRESS_SPACE_MEM_PREFETCH, platform_mmio_map);
diff --git a/vl.c b/vl.c
index e50a02d..1366a37 100644
--- a/vl.c
+++ b/vl.c
@@ -5401,6 +5401,8 @@ static int drive_init(struct drive_opt *arg, int snapshot,
            approximation.  */
     case IF_FLOPPY:
         bdrv_set_type_hint(bdrv, BDRV_TYPE_FLOPPY);
+	if (!drv)
+	    drv = &bdrv_raw;
         break;
     case IF_PFLASH:
     case IF_MTD:
