Re: [Qemu-devel] [PATCH 4/4] vhost-scsi: add an ioctl interface to get target id

2015-01-26 Thread Gonglei
On 2015/1/26 20:16, Paolo Bonzini wrote:

 
 
 On 26/01/2015 13:13, Gonglei wrote:

 That's okay, alternatively you could add a boot_tpgt argument that
 defaults to 1 (is it correct that 0 is not a valid tpgt?).

 No, 0 is the minimize valid value. :)
 Paolo, where do you think we should add a boot_tpgt argument?
 
 To vhost-scsi-pci.  (Property, not argument).
 

Got it. Thanks.

BTW, I will send the kernel patch later. :)

Regards,
-Gonglei




[Qemu-devel] [RFC] optimization for qcow2 cache get/put

2015-01-26 Thread Zhang Haoyu
Hi, all

Regarding too large qcow2 image, e.g., 2TB,
so long disruption happened when performing snapshot,
which was caused by cache update and IO wait.
perf top data shown as below,
   PerfTop:2554 irqs/sec  kernel: 0.4%  exact:  0.0% [4000Hz cycles],  
(target_pid: 34294)


33.80%  qemu-system-x86_64  [.] qcow2_cache_do_get
27.59%  qemu-system-x86_64  [.] qcow2_cache_put   
15.19%  qemu-system-x86_64  [.] qcow2_cache_entry_mark_dirty  
 5.49%  qemu-system-x86_64  [.] update_refcount   
 3.02%  libpthread-2.13.so  [.] pthread_getspecific   
 2.26%  qemu-system-x86_64  [.] get_refcount  
 1.95%  qemu-system-x86_64  [.] coroutine_get_thread_state
 1.32%  qemu-system-x86_64  [.] qcow2_update_snapshot_refcount
 1.20%  qemu-system-x86_64  [.] qemu_coroutine_self   
 1.16%  libz.so.1.2.7   [.] 0x3018
 0.95%  qemu-system-x86_64  [.] qcow2_update_cluster_refcount 
 0.91%  qemu-system-x86_64  [.] qcow2_cache_get   
 0.76%  libc-2.13.so[.] 0x00134e49
 0.73%  qemu-system-x86_64  [.] bdrv_debug_event  
 0.16%  qemu-system-x86_64  [.] pthread_getspecific@plt   
 0.12%  [kernel][k] _raw_spin_unlock_irqrestore   
 0.10%  qemu-system-x86_64  [.] vga_draw_line24_32
 0.09%  [vdso]  [.] 0x060c
 0.09%  qemu-system-x86_64  [.] qcow2_check_metadata_overlap  
 0.08%  [kernel][k] do_blockdev_direct_IO  

If expand the cache table size, the IO will be decreased, 
but the calculation time will be grown.
so it's worthy to optimize qcow2 cache get and put algorithm.

My proposal:
get:
using ((use offset  cluster_bits) % c-size) to locate the cache entry,
raw implementation,
index = (use offset  cluster_bits) % c-size;
if (c-entries[index].offset == offset) {
goto found;
}

replace:
c-entries[use offset  cluster_bits) % c-size].offset = offset;
...

put:
using 64-entries cache table to cache
the recently got c-entries, i.e., cache for cache,
then during put process, firstly search the 64-entries cache,
if not found, then the c-entries.

Any idea?

Thanks,
Zhang Haoyu




Re: [Qemu-devel] [PATCH v2 00/14] block: Remove growable, add blk_new_open()

2015-01-26 Thread Stefano Stabellini
On Thu, 22 Jan 2015, Max Reitz wrote:
 This series removes the growable field from the BlockDriverState
 object. Its use was to clamp guest requests against the limits of the
 BDS; however, this can now be done more easily by moving those checks
 into the BlockBackend functions.
 
 In a future series, growable may be reintroduced (maybe with a
 different name); it will then signify whether a BDS is able to grow (in
 contrast to the current growable, which signifies whether it is
 allowed to). Maybe I will add it to the BlockDriver instead of the BDS,
 though.
 
 To be able to remove that field, qemu-io needs to be converted to
 BlockBackend, which is done by this series as well. While working on
 that I decided to convert blk_new_with_bs()+bdrv_open() to
 blk_new_open(). I was skeptical about that decision at first, but it
 seems good now that I was able to replace nearly every blk_new_with_bs()
 call by blk_new_open(). In a future series I may try to convert some
 remaining bdrv_open() calls to blk_new_open() as well. (And, in fact, in
 a future series I *will* replace the last remaining blk_new_with_bs()
 outside of blk_new_open() by blk_new_open().)
 
 Finally, the question needs to be asked: If, after this series, every
 BDS is allowed to grow, are there any users which do not use BB, but
 should still be disallowed from reading/writing beyond a BDS's limits?
 The only users I could see were the block jobs. Some of them should
 indeed be converted to BB; but none of them takes a user-supplied offset
 or size, all work on the full BDS (or only on parts which have been
 modified, etc.). Therefore, it is by design impossible for them to
 exceed the BDS's limits, which makes making all BDS's growable safe.

Hello Max,
I applied the first four patches in this series, and this is what I get:

hw/block/xen_disk.c: In function ‘blk_connect’:
hw/block/xen_disk.c:907:27: error: implicit declaration of function 
‘qstring_from_str’ [-Werror=implicit-function-declaration]
hw/block/xen_disk.c:907:27: error: nested extern declaration of 
‘qstring_from_str’ [-Werror=nested-externs]
hw/block/xen_disk.c:907:27: error: invalid type argument of ‘-’ (have ‘int’)
hw/block/xen_disk.c:901:22: error: unused variable ‘drv’ 
[-Werror=unused-variable]
hw/block/xen_disk.c:900:23: error: unused variable ‘blk’ 
[-Werror=unused-variable]

it would be great if you could build test it.


 
 v2:
 - Rebased [Kevin]
 - Patch 2: Added a TODO comment about removing @filename and @flags from
   blk_new_open() when possible [Kevin]
 
 
 git-backport-diff against v1:
 
 Key:
 [] : patches are identical
 [] : number of functional differences between upstream/downstream patch
 [down] : patch is downstream-only
 The flags [FC] indicate (F)unctional and (C)ontextual differences, 
 respectively
 
 001/14:[] [--] 'block: Lift some BDS functions to the BlockBackend'
 002/14:[0006] [FC] 'block: Add blk_new_open()'
 003/14:[] [-C] 'blockdev: Use blk_new_open() in blockdev_init()'
 004/14:[] [--] 'block/xen: Use blk_new_open() in blk_connect()'
 005/14:[] [--] 'qemu-img: Use blk_new_open() in img_open()'
 006/14:[] [--] 'qemu-img: Use blk_new_open() in img_rebase()'
 007/14:[] [--] 'qemu-img: Use BlockBackend as far as possible'
 008/14:[] [--] 'qemu-nbd: Use blk_new_open() in main()'
 009/14:[] [--] 'qemu-io: Use blk_new_open() in openfile()'
 010/14:[0002] [FC] 'qemu-io: Remove growable option'
 011/14:[] [--] 'qemu-io: Use BlockBackend'
 012/14:[] [--] 'block: Clamp BlockBackend requests'
 013/14:[] [--] 'block: Remove growable from BDS'
 014/14:[] [--] 'block: Keep bdrv_check*_request()'s return value'
 
 
 Max Reitz (14):
   block: Lift some BDS functions to the BlockBackend
   block: Add blk_new_open()
   blockdev: Use blk_new_open() in blockdev_init()
   block/xen: Use blk_new_open() in blk_connect()
   qemu-img: Use blk_new_open() in img_open()
   qemu-img: Use blk_new_open() in img_rebase()
   qemu-img: Use BlockBackend as far as possible
   qemu-nbd: Use blk_new_open() in main()
   qemu-io: Use blk_new_open() in openfile()
   qemu-io: Remove growable option
   qemu-io: Use BlockBackend
   block: Clamp BlockBackend requests
   block: Remove growable from BDS
   block: Keep bdrv_check*_request()'s return value
 
  block.c|  59 +-
  block/block-backend.c  | 219 +
  block/qcow2.c  |   6 --
  block/raw-posix.c  |   2 +-
  block/raw-win32.c  |   2 +-
  block/sheepdog.c   |   2 +-
  blockdev.c |  92 
  hmp.c  |   9 +-
  hw/block/xen_disk.c|  24 ++---
  include/block/block_int.h  |   3 -
  include/qemu-io.h  |   4 +-
  include/sysemu/block-backend.h |  12 +++
  qemu-img.c | 171 ++---
  qemu-io-cmds.c | 238 
 

Re: [Qemu-devel] [PULL 0/1] Xen tree 2015-01-26

2015-01-26 Thread Peter Maydell
On 26 January 2015 at 12:00, Stefano Stabellini
stefano.stabell...@eu.citrix.com wrote:
 The following changes since commit b3a4755a67a52aa7297eb8927b482d09dabdefec:

   Merge remote-tracking branch 'remotes/kraxel/tags/pull-vnc-20150122-1' into 
 staging (2015-01-22 12:14:19 +)

 are available in the git repository at:


   git://xenbits.xen.org/people/sstabellini/qemu-dm.git xen-2015-01-26

 for you to fetch changes up to d01a5a3fe19645f3cdea1566f0e518ea2152a029:

   fix QEMU build on Xen/ARM (2015-01-26 11:56:33 +)

 
 Stefano Stabellini (1):
   fix QEMU build on Xen/ARM

Applied, thanks.

-- PMM



[Qemu-devel] [PATCH v3 2/2] target-arm: Add checks that cpreg raw accesses are handled

2015-01-26 Thread Peter Maydell
Add assertion checking when cpreg structures are registered that they
either forbid raw-access attempts or at least make an attempt at
handling them. Also add an assert in the raw-accessor-of-last-resort,
to avoid silently doing a read or write from offset zero, which is
actually AArch32 CPU register r0.

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

