]> xenbits.xensource.com Git - qemu-xen-3.4-testing.git/commitdiff
magic ioport 0x10 protocol - clean up document
authorIan Jackson <ian.jackson@eu.citrix.com>
Wed, 31 Dec 2008 16:12:51 +0000 (16:12 +0000)
committerIan Jackson <Ian.Jackson@eu.citrix.com>
Wed, 31 Dec 2008 16:12:51 +0000 (16:12 +0000)
Clean up the README and product number registry comment:
 - removing mail headers
 - specifying that the magic number will be reversed
   if the drivers are blacklisted
 - clarifying that logging is permitted if drivers are
   blacklisted
 - specifying clearly when people should allocate new numbers

Signed-off-by: Ian Jackson <ian.jackson@eu.citrix.com>
i386-dm/README.hvm-pv-magic-ioport-disable
xenstore.c

index 656f3c65451a1614185b362e10ae6329666d9511..142394a67169b8ecfc1167073b281713a7ca2de4 100644 (file)
@@ -1,35 +1,4 @@
-Message-ID: <20081215171059.GA2574@weybridge.uk.xensource.com>
-From: Steven Smith <steven.smith@eu.citrix.com>
-To: Keir Fraser <keir.fraser@eu.citrix.com>
-Cc: James Harper <james.harper@bendigoit.com.au>,
-       Ian Jackson <Ian.Jackson@eu.citrix.com>,
-       xen-devel@lists.xensource.com
-Subject: Re: [Xen-devel] disable qemu PCI devices in HVM domains
-Date: Mon, 15 Dec 2008 17:10:59 +0000
-
-> >> I like the principle of disabling the drivers via an instruction to
-> >> qemu rather than by attempting to wrestle with the Windows driver
-> >> machinery to try to hide the devices.  But couldn't we simulate a PCI
-> >> unplug or a medium change or something instead ?  Then you could do it
-> >> later in the boot after your own drivers have properly bound.
-> >> 
-> > 
-> > Is the 'pci unplug' as simple as making a call somewhere like
-> > pci_unplug(id of ide adapter)? I'm concerned that Windows may not like
-> > this.
-> My own opinion is that the ioports are fine, but they should be offsets from
-> the xen-platform-pci device's ioport bar. Also we ought to document the
-> ports in xen-platform-pci's source file, as it's going to start getting
-> messy in there.
-> 
-> I'm not sure if the approach taken by the Citrix drivers could be at all
-> useful. Cc'ing Steven Smith in case he has any comments to make.
-I can't see any reason why the approach we take in our closed-source
-drivers wouldn't work here as well.  I've attached the appropriate
-patches from our product qemu patchqueue, tidied up and stripped of
-the most obviously XenServer-specific bits, and made to apply to
-current ioemu-remote.
-
+MAGIC IOPORT 0x10 PROTOCOL
 
 The protocol covers three basic things:
 
@@ -59,8 +28,8 @@ drivers):
 4) The drivers write a four-byte build number to IO port 0x10.
 
 5) The drivers check the magic number by reading two bytes from 0x10
-   again.  If it's changed from 0x49d2, the drivers are blacklisted
-   and should not load.
+   again.  If it's changed from 0x49d2 to 0xd249, the drivers are
+   blacklisted and should not load.
 
 6) The drivers write a two-byte bitmask of devices to unplug to IO
    port 0x10.  The defined fields are:
@@ -74,9 +43,8 @@ drivers):
    buses.  For most guest operating systems, you want to do this
    before device enumeration happens.
 
-...) Once the drivers have checked the magic number (and the
-     blacklist, if appropriate), they can send log messages to qemu
-     which will be logged to wherever qemu's logs go
+...) Once the drivers have checked the magic number, they can send log
+     messages to qemu which will be logged to wherever qemu's logs go
      (/var/log/xen/qemu-dm.log on normal Xen, dom0 syslog on
      XenServer).  These messages are written to IO port 0x12 a byte at
      a time, and are terminated by newlines.  There's a fairly
