Re: [Qemu-devel] [PATCH v3 2/3] qdev: interface for SysBusDevice to change property on requirement

2013-09-02 Thread liu ping fan
On Fri, Aug 30, 2013 at 4:17 PM, Paolo Bonzini pbonz...@redhat.com wrote:
 Il 30/08/2013 09:53, Liu Ping Fan ha scritto:
 qdev's property can not be set after realized, but there is a
 requirement of adjusting device's behavior on different mother
 boards.  So introducing a callback in sysbus_try_create_simple()
 to adjust device's property on board's demand.

 (This patch is needed by the later one which changes hpet's intcap
 property)

 I don't think it is useful to add a new mechanism since there is an
 existing mechanism to set properties for compatibility (which I pointed
 you to earlier).  It is also incorrect because this will have an effect

Oh, just aware of this tricky method to set qdev's property. Thanks,
will try this way!

Regards,
Pingfan
 on all PC boards including pc-q35-1.7 and newer.

 You need to create a 1.7 machine like commit 45053fd (pc: Create
 pc-*-1.6 machine-types, 2013-05-27).  On top of this:

 * the 1.6 machines need to have a compatibility property in hw/i386/pc.h.

 * the pc-i440fx-1.7 machine needs to have a compatibility property for
 the same thing in hw/i386/pc_piix.c

 Paolo

 Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com
 ---
  hw/core/sysbus.c| 5 -
  hw/i386/pc.c| 2 +-
  include/hw/sysbus.h | 8 +---
  3 files changed, 10 insertions(+), 5 deletions(-)

 diff --git a/hw/core/sysbus.c b/hw/core/sysbus.c
 index 9004d8c..e894bbb 100644
 --- a/hw/core/sysbus.c
 +++ b/hw/core/sysbus.c
 @@ -172,7 +172,7 @@ DeviceState *sysbus_create_varargs(const char *name,
  return dev;
  }

 -DeviceState *sysbus_try_create_varargs(const char *name,
 +DeviceState *sysbus_try_create_varargs(const char *name, CompatSet set,
 hwaddr addr, ...)
  {
  DeviceState *dev;
 @@ -185,6 +185,9 @@ DeviceState *sysbus_try_create_varargs(const char *name,
  if (!dev) {
  return NULL;
  }
 +if (set) {
 +set(dev);
 +}
  s = SYS_BUS_DEVICE(dev);
  qdev_init_nofail(dev);
  if (addr != (hwaddr)-1) {
 diff --git a/hw/i386/pc.c b/hw/i386/pc.c
 index e8bc8ce..09c10ac 100644
 --- a/hw/i386/pc.c
 +++ b/hw/i386/pc.c
 @@ -1247,7 +1247,7 @@ void pc_basic_device_init(ISABus *isa_bus, qemu_irq 
 *gsi,
   * when the HPET wants to take over. Thus we have to disable the latter.
   */
  if (!no_hpet  (!kvm_irqchip_in_kernel() || kvm_has_pit_state2())) {
 -hpet = sysbus_try_create_simple(hpet, HPET_BASE, NULL);
 +hpet = sysbus_try_create_simple(hpet, NULL, HPET_BASE, NULL);

  if (hpet) {
  for (i = 0; i  GSI_NUM_PINS; i++) {
 diff --git a/include/hw/sysbus.h b/include/hw/sysbus.h
 index bb50a87..47337f2 100644
 --- a/include/hw/sysbus.h
 +++ b/include/hw/sysbus.h
 @@ -58,6 +58,8 @@ struct SysBusDevice {
  pio_addr_t pio[QDEV_MAX_PIO];
  };

 +typedef void (*CompatSet)(DeviceState *dev);
 +
  void sysbus_init_mmio(SysBusDevice *dev, MemoryRegion *memory);
  MemoryRegion *sysbus_mmio_get_region(SysBusDevice *dev, int n);
  void sysbus_init_irq(SysBusDevice *dev, qemu_irq *p);
 @@ -77,7 +79,7 @@ MemoryRegion *sysbus_address_space(SysBusDevice *dev);
  /* Legacy helper function for creating devices.  */
  DeviceState *sysbus_create_varargs(const char *name,
   hwaddr addr, ...);
 -DeviceState *sysbus_try_create_varargs(const char *name,
 +DeviceState *sysbus_try_create_varargs(const char *name, CompatSet set,
 hwaddr addr, ...);
  static inline DeviceState *sysbus_create_simple(const char *name,
hwaddr addr,
 @@ -86,11 +88,11 @@ static inline DeviceState *sysbus_create_simple(const 
 char *name,
  return sysbus_create_varargs(name, addr, irq, NULL);
  }

 -static inline DeviceState *sysbus_try_create_simple(const char *name,
 +static inline DeviceState *sysbus_try_create_simple(const char *name, 
 CompatSet set,
  hwaddr addr,
  qemu_irq irq)
  {
 -return sysbus_try_create_varargs(name, addr, irq, NULL);
 +return sysbus_try_create_varargs(name, set, addr, irq, NULL);
  }

  #endif /* !HW_SYSBUS_H */





[Qemu-devel] [Bug 1024248] Re: qemu -M isapc displays blank screen

2013-09-02 Thread Michael Tokarev
It looks like this issue is fixed in 1.6.0 version

** Changed in: qemu
   Status: Confirmed = Fix Released

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1024248

Title:
  qemu -M isapc displays blank screen

Status in QEMU:
  Fix Released
Status in “qemu” package in Debian:
  Confirmed

Bug description:
  $ qemu-system-x86_64 -M isapc

  This displays blank SDL window.  It has been this way since forever I
  guess, at least according to http://bugs.debian.org/605525 (a Debian
  bugreport about it).  However, this:

  $ qemu-system-x86_64 -M isapc -enable-kvm

  works (at least in current 1.1), and it works fine in qemu-kvm.  On
  the other hand, this:

  $ qemu-kvm -M isapc -no-kvm

  also shows blank window.  Something is wrong with isapc  TCG, and has
  been for a long time...

  Thanks,

  /mjt

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1024248/+subscriptions



Re: [Qemu-devel] [PATCH v3 2/3] qdev: interface for SysBusDevice to change property on requirement

2013-09-02 Thread liu ping fan
On Fri, Aug 30, 2013 at 8:32 PM, Andreas Färber afaer...@suse.de wrote:
 Am 30.08.2013 10:17, schrieb Paolo Bonzini:
 Il 30/08/2013 09:53, Liu Ping Fan ha scritto:
 qdev's property can not be set after realized, but there is a
 requirement of adjusting device's behavior on different mother
 boards.  So introducing a callback in sysbus_try_create_simple()
 to adjust device's property on board's demand.

 (This patch is needed by the later one which changes hpet's intcap
 property)

 I don't think it is useful to add a new mechanism since there is an
 existing mechanism to set properties for compatibility (which I pointed
 you to earlier).  It is also incorrect because this will have an effect
 on all PC boards including pc-q35-1.7 and newer.

 You need to create a 1.7 machine like commit 45053fd (pc: Create
 pc-*-1.6 machine-types, 2013-05-27).

 Stefan already has than in his net tree and just needs to (rebase and)
 flush his queue!

Thanks, will do like it.

Regards,
Pingfan



Re: [Qemu-devel] [Qemu-trivial] [PATCH v3] slirp: Port redirection option behave differently on Linux and Windows

2013-09-02 Thread Jan Kiszka
On 2013-09-01 18:13, Stefan Weil wrote:
 Am 01.09.2013 17:46, schrieb Michael Tokarev:
 30.08.2013 15:04, Jan Kiszka wrote:
 On 2013-08-15 21:25, Taimoor wrote:
 From: Taimoor Mirza tmi...@codesourcery.com

 port redirection code uses SO_REUSEADDR socket option before binding to
 host port. Behavior of SO_REUSEADDR is different on Windows and Linux.
 Relaunching QEMU with same host and guest port redirection values on
 Linux
 throws error but on Windows it does not throw any error.
 Problem is discussed in
 http://lists.gnu.org/archive/html/qemu-devel/2013-04/msg03089.html
 []
 Stefan, can you ack this? Then I would pick it up for the slirp queue.

 I remember having exactly the same issue myself a few years back with
 the difference of SO_REUSEADDR behavour on windows and *nix, and the
 suggested change appears to be correct.  So you can count on my

 Reviewed-by: Michael Tokarev m...@tls.msk.ru

 as well.

 I applied the v2 of this patch (with a trivial fix) to trivial queue
 (before seeing this v3), I can remove it if you like.

 Thanks,

 /mjt
 
 Hi Michael,
 
 thanks for your review of this patch. I had no opportunity to test
 it myself, but I also think that it is fine.
 
 (v2 + trivial fix) should be identical to v3, so this looks good, too.

Yep, fine with me as well.

Thanks, everyone.

Jan

-- 
Siemens AG, Corporate Technology, CT RTC ITP SES-DE
Corporate Competence Center Embedded Linux



[Qemu-devel] [Bug 1187121] Re: segfault with -vga vmware and -display gtk

2013-09-02 Thread Michael Tokarev
This has been fixed in 1.6.0.

** Changed in: qemu
   Status: Confirmed = Fix Released

-- 
You received this bug notification because you are a member of qemu-
devel-ml, which is subscribed to QEMU.
https://bugs.launchpad.net/bugs/1187121

Title:
  segfault with -vga vmware and -display gtk

Status in QEMU:
  Fix Released
Status in “qemu” package in Debian:
  Confirmed

Bug description:
  When some guest is run with -vga vmware -display gtk, qemu segfaults
  after certain guest gui operations.

  ./x86_64-softmmu/qemu-system-x86_64 -cdrom
  ubuntu-10.04.4-desktop-i386.iso -vga vmware -enable-kvm

  (-enable-kvm just to speed things up, it does not depend on kvm).

  (Ubuntu desktop image is from http://old-
  releases.ubuntu.com/releases/lucid/ )

  This segfaults in a few moments after initial boot.

  Program received signal SIGSEGV, Segmentation fault.
  [Switching to Thread 0xf5bccb70 (LWP 23460)]
  0xf710792c in g_object_unref ()
 from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  (gdb) bt
  #0  0xf710792c in g_object_unref ()
 from /usr/lib/i386-linux-gnu/libgobject-2.0.so.0
  #1  0x5673b635 in gd_cursor_define (dcl=0x57153d44, c=0x5710e7b8)
  at ui/gtk.c:380
  #2  0x5673895b in dpy_cursor_define (con=0x570c07f8, 
  cursor=cursor@entry=0x5710e7b8) at ui/console.c:1547
  #3  0x5665f2a7 in vmsvga_cursor_define (c=0xf5bc6ef0, s=optimized out)
  at hw/display/vmware_vga.c:492
  #4  vmsvga_fifo_run (s=optimized out)
  at hw/display/vmware_vga.c:628
  #5  0x567ce6a8 in memory_region_write_accessor (
  opaque=opaque@entry=0x571291d0, addr=1, value=value@entry=0xf5bcc038, 
  size=size@entry=4, shift=0, mask=4294967295) at memory.c:334
  #6  0x567ce146 in access_with_adjusted_size (addr=optimized out, 
  value=value@entry=0xf5bcc038, size=size@entry=4, 
  access_size_min=optimized out, access_size_max=optimized out, 
  access=access@entry=0x567ce5e0 memory_region_write_accessor, 
  opaque=opaque@entry=0x571291d0) at memory.c:364
  #7  0x567cf28c in memory_region_iorange_write (iorange=0x57243f58, offset=1, 
  width=4, data=1) at memory.c:439
  #8  0x567c8b48 in ioport_writel_thunk (opaque=0x57243f58, addr=49233, data=1)
  at ioport.c:226
  #9  0x567c92d3 in ioport_write (data=1, address=49233, index=2)
  ...

  (gdb) frame 1
  #1  0x5673b635 in gd_cursor_define (dcl=0x57153d44, c=0x5710e7b8)  at 
ui/gtk.c:380
  380   g_object_unref(cursor);
  (gdb) p cursor
  $1 = (GdkCursor *) 0x570eb1e0
  (gdb) p *cursor
  $2 = {type = GDK_CURSOR_IS_PIXMAP, ref_count = 3}

  (gdb) frame 2
  #2  0x5673895b in dpy_cursor_define (con=0x570c07f8, 
  cursor=cursor@entry=0x5710e7b8) at ui/console.c:1547
  1547  dcl-ops-dpy_cursor_define(dcl, cursor);
  (gdb) p *cursor
  $3 = {width = 64, height = 64, hot_x = 0, hot_y = 0, refcount = 1, 
data = 0x5710e7cc}
  (gdb) p *cursor-data
  $4 = 0
  (gdb) l
  1542  QLIST_FOREACH(dcl, s-listeners, next) {
  1543  if (con != (dcl-con ? dcl-con : active_console)) {
  1544  continue;
  1545  }
  1546  if (dcl-ops-dpy_cursor_define) {
  1547  dcl-ops-dpy_cursor_define(dcl, cursor);
  1548  }
  1549  }
  1550  }
  1551  
  (gdb)

To manage notifications about this bug go to:
https://bugs.launchpad.net/qemu/+bug/1187121/+subscriptions



[Qemu-devel] [PATCH v4 0/3] bugs fix for hpet

2013-09-02 Thread Liu Ping Fan
note: I rebase it onto Stefan's net-next tree, since pc-1.7 has already been 
defined there.

v4:
  use standard compat property to set hpet's interrupt compatibility

v3:
  change hpet interrupt capablity on board's demand


Liu Ping Fan (3):
  hpet: inverse polarity when pin above ISA_NUM_IRQS
  hpet: entitle more irq pins for hpet
  pc-1.6: add compatibility for hpet intcap on pc-*-1.6

 hw/timer/hpet.c  | 27 +++
 include/hw/i386/pc.h |  5 +
 2 files changed, 28 insertions(+), 4 deletions(-)

-- 
1.8.1.4




[Qemu-devel] [PATCH v4 1/3] hpet: inverse polarity when pin above ISA_NUM_IRQS

2013-09-02 Thread Liu Ping Fan
According to hpet spec, hpet irq is high active. But according to
ICH spec, there is inversion before the input of ioapic. So the OS
will expect low active on this IRQ line.(And this is observed on
bare metal).

We fold the emulation of this inversion inside the hpet logic.

Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com
---
 hw/timer/hpet.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index 648b383..1139448 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -198,13 +198,23 @@ static void update_irq(struct HPETTimer *timer, int set)
 if (!set || !timer_enabled(timer) || !hpet_enabled(timer-state)) {
 s-isr = ~mask;
 if (!timer_fsb_route(timer)) {
-qemu_irq_lower(s-irqs[route]);
+/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
+if (route = ISA_NUM_IRQS) {
+qemu_irq_raise(s-irqs[route]);
+} else {
+qemu_irq_lower(s-irqs[route]);
+}
 }
 } else if (timer_fsb_route(timer)) {
 stl_le_phys(timer-fsb  32, timer-fsb  0x);
 } else if (timer-config  HPET_TN_TYPE_LEVEL) {
 s-isr |= mask;
-qemu_irq_raise(s-irqs[route]);
+/* fold the ICH PIRQ# pin's internal inversion logic into hpet */
+if (route = ISA_NUM_IRQS) {
+qemu_irq_lower(s-irqs[route]);
+} else {
+qemu_irq_raise(s-irqs[route]);
+}
 } else {
 s-isr = ~mask;
 qemu_irq_pulse(s-irqs[route]);
-- 
1.8.1.4




[Qemu-devel] [PATCH v4 2/3] hpet: entitle more irq pins for hpet

2013-09-02 Thread Liu Ping Fan
On PC, IRQ2/8 can be reserved for hpet timer 0/1. And pin 16~23
of ioapic can be dynamically assigned to hpet as guest chooses.
(Will enable them after introducing pc 1.6 compat)

Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com
---
 hw/timer/hpet.c | 13 +++--
 1 file changed, 11 insertions(+), 2 deletions(-)

diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index 1139448..888be66 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -25,6 +25,7 @@
  */
 
 #include hw/hw.h
+#include hw/boards.h
 #include hw/i386/pc.h
 #include ui/console.h
 #include qemu/timer.h
@@ -42,6 +43,12 @@
 
 #define HPET_MSI_SUPPORT0
 
+/* For bug compat, using only IRQ2. Soon it will be fixed as
+ * 0xff0104ULL, i.e using IRQ16~23, IRQ8 and IRQ2 after
+ * introducing pc-1.6 compat.
+ */
+#define HPET_TN_INT_CAP_DEFAULT 0x4ULL
+
 #define TYPE_HPET hpet
 #define HPET(obj) OBJECT_CHECK(HPETState, (obj), TYPE_HPET)
 
@@ -73,6 +80,7 @@ typedef struct HPETState {
 uint8_t rtc_irq_level;
 qemu_irq pit_enabled;
 uint8_t num_timers;
+uint32_t intcap;
 HPETTimer timer[HPET_MAX_TIMERS];
 
 /* Memory-mapped, software visible registers */
@@ -663,8 +671,8 @@ static void hpet_reset(DeviceState *d)
 if (s-flags  (1  HPET_MSI_SUPPORT)) {
 timer-config |= HPET_TN_FSB_CAP;
 }
-/* advertise availability of ioapic inti2 */
-timer-config |=  0x0004ULL  32;
+/* advertise availability of ioapic int */
+timer-config |=  (uint64_t)s-intcap  32;
 timer-period = 0ULL;
 timer-wrap_flag = 0;
 }
@@ -753,6 +761,7 @@ static void hpet_realize(DeviceState *dev, Error **errp)
 static Property hpet_device_properties[] = {
 DEFINE_PROP_UINT8(timers, HPETState, num_timers, HPET_MIN_TIMERS),
 DEFINE_PROP_BIT(msi, HPETState, flags, HPET_MSI_SUPPORT, false),
+DEFINE_PROP_UINT32(intcap, HPETState, intcap, HPET_TN_INT_CAP_DEFAULT),
 DEFINE_PROP_END_OF_LIST(),
 };
 
-- 
1.8.1.4




[Qemu-devel] [PATCH v4 3/3] pc-1.6: add compatibility for hpet intcap on pc-*-1.6

2013-09-02 Thread Liu Ping Fan
For guest bug compat, we limit hpet's interrupt compatibility on
ioapic's IRQ2 for pc-*-1.6. As to pc-*-1.7 and newer, IRQ2, IRQ8,
and IRQ16~23 are allowed.

Signed-off-by: Liu Ping Fan pingf...@linux.vnet.ibm.com
---
 hw/timer/hpet.c  | 6 +-
 include/hw/i386/pc.h | 4 
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/hw/timer/hpet.c b/hw/timer/hpet.c
index 888be66..b6e8c12 100644
--- a/hw/timer/hpet.c
+++ b/hw/timer/hpet.c
@@ -43,11 +43,7 @@
 
 #define HPET_MSI_SUPPORT0
 
-/* For bug compat, using only IRQ2. Soon it will be fixed as
- * 0xff0104ULL, i.e using IRQ16~23, IRQ8 and IRQ2 after
- * introducing pc-1.6 compat.
- */
-#define HPET_TN_INT_CAP_DEFAULT 0x4ULL
+#define HPET_TN_INT_CAP_DEFAULT 0xff0104ULL
 
 #define TYPE_HPET hpet
 #define HPET(obj) OBJECT_CHECK(HPETState, (obj), TYPE_HPET)
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 894c124..ef481bc 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -219,6 +219,10 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
 .driver   = e1000,\
 .property = mitigation,\
 .value= off,\
+},{\
+.driver   = hpet,\
+.property = intcap,\
+.value= stringify(4),\
 }
 
 #define PC_COMPAT_1_5 \
-- 
1.8.1.4




Re: [Qemu-devel] [PATCH v3 04/19] block: update bs-total_sectors on writes

2013-09-02 Thread Peter Lieven

On 17.08.2013 08:27, Paolo Bonzini wrote:

Il 02/08/2013 09:05, Peter Lieven ha scritto:

can you give an update what are to current plans/schedule to merge this
series? I have
a few patches in the queue that in their current version depend on this
series being merged.

It should go in soon, perhaps a couple of weeks.

That would be good. I would like to make the relevant changes to iscsi soon and
as I promised to convert everything in block/iscsi to coroutines this will be a 
lot.

Peter




[Qemu-devel] [PATCH v5 3/8] qcow2: Employ metadata overlap checks

2013-09-02 Thread Max Reitz
The pre-write overlap check function is now called before most of the
qcow2 writes (aborting it on collision or other error).

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2-cache.c| 17 +
 block/qcow2-cluster.c  | 21 +
 block/qcow2-snapshot.c | 22 ++
 block/qcow2.c  | 26 ++
 4 files changed, 86 insertions(+)

diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
index 2f3114e..7bcae09 100644
--- a/block/qcow2-cache.c
+++ b/block/qcow2-cache.c
@@ -115,6 +115,23 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, 
Qcow2Cache *c, int i)
 }
 
 if (c == s-refcount_block_cache) {
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_REFCOUNT_BLOCK,
+c-entries[i].offset, s-cluster_size);
+} else if (c == s-l2_table_cache) {
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_ACTIVE_L2,
+c-entries[i].offset, s-cluster_size);
+} else {
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+c-entries[i].offset, s-cluster_size);
+}
+
+if (ret  0) {
+return ret;
+}
+
+if (c == s-refcount_block_cache) {
 BLKDBG_EVENT(bs-file, BLKDBG_REFBLOCK_UPDATE_PART);
 } else if (c == s-l2_table_cache) {
 BLKDBG_EVENT(bs-file, BLKDBG_L2_UPDATE);
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index cca76d4..7c248aa 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -80,6 +80,14 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t 
min_size,
 goto fail;
 }
 
+/* the L1 position has not yet been updated, so these clusters must
+ * indeed be completely free */
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+new_l1_table_offset, new_l1_size2);
+if (ret  0) {
+goto fail;
+}
+
 BLKDBG_EVENT(bs-file, BLKDBG_L1_GROW_WRITE_TABLE);
 for(i = 0; i  s-l1_size; i++)
 new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
@@ -149,6 +157,13 @@ static int write_l1_entry(BlockDriverState *bs, int 
l1_index)
 buf[i] = cpu_to_be64(s-l1_table[l1_start_index + i]);
 }
 
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_ACTIVE_L1,
+s-l1_table_offset + 8 * l1_start_index, sizeof(buf));
+if (ret  0) {
+return ret;
+}
+
 BLKDBG_EVENT(bs-file, BLKDBG_L1_UPDATE);
 ret = bdrv_pwrite_sync(bs-file, s-l1_table_offset + 8 * l1_start_index,
 buf, sizeof(buf));
@@ -368,6 +383,12 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,
 s-aes_encrypt_key);
 }
 
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+cluster_offset + n_start * BDRV_SECTOR_SIZE, n * BDRV_SECTOR_SIZE);
+if (ret  0) {
+goto out;
+}
+
 BLKDBG_EVENT(bs-file, BLKDBG_COW_WRITE);
 ret = bdrv_co_writev(bs-file, (cluster_offset  9) + n_start, n, qiov);
 if (ret  0) {
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 0caac90..e7e6013 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -189,6 +189,15 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
 return ret;
 }
 
+/* The snapshot list position has not yet been updated, so these clusters
+ * must indeed be completely free */
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, offset,
+s-snapshots_size);
+if (ret  0) {
+return ret;
+}
+
+
 /* Write all snapshots to the new list */
 for(i = 0; i  s-nb_snapshots; i++) {
 sn = s-snapshots + i;
@@ -363,6 +372,12 @@ int qcow2_snapshot_create(BlockDriverState *bs, 
QEMUSnapshotInfo *sn_info)
 l1_table[i] = cpu_to_be64(s-l1_table[i]);
 }
 
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+sn-l1_table_offset, s-l1_size * sizeof(uint64_t));
+if (ret  0) {
+goto fail;
+}
+
 ret = bdrv_pwrite(bs-file, sn-l1_table_offset, l1_table,
   s-l1_size * sizeof(uint64_t));
 if (ret  0) {
@@ -475,6 +490,13 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char 
*snapshot_id)
 goto fail;
 }
 
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_ACTIVE_L1,
+s-l1_table_offset, cur_l1_bytes);
+if (ret  0) {
+goto fail;
+}
+
 ret = bdrv_pwrite_sync(bs-file, s-l1_table_offset, sn_l1_table,
cur_l1_bytes);
 if (ret  0) {
diff --git a/block/qcow2.c b/block/qcow2.c
index 16c9898..3a95ff1 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -624,6 +624,8 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, 
int flags)
 qcow2_free_snapshots(bs);
 

[Qemu-devel] [PATCH v5 1/8] qcow2: Add corrupt bit

2013-09-02 Thread Max Reitz
This adds an incompatible bit indicating corruption to qcow2. Any image
with this bit set may not be written to unless for repairing (and
subsequently clearing the bit if the repair has been successful).

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2.c  | 47 ++
 block/qcow2.h  |  7 ++-
 docs/specs/qcow2.txt   |  7 ++-
 tests/qemu-iotests/031.out | 12 ++--
 tests/qemu-iotests/036.out |  2 +-
 5 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 78097e5..16c9898 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -272,6 +272,37 @@ static int qcow2_mark_clean(BlockDriverState *bs)
 return 0;
 }
 
+/*
+ * Marks the image as corrupt.
+ */
+int qcow2_mark_corrupt(BlockDriverState *bs)
+{
+BDRVQcowState *s = bs-opaque;
+
+s-incompatible_features |= QCOW2_INCOMPAT_CORRUPT;
+return qcow2_update_header(bs);
+}
+
+/*
+ * Marks the image as consistent, i.e., unsets the corrupt bit, and flushes
+ * before if necessary.
+ */
+int qcow2_mark_consistent(BlockDriverState *bs)
+{
+BDRVQcowState *s = bs-opaque;
+
+if (s-incompatible_features  QCOW2_INCOMPAT_CORRUPT) {
+int ret = bdrv_flush(bs);
+if (ret  0) {
+return ret;
+}
+
+s-incompatible_features = ~QCOW2_INCOMPAT_CORRUPT;
+return qcow2_update_header(bs);
+}
+return 0;
+}
+
 static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix)
 {
@@ -402,6 +433,17 @@ static int qcow2_open(BlockDriverState *bs, QDict 
*options, int flags)
 goto fail;
 }
 
+if (s-incompatible_features  QCOW2_INCOMPAT_CORRUPT) {
+/* Corrupt images may not be written to unless they are being repaired
+ */
+if ((flags  BDRV_O_RDWR)  !(flags  BDRV_O_CHECK)) {
+error_report(qcow2: Image is corrupt; cannot be opened 
+read/write.);
+ret = -EACCES;
+goto fail;
+}
+}
+
 /* Check support for various header values */
 if (header.refcount_order != 4) {
 report_unsupported(bs, %d bit reference counts,
@@ -1130,6 +1172,11 @@ int qcow2_update_header(BlockDriverState *bs)
 .name = dirty bit,
 },
 {
+.type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
+.bit  = QCOW2_INCOMPAT_CORRUPT_BITNR,
+.name = corrupt bit,
+},
+{
 .type = QCOW2_FEAT_TYPE_COMPATIBLE,
 .bit  = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
 .name = lazy refcounts,
diff --git a/block/qcow2.h b/block/qcow2.h
index dba9771..4297487 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -119,9 +119,12 @@ enum {
 /* Incompatible feature bits */
 enum {
 QCOW2_INCOMPAT_DIRTY_BITNR   = 0,
+QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
 QCOW2_INCOMPAT_DIRTY = 1  QCOW2_INCOMPAT_DIRTY_BITNR,
+QCOW2_INCOMPAT_CORRUPT   = 1  QCOW2_INCOMPAT_CORRUPT_BITNR,
 
-QCOW2_INCOMPAT_MASK  = QCOW2_INCOMPAT_DIRTY,
+QCOW2_INCOMPAT_MASK  = QCOW2_INCOMPAT_DIRTY
+ | QCOW2_INCOMPAT_CORRUPT,
 };
 
 /* Compatible feature bits */
@@ -361,6 +364,8 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector 
*qiov,
   int64_t sector_num, int nb_sectors);
 
 int qcow2_mark_dirty(BlockDriverState *bs);
+int qcow2_mark_corrupt(BlockDriverState *bs);
+int qcow2_mark_consistent(BlockDriverState *bs);
 int qcow2_update_header(BlockDriverState *bs);
 
 /* qcow2-refcount.c functions */
diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
index 36a559d..33eca36 100644
--- a/docs/specs/qcow2.txt
+++ b/docs/specs/qcow2.txt
@@ -80,7 +80,12 @@ in the description of a field.
 tables to repair refcounts before accessing the
 image.
 
-Bits 1-63:  Reserved (set to 0)
+Bit 1:  Corrupt bit.  If this bit is set then any data
+structure may be corrupt and the image must not
+be written to (unless for regaining
+consistency).
+
+Bits 2-63:  Reserved (set to 0)
 
  80 -  87:  compatible_features
 Bitmask of compatible features. An implementation can
diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out
index 796c993..a943344 100644
--- a/tests/qemu-iotests/031.out
+++ b/tests/qemu-iotests/031.out
@@ -54,7 +54,7 @@ header_length 72
 
 Header extension:
 magic 0x6803f857
-length96
+length144
 data  binary
 
 Header extension:
@@ -68,7 +68,7 @@ No errors were found on the image.
 
 magic 0x514649fb
 version   2
-backing_file_offset   

[Qemu-devel] [PATCH v5 0/8] Add metadata overlap checks

2013-09-02 Thread Max Reitz
If a qcow2 image file becomes corrupted, any write may inadvertently
overwrite important metadata structures such as the L1 table. This
series adds functionality for detecting, preventing and (to some extent)
repairing such collisions.

v5:
 - fixed patch 6 (forgot to update the event_names array for the new
   event BLKDBG_REFTABLE_UPDATE); no other changes

v4:
 - fixed handling of preallocated zero clusters in patch 4
 - moved OFLAG_COPIED checks into a separate function (this affects
   patches 4 and 5); functionality remains unchanged
 - patches 1, 2, 3, 6, 7 and 8 remain unmodified (except for line
   numbers in block/qcow2-refcount.c)

v3:
 - split PATCH 4/5 into four distinct patches (4/8, 5/8, 6/8 and 7/8,
   respectively)
 - directly generate a JSON message when marking the image corrupt
 - other (minor) fixes according to Kevin's comments

v2:
 - Generally implemented Kevin's comments, especially:
- new QMP event QEVENT_BLOCK_IMAGE_CORRUPTED
- removed BDRV_O_REPAIR in favor of BDRV_O_CHECK | BDRV_O_RDWR
- always check full clusters for overlaps
 - removed qcow2_check_allocations in favor of some
   qcow2_check_refcounts extensions that will hopefully include all
   that functionality

Max Reitz (8):
  qcow2: Add corrupt bit
  qcow2: Metadata overlap checks
  qcow2: Employ metadata overlap checks
  qcow2-refcount: Move OFLAG_COPIED checks
  qcow2-refcount: Repair OFLAG_COPIED errors
  qcow2-refcount: Repair shared refcount blocks
  qcow2_check: Mark image consistent
  qemu-iotests: Overlapping cluster allocations

 block/blkdebug.c   |   1 +
 block/qcow2-cache.c|  17 ++
 block/qcow2-cluster.c  |  25 ++-
 block/qcow2-refcount.c | 481 +
 block/qcow2-snapshot.c |  22 +++
 block/qcow2.c  |  79 +++-
 block/qcow2.h  |  47 -
 docs/specs/qcow2.txt   |   7 +-
 include/block/block.h  |   1 +
 include/monitor/monitor.h  |   1 +
 monitor.c  |   1 +
 tests/qemu-iotests/031.out |  12 +-
 tests/qemu-iotests/036.out |   2 +-
 tests/qemu-iotests/060 | 111 +++
 tests/qemu-iotests/060.out |  44 +
 tests/qemu-iotests/group   |   1 +
 16 files changed, 805 insertions(+), 47 deletions(-)
 create mode 100755 tests/qemu-iotests/060
 create mode 100644 tests/qemu-iotests/060.out

-- 
1.8.3.1




[Qemu-devel] [PATCH v5 2/8] qcow2: Metadata overlap checks

2013-09-02 Thread Max Reitz
Two new functions are added; the first one checks a given range in the
image file for overlaps with metadata (main header, L1 tables, L2
tables, refcount table and blocks).

The second one should be used immediately before writing to the image
file as it calls the first function and, upon collision, marks the
image as corrupt and makes the BDS unusable, thereby preventing
further access.

Both functions take a bitmask argument specifying the structures which
should be checked for overlaps, making it possible to also check
metadata writes against colliding with other structures.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2-refcount.c| 172 ++
 block/qcow2.h |  39 +++
 include/monitor/monitor.h |   1 +
 monitor.c |   1 +
 4 files changed, 213 insertions(+)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 1244693..310efcc 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -25,6 +25,8 @@
 #include qemu-common.h
 #include block/block_int.h
 #include block/qcow2.h
+#include qemu/range.h
+#include qapi/qmp/types.h
 
 static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size);
 static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
@@ -1372,3 +1374,173 @@ fail:
 return ret;
 }
 
