[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-devel] [PATCH 2/2] ioemu: Disable xen platform PCI device when xen_platform_pci=0 is specified



This patch is the ioemu side of the series.

- Alias the "platform_flags" byte of the ioport BAR to fixed byte port
  0x10, and don't remove existing "platform_flags" byte.

- Disable xen platform PCI device if "disable_pf" entry is 1. If there
  is not "disable_pf" entry, xen platform PCI device is enabled.

Thanks,
--
Yuji Shimada


Signed-off-by: Yuji Shimada <shimada-yxb@xxxxxxxxxxxxxxx>

diff --git a/hw/pc.c b/hw/pc.c
index 77f6812..dc5de7f 100644
--- a/hw/pc.c
+++ b/hw/pc.c
@@ -33,6 +33,7 @@
 #include "boards.h"
 #include "console.h"
 #include "exec-all.h"
+#include "qemu-xen.h"
 
 #include "xen_platform.h"
 #include "fw_cfg.h"
@@ -780,6 +781,7 @@ static void pc_init1(ram_addr_t ram_size, int vga_ram_size,
 {
     char buf[1024];
     int ret, linux_boot, i;
+    int disable_pf;
     ram_addr_t ram_addr, vga_ram_addr, bios_offset, vga_bios_offset;
     ram_addr_t below_4g_mem_size, above_4g_mem_size = 0;
     int bios_size, isa_bios_size, vga_bios_size;
@@ -1033,8 +1035,12 @@ vga_bios_error:
         pic_set_alt_irq_func(isa_pic, ioapic_set_irq, ioapic);
     }
 #endif /* !CONFIG_DM */
-    if (pci_enabled)
-        pci_xen_platform_init(pci_bus);
+    if (pci_enabled) {
+        disable_pf = xenstore_parse_disable_pf_config();
+        if (disable_pf != 1)
+            pci_xen_platform_init(pci_bus);
+        platform_fixed_ioport_init();
+    }
 
     for(i = 0; i < MAX_SERIAL_PORTS; i++) {
         if (serial_hds[i]) {
diff --git a/hw/xen_platform.c b/hw/xen_platform.c
index 65a2da4..e77ee9f 100644
--- a/hw/xen_platform.c
+++ b/hw/xen_platform.c
@@ -40,12 +40,13 @@ extern FILE *logfile;
 static char log_buffer[4096];
 static int log_buffer_off;
 
+static uint8_t platform_flags;
+
 #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
 
 typedef struct PCIXenPlatformState
 {
   PCIDevice  pci_dev;
-  uint8_t    platform_flags;
 } PCIXenPlatformState;
 
 /* We throttle access to dom0 syslog, to avoid DOS attacks.  This is
@@ -130,105 +131,6 @@ static void throttle(unsigned count)
     available -= count;
 }
 
-static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
-{
-    PCIXenPlatformState *s = opaque;
-
-    addr &= 0xff;
-
-    return (addr == 0) ? s->platform_flags : ~0u;
-}
-                              
-static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t 
val)
-{
-    PCIXenPlatformState *d = opaque;
-
-    addr &= 0xff;
-    val  &= 0xff;
-
-    switch (addr) {
-    case 0: /* Platform flags */ {
-        hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ?
-            HVMMEM_ram_ro : HVMMEM_ram_rw;
-        if (xc_hvm_set_mem_type(xc_handle, domid, mem_type, 0xc0, 0x40))
-            fprintf(logfile,"xen_platform: unable to change ro/rw "
-                    "state of ROM memory area!\n");
-        else
-            d->platform_flags = val & PFFLAG_ROM_LOCK;
-        break;
-    }
-    case 8:
-        {
-            if (val == '\n' || log_buffer_off == sizeof(log_buffer) - 1) {
-                /* Flush buffer */
-                log_buffer[log_buffer_off] = 0;
-                throttle(log_buffer_off);
-                fprintf(logfile, "%s\n", log_buffer);
-                log_buffer_off = 0;
-                break;
-            }
-            log_buffer[log_buffer_off++] = val;
-        }
-        break;
-    default:
-        break;
-    }
-}
-
-static void platform_ioport_map(PCIDevice *pci_dev, int region_num, uint32_t 
addr, uint32_t size, int type)
-{
-    PCIXenPlatformState *d = (PCIXenPlatformState *)pci_dev;
-    register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
-    register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
-}
-
-static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
-{
-    static int warnings = 0;
-    if (warnings < 5) {
-        fprintf(logfile, "Warning: attempted read from physical address "
-                "0x%"PRIx64" in xen platform mmio space\n", (uint64_t)addr);
-        warnings++;
-    }
-    return 0;
-}
-
-static void platform_mmio_write(void *opaque, target_phys_addr_t addr,
-                                uint32_t val)
-{
-    static int warnings = 0;
-    if (warnings < 5) {
-        fprintf(logfile, "Warning: attempted write of 0x%x to physical "
-                "address 0x%"PRIx64" in xen platform mmio space\n",
-                val, (uint64_t)addr);
-        warnings++;
-    }
-    return;
-}
-
-static CPUReadMemoryFunc *platform_mmio_read_funcs[3] = {
-    platform_mmio_read,
-    platform_mmio_read,
-    platform_mmio_read,
-};
-
-static CPUWriteMemoryFunc *platform_mmio_write_funcs[3] = {
-    platform_mmio_write,
-    platform_mmio_write,
-    platform_mmio_write,
-};
-
-static void platform_mmio_map(PCIDevice *d, int region_num,
-                              uint32_t addr, uint32_t size, int type)
-{
-    int mmio_io_addr;
-
-    mmio_io_addr = cpu_register_io_memory(0, platform_mmio_read_funcs,
-                                          platform_mmio_write_funcs, NULL);
-
-    cpu_register_physical_memory(addr, 0x1000000, mmio_io_addr);
-}
-
 #define UNPLUG_ALL_IDE_DISKS 1
 #define UNPLUG_ALL_NICS 2
 #define UNPLUG_AUX_IDE_DISKS 4
@@ -289,10 +191,23 @@ static void platform_fixed_ioport_write4(void *opaque, 
uint32_t addr,
     }
 }
 
