[qemu] Add patches from 1.0.1 queue
Justin M. Forbes
jforbes at fedoraproject.org
Wed Jan 11 21:29:17 UTC 2012
commit 45e84a0f42d47f3aed719e487256ee458f98d9b6
Author: Justin M. Forbes <jforbes at redhat.com>
Date: Wed Jan 11 15:27:49 2012 -0600
Add patches from 1.0.1 queue
...out-tcp-socket-close-code-in-a-separate-f.patch | 57 --
...-regression-i8259-interrupts-did-not-work.patch | 132 +++
...QemuChrHandlers-struct-to-initialise-char.patch | 882 --------------------
...subpage-memory-access-to-RAM-MemoryRegion.patch | 134 +++
...9pfs-Improve-portability-to-older-systems.patch | 101 +++
...Add-enable-disable_write_fd_handler-funct.patch | 77 --
...-framework-for-a-write-unblocked-callback.patch | 61 --
...-migration-blockers-to-prevent-live-migra.patch | 171 ++++
...-send_all-to-handle-nonblocking-chardev-w.patch | 199 -----
...w-9pfs-Reset-server-state-during-TVERSION.patch | 64 ++
...the-unix-tcp-backend-to-handle-nonblockin.patch | 81 --
...-qdev.reset-callback-for-virtio-9p-pci-de.patch | 57 ++
...har-Throttle-when-host-connection-is-down.patch | 56 --
...-the-correct-file-descriptor-in-Fsdriver-.patch | 210 +++++
...lace-iovec-manipulation-with-QEMUIOVector.patch | 305 +++++++
...ole-Enable-port-throttling-when-chardev-i.patch | 49 --
...-the-correct-signed-type-for-different-va.patch | 133 +++
0009-spice-qemu-char.c-add-throttling.patch | 133 ---
...ce-qemu-char.c-remove-intermediate-buffer.patch | 71 --
...et-i386-fix-cmpxchg-instruction-emulation.patch | 54 ++
...nable-build-by-default-PIE-read-only-relo.patch | 31 +
0011-usb-redir-Add-flow-control-support.patch | 64 --
...cris-Handle-conditional-stores-on-CRISv10.patch | 155 ++++
0012-spice-add-worker-wrapper-functions.patch | 323 -------
0013-pc-add-pc-0.15.patch | 40 +
...-spice-add-qemu_spice_display_init_common.patch | 84 --
...vent_idx-compatibility-for-virtio-devices.patch | 87 ++
0014-spice-qxl-move-worker-wrappers.patch | 294 -------
...f-usb-device-description-with-multiple-co.patch | 56 ++
0015-qxl-fix-surface-tracking-locking.patch | 92 --
0016-qxl-add-io_port_to_string.patch | 71 --
0016-usb-storage-cancel-I-O-on-reset.patch | 40 +
0017-qxl-error-handling-fixes-and-cleanups.patch | 110 ---
...host-properly-release-port-on-unplug-exit.patch | 111 +++
...ake-qxl_guest_bug-take-variable-arguments.patch | 52 --
...-td.cbp-incorrectly-updated-near-page-end.patch | 40 +
...l-only-disallow-specific-io-s-in-vga-mode.patch | 31 -
...et-sh4-ignore-ocbp-and-ocbwb-instructions.patch | 47 +
0020-PPC-Fix-linker-scripts-on-ppc-hosts.patch | 74 ++
...-qxl-async-io-support-using-new-spice-api.patch | 659 ---------------
...iov-prevent-double-free-or-use-after-free.patch | 34 +
..._IO_FLUSH_-SURFACES-RELEASE-for-guest-S3-.patch | 77 --
...witch-per-thread-free-pool-to-a-global-po.patch | 115 +++
0022-qxl-bump-pci-rev.patch | 90 --
...g-rebase-Fix-for-undersized-backing-files.patch | 86 ++
...serial-bus-replay-guest_open-on-migration.patch | 50 --
...tion-Add-qemu-img-t-parameter-in-man-page.patch | 82 ++
0024-qemu-char-make-qemu_chr_event-public.patch | 42 -
...s-set-out-parameter-in-qemu_rbd_snap_list.patch | 39 +
...u-char-Generate-chardev-open-close-events.patch | 79 --
...-usb-redir-Call-qemu_chr_guest_open-close.patch | 37 -
...evice-disconnect-re-connect-robustness-fi.patch | 88 --
...on-t-try-to-write-to-the-chardev-after-a-.patch | 32 -
Fix_save-restore_of_in-kernel_i8259.patch | 87 ++
sources | 2 +-
...o-blk_refuse_SG_IO_requests_with_scsi_off.patch | 111 +++
56 files changed, 2597 insertions(+), 3942 deletions(-)
---
diff --git a/0001-malta-Fix-regression-i8259-interrupts-did-not-work.patch b/0001-malta-Fix-regression-i8259-interrupts-did-not-work.patch
new file mode 100644
index 0000000..a57f4ec
--- /dev/null
+++ b/0001-malta-Fix-regression-i8259-interrupts-did-not-work.patch
@@ -0,0 +1,132 @@
+From 0b23c5d40ea933cfece3b4f69427f79c8a23256d Mon Sep 17 00:00:00 2001
+From: Stefan Weil <sw at weilnetz.de>
+Date: Tue, 29 Nov 2011 06:34:48 +0100
+Subject: [PATCH 01/25] malta: Fix regression (i8259 interrupts did not work)
+
+Commit 5632ae46d5bda798e971dae48ebb318ac2c3686a passes the address
+of i8259 to qemu_irq_proxy. i8259 is an auto variable with undefined
+value outside of mips_malta_init.
+
+This made the interrupt proxy unusable: either QEMU crashes, or
+the interrupt handler was not called.
+
+Ethernet for example no longer worked with MIPS Malta.
+
+v2:
+While v1 used a static variable for i8259, this patch introduces
+a qdev for the malta machine. i8259 is now part of the device status.
+This is a minimal qdev implementation to keep the patch small.
+
+Signed-off-by: Stefan Weil <sw at weilnetz.de>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit e9b40fd34ceb23461083d505a444a389c094455b)
+---
+ hw/mips_malta.c | 39 +++++++++++++++++++++++++++++++++++----
+ 1 files changed, 35 insertions(+), 4 deletions(-)
+
+diff --git a/hw/mips_malta.c b/hw/mips_malta.c
+index bb49749..941b9bd 100644
+--- a/hw/mips_malta.c
++++ b/hw/mips_malta.c
+@@ -47,6 +47,7 @@
+ #include "mc146818rtc.h"
+ #include "blockdev.h"
+ #include "exec-memory.h"
++#include "sysbus.h" /* SysBusDevice */
+
+ //#define DEBUG_BOARD_INIT
+
+@@ -72,6 +73,11 @@ typedef struct {
+ SerialState *uart;
+ } MaltaFPGAState;
+
++typedef struct {
++ SysBusDevice busdev;
++ qemu_irq *i8259;
++} MaltaState;
++
+ static ISADevice *pit;
+
+ static struct _loaderparams {
+@@ -775,7 +781,7 @@ void mips_malta_init (ram_addr_t ram_size,
+ int64_t kernel_entry;
+ PCIBus *pci_bus;
+ CPUState *env;
+- qemu_irq *i8259 = NULL, *isa_irq;
++ qemu_irq *isa_irq;
+ qemu_irq *cpu_exit_irq;
+ int piix4_devfn;
+ i2c_bus *smbus;
+@@ -787,6 +793,11 @@ void mips_malta_init (ram_addr_t ram_size,
+ int fl_sectors = 0;
+ int be;
+
++ DeviceState *dev = qdev_create(NULL, "mips-malta");
++ MaltaState *s = DO_UPCAST(MaltaState, busdev.qdev, dev);
++
++ qdev_init_nofail(dev);
++
+ /* Make sure the first 3 serial ports are associated with a device. */
+ for(i = 0; i < 3; i++) {
+ if (!serial_hds[i]) {
+@@ -932,7 +943,7 @@ void mips_malta_init (ram_addr_t ram_size,
+ * qemu_irq_proxy() adds an extra bit of indirection, allowing us
+ * to resolve the isa_irq -> i8259 dependency after i8259 is initialized.
+ */
+- isa_irq = qemu_irq_proxy(&i8259, 16);
++ isa_irq = qemu_irq_proxy(&s->i8259, 16);
+
+ /* Northbridge */
+ pci_bus = gt64120_register(isa_irq);
+@@ -944,9 +955,9 @@ void mips_malta_init (ram_addr_t ram_size,
+
+ /* Interrupt controller */
+ /* The 8259 is attached to the MIPS CPU INT0 pin, ie interrupt 2 */
+- i8259 = i8259_init(env->irq[2]);
++ s->i8259 = i8259_init(env->irq[2]);
+
+- isa_bus_irqs(i8259);
++ isa_bus_irqs(s->i8259);
+ pci_piix4_ide_init(pci_bus, hd, piix4_devfn + 1);
+ usb_uhci_piix4_init(pci_bus, piix4_devfn + 2);
+ smbus = piix4_pm_init(pci_bus, piix4_devfn + 3, 0x1100, isa_get_irq(9),
+@@ -990,6 +1001,20 @@ void mips_malta_init (ram_addr_t ram_size,
+ }
+ }
+
++static int mips_malta_sysbus_device_init(SysBusDevice *sysbusdev)
++{
++ return 0;
++}
++
++static SysBusDeviceInfo mips_malta_device = {
++ .init = mips_malta_sysbus_device_init,
++ .qdev.name = "mips-malta",
++ .qdev.size = sizeof(MaltaState),
++ .qdev.props = (Property[]) {
++ DEFINE_PROP_END_OF_LIST(),
++ }
++};
++
+ static QEMUMachine mips_malta_machine = {
+ .name = "malta",
+ .desc = "MIPS Malta Core LV",
+@@ -998,9 +1023,15 @@ static QEMUMachine mips_malta_machine = {
+ .is_default = 1,
+ };
+
++static void mips_malta_device_init(void)
++{
++ sysbus_register_withprop(&mips_malta_device);
++}
++
+ static void mips_malta_machine_init(void)
+ {
+ qemu_register_machine(&mips_malta_machine);
+ }
+
++device_init(mips_malta_device_init);
+ machine_init(mips_malta_machine_init);
+--
+1.7.7.5
+
diff --git a/0002-exec.c-Fix-subpage-memory-access-to-RAM-MemoryRegion.patch b/0002-exec.c-Fix-subpage-memory-access-to-RAM-MemoryRegion.patch
new file mode 100644
index 0000000..e49a049
--- /dev/null
+++ b/0002-exec.c-Fix-subpage-memory-access-to-RAM-MemoryRegion.patch
@@ -0,0 +1,134 @@
+From 2061800b85ddcc9b34b5ccbfaa87f7e8b94626a6 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Andreas=20F=C3=A4rber?= <afaerber at suse.de>
+Date: Wed, 30 Nov 2011 16:26:21 +0100
+Subject: [PATCH 02/25] exec.c: Fix subpage memory access to RAM MemoryRegion
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Commit 95c318f5e1f88d7e5bcc6deac17330fd4806a2d3 (Fix segfault in mmio
+subpage handling code.) prevented a segfault by making all subpage
+registrations over an existing memory page perform an unassigned access.
+Symptoms were writes not taking effect and reads returning zero.
+
+Very small page sizes are not currently supported either,
+so subpage memory areas cannot fully be avoided.
+
+Therefore change the previous fix to use a new IO_MEM_SUBPAGE_RAM
+instead of IO_MEM_UNASSIGNED. Suggested by Avi.
+
+Reviewed-by: Avi Kivity <avi at redhat.com>
+Signed-off-by: Andreas Färber <afaerber at suse.de>
+Cc: Avi Kivity <avi at redhat.com>
+Cc: Gleb Natapov <gleb at redhat.com>
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+---
+ cpu-common.h | 1 +
+ exec.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 2 files changed, 64 insertions(+), 2 deletions(-)
+
+diff --git a/cpu-common.h b/cpu-common.h
+index c9878ba..3f45428 100644
+--- a/cpu-common.h
++++ b/cpu-common.h
+@@ -172,6 +172,7 @@ void cpu_physical_memory_write_rom(target_phys_addr_t addr,
+ #define IO_MEM_ROM (1 << IO_MEM_SHIFT) /* hardcoded offset */
+ #define IO_MEM_UNASSIGNED (2 << IO_MEM_SHIFT)
+ #define IO_MEM_NOTDIRTY (3 << IO_MEM_SHIFT)
++#define IO_MEM_SUBPAGE_RAM (4 << IO_MEM_SHIFT)
+
+ /* Acts like a ROM when read and like a device when written. */
+ #define IO_MEM_ROMD (1)
+diff --git a/exec.c b/exec.c
+index 6b92198..6c206ff 100644
+--- a/exec.c
++++ b/exec.c
+@@ -3570,6 +3570,63 @@ static CPUWriteMemoryFunc * const subpage_write[] = {
+ &subpage_writel,
+ };
+
++static uint32_t subpage_ram_readb(void *opaque, target_phys_addr_t addr)
++{
++ ram_addr_t raddr = addr;
++ void *ptr = qemu_get_ram_ptr(raddr);
++ return ldub_p(ptr);
++}
++
++static void subpage_ram_writeb(void *opaque, target_phys_addr_t addr,
++ uint32_t value)
++{
++ ram_addr_t raddr = addr;
++ void *ptr = qemu_get_ram_ptr(raddr);
++ stb_p(ptr, value);
++}
++
++static uint32_t subpage_ram_readw(void *opaque, target_phys_addr_t addr)
++{
++ ram_addr_t raddr = addr;
++ void *ptr = qemu_get_ram_ptr(raddr);
++ return lduw_p(ptr);
++}
++
++static void subpage_ram_writew(void *opaque, target_phys_addr_t addr,
++ uint32_t value)
++{
++ ram_addr_t raddr = addr;
++ void *ptr = qemu_get_ram_ptr(raddr);
++ stw_p(ptr, value);
++}
++
++static uint32_t subpage_ram_readl(void *opaque, target_phys_addr_t addr)
++{
++ ram_addr_t raddr = addr;
++ void *ptr = qemu_get_ram_ptr(raddr);
++ return ldl_p(ptr);
++}
++
++static void subpage_ram_writel(void *opaque, target_phys_addr_t addr,
++ uint32_t value)
++{
++ ram_addr_t raddr = addr;
++ void *ptr = qemu_get_ram_ptr(raddr);
++ stl_p(ptr, value);
++}
++
++static CPUReadMemoryFunc * const subpage_ram_read[] = {
++ &subpage_ram_readb,
++ &subpage_ram_readw,
++ &subpage_ram_readl,
++};
++
++static CPUWriteMemoryFunc * const subpage_ram_write[] = {
++ &subpage_ram_writeb,
++ &subpage_ram_writew,
++ &subpage_ram_writel,
++};
++
+ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
+ ram_addr_t memory, ram_addr_t region_offset)
+ {
+@@ -3583,8 +3640,9 @@ static int subpage_register (subpage_t *mmio, uint32_t start, uint32_t end,
+ printf("%s: %p start %08x end %08x idx %08x eidx %08x mem %ld\n", __func__,
+ mmio, start, end, idx, eidx, memory);
+ #endif
+- if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM)
+- memory = IO_MEM_UNASSIGNED;
++ if ((memory & ~TARGET_PAGE_MASK) == IO_MEM_RAM) {
++ memory = IO_MEM_SUBPAGE_RAM;
++ }
+ memory = (memory >> IO_MEM_SHIFT) & (IO_MEM_NB_ENTRIES - 1);
+ for (; idx <= eidx; idx++) {
+ mmio->sub_io_index[idx] = memory;
+@@ -3817,6 +3875,9 @@ static void io_mem_init(void)
+ cpu_register_io_memory_fixed(IO_MEM_NOTDIRTY, error_mem_read,
+ notdirty_mem_write, NULL,
+ DEVICE_NATIVE_ENDIAN);
++ cpu_register_io_memory_fixed(IO_MEM_SUBPAGE_RAM, subpage_ram_read,
++ subpage_ram_write, NULL,
++ DEVICE_NATIVE_ENDIAN);
+ for (i=0; i<5; i++)
+ io_mem_used[i] = 1;
+
+--
+1.7.7.5
+
diff --git a/0003-hw-9pfs-Improve-portability-to-older-systems.patch b/0003-hw-9pfs-Improve-portability-to-older-systems.patch
new file mode 100644
index 0000000..4e91a9f
--- /dev/null
+++ b/0003-hw-9pfs-Improve-portability-to-older-systems.patch
@@ -0,0 +1,101 @@
+From f03969b952bc2aaf9f4445b6da28aebb0a9abde5 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar at linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:27 +0530
+Subject: [PATCH 03/25] hw/9pfs: Improve portability to older systems
+
+handle fs driver require a set of newly added syscalls. Don't
+Compile handle FS driver if those syscalls are not available.
+Instead of adding #ifdef for all those syscalls we check for
+open by handle syscall. If that is available then rest of the
+syscalls used by the driver should be available.
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+---
+ Makefile.objs | 4 ++--
+ fsdev/qemu-fsdev.c | 2 ++
+ hw/9pfs/virtio-9p-handle.c | 33 ---------------------------------
+ 3 files changed, 4 insertions(+), 35 deletions(-)
+
+diff --git a/Makefile.objs b/Makefile.objs
+index d7a6539..3a699ee 100644
+--- a/Makefile.objs
++++ b/Makefile.objs
+@@ -310,8 +310,8 @@ hw-obj-$(CONFIG_SOUND) += $(sound-obj-y)
+ 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-local.o virtio-9p-xattr.o
+ 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
+ 9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-coth.o cofs.o codir.o cofile.o
+-9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-handle.o
+-9pfs-nested-$(CONFIG_VIRTFS) += virtio-9p-synth.o
++9pfs-nested-$(CONFIG_VIRTFS) += coxattr.o virtio-9p-synth.o
++9pfs-nested-$(CONFIG_OPEN_BY_HANDLE) += virtio-9p-handle.o
+
+ hw-obj-$(CONFIG_REALLY_VIRTFS) += $(addprefix 9pfs/, $(9pfs-nested-y))
+ $(addprefix 9pfs/, $(9pfs-nested-y)): QEMU_CFLAGS+=$(GLIB_CFLAGS)
+diff --git a/fsdev/qemu-fsdev.c b/fsdev/qemu-fsdev.c
+index 7fd2aa7..6684f7e 100644
+--- a/fsdev/qemu-fsdev.c
++++ b/fsdev/qemu-fsdev.c
+@@ -23,7 +23,9 @@ static QTAILQ_HEAD(FsDriverEntry_head, FsDriverListEntry) fsdriver_entries =
+
+ static FsDriverTable FsDrivers[] = {
+ { .name = "local", .ops = &local_ops},
++#ifdef CONFIG_OPEN_BY_HANDLE
+ { .name = "handle", .ops = &handle_ops},
++#endif
+ { .name = "synth", .ops = &synth_ops},
+ };
+
+diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c
+index 7644ae5..a62f690 100644
+--- a/hw/9pfs/virtio-9p-handle.c
++++ b/hw/9pfs/virtio-9p-handle.c
+@@ -45,7 +45,6 @@ struct handle_data {
+ int handle_bytes;
+ };
+
+-#ifdef CONFIG_OPEN_BY_HANDLE
+ static inline int name_to_handle(int dirfd, const char *name,
+ struct file_handle *fh, int *mnt_id, int flags)
+ {
+@@ -56,38 +55,6 @@ static inline int open_by_handle(int mountfd, const char *fh, int flags)
+ {
+ return open_by_handle_at(mountfd, (struct file_handle *)fh, flags);
+ }
+-#else
+-
+-struct rpl_file_handle {
+- unsigned int handle_bytes;
+- int handle_type;
+- unsigned char handle[0];
+-};
+-#define file_handle rpl_file_handle
+-
+-#ifndef AT_REMOVEDIR
+-#define AT_REMOVEDIR 0x200
+-#endif
+-#ifndef AT_EMPTY_PATH
+-#define AT_EMPTY_PATH 0x1000 /* Allow empty relative pathname */
+-#endif
+-#ifndef O_PATH
+-#define O_PATH 010000000
+-#endif
+-
+-static inline int name_to_handle(int dirfd, const char *name,
+- struct file_handle *fh, int *mnt_id, int flags)
+-{
+- errno = ENOSYS;
+- return -1;
+-}
+-
+-static inline int open_by_handle(int mountfd, const char *fh, int flags)
+-{
+- errno = ENOSYS;
+- return -1;
+-}
+-#endif
+
+ static int handle_update_file_cred(int dirfd, const char *name, FsCred *credp)
+ {
+--
+1.7.7.5
+
diff --git a/0004-hw-9pfs-use-migration-blockers-to-prevent-live-migra.patch b/0004-hw-9pfs-use-migration-blockers-to-prevent-live-migra.patch
new file mode 100644
index 0000000..a63b9e1
--- /dev/null
+++ b/0004-hw-9pfs-use-migration-blockers-to-prevent-live-migra.patch
@@ -0,0 +1,171 @@
+From 77a02621812952acfde887244f6f480de1b51f95 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar at linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:28 +0530
+Subject: [PATCH 04/25] hw/9pfs: use migration blockers to prevent live
+ migration when virtfs export path is mounted
+
+Now when you try to migrate with VirtFS export path mounted, you get a proper QMP error:
+
+(qemu) migrate tcp:localhost:4444
+Migration is disabled when VirtFS export path '/tmp/' is mounted in the guest using mount_tag 'v_tmp'
+(qemu)
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+---
+ hw/9pfs/virtio-9p-device.c | 22 +++++++++++-----------
+ hw/9pfs/virtio-9p.c | 19 +++++++++++++++++++
+ hw/9pfs/virtio-9p.h | 5 +++--
+ qerror.c | 5 +++++
+ qerror.h | 3 +++
+ 5 files changed, 41 insertions(+), 13 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
+index bba4c54..c9bca8b 100644
+--- a/hw/9pfs/virtio-9p-device.c
++++ b/hw/9pfs/virtio-9p-device.c
+@@ -33,13 +33,15 @@ static V9fsState *to_virtio_9p(VirtIODevice *vdev)
+
+ static void virtio_9p_get_config(VirtIODevice *vdev, uint8_t *config)
+ {
++ int len;
+ struct virtio_9p_config *cfg;
+ V9fsState *s = to_virtio_9p(vdev);
+
+- cfg = g_malloc0(sizeof(struct virtio_9p_config) +
+- s->tag_len);
+- stw_raw(&cfg->tag_len, s->tag_len);
+- memcpy(cfg->tag, s->tag, s->tag_len);
++ len = strlen(s->tag);
++ cfg = g_malloc0(sizeof(struct virtio_9p_config) + len);
++ stw_raw(&cfg->tag_len, len);
++ /* We don't copy the terminating null to config space */
++ memcpy(cfg->tag, s->tag, len);
+ memcpy(config, cfg, s->config_size);
+ g_free(cfg);
+ }
+@@ -96,20 +98,18 @@ VirtIODevice *virtio_9p_init(DeviceState *dev, V9fsConf *conf)
+ }
+
+ len = strlen(conf->tag);
+- if (len > MAX_TAG_LEN) {
++ if (len > MAX_TAG_LEN - 1) {
+ fprintf(stderr, "mount tag '%s' (%d bytes) is longer than "
+- "maximum (%d bytes)", conf->tag, len, MAX_TAG_LEN);
++ "maximum (%d bytes)", conf->tag, len, MAX_TAG_LEN - 1);
+ exit(1);
+ }
+- /* s->tag is non-NULL terminated string */
+- s->tag = g_malloc(len);
+- memcpy(s->tag, conf->tag, len);
+- s->tag_len = len;
++
++ s->tag = strdup(conf->tag);
+ s->ctx.uid = -1;
+
+ s->ops = fse->ops;
+ s->vdev.get_features = virtio_9p_get_features;
+- s->config_size = sizeof(struct virtio_9p_config) + s->tag_len;
++ s->config_size = sizeof(struct virtio_9p_config) + len;
+ s->vdev.get_config = virtio_9p_get_config;
+ s->fid_list = NULL;
+ qemu_co_rwlock_init(&s->rename_lock);
+diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
+index 1b2fc5d..32b98dd 100644
+--- a/hw/9pfs/virtio-9p.c
++++ b/hw/9pfs/virtio-9p.c
+@@ -23,6 +23,7 @@
+ #include "virtio-9p-xattr.h"
+ #include "virtio-9p-coth.h"
+ #include "trace.h"
++#include "migration.h"
+
+ int open_fd_hw;
+ int total_open_fd;
+@@ -373,6 +374,19 @@ static void put_fid(V9fsPDU *pdu, V9fsFidState *fidp)
+ * Don't free the fid if it is in reclaim list
+ */
+ if (!fidp->ref && fidp->clunked) {
++ if (fidp->fid == pdu->s->root_fid) {
++ /*
++ * if the clunked fid is root fid then we
++ * have unmounted the fs on the client side.
++ * delete the migration blocker. Ideally, this
++ * should be hooked to transport close notification
++ */
++ if (pdu->s->migration_blocker) {
++ migrate_del_blocker(pdu->s->migration_blocker);
++ error_free(pdu->s->migration_blocker);
++ pdu->s->migration_blocker = NULL;
++ }
++ }
+ free_fid(pdu, fidp);
+ }
+ }
+@@ -1235,6 +1249,11 @@ static void v9fs_attach(void *opaque)
+ err = offset;
+ trace_v9fs_attach_return(pdu->tag, pdu->id,
+ qid.type, qid.version, qid.path);
++ s->root_fid = fid;
++ /* disable migration */
++ error_set(&s->migration_blocker, QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
++ s->ctx.fs_root, s->tag);
++ migrate_add_blocker(s->migration_blocker);
+ out:
+ put_fid(pdu, fidp);
+ out_nofid:
+diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
+index 7f88356..8b612da 100644
+--- a/hw/9pfs/virtio-9p.h
++++ b/hw/9pfs/virtio-9p.h
+@@ -246,8 +246,7 @@ typedef struct V9fsState
+ V9fsFidState *fid_list;
+ FileOperations *ops;
+ FsContext ctx;
+- uint16_t tag_len;
+- uint8_t *tag;
++ char *tag;
+ size_t config_size;
+ enum p9_proto_version proto_version;
+ int32_t msize;
+@@ -256,6 +255,8 @@ typedef struct V9fsState
+ * on rename.
+ */
+ CoRwlock rename_lock;
++ int32_t root_fid;
++ Error *migration_blocker;
+ } V9fsState;
+
+ typedef struct V9fsStatState {
+diff --git a/qerror.c b/qerror.c
+index fdf62b9..25bc91e 100644
+--- a/qerror.c
++++ b/qerror.c
+@@ -235,6 +235,11 @@ static const QErrorStringTable qerror_table[] = {
+ "supported by this qemu version: %(feature)",
+ },
+ {
++ .error_fmt = QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION,
++ .desc = "Migration is disabled when VirtFS export path '%(path)' "
++ "is mounted in the guest using mount_tag '%(tag)'",
++ },
++ {
+ .error_fmt = QERR_VNC_SERVER_FAILED,
+ .desc = "Could not start VNC server on %(target)",
+ },
+diff --git a/qerror.h b/qerror.h
+index 2d3d43b..6414cd9 100644
+--- a/qerror.h
++++ b/qerror.h
+@@ -192,6 +192,9 @@ QError *qobject_to_qerror(const QObject *obj);
+ #define QERR_UNKNOWN_BLOCK_FORMAT_FEATURE \
+ "{ 'class': 'UnknownBlockFormatFeature', 'data': { 'device': %s, 'format': %s, 'feature': %s } }"
+
++#define QERR_VIRTFS_FEATURE_BLOCKS_MIGRATION \
++ "{ 'class': 'VirtFSFeatureBlocksMigration', 'data': { 'path': %s, 'tag': %s } }"
++
+ #define QERR_VNC_SERVER_FAILED \
+ "{ 'class': 'VNCServerFailed', 'data': { 'target': %s } }"
+
+--
+1.7.7.5
+
diff --git a/0005-hw-9pfs-Reset-server-state-during-TVERSION.patch b/0005-hw-9pfs-Reset-server-state-during-TVERSION.patch
new file mode 100644
index 0000000..585b7cc
--- /dev/null
+++ b/0005-hw-9pfs-Reset-server-state-during-TVERSION.patch
@@ -0,0 +1,64 @@
+From c554919f74e5a79f15360c4c2f417003477634cf Mon Sep 17 00:00:00 2001
+From: Deepak C Shetty <deepakcs at linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:28 +0530
+Subject: [PATCH 05/25] hw/9pfs: Reset server state during TVERSION
+
+As per the 9p rfc, during TVERSION its necessary to clean all the active
+fids, so that we start the session from a clean state. Its also needed in
+scenarios where the guest is booting off 9p, and boot fails, and client
+restarts, without any knowledge of the past, it will issue a TVERSION again
+so this ensures that we always start from a clean state.
+
+Signed-off-by: Deepak C Shetty <deepakcs at linux.vnet.ibm.com>
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+---
+ hw/9pfs/virtio-9p.c | 26 ++++++++++++++++++++++++++
+ 1 files changed, 26 insertions(+), 0 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
+index 32b98dd..dd43209 100644
+--- a/hw/9pfs/virtio-9p.c
++++ b/hw/9pfs/virtio-9p.c
+@@ -523,6 +523,30 @@ static int v9fs_mark_fids_unreclaim(V9fsPDU *pdu, V9fsPath *path)
+ return 0;
+ }
+
++static void virtfs_reset(V9fsPDU *pdu)
++{
++ V9fsState *s = pdu->s;
++ V9fsFidState *fidp = NULL;
++
++ /* Free all fids */
++ while (s->fid_list) {
++ fidp = s->fid_list;
++ s->fid_list = fidp->next;
++
++ if (fidp->ref) {
++ fidp->clunked = 1;
++ } else {
++ free_fid(pdu, fidp);
++ }
++ }
++ if (fidp) {
++ /* One or more unclunked fids found... */
++ error_report("9pfs:%s: One or more uncluncked fids "
++ "found during reset", __func__);
++ }
++ return;
++}
++
+ #define P9_QID_TYPE_DIR 0x80
+ #define P9_QID_TYPE_SYMLINK 0x02
+
+@@ -1196,6 +1220,8 @@ static void v9fs_version(void *opaque)
+ pdu_unmarshal(pdu, offset, "ds", &s->msize, &version);
+ trace_v9fs_version(pdu->tag, pdu->id, s->msize, version.data);
+
++ virtfs_reset(pdu);
++
+ if (!strcmp(version.data, "9P2000.u")) {
+ s->proto_version = V9FS_PROTO_2000U;
+ } else if (!strcmp(version.data, "9P2000.L")) {
+--
+1.7.7.5
+
diff --git a/0006-hw-9pfs-Add-qdev.reset-callback-for-virtio-9p-pci-de.patch b/0006-hw-9pfs-Add-qdev.reset-callback-for-virtio-9p-pci-de.patch
new file mode 100644
index 0000000..aa49abb
--- /dev/null
+++ b/0006-hw-9pfs-Add-qdev.reset-callback-for-virtio-9p-pci-de.patch
@@ -0,0 +1,57 @@
+From 64dd41bc2de392fa018c5ce804cc451b83f18b94 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar at linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:28 +0530
+Subject: [PATCH 06/25] hw/9pfs: Add qdev.reset callback for virtio-9p-pci
+ device
+
+Add the device reset callback
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+---
+ hw/9pfs/virtio-9p-device.c | 3 ++-
+ hw/virtio-pci.c | 2 +-
+ hw/virtio-pci.h | 1 +
+ 3 files changed, 4 insertions(+), 2 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p-device.c b/hw/9pfs/virtio-9p-device.c
+index c9bca8b..cd343e1 100644
+--- a/hw/9pfs/virtio-9p-device.c
++++ b/hw/9pfs/virtio-9p-device.c
+@@ -176,7 +176,8 @@ static PCIDeviceInfo virtio_9p_info = {
+ DEFINE_PROP_STRING("mount_tag", VirtIOPCIProxy, fsconf.tag),
+ DEFINE_PROP_STRING("fsdev", VirtIOPCIProxy, fsconf.fsdev_id),
+ DEFINE_PROP_END_OF_LIST(),
+- }
++ },
++ .qdev.reset = virtio_pci_reset,
+ };
+
+ static void virtio_9p_register_devices(void)
+diff --git a/hw/virtio-pci.c b/hw/virtio-pci.c
+index 64c6a94..c665f5c 100644
+--- a/hw/virtio-pci.c
++++ b/hw/virtio-pci.c
+@@ -266,7 +266,7 @@ static void virtio_pci_stop_ioeventfd(VirtIOPCIProxy *proxy)
+ proxy->ioeventfd_started = false;
+ }
+
+-static void virtio_pci_reset(DeviceState *d)
++void virtio_pci_reset(DeviceState *d)
+ {
+ VirtIOPCIProxy *proxy = container_of(d, VirtIOPCIProxy, pci_dev.qdev);
+ virtio_pci_stop_ioeventfd(proxy);
+diff --git a/hw/virtio-pci.h b/hw/virtio-pci.h
+index f8404de..344c22b 100644
+--- a/hw/virtio-pci.h
++++ b/hw/virtio-pci.h
+@@ -45,6 +45,7 @@ typedef struct {
+ } VirtIOPCIProxy;
+
+ void virtio_init_pci(VirtIOPCIProxy *proxy, VirtIODevice *vdev);
++void virtio_pci_reset(DeviceState *d);
+
+ /* Virtio ABI version, if we increment this, we break the guest driver. */
+ #define VIRTIO_PCI_ABI_VERSION 0
+--
+1.7.7.5
+
diff --git a/0007-hw-9pfs-Use-the-correct-file-descriptor-in-Fsdriver-.patch b/0007-hw-9pfs-Use-the-correct-file-descriptor-in-Fsdriver-.patch
new file mode 100644
index 0000000..446716c
--- /dev/null
+++ b/0007-hw-9pfs-Use-the-correct-file-descriptor-in-Fsdriver-.patch
@@ -0,0 +1,210 @@
+From ed6857bf98e6c8b8080be208ffe15bb678591466 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar at linux.vnet.ibm.com>
+Date: Sun, 4 Dec 2011 22:35:28 +0530
+Subject: [PATCH 07/25] hw/9pfs: Use the correct file descriptor in Fsdriver
+ Callback
+
+Fsdriver callback that operate on file descriptor need to
+differentiate between directory fd and file fd.
+
+Based on the original patch from Sassan Panahinejad <sassan at sassan.me.uk>
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+---
+ fsdev/file-op-9p.h | 4 ++--
+ hw/9pfs/cofile.c | 4 ++--
+ hw/9pfs/virtio-9p-handle.c | 28 ++++++++++++++++++++++------
+ hw/9pfs/virtio-9p-local.c | 36 ++++++++++++++++++++++++++----------
+ hw/9pfs/virtio-9p-synth.c | 5 +++--
+ 5 files changed, 55 insertions(+), 22 deletions(-)
+
+diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
+index 1928da2..a85ecd3 100644
+--- a/fsdev/file-op-9p.h
++++ b/fsdev/file-op-9p.h
+@@ -112,10 +112,10 @@ typedef struct FileOperations
+ ssize_t (*pwritev)(FsContext *, V9fsFidOpenState *,
+ const struct iovec *, int, off_t);
+ int (*mkdir)(FsContext *, V9fsPath *, const char *, FsCred *);
+- int (*fstat)(FsContext *, V9fsFidOpenState *, struct stat *);
++ int (*fstat)(FsContext *, int, V9fsFidOpenState *, struct stat *);
+ int (*rename)(FsContext *, const char *, const char *);
+ int (*truncate)(FsContext *, V9fsPath *, off_t);
+- int (*fsync)(FsContext *, V9fsFidOpenState *, int);
++ int (*fsync)(FsContext *, int, V9fsFidOpenState *, int);
+ int (*statfs)(FsContext *s, V9fsPath *path, struct statfs *stbuf);
+ ssize_t (*lgetxattr)(FsContext *, V9fsPath *,
+ const char *, void *, size_t);
+diff --git a/hw/9pfs/cofile.c b/hw/9pfs/cofile.c
+index 586b038..b15838c 100644
+--- a/hw/9pfs/cofile.c
++++ b/hw/9pfs/cofile.c
+@@ -71,7 +71,7 @@ int v9fs_co_fstat(V9fsPDU *pdu, V9fsFidState *fidp, struct stat *stbuf)
+ }
+ v9fs_co_run_in_worker(
+ {
+- err = s->ops->fstat(&s->ctx, &fidp->fs, stbuf);
++ err = s->ops->fstat(&s->ctx, fidp->fid_type, &fidp->fs, stbuf);
+ if (err < 0) {
+ err = -errno;
+ }
+@@ -192,7 +192,7 @@ int v9fs_co_fsync(V9fsPDU *pdu, V9fsFidState *fidp, int datasync)
+ }
+ v9fs_co_run_in_worker(
+ {
+- err = s->ops->fsync(&s->ctx, &fidp->fs, datasync);
++ err = s->ops->fsync(&s->ctx, fidp->fid_type, &fidp->fs, datasync);
+ if (err < 0) {
+ err = -errno;
+ }
+diff --git a/hw/9pfs/virtio-9p-handle.c b/hw/9pfs/virtio-9p-handle.c
+index a62f690..f97d898 100644
+--- a/hw/9pfs/virtio-9p-handle.c
++++ b/hw/9pfs/virtio-9p-handle.c
+@@ -255,10 +255,17 @@ static int handle_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
+ return ret;
+ }
+
+-static int handle_fstat(FsContext *fs_ctx, V9fsFidOpenState *fs,
+- struct stat *stbuf)
++static int handle_fstat(FsContext *fs_ctx, int fid_type,
++ V9fsFidOpenState *fs, struct stat *stbuf)
+ {
+- return fstat(fs->fd, stbuf);
++ int fd;
++
++ if (fid_type == P9_FID_DIR) {
++ fd = dirfd(fs->dir);
++ } else {
++ fd = fs->fd;
++ }
++ return fstat(fd, stbuf);
+ }
+
+ static int handle_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
+@@ -395,12 +402,21 @@ static int handle_remove(FsContext *ctx, const char *path)
+ return -1;
+ }
+
+-static int handle_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
++static int handle_fsync(FsContext *ctx, int fid_type,
++ V9fsFidOpenState *fs, int datasync)
+ {
++ int fd;
++
++ if (fid_type == P9_FID_DIR) {
++ fd = dirfd(fs->dir);
++ } else {
++ fd = fs->fd;
++ }
++
+ if (datasync) {
+- return qemu_fdatasync(fs->fd);
++ return qemu_fdatasync(fd);
+ } else {
+- return fsync(fs->fd);
++ return fsync(fd);
+ }
+ }
+
+diff --git a/hw/9pfs/virtio-9p-local.c b/hw/9pfs/virtio-9p-local.c
+index 99ef0cd..371a94d 100644
+--- a/hw/9pfs/virtio-9p-local.c
++++ b/hw/9pfs/virtio-9p-local.c
+@@ -366,11 +366,18 @@ out:
+ return err;
+ }
+
+-static int local_fstat(FsContext *fs_ctx,
++static int local_fstat(FsContext *fs_ctx, int fid_type,
+ V9fsFidOpenState *fs, struct stat *stbuf)
+ {
+- int err;
+- err = fstat(fs->fd, stbuf);
++ int err, fd;
++
++ if (fid_type == P9_FID_DIR) {
++ fd = dirfd(fs->dir);
++ } else {
++ fd = fs->fd;
++ }
++
++ err = fstat(fd, stbuf);
+ if (err) {
+ return err;
+ }
+@@ -381,19 +388,19 @@ static int local_fstat(FsContext *fs_ctx,
+ mode_t tmp_mode;
+ dev_t tmp_dev;
+
+- if (fgetxattr(fs->fd, "user.virtfs.uid",
++ if (fgetxattr(fd, "user.virtfs.uid",
+ &tmp_uid, sizeof(uid_t)) > 0) {
+ stbuf->st_uid = tmp_uid;
+ }
+- if (fgetxattr(fs->fd, "user.virtfs.gid",
++ if (fgetxattr(fd, "user.virtfs.gid",
+ &tmp_gid, sizeof(gid_t)) > 0) {
+ stbuf->st_gid = tmp_gid;
+ }
+- if (fgetxattr(fs->fd, "user.virtfs.mode",
++ if (fgetxattr(fd, "user.virtfs.mode",
+ &tmp_mode, sizeof(mode_t)) > 0) {
+ stbuf->st_mode = tmp_mode;
+ }
+- if (fgetxattr(fs->fd, "user.virtfs.rdev",
++ if (fgetxattr(fd, "user.virtfs.rdev",
+ &tmp_dev, sizeof(dev_t)) > 0) {
+ stbuf->st_rdev = tmp_dev;
+ }
+@@ -592,12 +599,21 @@ static int local_remove(FsContext *ctx, const char *path)
+ return remove(rpath(ctx, path, buffer));
+ }
+
+-static int local_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
++static int local_fsync(FsContext *ctx, int fid_type,
++ V9fsFidOpenState *fs, int datasync)
+ {
++ int fd;
++
++ if (fid_type == P9_FID_DIR) {
++ fd = dirfd(fs->dir);
++ } else {
++ fd = fs->fd;
++ }
++
+ if (datasync) {
+- return qemu_fdatasync(fs->fd);
++ return qemu_fdatasync(fd);
+ } else {
+- return fsync(fs->fd);
++ return fsync(fd);
+ }
+ }
+
+diff --git a/hw/9pfs/virtio-9p-synth.c b/hw/9pfs/virtio-9p-synth.c
+index f573616..92e0b09 100644
+--- a/hw/9pfs/virtio-9p-synth.c
++++ b/hw/9pfs/virtio-9p-synth.c
+@@ -166,7 +166,7 @@ static int v9fs_synth_lstat(FsContext *fs_ctx,
+ return 0;
+ }
+
+-static int v9fs_synth_fstat(FsContext *fs_ctx,
++static int v9fs_synth_fstat(FsContext *fs_ctx, int fid_type,
+ V9fsFidOpenState *fs, struct stat *stbuf)
+ {
+ V9fsSynthOpenState *synth_open = fs->private;
+@@ -414,7 +414,8 @@ static int v9fs_synth_remove(FsContext *ctx, const char *path)
+ return -1;
+ }
+
+-static int v9fs_synth_fsync(FsContext *ctx, V9fsFidOpenState *fs, int datasync)
++static int v9fs_synth_fsync(FsContext *ctx, int fid_type,
++ V9fsFidOpenState *fs, int datasync)
+ {
+ errno = ENOSYS;
+ return 0;
+--
+1.7.7.5
+
diff --git a/0008-hw-9pfs-replace-iovec-manipulation-with-QEMUIOVector.patch b/0008-hw-9pfs-replace-iovec-manipulation-with-QEMUIOVector.patch
new file mode 100644
index 0000000..95c3f05
--- /dev/null
+++ b/0008-hw-9pfs-replace-iovec-manipulation-with-QEMUIOVector.patch
@@ -0,0 +1,305 @@
+From 45d6cdff48356dc8974497ec0524f971b646dd70 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Date: Wed, 21 Dec 2011 12:37:22 +0530
+Subject: [PATCH 08/25] hw/9pfs: replace iovec manipulation with QEMUIOVector
+
+The v9fs_read() and v9fs_write() functions rely on iovec[] manipulation
+code should be replaced with QEMUIOVector to avoid duplicating code.
+In the future it may be possible to make the code even more concise by
+using QEMUIOVector consistently across virtio and 9pfs.
+
+The "v" format specifier for pdu_marshal() and pdu_unmarshal() is
+dropped since it does not actually pack/unpack anything. The specifier
+was also not implemented to update the offset variable and could only be
+used at the end of a format string, another sign that this shouldn't
+really be a format specifier. Instead, see the new
+v9fs_init_qiov_from_pdu() function.
+
+This change avoids a possible iovec[] buffer overflow when indirect
+vrings are used since the number of vectors is now limited by the
+underlying VirtQueueElement and cannot be out-of-bounds.
+
+Signed-off-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+---
+ hw/9pfs/virtio-9p.c | 162 +++++++++++++++++++--------------------------------
+ 1 files changed, 60 insertions(+), 102 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
+index dd43209..c018916 100644
+--- a/hw/9pfs/virtio-9p.c
++++ b/hw/9pfs/virtio-9p.c
+@@ -674,40 +674,6 @@ static size_t pdu_pack(V9fsPDU *pdu, size_t offset, const void *src,
+ offset, size, 1);
+ }
+
+-static int pdu_copy_sg(V9fsPDU *pdu, size_t offset, int rx, struct iovec *sg)
+-{
+- size_t pos = 0;
+- int i, j;
+- struct iovec *src_sg;
+- unsigned int num;
+-
+- if (rx) {
+- src_sg = pdu->elem.in_sg;
+- num = pdu->elem.in_num;
+- } else {
+- src_sg = pdu->elem.out_sg;
+- num = pdu->elem.out_num;
+- }
+-
+- j = 0;
+- for (i = 0; i < num; i++) {
+- if (offset <= pos) {
+- sg[j].iov_base = src_sg[i].iov_base;
+- sg[j].iov_len = src_sg[i].iov_len;
+- j++;
+- } else if (offset < (src_sg[i].iov_len + pos)) {
+- sg[j].iov_base = src_sg[i].iov_base;
+- sg[j].iov_len = src_sg[i].iov_len;
+- sg[j].iov_base += (offset - pos);
+- sg[j].iov_len -= (offset - pos);
+- j++;
+- }
+- pos += src_sg[i].iov_len;
+- }
+-
+- return j;
+-}
+-
+ static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
+ {
+ size_t old_offset = offset;
+@@ -743,12 +709,6 @@ static size_t pdu_unmarshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
+ *valp = le64_to_cpu(val);
+ break;
+ }
+- case 'v': {
+- struct iovec *iov = va_arg(ap, struct iovec *);
+- int *iovcnt = va_arg(ap, int *);
+- *iovcnt = pdu_copy_sg(pdu, offset, 0, iov);
+- break;
+- }
+ case 's': {
+ V9fsString *str = va_arg(ap, V9fsString *);
+ offset += pdu_unmarshal(pdu, offset, "w", &str->size);
+@@ -827,12 +787,6 @@ static size_t pdu_marshal(V9fsPDU *pdu, size_t offset, const char *fmt, ...)
+ offset += pdu_pack(pdu, offset, &val, sizeof(val));
+ break;
+ }
+- case 'v': {
+- struct iovec *iov = va_arg(ap, struct iovec *);
+- int *iovcnt = va_arg(ap, int *);
+- *iovcnt = pdu_copy_sg(pdu, offset, 1, iov);
+- break;
+- }
+ case 's': {
+ V9fsString *str = va_arg(ap, V9fsString *);
+ offset += pdu_marshal(pdu, offset, "w", str->size);
+@@ -1143,42 +1097,6 @@ static void stat_to_v9stat_dotl(V9fsState *s, const struct stat *stbuf,
+ stat_to_qid(stbuf, &v9lstat->qid);
+ }
+
+-static struct iovec *adjust_sg(struct iovec *sg, int len, int *iovcnt)
+-{
+- while (len && *iovcnt) {
+- if (len < sg->iov_len) {
+- sg->iov_len -= len;
+- sg->iov_base += len;
+- len = 0;
+- } else {
+- len -= sg->iov_len;
+- sg++;
+- *iovcnt -= 1;
+- }
+- }
+-
+- return sg;
+-}
+-
+-static struct iovec *cap_sg(struct iovec *sg, int cap, int *cnt)
+-{
+- int i;
+- int total = 0;
+-
+- for (i = 0; i < *cnt; i++) {
+- if ((total + sg[i].iov_len) > cap) {
+- sg[i].iov_len -= ((total + sg[i].iov_len) - cap);
+- i++;
+- break;
+- }
+- total += sg[i].iov_len;
+- }
+-
+- *cnt = i;
+-
+- return sg;
+-}
+-
+ static void print_sg(struct iovec *sg, int cnt)
+ {
+ int i;
+@@ -1861,6 +1779,38 @@ out:
+ return count;
+ }
+
++/*
++ * Create a QEMUIOVector for a sub-region of PDU iovecs
++ *
++ * @qiov: uninitialized QEMUIOVector
++ * @skip: number of bytes to skip from beginning of PDU
++ * @size: number of bytes to include
++ * @is_write: true - write, false - read
++ *
++ * The resulting QEMUIOVector has heap-allocated iovecs and must be cleaned up
++ * with qemu_iovec_destroy().
++ */
++static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,
++ uint64_t skip, size_t size,
++ bool is_write)
++{
++ QEMUIOVector elem;
++ struct iovec *iov;
++ unsigned int niov;
++
++ if (is_write) {
++ iov = pdu->elem.out_sg;
++ niov = pdu->elem.out_num;
++ } else {
++ iov = pdu->elem.in_sg;
++ niov = pdu->elem.in_num;
++ }
++
++ qemu_iovec_init_external(&elem, iov, niov);
++ qemu_iovec_init(qiov, niov);
++ qemu_iovec_copy(qiov, &elem, skip, size);
++}
++
+ static void v9fs_read(void *opaque)
+ {
+ int32_t fid;
+@@ -1895,21 +1845,21 @@ static void v9fs_read(void *opaque)
+ err += pdu_marshal(pdu, offset, "d", count);
+ err += count;
+ } else if (fidp->fid_type == P9_FID_FILE) {
+- int32_t cnt;
++ QEMUIOVector qiov_full;
++ QEMUIOVector qiov;
+ int32_t len;
+- struct iovec *sg;
+- struct iovec iov[128]; /* FIXME: bad, bad, bad */
+
+- sg = iov;
+- pdu_marshal(pdu, offset + 4, "v", sg, &cnt);
+- sg = cap_sg(sg, max_count, &cnt);
++ v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset + 4, max_count, false);
++ qemu_iovec_init(&qiov, qiov_full.niov);
+ do {
++ qemu_iovec_reset(&qiov);
++ qemu_iovec_copy(&qiov, &qiov_full, count, qiov_full.size - count);
+ if (0) {
+- print_sg(sg, cnt);
++ print_sg(qiov.iov, qiov.niov);
+ }
+ /* Loop in case of EINTR */
+ do {
+- len = v9fs_co_preadv(pdu, fidp, sg, cnt, off);
++ len = v9fs_co_preadv(pdu, fidp, qiov.iov, qiov.niov, off);
+ if (len >= 0) {
+ off += len;
+ count += len;
+@@ -1920,11 +1870,12 @@ static void v9fs_read(void *opaque)
+ err = len;
+ goto out;
+ }
+- sg = adjust_sg(sg, len, &cnt);
+ } while (count < max_count && len > 0);
+ err = offset;
+ err += pdu_marshal(pdu, offset, "d", count);
+ err += count;
++ qemu_iovec_destroy(&qiov);
++ qemu_iovec_destroy(&qiov_full);
+ } else if (fidp->fid_type == P9_FID_XATTR) {
+ err = v9fs_xattr_read(s, pdu, fidp, off, max_count);
+ } else {
+@@ -2095,7 +2046,6 @@ out:
+
+ static void v9fs_write(void *opaque)
+ {
+- int cnt;
+ ssize_t err;
+ int32_t fid;
+ int64_t off;
+@@ -2104,13 +2054,14 @@ static void v9fs_write(void *opaque)
+ int32_t total = 0;
+ size_t offset = 7;
+ V9fsFidState *fidp;
+- struct iovec iov[128]; /* FIXME: bad, bad, bad */
+- struct iovec *sg = iov;
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
++ QEMUIOVector qiov_full;
++ QEMUIOVector qiov;
+
+- pdu_unmarshal(pdu, offset, "dqdv", &fid, &off, &count, sg, &cnt);
+- trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, cnt);
++ offset += pdu_unmarshal(pdu, offset, "dqd", &fid, &off, &count);
++ v9fs_init_qiov_from_pdu(&qiov_full, pdu, offset, count, true);
++ trace_v9fs_write(pdu->tag, pdu->id, fid, off, count, qiov_full.niov);
+
+ fidp = get_fid(pdu, fid);
+ if (fidp == NULL) {
+@@ -2126,20 +2077,23 @@ static void v9fs_write(void *opaque)
+ /*
+ * setxattr operation
+ */
+- err = v9fs_xattr_write(s, pdu, fidp, off, count, sg, cnt);
++ err = v9fs_xattr_write(s, pdu, fidp, off, count,
++ qiov_full.iov, qiov_full.niov);
+ goto out;
+ } else {
+ err = -EINVAL;
+ goto out;
+ }
+- sg = cap_sg(sg, count, &cnt);
++ qemu_iovec_init(&qiov, qiov_full.niov);
+ do {
++ qemu_iovec_reset(&qiov);
++ qemu_iovec_copy(&qiov, &qiov_full, total, qiov_full.size - total);
+ if (0) {
+- print_sg(sg, cnt);
++ print_sg(qiov.iov, qiov.niov);
+ }
+ /* Loop in case of EINTR */
+ do {
+- len = v9fs_co_pwritev(pdu, fidp, sg, cnt, off);
++ len = v9fs_co_pwritev(pdu, fidp, qiov.iov, qiov.niov, off);
+ if (len >= 0) {
+ off += len;
+ total += len;
+@@ -2148,16 +2102,20 @@ static void v9fs_write(void *opaque)
+ if (len < 0) {
+ /* IO error return the error */
+ err = len;
+- goto out;
++ goto out_qiov;
+ }
+- sg = adjust_sg(sg, len, &cnt);
+ } while (total < count && len > 0);
++
++ offset = 7;
+ offset += pdu_marshal(pdu, offset, "d", total);
+ err = offset;
+ trace_v9fs_write_return(pdu->tag, pdu->id, total, err);
++out_qiov:
++ qemu_iovec_destroy(&qiov);
+ out:
+ put_fid(pdu, fidp);
+ out_nofid:
++ qemu_iovec_destroy(&qiov_full);
+ complete_pdu(s, pdu, err);
+ }
+
+--
+1.7.7.5
+
diff --git a/0009-hw-9pfs-Use-the-correct-signed-type-for-different-va.patch b/0009-hw-9pfs-Use-the-correct-signed-type-for-different-va.patch
new file mode 100644
index 0000000..c0b02f2
--- /dev/null
+++ b/0009-hw-9pfs-Use-the-correct-signed-type-for-different-va.patch
@@ -0,0 +1,133 @@
+From 3d3ec7b809b91f2a71fb78fc6b5b079963383243 Mon Sep 17 00:00:00 2001
+From: "Aneesh Kumar K.V" <aneesh.kumar at linux.vnet.ibm.com>
+Date: Wed, 21 Dec 2011 12:37:23 +0530
+Subject: [PATCH 09/25] hw/9pfs: Use the correct signed type for different
+ variables
+
+Signed-off-by: Aneesh Kumar K.V <aneesh.kumar at linux.vnet.ibm.com>
+---
+ fsdev/file-op-9p.h | 2 +-
+ hw/9pfs/virtio-9p.c | 21 +++++++++++----------
+ hw/9pfs/virtio-9p.h | 2 +-
+ trace-events | 8 ++++----
+ 4 files changed, 17 insertions(+), 16 deletions(-)
+
+diff --git a/fsdev/file-op-9p.h b/fsdev/file-op-9p.h
+index a85ecd3..c823fe0 100644
+--- a/fsdev/file-op-9p.h
++++ b/fsdev/file-op-9p.h
+@@ -74,7 +74,7 @@ typedef struct FsContext
+ } FsContext;
+
+ typedef struct V9fsPath {
+- int16_t size;
++ uint16_t size;
+ char *data;
+ } V9fsPath;
+
+diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
+index c018916..b3fc3d0 100644
+--- a/hw/9pfs/virtio-9p.c
++++ b/hw/9pfs/virtio-9p.c
+@@ -1694,8 +1694,8 @@ out_nofid:
+ complete_pdu(s, pdu, err);
+ }
+
+-static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu,
+- V9fsFidState *fidp, int64_t off, int32_t max_count)
++static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
++ uint64_t off, uint32_t max_count)
+ {
+ size_t offset = 7;
+ int read_count;
+@@ -1719,7 +1719,7 @@ static int v9fs_xattr_read(V9fsState *s, V9fsPDU *pdu,
+ }
+
+ static int v9fs_do_readdir_with_stat(V9fsPDU *pdu,
+- V9fsFidState *fidp, int32_t max_count)
++ V9fsFidState *fidp, uint32_t max_count)
+ {
+ V9fsPath path;
+ V9fsStat v9stat;
+@@ -1814,11 +1814,11 @@ static void v9fs_init_qiov_from_pdu(QEMUIOVector *qiov, V9fsPDU *pdu,
+ static void v9fs_read(void *opaque)
+ {
+ int32_t fid;
+- int64_t off;
++ uint64_t off;
+ ssize_t err = 0;
+ int32_t count = 0;
+ size_t offset = 7;
+- int32_t max_count;
++ uint32_t max_count;
+ V9fsFidState *fidp;
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
+@@ -1962,8 +1962,9 @@ static void v9fs_readdir(void *opaque)
+ V9fsFidState *fidp;
+ ssize_t retval = 0;
+ size_t offset = 7;
+- int64_t initial_offset;
+- int32_t count, max_count;
++ uint64_t initial_offset;
++ int32_t count;
++ uint32_t max_count;
+ V9fsPDU *pdu = opaque;
+ V9fsState *s = pdu->s;
+
+@@ -2001,7 +2002,7 @@ out_nofid:
+ }
+
+ static int v9fs_xattr_write(V9fsState *s, V9fsPDU *pdu, V9fsFidState *fidp,
+- int64_t off, int32_t count,
++ uint64_t off, uint32_t count,
+ struct iovec *sg, int cnt)
+ {
+ int i, to_copy;
+@@ -2048,8 +2049,8 @@ static void v9fs_write(void *opaque)
+ {
+ ssize_t err;
+ int32_t fid;
+- int64_t off;
+- int32_t count;
++ uint64_t off;
++ uint32_t count;
+ int32_t len = 0;
+ int32_t total = 0;
+ size_t offset = 7;
+diff --git a/hw/9pfs/virtio-9p.h b/hw/9pfs/virtio-9p.h
+index 8b612da..19a797b 100644
+--- a/hw/9pfs/virtio-9p.h
++++ b/hw/9pfs/virtio-9p.h
+@@ -156,7 +156,7 @@ typedef struct V9fsFidState V9fsFidState;
+
+ typedef struct V9fsString
+ {
+- int16_t size;
++ uint16_t size;
+ char *data;
+ } V9fsString;
+
+diff --git a/trace-events b/trace-events
+index 962caca..e417897 100644
+--- a/trace-events
++++ b/trace-events
+@@ -579,11 +579,11 @@ v9fs_lcreate(uint16_t tag, uint8_t id, int32_t dfid, int32_t flags, int32_t mode
+ v9fs_lcreate_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int32_t iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
+ v9fs_fsync(uint16_t tag, uint8_t id, int32_t fid, int datasync) "tag %d id %d fid %d datasync %d"
+ v9fs_clunk(uint16_t tag, uint8_t id, int32_t fid) "tag %d id %d fid %d"
+-v9fs_read(uint16_t tag, uint8_t id, int32_t fid, int64_t off, int32_t max_count) "tag %d id %d fid %d off %"PRId64" max_count %d"
++v9fs_read(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t max_count) "tag %d id %d fid %d off %"PRIu64" max_count %u"
+ v9fs_read_return(uint16_t tag, uint8_t id, int32_t count, ssize_t err) "tag %d id %d count %d err %zd"
+-v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, int64_t offset, int32_t max_count) "tag %d id %d fid %d offset %"PRId64" max_count %d"
+-v9fs_readdir_return(uint16_t tag, uint8_t id, int32_t count, ssize_t retval) "tag %d id %d count %d retval %zd"
+-v9fs_write(uint16_t tag, uint8_t id, int32_t fid, int64_t off, int32_t count, int cnt) "tag %d id %d fid %d off %"PRId64" count %d cnt %d"
++v9fs_readdir(uint16_t tag, uint8_t id, int32_t fid, uint64_t offset, uint32_t max_count) "tag %d id %d fid %d offset %"PRIu64" max_count %u"
++v9fs_readdir_return(uint16_t tag, uint8_t id, uint32_t count, ssize_t retval) "tag %d id %d count %u retval %zd"
++v9fs_write(uint16_t tag, uint8_t id, int32_t fid, uint64_t off, uint32_t count, int cnt) "tag %d id %d fid %d off %"PRIu64" count %u cnt %d"
+ v9fs_write_return(uint16_t tag, uint8_t id, int32_t total, ssize_t err) "tag %d id %d total %d err %zd"
+ v9fs_create(uint16_t tag, uint8_t id, int32_t fid, char* name, int32_t perm, int8_t mode) "tag %d id %d fid %d name %s perm %d mode %d"
+ v9fs_create_return(uint16_t tag, uint8_t id, int8_t type, int32_t version, int64_t path, int iounit) "tag %d id %d qid={type %d version %d path %"PRId64"} iounit %d"
+--
+1.7.7.5
+
diff --git a/0010-target-i386-fix-cmpxchg-instruction-emulation.patch b/0010-target-i386-fix-cmpxchg-instruction-emulation.patch
new file mode 100644
index 0000000..a7276e2
--- /dev/null
+++ b/0010-target-i386-fix-cmpxchg-instruction-emulation.patch
@@ -0,0 +1,54 @@
+From abf80f880410ebbdd01a289c41c87153802fe900 Mon Sep 17 00:00:00 2001
+From: Andreas Gustafsson <gson at gson.org>
+Date: Mon, 12 Dec 2011 00:46:32 +0400
+Subject: [PATCH 10/25] target-i386: fix cmpxchg instruction emulation
+
+When the i386 cmpxchg instruction is executed with a memory operand
+and the comparison result is "unequal", do the memory write before
+changing the accumulator instead of the other way around, because
+otherwise the new accumulator value will incorrectly be used in the
+comparison when the instruction is restarted after a page fault.
+
+This bug was originally reported on 2010-04-25 as
+https://bugs.launchpad.net/qemu/+bug/569760
+
+Signed-off-by: Andreas Gustafsson <gson at gson.org>
+---
+ target-i386/translate.c | 11 +++++++----
+ 1 files changed, 7 insertions(+), 4 deletions(-)
+
+diff --git a/target-i386/translate.c b/target-i386/translate.c
+index 1ef8d16..8321bf3 100644
+--- a/target-i386/translate.c
++++ b/target-i386/translate.c
+@@ -4870,20 +4870,23 @@ static target_ulong disas_insn(DisasContext *s, target_ulong pc_start)
+ tcg_gen_sub_tl(t2, cpu_regs[R_EAX], t0);
+ gen_extu(ot, t2);
+ tcg_gen_brcondi_tl(TCG_COND_EQ, t2, 0, label1);
++ label2 = gen_new_label();
+ if (mod == 3) {
+- label2 = gen_new_label();
+ gen_op_mov_reg_v(ot, R_EAX, t0);
+ tcg_gen_br(label2);
+ gen_set_label(label1);
+ gen_op_mov_reg_v(ot, rm, t1);
+- gen_set_label(label2);
+ } else {
+- tcg_gen_mov_tl(t1, t0);
++ /* perform no-op store cycle like physical cpu; must be
++ before changing accumulator to ensure idempotency if
++ the store faults and the instruction is restarted */
++ gen_op_st_v(ot + s->mem_index, t0, a0);
+ gen_op_mov_reg_v(ot, R_EAX, t0);
++ tcg_gen_br(label2);
+ gen_set_label(label1);
+- /* always store */
+ gen_op_st_v(ot + s->mem_index, t1, a0);
+ }
++ gen_set_label(label2);
+ tcg_gen_mov_tl(cpu_cc_src, t0);
+ tcg_gen_mov_tl(cpu_cc_dst, t2);
+ s->cc_op = CC_OP_SUBB + ot;
+--
+1.7.7.5
+
diff --git a/0011-configure-Enable-build-by-default-PIE-read-only-relo.patch b/0011-configure-Enable-build-by-default-PIE-read-only-relo.patch
new file mode 100644
index 0000000..bd592c7
--- /dev/null
+++ b/0011-configure-Enable-build-by-default-PIE-read-only-relo.patch
@@ -0,0 +1,31 @@
+From 6d450bfbc862d0dab0e8da10ae15698612800726 Mon Sep 17 00:00:00 2001
+From: Brad <brad at comstyle.com>
+Date: Mon, 28 Nov 2011 19:53:49 -0500
+Subject: [PATCH 11/25] configure: Enable build by default PIE / read-only
+ relocation sections on OpenBSD amd64/i386.
+
+Enable build by default PIE / read-only relocation sections for the QEMU
+binaries on OpenBSD amd64/i386.
+
+Signed-off-by: Brad Smith <brad at comstyle.com>
+Signed-off-by: Blue Swirl <blauwirbel at gmail.com>
+---
+ configure | 2 +-
+ 1 files changed, 1 insertions(+), 1 deletions(-)
+
+diff --git a/configure b/configure
+index ac4840d..b113f60 100755
+--- a/configure
++++ b/configure
+@@ -1116,7 +1116,7 @@ fi
+
+ if test "$pie" = ""; then
+ case "$cpu-$targetos" in
+- i386-Linux|x86_64-Linux)
++ i386-Linux|x86_64-Linux|i386-OpenBSD|x86_64-OpenBSD)
+ ;;
+ *)
+ pie="no"
+--
+1.7.7.5
+
diff --git a/0012-cris-Handle-conditional-stores-on-CRISv10.patch b/0012-cris-Handle-conditional-stores-on-CRISv10.patch
new file mode 100644
index 0000000..c824a09
--- /dev/null
+++ b/0012-cris-Handle-conditional-stores-on-CRISv10.patch
@@ -0,0 +1,155 @@
+From 3e8088148bb56b84a739c2ef3c63d89188a1ad8f Mon Sep 17 00:00:00 2001
+From: Stefan Sandstrom <Stefan.Sandstrom at axis.com>
+Date: Mon, 12 Dec 2011 11:38:31 +0100
+Subject: [PATCH 12/25] cris: Handle conditional stores on CRISv10
+
+Signed-off-by: Stefan Sandstrom <Stefan.Sandstrom at axis.com>
+Signed-off-by: Edgar E. Iglesias <edgar.iglesias at gmail.com>
+---
+ target-cris/cpu.h | 2 +
+ target-cris/helper.c | 1 +
+ target-cris/translate_v10.c | 72 +++++++++++++++++++++++++++++++++++++++---
+ 3 files changed, 69 insertions(+), 6 deletions(-)
+
+diff --git a/target-cris/cpu.h b/target-cris/cpu.h
+index 8ae0ce3..453afbb 100644
+--- a/target-cris/cpu.h
++++ b/target-cris/cpu.h
+@@ -67,6 +67,8 @@
+ #define Q_FLAG 0x80000000
+ #define M_FLAG 0x40000000
+ #define PFIX_FLAG 0x800 /* CRISv10 Only. */
++#define F_FLAG_V10 0x400
++#define P_FLAG_V10 0x200
+ #define S_FLAG 0x200
+ #define R_FLAG 0x100
+ #define P_FLAG 0x80
+diff --git a/target-cris/helper.c b/target-cris/helper.c
+index 75f0035..5bc6d81 100644
+--- a/target-cris/helper.c
++++ b/target-cris/helper.c
+@@ -157,6 +157,7 @@ static void do_interruptv10(CPUState *env)
+ /* Now that we are in kernel mode, load the handlers address. */
+ env->pc = ldl_code(env->pregs[PR_EBP] + ex_vec * 4);
+ env->locked_irq = 1;
++ env->pregs[PR_CCS] |= F_FLAG_V10; /* set F. */
+
+ qemu_log_mask(CPU_LOG_INT, "%s isr=%x vec=%x ccs=%x pid=%d erp=%x\n",
+ __func__, env->pc, ex_vec,
+diff --git a/target-cris/translate_v10.c b/target-cris/translate_v10.c
+index 637ac20..95053b6 100644
+--- a/target-cris/translate_v10.c
++++ b/target-cris/translate_v10.c
+@@ -62,6 +62,65 @@ static inline void cris_illegal_insn(DisasContext *dc)
+ t_gen_raise_exception(EXCP_BREAK);
+ }
+
++static void gen_store_v10_conditional(DisasContext *dc, TCGv addr, TCGv val,
++ unsigned int size, int mem_index)
++{
++ int l1 = gen_new_label();
++ TCGv taddr = tcg_temp_local_new();
++ TCGv tval = tcg_temp_local_new();
++ TCGv t1 = tcg_temp_local_new();
++ dc->postinc = 0;
++ cris_evaluate_flags(dc);
++
++ tcg_gen_mov_tl(taddr, addr);
++ tcg_gen_mov_tl(tval, val);
++
++ /* Store only if F flag isn't set */
++ tcg_gen_andi_tl(t1, cpu_PR[PR_CCS], F_FLAG_V10);
++ tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
++ if (size == 1) {
++ tcg_gen_qemu_st8(tval, taddr, mem_index);
++ } else if (size == 2) {
++ tcg_gen_qemu_st16(tval, taddr, mem_index);
++ } else {
++ tcg_gen_qemu_st32(tval, taddr, mem_index);
++ }
++ gen_set_label(l1);
++ tcg_gen_shri_tl(t1, t1, 1); /* shift F to P position */
++ tcg_gen_or_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], t1); /*P=F*/
++ tcg_temp_free(t1);
++ tcg_temp_free(tval);
++ tcg_temp_free(taddr);
++}
++
++static void gen_store_v10(DisasContext *dc, TCGv addr, TCGv val,
++ unsigned int size)
++{
++ int mem_index = cpu_mmu_index(dc->env);
++
++ /* If we get a fault on a delayslot we must keep the jmp state in
++ the cpu-state to be able to re-execute the jmp. */
++ if (dc->delayed_branch == 1) {
++ cris_store_direct_jmp(dc);
++ }
++
++ /* Conditional writes. We only support the kind were X is known
++ at translation time. */
++ if (dc->flagx_known && dc->flags_x) {
++ gen_store_v10_conditional(dc, addr, val, size, mem_index);
++ return;
++ }
++
++ if (size == 1) {
++ tcg_gen_qemu_st8(val, addr, mem_index);
++ } else if (size == 2) {
++ tcg_gen_qemu_st16(val, addr, mem_index);
++ } else {
++ tcg_gen_qemu_st32(val, addr, mem_index);
++ }
++}
++
++
+ /* Prefix flag and register are used to handle the more complex
+ addressing modes. */
+ static void cris_set_prefix(DisasContext *dc)
+@@ -313,7 +372,8 @@ static unsigned int dec10_setclrf(DisasContext *dc)
+ if (set) {
+ tcg_gen_ori_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], flags);
+ } else {
+- tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS], ~flags);
++ tcg_gen_andi_tl(cpu_PR[PR_CCS], cpu_PR[PR_CCS],
++ ~(flags|F_FLAG_V10|P_FLAG_V10));
+ }
+
+ dc->flags_uptodate = 1;
+@@ -723,7 +783,7 @@ static unsigned int dec10_ind_move_r_m(DisasContext *dc, unsigned int size)
+ LOG_DIS("move.%d $r%d, [$r%d]\n", dc->size, dc->src, dc->dst);
+ addr = tcg_temp_new();
+ crisv10_prepare_memaddr(dc, addr, size);
+- gen_store(dc, addr, cpu_R[dc->dst], size);
++ gen_store_v10(dc, addr, cpu_R[dc->dst], size);
+ insn_len += crisv10_post_memaddr(dc, size);
+
+ return insn_len;
+@@ -767,10 +827,10 @@ static unsigned int dec10_ind_move_pr_m(DisasContext *dc)
+ t0 = tcg_temp_new();
+ cris_evaluate_flags(dc);
+ tcg_gen_andi_tl(t0, cpu_PR[PR_CCS], ~PFIX_FLAG);
+- gen_store(dc, addr, t0, size);
++ gen_store_v10(dc, addr, t0, size);
+ tcg_temp_free(t0);
+ } else {
+- gen_store(dc, addr, cpu_PR[dc->dst], size);
++ gen_store_v10(dc, addr, cpu_PR[dc->dst], size);
+ }
+ t0 = tcg_temp_new();
+ insn_len += crisv10_post_memaddr(dc, size);
+@@ -793,9 +853,9 @@ static void dec10_movem_r_m(DisasContext *dc)
+ tcg_gen_mov_tl(t0, addr);
+ for (i = dc->dst; i >= 0; i--) {
+ if ((pfix && dc->mode == CRISV10_MODE_AUTOINC) && dc->src == i) {
+- gen_store(dc, addr, t0, 4);
++ gen_store_v10(dc, addr, t0, 4);
+ } else {
+- gen_store(dc, addr, cpu_R[i], 4);
++ gen_store_v10(dc, addr, cpu_R[i], 4);
+ }
+ tcg_gen_addi_tl(addr, addr, 4);
+ }
+--
+1.7.7.5
+
diff --git a/0013-pc-add-pc-0.15.patch b/0013-pc-add-pc-0.15.patch
new file mode 100644
index 0000000..f85b065
--- /dev/null
+++ b/0013-pc-add-pc-0.15.patch
@@ -0,0 +1,40 @@
+From a25808dc5baee83f36e0cdab998eb6c0024156fa Mon Sep 17 00:00:00 2001
+From: Anthony Liguori <aliguori at us.ibm.com>
+Date: Sun, 18 Dec 2011 12:59:12 -0600
+Subject: [PATCH 13/25] pc: add pc-0.15
+
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+---
+ hw/pc_piix.c | 9 +++++++++
+ 1 files changed, 9 insertions(+), 0 deletions(-)
+
+diff --git a/hw/pc_piix.c b/hw/pc_piix.c
+index 970f43c..9093a28 100644
+--- a/hw/pc_piix.c
++++ b/hw/pc_piix.c
+@@ -306,6 +306,14 @@ static QEMUMachine pc_machine_v1_0 = {
+ .is_default = 1,
+ };
+
++static QEMUMachine pc_machine_v0_15 = {
++ .name = "pc-0.15",
++ .desc = "Standard PC",
++ .init = pc_init_pci,
++ .max_cpus = 255,
++ .is_default = 1,
++};
++
+ static QEMUMachine pc_machine_v0_14 = {
+ .name = "pc-0.14",
+ .desc = "Standard PC",
+@@ -557,6 +565,7 @@ static QEMUMachine xenfv_machine = {
+ static void pc_machine_init(void)
+ {
+ qemu_register_machine(&pc_machine_v1_0);
++ qemu_register_machine(&pc_machine_v0_15);
+ qemu_register_machine(&pc_machine_v0_14);
+ qemu_register_machine(&pc_machine_v0_13);
+ qemu_register_machine(&pc_machine_v0_12);
+--
+1.7.7.5
+
diff --git a/0014-pc-fix-event_idx-compatibility-for-virtio-devices.patch b/0014-pc-fix-event_idx-compatibility-for-virtio-devices.patch
new file mode 100644
index 0000000..121ec6c
--- /dev/null
+++ b/0014-pc-fix-event_idx-compatibility-for-virtio-devices.patch
@@ -0,0 +1,87 @@
+From 7e2191ae9898cc957a3d1991aff0e40f2e0f44a4 Mon Sep 17 00:00:00 2001
+From: Anthony Liguori <aliguori at us.ibm.com>
+Date: Sun, 18 Dec 2011 13:07:03 -0600
+Subject: [PATCH 14/25] pc: fix event_idx compatibility for virtio devices
+
+event_idx was introduced in 0.15 and must be disabled for all virtio-pci devices
+(including virtio-balloon-pci).
+
+Signed-off-by: Anthony Liguori <aliguori at us.ibm.com>
+---
+ hw/pc_piix.c | 32 ++++++++++++++++++++++++++++++++
+ 1 files changed, 32 insertions(+), 0 deletions(-)
+
+diff --git a/hw/pc_piix.c b/hw/pc_piix.c
+index 9093a28..05000e3 100644
+--- a/hw/pc_piix.c
++++ b/hw/pc_piix.c
+@@ -328,6 +328,22 @@ static QEMUMachine pc_machine_v0_14 = {
+ .driver = "qxl-vga",
+ .property = "revision",
+ .value = stringify(2),
++ },{
++ .driver = "virtio-blk-pci",
++ .property = "event_idx",
++ .value = "off",
++ },{
++ .driver = "virtio-serial-pci",
++ .property = "event_idx",
++ .value = "off",
++ },{
++ .driver = "virtio-net-pci",
++ .property = "event_idx",
++ .value = "off",
++ },{
++ .driver = "virtio-balloon-pci",
++ .property = "event_idx",
++ .value = "off",
+ },
+ { /* end of list */ }
+ },
+@@ -368,6 +384,10 @@ static QEMUMachine pc_machine_v0_13 = {
+ .property = "event_idx",
+ .value = "off",
+ },{
++ .driver = "virtio-balloon-pci",
++ .property = "event_idx",
++ .value = "off",
++ },{
+ .driver = "AC97",
+ .property = "use_broken_id",
+ .value = stringify(1),
+@@ -415,6 +435,10 @@ static QEMUMachine pc_machine_v0_12 = {
+ .property = "event_idx",
+ .value = "off",
+ },{
++ .driver = "virtio-balloon-pci",
++ .property = "event_idx",
++ .value = "off",
++ },{
+ .driver = "AC97",
+ .property = "use_broken_id",
+ .value = stringify(1),
+@@ -470,6 +494,10 @@ static QEMUMachine pc_machine_v0_11 = {
+ .property = "event_idx",
+ .value = "off",
+ },{
++ .driver = "virtio-balloon-pci",
++ .property = "event_idx",
++ .value = "off",
++ },{
+ .driver = "AC97",
+ .property = "use_broken_id",
+ .value = stringify(1),
+@@ -537,6 +565,10 @@ static QEMUMachine pc_machine_v0_10 = {
+ .property = "event_idx",
+ .value = "off",
+ },{
++ .driver = "virtio-balloon-pci",
++ .property = "event_idx",
++ .value = "off",
++ },{
+ .driver = "AC97",
+ .property = "use_broken_id",
+ .value = stringify(1),
+--
+1.7.7.5
+
diff --git a/0015-Fix-parse-of-usb-device-description-with-multiple-co.patch b/0015-Fix-parse-of-usb-device-description-with-multiple-co.patch
new file mode 100644
index 0000000..efc5119
--- /dev/null
+++ b/0015-Fix-parse-of-usb-device-description-with-multiple-co.patch
@@ -0,0 +1,56 @@
+From 9b81fbdbb0cc930aacec343c6ab37adfd60c9e76 Mon Sep 17 00:00:00 2001
+From: "Cao,Bing Bu" <mars at linux.vnet.ibm.com>
+Date: Tue, 13 Dec 2011 09:22:20 +0800
+Subject: [PATCH 15/25] Fix parse of usb device description with multiple
+ configurations
+
+Changed From V1:
+Use DPRINTF instead of fprintf,because it is not an error.
+
+When testing ipod on QEMU by He Jie Xu<xuhj at linux.vnet.ibm.com>,qemu made a assertion.
+We found that the ipod with 2 configurations,and the usb-linux did not parse the descriptor correctly.
+The descr_len returned is the total length of the all configurations,not one configuration.
+The older version will through the other configurations instead of skip,continue parsing the descriptor of interfaces/endpoints in other configurations,then went wrong.
+
+This patch will put the configuration descriptor parse in loop outside and dispel the other configurations not requested.
+
+Signed-off-by: Cao,Bing Bu <mars at linux.vnet.ibm.com>
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ usb-linux.c | 19 +++++++++++--------
+ 1 files changed, 11 insertions(+), 8 deletions(-)
+
+diff --git a/usb-linux.c b/usb-linux.c
+index ab4c693..ed14bb1 100644
+--- a/usb-linux.c
++++ b/usb-linux.c
+@@ -1141,15 +1141,18 @@ static int usb_linux_update_endp_table(USBHostDevice *s)
+ length = s->descr_len - 18;
+ i = 0;
+
+- if (descriptors[i + 1] != USB_DT_CONFIG ||
+- descriptors[i + 5] != s->configuration) {
+- fprintf(stderr, "invalid descriptor data - configuration %d\n",
+- s->configuration);
+- return 1;
+- }
+- i += descriptors[i];
+-
+ while (i < length) {
++ if (descriptors[i + 1] != USB_DT_CONFIG) {
++ fprintf(stderr, "invalid descriptor data\n");
++ return 1;
++ } else if (descriptors[i + 5] != s->configuration) {
++ DPRINTF("not requested configuration %d\n", s->configuration);
++ i += (descriptors[i + 3] << 8) + descriptors[i + 2];
++ continue;
++ }
++
++ i += descriptors[i];
++
+ if (descriptors[i + 1] != USB_DT_INTERFACE ||
+ (descriptors[i + 1] == USB_DT_INTERFACE &&
+ descriptors[i + 4] == 0)) {
+--
+1.7.7.5
+
diff --git a/0016-usb-storage-cancel-I-O-on-reset.patch b/0016-usb-storage-cancel-I-O-on-reset.patch
new file mode 100644
index 0000000..5fdd63d
--- /dev/null
+++ b/0016-usb-storage-cancel-I-O-on-reset.patch
@@ -0,0 +1,40 @@
+From f63d074313c5df917535587b50802ece7beb6e45 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Wed, 4 Jan 2012 18:13:54 +0100
+Subject: [PATCH 16/25] usb-storage: cancel I/O on reset
+
+When resetting the usb-storage device we'll have to carefully cancel
+and clear any requests which might be in flight, otherwise we'll confuse
+the state machine.
+
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ hw/usb-msd.c | 12 ++++++++++++
+ 1 files changed, 12 insertions(+), 0 deletions(-)
+
+diff --git a/hw/usb-msd.c b/hw/usb-msd.c
+index 4c06950..3147131 100644
+--- a/hw/usb-msd.c
++++ b/hw/usb-msd.c
+@@ -278,6 +278,18 @@ static void usb_msd_handle_reset(USBDevice *dev)
+ MSDState *s = (MSDState *)dev;
+
+ DPRINTF("Reset\n");
++ if (s->req) {
++ scsi_req_cancel(s->req);
++ }
++ assert(s->req == NULL);
++
++ if (s->packet) {
++ USBPacket *p = s->packet;
++ s->packet = NULL;
++ p->result = USB_RET_STALL;
++ usb_packet_complete(dev, p);
++ }
++
+ s->mode = USB_MSDM_CBW;
+ }
+
+--
+1.7.7.5
+
diff --git a/0017-usb-host-properly-release-port-on-unplug-exit.patch b/0017-usb-host-properly-release-port-on-unplug-exit.patch
new file mode 100644
index 0000000..5804510
--- /dev/null
+++ b/0017-usb-host-properly-release-port-on-unplug-exit.patch
@@ -0,0 +1,111 @@
+From c936f649d4a6b87cabe809170874f6b560cc0524 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel at redhat.com>
+Date: Thu, 5 Jan 2012 15:49:18 +0100
+Subject: [PATCH 17/25] usb-host: properly release port on unplug & exit
+
+Factor out port release into a separate function. Call release function
+in exit notifier too. Add explicit call the USBDEVFS_RELEASE_PORT
+ioctl, just closing the hub file handle seems not to be enougth. Make
+sure we release the port before resetting the device, otherwise host
+drivers will not re-attach.
+
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ usb-linux.c | 28 ++++++++++++++++++++--------
+ 1 files changed, 20 insertions(+), 8 deletions(-)
+
+diff --git a/usb-linux.c b/usb-linux.c
+index ed14bb1..749ce71 100644
+--- a/usb-linux.c
++++ b/usb-linux.c
+@@ -116,6 +116,7 @@ typedef struct USBHostDevice {
+ USBDevice dev;
+ int fd;
+ int hub_fd;
++ int hub_port;
+
+ uint8_t descr[8192];
+ int descr_len;
+@@ -434,7 +435,7 @@ static int usb_host_claim_port(USBHostDevice *s)
+ {
+ #ifdef USBDEVFS_CLAIM_PORT
+ char *h, hub_name[64], line[1024];
+- int hub_addr, portnr, ret;
++ int hub_addr, ret;
+
+ snprintf(hub_name, sizeof(hub_name), "%d-%s",
+ s->match.bus_num, s->match.port);
+@@ -442,13 +443,13 @@ static int usb_host_claim_port(USBHostDevice *s)
+ /* try strip off last ".$portnr" to get hub */
+ h = strrchr(hub_name, '.');
+ if (h != NULL) {
+- portnr = atoi(h+1);
++ s->hub_port = atoi(h+1);
+ *h = '\0';
+ } else {
+ /* no dot in there -> it is the root hub */
+ snprintf(hub_name, sizeof(hub_name), "usb%d",
+ s->match.bus_num);
+- portnr = atoi(s->match.port);
++ s->hub_port = atoi(s->match.port);
+ }
+
+ if (!usb_host_read_file(line, sizeof(line), "devnum",
+@@ -469,20 +470,32 @@ static int usb_host_claim_port(USBHostDevice *s)
+ return -1;
+ }
+
+- ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &portnr);
++ ret = ioctl(s->hub_fd, USBDEVFS_CLAIM_PORT, &s->hub_port);
+ if (ret < 0) {
+ close(s->hub_fd);
+ s->hub_fd = -1;
+ return -1;
+ }
+
+- trace_usb_host_claim_port(s->match.bus_num, hub_addr, portnr);
++ trace_usb_host_claim_port(s->match.bus_num, hub_addr, s->hub_port);
+ return 0;
+ #else
+ return -1;
+ #endif
+ }
+
++static void usb_host_release_port(USBHostDevice *s)
++{
++ if (s->hub_fd == -1) {
++ return;
++ }
++#ifdef USBDEVFS_RELEASE_PORT
++ ioctl(s->hub_fd, USBDEVFS_RELEASE_PORT, &s->hub_port);
++#endif
++ close(s->hub_fd);
++ s->hub_fd = -1;
++}
++
+ static int usb_host_disconnect_ifaces(USBHostDevice *dev, int nb_interfaces)
+ {
+ /* earlier Linux 2.4 do not support that */
+@@ -635,10 +648,8 @@ static void usb_host_handle_destroy(USBDevice *dev)
+ {
+ USBHostDevice *s = (USBHostDevice *)dev;
+
++ usb_host_release_port(s);
+ usb_host_close(s);
+- if (s->hub_fd != -1) {
+- close(s->hub_fd);
+- }
+ QTAILQ_REMOVE(&hostdevs, s, next);
+ qemu_remove_exit_notifier(&s->exit);
+ }
+@@ -1402,6 +1413,7 @@ static void usb_host_exit_notifier(struct Notifier *n, void *data)
+ {
+ USBHostDevice *s = container_of(n, USBHostDevice, exit);
+
++ usb_host_release_port(s);
+ if (s->fd != -1) {
+ usb_host_do_reset(s);;
+ }
+--
+1.7.7.5
+
diff --git a/0018-usb-ohci-td.cbp-incorrectly-updated-near-page-end.patch b/0018-usb-ohci-td.cbp-incorrectly-updated-near-page-end.patch
new file mode 100644
index 0000000..bba083e
--- /dev/null
+++ b/0018-usb-ohci-td.cbp-incorrectly-updated-near-page-end.patch
@@ -0,0 +1,40 @@
+From 23201c64a789cf948fedcea221a4b6e197fcd628 Mon Sep 17 00:00:00 2001
+From: Andriy Gapon <avg at FreeBSD.org>
+Date: Thu, 22 Dec 2011 11:34:30 +0200
+Subject: [PATCH 18/25] usb-ohci: td.cbp incorrectly updated near page end
+
+The current code that updates the cbp value after a transfer looks like this:
+td.cbp += ret;
+if ((td.cbp & 0xfff) + ret > 0xfff) {
+ <handle page overflow>
+because the 'ret' value is effectively added twice the check may fire too early
+when the overflow hasn't happened yet.
+
+Below is one of the possible changes that correct the behavior:
+
+Signed-off-by: Gerd Hoffmann <kraxel at redhat.com>
+---
+ hw/usb-ohci.c | 6 +++---
+ 1 files changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/hw/usb-ohci.c b/hw/usb-ohci.c
+index c2981c5..c27014a 100644
+--- a/hw/usb-ohci.c
++++ b/hw/usb-ohci.c
+@@ -1025,10 +1025,10 @@ static int ohci_service_td(OHCIState *ohci, struct ohci_ed *ed)
+ if (ret == len) {
+ td.cbp = 0;
+ } else {
+- td.cbp += ret;
+ if ((td.cbp & 0xfff) + ret > 0xfff) {
+- td.cbp &= 0xfff;
+- td.cbp |= td.be & ~0xfff;
++ td.cbp = (td.be & ~0xfff) + ((td.cbp + ret) & 0xfff);
++ } else {
++ td.cbp += ret;
+ }
+ }
+ td.flags |= OHCI_TD_T1;
+--
+1.7.7.5
+
diff --git a/0019-target-sh4-ignore-ocbp-and-ocbwb-instructions.patch b/0019-target-sh4-ignore-ocbp-and-ocbwb-instructions.patch
new file mode 100644
index 0000000..d3a4197
--- /dev/null
+++ b/0019-target-sh4-ignore-ocbp-and-ocbwb-instructions.patch
@@ -0,0 +1,47 @@
+From 37769d27270eff15d878a1c7df23407fc5f09b7f Mon Sep 17 00:00:00 2001
+From: Aurelien Jarno <aurelien at aurel32.net>
+Date: Sat, 7 Jan 2012 15:20:12 +0100
+Subject: [PATCH 19/25] target-sh4: ignore ocbp and ocbwb instructions
+
+ocbp and ocbwb controls the writeback of a cache line to memory. They
+are supposed to do nothing in case of a cache miss. Given QEMU only
+partially emulate caches, it is safe to ignore these instructions.
+
+This fixes a kernel oops when trying to access an rtl8139 NIC with
+recent versions.
+
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit 0cdb95549fedc73e13c147ab9dcabcc303426a07)
+---
+ target-sh4/translate.c | 14 +++-----------
+ 1 files changed, 3 insertions(+), 11 deletions(-)
+
+diff --git a/target-sh4/translate.c b/target-sh4/translate.c
+index bad3577..e04a6e0 100644
+--- a/target-sh4/translate.c
++++ b/target-sh4/translate.c
+@@ -1652,18 +1652,10 @@ static void _decode_opc(DisasContext * ctx)
+ }
+ return;
+ case 0x00a3: /* ocbp @Rn */
+- {
+- TCGv dummy = tcg_temp_new();
+- tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
+- tcg_temp_free(dummy);
+- }
+- return;
+ case 0x00b3: /* ocbwb @Rn */
+- {
+- TCGv dummy = tcg_temp_new();
+- tcg_gen_qemu_ld32s(dummy, REG(B11_8), ctx->memidx);
+- tcg_temp_free(dummy);
+- }
++ /* These instructions are supposed to do nothing in case of
++ a cache miss. Given that we only partially emulate caches
++ it is safe to simply ignore them. */
+ return;
+ case 0x0083: /* pref @Rn */
+ return;
+--
+1.7.7.5
+
diff --git a/0020-PPC-Fix-linker-scripts-on-ppc-hosts.patch b/0020-PPC-Fix-linker-scripts-on-ppc-hosts.patch
new file mode 100644
index 0000000..f6ce35a
--- /dev/null
+++ b/0020-PPC-Fix-linker-scripts-on-ppc-hosts.patch
@@ -0,0 +1,74 @@
+From fbcf305e5adc310e6383d4ec5e844f3f8d072116 Mon Sep 17 00:00:00 2001
+From: Alexander Graf <agraf at suse.de>
+Date: Mon, 12 Dec 2011 22:36:01 +0100
+Subject: [PATCH 20/25] PPC: Fix linker scripts on ppc hosts
+
+When compiling qemu statically with multilib on PPC, we hit the
+same issue that commit 845f2c2812d9ed24b36c02a3d06ee83aeafe8b49
+is fixing. Do the same here.
+
+Signed-off-by: Alexander Graf <agraf at suse.de>
+Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
+(cherry picked from commit 665a04ae1cbfa8004a38cf0fe99ba799c978a1fe)
+---
+ ppc.ld | 16 ++++++++++++++--
+ ppc64.ld | 16 ++++++++++++++--
+ 2 files changed, 28 insertions(+), 4 deletions(-)
+
+diff --git a/ppc.ld b/ppc.ld
+index 69aa3f2..2a0dcad 100644
+--- a/ppc.ld
++++ b/ppc.ld
+@@ -49,8 +49,20 @@ SECTIONS
+ .rela.sbss2 : { *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*) }
+ .rel.bss : { *(.rel.bss .rel.bss.* .rel.gnu.linkonce.b.*) }
+ .rela.bss : { *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*) }
+- .rel.plt : { *(.rel.plt) }
+- .rela.plt : { *(.rela.plt) }
++ .rel.plt :
++ {
++ *(.rel.plt)
++ PROVIDE (__rel_iplt_start = .);
++ *(.rel.iplt)
++ PROVIDE (__rel_iplt_end = .);
++ }
++ .rela.plt :
++ {
++ *(.rela.plt)
++ PROVIDE (__rela_iplt_start = .);
++ *(.rela.iplt)
++ PROVIDE (__rela_iplt_end = .);
++ }
+ .init :
+ {
+ KEEP (*(.init))
+diff --git a/ppc64.ld b/ppc64.ld
+index 0a7c0dd..e2dafa0 100644
+--- a/ppc64.ld
++++ b/ppc64.ld
+@@ -54,8 +54,20 @@ SECTIONS
+ *(.rela.sbss2 .rela.sbss2.* .rela.gnu.linkonce.sb2.*)
+ *(.rela.bss .rela.bss.* .rela.gnu.linkonce.b.*)
+ }
+- .rel.plt : { *(.rel.plt) }
+- .rela.plt : { *(.rela.plt) }
++ .rel.plt :
++ {
++ *(.rel.plt)
++ PROVIDE (__rel_iplt_start = .);
++ *(.rel.iplt)
++ PROVIDE (__rel_iplt_end = .);
++ }
++ .rela.plt :
++ {
++ *(.rela.plt)
++ PROVIDE (__rela_iplt_start = .);
++ *(.rela.iplt)
++ PROVIDE (__rela_iplt_end = .);
++ }
+ .rela.tocbss : { *(.rela.tocbss) }
+ .init :
+ {
+--
+1.7.7.5
+
diff --git a/0021-qiov-prevent-double-free-or-use-after-free.patch b/0021-qiov-prevent-double-free-or-use-after-free.patch
new file mode 100644
index 0000000..08e0e84
--- /dev/null
+++ b/0021-qiov-prevent-double-free-or-use-after-free.patch
@@ -0,0 +1,34 @@
+From 6061f16a8a119a46e61f2ddbabdb58f83e8857f7 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini at redhat.com>
+Date: Fri, 25 Nov 2011 12:06:22 +0100
+Subject: [PATCH 21/25] qiov: prevent double free or use-after-free
+
+qemu_iovec_destroy does not clear the QEMUIOVector fully, and the data
+could thus be used after free or freed again. While I do not know any
+example in the tree, I observed this using virtio-scsi (and SCSI
+scatter/gather) when canceling DMA requests.
+
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+---
+ cutils.c | 3 +++
+ 1 files changed, 3 insertions(+), 0 deletions(-)
+
+diff --git a/cutils.c b/cutils.c
+index 6db6304..24b3fe3 100644
+--- a/cutils.c
++++ b/cutils.c
+@@ -217,7 +217,10 @@ void qemu_iovec_destroy(QEMUIOVector *qiov)
+ {
+ assert(qiov->nalloc != -1);
+
++ qemu_iovec_reset(qiov);
+ g_free(qiov->iov);
++ qiov->nalloc = 0;
++ qiov->iov = NULL;
+ }
+
+ void qemu_iovec_reset(QEMUIOVector *qiov)
+--
+1.7.7.5
+
diff --git a/0022-coroutine-switch-per-thread-free-pool-to-a-global-po.patch b/0022-coroutine-switch-per-thread-free-pool-to-a-global-po.patch
new file mode 100644
index 0000000..eebdfaa
--- /dev/null
+++ b/0022-coroutine-switch-per-thread-free-pool-to-a-global-po.patch
@@ -0,0 +1,115 @@
+From fe5c13ebf1161d0f324229cfb36cb5fb87ec6248 Mon Sep 17 00:00:00 2001
+From: Avi Kivity <avi at redhat.com>
+Date: Mon, 5 Dec 2011 19:20:12 +0200
+Subject: [PATCH 22/25] coroutine: switch per-thread free pool to a global
+ pool
+
+ucontext-based coroutines use a free pool to reduce allocations and
+deallocations of coroutine objects. The pool is per-thread, presumably
+to improve locality. However, as coroutines are usually allocated in
+a vcpu thread and freed in the I/O thread, the pool accounting gets
+screwed up and we end allocating and freeing a coroutine for every I/O
+request. This is expensive since large objects are allocated via the
+kernel, and are not cached by the C runtime.
+
+Fix by switching to a global pool. This is safe since we're protected
+by the global mutex.
+
+Signed-off-by: Avi Kivity <avi at redhat.com>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+---
+ coroutine-ucontext.c | 30 ++++++++++++++++--------------
+ 1 files changed, 16 insertions(+), 14 deletions(-)
+
+diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c
+index 2b8d3e9..3d01075 100644
+--- a/coroutine-ucontext.c
++++ b/coroutine-ucontext.c
+@@ -35,6 +35,10 @@ enum {
+ POOL_MAX_SIZE = 64,
+ };
+
++/** Free list to speed up creation */
++static QLIST_HEAD(, Coroutine) pool = QLIST_HEAD_INITIALIZER(pool);
++static unsigned int pool_size;
++
+ typedef struct {
+ Coroutine base;
+ void *stack;
+@@ -48,10 +52,6 @@ typedef struct {
+ /** Currently executing coroutine */
+ Coroutine *current;
+
+- /** Free list to speed up creation */
+- QLIST_HEAD(, Coroutine) pool;
+- unsigned int pool_size;
+-
+ /** The default coroutine */
+ CoroutineUContext leader;
+ } CoroutineThreadState;
+@@ -75,7 +75,6 @@ static CoroutineThreadState *coroutine_get_thread_state(void)
+ if (!s) {
+ s = g_malloc0(sizeof(*s));
+ s->current = &s->leader.base;
+- QLIST_INIT(&s->pool);
+ pthread_setspecific(thread_state_key, s);
+ }
+ return s;
+@@ -84,14 +83,19 @@ static CoroutineThreadState *coroutine_get_thread_state(void)
+ static void qemu_coroutine_thread_cleanup(void *opaque)
+ {
+ CoroutineThreadState *s = opaque;
++
++ g_free(s);
++}
++
++static void __attribute__((destructor)) coroutine_cleanup(void)
++{
+ Coroutine *co;
+ Coroutine *tmp;
+
+- QLIST_FOREACH_SAFE(co, &s->pool, pool_next, tmp) {
++ QLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) {
+ g_free(DO_UPCAST(CoroutineUContext, base, co)->stack);
+ g_free(co);
+ }
+- g_free(s);
+ }
+
+ static void __attribute__((constructor)) coroutine_init(void)
+@@ -169,13 +173,12 @@ static Coroutine *coroutine_new(void)
+
+ Coroutine *qemu_coroutine_new(void)
+ {
+- CoroutineThreadState *s = coroutine_get_thread_state();
+ Coroutine *co;
+
+- co = QLIST_FIRST(&s->pool);
++ co = QLIST_FIRST(&pool);
+ if (co) {
+ QLIST_REMOVE(co, pool_next);
+- s->pool_size--;
++ pool_size--;
+ } else {
+ co = coroutine_new();
+ }
+@@ -184,13 +187,12 @@ Coroutine *qemu_coroutine_new(void)
+
+ void qemu_coroutine_delete(Coroutine *co_)
+ {
+- CoroutineThreadState *s = coroutine_get_thread_state();
+ CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_);
+
+- if (s->pool_size < POOL_MAX_SIZE) {
+- QLIST_INSERT_HEAD(&s->pool, &co->base, pool_next);
++ if (pool_size < POOL_MAX_SIZE) {
++ QLIST_INSERT_HEAD(&pool, &co->base, pool_next);
+ co->base.caller = NULL;
+- s->pool_size++;
++ pool_size++;
+ return;
+ }
+
+--
+1.7.7.5
+
diff --git a/0023-qemu-img-rebase-Fix-for-undersized-backing-files.patch b/0023-qemu-img-rebase-Fix-for-undersized-backing-files.patch
new file mode 100644
index 0000000..413ebd0
--- /dev/null
+++ b/0023-qemu-img-rebase-Fix-for-undersized-backing-files.patch
@@ -0,0 +1,86 @@
+From 5bb37d151b026759ee35f04212b11b4d625c7431 Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf at redhat.com>
+Date: Wed, 7 Dec 2011 12:42:10 +0100
+Subject: [PATCH 23/25] qemu-img rebase: Fix for undersized backing files
+
+Backing files may be smaller than the corresponding COW file. When
+reading directly from the backing file, qemu-img rebase must consider
+this and assume zero sectors after the end of backing files.
+
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+---
+ qemu-img.c | 42 +++++++++++++++++++++++++++++++++---------
+ 1 files changed, 33 insertions(+), 9 deletions(-)
+
+diff --git a/qemu-img.c b/qemu-img.c
+index 8bdae66..01cc0d3 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -1420,6 +1420,8 @@ static int img_rebase(int argc, char **argv)
+ */
+ if (!unsafe) {
+ uint64_t num_sectors;
++ uint64_t old_backing_num_sectors;
++ uint64_t new_backing_num_sectors;
+ uint64_t sector;
+ int n;
+ uint8_t * buf_old;
+@@ -1430,6 +1432,8 @@ static int img_rebase(int argc, char **argv)
+ buf_new = qemu_blockalign(bs, IO_BUF_SIZE);
+
+ bdrv_get_geometry(bs, &num_sectors);
++ bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors);
++ bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors);
+
+ local_progress = (float)100 /
+ (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512));
+@@ -1448,16 +1452,36 @@ static int img_rebase(int argc, char **argv)
+ continue;
+ }
+
+- /* Read old and new backing file */
+- ret = bdrv_read(bs_old_backing, sector, buf_old, n);
+- if (ret < 0) {
+- error_report("error while reading from old backing file");
+- goto out;
++ /*
++ * Read old and new backing file and take into consideration that
++ * backing files may be smaller than the COW image.
++ */
++ if (sector >= old_backing_num_sectors) {
++ memset(buf_old, 0, n * BDRV_SECTOR_SIZE);
++ } else {
++ if (sector + n > old_backing_num_sectors) {
++ n = old_backing_num_sectors - sector;
++ }
++
++ ret = bdrv_read(bs_old_backing, sector, buf_old, n);
++ if (ret < 0) {
++ error_report("error while reading from old backing file");
++ goto out;
++ }
+ }
+- ret = bdrv_read(bs_new_backing, sector, buf_new, n);
+- if (ret < 0) {
+- error_report("error while reading from new backing file");
+- goto out;
++
++ if (sector >= new_backing_num_sectors) {
++ memset(buf_new, 0, n * BDRV_SECTOR_SIZE);
++ } else {
++ if (sector + n > new_backing_num_sectors) {
++ n = new_backing_num_sectors - sector;
++ }
++
++ ret = bdrv_read(bs_new_backing, sector, buf_new, n);
++ if (ret < 0) {
++ error_report("error while reading from new backing file");
++ goto out;
++ }
+ }
+
+ /* If they differ, we need to write to the COW file */
+--
+1.7.7.5
+
diff --git a/0024-Documentation-Add-qemu-img-t-parameter-in-man-page.patch b/0024-Documentation-Add-qemu-img-t-parameter-in-man-page.patch
new file mode 100644
index 0000000..6df771d
--- /dev/null
+++ b/0024-Documentation-Add-qemu-img-t-parameter-in-man-page.patch
@@ -0,0 +1,82 @@
+From 8afe984ef7aa25cb2f8af51da021fdc8a242884d Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf at redhat.com>
+Date: Wed, 7 Dec 2011 13:57:13 +0100
+Subject: [PATCH 24/25] Documentation: Add qemu-img -t parameter in man page
+
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha at linux.vnet.ibm.com>
+---
+ qemu-img-cmds.hx | 6 +++---
+ qemu-img.texi | 10 +++++++---
+ 2 files changed, 10 insertions(+), 6 deletions(-)
+
+diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
+index 4be00a5..49dce7c 100644
+--- a/qemu-img-cmds.hx
++++ b/qemu-img-cmds.hx
+@@ -24,13 +24,13 @@ ETEXI
+ DEF("commit", img_commit,
+ "commit [-f fmt] [-t cache] filename")
+ STEXI
+- at item commit [-f @var{fmt}] @var{filename}
++ at item commit [-f @var{fmt}] [-t @var{cache}] @var{filename}
+ ETEXI
+
+ DEF("convert", img_convert,
+ "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename")
+ STEXI
+- at item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
++ at item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
+ ETEXI
+
+ DEF("info", img_info,
+@@ -48,7 +48,7 @@ ETEXI
+ DEF("rebase", img_rebase,
+ "rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
+ STEXI
+- at item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
++ at item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
+ ETEXI
+
+ DEF("resize", img_resize,
+diff --git a/qemu-img.texi b/qemu-img.texi
+index 70fa321..b2ca3a5 100644
+--- a/qemu-img.texi
++++ b/qemu-img.texi
+@@ -45,6 +45,10 @@ indicates the consecutive number of bytes that must contain only zeros
+ for qemu-img to create a sparse image during conversion. This value is rounded
+ down to the nearest 512 bytes. You may use the common size suffixes like
+ @code{k} for kilobytes.
++ at item -t @var{cache}
++specifies the cache mode that should be used with the (destination) file. See
++the documentation of the emulator's @code{-drive cache=...} option for allowed
++values.
+ @end table
+
+ Parameters to snapshot subcommand:
+@@ -87,11 +91,11 @@ this case. @var{backing_file} will never be modified unless you use the
+ The size can also be specified using the @var{size} option with @code{-o},
+ it doesn't need to be specified separately in this case.
+
+- at item commit [-f @var{fmt}] @var{filename}
++ at item commit [-f @var{fmt}] [-t @var{cache}] @var{filename}
+
+ Commit the changes recorded in @var{filename} in its base image.
+
+- at item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename}
++ at item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @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}
+@@ -121,7 +125,7 @@ they are displayed too.
+
+ List, apply, create or delete snapshots in image @var{filename}.
+
+- at item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
++ at item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
+
+ Changes the backing file of an image. Only the formats @code{qcow2} and
+ @code{qed} support changing the backing file.
+--
+1.7.7.5
+
diff --git a/0025-rbd-always-set-out-parameter-in-qemu_rbd_snap_list.patch b/0025-rbd-always-set-out-parameter-in-qemu_rbd_snap_list.patch
new file mode 100644
index 0000000..fb7010d
--- /dev/null
+++ b/0025-rbd-always-set-out-parameter-in-qemu_rbd_snap_list.patch
@@ -0,0 +1,39 @@
+From e47c212cb5af148ab6d9dcf49bc0e054fe9c2e1d Mon Sep 17 00:00:00 2001
+From: Josh Durgin <josh.durgin at dreamhost.com>
+Date: Tue, 6 Dec 2011 17:05:10 -0800
+Subject: [PATCH 25/25] rbd: always set out parameter in qemu_rbd_snap_list
+
+The caller expects psn_tab to be NULL when there are no snapshots or
+an error occurs. This results in calling g_free on an invalid address.
+
+Reported-by: Oliver Francke <Oliver at filoo.de>
+Signed-off-by: Josh Durgin <josh.durgin at dreamhost.com>
+Signed-off-by: Kevin Wolf <kwolf at redhat.com>
+---
+ block/rbd.c | 3 ++-
+ 1 files changed, 2 insertions(+), 1 deletions(-)
+
+diff --git a/block/rbd.c b/block/rbd.c
+index 9088c52..54a6961 100644
+--- a/block/rbd.c
++++ b/block/rbd.c
+@@ -808,7 +808,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
+ } while (snap_count == -ERANGE);
+
+ if (snap_count <= 0) {
+- return snap_count;
++ goto done;
+ }
+
+ sn_tab = g_malloc0(snap_count * sizeof(QEMUSnapshotInfo));
+@@ -827,6 +827,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs,
+ }
+ rbd_snap_list_end(snaps);
+
++ done:
+ *psn_tab = sn_tab;
+ return snap_count;
+ }
+--
+1.7.7.5
+
diff --git a/Fix_save-restore_of_in-kernel_i8259.patch b/Fix_save-restore_of_in-kernel_i8259.patch
new file mode 100644
index 0000000..15c772f
--- /dev/null
+++ b/Fix_save-restore_of_in-kernel_i8259.patch
@@ -0,0 +1,87 @@
+As the qemu-kvm version of the i8259 contains KVM bits, it still has to
+be compiled per target. This unbreaks migration of the i8259.
+
+Signed-off-by: Jan Kiszka <jan.kiszka at siemens.com>
+---
+
+Not sure if anyone bothers (no one should actually use qemu-kvm for
+targets != x86), but let's avoid needless breakages of other targets
+requiring the i8259.
+
+ Makefile.objs | 2 +-
+ Makefile.target | 8 ++++----
+ hw/i8259.c | 2 --
+ 3 files changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/Makefile.objs b/Makefile.objs
+index 13afd19..77237e1 100644
+--- a/Makefile.objs
++++ b/Makefile.objs
+@@ -223,7 +223,7 @@ hw-obj-$(CONFIG_APPLESMC) += applesmc.o
+ hw-obj-$(CONFIG_SMARTCARD) += usb-ccid.o ccid-card-passthru.o
+ hw-obj-$(CONFIG_SMARTCARD_NSS) += ccid-card-emulated.o
+ hw-obj-$(CONFIG_USB_REDIR) += usb-redir.o
+-hw-obj-$(CONFIG_I8259) += i8259.o
++# hw-obj-$(CONFIG_I8259) += i8259.o
+
+ # PPC devices
+ hw-obj-$(CONFIG_PREP_PCI) += prep_pci.o
+diff --git a/Makefile.target b/Makefile.target
+index 0b610ad..29eaa68 100644
+--- a/Makefile.target
++++ b/Makefile.target
+@@ -236,7 +236,7 @@ obj-$(CONFIG_IVSHMEM) += ivshmem.o
+
+ # Hardware support
+ obj-i386-y += vga.o
+-obj-i386-y += mc146818rtc.o pc.o
++obj-i386-y += mc146818rtc.o pc.o i8259.o
+ obj-i386-y += cirrus_vga.o sga.o apic.o ioapic.o piix_pci.o
+ obj-i386-y += vmport.o
+ obj-i386-y += device-hotplug.o pci-hotplug.o smbios.o wdt_ib700.o
+@@ -255,7 +255,7 @@ obj-i386-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += device-assignment.o
+ obj-ppc-y = ppc.o ppc_booke.o
+ obj-ppc-y += vga.o
+ # PREP target
+-obj-ppc-y += mc146818rtc.o
++obj-ppc-y += mc146818rtc.o i8259.o
+ obj-ppc-y += ppc_prep.o
+ # OldWorld PowerMac
+ obj-ppc-y += ppc_oldworld.o
+@@ -311,7 +311,7 @@ obj-mips-y += acpi.o acpi_piix4.o
+ obj-mips-y += mips_addr.o mips_timer.o mips_int.o
+ obj-mips-y += vga.o
+ obj-mips-y += jazz_led.o
+-obj-mips-y += gt64xxx.o mc146818rtc.o
++obj-mips-y += gt64xxx.o mc146818rtc.o i8259.o
+ obj-mips-y += cirrus_vga.o
+ obj-mips-$(CONFIG_FULONG) += bonito.o vt82c686.o mips_fulong2e.o
+
+@@ -392,7 +392,7 @@ obj-m68k-y += m68k-semi.o dummy_m68k.o
+
+ obj-s390x-y = s390-virtio-bus.o s390-virtio.o
+
+-obj-alpha-y = mc146818rtc.o
++obj-alpha-y = mc146818rtc.o i8259.o
+ obj-alpha-y += vga.o cirrus_vga.o
+ obj-alpha-y += alpha_pci.o alpha_dp264.o alpha_typhoon.o
+
+diff --git a/hw/i8259.c b/hw/i8259.c
+index fa63e83..a9ea9c9 100644
+--- a/hw/i8259.c
++++ b/hw/i8259.c
+@@ -697,8 +697,6 @@ static int kvm_kernel_pic_load_from_user(PicState *s)
+ return 0;
+ }
+
+-extern void apic_set_irq_delivered(void);
+-
+ static void kvm_i8259_set_irq(void *opaque, int irq, int level)
+ {
+ int pic_ret;
+--
+1.7.3.4
+--
+To unsubscribe from this list: send the line "unsubscribe kvm" in
+the body of a message to majordomo at vger.kernel.org
+More majordomo info at http://vger.kernel.org/majordomo-info.html
diff --git a/sources b/sources
index fcf95cc..c8f2676 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-8800a7d6b3aa4a168ea7f78dc66c0320 qemu-kvm-0.15.1.tar.gz
+00a825db46a70ba8ef9fc95da9cc7c1e qemu-kvm-1.0.tar.gz
diff --git a/virtio-blk_refuse_SG_IO_requests_with_scsi_off.patch b/virtio-blk_refuse_SG_IO_requests_with_scsi_off.patch
new file mode 100644
index 0000000..277e740
--- /dev/null
+++ b/virtio-blk_refuse_SG_IO_requests_with_scsi_off.patch
@@ -0,0 +1,111 @@
+From qemu-stable-bounces+jmforbes=linuxtx.org at nongnu.org Wed Jan 11 03:51:20 2012
+Return-Path: <qemu-stable-bounces+jmforbes=linuxtx.org at nongnu.org>
+Received: from citysiren.linuxtx.org (localhost [127.0.0.1])
+ by citysiren.linuxtx.org (8.14.4/8.14.4) with ESMTP id q0B9pIjw017454
+ for <jmfmail at localhost>; Wed, 11 Jan 2012 03:51:20 -0600
+Delivered-To: jmforbes at linuxtx.org
+Received: from gmail-pop.l.google.com [74.125.81.108]
+ by citysiren.linuxtx.org with POP3 (fetchmail-6.3.20)
+ for <jmfmail at localhost> (single-drop); Wed, 11 Jan 2012 03:51:20 -0600 (CST)
+Received: by 10.180.102.100 with SMTP id fn4cs34060wib;
+ Wed, 11 Jan 2012 01:48:56 -0800 (PST)
+Received: by 10.224.182.2 with SMTP id ca2mr28967033qab.57.1326275334564;
+ Wed, 11 Jan 2012 01:48:54 -0800 (PST)
+Received: from lists.gnu.org (lists.gnu.org. [140.186.70.17])
+ by mx.google.com with ESMTPS id gc3si782557qab.44.2012.01.11.01.48.54
+ (version=TLSv1/SSLv3 cipher=OTHER);
+ Wed, 11 Jan 2012 01:48:54 -0800 (PST)
+Received-SPF: pass (google.com: domain of qemu-stable-bounces+jmforbes=linuxtx.org at nongnu.org designates 140.186.70.17 as permitted sender) client-ip=140.186.70.17;
+Authentication-Results: mx.google.com; spf=pass (google.com: domain of qemu-stable-bounces+jmforbes=linuxtx.org at nongnu.org designates 140.186.70.17 as permitted sender) smtp.mail=qemu-stable-bounces+jmforbes=linuxtx.org at nongnu.org
+Received: from localhost ([::1]:48473 helo=lists.gnu.org)
+ by lists.gnu.org with esmtp (Exim 4.71)
+ (envelope-from <qemu-stable-bounces+jmforbes=linuxtx.org at nongnu.org>)
+ id 1Rkund-0003iT-UQ
+ for jmforbes at linuxtx.org; Wed, 11 Jan 2012 04:48:53 -0500
+Received: from eggs.gnu.org ([140.186.70.92]:40037)
+ by lists.gnu.org with esmtp (Exim 4.71)
+ (envelope-from <pbonzini at redhat.com>) id 1RkunV-0003fY-Vl
+ for qemu-stable at nongnu.org; Wed, 11 Jan 2012 04:48:53 -0500
+Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71)
+ (envelope-from <pbonzini at redhat.com>) id 1RkunQ-0004zL-Nl
+ for qemu-stable at nongnu.org; Wed, 11 Jan 2012 04:48:45 -0500
+Received: from mx1.redhat.com ([209.132.183.28]:23781)
+ by eggs.gnu.org with esmtp (Exim 4.71)
+ (envelope-from <pbonzini at redhat.com>) id 1RkunQ-0004vY-3c
+ for qemu-stable at nongnu.org; Wed, 11 Jan 2012 04:48:40 -0500
+Received: from int-mx11.intmail.prod.int.phx2.redhat.com
+ (int-mx11.intmail.prod.int.phx2.redhat.com [10.5.11.24])
+ by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id q0B9mcYI005348
+ (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK)
+ for <qemu-stable at nongnu.org>; Wed, 11 Jan 2012 04:48:38 -0500
+Received: from yakj.usersys.redhat.com (ovpn-112-23.ams2.redhat.com
+ [10.36.112.23])
+ by int-mx11.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP
+ id q0B9magG031084
+ for <qemu-stable at nongnu.org>; Wed, 11 Jan 2012 04:48:37 -0500
+From: Paolo Bonzini <pbonzini at redhat.com>
+To: qemu-stable at nongnu.org
+Date: Wed, 11 Jan 2012 10:48:33 +0100
+Message-Id: <1326275313-15635-1-git-send-email-pbonzini at redhat.com>
+X-Scanned-By: MIMEDefang 2.68 on 10.5.11.24
+X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 3)
+X-Received-From: 209.132.183.28
+Subject: [Qemu-stable] [PATCH] virtio-blk: refuse SG_IO requests with
+ scsi=off
+X-BeenThere: qemu-stable at nongnu.org
+X-Mailman-Version: 2.1.14
+Precedence: list
+List-Id: <qemu-stable.nongnu.org>
+List-Unsubscribe: <https://lists.nongnu.org/mailman/options/qemu-stable>,
+ <mailto:qemu-stable-request at nongnu.org?subject=unsubscribe>
+List-Archive: <http://lists.nongnu.org/archive/html/qemu-stable>
+List-Post: <mailto:qemu-stable at nongnu.org>
+List-Help: <mailto:qemu-stable-request at nongnu.org?subject=help>
+List-Subscribe: <https://lists.nongnu.org/mailman/listinfo/qemu-stable>,
+ <mailto:qemu-stable-request at nongnu.org?subject=subscribe>
+Errors-To: qemu-stable-bounces+jmforbes=linuxtx.org at nongnu.org
+Sender: qemu-stable-bounces+jmforbes=linuxtx.org at nongnu.org
+X-UID: 32
+Status: RO
+Content-Length: 1003
+Lines: 38
+
+QEMU does have a "scsi" option (to be used like -device
+virtio-blk-pci,drive=foo,scsi=off). However, it only
+masks the feature bit, and does not reject the command
+if a malicious guest disregards the feature bits and
+issues a request.
+
+Without this patch, using scsi=off does not protect you
+from CVE-2011-4127.
+
+Signed-off-by: Paolo Bonzini <pbonzini at redhat.com>
+---
+ hw/virtio-blk.c | 6 ++++++
+ 1 files changed, 6 insertions(+), 0 deletions(-)
+
+diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
+index b70d116..6cd3164 100644
+--- a/hw/virtio-blk.c
++++ b/hw/virtio-blk.c
+@@ -153,6 +153,12 @@ static void virtio_blk_handle_scsi(VirtIOBlockReq *req)
+ int status;
+ int i;
+
++ if ((req->dev->vdev.guest_features & (1 << VIRTIO_BLK_F_SCSI)) == 0) {
++ virtio_blk_req_complete(req, VIRTIO_BLK_S_UNSUPP);
++ g_free(req);
++ return;
++ }
++
+ /*
+ * We require at least one output segment each for the virtio_blk_outhdr
+ * and the SCSI command block.
+--
+1.7.7.1
+
+
+
+
+
+
More information about the scm-commits
mailing list