+#define overlaps_with(ofs, sz) \
+ranges_overlap(offset, size, ofs, sz)
+
+/*
+ * Checks if the given offset into the image file is actually free to use by
+ * looking for overlaps with important metadata sections (L1/L2 tables etc.),
+ * i.e. a sanity check without relying on the refcount tables.
+ *
+ * The chk parameter specifies exactly what checks to perform (being a bitmask
+ * of QCow2MetadataOverlap values).
+ *
+ * Returns:
+ * - 0 if writing to this offset will not affect the mentioned metadata
+ * - a positive QCow2MetadataOverlap value indicating one overlapping section
+ * - a negative value (-errno) indicating an error while performing a check,
+ *   e.g. when bdrv_read failed on QCOW2_OL_INACTIVE_L2
+ */
+int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,
+ int64_t size)
+{
+BDRVQcowState *s = bs-opaque;
+int i, j;
+
+if (!size) {
+return 0;
+}
+
+if (chk  QCOW2_OL_MAIN_HEADER) {
+if (offset  s-cluster_size) {
+return QCOW2_OL_MAIN_HEADER;
+}
+}
+
+/* align range to test to cluster boundaries */
+size = align_offset(offset_into_cluster(s, offset) + size, 
s-cluster_size);
+offset = start_of_cluster(s, offset);
+
+if ((chk  QCOW2_OL_ACTIVE_L1)  s-l1_size) {
+if (overlaps_with(s-l1_table_offset, s-l1_size * sizeof(uint64_t))) {
+return QCOW2_OL_ACTIVE_L1;
+}
+}
+
+if ((chk  QCOW2_OL_REFCOUNT_TABLE)  s-refcount_table_size) {
+if (overlaps_with(s-refcount_table_offset,
+s-refcount_table_size * sizeof(uint64_t))) {
+return QCOW2_OL_REFCOUNT_TABLE;
+}
+}
+
+if ((chk  QCOW2_OL_SNAPSHOT_TABLE)  s-snapshots_size) {
+if (overlaps_with(s-snapshots_offset, s-snapshots_size)) {
+return QCOW2_OL_SNAPSHOT_TABLE;
+}
+}
+
+if ((chk  QCOW2_OL_INACTIVE_L1)  s-snapshots) {
+for (i = 0; i  s-nb_snapshots; i++) {
+if (s-snapshots[i].l1_size 
+overlaps_with(s-snapshots[i].l1_table_offset,
+s-snapshots[i].l1_size * sizeof(uint64_t))) {
+return QCOW2_OL_INACTIVE_L1;
+}
+}
+}
+
+if ((chk  QCOW2_OL_ACTIVE_L2)  s-l1_table) {
+for (i = 0; i  s-l1_size; i++) {
+if ((s-l1_table[i]  L1E_OFFSET_MASK) 
+overlaps_with(s-l1_table[i]  L1E_OFFSET_MASK,
+s-cluster_size)) {
+return QCOW2_OL_ACTIVE_L2;
+}
+}
+}
+
+if ((chk  QCOW2_OL_REFCOUNT_BLOCK)  s-refcount_table) {
+for (i = 0; i  s-refcount_table_size; i++) {
+if ((s-refcount_table[i]  REFT_OFFSET_MASK) 
+overlaps_with(s-refcount_table[i]  REFT_OFFSET_MASK,
+s-cluster_size)) {
+return QCOW2_OL_REFCOUNT_BLOCK;
+}
+}
+}
+
+if ((chk  QCOW2_OL_INACTIVE_L2)  s-snapshots) {
+for (i = 0; i  s-nb_snapshots; i++) {
+uint64_t l1_ofs = s-snapshots[i].l1_table_offset;
+uint32_t l1_sz  = s-snapshots[i].l1_size;
+uint64_t *l1 = g_malloc(l1_sz * sizeof(uint64_t));
+int ret;
+
+ret = bdrv_read(bs-file, l1_ofs / BDRV_SECTOR_SIZE, (uint8_t *)l1,
+l1_sz * sizeof(uint64_t) / BDRV_SECTOR_SIZE);
+
+if (ret  0) {
+g_free(l1);
+return ret;
+}
+
+for (j = 0; j  l1_sz; j++) {
+if ((l1[j]  L1E_OFFSET_MASK) 
+overlaps_with(l1[j]  

[Qemu-devel] [PATCH v5 5/8] qcow2-refcount: Repair OFLAG_COPIED errors

2013-09-02 Thread Max Reitz
Since the OFLAG_COPIED checks are now executed after the refcounts have
been repaired (if repairing), it is safe to assume that they are correct
but the OFLAG_COPIED flag may be not. Therefore, if its value differs
from what it should be (considering the according refcount), that
discrepancy can be repaired by correctly setting (or clearing that flag.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2-cluster.c  |  4 ++--
 block/qcow2-refcount.c | 58 --
 block/qcow2.h  |  1 +
 3 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 7c248aa..2d5aa92 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -145,7 +145,7 @@ static int l2_load(BlockDriverState *bs, uint64_t l2_offset,
  * and we really don't want bdrv_pread to perform a read-modify-write)
  */
 #define L1_ENTRIES_PER_SECTOR (512 / 8)
-static int write_l1_entry(BlockDriverState *bs, int l1_index)
+int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
 {
 BDRVQcowState *s = bs-opaque;
 uint64_t buf[L1_ENTRIES_PER_SECTOR];
@@ -254,7 +254,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, 
uint64_t **table)
 /* update the L1 entry */
 trace_qcow2_l2_allocate_write_l1(bs, l1_index);
 s-l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
-ret = write_l1_entry(bs, l1_index);
+ret = qcow2_write_l1_entry(bs, l1_index);
 if (ret  0) {
 goto fail;
 }
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index ddc3029..92ecc64 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1207,7 +1207,8 @@ fail:
  * been already detected and sufficiently signaled by the calling function
  * (qcow2_check_refcounts) by the time this function is called).
  */
-static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res)
+static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
+  BdrvCheckMode fix)
 {
 BDRVQcowState *s = bs-opaque;
 uint64_t *l2_table = qemu_blockalign(bs, s-cluster_size);
@@ -1218,6 +1219,7 @@ static int check_oflag_copied(BlockDriverState *bs, 
BdrvCheckResult *res)
 for (i = 0; i  s-l1_size; i++) {
 uint64_t l1_entry = s-l1_table[i];
 uint64_t l2_offset = l1_entry  L1E_OFFSET_MASK;
+bool l2_dirty = false;
 
 if (!l2_offset) {
 continue;
@@ -1229,10 +1231,24 @@ static int check_oflag_copied(BlockDriverState *bs, 
BdrvCheckResult *res)
 continue;
 }
 if ((refcount == 1) != ((l1_entry  QCOW_OFLAG_COPIED) != 0)) {
-fprintf(stderr, ERROR OFLAG_COPIED L2 cluster: l1_index=%d 
+fprintf(stderr, %s OFLAG_COPIED L2 cluster: l1_index=%d 
 l1_entry=% PRIx64  refcount=%d\n,
+fix  BDRV_FIX_ERRORS ? Repairing :
+ERROR,
 i, l1_entry, refcount);
-res-corruptions++;
+if (fix  BDRV_FIX_ERRORS) {
+s-l1_table[i] = refcount == 1
+   ? l1_entry |  QCOW_OFLAG_COPIED
+   : l1_entry  ~QCOW_OFLAG_COPIED;
+ret = qcow2_write_l1_entry(bs, i);
+if (ret  0) {
+res-check_errors++;
+goto fail;
+}
+res-corruptions_fixed++;
+} else {
+res-corruptions++;
+}
 }
 
 ret = bdrv_pread(bs-file, l2_offset, l2_table,
@@ -1257,13 +1273,43 @@ static int check_oflag_copied(BlockDriverState *bs, 
BdrvCheckResult *res)
 continue;
 }
 if ((refcount == 1) != ((l2_entry  QCOW_OFLAG_COPIED) != 0)) {
-fprintf(stderr, ERROR OFLAG_COPIED data cluster: 
+fprintf(stderr, %s OFLAG_COPIED data cluster: 
 l2_entry=% PRIx64  refcount=%d\n,
+fix  BDRV_FIX_ERRORS ? Repairing :
+ERROR,
 l2_entry, refcount);
-res-corruptions++;
+if (fix  BDRV_FIX_ERRORS) {
+l2_table[j] = cpu_to_be64(refcount == 1
+? l2_entry |  QCOW_OFLAG_COPIED
+: l2_entry  ~QCOW_OFLAG_COPIED);
+l2_dirty = true;
+res-corruptions_fixed++;
+} else {
+res-corruptions++;
+}
 }
 }
 }
+
+if (l2_dirty) {
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_ACTIVE_L2, l2_offset,
+s-cluster_size);
+if (ret  0) {
+

[Qemu-devel] [PATCH v5 4/8] qcow2-refcount: Move OFLAG_COPIED checks

2013-09-02 Thread Max Reitz
Move the OFLAG_COPIED checks out of check_refcounts_l1 and
check_refcounts_l2 and after the actual refcount checks/fixes (since the
refcounts might actually change there).

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2-refcount.c | 115 +++--
 1 file changed, 82 insertions(+), 33 deletions(-)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 310efcc..ddc3029 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1035,7 +1035,7 @@ static int check_refcounts_l2(BlockDriverState *bs, 
BdrvCheckResult *res,
 BDRVQcowState *s = bs-opaque;
 uint64_t *l2_table, l2_entry;
 uint64_t next_contiguous_offset = 0;
-int i, l2_size, nb_csectors, refcount;
+int i, l2_size, nb_csectors;
 
 /* Read L2 table from disk */
 l2_size = s-l2_size * sizeof(uint64_t);
@@ -1087,23 +1087,8 @@ static int check_refcounts_l2(BlockDriverState *bs, 
BdrvCheckResult *res,
 
 case QCOW2_CLUSTER_NORMAL:
 {
-/* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
 uint64_t offset = l2_entry  L2E_OFFSET_MASK;
 
-if (flags  CHECK_OFLAG_COPIED) {
-refcount = get_refcount(bs, offset  s-cluster_bits);
-if (refcount  0) {
-fprintf(stderr, Can't get refcount for offset %
-PRIx64 : %s\n, l2_entry, strerror(-refcount));
-goto fail;
-}
-if ((refcount == 1) != ((l2_entry  QCOW_OFLAG_COPIED) != 0)) {
-fprintf(stderr, ERROR OFLAG_COPIED: offset=%
-PRIx64  refcount=%d\n, l2_entry, refcount);
-res-corruptions++;
-}
-}
-
 if (flags  CHECK_FRAG_INFO) {
 res-bfi.allocated_clusters++;
 if (next_contiguous_offset 
@@ -1160,7 +1145,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
 {
 BDRVQcowState *s = bs-opaque;
 uint64_t *l1_table, l2_offset, l1_size2;
-int i, refcount, ret;
+int i, ret;
 
 l1_size2 = l1_size * sizeof(uint64_t);
 
@@ -1184,22 +1169,6 @@ static int check_refcounts_l1(BlockDriverState *bs,
 for(i = 0; i  l1_size; i++) {
 l2_offset = l1_table[i];
 if (l2_offset) {
-/* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
-if (flags  CHECK_OFLAG_COPIED) {
-refcount = get_refcount(bs, (l2_offset  ~QCOW_OFLAG_COPIED)
- s-cluster_bits);
-if (refcount  0) {
-fprintf(stderr, Can't get refcount for l2_offset %
-PRIx64 : %s\n, l2_offset, strerror(-refcount));
-goto fail;
-}
-if ((refcount == 1) != ((l2_offset  QCOW_OFLAG_COPIED) != 0)) 
{
-fprintf(stderr, ERROR OFLAG_COPIED: l2_offset=% PRIx64
- refcount=%d\n, l2_offset, refcount);
-res-corruptions++;
-}
-}
-
 /* Mark L2 table as used */
 l2_offset = L1E_OFFSET_MASK;
 inc_refcounts(bs, res, refcount_table, refcount_table_size,
@@ -1231,6 +1200,80 @@ fail:
 }
 
 /*
+ * Checks the OFLAG_COPIED flag for all L1 and L2 entries.
+ *
+ * This function does not print an error message nor does it increment
+ * check_errors if get_refcount fails (this is because such an error will have
+ * been already detected and sufficiently signaled by the calling function
+ * (qcow2_check_refcounts) by the time this function is called).
+ */
+static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res)
+{
+BDRVQcowState *s = bs-opaque;
+uint64_t *l2_table = qemu_blockalign(bs, s-cluster_size);
+int ret;
+int refcount;
+int i, j;
+
+for (i = 0; i  s-l1_size; i++) {
+uint64_t l1_entry = s-l1_table[i];
+uint64_t l2_offset = l1_entry  L1E_OFFSET_MASK;
+
+if (!l2_offset) {
+continue;
+}
+
+refcount = get_refcount(bs, l2_offset  s-cluster_bits);
+if (refcount  0) {
+/* don't print message nor increment check_errors */
+continue;
+}
+if ((refcount == 1) != ((l1_entry  QCOW_OFLAG_COPIED) != 0)) {
+fprintf(stderr, ERROR OFLAG_COPIED L2 cluster: l1_index=%d 
+l1_entry=% PRIx64  refcount=%d\n,
+i, l1_entry, refcount);
+res-corruptions++;
+}
+
+ret = bdrv_pread(bs-file, l2_offset, l2_table,
+ s-l2_size * sizeof(uint64_t));
+if (ret  0) {
+fprintf(stderr, ERROR: Could not read L2 table: %s\n,
+strerror(-ret));
+res-check_errors++;
+goto fail;
+}
+
+for (j = 0; j  s-l2_size; j++) {
+uint64_t l2_entry = be64_to_cpu(l2_table[j]);
+uint64_t 

[Qemu-devel] [PATCH v5 8/8] qemu-iotests: Overlapping cluster allocations

2013-09-02 Thread Max Reitz
A new test on corrupted images with overlapping cluster allocations.

Signed-off-by: Max Reitz mre...@redhat.com
---
 tests/qemu-iotests/060 | 111 +
 tests/qemu-iotests/060.out |  44 ++
 tests/qemu-iotests/group   |   1 +
 3 files changed, 156 insertions(+)
 create mode 100755 tests/qemu-iotests/060
 create mode 100644 tests/qemu-iotests/060.out

diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
new file mode 100755
index 000..65bb09f
--- /dev/null
+++ b/tests/qemu-iotests/060
@@ -0,0 +1,111 @@
+#!/bin/bash
+#
+# Test case for image corruption (overlapping data structures) in qcow2
+#
+# Copyright (C) 2013 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/.
+#
+
+# creator
+owner=mre...@redhat.com
+
+seq=`basename $0`
+echo QA output created by $seq
+
+here=`pwd`
+tmp=/tmp/$$
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap _cleanup; exit \$status 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+rt_offset=65536  # 0x1 (XXX: just an assumption)
+rb_offset=131072 # 0x2 (XXX: just an assumption)
+l1_offset=196608 # 0x3 (XXX: just an assumption)
+l2_offset=262144 # 0x4 (XXX: just an assumption)
+
+IMGOPTS=compat=1.1
+
+echo
+echo === Testing L2 reference into L1 ===
+echo
+_make_test_img 64M
+# Link first L1 entry (first L2 table) onto itself
+# (Note the MSb in the L1 entry is set, ensuring the refcount is one - else any
+# later write will result in a COW operation, effectively ruining this attempt
+# on image corruption)
+poke_file $TEST_IMG $l1_offset \x80\x00\x00\x00\x00\x03\x00\x00
+_check_test_img
+
+# The corrupt bit should not be set anyway
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# Try to write something, thereby forcing the corrupt bit to be set
+$QEMU_IO -c write -P 0x2a 0 512 $TEST_IMG | _filter_qemu_io
+
+# The corrupt bit must now be set
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# Try to open the image R/W (which should fail)
+$QEMU_IO -c read 0 512 $TEST_IMG 21 | _filter_qemu_io | sed -e s/can't 
open device .*$/can't open device/
+
+# Try to open it RO (which should succeed)
+$QEMU_IO -c read 0 512 -r $TEST_IMG | _filter_qemu_io
+
+# We could now try to fix the image, but this would probably fail (how should 
an
+# L2 table linked onto the L1 table be fixed?)
+
+echo
+echo === Testing cluster data reference into refcount block ===
+echo
+_make_test_img 64M
+# Allocate L2 table
+truncate -s $(($l2_offset+65536)) $TEST_IMG
+poke_file $TEST_IMG $l1_offset \x80\x00\x00\x00\x00\x04\x00\x00
+# Mark cluster as used
+poke_file $TEST_IMG $(($rb_offset+8)) \x00\x01
+# Redirect new data cluster onto refcount block
+poke_file $TEST_IMG $l2_offset \x80\x00\x00\x00\x00\x02\x00\x00
+_check_test_img
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+$QEMU_IO -c write -P 0x2a 0 512 $TEST_IMG | _filter_qemu_io
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# Try to fix it
+_check_test_img -r all
+
+# The corrupt bit should be cleared
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# Look if it's really really fixed
+$QEMU_IO -c write -P 0x2a 0 512 $TEST_IMG | _filter_qemu_io
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# success, all done
+echo *** done
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
new file mode 100644
index 000..ca4583a
--- /dev/null
+++ b/tests/qemu-iotests/060.out
@@ -0,0 +1,44 @@
+QA output created by 060
+
+=== Testing L2 reference into L1 ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
+ERROR cluster 3 refcount=1 reference=3
+
+1 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+incompatible_features 0x0
+qcow2: Preventing invalid write on metadata (overlaps with active L1 table); 
image marked as corrupt.
+write failed: Input/output error
+incompatible_features 0x2
+qcow2: Image is corrupt; cannot be opened read/write.
+qemu-io: can't open device
+no file open, try 'help open'
+read 512/512 bytes at offset 0
+512 bytes, X ops; 

[Qemu-devel] [PATCH v5 7/8] qcow2_check: Mark image consistent

2013-09-02 Thread Max Reitz
If no corruptions remain after an image repair (and no errors have been
encountered), clear the corrupt flag in qcow2_check.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 3a95ff1..aeb2ebb 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -312,7 +312,11 @@ static int qcow2_check(BlockDriverState *bs, 
BdrvCheckResult *result,
 }
 
 if (fix  result-check_errors == 0  result-corruptions == 0) {
-return qcow2_mark_clean(bs);
+ret = qcow2_mark_clean(bs);
+if (ret  0) {
+return ret;
+}
+return qcow2_mark_consistent(bs);
 }
 return ret;
 }
-- 
1.8.3.1




[Qemu-devel] [PATCH v5 6/8] qcow2-refcount: Repair shared refcount blocks

2013-09-02 Thread Max Reitz
If the refcount of a refcount block is greater than one, we can at least
try to repair that problem by duplicating the affected block.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/blkdebug.c   |   1 +
 block/qcow2-refcount.c | 148 -
 include/block/block.h  |   1 +
 3 files changed, 148 insertions(+), 2 deletions(-)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index ccb627a..5d33e03 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -168,6 +168,7 @@ static const char *event_names[BLKDBG_EVENT_MAX] = {
 
 [BLKDBG_REFTABLE_LOAD]  = reftable_load,
 [BLKDBG_REFTABLE_GROW]  = reftable_grow,
+[BLKDBG_REFTABLE_UPDATE]= reftable_update,
 
 [BLKDBG_REFBLOCK_LOAD]  = refblock_load,
 [BLKDBG_REFBLOCK_UPDATE]= refblock_update,
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 92ecc64..927bdeb 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1320,6 +1320,121 @@ fail:
 }
 
 /*
+ * Writes one sector of the refcount table to the disk
+ */
+#define RT_ENTRIES_PER_SECTOR (512 / sizeof(uint64_t))
+static int write_reftable_entry(BlockDriverState *bs, int rt_index)
+{
+BDRVQcowState *s = bs-opaque;
+uint64_t buf[RT_ENTRIES_PER_SECTOR];
+int rt_start_index;
+int i, ret;
+
+rt_start_index = rt_index  ~(RT_ENTRIES_PER_SECTOR - 1);
+for (i = 0; i  RT_ENTRIES_PER_SECTOR; i++) {
+buf[i] = cpu_to_be64(s-refcount_table[rt_start_index + i]);
+}
+
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_REFCOUNT_TABLE,
+s-refcount_table_offset + rt_start_index * sizeof(uint64_t),
+sizeof(buf));
+if (ret  0) {
+return ret;
+}
+
+BLKDBG_EVENT(bs-file, BLKDBG_REFTABLE_UPDATE);
+ret = bdrv_pwrite_sync(bs-file, s-refcount_table_offset +
+rt_start_index * sizeof(uint64_t), buf, sizeof(buf));
+if (ret  0) {
+return ret;
+}
+
+return 0;
+}
+
+/*
+ * Allocates a new cluster for the given refcount block (represented by its
+ * offset in the image file) and copies the current content there. This 
function
+ * does _not_ decrement the reference count for the currently occupied cluster.
+ *
+ * This function prints an informative message to stderr on error (and returns
+ * -errno); on success, 0 is returned.
+ */
+static int64_t realloc_refcount_block(BlockDriverState *bs, int reftable_index,
+  uint64_t offset)
+{
+BDRVQcowState *s = bs-opaque;
+int64_t new_offset = 0;
+void *refcount_block = NULL;
+int ret;
+
+/* allocate new refcount block */
+new_offset = qcow2_alloc_clusters(bs, s-cluster_size);
+if (new_offset  0) {
+fprintf(stderr, Could not allocate new cluster: %s\n,
+strerror(-new_offset));
+ret = new_offset;
+goto fail;
+}
+
+/* fetch current refcount block content */
+ret = qcow2_cache_get(bs, s-refcount_block_cache, offset, 
refcount_block);
+if (ret  0) {
+fprintf(stderr, Could not fetch refcount block: %s\n, 
strerror(-ret));
+goto fail;
+}
+
+/* new block has not yet been entered into refcount table, therefore it is
+ * no refcount block yet (regarding this check) */
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, new_offset,
+s-cluster_size);
+if (ret  0) {
+fprintf(stderr, Could not write refcount block; metadata overlap 
+check failed: %s\n, strerror(-ret));
+/* the image will be marked corrupt, so don't even attempt on freeing
+ * the cluster */
+new_offset = 0;
+goto fail;
+}
+
+/* write to new block */
+ret = bdrv_write(bs-file, new_offset / BDRV_SECTOR_SIZE, refcount_block,
+s-cluster_sectors);
+if (ret  0) {
+fprintf(stderr, Could not write refcount block: %s\n, 
strerror(-ret));
+goto fail;
+}
+
+/* update refcount table */
+assert(!(new_offset  (s-cluster_size - 1)));
+s-refcount_table[reftable_index] = new_offset;
+ret = write_reftable_entry(bs, reftable_index);
+if (ret  0) {
+fprintf(stderr, Could not update refcount table: %s\n,
+strerror(-ret));
+goto fail;
+}
+
+fail:
+if (new_offset  (ret  0)) {
+qcow2_free_clusters(bs, new_offset, s-cluster_size,
+QCOW2_DISCARD_ALWAYS);
+}
+if (refcount_block) {
+if (ret  0) {
+qcow2_cache_put(bs, s-refcount_block_cache, refcount_block);
+} else {
+ret = qcow2_cache_put(bs, s-refcount_block_cache, 
refcount_block);
+}
+}
+if (ret  0) {
+return ret;
+}
+return new_offset;
+}
+
+/*
  * Checks an image for refcount consistency.
  *
  * Returns 0 if no errors are found, the number of errors in case 

Re: [Qemu-devel] [PATCH v3 2/3] qcow2: Implement bdrv_amend_options

2013-09-02 Thread Max Reitz

Am 02.09.2013 05:43, schrieb Fam Zheng:

On Fri, 08/30 12:27, Max Reitz wrote:

Implement bdrv_amend_options for compat, size, backing_file, backing_fmt
and lazy_refcounts.

Downgrading images from compat=1.1 to compat=0.10 is achieved through
handling all incompatible flags accordingly, clearing all compatible and
autoclear flags and expanding all zero clusters.

Signed-off-by: Max Reitz mre...@redhat.com
---
  block/qcow2-cluster.c | 165 ++
  block/qcow2.c | 194 +-
  block/qcow2.h |   3 +
  3 files changed, 361 insertions(+), 1 deletion(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index cca76d4..e0ca104 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1476,3 +1476,168 @@ fail:
  
  return ret;

  }
+
+/*
+ * Expands all zero clusters in a specific L1 table (or deallocates them, for
+ * non-backed non-pre-allocated zero clusters).
+ */
+static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
+  int l1_size)
+{
+BDRVQcowState *s = bs-opaque;
+bool is_active_l1 = (l1_table == s-l1_table);
+uint64_t *l2_table;
+int ret;
+int i, j;
+
+if (!is_active_l1) {
+/* inactive L2 tables require a buffer to be stored in when loading
+ * them from disk */
+l2_table = qemu_blockalign(bs, s-cluster_size);
+}
+
+for (i = 0; i  l1_size; i++) {
+uint64_t l2_offset = l1_table[i]  L1E_OFFSET_MASK;
+bool l2_dirty = false;
+
+if (!l2_offset) {
+/* unallocated */
+continue;
+}
+
+if (is_active_l1) {
+/* get active L2 tables from cache */
+ret = qcow2_cache_get(bs, s-l2_table_cache, l2_offset,
+(void **)l2_table);
+} else {
+/* load inactive L2 tables from disk */
+ret = bdrv_read(bs-file, l2_offset / BDRV_SECTOR_SIZE,
+(void *)l2_table, s-cluster_sectors);
+}
+if (ret  0) {
+goto fail;
+}
+
+for (j = 0; j  s-l2_size; j++) {
+uint64_t l2_entry = be64_to_cpu(l2_table[j]);
+int64_t offset;
+
+if (qcow2_get_cluster_type(l2_entry) != QCOW2_CLUSTER_ZERO) {
+continue;
+}
+
+offset = l2_entry  L2E_OFFSET_MASK;
+if (!offset) {
+/* not preallocated */
+if (!bs-backing_hd) {
+/* not backed; therefore we can simply deallocate the
+ * cluster */
+l2_table[j] = 0;
+l2_dirty = true;
+continue;
+}
+
+offset = qcow2_alloc_clusters(bs, s-cluster_size);
+if (offset  0) {
+ret = offset;
+goto fail;
+}
+}
+
+ret = bdrv_write_zeroes(bs-file, offset / BDRV_SECTOR_SIZE,
+s-cluster_sectors);
+if (ret  0) {
+qcow2_free_clusters(bs, offset, s-cluster_size,
+QCOW2_DISCARD_ALWAYS);
+goto fail;
+}
+
+l2_table[j] = cpu_to_be64(offset | QCOW_OFLAG_COPIED);
+l2_dirty = true;
+}
+
+if (is_active_l1) {
+if (l2_dirty) {
+qcow2_cache_entry_mark_dirty(s-l2_table_cache, l2_table);
+qcow2_cache_depends_on_flush(s-l2_table_cache);
+}
+ret = qcow2_cache_put(bs, s-l2_table_cache, (void **)l2_table);
+if (ret  0) {
+l2_table = NULL;
+goto fail;
+}
+} else {
+if (l2_dirty) {
+ret = bdrv_write(bs-file, l2_offset / BDRV_SECTOR_SIZE,
+(void *)l2_table, s-cluster_sectors);
+if (ret  0) {
+goto fail;
+}
+}
+}
+}
+
+ret = 0;
+
+fail:
+if (l2_table) {
+if (!is_active_l1) {
+qemu_vfree(l2_table);
+} else {
+if (ret  0) {
+qcow2_cache_put(bs, s-l2_table_cache, (void **)l2_table);
+} else {
+ret = qcow2_cache_put(bs, s-l2_table_cache,
+(void **)l2_table);
+}
+}
+}
+return ret;
+}
+
+/*
+ * For backed images, expands all zero clusters on the image. For non-backed
+ * images, deallocates all non-pre-allocated zero clusters (and claims the
+ * allocation for pre-allocated ones). This is important for downgrading to a
+ * qcow2 version which doesn't yet support metadata zero clusters.
+ */
+int qcow2_expand_zero_clusters(BlockDriverState *bs)
+{
+BDRVQcowState *s = bs-opaque;
+uint64_t *l1_table = NULL;
+int ret;
+int i, j;

Re: [Qemu-devel] [PATCH v2 2/2] milkymist-uart: use Device::realize instead of SysBusDevice::init

2013-09-02 Thread Andreas Färber
Am 01.09.2013 20:28, schrieb Antony Pavlov:
 On Sat, 31 Aug 2013 21:09:20 +0200
 Andreas Färber afaer...@suse.de wrote:
 
 Am 31.08.2013 19:22, schrieb Antony Pavlov:
 Use of SysBusDevice::init is deprecated.
 Use Device::realize instead of SysBusDevice::init.
 Check dma/pl330.c for an example of the pattern.

 Also introduce TypeInfo::instance_init milkymist_uart_init()
 as char/pl011.c does.

 Reported-by: Peter Crosthwaite peter.crosthwa...@xilinx.com
 Signed-off-by: Antony Pavlov antonynpav...@gmail.com
 CC: Peter Crosthwaite peter.crosthwa...@xilinx.com
 CC: Michael Walle mich...@walle.cc
 CC: Andreas Färber afaer...@suse.de
 ---
  hw/char/milkymist-uart.c | 24 ++--
  1 file changed, 14 insertions(+), 10 deletions(-)

 Thanks, applied to qom-next (with shortened commit message):
 https://github.com/afaerber/qemu-cpu/commits/qom-next

 
 That's about the patch number 1 ( milkymist-uart: use qemu_chr_fe_write_all() 
 instead of qemu_chr_fe_write()) ?

No, it's about patch 2, which I replied to. Patch 1 is not a QOM
conversion but an unrelated bug fix - it can be handled either by the
lm32 maintainer or by whomever takes care of the char layer these days
(Anthony/Gerd).

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



Re: [Qemu-devel] [PATCH v3 2/3] qcow2: Implement bdrv_amend_options

2013-09-02 Thread Kevin Wolf
Am 02.09.2013 um 05:43 hat Fam Zheng geschrieben:
 On Fri, 08/30 12:27, Max Reitz wrote:
  Implement bdrv_amend_options for compat, size, backing_file, backing_fmt
  and lazy_refcounts.
  
  Downgrading images from compat=1.1 to compat=0.10 is achieved through
  handling all incompatible flags accordingly, clearing all compatible and
  autoclear flags and expanding all zero clusters.
  
  Signed-off-by: Max Reitz mre...@redhat.com
  ---
   block/qcow2-cluster.c | 165 ++
   block/qcow2.c | 194 
  +-
   block/qcow2.h |   3 +
   3 files changed, 361 insertions(+), 1 deletion(-)

  +static int qcow2_amend_options(BlockDriverState *bs,
  +   QEMUOptionParameter *options)
  +{
  +BDRVQcowState *s = bs-opaque;
  +int old_version = s-qcow_version, new_version = old_version;
  +uint64_t new_size = 0;
  +const char *backing_file = NULL, *backing_format = NULL;
  +bool lazy_refcounts = s-use_lazy_refcounts;
  +int ret;
  +int i;
  +
  +for (i = 0; options[i].name; i++)
  +{
  +if (!strcmp(options[i].name, compat)) {
  +if (!options[i].value.s) {
  +/* preserve default */
  +} else if (!strcmp(options[i].value.s, 0.10)) {
  +new_version = 2;
  +} else if (!strcmp(options[i].value.s, 1.1)) {
  +new_version = 3;
  +} else {
  +fprintf(stderr, Unknown compatibility level %s.\n,
  +options[i].value.s);
  +return -EINVAL;
  +}
  +} else if (!strcmp(options[i].name, preallocation)) {
  +if (options[i].assigned) {
 
 For encryption flag and cluster_size, you checked the original value and only
 error out on actual change, should check the original preallocation value here
 as well?
 
  +fprintf(stderr, Cannot change preallocation mode.\n);
  +return -ENOTSUP;
  +}
  +} else if (!strcmp(options[i].name, size)) {
  +new_size = options[i].value.n;
  +} else if (!strcmp(options[i].name, backing_file)) {
  +backing_file = options[i].value.s;
  +} else if (!strcmp(options[i].name, backing_fmt)) {
  +backing_format = options[i].value.s;
  +} else if (!strcmp(options[i].name, encryption)) {
  +if (options[i].assigned 
  +(options[i].value.n != !!s-crypt_method)) {
  +fprintf(stderr, Changing the encryption flag is not 
  +supported.\n);
  +return -ENOTSUP;
  +}
  +} else if (!strcmp(options[i].name, cluster_size)) {
  +if (options[i].assigned  (options[i].value.n != 
  s-cluster_size))
  +{
  +fprintf(stderr, Changing the cluster size is not 
  +supported.\n);
  +return -ENOTSUP;
  +}
  +} else if (!strcmp(options[i].name, lazy_refcounts)) {
  +if (options[i].assigned) {
  +lazy_refcounts = options[i].value.n;
  +}
  +} else {
  +/* if this assertion fails, this probably means a new option 
  was
  + * added without having it covered here */
  +assert(false);
 
 A unknown option reported as -ENOTSUP with a proper message is good enough,
 it's not that critical for an assert.

assert() has nothing to do with being critical.

This is not code for handling a user error, but for catching programming
errors. If the else branch is reached, this is a bug, and you want it to
be detected as quickly as possible (and without having to debug a lot in
order to find out where a bogus -ENOTSUP comes from)

Kevin



Re: [Qemu-devel] [PATCH] target-ppc: Fix include for qemu_notify_event

2013-09-02 Thread Andreas Färber
Am 01.09.2013 18:00, schrieb Richard Henderson:
 Signed-off-by: Richard Henderson r...@twiddle.net
 ---
  target-ppc/kvm_ppc.c | 1 +
  1 file changed, 1 insertion(+)
 
 The PowerPC target has been broken for more than a week.

Déjà vu, Alex already sent a fix on ~Friday.

Andreas
 
 
 r~
 
 
 diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
 index 9b83655..47e54a6 100644
 --- a/target-ppc/kvm_ppc.c
 +++ b/target-ppc/kvm_ppc.c
 @@ -12,6 +12,7 @@
   */
  
  #include qemu-common.h
 +#include qemu/main-loop.h
  #include qemu/timer.h
  #include kvm_ppc.h
  #include sysemu/device_tree.h
 


-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



[Qemu-devel] [PULL 1/6] pci: Introduce helper to retrieve a PCI device's DMA address space

2013-09-02 Thread Michael S. Tsirkin
From: Alexey Kardashevskiy a...@ozlabs.ru

A PCI device's DMA address space (possibly an IOMMU) is returned by a
method on the PCIBus.  At the moment that only has one caller, so the
method is simply open coded.  We'll need another caller for VFIO, so
this patch introduces a helper/wrapper function.

If IOMMU is not set, the pci_device_iommu_address_space() function
returns the parent's IOMMU skipping the bus master address space as
otherwise proper emulation would require more effort for no benefit.

Signed-off-by: David Gibson da...@gibson.dropbear.id.au
[aik: added inheritance from parent if iommu is not set for the current bus]
Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/hw/pci/pci.h |  1 +
 hw/pci/pci.c | 24 ++--
 2 files changed, 19 insertions(+), 6 deletions(-)

diff --git a/include/hw/pci/pci.h b/include/hw/pci/pci.h
index ccec2ba..2374aa9 100644
--- a/include/hw/pci/pci.h
+++ b/include/hw/pci/pci.h
@@ -405,6 +405,7 @@ void pci_device_deassert_intx(PCIDevice *dev);
 
 typedef AddressSpace *(*PCIIOMMUFunc)(PCIBus *, void *, int);
 
+AddressSpace *pci_device_iommu_address_space(PCIDevice *dev);
 void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque);
 
 static inline void
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 4c004f5..8c33352 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -812,12 +812,7 @@ static PCIDevice *do_pci_register_device(PCIDevice 
*pci_dev, PCIBus *bus,
 }
 
 pci_dev-bus = bus;
-if (bus-iommu_fn) {
-dma_as = bus-iommu_fn(bus, bus-iommu_opaque, devfn);
-} else {
-/* FIXME: inherit memory region from bus creator */
-dma_as = address_space_memory;
-}
+dma_as = pci_device_iommu_address_space(pci_dev);
 
 memory_region_init_alias(pci_dev-bus_master_enable_region,
  OBJECT(pci_dev), bus master,
@@ -2239,6 +2234,23 @@ static void pci_device_class_init(ObjectClass *klass, 
void *data)
 k-props = pci_props;
 }
 
+AddressSpace *pci_device_iommu_address_space(PCIDevice *dev)
+{
+PCIBus *bus = PCI_BUS(dev-bus);
+
+if (bus-iommu_fn) {
+return bus-iommu_fn(bus, bus-iommu_opaque, dev-devfn);
+}
+
+if (bus-parent_dev) {
+/** We are ignoring the bus master DMA bit of the bridge
+ *  as it would complicate things such as VFIO for no good reason */
+return pci_device_iommu_address_space(bus-parent_dev);
+}
+
+return address_space_memory;
+}
+
 void pci_setup_iommu(PCIBus *bus, PCIIOMMUFunc fn, void *opaque)
 {
 bus-iommu_fn = fn;
-- 
MST




[Qemu-devel] [PULL 2/6] pc: fix regression for 64 bit PCI memory

2013-09-02 Thread Michael S. Tsirkin
commit 398489018183d613306ab022653552247d93919f
pc: limit 64 bit hole to 2G by default
introduced a way for management to control
the window allocated to the 64 bit PCI hole.

This is useful, but existing management tools do not know how to set
this property.  As a result, e.g. specifying a large ivshmem device with
size  4G is broken by default.  For example this configuration no
longer works:

-device ivshmem,size=4294967296,chardev=cfoo
-chardev socket,path=/tmp/sock,id=cfoo,server,nowait

Fix this by detecting that hole size was not specified
and defaulting to the backwards-compatible value of 1  62.

Cc: qemu-sta...@nongnu.org
Cc: Igor Mammedov imamm...@redhat.com
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/hw/i386/pc.h | 11 ++-
 hw/pci-host/piix.c   |  9 ++---
 hw/pci-host/q35.c|  8 +---
 3 files changed, 21 insertions(+), 7 deletions(-)

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index f79d478..475ba9e 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -106,7 +106,16 @@ PcGuestInfo *pc_guest_info_init(ram_addr_t 
below_4g_mem_size,
 #define PCI_HOST_PROP_PCI_HOLE64_START pci-hole64-start
 #define PCI_HOST_PROP_PCI_HOLE64_END   pci-hole64-end
 #define PCI_HOST_PROP_PCI_HOLE64_SIZE  pci-hole64-size
-#define DEFAULT_PCI_HOLE64_SIZE (1ULL  31)
+#define DEFAULT_PCI_HOLE64_SIZE (~0x0ULL)
+
+static inline uint64_t pci_host_get_hole64_size(uint64_t pci_hole64_size)
+{
+if (pci_hole64_size == DEFAULT_PCI_HOLE64_SIZE) {
+return 1ULL  62;
+} else {
+return pci_hole64_size;
+}
+}
 
 void pc_init_pci64_hole(PcPciInfo *pci_info, uint64_t pci_hole64_start,
 uint64_t pci_hole64_size);
diff --git a/hw/pci-host/piix.c b/hw/pci-host/piix.c
index dc1718f..221d82b 100644
--- a/hw/pci-host/piix.c
+++ b/hw/pci-host/piix.c
@@ -320,6 +320,7 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
 PCII440FXState *f;
 unsigned i;
 I440FXState *i440fx;
+uint64_t pci_hole64_size;
 
 dev = qdev_create(NULL, TYPE_I440FX_PCI_HOST_BRIDGE);
 s = PCI_HOST_BRIDGE(dev);
@@ -351,13 +352,15 @@ PCIBus *i440fx_init(PCII440FXState **pi440fx_state,
  pci_hole_start, pci_hole_size);
 memory_region_add_subregion(f-system_memory, pci_hole_start, 
f-pci_hole);
 
+pci_hole64_size = pci_host_get_hole64_size(i440fx-pci_hole64_size);
+
 pc_init_pci64_hole(i440fx-pci_info, 0x1ULL + above_4g_mem_size,
-   i440fx-pci_hole64_size);
+   pci_hole64_size);
 memory_region_init_alias(f-pci_hole_64bit, OBJECT(d), pci-hole64,
  f-pci_address_space,
  i440fx-pci_info.w64.begin,
- i440fx-pci_hole64_size);
-if (i440fx-pci_hole64_size) {
+ pci_hole64_size);
+if (pci_hole64_size) {
 memory_region_add_subregion(f-system_memory,
 i440fx-pci_info.w64.begin,
 f-pci_hole_64bit);
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 12314d8..4febd24 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -320,6 +320,7 @@ static int mch_init(PCIDevice *d)
 {
 int i;
 MCHPCIState *mch = MCH_PCI_DEVICE(d);
+uint64_t pci_hole64_size;
 
 /* setup pci memory regions */
 memory_region_init_alias(mch-pci_hole, OBJECT(mch), pci-hole,
@@ -329,13 +330,14 @@ static int mch_init(PCIDevice *d)
 memory_region_add_subregion(mch-system_memory, mch-below_4g_mem_size,
 mch-pci_hole);
 
+pci_hole64_size = pci_host_get_hole64_size(mch-pci_hole64_size);
 pc_init_pci64_hole(mch-pci_info, 0x1ULL + mch-above_4g_mem_size,
-   mch-pci_hole64_size);
+   pci_hole64_size);
 memory_region_init_alias(mch-pci_hole_64bit, OBJECT(mch), pci-hole64,
  mch-pci_address_space,
  mch-pci_info.w64.begin,
- mch-pci_hole64_size);
-if (mch-pci_hole64_size) {
+ pci_hole64_size);
+if (pci_hole64_size) {
 memory_region_add_subregion(mch-system_memory,
 mch-pci_info.w64.begin,
 mch-pci_hole_64bit);
-- 
MST




[Qemu-devel] [PULL 5/6] pc: reduce duplication, fix PIIX descriptions

2013-09-02 Thread Michael S. Tsirkin
We have a lot of code duplication between machine types,
this increases with each new machine type
and each new field.

This has already introduced a minor bug: description
for pc-1.3 says Standard PC while description for
pc-1.4 is Standard PC (i440FX + PIIX, 1996)
which makes you think 1.3 is somehow more standard,
or newer, while in fact it's a revision of the same PC.

This patch addresses this issue by using macros, along
the lines used by PC_COMPAT_X_X - only for
non-property options.

The approach can extend to non-PC machine types.

Cc: Paolo Bonzini pbonz...@redhat.com
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/hw/i386/pc.h |  8 +
 hw/i386/pc_piix.c| 86 +---
 hw/i386/pc_q35.c | 25 ---
 3 files changed, 56 insertions(+), 63 deletions(-)

diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index 475ba9e..7fb04d8 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -325,4 +325,12 @@ int e820_add_entry(uint64_t, uint64_t, uint32_t);
 .value= stringify(0),\
 }
 
+#define PC_COMMON_MACHINE_OPTIONS \
+.default_boot_order = cad
+
+#define PC_DEFAULT_MACHINE_OPTIONS \
+PC_COMMON_MACHINE_OPTIONS, \
+.hot_add_cpu = pc_hot_add_cpu, \
+.max_cpus = 255
+
 #endif
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index aa0a39a..275e395 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -334,36 +334,39 @@ static void pc_xen_hvm_init(QEMUMachineInitArgs *args)
 }
 #endif
 
+#define PC_I440FX_MACHINE_OPTIONS \
+PC_DEFAULT_MACHINE_OPTIONS, \
+.desc = Standard PC (i440FX + PIIX, 1996), \
+.hot_add_cpu = pc_hot_add_cpu
+
+#define PC_I440FX_1_6_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS
+
 static QEMUMachine pc_i440fx_machine_v1_6 = {
+PC_I440FX_1_6_MACHINE_OPTIONS,
 .name = pc-i440fx-1.6,
 .alias = pc,
-.desc = Standard PC (i440FX + PIIX, 1996),
 .init = pc_init_pci_1_6,
-.hot_add_cpu = pc_hot_add_cpu,
-.max_cpus = 255,
 .is_default = 1,
-.default_boot_order = cad,
 };
 
 static QEMUMachine pc_i440fx_machine_v1_5 = {
+PC_I440FX_1_6_MACHINE_OPTIONS,
 .name = pc-i440fx-1.5,
-.desc = Standard PC (i440FX + PIIX, 1996),
 .init = pc_init_pci_1_5,
-.hot_add_cpu = pc_hot_add_cpu,
-.max_cpus = 255,
 .compat_props = (GlobalProperty[]) {
 PC_COMPAT_1_5,
 { /* end of list */ }
 },
-.default_boot_order = cad,
 };
 
+#define PC_I440FX_1_4_MACHINE_OPTIONS \
+PC_I440FX_1_6_MACHINE_OPTIONS, \
+.hot_add_cpu = NULL
+
 static QEMUMachine pc_i440fx_machine_v1_4 = {
+PC_I440FX_1_4_MACHINE_OPTIONS,
 .name = pc-i440fx-1.4,
-.desc = Standard PC (i440FX + PIIX, 1996),
 .init = pc_init_pci_1_4,
-.max_cpus = 255,
-.default_boot_order = cad,
 .compat_props = (GlobalProperty[]) {
 PC_COMPAT_1_4,
 { /* end of list */ }
@@ -391,11 +394,9 @@ static QEMUMachine pc_i440fx_machine_v1_4 = {
 }
 
 static QEMUMachine pc_machine_v1_3 = {
+PC_I440FX_1_4_MACHINE_OPTIONS,
 .name = pc-1.3,
-.desc = Standard PC,
 .init = pc_init_pci_1_3,
-.max_cpus = 255,
-.default_boot_order = cad,
 .compat_props = (GlobalProperty[]) {
 PC_COMPAT_1_3,
 { /* end of list */ }
@@ -430,12 +431,13 @@ static QEMUMachine pc_machine_v1_3 = {
 .value= off,\
 }
 
+#define PC_I440FX_1_2_MACHINE_OPTIONS \
+PC_I440FX_1_4_MACHINE_OPTIONS, \
+.init = pc_init_pci_1_2
+
 static QEMUMachine pc_machine_v1_2 = {
+PC_I440FX_1_2_MACHINE_OPTIONS,
 .name = pc-1.2,
-.desc = Standard PC,
-.init = pc_init_pci_1_2,
-.max_cpus = 255,
-.default_boot_order = cad,
 .compat_props = (GlobalProperty[]) {
 PC_COMPAT_1_2,
 { /* end of list */ }
@@ -475,11 +477,8 @@ static QEMUMachine pc_machine_v1_2 = {
 }
 
 static QEMUMachine pc_machine_v1_1 = {
+PC_I440FX_1_2_MACHINE_OPTIONS,
 .name = pc-1.1,
-.desc = Standard PC,
-.init = pc_init_pci_1_2,
-.max_cpus = 255,
-.default_boot_order = cad,
 .compat_props = (GlobalProperty[]) {
 PC_COMPAT_1_1,
 { /* end of list */ }
@@ -507,11 +506,8 @@ static QEMUMachine pc_machine_v1_1 = {
 }
 
 static QEMUMachine pc_machine_v1_0 = {
+PC_I440FX_1_2_MACHINE_OPTIONS,
 .name = pc-1.0,
-.desc = Standard PC,
-.init = pc_init_pci_1_2,
-.max_cpus = 255,
-.default_boot_order = cad,
 .compat_props = (GlobalProperty[]) {
 PC_COMPAT_1_0,
 { /* end of list */ }
@@ -523,11 +519,8 @@ static QEMUMachine pc_machine_v1_0 = {
 PC_COMPAT_1_0
 
 static QEMUMachine pc_machine_v0_15 = {
+PC_I440FX_1_2_MACHINE_OPTIONS,
 .name = pc-0.15,
-.desc = Standard PC,
-.init = pc_init_pci_1_2,
-.max_cpus = 255,
-.default_boot_order = cad,
 .compat_props = (GlobalProperty[]) {
 PC_COMPAT_0_15,
 { /* end of list */ }
@@ -556,11 +549,8 

[Qemu-devel] [PULL 0/6] pc,pci,virtio fixes and cleanups

2013-09-02 Thread Michael S. Tsirkin
The following changes since commit 1ae2757c6c4525c9b42f408c86818f843bad7418:

  virtio: virtqueue_get_avail_bytes: fix desc_pa when loop over the indirect 
descriptor table (2013-08-25 12:52:33 +0300)

are available in the git repository at:

  git://git.kernel.org/pub/scm/virt/kvm/mst/qemu.git tags/for_anthony

for you to fetch changes up to 23fe2b3f9e7df8da53ac1bc32c6875254911d7f4:

  virtio_pci: fix level interrupts with irqfd (2013-09-01 11:15:03 +0300)


pc,pci,virtio fixes and cleanups

This includes pc and pci cleanups and enhancements,
and a virtio bugfix for level interrupts.

Signed-off-by: Michael S. Tsirkin m...@redhat.com


Alexey Kardashevskiy (2):
  pci: Introduce helper to retrieve a PCI device's DMA address space
  pci: add config space access traces

Markus Armbruster (1):
  hw: Clean up bogus default boot order

Michael S. Tsirkin (3):
  pc: fix regression for 64 bit PCI memory
  pc: reduce duplication, fix PIIX descriptions
  virtio_pci: fix level interrupts with irqfd

 include/hw/boards.h  |  7 +--
 include/hw/i386/pc.h | 19 ++-
 include/hw/pci/pci.h |  1 +
 hw/alpha/dp264.c |  1 -
 hw/arm/collie.c  |  1 -
 hw/arm/exynos4_boards.c  |  2 -
 hw/arm/gumstix.c |  2 -
 hw/arm/highbank.c|  2 -
 hw/arm/integratorcp.c|  1 -
 hw/arm/kzm.c |  1 -
 hw/arm/mainstone.c   |  1 -
 hw/arm/musicpal.c|  1 -
 hw/arm/nseries.c |  6 +--
 hw/arm/omap_sx1.c|  2 -
 hw/arm/palm.c|  1 -
 hw/arm/realview.c|  4 --
 hw/arm/spitz.c   |  4 --
 hw/arm/stellaris.c   |  2 -
 hw/arm/tosa.c|  1 -
 hw/arm/versatilepb.c |  2 -
 hw/arm/vexpress.c|  2 -
 hw/arm/xilinx_zynq.c |  1 -
 hw/arm/z2.c  |  1 -
 hw/core/null-machine.c   |  1 -
 hw/cris/axis_dev88.c |  1 -
 hw/i386/pc_piix.c| 88 +---
 hw/i386/pc_q35.c | 27 +-
 hw/i386/xen_machine_pv.c |  1 -
 hw/lm32/lm32_boards.c|  2 -
 hw/lm32/milkymist.c  |  1 -
 hw/m68k/an5206.c |  1 -
 hw/m68k/dummy_m68k.c |  1 -
 hw/m68k/mcf5208.c|  1 -
 hw/microblaze/petalogix_ml605_mmu.c  |  1 -
 hw/microblaze/petalogix_s3adsp1800_mmu.c |  1 -
 hw/mips/mips_fulong2e.c  |  1 -
 hw/mips/mips_jazz.c  |  2 -
 hw/mips/mips_malta.c |  1 -
 hw/mips/mips_mipssim.c   |  1 -
 hw/mips/mips_r4k.c   |  1 -
 hw/openrisc/openrisc_sim.c   |  1 -
 hw/pci-host/piix.c   |  9 ++--
 hw/pci-host/q35.c|  8 +--
 hw/pci/pci.c | 24 ++---
 hw/pci/pci_host.c| 11 +++-
 hw/ppc/e500plat.c|  1 -
 hw/ppc/mac_newworld.c|  4 +-
 hw/ppc/mac_oldworld.c|  4 +-
 hw/ppc/mpc8544ds.c   |  1 -
 hw/ppc/ppc405_boards.c   |  2 -
 hw/ppc/ppc440_bamboo.c   |  1 -
 hw/ppc/prep.c|  4 +-
 hw/ppc/spapr.c   |  4 +-
 hw/ppc/virtex_ml507.c|  1 -
 hw/s390x/s390-virtio-ccw.c   |  1 -
 hw/s390x/s390-virtio.c   |  1 -
 hw/sh4/r2d.c |  1 -
 hw/sh4/shix.c|  1 -
 hw/sparc/leon3.c |  1 -
 hw/sparc/sun4m.c | 22 
 hw/sparc64/sun4u.c   | 10 ++--
 hw/unicore32/puv3.c  |  1 -
 hw/virtio/virtio-pci.c   |  3 +-
 hw/xtensa/xtensa_lx60.c  |  2 -
 hw/xtensa/xtensa_sim.c   |  1 -
 vl.c |  4 +-
 trace-events |  4 ++
 67 files changed, 144 insertions(+), 180 deletions(-)




[Qemu-devel] [PULL 4/6] hw: Clean up bogus default boot order

2013-09-02 Thread Michael S. Tsirkin
From: Markus Armbruster arm...@redhat.com

We set default boot order cad in every single machine definition
except pseries and moxiesim, even though very few boards actually
care for boot order, and cad makes sense for even fewer.

Machines that care:

* pc and its variants

  Accept up to three letters 'a', 'b' (undocumented alias for 'a'),
  'c', 'd' and 'n'.  Reject all others (fatal with -boot).

* nseries (n800, n810)

  Check whether order starts with 'n'.  Silently ignored otherwise.

* prep, g3beige, mac99

  Extract the first character the machine understands (subset of
  'a'..'f').  Silently ignored otherwise.

* spapr

  Accept an arbitrary string (vl.c restricts it to contain only
  'a'..'p', no duplicates).

* sun4[mdc]

  Use the first character.  Silently ignored otherwise.

Strip characters these machines ignore from their default boot order.

For all other machines, remove the unused default boot order
alltogether.

Note that my rename of QEMUMachine member boot_order to
default_boot_order and QEMUMachineInitArgs member boot_device to
boot_order has a welcome side effect: it makes every use of boot
orders visible in this patch, for easy review.

Signed-off-by: Markus Armbruster arm...@redhat.com
Reviewed-by: Laszlo Ersek ler...@redhat.com
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 include/hw/boards.h  |  7 ++-
 hw/alpha/dp264.c |  1 -
 hw/arm/collie.c  |  1 -
 hw/arm/exynos4_boards.c  |  2 --
 hw/arm/gumstix.c |  2 --
 hw/arm/highbank.c|  2 --
 hw/arm/integratorcp.c|  1 -
 hw/arm/kzm.c |  1 -
 hw/arm/mainstone.c   |  1 -
 hw/arm/musicpal.c|  1 -
 hw/arm/nseries.c |  6 +++---
 hw/arm/omap_sx1.c|  2 --
 hw/arm/palm.c|  1 -
 hw/arm/realview.c|  4 
 hw/arm/spitz.c   |  4 
 hw/arm/stellaris.c   |  2 --
 hw/arm/tosa.c|  1 -
 hw/arm/versatilepb.c |  2 --
 hw/arm/vexpress.c|  2 --
 hw/arm/xilinx_zynq.c |  1 -
 hw/arm/z2.c  |  1 -
 hw/core/null-machine.c   |  1 -
 hw/cris/axis_dev88.c |  1 -
 hw/i386/pc_piix.c| 32 
 hw/i386/pc_q35.c |  8 
 hw/i386/xen_machine_pv.c |  1 -
 hw/lm32/lm32_boards.c|  2 --
 hw/lm32/milkymist.c  |  1 -
 hw/m68k/an5206.c |  1 -
 hw/m68k/dummy_m68k.c |  1 -
 hw/m68k/mcf5208.c|  1 -
 hw/microblaze/petalogix_ml605_mmu.c  |  1 -
 hw/microblaze/petalogix_s3adsp1800_mmu.c |  1 -
 hw/mips/mips_fulong2e.c  |  1 -
 hw/mips/mips_jazz.c  |  2 --
 hw/mips/mips_malta.c |  1 -
 hw/mips/mips_mipssim.c   |  1 -
 hw/mips/mips_r4k.c   |  1 -
 hw/openrisc/openrisc_sim.c   |  1 -
 hw/ppc/e500plat.c|  1 -
 hw/ppc/mac_newworld.c|  4 ++--
 hw/ppc/mac_oldworld.c|  4 ++--
 hw/ppc/mpc8544ds.c   |  1 -
 hw/ppc/ppc405_boards.c   |  2 --
 hw/ppc/ppc440_bamboo.c   |  1 -
 hw/ppc/prep.c|  4 ++--
 hw/ppc/spapr.c   |  4 ++--
 hw/ppc/virtex_ml507.c|  1 -
 hw/s390x/s390-virtio-ccw.c   |  1 -
 hw/s390x/s390-virtio.c   |  1 -
 hw/sh4/r2d.c |  1 -
 hw/sh4/shix.c|  1 -
 hw/sparc/leon3.c |  1 -
 hw/sparc/sun4m.c | 22 +++---
 hw/sparc64/sun4u.c   | 10 +-
 hw/unicore32/puv3.c  |  1 -
 hw/xtensa/xtensa_lx60.c  |  2 --
 hw/xtensa/xtensa_sim.c   |  1 -
 vl.c |  4 ++--
 59 files changed, 51 insertions(+), 119 deletions(-)

diff --git a/include/hw/boards.h b/include/hw/boards.h
index fb7c6f1..5a7ae9f 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -6,12 +6,9 @@
 #include sysemu/blockdev.h
 #include hw/qdev.h
 
-#define DEFAULT_MACHINE_OPTIONS \
-.boot_order = cad
-
 typedef struct QEMUMachineInitArgs {
 ram_addr_t ram_size;
-const char *boot_device;
+const char *boot_order;
 const char *kernel_filename;
 const char *kernel_cmdline;
 const char *initrd_filename;
@@ -42,7 +39,7 @@ typedef struct QEMUMachine {
 no_sdcard:1;
 int is_default;
 const char 

[Qemu-devel] [PULL 3/6] pci: add config space access traces

2013-09-02 Thread Michael S. Tsirkin
From: Alexey Kardashevskiy a...@ozlabs.ru

This adds pci_cfg_read and pci_cfg_write traces for config spaces
accesses.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 hw/pci/pci_host.c | 11 ++-
 trace-events  |  4 
 2 files changed, 14 insertions(+), 1 deletion(-)

diff --git a/hw/pci/pci_host.c b/hw/pci/pci_host.c
index 7dd9b25..77c7d1f 100644
--- a/hw/pci/pci_host.c
+++ b/hw/pci/pci_host.c
@@ -20,6 +20,7 @@
 
 #include hw/pci/pci.h
 #include hw/pci/pci_host.h
+#include trace.h
 
 /* debug PCI */
 //#define DEBUG_PCI
@@ -51,14 +52,22 @@ void pci_host_config_write_common(PCIDevice *pci_dev, 
uint32_t addr,
   uint32_t limit, uint32_t val, uint32_t len)
 {
 assert(len = 4);
+trace_pci_cfg_write(pci_dev-name, PCI_SLOT(pci_dev-devfn),
+PCI_FUNC(pci_dev-devfn), addr, val);
 pci_dev-config_write(pci_dev, addr, val, MIN(len, limit - addr));
 }
 
 uint32_t pci_host_config_read_common(PCIDevice *pci_dev, uint32_t addr,
  uint32_t limit, uint32_t len)
 {
+uint32_t ret;
+
 assert(len = 4);
-return pci_dev-config_read(pci_dev, addr, MIN(len, limit - addr));
+ret = pci_dev-config_read(pci_dev, addr, MIN(len, limit - addr));
+trace_pci_cfg_read(pci_dev-name, PCI_SLOT(pci_dev-devfn),
+   PCI_FUNC(pci_dev-devfn), addr, ret);
+
+return ret;
 }
 
 void pci_data_write(PCIBus *s, uint32_t addr, uint32_t val, int len)
diff --git a/trace-events b/trace-events
index 3856b5c..9d1d1df 100644
--- a/trace-events
+++ b/trace-events
@@ -1176,3 +1176,7 @@ object_class_dynamic_cast_assert(const char *type, const 
char *target, const cha
 # hw/xen/xen_pvdevice.c
 xen_pv_mmio_read(uint64_t addr) WARNING: read from Xen PV Device MMIO space 
(address %PRIx64)
 xen_pv_mmio_write(uint64_t addr) WARNING: write to Xen PV Device MMIO space 
(address %PRIx64)
+
+# hw/pci/pci_host.c
+pci_cfg_read(const char *dev, unsigned devid, unsigned fnid, unsigned offs, 
unsigned val) %s %02u:%u @0x%x - 0x%x
+pci_cfg_write(const char *dev, unsigned devid, unsigned fnid, unsigned offs, 
unsigned val) %s %02u:%u @0x%x - 0x%x
-- 
MST




[Qemu-devel] [PULL 6/6] virtio_pci: fix level interrupts with irqfd

2013-09-02 Thread Michael S. Tsirkin
commit 62c96360ae7f2c7a8b029277fbb7cb082fdef7fd
virtio-pci: fix level interrupts
only helps systems without irqfd: on systems with irqfd support we
passed in flag requesting irqfd even when msix is disabled.

As a result, for level interrupts we didn't install an fd handler so
unmasking an fd had no effect.

Fix this up.

Cc: qemu-sta...@nongnu.org
Signed-off-by: Michael S. Tsirkin m...@redhat.com
---
 hw/virtio/virtio-pci.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index d37037e..41b96ce 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -799,8 +799,7 @@ static int virtio_pci_set_guest_notifiers(DeviceState *d, 
int nvqs, bool assign)
 break;
 }
 
-r = virtio_pci_set_guest_notifier(d, n, assign,
-  kvm_msi_via_irqfd_enabled());
+r = virtio_pci_set_guest_notifier(d, n, assign, with_irqfd);
 if (r  0) {
 goto assign_error;
 }
-- 
MST




Re: [Qemu-devel] [PATCH] target-ppc: Fix include for qemu_notify_event

2013-09-02 Thread Alexander Graf

On 02.09.2013, at 09:56, Andreas Färber wrote:

 Am 01.09.2013 18:00, schrieb Richard Henderson:
 Signed-off-by: Richard Henderson r...@twiddle.net
 ---
 target-ppc/kvm_ppc.c | 1 +
 1 file changed, 1 insertion(+)
 
 The PowerPC target has been broken for more than a week.
 
 Déjà vu, Alex already sent a fix on ~Friday.

Sending out pull request :). I just wanted to do another autotest run last 
night.


Alex




[Qemu-devel] [PULL 10/18] target-ppc: fix bit extraction for FPBF and FPL

2013-09-02 Thread Alexander Graf
From: Aurelien Jarno aurel...@aurel32.net

Bit extraction for the FP BF and L field of the MTFSFI and MTFSF
instructions is wrong and doesn't match the reference manual (which
explain the bit number in big endian format). It has been broken in
commit 7d08d85645def18eac2a9d672c1868a35e0bcf79.

This patch fixes this, which in turn fixes the problem reported by
Khem Raj about the floor() function of libm.

Reported-by: Khem Raj raj.k...@gmail.com
Signed-off-by: Aurelien Jarno aurel...@aurel32.net
CC: qemu-sta...@nongnu.org (1.6)
Signed-off-by: Alexander Graf ag...@suse.de
---
 target-ppc/translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-ppc/translate.c b/target-ppc/translate.c
index f07d70d..41f4048 100644
--- a/target-ppc/translate.c
+++ b/target-ppc/translate.c
@@ -428,9 +428,9 @@ EXTRACT_HELPER(CRM, 12, 8);
 EXTRACT_HELPER(SR, 16, 4);
 
 /* mtfsf/mtfsfi */
-EXTRACT_HELPER(FPBF, 19, 3);
+EXTRACT_HELPER(FPBF, 23, 3);
 EXTRACT_HELPER(FPIMM, 12, 4);
-EXTRACT_HELPER(FPL, 21, 1);
+EXTRACT_HELPER(FPL, 25, 1);
 EXTRACT_HELPER(FPFLM, 17, 8);
 EXTRACT_HELPER(FPW, 16, 1);
 
-- 
1.8.1.4




[Qemu-devel] [PULL 16/18] PPC: KVM: Compile fix for qemu_notify_event

2013-09-02 Thread Alexander Graf
The function qemu_notify_event is defined by a header that we don't
include in the PPC KVM code. Include it to get the code building
again.

  target-ppc/kvm_ppc.c: In function 'kvmppc_timer_hack':
  target-ppc/kvm_ppc.c:26:5: error: implicit declaration of function 
'qemu_notify_event' [-Werror=implicit-function-declaration]
  target-ppc/kvm_ppc.c:26:5: error: nested extern declaration of 
'qemu_notify_event' [-Werror=nested-externs]

Signed-off-by: Alexander Graf ag...@suse.de
---
 target-ppc/kvm_ppc.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/target-ppc/kvm_ppc.c b/target-ppc/kvm_ppc.c
index 9b83655..f769acd 100644
--- a/target-ppc/kvm_ppc.c
+++ b/target-ppc/kvm_ppc.c
@@ -15,6 +15,7 @@
 #include qemu/timer.h
 #include kvm_ppc.h
 #include sysemu/device_tree.h
+#include qemu/main-loop.h
 
 #define PROC_DEVTREE_PATH /proc/device-tree
 
-- 
1.8.1.4




[Qemu-devel] [PULL 00/18] ppc patch queue 2013-09-02

2013-09-02 Thread Alexander Graf
Hi Blue / Aurelien / Anthony,

This is my current patch queue for ppc.  Please pull.

Alex


The following changes since commit 4ff78e0dbcd5c795962567fdc1b31e9e03c55b07:

  Merge remote-tracking branch 'luiz/queue/qmp' into staging (2013-08-30 
12:26:04 -0500)

are available in the git repository at:


  git://github.com/agraf/qemu.git ppc-for-upstream

for you to fetch changes up to 7e472264e9e2727bc7d08fe6f012db76e1c1a193:

  PPC: spapr: iommu: rework traces (2013-09-02 10:06:43 +0200)


Alexander Graf (2):
  PPC: E500: Generate device tree on reset
  PPC: KVM: Compile fix for qemu_notify_event

Alexey Kardashevskiy (5):
  spapr-pci: fix config space access to support bridges
  spapr-pci: rework MSI/MSIX
  xics: move registration of global state to realize()
  spapr: add stop-self RTAS call required to support hot CPU unplug
  PPC: spapr: iommu: rework traces

Andreas Färber (3):
  ppc405_boards: Disable debug output
  ppc405_uc: Disable debug output
  ppc405_boards: Don't enforce presence of firmware for qtest

Aneesh Kumar K.V (1):
  target-ppc: Use #define instead of opencoding SLB valid bit

Anton Blanchard (5):
  pseries: Fix stalls on hypervisor virtual console
  target-ppc: USE LPCR_ILE to control exception endian on POWER7
  target-ppc: POWER7 supports the MSR_LE bit
  disas/ppc.c: Fix little endian disassembly
  pseries: Add H_SET_MODE hcall to change guest exception endianness

Aurelien Jarno (1):
  target-ppc: fix bit extraction for FPBF and FPL

Efimov Vasily (1):
  ppc: virtex_ml507: QEMU_OPTION_dtb support for this machine.

 disas/ppc.c |  3 +-
 hw/char/spapr_vty.c |  2 ++
 hw/intc/xics.c  | 21 ++---
 hw/ppc/e500.c   | 52 ++--
 hw/ppc/ppc405_boards.c  | 39 +---
 hw/ppc/ppc405_uc.c  | 16 +-
 hw/ppc/spapr.c  | 31 +++
 hw/ppc/spapr_hcall.c| 50 +++
 hw/ppc/spapr_iommu.c| 71 +++
 hw/ppc/spapr_pci.c  | 73 ++---
 hw/ppc/spapr_rtas.c | 23 ++
 hw/ppc/virtex_ml507.c   | 29 +++---
 include/hw/pci-host/spapr.h |  8 +++--
 include/hw/ppc/spapr.h  | 21 +++--
 target-ppc/cpu.h|  2 ++
 target-ppc/excp_helper.c| 10 +++
 target-ppc/kvm_ppc.c|  1 +
 target-ppc/mmu_helper.c |  2 +-
 target-ppc/translate.c  |  4 +--
 target-ppc/translate_init.c |  2 +-
 trace-events|  5 
 21 files changed, 305 insertions(+), 160 deletions(-)



[Qemu-devel] [PULL 05/18] disas/ppc.c: Fix little endian disassembly

2013-09-02 Thread Alexander Graf
From: Anton Blanchard an...@samba.org

Use info-endian to select the endian of the instruction to
be disassembled.

Signed-off-by: Anton Blanchard an...@samba.org
Reviewed-by: Anthony Liguori aligu...@us.ibm.com
Signed-off-by: Alexander Graf ag...@suse.de
---
 disas/ppc.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/disas/ppc.c b/disas/ppc.c
index c149506..99c4cbc 100644
--- a/disas/ppc.c
+++ b/disas/ppc.c
@@ -5157,7 +5157,8 @@ int
 print_insn_ppc (bfd_vma memaddr, struct disassemble_info *info)
 {
   int dialect = (char *) info-private_data - (char *) 0;
-  return print_insn_powerpc (memaddr, info, 1, dialect);
+  return print_insn_powerpc (memaddr, info, info-endian == BFD_ENDIAN_BIG,
+ dialect);
 }
 
 /* Print a big endian PowerPC instruction.  */
-- 
1.8.1.4




[Qemu-devel] [PULL 08/18] ppc405_uc: Disable debug output

2013-09-02 Thread Alexander Graf
From: Andreas Färber afaer...@suse.de

Signed-off-by: Andreas Färber afaer...@suse.de
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/ppc405_uc.c | 16 
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/hw/ppc/ppc405_uc.c b/hw/ppc/ppc405_uc.c
index 0ef5254..6d6a7f1 100644
--- a/hw/ppc/ppc405_uc.c
+++ b/hw/ppc/ppc405_uc.c
@@ -30,15 +30,15 @@
 #include qemu/log.h
 #include exec/address-spaces.h
 
-#define DEBUG_OPBA
-#define DEBUG_SDRAM
-#define DEBUG_GPIO
-#define DEBUG_SERIAL
-#define DEBUG_OCM
+//#define DEBUG_OPBA
+//#define DEBUG_SDRAM
+//#define DEBUG_GPIO
+//#define DEBUG_SERIAL
+//#define DEBUG_OCM
 //#define DEBUG_I2C
-#define DEBUG_GPT
-#define DEBUG_MAL
-#define DEBUG_CLOCKS
+//#define DEBUG_GPT
+//#define DEBUG_MAL
+//#define DEBUG_CLOCKS
 //#define DEBUG_CLOCKS_LL
 
 ram_addr_t ppc405_set_bootinfo (CPUPPCState *env, ppc4xx_bd_info_t *bd,
-- 
1.8.1.4




[Qemu-devel] [PULL 06/18] ppc: virtex_ml507: QEMU_OPTION_dtb support for this machine.

2013-09-02 Thread Alexander Graf
From: Efimov Vasily r...@ispras.ru

QEMU has 'dtb' option for specifing the device tree file for the kernel.
The patch adds support for this option to the 'virtex_ml507' machine
implementation.

Signed-off-by: Efimov Vasily r...@ispras.ru
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/virtex_ml507.c | 29 +++--
 1 file changed, 19 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/virtex_ml507.c b/hw/ppc/virtex_ml507.c
index 08e77fb..e9468b1 100644
--- a/hw/ppc/virtex_ml507.c
+++ b/hw/ppc/virtex_ml507.c
@@ -141,22 +141,31 @@ static int xilinx_load_device_tree(hwaddr addr,
 {
 char *path;
 int fdt_size;
-void *fdt;
+void *fdt = NULL;
 int r;
+const char *dtb_filename;
 
-/* Try the local ppc.dtb override.  */
-fdt = load_device_tree(ppc.dtb, fdt_size);
-if (!fdt) {
-path = qemu_find_file(QEMU_FILE_TYPE_BIOS, BINARY_DEVICE_TREE_FILE);
-if (path) {
-fdt = load_device_tree(path, fdt_size);
-g_free(path);
+dtb_filename = qemu_opt_get(qemu_get_machine_opts(), dtb);
+if (dtb_filename) {
+fdt = load_device_tree(dtb_filename, fdt_size);
+if (!fdt) {
+error_report(Error while loading device tree file '%s',
+dtb_filename);
 }
+} else {
+/* Try the local ppc.dtb override.  */
+fdt = load_device_tree(ppc.dtb, fdt_size);
 if (!fdt) {
-return 0;
+path = qemu_find_file(QEMU_FILE_TYPE_BIOS, 
BINARY_DEVICE_TREE_FILE);
+if (path) {
+fdt = load_device_tree(path, fdt_size);
+g_free(path);
+}
 }
 }
-
+if (!fdt) {
+return 0;
+}
 r = qemu_devtree_setprop_string(fdt, /chosen, bootargs, 
kernel_cmdline);
 if (r  0)
 fprintf(stderr, couldn't set /chosen/bootargs\n);
-- 
1.8.1.4




[Qemu-devel] [PULL 07/18] ppc405_boards: Disable debug output

2013-09-02 Thread Alexander Graf
From: Andreas Färber afaer...@suse.de

Also move one stray debug output into an #ifdef.

Signed-off-by: Andreas Färber afaer...@suse.de
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/ppc405_boards.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index f74e5e5..807ada0 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -42,7 +42,7 @@
 
 #define USE_FLASH_BIOS
 
-#define DEBUG_BOARD_INIT
+//#define DEBUG_BOARD_INIT
 
 /*/
 /* PPC405EP reference board (IBM) */
@@ -353,9 +353,9 @@ static void ref405ep_init(QEMUMachineInitArgs *args)
 bdloc = 0;
 }
 #ifdef DEBUG_BOARD_INIT
+printf(bdloc  RAM_ADDR_FMT \n, bdloc);
 printf(%s: Done\n, __func__);
 #endif
-printf(bdloc  RAM_ADDR_FMT \n, bdloc);
 }
 
 static QEMUMachine ref405ep_machine = {
-- 
1.8.1.4




[Qemu-devel] [PULL 12/18] target-ppc: Use #define instead of opencoding SLB valid bit

2013-09-02 Thread Alexander Graf
From: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com

Use SLB_ESID_V instead of (1  27) in the code

Reviewed-by: Andreas Färber afaer...@suse.de
Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com
Signed-off-by: Alexander Graf ag...@suse.de
---
 target-ppc/mmu_helper.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-ppc/mmu_helper.c b/target-ppc/mmu_helper.c
index 5dd4e05..9c9132e 100644
--- a/target-ppc/mmu_helper.c
+++ b/target-ppc/mmu_helper.c
@@ -2061,7 +2061,7 @@ void helper_store_sr(CPUPPCState *env, target_ulong 
srnum, target_ulong value)
 /* ESID = srnum */
 rb |= ((uint32_t)srnum  0xf)  28;
 /* Set the valid bit */
-rb |= 1  27;
+rb |= SLB_ESID_V;
 /* Index = ESID */
 rb |= (uint32_t)srnum;
 
-- 
1.8.1.4




[Qemu-devel] [PULL 01/18] PPC: E500: Generate device tree on reset

2013-09-02 Thread Alexander Graf
Today we generate the device tree once on machine initialization and then
store the finalized blob in memory to reload it on reset.

This is bad for 2 reasons. First we potentially waste a bunch of RAM for no
good reason, as we have all information required to regenerate the device
tree available anyways.

The second reason is even more important. On machine init when we generate
the device tree for the first time, we don't have all of the devices fully
initialized yet. But the device tree needs to potentially walk devices to
put information about them into the device tree.

Move the generation into a reset function. That way we just generate it new
every time we reset, solving both of the above issues.

Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/e500.c | 52 +++-
 1 file changed, 43 insertions(+), 9 deletions(-)

diff --git a/hw/ppc/e500.c b/hw/ppc/e500.c
index e79612b..9059ff9 100644
--- a/hw/ppc/e500.c
+++ b/hw/ppc/e500.c
@@ -123,13 +123,14 @@ static void dt_serial_create(void *fdt, unsigned long 
long offset,
 }
 }
 
-static int ppce500_load_device_tree(CPUPPCState *env,
-QEMUMachineInitArgs *args,
+static int ppce500_load_device_tree(QEMUMachineInitArgs *args,
 PPCE500Params *params,
 hwaddr addr,
 hwaddr initrd_base,
-hwaddr initrd_size)
+hwaddr initrd_size,
+bool dry_run)
 {
+CPUPPCState *env = first_cpu-env_ptr;
 int ret = -1;
 uint64_t mem_reg_property[] = { 0, cpu_to_be64(args-ram_size) };
 int fdt_size;
@@ -369,12 +370,10 @@ static int ppce500_load_device_tree(CPUPPCState *env,
 }
 
 done:
-qemu_devtree_dumpdtb(fdt, fdt_size);
-ret = rom_add_blob_fixed(BINARY_DEVICE_TREE_FILE, fdt, fdt_size, addr);
-if (ret  0) {
-goto out;
+if (!dry_run) {
+qemu_devtree_dumpdtb(fdt, fdt_size);
+cpu_physical_memory_write(addr, fdt, fdt_size);
 }
-g_free(fdt);
 ret = fdt_size;
 
 out:
@@ -383,6 +382,41 @@ out:
 return ret;
 }
 
+typedef struct DeviceTreeParams {
+QEMUMachineInitArgs args;
+PPCE500Params params;
+hwaddr addr;
+hwaddr initrd_base;
+hwaddr initrd_size;
+} DeviceTreeParams;
+
+static void ppce500_reset_device_tree(void *opaque)
+{
+DeviceTreeParams *p = opaque;
+ppce500_load_device_tree(p-args, p-params, p-addr, p-initrd_base,
+ p-initrd_size, false);
+}
+
+static int ppce500_prep_device_tree(QEMUMachineInitArgs *args,
+PPCE500Params *params,
+hwaddr addr,
+hwaddr initrd_base,
+hwaddr initrd_size)
+{
+DeviceTreeParams *p = g_new(DeviceTreeParams, 1);
+p-args = *args;
+p-params = *params;
+p-addr = addr;
+p-initrd_base = initrd_base;
+p-initrd_size = initrd_size;
+
+qemu_register_reset(ppce500_reset_device_tree, p);
+
+/* Issue the device tree loader once, so that we get the size of the blob 
*/
+return ppce500_load_device_tree(args, params, addr, initrd_base,
+initrd_size, true);
+}
+
 /* Create -kernel TLB entries for BookE.  */
 static inline hwaddr booke206_page_size_to_tlb(uint64_t size)
 {
@@ -746,7 +780,7 @@ void ppce500_init(QEMUMachineInitArgs *args, PPCE500Params 
*params)
 struct boot_info *boot_info;
 int dt_size;
 
-dt_size = ppce500_load_device_tree(env, args, params, dt_base,
+dt_size = ppce500_prep_device_tree(args, params, dt_base,
initrd_base, initrd_size);
 if (dt_size  0) {
 fprintf(stderr, couldn't load device tree\n);
-- 
1.8.1.4




[Qemu-devel] [PULL 04/18] target-ppc: POWER7 supports the MSR_LE bit

2013-09-02 Thread Alexander Graf
From: Anton Blanchard an...@samba.org

Add MSR_LE to the msr_mask for POWER7.

Signed-off-by: Anton Blanchard an...@samba.org
Reviewed-by: Anthony Liguori aligu...@us.ibm.com
Signed-off-by: Alexander Graf ag...@suse.de
---
 target-ppc/translate_init.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/target-ppc/translate_init.c b/target-ppc/translate_init.c
index 609f797..d2645ba 100644
--- a/target-ppc/translate_init.c
+++ b/target-ppc/translate_init.c
@@ -7227,7 +7227,7 @@ POWERPC_FAMILY(POWER7)(ObjectClass *oc, void *data)
PPC_SEGMENT_64B | PPC_SLBI |
PPC_POPCNTB | PPC_POPCNTWD;
 pcc-insns_flags2 = PPC2_VSX | PPC2_DFP | PPC2_DBRX | PPC2_ISA205;
-pcc-msr_mask = 0x8204FF36ULL;
+pcc-msr_mask = 0x8204FF37ULL;
 pcc-mmu_model = POWERPC_MMU_2_06;
 #if defined(CONFIG_SOFTMMU)
 pcc-handle_mmu_fault = ppc_hash64_handle_mmu_fault;
-- 
1.8.1.4




[Qemu-devel] [PULL 02/18] pseries: Fix stalls on hypervisor virtual console

2013-09-02 Thread Alexander Graf
From: Anton Blanchard an...@samba.org

A number of users are reporting stalls when using the pseries
hypervisor virtual console.

A simple test case is to paste 15 or 17 characters at a time
into the console. Pasting 15 characters at a time works fine
but pasting 17 characters hangs for a random amount of time.
Other activity (network, qemu monitor etc) unblocks it.

If qemu-char tries to send more than 16 characters at once,
vty_can_receive returns false. At this point we have to
wait for the guest to consume that output. Everything is good
so far.

The problem occurs when the the guest does consume the output.
We need to signal back to the qemu-char layer that we are
ready for more input. Without this we block until something
else kicks us (eg network activity).

Signed-off-by: Anton Blanchard an...@samba.org
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/char/spapr_vty.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/hw/char/spapr_vty.c b/hw/char/spapr_vty.c
index a799721..9c2aef8 100644
--- a/hw/char/spapr_vty.c
+++ b/hw/char/spapr_vty.c
@@ -47,6 +47,8 @@ static int vty_getchars(VIOsPAPRDevice *sdev, uint8_t *buf, 
int max)
 buf[n++] = dev-buf[dev-out++ % VTERM_BUFSIZE];
 }
 
+qemu_chr_accept_input(dev-chardev);
+
 return n;
 }
 
-- 
1.8.1.4




[Qemu-devel] [PULL 13/18] spapr-pci: rework MSI/MSIX

2013-09-02 Thread Alexander Graf
From: Alexey Kardashevskiy a...@ozlabs.ru

On the sPAPR platform a guest allocates MSI/MSIX vectors via RTAS
hypercalls which return global IRQ numbers to a guest so it only
operates with those and never touches MSIMessage.

Therefore MSIMessage handling is completely hidden in QEMU.

Previously every sPAPR PCI host bridge implemented its own MSI window
to catch msi_notify()/msix_notify() calls from QEMU devices (virtio-pci
or vfio) and route them to the guest via qemu_pulse_irq().
MSIMessage used to be encoded as:
.addr - address within the PHB MSI window;
.data - the device index on PHB plus vector number.
The MSI MR write function translated this MSIMessage to a global IRQ
number and called qemu_pulse_irq().

However the total number of IRQs is not really big (at the moment it is
1024 IRQs starting from 4096) and even 16bit data field of MSIMessage
seems to be enough to store an IRQ number there.

This simplifies MSI handling in sPAPR PHB. Specifically, this does:
1. remove a MSI window from a PHB;
2. add a single memory region for all MSIs to sPAPREnvironment
and spapr_pci_msi_init() to initialize it;
3. encode MSIMessage as:
* .addr - a fixed address of SPAPR_PCI_MSI_WINDOW==0x400ULL;
* .data as an IRQ number.
4. change IRQ allocator to align first IRQ number in a block for MSI.
MSI uses lower bits to specify the vector number so the first IRQ has to
be aligned. MSIX does not need any special allocator though.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
Reviewed-by: Anthony Liguori aligu...@us.ibm.com
Acked-by: Michael S. Tsirkin m...@redhat.com
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/spapr.c  | 29 ++---
 hw/ppc/spapr_pci.c  | 61 -
 include/hw/pci-host/spapr.h |  8 +++---
 include/hw/ppc/spapr.h  |  4 ++-
 4 files changed, 60 insertions(+), 42 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 4b566aa..1ce9b0b 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -88,6 +88,9 @@ int spapr_allocate_irq(int hint, bool lsi)
 
 if (hint) {
 irq = hint;
+if (hint = spapr-next_irq) {
+spapr-next_irq = hint + 1;
+}
 /* FIXME: we should probably check for collisions somehow */
 } else {
 irq = spapr-next_irq++;
@@ -103,22 +106,39 @@ int spapr_allocate_irq(int hint, bool lsi)
 return irq;
 }
 
-/* Allocate block of consequtive IRQs, returns a number of the first */
-int spapr_allocate_irq_block(int num, bool lsi)
+/*
+ * Allocate block of consequtive IRQs, returns a number of the first.
+ * If msi==true, aligns the first IRQ number to num.
+ */
+int spapr_allocate_irq_block(int num, bool lsi, bool msi)
 {
 int first = -1;
-int i;
+int i, hint = 0;
+
+/*
+ * MSIMesage::data is used for storing VIRQ so
+ * it has to be aligned to num to support multiple
+ * MSI vectors. MSI-X is not affected by this.
+ * The hint is used for the first IRQ, the rest should
+ * be allocated continously.
+ */
+if (msi) {
+assert((num == 1) || (num == 2) || (num == 4) ||
+   (num == 8) || (num == 16) || (num == 32));
+hint = (spapr-next_irq + num - 1)  ~(num - 1);
+}
 
 for (i = 0; i  num; ++i) {
 int irq;
 
-irq = spapr_allocate_irq(0, lsi);
+irq = spapr_allocate_irq(hint, lsi);
 if (!irq) {
 return -1;
 }
 
 if (0 == i) {
 first = irq;
+hint = 0;
 }
 
 /* If the above doesn't create a consecutive block then that's
@@ -1214,6 +1234,7 @@ static void ppc_spapr_init(QEMUMachineInitArgs *args)
 spapr_create_nvram(spapr);
 
 /* Set up PCI */
+spapr_pci_msi_init(spapr, SPAPR_PCI_MSI_WINDOW);
 spapr_pci_rtas_init();
 
 phb = spapr_create_phb(spapr, 0);
diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 65be265..9b6ee32 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -250,11 +250,11 @@ static int spapr_msicfg_find(sPAPRPHBState *phb, uint32_t 
config_addr,
  * This is required for msi_notify()/msix_notify() which
  * will write at the addresses via spapr_msi_write().
  */
-static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr,
- bool msix, unsigned req_num)
+static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr, bool msix,
+ unsigned first_irq, unsigned req_num)
 {
 unsigned i;
-MSIMessage msg = { .address = addr, .data = 0 };
+MSIMessage msg = { .address = addr, .data = first_irq };
 
 if (!msix) {
 msi_set_message(pdev, msg);
@@ -262,8 +262,7 @@ static void spapr_msi_setmsg(PCIDevice *pdev, hwaddr addr,
 return;
 }
 
-for (i = 0; i  req_num; ++i) {
-msg.address = addr | (i  2);
+for (i = 0; i  req_num; ++i, ++msg.data) {
 msix_set_message(pdev, i, msg);
 

[Qemu-devel] [PULL 15/18] pseries: Add H_SET_MODE hcall to change guest exception endianness

2013-09-02 Thread Alexander Graf
From: Anton Blanchard an...@samba.org

H_SET_MODE is used for controlling various partition settings. One
of these settings is the endianness a guest takes its exceptions in.

Signed-off-by: Anton Blanchard an...@samba.org
[agraf: fix whitespace]
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/spapr.c |  2 +-
 hw/ppc/spapr_hcall.c   | 50 ++
 include/hw/ppc/spapr.h | 17 -
 3 files changed, 67 insertions(+), 2 deletions(-)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 1ce9b0b..04f0ee3 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -282,7 +282,7 @@ static void *spapr_create_fdt_skel(const char *cpu_model,
 uint32_t start_prop = cpu_to_be32(initrd_base);
 uint32_t end_prop = cpu_to_be32(initrd_base + initrd_size);
 char hypertas_prop[] = hcall-pft\0hcall-term\0hcall-dabr\0hcall-interrupt
-\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk;
+\0hcall-tce\0hcall-vio\0hcall-splpar\0hcall-bulk\0hcall-set-mode;
 char qemu_hypertas_prop[] = hcall-memop1;
 uint32_t refpoints[] = {cpu_to_be32(0x4), cpu_to_be32(0x4)};
 uint32_t interrupt_server_ranges_prop[] = {0, cpu_to_be32(smp_cpus)};
diff --git a/hw/ppc/spapr_hcall.c b/hw/ppc/spapr_hcall.c
index 67d6cd9..89e6a00 100644
--- a/hw/ppc/spapr_hcall.c
+++ b/hw/ppc/spapr_hcall.c
@@ -657,6 +657,54 @@ static target_ulong h_logical_dcbf(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
 return H_SUCCESS;
 }
 
+static target_ulong h_set_mode(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+   target_ulong opcode, target_ulong *args)
+{
+CPUState *cs;
+target_ulong mflags = args[0];
+target_ulong resource = args[1];
+target_ulong value1 = args[2];
+target_ulong value2 = args[3];
+target_ulong ret = H_P2;
+
+if (resource == H_SET_MODE_ENDIAN) {
+if (value1) {
+ret = H_P3;
+goto out;
+}
+if (value2) {
+ret = H_P4;
+goto out;
+}
+
+switch (mflags) {
+case H_SET_MODE_ENDIAN_BIG:
+for (cs = first_cpu; cs != NULL; cs = cs-next_cpu) {
+PowerPCCPU *cp = POWERPC_CPU(cs);
+CPUPPCState *env = cp-env;
+env-spr[SPR_LPCR] = ~LPCR_ILE;
+}
+ret = H_SUCCESS;
+break;
+
+case H_SET_MODE_ENDIAN_LITTLE:
+for (cs = first_cpu; cs != NULL; cs = cs-next_cpu) {
+PowerPCCPU *cp = POWERPC_CPU(cs);
+CPUPPCState *env = cp-env;
+env-spr[SPR_LPCR] |= LPCR_ILE;
+}
+ret = H_SUCCESS;
+break;
+
+default:
+ret = H_UNSUPPORTED_FLAG;
+}
+}
+
+out:
+return ret;
+}
+
 static spapr_hcall_fn papr_hypercall_table[(MAX_HCALL_OPCODE / 4) + 1];
 static spapr_hcall_fn kvmppc_hypercall_table[KVMPPC_HCALL_MAX - 
KVMPPC_HCALL_BASE + 1];
 
@@ -734,6 +782,8 @@ static void hypercall_register_types(void)
 
 /* qemu/KVM-PPC specific hcalls */
 spapr_register_hypercall(KVMPPC_H_RTAS, h_rtas);
+
+spapr_register_hypercall(H_SET_MODE, h_set_mode);
 }
 
 type_init(hypercall_register_types)
diff --git a/include/hw/ppc/spapr.h b/include/hw/ppc/spapr.h
index 41b0466..e37b419 100644
--- a/include/hw/ppc/spapr.h
+++ b/include/hw/ppc/spapr.h
@@ -111,6 +111,15 @@ typedef struct sPAPREnvironment {
 #define H_NOT_ENOUGH_RESOURCES -44
 #define H_R_STATE -45
 #define H_RESCINDEND  -46
+#define H_P2  -55
+#define H_P3  -56
+#define H_P4  -57
+#define H_P5  -58
+#define H_P6  -59
+#define H_P7  -60
+#define H_P8  -61
+#define H_P9  -62
+#define H_UNSUPPORTED_FLAG -256
 #define H_MULTI_THREADS_ACTIVE -9005
 
 
@@ -145,6 +154,11 @@ typedef struct sPAPREnvironment {
 #define H_PP1 (1ULL(63-62))
 #define H_PP2 (1ULL(63-63))
 
+/* H_SET_MODE flags */
+#define H_SET_MODE_ENDIAN4
+#define H_SET_MODE_ENDIAN_BIG0
+#define H_SET_MODE_ENDIAN_LITTLE 1
+
 /* VASI States */
 #define H_VASI_INVALID0
 #define H_VASI_ENABLED1
@@ -269,7 +283,8 @@ typedef struct sPAPREnvironment {
 #define H_GET_EM_PARMS  0x2B8
 #define H_SET_MPP   0x2D0
 #define H_GET_MPP   0x2D4
-#define MAX_HCALL_OPCODEH_GET_MPP
+#define H_SET_MODE  0x31C
+#define MAX_HCALL_OPCODEH_SET_MODE
 
 /* The hcalls above are standardized in PAPR and implemented by pHyp
  * as well.
-- 
1.8.1.4




[Qemu-devel] [PULL 17/18] spapr: add stop-self RTAS call required to support hot CPU unplug

2013-09-02 Thread Alexander Graf
From: Alexey Kardashevskiy a...@ozlabs.ru

PAPR+ requires two RTAS calls to be supported by the hypervisor in
order to allow hotplugging VCPUs from the guest. The start-cpu RTAS
call was already there but stop-self was not.

This adds the stop-self RTAS call.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/spapr_rtas.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/hw/ppc/spapr_rtas.c b/hw/ppc/spapr_rtas.c
index 394ce05..eb542f2 100644
--- a/hw/ppc/spapr_rtas.c
+++ b/hw/ppc/spapr_rtas.c
@@ -202,6 +202,28 @@ static void rtas_start_cpu(PowerPCCPU *cpu_, 
sPAPREnvironment *spapr,
 rtas_st(rets, 0, -3);
 }
 
+static void rtas_stop_self(PowerPCCPU *cpu, sPAPREnvironment *spapr,
+   uint32_t token, uint32_t nargs,
+   target_ulong args,
+   uint32_t nret, target_ulong rets)
+{
+CPUState *cs = CPU(cpu);
+CPUPPCState *env = cpu-env;
+
+cs-halted = 1;
+cpu_exit(cs);
+/*
+ * While stopping a CPU, the guest calls H_CPPR which
+ * effectively disables interrupts on XICS level.
+ * However decrementer interrupts in TCG can still
+ * wake the CPU up so here we disable interrupts in MSR
+ * as well.
+ * As rtas_start_cpu() resets the whole MSR anyway, there is
+ * no need to bother with specific bits, we just clear it.
+ */
+env-msr = 0;
+}
+
 static struct rtas_call {
 const char *name;
 spapr_rtas_fn fn;
@@ -322,6 +344,7 @@ static void core_rtas_register_types(void)
 spapr_rtas_register(query-cpu-stopped-state,
 rtas_query_cpu_stopped_state);
 spapr_rtas_register(start-cpu, rtas_start_cpu);
+spapr_rtas_register(stop-self, rtas_stop_self);
 }
 
 type_init(core_rtas_register_types)
-- 
1.8.1.4




[Qemu-devel] [PULL 03/18] target-ppc: USE LPCR_ILE to control exception endian on POWER7

2013-09-02 Thread Alexander Graf
From: Anton Blanchard an...@samba.org

On POWER7, LPCR_ILE is used to control what endian guests take
their exceptions in so use it instead of MSR_ILE.

Signed-off-by: Anton Blanchard an...@samba.org
Reviewed-by: Anthony Liguori aligu...@us.ibm.com
Signed-off-by: Alexander Graf ag...@suse.de
---
 target-ppc/cpu.h |  2 ++
 target-ppc/excp_helper.c | 10 ++
 2 files changed, 12 insertions(+)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index 711db08..422a6bb 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -453,6 +453,8 @@ struct ppc_slb_t {
 #define MSR_RI   1  /* Recoverable interrupt1*/
 #define MSR_LE   0  /* Little-endian mode   1 hflags */
 
+#define LPCR_ILE (1  (63-38))
+
 #define msr_sf   ((env-msr  MSR_SF)1)
 #define msr_isf  ((env-msr  MSR_ISF)   1)
 #define msr_shv  ((env-msr  MSR_SHV)   1)
diff --git a/target-ppc/excp_helper.c b/target-ppc/excp_helper.c
index e9fcad8..e957761 100644
--- a/target-ppc/excp_helper.c
+++ b/target-ppc/excp_helper.c
@@ -611,9 +611,19 @@ static inline void powerpc_excp(PowerPCCPU *cpu, int 
excp_model, int excp)
 tlb_flush(env, 1);
 }
 
+#ifdef TARGET_PPC64
+if (excp_model == POWERPC_EXCP_POWER7) {
+if (env-spr[SPR_LPCR]  LPCR_ILE) {
+new_msr |= (target_ulong)1  MSR_LE;
+}
+} else if (msr_ile) {
+new_msr |= (target_ulong)1  MSR_LE;
+}
+#else
 if (msr_ile) {
 new_msr |= (target_ulong)1  MSR_LE;
 }
+#endif
 
 /* Jump to handler */
 vector = env-excp_vectors[excp];
-- 
1.8.1.4




[Qemu-devel] [PULL 09/18] ppc405_boards: Don't enforce presence of firmware for qtest

2013-09-02 Thread Alexander Graf
From: Andreas Färber afaer...@suse.de

Adopt error_report() while at it.

Signed-off-by: Andreas Färber afaer...@suse.de
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/ppc405_boards.c | 35 ---
 1 file changed, 20 insertions(+), 15 deletions(-)

diff --git a/hw/ppc/ppc405_boards.c b/hw/ppc/ppc405_boards.c
index 807ada0..75b2177 100644
--- a/hw/ppc/ppc405_boards.c
+++ b/hw/ppc/ppc405_boards.c
@@ -27,9 +27,11 @@
 #include hw/timer/m48t59.h
 #include hw/block/flash.h
 #include sysemu/sysemu.h
+#include sysemu/qtest.h
 #include block/block.h
 #include hw/boards.h
 #include qemu/log.h
+#include qemu/error-report.h
 #include hw/loader.h
 #include sysemu/blockdev.h
 #include exec/address-spaces.h
@@ -252,17 +254,20 @@ static void ref405ep_init(QEMUMachineInitArgs *args)
 if (filename) {
 bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
 g_free(filename);
+if (bios_size  0 || bios_size  BIOS_SIZE) {
+error_report(Could not load PowerPC BIOS '%s', bios_name);
+exit(1);
+}
+bios_size = (bios_size + 0xfff)  ~0xfff;
+memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
+} else if (!qtest_enabled() || kernel_filename != NULL) {
+error_report(Could not load PowerPC BIOS '%s', bios_name);
+exit(1);
 } else {
+/* Avoid an uninitialized variable warning */
 bios_size = -1;
 }
-if (bios_size  0 || bios_size  BIOS_SIZE) {
-fprintf(stderr, qemu: could not load PowerPC bios '%s'\n,
-bios_name);
-exit(1);
-}
-bios_size = (bios_size + 0xfff)  ~0xfff;
 memory_region_set_readonly(bios, true);
-memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
 }
 /* Register FPGA */
 #ifdef DEBUG_BOARD_INIT
@@ -569,17 +574,17 @@ static void taihu_405ep_init(QEMUMachineInitArgs *args)
 if (filename) {
 bios_size = load_image(filename, memory_region_get_ram_ptr(bios));
 g_free(filename);
-} else {
-bios_size = -1;
-}
-if (bios_size  0 || bios_size  BIOS_SIZE) {
-fprintf(stderr, qemu: could not load PowerPC bios '%s'\n,
-bios_name);
+if (bios_size  0 || bios_size  BIOS_SIZE) {
+error_report(Could not load PowerPC BIOS '%s', bios_name);
+exit(1);
+}
+bios_size = (bios_size + 0xfff)  ~0xfff;
+memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
+} else if (!qtest_enabled()) {
+error_report(Could not load PowerPC BIOS '%s', bios_name);
 exit(1);
 }
-bios_size = (bios_size + 0xfff)  ~0xfff;
 memory_region_set_readonly(bios, true);
-memory_region_add_subregion(sysmem, (uint32_t)(-bios_size), bios);
 }
 /* Register Linux flash */
 dinfo = drive_get(IF_PFLASH, 0, fl_idx);
-- 
1.8.1.4




[Qemu-devel] [PULL 14/18] xics: move registration of global state to realize()

2013-09-02 Thread Alexander Graf
From: Alexey Kardashevskiy a...@ozlabs.ru

Registration of global state belongs into realize so move it there.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
Reviewed-by: Andreas Färber afaer...@suse.de
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/intc/xics.c | 21 +++--
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/hw/intc/xics.c b/hw/intc/xics.c
index 6b3c071..31868c4 100644
--- a/hw/intc/xics.c
+++ b/hw/intc/xics.c
@@ -642,6 +642,17 @@ static void xics_realize(DeviceState *dev, Error **errp)
 ICSState *ics = icp-ics;
 int i;
 
+/* Registration of global state belongs into realize */
+spapr_rtas_register(ibm,set-xive, rtas_set_xive);
+spapr_rtas_register(ibm,get-xive, rtas_get_xive);
+spapr_rtas_register(ibm,int-off, rtas_int_off);
+spapr_rtas_register(ibm,int-on, rtas_int_on);
+
+spapr_register_hypercall(H_CPPR, h_cppr);
+spapr_register_hypercall(H_IPI, h_ipi);
+spapr_register_hypercall(H_XIRR, h_xirr);
+spapr_register_hypercall(H_EOI, h_eoi);
+
 ics-nr_irqs = icp-nr_irqs;
 ics-offset = XICS_IRQ_BASE;
 ics-icp = icp;
@@ -678,16 +689,6 @@ static void xics_class_init(ObjectClass *oc, void *data)
 dc-realize = xics_realize;
 dc-props = xics_properties;
 dc-reset = xics_reset;
-
-spapr_rtas_register(ibm,set-xive, rtas_set_xive);
-spapr_rtas_register(ibm,get-xive, rtas_get_xive);
-spapr_rtas_register(ibm,int-off, rtas_int_off);
-spapr_rtas_register(ibm,int-on, rtas_int_on);
-
-spapr_register_hypercall(H_CPPR, h_cppr);
-spapr_register_hypercall(H_IPI, h_ipi);
-spapr_register_hypercall(H_XIRR, h_xirr);
-spapr_register_hypercall(H_EOI, h_eoi);
 }
 
 static const TypeInfo xics_info = {
-- 
1.8.1.4




[Qemu-devel] [PULL 11/18] spapr-pci: fix config space access to support bridges

2013-09-02 Thread Alexander Graf
From: Alexey Kardashevskiy a...@ozlabs.ru

spapr-pci config space accessors use find_dev() to find a PCI device.
However find_dev() only searched on a primary bus and did not do
recursive search through secondary buses so config space access was not
possible for devices other that on a primary bus.

This fixed find_dev() by using the PCI API pci_find_device() function.
This effectively enabled pci bridges on spapr.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
Acked-by: Michael S. Tsirkin m...@redhat.com
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/spapr_pci.c | 12 ++--
 1 file changed, 2 insertions(+), 10 deletions(-)

diff --git a/hw/ppc/spapr_pci.c b/hw/ppc/spapr_pci.c
index 1ca35a0..65be265 100644
--- a/hw/ppc/spapr_pci.c
+++ b/hw/ppc/spapr_pci.c
@@ -65,22 +65,14 @@ static PCIDevice *find_dev(sPAPREnvironment *spapr, 
uint64_t buid,
 {
 sPAPRPHBState *sphb = find_phb(spapr, buid);
 PCIHostState *phb = PCI_HOST_BRIDGE(sphb);
-BusState *bus = BUS(phb-bus);
-BusChild *kid;
+int bus_num = (config_addr  16)  0xFF;
 int devfn = (config_addr  8)  0xFF;
 
 if (!phb) {
 return NULL;
 }
 
-QTAILQ_FOREACH(kid, bus-children, sibling) {
-PCIDevice *dev = (PCIDevice *)kid-child;
-if (dev-devfn == devfn) {
-return dev;
-}
-}
-
-return NULL;
+return pci_find_device(phb-bus, bus_num, devfn);
 }
 
 static uint32_t rtas_pci_cfgaddr(uint32_t arg)
-- 
1.8.1.4




[Qemu-devel] [PULL 18/18] PPC: spapr: iommu: rework traces

2013-09-02 Thread Alexander Graf
From: Alexey Kardashevskiy a...@ozlabs.ru

This converts old style fprintf to traces.

Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
[agraf: change patch subject]
Signed-off-by: Alexander Graf ag...@suse.de
---
 hw/ppc/spapr_iommu.c | 71 ++--
 trace-events |  5 
 2 files changed, 29 insertions(+), 47 deletions(-)

diff --git a/hw/ppc/spapr_iommu.c b/hw/ppc/spapr_iommu.c
index 3d4a1fc..ef45f4f 100644
--- a/hw/ppc/spapr_iommu.c
+++ b/hw/ppc/spapr_iommu.c
@@ -22,13 +22,12 @@
 #include kvm_ppc.h
 #include sysemu/dma.h
 #include exec/address-spaces.h
+#include trace.h
 
 #include hw/ppc/spapr.h
 
 #include libfdt.h
 
-/* #define DEBUG_TCE */
-
 enum sPAPRTCEAccess {
 SPAPR_TCE_FAULT = 0,
 SPAPR_TCE_RO = 1,
@@ -61,44 +60,28 @@ static IOMMUTLBEntry spapr_tce_translate_iommu(MemoryRegion 
*iommu, hwaddr addr)
 {
 sPAPRTCETable *tcet = container_of(iommu, sPAPRTCETable, iommu);
 uint64_t tce;
-
-#ifdef DEBUG_TCE
-fprintf(stderr, spapr_tce_translate liobn=0x% PRIx32  addr=0x
-DMA_ADDR_FMT \n, tcet-liobn, addr);
-#endif
+IOMMUTLBEntry ret = {
+.target_as = address_space_memory,
+.iova = 0,
+.translated_addr = 0,
+.addr_mask = ~(hwaddr)0,
+.perm = IOMMU_NONE,
+};
 
 if (tcet-bypass) {
-return (IOMMUTLBEntry) {
-.target_as = address_space_memory,
-.iova = 0,
-.translated_addr = 0,
-.addr_mask = ~(hwaddr)0,
-.perm = IOMMU_RW,
-};
-}
-
-/* Check if we are in bound */
-if (addr = tcet-window_size) {
-#ifdef DEBUG_TCE
-fprintf(stderr, spapr_tce_translate out of bounds\n);
-#endif
-return (IOMMUTLBEntry) { .perm = IOMMU_NONE };
+ret.perm = IOMMU_RW;
+} else if (addr  tcet-window_size) {
+/* Check if we are in bound */
+tce = tcet-table[addr  SPAPR_TCE_PAGE_SHIFT];
+ret.iova = addr  ~SPAPR_TCE_PAGE_MASK;
+ret.translated_addr = tce  ~SPAPR_TCE_PAGE_MASK;
+ret.addr_mask = SPAPR_TCE_PAGE_MASK;
+ret.perm = tce;
 }
+trace_spapr_iommu_xlate(tcet-liobn, addr, ret.iova, ret.perm,
+ret.addr_mask);
 
-tce = tcet-table[addr  SPAPR_TCE_PAGE_SHIFT];
-
-#ifdef DEBUG_TCE
-fprintf(stderr,  -  *paddr=0x%llx, *len=0x%llx\n,
-(tce  ~SPAPR_TCE_PAGE_MASK), SPAPR_TCE_PAGE_MASK + 1);
-#endif
-
-return (IOMMUTLBEntry) {
-.target_as = address_space_memory,
-.iova = addr  ~SPAPR_TCE_PAGE_MASK,
-.translated_addr = tce  ~SPAPR_TCE_PAGE_MASK,
-.addr_mask = SPAPR_TCE_PAGE_MASK,
-.perm = tce,
-};
+return ret;
 }
 
 static int spapr_tce_table_pre_load(void *opaque)
@@ -150,10 +133,7 @@ static int spapr_tce_table_realize(DeviceState *dev)
 }
 tcet-nb_table = tcet-window_size  SPAPR_TCE_PAGE_SHIFT;
 
-#ifdef DEBUG_TCE
-fprintf(stderr, spapr_iommu: New TCE table @ %p, liobn=0x%x, 
-table @ %p, fd=%d\n, tcet, liobn, tcet-table, tcet-fd);
-#endif
+trace_spapr_iommu_new_table(tcet-liobn, tcet, tcet-table, tcet-fd);
 
 memory_region_init_iommu(tcet-iommu, OBJECT(dev), spapr_iommu_ops,
  iommu-spapr, UINT64_MAX);
@@ -250,20 +230,17 @@ static target_ulong h_put_tce(PowerPCCPU *cpu, 
sPAPREnvironment *spapr,
 target_ulong liobn = args[0];
 target_ulong ioba = args[1];
 target_ulong tce = args[2];
+target_ulong ret = H_PARAMETER;
 sPAPRTCETable *tcet = spapr_tce_find_by_liobn(liobn);
 
 ioba = ~(SPAPR_TCE_PAGE_SIZE - 1);
 
 if (tcet) {
-return put_tce_emu(tcet, ioba, tce);
+ret = put_tce_emu(tcet, ioba, tce);
 }
-#ifdef DEBUG_TCE
-fprintf(stderr, %s on liobn= TARGET_FMT_lx /*%s*/
-  ioba 0x TARGET_FMT_lx   TCE 0x TARGET_FMT_lx \n,
-__func__, liobn, /*dev-qdev.id, */ioba, tce);
-#endif
+trace_spapr_iommu_put(liobn, ioba, tce, ret);
 
-return H_PARAMETER;
+return ret;
 }
 
 int spapr_dma_dt(void *fdt, int node_off, const char *propname,
diff --git a/trace-events b/trace-events
index 3856b5c..aaad356 100644
--- a/trace-events
+++ b/trace-events
@@ -1133,6 +1133,11 @@ xics_ics_write_xive(int nr, int srcno, int server, 
uint8_t priority) ics_write_
 xics_ics_reject(int nr, int srcno) reject irq %#x [src %d]
 xics_ics_eoi(int nr) ics_eoi: irq %#x
 
+# hw/ppc/spapr_iommu.c
+spapr_iommu_put(uint64_t liobn, uint64_t ioba, uint64_t tce, uint64_t ret) 
liobn=%PRIx64 ioba=0x%PRIx64 tce=0x%PRIx64 ret=%PRId64
+spapr_iommu_xlate(uint64_t liobn, uint64_t ioba, uint64_t tce, unsigned perm, 
unsigned pgsize) liobn=%PRIx64 0x%PRIx64 - 0x%PRIx64 perm=%u mask=%x
+spapr_iommu_new_table(uint64_t liobn, void *tcet, void *table, int fd) 
liobn=%PRIx64 tcet=%p table=%p fd=%d
+
 # util/hbitmap.c
 hbitmap_iter_skip_words(const void *hb, void *hbi, uint64_t pos, unsigned long 
cur) hb %p hbi %p pos %PRId64 cur 0x%lx
 hbitmap_reset(void 

Re: [Qemu-devel] [PULL 00/26] Block patches

2013-09-02 Thread Kevin Wolf
Am 30.08.2013 um 19:14 hat Anthony Liguori geschrieben:
 This pull request breaks make check, qemu-system-i386 segvs when
 running qtest.  bisect blames the following commit.  I confirmed this
 commit introduces the breakage too.
 
 commit 19abade25242079f4b5582de17b2302fe185be2b
 Author: Max Reitz mre...@redhat.com
 Date:   Fri Aug 30 14:34:29 2013 +0200
 
 qcow2-refcount: Repair shared refcount blocks
 
 If the refcount of a refcount block is greater than one, we can at least
 try to repair that problem by duplicating the affected block.
 
 Signed-off-by: Max Reitz mre...@redhat.com
 Signed-off-by: Kevin Wolf kw...@redhat.com

Sorry, seems I messed up here. The shell history shows that I did
run 'make check', but somehow the failure must have escaped my
attention (it's not an assertion failure and we do have some noise
in successful runs, maybe that's why)

The other test case that could have caught it (qemu-iotests 026) has
been broken for ages, and we need to finally fix it.

Thanks for catching this, Anthony. I'll send a v2.

Kevin



Re: [Qemu-devel] [PATCH] target-i386: Only provide CMOV and friends if feature bit set

2013-09-02 Thread Peter Maydell
Ping^3!

thanks
-- PMM

On 20 August 2013 13:59, Peter Maydell peter.mayd...@linaro.org wrote:
 Ping^2! This has been reviewed and I've checked that the
 patch still applies to master.

 thanks
 -- PMM

 On 25 July 2013 17:54, Peter Maydell peter.mayd...@linaro.org wrote:
 Ping!

 (patchwork url: http://patchwork.ozlabs.org/patch/259148/)

 thanks
 -- PMM

 On 15 July 2013 18:21, Peter Maydell peter.mayd...@linaro.org wrote:
 The instructions CMOVcc, FCMOVcc and F[U]COMI[P] should only be
 present if the CMOV feature bit is set. Add missing feature bit
 checks so we correctly fault if emulating a 486 or 586.
 This fixes bug LP:1201446.

 Signed-off-by: Peter Maydell peter.mayd...@linaro.org
 ---
  target-i386/translate.c |   19 +++
  1 file changed, 19 insertions(+)

 diff --git a/target-i386/translate.c b/target-i386/translate.c
 index 6550c27..f75e3b1 100644
 --- a/target-i386/translate.c
 +++ b/target-i386/translate.c
 @@ -6434,12 +6434,18 @@ static target_ulong disas_insn(CPUX86State *env, 
 DisasContext *s,
  }
  break;
  case 0x1d: /* fucomi */
 +if (!(s-cpuid_features  CPUID_CMOV)) {
 +goto illegal_op;
 +}
  gen_update_cc_op(s);
  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
  gen_helper_fucomi_ST0_FT0(cpu_env);
  set_cc_op(s, CC_OP_EFLAGS);
  break;
  case 0x1e: /* fcomi */
 +if (!(s-cpuid_features  CPUID_CMOV)) {
 +goto illegal_op;
 +}
  gen_update_cc_op(s);
  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
  gen_helper_fcomi_ST0_FT0(cpu_env);
 @@ -6495,6 +6501,9 @@ static target_ulong disas_insn(CPUX86State *env, 
 DisasContext *s,
  }
  break;
  case 0x3d: /* fucomip */
 +if (!(s-cpuid_features  CPUID_CMOV)) {
 +goto illegal_op;
 +}
  gen_update_cc_op(s);
  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
  gen_helper_fucomi_ST0_FT0(cpu_env);
 @@ -6502,6 +6511,9 @@ static target_ulong disas_insn(CPUX86State *env, 
 DisasContext *s,
  set_cc_op(s, CC_OP_EFLAGS);
  break;
  case 0x3e: /* fcomip */
 +if (!(s-cpuid_features  CPUID_CMOV)) {
 +goto illegal_op;
 +}
  gen_update_cc_op(s);
  gen_helper_fmov_FT0_STN(cpu_env, tcg_const_i32(opreg));
  gen_helper_fcomi_ST0_FT0(cpu_env);
 @@ -6518,6 +6530,10 @@ static target_ulong disas_insn(CPUX86State *env, 
 DisasContext *s,
  (JCC_BE  1),
  (JCC_P  1),
  };
 +
 +if (!(s-cpuid_features  CPUID_CMOV)) {
 +goto illegal_op;
 +}
  op1 = fcmov_cc[op  3] | (((op  3)  1) ^ 1);
  l1 = gen_new_label();
  gen_jcc1_noeob(s, op1, l1);
 @@ -6889,6 +6905,9 @@ static target_ulong disas_insn(CPUX86State *env, 
 DisasContext *s,
  gen_ldst_modrm(env, s, modrm, OT_BYTE, OR_TMP0, 1);
  break;
  case 0x140 ... 0x14f: /* cmov Gv, Ev */
 +if (!(s-cpuid_features  CPUID_CMOV)) {
 +goto illegal_op;
 +}
  ot = dflag + OT_WORD;
  modrm = cpu_ldub_code(env, s-pc++);
  reg = ((modrm  3)  7) | rex_r;
 --
 1.7.9.5





-- 
12345678901234567890123456789012345678901234567890123456789012345678901234567890
 1 2 3 4 5 6 7 8



Re: [Qemu-devel] [PATCH v2] pseries: Update SLOF firmware image

2013-09-02 Thread Alexander Graf

On 28.08.2013, at 09:42, Alexey Kardashevskiy wrote:

 On 08/27/2013 06:33 PM, Alexander Graf wrote:
 
 On 27.08.2013, at 05:42, Alexey Kardashevskiy wrote:
 
 This has reworked USB OHCI and adds support of USB EHCI,
 VIRTIO-SCSI and various fixes (IBM VSCSI, VGA and more).
 
 The full list of fixes is:
 *  usb-ohci: Convert td-phys every time to td-virt
 *  usb-storage: Fix cbwflags field
 *  Add -fno-strict-aliasing in global CFLAGS
 *  usb: fix various issues found with js2x
 *  Move hex64-{decode,encode}-unit to node.fs
 *  usb: Use separate in-memory endian swap
 *  usb-ohci: collect TDs from done list
 *  js2x: more fixes
 *  js2x: Fix build of takeover image
 *  js2x: use new usb stack
 *  usb-ohci: Use proper memory barriers always
 *  usb: Fix a couple of warnings
 *  Fix $cat-instance-unit
 *  Cache phandle of /chosen
 *  Use root.fs on qemu as well
 *  usb-ehci: Add ehci handshake
 *  usb: add mb for write accessors
 *  usb-ohci: add missing memory barriers
 *  usb-ohci: suspend the controller in exit code path
 *  usb-ohci: Add a reset when closing the OHCI
 *  usb: Use proper accessors for MMIO and separate in-memory endian swap
 *  Use a global definition of sync() and mb()
 *  net-snk: Remove exception handling
 *  usb: unmap buffers
 *  slof: call quiesce on closing of stdin
 *  usb-kbd: accept s to drop to OF prompt
 *  USB storage driver
 *  usb-ohci: add Bulk transfer support
 *  usb-ehci: Add bulk support
 *  usb-core: add usb bulk support
 *  USB generic hub device driver
 *  usb-ehci: setup new device
 *  usb-ehci: Check ehci ports
 *  usb-ehci: initialize controller
 *  USB keyboard driver
 *  usb-core: setup new device
 *  usb-core: create dev pool allocation
 *  usb-ohci: implement ohci send control
 *  usb-core: usb send control
 *  usb-core: implement usb_{get,put}_pipe routines
 *  usb-ohci: allocate pipe pool
 *  usb-ohci: reset, init and check-ports
 *  Add standard header stdbool.h
 *  usb-slof: forth support routines for C
 *  usb-ehci: Add USB EHCI skeleton
 *  usb-core: Add register accessor functions
 *  Use __builtin_bswap routines for endianness swapping
 *  usb-core: hcd registration and query routines
 *  usb-core: adding generic dev-hci.fs
 *  usb-core: registration and makefiles
 *  Add new USB code
 *  Remove old usb code
 *  vga: fix hcall-invert-screen and hcall-blink-screen
 *  Enumerate disk/cdrom aliases for multiple disks or cdroms
 *  scsi: unify scsi probing code
 *  vscsi: generalizing probe code
 *  virtio-scsi: iterate through targets
 *  scsi: unify and use make-disk-alias
 *  nvram: remove unnecessary prints
 *  Add hack to client interface finddevice of /memory
 *  scsi: Fix cdrom boot crash when no medium present
 *  Look for /memory@0, not just /memory
 *  Fix instanceqname crashing when displaying instance arguments
 *  Fix js2x build
 *  scsi-disk: Bound check read-blocks
 *  Fix off by one error in scsi-disk get-capacity
 *  scsi: fix report-luns handling
 *  SLOF: virtio-scsi block driver code
 *  scsi: Move bits of vio-vscsi.fs to a common helpers file
 *  scsi: Move scsi-disk.fs to a generic place
 *  SLOF: virtio-scsi helper routines
 *  SLOF: virtio-scsi - add pci device file
 *  iso9660: Don't constantly reallocate the read buffer
 *  vscsi: Sanitize interface between scsi-disk.fs and vio-vscsi.fs
 *  vio-vscsi: Rework vio-vscsi support
 *  virtio: Add a virtio-set-qaddr helper
 *  disk-label: Allocate 4096 bytes for 4k block devices
 *  disk-label: Increase the max size of the PReP boot partition
 *  Make load-base a real environment variable
 *  vio-vscsi: Switch to using a wildcard disk node and make scsi-disk 
 generic
 *  Fix disk-label package to use proper instance path
 *  Increase size of catpad
 *  Fix instancepath to contain unit address for wildcard nodes
 *  Fix handling of wildcard nodes in open-dev
 *  vio-vscsi: Get CRQ on open and release on close
 
 Cc: Benjamin Herrenschmidt b...@kernel.crashing.org
 Cc: Nikunj A Dadhania nik...@linux.vnet.ibm.com
 Signed-off-by: Alexey Kardashevskiy a...@ozlabs.ru
 
 ---
 Changes:
 v2:
 * added 2 patches on top
 ---
 pc-bios/README   |   2 +-
 pc-bios/slof.bin | Bin 909720 - 875424 bytes
 roms/SLOF|   2 +-
 
 For this to work we also need to update the SLOF copy at git.qemu.org. 
 Anthony, could you please do that?
 
 
 Checked - it is there. What is the next step to get it in upstream?

Pinging me :). Thanks, applied to ppc-next.


Alex




[Qemu-devel] [PULL v2 00/26] Block patches

2013-09-02 Thread Kevin Wolf
The following changes since commit b5d54bd42158b90b239bb6ce9c13072eb3a53fd2:

  Merge remote-tracking branch 'qemu-kvm/uq/master' into stable-1.5 (2013-08-29 
17:21:51 -0500)

are available in the git repository at:


  git://repo.or.cz/qemu/kevin.git for-anthony

for you to fetch changes up to ca0eca91b65c34d6e5f5c77d5c18ed3de5b26139:

  qemu-iotests: Overlapping cluster allocations (2013-09-02 10:15:15 +0200)


Bharata B Rao (1):
  gluster: Abort on AIO completion failure

Kevin Wolf (6):
  qcow2: Change default for new images to compat=1.1
  block: Remove redundant assertion
  qapi-types.py: Split off generate_struct_fields()
  Revert block: Disable driver-specific options for 1.6
  qemu-iotests: Update reference output for 051
  block: Remove old raw driver

Laszlo Ersek (7):
  add skeleton for BSD licensed raw BlockDriver
  raw_bsd: emit debug events in bdrv_co_readv() and bdrv_co_writev()
  raw_bsd: add raw_create()
  raw_bsd: introduce special members
  raw_bsd: add raw_create_options
  raw_bsd: register bdrv_raw
  switch raw block driver from raw.o to raw_bsd.o

Max Reitz (11):
  option: Add assigned flag to QEMUOptionParameter
  qcow2-refcount: Snapshot update for zero clusters
  qemu-iotests: Snapshotting zero clusters
  qcow2: Add corrupt bit
  qcow2: Metadata overlap checks
  qcow2: Employ metadata overlap checks
  qcow2-refcount: Move OFLAG_COPIED checks
  qcow2-refcount: Repair OFLAG_COPIED errors
  qcow2-refcount: Repair shared refcount blocks
  qcow2_check: Mark image consistent
  qemu-iotests: Overlapping cluster allocations

Peter Maydell (1):
  block/qcow2.h: Avoid 1LL  63 (shifts into sign bit)

 block.c|   1 -
 block/Makefile.objs|   2 +-
 block/blkdebug.c   |   1 +
 block/gluster.c|  15 +-
 block/qcow2-cache.c|  17 ++
 block/qcow2-cluster.c  |  25 ++-
 block/qcow2-refcount.c | 533 -
 block/qcow2-snapshot.c |  22 ++
 block/qcow2.c  |  83 ++-
 block/qcow2.h  |  53 -
 block/{raw.c = raw_bsd.c} | 170 +++
 blockdev.c | 143 
 docs/specs/qcow2.txt   |   7 +-
 include/block/block.h  |   1 +
 include/monitor/monitor.h  |   1 +
 include/qemu/option.h  |   1 +
 monitor.c  |   1 +
 scripts/qapi-types.py  |  19 +-
 tests/qemu-iotests/031.out |  12 +-
 tests/qemu-iotests/036.out |   2 +-
 tests/qemu-iotests/051.out |   1 -
 tests/qemu-iotests/060 | 111 ++
 tests/qemu-iotests/060.out |  44 
 tests/qemu-iotests/062 |  64 ++
 tests/qemu-iotests/062.out |   9 +
 tests/qemu-iotests/group   |   4 +-
 util/qemu-option.c |   9 +
 27 files changed, 1029 insertions(+), 322 deletions(-)
 rename block/{raw.c = raw_bsd.c} (57%)
 create mode 100755 tests/qemu-iotests/060
 create mode 100644 tests/qemu-iotests/060.out
 create mode 100755 tests/qemu-iotests/062
 create mode 100644 tests/qemu-iotests/062.out



[Qemu-devel] [PULL v2 01/26] qcow2: Change default for new images to compat=1.1

2013-09-02 Thread Kevin Wolf
By the time that qemu 1.7 will be released, enough time will have passed
since qemu 1.1, which is the first version to understand version 3
images, that changing the default shouldn't hurt many people any more
and the benefits of using the new format outweigh the pain.

qemu-iotests already runs with compat=1.1 by default.

Signed-off-by: Kevin Wolf kw...@redhat.com
Reviewed-by: Eric Blake ebl...@redhat.com
---
 block/qcow2.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 78097e5..5e5f413 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1429,7 +1429,9 @@ static int qcow2_create(const char *filename, 
QEMUOptionParameter *options)
 return -EINVAL;
 }
 } else if (!strcmp(options-name, BLOCK_OPT_COMPAT_LEVEL)) {
-if (!options-value.s || !strcmp(options-value.s, 0.10)) {
+if (!options-value.s) {
+/* keep the default */
+} else if (!strcmp(options-value.s, 0.10)) {
 version = 2;
 } else if (!strcmp(options-value.s, 1.1)) {
 version = 3;
-- 
1.8.1.4




[Qemu-devel] [PULL v2 02/26] block: Remove redundant assertion

2013-09-02 Thread Kevin Wolf
The failing condition is checked immediately before the assertion, so
keeping the assertion is kind of redundant.

Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/block.c b/block.c
index a387c1a..26639e8 100644
--- a/block.c
+++ b/block.c
@@ -743,7 +743,6 @@ static int bdrv_open_common(BlockDriverState *bs, 
BlockDriverState *file,
 ret = -EINVAL;
 goto free_and_fail;
 }
-assert(file != NULL);
 bs-file = file;
 ret = drv-bdrv_open(bs, options, open_flags);
 }
-- 
1.8.1.4




[Qemu-devel] [PULL v2 11/26] raw_bsd: add raw_create_options

2013-09-02 Thread Kevin Wolf
From: Laszlo Ersek ler...@redhat.com

On 08/05/13 15:03, Paolo Bonzini wrote:

 [...]

 4) There is another member, .create_options, which is an array of
 QEMUOptionParameter structs, terminated by an all-zero item.  The only
 option you need is for the virtual disk size.  You will find something
 to copy from in other block drivers, for example block/qcow2.c.

Code taken and adapted from block/qcow2.c, as suggested. The code being
copied/modified is blamed on

commit 20d97356c9df6d68fbd37d6334fdb7063f24eab6
Author: Blue Swirl blauwir...@gmail.com
Date:   Fri Apr 23 20:19:47 2010 +

Fix OpenBSD build

and

commit 7c80ab3f21f0b1342f23057d4345ae266c7348d9
Author: Jes Sorensen jes.soren...@redhat.com
Date:   Fri Dec 17 16:02:39 2010 +0100

block/qcow2.c: rename qcow_ functions to qcow2_

Signed-off-by: Laszlo Ersek ler...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/raw_bsd.c | 13 -
 1 file changed, 12 insertions(+), 1 deletion(-)

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index b1d7209..b70245d 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -1,6 +1,7 @@
 /* BlockDriver implementation for raw
  *
- * Copyright (C) 2013, Red Hat, Inc.
+ * Copyright (C) 2010, 2013, Red Hat, Inc.
+ * Copyright (C) 2010, Blue Swirl blauwir...@gmail.com
  *
  * Author:
  *   Laszlo Ersek ler...@redhat.com
@@ -25,6 +26,16 @@
  */
 
 #include block/block_int.h
+#include qemu/option.h
+
+static const QEMUOptionParameter raw_create_options[] = {
+{
+.name = BLOCK_OPT_SIZE,
+.type = OPT_SIZE,
+.help = Virtual disk size
+},
+{ 0 }
+};
 
 static TYPE raw_reopen_prepare(BlockDriverState *bs)
 {
-- 
1.8.1.4




[Qemu-devel] [PULL v2 07/26] add skeleton for BSD licensed raw BlockDriver

2013-09-02 Thread Kevin Wolf
From: Laszlo Ersek ler...@redhat.com

On 08/05/13 15:03, Paolo Bonzini wrote:


 - Original Message -
 From: Laszlo Ersek ler...@redhat.com
 To: Paolo Bonzini pbonz...@redhat.com
 Sent: Monday, August 5, 2013 2:43:46 PM
 Subject: Re: [PATCH 1/2] raw: add license header

 On 08/02/13 00:27, Paolo Bonzini wrote:
 On 08/01/2013 10:13 AM, Christoph Hellwig wrote:
 On Wed, Jul 31, 2013 at 08:19:51AM +0200, Paolo Bonzini wrote:
 Most of the block layer is under the BSD license, thus it is
 reasonable to license block/raw.c the same way.  CCed people should
 ACK by replying with a Signed-off-by line.

 The coded was intended to be GPLv2.

 Laszlo, would you be willing to do clean-room reverse engineering?

 (No rants, please. :))

 What's the scope exactly?

 It's quite small, it's a file full of forwarders like

 static void raw_foo(BlockDriverState *bs)
 {
 return bdrv_foo(bs-file);
 }

 It's 170 lines of code, all as boring as this.  I only picked you
 because I'm quite certain you have never seen the file (and the answer
 confirmed it).

 Basically:

 1) BlockDriver is a struct in which these function members are
 interesting:

 .bdrv_reopen_prepare
 .bdrv_co_readv
 .bdrv_co_writev
 .bdrv_co_is_allocated
 .bdrv_co_write_zeroes
 .bdrv_co_discard
 .bdrv_getlength
 .bdrv_get_info
 .bdrv_truncate
 .bdrv_is_inserted
 .bdrv_media_changed
 .bdrv_eject
 .bdrv_lock_medium
 .bdrv_ioctl
 .bdrv_aio_ioctl
 .bdrv_has_zero_init

 They should be implemented as simple forwarders (see above).
 There are 16 functions listed here, you can easily see how this
 already accounts for 100+ SLOC roughly...

 The implementations of bdrv_co_readv and bdrv_co_writev should also
 call BLKDBG_EVENT on bs-file too, before forwarding to bs-file.  The
 events to be generated are BLKDBG_READ_AIO and BLKDBG_WRITE_AIO.

 2) This is also a simple forwarder function:

 .bdrv_create

 but there is no BlockDriverState argument so the forwarded-to function
 does not have a bs-file argument either.  The forwarded-to function
 is bdrv_create_file.

 3) These members are special

 .format_name   is the string raw
 .bdrv_open raw_open should set bs-sg to bs-file-sg and return 0
 .bdrv_closeraw_close should do nothing
 .bdrv_proberaw_probe should just return 1.

 4) There is another member, .create_options, which is an array of
 QEMUOptionParameter structs, terminated by an all-zero item.  The only
 option you need is for the virtual disk size.  You will find something
 to copy from in other block drivers, for example block/qcow2.c.

 5) Formats are registered with bdrv_register (takes a BlockDriver*).
 You also need to pass the caller of bdrv_register to block_init.

 6) I'm not sure how to organize the patch series, so I'll leave this to
 your creativity.  I guess in this case move/copy detection of git should
 be disabled.  I would definitely include this spec in the commit
 message as a proof of clean-room reverse engineering.

 7) Remember a BSD header like the one in block.c.

 Paolo

This patch implements the email up to the paragraph ending with 100+ SLOC
roughly. The skeleton is generated from the list there, with a simple
shell loop using sed and the raw_foo() template.

The BSD license block is copied (and reflowed) from
util/qemu-progress.c.

Signed-off-by: Laszlo Ersek ler...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/raw_bsd.c | 108 
 1 file changed, 108 insertions(+)
 create mode 100644 block/raw_bsd.c

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
new file mode 100644
index 000..5c17d53
--- /dev/null
+++ b/block/raw_bsd.c
@@ -0,0 +1,108 @@
+/* BlockDriver implementation for raw
+ *
+ * Copyright (C) 2013, Red Hat, Inc.
+ *
+ * Author:
+ *   Laszlo Ersek ler...@redhat.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the Software), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+

[Qemu-devel] [PULL v2 06/26] block/qcow2.h: Avoid 1LL 63 (shifts into sign bit)

2013-09-02 Thread Kevin Wolf
From: Peter Maydell peter.mayd...@linaro.org

The expression 1LL  63 tries to shift the 1 into the sign bit of a
'long long', which provokes a clang sanitizer warning:

runtime error: left shift of 1 by 63 places cannot be represented in type 'long 
long'

Use 1ULL  63 as the definition of QCOW_OFLAG_COPIED instead
to avoid this. For consistency, we also update the other QCOW_OFLAG
definitions to use the ULL suffix rather than LL, though only the
shift by 63 is undefined behaviour.

Signed-off-by: Peter Maydell peter.mayd...@linaro.org
Reviewed-by: Eric Blake ebl...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/qcow2.h | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/block/qcow2.h b/block/qcow2.h
index dba9771..365a17e 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -40,11 +40,11 @@
 #define QCOW_MAX_CRYPT_CLUSTERS 32
 
 /* indicate that the refcount of the referenced cluster is exactly one. */
-#define QCOW_OFLAG_COPIED (1LL  63)
+#define QCOW_OFLAG_COPIED (1ULL  63)
 /* indicate that the cluster is compressed (they never have the copied flag) */
-#define QCOW_OFLAG_COMPRESSED (1LL  62)
+#define QCOW_OFLAG_COMPRESSED (1ULL  62)
 /* The cluster reads as all zeros */
-#define QCOW_OFLAG_ZERO (1LL  0)
+#define QCOW_OFLAG_ZERO (1ULL  0)
 
 #define REFCOUNT_SHIFT 1 /* refcount size is 2 bytes */
 
-- 
1.8.1.4




[Qemu-devel] [PULL v2 03/26] qapi-types.py: Split off generate_struct_fields()

2013-09-02 Thread Kevin Wolf
Signed-off-by: Kevin Wolf kw...@redhat.com
Reviewed-by: Eric Blake ebl...@redhat.com
---
 scripts/qapi-types.py | 19 +--
 1 file changed, 13 insertions(+), 6 deletions(-)

diff --git a/scripts/qapi-types.py b/scripts/qapi-types.py
index 5ee46ea..86de980 100644
--- a/scripts/qapi-types.py
+++ b/scripts/qapi-types.py
@@ -57,12 +57,8 @@ typedef struct %(name)sList
 ''',
  name=name)
 
-def generate_struct(structname, fieldname, members):
-ret = mcgen('''
-struct %(name)s
-{
-''',
-  name=structname)
+def generate_struct_fields(members):
+ret = ''
 
 for argname, argentry, optional, structured in parse_args(members):
 if optional:
@@ -80,6 +76,17 @@ struct %(name)s
 ''',
  c_type=c_type(argentry), c_name=c_var(argname))
 
+return ret
+
+def generate_struct(structname, fieldname, members):
+ret = mcgen('''
+struct %(name)s
+{
+''',
+  name=structname)
+
+ret += generate_struct_fields(members)
+
 if len(fieldname):
 fieldname =   + fieldname
 ret += mcgen('''
-- 
1.8.1.4




[Qemu-devel] [PULL v2 13/26] switch raw block driver from raw.o to raw_bsd.o

2013-09-02 Thread Kevin Wolf
From: Laszlo Ersek ler...@redhat.com

Incoming function prototypes and outgoing function calls must match
reality. Implemented using the struct BlockDriver definition in
include/block/block_int.h, and gcc errors  warnings.

v1-v2:

On 08/20/13 09:51, Kevin Wolf wrote:
 Am 18.08.2013 um 16:29 hat Paolo Bonzini geschrieben:
 Il 16/08/2013 16:15, Laszlo Ersek ha scritto:
 +static int raw_reopen_prepare(BDRVReopenState *reopen_state,
 +  BlockReopenQueue *queue, Error **errp)
  {
 -return bdrv_reopen_prepare(bs-file);
 +BDRVReopenState tmp = *reopen_state;
 +
 +tmp.bs = tmp.bs-file;
 +return bdrv_reopen_prepare(tmp, queue, errp);
  }

 This should just return zero, my fault.

 Which is because bdrv_reopen_queue() already queues bs-file for reopen.
 The simple return 0; implementation is shared by all other format drivers
 that support reopening images.

Signed-off-by: Laszlo Ersek ler...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/Makefile.objs |  2 +-
 block/raw_bsd.c | 78 ++---
 2 files changed, 45 insertions(+), 35 deletions(-)

diff --git a/block/Makefile.objs b/block/Makefile.objs
index 4cf9aa4..3bb85b5 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -1,4 +1,4 @@
-block-obj-y += raw.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o 
vvfat.o
+block-obj-y += raw_bsd.o cow.o qcow.o vdi.o vmdk.o cloop.o dmg.o bochs.o vpc.o 
vvfat.o
 block-obj-y += qcow2.o qcow2-refcount.o qcow2-cluster.o qcow2-snapshot.o 
qcow2-cache.o
 block-obj-y += qed.o qed-gencb.o qed-l2-cache.o qed-table.o qed-cluster.o
 block-obj-y += qed-check.o
diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 2dc1921..ab2b0fd 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -29,7 +29,7 @@
 #include block/block_int.h
 #include qemu/option.h
 
-static const QEMUOptionParameter raw_create_options[] = {
+static QEMUOptionParameter raw_create_options[] = {
 {
 .name = BLOCK_OPT_SIZE,
 .type = OPT_SIZE,
@@ -38,104 +38,114 @@ static const QEMUOptionParameter raw_create_options[] = {
 { 0 }
 };
 
-static TYPE raw_reopen_prepare(BlockDriverState *bs)
+static int raw_reopen_prepare(BDRVReopenState *reopen_state,
+  BlockReopenQueue *queue, Error **errp)
 {
-return bdrv_reopen_prepare(bs-file);
+return 0;
 }
 
-static TYPE raw_co_readv(BlockDriverState *bs)
+static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
+ int nb_sectors, QEMUIOVector *qiov)
 {
 BLKDBG_EVENT(bs-file, BLKDBG_READ_AIO);
-return bdrv_co_readv(bs-file);
+return bdrv_co_readv(bs-file, sector_num, nb_sectors, qiov);
 }
 
-static TYPE raw_co_writev(BlockDriverState *bs)
+static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
+  int nb_sectors, QEMUIOVector *qiov)
 {
 BLKDBG_EVENT(bs-file, BLKDBG_WRITE_AIO);
-return bdrv_co_writev(bs-file);
+return bdrv_co_writev(bs-file, sector_num, nb_sectors, qiov);
 }
 
-static TYPE raw_co_is_allocated(BlockDriverState *bs)
+static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
+int64_t sector_num, int nb_sectors,
+int *pnum)
 {
-return bdrv_co_is_allocated(bs-file);
+return bdrv_co_is_allocated(bs-file, sector_num, nb_sectors, pnum);
 }
 
-static TYPE raw_co_write_zeroes(BlockDriverState *bs)
+static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs,
+int64_t sector_num, int nb_sectors)
 {
-return bdrv_co_write_zeroes(bs-file);
+return bdrv_co_write_zeroes(bs-file, sector_num, nb_sectors);
 }
 
-static TYPE raw_co_discard(BlockDriverState *bs)
+static int coroutine_fn raw_co_discard(BlockDriverState *bs,
+   int64_t sector_num, int nb_sectors)
 {
-return bdrv_co_discard(bs-file);
+return bdrv_co_discard(bs-file, sector_num, nb_sectors);
 }
 
-static TYPE raw_getlength(BlockDriverState *bs)
+static int64_t raw_getlength(BlockDriverState *bs)
 {
 return bdrv_getlength(bs-file);
 }
 
-static TYPE raw_get_info(BlockDriverState *bs)
+static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
 {
-return bdrv_get_info(bs-file);
+return bdrv_get_info(bs-file, bdi);
 }
 
-static TYPE raw_truncate(BlockDriverState *bs)
+static int raw_truncate(BlockDriverState *bs, int64_t offset)
 {
-return bdrv_truncate(bs-file);
+return bdrv_truncate(bs-file, offset);
 }
 
-static TYPE raw_is_inserted(BlockDriverState *bs)
+static int raw_is_inserted(BlockDriverState *bs)
 {
 return bdrv_is_inserted(bs-file);
 }
 
-static TYPE raw_media_changed(BlockDriverState *bs)
+static int raw_media_changed(BlockDriverState *bs)
 {
 return bdrv_media_changed(bs-file);
 }
 
-static TYPE 

[Qemu-devel] [PULL v2 09/26] raw_bsd: add raw_create()

2013-09-02 Thread Kevin Wolf
From: Laszlo Ersek ler...@redhat.com

On 08/05/13 15:03, Paolo Bonzini wrote:

 [...]

 2) This is also a simple forwarder function:

 .bdrv_create

 but there is no BlockDriverState argument so the forwarded-to function
 does not have a bs-file argument either.  The forwarded-to function is
 bdrv_create_file.

Signed-off-by: Laszlo Ersek ler...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/raw_bsd.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 19091a3..5bcbe71 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -108,3 +108,7 @@ static TYPE raw_has_zero_init(BlockDriverState *bs)
 return bdrv_has_zero_init(bs-file);
 }
 
+static TYPE raw_create(void)
+{
+return bdrv_create_file();
+}
-- 
1.8.1.4




[Qemu-devel] [PULL v2 05/26] qemu-iotests: Update reference output for 051

2013-09-02 Thread Kevin Wolf
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 tests/qemu-iotests/051.out | 1 -
 1 file changed, 1 deletion(-)

diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index 5582ed3..86e989c 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -85,7 +85,6 @@ QEMU_PROG: -drive if=virtio: Device 'virtio-blk-pci' could 
not be initialized
 Testing: -drive if=scsi
 QEMU X.Y.Z monitor - type 'help' for more information
 (qemu) QEMU_PROG: -drive if=scsi: Device needs media, but drive is empty
-QEMU_PROG: -drive if=scsi: Device initialization failed.
 QEMU_PROG: Device initialization failed.
 QEMU_PROG: Initialization of device lsi53c895a failed
 
-- 
1.8.1.4




[Qemu-devel] [PULL v2 19/26] qcow2: Add corrupt bit

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

This adds an incompatible bit indicating corruption to qcow2. Any image
with this bit set may not be written to unless for repairing (and
subsequently clearing the bit if the repair has been successful).

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/qcow2.c  | 47 ++
 block/qcow2.h  |  7 ++-
 docs/specs/qcow2.txt   |  7 ++-
 tests/qemu-iotests/031.out | 12 ++--
 tests/qemu-iotests/036.out |  2 +-
 5 files changed, 66 insertions(+), 9 deletions(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 5e5f413..fe91568 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -272,6 +272,37 @@ static int qcow2_mark_clean(BlockDriverState *bs)
 return 0;
 }
 
+/*
+ * Marks the image as corrupt.
+ */
+int qcow2_mark_corrupt(BlockDriverState *bs)
+{
+BDRVQcowState *s = bs-opaque;
+
+s-incompatible_features |= QCOW2_INCOMPAT_CORRUPT;
+return qcow2_update_header(bs);
+}
+
+/*
+ * Marks the image as consistent, i.e., unsets the corrupt bit, and flushes
+ * before if necessary.
+ */
+int qcow2_mark_consistent(BlockDriverState *bs)
+{
+BDRVQcowState *s = bs-opaque;
+
+if (s-incompatible_features  QCOW2_INCOMPAT_CORRUPT) {
+int ret = bdrv_flush(bs);
+if (ret  0) {
+return ret;
+}
+
+s-incompatible_features = ~QCOW2_INCOMPAT_CORRUPT;
+return qcow2_update_header(bs);
+}
+return 0;
+}
+
 static int qcow2_check(BlockDriverState *bs, BdrvCheckResult *result,
BdrvCheckMode fix)
 {
@@ -402,6 +433,17 @@ static int qcow2_open(BlockDriverState *bs, QDict 
*options, int flags)
 goto fail;
 }
 
+if (s-incompatible_features  QCOW2_INCOMPAT_CORRUPT) {
+/* Corrupt images may not be written to unless they are being repaired
+ */
+if ((flags  BDRV_O_RDWR)  !(flags  BDRV_O_CHECK)) {
+error_report(qcow2: Image is corrupt; cannot be opened 
+read/write.);
+ret = -EACCES;
+goto fail;
+}
+}
+
 /* Check support for various header values */
 if (header.refcount_order != 4) {
 report_unsupported(bs, %d bit reference counts,
@@ -1130,6 +1172,11 @@ int qcow2_update_header(BlockDriverState *bs)
 .name = dirty bit,
 },
 {
+.type = QCOW2_FEAT_TYPE_INCOMPATIBLE,
+.bit  = QCOW2_INCOMPAT_CORRUPT_BITNR,
+.name = corrupt bit,
+},
+{
 .type = QCOW2_FEAT_TYPE_COMPATIBLE,
 .bit  = QCOW2_COMPAT_LAZY_REFCOUNTS_BITNR,
 .name = lazy refcounts,
diff --git a/block/qcow2.h b/block/qcow2.h
index 365a17e..32ecb33 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -119,9 +119,12 @@ enum {
 /* Incompatible feature bits */
 enum {
 QCOW2_INCOMPAT_DIRTY_BITNR   = 0,
+QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
 QCOW2_INCOMPAT_DIRTY = 1  QCOW2_INCOMPAT_DIRTY_BITNR,
+QCOW2_INCOMPAT_CORRUPT   = 1  QCOW2_INCOMPAT_CORRUPT_BITNR,
 
-QCOW2_INCOMPAT_MASK  = QCOW2_INCOMPAT_DIRTY,
+QCOW2_INCOMPAT_MASK  = QCOW2_INCOMPAT_DIRTY
+ | QCOW2_INCOMPAT_CORRUPT,
 };
 
 /* Compatible feature bits */
@@ -361,6 +364,8 @@ int qcow2_backing_read1(BlockDriverState *bs, QEMUIOVector 
*qiov,
   int64_t sector_num, int nb_sectors);
 
 int qcow2_mark_dirty(BlockDriverState *bs);
+int qcow2_mark_corrupt(BlockDriverState *bs);
+int qcow2_mark_consistent(BlockDriverState *bs);
 int qcow2_update_header(BlockDriverState *bs);
 
 /* qcow2-refcount.c functions */
diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt
index 36a559d..33eca36 100644
--- a/docs/specs/qcow2.txt
+++ b/docs/specs/qcow2.txt
@@ -80,7 +80,12 @@ in the description of a field.
 tables to repair refcounts before accessing the
 image.
 
-Bits 1-63:  Reserved (set to 0)
+Bit 1:  Corrupt bit.  If this bit is set then any data
+structure may be corrupt and the image must not
+be written to (unless for regaining
+consistency).
+
+Bits 2-63:  Reserved (set to 0)
 
  80 -  87:  compatible_features
 Bitmask of compatible features. An implementation can
diff --git a/tests/qemu-iotests/031.out b/tests/qemu-iotests/031.out
index 796c993..a943344 100644
--- a/tests/qemu-iotests/031.out
+++ b/tests/qemu-iotests/031.out
@@ -54,7 +54,7 @@ header_length 72
 
 Header extension:
 magic 0x6803f857
-length96
+length144
 data  binary
 
 Header extension:
@@ -68,7 +68,7 @@ No errors were found on the image.
 
 magic 

[Qemu-devel] [PULL v2 04/26] Revert block: Disable driver-specific options for 1.6

2013-09-02 Thread Kevin Wolf
This reverts commit 8afaefb8919dc8746a57c450a758717c516c7b0a.

Signed-off-by: Kevin Wolf kw...@redhat.com
---
 blockdev.c   | 143 ---
 tests/qemu-iotests/group |   2 +-
 2 files changed, 1 insertion(+), 144 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 121520e..e70e16e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -46,7 +46,6 @@
 
 static QTAILQ_HEAD(drivelist, DriveInfo) drives = 
QTAILQ_HEAD_INITIALIZER(drives);
 extern QemuOptsList qemu_common_drive_opts;
-extern QemuOptsList qemu_old_drive_opts;
 
 static const char *const if_name[IF_COUNT] = {
 [IF_NONE] = none,
@@ -755,26 +754,6 @@ DriveInfo *drive_init(QemuOpts *all_opts, 
BlockInterfaceType block_default_type)
 {
 const char *value;
 
-/*
- * Check that only old options are used by copying into a QemuOpts with
- * stricter checks. Going through a QDict seems to be the easiest way to
- * achieve this...
- */
-QemuOpts* check_opts;
-QDict *qdict;
-Error *local_err = NULL;
-
-qdict = qemu_opts_to_qdict(all_opts, NULL);
-check_opts = qemu_opts_from_qdict(qemu_old_drive_opts, qdict, local_err);
-QDECREF(qdict);
-
-if (error_is_set(local_err)) {
-qerror_report_err(local_err);
-error_free(local_err);
-return NULL;
-}
-qemu_opts_del(check_opts);
-
 /* Change legacy command line options into QMP ones */
 qemu_opt_rename(all_opts, iops, throttling.iops-total);
 qemu_opt_rename(all_opts, iops_rd, throttling.iops-read);
@@ -2001,128 +1980,6 @@ QemuOptsList qemu_common_drive_opts = {
 },
 };
 
-QemuOptsList qemu_old_drive_opts = {
-.name = drive,
-.head = QTAILQ_HEAD_INITIALIZER(qemu_old_drive_opts.head),
-.desc = {
-{
-.name = bus,
-.type = QEMU_OPT_NUMBER,
-.help = bus number,
-},{
-.name = unit,
-.type = QEMU_OPT_NUMBER,
-.help = unit number (i.e. lun for scsi),
-},{
-.name = if,
-.type = QEMU_OPT_STRING,
-.help = interface (ide, scsi, sd, mtd, floppy, pflash, virtio),
-},{
-.name = index,
-.type = QEMU_OPT_NUMBER,
-.help = index number,
-},{
-.name = cyls,
-.type = QEMU_OPT_NUMBER,
-.help = number of cylinders (ide disk geometry),
-},{
-.name = heads,
-.type = QEMU_OPT_NUMBER,
-.help = number of heads (ide disk geometry),
-},{
-.name = secs,
-.type = QEMU_OPT_NUMBER,
-.help = number of sectors (ide disk geometry),
-},{
-.name = trans,
-.type = QEMU_OPT_STRING,
-.help = chs translation (auto, lba. none),
-},{
-.name = media,
-.type = QEMU_OPT_STRING,
-.help = media type (disk, cdrom),
-},{
-.name = snapshot,
-.type = QEMU_OPT_BOOL,
-.help = enable/disable snapshot mode,
-},{
-.name = file,
-.type = QEMU_OPT_STRING,
-.help = disk image,
-},{
-.name = discard,
-.type = QEMU_OPT_STRING,
-.help = discard operation (ignore/off, unmap/on),
-},{
-.name = cache,
-.type = QEMU_OPT_STRING,
-.help = host cache usage (none, writeback, writethrough, 
-directsync, unsafe),
-},{
-.name = aio,
-.type = QEMU_OPT_STRING,
-.help = host AIO implementation (threads, native),
-},{
-.name = format,
-.type = QEMU_OPT_STRING,
-.help = disk format (raw, qcow2, ...),
-},{
-.name = serial,
-.type = QEMU_OPT_STRING,
-.help = disk serial number,
-},{
-.name = rerror,
-.type = QEMU_OPT_STRING,
-.help = read error action,
-},{
-.name = werror,
-.type = QEMU_OPT_STRING,
-.help = write error action,
-},{
-.name = addr,
-.type = QEMU_OPT_STRING,
-.help = pci address (virtio only),
-},{
-.name = readonly,
-.type = QEMU_OPT_BOOL,
-.help = open drive file as read-only,
-},{
-.name = iops,
-.type = QEMU_OPT_NUMBER,
-.help = limit total I/O operations per second,
-},{
-.name = iops_rd,
-.type = QEMU_OPT_NUMBER,
-.help = limit read operations per second,
-},{
-.name = iops_wr,
-.type = QEMU_OPT_NUMBER,
-.help = limit write operations per second,
-},{
-.name = bps,
-.type = QEMU_OPT_NUMBER,
-.help = limit total bytes per second,
-},{
-.name = 

[Qemu-devel] [PULL v2 08/26] raw_bsd: emit debug events in bdrv_co_readv() and bdrv_co_writev()

2013-09-02 Thread Kevin Wolf
From: Laszlo Ersek ler...@redhat.com

On 08/05/13 15:03, Paolo Bonzini wrote:

 [...]

 1) BlockDriver is a struct in which these function members are
 interesting:

 .bdrv_reopen_prepare
 .bdrv_co_readv
 .bdrv_co_writev
 .bdrv_co_is_allocated
 .bdrv_co_write_zeroes
 .bdrv_co_discard
 .bdrv_getlength
 .bdrv_get_info
 .bdrv_truncate
 .bdrv_is_inserted
 .bdrv_media_changed
 .bdrv_eject
 .bdrv_lock_medium
 .bdrv_ioctl
 .bdrv_aio_ioctl
 .bdrv_has_zero_init

 They should be implemented as simple forwarders (see above). There are
 16 functions listed here, you can easily see how this already accounts
 for 100+ SLOC roughly...

 The implementations of bdrv_co_readv and bdrv_co_writev should also call
 BLKDBG_EVENT on bs-file too, before forwarding to bs-file.  The events
 to be generated are BLKDBG_READ_AIO and BLKDBG_WRITE_AIO.

Signed-off-by: Laszlo Ersek ler...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/raw_bsd.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 5c17d53..19091a3 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -33,11 +33,13 @@ static TYPE raw_reopen_prepare(BlockDriverState *bs)
 
 static TYPE raw_co_readv(BlockDriverState *bs)
 {
+BLKDBG_EVENT(bs-file, BLKDBG_READ_AIO);
 return bdrv_co_readv(bs-file);
 }
 
 static TYPE raw_co_writev(BlockDriverState *bs)
 {
+BLKDBG_EVENT(bs-file, BLKDBG_WRITE_AIO);
 return bdrv_co_writev(bs-file);
 }
 
-- 
1.8.1.4




[Qemu-devel] [PULL v2 10/26] raw_bsd: introduce special members

2013-09-02 Thread Kevin Wolf
From: Laszlo Ersek ler...@redhat.com

On 08/05/13 15:03, Paolo Bonzini wrote:

 [...]

 3) These members are special

 .format_name   is the string raw
 .bdrv_open raw_open should set bs-sg to bs-file-sg and return 0
 .bdrv_closeraw_close should do nothing
 .bdrv_proberaw_probe should just return 1.

v1-v2:

On 08/20/13 10:11, Kevin Wolf wrote:
 Am 16.08.2013 um 16:15 hat Laszlo Ersek geschrieben:

 +static int raw_probe(void)
 +{
 +return 1;
 +}

 Maybe add a comment here like smallest possible positive score so that
 raw is used if and only if no other block driver works.

Signed-off-by: Laszlo Ersek ler...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/raw_bsd.c | 23 +++
 1 file changed, 23 insertions(+)

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index 5bcbe71..b1d7209 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -112,3 +112,26 @@ static TYPE raw_create(void)
 {
 return bdrv_create_file();
 }
+
+static const char *raw_format_name(void)
+{
+return raw;
+}
+
+static int raw_open(BlockDriverState *bs)
+{
+bs-sg = bs-file-sg;
+return 0;
+}
+
+static void raw_close(void)
+{
+}
+
+static int raw_probe(void)
+{
+/* smallest possible positive score so that raw is used if and only if no
+ * other block driver works
+ */
+return 1;
+}
-- 
1.8.1.4




[Qemu-devel] [PULL v2 24/26] qcow2-refcount: Repair shared refcount blocks

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

If the refcount of a refcount block is greater than one, we can at least
try to repair that problem by duplicating the affected block.

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/blkdebug.c   |   1 +
 block/qcow2-refcount.c | 148 -
 include/block/block.h  |   1 +
 3 files changed, 148 insertions(+), 2 deletions(-)

diff --git a/block/blkdebug.c b/block/blkdebug.c
index ccb627a..5d33e03 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -168,6 +168,7 @@ static const char *event_names[BLKDBG_EVENT_MAX] = {
 
 [BLKDBG_REFTABLE_LOAD]  = reftable_load,
 [BLKDBG_REFTABLE_GROW]  = reftable_grow,
+[BLKDBG_REFTABLE_UPDATE]= reftable_update,
 
 [BLKDBG_REFBLOCK_LOAD]  = refblock_load,
 [BLKDBG_REFBLOCK_UPDATE]= refblock_update,
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 2276b6f..ba129de 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1338,6 +1338,121 @@ fail:
 }
 
 /*
+ * Writes one sector of the refcount table to the disk
+ */
+#define RT_ENTRIES_PER_SECTOR (512 / sizeof(uint64_t))
+static int write_reftable_entry(BlockDriverState *bs, int rt_index)
+{
+BDRVQcowState *s = bs-opaque;
+uint64_t buf[RT_ENTRIES_PER_SECTOR];
+int rt_start_index;
+int i, ret;
+
+rt_start_index = rt_index  ~(RT_ENTRIES_PER_SECTOR - 1);
+for (i = 0; i  RT_ENTRIES_PER_SECTOR; i++) {
+buf[i] = cpu_to_be64(s-refcount_table[rt_start_index + i]);
+}
+
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_REFCOUNT_TABLE,
+s-refcount_table_offset + rt_start_index * sizeof(uint64_t),
+sizeof(buf));
+if (ret  0) {
+return ret;
+}
+
+BLKDBG_EVENT(bs-file, BLKDBG_REFTABLE_UPDATE);
+ret = bdrv_pwrite_sync(bs-file, s-refcount_table_offset +
+rt_start_index * sizeof(uint64_t), buf, sizeof(buf));
+if (ret  0) {
+return ret;
+}
+
+return 0;
+}
+
+/*
+ * Allocates a new cluster for the given refcount block (represented by its
+ * offset in the image file) and copies the current content there. This 
function
+ * does _not_ decrement the reference count for the currently occupied cluster.
+ *
+ * This function prints an informative message to stderr on error (and returns
+ * -errno); on success, 0 is returned.
+ */
+static int64_t realloc_refcount_block(BlockDriverState *bs, int reftable_index,
+  uint64_t offset)
+{
+BDRVQcowState *s = bs-opaque;
+int64_t new_offset = 0;
+void *refcount_block = NULL;
+int ret;
+
+/* allocate new refcount block */
+new_offset = qcow2_alloc_clusters(bs, s-cluster_size);
+if (new_offset  0) {
+fprintf(stderr, Could not allocate new cluster: %s\n,
+strerror(-new_offset));
+ret = new_offset;
+goto fail;
+}
+
+/* fetch current refcount block content */
+ret = qcow2_cache_get(bs, s-refcount_block_cache, offset, 
refcount_block);
+if (ret  0) {
+fprintf(stderr, Could not fetch refcount block: %s\n, 
strerror(-ret));
+goto fail;
+}
+
+/* new block has not yet been entered into refcount table, therefore it is
+ * no refcount block yet (regarding this check) */
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, new_offset,
+s-cluster_size);
+if (ret  0) {
+fprintf(stderr, Could not write refcount block; metadata overlap 
+check failed: %s\n, strerror(-ret));
+/* the image will be marked corrupt, so don't even attempt on freeing
+ * the cluster */
+new_offset = 0;
+goto fail;
+}
+
+/* write to new block */
+ret = bdrv_write(bs-file, new_offset / BDRV_SECTOR_SIZE, refcount_block,
+s-cluster_sectors);
+if (ret  0) {
+fprintf(stderr, Could not write refcount block: %s\n, 
strerror(-ret));
+goto fail;
+}
+
+/* update refcount table */
+assert(!(new_offset  (s-cluster_size - 1)));
+s-refcount_table[reftable_index] = new_offset;
+ret = write_reftable_entry(bs, reftable_index);
+if (ret  0) {
+fprintf(stderr, Could not update refcount table: %s\n,
+strerror(-ret));
+goto fail;
+}
+
+fail:
+if (new_offset  (ret  0)) {
+qcow2_free_clusters(bs, new_offset, s-cluster_size,
+QCOW2_DISCARD_ALWAYS);
+}
+if (refcount_block) {
+if (ret  0) {
+qcow2_cache_put(bs, s-refcount_block_cache, refcount_block);
+} else {
+ret = qcow2_cache_put(bs, s-refcount_block_cache, 
refcount_block);
+}
+}
+if (ret  0) {
+return ret;
+}
+return new_offset;
+}
+
+/*
  * Checks an image for refcount 

[Qemu-devel] [PULL v2 14/26] block: Remove old raw driver

2013-09-02 Thread Kevin Wolf
This is unused code now.

Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/raw.c | 192 
 1 file changed, 192 deletions(-)
 delete mode 100644 block/raw.c

diff --git a/block/raw.c b/block/raw.c
deleted file mode 100644
index 4751825..000
--- a/block/raw.c
+++ /dev/null
@@ -1,192 +0,0 @@
-/*
- * Block driver for RAW format
- *
- * Copyright (c) 2006 Fabrice Bellard
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the Software), to 
deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED AS IS, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-#include qemu-common.h
-#include block/block_int.h
-#include qemu/module.h
-
-static int raw_open(BlockDriverState *bs, QDict *options, int flags)
-{
-bs-sg = bs-file-sg;
-return 0;
-}
-
-/* We have nothing to do for raw reopen, stubs just return
- * success */
-static int raw_reopen_prepare(BDRVReopenState *state,
-  BlockReopenQueue *queue,  Error **errp)
-{
-return 0;
-}
-
-static int coroutine_fn raw_co_readv(BlockDriverState *bs, int64_t sector_num,
- int nb_sectors, QEMUIOVector *qiov)
-{
-BLKDBG_EVENT(bs-file, BLKDBG_READ_AIO);
-return bdrv_co_readv(bs-file, sector_num, nb_sectors, qiov);
-}
-
-static int coroutine_fn raw_co_writev(BlockDriverState *bs, int64_t sector_num,
-  int nb_sectors, QEMUIOVector *qiov)
-{
-BLKDBG_EVENT(bs-file, BLKDBG_WRITE_AIO);
-return bdrv_co_writev(bs-file, sector_num, nb_sectors, qiov);
-}
-
-static void raw_close(BlockDriverState *bs)
-{
-}
-
-static int coroutine_fn raw_co_is_allocated(BlockDriverState *bs,
-int64_t sector_num,
-int nb_sectors, int *pnum)
-{
-return bdrv_co_is_allocated(bs-file, sector_num, nb_sectors, pnum);
-}
-
-static int coroutine_fn raw_co_write_zeroes(BlockDriverState *bs,
-int64_t sector_num,
-int nb_sectors)
-{
-return bdrv_co_write_zeroes(bs-file, sector_num, nb_sectors);
-}
-
-static int64_t raw_getlength(BlockDriverState *bs)
-{
-return bdrv_getlength(bs-file);
-}
-
-static int raw_truncate(BlockDriverState *bs, int64_t offset)
-{
-return bdrv_truncate(bs-file, offset);
-}
-
-static int raw_probe(const uint8_t *buf, int buf_size, const char *filename)
-{
-   return 1; /* everything can be opened as raw image */
-}
-
-static int coroutine_fn raw_co_discard(BlockDriverState *bs,
-   int64_t sector_num, int nb_sectors)
-{
-return bdrv_co_discard(bs-file, sector_num, nb_sectors);
-}
-
-static int raw_is_inserted(BlockDriverState *bs)
-{
-return bdrv_is_inserted(bs-file);
-}
-
-static int raw_media_changed(BlockDriverState *bs)
-{
-return bdrv_media_changed(bs-file);
-}
-
-static void raw_eject(BlockDriverState *bs, bool eject_flag)
-{
-bdrv_eject(bs-file, eject_flag);
-}
-
-static void raw_lock_medium(BlockDriverState *bs, bool locked)
-{
-bdrv_lock_medium(bs-file, locked);
-}
-
-static int raw_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
-{
-   return bdrv_ioctl(bs-file, req, buf);
-}
-
-static BlockDriverAIOCB *raw_aio_ioctl(BlockDriverState *bs,
-unsigned long int req, void *buf,
-BlockDriverCompletionFunc *cb, void *opaque)
-{
-   return bdrv_aio_ioctl(bs-file, req, buf, cb, opaque);
-}
-
-static int raw_create(const char *filename, QEMUOptionParameter *options)
-{
-return bdrv_create_file(filename, options);
-}
-
-static QEMUOptionParameter raw_create_options[] = {
-{
-.name = BLOCK_OPT_SIZE,
-.type = OPT_SIZE,
-.help = Virtual disk size
-},
-{ NULL }
-};
-
-static int raw_has_zero_init(BlockDriverState *bs)
-{
-return bdrv_has_zero_init(bs-file);
-}
-
-static int raw_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
-{
-return bdrv_get_info(bs-file, bdi);
-}
-
-static BlockDriver 

[Qemu-devel] [PULL v2 12/26] raw_bsd: register bdrv_raw

2013-09-02 Thread Kevin Wolf
From: Laszlo Ersek ler...@redhat.com

On 08/05/13 15:03, Paolo Bonzini wrote:

 [...]

 5) Formats are registered with bdrv_register (takes a BlockDriver*). You
 also need to pass the caller of bdrv_register to block_init.

Fill in the BlockDriver structure with the raw_*() functions that have
been added to block/raw_bsd.c, in the order the fields are defined in
include/block/block_int.h.

I needed more explanation / naming examples for registering the driver
than what Paolo gave me, so I copied / adapted from block/qcow2.c. The
parts I took as basis for modification are blamed on

commit 5efa9d5a8b18841c9c62208a494d7f519238979a
Author: Anthony Liguori aligu...@us.ibm.com
Date:   Sat May 9 17:03:42 2009 -0500

Convert block infrastructure to use new module init functionality

commit 20d97356c9df6d68fbd37d6334fdb7063f24eab6
Author: Blue Swirl blauwir...@gmail.com
Date:   Fri Apr 23 20:19:47 2010 +

Fix OpenBSD build

Signed-off-by: Laszlo Ersek ler...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/raw_bsd.c | 38 +-
 1 file changed, 33 insertions(+), 5 deletions(-)

diff --git a/block/raw_bsd.c b/block/raw_bsd.c
index b70245d..2dc1921 100644
--- a/block/raw_bsd.c
+++ b/block/raw_bsd.c
@@ -2,6 +2,7 @@
  *
  * Copyright (C) 2010, 2013, Red Hat, Inc.
  * Copyright (C) 2010, Blue Swirl blauwir...@gmail.com
+ * Copyright (C) 2009, Anthony Liguori aligu...@us.ibm.com
  *
  * Author:
  *   Laszlo Ersek ler...@redhat.com
@@ -124,11 +125,6 @@ static TYPE raw_create(void)
 return bdrv_create_file();
 }
 
-static const char *raw_format_name(void)
-{
-return raw;
-}
-
 static int raw_open(BlockDriverState *bs)
 {
 bs-sg = bs-file-sg;
@@ -146,3 +142,35 @@ static int raw_probe(void)
  */
 return 1;
 }
+
+static BlockDriver bdrv_raw = {
+.format_name  = raw,
+.bdrv_probe   = raw_probe,
+.bdrv_reopen_prepare  = raw_reopen_prepare,
+.bdrv_open= raw_open,
+.bdrv_close   = raw_close,
+.bdrv_create  = raw_create,
+.bdrv_co_readv= raw_co_readv,
+.bdrv_co_writev   = raw_co_writev,
+.bdrv_co_write_zeroes = raw_co_write_zeroes,
+.bdrv_co_discard  = raw_co_discard,
+.bdrv_co_is_allocated = raw_co_is_allocated,
+.bdrv_truncate= raw_truncate,
+.bdrv_getlength   = raw_getlength,
+.bdrv_get_info= raw_get_info,
+.bdrv_is_inserted = raw_is_inserted,
+.bdrv_media_changed   = raw_media_changed,
+.bdrv_eject   = raw_eject,
+.bdrv_lock_medium = raw_lock_medium,
+.bdrv_ioctl   = raw_ioctl,
+.bdrv_aio_ioctl   = raw_aio_ioctl,
+.create_options   = raw_create_options[0],
+.bdrv_has_zero_init   = raw_has_zero_init
+};
+
+static void bdrv_raw_init(void)
+{
+bdrv_register(bdrv_raw);
+}
+
+block_init(bdrv_raw_init);
-- 
1.8.1.4




[Qemu-devel] [PULL v2 18/26] qemu-iotests: Snapshotting zero clusters

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

This test creates an image with unallocated zero clusters, then creates
a snapshot. Afterwards, there should be neither any errors nor leaks.

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 tests/qemu-iotests/062 | 64 ++
 tests/qemu-iotests/062.out |  9 +++
 tests/qemu-iotests/group   |  1 +
 3 files changed, 74 insertions(+)
 create mode 100755 tests/qemu-iotests/062
 create mode 100644 tests/qemu-iotests/062.out

diff --git a/tests/qemu-iotests/062 b/tests/qemu-iotests/062
new file mode 100755
index 000..0511246
--- /dev/null
+++ b/tests/qemu-iotests/062
@@ -0,0 +1,64 @@
+#!/bin/bash
+#
+# Test case for snapshotting images with unallocated zero clusters in
+# qcow2
+#
+# Copyright (C) 2013 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/.
+#
+
+# creator
+owner=mre...@redhat.com
+
+seq=`basename $0`
+echo QA output created by $seq
+
+here=`pwd`
+tmp=/tmp/$$
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap _cleanup; exit \$status 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+IMGOPTS=compat=1.1
+IMG_SIZE=64M
+
+echo
+echo === Testing snapshotting an image with zero clusters ===
+echo
+_make_test_img $IMG_SIZE
+# Write some zero clusters
+$QEMU_IO -c write -z 0 256k $TEST_IMG | _filter_qemu_io
+# Create a snapshot
+$QEMU_IMG snapshot -c foo $TEST_IMG
+# Check the image (there shouldn't be any errors or leaks)
+_check_test_img
+
+# success, all done
+echo *** done
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/062.out b/tests/qemu-iotests/062.out
new file mode 100644
index 000..442d761
--- /dev/null
+++ b/tests/qemu-iotests/062.out
@@ -0,0 +1,9 @@
+QA output created by 062
+
+=== Testing snapshotting an image with zero clusters ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
+wrote 262144/262144 bytes at offset 0
+256 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+No errors were found on the image.
+*** done
diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group
index 93ace2e..fb13792 100644
--- a/tests/qemu-iotests/group
+++ b/tests/qemu-iotests/group
@@ -64,3 +64,4 @@
 055 rw auto
 056 rw auto backing
 059 rw auto
+062 rw auto
-- 
1.8.1.4




[Qemu-devel] [PULL v2 16/26] option: Add assigned flag to QEMUOptionParameter

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

Adds an assigned flag to QEMUOptionParameter which is cleared at the
beginning of parse_option_parameters and set on (successful)
set_option_parameter and set_option_parameter_int.

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 include/qemu/option.h | 1 +
 util/qemu-option.c| 9 +
 2 files changed, 10 insertions(+)

diff --git a/include/qemu/option.h b/include/qemu/option.h
index 7a58e47..63db4cc 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -46,6 +46,7 @@ typedef struct QEMUOptionParameter {
 char* s;
 } value;
 const char *help;
+bool assigned;
 } QEMUOptionParameter;
 
 
diff --git a/util/qemu-option.c b/util/qemu-option.c
index 4ebdc4c..e0844a9 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -275,6 +275,8 @@ int set_option_parameter(QEMUOptionParameter *list, const 
char *name,
 return -1;
 }
 
+list-assigned = true;
+
 return 0;
 }
 
@@ -306,6 +308,8 @@ int set_option_parameter_int(QEMUOptionParameter *list, 
const char *name,
 return -1;
 }
 
+list-assigned = true;
+
 return 0;
 }
 
@@ -397,6 +401,7 @@ QEMUOptionParameter *parse_option_parameters(const char 
*param,
 char value[256];
 char *param_delim, *value_delim;
 char next_delim;
+int i;
 
 if (list == NULL) {
 return NULL;
@@ -406,6 +411,10 @@ QEMUOptionParameter *parse_option_parameters(const char 
*param,
 dest = allocated = append_option_parameters(NULL, list);
 }
 
+for (i = 0; dest[i].name; i++) {
+dest[i].assigned = false;
+}
+
 while (*param) {
 
 // Find parameter name and value in the string
-- 
1.8.1.4




[Qemu-devel] [PULL v2 21/26] qcow2: Employ metadata overlap checks

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

The pre-write overlap check function is now called before most of the
qcow2 writes (aborting it on collision or other error).

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/qcow2-cache.c| 17 +
 block/qcow2-cluster.c  | 21 +
 block/qcow2-snapshot.c | 22 ++
 block/qcow2.c  | 26 ++
 4 files changed, 86 insertions(+)

diff --git a/block/qcow2-cache.c b/block/qcow2-cache.c
index 2f3114e..7bcae09 100644
--- a/block/qcow2-cache.c
+++ b/block/qcow2-cache.c
@@ -115,6 +115,23 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, 
Qcow2Cache *c, int i)
 }
 
 if (c == s-refcount_block_cache) {
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_REFCOUNT_BLOCK,
+c-entries[i].offset, s-cluster_size);
+} else if (c == s-l2_table_cache) {
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_ACTIVE_L2,
+c-entries[i].offset, s-cluster_size);
+} else {
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+c-entries[i].offset, s-cluster_size);
+}
+
+if (ret  0) {
+return ret;
+}
+
+if (c == s-refcount_block_cache) {
 BLKDBG_EVENT(bs-file, BLKDBG_REFBLOCK_UPDATE_PART);
 } else if (c == s-l2_table_cache) {
 BLKDBG_EVENT(bs-file, BLKDBG_L2_UPDATE);
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index cca76d4..7c248aa 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -80,6 +80,14 @@ int qcow2_grow_l1_table(BlockDriverState *bs, uint64_t 
min_size,
 goto fail;
 }
 
+/* the L1 position has not yet been updated, so these clusters must
+ * indeed be completely free */
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+new_l1_table_offset, new_l1_size2);
+if (ret  0) {
+goto fail;
+}
+
 BLKDBG_EVENT(bs-file, BLKDBG_L1_GROW_WRITE_TABLE);
 for(i = 0; i  s-l1_size; i++)
 new_l1_table[i] = cpu_to_be64(new_l1_table[i]);
@@ -149,6 +157,13 @@ static int write_l1_entry(BlockDriverState *bs, int 
l1_index)
 buf[i] = cpu_to_be64(s-l1_table[l1_start_index + i]);
 }
 
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_ACTIVE_L1,
+s-l1_table_offset + 8 * l1_start_index, sizeof(buf));
+if (ret  0) {
+return ret;
+}
+
 BLKDBG_EVENT(bs-file, BLKDBG_L1_UPDATE);
 ret = bdrv_pwrite_sync(bs-file, s-l1_table_offset + 8 * l1_start_index,
 buf, sizeof(buf));
@@ -368,6 +383,12 @@ static int coroutine_fn copy_sectors(BlockDriverState *bs,
 s-aes_encrypt_key);
 }
 
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+cluster_offset + n_start * BDRV_SECTOR_SIZE, n * BDRV_SECTOR_SIZE);
+if (ret  0) {
+goto out;
+}
+
 BLKDBG_EVENT(bs-file, BLKDBG_COW_WRITE);
 ret = bdrv_co_writev(bs-file, (cluster_offset  9) + n_start, n, qiov);
 if (ret  0) {
diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c
index 0caac90..e7e6013 100644
--- a/block/qcow2-snapshot.c
+++ b/block/qcow2-snapshot.c
@@ -189,6 +189,15 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
 return ret;
 }
 
+/* The snapshot list position has not yet been updated, so these clusters
+ * must indeed be completely free */
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT, offset,
+s-snapshots_size);
+if (ret  0) {
+return ret;
+}
+
+
 /* Write all snapshots to the new list */
 for(i = 0; i  s-nb_snapshots; i++) {
 sn = s-snapshots + i;
@@ -363,6 +372,12 @@ int qcow2_snapshot_create(BlockDriverState *bs, 
QEMUSnapshotInfo *sn_info)
 l1_table[i] = cpu_to_be64(s-l1_table[i]);
 }
 
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+sn-l1_table_offset, s-l1_size * sizeof(uint64_t));
+if (ret  0) {
+goto fail;
+}
+
 ret = bdrv_pwrite(bs-file, sn-l1_table_offset, l1_table,
   s-l1_size * sizeof(uint64_t));
 if (ret  0) {
@@ -475,6 +490,13 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char 
*snapshot_id)
 goto fail;
 }
 
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_ACTIVE_L1,
+s-l1_table_offset, cur_l1_bytes);
+if (ret  0) {
+goto fail;
+}
+
 ret = bdrv_pwrite_sync(bs-file, s-l1_table_offset, sn_l1_table,
cur_l1_bytes);
 if (ret  0) {
diff --git a/block/qcow2.c b/block/qcow2.c
index fe91568..05e002d 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -624,6 +624,8 @@ static int qcow2_open(BlockDriverState *bs, QDict 

[Qemu-devel] [PULL v2 22/26] qcow2-refcount: Move OFLAG_COPIED checks

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

Move the OFLAG_COPIED checks out of check_refcounts_l1 and
check_refcounts_l2 and after the actual refcount checks/fixes (since the
refcounts might actually change there).

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/qcow2-refcount.c | 115 +++--
 1 file changed, 82 insertions(+), 33 deletions(-)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 8ee2f13..aa4b98d 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1053,7 +1053,7 @@ static int check_refcounts_l2(BlockDriverState *bs, 
BdrvCheckResult *res,
 BDRVQcowState *s = bs-opaque;
 uint64_t *l2_table, l2_entry;
 uint64_t next_contiguous_offset = 0;
-int i, l2_size, nb_csectors, refcount;
+int i, l2_size, nb_csectors;
 
 /* Read L2 table from disk */
 l2_size = s-l2_size * sizeof(uint64_t);
@@ -1105,23 +1105,8 @@ static int check_refcounts_l2(BlockDriverState *bs, 
BdrvCheckResult *res,
 
 case QCOW2_CLUSTER_NORMAL:
 {
-/* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
 uint64_t offset = l2_entry  L2E_OFFSET_MASK;
 
-if (flags  CHECK_OFLAG_COPIED) {
-refcount = get_refcount(bs, offset  s-cluster_bits);
-if (refcount  0) {
-fprintf(stderr, Can't get refcount for offset %
-PRIx64 : %s\n, l2_entry, strerror(-refcount));
-goto fail;
-}
-if ((refcount == 1) != ((l2_entry  QCOW_OFLAG_COPIED) != 0)) {
-fprintf(stderr, ERROR OFLAG_COPIED: offset=%
-PRIx64  refcount=%d\n, l2_entry, refcount);
-res-corruptions++;
-}
-}
-
 if (flags  CHECK_FRAG_INFO) {
 res-bfi.allocated_clusters++;
 if (next_contiguous_offset 
@@ -1178,7 +1163,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
 {
 BDRVQcowState *s = bs-opaque;
 uint64_t *l1_table, l2_offset, l1_size2;
-int i, refcount, ret;
+int i, ret;
 
 l1_size2 = l1_size * sizeof(uint64_t);
 
@@ -1202,22 +1187,6 @@ static int check_refcounts_l1(BlockDriverState *bs,
 for(i = 0; i  l1_size; i++) {
 l2_offset = l1_table[i];
 if (l2_offset) {
-/* QCOW_OFLAG_COPIED must be set iff refcount == 1 */
-if (flags  CHECK_OFLAG_COPIED) {
-refcount = get_refcount(bs, (l2_offset  ~QCOW_OFLAG_COPIED)
- s-cluster_bits);
-if (refcount  0) {
-fprintf(stderr, Can't get refcount for l2_offset %
-PRIx64 : %s\n, l2_offset, strerror(-refcount));
-goto fail;
-}
-if ((refcount == 1) != ((l2_offset  QCOW_OFLAG_COPIED) != 0)) 
{
-fprintf(stderr, ERROR OFLAG_COPIED: l2_offset=% PRIx64
- refcount=%d\n, l2_offset, refcount);
-res-corruptions++;
-}
-}
-
 /* Mark L2 table as used */
 l2_offset = L1E_OFFSET_MASK;
 inc_refcounts(bs, res, refcount_table, refcount_table_size,
@@ -1249,6 +1218,80 @@ fail:
 }
 
 /*
+ * Checks the OFLAG_COPIED flag for all L1 and L2 entries.
+ *
+ * This function does not print an error message nor does it increment
+ * check_errors if get_refcount fails (this is because such an error will have
+ * been already detected and sufficiently signaled by the calling function
+ * (qcow2_check_refcounts) by the time this function is called).
+ */
+static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res)
+{
+BDRVQcowState *s = bs-opaque;
+uint64_t *l2_table = qemu_blockalign(bs, s-cluster_size);
+int ret;
+int refcount;
+int i, j;
+
+for (i = 0; i  s-l1_size; i++) {
+uint64_t l1_entry = s-l1_table[i];
+uint64_t l2_offset = l1_entry  L1E_OFFSET_MASK;
+
+if (!l2_offset) {
+continue;
+}
+
+refcount = get_refcount(bs, l2_offset  s-cluster_bits);
+if (refcount  0) {
+/* don't print message nor increment check_errors */
+continue;
+}
+if ((refcount == 1) != ((l1_entry  QCOW_OFLAG_COPIED) != 0)) {
+fprintf(stderr, ERROR OFLAG_COPIED L2 cluster: l1_index=%d 
+l1_entry=% PRIx64  refcount=%d\n,
+i, l1_entry, refcount);
+res-corruptions++;
+}
+
+ret = bdrv_pread(bs-file, l2_offset, l2_table,
+ s-l2_size * sizeof(uint64_t));
+if (ret  0) {
+fprintf(stderr, ERROR: Could not read L2 table: %s\n,
+strerror(-ret));
+res-check_errors++;
+goto fail;
+}
+
+for (j = 0; j  s-l2_size; j++) {
+ 

[Qemu-devel] [PULL v2 26/26] qemu-iotests: Overlapping cluster allocations

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

A new test on corrupted images with overlapping cluster allocations.

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 tests/qemu-iotests/060 | 111 +
 tests/qemu-iotests/060.out |  44 ++
 tests/qemu-iotests/group   |   1 +
 3 files changed, 156 insertions(+)
 create mode 100755 tests/qemu-iotests/060
 create mode 100644 tests/qemu-iotests/060.out

diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060
new file mode 100755
index 000..65bb09f
--- /dev/null
+++ b/tests/qemu-iotests/060
@@ -0,0 +1,111 @@
+#!/bin/bash
+#
+# Test case for image corruption (overlapping data structures) in qcow2
+#
+# Copyright (C) 2013 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/.
+#
+
+# creator
+owner=mre...@redhat.com
+
+seq=`basename $0`
+echo QA output created by $seq
+
+here=`pwd`
+tmp=/tmp/$$
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap _cleanup; exit \$status 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+rt_offset=65536  # 0x1 (XXX: just an assumption)
+rb_offset=131072 # 0x2 (XXX: just an assumption)
+l1_offset=196608 # 0x3 (XXX: just an assumption)
+l2_offset=262144 # 0x4 (XXX: just an assumption)
+
+IMGOPTS=compat=1.1
+
+echo
+echo === Testing L2 reference into L1 ===
+echo
+_make_test_img 64M
+# Link first L1 entry (first L2 table) onto itself
+# (Note the MSb in the L1 entry is set, ensuring the refcount is one - else any
+# later write will result in a COW operation, effectively ruining this attempt
+# on image corruption)
+poke_file $TEST_IMG $l1_offset \x80\x00\x00\x00\x00\x03\x00\x00
+_check_test_img
+
+# The corrupt bit should not be set anyway
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# Try to write something, thereby forcing the corrupt bit to be set
+$QEMU_IO -c write -P 0x2a 0 512 $TEST_IMG | _filter_qemu_io
+
+# The corrupt bit must now be set
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# Try to open the image R/W (which should fail)
+$QEMU_IO -c read 0 512 $TEST_IMG 21 | _filter_qemu_io | sed -e s/can't 
open device .*$/can't open device/
+
+# Try to open it RO (which should succeed)
+$QEMU_IO -c read 0 512 -r $TEST_IMG | _filter_qemu_io
+
+# We could now try to fix the image, but this would probably fail (how should 
an
+# L2 table linked onto the L1 table be fixed?)
+
+echo
+echo === Testing cluster data reference into refcount block ===
+echo
+_make_test_img 64M
+# Allocate L2 table
+truncate -s $(($l2_offset+65536)) $TEST_IMG
+poke_file $TEST_IMG $l1_offset \x80\x00\x00\x00\x00\x04\x00\x00
+# Mark cluster as used
+poke_file $TEST_IMG $(($rb_offset+8)) \x00\x01
+# Redirect new data cluster onto refcount block
+poke_file $TEST_IMG $l2_offset \x80\x00\x00\x00\x00\x02\x00\x00
+_check_test_img
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+$QEMU_IO -c write -P 0x2a 0 512 $TEST_IMG | _filter_qemu_io
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# Try to fix it
+_check_test_img -r all
+
+# The corrupt bit should be cleared
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# Look if it's really really fixed
+$QEMU_IO -c write -P 0x2a 0 512 $TEST_IMG | _filter_qemu_io
+./qcow2.py $TEST_IMG dump-header | grep incompatible_features
+
+# success, all done
+echo *** done
+rm -f $seq.full
+status=0
diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out
new file mode 100644
index 000..ca4583a
--- /dev/null
+++ b/tests/qemu-iotests/060.out
@@ -0,0 +1,44 @@
+QA output created by 060
+
+=== Testing L2 reference into L1 ===
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 
+ERROR cluster 3 refcount=1 reference=3
+
+1 errors were found on the image.
+Data may be corrupted, or further writes to the image may corrupt it.
+incompatible_features 0x0
+qcow2: Preventing invalid write on metadata (overlaps with active L1 table); 
image marked as corrupt.
+write failed: Input/output error
+incompatible_features 0x2
+qcow2: Image is corrupt; cannot be opened read/write.
+qemu-io: can't open device
+no file 

[Qemu-devel] [PULL v2 23/26] qcow2-refcount: Repair OFLAG_COPIED errors

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

Since the OFLAG_COPIED checks are now executed after the refcounts have
been repaired (if repairing), it is safe to assume that they are correct
but the OFLAG_COPIED flag may be not. Therefore, if its value differs
from what it should be (considering the according refcount), that
discrepancy can be repaired by correctly setting (or clearing that flag.

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/qcow2-cluster.c  |  4 ++--
 block/qcow2-refcount.c | 58 --
 block/qcow2.h  |  1 +
 3 files changed, 55 insertions(+), 8 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 7c248aa..2d5aa92 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -145,7 +145,7 @@ static int l2_load(BlockDriverState *bs, uint64_t l2_offset,
  * and we really don't want bdrv_pread to perform a read-modify-write)
  */
 #define L1_ENTRIES_PER_SECTOR (512 / 8)
-static int write_l1_entry(BlockDriverState *bs, int l1_index)
+int qcow2_write_l1_entry(BlockDriverState *bs, int l1_index)
 {
 BDRVQcowState *s = bs-opaque;
 uint64_t buf[L1_ENTRIES_PER_SECTOR];
@@ -254,7 +254,7 @@ static int l2_allocate(BlockDriverState *bs, int l1_index, 
uint64_t **table)
 /* update the L1 entry */
 trace_qcow2_l2_allocate_write_l1(bs, l1_index);
 s-l1_table[l1_index] = l2_offset | QCOW_OFLAG_COPIED;
-ret = write_l1_entry(bs, l1_index);
+ret = qcow2_write_l1_entry(bs, l1_index);
 if (ret  0) {
 goto fail;
 }
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index aa4b98d..2276b6f 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1225,7 +1225,8 @@ fail:
  * been already detected and sufficiently signaled by the calling function
  * (qcow2_check_refcounts) by the time this function is called).
  */
-static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res)
+static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
+  BdrvCheckMode fix)
 {
 BDRVQcowState *s = bs-opaque;
 uint64_t *l2_table = qemu_blockalign(bs, s-cluster_size);
@@ -1236,6 +1237,7 @@ static int check_oflag_copied(BlockDriverState *bs, 
BdrvCheckResult *res)
 for (i = 0; i  s-l1_size; i++) {
 uint64_t l1_entry = s-l1_table[i];
 uint64_t l2_offset = l1_entry  L1E_OFFSET_MASK;
+bool l2_dirty = false;
 
 if (!l2_offset) {
 continue;
@@ -1247,10 +1249,24 @@ static int check_oflag_copied(BlockDriverState *bs, 
BdrvCheckResult *res)
 continue;
 }
 if ((refcount == 1) != ((l1_entry  QCOW_OFLAG_COPIED) != 0)) {
-fprintf(stderr, ERROR OFLAG_COPIED L2 cluster: l1_index=%d 
+fprintf(stderr, %s OFLAG_COPIED L2 cluster: l1_index=%d 
 l1_entry=% PRIx64  refcount=%d\n,
+fix  BDRV_FIX_ERRORS ? Repairing :
+ERROR,
 i, l1_entry, refcount);
-res-corruptions++;
+if (fix  BDRV_FIX_ERRORS) {
+s-l1_table[i] = refcount == 1
+   ? l1_entry |  QCOW_OFLAG_COPIED
+   : l1_entry  ~QCOW_OFLAG_COPIED;
+ret = qcow2_write_l1_entry(bs, i);
+if (ret  0) {
+res-check_errors++;
+goto fail;
+}
+res-corruptions_fixed++;
+} else {
+res-corruptions++;
+}
 }
 
 ret = bdrv_pread(bs-file, l2_offset, l2_table,
@@ -1275,13 +1291,43 @@ static int check_oflag_copied(BlockDriverState *bs, 
BdrvCheckResult *res)
 continue;
 }
 if ((refcount == 1) != ((l2_entry  QCOW_OFLAG_COPIED) != 0)) {
-fprintf(stderr, ERROR OFLAG_COPIED data cluster: 
+fprintf(stderr, %s OFLAG_COPIED data cluster: 
 l2_entry=% PRIx64  refcount=%d\n,
+fix  BDRV_FIX_ERRORS ? Repairing :
+ERROR,
 l2_entry, refcount);
-res-corruptions++;
+if (fix  BDRV_FIX_ERRORS) {
+l2_table[j] = cpu_to_be64(refcount == 1
+? l2_entry |  QCOW_OFLAG_COPIED
+: l2_entry  ~QCOW_OFLAG_COPIED);
+l2_dirty = true;
+res-corruptions_fixed++;
+} else {
+res-corruptions++;
+}
 }
 }
 }
+
+if (l2_dirty) {
+ret = qcow2_pre_write_overlap_check(bs,
+QCOW2_OL_DEFAULT  ~QCOW2_OL_ACTIVE_L2, l2_offset,
+  

[Qemu-devel] [PULL v2 15/26] gluster: Abort on AIO completion failure

2013-09-02 Thread Kevin Wolf
From: Bharata B Rao bhar...@linux.vnet.ibm.com

Currently if gluster AIO callback thread fails to notify the QEMU thread about
AIO completion, we try graceful recovery by marking the disk drive as
inaccessible. This error recovery code is race-prone as found by Asias and
Stefan. However as found out by Paolo, this kind of error is impossible and
hence simplify the code that handles this error recovery.

Signed-off-by: Bharata B Rao bhar...@linux.vnet.ibm.com
Reviewed-by: Stefan Hajnoczi stefa...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/gluster.c | 15 ++-
 1 file changed, 2 insertions(+), 13 deletions(-)

diff --git a/block/gluster.c b/block/gluster.c
index 46f36f8..dbb03f4 100644
--- a/block/gluster.c
+++ b/block/gluster.c
@@ -427,20 +427,9 @@ static void gluster_finish_aiocb(struct glfs_fd *fd, 
ssize_t ret, void *arg)
 /*
  * Gluster AIO callback thread failed to notify the waiting
  * QEMU thread about IO completion.
- *
- * Complete this IO request and make the disk inaccessible for
- * subsequent reads and writes.
  */
-error_report(Gluster failed to notify QEMU about IO completion);
-
-qemu_mutex_lock_iothread(); /* We are in gluster thread context */
-acb-common.cb(acb-common.opaque, -EIO);
-qemu_aio_release(acb);
-close(s-fds[GLUSTER_FD_READ]);
-close(s-fds[GLUSTER_FD_WRITE]);
-qemu_aio_set_fd_handler(s-fds[GLUSTER_FD_READ], NULL, NULL, NULL);
-bs-drv = NULL; /* Make the disk inaccessible */
-qemu_mutex_unlock_iothread();
+error_report(Gluster AIO completion failed: %s, strerror(errno));
+abort();
 }
 }
 
-- 
1.8.1.4




[Qemu-devel] [PULL v2 17/26] qcow2-refcount: Snapshot update for zero clusters

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

Account for all cluster types in qcow2_update_snapshot_refcounts;
this prevents this function from updating the refcount of unallocated
zero clusters which effectively led to wrong adjustments of the refcount
of cluster 0 (the main qcow2 header). This in turn resulted in images
with (unallocated) zero clusters having a cluster 0 refcount greater
than one after creating a snapshot.

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/qcow2-refcount.c | 52 +-
 1 file changed, 35 insertions(+), 17 deletions(-)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index 1244693..a61224a 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -861,11 +861,14 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
 }
 
 for(j = 0; j  s-l2_size; j++) {
+uint64_t cluster_index;
+
 offset = be64_to_cpu(l2_table[j]);
-if (offset != 0) {
-old_offset = offset;
-offset = ~QCOW_OFLAG_COPIED;
-if (offset  QCOW_OFLAG_COMPRESSED) {
+old_offset = offset;
+offset = ~QCOW_OFLAG_COPIED;
+
+switch (qcow2_get_cluster_type(offset)) {
+case QCOW2_CLUSTER_COMPRESSED:
 nb_csectors = ((offset  s-csize_shift) 
s-csize_mask) + 1;
 if (addend != 0) {
@@ -880,8 +883,16 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
 }
 /* compressed clusters are never modified */
 refcount = 2;
-} else {
-uint64_t cluster_index = (offset  L2E_OFFSET_MASK)  
s-cluster_bits;
+break;
+
+case QCOW2_CLUSTER_NORMAL:
+case QCOW2_CLUSTER_ZERO:
+cluster_index = (offset  L2E_OFFSET_MASK)  
s-cluster_bits;
+if (!cluster_index) {
+/* unallocated */
+refcount = 0;
+break;
+}
 if (addend != 0) {
 refcount = update_cluster_refcount(bs, 
cluster_index, addend,

QCOW2_DISCARD_SNAPSHOT);
@@ -893,19 +904,26 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
 ret = refcount;
 goto fail;
 }
-}
+break;
 
-if (refcount == 1) {
-offset |= QCOW_OFLAG_COPIED;
-}
-if (offset != old_offset) {
-if (addend  0) {
-qcow2_cache_set_dependency(bs, s-l2_table_cache,
-s-refcount_block_cache);
-}
-l2_table[j] = cpu_to_be64(offset);
-qcow2_cache_entry_mark_dirty(s-l2_table_cache, 
l2_table);
+case QCOW2_CLUSTER_UNALLOCATED:
+refcount = 0;
+break;
+
+default:
+abort();
+}
+
+if (refcount == 1) {
+offset |= QCOW_OFLAG_COPIED;
+}
+if (offset != old_offset) {
+if (addend  0) {
+qcow2_cache_set_dependency(bs, s-l2_table_cache,
+s-refcount_block_cache);
 }
+l2_table[j] = cpu_to_be64(offset);
+qcow2_cache_entry_mark_dirty(s-l2_table_cache, l2_table);
 }
 }
 
-- 
1.8.1.4




[Qemu-devel] [PULL v2 20/26] qcow2: Metadata overlap checks

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

Two new functions are added; the first one checks a given range in the
image file for overlaps with metadata (main header, L1 tables, L2
tables, refcount table and blocks).

The second one should be used immediately before writing to the image
file as it calls the first function and, upon collision, marks the
image as corrupt and makes the BDS unusable, thereby preventing
further access.

Both functions take a bitmask argument specifying the structures which
should be checked for overlaps, making it possible to also check
metadata writes against colliding with other structures.

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/qcow2-refcount.c| 172 ++
 block/qcow2.h |  39 +++
 include/monitor/monitor.h |   1 +
 monitor.c |   1 +
 4 files changed, 213 insertions(+)

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index a61224a..8ee2f13 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -25,6 +25,8 @@
 #include qemu-common.h
 #include block/block_int.h
 #include block/qcow2.h
+#include qemu/range.h
+#include qapi/qmp/types.h
 
 static int64_t alloc_clusters_noref(BlockDriverState *bs, int64_t size);
 static int QEMU_WARN_UNUSED_RESULT update_refcount(BlockDriverState *bs,
@@ -1390,3 +1392,173 @@ fail:
 return ret;
 }
 
+#define overlaps_with(ofs, sz) \
+ranges_overlap(offset, size, ofs, sz)
+
+/*
+ * Checks if the given offset into the image file is actually free to use by
+ * looking for overlaps with important metadata sections (L1/L2 tables etc.),
+ * i.e. a sanity check without relying on the refcount tables.
+ *
+ * The chk parameter specifies exactly what checks to perform (being a bitmask
+ * of QCow2MetadataOverlap values).
+ *
+ * Returns:
+ * - 0 if writing to this offset will not affect the mentioned metadata
+ * - a positive QCow2MetadataOverlap value indicating one overlapping section
+ * - a negative value (-errno) indicating an error while performing a check,
+ *   e.g. when bdrv_read failed on QCOW2_OL_INACTIVE_L2
+ */
+int qcow2_check_metadata_overlap(BlockDriverState *bs, int chk, int64_t offset,
+ int64_t size)
+{
+BDRVQcowState *s = bs-opaque;
+int i, j;
+
+if (!size) {
+return 0;
+}
+
+if (chk  QCOW2_OL_MAIN_HEADER) {
+if (offset  s-cluster_size) {
+return QCOW2_OL_MAIN_HEADER;
+}
+}
+
+/* align range to test to cluster boundaries */
+size = align_offset(offset_into_cluster(s, offset) + size, 
s-cluster_size);
+offset = start_of_cluster(s, offset);
+
+if ((chk  QCOW2_OL_ACTIVE_L1)  s-l1_size) {
+if (overlaps_with(s-l1_table_offset, s-l1_size * sizeof(uint64_t))) {
+return QCOW2_OL_ACTIVE_L1;
+}
+}
+
+if ((chk  QCOW2_OL_REFCOUNT_TABLE)  s-refcount_table_size) {
+if (overlaps_with(s-refcount_table_offset,
+s-refcount_table_size * sizeof(uint64_t))) {
+return QCOW2_OL_REFCOUNT_TABLE;
+}
+}
+
+if ((chk  QCOW2_OL_SNAPSHOT_TABLE)  s-snapshots_size) {
+if (overlaps_with(s-snapshots_offset, s-snapshots_size)) {
+return QCOW2_OL_SNAPSHOT_TABLE;
+}
+}
+
+if ((chk  QCOW2_OL_INACTIVE_L1)  s-snapshots) {
+for (i = 0; i  s-nb_snapshots; i++) {
+if (s-snapshots[i].l1_size 
+overlaps_with(s-snapshots[i].l1_table_offset,
+s-snapshots[i].l1_size * sizeof(uint64_t))) {
+return QCOW2_OL_INACTIVE_L1;
+}
+}
+}
+
+if ((chk  QCOW2_OL_ACTIVE_L2)  s-l1_table) {
+for (i = 0; i  s-l1_size; i++) {
+if ((s-l1_table[i]  L1E_OFFSET_MASK) 
+overlaps_with(s-l1_table[i]  L1E_OFFSET_MASK,
+s-cluster_size)) {
+return QCOW2_OL_ACTIVE_L2;
+}
+}
+}
+
+if ((chk  QCOW2_OL_REFCOUNT_BLOCK)  s-refcount_table) {
+for (i = 0; i  s-refcount_table_size; i++) {
+if ((s-refcount_table[i]  REFT_OFFSET_MASK) 
+overlaps_with(s-refcount_table[i]  REFT_OFFSET_MASK,
+s-cluster_size)) {
+return QCOW2_OL_REFCOUNT_BLOCK;
+}
+}
+}
+
+if ((chk  QCOW2_OL_INACTIVE_L2)  s-snapshots) {
+for (i = 0; i  s-nb_snapshots; i++) {
+uint64_t l1_ofs = s-snapshots[i].l1_table_offset;
+uint32_t l1_sz  = s-snapshots[i].l1_size;
+uint64_t *l1 = g_malloc(l1_sz * sizeof(uint64_t));
+int ret;
+
+ret = bdrv_read(bs-file, l1_ofs / BDRV_SECTOR_SIZE, (uint8_t *)l1,
+l1_sz * sizeof(uint64_t) / BDRV_SECTOR_SIZE);
+
+if (ret  0) {
+g_free(l1);
+return ret;
+}
+
+for (j = 0; j  l1_sz; j++) {
+   

[Qemu-devel] [PATCH 1/4] monitor: introduce monitor_read_console

2013-09-02 Thread Lei Li
This patch introduces monitor_read_console(), which will drop
into interactive mode with chardev ringbuf backend, and install
a readline handler. When the handler is invoked, the given data
will be written to ringbuf backend.

Signed-off-by: Lei Li li...@linux.vnet.ibm.com
---
 include/monitor/monitor.h |3 +++
 monitor.c |   14 ++
 2 files changed, 17 insertions(+), 0 deletions(-)

diff --git a/include/monitor/monitor.h b/include/monitor/monitor.h
index 1942cc4..e6a6f47 100644
--- a/include/monitor/monitor.h
+++ b/include/monitor/monitor.h
@@ -89,6 +89,9 @@ ReadLineState *monitor_get_rs(Monitor *mon);
 int monitor_read_password(Monitor *mon, ReadLineFunc *readline_func,
   void *opaque);
 
+int monitor_read_console(Monitor *mon, const char *device,
+ ReadLineFunc *readline_func, void *opaque);
+
 int qmp_qom_set(Monitor *mon, const QDict *qdict, QObject **ret);
 
 int qmp_qom_get(Monitor *mon, const QDict *qdict, QObject **ret);
diff --git a/monitor.c b/monitor.c
index 0aeaf6c..531095e 100644
--- a/monitor.c
+++ b/monitor.c
@@ -263,6 +263,20 @@ int monitor_read_password(Monitor *mon, ReadLineFunc 
*readline_func,
 }
 }
 
+int monitor_read_console(Monitor *mon, const char *device,
+ ReadLineFunc *readline_func, void *opaque)
+{
+char prompt[60];
+
+if (!mon-rs) {
+return -1;
+}
+
+snprintf(prompt, sizeof(prompt), %s: , device);
+readline_start(mon-rs, prompt, 0, readline_func, opaque);
+return 0;
+}
+
 static gboolean monitor_unblocked(GIOChannel *chan, GIOCondition cond,
   void *opaque)
 {
-- 
1.7.7.6




[Qemu-devel] [PATCH 0/4 RFC] Introduce console for ringbuf backend

2013-09-02 Thread Lei Li
This patch series aims at adding HMP console feature for ringbuf
backend. It behaves like a serial console, which drops user into 
an interactive mode with ringbuf backend and takes user back to 
the monitor by the 'ctrl-]' escape sequence.

It would suspend the monitor, output the data that backed in the 
ringbuf backend to console first, and install a new readline
handler to get input from console back into the ringbuf backend. 
Once escape sequence is detected, it will resume the monitor.

This implementation is reworked based on Anthony's suggestions
on the previous version:

http://lists.gnu.org/archive/html/qemu-devel/2013-01/msg03888.html

Suggestions and comments are very welcome!


Lei Li (4):
  monitor: introduce monitor_read_console
  hmp: factor out ringbuf_print_help()
  qemu-char: export ringbuf_count
  hmp: add console support for ringbuf backend


 hmp-commands.hx   |   21 +++
 hmp.c |  141 +
 hmp.h |1 +
 include/monitor/monitor.h |3 +
 include/sysemu/char.h |2 +
 monitor.c |   14 +
 qemu-char.c   |2 +-
 7 files changed, 171 insertions(+), 13 deletions(-)




[Qemu-devel] [PULL v2 25/26] qcow2_check: Mark image consistent

2013-09-02 Thread Kevin Wolf
From: Max Reitz mre...@redhat.com

If no corruptions remain after an image repair (and no errors have been
encountered), clear the corrupt flag in qcow2_check.

Signed-off-by: Max Reitz mre...@redhat.com
Signed-off-by: Kevin Wolf kw...@redhat.com
---
 block/qcow2.c | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index 05e002d..4bc679a 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -312,7 +312,11 @@ static int qcow2_check(BlockDriverState *bs, 
BdrvCheckResult *result,
 }
 
 if (fix  result-check_errors == 0  result-corruptions == 0) {
-return qcow2_mark_clean(bs);
+ret = qcow2_mark_clean(bs);
+if (ret  0) {
+return ret;
+}
+return qcow2_mark_consistent(bs);
 }
 return ret;
 }
-- 
1.8.1.4




[Qemu-devel] [PATCH 3/4] qemu-char: export ringbuf_count

2013-09-02 Thread Lei Li
Signed-off-by: Lei Li li...@linux.vnet.ibm.com
---
 include/sysemu/char.h |2 ++
 qemu-char.c   |2 +-
 2 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/include/sysemu/char.h b/include/sysemu/char.h
index 8053130..ed20fe3 100644
--- a/include/sysemu/char.h
+++ b/include/sysemu/char.h
@@ -288,6 +288,8 @@ void register_char_driver_qapi(const char *name, 
ChardevBackendKind kind,
 /* add an eventfd to the qemu devices that are polled */
 CharDriverState *qemu_chr_open_eventfd(int eventfd);
 
+size_t ringbuf_count(const CharDriverState *chr);
+
 extern int term_escape_char;
 
 CharDriverState *qemu_char_get_next_serial(void);
diff --git a/qemu-char.c b/qemu-char.c
index 6259496..0d74fae 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -2781,7 +2781,7 @@ typedef struct {
 uint8_t *cbuf;
 } RingBufCharDriver;
 
-static size_t ringbuf_count(const CharDriverState *chr)
+size_t ringbuf_count(const CharDriverState *chr)
 {
 const RingBufCharDriver *d = chr-opaque;
 
-- 
1.7.7.6




[Qemu-devel] [PATCH 2/4] hmp: factor out ringbuf_print_help()

2013-09-02 Thread Lei Li
Factor out ringbuf_print_help(), which will be called in
hmp_read_ringbuf_cb() reading data that can be written with
monitor_printf() to the console from ringbuf backend.

Signed-off-by: Lei Li li...@linux.vnet.ibm.com
---
 hmp.c |   31 +++
 1 files changed, 19 insertions(+), 12 deletions(-)

diff --git a/hmp.c b/hmp.c
index fcca6ae..624ed6f 100644
--- a/hmp.c
+++ b/hmp.c
@@ -752,6 +752,24 @@ void hmp_pmemsave(Monitor *mon, const QDict *qdict)
 hmp_handle_error(mon, errp);
 }
 
+static void ringbuf_print_help(Monitor *mon, const char *data)
+{
+int i;
+
+for (i = 0; data[i]; i++) {
+unsigned char ch = data[i];
+
+if (ch == '\\') {
+monitor_printf(mon, );
+} else if ((ch  0x20  ch != '\n'  ch != '\t') || ch == 0x7F) {
+monitor_printf(mon, \\u%04X, ch);
+} else {
+monitor_printf(mon, %c, ch);
+}
+
+}
+}
+
 void hmp_ringbuf_write(Monitor *mon, const QDict *qdict)
 {
 const char *chardev = qdict_get_str(qdict, device);
@@ -769,7 +787,6 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
 const char *chardev = qdict_get_str(qdict, device);
 char *data;
 Error *errp = NULL;
-int i;
 
 data = qmp_ringbuf_read(chardev, size, false, 0, errp);
 if (errp) {
@@ -778,18 +795,8 @@ void hmp_ringbuf_read(Monitor *mon, const QDict *qdict)
 return;
 }
 
-for (i = 0; data[i]; i++) {
-unsigned char ch = data[i];
-
-if (ch == '\\') {
-monitor_printf(mon, );
-} else if ((ch  0x20  ch != '\n'  ch != '\t') || ch == 0x7F) {
-monitor_printf(mon, \\u%04X, ch);
-} else {
-monitor_printf(mon, %c, ch);
-}
+ringbuf_print_help(mon, data);
 
-}
 monitor_printf(mon, \n);
 g_free(data);
 }
-- 
1.7.7.6




[Qemu-devel] [PATCH 4/4] hmp: add console support for ringbuf backend

2013-09-02 Thread Lei Li
This patch add console command which would suspend the monitor,
output the data that backed in the ringbuf backend to console
first, and install a new readline handler to get input back to
the ringbuf backend. Take back to the monitor once escape sequence
'Ctrl-]' is detected.

Signed-off-by: Lei Li li...@linux.vnet.ibm.com
---
 hmp-commands.hx |   21 ++
 hmp.c   |  110 +++
 hmp.h   |1 +
 3 files changed, 132 insertions(+), 0 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 65b7f60..286d48d 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -876,6 +876,27 @@ stops because the size limit is reached.
 ETEXI
 
 {
+.name   = console,
+.args_type  = chardev:s,
+.params = chardev,
+.mhandler.cmd = hmp_console,
+},
+
+STEXI
+@item console @var{device}
+@findex console
+Connect to the serial console from within the monitor, allow to read and
+write data from/to ringbuf device @var{chardev}. Exit from the console and
+return back to monitor by 'ctrl-]'.
+
+@example
+(qemu) console foo
+foo: data string...
+@end example
+
+ETEXI
+
+{
 .name   = migrate,
 .args_type  = detach:-d,blk:-b,inc:-i,uri:s,
 .params = [-d] [-b] [-i] uri,
diff --git a/hmp.c b/hmp.c
index 624ed6f..87613cc 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1521,3 +1521,113 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
 
 hmp_handle_error(mon, err);
 }
+
+typedef struct ConsoleStatus
+{
+QEMUTimer *timer;
+Monitor *mon;
+CharDriverState *chr;
+} ConsoleStatus;
+
+enum escape_char
+{
+ESCAPE_CHAR_CTRL_GS = 0x1d /* ctrl-] is used for escape */
+};
+
+static void hmp_read_ringbuf_cb(void *opaque)
+{
+ConsoleStatus *status = opaque;
+char *data;
+int len;
+Error *err = NULL;
+
+len = ringbuf_count(status-chr);
+if (len) {
+data = qmp_ringbuf_read(status-chr-label, len, 0, 0, err);
+if (err) {
+monitor_printf(status-mon, %s\n, error_get_pretty(err));
+error_free(err);
+return;
+}
+ringbuf_print_help(status-mon, data);
+monitor_flush(status-mon);
+g_free(data);
+timer_mod(status-timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME) + 
1000);
+} else {
+timer_del(status-timer);
+}
+
+monitor_resume(status-mon);
+g_free(status);
+}
+
+static void hmp_write_console(Monitor *mon, void *opaque)
+{
+CharDriverState *chr = opaque;
+ConsoleStatus *status;
+
+status = g_malloc0(sizeof(*status));
+status-mon = mon;
+status-chr = chr;
+status-timer = timer_new_ms(QEMU_CLOCK_REALTIME, hmp_read_ringbuf_cb,
+ status);
+timer_mod(status-timer, qemu_clock_get_ms(QEMU_CLOCK_REALTIME));
+}
+
+static void hmp_read_console(Monitor *mon, const char *data,
+ void *opaque)
+{
+CharDriverState *chr = opaque;
+enum escape_char console_escape = ESCAPE_CHAR_CTRL_GS;
+int len = strlen(data) + 1;
+char *tmp_buf = g_malloc0(len);
+int i;
+Error *err = NULL;
+
+for (i = 0; data[i]; i++) {
+if (data[i] == console_escape) {
+monitor_read_command(mon, 1);
+goto out;
+}
+tmp_buf[i] = data[i];
+}
+
+qmp_ringbuf_write(chr-label, tmp_buf, 0, 0, err);
+if (err) {
+monitor_printf(mon, %s\n, error_get_pretty(err));
+monitor_read_command(mon, 1);
+error_free(err);
+goto out;
+}
+
+out:
+g_free(tmp_buf);
+return;
+}
+
+void hmp_console(Monitor *mon, const QDict *qdict)
+{
+const char *device = qdict_get_str(qdict, chardev);
+CharDriverState *chr;
+Error *err = NULL;
+
+chr = qemu_chr_find(device);
+if (!chr) {
+error_set(err, QERR_DEVICE_NOT_FOUND, device);
+goto out;
+}
+
+if (monitor_suspend(mon)) {
+monitor_printf(mon, Failed to suspend console\n);
+return;
+}
+
+hmp_write_console(mon, chr);
+
+if (monitor_read_console(mon, device, hmp_read_console, chr)  0) {
+monitor_printf(mon, Connect to console %s failed\n, device);
+}
+
+out:
+hmp_handle_error(mon, err);
+}
diff --git a/hmp.h b/hmp.h
index 6c3bdcd..d7fb52d 100644
--- a/hmp.h
+++ b/hmp.h
@@ -87,5 +87,6 @@ void hmp_nbd_server_stop(Monitor *mon, const QDict *qdict);
 void hmp_chardev_add(Monitor *mon, const QDict *qdict);
 void hmp_chardev_remove(Monitor *mon, const QDict *qdict);
 void hmp_qemu_io(Monitor *mon, const QDict *qdict);
+void hmp_console(Monitor *mon, const QDict *qdict);
 
 #endif
-- 
1.7.7.6




Re: [Qemu-devel] [PATCH] seccomp: adding a second whitelist

2013-09-02 Thread Stefan Hajnoczi
On Fri, Aug 30, 2013 at 11:42:34AM -0400, Paul Moore wrote:
 On Friday, August 30, 2013 05:23:45 PM Stefan Hajnoczi wrote:
  On Fri, Aug 30, 2013 at 4:21 PM, Eduardo Otubo ot...@linux.vnet.ibm.com 
 wrote:
   On 08/29/2013 05:34 AM, Stefan Hajnoczi wrote:
   On Wed, Aug 28, 2013 at 10:04:32PM -0300, Eduardo Otubo wrote:
   Now there's a second whitelist, right before the vcpu starts. The second
   whitelist is the same as the first one, except for exec() and select().
   
   -netdev tap,downscript=/path/to/script requires exec() in the QEMU
   shutdown code path.  Will this work with seccomp?
   
   I actually don't know, but I'll test that as well. Can you run a test with
   this patch and -netdev? I mean, if you're pointing that out you might have
   a scenario already setup, right?
  
  I'm not having much luck running qemu.git/master with CONFIG_SECCOMP
  on Fedora 19.  The GTK UI opens but I don't see the guest's display.
  
  $ x86_64-softmmu/qemu-system-x86_64
  [...GTK UI opens but QEMU is hung...]
  
  strace shows the process is hung somehow and ps says it's defunct
  although it never exited.
  
  $ sudo cat /proc/5912/stack
  [81061fda] do_exit+0x6ca/0xa20
  [810ef090] __secure_computing+0xe0/0x240
  [8101d722] syscall_trace_enter+0x172/0x230
  [816478c8] tracesys+0x7e/0xe2
  [] 0x
  
  Okay, so seccomp killed the process.
  
  $ sudo cat /proc/5912/syscall
  29 0x0 0x1000 0x380 0x7fffbeb49380 0x0 0x0 0x7fffbeb495b8 0x7f6b72402657
  
  $ git grep '\29\' arch/x86/include/generated/uapi/asm/unistd_64.h
  #define __NR_shmget 29
  
  Now it needs syscall 30.  I guess the whitelist is only designed for a
  specific invocation that you are testing?
 
 For future reference, it doesn't need to be that hard to identify when 
 seccomp 
 has killed a process.  If you're running audit go ahead and check the audit 
 log:
 
  # ausearch -m SECCOMP
  
  time-Fri Aug 30 11:37:46 2013
  type=SECCOMP msg=audit(1377877066.414:64): auid=0 uid=0 gid=0 ses=1
  subj=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023 pid=3787
  comm=20-live-basic_d sig=31 syscall=2 compat=0 ip=0x3a27ae6570 code=0x0
 
 ... and notice the 'syscall' field which in this case happens to be '2'.  If 
 you have the 'scmp_sys_resolver' tool installed on your system (libseccomp-
 devel = 2.1.0 on Fedora) you can then resolve the syscall number:
 
  # scmp_sys_resolver 2
  open
 
 It is also worth mentioning that while scmp_sys_resolver resolves syscalls 
 for 
 the native architecture by default, it can resolve for any of the 
 architectures that libseccomp supports, see the manpage for details 
 (currently: x86, x86_64, x32, and arm).

Useful tips, thanks.

Stefan



Re: [Qemu-devel] About coroutine inside qemu

2013-09-02 Thread Stefan Hajnoczi
On Fri, Aug 30, 2013 at 08:59:37PM +, Yaodong Yang wrote:
 When a new work thread, which is not inside coroutine,  enter a
 coroutine(named as A), what happened to the work thread? Is it true
 that the work thread also become a coroutine, or it just stop? Later
 if the coroutine A call yield. what happened to the work thread?

qemu_coroutine_enter() returns when the coroutine yields or terminates.

Therefore the thread gives its control to the coroutine until it yields
or terminates.

Stefan



Re: [Qemu-devel] Capture SIGSEGV to track pc.ram page access

2013-09-02 Thread Stefan Hajnoczi
On Sun, Sep 01, 2013 at 11:38:34AM +0200, Thomas Knauth wrote:
 My question is where do I have to touch qemu to call my code for
 handling SIGSEGVs? Is this possible at all? Can anyone suggest
 alternative ways of tracking which pages of pc.ram are accessed?

Maybe you can use the dirty page tracking infrastructure?
memory_global_dirty_log_start()

Stefan



[Qemu-devel] [PATCH V3 0/3] qemu-iotests: add test for fd passing via SCM rights

2013-09-02 Thread Wenchao Xia
This series add test case for fd passing with unix socket at runtime. Since
getfd and closefd interface will interact with monitor's data, so it will
help to do regression test for monitor patches. Since python2 do not support
sendmsg(), so a C helper program is added to do the job.

v2:
  1: add missing $ in the makefile rule.

v3:
  Address Eric's comments:
  1: typo fix, remove . in the end of error message, strick
check argc as !=, use EXIT_SUCCESS and EXIT_FAILURE as exit
values, strict error check for strtol() call.
  Address Luiz's comments:
  1: change the helper program parameter as bin  socket-fd   file-path ,
the program open the file itself now, data parameter is removed and blank
is always used as iov data, better usage tip message, folder the string parsing
code into a function.
  2: related change for helper program parameter change.
  3: related change for helper program parameter change.
  Other:
  1: remove LINK rule in makefile, remove fd checking code inside send_fd()
since it is already checked before calling, add '' around %s for path and
number string in error message.
  2: renamed fd_bin to bin in send_fd_scm() to tip better, add '' around %s
for path in error message.

Wenchao Xia (3):
  1 qemu-iotests: add unix socket help program
  2 qemu-iotests: add infrastructure of fd passing via SCM
  3 qemu-iotests: add tests for runtime fd passing via SCM rights

 QMP/qmp.py |6 ++
 configure  |2 +-
 tests/Makefile |3 +-
 tests/qemu-iotests/045 |   36 -
 tests/qemu-iotests/045.out |4 +-
 tests/qemu-iotests/check   |1 +
 tests/qemu-iotests/iotests.py  |   23 ++
 tests/qemu-iotests/socket_scm_helper.c |  135 
 8 files changed, 205 insertions(+), 5 deletions(-)
 create mode 100644 tests/qemu-iotests/socket_scm_helper.c





[Qemu-devel] [PATCH V3 1/3] qemu-iotests: add unix socket help program

2013-09-02 Thread Wenchao Xia
This program can do a sendmsg call to transfer fd with unix
socket, which is not supported in python2.

The built binary will not be deleted in clean, but it is a
existing issue in ./tests, which should be solved in another
patch.

Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com
---
 configure  |2 +-
 tests/Makefile |3 +-
 tests/qemu-iotests/socket_scm_helper.c |  135 
 3 files changed, 138 insertions(+), 2 deletions(-)
 create mode 100644 tests/qemu-iotests/socket_scm_helper.c

diff --git a/configure b/configure
index 0a55c20..5080c38 100755
--- a/configure
+++ b/configure
@@ -4544,7 +4544,7 @@ if [ $dtc_internal = yes ]; then
 fi
 
 # build tree in object directory in case the source is not in the current 
directory
-DIRS=tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos 
tests/qapi-schema tests/tcg/xtensa
+DIRS=tests tests/tcg tests/tcg/cris tests/tcg/lm32 tests/libqos 
tests/qapi-schema tests/tcg/xtensa tests/qemu-iotests
 DIRS=$DIRS pc-bios/optionrom pc-bios/spapr-rtas pc-bios/s390-ccw
 DIRS=$DIRS roms/seabios roms/vgabios
 DIRS=$DIRS qapi-generated
diff --git a/tests/Makefile b/tests/Makefile
index baba9e9..c285805 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -172,6 +172,7 @@ tests/boot-order-test$(EXESUF): tests/boot-order-test.o 
$(libqos-obj-y)
 tests/tmp105-test$(EXESUF): tests/tmp105-test.o $(libqos-omap-obj-y)
 tests/i440fx-test$(EXESUF): tests/i440fx-test.o $(libqos-pc-obj-y)
 tests/fw_cfg-test$(EXESUF): tests/fw_cfg-test.o $(libqos-pc-obj-y)
+tests/qemu-iotests/socket_scm_helper$(EXESUF): 
tests/qemu-iotests/socket_scm_helper.o
 
 # QTest rules
 
@@ -250,7 +251,7 @@ check-report.html: check-report.xml
 # Other tests
 
 .PHONY: check-tests/qemu-iotests-quick.sh
-check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh 
qemu-img$(EXESUF) qemu-io$(EXESUF)
+check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh 
qemu-img$(EXESUF) qemu-io$(EXESUF) tests/qemu-iotests/socket_scm_helper$(EXESUF)
$
 
 .PHONY: check-tests/test-qapi.py
diff --git a/tests/qemu-iotests/socket_scm_helper.c 
b/tests/qemu-iotests/socket_scm_helper.c
new file mode 100644
index 000..0e2b285
--- /dev/null
+++ b/tests/qemu-iotests/socket_scm_helper.c
@@ -0,0 +1,135 @@
+/*
+ * SCM_RIGHTS with unix socket help program for test
+ *
+ * Copyright IBM, Inc. 2013
+ *
+ * Authors:
+ *  Wenchao Xiaxiaw...@linux.vnet.ibm.com
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2 or later.
+ * See the COPYING.LIB file in the top-level directory.
+ */
+
+#include stdio.h
+#include errno.h
+#include sys/socket.h
+#include sys/un.h
+#include stdlib.h
+#include sys/types.h
+#include sys/stat.h
+#include fcntl.h
+#include unistd.h
+
+/* #define SOCKET_SCM_DEBUG */
+
+/*
+ * @fd and @fd_to_send will not be checked for validation in this function,
+ * a blank will be sent as iov data to notify qemu.
+ */
+static int send_fd(int fd, int fd_to_send)
+{
+struct msghdr msg;
+struct iovec iov[1];
+int ret;
+char control[CMSG_SPACE(sizeof(int))];
+struct cmsghdr *cmsg;
+
+memset(msg, 0, sizeof(msg));
+memset(control, 0, sizeof(control));
+
+/* Send a blank to notify qemu */
+iov[0].iov_base = (void *) ;
+iov[0].iov_len = 1;
+
+msg.msg_iov = iov;
+msg.msg_iovlen = 1;
+
+msg.msg_control = control;
+msg.msg_controllen = sizeof(control);
+
+cmsg = CMSG_FIRSTHDR(msg);
+
+cmsg-cmsg_len = CMSG_LEN(sizeof(int));
+cmsg-cmsg_level = SOL_SOCKET;
+cmsg-cmsg_type = SCM_RIGHTS;
+memcpy(CMSG_DATA(cmsg), fd, sizeof(int));
+
+do {
+ret = sendmsg(fd, msg, 0);
+} while (ret  0  errno == EINTR);
+
+if (ret  0) {
+fprintf(stderr, Failed to send msg, reason: %s\n, strerror(errno));
+}
+
+return ret;
+}
+
+/* Convert string to fd number. */
+static int get_fd_num(const char *fd_str)
+{
+int sock;
+char *err;
+
+errno = 0;
+sock = strtol(fd_str, err, 10);
+if (errno) {
+fprintf(stderr, Failed in strtol for socket fd, reason: %s\n,
+strerror(errno));
+return -1;
+}
+if (!*fd_str || *err || sock  0) {
+fprintf(stderr, bad numerical value for socket fd '%s'\n, fd_str);
+return -1;
+}
+
+return sock;
+}
+
+/*
+ * To make things simple, the caller needs to specify:
+ * 1. socket fd.
+ * 2. path of the file to be sent.
+ */
+int main(int argc, char **argv, char **envp)
+{
+int sock, fd, ret;
+
+#ifdef SOCKET_SCM_DEBUG
+int i;
+for (i = 0; i  argc; i++) {
+fprintf(stderr, Parameter %d: %s\n, i, argv[i]);
+}
+#endif
+
+if (argc != 3) {
+fprintf(stderr,
+Usage: %s  socket-fd   file-path \n,
+argv[0]);
+return EXIT_FAILURE;
+}
+
+
+sock = get_fd_num(argv[1]);
+if (sock  0) {
+return EXIT_FAILURE;
+}
+
+/* Now only open a file in 

[Qemu-devel] [PATCH V3 2/3] qemu-iotests: add infrastructure of fd passing via SCM

2013-09-02 Thread Wenchao Xia
This patch make use of the compiled scm helper program to transfer
fd via unix socket at runtime.

Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com
---
 QMP/qmp.py|6 ++
 tests/qemu-iotests/check  |1 +
 tests/qemu-iotests/iotests.py |   23 +++
 3 files changed, 30 insertions(+), 0 deletions(-)

diff --git a/QMP/qmp.py b/QMP/qmp.py
index c551df1..074f09a 100644
--- a/QMP/qmp.py
+++ b/QMP/qmp.py
@@ -188,3 +188,9 @@ class QEMUMonitorProtocol:
 
 def settimeout(self, timeout):
 self.__sock.settimeout(timeout)
+
+def get_sock_fd(self):
+return self.__sock.fileno()
+
+def is_scm_available(self):
+return self.__sock.family == socket.AF_UNIX
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 74628ae..2f7f78e 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -164,6 +164,7 @@ QEMU_IO   -- $QEMU_IO
 IMGFMT-- $FULL_IMGFMT_DETAILS
 IMGPROTO  -- $FULL_IMGPROTO_DETAILS
 PLATFORM  -- $FULL_HOST_DETAILS
+SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
 
 EOF
 #MKFS_OPTIONS  -- $FULL_MKFS_OPTIONS
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 33ad0ec..d79cc56 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -38,6 +38,8 @@ imgfmt = os.environ.get('IMGFMT', 'raw')
 imgproto = os.environ.get('IMGPROTO', 'file')
 test_dir = os.environ.get('TEST_DIR', '/var/tmp')
 
+socket_scm_helper = os.environ.get('SOCKET_SCM_HELPER', 'socket_scm_helper')
+
 def qemu_img(*args):
 '''Run qemu-img and return the exit code'''
 devnull = open('/dev/null', 'r+')
@@ -80,6 +82,12 @@ class VM(object):
  '-display', 'none', '-vga', 'none']
 self._num_drives = 0
 
+#This can be used to add unused monitor
+def add_monitor_telnet(self, ip, port):
+args = 'tcp:%s:%d,server,nowait,telnet' % (ip, port)
+self._args.append('-monitor')
+self._args.append(args)
+
 def add_drive(self, path, opts=''):
 '''Add a virtio-blk drive to the VM'''
 options = ['if=virtio',
@@ -112,6 +120,21 @@ class VM(object):
 self._args.append(','.join(options))
 return self
 
+def send_fd_scm(self, fd_file_path):
+#In iotest.py, the qmp should always use unix socket.
+assert self._qmp.is_scm_available()
+bin = socket_scm_helper
+if os.path.exists(bin) == False:
+print Scm help program does not present, path '%s'. % bin
+return -1
+fd_param = [%s % bin,
+%d % self._qmp.get_sock_fd(),
+%s % fd_file_path]
+devnull = open('/dev/null', 'rb')
+p = subprocess.Popen(fd_param, stdin=devnull, stdout=sys.stdout,
+ stderr=sys.stderr)
+return p.wait()
+
 def launch(self):
 '''Launch the VM and establish a QMP connection'''
 devnull = open('/dev/null', 'rb')
-- 
1.7.1





[Qemu-devel] [PATCH V3 3/3] qemu-iotests: add tests for runtime fd passing via SCM rights

2013-09-02 Thread Wenchao Xia
This case will test whether the monitor can receive fd at runtime.
To verify better, additional monitor is created to see if qemu
can handler two monitor instances correctly.

Signed-off-by: Wenchao Xia xiaw...@linux.vnet.ibm.com
---
 tests/qemu-iotests/045 |   36 +++-
 tests/qemu-iotests/045.out |4 ++--
 2 files changed, 37 insertions(+), 3 deletions(-)

diff --git a/tests/qemu-iotests/045 b/tests/qemu-iotests/045
index 2b6f1af..4381d8a 100755
--- a/tests/qemu-iotests/045
+++ b/tests/qemu-iotests/045
@@ -1,6 +1,6 @@
 #!/usr/bin/env python
 #
-# Tests for fdsets.
+# Tests for fdsets and getfd.
 #
 # Copyright (C) 2012 IBM Corp.
 #
@@ -125,5 +125,39 @@ class TestFdSets(iotests.QMPTestCase):
 'No file descriptor supplied via SCM_RIGHTS')
 self.vm.shutdown()
 
+#Add fd at runtime, there are two ways: monitor related or fdset related
+class TestSCMFd(iotests.QMPTestCase):
+def setUp(self):
+self.vm = iotests.VM()
+qemu_img('create', '-f', iotests.imgfmt, image0, '128K')
+#Add a unused monitor, to verify it works fine when two minitor present
+self.vm.add_monitor_telnet(0,4445)
+self.vm.launch()
+
+def tearDown(self):
+self.vm.shutdown()
+os.remove(image0)
+
+def _send_fd_by_SCM(self):
+ret = self.vm.send_fd_scm(image0)
+self.assertEqual(ret, 0, 'Failed to send fd with UNIX SCM')
+
+def test_add_fd(self):
+self._send_fd_by_SCM()
+result = self.vm.qmp('add-fd', fdset_id=2, opaque='image0:r')
+self.assert_qmp(result, 'return/fdset-id', 2)
+
+def test_getfd(self):
+self._send_fd_by_SCM()
+result = self.vm.qmp('getfd', fdname='image0:r')
+self.assert_qmp(result, 'return', {})
+
+def test_closefd(self):
+self._send_fd_by_SCM()
+result = self.vm.qmp('getfd', fdname='image0:r')
+self.assert_qmp(result, 'return', {})
+result = self.vm.qmp('closefd', fdname='image0:r')
+self.assert_qmp(result, 'return', {})
+
 if __name__ == '__main__':
 iotests.main(supported_fmts=['raw'])
diff --git a/tests/qemu-iotests/045.out b/tests/qemu-iotests/045.out
index 3f8a935..dae404e 100644
--- a/tests/qemu-iotests/045.out
+++ b/tests/qemu-iotests/045.out
@@ -1,5 +1,5 @@
-..
+.
 --
-Ran 6 tests
+Ran 9 tests
 
 OK
-- 
1.7.1





Re: [Qemu-devel] [PATCH 0/6][RFC] AArch64 support for Versatile Express using KVM

2013-09-02 Thread Andreas Färber
Alex,

Am 28.06.2013 15:04, schrieb Andreas Färber:
 Am 28.06.2013 14:44, schrieb Peter Maydell:
 On 28 June 2013 13:20, Mian M. Hamayun m.hama...@virtualopensystems.com 
 wrote:
 This patch series implements KVM support in QEMU for the ARMv8 Cortex
 A57 CPU.
 It depends on the previously submitted AArch64 Preparation Patchset V4,
 and uses
 as a base, the existing Versatile Express machine model and the already
 available KVM in-kernel GIC support.

 This rather overlaps with a bunch of work John Rigby has already done
 (though not yet published to the mailing lists):

 https://git.linaro.org/gitweb?p=people/pmaydell/qemu-aarch64.git;a=shortlog;h=refs/heads/kvm-aarch64-wip

 so now we need to reconcile the two trees. If you'd let us know
 you were doing this a bit earlier we could probably have
 coordinated something...
 
 I had been looking into that tree myself, and apart from John's
 Linux'ish ARM:  prefixes rather than our usual target-arm:  (part of
 which you forgot to fix before sending a PULL), I am really opposed to
 copying A15MPCore_priv for A57. I plan to post a cleanup for the A9
 version the weekend, now that we have a more elaborate hw/ directory
 structure for headers.
 
 Also I would really prefer to have the is_aarch64() helper operate on
 ARMCPU rather than CPUARMState. QOM cast removal is underway to make
 that more efficient.
 
 Is there a 32-bit aarch64 register in ARMv8 to be accessed by TCG? If
 not, the field should be in ARMCPU and a bool rather than uint32_t.

Care to comment on the latter?

Regards,
Andreas

-- 
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg, Germany
GF: Jeff Hawn, Jennifer Guild, Felix Imendörffer; HRB 16746 AG Nürnberg



[Qemu-devel] [PATCH] spice-core: Use g_strdup_printf instead of snprintf

2013-09-02 Thread Christophe Fergeau
Several places in spice-core.c were using either g_malloc+snprintf
or snprintf+g_strdup to achieve the same result as g_strdup_printf.

Signed-off-by: Christophe Fergeau cferg...@redhat.com
---
 ui/spice-core.c | 22 --
 1 file changed, 8 insertions(+), 14 deletions(-)

diff --git a/ui/spice-core.c b/ui/spice-core.c
index bd7a248..01b9906 100644
--- a/ui/spice-core.c
+++ b/ui/spice-core.c
@@ -511,7 +511,6 @@ SpiceInfo *qmp_query_spice(Error **errp)
 int port, tls_port;
 const char *addr;
 SpiceInfo *info;
-char version_string[20]; /* 12 = |255.255.255\0| is the max */
 
 info = g_malloc0(sizeof(*info));
 
@@ -534,11 +533,10 @@ SpiceInfo *qmp_query_spice(Error **errp)
 info-host = g_strdup(addr ? addr : 0.0.0.0);
 
 info-has_compiled_version = true;
-snprintf(version_string, sizeof(version_string), %d.%d.%d,
- (SPICE_SERVER_VERSION  0xff)  16,
- (SPICE_SERVER_VERSION  0xff00)  8,
- SPICE_SERVER_VERSION  0xff);
-info-compiled_version = g_strdup(version_string);
+info-compiled_version = g_strdup_printf(%d.%d.%d,
+ (SPICE_SERVER_VERSION  0xff) 
 16,
+ (SPICE_SERVER_VERSION  0xff00) 
 8,
+ SPICE_SERVER_VERSION  0xff);
 
 if (port) {
 info-has_port = true;
@@ -640,7 +638,7 @@ void qemu_spice_init(void)
 char *x509_key_file = NULL,
 *x509_cert_file = NULL,
 *x509_cacert_file = NULL;
-int port, tls_port, len, addr_flags;
+int port, tls_port, addr_flags;
 spice_image_compression_t compression;
 spice_wan_compression_t wan_compr;
 bool seamless_migration;
@@ -671,30 +669,26 @@ void qemu_spice_init(void)
 if (NULL == x509_dir) {
 x509_dir = .;
 }
-len = strlen(x509_dir) + 32;
 
 str = qemu_opt_get(opts, x509-key-file);
 if (str) {
 x509_key_file = g_strdup(str);
 } else {
-x509_key_file = g_malloc(len);
-snprintf(x509_key_file, len, %s/%s, x509_dir, 
X509_SERVER_KEY_FILE);
+x509_key_file = g_strdup_printf(%s/%s, x509_dir, 
X509_SERVER_KEY_FILE);
 }
 
 str = qemu_opt_get(opts, x509-cert-file);
 if (str) {
 x509_cert_file = g_strdup(str);
 } else {
-x509_cert_file = g_malloc(len);
-snprintf(x509_cert_file, len, %s/%s, x509_dir, 
X509_SERVER_CERT_FILE);
+x509_cert_file = g_strdup_printf(%s/%s, x509_dir, 
X509_SERVER_CERT_FILE);
 }
 
 str = qemu_opt_get(opts, x509-cacert-file);
 if (str) {
 x509_cacert_file = g_strdup(str);
 } else {
-x509_cacert_file = g_malloc(len);
-snprintf(x509_cacert_file, len, %s/%s, x509_dir, 
X509_CA_CERT_FILE);
+x509_cacert_file = g_strdup_printf(%s/%s, x509_dir, 
X509_CA_CERT_FILE);
 }
 
 x509_key_password = qemu_opt_get(opts, x509-key-password);
-- 
1.8.3.1




Re: [Qemu-devel] [PATCH 0/6][RFC] AArch64 support for Versatile Express using KVM

2013-09-02 Thread Peter Maydell
On 2 September 2013 10:46, Andreas Färber afaer...@suse.de wrote:
 Am 28.06.2013 15:04, schrieb Andreas Färber:
 Is there a 32-bit aarch64 register in ARMv8 to be accessed by TCG? If
 not, the field should be in ARMCPU and a bool rather than uint32_t.

 Care to comment on the latter?

I don't suppose the usermode emulation touches it, but the
architectural state corresponding to that 'aarch64' field is the
PSTATE nRW bit. I don't think this bit is directly accessible via
a register access though (other PSTATE bits may be).

thanks
-- PMM



[Qemu-devel] [PATCH v4 1/5] block: Image file option amendment

2013-09-02 Thread Max Reitz
This patch adds the amend option to qemu-img which allows changing
image options on existing image files. It also adds the generic bdrv
implementation which is basically just a wrapper for the image format
specific function.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block.c   |  8 +
 include/block/block.h |  2 ++
 include/block/block_int.h |  3 ++
 qemu-img-cmds.hx  |  6 
 qemu-img.c| 84 +++
 qemu-img.texi |  5 +++
 6 files changed, 108 insertions(+)

diff --git a/block.c b/block.c
index a387c1a..9c40a15 100644
--- a/block.c
+++ b/block.c
@@ -4674,3 +4674,11 @@ void bdrv_add_before_write_notifier(BlockDriverState *bs,
 {
 notifier_with_return_list_add(bs-before_write_notifiers, notifier);
 }
+
+int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options)
+{
+if (bs-drv-bdrv_amend_options == NULL) {
+return -ENOTSUP;
+}
+return bs-drv-bdrv_amend_options(bs, options);
+}
diff --git a/include/block/block.h b/include/block/block.h
index e6b391c..c284b4a 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -223,6 +223,8 @@ typedef enum {
 
 int bdrv_check(BlockDriverState *bs, BdrvCheckResult *res, BdrvCheckMode fix);
 
+int bdrv_amend_options(BlockDriverState *bs_new, QEMUOptionParameter *options);
+
 /* async block I/O */
 typedef void BlockDriverDirtyHandler(BlockDriverState *bs, int64_t sector,
  int sector_num);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 8012e25..3c93766 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -205,6 +205,9 @@ struct BlockDriver {
 int (*bdrv_check)(BlockDriverState* bs, BdrvCheckResult *result,
 BdrvCheckMode fix);
 
+int (*bdrv_amend_options)(BlockDriverState *bs,
+QEMUOptionParameter *options);
+
 void (*bdrv_debug_event)(BlockDriverState *bs, BlkDebugEvent event);
 
 /* TODO Better pass a option string/QDict/QemuOpts to add any rule? */
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 4ca7e95..5a066b5 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -61,5 +61,11 @@ DEF(resize, img_resize,
 resize [-q] filename [+ | -]size)
 STEXI
 @item resize [-q] @var{filename} [+ | -]@var{size}
+ETEXI
+
+DEF(amend, img_amend,
+amend [-q] [-f fmt] -o options filename)
+STEXI
+@item amend [-q] [-f @var{fmt}] -o @var{options} @var{filename}
 @end table
 ETEXI
diff --git a/qemu-img.c b/qemu-img.c
index b9a848d..7a8f064 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2308,6 +2308,90 @@ out:
 return 0;
 }
 
+static int img_amend(int argc, char **argv)
+{
+int c, ret = 0;
+char *options = NULL;
+QEMUOptionParameter *create_options = NULL, *options_param = NULL;
+const char *fmt = NULL, *filename;
+bool quiet = false;
+BlockDriverState *bs = NULL;
+
+for (;;) {
+c = getopt(argc, argv, hqf:o:);
+if (c == -1) {
+break;
+}
+
+switch (c) {
+case 'h':
+case '?':
+help();
+break;
+case 'o':
+options = optarg;
+break;
+case 'f':
+fmt = optarg;
+break;
+case 'q':
+quiet = true;
+break;
+}
+}
+
+if (optind != argc - 1) {
+help();
+}
+
+if (!options) {
+help();
+}
+
+filename = argv[argc - 1];
+
+bs = bdrv_new_open(filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR, true, quiet);
+if (!bs) {
+error_report(Could not open image '%s', filename);
+ret = -1;
+goto out;
+}
+
+fmt = bs-drv-format_name;
+
+if (is_help_option(options)) {
+ret = print_block_option_help(filename, fmt);
+goto out;
+}
+
+create_options = append_option_parameters(create_options,
+bs-drv-create_options);
+options_param = parse_option_parameters(options, create_options,
+options_param);
+if (options_param == NULL) {
+error_report(Invalid options for file format '%s', fmt);
+ret = -1;
+goto out;
+}
+
+ret = bdrv_amend_options(bs, options_param);
+if (ret  0) {
+error_report(Error while amending options: %s, strerror(-ret));
+goto out;
+}
+
+out:
+if (bs) {
+bdrv_delete(bs);
+}
+free_option_parameters(create_options);
+free_option_parameters(options_param);
+if (ret) {
+return 1;
+}
+return 0;
+}
+
 static const img_cmd_t img_cmds[] = {
 #define DEF(option, callback, arg_string)\
 { option, callback },
diff --git a/qemu-img.texi b/qemu-img.texi
index 69f1bda..8697f23 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -282,6 +282,11 @@ sizes accordingly.  Failure to do so will result in data 
loss!
 After using this command to grow a 

[Qemu-devel] [PATCH v4 2/5] qcow2-cluster: Expand zero clusters

2013-09-02 Thread Max Reitz
Add functionality for expanding zero clusters. This is necessary for
downgrading the image version to one without zero cluster support.

For non-backed images, this function may also just discard zero clusters
instead of truly expanding them.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2-cluster.c  | 228 +
 block/qcow2-refcount.c |  29 ---
 block/qcow2.h  |   5 ++
 3 files changed, 248 insertions(+), 14 deletions(-)

diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index 2d5aa92..c90fb51 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1497,3 +1497,231 @@ fail:
 
 return ret;
 }
+
+/*
+ * Expands all zero clusters in a specific L1 table (or deallocates them, for
+ * non-backed non-pre-allocated zero clusters).
+ *
+ * expanded_clusters is a bitmap where every bit corresponds to one cluster in
+ * the image file; a bit gets set if the corresponding cluster has been used 
for
+ * zero expansion (i.e., has been filled with zeroes and is referenced from an
+ * L2 table). nb_clusters contains the total cluster count of the image file,
+ * i.e., the number of bits in expanded_clusters.
+ */
+static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
+  int l1_size, uint8_t *expanded_clusters,
+  uint64_t nb_clusters)
+{
+BDRVQcowState *s = bs-opaque;
+bool is_active_l1 = (l1_table == s-l1_table);
+uint64_t *l2_table = NULL;
+int ret;
+int i, j;
+
+if (!is_active_l1) {
+/* inactive L2 tables require a buffer to be stored in when loading
+ * them from disk */
+l2_table = qemu_blockalign(bs, s-cluster_size);
+}
+
+for (i = 0; i  l1_size; i++) {
+uint64_t l2_offset = l1_table[i]  L1E_OFFSET_MASK;
+bool l2_dirty = false;
+
+if (!l2_offset) {
+/* unallocated */
+continue;
+}
+
+if (is_active_l1) {
+/* get active L2 tables from cache */
+ret = qcow2_cache_get(bs, s-l2_table_cache, l2_offset,
+(void **)l2_table);
+} else {
+/* load inactive L2 tables from disk */
+ret = bdrv_read(bs-file, l2_offset / BDRV_SECTOR_SIZE,
+(void *)l2_table, s-cluster_sectors);
+}
+if (ret  0) {
+goto fail;
+}
+
+for (j = 0; j  s-l2_size; j++) {
+uint64_t l2_entry = be64_to_cpu(l2_table[j]);
+int64_t offset = l2_entry  L2E_OFFSET_MASK, cluster_index;
+int cluster_type = qcow2_get_cluster_type(l2_entry);
+
+if (cluster_type == QCOW2_CLUSTER_NORMAL) {
+cluster_index = offset  s-cluster_bits;
+assert((cluster_index = 0)  (cluster_index  nb_clusters));
+if (expanded_clusters[cluster_index / 8] 
+(1  (cluster_index % 8))) {
+/* Probably a shared L2 table; this cluster was a zero
+ * cluster which has been expanded, its refcount
+ * therefore most likely requires an update. */
+ret = qcow2_update_cluster_refcount(bs, cluster_index, 1,
+QCOW2_DISCARD_NEVER);
+if (ret  0) {
+goto fail;
+}
+/* Since we just increased the refcount, the COPIED flag 
may
+ * no longer be set. */
+l2_table[j] = cpu_to_be64(l2_entry  ~QCOW_OFLAG_COPIED);
+l2_dirty = true;
+}
+continue;
+}
+else if (qcow2_get_cluster_type(l2_entry) != QCOW2_CLUSTER_ZERO) {
+continue;
+}
+
+if (!offset) {
+/* not preallocated */
+if (!bs-backing_hd) {
+/* not backed; therefore we can simply deallocate the
+ * cluster */
+l2_table[j] = 0;
+l2_dirty = true;
+continue;
+}
+
+offset = qcow2_alloc_clusters(bs, s-cluster_size);
+if (offset  0) {
+ret = offset;
+goto fail;
+}
+}
+
+ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_DEFAULT,
+offset, s-cluster_size);
+if (ret  0) {
+qcow2_free_clusters(bs, offset, s-cluster_size,
+QCOW2_DISCARD_ALWAYS);
+goto fail;
+}
+
+ret = bdrv_write_zeroes(bs-file, offset / BDRV_SECTOR_SIZE,
+s-cluster_sectors);
+if (ret  0) {
+qcow2_free_clusters(bs, offset, 

[Qemu-devel] [PATCH v4 0/5] block/qcow2: Image file option amendment

2013-09-02 Thread Max Reitz
This series adds support to qemu-img, block and qcow2 for amending image
options on existing image files.

Depends on:
 - option: Add assigned flag to QEMUOptionParameter
 - qcow2-refcount: Snapshot update for zero clusters (series, v3)
 - Add metadata overlap checks (series, v5)

v4:
 - rebased on the metadata overlap check series (and fit to it)
 - split patch 2 into three distinct patches (2, 3 and 4)
 - extended test for zero expansion on backed and inactive backed clusters
   (and fixed according to the metadata overlap check series (i.e.,
   adjusted header length))
 - fixed zero expansion with shared L2 tables

v3:
 - deallocate non-preallocated zero clusters on non-backed images instead
   of zero expanding them
 - qcow2 version downgrade: error out on refcount_order != 4
 - implemented Eric's comments regarding the qemu-img amend and img_amend
   itself

v2:
 - Generally implemented Kevin's comments, especially:
   - Zero cluster expansion for inactive L2 tables
   - Correct handling of preallocated zero clusters
   - More test cases

Max Reitz (5):
  block: Image file option amendment
  qcow2-cluster: Expand zero clusters
  qcow2: Save refcount order in BDRVQcowState
  qcow2: Implement bdrv_amend_options
  qemu-iotest: qcow2 image option amendment

 block.c|   8 ++
 block/qcow2-cluster.c  | 228 +
 block/qcow2-refcount.c |  29 ++--
 block/qcow2.c  | 198 -
 block/qcow2.h  |   6 +
 include/block/block.h  |   2 +
 include/block/block_int.h  |   3 +
 qemu-img-cmds.hx   |   6 +
 qemu-img.c |  84 +++
 qemu-img.texi  |   5 +
 tests/qemu-iotests/061 | 178 +++
 tests/qemu-iotests/061.out | 349 +
 tests/qemu-iotests/group   |   1 +
 13 files changed, 1082 insertions(+), 15 deletions(-)
 create mode 100755 tests/qemu-iotests/061
 create mode 100644 tests/qemu-iotests/061.out

-- 
1.8.3.1




[Qemu-devel] [PATCH v4 3/5] qcow2: Save refcount order in BDRVQcowState

2013-09-02 Thread Max Reitz
Save the image refcount order in BDRVQcowState. This will be relevant
for future code supporting different refcount orders than four and also
for code that needs to verify a certain refcount order for an opened
image.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qcow2.c | 3 ++-
 block/qcow2.h | 1 +
 2 files changed, 3 insertions(+), 1 deletion(-)

diff --git a/block/qcow2.c b/block/qcow2.c
index aeb2ebb..28b104e 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -455,6 +455,7 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, 
int flags)
 ret = -ENOTSUP;
 goto fail;
 }
+s-refcount_order = header.refcount_order;
 
 if (header.cluster_bits  MIN_CLUSTER_BITS ||
 header.cluster_bits  MAX_CLUSTER_BITS) {
@@ -1133,7 +1134,7 @@ int qcow2_update_header(BlockDriverState *bs)
 .incompatible_features  = cpu_to_be64(s-incompatible_features),
 .compatible_features= cpu_to_be64(s-compatible_features),
 .autoclear_features = cpu_to_be64(s-autoclear_features),
-.refcount_order = cpu_to_be32(3 + REFCOUNT_SHIFT),
+.refcount_order = cpu_to_be32(s-refcount_order),
 .header_length  = cpu_to_be32(header_length),
 };
 
diff --git a/block/qcow2.h b/block/qcow2.h
index 25176ac..b070709 100644
--- a/block/qcow2.h
+++ b/block/qcow2.h
@@ -199,6 +199,7 @@ typedef struct BDRVQcowState {
 int flags;
 int qcow_version;
 bool use_lazy_refcounts;
+int refcount_order;
 
 bool discard_passthrough[QCOW2_DISCARD_MAX];
 
-- 
1.8.3.1




[Qemu-devel] [PATCH v4 5/5] qemu-iotest: qcow2 image option amendment

2013-09-02 Thread Max Reitz
Add tests for qemu-img amend on qcow2 image files.

Signed-off-by: Max Reitz mre...@redhat.com
---
 tests/qemu-iotests/061 | 178 +++
 tests/qemu-iotests/061.out | 349 +
 tests/qemu-iotests/group   |   1 +
 3 files changed, 528 insertions(+)
 create mode 100755 tests/qemu-iotests/061
 create mode 100644 tests/qemu-iotests/061.out

diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
new file mode 100755
index 000..86404e6
--- /dev/null
+++ b/tests/qemu-iotests/061
@@ -0,0 +1,178 @@
+#!/bin/bash
+#
+# Test case for image option amendment in qcow2.
+#
+# Copyright (C) 2013 Red Hat, Inc.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see http://www.gnu.org/licenses/.
+#
+
+# creator
+owner=mre...@redhat.com
+
+seq=`basename $0`
+echo QA output created by $seq
+
+here=`pwd`
+tmp=/tmp/$$
+status=1   # failure is the default!
+
+_cleanup()
+{
+   _cleanup_test_img
+}
+trap _cleanup; exit \$status 0 1 2 3 15
+
+# get standard environment, filters and checks
+. ./common.rc
+. ./common.filter
+
+# This tests qocw2-specific low-level functionality
+_supported_fmt qcow2
+_supported_proto generic
+_supported_os Linux
+
+echo
+echo === Testing version downgrade with zero expansion ===
+echo
+IMGOPTS=compat=1.1,lazy_refcounts=on _make_test_img 64M
+$QEMU_IO -c write -z 0 128k $TEST_IMG | _filter_qemu_io
+./qcow2.py $TEST_IMG dump-header
+$QEMU_IMG amend -o compat=0.10 $TEST_IMG
+./qcow2.py $TEST_IMG dump-header
+$QEMU_IO -c read -P 0 0 128k $TEST_IMG | _filter_qemu_io
+_check_test_img
+
+echo
+echo === Testing dirty version downgrade ===
+echo
+IMGOPTS=compat=1.1,lazy_refcounts=on _make_test_img 64M
+$QEMU_IO -c write -P 0x2a 0 128k -c flush -c abort $TEST_IMG | 
_filter_qemu_io
+./qcow2.py $TEST_IMG dump-header
+$QEMU_IMG amend -o compat=0.10 $TEST_IMG
+./qcow2.py $TEST_IMG dump-header
+$QEMU_IO -c read -P 0x2a 0 128k $TEST_IMG | _filter_qemu_io
+_check_test_img
+
+echo
+echo === Testing version downgrade with unknown compat/autoclear flags ===
+echo
+IMGOPTS=compat=1.1 _make_test_img 64M
+./qcow2.py $TEST_IMG set-feature-bit compatible 42
+./qcow2.py $TEST_IMG set-feature-bit autoclear 42
+./qcow2.py $TEST_IMG dump-header
+$QEMU_IMG amend -o compat=0.10 $TEST_IMG
+./qcow2.py $TEST_IMG dump-header
+_check_test_img
+
+echo
+echo === Testing version upgrade and resize ===
+echo
+IMGOPTS=compat=0.10 _make_test_img 64M
+$QEMU_IO -c write -P 0x2a 42M 64k $TEST_IMG | _filter_qemu_io
+./qcow2.py $TEST_IMG dump-header
+$QEMU_IMG amend -o compat=1.1,lazy_refcounts=on,size=128M $TEST_IMG
+./qcow2.py $TEST_IMG dump-header
+$QEMU_IO -c read -P 0x2a 42M 64k $TEST_IMG | _filter_qemu_io
+_check_test_img
+
+echo
+echo === Testing dirty lazy_refcounts=off ===
+echo
+IMGOPTS=compat=1.1,lazy_refcounts=on _make_test_img 64M
+$QEMU_IO -c write -P 0x2a 0 128k -c flush -c abort $TEST_IMG | 
_filter_qemu_io
+./qcow2.py $TEST_IMG dump-header
+$QEMU_IMG amend -o lazy_refcounts=off $TEST_IMG
+./qcow2.py $TEST_IMG dump-header
+$QEMU_IO -c read -P 0x2a 0 128k $TEST_IMG | _filter_qemu_io
+_check_test_img
+
+echo
+echo === Testing backing file ===
+echo
+IMGOPTS=compat=1.1 _make_test_img 64M
+IMGOPTS=compat=1.1 TEST_IMG=$TEST_IMG.base _make_test_img 64M
+$QEMU_IO -c write -P 0x2a 0 128k $TEST_IMG.base | _filter_qemu_io
+$QEMU_IO -c read -P 0 0 128k $TEST_IMG | _filter_qemu_io
+$QEMU_IMG amend -o backing_file=$TEST_IMG.base,backing_fmt=qcow2 $TEST_IMG
+$QEMU_IO -c read -P 0x2a 0 128k $TEST_IMG | _filter_qemu_io
+_check_test_img
+
+echo
+echo === Testing invalid configurations ===
+echo
+IMGOPTS=compat=0.10 _make_test_img 64M
+$QEMU_IMG amend -o lazy_refcounts=on $TEST_IMG
+$QEMU_IMG amend -o compat=1.1 $TEST_IMG # actually valid
+$QEMU_IMG amend -o compat=0.10,lazy_refcounts=on $TEST_IMG
+$QEMU_IMG amend -o compat=0.42 $TEST_IMG
+$QEMU_IMG amend -o foo=bar $TEST_IMG
+$QEMU_IMG amend -o cluster_size=1k $TEST_IMG
+$QEMU_IMG amend -o encryption=on $TEST_IMG
+$QEMU_IMG amend -o preallocation=on $TEST_IMG
+
+echo
+echo === Testing correct handling of unset value ===
+echo
+IMGOPTS=compat=1.1,cluster_size=1k _make_test_img 64M
+echo Should work:
+$QEMU_IMG amend -o lazy_refcounts=on $TEST_IMG
+echo Should not work: # Just to know which of these tests actually fails
+$QEMU_IMG amend -o cluster_size=64k $TEST_IMG
+
+echo
+echo === Testing zero expansion on inactive clusters ===
+echo
+IMGOPTS=compat=1.1 

  1   2   3   4   >