@@ -84,6 +52,10 @@ drivers):
      used for anything even vaguely high-volume, but they're rather
      useful for debugging and support.
 
+     It is still permitted for a driver to use this logging feature if
+     it is blacklisted, but ONLY if it has checked the magic number
+     and found it to be 0x49d2 or 0xd249.
+
 This isn't exactly a pretty protocol, but it does solve the problem.
 
 
@@ -92,770 +64,7 @@ xenstore.  A driver version is considered to be blacklisted if
 /mh/driver-blacklist/{product_name}/{build_number} exists and is
 readable, where {build_number} is the build number from step 4 as a
 decimal number.  {product_name} is a string corresponding to the
-product number in step 3; at present, the only product number is 1,
-which has a product_name of xensource-windows.
-
-
-A previous version of the protocol put the IO ports on the PCI
-platform device.  Unfortunately, that makes it difficult to get at
-them before PCI bus enumeration happens, which complicates removal of
-the emulated NICs.  It is possible to work around these but (at least
-on Windows) it's complicated and messy, and generally best avoided.
+product number in step 3.
 
-Steven.
-support-hvm-pv-drivers-ioemu-support
-hvm-log-to-dom0
-rate_limit_guest_syslog
-pv-driver-version
-Index: ioemu-remote/hw/ide.c
-===================================================================
---- ioemu-remote.orig/hw/ide.c 2008-12-15 16:02:19.000000000 +0000
-+++ ioemu-remote/hw/ide.c      2008-12-15 16:02:35.000000000 +0000
-@@ -484,6 +484,7 @@
-     int type; /* see IDE_TYPE_xxx */
- } PCIIDEState;
-+static PCIIDEState *principal_ide_controller;
- #if defined(__ia64__)
- #include <xen/hvm/ioreq.h>
-@@ -2778,6 +2779,47 @@
-     s->media_changed = 0;
- }
-+/* Unplug all of the IDE hard disks, starting at index @start in the
-+   table. */
-+static void _ide_unplug_harddisks(int start)
-+{
-+    IDEState *s;
-+    int i, j;
-+
-+    if (!principal_ide_controller) {
-+        fprintf(stderr, "No principal controller?\n");
-+        return;
-+    }
-+    for (i = start; i < 4; i++) {
-+        s = principal_ide_controller->ide_if + i;
-+        if (!s->bs)
-+            continue; /* drive not present */
-+        if (s->is_cdrom)
-+            continue; /* cdrom */
-+        /* Is a hard disk, unplug it. */
-+        for (j = 0; j < nb_drives; j++)
-+            if (drives_table[j].bdrv == s->bs)
-+                drives_table[j].bdrv = NULL;
-+        bdrv_close(s->bs);
-+        s->bs = NULL;
-+        ide_reset(s);
-+    }
-+}
-+
-+/* Unplug all hard disks except for the primary master (which will
-+   almost always be the boot device). */
-+void ide_unplug_aux_harddisks(void)
-+{
-+    _ide_unplug_harddisks(1);
-+}
-+
-+/* Unplug all hard disks, including the boot device. */
-+void ide_unplug_harddisks(void)
-+{
-+    _ide_unplug_harddisks(0);
-+}
-+
-+
- struct partition {
-       uint8_t boot_ind;               /* 0x80 - active */
-       uint8_t head;           /* starting head */
-@@ -3290,6 +3332,9 @@
-                                            sizeof(PCIIDEState),
-                                            -1,
-                                            NULL, NULL);
-+    if (principal_ide_controller)
-+      abort();
-+    principal_ide_controller = d;
-     d->type = IDE_TYPE_CMD646;
-     pci_conf = d->dev.config;
-     pci_conf[0x00] = 0x95; // CMD646
-@@ -3419,6 +3464,9 @@
-                                            sizeof(PCIIDEState),
-                                            devfn,
-                                            NULL, NULL);
-+    if (principal_ide_controller)
-+      abort();
-+    principal_ide_controller = d;
-     d->type = IDE_TYPE_PIIX3;
-     pci_conf = d->dev.config;
-Index: ioemu-remote/hw/pci.c
-===================================================================
---- ioemu-remote.orig/hw/pci.c 2008-12-15 16:02:19.000000000 +0000
-+++ ioemu-remote/hw/pci.c      2008-12-15 16:02:22.000000000 +0000
-@@ -26,6 +26,9 @@
- #include "console.h"
- #include "net.h"
-+#include "exec-all.h"
-+#include "qemu-xen.h"
-+
- //#define DEBUG_PCI
- struct PCIBus {
-@@ -648,6 +651,46 @@
-     }
- }
-+void pci_unplug_netifs(void)
-+{
-+    PCIBus *bus;
-+    PCIDevice *dev;
-+    PCIIORegion *region;
-+    int x;
-+    int i;
-+
-+    /* We only support one PCI bus */
-+    for (bus = first_bus; bus; bus = NULL) {
-+       for (x = 0; x < 256; x++) {
-+           dev = bus->devices[x];
-+           if (dev &&
-+               dev->config[0xa] == 0 &&
-+               dev->config[0xb] == 2) {
-+               /* Found a netif.  Remove it from the bus.  Note that
-+                  we don't free it here, since there could still be
-+                  references to it floating around.  There are only
-+                  ever one or two structures leaked, and it's not
-+                  worth finding them all. */
-+               bus->devices[x] = NULL;
-+               for (i = 0; i < PCI_NUM_REGIONS; i++) {
-+                   region = &dev->io_regions[i];
-+                   if (region->addr == (uint32_t)-1 ||
-+                       region->size == 0)
-+                       continue;
-+                   fprintf(logfile, "region type %d at [%x,%x).\n",
-+                           region->type, region->addr,
-+                           region->addr+region->size);
-+                   if (region->type == PCI_ADDRESS_SPACE_IO) {
-+                       isa_unassign_ioport(region->addr, region->size);
-+                   } else if (region->type == PCI_ADDRESS_SPACE_MEM) {
-+                       unregister_iomem(region->addr);
-+                   }
-+               }
-+           }
-+       }
-+    }
-+}
-+
- typedef struct {
-     PCIDevice dev;
-     PCIBus *bus;
-Index: ioemu-remote/qemu-xen.h
-===================================================================
---- ioemu-remote.orig/qemu-xen.h       2008-12-15 16:02:19.000000000 +0000
-+++ ioemu-remote/qemu-xen.h    2008-12-15 16:02:22.000000000 +0000
-@@ -26,8 +26,11 @@
- void xen_vga_vram_map(uint64_t vram_addr, int copy);
- #endif
--
-+void ide_unplug_harddisks(void);
-+void net_tap_shutdown_all(void);
-+void pci_unplug_netifs(void);
- void destroy_hvm_domain(void);
-+void unregister_iomem(target_phys_addr_t start);
- #ifdef __ia64__
- static inline void xc_domain_shutdown_hook(int xc_handle, uint32_t domid)
-Index: ioemu-remote/vl.c
-===================================================================
---- ioemu-remote.orig/vl.c     2008-12-15 16:02:19.000000000 +0000
-+++ ioemu-remote/vl.c  2008-12-15 16:02:22.000000000 +0000
-@@ -262,6 +262,20 @@
- #include "xen-vl-extra.c"
-+typedef struct IOHandlerRecord {
-+    int fd;
-+    IOCanRWHandler *fd_read_poll;
-+    IOHandler *fd_read;
-+    IOHandler *fd_write;
-+    int deleted;
-+    void *opaque;
-+    /* temporary data */
-+    struct pollfd *ufd;
-+    struct IOHandlerRecord *next;
-+} IOHandlerRecord;
-+
-+static IOHandlerRecord *first_io_handler;
-+
- /***********************************************************/
- /* x86 ISA bus support */
-@@ -4055,6 +4069,7 @@
- typedef struct TAPState {
-     VLANClientState *vc;
-     int fd;
-+    struct TAPState *next;
-     char down_script[1024];
-     char script_arg[1024];
- } TAPState;
-@@ -4092,6 +4107,34 @@
-     }
- }
-+static TAPState *head_net_tap;
-+
-+void net_tap_shutdown_all(void)
-+{
-+    struct IOHandlerRecord **pioh, *ioh;
-+
-+    while (head_net_tap) {
-+       pioh = &first_io_handler;
-+       for (;;) {
-+           ioh = *pioh;
-+           if (ioh == NULL)
-+               break;
-+           if (ioh->fd == head_net_tap->fd) {
-+               *pioh = ioh->next;
-+               qemu_free(ioh);
-+               break;
-+           }
-+           pioh = &ioh->next;
-+       }
-+       if (!ioh)
-+           fprintf(stderr,
-+                   "warning: can't find iohandler for %d to close it properly.\n",
-+                   head_net_tap->fd);
-+       close(head_net_tap->fd);
-+       head_net_tap = head_net_tap->next;
-+    }
-+}
-+
- /* fd support */
- static TAPState *net_tap_fd_init(VLANState *vlan, int fd)
-@@ -4103,6 +4146,8 @@
-         return NULL;
-     s->fd = fd;
-     s->vc = qemu_new_vlan_client(vlan, tap_receive, NULL, s);
-+    s->next = head_net_tap;
-+    head_net_tap = s;
-     qemu_set_fd_handler(s->fd, tap_send, NULL, s);
-     snprintf(s->vc->info_str, sizeof(s->vc->info_str), "tap: fd=%d", fd);
-     return s;
-@@ -5666,20 +5711,6 @@
- #define MAX_IO_HANDLERS 64
--typedef struct IOHandlerRecord {
--    int fd;
--    IOCanRWHandler *fd_read_poll;
--    IOHandler *fd_read;
--    IOHandler *fd_write;
--    int deleted;
--    void *opaque;
--    /* temporary data */
--    struct pollfd *ufd;
--    struct IOHandlerRecord *next;
--} IOHandlerRecord;
--
--static IOHandlerRecord *first_io_handler;
--
- /* XXX: fd_read_poll should be suppressed, but an API change is
-    necessary in the character devices to suppress fd_can_read(). */
- int qemu_set_fd_handler2(int fd,
-Index: ioemu-remote/block-raw-posix.c
-===================================================================
---- ioemu-remote.orig/block-raw-posix.c        2008-12-15 16:02:19.000000000 +0000
-+++ ioemu-remote/block-raw-posix.c     2008-12-15 16:02:22.000000000 +0000
-@@ -55,6 +55,7 @@
- #include <sys/ioctl.h>
- #include <linux/cdrom.h>
- #include <linux/fd.h>
-+#include <sys/mount.h>
- #endif
- #ifdef __FreeBSD__
- #include <sys/disk.h>
-@@ -125,6 +126,10 @@
-         return ret;
-     }
-     s->fd = fd;
-+#ifndef CONFIG_STUBDOM
-+    /* Invalidate buffer cache for this device. */
-+    ioctl(s->fd, BLKFLSBUF, 0);
-+#endif
-     return 0;
- }
-@@ -505,6 +510,10 @@
- {
-     BDRVRawState *s = bs->opaque;
-     if (s->fd >= 0) {
-+#ifndef CONFIG_STUBDOM
-+        /* Invalidate buffer cache for this device. */
-+        ioctl(s->fd, BLKFLSBUF, 0);
-+#endif
-         close(s->fd);
-         s->fd = -1;
-     }
-Index: ioemu-remote/i386-dm/exec-dm.c
-===================================================================
---- ioemu-remote.orig/i386-dm/exec-dm.c        2008-12-15 16:02:19.000000000 +0000
-+++ ioemu-remote/i386-dm/exec-dm.c     2008-12-15 16:02:22.000000000 +0000
-@@ -267,7 +267,7 @@
- /* XXX: Simple implementation. Fix later */
- #define MAX_MMIO 32
--struct mmio_space {
-+static struct mmio_space {
-         target_phys_addr_t start;
-         unsigned long size;
-         unsigned long io_index;
-@@ -413,6 +413,17 @@
-         return 0;
- }
-+void unregister_iomem(target_phys_addr_t start)
-+{
-+    int index = iomem_index(start);
-+    if (index) {
-+        fprintf(logfile, "squash iomem [%lx, %lx).\n", mmio[index].start,
-+                mmio[index].start + mmio[index].size);
-+        mmio[index].start = mmio[index].size = 0;
-+    }
-+}
-+
-+
- #if defined(__i386__) || defined(__x86_64__)
- #define phys_ram_addr(x) (qemu_map_cache(x))
- #elif defined(__ia64__)
-Index: ioemu-remote/hw/xen_platform.c
-===================================================================
---- ioemu-remote.orig/hw/xen_platform.c        2008-12-15 16:02:19.000000000 +0000
-+++ ioemu-remote/hw/xen_platform.c     2008-12-15 16:02:35.000000000 +0000
-@@ -24,6 +24,7 @@
-  */
- #include "hw.h"
-+#include "pc.h"
- #include "pci.h"
- #include "irq.h"
- #include "qemu-xen.h"
-@@ -163,6 +164,52 @@
-     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
-+
-+static void platform_fixed_ioport_write2(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    switch (addr - 0x10) {
-+    case 0:
-+        /* Unplug devices.  Value is a bitmask of which devices to
-+           unplug, with bit 0 the IDE devices, bit 1 the network
-+           devices, and bit 2 the non-primary-master IDE devices. */
-+        if (val & UNPLUG_ALL_IDE_DISKS)
-+            ide_unplug_harddisks();
-+        if (val & UNPLUG_ALL_NICS) {
-+            pci_unplug_netifs();
-+            net_tap_shutdown_all();
-+        }
-+        if (val & UNPLUG_AUX_IDE_DISKS) {
-+            ide_unplug_aux_harddisks();
-+        }
-+        break;
-+    }
-+}
-+
-+static uint32_t platform_fixed_ioport_read2(void *opaque, uint32_t addr)
-+{
-+    switch (addr - 0x10) {
-+    case 0:
-+        return 0x49d2; /* Magic value so that you can identify the
-+                          interface. */
-+    default:
-+        return 0xffff;
-+    }
-+}
-+
-+static uint32_t platform_fixed_ioport_read1(void *opaque, uint32_t addr)
-+{
-+    switch (addr - 0x10) {
-+    case 2:
-+        /* Version number */
-+        return 0;
-+    default:
-+        return 0xff;
-+    }
-+}
-+
- struct pci_config_header {
-     uint16_t vendor_id;
-     uint16_t device_id;
-@@ -255,4 +302,7 @@
-     register_savevm("platform", 0, 2, xen_pci_save, xen_pci_load, d);
-     printf("Done register platform.\n");
-+    register_ioport_write(0x10, 16, 2, platform_fixed_ioport_write2, NULL);
-+    register_ioport_read(0x10, 16, 2, platform_fixed_ioport_read2, NULL);
-+    register_ioport_read(0x10, 16, 1, platform_fixed_ioport_read1, NULL);
- }
-Index: ioemu-remote/hw/pc.h
-===================================================================
---- ioemu-remote.orig/hw/pc.h  2008-12-15 16:02:19.000000000 +0000
-+++ ioemu-remote/hw/pc.h       2008-12-15 16:02:35.000000000 +0000
-@@ -146,6 +146,8 @@
-                         qemu_irq *pic);
- void pci_piix4_ide_init(PCIBus *bus, BlockDriverState **hd_table, int devfn,
-                         qemu_irq *pic);
-+void ide_unplug_harddisks(void);
-+void ide_unplug_aux_harddisks(void);
- /* ne2000.c */
-Index: ioemu-remote/hw/xen_platform.c
-===================================================================
---- ioemu-remote.orig/hw/xen_platform.c        2008-12-15 15:57:04.000000000 +0000
-+++ ioemu-remote/hw/xen_platform.c     2008-12-15 16:00:19.000000000 +0000
-@@ -31,6 +31,8 @@
- #include <xenguest.h>
- extern FILE *logfile;
-+static char log_buffer[4096];
-+static int log_buffer_off;
- #define PFFLAG_ROM_LOCK 1 /* Sets whether ROM memory area is RW or RO */
-@@ -68,6 +70,18 @@
-             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;
-+                fprintf(logfile, "%s\n", log_buffer);
-+                log_buffer_off = 0;
-+                break;
-+            }
-+            log_buffer[log_buffer_off++] = val;
-+        }
-+        break;
-     default:
-         break;
-     }
-@@ -180,6 +194,24 @@
-     }
- }
-+
-+static void platform_fixed_ioport_write1(void *opaque, uint32_t addr, uint32_t val)
-+{
-+    switch (addr - 0x10) {
-+    case 2:
-+        /* Send bytes to syslog */
-+        if (val == '\n' || log_buffer_off == sizeof(log_buffer) - 1) {
-+            /* Flush buffer */
-+            log_buffer[log_buffer_off] = 0;
-+            fprintf(logfile, "%s\n", log_buffer);
-+            log_buffer_off = 0;
-+            break;
-+        }
-+        log_buffer[log_buffer_off++] = val;
-+        break;
-+    }
-+}
-+
- static uint32_t platform_fixed_ioport_read2(void *opaque, uint32_t addr)
- {
-     switch (addr - 0x10) {
-@@ -295,6 +327,7 @@
-     register_savevm("platform", 0, 2, xen_pci_save, xen_pci_load, d);
-     printf("Done register platform.\n");
-     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);
- }
-Index: ioemu-remote/hw/xen_platform.c
-===================================================================
---- ioemu-remote.orig/hw/xen_platform.c        2008-12-15 15:02:53.000000000 +0000
-+++ ioemu-remote/hw/xen_platform.c     2008-12-15 15:03:34.000000000 +0000
-@@ -29,8 +29,10 @@
- #include "irq.h"
- #include "qemu-xen.h"
-+#include <assert.h>
- #include <xenguest.h>
-+static int throttling_disabled;
- extern FILE *logfile;
- static char log_buffer[4096];
- static int log_buffer_off;
-@@ -44,6 +46,88 @@
-   uint64_t   vga_stolen_ram;
- } PCIXenPlatformState;
-+/* We throttle access to dom0 syslog, to avoid DOS attacks.  This is
-+   modelled as a token bucket, with one token for every byte of log.
-+   The bucket size is 128KB (->1024 lines of 128 bytes each) and
-+   refills at 256B/s.  It starts full.  The guest is blocked if no
-+   tokens are available when it tries to generate a log message. */
-+#define BUCKET_MAX_SIZE (128*1024)
-+#define BUCKET_FILL_RATE 256
-+
-+static void throttle(unsigned count)
-+{
-+    static unsigned available;
-+    static struct timespec last_refil;
-+    static int started;
-+    static int warned;
-+
-+    struct timespec waiting_for, now;
-+    double delay;
-+    struct timespec ts;
-+
-+    if (throttling_disabled)
-+        return;
-+
-+    if (!started) {
-+        clock_gettime(CLOCK_MONOTONIC, &last_refil);
-+        available = BUCKET_MAX_SIZE;
-+        started = 1;
-+    }
-+
-+    if (count > BUCKET_MAX_SIZE) {
-+        fprintf(logfile, "tried to get %d tokens, but bucket size is %d\n",
-+                BUCKET_MAX_SIZE, count);
-+        exit(1);
-+    }
-+
-+    if (available < count) {
-+        /* The bucket is empty.  Refil it */
-+
-+        /* When will it be full enough to handle this request? */
-+        delay = (double)(count - available) / BUCKET_FILL_RATE;
-+        waiting_for = last_refil;
-+        waiting_for.tv_sec += delay;
-+        waiting_for.tv_nsec += (delay - (int)delay) * 1e9;
-+        if (waiting_for.tv_nsec >= 1000000000) {
-+            waiting_for.tv_nsec -= 1000000000;
-+            waiting_for.tv_sec++;
-+        }
-+
-+        /* How long do we have to wait? (might be negative) */
-+        clock_gettime(CLOCK_MONOTONIC, &now);
-+        ts.tv_sec = waiting_for.tv_sec - now.tv_sec;
-+        ts.tv_nsec = waiting_for.tv_nsec - now.tv_nsec;
-+        if (ts.tv_nsec < 0) {
-+            ts.tv_sec--;
-+            ts.tv_nsec += 1000000000;
-+        }
-+
-+        /* Wait for it. */
-+        if (ts.tv_sec > 0 ||
-+            (ts.tv_sec == 0 && ts.tv_nsec > 0)) {
-+            if (!warned) {
-+                fprintf(logfile, "throttling guest access to syslog");
-+                warned = 1;
-+            }
-+            while (nanosleep(&ts, &ts) < 0 && errno == EINTR)
-+                ;
-+        }
-+
-+        /* Refil */
-+        clock_gettime(CLOCK_MONOTONIC, &now);
-+        delay = (now.tv_sec - last_refil.tv_sec) +
-+            (now.tv_nsec - last_refil.tv_nsec) * 1.0e-9;
-+        available += BUCKET_FILL_RATE * delay;
-+        if (available > BUCKET_MAX_SIZE)
-+            available = BUCKET_MAX_SIZE;
-+        last_refil = now;
-+    }
-+
-+    assert(available >= count);
-+
-+    available -= count;
-+}
-+
- static uint32_t xen_platform_ioport_readb(void *opaque, uint32_t addr)
- {
-     PCIXenPlatformState *s = opaque;
-@@ -76,6 +160,7 @@
-             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;
-@@ -278,6 +363,7 @@
-         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;
-@@ -302,6 +388,7 @@
- {
-     PCIXenPlatformState *d;
-     struct pci_config_header *pch;
-+    struct stat stbuf;
-     printf("Register xen platform.\n");
-     d = (PCIXenPlatformState *)pci_register_device(
-@@ -337,4 +424,8 @@
-     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;
-+
- }
-Index: ioemu-remote/hw/xen_platform.c
-===================================================================
---- ioemu-remote.orig/hw/xen_platform.c        2008-12-15 15:03:34.000000000 +0000
-+++ ioemu-remote/hw/xen_platform.c     2008-12-15 15:06:08.000000000 +0000
-@@ -32,6 +32,8 @@
- #include <assert.h>
- #include <xenguest.h>
-+static int drivers_blacklisted;
-+static uint16_t driver_product_version;
- static int throttling_disabled;
- extern FILE *logfile;
- static char log_buffer[4096];
-@@ -341,6 +343,42 @@
-             ide_unplug_aux_harddisks();
-         }
-         break;
-+    case 2:
-+        switch (val) {
-+        case 1:
-+            fprintf(logfile, "Citrix Windows PV drivers loaded in guest\n");
-+            break;
-+        case 0:
-+            fprintf(logfile, "Guest claimed to be running PV product 0?\n");
-+            break;
-+        default:
-+            fprintf(logfile, "Unknown PV product %d loaded in guest\n", val);
-+            break;
-+        }
-+        driver_product_version = val;
-+        break;
-+    }
-+}
-+
-+static void platform_fixed_ioport_write4(void *opaque, uint32_t addr,
-+                                         uint32_t val)
-+{
-+    switch (addr - 0x10) {
-+    case 0:
-+        /* PV driver version */
-+        if (driver_product_version == 0) {
-+            fprintf(logfile,
-+                    "Drivers tried to set their version number (%d) before setting the product number?\n",
-+                    val);
-+            return;
-+        }
-+        fprintf(logfile, "PV driver build %d\n", val);
-+        if (xenstore_pv_driver_build_blacklisted(driver_product_version,
-+                                                 val)) {
-+            fprintf(logfile, "Drivers are blacklisted!\n");
-+            drivers_blacklisted = 1;
-+        }
-+        break;
-     }
- }
-@@ -348,8 +386,14 @@
- {
-     switch (addr - 0x10) {
-     case 0:
--        return 0x49d2; /* Magic value so that you can identify the
--                          interface. */
-+        if (drivers_blacklisted) {
-+            /* The drivers will recognise this magic number and refuse
-+             * to do anything. */
-+            return 0xd249;
-+        } else {
-+            /* Magic value so that you can identify the interface. */
-+            return 0x49d2;
-+        }
-     default:
-         return 0xffff;
-     }
-@@ -378,7 +422,7 @@
-     switch (addr - 0x10) {
-     case 2:
-         /* Version number */
--        return 0;
-+        return 1;
-     default:
-         return 0xff;
-     }
-@@ -420,6 +464,7 @@
-     register_savevm("platform", 0, 2, 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);
-Index: ioemu-remote/qemu-xen.h
-===================================================================
---- ioemu-remote.orig/qemu-xen.h       2008-12-15 15:02:53.000000000 +0000
-+++ ioemu-remote/qemu-xen.h    2008-12-15 15:06:39.000000000 +0000
-@@ -91,6 +91,8 @@
- char *xenstore_device_model_read(int domid, char *key, unsigned int *len);
- char *xenstore_read_battery_data(int battery_status);
- int xenstore_refresh_battery_status(void);
-+int xenstore_pv_driver_build_blacklisted(uint16_t product_number,
-+                                         uint32_t build_nr);
- /* xenfbfront.c */
- int xenfb_pv_display_init(DisplayState *ds);
-Index: ioemu-remote/xenstore.c
-===================================================================
---- ioemu-remote.orig/xenstore.c       2008-12-15 14:30:47.000000000 +0000
-+++ ioemu-remote/xenstore.c    2008-12-15 15:06:08.000000000 +0000
-@@ -782,6 +782,34 @@
-     free(path);
- }
-+int
-+xenstore_pv_driver_build_blacklisted(uint16_t product_nr,
-+                                     uint32_t build_nr)
-+{
-+    char *buf = NULL;
-+    char *tmp;
-+    const char *product;
-+
-+    switch (product_nr) {
-+    case 1:
-+        product = "xensource-windows";
-+        break;
-+    default:
-+        /* Don't know what product this is -> we can't blacklist
-+         * it. */
-+        return 0;
-+    }
-+    if (asprintf(&buf, "/mh/driver-blacklist/%s/%d", product, build_nr) < 0)
-+        return 0;
-+    tmp = xs_read(xsh, XBT_NULL, buf, NULL);
-+    free(tmp);
-+    free(buf);
-+    if (tmp == NULL)
-+        return 0;
-+    else
-+        return 1;
-+}
-+
- void xenstore_record_dm_state(char *state)
- {
-     xenstore_record_dm("state", state);
-application/pgp-signature           [Press RETURN to save to a file]
+The master registry of product names and numbers is in
+qemu-xen-unstable's xenstore.c.
index e57fd6658792cedbd044609fecc614ba42dd8a1c..1793ca54efcdf63d80f9fa4dc0e6bda60d1af740 100644 (file)
@@ -787,9 +787,17 @@ xenstore_pv_driver_build_blacklisted(uint16_t product_nr,
     const char *product;
 
     switch (product_nr) {
-    case 1:
-        product = "xensource-windows";
-        break;
+    /*
+     * In qemu-xen-unstable, this is the master registry of product
+     * numbers.  If you need a new product number allocating, please
+     * post to xen-devel@lists.xensource.com.  You should NOT use
+     * an existing product number without allocating one.
+     *
+     * If you maintain a seaparate versioning and distribution path
+     * for PV drivers you should have a separate product number so
+     * that your drivers can be separated from others'.
+     */
+    case 1:  product = "xensource-windows";  break;
     default:
         /* Don't know what product this is -> we can't blacklist
          * it. */