[Spice-commits] 86 commits - Makefile Makefile.objs Makefile.target QMP/qmp-events.txt audio/alsaaudio.c block.c block.h block/blkverify.c block/qcow2-cluster.c block/qcow2-snapshot.c block/qcow2.c block/qcow2.h block/raw-posix.c block_int.h cache-utils.c check-qjson.c compatfd.c compatfd.h configure cpu-all.h cpu-common.h cpus.c cpus.h cris-dis.c disas.h docs/tracing.txt dyngen-exec.h exec-all.h exec.c fsdev/qemu-fsdev.c hw/acpi_piix4.c hw/apic.c hw/bt-sdp.c hw/cs4231.c hw/eccmemctl.c hw/file-op-9p.h hw/ide hw/lance.c hw/mips_fulong2e.c hw/slavio_intctl.c hw/slavio_misc.c hw/slavio_timer.c hw/sparc32_dma.c hw/sun4m.c hw/sun4m_iommu.c hw/usb-wacom.c hw/virtio-9p-debug.c hw/virtio-9p-local.c hw/virtio-9p-posix-acl.c hw/virtio-9p-xattr-user.c hw/virtio-9p-xattr.c hw/virtio-9p-xattr.h hw/virtio-9p.c hw/virtio-9p.h hw/virtio-blk.c hw/vmmouse.c kvm-all.c kvm-stub.c kvm.h m68k-semi.c monitor.c os-posix.c os-win32.c osdep.c osdep.h oslib-posix.c oslib-win32.c pc-bios/bios.bin posix-aio-com pat.c qemu-common.h qemu-img-cmds.hx qemu-img.c qemu-img.texi qemu-io.c qemu-malloc.c qemu-os-posix.h qemu-os-win32.h qemu-timer-common.c qemu-timer.c qemu-timer.h qemu-tool.c roms/seabios rules.mak simpletrace.c simpletrace.py target-alpha/helper.c target-arm/cpu.h target-arm/helper.c target-arm/translate.c target-cris/cpu.h target-cris/translate.c target-i386/cpu.h target-i386/cpuid.c target-i386/helper.c target-i386/kvm.c target-i386/kvm_x86.h target-m68k/cpu.h target-m68k/helper.c target-m68k/translate.c target-microblaze/translate.c target-mips/cpu.h target-mips/translate.c target-mips/translate_init.c target-ppc/cpu.h target-ppc/translate.c target-ppc/translate_init.c target-s390x/translate.c target-sh4/cpu.h target-sh4/translate.c target-sparc/helper.c tcg/tcg.c tcg/tcg.h tests/Makefile tests/runcom.c tests/test-i386.c tests/test_path.c trace-events ui/curses.c ui/curses_keys.h ui/spice-display.c vl.c

Gerd Hoffmann kraxel at kemper.freedesktop.org
Mon Nov 1 04:43:57 PDT 2010


 Makefile                      |   18 -
 Makefile.objs                 |   16 +
 Makefile.target               |    2 
 QMP/qmp-events.txt            |    2 
 audio/alsaaudio.c             |   27 ++
 block.c                       |   16 +
 block.h                       |    2 
 block/blkverify.c             |    5 
 block/qcow2-cluster.c         |   25 +-
 block/qcow2-snapshot.c        |   33 +++
 block/qcow2.c                 |  278 +++++++++-------------------
 block/qcow2.h                 |    3 
 block/raw-posix.c             |   12 -
 block_int.h                   |    2 
 cache-utils.c                 |    2 
 check-qjson.c                 |    4 
 compatfd.c                    |  117 +++++++++++
 compatfd.h                    |   43 ++++
 configure                     |   25 ++
 cpu-all.h                     |   13 -
 cpu-common.h                  |    3 
 cpus.c                        |  158 ++++++++++++++-
 cpus.h                        |    3 
 cris-dis.c                    |    4 
 disas.h                       |    3 
 docs/tracing.txt              |    5 
 dyngen-exec.h                 |   23 --
 exec-all.h                    |    2 
 exec.c                        |   42 ++--
 fsdev/qemu-fsdev.c            |   48 +++-
 hw/acpi_piix4.c               |   34 ++-
 hw/apic.c                     |   48 +---
 hw/bt-sdp.c                   |   20 +-
 hw/cs4231.c                   |   20 --
 hw/eccmemctl.c                |   46 +---
 hw/file-op-9p.h               |   16 +
 hw/ide/core.c                 |   28 ++
 hw/ide/internal.h             |    3 
 hw/lance.c                    |   14 -
 hw/mips_fulong2e.c            |    2 
 hw/slavio_intctl.c            |   38 +--
 hw/slavio_misc.c              |   51 ++---
 hw/slavio_timer.c             |   49 +---
 hw/sparc32_dma.c              |   42 +---
 hw/sun4m.c                    |   18 -
 hw/sun4m_iommu.c              |   33 ---
 hw/usb-wacom.c                |   13 +
 hw/virtio-9p-debug.c          |   46 ++++
 hw/virtio-9p-local.c          |  135 +++----------
 hw/virtio-9p-posix-acl.c      |  140 ++++++++++++++
 hw/virtio-9p-xattr-user.c     |  109 +++++++++++
 hw/virtio-9p-xattr.c          |  156 +++++++++++++++
 hw/virtio-9p-xattr.h          |  103 ++++++++++
 hw/virtio-9p.c                |  314 +++++++++++++++++++++++--------
 hw/virtio-9p.h                |   61 ++++++
 hw/virtio-blk.c               |    8 
 hw/vmmouse.c                  |   31 ++-
 kvm-all.c                     |   18 +
 kvm-stub.c                    |    5 
 kvm.h                         |    9 
 m68k-semi.c                   |    2 
 monitor.c                     |    5 
 os-posix.c                    |   53 +++++
 os-win32.c                    |   24 ++
 osdep.c                       |  256 -------------------------
 osdep.h                       |   15 -
 oslib-posix.c                 |  109 +++++++++++
 oslib-win32.c                 |  121 ++++++++++++
 pc-bios/bios.bin              |binary
 posix-aio-compat.c            |    1 
 qemu-common.h                 |   42 +++-
 qemu-img-cmds.hx              |    4 
 qemu-img.c                    |   27 ++
 qemu-img.texi                 |    4 
 qemu-io.c                     |   39 +++
 qemu-malloc.c                 |   14 -
 qemu-os-posix.h               |    3 
 qemu-os-win32.h               |    8 
 qemu-timer-common.c           |   62 ++++++
 qemu-timer.c                  |   73 -------
 qemu-timer.h                  |   50 +++++
 qemu-tool.c                   |    8 
 roms/seabios                  |    2 
 rules.mak                     |    9 
 simpletrace.c                 |   16 -
 simpletrace.py                |    4 
 target-alpha/helper.c         |    3 
 target-arm/cpu.h              |    4 
 target-arm/helper.c           |    2 
 target-arm/translate.c        |    3 
 target-cris/cpu.h             |    2 
 target-cris/translate.c       |    5 
 target-i386/cpu.h             |   36 +++
 target-i386/cpuid.c           |   82 ++++++--
 target-i386/helper.c          |   20 +-
 target-i386/kvm.c             |  415 +++++++++++++++++++++++++++++++++++++++---
 target-i386/kvm_x86.h         |   22 ++
 target-m68k/cpu.h             |    3 
 target-m68k/helper.c          |    2 
 target-m68k/translate.c       |    3 
 target-microblaze/translate.c |    3 
 target-mips/cpu.h             |    3 
 target-mips/translate.c       |   12 -
 target-mips/translate_init.c  |    2 
 target-ppc/cpu.h              |    4 
 target-ppc/translate.c        |   14 -
 target-ppc/translate_init.c   |    2 
 target-s390x/translate.c      |    3 
 target-sh4/cpu.h              |    3 
 target-sh4/translate.c        |    2 
 target-sparc/helper.c         |   11 -
 tcg/tcg.c                     |    8 
 tcg/tcg.h                     |    3 
 tests/Makefile                |  123 ++++++++----
 tests/runcom.c                |   11 -
 tests/test-i386.c             |    5 
 tests/test_path.c             |   13 +
 trace-events                  |  120 ++++++++++++
 ui/curses.c                   |    9 
 ui/curses_keys.h              |    1 
 ui/spice-display.c            |    3 
 vl.c                          |   24 --
 122 files changed, 3109 insertions(+), 1369 deletions(-)

New commits:
commit 12b6278f9e2a1e3b8f60223fe065ddf2b119c6bc
Author: malc <av1474 at comtv.ru>
Date:   Mon Nov 1 00:53:19 2010 +0300

    Remove trailing whitespace
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/cache-utils.c b/cache-utils.c
index b1f2097..2db5af2 100644
--- a/cache-utils.c
+++ b/cache-utils.c
@@ -79,7 +79,7 @@ static void ppc_init_cacheline_sizes(void)
     qemu_cache_conf.dcache_bsize = cacheline;
     qemu_cache_conf.icache_bsize = cacheline;
 }
-#endif    
+#endif
 
 #ifdef __linux__
 void qemu_cache_utils_init(char **envp)
commit 97bf4851fe2542635ebe33bdd1473012a2421b42
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sun Oct 31 09:24:14 2010 +0000

    sparc32: convert debug printf statements to tracepoints
    
    Replace debug printf statements with tracepoints.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/cs4231.c b/hw/cs4231.c
index f7ce0af..2977101 100644
--- a/hw/cs4231.c
+++ b/hw/cs4231.c
@@ -23,9 +23,7 @@
  */
 
 #include "sysbus.h"
-
-/* debug CS4231 */
-//#define DEBUG_CS
+#include "trace.h"
 
 /*
  * In addition to Crystal CS4231 there is a DMA controller on Sparc.
@@ -46,13 +44,6 @@ typedef struct CSState {
 #define CS_VER 0xa0
 #define CS_CDC_VER 0x8a
 
-#ifdef DEBUG_CS
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("CS: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
 static void cs_reset(DeviceState *d)
 {
     CSState *s = container_of(d, CSState, busdev.qdev);
@@ -79,11 +70,11 @@ static uint32_t cs_mem_readl(void *opaque, target_phys_addr_t addr)
             ret = s->dregs[CS_RAP(s)];
             break;
         }
-        DPRINTF("read dreg[%d]: 0x%8.8x\n", CS_RAP(s), ret);
+        trace_cs4231_mem_readl_dreg(CS_RAP(s), ret);
         break;
     default:
         ret = s->regs[saddr];
-        DPRINTF("read reg[%d]: 0x%8.8x\n", saddr, ret);
+        trace_cs4231_mem_readl_reg(saddr, ret);
         break;
     }
     return ret;
@@ -95,11 +86,10 @@ static void cs_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
     uint32_t saddr;
 
     saddr = addr >> 2;
-    DPRINTF("write reg[%d]: 0x%8.8x -> 0x%8.8x\n", saddr, s->regs[saddr], val);
+    trace_cs4231_mem_writel_reg(saddr, s->regs[saddr], val);
     switch (saddr) {
     case 1:
-        DPRINTF("write dreg[%d]: 0x%2.2x -> 0x%2.2x\n", CS_RAP(s),
-                s->dregs[CS_RAP(s)], val);
+        trace_cs4231_mem_writel_dreg(CS_RAP(s), s->dregs[CS_RAP(s)], val);
         switch(CS_RAP(s)) {
         case 11:
         case 25: // Read only
diff --git a/hw/eccmemctl.c b/hw/eccmemctl.c
index 498c61a..a8042e9 100644
--- a/hw/eccmemctl.c
+++ b/hw/eccmemctl.c
@@ -23,15 +23,7 @@
  */
 
 #include "sysbus.h"
-
-//#define DEBUG_ECC
-
-#ifdef DEBUG_ECC
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("ECC: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
+#include "trace.h"
 
 /* There are 3 versions of this chip used in SMP sun4m systems:
  * MCC (version 0, implementation 0) SS-600MP
@@ -148,32 +140,32 @@ static void ecc_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
             s->regs[ECC_MER] = s->version | (val & ECC_MER_MASK_1);
         else if (s->version == ECC_SMC)
             s->regs[ECC_MER] = s->version | (val & ECC_MER_MASK_2);
-        DPRINTF("Write memory enable %08x\n", val);
+        trace_ecc_mem_writel_mer(val);
         break;
     case ECC_MDR:
         s->regs[ECC_MDR] =  val & ECC_MDR_MASK;
-        DPRINTF("Write memory delay %08x\n", val);
+        trace_ecc_mem_writel_mdr(val);
         break;
     case ECC_MFSR:
         s->regs[ECC_MFSR] =  val;
         qemu_irq_lower(s->irq);
-        DPRINTF("Write memory fault status %08x\n", val);
+        trace_ecc_mem_writel_mfsr(val);
         break;
     case ECC_VCR:
         s->regs[ECC_VCR] =  val;
-        DPRINTF("Write slot configuration %08x\n", val);
+        trace_ecc_mem_writel_vcr(val);
         break;
     case ECC_DR:
         s->regs[ECC_DR] =  val;
-        DPRINTF("Write diagnostic %08x\n", val);
+        trace_ecc_mem_writel_dr(val);
         break;
     case ECC_ECR0:
         s->regs[ECC_ECR0] =  val;
-        DPRINTF("Write event count 1 %08x\n", val);
+        trace_ecc_mem_writel_ecr0(val);
         break;
     case ECC_ECR1:
         s->regs[ECC_ECR0] =  val;
-        DPRINTF("Write event count 2 %08x\n", val);
+        trace_ecc_mem_writel_ecr1(val);
         break;
     }
 }
@@ -186,39 +178,39 @@ static uint32_t ecc_mem_readl(void *opaque, target_phys_addr_t addr)
     switch (addr >> 2) {
     case ECC_MER:
         ret = s->regs[ECC_MER];
-        DPRINTF("Read memory enable %08x\n", ret);
+        trace_ecc_mem_readl_mer(ret);
         break;
     case ECC_MDR:
         ret = s->regs[ECC_MDR];
-        DPRINTF("Read memory delay %08x\n", ret);
+        trace_ecc_mem_readl_mdr(ret);
         break;
     case ECC_MFSR:
         ret = s->regs[ECC_MFSR];
-        DPRINTF("Read memory fault status %08x\n", ret);
+        trace_ecc_mem_readl_mfsr(ret);
         break;
     case ECC_VCR:
         ret = s->regs[ECC_VCR];
-        DPRINTF("Read slot configuration %08x\n", ret);
+        trace_ecc_mem_readl_vcr(ret);
         break;
     case ECC_MFAR0:
         ret = s->regs[ECC_MFAR0];
-        DPRINTF("Read memory fault address 0 %08x\n", ret);
+        trace_ecc_mem_readl_mfar0(ret);
         break;
     case ECC_MFAR1:
         ret = s->regs[ECC_MFAR1];
-        DPRINTF("Read memory fault address 1 %08x\n", ret);
+        trace_ecc_mem_readl_mfar1(ret);
         break;
     case ECC_DR:
         ret = s->regs[ECC_DR];
-        DPRINTF("Read diagnostic %08x\n", ret);
+        trace_ecc_mem_readl_dr(ret);
         break;
     case ECC_ECR0:
         ret = s->regs[ECC_ECR0];
-        DPRINTF("Read event count 1 %08x\n", ret);
+        trace_ecc_mem_readl_ecr0(ret);
         break;
     case ECC_ECR1:
         ret = s->regs[ECC_ECR0];
-        DPRINTF("Read event count 2 %08x\n", ret);
+        trace_ecc_mem_readl_ecr1(ret);
         break;
     }
     return ret;
@@ -241,7 +233,7 @@ static void ecc_diag_mem_writeb(void *opaque, target_phys_addr_t addr,
 {
     ECCState *s = opaque;
 
-    DPRINTF("Write diagnostic[%d] = %02x\n", (int)addr, val);
+    trace_ecc_diag_mem_writeb(addr, val);
     s->diag[addr & ECC_DIAG_MASK] = val;
 }
 
@@ -250,7 +242,7 @@ static uint32_t ecc_diag_mem_readb(void *opaque, target_phys_addr_t addr)
     ECCState *s = opaque;
     uint32_t ret = s->diag[(int)addr];
 
-    DPRINTF("Read diagnostic[%d] = %02x\n", (int)addr, ret);
+    trace_ecc_diag_mem_readb(addr, ret);
     return ret;
 }
 
diff --git a/hw/lance.c b/hw/lance.c
index b6b04dd..dc12144 100644
--- a/hw/lance.c
+++ b/hw/lance.c
@@ -40,8 +40,8 @@
 #include "qemu-timer.h"
 #include "qemu_socket.h"
 #include "sun4m.h"
-
 #include "pcnet.h"
+#include "trace.h"
 
 typedef struct {
     SysBusDevice busdev;
@@ -59,10 +59,8 @@ static void lance_mem_writew(void *opaque, target_phys_addr_t addr,
                              uint32_t val)
 {
     SysBusPCNetState *d = opaque;
-#ifdef PCNET_DEBUG_IO
-    printf("lance_mem_writew addr=" TARGET_FMT_plx " val=0x%04x\n", addr,
-           val & 0xffff);
-#endif
+
+    trace_lance_mem_writew(addr, val & 0xffff);
     pcnet_ioport_writew(&d->state, addr, val & 0xffff);
 }
 
@@ -72,11 +70,7 @@ static uint32_t lance_mem_readw(void *opaque, target_phys_addr_t addr)
     uint32_t val;
 
     val = pcnet_ioport_readw(&d->state, addr);
-#ifdef PCNET_DEBUG_IO
-    printf("lance_mem_readw addr=" TARGET_FMT_plx " val = 0x%04x\n", addr,
-           val & 0xffff);
-#endif
-
+    trace_lance_mem_readw(addr, val & 0xffff);
     return val & 0xffff;
 }
 
diff --git a/hw/slavio_intctl.c b/hw/slavio_intctl.c
index 10362a3..9d5ad86 100644
--- a/hw/slavio_intctl.c
+++ b/hw/slavio_intctl.c
@@ -25,16 +25,9 @@
 #include "sun4m.h"
 #include "monitor.h"
 #include "sysbus.h"
+#include "trace.h"
 
 //#define DEBUG_IRQ_COUNT
-//#define DEBUG_IRQ
-
-#ifdef DEBUG_IRQ
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("IRQ: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
 
 /*
  * Registers of interrupt controller in sun4m.
@@ -97,7 +90,7 @@ static uint32_t slavio_intctl_mem_readl(void *opaque, target_phys_addr_t addr)
         ret = 0;
         break;
     }
-    DPRINTF("read cpu %d reg 0x" TARGET_FMT_plx " = %x\n", s->cpu, addr, ret);
+    trace_slavio_intctl_mem_readl(s->cpu, addr, ret);
 
     return ret;
 }
@@ -109,21 +102,19 @@ static void slavio_intctl_mem_writel(void *opaque, target_phys_addr_t addr,
     uint32_t saddr;
 
     saddr = addr >> 2;
-    DPRINTF("write cpu %d reg 0x" TARGET_FMT_plx " = %x\n", s->cpu, addr, val);
+    trace_slavio_intctl_mem_writel(s->cpu, addr, val);
     switch (saddr) {
     case 1: // clear pending softints
         val &= CPU_SOFTIRQ_MASK | CPU_IRQ_INT15_IN;
         s->intreg_pending &= ~val;
         slavio_check_interrupts(s->master, 1);
-        DPRINTF("Cleared cpu %d irq mask %x, curmask %x\n", s->cpu, val,
-                s->intreg_pending);
+        trace_slavio_intctl_mem_writel_clear(s->cpu, val, s->intreg_pending);
         break;
     case 2: // set softint
         val &= CPU_SOFTIRQ_MASK;
         s->intreg_pending |= val;
         slavio_check_interrupts(s->master, 1);
-        DPRINTF("Set cpu %d irq mask %x, curmask %x\n", s->cpu, val,
-                s->intreg_pending);
+        trace_slavio_intctl_mem_writel_set(s->cpu, val, s->intreg_pending);
         break;
     default:
         break;
@@ -163,7 +154,7 @@ static uint32_t slavio_intctlm_mem_readl(void *opaque, target_phys_addr_t addr)
         ret = 0;
         break;
     }
-    DPRINTF("read system reg 0x" TARGET_FMT_plx " = %x\n", addr, ret);
+    trace_slavio_intctlm_mem_readl(addr, ret);
 
     return ret;
 }
@@ -175,14 +166,13 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr,
     uint32_t saddr;
 
     saddr = addr >> 2;
-    DPRINTF("write system reg 0x" TARGET_FMT_plx " = %x\n", addr, val);
+    trace_slavio_intctlm_mem_writel(addr, val);
     switch (saddr) {
     case 2: // clear (enable)
         // Force clear unused bits
         val &= MASTER_IRQ_MASK;
         s->intregm_disabled &= ~val;
-        DPRINTF("Enabled master irq mask %x, curmask %x\n", val,
-                s->intregm_disabled);
+        trace_slavio_intctlm_mem_writel_enable(val, s->intregm_disabled);
         slavio_check_interrupts(s, 1);
         break;
     case 3: // set (disable; doesn't affect pending)
@@ -190,13 +180,12 @@ static void slavio_intctlm_mem_writel(void *opaque, target_phys_addr_t addr,
         val &= MASTER_IRQ_MASK;
         s->intregm_disabled |= val;
         slavio_check_interrupts(s, 1);
-        DPRINTF("Disabled master irq mask %x, curmask %x\n", val,
-                s->intregm_disabled);
+        trace_slavio_intctlm_mem_writel_disable(val, s->intregm_disabled);
         break;
     case 4:
         s->target_cpu = val & (MAX_CPUS - 1);
         slavio_check_interrupts(s, 1);
-        DPRINTF("Set master irq cpu %d\n", s->target_cpu);
+        trace_slavio_intctlm_mem_writel_target(s->target_cpu);
         break;
     default:
         break;
@@ -264,7 +253,7 @@ static void slavio_check_interrupts(SLAVIO_INTCTLState *s, int set_irqs)
 
     pending &= ~s->intregm_disabled;
 
-    DPRINTF("pending %x disabled %x\n", pending, s->intregm_disabled);
+    trace_slavio_check_interrupts(pending, s->intregm_disabled);
     for (i = 0; i < MAX_CPUS; i++) {
         pil_pending = 0;
 
@@ -327,8 +316,7 @@ static void slavio_set_irq(void *opaque, int irq, int level)
     uint32_t pil = intbit_to_level[irq];
     unsigned int i;
 
-    DPRINTF("Set cpu %d irq %d -> pil %d level %d\n", s->target_cpu, irq, pil,
-            level);
+    trace_slavio_set_irq(s->target_cpu, irq, pil, level);
     if (pil > 0) {
         if (level) {
 #ifdef DEBUG_IRQ_COUNT
@@ -356,7 +344,7 @@ static void slavio_set_timer_irq_cpu(void *opaque, int cpu, int level)
 {
     SLAVIO_INTCTLState *s = opaque;
 
-    DPRINTF("Set cpu %d local timer level %d\n", cpu, level);
+    trace_slavio_set_timer_irq_cpu(cpu, level);
 
     if (level) {
         s->slaves[cpu].intreg_pending |= CPU_IRQ_TIMER_IN;
diff --git a/hw/slavio_misc.c b/hw/slavio_misc.c
index 5ae628d..1d81a63 100644
--- a/hw/slavio_misc.c
+++ b/hw/slavio_misc.c
@@ -24,9 +24,7 @@
 
 #include "sysemu.h"
 #include "sysbus.h"
-
-/* debug misc */
-//#define DEBUG_MISC
+#include "trace.h"
 
 /*
  * This is the auxio port, chip control and system control part of
@@ -36,13 +34,6 @@
  * This also includes the PMC CPU idle controller.
  */
 
-#ifdef DEBUG_MISC
-#define MISC_DPRINTF(fmt, ...)                                  \
-    do { printf("MISC: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define MISC_DPRINTF(fmt, ...)
-#endif
-
 typedef struct MiscState {
     SysBusDevice busdev;
     qemu_irq irq;
@@ -79,10 +70,10 @@ static void slavio_misc_update_irq(void *opaque)
     MiscState *s = opaque;
 
     if ((s->aux2 & AUX2_PWRFAIL) && (s->config & CFG_PWRINTEN)) {
-        MISC_DPRINTF("Raise IRQ\n");
+        trace_slavio_misc_update_irq_raise();
         qemu_irq_raise(s->irq);
     } else {
-        MISC_DPRINTF("Lower IRQ\n");
+        trace_slavio_misc_update_irq_lower();
         qemu_irq_lower(s->irq);
     }
 }
@@ -99,7 +90,7 @@ static void slavio_set_power_fail(void *opaque, int irq, int power_failing)
 {
     MiscState *s = opaque;
 
-    MISC_DPRINTF("Power fail: %d, config: %d\n", power_failing, s->config);
+    trace_slavio_set_power_fail(power_failing, s->config);
     if (power_failing && (s->config & CFG_PWRINTEN)) {
         s->aux2 |= AUX2_PWRFAIL;
     } else {
@@ -113,7 +104,7 @@ static void slavio_cfg_mem_writeb(void *opaque, target_phys_addr_t addr,
 {
     MiscState *s = opaque;
 
-    MISC_DPRINTF("Write config %2.2x\n", val & 0xff);
+    trace_slavio_cfg_mem_writeb(val & 0xff);
     s->config = val & 0xff;
     slavio_misc_update_irq(s);
 }
@@ -124,7 +115,7 @@ static uint32_t slavio_cfg_mem_readb(void *opaque, target_phys_addr_t addr)
     uint32_t ret = 0;
 
     ret = s->config;
-    MISC_DPRINTF("Read config %2.2x\n", ret);
+    trace_slavio_cfg_mem_readb(ret);
     return ret;
 }
 
@@ -145,7 +136,7 @@ static void slavio_diag_mem_writeb(void *opaque, target_phys_addr_t addr,
 {
     MiscState *s = opaque;
 
-    MISC_DPRINTF("Write diag %2.2x\n", val & 0xff);
+    trace_slavio_diag_mem_writeb(val & 0xff);
     s->diag = val & 0xff;
 }
 
@@ -155,7 +146,7 @@ static uint32_t slavio_diag_mem_readb(void *opaque, target_phys_addr_t addr)
     uint32_t ret = 0;
 
     ret = s->diag;
-    MISC_DPRINTF("Read diag %2.2x\n", ret);
+    trace_slavio_diag_mem_readb(ret);
     return ret;
 }
 
@@ -176,7 +167,7 @@ static void slavio_mdm_mem_writeb(void *opaque, target_phys_addr_t addr,
 {
     MiscState *s = opaque;
 
-    MISC_DPRINTF("Write modem control %2.2x\n", val & 0xff);
+    trace_slavio_mdm_mem_writeb(val & 0xff);
     s->mctrl = val & 0xff;
 }
 
@@ -186,7 +177,7 @@ static uint32_t slavio_mdm_mem_readb(void *opaque, target_phys_addr_t addr)
     uint32_t ret = 0;
 
     ret = s->mctrl;
-    MISC_DPRINTF("Read modem control %2.2x\n", ret);
+    trace_slavio_mdm_mem_readb(ret);
     return ret;
 }
 
@@ -207,7 +198,7 @@ static void slavio_aux1_mem_writeb(void *opaque, target_phys_addr_t addr,
 {
     MiscState *s = opaque;
 
-    MISC_DPRINTF("Write aux1 %2.2x\n", val & 0xff);
+    trace_slavio_aux1_mem_writeb(val & 0xff);
     if (val & AUX1_TC) {
         // Send a pulse to floppy terminal count line
         if (s->fdc_tc) {
@@ -225,8 +216,7 @@ static uint32_t slavio_aux1_mem_readb(void *opaque, target_phys_addr_t addr)
     uint32_t ret = 0;
 
     ret = s->aux1;
-    MISC_DPRINTF("Read aux1 %2.2x\n", ret);
-
+    trace_slavio_aux1_mem_readb(ret);
     return ret;
 }
 
@@ -248,7 +238,7 @@ static void slavio_aux2_mem_writeb(void *opaque, target_phys_addr_t addr,
     MiscState *s = opaque;
 
     val &= AUX2_PWRINTCLR | AUX2_PWROFF;
-    MISC_DPRINTF("Write aux2 %2.2x\n", val);
+    trace_slavio_aux2_mem_writeb(val & 0xff);
     val |= s->aux2 & AUX2_PWRFAIL;
     if (val & AUX2_PWRINTCLR) // Clear Power Fail int
         val &= AUX2_PWROFF;
@@ -264,8 +254,7 @@ static uint32_t slavio_aux2_mem_readb(void *opaque, target_phys_addr_t addr)
     uint32_t ret = 0;
 
     ret = s->aux2;
-    MISC_DPRINTF("Read aux2 %2.2x\n", ret);
-
+    trace_slavio_aux2_mem_readb(ret);
     return ret;
 }
 
@@ -285,7 +274,7 @@ static void apc_mem_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
 {
     APCState *s = opaque;
 
-    MISC_DPRINTF("Write power management %2.2x\n", val & 0xff);
+    trace_apc_mem_writeb(val & 0xff);
     qemu_irq_raise(s->cpu_halt);
 }
 
@@ -293,7 +282,7 @@ static uint32_t apc_mem_readb(void *opaque, target_phys_addr_t addr)
 {
     uint32_t ret = 0;
 
-    MISC_DPRINTF("Read power management %2.2x\n", ret);
+    trace_apc_mem_readb(ret);
     return ret;
 }
 
@@ -321,7 +310,7 @@ static uint32_t slavio_sysctrl_mem_readl(void *opaque, target_phys_addr_t addr)
     default:
         break;
     }
-    MISC_DPRINTF("Read system control %08x\n", ret);
+    trace_slavio_sysctrl_mem_readl(ret);
     return ret;
 }
 
@@ -330,7 +319,7 @@ static void slavio_sysctrl_mem_writel(void *opaque, target_phys_addr_t addr,
 {
     MiscState *s = opaque;
 
-    MISC_DPRINTF("Write system control %08x\n", val);
+    trace_slavio_sysctrl_mem_writel(val);
     switch (addr) {
     case 0:
         if (val & SYS_RESET) {
@@ -367,7 +356,7 @@ static uint32_t slavio_led_mem_readw(void *opaque, target_phys_addr_t addr)
     default:
         break;
     }
-    MISC_DPRINTF("Read diagnostic LED %04x\n", ret);
+    trace_slavio_led_mem_readw(ret);
     return ret;
 }
 
@@ -376,7 +365,7 @@ static void slavio_led_mem_writew(void *opaque, target_phys_addr_t addr,
 {
     MiscState *s = opaque;
 
-    MISC_DPRINTF("Write diagnostic LED %04x\n", val & 0xffff);
+    trace_slavio_led_mem_readw(val & 0xffff);
     switch (addr) {
     case 0:
         s->leds = val;
diff --git a/hw/slavio_timer.c b/hw/slavio_timer.c
index c125de4..13f1e62 100644
--- a/hw/slavio_timer.c
+++ b/hw/slavio_timer.c
@@ -25,15 +25,7 @@
 #include "sun4m.h"
 #include "qemu-timer.h"
 #include "sysbus.h"
-
-//#define DEBUG_TIMER
-
-#ifdef DEBUG_TIMER
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("TIMER: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...) do {} while (0)
-#endif
+#include "trace.h"
 
 /*
  * Registers of hardware timer in sun4m.
@@ -112,8 +104,7 @@ static void slavio_timer_get_out(CPUTimerState *t)
     }
     count = limit - PERIODS_TO_LIMIT(ptimer_get_count(t->timer));
 
-    DPRINTF("get_out: limit %" PRIx64 " count %x%08x\n", t->limit, t->counthigh,
-            t->count);
+    trace_slavio_timer_get_out(t->limit, t->counthigh, t->count);
     t->count = count & TIMER_COUNT_MASK32;
     t->counthigh = count >> 32;
 }
@@ -126,7 +117,7 @@ static void slavio_timer_irq(void *opaque)
     CPUTimerState *t = &s->cputimer[tc->timer_index];
 
     slavio_timer_get_out(t);
-    DPRINTF("callback: count %x%08x\n", t->counthigh, t->count);
+    trace_slavio_timer_irq(t->counthigh, t->count);
     /* if limit is 0 (free-run), there will be no match */
     if (t->limit != 0) {
         t->reached = TIMER_REACHED;
@@ -188,12 +179,11 @@ static uint32_t slavio_timer_mem_readl(void *opaque, target_phys_addr_t addr)
         ret = s->cputimer_mode;
         break;
     default:
-        DPRINTF("invalid read address " TARGET_FMT_plx "\n", addr);
+        trace_slavio_timer_mem_readl_invalid(addr);
         ret = 0;
         break;
     }
-    DPRINTF("read " TARGET_FMT_plx " = %08x\n", addr, ret);
-
+    trace_slavio_timer_mem_readl(addr, ret);
     return ret;
 }
 
@@ -206,7 +196,7 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
     unsigned int timer_index = tc->timer_index;
     CPUTimerState *t = &s->cputimer[timer_index];
 
-    DPRINTF("write " TARGET_FMT_plx " %08x\n", addr, val);
+    trace_slavio_timer_mem_writel(addr, val);
     saddr = addr >> 2;
     switch (saddr) {
     case TIMER_LIMIT:
@@ -218,8 +208,7 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
             t->counthigh = val & (TIMER_MAX_COUNT64 >> 32);
             t->reached = 0;
             count = ((uint64_t)t->counthigh << 32) | t->count;
-            DPRINTF("processor %d user timer set to %016" PRIx64 "\n",
-                    timer_index, count);
+            trace_slavio_timer_mem_writel_limit(timer_index, count);
             ptimer_set_count(t->timer, LIMIT_TO_PERIODS(t->limit - count));
         } else {
             // set limit, reset counter
@@ -244,11 +233,11 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
             t->count = val & TIMER_MAX_COUNT64;
             t->reached = 0;
             count = ((uint64_t)t->counthigh) << 32 | t->count;
-            DPRINTF("processor %d user timer set to %016" PRIx64 "\n",
-                    timer_index, count);
+            trace_slavio_timer_mem_writel_limit(timer_index, count);
             ptimer_set_count(t->timer, LIMIT_TO_PERIODS(t->limit - count));
-        } else
-            DPRINTF("not user timer\n");
+        } else {
+            trace_slavio_timer_mem_writel_counter_invalid();
+        }
         break;
     case TIMER_COUNTER_NORST:
         // set limit without resetting counter
@@ -263,13 +252,11 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
         if (slavio_timer_is_user(tc)) {
             // start/stop user counter
             if ((val & 1) && !t->running) {
-                DPRINTF("processor %d user timer started\n",
-                        timer_index);
+                trace_slavio_timer_mem_writel_status_start(timer_index);
                 ptimer_run(t->timer, 0);
                 t->running = 1;
             } else if (!(val & 1) && t->running) {
-                DPRINTF("processor %d user timer stopped\n",
-                        timer_index);
+                trace_slavio_timer_mem_writel_status_stop(timer_index);
                 ptimer_stop(t->timer);
                 t->running = 0;
             }
@@ -298,8 +285,7 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
                         // set this processors user timer bit in config
                         // register
                         s->cputimer_mode |= processor;
-                        DPRINTF("processor %d changed from counter to user "
-                                "timer\n", timer_index);
+                        trace_slavio_timer_mem_writel_mode_user(timer_index);
                     } else { // user timer -> counter
                         // stop the user timer if it is running
                         if (curr_timer->running) {
@@ -311,17 +297,16 @@ static void slavio_timer_mem_writel(void *opaque, target_phys_addr_t addr,
                         // clear this processors user timer bit in config
                         // register
                         s->cputimer_mode &= ~processor;
-                        DPRINTF("processor %d changed from user timer to "
-                                "counter\n", timer_index);
+                        trace_slavio_timer_mem_writel_mode_counter(timer_index);
                     }
                 }
             }
         } else {
-            DPRINTF("not system timer\n");
+            trace_slavio_timer_mem_writel_mode_invalid();
         }
         break;
     default:
-        DPRINTF("invalid write address " TARGET_FMT_plx "\n", addr);
+        trace_slavio_timer_mem_writel_invalid(addr);
         break;
     }
 }
diff --git a/hw/sparc32_dma.c b/hw/sparc32_dma.c
index 984ffc3..0904188 100644
--- a/hw/sparc32_dma.c
+++ b/hw/sparc32_dma.c
@@ -29,9 +29,7 @@
 #include "sparc32_dma.h"
 #include "sun4m.h"
 #include "sysbus.h"
-
-/* debug DMA */
-//#define DEBUG_DMA
+#include "trace.h"
 
 /*
  * This is the DMA controller part of chip STP2000 (Master I/O), also
@@ -41,13 +39,6 @@
  * http://www.ibiblio.org/pub/historic-linux/early-ports/Sparc/NCR/DMA2.txt
  */
 
-#ifdef DEBUG_DMA
-#define DPRINTF(fmt, ...)                               \
-    do { printf("DMA: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
 #define DMA_REGS 4
 #define DMA_SIZE (4 * sizeof(uint32_t))
 /* We need the mask, because one instance of the device is not page
@@ -88,9 +79,8 @@ void ledma_memory_read(void *opaque, target_phys_addr_t addr,
     DMAState *s = opaque;
     int i;
 
-    DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n",
-            s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
     addr |= s->dmaregs[3];
+    trace_ledma_memory_read(addr);
     if (do_bswap) {
         sparc_iommu_memory_read(s->iommu, addr, buf, len);
     } else {
@@ -110,9 +100,8 @@ void ledma_memory_write(void *opaque, target_phys_addr_t addr,
     int l, i;
     uint16_t tmp_buf[32];
 
-    DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n",
-            s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
     addr |= s->dmaregs[3];
+    trace_ledma_memory_write(addr);
     if (do_bswap) {
         sparc_iommu_memory_write(s->iommu, addr, buf, len);
     } else {
@@ -139,14 +128,14 @@ static void dma_set_irq(void *opaque, int irq, int level)
     if (level) {
         s->dmaregs[0] |= DMA_INTR;
         if (s->dmaregs[0] & DMA_INTREN) {
-            DPRINTF("Raise IRQ\n");
+            trace_sparc32_dma_set_irq_raise();
             qemu_irq_raise(s->irq);
         }
     } else {
         if (s->dmaregs[0] & DMA_INTR) {
             s->dmaregs[0] &= ~DMA_INTR;
             if (s->dmaregs[0] & DMA_INTREN) {
-                DPRINTF("Lower IRQ\n");
+                trace_sparc32_dma_set_irq_lower();
                 qemu_irq_lower(s->irq);
             }
         }
@@ -157,8 +146,7 @@ void espdma_memory_read(void *opaque, uint8_t *buf, int len)
 {
     DMAState *s = opaque;
 
-    DPRINTF("DMA read, direction: %c, addr 0x%8.8x\n",
-            s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
+    trace_espdma_memory_read(s->dmaregs[1]);
     sparc_iommu_memory_read(s->iommu, s->dmaregs[1], buf, len);
     s->dmaregs[1] += len;
 }
@@ -167,8 +155,7 @@ void espdma_memory_write(void *opaque, uint8_t *buf, int len)
 {
     DMAState *s = opaque;
 
-    DPRINTF("DMA write, direction: %c, addr 0x%8.8x\n",
-            s->dmaregs[0] & DMA_WRITE_MEM ? 'w': 'r', s->dmaregs[1]);
+    trace_espdma_memory_write(s->dmaregs[1]);
     sparc_iommu_memory_write(s->iommu, s->dmaregs[1], buf, len);
     s->dmaregs[1] += len;
 }
@@ -179,9 +166,7 @@ static uint32_t dma_mem_readl(void *opaque, target_phys_addr_t addr)
     uint32_t saddr;
 
     saddr = (addr & DMA_MASK) >> 2;
-    DPRINTF("read dmareg " TARGET_FMT_plx ": 0x%8.8x\n", addr,
-            s->dmaregs[saddr]);
-
+    trace_sparc32_dma_mem_readl(addr, s->dmaregs[saddr]);
     return s->dmaregs[saddr];
 }
 
@@ -191,18 +176,17 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
     uint32_t saddr;
 
     saddr = (addr & DMA_MASK) >> 2;
-    DPRINTF("write dmareg " TARGET_FMT_plx ": 0x%8.8x -> 0x%8.8x\n", addr,
-            s->dmaregs[saddr], val);
+    trace_sparc32_dma_mem_writel(addr, s->dmaregs[saddr], val);
     switch (saddr) {
     case 0:
         if (val & DMA_INTREN) {
             if (s->dmaregs[0] & DMA_INTR) {
-                DPRINTF("Raise IRQ\n");
+                trace_sparc32_dma_set_irq_raise();
                 qemu_irq_raise(s->irq);
             }
         } else {
             if (s->dmaregs[0] & (DMA_INTR | DMA_INTREN)) {
-                DPRINTF("Lower IRQ\n");
+                trace_sparc32_dma_set_irq_lower();
                 qemu_irq_lower(s->irq);
             }
         }
@@ -215,10 +199,10 @@ static void dma_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
             val = DMA_DRAIN_FIFO;
 
         if (val & DMA_EN && !(s->dmaregs[0] & DMA_EN)) {
-            DPRINTF("Raise DMA enable\n");
+            trace_sparc32_dma_enable_raise();
             qemu_irq_raise(s->gpio[GPIO_DMA]);
         } else if (!(val & DMA_EN) && !!(s->dmaregs[0] & DMA_EN)) {
-            DPRINTF("Lower DMA enable\n");
+            trace_sparc32_dma_enable_lower();
             qemu_irq_lower(s->gpio[GPIO_DMA]);
         }
 
diff --git a/hw/sun4m.c b/hw/sun4m.c
index 0392109..4795b3f 100644
--- a/hw/sun4m.c
+++ b/hw/sun4m.c
@@ -41,8 +41,7 @@
 #include "loader.h"
 #include "elf.h"
 #include "blockdev.h"
-
-//#define DEBUG_IRQ
+#include "trace.h"
 
 /*
  * Sun4m architecture was used in the following machines:
@@ -72,13 +71,6 @@
  * See for example: http://www.sunhelp.org/faq/sunref1.html
  */
 
-#ifdef DEBUG_IRQ
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("CPUIRQ: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
 #define KERNEL_LOAD_ADDR     0x00004000
 #define CMDLINE_ADDR         0x007ff000
 #define INITRD_LOAD_ADDR     0x00800000
@@ -248,14 +240,14 @@ void cpu_check_irqs(CPUState *env)
 
                 env->interrupt_index = TT_EXTINT | i;
                 if (old_interrupt != env->interrupt_index) {
-                    DPRINTF("Set CPU IRQ %d\n", i);
+                    trace_sun4m_cpu_interrupt(i);
                     cpu_interrupt(env, CPU_INTERRUPT_HARD);
                 }
                 break;
             }
         }
     } else if (!env->pil_in && (env->interrupt_index & ~15) == TT_EXTINT) {
-        DPRINTF("Reset CPU IRQ %d\n", env->interrupt_index & 15);
+        trace_sun4m_cpu_reset_interrupt(env->interrupt_index & 15);
         env->interrupt_index = 0;
         cpu_reset_interrupt(env, CPU_INTERRUPT_HARD);
     }
@@ -266,12 +258,12 @@ static void cpu_set_irq(void *opaque, int irq, int level)
     CPUState *env = opaque;
 
     if (level) {
-        DPRINTF("Raise CPU IRQ %d\n", irq);
+        trace_sun4m_cpu_set_irq_raise(irq);
         env->halted = 0;
         env->pil_in |= 1 << irq;
         cpu_check_irqs(env);
     } else {
-        DPRINTF("Lower CPU IRQ %d\n", irq);
+        trace_sun4m_cpu_set_irq_lower(irq);
         env->pil_in &= ~(1 << irq);
         cpu_check_irqs(env);
     }
diff --git a/hw/sun4m_iommu.c b/hw/sun4m_iommu.c
index 1dbe077..720ee3f 100644
--- a/hw/sun4m_iommu.c
+++ b/hw/sun4m_iommu.c
@@ -24,16 +24,7 @@
 
 #include "sun4m.h"
 #include "sysbus.h"
-
-/* debug iommu */
-//#define DEBUG_IOMMU
-
-#ifdef DEBUG_IOMMU
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("IOMMU: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
+#include "trace.h"
 
 /*
  * I/O MMU used by Sun4m systems
@@ -160,7 +151,7 @@ static uint32_t iommu_mem_readl(void *opaque, target_phys_addr_t addr)
         qemu_irq_lower(s->irq);
         break;
     }
-    DPRINTF("read reg[%d] = %x\n", (int)saddr, ret);
+    trace_sun4m_iommu_mem_readl(saddr, ret);
     return ret;
 }
 
@@ -171,7 +162,7 @@ static void iommu_mem_writel(void *opaque, target_phys_addr_t addr,
     target_phys_addr_t saddr;
 
     saddr = addr >> 2;
-    DPRINTF("write reg[%d] = %x\n", (int)saddr, val);
+    trace_sun4m_iommu_mem_writel(saddr, val);
     switch (saddr) {
     case IOMMU_CTRL:
         switch (val & IOMMU_CTRL_RNGE) {
@@ -201,18 +192,18 @@ static void iommu_mem_writel(void *opaque, target_phys_addr_t addr,
             s->iostart = 0xffffffff80000000ULL;
             break;
         }
-        DPRINTF("iostart = " TARGET_FMT_plx "\n", s->iostart);
+        trace_sun4m_iommu_mem_writel_ctrl(s->iostart);
         s->regs[saddr] = ((val & IOMMU_CTRL_MASK) | s->version);
         break;
     case IOMMU_BASE:
         s->regs[saddr] = val & IOMMU_BASE_MASK;
         break;
     case IOMMU_TLBFLUSH:
-        DPRINTF("tlb flush %x\n", val);
+        trace_sun4m_iommu_mem_writel_tlbflush(val);
         s->regs[saddr] = val & IOMMU_TLBFLUSH_MASK;
         break;
     case IOMMU_PGFLUSH:
-        DPRINTF("page flush %x\n", val);
+        trace_sun4m_iommu_mem_writel_pgflush(val);
         s->regs[saddr] = val & IOMMU_PGFLUSH_MASK;
         break;
     case IOMMU_AFAR:
@@ -262,18 +253,14 @@ static uint32_t iommu_page_get_flags(IOMMUState *s, target_phys_addr_t addr)
 {
     uint32_t ret;
     target_phys_addr_t iopte;
-#ifdef DEBUG_IOMMU
     target_phys_addr_t pa = addr;
-#endif
 
     iopte = s->regs[IOMMU_BASE] << 4;
     addr &= ~s->iostart;
     iopte += (addr >> (IOMMU_PAGE_SHIFT - 2)) & ~3;
     cpu_physical_memory_read(iopte, (uint8_t *)&ret, 4);
     tswap32s(&ret);
-    DPRINTF("get flags addr " TARGET_FMT_plx " => pte " TARGET_FMT_plx
-            ", *pte = %x\n", pa, iopte, ret);
-
+    trace_sun4m_iommu_page_get_flags(pa, iopte, ret);
     return ret;
 }
 
@@ -283,16 +270,14 @@ static target_phys_addr_t iommu_translate_pa(target_phys_addr_t addr,
     target_phys_addr_t pa;
 
     pa = ((pte & IOPTE_PAGE) << 4) + (addr & ~IOMMU_PAGE_MASK);
-    DPRINTF("xlate dva " TARGET_FMT_plx " => pa " TARGET_FMT_plx
-            " (iopte = %x)\n", addr, pa, pte);
-
+    trace_sun4m_iommu_translate_pa(addr, pa, pte);
     return pa;
 }
 
 static void iommu_bad_addr(IOMMUState *s, target_phys_addr_t addr,
                            int is_write)
 {
-    DPRINTF("bad addr " TARGET_FMT_plx "\n", addr);
+    trace_sun4m_iommu_bad_addr(addr);
     s->regs[IOMMU_AFSR] = IOMMU_AFSR_ERR | IOMMU_AFSR_LE | IOMMU_AFSR_RESV |
         IOMMU_AFSR_FAV;
     if (!is_write)
diff --git a/trace-events b/trace-events
index ed2055e..947f8b0 100644
--- a/trace-events
+++ b/trace-events
@@ -81,3 +81,111 @@ disable apic_mem_writel(uint64_t addr, uint32_t val) "%"PRIx64" = %08x"
 disable apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d"
 disable apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d"
 disable apic_set_irq(int apic_irq_delivered) "coalescing %d"
+
+# hw/cs4231.c
+disable cs4231_mem_readl_dreg(uint32_t reg, uint32_t ret) "read dreg %d: 0x%02x"
+disable cs4231_mem_readl_reg(uint32_t reg, uint32_t ret) "read reg %d: 0x%08x"
+disable cs4231_mem_writel_reg(uint32_t reg, uint32_t old, uint32_t val) "write reg %d: 0x%08x -> 0x%08x"
+disable cs4231_mem_writel_dreg(uint32_t reg, uint32_t old, uint32_t val) "write dreg %d: 0x%02x -> 0x%02x"
+
+# hw/eccmemctl.c
+disable ecc_mem_writel_mer(uint32_t val) "Write memory enable %08x"
+disable ecc_mem_writel_mdr(uint32_t val) "Write memory delay %08x"
+disable ecc_mem_writel_mfsr(uint32_t val) "Write memory fault status %08x"
+disable ecc_mem_writel_vcr(uint32_t val) "Write slot configuration %08x"
+disable ecc_mem_writel_dr(uint32_t val) "Write diagnostic %08x"
+disable ecc_mem_writel_ecr0(uint32_t val) "Write event count 1 %08x"
+disable ecc_mem_writel_ecr1(uint32_t val) "Write event count 2 %08x"
+disable ecc_mem_readl_mer(uint32_t ret) "Read memory enable %08x"
+disable ecc_mem_readl_mdr(uint32_t ret) "Read memory delay %08x"
+disable ecc_mem_readl_mfsr(uint32_t ret) "Read memory fault status %08x"
+disable ecc_mem_readl_vcr(uint32_t ret) "Read slot configuration %08x"
+disable ecc_mem_readl_mfar0(uint32_t ret) "Read memory fault address 0 %08x"
+disable ecc_mem_readl_mfar1(uint32_t ret) "Read memory fault address 1 %08x"
+disable ecc_mem_readl_dr(uint32_t ret) "Read diagnostic %08x"
+disable ecc_mem_readl_ecr0(uint32_t ret) "Read event count 1 %08x"
+disable ecc_mem_readl_ecr1(uint32_t ret) "Read event count 2 %08x"
+disable ecc_diag_mem_writeb(uint64_t addr, uint32_t val) "Write diagnostic %"PRId64" = %02x"
+disable ecc_diag_mem_readb(uint64_t addr, uint32_t ret) "Read diagnostic %"PRId64"= %02x"
+
+# hw/lance.c
+disable lance_mem_readw(uint64_t addr, uint32_t ret) "addr=%"PRIx64"val=0x%04x"
+disable lance_mem_writew(uint64_t addr, uint32_t val) "addr=%"PRIx64"val=0x%04x"
+
+# hw/slavio_intctl.c
+disable slavio_intctl_mem_readl(uint32_t cpu, uint64_t addr, uint32_t ret) "read cpu %d reg 0x%"PRIx64" = %x"
+disable slavio_intctl_mem_writel(uint32_t cpu, uint64_t addr, uint32_t val) "write cpu %d reg 0x%"PRIx64" = %x"
+disable slavio_intctl_mem_writel_clear(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Cleared cpu %d irq mask %x, curmask %x"
+disable slavio_intctl_mem_writel_set(uint32_t cpu, uint32_t val, uint32_t intreg_pending) "Set cpu %d irq mask %x, curmask %x"
+disable slavio_intctlm_mem_readl(uint64_t addr, uint32_t ret) "read system reg 0x%"PRIx64" = %x"
+disable slavio_intctlm_mem_writel(uint64_t addr, uint32_t val) "write system reg 0x%"PRIx64" = %x"
+disable slavio_intctlm_mem_writel_enable(uint32_t val, uint32_t intregm_disabled) "Enabled master irq mask %x, curmask %x"
+disable slavio_intctlm_mem_writel_disable(uint32_t val, uint32_t intregm_disabled) "Disabled master irq mask %x, curmask %x"
+disable slavio_intctlm_mem_writel_target(uint32_t cpu) "Set master irq cpu %d"
+disable slavio_check_interrupts(uint32_t pending, uint32_t intregm_disabled) "pending %x disabled %x"
+disable slavio_set_irq(uint32_t target_cpu, int irq, uint32_t pil, int level) "Set cpu %d irq %d -> pil %d level %d"
+disable slavio_set_timer_irq_cpu(int cpu, int level) "Set cpu %d local timer level %d"
+
+# hw/slavio_misc.c
+disable slavio_misc_update_irq_raise(void) "Raise IRQ"
+disable slavio_misc_update_irq_lower(void) "Lower IRQ"
+disable slavio_set_power_fail(int power_failing, uint8_t config) "Power fail: %d, config: %d"
+disable slavio_cfg_mem_writeb(uint32_t val) "Write config %02x"
+disable slavio_cfg_mem_readb(uint32_t ret) "Read config %02x"
+disable slavio_diag_mem_writeb(uint32_t val) "Write diag %02x"
+disable slavio_diag_mem_readb(uint32_t ret) "Read diag %02x"
+disable slavio_mdm_mem_writeb(uint32_t val) "Write modem control %02x"
+disable slavio_mdm_mem_readb(uint32_t ret) "Read modem control %02x"
+disable slavio_aux1_mem_writeb(uint32_t val) "Write aux1 %02x"
+disable slavio_aux1_mem_readb(uint32_t ret) "Read aux1 %02x"
+disable slavio_aux2_mem_writeb(uint32_t val) "Write aux2 %02x"
+disable slavio_aux2_mem_readb(uint32_t ret) "Read aux2 %02x"
+disable apc_mem_writeb(uint32_t val) "Write power management %02x"
+disable apc_mem_readb(uint32_t ret) "Read power management %02x"
+disable slavio_sysctrl_mem_writel(uint32_t val) "Write system control %08x"
+disable slavio_sysctrl_mem_readl(uint32_t ret) "Read system control %08x"
+disable slavio_led_mem_writew(uint32_t val) "Write diagnostic LED %04x"
+disable slavio_led_mem_readw(uint32_t ret) "Read diagnostic LED %04x"
+
+# hw/slavio_timer.c
+disable slavio_timer_get_out(uint64_t limit, uint32_t counthigh, uint32_t count) "limit %"PRIx64" count %x%08x"
+disable slavio_timer_irq(uint32_t counthigh, uint32_t count) "callback: count %x%08x"
+disable slavio_timer_mem_readl_invalid(uint64_t addr) "invalid read address %"PRIx64""
+disable slavio_timer_mem_readl(uint64_t addr, uint32_t ret) "read %"PRIx64" = %08x"
+disable slavio_timer_mem_writel(uint64_t addr, uint32_t val) "write %"PRIx64" = %08x"
+disable slavio_timer_mem_writel_limit(unsigned int timer_index, uint64_t count) "processor %d user timer set to %016"PRIx64""
+disable slavio_timer_mem_writel_counter_invalid(void) "not user timer"
+disable slavio_timer_mem_writel_status_start(unsigned int timer_index) "processor %d user timer started"
+disable slavio_timer_mem_writel_status_stop(unsigned int timer_index) "processor %d user timer stopped"
+disable slavio_timer_mem_writel_mode_user(unsigned int timer_index) "processor %d changed from counter to user timer"
+disable slavio_timer_mem_writel_mode_counter(unsigned int timer_index) "processor %d changed from user timer to counter"
+disable slavio_timer_mem_writel_mode_invalid(void) "not system timer"
+disable slavio_timer_mem_writel_invalid(uint64_t addr) "invalid write address %"PRIx64""
+
+# hw/sparc32_dma.c
+disable ledma_memory_read(uint64_t addr) "DMA read addr 0x%"PRIx64""
+disable ledma_memory_write(uint64_t addr) "DMA write addr 0x%"PRIx64""
+disable sparc32_dma_set_irq_raise(void) "Raise IRQ"
+disable sparc32_dma_set_irq_lower(void) "Lower IRQ"
+disable espdma_memory_read(uint32_t addr) "DMA read addr 0x%08x"
+disable espdma_memory_write(uint32_t addr) "DMA write addr 0x%08x"
+disable sparc32_dma_mem_readl(uint64_t addr, uint32_t ret) "read dmareg %"PRIx64": 0x%08x"
+disable sparc32_dma_mem_writel(uint64_t addr, uint32_t old, uint32_t val) "write dmareg %"PRIx64": 0x%08x -> 0x%08x"
+disable sparc32_dma_enable_raise(void) "Raise DMA enable"
+disable sparc32_dma_enable_lower(void) "Lower DMA enable"
+
+# hw/sun4m.c
+disable sun4m_cpu_interrupt(unsigned int level) "Set CPU IRQ %d"
+disable sun4m_cpu_reset_interrupt(unsigned int level) "Reset CPU IRQ %d"
+disable sun4m_cpu_set_irq_raise(int level) "Raise CPU IRQ %d"
+disable sun4m_cpu_set_irq_lower(int level) "Lower CPU IRQ %d"
+
+# hw/sun4m_iommu.c
+disable sun4m_iommu_mem_readl(uint64_t addr, uint32_t ret) "read reg[%"PRIx64"] = %x"
+disable sun4m_iommu_mem_writel(uint64_t addr, uint32_t val) "write reg[%"PRIx64"] = %x"
+disable sun4m_iommu_mem_writel_ctrl(uint64_t iostart) "iostart = %"PRIx64""
+disable sun4m_iommu_mem_writel_tlbflush(uint32_t val) "tlb flush %x"
+disable sun4m_iommu_mem_writel_pgflush(uint32_t val) "page flush %x"
+disable sun4m_iommu_page_get_flags(uint64_t pa, uint64_t iopte, uint32_t ret) "get flags addr %"PRIx64" => pte %"PRIx64", *pte = %x"
+disable sun4m_iommu_translate_pa(uint64_t addr, uint64_t pa, uint32_t iopte) "xlate dva %"PRIx64" => pa %"PRIx64" iopte = %x"
+disable sun4m_iommu_bad_addr(uint64_t addr) "bad addr %"PRIx64""
commit b45e9c05dbacba8e992f0bffeca04c6379c3ad45
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue Oct 26 10:39:27 2010 +0200

    Remove unncessary includes
    
    No need to include stdlib.h for BSD as it is included by
    qemu-common.h, windows.h is handled by sysemu.h and osdep.c no longer
    needs malloc.h
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/osdep.c b/osdep.c
index 0d48561..327583b 100644
--- a/osdep.c
+++ b/osdep.c
@@ -44,14 +44,6 @@
 extern int madvise(caddr_t, size_t, int);
 #endif
 
-#ifdef _WIN32
-#include <windows.h>
-#elif defined(CONFIG_BSD)
-#include <stdlib.h>
-#else
-#include <malloc.h>
-#endif
-
 #include "qemu-common.h"
 #include "trace.h"
 #include "sysemu.h"
commit b152aa84d52882bb1846485a89baf13aa07c86bc
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue Oct 26 10:39:26 2010 +0200

    Consolidate oom_check() functions
    
    This consolidates the duplicated oom_check() functions, as well as
    splitting them into OS dependant versions to avoid the #ifdef
    grossness that was present in the old osdep.c version.
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile.target b/Makefile.target
index c48cbcc..91e6e74 100644
--- a/Makefile.target
+++ b/Makefile.target
@@ -88,7 +88,7 @@ $(call set-vpath, $(SRC_PATH)/linux-user:$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR
 QEMU_CFLAGS+=-I$(SRC_PATH)/linux-user -I$(SRC_PATH)/linux-user/$(TARGET_ABI_DIR)
 obj-y = main.o syscall.o strace.o mmap.o signal.o thunk.o \
       elfload.o linuxload.o uaccess.o gdbstub.o cpu-uname.o \
-      qemu-malloc.o
+      qemu-malloc.o $(oslib-obj-y)
 
 obj-$(TARGET_HAS_BFLT) += flatload.o
 
diff --git a/oslib-posix.c b/oslib-posix.c
index ad44b17..6e9b0c3 100644
--- a/oslib-posix.c
+++ b/oslib-posix.c
@@ -31,8 +31,7 @@
 #include "trace.h"
 #include "qemu_socket.h"
 
-#if !defined(_POSIX_C_SOURCE) || defined(__sun__)
-static void *oom_check(void *ptr)
+void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
@@ -40,7 +39,6 @@ static void *oom_check(void *ptr)
     }
     return ptr;
 }
-#endif
 
 void *qemu_memalign(size_t alignment, size_t size)
 {
@@ -54,9 +52,9 @@ void *qemu_memalign(size_t alignment, size_t size)
         abort();
     }
 #elif defined(CONFIG_BSD)
-    ptr = oom_check(valloc(size));
+    ptr = qemu_oom_check(valloc(size));
 #else
-    ptr = oom_check(memalign(alignment, size));
+    ptr = qemu_oom_check(memalign(alignment, size));
 #endif
     trace_qemu_memalign(alignment, size, ptr);
     return ptr;
diff --git a/oslib-win32.c b/oslib-win32.c
index e03c472..ab29eae 100644
--- a/oslib-win32.c
+++ b/oslib-win32.c
@@ -31,7 +31,7 @@
 #include "trace.h"
 #include "qemu_socket.h"
 
-static void *oom_check(void *ptr)
+void *qemu_oom_check(void *ptr)
 {
     if (ptr == NULL) {
         fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
@@ -47,7 +47,7 @@ void *qemu_memalign(size_t alignment, size_t size)
     if (!size) {
         abort();
     }
-    ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
+    ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
     trace_qemu_memalign(alignment, size, ptr);
     return ptr;
 }
@@ -62,7 +62,7 @@ void *qemu_vmalloc(size_t size)
     if (!size) {
         abort();
     }
-    ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
+    ptr = qemu_oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
     trace_qemu_vmalloc(size, ptr);
     return ptr;
 }
diff --git a/qemu-common.h b/qemu-common.h
index 5555226..5a18ca5 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -175,6 +175,7 @@ const char *path(const char *pathname);
 int ffs(int i);
 #endif
 
+void *qemu_oom_check(void *ptr);
 void *qemu_malloc(size_t size);
 void *qemu_realloc(void *ptr, size_t size);
 void *qemu_mallocz(size_t size);
diff --git a/qemu-malloc.c b/qemu-malloc.c
index ecffb67..28fb05a 100644
--- a/qemu-malloc.c
+++ b/qemu-malloc.c
@@ -25,14 +25,6 @@
 #include "trace.h"
 #include <stdlib.h>
 
-static void *oom_check(void *ptr)
-{
-    if (ptr == NULL) {
-        abort();
-    }
-    return ptr;
-}
-
 void qemu_free(void *ptr)
 {
     trace_qemu_free(ptr);
@@ -54,7 +46,7 @@ void *qemu_malloc(size_t size)
     if (!size && !allow_zero_malloc()) {
         abort();
     }
-    ptr = oom_check(malloc(size ? size : 1));
+    ptr = qemu_oom_check(malloc(size ? size : 1));
     trace_qemu_malloc(size, ptr);
     return ptr;
 }
@@ -65,7 +57,7 @@ void *qemu_realloc(void *ptr, size_t size)
     if (!size && !allow_zero_malloc()) {
         abort();
     }
-    newptr = oom_check(realloc(ptr, size ? size : 1));
+    newptr = qemu_oom_check(realloc(ptr, size ? size : 1));
     trace_qemu_realloc(ptr, size, newptr);
     return newptr;
 }
@@ -75,7 +67,7 @@ void *qemu_mallocz(size_t size)
     if (!size && !allow_zero_malloc()) {
         abort();
     }
-    return oom_check(calloc(1, size ? size : 1));
+    return qemu_oom_check(calloc(1, size ? size : 1));
 }
 
 char *qemu_strdup(const char *str)
commit bc4a957c46acd8f4b2f2ffe6b2f90512325924dd
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue Oct 26 10:39:25 2010 +0200

    Separate qemu_pidfile() into OS specific versions
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/os-posix.c b/os-posix.c
index 612b641..38c29d1 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -361,3 +361,24 @@ int qemu_eventfd(int fds[2])
 
     return qemu_pipe(fds);
 }
+
+int qemu_create_pidfile(const char *filename)
+{
+    char buffer[128];
+    int len;
+    int fd;
+
+    fd = qemu_open(filename, O_RDWR | O_CREAT, 0600);
+    if (fd == -1) {
+        return -1;
+    }
+    if (lockf(fd, F_TLOCK, 0) == -1) {
+        return -1;
+    }
+    len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
+    if (write(fd, buffer, len) != len) {
+        return -1;
+    }
+
+    return 0;
+}
diff --git a/os-win32.c b/os-win32.c
index 3c6f50f..566d5e9 100644
--- a/os-win32.c
+++ b/os-win32.c
@@ -240,3 +240,27 @@ void os_pidfile_error(void)
 {
     fprintf(stderr, "Could not acquire pid file: %s\n", strerror(errno));
 }
+
+int qemu_create_pidfile(const char *filename)
+{
+    char buffer[128];
+    int len;
+    HANDLE file;
+    OVERLAPPED overlap;
+    BOOL ret;
+    memset(&overlap, 0, sizeof(overlap));
+
+    file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
+		      OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
+
+    if (file == INVALID_HANDLE_VALUE) {
+        return -1;
+    }
+    len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
+    ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
+		      &overlap, NULL);
+    if (ret == 0) {
+        return -1;
+    }
+    return 0;
+}
diff --git a/osdep.c b/osdep.c
index b1664ac..0d48561 100644
--- a/osdep.c
+++ b/osdep.c
@@ -73,44 +73,6 @@ int qemu_madvise(void *addr, size_t len, int advice)
 #endif
 }
 
-int qemu_create_pidfile(const char *filename)
-{
-    char buffer[128];
-    int len;
-#ifndef _WIN32
-    int fd;
-
-    fd = qemu_open(filename, O_RDWR | O_CREAT, 0600);
-    if (fd == -1)
-        return -1;
-
-    if (lockf(fd, F_TLOCK, 0) == -1)
-        return -1;
-
-    len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
-    if (write(fd, buffer, len) != len)
-        return -1;
-#else
-    HANDLE file;
-    OVERLAPPED overlap;
-    BOOL ret;
-    memset(&overlap, 0, sizeof(overlap));
-
-    file = CreateFile(filename, GENERIC_WRITE, FILE_SHARE_READ, NULL,
-		      OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
-
-    if (file == INVALID_HANDLE_VALUE)
-      return -1;
-
-    len = snprintf(buffer, sizeof(buffer), "%ld\n", (long)getpid());
-    ret = WriteFileEx(file, (LPCVOID)buffer, (DWORD)len,
-		      &overlap, NULL);
-    if (ret == 0)
-      return -1;
-#endif
-    return 0;
-}
-
 
 /*
  * Opens a file with FD_CLOEXEC set
commit ff753bb9a60780e7af93288ac55bf1277a30cff7
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue Oct 26 10:39:24 2010 +0200

    Do not redefine reserved key-words TRUE/FALSE
    
    TRUE/FALSE are generally reserved keywords and shouldn't be defined in
    a driver like this. Rename the macros to SDP_TRUE and SDP_FALSE
    respectively.
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/bt-sdp.c b/hw/bt-sdp.c
index cc0bf2f..cdf2d95 100644
--- a/hw/bt-sdp.c
+++ b/hw/bt-sdp.c
@@ -786,11 +786,11 @@ static void sdp_service_db_build(struct bt_l2cap_sdp_state_s *sdp,
         .type       = SDP_DTYPE_UUID | SDP_DSIZE_16,	\
         .value.uint = val,				\
     },
-#define TRUE	{				\
+#define SDP_TRUE	{				\
         .type       = SDP_DTYPE_BOOL | SDP_DSIZE_1,	\
         .value.uint = 1,				\
     },
-#define FALSE	{				\
+#define SDP_FALSE	{				\
         .type       = SDP_DTYPE_BOOL | SDP_DSIZE_1,	\
         .value.uint = 0,				\
     },
@@ -842,8 +842,8 @@ SERVICE(hid,
     /* TODO: extract from l2cap_device->device.class[0] */
     ATTRIBUTE(DEVICE_SUBCLASS,		UINT8(0x40))
     ATTRIBUTE(COUNTRY_CODE,		UINT8(0x15))
-    ATTRIBUTE(VIRTUAL_CABLE,		TRUE)
-    ATTRIBUTE(RECONNECT_INITIATE,	FALSE)
+    ATTRIBUTE(VIRTUAL_CABLE,		SDP_TRUE)
+    ATTRIBUTE(RECONNECT_INITIATE,	SDP_FALSE)
     /* TODO: extract from hid->usbdev->report_desc */
     ATTRIBUTE(DESCRIPTOR_LIST,		LIST(
         LIST(UINT8(0x22) ARRAY(
@@ -883,12 +883,12 @@ SERVICE(hid,
     ATTRIBUTE(LANG_ID_BASE_LIST,	LIST(
         LIST(UINT16(0x0409) UINT16(0x0100))
     ))
-    ATTRIBUTE(SDP_DISABLE,		FALSE)
-    ATTRIBUTE(BATTERY_POWER,		TRUE)
-    ATTRIBUTE(REMOTE_WAKEUP,		TRUE)
-    ATTRIBUTE(BOOT_DEVICE,		TRUE)	/* XXX: untested */
+    ATTRIBUTE(SDP_DISABLE,		SDP_FALSE)
+    ATTRIBUTE(BATTERY_POWER,		SDP_TRUE)
+    ATTRIBUTE(REMOTE_WAKEUP,		SDP_TRUE)
+    ATTRIBUTE(BOOT_DEVICE,		SDP_TRUE)	/* XXX: untested */
     ATTRIBUTE(SUPERVISION_TIMEOUT,	UINT16(0x0c80))
-    ATTRIBUTE(NORMALLY_CONNECTABLE,	TRUE)
+    ATTRIBUTE(NORMALLY_CONNECTABLE,	SDP_TRUE)
     ATTRIBUTE(PROFILE_VERSION,		UINT16(0x0100))
 )
 
@@ -936,7 +936,7 @@ SERVICE(pnp,
     /* Profile specific */
     ATTRIBUTE(SPECIFICATION_ID, UINT16(0x0100))
     ATTRIBUTE(VERSION,         UINT16(0x0100))
-    ATTRIBUTE(PRIMARY_RECORD,  TRUE)
+    ATTRIBUTE(PRIMARY_RECORD,  SDP_TRUE)
 )
 
 static int bt_l2cap_sdp_new_ch(struct bt_l2cap_device_s *dev,
commit dc786bc9103801fac5b90511b0761255b4eab622
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue Oct 26 10:39:23 2010 +0200

    Move qemu_gettimeofday() to OS specific files
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/m68k-semi.c b/m68k-semi.c
index d16bc67..0371089 100644
--- a/m68k-semi.c
+++ b/m68k-semi.c
@@ -33,10 +33,10 @@
 #define SEMIHOSTING_HEAP_SIZE (128 * 1024 * 1024)
 #else
 #include "qemu-common.h"
-#include "sysemu.h"
 #include "gdbstub.h"
 #include "softmmu-semi.h"
 #endif
+#include "sysemu.h"
 
 #define HOSTED_EXIT  0
 #define HOSTED_INIT_SIM 1
diff --git a/osdep.c b/osdep.c
index cb12e5f..b1664ac 100644
--- a/osdep.c
+++ b/osdep.c
@@ -111,37 +111,6 @@ int qemu_create_pidfile(const char *filename)
     return 0;
 }
 
-#ifdef _WIN32
-
-/* mingw32 needs ffs for compilations without optimization. */
-int ffs(int i)
-{
-    /* Use gcc's builtin ffs. */
-    return __builtin_ffs(i);
-}
-
-/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
-#define _W32_FT_OFFSET (116444736000000000ULL)
-
-int qemu_gettimeofday(qemu_timeval *tp)
-{
-  union {
-    unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
-    FILETIME ft;
-  }  _now;
-
-  if(tp)
-    {
-      GetSystemTimeAsFileTime (&_now.ft);
-      tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
-      tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
-    }
-  /* Always return 0 as per Open Group Base Specifications Issue 6.
-     Do not set errno on error.  */
-  return 0;
-}
-#endif /* _WIN32 */
-
 
 /*
  * Opens a file with FD_CLOEXEC set
diff --git a/osdep.h b/osdep.h
index 6716281..8bd30d7 100644
--- a/osdep.h
+++ b/osdep.h
@@ -127,19 +127,4 @@ int qemu_madvise(void *addr, size_t len, int advice);
 
 int qemu_create_pidfile(const char *filename);
 
-#ifdef _WIN32
-int ffs(int i);
-
-int setenv(const char *name, const char *value, int overwrite);
-
-typedef struct {
-    long tv_sec;
-    long tv_usec;
-} qemu_timeval;
-int qemu_gettimeofday(qemu_timeval *tp);
-#else
-typedef struct timeval qemu_timeval;
-#define qemu_gettimeofday(tp) gettimeofday(tp, NULL);
-#endif /* !_WIN32 */
-
 #endif
diff --git a/oslib-win32.c b/oslib-win32.c
index 1ddd857..e03c472 100644
--- a/oslib-win32.c
+++ b/oslib-win32.c
@@ -92,3 +92,30 @@ int inet_aton(const char *cp, struct in_addr *ia)
 void qemu_set_cloexec(int fd)
 {
 }
+
+/* mingw32 needs ffs for compilations without optimization. */
+int ffs(int i)
+{
+    /* Use gcc's builtin ffs. */
+    return __builtin_ffs(i);
+}
+
+/* Offset between 1/1/1601 and 1/1/1970 in 100 nanosec units */
+#define _W32_FT_OFFSET (116444736000000000ULL)
+
+int qemu_gettimeofday(qemu_timeval *tp)
+{
+  union {
+    unsigned long long ns100; /*time since 1 Jan 1601 in 100ns units */
+    FILETIME ft;
+  }  _now;
+
+  if(tp) {
+      GetSystemTimeAsFileTime (&_now.ft);
+      tp->tv_usec=(long)((_now.ns100 / 10ULL) % 1000000ULL );
+      tp->tv_sec= (long)((_now.ns100 - _W32_FT_OFFSET) / 10000000ULL);
+  }
+  /* Always return 0 as per Open Group Base Specifications Issue 6.
+     Do not set errno on error.  */
+  return 0;
+}
diff --git a/posix-aio-compat.c b/posix-aio-compat.c
index 7b862b5..fa5494d 100644
--- a/posix-aio-compat.c
+++ b/posix-aio-compat.c
@@ -24,6 +24,7 @@
 
 #include "qemu-queue.h"
 #include "osdep.h"
+#include "sysemu.h"
 #include "qemu-common.h"
 #include "trace.h"
 #include "block_int.h"
diff --git a/qemu-common.h b/qemu-common.h
index 3496e4f..5555226 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -170,6 +170,11 @@ const char *path(const char *pathname);
 #define qemu_isascii(c)		isascii((unsigned char)(c))
 #define qemu_toascii(c)		toascii((unsigned char)(c))
 
+#ifdef _WIN32
+/* ffs() in oslib-win32.c for WIN32, strings.h for the rest of the world */
+int ffs(int i);
+#endif
+
 void *qemu_malloc(size_t size);
 void *qemu_realloc(void *ptr, size_t size);
 void *qemu_mallocz(size_t size);
diff --git a/qemu-img.c b/qemu-img.c
index 2864cb8..fa77ac0 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -24,6 +24,7 @@
 #include "qemu-common.h"
 #include "qemu-option.h"
 #include "osdep.h"
+#include "sysemu.h"
 #include "block_int.h"
 #include <stdio.h>
 
diff --git a/qemu-os-posix.h b/qemu-os-posix.h
index ed5c058..353f878 100644
--- a/qemu-os-posix.h
+++ b/qemu-os-posix.h
@@ -36,4 +36,7 @@ void os_setup_signal_handling(void);
 void os_daemonize(void);
 void os_setup_post(void);
 
+typedef struct timeval qemu_timeval;
+#define qemu_gettimeofday(tp) gettimeofday(tp, NULL)
+
 #endif
diff --git a/qemu-os-win32.h b/qemu-os-win32.h
index c63778d..1a07e5e 100644
--- a/qemu-os-win32.h
+++ b/qemu-os-win32.h
@@ -52,4 +52,12 @@ static inline void os_set_proc_name(const char *dummy) {}
 # define EPROTONOSUPPORT EINVAL
 #endif
 
+int setenv(const char *name, const char *value, int overwrite);
+
+typedef struct {
+    long tv_sec;
+    long tv_usec;
+} qemu_timeval;
+int qemu_gettimeofday(qemu_timeval *tp);
+
 #endif
diff --git a/qemu-tool.c b/qemu-tool.c
index 9ccca65..392e1c9 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -15,6 +15,7 @@
 #include "monitor.h"
 #include "qemu-timer.h"
 #include "qemu-log.h"
+#include "sysemu.h"
 
 #include <sys/time.h>
 
commit 949d31e665e9847b2a8f24a916abd96e79353535
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue Oct 26 10:39:22 2010 +0200

    We only support eventfd under POSIX, move qemu_eventfd() to os-posix.c
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/os-posix.c b/os-posix.c
index 6321e99..612b641 100644
--- a/os-posix.c
+++ b/os-posix.c
@@ -43,6 +43,10 @@
 #include <sys/prctl.h>
 #endif
 
+#ifdef CONFIG_EVENTFD
+#include <sys/eventfd.h>
+#endif
+
 static struct passwd *user_pwd;
 static const char *chroot_dir;
 static int daemonize;
@@ -329,3 +333,31 @@ void os_set_line_buffering(void)
 {
     setvbuf(stdout, NULL, _IOLBF, 0);
 }
+
+/*
+ * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
+ */
+int qemu_eventfd(int fds[2])
+{
+#ifdef CONFIG_EVENTFD
+    int ret;
+
+    ret = eventfd(0, 0);
+    if (ret >= 0) {
+        fds[0] = ret;
+        qemu_set_cloexec(ret);
+        if ((fds[1] = dup(ret)) == -1) {
+            close(ret);
+            return -1;
+        }
+        qemu_set_cloexec(fds[1]);
+        return 0;
+    }
+
+    if (errno != ENOSYS) {
+        return -1;
+    }
+#endif
+
+    return qemu_pipe(fds);
+}
diff --git a/osdep.c b/osdep.c
index 926c8ad..cb12e5f 100644
--- a/osdep.c
+++ b/osdep.c
@@ -44,10 +44,6 @@
 extern int madvise(caddr_t, size_t, int);
 #endif
 
-#ifdef CONFIG_EVENTFD
-#include <sys/eventfd.h>
-#endif
-
 #ifdef _WIN32
 #include <windows.h>
 #elif defined(CONFIG_BSD)
@@ -207,36 +203,6 @@ ssize_t qemu_write_full(int fd, const void *buf, size_t count)
     return total;
 }
 
-#ifndef _WIN32
-/*
- * Creates an eventfd that looks like a pipe and has EFD_CLOEXEC set.
- */
-int qemu_eventfd(int fds[2])
-{
-#ifdef CONFIG_EVENTFD
-    int ret;
-
-    ret = eventfd(0, 0);
-    if (ret >= 0) {
-        fds[0] = ret;
-        qemu_set_cloexec(ret);
-        if ((fds[1] = dup(ret)) == -1) {
-            close(ret);
-            return -1;
-        }
-        qemu_set_cloexec(fds[1]);
-        return 0;
-    }
-
-    if (errno != ENOSYS) {
-        return -1;
-    }
-#endif
-
-    return qemu_pipe(fds);
-}
-#endif
-
 /*
  * Opens a socket with FD_CLOEXEC set
  */
commit 70e72ce45e1f06415b5ec28439c2a87a72e5aad3
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue Oct 26 10:39:21 2010 +0200

    qemu_pipe() is used only by POSIX code, so move to oslib-posix.c
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/osdep.c b/osdep.c
index 902fce9..926c8ad 100644
--- a/osdep.c
+++ b/osdep.c
@@ -235,28 +235,6 @@ int qemu_eventfd(int fds[2])
 
     return qemu_pipe(fds);
 }
-
-/*
- * Creates a pipe with FD_CLOEXEC set on both file descriptors
- */
-int qemu_pipe(int pipefd[2])
-{
-    int ret;
-
-#ifdef CONFIG_PIPE2
-    ret = pipe2(pipefd, O_CLOEXEC);
-    if (ret != -1 || errno != ENOSYS) {
-        return ret;
-    }
-#endif
-    ret = pipe(pipefd);
-    if (ret == 0) {
-        qemu_set_cloexec(pipefd[0]);
-        qemu_set_cloexec(pipefd[1]);
-    }
-
-    return ret;
-}
 #endif
 
 /*
diff --git a/oslib-posix.c b/oslib-posix.c
index aebe3ac..ad44b17 100644
--- a/oslib-posix.c
+++ b/oslib-posix.c
@@ -87,3 +87,25 @@ void qemu_set_cloexec(int fd)
     f = fcntl(fd, F_GETFD);
     fcntl(fd, F_SETFD, f | FD_CLOEXEC);
 }
+
+/*
+ * Creates a pipe with FD_CLOEXEC set on both file descriptors
+ */
+int qemu_pipe(int pipefd[2])
+{
+    int ret;
+
+#ifdef CONFIG_PIPE2
+    ret = pipe2(pipefd, O_CLOEXEC);
+    if (ret != -1 || errno != ENOSYS) {
+        return ret;
+    }
+#endif
+    ret = pipe(pipefd);
+    if (ret == 0) {
+        qemu_set_cloexec(pipefd[0]);
+        qemu_set_cloexec(pipefd[1]);
+    }
+
+    return ret;
+}
commit 9549e764bdc24b085cb1bb87400bf6ef79ae9eb1
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue Oct 26 10:39:20 2010 +0200

    Move osdep socket code to oslib-{posix,win32}.c
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/osdep.c b/osdep.c
index 581768a..902fce9 100644
--- a/osdep.c
+++ b/osdep.c
@@ -147,44 +147,6 @@ int qemu_gettimeofday(qemu_timeval *tp)
 #endif /* _WIN32 */
 
 
-#ifdef _WIN32
-void socket_set_nonblock(int fd)
-{
-    unsigned long opt = 1;
-    ioctlsocket(fd, FIONBIO, &opt);
-}
-
-int inet_aton(const char *cp, struct in_addr *ia)
-{
-    uint32_t addr = inet_addr(cp);
-    if (addr == 0xffffffff)
-	return 0;
-    ia->s_addr = addr;
-    return 1;
-}
-
-void qemu_set_cloexec(int fd)
-{
-}
-
-#else
-
-void socket_set_nonblock(int fd)
-{
-    int f;
-    f = fcntl(fd, F_GETFL);
-    fcntl(fd, F_SETFL, f | O_NONBLOCK);
-}
-
-void qemu_set_cloexec(int fd)
-{
-    int f;
-    f = fcntl(fd, F_GETFD);
-    fcntl(fd, F_SETFD, f | FD_CLOEXEC);
-}
-
-#endif
-
 /*
  * Opens a file with FD_CLOEXEC set
  */
diff --git a/oslib-posix.c b/oslib-posix.c
index df97304..aebe3ac 100644
--- a/oslib-posix.c
+++ b/oslib-posix.c
@@ -29,6 +29,7 @@
 #include "config-host.h"
 #include "sysemu.h"
 #include "trace.h"
+#include "qemu_socket.h"
 
 #if !defined(_POSIX_C_SOURCE) || defined(__sun__)
 static void *oom_check(void *ptr)
@@ -72,3 +73,17 @@ void qemu_vfree(void *ptr)
     trace_qemu_vfree(ptr);
     free(ptr);
 }
+
+void socket_set_nonblock(int fd)
+{
+    int f;
+    f = fcntl(fd, F_GETFL);
+    fcntl(fd, F_SETFL, f | O_NONBLOCK);
+}
+
+void qemu_set_cloexec(int fd)
+{
+    int f;
+    f = fcntl(fd, F_GETFD);
+    fcntl(fd, F_SETFD, f | FD_CLOEXEC);
+}
diff --git a/oslib-win32.c b/oslib-win32.c
index 3b5245d..1ddd857 100644
--- a/oslib-win32.c
+++ b/oslib-win32.c
@@ -29,6 +29,7 @@
 #include "config-host.h"
 #include "sysemu.h"
 #include "trace.h"
+#include "qemu_socket.h"
 
 static void *oom_check(void *ptr)
 {
@@ -71,3 +72,23 @@ void qemu_vfree(void *ptr)
     trace_qemu_vfree(ptr);
     VirtualFree(ptr, 0, MEM_RELEASE);
 }
+
+void socket_set_nonblock(int fd)
+{
+    unsigned long opt = 1;
+    ioctlsocket(fd, FIONBIO, &opt);
+}
+
+int inet_aton(const char *cp, struct in_addr *ia)
+{
+    uint32_t addr = inet_addr(cp);
+    if (addr == 0xffffffff) {
+	return 0;
+    }
+    ia->s_addr = addr;
+    return 1;
+}
+
+void qemu_set_cloexec(int fd)
+{
+}
commit c1b0b93b06ab026ef45ae02d0ee7557741910637
Author: Jes Sorensen <Jes.Sorensen at redhat.com>
Date:   Tue Oct 26 10:39:19 2010 +0200

    Move QEMU OS dependant library functions to OS specific files
    
    This moves library functions used by both QEMU and the QEMU tools,
    such as qemu-img, qemu-nbd etc. from osdep.c to oslib-{posix,win32}.c
    
    In addition it introduces oslib-obj.y to the Makefile set to be
    included by the various targets, instead of relying on these library
    functions magically getting included via block-obj-y.
    
    Signed-off-by: Jes Sorensen <Jes.Sorensen at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile b/Makefile
index 3df202c..071baa3 100644
--- a/Makefile
+++ b/Makefile
@@ -129,11 +129,11 @@ version-obj-$(CONFIG_WIN32) += version.o
 qemu-img.o: qemu-img-cmds.h
 qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
 
-qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
+qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
-qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
+qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
-qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
+qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(oslib-obj-y) $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
 qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
 	$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@,"  GEN   $@")
diff --git a/Makefile.objs b/Makefile.objs
index f07fb01..c88e82d 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -5,10 +5,16 @@ qobject-obj-y += qjson.o json-lexer.o json-streamer.o json-parser.o
 qobject-obj-y += qerror.o
 
 #######################################################################
+# oslib-obj-y is code depending on the OS (win32 vs posix)
+oslib-obj-y = osdep.o
+oslib-obj-$(CONFIG_WIN32) += oslib-win32.o
+oslib-obj-$(CONFIG_POSIX) += oslib-posix.o
+
+#######################################################################
 # block-obj-y is code used by both qemu system emulation and qemu-img
 
 block-obj-y = cutils.o cache-utils.o qemu-malloc.o qemu-option.o module.o
-block-obj-y += nbd.o block.o aio.o aes.o osdep.o qemu-config.o
+block-obj-y += nbd.o block.o aio.o aes.o qemu-config.o
 block-obj-$(CONFIG_POSIX) += posix-aio-compat.o
 block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
 
@@ -50,6 +56,7 @@ common-obj-y += $(net-obj-y)
 common-obj-y += $(qobject-obj-y)
 common-obj-$(CONFIG_LINUX) += $(fsdev-obj-$(CONFIG_LINUX))
 common-obj-y += readline.o console.o cursor.o async.o qemu-error.o
+common-obj-y += $(oslib-obj-y)
 common-obj-$(CONFIG_WIN32) += os-win32.o
 common-obj-$(CONFIG_POSIX) += os-posix.o
 
diff --git a/osdep.c b/osdep.c
index 2e05b21..581768a 100644
--- a/osdep.c
+++ b/osdep.c
@@ -61,91 +61,6 @@ extern int madvise(caddr_t, size_t, int);
 #include "sysemu.h"
 #include "qemu_socket.h"
 
-#if !defined(_POSIX_C_SOURCE) || defined(_WIN32) || defined(__sun__)
-static void *oom_check(void *ptr)
-{
-    if (ptr == NULL) {
-#if defined(_WIN32)
-        fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
-#else
-        fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
-#endif
-        abort();
-    }
-    return ptr;
-}
-#endif
-
-#if defined(_WIN32)
-void *qemu_memalign(size_t alignment, size_t size)
-{
-    void *ptr;
-
-    if (!size) {
-        abort();
-    }
-    ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
-    trace_qemu_memalign(alignment, size, ptr);
-    return ptr;
-}
-
-void *qemu_vmalloc(size_t size)
-{
-    void *ptr;
-
-    /* FIXME: this is not exactly optimal solution since VirtualAlloc
-       has 64Kb granularity, but at least it guarantees us that the
-       memory is page aligned. */
-    if (!size) {
-        abort();
-    }
-    ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
-    trace_qemu_vmalloc(size, ptr);
-    return ptr;
-}
-
-void qemu_vfree(void *ptr)
-{
-    trace_qemu_vfree(ptr);
-    VirtualFree(ptr, 0, MEM_RELEASE);
-}
-
-#else
-
-void *qemu_memalign(size_t alignment, size_t size)
-{
-    void *ptr;
-#if defined(_POSIX_C_SOURCE) && !defined(__sun__)
-    int ret;
-    ret = posix_memalign(&ptr, alignment, size);
-    if (ret != 0) {
-        fprintf(stderr, "Failed to allocate %zu B: %s\n",
-                size, strerror(ret));
-        abort();
-    }
-#elif defined(CONFIG_BSD)
-    ptr = oom_check(valloc(size));
-#else
-    ptr = oom_check(memalign(alignment, size));
-#endif
-    trace_qemu_memalign(alignment, size, ptr);
-    return ptr;
-}
-
-/* alloc shared memory pages */
-void *qemu_vmalloc(size_t size)
-{
-    return qemu_memalign(getpagesize(), size);
-}
-
-void qemu_vfree(void *ptr)
-{
-    trace_qemu_vfree(ptr);
-    free(ptr);
-}
-
-#endif
-
 int qemu_madvise(void *addr, size_t len, int advice)
 {
     if (advice == QEMU_MADV_INVALID) {
diff --git a/oslib-posix.c b/oslib-posix.c
new file mode 100644
index 0000000..df97304
--- /dev/null
+++ b/oslib-posix.c
@@ -0,0 +1,74 @@
+/*
+ * os-posix-lib.c
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010 Red Hat, Inc.
+ *
+ * QEMU library functions on POSIX which are shared between QEMU and
+ * the QEMU tools.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+#include "config-host.h"
+#include "sysemu.h"
+#include "trace.h"
+
+#if !defined(_POSIX_C_SOURCE) || defined(__sun__)
+static void *oom_check(void *ptr)
+{
+    if (ptr == NULL) {
+        fprintf(stderr, "Failed to allocate memory: %s\n", strerror(errno));
+        abort();
+    }
+    return ptr;
+}
+#endif
+
+void *qemu_memalign(size_t alignment, size_t size)
+{
+    void *ptr;
+#if defined(_POSIX_C_SOURCE) && !defined(__sun__)
+    int ret;
+    ret = posix_memalign(&ptr, alignment, size);
+    if (ret != 0) {
+        fprintf(stderr, "Failed to allocate %zu B: %s\n",
+                size, strerror(ret));
+        abort();
+    }
+#elif defined(CONFIG_BSD)
+    ptr = oom_check(valloc(size));
+#else
+    ptr = oom_check(memalign(alignment, size));
+#endif
+    trace_qemu_memalign(alignment, size, ptr);
+    return ptr;
+}
+
+/* alloc shared memory pages */
+void *qemu_vmalloc(size_t size)
+{
+    return qemu_memalign(getpagesize(), size);
+}
+
+void qemu_vfree(void *ptr)
+{
+    trace_qemu_vfree(ptr);
+    free(ptr);
+}
diff --git a/oslib-win32.c b/oslib-win32.c
new file mode 100644
index 0000000..3b5245d
--- /dev/null
+++ b/oslib-win32.c
@@ -0,0 +1,73 @@
+/*
+ * os-win32.c
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ * Copyright (c) 2010 Red Hat, Inc.
+ *
+ * QEMU library functions for win32 which are shared between QEMU and
+ * the QEMU tools.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include <windows.h>
+#include "config-host.h"
+#include "sysemu.h"
+#include "trace.h"
+
+static void *oom_check(void *ptr)
+{
+    if (ptr == NULL) {
+        fprintf(stderr, "Failed to allocate memory: %lu\n", GetLastError());
+        abort();
+    }
+    return ptr;
+}
+
+void *qemu_memalign(size_t alignment, size_t size)
+{
+    void *ptr;
+
+    if (!size) {
+        abort();
+    }
+    ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
+    trace_qemu_memalign(alignment, size, ptr);
+    return ptr;
+}
+
+void *qemu_vmalloc(size_t size)
+{
+    void *ptr;
+
+    /* FIXME: this is not exactly optimal solution since VirtualAlloc
+       has 64Kb granularity, but at least it guarantees us that the
+       memory is page aligned. */
+    if (!size) {
+        abort();
+    }
+    ptr = oom_check(VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_READWRITE));
+    trace_qemu_vmalloc(size, ptr);
+    return ptr;
+}
+
+void qemu_vfree(void *ptr)
+{
+    trace_qemu_vfree(ptr);
+    VirtualFree(ptr, 0, MEM_RELEASE);
+}
commit 9a78eead0c74333a394c0f7bbfc4423ac746fcd5
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Oct 22 23:03:33 2010 +0200

    target-xxx: Use fprintf_function (format checking)
    
    fprintf_function uses format checking with GCC_FMT_ATTR.
    
    Format errors were fixed in
    * target-i386/helper.c
    * target-mips/translate.c
    * target-ppc/translate.c
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-all.h b/cpu-all.h
index ba9d766..30ae17d 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -765,12 +765,10 @@ int page_check_range(target_ulong start, target_ulong len, int flags);
 CPUState *cpu_copy(CPUState *env);
 CPUState *qemu_get_cpu(int cpu);
 
-void cpu_dump_state(CPUState *env, FILE *f,
-                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags);
-void cpu_dump_statistics (CPUState *env, FILE *f,
-                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
-                          int flags);
+void cpu_dump_statistics(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
+                         int flags);
 
 void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
     GCC_FMT_ATTR(2, 3);
diff --git a/cpus.c b/cpus.c
index 36a6d1f..91a0fb1 100644
--- a/cpus.c
+++ b/cpus.c
@@ -978,8 +978,7 @@ int64_t cpu_get_icount(void)
     return qemu_icount_bias + (icount << icount_time_shift);
 }
 
-void list_cpus(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
-               const char *optarg)
+void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 {
     /* XXX: implement xxx_cpu_list for targets that still miss it */
 #if defined(cpu_list_id)
diff --git a/cpus.h b/cpus.h
index af267ea..bf4d9bb 100644
--- a/cpus.h
+++ b/cpus.h
@@ -16,7 +16,6 @@ void vm_state_notify(int running, int reason);
 bool cpu_exec_all(void);
 void set_numa_modes(void);
 void set_cpu_log(const char *optarg);
-void list_cpus(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
-               const char *optarg);
+void list_cpus(FILE *f, fprintf_function cpu_fprintf, const char *optarg);
 
 #endif
diff --git a/target-alpha/helper.c b/target-alpha/helper.c
index b6d2160..3ba4478 100644
--- a/target-alpha/helper.c
+++ b/target-alpha/helper.c
@@ -537,8 +537,7 @@ void do_interrupt (CPUState *env)
 }
 #endif
 
-void cpu_dump_state (CPUState *env, FILE *f,
-                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                      int flags)
 {
     static const char *linux_reg_names[] = {
diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 39c4a0e..b87c605 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -25,6 +25,8 @@
 
 #define CPUState struct CPUARMState
 
+#include "config.h"
+#include "qemu-common.h"
 #include "cpu-defs.h"
 
 #include "softfloat.h"
@@ -353,7 +355,7 @@ static inline int arm_feature(CPUARMState *env, int feature)
     return (env->features & (1u << feature)) != 0;
 }
 
-void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
 /* Interface between CPU and Interrupt controller.  */
 void armv7m_nvic_set_pending(void *opaque, int irq);
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 2dd64d9..996d40d 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -348,7 +348,7 @@ static const struct arm_cpu_t arm_cpu_names[] = {
     { 0, NULL}
 };
 
-void arm_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void arm_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
     int i;
 
diff --git a/target-arm/translate.c b/target-arm/translate.c
index 6fcdd7e..99464ab 100644
--- a/target-arm/translate.c
+++ b/target-arm/translate.c
@@ -9262,8 +9262,7 @@ static const char *cpu_mode_names[16] = {
   "???", "???", "???", "und", "???", "???", "???", "sys"
 };
 
-void cpu_dump_state(CPUState *env, FILE *f,
-                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
     int i;
diff --git a/target-cris/cpu.h b/target-cris/cpu.h
index e1d48ed..d908775 100644
--- a/target-cris/cpu.h
+++ b/target-cris/cpu.h
@@ -263,6 +263,6 @@ static inline void cpu_get_tb_cpu_state(CPUState *env, target_ulong *pc,
 }
 
 #define cpu_list cris_cpu_list
-void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
 #endif
diff --git a/target-cris/translate.c b/target-cris/translate.c
index 8361369..4e4606c 100644
--- a/target-cris/translate.c
+++ b/target-cris/translate.c
@@ -3426,8 +3426,7 @@ void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state (CPUState *env, FILE *f,
-                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                      int flags)
 {
 	int i;
@@ -3480,7 +3479,7 @@ struct
 	{32, "crisv32"},
 };
 
-void cris_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void cris_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
     unsigned int i;
 
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 85ed30f..2440d65 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -20,6 +20,7 @@
 #define CPU_I386_H
 
 #include "config.h"
+#include "qemu-common.h"
 
 #ifdef TARGET_X86_64
 #define TARGET_LONG_BITS 64
@@ -756,8 +757,7 @@ typedef struct CPUX86State {
 CPUX86State *cpu_x86_init(const char *cpu_model);
 int cpu_x86_exec(CPUX86State *s);
 void cpu_x86_close(CPUX86State *s);
-void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
-                   const char *optarg);
+void x86_cpu_list (FILE *f, fprintf_function cpu_fprintf, const char *optarg);
 void x86_cpudef_setup(void);
 
 int cpu_get_pic_interrupt(CPUX86State *s);
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 0e0bf60..650a719 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -762,8 +762,7 @@ static void listflags(char *buf, int bufsize, uint32_t fbits,
  * -?dump    output all model (x86_def_t) data
  * -?cpuid   list all recognized cpuid flag names
  */
-void x86_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
-                  const char *optarg)
+void x86_cpu_list(FILE *f, fprintf_function cpu_fprintf, const char *optarg)
 {
     unsigned char model = !strcmp("?model", optarg);
     unsigned char dump = !strcmp("?dump", optarg);
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 4fff4a8..26ea1e5 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -169,8 +169,7 @@ static const char *cc_op_str[] = {
 };
 
 static void
-cpu_x86_dump_seg_cache(CPUState *env, FILE *f,
-                       int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+cpu_x86_dump_seg_cache(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                        const char *name, struct SegmentCache *sc)
 {
 #ifdef TARGET_X86_64
@@ -224,8 +223,7 @@ done:
     cpu_fprintf(f, "\n");
 }
 
-void cpu_dump_state(CPUState *env, FILE *f,
-                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
     int eflags, i, nb;
@@ -335,9 +333,11 @@ void cpu_dump_state(CPUState *env, FILE *f,
                     (uint32_t)env->cr[2],
                     (uint32_t)env->cr[3],
                     (uint32_t)env->cr[4]);
-        for(i = 0; i < 4; i++)
-            cpu_fprintf(f, "DR%d=%08x ", i, env->dr[i]);
-        cpu_fprintf(f, "\nDR6=%08x DR7=%08x\n", env->dr[6], env->dr[7]);
+        for(i = 0; i < 4; i++) {
+            cpu_fprintf(f, "DR%d=" TARGET_FMT_lx " ", i, env->dr[i]);
+        }
+        cpu_fprintf(f, "\nDR6=" TARGET_FMT_lx " DR7=" TARGET_FMT_lx "\n",
+                    env->dr[6], env->dr[7]);
     }
     if (flags & X86_DUMP_CCOP) {
         if ((unsigned)env->cc_op < CC_OP_NB)
diff --git a/target-m68k/cpu.h b/target-m68k/cpu.h
index 33c41b2..b025b66 100644
--- a/target-m68k/cpu.h
+++ b/target-m68k/cpu.h
@@ -24,6 +24,7 @@
 
 #define CPUState struct CPUM68KState
 
+#include "qemu-common.h"
 #include "cpu-defs.h"
 
 #include "softfloat.h"
@@ -198,7 +199,7 @@ static inline int m68k_feature(CPUM68KState *env, int feature)
     return (env->features & (1u << feature)) != 0;
 }
 
-void m68k_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 
 void register_m68k_insns (CPUM68KState *env);
 
diff --git a/target-m68k/helper.c b/target-m68k/helper.c
index b4ebb14..56de897 100644
--- a/target-m68k/helper.c
+++ b/target-m68k/helper.c
@@ -53,7 +53,7 @@ static m68k_def_t m68k_cpu_defs[] = {
     {NULL, 0},
 };
 
-void m68k_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void m68k_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
     unsigned int i;
 
diff --git a/target-m68k/translate.c b/target-m68k/translate.c
index 5351880..6f72a2b 100644
--- a/target-m68k/translate.c
+++ b/target-m68k/translate.c
@@ -3092,8 +3092,7 @@ void gen_intermediate_code_pc(CPUState *env, TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state(CPUState *env, FILE *f,
-                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
     int i;
diff --git a/target-microblaze/translate.c b/target-microblaze/translate.c
index 38149bb..1ada15e 100644
--- a/target-microblaze/translate.c
+++ b/target-microblaze/translate.c
@@ -1534,8 +1534,7 @@ void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-void cpu_dump_state (CPUState *env, FILE *f,
-                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                      int flags)
 {
     int i;
diff --git a/target-mips/cpu.h b/target-mips/cpu.h
index 19511d7..c1f211f 100644
--- a/target-mips/cpu.h
+++ b/target-mips/cpu.h
@@ -8,6 +8,7 @@
 #define CPUState struct CPUMIPSState
 
 #include "config.h"
+#include "qemu-common.h"
 #include "mips-defs.h"
 #include "cpu-defs.h"
 #include "softfloat.h"
@@ -496,7 +497,7 @@ void do_unassigned_access(target_phys_addr_t addr, int is_write, int is_exec,
                           int unused, int size);
 #endif
 
-void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf);
 
 #define cpu_init cpu_mips_init
 #define cpu_exec cpu_mips_exec
diff --git a/target-mips/translate.c b/target-mips/translate.c
index d62c615..ba45eb0 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -12450,8 +12450,7 @@ void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
     gen_intermediate_code_internal(env, tb, 1);
 }
 
-static void fpu_dump_state(CPUState *env, FILE *f,
-                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
+static void fpu_dump_state(CPUState *env, FILE *f, fprintf_function fpu_fprintf,
                            int flags)
 {
     int i;
@@ -12480,8 +12479,8 @@ static void fpu_dump_state(CPUState *env, FILE *f,
     } while(0)
 
 
-    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
-                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
+    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
+                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
                 get_float_exception_flags(&env->active_fpu.fp_status));
     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
         fpu_fprintf(f, "%3s: ", fregnames[i]);
@@ -12499,7 +12498,7 @@ static void fpu_dump_state(CPUState *env, FILE *f,
 
 static void
 cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
-                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+                                fprintf_function cpu_fprintf,
                                 int flags)
 {
     int i;
@@ -12525,8 +12524,7 @@ cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
 }
 #endif
 
-void cpu_dump_state (CPUState *env, FILE *f,
-                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                      int flags)
 {
     int i;
diff --git a/target-mips/translate_init.c b/target-mips/translate_init.c
index 8d1ece7..590e092 100644
--- a/target-mips/translate_init.c
+++ b/target-mips/translate_init.c
@@ -500,7 +500,7 @@ static const mips_def_t *cpu_mips_find_by_name (const char *name)
     return NULL;
 }
 
-void mips_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void mips_cpu_list (FILE *f, fprintf_function cpu_fprintf)
 {
     int i;
 
diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 1334dd1..deb8d7c 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -20,7 +20,7 @@
 #define __CPU_PPC_H__
 
 #include "config.h"
-#include <inttypes.h>
+#include "qemu-common.h"
 
 //#define PPC_EMULATE_32BITS_HYPV
 
@@ -761,7 +761,7 @@ void ppc_store_sr (CPUPPCState *env, int srnum, target_ulong value);
 #endif /* !defined(CONFIG_USER_ONLY) */
 void ppc_store_msr (CPUPPCState *env, target_ulong value);
 
-void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf);
 
 const ppc_def_t *cpu_ppc_find_by_name (const char *name);
 int cpu_ppc_register_internal (CPUPPCState *env, const ppc_def_t *def);
diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index fd06861..c82a483 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -8830,8 +8830,7 @@ GEN_SPEOP_LDST(evstwwo, 0x1E, 2),
 
 /*****************************************************************************/
 /* Misc PowerPC helpers */
-void cpu_dump_state (CPUState *env, FILE *f,
-                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                      int flags)
 {
 #define RGPL  4
@@ -8840,15 +8839,15 @@ void cpu_dump_state (CPUState *env, FILE *f,
     int i;
 
     cpu_fprintf(f, "NIP " TARGET_FMT_lx "   LR " TARGET_FMT_lx " CTR "
-                TARGET_FMT_lx " XER %08x\n", env->nip, env->lr, env->ctr,
-                env->xer);
+                TARGET_FMT_lx " XER " TARGET_FMT_lx "\n",
+                env->nip, env->lr, env->ctr, env->xer);
     cpu_fprintf(f, "MSR " TARGET_FMT_lx " HID0 " TARGET_FMT_lx "  HF "
                 TARGET_FMT_lx " idx %d\n", env->msr, env->spr[SPR_HID0],
                 env->hflags, env->mmu_idx);
 #if !defined(NO_TIMER_DUMP)
-    cpu_fprintf(f, "TB %08x %08x "
+    cpu_fprintf(f, "TB %08" PRIu32 " %08" PRIu64
 #if !defined(CONFIG_USER_ONLY)
-                "DECR %08x"
+                " DECR %08" PRIu32
 #endif
                 "\n",
                 cpu_ppc_load_tbu(env), cpu_ppc_load_tbl(env)
@@ -8898,8 +8897,7 @@ void cpu_dump_state (CPUState *env, FILE *f,
 #undef RFPL
 }
 
-void cpu_dump_statistics (CPUState *env, FILE*f,
-                          int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_statistics (CPUState *env, FILE*f, fprintf_function cpu_fprintf,
                           int flags)
 {
 #if defined(DO_PPC_STATISTICS)
diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 05ffe95..dfcd949 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -9756,7 +9756,7 @@ const ppc_def_t *cpu_ppc_find_by_name (const char *name)
     return ret;
 }
 
-void ppc_cpu_list (FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void ppc_cpu_list (FILE *f, fprintf_function cpu_fprintf)
 {
     int i, max;
 
diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index 44dfa65..881d8c4 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -23,8 +23,7 @@
 #include "tcg-op.h"
 #include "qemu-log.h"
 
-void cpu_dump_state(CPUState *env, FILE *f,
-                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
     int i;
diff --git a/target-sh4/cpu.h b/target-sh4/cpu.h
index 64a609b..e197766 100644
--- a/target-sh4/cpu.h
+++ b/target-sh4/cpu.h
@@ -20,6 +20,7 @@
 #define _CPU_SH4_H
 
 #include "config.h"
+#include "qemu-common.h"
 
 #define TARGET_LONG_BITS 32
 #define TARGET_HAS_ICE 1
@@ -168,7 +169,7 @@ int cpu_sh4_handle_mmu_fault(CPUSH4State * env, target_ulong address, int rw,
 #define cpu_handle_mmu_fault cpu_sh4_handle_mmu_fault
 void do_interrupt(CPUSH4State * env);
 
-void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf);
 #if !defined(CONFIG_USER_ONLY)
 void cpu_sh4_invalidate_tlb(CPUSH4State *s);
 void cpu_sh4_write_mmaped_utlb_addr(CPUSH4State *s, target_phys_addr_t addr,
diff --git a/target-sh4/translate.c b/target-sh4/translate.c
index deee939..f418139 100644
--- a/target-sh4/translate.c
+++ b/target-sh4/translate.c
@@ -257,7 +257,7 @@ static const sh4_def_t *cpu_sh4_find_by_name(const char *name)
     return NULL;
 }
 
-void sh4_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void sh4_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
     int i;
 
diff --git a/target-sparc/helper.c b/target-sparc/helper.c
index aa1fd63..e84c312 100644
--- a/target-sparc/helper.c
+++ b/target-sparc/helper.c
@@ -1323,8 +1323,7 @@ static const char * const feature_name[] = {
     "gl",
 };
 
-static void print_features(FILE *f,
-                           int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+static void print_features(FILE *f, fprintf_function cpu_fprintf,
                            uint32_t features, const char *prefix)
 {
     unsigned int i;
@@ -1452,7 +1451,7 @@ static int cpu_sparc_find_by_name(sparc_def_t *cpu_def, const char *cpu_model)
     return -1;
 }
 
-void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void sparc_cpu_list(FILE *f, fprintf_function cpu_fprintf)
 {
     unsigned int i;
 
@@ -1479,8 +1478,7 @@ void sparc_cpu_list(FILE *f, int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
                    "fpu_version mmu_version nwindows\n");
 }
 
-static void cpu_print_cc(FILE *f,
-                         int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+static void cpu_print_cc(FILE *f, fprintf_function cpu_fprintf,
                          uint32_t cc)
 {
     cpu_fprintf(f, "%c%c%c%c", cc & PSR_NEG? 'N' : '-',
@@ -1494,8 +1492,7 @@ static void cpu_print_cc(FILE *f,
 #define REGS_PER_LINE 8
 #endif
 
-void cpu_dump_state(CPUState *env, FILE *f,
-                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
+void cpu_dump_state(CPUState *env, FILE *f, fprintf_function cpu_fprintf,
                     int flags)
 {
     int i, x;
commit 055403b2a72729497fb58e0c6293547e767679d3
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Oct 22 23:03:32 2010 +0200

    exec: Use fprintf_function for dump_exec_info (format checking)
    
    fprintf_function uses format checking with GCC_FMT_ATTR.
    
    It is declared in qemu-common.h and used in cpu-all.h
    (which is included from cpu.h), so qemu-common.h must
    be included earlier. Some redundant include statements
    for standard include files were removed.
    
    Fix also two format errors (ptrdiff_t needs %td).
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-all.h b/cpu-all.h
index 11edddc..ba9d766 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -959,8 +959,7 @@ int cpu_physical_memory_get_dirty_tracking(void);
 int cpu_physical_sync_dirty_bitmap(target_phys_addr_t start_addr,
                                    target_phys_addr_t end_addr);
 
-void dump_exec_info(FILE *f,
-                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+void dump_exec_info(FILE *f, fprintf_function cpu_fprintf);
 #endif /* !CONFIG_USER_ONLY */
 
 int cpu_memory_rw_debug(CPUState *env, target_ulong addr,
diff --git a/exec.c b/exec.c
index 631d8c5..db9ff55 100644
--- a/exec.c
+++ b/exec.c
@@ -23,17 +23,10 @@
 #include <sys/types.h>
 #include <sys/mman.h>
 #endif
-#include <stdlib.h>
-#include <stdio.h>
-#include <stdarg.h>
-#include <string.h>
-#include <errno.h>
-#include <unistd.h>
-#include <inttypes.h>
 
+#include "qemu-common.h"
 #include "cpu.h"
 #include "exec-all.h"
-#include "qemu-common.h"
 #include "tcg.h"
 #include "hw/hw.h"
 #include "hw/qdev.h"
@@ -4096,8 +4089,7 @@ void cpu_io_recompile(CPUState *env, void *retaddr)
 
 #if !defined(CONFIG_USER_ONLY)
 
-void dump_exec_info(FILE *f,
-                    int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void dump_exec_info(FILE *f, fprintf_function cpu_fprintf)
 {
     int i, target_code_size, max_target_code_size;
     int direct_jmp_count, direct_jmp2_count, cross_page;
@@ -4124,14 +4116,14 @@ void dump_exec_info(FILE *f,
     }
     /* XXX: avoid using doubles ? */
     cpu_fprintf(f, "Translation buffer state:\n");
-    cpu_fprintf(f, "gen code size       %ld/%ld\n",
+    cpu_fprintf(f, "gen code size       %td/%ld\n",
                 code_gen_ptr - code_gen_buffer, code_gen_buffer_max_size);
     cpu_fprintf(f, "TB count            %d/%d\n", 
                 nb_tbs, code_gen_max_blocks);
     cpu_fprintf(f, "TB avg target size  %d max=%d bytes\n",
                 nb_tbs ? target_code_size / nb_tbs : 0,
                 max_target_code_size);
-    cpu_fprintf(f, "TB avg host size    %d bytes (expansion ratio: %0.1f)\n",
+    cpu_fprintf(f, "TB avg host size    %td bytes (expansion ratio: %0.1f)\n",
                 nb_tbs ? (code_gen_ptr - code_gen_buffer) / nb_tbs : 0,
                 target_code_size ? (double) (code_gen_ptr - code_gen_buffer) / target_code_size : 0);
     cpu_fprintf(f, "cross page TB count %d (%d%%)\n",
commit 405cf9ff007a62f120e2f38a517b41e1a1dbf0ce
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Oct 22 23:03:31 2010 +0200

    tcg: Use fprintf_function (format checking)
    
    fprintf_function uses format checking with GCC_FMT_ATTR.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index 0cdef0d..5dd6a2c 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -2124,8 +2124,7 @@ int tcg_gen_code_search_pc(TCGContext *s, uint8_t *gen_code_buf, long offset)
 }
 
 #ifdef CONFIG_PROFILER
-void tcg_dump_info(FILE *f,
-                   int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
 {
     TCGContext *s = &tcg_ctx;
     int64_t tot;
@@ -2169,8 +2168,7 @@ void tcg_dump_info(FILE *f,
     dump_op_count();
 }
 #else
-void tcg_dump_info(FILE *f,
-                   int (*cpu_fprintf)(FILE *f, const char *fmt, ...))
+void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf)
 {
     cpu_fprintf(f, "[TCG profiler not compiled]\n");
 }
diff --git a/tcg/tcg.h b/tcg/tcg.h
index 972df72..e1afde2 100644
--- a/tcg/tcg.h
+++ b/tcg/tcg.h
@@ -392,8 +392,7 @@ static inline TCGv_i64 tcg_temp_local_new_i64(void)
 void tcg_temp_free_i64(TCGv_i64 arg);
 char *tcg_get_arg_str_i64(TCGContext *s, char *buf, int buf_size, TCGv_i64 arg);
 
-void tcg_dump_info(FILE *f,
-                   int (*cpu_fprintf)(FILE *f, const char *fmt, ...));
+void tcg_dump_info(FILE *f, fprintf_function cpu_fprintf);
 
 #define TCG_CT_ALIAS  0x80
 #define TCG_CT_IALIAS 0x40
commit f868445a502a75b6ac785dddbcc3233cc5f986b0
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Oct 22 23:03:30 2010 +0200

    Add fprintf_function for function pointers to fprintf-like functions
    
    This kind of function pointers is used very often in qemu.
    
    The new data type uses format checking with GCC_FMT_ATTR
    and will be used in later patches.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/qemu-common.h b/qemu-common.h
index d31f366..3496e4f 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -81,6 +81,9 @@ struct iovec {
 #define GCC_FMT_ATTR(n, m)
 #endif
 
+typedef int (*fprintf_function)(FILE *f, const char *fmt, ...)
+    GCC_FMT_ATTR(2, 3);
+
 #ifdef _WIN32
 #define fsync _commit
 #define lseek _lseeki64
commit 338b922edd88440ef555f08d6924609915c6f00c
Author: malc <av1474 at comtv.ru>
Date:   Sat Oct 30 01:41:01 2010 +0400

    Mov muldiv64 to qemu-common.h (Thus unbreaking gus)
    
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index 10c9c43..6bcabef 100644
--- a/hw/omap_clk.c
+++ b/hw/omap_clk.c
@@ -20,7 +20,6 @@
  */
 #include "hw.h"
 #include "omap.h"
-#include "qemu-timer.h" /* for muldiv64() */
 
 struct clk {
     const char *name;
diff --git a/qemu-common.h b/qemu-common.h
index 2fbc27f..d31f366 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -309,6 +309,30 @@ static inline uint8_t from_bcd(uint8_t val)
     return ((val >> 4) * 10) + (val & 0x0f);
 }
 
+/* compute with 96 bit intermediate result: (a*b)/c */
+static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+    union {
+        uint64_t ll;
+        struct {
+#ifdef HOST_WORDS_BIGENDIAN
+            uint32_t high, low;
+#else
+            uint32_t low, high;
+#endif
+        } l;
+    } u, res;
+    uint64_t rl, rh;
+
+    u.ll = a;
+    rl = (uint64_t)u.l.low * (uint64_t)b;
+    rh = (uint64_t)u.l.high * (uint64_t)b;
+    rh += (rl >> 32);
+    res.l.high = rh / c;
+    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+    return res.ll;
+}
+
 #include "module.h"
 
 #endif
diff --git a/qemu-timer.h b/qemu-timer.h
index 299e387..8cd8f83 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -59,30 +59,6 @@ static inline int64_t get_ticks_per_sec(void)
     return 1000000000LL;
 }
 
-/* compute with 96 bit intermediate result: (a*b)/c */
-static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
-    union {
-        uint64_t ll;
-        struct {
-#ifdef HOST_WORDS_BIGENDIAN
-            uint32_t high, low;
-#else
-            uint32_t low, high;
-#endif
-        } l;
-    } u, res;
-    uint64_t rl, rh;
-
-    u.ll = a;
-    rl = (uint64_t)u.l.low * (uint64_t)b;
-    rh = (uint64_t)u.l.high * (uint64_t)b;
-    rh += (rl >> 32);
-    res.l.high = rh / c;
-    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
-    return res.ll;
-}
-
 /* real time host monotonic timer */
 static inline int64_t get_clock_realtime(void)
 {
commit 174b2877b0f6a607f994f7a5b9b9a36caaff5d75
Merge: 21bcc59... 46c7fc1...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Oct 26 09:51:03 2010 -0500

    Merge remote branch 'qmp/for-anthony' into staging

commit 21bcc5907f4c4a8acffcda8b6662710784cba388
Merge: 758c309... 8c269b5...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Tue Oct 26 09:50:58 2010 -0500

    Merge remote branch 'kwolf/for-anthony' into staging

commit 758c309f0a5cb52441a1ee015566cf9cd96fa933
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Mon Oct 25 16:06:45 2010 -0500

    seabios: Update to 0.6.1
    
     - 0ff9051 Update version to 0.6.1
     - 9c000e6 Support Samsung SE-S084 USB DVD drive (and probably many others)
     - eebe949 pciinit: remove unused variable, old_addr, in pci_set_io_region_addr().
     - 06644f4 Minor - indentation change to jpeg.c.
     - 2dcd9fa Enhance tools/readserial.py to support reading from a pipe.
     - 7ce09ae Make tools/transdump.py more resilient to unknown input.
     - 6039fc5 Update qemu_cfg_read to use "rep insb".
     - 9a01a9c Only show bootsplash during boot menu.
     - 5feb83c add write support to virtio-blk
     - 22f6378 Don't try to talk to APIC on 486
     - e2074bf Add ACPI SSDT/DSDT support for CPU hotplug.
     - eb6dc78 Add additional debug status messages to bootsplash code.
     - c8e4e88 Allow qemu to use bootsplash code via fwcfg interface.
     - 597040d Add tools/trandump.py tool for converting hexdump() output.
     - 48f5f8b Default bootsplash on (for coreboot users).
     - 8d85eb1 Autodetect video mode based on bootsplash jpeg dimensions.
     - b2b9d4a Rename "decdata" to "jpeg" in bootsplash - to be consistent with jpeg.c.
     - bbc4722 Breakup jpeg_decode into parsing and displaying phases.
     - 2976dd4 Avoid using BSS variables in jpeg.c.
     - cc9e1bf Add FUNC16() helper macro for converting a 16bit func to a segoff_s.
     - b4525a0 Handle unaligned sizes in iomemcpy().
     - 0e27e19 Cleanup bootsplash vesa signature detection.
     - cadaf0e Be sure to disable bootsplash on all BIOS boot cases.
     - 2641186 Add call16_int10 helper to bootsplash.c.
     - 6dc76f4 Don't do "double buffering" in bootsplash code.
     - 227dc3e Check that malloc succeeds in bootsplash code.
     - a576c9c Bootsplash fixes and cleanups.
     - 9fd4851 Minor - clarify bit logic in mptable.c.
     - abf31d3 Fix integer truncating bug in calc_future_timer().
     - 1d5c333 seabios: pciinit: fix 64bit bar initilization.
     - ae6924d Minor - introduce GDT_GRANLIMIT macro.
     - 0f78889 Avoid code addresses >64K in big real mode.
     - aec19c9 seabios: smm: move out piix4 specific smram logic to dev-i440fx.c
     - 08328e7 seabios: shadow: make device finding more generic.
     - 4c67f90 seabios: acpi: clean up of finding pm device.
     - fe54a53 seabios: acpi: split out piix4 pm logic.
     - d06afb4 seabios: acpi: move acpi definitions to acpi.h from acpi.c
     - 2f54bb4 seabios: acpi: move out endian conversion helper function.
     - 23173ac seabios: pci: introduce helper function to find device from table and initialize it.
    
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/pc-bios/bios.bin b/pc-bios/bios.bin
index d0d4b6a..f79c342 100644
Binary files a/pc-bios/bios.bin and b/pc-bios/bios.bin differ
diff --git a/roms/seabios b/roms/seabios
index 17d3e46..0ff9051 160000
--- a/roms/seabios
+++ b/roms/seabios
@@ -1 +1 @@
-Subproject commit 17d3e46511aeedc9f09a8216d194d749187b80aa
+Subproject commit 0ff9051f756ba739bc2edca77925191c3c6cbc2f
commit c57c846a80f9306aa2c6cf7efdef45ed42723fac
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Sat Oct 23 15:24:07 2010 +0000

    qemu-timer: move commonly used timer code to qemu-timer-common
    
    Move timer init functions to a new file, qemu-timer-common.c. Make other
    critical timer functions inlined to preserve performance in
    qemu-timer.c, also move muldiv64() (used by the inline functions)
    to qemu-timer.h.
    
    Adjust block/raw-posix.c and simpletrace.c to use get_clock() directly.
    Remove a similar/duplicate definition in qemu-tool.c.
    
    Adjust hw/omap_clk.c to include qemu-timer.h because muldiv64() is used
    there.
    
    After this change, tracing can be used also for user code and
    simpletrace on Win32.
    
    Cc: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Acked-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/Makefile b/Makefile
index 252c817..a1434b1 100644
--- a/Makefile
+++ b/Makefile
@@ -129,11 +129,11 @@ version-obj-$(CONFIG_WIN32) += version.o
 qemu-img.o: qemu-img-cmds.h
 qemu-img.o qemu-tool.o qemu-nbd.o qemu-io.o: $(GENERATED_HEADERS)
 
-qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-img$(EXESUF): qemu-img.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
-qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-nbd$(EXESUF): qemu-nbd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
-qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y)
+qemu-io$(EXESUF): qemu-io.o cmd.o qemu-tool.o qemu-error.o $(trace-obj-y) $(block-obj-y) $(qobject-obj-y) $(version-obj-y) qemu-timer-common.o
 
 qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
 	$(call quiet-command,sh $(SRC_PATH)/hxtool -h < $< > $@,"  GEN   $@")
diff --git a/Makefile.objs b/Makefile.objs
index 6e6f60a..f07fb01 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -127,7 +127,7 @@ common-obj-y += iov.o acl.o
 common-obj-$(CONFIG_THREAD) += qemu-thread.o
 common-obj-$(CONFIG_IOTHREAD) += compatfd.o
 common-obj-y += notify.o event_notifier.o
-common-obj-y += qemu-timer.o
+common-obj-y += qemu-timer.o qemu-timer-common.o
 
 slirp-obj-y = cksum.o if.o ip_icmp.o ip_input.o ip_output.o
 slirp-obj-y += slirp.o mbuf.o misc.o sbuf.o socket.o tcp_input.o tcp_output.o
@@ -278,6 +278,7 @@ libdis-$(CONFIG_SPARC_DIS) += sparc-dis.o
 trace-obj-y = trace.o
 ifeq ($(TRACE_BACKEND),simple)
 trace-obj-y += simpletrace.o
+user-obj-y += qemu-timer-common.o
 endif
 
 vl.o: QEMU_CFLAGS+=$(GPROF_CFLAGS)
diff --git a/block/raw-posix.c b/block/raw-posix.c
index a5cbb7e..d0393e0 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -97,9 +97,9 @@
 #define FTYPE_CD     1
 #define FTYPE_FD     2
 
-/* if the FD is not accessed during that time (in ms), we try to
+/* if the FD is not accessed during that time (in ns), we try to
    reopen it to see if the disk has been changed */
-#define FD_OPEN_TIMEOUT 1000
+#define FD_OPEN_TIMEOUT (1000000000)
 
 #define MAX_BLOCKSIZE	4096
 
@@ -908,7 +908,7 @@ static int fd_open(BlockDriverState *bs)
         return 0;
     last_media_present = (s->fd >= 0);
     if (s->fd >= 0 &&
-        (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
+        (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
         close(s->fd);
         s->fd = -1;
 #ifdef DEBUG_FLOPPY
@@ -917,7 +917,7 @@ static int fd_open(BlockDriverState *bs)
     }
     if (s->fd < 0) {
         if (s->fd_got_error &&
-            (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
+            (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
 #ifdef DEBUG_FLOPPY
             printf("No floppy (open delayed)\n");
 #endif
@@ -925,7 +925,7 @@ static int fd_open(BlockDriverState *bs)
         }
         s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
         if (s->fd < 0) {
-            s->fd_error_time = qemu_get_clock(rt_clock);
+            s->fd_error_time = get_clock();
             s->fd_got_error = 1;
             if (last_media_present)
                 s->fd_media_changed = 1;
@@ -940,7 +940,7 @@ static int fd_open(BlockDriverState *bs)
     }
     if (!last_media_present)
         s->fd_media_changed = 1;
-    s->fd_open_time = qemu_get_clock(rt_clock);
+    s->fd_open_time = get_clock();
     s->fd_got_error = 0;
     return 0;
 }
diff --git a/hw/omap_clk.c b/hw/omap_clk.c
index 6bcabef..10c9c43 100644
--- a/hw/omap_clk.c
+++ b/hw/omap_clk.c
@@ -20,6 +20,7 @@
  */
 #include "hw.h"
 #include "omap.h"
+#include "qemu-timer.h" /* for muldiv64() */
 
 struct clk {
     const char *name;
diff --git a/qemu-common.h b/qemu-common.h
index d5ae420..2fbc27f 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -133,8 +133,6 @@ void qemu_bh_delete(QEMUBH *bh);
 int qemu_bh_poll(void);
 void qemu_bh_update_timeout(int *timeout);
 
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c);
-
 void qemu_get_timedate(struct tm *tm, int offset);
 int qemu_timedate_diff(struct tm *tm);
 
diff --git a/qemu-timer-common.c b/qemu-timer-common.c
new file mode 100644
index 0000000..fff4399
--- /dev/null
+++ b/qemu-timer-common.c
@@ -0,0 +1,62 @@
+/*
+ * QEMU System Emulator
+ *
+ * Copyright (c) 2003-2008 Fabrice Bellard
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+#include "qemu-timer.h"
+
+/***********************************************************/
+/* real time host monotonic timer */
+
+#ifdef _WIN32
+
+int64_t clock_freq;
+
+static void __attribute__((constructor)) init_get_clock(void)
+{
+    LARGE_INTEGER freq;
+    int ret;
+    ret = QueryPerformanceFrequency(&freq);
+    if (ret == 0) {
+        fprintf(stderr, "Could not calibrate ticks\n");
+        exit(1);
+    }
+    clock_freq = freq.QuadPart;
+}
+
+#else
+
+int use_rt_clock;
+
+static void __attribute__((constructor)) init_get_clock(void)
+{
+    use_rt_clock = 0;
+#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
+    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+    {
+        struct timespec ts;
+        if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
+            use_rt_clock = 1;
+        }
+    }
+#endif
+}
+#endif
diff --git a/qemu-timer.c b/qemu-timer.c
index bc5f207..95814af 100644
--- a/qemu-timer.c
+++ b/qemu-timer.c
@@ -64,78 +64,6 @@ int64_t qemu_icount_bias;
 static QEMUTimer *icount_rt_timer;
 static QEMUTimer *icount_vm_timer;
 
-
-/***********************************************************/
-/* real time host monotonic timer */
-
-
-static int64_t get_clock_realtime(void)
-{
-    struct timeval tv;
-
-    gettimeofday(&tv, NULL);
-    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
-}
-
-#ifdef WIN32
-
-static int64_t clock_freq;
-
-static void init_get_clock(void)
-{
-    LARGE_INTEGER freq;
-    int ret;
-    ret = QueryPerformanceFrequency(&freq);
-    if (ret == 0) {
-        fprintf(stderr, "Could not calibrate ticks\n");
-        exit(1);
-    }
-    clock_freq = freq.QuadPart;
-}
-
-static int64_t get_clock(void)
-{
-    LARGE_INTEGER ti;
-    QueryPerformanceCounter(&ti);
-    return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
-}
-
-#else
-
-static int use_rt_clock;
-
-static void init_get_clock(void)
-{
-    use_rt_clock = 0;
-#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
-    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
-    {
-        struct timespec ts;
-        if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) {
-            use_rt_clock = 1;
-        }
-    }
-#endif
-}
-
-static int64_t get_clock(void)
-{
-#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
-	|| defined(__DragonFly__) || defined(__FreeBSD_kernel__)
-    if (use_rt_clock) {
-        struct timespec ts;
-        clock_gettime(CLOCK_MONOTONIC, &ts);
-        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
-    } else
-#endif
-    {
-        /* XXX: using gettimeofday leads to problems if the date
-           changes, so it should be avoided. */
-        return get_clock_realtime();
-    }
-}
-#endif
-
 /***********************************************************/
 /* guest cycle counter */
 
@@ -614,7 +542,6 @@ int64_t qemu_get_clock_ns(QEMUClock *clock)
 
 void init_clocks(void)
 {
-    init_get_clock();
     rt_clock = qemu_new_clock(QEMU_CLOCK_REALTIME);
     vm_clock = qemu_new_clock(QEMU_CLOCK_VIRTUAL);
     host_clock = qemu_new_clock(QEMU_CLOCK_HOST);
diff --git a/qemu-timer.h b/qemu-timer.h
index 1494f79..299e387 100644
--- a/qemu-timer.h
+++ b/qemu-timer.h
@@ -2,6 +2,13 @@
 #define QEMU_TIMER_H
 
 #include "qemu-common.h"
+#include <time.h>
+#include <sys/time.h>
+
+#ifdef _WIN32
+#include <windows.h>
+#include <mmsystem.h>
+#endif
 
 /* timers */
 
@@ -52,6 +59,73 @@ static inline int64_t get_ticks_per_sec(void)
     return 1000000000LL;
 }
 
+/* compute with 96 bit intermediate result: (a*b)/c */
+static inline uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+    union {
+        uint64_t ll;
+        struct {
+#ifdef HOST_WORDS_BIGENDIAN
+            uint32_t high, low;
+#else
+            uint32_t low, high;
+#endif
+        } l;
+    } u, res;
+    uint64_t rl, rh;
+
+    u.ll = a;
+    rl = (uint64_t)u.l.low * (uint64_t)b;
+    rh = (uint64_t)u.l.high * (uint64_t)b;
+    rh += (rl >> 32);
+    res.l.high = rh / c;
+    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+    return res.ll;
+}
+
+/* real time host monotonic timer */
+static inline int64_t get_clock_realtime(void)
+{
+    struct timeval tv;
+
+    gettimeofday(&tv, NULL);
+    return tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000);
+}
+
+/* Warning: don't insert tracepoints into these functions, they are
+   also used by simpletrace backend and tracepoints would cause
+   an infinite recursion! */
+#ifdef _WIN32
+extern int64_t clock_freq;
+
+static inline int64_t get_clock(void)
+{
+    LARGE_INTEGER ti;
+    QueryPerformanceCounter(&ti);
+    return muldiv64(ti.QuadPart, get_ticks_per_sec(), clock_freq);
+}
+
+#else
+
+extern int use_rt_clock;
+
+static inline int64_t get_clock(void)
+{
+#if defined(__linux__) || (defined(__FreeBSD__) && __FreeBSD_version >= 500000) \
+    || defined(__DragonFly__) || defined(__FreeBSD_kernel__)
+    if (use_rt_clock) {
+        struct timespec ts;
+        clock_gettime(CLOCK_MONOTONIC, &ts);
+        return ts.tv_sec * 1000000000LL + ts.tv_nsec;
+    } else
+#endif
+    {
+        /* XXX: using gettimeofday leads to problems if the date
+           changes, so it should be avoided. */
+        return get_clock_realtime();
+    }
+}
+#endif
 
 void qemu_get_timer(QEMUFile *f, QEMUTimer *ts);
 void qemu_put_timer(QEMUFile *f, QEMUTimer *ts);
diff --git a/qemu-tool.c b/qemu-tool.c
index b39af86..9ccca65 100644
--- a/qemu-tool.c
+++ b/qemu-tool.c
@@ -110,10 +110,3 @@ int qemu_set_fd_handler2(int fd,
 {
     return 0;
 }
-
-int64_t qemu_get_clock(QEMUClock *clock)
-{
-    qemu_timeval tv;
-    qemu_gettimeofday(&tv);
-    return (tv.tv_sec * 1000000000LL + (tv.tv_usec * 1000)) / 1000000;
-}
diff --git a/simpletrace.c b/simpletrace.c
index b488d51..9ea0d1f 100644
--- a/simpletrace.c
+++ b/simpletrace.c
@@ -12,6 +12,7 @@
 #include <stdint.h>
 #include <stdio.h>
 #include <time.h>
+#include "qemu-timer.h"
 #include "trace.h"
 
 /** Trace file header event ID */
@@ -140,20 +141,13 @@ static void trace(TraceEventID event, uint64_t x1, uint64_t x2, uint64_t x3,
                   uint64_t x4, uint64_t x5, uint64_t x6)
 {
     TraceRecord *rec = &trace_buf[trace_idx];
-    struct timespec ts;
-
-    /* TODO Windows?  It would be good to use qemu-timer here but that isn't
-     * linked into qemu-tools.  Also we should avoid recursion in the tracing
-     * code, therefore it is useful to be self-contained.
-     */
-    clock_gettime(CLOCK_MONOTONIC, &ts);
 
     if (!trace_list[event].state) {
         return;
     }
 
     rec->event = event;
-    rec->timestamp_ns = ts.tv_sec * 1000000000LL + ts.tv_nsec;
+    rec->timestamp_ns = get_clock();
     rec->x1 = x1;
     rec->x2 = x2;
     rec->x3 = x3;
diff --git a/vl.c b/vl.c
index df414ef..7038952 100644
--- a/vl.c
+++ b/vl.c
@@ -289,30 +289,6 @@ static int default_driver_check(QemuOpts *opts, void *opaque)
 /***********************************************************/
 /* real time host monotonic timer */
 
-/* compute with 96 bit intermediate result: (a*b)/c */
-uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
-{
-    union {
-        uint64_t ll;
-        struct {
-#ifdef HOST_WORDS_BIGENDIAN
-            uint32_t high, low;
-#else
-            uint32_t low, high;
-#endif
-        } l;
-    } u, res;
-    uint64_t rl, rh;
-
-    u.ll = a;
-    rl = (uint64_t)u.l.low * (uint64_t)b;
-    rh = (uint64_t)u.l.high * (uint64_t)b;
-    rh += (rl >> 32);
-    res.l.high = rh / c;
-    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
-    return res.ll;
-}
-
 /***********************************************************/
 /* host time/date access */
 void qemu_get_timedate(struct tm *tm, int offset)
commit 2b2e59e6c95beff2248069b2b129ba8c92c5f4d3
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Oct 21 10:18:40 2010 +0200

    rewrite i386 tests Makefile
    
    1) compute path to i386 compiler from configure.  If it is found, run
    the i386 tests.  I use macros so that this approach could be applied
    for other arches as well.
    
    2) provide an easily extensible way to add tests
    
    Most tests fail, but at least "make test" does something meaningful.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index f6a63bc..f62c1fe 100755
--- a/configure
+++ b/configure
@@ -92,6 +92,7 @@ libs_softmmu=""
 libs_tools=""
 audio_pt_int=""
 audio_win_int=""
+cc_i386=i386-pc-linux-gnu-gcc
 
 # parse CC options first
 for opt do
@@ -789,12 +790,14 @@ case "$cpu" in
     i386)
            QEMU_CFLAGS="-m32 $QEMU_CFLAGS"
            LDFLAGS="-m32 $LDFLAGS"
+           cc_i386='$(CC) -m32'
            helper_cflags="-fomit-frame-pointer"
            host_guest_base="yes"
            ;;
     x86_64)
            QEMU_CFLAGS="-m64 $QEMU_CFLAGS"
            LDFLAGS="-m64 $LDFLAGS"
+           cc_i386='$(CC) -m32'
            host_guest_base="yes"
            ;;
     arm*)
@@ -2640,6 +2643,7 @@ echo "INSTALL_DIR=$install -d -m0755 -p" >> $config_host_mak
 echo "INSTALL_DATA=$install -m0644 -p" >> $config_host_mak
 echo "INSTALL_PROG=$install -m0755 -p" >> $config_host_mak
 echo "CC=$cc" >> $config_host_mak
+echo "CC_I386=$cc_i386" >> $config_host_mak
 echo "HOST_CC=$host_cc" >> $config_host_mak
 if test "$sparse" = "yes" ; then
   echo "CC      := REAL_CC=\"\$(CC)\" cgcc"       >> $config_host_mak
diff --git a/rules.mak b/rules.mak
index c843a13..6dac777 100644
--- a/rules.mak
+++ b/rules.mak
@@ -42,6 +42,15 @@ cc-option = $(if $(shell $(CC) $1 $2 -S -o /dev/null -xc /dev/null \
 VPATH_SUFFIXES = %.c %.h %.S %.m %.mak %.texi
 set-vpath = $(if $1,$(foreach PATTERN,$(VPATH_SUFFIXES),$(eval vpath $(PATTERN) $1)))
 
+# find-in-path
+# Usage: $(call find-in-path, prog)
+# Looks in the PATH if the argument contains no slash, else only considers one
+# specific directory.  Returns an # empty string if the program doesn't exist
+# there.
+find-in-path = $(if $(find-string /, $1), \
+        $(wildcard $1), \
+        $(wildcard $(patsubst %, %/$1, $(subst :, ,$(PATH)))))
+
 # Generate timestamp files for .h include files
 
 %.h: %.h-timestamp
diff --git a/tests/Makefile b/tests/Makefile
index ef575a4..e43ec70 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -3,82 +3,118 @@
 
 $(call set-vpath, $(SRC_PATH)/tests)
 
+QEMU=../i386-linux-user/qemu-i386
+QEMU_X86_64=../x86_64-linux-user/qemu-x86_64
+CC_X86_64=$(CC_I386) -m64
+
 CFLAGS=-Wall -O2 -g -fno-strict-aliasing -I..
 #CFLAGS+=-msse2
 LDFLAGS=
 
-ifeq ($(ARCH),i386)
-TESTS=linux-test testthread sha1-i386 test-i386
+# TODO: automatically detect ARM and MIPS compilers, and run those too
+
+# runcom maps page 0, so it requires root privileges
+# also, pi_10.com runs indefinitely
+
+I386_TESTS=hello-i386 \
+	   linux-test \
+	   testthread \
+	   sha1-i386 \
+	   test-i386 \
+	   test-mmap \
+	   # runcom
+
+# native i386 compilers sometimes are not biarch.  assume cross-compilers are
+ifneq ($(ARCH),i386)
+I386_TESTS+=run-test-x86_64
 endif
-ifeq ($(ARCH),x86_64)
-TESTS=test-x86_64
+
+TESTS = test_path
+ifneq ($(call find-in-path, $(CC_I386)),)
+TESTS += $(I386_TESTS)
 endif
-TESTS+=sha1# test_path
-#TESTS+=test_path
-#TESTS+=runcom
 
-QEMU=../i386-linux-user/qemu-i386
+all: $(patsubst %,run-%,$(TESTS))
+
+# rules to run tests
+
+.PHONY: $(patsubst %,run-%,$(TESTS))
+
+run-%: %
+	-$(QEMU) ./$*
+
+run-hello-i386: hello-i386
+run-linux-test: linux-test
+run-testthread: testthread
+run-sha1-i386: sha1-i386
+
+run-test-i386: test-i386
+	./test-i386 > test-i386.ref
+	-$(QEMU) test-i386 > test-i386.out
+	@if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
+
+run-test-x86_64: test-x86_64
+	./test-x86_64 > test-x86_64.ref
+	-$(QEMU_X86_64) test-x86_64 > test-x86_64.out
+	@if diff -u test-x86_64.ref test-x86_64.out ; then echo "Auto Test OK"; fi
+
+run-test-mmap: test-mmap
+	-$(QEMU) ./test-mmap
+	-$(QEMU) -p 8192 ./test-mmap 8192
+	-$(QEMU) -p 16384 ./test-mmap 16384
+	-$(QEMU) -p 32768 ./test-mmap 32768
+
+run-runcom: runcom
+	-$(QEMU) ./runcom $(SRC_PATH)/tests/pi_10.com
+
+run-test_path: test_path
+	./test_path
+
+# rules to compile tests
 
-all: $(TESTS)
+test_path: test_path.o
+test_path.o: test_path.c
 
 hello-i386: hello-i386.c
-	$(CC) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
+	$(CC_I386) -nostdlib $(CFLAGS) -static $(LDFLAGS) -o $@ $<
 	strip $@
 
 testthread: testthread.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
-
-test_path: test_path.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
-	./$@ || { rm $@; exit 1; }
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lpthread
 
 # i386/x86_64 emulation test (test various opcodes) */
 test-i386: test-i386.c test-i386-code16.S test-i386-vm86.S \
            test-i386.h test-i386-shift.h test-i386-muldiv.h
-	$(CC) -m32 $(CFLAGS) $(LDFLAGS) -static -o $@ \
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ \
               $(<D)/test-i386.c $(<D)/test-i386-code16.S $(<D)/test-i386-vm86.S -lm
 
 test-x86_64: test-i386.c \
            test-i386.h test-i386-shift.h test-i386-muldiv.h
-	$(CC) -m64 $(CFLAGS) $(LDFLAGS) -static -o $@ $(<D)/test-i386.c -lm
-
-ifeq ($(ARCH),i386)
-test: test-i386
-	./test-i386 > test-i386.ref
-else
-test:
-endif
-	$(QEMU) test-i386 > test-i386.out
-	@if diff -u test-i386.ref test-i386.out ; then echo "Auto Test OK"; fi
-
-.PHONY: test-mmap
-test-mmap: test-mmap.c
-	$(CC) $(CFLAGS) -Wall -static -O2 $(LDFLAGS) -o $@ $<
-	-./test-mmap
-	-$(QEMU) ./test-mmap
-	-$(QEMU) -p 8192 ./test-mmap 8192
-	-$(QEMU) -p 16384 ./test-mmap 16384
-	-$(QEMU) -p 32768 ./test-mmap 32768
+	$(CC_X86_64) $(CFLAGS) $(LDFLAGS) -o $@ $(<D)/test-i386.c -lm
 
 # generic Linux and CPU test
 linux-test: linux-test.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $< -lm
+
+# vm86 test
+runcom: runcom.c
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $<
+
+test-mmap: test-mmap.c
+	$(CC_I386) -m32 $(CFLAGS) -Wall -O2 $(LDFLAGS) -o $@ $<
 
 # speed test
 sha1-i386: sha1.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+	$(CC_I386) $(CFLAGS) $(LDFLAGS) -o $@ $<
 
 sha1: sha1.c
-	$(HOST_CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
+	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
 
 speed: sha1 sha1-i386
 	time ./sha1
 	time $(QEMU) ./sha1-i386
 
-# vm86 test
-runcom: runcom.c
-	$(CC) $(CFLAGS) $(LDFLAGS) -o $@ $<
-
+# broken test
 # NOTE: -fomit-frame-pointer is currently needed : this is a bug in libqemu
 qruncom: qruncom.c ../ioport-user.c ../i386-user/libqemu.a
 	$(CC) $(CFLAGS) -fomit-frame-pointer $(LDFLAGS) -I../target-i386 -I.. -I../i386-user -I../fpu \
commit 48118b020558bb4cde05894d9d8322a20cbb2f8d
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Oct 21 10:18:39 2010 +0200

    fix test_path
    
    path.c grew quite a few new dependencies (mostly via cutils.c),
    include them.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/Makefile b/tests/Makefile
index e26b2d7..ef575a4 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -3,7 +3,7 @@
 
 $(call set-vpath, $(SRC_PATH)/tests)
 
-CFLAGS=-Wall -O2 -g -fno-strict-aliasing
+CFLAGS=-Wall -O2 -g -fno-strict-aliasing -I..
 #CFLAGS+=-msse2
 LDFLAGS=
 
diff --git a/tests/test_path.c b/tests/test_path.c
index def7441..234ed97 100644
--- a/tests/test_path.c
+++ b/tests/test_path.c
@@ -1,12 +1,21 @@
 /* Test path override code */
-#define _GNU_SOURCE
+#include "../config-host.h"
+#include "../qemu-malloc.c"
+#include "../cutils.c"
 #include "../path.c"
+#include "../trace.c"
+#ifdef CONFIG_SIMPLE_TRACE
+#include "../simpletrace.c"
+#endif
+
 #include <stdarg.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 
+void qemu_log(const char *fmt, ...);
+
 /* Any log message kills the test. */
-void gemu_log(const char *fmt, ...)
+void qemu_log(const char *fmt, ...)
 {
     va_list ap;
 
commit e311248b6442827820bfc7340ea1401caee3a0f1
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Oct 21 10:18:38 2010 +0200

    make runcom compile on recent distributions
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/runcom.c b/tests/runcom.c
index 6380566..d60342b 100644
--- a/tests/runcom.c
+++ b/tests/runcom.c
@@ -13,15 +13,12 @@
 #include <linux/unistd.h>
 #include <asm/vm86.h>
 
-//#define SIGTEST
+extern int vm86 (unsigned long int subfunction,
+		 struct vm86plus_struct *info);
 
-#undef __syscall_return
-#define __syscall_return(type, res) \
-do { \
-	return (type) (res); \
-} while (0)
+#define VIF_MASK                0x00080000
 
-_syscall2(int, vm86, int, func, struct vm86plus_struct *, v86)
+//#define SIGTEST
 
 #define COM_BASE_ADDR    0x10100
 
commit f34f1fed71a6b63a243962b473a3b69358a07fa0
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Oct 21 10:18:37 2010 +0200

    disable test_enter on i386, it is broken
    
    Many other tests fail, but this has an infinite loop with both
    qemu-i386 and native execution (albeit on x86_64), so there is
    something more going on.  I'm not going to debug it now, so just
    disable the test.
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/test-i386.c b/tests/test-i386.c
index b28b257..8f481c7 100644
--- a/tests/test-i386.c
+++ b/tests/test-i386.c
@@ -2047,6 +2047,10 @@ long enter_stack[4096];
 #define RBP "%%ebp"
 #endif
 
+#if !defined(__x86_64__)
+/* causes an infinite loop, disable it for now.  */
+#define TEST_ENTER(size, stack_type, level)
+#else
 #define TEST_ENTER(size, stack_type, level)\
 {\
     long esp_save, esp_val, ebp_val, ebp_save, i;\
@@ -2078,6 +2082,7 @@ long enter_stack[4096];
     for(ptr = (stack_type *)esp_val; ptr < stack_end; ptr++)\
         printf(FMTLX "\n", (long)ptr[0]);\
 }
+#endif
 
 static void test_enter(void)
 {
commit 9517a9e6a550a141f6e60550e1cec65005273170
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Oct 21 10:18:36 2010 +0200

    unbreak "make" from vpath-built tests directory
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tests/Makefile b/tests/Makefile
index ff7f787..e26b2d7 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -1,4 +1,5 @@
 -include ../config-host.mak
+-include $(SRC_PATH)/rules.mak
 
 $(call set-vpath, $(SRC_PATH)/tests)
 
commit e6c3b0f7c4c544b7e06b72fb7d9813bb80c8784b
Author: Paolo Bonzini <pbonzini at redhat.com>
Date:   Thu Oct 21 10:18:35 2010 +0200

    unbreak "make" from tests directory
    
    Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index 9ed05de..f6a63bc 100755
--- a/configure
+++ b/configure
@@ -2348,6 +2348,7 @@ printf "# Configured with:" >> $config_host_mak
 printf " '%s'" "$0" "$@" >> $config_host_mak
 echo >> $config_host_mak
 
+echo all: >> $config_host_mak
 echo "prefix=$prefix" >> $config_host_mak
 echo "bindir=$bindir" >> $config_host_mak
 echo "mandir=$mandir" >> $config_host_mak
commit 5340c8a0f358f2dccf9b1a92da15c9f9fd25096f
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Fri Oct 22 18:26:08 2010 +0000

    mips_fulong2e: fix ram allocation
    
    RAM registration used incorrect offset.
    
    Fix by using the offset obtained previously for this purpose.
    
    Spotted by GCC 4.6.0 20100925 warning, which is also avoided.
    
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/mips_fulong2e.c b/hw/mips_fulong2e.c
index f9723f5..07eb9ee 100644
--- a/hw/mips_fulong2e.c
+++ b/hw/mips_fulong2e.c
@@ -295,7 +295,7 @@ static void mips_fulong2e_init(ram_addr_t ram_size, const char *boot_device,
     ram_offset = qemu_ram_alloc(NULL, "fulong2e.ram", ram_size);
     bios_offset = qemu_ram_alloc(NULL, "fulong2e.bios", bios_size);
 
-    cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
+    cpu_register_physical_memory(0, ram_size, ram_offset);
     cpu_register_physical_memory(0x1fc00000LL,
 					   bios_size, bios_offset | IO_MEM_ROM);
 
commit 2c80e42395bfe0bf291c082f9399431e1ff9d758
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Wed Oct 13 20:54:27 2010 +0200

    Replace remaining gcc format attributes by macro GCC_FMT_ATTR (format checking)
    
    Replace the remaining format attribute printf by macro
    GCC_FMT_ATTR which uses gnu_printf (if supported).
    
    v2
    * Removal of dyngen specific code is now done in a separate patch.
    * Handle attribute in new ui/spice-display.c, too.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cpu-all.h b/cpu-all.h
index 67a3266..11edddc 100644
--- a/cpu-all.h
+++ b/cpu-all.h
@@ -773,7 +773,7 @@ void cpu_dump_statistics (CPUState *env, FILE *f,
                           int flags);
 
 void QEMU_NORETURN cpu_abort(CPUState *env, const char *fmt, ...)
-    __attribute__ ((__format__ (__printf__, 2, 3)));
+    GCC_FMT_ATTR(2, 3);
 extern CPUState *first_cpu;
 extern CPUState *cpu_single_env;
 
diff --git a/ui/spice-display.c b/ui/spice-display.c
index 6702dfd..7b4f5c1 100644
--- a/ui/spice-display.c
+++ b/ui/spice-display.c
@@ -29,8 +29,7 @@
 
 static int debug = 0;
 
-static void __attribute__((format(printf,2,3)))
-dprint(int level, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) dprint(int level, const char *fmt, ...)
 {
     va_list args;
 
commit 47b01cf3a16b9526f99084e99de13dfd9072882e
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Wed Oct 13 20:54:26 2010 +0200

    Remove special handling of system include files (no longer needed)
    
    The formerly used dyngen code did not work with
    system include files like stdio.h.
    
    Tests with Linux, OSX and Win32 show that this
    restriction is no longer needed.
    
    So we hopefully can remove that special piece of code.
    This results in cleaner code and allows better use of
    the new GCC_FMT_ATTR macro.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/cris-dis.c b/cris-dis.c
index 455ba8a..afd775c 100644
--- a/cris-dis.c
+++ b/cris-dis.c
@@ -18,13 +18,11 @@
    You should have received a copy of the GNU General Public License
    along with this program; if not, see <http://www.gnu.org/licenses/>. */
 
+#include "qemu-common.h"
 #include "dis-asm.h"
 //#include "sysdep.h"
 #include "target-cris/opcode-cris.h"
 //#include "libiberty.h"
-
-
-void *qemu_malloc(size_t len); /* can't include qemu-common.h here */
 
 #define CONST_STRNEQ(STR1,STR2) (strncmp ((STR1), (STR2), sizeof (STR2) - 1) == 0)
 
diff --git a/disas.h b/disas.h
index 6a9332d..f9287f7 100644
--- a/disas.h
+++ b/disas.h
@@ -8,11 +8,8 @@
 void disas(FILE *out, void *code, unsigned long size);
 void target_disas(FILE *out, target_ulong code, target_ulong size, int flags);
 
-/* The usual mess... FIXME: Remove this condition once dyngen-exec.h is gone */
-#ifndef __DYNGEN_EXEC_H__
 void monitor_disas(Monitor *mon, CPUState *env,
                    target_ulong pc, int nb_insn, int is_physical, int flags);
-#endif
 
 /* Look up symbol for debugging purpose.  Returns "" if unknown. */
 const char *lookup_symbol(target_ulong orig_addr);
diff --git a/dyngen-exec.h b/dyngen-exec.h
index 5bfef3f..db00fba 100644
--- a/dyngen-exec.h
+++ b/dyngen-exec.h
@@ -19,19 +19,7 @@
 #if !defined(__DYNGEN_EXEC_H__)
 #define __DYNGEN_EXEC_H__
 
-/* prevent Solaris from trying to typedef FILE in gcc's
-   include/floatingpoint.h which will conflict with the
-   definition down below */
-#ifdef __sun__
-#define _FILEDEFED
-#endif
-
-/* NOTE: standard headers should be used with special care at this
-   point because host CPU registers are used as global variables. Some
-   host headers do not allow that. */
-#include <stddef.h>
-#include <stdint.h>
-#include <stdbool.h>
+#include "qemu-common.h"
 
 #ifdef __OpenBSD__
 #include <sys/types.h>
@@ -40,15 +28,6 @@
 /* XXX: This may be wrong for 64-bit ILP32 hosts.  */
 typedef void * host_reg_t;
 
-#ifdef CONFIG_BSD
-typedef struct __sFILE FILE;
-#else
-typedef struct FILE FILE;
-#endif
-extern int fprintf(FILE *, const char *, ...);
-extern int fputs(const char *, FILE *);
-extern int printf(const char *, ...);
-
 #if defined(__i386__)
 #define AREG0 "ebp"
 #elif defined(__x86_64__)
diff --git a/qemu-common.h b/qemu-common.h
index 81aafa0..d5ae420 100644
--- a/qemu-common.h
+++ b/qemu-common.h
@@ -18,11 +18,6 @@ typedef struct QEMUFile QEMUFile;
 typedef struct QEMUBH QEMUBH;
 typedef struct DeviceState DeviceState;
 
-/* Hack around the mess dyngen-exec.h causes: We need QEMU_NORETURN in files that
-   cannot include the following headers without conflicts. This condition has
-   to be removed once dyngen is gone. */
-#ifndef __DYNGEN_EXEC_H__
-
 /* we put basic includes here to avoid repeating them in device drivers */
 #include <stdlib.h>
 #include <stdio.h>
@@ -318,6 +313,4 @@ static inline uint8_t from_bcd(uint8_t val)
 
 #include "module.h"
 
-#endif /* dyngen-exec.h hack */
-
 #endif
commit dbb1413589512574519abcf52a9a7127ddc7844b
Merge: d03703c... 25d2e36...
Author: Anthony Liguori <aliguori at us.ibm.com>
Date:   Fri Oct 22 08:02:14 2010 -0500

    Merge remote branch 'qemu-kvm/uq/master' into staging

commit 8c269b542c5bbbcd74c1664959b223d941a2893b
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Wed Oct 20 13:17:30 2010 +0200

    virtio-blk: Respect werror option for flushes
    
    The werror option now affects not only write requests, but also flush requests.
    Previously, it was not possible to stop a VM on a failed flush.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index a1df26d..dbe2070 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -106,7 +106,13 @@ static void virtio_blk_flush_complete(void *opaque, int ret)
 {
     VirtIOBlockReq *req = opaque;
 
-    virtio_blk_req_complete(req, ret ? VIRTIO_BLK_S_IOERR : VIRTIO_BLK_S_OK);
+    if (ret) {
+        if (virtio_blk_handle_rw_error(req, -ret, 0)) {
+            return;
+        }
+    }
+
+    virtio_blk_req_complete(req, VIRTIO_BLK_S_OK);
 }
 
 static VirtIOBlockReq *virtio_blk_alloc_request(VirtIOBlock *s)
commit e2bcadadc35673223c1445152445d0c9b6887b9e
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Oct 18 17:13:05 2010 +0200

    ide: Handle flush failure
    
    Instead of always assuming success for bdrv_aio_flush, actually do something
    with the error. This respects the werror option and accordingly ignores the
    error, reports it to the guest or stops the VM and retries after cont.
    
    Ignoring the error is trivial, obviously. For stopping the VM and retrying
    later old code can be reused, but we need to introduce a new status for "retry
    a flush". For reporting to the guest, fortunately the same action is required
    as for a failed read/write (status = DRDY | ERR, error = ABRT), so this code
    can be reused as well.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 6d8606e..bc3e916 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -65,6 +65,7 @@ static void ide_dma_start(IDEState *s, BlockDriverCompletionFunc *dma_cb);
 static void ide_dma_restart(IDEState *s, int is_read);
 static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret);
 static int ide_handle_rw_error(IDEState *s, int error, int op);
+static void ide_flush_cache(IDEState *s);
 
 static void padstr(char *str, const char *src, int len)
 {
@@ -688,6 +689,8 @@ static void ide_dma_restart_bh(void *opaque)
         } else {
             ide_sector_write(bmdma_active_if(bm));
         }
+    } else if (bm->status & BM_STATUS_RETRY_FLUSH) {
+        ide_flush_cache(bmdma_active_if(bm));
     }
 }
 
@@ -795,7 +798,12 @@ static void ide_flush_cb(void *opaque, int ret)
 {
     IDEState *s = opaque;
 
-    /* XXX: how do we signal I/O errors here? */
+    if (ret < 0) {
+        /* XXX: What sector number to set here? */
+        if (ide_handle_rw_error(s, -ret, BM_STATUS_RETRY_FLUSH)) {
+            return;
+        }
+    }
 
     s->status = READY_STAT | SEEK_STAT;
     ide_set_irq(s->bus);
diff --git a/hw/ide/internal.h b/hw/ide/internal.h
index 4165543..d652e06 100644
--- a/hw/ide/internal.h
+++ b/hw/ide/internal.h
@@ -472,7 +472,8 @@ struct IDEDeviceInfo {
 #define BM_STATUS_INT    0x04
 #define BM_STATUS_DMA_RETRY  0x08
 #define BM_STATUS_PIO_RETRY  0x10
-#define BM_STATUS_RETRY_READ 0x20
+#define BM_STATUS_RETRY_READ  0x20
+#define BM_STATUS_RETRY_FLUSH 0x40
 
 #define BM_CMD_START     0x01
 #define BM_CMD_READ      0x08
commit 6bcb1a79a31563f2c414e1bd35d044d6ab385011
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Oct 18 17:10:49 2010 +0200

    ide: Factor ide_flush_cache out
    
    The next patch reuses this code, so put it in its own function.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 5ccb09c..6d8606e 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -801,6 +801,15 @@ static void ide_flush_cb(void *opaque, int ret)
     ide_set_irq(s->bus);
 }
 
+static void ide_flush_cache(IDEState *s)
+{
+    if (s->bs) {
+        bdrv_aio_flush(s->bs, ide_flush_cb, s);
+    } else {
+        ide_flush_cb(s, 0);
+    }
+}
+
 static inline void cpu_to_ube16(uint8_t *buf, int val)
 {
     buf[0] = val >> 8;
@@ -2031,10 +2040,7 @@ void ide_ioport_write(void *opaque, uint32_t addr, uint32_t val)
             break;
         case WIN_FLUSH_CACHE:
         case WIN_FLUSH_CACHE_EXT:
-            if (s->bs)
-                bdrv_aio_flush(s->bs, ide_flush_cb, s);
-            else
-                ide_flush_cb(s, 0);
+            ide_flush_cache(s);
             break;
         case WIN_STANDBY:
         case WIN_STANDBY2:
commit a18953fbe72ba553a564ba11fdda03aac41d4f38
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Thu Oct 14 15:46:04 2010 +0200

    qemu-img: Fix qemu-img convert -obacking_file
    
    The old -B option caused a backing file to be used for the converted image and
    to avoid copying clusters from the old backing file. When replaced with
    -obacking_file, qemu-img convert does assign the backing file to the new image,
    but it doesn't realize that it should avoid copying clusters from the backing
    file.
    
    This patch checks the -o options for a backing_file and applies the same logic
    as for -B in this case.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/qemu-img.c b/qemu-img.c
index d4a3b4e..2864cb8 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -645,6 +645,7 @@ static int img_convert(int argc, char **argv)
     const uint8_t *buf1;
     BlockDriverInfo bdi;
     QEMUOptionParameter *param = NULL, *create_options = NULL;
+    QEMUOptionParameter *out_baseimg_param;
     char *options = NULL;
     const char *snapshot_name = NULL;
 
@@ -769,6 +770,12 @@ static int img_convert(int argc, char **argv)
         goto out;
     }
 
+    /* Get backing file name if -o backing_file was used */
+    out_baseimg_param = get_option_parameter(param, BLOCK_OPT_BACKING_FILE);
+    if (out_baseimg_param) {
+        out_baseimg = out_baseimg_param->value.s;
+    }
+
     /* Check if compression is supported */
     if (flags & BLOCK_FLAG_COMPRESS) {
         QEMUOptionParameter *encryption =
commit a77cffe7e916f4dd28f2048982ea2e0d98143b11
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Sep 24 21:02:05 2010 +0200

    block: Use GCC_FMT_ATTR and fix a format error
    
    Adding the gcc format attribute detects a format bug
    which is fixed here.
    
    v2:
    Don't use type cast. BDRV_SECTOR_SIZE is unsigned long long,
    so %lld should be the correct format specifier.
    
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Cc: Kevin Wolf <kwolf at redhat.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/blkverify.c b/block/blkverify.c
index 8083464..b2a12fe 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -53,7 +53,8 @@ static AIOPool blkverify_aio_pool = {
     .cancel             = blkverify_aio_cancel,
 };
 
-static void blkverify_err(BlkverifyAIOCB *acb, const char *fmt, ...)
+static void GCC_FMT_ATTR(2, 3) blkverify_err(BlkverifyAIOCB *acb,
+                                             const char *fmt, ...)
 {
     va_list ap;
 
@@ -299,7 +300,7 @@ static void blkverify_verify_readv(BlkverifyAIOCB *acb)
 {
     ssize_t offset = blkverify_iovec_compare(acb->qiov, &acb->raw_qiov);
     if (offset != -1) {
-        blkverify_err(acb, "contents mismatch in sector %ld",
+        blkverify_err(acb, "contents mismatch in sector %lld",
                       acb->sector_num + (offset / BDRV_SECTOR_SIZE));
     }
 }
commit 191c2890ddc9626d35c9e432494e1699a8181025
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Thu Sep 16 13:18:08 2010 +0200

    qemu-io: New command map
    
    The new map command in qemu-io lists all allocated/unallocated areas in an
    image file.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/qemu-io.c b/qemu-io.c
index b4e5cc8..ff353eb 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -1443,6 +1443,44 @@ static const cmdinfo_t alloc_cmd = {
 };
 
 static int
+map_f(int argc, char **argv)
+{
+	int64_t offset;
+	int64_t nb_sectors;
+	char s1[64];
+	int num, num_checked;
+	int ret;
+	const char *retstr;
+
+	offset = 0;
+	nb_sectors = bs->total_sectors;
+
+	do {
+		num_checked = MIN(nb_sectors, INT_MAX);
+		ret = bdrv_is_allocated(bs, offset, num_checked, &num);
+		retstr = ret ? "    allocated" : "not allocated";
+		cvtstr(offset << 9ULL, s1, sizeof(s1));
+		printf("[% 24" PRId64 "] % 8d/% 8d sectors %s at offset %s (%d)\n",
+				offset << 9ULL, num, num_checked, retstr, s1, ret);
+
+		offset += num;
+		nb_sectors -= num;
+	} while(offset < bs->total_sectors);
+
+	return 0;
+}
+
+static const cmdinfo_t map_cmd = {
+       .name           = "map",
+       .argmin         = 0,
+       .argmax         = 0,
+       .cfunc          = map_f,
+       .args           = "",
+       .oneline        = "prints the allocated areas of a file",
+};
+
+
+static int
 close_f(int argc, char **argv)
 {
 	bdrv_close(bs);
@@ -1680,6 +1718,7 @@ int main(int argc, char **argv)
 	add_command(&length_cmd);
 	add_command(&info_cmd);
 	add_command(&alloc_cmd);
+	add_command(&map_cmd);
 
 	add_args_command(init_args_command);
 	add_check_command(init_check_command);
commit 51ef67270b1d10e1fcf3de7368dccad1ba0bf9d1
Author: edison <edison at cloud.com>
Date:   Tue Sep 21 19:58:41 2010 -0700

    Copy snapshots out of QCOW2 disk
    
    In order to backup snapshots, created from QCOW2 iamge, we want to copy snapshots out of QCOW2 disk to a seperate storage.
    The following patch adds a new option in "qemu-img": qemu-img convert -f qcow2 -O qcow2 -s snapshot_name src_img bck_img.
    Right now, it only supports to copy the full snapshot, delta snapshot is on the way.
    
    Changes from V1: all the comments from Kevin are addressed:
    Add read-only checking
    Fix coding style
    Change the name from bdrv_snapshot_load to bdrv_snapshot_load_tmp
    
    Signed-off-by: Disheng Su <edison at cloud.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block.c b/block.c
index a19374d..985d0b7 100644
--- a/block.c
+++ b/block.c
@@ -1899,6 +1899,22 @@ int bdrv_snapshot_list(BlockDriverState *bs,
     return -ENOTSUP;
 }
 
+int bdrv_snapshot_load_tmp(BlockDriverState *bs,
+        const char *snapshot_name)
+{
+    BlockDriver *drv = bs->drv;
+    if (!drv) {
+        return -ENOMEDIUM;
+    }
+    if (!bs->read_only) {
+        return -EINVAL;
+    }
+    if (drv->bdrv_snapshot_load_tmp) {
+        return drv->bdrv_snapshot_load_tmp(bs, snapshot_name);
+    }
+    return -ENOTSUP;
+}
+
 #define NB_SUFFIXES 4
 
 char *get_human_readable_size(char *buf, int buf_size, int64_t size)
diff --git a/block.h b/block.h
index 5f64380..a4facf2 100644
--- a/block.h
+++ b/block.h
@@ -211,6 +211,8 @@ int bdrv_snapshot_goto(BlockDriverState *bs,
 int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
 int bdrv_snapshot_list(BlockDriverState *bs,
                        QEMUSnapshotInfo **psn_info);
+int bdrv_snapshot_load_tmp(BlockDriverState *bs,
+                           const char *snapshot_name);
 char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn);
 
 char *get_human_readable_size(char *buf, int buf_size, int64_t size);
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 8dd5df0..aacf357 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -418,3 +418,34 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
     return s->nb_snapshots;
 }
 
+int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name)
+{
+    int i, snapshot_index, l1_size2;
+    BDRVQcowState *s = bs->opaque;
+    QCowSnapshot *sn;
+
+    snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_name);
+    if (snapshot_index < 0) {
+        return -ENOENT;
+    }
+
+    sn = &s->snapshots[snapshot_index];
+    s->l1_size = sn->l1_size;
+    l1_size2 = s->l1_size * sizeof(uint64_t);
+    if (s->l1_table != NULL) {
+        qemu_free(s->l1_table);
+    }
+
+    s->l1_table_offset = sn->l1_table_offset;
+    s->l1_table = qemu_mallocz(align_offset(l1_size2, 512));
+
+    if (bdrv_pread(bs->file, sn->l1_table_offset,
+                   s->l1_table, l1_size2) != l1_size2) {
+        return -1;
+    }
+
+    for(i = 0;i < s->l1_size; i++) {
+        be64_to_cpus(&s->l1_table[i]);
+    }
+    return 0;
+}
diff --git a/block/qcow2.c b/block/qcow2.c
index 45ed073..b816d87 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1286,6 +1286,7 @@ static BlockDriver bdrv_qcow2 = {
     .bdrv_snapshot_goto     = qcow2_snapshot_goto,
     .bdrv_snapshot_delete   = qcow2_snapshot_delete,
     .bdrv_snapshot_list     = qcow2_snapshot_list,
+    .bdrv_snapshot_load_tmp     = qcow2_snapshot_load_tmp,
     .bdrv_get_info	= qcow_get_info,
 
     .bdrv_save_vmstate    = qcow_save_vmstate,
diff --git a/block/qcow2.h b/block/qcow2.h
index add710b..2d22e5e 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -211,6 +211,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info);
 int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id);
 int qcow2_snapshot_delete(BlockDriverState *bs, const char *snapshot_id);
 int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab);
+int qcow2_snapshot_load_tmp(BlockDriverState *bs, const char *snapshot_name);
 
 void qcow2_free_snapshots(BlockDriverState *bs);
 int qcow2_read_snapshots(BlockDriverState *bs);
diff --git a/block_int.h b/block_int.h
index e8e7156..87e60b8 100644
--- a/block_int.h
+++ b/block_int.h
@@ -93,6 +93,8 @@ struct BlockDriver {
     int (*bdrv_snapshot_delete)(BlockDriverState *bs, const char *snapshot_id);
     int (*bdrv_snapshot_list)(BlockDriverState *bs,
                               QEMUSnapshotInfo **psn_info);
+    int (*bdrv_snapshot_load_tmp)(BlockDriverState *bs,
+                                  const char *snapshot_name);
     int (*bdrv_get_info)(BlockDriverState *bs, BlockDriverInfo *bdi);
 
     int (*bdrv_save_vmstate)(BlockDriverState *bs, const uint8_t *buf,
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 6d3e5f8..6c7176f 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -28,9 +28,9 @@ STEXI
 ETEXI
 
 DEF("convert", img_convert,
-    "convert [-c] [-f fmt] [-O output_fmt] [-o options] filename [filename2 [...]] output_filename")
+    "convert [-c] [-f fmt] [-O output_fmt] [-o options] [-s snapshot_name] filename [filename2 [...]] output_filename")
 STEXI
- at item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+ at item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 ETEXI
 
 DEF("info", img_info,
diff --git a/qemu-img.c b/qemu-img.c
index 578b8eb..d4a3b4e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -646,13 +646,14 @@ static int img_convert(int argc, char **argv)
     BlockDriverInfo bdi;
     QEMUOptionParameter *param = NULL, *create_options = NULL;
     char *options = NULL;
+    const char *snapshot_name = NULL;
 
     fmt = NULL;
     out_fmt = "raw";
     out_baseimg = NULL;
     flags = 0;
     for(;;) {
-        c = getopt(argc, argv, "f:O:B:hce6o:");
+        c = getopt(argc, argv, "f:O:B:s:hce6o:");
         if (c == -1)
             break;
         switch(c) {
@@ -680,6 +681,9 @@ static int img_convert(int argc, char **argv)
         case 'o':
             options = optarg;
             break;
+        case 's':
+            snapshot_name = optarg;
+            break;
         }
     }
 
@@ -711,6 +715,19 @@ static int img_convert(int argc, char **argv)
         total_sectors += bs_sectors;
     }
 
+    if (snapshot_name != NULL) {
+        if (bs_n > 1) {
+            error("No support for concatenating multiple snapshot\n");
+            ret = -1;
+            goto out;
+        }
+        if (bdrv_snapshot_load_tmp(bs[0], snapshot_name) < 0) {
+            error("Failed to load snapshot\n");
+            ret = -1;
+            goto out;
+        }
+    }
+
     /* Find driver and parse its options */
     drv = bdrv_find_format(out_fmt);
     if (!drv) {
diff --git a/qemu-img.texi b/qemu-img.texi
index c1b1f27..1b90ddb 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -77,9 +77,9 @@ it doesn't need to be specified separately in this case.
 
 Commit the changes recorded in @var{filename} in its base image.
 
- at item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+ at item convert [-c] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] @var{filename} [@var{filename2} [...]] @var{output_filename}
 
-Convert the disk image @var{filename} to disk image @var{output_filename}
+Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename}
 using format @var{output_fmt}. It can be optionally compressed (@code{-c}
 option) or use any format specific options like encryption (@code{-o} option).
 
commit a58b8d5401b6064d52113f243456115d046bdd12
Author: Christoph Hellwig <hch at lst.de>
Date:   Mon Oct 4 15:29:41 2010 +0200

    ide: set WCACHE supported in IDENTIFY data
    
    ATA does not only have the WCACHE enabled bit in identify word 85, but also
    a WCACHE supported bit in word 82.  While the Linux kernel is fine with the
    latter at least hdparm also needs the former before correctly displaying
    the cache settings.  There's also a non-zero chance other operating systems
    are more picky in their volatile write cache detection.
    
    Signed-off-by: Christoph Hellwig <hch at lst.de>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/hw/ide/core.c b/hw/ide/core.c
index 06b6e14..5ccb09c 100644
--- a/hw/ide/core.c
+++ b/hw/ide/core.c
@@ -146,8 +146,8 @@ static void ide_identify(IDEState *s)
     put_le16(p + 68, 120);
     put_le16(p + 80, 0xf0); /* ata3 -> ata6 supported */
     put_le16(p + 81, 0x16); /* conforms to ata5 */
-    /* 14=NOP supported, 0=SMART supported */
-    put_le16(p + 82, (1 << 14) | 1);
+    /* 14=NOP supported, 5=WCACHE supported, 0=SMART supported */
+    put_le16(p + 82, (1 << 14) | (1 << 5) | 1);
     /* 13=flush_cache_ext,12=flush_cache,10=lba48 */
     put_le16(p + 83, (1 << 14) | (1 << 13) | (1 <<12) | (1 << 10));
     /* 14=set to 1, 1=SMART self test, 0=SMART error logging */
commit 9b036055ef65d0ab3236dfdb0d07828cea961133
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Mon Jun 14 15:15:03 2010 +0200

    qcow2: Remove old image creation function
    
    They have been #ifdef'd out by the previous patch.
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 3b2e38c..45ed073 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -795,30 +795,6 @@ static int qcow2_change_backing_file(BlockDriverState *bs,
     return qcow2_update_ext_header(bs, backing_file, backing_fmt);
 }
 
-#if 0
-static int get_bits_from_size(size_t size)
-{
-    int res = 0;
-
-    if (size == 0) {
-        return -1;
-    }
-
-    while (size != 1) {
-        /* Not a power of two */
-        if (size & 1) {
-            return -1;
-        }
-
-        size >>= 1;
-        res++;
-    }
-
-    return res;
-}
-#endif
-
-
 static int preallocate(BlockDriverState *bs)
 {
     uint64_t nb_sectors;
@@ -872,205 +848,6 @@ static int preallocate(BlockDriverState *bs)
     return 0;
 }
 
-#if 0
-static int qcow_create2(const char *filename, int64_t total_size,
-                        const char *backing_file, const char *backing_format,
-                        int flags, size_t cluster_size, int prealloc)
-{
-
-    int fd, header_size, backing_filename_len, l1_size, i, shift, l2_bits;
-    int ref_clusters, reftable_clusters, backing_format_len = 0;
-    int rounded_ext_bf_len = 0;
-    QCowHeader header;
-    uint64_t tmp, offset;
-    uint64_t old_ref_clusters;
-    QCowCreateState s1, *s = &s1;
-    QCowExtension ext_bf = {0, 0};
-    int ret;
-
-    memset(s, 0, sizeof(*s));
-
-    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY, 0644);
-    if (fd < 0)
-        return -errno;
-    memset(&header, 0, sizeof(header));
-    header.magic = cpu_to_be32(QCOW_MAGIC);
-    header.version = cpu_to_be32(QCOW_VERSION);
-    header.size = cpu_to_be64(total_size * 512);
-    header_size = sizeof(header);
-    backing_filename_len = 0;
-    if (backing_file) {
-        if (backing_format) {
-            ext_bf.magic = QCOW_EXT_MAGIC_BACKING_FORMAT;
-            backing_format_len = strlen(backing_format);
-            ext_bf.len = backing_format_len;
-            rounded_ext_bf_len = (sizeof(ext_bf) + ext_bf.len + 7) & ~7;
-            header_size += rounded_ext_bf_len;
-        }
-        header.backing_file_offset = cpu_to_be64(header_size);
-        backing_filename_len = strlen(backing_file);
-        header.backing_file_size = cpu_to_be32(backing_filename_len);
-        header_size += backing_filename_len;
-    }
-
-    /* Cluster size */
-    s->cluster_bits = get_bits_from_size(cluster_size);
-    if (s->cluster_bits < MIN_CLUSTER_BITS ||
-        s->cluster_bits > MAX_CLUSTER_BITS)
-    {
-        fprintf(stderr, "Cluster size must be a power of two between "
-            "%d and %dk\n",
-            1 << MIN_CLUSTER_BITS,
-            1 << (MAX_CLUSTER_BITS - 10));
-        return -EINVAL;
-    }
-    s->cluster_size = 1 << s->cluster_bits;
-
-    header.cluster_bits = cpu_to_be32(s->cluster_bits);
-    header_size = (header_size + 7) & ~7;
-    if (flags & BLOCK_FLAG_ENCRYPT) {
-        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
-    } else {
-        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
-    }
-    l2_bits = s->cluster_bits - 3;
-    shift = s->cluster_bits + l2_bits;
-    l1_size = (((total_size * 512) + (1LL << shift) - 1) >> shift);
-    offset = align_offset(header_size, s->cluster_size);
-    s->l1_table_offset = offset;
-    header.l1_table_offset = cpu_to_be64(s->l1_table_offset);
-    header.l1_size = cpu_to_be32(l1_size);
-    offset += align_offset(l1_size * sizeof(uint64_t), s->cluster_size);
-
-    /* count how many refcount blocks needed */
-
-#define NUM_CLUSTERS(bytes) \
-    (((bytes) + (s->cluster_size) - 1) / (s->cluster_size))
-
-    ref_clusters = NUM_CLUSTERS(NUM_CLUSTERS(offset) * sizeof(uint16_t));
-
-    do {
-        uint64_t image_clusters;
-        old_ref_clusters = ref_clusters;
-
-        /* Number of clusters used for the refcount table */
-        reftable_clusters = NUM_CLUSTERS(ref_clusters * sizeof(uint64_t));
-
-        /* Number of clusters that the whole image will have */
-        image_clusters = NUM_CLUSTERS(offset) + ref_clusters
-            + reftable_clusters;
-
-        /* Number of refcount blocks needed for the image */
-        ref_clusters = NUM_CLUSTERS(image_clusters * sizeof(uint16_t));
-
-    } while (ref_clusters != old_ref_clusters);
-
-    s->refcount_table = qemu_mallocz(reftable_clusters * s->cluster_size);
-
-    s->refcount_table_offset = offset;
-    header.refcount_table_offset = cpu_to_be64(offset);
-    header.refcount_table_clusters = cpu_to_be32(reftable_clusters);
-    offset += (reftable_clusters * s->cluster_size);
-    s->refcount_block_offset = offset;
-
-    for (i=0; i < ref_clusters; i++) {
-        s->refcount_table[i] = cpu_to_be64(offset);
-        offset += s->cluster_size;
-    }
-
-    s->refcount_block = qemu_mallocz(ref_clusters * s->cluster_size);
-
-    /* update refcounts */
-    qcow2_create_refcount_update(s, 0, header_size);
-    qcow2_create_refcount_update(s, s->l1_table_offset,
-        l1_size * sizeof(uint64_t));
-    qcow2_create_refcount_update(s, s->refcount_table_offset,
-        reftable_clusters * s->cluster_size);
-    qcow2_create_refcount_update(s, s->refcount_block_offset,
-        ref_clusters * s->cluster_size);
-
-    /* write all the data */
-    ret = qemu_write_full(fd, &header, sizeof(header));
-    if (ret != sizeof(header)) {
-        ret = -errno;
-        goto exit;
-    }
-    if (backing_file) {
-        if (backing_format_len) {
-            char zero[16];
-            int padding = rounded_ext_bf_len - (ext_bf.len + sizeof(ext_bf));
-
-            memset(zero, 0, sizeof(zero));
-            cpu_to_be32s(&ext_bf.magic);
-            cpu_to_be32s(&ext_bf.len);
-            ret = qemu_write_full(fd, &ext_bf, sizeof(ext_bf));
-            if (ret != sizeof(ext_bf)) {
-                ret = -errno;
-                goto exit;
-            }
-            ret = qemu_write_full(fd, backing_format, backing_format_len);
-            if (ret != backing_format_len) {
-                ret = -errno;
-                goto exit;
-            }
-            if (padding > 0) {
-                ret = qemu_write_full(fd, zero, padding);
-                if (ret != padding) {
-                    ret = -errno;
-                    goto exit;
-                }
-            }
-        }
-        ret = qemu_write_full(fd, backing_file, backing_filename_len);
-        if (ret != backing_filename_len) {
-            ret = -errno;
-            goto exit;
-        }
-    }
-    lseek(fd, s->l1_table_offset, SEEK_SET);
-    tmp = 0;
-    for(i = 0;i < l1_size; i++) {
-        ret = qemu_write_full(fd, &tmp, sizeof(tmp));
-        if (ret != sizeof(tmp)) {
-            ret = -errno;
-            goto exit;
-        }
-    }
-    lseek(fd, s->refcount_table_offset, SEEK_SET);
-    ret = qemu_write_full(fd, s->refcount_table,
-        reftable_clusters * s->cluster_size);
-    if (ret != reftable_clusters * s->cluster_size) {
-        ret = -errno;
-        goto exit;
-    }
-
-    lseek(fd, s->refcount_block_offset, SEEK_SET);
-    ret = qemu_write_full(fd, s->refcount_block,
-		    ref_clusters * s->cluster_size);
-    if (ret != ref_clusters * s->cluster_size) {
-        ret = -errno;
-        goto exit;
-    }
-
-    ret = 0;
-exit:
-    qemu_free(s->refcount_table);
-    qemu_free(s->refcount_block);
-    close(fd);
-
-    /* Preallocate metadata */
-    if (ret == 0 && prealloc) {
-        BlockDriverState *bs;
-        BlockDriver *drv = bdrv_find_format("qcow2");
-        bs = bdrv_new("");
-        bdrv_open(bs, filename, BDRV_O_CACHE_WB | BDRV_O_RDWR, drv);
-        ret = preallocate(bs);
-        bdrv_close(bs);
-    }
-
-    return ret;
-}
-#else
 static int qcow_create2(const char *filename, int64_t total_size,
                         const char *backing_file, const char *backing_format,
                         int flags, size_t cluster_size, int prealloc,
@@ -1196,7 +973,6 @@ out:
     bdrv_delete(bs);
     return ret;
 }
-#endif
 
 static int qcow_create(const char *filename, QEMUOptionParameter *options)
 {
commit a9420734b617be43d075c55b980479411807512e
Author: Kevin Wolf <kwolf at redhat.com>
Date:   Fri Jun 11 21:37:37 2010 +0200

    qcow2: Simplify image creation
    
    Instead of doing lots of magic for setting up initial refcount blocks and stuff
    create a minimal (inconsistent) image, open it and initialize the rest with
    regular qcow2 functions.
    
    This is a complete rewrite of the image creation function. The old
    implementating is #ifdef'd out and will be removed by the next patch (removing
    it here would have made the diff unreadable because diff tries to find
    similarities when it's really a rewrite)
    
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2.c b/block/qcow2.c
index 345d2e4..3b2e38c 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -27,6 +27,7 @@
 #include <zlib.h>
 #include "aes.h"
 #include "block/qcow2.h"
+#include "qemu-error.h"
 
 /*
   Differences with QCOW:
@@ -794,6 +795,7 @@ static int qcow2_change_backing_file(BlockDriverState *bs,
     return qcow2_update_ext_header(bs, backing_file, backing_fmt);
 }
 
+#if 0
 static int get_bits_from_size(size_t size)
 {
     int res = 0;
@@ -814,6 +816,7 @@ static int get_bits_from_size(size_t size)
 
     return res;
 }
+#endif
 
 
 static int preallocate(BlockDriverState *bs)
@@ -869,6 +872,7 @@ static int preallocate(BlockDriverState *bs)
     return 0;
 }
 
+#if 0
 static int qcow_create2(const char *filename, int64_t total_size,
                         const char *backing_file, const char *backing_format,
                         int flags, size_t cluster_size, int prealloc)
@@ -1066,6 +1070,133 @@ exit:
 
     return ret;
 }
+#else
+static int qcow_create2(const char *filename, int64_t total_size,
+                        const char *backing_file, const char *backing_format,
+                        int flags, size_t cluster_size, int prealloc,
+                        QEMUOptionParameter *options)
+{
+    /* Calulate cluster_bits */
+    int cluster_bits;
+    cluster_bits = ffs(cluster_size) - 1;
+    if (cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS ||
+        (1 << cluster_bits) != cluster_size)
+    {
+        error_report(
+            "Cluster size must be a power of two between %d and %dk\n",
+            1 << MIN_CLUSTER_BITS, 1 << (MAX_CLUSTER_BITS - 10));
+        return -EINVAL;
+    }
+
+    /*
+     * Open the image file and write a minimal qcow2 header.
+     *
+     * We keep things simple and start with a zero-sized image. We also
+     * do without refcount blocks or a L1 table for now. We'll fix the
+     * inconsistency later.
+     *
+     * We do need a refcount table because growing the refcount table means
+     * allocating two new refcount blocks - the seconds of which would be at
+     * 2 GB for 64k clusters, and we don't want to have a 2 GB initial file
+     * size for any qcow2 image.
+     */
+    BlockDriverState* bs;
+    QCowHeader header;
+    uint8_t* refcount_table;
+    int ret;
+
+    ret = bdrv_create_file(filename, options);
+    if (ret < 0) {
+        return ret;
+    }
+
+    ret = bdrv_file_open(&bs, filename, BDRV_O_RDWR);
+    if (ret < 0) {
+        return ret;
+    }
+
+    /* Write the header */
+    memset(&header, 0, sizeof(header));
+    header.magic = cpu_to_be32(QCOW_MAGIC);
+    header.version = cpu_to_be32(QCOW_VERSION);
+    header.cluster_bits = cpu_to_be32(cluster_bits);
+    header.size = cpu_to_be64(0);
+    header.l1_table_offset = cpu_to_be64(0);
+    header.l1_size = cpu_to_be32(0);
+    header.refcount_table_offset = cpu_to_be64(cluster_size);
+    header.refcount_table_clusters = cpu_to_be32(1);
+
+    if (flags & BLOCK_FLAG_ENCRYPT) {
+        header.crypt_method = cpu_to_be32(QCOW_CRYPT_AES);
+    } else {
+        header.crypt_method = cpu_to_be32(QCOW_CRYPT_NONE);
+    }
+
+    ret = bdrv_pwrite(bs, 0, &header, sizeof(header));
+    if (ret < 0) {
+        goto out;
+    }
+
+    /* Write an empty refcount table */
+    refcount_table = qemu_mallocz(cluster_size);
+    ret = bdrv_pwrite(bs, cluster_size, refcount_table, cluster_size);
+    qemu_free(refcount_table);
+
+    if (ret < 0) {
+        goto out;
+    }
+
+    bdrv_close(bs);
+
+    /*
+     * And now open the image and make it consistent first (i.e. increase the
+     * refcount of the cluster that is occupied by the header and the refcount
+     * table)
+     */
+    BlockDriver* drv = bdrv_find_format("qcow2");
+    assert(drv != NULL);
+    ret = bdrv_open(bs, filename, BDRV_O_RDWR | BDRV_O_NO_FLUSH, drv);
+    if (ret < 0) {
+        goto out;
+    }
+
+    ret = qcow2_alloc_clusters(bs, 2 * cluster_size);
+    if (ret < 0) {
+        goto out;
+
+    } else if (ret != 0) {
+        error_report("Huh, first cluster in empty image is already in use?");
+        abort();
+    }
+
+    /* Okay, now that we have a valid image, let's give it the right size */
+    ret = bdrv_truncate(bs, total_size * BDRV_SECTOR_SIZE);
+    if (ret < 0) {
+        goto out;
+    }
+
+    /* Want a backing file? There you go.*/
+    if (backing_file) {
+        ret = bdrv_change_backing_file(bs, backing_file, backing_format);
+        if (ret < 0) {
+            goto out;
+        }
+    }
+
+    /* And if we're supposed to preallocate metadata, do that now */
+    if (prealloc) {
+        ret = preallocate(bs);
+        if (ret < 0) {
+            goto out;
+        }
+    }
+
+    ret = 0;
+out:
+    bdrv_delete(bs);
+    return ret;
+}
+#endif
 
 static int qcow_create(const char *filename, QEMUOptionParameter *options)
 {
@@ -1111,7 +1242,7 @@ static int qcow_create(const char *filename, QEMUOptionParameter *options)
     }
 
     return qcow_create2(filename, sectors, backing_file, backing_fmt, flags,
-        cluster_size, prealloc);
+        cluster_size, prealloc, options);
 }
 
 static int qcow_make_empty(BlockDriverState *bs)
commit 72893756e0da74fcb626c52dfff1fc6e9de84f0c
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Mon Oct 18 16:53:53 2010 +0100

    qcow2: Support exact L1 table growth
    
    The L1 table grow operation includes a size calculation that bumps up
    the new L1 table size in order to anticipate the size needs of vmstate
    data.  This helps reduce the number of times that the L1 table has to be
    grown when vmstate data is appended.
    
    This size overhead is not necessary during image creation,
    bdrv_truncate(), or snapshot goto operations.  In fact, existing
    qemu-iotests that exercise table growth are no longer able to trigger it
    because image creation preallocates an L1 table that is too large after
    changes to qcow_create2().
    
    This patch keeps the size calculation but also adds exact growth for
    callers that do not want to inflate the L1 table size unnecessarily.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Kevin Wolf <kwolf at redhat.com>

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index fb4224a..4f7dc59 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -28,7 +28,7 @@
 #include "block_int.h"
 #include "block/qcow2.h"
 
-int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
+int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size)
 {
     BDRVQcowState *s = bs->opaque;
     int new_l1_size, new_l1_size2, ret, i;
@@ -36,15 +36,22 @@ int qcow2_grow_l1_table(BlockDriverState *bs, int min_size)
     int64_t new_l1_table_offset;
     uint8_t data[12];
 
-    new_l1_size = s->l1_size;
-    if (min_size <= new_l1_size)
+    if (min_size <= s->l1_size)
         return 0;
-    if (new_l1_size == 0) {
-        new_l1_size = 1;
-    }
-    while (min_size > new_l1_size) {
-        new_l1_size = (new_l1_size * 3 + 1) / 2;
+
+    if (exact_size) {
+        new_l1_size = min_size;
+    } else {
+        /* Bump size up to reduce the number of times we have to grow */
+        new_l1_size = s->l1_size;
+        if (new_l1_size == 0) {
+            new_l1_size = 1;
+        }
+        while (min_size > new_l1_size) {
+            new_l1_size = (new_l1_size * 3 + 1) / 2;
+        }
     }
+
 #ifdef DEBUG_ALLOC2
     printf("grow l1_table from %d to %d\n", s->l1_size, new_l1_size);
 #endif
@@ -550,7 +557,7 @@ static int get_cluster_table(BlockDriverState *bs, uint64_t offset,
 
     l1_index = offset >> (s->l2_bits + s->cluster_bits);
     if (l1_index >= s->l1_size) {
-        ret = qcow2_grow_l1_table(bs, l1_index + 1);
+        ret = qcow2_grow_l1_table(bs, l1_index + 1, false);
         if (ret < 0) {
             return ret;
         }
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index bbfcaaa..8dd5df0 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -327,7 +327,7 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
     if (qcow2_update_snapshot_refcount(bs, s->l1_table_offset, s->l1_size, -1) < 0)
         goto fail;
 
-    if (qcow2_grow_l1_table(bs, sn->l1_size) < 0)
+    if (qcow2_grow_l1_table(bs, sn->l1_size, true) < 0)
         goto fail;
 
     s->l1_size = sn->l1_size;
diff --git a/block/qcow2.c b/block/qcow2.c
index ee3481b..345d2e4 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1154,7 +1154,7 @@ static int qcow2_truncate(BlockDriverState *bs, int64_t offset)
     }
 
     new_l1_size = size_to_l1(s, offset);
-    ret = qcow2_grow_l1_table(bs, new_l1_size);
+    ret = qcow2_grow_l1_table(bs, new_l1_size, true);
     if (ret < 0) {
         return ret;
     }
diff --git a/block/qcow2.h b/block/qcow2.h
index 356a34a..add710b 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -188,7 +188,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
 int qcow2_check_refcounts(BlockDriverState *bs, BdrvCheckResult *res);
 
 /* qcow2-cluster.c functions */
-int qcow2_grow_l1_table(BlockDriverState *bs, int min_size);
+int qcow2_grow_l1_table(BlockDriverState *bs, int min_size, bool exact_size);
 void qcow2_l2_cache_reset(BlockDriverState *bs);
 int qcow2_decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset);
 void qcow2_encrypt_sectors(BDRVQcowState *s, int64_t sector_num,
commit 46c7fc182d990a373d6a9197a69ff05bba902005
Author: Kusanagi Kouichi <slash at ac.auone-net.jp>
Date:   Wed Oct 20 18:00:01 2010 +0900

    monitor: Ignore "." and ".." when completing file name.
    
    Signed-off-by: Kusanagi Kouichi <slash at ac.auone-net.jp>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/monitor.c b/monitor.c
index 260cc02..61607c5 100644
--- a/monitor.c
+++ b/monitor.c
@@ -3976,6 +3976,11 @@ static void file_completion(const char *input)
         d = readdir(ffs);
         if (!d)
             break;
+
+        if (strcmp(d->d_name, ".") == 0 || strcmp(d->d_name, "..") == 0) {
+            continue;
+        }
+
         if (strstart(d->d_name, file_prefix, NULL)) {
             memcpy(file, input, input_path_len);
             if (input_path_len < sizeof(file))
commit 945d3e6378fc639925370c62cb5e3d32b8f297c3
Author: Jan Kiszka <jan.kiszka at siemens.com>
Date:   Tue Oct 19 16:03:15 2010 +0200

    Fix test suite build with tracing enabled
    
    qemu_malloc instrumentations require linking against the trace objects.
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Acked-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/Makefile b/Makefile
index 252c817..106a401 100644
--- a/Makefile
+++ b/Makefile
@@ -140,12 +140,12 @@ qemu-img-cmds.h: $(SRC_PATH)/qemu-img-cmds.hx
 
 check-qint.o check-qstring.o check-qdict.o check-qlist.o check-qfloat.o check-qjson.o: $(GENERATED_HEADERS)
 
-check-qint: check-qint.o qint.o qemu-malloc.o
-check-qstring: check-qstring.o qstring.o qemu-malloc.o
-check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qemu-malloc.o qlist.o
-check-qlist: check-qlist.o qlist.o qint.o qemu-malloc.o
-check-qfloat: check-qfloat.o qfloat.o qemu-malloc.o
-check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o qemu-malloc.o
+check-qint: check-qint.o qint.o qemu-malloc.o $(trace-obj-y)
+check-qstring: check-qstring.o qstring.o qemu-malloc.o $(trace-obj-y)
+check-qdict: check-qdict.o qdict.o qfloat.o qint.o qstring.o qbool.o qemu-malloc.o qlist.o $(trace-obj-y)
+check-qlist: check-qlist.o qlist.o qint.o qemu-malloc.o $(trace-obj-y)
+check-qfloat: check-qfloat.o qfloat.o qemu-malloc.o $(trace-obj-y)
+check-qjson: check-qjson.o qfloat.o qint.o qdict.o qstring.o qlist.o qbool.o qjson.o json-streamer.o json-lexer.o json-parser.o qemu-malloc.o $(trace-obj-y)
 
 clean:
 # avoid old build problems by removing potentially incorrect old files
commit e7a06af838a45be4f92e655fd4628e3351a09c98
Author: Jan Kiszka <jan.kiszka at web.de>
Date:   Sat Oct 16 19:42:43 2010 +0200

    Silence compiler warning in json test case
    
    This avoids
    
        error: zero-length gnu_printf format string
    
    Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/check-qjson.c b/check-qjson.c
index 0b60e45..64fcdcb 100644
--- a/check-qjson.c
+++ b/check-qjson.c
@@ -639,7 +639,9 @@ END_TEST
 
 START_TEST(empty_input)
 {
-    QObject *obj = qobject_from_json("");
+    const char *empty = "";
+
+    QObject *obj = qobject_from_json(empty);
     fail_unless(obj == NULL);
 }
 END_TEST
commit 7af72c24aed92bfb7ebc999ddd509c3d8c8b3f83
Author: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
Date:   Thu Oct 14 09:51:02 2010 +0900

    Trivial fix for QMP/qmp-events.txt
    
    Fix example of STOP event that was just copy-and-pasted.
    
    Signed-off-by: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
    Signed-off-by: Luiz Capitulino <lcapitulino at redhat.com>

diff --git a/QMP/qmp-events.txt b/QMP/qmp-events.txt
index 01ec85f..aa20210 100644
--- a/QMP/qmp-events.txt
+++ b/QMP/qmp-events.txt
@@ -89,7 +89,7 @@ Data: None.
 
 Example:
 
-{ "event": "SHUTDOWN",
+{ "event": "STOP",
     "timestamp": { "seconds": 1267041730, "microseconds": 281295 } }
 
 VNC_CONNECTED
commit d03703c81a202cea156811e5dbc8e88627c19986
Author: Samuel Thibault <samuel.thibault at gnu.org>
Date:   Tue Oct 19 19:48:20 2010 +0200

    curses: Fix control-{@[\]^_} and ESC
    
    control-{@[\]^_} shouldn't get the 'a' - 'A' offset for correct
    translation. ESC is better simulated as escape key.
    
    Signed-off-by: Samuel Thibault <samuel.thibault at ens-lyon.org>
    Signed-off-by: Andrew Zaborowski <balrogg at gmail.com>

diff --git a/ui/curses.c b/ui/curses.c
index ed3165e..82bc614 100644
--- a/ui/curses.c
+++ b/ui/curses.c
@@ -238,9 +238,12 @@ static void curses_refresh(DisplayState *ds)
                 keysym = curses2keysym[chr];
 
             if (keysym == -1) {
-                if (chr < ' ')
-                    keysym = (chr + '@' - 'A' + 'a') | KEYSYM_CNTRL;
-                else
+                if (chr < ' ') {
+                    keysym = chr + '@';
+                    if (keysym >= 'A' && keysym <= 'Z')
+                        keysym += 'a' - 'A';
+                    keysym |= KEYSYM_CNTRL;
+                } else
                     keysym = chr;
             }
 
diff --git a/ui/curses_keys.h b/ui/curses_keys.h
index 1decd11..c0d5eb4 100644
--- a/ui/curses_keys.h
+++ b/ui/curses_keys.h
@@ -55,6 +55,7 @@ static const int curses2keysym[CURSES_KEYS] = {
     [0x7f] = KEY_BACKSPACE,
     ['\r'] = KEY_ENTER,
     ['\n'] = KEY_ENTER,
+    [27] = 27,
     [KEY_BTAB] = '\t' | KEYSYM_SHIFT,
 };
 
commit 25d2e3613d159782b66f497184ebdcf3ccb686ab
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Thu Oct 21 13:35:04 2010 -0200

    kvm: save/restore x86-64 MSRs on x86-64 kernels
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index e2f7e2e..ae0a034 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -15,6 +15,7 @@
 #include <sys/types.h>
 #include <sys/ioctl.h>
 #include <sys/mman.h>
+#include <sys/utsname.h>
 
 #include <linux/kvm.h>
 
@@ -53,6 +54,8 @@
 #define BUS_MCEERR_AO 5
 #endif
 
+static int lm_capable_kernel;
+
 #ifdef KVM_CAP_EXT_CPUID
 
 static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
@@ -523,6 +526,11 @@ int kvm_arch_init(KVMState *s, int smp_cpus)
 {
     int ret;
 
+    struct utsname utsname;
+
+    uname(&utsname);
+    lm_capable_kernel = strcmp(utsname.machine, "x86_64") == 0;
+
     /* create vm86 tss.  KVM uses vm86 mode to emulate 16-bit code
      * directly.  In order to use vm86 mode, a TSS is needed.  Since this
      * must be part of guest physical memory, we need to allocate it.  Older
@@ -810,11 +818,12 @@ static int kvm_put_msrs(CPUState *env, int level)
     if (kvm_has_msr_hsave_pa(env))
         kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave);
 #ifdef TARGET_X86_64
-    /* FIXME if lm capable */
-    kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
-    kvm_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
-    kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
-    kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
+    if (lm_capable_kernel) {
+        kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
+        kvm_msr_entry_set(&msrs[n++], MSR_KERNELGSBASE, env->kernelgsbase);
+        kvm_msr_entry_set(&msrs[n++], MSR_FMASK, env->fmask);
+        kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
+    }
 #endif
     if (level == KVM_PUT_FULL_STATE) {
         /*
@@ -1046,11 +1055,12 @@ static int kvm_get_msrs(CPUState *env)
         msrs[n++].index = MSR_VM_HSAVE_PA;
     msrs[n++].index = MSR_IA32_TSC;
 #ifdef TARGET_X86_64
-    /* FIXME lm_capable_kernel */
-    msrs[n++].index = MSR_CSTAR;
-    msrs[n++].index = MSR_KERNELGSBASE;
-    msrs[n++].index = MSR_FMASK;
-    msrs[n++].index = MSR_LSTAR;
+    if (lm_capable_kernel) {
+        msrs[n++].index = MSR_CSTAR;
+        msrs[n++].index = MSR_KERNELGSBASE;
+        msrs[n++].index = MSR_FMASK;
+        msrs[n++].index = MSR_LSTAR;
+    }
 #endif
     msrs[n++].index = MSR_KVM_SYSTEM_TIME;
     msrs[n++].index = MSR_KVM_WALL_CLOCK;
commit 384331a61a8ca42f32516ced20cb52470c5f6f57
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Thu Oct 21 13:35:03 2010 -0200

    kvm: writeback SMP TSCs on migration only
    
    commit 6389c45441269baa2873e6feafebd17105ddeaf6
    Author: Jan Kiszka <jan.kiszka at siemens.com>
    Date:   Mon Mar 1 18:17:26 2010 +0100
    
        qemu-kvm: Cleanup/fix TSC and PV clock writeback
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 06474d6..e2f7e2e 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -817,7 +817,15 @@ static int kvm_put_msrs(CPUState *env, int level)
     kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
 #endif
     if (level == KVM_PUT_FULL_STATE) {
-        kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
+        /*
+         * KVM is yet unable to synchronize TSC values of multiple VCPUs on
+         * writeback. Until this is fixed, we only write the offset to SMP
+         * guests after migration, desynchronizing the VCPUs, but avoiding
+         * huge jump-backs that would occur without any writeback at all.
+         */
+        if (smp_cpus == 1 || env->tsc != 0) {
+            kvm_msr_entry_set(&msrs[n++], MSR_IA32_TSC, env->tsc);
+        }
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_SYSTEM_TIME,
                           env->system_time_msr);
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
commit 75b10c43365e2a9cab5398f31b96a463b0d57eff
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Thu Oct 21 13:35:02 2010 -0200

    kvm: factor out kvm_has_msr_star
    
    And add kvm_has_msr_hsave_pa(), to avoid warnings on older
    kernels without support.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index e6c9a1d..06474d6 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -438,23 +438,26 @@ void kvm_arch_reset_vcpu(CPUState *env)
     }
 }
 
-static int kvm_has_msr_star(CPUState *env)
+int has_msr_star;
+int has_msr_hsave_pa;
+
+static void kvm_supported_msrs(CPUState *env)
 {
-    static int has_msr_star;
+    static int kvm_supported_msrs;
     int ret;
 
     /* first time */
-    if (has_msr_star == 0) {        
+    if (kvm_supported_msrs == 0) {
         struct kvm_msr_list msr_list, *kvm_msr_list;
 
-        has_msr_star = -1;
+        kvm_supported_msrs = -1;
 
         /* Obtain MSR list from KVM.  These are the MSRs that we must
          * save/restore */
         msr_list.nmsrs = 0;
         ret = kvm_ioctl(env->kvm_state, KVM_GET_MSR_INDEX_LIST, &msr_list);
         if (ret < 0 && ret != -E2BIG) {
-            return 0;
+            return;
         }
         /* Old kernel modules had a bug and could write beyond the provided
            memory. Allocate at least a safe amount of 1K. */
@@ -470,7 +473,11 @@ static int kvm_has_msr_star(CPUState *env)
             for (i = 0; i < kvm_msr_list->nmsrs; i++) {
                 if (kvm_msr_list->indices[i] == MSR_STAR) {
                     has_msr_star = 1;
-                    break;
+                    continue;
+                }
+                if (kvm_msr_list->indices[i] == MSR_VM_HSAVE_PA) {
+                    has_msr_hsave_pa = 1;
+                    continue;
                 }
             }
         }
@@ -478,9 +485,19 @@ static int kvm_has_msr_star(CPUState *env)
         free(kvm_msr_list);
     }
 
-    if (has_msr_star == 1)
-        return 1;
-    return 0;
+    return;
+}
+
+static int kvm_has_msr_hsave_pa(CPUState *env)
+{
+    kvm_supported_msrs(env);
+    return has_msr_hsave_pa;
+}
+
+static int kvm_has_msr_star(CPUState *env)
+{
+    kvm_supported_msrs(env);
+    return has_msr_star;
 }
 
 static int kvm_init_identity_map_page(KVMState *s)
@@ -790,7 +807,8 @@ static int kvm_put_msrs(CPUState *env, int level)
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
     if (kvm_has_msr_star(env))
 	kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
-    kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave);
+    if (kvm_has_msr_hsave_pa(env))
+        kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave);
 #ifdef TARGET_X86_64
     /* FIXME if lm capable */
     kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
@@ -1016,7 +1034,8 @@ static int kvm_get_msrs(CPUState *env)
     msrs[n++].index = MSR_IA32_SYSENTER_EIP;
     if (kvm_has_msr_star(env))
 	msrs[n++].index = MSR_STAR;
-    msrs[n++].index = MSR_VM_HSAVE_PA;
+    if (kvm_has_msr_hsave_pa(env))
+        msrs[n++].index = MSR_VM_HSAVE_PA;
     msrs[n++].index = MSR_IA32_TSC;
 #ifdef TARGET_X86_64
     /* FIXME lm_capable_kernel */
commit aa851e365b3f62ad86cf599860217b60e02dc893
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Thu Oct 21 13:35:01 2010 -0200

    kvm: add save/restore of MSR_VM_HSAVE_PA
    
    commit 2bba4446746add456ceeb0e8359a43032a2ea333
    Author: Alexander Graf <agraf at suse.de>
    Date:   Thu Dec 18 15:38:32 2008 +0100
    
        Enable nested SVM support in userspace
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 587ee19..e6c9a1d 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -790,6 +790,7 @@ static int kvm_put_msrs(CPUState *env, int level)
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_EIP, env->sysenter_eip);
     if (kvm_has_msr_star(env))
 	kvm_msr_entry_set(&msrs[n++], MSR_STAR, env->star);
+    kvm_msr_entry_set(&msrs[n++], MSR_VM_HSAVE_PA, env->vm_hsave);
 #ifdef TARGET_X86_64
     /* FIXME if lm capable */
     kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
@@ -1015,6 +1016,7 @@ static int kvm_get_msrs(CPUState *env)
     msrs[n++].index = MSR_IA32_SYSENTER_EIP;
     if (kvm_has_msr_star(env))
 	msrs[n++].index = MSR_STAR;
+    msrs[n++].index = MSR_VM_HSAVE_PA;
     msrs[n++].index = MSR_IA32_TSC;
 #ifdef TARGET_X86_64
     /* FIXME lm_capable_kernel */
@@ -1071,6 +1073,9 @@ static int kvm_get_msrs(CPUState *env)
         case MSR_IA32_TSC:
             env->tsc = msrs[i].data;
             break;
+        case MSR_VM_HSAVE_PA:
+            env->vm_hsave = msrs[i].data;
+            break;
         case MSR_KVM_SYSTEM_TIME:
             env->system_time_msr = msrs[i].data;
             break;
commit d8da8574b167144d1868f343514dfb88716e2edb
Author: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
Date:   Thu Oct 21 17:23:14 2010 +0900

    Fix build on !KVM_CAP_MCE
    
    This patch removes following warnings:
    
    target-i386/kvm.c: In function 'kvm_put_msrs':
    target-i386/kvm.c:782: error: unused variable 'i'
    target-i386/kvm.c: In function 'kvm_get_msrs':
    target-i386/kvm.c:1083: error: label at end of compound statement
    
    Signed-off-by: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 9144f74..587ee19 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -783,7 +783,7 @@ static int kvm_put_msrs(CPUState *env, int level)
         struct kvm_msr_entry entries[100];
     } msr_data;
     struct kvm_msr_entry *msrs = msr_data.entries;
-    int i, n = 0;
+    int n = 0;
 
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
@@ -805,6 +805,7 @@ static int kvm_put_msrs(CPUState *env, int level)
     }
 #ifdef KVM_CAP_MCE
     if (env->mcg_cap) {
+        int i;
         if (level == KVM_PUT_RESET_STATE)
             kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
         else if (level == KVM_PUT_FULL_STATE) {
@@ -1089,9 +1090,9 @@ static int kvm_get_msrs(CPUState *env)
             if (msrs[i].index >= MSR_MC0_CTL &&
                 msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
                 env->mce_banks[msrs[i].index - MSR_MC0_CTL] = msrs[i].data;
-                break;
             }
 #endif
+            break;
         }
     }
 
commit f71ac88fe97620f9cc80facc5e00826b8256fe5d
Author: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
Date:   Thu Oct 21 17:47:06 2010 +0900

    x86, mce: broadcast mce depending on the cpu version
    
    There is no reason why SRAO event received by the main thread
    is the only one that being broadcasted.
    
    According to the x86 ASDM vol.3A 15.10.4.1,
    MCE signal is broadcast on processor version 06H_EH or later.
    
    This change is required to handle SRAR in smp guests.
    
    Signed-off-by: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index b813953..9144f74 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -1636,6 +1636,28 @@ static void hardware_memory_error(void)
     exit(1);
 }
 
+#ifdef KVM_CAP_MCE
+static void kvm_mce_broadcast_rest(CPUState *env)
+{
+    CPUState *cenv;
+    int family, model, cpuver = env->cpuid_version;
+
+    family = (cpuver >> 8) & 0xf;
+    model = ((cpuver >> 12) & 0xf0) + ((cpuver >> 4) & 0xf);
+
+    /* Broadcast MCA signal for processor version 06H_EH and above */
+    if ((family == 6 && model >= 14) || family > 6) {
+        for (cenv = first_cpu; cenv != NULL; cenv = cenv->next_cpu) {
+            if (cenv == env) {
+                continue;
+            }
+            kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
+                               MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
+        }
+    }
+}
+#endif
+
 int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
 {
 #if defined(KVM_CAP_MCE)
@@ -1693,6 +1715,7 @@ int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
             fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
             abort();
         }
+        kvm_mce_broadcast_rest(env);
     } else
 #endif
     {
@@ -1715,7 +1738,6 @@ int kvm_on_sigbus(int code, void *addr)
         void *vaddr;
         ram_addr_t ram_addr;
         target_phys_addr_t paddr;
-        CPUState *cenv;
 
         /* Hope we are lucky for AO MCE */
         vaddr = addr;
@@ -1731,10 +1753,7 @@ int kvm_on_sigbus(int code, void *addr)
         kvm_inject_x86_mce(first_cpu, 9, status,
                            MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
                            (MCM_ADDR_PHYS << 6) | 0xc, 1);
-        for (cenv = first_cpu->next_cpu; cenv != NULL; cenv = cenv->next_cpu) {
-            kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
-                               MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
-        }
+        kvm_mce_broadcast_rest(first_cpu);
     } else
 #endif
     {
commit f8502cfbbf0bdd30603159a23d86cd19ad202a25
Author: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
Date:   Thu Oct 21 17:46:49 2010 +0900

    x86, mce: ignore SRAO only when MCG_SER_P is available
    
    And restruct this block to call kvm_mce_in_exception() only when it is
    required.
    
    Signed-off-by: Hidetoshi Seto <seto.hidetoshi at jp.fujitsu.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 512d533..b813953 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -239,12 +239,16 @@ static void kvm_do_inject_x86_mce(void *_data)
     struct kvm_x86_mce_data *data = _data;
     int r;
 
-    /* If there is an MCE excpetion being processed, ignore this SRAO MCE */
-    r = kvm_mce_in_exception(data->env);
-    if (r == -1)
-        fprintf(stderr, "Failed to get MCE status\n");
-    else if (r && !(data->mce->status & MCI_STATUS_AR))
-        return;
+    /* If there is an MCE exception being processed, ignore this SRAO MCE */
+    if ((data->env->mcg_cap & MCG_SER_P) &&
+        !(data->mce->status & MCI_STATUS_AR)) {
+        r = kvm_mce_in_exception(data->env);
+        if (r == -1) {
+            fprintf(stderr, "Failed to get MCE status\n");
+        } else if (r) {
+            return;
+        }
+    }
 
     r = kvm_set_mce(data->env, data->mce);
     if (r < 0) {
commit 633aa0acfe2c4d3e56acfe28c912796bf54de6d3
Author: Gleb Natapov <gleb at redhat.com>
Date:   Sun Oct 17 11:45:25 2010 +0200

    Fix pci hotplug to generate level triggered interrupt.
    
    SCI is level triggered. pci hotplug should behave appropriately.
    
    Signed-off-by: Gleb Natapov <gleb at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index bec42b4..f74f34c 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -107,7 +107,9 @@ static void pm_update_sci(PIIX4PMState *s)
                   (ACPI_BITMASK_RT_CLOCK_ENABLE |
                    ACPI_BITMASK_POWER_BUTTON_ENABLE |
                    ACPI_BITMASK_GLOBAL_LOCK_ENABLE |
-                   ACPI_BITMASK_TIMER_ENABLE)) != 0);
+                   ACPI_BITMASK_TIMER_ENABLE)) != 0) ||
+        (((s->gpe.sts & s->gpe.en) & PIIX4_PCI_HOTPLUG_STATUS) != 0);
+
     qemu_set_irq(s->irq, sci_level);
     /* schedule a timer interruption if needed */
     if ((s->pmen & ACPI_BITMASK_TIMER_ENABLE) &&
@@ -462,7 +464,9 @@ static uint32_t gpe_read_val(uint16_t val, uint32_t addr)
 static uint32_t gpe_readb(void *opaque, uint32_t addr)
 {
     uint32_t val = 0;
-    struct gpe_regs *g = opaque;
+    PIIX4PMState *s = opaque;
+    struct gpe_regs *g = &s->gpe;
+
     switch (addr) {
         case GPE_BASE:
         case GPE_BASE + 1:
@@ -502,7 +506,9 @@ static void gpe_reset_val(uint16_t *cur, int addr, uint32_t val)
 
 static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
 {
-    struct gpe_regs *g = opaque;
+    PIIX4PMState *s = opaque;
+    struct gpe_regs *g = &s->gpe;
+
     switch (addr) {
         case GPE_BASE:
         case GPE_BASE + 1:
@@ -514,7 +520,9 @@ static void gpe_writeb(void *opaque, uint32_t addr, uint32_t val)
             break;
         default:
             break;
-   }
+    }
+
+    pm_update_sci(s);
 
     PIIX4_DPRINTF("gpe write %x <== %d\n", addr, val);
 }
@@ -581,11 +589,10 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state);
 
 static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 {
-    struct gpe_regs *gpe = &s->gpe;
     struct pci_status *pci0_status = &s->pci0_status;
 
-    register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, gpe);
-    register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, gpe);
+    register_ioport_write(GPE_BASE, 4, 1, gpe_writeb, s);
+    register_ioport_read(GPE_BASE, 4, 1,  gpe_readb, s);
 
     register_ioport_write(PCI_BASE, 8, 4, pcihotplug_write, pci0_status);
     register_ioport_read(PCI_BASE, 8, 4,  pcihotplug_read, pci0_status);
@@ -621,9 +628,8 @@ static int piix4_device_hotplug(DeviceState *qdev, PCIDevice *dev, int state)
     } else {
         disable_device(s, slot);
     }
-    if (s->gpe.en & 2) {
-        qemu_set_irq(s->irq, 1);
-        qemu_set_irq(s->irq, 0);
-    }
+
+    pm_update_sci(s);
+
     return 0;
 }
commit 4441a2870a669b9dd0f79a040850412f3d8428ca
Author: Gleb Natapov <gleb at redhat.com>
Date:   Sun Oct 17 11:45:24 2010 +0200

    Use defines instead of numbers for pci hotplug sts bit
    
    Signed-off-by: Gleb Natapov <gleb at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/acpi_piix4.c b/hw/acpi_piix4.c
index c8733e5..bec42b4 100644
--- a/hw/acpi_piix4.c
+++ b/hw/acpi_piix4.c
@@ -38,6 +38,8 @@
 #define PCI_BASE 0xae00
 #define PCI_EJ_BASE 0xae08
 
+#define PIIX4_PCI_HOTPLUG_STATUS 2
+
 struct gpe_regs {
     uint16_t sts; /* status */
     uint16_t en;  /* enabled */
@@ -596,13 +598,13 @@ static void piix4_acpi_system_hot_add_init(PCIBus *bus, PIIX4PMState *s)
 
 static void enable_device(PIIX4PMState *s, int slot)
 {
-    s->gpe.sts |= 2;
+    s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS;
     s->pci0_status.up |= (1 << slot);
 }
 
 static void disable_device(PIIX4PMState *s, int slot)
 {
-    s->gpe.sts |= 2;
+    s->gpe.sts |= PIIX4_PCI_HOTPLUG_STATUS;
     s->pci0_status.down |= (1 << slot);
 }
 
commit 0f53994f7ad4d34e0a0a4a10cb71b2f936e25e3f
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Tue Oct 19 09:00:34 2010 -0200

    Fix memory leak in register save load due to xsave support
    
    From: Avi Kivity <avi at redhat.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 35daf90..512d533 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -660,7 +660,7 @@ static int kvm_put_fpu(CPUState *env)
 static int kvm_put_xsave(CPUState *env)
 {
 #ifdef KVM_CAP_XSAVE
-    int i;
+    int i, r;
     struct kvm_xsave* xsave;
     uint16_t cwd, swd, twd, fop;
 
@@ -685,7 +685,9 @@ static int kvm_put_xsave(CPUState *env)
     *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV] = env->xstate_bv;
     memcpy(&xsave->region[XSAVE_YMMH_SPACE], env->ymmh_regs,
             sizeof env->ymmh_regs);
-    return kvm_vcpu_ioctl(env, KVM_SET_XSAVE, xsave);
+    r = kvm_vcpu_ioctl(env, KVM_SET_XSAVE, xsave);
+    qemu_free(xsave);
+    return r;
 #else
     return kvm_put_fpu(env);
 #endif
@@ -850,8 +852,10 @@ static int kvm_get_xsave(CPUState *env)
 
     xsave = qemu_memalign(4096, sizeof(struct kvm_xsave));
     ret = kvm_vcpu_ioctl(env, KVM_GET_XSAVE, xsave);
-    if (ret < 0)
+    if (ret < 0) {
+        qemu_free(xsave);
         return ret;
+    }
 
     cwd = (uint16_t)xsave->region[0];
     swd = (uint16_t)(xsave->region[0] >> 16);
@@ -870,6 +874,7 @@ static int kvm_get_xsave(CPUState *env)
     env->xstate_bv = *(uint64_t *)&xsave->region[XSAVE_XSTATE_BV];
     memcpy(env->ymmh_regs, &xsave->region[XSAVE_YMMH_SPACE],
             sizeof env->ymmh_regs);
+    qemu_free(xsave);
     return 0;
 #else
     return kvm_get_fpu(env);
commit 577804958ae8ea40b630bc820b72c33f37b01e81
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Mon Oct 11 15:31:22 2010 -0300

    Add savevm/loadvm support for MCE
    
    Port qemu-kvm's
    
    commit 1bab5d11545d8de5facf46c28630085a2f9651ae
    Author: Huang Ying <ying.huang at intel.com>
    Date:   Wed Mar 3 16:52:46 2010 +0800
    
        Add savevm/loadvm support for MCE
    
        MCE registers are saved/load into/from CPUState in
        kvm_arch_save/load_regs. To simulate the MCG_STATUS clearing upon
        reset, MSR_MCG_STATUS is set to 0 for KVM_PUT_RESET_STATE.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 0161f6d..35daf90 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -777,7 +777,7 @@ static int kvm_put_msrs(CPUState *env, int level)
         struct kvm_msr_entry entries[100];
     } msr_data;
     struct kvm_msr_entry *msrs = msr_data.entries;
-    int n = 0;
+    int i, n = 0;
 
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_CS, env->sysenter_cs);
     kvm_msr_entry_set(&msrs[n++], MSR_IA32_SYSENTER_ESP, env->sysenter_esp);
@@ -797,6 +797,18 @@ static int kvm_put_msrs(CPUState *env, int level)
                           env->system_time_msr);
         kvm_msr_entry_set(&msrs[n++], MSR_KVM_WALL_CLOCK, env->wall_clock_msr);
     }
+#ifdef KVM_CAP_MCE
+    if (env->mcg_cap) {
+        if (level == KVM_PUT_RESET_STATE)
+            kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
+        else if (level == KVM_PUT_FULL_STATE) {
+            kvm_msr_entry_set(&msrs[n++], MSR_MCG_STATUS, env->mcg_status);
+            kvm_msr_entry_set(&msrs[n++], MSR_MCG_CTL, env->mcg_ctl);
+            for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++)
+                kvm_msr_entry_set(&msrs[n++], MSR_MC0_CTL + i, env->mce_banks[i]);
+        }
+    }
+#endif
 
     msr_data.info.nmsrs = n;
 
@@ -1004,6 +1016,15 @@ static int kvm_get_msrs(CPUState *env)
     msrs[n++].index = MSR_KVM_SYSTEM_TIME;
     msrs[n++].index = MSR_KVM_WALL_CLOCK;
 
+#ifdef KVM_CAP_MCE
+    if (env->mcg_cap) {
+        msrs[n++].index = MSR_MCG_STATUS;
+        msrs[n++].index = MSR_MCG_CTL;
+        for (i = 0; i < (env->mcg_cap & 0xff) * 4; i++)
+            msrs[n++].index = MSR_MC0_CTL + i;
+    }
+#endif
+
     msr_data.info.nmsrs = n;
     ret = kvm_vcpu_ioctl(env, KVM_GET_MSRS, &msr_data);
     if (ret < 0)
@@ -1046,6 +1067,22 @@ static int kvm_get_msrs(CPUState *env)
         case MSR_KVM_WALL_CLOCK:
             env->wall_clock_msr = msrs[i].data;
             break;
+#ifdef KVM_CAP_MCE
+        case MSR_MCG_STATUS:
+            env->mcg_status = msrs[i].data;
+            break;
+        case MSR_MCG_CTL:
+            env->mcg_ctl = msrs[i].data;
+            break;
+#endif
+        default:
+#ifdef KVM_CAP_MCE
+            if (msrs[i].index >= MSR_MC0_CTL &&
+                msrs[i].index < MSR_MC0_CTL + (env->mcg_cap & 0xff) * 4) {
+                env->mce_banks[msrs[i].index - MSR_MC0_CTL] = msrs[i].data;
+                break;
+            }
+#endif
         }
     }
 
commit c0532a76b407af4b276dc5a62d8178db59857ea6
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Mon Oct 11 15:31:21 2010 -0300

    MCE: Relay UCR MCE to guest
    
    Port qemu-kvm's
    
    commit 4b62fff1101a7ad77553147717a8bd3bf79df7ef
    Author: Huang Ying <ying.huang at intel.com>
    Date:   Mon Sep 21 10:43:25 2009 +0800
    
        MCE: Relay UCR MCE to guest
    
        UCR (uncorrected recovery) MCE is supported in recent Intel CPUs,
        where some hardware error such as some memory error can be reported
        without PCC (processor context corrupted). To recover from such MCE,
        the corresponding memory will be unmapped, and all processes accessing
        the memory will be killed via SIGBUS.
    
        For KVM, if QEMU/KVM is killed, all guest processes will be killed
        too. So we relay SIGBUS from host OS to guest system via a UCR MCE
        injection. Then guest OS can isolate corresponding memory and kill
        necessary guest processes only. SIGBUS sent to main thread (not VCPU
        threads) will be broadcast to all VCPU threads as UCR MCE.
    
    aliguori: fix build
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/cpus.c b/cpus.c
index 3875657..36a6d1f 100644
--- a/cpus.c
+++ b/cpus.c
@@ -34,6 +34,9 @@
 
 #include "cpus.h"
 #include "compatfd.h"
+#ifdef CONFIG_LINUX
+#include <sys/prctl.h>
+#endif
 
 #ifdef SIGRTMIN
 #define SIG_IPI (SIGRTMIN+4)
@@ -41,6 +44,10 @@
 #define SIG_IPI SIGUSR1
 #endif
 
+#ifndef PR_MCE_KILL
+#define PR_MCE_KILL 33
+#endif
+
 static CPUState *next_cpu;
 
 /***********************************************************/
@@ -498,28 +505,77 @@ static void qemu_tcg_wait_io_event(void)
     }
 }
 
+static void sigbus_reraise(void)
+{
+    sigset_t set;
+    struct sigaction action;
+
+    memset(&action, 0, sizeof(action));
+    action.sa_handler = SIG_DFL;
+    if (!sigaction(SIGBUS, &action, NULL)) {
+        raise(SIGBUS);
+        sigemptyset(&set);
+        sigaddset(&set, SIGBUS);
+        sigprocmask(SIG_UNBLOCK, &set, NULL);
+    }
+    perror("Failed to re-raise SIGBUS!\n");
+    abort();
+}
+
+static void sigbus_handler(int n, struct qemu_signalfd_siginfo *siginfo,
+                           void *ctx)
+{
+#if defined(TARGET_I386)
+    if (kvm_on_sigbus(siginfo->ssi_code, (void *)(intptr_t)siginfo->ssi_addr))
+#endif
+        sigbus_reraise();
+}
+
 static void qemu_kvm_eat_signal(CPUState *env, int timeout)
 {
     struct timespec ts;
     int r, e;
     siginfo_t siginfo;
     sigset_t waitset;
+    sigset_t chkset;
 
     ts.tv_sec = timeout / 1000;
     ts.tv_nsec = (timeout % 1000) * 1000000;
 
     sigemptyset(&waitset);
     sigaddset(&waitset, SIG_IPI);
+    sigaddset(&waitset, SIGBUS);
 
-    qemu_mutex_unlock(&qemu_global_mutex);
-    r = sigtimedwait(&waitset, &siginfo, &ts);
-    e = errno;
-    qemu_mutex_lock(&qemu_global_mutex);
+    do {
+        qemu_mutex_unlock(&qemu_global_mutex);
 
-    if (r == -1 && !(e == EAGAIN || e == EINTR)) {
-        fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
-        exit(1);
-    }
+        r = sigtimedwait(&waitset, &siginfo, &ts);
+        e = errno;
+
+        qemu_mutex_lock(&qemu_global_mutex);
+
+        if (r == -1 && !(e == EAGAIN || e == EINTR)) {
+            fprintf(stderr, "sigtimedwait: %s\n", strerror(e));
+            exit(1);
+        }
+
+        switch (r) {
+        case SIGBUS:
+#ifdef TARGET_I386
+            if (kvm_on_sigbus_vcpu(env, siginfo.si_code, siginfo.si_addr))
+#endif
+                sigbus_reraise();
+            break;
+        default:
+            break;
+        }
+
+        r = sigpending(&chkset);
+        if (r == -1) {
+            fprintf(stderr, "sigpending: %s\n", strerror(e));
+            exit(1);
+        }
+    } while (sigismember(&chkset, SIG_IPI) || sigismember(&chkset, SIGBUS));
 }
 
 static void qemu_kvm_wait_io_event(CPUState *env)
@@ -640,6 +696,7 @@ static void kvm_init_ipi(CPUState *env)
 
     pthread_sigmask(SIG_BLOCK, NULL, &set);
     sigdelset(&set, SIG_IPI);
+    sigdelset(&set, SIGBUS);
     r = kvm_set_signal_mask(env, &set);
     if (r) {
         fprintf(stderr, "kvm_set_signal_mask: %s\n", strerror(r));
@@ -650,6 +707,7 @@ static void kvm_init_ipi(CPUState *env)
 static sigset_t block_io_signals(void)
 {
     sigset_t set;
+    struct sigaction action;
 
     /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
@@ -660,8 +718,15 @@ static sigset_t block_io_signals(void)
     sigaddset(&set, SIGIO);
     sigaddset(&set, SIGALRM);
     sigaddset(&set, SIG_IPI);
+    sigaddset(&set, SIGBUS);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
 
+    memset(&action, 0, sizeof(action));
+    action.sa_flags = SA_SIGINFO;
+    action.sa_sigaction = (void (*)(int, siginfo_t*, void*))sigbus_handler;
+    sigaction(SIGBUS, &action, NULL);
+    prctl(PR_MCE_KILL, 1, 1, 0, 0);
+
     return set;
 }
 
diff --git a/kvm-stub.c b/kvm-stub.c
index d45f9fa..5384a4b 100644
--- a/kvm-stub.c
+++ b/kvm-stub.c
@@ -141,3 +141,8 @@ int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign)
 {
     return -ENOSYS;
 }
+
+int kvm_on_sigbus(int code, void *addr)
+{
+    return 1;
+}
diff --git a/kvm.h b/kvm.h
index b2fb3af..60a9b42 100644
--- a/kvm.h
+++ b/kvm.h
@@ -110,6 +110,9 @@ int kvm_arch_init_vcpu(CPUState *env);
 
 void kvm_arch_reset_vcpu(CPUState *env);
 
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr);
+int kvm_on_sigbus(int code, void *addr);
+
 struct kvm_guest_debug;
 struct kvm_debug_exit_arch;
 
diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 77eeab1..85ed30f 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -250,16 +250,32 @@
 #define PG_ERROR_RSVD_MASK 0x08
 #define PG_ERROR_I_D_MASK  0x10
 
-#define MCG_CTL_P	(1UL<<8)   /* MCG_CAP register available */
+#define MCG_CTL_P	(1ULL<<8)   /* MCG_CAP register available */
+#define MCG_SER_P	(1ULL<<24) /* MCA recovery/new status bits */
 
-#define MCE_CAP_DEF	MCG_CTL_P
+#define MCE_CAP_DEF	(MCG_CTL_P|MCG_SER_P)
 #define MCE_BANKS_DEF	10
 
+#define MCG_STATUS_RIPV	(1ULL<<0)   /* restart ip valid */
+#define MCG_STATUS_EIPV	(1ULL<<1)   /* ip points to correct instruction */
 #define MCG_STATUS_MCIP	(1ULL<<2)   /* machine check in progress */
 
 #define MCI_STATUS_VAL	(1ULL<<63)  /* valid error */
 #define MCI_STATUS_OVER	(1ULL<<62)  /* previous errors lost */
 #define MCI_STATUS_UC	(1ULL<<61)  /* uncorrected error */
+#define MCI_STATUS_EN	(1ULL<<60)  /* error enabled */
+#define MCI_STATUS_MISCV (1ULL<<59) /* misc error reg. valid */
+#define MCI_STATUS_ADDRV (1ULL<<58) /* addr reg. valid */
+#define MCI_STATUS_PCC	(1ULL<<57)  /* processor context corrupt */
+#define MCI_STATUS_S	(1ULL<<56)  /* Signaled machine check */
+#define MCI_STATUS_AR	(1ULL<<55)  /* Action required */
+
+/* MISC register defines */
+#define MCM_ADDR_SEGOFF	0	/* segment offset */
+#define MCM_ADDR_LINEAR	1	/* linear address */
+#define MCM_ADDR_PHYS	2	/* physical address */
+#define MCM_ADDR_MEM	3	/* memory address */
+#define MCM_ADDR_GENERIC 7	/* generic */
 
 #define MSR_IA32_TSC                    0x10
 #define MSR_IA32_APICBASE               0x1b
diff --git a/target-i386/helper.c b/target-i386/helper.c
index 4b430dd..4fff4a8 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -1032,7 +1032,7 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
         return;
 
     if (kvm_enabled()) {
-        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc, 0);
         return;
     }
 
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 343fb02..0161f6d 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -46,6 +46,13 @@
 #define MSR_KVM_WALL_CLOCK  0x11
 #define MSR_KVM_SYSTEM_TIME 0x12
 
+#ifndef BUS_MCEERR_AR
+#define BUS_MCEERR_AR 4
+#endif
+#ifndef BUS_MCEERR_AO
+#define BUS_MCEERR_AO 5
+#endif
+
 #ifdef KVM_CAP_EXT_CPUID
 
 static struct kvm_cpuid2 *try_get_cpuid(KVMState *s, int max)
@@ -192,10 +199,39 @@ static int kvm_set_mce(CPUState *env, struct kvm_x86_mce *m)
     return kvm_vcpu_ioctl(env, KVM_X86_SET_MCE, m);
 }
 
+static int kvm_get_msr(CPUState *env, struct kvm_msr_entry *msrs, int n)
+{
+    struct kvm_msrs *kmsrs = qemu_malloc(sizeof *kmsrs + n * sizeof *msrs);
+    int r;
+
+    kmsrs->nmsrs = n;
+    memcpy(kmsrs->entries, msrs, n * sizeof *msrs);
+    r = kvm_vcpu_ioctl(env, KVM_GET_MSRS, kmsrs);
+    memcpy(msrs, kmsrs->entries, n * sizeof *msrs);
+    free(kmsrs);
+    return r;
+}
+
+/* FIXME: kill this and kvm_get_msr, use env->mcg_status instead */
+static int kvm_mce_in_exception(CPUState *env)
+{
+    struct kvm_msr_entry msr_mcg_status = {
+        .index = MSR_MCG_STATUS,
+    };
+    int r;
+
+    r = kvm_get_msr(env, &msr_mcg_status, 1);
+    if (r == -1 || r == 0) {
+        return -1;
+    }
+    return !!(msr_mcg_status.data & MCG_STATUS_MCIP);
+}
+
 struct kvm_x86_mce_data
 {
     CPUState *env;
     struct kvm_x86_mce *mce;
+    int abort_on_error;
 };
 
 static void kvm_do_inject_x86_mce(void *_data)
@@ -203,14 +239,26 @@ static void kvm_do_inject_x86_mce(void *_data)
     struct kvm_x86_mce_data *data = _data;
     int r;
 
+    /* If there is an MCE excpetion being processed, ignore this SRAO MCE */
+    r = kvm_mce_in_exception(data->env);
+    if (r == -1)
+        fprintf(stderr, "Failed to get MCE status\n");
+    else if (r && !(data->mce->status & MCI_STATUS_AR))
+        return;
+
     r = kvm_set_mce(data->env, data->mce);
-    if (r < 0)
+    if (r < 0) {
         perror("kvm_set_mce FAILED");
+        if (data->abort_on_error) {
+            abort();
+        }
+    }
 }
 #endif
 
 void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
-                        uint64_t mcg_status, uint64_t addr, uint64_t misc)
+                        uint64_t mcg_status, uint64_t addr, uint64_t misc,
+                        int abort_on_error)
 {
 #ifdef KVM_CAP_MCE
     struct kvm_x86_mce mce = {
@@ -225,7 +273,15 @@ void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
             .mce = &mce,
     };
 
+    if (!cenv->mcg_cap) {
+        fprintf(stderr, "MCE support is not enabled!\n");
+        return;
+    }
+
     run_on_cpu(cenv, kvm_do_inject_x86_mce, &data);
+#else
+    if (abort_on_error)
+        abort();
 #endif
 }
 
@@ -1528,3 +1584,121 @@ bool kvm_arch_stop_on_emulation_error(CPUState *env)
               ((env->segs[R_CS].selector  & 3) != 3);
 }
 
+static void hardware_memory_error(void)
+{
+    fprintf(stderr, "Hardware memory error!\n");
+    exit(1);
+}
+
+int kvm_on_sigbus_vcpu(CPUState *env, int code, void *addr)
+{
+#if defined(KVM_CAP_MCE)
+    struct kvm_x86_mce mce = {
+            .bank = 9,
+    };
+    void *vaddr;
+    ram_addr_t ram_addr;
+    target_phys_addr_t paddr;
+    int r;
+
+    if ((env->mcg_cap & MCG_SER_P) && addr
+        && (code == BUS_MCEERR_AR
+            || code == BUS_MCEERR_AO)) {
+        if (code == BUS_MCEERR_AR) {
+            /* Fake an Intel architectural Data Load SRAR UCR */
+            mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+                | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+                | MCI_STATUS_AR | 0x134;
+            mce.misc = (MCM_ADDR_PHYS << 6) | 0xc;
+            mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_EIPV;
+        } else {
+            /*
+             * If there is an MCE excpetion being processed, ignore
+             * this SRAO MCE
+             */
+            r = kvm_mce_in_exception(env);
+            if (r == -1) {
+                fprintf(stderr, "Failed to get MCE status\n");
+            } else if (r) {
+                return 0;
+            }
+            /* Fake an Intel architectural Memory scrubbing UCR */
+            mce.status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+                | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+                | 0xc0;
+            mce.misc = (MCM_ADDR_PHYS << 6) | 0xc;
+            mce.mcg_status = MCG_STATUS_MCIP | MCG_STATUS_RIPV;
+        }
+        vaddr = (void *)addr;
+        if (qemu_ram_addr_from_host(vaddr, &ram_addr) ||
+            !kvm_physical_memory_addr_from_ram(env->kvm_state, ram_addr, &paddr)) {
+            fprintf(stderr, "Hardware memory error for memory used by "
+                    "QEMU itself instead of guest system!\n");
+            /* Hope we are lucky for AO MCE */
+            if (code == BUS_MCEERR_AO) {
+                return 0;
+            } else {
+                hardware_memory_error();
+            }
+        }
+        mce.addr = paddr;
+        r = kvm_set_mce(env, &mce);
+        if (r < 0) {
+            fprintf(stderr, "kvm_set_mce: %s\n", strerror(errno));
+            abort();
+        }
+    } else
+#endif
+    {
+        if (code == BUS_MCEERR_AO) {
+            return 0;
+        } else if (code == BUS_MCEERR_AR) {
+            hardware_memory_error();
+        } else {
+            return 1;
+        }
+    }
+    return 0;
+}
+
+int kvm_on_sigbus(int code, void *addr)
+{
+#if defined(KVM_CAP_MCE)
+    if ((first_cpu->mcg_cap & MCG_SER_P) && addr && code == BUS_MCEERR_AO) {
+        uint64_t status;
+        void *vaddr;
+        ram_addr_t ram_addr;
+        target_phys_addr_t paddr;
+        CPUState *cenv;
+
+        /* Hope we are lucky for AO MCE */
+        vaddr = addr;
+        if (qemu_ram_addr_from_host(vaddr, &ram_addr) ||
+            !kvm_physical_memory_addr_from_ram(first_cpu->kvm_state, ram_addr, &paddr)) {
+            fprintf(stderr, "Hardware memory error for memory used by "
+                    "QEMU itself instead of guest system!: %p\n", addr);
+            return 0;
+        }
+        status = MCI_STATUS_VAL | MCI_STATUS_UC | MCI_STATUS_EN
+            | MCI_STATUS_MISCV | MCI_STATUS_ADDRV | MCI_STATUS_S
+            | 0xc0;
+        kvm_inject_x86_mce(first_cpu, 9, status,
+                           MCG_STATUS_MCIP | MCG_STATUS_RIPV, paddr,
+                           (MCM_ADDR_PHYS << 6) | 0xc, 1);
+        for (cenv = first_cpu->next_cpu; cenv != NULL; cenv = cenv->next_cpu) {
+            kvm_inject_x86_mce(cenv, 1, MCI_STATUS_VAL | MCI_STATUS_UC,
+                               MCG_STATUS_MCIP | MCG_STATUS_RIPV, 0, 0, 1);
+        }
+    } else
+#endif
+    {
+        if (code == BUS_MCEERR_AO) {
+            return 0;
+        } else if (code == BUS_MCEERR_AR) {
+            hardware_memory_error();
+        } else {
+            return 1;
+        }
+    }
+    return 0;
+}
diff --git a/target-i386/kvm_x86.h b/target-i386/kvm_x86.h
index c1ebd24..04932cf 100644
--- a/target-i386/kvm_x86.h
+++ b/target-i386/kvm_x86.h
@@ -16,6 +16,7 @@
 #define __KVM_X86_H__
 
 void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
-                        uint64_t mcg_status, uint64_t addr, uint64_t misc);
+                        uint64_t mcg_status, uint64_t addr, uint64_t misc,
+                        int abort_on_error);
 
 #endif
commit 983dfc3b135de0a4808a41a8ca71e1809ba6a62e
Author: Huang Ying <ying.huang at intel.com>
Date:   Mon Oct 11 15:31:20 2010 -0300

    Add RAM -> physical addr mapping in MCE simulation
    
    In QEMU-KVM, physical address != RAM address. While MCE simulation
    needs physical address instead of RAM address. So
    kvm_physical_memory_addr_from_ram() is implemented to do the
    conversion, and it is invoked before being filled in the IA32_MCi_ADDR
    MSR.
    
    Reported-by: Dean Nelson <dnelson at redhat.com>
    Signed-off-by: Huang Ying <ying.huang at intel.com>
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/kvm-all.c b/kvm-all.c
index 1cc696f..37b99c7 100644
--- a/kvm-all.c
+++ b/kvm-all.c
@@ -137,6 +137,24 @@ static KVMSlot *kvm_lookup_overlapping_slot(KVMState *s,
     return found;
 }
 
+int kvm_physical_memory_addr_from_ram(KVMState *s, ram_addr_t ram_addr,
+                                      target_phys_addr_t *phys_addr)
+{
+    int i;
+
+    for (i = 0; i < ARRAY_SIZE(s->slots); i++) {
+        KVMSlot *mem = &s->slots[i];
+
+        if (ram_addr >= mem->phys_offset &&
+            ram_addr < mem->phys_offset + mem->memory_size) {
+            *phys_addr = mem->start_addr + (ram_addr - mem->phys_offset);
+            return 1;
+        }
+    }
+
+    return 0;
+}
+
 static int kvm_set_user_memory_region(KVMState *s, KVMSlot *slot)
 {
     struct kvm_userspace_memory_region mem;
diff --git a/kvm.h b/kvm.h
index 50b6c01..b2fb3af 100644
--- a/kvm.h
+++ b/kvm.h
@@ -174,6 +174,12 @@ static inline void cpu_synchronize_post_init(CPUState *env)
     }
 }
 
+
+#if !defined(CONFIG_USER_ONLY)
+int kvm_physical_memory_addr_from_ram(KVMState *s, ram_addr_t ram_addr,
+                                      target_phys_addr_t *phys_addr);
+#endif
+
 #endif
 int kvm_set_ioeventfd_mmio_long(int fd, uint32_t adr, uint32_t val, bool assign);
 
commit e890261f671a0573efbc024972d8769423fc82fc
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Mon Oct 11 15:31:19 2010 -0300

    Export qemu_ram_addr_from_host
    
    To be used by next patches.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/cpu-common.h b/cpu-common.h
index 0426bc8..a543b5d 100644
--- a/cpu-common.h
+++ b/cpu-common.h
@@ -47,7 +47,8 @@ void qemu_ram_free(ram_addr_t addr);
 /* This should only be used for ram local to a device.  */
 void *qemu_get_ram_ptr(ram_addr_t addr);
 /* This should not be used by devices.  */
-ram_addr_t qemu_ram_addr_from_host(void *ptr);
+int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr);
+ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr);
 
 int cpu_register_io_memory(CPUReadMemoryFunc * const *mem_read,
                            CPUWriteMemoryFunc * const *mem_write,
diff --git a/exec-all.h b/exec-all.h
index 3a53fe6..c457058 100644
--- a/exec-all.h
+++ b/exec-all.h
@@ -334,7 +334,7 @@ static inline tb_page_addr_t get_page_addr_code(CPUState *env1, target_ulong add
     }
     p = (void *)(unsigned long)addr
         + env1->tlb_table[mmu_idx][page_index].addend;
-    return qemu_ram_addr_from_host(p);
+    return qemu_ram_addr_from_host_nofail(p);
 }
 #endif
 
diff --git a/exec.c b/exec.c
index 1fbe91c..631d8c5 100644
--- a/exec.c
+++ b/exec.c
@@ -2085,7 +2085,7 @@ static inline void tlb_update_dirty(CPUTLBEntry *tlb_entry)
     if ((tlb_entry->addr_write & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
         p = (void *)(unsigned long)((tlb_entry->addr_write & TARGET_PAGE_MASK)
             + tlb_entry->addend);
-        ram_addr = qemu_ram_addr_from_host(p);
+        ram_addr = qemu_ram_addr_from_host_nofail(p);
         if (!cpu_physical_memory_is_dirty(ram_addr)) {
             tlb_entry->addr_write |= TLB_NOTDIRTY;
         }
@@ -2938,23 +2938,31 @@ void *qemu_get_ram_ptr(ram_addr_t addr)
     return NULL;
 }
 
-/* Some of the softmmu routines need to translate from a host pointer
-   (typically a TLB entry) back to a ram offset.  */
-ram_addr_t qemu_ram_addr_from_host(void *ptr)
+int qemu_ram_addr_from_host(void *ptr, ram_addr_t *ram_addr)
 {
     RAMBlock *block;
     uint8_t *host = ptr;
 
     QLIST_FOREACH(block, &ram_list.blocks, next) {
         if (host - block->host < block->length) {
-            return block->offset + (host - block->host);
+            *ram_addr = block->offset + (host - block->host);
+            return 0;
         }
     }
+    return -1;
+}
 
-    fprintf(stderr, "Bad ram pointer %p\n", ptr);
-    abort();
+/* Some of the softmmu routines need to translate from a host pointer
+   (typically a TLB entry) back to a ram offset.  */
+ram_addr_t qemu_ram_addr_from_host_nofail(void *ptr)
+{
+    ram_addr_t ram_addr;
 
-    return 0;
+    if (qemu_ram_addr_from_host(ptr, &ram_addr)) {
+        fprintf(stderr, "Bad ram pointer %p\n", ptr);
+        abort();
+    }
+    return ram_addr;
 }
 
 static uint32_t unassigned_mem_readb(void *opaque, target_phys_addr_t addr)
@@ -3703,7 +3711,7 @@ void cpu_physical_memory_unmap(void *buffer, target_phys_addr_t len,
 {
     if (buffer != bounce.buffer) {
         if (is_write) {
-            ram_addr_t addr1 = qemu_ram_addr_from_host(buffer);
+            ram_addr_t addr1 = qemu_ram_addr_from_host_nofail(buffer);
             while (access_len) {
                 unsigned l;
                 l = TARGET_PAGE_SIZE;
commit e7701825e17d74913b0f1585d523cedaf1d6632a
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Mon Oct 11 15:31:18 2010 -0300

    kvm: x86: add mce support
    
    Port qemu-kvm's MCE support
    
    commit c68b2374c9048812f488e00ffb95db66c0bc07a7
    Author: Huang Ying <ying.huang at intel.com>
    Date:   Mon Jul 20 10:00:53 2009 +0800
    
        Add MCE simulation support to qemu/kvm
    
        KVM ioctls are used to initialize MCE simulation and inject MCE. The
        real MCE simulation is implemented in Linux kernel. The Kernel part
        has been merged.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/target-i386/helper.c b/target-i386/helper.c
index e134340..4b430dd 100644
--- a/target-i386/helper.c
+++ b/target-i386/helper.c
@@ -27,6 +27,7 @@
 #include "exec-all.h"
 #include "qemu-common.h"
 #include "kvm.h"
+#include "kvm_x86.h"
 
 //#define DEBUG_MMU
 
@@ -1030,6 +1031,11 @@ void cpu_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
     if (bank >= bank_num || !(status & MCI_STATUS_VAL))
         return;
 
+    if (kvm_enabled()) {
+        kvm_inject_x86_mce(cenv, bank, status, mcg_status, addr, misc);
+        return;
+    }
+
     /*
      * if MSR_MCG_CTL is not all 1s, the uncorrected error
      * reporting is disabled
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index 74e7b4f..343fb02 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -27,6 +27,7 @@
 #include "hw/pc.h"
 #include "hw/apic.h"
 #include "ioport.h"
+#include "kvm_x86.h"
 
 #ifdef CONFIG_KVM_PARA
 #include <linux/kvm_para.h>
@@ -167,6 +168,67 @@ static int get_para_features(CPUState *env)
 }
 #endif
 
+#ifdef KVM_CAP_MCE
+static int kvm_get_mce_cap_supported(KVMState *s, uint64_t *mce_cap,
+                                     int *max_banks)
+{
+    int r;
+
+    r = kvm_ioctl(s, KVM_CHECK_EXTENSION, KVM_CAP_MCE);
+    if (r > 0) {
+        *max_banks = r;
+        return kvm_ioctl(s, KVM_X86_GET_MCE_CAP_SUPPORTED, mce_cap);
+    }
+    return -ENOSYS;
+}
+
+static int kvm_setup_mce(CPUState *env, uint64_t *mcg_cap)
+{
+    return kvm_vcpu_ioctl(env, KVM_X86_SETUP_MCE, mcg_cap);
+}
+
+static int kvm_set_mce(CPUState *env, struct kvm_x86_mce *m)
+{
+    return kvm_vcpu_ioctl(env, KVM_X86_SET_MCE, m);
+}
+
+struct kvm_x86_mce_data
+{
+    CPUState *env;
+    struct kvm_x86_mce *mce;
+};
+
+static void kvm_do_inject_x86_mce(void *_data)
+{
+    struct kvm_x86_mce_data *data = _data;
+    int r;
+
+    r = kvm_set_mce(data->env, data->mce);
+    if (r < 0)
+        perror("kvm_set_mce FAILED");
+}
+#endif
+
+void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+                        uint64_t mcg_status, uint64_t addr, uint64_t misc)
+{
+#ifdef KVM_CAP_MCE
+    struct kvm_x86_mce mce = {
+        .bank = bank,
+        .status = status,
+        .mcg_status = mcg_status,
+        .addr = addr,
+        .misc = misc,
+    };
+    struct kvm_x86_mce_data data = {
+            .env = cenv,
+            .mce = &mce,
+    };
+
+    run_on_cpu(cenv, kvm_do_inject_x86_mce, &data);
+#endif
+}
+
 int kvm_arch_init_vcpu(CPUState *env)
 {
     struct {
@@ -277,6 +339,28 @@ int kvm_arch_init_vcpu(CPUState *env)
 
     cpuid_data.cpuid.nent = cpuid_i;
 
+#ifdef KVM_CAP_MCE
+    if (((env->cpuid_version >> 8)&0xF) >= 6
+        && (env->cpuid_features&(CPUID_MCE|CPUID_MCA)) == (CPUID_MCE|CPUID_MCA)
+        && kvm_check_extension(env->kvm_state, KVM_CAP_MCE) > 0) {
+        uint64_t mcg_cap;
+        int banks;
+
+        if (kvm_get_mce_cap_supported(env->kvm_state, &mcg_cap, &banks))
+            perror("kvm_get_mce_cap_supported FAILED");
+        else {
+            if (banks > MCE_BANKS_DEF)
+                banks = MCE_BANKS_DEF;
+            mcg_cap &= MCE_CAP_DEF;
+            mcg_cap |= banks;
+            if (kvm_setup_mce(env, &mcg_cap))
+                perror("kvm_setup_mce FAILED");
+            else
+                env->mcg_cap = mcg_cap;
+        }
+    }
+#endif
+
     return kvm_vcpu_ioctl(env, KVM_SET_CPUID2, &cpuid_data);
 }
 
diff --git a/target-i386/kvm_x86.h b/target-i386/kvm_x86.h
new file mode 100644
index 0000000..c1ebd24
--- /dev/null
+++ b/target-i386/kvm_x86.h
@@ -0,0 +1,21 @@
+/*
+ * QEMU KVM support
+ *
+ * Copyright (C) 2009 Red Hat Inc.
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori at us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
+ * See the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef __KVM_X86_H__
+#define __KVM_X86_H__
+
+void kvm_inject_x86_mce(CPUState *cenv, int bank, uint64_t status,
+                        uint64_t mcg_status, uint64_t addr, uint64_t misc);
+
+#endif
commit a8486bc9c91a10c9190bbd577f6f02b9eb515d90
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Mon Oct 11 15:31:16 2010 -0300

    iothread: use signalfd
    
    Block SIGALRM, SIGIO and consume them via signalfd.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/cpus.c b/cpus.c
index b09f5e3..3875657 100644
--- a/cpus.c
+++ b/cpus.c
@@ -33,6 +33,7 @@
 #include "exec-all.h"
 
 #include "cpus.h"
+#include "compatfd.h"
 
 #ifdef SIGRTMIN
 #define SIG_IPI (SIGRTMIN+4)
@@ -329,14 +330,75 @@ static QemuCond qemu_work_cond;
 
 static void tcg_init_ipi(void);
 static void kvm_init_ipi(CPUState *env);
-static void unblock_io_signals(void);
+static sigset_t block_io_signals(void);
+
+/* If we have signalfd, we mask out the signals we want to handle and then
+ * use signalfd to listen for them.  We rely on whatever the current signal
+ * handler is to dispatch the signals when we receive them.
+ */
+static void sigfd_handler(void *opaque)
+{
+    int fd = (unsigned long) opaque;
+    struct qemu_signalfd_siginfo info;
+    struct sigaction action;
+    ssize_t len;
+
+    while (1) {
+        do {
+            len = read(fd, &info, sizeof(info));
+        } while (len == -1 && errno == EINTR);
+
+        if (len == -1 && errno == EAGAIN) {
+            break;
+        }
+
+        if (len != sizeof(info)) {
+            printf("read from sigfd returned %zd: %m\n", len);
+            return;
+        }
+
+        sigaction(info.ssi_signo, NULL, &action);
+        if ((action.sa_flags & SA_SIGINFO) && action.sa_sigaction) {
+            action.sa_sigaction(info.ssi_signo,
+                                (siginfo_t *)&info, NULL);
+        } else if (action.sa_handler) {
+            action.sa_handler(info.ssi_signo);
+        }
+    }
+}
+
+static int qemu_signalfd_init(sigset_t mask)
+{
+    int sigfd;
+
+    sigfd = qemu_signalfd(&mask);
+    if (sigfd == -1) {
+        fprintf(stderr, "failed to create signalfd\n");
+        return -errno;
+    }
+
+    fcntl_setfl(sigfd, O_NONBLOCK);
+
+    qemu_set_fd_handler2(sigfd, NULL, sigfd_handler, NULL,
+                         (void *)(unsigned long) sigfd);
+
+    return 0;
+}
 
 int qemu_init_main_loop(void)
 {
     int ret;
+    sigset_t blocked_signals;
 
     cpu_set_debug_excp_handler(cpu_debug_handler);
 
+    blocked_signals = block_io_signals();
+
+    ret = qemu_signalfd_init(blocked_signals);
+    if (ret)
+        return ret;
+
+    /* Note eventfd must be drained before signalfd handlers run */
     ret = qemu_event_init();
     if (ret)
         return ret;
@@ -347,7 +409,6 @@ int qemu_init_main_loop(void)
     qemu_mutex_init(&qemu_global_mutex);
     qemu_mutex_lock(&qemu_global_mutex);
 
-    unblock_io_signals();
     qemu_thread_self(&io_thread);
 
     return 0;
@@ -586,19 +647,22 @@ static void kvm_init_ipi(CPUState *env)
     }
 }
 
-static void unblock_io_signals(void)
+static sigset_t block_io_signals(void)
 {
     sigset_t set;
 
+    /* SIGUSR2 used by posix-aio-compat.c */
     sigemptyset(&set);
     sigaddset(&set, SIGUSR2);
-    sigaddset(&set, SIGIO);
-    sigaddset(&set, SIGALRM);
     pthread_sigmask(SIG_UNBLOCK, &set, NULL);
 
     sigemptyset(&set);
+    sigaddset(&set, SIGIO);
+    sigaddset(&set, SIGALRM);
     sigaddset(&set, SIG_IPI);
     pthread_sigmask(SIG_BLOCK, &set, NULL);
+
+    return set;
 }
 
 void qemu_mutex_lock_iothread(void)
commit dcc38d1cce61e7d986e74dcd9bff2a5efc53a87c
Author: Marcelo Tosatti <mtosatti at redhat.com>
Date:   Mon Oct 11 15:31:15 2010 -0300

    signalfd compatibility
    
    Port qemu-kvm's signalfd compat code.
    
    commit 5a7fdd0abd7cd24dac205317a4195446ab8748b5
    Author: Anthony Liguori <aliguori at us.ibm.com>
    Date:   Wed May 7 11:55:47 2008 -0500
    
        Use signalfd() in io-thread
    
        This patch reworks the IO thread to use signalfd() instead of sigtimedwait()
        This will eliminate the need to use SIGIO everywhere.
    
    Signed-off-by: Marcelo Tosatti <mtosatti at redhat.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/Makefile.objs b/Makefile.objs
index cd5a24b..6e6f60a 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -125,6 +125,7 @@ common-obj-y += $(addprefix ui/, $(ui-obj-y))
 
 common-obj-y += iov.o acl.o
 common-obj-$(CONFIG_THREAD) += qemu-thread.o
+common-obj-$(CONFIG_IOTHREAD) += compatfd.o
 common-obj-y += notify.o event_notifier.o
 common-obj-y += qemu-timer.o
 
diff --git a/compatfd.c b/compatfd.c
new file mode 100644
index 0000000..a7cebc4
--- /dev/null
+++ b/compatfd.c
@@ -0,0 +1,117 @@
+/*
+ * signalfd/eventfd compatibility
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori at us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "qemu-common.h"
+#include "compatfd.h"
+
+#include <sys/syscall.h>
+#include <pthread.h>
+
+struct sigfd_compat_info
+{
+    sigset_t mask;
+    int fd;
+};
+
+static void *sigwait_compat(void *opaque)
+{
+    struct sigfd_compat_info *info = opaque;
+    int err;
+    sigset_t all;
+
+    sigfillset(&all);
+    sigprocmask(SIG_BLOCK, &all, NULL);
+
+    do {
+        siginfo_t siginfo;
+
+        err = sigwaitinfo(&info->mask, &siginfo);
+        if (err == -1 && errno == EINTR) {
+            err = 0;
+            continue;
+        }
+
+        if (err > 0) {
+            char buffer[128];
+            size_t offset = 0;
+
+            memcpy(buffer, &err, sizeof(err));
+            while (offset < sizeof(buffer)) {
+                ssize_t len;
+
+                len = write(info->fd, buffer + offset,
+                            sizeof(buffer) - offset);
+                if (len == -1 && errno == EINTR)
+                    continue;
+
+                if (len <= 0) {
+                    err = -1;
+                    break;
+                }
+
+                offset += len;
+            }
+        }
+    } while (err >= 0);
+
+    return NULL;
+}
+
+static int qemu_signalfd_compat(const sigset_t *mask)
+{
+    pthread_attr_t attr;
+    pthread_t tid;
+    struct sigfd_compat_info *info;
+    int fds[2];
+
+    info = malloc(sizeof(*info));
+    if (info == NULL) {
+        errno = ENOMEM;
+        return -1;
+    }
+
+    if (pipe(fds) == -1) {
+        free(info);
+        return -1;
+    }
+
+    qemu_set_cloexec(fds[0]);
+    qemu_set_cloexec(fds[1]);
+
+    memcpy(&info->mask, mask, sizeof(*mask));
+    info->fd = fds[1];
+
+    pthread_attr_init(&attr);
+    pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+    pthread_create(&tid, &attr, sigwait_compat, info);
+
+    pthread_attr_destroy(&attr);
+
+    return fds[0];
+}
+
+int qemu_signalfd(const sigset_t *mask)
+{
+#if defined(CONFIG_SIGNALFD)
+    int ret;
+
+    ret = syscall(SYS_signalfd, -1, mask, _NSIG / 8);
+    if (ret != -1) {
+        qemu_set_cloexec(ret);
+        return ret;
+    }
+#endif
+
+    return qemu_signalfd_compat(mask);
+}
diff --git a/compatfd.h b/compatfd.h
new file mode 100644
index 0000000..fc37915
--- /dev/null
+++ b/compatfd.h
@@ -0,0 +1,43 @@
+/*
+ * signalfd/eventfd compatibility
+ *
+ * Copyright IBM, Corp. 2008
+ *
+ * Authors:
+ *  Anthony Liguori   <aliguori at us.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#ifndef QEMU_COMPATFD_H
+#define QEMU_COMPATFD_H
+
+#include <signal.h>
+
+struct qemu_signalfd_siginfo {
+    uint32_t ssi_signo;   /* Signal number */
+    int32_t  ssi_errno;   /* Error number (unused) */
+    int32_t  ssi_code;    /* Signal code */
+    uint32_t ssi_pid;     /* PID of sender */
+    uint32_t ssi_uid;     /* Real UID of sender */
+    int32_t  ssi_fd;      /* File descriptor (SIGIO) */
+    uint32_t ssi_tid;     /* Kernel timer ID (POSIX timers) */
+    uint32_t ssi_band;    /* Band event (SIGIO) */
+    uint32_t ssi_overrun; /* POSIX timer overrun count */
+    uint32_t ssi_trapno;  /* Trap number that caused signal */
+    int32_t  ssi_status;  /* Exit status or signal (SIGCHLD) */
+    int32_t  ssi_int;     /* Integer sent by sigqueue(2) */
+    uint64_t ssi_ptr;     /* Pointer sent by sigqueue(2) */
+    uint64_t ssi_utime;   /* User CPU time consumed (SIGCHLD) */
+    uint64_t ssi_stime;   /* System CPU time consumed (SIGCHLD) */
+    uint64_t ssi_addr;    /* Address that generated signal
+                             (for hardware-generated signals) */
+    uint8_t  pad[48];     /* Pad size to 128 bytes (allow for
+                             additional fields in the future) */
+};
+
+int qemu_signalfd(const sigset_t *mask);
+
+#endif
diff --git a/configure b/configure
index 5f4d718..9ed05de 100755
--- a/configure
+++ b/configure
@@ -1957,6 +1957,21 @@ if compile_prog "" "" ; then
   splice=yes
 fi
 
+##########################################
+# signalfd probe
+signalfd="no"
+cat > $TMPC << EOF
+#define _GNU_SOURCE
+#include <unistd.h>
+#include <sys/syscall.h>
+#include <signal.h>
+int main(void) { return syscall(SYS_signalfd, -1, NULL, _NSIG / 8); }
+EOF
+
+if compile_prog "" "" ; then
+  signalfd=yes
+fi
+
 # check if eventfd is supported
 eventfd=no
 cat > $TMPC << EOF
@@ -2559,6 +2574,9 @@ fi
 if test "$fdt" = "yes" ; then
   echo "CONFIG_FDT=y" >> $config_host_mak
 fi
+if test "$signalfd" = "yes" ; then
+  echo "CONFIG_SIGNALFD=y" >> $config_host_mak
+fi
 if test "$need_offsetof" = "yes" ; then
   echo "CONFIG_NEED_OFFSETOF=y" >> $config_host_mak
 fi
commit 296acb643b0f7ec3ab3d8c4a8fc48039d9269818
Author: Joerg Roedel <joerg.roedel at amd.com>
Date:   Mon Sep 27 15:16:17 2010 +0200

    Add svm cpuid features
    
    This patch adds the svm cpuid feature flags to the qemu
    intialization path. It also adds the svm features available
    on phenom to its cpu-definition and extends the host cpu
    type to support all svm features KVM can provide.
    
    Signed-off-by: Joerg Roedel <joerg.roedel at amd.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/target-i386/cpu.h b/target-i386/cpu.h
index 1144d4e..77eeab1 100644
--- a/target-i386/cpu.h
+++ b/target-i386/cpu.h
@@ -405,6 +405,17 @@
 #define CPUID_EXT3_IBS     (1 << 10)
 #define CPUID_EXT3_SKINIT  (1 << 12)
 
+#define CPUID_SVM_NPT          (1 << 0)
+#define CPUID_SVM_LBRV         (1 << 1)
+#define CPUID_SVM_SVMLOCK      (1 << 2)
+#define CPUID_SVM_NRIPSAVE     (1 << 3)
+#define CPUID_SVM_TSCSCALE     (1 << 4)
+#define CPUID_SVM_VMCBCLEAN    (1 << 5)
+#define CPUID_SVM_FLUSHASID    (1 << 6)
+#define CPUID_SVM_DECODEASSIST (1 << 7)
+#define CPUID_SVM_PAUSEFILTER  (1 << 10)
+#define CPUID_SVM_PFTHRESHOLD  (1 << 12)
+
 #define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
 #define CPUID_VENDOR_INTEL_2 0x49656e69 /* "ineI" */
 #define CPUID_VENDOR_INTEL_3 0x6c65746e /* "ntel" */
@@ -702,6 +713,7 @@ typedef struct CPUX86State {
     uint8_t has_error_code;
     uint32_t sipi_vector;
     uint32_t cpuid_kvm_features;
+    uint32_t cpuid_svm_features;
     
     /* in order to simplify APIC support, we leave this pointer to the
        user */
diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 3fcf78f..0e0bf60 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -79,6 +79,17 @@ static const char *kvm_feature_name[] = {
     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
 };
 
+static const char *svm_feature_name[] = {
+    "npt", "lbrv", "svm_lock", "nrip_save",
+    "tsc_scale", "vmcb_clean",  "flushbyasid", "decodeassists",
+    NULL, NULL, "pause_filter", NULL,
+    "pfthreshold", NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+    NULL, NULL, NULL, NULL,
+};
+
 /* collects per-function cpuid data
  */
 typedef struct model_features_t {
@@ -192,13 +203,15 @@ static void add_flagname_to_bitmaps(const char *flagname, uint32_t *features,
                                     uint32_t *ext_features,
                                     uint32_t *ext2_features,
                                     uint32_t *ext3_features,
-                                    uint32_t *kvm_features)
+                                    uint32_t *kvm_features,
+                                    uint32_t *svm_features)
 {
     if (!lookup_feature(features, flagname, NULL, feature_name) &&
         !lookup_feature(ext_features, flagname, NULL, ext_feature_name) &&
         !lookup_feature(ext2_features, flagname, NULL, ext2_feature_name) &&
         !lookup_feature(ext3_features, flagname, NULL, ext3_feature_name) &&
-        !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name))
+        !lookup_feature(kvm_features, flagname, NULL, kvm_feature_name) &&
+        !lookup_feature(svm_features, flagname, NULL, svm_feature_name))
             fprintf(stderr, "CPU feature %s not found\n", flagname);
 }
 
@@ -210,7 +223,8 @@ typedef struct x86_def_t {
     int family;
     int model;
     int stepping;
-    uint32_t features, ext_features, ext2_features, ext3_features, kvm_features;
+    uint32_t features, ext_features, ext2_features, ext3_features;
+    uint32_t kvm_features, svm_features;
     uint32_t xlevel;
     char model_id[48];
     int vendor_override;
@@ -253,6 +267,7 @@ typedef struct x86_def_t {
           CPUID_EXT2_PDPE1GB */
 #define TCG_EXT3_FEATURES (CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM | \
           CPUID_EXT3_CR8LEG | CPUID_EXT3_ABM | CPUID_EXT3_SSE4A)
+#define TCG_SVM_FEATURES 0
 
 /* maintains list of cpu model definitions
  */
@@ -305,6 +320,7 @@ static x86_def_t builtin_x86_defs[] = {
                     CPUID_EXT3_OSVW, CPUID_EXT3_IBS */
         .ext3_features = CPUID_EXT3_LAHF_LM | CPUID_EXT3_SVM |
             CPUID_EXT3_ABM | CPUID_EXT3_SSE4A,
+        .svm_features = CPUID_SVM_NPT | CPUID_SVM_LBRV,
         .xlevel = 0x8000001A,
         .model_id = "AMD Phenom(tm) 9550 Quad-Core Processor"
     },
@@ -505,6 +521,15 @@ static int cpu_x86_fill_host(x86_def_t *x86_cpu_def)
     cpu_x86_fill_model_id(x86_cpu_def->model_id);
     x86_cpu_def->vendor_override = 0;
 
+
+    /*
+     * Every SVM feature requires emulation support in KVM - so we can't just
+     * read the host features here. KVM might even support SVM features not
+     * available on the host hardware. Just set all bits and mask out the
+     * unsupported ones later.
+     */
+    x86_cpu_def->svm_features = -1;
+
     return 0;
 }
 
@@ -560,8 +585,14 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
 
     char *s = strdup(cpu_model);
     char *featurestr, *name = strtok(s, ",");
-    uint32_t plus_features = 0, plus_ext_features = 0, plus_ext2_features = 0, plus_ext3_features = 0, plus_kvm_features = 0;
-    uint32_t minus_features = 0, minus_ext_features = 0, minus_ext2_features = 0, minus_ext3_features = 0, minus_kvm_features = 0;
+    /* Features to be added*/
+    uint32_t plus_features = 0, plus_ext_features = 0;
+    uint32_t plus_ext2_features = 0, plus_ext3_features = 0;
+    uint32_t plus_kvm_features = 0, plus_svm_features = 0;
+    /* Features to be removed */
+    uint32_t minus_features = 0, minus_ext_features = 0;
+    uint32_t minus_ext2_features = 0, minus_ext3_features = 0;
+    uint32_t minus_kvm_features = 0, minus_svm_features = 0;
     uint32_t numvalue;
 
     for (def = x86_defs; def; def = def->next)
@@ -579,16 +610,22 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
 
     add_flagname_to_bitmaps("hypervisor", &plus_features,
         &plus_ext_features, &plus_ext2_features, &plus_ext3_features,
-        &plus_kvm_features);
+        &plus_kvm_features, &plus_svm_features);
 
     featurestr = strtok(NULL, ",");
 
     while (featurestr) {
         char *val;
         if (featurestr[0] == '+') {
-            add_flagname_to_bitmaps(featurestr + 1, &plus_features, &plus_ext_features, &plus_ext2_features, &plus_ext3_features, &plus_kvm_features);
+            add_flagname_to_bitmaps(featurestr + 1, &plus_features,
+                            &plus_ext_features, &plus_ext2_features,
+                            &plus_ext3_features, &plus_kvm_features,
+                            &plus_svm_features);
         } else if (featurestr[0] == '-') {
-            add_flagname_to_bitmaps(featurestr + 1, &minus_features, &minus_ext_features, &minus_ext2_features, &minus_ext3_features, &minus_kvm_features);
+            add_flagname_to_bitmaps(featurestr + 1, &minus_features,
+                            &minus_ext_features, &minus_ext2_features,
+                            &minus_ext3_features, &minus_kvm_features,
+                            &minus_svm_features);
         } else if ((val = strchr(featurestr, '='))) {
             *val = 0; val++;
             if (!strcmp(featurestr, "family")) {
@@ -670,11 +707,13 @@ static int cpu_x86_find_by_name(x86_def_t *x86_cpu_def, const char *cpu_model)
     x86_cpu_def->ext2_features |= plus_ext2_features;
     x86_cpu_def->ext3_features |= plus_ext3_features;
     x86_cpu_def->kvm_features |= plus_kvm_features;
+    x86_cpu_def->svm_features |= plus_svm_features;
     x86_cpu_def->features &= ~minus_features;
     x86_cpu_def->ext_features &= ~minus_ext_features;
     x86_cpu_def->ext2_features &= ~minus_ext2_features;
     x86_cpu_def->ext3_features &= ~minus_ext3_features;
     x86_cpu_def->kvm_features &= ~minus_kvm_features;
+    x86_cpu_def->svm_features &= ~minus_svm_features;
     if (check_cpuid) {
         if (check_features_against_host(x86_cpu_def) && enforce_cpuid)
             goto error;
@@ -816,6 +855,7 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
     env->cpuid_ext3_features = def->ext3_features;
     env->cpuid_xlevel = def->xlevel;
     env->cpuid_kvm_features = def->kvm_features;
+    env->cpuid_svm_features = def->svm_features;
     if (!kvm_enabled()) {
         env->cpuid_features &= TCG_FEATURES;
         env->cpuid_ext_features &= TCG_EXT_FEATURES;
@@ -825,6 +865,7 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
 #endif
             );
         env->cpuid_ext3_features &= TCG_EXT3_FEATURES;
+        env->cpuid_svm_features &= TCG_SVM_FEATURES;
     }
     {
         const char *model_id = def->model_id;
@@ -1135,11 +1176,6 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
                 *ecx |= 1 << 1;    /* CmpLegacy bit */
             }
         }
-
-        if (kvm_enabled()) {
-            /* Nested SVM not yet supported in upstream QEMU */
-            *ecx &= ~CPUID_EXT3_SVM;
-        }
         break;
     case 0x80000002:
     case 0x80000003:
@@ -1184,10 +1220,17 @@ void cpu_x86_cpuid(CPUX86State *env, uint32_t index, uint32_t count,
         }
         break;
     case 0x8000000A:
-        *eax = 0x00000001; /* SVM Revision */
-        *ebx = 0x00000010; /* nr of ASIDs */
-        *ecx = 0;
-        *edx = 0; /* optional features */
+	if (env->cpuid_ext3_features & CPUID_EXT3_SVM) {
+		*eax = 0x00000001; /* SVM Revision */
+		*ebx = 0x00000010; /* nr of ASIDs */
+		*ecx = 0;
+		*edx = env->cpuid_svm_features; /* optional features */
+	} else {
+		*eax = 0;
+		*ebx = 0;
+		*ecx = 0;
+		*edx = 0;
+	}
         break;
     default:
         /* reserved values: zero */
diff --git a/target-i386/kvm.c b/target-i386/kvm.c
index a33d2fa..74e7b4f 100644
--- a/target-i386/kvm.c
+++ b/target-i386/kvm.c
@@ -192,6 +192,9 @@ int kvm_arch_init_vcpu(CPUState *env)
                                                              0, R_EDX);
     env->cpuid_ext3_features &= kvm_arch_get_supported_cpuid(env, 0x80000001,
                                                              0, R_ECX);
+    env->cpuid_svm_features  &= kvm_arch_get_supported_cpuid(env, 0x8000000A,
+                                                             0, R_EDX);
+
 
     cpuid_i = 0;
 
commit db0ad1ba047b59cb89865008dcd0edd301e84c37
Author: Joerg Roedel <joerg.roedel at amd.com>
Date:   Mon Sep 27 15:16:16 2010 +0200

    Set cpuid definition to 0 before initializing it
    
    This patch cleans the (stack-allocated) cpuid definition to
    0 before actually initializing it.
    
    Signed-off-by: Joerg Roedel <joerg.roedel at amd.com>
    Signed-off-by: Avi Kivity <avi at redhat.com>

diff --git a/target-i386/cpuid.c b/target-i386/cpuid.c
index 04ba8d5..3fcf78f 100644
--- a/target-i386/cpuid.c
+++ b/target-i386/cpuid.c
@@ -788,6 +788,8 @@ int cpu_x86_register (CPUX86State *env, const char *cpu_model)
 {
     x86_def_t def1, *def = &def1;
 
+    memset(def, 0, sizeof(*def));
+
     if (cpu_x86_find_by_name(def, cpu_model) < 0)
         return -1;
     if (def->vendor1) {
commit 1e027be7e91d854d7a0132e4a32bdf222c33dcfe
Author: Markus Armbruster <armbru at redhat.com>
Date:   Thu Oct 14 11:19:04 2010 +0200

    configure: Support disabling warnings in $gcc_flags
    
    -Wall enables a bunch of warnings at once.  configure puts it after
    $gcc_flags.  This makes it impossible to disable warnings enabled by
    -Wall there.  Fix by putting configured flags last.
    
    Signed-off-by: Markus Armbruster <armbru at redhat.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/configure b/configure
index a079a49..5f4d718 100755
--- a/configure
+++ b/configure
@@ -154,7 +154,7 @@ int main(void) { return 0; }
 EOF
 for flag in $gcc_flags; do
     if compile_prog "-Werror $QEMU_CFLAGS" "-Werror $flag" ; then
-	QEMU_CFLAGS="$flag $QEMU_CFLAGS"
+	QEMU_CFLAGS="$QEMU_CFLAGS $flag"
     fi
 done
 
commit c3b08d0e05f381b0a02647038d454eecf51ae014
Author: Stefan Weil <weil at mail.berlios.de>
Date:   Fri Oct 8 10:32:23 2010 +0200

    tcg: Fix compiler error (comparison of unsigned expression)
    
    When qemu is configured with --enable-debug-tcg,
    gcc throws this warning (or error with -Werror):
    
    tcg/tcg.c:1030: error: comparison of unsigned expression >= 0 is always true
    
    Fix it by removing the >= 0 part.
    The type cast to 'unsigned' catches negative values of op
    (which should never happen).
    
    This is a modification of Hollis Blanchard's patch.
    
    Cc: Hollis Blanchard <hollis at penguinppc.org>
    Cc: Blue Swirl <blauwirbel at gmail.com>
    Signed-off-by: Stefan Weil <weil at mail.berlios.de>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/tcg/tcg.c b/tcg/tcg.c
index e0a9030..0cdef0d 100644
--- a/tcg/tcg.c
+++ b/tcg/tcg.c
@@ -1027,7 +1027,7 @@ void tcg_add_target_add_op_defs(const TCGTargetOpDef *tdefs)
         if (tdefs->op == (TCGOpcode)-1)
             break;
         op = tdefs->op;
-        assert(op >= 0 && op < NB_OPS);
+        assert((unsigned)op < NB_OPS);
         def = &tcg_op_defs[op];
 #if defined(CONFIG_DEBUG_TCG)
         /* Duplicate entry in op definitions? */
commit b2d4d8329963b13c5cebe5944dcc99f0e9d1b5c7
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Oct 8 12:30:14 2010 +0200

    wacom tablet: activate event handlers.
    
    Add qemu_activate_mouse_event_handler() calls to the usb wavom tablet so
    it actually receives events.  Also make sure we only remove the handler
    if we registered it before.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/usb-wacom.c b/hw/usb-wacom.c
index fe052eb..47f26cd 100644
--- a/hw/usb-wacom.c
+++ b/hw/usb-wacom.c
@@ -160,6 +160,7 @@ static int usb_mouse_poll(USBWacomState *s, uint8_t *buf, int len)
     if (!s->mouse_grabbed) {
         s->eh_entry = qemu_add_mouse_event_handler(usb_mouse_event, s, 0,
                         "QEMU PenPartner tablet");
+        qemu_activate_mouse_event_handler(s->eh_entry);
         s->mouse_grabbed = 1;
     }
 
@@ -197,6 +198,7 @@ static int usb_wacom_poll(USBWacomState *s, uint8_t *buf, int len)
     if (!s->mouse_grabbed) {
         s->eh_entry = qemu_add_mouse_event_handler(usb_wacom_event, s, 1,
                         "QEMU PenPartner tablet");
+        qemu_activate_mouse_event_handler(s->eh_entry);
         s->mouse_grabbed = 1;
     }
 
@@ -334,8 +336,10 @@ static int usb_wacom_handle_control(USBDevice *dev, int request, int value,
         ret = 0;
         break;
     case WACOM_SET_REPORT:
-        qemu_remove_mouse_event_handler(s->eh_entry);
-        s->mouse_grabbed = 0;
+        if (s->mouse_grabbed) {
+            qemu_remove_mouse_event_handler(s->eh_entry);
+            s->mouse_grabbed = 0;
+        }
         s->mode = data[0];
         ret = 0;
         break;
@@ -397,7 +401,10 @@ static void usb_wacom_handle_destroy(USBDevice *dev)
 {
     USBWacomState *s = (USBWacomState *) dev;
 
-    qemu_remove_mouse_event_handler(s->eh_entry);
+    if (s->mouse_grabbed) {
+        qemu_remove_mouse_event_handler(s->eh_entry);
+        s->mouse_grabbed = 0;
+    }
 }
 
 static int usb_wacom_initfn(USBDevice *dev)
commit cd496926155afcb3b6323e70dd720dc118b3a255
Author: Gerd Hoffmann <kraxel at redhat.com>
Date:   Fri Oct 8 12:30:13 2010 +0200

    vmmouse: adapt to mouse handler changes.
    
    This patch updates the vmmouse handler registration and activation.
    
    Old behavior:
      vmmouse_read_id, vmmouse_request_relative and vmmouse_request_absolute
      unregister the handler and re-register it.
    
    New behavior:
      vmmouse_request_relative and vmmouse_request_absolute will unregister
      the handler in case the mode did change.  Then register and active the
      handler with current mode if needed.
    
    Note that the old code never ever *activates* the handler, so the
    vmmouse doesn't receive events.  This trips up Fedora 14 for example:
    Boot a default install without usb tablet, watch the X-Server activating
    the vmmouse then, enjoy a non-functional mouse.
    
    Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
    Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>

diff --git a/hw/vmmouse.c b/hw/vmmouse.c
index f359304..2097119 100644
--- a/hw/vmmouse.c
+++ b/hw/vmmouse.c
@@ -100,16 +100,29 @@ static void vmmouse_mouse_event(void *opaque, int x, int y, int dz, int buttons_
     i8042_isa_mouse_fake_event(s->ps2_mouse);
 }
 
-static void vmmouse_update_handler(VMMouseState *s)
+static void vmmouse_remove_handler(VMMouseState *s)
 {
     if (s->entry) {
         qemu_remove_mouse_event_handler(s->entry);
         s->entry = NULL;
     }
-    if (s->status == 0)
+}
+
+static void vmmouse_update_handler(VMMouseState *s, int absolute)
+{
+    if (s->status != 0) {
+        return;
+    }
+    if (s->absolute != absolute) {
+        s->absolute = absolute;
+        vmmouse_remove_handler(s);
+    }
+    if (s->entry == NULL) {
         s->entry = qemu_add_mouse_event_handler(vmmouse_mouse_event,
                                                 s, s->absolute,
                                                 "vmmouse");
+        qemu_activate_mouse_event_handler(s->entry);
+    }
 }
 
 static void vmmouse_read_id(VMMouseState *s)
@@ -121,28 +134,25 @@ static void vmmouse_read_id(VMMouseState *s)
 
     s->queue[s->nb_queue++] = VMMOUSE_VERSION;
     s->status = 0;
-    vmmouse_update_handler(s);
 }
 
 static void vmmouse_request_relative(VMMouseState *s)
 {
     DPRINTF("vmmouse_request_relative()\n");
-    s->absolute = 0;
-    vmmouse_update_handler(s);
+    vmmouse_update_handler(s, 0);
 }
 
 static void vmmouse_request_absolute(VMMouseState *s)
 {
     DPRINTF("vmmouse_request_absolute()\n");
-    s->absolute = 1;
-    vmmouse_update_handler(s);
+    vmmouse_update_handler(s, 1);
 }
 
 static void vmmouse_disable(VMMouseState *s)
 {
     DPRINTF("vmmouse_disable()\n");
     s->status = 0xffff;
-    vmmouse_update_handler(s);
+    vmmouse_remove_handler(s);
 }
 
 static void vmmouse_data(VMMouseState *s, uint32_t *data, uint32_t size)
@@ -154,7 +164,7 @@ static void vmmouse_data(VMMouseState *s, uint32_t *data, uint32_t size)
     if (size == 0 || size > 6 || size > s->nb_queue) {
         printf("vmmouse: driver requested too much data %d\n", size);
         s->status = 0xffff;
-        vmmouse_update_handler(s);
+        vmmouse_remove_handler(s);
         return;
     }
 
@@ -239,7 +249,8 @@ static int vmmouse_post_load(void *opaque, int version_id)
 {
     VMMouseState *s = opaque;
 
-    vmmouse_update_handler(s);
+    vmmouse_remove_handler(s);
+    vmmouse_update_handler(s, s->absolute);
     return 0;
 }
 
commit 45b23ff8f05d8f145d680476dd08e7f444cef547
Author: Venkateswararao Jujjuri (JV) <jvrao at linux.vnet.ibm.com>
Date:   Wed Oct 6 17:09:42 2010 -0700

    [virtio-9p] Add support to v9fs_string_alloc_printf() for handling %lu.
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 0e87722..daade77 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -321,6 +321,14 @@ static int number_to_string(void *arg, char type)
         } while (num);
         break;
     }
+    case 'U': {
+        unsigned long num = *(unsigned long *)arg;
+        do {
+            ret++;
+            num = num/10;
+        } while (num);
+        break;
+    }
     default:
         printf("Number_to_string: Unknown number format\n");
         return -1;
@@ -338,6 +346,7 @@ v9fs_string_alloc_printf(char **strp, const char *fmt, va_list ap)
     int nr_args = 0;
     char *arg_char_ptr;
     unsigned int arg_uint;
+    unsigned long arg_ulong;
 
     /* Find the number of %'s that denotes an argument */
     for (iter = strstr(iter, "%"); iter; iter = strstr(iter, "%")) {
@@ -363,6 +372,14 @@ v9fs_string_alloc_printf(char **strp, const char *fmt, va_list ap)
             arg_uint = va_arg(ap2, unsigned int);
             len += number_to_string((void *)&arg_uint, 'u');
             break;
+        case 'l':
+            if (*++iter == 'u') {
+                arg_ulong = va_arg(ap2, unsigned long);
+                len += number_to_string((void *)&arg_ulong, 'U');
+            } else {
+                return -1;
+            }
+            break;
         case 's':
             arg_char_ptr = va_arg(ap2, char *);
             len += strlen(arg_char_ptr);
commit 56d15a53292c06a9c8c574e368003f57a06522ee
Author: Sanchit Garg <sancgarg at linux.vnet.ibm.com>
Date:   Fri Oct 8 11:30:16 2010 +0530

    [virtio-9p] Use preadv/pwritev instead of readv/writev
    
    readv & writev, read & write respectively from the current offset
    of the file & hence their use has to be preceeded by a call to lseek.
    preadv/writev can be used instead, as they take the offset as an argument.
    This saves one system call( lseek ).
    In case preadv is not supported, it is implemented by an lseek
    followed by a readv. Depending upon the configuration of QEMU, the
    appropriate read & write methods are selected. This patch also fixes the
    zero byte read/write bug & obviates the need to apply a fix for that bug separately.
    
    Signed-off-by: M. Mohan Kumar <mohan at in.ibm.com>
    Signed-off-by: Sanchit Garg <sancgarg at linux.vnet.ibm.com>
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index bf867b9..21d60b5 100644
--- a/hw/file-op-9p.h
+++ b/hw/file-op-9p.h
@@ -80,9 +80,8 @@ typedef struct FileOperations
     off_t (*telldir)(FsContext *, DIR *);
     struct dirent *(*readdir)(FsContext *, DIR *);
     void (*seekdir)(FsContext *, DIR *, off_t);
-    ssize_t (*readv)(FsContext *, int, const struct iovec *, int);
-    ssize_t (*writev)(FsContext *, int, const struct iovec *, int);
-    off_t (*lseek)(FsContext *, int, off_t, int);
+    ssize_t (*preadv)(FsContext *, int, const struct iovec *, int, off_t);
+    ssize_t (*pwritev)(FsContext *, int, const struct iovec *, int, off_t);
     int (*mkdir)(FsContext *, const char *, FsCred *);
     int (*fstat)(FsContext *, int, struct stat *);
     int (*rename)(FsContext *, const char *, const char *);
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index ee63033..0d52020 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -168,21 +168,34 @@ static void local_seekdir(FsContext *ctx, DIR *dir, off_t off)
     return seekdir(dir, off);
 }
 
-static ssize_t local_readv(FsContext *ctx, int fd, const struct iovec *iov,
-                            int iovcnt)
+static ssize_t local_preadv(FsContext *ctx, int fd, const struct iovec *iov,
+                            int iovcnt, off_t offset)
 {
-    return readv(fd, iov, iovcnt);
-}
-
-static off_t local_lseek(FsContext *ctx, int fd, off_t offset, int whence)
-{
-    return lseek(fd, offset, whence);
+#ifdef CONFIG_PREADV
+    return preadv(fd, iov, iovcnt, offset);
+#else
+    int err = lseek(fd, offset, SEEK_SET);
+    if (err == -1) {
+        return err;
+    } else {
+        return readv(fd, iov, iovcnt);
+    }
+#endif
 }
 
-static ssize_t local_writev(FsContext *ctx, int fd, const struct iovec *iov,
-                            int iovcnt)
+static ssize_t local_pwritev(FsContext *ctx, int fd, const struct iovec *iov,
+                            int iovcnt, off_t offset)
 {
-    return writev(fd, iov, iovcnt);
+#ifdef CONFIG_PREADV
+    return pwritev(fd, iov, iovcnt, offset);
+#else
+    int err = lseek(fd, offset, SEEK_SET);
+    if (err == -1) {
+        return err;
+    } else {
+        return writev(fd, iov, iovcnt);
+    }
+#endif
 }
 
 static int local_chmod(FsContext *fs_ctx, const char *path, FsCred *credp)
@@ -523,9 +536,8 @@ FileOperations local_ops = {
     .telldir = local_telldir,
     .readdir = local_readdir,
     .seekdir = local_seekdir,
-    .readv = local_readv,
-    .lseek = local_lseek,
-    .writev = local_writev,
+    .preadv = local_preadv,
+    .pwritev = local_pwritev,
     .chmod = local_chmod,
     .mknod = local_mknod,
     .mkdir = local_mkdir,
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 867fcfa..0e87722 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -135,21 +135,16 @@ static void v9fs_do_seekdir(V9fsState *s, DIR *dir, off_t off)
     return s->ops->seekdir(&s->ctx, dir, off);
 }
 
-static int v9fs_do_readv(V9fsState *s, int fd, const struct iovec *iov,
-                            int iovcnt)
+static int v9fs_do_preadv(V9fsState *s, int fd, const struct iovec *iov,
+                            int iovcnt, int64_t offset)
 {
-    return s->ops->readv(&s->ctx, fd, iov, iovcnt);
+    return s->ops->preadv(&s->ctx, fd, iov, iovcnt, offset);
 }
 
-static off_t v9fs_do_lseek(V9fsState *s, int fd, off_t offset, int whence)
+static int v9fs_do_pwritev(V9fsState *s, int fd, const struct iovec *iov,
+                       int iovcnt, int64_t offset)
 {
-    return s->ops->lseek(&s->ctx, fd, offset, whence);
-}
-
-static int v9fs_do_writev(V9fsState *s, int fd, const struct iovec *iov,
-                       int iovcnt)
-{
-    return s->ops->writev(&s->ctx, fd, iov, iovcnt);
+    return s->ops->pwritev(&s->ctx, fd, iov, iovcnt, offset);
 }
 
 static int v9fs_do_chmod(V9fsState *s, V9fsString *path, mode_t mode)
@@ -1975,7 +1970,7 @@ static void v9fs_read_post_rewinddir(V9fsState *s, V9fsReadState *vs,
     return;
 }
 
-static void v9fs_read_post_readv(V9fsState *s, V9fsReadState *vs, ssize_t err)
+static void v9fs_read_post_preadv(V9fsState *s, V9fsReadState *vs, ssize_t err)
 {
     if (err  < 0) {
         /* IO error return the error */
@@ -1989,12 +1984,16 @@ static void v9fs_read_post_readv(V9fsState *s, V9fsReadState *vs, ssize_t err)
             if (0) {
                 print_sg(vs->sg, vs->cnt);
             }
-            vs->len = v9fs_do_readv(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
+            vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
+                      vs->off);
+            if (vs->len > 0) {
+                vs->off += vs->len;
+            }
         } while (vs->len == -1 && errno == EINTR);
         if (vs->len == -1) {
             err  = -errno;
         }
-        v9fs_read_post_readv(s, vs, err);
+        v9fs_read_post_preadv(s, vs, err);
         return;
     }
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
@@ -2006,32 +2005,6 @@ out:
     qemu_free(vs);
 }
 
-static void v9fs_read_post_lseek(V9fsState *s, V9fsReadState *vs, ssize_t err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-    vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
-
-    if (vs->total < vs->count) {
-        do {
-            if (0) {
-                print_sg(vs->sg, vs->cnt);
-            }
-            vs->len = v9fs_do_readv(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
-        } while (vs->len == -1 && errno == EINTR);
-        if (vs->len == -1) {
-            err  = -errno;
-        }
-        v9fs_read_post_readv(s, vs, err);
-        return;
-    }
-out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
-}
-
 static void v9fs_xattr_read(V9fsState *s, V9fsReadState *vs)
 {
     ssize_t err = 0;
@@ -2089,8 +2062,16 @@ static void v9fs_read(V9fsState *s, V9fsPDU *pdu)
     } else if (vs->fidp->fid_type == P9_FID_FILE) {
         vs->sg = vs->iov;
         pdu_marshal(vs->pdu, vs->offset + 4, "v", vs->sg, &vs->cnt);
-        err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET);
-        v9fs_read_post_lseek(s, vs, err);
+        vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
+        if (vs->total <= vs->count) {
+            vs->len = v9fs_do_preadv(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
+                                    vs->off);
+            if (vs->len > 0) {
+                vs->off += vs->len;
+            }
+            err = vs->len;
+            v9fs_read_post_preadv(s, vs, err);
+        }
         return;
     } else if (vs->fidp->fid_type == P9_FID_XATTR) {
         v9fs_xattr_read(s, vs);
@@ -2224,7 +2205,7 @@ out:
     return;
 }
 
-static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs,
+static void v9fs_write_post_pwritev(V9fsState *s, V9fsWriteState *vs,
                                    ssize_t err)
 {
     if (err  < 0) {
@@ -2239,49 +2220,25 @@ static void v9fs_write_post_writev(V9fsState *s, V9fsWriteState *vs,
             if (0) {
                 print_sg(vs->sg, vs->cnt);
             }
-            vs->len =  v9fs_do_writev(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
+            vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt,
+                      vs->off);
+            if (vs->len > 0) {
+                vs->off += vs->len;
+            }
         } while (vs->len == -1 && errno == EINTR);
         if (vs->len == -1) {
             err  = -errno;
         }
-        v9fs_write_post_writev(s, vs, err);
+        v9fs_write_post_pwritev(s, vs, err);
         return;
     }
     vs->offset += pdu_marshal(vs->pdu, vs->offset, "d", vs->total);
-
     err = vs->offset;
 out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
 }
 
-static void v9fs_write_post_lseek(V9fsState *s, V9fsWriteState *vs, ssize_t err)
-{
-    if (err == -1) {
-        err = -errno;
-        goto out;
-    }
-    vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
-
-    if (vs->total < vs->count) {
-        do {
-            if (0) {
-                print_sg(vs->sg, vs->cnt);
-            }
-            vs->len = v9fs_do_writev(s, vs->fidp->fs.fd, vs->sg, vs->cnt);
-        } while (vs->len == -1 && errno == EINTR);
-        if (vs->len == -1) {
-            err  = -errno;
-        }
-        v9fs_write_post_writev(s, vs, err);
-        return;
-    }
-
-out:
-    complete_pdu(s, vs->pdu, err);
-    qemu_free(vs);
-}
-
 static void v9fs_xattr_write(V9fsState *s, V9fsWriteState *vs)
 {
     int i, to_copy;
@@ -2362,11 +2319,16 @@ static void v9fs_write(V9fsState *s, V9fsPDU *pdu)
         err = -EINVAL;
         goto out;
     }
-    err = v9fs_do_lseek(s, vs->fidp->fs.fd, vs->off, SEEK_SET);
-
-    v9fs_write_post_lseek(s, vs, err);
+    vs->sg = cap_sg(vs->sg, vs->count, &vs->cnt);
+    if (vs->total <= vs->count) {
+        vs->len = v9fs_do_pwritev(s, vs->fidp->fs.fd, vs->sg, vs->cnt, vs->off);
+        if (vs->len > 0) {
+            vs->off += vs->len;
+        }
+        err = vs->len;
+        v9fs_write_post_pwritev(s, vs, err);
+    }
     return;
-
 out:
     complete_pdu(s, vs->pdu, err);
     qemu_free(vs);
commit 9f506893a454ce24263aba49594aa953e9a52853
Author: Harsh Prateek Bora <harsh at linux.vnet.ibm.com>
Date:   Mon Oct 18 15:36:36 2010 +0530

    [virtio-9p] Qemu 9p commandline options validity checks
    
    Signed-off-by: Harsh Prateek Bora <harsh at linux.vnet.ibm.com>
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
index 280b8f5..0b33290 100644
--- a/fsdev/qemu-fsdev.c
+++ b/fsdev/qemu-fsdev.c
@@ -29,35 +29,47 @@ int qemu_fsdev_add(QemuOpts *opts)
 {
     struct FsTypeListEntry *fsle;
     int i;
+    const char *fsdev_id = qemu_opts_id(opts);
+    const char *fstype = qemu_opt_get(opts, "fstype");
+    const char *path = qemu_opt_get(opts, "path");
+    const char *sec_model = qemu_opt_get(opts, "security_model");
 
-    if (qemu_opts_id(opts) == NULL) {
+    if (!fsdev_id) {
         fprintf(stderr, "fsdev: No id specified\n");
         return -1;
     }
 
-    for (i = 0; i < ARRAY_SIZE(FsTypes); i++) {
-        if (strcmp(FsTypes[i].name, qemu_opt_get(opts, "fstype")) == 0) {
-            break;
+    if (fstype) {
+        for (i = 0; i < ARRAY_SIZE(FsTypes); i++) {
+            if (strcmp(FsTypes[i].name, fstype) == 0) {
+                break;
+            }
         }
-    }
 
-    if (i == ARRAY_SIZE(FsTypes)) {
-        fprintf(stderr, "fsdev: fstype %s not found\n",
-                    qemu_opt_get(opts, "fstype"));
+        if (i == ARRAY_SIZE(FsTypes)) {
+            fprintf(stderr, "fsdev: fstype %s not found\n", fstype);
+            return -1;
+        }
+    } else {
+        fprintf(stderr, "fsdev: No fstype specified\n");
         return -1;
     }
 
-    if (qemu_opt_get(opts, "security_model") == NULL) {
+    if (!sec_model) {
         fprintf(stderr, "fsdev: No security_model specified.\n");
         return -1;
     }
 
+    if (!path) {
+        fprintf(stderr, "fsdev: No path specified.\n");
+        return -1;
+    }
+
     fsle = qemu_malloc(sizeof(*fsle));
 
-    fsle->fse.fsdev_id = qemu_strdup(qemu_opts_id(opts));
-    fsle->fse.path = qemu_strdup(qemu_opt_get(opts, "path"));
-    fsle->fse.security_model = qemu_strdup(qemu_opt_get(opts,
-                "security_model"));
+    fsle->fse.fsdev_id = qemu_strdup(fsdev_id);
+    fsle->fse.path = qemu_strdup(path);
+    fsle->fse.security_model = qemu_strdup(sec_model);
     fsle->fse.ops = FsTypes[i].ops;
 
     QTAILQ_INSERT_TAIL(&fstype_entries, fsle, next);
@@ -67,11 +79,13 @@ int qemu_fsdev_add(QemuOpts *opts)
 
 FsTypeEntry *get_fsdev_fsentry(char *id)
 {
-    struct FsTypeListEntry *fsle;
+    if (id) {
+        struct FsTypeListEntry *fsle;
 
-    QTAILQ_FOREACH(fsle, &fstype_entries, next) {
-        if (strcmp(fsle->fse.fsdev_id, id) == 0) {
-            return &fsle->fse;
+        QTAILQ_FOREACH(fsle, &fstype_entries, next) {
+            if (strcmp(fsle->fse.fsdev_id, id) == 0) {
+                return &fsle->fse;
+            }
         }
     }
     return NULL;
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 4586cce..867fcfa 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -3697,8 +3697,8 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
 
     if (!fse) {
         /* We don't have a fsdev identified by fsdev_id */
-        fprintf(stderr, "Virtio-9p device couldn't find fsdev "
-                    "with the id %s\n", conf->fsdev_id);
+        fprintf(stderr, "Virtio-9p device couldn't find fsdev with the "
+                "id = %s\n", conf->fsdev_id ? conf->fsdev_id : "NULL");
         exit(1);
     }
 
commit 70fc55ebe4fe5e72802468f16ae09169cf323b04
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Mon Oct 18 15:28:16 2010 +0530

    virtio-9p: Support mapped posix acl
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/Makefile.objs b/Makefile.objs
index be4fade..cd5a24b 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -250,7 +250,7 @@ adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 
 hw-obj-$(CONFIG_VIRTFS) += virtio-9p-debug.o virtio-9p-local.o virtio-9p-xattr.o
-hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o
+hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
 
 ######################################################################
 # libdis
diff --git a/hw/virtio-9p-posix-acl.c b/hw/virtio-9p-posix-acl.c
new file mode 100644
index 0000000..3978d0c
--- /dev/null
+++ b/hw/virtio-9p-posix-acl.c
@@ -0,0 +1,140 @@
+/*
+ * Virtio 9p system.posix* xattr callback
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ * Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <sys/types.h>
+#include <attr/xattr.h>
+#include "virtio.h"
+#include "virtio-9p.h"
+#include "file-op-9p.h"
+#include "virtio-9p-xattr.h"
+
+#define MAP_ACL_ACCESS "user.virtfs.system.posix_acl_access"
+#define MAP_ACL_DEFAULT "user.virtfs.system.posix_acl_default"
+#define ACL_ACCESS "system.posix_acl_access"
+#define ACL_DEFAULT "system.posix_acl_default"
+
+static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path,
+                                const char *name, void *value, size_t size)
+{
+    return lgetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size);
+}
+
+static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
+                                 char *name, void *value, size_t osize)
+{
+    ssize_t len = sizeof(ACL_ACCESS);
+
+    if (!value) {
+        return len;
+    }
+
+    if (osize < len) {
+        errno = ERANGE;
+        return -1;
+    }
+
+    strncpy(value, ACL_ACCESS, len);
+    return 0;
+}
+
+static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name,
+                            void *value, size_t size, int flags)
+{
+    return lsetxattr(rpath(ctx, path), MAP_ACL_ACCESS, value, size, flags);
+}
+
+static int mp_pacl_removexattr(FsContext *ctx,
+                               const char *path, const char *name)
+{
+    int ret;
+    ret  = lremovexattr(rpath(ctx, path), MAP_ACL_ACCESS);
+    if (ret == -1 && errno == ENODATA) {
+        /*
+         * We don't get ENODATA error when trying to remote a
+         * posix acl that is not present. So don't throw the error
+         * even in case of mapped security model
+         */
+        errno = 0;
+        ret = 0;
+    }
+    return ret;
+}
+
+static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,
+                                const char *name, void *value, size_t size)
+{
+    return lgetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size);
+}
+
+static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
+                                 char *name, void *value, size_t osize)
+{
+    ssize_t len = sizeof(ACL_DEFAULT);
+
+    if (!value) {
+        return len;
+    }
+
+    if (osize < len) {
+        errno = ERANGE;
+        return -1;
+    }
+
+    strncpy(value, ACL_DEFAULT, len);
+    return 0;
+}
+
+static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
+                            void *value, size_t size, int flags)
+{
+    return lsetxattr(rpath(ctx, path), MAP_ACL_DEFAULT, value, size, flags);
+}
+
+static int mp_dacl_removexattr(FsContext *ctx,
+                               const char *path, const char *name)
+{
+    return lremovexattr(rpath(ctx, path), MAP_ACL_DEFAULT);
+}
+
+
+XattrOperations mapped_pacl_xattr = {
+    .name = "system.posix_acl_access",
+    .getxattr = mp_pacl_getxattr,
+    .setxattr = mp_pacl_setxattr,
+    .listxattr = mp_pacl_listxattr,
+    .removexattr = mp_pacl_removexattr,
+};
+
+XattrOperations mapped_dacl_xattr = {
+    .name = "system.posix_acl_default",
+    .getxattr = mp_dacl_getxattr,
+    .setxattr = mp_dacl_setxattr,
+    .listxattr = mp_dacl_listxattr,
+    .removexattr = mp_dacl_removexattr,
+};
+
+XattrOperations passthrough_acl_xattr = {
+    .name = "system.posix_acl_",
+    .getxattr = pt_getxattr,
+    .setxattr = pt_setxattr,
+    .listxattr = pt_listxattr,
+    .removexattr = pt_removexattr,
+};
+
+XattrOperations none_acl_xattr = {
+    .name = "system.posix_acl_",
+    .getxattr = notsup_getxattr,
+    .setxattr = notsup_setxattr,
+    .listxattr = notsup_listxattr,
+    .removexattr = notsup_removexattr,
+};
diff --git a/hw/virtio-9p-xattr-user.c b/hw/virtio-9p-xattr-user.c
index b14dbb9..faa02a1 100644
--- a/hw/virtio-9p-xattr-user.c
+++ b/hw/virtio-9p-xattr-user.c
@@ -37,11 +37,19 @@ static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
 {
     int name_size = strlen(name) + 1;
     if (strncmp(name, "user.virtfs.", 12) == 0) {
-        /*
-         * Don't allow fetch of user.virtfs namesapce
-         * in case of mapped security
-         */
-        return 0;
+
+        /*  check if it is a mapped posix acl */
+        if (strncmp(name, "user.virtfs.system.posix_acl_", 29) == 0) {
+            /* adjust the name and size */
+            name += 12;
+            name_size -= 12;
+        } else {
+            /*
+             * Don't allow fetch of user.virtfs namesapce
+             * in case of mapped security
+             */
+            return 0;
+        }
     }
     if (!value) {
         return name_size;
diff --git a/hw/virtio-9p-xattr.c b/hw/virtio-9p-xattr.c
index 5ddc3c9..175f372 100644
--- a/hw/virtio-9p-xattr.c
+++ b/hw/virtio-9p-xattr.c
@@ -137,16 +137,20 @@ int v9fs_remove_xattr(FsContext *ctx,
 
 XattrOperations *mapped_xattr_ops[] = {
     &mapped_user_xattr,
+    &mapped_pacl_xattr,
+    &mapped_dacl_xattr,
     NULL,
 };
 
 XattrOperations *passthrough_xattr_ops[] = {
     &passthrough_user_xattr,
+    &passthrough_acl_xattr,
     NULL,
 };
 
 /* for .user none model should be same as passthrough */
 XattrOperations *none_xattr_ops[] = {
     &passthrough_user_xattr,
+    &none_acl_xattr,
     NULL,
 };
diff --git a/hw/virtio-9p-xattr.h b/hw/virtio-9p-xattr.h
index 15632f8..a6e31a1 100644
--- a/hw/virtio-9p-xattr.h
+++ b/hw/virtio-9p-xattr.h
@@ -32,6 +32,11 @@ typedef struct xattr_operations
 extern XattrOperations mapped_user_xattr;
 extern XattrOperations passthrough_user_xattr;
 
+extern XattrOperations mapped_pacl_xattr;
+extern XattrOperations mapped_dacl_xattr;
+extern XattrOperations passthrough_acl_xattr;
+extern XattrOperations none_acl_xattr;
+
 extern XattrOperations *mapped_xattr_ops[];
 extern XattrOperations *passthrough_xattr_ops[];
 extern XattrOperations *none_xattr_ops[];
@@ -66,4 +71,33 @@ static inline int pt_removexattr(FsContext *ctx,
     return lremovexattr(rpath(ctx, path), name);
 }
 
+static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path,
+                                      const char *name, void *value,
+                                      size_t size)
+{
+    errno = ENOTSUP;
+    return -1;
+}
+
+static inline int notsup_setxattr(FsContext *ctx, const char *path,
+                                  const char *name, void *value,
+                                  size_t size, int flags)
+{
+    errno = ENOTSUP;
+    return -1;
+}
+
+static inline ssize_t notsup_listxattr(FsContext *ctx, const char *path,
+                                       char *name, void *value, size_t size)
+{
+    return 0;
+}
+
+static inline int notsup_removexattr(FsContext *ctx,
+                                     const char *path, const char *name)
+{
+    errno = ENOTSUP;
+    return -1;
+}
+
 #endif
commit fc22118d9bb56ec71655b936a29513c140e6c289
Author: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
Date:   Mon Oct 18 15:28:16 2010 +0530

    virtio-9p: Use layered xattr approach
    
    We would need this to make sure we handle the mapped
    security model correctly for different xattr names.
    
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/Makefile.objs b/Makefile.objs
index 816194a..be4fade 100644
--- a/Makefile.objs
+++ b/Makefile.objs
@@ -249,7 +249,8 @@ sound-obj-$(CONFIG_CS4231A) += cs4231a.o
 adlib.o fmopl.o: QEMU_CFLAGS += -DBUILD_Y8950=0
 hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
 
-hw-obj-$(CONFIG_VIRTFS) += virtio-9p-debug.o virtio-9p-local.o
+hw-obj-$(CONFIG_VIRTFS) += virtio-9p-debug.o virtio-9p-local.o virtio-9p-xattr.o
+hw-obj-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o
 
 ######################################################################
 # libdis
diff --git a/hw/file-op-9p.h b/hw/file-op-9p.h
index d91b7e7..bf867b9 100644
--- a/hw/file-op-9p.h
+++ b/hw/file-op-9p.h
@@ -47,11 +47,14 @@ typedef struct FsCred
     dev_t   fc_rdev;
 } FsCred;
 
+struct xattr_operations;
+
 typedef struct FsContext
 {
     char *fs_root;
     SecModel fs_sm;
     uid_t uid;
+    struct xattr_operations **xops;
 } FsContext;
 
 extern void cred_init(FsCred *);
@@ -94,4 +97,12 @@ typedef struct FileOperations
     int (*lremovexattr)(FsContext *, const char *, const char *);
     void *opaque;
 } FileOperations;
+
+static inline const char *rpath(FsContext *ctx, const char *path)
+{
+    /* FIXME: so wrong... */
+    static char buffer[4096];
+    snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path);
+    return buffer;
+}
 #endif
diff --git a/hw/virtio-9p-local.c b/hw/virtio-9p-local.c
index 57f9243..ee63033 100644
--- a/hw/virtio-9p-local.c
+++ b/hw/virtio-9p-local.c
@@ -12,6 +12,7 @@
  */
 #include "virtio.h"
 #include "virtio-9p.h"
+#include "virtio-9p-xattr.h"
 #include <arpa/inet.h>
 #include <pwd.h>
 #include <grp.h>
@@ -19,14 +20,6 @@
 #include <sys/un.h>
 #include <attr/xattr.h>
 
-static const char *rpath(FsContext *ctx, const char *path)
-{
-    /* FIXME: so wrong... */
-    static char buffer[4096];
-    snprintf(buffer, sizeof(buffer), "%s/%s", ctx->fs_root, path);
-    return buffer;
-}
-
 
 static int local_lstat(FsContext *fs_ctx, const char *path, struct stat *stbuf)
 {
@@ -497,103 +490,25 @@ static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
 static ssize_t local_lgetxattr(FsContext *ctx, const char *path,
                                const char *name, void *value, size_t size)
 {
-    if ((ctx->fs_sm == SM_MAPPED) &&
-        (strncmp(name, "user.virtfs.", 12) == 0)) {
-        /*
-         * Don't allow fetch of user.virtfs namesapce
-         * in case of mapped security
-         */
-        errno = ENOATTR;
-        return -1;
-    }
-
-    return lgetxattr(rpath(ctx, path), name, value, size);
+    return v9fs_get_xattr(ctx, path, name, value, size);
 }
 
 static ssize_t local_llistxattr(FsContext *ctx, const char *path,
                                 void *value, size_t size)
 {
-    ssize_t retval;
-    ssize_t actual_len = 0;
-    char *orig_value, *orig_value_start;
-    char *temp_value, *temp_value_start;
-    ssize_t xattr_len, parsed_len = 0, attr_len;
-
-    if (ctx->fs_sm != SM_MAPPED) {
-        return llistxattr(rpath(ctx, path), value, size);
-    }
-
-    /* Get the actual len */
-    xattr_len = llistxattr(rpath(ctx, path), value, 0);
-
-    /* Now fetch the xattr and find the actual size */
-    orig_value = qemu_malloc(xattr_len);
-    xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len);
-
-    /*
-     * For mapped security model drop user.virtfs namespace
-     * from the list
-     */
-    temp_value = qemu_mallocz(xattr_len);
-    temp_value_start = temp_value;
-    orig_value_start = orig_value;
-    while (xattr_len > parsed_len) {
-        attr_len = strlen(orig_value) + 1;
-        if (strncmp(orig_value, "user.virtfs.", 12) != 0) {
-            /* Copy this entry */
-            strcat(temp_value, orig_value);
-            temp_value  += attr_len;
-            actual_len += attr_len;
-        }
-        parsed_len += attr_len;
-        orig_value += attr_len;
-    }
-    if (!size) {
-        retval = actual_len;
-        goto out;
-    } else if (size >= actual_len) {
-        /* now copy the parsed attribute list back */
-        memset(value, 0, size);
-        memcpy(value, temp_value_start, actual_len);
-        retval = actual_len;
-        goto out;
-    }
-    errno = ERANGE;
-    retval = -1;
-out:
-    qemu_free(orig_value_start);
-    qemu_free(temp_value_start);
-    return retval;
+    return v9fs_list_xattr(ctx, path, value, size);
 }
 
 static int local_lsetxattr(FsContext *ctx, const char *path, const char *name,
                            void *value, size_t size, int flags)
 {
-    if ((ctx->fs_sm == SM_MAPPED) &&
-        (strncmp(name, "user.virtfs.", 12) == 0)) {
-        /*
-         * Don't allow fetch of user.virtfs namesapce
-         * in case of mapped security
-         */
-        errno = EACCES;
-        return -1;
-    }
-    return lsetxattr(rpath(ctx, path), name, value, size, flags);
+    return v9fs_set_xattr(ctx, path, name, value, size, flags);
 }
 
 static int local_lremovexattr(FsContext *ctx,
                               const char *path, const char *name)
 {
-    if ((ctx->fs_sm == SM_MAPPED) &&
-        (strncmp(name, "user.virtfs.", 12) == 0)) {
-        /*
-         * Don't allow fetch of user.virtfs namesapce
-         * in case of mapped security
-         */
-        errno = EACCES;
-        return -1;
-    }
-    return lremovexattr(rpath(ctx, path), name);
+    return v9fs_remove_xattr(ctx, path, name);
 }
 
 
diff --git a/hw/virtio-9p-xattr-user.c b/hw/virtio-9p-xattr-user.c
new file mode 100644
index 0000000..b14dbb9
--- /dev/null
+++ b/hw/virtio-9p-xattr-user.c
@@ -0,0 +1,101 @@
+/*
+ * Virtio 9p user. xattr callback
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ * Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include <sys/types.h>
+#include "virtio.h"
+#include "virtio-9p.h"
+#include "file-op-9p.h"
+#include "virtio-9p-xattr.h"
+
+
+static ssize_t mp_user_getxattr(FsContext *ctx, const char *path,
+                                const char *name, void *value, size_t size)
+{
+    if (strncmp(name, "user.virtfs.", 12) == 0) {
+        /*
+         * Don't allow fetch of user.virtfs namesapce
+         * in case of mapped security
+         */
+        errno = ENOATTR;
+        return -1;
+    }
+    return lgetxattr(rpath(ctx, path), name, value, size);
+}
+
+static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
+                                 char *name, void *value, size_t size)
+{
+    int name_size = strlen(name) + 1;
+    if (strncmp(name, "user.virtfs.", 12) == 0) {
+        /*
+         * Don't allow fetch of user.virtfs namesapce
+         * in case of mapped security
+         */
+        return 0;
+    }
+    if (!value) {
+        return name_size;
+    }
+
+    if (size < name_size) {
+        errno = ERANGE;
+        return -1;
+    }
+
+    strncpy(value, name, name_size);
+    return name_size;
+}
+
+static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,
+                            void *value, size_t size, int flags)
+{
+    if (strncmp(name, "user.virtfs.", 12) == 0) {
+        /*
+         * Don't allow fetch of user.virtfs namesapce
+         * in case of mapped security
+         */
+        errno = EACCES;
+        return -1;
+    }
+    return lsetxattr(rpath(ctx, path), name, value, size, flags);
+}
+
+static int mp_user_removexattr(FsContext *ctx,
+                               const char *path, const char *name)
+{
+    if (strncmp(name, "user.virtfs.", 12) == 0) {
+        /*
+         * Don't allow fetch of user.virtfs namesapce
+         * in case of mapped security
+         */
+        errno = EACCES;
+        return -1;
+    }
+    return lremovexattr(rpath(ctx, path), name);
+}
+
+XattrOperations mapped_user_xattr = {
+    .name = "user.",
+    .getxattr = mp_user_getxattr,
+    .setxattr = mp_user_setxattr,
+    .listxattr = mp_user_listxattr,
+    .removexattr = mp_user_removexattr,
+};
+
+XattrOperations passthrough_user_xattr = {
+    .name = "user.",
+    .getxattr = pt_getxattr,
+    .setxattr = pt_setxattr,
+    .listxattr = pt_listxattr,
+    .removexattr = pt_removexattr,
+};
diff --git a/hw/virtio-9p-xattr.c b/hw/virtio-9p-xattr.c
new file mode 100644
index 0000000..5ddc3c9
--- /dev/null
+++ b/hw/virtio-9p-xattr.c
@@ -0,0 +1,152 @@
+/*
+ * Virtio 9p  xattr callback
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ * Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+
+#include "virtio.h"
+#include "virtio-9p.h"
+#include "file-op-9p.h"
+#include "virtio-9p-xattr.h"
+
+
+static XattrOperations *get_xattr_operations(XattrOperations **h,
+                                             const char *name)
+{
+    XattrOperations *xops;
+    for (xops = *(h)++; xops != NULL; xops = *(h)++) {
+        if (!strncmp(name, xops->name, strlen(xops->name))) {
+            return xops;
+        }
+    }
+    return NULL;
+}
+
+ssize_t v9fs_get_xattr(FsContext *ctx, const char *path,
+                       const char *name, void *value, size_t size)
+{
+    XattrOperations *xops = get_xattr_operations(ctx->xops, name);
+    if (xops) {
+        return xops->getxattr(ctx, path, name, value, size);
+    }
+    errno = -EOPNOTSUPP;
+    return -1;
+}
+
+ssize_t pt_listxattr(FsContext *ctx, const char *path,
+                     char *name, void *value, size_t size)
+{
+    int name_size = strlen(name) + 1;
+    if (!value) {
+        return name_size;
+    }
+
+    if (size < name_size) {
+        errno = ERANGE;
+        return -1;
+    }
+
+    strncpy(value, name, name_size);
+    return name_size;
+}
+
+
+/*
+ * Get the list and pass to each layer to find out whether
+ * to send the data or not
+ */
+ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
+                        void *value, size_t vsize)
+{
+    ssize_t size = 0;
+    void *ovalue = value;
+    XattrOperations *xops;
+    char *orig_value, *orig_value_start;
+    ssize_t xattr_len, parsed_len = 0, attr_len;
+
+    /* Get the actual len */
+    xattr_len = llistxattr(rpath(ctx, path), value, 0);
+
+    /* Now fetch the xattr and find the actual size */
+    orig_value = qemu_malloc(xattr_len);
+    xattr_len = llistxattr(rpath(ctx, path), orig_value, xattr_len);
+
+    /* store the orig pointer */
+    orig_value_start = orig_value;
+    while (xattr_len > parsed_len) {
+        xops = get_xattr_operations(ctx->xops, orig_value);
+        if (!xops) {
+            goto next_entry;
+        }
+
+        if (!value) {
+            size += xops->listxattr(ctx, path, orig_value, value, vsize);
+        } else {
+            size = xops->listxattr(ctx, path, orig_value, value, vsize);
+            if (size < 0) {
+                goto err_out;
+            }
+            value += size;
+            vsize -= size;
+        }
+next_entry:
+        /* Got the next entry */
+        attr_len = strlen(orig_value) + 1;
+        parsed_len += attr_len;
+        orig_value += attr_len;
+    }
+    if (value) {
+        size = value - ovalue;
+    }
+
+err_out:
+    qemu_free(orig_value_start);
+    return size;
+}
+
+int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
+                   void *value, size_t size, int flags)
+{
+    XattrOperations *xops = get_xattr_operations(ctx->xops, name);
+    if (xops) {
+        return xops->setxattr(ctx, path, name, value, size, flags);
+    }
+    errno = -EOPNOTSUPP;
+    return -1;
+
+}
+
+int v9fs_remove_xattr(FsContext *ctx,
+                      const char *path, const char *name)
+{
+    XattrOperations *xops = get_xattr_operations(ctx->xops, name);
+    if (xops) {
+        return xops->removexattr(ctx, path, name);
+    }
+    errno = -EOPNOTSUPP;
+    return -1;
+
+}
+
+XattrOperations *mapped_xattr_ops[] = {
+    &mapped_user_xattr,
+    NULL,
+};
+
+XattrOperations *passthrough_xattr_ops[] = {
+    &passthrough_user_xattr,
+    NULL,
+};
+
+/* for .user none model should be same as passthrough */
+XattrOperations *none_xattr_ops[] = {
+    &passthrough_user_xattr,
+    NULL,
+};
diff --git a/hw/virtio-9p-xattr.h b/hw/virtio-9p-xattr.h
new file mode 100644
index 0000000..15632f8
--- /dev/null
+++ b/hw/virtio-9p-xattr.h
@@ -0,0 +1,69 @@
+/*
+ * Virtio 9p
+ *
+ * Copyright IBM, Corp. 2010
+ *
+ * Authors:
+ *  Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2.  See
+ * the COPYING file in the top-level directory.
+ *
+ */
+#ifndef _QEMU_VIRTIO_9P_XATTR_H
+#define _QEMU_VIRTIO_9P_XATTR_H
+
+#include <attr/xattr.h>
+
+typedef struct xattr_operations
+{
+    const char *name;
+    ssize_t (*getxattr)(FsContext *ctx, const char *path,
+                        const char *name, void *value, size_t size);
+    ssize_t (*listxattr)(FsContext *ctx, const char *path,
+                         char *name, void *value, size_t size);
+    int (*setxattr)(FsContext *ctx, const char *path, const char *name,
+                    void *value, size_t size, int flags);
+    int (*removexattr)(FsContext *ctx,
+                       const char *path, const char *name);
+} XattrOperations;
+
+
+extern XattrOperations mapped_user_xattr;
+extern XattrOperations passthrough_user_xattr;
+
+extern XattrOperations *mapped_xattr_ops[];
+extern XattrOperations *passthrough_xattr_ops[];
+extern XattrOperations *none_xattr_ops[];
+
+extern ssize_t v9fs_get_xattr(FsContext *ctx, const char *path,
+                              const char *name, void *value, size_t size);
+extern ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
+                               void *value, size_t vsize);
+extern int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
+                          void *value, size_t size, int flags);
+extern int v9fs_remove_xattr(FsContext *ctx,
+                             const char *path, const char *name);
+extern ssize_t pt_listxattr(FsContext *ctx, const char *path,
+                            char *name, void *value, size_t size);
+
+static inline ssize_t pt_getxattr(FsContext *ctx, const char *path,
+                                  const char *name, void *value, size_t size)
+{
+    return lgetxattr(rpath(ctx, path), name, value, size);
+}
+
+static inline int pt_setxattr(FsContext *ctx, const char *path,
+                              const char *name, void *value,
+                              size_t size, int flags)
+{
+    return lsetxattr(rpath(ctx, path), name, value, size, flags);
+}
+
+static inline int pt_removexattr(FsContext *ctx,
+                                 const char *path, const char *name)
+{
+    return lremovexattr(rpath(ctx, path), name);
+}
+
+#endif
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index cb6366b..4586cce 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -17,6 +17,7 @@
 #include "virtio-9p.h"
 #include "fsdev/qemu-fsdev.h"
 #include "virtio-9p-debug.h"
+#include "virtio-9p-xattr.h"
 
 int debug_9p_pdu;
 
@@ -3712,23 +3713,26 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
     if (!strcmp(fse->security_model, "passthrough")) {
         /* Files on the Fileserver set to client user credentials */
         s->ctx.fs_sm = SM_PASSTHROUGH;
+        s->ctx.xops = passthrough_xattr_ops;
     } else if (!strcmp(fse->security_model, "mapped")) {
         /* Files on the fileserver are set to QEMU credentials.
          * Client user credentials are saved in extended attributes.
          */
         s->ctx.fs_sm = SM_MAPPED;
+        s->ctx.xops = mapped_xattr_ops;
     } else if (!strcmp(fse->security_model, "none")) {
         /*
          * Files on the fileserver are set to QEMU credentials.
          */
         s->ctx.fs_sm = SM_NONE;
-
+        s->ctx.xops = none_xattr_ops;
     } else {
         fprintf(stderr, "Default to security_model=none. You may want"
                 " enable advanced security model using "
                 "security option:\n\t security_model=passthrough \n\t "
                 "security_model=mapped\n");
         s->ctx.fs_sm = SM_NONE;
+        s->ctx.xops = none_xattr_ops;
     }
 
     if (lstat(fse->path, &stat)) {
commit 0f8151cb75e09c9a7de24a37f22166e46a9eaf7b
Author: Venkateswararao Jujjuri (JV) <jvrao at linux.vnet.ibm.com>
Date:   Sun Sep 19 10:47:11 2010 -0700

    [virtio-9p] Ignore O_DIRECT hint from client.
    
    The O_DIRECT flag imposes alignment restrictions on the length and address
    of userspace buffers and the file offset of I/Os.
    
    While VirtFS/9P has plans to implement O_DIRECT behavior on the server,
    for now we will stick to a behavior like NFS by bypassing the page cache
    only on the client. Server may still cache the I/O.
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 6c80795..cb6366b 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1704,6 +1704,8 @@ static void v9fs_open_post_lstat(V9fsState *s, V9fsOpenState *vs, int err)
         if (s->proto_version == V9FS_PROTO_2000L) {
             flags = vs->mode;
             flags &= ~(O_NOCTTY | O_ASYNC | O_CREAT);
+            /* Ignore direct disk access hint until the server supports it. */
+            flags &= ~O_DIRECT;
         } else {
             flags = omode_to_uflags(vs->mode);
         }
@@ -1826,6 +1828,9 @@ static void v9fs_lcreate(V9fsState *s, V9fsPDU *pdu)
     v9fs_string_sprintf(&vs->fullname, "%s/%s", vs->fidp->path.data,
              vs->name.data);
 
+    /* Ignore direct disk access hint until the server supports it. */
+    flags &= ~O_DIRECT;
+
     vs->fidp->fs.fd = v9fs_do_open2(s, vs->fullname.data, vs->fidp->uid,
             gid, flags, mode);
     v9fs_lcreate_post_do_open2(s, vs, err);
commit df0973a4650d4889463ff66cb6fbdf0ab8090c70
Author: M. Mohan Kumar <mohan at in.ibm.com>
Date:   Tue Sep 14 15:08:25 2010 +0530

    qemu-virtio-9p: Implement TREADLINK operation for 9p2000.L
    
    Synopsis
    
            size[4] TReadlink tag[2] fid[4]
            size[4] RReadlink tag[2] target[s]
    
    Description
            Readlink is used to return the contents of the symoblic link
            referred by fid. Contents of symboic link is returned as a
            response.
    
            target[s] - Contents of the symbolic link referred by fid.
    
    Signed-off-by: M. Mohan Kumar <mohan at in.ibm.com>
    Reviewed-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c
index 8f3c321..cff5b07 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -502,6 +502,14 @@ void pprint_pdu(V9fsPDU *pdu)
         fprintf(llogfile, "RMKNOD: )");
         pprint_qid(pdu, 0, &offset, "qid");
         break;
+    case P9_TREADLINK:
+	fprintf(llogfile, "TREADLINK: (");
+        pprint_int32(pdu, 0, &offset, "fid");
+        break;
+    case P9_RREADLINK:
+	fprintf(llogfile, "RREADLINK: (");
+        pprint_str(pdu, 0, &offset, "target");
+        break;
     case P9_TREAD:
         fprintf(llogfile, "TREAD: (");
         pprint_int32(pdu, 0, &offset, "fid");
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index e8eec7f..6c80795 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -3520,6 +3520,49 @@ out:
     qemu_free(vs);
 }
 
+static void v9fs_readlink_post_readlink(V9fsState *s, V9fsReadLinkState *vs,
+                                                    int err)
+{
+    if (err < 0) {
+        err = -errno;
+        goto out;
+    }
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "s", &vs->target);
+    err = vs->offset;
+out:
+    complete_pdu(s, vs->pdu, err);
+    v9fs_string_free(&vs->target);
+    qemu_free(vs);
+}
+
+static void v9fs_readlink(V9fsState *s, V9fsPDU *pdu)
+{
+    int32_t fid;
+    V9fsReadLinkState *vs;
+    int err = 0;
+    V9fsFidState *fidp;
+
+    vs = qemu_malloc(sizeof(*vs));
+    vs->pdu = pdu;
+    vs->offset = 7;
+
+    pdu_unmarshal(vs->pdu, vs->offset, "d", &fid);
+
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
+        err = -ENOENT;
+        goto out;
+    }
+
+    v9fs_string_init(&vs->target);
+    err = v9fs_do_readlink(s, &fidp->path, &vs->target);
+    v9fs_readlink_post_readlink(s, vs, err);
+    return;
+out:
+    complete_pdu(s, vs->pdu, err);
+    qemu_free(vs);
+}
+
 typedef void (pdu_handler_t)(V9fsState *s, V9fsPDU *pdu);
 
 static pdu_handler_t *pdu_handlers[] = {
@@ -3533,6 +3576,7 @@ static pdu_handler_t *pdu_handlers[] = {
     [P9_TRENAME] = v9fs_rename,
     [P9_TLOCK] = v9fs_lock,
     [P9_TGETLOCK] = v9fs_getlock,
+    [P9_TREADLINK] = v9fs_readlink,
     [P9_TMKDIR] = v9fs_mkdir,
     [P9_TVERSION] = v9fs_version,
     [P9_TLOPEN] = v9fs_open,
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 637cea6..6c23319 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -27,6 +27,8 @@ enum {
     P9_RMKNOD,
     P9_TRENAME = 20,
     P9_RRENAME,
+    P9_TREADLINK = 22,
+    P9_RREADLINK,
     P9_TGETATTR = 24,
     P9_RGETATTR,
     P9_TSETATTR = 26,
@@ -486,6 +488,12 @@ typedef struct V9fsGetlockState
     V9fsGetlock *glock;
 } V9fsGetlockState;
 
+typedef struct V9fsReadLinkState
+{
+    V9fsPDU *pdu;
+    size_t offset;
+    V9fsString target;
+} V9fsReadLinkState;
 
 extern size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
                             size_t offset, size_t size, int pack);
commit b41e95d34877c1917ba9fca7ca8f5d4122d4c619
Author: Venkateswararao Jujjuri (JV) <jvrao at linux.vnet.ibm.com>
Date:   Wed Sep 22 17:18:33 2010 -0700

    [virtio-9p] Introduce server side TFSYNC/RFSYNC for dotl
    
    SYNOPSIS
        size[4] Tfsync tag[2] fid[4]
    
        size[4] Rfsync tag[2]
    
    DESCRIPTION
    
    The Tfsync transaction transfers ("flushes") all modified in-core data of
    file identified by fid to the disk device (or other  permanent  storage
    device)  where that  file  resides.
    
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c
index 85c9900..8f3c321 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -535,6 +535,13 @@ void pprint_pdu(V9fsPDU *pdu)
     case P9_RCLUNK:
         fprintf(llogfile, "RCLUNK: (");
         break;
+    case P9_TFSYNC:
+        fprintf(llogfile, "TFSYNC: (");
+        pprint_int32(pdu, 0, &offset, "fid");
+        break;
+    case P9_RFSYNC:
+        fprintf(llogfile, "RFSYNC: (");
+        break;
     case P9_TLINK:
         fprintf(llogfile, "TLINK: (");
         pprint_int32(pdu, 0, &offset, "fid");
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 8ae233e..e8eec7f 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1837,6 +1837,32 @@ out:
     qemu_free(vs);
 }
 
+static void v9fs_post_do_fsync(V9fsState *s, V9fsPDU *pdu, int err)
+{
+    if (err == -1) {
+        err = -errno;
+    }
+    complete_pdu(s, pdu, err);
+}
+
+static void v9fs_fsync(V9fsState *s, V9fsPDU *pdu)
+{
+    int32_t fid;
+    size_t offset = 7;
+    V9fsFidState *fidp;
+    int err;
+
+    pdu_unmarshal(pdu, offset, "d", &fid);
+    fidp = lookup_fid(s, fid);
+    if (fidp == NULL) {
+        err = -ENOENT;
+        v9fs_post_do_fsync(s, pdu, err);
+        return;
+    }
+    err = v9fs_do_fsync(s, fidp->fs.fd);
+    v9fs_post_do_fsync(s, pdu, err);
+}
+
 static void v9fs_clunk(V9fsState *s, V9fsPDU *pdu)
 {
     int32_t fid;
@@ -3514,6 +3540,7 @@ static pdu_handler_t *pdu_handlers[] = {
     [P9_TSTAT] = v9fs_stat,
     [P9_TWALK] = v9fs_walk,
     [P9_TCLUNK] = v9fs_clunk,
+    [P9_TFSYNC] = v9fs_fsync,
     [P9_TOPEN] = v9fs_open,
     [P9_TREAD] = v9fs_read,
 #if 0
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 6a68895..637cea6 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -37,6 +37,8 @@ enum {
     P9_RXATTRCREATE,
     P9_TREADDIR = 40,
     P9_RREADDIR,
+    P9_TFSYNC = 50,
+    P9_RFSYNC,
     P9_TLOCK = 52,
     P9_RLOCK,
     P9_TGETLOCK = 54,
commit 8f35400358488ffa1147e9eab9e2c9cf0efd5e4e
Author: M. Mohan Kumar <mohan at in.ibm.com>
Date:   Wed Sep 8 02:36:52 2010 +0530

    qemu-virtio9p: Implement TGETLOCK
    
    Synopsis
    
        size[4] TGetlock tag[2] fid[4] getlock[n]
        size[4] RGetlock tag[2] getlock[n]
    
    Description
    
    TGetlock is used to test for the existence of byte range posix locks on
    a file identified by given fid. The reply contains getlock structure. If
    the lock could be placed it returns F_UNLCK in type field of getlock structure.
    Otherwise it returns the details of the conflicting locks in the getlock
    structure
    
        getlock structure:
          type[1] - Type of lock: F_RDLCK, F_WRLCK
          start[8] - Starting offset for lock
          length[8] - Number of bytes to lock
            If length is 0, lock all bytes starting at the location
            'start' through to the end of file
          proc_id[4] - process id that wants to take lock/owns the task
                   in case of reply
          client[4] - Client id of the system that owns the process
    
    Signed-off-by: M. Mohan Kumar <mohan at in.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c
index 045774f..85c9900 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -602,6 +602,23 @@ void pprint_pdu(V9fsPDU *pdu)
         fprintf(llogfile, "RLOCK: (");
         pprint_int8(pdu, 0, &offset, "status");
         break;
+    case P9_TGETLOCK:
+        fprintf(llogfile, "TGETLOCK: (");
+        pprint_int32(pdu, 0, &offset, "fid");
+        pprint_int8(pdu, 0, &offset, ", type");
+        pprint_int64(pdu, 0, &offset, ", start");
+        pprint_int64(pdu, 0, &offset, ", length");
+        pprint_int32(pdu, 0, &offset, ", proc_id");
+        pprint_str(pdu, 0, &offset, ", client_id");
+        break;
+    case P9_RGETLOCK:
+        fprintf(llogfile, "RGETLOCK: (");
+        pprint_int8(pdu, 0, &offset, "type");
+        pprint_int64(pdu, 0, &offset, ", start");
+        pprint_int64(pdu, 0, &offset, ", length");
+        pprint_int32(pdu, 0, &offset, ", proc_id");
+        pprint_str(pdu, 0, &offset, ", client_id");
+        break;
     default:
         fprintf(llogfile, "unknown(%d): (", pdu->id);
         break;
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 20acb5b..8ae233e 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -3203,6 +3203,46 @@ out:
     qemu_free(vs);
 }
 
+/*
+ * When a TGETLOCK request comes, always return success because all lock
+ * handling is done by client's VFS layer.
+ */
+
+static void v9fs_getlock(V9fsState *s, V9fsPDU *pdu)
+{
+    int32_t fid, err = 0;
+    V9fsGetlockState *vs;
+
+    vs = qemu_mallocz(sizeof(*vs));
+    vs->pdu = pdu;
+    vs->offset = 7;
+
+    vs->glock = qemu_malloc(sizeof(*vs->glock));
+    pdu_unmarshal(vs->pdu, vs->offset, "dbqqds", &fid, &vs->glock->type,
+                &vs->glock->start, &vs->glock->length, &vs->glock->proc_id,
+		&vs->glock->client_id);
+
+    vs->fidp = lookup_fid(s, fid);
+    if (vs->fidp == NULL) {
+        err = -ENOENT;
+        goto out;
+    }
+
+    err = v9fs_do_fstat(s, vs->fidp->fs.fd, &vs->stbuf);
+    if (err < 0) {
+        err = -errno;
+        goto out;
+    }
+    vs->glock->type = F_UNLCK;
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "bqqds", vs->glock->type,
+                vs->glock->start, vs->glock->length, vs->glock->proc_id,
+		&vs->glock->client_id);
+out:
+    complete_pdu(s, vs->pdu, err);
+    qemu_free(vs->glock);
+    qemu_free(vs);
+}
+
 static void v9fs_mkdir_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
 {
     if (err == -1) {
@@ -3466,6 +3506,7 @@ static pdu_handler_t *pdu_handlers[] = {
     [P9_TMKNOD] = v9fs_mknod,
     [P9_TRENAME] = v9fs_rename,
     [P9_TLOCK] = v9fs_lock,
+    [P9_TGETLOCK] = v9fs_getlock,
     [P9_TMKDIR] = v9fs_mkdir,
     [P9_TVERSION] = v9fs_version,
     [P9_TLOPEN] = v9fs_open,
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 4555f39..6a68895 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -39,6 +39,8 @@ enum {
     P9_RREADDIR,
     P9_TLOCK = 52,
     P9_RLOCK,
+    P9_TGETLOCK = 54,
+    P9_RGETLOCK,
     P9_TLINK = 70,
     P9_RLINK,
     P9_TMKDIR = 72,
@@ -464,6 +466,25 @@ typedef struct V9fsLockState
     V9fsFlock *flock;
 } V9fsLockState;
 
+typedef struct V9fsGetlock
+{
+    uint8_t type;
+    uint64_t start; /* absolute offset */
+    uint64_t length;
+    uint32_t proc_id;
+    V9fsString client_id;
+} V9fsGetlock;
+
+typedef struct V9fsGetlockState
+{
+    V9fsPDU *pdu;
+    size_t offset;
+    struct stat stbuf;
+    V9fsFidState *fidp;
+    V9fsGetlock *glock;
+} V9fsGetlockState;
+
+
 extern size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
                             size_t offset, size_t size, int pack);
 
commit 82cc3ee88ba238ec3ba96f4673d8a184588b82a4
Author: M. Mohan Kumar <mohan at in.ibm.com>
Date:   Wed Sep 8 02:19:32 2010 +0530

    [virto-9p] Implement TLOCK
    
    Synopsis
    
        size[4] TLock tag[2] fid[4] flock[n]
        size[4] RLock tag[2] status[1]
    
    Description
    
    Tlock is used to acquire/release byte range posix locks on a file
    identified by given fid. The reply contains status of the lock request
    
        flock structure:
            type[1] - Type of lock: F_RDLCK, F_WRLCK, F_UNLCK
            flags[4] - Flags could be either of
              P9_LOCK_FLAGS_BLOCK(1) - Blocked lock request, if there is a
                conflicting lock exists, wait for that lock to be released.
              P9_LOCK_FLAGS_RECLAIM(2) - Reclaim lock request, used when client is
                trying to reclaim a lock after a server restrart (due to crash)
            start[8] - Starting offset for lock
            length[8] - Number of bytes to lock
              If length is 0, lock all bytes starting at the location 'start'
              through to the end of file
            pid[4] - PID of the process that wants to take lock
            client_id[4] - Unique client id
    
            status[1] - Status of the lock request, can be
              P9_LOCK_SUCCESS(0), P9_LOCK_BLOCKED(1), P9_LOCK_ERROR(2) or
              P9_LOCK_GRACE(3)
              P9_LOCK_SUCCESS - Request was successful
              P9_LOCK_BLOCKED - A conflicting lock is held by another process
              P9_LOCK_ERROR - Error while processing the lock request
              P9_LOCK_GRACE - Server is in grace period, it can't accept new lock
                    requests in this period (except locks with
                    P9_LOCK_FLAGS_RECLAIM flag set)
    
    Signed-off-by: M. Mohan Kumar <mohan at in.ibm.com>
    Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/hw/virtio-9p-debug.c b/hw/virtio-9p-debug.c
index 6f6a0ec..045774f 100644
--- a/hw/virtio-9p-debug.c
+++ b/hw/virtio-9p-debug.c
@@ -588,6 +588,20 @@ void pprint_pdu(V9fsPDU *pdu)
     case P9_RXATTRCREATE:
         fprintf(llogfile, "RXATTRCREATE: (");
         break;
+    case P9_TLOCK:
+        fprintf(llogfile, "TLOCK: (");
+        pprint_int32(pdu, 0, &offset, "fid");
+        pprint_int8(pdu, 0, &offset, ", type");
+        pprint_int32(pdu, 0, &offset, ", flags");
+        pprint_int64(pdu, 0, &offset, ", start");
+        pprint_int64(pdu, 0, &offset, ", length");
+        pprint_int32(pdu, 0, &offset, ", proc_id");
+        pprint_str(pdu, 0, &offset, ", client_id");
+        break;
+    case P9_RLOCK:
+        fprintf(llogfile, "RLOCK: (");
+        pprint_int8(pdu, 0, &offset, "status");
+        break;
     default:
         fprintf(llogfile, "unknown(%d): (", pdu->id);
         break;
diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 3379a30..20acb5b 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -3154,6 +3154,55 @@ out:
     qemu_free(vs);
 }
 
+/*
+ * Implement posix byte range locking code
+ * Server side handling of locking code is very simple, because 9p server in
+ * QEMU can handle only one client. And most of the lock handling
+ * (like conflict, merging) etc is done by the VFS layer itself, so no need to
+ * do any thing in * qemu 9p server side lock code path.
+ * So when a TLOCK request comes, always return success
+ */
+
+static void v9fs_lock(V9fsState *s, V9fsPDU *pdu)
+{
+    int32_t fid, err = 0;
+    V9fsLockState *vs;
+
+    vs = qemu_mallocz(sizeof(*vs));
+    vs->pdu = pdu;
+    vs->offset = 7;
+
+    vs->flock = qemu_malloc(sizeof(*vs->flock));
+    pdu_unmarshal(vs->pdu, vs->offset, "dbdqqds", &fid, &vs->flock->type,
+                &vs->flock->flags, &vs->flock->start, &vs->flock->length,
+                            &vs->flock->proc_id, &vs->flock->client_id);
+
+    vs->status = P9_LOCK_ERROR;
+
+    /* We support only block flag now (that too ignored currently) */
+    if (vs->flock->flags & ~P9_LOCK_FLAGS_BLOCK) {
+        err = -EINVAL;
+        goto out;
+    }
+    vs->fidp = lookup_fid(s, fid);
+    if (vs->fidp == NULL) {
+        err = -ENOENT;
+        goto out;
+    }
+
+    err = v9fs_do_fstat(s, vs->fidp->fs.fd, &vs->stbuf);
+    if (err < 0) {
+        err = -errno;
+        goto out;
+    }
+    vs->status = P9_LOCK_SUCCESS;
+out:
+    vs->offset += pdu_marshal(vs->pdu, vs->offset, "b", vs->status);
+    complete_pdu(s, vs->pdu, err);
+    qemu_free(vs->flock);
+    qemu_free(vs);
+}
+
 static void v9fs_mkdir_post_lstat(V9fsState *s, V9fsMkState *vs, int err)
 {
     if (err == -1) {
@@ -3416,6 +3465,7 @@ static pdu_handler_t *pdu_handlers[] = {
     [P9_TXATTRCREATE] = v9fs_xattrcreate,
     [P9_TMKNOD] = v9fs_mknod,
     [P9_TRENAME] = v9fs_rename,
+    [P9_TLOCK] = v9fs_lock,
     [P9_TMKDIR] = v9fs_mkdir,
     [P9_TVERSION] = v9fs_version,
     [P9_TLOPEN] = v9fs_open,
diff --git a/hw/virtio-9p.h b/hw/virtio-9p.h
index 0816ad6..4555f39 100644
--- a/hw/virtio-9p.h
+++ b/hw/virtio-9p.h
@@ -37,6 +37,8 @@ enum {
     P9_RXATTRCREATE,
     P9_TREADDIR = 40,
     P9_RREADDIR,
+    P9_TLOCK = 52,
+    P9_RLOCK,
     P9_TLINK = 70,
     P9_RLINK,
     P9_TMKDIR = 72,
@@ -434,6 +436,34 @@ typedef struct V9fsXattrState
     void *value;
 } V9fsXattrState;
 
+#define P9_LOCK_SUCCESS 0
+#define P9_LOCK_BLOCKED 1
+#define P9_LOCK_ERROR 2
+#define P9_LOCK_GRACE 3
+
+#define P9_LOCK_FLAGS_BLOCK 1
+#define P9_LOCK_FLAGS_RECLAIM 2
+
+typedef struct V9fsFlock
+{
+    uint8_t type;
+    uint32_t flags;
+    uint64_t start; /* absolute offset */
+    uint64_t length;
+    uint32_t proc_id;
+    V9fsString client_id;
+} V9fsFlock;
+
+typedef struct V9fsLockState
+{
+    V9fsPDU *pdu;
+    size_t offset;
+    int8_t status;
+    struct stat stbuf;
+    V9fsFidState *fidp;
+    V9fsFlock *flock;
+} V9fsLockState;
+
 extern size_t pdu_packunpack(void *addr, struct iovec *sg, int sg_count,
                             size_t offset, size_t size, int pack);
 
commit ab03b63d7a9c7978d51e56c191f0b86888d121dc
Author: Sripathi Kodi <sripathik at in.ibm.com>
Date:   Mon Sep 20 23:24:29 2010 +0530

    [virtio-9p] open should not return EBADF
    
    When 9P server fails to create a file due to permission problems it should
    return EPERM. However the current 9P2000.L code returns EBADF. EBADF is NOT
    a valid return value from open() call.
    
    The problem is because we do not preserve the errno variable properly. If the
    file open had failed, the call to close() on the fd in v9fs_post_lcreate()
    fails and sets errno to EBADF. We should preserve the errno that we got from
    open() and we should call close() only if we had a valid fd.
    
    Signed-off-by: Sripathi Kodi <sripathik at in.ibm.com>
    Signed-off-by: Venkateswararao Jujjuri <jvrao at linux.vnet.ibm.com>

diff --git a/hw/virtio-9p.c b/hw/virtio-9p.c
index 3b2d49c..3379a30 100644
--- a/hw/virtio-9p.c
+++ b/hw/virtio-9p.c
@@ -1760,8 +1760,10 @@ static void v9fs_post_lcreate(V9fsState *s, V9fsLcreateState *vs, int err)
         err = vs->offset;
     } else {
         vs->fidp->fid_type = P9_FID_NONE;
-        close(vs->fidp->fs.fd);
         err = -errno;
+        if (vs->fidp->fs.fd > 0) {
+            close(vs->fidp->fs.fd);
+        }
     }
 
     complete_pdu(s, vs->pdu, err);
commit a12c668f0a44bbbb7b9bc2b852c62f6864c8b92d
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Wed Oct 20 16:41:36 2010 +0000

    trace: improve info trace output
    
    Use PRI*64 to print full 64 bit data even on ILP32 hosts.
    
    Print also sixth tracepoint parameter.
    
    Acked-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Cc: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/simpletrace.c b/simpletrace.c
index deb1e07..b488d51 100644
--- a/simpletrace.c
+++ b/simpletrace.c
@@ -214,9 +214,11 @@ void st_print_trace(FILE *stream, int (*stream_printf)(FILE *stream, const char
     unsigned int i;
 
     for (i = 0; i < trace_idx; i++) {
-        stream_printf(stream, "Event %lu : %lx %lx %lx %lx %lx\n",
+        stream_printf(stream, "Event %" PRIu64 " : %" PRIx64 " %" PRIx64
+                      " %" PRIx64 " %" PRIx64 " %" PRIx64 " %" PRIx64 "\n",
                       trace_buf[i].event, trace_buf[i].x1, trace_buf[i].x2,
-                      trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5);
+                      trace_buf[i].x3, trace_buf[i].x4, trace_buf[i].x5,
+                      trace_buf[i].x6);
     }
 }
 
commit cf85cf8e972f3ad79f203be4edb7968d6e052293
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Wed Oct 20 16:41:31 2010 +0000

    trace: Format strings must begin/end with double quotes
    
    Document the restriction that format strings must begin and end with
    double quotes.  This is for easy parsing since we don't run cpp over
    trace-events.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/docs/tracing.txt b/docs/tracing.txt
index 5504850..963c504 100644
--- a/docs/tracing.txt
+++ b/docs/tracing.txt
@@ -74,7 +74,10 @@ Trace events should use types as follows:
 
 Format strings should reflect the types defined in the trace event.  Take
 special care to use PRId64 and PRIu64 for int64_t and uint64_t types,
-respectively.  This ensures portability between 32- and 64-bit platforms.
+respectively.  This ensures portability between 32- and 64-bit platforms.  Note
+that format strings must begin and end with double quotes.  When using
+portability macros, ensure they are preceded and followed by double quotes:
+"value %"PRIx64"".
 
 === Hints for adding new trace events ===
 
commit d8023f311499e06c02b4da7e74388d7ad906ea23
Author: Blue Swirl <blauwirbel at gmail.com>
Date:   Wed Oct 20 16:41:28 2010 +0000

    apic: convert debug printf statements to tracepoints
    
    Replace debug printf statements with tracepoints.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/hw/apic.c b/hw/apic.c
index d686b51..63d62c7 100644
--- a/hw/apic.c
+++ b/hw/apic.c
@@ -21,23 +21,7 @@
 #include "qemu-timer.h"
 #include "host-utils.h"
 #include "sysbus.h"
-
-//#define DEBUG_APIC
-//#define DEBUG_COALESCING
-
-#ifdef DEBUG_APIC
-#define DPRINTF(fmt, ...)                                       \
-    do { printf("apic: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF(fmt, ...)
-#endif
-
-#ifdef DEBUG_COALESCING
-#define DPRINTF_C(fmt, ...)                                     \
-    do { printf("apic: " fmt , ## __VA_ARGS__); } while (0)
-#else
-#define DPRINTF_C(fmt, ...)
-#endif
+#include "trace.h"
 
 /* APIC Local Vector Table */
 #define APIC_LVT_TIMER   0
@@ -168,8 +152,8 @@ static void apic_local_deliver(APICState *s, int vector)
     uint32_t lvt = s->lvt[vector];
     int trigger_mode;
 
-    DPRINTF("%s: vector %d delivery mode %d\n", __func__, vector,
-            (lvt >> 8) & 7);
+    trace_apic_local_deliver(vector, (lvt >> 8) & 7);
+
     if (lvt & APIC_LVT_MASKED)
         return;
 
@@ -300,9 +284,9 @@ void apic_deliver_irq(uint8_t dest, uint8_t dest_mode,
 {
     uint32_t deliver_bitmask[MAX_APIC_WORDS];
 
-    DPRINTF("%s: dest %d dest_mode %d delivery_mode %d vector %d"
-            " polarity %d trigger_mode %d\n", __func__, dest, dest_mode,
-            delivery_mode, vector_num, polarity, trigger_mode);
+    trace_apic_deliver_irq(dest, dest_mode, delivery_mode, vector_num,
+                           polarity, trigger_mode);
+
     apic_get_delivery_bitmask(deliver_bitmask, dest, dest_mode);
     apic_bus_deliver(deliver_bitmask, delivery_mode, vector_num, polarity,
                      trigger_mode);
@@ -312,7 +296,8 @@ void cpu_set_apic_base(DeviceState *d, uint64_t val)
 {
     APICState *s = DO_UPCAST(APICState, busdev.qdev, d);
 
-    DPRINTF("cpu_set_apic_base: %016" PRIx64 "\n", val);
+    trace_cpu_set_apic_base(val);
+
     if (!s)
         return;
     s->apicbase = (val & 0xfffff000) |
@@ -329,8 +314,8 @@ uint64_t cpu_get_apic_base(DeviceState *d)
 {
     APICState *s = DO_UPCAST(APICState, busdev.qdev, d);
 
-    DPRINTF("cpu_get_apic_base: %016" PRIx64 "\n",
-            s ? (uint64_t)s->apicbase: 0);
+    trace_cpu_get_apic_base(s ? (uint64_t)s->apicbase: 0);
+
     return s ? s->apicbase : 0;
 }
 
@@ -402,20 +387,23 @@ static void apic_update_irq(APICState *s)
 
 void apic_reset_irq_delivered(void)
 {
-    DPRINTF_C("%s: old coalescing %d\n", __func__, apic_irq_delivered);
+    trace_apic_reset_irq_delivered(apic_irq_delivered);
+
     apic_irq_delivered = 0;
 }
 
 int apic_get_irq_delivered(void)
 {
-    DPRINTF_C("%s: returning coalescing %d\n", __func__, apic_irq_delivered);
+    trace_apic_get_irq_delivered(apic_irq_delivered);
+
     return apic_irq_delivered;
 }
 
 static void apic_set_irq(APICState *s, int vector_num, int trigger_mode)
 {
     apic_irq_delivered += !get_bit(s->irr, vector_num);
-    DPRINTF_C("%s: coalescing %d\n", __func__, apic_irq_delivered);
+
+    trace_apic_set_irq(apic_irq_delivered);
 
     set_bit(s->irr, vector_num);
     if (trigger_mode)
@@ -769,7 +757,7 @@ static uint32_t apic_mem_readl(void *opaque, target_phys_addr_t addr)
         val = 0;
         break;
     }
-    DPRINTF("read: " TARGET_FMT_plx " = %08x\n", addr, val);
+    trace_apic_mem_readl(addr, val);
     return val;
 }
 
@@ -805,7 +793,7 @@ static void apic_mem_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
     }
     s = DO_UPCAST(APICState, busdev.qdev, d);
 
-    DPRINTF("write: " TARGET_FMT_plx " = %08x\n", addr, val);
+    trace_apic_mem_writel(addr, val);
 
     switch(index) {
     case 0x02:
diff --git a/trace-events b/trace-events
index 4300178..ed2055e 100644
--- a/trace-events
+++ b/trace-events
@@ -69,3 +69,15 @@ disable cpu_out(unsigned int addr, unsigned int val) "addr %#x value %u"
 # balloon.c
 # Since requests are raised via monitor, not many tracepoints are needed.
 disable balloon_event(void *opaque, unsigned long addr) "opaque %p addr %lu"
+
+# hw/apic.c
+disable apic_local_deliver(int vector, uint32_t lvt) "vector %d delivery mode %d"
+disable apic_deliver_irq(uint8_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t vector_num, uint8_t polarity, uint8_t trigger_mode) "dest %d dest_mode %d delivery_mode %d vector %d polarity %d trigger_mode %d"
+disable cpu_set_apic_base(uint64_t val) "%016"PRIx64""
+disable cpu_get_apic_base(uint64_t val) "%016"PRIx64""
+disable apic_mem_readl(uint64_t addr, uint32_t val)  "%"PRIx64" = %08x"
+disable apic_mem_writel(uint64_t addr, uint32_t val) "%"PRIx64" = %08x"
+# coalescing
+disable apic_reset_irq_delivered(int apic_irq_delivered) "old coalescing %d"
+disable apic_get_irq_delivered(int apic_irq_delivered) "returning coalescing %d"
+disable apic_set_irq(int apic_irq_delivered) "coalescing %d"
commit 6df40080b00ecd004466714c25cb762056036c56
Author: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
Date:   Mon Oct 18 13:42:54 2010 +0100

    trace: Relax trace-events parsing regex in simpletrace.py
    
    The regular expression to parse trace event definitions assumed the
    format string would be a simple double-quoted string.  However, we now
    use PRI?64 for portability which splits string literals.  The regular
    expression can disregard the format string entirely since simpletrace.py
    never needs to use it.
    
    Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
    Signed-off-by: Blue Swirl <blauwirbel at gmail.com>

diff --git a/simpletrace.py b/simpletrace.py
index c2cf168..553a727 100755
--- a/simpletrace.py
+++ b/simpletrace.py
@@ -19,7 +19,7 @@ header_version  = 0
 
 trace_fmt = '=QQQQQQQQ'
 trace_len = struct.calcsize(trace_fmt)
-event_re  = re.compile(r'(disable\s+)?([a-zA-Z0-9_]+)\(([^)]*)\)\s+"([^"]*)"')
+event_re  = re.compile(r'(disable\s+)?([a-zA-Z0-9_]+)\(([^)]*)\).*')
 
 def err(msg):
     sys.stderr.write(msg + '\n')
@@ -39,7 +39,7 @@ def parse_events(fobj):
         if m is None:
             continue
 
-        disable, name, args, fmt = m.groups()
+        disable, name, args = m.groups()
         events[event_num] = (name,) + get_argnames(args)
         event_num += 1
     return events
commit 38cc9b607f85017b095793cab6c129bc9844f441
Author: Jindrich Makovicka <makovick at gmail.com>
Date:   Sun Oct 17 20:17:19 2010 +0200

    issue snd_pcm_start() when capturing audio
    
    snd_pcm_start() starts the capture process and ensures that the events
    are delivered to the poll handler. Without the call, capture can be started
    only when there is simultaneous playback running.
    
    Signed-off-by: Jindrich Makovicka <makovick at gmail.com>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 3ca4078..0741203 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -843,11 +843,15 @@ static int alsa_init_out (HWVoiceOut *hw, struct audsettings *as)
     return 0;
 }
 
-static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
+#define VOICE_CTL_PAUSE 0
+#define VOICE_CTL_PREPARE 1
+#define VOICE_CTL_START 2
+
+static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int ctl)
 {
     int err;
 
-    if (pause) {
+    if (ctl == VOICE_CTL_PAUSE) {
         err = snd_pcm_drop (handle);
         if (err < 0) {
             alsa_logerr (err, "Could not stop %s\n", typ);
@@ -860,6 +864,13 @@ static int alsa_voice_ctl (snd_pcm_t *handle, const char *typ, int pause)
             alsa_logerr (err, "Could not prepare handle for %s\n", typ);
             return -1;
         }
+        if (ctl == VOICE_CTL_START) {
+            err = snd_pcm_start(handle);
+            if (err < 0) {
+                alsa_logerr (err, "Could not start handle for %s\n", typ);
+                return -1;
+            }
+        }
     }
 
     return 0;
@@ -884,7 +895,7 @@ static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
                 poll_mode = 0;
             }
             hw->poll_mode = poll_mode;
-            return alsa_voice_ctl (alsa->handle, "playback", 0);
+            return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PREPARE);
         }
 
     case VOICE_DISABLE:
@@ -893,7 +904,7 @@ static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
             hw->poll_mode = 0;
             alsa_fini_poll (&alsa->pollhlp);
         }
-        return alsa_voice_ctl (alsa->handle, "playback", 1);
+        return alsa_voice_ctl (alsa->handle, "playback", VOICE_CTL_PAUSE);
     }
 
     return -1;
@@ -1106,7 +1117,7 @@ static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
             }
             hw->poll_mode = poll_mode;
 
-            return alsa_voice_ctl (alsa->handle, "capture", 0);
+            return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_START);
         }
 
     case VOICE_DISABLE:
@@ -1115,7 +1126,7 @@ static int alsa_ctl_in (HWVoiceIn *hw, int cmd, ...)
             hw->poll_mode = 0;
             alsa_fini_poll (&alsa->pollhlp);
         }
-        return alsa_voice_ctl (alsa->handle, "capture", 1);
+        return alsa_voice_ctl (alsa->handle, "capture", VOICE_CTL_PAUSE);
     }
 
     return -1;
commit 22d948a2d97434192018bdabaf0a50cda7f994be
Author: Jindrich Makovicka <makovick at gmail.com>
Date:   Sun Oct 17 19:28:14 2010 +0200

    fix 100% CPU load when idle with ALSA
    
    Playback control function did not disable polling when playback stops.
    Caused busy spinning of the main loop due to unprocessed events.
    
    Signed-off-by: Jindrich Makovicka <makovick at gmail.com>
    Signed-off-by: malc <av1474 at comtv.ru>

diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index f0171f9..3ca4078 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -889,6 +889,10 @@ static int alsa_ctl_out (HWVoiceOut *hw, int cmd, ...)
 
     case VOICE_DISABLE:
         ldebug ("disabling voice\n");
+        if (hw->poll_mode) {
+            hw->poll_mode = 0;
+            alsa_fini_poll (&alsa->pollhlp);
+        }
         return alsa_voice_ctl (alsa->handle, "playback", 1);
     }
 


More information about the Spice-commits mailing list