diff --git a/target-arm/helper.c b/target-arm/helper.c
index 18f04b2..95b1679 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -119,6 +119,7 @@ static int aarch64_fpu_gdb_set_reg(CPUARMState *env, 
uint8_t *buf, int reg)
 
 static uint64_t raw_read(CPUARMState *env, const ARMCPRegInfo *ri)
 {
+assert(ri-fieldoffset);
 if (cpreg_field_is_64bit(ri)) {
 return CPREG_FIELD64(env, ri);
 } else {
@@ -129,6 +130,7 @@ static uint64_t raw_read(CPUARMState *env, const 
ARMCPRegInfo *ri)
 static void raw_write(CPUARMState *env, const ARMCPRegInfo *ri,
   uint64_t value)
 {
+assert(ri-fieldoffset);
 if (cpreg_field_is_64bit(ri)) {
 CPREG_FIELD64(env, ri) = value;
 } else {
@@ -174,6 +176,27 @@ static void write_raw_cp_reg(CPUARMState *env, const 
ARMCPRegInfo *ri,
 }
 }
 
+static bool raw_accessors_invalid(const ARMCPRegInfo *ri)
+{
+   /* Return true if the regdef would cause an assertion if you called
+* read_raw_cp_reg() or write_raw_cp_reg() on it (ie if it is a
+* program bug for it not to have the NO_RAW flag).
+* NB that returning false here doesn't necessarily mean that calling
+* read/write_raw_cp_reg() is safe, because we can't distinguish has
+* read/write access functions which are safe for raw use from has
+* read/write access functions which have side effects but has forgotten
+* to provide raw access functions.
+* The tests here line up with the conditions in read/write_raw_cp_reg()
+* and assertions in raw_read()/raw_write().
+*/
+if ((ri-type  ARM_CP_CONST) ||
+ri-fieldoffset ||
+((ri-raw_writefn || ri-writefn)  (ri-raw_readfn || ri-readfn))) {
+return false;
+}
+return true;
+}
+
 bool write_cpustate_to_list(ARMCPU *cpu)
 {
 /* Write the coprocessor state from cpu-env to the (index,value) list. */
@@ -3509,6 +3532,14 @@ static void add_cpreg_to_hashtable(ARMCPU *cpu, const 
ARMCPRegInfo *r,
 r2-type |= ARM_CP_ALIAS;
 }
 
+/* Check that raw accesses are either forbidden or handled. Note that
+ * we can't assert this earlier because the setup of fieldoffset for
+ * banked registers has to be done first.
+ */
+if (!(r2-type  ARM_CP_NO_RAW)) {
+assert(!raw_accessors_invalid(r2));
+}
+
 /* Overriding of an existing definition must be explicitly
  * requested.
  */
-- 
1.9.1




Re: [Qemu-devel] [PATCH v2 00/14] block: Remove growable, add blk_new_open()

2015-01-26 Thread Max Reitz

On 2015-01-26 at 07:18, Stefano Stabellini wrote:

On Thu, 22 Jan 2015, Max Reitz wrote:

This series removes the growable field from the BlockDriverState
object. Its use was to clamp guest requests against the limits of the
BDS; however, this can now be done more easily by moving those checks
into the BlockBackend functions.

In a future series, growable may be reintroduced (maybe with a
different name); it will then signify whether a BDS is able to grow (in
contrast to the current growable, which signifies whether it is
allowed to). Maybe I will add it to the BlockDriver instead of the BDS,
though.

To be able to remove that field, qemu-io needs to be converted to
BlockBackend, which is done by this series as well. While working on
that I decided to convert blk_new_with_bs()+bdrv_open() to
blk_new_open(). I was skeptical about that decision at first, but it
seems good now that I was able to replace nearly every blk_new_with_bs()
call by blk_new_open(). In a future series I may try to convert some
remaining bdrv_open() calls to blk_new_open() as well. (And, in fact, in
a future series I *will* replace the last remaining blk_new_with_bs()
outside of blk_new_open() by blk_new_open().)

Finally, the question needs to be asked: If, after this series, every
BDS is allowed to grow, are there any users which do not use BB, but
should still be disallowed from reading/writing beyond a BDS's limits?
The only users I could see were the block jobs. Some of them should
indeed be converted to BB; but none of them takes a user-supplied offset
or size, all work on the full BDS (or only on parts which have been
modified, etc.). Therefore, it is by design impossible for them to
exceed the BDS's limits, which makes making all BDS's growable safe.

Hello Max,
I applied the first four patches in this series, and this is what I get:

hw/block/xen_disk.c: In function ‘blk_connect’:
hw/block/xen_disk.c:907:27: error: implicit declaration of function 
‘qstring_from_str’ [-Werror=implicit-function-declaration]
hw/block/xen_disk.c:907:27: error: nested extern declaration of 
‘qstring_from_str’ [-Werror=nested-externs]
hw/block/xen_disk.c:907:27: error: invalid type argument of ‘-’ (have ‘int’)
hw/block/xen_disk.c:901:22: error: unused variable ‘drv’ 
[-Werror=unused-variable]
hw/block/xen_disk.c:900:23: error: unused variable ‘blk’ 
[-Werror=unused-variable]

it would be great if you could build test it.


Sorry, of course I build test my patches, but I just don't have some 
subsystems enabled (there was no real reason not to have the Xen 
backends enabled, but that's just how it was; another example are 
Windows-specific areas), so I have to work blind on them. In this case I 
forgot to include the QMP type headers and to remove the now unused 
variables.


Thank you for looking at my patches and finding this issue! I'll send a 
fixed v3.


Max


v2:
- Rebased [Kevin]
- Patch 2: Added a TODO comment about removing @filename and @flags from
   blk_new_open() when possible [Kevin]


git-backport-diff against v1:

Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/14:[] [--] 'block: Lift some BDS functions to the BlockBackend'
002/14:[0006] [FC] 'block: Add blk_new_open()'
003/14:[] [-C] 'blockdev: Use blk_new_open() in blockdev_init()'
004/14:[] [--] 'block/xen: Use blk_new_open() in blk_connect()'
005/14:[] [--] 'qemu-img: Use blk_new_open() in img_open()'
006/14:[] [--] 'qemu-img: Use blk_new_open() in img_rebase()'
007/14:[] [--] 'qemu-img: Use BlockBackend as far as possible'
008/14:[] [--] 'qemu-nbd: Use blk_new_open() in main()'
009/14:[] [--] 'qemu-io: Use blk_new_open() in openfile()'
010/14:[0002] [FC] 'qemu-io: Remove growable option'
011/14:[] [--] 'qemu-io: Use BlockBackend'
012/14:[] [--] 'block: Clamp BlockBackend requests'
013/14:[] [--] 'block: Remove growable from BDS'
014/14:[] [--] 'block: Keep bdrv_check*_request()'s return value'


Max Reitz (14):
   block: Lift some BDS functions to the BlockBackend
   block: Add blk_new_open()
   blockdev: Use blk_new_open() in blockdev_init()
   block/xen: Use blk_new_open() in blk_connect()
   qemu-img: Use blk_new_open() in img_open()
   qemu-img: Use blk_new_open() in img_rebase()
   qemu-img: Use BlockBackend as far as possible
   qemu-nbd: Use blk_new_open() in main()
   qemu-io: Use blk_new_open() in openfile()
   qemu-io: Remove growable option
   qemu-io: Use BlockBackend
   block: Clamp BlockBackend requests
   block: Remove growable from BDS
   block: Keep bdrv_check*_request()'s return value

  block.c|  59 +-
  block/block-backend.c  | 219 +
  block/qcow2.c  |   6 --
  block/raw-posix.c  |   2 +-
  block/raw-win32.c  |   2 

Re: [Qemu-devel] [PATCH 05/11] target-arm: Use correct mmu_idx for unprivileged loads and stores

2015-01-26 Thread Greg Bellows
On Fri, Jan 23, 2015 at 12:20 PM, Peter Maydell peter.mayd...@linaro.org
wrote:

 The MMU index to use for unprivileged loads and stores is more
 complicated than we currently implement:
  * for A64, it should be if at EL1, access as if EL0; otherwise
access at current EL
  * for A32/T32, it should be if EL2, UNPREDICTABLE; otherwise
access as if at EL0.


​The wording between the specs appears to be almost identical, curious why
the handling is different?​



 In both cases, if we want to make the access for Secure EL0
 this is not the same mmu_idx as for Non-Secure EL0.

 Signed-off-by: Peter Maydell peter.mayd...@linaro.org
 ---
  target-arm/translate-a64.c | 19 ++-
  target-arm/translate.c | 26 --
  2 files changed, 42 insertions(+), 3 deletions(-)

 diff --git a/target-arm/translate-a64.c b/target-arm/translate-a64.c
 index 96f14ff..acf4b16 100644
 --- a/target-arm/translate-a64.c
 +++ b/target-arm/translate-a64.c
 @@ -123,6 +123,23 @@ void a64_translate_init(void)
  #endif
  }

 +static inline ARMMMUIdx get_a64_user_mem_index(DisasContext *s)
 +{
 +/* Return the mmu_idx to use for A64 unprivileged load/store insns:
 + *  if EL1, access as if EL0; otherwise access at current EL
 + */
 +switch (s-mmu_idx) {
 +case ARMMMUIdx_S12NSE1:
 +return ARMMMUIdx_S12NSE0;
 +case ARMMMUIdx_S1SE1:
 +return ARMMMUIdx_S1SE0;
 +case ARMMMUIdx_S2NS:
 +g_assert_not_reached();
 +default:
 +return s-mmu_idx;
 +}
 +}
 +
  void aarch64_cpu_dump_state(CPUState *cs, FILE *f,
  fprintf_function cpu_fprintf, int flags)
  {
 @@ -2107,7 +2124,7 @@ static void disas_ldst_reg_imm9(DisasContext *s,
 uint32_t insn)
  }
  } else {
  TCGv_i64 tcg_rt = cpu_reg(s, rt);
 -int memidx = is_unpriv ? MMU_USER_IDX : get_mem_index(s);
 +int memidx = is_unpriv ? get_a64_user_mem_index(s) :
 get_mem_index(s);

  if (is_store) {
  do_gpr_st_memidx(s, tcg_rt, tcg_addr, size, memidx);
 diff --git a/target-arm/translate.c b/target-arm/translate.c
 index 7163649..715f65d 100644
 --- a/target-arm/translate.c
 +++ b/target-arm/translate.c
 @@ -113,6 +113,28 @@ void arm_translate_init(void)
  a64_translate_init();
  }

 +static inline ARMMMUIdx get_a32_user_mem_index(DisasContext *s)
 +{
 +/* Return the mmu_idx to use for A32/T32 unprivileged load/store
 + * insns:
 + *  if PL2, UNPREDICTABLE (we choose to implement as if PL0)
 + *  otherwise, access as if at PL0.
 + */
 +switch (s-mmu_idx) {
 +case ARMMMUIdx_S1E2:/* this one is UNPREDICTABLE */
 +case ARMMMUIdx_S12NSE0:
 +case ARMMMUIdx_S12NSE1:
 +return ARMMMUIdx_S12NSE0;
 +case ARMMMUIdx_S1E3:
 +case ARMMMUIdx_S1SE0:
 +case ARMMMUIdx_S1SE1:
 +return ARMMMUIdx_S1SE0;
 +case ARMMMUIdx_S2NS:
 +default:
 +g_assert_not_reached();
 +}
 +}
 +
  static inline TCGv_i32 load_cpu_offset(int offset)
  {
  TCGv_i32 tmp = tcg_temp_new_i32();
 @@ -8793,7 +8815,7 @@ static void disas_arm_insn(DisasContext *s, unsigned
 int insn)
  tmp2 = load_reg(s, rn);
  if ((insn  0x0120) == 0x0020) {
  /* ldrt/strt */
 -i = MMU_USER_IDX;
 +i = get_a32_user_mem_index(s);
  } else {
  i = get_mem_index(s);
  }
 @@ -10173,7 +10195,7 @@ static int disas_thumb2_insn(CPUARMState *env,
 DisasContext *s, uint16_t insn_hw
  break;
  case 0xe: /* User privilege.  */
  tcg_gen_addi_i32(addr, addr, imm);
 -memidx = MMU_USER_IDX;
 +memidx = get_a32_user_mem_index(s);
  break;
  case 0x9: /* Post-decrement.  */
  imm = -imm;
 --
 1.9.1

 ​Otherwise,

Reviewed-by: Greg Bellows greg.bell...@linaro.org​


[Qemu-devel] [PATCH v3 1/2] target-arm: Split NO_MIGRATE into ALIAS and NO_RAW

2015-01-26 Thread Peter Maydell
We currently mark ARM coprocessor/system register definitions with
the flag ARM_CP_NO_MIGRATE for two different reasons:
1) register is an alias on to state that's also visible via
   some other register, and that other register is the one
   responsible for migrating the state
2) register is not actually state at all (for instance the TLB
   or cache maintenance operation registers) and it makes no
   sense to attempt to migrate it or otherwise access the raw state

This works fine for identifying which registers should be ignored
when performing migration, but we also use the same functions for
synchronizing system register state between QEMU and the kernel
when using KVM. In this case we don't want to try to sync state
into registers in category 2, but we do want to sync into registers
in category 1, because the kernel might have picked a different
one of the aliases as its choice for which one to expose for
migration. (In particular, on 32 bit hosts the kernel will
expose the state in the AArch32 version of the register, but
TCG's convention is to mark the AArch64 version as the version
to migrate, even if the CPU being emulated happens to be 32 bit,
so almost all system registers will hit this issue now that we've
added AArch64 system emulation.)

Fix this by splitting the NO_MIGRATE flag in two (ALIAS and NO_RAW)
corresponding to the two different reasons we might not want to
migrate a register. When setting up the TCG list of registers to
migrate we honour both flags; when populating the list from KVM,
only ignore registers which are NO_RAW.

Signed-off-by: Peter Maydell peter.mayd...@linaro.org
Reviewed-by: Greg Bellows greg.bell...@linaro.org
---
 target-arm/cpu.h|  15 +++-
 target-arm/helper.c | 206 ++--
 2 files changed, 115 insertions(+), 106 deletions(-)

diff --git a/target-arm/cpu.h b/target-arm/cpu.h
index 7ba55f0..831a841 100644
--- a/target-arm/cpu.h
+++ b/target-arm/cpu.h
@@ -1112,8 +1112,14 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
  * a register definition to override a previous definition for the
  * same (cp, is64, crn, crm, opc1, opc2) tuple: either the new or the
  * old must have the OVERRIDE bit set.
- * NO_MIGRATE indicates that this register should be ignored for migration;
- * (eg because any state is accessed via some other coprocessor register).
+ * ALIAS indicates that this register is an alias view of some underlying
+ * state which is also visible via another register, and that the other
+ * register is handling migration; registers marked ALIAS will not be migrated
+ * but may have their state set by syncing of register state from KVM.
+ * NO_RAW indicates that this register has no underlying state and does not
+ * support raw access for state saving/loading; it will not be used for either
+ * migration or KVM state synchronization. (Typically this is for registers
+ * which are actually used as instructions for cache maintenance and so on.)
  * IO indicates that this register does I/O and therefore its accesses
  * need to be surrounded by gen_io_start()/gen_io_end(). In particular,
  * registers which implement clocks or timers require this.
@@ -1123,8 +1129,9 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
 #define ARM_CP_64BIT 4
 #define ARM_CP_SUPPRESS_TB_END 8
 #define ARM_CP_OVERRIDE 16
-#define ARM_CP_NO_MIGRATE 32
+#define ARM_CP_ALIAS 32
 #define ARM_CP_IO 64
+#define ARM_CP_NO_RAW 128
 #define ARM_CP_NOP (ARM_CP_SPECIAL | (1  8))
 #define ARM_CP_WFI (ARM_CP_SPECIAL | (2  8))
 #define ARM_CP_NZCV (ARM_CP_SPECIAL | (3  8))
@@ -1134,7 +1141,7 @@ static inline uint64_t cpreg_to_kvm_id(uint32_t cpregid)
 /* Used only as a terminator for ARMCPRegInfo lists */
 #define ARM_CP_SENTINEL 0x
 /* Mask of only the flag bits in a type field */
-#define ARM_CP_FLAG_MASK 0x7f
+#define ARM_CP_FLAG_MASK 0xff
 
 /* Valid values for ARMCPRegInfo state field, indicating which of
  * the AArch32 and AArch64 execution states this register is visible in.
diff --git a/target-arm/helper.c b/target-arm/helper.c
index 1a5e067..18f04b2 100644
--- a/target-arm/helper.c
+++ b/target-arm/helper.c
@@ -189,7 +189,7 @@ bool write_cpustate_to_list(ARMCPU *cpu)
 ok = false;
 continue;
 }
-if (ri-type  ARM_CP_NO_MIGRATE) {
+if (ri-type  ARM_CP_NO_RAW) {
 continue;
 }
 cpu-cpreg_values[i] = read_raw_cp_reg(cpu-env, ri);
@@ -212,7 +212,7 @@ bool write_list_to_cpustate(ARMCPU *cpu)
 ok = false;
 continue;
 }
-if (ri-type  ARM_CP_NO_MIGRATE) {
+if (ri-type  ARM_CP_NO_RAW) {
 continue;
 }
 /* Write value and confirm it reads back as written
@@ -236,7 +236,7 @@ static void add_cpreg_to_list(gpointer key, gpointer opaque)
 regidx = *(uint32_t *)key;
 ri = get_arm_cp_reginfo(cpu-cp_regs, regidx);
 
-if (!(ri-type  ARM_CP_NO_MIGRATE)) {
+if (!(ri-type  

Re: [Qemu-devel] [PATCH] linux-user/syscall.c: Let all lock_user_struct() and unlock_user_struct() paired with each other

2015-01-26 Thread Chen Gang S
On 1/26/15 06:10, Peter Maydell wrote:
 On 25 January 2015 at 21:59, Chen Gang S gang.c...@sunrus.com.cn wrote:
 On 1/25/15 20:49, Peter Maydell wrote:
 Are you claiming that you've reviewed *all* the code in this
 file for mismatched lock/unlock calls? If so, it would be nice
 to say so explicitly in the commit message. If not, it would be
 nice if the commit message was clearer about what areas of the
 code it applied to. The code changes are correct, though.


 At present, I finished all lock_user_struct() and unlock_user_struct()
 in linux-user/syscall.c. For me, after this patch, they are all OK.

 But for all lock/unlock in linux-user/syscall.c, for me, I am doubting
 several areas, but I did not send patch for them:

  - I need check them carefully again to be sure they are really issue:

Read the related code again and again, if I really treat it as an
issue, I shall make related patch (and pass compiling, at least).

  - I have no enough time resources on it:
 
 That's fine. I'm definitely not asking you to do this work.

OK, thanks. :-)

 I would just like the commit message to be clear about the
 scope of the work the patch covers. If the patch is just Fix
 mismatched lock/unlock calls in IPC struct conversion functions
 then that's fine, but the commit message should say that. At the
 moment the commit message is very vague.
 

OK, thanks.

I am not quite familiar with this file, so I describe the modification
by function name, e.g. lock_user_struct() and unlick_user_struct() in
the patch subject.

Welcome to help improve the patch comments. If necessary to send patch
v2, please let me know, I shall try.


Thanks.
-- 
Chen Gang

Open, share, and attitude like air, water, and life which God blessed



[Qemu-devel] [PATCH v3 0/2] target-arm: fix broken sync of sysregs between QEMU and KVM 32

2015-01-26 Thread Peter Maydell

This patchset fixes a regression in the synchronization of
system registers between QEMU and KVM for 32-bit ARM hosts.
The most obvious effect of the bug is that trying to access
memory via the gdbstub doesn't work, because gdbstub thinks the
MMU is off and doesn't get the virt-to-phys translation right.
(Migration would not be broken.)

The underlying cause of this is that we are using the cpreg
definition flag ARM_CP_NO_MIGRATE for two different purposes:
1) register is an alias on to state that's also visible via
   some other register, and that other register is the one
   responsible for migrating the state
2) register is not actually state at all (for instance the TLB
   or cache maintenance operation registers) and it makes no
   sense to attempt to migrate it or otherwise access the raw state

This works fine for identifying which registers should be ignored
when performing migration, but we also use the same functions for
synchronizing system register state between QEMU and the kernel
when using KVM. In this case we don't want to try to sync state
into registers in category 2, but we do want to sync into registers
in category 1, because the kernel might have picked a different
one of the aliases as its choice for which one to expose for
migration. (In particular, on 32 bit hosts the kernel will
expose the state in the AArch32 version of the register, but
TCG's convention is to mark the AArch64 version as the version
to migrate, even if the CPU being emulated happens to be 32 bit,
so almost all system registers will hit this issue now that we've
added AArch64 system emulation.)

Fix this by splitting the NO_MIGRATE flag in two (ALIAS and NO_RAW)
corresponding to the two different reasons we might not want to
migrate a register. When setting up the TCG list of registers to
migrate we honour both flags; when populating the list from KVM,
only ignore registers which are NO_RAW.

Changes v1-v2:
 * change raw_accessors_valid() to raw_accessors_invalid() and
   beef up its comment, following confusion during review of v1
Changes v2-v3:
 * actually change behaviour of the raw_accessors_invalid()
   function rather than merely its name...

Peter Maydell (2):
  target-arm: Split NO_MIGRATE into ALIAS and NO_RAW
  target-arm: Add checks that cpreg raw accesses are handled

 target-arm/cpu.h|  15 +++-
 target-arm/helper.c | 237 ++--
 2 files changed, 146 insertions(+), 106 deletions(-)

-- 
1.9.1




[Qemu-devel] [PATCH 1/2] disas/libvixl: Update to upstream VIXL 1.7

2015-01-26 Thread Peter Maydell
Update our copy of libvixl to upstream's 1.7 release.
This includes upstream's fix for the issue we had a local
patch for in commit 94cc44a9e.

Signed-off-by: Peter Maydell peter.mayd...@linaro.org
---
 disas/libvixl/README  |   2 +-
 disas/libvixl/a64/assembler-a64.h | 290 +-
 disas/libvixl/a64/constants-a64.h |  61 +--
 disas/libvixl/a64/decoder-a64.h   |   2 +-
 disas/libvixl/a64/disasm-a64.cc   | 142 ++---
 disas/libvixl/a64/disasm-a64.h|  48 --
 disas/libvixl/a64/instructions-a64.cc |  63 
 disas/libvixl/a64/instructions-a64.h  | 110 -
 disas/libvixl/globals.h   |   2 +-
 disas/libvixl/utils.cc|  13 ++
 disas/libvixl/utils.h |  14 +-
 11 files changed, 537 insertions(+), 210 deletions(-)

diff --git a/disas/libvixl/README b/disas/libvixl/README
index cba31b4..58db41c 100644
--- a/disas/libvixl/README
+++ b/disas/libvixl/README
@@ -2,7 +2,7 @@
 The code in this directory is a subset of libvixl:
  https://github.com/armvixl/vixl
 (specifically, it is the set of files needed for disassembly only,
-taken from libvixl 1.6).
+taken from libvixl 1.7).
 Bugfixes should preferably be sent upstream initially.
 
 The disassembler does not currently support the entire A64 instruction
diff --git a/disas/libvixl/a64/assembler-a64.h 
b/disas/libvixl/a64/assembler-a64.h
index 16a704b..35aaf20 100644
--- a/disas/libvixl/a64/assembler-a64.h
+++ b/disas/libvixl/a64/assembler-a64.h
@@ -151,21 +151,21 @@ class CPURegister {
 return Aliases(other)  (size_ == other.size_);
   }
 
-  inline bool IsZero() const {
+  bool IsZero() const {
 VIXL_ASSERT(IsValid());
 return IsRegister()  (code_ == kZeroRegCode);
   }
 
-  inline bool IsSP() const {
+  bool IsSP() const {
 VIXL_ASSERT(IsValid());
 return IsRegister()  (code_ == kSPRegInternalCode);
   }
 
-  inline bool IsRegister() const {
+  bool IsRegister() const {
 return type_ == kRegister;
   }
 
-  inline bool IsFPRegister() const {
+  bool IsFPRegister() const {
 return type_ == kFPRegister;
   }
 
@@ -179,7 +179,7 @@ class CPURegister {
   const FPRegister S() const;
   const FPRegister D() const;
 
-  inline bool IsSameSizeAndType(const CPURegister other) const {
+  bool IsSameSizeAndType(const CPURegister other) const {
 return (size_ == other.size_)  (type_ == other.type_);
   }
 
@@ -198,7 +198,7 @@ class CPURegister {
 class Register : public CPURegister {
  public:
   Register() : CPURegister() {}
-  inline explicit Register(const CPURegister other)
+  explicit Register(const CPURegister other)
   : CPURegister(other.code(), other.size(), other.type()) {
 VIXL_ASSERT(IsValidRegister());
   }
@@ -213,10 +213,6 @@ class Register : public CPURegister {
   static const Register WRegFromCode(unsigned code);
   static const Register XRegFromCode(unsigned code);
 
-  // V8 compatibility.
-  static const int kNumRegisters = kNumberOfRegisters;
-  static const int kNumAllocatableRegisters = kNumberOfRegisters - 1;
-
  private:
   static const Register wregisters[];
   static const Register xregisters[];
@@ -225,12 +221,12 @@ class Register : public CPURegister {
 
 class FPRegister : public CPURegister {
  public:
-  inline FPRegister() : CPURegister() {}
-  inline explicit FPRegister(const CPURegister other)
+  FPRegister() : CPURegister() {}
+  explicit FPRegister(const CPURegister other)
   : CPURegister(other.code(), other.size(), other.type()) {
 VIXL_ASSERT(IsValidFPRegister());
   }
-  inline FPRegister(unsigned code, unsigned size)
+  FPRegister(unsigned code, unsigned size)
   : CPURegister(code, size, kFPRegister) {}
 
   bool IsValid() const {
@@ -241,10 +237,6 @@ class FPRegister : public CPURegister {
   static const FPRegister SRegFromCode(unsigned code);
   static const FPRegister DRegFromCode(unsigned code);
 
-  // V8 compatibility.
-  static const int kNumRegisters = kNumberOfFPRegisters;
-  static const int kNumAllocatableRegisters = kNumberOfFPRegisters - 1;
-
  private:
   static const FPRegister sregisters[];
   static const FPRegister dregisters[];
@@ -312,23 +304,23 @@ bool AreSameSizeAndType(const CPURegister reg1,
 // Lists of registers.
 class CPURegList {
  public:
-  inline explicit CPURegList(CPURegister reg1,
- CPURegister reg2 = NoCPUReg,
- CPURegister reg3 = NoCPUReg,
- CPURegister reg4 = NoCPUReg)
+  explicit CPURegList(CPURegister reg1,
+  CPURegister reg2 = NoCPUReg,
+  CPURegister reg3 = NoCPUReg,
+  CPURegister reg4 = NoCPUReg)
   : list_(reg1.Bit() | reg2.Bit() | reg3.Bit() | reg4.Bit()),
 size_(reg1.size()), type_(reg1.type()) {
 VIXL_ASSERT(AreSameSizeAndType(reg1, reg2, reg3, reg4));
 VIXL_ASSERT(IsValid());
   }
 
-  inline CPURegList(CPURegister::RegisterType type, 

[Qemu-devel] [PATCH] vhost-scsi: introduce an ioctl to get the minimum tpgt

2015-01-26 Thread arei.gonglei
From: Gonglei arei.gong...@huawei.com

In order to support to assign a boot order for
vhost-scsi device, we should get the tpgt for
user level (such as Qemu). and at present, we
only support the minimum tpgt can boot.

Signed-off-by: Gonglei arei.gong...@huawei.com
Signed-off-by: Bo Su su...@huawei.com
---
 drivers/vhost/scsi.c   | 41 +
 include/uapi/linux/vhost.h |  2 ++
 2 files changed, 43 insertions(+)

diff --git a/drivers/vhost/scsi.c b/drivers/vhost/scsi.c
index d695b16..12e79b9 100644
--- a/drivers/vhost/scsi.c
+++ b/drivers/vhost/scsi.c
@@ -1522,6 +1522,38 @@ err_dev:
return ret;
 }
 
+static int vhost_scsi_get_first_tpgt(
+   struct vhost_scsi *vs,
+   struct vhost_scsi_target *t)
+{
+   struct tcm_vhost_tpg *tv_tpg;
+   struct tcm_vhost_tport *tv_tport;
+   int tpgt = -1;
+
+   mutex_lock(tcm_vhost_mutex);
+   mutex_lock(vs-dev.mutex);
+
+   list_for_each_entry(tv_tpg, tcm_vhost_list, tv_tpg_list) {
+   tv_tport = tv_tpg-tport;
+
+   if (!strcmp(tv_tport-tport_name, t-vhost_wwpn)) {
+   if (tpgt  0)
+   tpgt = tv_tpg-tport_tpgt;
+   else if (tpgt  tv_tpg-tport_tpgt)
+   tpgt = tv_tpg-tport_tpgt;
+   }
+   }
+
+   mutex_unlock(vs-dev.mutex);
+   mutex_unlock(tcm_vhost_mutex);
+
+   if (tpgt  0)
+   return -ENXIO;
+
+   t-vhost_tpgt = tpgt;
+   return 0;
+}
+
 static int vhost_scsi_set_features(struct vhost_scsi *vs, u64 features)
 {
struct vhost_virtqueue *vq;
@@ -1657,6 +1689,15 @@ vhost_scsi_ioctl(struct file *f,
if (put_user(events_missed, eventsp))
return -EFAULT;
return 0;
+   case VHOST_SCSI_GET_TPGT:
+   if (copy_from_user(backend, argp, sizeof(backend)))
+   return -EFAULT;
+   r = vhost_scsi_get_first_tpgt(vs, backend);
+   if (r  0)
+   return r;
+   if (copy_to_user(argp, backend, sizeof(backend)))
+   return -EFAULT;
+   return 0;
case VHOST_GET_FEATURES:
features = VHOST_SCSI_FEATURES;
if (copy_to_user(featurep, features, sizeof features))
diff --git a/include/uapi/linux/vhost.h b/include/uapi/linux/vhost.h
index bb6a5b4..5d350f7 100644
--- a/include/uapi/linux/vhost.h
+++ b/include/uapi/linux/vhost.h
@@ -155,4 +155,6 @@ struct vhost_scsi_target {
 #define VHOST_SCSI_SET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x43, __u32)
 #define VHOST_SCSI_GET_EVENTS_MISSED _IOW(VHOST_VIRTIO, 0x44, __u32)
 
+#define VHOST_SCSI_GET_TPGT _IOW(VHOST_VIRTIO, 0x45, struct vhost_scsi_target)
+
 #endif
-- 
1.7.12.4





[Qemu-devel] [PATCH] target-ppc: Use right page size with hash table lookup

2015-01-26 Thread Aneesh Kumar K.V
We look at two sizes specified in ISA (4K, 64K). If not found matching,
we consider it 16MB.

Without this patch we would fail to lookup address above 16MB range.
Below 16MB happened to work before because the kernel have a liner
mapping and we always looked up hash for 0xc000. The
actual real address was computed by using the 16MB offset
with the real address found with the above hash.

Without Fix:
(gdb) x/16x 0xc100
0xc100 list_entries+453208:   Cannot access memory at address 
0xc100
(gdb)

With Fix:
(gdb)  x/16x 0xc100
0xc100 list_entries+453208:   0x  0x  
0x  0x
0xc110 list_entries+453224:   0x  0x  
0x  0x
0xc120 list_entries+453240:   0x  0x  
0x  0x
0xc130 list_entries+453256:   0x  0x  
0x  0x

Signed-off-by: Aneesh Kumar K.V aneesh.ku...@linux.vnet.ibm.com
---
 target-ppc/cpu.h|  1 +
 target-ppc/mmu-hash64.c | 37 ++---
 target-ppc/mmu-hash64.h |  3 +++
 3 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/target-ppc/cpu.h b/target-ppc/cpu.h
index aae33a9237d7..b706b9fdf6c3 100644
--- a/target-ppc/cpu.h
+++ b/target-ppc/cpu.h
@@ -45,6 +45,7 @@
 # define TARGET_VIRT_ADDR_SPACE_BITS 64
 #endif
 
+#define TARGET_PAGE_BITS_64K 16
 #define TARGET_PAGE_BITS_16M 24
 
 #else /* defined (TARGET_PPC64) */
diff --git a/target-ppc/mmu-hash64.c b/target-ppc/mmu-hash64.c
index b0278c95e1d3..971751f7de89 100644
--- a/target-ppc/mmu-hash64.c
+++ b/target-ppc/mmu-hash64.c
@@ -388,6 +388,24 @@ static hwaddr ppc_hash64_pteg_search(CPUPPCState *env, 
hwaddr hash,
 return -1;
 }
 
+static uint64_t ppc_hash64_page_shift(ppc_slb_t *slb)
+{
+uint64_t epnshift;
+
+/* Page size according to the SLB, which we use to generate the
+ * EPN for hash table lookup..  When we implement more recent MMU
+ * extensions this might be different from the actual page size
+ * encoded in the PTE */
+if ((slb-vsid  SLB_VSID_LLP_MASK) == SLB_VSID_4K) {
+epnshift = TARGET_PAGE_BITS;
+} else if ((slb-vsid  SLB_VSID_LLP_MASK) == SLB_VSID_64K) {
+epnshift = TARGET_PAGE_BITS_64K;
+} else {
+epnshift = TARGET_PAGE_BITS_16M;
+}
+return epnshift;
+}
+
 static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
  ppc_slb_t *slb, target_ulong eaddr,
  ppc_hash_pte64_t *pte)
@@ -396,12 +414,7 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
 hwaddr hash;
 uint64_t vsid, epnshift, epnmask, epn, ptem;
 
-/* Page size according to the SLB, which we use to generate the
- * EPN for hash table lookup..  When we implement more recent MMU
- * extensions this might be different from the actual page size
- * encoded in the PTE */
-epnshift = (slb-vsid  SLB_VSID_L)
-? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
+epnshift = ppc_hash64_page_shift(slb);
 epnmask = ~((1ULL  epnshift) - 1);
 
 if (slb-vsid  SLB_VSID_B) {
@@ -448,12 +461,14 @@ static hwaddr ppc_hash64_htab_lookup(CPUPPCState *env,
 static hwaddr ppc_hash64_pte_raddr(ppc_slb_t *slb, ppc_hash_pte64_t pte,
target_ulong eaddr)
 {
+hwaddr mask;
+int target_page_bits;
 hwaddr rpn = pte.pte1  HPTE64_R_RPN;
-/* FIXME: Add support for SLLP extended page sizes */
-int target_page_bits = (slb-vsid  SLB_VSID_L)
-? TARGET_PAGE_BITS_16M : TARGET_PAGE_BITS;
-hwaddr mask = (1ULL  target_page_bits) - 1;
-
+/*
+ * We support 4K, 64K and 16M now
+ */
+target_page_bits = ppc_hash64_page_shift(slb);
+mask = (1ULL  target_page_bits) - 1;
 return (rpn  ~mask) | (eaddr  mask);
 }
 
diff --git a/target-ppc/mmu-hash64.h b/target-ppc/mmu-hash64.h
index 49e385db90fb..291750f3e5a5 100644
--- a/target-ppc/mmu-hash64.h
+++ b/target-ppc/mmu-hash64.h
@@ -37,6 +37,9 @@ void ppc_hash64_store_hpte(CPUPPCState *env, target_ulong 
index,
 #define SLB_VSID_C  0x0080ULL /* class */
 #define SLB_VSID_LP 0x0030ULL
 #define SLB_VSID_ATTR   0x0FFFULL
+#define SLB_VSID_LLP_MASK   (SLB_VSID_L | SLB_VSID_LP)
+#define SLB_VSID_4K 0xULL
+#define SLB_VSID_64K0x0110ULL
 
 /*
  * Hash page table definitions
-- 
2.1.0




Re: [Qemu-devel] [PATCH 1/2] hw/ppc/spapr.c Set default boot order

2015-01-26 Thread Markus Armbruster
Dinar Valeev dval...@suse.de writes:

 On 01/26/2015 10:11 AM, Markus Armbruster wrote:
 dval...@suse.de writes:

 From: Dinar Valeev dval...@suse.com

 In order to use -boot once=X option we need to have default list
   where restore to on reset.

 Really?  What happens without this patch?

 qemu segfaults on reset.
 0  reset-all  Segmentation fault

Next time, include a backtrace, please.

Here's what I think happens.

Boot order comes from --boot parameter once, order, or else the machine
type's .default_boot_order.  The latter is null for you.

It gets passed via ppc_spapr_init() to spapr_create_fdt_skel(), which
sets qemu,boot-device in the FDT to it, but only when it isn't null.

If it comes from parameter once, we additionally register a reset
handler to switch it to parameter order or else .default_boot_order on
reset.  If you specify once, but not order, this is null for you.

On reset, reset handler restore_boot_order() runs.  Unlike
spapr_create_fdt_skel(), it doesn't check for null, and crashes in
validate_bootdevices().

Correct?

For me, a null .default_boot_order means machine type does not support
boot order (this is how commit c165473 treats it).  Arguably, --boot
order and once should be rejected then.

If I understand you correctly, your machine type does support boot
order.  Giving it a non-null .default_boot_order makes sense then.  The
appropriate value depends on firmware.  It could even be .

The null check in spapr_create_fdt_skel() looks superfluous then.
Consider dropping it.

Makes sense?



Re: [Qemu-devel] [PULL v2 00/19] i386, KVM, misc changes for 2015-01-26

2015-01-26 Thread Peter Maydell
On 26 January 2015 at 11:46, Paolo Bonzini pbonz...@redhat.com wrote:
 The following changes since commit a46b3aaf6bb038d4f6f192a84df204f10929e75c:

   Merge remote-tracking branch 'remotes/otubo/tags/pull-seccomp-20150123' 
 into staging (2015-01-23 13:24:17 +)

 are available in the git repository at:


   git://github.com/bonzini/qemu.git tags/for-upstream

 for you to fetch changes up to fc116efad0aadb2f8a49d51240bddbfe21b631a0:

   kvm_stat: Add RESET support for perf event ioctl (2015-01-26 12:27:05 +0100)

 
 - Many fixes from the floor as usual
 - New edu device (v1-v2: fix 32-bit compilation)
 - Disabling HLE and RTM on Haswell  Broadwell
 - kvm_stat updates
 - Added --enable-modules to Travis, in preparation for switching
   the default

 

Applied, thanks.

-- PMM



[Qemu-devel] [PATCH 2/2] disas/arm-a64.cc: Tell libvixl correct code addresses

2015-01-26 Thread Peter Maydell
From 1.7, libvixl supports giving correct target addresses when
disassembling relative branches in code which doesn't reside at
what the guest CPU would think its execution address is. Use
the new MapCodeAddress() API to tell libvixl where the code is
from the guest CPU's point of view so it can get the target
addresses right.

Previous disassembly:

0x4000:  58c0  ldr x0, pc+24 (addr 0x7f6cb7020434)
0x4004:  aa1f03e1  mov x1, xzr
0x4008:  aa1f03e2  mov x2, xzr
0x400c:  aa1f03e3  mov x3, xzr
0x4010:  5884  ldr x4, pc+16 (addr 0x7f6cb702042c)
0x4014:  d61f0080  br x4

Fixed disassembly:
0x4000:  58c0  ldr x0, pc+24 (addr 0x4018)
0x4004:  aa1f03e1  mov x1, xzr
0x4008:  aa1f03e2  mov x2, xzr
0x400c:  aa1f03e3  mov x3, xzr
0x4010:  5884  ldr x4, pc+16 (addr 0x4020)
0x4014:  d61f0080  br x4

Signed-off-by: Peter Maydell peter.mayd...@linaro.org
---
 disas/arm-a64.cc | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/disas/arm-a64.cc b/disas/arm-a64.cc
index ca29f6f..e04f946 100644
--- a/disas/arm-a64.cc
+++ b/disas/arm-a64.cc
@@ -67,7 +67,8 @@ static void vixl_init(FILE *f) {
 int print_insn_arm_a64(uint64_t addr, disassemble_info *info)
 {
 uint8_t bytes[INSN_SIZE];
-uint32_t instr;
+uint32_t instrval;
+const Instruction *instr;
 int status;
 
 status = info-read_memory_func(addr, bytes, INSN_SIZE, info);
@@ -80,8 +81,10 @@ int print_insn_arm_a64(uint64_t addr, disassemble_info *info)
 vixl_init(info-stream);
 }
 
-instr = bytes[0] | bytes[1]  8 | bytes[2]  16 | bytes[3]  24;
-vixl_decoder-Decode(reinterpret_castInstruction*(instr));
+instrval = bytes[0] | bytes[1]  8 | bytes[2]  16 | bytes[3]  24;
+instr = reinterpret_castconst Instruction *(instrval);
+vixl_disasm-MapCodeAddress(addr, instr);
+vixl_decoder-Decode(instr);
 
 return INSN_SIZE;
 }
-- 
1.9.1




[Qemu-devel] [PATCH 0/2] disas/libvixl: Update to VIXL 1.7

2015-01-26 Thread Peter Maydell
This patchseries brings our copy of libvixl up to upstream's
1.7 release. Patch 1 is the usual straight copy of upstream's
files into our tree (note that this includes a fix for the compile
warnings we previously dealt with locally in commit 94cc44a9e5).
Patch 2 uses a new-in-1.7 feature to correct our disassembly of
target addresses for relative jumps and offsets:

Previous disassembly:

0x4000:  58c0  ldr x0, pc+24 (addr 0x7f6cb7020434)
0x4004:  aa1f03e1  mov x1, xzr
0x4008:  aa1f03e2  mov x2, xzr
0x400c:  aa1f03e3  mov x3, xzr
0x4010:  5884  ldr x4, pc+16 (addr 0x7f6cb702042c)
0x4014:  d61f0080  br x4

Fixed disassembly:
0x4000:  58c0  ldr x0, pc+24 (addr 0x4018)
0x4004:  aa1f03e1  mov x1, xzr
0x4008:  aa1f03e2  mov x2, xzr
0x400c:  aa1f03e3  mov x3, xzr
0x4010:  5884  ldr x4, pc+16 (addr 0x4020)
0x4014:  d61f0080  br x4

(previous versions of vixl assumed that the host address of the
instruction was the address the ARM CPU would see, since the primary
usecase was disassembly of code generated by JITs targeting AArch64.)

Peter Maydell (2):
  disas/libvixl: Update to upstream VIXL 1.7
  disas/arm-a64.cc: Tell libvixl correct code addresses

 disas/arm-a64.cc  |   9 +-
 disas/libvixl/README  |   2 +-
 disas/libvixl/a64/assembler-a64.h | 290 +-
 disas/libvixl/a64/constants-a64.h |  61 +--
 disas/libvixl/a64/decoder-a64.h   |   2 +-
 disas/libvixl/a64/disasm-a64.cc   | 142 ++---
 disas/libvixl/a64/disasm-a64.h|  48 --
 disas/libvixl/a64/instructions-a64.cc |  63 
 disas/libvixl/a64/instructions-a64.h  | 110 -
 disas/libvixl/globals.h   |   2 +-
 disas/libvixl/utils.cc|  13 ++
 disas/libvixl/utils.h |  14 +-
 12 files changed, 543 insertions(+), 213 deletions(-)

-- 
1.9.1




Re: [Qemu-devel] [question] incremental backup a running vm

2015-01-26 Thread Zhang Haoyu

On 2015-01-26 19:29:03, Paolo Bonzini wrote:

 On 26/01/2015 12:13, Zhang Haoyu wrote:
  Thanks, Paolo,
  but too many internal snapshots were saved by customers,
 switching to external snapshot mechanism has significant impaction
  on subsequent upgrade.
 
 In that case, patches are welcome. :)

  Another problem:
  drive_backup just implement one time backup,
  but I want VMWare's VDP-like backup mechanism.
  The initial backup of a virtual machine takes comparatively more time,
 because all of the data for that virtual machine is being backed up. 
  Subsequent backups of the same virtual machine take less time, because
  changed block tracking (log dirty) mechanism is used to only backup the 
  dirty data.
  After inittial backup done, even the VM shutdown, but subsequent backup 
  also only 
 copy the changed data.
 
 As mentioned before, patches for this are on the list.
 
I see, thanks, Paolo.
 Paolo




[Qemu-devel] [PATCH v3 03/14] blockdev: Use blk_new_open() in blockdev_init()

2015-01-26 Thread Max Reitz
Due to different error propagation, this breaks tests 051 and 087; fix
their output.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 92 +-
 tests/qemu-iotests/051.out | 60 +++---
 tests/qemu-iotests/087.out |  8 ++--
 3 files changed, 76 insertions(+), 84 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index d59efd3..7573746 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -354,13 +354,11 @@ static BlockBackend *blockdev_init(const char *file, 
QDict *bs_opts,
 ThrottleConfig cfg;
 int snapshot = 0;
 bool copy_on_read;
-int ret;
 Error *error = NULL;
 QemuOpts *opts;
 const char *id;
 bool has_driver_specific_opts;
 BlockdevDetectZeroesOptions detect_zeroes;
-BlockDriver *drv = NULL;
 
 /* Check common options by copying from bs_opts to opts, all other options
  * stay in bs_opts for processing by bdrv_open(). */
@@ -426,11 +424,11 @@ static BlockBackend *blockdev_init(const char *file, 
QDict *bs_opts,
 goto early_err;
 }
 
-drv = bdrv_find_format(buf);
-if (!drv) {
-error_setg(errp, '%s' invalid format, buf);
+if (qdict_haskey(bs_opts, driver)) {
+error_setg(errp, Cannot specify both 'driver' and 'format');
 goto early_err;
 }
+qdict_put_obj(bs_opts, driver, QOBJECT(qstring_from_str(buf)));
 }
 
 /* disk I/O throttling */
@@ -505,70 +503,64 @@ static BlockBackend *blockdev_init(const char *file, 
QDict *bs_opts,
 }
 
 /* init */
-blk = blk_new_with_bs(qemu_opts_id(opts), errp);
-if (!blk) {
-goto early_err;
-}
-bs = blk_bs(blk);
-bs-open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
-bs-read_only = ro;
-bs-detect_zeroes = detect_zeroes;
-
-bdrv_set_on_error(bs, on_read_error, on_write_error);
+if ((!file || !*file)  !has_driver_specific_opts) {
+blk = blk_new_with_bs(qemu_opts_id(opts), errp);
+if (!blk) {
+goto early_err;
+}
 
-/* disk I/O throttling */
-if (throttle_enabled(cfg)) {
-bdrv_io_limits_enable(bs);
-bdrv_set_io_limits(bs, cfg);
-}
+bs = blk_bs(blk);
+bs-open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
+bs-read_only = ro;
 
-if (!file || !*file) {
-if (has_driver_specific_opts) {
+QDECREF(bs_opts);
+} else {
+if (file  !*file) {
 file = NULL;
-} else {
-QDECREF(bs_opts);
-qemu_opts_del(opts);
-return blk;
 }
-}
-if (snapshot) {
-/* always use cache=unsafe with snapshot */
-bdrv_flags = ~BDRV_O_CACHE_MASK;
-bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
-}
 
-if (copy_on_read) {
-bdrv_flags |= BDRV_O_COPY_ON_READ;
-}
+if (snapshot) {
+/* always use cache=unsafe with snapshot */
+bdrv_flags = ~BDRV_O_CACHE_MASK;
+bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
+}
+
+if (copy_on_read) {
+bdrv_flags |= BDRV_O_COPY_ON_READ;
+}
+
+if (runstate_check(RUN_STATE_INMIGRATE)) {
+bdrv_flags |= BDRV_O_INCOMING;
+}
 
-if (runstate_check(RUN_STATE_INMIGRATE)) {
-bdrv_flags |= BDRV_O_INCOMING;
+bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
+
+blk = blk_new_open(qemu_opts_id(opts), file, NULL, bs_opts, bdrv_flags,
+   errp);
+if (!blk) {
+goto err_no_bs_opts;
+}
+bs = blk_bs(blk);
 }
 
-bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
+bs-detect_zeroes = detect_zeroes;
 
-QINCREF(bs_opts);
-ret = bdrv_open(bs, file, NULL, bs_opts, bdrv_flags, drv, error);
-assert(bs == blk_bs(blk));
+bdrv_set_on_error(bs, on_read_error, on_write_error);
 
-if (ret  0) {
-error_setg(errp, could not open disk image %s: %s,
-   file ?: blk_name(blk), error_get_pretty(error));
-error_free(error);
-goto err;
+/* disk I/O throttling */
+if (throttle_enabled(cfg)) {
+bdrv_io_limits_enable(bs);
+bdrv_set_io_limits(bs, cfg);
 }
 
 if (bdrv_key_required(bs)) {
 autostart = 0;
 }
 
-QDECREF(bs_opts);
+err_no_bs_opts:
 qemu_opts_del(opts);
-
 return blk;
 
-err:
-blk_unref(blk);
 early_err:
 qemu_opts_del(opts);
 err_no_opts:
diff --git a/tests/qemu-iotests/051.out b/tests/qemu-iotests/051.out
index f497c57..ecf0a31 100644
--- a/tests/qemu-iotests/051.out
+++ b/tests/qemu-iotests/051.out
@@ -5,43 +5,43 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 
backing_file='TEST_DIR
 === Unknown option ===
 
 Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=
-QEMU_PROG: -drive file=TEST_DIR/t.qcow2,format=qcow2,unknown_opt=: could not 
open disk image 

[Qemu-devel] [PATCH v3 08/14] qemu-nbd: Use blk_new_open() in main()

2015-01-26 Thread Max Reitz
Signed-off-by: Max Reitz mre...@redhat.com
---
 qemu-nbd.c | 25 +
 1 file changed, 9 insertions(+), 16 deletions(-)

diff --git a/qemu-nbd.c b/qemu-nbd.c
index d222512..fdc9590 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -386,7 +386,6 @@ int main(int argc, char **argv)
 {
 BlockBackend *blk;
 BlockDriverState *bs;
-BlockDriver *drv;
 off_t dev_offset = 0;
 uint32_t nbdflags = 0;
 bool disconnect = false;
@@ -429,7 +428,7 @@ int main(int argc, char **argv)
 char *end;
 int flags = BDRV_O_RDWR;
 int partition = -1;
-int ret;
+int ret = 0;
 int fd;
 bool seen_cache = false;
 bool seen_discard = false;
@@ -440,6 +439,7 @@ int main(int argc, char **argv)
 const char *fmt = NULL;
 Error *local_err = NULL;
 BlockdevDetectZeroesOptions detect_zeroes = 
BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
+QDict *options = NULL;
 
 /* The client thread uses SIGTERM to interrupt the server.  A signal
  * handler ensures that qemu-nbd -v -c exits with a nice status code.
@@ -684,24 +684,17 @@ int main(int argc, char **argv)
 atexit(bdrv_close_all);
 
 if (fmt) {
-drv = bdrv_find_format(fmt);
-if (!drv) {
-errx(EXIT_FAILURE, Unknown file format '%s', fmt);
-}
-} else {
-drv = NULL;
+options = qdict_new();
+qdict_put_obj(options, driver, QOBJECT(qstring_from_str(fmt)));
 }
 
-blk = blk_new_with_bs(hda, error_abort);
-bs = blk_bs(blk);
-
 srcpath = argv[optind];
-ret = bdrv_open(bs, srcpath, NULL, NULL, flags, drv, local_err);
-if (ret  0) {
-errno = -ret;
-err(EXIT_FAILURE, Failed to bdrv_open '%s': %s, argv[optind],
-error_get_pretty(local_err));
+blk = blk_new_open(hda, srcpath, NULL, options, flags, local_err);
+if (!blk) {
+errx(EXIT_FAILURE, Failed to blk_new_open '%s': %s, argv[optind],
+ error_get_pretty(local_err));
 }
+bs = blk_bs(blk);
 
 if (sn_opts) {
 ret = bdrv_snapshot_load_tmp(bs,
-- 
2.1.0




Re: [Qemu-devel] [PATCH 2/2] target-openrisc: Add l.lwa/l.swa support

2015-01-26 Thread Christian Svensson
Hi Jia.

On Mon, Jan 26, 2015 at 9:50 AM, Jia Liu pro...@gmail.com wrote:

 Is it a new instruction new added into OpenRISC?


Yes. Please see the latest architecture specification for details.

It should be blank lines in here in [patch 1/2].

Care to elaborate why?


[Qemu-devel] [PATCH v2 2/4] target-tricore: Add instructions of RR2 opcode format

2015-01-26 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de
---
 target-tricore/translate.c | 37 +
 1 file changed, 37 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 804d181..8f9679e 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -4957,6 +4957,39 @@ static void decode_rr1_mulq(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(temp2);
 }
 
+/* RR2 format */
+static void decode_rr2_mul(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+
+op2 = MASK_OP_RR2_OP2(ctx-opcode);
+r1  = MASK_OP_RR2_S1(ctx-opcode);
+r2  = MASK_OP_RR2_S2(ctx-opcode);
+r3  = MASK_OP_RR2_D(ctx-opcode);
+switch (op2) {
+case OPC2_32_RR2_MUL_32:
+gen_mul_i32s(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2]);
+break;
+case OPC2_32_RR2_MUL_64:
+gen_mul_i64s(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r2]);
+break;
+case OPC2_32_RR2_MULS_32:
+gen_helper_mul_ssov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+cpu_gpr_d[r2]);
+break;
+case OPC2_32_RR2_MUL_U_64:
+gen_mul_i64u(cpu_gpr_d[r3], cpu_gpr_d[r3+1], cpu_gpr_d[r1],
+ cpu_gpr_d[r2]);
+break;
+case OPC2_32_RR2_MULS_U_32:
+gen_helper_mul_suov(cpu_gpr_d[r3], cpu_env, cpu_gpr_d[r1],
+cpu_gpr_d[r2]);
+break;
+}
+}
+
 static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
 {
 int op1;
@@ -5217,6 +5250,10 @@ static void decode_32Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPCM_32_RR1_MULQ:
 decode_rr1_mulq(env, ctx);
 break;
+/* RR2 format */
+case OPCM_32_RR2_MUL:
+decode_rr2_mul(env, ctx);
+break;
 }
 }
 
-- 
2.2.2




[Qemu-devel] [Bug 1368815] Change abandoned on cinder (master)

2015-01-26 Thread OpenStack Infra
Change abandoned by Mike Perez (thin...@gmail.com) on branch: master
Review: https://review.openstack.org/143575
Reason: 1 month, no update.

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

Title:
  qemu-img convert intermittently corrupts output images

Status in Cinder:
  In Progress
Status in OpenStack Compute (Nova):
  In Progress
Status in QEMU:
  In Progress
Status in qemu package in Ubuntu:
  Fix Released
Status in qemu source package in Trusty:
  Fix Released
Status in qemu source package in Utopic:
  Fix Released
Status in qemu source package in Vivid:
  Fix Released

Bug description:
  ==
  Impact: occasional image corruption (any format on local filesystem)
  Test case: see the qemu-img command below
  Regression potential: this cherrypicks a patch from upstream to a 
not-insignificantly older qemu source tree.  While the cherrypick seems sane, 
it's possible that there are subtle interactions with the other delta.  I'd 
really like for a full qa-regression-test qemu testcase to be run against this 
package.
  ==

  -- Found in releases qemu-2.0.0, qemu-2.0.2, qemu-2.1.0. Tested on
  Ubuntu 14.04 using Ext4 filesystems.

  The command

    qemu-img convert -O raw inputimage.qcow2 outputimage.raw

  intermittently creates corrupted output images, when the input image
  is not yet fully synchronized to disk. While the issue has actually
  been discovered in operation of of OpenStack nova, it can be
  reproduced easily on command line using

    cat $SRC_PATH  $TMP_PATH  $QEMU_IMG_PATH convert -O raw $TMP_PATH
  $DST_PATH  cksum $DST_PATH

  on filesystems exposing this behavior. (The difficult part of this
  exercise is to prepare a filesystem to reliably trigger this race. On
  my test machine some filesystems are affected while other aren't, and
  unfortunately I haven't found the relevant difference between them,
  yet. Possible it's timing issues completely out of userspace control
  ...)

  The root cause, however, is the same as in

    http://lists.gnu.org/archive/html/coreutils/2011-04/msg00069.html

  and it can be solved the same way as suggested in

    http://lists.gnu.org/archive/html/coreutils/2011-04/msg00102.html

  In qemu, file block/raw-posix.c use the FIEMAP_FLAG_SYNC, i.e change

  f.fm.fm_flags = 0;

  to

  f.fm.fm_flags = FIEMAP_FLAG_SYNC;

  As discussed in the thread mentioned above, retrieving a page cache
  coherent map of file extents is possible only after fsync on that
  file.

  See also

    https://bugs.launchpad.net/nova/+bug/1350766

  In that bug report filed against nova, fsync had been suggested to be
  performed by the framework invoking qemu-img. However, as the choice
  of fiemap -- implying this otherwise unneeded fsync of a temporary
  file  -- is not made by the caller but by qemu-img, I agree with the
  nova bug reviewer's objection to put it into nova. The fsync should
  instead be triggered by qemu-img utilizing the FIEMAP_FLAG_SYNC,
  specifically intended for that purpose.

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



[Qemu-devel] [PATCH 12/50] block: Move I/O status and error actions into BB

2015-01-26 Thread Max Reitz
These options are only relevant for the user of a whole BDS tree (like a
guest device or a block job) and should thus be moved into the
BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block.c| 125 -
 block/backup.c |  17 --
 block/block-backend.c  | 116 --
 block/commit.c |   3 +-
 block/mirror.c |  17 --
 block/qapi.c   |   4 +-
 block/stream.c |   3 +-
 blockdev.c |   6 +-
 blockjob.c |   5 +-
 include/block/block.h  |  11 
 include/block/block_int.h  |   6 --
 include/sysemu/block-backend.h |   7 +++
 qmp.c  |   6 +-
 13 files changed, 158 insertions(+), 168 deletions(-)

diff --git a/block.c b/block.c
index 17e4ee3..9a0a510 100644
--- a/block.c
+++ b/block.c
@@ -371,7 +371,6 @@ BlockDriverState *bdrv_new(void)
 for (i = 0; i  BLOCK_OP_TYPE_MAX; i++) {
 QLIST_INIT(bs-op_blockers[i]);
 }
-bdrv_iostatus_disable(bs);
 notifier_list_init(bs-close_notifiers);
 notifier_with_return_list_init(bs-before_write_notifiers);
 qemu_co_queue_init(bs-throttled_reqs[0]);
@@ -2050,14 +2049,6 @@ static void bdrv_move_feature_fields(BlockDriverState 
*bs_dest,
 bs_dest-throttled_reqs[1]  = bs_src-throttled_reqs[1];
 bs_dest-io_limits_enabled  = bs_src-io_limits_enabled;
 
-/* r/w error */
-bs_dest-on_read_error  = bs_src-on_read_error;
-bs_dest-on_write_error = bs_src-on_write_error;
-
-/* i/o status */
-bs_dest-iostatus_enabled   = bs_src-iostatus_enabled;
-bs_dest-iostatus   = bs_src-iostatus;
-
 /* dirty bitmap */
 bs_dest-dirty_bitmaps  = bs_src-dirty_bitmaps;
 
@@ -3562,82 +3553,6 @@ void bdrv_get_geometry(BlockDriverState *bs, uint64_t 
*nb_sectors_ptr)
 *nb_sectors_ptr = nb_sectors  0 ? 0 : nb_sectors;
 }
 
-void bdrv_set_on_error(BlockDriverState *bs, BlockdevOnError on_read_error,
-   BlockdevOnError on_write_error)
-{
-bs-on_read_error = on_read_error;
-bs-on_write_error = on_write_error;
-}
-
-BlockdevOnError bdrv_get_on_error(BlockDriverState *bs, bool is_read)
-{
-return is_read ? bs-on_read_error : bs-on_write_error;
-}
-
-BlockErrorAction bdrv_get_error_action(BlockDriverState *bs, bool is_read, int 
error)
-{
-BlockdevOnError on_err = is_read ? bs-on_read_error : bs-on_write_error;
-
-switch (on_err) {
-case BLOCKDEV_ON_ERROR_ENOSPC:
-return (error == ENOSPC) ?
-   BLOCK_ERROR_ACTION_STOP : BLOCK_ERROR_ACTION_REPORT;
-case BLOCKDEV_ON_ERROR_STOP:
-return BLOCK_ERROR_ACTION_STOP;
-case BLOCKDEV_ON_ERROR_REPORT:
-return BLOCK_ERROR_ACTION_REPORT;
-case BLOCKDEV_ON_ERROR_IGNORE:
-return BLOCK_ERROR_ACTION_IGNORE;
-default:
-abort();
-}
-}
-
-static void send_qmp_error_event(BlockDriverState *bs,
- BlockErrorAction action,
- bool is_read, int error)
-{
-IoOperationType optype;
-
-optype = is_read ? IO_OPERATION_TYPE_READ : IO_OPERATION_TYPE_WRITE;
-qapi_event_send_block_io_error(bdrv_get_device_name(bs), optype, action,
-   bdrv_iostatus_is_enabled(bs),
-   error == ENOSPC, strerror(error),
-   error_abort);
-}
-
-/* This is done by device models because, while the block layer knows
- * about the error, it does not know whether an operation comes from
- * the device or the block layer (from a job, for example).
- */
-void bdrv_error_action(BlockDriverState *bs, BlockErrorAction action,
-   bool is_read, int error)
-{
-assert(error = 0);
-
-if (action == BLOCK_ERROR_ACTION_STOP) {
-/* First set the iostatus, so that info block returns an iostatus
- * that matches the events raised so far (an additional error iostatus
- * is fine, but not a lost one).
- */
-bdrv_iostatus_set_err(bs, error);
-
-/* Then raise the request to stop the VM and the event.
- * qemu_system_vmstop_request_prepare has two effects.  First,
- * it ensures that the STOP event always comes after the
- * BLOCK_IO_ERROR event.  Second, it ensures that even if management
- * can observe the STOP event and do a cont before the STOP
- * event is issued, the VM will not stop.  In this case, vm_start()
- * also ensures that the STOP/RESUME pair of events is emitted.
- */
-qemu_system_vmstop_request_prepare();
-send_qmp_error_event(bs, action, is_read, error);
-qemu_system_vmstop_request(RUN_STATE_IO_ERROR);
-} else {
-send_qmp_error_event(bs, action, is_read, error);
-}
-}
-
 int bdrv_is_read_only(BlockDriverState *bs)

[Qemu-devel] [PATCH 22/50] blockdev: Check BB validity in drive-backup TA

2015-01-26 Thread Max Reitz
In the drive-backup transaction, call blk_is_available() before using
blk_bs() to obtain the root BlockDriverState behind the BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 012c603..5f7eef5 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1507,23 +1507,28 @@ typedef struct DriveBackupState {
 static void drive_backup_prepare(BlkTransactionState *common, Error **errp)
 {
 DriveBackupState *state = DO_UPCAST(DriveBackupState, common, common);
-BlockDriverState *bs;
+BlockBackend *blk;
 DriveBackup *backup;
 Error *local_err = NULL;
 
 assert(common-action-kind == TRANSACTION_ACTION_KIND_DRIVE_BACKUP);
 backup = common-action-drive_backup;
 
-bs = bdrv_find(backup-device);
-if (!bs) {
+blk = blk_by_name(backup-device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, backup-device);
 return;
 }
 
 /* AioContext is released in .clean() */
-state-aio_context = bdrv_get_aio_context(bs);
+state-aio_context = blk_get_aio_context(blk);
 aio_context_acquire(state-aio_context);
 
+if (!blk_is_available(blk)) {
+error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, backup-device);
+return;
+}
+
 qmp_drive_backup(backup-device, backup-target,
  backup-has_format, backup-format,
  backup-sync,
@@ -1537,7 +1542,7 @@ static void drive_backup_prepare(BlkTransactionState 
*common, Error **errp)
 return;
 }
 
-state-bs = bs;
+state-bs = blk_bs(blk);
 state-job = state-bs-job;
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH 31/50] block: Add blk_insert_bs()

2015-01-26 Thread Max Reitz
This function associates the given BlockDriverState with the given
BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/block-backend.c  | 16 
 include/sysemu/block-backend.h |  1 +
 2 files changed, 17 insertions(+)

diff --git a/block/block-backend.c b/block/block-backend.c
index 760558f..656ebfc 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -312,6 +312,22 @@ void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk)
 }
 
 /*
+ * Associates a new BlockDriverState with @blk.
+ */
+void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs)
+{
+if (bs-blk == blk) {
+return;
+}
+
+assert(!blk-bs);
+assert(!bs-blk);
+bdrv_ref(bs);
+blk-bs = bs;
+bs-blk = blk;
+}
+
+/*
  * Attach device model @dev to @blk.
  * Return 0 on success, -EBUSY when a device model is attached already.
  */
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index afb62e1..b6cf5bf 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -72,6 +72,7 @@ BlockBackend *blk_by_name(const char *name);
 BlockBackend *blk_next(BlockBackend *blk);
 
 BlockDriverState *blk_bs(BlockBackend *blk);
+void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs);
 
 void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk);
 