-
 static void platform_fixed_ioport_write1(void *opaque, uint32_t addr, uint32_t 
val)
 {
     switch (addr - 0x10) {
+    case 0: /* Platform flags */ {
+        hvmmem_type_t mem_type = (val & PFFLAG_ROM_LOCK) ?
+            HVMMEM_ram_ro : HVMMEM_ram_rw;
+        if (xc_hvm_set_mem_type(xc_handle, domid, mem_type, 0xc0, 0x40))
+            fprintf(logfile,"platform_fixed_ioport: unable to change ro/rw "
+                    "state of ROM memory area!\n");
+        else {
+            platform_flags = val & PFFLAG_ROM_LOCK;
+            fprintf(logfile,"platform_fixed_ioport: changed ro/rw "
+                    "state of ROM memory area. now is %s state.\n",
+                    (mem_type == HVMMEM_ram_ro ? "ro":"rw"));
+        }
+        break;
+    }
     case 2:
         /* Send bytes to syslog */
         if (val == '\n' || log_buffer_off == sizeof(log_buffer) - 1) {
@@ -328,6 +243,9 @@ static uint32_t platform_fixed_ioport_read2(void *opaque, 
uint32_t addr)
 static uint32_t platform_fixed_ioport_read1(void *opaque, uint32_t addr)
 {
     switch (addr - 0x10) {
+    case 0:
+        /* Platform flags */
+        return platform_flags;
     case 2:
         /* Version number */
         return 1;
@@ -336,6 +254,131 @@ static uint32_t platform_fixed_ioport_read1(void *opaque, 
uint32_t addr)
     }
 }
 
+void platform_fixed_ioport_save(QEMUFile *f, void *opaque)
+{
+    qemu_put_8s(f, &platform_flags);
+}
+
+int platform_fixed_ioport_load(QEMUFile *f, void *opaque, int version_id)
+{
+    uint8_t flags;
+
+    if (version_id > 1)
+        return -EINVAL;
+
+    qemu_get_8s(f, &flags);
+    platform_fixed_ioport_write1(NULL, 0x10, flags);
+
+    return 0;
+}
+
+void platform_fixed_ioport_init(void)
+{
+    struct stat stbuf;
+
+    register_savevm("platform_fixed_ioport", 0, 1, platform_fixed_ioport_save,
+                    platform_fixed_ioport_load, NULL);
+
+    register_ioport_write(0x10, 16, 4, platform_fixed_ioport_write4, NULL);
+    register_ioport_write(0x10, 16, 2, platform_fixed_ioport_write2, NULL);
+    register_ioport_write(0x10, 16, 1, platform_fixed_ioport_write1, NULL);
+    register_ioport_read(0x10, 16, 2, platform_fixed_ioport_read2, NULL);
+    register_ioport_read(0x10, 16, 1, platform_fixed_ioport_read1, NULL);
+
+    if (stat("/etc/disable-guest-log-throttle", &stbuf) == 0)
+        throttling_disabled = 1;
+
+    platform_fixed_ioport_write1(NULL, 0x10, 0);
+}
+
+static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
+{
+    addr &= 0xff;
+
+    return (addr == 0) ? platform_fixed_ioport_read1(NULL, 0x10) : ~0u;
+}
+
+static void xen_platform_ioport_writeb(void *opaque, uint32_t addr, uint32_t 
val)
+{
+    addr &= 0xff;
+    val  &= 0xff;
+
+    switch (addr) {
+    case 0: /* Platform flags */
+        platform_fixed_ioport_write1(NULL, 0x10, val);
+        break;
+    case 8:
+        {
+            if (val == '\n' || log_buffer_off == sizeof(log_buffer) - 1) {
+                /* Flush buffer */
+                log_buffer[log_buffer_off] = 0;
+                throttle(log_buffer_off);
+                fprintf(logfile, "%s\n", log_buffer);
+                log_buffer_off = 0;
+                break;
+            }
+            log_buffer[log_buffer_off++] = val;
+        }
+        break;
+    default:
+        break;
+    }
+}
+
+static void platform_ioport_map(PCIDevice *pci_dev, int region_num, uint32_t 
addr, uint32_t size, int type)
+{
+    PCIXenPlatformState *d = (PCIXenPlatformState *)pci_dev;
+    register_ioport_write(addr, size, 1, xen_platform_ioport_writeb, d);
+    register_ioport_read(addr, size, 1, xen_platform_ioport_readb, d);
+}
+
+static uint32_t platform_mmio_read(void *opaque, target_phys_addr_t addr)
+{
+    static int warnings = 0;
+    if (warnings < 5) {
+        fprintf(logfile, "Warning: attempted read from physical address "
+                "0x%"PRIx64" in xen platform mmio space\n", (uint64_t)addr);
+        warnings++;
+    }
+    return 0;
+}
+
+static void platform_mmio_write(void *opaque, target_phys_addr_t addr,
+                                uint32_t val)
+{
+    static int warnings = 0;
+    if (warnings < 5) {
+        fprintf(logfile, "Warning: attempted write of 0x%x to physical "
+                "address 0x%"PRIx64" in xen platform mmio space\n",
+                val, (uint64_t)addr);
+        warnings++;
+    }
+    return;
+}
+
+static CPUReadMemoryFunc *platform_mmio_read_funcs[3] = {
+    platform_mmio_read,
+    platform_mmio_read,
+    platform_mmio_read,
+};
+
+static CPUWriteMemoryFunc *platform_mmio_write_funcs[3] = {
+    platform_mmio_write,
+    platform_mmio_write,
+    platform_mmio_write,
+};
+
+static void platform_mmio_map(PCIDevice *d, int region_num,
+                              uint32_t addr, uint32_t size, int type)
+{
+    int mmio_io_addr;
+
+    mmio_io_addr = cpu_register_io_memory(0, platform_mmio_read_funcs,
+                                          platform_mmio_write_funcs, NULL);
+
+    cpu_register_physical_memory(addr, 0x1000000, mmio_io_addr);
+}
+
 struct pci_config_header {
     uint16_t vendor_id;
     uint16_t device_id;
@@ -368,7 +411,6 @@ static void xen_pci_save(QEMUFile *f, void *opaque)
     uint64_t t = 0;
 
     pci_device_save(&d->pci_dev, f);
-    qemu_put_8s(f, &d->platform_flags);
     qemu_put_be64s(f, &t);
 }
 
@@ -377,7 +419,7 @@ static int xen_pci_load(QEMUFile *f, void *opaque, int 
version_id)
     PCIXenPlatformState *d = opaque;
     int ret;
 
-    if (version_id > 2)
+    if (version_id > 3)
         return -EINVAL;
 
     ret = pci_device_load(&d->pci_dev, f);
@@ -385,9 +427,11 @@ static int xen_pci_load(QEMUFile *f, void *opaque, int 
version_id)
         return ret;
 
     if (version_id >= 2) {
-        uint8_t flags;
-        qemu_get_8s(f, &flags);
-        xen_platform_ioport_writeb(d, 0, flags);
+        if (version_id == 2) {
+            uint8_t flags;
+            qemu_get_8s(f, &flags);
+            xen_platform_ioport_writeb(d, 0, flags);
+        }
         qemu_get_be64(f);
     }
 
@@ -398,7 +442,6 @@ void pci_xen_platform_init(PCIBus *bus)
 {
     PCIXenPlatformState *d;
     struct pci_config_header *pch;
-    struct stat stbuf;
 
     printf("Register xen platform.\n");
     d = (PCIXenPlatformState *)pci_register_device(
@@ -426,17 +469,8 @@ void pci_xen_platform_init(PCIBus *bus)
     pci_register_io_region(&d->pci_dev, 1, 0x1000000,
                            PCI_ADDRESS_SPACE_MEM_PREFETCH, platform_mmio_map);
 
-    xen_platform_ioport_writeb(d, 0, 0);
-
-    register_savevm("platform", 0, 2, xen_pci_save, xen_pci_load, d);
+    register_savevm("platform", 0, 3, xen_pci_save, xen_pci_load, d);
     printf("Done register platform.\n");
-    register_ioport_write(0x10, 16, 4, platform_fixed_ioport_write4, NULL);
-    register_ioport_write(0x10, 16, 2, platform_fixed_ioport_write2, NULL);
-    register_ioport_write(0x10, 16, 1, platform_fixed_ioport_write1, NULL);
-    register_ioport_read(0x10, 16, 2, platform_fixed_ioport_read2, NULL);
-    register_ioport_read(0x10, 16, 1, platform_fixed_ioport_read1, NULL);
-
-    if (stat("/etc/disable-guest-log-throttle", &stbuf) == 0)
-        throttling_disabled = 1;
 
 }
+
diff --git a/hw/xen_platform.h b/hw/xen_platform.h
index 5bf16f8..33af766 100644
--- a/hw/xen_platform.h
+++ b/hw/xen_platform.h
@@ -4,5 +4,6 @@
 #include "pci.h"
 
 void pci_xen_platform_init(PCIBus *bus);
+void platform_fixed_ioport_init(void);
 
 #endif
diff --git a/qemu-xen.h b/qemu-xen.h
index 7ca9428..ec4cd94 100644
--- a/qemu-xen.h
+++ b/qemu-xen.h
@@ -48,6 +48,7 @@ void handle_buffered_pio(void);
 
 /* xenstore.c */
 void xenstore_parse_domain_config(int domid);
+int xenstore_parse_disable_pf_config(void);
 int xenstore_fd(void);
 void xenstore_process_event(void *opaque);
 void xenstore_record_dm(const char *subpath, const char *state);
diff --git a/xenstore.c b/xenstore.c
index 4ee6ceb..66b64ab 100644
--- a/xenstore.c
+++ b/xenstore.c
@@ -639,6 +639,27 @@ void xenstore_parse_domain_config(int hvm_domid)
     return;
 }
 
+int xenstore_parse_disable_pf_config ()
+{
+    char *params = NULL, *buf = NULL;
+    int disable_pf = 0;
+    unsigned int len;
+
+    if (pasprintf(&buf, "/local/domain/0/device-model/%u/disable_pf",domid) == 
-1)
+        goto out;
+
+    params = xs_read(xsh, XBT_NULL, buf, &len);
+    if (params == NULL)
+        goto out;
+
+    disable_pf = atoi(params);
+
+ out:
+    free(buf);
+    free(params);
+    return disable_pf;
+}
+
 int xenstore_fd(void)
 {
     if (xsh)


_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.