-- 
2.1.0




[Qemu-devel] [PATCH 37/50] block: Add blk_remove_bs()

2015-01-26 Thread Max Reitz
This function removes the BlockDriverState associated with the given
BlockBackend from that BB and sets the BDS pointer in the BB to NULL.

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

diff --git a/block/block-backend.c b/block/block-backend.c
index 656ebfc..d2c1bff 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -312,6 +312,22 @@ void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk)
 }
 
 /*
+ * Disassociates the currently associated BlockDriverState from @blk.
+ */
+void blk_remove_bs(BlockBackend *blk)
+{
+if (!blk-bs) {
+return;
+}
+
+blk_update_root_state(blk);
+
+bdrv_unref(blk-bs);
+blk-bs-blk = NULL;
+blk-bs = NULL;
+}
+
+/*
  * Associates a new BlockDriverState with @blk.
  */
 void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs)
@@ -321,9 +337,13 @@ void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs)
 }
 
 assert(!blk-bs);
-assert(!bs-blk);
 bdrv_ref(bs);
 blk-bs = bs;
+
+if (bs-blk) {
+blk_remove_bs(bs-blk);
+}
+
 bs-blk = blk;
 }
 
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index b6cf5bf..c8b47f7 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -72,6 +72,7 @@ BlockBackend *blk_by_name(const char *name);
 BlockBackend *blk_next(BlockBackend *blk);
 
 BlockDriverState *blk_bs(BlockBackend *blk);
+void blk_remove_bs(BlockBackend *blk);
 void blk_insert_bs(BlockBackend *blk, BlockDriverState *bs);
 
 void blk_hide_on_behalf_of_do_drive_del(BlockBackend *blk);
-- 
2.1.0




[Qemu-devel] [PATCH 40/50] blockdev: Add blockdev-remove-medium

2015-01-26 Thread Max Reitz
Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c   | 25 +
 qapi/block-core.json | 13 +
 qmp-commands.hx  | 43 +++
 3 files changed, 81 insertions(+)

diff --git a/blockdev.c b/blockdev.c
index d6a3fdf..17785b8 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2063,6 +2063,31 @@ void qmp_blockdev_close_tray(const char *device, Error 
**errp)
 blk_dev_change_media_cb(blk, true);
 }
 
+void qmp_blockdev_remove_medium(const char *device, Error **errp)
+{
+BlockBackend *blk;
+
+blk = blk_by_name(device);
+if (!blk) {
+error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+return;
+}
+
+if (!blk_dev_has_removable_media(blk)) {
+error_setg(errp, Device '%s' is not removable, device);
+return;
+}
+
+if (!blk_dev_is_tray_open(blk)) {
+error_setg(errp, Tray of device '%s' is not open, device);
+return;
+}
+
+if (blk_bs(blk)) {
+blk_remove_bs(blk);
+}
+}
+
 /* throttling disk I/O limits */
 void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
int64_t bps_wr,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 802734a..1ace69d 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1753,6 +1753,19 @@
 { 'command': 'blockdev-close-tray',
   'data': { 'device': 'str' } }
 
+##
+# @blockdev-remove-medium:
+#
+# Removes a medium (a block driver state tree) from a block device. That block
+# device's tray must currently be open.
+#
+# @device: block device name
+#
+# Since: 2.3
+##
+{ 'command': 'blockdev-remove-medium',
+  'data': { 'device': 'str' } }
+
 
 ##
 # @BlockErrorAction
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 5927507..3d5c10c 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3711,6 +3711,49 @@ Example (1):
 EQMP
 
 {
+.name   = blockdev-remove-medium,
+.args_type  = device:s,
+.mhandler.cmd_new = qmp_marshal_input_blockdev_remove_medium,
+},
+
+SQMP
+blockdev-remove-medium
+--
+
+Removes a medium (a block driver state tree) from a block device. That block
+device's tray must currently be open.
+
+Arguments:
+
+- device: block device name (json-string)
+
+Example (1):
+
+- { execute: blockdev-remove-medium,
+ arguments: { device: ide1-cd0 } }
+
+- { error: { class: GenericError,
+desc: Tray of device 'ide1-cd0' is not open } }
+
+- { execute: blockdev-open-tray,
+ arguments: { device: ide1-cd0 } }
+
+- { timestamp: { seconds: 1418751627,
+microseconds: 549958 },
+ event: DEVICE_TRAY_MOVED,
+ data: { device: ide1-cd0,
+   tray-open: true } }
+
+- { return: {} }
+
+- { execute: blockdev-remove-medium,
+ arguments: { device: ide1-cd0 } }
+
+- { return: {} }
+
+EQMP
+
+{
 .name   = query-named-block-nodes,
 .args_type  = ,
 .mhandler.cmd_new = qmp_marshal_input_query_named_block_nodes,
-- 
2.1.0




[Qemu-devel] [PATCH 42/50] blockdev: Implement eject with basic operations

2015-01-26 Thread Max Reitz
Implement 'eject' by calling blockdev-open-tray and
blockdev-remove-medium.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index e4588b3..0b204eb 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1865,15 +1865,15 @@ out:
 
 void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
 {
-BlockBackend *blk;
+Error *local_err = NULL;
 
-blk = blk_by_name(device);
-if (!blk) {
-error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+qmp_blockdev_open_tray(device, has_force, force, local_err);
+if (local_err) {
+error_propagate(errp, local_err);
 return;
 }
 
-eject_device(blk, force, errp);
+qmp_blockdev_remove_medium(device, errp);
 }
 
 void qmp_block_passwd(bool has_device, const char *device,
-- 
2.1.0




[Qemu-devel] [PATCH] target-mips: ll and lld cause AdEL exception for unaligned address

2015-01-26 Thread Leon Alrae
Signed-off-by: Leon Alrae leon.al...@imgtec.com
---
 target-mips/op_helper.c | 10 +++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/target-mips/op_helper.c b/target-mips/op_helper.c
index ea7d95f..73a8e45 100644
--- a/target-mips/op_helper.c
+++ b/target-mips/op_helper.c
@@ -304,16 +304,20 @@ static inline hwaddr do_translate_address(CPUMIPSState 
*env,
 }
 }
 
-#define HELPER_LD_ATOMIC(name, insn)  \
+#define HELPER_LD_ATOMIC(name, insn, almask)  \
 target_ulong helper_##name(CPUMIPSState *env, target_ulong arg, int mem_idx)  \
 { \
+if (arg  almask) {   \
+env-CP0_BadVAddr = arg;  \
+helper_raise_exception(env, EXCP_AdEL);   \
+} \
 env-lladdr = do_translate_address(env, arg, 0);  \
 env-llval = do_##insn(env, arg, mem_idx);\
 return env-llval;\
 }
-HELPER_LD_ATOMIC(ll, lw)
+HELPER_LD_ATOMIC(ll, lw, 0x3)
 #ifdef TARGET_MIPS64
-HELPER_LD_ATOMIC(lld, ld)
+HELPER_LD_ATOMIC(lld, ld, 0x7)
 #endif
 #undef HELPER_LD_ATOMIC
 
-- 
2.1.0




[Qemu-devel] [PATCH 48/50] hmp: Add read-only option to change command

2015-01-26 Thread Max Reitz
Expose the new read-only option of 'blockdev-change-medium' for the
'change' HMP command.

Signed-off-by: Max Reitz mre...@redhat.com
Reviewed-by: Eric Blake ebl...@redhat.com
---
 hmp-commands.hx | 20 +---
 hmp.c   | 21 -
 2 files changed, 37 insertions(+), 4 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index e37bc8b..70cb7d7 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -196,8 +196,8 @@ ETEXI
 
 {
 .name   = change,
-.args_type  = device:B,target:F,arg:s?,
-.params = device filename [format],
+.args_type  = device:B,target:F,arg:s?,read-only:s?,
+.params = device filename [format [read-only]],
 .help   = change a removable medium, optional format,
 .mhandler.cmd = hmp_change,
 },
@@ -209,7 +209,7 @@ STEXI
 Change the configuration of a device.
 
 @table @option
-@item change @var{diskdevice} @var{filename} [@var{format}]
+@item change @var{diskdevice} @var{filename} [@var{format} [@var{read-only}]]
 Change the medium for a removable disk device to point to @var{filename}. eg
 
 @example
@@ -218,6 +218,20 @@ Change the medium for a removable disk device to point to 
@var{filename}. eg
 
 @var{format} is optional.
 
+@var{read-only} may be used to change the read-only status of the device. It
+accepts the following values:
+
+@table @var
+@item retain
+Retains the current status; this is the default.
+
+@item ro
+Makes the device read-only.
+
+@item rw
+Makes the device writable.
+@end table
+
 @item change vnc @var{display},@var{options}
 Change the configuration of the VNC server. The valid syntax for @var{display}
 and @var{options} are described at @ref{sec_invocation}. eg
diff --git a/hmp.c b/hmp.c
index dbf0947..8e75771 100644
--- a/hmp.c
+++ b/hmp.c
@@ -24,6 +24,7 @@
 #include monitor/monitor.h
 #include qapi/opts-visitor.h
 #include qapi/string-output-visitor.h
+#include qapi/util.h
 #include qapi-visit.h
 #include ui/console.h
 #include block/qapi.h
@@ -1178,9 +1179,15 @@ void hmp_change(Monitor *mon, const QDict *qdict)
 const char *device = qdict_get_str(qdict, device);
 const char *target = qdict_get_str(qdict, target);
 const char *arg = qdict_get_try_str(qdict, arg);
+const char *read_only = qdict_get_try_str(qdict, read-only);
+BlockdevChangeReadOnlyMode read_only_mode = 0;
 Error *err = NULL;
 
 if (strcmp(device, vnc) == 0) {
+if (read_only) {
+monitor_printf(mon, Parameter 'read-only' is invalid for VNC);
+return;
+}
 if (strcmp(target, passwd) == 0 ||
 strcmp(target, password) == 0) {
 if (!arg) {
@@ -1190,7 +1197,19 @@ void hmp_change(Monitor *mon, const QDict *qdict)
 }
 qmp_change(vnc, target, !!arg, arg, err);
 } else {
-qmp_blockdev_change_medium(device, target, !!arg, arg, false, 0, err);
+if (read_only) {
+read_only_mode =
+qapi_enum_parse(BlockdevChangeReadOnlyMode_lookup,
+read_only, BLOCKDEV_CHANGE_READ_ONLY_MODE_MAX,
+BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN, err);
+if (err) {
+hmp_handle_error(mon, err);
+return;
+}
+}
+
+qmp_blockdev_change_medium(device, target, !!arg, arg,
+   !!read_only, read_only_mode, err);
 if (err 
 error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
 error_free(err);
-- 
2.1.0




[Qemu-devel] [PATCH v3 11/14] qemu-io: Use BlockBackend

2015-01-26 Thread Max Reitz
qemu-io should behave like a guest, therefore it should use BlockBackend
to access the block layer.

There are a couple of places where that is infeasible: First, the
bdrv_debug_* functions could theoretically be mirrored in the
BlockBackend, but since these are functions internal to the block layer,
they should not be visible externally (qemu-io as a test tool is excempt
from this).

Second, bdrv_get_info() and bdrv_get_specific_info() work on a single
BDS alone, therefore they should stay BDS-specific.

Third, bdrv_is_allocated() mainly works on a single BDS as well. Some
data may be passed through from the BDS's file (if sectors which are
apparently allocated in the file are not really allocated there but just
zero).

Signed-off-by: Max Reitz mre...@redhat.com
---
 hmp.c |   9 ++-
 include/qemu-io.h |   4 +-
 qemu-io-cmds.c| 238 --
 qemu-io.c |  12 +--
 4 files changed, 138 insertions(+), 125 deletions(-)

diff --git a/hmp.c b/hmp.c
index 481be80..f806387 100644
--- a/hmp.c
+++ b/hmp.c
@@ -16,6 +16,7 @@
 #include hmp.h
 #include net/net.h
 #include sysemu/char.h
+#include sysemu/block-backend.h
 #include qemu/option.h
 #include qemu/timer.h
 #include qmp-commands.h
@@ -1714,14 +1715,14 @@ void hmp_chardev_remove(Monitor *mon, const QDict 
*qdict)
 
 void hmp_qemu_io(Monitor *mon, const QDict *qdict)
 {
-BlockDriverState *bs;
+BlockBackend *blk;
 const char* device = qdict_get_str(qdict, device);
 const char* command = qdict_get_str(qdict, command);
 Error *err = NULL;
 
-bs = bdrv_find(device);
-if (bs) {
-qemuio_command(bs, command);
+blk = blk_by_name(device);
+if (blk) {
+qemuio_command(blk, command);
 } else {
 error_set(err, QERR_DEVICE_NOT_FOUND, device);
 }
diff --git a/include/qemu-io.h b/include/qemu-io.h
index 5d6006f..4d402b9 100644
--- a/include/qemu-io.h
+++ b/include/qemu-io.h
@@ -22,7 +22,7 @@
 
 #define CMD_FLAG_GLOBAL ((int)0x8000) /* don't iterate args */
 
-typedef int (*cfunc_t)(BlockDriverState *bs, int argc, char **argv);
+typedef int (*cfunc_t)(BlockBackend *blk, int argc, char **argv);
 typedef void (*helpfunc_t)(void);
 
 typedef struct cmdinfo {
@@ -40,7 +40,7 @@ typedef struct cmdinfo {
 
 extern bool qemuio_misalign;
 
-bool qemuio_command(BlockDriverState *bs, const char *cmd);
+bool qemuio_command(BlockBackend *blk, const char *cmd);
 
 void qemuio_add_command(const cmdinfo_t *ci);
 int qemuio_command_usage(const cmdinfo_t *ci);
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index e708552..fa21fc8 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -9,7 +9,9 @@
  */
 
 #include qemu-io.h
-#include block/block_int.h
+#include sysemu/block-backend.h
+#include block/block.h
+#include block/block_int.h /* for info_f() */
 #include block/qapi.h
 #include qemu/main-loop.h
 #include qemu/timer.h
@@ -40,24 +42,24 @@ int qemuio_command_usage(const cmdinfo_t *ci)
 return 0;
 }
 
-static int init_check_command(BlockDriverState *bs, const cmdinfo_t *ct)
+static int init_check_command(BlockBackend *blk, const cmdinfo_t *ct)
 {
 if (ct-flags  CMD_FLAG_GLOBAL) {
 return 1;
 }
-if (!(ct-flags  CMD_NOFILE_OK)  !bs) {
+if (!(ct-flags  CMD_NOFILE_OK)  !blk) {
 fprintf(stderr, no file open, try 'help open'\n);
 return 0;
 }
 return 1;
 }
 
-static int command(BlockDriverState *bs, const cmdinfo_t *ct, int argc,
+static int command(BlockBackend *blk, const cmdinfo_t *ct, int argc,
char **argv)
 {
 char *cmd = argv[0];
 
-if (!init_check_command(bs, ct)) {
+if (!init_check_command(blk, ct)) {
 return 0;
 }
 
@@ -78,7 +80,7 @@ static int command(BlockDriverState *bs, const cmdinfo_t *ct, 
int argc,
 return 0;
 }
 optind = 0;
-return ct-cfunc(bs, argc, argv);
+return ct-cfunc(blk, argc, argv);
 }
 
 static const cmdinfo_t *find_command(const char *cmd)
@@ -267,14 +269,14 @@ static int parse_pattern(const char *arg)
  */
 
 #define MISALIGN_OFFSET 16
-static void *qemu_io_alloc(BlockDriverState *bs, size_t len, int pattern)
+static void *qemu_io_alloc(BlockBackend *blk, size_t len, int pattern)
 {
 void *buf;
 
 if (qemuio_misalign) {
 len += MISALIGN_OFFSET;
 }
-buf = qemu_blockalign(bs, len);
+buf = blk_blockalign(blk, len);
 memset(buf, pattern, len);
 if (qemuio_misalign) {
 buf += MISALIGN_OFFSET;
@@ -340,7 +342,7 @@ static void print_report(const char *op, struct timeval *t, 
int64_t offset,
  * vector matching it.
  */
 static void *
-create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char **argv, int nr_iov,
+create_iovec(BlockBackend *blk, QEMUIOVector *qiov, char **argv, int nr_iov,
  int pattern)
 {
 size_t *sizes = g_new0(size_t, nr_iov);
@@ -377,7 +379,7 @@ create_iovec(BlockDriverState *bs, QEMUIOVector *qiov, char 
**argv, int nr_iov,
 
 

[Qemu-devel] [PATCH 03/50] hw/block/fdc: Implement tray status

2015-01-26 Thread Max Reitz
The tray of an FDD is open iff there is no medium inserted (there are
only two states for an FDD: medium inserted or no medium inserted).

This results in the tray being reported as open if qemu has been started
with the default floppy drive, which breaks some tests. Fix them.

Signed-off-by: Max Reitz mre...@redhat.com
---
 hw/block/fdc.c | 20 +---
 tests/fdc-test.c   |  4 +---
 tests/qemu-iotests/067.out | 60 +++---
 tests/qemu-iotests/071.out |  2 --
 tests/qemu-iotests/081.out |  1 -
 tests/qemu-iotests/087.out |  5 
 6 files changed, 26 insertions(+), 66 deletions(-)

diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 2bf87c9..0c5a6b4 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -192,6 +192,8 @@ typedef struct FDrive {
 uint8_t ro;   /* Is read-only   */
 uint8_t media_changed;/* Is media changed   */
 uint8_t media_rate;   /* Data rate of medium*/
+
+bool media_inserted;  /* Is there a medium in the tray */
 } FDrive;
 
 static void fd_init(FDrive *drv)
@@ -261,7 +263,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t 
track, uint8_t sect,
 #endif
 drv-head = head;
 if (drv-track != track) {
-if (drv-blk != NULL  blk_is_inserted(drv-blk)) {
+if (drv-media_inserted) {
 drv-media_changed = 0;
 }
 ret = 1;
@@ -270,7 +272,7 @@ static int fd_seek(FDrive *drv, uint8_t head, uint8_t 
track, uint8_t sect,
 drv-sect = sect;
 }
 
-if (drv-blk == NULL || !blk_is_inserted(drv-blk)) {
+if (!drv-media_inserted) {
 ret = 2;
 }
 
@@ -296,7 +298,7 @@ static void fd_revalidate(FDrive *drv)
 ro = blk_is_read_only(drv-blk);
 pick_geometry(drv-blk, nb_heads, max_track,
   last_sect, drv-drive, drive, rate);
-if (!blk_is_inserted(drv-blk)) {
+if (!drv-media_inserted) {
 FLOPPY_DPRINTF(No disk in drive\n);
 } else {
 FLOPPY_DPRINTF(Floppy disk (%d h %d t %d s) %s\n, nb_heads,
@@ -2062,12 +2064,21 @@ static void fdctrl_change_cb(void *opaque, bool load)
 {
 FDrive *drive = opaque;
 
+drive-media_inserted = load  drive-blk  blk_is_inserted(drive-blk);
+
 drive-media_changed = 1;
 fd_revalidate(drive);
 }
 
+static bool fdctrl_is_tray_open(void *opaque)
+{
+FDrive *drive = opaque;
+return !drive-media_inserted;
+}
+
 static const BlockDevOps fdctrl_block_ops = {
 .change_media_cb = fdctrl_change_cb,
+.is_tray_open = fdctrl_is_tray_open,
 };
 
 /* Init functions */
@@ -2095,6 +2106,9 @@ static void fdctrl_connect_drives(FDCtrl *fdctrl, Error 
**errp)
 fdctrl_change_cb(drive, 0);
 if (drive-blk) {
 blk_set_dev_ops(drive-blk, fdctrl_block_ops, drive);
+if (blk_is_inserted(drive-blk)) {
+drive-media_inserted = true;
+}
 }
 }
 }
diff --git a/tests/fdc-test.c b/tests/fdc-test.c
index 3c6c83c..f287c10 100644
--- a/tests/fdc-test.c
+++ b/tests/fdc-test.c
@@ -293,9 +293,7 @@ static void test_media_insert(void)
 qmp_discard_response({'execute':'change', 'arguments':{
   'device':'floppy0', 'target': %s, 'arg': 'raw' }},
  test_image);
-qmp_discard_response(); /* ignore event
- (FIXME open - open transition?!) */
-qmp_discard_response(); /* ignore event */
+qmp_discard_response(); /* ignore event (open - close) */
 
 dir = inb(FLOPPY_BASE + reg_dir);
 assert_bit_set(dir, DSKCHG);
diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out
index 00b3eae..42bae32 100644
--- a/tests/qemu-iotests/067.out
+++ b/tests/qemu-iotests/067.out
@@ -69,7 +69,7 @@ Testing: -drive 
file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti
 device: floppy0,
 locked: false,
 removable: true,
-tray_open: false,
+tray_open: true,
 type: unknown
 },
 {
@@ -131,7 +131,7 @@ Testing: -drive 
file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti
 device: floppy0,
 locked: false,
 removable: true,
-tray_open: false,
+tray_open: true,
 type: unknown
 },
 {
@@ -165,17 +165,6 @@ Testing: -drive 
file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti
 tray-open: true
 }
 }
-{
-timestamp: {
-seconds:  TIMESTAMP,
-microseconds:  TIMESTAMP
-},
-event: DEVICE_TRAY_MOVED,
-data: {
-device: floppy0,
-tray-open: true
-}
-}
 
 
 === -drive/device_add and device_del ===
@@ -246,7 +235,7 @@ Testing: -drive 
file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
 device: floppy0,
 locked: false,
 removable: true,
-  

[Qemu-devel] [PATCH 06/50] block: Add blk_is_available()

2015-01-26 Thread Max Reitz
blk_is_available() returns true iff the BDS is inserted (which means
blk_bs() is not NULL and bdrv_is_inserted() returns true) and if the
tray of the guest device is closed.

blk_is_inserted() is changed to return true only if blk_bs() is not
NULL.

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

diff --git a/block/block-backend.c b/block/block-backend.c
index 4c40747..4a2428e 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -738,7 +738,12 @@ void blk_invalidate_cache(BlockBackend *blk, Error **errp)
 
 int blk_is_inserted(BlockBackend *blk)
 {
-return bdrv_is_inserted(blk-bs);
+return blk-bs  bdrv_is_inserted(blk-bs);
+}
+
+bool blk_is_available(BlockBackend *blk)
+{
+return blk_is_inserted(blk)  !blk_dev_is_tray_open(blk);
 }
 
 void blk_lock_medium(BlockBackend *blk, bool locked)
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index f39bb5c..f91f3c7 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -127,6 +127,7 @@ int blk_enable_write_cache(BlockBackend *blk);
 void blk_set_enable_write_cache(BlockBackend *blk, bool wce);
 void blk_invalidate_cache(BlockBackend *blk, Error **errp);
 int blk_is_inserted(BlockBackend *blk);
+bool blk_is_available(BlockBackend *blk);
 void blk_lock_medium(BlockBackend *blk, bool locked);
 void blk_eject(BlockBackend *blk, bool eject_flag);
 int blk_get_flags(BlockBackend *blk);
-- 
2.1.0




[Qemu-devel] [PATCH 07/50] block: Make bdrv_is_inserted() recursive

2015-01-26 Thread Max Reitz
If bdrv_is_inserted() is called on the top level BDS, it should make
sure all nodes in the BDS tree are actually inserted.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block.c | 9 +
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/block.c b/block.c
index 4a5f8fc..aff7682 100644
--- a/block.c
+++ b/block.c
@@ -5208,11 +5208,12 @@ int bdrv_is_inserted(BlockDriverState *bs)
 {
 BlockDriver *drv = bs-drv;
 
-if (!drv)
+if (!drv) {
 return 0;
-if (!drv-bdrv_is_inserted)
-return 1;
-return drv-bdrv_is_inserted(bs);
+}
+return (!drv-bdrv_is_inserted || drv-bdrv_is_inserted(bs)) 
+   (!bs-file  || bdrv_is_inserted(bs-file)) 
+   (!bs-backing_hd|| bdrv_is_inserted(bs-backing_hd));
 }
 
 /**
-- 
2.1.0




[Qemu-devel] [PATCH 27/50] blockdev: Check BB validity in blockdev-backup

2015-01-26 Thread Max Reitz
Call blk_is_available() before using blk_bs() to obtain the root
BlockDriverState behind the BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 13 ++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 9476c72..e335d06 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2452,6 +2452,7 @@ void qmp_blockdev_backup(const char *device, const char 
*target,
  BlockdevOnError on_target_error,
  Error **errp)
 {
+BlockBackend *blk;
 BlockDriverState *bs;
 BlockDriverState *target_bs;
 Error *local_err = NULL;
@@ -2467,15 +2468,21 @@ void qmp_blockdev_backup(const char *device, const char 
*target,
 on_target_error = BLOCKDEV_ON_ERROR_REPORT;
 }
 
-bs = bdrv_find(device);
-if (!bs) {
+blk = blk_by_name(device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
 
-aio_context = bdrv_get_aio_context(bs);
+aio_context = blk_get_aio_context(blk);
 aio_context_acquire(aio_context);
 
+if (!blk_is_available(blk)) {
+error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+goto out;
+}
+bs = blk_bs(blk);
+
 target_bs = bdrv_find(target);
 if (!target_bs) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, target);
-- 
2.1.0




[Qemu-devel] [PATCH 10/50] block: Remove wr_highest_offset from BlockAcctStats

2015-01-26 Thread Max Reitz
BlockAcctStats contains statistics about the data transferred from and
to the device; wr_highest_offset does not fit in with the rest.

Furthermore, those statistics are supposed to be specific for a certain
device and not necessarily for a BDS (see the comment above
bdrv_get_stats()); on the other hand, wr_highest_offset may be a rather
important information to know for each BDS. When BlockAcctStats is
finally removed from the BDS, we will want to keep wr_highest_offset in
the BDS.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block.c| 4 +++-
 block/accounting.c | 9 -
 block/qapi.c   | 4 ++--
 include/block/accounting.h | 3 ---
 include/block/block_int.h  | 3 +++
 5 files changed, 8 insertions(+), 15 deletions(-)

diff --git a/block.c b/block.c
index eff92ca..5db71c6 100644
--- a/block.c
+++ b/block.c
@@ -3312,7 +3312,9 @@ static int coroutine_fn 
bdrv_aligned_pwritev(BlockDriverState *bs,
 
 bdrv_set_dirty(bs, sector_num, nb_sectors);
 
-block_acct_highest_sector(bs-stats, sector_num, nb_sectors);
+if (bs-wr_highest_sector  sector_num + nb_sectors - 1) {
+bs-wr_highest_sector = sector_num + nb_sectors - 1;
+}
 
 if (ret = 0) {
 bs-total_sectors = MAX(bs-total_sectors, sector_num + nb_sectors);
diff --git a/block/accounting.c b/block/accounting.c
index 18102f0..c77b6c2 100644
--- a/block/accounting.c
+++ b/block/accounting.c
@@ -45,12 +45,3 @@ void block_acct_done(BlockAcctStats *stats, BlockAcctCookie 
*cookie)
 stats-total_time_ns[cookie-type] +=
 qemu_clock_get_ns(QEMU_CLOCK_REALTIME) - cookie-start_time_ns;
 }
-
-
-void block_acct_highest_sector(BlockAcctStats *stats, int64_t sector_num,
-   unsigned int nb_sectors)
-{
-if (stats-wr_highest_sector  sector_num + nb_sectors - 1) {
-stats-wr_highest_sector = sector_num + nb_sectors - 1;
-}
-}
diff --git a/block/qapi.c b/block/qapi.c
index 8c3b9d9..4e97574 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -338,13 +338,13 @@ static BlockStats *bdrv_query_stats(const 
BlockDriverState *bs,
 s-stats-wr_bytes = bs-stats.nr_bytes[BLOCK_ACCT_WRITE];
 s-stats-rd_operations = bs-stats.nr_ops[BLOCK_ACCT_READ];
 s-stats-wr_operations = bs-stats.nr_ops[BLOCK_ACCT_WRITE];
-s-stats-wr_highest_offset =
-bs-stats.wr_highest_sector * BDRV_SECTOR_SIZE;
 s-stats-flush_operations = bs-stats.nr_ops[BLOCK_ACCT_FLUSH];
 s-stats-wr_total_time_ns = bs-stats.total_time_ns[BLOCK_ACCT_WRITE];
 s-stats-rd_total_time_ns = bs-stats.total_time_ns[BLOCK_ACCT_READ];
 s-stats-flush_total_time_ns = bs-stats.total_time_ns[BLOCK_ACCT_FLUSH];
 
+s-stats-wr_highest_offset = bs-wr_highest_sector * BDRV_SECTOR_SIZE;
+
 if (bs-file) {
 s-has_parent = true;
 s-parent = bdrv_query_stats(bs-file, query_backing);
diff --git a/include/block/accounting.h b/include/block/accounting.h
index 50b42b3..9089b67 100644
--- a/include/block/accounting.h
+++ b/include/block/accounting.h
@@ -39,7 +39,6 @@ typedef struct BlockAcctStats {
 uint64_t nr_bytes[BLOCK_MAX_IOTYPE];
 uint64_t nr_ops[BLOCK_MAX_IOTYPE];
 uint64_t total_time_ns[BLOCK_MAX_IOTYPE];
-uint64_t wr_highest_sector;
 } BlockAcctStats;
 
 typedef struct BlockAcctCookie {
@@ -51,7 +50,5 @@ typedef struct BlockAcctCookie {
 void block_acct_start(BlockAcctStats *stats, BlockAcctCookie *cookie,
   int64_t bytes, enum BlockAcctType type);
 void block_acct_done(BlockAcctStats *stats, BlockAcctCookie *cookie);
-void block_acct_highest_sector(BlockAcctStats *stats, int64_t sector_num,
-   unsigned int nb_sectors);
 
 #endif
diff --git a/include/block/block_int.h b/include/block/block_int.h
index c6ab73a..e309d8a 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -366,6 +366,9 @@ struct BlockDriverState {
 /* I/O stats (display with info blockstats). */
 BlockAcctStats stats;
 
+/* Highest sector index written to */
+uint64_t wr_highest_sector;
+
 /* I/O Limits */
 BlockLimits bl;
 
-- 
2.1.0




[Qemu-devel] [PATCH 18/50] block: Respect empty BB in bdrv_query_info()

2015-01-26 Thread Max Reitz
Signed-off-by: Max Reitz mre...@redhat.com
---
 block/qapi.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/block/qapi.c b/block/qapi.c
index 9a44d40..db42a6e 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -282,12 +282,12 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo 
**p_info,
 info-io_status = blk_iostatus(blk);
 }
 
-if (!QLIST_EMPTY(bs-dirty_bitmaps)) {
+if (bs  !QLIST_EMPTY(bs-dirty_bitmaps)) {
 info-has_dirty_bitmaps = true;
 info-dirty_bitmaps = bdrv_query_dirty_bitmaps(bs);
 }
 
-if (bs-drv) {
+if (bs  bs-drv) {
 info-has_inserted = true;
 info-inserted = bdrv_block_device_info(bs);
 
-- 
2.1.0




[Qemu-devel] [PATCH 26/50] blockdev: Check BB validity in drive-backup

2015-01-26 Thread Max Reitz
Call blk_is_available() before using blk_bs() to obtain the root
BlockDriverState behind the BlockBackend (instead of calling
bdrv_is_inserted() after bdrv_find()).

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 431afcd..9476c72 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2323,6 +2323,7 @@ void qmp_drive_backup(const char *device, const char 
*target,
   bool has_on_target_error, BlockdevOnError 
on_target_error,
   Error **errp)
 {
+BlockBackend *blk;
 BlockDriverState *bs;
 BlockDriverState *target_bs;
 BlockDriverState *source = NULL;
@@ -2346,21 +2347,22 @@ void qmp_drive_backup(const char *device, const char 
*target,
 mode = NEW_IMAGE_MODE_ABSOLUTE_PATHS;
 }
 
-bs = bdrv_find(device);
-if (!bs) {
+blk = blk_by_name(device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
 
-aio_context = bdrv_get_aio_context(bs);
+aio_context = blk_get_aio_context(blk);
 aio_context_acquire(aio_context);
 
 /* Although backup_run has this check too, we need to use bs-drv below, so
  * do an early check redundantly. */
-if (!bdrv_is_inserted(bs)) {
+if (!blk_is_available(blk)) {
 error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
 goto out;
 }
+bs = blk_bs(blk);
 
 if (!has_format) {
 format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs-drv-format_name;
-- 
2.1.0




[Qemu-devel] [PATCH 34/50] blockdev: Do not create BDS for empty drive

2015-01-26 Thread Max Reitz
Do not use rudimentary BDSs for empty drives any longer (for
freshly created drives).

With this change, bdrv_close_all() has no effect on empty drives (whose
media were not changed) any longer. This breaks some test outputs, fix
them.

After a follow-up patch, empty drives will generally use a NULL BDS, not
only the freshly created drives.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 68 ++
 tests/qemu-iotests/067.out | 44 --
 tests/qemu-iotests/071.out |  2 --
 tests/qemu-iotests/081.out |  1 -
 tests/qemu-iotests/087.out |  5 
 5 files changed, 38 insertions(+), 82 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index f82b20c..d99edbb 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -502,16 +502,40 @@ static BlockBackend *blockdev_init(const char *file, 
QDict *bs_opts,
 goto early_err;
 }
 
+if (snapshot) {
+/* always use cache=unsafe with snapshot */
+bdrv_flags = ~BDRV_O_CACHE_MASK;
+bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
+}
+
+if (copy_on_read) {
+bdrv_flags |= BDRV_O_COPY_ON_READ;
+}
+
+if (runstate_check(RUN_STATE_INMIGRATE)) {
+bdrv_flags |= BDRV_O_INCOMING;
+}
+
+bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
+
 /* init */
 if ((!file || !*file)  !has_driver_specific_opts) {
-blk = blk_new_with_bs(qemu_opts_id(opts), errp);
+BlockBackendRootState *blk_rs;
+
+blk = blk_new(qemu_opts_id(opts), errp);
 if (!blk) {
 goto early_err;
 }
 
-bs = blk_bs(blk);
-bs-open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
-bs-read_only = ro;
+blk_rs = blk_get_root_state(blk);
+blk_rs-open_flags= bdrv_flags;
+blk_rs-read_only = ro;
+blk_rs-detect_zeroes = detect_zeroes;
+
+if (throttle_enabled(cfg)) {
+blk_rs-io_limits_enabled = true;
+blk_rs-throttle_config = cfg;
+}
 
 QDECREF(bs_opts);
 } else {
@@ -519,43 +543,27 @@ static BlockBackend *blockdev_init(const char *file, 
QDict *bs_opts,
 file = NULL;
 }
 
-if (snapshot) {
-/* always use cache=unsafe with snapshot */
-bdrv_flags = ~BDRV_O_CACHE_MASK;
-bdrv_flags |= (BDRV_O_SNAPSHOT|BDRV_O_CACHE_WB|BDRV_O_NO_FLUSH);
-}
-
-if (copy_on_read) {
-bdrv_flags |= BDRV_O_COPY_ON_READ;
-}
-
-if (runstate_check(RUN_STATE_INMIGRATE)) {
-bdrv_flags |= BDRV_O_INCOMING;
-}
-
-bdrv_flags |= ro ? 0 : BDRV_O_RDWR;
-
 blk = blk_new_open(qemu_opts_id(opts), file, NULL, bs_opts, bdrv_flags,
errp);
 if (!blk) {
 goto err_no_bs_opts;
 }
 bs = blk_bs(blk);
-}
 
-bs-detect_zeroes = detect_zeroes;
+bs-detect_zeroes = detect_zeroes;
 
-blk_set_on_error(blk, on_read_error, on_write_error);
+/* disk I/O throttling */
+if (throttle_enabled(cfg)) {
+bdrv_io_limits_enable(bs);
+bdrv_set_io_limits(bs, cfg);
+}
 
-/* disk I/O throttling */
-if (throttle_enabled(cfg)) {
-bdrv_io_limits_enable(bs);
-bdrv_set_io_limits(bs, cfg);
+if (bdrv_key_required(bs)) {
+autostart = 0;
+}
 }
 
-if (bdrv_key_required(bs)) {
-autostart = 0;
-}
+blk_set_on_error(blk, on_read_error, on_write_error);
 
 err_no_bs_opts:
 qemu_opts_del(opts);
diff --git a/tests/qemu-iotests/067.out b/tests/qemu-iotests/067.out
index 42bae32..47b0b68 100644
--- a/tests/qemu-iotests/067.out
+++ b/tests/qemu-iotests/067.out
@@ -154,17 +154,6 @@ Testing: -drive 
file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti
 },
 event: SHUTDOWN
 }
-{
-timestamp: {
-seconds:  TIMESTAMP,
-microseconds:  TIMESTAMP
-},
-event: DEVICE_TRAY_MOVED,
-data: {
-device: ide1-cd0,
-tray-open: true
-}
-}
 
 
 === -drive/device_add and device_del ===
@@ -324,17 +313,6 @@ Testing: -drive 
file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
 },
 event: SHUTDOWN
 }
-{
-timestamp: {
-seconds:  TIMESTAMP,
-microseconds:  TIMESTAMP
-},
-event: DEVICE_TRAY_MOVED,
-data: {
-device: ide1-cd0,
-tray-open: true
-}
-}
 
 
 === drive_add/device_add and device_del ===
@@ -497,17 +475,6 @@ Testing:
 },
 event: SHUTDOWN
 }
-{
-timestamp: {
-seconds:  TIMESTAMP,
-microseconds:  TIMESTAMP
-},
-event: DEVICE_TRAY_MOVED,
-data: {
-device: ide1-cd0,
-tray-open: true
-}
-}
 
 
 === blockdev_add/device_add and device_del ===
@@ -716,16 +683,5 @@ Testing:
 },
 event: SHUTDOWN
 }
-{
-timestamp: {
-seconds:  TIMESTAMP,
-microseconds:  TIMESTAMP
-},
-

[Qemu-devel] [PATCH 30/50] blockdev: Check BB validity in change-backing-file

2015-01-26 Thread Max Reitz
Call blk_is_available() before using blk_bs() to obtain the root
BlockDriverState behind the BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 4bd52b8..7f4470f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2821,7 +2821,8 @@ void qmp_change_backing_file(const char *device,
  const char *backing_file,
  Error **errp)
 {
-BlockDriverState *bs = NULL;
+BlockBackend *blk;
+BlockDriverState *bs;
 AioContext *aio_context;
 BlockDriverState *image_bs = NULL;
 Error *local_err = NULL;
@@ -2830,15 +2831,21 @@ void qmp_change_backing_file(const char *device,
 int ret;
 
 /* find the top layer BDS of the chain */
-bs = bdrv_find(device);
-if (!bs) {
+blk = blk_by_name(device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
 
-aio_context = bdrv_get_aio_context(bs);
+aio_context = blk_get_aio_context(blk);
 aio_context_acquire(aio_context);
 
+if (!blk_is_available(blk)) {
+error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+goto out;
+}
+bs = blk_bs(blk);
+
 image_bs = bdrv_lookup_bs(NULL, image_node_name, local_err);
 if (local_err) {
 error_propagate(errp, local_err);
-- 
2.1.0




Re: [Qemu-devel] [Spice-devel] [PATCH] [RFC] LZ4 compression option for SPICE

2015-01-26 Thread Eric Blake
On 01/26/2015 01:48 AM, Javier Celaya wrote:
 Sorry, I forgot to patch the command-line help. Hope it helps.
 


 Recently, SPICE included the lz4 compression algorithm. This patch adds
 a command line option to select it.


 How is libvirt going to introspect whether the command line supports
 this option?  Is there some QMP command that lists the set of valid
 compression formats understood by a given qemu binary?

No, patching the command line --help does NOT help libvirt.  It needs to
be discoverable via QMP to be introspectible, as scraping --help output
is not machine-friendly.  (That said, you DO want to expose it in --help
output; I'm just complaining that --help output alone is not enough).

-- 
Eric Blake   eblake redhat com+1-919-301-3266
Libvirt virtualization library http://libvirt.org



signature.asc
Description: OpenPGP digital signature


[Qemu-devel] [PATCH 46/50] hmp: Use blockdev-change-medium for change command

2015-01-26 Thread Max Reitz
Use separate code paths for the two overloaded functions of the 'change'
HMP command, and invoke the 'blockdev-change-medium' QMP command if used
on a block device (by calling qmp_blockdev_change_medium()).

Signed-off-by: Max Reitz mre...@redhat.com
Reviewed-by: Eric Blake ebl...@redhat.com
---
 hmp.c | 27 +++
 1 file changed, 15 insertions(+), 12 deletions(-)

diff --git a/hmp.c b/hmp.c
index f806387..300e7d8 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1180,22 +1180,25 @@ void hmp_change(Monitor *mon, const QDict *qdict)
 const char *arg = qdict_get_try_str(qdict, arg);
 Error *err = NULL;
 
-if (strcmp(device, vnc) == 0 
-(strcmp(target, passwd) == 0 ||
- strcmp(target, password) == 0)) {
-if (!arg) {
-monitor_read_password(mon, hmp_change_read_arg, NULL);
+if (strcmp(device, vnc) == 0) {
+if (strcmp(target, passwd) == 0 ||
+strcmp(target, password) == 0) {
+if (!arg) {
+monitor_read_password(mon, hmp_change_read_arg, NULL);
+return;
+}
+}
+qmp_change(vnc, target, !!arg, arg, err);
+} else {
+qmp_blockdev_change_medium(device, target, !!arg, arg, err);
+if (err 
+error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
+error_free(err);
+monitor_read_block_device_key(mon, device, NULL, NULL);
 return;
 }
 }
 
-qmp_change(device, target, !!arg, arg, err);
-if (err 
-error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
-error_free(err);
-monitor_read_block_device_key(mon, device, NULL, NULL);
-return;
-}
 hmp_handle_error(mon, err);
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v3 09/14] qemu-io: Use blk_new_open() in openfile()

2015-01-26 Thread Max Reitz
Signed-off-by: Max Reitz mre...@redhat.com
---
 qemu-io.c | 31 ---
 1 file changed, 12 insertions(+), 19 deletions(-)

diff --git a/qemu-io.c b/qemu-io.c
index 91a445a..81f8f64 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -39,7 +39,6 @@ static ReadLineState *readline_state;
 static int close_f(BlockDriverState *bs, int argc, char **argv)
 {
 blk_unref(qemuio_blk);
-qemuio_bs = NULL;
 qemuio_blk = NULL;
 return 0;
 }
@@ -51,34 +50,29 @@ static const cmdinfo_t close_cmd = {
 .oneline= close the current open file,
 };
 
-static int openfile(char *name, BlockDriver *drv, int flags, int growable,
-QDict *opts)
+static int openfile(char *name, int flags, int growable, QDict *opts)
 {
 Error *local_err = NULL;
 
-if (qemuio_bs) {
+if (qemuio_blk) {
 fprintf(stderr, file open already, try 'help close'\n);
 QDECREF(opts);
 return 1;
 }
 
-qemuio_blk = blk_new_with_bs(hda, error_abort);
-qemuio_bs = blk_bs(qemuio_blk);
-
 if (growable) {
 flags |= BDRV_O_PROTOCOL;
 }
 
-if (bdrv_open(qemuio_bs, name, NULL, opts, flags, drv, local_err)  0) {
+qemuio_blk = blk_new_open(hda, name, NULL, opts, flags, local_err);
+if (!qemuio_blk) {
 fprintf(stderr, %s: can't open%s%s: %s\n, progname,
 name ?  device  : , name ?: ,
 error_get_pretty(local_err));
 error_free(local_err);
-blk_unref(qemuio_blk);
-qemuio_bs = NULL;
-qemuio_blk = NULL;
 return 1;
 }
+qemuio_bs = blk_bs(qemuio_blk);
 
 return 0;
 }
@@ -170,9 +164,9 @@ static int open_f(BlockDriverState *bs, int argc, char 
**argv)
 qemu_opts_reset(empty_opts);
 
 if (optind == argc - 1) {
-return openfile(argv[optind], NULL, flags, growable, opts);
+return openfile(argv[optind], flags, growable, opts);
 } else if (optind == argc) {
-return openfile(NULL, NULL, flags, growable, opts);
+return openfile(NULL, flags, growable, opts);
 } else {
 QDECREF(opts);
 return qemuio_command_usage(open_cmd);
@@ -387,8 +381,8 @@ int main(int argc, char **argv)
 int c;
 int opt_index = 0;
 int flags = BDRV_O_UNMAP;
-BlockDriver *drv = NULL;
 Error *local_error = NULL;
+QDict *opts = NULL;
 
 #ifdef CONFIG_POSIX
 signal(SIGPIPE, SIG_IGN);
@@ -414,11 +408,10 @@ int main(int argc, char **argv)
 }
 break;
 case 'f':
-drv = bdrv_find_format(optarg);
-if (!drv) {
-error_report(Invalid format '%s', optarg);
-exit(EXIT_FAILURE);
+if (!opts) {
+opts = qdict_new();
 }
+qdict_put_obj(opts, driver, QOBJECT(qstring_from_str(optarg)));
 break;
 case 'c':
 add_user_command(optarg);
@@ -489,7 +482,7 @@ int main(int argc, char **argv)
 }
 
 if ((argc - optind) == 1) {
-openfile(argv[optind], drv, flags, growable, NULL);
+openfile(argv[optind], flags, growable, opts);
 }
 command_loop();
 
-- 
2.1.0




[Qemu-devel] [PATCH v3 05/14] qemu-img: Use blk_new_open() in img_open()

2015-01-26 Thread Max Reitz
Signed-off-by: Max Reitz mre...@redhat.com
---
 qemu-img.c | 20 ++--
 1 file changed, 6 insertions(+), 14 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 4e9a7f5..be1953d 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -291,32 +291,24 @@ static BlockBackend *img_open(const char *id, const char 
*filename,
 {
 BlockBackend *blk;
 BlockDriverState *bs;
-BlockDriver *drv;
 char password[256];
 Error *local_err = NULL;
-int ret;
-
-blk = blk_new_with_bs(id, error_abort);
-bs = blk_bs(blk);
+QDict *options = NULL;
 
 if (fmt) {
-drv = bdrv_find_format(fmt);
-if (!drv) {
-error_report(Unknown file format '%s', fmt);
-goto fail;
-}
-} else {
-drv = NULL;
+options = qdict_new();
+qdict_put_obj(options, driver, QOBJECT(qstring_from_str(fmt)));
 }
 
-ret = bdrv_open(bs, filename, NULL, NULL, flags, drv, local_err);
-if (ret  0) {
+blk = blk_new_open(id, filename, NULL, options, flags, local_err);
+if (!blk) {
 error_report(Could not open '%s': %s, filename,
  error_get_pretty(local_err));
 error_free(local_err);
 goto fail;
 }
 
+bs = blk_bs(blk);
 if (bdrv_is_encrypted(bs)  require_io) {
 qprintf(quiet, Disk image '%s' is encrypted.\n, filename);
 if (read_password(password, sizeof(password))  0) {
-- 
2.1.0




[Qemu-devel] [PATCH v3 12/14] block: Clamp BlockBackend requests

2015-01-26 Thread Max Reitz
BlockBackend is used as the interface between the block layer and guest
devices. It should therefore assure that all requests are clamped to the
image size.

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

diff --git a/block/block-backend.c b/block/block-backend.c
index 543edaa..96a5bc6 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -31,6 +31,16 @@ struct BlockBackend {
 void *dev_opaque;
 };
 
+typedef struct BlockBackendAIOCB {
+BlockAIOCB common;
+QEMUBH *bh;
+int ret;
+} BlockBackendAIOCB;
+
+static const AIOCBInfo block_backend_aiocb_info = {
+.aiocb_size = sizeof(BlockBackendAIOCB),
+};
+
 static void drive_info_del(DriveInfo *dinfo);
 
 /* All the BlockBackends (except for hidden ones) */
@@ -428,39 +438,137 @@ void blk_iostatus_enable(BlockBackend *blk)
 bdrv_iostatus_enable(blk-bs);
 }
 
+static int blk_check_byte_request(BlockBackend *blk, int64_t offset,
+  size_t size)
+{
+int64_t len;
+
+if (size  INT_MAX) {
+return -EIO;
+}
+
+if (!blk_is_inserted(blk)) {
+return -ENOMEDIUM;
+}
+
+len = blk_getlength(blk);
+if (len  0) {
+return len;
+}
+
+if (offset  0) {
+return -EIO;
+}
+
+if (offset  len || len - offset  size) {
+return -EIO;
+}
+
+return 0;
+}
+
+static int blk_check_request(BlockBackend *blk, int64_t sector_num,
+ int nb_sectors)
+{
+if (sector_num  0 || sector_num  INT64_MAX / BDRV_SECTOR_SIZE) {
+return -EIO;
+}
+
+if (nb_sectors  0 || nb_sectors  INT_MAX / BDRV_SECTOR_SIZE) {
+return -EIO;
+}
+
+return blk_check_byte_request(blk, sector_num * BDRV_SECTOR_SIZE,
+  nb_sectors * BDRV_SECTOR_SIZE);
+}
+
 int blk_read(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
  int nb_sectors)
 {
+int ret = blk_check_request(blk, sector_num, nb_sectors);
+if (ret  0) {
+return ret;
+}
+
 return bdrv_read(blk-bs, sector_num, buf, nb_sectors);
 }
 
 int blk_read_unthrottled(BlockBackend *blk, int64_t sector_num, uint8_t *buf,
  int nb_sectors)
 {
+int ret = blk_check_request(blk, sector_num, nb_sectors);
+if (ret  0) {
+return ret;
+}
+
 return bdrv_read_unthrottled(blk-bs, sector_num, buf, nb_sectors);
 }
 
 int blk_write(BlockBackend *blk, int64_t sector_num, const uint8_t *buf,
   int nb_sectors)
 {
+int ret = blk_check_request(blk, sector_num, nb_sectors);
+if (ret  0) {
+return ret;
+}
+
 return bdrv_write(blk-bs, sector_num, buf, nb_sectors);
 }
 
+static void error_callback_bh(void *opaque)
+{
+struct BlockBackendAIOCB *acb = opaque;
+qemu_bh_delete(acb-bh);
+acb-common.cb(acb-common.opaque, acb-ret);
+qemu_aio_unref(acb);
+}
+
+static BlockAIOCB *abort_aio_request(BlockBackend *blk, BlockCompletionFunc 
*cb,
+ void *opaque, int ret)
+{
+struct BlockBackendAIOCB *acb;
+QEMUBH *bh;
+
+acb = blk_aio_get(block_backend_aiocb_info, blk, cb, opaque);
+acb-ret = ret;
+
+bh = aio_bh_new(blk_get_aio_context(blk), error_callback_bh, acb);
+acb-bh = bh;
+qemu_bh_schedule(bh);
+
+return acb-common;
+}
+
 BlockAIOCB *blk_aio_write_zeroes(BlockBackend *blk, int64_t sector_num,
  int nb_sectors, BdrvRequestFlags flags,
  BlockCompletionFunc *cb, void *opaque)
 {
+int ret = blk_check_request(blk, sector_num, nb_sectors);
+if (ret  0) {
+return abort_aio_request(blk, cb, opaque, ret);
+}
+
 return bdrv_aio_write_zeroes(blk-bs, sector_num, nb_sectors, flags,
  cb, opaque);
 }
 
 int blk_pread(BlockBackend *blk, int64_t offset, void *buf, int count)
 {
+int ret = blk_check_byte_request(blk, offset, count);
+if (ret  0) {
+return ret;
+}
+
 return bdrv_pread(blk-bs, offset, buf, count);
 }
 
 int blk_pwrite(BlockBackend *blk, int64_t offset, const void *buf, int count)
 {
+int ret = blk_check_byte_request(blk, offset, count);
+if (ret  0) {
+return ret;
+}
+
 return bdrv_pwrite(blk-bs, offset, buf, count);
 }
 
@@ -478,6 +586,11 @@ BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t 
sector_num,
   QEMUIOVector *iov, int nb_sectors,
   BlockCompletionFunc *cb, void *opaque)
 {
+int ret = blk_check_request(blk, sector_num, nb_sectors);
+if (ret  0) {
+return abort_aio_request(blk, cb, opaque, ret);
+}
+
 return bdrv_aio_readv(blk-bs, sector_num, iov, nb_sectors, cb, opaque);
 }
 
@@ -485,6 +598,11 @@ BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t 
sector_num,

Re: [Qemu-devel] [PATCH 05/11] target-arm: Use correct mmu_idx for unprivileged loads and stores

2015-01-26 Thread Peter Maydell
On 26 January 2015 at 14:40, Greg Bellows greg.bell...@linaro.org wrote:
 On Fri, Jan 23, 2015 at 12:20 PM, Peter Maydell peter.mayd...@linaro.org
 wrote:

 The MMU index to use for unprivileged loads and stores is more
 complicated than we currently implement:
  * for A64, it should be if at EL1, access as if EL0; otherwise
access at current EL
  * for A32/T32, it should be if EL2, UNPREDICTABLE; otherwise
access as if at EL0.


 The wording between the specs appears to be almost identical, curious why
 the handling is different?

Because that's what the ARM ARM specifies. Compare C3.2.5 (A64 LDT c)
with F7.1.95 (A32/T32 LDRT).

-- PMM



[Qemu-devel] [PATCH 1/2] vl.c: Fix error messages when parsing maxmem parameters

2015-01-26 Thread Peter Krempa
Produce more human readable error messages and fix few spelling
mistakes.

Also remove a redundant check for the max memory size.

Signed-off-by: Peter Krempa pkre...@redhat.com
---
 vl.c | 22 +++---
 1 file changed, 7 insertions(+), 15 deletions(-)

diff --git a/vl.c b/vl.c
index 983259b..cdc920c 100644
--- a/vl.c
+++ b/vl.c
@@ -2694,29 +2694,21 @@ static void set_memory_options(uint64_t *ram_slots, 
ram_addr_t *maxram_size)
 uint64_t slots;

 sz = qemu_opt_get_size(opts, maxmem, 0);
-if (sz  ram_size) {
-error_report(invalid -m option value: maxmem 
-(0x% PRIx64 ) = initial memory (0x
-RAM_ADDR_FMT ), sz, ram_size);
+if (sz = ram_size) {
+error_report(invalid value of -m option maxmem: 
+ maximum memory size (0x% PRIx64 ) must be greater 
+ than initial memory size (0x  RAM_ADDR_FMT ),
+ sz, ram_size);
 exit(EXIT_FAILURE);
 }

 slots = qemu_opt_get_number(opts, slots, 0);
 if ((sz  ram_size)  !slots) {
-error_report(invalid -m option value: maxmem 
-(0x% PRIx64 ) more than initial memory (0x
-RAM_ADDR_FMT ) but no hotplug slots where 
-specified, sz, ram_size);
+error_report(invalid value of -m option: maxmem was specified, 
+ but no hotplug slots were specified);
 exit(EXIT_FAILURE);
 }

-if ((sz = ram_size)  slots) {
-error_report(invalid -m option value:  %
-PRIu64  hotplug slots where specified but 
-maxmem (0x% PRIx64 ) = initial memory (0x
-RAM_ADDR_FMT ), slots, sz, ram_size);
-exit(EXIT_FAILURE);
-}
 *maxram_size = sz;
 *ram_slots = slots;
 } else if ((!maxmem_str  slots_str) ||
-- 
2.2.1




[Qemu-devel] [PATCH 13/50] block: Add BlockBackendRootState

2015-01-26 Thread Max Reitz
This structure will store some of the state of the root BDS if the BDS
tree is removed, so that state can be restored once a new BDS tree is
inserted.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/block-backend.c  | 26 ++
 include/block/block_int.h  |  9 +
 include/qemu/typedefs.h|  1 +
 include/sysemu/block-backend.h |  2 ++
 4 files changed, 38 insertions(+)

diff --git a/block/block-backend.c b/block/block-backend.c
index 2a48e82..7be03ee 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -37,6 +37,10 @@ struct BlockBackend {
 /* the block size for which the guest device expects atomicity */
 int guest_block_size;
 
+/* If the BDS tree is removed, some of its options are stored here (which
+ * can be used to restore those options in the new BDS on insert) */
+BlockBackendRootState root_state;
+
 /* I/O stats (display with info blockstats). */
 BlockAcctStats stats;
 
@@ -1014,3 +1018,25 @@ int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, 
int64_t pos, int size)
 {
 return bdrv_load_vmstate(blk-bs, buf, pos, size);
 }
+
+/*
+ * Updates the BlockBackendRootState object with data from the currently
+ * attached BlockDriverState.
+ */
+void blk_update_root_state(BlockBackend *blk)
+{
+assert(blk-bs);
+
+blk-root_state.open_flags= blk-bs-open_flags;
+blk-root_state.read_only = blk-bs-read_only;
+blk-root_state.detect_zeroes = blk-bs-detect_zeroes;
+
+blk-root_state.io_limits_enabled = blk-bs-io_limits_enabled;
+throttle_get_config(blk-bs-throttle_state,
+blk-root_state.throttle_config);
+}
+
+BlockBackendRootState *blk_get_root_state(BlockBackend *blk)
+{
+return blk-root_state;
+}
diff --git a/include/block/block_int.h b/include/block/block_int.h
index 69668e4..91d21c5 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -406,6 +406,15 @@ struct BlockDriverState {
 NotifierWithReturn write_threshold_notifier;
 };
 
+struct BlockBackendRootState {
+int open_flags;
+bool read_only;
+BlockdevDetectZeroesOptions detect_zeroes;
+
+bool io_limits_enabled;
+ThrottleConfig throttle_config;
+};
+
 
 /* Essential block drivers which must always be statically linked into qemu, 
and
  * which therefore can be accessed without using bdrv_find_format() */
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index cde3314..39a95dd 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -11,6 +11,7 @@ typedef struct AddressSpace AddressSpace;
 typedef struct AioContext AioContext;
 typedef struct AudioState AudioState;
 typedef struct BlockBackend BlockBackend;
+typedef struct BlockBackendRootState BlockBackendRootState;
 typedef struct BlockDriverState BlockDriverState;
 typedef struct BusClass BusClass;
 typedef struct BusState BusState;
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index c4a61c0..afb62e1 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -158,6 +158,8 @@ void blk_add_close_notifier(BlockBackend *blk, Notifier 
*notify);
 void blk_io_plug(BlockBackend *blk);
 void blk_io_unplug(BlockBackend *blk);
 BlockAcctStats *blk_get_stats(BlockBackend *blk);
+BlockBackendRootState *blk_get_root_state(BlockBackend *blk);
+void blk_update_root_state(BlockBackend *blk);
 
 void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
   BlockCompletionFunc *cb, void *opaque);
-- 
2.1.0




[Qemu-devel] [PATCH 14/50] block: Make some BB functions fall back to BBRS

2015-01-26 Thread Max Reitz
If there is no BDS tree attached to a BlockBackend, functions that can
do so should fall back to the BlockBackendRootState structure (which are
blk_is_read_only() and blk_get_flags(), because the read-only status and
the open flags are part of the BBRS).

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/block-backend.c | 12 ++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 7be03ee..62be370 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -829,7 +829,11 @@ void blk_error_action(BlockBackend *blk, BlockErrorAction 
action,
 
 int blk_is_read_only(BlockBackend *blk)
 {
-return bdrv_is_read_only(blk-bs);
+if (blk-bs) {
+return bdrv_is_read_only(blk-bs);
+} else {
+return blk-root_state.read_only;
+}
 }
 
 int blk_is_sg(BlockBackend *blk)
@@ -874,7 +878,11 @@ void blk_eject(BlockBackend *blk, bool eject_flag)
 
 int blk_get_flags(BlockBackend *blk)
 {
-return bdrv_get_flags(blk-bs);
+if (blk-bs) {
+return bdrv_get_flags(blk-bs);
+} else {
+return blk-root_state.open_flags;
+}
 }
 
 void blk_set_guest_block_size(BlockBackend *blk, int align)
-- 
2.1.0




[Qemu-devel] [PATCH 23/50] blockdev: Catch NULL BDS in block_set_io_throttle

2015-01-26 Thread Max Reitz
Split bdrv_find() into blk_by_name() and blk_bs() to separate the
no medium inserted case from the device not found case.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 20 ++--
 1 file changed, 14 insertions(+), 6 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 5f7eef5..9801a7e 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1922,15 +1922,25 @@ void qmp_block_set_io_throttle(const char *device, 
int64_t bps, int64_t bps_rd,
int64_t iops_size, Error **errp)
 {
 ThrottleConfig cfg;
+BlockBackend *blk;
 BlockDriverState *bs;
 AioContext *aio_context;
 
-bs = bdrv_find(device);
-if (!bs) {
+blk = blk_by_name(device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
 
+aio_context = blk_get_aio_context(blk);
+aio_context_acquire(aio_context);
+
+bs = blk_bs(blk);
+if (!bs) {
+error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+goto out;
+}
+
 memset(cfg, 0, sizeof(cfg));
 cfg.buckets[THROTTLE_BPS_TOTAL].avg = bps;
 cfg.buckets[THROTTLE_BPS_READ].avg  = bps_rd;
@@ -1964,12 +1974,9 @@ void qmp_block_set_io_throttle(const char *device, 
int64_t bps, int64_t bps_rd,
 }
 
 if (!check_throttle_config(cfg, errp)) {
-return;
+goto out;
 }
 
-aio_context = bdrv_get_aio_context(bs);
-aio_context_acquire(aio_context);
-
 if (!bs-io_limits_enabled  throttle_enabled(cfg)) {
 bdrv_io_limits_enable(bs);
 } else if (bs-io_limits_enabled  !throttle_enabled(cfg)) {
@@ -1980,6 +1987,7 @@ void qmp_block_set_io_throttle(const char *device, 
int64_t bps, int64_t bps_rd,
 bdrv_set_io_limits(bs, cfg);
 }
 
+out:
 aio_context_release(aio_context);
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH 05/50] block: Fix BB AIOCB AioContext without BDS

2015-01-26 Thread Max Reitz
Fix the BlockBackend's AIOCB AioContext for aborting AIO in case there
is no BDS. If there is no implementation of AIOCBInfo::get_aio_context()
the AioContext is derived from the BDS the AIOCB belongs to. If that BDS
is NULL (because it has been removed from the BB) this will not work.

This patch makes blk_get_aio_context() fall back to the main loop
context if the BDS pointer is NULL and implements
AIOCBInfo::get_aio_context() (blk_aiocb_get_aio_context()) which invokes
blk_get_aio_context().

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

diff --git a/block/block-backend.c b/block/block-backend.c
index 96a5bc6..4c40747 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -18,6 +18,8 @@
 /* Number of coroutines to reserve per attached device model */
 #define COROUTINE_POOL_RESERVATION 64
 
+static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb);
+
 struct BlockBackend {
 char *name;
 int refcnt;
@@ -34,10 +36,12 @@ struct BlockBackend {
 typedef struct BlockBackendAIOCB {
 BlockAIOCB common;
 QEMUBH *bh;
+BlockBackend *blk;
 int ret;
 } BlockBackendAIOCB;
 
 static const AIOCBInfo block_backend_aiocb_info = {
+.get_aio_context = blk_aiocb_get_aio_context,
 .aiocb_size = sizeof(BlockBackendAIOCB),
 };
 
@@ -530,6 +534,7 @@ static BlockAIOCB *abort_aio_request(BlockBackend *blk, 
BlockCompletionFunc *cb,
 QEMUBH *bh;
 
 acb = blk_aio_get(block_backend_aiocb_info, blk, cb, opaque);
+acb-blk = blk;
 acb-ret = ret;
 
 bh = aio_bh_new(blk_get_aio_context(blk), error_callback_bh, acb);
@@ -783,7 +788,17 @@ void blk_op_unblock_all(BlockBackend *blk, Error *reason)
 
 AioContext *blk_get_aio_context(BlockBackend *blk)
 {
-return bdrv_get_aio_context(blk-bs);
+if (blk-bs) {
+return bdrv_get_aio_context(blk-bs);
+} else {
+return qemu_get_aio_context();
+}
+}
+
+static AioContext *blk_aiocb_get_aio_context(BlockAIOCB *acb)
+{
+BlockBackendAIOCB *blk_acb = DO_UPCAST(BlockBackendAIOCB, common, acb);
+return blk_get_aio_context(blk_acb-blk);
 }
 
 void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
-- 
2.1.0




[Qemu-devel] [PATCH 47/50] blockdev: Add read-only option to blockdev-change-medium

2015-01-26 Thread Max Reitz
Add an option to qmp_blockdev_change_medium() which allows changing the
read-only status of the block device whose medium is changed.

Some drives do not have a inherently fixed read-only status; for
instance, floppy disks can be set read-only or writable independently of
the drive. Some users may find it useful to be able to therefore change
the read-only status of a block device when changing the medium.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c   | 25 -
 hmp.c|  2 +-
 qapi/block-core.json | 24 +++-
 qmp-commands.hx  | 24 +++-
 qmp.c|  3 ++-
 5 files changed, 73 insertions(+), 5 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 2ada2b1..8ed2fec 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2014,6 +2014,8 @@ void qmp_blockdev_insert_medium(const char *device, const 
char *node_name,
 
 void qmp_blockdev_change_medium(const char *device, const char *filename,
 bool has_format, const char *format,
+bool has_read_only,
+BlockdevChangeReadOnlyMode read_only,
 Error **errp)
 {
 BlockBackend *blk;
@@ -2034,7 +2036,28 @@ void qmp_blockdev_change_medium(const char *device, 
const char *filename,
 }
 
 blk_rs = blk_get_root_state(blk);
-bdrv_flags = blk_rs-read_only ? 0 : BDRV_O_RDWR;
+
+if (!has_read_only) {
+read_only = BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN;
+}
+
+switch (read_only) {
+case BLOCKDEV_CHANGE_READ_ONLY_MODE_RETAIN:
+bdrv_flags = blk_rs-read_only ? 0 : BDRV_O_RDWR;
+break;
+
+case BLOCKDEV_CHANGE_READ_ONLY_MODE_RO:
+bdrv_flags = 0;
+break;
+
+case BLOCKDEV_CHANGE_READ_ONLY_MODE_RW:
+bdrv_flags = BDRV_O_RDWR;
+break;
+
+default:
+abort();
+}
+
 bdrv_flags |= blk_rs-open_flags  ~BDRV_O_RDWR;
 
 if (has_format) {
diff --git a/hmp.c b/hmp.c
index 300e7d8..dbf0947 100644
--- a/hmp.c
+++ b/hmp.c
@@ -1190,7 +1190,7 @@ void hmp_change(Monitor *mon, const QDict *qdict)
 }
 qmp_change(vnc, target, !!arg, arg, err);
 } else {
-qmp_blockdev_change_medium(device, target, !!arg, arg, err);
+qmp_blockdev_change_medium(device, target, !!arg, arg, false, 0, err);
 if (err 
 error_get_class(err) == ERROR_CLASS_DEVICE_ENCRYPTED) {
 error_free(err);
diff --git a/qapi/block-core.json b/qapi/block-core.json
index d3c3ca7..eb2724e 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1785,6 +1785,24 @@
 
 
 ##
+# @BlockdevChangeReadOnlyMode:
+#
+# Specifies the new read-only mode of a block device subject to the
+# @blockdev-change-medium command.
+#
+# @retain:  Retains the current read-only mode
+#
+# @ro:  Makes the device read-only
+#
+# @rw:  Makes the device writable
+#
+# Since: 2.3
+##
+{ 'enum': 'BlockdevChangeReadOnlyMode',
+  'data': ['retain', 'ro', 'rw'] }
+
+
+##
 # @blockdev-change-medium:
 #
 # Changes the medium inserted into a block device by ejecting the current 
medium
@@ -1799,12 +1817,16 @@
 # @format:  #optional, format to open the new image with (defaults to the
 #   probed format)
 #
+# @read-only:   #optional, change the read-only mode of the device; defaults to
+#   'retain'
+#
 # Since: 2.3
 ##
 { 'command': 'blockdev-change-medium',
   'data': { 'device': 'str',
 'filename': 'str',
-'*format': 'str' } }
+'*format': 'str',
+'*read-only': 'BlockdevChangeReadOnlyMode' } }
 
 
 ##
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 1987a09..f14953a 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3855,7 +3855,7 @@ EQMP
 
 {
 .name   = blockdev-change-medium,
-.args_type  = device:B,filename:F,format:s?,
+.args_type  = device:B,filename:F,format:s?,read-only:s?,
 .mhandler.cmd_new = qmp_marshal_input_blockdev_change_medium,
 },
 
@@ -3871,6 +3871,8 @@ Arguments:
 - device: device name (json-string)
 - filename: filename of the new image (json-string)
 - format: format of the new image (json-string, optional)
+- read-only: new read-only mode (json-string, optional)
+  - Possible values: retain (default), ro, rw
 
 Examples:
 
@@ -3882,6 +3884,26 @@ Examples:
 format: raw } }
 - { return: {} }
 
+2. Load a read-only medium into a writable drive
+
+- { execute: blockdev-change-medium,
+ arguments: { device: isa-fd0,
+filename: /srv/images/ro.img,
+format: raw,
+read-only: retain } }
+
+- { error:
+ { class: GenericError,
+   desc: Could not open '/srv/images/ro.img': Permission denied } }
+
+- { execute: blockdev-change-medium,
+ arguments: { device: isa-fd0,
+ 

[Qemu-devel] [PATCH v3 06/14] qemu-img: Use blk_new_open() in img_rebase()

2015-01-26 Thread Max Reitz
Signed-off-by: Max Reitz mre...@redhat.com
---
 qemu-img.c | 57 -
 1 file changed, 24 insertions(+), 33 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index be1953d..0b23c87 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -2430,7 +2430,6 @@ static int img_rebase(int argc, char **argv)
 {
 BlockBackend *blk = NULL, *blk_old_backing = NULL, *blk_new_backing = NULL;
 BlockDriverState *bs = NULL, *bs_old_backing = NULL, *bs_new_backing = 
NULL;
-BlockDriver *old_backing_drv, *new_backing_drv;
 char *filename;
 const char *fmt, *cache, *src_cache, *out_basefmt, *out_baseimg;
 int c, flags, src_flags, ret;
@@ -2524,54 +2523,46 @@ static int img_rebase(int argc, char **argv)
 }
 bs = blk_bs(blk);
 
-/* Find the right drivers for the backing files */
-old_backing_drv = NULL;
-new_backing_drv = NULL;
-
-if (!unsafe  bs-backing_format[0] != '\0') {
-old_backing_drv = bdrv_find_format(bs-backing_format);
-if (old_backing_drv == NULL) {
-error_report(Invalid format name: '%s', bs-backing_format);
-ret = -1;
-goto out;
-}
-}
-
-if (out_basefmt != NULL) {
-new_backing_drv = bdrv_find_format(out_basefmt);
-if (new_backing_drv == NULL) {
-error_report(Invalid format name: '%s', out_basefmt);
-ret = -1;
-goto out;
-}
-}
-
 /* For safe rebasing we need to compare old and new backing file */
 if (!unsafe) {
 char backing_name[PATH_MAX];
+QDict *options = NULL;
+
+if (!unsafe  bs-backing_format[0] != '\0') {
+options = qdict_new();
+qdict_put_obj(options, driver,
+  QOBJECT(qstring_from_str(bs-backing_format)));
+}
 
-blk_old_backing = blk_new_with_bs(old_backing, error_abort);
-bs_old_backing = blk_bs(blk_old_backing);
 bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
-ret = bdrv_open(bs_old_backing, backing_name, NULL, NULL, src_flags,
-old_backing_drv, local_err);
-if (ret) {
+blk_old_backing = blk_new_open(old_backing, backing_name, NULL,
+   options, src_flags, local_err);
+if (!blk_old_backing) {
 error_report(Could not open old backing file '%s': %s,
  backing_name, error_get_pretty(local_err));
 error_free(local_err);
 goto out;
 }
+bs_old_backing = blk_bs(blk_old_backing);
+
 if (out_baseimg[0]) {
-blk_new_backing = blk_new_with_bs(new_backing, error_abort);
-bs_new_backing = blk_bs(blk_new_backing);
-ret = bdrv_open(bs_new_backing, out_baseimg, NULL, NULL, 
src_flags,
-new_backing_drv, local_err);
-if (ret) {
+if (out_basefmt) {
+options = qdict_new();
+qdict_put_obj(options, driver,
+  QOBJECT(qstring_from_str(out_basefmt)));
+} else {
+options = NULL;
+}
+
+blk_new_backing = blk_new_open(new_backing, out_baseimg, NULL,
+   options, src_flags, local_err);
+if (!blk_new_backing) {
 error_report(Could not open new backing file '%s': %s,
  out_baseimg, error_get_pretty(local_err));
 error_free(local_err);
 goto out;
 }
+bs_new_backing = blk_bs(blk_new_backing);
 }
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH v3 00/14] block: Remove growable, add blk_new_open()

2015-01-26 Thread Max Reitz
This series removes the growable field from the BlockDriverState
object. Its use was to clamp guest requests against the limits of the
BDS; however, this can now be done more easily by moving those checks
into the BlockBackend functions.

In a future series, growable may be reintroduced (maybe with a
different name); it will then signify whether a BDS is able to grow (in
contrast to the current growable, which signifies whether it is
allowed to). Maybe I will add it to the BlockDriver instead of the BDS,
though.

To be able to remove that field, qemu-io needs to be converted to
BlockBackend, which is done by this series as well. While working on
that I decided to convert blk_new_with_bs()+bdrv_open() to
blk_new_open(). I was skeptical about that decision at first, but it
seems good now that I was able to replace nearly every blk_new_with_bs()
call by blk_new_open(). In a future series I may try to convert some
remaining bdrv_open() calls to blk_new_open() as well. (And, in fact, in
a future series I *will* replace the last remaining blk_new_with_bs()
outside of blk_new_open() by blk_new_open().)

Finally, the question needs to be asked: If, after this series, every
BDS is allowed to grow, are there any users which do not use BB, but
should still be disallowed from reading/writing beyond a BDS's limits?
The only users I could see were the block jobs. Some of them should
indeed be converted to BB; but none of them takes a user-supplied offset
or size, all work on the full BDS (or only on parts which have been
modified, etc.). Therefore, it is by design impossible for them to
exceed the BDS's limits, which makes making all BDS's growable safe.


v3:
- Rebased (onto Stefan's branch rebased onto master)
- Fixed patch 4 [Stefano]

v2:
- Rebased [Kevin]
- Patch 2: Added a TODO comment about removing @filename and @flags from
  blk_new_open() when possible [Kevin]


git-backport-diff against v2:

Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/14:[] [--] 'block: Lift some BDS functions to the BlockBackend'
002/14:[] [--] 'block: Add blk_new_open()'
003/14:[] [--] 'blockdev: Use blk_new_open() in blockdev_init()'
004/14:[0004] [FC] 'block/xen: Use blk_new_open() in blk_connect()'
005/14:[] [--] 'qemu-img: Use blk_new_open() in img_open()'
006/14:[] [-C] 'qemu-img: Use blk_new_open() in img_rebase()'
007/14:[] [-C] 'qemu-img: Use BlockBackend as far as possible'
008/14:[] [--] 'qemu-nbd: Use blk_new_open() in main()'
009/14:[] [--] 'qemu-io: Use blk_new_open() in openfile()'
010/14:[] [--] 'qemu-io: Remove growable option'
011/14:[] [--] 'qemu-io: Use BlockBackend'
012/14:[] [--] 'block: Clamp BlockBackend requests'
013/14:[] [--] 'block: Remove growable from BDS'
014/14:[] [--] 'block: Keep bdrv_check*_request()'s return value'


git-backport-diff against v1:

Key:
[] : patches are identical
[] : number of functional differences between upstream/downstream patch
[down] : patch is downstream-only
The flags [FC] indicate (F)unctional and (C)ontextual differences, respectively

001/14:[] [--] 'block: Lift some BDS functions to the BlockBackend'
002/14:[0006] [FC] 'block: Add blk_new_open()'
003/14:[] [-C] 'blockdev: Use blk_new_open() in blockdev_init()'
004/14:[0004] [FC] 'block/xen: Use blk_new_open() in blk_connect()'
005/14:[] [--] 'qemu-img: Use blk_new_open() in img_open()'
006/14:[] [-C] 'qemu-img: Use blk_new_open() in img_rebase()'
007/14:[] [-C] 'qemu-img: Use BlockBackend as far as possible'
008/14:[] [--] 'qemu-nbd: Use blk_new_open() in main()'
009/14:[] [--] 'qemu-io: Use blk_new_open() in openfile()'
010/14:[0002] [FC] 'qemu-io: Remove growable option'
011/14:[] [--] 'qemu-io: Use BlockBackend'
012/14:[] [--] 'block: Clamp BlockBackend requests'
013/14:[] [--] 'block: Remove growable from BDS'
014/14:[] [--] 'block: Keep bdrv_check*_request()'s return value'


Max Reitz (14):
  block: Lift some BDS functions to the BlockBackend
  block: Add blk_new_open()
  blockdev: Use blk_new_open() in blockdev_init()
  block/xen: Use blk_new_open() in blk_connect()
  qemu-img: Use blk_new_open() in img_open()
  qemu-img: Use blk_new_open() in img_rebase()
  qemu-img: Use BlockBackend as far as possible
  qemu-nbd: Use blk_new_open() in main()
  qemu-io: Use blk_new_open() in openfile()
  qemu-io: Remove growable option
  qemu-io: Use BlockBackend
  block: Clamp BlockBackend requests
  block: Remove growable from BDS
  block: Keep bdrv_check*_request()'s return value

 block.c|  59 +-
 block/block-backend.c  | 219 +
 block/qcow2.c  |   6 --
 block/raw-posix.c  |   2 +-
 block/raw-win32.c  |   2 +-
 block/sheepdog.c   

[Qemu-devel] [PATCH v2 4/4] target-tricore: Add instructions of RRR opcode format

2015-01-26 Thread Bastian Koppelmann
Add microcode generator function gen_cond_sub.

Add helper functions:
* ixmax/ixmin: search for the max/min value and its related index in a
   vector of 16-bit values.
* pack: dack two data registers into an IEEE-754 single precision floating
point format number.
* dvadj: divide-adjust the result after dvstep instructions.
* dvstep: divide a reg by a divisor, producing 8-bits of quotient at a time.

OPCM_32_RRR_FLOAT - OPCM_32_RRR_DIVIDE

Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de
Reviewed-by: Richard Henderson r...@twiddle.net
---
 target-tricore/helper.h  |   8 ++
 target-tricore/op_helper.c   | 160 +++
 target-tricore/translate.c   | 150 
 target-tricore/tricore-opcodes.h |   2 +-
 4 files changed, 319 insertions(+), 1 deletion(-)

diff --git a/target-tricore/helper.h b/target-tricore/helper.h
index 068dc7b..7405fee 100644
--- a/target-tricore/helper.h
+++ b/target-tricore/helper.h
@@ -60,10 +60,14 @@ DEF_HELPER_FLAGS_2(max_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 DEF_HELPER_FLAGS_2(max_bu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 DEF_HELPER_FLAGS_2(max_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 DEF_HELPER_FLAGS_2(max_hu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
+DEF_HELPER_FLAGS_2(ixmax, TCG_CALL_NO_RWG_SE, i64, i64, i32)
+DEF_HELPER_FLAGS_2(ixmax_u, TCG_CALL_NO_RWG_SE, i64, i64, i32)
 DEF_HELPER_FLAGS_2(min_b, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 DEF_HELPER_FLAGS_2(min_bu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 DEF_HELPER_FLAGS_2(min_h, TCG_CALL_NO_RWG_SE, i32, i32, i32)
 DEF_HELPER_FLAGS_2(min_hu, TCG_CALL_NO_RWG_SE, i32, i32, i32)
+DEF_HELPER_FLAGS_2(ixmin, TCG_CALL_NO_RWG_SE, i64, i64, i32)
+DEF_HELPER_FLAGS_2(ixmin_u, TCG_CALL_NO_RWG_SE, i64, i64, i32)
 /* count leading ... */
 DEF_HELPER_FLAGS_1(clo, TCG_CALL_NO_RWG_SE, i32, i32)
 DEF_HELPER_FLAGS_1(clo_h, TCG_CALL_NO_RWG_SE, i32, i32)
@@ -81,12 +85,16 @@ DEF_HELPER_FLAGS_2(bmerge, TCG_CALL_NO_RWG_SE, i32, i32, 
i32)
 DEF_HELPER_FLAGS_1(bsplit, TCG_CALL_NO_RWG_SE, i64, i32)
 DEF_HELPER_FLAGS_1(parity, TCG_CALL_NO_RWG_SE, i32, i32)
 /* float */
+DEF_HELPER_FLAGS_4(pack, TCG_CALL_NO_RWG_SE, i32, i32, i32, i32, i32)
 DEF_HELPER_1(unpack, i64, i32)
 /* dvinit */
 DEF_HELPER_3(dvinit_b_13, i64, env, i32, i32)
 DEF_HELPER_3(dvinit_b_131, i64, env, i32, i32)
 DEF_HELPER_3(dvinit_h_13, i64, env, i32, i32)
 DEF_HELPER_3(dvinit_h_131, i64, env, i32, i32)
+DEF_HELPER_FLAGS_2(dvadj, TCG_CALL_NO_RWG_SE, i64, i64, i32)
+DEF_HELPER_FLAGS_2(dvstep, TCG_CALL_NO_RWG_SE, i64, i64, i32)
+DEF_HELPER_FLAGS_2(dvstep_u, TCG_CALL_NO_RWG_SE, i64, i64, i32)
 /* mulh */
 DEF_HELPER_FLAGS_5(mul_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
 DEF_HELPER_FLAGS_5(mulm_h, TCG_CALL_NO_RWG_SE, i64, i32, i32, i32, i32, i32)
diff --git a/target-tricore/op_helper.c b/target-tricore/op_helper.c
index 13e2729..7047b7c 100644
--- a/target-tricore/op_helper.c
+++ b/target-tricore/op_helper.c
@@ -867,6 +867,50 @@ uint32_t helper_##name ##_hu(target_ulong r1, target_ulong 
r2)\
   \
 return ret;   \
 } \
+  \
+uint64_t helper_ix##name(uint64_t r1, uint32_t r2)\
+{ \
+int64_t r2l, r2h, r1hl;   \
+uint64_t ret = 0; \
+  \
+ret = ((r1 + 2)  0x);\
+r2l = sextract64(r2, 0, 16);  \
+r2h = sextract64(r2, 16, 16); \
+r1hl = sextract64(r1, 32, 16);\
+  \
+if ((r2l op ## = r2h)  (r2l op r1hl)) { \
+ret |= (r2l  0x)  32;  \
+ret |= extract64(r1, 0, 16)  16;\
+} else if ((r2h op r2l)  (r2h op r1hl)) {   \
+ret |= extract64(r2, 16, 16)  32;   \
+ret |= extract64(r1 + 1, 0, 16)  16;\
+} else {  \
+ret |= r1  0xull;\
+} \
+return ret;   \
+} \
+  \
+uint64_t helper_ix##name ##_u(uint64_t r1, uint32_t r2)   \
+{ \
+int64_t r2l, r2h, r1hl;   \
+uint64_t ret = 0;   

Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()

2015-01-26 Thread Andrew Jones
On Mon, Jan 26, 2015 at 04:09:20PM +0100, Igor Mammedov wrote:
 On Mon, 26 Jan 2015 10:57:21 +0100
 Igor Mammedov imamm...@redhat.com wrote:
 
  On Sat, 24 Jan 2015 18:33:50 +0200
  Michael S. Tsirkin m...@redhat.com wrote:
  
   On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
On Fri, 23 Jan 2015 15:55:11 +0200
Michael S. Tsirkin m...@redhat.com wrote:

 [...]
I refuse to give up on cleaner and simpler API yet :)

 
 
 Your patches are almost there, they are pretty clean, the only issue I
 think is this passing of AcpiAml by value, sometimes freeing buffer in
 the process, sometimes not.
Currently buffer is allocated by API and is always freed whenever
it's passed to another API function.
That's why it makes user not to care about memory mgmt.

The only limitation of it is if you store AcpiAml return value into some
variable you are responsible to use it only once for passing to another 
API
function. Reusing this variable's value (pass it to API function second 
time)
would cause cause use-after-free and freeing-freed bugs.
Like this:
AcpiAml table = acpi_definition_block(SSDT,...);
AcpiAml scope = acpi_scope(PCI0);
aml_append(table, scope); // - here scope becomes invalid
// a bug
aml_append(table, scope); // use-after-free + freeing-freed bugs

There are several approaches to look for resolving above issues:
1. Adopt and use memory mgmt model used by GTK+
   in nutshell: 
http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
   In particular adopt behavior of GInitiallyUnowned usage model

   that will allow to keep convenient chained call style and if 
necessary
   reuse objects returned by API by explicitly referencing/dereferencing
   them if needed.
   
   Hmm, it's still easy to misuse. I think I prefer option 2 below.
  That's basically what we have/use in QOM with object_new(FOO) + 
  object_unref()
  I have no idea why we invented our own Object infrastructure
  when we could just use GObject one from already used glib.
  
   
2. It's possible to drop freeing inside API completely and
   record(store in list) every new object inside a table context.
   When table is constructed, list of created objects could be
   safely freed.
   With that it would be safe to reuse every AcpiAml object
   and avoid free-after-use issues with limitation that created
   AcpiAml objects shouldn't be used after table was closed.
   It should cover all practical use of API, i.e. no cross
   table AcpiAml objects.
   
   So each aml_alloc function gets pointer to this list,
   and adds the new element there.
   Eventually we do free_all to free all elements,
   so there isn't even an aml_free to mis-use.
  I'm thinking a little bit different about implementation though.
  I still don't like the use of explicit alloc/free being called
  by API user since it doesn't allow chained API calls and
  I think it's unnecessary complication see below why.
  
  Here is what's true about current API and a I'd like to with it:
  
1. Every API call (except aml_append) makes aml_alloc(), it's just
   like a wrapper about object_new(FOO). (current + new impl.)
  
2 Every API call that takes AML type as input argument
2.1 consumes (frees) it (current impl.)
(it's easy to fix use after free concern too,
 just pass AML by pointer and zero-out memory before it's freed
 and assert whenever one of input arguments is not correct,
 i.e. it was reused second time)
There is no need for following steps after this one.
2.2 takes ownership of GInitiallyUnowned and adds it to its list
of its children.
3. Free children when AML object is destroyed (i.e. ref count zero)
   That way when toplevel table object (definition block in 42/47)
   is added to ACPI blob we can unref it, which will cause
   its whole children tree freed, except for AML objects where
   API user explicitly took extra reference (i.e. wanted them
   to reuse in another table)
  
  I'd prefer:
   *  2.1 way to address your current concern of use-after-free
  as the most simplest one (no reuse is possible however)
  or
   * follow already used by QEMU QOM/GObject pattern of
 implicit alloc/free
  
  since they allow to construct AML in a more simple/manageable way i.e.
   
aml_append(method,
aml_store(aml_string(foo), aml_local(0)))
);
  
  v.s. explicit headache of alloc/free, which doesn't fix
   use-after-free anyway and just adds more boiler plate
   plus makes code har to read read
  
str = aml_alloc();
aml_string(str, foo);
loc0 = aml_alloc();
aml_local(loc0, 0);
store = aml_alloc();
aml_store(store, str, loc0);
aml_append(method, store);
aml_free(store);
aml_free(loc0);

[Qemu-devel] [PATCH 2/2] pc: memory: Validate alignment of maxram_size to page size

2015-01-26 Thread Peter Krempa
If the maxram_size is not aligned and dimm devices were added on the
command line qemu would terminate with a rather unhelpful message:

ERROR:hw/mem/pc-dimm.c:150:pc_dimm_get_free_addr: assertion failed:
(QEMU_ALIGN_UP(address_space_size, align) == address_space_size)

In case no dimm device was originally added on the commandline qemu
exits on the assertion failure.

Signed-off-by: Peter Krempa pkre...@redhat.com
---
 hw/i386/pc.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index e07f1fa..157eefe 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -1246,6 +1246,13 @@ FWCfgState *pc_memory_init(MachineState *machine,
 exit(EXIT_FAILURE);
 }

+if (QEMU_ALIGN_UP(machine-maxram_size,
+  TARGET_PAGE_SIZE) != machine-maxram_size) {
+error_report(maximum memory size must by aligned to multiple of 
+ %d bytes, TARGET_PAGE_SIZE);
+exit(EXIT_FAILURE);
+}
+
 pcms-hotplug_memory_base =
 ROUND_UP(0x1ULL + above_4g_mem_size, 1ULL  30);

-- 
2.2.1




Re: [Qemu-devel] [PATCH 1/2] hw/ppc/spapr.c Set default boot order

2015-01-26 Thread Alexander Graf

On 01/26/2015 01:57 PM, Dinar Valeev wrote:

On 01/26/2015 01:37 PM, Markus Armbruster wrote:

Dinar Valeev dval...@suse.de writes:


On 01/26/2015 10:11 AM, Markus Armbruster wrote:

dval...@suse.de writes:


From: Dinar Valeev dval...@suse.com

In order to use -boot once=X option we need to have default list
   where restore to on reset.


Really?  What happens without this patch?


qemu segfaults on reset.
0  reset-all  Segmentation fault


Next time, include a backtrace, please.

Ok, sorry for that.


Here's what I think happens.

Boot order comes from --boot parameter once, order, or else the machine
type's .default_boot_order.  The latter is null for you.

It gets passed via ppc_spapr_init() to spapr_create_fdt_skel(), which
sets qemu,boot-device in the FDT to it, but only when it isn't null.

If it comes from parameter once, we additionally register a reset
handler to switch it to parameter order or else .default_boot_order on
reset.  If you specify once, but not order, this is null for you.

On reset, reset handler restore_boot_order() runs.  Unlike
spapr_create_fdt_skel(), it doesn't check for null, and crashes in
validate_bootdevices().

Correct?

Yes

qemu_register_boot_set is implemented in PATCH 2/2. on reset 
boot_device is restored to NULL


For me, a null .default_boot_order means machine type does not support
boot order (this is how commit c165473 treats it).  Arguably, --boot
order and once should be rejected then.
AFICS SLOF handles qemu,boot-device as boot device, if nothing passed 
then it goes disk, cdrom, network. Which is the same as cdn list.


That's not entirely true. If SLOF doesn't see qemu,boot-device, it first 
goes via its NVRAM configured boot list and only if nothing is there it 
falls back to cdn.


Maybe the actual appropriate thing would be mcdn with m meaning NVRAM.


Alex




If I understand you correctly, your machine type does support boot
order.  Giving it a non-null .default_boot_order makes sense then.  The
appropriate value depends on firmware.  It could even be .

The null check in spapr_create_fdt_skel() looks superfluous then.
Consider dropping it.

Makes sense?








[Qemu-devel] [PATCH 0/2] pc: Fix startup with memory hotplug enabled

2015-01-26 Thread Peter Krempa
Tweak error messages to make sense and add check to verify that maxmem_size is
properly aligned right away rather than just crashing afterwards.

Peter Krempa (2):
  vl.c: Fix error messages when parsing maxmem parameters
  pc: memory: Validate alignment of maxram_size to page size

 hw/i386/pc.c |  7 +++
 vl.c | 22 +++---
 2 files changed, 14 insertions(+), 15 deletions(-)

-- 
2.2.1




Re: [Qemu-devel] [PATCH v2 0/4] target-arm: ARM64: Adding EL1 AARCH32 guest support

2015-01-26 Thread Greg Bellows
On Mon, Jan 26, 2015 at 5:03 AM, Christoffer Dall 
christoffer.d...@linaro.org wrote:

 On Wed, Jan 21, 2015 at 12:49:49PM -0600, Greg Bellows wrote:
  Added support for running an AArch32 guest on a AArch64 KVM host.
 Support has
  only been added to the QEMU machvirt machine.  The addition of CPU
 properties
  specifiable from the command line were added to allow disablement of
 AArch64
  execution state hereby forcing EL1 to be AArch32.  The new CPU command
 line
  property is aarch64=on/off that is specified as follows:
 
  aarch64-softmmu/qemu-system-aarch64 -M virt -cpu
 cortex-a57,aarch64=off ...
 

 This patch set seems to break standard aarch64 KVM guest functionality,
 I never see my guest progressing

 -Christoffer


​Hmm... sounds like something I need to debug.  I'll work with you on the
environment.


[Qemu-devel] [PATCH 32/50] blockdev: Check BB validity in eject and change

2015-01-26 Thread Max Reitz
Both commands will be reimplemented in a follow-up to this patch so this
does not need to be nice, it just has to work.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 35 +--
 1 file changed, 25 insertions(+), 10 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 7f4470f..f3091df 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1756,10 +1756,10 @@ static void eject_device(BlockBackend *blk, int force, 
Error **errp)
 BlockDriverState *bs = blk_bs(blk);
 AioContext *aio_context;
 
-aio_context = bdrv_get_aio_context(bs);
+aio_context = blk_get_aio_context(blk);
 aio_context_acquire(aio_context);
 
-if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
+if (bs  bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
 goto out;
 }
 if (!blk_dev_has_removable_media(blk)) {
@@ -1777,7 +1777,9 @@ static void eject_device(BlockBackend *blk, int force, 
Error **errp)
 }
 }
 
-bdrv_close(bs);
+if (bs) {
+bdrv_close(bs);
+}
 
 out:
 aio_context_release(aio_context);
@@ -1830,18 +1832,21 @@ out:
 }
 
 /* Assumes AioContext is held */
-static void qmp_bdrv_open_encrypted(BlockDriverState *bs, const char *filename,
+static void qmp_bdrv_open_encrypted(BlockDriverState **pbs,
+const char *filename,
 int bdrv_flags, BlockDriver *drv,
 const char *password, Error **errp)
 {
+BlockDriverState *bs;
 Error *local_err = NULL;
 int ret;
 
-ret = bdrv_open(bs, filename, NULL, NULL, bdrv_flags, drv, local_err);
+ret = bdrv_open(pbs, filename, NULL, NULL, bdrv_flags, drv, local_err);
 if (ret  0) {
 error_propagate(errp, local_err);
 return;
 }
+bs = *pbs;
 
 if (bdrv_key_required(bs)) {
 if (password) {
@@ -1865,6 +1870,7 @@ void qmp_change_blockdev(const char *device, const char 
*filename,
 AioContext *aio_context;
 BlockDriver *drv = NULL;
 int bdrv_flags;
+bool new_bs;
 Error *err = NULL;
 
 blk = blk_by_name(device);
@@ -1873,12 +1879,13 @@ void qmp_change_blockdev(const char *device, const char 
*filename,
 return;
 }
 bs = blk_bs(blk);
+new_bs = !bs;
 
-aio_context = bdrv_get_aio_context(bs);
+aio_context = blk_get_aio_context(blk);
 aio_context_acquire(aio_context);
 
 if (format) {
-drv = bdrv_find_whitelisted_format(format, bs-read_only);
+drv = bdrv_find_whitelisted_format(format, blk_is_read_only(blk));
 if (!drv) {
 error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
 goto out;
@@ -1891,10 +1898,18 @@ void qmp_change_blockdev(const char *device, const char 
*filename,
 goto out;
 }
 
-bdrv_flags = bdrv_is_read_only(bs) ? 0 : BDRV_O_RDWR;
-bdrv_flags |= bdrv_is_snapshot(bs) ? BDRV_O_SNAPSHOT : 0;
+bdrv_flags = blk_is_read_only(blk) ? 0 : BDRV_O_RDWR;
+bdrv_flags |= blk_get_root_state(blk)-open_flags  ~BDRV_O_RDWR;
 
-qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, errp);
+qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, err);
+if (err) {
+error_propagate(errp, err);
+} else if (new_bs) {
+blk_insert_bs(blk, bs);
+/* Has been sent automatically by bdrv_open() if blk_bs(blk) was not
+ * NULL */
+blk_dev_change_media_cb(blk, true);
+}
 
 out:
 aio_context_release(aio_context);
-- 
2.1.0




[Qemu-devel] [PATCH 19/50] blockdev: Use BlockBackend for blockdev-backup TA

2015-01-26 Thread Max Reitz
When preparing a blockdev-backup transaction, the BlockBackend should be
used because there may be no medium associated to the BB (which would
make bdrv_find() fail, whereas blk_by_name() does not).

This does not make a real difference because blockdev-backup will fail
without a medium anyway; however, it will have an impact on the error
returned (device not found vs. no medium).

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 17 ++---
 1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index c9e9ab9..ae1137f 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1562,27 +1562,27 @@ static void blockdev_backup_prepare(BlkTransactionState 
*common, Error **errp)
 {
 BlockdevBackupState *state = DO_UPCAST(BlockdevBackupState, common, 
common);
 BlockdevBackup *backup;
-BlockDriverState *bs, *target;
+BlockBackend *blk, *target;
 Error *local_err = NULL;
 
 assert(common-action-kind == TRANSACTION_ACTION_KIND_BLOCKDEV_BACKUP);
 backup = common-action-blockdev_backup;
 
-bs = bdrv_find(backup-device);
-if (!bs) {
+blk = blk_by_name(backup-device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, backup-device);
 return;
 }
 
-target = bdrv_find(backup-target);
+target = blk_by_name(backup-target);
 if (!target) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, backup-target);
 return;
 }
 
 /* AioContext is released in .clean() */
-state-aio_context = bdrv_get_aio_context(bs);
-if (state-aio_context != bdrv_get_aio_context(target)) {
+state-aio_context = blk_get_aio_context(blk);
+if (state-aio_context != blk_get_aio_context(target)) {
 state-aio_context = NULL;
 error_setg(errp, Backup between two IO threads is not implemented);
 return;
@@ -1600,7 +1600,10 @@ static void blockdev_backup_prepare(BlkTransactionState 
*common, Error **errp)
 return;
 }
 
-state-bs = bs;
+/* qmp_blockdev_backup() would have failed otherwise */
+assert(blk_bs(blk));
+
+state-bs = blk_bs(blk);
 state-job = state-bs-job;
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH 49/50] iotests: More options for VM.add_drive()

2015-01-26 Thread Max Reitz
This patch allows specifying the interface to be used for the drive, and
makes specifying a path optional (if the path is None, the file option
will be omitted, thus creating an empty drive).

Signed-off-by: Max Reitz mre...@redhat.com
---
 tests/qemu-iotests/iotests.py | 9 ++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
index 241b5ee..27b2490 100644
--- a/tests/qemu-iotests/iotests.py
+++ b/tests/qemu-iotests/iotests.py
@@ -94,13 +94,16 @@ class VM(object):
 self._args.append('-monitor')
 self._args.append(args)
 
-def add_drive(self, path, opts=''):
+def add_drive(self, path, opts='', interface='virtio'):
 '''Add a virtio-blk drive to the VM'''
-options = ['if=virtio',
+options = ['if=%s' % interface,
'format=%s' % imgfmt,
'cache=%s' % cachemode,
-   'file=%s' % path,
'id=drive%d' % self._num_drives]
+
+if not path is None:
+options.append('file=%s' % path)
+
 if opts:
 options.append(opts)
 
-- 
2.1.0




[Qemu-devel] [PATCH v2 1/1] dataplane: endianness-aware accesses

2015-01-26 Thread Cornelia Huck
The vring.c code currently assumes that guest and host endianness match,
which is not true for a number of cases:

- emulating targets with a different endianness than the host
- bi-endian targets, where the correct endianness depends on the virtio
  device
- upcoming support for the virtio-1 standard mandates little-endian
  accesses even for big-endian targets and hosts

Make sure to use accessors that depend on the virtio device.

Note that dataplane now needs to be built per-target.

Cc: Stefan Hajnoczi stefa...@redhat.com
Cc: Paolo Bonzini pbonz...@redhat.com
Cc: Fam Zheng f...@redhat.com
Reviewed-by: David Gibson da...@gibson.dropbear.id.au
Tested-by: David Gibson da...@gibson.dropbear.id.au
Signed-off-by: Cornelia Huck cornelia.h...@de.ibm.com
---
 hw/block/dataplane/virtio-blk.c   |  4 +-
 hw/scsi/virtio-scsi-dataplane.c   |  2 +-
 hw/virtio/Makefile.objs   |  2 +-
 hw/virtio/dataplane/Makefile.objs |  2 +-
 hw/virtio/dataplane/vring.c   | 53 ---
 include/hw/virtio/dataplane/vring-accessors.h | 75 +++
 include/hw/virtio/dataplane/vring.h   | 14 +
 7 files changed, 117 insertions(+), 35 deletions(-)
 create mode 100644 include/hw/virtio/dataplane/vring-accessors.h

diff --git a/hw/block/dataplane/virtio-blk.c b/hw/block/dataplane/virtio-blk.c
index 39c5d71..7ae4e03 100644
--- a/hw/block/dataplane/virtio-blk.c
+++ b/hw/block/dataplane/virtio-blk.c
@@ -16,7 +16,9 @@
 #include qemu/iov.h
 #include qemu/thread.h
 #include qemu/error-report.h
+#include hw/virtio/virtio-access.h
 #include hw/virtio/dataplane/vring.h
+#include hw/virtio/dataplane/vring-accessors.h
 #include sysemu/block-backend.h
 #include hw/virtio/virtio-blk.h
 #include virtio-blk.h
@@ -75,7 +77,7 @@ static void complete_request_vring(VirtIOBlockReq *req, 
unsigned char status)
 VirtIOBlockDataPlane *s = req-dev-dataplane;
 stb_p(req-in-status, status);
 
-vring_push(req-dev-dataplane-vring, req-elem,
+vring_push(s-vdev, req-dev-dataplane-vring, req-elem,
req-qiov.size + sizeof(*req-in));
 
 /* Suppress notification to guest by BH and its scheduled
diff --git a/hw/scsi/virtio-scsi-dataplane.c b/hw/scsi/virtio-scsi-dataplane.c
index 03a1e8c..418d73b 100644
--- a/hw/scsi/virtio-scsi-dataplane.c
+++ b/hw/scsi/virtio-scsi-dataplane.c
@@ -94,7 +94,7 @@ void virtio_scsi_vring_push_notify(VirtIOSCSIReq *req)
 {
 VirtIODevice *vdev = VIRTIO_DEVICE(req-vring-parent);
 
-vring_push(req-vring-vring, req-elem,
+vring_push(vdev, req-vring-vring, req-elem,
req-qsgl.size + req-resp_iov.size);
 
 if (vring_should_notify(vdev, req-vring-vring)) {
diff --git a/hw/virtio/Makefile.objs b/hw/virtio/Makefile.objs
index d21c397..19b224a 100644
--- a/hw/virtio/Makefile.objs
+++ b/hw/virtio/Makefile.objs
@@ -2,7 +2,7 @@ common-obj-y += virtio-rng.o
 common-obj-$(CONFIG_VIRTIO_PCI) += virtio-pci.o
 common-obj-y += virtio-bus.o
 common-obj-y += virtio-mmio.o
-common-obj-$(CONFIG_VIRTIO) += dataplane/
+obj-$(CONFIG_VIRTIO) += dataplane/
 
 obj-y += virtio.o virtio-balloon.o 
 obj-$(CONFIG_LINUX) += vhost.o vhost-backend.o vhost-user.o
diff --git a/hw/virtio/dataplane/Makefile.objs 
b/hw/virtio/dataplane/Makefile.objs
index 9a8cfc0..753a9ca 100644
--- a/hw/virtio/dataplane/Makefile.objs
+++ b/hw/virtio/dataplane/Makefile.objs
@@ -1 +1 @@
-common-obj-y += vring.o
+obj-y += vring.o
diff --git a/hw/virtio/dataplane/vring.c b/hw/virtio/dataplane/vring.c
index 61f6d83..87d9121 100644
--- a/hw/virtio/dataplane/vring.c
+++ b/hw/virtio/dataplane/vring.c
@@ -18,7 +18,9 @@
 #include hw/hw.h
 #include exec/memory.h
 #include exec/address-spaces.h
+#include hw/virtio/virtio-access.h
 #include hw/virtio/dataplane/vring.h
+#include hw/virtio/dataplane/vring-accessors.h
 #include qemu/error-report.h
 
 /* vring_map can be coupled with vring_unmap or (if you still have the
@@ -83,7 +85,7 @@ bool vring_setup(Vring *vring, VirtIODevice *vdev, int n)
 vring_init(vring-vr, virtio_queue_get_num(vdev, n), vring_ptr, 4096);
 
 vring-last_avail_idx = virtio_queue_get_last_avail_idx(vdev, n);
-vring-last_used_idx = vring-vr.used-idx;
+vring-last_used_idx = vring_get_used_idx(vdev, vring);
 vring-signalled_used = 0;
 vring-signalled_used_valid = false;
 
@@ -104,7 +106,7 @@ void vring_teardown(Vring *vring, VirtIODevice *vdev, int n)
 void vring_disable_notification(VirtIODevice *vdev, Vring *vring)
 {
 if (!(vdev-guest_features  (1  VIRTIO_RING_F_EVENT_IDX))) {
-vring-vr.used-flags |= VRING_USED_F_NO_NOTIFY;
+vring_set_used_flags(vdev, vring, VRING_USED_F_NO_NOTIFY);
 }
 }
 
@@ -117,10 +119,10 @@ bool vring_enable_notification(VirtIODevice *vdev, Vring 
*vring)
 if (vdev-guest_features  (1  VIRTIO_RING_F_EVENT_IDX)) {
 vring_avail_event(vring-vr) = vring-vr.avail-idx;
 } else {
-vring-vr.used-flags = ~VRING_USED_F_NO_NOTIFY;
+ 

[Qemu-devel] [PATCH v2 0/1] dataplane vs. endianness

2015-01-26 Thread Cornelia Huck
Stefan:

Here's v2 of my endianness patch for dataplane, with the extraneous
vdev argument dropped from get_desc().

I orginally planned to send my virtio-1 patchset as well, but I haven't
found the time for it; therefore, I think this should be applied
independently.

David: I take it your r-b still holds?

Cornelia Huck (1):
  dataplane: endianness-aware accesses

 hw/block/dataplane/virtio-blk.c   |  4 +-
 hw/scsi/virtio-scsi-dataplane.c   |  2 +-
 hw/virtio/Makefile.objs   |  2 +-
 hw/virtio/dataplane/Makefile.objs |  2 +-
 hw/virtio/dataplane/vring.c   | 53 ---
 include/hw/virtio/dataplane/vring-accessors.h | 75 +++
 include/hw/virtio/dataplane/vring.h   | 14 +
 7 files changed, 117 insertions(+), 35 deletions(-)
 create mode 100644 include/hw/virtio/dataplane/vring-accessors.h

-- 
2.1.4




[Qemu-devel] [PATCH v3 10/14] qemu-io: Remove growable option

2015-01-26 Thread Max Reitz
Remove growable option from the open command and from the qemu-io
command line. qemu-io is about to be converted to BlockBackend which
will make sure that no request exceeds the image size, so the only way
to keep growable would be to use BlockBackend if it is not given and
to directly access the BDS if it is.

qemu-io is a debugging tool, therefore removing a rarely used option
will have only a very small impact, if any. There was only one
qemu-iotest which used the option; since it is not critical, this patch
just removes it.

Signed-off-by: Max Reitz mre...@redhat.com
---
 qemu-io.c  | 23 +++
 tests/qemu-iotests/016 | 73 --
 tests/qemu-iotests/016.out | 23 ---
 tests/qemu-iotests/group   |  1 -
 4 files changed, 4 insertions(+), 116 deletions(-)
 delete mode 100755 tests/qemu-iotests/016
 delete mode 100644 tests/qemu-iotests/016.out

diff --git a/qemu-io.c b/qemu-io.c
index 81f8f64..0237ecb 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -50,7 +50,7 @@ static const cmdinfo_t close_cmd = {
 .oneline= close the current open file,
 };
 
-static int openfile(char *name, int flags, int growable, QDict *opts)
+static int openfile(char *name, int flags, QDict *opts)
 {
 Error *local_err = NULL;
 
@@ -60,10 +60,6 @@ static int openfile(char *name, int flags, int growable, 
QDict *opts)
 return 1;
 }
 
-if (growable) {
-flags |= BDRV_O_PROTOCOL;
-}
-
 qemuio_blk = blk_new_open(hda, name, NULL, opts, flags, local_err);
 if (!qemuio_blk) {
 fprintf(stderr, %s: can't open%s%s: %s\n, progname,
@@ -90,7 +86,6 @@ static void open_help(void)
  -r, -- open file read-only\n
  -s, -- use snapshot file\n
  -n, -- disable host cache\n
- -g, -- allow file to grow (only applies to protocols)\n
  -o, -- options to be given to the block driver
 \n);
 }
@@ -123,7 +118,6 @@ static int open_f(BlockDriverState *bs, int argc, char 
**argv)
 {
 int flags = 0;
 int readonly = 0;
-int growable = 0;
 int c;
 QemuOpts *qopts;
 QDict *opts;
@@ -139,9 +133,6 @@ static int open_f(BlockDriverState *bs, int argc, char 
**argv)
 case 'r':
 readonly = 1;
 break;
-case 'g':
-growable = 1;
-break;
 case 'o':
 if (!qemu_opts_parse(empty_opts, optarg, 0)) {
 printf(could not parse option list -- %s\n, optarg);
@@ -164,9 +155,9 @@ static int open_f(BlockDriverState *bs, int argc, char 
**argv)
 qemu_opts_reset(empty_opts);
 
 if (optind == argc - 1) {
-return openfile(argv[optind], flags, growable, opts);
+return openfile(argv[optind], flags, opts);
 } else if (optind == argc) {
-return openfile(NULL, flags, growable, opts);
+return openfile(NULL, flags, opts);
 } else {
 QDECREF(opts);
 return qemuio_command_usage(open_cmd);
@@ -200,7 +191,6 @@ static void usage(const char *name)
   -r, --read-only  export read-only\n
   -s, --snapshot   use snapshot file\n
   -n, --nocachedisable host cache\n
-  -g, --growable   allow file to grow (only applies to protocols)\n
   -m, --misalign   misalign allocations for O_DIRECT\n
   -k, --native-aio use kernel AIO implementation (on Linux only)\n
   -t, --cache=MODE use the given cache mode for the image\n
@@ -359,7 +349,6 @@ static void reenable_tty_echo(void)
 int main(int argc, char **argv)
 {
 int readonly = 0;
-int growable = 0;
 const char *sopt = hVc:d:f:rsnmgkt:T:;
 const struct option lopt[] = {
 { help, 0, NULL, 'h' },
@@ -371,7 +360,6 @@ int main(int argc, char **argv)
 { snapshot, 0, NULL, 's' },
 { nocache, 0, NULL, 'n' },
 { misalign, 0, NULL, 'm' },
-{ growable, 0, NULL, 'g' },
 { native-aio, 0, NULL, 'k' },
 { discard, 1, NULL, 'd' },
 { cache, 1, NULL, 't' },
@@ -422,9 +410,6 @@ int main(int argc, char **argv)
 case 'm':
 qemuio_misalign = true;
 break;
-case 'g':
-growable = 1;
-break;
 case 'k':
 flags |= BDRV_O_NATIVE_AIO;
 break;
@@ -482,7 +467,7 @@ int main(int argc, char **argv)
 }
 
 if ((argc - optind) == 1) {
-openfile(argv[optind], flags, growable, opts);
+openfile(argv[optind], flags, opts);
 }
 command_loop();
 
diff --git a/tests/qemu-iotests/016 b/tests/qemu-iotests/016
deleted file mode 100755
index 52397aa..000
--- a/tests/qemu-iotests/016
+++ /dev/null
@@ -1,73 +0,0 @@
-#!/bin/bash
-#
-# Test I/O after EOF for growable images.
-#
-# Copyright (C) 2009 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.
-#

[Qemu-devel] [PATCH v3 04/14] block/xen: Use blk_new_open() in blk_connect()

2015-01-26 Thread Max Reitz
Signed-off-by: Max Reitz mre...@redhat.com
---
 hw/block/xen_disk.c | 28 
 1 file changed, 12 insertions(+), 16 deletions(-)

diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 21842a0..1b0257c 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -40,6 +40,8 @@
 #include xen_blkif.h
 #include sysemu/blockdev.h
 #include sysemu/block-backend.h
+#include qapi/qmp/qdict.h
+#include qapi/qmp/qstring.h
 
 /* - */
 
@@ -897,30 +899,24 @@ static int blk_connect(struct XenDevice *xendev)
 blkdev-dinfo = drive_get(IF_XEN, 0, index);
 if (!blkdev-dinfo) {
 Error *local_err = NULL;
-BlockBackend *blk;
-BlockDriver *drv;
-BlockDriverState *bs;
+QDict *options = NULL;
 
-/* setup via xenbus - create new block driver instance */
-xen_be_printf(blkdev-xendev, 2, create new bdrv (xenbus setup)\n);
-blk = blk_new_with_bs(blkdev-dev, NULL);
-if (!blk) {
-return -1;
+if (strcmp(blkdev-fileproto, unset)) {
+options = qdict_new();
+qdict_put_obj(options, driver,
+  QOBJECT(qstring_from_str(blkdev-fileproto)));
 }
-blkdev-blk = blk;
 
-bs = blk_bs(blk);
-drv = bdrv_find_whitelisted_format(blkdev-fileproto, readonly);
-if (bdrv_open(bs, blkdev-filename, NULL, NULL, qflags,
-  drv, local_err) != 0) {
+/* setup via xenbus - create new block driver instance */
+xen_be_printf(blkdev-xendev, 2, create new bdrv (xenbus setup)\n);
+blkdev-blk = blk_new_open(blkdev-dev, blkdev-filename, NULL, 
options,
+   qflags, local_err);
+if (!blkdev-blk) {
 xen_be_printf(blkdev-xendev, 0, error: %s\n,
   error_get_pretty(local_err));
 error_free(local_err);
-blk_unref(blk);
-blkdev-blk = NULL;
 return -1;
 }
-assert(bs == blk_bs(blk));
 } else {
 /* setup via qemu cmdline - already setup for us */
 xen_be_printf(blkdev-xendev, 2, get configured bdrv (cmdline 
setup)\n);
-- 
2.1.0




[Qemu-devel] [PATCH v3 13/14] block: Remove growable from BDS

2015-01-26 Thread Max Reitz
Now that request clamping is done in the BlockBackend, the growable
field can be removed from the BlockDriverState. All BDSs are now treated
as being growable (that is, they are allowed to grow; they are not
necessarily actually able to).

Signed-off-by: Max Reitz mre...@redhat.com
---
 block.c   | 24 +---
 block/qcow2.c |  6 --
 block/raw-posix.c |  2 +-
 block/raw-win32.c |  2 +-
 block/sheepdog.c  |  2 +-
 include/block/block_int.h |  3 ---
 6 files changed, 8 insertions(+), 31 deletions(-)

diff --git a/block.c b/block.c
index d45e4dd..356a857 100644
--- a/block.c
+++ b/block.c
@@ -970,7 +970,6 @@ static int bdrv_open_common(BlockDriverState *bs, 
BlockDriverState *file,
 bs-zero_beyond_eof = true;
 open_flags = bdrv_open_flags(bs, flags);
 bs-read_only = !(open_flags  BDRV_O_RDWR);
-bs-growable = !!(flags  BDRV_O_PROTOCOL);
 
 if (use_bdrv_whitelist  !bdrv_is_whitelisted(drv, bs-read_only)) {
 error_setg(errp,
@@ -1885,7 +1884,6 @@ void bdrv_close(BlockDriverState *bs)
 bs-encrypted = 0;
 bs-valid_key = 0;
 bs-sg = 0;
-bs-growable = 0;
 bs-zero_beyond_eof = false;
 QDECREF(bs-options);
 bs-options = NULL;
@@ -2645,25 +2643,13 @@ exit:
 static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
size_t size)
 {
-int64_t len;
-
 if (size  INT_MAX) {
 return -EIO;
 }
 
-if (!bdrv_is_inserted(bs))
+if (!bdrv_is_inserted(bs)) {
 return -ENOMEDIUM;
-
-if (bs-growable)
-return 0;
-
-len = bdrv_getlength(bs);
-
-if (offset  0)
-return -EIO;
-
-if ((offset  len) || (len - offset  size))
-return -EIO;
+}
 
 return 0;
 }
@@ -3045,10 +3031,10 @@ static int coroutine_fn 
bdrv_aligned_preadv(BlockDriverState *bs,
 }
 
 /* Forward the request to the BlockDriver */
-if (!(bs-zero_beyond_eof  bs-growable)) {
+if (!bs-zero_beyond_eof) {
 ret = drv-bdrv_co_readv(bs, sector_num, nb_sectors, qiov);
 } else {
-/* Read zeros after EOF of growable BDSes */
+/* Read zeros after EOF */
 int64_t total_sectors, max_nb_sectors;
 
 total_sectors = bdrv_nb_sectors(bs);
@@ -3328,7 +3314,7 @@ static int coroutine_fn 
bdrv_aligned_pwritev(BlockDriverState *bs,
 
 block_acct_highest_sector(bs-stats, sector_num, nb_sectors);
 
-if (bs-growable  ret = 0) {
+if (ret = 0) {
 bs-total_sectors = MAX(bs-total_sectors, sector_num + nb_sectors);
 }
 
diff --git a/block/qcow2.c b/block/qcow2.c
index dbaf016..2b31dac 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -2521,15 +2521,12 @@ static int qcow2_save_vmstate(BlockDriverState *bs, 
QEMUIOVector *qiov,
 {
 BDRVQcowState *s = bs-opaque;
 int64_t total_sectors = bs-total_sectors;
-int growable = bs-growable;
 bool zero_beyond_eof = bs-zero_beyond_eof;
 int ret;
 
 BLKDBG_EVENT(bs-file, BLKDBG_VMSTATE_SAVE);
-bs-growable = 1;
 bs-zero_beyond_eof = false;
 ret = bdrv_pwritev(bs, qcow2_vm_state_offset(s) + pos, qiov);
-bs-growable = growable;
 bs-zero_beyond_eof = zero_beyond_eof;
 
 /* bdrv_co_do_writev will have increased the total_sectors value to include
@@ -2544,15 +2541,12 @@ static int qcow2_load_vmstate(BlockDriverState *bs, 
uint8_t *buf,
   int64_t pos, int size)
 {
 BDRVQcowState *s = bs-opaque;
-int growable = bs-growable;
 bool zero_beyond_eof = bs-zero_beyond_eof;
 int ret;
 
 BLKDBG_EVENT(bs-file, BLKDBG_VMSTATE_LOAD);
-bs-growable = 1;
 bs-zero_beyond_eof = false;
 ret = bdrv_pread(bs, qcow2_vm_state_offset(s) + pos, buf, size);
-bs-growable = growable;
 bs-zero_beyond_eof = zero_beyond_eof;
 
 return ret;
diff --git a/block/raw-posix.c b/block/raw-posix.c
index e51293a..5debc72 100644
--- a/block/raw-posix.c
+++ b/block/raw-posix.c
@@ -984,7 +984,7 @@ static int aio_worker(void *arg)
 switch (aiocb-aio_type  QEMU_AIO_TYPE_MASK) {
 case QEMU_AIO_READ:
 ret = handle_aiocb_rw(aiocb);
-if (ret = 0  ret  aiocb-aio_nbytes  aiocb-bs-growable) {
+if (ret = 0  ret  aiocb-aio_nbytes) {
 iov_memset(aiocb-aio_iov, aiocb-aio_niov, ret,
   0, aiocb-aio_nbytes - ret);
 
diff --git a/block/raw-win32.c b/block/raw-win32.c
index 06243d7..dae5d2f 100644
--- a/block/raw-win32.c
+++ b/block/raw-win32.c
@@ -101,7 +101,7 @@ static int aio_worker(void *arg)
 switch (aiocb-aio_type  QEMU_AIO_TYPE_MASK) {
 case QEMU_AIO_READ:
 count = handle_aiocb_rw(aiocb);
-if (count  aiocb-aio_nbytes  aiocb-bs-growable) {
+if (count  aiocb-aio_nbytes) {
 /* A short read means that we have reached EOF. Pad the buffer
  * with zeros for bytes after EOF. */
 iov_memset(aiocb-aio_iov, aiocb-aio_niov, 

[Qemu-devel] [PATCH v3 02/14] block: Add blk_new_open()

2015-01-26 Thread Max Reitz
blk_new_with_bs() creates a BlockBackend with an empty BlockDriverState
attached to it. Empty BDSs are not nice, therefore add an alternative
function which combines blk_new_with_bs() with bdrv_open().

Note: In contrast to bdrv_open() which takes a BlockDriver parameter,
blk_new_open() does not take such a parameter. This is because
bdrv_open() opens a BlockDriverState, therefore it is naturally to be
able to set the BlockDriver for that BDS. The fact that bdrv_open() can
open more than a single BDS is merely some form of a byproduct.

blk_new_open() on the other hand is intended to be used to create a
whole tree of BlockDriverStates. Therefore, setting a single BlockDriver
does not make much sense. Instead, the drivers to be used for each of
the nodes must be configured through the options QDict; including the
driver of the root BDS.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/block-backend.c  | 34 ++
 include/sysemu/block-backend.h |  3 +++
 2 files changed, 37 insertions(+)

diff --git a/block/block-backend.c b/block/block-backend.c
index b359545..543edaa 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -91,6 +91,40 @@ BlockBackend *blk_new_with_bs(const char *name, Error **errp)
 return blk;
 }
 
+/*
+ * Calls blk_new_with_bs() and then calls bdrv_open() on the BlockDriverState.
+ *
+ * Just as with bdrv_open(), after having called this function the reference to
+ * @options belongs to the block layer (even on failure).
+ *
+ * TODO: Remove @filename and @flags; it should be possible to specify a whole
+ * BDS tree just by specifying the @options QDict (or @reference,
+ * alternatively). At the time of adding this function, this is not possible,
+ * though, so callers of this function have to be able to specify @filename and
+ * @flags.
+ */
+BlockBackend *blk_new_open(const char *name, const char *filename,
+   const char *reference, QDict *options, int flags,
+   Error **errp)
+{
+BlockBackend *blk;
+int ret;
+
+blk = blk_new_with_bs(name, errp);
+if (!blk) {
+QDECREF(options);
+return NULL;
+}
+
+ret = bdrv_open(blk-bs, filename, reference, options, flags, NULL, errp);
+if (ret  0) {
+blk_unref(blk);
+return NULL;
+}
+
+return blk;
+}
+
 static void blk_delete(BlockBackend *blk)
 {
 assert(!blk-refcnt);
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 38afa79..f39bb5c 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -62,6 +62,9 @@ typedef struct BlockDevOps {
 
 BlockBackend *blk_new(const char *name, Error **errp);
 BlockBackend *blk_new_with_bs(const char *name, Error **errp);
+BlockBackend *blk_new_open(const char *name, const char *filename,
+   const char *reference, QDict *options, int flags,
+   Error **errp);
 void blk_ref(BlockBackend *blk);
 void blk_unref(BlockBackend *blk);
 const char *blk_name(BlockBackend *blk);
-- 
2.1.0




[Qemu-devel] [PATCH 09/50] block: Move guest_block_size into BlockBackend

2015-01-26 Thread Max Reitz
guest_block_size is a guest device property so it should be moved into
the interface between block layer and guest devices, which is the
BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block.c   | 7 ---
 block/block-backend.c | 7 +--
 include/block/block.h | 1 -
 include/block/block_int.h | 3 ---
 4 files changed, 5 insertions(+), 13 deletions(-)

diff --git a/block.c b/block.c
index aff7682..eff92ca 100644
--- a/block.c
+++ b/block.c
@@ -965,7 +965,6 @@ static int bdrv_open_common(BlockDriverState *bs, 
BlockDriverState *file,
 }
 
 bs-open_flags = flags;
-bs-guest_block_size = 512;
 bs-request_alignment = 512;
 bs-zero_beyond_eof = true;
 open_flags = bdrv_open_flags(bs, flags);
@@ -2039,7 +2038,6 @@ static void bdrv_move_feature_fields(BlockDriverState 
*bs_dest,
 /* move some fields that need to stay attached to the device */
 
 /* dev info */
-bs_dest-guest_block_size   = bs_src-guest_block_size;
 bs_dest-copy_on_read   = bs_src-copy_on_read;
 
 bs_dest-enable_write_cache = bs_src-enable_write_cache;
@@ -5286,11 +5284,6 @@ BlockAIOCB *bdrv_aio_ioctl(BlockDriverState *bs,
 return NULL;
 }
 
-void bdrv_set_guest_block_size(BlockDriverState *bs, int align)
-{
-bs-guest_block_size = align;
-}
-
 void *qemu_blockalign(BlockDriverState *bs, size_t size)
 {
 return qemu_memalign(bdrv_opt_mem_align(bs), size);
diff --git a/block/block-backend.c b/block/block-backend.c
index 4a2428e..bf0fcc9 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -31,6 +31,9 @@ struct BlockBackend {
 /* TODO change to DeviceState when all users are qdevified */
 const BlockDevOps *dev_ops;
 void *dev_opaque;
+
+/* the block size for which the guest device expects atomicity */
+int guest_block_size;
 };
 
 typedef struct BlockBackendAIOCB {
@@ -334,7 +337,7 @@ void blk_detach_dev(BlockBackend *blk, void *dev)
 blk-dev = NULL;
 blk-dev_ops = NULL;
 blk-dev_opaque = NULL;
-bdrv_set_guest_block_size(blk-bs, 512);
+blk-guest_block_size = 512;
 blk_unref(blk);
 }
 
@@ -763,7 +766,7 @@ int blk_get_flags(BlockBackend *blk)
 
 void blk_set_guest_block_size(BlockBackend *blk, int align)
 {
-bdrv_set_guest_block_size(blk-bs, align);
+blk-guest_block_size = align;
 }
 
 void *blk_blockalign(BlockBackend *blk, size_t size)
diff --git a/include/block/block.h b/include/block/block.h
index 3082d2b..df656db 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -425,7 +425,6 @@ void bdrv_img_create(const char *filename, const char *fmt,
 /* Returns the alignment in bytes that is required so that no bounce buffer
  * is required throughout the stack */
 size_t bdrv_opt_mem_align(BlockDriverState *bs);
-void bdrv_set_guest_block_size(BlockDriverState *bs, int align);
 void *qemu_blockalign(BlockDriverState *bs, size_t size);
 void *qemu_blockalign0(BlockDriverState *bs, size_t size);
 void *qemu_try_blockalign(BlockDriverState *bs, size_t size);
diff --git a/include/block/block_int.h b/include/block/block_int.h
index b340e7e..c6ab73a 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -375,9 +375,6 @@ struct BlockDriverState {
 /* Alignment requirement for offset/length of I/O requests */
 unsigned int request_alignment;
 
-/* the block size for which the guest device expects atomicity */
-int guest_block_size;
-
 /* do we need to tell the quest if we have a volatile write cache? */
 int enable_write_cache;
 
-- 
2.1.0




[Qemu-devel] [PATCH 20/50] blockdev: Check blk_is_available() in sn-del-int-sync

2015-01-26 Thread Max Reitz
Check whether the BlockBackend is actually available at the start of
snapshot-delete-internal-sync.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 18 +-
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index ae1137f..858d181 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1096,18 +1096,23 @@ SnapshotInfo 
*qmp_blockdev_snapshot_delete_internal_sync(const char *device,
  const char *name,
  Error **errp)
 {
-BlockDriverState *bs = bdrv_find(device);
+BlockBackend *blk;
+BlockDriverState *bs;
 AioContext *aio_context;
 QEMUSnapshotInfo sn;
 Error *local_err = NULL;
 SnapshotInfo *info = NULL;
 int ret;
 
-if (!bs) {
+blk = blk_by_name(device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return NULL;
 }
 
+aio_context = blk_get_aio_context(blk);
+aio_context_acquire(aio_context);
+
 if (!has_id) {
 id = NULL;
 }
@@ -1118,11 +1123,14 @@ SnapshotInfo 
*qmp_blockdev_snapshot_delete_internal_sync(const char *device,
 
 if (!id  !name) {
 error_setg(errp, Name or id must be provided);
-return NULL;
+goto out_aio_context;
 }
 
-aio_context = bdrv_get_aio_context(bs);
-aio_context_acquire(aio_context);
+if (!blk_is_available(blk)) {
+error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+goto out_aio_context;
+}
+bs = blk_bs(blk);
 
 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT_DELETE, errp)) {
 goto out_aio_context;
-- 
2.1.0




[Qemu-devel] [PATCH 36/50] blockdev: Allow more options for BB-less BDS tree

2015-01-26 Thread Max Reitz
Most of the options which blockdev_init() parses for both the
BlockBackend and the root BDS are valid for just the root BDS as well
(e.g. read-only). This patch allows specifying these options even if not
creating a BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 156 ++---
 1 file changed, 150 insertions(+), 6 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index d573c5c..2f3ccb5 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -591,6 +591,61 @@ err_no_opts:
 return NULL;
 }
 
+static QemuOptsList qemu_root_bds_opts;
+
+/* Takes the ownership of bs_opts */
+static BlockDriverState *bds_tree_init(QDict *bs_opts, Error **errp)
+{
+BlockDriverState *bs;
+QemuOpts *opts;
+Error *local_error = NULL;
+ThrottleConfig cfg;
+BlockdevDetectZeroesOptions detect_zeroes;
+int ret;
+int bdrv_flags = 0;
+
+opts = qemu_opts_create(qemu_root_bds_opts, NULL, 1, errp);
+if (!opts) {
+goto fail;
+}
+
+qemu_opts_absorb_qdict(opts, bs_opts, local_error);
+if (local_error) {
+error_propagate(errp, local_error);
+goto fail;
+}
+
+extract_common_blockdev_options(opts, bdrv_flags, cfg, detect_zeroes,
+local_error);
+if (local_error) {
+error_propagate(errp, local_error);
+goto fail;
+}
+
+bs = NULL;
+ret = bdrv_open(bs, NULL, NULL, bs_opts, bdrv_flags, NULL, errp);
+if (ret  0) {
+goto fail_no_bs_opts;
+}
+
+bs-detect_zeroes = detect_zeroes;
+
+/* disk I/O throttling */
+if (throttle_enabled(cfg)) {
+bdrv_io_limits_enable(bs);
+bdrv_set_io_limits(bs, cfg);
+}
+
+fail_no_bs_opts:
+qemu_opts_del(opts);
+return bs;
+
+fail:
+qemu_opts_del(opts);
+QDECREF(bs_opts);
+return NULL;
+}
+
 static void qemu_opt_rename(QemuOpts *opts, const char *from, const char *to,
 Error **errp)
 {
@@ -2994,12 +3049,8 @@ void qmp_blockdev_add(BlockdevOptions *options, Error 
**errp)
 
 bs = blk_bs(blk);
 } else {
-int ret;
-
-bs = NULL;
-ret = bdrv_open(bs, NULL, NULL, qdict, BDRV_O_RDWR | BDRV_O_CACHE_WB,
-NULL, errp);
-if (ret  0) {
+bs = bds_tree_init(qdict, errp);
+if (!bs) {
 goto fail;
 }
 }
@@ -3150,6 +3201,99 @@ QemuOptsList qemu_common_drive_opts = {
 },
 };
 
+static QemuOptsList qemu_root_bds_opts = {
+.name = root-bds,
+.head = QTAILQ_HEAD_INITIALIZER(qemu_common_drive_opts.head),
+.desc = {
+{
+.name = discard,
+.type = QEMU_OPT_STRING,
+.help = discard operation (ignore/off, unmap/on),
+},{
+.name = cache.writeback,
+.type = QEMU_OPT_BOOL,
+.help = enables writeback mode for any caches,
+},{
+.name = cache.direct,
+.type = QEMU_OPT_BOOL,
+.help = enables use of O_DIRECT (bypass the host page cache),
+},{
+.name = cache.no-flush,
+.type = QEMU_OPT_BOOL,
+.help = ignore any flush requests for the device,
+},{
+.name = aio,
+.type = QEMU_OPT_STRING,
+.help = host AIO implementation (threads, native),
+},{
+.name = read-only,
+.type = QEMU_OPT_BOOL,
+.help = open drive file as read-only,
+},{
+.name = throttling.iops-total,
+.type = QEMU_OPT_NUMBER,
+.help = limit total I/O operations per second,
+},{
+.name = throttling.iops-read,
+.type = QEMU_OPT_NUMBER,
+.help = limit read operations per second,
+},{
+.name = throttling.iops-write,
+.type = QEMU_OPT_NUMBER,
+.help = limit write operations per second,
+},{
+.name = throttling.bps-total,
+.type = QEMU_OPT_NUMBER,
+.help = limit total bytes per second,
+},{
+.name = throttling.bps-read,
+.type = QEMU_OPT_NUMBER,
+.help = limit read bytes per second,
+},{
+.name = throttling.bps-write,
+.type = QEMU_OPT_NUMBER,
+.help = limit write bytes per second,
+},{
+.name = throttling.iops-total-max,
+.type = QEMU_OPT_NUMBER,
+.help = I/O operations burst,
+},{
+.name = throttling.iops-read-max,
+.type = QEMU_OPT_NUMBER,
+.help = I/O operations read burst,
+},{
+.name = throttling.iops-write-max,
+.type = QEMU_OPT_NUMBER,
+.help = I/O operations write burst,
+},{
+.name = throttling.bps-total-max,
+.type = QEMU_OPT_NUMBER,
+.help = total bytes burst,
+},{
+  

[Qemu-devel] [PATCH 15/50] block: Fail requests to empty BlockBackend

2015-01-26 Thread Max Reitz
If there is no BlockDriverState in a BlockBackend or if the tray of the
guest device is open, fail all requests (where that is possible) with
-ENOMEDIUM.

The reason the status of the guest device is taken into account is
because once the guest device's tray is opened, any request on the same
BlockBackend as the guest uses should fail. If the BDS tree is supposed
to be usable even after ejecting it from the guest, a different
BlockBackend must be used.

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

diff --git a/block/block-backend.c b/block/block-backend.c
index 62be370..4f3122a 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -507,7 +507,7 @@ static int blk_check_byte_request(BlockBackend *blk, 
int64_t offset,
 return -EIO;
 }
 
-if (!blk_is_inserted(blk)) {
+if (!blk_is_available(blk)) {
 return -ENOMEDIUM;
 }
 
@@ -635,6 +635,10 @@ int blk_pwrite(BlockBackend *blk, int64_t offset, const 
void *buf, int count)
 
 int64_t blk_getlength(BlockBackend *blk)
 {
+if (!blk_is_available(blk)) {
+return -ENOMEDIUM;
+}
+
 return bdrv_getlength(blk-bs);
 }
 
@@ -670,6 +674,10 @@ BlockAIOCB *blk_aio_writev(BlockBackend *blk, int64_t 
sector_num,
 BlockAIOCB *blk_aio_flush(BlockBackend *blk,
   BlockCompletionFunc *cb, void *opaque)
 {
+if (!blk_is_available(blk)) {
+return abort_aio_request(blk, cb, opaque, -ENOMEDIUM);
+}
+
 return bdrv_aio_flush(blk-bs, cb, opaque);
 }
 
@@ -711,12 +719,20 @@ int blk_aio_multiwrite(BlockBackend *blk, BlockRequest 
*reqs, int num_reqs)
 
 int blk_ioctl(BlockBackend *blk, unsigned long int req, void *buf)
 {
+if (!blk_is_available(blk)) {
+return -ENOMEDIUM;
+}
+
 return bdrv_ioctl(blk-bs, req, buf);
 }
 
 BlockAIOCB *blk_aio_ioctl(BlockBackend *blk, unsigned long int req, void *buf,
   BlockCompletionFunc *cb, void *opaque)
 {
+if (!blk_is_available(blk)) {
+return abort_aio_request(blk, cb, opaque, -ENOMEDIUM);
+}
+
 return bdrv_aio_ioctl(blk-bs, req, buf, cb, opaque);
 }
 
@@ -732,11 +748,19 @@ int blk_co_discard(BlockBackend *blk, int64_t sector_num, 
int nb_sectors)
 
 int blk_co_flush(BlockBackend *blk)
 {
+if (!blk_is_available(blk)) {
+return -ENOMEDIUM;
+}
+
 return bdrv_co_flush(blk-bs);
 }
 
 int blk_flush(BlockBackend *blk)
 {
+if (!blk_is_available(blk)) {
+return -ENOMEDIUM;
+}
+
 return bdrv_flush(blk-bs);
 }
 
@@ -853,6 +877,11 @@ void blk_set_enable_write_cache(BlockBackend *blk, bool 
wce)
 
 void blk_invalidate_cache(BlockBackend *blk, Error **errp)
 {
+if (!blk-bs) {
+error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, blk-name);
+return;
+}
+
 bdrv_invalidate_cache(blk-bs, errp);
 }
 
@@ -1003,6 +1032,10 @@ int blk_write_compressed(BlockBackend *blk, int64_t 
sector_num,
 
 int blk_truncate(BlockBackend *blk, int64_t offset)
 {
+if (!blk_is_available(blk)) {
+return -ENOMEDIUM;
+}
+
 return bdrv_truncate(blk-bs, offset);
 }
 
@@ -1019,11 +1052,19 @@ int blk_discard(BlockBackend *blk, int64_t sector_num, 
int nb_sectors)
 int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
  int64_t pos, int size)
 {
+if (!blk_is_available(blk)) {
+return -ENOMEDIUM;
+}
+
 return bdrv_save_vmstate(blk-bs, buf, pos, size);
 }
 
 int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
 {
+if (!blk_is_available(blk)) {
+return -ENOMEDIUM;
+}
+
 return bdrv_load_vmstate(blk-bs, buf, pos, size);
 }
 
-- 
2.1.0




[Qemu-devel] [PATCH 45/50] qmp: Introduce blockdev-change-medium

2015-01-26 Thread Max Reitz
Introduce a new QMP command 'blockdev-change-medium' which is intended
to replace the 'change' command for block devices. The existing function
qmp_change_blockdev() is accordingly renamed to
qmp_blockdev_change_medium().

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c|  7 ---
 include/sysemu/blockdev.h |  2 --
 qapi-schema.json  |  3 ++-
 qapi/block-core.json  | 23 +++
 qmp-commands.hx   | 31 +++
 qmp.c |  2 +-
 6 files changed, 61 insertions(+), 7 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 6e440b8..2ada2b1 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2012,8 +2012,9 @@ void qmp_blockdev_insert_medium(const char *device, const 
char *node_name,
 qmp_blockdev_insert_anon_medium(device, bs, errp);
 }
 
-void qmp_change_blockdev(const char *device, const char *filename,
- const char *format, Error **errp)
+void qmp_blockdev_change_medium(const char *device, const char *filename,
+bool has_format, const char *format,
+Error **errp)
 {
 BlockBackend *blk;
 BlockBackendRootState *blk_rs;
@@ -2036,7 +2037,7 @@ void qmp_change_blockdev(const char *device, const char 
*filename,
 bdrv_flags = blk_rs-read_only ? 0 : BDRV_O_RDWR;
 bdrv_flags |= blk_rs-open_flags  ~BDRV_O_RDWR;
 
-if (format) {
+if (has_format) {
 drv = bdrv_find_whitelisted_format(format, bdrv_flags  BDRV_O_RDWR);
 if (!drv) {
 error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
diff --git a/include/sysemu/blockdev.h b/include/sysemu/blockdev.h
index 09d1e30..2a34332 100644
--- a/include/sysemu/blockdev.h
+++ b/include/sysemu/blockdev.h
@@ -65,8 +65,6 @@ DriveInfo *drive_new(QemuOpts *arg, BlockInterfaceType 
block_default_type);
 
 DriveInfo *add_init_drive(const char *opts);
 
-void qmp_change_blockdev(const char *device, const char *filename,
- const char *format, Error **errp);
 void do_commit(Monitor *mon, const QDict *qdict);
 int do_drive_del(Monitor *mon, const QDict *qdict, QObject **ret_data);
 #endif
diff --git a/qapi-schema.json b/qapi-schema.json
index e16f8eb..61867e1 100644
--- a/qapi-schema.json
+++ b/qapi-schema.json
@@ -1649,7 +1649,8 @@
 #  device between when these calls are executed is undefined.
 #
 # Notes:  It is strongly recommended that this interface is not used especially
-# for changing block devices.
+# for changing block devices.  Please use blockdev-change-medium
+# instead (for VNC, please use change-vnc-password).
 #
 # Since: 0.14.0
 ##
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ba41015..d3c3ca7 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1785,6 +1785,29 @@
 
 
 ##
+# @blockdev-change-medium:
+#
+# Changes the medium inserted into a block device by ejecting the current 
medium
+# and loading a new image file which is inserted as the new medium (this 
command
+# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium
+# and blockdev-close-tray).
+#
+# @device:  block device name
+#
+# @filename:filename of the new image to be loaded
+#
+# @format:  #optional, format to open the new image with (defaults to the
+#   probed format)
+#
+# Since: 2.3
+##
+{ 'command': 'blockdev-change-medium',
+  'data': { 'device': 'str',
+'filename': 'str',
+'*format': 'str' } }
+
+
+##
 # @BlockErrorAction
 #
 # An enumeration of action that has been taken when a DISK I/O occurs
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 604d638..1987a09 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3854,6 +3854,37 @@ Example:
 EQMP
 
 {
+.name   = blockdev-change-medium,
+.args_type  = device:B,filename:F,format:s?,
+.mhandler.cmd_new = qmp_marshal_input_blockdev_change_medium,
+},
+
+SQMP
+blockdev-change-medium
+--
+
+Changes the medium inserted into a block device by ejecting the current medium
+and loading a new image file which is inserted as the new medium.
+
+Arguments:
+
+- device: device name (json-string)
+- filename: filename of the new image (json-string)
+- format: format of the new image (json-string, optional)
+
+Examples:
+
+1. Change a removable medium
+
+- { execute: blockdev-change-medium,
+ arguments: { device: ide1-cd0,
+filename: /srv/images/Fedora-12-x86_64-DVD.iso,
+format: raw } }
+- { return: {} }
+
+EQMP
+
+{
 .name   = query-memdev,
 .args_type  = ,
 .mhandler.cmd_new = qmp_marshal_input_query_memdev,
diff --git a/qmp.c b/qmp.c
index 635d001..1cfdb74 100644
--- a/qmp.c
+++ b/qmp.c
@@ -417,7 +417,7 @@ void qmp_change(const char *device, const char *target,
 if (strcmp(device, vnc) == 0) {
 

[Qemu-devel] [PATCH 28/50] blockdev: Check BB validity in drive-mirror

2015-01-26 Thread Max Reitz
Call blk_is_available() before using blk_bs() to obtain the root
BlockDriverState behind the BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index e335d06..4e12061 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2516,6 +2516,7 @@ void qmp_drive_mirror(const char *device, const char 
*target,
   bool has_on_target_error, BlockdevOnError 
on_target_error,
   Error **errp)
 {
+BlockBackend *blk;
 BlockDriverState *bs;
 BlockDriverState *source, *target_bs;
 AioContext *aio_context;
@@ -2555,19 +2556,20 @@ void qmp_drive_mirror(const char *device, const char 
*target,
 return;
 }
 
-bs = bdrv_find(device);
-if (!bs) {
+blk = blk_by_name(device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
 
-aio_context = bdrv_get_aio_context(bs);
+aio_context = blk_get_aio_context(blk);
 aio_context_acquire(aio_context);
 
-if (!bdrv_is_inserted(bs)) {
+if (!blk_is_available(blk)) {
 error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
 goto out;
 }
+bs = blk_bs(blk);
 
 if (!has_format) {
 format = mode == NEW_IMAGE_MODE_EXISTING ? NULL : bs-drv-format_name;
-- 
2.1.0




[Qemu-devel] [PATCH 43/50] blockdev: Implement change with basic operations

2015-01-26 Thread Max Reitz
Implement 'change' on block devices by calling blockdev-open-tray,
blockdev-remove-medium, blockdev-insert-medium (a variation of that
which does not need a node-name) and blockdev-close-tray.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 191 +++--
 1 file changed, 72 insertions(+), 119 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 0b204eb..6e440b8 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1828,41 +1828,6 @@ exit:
 }
 }
 
-
-static void eject_device(BlockBackend *blk, int force, Error **errp)
-{
-BlockDriverState *bs = blk_bs(blk);
-AioContext *aio_context;
-
-aio_context = blk_get_aio_context(blk);
-aio_context_acquire(aio_context);
-
-if (bs  bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
-goto out;
-}
-if (!blk_dev_has_removable_media(blk)) {
-error_setg(errp, Device '%s' is not removable,
-   bdrv_get_device_name(bs));
-goto out;
-}
-
-if (blk_dev_is_medium_locked(blk)  !blk_dev_is_tray_open(blk)) {
-blk_dev_eject_request(blk, force);
-if (!force) {
-error_setg(errp, Device '%s' is locked,
-   bdrv_get_device_name(bs));
-goto out;
-}
-}
-
-if (bs) {
-bdrv_close(bs);
-}
-
-out:
-aio_context_release(aio_context);
-}
-
 void qmp_eject(const char *device, bool has_force, bool force, Error **errp)
 {
 Error *local_err = NULL;
@@ -1909,90 +1874,6 @@ out:
 aio_context_release(aio_context);
 }
 
-/* Assumes AioContext is held */
-static void qmp_bdrv_open_encrypted(BlockDriverState **pbs,
-const char *filename,
-int bdrv_flags, BlockDriver *drv,
-const char *password, Error **errp)
-{
-BlockDriverState *bs;
-Error *local_err = NULL;
-int ret;
-
-ret = bdrv_open(pbs, filename, NULL, NULL, bdrv_flags, drv, local_err);
-if (ret  0) {
-error_propagate(errp, local_err);
-return;
-}
-bs = *pbs;
-
-if (bdrv_key_required(bs)) {
-if (password) {
-if (bdrv_set_key(bs, password)  0) {
-error_set(errp, QERR_INVALID_PASSWORD);
-}
-} else {
-error_set(errp, QERR_DEVICE_ENCRYPTED, bdrv_get_device_name(bs),
-  bdrv_get_encrypted_filename(bs));
-}
-} else if (password) {
-error_set(errp, QERR_DEVICE_NOT_ENCRYPTED, bdrv_get_device_name(bs));
-}
-}
-
-void qmp_change_blockdev(const char *device, const char *filename,
- const char *format, Error **errp)
-{
-BlockBackend *blk;
-BlockDriverState *bs;
-AioContext *aio_context;
-BlockDriver *drv = NULL;
-int bdrv_flags;
-bool new_bs;
-Error *err = NULL;
-
-blk = blk_by_name(device);
-if (!blk) {
-error_set(errp, QERR_DEVICE_NOT_FOUND, device);
-return;
-}
-bs = blk_bs(blk);
-new_bs = !bs;
-
-aio_context = blk_get_aio_context(blk);
-aio_context_acquire(aio_context);
-
-if (format) {
-drv = bdrv_find_whitelisted_format(format, blk_is_read_only(blk));
-if (!drv) {
-error_set(errp, QERR_INVALID_BLOCK_FORMAT, format);
-goto out;
-}
-}
-
-eject_device(blk, 0, err);
-if (err) {
-error_propagate(errp, err);
-goto out;
-}
-
-bdrv_flags = blk_is_read_only(blk) ? 0 : BDRV_O_RDWR;
-bdrv_flags |= blk_get_root_state(blk)-open_flags  ~BDRV_O_RDWR;
-
-qmp_bdrv_open_encrypted(bs, filename, bdrv_flags, drv, NULL, err);
-if (err) {
-error_propagate(errp, err);
-} else if (new_bs) {
-blk_insert_bs(blk, bs);
-/* Has been sent automatically by bdrv_open() if blk_bs(blk) was not
- * NULL */
-blk_dev_change_media_cb(blk, true);
-}
-
-out:
-aio_context_release(aio_context);
-}
-
 void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
 Error **errp)
 {
@@ -2131,6 +2012,78 @@ void qmp_blockdev_insert_medium(const char *device, 
const char *node_name,
 qmp_blockdev_insert_anon_medium(device, bs, errp);
 }
 
+void qmp_change_blockdev(const char *device, const char *filename,
+ const char *format, Error **errp)
+{
+BlockBackend *blk;
+BlockBackendRootState *blk_rs;
+BlockDriverState *medium_bs;
+BlockDriver *drv = NULL;
+int bdrv_flags, ret;
+Error *err = NULL;
+
+blk = blk_by_name(device);
+if (!blk) {
+error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+return;
+}
+
+if (blk_bs(blk)) {
+blk_update_root_state(blk);
+}
+
+blk_rs = blk_get_root_state(blk);
+bdrv_flags = blk_rs-read_only ? 0 : BDRV_O_RDWR;
+bdrv_flags |= blk_rs-open_flags  ~BDRV_O_RDWR;
+
+if (format) {
+drv = 

[Qemu-devel] [PATCH 38/50] blockdev: Add blockdev-open-tray

2015-01-26 Thread Max Reitz
Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c   | 48 
 qapi/block-core.json | 21 +
 qmp-commands.hx  | 37 +
 3 files changed, 106 insertions(+)

diff --git a/blockdev.c b/blockdev.c
index 2f3ccb5..a0b9f17 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1993,6 +1993,54 @@ out:
 aio_context_release(aio_context);
 }
 
+void qmp_blockdev_open_tray(const char *device, bool has_force, bool force,
+Error **errp)
+{
+BlockBackend *blk;
+BlockDriverState *bs;
+AioContext *aio_context = NULL;
+
+if (!has_force) {
+force = false;
+}
+
+blk = blk_by_name(device);
+if (!blk) {
+error_set(errp, QERR_DEVICE_NOT_FOUND, device);
+return;
+}
+
+if (!blk_dev_has_removable_media(blk)) {
+error_setg(errp, Device '%s' is not removable, device);
+return;
+}
+
+if (blk_dev_is_tray_open(blk)) {
+return;
+}
+
+bs = blk_bs(blk);
+if (bs) {
+aio_context = bdrv_get_aio_context(bs);
+aio_context_acquire(aio_context);
+
+if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_EJECT, errp)) {
+goto out;
+}
+}
+
+if (blk_dev_is_medium_locked(blk)) {
+blk_dev_eject_request(blk, force);
+} else {
+blk_dev_change_media_cb(blk, false);
+}
+
+out:
+if (aio_context) {
+aio_context_release(aio_context);
+}
+}
+
 /* throttling disk I/O limits */
 void qmp_block_set_io_throttle(const char *device, int64_t bps, int64_t bps_rd,
int64_t bps_wr,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index ca9bc32..029f08b 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -1718,6 +1718,27 @@
 ##
 { 'command': 'blockdev-add', 'data': { 'options': 'BlockdevOptions' } }
 
+##
+# @blockdev-open-tray:
+#
+# Opens a block device's tray. If there is a block driver state tree inserted 
as
+# a medium, it will become inaccessible to the guest (but it will remain
+# associated to the block device, so closing the tray will make it accessible
+# again).
+#
+# @device: block device name
+#
+# @force:  #optional if false (the default), an eject request will be sent to
+#  the guest if it has locked the tray (and the tray will not be opened
+#  immediately); if true, the tray will be opened regardless of whether
+#  it is locked
+#
+# Since: 2.3
+##
+{ 'command': 'blockdev-open-tray',
+  'data': { 'device': 'str',
+'*force': 'bool' } }
+
 
 ##
 # @BlockErrorAction
diff --git a/qmp-commands.hx b/qmp-commands.hx
index 7576c18..cfa1b98 100644
--- a/qmp-commands.hx
+++ b/qmp-commands.hx
@@ -3641,6 +3641,43 @@ Example (2):
 EQMP
 
 {
+.name   = blockdev-open-tray,
+.args_type  = device:s,force:b?,
+.mhandler.cmd_new = qmp_marshal_input_blockdev_open_tray,
+},
+
+SQMP
+blockdev-open-tray
+--
+
+Opens a block device's tray. If there is a block driver state tree inserted as 
a
+medium, it will become inaccessible to the guest (but it will remain associated
+to the block device, so closing the tray will make it accessible again).
+
+Arguments:
+
+- device: block device name (json-string)
+- force: if false (the default), an eject request will be sent to the guest 
if
+   it has locked the tray (and the tray will not be opened 
immediately);
+   if true, the tray will be opened regardless of whether it is locked
+   (json-bool, optional)
+
+Example (1):
+
+- { execute: blockdev-open-tray,
+ arguments: { device: ide1-cd0 } }
+
+- { timestamp: { seconds: 1418751016,
+microseconds: 716996 },
+ event: DEVICE_TRAY_MOVED,
+ data: { device: ide1-cd0,
+   tray-open: true } }
+
+- { return: {} }
+
+EQMP
+
+{
 .name   = query-named-block-nodes,
 .args_type  = ,
 .mhandler.cmd_new = qmp_marshal_input_query_named_block_nodes,
-- 
2.1.0




[Qemu-devel] [PATCH v2 1/2] target-s390x: Mark check_privileged() as !CONFIG_USER_ONLY

2015-01-26 Thread Peter Maydell
The function check_privileged() is only used in the softmmu configs;
wrap it in an #ifndef CONFIG_USER_ONLY to avoid clang warnings on the
linux-user builds.

Signed-off-by: Peter Maydell peter.mayd...@linaro.org
Reviewed-by: Stefan Weil s...@weilnetz.de
Message-id: 1419373100-17690-2-git-send-email-peter.mayd...@linaro.org
---
 target-s390x/translate.c | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/target-s390x/translate.c b/target-s390x/translate.c
index ab01bc0..1c3a8e8 100644
--- a/target-s390x/translate.c
+++ b/target-s390x/translate.c
@@ -317,12 +317,14 @@ static inline void gen_illegal_opcode(DisasContext *s)
 gen_program_exception(s, PGM_SPECIFICATION);
 }
 
+#ifndef CONFIG_USER_ONLY
 static inline void check_privileged(DisasContext *s)
 {
 if (s-tb-flags  (PSW_MASK_PSTATE  32)) {
 gen_program_exception(s, PGM_PRIVILEGED);
 }
 }
+#endif
 
 static TCGv_i64 get_address(DisasContext *s, int x2, int b2, int d2)
 {
-- 
1.9.1




[Qemu-devel] [PATCH] target-mips: use CP0EnLo_XI instead of magic number

2015-01-26 Thread Leon Alrae
Signed-off-by: Leon Alrae leon.al...@imgtec.com
---
 target-mips/translate.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index 635192c..77d89be 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -4947,7 +4947,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int 
reg, int sel)
 #if defined(TARGET_MIPS64)
 if (ctx-rxi) {
 TCGv tmp = tcg_temp_new();
-tcg_gen_andi_tl(tmp, arg, (3ull  62));
+tcg_gen_andi_tl(tmp, arg, (3ull  CP0EnLo_XI));
 tcg_gen_shri_tl(tmp, tmp, 32);
 tcg_gen_or_tl(arg, arg, tmp);
 tcg_temp_free(tmp);
@@ -5002,7 +5002,7 @@ static void gen_mfc0(DisasContext *ctx, TCGv arg, int 
reg, int sel)
 #if defined(TARGET_MIPS64)
 if (ctx-rxi) {
 TCGv tmp = tcg_temp_new();
-tcg_gen_andi_tl(tmp, arg, (3ull  62));
+tcg_gen_andi_tl(tmp, arg, (3ull  CP0EnLo_XI));
 tcg_gen_shri_tl(tmp, tmp, 32);
 tcg_gen_or_tl(arg, arg, tmp);
 tcg_temp_free(tmp);
-- 
2.1.0




[Qemu-devel] [PATCH v3 07/14] qemu-img: Use BlockBackend as far as possible

2015-01-26 Thread Max Reitz
Although qemu-img already creates BlockBackends, it does not do accesses
to the images through them. This patch converts all of the bdrv_* calls
for which this is currently possible to blk_* calls. Most of the
remaining calls will probably stay bdrv_* calls because they really do
operate on the BDS level instead of the BB level.

Signed-off-by: Max Reitz mre...@redhat.com
---
 qemu-img.c | 98 ++
 1 file changed, 54 insertions(+), 44 deletions(-)

diff --git a/qemu-img.c b/qemu-img.c
index 0b23c87..8b4139e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -1008,19 +1008,19 @@ static int64_t sectors_to_process(int64_t total, 
int64_t from)
  * Returns 0 in case sectors are filled with 0, 1 if sectors contain non-zero
  * data and negative value on error.
  *
- * @param bs:  Driver used for accessing file
+ * @param blk:  BlockBackend for the image
  * @param sect_num: Number of first sector to check
  * @param sect_count: Number of sectors to check
  * @param filename: Name of disk file we are checking (logging purpose)
  * @param buffer: Allocated buffer for storing read data
  * @param quiet: Flag for quiet mode
  */
-static int check_empty_sectors(BlockDriverState *bs, int64_t sect_num,
+static int check_empty_sectors(BlockBackend *blk, int64_t sect_num,
int sect_count, const char *filename,
uint8_t *buffer, bool quiet)
 {
 int pnum, ret = 0;
-ret = bdrv_read(bs, sect_num, buffer, sect_count);
+ret = blk_read(blk, sect_num, buffer, sect_count);
 if (ret  0) {
 error_report(Error while reading offset % PRId64  of %s: %s,
  sectors_to_bytes(sect_num), filename, strerror(-ret));
@@ -1130,22 +1130,26 @@ static int img_compare(int argc, char **argv)
 }
 bs2 = blk_bs(blk2);
 
-buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
-buf2 = qemu_blockalign(bs2, IO_BUF_SIZE);
-total_sectors1 = bdrv_nb_sectors(bs1);
+buf1 = blk_blockalign(blk1, IO_BUF_SIZE);
+buf2 = blk_blockalign(blk2, IO_BUF_SIZE);
+total_sectors1 = blk_getlength(blk1);
 if (total_sectors1  0) {
 error_report(Can't get size of %s: %s,
  filename1, strerror(-total_sectors1));
 ret = 4;
 goto out;
 }
-total_sectors2 = bdrv_nb_sectors(bs2);
+total_sectors2 = blk_getlength(blk2);
 if (total_sectors2  0) {
 error_report(Can't get size of %s: %s,
  filename2, strerror(-total_sectors2));
 ret = 4;
 goto out;
 }
+
+total_sectors1 /= BDRV_SECTOR_SIZE;
+total_sectors2 /= BDRV_SECTOR_SIZE;
+
 total_sectors = MIN(total_sectors1, total_sectors2);
 progress_base = MAX(total_sectors1, total_sectors2);
 
@@ -1181,7 +1185,7 @@ static int img_compare(int argc, char **argv)
 
 if (allocated1 == allocated2) {
 if (allocated1) {
-ret = bdrv_read(bs1, sector_num, buf1, nb_sectors);
+ret = blk_read(blk1, sector_num, buf1, nb_sectors);
 if (ret  0) {
 error_report(Error while reading offset % PRId64  of 
%s:
   %s, sectors_to_bytes(sector_num), 
filename1,
@@ -1189,7 +1193,7 @@ static int img_compare(int argc, char **argv)
 ret = 4;
 goto out;
 }
-ret = bdrv_read(bs2, sector_num, buf2, nb_sectors);
+ret = blk_read(blk2, sector_num, buf2, nb_sectors);
 if (ret  0) {
 error_report(Error while reading offset % PRId64
   of %s: %s, sectors_to_bytes(sector_num),
@@ -1216,10 +1220,10 @@ static int img_compare(int argc, char **argv)
 }
 
 if (allocated1) {
-ret = check_empty_sectors(bs1, sector_num, nb_sectors,
+ret = check_empty_sectors(blk1, sector_num, nb_sectors,
   filename1, buf1, quiet);
 } else {
-ret = check_empty_sectors(bs2, sector_num, nb_sectors,
+ret = check_empty_sectors(blk2, sector_num, nb_sectors,
   filename2, buf1, quiet);
 }
 if (ret) {
@@ -1236,18 +1240,18 @@ static int img_compare(int argc, char **argv)
 }
 
 if (total_sectors1 != total_sectors2) {
-BlockDriverState *bs_over;
+BlockBackend *blk_over;
 int64_t total_sectors_over;
 const char *filename_over;
 
 qprintf(quiet, Warning: Image size mismatch!\n);
 if (total_sectors1  total_sectors2) {
 total_sectors_over = total_sectors1;
-bs_over = bs1;
+blk_over = blk1;
 filename_over = filename1;
 } else {
 total_sectors_over = total_sectors2;
-bs_over = bs2;
+blk_over = blk2;
   

Re: [Qemu-devel] [PATCH] linux-user/syscall.c: Let all lock_user_struct() and unlock_user_struct() paired with each other

2015-01-26 Thread Peter Maydell
On 26 January 2015 at 14:59, Chen Gang S gang.c...@sunrus.com.cn wrote:
 On 1/26/15 06:10, Peter Maydell wrote:
 I would just like the commit message to be clear about the
 scope of the work the patch covers. If the patch is just Fix
 mismatched lock/unlock calls in IPC struct conversion functions
 then that's fine, but the commit message should say that. At the
 moment the commit message is very vague.


 OK, thanks.

 I am not quite familiar with this file, so I describe the modification
 by function name, e.g. lock_user_struct() and unlick_user_struct() in
 the patch subject.

In a big file I think it's often more useful to describe the
functions which are being changed. My suggested subject would be:

Fix mismatched lock/unlock calls in IPC struct conversion functions

Riku can decide if he wants a v2 or will just fix it up as he
applies it to his linux-user tree.

-- PMM



[Qemu-devel] [PATCH v3 01/14] block: Lift some BDS functions to the BlockBackend

2015-01-26 Thread Max Reitz
Create the blk_* counterparts for the following bdrv_* functions (which
make sense to call on the BlockBackend level):
- bdrv_co_write_zeroes()
- bdrv_write_compressed()
- bdrv_truncate()
- bdrv_discard()
- bdrv_load_vmstate()
- bdrv_save_vmstate()

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/block-backend.c  | 33 +
 include/sysemu/block-backend.h |  9 +
 2 files changed, 42 insertions(+)

diff --git a/block/block-backend.c b/block/block-backend.c
index d00c129..b359545 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -663,3 +663,36 @@ void *blk_aio_get(const AIOCBInfo *aiocb_info, 
BlockBackend *blk,
 {
 return qemu_aio_get(aiocb_info, blk_bs(blk), cb, opaque);
 }
+
+int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num,
+ int nb_sectors, BdrvRequestFlags flags)
+{
+return bdrv_co_write_zeroes(blk-bs, sector_num, nb_sectors, flags);
+}
+
+int blk_write_compressed(BlockBackend *blk, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors)
+{
+return bdrv_write_compressed(blk-bs, sector_num, buf, nb_sectors);
+}
+
+int blk_truncate(BlockBackend *blk, int64_t offset)
+{
+return bdrv_truncate(blk-bs, offset);
+}
+
+int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
+{
+return bdrv_discard(blk-bs, sector_num, nb_sectors);
+}
+
+int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
+ int64_t pos, int size)
+{
+return bdrv_save_vmstate(blk-bs, buf, pos, size);
+}
+
+int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size)
+{
+return bdrv_load_vmstate(blk-bs, buf, pos, size);
+}
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 8871a02..38afa79 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -150,5 +150,14 @@ BlockAcctStats *blk_get_stats(BlockBackend *blk);
 
 void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
   BlockCompletionFunc *cb, void *opaque);
+int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t sector_num,
+ int nb_sectors, BdrvRequestFlags flags);
+int blk_write_compressed(BlockBackend *blk, int64_t sector_num,
+ const uint8_t *buf, int nb_sectors);
+int blk_truncate(BlockBackend *blk, int64_t offset);
+int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors);
+int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
+ int64_t pos, int size);
+int blk_load_vmstate(BlockBackend *blk, uint8_t *buf, int64_t pos, int size);
 
 #endif
-- 
2.1.0




[Qemu-devel] [PATCH v2 1/4] target-tricore: target-tricore: Add instructions of RR1 opcode format, that have 0x93 as first opcode

2015-01-26 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de
---
v1 - v2:
- now uses 3 helper functions (gen_mul_q, gen_mul_q_16, gen_mulr_q) to
  remove repetition.
- now uses 64 arithmetic instead of emulating it.
- now uses arithmetic shift, instead of normal shift + sign extend for arg
  extraction.

 target-tricore/translate.c | 182 +
 1 file changed, 182 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index def7f4a..804d181 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -987,6 +987,119 @@ static inline void gen_maddsui_32(TCGv ret, TCGv r1, TCGv 
r2, int32_t con)
 tcg_temp_free(temp);
 }

+static void
+gen_mul_q(TCGv rl, TCGv rh, TCGv arg1, TCGv arg2, uint32_t n, uint32_t 
up_shift)
+{
+TCGv temp = tcg_temp_new();
+TCGv_i64 temp_64 = tcg_temp_new_i64();
+TCGv_i64 temp2_64 = tcg_temp_new_i64();
+
+if (n == 0) {
+if ((up_shift == 32)) {
+tcg_gen_muls2_tl(rh, rl, arg1, arg2);
+} else if (up_shift == 16) {
+tcg_gen_ext_i32_i64(temp_64, arg1);
+tcg_gen_ext_i32_i64(temp2_64, arg2);
+
+tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
+tcg_gen_shri_i64(temp_64, temp_64, up_shift);
+tcg_gen_extr_i64_i32(rl, rh, temp_64);
+} else {
+tcg_gen_muls2_tl(rl, rh, arg1, arg2);
+}
+/* reset v bit */
+tcg_gen_movi_tl(cpu_PSW_V, 0);
+} else { /* n is exspected to be 1 */
+tcg_gen_ext_i32_i64(temp_64, arg1);
+tcg_gen_ext_i32_i64(temp2_64, arg2);
+
+tcg_gen_mul_i64(temp_64, temp_64, temp2_64);
+
+if (up_shift == 0) {
+tcg_gen_shli_i64(temp_64, temp_64, 1);
+} else {
+tcg_gen_shri_i64(temp_64, temp_64, up_shift - 1);
+}
+tcg_gen_extr_i64_i32(rl, rh, temp_64);
+/* overflow only occours if r1 = r2 = 0x8000 */
+if (up_shift == 0) {/* result is 64 bit */
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, rh,
+0x8000);
+} else { /* result is 32 bit */
+tcg_gen_setcondi_tl(TCG_COND_EQ, cpu_PSW_V, rl,
+0x8000);
+}
+tcg_gen_shli_tl(cpu_PSW_V, cpu_PSW_V, 31);
+/* calc sv overflow bit */
+tcg_gen_or_tl(cpu_PSW_SV, cpu_PSW_SV, cpu_PSW_V);
+}
+/* calc av overflow bit */
+if (up_shift == 0) {
+tcg_gen_add_tl(cpu_PSW_AV, rh, rh);
+tcg_gen_xor_tl(cpu_PSW_AV, rh, cpu_PSW_AV);
+} else {
+tcg_gen_add_tl(cpu_PSW_AV, rl, rl);
+tcg_gen_xor_tl(cpu_PSW_AV, rl, cpu_PSW_AV);
+}
+/* calc sav overflow bit */
+tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+tcg_temp_free(temp);
+tcg_temp_free_i64(temp_64);
+tcg_temp_free_i64(temp2_64);
+}
+
+static void
+gen_mul_q_16(TCGv ret, TCGv arg1, TCGv arg2, uint32_t n)
+{
+TCGv temp = tcg_temp_new();
+if (n == 0) {
+tcg_gen_mul_tl(ret, arg1, arg2);
+} else { /* n is exspected to be 1 */
+tcg_gen_mul_tl(ret, arg1, arg2);
+tcg_gen_shli_tl(ret, ret, 1);
+/* catch special case r1 = r2 = 0x8000 */
+tcg_gen_setcondi_tl(TCG_COND_EQ, temp, ret, 0x8000);
+tcg_gen_sub_tl(ret, ret, temp);
+}
+/* reset v bit */
+tcg_gen_movi_tl(cpu_PSW_V, 0);
+/* calc av overflow bit */
+tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+/* calc sav overflow bit */
+tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+
+tcg_temp_free(temp);
+}
+
+static void gen_mulr_q(TCGv ret, TCGv arg1, TCGv arg2, uint32_t n)
+{
+TCGv temp = tcg_temp_new();
+if (n == 0) {
+tcg_gen_mul_tl(ret, arg1, arg2);
+tcg_gen_addi_tl(ret, ret, 0x8000);
+} else {
+tcg_gen_mul_tl(ret, arg1, arg2);
+tcg_gen_shli_tl(ret, ret, 1);
+tcg_gen_addi_tl(ret, ret, 0x8000);
+/* catch special case r1 = r2 = 0x8000 */
+tcg_gen_setcondi_tl(TCG_COND_EQ, temp, ret, 0x80008000);
+tcg_gen_muli_tl(temp, temp, 0x8001);
+tcg_gen_sub_tl(ret, ret, temp);
+}
+/* reset v bit */
+tcg_gen_movi_tl(cpu_PSW_V, 0);
+/* calc av overflow bit */
+tcg_gen_add_tl(cpu_PSW_AV, ret, ret);
+tcg_gen_xor_tl(cpu_PSW_AV, ret, cpu_PSW_AV);
+/* calc sav overflow bit */
+tcg_gen_or_tl(cpu_PSW_SAV, cpu_PSW_SAV, cpu_PSW_AV);
+/* cut halfword off */
+tcg_gen_andi_tl(ret, ret, 0x);
+
+tcg_temp_free(temp);
+}
+
 static inline void
 gen_maddsi_64(TCGv ret_low, TCGv ret_high, TCGv r1, TCGv r2_low, TCGv r2_high,
   int32_t con)
@@ -4778,6 +4891,72 @@ static void decode_rr1_mul(CPUTriCoreState *env, 
DisasContext *ctx)
 tcg_temp_free(n);
 }

+static void decode_rr1_mulq(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+

[Qemu-devel] [PATCH v2 3/4] target-tricore: Add instructions of RRPW opcode format

2015-01-26 Thread Bastian Koppelmann
Signed-off-by: Bastian Koppelmann kbast...@mail.uni-paderborn.de
---
v1 - v2:
- optimize OPC2_32_RRPW_EXTR by using only two shifts, instead of four.
- OPC1_32_RRPW_DEXTR now has r1 == r2 as a special case.

 target-tricore/translate.c | 70 ++
 1 file changed, 70 insertions(+)

diff --git a/target-tricore/translate.c b/target-tricore/translate.c
index 8f9679e..aa70f61 100644
--- a/target-tricore/translate.c
+++ b/target-tricore/translate.c
@@ -4990,6 +4990,57 @@ static void decode_rr2_mul(CPUTriCoreState *env, 
DisasContext *ctx)
 }
 }

+/* RRPW format */
+static void decode_rrpw_extract_insert(CPUTriCoreState *env, DisasContext *ctx)
+{
+uint32_t op2;
+int r1, r2, r3;
+int32_t pos, width;
+
+op2 = MASK_OP_RRPW_OP2(ctx-opcode);
+r1 = MASK_OP_RRPW_S1(ctx-opcode);
+r2 = MASK_OP_RRPW_S2(ctx-opcode);
+r3 = MASK_OP_RRPW_D(ctx-opcode);
+pos = MASK_OP_RRPW_POS(ctx-opcode);
+width = MASK_OP_RRPW_WIDTH(ctx-opcode);
+
+switch (op2) {
+case OPC2_32_RRPW_EXTR:
+if (pos + width = 31) {
+/* optimize special cases */
+if ((pos == 0)  (width == 8)){
+tcg_gen_ext8s_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+} else if ((pos == 0)  (width == 16)) {
+tcg_gen_ext16s_tl(cpu_gpr_d[r3], cpu_gpr_d[r1]);
+} else {
+tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], 32 - pos - 
width);
+tcg_gen_sari_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], 32 - width);
+}
+}
+break;
+case OPC2_32_RRPW_EXTR_U:
+if (width == 0) {
+tcg_gen_movi_tl(cpu_gpr_d[r3], 0);
+} else {
+tcg_gen_shri_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], pos);
+tcg_gen_andi_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], ~0u  (32-width));
+}
+break;
+case OPC2_32_RRPW_IMASK:
+if (pos + width = 31) {
+tcg_gen_movi_tl(cpu_gpr_d[r3+1], ((1u  width) - 1)  pos);
+tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], pos);
+}
+break;
+case OPC2_32_RRPW_INSERT:
+if (pos + width = 31) {
+tcg_gen_deposit_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], cpu_gpr_d[r2],
+   width, pos);
+}
+break;
+}
+}
+
 static void decode_32Bit_opc(CPUTriCoreState *env, DisasContext *ctx)
 {
 int op1;
@@ -5254,6 +5305,25 @@ static void decode_32Bit_opc(CPUTriCoreState *env, 
DisasContext *ctx)
 case OPCM_32_RR2_MUL:
 decode_rr2_mul(env, ctx);
 break;
+/* RRPW format */
+case OPCM_32_RRPW_EXTRACT_INSERT:
+decode_rrpw_extract_insert(env, ctx);
+break;
+case OPC1_32_RRPW_DEXTR:
+r1 = MASK_OP_RRPW_S1(ctx-opcode);
+r2 = MASK_OP_RRPW_S2(ctx-opcode);
+r3 = MASK_OP_RRPW_D(ctx-opcode);
+const16 = MASK_OP_RRPW_POS(ctx-opcode);
+if (r1 == r2) {
+tcg_gen_rotli_tl(cpu_gpr_d[r3], cpu_gpr_d[r1], const16);
+} else {
+temp = tcg_temp_new();
+tcg_gen_shli_tl(cpu_gpr_d[r3], cpu_gpr_d[r2], const16);
+tcg_gen_shri_tl(temp, cpu_gpr_d[r1], 32 - const16);
+tcg_gen_or_tl(cpu_gpr_d[r3], cpu_gpr_d[r3], temp);
+tcg_temp_free(temp);
+}
+break;
 }
 }

--
2.2.2




[Qemu-devel] [PATCH v2 0/4] TriCore add instructions of RR1, RR2, RRPW and RRR opcode format

2015-01-26 Thread Bastian Koppelmann
Hi,

this is a rather short patchset, that only implements instructions of four
formats. There will be another patchset, which has a few bugfixes.

Cheers,
Bastian

v1 - v2:
- Add 3 helper functions (gen_mul_q, gen_mul_q_16, gen_mulr_q) to
  remove repetition.
- gen_mul_q now uses 64 arithmetic instead of emulating it.
- MUL_Q now uses arithmetic shift, instead of normal shift + sign extend 
for arg
  extraction.
- optimize OPC2_32_RRPW_EXTR by using only two shifts, instead of four.
- OPC1_32_RRPW_DEXTR now has r1 == r2 as a special case.

Bastian Koppelmann (4):
  target-tricore: target-tricore: Add instructions of RR1 opcode format,
that have 0x93 as first opcode
  target-tricore: Add instructions of RR2 opcode format
  target-tricore: Add instructions of RRPW opcode format
  target-tricore: Add instructions of RRR opcode format

 target-tricore/helper.h  |   8 +
 target-tricore/op_helper.c   | 160 ++
 target-tricore/translate.c   | 439 +++
 target-tricore/tricore-opcodes.h |   2 +-
 4 files changed, 608 insertions(+), 1 deletion(-)

--
2.2.2




Re: [Qemu-devel] [PATCH 2/2] hw/ppc/spapr Add qemu_register_boot_set for SPAPR

2015-01-26 Thread Alexander Graf

On 01/26/2015 11:49 AM, Dinar Valeev wrote:

On 01/24/2015 12:04 AM, Alexander Graf wrote:



On 23.01.15 23:51, dval...@suse.de wrote:

From: Dinar Valeev dval...@suse.com

In order to have -boot once=d functioning, it is required to have
qemu_register_boot_set

qemu-system-ppc64 -enable-kvm -boot once=d

Ready!
0  dev /chosen   ok
0  .properties
...
qemu,boot-device d
...
0  reset-all

Ready!
0  dev /chosen   ok
0  .properties
...
qemu,boot-device cdn
...

Signed-off-by: Dinar Valeev dval...@suse.com
---
  hw/ppc/spapr.c | 12 
  1 file changed, 12 insertions(+)

diff --git a/hw/ppc/spapr.c b/hw/ppc/spapr.c
index 3d2cfa3..38b03fc 100644
--- a/hw/ppc/spapr.c
+++ b/hw/ppc/spapr.c
@@ -314,6 +314,16 @@ static void add_str(GString *s, const gchar *s1)
  g_string_append_len(s, s1, strlen(s1) + 1);
  }

+static void spapr_boot_set(void *opaque, const char *boot_device,
+   Error **errp)
+{
+int offset;
+offset = fdt_path_offset(opaque, /chosen);
+fdt_setprop_string(opaque, offset, qemu,boot-device, 
boot_device);

+
+}
+
+
  static void *spapr_create_fdt_skel(hwaddr initrd_base,
 hwaddr initrd_size,
 hwaddr kernel_size,
@@ -414,6 +424,8 @@ static void *spapr_create_fdt_skel(hwaddr 
initrd_base,

  if (boot_device) {
  _FDT((fdt_property_string(fdt, qemu,boot-device, 
boot_device)));

  }
+qemu_register_boot_set(spapr_boot_set, fdt);


If you simply move the code above (the _FDT() one) from create_fdt_skel
to spapr_finalize_fdt() you should have the same net effect and much
cleaner code :).

I've tried your proposal, on reset boot-device property stays d


Ugh, the machine field doesn't change on reset. I think it'd be a lot 
more intuitive if it did. Can you try with the patch below applied as well?



diff --git a/bootdevice.c b/bootdevice.c
index 5914417..3b750ff 100644
--- a/bootdevice.c
+++ b/bootdevice.c
@@ -50,6 +50,7 @@ void qemu_register_boot_set(QEMUBootSetHandler *func, 
void *opaque)

 void qemu_boot_set(const char *boot_order, Error **errp)
 {
 Error *local_err = NULL;
+MachineState *machine = MACHINE(qdev_get_machine());

 if (!boot_set_handler) {
 error_setg(errp, no function defined to set boot device list for
@@ -63,6 +64,7 @@ void qemu_boot_set(const char *boot_order, Error **errp)
 return;
 }

+machine-boot_order = boot_order;
 boot_set_handler(boot_set_opaque, boot_order, errp);
 }



Thanks,

Alex




Re: [Qemu-devel] [PATCH v3 00/14] block: Remove growable, add blk_new_open()

2015-01-26 Thread Stefano Stabellini
On Mon, 26 Jan 2015, Max Reitz wrote:
 This series removes the growable field from the BlockDriverState
 object. Its use was to clamp guest requests against the limits of the
 BDS; however, this can now be done more easily by moving those checks
 into the BlockBackend functions.
 
 In a future series, growable may be reintroduced (maybe with a
 different name); it will then signify whether a BDS is able to grow (in
 contrast to the current growable, which signifies whether it is
 allowed to). Maybe I will add it to the BlockDriver instead of the BDS,
 though.
 
 To be able to remove that field, qemu-io needs to be converted to
 BlockBackend, which is done by this series as well. While working on
 that I decided to convert blk_new_with_bs()+bdrv_open() to
 blk_new_open(). I was skeptical about that decision at first, but it
 seems good now that I was able to replace nearly every blk_new_with_bs()
 call by blk_new_open(). In a future series I may try to convert some
 remaining bdrv_open() calls to blk_new_open() as well. (And, in fact, in
 a future series I *will* replace the last remaining blk_new_with_bs()
 outside of blk_new_open() by blk_new_open().)
 
 Finally, the question needs to be asked: If, after this series, every
 BDS is allowed to grow, are there any users which do not use BB, but
 should still be disallowed from reading/writing beyond a BDS's limits?
 The only users I could see were the block jobs. Some of them should
 indeed be converted to BB; but none of them takes a user-supplied offset
 or size, all work on the full BDS (or only on parts which have been
 modified, etc.). Therefore, it is by design impossible for them to
 exceed the BDS's limits, which makes making all BDS's growable safe.
 
 
 v3:
 - Rebased (onto Stefan's branch rebased onto master)
 - Fixed patch 4 [Stefano]

Thanks! It builds correctly and seems to work OK.


 v2:
 - Rebased [Kevin]
 - Patch 2: Added a TODO comment about removing @filename and @flags from
   blk_new_open() when possible [Kevin]
 
 
 git-backport-diff against v2:
 
 Key:
 [] : patches are identical
 [] : number of functional differences between upstream/downstream patch
 [down] : patch is downstream-only
 The flags [FC] indicate (F)unctional and (C)ontextual differences, 
 respectively
 
 001/14:[] [--] 'block: Lift some BDS functions to the BlockBackend'
 002/14:[] [--] 'block: Add blk_new_open()'
 003/14:[] [--] 'blockdev: Use blk_new_open() in blockdev_init()'
 004/14:[0004] [FC] 'block/xen: Use blk_new_open() in blk_connect()'
 005/14:[] [--] 'qemu-img: Use blk_new_open() in img_open()'
 006/14:[] [-C] 'qemu-img: Use blk_new_open() in img_rebase()'
 007/14:[] [-C] 'qemu-img: Use BlockBackend as far as possible'
 008/14:[] [--] 'qemu-nbd: Use blk_new_open() in main()'
 009/14:[] [--] 'qemu-io: Use blk_new_open() in openfile()'
 010/14:[] [--] 'qemu-io: Remove growable option'
 011/14:[] [--] 'qemu-io: Use BlockBackend'
 012/14:[] [--] 'block: Clamp BlockBackend requests'
 013/14:[] [--] 'block: Remove growable from BDS'
 014/14:[] [--] 'block: Keep bdrv_check*_request()'s return value'
 
 
 git-backport-diff against v1:
 
 Key:
 [] : patches are identical
 [] : number of functional differences between upstream/downstream patch
 [down] : patch is downstream-only
 The flags [FC] indicate (F)unctional and (C)ontextual differences, 
 respectively
 
 001/14:[] [--] 'block: Lift some BDS functions to the BlockBackend'
 002/14:[0006] [FC] 'block: Add blk_new_open()'
 003/14:[] [-C] 'blockdev: Use blk_new_open() in blockdev_init()'
 004/14:[0004] [FC] 'block/xen: Use blk_new_open() in blk_connect()'
 005/14:[] [--] 'qemu-img: Use blk_new_open() in img_open()'
 006/14:[] [-C] 'qemu-img: Use blk_new_open() in img_rebase()'
 007/14:[] [-C] 'qemu-img: Use BlockBackend as far as possible'
 008/14:[] [--] 'qemu-nbd: Use blk_new_open() in main()'
 009/14:[] [--] 'qemu-io: Use blk_new_open() in openfile()'
 010/14:[0002] [FC] 'qemu-io: Remove growable option'
 011/14:[] [--] 'qemu-io: Use BlockBackend'
 012/14:[] [--] 'block: Clamp BlockBackend requests'
 013/14:[] [--] 'block: Remove growable from BDS'
 014/14:[] [--] 'block: Keep bdrv_check*_request()'s return value'
 
 
 Max Reitz (14):
   block: Lift some BDS functions to the BlockBackend
   block: Add blk_new_open()
   blockdev: Use blk_new_open() in blockdev_init()
   block/xen: Use blk_new_open() in blk_connect()
   qemu-img: Use blk_new_open() in img_open()
   qemu-img: Use blk_new_open() in img_rebase()
   qemu-img: Use BlockBackend as far as possible
   qemu-nbd: Use blk_new_open() in main()
   qemu-io: Use blk_new_open() in openfile()
   qemu-io: Remove growable option
   qemu-io: Use BlockBackend
   block: Clamp BlockBackend requests
   block: Remove growable from BDS
   block: Keep bdrv_check*_request()'s return value
 
  block.c|  59 +-
  block/block-backend.c 

[Qemu-devel] [PATCH 00/50] blockdev: BlockBackend and media

2015-01-26 Thread Max Reitz
This series reworks a lot regarding BlockBackend and media. It is
essentially a v3 to the blockdev: Add blockdev-change-medium with
read-only option series (which is in fact a part of this series), but
of course does a lot more.

Basically, this series allows empty BlockBackends, that is BBs without a
BDS tree.

Before this series, empty drives are represented by a BlockBackend with
an empty BDS attached to it (a BDS with a NULL driver). However, now we
have BlockBackends, thus an empty drive should be represented by a
BlockBackend without any BDS tree attached to it. This is what this
series does.


I am CC'ing a lot of people (basically everyone who is working on the
block layer) due to the fact that this series touches a lot of places in
the block layer. Please pick out patches that seem to be relevant to
your area of expertise (e.g. there is an FDC tray patch for John; there
are some block job patches for Jeff; etc. pp.). I want to explicitly
encourage you to review only parts of this series! (Of course, reviewing
everything is fine, too :-))

Also, brace for a follow-up regarding bdrv_close_all() (there is a nice
bug in there which I found while working on this series).


This series depends on v3 (or any later version) of my series
'block: Remove growable, add blk_new_open()'.


- Patches 1 and 2 make it possible to use blockdev-add without creating
  a BlockBackend. This is necessary because the QMP command introduced
  in patch 42 (blockdev-insert-medium) will insert a BDS tree (a medium)
  into a BlockBackend (a drive). Creating a BlockBackend for such a BDS
  tree would both be a hassle and a waste, so this makes it possible to
  omit creating a BB.
  Patches 35 and 36 are kind of a follow-up to these; but patch 35
  depends on patch 34 which is the reason why there is a large gap
  between patch 2 and 35.

- Patch 3 implements a tray status for floppy disk drives. See the
  commit message for more information on what this means.

- Patches 3 to 33 basically all prepare the block layer for having BBs
  without BDS trees. I will only list the most notable ones (patch 3,
  for instance, is not notable).
  They do so by moving some information into the BlockBackend, and
  primarily by intercepting accesses to empty BBs in the BB layer and
  resorting to default actions there.
  Furthermore, hopefully all non-BB calls to bdrv_*() functions are
  guarded by checking whether that BDS actually exists.

- Patch 6 makes blk_is_inserted() return true only if there is a BDS
  tree; furthermore, blk_is_available() is added which additionally
  checks whether the guest device tray is closed.

- Patches 7 and 8 are some kind of follow-up to patch 6; they make
  bdrv_is_inserted() actually useful (unless I'm not mistaken; maybe I
  am and they make bdrv_is_inserted() actually useless).

- Patches 9, 11 and 12 move some (root!) BDS fields into the BB, because
  that is where they belong. This way they survive a medium (BDS tree)
  change.

- Patch 10 is necessary because the structure moved in patch 11
  (BlockAcctStats) contains one field which does belong into the BDS
  (wr_highest_offset). Thus, this field is moved out of that structure
  into the BDS here.

- Patch 13 adds a structure to the BB which can save some options from
  the root BDS so they survive a medium change. In theory, those options
  should probably not survive a medium change (they are not really
  drive- but medium-related), but this is how the 'change' command
  always handled it so this structure (the BlockBackendRootState, BBRS)
  is required for compatibility.
  One of these options is the read-only status, for example.

- Patches 17 to 30 and patches 32 and 33 prepare functions in the block
  layer which directly access a BDS to cope with a non-existing BDS
  tree. Patch 31 is a prerequisite for patch 32.

- Patch 34 gets down to business: Empty drives no longer have a BDS
  tree.

- Patches 35 and 36 are, as described above, a follow-up to patch 1.

- Patch 37 is the counterpart to patch 31, obviously.

- Patches 38 to 41 implement the basic QMP operations for tray and
  medium operation: blockdev-open-tray, blockdev-close-tray,
  blockdev-remove-medium and blockdev-insert-medium.

- Patches 42 and 43 reimplement 'eject' and 'change' using these new
  medium operations.

- With me now knowing exactly what 'change' does (because I
  reimplemented it), patch 44 became possible.

- Patches 45 to 48 are from v2 of series (slightly modified)
  blockdev: Add blockdev-change-medium with read-only option
  One modification are notes in patch 45 that blockdev-change-medium is
  preferred over simply 'change' [Eric] and what atomic operations
  blockdev-change-medium itself performs.

- Patch 50 adds a test for 'change' and all associated QMP commands,
  patch 49 makes small amendments to VM.add_drive() in iotests.py to
  make the new test work.


git-backport-diff output against v2 of
blockdev: Add blockdev-change-medium with read-only 

[Qemu-devel] [PATCH 02/50] iotests: Only create BB if necessary

2015-01-26 Thread Max Reitz
Tests 071 and 081 test giving references in blockdev-add. It is not
necessary to create a BlockBackend here, so omit it.

Signed-off-by: Max Reitz mre...@redhat.com
---
 tests/qemu-iotests/071 | 50 ++
 tests/qemu-iotests/071.out | 12 +++
 tests/qemu-iotests/081 | 14 -
 tests/qemu-iotests/081.out |  5 +++--
 4 files changed, 70 insertions(+), 11 deletions(-)

diff --git a/tests/qemu-iotests/071 b/tests/qemu-iotests/071
index 9eaa49b..68bedd4 100755
--- a/tests/qemu-iotests/071
+++ b/tests/qemu-iotests/071
@@ -104,11 +104,20 @@ echo
 echo === Testing blkdebug on existing block device ===
 echo
 
-run_qemu -drive file=$TEST_IMG,format=raw,if=none,id=drive0 EOF
+run_qemu EOF
 { execute: qmp_capabilities }
 { execute: blockdev-add,
 arguments: {
 options: {
+node-name: drive0,
+driver: file,
+filename: $TEST_IMG
+}
+}
+}
+{ execute: blockdev-add,
+arguments: {
+options: {
 driver: $IMGFMT,
 id: drive0-debug,
 file: {
@@ -133,11 +142,23 @@ echo
 echo === Testing blkverify on existing block device ===
 echo
 
-run_qemu -drive file=$TEST_IMG,format=$IMGFMT,if=none,id=drive0 EOF
+run_qemu EOF
 { execute: qmp_capabilities }
 { execute: blockdev-add,
 arguments: {
 options: {
+node-name: drive0,
+driver: $IMGFMT,
+file: {
+driver: file,
+filename: $TEST_IMG
+}
+}
+}
+}
+{ execute: blockdev-add,
+arguments: {
+options: {
 driver: blkverify,
 id: drive0-verify,
 test: drive0,
@@ -163,11 +184,23 @@ echo
 echo === Testing blkverify on existing raw block device ===
 echo
 
-run_qemu -drive file=$TEST_IMG.base,format=raw,if=none,id=drive0 EOF
+run_qemu EOF
 { execute: qmp_capabilities }
 { execute: blockdev-add,
 arguments: {
 options: {
+node-name: drive0,
+driver: raw,
+file: {
+driver: file,
+filename: $TEST_IMG.base
+}
+}
+}
+}
+{ execute: blockdev-add,
+arguments: {
+options: {
 driver: blkverify,
 id: drive0-verify,
 test: {
@@ -193,11 +226,20 @@ echo
 echo === Testing blkdebug's set-state through QMP ===
 echo
 
-run_qemu -drive file=$TEST_IMG,format=raw,if=none,id=drive0 EOF
+run_qemu EOF
 { execute: qmp_capabilities }
 { execute: blockdev-add,
 arguments: {
 options: {
+node-name: drive0,
+driver: file,
+filename: $TEST_IMG
+}
+}
+}
+{ execute: blockdev-add,
+arguments: {
+options: {
 driver: $IMGFMT,
 id: drive0-debug,
 file: {
diff --git a/tests/qemu-iotests/071.out b/tests/qemu-iotests/071.out
index 9205ce2..c8ecfaf 100644
--- a/tests/qemu-iotests/071.out
+++ b/tests/qemu-iotests/071.out
@@ -42,10 +42,11 @@ read failed: Input/output error
 
 === Testing blkdebug on existing block device ===
 
-Testing: -drive file=TEST_DIR/t.IMGFMT,format=raw,if=none,id=drive0
+Testing:
 QMP_VERSION
 {return: {}}
 {return: {}}
+{return: {}}
 read failed: Input/output error
 {return: }
 {return: {}}
@@ -58,28 +59,31 @@ QEMU_PROG: Failed to flush the refcount block cache: 
Input/output error
 
 === Testing blkverify on existing block device ===
 
-Testing: -drive file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=drive0
+Testing:
 QMP_VERSION
 {return: {}}
 {return: {}}
+{return: {}}
 blkverify: read sector_num=0 nb_sectors=1 contents mismatch in sector 0
 
 
 === Testing blkverify on existing raw block device ===
 
-Testing: -drive file=TEST_DIR/t.IMGFMT.base,format=raw,if=none,id=drive0
+Testing:
 QMP_VERSION
 {return: {}}
 {return: {}}
+{return: {}}
 blkverify: read sector_num=0 nb_sectors=1 contents mismatch in sector 0
 
 
 === Testing blkdebug's set-state through QMP ===
 
-Testing: -drive file=TEST_DIR/t.IMGFMT,format=raw,if=none,id=drive0
+Testing:
 QMP_VERSION
 {return: {}}
 {return: {}}
+{return: {}}
 read 512/512 bytes at offset 0
 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
 {return: }
diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081
index d9b042c..5c8a8fa 100755
--- a/tests/qemu-iotests/081
+++ b/tests/qemu-iotests/081
@@ -101,11 +101,23 @@ $QEMU_IO -c open -o $quorum -c read -P 0x32 0 $size | 
_filter_qemu_io
 echo
 echo == checking mixed reference/option specification ==
 
-run_qemu -drive file=$TEST_DIR/2.raw,format=$IMGFMT,if=none,id=drive2 EOF
+run_qemu EOF
 { execute: qmp_capabilities }
 { execute: blockdev-add,
 arguments: {
 options: {
+node-name: drive2,
+driver: raw,
+file: {
+driver: file,
+filename: $TEST_DIR/2.raw
+}
+}
+}
+}
+{ execute: blockdev-add,
+arguments: {
+options: {
 

[Qemu-devel] [PATCH 08/50] block/quorum: Implement bdrv_is_inserted()

2015-01-26 Thread Max Reitz
bdrv_is_inserted() should be invoked recursively on the children of
quorum.

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

diff --git a/block/quorum.c b/block/quorum.c
index 437b122..7811c4a 100644
--- a/block/quorum.c
+++ b/block/quorum.c
@@ -1064,6 +1064,20 @@ static void quorum_refresh_filename(BlockDriverState *bs)
 bs-full_open_options = opts;
 }
 
+static int quorum_is_inserted(BlockDriverState *bs)
+{
+BDRVQuorumState *s = bs-opaque;
+int i;
+
+for (i = 0; i  s-num_children; i++) {
+if (!bdrv_is_inserted(s-bs[i])) {
+return 0;
+}
+}
+
+return 1;
+}
+
 static BlockDriver bdrv_quorum = {
 .format_name= quorum,
 .protocol_name  = quorum,
@@ -1087,6 +1101,8 @@ static BlockDriver bdrv_quorum = {
 
 .is_filter  = true,
 .bdrv_recurse_is_first_non_filter   = quorum_recurse_is_first_non_filter,
+
+.bdrv_is_inserted   = quorum_is_inserted,
 };
 
 static void bdrv_quorum_init(void)
-- 
2.1.0




[Qemu-devel] [PATCH 11/50] block: Move BlockAcctStats into BlockBackend

2015-01-26 Thread Max Reitz
As the comment above bdrv_get_stats() says, BlockAcctStats is something
which belongs to the device instead of each BlockDriverState. This patch
therefore moves it into the BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block.c   | 11 ---
 block/block-backend.c |  5 -
 block/qapi.c  | 20 
 include/block/block.h |  2 --
 include/block/block_int.h |  3 ---
 5 files changed, 16 insertions(+), 25 deletions(-)

diff --git a/block.c b/block.c
index 5db71c6..17e4ee3 100644
--- a/block.c
+++ b/block.c
@@ -6119,14 +6119,3 @@ void bdrv_refresh_filename(BlockDriverState *bs)
 QDECREF(json);
 }
 }
-
-/* This accessor function purpose is to allow the device models to access the
- * BlockAcctStats structure embedded inside a BlockDriverState without being
- * aware of the BlockDriverState structure layout.
- * It will go away when the BlockAcctStats structure will be moved inside
- * the device models.
- */
-BlockAcctStats *bdrv_get_stats(BlockDriverState *bs)
-{
-return bs-stats;
-}
diff --git a/block/block-backend.c b/block/block-backend.c
index bf0fcc9..3d565d8 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -34,6 +34,9 @@ struct BlockBackend {
 
 /* the block size for which the guest device expects atomicity */
 int guest_block_size;
+
+/* I/O stats (display with info blockstats). */
+BlockAcctStats stats;
 };
 
 typedef struct BlockBackendAIOCB {
@@ -849,7 +852,7 @@ void blk_io_unplug(BlockBackend *blk)
 
 BlockAcctStats *blk_get_stats(BlockBackend *blk)
 {
-return bdrv_get_stats(blk-bs);
+return blk-stats;
 }
 
 void *blk_aio_get(const AIOCBInfo *aiocb_info, BlockBackend *blk,
diff --git a/block/qapi.c b/block/qapi.c
index 4e97574..7840c81 100644
--- a/block/qapi.c
+++ b/block/qapi.c
@@ -334,14 +334,18 @@ static BlockStats *bdrv_query_stats(const 
BlockDriverState *bs,
 }
 
 s-stats = g_malloc0(sizeof(*s-stats));
-s-stats-rd_bytes = bs-stats.nr_bytes[BLOCK_ACCT_READ];
-s-stats-wr_bytes = bs-stats.nr_bytes[BLOCK_ACCT_WRITE];
-s-stats-rd_operations = bs-stats.nr_ops[BLOCK_ACCT_READ];
-s-stats-wr_operations = bs-stats.nr_ops[BLOCK_ACCT_WRITE];
-s-stats-flush_operations = bs-stats.nr_ops[BLOCK_ACCT_FLUSH];
-s-stats-wr_total_time_ns = bs-stats.total_time_ns[BLOCK_ACCT_WRITE];
-s-stats-rd_total_time_ns = bs-stats.total_time_ns[BLOCK_ACCT_READ];
-s-stats-flush_total_time_ns = bs-stats.total_time_ns[BLOCK_ACCT_FLUSH];
+if (bs-blk) {
+BlockAcctStats *stats = blk_get_stats(bs-blk);
+
+s-stats-rd_bytes = stats-nr_bytes[BLOCK_ACCT_READ];
+s-stats-wr_bytes = stats-nr_bytes[BLOCK_ACCT_WRITE];
+s-stats-rd_operations = stats-nr_ops[BLOCK_ACCT_READ];
+s-stats-wr_operations = stats-nr_ops[BLOCK_ACCT_WRITE];
+s-stats-flush_operations = stats-nr_ops[BLOCK_ACCT_FLUSH];
+s-stats-wr_total_time_ns = stats-total_time_ns[BLOCK_ACCT_WRITE];
+s-stats-rd_total_time_ns = stats-total_time_ns[BLOCK_ACCT_READ];
+s-stats-flush_total_time_ns = stats-total_time_ns[BLOCK_ACCT_FLUSH];
+}
 
 s-stats-wr_highest_offset = bs-wr_highest_sector * BDRV_SECTOR_SIZE;
 
diff --git a/include/block/block.h b/include/block/block.h
index df656db..8cd6b31 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -550,6 +550,4 @@ void bdrv_io_plug(BlockDriverState *bs);
 void bdrv_io_unplug(BlockDriverState *bs);
 void bdrv_flush_io_queue(BlockDriverState *bs);
 
-BlockAcctStats *bdrv_get_stats(BlockDriverState *bs);
-
 #endif
diff --git a/include/block/block_int.h b/include/block/block_int.h
index e309d8a..d023913 100644
--- a/include/block/block_int.h
+++ b/include/block/block_int.h
@@ -363,9 +363,6 @@ struct BlockDriverState {
 CoQueue  throttled_reqs[2];
 bool io_limits_enabled;
 
-/* I/O stats (display with info blockstats). */
-BlockAcctStats stats;
-
 /* Highest sector index written to */
 uint64_t wr_highest_sector;
 
-- 
2.1.0




[Qemu-devel] [PATCH 21/50] blockdev: Check BB validity in internal snapshot TA

2015-01-26 Thread Max Reitz
Call blk_is_available() before using blk_bs() to obtain the root
BlockDriverState behind the BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 858d181..012c603 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -1217,6 +1217,7 @@ static void internal_snapshot_prepare(BlkTransactionState 
*common,
 Error *local_err = NULL;
 const char *device;
 const char *name;
+BlockBackend *blk;
 BlockDriverState *bs;
 QEMUSnapshotInfo old_sn, *sn;
 bool ret;
@@ -1235,20 +1236,21 @@ static void 
internal_snapshot_prepare(BlkTransactionState *common,
 name = internal-name;
 
 /* 2. check for validation */
-bs = bdrv_find(device);
-if (!bs) {
+blk = blk_by_name(device);
+if (!blk) {
 error_set(errp, QERR_DEVICE_NOT_FOUND, device);
 return;
 }
 
 /* AioContext is released in .clean() */
-state-aio_context = bdrv_get_aio_context(bs);
+state-aio_context = blk_get_aio_context(blk);
 aio_context_acquire(state-aio_context);
 
-if (!bdrv_is_inserted(bs)) {
+if (!blk_is_available(blk)) {
 error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
 return;
 }
+bs = blk_bs(blk);
 
 if (bdrv_op_is_blocked(bs, BLOCK_OP_TYPE_INTERNAL_SNAPSHOT, errp)) {
 return;
-- 
2.1.0




[Qemu-devel] [PATCH 16/50] block: Prepare remaining BB functions for NULL BDS

2015-01-26 Thread Max Reitz
There are several BlockBackend functions which, in theory, cannot fail.
This patch makes them cope with the BlockDriverState pointer being NULL
by making them fall back to some default action like ignoring the value
in setters and returning the default in getters.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block/block-backend.c | 70 ---
 1 file changed, 55 insertions(+), 15 deletions(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 4f3122a..760558f 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -644,7 +644,11 @@ int64_t blk_getlength(BlockBackend *blk)
 
 void blk_get_geometry(BlockBackend *blk, uint64_t *nb_sectors_ptr)
 {
-bdrv_get_geometry(blk-bs, nb_sectors_ptr);
+if (!blk-bs) {
+*nb_sectors_ptr = 0;
+} else {
+bdrv_get_geometry(blk-bs, nb_sectors_ptr);
+}
 }
 
 BlockAIOCB *blk_aio_readv(BlockBackend *blk, int64_t sector_num,
@@ -862,17 +866,27 @@ int blk_is_read_only(BlockBackend *blk)
 
 int blk_is_sg(BlockBackend *blk)
 {
+if (!blk-bs) {
+return 0;
+}
+
 return bdrv_is_sg(blk-bs);
 }
 
 int blk_enable_write_cache(BlockBackend *blk)
 {
+if (!blk-bs) {
+return 0;
+}
+
 return bdrv_enable_write_cache(blk-bs);
 }
 
 void blk_set_enable_write_cache(BlockBackend *blk, bool wce)
 {
-bdrv_set_enable_write_cache(blk-bs, wce);
+if (blk-bs) {
+bdrv_set_enable_write_cache(blk-bs, wce);
+}
 }
 
 void blk_invalidate_cache(BlockBackend *blk, Error **errp)
@@ -897,12 +911,16 @@ bool blk_is_available(BlockBackend *blk)
 
 void blk_lock_medium(BlockBackend *blk, bool locked)
 {
-bdrv_lock_medium(blk-bs, locked);
+if (blk-bs) {
+bdrv_lock_medium(blk-bs, locked);
+}
 }
 
 void blk_eject(BlockBackend *blk, bool eject_flag)
 {
-bdrv_eject(blk-bs, eject_flag);
+if (blk-bs) {
+bdrv_eject(blk-bs, eject_flag);
+}
 }
 
 int blk_get_flags(BlockBackend *blk)
@@ -926,22 +944,32 @@ void *blk_blockalign(BlockBackend *blk, size_t size)
 
 bool blk_op_is_blocked(BlockBackend *blk, BlockOpType op, Error **errp)
 {
+if (!blk-bs) {
+return false;
+}
+
 return bdrv_op_is_blocked(blk-bs, op, errp);
 }
 
 void blk_op_unblock(BlockBackend *blk, BlockOpType op, Error *reason)
 {
-bdrv_op_unblock(blk-bs, op, reason);
+if (blk-bs) {
+bdrv_op_unblock(blk-bs, op, reason);
+}
 }
 
 void blk_op_block_all(BlockBackend *blk, Error *reason)
 {
-bdrv_op_block_all(blk-bs, reason);
+if (blk-bs) {
+bdrv_op_block_all(blk-bs, reason);
+}
 }
 
 void blk_op_unblock_all(BlockBackend *blk, Error *reason)
 {
-bdrv_op_unblock_all(blk-bs, reason);
+if (blk-bs) {
+bdrv_op_unblock_all(blk-bs, reason);
+}
 }
 
 AioContext *blk_get_aio_context(BlockBackend *blk)
@@ -961,15 +989,19 @@ static AioContext *blk_aiocb_get_aio_context(BlockAIOCB 
*acb)
 
 void blk_set_aio_context(BlockBackend *blk, AioContext *new_context)
 {
-bdrv_set_aio_context(blk-bs, new_context);
+if (blk-bs) {
+bdrv_set_aio_context(blk-bs, new_context);
+}
 }
 
 void blk_add_aio_context_notifier(BlockBackend *blk,
 void (*attached_aio_context)(AioContext *new_context, void *opaque),
 void (*detach_aio_context)(void *opaque), void *opaque)
 {
-bdrv_add_aio_context_notifier(blk-bs, attached_aio_context,
-  detach_aio_context, opaque);
+if (blk-bs) {
+bdrv_add_aio_context_notifier(blk-bs, attached_aio_context,
+  detach_aio_context, opaque);
+}
 }
 
 void blk_remove_aio_context_notifier(BlockBackend *blk,
@@ -978,23 +1010,31 @@ void blk_remove_aio_context_notifier(BlockBackend *blk,
  void (*detach_aio_context)(void *),
  void *opaque)
 {
-bdrv_remove_aio_context_notifier(blk-bs, attached_aio_context,
- detach_aio_context, opaque);
+if (blk-bs) {
+bdrv_remove_aio_context_notifier(blk-bs, attached_aio_context,
+ detach_aio_context, opaque);
+}
 }
 
 void blk_add_close_notifier(BlockBackend *blk, Notifier *notify)
 {
-bdrv_add_close_notifier(blk-bs, notify);
+if (blk-bs) {
+bdrv_add_close_notifier(blk-bs, notify);
+}
 }
 
 void blk_io_plug(BlockBackend *blk)
 {
-bdrv_io_plug(blk-bs);
+if (blk-bs) {
+bdrv_io_plug(blk-bs);
+}
 }
 
 void blk_io_unplug(BlockBackend *blk)
 {
-bdrv_io_unplug(blk-bs);
+if (blk-bs) {
+bdrv_io_unplug(blk-bs);
+}
 }
 
 BlockAcctStats *blk_get_stats(BlockBackend *blk)
-- 
2.1.0




[Qemu-devel] [PATCH 17/50] block: Respect empty BB in bdrv_lookup_bs()

2015-01-26 Thread Max Reitz
blk_by_name() may return a BlockBackend for which blk_bs() returns NULL.
In this case, an error should be returned (instead of just returning
NULL without modifying *errp).

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

diff --git a/block.c b/block.c
index 9a0a510..b7e631c 100644
--- a/block.c
+++ b/block.c
@@ -3718,6 +3718,11 @@ BlockDriverState *bdrv_lookup_bs(const char *device,
 blk = blk_by_name(device);
 
 if (blk) {
+if (!blk_bs(blk)) {
+error_set(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
+return NULL;
+}
+
 return blk_bs(blk);
 }
 }
-- 
2.1.0




[Qemu-devel] [PATCH 35/50] blockdev: Pull out blockdev option extraction

2015-01-26 Thread Max Reitz
Extract some of the blockdev option extraction code from blockdev_init()
into an own function. This simplifies blockdev_init() and will allow
reusing the code in a different function added in a follow-up patch.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 201 +
 1 file changed, 108 insertions(+), 93 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index d99edbb..d573c5c 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -341,24 +341,123 @@ static bool check_throttle_config(ThrottleConfig *cfg, 
Error **errp)
 
 typedef enum { MEDIA_DISK, MEDIA_CDROM } DriveMediaType;
 
+static void extract_common_blockdev_options(QemuOpts *opts, int *bdrv_flags,
+ThrottleConfig *throttle_cfg, BlockdevDetectZeroesOptions *detect_zeroes,
+Error **errp)
+{
+const char *discard, *aio;
+Error *local_error = NULL;
+
+if (!qemu_opt_get_bool(opts, read-only, false)) {
+*bdrv_flags |= BDRV_O_RDWR;
+}
+if (qemu_opt_get_bool(opts, copy-on-read, false)) {
+*bdrv_flags |= BDRV_O_COPY_ON_READ;
+}
+
+if ((discard = qemu_opt_get(opts, discard)) != NULL) {
+if (bdrv_parse_discard_flags(discard, bdrv_flags) != 0) {
+error_setg(errp, Invalid discard option);
+return;
+}
+}
+
+if (qemu_opt_get_bool(opts, cache.writeback, true)) {
+*bdrv_flags |= BDRV_O_CACHE_WB;
+}
+if (qemu_opt_get_bool(opts, cache.direct, false)) {
+*bdrv_flags |= BDRV_O_NOCACHE;
+}
+if (qemu_opt_get_bool(opts, cache.no-flush, false)) {
+*bdrv_flags |= BDRV_O_NO_FLUSH;
+}
+
+#ifdef CONFIG_LINUX_AIO
+if ((aio = qemu_opt_get(opts, aio)) != NULL) {
+if (!strcmp(aio, native)) {
+*bdrv_flags |= BDRV_O_NATIVE_AIO;
+} else if (!strcmp(aio, threads)) {
+/* this is the default */
+} else {
+   error_setg(errp, invalid aio option);
+   return;
+}
+}
+#endif
+
+/* disk I/O throttling */
+memset(throttle_cfg, 0, sizeof(*throttle_cfg));
+throttle_cfg-buckets[THROTTLE_BPS_TOTAL].avg =
+qemu_opt_get_number(opts, throttling.bps-total, 0);
+throttle_cfg-buckets[THROTTLE_BPS_READ].avg  =
+qemu_opt_get_number(opts, throttling.bps-read, 0);
+throttle_cfg-buckets[THROTTLE_BPS_WRITE].avg =
+qemu_opt_get_number(opts, throttling.bps-write, 0);
+throttle_cfg-buckets[THROTTLE_OPS_TOTAL].avg =
+qemu_opt_get_number(opts, throttling.iops-total, 0);
+throttle_cfg-buckets[THROTTLE_OPS_READ].avg =
+qemu_opt_get_number(opts, throttling.iops-read, 0);
+throttle_cfg-buckets[THROTTLE_OPS_WRITE].avg =
+qemu_opt_get_number(opts, throttling.iops-write, 0);
+
+throttle_cfg-buckets[THROTTLE_BPS_TOTAL].max =
+qemu_opt_get_number(opts, throttling.bps-total-max, 0);
+throttle_cfg-buckets[THROTTLE_BPS_READ].max  =
+qemu_opt_get_number(opts, throttling.bps-read-max, 0);
+throttle_cfg-buckets[THROTTLE_BPS_WRITE].max =
+qemu_opt_get_number(opts, throttling.bps-write-max, 0);
+throttle_cfg-buckets[THROTTLE_OPS_TOTAL].max =
+qemu_opt_get_number(opts, throttling.iops-total-max, 0);
+throttle_cfg-buckets[THROTTLE_OPS_READ].max =
+qemu_opt_get_number(opts, throttling.iops-read-max, 0);
+throttle_cfg-buckets[THROTTLE_OPS_WRITE].max =
+qemu_opt_get_number(opts, throttling.iops-write-max, 0);
+
+throttle_cfg-op_size =
+qemu_opt_get_number(opts, throttling.iops-size, 0);
+
+if (!check_throttle_config(throttle_cfg, errp)) {
+return;
+}
+
+*detect_zeroes =
+qapi_enum_parse(BlockdevDetectZeroesOptions_lookup,
+qemu_opt_get(opts, detect-zeroes),
+BLOCKDEV_DETECT_ZEROES_OPTIONS_MAX,
+BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF,
+local_error);
+if (local_error) {
+error_propagate(errp, local_error);
+return;
+}
+
+if (*detect_zeroes == BLOCKDEV_DETECT_ZEROES_OPTIONS_UNMAP 
+!(*bdrv_flags  BDRV_O_UNMAP))
+{
+error_setg(errp, setting detect-zeroes to unmap is not allowed 
+ without setting discard operation to unmap);
+return;
+}
+
+}
+
 /* Takes the ownership of bs_opts */
 static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
Error **errp)
 {
 const char *buf;
-int ro = 0;
 int bdrv_flags = 0;
 int on_read_error, on_write_error;
 BlockBackend *blk;
 BlockDriverState *bs;
 ThrottleConfig cfg;
 int snapshot = 0;
-bool copy_on_read;
 Error *error = NULL;
 QemuOpts *opts;
 const char *id;
 bool has_driver_specific_opts;
-BlockdevDetectZeroesOptions detect_zeroes;
+BlockdevDetectZeroesOptions detect_zeroes =
+BLOCKDEV_DETECT_ZEROES_OPTIONS_OFF;
 
 /* Check common options 

[Qemu-devel] [PATCH v3 14/14] block: Keep bdrv_check*_request()'s return value

2015-01-26 Thread Max Reitz
Do not throw away the value returned by bdrv_check_request() and
bdrv_check_byte_request().

Fix up some coding style issues in the proximity of the affected hunks.

Signed-off-by: Max Reitz mre...@redhat.com
---
 block.c | 35 ---
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/block.c b/block.c
index 356a857..4a5f8fc 100644
--- a/block.c
+++ b/block.c
@@ -3096,8 +3096,10 @@ static int coroutine_fn 
bdrv_co_do_preadv(BlockDriverState *bs,
 if (!drv) {
 return -ENOMEDIUM;
 }
-if (bdrv_check_byte_request(bs, offset, bytes)) {
-return -EIO;
+
+ret = bdrv_check_byte_request(bs, offset, bytes);
+if (ret  0) {
+return ret;
 }
 
 if (bs-copy_on_read) {
@@ -3343,8 +3345,10 @@ static int coroutine_fn 
bdrv_co_do_pwritev(BlockDriverState *bs,
 if (bs-read_only) {
 return -EACCES;
 }
-if (bdrv_check_byte_request(bs, offset, bytes)) {
-return -EIO;
+
+ret = bdrv_check_byte_request(bs, offset, bytes);
+if (ret  0) {
+return ret;
 }
 
 /* throttling disk I/O */
@@ -4168,12 +4172,18 @@ int bdrv_write_compressed(BlockDriverState *bs, int64_t 
sector_num,
   const uint8_t *buf, int nb_sectors)
 {
 BlockDriver *drv = bs-drv;
-if (!drv)
+int ret;
+
+if (!drv) {
 return -ENOMEDIUM;
-if (!drv-bdrv_write_compressed)
+}
+if (!drv-bdrv_write_compressed) {
 return -ENOTSUP;
-if (bdrv_check_request(bs, sector_num, nb_sectors))
-return -EIO;
+}
+ret = bdrv_check_request(bs, sector_num, nb_sectors);
+if (ret  0) {
+return ret;
+}
 
 assert(QLIST_EMPTY(bs-dirty_bitmaps));
 
@@ -5091,12 +5101,15 @@ static void coroutine_fn bdrv_discard_co_entry(void 
*opaque)
 int coroutine_fn bdrv_co_discard(BlockDriverState *bs, int64_t sector_num,
  int nb_sectors)
 {
-int max_discard;
+int max_discard, ret;
 
 if (!bs-drv) {
 return -ENOMEDIUM;
-} else if (bdrv_check_request(bs, sector_num, nb_sectors)) {
-return -EIO;
+}
+
+ret = bdrv_check_request(bs, sector_num, nb_sectors);
+if (ret  0) {
+return ret;
 } else if (bs-read_only) {
 return -EROFS;
 }
-- 
2.1.0




Re: [Qemu-devel] [PATCH v2 01/47] acpi: introduce AML composer aml_append()

2015-01-26 Thread Igor Mammedov
On Mon, 26 Jan 2015 10:57:21 +0100
Igor Mammedov imamm...@redhat.com wrote:

 On Sat, 24 Jan 2015 18:33:50 +0200
 Michael S. Tsirkin m...@redhat.com wrote:
 
  On Fri, Jan 23, 2015 at 06:56:20PM +0100, Igor Mammedov wrote:
   On Fri, 23 Jan 2015 15:55:11 +0200
   Michael S. Tsirkin m...@redhat.com wrote:
   
[...]
   I refuse to give up on cleaner and simpler API yet :)
   


Your patches are almost there, they are pretty clean, the only issue I
think is this passing of AcpiAml by value, sometimes freeing buffer in
the process, sometimes not.
   Currently buffer is allocated by API and is always freed whenever
   it's passed to another API function.
   That's why it makes user not to care about memory mgmt.
   
   The only limitation of it is if you store AcpiAml return value into some
   variable you are responsible to use it only once for passing to another 
   API
   function. Reusing this variable's value (pass it to API function second 
   time)
   would cause cause use-after-free and freeing-freed bugs.
   Like this:
   AcpiAml table = acpi_definition_block(SSDT,...);
   AcpiAml scope = acpi_scope(PCI0);
   aml_append(table, scope); // - here scope becomes invalid
   // a bug
   aml_append(table, scope); // use-after-free + freeing-freed bugs
   
   There are several approaches to look for resolving above issues:
   1. Adopt and use memory mgmt model used by GTK+
  in nutshell: 
   http://www.cs.hunter.cuny.edu/~sweiss/course_materials/csci493.70/lecture_notes/GTK_memory_mngmt.pdf
  In particular adopt behavior of GInitiallyUnowned usage model
   
  that will allow to keep convenient chained call style and if necessary
  reuse objects returned by API by explicitly referencing/dereferencing
  them if needed.
  
  Hmm, it's still easy to misuse. I think I prefer option 2 below.
 That's basically what we have/use in QOM with object_new(FOO) + object_unref()
 I have no idea why we invented our own Object infrastructure
 when we could just use GObject one from already used glib.
 
  
   2. It's possible to drop freeing inside API completely and
  record(store in list) every new object inside a table context.
  When table is constructed, list of created objects could be
  safely freed.
  With that it would be safe to reuse every AcpiAml object
  and avoid free-after-use issues with limitation that created
  AcpiAml objects shouldn't be used after table was closed.
  It should cover all practical use of API, i.e. no cross
  table AcpiAml objects.
  
  So each aml_alloc function gets pointer to this list,
  and adds the new element there.
  Eventually we do free_all to free all elements,
  so there isn't even an aml_free to mis-use.
 I'm thinking a little bit different about implementation though.
 I still don't like the use of explicit alloc/free being called
 by API user since it doesn't allow chained API calls and
 I think it's unnecessary complication see below why.
 
 Here is what's true about current API and a I'd like to with it:
 
   1. Every API call (except aml_append) makes aml_alloc(), it's just
  like a wrapper about object_new(FOO). (current + new impl.)
 
   2 Every API call that takes AML type as input argument
   2.1 consumes (frees) it (current impl.)
   (it's easy to fix use after free concern too,
just pass AML by pointer and zero-out memory before it's freed
and assert whenever one of input arguments is not correct,
i.e. it was reused second time)
   There is no need for following steps after this one.
   2.2 takes ownership of GInitiallyUnowned and adds it to its list
   of its children.
   3. Free children when AML object is destroyed (i.e. ref count zero)
  That way when toplevel table object (definition block in 42/47)
  is added to ACPI blob we can unref it, which will cause
  its whole children tree freed, except for AML objects where
  API user explicitly took extra reference (i.e. wanted them
  to reuse in another table)
 
 I'd prefer:
  *  2.1 way to address your current concern of use-after-free
 as the most simplest one (no reuse is possible however)
 or
  * follow already used by QEMU QOM/GObject pattern of
implicit alloc/free
 
 since they allow to construct AML in a more simple/manageable way i.e.
  
   aml_append(method,
   aml_store(aml_string(foo), aml_local(0)))
   );
 
 v.s. explicit headache of alloc/free, which doesn't fix
  use-after-free anyway and just adds more boiler plate
  plus makes code har to read read
 
   str = aml_alloc();
   aml_string(str, foo);
   loc0 = aml_alloc();
   aml_local(loc0, 0);
   store = aml_alloc();
   aml_store(store, str, loc0);
   aml_append(method, store);
   aml_free(store);
   aml_free(loc0);
   aml_free(str);

Here is a compromise what I and Michael came to on a phone call:

Externally API usage would look like:

AmlAllocList *p = some_list_alloc();

Aml *ssdt = aml_def_block(p, 

[Qemu-devel] [PATCH] target-mips: fix detection of the end of the page during translation

2015-01-26 Thread Leon Alrae
The test is supposed to terminate TB if the end of the page is reached.
However, with current implementation it may never succeed for microMIPS or
mips16.

Reported-by: Richard Henderson r...@twiddle.net
Signed-off-by: Leon Alrae leon.al...@imgtec.com
---
 target-mips/translate.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/target-mips/translate.c b/target-mips/translate.c
index e9d86b2..f33c10c 100644
--- a/target-mips/translate.c
+++ b/target-mips/translate.c
@@ -19091,6 +19091,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, 
TranslationBlock *tb,
 CPUMIPSState *env = cpu-env;
 DisasContext ctx;
 target_ulong pc_start;
+target_ulong next_page_start;
 uint16_t *gen_opc_end;
 CPUBreakpoint *bp;
 int j, lj = -1;
@@ -19103,6 +19104,7 @@ gen_intermediate_code_internal(MIPSCPU *cpu, 
TranslationBlock *tb,
 qemu_log(search pc %d\n, search_pc);
 
 pc_start = tb-pc;
+next_page_start = (pc_start  TARGET_PAGE_MASK) + TARGET_PAGE_SIZE;
 gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
 ctx.pc = pc_start;
 ctx.saved_pc = -1;
@@ -19202,8 +19204,9 @@ gen_intermediate_code_internal(MIPSCPU *cpu, 
TranslationBlock *tb,
 break;
 }
 
-if ((ctx.pc  (TARGET_PAGE_SIZE - 1)) == 0)
+if (ctx.pc = next_page_start) {
 break;
+}
 
 if (tcg_ctx.gen_opc_ptr = gen_opc_end) {
 break;
-- 
2.1.0




[Qemu-devel] [PATCH 29/50] blockdev: Check BB validity in find_block_job()

2015-01-26 Thread Max Reitz
Call blk_is_available() before using blk_bs() to obtain the root
BlockDriverState behind the BlockBackend.

Signed-off-by: Max Reitz mre...@redhat.com
---
 blockdev.c | 20 +++-
 1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/blockdev.c b/blockdev.c
index 4e12061..4bd52b8 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2698,25 +2698,35 @@ out:
 /* Get the block job for a given device name and acquire its AioContext */
 static BlockJob *find_block_job(const char *device, AioContext **aio_context)
 {
+BlockBackend *blk;
 BlockDriverState *bs;
 
-bs = bdrv_find(device);
-if (!bs) {
+*aio_context = NULL;
+
+blk = blk_by_name(device);
+if (!blk) {
 goto notfound;
 }
 
-*aio_context = bdrv_get_aio_context(bs);
+*aio_context = blk_get_aio_context(blk);
 aio_context_acquire(*aio_context);
 
+if (!blk_is_available(blk)) {
+goto notfound;
+}
+bs = blk_bs(blk);
+
 if (!bs-job) {
-aio_context_release(*aio_context);
 goto notfound;
 }
 
 return bs-job;
 
 notfound:
-*aio_context = NULL;
+if (*aio_context) {
+aio_context_release(*aio_context);
+*aio_context = NULL;
+}
 return NULL;
 }
 
-- 
2.1.0




  1   2   3   4   >